From 2895b917fcb10207f8fdef5405937332f66e8e3f Mon Sep 17 00:00:00 2001 From: pk Date: Sun, 6 Jul 2025 19:03:59 +0200 Subject: [PATCH] Good point to make a commit --- .gowebbuild.yaml | 24 + README.md | 2 +- demo/dist/the-app.js | 17440 +++++++++++++++++++++++++++++++++++++ demo/index.html | 18 + demo/src/the-app.js | 54 + package-lock.json | 597 ++ package.json | 16 +- tp-element.js | 35 - tp-rich-text-box.js | 227 + tp-rtb-base-extension.js | 76 + tp-rtb-bold.js | 34 + tp-rtb-clear-format.js | 16 + tp-rtb-code.js | 34 + tp-rtb-italic.js | 34 + tp-rtb-strike.js | 34 + tp-rtb-underline.js | 34 + 16 files changed, 18636 insertions(+), 39 deletions(-) create mode 100644 .gowebbuild.yaml create mode 100644 demo/dist/the-app.js create mode 100644 demo/index.html create mode 100644 demo/src/the-app.js create mode 100644 package-lock.json delete mode 100644 tp-element.js create mode 100644 tp-rich-text-box.js create mode 100644 tp-rtb-base-extension.js create mode 100644 tp-rtb-bold.js create mode 100644 tp-rtb-clear-format.js create mode 100644 tp-rtb-code.js create mode 100644 tp-rtb-italic.js create mode 100644 tp-rtb-strike.js create mode 100644 tp-rtb-underline.js diff --git a/.gowebbuild.yaml b/.gowebbuild.yaml new file mode 100644 index 0000000..574af8f --- /dev/null +++ b/.gowebbuild.yaml @@ -0,0 +1,24 @@ +- esbuild: + entryPoints: + - demo/src/the-app.js + outdir: demo/dist + sourcemap: 1 + format: 3 + splitting: true + platform: 0 + bundle: true + write: true + logLevel: 3 + purgeBeforeBuild: false + watch: + paths: + - . + exclude: + - demo/ + injectLiveReload: demo/index.html + serve: + path: "demo" + port: 8080 + # link: + # from: ../../web/tp-elements + # to: ./frontend diff --git a/README.md b/README.md index 1ab27b7..154ca60 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# tp-element +# tp-rich-text-box diff --git a/demo/dist/the-app.js b/demo/dist/the-app.js new file mode 100644 index 0000000..a969e3c --- /dev/null +++ b/demo/dist/the-app.js @@ -0,0 +1,17440 @@ +// node_modules/@lit/reactive-element/css-tag.js +var t = globalThis; +var e = t.ShadowRoot && (void 0 === t.ShadyCSS || t.ShadyCSS.nativeShadow) && "adoptedStyleSheets" in Document.prototype && "replace" in CSSStyleSheet.prototype; +var s = Symbol(); +var o = /* @__PURE__ */ new WeakMap(); +var n = class { + constructor(t3, e4, o5) { + if (this._$cssResult$ = true, o5 !== s) throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead."); + this.cssText = t3, this.t = e4; + } + get styleSheet() { + let t3 = this.o; + const s4 = this.t; + if (e && void 0 === t3) { + const e4 = void 0 !== s4 && 1 === s4.length; + e4 && (t3 = o.get(s4)), void 0 === t3 && ((this.o = t3 = new CSSStyleSheet()).replaceSync(this.cssText), e4 && o.set(s4, t3)); + } + return t3; + } + toString() { + return this.cssText; + } +}; +var r = (t3) => new n("string" == typeof t3 ? t3 : t3 + "", void 0, s); +var i = (t3, ...e4) => { + const o5 = 1 === t3.length ? t3[0] : e4.reduce((e5, s4, o6) => e5 + ((t4) => { + if (true === t4._$cssResult$) return t4.cssText; + if ("number" == typeof t4) return t4; + throw Error("Value passed to 'css' function must be a 'css' function result: " + t4 + ". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security."); + })(s4) + t3[o6 + 1], t3[0]); + return new n(o5, t3, s); +}; +var S = (s4, o5) => { + if (e) s4.adoptedStyleSheets = o5.map((t3) => t3 instanceof CSSStyleSheet ? t3 : t3.styleSheet); + else for (const e4 of o5) { + const o6 = document.createElement("style"), n4 = t.litNonce; + void 0 !== n4 && o6.setAttribute("nonce", n4), o6.textContent = e4.cssText, s4.appendChild(o6); + } +}; +var c = e ? (t3) => t3 : (t3) => t3 instanceof CSSStyleSheet ? ((t4) => { + let e4 = ""; + for (const s4 of t4.cssRules) e4 += s4.cssText; + return r(e4); +})(t3) : t3; + +// node_modules/@lit/reactive-element/reactive-element.js +var { is: i2, defineProperty: e2, getOwnPropertyDescriptor: h, getOwnPropertyNames: r2, getOwnPropertySymbols: o2, getPrototypeOf: n2 } = Object; +var a = globalThis; +var c2 = a.trustedTypes; +var l = c2 ? c2.emptyScript : ""; +var p = a.reactiveElementPolyfillSupport; +var d = (t3, s4) => t3; +var u = { toAttribute(t3, s4) { + switch (s4) { + case Boolean: + t3 = t3 ? l : null; + break; + case Object: + case Array: + t3 = null == t3 ? t3 : JSON.stringify(t3); + } + return t3; +}, fromAttribute(t3, s4) { + let i5 = t3; + switch (s4) { + case Boolean: + i5 = null !== t3; + break; + case Number: + i5 = null === t3 ? null : Number(t3); + break; + case Object: + case Array: + try { + i5 = JSON.parse(t3); + } catch (t4) { + i5 = null; + } + } + return i5; +} }; +var f = (t3, s4) => !i2(t3, s4); +var b = { attribute: true, type: String, converter: u, reflect: false, useDefault: false, hasChanged: f }; +Symbol.metadata ??= Symbol("metadata"), a.litPropertyMetadata ??= /* @__PURE__ */ new WeakMap(); +var y = class extends HTMLElement { + static addInitializer(t3) { + this._$Ei(), (this.l ??= []).push(t3); + } + static get observedAttributes() { + return this.finalize(), this._$Eh && [...this._$Eh.keys()]; + } + static createProperty(t3, s4 = b) { + if (s4.state && (s4.attribute = false), this._$Ei(), this.prototype.hasOwnProperty(t3) && ((s4 = Object.create(s4)).wrapped = true), this.elementProperties.set(t3, s4), !s4.noAccessor) { + const i5 = Symbol(), h3 = this.getPropertyDescriptor(t3, i5, s4); + void 0 !== h3 && e2(this.prototype, t3, h3); + } + } + static getPropertyDescriptor(t3, s4, i5) { + const { get: e4, set: r4 } = h(this.prototype, t3) ?? { get() { + return this[s4]; + }, set(t4) { + this[s4] = t4; + } }; + return { get: e4, set(s5) { + const h3 = e4?.call(this); + r4?.call(this, s5), this.requestUpdate(t3, h3, i5); + }, configurable: true, enumerable: true }; + } + static getPropertyOptions(t3) { + return this.elementProperties.get(t3) ?? b; + } + static _$Ei() { + if (this.hasOwnProperty(d("elementProperties"))) return; + const t3 = n2(this); + t3.finalize(), void 0 !== t3.l && (this.l = [...t3.l]), this.elementProperties = new Map(t3.elementProperties); + } + static finalize() { + if (this.hasOwnProperty(d("finalized"))) return; + if (this.finalized = true, this._$Ei(), this.hasOwnProperty(d("properties"))) { + const t4 = this.properties, s4 = [...r2(t4), ...o2(t4)]; + for (const i5 of s4) this.createProperty(i5, t4[i5]); + } + const t3 = this[Symbol.metadata]; + if (null !== t3) { + const s4 = litPropertyMetadata.get(t3); + if (void 0 !== s4) for (const [t4, i5] of s4) this.elementProperties.set(t4, i5); + } + this._$Eh = /* @__PURE__ */ new Map(); + for (const [t4, s4] of this.elementProperties) { + const i5 = this._$Eu(t4, s4); + void 0 !== i5 && this._$Eh.set(i5, t4); + } + this.elementStyles = this.finalizeStyles(this.styles); + } + static finalizeStyles(s4) { + const i5 = []; + if (Array.isArray(s4)) { + const e4 = new Set(s4.flat(1 / 0).reverse()); + for (const s5 of e4) i5.unshift(c(s5)); + } else void 0 !== s4 && i5.push(c(s4)); + return i5; + } + static _$Eu(t3, s4) { + const i5 = s4.attribute; + return false === i5 ? void 0 : "string" == typeof i5 ? i5 : "string" == typeof t3 ? t3.toLowerCase() : void 0; + } + constructor() { + super(), this._$Ep = void 0, this.isUpdatePending = false, this.hasUpdated = false, this._$Em = null, this._$Ev(); + } + _$Ev() { + this._$ES = new Promise((t3) => this.enableUpdating = t3), this._$AL = /* @__PURE__ */ new Map(), this._$E_(), this.requestUpdate(), this.constructor.l?.forEach((t3) => t3(this)); + } + addController(t3) { + (this._$EO ??= /* @__PURE__ */ new Set()).add(t3), void 0 !== this.renderRoot && this.isConnected && t3.hostConnected?.(); + } + removeController(t3) { + this._$EO?.delete(t3); + } + _$E_() { + const t3 = /* @__PURE__ */ new Map(), s4 = this.constructor.elementProperties; + for (const i5 of s4.keys()) this.hasOwnProperty(i5) && (t3.set(i5, this[i5]), delete this[i5]); + t3.size > 0 && (this._$Ep = t3); + } + createRenderRoot() { + const t3 = this.shadowRoot ?? this.attachShadow(this.constructor.shadowRootOptions); + return S(t3, this.constructor.elementStyles), t3; + } + connectedCallback() { + this.renderRoot ??= this.createRenderRoot(), this.enableUpdating(true), this._$EO?.forEach((t3) => t3.hostConnected?.()); + } + enableUpdating(t3) { + } + disconnectedCallback() { + this._$EO?.forEach((t3) => t3.hostDisconnected?.()); + } + attributeChangedCallback(t3, s4, i5) { + this._$AK(t3, i5); + } + _$ET(t3, s4) { + const i5 = this.constructor.elementProperties.get(t3), e4 = this.constructor._$Eu(t3, i5); + if (void 0 !== e4 && true === i5.reflect) { + const h3 = (void 0 !== i5.converter?.toAttribute ? i5.converter : u).toAttribute(s4, i5.type); + this._$Em = t3, null == h3 ? this.removeAttribute(e4) : this.setAttribute(e4, h3), this._$Em = null; + } + } + _$AK(t3, s4) { + const i5 = this.constructor, e4 = i5._$Eh.get(t3); + if (void 0 !== e4 && this._$Em !== e4) { + const t4 = i5.getPropertyOptions(e4), h3 = "function" == typeof t4.converter ? { fromAttribute: t4.converter } : void 0 !== t4.converter?.fromAttribute ? t4.converter : u; + this._$Em = e4, this[e4] = h3.fromAttribute(s4, t4.type) ?? this._$Ej?.get(e4) ?? null, this._$Em = null; + } + } + requestUpdate(t3, s4, i5) { + if (void 0 !== t3) { + const e4 = this.constructor, h3 = this[t3]; + if (i5 ??= e4.getPropertyOptions(t3), !((i5.hasChanged ?? f)(h3, s4) || i5.useDefault && i5.reflect && h3 === this._$Ej?.get(t3) && !this.hasAttribute(e4._$Eu(t3, i5)))) return; + this.C(t3, s4, i5); + } + false === this.isUpdatePending && (this._$ES = this._$EP()); + } + C(t3, s4, { useDefault: i5, reflect: e4, wrapped: h3 }, r4) { + i5 && !(this._$Ej ??= /* @__PURE__ */ new Map()).has(t3) && (this._$Ej.set(t3, r4 ?? s4 ?? this[t3]), true !== h3 || void 0 !== r4) || (this._$AL.has(t3) || (this.hasUpdated || i5 || (s4 = void 0), this._$AL.set(t3, s4)), true === e4 && this._$Em !== t3 && (this._$Eq ??= /* @__PURE__ */ new Set()).add(t3)); + } + async _$EP() { + this.isUpdatePending = true; + try { + await this._$ES; + } catch (t4) { + Promise.reject(t4); + } + const t3 = this.scheduleUpdate(); + return null != t3 && await t3, !this.isUpdatePending; + } + scheduleUpdate() { + return this.performUpdate(); + } + performUpdate() { + if (!this.isUpdatePending) return; + if (!this.hasUpdated) { + if (this.renderRoot ??= this.createRenderRoot(), this._$Ep) { + for (const [t5, s5] of this._$Ep) this[t5] = s5; + this._$Ep = void 0; + } + const t4 = this.constructor.elementProperties; + if (t4.size > 0) for (const [s5, i5] of t4) { + const { wrapped: t5 } = i5, e4 = this[s5]; + true !== t5 || this._$AL.has(s5) || void 0 === e4 || this.C(s5, void 0, i5, e4); + } + } + let t3 = false; + const s4 = this._$AL; + try { + t3 = this.shouldUpdate(s4), t3 ? (this.willUpdate(s4), this._$EO?.forEach((t4) => t4.hostUpdate?.()), this.update(s4)) : this._$EM(); + } catch (s5) { + throw t3 = false, this._$EM(), s5; + } + t3 && this._$AE(s4); + } + willUpdate(t3) { + } + _$AE(t3) { + this._$EO?.forEach((t4) => t4.hostUpdated?.()), this.hasUpdated || (this.hasUpdated = true, this.firstUpdated(t3)), this.updated(t3); + } + _$EM() { + this._$AL = /* @__PURE__ */ new Map(), this.isUpdatePending = false; + } + get updateComplete() { + return this.getUpdateComplete(); + } + getUpdateComplete() { + return this._$ES; + } + shouldUpdate(t3) { + return true; + } + update(t3) { + this._$Eq &&= this._$Eq.forEach((t4) => this._$ET(t4, this[t4])), this._$EM(); + } + updated(t3) { + } + firstUpdated(t3) { + } +}; +y.elementStyles = [], y.shadowRootOptions = { mode: "open" }, y[d("elementProperties")] = /* @__PURE__ */ new Map(), y[d("finalized")] = /* @__PURE__ */ new Map(), p?.({ ReactiveElement: y }), (a.reactiveElementVersions ??= []).push("2.1.0"); + +// node_modules/lit-html/lit-html.js +var t2 = globalThis; +var i3 = t2.trustedTypes; +var s2 = i3 ? i3.createPolicy("lit-html", { createHTML: (t3) => t3 }) : void 0; +var e3 = "$lit$"; +var h2 = `lit$${Math.random().toFixed(9).slice(2)}$`; +var o3 = "?" + h2; +var n3 = `<${o3}>`; +var r3 = document; +var l2 = () => r3.createComment(""); +var c3 = (t3) => null === t3 || "object" != typeof t3 && "function" != typeof t3; +var a2 = Array.isArray; +var u2 = (t3) => a2(t3) || "function" == typeof t3?.[Symbol.iterator]; +var d2 = "[ \n\f\r]"; +var f2 = /<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g; +var v = /-->/g; +var _ = />/g; +var m = RegExp(`>|${d2}(?:([^\\s"'>=/]+)(${d2}*=${d2}*(?:[^ +\f\r"'\`<>=]|("|')|))|$)`, "g"); +var p2 = /'/g; +var g = /"/g; +var $ = /^(?:script|style|textarea|title)$/i; +var y2 = (t3) => (i5, ...s4) => ({ _$litType$: t3, strings: i5, values: s4 }); +var x = y2(1); +var b2 = y2(2); +var w = y2(3); +var T = Symbol.for("lit-noChange"); +var E = Symbol.for("lit-nothing"); +var A = /* @__PURE__ */ new WeakMap(); +var C = r3.createTreeWalker(r3, 129); +function P(t3, i5) { + if (!a2(t3) || !t3.hasOwnProperty("raw")) throw Error("invalid template strings array"); + return void 0 !== s2 ? s2.createHTML(i5) : i5; +} +var V = (t3, i5) => { + const s4 = t3.length - 1, o5 = []; + let r4, l3 = 2 === i5 ? "" : 3 === i5 ? "" : "", c4 = f2; + for (let i6 = 0; i6 < s4; i6++) { + const s5 = t3[i6]; + let a3, u3, d3 = -1, y3 = 0; + for (; y3 < s5.length && (c4.lastIndex = y3, u3 = c4.exec(s5), null !== u3); ) y3 = c4.lastIndex, c4 === f2 ? "!--" === u3[1] ? c4 = v : void 0 !== u3[1] ? c4 = _ : void 0 !== u3[2] ? ($.test(u3[2]) && (r4 = RegExp("" === u3[0] ? (c4 = r4 ?? f2, d3 = -1) : void 0 === u3[1] ? d3 = -2 : (d3 = c4.lastIndex - u3[2].length, a3 = u3[1], c4 = void 0 === u3[3] ? m : '"' === u3[3] ? g : p2) : c4 === g || c4 === p2 ? c4 = m : c4 === v || c4 === _ ? c4 = f2 : (c4 = m, r4 = void 0); + const x2 = c4 === m && t3[i6 + 1].startsWith("/>") ? " " : ""; + l3 += c4 === f2 ? s5 + n3 : d3 >= 0 ? (o5.push(a3), s5.slice(0, d3) + e3 + s5.slice(d3) + h2 + x2) : s5 + h2 + (-2 === d3 ? i6 : x2); + } + return [P(t3, l3 + (t3[s4] || "") + (2 === i5 ? "" : 3 === i5 ? "" : "")), o5]; +}; +var N = class _N { + constructor({ strings: t3, _$litType$: s4 }, n4) { + let r4; + this.parts = []; + let c4 = 0, a3 = 0; + const u3 = t3.length - 1, d3 = this.parts, [f3, v2] = V(t3, s4); + if (this.el = _N.createElement(f3, n4), C.currentNode = this.el.content, 2 === s4 || 3 === s4) { + const t4 = this.el.content.firstChild; + t4.replaceWith(...t4.childNodes); + } + for (; null !== (r4 = C.nextNode()) && d3.length < u3; ) { + if (1 === r4.nodeType) { + if (r4.hasAttributes()) for (const t4 of r4.getAttributeNames()) if (t4.endsWith(e3)) { + const i5 = v2[a3++], s5 = r4.getAttribute(t4).split(h2), e4 = /([.?@])?(.*)/.exec(i5); + d3.push({ type: 1, index: c4, name: e4[2], strings: s5, ctor: "." === e4[1] ? H : "?" === e4[1] ? I : "@" === e4[1] ? L : k }), r4.removeAttribute(t4); + } else t4.startsWith(h2) && (d3.push({ type: 6, index: c4 }), r4.removeAttribute(t4)); + if ($.test(r4.tagName)) { + const t4 = r4.textContent.split(h2), s5 = t4.length - 1; + if (s5 > 0) { + r4.textContent = i3 ? i3.emptyScript : ""; + for (let i5 = 0; i5 < s5; i5++) r4.append(t4[i5], l2()), C.nextNode(), d3.push({ type: 2, index: ++c4 }); + r4.append(t4[s5], l2()); + } + } + } else if (8 === r4.nodeType) if (r4.data === o3) d3.push({ type: 2, index: c4 }); + else { + let t4 = -1; + for (; -1 !== (t4 = r4.data.indexOf(h2, t4 + 1)); ) d3.push({ type: 7, index: c4 }), t4 += h2.length - 1; + } + c4++; + } + } + static createElement(t3, i5) { + const s4 = r3.createElement("template"); + return s4.innerHTML = t3, s4; + } +}; +function S2(t3, i5, s4 = t3, e4) { + if (i5 === T) return i5; + let h3 = void 0 !== e4 ? s4._$Co?.[e4] : s4._$Cl; + const o5 = c3(i5) ? void 0 : i5._$litDirective$; + return h3?.constructor !== o5 && (h3?._$AO?.(false), void 0 === o5 ? h3 = void 0 : (h3 = new o5(t3), h3._$AT(t3, s4, e4)), void 0 !== e4 ? (s4._$Co ??= [])[e4] = h3 : s4._$Cl = h3), void 0 !== h3 && (i5 = S2(t3, h3._$AS(t3, i5.values), h3, e4)), i5; +} +var M = class { + constructor(t3, i5) { + this._$AV = [], this._$AN = void 0, this._$AD = t3, this._$AM = i5; + } + get parentNode() { + return this._$AM.parentNode; + } + get _$AU() { + return this._$AM._$AU; + } + u(t3) { + const { el: { content: i5 }, parts: s4 } = this._$AD, e4 = (t3?.creationScope ?? r3).importNode(i5, true); + C.currentNode = e4; + let h3 = C.nextNode(), o5 = 0, n4 = 0, l3 = s4[0]; + for (; void 0 !== l3; ) { + if (o5 === l3.index) { + let i6; + 2 === l3.type ? i6 = new R(h3, h3.nextSibling, this, t3) : 1 === l3.type ? i6 = new l3.ctor(h3, l3.name, l3.strings, this, t3) : 6 === l3.type && (i6 = new z(h3, this, t3)), this._$AV.push(i6), l3 = s4[++n4]; + } + o5 !== l3?.index && (h3 = C.nextNode(), o5++); + } + return C.currentNode = r3, e4; + } + p(t3) { + let i5 = 0; + for (const s4 of this._$AV) void 0 !== s4 && (void 0 !== s4.strings ? (s4._$AI(t3, s4, i5), i5 += s4.strings.length - 2) : s4._$AI(t3[i5])), i5++; + } +}; +var R = class _R { + get _$AU() { + return this._$AM?._$AU ?? this._$Cv; + } + constructor(t3, i5, s4, e4) { + this.type = 2, this._$AH = E, this._$AN = void 0, this._$AA = t3, this._$AB = i5, this._$AM = s4, this.options = e4, this._$Cv = e4?.isConnected ?? true; + } + get parentNode() { + let t3 = this._$AA.parentNode; + const i5 = this._$AM; + return void 0 !== i5 && 11 === t3?.nodeType && (t3 = i5.parentNode), t3; + } + get startNode() { + return this._$AA; + } + get endNode() { + return this._$AB; + } + _$AI(t3, i5 = this) { + t3 = S2(this, t3, i5), c3(t3) ? t3 === E || null == t3 || "" === t3 ? (this._$AH !== E && this._$AR(), this._$AH = E) : t3 !== this._$AH && t3 !== T && this._(t3) : void 0 !== t3._$litType$ ? this.$(t3) : void 0 !== t3.nodeType ? this.T(t3) : u2(t3) ? this.k(t3) : this._(t3); + } + O(t3) { + return this._$AA.parentNode.insertBefore(t3, this._$AB); + } + T(t3) { + this._$AH !== t3 && (this._$AR(), this._$AH = this.O(t3)); + } + _(t3) { + this._$AH !== E && c3(this._$AH) ? this._$AA.nextSibling.data = t3 : this.T(r3.createTextNode(t3)), this._$AH = t3; + } + $(t3) { + const { values: i5, _$litType$: s4 } = t3, e4 = "number" == typeof s4 ? this._$AC(t3) : (void 0 === s4.el && (s4.el = N.createElement(P(s4.h, s4.h[0]), this.options)), s4); + if (this._$AH?._$AD === e4) this._$AH.p(i5); + else { + const t4 = new M(e4, this), s5 = t4.u(this.options); + t4.p(i5), this.T(s5), this._$AH = t4; + } + } + _$AC(t3) { + let i5 = A.get(t3.strings); + return void 0 === i5 && A.set(t3.strings, i5 = new N(t3)), i5; + } + k(t3) { + a2(this._$AH) || (this._$AH = [], this._$AR()); + const i5 = this._$AH; + let s4, e4 = 0; + for (const h3 of t3) e4 === i5.length ? i5.push(s4 = new _R(this.O(l2()), this.O(l2()), this, this.options)) : s4 = i5[e4], s4._$AI(h3), e4++; + e4 < i5.length && (this._$AR(s4 && s4._$AB.nextSibling, e4), i5.length = e4); + } + _$AR(t3 = this._$AA.nextSibling, i5) { + for (this._$AP?.(false, true, i5); t3 && t3 !== this._$AB; ) { + const i6 = t3.nextSibling; + t3.remove(), t3 = i6; + } + } + setConnected(t3) { + void 0 === this._$AM && (this._$Cv = t3, this._$AP?.(t3)); + } +}; +var k = class { + get tagName() { + return this.element.tagName; + } + get _$AU() { + return this._$AM._$AU; + } + constructor(t3, i5, s4, e4, h3) { + this.type = 1, this._$AH = E, this._$AN = void 0, this.element = t3, this.name = i5, this._$AM = e4, this.options = h3, s4.length > 2 || "" !== s4[0] || "" !== s4[1] ? (this._$AH = Array(s4.length - 1).fill(new String()), this.strings = s4) : this._$AH = E; + } + _$AI(t3, i5 = this, s4, e4) { + const h3 = this.strings; + let o5 = false; + if (void 0 === h3) t3 = S2(this, t3, i5, 0), o5 = !c3(t3) || t3 !== this._$AH && t3 !== T, o5 && (this._$AH = t3); + else { + const e5 = t3; + let n4, r4; + for (t3 = h3[0], n4 = 0; n4 < h3.length - 1; n4++) r4 = S2(this, e5[s4 + n4], i5, n4), r4 === T && (r4 = this._$AH[n4]), o5 ||= !c3(r4) || r4 !== this._$AH[n4], r4 === E ? t3 = E : t3 !== E && (t3 += (r4 ?? "") + h3[n4 + 1]), this._$AH[n4] = r4; + } + o5 && !e4 && this.j(t3); + } + j(t3) { + t3 === E ? this.element.removeAttribute(this.name) : this.element.setAttribute(this.name, t3 ?? ""); + } +}; +var H = class extends k { + constructor() { + super(...arguments), this.type = 3; + } + j(t3) { + this.element[this.name] = t3 === E ? void 0 : t3; + } +}; +var I = class extends k { + constructor() { + super(...arguments), this.type = 4; + } + j(t3) { + this.element.toggleAttribute(this.name, !!t3 && t3 !== E); + } +}; +var L = class extends k { + constructor(t3, i5, s4, e4, h3) { + super(t3, i5, s4, e4, h3), this.type = 5; + } + _$AI(t3, i5 = this) { + if ((t3 = S2(this, t3, i5, 0) ?? E) === T) return; + const s4 = this._$AH, e4 = t3 === E && s4 !== E || t3.capture !== s4.capture || t3.once !== s4.once || t3.passive !== s4.passive, h3 = t3 !== E && (s4 === E || e4); + e4 && this.element.removeEventListener(this.name, this, s4), h3 && this.element.addEventListener(this.name, this, t3), this._$AH = t3; + } + handleEvent(t3) { + "function" == typeof this._$AH ? this._$AH.call(this.options?.host ?? this.element, t3) : this._$AH.handleEvent(t3); + } +}; +var z = class { + constructor(t3, i5, s4) { + this.element = t3, this.type = 6, this._$AN = void 0, this._$AM = i5, this.options = s4; + } + get _$AU() { + return this._$AM._$AU; + } + _$AI(t3) { + S2(this, t3); + } +}; +var j = t2.litHtmlPolyfillSupport; +j?.(N, R), (t2.litHtmlVersions ??= []).push("3.3.0"); +var B = (t3, i5, s4) => { + const e4 = s4?.renderBefore ?? i5; + let h3 = e4._$litPart$; + if (void 0 === h3) { + const t4 = s4?.renderBefore ?? null; + e4._$litPart$ = h3 = new R(i5.insertBefore(l2(), t4), t4, void 0, s4 ?? {}); + } + return h3._$AI(t3), h3; +}; + +// node_modules/lit-element/lit-element.js +var s3 = globalThis; +var i4 = class extends y { + constructor() { + super(...arguments), this.renderOptions = { host: this }, this._$Do = void 0; + } + createRenderRoot() { + const t3 = super.createRenderRoot(); + return this.renderOptions.renderBefore ??= t3.firstChild, t3; + } + update(t3) { + const r4 = this.render(); + this.hasUpdated || (this.renderOptions.isConnected = this.isConnected), super.update(t3), this._$Do = B(r4, this.renderRoot, this.renderOptions); + } + connectedCallback() { + super.connectedCallback(), this._$Do?.setConnected(true); + } + disconnectedCallback() { + super.disconnectedCallback(), this._$Do?.setConnected(false); + } + render() { + return T; + } +}; +i4._$litElement$ = true, i4["finalized"] = true, s3.litElementHydrateSupport?.({ LitElement: i4 }); +var o4 = s3.litElementPolyfillSupport; +o4?.({ LitElement: i4 }); +(s3.litElementVersions ??= []).push("4.2.0"); + +// node_modules/orderedmap/dist/index.js +function OrderedMap(content) { + this.content = content; +} +OrderedMap.prototype = { + constructor: OrderedMap, + find: function(key) { + for (var i5 = 0; i5 < this.content.length; i5 += 2) + if (this.content[i5] === key) return i5; + return -1; + }, + // :: (string) → ?any + // Retrieve the value stored under `key`, or return undefined when + // no such key exists. + get: function(key) { + var found2 = this.find(key); + return found2 == -1 ? void 0 : this.content[found2 + 1]; + }, + // :: (string, any, ?string) → OrderedMap + // Create a new map by replacing the value of `key` with a new + // value, or adding a binding to the end of the map. If `newKey` is + // given, the key of the binding will be replaced with that key. + update: function(key, value, newKey) { + var self = newKey && newKey != key ? this.remove(newKey) : this; + var found2 = self.find(key), content = self.content.slice(); + if (found2 == -1) { + content.push(newKey || key, value); + } else { + content[found2 + 1] = value; + if (newKey) content[found2] = newKey; + } + return new OrderedMap(content); + }, + // :: (string) → OrderedMap + // Return a map with the given key removed, if it existed. + remove: function(key) { + var found2 = this.find(key); + if (found2 == -1) return this; + var content = this.content.slice(); + content.splice(found2, 2); + return new OrderedMap(content); + }, + // :: (string, any) → OrderedMap + // Add a new key to the start of the map. + addToStart: function(key, value) { + return new OrderedMap([key, value].concat(this.remove(key).content)); + }, + // :: (string, any) → OrderedMap + // Add a new key to the end of the map. + addToEnd: function(key, value) { + var content = this.remove(key).content.slice(); + content.push(key, value); + return new OrderedMap(content); + }, + // :: (string, string, any) → OrderedMap + // Add a key after the given key. If `place` is not found, the new + // key is added to the end. + addBefore: function(place, key, value) { + var without = this.remove(key), content = without.content.slice(); + var found2 = without.find(place); + content.splice(found2 == -1 ? content.length : found2, 0, key, value); + return new OrderedMap(content); + }, + // :: ((key: string, value: any)) + // Call the given function for each key/value pair in the map, in + // order. + forEach: function(f3) { + for (var i5 = 0; i5 < this.content.length; i5 += 2) + f3(this.content[i5], this.content[i5 + 1]); + }, + // :: (union) → OrderedMap + // Create a new map by prepending the keys in this map that don't + // appear in `map` before the keys in `map`. + prepend: function(map) { + map = OrderedMap.from(map); + if (!map.size) return this; + return new OrderedMap(map.content.concat(this.subtract(map).content)); + }, + // :: (union) → OrderedMap + // Create a new map by appending the keys in this map that don't + // appear in `map` after the keys in `map`. + append: function(map) { + map = OrderedMap.from(map); + if (!map.size) return this; + return new OrderedMap(this.subtract(map).content.concat(map.content)); + }, + // :: (union) → OrderedMap + // Create a map containing all the keys in this map that don't + // appear in `map`. + subtract: function(map) { + var result = this; + map = OrderedMap.from(map); + for (var i5 = 0; i5 < map.content.length; i5 += 2) + result = result.remove(map.content[i5]); + return result; + }, + // :: () → Object + // Turn ordered map into a plain object. + toObject: function() { + var result = {}; + this.forEach(function(key, value) { + result[key] = value; + }); + return result; + }, + // :: number + // The amount of keys in this map. + get size() { + return this.content.length >> 1; + } +}; +OrderedMap.from = function(value) { + if (value instanceof OrderedMap) return value; + var content = []; + if (value) for (var prop in value) content.push(prop, value[prop]); + return new OrderedMap(content); +}; +var dist_default = OrderedMap; + +// node_modules/prosemirror-model/dist/index.js +function findDiffStart(a3, b3, pos) { + for (let i5 = 0; ; i5++) { + if (i5 == a3.childCount || i5 == b3.childCount) + return a3.childCount == b3.childCount ? null : pos; + let childA = a3.child(i5), childB = b3.child(i5); + if (childA == childB) { + pos += childA.nodeSize; + continue; + } + if (!childA.sameMarkup(childB)) + return pos; + if (childA.isText && childA.text != childB.text) { + for (let j2 = 0; childA.text[j2] == childB.text[j2]; j2++) + pos++; + return pos; + } + if (childA.content.size || childB.content.size) { + let inner = findDiffStart(childA.content, childB.content, pos + 1); + if (inner != null) + return inner; + } + pos += childA.nodeSize; + } +} +function findDiffEnd(a3, b3, posA, posB) { + for (let iA = a3.childCount, iB = b3.childCount; ; ) { + if (iA == 0 || iB == 0) + return iA == iB ? null : { a: posA, b: posB }; + let childA = a3.child(--iA), childB = b3.child(--iB), size = childA.nodeSize; + if (childA == childB) { + posA -= size; + posB -= size; + continue; + } + if (!childA.sameMarkup(childB)) + return { a: posA, b: posB }; + if (childA.isText && childA.text != childB.text) { + let same = 0, minSize = Math.min(childA.text.length, childB.text.length); + while (same < minSize && childA.text[childA.text.length - same - 1] == childB.text[childB.text.length - same - 1]) { + same++; + posA--; + posB--; + } + return { a: posA, b: posB }; + } + if (childA.content.size || childB.content.size) { + let inner = findDiffEnd(childA.content, childB.content, posA - 1, posB - 1); + if (inner) + return inner; + } + posA -= size; + posB -= size; + } +} +var Fragment = class _Fragment { + /** + @internal + */ + constructor(content, size) { + this.content = content; + this.size = size || 0; + if (size == null) + for (let i5 = 0; i5 < content.length; i5++) + this.size += content[i5].nodeSize; + } + /** + Invoke a callback for all descendant nodes between the given two + positions (relative to start of this fragment). Doesn't descend + into a node when the callback returns `false`. + */ + nodesBetween(from, to, f3, nodeStart = 0, parent) { + for (let i5 = 0, pos = 0; pos < to; i5++) { + let child = this.content[i5], end = pos + child.nodeSize; + if (end > from && f3(child, nodeStart + pos, parent || null, i5) !== false && child.content.size) { + let start = pos + 1; + child.nodesBetween(Math.max(0, from - start), Math.min(child.content.size, to - start), f3, nodeStart + start); + } + pos = end; + } + } + /** + Call the given callback for every descendant node. `pos` will be + relative to the start of the fragment. The callback may return + `false` to prevent traversal of a given node's children. + */ + descendants(f3) { + this.nodesBetween(0, this.size, f3); + } + /** + Extract the text between `from` and `to`. See the same method on + [`Node`](https://prosemirror.net/docs/ref/#model.Node.textBetween). + */ + textBetween(from, to, blockSeparator, leafText) { + let text = "", first2 = true; + this.nodesBetween(from, to, (node, pos) => { + let nodeText = node.isText ? node.text.slice(Math.max(from, pos) - pos, to - pos) : !node.isLeaf ? "" : leafText ? typeof leafText === "function" ? leafText(node) : leafText : node.type.spec.leafText ? node.type.spec.leafText(node) : ""; + if (node.isBlock && (node.isLeaf && nodeText || node.isTextblock) && blockSeparator) { + if (first2) + first2 = false; + else + text += blockSeparator; + } + text += nodeText; + }, 0); + return text; + } + /** + Create a new fragment containing the combined content of this + fragment and the other. + */ + append(other) { + if (!other.size) + return this; + if (!this.size) + return other; + let last = this.lastChild, first2 = other.firstChild, content = this.content.slice(), i5 = 0; + if (last.isText && last.sameMarkup(first2)) { + content[content.length - 1] = last.withText(last.text + first2.text); + i5 = 1; + } + for (; i5 < other.content.length; i5++) + content.push(other.content[i5]); + return new _Fragment(content, this.size + other.size); + } + /** + Cut out the sub-fragment between the two given positions. + */ + cut(from, to = this.size) { + if (from == 0 && to == this.size) + return this; + let result = [], size = 0; + if (to > from) + for (let i5 = 0, pos = 0; pos < to; i5++) { + let child = this.content[i5], end = pos + child.nodeSize; + if (end > from) { + if (pos < from || end > to) { + if (child.isText) + child = child.cut(Math.max(0, from - pos), Math.min(child.text.length, to - pos)); + else + child = child.cut(Math.max(0, from - pos - 1), Math.min(child.content.size, to - pos - 1)); + } + result.push(child); + size += child.nodeSize; + } + pos = end; + } + return new _Fragment(result, size); + } + /** + @internal + */ + cutByIndex(from, to) { + if (from == to) + return _Fragment.empty; + if (from == 0 && to == this.content.length) + return this; + return new _Fragment(this.content.slice(from, to)); + } + /** + Create a new fragment in which the node at the given index is + replaced by the given node. + */ + replaceChild(index, node) { + let current = this.content[index]; + if (current == node) + return this; + let copy2 = this.content.slice(); + let size = this.size + node.nodeSize - current.nodeSize; + copy2[index] = node; + return new _Fragment(copy2, size); + } + /** + Create a new fragment by prepending the given node to this + fragment. + */ + addToStart(node) { + return new _Fragment([node].concat(this.content), this.size + node.nodeSize); + } + /** + Create a new fragment by appending the given node to this + fragment. + */ + addToEnd(node) { + return new _Fragment(this.content.concat(node), this.size + node.nodeSize); + } + /** + Compare this fragment to another one. + */ + eq(other) { + if (this.content.length != other.content.length) + return false; + for (let i5 = 0; i5 < this.content.length; i5++) + if (!this.content[i5].eq(other.content[i5])) + return false; + return true; + } + /** + The first child of the fragment, or `null` if it is empty. + */ + get firstChild() { + return this.content.length ? this.content[0] : null; + } + /** + The last child of the fragment, or `null` if it is empty. + */ + get lastChild() { + return this.content.length ? this.content[this.content.length - 1] : null; + } + /** + The number of child nodes in this fragment. + */ + get childCount() { + return this.content.length; + } + /** + Get the child node at the given index. Raise an error when the + index is out of range. + */ + child(index) { + let found2 = this.content[index]; + if (!found2) + throw new RangeError("Index " + index + " out of range for " + this); + return found2; + } + /** + Get the child node at the given index, if it exists. + */ + maybeChild(index) { + return this.content[index] || null; + } + /** + Call `f` for every child node, passing the node, its offset + into this parent node, and its index. + */ + forEach(f3) { + for (let i5 = 0, p3 = 0; i5 < this.content.length; i5++) { + let child = this.content[i5]; + f3(child, p3, i5); + p3 += child.nodeSize; + } + } + /** + Find the first position at which this fragment and another + fragment differ, or `null` if they are the same. + */ + findDiffStart(other, pos = 0) { + return findDiffStart(this, other, pos); + } + /** + Find the first position, searching from the end, at which this + fragment and the given fragment differ, or `null` if they are + the same. Since this position will not be the same in both + nodes, an object with two separate positions is returned. + */ + findDiffEnd(other, pos = this.size, otherPos = other.size) { + return findDiffEnd(this, other, pos, otherPos); + } + /** + Find the index and inner offset corresponding to a given relative + position in this fragment. The result object will be reused + (overwritten) the next time the function is called. @internal + */ + findIndex(pos, round = -1) { + if (pos == 0) + return retIndex(0, pos); + if (pos == this.size) + return retIndex(this.content.length, pos); + if (pos > this.size || pos < 0) + throw new RangeError(`Position ${pos} outside of fragment (${this})`); + for (let i5 = 0, curPos = 0; ; i5++) { + let cur = this.child(i5), end = curPos + cur.nodeSize; + if (end >= pos) { + if (end == pos || round > 0) + return retIndex(i5 + 1, end); + return retIndex(i5, curPos); + } + curPos = end; + } + } + /** + Return a debugging string that describes this fragment. + */ + toString() { + return "<" + this.toStringInner() + ">"; + } + /** + @internal + */ + toStringInner() { + return this.content.join(", "); + } + /** + Create a JSON-serializeable representation of this fragment. + */ + toJSON() { + return this.content.length ? this.content.map((n4) => n4.toJSON()) : null; + } + /** + Deserialize a fragment from its JSON representation. + */ + static fromJSON(schema, value) { + if (!value) + return _Fragment.empty; + if (!Array.isArray(value)) + throw new RangeError("Invalid input for Fragment.fromJSON"); + return new _Fragment(value.map(schema.nodeFromJSON)); + } + /** + Build a fragment from an array of nodes. Ensures that adjacent + text nodes with the same marks are joined together. + */ + static fromArray(array) { + if (!array.length) + return _Fragment.empty; + let joined, size = 0; + for (let i5 = 0; i5 < array.length; i5++) { + let node = array[i5]; + size += node.nodeSize; + if (i5 && node.isText && array[i5 - 1].sameMarkup(node)) { + if (!joined) + joined = array.slice(0, i5); + joined[joined.length - 1] = node.withText(joined[joined.length - 1].text + node.text); + } else if (joined) { + joined.push(node); + } + } + return new _Fragment(joined || array, size); + } + /** + Create a fragment from something that can be interpreted as a + set of nodes. For `null`, it returns the empty fragment. For a + fragment, the fragment itself. For a node or array of nodes, a + fragment containing those nodes. + */ + static from(nodes) { + if (!nodes) + return _Fragment.empty; + if (nodes instanceof _Fragment) + return nodes; + if (Array.isArray(nodes)) + return this.fromArray(nodes); + if (nodes.attrs) + return new _Fragment([nodes], nodes.nodeSize); + throw new RangeError("Can not convert " + nodes + " to a Fragment" + (nodes.nodesBetween ? " (looks like multiple versions of prosemirror-model were loaded)" : "")); + } +}; +Fragment.empty = new Fragment([], 0); +var found = { index: 0, offset: 0 }; +function retIndex(index, offset) { + found.index = index; + found.offset = offset; + return found; +} +function compareDeep(a3, b3) { + if (a3 === b3) + return true; + if (!(a3 && typeof a3 == "object") || !(b3 && typeof b3 == "object")) + return false; + let array = Array.isArray(a3); + if (Array.isArray(b3) != array) + return false; + if (array) { + if (a3.length != b3.length) + return false; + for (let i5 = 0; i5 < a3.length; i5++) + if (!compareDeep(a3[i5], b3[i5])) + return false; + } else { + for (let p3 in a3) + if (!(p3 in b3) || !compareDeep(a3[p3], b3[p3])) + return false; + for (let p3 in b3) + if (!(p3 in a3)) + return false; + } + return true; +} +var Mark = class _Mark { + /** + @internal + */ + constructor(type, attrs) { + this.type = type; + this.attrs = attrs; + } + /** + Given a set of marks, create a new set which contains this one as + well, in the right position. If this mark is already in the set, + the set itself is returned. If any marks that are set to be + [exclusive](https://prosemirror.net/docs/ref/#model.MarkSpec.excludes) with this mark are present, + those are replaced by this one. + */ + addToSet(set) { + let copy2, placed = false; + for (let i5 = 0; i5 < set.length; i5++) { + let other = set[i5]; + if (this.eq(other)) + return set; + if (this.type.excludes(other.type)) { + if (!copy2) + copy2 = set.slice(0, i5); + } else if (other.type.excludes(this.type)) { + return set; + } else { + if (!placed && other.type.rank > this.type.rank) { + if (!copy2) + copy2 = set.slice(0, i5); + copy2.push(this); + placed = true; + } + if (copy2) + copy2.push(other); + } + } + if (!copy2) + copy2 = set.slice(); + if (!placed) + copy2.push(this); + return copy2; + } + /** + Remove this mark from the given set, returning a new set. If this + mark is not in the set, the set itself is returned. + */ + removeFromSet(set) { + for (let i5 = 0; i5 < set.length; i5++) + if (this.eq(set[i5])) + return set.slice(0, i5).concat(set.slice(i5 + 1)); + return set; + } + /** + Test whether this mark is in the given set of marks. + */ + isInSet(set) { + for (let i5 = 0; i5 < set.length; i5++) + if (this.eq(set[i5])) + return true; + return false; + } + /** + Test whether this mark has the same type and attributes as + another mark. + */ + eq(other) { + return this == other || this.type == other.type && compareDeep(this.attrs, other.attrs); + } + /** + Convert this mark to a JSON-serializeable representation. + */ + toJSON() { + let obj = { type: this.type.name }; + for (let _2 in this.attrs) { + obj.attrs = this.attrs; + break; + } + return obj; + } + /** + Deserialize a mark from JSON. + */ + static fromJSON(schema, json) { + if (!json) + throw new RangeError("Invalid input for Mark.fromJSON"); + let type = schema.marks[json.type]; + if (!type) + throw new RangeError(`There is no mark type ${json.type} in this schema`); + let mark = type.create(json.attrs); + type.checkAttrs(mark.attrs); + return mark; + } + /** + Test whether two sets of marks are identical. + */ + static sameSet(a3, b3) { + if (a3 == b3) + return true; + if (a3.length != b3.length) + return false; + for (let i5 = 0; i5 < a3.length; i5++) + if (!a3[i5].eq(b3[i5])) + return false; + return true; + } + /** + Create a properly sorted mark set from null, a single mark, or an + unsorted array of marks. + */ + static setFrom(marks) { + if (!marks || Array.isArray(marks) && marks.length == 0) + return _Mark.none; + if (marks instanceof _Mark) + return [marks]; + let copy2 = marks.slice(); + copy2.sort((a3, b3) => a3.type.rank - b3.type.rank); + return copy2; + } +}; +Mark.none = []; +var ReplaceError = class extends Error { +}; +var Slice = class _Slice { + /** + Create a slice. When specifying a non-zero open depth, you must + make sure that there are nodes of at least that depth at the + appropriate side of the fragment—i.e. if the fragment is an + empty paragraph node, `openStart` and `openEnd` can't be greater + than 1. + + It is not necessary for the content of open nodes to conform to + the schema's content constraints, though it should be a valid + start/end/middle for such a node, depending on which sides are + open. + */ + constructor(content, openStart, openEnd) { + this.content = content; + this.openStart = openStart; + this.openEnd = openEnd; + } + /** + The size this slice would add when inserted into a document. + */ + get size() { + return this.content.size - this.openStart - this.openEnd; + } + /** + @internal + */ + insertAt(pos, fragment) { + let content = insertInto(this.content, pos + this.openStart, fragment); + return content && new _Slice(content, this.openStart, this.openEnd); + } + /** + @internal + */ + removeBetween(from, to) { + return new _Slice(removeRange(this.content, from + this.openStart, to + this.openStart), this.openStart, this.openEnd); + } + /** + Tests whether this slice is equal to another slice. + */ + eq(other) { + return this.content.eq(other.content) && this.openStart == other.openStart && this.openEnd == other.openEnd; + } + /** + @internal + */ + toString() { + return this.content + "(" + this.openStart + "," + this.openEnd + ")"; + } + /** + Convert a slice to a JSON-serializable representation. + */ + toJSON() { + if (!this.content.size) + return null; + let json = { content: this.content.toJSON() }; + if (this.openStart > 0) + json.openStart = this.openStart; + if (this.openEnd > 0) + json.openEnd = this.openEnd; + return json; + } + /** + Deserialize a slice from its JSON representation. + */ + static fromJSON(schema, json) { + if (!json) + return _Slice.empty; + let openStart = json.openStart || 0, openEnd = json.openEnd || 0; + if (typeof openStart != "number" || typeof openEnd != "number") + throw new RangeError("Invalid input for Slice.fromJSON"); + return new _Slice(Fragment.fromJSON(schema, json.content), openStart, openEnd); + } + /** + Create a slice from a fragment by taking the maximum possible + open value on both side of the fragment. + */ + static maxOpen(fragment, openIsolating = true) { + let openStart = 0, openEnd = 0; + for (let n4 = fragment.firstChild; n4 && !n4.isLeaf && (openIsolating || !n4.type.spec.isolating); n4 = n4.firstChild) + openStart++; + for (let n4 = fragment.lastChild; n4 && !n4.isLeaf && (openIsolating || !n4.type.spec.isolating); n4 = n4.lastChild) + openEnd++; + return new _Slice(fragment, openStart, openEnd); + } +}; +Slice.empty = new Slice(Fragment.empty, 0, 0); +function removeRange(content, from, to) { + let { index, offset } = content.findIndex(from), child = content.maybeChild(index); + let { index: indexTo, offset: offsetTo } = content.findIndex(to); + if (offset == from || child.isText) { + if (offsetTo != to && !content.child(indexTo).isText) + throw new RangeError("Removing non-flat range"); + return content.cut(0, from).append(content.cut(to)); + } + if (index != indexTo) + throw new RangeError("Removing non-flat range"); + return content.replaceChild(index, child.copy(removeRange(child.content, from - offset - 1, to - offset - 1))); +} +function insertInto(content, dist, insert, parent) { + let { index, offset } = content.findIndex(dist), child = content.maybeChild(index); + if (offset == dist || child.isText) { + if (parent && !parent.canReplace(index, index, insert)) + return null; + return content.cut(0, dist).append(insert).append(content.cut(dist)); + } + let inner = insertInto(child.content, dist - offset - 1, insert); + return inner && content.replaceChild(index, child.copy(inner)); +} +function replace($from, $to, slice) { + if (slice.openStart > $from.depth) + throw new ReplaceError("Inserted content deeper than insertion position"); + if ($from.depth - slice.openStart != $to.depth - slice.openEnd) + throw new ReplaceError("Inconsistent open depths"); + return replaceOuter($from, $to, slice, 0); +} +function replaceOuter($from, $to, slice, depth) { + let index = $from.index(depth), node = $from.node(depth); + if (index == $to.index(depth) && depth < $from.depth - slice.openStart) { + let inner = replaceOuter($from, $to, slice, depth + 1); + return node.copy(node.content.replaceChild(index, inner)); + } else if (!slice.content.size) { + return close(node, replaceTwoWay($from, $to, depth)); + } else if (!slice.openStart && !slice.openEnd && $from.depth == depth && $to.depth == depth) { + let parent = $from.parent, content = parent.content; + return close(parent, content.cut(0, $from.parentOffset).append(slice.content).append(content.cut($to.parentOffset))); + } else { + let { start, end } = prepareSliceForReplace(slice, $from); + return close(node, replaceThreeWay($from, start, end, $to, depth)); + } +} +function checkJoin(main, sub) { + if (!sub.type.compatibleContent(main.type)) + throw new ReplaceError("Cannot join " + sub.type.name + " onto " + main.type.name); +} +function joinable($before, $after, depth) { + let node = $before.node(depth); + checkJoin(node, $after.node(depth)); + return node; +} +function addNode(child, target) { + let last = target.length - 1; + if (last >= 0 && child.isText && child.sameMarkup(target[last])) + target[last] = child.withText(target[last].text + child.text); + else + target.push(child); +} +function addRange($start, $end, depth, target) { + let node = ($end || $start).node(depth); + let startIndex = 0, endIndex = $end ? $end.index(depth) : node.childCount; + if ($start) { + startIndex = $start.index(depth); + if ($start.depth > depth) { + startIndex++; + } else if ($start.textOffset) { + addNode($start.nodeAfter, target); + startIndex++; + } + } + for (let i5 = startIndex; i5 < endIndex; i5++) + addNode(node.child(i5), target); + if ($end && $end.depth == depth && $end.textOffset) + addNode($end.nodeBefore, target); +} +function close(node, content) { + node.type.checkContent(content); + return node.copy(content); +} +function replaceThreeWay($from, $start, $end, $to, depth) { + let openStart = $from.depth > depth && joinable($from, $start, depth + 1); + let openEnd = $to.depth > depth && joinable($end, $to, depth + 1); + let content = []; + addRange(null, $from, depth, content); + if (openStart && openEnd && $start.index(depth) == $end.index(depth)) { + checkJoin(openStart, openEnd); + addNode(close(openStart, replaceThreeWay($from, $start, $end, $to, depth + 1)), content); + } else { + if (openStart) + addNode(close(openStart, replaceTwoWay($from, $start, depth + 1)), content); + addRange($start, $end, depth, content); + if (openEnd) + addNode(close(openEnd, replaceTwoWay($end, $to, depth + 1)), content); + } + addRange($to, null, depth, content); + return new Fragment(content); +} +function replaceTwoWay($from, $to, depth) { + let content = []; + addRange(null, $from, depth, content); + if ($from.depth > depth) { + let type = joinable($from, $to, depth + 1); + addNode(close(type, replaceTwoWay($from, $to, depth + 1)), content); + } + addRange($to, null, depth, content); + return new Fragment(content); +} +function prepareSliceForReplace(slice, $along) { + let extra = $along.depth - slice.openStart, parent = $along.node(extra); + let node = parent.copy(slice.content); + for (let i5 = extra - 1; i5 >= 0; i5--) + node = $along.node(i5).copy(Fragment.from(node)); + return { + start: node.resolveNoCache(slice.openStart + extra), + end: node.resolveNoCache(node.content.size - slice.openEnd - extra) + }; +} +var ResolvedPos = class _ResolvedPos { + /** + @internal + */ + constructor(pos, path, parentOffset) { + this.pos = pos; + this.path = path; + this.parentOffset = parentOffset; + this.depth = path.length / 3 - 1; + } + /** + @internal + */ + resolveDepth(val) { + if (val == null) + return this.depth; + if (val < 0) + return this.depth + val; + return val; + } + /** + The parent node that the position points into. Note that even if + a position points into a text node, that node is not considered + the parent—text nodes are ‘flat’ in this model, and have no content. + */ + get parent() { + return this.node(this.depth); + } + /** + The root node in which the position was resolved. + */ + get doc() { + return this.node(0); + } + /** + The ancestor node at the given level. `p.node(p.depth)` is the + same as `p.parent`. + */ + node(depth) { + return this.path[this.resolveDepth(depth) * 3]; + } + /** + The index into the ancestor at the given level. If this points + at the 3rd node in the 2nd paragraph on the top level, for + example, `p.index(0)` is 1 and `p.index(1)` is 2. + */ + index(depth) { + return this.path[this.resolveDepth(depth) * 3 + 1]; + } + /** + The index pointing after this position into the ancestor at the + given level. + */ + indexAfter(depth) { + depth = this.resolveDepth(depth); + return this.index(depth) + (depth == this.depth && !this.textOffset ? 0 : 1); + } + /** + The (absolute) position at the start of the node at the given + level. + */ + start(depth) { + depth = this.resolveDepth(depth); + return depth == 0 ? 0 : this.path[depth * 3 - 1] + 1; + } + /** + The (absolute) position at the end of the node at the given + level. + */ + end(depth) { + depth = this.resolveDepth(depth); + return this.start(depth) + this.node(depth).content.size; + } + /** + The (absolute) position directly before the wrapping node at the + given level, or, when `depth` is `this.depth + 1`, the original + position. + */ + before(depth) { + depth = this.resolveDepth(depth); + if (!depth) + throw new RangeError("There is no position before the top-level node"); + return depth == this.depth + 1 ? this.pos : this.path[depth * 3 - 1]; + } + /** + The (absolute) position directly after the wrapping node at the + given level, or the original position when `depth` is `this.depth + 1`. + */ + after(depth) { + depth = this.resolveDepth(depth); + if (!depth) + throw new RangeError("There is no position after the top-level node"); + return depth == this.depth + 1 ? this.pos : this.path[depth * 3 - 1] + this.path[depth * 3].nodeSize; + } + /** + When this position points into a text node, this returns the + distance between the position and the start of the text node. + Will be zero for positions that point between nodes. + */ + get textOffset() { + return this.pos - this.path[this.path.length - 1]; + } + /** + Get the node directly after the position, if any. If the position + points into a text node, only the part of that node after the + position is returned. + */ + get nodeAfter() { + let parent = this.parent, index = this.index(this.depth); + if (index == parent.childCount) + return null; + let dOff = this.pos - this.path[this.path.length - 1], child = parent.child(index); + return dOff ? parent.child(index).cut(dOff) : child; + } + /** + Get the node directly before the position, if any. If the + position points into a text node, only the part of that node + before the position is returned. + */ + get nodeBefore() { + let index = this.index(this.depth); + let dOff = this.pos - this.path[this.path.length - 1]; + if (dOff) + return this.parent.child(index).cut(0, dOff); + return index == 0 ? null : this.parent.child(index - 1); + } + /** + Get the position at the given index in the parent node at the + given depth (which defaults to `this.depth`). + */ + posAtIndex(index, depth) { + depth = this.resolveDepth(depth); + let node = this.path[depth * 3], pos = depth == 0 ? 0 : this.path[depth * 3 - 1] + 1; + for (let i5 = 0; i5 < index; i5++) + pos += node.child(i5).nodeSize; + return pos; + } + /** + Get the marks at this position, factoring in the surrounding + marks' [`inclusive`](https://prosemirror.net/docs/ref/#model.MarkSpec.inclusive) property. If the + position is at the start of a non-empty node, the marks of the + node after it (if any) are returned. + */ + marks() { + let parent = this.parent, index = this.index(); + if (parent.content.size == 0) + return Mark.none; + if (this.textOffset) + return parent.child(index).marks; + let main = parent.maybeChild(index - 1), other = parent.maybeChild(index); + if (!main) { + let tmp = main; + main = other; + other = tmp; + } + let marks = main.marks; + for (var i5 = 0; i5 < marks.length; i5++) + if (marks[i5].type.spec.inclusive === false && (!other || !marks[i5].isInSet(other.marks))) + marks = marks[i5--].removeFromSet(marks); + return marks; + } + /** + Get the marks after the current position, if any, except those + that are non-inclusive and not present at position `$end`. This + is mostly useful for getting the set of marks to preserve after a + deletion. Will return `null` if this position is at the end of + its parent node or its parent node isn't a textblock (in which + case no marks should be preserved). + */ + marksAcross($end) { + let after = this.parent.maybeChild(this.index()); + if (!after || !after.isInline) + return null; + let marks = after.marks, next = $end.parent.maybeChild($end.index()); + for (var i5 = 0; i5 < marks.length; i5++) + if (marks[i5].type.spec.inclusive === false && (!next || !marks[i5].isInSet(next.marks))) + marks = marks[i5--].removeFromSet(marks); + return marks; + } + /** + The depth up to which this position and the given (non-resolved) + position share the same parent nodes. + */ + sharedDepth(pos) { + for (let depth = this.depth; depth > 0; depth--) + if (this.start(depth) <= pos && this.end(depth) >= pos) + return depth; + return 0; + } + /** + Returns a range based on the place where this position and the + given position diverge around block content. If both point into + the same textblock, for example, a range around that textblock + will be returned. If they point into different blocks, the range + around those blocks in their shared ancestor is returned. You can + pass in an optional predicate that will be called with a parent + node to see if a range into that parent is acceptable. + */ + blockRange(other = this, pred) { + if (other.pos < this.pos) + return other.blockRange(this); + for (let d3 = this.depth - (this.parent.inlineContent || this.pos == other.pos ? 1 : 0); d3 >= 0; d3--) + if (other.pos <= this.end(d3) && (!pred || pred(this.node(d3)))) + return new NodeRange(this, other, d3); + return null; + } + /** + Query whether the given position shares the same parent node. + */ + sameParent(other) { + return this.pos - this.parentOffset == other.pos - other.parentOffset; + } + /** + Return the greater of this and the given position. + */ + max(other) { + return other.pos > this.pos ? other : this; + } + /** + Return the smaller of this and the given position. + */ + min(other) { + return other.pos < this.pos ? other : this; + } + /** + @internal + */ + toString() { + let str = ""; + for (let i5 = 1; i5 <= this.depth; i5++) + str += (str ? "/" : "") + this.node(i5).type.name + "_" + this.index(i5 - 1); + return str + ":" + this.parentOffset; + } + /** + @internal + */ + static resolve(doc3, pos) { + if (!(pos >= 0 && pos <= doc3.content.size)) + throw new RangeError("Position " + pos + " out of range"); + let path = []; + let start = 0, parentOffset = pos; + for (let node = doc3; ; ) { + let { index, offset } = node.content.findIndex(parentOffset); + let rem = parentOffset - offset; + path.push(node, index, start + offset); + if (!rem) + break; + node = node.child(index); + if (node.isText) + break; + parentOffset = rem - 1; + start += offset + 1; + } + return new _ResolvedPos(pos, path, parentOffset); + } + /** + @internal + */ + static resolveCached(doc3, pos) { + let cache = resolveCache.get(doc3); + if (cache) { + for (let i5 = 0; i5 < cache.elts.length; i5++) { + let elt = cache.elts[i5]; + if (elt.pos == pos) + return elt; + } + } else { + resolveCache.set(doc3, cache = new ResolveCache()); + } + let result = cache.elts[cache.i] = _ResolvedPos.resolve(doc3, pos); + cache.i = (cache.i + 1) % resolveCacheSize; + return result; + } +}; +var ResolveCache = class { + constructor() { + this.elts = []; + this.i = 0; + } +}; +var resolveCacheSize = 12; +var resolveCache = /* @__PURE__ */ new WeakMap(); +var NodeRange = class { + /** + Construct a node range. `$from` and `$to` should point into the + same node until at least the given `depth`, since a node range + denotes an adjacent set of nodes in a single parent node. + */ + constructor($from, $to, depth) { + this.$from = $from; + this.$to = $to; + this.depth = depth; + } + /** + The position at the start of the range. + */ + get start() { + return this.$from.before(this.depth + 1); + } + /** + The position at the end of the range. + */ + get end() { + return this.$to.after(this.depth + 1); + } + /** + The parent node that the range points into. + */ + get parent() { + return this.$from.node(this.depth); + } + /** + The start index of the range in the parent node. + */ + get startIndex() { + return this.$from.index(this.depth); + } + /** + The end index of the range in the parent node. + */ + get endIndex() { + return this.$to.indexAfter(this.depth); + } +}; +var emptyAttrs = /* @__PURE__ */ Object.create(null); +var Node = class _Node { + /** + @internal + */ + constructor(type, attrs, content, marks = Mark.none) { + this.type = type; + this.attrs = attrs; + this.marks = marks; + this.content = content || Fragment.empty; + } + /** + The array of this node's child nodes. + */ + get children() { + return this.content.content; + } + /** + The size of this node, as defined by the integer-based [indexing + scheme](https://prosemirror.net/docs/guide/#doc.indexing). For text nodes, this is the + amount of characters. For other leaf nodes, it is one. For + non-leaf nodes, it is the size of the content plus two (the + start and end token). + */ + get nodeSize() { + return this.isLeaf ? 1 : 2 + this.content.size; + } + /** + The number of children that the node has. + */ + get childCount() { + return this.content.childCount; + } + /** + Get the child node at the given index. Raises an error when the + index is out of range. + */ + child(index) { + return this.content.child(index); + } + /** + Get the child node at the given index, if it exists. + */ + maybeChild(index) { + return this.content.maybeChild(index); + } + /** + Call `f` for every child node, passing the node, its offset + into this parent node, and its index. + */ + forEach(f3) { + this.content.forEach(f3); + } + /** + Invoke a callback for all descendant nodes recursively between + the given two positions that are relative to start of this + node's content. The callback is invoked with the node, its + position relative to the original node (method receiver), + its parent node, and its child index. When the callback returns + false for a given node, that node's children will not be + recursed over. The last parameter can be used to specify a + starting position to count from. + */ + nodesBetween(from, to, f3, startPos = 0) { + this.content.nodesBetween(from, to, f3, startPos, this); + } + /** + Call the given callback for every descendant node. Doesn't + descend into a node when the callback returns `false`. + */ + descendants(f3) { + this.nodesBetween(0, this.content.size, f3); + } + /** + Concatenates all the text nodes found in this fragment and its + children. + */ + get textContent() { + return this.isLeaf && this.type.spec.leafText ? this.type.spec.leafText(this) : this.textBetween(0, this.content.size, ""); + } + /** + Get all text between positions `from` and `to`. When + `blockSeparator` is given, it will be inserted to separate text + from different block nodes. If `leafText` is given, it'll be + inserted for every non-text leaf node encountered, otherwise + [`leafText`](https://prosemirror.net/docs/ref/#model.NodeSpec^leafText) will be used. + */ + textBetween(from, to, blockSeparator, leafText) { + return this.content.textBetween(from, to, blockSeparator, leafText); + } + /** + Returns this node's first child, or `null` if there are no + children. + */ + get firstChild() { + return this.content.firstChild; + } + /** + Returns this node's last child, or `null` if there are no + children. + */ + get lastChild() { + return this.content.lastChild; + } + /** + Test whether two nodes represent the same piece of document. + */ + eq(other) { + return this == other || this.sameMarkup(other) && this.content.eq(other.content); + } + /** + Compare the markup (type, attributes, and marks) of this node to + those of another. Returns `true` if both have the same markup. + */ + sameMarkup(other) { + return this.hasMarkup(other.type, other.attrs, other.marks); + } + /** + Check whether this node's markup correspond to the given type, + attributes, and marks. + */ + hasMarkup(type, attrs, marks) { + return this.type == type && compareDeep(this.attrs, attrs || type.defaultAttrs || emptyAttrs) && Mark.sameSet(this.marks, marks || Mark.none); + } + /** + Create a new node with the same markup as this node, containing + the given content (or empty, if no content is given). + */ + copy(content = null) { + if (content == this.content) + return this; + return new _Node(this.type, this.attrs, content, this.marks); + } + /** + Create a copy of this node, with the given set of marks instead + of the node's own marks. + */ + mark(marks) { + return marks == this.marks ? this : new _Node(this.type, this.attrs, this.content, marks); + } + /** + Create a copy of this node with only the content between the + given positions. If `to` is not given, it defaults to the end of + the node. + */ + cut(from, to = this.content.size) { + if (from == 0 && to == this.content.size) + return this; + return this.copy(this.content.cut(from, to)); + } + /** + Cut out the part of the document between the given positions, and + return it as a `Slice` object. + */ + slice(from, to = this.content.size, includeParents = false) { + if (from == to) + return Slice.empty; + let $from = this.resolve(from), $to = this.resolve(to); + let depth = includeParents ? 0 : $from.sharedDepth(to); + let start = $from.start(depth), node = $from.node(depth); + let content = node.content.cut($from.pos - start, $to.pos - start); + return new Slice(content, $from.depth - depth, $to.depth - depth); + } + /** + Replace the part of the document between the given positions with + the given slice. The slice must 'fit', meaning its open sides + must be able to connect to the surrounding content, and its + content nodes must be valid children for the node they are placed + into. If any of this is violated, an error of type + [`ReplaceError`](https://prosemirror.net/docs/ref/#model.ReplaceError) is thrown. + */ + replace(from, to, slice) { + return replace(this.resolve(from), this.resolve(to), slice); + } + /** + Find the node directly after the given position. + */ + nodeAt(pos) { + for (let node = this; ; ) { + let { index, offset } = node.content.findIndex(pos); + node = node.maybeChild(index); + if (!node) + return null; + if (offset == pos || node.isText) + return node; + pos -= offset + 1; + } + } + /** + Find the (direct) child node after the given offset, if any, + and return it along with its index and offset relative to this + node. + */ + childAfter(pos) { + let { index, offset } = this.content.findIndex(pos); + return { node: this.content.maybeChild(index), index, offset }; + } + /** + Find the (direct) child node before the given offset, if any, + and return it along with its index and offset relative to this + node. + */ + childBefore(pos) { + if (pos == 0) + return { node: null, index: 0, offset: 0 }; + let { index, offset } = this.content.findIndex(pos); + if (offset < pos) + return { node: this.content.child(index), index, offset }; + let node = this.content.child(index - 1); + return { node, index: index - 1, offset: offset - node.nodeSize }; + } + /** + Resolve the given position in the document, returning an + [object](https://prosemirror.net/docs/ref/#model.ResolvedPos) with information about its context. + */ + resolve(pos) { + return ResolvedPos.resolveCached(this, pos); + } + /** + @internal + */ + resolveNoCache(pos) { + return ResolvedPos.resolve(this, pos); + } + /** + Test whether a given mark or mark type occurs in this document + between the two given positions. + */ + rangeHasMark(from, to, type) { + let found2 = false; + if (to > from) + this.nodesBetween(from, to, (node) => { + if (type.isInSet(node.marks)) + found2 = true; + return !found2; + }); + return found2; + } + /** + True when this is a block (non-inline node) + */ + get isBlock() { + return this.type.isBlock; + } + /** + True when this is a textblock node, a block node with inline + content. + */ + get isTextblock() { + return this.type.isTextblock; + } + /** + True when this node allows inline content. + */ + get inlineContent() { + return this.type.inlineContent; + } + /** + True when this is an inline node (a text node or a node that can + appear among text). + */ + get isInline() { + return this.type.isInline; + } + /** + True when this is a text node. + */ + get isText() { + return this.type.isText; + } + /** + True when this is a leaf node. + */ + get isLeaf() { + return this.type.isLeaf; + } + /** + True when this is an atom, i.e. when it does not have directly + editable content. This is usually the same as `isLeaf`, but can + be configured with the [`atom` property](https://prosemirror.net/docs/ref/#model.NodeSpec.atom) + on a node's spec (typically used when the node is displayed as + an uneditable [node view](https://prosemirror.net/docs/ref/#view.NodeView)). + */ + get isAtom() { + return this.type.isAtom; + } + /** + Return a string representation of this node for debugging + purposes. + */ + toString() { + if (this.type.spec.toDebugString) + return this.type.spec.toDebugString(this); + let name = this.type.name; + if (this.content.size) + name += "(" + this.content.toStringInner() + ")"; + return wrapMarks(this.marks, name); + } + /** + Get the content match in this node at the given index. + */ + contentMatchAt(index) { + let match = this.type.contentMatch.matchFragment(this.content, 0, index); + if (!match) + throw new Error("Called contentMatchAt on a node with invalid content"); + return match; + } + /** + Test whether replacing the range between `from` and `to` (by + child index) with the given replacement fragment (which defaults + to the empty fragment) would leave the node's content valid. You + can optionally pass `start` and `end` indices into the + replacement fragment. + */ + canReplace(from, to, replacement = Fragment.empty, start = 0, end = replacement.childCount) { + let one = this.contentMatchAt(from).matchFragment(replacement, start, end); + let two = one && one.matchFragment(this.content, to); + if (!two || !two.validEnd) + return false; + for (let i5 = start; i5 < end; i5++) + if (!this.type.allowsMarks(replacement.child(i5).marks)) + return false; + return true; + } + /** + Test whether replacing the range `from` to `to` (by index) with + a node of the given type would leave the node's content valid. + */ + canReplaceWith(from, to, type, marks) { + if (marks && !this.type.allowsMarks(marks)) + return false; + let start = this.contentMatchAt(from).matchType(type); + let end = start && start.matchFragment(this.content, to); + return end ? end.validEnd : false; + } + /** + Test whether the given node's content could be appended to this + node. If that node is empty, this will only return true if there + is at least one node type that can appear in both nodes (to avoid + merging completely incompatible nodes). + */ + canAppend(other) { + if (other.content.size) + return this.canReplace(this.childCount, this.childCount, other.content); + else + return this.type.compatibleContent(other.type); + } + /** + Check whether this node and its descendants conform to the + schema, and raise an exception when they do not. + */ + check() { + this.type.checkContent(this.content); + this.type.checkAttrs(this.attrs); + let copy2 = Mark.none; + for (let i5 = 0; i5 < this.marks.length; i5++) { + let mark = this.marks[i5]; + mark.type.checkAttrs(mark.attrs); + copy2 = mark.addToSet(copy2); + } + if (!Mark.sameSet(copy2, this.marks)) + throw new RangeError(`Invalid collection of marks for node ${this.type.name}: ${this.marks.map((m2) => m2.type.name)}`); + this.content.forEach((node) => node.check()); + } + /** + Return a JSON-serializeable representation of this node. + */ + toJSON() { + let obj = { type: this.type.name }; + for (let _2 in this.attrs) { + obj.attrs = this.attrs; + break; + } + if (this.content.size) + obj.content = this.content.toJSON(); + if (this.marks.length) + obj.marks = this.marks.map((n4) => n4.toJSON()); + return obj; + } + /** + Deserialize a node from its JSON representation. + */ + static fromJSON(schema, json) { + if (!json) + throw new RangeError("Invalid input for Node.fromJSON"); + let marks = void 0; + if (json.marks) { + if (!Array.isArray(json.marks)) + throw new RangeError("Invalid mark data for Node.fromJSON"); + marks = json.marks.map(schema.markFromJSON); + } + if (json.type == "text") { + if (typeof json.text != "string") + throw new RangeError("Invalid text node in JSON"); + return schema.text(json.text, marks); + } + let content = Fragment.fromJSON(schema, json.content); + let node = schema.nodeType(json.type).create(json.attrs, content, marks); + node.type.checkAttrs(node.attrs); + return node; + } +}; +Node.prototype.text = void 0; +var TextNode = class _TextNode extends Node { + /** + @internal + */ + constructor(type, attrs, content, marks) { + super(type, attrs, null, marks); + if (!content) + throw new RangeError("Empty text nodes are not allowed"); + this.text = content; + } + toString() { + if (this.type.spec.toDebugString) + return this.type.spec.toDebugString(this); + return wrapMarks(this.marks, JSON.stringify(this.text)); + } + get textContent() { + return this.text; + } + textBetween(from, to) { + return this.text.slice(from, to); + } + get nodeSize() { + return this.text.length; + } + mark(marks) { + return marks == this.marks ? this : new _TextNode(this.type, this.attrs, this.text, marks); + } + withText(text) { + if (text == this.text) + return this; + return new _TextNode(this.type, this.attrs, text, this.marks); + } + cut(from = 0, to = this.text.length) { + if (from == 0 && to == this.text.length) + return this; + return this.withText(this.text.slice(from, to)); + } + eq(other) { + return this.sameMarkup(other) && this.text == other.text; + } + toJSON() { + let base2 = super.toJSON(); + base2.text = this.text; + return base2; + } +}; +function wrapMarks(marks, str) { + for (let i5 = marks.length - 1; i5 >= 0; i5--) + str = marks[i5].type.name + "(" + str + ")"; + return str; +} +var ContentMatch = class _ContentMatch { + /** + @internal + */ + constructor(validEnd) { + this.validEnd = validEnd; + this.next = []; + this.wrapCache = []; + } + /** + @internal + */ + static parse(string, nodeTypes) { + let stream = new TokenStream(string, nodeTypes); + if (stream.next == null) + return _ContentMatch.empty; + let expr = parseExpr(stream); + if (stream.next) + stream.err("Unexpected trailing text"); + let match = dfa(nfa(expr)); + checkForDeadEnds(match, stream); + return match; + } + /** + Match a node type, returning a match after that node if + successful. + */ + matchType(type) { + for (let i5 = 0; i5 < this.next.length; i5++) + if (this.next[i5].type == type) + return this.next[i5].next; + return null; + } + /** + Try to match a fragment. Returns the resulting match when + successful. + */ + matchFragment(frag, start = 0, end = frag.childCount) { + let cur = this; + for (let i5 = start; cur && i5 < end; i5++) + cur = cur.matchType(frag.child(i5).type); + return cur; + } + /** + @internal + */ + get inlineContent() { + return this.next.length != 0 && this.next[0].type.isInline; + } + /** + Get the first matching node type at this match position that can + be generated. + */ + get defaultType() { + for (let i5 = 0; i5 < this.next.length; i5++) { + let { type } = this.next[i5]; + if (!(type.isText || type.hasRequiredAttrs())) + return type; + } + return null; + } + /** + @internal + */ + compatible(other) { + for (let i5 = 0; i5 < this.next.length; i5++) + for (let j2 = 0; j2 < other.next.length; j2++) + if (this.next[i5].type == other.next[j2].type) + return true; + return false; + } + /** + Try to match the given fragment, and if that fails, see if it can + be made to match by inserting nodes in front of it. When + successful, return a fragment of inserted nodes (which may be + empty if nothing had to be inserted). When `toEnd` is true, only + return a fragment if the resulting match goes to the end of the + content expression. + */ + fillBefore(after, toEnd = false, startIndex = 0) { + let seen = [this]; + function search(match, types) { + let finished = match.matchFragment(after, startIndex); + if (finished && (!toEnd || finished.validEnd)) + return Fragment.from(types.map((tp) => tp.createAndFill())); + for (let i5 = 0; i5 < match.next.length; i5++) { + let { type, next } = match.next[i5]; + if (!(type.isText || type.hasRequiredAttrs()) && seen.indexOf(next) == -1) { + seen.push(next); + let found2 = search(next, types.concat(type)); + if (found2) + return found2; + } + } + return null; + } + return search(this, []); + } + /** + Find a set of wrapping node types that would allow a node of the + given type to appear at this position. The result may be empty + (when it fits directly) and will be null when no such wrapping + exists. + */ + findWrapping(target) { + for (let i5 = 0; i5 < this.wrapCache.length; i5 += 2) + if (this.wrapCache[i5] == target) + return this.wrapCache[i5 + 1]; + let computed = this.computeWrapping(target); + this.wrapCache.push(target, computed); + return computed; + } + /** + @internal + */ + computeWrapping(target) { + let seen = /* @__PURE__ */ Object.create(null), active = [{ match: this, type: null, via: null }]; + while (active.length) { + let current = active.shift(), match = current.match; + if (match.matchType(target)) { + let result = []; + for (let obj = current; obj.type; obj = obj.via) + result.push(obj.type); + return result.reverse(); + } + for (let i5 = 0; i5 < match.next.length; i5++) { + let { type, next } = match.next[i5]; + if (!type.isLeaf && !type.hasRequiredAttrs() && !(type.name in seen) && (!current.type || next.validEnd)) { + active.push({ match: type.contentMatch, type, via: current }); + seen[type.name] = true; + } + } + } + return null; + } + /** + The number of outgoing edges this node has in the finite + automaton that describes the content expression. + */ + get edgeCount() { + return this.next.length; + } + /** + Get the _n_​th outgoing edge from this node in the finite + automaton that describes the content expression. + */ + edge(n4) { + if (n4 >= this.next.length) + throw new RangeError(`There's no ${n4}th edge in this content match`); + return this.next[n4]; + } + /** + @internal + */ + toString() { + let seen = []; + function scan(m2) { + seen.push(m2); + for (let i5 = 0; i5 < m2.next.length; i5++) + if (seen.indexOf(m2.next[i5].next) == -1) + scan(m2.next[i5].next); + } + scan(this); + return seen.map((m2, i5) => { + let out = i5 + (m2.validEnd ? "*" : " ") + " "; + for (let i6 = 0; i6 < m2.next.length; i6++) + out += (i6 ? ", " : "") + m2.next[i6].type.name + "->" + seen.indexOf(m2.next[i6].next); + return out; + }).join("\n"); + } +}; +ContentMatch.empty = new ContentMatch(true); +var TokenStream = class { + constructor(string, nodeTypes) { + this.string = string; + this.nodeTypes = nodeTypes; + this.inline = null; + this.pos = 0; + this.tokens = string.split(/\s*(?=\b|\W|$)/); + if (this.tokens[this.tokens.length - 1] == "") + this.tokens.pop(); + if (this.tokens[0] == "") + this.tokens.shift(); + } + get next() { + return this.tokens[this.pos]; + } + eat(tok) { + return this.next == tok && (this.pos++ || true); + } + err(str) { + throw new SyntaxError(str + " (in content expression '" + this.string + "')"); + } +}; +function parseExpr(stream) { + let exprs = []; + do { + exprs.push(parseExprSeq(stream)); + } while (stream.eat("|")); + return exprs.length == 1 ? exprs[0] : { type: "choice", exprs }; +} +function parseExprSeq(stream) { + let exprs = []; + do { + exprs.push(parseExprSubscript(stream)); + } while (stream.next && stream.next != ")" && stream.next != "|"); + return exprs.length == 1 ? exprs[0] : { type: "seq", exprs }; +} +function parseExprSubscript(stream) { + let expr = parseExprAtom(stream); + for (; ; ) { + if (stream.eat("+")) + expr = { type: "plus", expr }; + else if (stream.eat("*")) + expr = { type: "star", expr }; + else if (stream.eat("?")) + expr = { type: "opt", expr }; + else if (stream.eat("{")) + expr = parseExprRange(stream, expr); + else + break; + } + return expr; +} +function parseNum(stream) { + if (/\D/.test(stream.next)) + stream.err("Expected number, got '" + stream.next + "'"); + let result = Number(stream.next); + stream.pos++; + return result; +} +function parseExprRange(stream, expr) { + let min = parseNum(stream), max = min; + if (stream.eat(",")) { + if (stream.next != "}") + max = parseNum(stream); + else + max = -1; + } + if (!stream.eat("}")) + stream.err("Unclosed braced range"); + return { type: "range", min, max, expr }; +} +function resolveName(stream, name) { + let types = stream.nodeTypes, type = types[name]; + if (type) + return [type]; + let result = []; + for (let typeName in types) { + let type2 = types[typeName]; + if (type2.isInGroup(name)) + result.push(type2); + } + if (result.length == 0) + stream.err("No node type or group '" + name + "' found"); + return result; +} +function parseExprAtom(stream) { + if (stream.eat("(")) { + let expr = parseExpr(stream); + if (!stream.eat(")")) + stream.err("Missing closing paren"); + return expr; + } else if (!/\W/.test(stream.next)) { + let exprs = resolveName(stream, stream.next).map((type) => { + if (stream.inline == null) + stream.inline = type.isInline; + else if (stream.inline != type.isInline) + stream.err("Mixing inline and block content"); + return { type: "name", value: type }; + }); + stream.pos++; + return exprs.length == 1 ? exprs[0] : { type: "choice", exprs }; + } else { + stream.err("Unexpected token '" + stream.next + "'"); + } +} +function nfa(expr) { + let nfa2 = [[]]; + connect(compile(expr, 0), node()); + return nfa2; + function node() { + return nfa2.push([]) - 1; + } + function edge(from, to, term) { + let edge2 = { term, to }; + nfa2[from].push(edge2); + return edge2; + } + function connect(edges, to) { + edges.forEach((edge2) => edge2.to = to); + } + function compile(expr2, from) { + if (expr2.type == "choice") { + return expr2.exprs.reduce((out, expr3) => out.concat(compile(expr3, from)), []); + } else if (expr2.type == "seq") { + for (let i5 = 0; ; i5++) { + let next = compile(expr2.exprs[i5], from); + if (i5 == expr2.exprs.length - 1) + return next; + connect(next, from = node()); + } + } else if (expr2.type == "star") { + let loop = node(); + edge(from, loop); + connect(compile(expr2.expr, loop), loop); + return [edge(loop)]; + } else if (expr2.type == "plus") { + let loop = node(); + connect(compile(expr2.expr, from), loop); + connect(compile(expr2.expr, loop), loop); + return [edge(loop)]; + } else if (expr2.type == "opt") { + return [edge(from)].concat(compile(expr2.expr, from)); + } else if (expr2.type == "range") { + let cur = from; + for (let i5 = 0; i5 < expr2.min; i5++) { + let next = node(); + connect(compile(expr2.expr, cur), next); + cur = next; + } + if (expr2.max == -1) { + connect(compile(expr2.expr, cur), cur); + } else { + for (let i5 = expr2.min; i5 < expr2.max; i5++) { + let next = node(); + edge(cur, next); + connect(compile(expr2.expr, cur), next); + cur = next; + } + } + return [edge(cur)]; + } else if (expr2.type == "name") { + return [edge(from, void 0, expr2.value)]; + } else { + throw new Error("Unknown expr type"); + } + } +} +function cmp(a3, b3) { + return b3 - a3; +} +function nullFrom(nfa2, node) { + let result = []; + scan(node); + return result.sort(cmp); + function scan(node2) { + let edges = nfa2[node2]; + if (edges.length == 1 && !edges[0].term) + return scan(edges[0].to); + result.push(node2); + for (let i5 = 0; i5 < edges.length; i5++) { + let { term, to } = edges[i5]; + if (!term && result.indexOf(to) == -1) + scan(to); + } + } +} +function dfa(nfa2) { + let labeled = /* @__PURE__ */ Object.create(null); + return explore(nullFrom(nfa2, 0)); + function explore(states) { + let out = []; + states.forEach((node) => { + nfa2[node].forEach(({ term, to }) => { + if (!term) + return; + let set; + for (let i5 = 0; i5 < out.length; i5++) + if (out[i5][0] == term) + set = out[i5][1]; + nullFrom(nfa2, to).forEach((node2) => { + if (!set) + out.push([term, set = []]); + if (set.indexOf(node2) == -1) + set.push(node2); + }); + }); + }); + let state = labeled[states.join(",")] = new ContentMatch(states.indexOf(nfa2.length - 1) > -1); + for (let i5 = 0; i5 < out.length; i5++) { + let states2 = out[i5][1].sort(cmp); + state.next.push({ type: out[i5][0], next: labeled[states2.join(",")] || explore(states2) }); + } + return state; + } +} +function checkForDeadEnds(match, stream) { + for (let i5 = 0, work = [match]; i5 < work.length; i5++) { + let state = work[i5], dead = !state.validEnd, nodes = []; + for (let j2 = 0; j2 < state.next.length; j2++) { + let { type, next } = state.next[j2]; + nodes.push(type.name); + if (dead && !(type.isText || type.hasRequiredAttrs())) + dead = false; + if (work.indexOf(next) == -1) + work.push(next); + } + if (dead) + stream.err("Only non-generatable nodes (" + nodes.join(", ") + ") in a required position (see https://prosemirror.net/docs/guide/#generatable)"); + } +} +function defaultAttrs(attrs) { + let defaults = /* @__PURE__ */ Object.create(null); + for (let attrName in attrs) { + let attr = attrs[attrName]; + if (!attr.hasDefault) + return null; + defaults[attrName] = attr.default; + } + return defaults; +} +function computeAttrs(attrs, value) { + let built = /* @__PURE__ */ Object.create(null); + for (let name in attrs) { + let given = value && value[name]; + if (given === void 0) { + let attr = attrs[name]; + if (attr.hasDefault) + given = attr.default; + else + throw new RangeError("No value supplied for attribute " + name); + } + built[name] = given; + } + return built; +} +function checkAttrs(attrs, values, type, name) { + for (let name2 in values) + if (!(name2 in attrs)) + throw new RangeError(`Unsupported attribute ${name2} for ${type} of type ${name2}`); + for (let name2 in attrs) { + let attr = attrs[name2]; + if (attr.validate) + attr.validate(values[name2]); + } +} +function initAttrs(typeName, attrs) { + let result = /* @__PURE__ */ Object.create(null); + if (attrs) + for (let name in attrs) + result[name] = new Attribute(typeName, name, attrs[name]); + return result; +} +var NodeType = class _NodeType { + /** + @internal + */ + constructor(name, schema, spec) { + this.name = name; + this.schema = schema; + this.spec = spec; + this.markSet = null; + this.groups = spec.group ? spec.group.split(" ") : []; + this.attrs = initAttrs(name, spec.attrs); + this.defaultAttrs = defaultAttrs(this.attrs); + this.contentMatch = null; + this.inlineContent = null; + this.isBlock = !(spec.inline || name == "text"); + this.isText = name == "text"; + } + /** + True if this is an inline type. + */ + get isInline() { + return !this.isBlock; + } + /** + True if this is a textblock type, a block that contains inline + content. + */ + get isTextblock() { + return this.isBlock && this.inlineContent; + } + /** + True for node types that allow no content. + */ + get isLeaf() { + return this.contentMatch == ContentMatch.empty; + } + /** + True when this node is an atom, i.e. when it does not have + directly editable content. + */ + get isAtom() { + return this.isLeaf || !!this.spec.atom; + } + /** + Return true when this node type is part of the given + [group](https://prosemirror.net/docs/ref/#model.NodeSpec.group). + */ + isInGroup(group) { + return this.groups.indexOf(group) > -1; + } + /** + The node type's [whitespace](https://prosemirror.net/docs/ref/#model.NodeSpec.whitespace) option. + */ + get whitespace() { + return this.spec.whitespace || (this.spec.code ? "pre" : "normal"); + } + /** + Tells you whether this node type has any required attributes. + */ + hasRequiredAttrs() { + for (let n4 in this.attrs) + if (this.attrs[n4].isRequired) + return true; + return false; + } + /** + Indicates whether this node allows some of the same content as + the given node type. + */ + compatibleContent(other) { + return this == other || this.contentMatch.compatible(other.contentMatch); + } + /** + @internal + */ + computeAttrs(attrs) { + if (!attrs && this.defaultAttrs) + return this.defaultAttrs; + else + return computeAttrs(this.attrs, attrs); + } + /** + Create a `Node` of this type. The given attributes are + checked and defaulted (you can pass `null` to use the type's + defaults entirely, if no required attributes exist). `content` + may be a `Fragment`, a node, an array of nodes, or + `null`. Similarly `marks` may be `null` to default to the empty + set of marks. + */ + create(attrs = null, content, marks) { + if (this.isText) + throw new Error("NodeType.create can't construct text nodes"); + return new Node(this, this.computeAttrs(attrs), Fragment.from(content), Mark.setFrom(marks)); + } + /** + Like [`create`](https://prosemirror.net/docs/ref/#model.NodeType.create), but check the given content + against the node type's content restrictions, and throw an error + if it doesn't match. + */ + createChecked(attrs = null, content, marks) { + content = Fragment.from(content); + this.checkContent(content); + return new Node(this, this.computeAttrs(attrs), content, Mark.setFrom(marks)); + } + /** + Like [`create`](https://prosemirror.net/docs/ref/#model.NodeType.create), but see if it is + necessary to add nodes to the start or end of the given fragment + to make it fit the node. If no fitting wrapping can be found, + return null. Note that, due to the fact that required nodes can + always be created, this will always succeed if you pass null or + `Fragment.empty` as content. + */ + createAndFill(attrs = null, content, marks) { + attrs = this.computeAttrs(attrs); + content = Fragment.from(content); + if (content.size) { + let before = this.contentMatch.fillBefore(content); + if (!before) + return null; + content = before.append(content); + } + let matched = this.contentMatch.matchFragment(content); + let after = matched && matched.fillBefore(Fragment.empty, true); + if (!after) + return null; + return new Node(this, attrs, content.append(after), Mark.setFrom(marks)); + } + /** + Returns true if the given fragment is valid content for this node + type. + */ + validContent(content) { + let result = this.contentMatch.matchFragment(content); + if (!result || !result.validEnd) + return false; + for (let i5 = 0; i5 < content.childCount; i5++) + if (!this.allowsMarks(content.child(i5).marks)) + return false; + return true; + } + /** + Throws a RangeError if the given fragment is not valid content for this + node type. + @internal + */ + checkContent(content) { + if (!this.validContent(content)) + throw new RangeError(`Invalid content for node ${this.name}: ${content.toString().slice(0, 50)}`); + } + /** + @internal + */ + checkAttrs(attrs) { + checkAttrs(this.attrs, attrs, "node", this.name); + } + /** + Check whether the given mark type is allowed in this node. + */ + allowsMarkType(markType) { + return this.markSet == null || this.markSet.indexOf(markType) > -1; + } + /** + Test whether the given set of marks are allowed in this node. + */ + allowsMarks(marks) { + if (this.markSet == null) + return true; + for (let i5 = 0; i5 < marks.length; i5++) + if (!this.allowsMarkType(marks[i5].type)) + return false; + return true; + } + /** + Removes the marks that are not allowed in this node from the given set. + */ + allowedMarks(marks) { + if (this.markSet == null) + return marks; + let copy2; + for (let i5 = 0; i5 < marks.length; i5++) { + if (!this.allowsMarkType(marks[i5].type)) { + if (!copy2) + copy2 = marks.slice(0, i5); + } else if (copy2) { + copy2.push(marks[i5]); + } + } + return !copy2 ? marks : copy2.length ? copy2 : Mark.none; + } + /** + @internal + */ + static compile(nodes, schema) { + let result = /* @__PURE__ */ Object.create(null); + nodes.forEach((name, spec) => result[name] = new _NodeType(name, schema, spec)); + let topType = schema.spec.topNode || "doc"; + if (!result[topType]) + throw new RangeError("Schema is missing its top node type ('" + topType + "')"); + if (!result.text) + throw new RangeError("Every schema needs a 'text' type"); + for (let _2 in result.text.attrs) + throw new RangeError("The text node type should not have attributes"); + return result; + } +}; +function validateType(typeName, attrName, type) { + let types = type.split("|"); + return (value) => { + let name = value === null ? "null" : typeof value; + if (types.indexOf(name) < 0) + throw new RangeError(`Expected value of type ${types} for attribute ${attrName} on type ${typeName}, got ${name}`); + }; +} +var Attribute = class { + constructor(typeName, attrName, options) { + this.hasDefault = Object.prototype.hasOwnProperty.call(options, "default"); + this.default = options.default; + this.validate = typeof options.validate == "string" ? validateType(typeName, attrName, options.validate) : options.validate; + } + get isRequired() { + return !this.hasDefault; + } +}; +var MarkType = class _MarkType { + /** + @internal + */ + constructor(name, rank, schema, spec) { + this.name = name; + this.rank = rank; + this.schema = schema; + this.spec = spec; + this.attrs = initAttrs(name, spec.attrs); + this.excluded = null; + let defaults = defaultAttrs(this.attrs); + this.instance = defaults ? new Mark(this, defaults) : null; + } + /** + Create a mark of this type. `attrs` may be `null` or an object + containing only some of the mark's attributes. The others, if + they have defaults, will be added. + */ + create(attrs = null) { + if (!attrs && this.instance) + return this.instance; + return new Mark(this, computeAttrs(this.attrs, attrs)); + } + /** + @internal + */ + static compile(marks, schema) { + let result = /* @__PURE__ */ Object.create(null), rank = 0; + marks.forEach((name, spec) => result[name] = new _MarkType(name, rank++, schema, spec)); + return result; + } + /** + When there is a mark of this type in the given set, a new set + without it is returned. Otherwise, the input set is returned. + */ + removeFromSet(set) { + for (var i5 = 0; i5 < set.length; i5++) + if (set[i5].type == this) { + set = set.slice(0, i5).concat(set.slice(i5 + 1)); + i5--; + } + return set; + } + /** + Tests whether there is a mark of this type in the given set. + */ + isInSet(set) { + for (let i5 = 0; i5 < set.length; i5++) + if (set[i5].type == this) + return set[i5]; + } + /** + @internal + */ + checkAttrs(attrs) { + checkAttrs(this.attrs, attrs, "mark", this.name); + } + /** + Queries whether a given mark type is + [excluded](https://prosemirror.net/docs/ref/#model.MarkSpec.excludes) by this one. + */ + excludes(other) { + return this.excluded.indexOf(other) > -1; + } +}; +var Schema = class { + /** + Construct a schema from a schema [specification](https://prosemirror.net/docs/ref/#model.SchemaSpec). + */ + constructor(spec) { + this.linebreakReplacement = null; + this.cached = /* @__PURE__ */ Object.create(null); + let instanceSpec = this.spec = {}; + for (let prop in spec) + instanceSpec[prop] = spec[prop]; + instanceSpec.nodes = dist_default.from(spec.nodes), instanceSpec.marks = dist_default.from(spec.marks || {}), this.nodes = NodeType.compile(this.spec.nodes, this); + this.marks = MarkType.compile(this.spec.marks, this); + let contentExprCache = /* @__PURE__ */ Object.create(null); + for (let prop in this.nodes) { + if (prop in this.marks) + throw new RangeError(prop + " can not be both a node and a mark"); + let type = this.nodes[prop], contentExpr = type.spec.content || "", markExpr = type.spec.marks; + type.contentMatch = contentExprCache[contentExpr] || (contentExprCache[contentExpr] = ContentMatch.parse(contentExpr, this.nodes)); + type.inlineContent = type.contentMatch.inlineContent; + if (type.spec.linebreakReplacement) { + if (this.linebreakReplacement) + throw new RangeError("Multiple linebreak nodes defined"); + if (!type.isInline || !type.isLeaf) + throw new RangeError("Linebreak replacement nodes must be inline leaf nodes"); + this.linebreakReplacement = type; + } + type.markSet = markExpr == "_" ? null : markExpr ? gatherMarks(this, markExpr.split(" ")) : markExpr == "" || !type.inlineContent ? [] : null; + } + for (let prop in this.marks) { + let type = this.marks[prop], excl = type.spec.excludes; + type.excluded = excl == null ? [type] : excl == "" ? [] : gatherMarks(this, excl.split(" ")); + } + this.nodeFromJSON = this.nodeFromJSON.bind(this); + this.markFromJSON = this.markFromJSON.bind(this); + this.topNodeType = this.nodes[this.spec.topNode || "doc"]; + this.cached.wrappings = /* @__PURE__ */ Object.create(null); + } + /** + Create a node in this schema. The `type` may be a string or a + `NodeType` instance. Attributes will be extended with defaults, + `content` may be a `Fragment`, `null`, a `Node`, or an array of + nodes. + */ + node(type, attrs = null, content, marks) { + if (typeof type == "string") + type = this.nodeType(type); + else if (!(type instanceof NodeType)) + throw new RangeError("Invalid node type: " + type); + else if (type.schema != this) + throw new RangeError("Node type from different schema used (" + type.name + ")"); + return type.createChecked(attrs, content, marks); + } + /** + Create a text node in the schema. Empty text nodes are not + allowed. + */ + text(text, marks) { + let type = this.nodes.text; + return new TextNode(type, type.defaultAttrs, text, Mark.setFrom(marks)); + } + /** + Create a mark with the given type and attributes. + */ + mark(type, attrs) { + if (typeof type == "string") + type = this.marks[type]; + return type.create(attrs); + } + /** + Deserialize a node from its JSON representation. This method is + bound. + */ + nodeFromJSON(json) { + return Node.fromJSON(this, json); + } + /** + Deserialize a mark from its JSON representation. This method is + bound. + */ + markFromJSON(json) { + return Mark.fromJSON(this, json); + } + /** + @internal + */ + nodeType(name) { + let found2 = this.nodes[name]; + if (!found2) + throw new RangeError("Unknown node type: " + name); + return found2; + } +}; +function gatherMarks(schema, marks) { + let found2 = []; + for (let i5 = 0; i5 < marks.length; i5++) { + let name = marks[i5], mark = schema.marks[name], ok = mark; + if (mark) { + found2.push(mark); + } else { + for (let prop in schema.marks) { + let mark2 = schema.marks[prop]; + if (name == "_" || mark2.spec.group && mark2.spec.group.split(" ").indexOf(name) > -1) + found2.push(ok = mark2); + } + } + if (!ok) + throw new SyntaxError("Unknown mark type: '" + marks[i5] + "'"); + } + return found2; +} +function isTagRule(rule) { + return rule.tag != null; +} +function isStyleRule(rule) { + return rule.style != null; +} +var DOMParser = class _DOMParser { + /** + Create a parser that targets the given schema, using the given + parsing rules. + */ + constructor(schema, rules) { + this.schema = schema; + this.rules = rules; + this.tags = []; + this.styles = []; + let matchedStyles = this.matchedStyles = []; + rules.forEach((rule) => { + if (isTagRule(rule)) { + this.tags.push(rule); + } else if (isStyleRule(rule)) { + let prop = /[^=]*/.exec(rule.style)[0]; + if (matchedStyles.indexOf(prop) < 0) + matchedStyles.push(prop); + this.styles.push(rule); + } + }); + this.normalizeLists = !this.tags.some((r4) => { + if (!/^(ul|ol)\b/.test(r4.tag) || !r4.node) + return false; + let node = schema.nodes[r4.node]; + return node.contentMatch.matchType(node); + }); + } + /** + Parse a document from the content of a DOM node. + */ + parse(dom, options = {}) { + let context = new ParseContext(this, options, false); + context.addAll(dom, Mark.none, options.from, options.to); + return context.finish(); + } + /** + Parses the content of the given DOM node, like + [`parse`](https://prosemirror.net/docs/ref/#model.DOMParser.parse), and takes the same set of + options. But unlike that method, which produces a whole node, + this one returns a slice that is open at the sides, meaning that + the schema constraints aren't applied to the start of nodes to + the left of the input and the end of nodes at the end. + */ + parseSlice(dom, options = {}) { + let context = new ParseContext(this, options, true); + context.addAll(dom, Mark.none, options.from, options.to); + return Slice.maxOpen(context.finish()); + } + /** + @internal + */ + matchTag(dom, context, after) { + for (let i5 = after ? this.tags.indexOf(after) + 1 : 0; i5 < this.tags.length; i5++) { + let rule = this.tags[i5]; + if (matches(dom, rule.tag) && (rule.namespace === void 0 || dom.namespaceURI == rule.namespace) && (!rule.context || context.matchesContext(rule.context))) { + if (rule.getAttrs) { + let result = rule.getAttrs(dom); + if (result === false) + continue; + rule.attrs = result || void 0; + } + return rule; + } + } + } + /** + @internal + */ + matchStyle(prop, value, context, after) { + for (let i5 = after ? this.styles.indexOf(after) + 1 : 0; i5 < this.styles.length; i5++) { + let rule = this.styles[i5], style2 = rule.style; + if (style2.indexOf(prop) != 0 || rule.context && !context.matchesContext(rule.context) || // Test that the style string either precisely matches the prop, + // or has an '=' sign after the prop, followed by the given + // value. + style2.length > prop.length && (style2.charCodeAt(prop.length) != 61 || style2.slice(prop.length + 1) != value)) + continue; + if (rule.getAttrs) { + let result = rule.getAttrs(value); + if (result === false) + continue; + rule.attrs = result || void 0; + } + return rule; + } + } + /** + @internal + */ + static schemaRules(schema) { + let result = []; + function insert(rule) { + let priority = rule.priority == null ? 50 : rule.priority, i5 = 0; + for (; i5 < result.length; i5++) { + let next = result[i5], nextPriority = next.priority == null ? 50 : next.priority; + if (nextPriority < priority) + break; + } + result.splice(i5, 0, rule); + } + for (let name in schema.marks) { + let rules = schema.marks[name].spec.parseDOM; + if (rules) + rules.forEach((rule) => { + insert(rule = copy(rule)); + if (!(rule.mark || rule.ignore || rule.clearMark)) + rule.mark = name; + }); + } + for (let name in schema.nodes) { + let rules = schema.nodes[name].spec.parseDOM; + if (rules) + rules.forEach((rule) => { + insert(rule = copy(rule)); + if (!(rule.node || rule.ignore || rule.mark)) + rule.node = name; + }); + } + return result; + } + /** + Construct a DOM parser using the parsing rules listed in a + schema's [node specs](https://prosemirror.net/docs/ref/#model.NodeSpec.parseDOM), reordered by + [priority](https://prosemirror.net/docs/ref/#model.ParseRule.priority). + */ + static fromSchema(schema) { + return schema.cached.domParser || (schema.cached.domParser = new _DOMParser(schema, _DOMParser.schemaRules(schema))); + } +}; +var blockTags = { + address: true, + article: true, + aside: true, + blockquote: true, + canvas: true, + dd: true, + div: true, + dl: true, + fieldset: true, + figcaption: true, + figure: true, + footer: true, + form: true, + h1: true, + h2: true, + h3: true, + h4: true, + h5: true, + h6: true, + header: true, + hgroup: true, + hr: true, + li: true, + noscript: true, + ol: true, + output: true, + p: true, + pre: true, + section: true, + table: true, + tfoot: true, + ul: true +}; +var ignoreTags = { + head: true, + noscript: true, + object: true, + script: true, + style: true, + title: true +}; +var listTags = { ol: true, ul: true }; +var OPT_PRESERVE_WS = 1; +var OPT_PRESERVE_WS_FULL = 2; +var OPT_OPEN_LEFT = 4; +function wsOptionsFor(type, preserveWhitespace, base2) { + if (preserveWhitespace != null) + return (preserveWhitespace ? OPT_PRESERVE_WS : 0) | (preserveWhitespace === "full" ? OPT_PRESERVE_WS_FULL : 0); + return type && type.whitespace == "pre" ? OPT_PRESERVE_WS | OPT_PRESERVE_WS_FULL : base2 & ~OPT_OPEN_LEFT; +} +var NodeContext = class { + constructor(type, attrs, marks, solid, match, options) { + this.type = type; + this.attrs = attrs; + this.marks = marks; + this.solid = solid; + this.options = options; + this.content = []; + this.activeMarks = Mark.none; + this.match = match || (options & OPT_OPEN_LEFT ? null : type.contentMatch); + } + findWrapping(node) { + if (!this.match) { + if (!this.type) + return []; + let fill = this.type.contentMatch.fillBefore(Fragment.from(node)); + if (fill) { + this.match = this.type.contentMatch.matchFragment(fill); + } else { + let start = this.type.contentMatch, wrap2; + if (wrap2 = start.findWrapping(node.type)) { + this.match = start; + return wrap2; + } else { + return null; + } + } + } + return this.match.findWrapping(node.type); + } + finish(openEnd) { + if (!(this.options & OPT_PRESERVE_WS)) { + let last = this.content[this.content.length - 1], m2; + if (last && last.isText && (m2 = /[ \t\r\n\u000c]+$/.exec(last.text))) { + let text = last; + if (last.text.length == m2[0].length) + this.content.pop(); + else + this.content[this.content.length - 1] = text.withText(text.text.slice(0, text.text.length - m2[0].length)); + } + } + let content = Fragment.from(this.content); + if (!openEnd && this.match) + content = content.append(this.match.fillBefore(Fragment.empty, true)); + return this.type ? this.type.create(this.attrs, content, this.marks) : content; + } + inlineContext(node) { + if (this.type) + return this.type.inlineContent; + if (this.content.length) + return this.content[0].isInline; + return node.parentNode && !blockTags.hasOwnProperty(node.parentNode.nodeName.toLowerCase()); + } +}; +var ParseContext = class { + constructor(parser, options, isOpen) { + this.parser = parser; + this.options = options; + this.isOpen = isOpen; + this.open = 0; + this.localPreserveWS = false; + let topNode = options.topNode, topContext; + let topOptions = wsOptionsFor(null, options.preserveWhitespace, 0) | (isOpen ? OPT_OPEN_LEFT : 0); + if (topNode) + topContext = new NodeContext(topNode.type, topNode.attrs, Mark.none, true, options.topMatch || topNode.type.contentMatch, topOptions); + else if (isOpen) + topContext = new NodeContext(null, null, Mark.none, true, null, topOptions); + else + topContext = new NodeContext(parser.schema.topNodeType, null, Mark.none, true, null, topOptions); + this.nodes = [topContext]; + this.find = options.findPositions; + this.needsBlock = false; + } + get top() { + return this.nodes[this.open]; + } + // Add a DOM node to the content. Text is inserted as text node, + // otherwise, the node is passed to `addElement` or, if it has a + // `style` attribute, `addElementWithStyles`. + addDOM(dom, marks) { + if (dom.nodeType == 3) + this.addTextNode(dom, marks); + else if (dom.nodeType == 1) + this.addElement(dom, marks); + } + addTextNode(dom, marks) { + let value = dom.nodeValue; + let top = this.top, preserveWS = top.options & OPT_PRESERVE_WS_FULL ? "full" : this.localPreserveWS || (top.options & OPT_PRESERVE_WS) > 0; + if (preserveWS === "full" || top.inlineContext(dom) || /[^ \t\r\n\u000c]/.test(value)) { + if (!preserveWS) { + value = value.replace(/[ \t\r\n\u000c]+/g, " "); + if (/^[ \t\r\n\u000c]/.test(value) && this.open == this.nodes.length - 1) { + let nodeBefore = top.content[top.content.length - 1]; + let domNodeBefore = dom.previousSibling; + if (!nodeBefore || domNodeBefore && domNodeBefore.nodeName == "BR" || nodeBefore.isText && /[ \t\r\n\u000c]$/.test(nodeBefore.text)) + value = value.slice(1); + } + } else if (preserveWS !== "full") { + value = value.replace(/\r?\n|\r/g, " "); + } else { + value = value.replace(/\r\n?/g, "\n"); + } + if (value) + this.insertNode(this.parser.schema.text(value), marks, !/\S/.test(value)); + this.findInText(dom); + } else { + this.findInside(dom); + } + } + // Try to find a handler for the given tag and use that to parse. If + // none is found, the element's content nodes are added directly. + addElement(dom, marks, matchAfter) { + let outerWS = this.localPreserveWS, top = this.top; + if (dom.tagName == "PRE" || /pre/.test(dom.style && dom.style.whiteSpace)) + this.localPreserveWS = true; + let name = dom.nodeName.toLowerCase(), ruleID; + if (listTags.hasOwnProperty(name) && this.parser.normalizeLists) + normalizeList(dom); + let rule = this.options.ruleFromNode && this.options.ruleFromNode(dom) || (ruleID = this.parser.matchTag(dom, this, matchAfter)); + out: if (rule ? rule.ignore : ignoreTags.hasOwnProperty(name)) { + this.findInside(dom); + this.ignoreFallback(dom, marks); + } else if (!rule || rule.skip || rule.closeParent) { + if (rule && rule.closeParent) + this.open = Math.max(0, this.open - 1); + else if (rule && rule.skip.nodeType) + dom = rule.skip; + let sync, oldNeedsBlock = this.needsBlock; + if (blockTags.hasOwnProperty(name)) { + if (top.content.length && top.content[0].isInline && this.open) { + this.open--; + top = this.top; + } + sync = true; + if (!top.type) + this.needsBlock = true; + } else if (!dom.firstChild) { + this.leafFallback(dom, marks); + break out; + } + let innerMarks = rule && rule.skip ? marks : this.readStyles(dom, marks); + if (innerMarks) + this.addAll(dom, innerMarks); + if (sync) + this.sync(top); + this.needsBlock = oldNeedsBlock; + } else { + let innerMarks = this.readStyles(dom, marks); + if (innerMarks) + this.addElementByRule(dom, rule, innerMarks, rule.consuming === false ? ruleID : void 0); + } + this.localPreserveWS = outerWS; + } + // Called for leaf DOM nodes that would otherwise be ignored + leafFallback(dom, marks) { + if (dom.nodeName == "BR" && this.top.type && this.top.type.inlineContent) + this.addTextNode(dom.ownerDocument.createTextNode("\n"), marks); + } + // Called for ignored nodes + ignoreFallback(dom, marks) { + if (dom.nodeName == "BR" && (!this.top.type || !this.top.type.inlineContent)) + this.findPlace(this.parser.schema.text("-"), marks, true); + } + // Run any style parser associated with the node's styles. Either + // return an updated array of marks, or null to indicate some of the + // styles had a rule with `ignore` set. + readStyles(dom, marks) { + let styles = dom.style; + if (styles && styles.length) + for (let i5 = 0; i5 < this.parser.matchedStyles.length; i5++) { + let name = this.parser.matchedStyles[i5], value = styles.getPropertyValue(name); + if (value) + for (let after = void 0; ; ) { + let rule = this.parser.matchStyle(name, value, this, after); + if (!rule) + break; + if (rule.ignore) + return null; + if (rule.clearMark) + marks = marks.filter((m2) => !rule.clearMark(m2)); + else + marks = marks.concat(this.parser.schema.marks[rule.mark].create(rule.attrs)); + if (rule.consuming === false) + after = rule; + else + break; + } + } + return marks; + } + // Look up a handler for the given node. If none are found, return + // false. Otherwise, apply it, use its return value to drive the way + // the node's content is wrapped, and return true. + addElementByRule(dom, rule, marks, continueAfter) { + let sync, nodeType; + if (rule.node) { + nodeType = this.parser.schema.nodes[rule.node]; + if (!nodeType.isLeaf) { + let inner = this.enter(nodeType, rule.attrs || null, marks, rule.preserveWhitespace); + if (inner) { + sync = true; + marks = inner; + } + } else if (!this.insertNode(nodeType.create(rule.attrs), marks, dom.nodeName == "BR")) { + this.leafFallback(dom, marks); + } + } else { + let markType = this.parser.schema.marks[rule.mark]; + marks = marks.concat(markType.create(rule.attrs)); + } + let startIn = this.top; + if (nodeType && nodeType.isLeaf) { + this.findInside(dom); + } else if (continueAfter) { + this.addElement(dom, marks, continueAfter); + } else if (rule.getContent) { + this.findInside(dom); + rule.getContent(dom, this.parser.schema).forEach((node) => this.insertNode(node, marks, false)); + } else { + let contentDOM = dom; + if (typeof rule.contentElement == "string") + contentDOM = dom.querySelector(rule.contentElement); + else if (typeof rule.contentElement == "function") + contentDOM = rule.contentElement(dom); + else if (rule.contentElement) + contentDOM = rule.contentElement; + this.findAround(dom, contentDOM, true); + this.addAll(contentDOM, marks); + this.findAround(dom, contentDOM, false); + } + if (sync && this.sync(startIn)) + this.open--; + } + // Add all child nodes between `startIndex` and `endIndex` (or the + // whole node, if not given). If `sync` is passed, use it to + // synchronize after every block element. + addAll(parent, marks, startIndex, endIndex) { + let index = startIndex || 0; + for (let dom = startIndex ? parent.childNodes[startIndex] : parent.firstChild, end = endIndex == null ? null : parent.childNodes[endIndex]; dom != end; dom = dom.nextSibling, ++index) { + this.findAtPoint(parent, index); + this.addDOM(dom, marks); + } + this.findAtPoint(parent, index); + } + // Try to find a way to fit the given node type into the current + // context. May add intermediate wrappers and/or leave non-solid + // nodes that we're in. + findPlace(node, marks, cautious) { + let route, sync; + for (let depth = this.open, penalty = 0; depth >= 0; depth--) { + let cx = this.nodes[depth]; + let found2 = cx.findWrapping(node); + if (found2 && (!route || route.length > found2.length + penalty)) { + route = found2; + sync = cx; + if (!found2.length) + break; + } + if (cx.solid) { + if (cautious) + break; + penalty += 2; + } + } + if (!route) + return null; + this.sync(sync); + for (let i5 = 0; i5 < route.length; i5++) + marks = this.enterInner(route[i5], null, marks, false); + return marks; + } + // Try to insert the given node, adjusting the context when needed. + insertNode(node, marks, cautious) { + if (node.isInline && this.needsBlock && !this.top.type) { + let block = this.textblockFromContext(); + if (block) + marks = this.enterInner(block, null, marks); + } + let innerMarks = this.findPlace(node, marks, cautious); + if (innerMarks) { + this.closeExtra(); + let top = this.top; + if (top.match) + top.match = top.match.matchType(node.type); + let nodeMarks = Mark.none; + for (let m2 of innerMarks.concat(node.marks)) + if (top.type ? top.type.allowsMarkType(m2.type) : markMayApply(m2.type, node.type)) + nodeMarks = m2.addToSet(nodeMarks); + top.content.push(node.mark(nodeMarks)); + return true; + } + return false; + } + // Try to start a node of the given type, adjusting the context when + // necessary. + enter(type, attrs, marks, preserveWS) { + let innerMarks = this.findPlace(type.create(attrs), marks, false); + if (innerMarks) + innerMarks = this.enterInner(type, attrs, marks, true, preserveWS); + return innerMarks; + } + // Open a node of the given type + enterInner(type, attrs, marks, solid = false, preserveWS) { + this.closeExtra(); + let top = this.top; + top.match = top.match && top.match.matchType(type); + let options = wsOptionsFor(type, preserveWS, top.options); + if (top.options & OPT_OPEN_LEFT && top.content.length == 0) + options |= OPT_OPEN_LEFT; + let applyMarks = Mark.none; + marks = marks.filter((m2) => { + if (top.type ? top.type.allowsMarkType(m2.type) : markMayApply(m2.type, type)) { + applyMarks = m2.addToSet(applyMarks); + return false; + } + return true; + }); + this.nodes.push(new NodeContext(type, attrs, applyMarks, solid, null, options)); + this.open++; + return marks; + } + // Make sure all nodes above this.open are finished and added to + // their parents + closeExtra(openEnd = false) { + let i5 = this.nodes.length - 1; + if (i5 > this.open) { + for (; i5 > this.open; i5--) + this.nodes[i5 - 1].content.push(this.nodes[i5].finish(openEnd)); + this.nodes.length = this.open + 1; + } + } + finish() { + this.open = 0; + this.closeExtra(this.isOpen); + return this.nodes[0].finish(!!(this.isOpen || this.options.topOpen)); + } + sync(to) { + for (let i5 = this.open; i5 >= 0; i5--) { + if (this.nodes[i5] == to) { + this.open = i5; + return true; + } else if (this.localPreserveWS) { + this.nodes[i5].options |= OPT_PRESERVE_WS; + } + } + return false; + } + get currentPos() { + this.closeExtra(); + let pos = 0; + for (let i5 = this.open; i5 >= 0; i5--) { + let content = this.nodes[i5].content; + for (let j2 = content.length - 1; j2 >= 0; j2--) + pos += content[j2].nodeSize; + if (i5) + pos++; + } + return pos; + } + findAtPoint(parent, offset) { + if (this.find) + for (let i5 = 0; i5 < this.find.length; i5++) { + if (this.find[i5].node == parent && this.find[i5].offset == offset) + this.find[i5].pos = this.currentPos; + } + } + findInside(parent) { + if (this.find) + for (let i5 = 0; i5 < this.find.length; i5++) { + if (this.find[i5].pos == null && parent.nodeType == 1 && parent.contains(this.find[i5].node)) + this.find[i5].pos = this.currentPos; + } + } + findAround(parent, content, before) { + if (parent != content && this.find) + for (let i5 = 0; i5 < this.find.length; i5++) { + if (this.find[i5].pos == null && parent.nodeType == 1 && parent.contains(this.find[i5].node)) { + let pos = content.compareDocumentPosition(this.find[i5].node); + if (pos & (before ? 2 : 4)) + this.find[i5].pos = this.currentPos; + } + } + } + findInText(textNode) { + if (this.find) + for (let i5 = 0; i5 < this.find.length; i5++) { + if (this.find[i5].node == textNode) + this.find[i5].pos = this.currentPos - (textNode.nodeValue.length - this.find[i5].offset); + } + } + // Determines whether the given context string matches this context. + matchesContext(context) { + if (context.indexOf("|") > -1) + return context.split(/\s*\|\s*/).some(this.matchesContext, this); + let parts = context.split("/"); + let option = this.options.context; + let useRoot = !this.isOpen && (!option || option.parent.type == this.nodes[0].type); + let minDepth = -(option ? option.depth + 1 : 0) + (useRoot ? 0 : 1); + let match = (i5, depth) => { + for (; i5 >= 0; i5--) { + let part = parts[i5]; + if (part == "") { + if (i5 == parts.length - 1 || i5 == 0) + continue; + for (; depth >= minDepth; depth--) + if (match(i5 - 1, depth)) + return true; + return false; + } else { + let next = depth > 0 || depth == 0 && useRoot ? this.nodes[depth].type : option && depth >= minDepth ? option.node(depth - minDepth).type : null; + if (!next || next.name != part && !next.isInGroup(part)) + return false; + depth--; + } + } + return true; + }; + return match(parts.length - 1, this.open); + } + textblockFromContext() { + let $context = this.options.context; + if ($context) + for (let d3 = $context.depth; d3 >= 0; d3--) { + let deflt = $context.node(d3).contentMatchAt($context.indexAfter(d3)).defaultType; + if (deflt && deflt.isTextblock && deflt.defaultAttrs) + return deflt; + } + for (let name in this.parser.schema.nodes) { + let type = this.parser.schema.nodes[name]; + if (type.isTextblock && type.defaultAttrs) + return type; + } + } +}; +function normalizeList(dom) { + for (let child = dom.firstChild, prevItem = null; child; child = child.nextSibling) { + let name = child.nodeType == 1 ? child.nodeName.toLowerCase() : null; + if (name && listTags.hasOwnProperty(name) && prevItem) { + prevItem.appendChild(child); + child = prevItem; + } else if (name == "li") { + prevItem = child; + } else if (name) { + prevItem = null; + } + } +} +function matches(dom, selector) { + return (dom.matches || dom.msMatchesSelector || dom.webkitMatchesSelector || dom.mozMatchesSelector).call(dom, selector); +} +function copy(obj) { + let copy2 = {}; + for (let prop in obj) + copy2[prop] = obj[prop]; + return copy2; +} +function markMayApply(markType, nodeType) { + let nodes = nodeType.schema.nodes; + for (let name in nodes) { + let parent = nodes[name]; + if (!parent.allowsMarkType(markType)) + continue; + let seen = [], scan = (match) => { + seen.push(match); + for (let i5 = 0; i5 < match.edgeCount; i5++) { + let { type, next } = match.edge(i5); + if (type == nodeType) + return true; + if (seen.indexOf(next) < 0 && scan(next)) + return true; + } + }; + if (scan(parent.contentMatch)) + return true; + } +} +var DOMSerializer = class _DOMSerializer { + /** + Create a serializer. `nodes` should map node names to functions + that take a node and return a description of the corresponding + DOM. `marks` does the same for mark names, but also gets an + argument that tells it whether the mark's content is block or + inline content (for typical use, it'll always be inline). A mark + serializer may be `null` to indicate that marks of that type + should not be serialized. + */ + constructor(nodes, marks) { + this.nodes = nodes; + this.marks = marks; + } + /** + Serialize the content of this fragment to a DOM fragment. When + not in the browser, the `document` option, containing a DOM + document, should be passed so that the serializer can create + nodes. + */ + serializeFragment(fragment, options = {}, target) { + if (!target) + target = doc(options).createDocumentFragment(); + let top = target, active = []; + fragment.forEach((node) => { + if (active.length || node.marks.length) { + let keep = 0, rendered = 0; + while (keep < active.length && rendered < node.marks.length) { + let next = node.marks[rendered]; + if (!this.marks[next.type.name]) { + rendered++; + continue; + } + if (!next.eq(active[keep][0]) || next.type.spec.spanning === false) + break; + keep++; + rendered++; + } + while (keep < active.length) + top = active.pop()[1]; + while (rendered < node.marks.length) { + let add = node.marks[rendered++]; + let markDOM = this.serializeMark(add, node.isInline, options); + if (markDOM) { + active.push([add, top]); + top.appendChild(markDOM.dom); + top = markDOM.contentDOM || markDOM.dom; + } + } + } + top.appendChild(this.serializeNodeInner(node, options)); + }); + return target; + } + /** + @internal + */ + serializeNodeInner(node, options) { + let { dom, contentDOM } = renderSpec(doc(options), this.nodes[node.type.name](node), null, node.attrs); + if (contentDOM) { + if (node.isLeaf) + throw new RangeError("Content hole not allowed in a leaf node spec"); + this.serializeFragment(node.content, options, contentDOM); + } + return dom; + } + /** + Serialize this node to a DOM node. This can be useful when you + need to serialize a part of a document, as opposed to the whole + document. To serialize a whole document, use + [`serializeFragment`](https://prosemirror.net/docs/ref/#model.DOMSerializer.serializeFragment) on + its [content](https://prosemirror.net/docs/ref/#model.Node.content). + */ + serializeNode(node, options = {}) { + let dom = this.serializeNodeInner(node, options); + for (let i5 = node.marks.length - 1; i5 >= 0; i5--) { + let wrap2 = this.serializeMark(node.marks[i5], node.isInline, options); + if (wrap2) { + (wrap2.contentDOM || wrap2.dom).appendChild(dom); + dom = wrap2.dom; + } + } + return dom; + } + /** + @internal + */ + serializeMark(mark, inline, options = {}) { + let toDOM = this.marks[mark.type.name]; + return toDOM && renderSpec(doc(options), toDOM(mark, inline), null, mark.attrs); + } + static renderSpec(doc3, structure, xmlNS = null, blockArraysIn) { + return renderSpec(doc3, structure, xmlNS, blockArraysIn); + } + /** + Build a serializer using the [`toDOM`](https://prosemirror.net/docs/ref/#model.NodeSpec.toDOM) + properties in a schema's node and mark specs. + */ + static fromSchema(schema) { + return schema.cached.domSerializer || (schema.cached.domSerializer = new _DOMSerializer(this.nodesFromSchema(schema), this.marksFromSchema(schema))); + } + /** + Gather the serializers in a schema's node specs into an object. + This can be useful as a base to build a custom serializer from. + */ + static nodesFromSchema(schema) { + let result = gatherToDOM(schema.nodes); + if (!result.text) + result.text = (node) => node.text; + return result; + } + /** + Gather the serializers in a schema's mark specs into an object. + */ + static marksFromSchema(schema) { + return gatherToDOM(schema.marks); + } +}; +function gatherToDOM(obj) { + let result = {}; + for (let name in obj) { + let toDOM = obj[name].spec.toDOM; + if (toDOM) + result[name] = toDOM; + } + return result; +} +function doc(options) { + return options.document || window.document; +} +var suspiciousAttributeCache = /* @__PURE__ */ new WeakMap(); +function suspiciousAttributes(attrs) { + let value = suspiciousAttributeCache.get(attrs); + if (value === void 0) + suspiciousAttributeCache.set(attrs, value = suspiciousAttributesInner(attrs)); + return value; +} +function suspiciousAttributesInner(attrs) { + let result = null; + function scan(value) { + if (value && typeof value == "object") { + if (Array.isArray(value)) { + if (typeof value[0] == "string") { + if (!result) + result = []; + result.push(value); + } else { + for (let i5 = 0; i5 < value.length; i5++) + scan(value[i5]); + } + } else { + for (let prop in value) + scan(value[prop]); + } + } + } + scan(attrs); + return result; +} +function renderSpec(doc3, structure, xmlNS, blockArraysIn) { + if (typeof structure == "string") + return { dom: doc3.createTextNode(structure) }; + if (structure.nodeType != null) + return { dom: structure }; + if (structure.dom && structure.dom.nodeType != null) + return structure; + let tagName = structure[0], suspicious; + if (typeof tagName != "string") + throw new RangeError("Invalid array passed to renderSpec"); + if (blockArraysIn && (suspicious = suspiciousAttributes(blockArraysIn)) && suspicious.indexOf(structure) > -1) + throw new RangeError("Using an array from an attribute object as a DOM spec. This may be an attempted cross site scripting attack."); + let space = tagName.indexOf(" "); + if (space > 0) { + xmlNS = tagName.slice(0, space); + tagName = tagName.slice(space + 1); + } + let contentDOM; + let dom = xmlNS ? doc3.createElementNS(xmlNS, tagName) : doc3.createElement(tagName); + let attrs = structure[1], start = 1; + if (attrs && typeof attrs == "object" && attrs.nodeType == null && !Array.isArray(attrs)) { + start = 2; + for (let name in attrs) + if (attrs[name] != null) { + let space2 = name.indexOf(" "); + if (space2 > 0) + dom.setAttributeNS(name.slice(0, space2), name.slice(space2 + 1), attrs[name]); + else + dom.setAttribute(name, attrs[name]); + } + } + for (let i5 = start; i5 < structure.length; i5++) { + let child = structure[i5]; + if (child === 0) { + if (i5 < structure.length - 1 || i5 > start) + throw new RangeError("Content hole must be the only child of its parent node"); + return { dom, contentDOM: dom }; + } else { + let { dom: inner, contentDOM: innerContent } = renderSpec(doc3, child, xmlNS, blockArraysIn); + dom.appendChild(inner); + if (innerContent) { + if (contentDOM) + throw new RangeError("Multiple content holes"); + contentDOM = innerContent; + } + } + } + return { dom, contentDOM }; +} + +// node_modules/prosemirror-transform/dist/index.js +var lower16 = 65535; +var factor16 = Math.pow(2, 16); +function makeRecover(index, offset) { + return index + offset * factor16; +} +function recoverIndex(value) { + return value & lower16; +} +function recoverOffset(value) { + return (value - (value & lower16)) / factor16; +} +var DEL_BEFORE = 1; +var DEL_AFTER = 2; +var DEL_ACROSS = 4; +var DEL_SIDE = 8; +var MapResult = class { + /** + @internal + */ + constructor(pos, delInfo, recover) { + this.pos = pos; + this.delInfo = delInfo; + this.recover = recover; + } + /** + Tells you whether the position was deleted, that is, whether the + step removed the token on the side queried (via the `assoc`) + argument from the document. + */ + get deleted() { + return (this.delInfo & DEL_SIDE) > 0; + } + /** + Tells you whether the token before the mapped position was deleted. + */ + get deletedBefore() { + return (this.delInfo & (DEL_BEFORE | DEL_ACROSS)) > 0; + } + /** + True when the token after the mapped position was deleted. + */ + get deletedAfter() { + return (this.delInfo & (DEL_AFTER | DEL_ACROSS)) > 0; + } + /** + Tells whether any of the steps mapped through deletes across the + position (including both the token before and after the + position). + */ + get deletedAcross() { + return (this.delInfo & DEL_ACROSS) > 0; + } +}; +var StepMap = class _StepMap { + /** + Create a position map. The modifications to the document are + represented as an array of numbers, in which each group of three + represents a modified chunk as `[start, oldSize, newSize]`. + */ + constructor(ranges, inverted = false) { + this.ranges = ranges; + this.inverted = inverted; + if (!ranges.length && _StepMap.empty) + return _StepMap.empty; + } + /** + @internal + */ + recover(value) { + let diff = 0, index = recoverIndex(value); + if (!this.inverted) + for (let i5 = 0; i5 < index; i5++) + diff += this.ranges[i5 * 3 + 2] - this.ranges[i5 * 3 + 1]; + return this.ranges[index * 3] + diff + recoverOffset(value); + } + mapResult(pos, assoc = 1) { + return this._map(pos, assoc, false); + } + map(pos, assoc = 1) { + return this._map(pos, assoc, true); + } + /** + @internal + */ + _map(pos, assoc, simple) { + let diff = 0, oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2; + for (let i5 = 0; i5 < this.ranges.length; i5 += 3) { + let start = this.ranges[i5] - (this.inverted ? diff : 0); + if (start > pos) + break; + let oldSize = this.ranges[i5 + oldIndex], newSize = this.ranges[i5 + newIndex], end = start + oldSize; + if (pos <= end) { + let side = !oldSize ? assoc : pos == start ? -1 : pos == end ? 1 : assoc; + let result = start + diff + (side < 0 ? 0 : newSize); + if (simple) + return result; + let recover = pos == (assoc < 0 ? start : end) ? null : makeRecover(i5 / 3, pos - start); + let del2 = pos == start ? DEL_AFTER : pos == end ? DEL_BEFORE : DEL_ACROSS; + if (assoc < 0 ? pos != start : pos != end) + del2 |= DEL_SIDE; + return new MapResult(result, del2, recover); + } + diff += newSize - oldSize; + } + return simple ? pos + diff : new MapResult(pos + diff, 0, null); + } + /** + @internal + */ + touches(pos, recover) { + let diff = 0, index = recoverIndex(recover); + let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2; + for (let i5 = 0; i5 < this.ranges.length; i5 += 3) { + let start = this.ranges[i5] - (this.inverted ? diff : 0); + if (start > pos) + break; + let oldSize = this.ranges[i5 + oldIndex], end = start + oldSize; + if (pos <= end && i5 == index * 3) + return true; + diff += this.ranges[i5 + newIndex] - oldSize; + } + return false; + } + /** + Calls the given function on each of the changed ranges included in + this map. + */ + forEach(f3) { + let oldIndex = this.inverted ? 2 : 1, newIndex = this.inverted ? 1 : 2; + for (let i5 = 0, diff = 0; i5 < this.ranges.length; i5 += 3) { + let start = this.ranges[i5], oldStart = start - (this.inverted ? diff : 0), newStart = start + (this.inverted ? 0 : diff); + let oldSize = this.ranges[i5 + oldIndex], newSize = this.ranges[i5 + newIndex]; + f3(oldStart, oldStart + oldSize, newStart, newStart + newSize); + diff += newSize - oldSize; + } + } + /** + Create an inverted version of this map. The result can be used to + map positions in the post-step document to the pre-step document. + */ + invert() { + return new _StepMap(this.ranges, !this.inverted); + } + /** + @internal + */ + toString() { + return (this.inverted ? "-" : "") + JSON.stringify(this.ranges); + } + /** + Create a map that moves all positions by offset `n` (which may be + negative). This can be useful when applying steps meant for a + sub-document to a larger document, or vice-versa. + */ + static offset(n4) { + return n4 == 0 ? _StepMap.empty : new _StepMap(n4 < 0 ? [0, -n4, 0] : [0, 0, n4]); + } +}; +StepMap.empty = new StepMap([]); +var Mapping = class _Mapping { + /** + Create a new mapping with the given position maps. + */ + constructor(maps, mirror, from = 0, to = maps ? maps.length : 0) { + this.mirror = mirror; + this.from = from; + this.to = to; + this._maps = maps || []; + this.ownData = !(maps || mirror); + } + /** + The step maps in this mapping. + */ + get maps() { + return this._maps; + } + /** + Create a mapping that maps only through a part of this one. + */ + slice(from = 0, to = this.maps.length) { + return new _Mapping(this._maps, this.mirror, from, to); + } + /** + Add a step map to the end of this mapping. If `mirrors` is + given, it should be the index of the step map that is the mirror + image of this one. + */ + appendMap(map, mirrors) { + if (!this.ownData) { + this._maps = this._maps.slice(); + this.mirror = this.mirror && this.mirror.slice(); + this.ownData = true; + } + this.to = this._maps.push(map); + if (mirrors != null) + this.setMirror(this._maps.length - 1, mirrors); + } + /** + Add all the step maps in a given mapping to this one (preserving + mirroring information). + */ + appendMapping(mapping) { + for (let i5 = 0, startSize = this._maps.length; i5 < mapping._maps.length; i5++) { + let mirr = mapping.getMirror(i5); + this.appendMap(mapping._maps[i5], mirr != null && mirr < i5 ? startSize + mirr : void 0); + } + } + /** + Finds the offset of the step map that mirrors the map at the + given offset, in this mapping (as per the second argument to + `appendMap`). + */ + getMirror(n4) { + if (this.mirror) { + for (let i5 = 0; i5 < this.mirror.length; i5++) + if (this.mirror[i5] == n4) + return this.mirror[i5 + (i5 % 2 ? -1 : 1)]; + } + } + /** + @internal + */ + setMirror(n4, m2) { + if (!this.mirror) + this.mirror = []; + this.mirror.push(n4, m2); + } + /** + Append the inverse of the given mapping to this one. + */ + appendMappingInverted(mapping) { + for (let i5 = mapping.maps.length - 1, totalSize = this._maps.length + mapping._maps.length; i5 >= 0; i5--) { + let mirr = mapping.getMirror(i5); + this.appendMap(mapping._maps[i5].invert(), mirr != null && mirr > i5 ? totalSize - mirr - 1 : void 0); + } + } + /** + Create an inverted version of this mapping. + */ + invert() { + let inverse = new _Mapping(); + inverse.appendMappingInverted(this); + return inverse; + } + /** + Map a position through this mapping. + */ + map(pos, assoc = 1) { + if (this.mirror) + return this._map(pos, assoc, true); + for (let i5 = this.from; i5 < this.to; i5++) + pos = this._maps[i5].map(pos, assoc); + return pos; + } + /** + Map a position through this mapping, returning a mapping + result. + */ + mapResult(pos, assoc = 1) { + return this._map(pos, assoc, false); + } + /** + @internal + */ + _map(pos, assoc, simple) { + let delInfo = 0; + for (let i5 = this.from; i5 < this.to; i5++) { + let map = this._maps[i5], result = map.mapResult(pos, assoc); + if (result.recover != null) { + let corr = this.getMirror(i5); + if (corr != null && corr > i5 && corr < this.to) { + i5 = corr; + pos = this._maps[corr].recover(result.recover); + continue; + } + } + delInfo |= result.delInfo; + pos = result.pos; + } + return simple ? pos : new MapResult(pos, delInfo, null); + } +}; +var stepsByID = /* @__PURE__ */ Object.create(null); +var Step = class { + /** + Get the step map that represents the changes made by this step, + and which can be used to transform between positions in the old + and the new document. + */ + getMap() { + return StepMap.empty; + } + /** + Try to merge this step with another one, to be applied directly + after it. Returns the merged step when possible, null if the + steps can't be merged. + */ + merge(other) { + return null; + } + /** + Deserialize a step from its JSON representation. Will call + through to the step class' own implementation of this method. + */ + static fromJSON(schema, json) { + if (!json || !json.stepType) + throw new RangeError("Invalid input for Step.fromJSON"); + let type = stepsByID[json.stepType]; + if (!type) + throw new RangeError(`No step type ${json.stepType} defined`); + return type.fromJSON(schema, json); + } + /** + To be able to serialize steps to JSON, each step needs a string + ID to attach to its JSON representation. Use this method to + register an ID for your step classes. Try to pick something + that's unlikely to clash with steps from other modules. + */ + static jsonID(id, stepClass) { + if (id in stepsByID) + throw new RangeError("Duplicate use of step JSON ID " + id); + stepsByID[id] = stepClass; + stepClass.prototype.jsonID = id; + return stepClass; + } +}; +var StepResult = class _StepResult { + /** + @internal + */ + constructor(doc3, failed) { + this.doc = doc3; + this.failed = failed; + } + /** + Create a successful step result. + */ + static ok(doc3) { + return new _StepResult(doc3, null); + } + /** + Create a failed step result. + */ + static fail(message) { + return new _StepResult(null, message); + } + /** + Call [`Node.replace`](https://prosemirror.net/docs/ref/#model.Node.replace) with the given + arguments. Create a successful result if it succeeds, and a + failed one if it throws a `ReplaceError`. + */ + static fromReplace(doc3, from, to, slice) { + try { + return _StepResult.ok(doc3.replace(from, to, slice)); + } catch (e4) { + if (e4 instanceof ReplaceError) + return _StepResult.fail(e4.message); + throw e4; + } + } +}; +function mapFragment(fragment, f3, parent) { + let mapped = []; + for (let i5 = 0; i5 < fragment.childCount; i5++) { + let child = fragment.child(i5); + if (child.content.size) + child = child.copy(mapFragment(child.content, f3, child)); + if (child.isInline) + child = f3(child, parent, i5); + mapped.push(child); + } + return Fragment.fromArray(mapped); +} +var AddMarkStep = class _AddMarkStep extends Step { + /** + Create a mark step. + */ + constructor(from, to, mark) { + super(); + this.from = from; + this.to = to; + this.mark = mark; + } + apply(doc3) { + let oldSlice = doc3.slice(this.from, this.to), $from = doc3.resolve(this.from); + let parent = $from.node($from.sharedDepth(this.to)); + let slice = new Slice(mapFragment(oldSlice.content, (node, parent2) => { + if (!node.isAtom || !parent2.type.allowsMarkType(this.mark.type)) + return node; + return node.mark(this.mark.addToSet(node.marks)); + }, parent), oldSlice.openStart, oldSlice.openEnd); + return StepResult.fromReplace(doc3, this.from, this.to, slice); + } + invert() { + return new RemoveMarkStep(this.from, this.to, this.mark); + } + map(mapping) { + let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); + if (from.deleted && to.deleted || from.pos >= to.pos) + return null; + return new _AddMarkStep(from.pos, to.pos, this.mark); + } + merge(other) { + if (other instanceof _AddMarkStep && other.mark.eq(this.mark) && this.from <= other.to && this.to >= other.from) + return new _AddMarkStep(Math.min(this.from, other.from), Math.max(this.to, other.to), this.mark); + return null; + } + toJSON() { + return { + stepType: "addMark", + mark: this.mark.toJSON(), + from: this.from, + to: this.to + }; + } + /** + @internal + */ + static fromJSON(schema, json) { + if (typeof json.from != "number" || typeof json.to != "number") + throw new RangeError("Invalid input for AddMarkStep.fromJSON"); + return new _AddMarkStep(json.from, json.to, schema.markFromJSON(json.mark)); + } +}; +Step.jsonID("addMark", AddMarkStep); +var RemoveMarkStep = class _RemoveMarkStep extends Step { + /** + Create a mark-removing step. + */ + constructor(from, to, mark) { + super(); + this.from = from; + this.to = to; + this.mark = mark; + } + apply(doc3) { + let oldSlice = doc3.slice(this.from, this.to); + let slice = new Slice(mapFragment(oldSlice.content, (node) => { + return node.mark(this.mark.removeFromSet(node.marks)); + }, doc3), oldSlice.openStart, oldSlice.openEnd); + return StepResult.fromReplace(doc3, this.from, this.to, slice); + } + invert() { + return new AddMarkStep(this.from, this.to, this.mark); + } + map(mapping) { + let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); + if (from.deleted && to.deleted || from.pos >= to.pos) + return null; + return new _RemoveMarkStep(from.pos, to.pos, this.mark); + } + merge(other) { + if (other instanceof _RemoveMarkStep && other.mark.eq(this.mark) && this.from <= other.to && this.to >= other.from) + return new _RemoveMarkStep(Math.min(this.from, other.from), Math.max(this.to, other.to), this.mark); + return null; + } + toJSON() { + return { + stepType: "removeMark", + mark: this.mark.toJSON(), + from: this.from, + to: this.to + }; + } + /** + @internal + */ + static fromJSON(schema, json) { + if (typeof json.from != "number" || typeof json.to != "number") + throw new RangeError("Invalid input for RemoveMarkStep.fromJSON"); + return new _RemoveMarkStep(json.from, json.to, schema.markFromJSON(json.mark)); + } +}; +Step.jsonID("removeMark", RemoveMarkStep); +var AddNodeMarkStep = class _AddNodeMarkStep extends Step { + /** + Create a node mark step. + */ + constructor(pos, mark) { + super(); + this.pos = pos; + this.mark = mark; + } + apply(doc3) { + let node = doc3.nodeAt(this.pos); + if (!node) + return StepResult.fail("No node at mark step's position"); + let updated = node.type.create(node.attrs, null, this.mark.addToSet(node.marks)); + return StepResult.fromReplace(doc3, this.pos, this.pos + 1, new Slice(Fragment.from(updated), 0, node.isLeaf ? 0 : 1)); + } + invert(doc3) { + let node = doc3.nodeAt(this.pos); + if (node) { + let newSet = this.mark.addToSet(node.marks); + if (newSet.length == node.marks.length) { + for (let i5 = 0; i5 < node.marks.length; i5++) + if (!node.marks[i5].isInSet(newSet)) + return new _AddNodeMarkStep(this.pos, node.marks[i5]); + return new _AddNodeMarkStep(this.pos, this.mark); + } + } + return new RemoveNodeMarkStep(this.pos, this.mark); + } + map(mapping) { + let pos = mapping.mapResult(this.pos, 1); + return pos.deletedAfter ? null : new _AddNodeMarkStep(pos.pos, this.mark); + } + toJSON() { + return { stepType: "addNodeMark", pos: this.pos, mark: this.mark.toJSON() }; + } + /** + @internal + */ + static fromJSON(schema, json) { + if (typeof json.pos != "number") + throw new RangeError("Invalid input for AddNodeMarkStep.fromJSON"); + return new _AddNodeMarkStep(json.pos, schema.markFromJSON(json.mark)); + } +}; +Step.jsonID("addNodeMark", AddNodeMarkStep); +var RemoveNodeMarkStep = class _RemoveNodeMarkStep extends Step { + /** + Create a mark-removing step. + */ + constructor(pos, mark) { + super(); + this.pos = pos; + this.mark = mark; + } + apply(doc3) { + let node = doc3.nodeAt(this.pos); + if (!node) + return StepResult.fail("No node at mark step's position"); + let updated = node.type.create(node.attrs, null, this.mark.removeFromSet(node.marks)); + return StepResult.fromReplace(doc3, this.pos, this.pos + 1, new Slice(Fragment.from(updated), 0, node.isLeaf ? 0 : 1)); + } + invert(doc3) { + let node = doc3.nodeAt(this.pos); + if (!node || !this.mark.isInSet(node.marks)) + return this; + return new AddNodeMarkStep(this.pos, this.mark); + } + map(mapping) { + let pos = mapping.mapResult(this.pos, 1); + return pos.deletedAfter ? null : new _RemoveNodeMarkStep(pos.pos, this.mark); + } + toJSON() { + return { stepType: "removeNodeMark", pos: this.pos, mark: this.mark.toJSON() }; + } + /** + @internal + */ + static fromJSON(schema, json) { + if (typeof json.pos != "number") + throw new RangeError("Invalid input for RemoveNodeMarkStep.fromJSON"); + return new _RemoveNodeMarkStep(json.pos, schema.markFromJSON(json.mark)); + } +}; +Step.jsonID("removeNodeMark", RemoveNodeMarkStep); +var ReplaceStep = class _ReplaceStep extends Step { + /** + The given `slice` should fit the 'gap' between `from` and + `to`—the depths must line up, and the surrounding nodes must be + able to be joined with the open sides of the slice. When + `structure` is true, the step will fail if the content between + from and to is not just a sequence of closing and then opening + tokens (this is to guard against rebased replace steps + overwriting something they weren't supposed to). + */ + constructor(from, to, slice, structure = false) { + super(); + this.from = from; + this.to = to; + this.slice = slice; + this.structure = structure; + } + apply(doc3) { + if (this.structure && contentBetween(doc3, this.from, this.to)) + return StepResult.fail("Structure replace would overwrite content"); + return StepResult.fromReplace(doc3, this.from, this.to, this.slice); + } + getMap() { + return new StepMap([this.from, this.to - this.from, this.slice.size]); + } + invert(doc3) { + return new _ReplaceStep(this.from, this.from + this.slice.size, doc3.slice(this.from, this.to)); + } + map(mapping) { + let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); + if (from.deletedAcross && to.deletedAcross) + return null; + return new _ReplaceStep(from.pos, Math.max(from.pos, to.pos), this.slice, this.structure); + } + merge(other) { + if (!(other instanceof _ReplaceStep) || other.structure || this.structure) + return null; + if (this.from + this.slice.size == other.from && !this.slice.openEnd && !other.slice.openStart) { + let slice = this.slice.size + other.slice.size == 0 ? Slice.empty : new Slice(this.slice.content.append(other.slice.content), this.slice.openStart, other.slice.openEnd); + return new _ReplaceStep(this.from, this.to + (other.to - other.from), slice, this.structure); + } else if (other.to == this.from && !this.slice.openStart && !other.slice.openEnd) { + let slice = this.slice.size + other.slice.size == 0 ? Slice.empty : new Slice(other.slice.content.append(this.slice.content), other.slice.openStart, this.slice.openEnd); + return new _ReplaceStep(other.from, this.to, slice, this.structure); + } else { + return null; + } + } + toJSON() { + let json = { stepType: "replace", from: this.from, to: this.to }; + if (this.slice.size) + json.slice = this.slice.toJSON(); + if (this.structure) + json.structure = true; + return json; + } + /** + @internal + */ + static fromJSON(schema, json) { + if (typeof json.from != "number" || typeof json.to != "number") + throw new RangeError("Invalid input for ReplaceStep.fromJSON"); + return new _ReplaceStep(json.from, json.to, Slice.fromJSON(schema, json.slice), !!json.structure); + } +}; +Step.jsonID("replace", ReplaceStep); +var ReplaceAroundStep = class _ReplaceAroundStep extends Step { + /** + Create a replace-around step with the given range and gap. + `insert` should be the point in the slice into which the content + of the gap should be moved. `structure` has the same meaning as + it has in the [`ReplaceStep`](https://prosemirror.net/docs/ref/#transform.ReplaceStep) class. + */ + constructor(from, to, gapFrom, gapTo, slice, insert, structure = false) { + super(); + this.from = from; + this.to = to; + this.gapFrom = gapFrom; + this.gapTo = gapTo; + this.slice = slice; + this.insert = insert; + this.structure = structure; + } + apply(doc3) { + if (this.structure && (contentBetween(doc3, this.from, this.gapFrom) || contentBetween(doc3, this.gapTo, this.to))) + return StepResult.fail("Structure gap-replace would overwrite content"); + let gap = doc3.slice(this.gapFrom, this.gapTo); + if (gap.openStart || gap.openEnd) + return StepResult.fail("Gap is not a flat range"); + let inserted = this.slice.insertAt(this.insert, gap.content); + if (!inserted) + return StepResult.fail("Content does not fit in gap"); + return StepResult.fromReplace(doc3, this.from, this.to, inserted); + } + getMap() { + return new StepMap([ + this.from, + this.gapFrom - this.from, + this.insert, + this.gapTo, + this.to - this.gapTo, + this.slice.size - this.insert + ]); + } + invert(doc3) { + let gap = this.gapTo - this.gapFrom; + return new _ReplaceAroundStep(this.from, this.from + this.slice.size + gap, this.from + this.insert, this.from + this.insert + gap, doc3.slice(this.from, this.to).removeBetween(this.gapFrom - this.from, this.gapTo - this.from), this.gapFrom - this.from, this.structure); + } + map(mapping) { + let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1); + let gapFrom = this.from == this.gapFrom ? from.pos : mapping.map(this.gapFrom, -1); + let gapTo = this.to == this.gapTo ? to.pos : mapping.map(this.gapTo, 1); + if (from.deletedAcross && to.deletedAcross || gapFrom < from.pos || gapTo > to.pos) + return null; + return new _ReplaceAroundStep(from.pos, to.pos, gapFrom, gapTo, this.slice, this.insert, this.structure); + } + toJSON() { + let json = { + stepType: "replaceAround", + from: this.from, + to: this.to, + gapFrom: this.gapFrom, + gapTo: this.gapTo, + insert: this.insert + }; + if (this.slice.size) + json.slice = this.slice.toJSON(); + if (this.structure) + json.structure = true; + return json; + } + /** + @internal + */ + static fromJSON(schema, json) { + if (typeof json.from != "number" || typeof json.to != "number" || typeof json.gapFrom != "number" || typeof json.gapTo != "number" || typeof json.insert != "number") + throw new RangeError("Invalid input for ReplaceAroundStep.fromJSON"); + return new _ReplaceAroundStep(json.from, json.to, json.gapFrom, json.gapTo, Slice.fromJSON(schema, json.slice), json.insert, !!json.structure); + } +}; +Step.jsonID("replaceAround", ReplaceAroundStep); +function contentBetween(doc3, from, to) { + let $from = doc3.resolve(from), dist = to - from, depth = $from.depth; + while (dist > 0 && depth > 0 && $from.indexAfter(depth) == $from.node(depth).childCount) { + depth--; + dist--; + } + if (dist > 0) { + let next = $from.node(depth).maybeChild($from.indexAfter(depth)); + while (dist > 0) { + if (!next || next.isLeaf) + return true; + next = next.firstChild; + dist--; + } + } + return false; +} +function addMark(tr, from, to, mark) { + let removed = [], added = []; + let removing, adding; + tr.doc.nodesBetween(from, to, (node, pos, parent) => { + if (!node.isInline) + return; + let marks = node.marks; + if (!mark.isInSet(marks) && parent.type.allowsMarkType(mark.type)) { + let start = Math.max(pos, from), end = Math.min(pos + node.nodeSize, to); + let newSet = mark.addToSet(marks); + for (let i5 = 0; i5 < marks.length; i5++) { + if (!marks[i5].isInSet(newSet)) { + if (removing && removing.to == start && removing.mark.eq(marks[i5])) + removing.to = end; + else + removed.push(removing = new RemoveMarkStep(start, end, marks[i5])); + } + } + if (adding && adding.to == start) + adding.to = end; + else + added.push(adding = new AddMarkStep(start, end, mark)); + } + }); + removed.forEach((s4) => tr.step(s4)); + added.forEach((s4) => tr.step(s4)); +} +function removeMark(tr, from, to, mark) { + let matched = [], step = 0; + tr.doc.nodesBetween(from, to, (node, pos) => { + if (!node.isInline) + return; + step++; + let toRemove = null; + if (mark instanceof MarkType) { + let set = node.marks, found2; + while (found2 = mark.isInSet(set)) { + (toRemove || (toRemove = [])).push(found2); + set = found2.removeFromSet(set); + } + } else if (mark) { + if (mark.isInSet(node.marks)) + toRemove = [mark]; + } else { + toRemove = node.marks; + } + if (toRemove && toRemove.length) { + let end = Math.min(pos + node.nodeSize, to); + for (let i5 = 0; i5 < toRemove.length; i5++) { + let style2 = toRemove[i5], found2; + for (let j2 = 0; j2 < matched.length; j2++) { + let m2 = matched[j2]; + if (m2.step == step - 1 && style2.eq(matched[j2].style)) + found2 = m2; + } + if (found2) { + found2.to = end; + found2.step = step; + } else { + matched.push({ style: style2, from: Math.max(pos, from), to: end, step }); + } + } + } + }); + matched.forEach((m2) => tr.step(new RemoveMarkStep(m2.from, m2.to, m2.style))); +} +function clearIncompatible(tr, pos, parentType, match = parentType.contentMatch, clearNewlines = true) { + let node = tr.doc.nodeAt(pos); + let replSteps = [], cur = pos + 1; + for (let i5 = 0; i5 < node.childCount; i5++) { + let child = node.child(i5), end = cur + child.nodeSize; + let allowed = match.matchType(child.type); + if (!allowed) { + replSteps.push(new ReplaceStep(cur, end, Slice.empty)); + } else { + match = allowed; + for (let j2 = 0; j2 < child.marks.length; j2++) + if (!parentType.allowsMarkType(child.marks[j2].type)) + tr.step(new RemoveMarkStep(cur, end, child.marks[j2])); + if (clearNewlines && child.isText && parentType.whitespace != "pre") { + let m2, newline = /\r?\n|\r/g, slice; + while (m2 = newline.exec(child.text)) { + if (!slice) + slice = new Slice(Fragment.from(parentType.schema.text(" ", parentType.allowedMarks(child.marks))), 0, 0); + replSteps.push(new ReplaceStep(cur + m2.index, cur + m2.index + m2[0].length, slice)); + } + } + } + cur = end; + } + if (!match.validEnd) { + let fill = match.fillBefore(Fragment.empty, true); + tr.replace(cur, cur, new Slice(fill, 0, 0)); + } + for (let i5 = replSteps.length - 1; i5 >= 0; i5--) + tr.step(replSteps[i5]); +} +function canCut(node, start, end) { + return (start == 0 || node.canReplace(start, node.childCount)) && (end == node.childCount || node.canReplace(0, end)); +} +function liftTarget(range) { + let parent = range.parent; + let content = parent.content.cutByIndex(range.startIndex, range.endIndex); + for (let depth = range.depth; ; --depth) { + let node = range.$from.node(depth); + let index = range.$from.index(depth), endIndex = range.$to.indexAfter(depth); + if (depth < range.depth && node.canReplace(index, endIndex, content)) + return depth; + if (depth == 0 || node.type.spec.isolating || !canCut(node, index, endIndex)) + break; + } + return null; +} +function lift(tr, range, target) { + let { $from, $to, depth } = range; + let gapStart = $from.before(depth + 1), gapEnd = $to.after(depth + 1); + let start = gapStart, end = gapEnd; + let before = Fragment.empty, openStart = 0; + for (let d3 = depth, splitting = false; d3 > target; d3--) + if (splitting || $from.index(d3) > 0) { + splitting = true; + before = Fragment.from($from.node(d3).copy(before)); + openStart++; + } else { + start--; + } + let after = Fragment.empty, openEnd = 0; + for (let d3 = depth, splitting = false; d3 > target; d3--) + if (splitting || $to.after(d3 + 1) < $to.end(d3)) { + splitting = true; + after = Fragment.from($to.node(d3).copy(after)); + openEnd++; + } else { + end++; + } + tr.step(new ReplaceAroundStep(start, end, gapStart, gapEnd, new Slice(before.append(after), openStart, openEnd), before.size - openStart, true)); +} +function findWrapping(range, nodeType, attrs = null, innerRange = range) { + let around = findWrappingOutside(range, nodeType); + let inner = around && findWrappingInside(innerRange, nodeType); + if (!inner) + return null; + return around.map(withAttrs).concat({ type: nodeType, attrs }).concat(inner.map(withAttrs)); +} +function withAttrs(type) { + return { type, attrs: null }; +} +function findWrappingOutside(range, type) { + let { parent, startIndex, endIndex } = range; + let around = parent.contentMatchAt(startIndex).findWrapping(type); + if (!around) + return null; + let outer = around.length ? around[0] : type; + return parent.canReplaceWith(startIndex, endIndex, outer) ? around : null; +} +function findWrappingInside(range, type) { + let { parent, startIndex, endIndex } = range; + let inner = parent.child(startIndex); + let inside = type.contentMatch.findWrapping(inner.type); + if (!inside) + return null; + let lastType = inside.length ? inside[inside.length - 1] : type; + let innerMatch = lastType.contentMatch; + for (let i5 = startIndex; innerMatch && i5 < endIndex; i5++) + innerMatch = innerMatch.matchType(parent.child(i5).type); + if (!innerMatch || !innerMatch.validEnd) + return null; + return inside; +} +function wrap(tr, range, wrappers) { + let content = Fragment.empty; + for (let i5 = wrappers.length - 1; i5 >= 0; i5--) { + if (content.size) { + let match = wrappers[i5].type.contentMatch.matchFragment(content); + if (!match || !match.validEnd) + throw new RangeError("Wrapper type given to Transform.wrap does not form valid content of its parent wrapper"); + } + content = Fragment.from(wrappers[i5].type.create(wrappers[i5].attrs, content)); + } + let start = range.start, end = range.end; + tr.step(new ReplaceAroundStep(start, end, start, end, new Slice(content, 0, 0), wrappers.length, true)); +} +function setBlockType(tr, from, to, type, attrs) { + if (!type.isTextblock) + throw new RangeError("Type given to setBlockType should be a textblock"); + let mapFrom = tr.steps.length; + tr.doc.nodesBetween(from, to, (node, pos) => { + let attrsHere = typeof attrs == "function" ? attrs(node) : attrs; + if (node.isTextblock && !node.hasMarkup(type, attrsHere) && canChangeType(tr.doc, tr.mapping.slice(mapFrom).map(pos), type)) { + let convertNewlines = null; + if (type.schema.linebreakReplacement) { + let pre = type.whitespace == "pre", supportLinebreak = !!type.contentMatch.matchType(type.schema.linebreakReplacement); + if (pre && !supportLinebreak) + convertNewlines = false; + else if (!pre && supportLinebreak) + convertNewlines = true; + } + if (convertNewlines === false) + replaceLinebreaks(tr, node, pos, mapFrom); + clearIncompatible(tr, tr.mapping.slice(mapFrom).map(pos, 1), type, void 0, convertNewlines === null); + let mapping = tr.mapping.slice(mapFrom); + let startM = mapping.map(pos, 1), endM = mapping.map(pos + node.nodeSize, 1); + tr.step(new ReplaceAroundStep(startM, endM, startM + 1, endM - 1, new Slice(Fragment.from(type.create(attrsHere, null, node.marks)), 0, 0), 1, true)); + if (convertNewlines === true) + replaceNewlines(tr, node, pos, mapFrom); + return false; + } + }); +} +function replaceNewlines(tr, node, pos, mapFrom) { + node.forEach((child, offset) => { + if (child.isText) { + let m2, newline = /\r?\n|\r/g; + while (m2 = newline.exec(child.text)) { + let start = tr.mapping.slice(mapFrom).map(pos + 1 + offset + m2.index); + tr.replaceWith(start, start + 1, node.type.schema.linebreakReplacement.create()); + } + } + }); +} +function replaceLinebreaks(tr, node, pos, mapFrom) { + node.forEach((child, offset) => { + if (child.type == child.type.schema.linebreakReplacement) { + let start = tr.mapping.slice(mapFrom).map(pos + 1 + offset); + tr.replaceWith(start, start + 1, node.type.schema.text("\n")); + } + }); +} +function canChangeType(doc3, pos, type) { + let $pos = doc3.resolve(pos), index = $pos.index(); + return $pos.parent.canReplaceWith(index, index + 1, type); +} +function setNodeMarkup(tr, pos, type, attrs, marks) { + let node = tr.doc.nodeAt(pos); + if (!node) + throw new RangeError("No node at given position"); + if (!type) + type = node.type; + let newNode = type.create(attrs, null, marks || node.marks); + if (node.isLeaf) + return tr.replaceWith(pos, pos + node.nodeSize, newNode); + if (!type.validContent(node.content)) + throw new RangeError("Invalid content for node type " + type.name); + tr.step(new ReplaceAroundStep(pos, pos + node.nodeSize, pos + 1, pos + node.nodeSize - 1, new Slice(Fragment.from(newNode), 0, 0), 1, true)); +} +function canSplit(doc3, pos, depth = 1, typesAfter) { + let $pos = doc3.resolve(pos), base2 = $pos.depth - depth; + let innerType = typesAfter && typesAfter[typesAfter.length - 1] || $pos.parent; + if (base2 < 0 || $pos.parent.type.spec.isolating || !$pos.parent.canReplace($pos.index(), $pos.parent.childCount) || !innerType.type.validContent($pos.parent.content.cutByIndex($pos.index(), $pos.parent.childCount))) + return false; + for (let d3 = $pos.depth - 1, i5 = depth - 2; d3 > base2; d3--, i5--) { + let node = $pos.node(d3), index2 = $pos.index(d3); + if (node.type.spec.isolating) + return false; + let rest = node.content.cutByIndex(index2, node.childCount); + let overrideChild = typesAfter && typesAfter[i5 + 1]; + if (overrideChild) + rest = rest.replaceChild(0, overrideChild.type.create(overrideChild.attrs)); + let after = typesAfter && typesAfter[i5] || node; + if (!node.canReplace(index2 + 1, node.childCount) || !after.type.validContent(rest)) + return false; + } + let index = $pos.indexAfter(base2); + let baseType = typesAfter && typesAfter[0]; + return $pos.node(base2).canReplaceWith(index, index, baseType ? baseType.type : $pos.node(base2 + 1).type); +} +function split(tr, pos, depth = 1, typesAfter) { + let $pos = tr.doc.resolve(pos), before = Fragment.empty, after = Fragment.empty; + for (let d3 = $pos.depth, e4 = $pos.depth - depth, i5 = depth - 1; d3 > e4; d3--, i5--) { + before = Fragment.from($pos.node(d3).copy(before)); + let typeAfter = typesAfter && typesAfter[i5]; + after = Fragment.from(typeAfter ? typeAfter.type.create(typeAfter.attrs, after) : $pos.node(d3).copy(after)); + } + tr.step(new ReplaceStep(pos, pos, new Slice(before.append(after), depth, depth), true)); +} +function canJoin(doc3, pos) { + let $pos = doc3.resolve(pos), index = $pos.index(); + return joinable2($pos.nodeBefore, $pos.nodeAfter) && $pos.parent.canReplace(index, index + 1); +} +function canAppendWithSubstitutedLinebreaks(a3, b3) { + if (!b3.content.size) + a3.type.compatibleContent(b3.type); + let match = a3.contentMatchAt(a3.childCount); + let { linebreakReplacement } = a3.type.schema; + for (let i5 = 0; i5 < b3.childCount; i5++) { + let child = b3.child(i5); + let type = child.type == linebreakReplacement ? a3.type.schema.nodes.text : child.type; + match = match.matchType(type); + if (!match) + return false; + if (!a3.type.allowsMarks(child.marks)) + return false; + } + return match.validEnd; +} +function joinable2(a3, b3) { + return !!(a3 && b3 && !a3.isLeaf && canAppendWithSubstitutedLinebreaks(a3, b3)); +} +function joinPoint(doc3, pos, dir = -1) { + let $pos = doc3.resolve(pos); + for (let d3 = $pos.depth; ; d3--) { + let before, after, index = $pos.index(d3); + if (d3 == $pos.depth) { + before = $pos.nodeBefore; + after = $pos.nodeAfter; + } else if (dir > 0) { + before = $pos.node(d3 + 1); + index++; + after = $pos.node(d3).maybeChild(index); + } else { + before = $pos.node(d3).maybeChild(index - 1); + after = $pos.node(d3 + 1); + } + if (before && !before.isTextblock && joinable2(before, after) && $pos.node(d3).canReplace(index, index + 1)) + return pos; + if (d3 == 0) + break; + pos = dir < 0 ? $pos.before(d3) : $pos.after(d3); + } +} +function join(tr, pos, depth) { + let convertNewlines = null; + let { linebreakReplacement } = tr.doc.type.schema; + let $before = tr.doc.resolve(pos - depth), beforeType = $before.node().type; + if (linebreakReplacement && beforeType.inlineContent) { + let pre = beforeType.whitespace == "pre"; + let supportLinebreak = !!beforeType.contentMatch.matchType(linebreakReplacement); + if (pre && !supportLinebreak) + convertNewlines = false; + else if (!pre && supportLinebreak) + convertNewlines = true; + } + let mapFrom = tr.steps.length; + if (convertNewlines === false) { + let $after = tr.doc.resolve(pos + depth); + replaceLinebreaks(tr, $after.node(), $after.before(), mapFrom); + } + if (beforeType.inlineContent) + clearIncompatible(tr, pos + depth - 1, beforeType, $before.node().contentMatchAt($before.index()), convertNewlines == null); + let mapping = tr.mapping.slice(mapFrom), start = mapping.map(pos - depth); + tr.step(new ReplaceStep(start, mapping.map(pos + depth, -1), Slice.empty, true)); + if (convertNewlines === true) { + let $full = tr.doc.resolve(start); + replaceNewlines(tr, $full.node(), $full.before(), tr.steps.length); + } + return tr; +} +function insertPoint(doc3, pos, nodeType) { + let $pos = doc3.resolve(pos); + if ($pos.parent.canReplaceWith($pos.index(), $pos.index(), nodeType)) + return pos; + if ($pos.parentOffset == 0) + for (let d3 = $pos.depth - 1; d3 >= 0; d3--) { + let index = $pos.index(d3); + if ($pos.node(d3).canReplaceWith(index, index, nodeType)) + return $pos.before(d3 + 1); + if (index > 0) + return null; + } + if ($pos.parentOffset == $pos.parent.content.size) + for (let d3 = $pos.depth - 1; d3 >= 0; d3--) { + let index = $pos.indexAfter(d3); + if ($pos.node(d3).canReplaceWith(index, index, nodeType)) + return $pos.after(d3 + 1); + if (index < $pos.node(d3).childCount) + return null; + } + return null; +} +function dropPoint(doc3, pos, slice) { + let $pos = doc3.resolve(pos); + if (!slice.content.size) + return pos; + let content = slice.content; + for (let i5 = 0; i5 < slice.openStart; i5++) + content = content.firstChild.content; + for (let pass = 1; pass <= (slice.openStart == 0 && slice.size ? 2 : 1); pass++) { + for (let d3 = $pos.depth; d3 >= 0; d3--) { + let bias = d3 == $pos.depth ? 0 : $pos.pos <= ($pos.start(d3 + 1) + $pos.end(d3 + 1)) / 2 ? -1 : 1; + let insertPos = $pos.index(d3) + (bias > 0 ? 1 : 0); + let parent = $pos.node(d3), fits = false; + if (pass == 1) { + fits = parent.canReplace(insertPos, insertPos, content); + } else { + let wrapping = parent.contentMatchAt(insertPos).findWrapping(content.firstChild.type); + fits = wrapping && parent.canReplaceWith(insertPos, insertPos, wrapping[0]); + } + if (fits) + return bias == 0 ? $pos.pos : bias < 0 ? $pos.before(d3 + 1) : $pos.after(d3 + 1); + } + } + return null; +} +function replaceStep(doc3, from, to = from, slice = Slice.empty) { + if (from == to && !slice.size) + return null; + let $from = doc3.resolve(from), $to = doc3.resolve(to); + if (fitsTrivially($from, $to, slice)) + return new ReplaceStep(from, to, slice); + return new Fitter($from, $to, slice).fit(); +} +function fitsTrivially($from, $to, slice) { + return !slice.openStart && !slice.openEnd && $from.start() == $to.start() && $from.parent.canReplace($from.index(), $to.index(), slice.content); +} +var Fitter = class { + constructor($from, $to, unplaced) { + this.$from = $from; + this.$to = $to; + this.unplaced = unplaced; + this.frontier = []; + this.placed = Fragment.empty; + for (let i5 = 0; i5 <= $from.depth; i5++) { + let node = $from.node(i5); + this.frontier.push({ + type: node.type, + match: node.contentMatchAt($from.indexAfter(i5)) + }); + } + for (let i5 = $from.depth; i5 > 0; i5--) + this.placed = Fragment.from($from.node(i5).copy(this.placed)); + } + get depth() { + return this.frontier.length - 1; + } + fit() { + while (this.unplaced.size) { + let fit = this.findFittable(); + if (fit) + this.placeNodes(fit); + else + this.openMore() || this.dropNode(); + } + let moveInline = this.mustMoveInline(), placedSize = this.placed.size - this.depth - this.$from.depth; + let $from = this.$from, $to = this.close(moveInline < 0 ? this.$to : $from.doc.resolve(moveInline)); + if (!$to) + return null; + let content = this.placed, openStart = $from.depth, openEnd = $to.depth; + while (openStart && openEnd && content.childCount == 1) { + content = content.firstChild.content; + openStart--; + openEnd--; + } + let slice = new Slice(content, openStart, openEnd); + if (moveInline > -1) + return new ReplaceAroundStep($from.pos, moveInline, this.$to.pos, this.$to.end(), slice, placedSize); + if (slice.size || $from.pos != this.$to.pos) + return new ReplaceStep($from.pos, $to.pos, slice); + return null; + } + // Find a position on the start spine of `this.unplaced` that has + // content that can be moved somewhere on the frontier. Returns two + // depths, one for the slice and one for the frontier. + findFittable() { + let startDepth = this.unplaced.openStart; + for (let cur = this.unplaced.content, d3 = 0, openEnd = this.unplaced.openEnd; d3 < startDepth; d3++) { + let node = cur.firstChild; + if (cur.childCount > 1) + openEnd = 0; + if (node.type.spec.isolating && openEnd <= d3) { + startDepth = d3; + break; + } + cur = node.content; + } + for (let pass = 1; pass <= 2; pass++) { + for (let sliceDepth = pass == 1 ? startDepth : this.unplaced.openStart; sliceDepth >= 0; sliceDepth--) { + let fragment, parent = null; + if (sliceDepth) { + parent = contentAt(this.unplaced.content, sliceDepth - 1).firstChild; + fragment = parent.content; + } else { + fragment = this.unplaced.content; + } + let first2 = fragment.firstChild; + for (let frontierDepth = this.depth; frontierDepth >= 0; frontierDepth--) { + let { type, match } = this.frontier[frontierDepth], wrap2, inject = null; + if (pass == 1 && (first2 ? match.matchType(first2.type) || (inject = match.fillBefore(Fragment.from(first2), false)) : parent && type.compatibleContent(parent.type))) + return { sliceDepth, frontierDepth, parent, inject }; + else if (pass == 2 && first2 && (wrap2 = match.findWrapping(first2.type))) + return { sliceDepth, frontierDepth, parent, wrap: wrap2 }; + if (parent && match.matchType(parent.type)) + break; + } + } + } + } + openMore() { + let { content, openStart, openEnd } = this.unplaced; + let inner = contentAt(content, openStart); + if (!inner.childCount || inner.firstChild.isLeaf) + return false; + this.unplaced = new Slice(content, openStart + 1, Math.max(openEnd, inner.size + openStart >= content.size - openEnd ? openStart + 1 : 0)); + return true; + } + dropNode() { + let { content, openStart, openEnd } = this.unplaced; + let inner = contentAt(content, openStart); + if (inner.childCount <= 1 && openStart > 0) { + let openAtEnd = content.size - openStart <= openStart + inner.size; + this.unplaced = new Slice(dropFromFragment(content, openStart - 1, 1), openStart - 1, openAtEnd ? openStart - 1 : openEnd); + } else { + this.unplaced = new Slice(dropFromFragment(content, openStart, 1), openStart, openEnd); + } + } + // Move content from the unplaced slice at `sliceDepth` to the + // frontier node at `frontierDepth`. Close that frontier node when + // applicable. + placeNodes({ sliceDepth, frontierDepth, parent, inject, wrap: wrap2 }) { + while (this.depth > frontierDepth) + this.closeFrontierNode(); + if (wrap2) + for (let i5 = 0; i5 < wrap2.length; i5++) + this.openFrontierNode(wrap2[i5]); + let slice = this.unplaced, fragment = parent ? parent.content : slice.content; + let openStart = slice.openStart - sliceDepth; + let taken = 0, add = []; + let { match, type } = this.frontier[frontierDepth]; + if (inject) { + for (let i5 = 0; i5 < inject.childCount; i5++) + add.push(inject.child(i5)); + match = match.matchFragment(inject); + } + let openEndCount = fragment.size + sliceDepth - (slice.content.size - slice.openEnd); + while (taken < fragment.childCount) { + let next = fragment.child(taken), matches2 = match.matchType(next.type); + if (!matches2) + break; + taken++; + if (taken > 1 || openStart == 0 || next.content.size) { + match = matches2; + add.push(closeNodeStart(next.mark(type.allowedMarks(next.marks)), taken == 1 ? openStart : 0, taken == fragment.childCount ? openEndCount : -1)); + } + } + let toEnd = taken == fragment.childCount; + if (!toEnd) + openEndCount = -1; + this.placed = addToFragment(this.placed, frontierDepth, Fragment.from(add)); + this.frontier[frontierDepth].match = match; + if (toEnd && openEndCount < 0 && parent && parent.type == this.frontier[this.depth].type && this.frontier.length > 1) + this.closeFrontierNode(); + for (let i5 = 0, cur = fragment; i5 < openEndCount; i5++) { + let node = cur.lastChild; + this.frontier.push({ type: node.type, match: node.contentMatchAt(node.childCount) }); + cur = node.content; + } + this.unplaced = !toEnd ? new Slice(dropFromFragment(slice.content, sliceDepth, taken), slice.openStart, slice.openEnd) : sliceDepth == 0 ? Slice.empty : new Slice(dropFromFragment(slice.content, sliceDepth - 1, 1), sliceDepth - 1, openEndCount < 0 ? slice.openEnd : sliceDepth - 1); + } + mustMoveInline() { + if (!this.$to.parent.isTextblock) + return -1; + let top = this.frontier[this.depth], level; + if (!top.type.isTextblock || !contentAfterFits(this.$to, this.$to.depth, top.type, top.match, false) || this.$to.depth == this.depth && (level = this.findCloseLevel(this.$to)) && level.depth == this.depth) + return -1; + let { depth } = this.$to, after = this.$to.after(depth); + while (depth > 1 && after == this.$to.end(--depth)) + ++after; + return after; + } + findCloseLevel($to) { + scan: for (let i5 = Math.min(this.depth, $to.depth); i5 >= 0; i5--) { + let { match, type } = this.frontier[i5]; + let dropInner = i5 < $to.depth && $to.end(i5 + 1) == $to.pos + ($to.depth - (i5 + 1)); + let fit = contentAfterFits($to, i5, type, match, dropInner); + if (!fit) + continue; + for (let d3 = i5 - 1; d3 >= 0; d3--) { + let { match: match2, type: type2 } = this.frontier[d3]; + let matches2 = contentAfterFits($to, d3, type2, match2, true); + if (!matches2 || matches2.childCount) + continue scan; + } + return { depth: i5, fit, move: dropInner ? $to.doc.resolve($to.after(i5 + 1)) : $to }; + } + } + close($to) { + let close2 = this.findCloseLevel($to); + if (!close2) + return null; + while (this.depth > close2.depth) + this.closeFrontierNode(); + if (close2.fit.childCount) + this.placed = addToFragment(this.placed, close2.depth, close2.fit); + $to = close2.move; + for (let d3 = close2.depth + 1; d3 <= $to.depth; d3++) { + let node = $to.node(d3), add = node.type.contentMatch.fillBefore(node.content, true, $to.index(d3)); + this.openFrontierNode(node.type, node.attrs, add); + } + return $to; + } + openFrontierNode(type, attrs = null, content) { + let top = this.frontier[this.depth]; + top.match = top.match.matchType(type); + this.placed = addToFragment(this.placed, this.depth, Fragment.from(type.create(attrs, content))); + this.frontier.push({ type, match: type.contentMatch }); + } + closeFrontierNode() { + let open = this.frontier.pop(); + let add = open.match.fillBefore(Fragment.empty, true); + if (add.childCount) + this.placed = addToFragment(this.placed, this.frontier.length, add); + } +}; +function dropFromFragment(fragment, depth, count) { + if (depth == 0) + return fragment.cutByIndex(count, fragment.childCount); + return fragment.replaceChild(0, fragment.firstChild.copy(dropFromFragment(fragment.firstChild.content, depth - 1, count))); +} +function addToFragment(fragment, depth, content) { + if (depth == 0) + return fragment.append(content); + return fragment.replaceChild(fragment.childCount - 1, fragment.lastChild.copy(addToFragment(fragment.lastChild.content, depth - 1, content))); +} +function contentAt(fragment, depth) { + for (let i5 = 0; i5 < depth; i5++) + fragment = fragment.firstChild.content; + return fragment; +} +function closeNodeStart(node, openStart, openEnd) { + if (openStart <= 0) + return node; + let frag = node.content; + if (openStart > 1) + frag = frag.replaceChild(0, closeNodeStart(frag.firstChild, openStart - 1, frag.childCount == 1 ? openEnd - 1 : 0)); + if (openStart > 0) { + frag = node.type.contentMatch.fillBefore(frag).append(frag); + if (openEnd <= 0) + frag = frag.append(node.type.contentMatch.matchFragment(frag).fillBefore(Fragment.empty, true)); + } + return node.copy(frag); +} +function contentAfterFits($to, depth, type, match, open) { + let node = $to.node(depth), index = open ? $to.indexAfter(depth) : $to.index(depth); + if (index == node.childCount && !type.compatibleContent(node.type)) + return null; + let fit = match.fillBefore(node.content, true, index); + return fit && !invalidMarks(type, node.content, index) ? fit : null; +} +function invalidMarks(type, fragment, start) { + for (let i5 = start; i5 < fragment.childCount; i5++) + if (!type.allowsMarks(fragment.child(i5).marks)) + return true; + return false; +} +function definesContent(type) { + return type.spec.defining || type.spec.definingForContent; +} +function replaceRange(tr, from, to, slice) { + if (!slice.size) + return tr.deleteRange(from, to); + let $from = tr.doc.resolve(from), $to = tr.doc.resolve(to); + if (fitsTrivially($from, $to, slice)) + return tr.step(new ReplaceStep(from, to, slice)); + let targetDepths = coveredDepths($from, tr.doc.resolve(to)); + if (targetDepths[targetDepths.length - 1] == 0) + targetDepths.pop(); + let preferredTarget = -($from.depth + 1); + targetDepths.unshift(preferredTarget); + for (let d3 = $from.depth, pos = $from.pos - 1; d3 > 0; d3--, pos--) { + let spec = $from.node(d3).type.spec; + if (spec.defining || spec.definingAsContext || spec.isolating) + break; + if (targetDepths.indexOf(d3) > -1) + preferredTarget = d3; + else if ($from.before(d3) == pos) + targetDepths.splice(1, 0, -d3); + } + let preferredTargetIndex = targetDepths.indexOf(preferredTarget); + let leftNodes = [], preferredDepth = slice.openStart; + for (let content = slice.content, i5 = 0; ; i5++) { + let node = content.firstChild; + leftNodes.push(node); + if (i5 == slice.openStart) + break; + content = node.content; + } + for (let d3 = preferredDepth - 1; d3 >= 0; d3--) { + let leftNode = leftNodes[d3], def = definesContent(leftNode.type); + if (def && !leftNode.sameMarkup($from.node(Math.abs(preferredTarget) - 1))) + preferredDepth = d3; + else if (def || !leftNode.type.isTextblock) + break; + } + for (let j2 = slice.openStart; j2 >= 0; j2--) { + let openDepth = (j2 + preferredDepth + 1) % (slice.openStart + 1); + let insert = leftNodes[openDepth]; + if (!insert) + continue; + for (let i5 = 0; i5 < targetDepths.length; i5++) { + let targetDepth = targetDepths[(i5 + preferredTargetIndex) % targetDepths.length], expand = true; + if (targetDepth < 0) { + expand = false; + targetDepth = -targetDepth; + } + let parent = $from.node(targetDepth - 1), index = $from.index(targetDepth - 1); + if (parent.canReplaceWith(index, index, insert.type, insert.marks)) + return tr.replace($from.before(targetDepth), expand ? $to.after(targetDepth) : to, new Slice(closeFragment(slice.content, 0, slice.openStart, openDepth), openDepth, slice.openEnd)); + } + } + let startSteps = tr.steps.length; + for (let i5 = targetDepths.length - 1; i5 >= 0; i5--) { + tr.replace(from, to, slice); + if (tr.steps.length > startSteps) + break; + let depth = targetDepths[i5]; + if (depth < 0) + continue; + from = $from.before(depth); + to = $to.after(depth); + } +} +function closeFragment(fragment, depth, oldOpen, newOpen, parent) { + if (depth < oldOpen) { + let first2 = fragment.firstChild; + fragment = fragment.replaceChild(0, first2.copy(closeFragment(first2.content, depth + 1, oldOpen, newOpen, first2))); + } + if (depth > newOpen) { + let match = parent.contentMatchAt(0); + let start = match.fillBefore(fragment).append(fragment); + fragment = start.append(match.matchFragment(start).fillBefore(Fragment.empty, true)); + } + return fragment; +} +function replaceRangeWith(tr, from, to, node) { + if (!node.isInline && from == to && tr.doc.resolve(from).parent.content.size) { + let point = insertPoint(tr.doc, from, node.type); + if (point != null) + from = to = point; + } + tr.replaceRange(from, to, new Slice(Fragment.from(node), 0, 0)); +} +function deleteRange(tr, from, to) { + let $from = tr.doc.resolve(from), $to = tr.doc.resolve(to); + let covered = coveredDepths($from, $to); + for (let i5 = 0; i5 < covered.length; i5++) { + let depth = covered[i5], last = i5 == covered.length - 1; + if (last && depth == 0 || $from.node(depth).type.contentMatch.validEnd) + return tr.delete($from.start(depth), $to.end(depth)); + if (depth > 0 && (last || $from.node(depth - 1).canReplace($from.index(depth - 1), $to.indexAfter(depth - 1)))) + return tr.delete($from.before(depth), $to.after(depth)); + } + for (let d3 = 1; d3 <= $from.depth && d3 <= $to.depth; d3++) { + if (from - $from.start(d3) == $from.depth - d3 && to > $from.end(d3) && $to.end(d3) - to != $to.depth - d3 && $from.start(d3 - 1) == $to.start(d3 - 1) && $from.node(d3 - 1).canReplace($from.index(d3 - 1), $to.index(d3 - 1))) + return tr.delete($from.before(d3), to); + } + tr.delete(from, to); +} +function coveredDepths($from, $to) { + let result = [], minDepth = Math.min($from.depth, $to.depth); + for (let d3 = minDepth; d3 >= 0; d3--) { + let start = $from.start(d3); + if (start < $from.pos - ($from.depth - d3) || $to.end(d3) > $to.pos + ($to.depth - d3) || $from.node(d3).type.spec.isolating || $to.node(d3).type.spec.isolating) + break; + if (start == $to.start(d3) || d3 == $from.depth && d3 == $to.depth && $from.parent.inlineContent && $to.parent.inlineContent && d3 && $to.start(d3 - 1) == start - 1) + result.push(d3); + } + return result; +} +var AttrStep = class _AttrStep extends Step { + /** + Construct an attribute step. + */ + constructor(pos, attr, value) { + super(); + this.pos = pos; + this.attr = attr; + this.value = value; + } + apply(doc3) { + let node = doc3.nodeAt(this.pos); + if (!node) + return StepResult.fail("No node at attribute step's position"); + let attrs = /* @__PURE__ */ Object.create(null); + for (let name in node.attrs) + attrs[name] = node.attrs[name]; + attrs[this.attr] = this.value; + let updated = node.type.create(attrs, null, node.marks); + return StepResult.fromReplace(doc3, this.pos, this.pos + 1, new Slice(Fragment.from(updated), 0, node.isLeaf ? 0 : 1)); + } + getMap() { + return StepMap.empty; + } + invert(doc3) { + return new _AttrStep(this.pos, this.attr, doc3.nodeAt(this.pos).attrs[this.attr]); + } + map(mapping) { + let pos = mapping.mapResult(this.pos, 1); + return pos.deletedAfter ? null : new _AttrStep(pos.pos, this.attr, this.value); + } + toJSON() { + return { stepType: "attr", pos: this.pos, attr: this.attr, value: this.value }; + } + static fromJSON(schema, json) { + if (typeof json.pos != "number" || typeof json.attr != "string") + throw new RangeError("Invalid input for AttrStep.fromJSON"); + return new _AttrStep(json.pos, json.attr, json.value); + } +}; +Step.jsonID("attr", AttrStep); +var DocAttrStep = class _DocAttrStep extends Step { + /** + Construct an attribute step. + */ + constructor(attr, value) { + super(); + this.attr = attr; + this.value = value; + } + apply(doc3) { + let attrs = /* @__PURE__ */ Object.create(null); + for (let name in doc3.attrs) + attrs[name] = doc3.attrs[name]; + attrs[this.attr] = this.value; + let updated = doc3.type.create(attrs, doc3.content, doc3.marks); + return StepResult.ok(updated); + } + getMap() { + return StepMap.empty; + } + invert(doc3) { + return new _DocAttrStep(this.attr, doc3.attrs[this.attr]); + } + map(mapping) { + return this; + } + toJSON() { + return { stepType: "docAttr", attr: this.attr, value: this.value }; + } + static fromJSON(schema, json) { + if (typeof json.attr != "string") + throw new RangeError("Invalid input for DocAttrStep.fromJSON"); + return new _DocAttrStep(json.attr, json.value); + } +}; +Step.jsonID("docAttr", DocAttrStep); +var TransformError = class extends Error { +}; +TransformError = function TransformError2(message) { + let err = Error.call(this, message); + err.__proto__ = TransformError2.prototype; + return err; +}; +TransformError.prototype = Object.create(Error.prototype); +TransformError.prototype.constructor = TransformError; +TransformError.prototype.name = "TransformError"; +var Transform = class { + /** + Create a transform that starts with the given document. + */ + constructor(doc3) { + this.doc = doc3; + this.steps = []; + this.docs = []; + this.mapping = new Mapping(); + } + /** + The starting document. + */ + get before() { + return this.docs.length ? this.docs[0] : this.doc; + } + /** + Apply a new step in this transform, saving the result. Throws an + error when the step fails. + */ + step(step) { + let result = this.maybeStep(step); + if (result.failed) + throw new TransformError(result.failed); + return this; + } + /** + Try to apply a step in this transformation, ignoring it if it + fails. Returns the step result. + */ + maybeStep(step) { + let result = step.apply(this.doc); + if (!result.failed) + this.addStep(step, result.doc); + return result; + } + /** + True when the document has been changed (when there are any + steps). + */ + get docChanged() { + return this.steps.length > 0; + } + /** + @internal + */ + addStep(step, doc3) { + this.docs.push(this.doc); + this.steps.push(step); + this.mapping.appendMap(step.getMap()); + this.doc = doc3; + } + /** + Replace the part of the document between `from` and `to` with the + given `slice`. + */ + replace(from, to = from, slice = Slice.empty) { + let step = replaceStep(this.doc, from, to, slice); + if (step) + this.step(step); + return this; + } + /** + Replace the given range with the given content, which may be a + fragment, node, or array of nodes. + */ + replaceWith(from, to, content) { + return this.replace(from, to, new Slice(Fragment.from(content), 0, 0)); + } + /** + Delete the content between the given positions. + */ + delete(from, to) { + return this.replace(from, to, Slice.empty); + } + /** + Insert the given content at the given position. + */ + insert(pos, content) { + return this.replaceWith(pos, pos, content); + } + /** + Replace a range of the document with a given slice, using + `from`, `to`, and the slice's + [`openStart`](https://prosemirror.net/docs/ref/#model.Slice.openStart) property as hints, rather + than fixed start and end points. This method may grow the + replaced area or close open nodes in the slice in order to get a + fit that is more in line with WYSIWYG expectations, by dropping + fully covered parent nodes of the replaced region when they are + marked [non-defining as + context](https://prosemirror.net/docs/ref/#model.NodeSpec.definingAsContext), or including an + open parent node from the slice that _is_ marked as [defining + its content](https://prosemirror.net/docs/ref/#model.NodeSpec.definingForContent). + + This is the method, for example, to handle paste. The similar + [`replace`](https://prosemirror.net/docs/ref/#transform.Transform.replace) method is a more + primitive tool which will _not_ move the start and end of its given + range, and is useful in situations where you need more precise + control over what happens. + */ + replaceRange(from, to, slice) { + replaceRange(this, from, to, slice); + return this; + } + /** + Replace the given range with a node, but use `from` and `to` as + hints, rather than precise positions. When from and to are the same + and are at the start or end of a parent node in which the given + node doesn't fit, this method may _move_ them out towards a parent + that does allow the given node to be placed. When the given range + completely covers a parent node, this method may completely replace + that parent node. + */ + replaceRangeWith(from, to, node) { + replaceRangeWith(this, from, to, node); + return this; + } + /** + Delete the given range, expanding it to cover fully covered + parent nodes until a valid replace is found. + */ + deleteRange(from, to) { + deleteRange(this, from, to); + return this; + } + /** + Split the content in the given range off from its parent, if there + is sibling content before or after it, and move it up the tree to + the depth specified by `target`. You'll probably want to use + [`liftTarget`](https://prosemirror.net/docs/ref/#transform.liftTarget) to compute `target`, to make + sure the lift is valid. + */ + lift(range, target) { + lift(this, range, target); + return this; + } + /** + Join the blocks around the given position. If depth is 2, their + last and first siblings are also joined, and so on. + */ + join(pos, depth = 1) { + join(this, pos, depth); + return this; + } + /** + Wrap the given [range](https://prosemirror.net/docs/ref/#model.NodeRange) in the given set of wrappers. + The wrappers are assumed to be valid in this position, and should + probably be computed with [`findWrapping`](https://prosemirror.net/docs/ref/#transform.findWrapping). + */ + wrap(range, wrappers) { + wrap(this, range, wrappers); + return this; + } + /** + Set the type of all textblocks (partly) between `from` and `to` to + the given node type with the given attributes. + */ + setBlockType(from, to = from, type, attrs = null) { + setBlockType(this, from, to, type, attrs); + return this; + } + /** + Change the type, attributes, and/or marks of the node at `pos`. + When `type` isn't given, the existing node type is preserved, + */ + setNodeMarkup(pos, type, attrs = null, marks) { + setNodeMarkup(this, pos, type, attrs, marks); + return this; + } + /** + Set a single attribute on a given node to a new value. + The `pos` addresses the document content. Use `setDocAttribute` + to set attributes on the document itself. + */ + setNodeAttribute(pos, attr, value) { + this.step(new AttrStep(pos, attr, value)); + return this; + } + /** + Set a single attribute on the document to a new value. + */ + setDocAttribute(attr, value) { + this.step(new DocAttrStep(attr, value)); + return this; + } + /** + Add a mark to the node at position `pos`. + */ + addNodeMark(pos, mark) { + this.step(new AddNodeMarkStep(pos, mark)); + return this; + } + /** + Remove a mark (or all marks of the given type) from the node at + position `pos`. + */ + removeNodeMark(pos, mark) { + let node = this.doc.nodeAt(pos); + if (!node) + throw new RangeError("No node at position " + pos); + if (mark instanceof Mark) { + if (mark.isInSet(node.marks)) + this.step(new RemoveNodeMarkStep(pos, mark)); + } else { + let set = node.marks, found2, steps = []; + while (found2 = mark.isInSet(set)) { + steps.push(new RemoveNodeMarkStep(pos, found2)); + set = found2.removeFromSet(set); + } + for (let i5 = steps.length - 1; i5 >= 0; i5--) + this.step(steps[i5]); + } + return this; + } + /** + Split the node at the given position, and optionally, if `depth` is + greater than one, any number of nodes above that. By default, the + parts split off will inherit the node type of the original node. + This can be changed by passing an array of types and attributes to + use after the split (with the outermost nodes coming first). + */ + split(pos, depth = 1, typesAfter) { + split(this, pos, depth, typesAfter); + return this; + } + /** + Add the given mark to the inline content between `from` and `to`. + */ + addMark(from, to, mark) { + addMark(this, from, to, mark); + return this; + } + /** + Remove marks from inline nodes between `from` and `to`. When + `mark` is a single mark, remove precisely that mark. When it is + a mark type, remove all marks of that type. When it is null, + remove all marks of any type. + */ + removeMark(from, to, mark) { + removeMark(this, from, to, mark); + return this; + } + /** + Removes all marks and nodes from the content of the node at + `pos` that don't match the given new parent node type. Accepts + an optional starting [content match](https://prosemirror.net/docs/ref/#model.ContentMatch) as + third argument. + */ + clearIncompatible(pos, parentType, match) { + clearIncompatible(this, pos, parentType, match); + return this; + } +}; + +// node_modules/prosemirror-state/dist/index.js +var classesById = /* @__PURE__ */ Object.create(null); +var Selection = class { + /** + Initialize a selection with the head and anchor and ranges. If no + ranges are given, constructs a single range across `$anchor` and + `$head`. + */ + constructor($anchor, $head, ranges) { + this.$anchor = $anchor; + this.$head = $head; + this.ranges = ranges || [new SelectionRange($anchor.min($head), $anchor.max($head))]; + } + /** + The selection's anchor, as an unresolved position. + */ + get anchor() { + return this.$anchor.pos; + } + /** + The selection's head. + */ + get head() { + return this.$head.pos; + } + /** + The lower bound of the selection's main range. + */ + get from() { + return this.$from.pos; + } + /** + The upper bound of the selection's main range. + */ + get to() { + return this.$to.pos; + } + /** + The resolved lower bound of the selection's main range. + */ + get $from() { + return this.ranges[0].$from; + } + /** + The resolved upper bound of the selection's main range. + */ + get $to() { + return this.ranges[0].$to; + } + /** + Indicates whether the selection contains any content. + */ + get empty() { + let ranges = this.ranges; + for (let i5 = 0; i5 < ranges.length; i5++) + if (ranges[i5].$from.pos != ranges[i5].$to.pos) + return false; + return true; + } + /** + Get the content of this selection as a slice. + */ + content() { + return this.$from.doc.slice(this.from, this.to, true); + } + /** + Replace the selection with a slice or, if no slice is given, + delete the selection. Will append to the given transaction. + */ + replace(tr, content = Slice.empty) { + let lastNode = content.content.lastChild, lastParent = null; + for (let i5 = 0; i5 < content.openEnd; i5++) { + lastParent = lastNode; + lastNode = lastNode.lastChild; + } + let mapFrom = tr.steps.length, ranges = this.ranges; + for (let i5 = 0; i5 < ranges.length; i5++) { + let { $from, $to } = ranges[i5], mapping = tr.mapping.slice(mapFrom); + tr.replaceRange(mapping.map($from.pos), mapping.map($to.pos), i5 ? Slice.empty : content); + if (i5 == 0) + selectionToInsertionEnd(tr, mapFrom, (lastNode ? lastNode.isInline : lastParent && lastParent.isTextblock) ? -1 : 1); + } + } + /** + Replace the selection with the given node, appending the changes + to the given transaction. + */ + replaceWith(tr, node) { + let mapFrom = tr.steps.length, ranges = this.ranges; + for (let i5 = 0; i5 < ranges.length; i5++) { + let { $from, $to } = ranges[i5], mapping = tr.mapping.slice(mapFrom); + let from = mapping.map($from.pos), to = mapping.map($to.pos); + if (i5) { + tr.deleteRange(from, to); + } else { + tr.replaceRangeWith(from, to, node); + selectionToInsertionEnd(tr, mapFrom, node.isInline ? -1 : 1); + } + } + } + /** + Find a valid cursor or leaf node selection starting at the given + position and searching back if `dir` is negative, and forward if + positive. When `textOnly` is true, only consider cursor + selections. Will return null when no valid selection position is + found. + */ + static findFrom($pos, dir, textOnly = false) { + let inner = $pos.parent.inlineContent ? new TextSelection($pos) : findSelectionIn($pos.node(0), $pos.parent, $pos.pos, $pos.index(), dir, textOnly); + if (inner) + return inner; + for (let depth = $pos.depth - 1; depth >= 0; depth--) { + let found2 = dir < 0 ? findSelectionIn($pos.node(0), $pos.node(depth), $pos.before(depth + 1), $pos.index(depth), dir, textOnly) : findSelectionIn($pos.node(0), $pos.node(depth), $pos.after(depth + 1), $pos.index(depth) + 1, dir, textOnly); + if (found2) + return found2; + } + return null; + } + /** + Find a valid cursor or leaf node selection near the given + position. Searches forward first by default, but if `bias` is + negative, it will search backwards first. + */ + static near($pos, bias = 1) { + return this.findFrom($pos, bias) || this.findFrom($pos, -bias) || new AllSelection($pos.node(0)); + } + /** + Find the cursor or leaf node selection closest to the start of + the given document. Will return an + [`AllSelection`](https://prosemirror.net/docs/ref/#state.AllSelection) if no valid position + exists. + */ + static atStart(doc3) { + return findSelectionIn(doc3, doc3, 0, 0, 1) || new AllSelection(doc3); + } + /** + Find the cursor or leaf node selection closest to the end of the + given document. + */ + static atEnd(doc3) { + return findSelectionIn(doc3, doc3, doc3.content.size, doc3.childCount, -1) || new AllSelection(doc3); + } + /** + Deserialize the JSON representation of a selection. Must be + implemented for custom classes (as a static class method). + */ + static fromJSON(doc3, json) { + if (!json || !json.type) + throw new RangeError("Invalid input for Selection.fromJSON"); + let cls = classesById[json.type]; + if (!cls) + throw new RangeError(`No selection type ${json.type} defined`); + return cls.fromJSON(doc3, json); + } + /** + To be able to deserialize selections from JSON, custom selection + classes must register themselves with an ID string, so that they + can be disambiguated. Try to pick something that's unlikely to + clash with classes from other modules. + */ + static jsonID(id, selectionClass) { + if (id in classesById) + throw new RangeError("Duplicate use of selection JSON ID " + id); + classesById[id] = selectionClass; + selectionClass.prototype.jsonID = id; + return selectionClass; + } + /** + Get a [bookmark](https://prosemirror.net/docs/ref/#state.SelectionBookmark) for this selection, + which is a value that can be mapped without having access to a + current document, and later resolved to a real selection for a + given document again. (This is used mostly by the history to + track and restore old selections.) The default implementation of + this method just converts the selection to a text selection and + returns the bookmark for that. + */ + getBookmark() { + return TextSelection.between(this.$anchor, this.$head).getBookmark(); + } +}; +Selection.prototype.visible = true; +var SelectionRange = class { + /** + Create a range. + */ + constructor($from, $to) { + this.$from = $from; + this.$to = $to; + } +}; +var warnedAboutTextSelection = false; +function checkTextSelection($pos) { + if (!warnedAboutTextSelection && !$pos.parent.inlineContent) { + warnedAboutTextSelection = true; + console["warn"]("TextSelection endpoint not pointing into a node with inline content (" + $pos.parent.type.name + ")"); + } +} +var TextSelection = class _TextSelection extends Selection { + /** + Construct a text selection between the given points. + */ + constructor($anchor, $head = $anchor) { + checkTextSelection($anchor); + checkTextSelection($head); + super($anchor, $head); + } + /** + Returns a resolved position if this is a cursor selection (an + empty text selection), and null otherwise. + */ + get $cursor() { + return this.$anchor.pos == this.$head.pos ? this.$head : null; + } + map(doc3, mapping) { + let $head = doc3.resolve(mapping.map(this.head)); + if (!$head.parent.inlineContent) + return Selection.near($head); + let $anchor = doc3.resolve(mapping.map(this.anchor)); + return new _TextSelection($anchor.parent.inlineContent ? $anchor : $head, $head); + } + replace(tr, content = Slice.empty) { + super.replace(tr, content); + if (content == Slice.empty) { + let marks = this.$from.marksAcross(this.$to); + if (marks) + tr.ensureMarks(marks); + } + } + eq(other) { + return other instanceof _TextSelection && other.anchor == this.anchor && other.head == this.head; + } + getBookmark() { + return new TextBookmark(this.anchor, this.head); + } + toJSON() { + return { type: "text", anchor: this.anchor, head: this.head }; + } + /** + @internal + */ + static fromJSON(doc3, json) { + if (typeof json.anchor != "number" || typeof json.head != "number") + throw new RangeError("Invalid input for TextSelection.fromJSON"); + return new _TextSelection(doc3.resolve(json.anchor), doc3.resolve(json.head)); + } + /** + Create a text selection from non-resolved positions. + */ + static create(doc3, anchor, head = anchor) { + let $anchor = doc3.resolve(anchor); + return new this($anchor, head == anchor ? $anchor : doc3.resolve(head)); + } + /** + Return a text selection that spans the given positions or, if + they aren't text positions, find a text selection near them. + `bias` determines whether the method searches forward (default) + or backwards (negative number) first. Will fall back to calling + [`Selection.near`](https://prosemirror.net/docs/ref/#state.Selection^near) when the document + doesn't contain a valid text position. + */ + static between($anchor, $head, bias) { + let dPos = $anchor.pos - $head.pos; + if (!bias || dPos) + bias = dPos >= 0 ? 1 : -1; + if (!$head.parent.inlineContent) { + let found2 = Selection.findFrom($head, bias, true) || Selection.findFrom($head, -bias, true); + if (found2) + $head = found2.$head; + else + return Selection.near($head, bias); + } + if (!$anchor.parent.inlineContent) { + if (dPos == 0) { + $anchor = $head; + } else { + $anchor = (Selection.findFrom($anchor, -bias, true) || Selection.findFrom($anchor, bias, true)).$anchor; + if ($anchor.pos < $head.pos != dPos < 0) + $anchor = $head; + } + } + return new _TextSelection($anchor, $head); + } +}; +Selection.jsonID("text", TextSelection); +var TextBookmark = class _TextBookmark { + constructor(anchor, head) { + this.anchor = anchor; + this.head = head; + } + map(mapping) { + return new _TextBookmark(mapping.map(this.anchor), mapping.map(this.head)); + } + resolve(doc3) { + return TextSelection.between(doc3.resolve(this.anchor), doc3.resolve(this.head)); + } +}; +var NodeSelection = class _NodeSelection extends Selection { + /** + Create a node selection. Does not verify the validity of its + argument. + */ + constructor($pos) { + let node = $pos.nodeAfter; + let $end = $pos.node(0).resolve($pos.pos + node.nodeSize); + super($pos, $end); + this.node = node; + } + map(doc3, mapping) { + let { deleted, pos } = mapping.mapResult(this.anchor); + let $pos = doc3.resolve(pos); + if (deleted) + return Selection.near($pos); + return new _NodeSelection($pos); + } + content() { + return new Slice(Fragment.from(this.node), 0, 0); + } + eq(other) { + return other instanceof _NodeSelection && other.anchor == this.anchor; + } + toJSON() { + return { type: "node", anchor: this.anchor }; + } + getBookmark() { + return new NodeBookmark(this.anchor); + } + /** + @internal + */ + static fromJSON(doc3, json) { + if (typeof json.anchor != "number") + throw new RangeError("Invalid input for NodeSelection.fromJSON"); + return new _NodeSelection(doc3.resolve(json.anchor)); + } + /** + Create a node selection from non-resolved positions. + */ + static create(doc3, from) { + return new _NodeSelection(doc3.resolve(from)); + } + /** + Determines whether the given node may be selected as a node + selection. + */ + static isSelectable(node) { + return !node.isText && node.type.spec.selectable !== false; + } +}; +NodeSelection.prototype.visible = false; +Selection.jsonID("node", NodeSelection); +var NodeBookmark = class _NodeBookmark { + constructor(anchor) { + this.anchor = anchor; + } + map(mapping) { + let { deleted, pos } = mapping.mapResult(this.anchor); + return deleted ? new TextBookmark(pos, pos) : new _NodeBookmark(pos); + } + resolve(doc3) { + let $pos = doc3.resolve(this.anchor), node = $pos.nodeAfter; + if (node && NodeSelection.isSelectable(node)) + return new NodeSelection($pos); + return Selection.near($pos); + } +}; +var AllSelection = class _AllSelection extends Selection { + /** + Create an all-selection over the given document. + */ + constructor(doc3) { + super(doc3.resolve(0), doc3.resolve(doc3.content.size)); + } + replace(tr, content = Slice.empty) { + if (content == Slice.empty) { + tr.delete(0, tr.doc.content.size); + let sel = Selection.atStart(tr.doc); + if (!sel.eq(tr.selection)) + tr.setSelection(sel); + } else { + super.replace(tr, content); + } + } + toJSON() { + return { type: "all" }; + } + /** + @internal + */ + static fromJSON(doc3) { + return new _AllSelection(doc3); + } + map(doc3) { + return new _AllSelection(doc3); + } + eq(other) { + return other instanceof _AllSelection; + } + getBookmark() { + return AllBookmark; + } +}; +Selection.jsonID("all", AllSelection); +var AllBookmark = { + map() { + return this; + }, + resolve(doc3) { + return new AllSelection(doc3); + } +}; +function findSelectionIn(doc3, node, pos, index, dir, text = false) { + if (node.inlineContent) + return TextSelection.create(doc3, pos); + for (let i5 = index - (dir > 0 ? 0 : 1); dir > 0 ? i5 < node.childCount : i5 >= 0; i5 += dir) { + let child = node.child(i5); + if (!child.isAtom) { + let inner = findSelectionIn(doc3, child, pos + dir, dir < 0 ? child.childCount : 0, dir, text); + if (inner) + return inner; + } else if (!text && NodeSelection.isSelectable(child)) { + return NodeSelection.create(doc3, pos - (dir < 0 ? child.nodeSize : 0)); + } + pos += child.nodeSize * dir; + } + return null; +} +function selectionToInsertionEnd(tr, startLen, bias) { + let last = tr.steps.length - 1; + if (last < startLen) + return; + let step = tr.steps[last]; + if (!(step instanceof ReplaceStep || step instanceof ReplaceAroundStep)) + return; + let map = tr.mapping.maps[last], end; + map.forEach((_from, _to, _newFrom, newTo) => { + if (end == null) + end = newTo; + }); + tr.setSelection(Selection.near(tr.doc.resolve(end), bias)); +} +var UPDATED_SEL = 1; +var UPDATED_MARKS = 2; +var UPDATED_SCROLL = 4; +var Transaction = class extends Transform { + /** + @internal + */ + constructor(state) { + super(state.doc); + this.curSelectionFor = 0; + this.updated = 0; + this.meta = /* @__PURE__ */ Object.create(null); + this.time = Date.now(); + this.curSelection = state.selection; + this.storedMarks = state.storedMarks; + } + /** + The transaction's current selection. This defaults to the editor + selection [mapped](https://prosemirror.net/docs/ref/#state.Selection.map) through the steps in the + transaction, but can be overwritten with + [`setSelection`](https://prosemirror.net/docs/ref/#state.Transaction.setSelection). + */ + get selection() { + if (this.curSelectionFor < this.steps.length) { + this.curSelection = this.curSelection.map(this.doc, this.mapping.slice(this.curSelectionFor)); + this.curSelectionFor = this.steps.length; + } + return this.curSelection; + } + /** + Update the transaction's current selection. Will determine the + selection that the editor gets when the transaction is applied. + */ + setSelection(selection) { + if (selection.$from.doc != this.doc) + throw new RangeError("Selection passed to setSelection must point at the current document"); + this.curSelection = selection; + this.curSelectionFor = this.steps.length; + this.updated = (this.updated | UPDATED_SEL) & ~UPDATED_MARKS; + this.storedMarks = null; + return this; + } + /** + Whether the selection was explicitly updated by this transaction. + */ + get selectionSet() { + return (this.updated & UPDATED_SEL) > 0; + } + /** + Set the current stored marks. + */ + setStoredMarks(marks) { + this.storedMarks = marks; + this.updated |= UPDATED_MARKS; + return this; + } + /** + Make sure the current stored marks or, if that is null, the marks + at the selection, match the given set of marks. Does nothing if + this is already the case. + */ + ensureMarks(marks) { + if (!Mark.sameSet(this.storedMarks || this.selection.$from.marks(), marks)) + this.setStoredMarks(marks); + return this; + } + /** + Add a mark to the set of stored marks. + */ + addStoredMark(mark) { + return this.ensureMarks(mark.addToSet(this.storedMarks || this.selection.$head.marks())); + } + /** + Remove a mark or mark type from the set of stored marks. + */ + removeStoredMark(mark) { + return this.ensureMarks(mark.removeFromSet(this.storedMarks || this.selection.$head.marks())); + } + /** + Whether the stored marks were explicitly set for this transaction. + */ + get storedMarksSet() { + return (this.updated & UPDATED_MARKS) > 0; + } + /** + @internal + */ + addStep(step, doc3) { + super.addStep(step, doc3); + this.updated = this.updated & ~UPDATED_MARKS; + this.storedMarks = null; + } + /** + Update the timestamp for the transaction. + */ + setTime(time) { + this.time = time; + return this; + } + /** + Replace the current selection with the given slice. + */ + replaceSelection(slice) { + this.selection.replace(this, slice); + return this; + } + /** + Replace the selection with the given node. When `inheritMarks` is + true and the content is inline, it inherits the marks from the + place where it is inserted. + */ + replaceSelectionWith(node, inheritMarks = true) { + let selection = this.selection; + if (inheritMarks) + node = node.mark(this.storedMarks || (selection.empty ? selection.$from.marks() : selection.$from.marksAcross(selection.$to) || Mark.none)); + selection.replaceWith(this, node); + return this; + } + /** + Delete the selection. + */ + deleteSelection() { + this.selection.replace(this); + return this; + } + /** + Replace the given range, or the selection if no range is given, + with a text node containing the given string. + */ + insertText(text, from, to) { + let schema = this.doc.type.schema; + if (from == null) { + if (!text) + return this.deleteSelection(); + return this.replaceSelectionWith(schema.text(text), true); + } else { + if (to == null) + to = from; + to = to == null ? from : to; + if (!text) + return this.deleteRange(from, to); + let marks = this.storedMarks; + if (!marks) { + let $from = this.doc.resolve(from); + marks = to == from ? $from.marks() : $from.marksAcross(this.doc.resolve(to)); + } + this.replaceRangeWith(from, to, schema.text(text, marks)); + if (!this.selection.empty) + this.setSelection(Selection.near(this.selection.$to)); + return this; + } + } + /** + Store a metadata property in this transaction, keyed either by + name or by plugin. + */ + setMeta(key, value) { + this.meta[typeof key == "string" ? key : key.key] = value; + return this; + } + /** + Retrieve a metadata property for a given name or plugin. + */ + getMeta(key) { + return this.meta[typeof key == "string" ? key : key.key]; + } + /** + Returns true if this transaction doesn't contain any metadata, + and can thus safely be extended. + */ + get isGeneric() { + for (let _2 in this.meta) + return false; + return true; + } + /** + Indicate that the editor should scroll the selection into view + when updated to the state produced by this transaction. + */ + scrollIntoView() { + this.updated |= UPDATED_SCROLL; + return this; + } + /** + True when this transaction has had `scrollIntoView` called on it. + */ + get scrolledIntoView() { + return (this.updated & UPDATED_SCROLL) > 0; + } +}; +function bind(f3, self) { + return !self || !f3 ? f3 : f3.bind(self); +} +var FieldDesc = class { + constructor(name, desc, self) { + this.name = name; + this.init = bind(desc.init, self); + this.apply = bind(desc.apply, self); + } +}; +var baseFields = [ + new FieldDesc("doc", { + init(config) { + return config.doc || config.schema.topNodeType.createAndFill(); + }, + apply(tr) { + return tr.doc; + } + }), + new FieldDesc("selection", { + init(config, instance) { + return config.selection || Selection.atStart(instance.doc); + }, + apply(tr) { + return tr.selection; + } + }), + new FieldDesc("storedMarks", { + init(config) { + return config.storedMarks || null; + }, + apply(tr, _marks, _old, state) { + return state.selection.$cursor ? tr.storedMarks : null; + } + }), + new FieldDesc("scrollToSelection", { + init() { + return 0; + }, + apply(tr, prev) { + return tr.scrolledIntoView ? prev + 1 : prev; + } + }) +]; +var Configuration = class { + constructor(schema, plugins) { + this.schema = schema; + this.plugins = []; + this.pluginsByKey = /* @__PURE__ */ Object.create(null); + this.fields = baseFields.slice(); + if (plugins) + plugins.forEach((plugin) => { + if (this.pluginsByKey[plugin.key]) + throw new RangeError("Adding different instances of a keyed plugin (" + plugin.key + ")"); + this.plugins.push(plugin); + this.pluginsByKey[plugin.key] = plugin; + if (plugin.spec.state) + this.fields.push(new FieldDesc(plugin.key, plugin.spec.state, plugin)); + }); + } +}; +var EditorState = class _EditorState { + /** + @internal + */ + constructor(config) { + this.config = config; + } + /** + The schema of the state's document. + */ + get schema() { + return this.config.schema; + } + /** + The plugins that are active in this state. + */ + get plugins() { + return this.config.plugins; + } + /** + Apply the given transaction to produce a new state. + */ + apply(tr) { + return this.applyTransaction(tr).state; + } + /** + @internal + */ + filterTransaction(tr, ignore = -1) { + for (let i5 = 0; i5 < this.config.plugins.length; i5++) + if (i5 != ignore) { + let plugin = this.config.plugins[i5]; + if (plugin.spec.filterTransaction && !plugin.spec.filterTransaction.call(plugin, tr, this)) + return false; + } + return true; + } + /** + Verbose variant of [`apply`](https://prosemirror.net/docs/ref/#state.EditorState.apply) that + returns the precise transactions that were applied (which might + be influenced by the [transaction + hooks](https://prosemirror.net/docs/ref/#state.PluginSpec.filterTransaction) of + plugins) along with the new state. + */ + applyTransaction(rootTr) { + if (!this.filterTransaction(rootTr)) + return { state: this, transactions: [] }; + let trs = [rootTr], newState = this.applyInner(rootTr), seen = null; + for (; ; ) { + let haveNew = false; + for (let i5 = 0; i5 < this.config.plugins.length; i5++) { + let plugin = this.config.plugins[i5]; + if (plugin.spec.appendTransaction) { + let n4 = seen ? seen[i5].n : 0, oldState = seen ? seen[i5].state : this; + let tr = n4 < trs.length && plugin.spec.appendTransaction.call(plugin, n4 ? trs.slice(n4) : trs, oldState, newState); + if (tr && newState.filterTransaction(tr, i5)) { + tr.setMeta("appendedTransaction", rootTr); + if (!seen) { + seen = []; + for (let j2 = 0; j2 < this.config.plugins.length; j2++) + seen.push(j2 < i5 ? { state: newState, n: trs.length } : { state: this, n: 0 }); + } + trs.push(tr); + newState = newState.applyInner(tr); + haveNew = true; + } + if (seen) + seen[i5] = { state: newState, n: trs.length }; + } + } + if (!haveNew) + return { state: newState, transactions: trs }; + } + } + /** + @internal + */ + applyInner(tr) { + if (!tr.before.eq(this.doc)) + throw new RangeError("Applying a mismatched transaction"); + let newInstance = new _EditorState(this.config), fields = this.config.fields; + for (let i5 = 0; i5 < fields.length; i5++) { + let field = fields[i5]; + newInstance[field.name] = field.apply(tr, this[field.name], this, newInstance); + } + return newInstance; + } + /** + Start a [transaction](https://prosemirror.net/docs/ref/#state.Transaction) from this state. + */ + get tr() { + return new Transaction(this); + } + /** + Create a new state. + */ + static create(config) { + let $config = new Configuration(config.doc ? config.doc.type.schema : config.schema, config.plugins); + let instance = new _EditorState($config); + for (let i5 = 0; i5 < $config.fields.length; i5++) + instance[$config.fields[i5].name] = $config.fields[i5].init(config, instance); + return instance; + } + /** + Create a new state based on this one, but with an adjusted set + of active plugins. State fields that exist in both sets of + plugins are kept unchanged. Those that no longer exist are + dropped, and those that are new are initialized using their + [`init`](https://prosemirror.net/docs/ref/#state.StateField.init) method, passing in the new + configuration object.. + */ + reconfigure(config) { + let $config = new Configuration(this.schema, config.plugins); + let fields = $config.fields, instance = new _EditorState($config); + for (let i5 = 0; i5 < fields.length; i5++) { + let name = fields[i5].name; + instance[name] = this.hasOwnProperty(name) ? this[name] : fields[i5].init(config, instance); + } + return instance; + } + /** + Serialize this state to JSON. If you want to serialize the state + of plugins, pass an object mapping property names to use in the + resulting JSON object to plugin objects. The argument may also be + a string or number, in which case it is ignored, to support the + way `JSON.stringify` calls `toString` methods. + */ + toJSON(pluginFields) { + let result = { doc: this.doc.toJSON(), selection: this.selection.toJSON() }; + if (this.storedMarks) + result.storedMarks = this.storedMarks.map((m2) => m2.toJSON()); + if (pluginFields && typeof pluginFields == "object") + for (let prop in pluginFields) { + if (prop == "doc" || prop == "selection") + throw new RangeError("The JSON fields `doc` and `selection` are reserved"); + let plugin = pluginFields[prop], state = plugin.spec.state; + if (state && state.toJSON) + result[prop] = state.toJSON.call(plugin, this[plugin.key]); + } + return result; + } + /** + Deserialize a JSON representation of a state. `config` should + have at least a `schema` field, and should contain array of + plugins to initialize the state with. `pluginFields` can be used + to deserialize the state of plugins, by associating plugin + instances with the property names they use in the JSON object. + */ + static fromJSON(config, json, pluginFields) { + if (!json) + throw new RangeError("Invalid input for EditorState.fromJSON"); + if (!config.schema) + throw new RangeError("Required config field 'schema' missing"); + let $config = new Configuration(config.schema, config.plugins); + let instance = new _EditorState($config); + $config.fields.forEach((field) => { + if (field.name == "doc") { + instance.doc = Node.fromJSON(config.schema, json.doc); + } else if (field.name == "selection") { + instance.selection = Selection.fromJSON(instance.doc, json.selection); + } else if (field.name == "storedMarks") { + if (json.storedMarks) + instance.storedMarks = json.storedMarks.map(config.schema.markFromJSON); + } else { + if (pluginFields) + for (let prop in pluginFields) { + let plugin = pluginFields[prop], state = plugin.spec.state; + if (plugin.key == field.name && state && state.fromJSON && Object.prototype.hasOwnProperty.call(json, prop)) { + instance[field.name] = state.fromJSON.call(plugin, config, json[prop], instance); + return; + } + } + instance[field.name] = field.init(config, instance); + } + }); + return instance; + } +}; +function bindProps(obj, self, target) { + for (let prop in obj) { + let val = obj[prop]; + if (val instanceof Function) + val = val.bind(self); + else if (prop == "handleDOMEvents") + val = bindProps(val, self, {}); + target[prop] = val; + } + return target; +} +var Plugin = class { + /** + Create a plugin. + */ + constructor(spec) { + this.spec = spec; + this.props = {}; + if (spec.props) + bindProps(spec.props, this, this.props); + this.key = spec.key ? spec.key.key : createKey("plugin"); + } + /** + Extract the plugin's state field from an editor state. + */ + getState(state) { + return state[this.key]; + } +}; +var keys = /* @__PURE__ */ Object.create(null); +function createKey(name) { + if (name in keys) + return name + "$" + ++keys[name]; + keys[name] = 0; + return name + "$"; +} +var PluginKey = class { + /** + Create a plugin key. + */ + constructor(name = "key") { + this.key = createKey(name); + } + /** + Get the active plugin with this key, if any, from an editor + state. + */ + get(state) { + return state.config.pluginsByKey[this.key]; + } + /** + Get the plugin's state from an editor state. + */ + getState(state) { + return state[this.key]; + } +}; + +// node_modules/prosemirror-view/dist/index.js +var domIndex = function(node) { + for (var index = 0; ; index++) { + node = node.previousSibling; + if (!node) + return index; + } +}; +var parentNode = function(node) { + let parent = node.assignedSlot || node.parentNode; + return parent && parent.nodeType == 11 ? parent.host : parent; +}; +var reusedRange = null; +var textRange = function(node, from, to) { + let range = reusedRange || (reusedRange = document.createRange()); + range.setEnd(node, to == null ? node.nodeValue.length : to); + range.setStart(node, from || 0); + return range; +}; +var clearReusedRange = function() { + reusedRange = null; +}; +var isEquivalentPosition = function(node, off, targetNode, targetOff) { + return targetNode && (scanFor(node, off, targetNode, targetOff, -1) || scanFor(node, off, targetNode, targetOff, 1)); +}; +var atomElements = /^(img|br|input|textarea|hr)$/i; +function scanFor(node, off, targetNode, targetOff, dir) { + for (; ; ) { + if (node == targetNode && off == targetOff) + return true; + if (off == (dir < 0 ? 0 : nodeSize(node))) { + let parent = node.parentNode; + if (!parent || parent.nodeType != 1 || hasBlockDesc(node) || atomElements.test(node.nodeName) || node.contentEditable == "false") + return false; + off = domIndex(node) + (dir < 0 ? 0 : 1); + node = parent; + } else if (node.nodeType == 1) { + node = node.childNodes[off + (dir < 0 ? -1 : 0)]; + if (node.contentEditable == "false") + return false; + off = dir < 0 ? nodeSize(node) : 0; + } else { + return false; + } + } +} +function nodeSize(node) { + return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length; +} +function textNodeBefore$1(node, offset) { + for (; ; ) { + if (node.nodeType == 3 && offset) + return node; + if (node.nodeType == 1 && offset > 0) { + if (node.contentEditable == "false") + return null; + node = node.childNodes[offset - 1]; + offset = nodeSize(node); + } else if (node.parentNode && !hasBlockDesc(node)) { + offset = domIndex(node); + node = node.parentNode; + } else { + return null; + } + } +} +function textNodeAfter$1(node, offset) { + for (; ; ) { + if (node.nodeType == 3 && offset < node.nodeValue.length) + return node; + if (node.nodeType == 1 && offset < node.childNodes.length) { + if (node.contentEditable == "false") + return null; + node = node.childNodes[offset]; + offset = 0; + } else if (node.parentNode && !hasBlockDesc(node)) { + offset = domIndex(node) + 1; + node = node.parentNode; + } else { + return null; + } + } +} +function isOnEdge(node, offset, parent) { + for (let atStart = offset == 0, atEnd = offset == nodeSize(node); atStart || atEnd; ) { + if (node == parent) + return true; + let index = domIndex(node); + node = node.parentNode; + if (!node) + return false; + atStart = atStart && index == 0; + atEnd = atEnd && index == nodeSize(node); + } +} +function hasBlockDesc(dom) { + let desc; + for (let cur = dom; cur; cur = cur.parentNode) + if (desc = cur.pmViewDesc) + break; + return desc && desc.node && desc.node.isBlock && (desc.dom == dom || desc.contentDOM == dom); +} +var selectionCollapsed = function(domSel) { + return domSel.focusNode && isEquivalentPosition(domSel.focusNode, domSel.focusOffset, domSel.anchorNode, domSel.anchorOffset); +}; +function keyEvent(keyCode, key) { + let event = document.createEvent("Event"); + event.initEvent("keydown", true, true); + event.keyCode = keyCode; + event.key = event.code = key; + return event; +} +function deepActiveElement(doc3) { + let elt = doc3.activeElement; + while (elt && elt.shadowRoot) + elt = elt.shadowRoot.activeElement; + return elt; +} +function caretFromPoint(doc3, x2, y3) { + if (doc3.caretPositionFromPoint) { + try { + let pos = doc3.caretPositionFromPoint(x2, y3); + if (pos) + return { node: pos.offsetNode, offset: Math.min(nodeSize(pos.offsetNode), pos.offset) }; + } catch (_2) { + } + } + if (doc3.caretRangeFromPoint) { + let range = doc3.caretRangeFromPoint(x2, y3); + if (range) + return { node: range.startContainer, offset: Math.min(nodeSize(range.startContainer), range.startOffset) }; + } +} +var nav = typeof navigator != "undefined" ? navigator : null; +var doc2 = typeof document != "undefined" ? document : null; +var agent = nav && nav.userAgent || ""; +var ie_edge = /Edge\/(\d+)/.exec(agent); +var ie_upto10 = /MSIE \d/.exec(agent); +var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(agent); +var ie = !!(ie_upto10 || ie_11up || ie_edge); +var ie_version = ie_upto10 ? document.documentMode : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : 0; +var gecko = !ie && /gecko\/(\d+)/i.test(agent); +gecko && +(/Firefox\/(\d+)/.exec(agent) || [0, 0])[1]; +var _chrome = !ie && /Chrome\/(\d+)/.exec(agent); +var chrome = !!_chrome; +var chrome_version = _chrome ? +_chrome[1] : 0; +var safari = !ie && !!nav && /Apple Computer/.test(nav.vendor); +var ios = safari && (/Mobile\/\w+/.test(agent) || !!nav && nav.maxTouchPoints > 2); +var mac = ios || (nav ? /Mac/.test(nav.platform) : false); +var windows = nav ? /Win/.test(nav.platform) : false; +var android = /Android \d/.test(agent); +var webkit = !!doc2 && "webkitFontSmoothing" in doc2.documentElement.style; +var webkit_version = webkit ? +(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent) || [0, 0])[1] : 0; +function windowRect(doc3) { + let vp = doc3.defaultView && doc3.defaultView.visualViewport; + if (vp) + return { + left: 0, + right: vp.width, + top: 0, + bottom: vp.height + }; + return { + left: 0, + right: doc3.documentElement.clientWidth, + top: 0, + bottom: doc3.documentElement.clientHeight + }; +} +function getSide(value, side) { + return typeof value == "number" ? value : value[side]; +} +function clientRect(node) { + let rect = node.getBoundingClientRect(); + let scaleX = rect.width / node.offsetWidth || 1; + let scaleY = rect.height / node.offsetHeight || 1; + return { + left: rect.left, + right: rect.left + node.clientWidth * scaleX, + top: rect.top, + bottom: rect.top + node.clientHeight * scaleY + }; +} +function scrollRectIntoView(view, rect, startDOM) { + let scrollThreshold = view.someProp("scrollThreshold") || 0, scrollMargin = view.someProp("scrollMargin") || 5; + let doc3 = view.dom.ownerDocument; + for (let parent = startDOM || view.dom; ; ) { + if (!parent) + break; + if (parent.nodeType != 1) { + parent = parentNode(parent); + continue; + } + let elt = parent; + let atTop = elt == doc3.body; + let bounding = atTop ? windowRect(doc3) : clientRect(elt); + let moveX = 0, moveY = 0; + if (rect.top < bounding.top + getSide(scrollThreshold, "top")) + moveY = -(bounding.top - rect.top + getSide(scrollMargin, "top")); + else if (rect.bottom > bounding.bottom - getSide(scrollThreshold, "bottom")) + moveY = rect.bottom - rect.top > bounding.bottom - bounding.top ? rect.top + getSide(scrollMargin, "top") - bounding.top : rect.bottom - bounding.bottom + getSide(scrollMargin, "bottom"); + if (rect.left < bounding.left + getSide(scrollThreshold, "left")) + moveX = -(bounding.left - rect.left + getSide(scrollMargin, "left")); + else if (rect.right > bounding.right - getSide(scrollThreshold, "right")) + moveX = rect.right - bounding.right + getSide(scrollMargin, "right"); + if (moveX || moveY) { + if (atTop) { + doc3.defaultView.scrollBy(moveX, moveY); + } else { + let startX = elt.scrollLeft, startY = elt.scrollTop; + if (moveY) + elt.scrollTop += moveY; + if (moveX) + elt.scrollLeft += moveX; + let dX = elt.scrollLeft - startX, dY = elt.scrollTop - startY; + rect = { left: rect.left - dX, top: rect.top - dY, right: rect.right - dX, bottom: rect.bottom - dY }; + } + } + let pos = atTop ? "fixed" : getComputedStyle(parent).position; + if (/^(fixed|sticky)$/.test(pos)) + break; + parent = pos == "absolute" ? parent.offsetParent : parentNode(parent); + } +} +function storeScrollPos(view) { + let rect = view.dom.getBoundingClientRect(), startY = Math.max(0, rect.top); + let refDOM, refTop; + for (let x2 = (rect.left + rect.right) / 2, y3 = startY + 1; y3 < Math.min(innerHeight, rect.bottom); y3 += 5) { + let dom = view.root.elementFromPoint(x2, y3); + if (!dom || dom == view.dom || !view.dom.contains(dom)) + continue; + let localRect = dom.getBoundingClientRect(); + if (localRect.top >= startY - 20) { + refDOM = dom; + refTop = localRect.top; + break; + } + } + return { refDOM, refTop, stack: scrollStack(view.dom) }; +} +function scrollStack(dom) { + let stack = [], doc3 = dom.ownerDocument; + for (let cur = dom; cur; cur = parentNode(cur)) { + stack.push({ dom: cur, top: cur.scrollTop, left: cur.scrollLeft }); + if (dom == doc3) + break; + } + return stack; +} +function resetScrollPos({ refDOM, refTop, stack }) { + let newRefTop = refDOM ? refDOM.getBoundingClientRect().top : 0; + restoreScrollStack(stack, newRefTop == 0 ? 0 : newRefTop - refTop); +} +function restoreScrollStack(stack, dTop) { + for (let i5 = 0; i5 < stack.length; i5++) { + let { dom, top, left } = stack[i5]; + if (dom.scrollTop != top + dTop) + dom.scrollTop = top + dTop; + if (dom.scrollLeft != left) + dom.scrollLeft = left; + } +} +var preventScrollSupported = null; +function focusPreventScroll(dom) { + if (dom.setActive) + return dom.setActive(); + if (preventScrollSupported) + return dom.focus(preventScrollSupported); + let stored = scrollStack(dom); + dom.focus(preventScrollSupported == null ? { + get preventScroll() { + preventScrollSupported = { preventScroll: true }; + return true; + } + } : void 0); + if (!preventScrollSupported) { + preventScrollSupported = false; + restoreScrollStack(stored, 0); + } +} +function findOffsetInNode(node, coords) { + let closest, dxClosest = 2e8, coordsClosest, offset = 0; + let rowBot = coords.top, rowTop = coords.top; + let firstBelow, coordsBelow; + for (let child = node.firstChild, childIndex = 0; child; child = child.nextSibling, childIndex++) { + let rects; + if (child.nodeType == 1) + rects = child.getClientRects(); + else if (child.nodeType == 3) + rects = textRange(child).getClientRects(); + else + continue; + for (let i5 = 0; i5 < rects.length; i5++) { + let rect = rects[i5]; + if (rect.top <= rowBot && rect.bottom >= rowTop) { + rowBot = Math.max(rect.bottom, rowBot); + rowTop = Math.min(rect.top, rowTop); + let dx = rect.left > coords.left ? rect.left - coords.left : rect.right < coords.left ? coords.left - rect.right : 0; + if (dx < dxClosest) { + closest = child; + dxClosest = dx; + coordsClosest = dx && closest.nodeType == 3 ? { + left: rect.right < coords.left ? rect.right : rect.left, + top: coords.top + } : coords; + if (child.nodeType == 1 && dx) + offset = childIndex + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0); + continue; + } + } else if (rect.top > coords.top && !firstBelow && rect.left <= coords.left && rect.right >= coords.left) { + firstBelow = child; + coordsBelow = { left: Math.max(rect.left, Math.min(rect.right, coords.left)), top: rect.top }; + } + if (!closest && (coords.left >= rect.right && coords.top >= rect.top || coords.left >= rect.left && coords.top >= rect.bottom)) + offset = childIndex + 1; + } + } + if (!closest && firstBelow) { + closest = firstBelow; + coordsClosest = coordsBelow; + dxClosest = 0; + } + if (closest && closest.nodeType == 3) + return findOffsetInText(closest, coordsClosest); + if (!closest || dxClosest && closest.nodeType == 1) + return { node, offset }; + return findOffsetInNode(closest, coordsClosest); +} +function findOffsetInText(node, coords) { + let len = node.nodeValue.length; + let range = document.createRange(); + for (let i5 = 0; i5 < len; i5++) { + range.setEnd(node, i5 + 1); + range.setStart(node, i5); + let rect = singleRect(range, 1); + if (rect.top == rect.bottom) + continue; + if (inRect(coords, rect)) + return { node, offset: i5 + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0) }; + } + return { node, offset: 0 }; +} +function inRect(coords, rect) { + return coords.left >= rect.left - 1 && coords.left <= rect.right + 1 && coords.top >= rect.top - 1 && coords.top <= rect.bottom + 1; +} +function targetKludge(dom, coords) { + let parent = dom.parentNode; + if (parent && /^li$/i.test(parent.nodeName) && coords.left < dom.getBoundingClientRect().left) + return parent; + return dom; +} +function posFromElement(view, elt, coords) { + let { node, offset } = findOffsetInNode(elt, coords), bias = -1; + if (node.nodeType == 1 && !node.firstChild) { + let rect = node.getBoundingClientRect(); + bias = rect.left != rect.right && coords.left > (rect.left + rect.right) / 2 ? 1 : -1; + } + return view.docView.posFromDOM(node, offset, bias); +} +function posFromCaret(view, node, offset, coords) { + let outsideBlock = -1; + for (let cur = node, sawBlock = false; ; ) { + if (cur == view.dom) + break; + let desc = view.docView.nearestDesc(cur, true), rect; + if (!desc) + return null; + if (desc.dom.nodeType == 1 && (desc.node.isBlock && desc.parent || !desc.contentDOM) && // Ignore elements with zero-size bounding rectangles + ((rect = desc.dom.getBoundingClientRect()).width || rect.height)) { + if (desc.node.isBlock && desc.parent) { + if (!sawBlock && rect.left > coords.left || rect.top > coords.top) + outsideBlock = desc.posBefore; + else if (!sawBlock && rect.right < coords.left || rect.bottom < coords.top) + outsideBlock = desc.posAfter; + sawBlock = true; + } + if (!desc.contentDOM && outsideBlock < 0 && !desc.node.isText) { + let before = desc.node.isBlock ? coords.top < (rect.top + rect.bottom) / 2 : coords.left < (rect.left + rect.right) / 2; + return before ? desc.posBefore : desc.posAfter; + } + } + cur = desc.dom.parentNode; + } + return outsideBlock > -1 ? outsideBlock : view.docView.posFromDOM(node, offset, -1); +} +function elementFromPoint(element, coords, box) { + let len = element.childNodes.length; + if (len && box.top < box.bottom) { + for (let startI = Math.max(0, Math.min(len - 1, Math.floor(len * (coords.top - box.top) / (box.bottom - box.top)) - 2)), i5 = startI; ; ) { + let child = element.childNodes[i5]; + if (child.nodeType == 1) { + let rects = child.getClientRects(); + for (let j2 = 0; j2 < rects.length; j2++) { + let rect = rects[j2]; + if (inRect(coords, rect)) + return elementFromPoint(child, coords, rect); + } + } + if ((i5 = (i5 + 1) % len) == startI) + break; + } + } + return element; +} +function posAtCoords(view, coords) { + let doc3 = view.dom.ownerDocument, node, offset = 0; + let caret = caretFromPoint(doc3, coords.left, coords.top); + if (caret) + ({ node, offset } = caret); + let elt = (view.root.elementFromPoint ? view.root : doc3).elementFromPoint(coords.left, coords.top); + let pos; + if (!elt || !view.dom.contains(elt.nodeType != 1 ? elt.parentNode : elt)) { + let box = view.dom.getBoundingClientRect(); + if (!inRect(coords, box)) + return null; + elt = elementFromPoint(view.dom, coords, box); + if (!elt) + return null; + } + if (safari) { + for (let p3 = elt; node && p3; p3 = parentNode(p3)) + if (p3.draggable) + node = void 0; + } + elt = targetKludge(elt, coords); + if (node) { + if (gecko && node.nodeType == 1) { + offset = Math.min(offset, node.childNodes.length); + if (offset < node.childNodes.length) { + let next = node.childNodes[offset], box; + if (next.nodeName == "IMG" && (box = next.getBoundingClientRect()).right <= coords.left && box.bottom > coords.top) + offset++; + } + } + let prev; + if (webkit && offset && node.nodeType == 1 && (prev = node.childNodes[offset - 1]).nodeType == 1 && prev.contentEditable == "false" && prev.getBoundingClientRect().top >= coords.top) + offset--; + if (node == view.dom && offset == node.childNodes.length - 1 && node.lastChild.nodeType == 1 && coords.top > node.lastChild.getBoundingClientRect().bottom) + pos = view.state.doc.content.size; + else if (offset == 0 || node.nodeType != 1 || node.childNodes[offset - 1].nodeName != "BR") + pos = posFromCaret(view, node, offset, coords); + } + if (pos == null) + pos = posFromElement(view, elt, coords); + let desc = view.docView.nearestDesc(elt, true); + return { pos, inside: desc ? desc.posAtStart - desc.border : -1 }; +} +function nonZero(rect) { + return rect.top < rect.bottom || rect.left < rect.right; +} +function singleRect(target, bias) { + let rects = target.getClientRects(); + if (rects.length) { + let first2 = rects[bias < 0 ? 0 : rects.length - 1]; + if (nonZero(first2)) + return first2; + } + return Array.prototype.find.call(rects, nonZero) || target.getBoundingClientRect(); +} +var BIDI = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/; +function coordsAtPos(view, pos, side) { + let { node, offset, atom } = view.docView.domFromPos(pos, side < 0 ? -1 : 1); + let supportEmptyRange = webkit || gecko; + if (node.nodeType == 3) { + if (supportEmptyRange && (BIDI.test(node.nodeValue) || (side < 0 ? !offset : offset == node.nodeValue.length))) { + let rect = singleRect(textRange(node, offset, offset), side); + if (gecko && offset && /\s/.test(node.nodeValue[offset - 1]) && offset < node.nodeValue.length) { + let rectBefore = singleRect(textRange(node, offset - 1, offset - 1), -1); + if (rectBefore.top == rect.top) { + let rectAfter = singleRect(textRange(node, offset, offset + 1), -1); + if (rectAfter.top != rect.top) + return flattenV(rectAfter, rectAfter.left < rectBefore.left); + } + } + return rect; + } else { + let from = offset, to = offset, takeSide = side < 0 ? 1 : -1; + if (side < 0 && !offset) { + to++; + takeSide = -1; + } else if (side >= 0 && offset == node.nodeValue.length) { + from--; + takeSide = 1; + } else if (side < 0) { + from--; + } else { + to++; + } + return flattenV(singleRect(textRange(node, from, to), takeSide), takeSide < 0); + } + } + let $dom = view.state.doc.resolve(pos - (atom || 0)); + if (!$dom.parent.inlineContent) { + if (atom == null && offset && (side < 0 || offset == nodeSize(node))) { + let before = node.childNodes[offset - 1]; + if (before.nodeType == 1) + return flattenH(before.getBoundingClientRect(), false); + } + if (atom == null && offset < nodeSize(node)) { + let after = node.childNodes[offset]; + if (after.nodeType == 1) + return flattenH(after.getBoundingClientRect(), true); + } + return flattenH(node.getBoundingClientRect(), side >= 0); + } + if (atom == null && offset && (side < 0 || offset == nodeSize(node))) { + let before = node.childNodes[offset - 1]; + let target = before.nodeType == 3 ? textRange(before, nodeSize(before) - (supportEmptyRange ? 0 : 1)) : before.nodeType == 1 && (before.nodeName != "BR" || !before.nextSibling) ? before : null; + if (target) + return flattenV(singleRect(target, 1), false); + } + if (atom == null && offset < nodeSize(node)) { + let after = node.childNodes[offset]; + while (after.pmViewDesc && after.pmViewDesc.ignoreForCoords) + after = after.nextSibling; + let target = !after ? null : after.nodeType == 3 ? textRange(after, 0, supportEmptyRange ? 0 : 1) : after.nodeType == 1 ? after : null; + if (target) + return flattenV(singleRect(target, -1), true); + } + return flattenV(singleRect(node.nodeType == 3 ? textRange(node) : node, -side), side >= 0); +} +function flattenV(rect, left) { + if (rect.width == 0) + return rect; + let x2 = left ? rect.left : rect.right; + return { top: rect.top, bottom: rect.bottom, left: x2, right: x2 }; +} +function flattenH(rect, top) { + if (rect.height == 0) + return rect; + let y3 = top ? rect.top : rect.bottom; + return { top: y3, bottom: y3, left: rect.left, right: rect.right }; +} +function withFlushedState(view, state, f3) { + let viewState = view.state, active = view.root.activeElement; + if (viewState != state) + view.updateState(state); + if (active != view.dom) + view.focus(); + try { + return f3(); + } finally { + if (viewState != state) + view.updateState(viewState); + if (active != view.dom && active) + active.focus(); + } +} +function endOfTextblockVertical(view, state, dir) { + let sel = state.selection; + let $pos = dir == "up" ? sel.$from : sel.$to; + return withFlushedState(view, state, () => { + let { node: dom } = view.docView.domFromPos($pos.pos, dir == "up" ? -1 : 1); + for (; ; ) { + let nearest = view.docView.nearestDesc(dom, true); + if (!nearest) + break; + if (nearest.node.isBlock) { + dom = nearest.contentDOM || nearest.dom; + break; + } + dom = nearest.dom.parentNode; + } + let coords = coordsAtPos(view, $pos.pos, 1); + for (let child = dom.firstChild; child; child = child.nextSibling) { + let boxes; + if (child.nodeType == 1) + boxes = child.getClientRects(); + else if (child.nodeType == 3) + boxes = textRange(child, 0, child.nodeValue.length).getClientRects(); + else + continue; + for (let i5 = 0; i5 < boxes.length; i5++) { + let box = boxes[i5]; + if (box.bottom > box.top + 1 && (dir == "up" ? coords.top - box.top > (box.bottom - coords.top) * 2 : box.bottom - coords.bottom > (coords.bottom - box.top) * 2)) + return false; + } + } + return true; + }); +} +var maybeRTL = /[\u0590-\u08ac]/; +function endOfTextblockHorizontal(view, state, dir) { + let { $head } = state.selection; + if (!$head.parent.isTextblock) + return false; + let offset = $head.parentOffset, atStart = !offset, atEnd = offset == $head.parent.content.size; + let sel = view.domSelection(); + if (!sel) + return $head.pos == $head.start() || $head.pos == $head.end(); + if (!maybeRTL.test($head.parent.textContent) || !sel.modify) + return dir == "left" || dir == "backward" ? atStart : atEnd; + return withFlushedState(view, state, () => { + let { focusNode: oldNode, focusOffset: oldOff, anchorNode, anchorOffset } = view.domSelectionRange(); + let oldBidiLevel = sel.caretBidiLevel; + sel.modify("move", dir, "character"); + let parentDOM = $head.depth ? view.docView.domAfterPos($head.before()) : view.dom; + let { focusNode: newNode, focusOffset: newOff } = view.domSelectionRange(); + let result = newNode && !parentDOM.contains(newNode.nodeType == 1 ? newNode : newNode.parentNode) || oldNode == newNode && oldOff == newOff; + try { + sel.collapse(anchorNode, anchorOffset); + if (oldNode && (oldNode != anchorNode || oldOff != anchorOffset) && sel.extend) + sel.extend(oldNode, oldOff); + } catch (_2) { + } + if (oldBidiLevel != null) + sel.caretBidiLevel = oldBidiLevel; + return result; + }); +} +var cachedState = null; +var cachedDir = null; +var cachedResult = false; +function endOfTextblock(view, state, dir) { + if (cachedState == state && cachedDir == dir) + return cachedResult; + cachedState = state; + cachedDir = dir; + return cachedResult = dir == "up" || dir == "down" ? endOfTextblockVertical(view, state, dir) : endOfTextblockHorizontal(view, state, dir); +} +var NOT_DIRTY = 0; +var CHILD_DIRTY = 1; +var CONTENT_DIRTY = 2; +var NODE_DIRTY = 3; +var ViewDesc = class { + constructor(parent, children, dom, contentDOM) { + this.parent = parent; + this.children = children; + this.dom = dom; + this.contentDOM = contentDOM; + this.dirty = NOT_DIRTY; + dom.pmViewDesc = this; + } + // Used to check whether a given description corresponds to a + // widget/mark/node. + matchesWidget(widget) { + return false; + } + matchesMark(mark) { + return false; + } + matchesNode(node, outerDeco, innerDeco) { + return false; + } + matchesHack(nodeName) { + return false; + } + // When parsing in-editor content (in domchange.js), we allow + // descriptions to determine the parse rules that should be used to + // parse them. + parseRule() { + return null; + } + // Used by the editor's event handler to ignore events that come + // from certain descs. + stopEvent(event) { + return false; + } + // The size of the content represented by this desc. + get size() { + let size = 0; + for (let i5 = 0; i5 < this.children.length; i5++) + size += this.children[i5].size; + return size; + } + // For block nodes, this represents the space taken up by their + // start/end tokens. + get border() { + return 0; + } + destroy() { + this.parent = void 0; + if (this.dom.pmViewDesc == this) + this.dom.pmViewDesc = void 0; + for (let i5 = 0; i5 < this.children.length; i5++) + this.children[i5].destroy(); + } + posBeforeChild(child) { + for (let i5 = 0, pos = this.posAtStart; ; i5++) { + let cur = this.children[i5]; + if (cur == child) + return pos; + pos += cur.size; + } + } + get posBefore() { + return this.parent.posBeforeChild(this); + } + get posAtStart() { + return this.parent ? this.parent.posBeforeChild(this) + this.border : 0; + } + get posAfter() { + return this.posBefore + this.size; + } + get posAtEnd() { + return this.posAtStart + this.size - 2 * this.border; + } + localPosFromDOM(dom, offset, bias) { + if (this.contentDOM && this.contentDOM.contains(dom.nodeType == 1 ? dom : dom.parentNode)) { + if (bias < 0) { + let domBefore, desc; + if (dom == this.contentDOM) { + domBefore = dom.childNodes[offset - 1]; + } else { + while (dom.parentNode != this.contentDOM) + dom = dom.parentNode; + domBefore = dom.previousSibling; + } + while (domBefore && !((desc = domBefore.pmViewDesc) && desc.parent == this)) + domBefore = domBefore.previousSibling; + return domBefore ? this.posBeforeChild(desc) + desc.size : this.posAtStart; + } else { + let domAfter, desc; + if (dom == this.contentDOM) { + domAfter = dom.childNodes[offset]; + } else { + while (dom.parentNode != this.contentDOM) + dom = dom.parentNode; + domAfter = dom.nextSibling; + } + while (domAfter && !((desc = domAfter.pmViewDesc) && desc.parent == this)) + domAfter = domAfter.nextSibling; + return domAfter ? this.posBeforeChild(desc) : this.posAtEnd; + } + } + let atEnd; + if (dom == this.dom && this.contentDOM) { + atEnd = offset > domIndex(this.contentDOM); + } else if (this.contentDOM && this.contentDOM != this.dom && this.dom.contains(this.contentDOM)) { + atEnd = dom.compareDocumentPosition(this.contentDOM) & 2; + } else if (this.dom.firstChild) { + if (offset == 0) + for (let search = dom; ; search = search.parentNode) { + if (search == this.dom) { + atEnd = false; + break; + } + if (search.previousSibling) + break; + } + if (atEnd == null && offset == dom.childNodes.length) + for (let search = dom; ; search = search.parentNode) { + if (search == this.dom) { + atEnd = true; + break; + } + if (search.nextSibling) + break; + } + } + return (atEnd == null ? bias > 0 : atEnd) ? this.posAtEnd : this.posAtStart; + } + nearestDesc(dom, onlyNodes = false) { + for (let first2 = true, cur = dom; cur; cur = cur.parentNode) { + let desc = this.getDesc(cur), nodeDOM; + if (desc && (!onlyNodes || desc.node)) { + if (first2 && (nodeDOM = desc.nodeDOM) && !(nodeDOM.nodeType == 1 ? nodeDOM.contains(dom.nodeType == 1 ? dom : dom.parentNode) : nodeDOM == dom)) + first2 = false; + else + return desc; + } + } + } + getDesc(dom) { + let desc = dom.pmViewDesc; + for (let cur = desc; cur; cur = cur.parent) + if (cur == this) + return desc; + } + posFromDOM(dom, offset, bias) { + for (let scan = dom; scan; scan = scan.parentNode) { + let desc = this.getDesc(scan); + if (desc) + return desc.localPosFromDOM(dom, offset, bias); + } + return -1; + } + // Find the desc for the node after the given pos, if any. (When a + // parent node overrode rendering, there might not be one.) + descAt(pos) { + for (let i5 = 0, offset = 0; i5 < this.children.length; i5++) { + let child = this.children[i5], end = offset + child.size; + if (offset == pos && end != offset) { + while (!child.border && child.children.length) { + for (let i6 = 0; i6 < child.children.length; i6++) { + let inner = child.children[i6]; + if (inner.size) { + child = inner; + break; + } + } + } + return child; + } + if (pos < end) + return child.descAt(pos - offset - child.border); + offset = end; + } + } + domFromPos(pos, side) { + if (!this.contentDOM) + return { node: this.dom, offset: 0, atom: pos + 1 }; + let i5 = 0, offset = 0; + for (let curPos = 0; i5 < this.children.length; i5++) { + let child = this.children[i5], end = curPos + child.size; + if (end > pos || child instanceof TrailingHackViewDesc) { + offset = pos - curPos; + break; + } + curPos = end; + } + if (offset) + return this.children[i5].domFromPos(offset - this.children[i5].border, side); + for (let prev; i5 && !(prev = this.children[i5 - 1]).size && prev instanceof WidgetViewDesc && prev.side >= 0; i5--) { + } + if (side <= 0) { + let prev, enter2 = true; + for (; ; i5--, enter2 = false) { + prev = i5 ? this.children[i5 - 1] : null; + if (!prev || prev.dom.parentNode == this.contentDOM) + break; + } + if (prev && side && enter2 && !prev.border && !prev.domAtom) + return prev.domFromPos(prev.size, side); + return { node: this.contentDOM, offset: prev ? domIndex(prev.dom) + 1 : 0 }; + } else { + let next, enter2 = true; + for (; ; i5++, enter2 = false) { + next = i5 < this.children.length ? this.children[i5] : null; + if (!next || next.dom.parentNode == this.contentDOM) + break; + } + if (next && enter2 && !next.border && !next.domAtom) + return next.domFromPos(0, side); + return { node: this.contentDOM, offset: next ? domIndex(next.dom) : this.contentDOM.childNodes.length }; + } + } + // Used to find a DOM range in a single parent for a given changed + // range. + parseRange(from, to, base2 = 0) { + if (this.children.length == 0) + return { node: this.contentDOM, from, to, fromOffset: 0, toOffset: this.contentDOM.childNodes.length }; + let fromOffset = -1, toOffset = -1; + for (let offset = base2, i5 = 0; ; i5++) { + let child = this.children[i5], end = offset + child.size; + if (fromOffset == -1 && from <= end) { + let childBase = offset + child.border; + if (from >= childBase && to <= end - child.border && child.node && child.contentDOM && this.contentDOM.contains(child.contentDOM)) + return child.parseRange(from, to, childBase); + from = offset; + for (let j2 = i5; j2 > 0; j2--) { + let prev = this.children[j2 - 1]; + if (prev.size && prev.dom.parentNode == this.contentDOM && !prev.emptyChildAt(1)) { + fromOffset = domIndex(prev.dom) + 1; + break; + } + from -= prev.size; + } + if (fromOffset == -1) + fromOffset = 0; + } + if (fromOffset > -1 && (end > to || i5 == this.children.length - 1)) { + to = end; + for (let j2 = i5 + 1; j2 < this.children.length; j2++) { + let next = this.children[j2]; + if (next.size && next.dom.parentNode == this.contentDOM && !next.emptyChildAt(-1)) { + toOffset = domIndex(next.dom); + break; + } + to += next.size; + } + if (toOffset == -1) + toOffset = this.contentDOM.childNodes.length; + break; + } + offset = end; + } + return { node: this.contentDOM, from, to, fromOffset, toOffset }; + } + emptyChildAt(side) { + if (this.border || !this.contentDOM || !this.children.length) + return false; + let child = this.children[side < 0 ? 0 : this.children.length - 1]; + return child.size == 0 || child.emptyChildAt(side); + } + domAfterPos(pos) { + let { node, offset } = this.domFromPos(pos, 0); + if (node.nodeType != 1 || offset == node.childNodes.length) + throw new RangeError("No node after pos " + pos); + return node.childNodes[offset]; + } + // View descs are responsible for setting any selection that falls + // entirely inside of them, so that custom implementations can do + // custom things with the selection. Note that this falls apart when + // a selection starts in such a node and ends in another, in which + // case we just use whatever domFromPos produces as a best effort. + setSelection(anchor, head, view, force = false) { + let from = Math.min(anchor, head), to = Math.max(anchor, head); + for (let i5 = 0, offset = 0; i5 < this.children.length; i5++) { + let child = this.children[i5], end = offset + child.size; + if (from > offset && to < end) + return child.setSelection(anchor - offset - child.border, head - offset - child.border, view, force); + offset = end; + } + let anchorDOM = this.domFromPos(anchor, anchor ? -1 : 1); + let headDOM = head == anchor ? anchorDOM : this.domFromPos(head, head ? -1 : 1); + let domSel = view.root.getSelection(); + let selRange = view.domSelectionRange(); + let brKludge = false; + if ((gecko || safari) && anchor == head) { + let { node, offset } = anchorDOM; + if (node.nodeType == 3) { + brKludge = !!(offset && node.nodeValue[offset - 1] == "\n"); + if (brKludge && offset == node.nodeValue.length) { + for (let scan = node, after; scan; scan = scan.parentNode) { + if (after = scan.nextSibling) { + if (after.nodeName == "BR") + anchorDOM = headDOM = { node: after.parentNode, offset: domIndex(after) + 1 }; + break; + } + let desc = scan.pmViewDesc; + if (desc && desc.node && desc.node.isBlock) + break; + } + } + } else { + let prev = node.childNodes[offset - 1]; + brKludge = prev && (prev.nodeName == "BR" || prev.contentEditable == "false"); + } + } + if (gecko && selRange.focusNode && selRange.focusNode != headDOM.node && selRange.focusNode.nodeType == 1) { + let after = selRange.focusNode.childNodes[selRange.focusOffset]; + if (after && after.contentEditable == "false") + force = true; + } + if (!(force || brKludge && safari) && isEquivalentPosition(anchorDOM.node, anchorDOM.offset, selRange.anchorNode, selRange.anchorOffset) && isEquivalentPosition(headDOM.node, headDOM.offset, selRange.focusNode, selRange.focusOffset)) + return; + let domSelExtended = false; + if ((domSel.extend || anchor == head) && !brKludge) { + domSel.collapse(anchorDOM.node, anchorDOM.offset); + try { + if (anchor != head) + domSel.extend(headDOM.node, headDOM.offset); + domSelExtended = true; + } catch (_2) { + } + } + if (!domSelExtended) { + if (anchor > head) { + let tmp = anchorDOM; + anchorDOM = headDOM; + headDOM = tmp; + } + let range = document.createRange(); + range.setEnd(headDOM.node, headDOM.offset); + range.setStart(anchorDOM.node, anchorDOM.offset); + domSel.removeAllRanges(); + domSel.addRange(range); + } + } + ignoreMutation(mutation) { + return !this.contentDOM && mutation.type != "selection"; + } + get contentLost() { + return this.contentDOM && this.contentDOM != this.dom && !this.dom.contains(this.contentDOM); + } + // Remove a subtree of the element tree that has been touched + // by a DOM change, so that the next update will redraw it. + markDirty(from, to) { + for (let offset = 0, i5 = 0; i5 < this.children.length; i5++) { + let child = this.children[i5], end = offset + child.size; + if (offset == end ? from <= end && to >= offset : from < end && to > offset) { + let startInside = offset + child.border, endInside = end - child.border; + if (from >= startInside && to <= endInside) { + this.dirty = from == offset || to == end ? CONTENT_DIRTY : CHILD_DIRTY; + if (from == startInside && to == endInside && (child.contentLost || child.dom.parentNode != this.contentDOM)) + child.dirty = NODE_DIRTY; + else + child.markDirty(from - startInside, to - startInside); + return; + } else { + child.dirty = child.dom == child.contentDOM && child.dom.parentNode == this.contentDOM && !child.children.length ? CONTENT_DIRTY : NODE_DIRTY; + } + } + offset = end; + } + this.dirty = CONTENT_DIRTY; + } + markParentsDirty() { + let level = 1; + for (let node = this.parent; node; node = node.parent, level++) { + let dirty = level == 1 ? CONTENT_DIRTY : CHILD_DIRTY; + if (node.dirty < dirty) + node.dirty = dirty; + } + } + get domAtom() { + return false; + } + get ignoreForCoords() { + return false; + } + isText(text) { + return false; + } +}; +var WidgetViewDesc = class extends ViewDesc { + constructor(parent, widget, view, pos) { + let self, dom = widget.type.toDOM; + if (typeof dom == "function") + dom = dom(view, () => { + if (!self) + return pos; + if (self.parent) + return self.parent.posBeforeChild(self); + }); + if (!widget.type.spec.raw) { + if (dom.nodeType != 1) { + let wrap2 = document.createElement("span"); + wrap2.appendChild(dom); + dom = wrap2; + } + dom.contentEditable = "false"; + dom.classList.add("ProseMirror-widget"); + } + super(parent, [], dom, null); + this.widget = widget; + this.widget = widget; + self = this; + } + matchesWidget(widget) { + return this.dirty == NOT_DIRTY && widget.type.eq(this.widget.type); + } + parseRule() { + return { ignore: true }; + } + stopEvent(event) { + let stop = this.widget.spec.stopEvent; + return stop ? stop(event) : false; + } + ignoreMutation(mutation) { + return mutation.type != "selection" || this.widget.spec.ignoreSelection; + } + destroy() { + this.widget.type.destroy(this.dom); + super.destroy(); + } + get domAtom() { + return true; + } + get side() { + return this.widget.type.side; + } +}; +var CompositionViewDesc = class extends ViewDesc { + constructor(parent, dom, textDOM, text) { + super(parent, [], dom, null); + this.textDOM = textDOM; + this.text = text; + } + get size() { + return this.text.length; + } + localPosFromDOM(dom, offset) { + if (dom != this.textDOM) + return this.posAtStart + (offset ? this.size : 0); + return this.posAtStart + offset; + } + domFromPos(pos) { + return { node: this.textDOM, offset: pos }; + } + ignoreMutation(mut) { + return mut.type === "characterData" && mut.target.nodeValue == mut.oldValue; + } +}; +var MarkViewDesc = class _MarkViewDesc extends ViewDesc { + constructor(parent, mark, dom, contentDOM, spec) { + super(parent, [], dom, contentDOM); + this.mark = mark; + this.spec = spec; + } + static create(parent, mark, inline, view) { + let custom = view.nodeViews[mark.type.name]; + let spec = custom && custom(mark, view, inline); + if (!spec || !spec.dom) + spec = DOMSerializer.renderSpec(document, mark.type.spec.toDOM(mark, inline), null, mark.attrs); + return new _MarkViewDesc(parent, mark, spec.dom, spec.contentDOM || spec.dom, spec); + } + parseRule() { + if (this.dirty & NODE_DIRTY || this.mark.type.spec.reparseInView) + return null; + return { mark: this.mark.type.name, attrs: this.mark.attrs, contentElement: this.contentDOM }; + } + matchesMark(mark) { + return this.dirty != NODE_DIRTY && this.mark.eq(mark); + } + markDirty(from, to) { + super.markDirty(from, to); + if (this.dirty != NOT_DIRTY) { + let parent = this.parent; + while (!parent.node) + parent = parent.parent; + if (parent.dirty < this.dirty) + parent.dirty = this.dirty; + this.dirty = NOT_DIRTY; + } + } + slice(from, to, view) { + let copy2 = _MarkViewDesc.create(this.parent, this.mark, true, view); + let nodes = this.children, size = this.size; + if (to < size) + nodes = replaceNodes(nodes, to, size, view); + if (from > 0) + nodes = replaceNodes(nodes, 0, from, view); + for (let i5 = 0; i5 < nodes.length; i5++) + nodes[i5].parent = copy2; + copy2.children = nodes; + return copy2; + } + ignoreMutation(mutation) { + return this.spec.ignoreMutation ? this.spec.ignoreMutation(mutation) : super.ignoreMutation(mutation); + } + destroy() { + if (this.spec.destroy) + this.spec.destroy(); + super.destroy(); + } +}; +var NodeViewDesc = class _NodeViewDesc extends ViewDesc { + constructor(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos) { + super(parent, [], dom, contentDOM); + this.node = node; + this.outerDeco = outerDeco; + this.innerDeco = innerDeco; + this.nodeDOM = nodeDOM; + } + // By default, a node is rendered using the `toDOM` method from the + // node type spec. But client code can use the `nodeViews` spec to + // supply a custom node view, which can influence various aspects of + // the way the node works. + // + // (Using subclassing for this was intentionally decided against, + // since it'd require exposing a whole slew of finicky + // implementation details to the user code that they probably will + // never need.) + static create(parent, node, outerDeco, innerDeco, view, pos) { + let custom = view.nodeViews[node.type.name], descObj; + let spec = custom && custom(node, view, () => { + if (!descObj) + return pos; + if (descObj.parent) + return descObj.parent.posBeforeChild(descObj); + }, outerDeco, innerDeco); + let dom = spec && spec.dom, contentDOM = spec && spec.contentDOM; + if (node.isText) { + if (!dom) + dom = document.createTextNode(node.text); + else if (dom.nodeType != 3) + throw new RangeError("Text must be rendered as a DOM text node"); + } else if (!dom) { + let spec2 = DOMSerializer.renderSpec(document, node.type.spec.toDOM(node), null, node.attrs); + ({ dom, contentDOM } = spec2); + } + if (!contentDOM && !node.isText && dom.nodeName != "BR") { + if (!dom.hasAttribute("contenteditable")) + dom.contentEditable = "false"; + if (node.type.spec.draggable) + dom.draggable = true; + } + let nodeDOM = dom; + dom = applyOuterDeco(dom, outerDeco, node); + if (spec) + return descObj = new CustomNodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM || null, nodeDOM, spec, view, pos + 1); + else if (node.isText) + return new TextViewDesc(parent, node, outerDeco, innerDeco, dom, nodeDOM, view); + else + return new _NodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM || null, nodeDOM, view, pos + 1); + } + parseRule() { + if (this.node.type.spec.reparseInView) + return null; + let rule = { node: this.node.type.name, attrs: this.node.attrs }; + if (this.node.type.whitespace == "pre") + rule.preserveWhitespace = "full"; + if (!this.contentDOM) { + rule.getContent = () => this.node.content; + } else if (!this.contentLost) { + rule.contentElement = this.contentDOM; + } else { + for (let i5 = this.children.length - 1; i5 >= 0; i5--) { + let child = this.children[i5]; + if (this.dom.contains(child.dom.parentNode)) { + rule.contentElement = child.dom.parentNode; + break; + } + } + if (!rule.contentElement) + rule.getContent = () => Fragment.empty; + } + return rule; + } + matchesNode(node, outerDeco, innerDeco) { + return this.dirty == NOT_DIRTY && node.eq(this.node) && sameOuterDeco(outerDeco, this.outerDeco) && innerDeco.eq(this.innerDeco); + } + get size() { + return this.node.nodeSize; + } + get border() { + return this.node.isLeaf ? 0 : 1; + } + // Syncs `this.children` to match `this.node.content` and the local + // decorations, possibly introducing nesting for marks. Then, in a + // separate step, syncs the DOM inside `this.contentDOM` to + // `this.children`. + updateChildren(view, pos) { + let inline = this.node.inlineContent, off = pos; + let composition = view.composing ? this.localCompositionInfo(view, pos) : null; + let localComposition = composition && composition.pos > -1 ? composition : null; + let compositionInChild = composition && composition.pos < 0; + let updater = new ViewTreeUpdater(this, localComposition && localComposition.node, view); + iterDeco(this.node, this.innerDeco, (widget, i5, insideNode) => { + if (widget.spec.marks) + updater.syncToMarks(widget.spec.marks, inline, view); + else if (widget.type.side >= 0 && !insideNode) + updater.syncToMarks(i5 == this.node.childCount ? Mark.none : this.node.child(i5).marks, inline, view); + updater.placeWidget(widget, view, off); + }, (child, outerDeco, innerDeco, i5) => { + updater.syncToMarks(child.marks, inline, view); + let compIndex; + if (updater.findNodeMatch(child, outerDeco, innerDeco, i5)) ; + else if (compositionInChild && view.state.selection.from > off && view.state.selection.to < off + child.nodeSize && (compIndex = updater.findIndexWithChild(composition.node)) > -1 && updater.updateNodeAt(child, outerDeco, innerDeco, compIndex, view)) ; + else if (updater.updateNextNode(child, outerDeco, innerDeco, view, i5, off)) ; + else { + updater.addNode(child, outerDeco, innerDeco, view, off); + } + off += child.nodeSize; + }); + updater.syncToMarks([], inline, view); + if (this.node.isTextblock) + updater.addTextblockHacks(); + updater.destroyRest(); + if (updater.changed || this.dirty == CONTENT_DIRTY) { + if (localComposition) + this.protectLocalComposition(view, localComposition); + renderDescs(this.contentDOM, this.children, view); + if (ios) + iosHacks(this.dom); + } + } + localCompositionInfo(view, pos) { + let { from, to } = view.state.selection; + if (!(view.state.selection instanceof TextSelection) || from < pos || to > pos + this.node.content.size) + return null; + let textNode = view.input.compositionNode; + if (!textNode || !this.dom.contains(textNode.parentNode)) + return null; + if (this.node.inlineContent) { + let text = textNode.nodeValue; + let textPos = findTextInFragment(this.node.content, text, from - pos, to - pos); + return textPos < 0 ? null : { node: textNode, pos: textPos, text }; + } else { + return { node: textNode, pos: -1, text: "" }; + } + } + protectLocalComposition(view, { node, pos, text }) { + if (this.getDesc(node)) + return; + let topNode = node; + for (; ; topNode = topNode.parentNode) { + if (topNode.parentNode == this.contentDOM) + break; + while (topNode.previousSibling) + topNode.parentNode.removeChild(topNode.previousSibling); + while (topNode.nextSibling) + topNode.parentNode.removeChild(topNode.nextSibling); + if (topNode.pmViewDesc) + topNode.pmViewDesc = void 0; + } + let desc = new CompositionViewDesc(this, topNode, node, text); + view.input.compositionNodes.push(desc); + this.children = replaceNodes(this.children, pos, pos + text.length, view, desc); + } + // If this desc must be updated to match the given node decoration, + // do so and return true. + update(node, outerDeco, innerDeco, view) { + if (this.dirty == NODE_DIRTY || !node.sameMarkup(this.node)) + return false; + this.updateInner(node, outerDeco, innerDeco, view); + return true; + } + updateInner(node, outerDeco, innerDeco, view) { + this.updateOuterDeco(outerDeco); + this.node = node; + this.innerDeco = innerDeco; + if (this.contentDOM) + this.updateChildren(view, this.posAtStart); + this.dirty = NOT_DIRTY; + } + updateOuterDeco(outerDeco) { + if (sameOuterDeco(outerDeco, this.outerDeco)) + return; + let needsWrap = this.nodeDOM.nodeType != 1; + let oldDOM = this.dom; + this.dom = patchOuterDeco(this.dom, this.nodeDOM, computeOuterDeco(this.outerDeco, this.node, needsWrap), computeOuterDeco(outerDeco, this.node, needsWrap)); + if (this.dom != oldDOM) { + oldDOM.pmViewDesc = void 0; + this.dom.pmViewDesc = this; + } + this.outerDeco = outerDeco; + } + // Mark this node as being the selected node. + selectNode() { + if (this.nodeDOM.nodeType == 1) + this.nodeDOM.classList.add("ProseMirror-selectednode"); + if (this.contentDOM || !this.node.type.spec.draggable) + this.dom.draggable = true; + } + // Remove selected node marking from this node. + deselectNode() { + if (this.nodeDOM.nodeType == 1) { + this.nodeDOM.classList.remove("ProseMirror-selectednode"); + if (this.contentDOM || !this.node.type.spec.draggable) + this.dom.removeAttribute("draggable"); + } + } + get domAtom() { + return this.node.isAtom; + } +}; +function docViewDesc(doc3, outerDeco, innerDeco, dom, view) { + applyOuterDeco(dom, outerDeco, doc3); + let docView = new NodeViewDesc(void 0, doc3, outerDeco, innerDeco, dom, dom, dom, view, 0); + if (docView.contentDOM) + docView.updateChildren(view, 0); + return docView; +} +var TextViewDesc = class _TextViewDesc extends NodeViewDesc { + constructor(parent, node, outerDeco, innerDeco, dom, nodeDOM, view) { + super(parent, node, outerDeco, innerDeco, dom, null, nodeDOM, view, 0); + } + parseRule() { + let skip = this.nodeDOM.parentNode; + while (skip && skip != this.dom && !skip.pmIsDeco) + skip = skip.parentNode; + return { skip: skip || true }; + } + update(node, outerDeco, innerDeco, view) { + if (this.dirty == NODE_DIRTY || this.dirty != NOT_DIRTY && !this.inParent() || !node.sameMarkup(this.node)) + return false; + this.updateOuterDeco(outerDeco); + if ((this.dirty != NOT_DIRTY || node.text != this.node.text) && node.text != this.nodeDOM.nodeValue) { + this.nodeDOM.nodeValue = node.text; + if (view.trackWrites == this.nodeDOM) + view.trackWrites = null; + } + this.node = node; + this.dirty = NOT_DIRTY; + return true; + } + inParent() { + let parentDOM = this.parent.contentDOM; + for (let n4 = this.nodeDOM; n4; n4 = n4.parentNode) + if (n4 == parentDOM) + return true; + return false; + } + domFromPos(pos) { + return { node: this.nodeDOM, offset: pos }; + } + localPosFromDOM(dom, offset, bias) { + if (dom == this.nodeDOM) + return this.posAtStart + Math.min(offset, this.node.text.length); + return super.localPosFromDOM(dom, offset, bias); + } + ignoreMutation(mutation) { + return mutation.type != "characterData" && mutation.type != "selection"; + } + slice(from, to, view) { + let node = this.node.cut(from, to), dom = document.createTextNode(node.text); + return new _TextViewDesc(this.parent, node, this.outerDeco, this.innerDeco, dom, dom, view); + } + markDirty(from, to) { + super.markDirty(from, to); + if (this.dom != this.nodeDOM && (from == 0 || to == this.nodeDOM.nodeValue.length)) + this.dirty = NODE_DIRTY; + } + get domAtom() { + return false; + } + isText(text) { + return this.node.text == text; + } +}; +var TrailingHackViewDesc = class extends ViewDesc { + parseRule() { + return { ignore: true }; + } + matchesHack(nodeName) { + return this.dirty == NOT_DIRTY && this.dom.nodeName == nodeName; + } + get domAtom() { + return true; + } + get ignoreForCoords() { + return this.dom.nodeName == "IMG"; + } +}; +var CustomNodeViewDesc = class extends NodeViewDesc { + constructor(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, spec, view, pos) { + super(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, view, pos); + this.spec = spec; + } + // A custom `update` method gets to decide whether the update goes + // through. If it does, and there's a `contentDOM` node, our logic + // updates the children. + update(node, outerDeco, innerDeco, view) { + if (this.dirty == NODE_DIRTY) + return false; + if (this.spec.update && (this.node.type == node.type || this.spec.multiType)) { + let result = this.spec.update(node, outerDeco, innerDeco); + if (result) + this.updateInner(node, outerDeco, innerDeco, view); + return result; + } else if (!this.contentDOM && !node.isLeaf) { + return false; + } else { + return super.update(node, outerDeco, innerDeco, view); + } + } + selectNode() { + this.spec.selectNode ? this.spec.selectNode() : super.selectNode(); + } + deselectNode() { + this.spec.deselectNode ? this.spec.deselectNode() : super.deselectNode(); + } + setSelection(anchor, head, view, force) { + this.spec.setSelection ? this.spec.setSelection(anchor, head, view.root) : super.setSelection(anchor, head, view, force); + } + destroy() { + if (this.spec.destroy) + this.spec.destroy(); + super.destroy(); + } + stopEvent(event) { + return this.spec.stopEvent ? this.spec.stopEvent(event) : false; + } + ignoreMutation(mutation) { + return this.spec.ignoreMutation ? this.spec.ignoreMutation(mutation) : super.ignoreMutation(mutation); + } +}; +function renderDescs(parentDOM, descs, view) { + let dom = parentDOM.firstChild, written = false; + for (let i5 = 0; i5 < descs.length; i5++) { + let desc = descs[i5], childDOM = desc.dom; + if (childDOM.parentNode == parentDOM) { + while (childDOM != dom) { + dom = rm(dom); + written = true; + } + dom = dom.nextSibling; + } else { + written = true; + parentDOM.insertBefore(childDOM, dom); + } + if (desc instanceof MarkViewDesc) { + let pos = dom ? dom.previousSibling : parentDOM.lastChild; + renderDescs(desc.contentDOM, desc.children, view); + dom = pos ? pos.nextSibling : parentDOM.firstChild; + } + } + while (dom) { + dom = rm(dom); + written = true; + } + if (written && view.trackWrites == parentDOM) + view.trackWrites = null; +} +var OuterDecoLevel = function(nodeName) { + if (nodeName) + this.nodeName = nodeName; +}; +OuterDecoLevel.prototype = /* @__PURE__ */ Object.create(null); +var noDeco = [new OuterDecoLevel()]; +function computeOuterDeco(outerDeco, node, needsWrap) { + if (outerDeco.length == 0) + return noDeco; + let top = needsWrap ? noDeco[0] : new OuterDecoLevel(), result = [top]; + for (let i5 = 0; i5 < outerDeco.length; i5++) { + let attrs = outerDeco[i5].type.attrs; + if (!attrs) + continue; + if (attrs.nodeName) + result.push(top = new OuterDecoLevel(attrs.nodeName)); + for (let name in attrs) { + let val = attrs[name]; + if (val == null) + continue; + if (needsWrap && result.length == 1) + result.push(top = new OuterDecoLevel(node.isInline ? "span" : "div")); + if (name == "class") + top.class = (top.class ? top.class + " " : "") + val; + else if (name == "style") + top.style = (top.style ? top.style + ";" : "") + val; + else if (name != "nodeName") + top[name] = val; + } + } + return result; +} +function patchOuterDeco(outerDOM, nodeDOM, prevComputed, curComputed) { + if (prevComputed == noDeco && curComputed == noDeco) + return nodeDOM; + let curDOM = nodeDOM; + for (let i5 = 0; i5 < curComputed.length; i5++) { + let deco = curComputed[i5], prev = prevComputed[i5]; + if (i5) { + let parent; + if (prev && prev.nodeName == deco.nodeName && curDOM != outerDOM && (parent = curDOM.parentNode) && parent.nodeName.toLowerCase() == deco.nodeName) { + curDOM = parent; + } else { + parent = document.createElement(deco.nodeName); + parent.pmIsDeco = true; + parent.appendChild(curDOM); + prev = noDeco[0]; + curDOM = parent; + } + } + patchAttributes(curDOM, prev || noDeco[0], deco); + } + return curDOM; +} +function patchAttributes(dom, prev, cur) { + for (let name in prev) + if (name != "class" && name != "style" && name != "nodeName" && !(name in cur)) + dom.removeAttribute(name); + for (let name in cur) + if (name != "class" && name != "style" && name != "nodeName" && cur[name] != prev[name]) + dom.setAttribute(name, cur[name]); + if (prev.class != cur.class) { + let prevList = prev.class ? prev.class.split(" ").filter(Boolean) : []; + let curList = cur.class ? cur.class.split(" ").filter(Boolean) : []; + for (let i5 = 0; i5 < prevList.length; i5++) + if (curList.indexOf(prevList[i5]) == -1) + dom.classList.remove(prevList[i5]); + for (let i5 = 0; i5 < curList.length; i5++) + if (prevList.indexOf(curList[i5]) == -1) + dom.classList.add(curList[i5]); + if (dom.classList.length == 0) + dom.removeAttribute("class"); + } + if (prev.style != cur.style) { + if (prev.style) { + let prop = /\s*([\w\-\xa1-\uffff]+)\s*:(?:"(?:\\.|[^"])*"|'(?:\\.|[^'])*'|\(.*?\)|[^;])*/g, m2; + while (m2 = prop.exec(prev.style)) + dom.style.removeProperty(m2[1]); + } + if (cur.style) + dom.style.cssText += cur.style; + } +} +function applyOuterDeco(dom, deco, node) { + return patchOuterDeco(dom, dom, noDeco, computeOuterDeco(deco, node, dom.nodeType != 1)); +} +function sameOuterDeco(a3, b3) { + if (a3.length != b3.length) + return false; + for (let i5 = 0; i5 < a3.length; i5++) + if (!a3[i5].type.eq(b3[i5].type)) + return false; + return true; +} +function rm(dom) { + let next = dom.nextSibling; + dom.parentNode.removeChild(dom); + return next; +} +var ViewTreeUpdater = class { + constructor(top, lock, view) { + this.lock = lock; + this.view = view; + this.index = 0; + this.stack = []; + this.changed = false; + this.top = top; + this.preMatch = preMatch(top.node.content, top); + } + // Destroy and remove the children between the given indices in + // `this.top`. + destroyBetween(start, end) { + if (start == end) + return; + for (let i5 = start; i5 < end; i5++) + this.top.children[i5].destroy(); + this.top.children.splice(start, end - start); + this.changed = true; + } + // Destroy all remaining children in `this.top`. + destroyRest() { + this.destroyBetween(this.index, this.top.children.length); + } + // Sync the current stack of mark descs with the given array of + // marks, reusing existing mark descs when possible. + syncToMarks(marks, inline, view) { + let keep = 0, depth = this.stack.length >> 1; + let maxKeep = Math.min(depth, marks.length); + while (keep < maxKeep && (keep == depth - 1 ? this.top : this.stack[keep + 1 << 1]).matchesMark(marks[keep]) && marks[keep].type.spec.spanning !== false) + keep++; + while (keep < depth) { + this.destroyRest(); + this.top.dirty = NOT_DIRTY; + this.index = this.stack.pop(); + this.top = this.stack.pop(); + depth--; + } + while (depth < marks.length) { + this.stack.push(this.top, this.index + 1); + let found2 = -1; + for (let i5 = this.index; i5 < Math.min(this.index + 3, this.top.children.length); i5++) { + let next = this.top.children[i5]; + if (next.matchesMark(marks[depth]) && !this.isLocked(next.dom)) { + found2 = i5; + break; + } + } + if (found2 > -1) { + if (found2 > this.index) { + this.changed = true; + this.destroyBetween(this.index, found2); + } + this.top = this.top.children[this.index]; + } else { + let markDesc = MarkViewDesc.create(this.top, marks[depth], inline, view); + this.top.children.splice(this.index, 0, markDesc); + this.top = markDesc; + this.changed = true; + } + this.index = 0; + depth++; + } + } + // Try to find a node desc matching the given data. Skip over it and + // return true when successful. + findNodeMatch(node, outerDeco, innerDeco, index) { + let found2 = -1, targetDesc; + if (index >= this.preMatch.index && (targetDesc = this.preMatch.matches[index - this.preMatch.index]).parent == this.top && targetDesc.matchesNode(node, outerDeco, innerDeco)) { + found2 = this.top.children.indexOf(targetDesc, this.index); + } else { + for (let i5 = this.index, e4 = Math.min(this.top.children.length, i5 + 5); i5 < e4; i5++) { + let child = this.top.children[i5]; + if (child.matchesNode(node, outerDeco, innerDeco) && !this.preMatch.matched.has(child)) { + found2 = i5; + break; + } + } + } + if (found2 < 0) + return false; + this.destroyBetween(this.index, found2); + this.index++; + return true; + } + updateNodeAt(node, outerDeco, innerDeco, index, view) { + let child = this.top.children[index]; + if (child.dirty == NODE_DIRTY && child.dom == child.contentDOM) + child.dirty = CONTENT_DIRTY; + if (!child.update(node, outerDeco, innerDeco, view)) + return false; + this.destroyBetween(this.index, index); + this.index++; + return true; + } + findIndexWithChild(domNode) { + for (; ; ) { + let parent = domNode.parentNode; + if (!parent) + return -1; + if (parent == this.top.contentDOM) { + let desc = domNode.pmViewDesc; + if (desc) + for (let i5 = this.index; i5 < this.top.children.length; i5++) { + if (this.top.children[i5] == desc) + return i5; + } + return -1; + } + domNode = parent; + } + } + // Try to update the next node, if any, to the given data. Checks + // pre-matches to avoid overwriting nodes that could still be used. + updateNextNode(node, outerDeco, innerDeco, view, index, pos) { + for (let i5 = this.index; i5 < this.top.children.length; i5++) { + let next = this.top.children[i5]; + if (next instanceof NodeViewDesc) { + let preMatch2 = this.preMatch.matched.get(next); + if (preMatch2 != null && preMatch2 != index) + return false; + let nextDOM = next.dom, updated; + let locked = this.isLocked(nextDOM) && !(node.isText && next.node && next.node.isText && next.nodeDOM.nodeValue == node.text && next.dirty != NODE_DIRTY && sameOuterDeco(outerDeco, next.outerDeco)); + if (!locked && next.update(node, outerDeco, innerDeco, view)) { + this.destroyBetween(this.index, i5); + if (next.dom != nextDOM) + this.changed = true; + this.index++; + return true; + } else if (!locked && (updated = this.recreateWrapper(next, node, outerDeco, innerDeco, view, pos))) { + this.destroyBetween(this.index, i5); + this.top.children[this.index] = updated; + if (updated.contentDOM) { + updated.dirty = CONTENT_DIRTY; + updated.updateChildren(view, pos + 1); + updated.dirty = NOT_DIRTY; + } + this.changed = true; + this.index++; + return true; + } + break; + } + } + return false; + } + // When a node with content is replaced by a different node with + // identical content, move over its children. + recreateWrapper(next, node, outerDeco, innerDeco, view, pos) { + if (next.dirty || node.isAtom || !next.children.length || !next.node.content.eq(node.content) || !sameOuterDeco(outerDeco, next.outerDeco) || !innerDeco.eq(next.innerDeco)) + return null; + let wrapper = NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos); + if (wrapper.contentDOM) { + wrapper.children = next.children; + next.children = []; + for (let ch of wrapper.children) + ch.parent = wrapper; + } + next.destroy(); + return wrapper; + } + // Insert the node as a newly created node desc. + addNode(node, outerDeco, innerDeco, view, pos) { + let desc = NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos); + if (desc.contentDOM) + desc.updateChildren(view, pos + 1); + this.top.children.splice(this.index++, 0, desc); + this.changed = true; + } + placeWidget(widget, view, pos) { + let next = this.index < this.top.children.length ? this.top.children[this.index] : null; + if (next && next.matchesWidget(widget) && (widget == next.widget || !next.widget.type.toDOM.parentNode)) { + this.index++; + } else { + let desc = new WidgetViewDesc(this.top, widget, view, pos); + this.top.children.splice(this.index++, 0, desc); + this.changed = true; + } + } + // Make sure a textblock looks and behaves correctly in + // contentEditable. + addTextblockHacks() { + let lastChild = this.top.children[this.index - 1], parent = this.top; + while (lastChild instanceof MarkViewDesc) { + parent = lastChild; + lastChild = parent.children[parent.children.length - 1]; + } + if (!lastChild || // Empty textblock + !(lastChild instanceof TextViewDesc) || /\n$/.test(lastChild.node.text) || this.view.requiresGeckoHackNode && /\s$/.test(lastChild.node.text)) { + if ((safari || chrome) && lastChild && lastChild.dom.contentEditable == "false") + this.addHackNode("IMG", parent); + this.addHackNode("BR", this.top); + } + } + addHackNode(nodeName, parent) { + if (parent == this.top && this.index < parent.children.length && parent.children[this.index].matchesHack(nodeName)) { + this.index++; + } else { + let dom = document.createElement(nodeName); + if (nodeName == "IMG") { + dom.className = "ProseMirror-separator"; + dom.alt = ""; + } + if (nodeName == "BR") + dom.className = "ProseMirror-trailingBreak"; + let hack = new TrailingHackViewDesc(this.top, [], dom, null); + if (parent != this.top) + parent.children.push(hack); + else + parent.children.splice(this.index++, 0, hack); + this.changed = true; + } + } + isLocked(node) { + return this.lock && (node == this.lock || node.nodeType == 1 && node.contains(this.lock.parentNode)); + } +}; +function preMatch(frag, parentDesc) { + let curDesc = parentDesc, descI = curDesc.children.length; + let fI = frag.childCount, matched = /* @__PURE__ */ new Map(), matches2 = []; + outer: while (fI > 0) { + let desc; + for (; ; ) { + if (descI) { + let next = curDesc.children[descI - 1]; + if (next instanceof MarkViewDesc) { + curDesc = next; + descI = next.children.length; + } else { + desc = next; + descI--; + break; + } + } else if (curDesc == parentDesc) { + break outer; + } else { + descI = curDesc.parent.children.indexOf(curDesc); + curDesc = curDesc.parent; + } + } + let node = desc.node; + if (!node) + continue; + if (node != frag.child(fI - 1)) + break; + --fI; + matched.set(desc, fI); + matches2.push(desc); + } + return { index: fI, matched, matches: matches2.reverse() }; +} +function compareSide(a3, b3) { + return a3.type.side - b3.type.side; +} +function iterDeco(parent, deco, onWidget, onNode) { + let locals = deco.locals(parent), offset = 0; + if (locals.length == 0) { + for (let i5 = 0; i5 < parent.childCount; i5++) { + let child = parent.child(i5); + onNode(child, locals, deco.forChild(offset, child), i5); + offset += child.nodeSize; + } + return; + } + let decoIndex = 0, active = [], restNode = null; + for (let parentIndex = 0; ; ) { + let widget, widgets; + while (decoIndex < locals.length && locals[decoIndex].to == offset) { + let next = locals[decoIndex++]; + if (next.widget) { + if (!widget) + widget = next; + else + (widgets || (widgets = [widget])).push(next); + } + } + if (widget) { + if (widgets) { + widgets.sort(compareSide); + for (let i5 = 0; i5 < widgets.length; i5++) + onWidget(widgets[i5], parentIndex, !!restNode); + } else { + onWidget(widget, parentIndex, !!restNode); + } + } + let child, index; + if (restNode) { + index = -1; + child = restNode; + restNode = null; + } else if (parentIndex < parent.childCount) { + index = parentIndex; + child = parent.child(parentIndex++); + } else { + break; + } + for (let i5 = 0; i5 < active.length; i5++) + if (active[i5].to <= offset) + active.splice(i5--, 1); + while (decoIndex < locals.length && locals[decoIndex].from <= offset && locals[decoIndex].to > offset) + active.push(locals[decoIndex++]); + let end = offset + child.nodeSize; + if (child.isText) { + let cutAt = end; + if (decoIndex < locals.length && locals[decoIndex].from < cutAt) + cutAt = locals[decoIndex].from; + for (let i5 = 0; i5 < active.length; i5++) + if (active[i5].to < cutAt) + cutAt = active[i5].to; + if (cutAt < end) { + restNode = child.cut(cutAt - offset); + child = child.cut(0, cutAt - offset); + end = cutAt; + index = -1; + } + } else { + while (decoIndex < locals.length && locals[decoIndex].to < end) + decoIndex++; + } + let outerDeco = child.isInline && !child.isLeaf ? active.filter((d3) => !d3.inline) : active.slice(); + onNode(child, outerDeco, deco.forChild(offset, child), index); + offset = end; + } +} +function iosHacks(dom) { + if (dom.nodeName == "UL" || dom.nodeName == "OL") { + let oldCSS = dom.style.cssText; + dom.style.cssText = oldCSS + "; list-style: square !important"; + window.getComputedStyle(dom).listStyle; + dom.style.cssText = oldCSS; + } +} +function findTextInFragment(frag, text, from, to) { + for (let i5 = 0, pos = 0; i5 < frag.childCount && pos <= to; ) { + let child = frag.child(i5++), childStart = pos; + pos += child.nodeSize; + if (!child.isText) + continue; + let str = child.text; + while (i5 < frag.childCount) { + let next = frag.child(i5++); + pos += next.nodeSize; + if (!next.isText) + break; + str += next.text; + } + if (pos >= from) { + if (pos >= to && str.slice(to - text.length - childStart, to - childStart) == text) + return to - text.length; + let found2 = childStart < to ? str.lastIndexOf(text, to - childStart - 1) : -1; + if (found2 >= 0 && found2 + text.length + childStart >= from) + return childStart + found2; + if (from == to && str.length >= to + text.length - childStart && str.slice(to - childStart, to - childStart + text.length) == text) + return to; + } + } + return -1; +} +function replaceNodes(nodes, from, to, view, replacement) { + let result = []; + for (let i5 = 0, off = 0; i5 < nodes.length; i5++) { + let child = nodes[i5], start = off, end = off += child.size; + if (start >= to || end <= from) { + result.push(child); + } else { + if (start < from) + result.push(child.slice(0, from - start, view)); + if (replacement) { + result.push(replacement); + replacement = void 0; + } + if (end > to) + result.push(child.slice(to - start, child.size, view)); + } + } + return result; +} +function selectionFromDOM(view, origin = null) { + let domSel = view.domSelectionRange(), doc3 = view.state.doc; + if (!domSel.focusNode) + return null; + let nearestDesc = view.docView.nearestDesc(domSel.focusNode), inWidget = nearestDesc && nearestDesc.size == 0; + let head = view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset, 1); + if (head < 0) + return null; + let $head = doc3.resolve(head), anchor, selection; + if (selectionCollapsed(domSel)) { + anchor = head; + while (nearestDesc && !nearestDesc.node) + nearestDesc = nearestDesc.parent; + let nearestDescNode = nearestDesc.node; + if (nearestDesc && nearestDescNode.isAtom && NodeSelection.isSelectable(nearestDescNode) && nearestDesc.parent && !(nearestDescNode.isInline && isOnEdge(domSel.focusNode, domSel.focusOffset, nearestDesc.dom))) { + let pos = nearestDesc.posBefore; + selection = new NodeSelection(head == pos ? $head : doc3.resolve(pos)); + } + } else { + if (domSel instanceof view.dom.ownerDocument.defaultView.Selection && domSel.rangeCount > 1) { + let min = head, max = head; + for (let i5 = 0; i5 < domSel.rangeCount; i5++) { + let range = domSel.getRangeAt(i5); + min = Math.min(min, view.docView.posFromDOM(range.startContainer, range.startOffset, 1)); + max = Math.max(max, view.docView.posFromDOM(range.endContainer, range.endOffset, -1)); + } + if (min < 0) + return null; + [anchor, head] = max == view.state.selection.anchor ? [max, min] : [min, max]; + $head = doc3.resolve(head); + } else { + anchor = view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset, 1); + } + if (anchor < 0) + return null; + } + let $anchor = doc3.resolve(anchor); + if (!selection) { + let bias = origin == "pointer" || view.state.selection.head < $head.pos && !inWidget ? 1 : -1; + selection = selectionBetween(view, $anchor, $head, bias); + } + return selection; +} +function editorOwnsSelection(view) { + return view.editable ? view.hasFocus() : hasSelection(view) && document.activeElement && document.activeElement.contains(view.dom); +} +function selectionToDOM(view, force = false) { + let sel = view.state.selection; + syncNodeSelection(view, sel); + if (!editorOwnsSelection(view)) + return; + if (!force && view.input.mouseDown && view.input.mouseDown.allowDefault && chrome) { + let domSel = view.domSelectionRange(), curSel = view.domObserver.currentSelection; + if (domSel.anchorNode && curSel.anchorNode && isEquivalentPosition(domSel.anchorNode, domSel.anchorOffset, curSel.anchorNode, curSel.anchorOffset)) { + view.input.mouseDown.delayedSelectionSync = true; + view.domObserver.setCurSelection(); + return; + } + } + view.domObserver.disconnectSelection(); + if (view.cursorWrapper) { + selectCursorWrapper(view); + } else { + let { anchor, head } = sel, resetEditableFrom, resetEditableTo; + if (brokenSelectBetweenUneditable && !(sel instanceof TextSelection)) { + if (!sel.$from.parent.inlineContent) + resetEditableFrom = temporarilyEditableNear(view, sel.from); + if (!sel.empty && !sel.$from.parent.inlineContent) + resetEditableTo = temporarilyEditableNear(view, sel.to); + } + view.docView.setSelection(anchor, head, view, force); + if (brokenSelectBetweenUneditable) { + if (resetEditableFrom) + resetEditable(resetEditableFrom); + if (resetEditableTo) + resetEditable(resetEditableTo); + } + if (sel.visible) { + view.dom.classList.remove("ProseMirror-hideselection"); + } else { + view.dom.classList.add("ProseMirror-hideselection"); + if ("onselectionchange" in document) + removeClassOnSelectionChange(view); + } + } + view.domObserver.setCurSelection(); + view.domObserver.connectSelection(); +} +var brokenSelectBetweenUneditable = safari || chrome && chrome_version < 63; +function temporarilyEditableNear(view, pos) { + let { node, offset } = view.docView.domFromPos(pos, 0); + let after = offset < node.childNodes.length ? node.childNodes[offset] : null; + let before = offset ? node.childNodes[offset - 1] : null; + if (safari && after && after.contentEditable == "false") + return setEditable(after); + if ((!after || after.contentEditable == "false") && (!before || before.contentEditable == "false")) { + if (after) + return setEditable(after); + else if (before) + return setEditable(before); + } +} +function setEditable(element) { + element.contentEditable = "true"; + if (safari && element.draggable) { + element.draggable = false; + element.wasDraggable = true; + } + return element; +} +function resetEditable(element) { + element.contentEditable = "false"; + if (element.wasDraggable) { + element.draggable = true; + element.wasDraggable = null; + } +} +function removeClassOnSelectionChange(view) { + let doc3 = view.dom.ownerDocument; + doc3.removeEventListener("selectionchange", view.input.hideSelectionGuard); + let domSel = view.domSelectionRange(); + let node = domSel.anchorNode, offset = domSel.anchorOffset; + doc3.addEventListener("selectionchange", view.input.hideSelectionGuard = () => { + if (domSel.anchorNode != node || domSel.anchorOffset != offset) { + doc3.removeEventListener("selectionchange", view.input.hideSelectionGuard); + setTimeout(() => { + if (!editorOwnsSelection(view) || view.state.selection.visible) + view.dom.classList.remove("ProseMirror-hideselection"); + }, 20); + } + }); +} +function selectCursorWrapper(view) { + let domSel = view.domSelection(), range = document.createRange(); + if (!domSel) + return; + let node = view.cursorWrapper.dom, img = node.nodeName == "IMG"; + if (img) + range.setStart(node.parentNode, domIndex(node) + 1); + else + range.setStart(node, 0); + range.collapse(true); + domSel.removeAllRanges(); + domSel.addRange(range); + if (!img && !view.state.selection.visible && ie && ie_version <= 11) { + node.disabled = true; + node.disabled = false; + } +} +function syncNodeSelection(view, sel) { + if (sel instanceof NodeSelection) { + let desc = view.docView.descAt(sel.from); + if (desc != view.lastSelectedViewDesc) { + clearNodeSelection(view); + if (desc) + desc.selectNode(); + view.lastSelectedViewDesc = desc; + } + } else { + clearNodeSelection(view); + } +} +function clearNodeSelection(view) { + if (view.lastSelectedViewDesc) { + if (view.lastSelectedViewDesc.parent) + view.lastSelectedViewDesc.deselectNode(); + view.lastSelectedViewDesc = void 0; + } +} +function selectionBetween(view, $anchor, $head, bias) { + return view.someProp("createSelectionBetween", (f3) => f3(view, $anchor, $head)) || TextSelection.between($anchor, $head, bias); +} +function hasFocusAndSelection(view) { + if (view.editable && !view.hasFocus()) + return false; + return hasSelection(view); +} +function hasSelection(view) { + let sel = view.domSelectionRange(); + if (!sel.anchorNode) + return false; + try { + return view.dom.contains(sel.anchorNode.nodeType == 3 ? sel.anchorNode.parentNode : sel.anchorNode) && (view.editable || view.dom.contains(sel.focusNode.nodeType == 3 ? sel.focusNode.parentNode : sel.focusNode)); + } catch (_2) { + return false; + } +} +function anchorInRightPlace(view) { + let anchorDOM = view.docView.domFromPos(view.state.selection.anchor, 0); + let domSel = view.domSelectionRange(); + return isEquivalentPosition(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset); +} +function moveSelectionBlock(state, dir) { + let { $anchor, $head } = state.selection; + let $side = dir > 0 ? $anchor.max($head) : $anchor.min($head); + let $start = !$side.parent.inlineContent ? $side : $side.depth ? state.doc.resolve(dir > 0 ? $side.after() : $side.before()) : null; + return $start && Selection.findFrom($start, dir); +} +function apply(view, sel) { + view.dispatch(view.state.tr.setSelection(sel).scrollIntoView()); + return true; +} +function selectHorizontally(view, dir, mods) { + let sel = view.state.selection; + if (sel instanceof TextSelection) { + if (mods.indexOf("s") > -1) { + let { $head } = sel, node = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter; + if (!node || node.isText || !node.isLeaf) + return false; + let $newHead = view.state.doc.resolve($head.pos + node.nodeSize * (dir < 0 ? -1 : 1)); + return apply(view, new TextSelection(sel.$anchor, $newHead)); + } else if (!sel.empty) { + return false; + } else if (view.endOfTextblock(dir > 0 ? "forward" : "backward")) { + let next = moveSelectionBlock(view.state, dir); + if (next && next instanceof NodeSelection) + return apply(view, next); + return false; + } else if (!(mac && mods.indexOf("m") > -1)) { + let $head = sel.$head, node = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter, desc; + if (!node || node.isText) + return false; + let nodePos = dir < 0 ? $head.pos - node.nodeSize : $head.pos; + if (!(node.isAtom || (desc = view.docView.descAt(nodePos)) && !desc.contentDOM)) + return false; + if (NodeSelection.isSelectable(node)) { + return apply(view, new NodeSelection(dir < 0 ? view.state.doc.resolve($head.pos - node.nodeSize) : $head)); + } else if (webkit) { + return apply(view, new TextSelection(view.state.doc.resolve(dir < 0 ? nodePos : nodePos + node.nodeSize))); + } else { + return false; + } + } + } else if (sel instanceof NodeSelection && sel.node.isInline) { + return apply(view, new TextSelection(dir > 0 ? sel.$to : sel.$from)); + } else { + let next = moveSelectionBlock(view.state, dir); + if (next) + return apply(view, next); + return false; + } +} +function nodeLen(node) { + return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length; +} +function isIgnorable(dom, dir) { + let desc = dom.pmViewDesc; + return desc && desc.size == 0 && (dir < 0 || dom.nextSibling || dom.nodeName != "BR"); +} +function skipIgnoredNodes(view, dir) { + return dir < 0 ? skipIgnoredNodesBefore(view) : skipIgnoredNodesAfter(view); +} +function skipIgnoredNodesBefore(view) { + let sel = view.domSelectionRange(); + let node = sel.focusNode, offset = sel.focusOffset; + if (!node) + return; + let moveNode, moveOffset, force = false; + if (gecko && node.nodeType == 1 && offset < nodeLen(node) && isIgnorable(node.childNodes[offset], -1)) + force = true; + for (; ; ) { + if (offset > 0) { + if (node.nodeType != 1) { + break; + } else { + let before = node.childNodes[offset - 1]; + if (isIgnorable(before, -1)) { + moveNode = node; + moveOffset = --offset; + } else if (before.nodeType == 3) { + node = before; + offset = node.nodeValue.length; + } else + break; + } + } else if (isBlockNode(node)) { + break; + } else { + let prev = node.previousSibling; + while (prev && isIgnorable(prev, -1)) { + moveNode = node.parentNode; + moveOffset = domIndex(prev); + prev = prev.previousSibling; + } + if (!prev) { + node = node.parentNode; + if (node == view.dom) + break; + offset = 0; + } else { + node = prev; + offset = nodeLen(node); + } + } + } + if (force) + setSelFocus(view, node, offset); + else if (moveNode) + setSelFocus(view, moveNode, moveOffset); +} +function skipIgnoredNodesAfter(view) { + let sel = view.domSelectionRange(); + let node = sel.focusNode, offset = sel.focusOffset; + if (!node) + return; + let len = nodeLen(node); + let moveNode, moveOffset; + for (; ; ) { + if (offset < len) { + if (node.nodeType != 1) + break; + let after = node.childNodes[offset]; + if (isIgnorable(after, 1)) { + moveNode = node; + moveOffset = ++offset; + } else + break; + } else if (isBlockNode(node)) { + break; + } else { + let next = node.nextSibling; + while (next && isIgnorable(next, 1)) { + moveNode = next.parentNode; + moveOffset = domIndex(next) + 1; + next = next.nextSibling; + } + if (!next) { + node = node.parentNode; + if (node == view.dom) + break; + offset = len = 0; + } else { + node = next; + offset = 0; + len = nodeLen(node); + } + } + } + if (moveNode) + setSelFocus(view, moveNode, moveOffset); +} +function isBlockNode(dom) { + let desc = dom.pmViewDesc; + return desc && desc.node && desc.node.isBlock; +} +function textNodeAfter(node, offset) { + while (node && offset == node.childNodes.length && !hasBlockDesc(node)) { + offset = domIndex(node) + 1; + node = node.parentNode; + } + while (node && offset < node.childNodes.length) { + let next = node.childNodes[offset]; + if (next.nodeType == 3) + return next; + if (next.nodeType == 1 && next.contentEditable == "false") + break; + node = next; + offset = 0; + } +} +function textNodeBefore(node, offset) { + while (node && !offset && !hasBlockDesc(node)) { + offset = domIndex(node); + node = node.parentNode; + } + while (node && offset) { + let next = node.childNodes[offset - 1]; + if (next.nodeType == 3) + return next; + if (next.nodeType == 1 && next.contentEditable == "false") + break; + node = next; + offset = node.childNodes.length; + } +} +function setSelFocus(view, node, offset) { + if (node.nodeType != 3) { + let before, after; + if (after = textNodeAfter(node, offset)) { + node = after; + offset = 0; + } else if (before = textNodeBefore(node, offset)) { + node = before; + offset = before.nodeValue.length; + } + } + let sel = view.domSelection(); + if (!sel) + return; + if (selectionCollapsed(sel)) { + let range = document.createRange(); + range.setEnd(node, offset); + range.setStart(node, offset); + sel.removeAllRanges(); + sel.addRange(range); + } else if (sel.extend) { + sel.extend(node, offset); + } + view.domObserver.setCurSelection(); + let { state } = view; + setTimeout(() => { + if (view.state == state) + selectionToDOM(view); + }, 50); +} +function findDirection(view, pos) { + let $pos = view.state.doc.resolve(pos); + if (!(chrome || windows) && $pos.parent.inlineContent) { + let coords = view.coordsAtPos(pos); + if (pos > $pos.start()) { + let before = view.coordsAtPos(pos - 1); + let mid = (before.top + before.bottom) / 2; + if (mid > coords.top && mid < coords.bottom && Math.abs(before.left - coords.left) > 1) + return before.left < coords.left ? "ltr" : "rtl"; + } + if (pos < $pos.end()) { + let after = view.coordsAtPos(pos + 1); + let mid = (after.top + after.bottom) / 2; + if (mid > coords.top && mid < coords.bottom && Math.abs(after.left - coords.left) > 1) + return after.left > coords.left ? "ltr" : "rtl"; + } + } + let computed = getComputedStyle(view.dom).direction; + return computed == "rtl" ? "rtl" : "ltr"; +} +function selectVertically(view, dir, mods) { + let sel = view.state.selection; + if (sel instanceof TextSelection && !sel.empty || mods.indexOf("s") > -1) + return false; + if (mac && mods.indexOf("m") > -1) + return false; + let { $from, $to } = sel; + if (!$from.parent.inlineContent || view.endOfTextblock(dir < 0 ? "up" : "down")) { + let next = moveSelectionBlock(view.state, dir); + if (next && next instanceof NodeSelection) + return apply(view, next); + } + if (!$from.parent.inlineContent) { + let side = dir < 0 ? $from : $to; + let beyond = sel instanceof AllSelection ? Selection.near(side, dir) : Selection.findFrom(side, dir); + return beyond ? apply(view, beyond) : false; + } + return false; +} +function stopNativeHorizontalDelete(view, dir) { + if (!(view.state.selection instanceof TextSelection)) + return true; + let { $head, $anchor, empty: empty2 } = view.state.selection; + if (!$head.sameParent($anchor)) + return true; + if (!empty2) + return false; + if (view.endOfTextblock(dir > 0 ? "forward" : "backward")) + return true; + let nextNode = !$head.textOffset && (dir < 0 ? $head.nodeBefore : $head.nodeAfter); + if (nextNode && !nextNode.isText) { + let tr = view.state.tr; + if (dir < 0) + tr.delete($head.pos - nextNode.nodeSize, $head.pos); + else + tr.delete($head.pos, $head.pos + nextNode.nodeSize); + view.dispatch(tr); + return true; + } + return false; +} +function switchEditable(view, node, state) { + view.domObserver.stop(); + node.contentEditable = state; + view.domObserver.start(); +} +function safariDownArrowBug(view) { + if (!safari || view.state.selection.$head.parentOffset > 0) + return false; + let { focusNode, focusOffset } = view.domSelectionRange(); + if (focusNode && focusNode.nodeType == 1 && focusOffset == 0 && focusNode.firstChild && focusNode.firstChild.contentEditable == "false") { + let child = focusNode.firstChild; + switchEditable(view, child, "true"); + setTimeout(() => switchEditable(view, child, "false"), 20); + } + return false; +} +function getMods(event) { + let result = ""; + if (event.ctrlKey) + result += "c"; + if (event.metaKey) + result += "m"; + if (event.altKey) + result += "a"; + if (event.shiftKey) + result += "s"; + return result; +} +function captureKeyDown(view, event) { + let code = event.keyCode, mods = getMods(event); + if (code == 8 || mac && code == 72 && mods == "c") { + return stopNativeHorizontalDelete(view, -1) || skipIgnoredNodes(view, -1); + } else if (code == 46 && !event.shiftKey || mac && code == 68 && mods == "c") { + return stopNativeHorizontalDelete(view, 1) || skipIgnoredNodes(view, 1); + } else if (code == 13 || code == 27) { + return true; + } else if (code == 37 || mac && code == 66 && mods == "c") { + let dir = code == 37 ? findDirection(view, view.state.selection.from) == "ltr" ? -1 : 1 : -1; + return selectHorizontally(view, dir, mods) || skipIgnoredNodes(view, dir); + } else if (code == 39 || mac && code == 70 && mods == "c") { + let dir = code == 39 ? findDirection(view, view.state.selection.from) == "ltr" ? 1 : -1 : 1; + return selectHorizontally(view, dir, mods) || skipIgnoredNodes(view, dir); + } else if (code == 38 || mac && code == 80 && mods == "c") { + return selectVertically(view, -1, mods) || skipIgnoredNodes(view, -1); + } else if (code == 40 || mac && code == 78 && mods == "c") { + return safariDownArrowBug(view) || selectVertically(view, 1, mods) || skipIgnoredNodes(view, 1); + } else if (mods == (mac ? "m" : "c") && (code == 66 || code == 73 || code == 89 || code == 90)) { + return true; + } + return false; +} +function serializeForClipboard(view, slice) { + view.someProp("transformCopied", (f3) => { + slice = f3(slice, view); + }); + let context = [], { content, openStart, openEnd } = slice; + while (openStart > 1 && openEnd > 1 && content.childCount == 1 && content.firstChild.childCount == 1) { + openStart--; + openEnd--; + let node = content.firstChild; + context.push(node.type.name, node.attrs != node.type.defaultAttrs ? node.attrs : null); + content = node.content; + } + let serializer = view.someProp("clipboardSerializer") || DOMSerializer.fromSchema(view.state.schema); + let doc3 = detachedDoc(), wrap2 = doc3.createElement("div"); + wrap2.appendChild(serializer.serializeFragment(content, { document: doc3 })); + let firstChild = wrap2.firstChild, needsWrap, wrappers = 0; + while (firstChild && firstChild.nodeType == 1 && (needsWrap = wrapMap[firstChild.nodeName.toLowerCase()])) { + for (let i5 = needsWrap.length - 1; i5 >= 0; i5--) { + let wrapper = doc3.createElement(needsWrap[i5]); + while (wrap2.firstChild) + wrapper.appendChild(wrap2.firstChild); + wrap2.appendChild(wrapper); + wrappers++; + } + firstChild = wrap2.firstChild; + } + if (firstChild && firstChild.nodeType == 1) + firstChild.setAttribute("data-pm-slice", `${openStart} ${openEnd}${wrappers ? ` -${wrappers}` : ""} ${JSON.stringify(context)}`); + let text = view.someProp("clipboardTextSerializer", (f3) => f3(slice, view)) || slice.content.textBetween(0, slice.content.size, "\n\n"); + return { dom: wrap2, text, slice }; +} +function parseFromClipboard(view, text, html, plainText, $context) { + let inCode = $context.parent.type.spec.code; + let dom, slice; + if (!html && !text) + return null; + let asText = text && (plainText || inCode || !html); + if (asText) { + view.someProp("transformPastedText", (f3) => { + text = f3(text, inCode || plainText, view); + }); + if (inCode) + return text ? new Slice(Fragment.from(view.state.schema.text(text.replace(/\r\n?/g, "\n"))), 0, 0) : Slice.empty; + let parsed = view.someProp("clipboardTextParser", (f3) => f3(text, $context, plainText, view)); + if (parsed) { + slice = parsed; + } else { + let marks = $context.marks(); + let { schema } = view.state, serializer = DOMSerializer.fromSchema(schema); + dom = document.createElement("div"); + text.split(/(?:\r\n?|\n)+/).forEach((block) => { + let p3 = dom.appendChild(document.createElement("p")); + if (block) + p3.appendChild(serializer.serializeNode(schema.text(block, marks))); + }); + } + } else { + view.someProp("transformPastedHTML", (f3) => { + html = f3(html, view); + }); + dom = readHTML(html); + if (webkit) + restoreReplacedSpaces(dom); + } + let contextNode = dom && dom.querySelector("[data-pm-slice]"); + let sliceData = contextNode && /^(\d+) (\d+)(?: -(\d+))? (.*)/.exec(contextNode.getAttribute("data-pm-slice") || ""); + if (sliceData && sliceData[3]) + for (let i5 = +sliceData[3]; i5 > 0; i5--) { + let child = dom.firstChild; + while (child && child.nodeType != 1) + child = child.nextSibling; + if (!child) + break; + dom = child; + } + if (!slice) { + let parser = view.someProp("clipboardParser") || view.someProp("domParser") || DOMParser.fromSchema(view.state.schema); + slice = parser.parseSlice(dom, { + preserveWhitespace: !!(asText || sliceData), + context: $context, + ruleFromNode(dom2) { + if (dom2.nodeName == "BR" && !dom2.nextSibling && dom2.parentNode && !inlineParents.test(dom2.parentNode.nodeName)) + return { ignore: true }; + return null; + } + }); + } + if (sliceData) { + slice = addContext(closeSlice(slice, +sliceData[1], +sliceData[2]), sliceData[4]); + } else { + slice = Slice.maxOpen(normalizeSiblings(slice.content, $context), true); + if (slice.openStart || slice.openEnd) { + let openStart = 0, openEnd = 0; + for (let node = slice.content.firstChild; openStart < slice.openStart && !node.type.spec.isolating; openStart++, node = node.firstChild) { + } + for (let node = slice.content.lastChild; openEnd < slice.openEnd && !node.type.spec.isolating; openEnd++, node = node.lastChild) { + } + slice = closeSlice(slice, openStart, openEnd); + } + } + view.someProp("transformPasted", (f3) => { + slice = f3(slice, view); + }); + return slice; +} +var inlineParents = /^(a|abbr|acronym|b|cite|code|del|em|i|ins|kbd|label|output|q|ruby|s|samp|span|strong|sub|sup|time|u|tt|var)$/i; +function normalizeSiblings(fragment, $context) { + if (fragment.childCount < 2) + return fragment; + for (let d3 = $context.depth; d3 >= 0; d3--) { + let parent = $context.node(d3); + let match = parent.contentMatchAt($context.index(d3)); + let lastWrap, result = []; + fragment.forEach((node) => { + if (!result) + return; + let wrap2 = match.findWrapping(node.type), inLast; + if (!wrap2) + return result = null; + if (inLast = result.length && lastWrap.length && addToSibling(wrap2, lastWrap, node, result[result.length - 1], 0)) { + result[result.length - 1] = inLast; + } else { + if (result.length) + result[result.length - 1] = closeRight(result[result.length - 1], lastWrap.length); + let wrapped = withWrappers(node, wrap2); + result.push(wrapped); + match = match.matchType(wrapped.type); + lastWrap = wrap2; + } + }); + if (result) + return Fragment.from(result); + } + return fragment; +} +function withWrappers(node, wrap2, from = 0) { + for (let i5 = wrap2.length - 1; i5 >= from; i5--) + node = wrap2[i5].create(null, Fragment.from(node)); + return node; +} +function addToSibling(wrap2, lastWrap, node, sibling, depth) { + if (depth < wrap2.length && depth < lastWrap.length && wrap2[depth] == lastWrap[depth]) { + let inner = addToSibling(wrap2, lastWrap, node, sibling.lastChild, depth + 1); + if (inner) + return sibling.copy(sibling.content.replaceChild(sibling.childCount - 1, inner)); + let match = sibling.contentMatchAt(sibling.childCount); + if (match.matchType(depth == wrap2.length - 1 ? node.type : wrap2[depth + 1])) + return sibling.copy(sibling.content.append(Fragment.from(withWrappers(node, wrap2, depth + 1)))); + } +} +function closeRight(node, depth) { + if (depth == 0) + return node; + let fragment = node.content.replaceChild(node.childCount - 1, closeRight(node.lastChild, depth - 1)); + let fill = node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true); + return node.copy(fragment.append(fill)); +} +function closeRange(fragment, side, from, to, depth, openEnd) { + let node = side < 0 ? fragment.firstChild : fragment.lastChild, inner = node.content; + if (fragment.childCount > 1) + openEnd = 0; + if (depth < to - 1) + inner = closeRange(inner, side, from, to, depth + 1, openEnd); + if (depth >= from) + inner = side < 0 ? node.contentMatchAt(0).fillBefore(inner, openEnd <= depth).append(inner) : inner.append(node.contentMatchAt(node.childCount).fillBefore(Fragment.empty, true)); + return fragment.replaceChild(side < 0 ? 0 : fragment.childCount - 1, node.copy(inner)); +} +function closeSlice(slice, openStart, openEnd) { + if (openStart < slice.openStart) + slice = new Slice(closeRange(slice.content, -1, openStart, slice.openStart, 0, slice.openEnd), openStart, slice.openEnd); + if (openEnd < slice.openEnd) + slice = new Slice(closeRange(slice.content, 1, openEnd, slice.openEnd, 0, 0), slice.openStart, openEnd); + return slice; +} +var wrapMap = { + thead: ["table"], + tbody: ["table"], + tfoot: ["table"], + caption: ["table"], + colgroup: ["table"], + col: ["table", "colgroup"], + tr: ["table", "tbody"], + td: ["table", "tbody", "tr"], + th: ["table", "tbody", "tr"] +}; +var _detachedDoc = null; +function detachedDoc() { + return _detachedDoc || (_detachedDoc = document.implementation.createHTMLDocument("title")); +} +var _policy = null; +function maybeWrapTrusted(html) { + let trustedTypes = window.trustedTypes; + if (!trustedTypes) + return html; + if (!_policy) + _policy = trustedTypes.defaultPolicy || trustedTypes.createPolicy("ProseMirrorClipboard", { createHTML: (s4) => s4 }); + return _policy.createHTML(html); +} +function readHTML(html) { + let metas = /^(\s*]*>)*/.exec(html); + if (metas) + html = html.slice(metas[0].length); + let elt = detachedDoc().createElement("div"); + let firstTag = /<([a-z][^>\s]+)/i.exec(html), wrap2; + if (wrap2 = firstTag && wrapMap[firstTag[1].toLowerCase()]) + html = wrap2.map((n4) => "<" + n4 + ">").join("") + html + wrap2.map((n4) => "").reverse().join(""); + elt.innerHTML = maybeWrapTrusted(html); + if (wrap2) + for (let i5 = 0; i5 < wrap2.length; i5++) + elt = elt.querySelector(wrap2[i5]) || elt; + return elt; +} +function restoreReplacedSpaces(dom) { + let nodes = dom.querySelectorAll(chrome ? "span:not([class]):not([style])" : "span.Apple-converted-space"); + for (let i5 = 0; i5 < nodes.length; i5++) { + let node = nodes[i5]; + if (node.childNodes.length == 1 && node.textContent == "\xA0" && node.parentNode) + node.parentNode.replaceChild(dom.ownerDocument.createTextNode(" "), node); + } +} +function addContext(slice, context) { + if (!slice.size) + return slice; + let schema = slice.content.firstChild.type.schema, array; + try { + array = JSON.parse(context); + } catch (e4) { + return slice; + } + let { content, openStart, openEnd } = slice; + for (let i5 = array.length - 2; i5 >= 0; i5 -= 2) { + let type = schema.nodes[array[i5]]; + if (!type || type.hasRequiredAttrs()) + break; + content = Fragment.from(type.create(array[i5 + 1], content)); + openStart++; + openEnd++; + } + return new Slice(content, openStart, openEnd); +} +var handlers = {}; +var editHandlers = {}; +var passiveHandlers = { touchstart: true, touchmove: true }; +var InputState = class { + constructor() { + this.shiftKey = false; + this.mouseDown = null; + this.lastKeyCode = null; + this.lastKeyCodeTime = 0; + this.lastClick = { time: 0, x: 0, y: 0, type: "", button: 0 }; + this.lastSelectionOrigin = null; + this.lastSelectionTime = 0; + this.lastIOSEnter = 0; + this.lastIOSEnterFallbackTimeout = -1; + this.lastFocus = 0; + this.lastTouch = 0; + this.lastChromeDelete = 0; + this.composing = false; + this.compositionNode = null; + this.composingTimeout = -1; + this.compositionNodes = []; + this.compositionEndedAt = -2e8; + this.compositionID = 1; + this.compositionPendingChanges = 0; + this.domChangeCount = 0; + this.eventHandlers = /* @__PURE__ */ Object.create(null); + this.hideSelectionGuard = null; + } +}; +function initInput(view) { + for (let event in handlers) { + let handler = handlers[event]; + view.dom.addEventListener(event, view.input.eventHandlers[event] = (event2) => { + if (eventBelongsToView(view, event2) && !runCustomHandler(view, event2) && (view.editable || !(event2.type in editHandlers))) + handler(view, event2); + }, passiveHandlers[event] ? { passive: true } : void 0); + } + if (safari) + view.dom.addEventListener("input", () => null); + ensureListeners(view); +} +function setSelectionOrigin(view, origin) { + view.input.lastSelectionOrigin = origin; + view.input.lastSelectionTime = Date.now(); +} +function destroyInput(view) { + view.domObserver.stop(); + for (let type in view.input.eventHandlers) + view.dom.removeEventListener(type, view.input.eventHandlers[type]); + clearTimeout(view.input.composingTimeout); + clearTimeout(view.input.lastIOSEnterFallbackTimeout); +} +function ensureListeners(view) { + view.someProp("handleDOMEvents", (currentHandlers) => { + for (let type in currentHandlers) + if (!view.input.eventHandlers[type]) + view.dom.addEventListener(type, view.input.eventHandlers[type] = (event) => runCustomHandler(view, event)); + }); +} +function runCustomHandler(view, event) { + return view.someProp("handleDOMEvents", (handlers2) => { + let handler = handlers2[event.type]; + return handler ? handler(view, event) || event.defaultPrevented : false; + }); +} +function eventBelongsToView(view, event) { + if (!event.bubbles) + return true; + if (event.defaultPrevented) + return false; + for (let node = event.target; node != view.dom; node = node.parentNode) + if (!node || node.nodeType == 11 || node.pmViewDesc && node.pmViewDesc.stopEvent(event)) + return false; + return true; +} +function dispatchEvent(view, event) { + if (!runCustomHandler(view, event) && handlers[event.type] && (view.editable || !(event.type in editHandlers))) + handlers[event.type](view, event); +} +editHandlers.keydown = (view, _event) => { + let event = _event; + view.input.shiftKey = event.keyCode == 16 || event.shiftKey; + if (inOrNearComposition(view, event)) + return; + view.input.lastKeyCode = event.keyCode; + view.input.lastKeyCodeTime = Date.now(); + if (android && chrome && event.keyCode == 13) + return; + if (event.keyCode != 229) + view.domObserver.forceFlush(); + if (ios && event.keyCode == 13 && !event.ctrlKey && !event.altKey && !event.metaKey) { + let now = Date.now(); + view.input.lastIOSEnter = now; + view.input.lastIOSEnterFallbackTimeout = setTimeout(() => { + if (view.input.lastIOSEnter == now) { + view.someProp("handleKeyDown", (f3) => f3(view, keyEvent(13, "Enter"))); + view.input.lastIOSEnter = 0; + } + }, 200); + } else if (view.someProp("handleKeyDown", (f3) => f3(view, event)) || captureKeyDown(view, event)) { + event.preventDefault(); + } else { + setSelectionOrigin(view, "key"); + } +}; +editHandlers.keyup = (view, event) => { + if (event.keyCode == 16) + view.input.shiftKey = false; +}; +editHandlers.keypress = (view, _event) => { + let event = _event; + if (inOrNearComposition(view, event) || !event.charCode || event.ctrlKey && !event.altKey || mac && event.metaKey) + return; + if (view.someProp("handleKeyPress", (f3) => f3(view, event))) { + event.preventDefault(); + return; + } + let sel = view.state.selection; + if (!(sel instanceof TextSelection) || !sel.$from.sameParent(sel.$to)) { + let text = String.fromCharCode(event.charCode); + if (!/[\r\n]/.test(text) && !view.someProp("handleTextInput", (f3) => f3(view, sel.$from.pos, sel.$to.pos, text))) + view.dispatch(view.state.tr.insertText(text).scrollIntoView()); + event.preventDefault(); + } +}; +function eventCoords(event) { + return { left: event.clientX, top: event.clientY }; +} +function isNear(event, click) { + let dx = click.x - event.clientX, dy = click.y - event.clientY; + return dx * dx + dy * dy < 100; +} +function runHandlerOnContext(view, propName, pos, inside, event) { + if (inside == -1) + return false; + let $pos = view.state.doc.resolve(inside); + for (let i5 = $pos.depth + 1; i5 > 0; i5--) { + if (view.someProp(propName, (f3) => i5 > $pos.depth ? f3(view, pos, $pos.nodeAfter, $pos.before(i5), event, true) : f3(view, pos, $pos.node(i5), $pos.before(i5), event, false))) + return true; + } + return false; +} +function updateSelection(view, selection, origin) { + if (!view.focused) + view.focus(); + if (view.state.selection.eq(selection)) + return; + let tr = view.state.tr.setSelection(selection); + if (origin == "pointer") + tr.setMeta("pointer", true); + view.dispatch(tr); +} +function selectClickedLeaf(view, inside) { + if (inside == -1) + return false; + let $pos = view.state.doc.resolve(inside), node = $pos.nodeAfter; + if (node && node.isAtom && NodeSelection.isSelectable(node)) { + updateSelection(view, new NodeSelection($pos), "pointer"); + return true; + } + return false; +} +function selectClickedNode(view, inside) { + if (inside == -1) + return false; + let sel = view.state.selection, selectedNode, selectAt; + if (sel instanceof NodeSelection) + selectedNode = sel.node; + let $pos = view.state.doc.resolve(inside); + for (let i5 = $pos.depth + 1; i5 > 0; i5--) { + let node = i5 > $pos.depth ? $pos.nodeAfter : $pos.node(i5); + if (NodeSelection.isSelectable(node)) { + if (selectedNode && sel.$from.depth > 0 && i5 >= sel.$from.depth && $pos.before(sel.$from.depth + 1) == sel.$from.pos) + selectAt = $pos.before(sel.$from.depth); + else + selectAt = $pos.before(i5); + break; + } + } + if (selectAt != null) { + updateSelection(view, NodeSelection.create(view.state.doc, selectAt), "pointer"); + return true; + } else { + return false; + } +} +function handleSingleClick(view, pos, inside, event, selectNode) { + return runHandlerOnContext(view, "handleClickOn", pos, inside, event) || view.someProp("handleClick", (f3) => f3(view, pos, event)) || (selectNode ? selectClickedNode(view, inside) : selectClickedLeaf(view, inside)); +} +function handleDoubleClick(view, pos, inside, event) { + return runHandlerOnContext(view, "handleDoubleClickOn", pos, inside, event) || view.someProp("handleDoubleClick", (f3) => f3(view, pos, event)); +} +function handleTripleClick(view, pos, inside, event) { + return runHandlerOnContext(view, "handleTripleClickOn", pos, inside, event) || view.someProp("handleTripleClick", (f3) => f3(view, pos, event)) || defaultTripleClick(view, inside, event); +} +function defaultTripleClick(view, inside, event) { + if (event.button != 0) + return false; + let doc3 = view.state.doc; + if (inside == -1) { + if (doc3.inlineContent) { + updateSelection(view, TextSelection.create(doc3, 0, doc3.content.size), "pointer"); + return true; + } + return false; + } + let $pos = doc3.resolve(inside); + for (let i5 = $pos.depth + 1; i5 > 0; i5--) { + let node = i5 > $pos.depth ? $pos.nodeAfter : $pos.node(i5); + let nodePos = $pos.before(i5); + if (node.inlineContent) + updateSelection(view, TextSelection.create(doc3, nodePos + 1, nodePos + 1 + node.content.size), "pointer"); + else if (NodeSelection.isSelectable(node)) + updateSelection(view, NodeSelection.create(doc3, nodePos), "pointer"); + else + continue; + return true; + } +} +function forceDOMFlush(view) { + return endComposition(view); +} +var selectNodeModifier = mac ? "metaKey" : "ctrlKey"; +handlers.mousedown = (view, _event) => { + let event = _event; + view.input.shiftKey = event.shiftKey; + let flushed = forceDOMFlush(view); + let now = Date.now(), type = "singleClick"; + if (now - view.input.lastClick.time < 500 && isNear(event, view.input.lastClick) && !event[selectNodeModifier] && view.input.lastClick.button == event.button) { + if (view.input.lastClick.type == "singleClick") + type = "doubleClick"; + else if (view.input.lastClick.type == "doubleClick") + type = "tripleClick"; + } + view.input.lastClick = { time: now, x: event.clientX, y: event.clientY, type, button: event.button }; + let pos = view.posAtCoords(eventCoords(event)); + if (!pos) + return; + if (type == "singleClick") { + if (view.input.mouseDown) + view.input.mouseDown.done(); + view.input.mouseDown = new MouseDown(view, pos, event, !!flushed); + } else if ((type == "doubleClick" ? handleDoubleClick : handleTripleClick)(view, pos.pos, pos.inside, event)) { + event.preventDefault(); + } else { + setSelectionOrigin(view, "pointer"); + } +}; +var MouseDown = class { + constructor(view, pos, event, flushed) { + this.view = view; + this.pos = pos; + this.event = event; + this.flushed = flushed; + this.delayedSelectionSync = false; + this.mightDrag = null; + this.startDoc = view.state.doc; + this.selectNode = !!event[selectNodeModifier]; + this.allowDefault = event.shiftKey; + let targetNode, targetPos; + if (pos.inside > -1) { + targetNode = view.state.doc.nodeAt(pos.inside); + targetPos = pos.inside; + } else { + let $pos = view.state.doc.resolve(pos.pos); + targetNode = $pos.parent; + targetPos = $pos.depth ? $pos.before() : 0; + } + const target = flushed ? null : event.target; + const targetDesc = target ? view.docView.nearestDesc(target, true) : null; + this.target = targetDesc && targetDesc.dom.nodeType == 1 ? targetDesc.dom : null; + let { selection } = view.state; + if (event.button == 0 && targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false || selection instanceof NodeSelection && selection.from <= targetPos && selection.to > targetPos) + this.mightDrag = { + node: targetNode, + pos: targetPos, + addAttr: !!(this.target && !this.target.draggable), + setUneditable: !!(this.target && gecko && !this.target.hasAttribute("contentEditable")) + }; + if (this.target && this.mightDrag && (this.mightDrag.addAttr || this.mightDrag.setUneditable)) { + this.view.domObserver.stop(); + if (this.mightDrag.addAttr) + this.target.draggable = true; + if (this.mightDrag.setUneditable) + setTimeout(() => { + if (this.view.input.mouseDown == this) + this.target.setAttribute("contentEditable", "false"); + }, 20); + this.view.domObserver.start(); + } + view.root.addEventListener("mouseup", this.up = this.up.bind(this)); + view.root.addEventListener("mousemove", this.move = this.move.bind(this)); + setSelectionOrigin(view, "pointer"); + } + done() { + this.view.root.removeEventListener("mouseup", this.up); + this.view.root.removeEventListener("mousemove", this.move); + if (this.mightDrag && this.target) { + this.view.domObserver.stop(); + if (this.mightDrag.addAttr) + this.target.removeAttribute("draggable"); + if (this.mightDrag.setUneditable) + this.target.removeAttribute("contentEditable"); + this.view.domObserver.start(); + } + if (this.delayedSelectionSync) + setTimeout(() => selectionToDOM(this.view)); + this.view.input.mouseDown = null; + } + up(event) { + this.done(); + if (!this.view.dom.contains(event.target)) + return; + let pos = this.pos; + if (this.view.state.doc != this.startDoc) + pos = this.view.posAtCoords(eventCoords(event)); + this.updateAllowDefault(event); + if (this.allowDefault || !pos) { + setSelectionOrigin(this.view, "pointer"); + } else if (handleSingleClick(this.view, pos.pos, pos.inside, event, this.selectNode)) { + event.preventDefault(); + } else if (event.button == 0 && (this.flushed || // Safari ignores clicks on draggable elements + safari && this.mightDrag && !this.mightDrag.node.isAtom || // Chrome will sometimes treat a node selection as a + // cursor, but still report that the node is selected + // when asked through getSelection. You'll then get a + // situation where clicking at the point where that + // (hidden) cursor is doesn't change the selection, and + // thus doesn't get a reaction from ProseMirror. This + // works around that. + chrome && !this.view.state.selection.visible && Math.min(Math.abs(pos.pos - this.view.state.selection.from), Math.abs(pos.pos - this.view.state.selection.to)) <= 2)) { + updateSelection(this.view, Selection.near(this.view.state.doc.resolve(pos.pos)), "pointer"); + event.preventDefault(); + } else { + setSelectionOrigin(this.view, "pointer"); + } + } + move(event) { + this.updateAllowDefault(event); + setSelectionOrigin(this.view, "pointer"); + if (event.buttons == 0) + this.done(); + } + updateAllowDefault(event) { + if (!this.allowDefault && (Math.abs(this.event.x - event.clientX) > 4 || Math.abs(this.event.y - event.clientY) > 4)) + this.allowDefault = true; + } +}; +handlers.touchstart = (view) => { + view.input.lastTouch = Date.now(); + forceDOMFlush(view); + setSelectionOrigin(view, "pointer"); +}; +handlers.touchmove = (view) => { + view.input.lastTouch = Date.now(); + setSelectionOrigin(view, "pointer"); +}; +handlers.contextmenu = (view) => forceDOMFlush(view); +function inOrNearComposition(view, event) { + if (view.composing) + return true; + if (safari && Math.abs(event.timeStamp - view.input.compositionEndedAt) < 500) { + view.input.compositionEndedAt = -2e8; + return true; + } + return false; +} +var timeoutComposition = android ? 5e3 : -1; +editHandlers.compositionstart = editHandlers.compositionupdate = (view) => { + if (!view.composing) { + view.domObserver.flush(); + let { state } = view, $pos = state.selection.$to; + if (state.selection instanceof TextSelection && (state.storedMarks || !$pos.textOffset && $pos.parentOffset && $pos.nodeBefore.marks.some((m2) => m2.type.spec.inclusive === false))) { + view.markCursor = view.state.storedMarks || $pos.marks(); + endComposition(view, true); + view.markCursor = null; + } else { + endComposition(view, !state.selection.empty); + if (gecko && state.selection.empty && $pos.parentOffset && !$pos.textOffset && $pos.nodeBefore.marks.length) { + let sel = view.domSelectionRange(); + for (let node = sel.focusNode, offset = sel.focusOffset; node && node.nodeType == 1 && offset != 0; ) { + let before = offset < 0 ? node.lastChild : node.childNodes[offset - 1]; + if (!before) + break; + if (before.nodeType == 3) { + let sel2 = view.domSelection(); + if (sel2) + sel2.collapse(before, before.nodeValue.length); + break; + } else { + node = before; + offset = -1; + } + } + } + } + view.input.composing = true; + } + scheduleComposeEnd(view, timeoutComposition); +}; +editHandlers.compositionend = (view, event) => { + if (view.composing) { + view.input.composing = false; + view.input.compositionEndedAt = event.timeStamp; + view.input.compositionPendingChanges = view.domObserver.pendingRecords().length ? view.input.compositionID : 0; + view.input.compositionNode = null; + if (view.input.compositionPendingChanges) + Promise.resolve().then(() => view.domObserver.flush()); + view.input.compositionID++; + scheduleComposeEnd(view, 20); + } +}; +function scheduleComposeEnd(view, delay) { + clearTimeout(view.input.composingTimeout); + if (delay > -1) + view.input.composingTimeout = setTimeout(() => endComposition(view), delay); +} +function clearComposition(view) { + if (view.composing) { + view.input.composing = false; + view.input.compositionEndedAt = timestampFromCustomEvent(); + } + while (view.input.compositionNodes.length > 0) + view.input.compositionNodes.pop().markParentsDirty(); +} +function findCompositionNode(view) { + let sel = view.domSelectionRange(); + if (!sel.focusNode) + return null; + let textBefore = textNodeBefore$1(sel.focusNode, sel.focusOffset); + let textAfter = textNodeAfter$1(sel.focusNode, sel.focusOffset); + if (textBefore && textAfter && textBefore != textAfter) { + let descAfter = textAfter.pmViewDesc, lastChanged = view.domObserver.lastChangedTextNode; + if (textBefore == lastChanged || textAfter == lastChanged) + return lastChanged; + if (!descAfter || !descAfter.isText(textAfter.nodeValue)) { + return textAfter; + } else if (view.input.compositionNode == textAfter) { + let descBefore = textBefore.pmViewDesc; + if (!(!descBefore || !descBefore.isText(textBefore.nodeValue))) + return textAfter; + } + } + return textBefore || textAfter; +} +function timestampFromCustomEvent() { + let event = document.createEvent("Event"); + event.initEvent("event", true, true); + return event.timeStamp; +} +function endComposition(view, restarting = false) { + if (android && view.domObserver.flushingSoon >= 0) + return; + view.domObserver.forceFlush(); + clearComposition(view); + if (restarting || view.docView && view.docView.dirty) { + let sel = selectionFromDOM(view), cur = view.state.selection; + if (sel && !sel.eq(cur)) + view.dispatch(view.state.tr.setSelection(sel)); + else if ((view.markCursor || restarting) && !cur.$from.node(cur.$from.sharedDepth(cur.to)).inlineContent) + view.dispatch(view.state.tr.deleteSelection()); + else + view.updateState(view.state); + return true; + } + return false; +} +function captureCopy(view, dom) { + if (!view.dom.parentNode) + return; + let wrap2 = view.dom.parentNode.appendChild(document.createElement("div")); + wrap2.appendChild(dom); + wrap2.style.cssText = "position: fixed; left: -10000px; top: 10px"; + let sel = getSelection(), range = document.createRange(); + range.selectNodeContents(dom); + view.dom.blur(); + sel.removeAllRanges(); + sel.addRange(range); + setTimeout(() => { + if (wrap2.parentNode) + wrap2.parentNode.removeChild(wrap2); + view.focus(); + }, 50); +} +var brokenClipboardAPI = ie && ie_version < 15 || ios && webkit_version < 604; +handlers.copy = editHandlers.cut = (view, _event) => { + let event = _event; + let sel = view.state.selection, cut2 = event.type == "cut"; + if (sel.empty) + return; + let data = brokenClipboardAPI ? null : event.clipboardData; + let slice = sel.content(), { dom, text } = serializeForClipboard(view, slice); + if (data) { + event.preventDefault(); + data.clearData(); + data.setData("text/html", dom.innerHTML); + data.setData("text/plain", text); + } else { + captureCopy(view, dom); + } + if (cut2) + view.dispatch(view.state.tr.deleteSelection().scrollIntoView().setMeta("uiEvent", "cut")); +}; +function sliceSingleNode(slice) { + return slice.openStart == 0 && slice.openEnd == 0 && slice.content.childCount == 1 ? slice.content.firstChild : null; +} +function capturePaste(view, event) { + if (!view.dom.parentNode) + return; + let plainText = view.input.shiftKey || view.state.selection.$from.parent.type.spec.code; + let target = view.dom.parentNode.appendChild(document.createElement(plainText ? "textarea" : "div")); + if (!plainText) + target.contentEditable = "true"; + target.style.cssText = "position: fixed; left: -10000px; top: 10px"; + target.focus(); + let plain = view.input.shiftKey && view.input.lastKeyCode != 45; + setTimeout(() => { + view.focus(); + if (target.parentNode) + target.parentNode.removeChild(target); + if (plainText) + doPaste(view, target.value, null, plain, event); + else + doPaste(view, target.textContent, target.innerHTML, plain, event); + }, 50); +} +function doPaste(view, text, html, preferPlain, event) { + let slice = parseFromClipboard(view, text, html, preferPlain, view.state.selection.$from); + if (view.someProp("handlePaste", (f3) => f3(view, event, slice || Slice.empty))) + return true; + if (!slice) + return false; + let singleNode = sliceSingleNode(slice); + let tr = singleNode ? view.state.tr.replaceSelectionWith(singleNode, preferPlain) : view.state.tr.replaceSelection(slice); + view.dispatch(tr.scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste")); + return true; +} +function getText(clipboardData) { + let text = clipboardData.getData("text/plain") || clipboardData.getData("Text"); + if (text) + return text; + let uris = clipboardData.getData("text/uri-list"); + return uris ? uris.replace(/\r?\n/g, " ") : ""; +} +editHandlers.paste = (view, _event) => { + let event = _event; + if (view.composing && !android) + return; + let data = brokenClipboardAPI ? null : event.clipboardData; + let plain = view.input.shiftKey && view.input.lastKeyCode != 45; + if (data && doPaste(view, getText(data), data.getData("text/html"), plain, event)) + event.preventDefault(); + else + capturePaste(view, event); +}; +var Dragging = class { + constructor(slice, move, node) { + this.slice = slice; + this.move = move; + this.node = node; + } +}; +var dragCopyModifier = mac ? "altKey" : "ctrlKey"; +function dragMoves(view, event) { + let moves = view.someProp("dragCopies", (test) => !test(event)); + return moves != null ? moves : !event[dragCopyModifier]; +} +handlers.dragstart = (view, _event) => { + let event = _event; + let mouseDown = view.input.mouseDown; + if (mouseDown) + mouseDown.done(); + if (!event.dataTransfer) + return; + let sel = view.state.selection; + let pos = sel.empty ? null : view.posAtCoords(eventCoords(event)); + let node; + if (pos && pos.pos >= sel.from && pos.pos <= (sel instanceof NodeSelection ? sel.to - 1 : sel.to)) ; + else if (mouseDown && mouseDown.mightDrag) { + node = NodeSelection.create(view.state.doc, mouseDown.mightDrag.pos); + } else if (event.target && event.target.nodeType == 1) { + let desc = view.docView.nearestDesc(event.target, true); + if (desc && desc.node.type.spec.draggable && desc != view.docView) + node = NodeSelection.create(view.state.doc, desc.posBefore); + } + let draggedSlice = (node || view.state.selection).content(); + let { dom, text, slice } = serializeForClipboard(view, draggedSlice); + if (!event.dataTransfer.files.length || !chrome || chrome_version > 120) + event.dataTransfer.clearData(); + event.dataTransfer.setData(brokenClipboardAPI ? "Text" : "text/html", dom.innerHTML); + event.dataTransfer.effectAllowed = "copyMove"; + if (!brokenClipboardAPI) + event.dataTransfer.setData("text/plain", text); + view.dragging = new Dragging(slice, dragMoves(view, event), node); +}; +handlers.dragend = (view) => { + let dragging = view.dragging; + window.setTimeout(() => { + if (view.dragging == dragging) + view.dragging = null; + }, 50); +}; +editHandlers.dragover = editHandlers.dragenter = (_2, e4) => e4.preventDefault(); +editHandlers.drop = (view, _event) => { + let event = _event; + let dragging = view.dragging; + view.dragging = null; + if (!event.dataTransfer) + return; + let eventPos = view.posAtCoords(eventCoords(event)); + if (!eventPos) + return; + let $mouse = view.state.doc.resolve(eventPos.pos); + let slice = dragging && dragging.slice; + if (slice) { + view.someProp("transformPasted", (f3) => { + slice = f3(slice, view); + }); + } else { + slice = parseFromClipboard(view, getText(event.dataTransfer), brokenClipboardAPI ? null : event.dataTransfer.getData("text/html"), false, $mouse); + } + let move = !!(dragging && dragMoves(view, event)); + if (view.someProp("handleDrop", (f3) => f3(view, event, slice || Slice.empty, move))) { + event.preventDefault(); + return; + } + if (!slice) + return; + event.preventDefault(); + let insertPos = slice ? dropPoint(view.state.doc, $mouse.pos, slice) : $mouse.pos; + if (insertPos == null) + insertPos = $mouse.pos; + let tr = view.state.tr; + if (move) { + let { node } = dragging; + if (node) + node.replace(tr); + else + tr.deleteSelection(); + } + let pos = tr.mapping.map(insertPos); + let isNode = slice.openStart == 0 && slice.openEnd == 0 && slice.content.childCount == 1; + let beforeInsert = tr.doc; + if (isNode) + tr.replaceRangeWith(pos, pos, slice.content.firstChild); + else + tr.replaceRange(pos, pos, slice); + if (tr.doc.eq(beforeInsert)) + return; + let $pos = tr.doc.resolve(pos); + if (isNode && NodeSelection.isSelectable(slice.content.firstChild) && $pos.nodeAfter && $pos.nodeAfter.sameMarkup(slice.content.firstChild)) { + tr.setSelection(new NodeSelection($pos)); + } else { + let end = tr.mapping.map(insertPos); + tr.mapping.maps[tr.mapping.maps.length - 1].forEach((_from, _to, _newFrom, newTo) => end = newTo); + tr.setSelection(selectionBetween(view, $pos, tr.doc.resolve(end))); + } + view.focus(); + view.dispatch(tr.setMeta("uiEvent", "drop")); +}; +handlers.focus = (view) => { + view.input.lastFocus = Date.now(); + if (!view.focused) { + view.domObserver.stop(); + view.dom.classList.add("ProseMirror-focused"); + view.domObserver.start(); + view.focused = true; + setTimeout(() => { + if (view.docView && view.hasFocus() && !view.domObserver.currentSelection.eq(view.domSelectionRange())) + selectionToDOM(view); + }, 20); + } +}; +handlers.blur = (view, _event) => { + let event = _event; + if (view.focused) { + view.domObserver.stop(); + view.dom.classList.remove("ProseMirror-focused"); + view.domObserver.start(); + if (event.relatedTarget && view.dom.contains(event.relatedTarget)) + view.domObserver.currentSelection.clear(); + view.focused = false; + } +}; +handlers.beforeinput = (view, _event) => { + let event = _event; + if (chrome && android && event.inputType == "deleteContentBackward") { + view.domObserver.flushSoon(); + let { domChangeCount } = view.input; + setTimeout(() => { + if (view.input.domChangeCount != domChangeCount) + return; + view.dom.blur(); + view.focus(); + if (view.someProp("handleKeyDown", (f3) => f3(view, keyEvent(8, "Backspace")))) + return; + let { $cursor } = view.state.selection; + if ($cursor && $cursor.pos > 0) + view.dispatch(view.state.tr.delete($cursor.pos - 1, $cursor.pos).scrollIntoView()); + }, 50); + } +}; +for (let prop in editHandlers) + handlers[prop] = editHandlers[prop]; +function compareObjs(a3, b3) { + if (a3 == b3) + return true; + for (let p3 in a3) + if (a3[p3] !== b3[p3]) + return false; + for (let p3 in b3) + if (!(p3 in a3)) + return false; + return true; +} +var WidgetType = class _WidgetType { + constructor(toDOM, spec) { + this.toDOM = toDOM; + this.spec = spec || noSpec; + this.side = this.spec.side || 0; + } + map(mapping, span, offset, oldOffset) { + let { pos, deleted } = mapping.mapResult(span.from + oldOffset, this.side < 0 ? -1 : 1); + return deleted ? null : new Decoration(pos - offset, pos - offset, this); + } + valid() { + return true; + } + eq(other) { + return this == other || other instanceof _WidgetType && (this.spec.key && this.spec.key == other.spec.key || this.toDOM == other.toDOM && compareObjs(this.spec, other.spec)); + } + destroy(node) { + if (this.spec.destroy) + this.spec.destroy(node); + } +}; +var InlineType = class _InlineType { + constructor(attrs, spec) { + this.attrs = attrs; + this.spec = spec || noSpec; + } + map(mapping, span, offset, oldOffset) { + let from = mapping.map(span.from + oldOffset, this.spec.inclusiveStart ? -1 : 1) - offset; + let to = mapping.map(span.to + oldOffset, this.spec.inclusiveEnd ? 1 : -1) - offset; + return from >= to ? null : new Decoration(from, to, this); + } + valid(_2, span) { + return span.from < span.to; + } + eq(other) { + return this == other || other instanceof _InlineType && compareObjs(this.attrs, other.attrs) && compareObjs(this.spec, other.spec); + } + static is(span) { + return span.type instanceof _InlineType; + } + destroy() { + } +}; +var NodeType2 = class _NodeType { + constructor(attrs, spec) { + this.attrs = attrs; + this.spec = spec || noSpec; + } + map(mapping, span, offset, oldOffset) { + let from = mapping.mapResult(span.from + oldOffset, 1); + if (from.deleted) + return null; + let to = mapping.mapResult(span.to + oldOffset, -1); + if (to.deleted || to.pos <= from.pos) + return null; + return new Decoration(from.pos - offset, to.pos - offset, this); + } + valid(node, span) { + let { index, offset } = node.content.findIndex(span.from), child; + return offset == span.from && !(child = node.child(index)).isText && offset + child.nodeSize == span.to; + } + eq(other) { + return this == other || other instanceof _NodeType && compareObjs(this.attrs, other.attrs) && compareObjs(this.spec, other.spec); + } + destroy() { + } +}; +var Decoration = class _Decoration { + /** + @internal + */ + constructor(from, to, type) { + this.from = from; + this.to = to; + this.type = type; + } + /** + @internal + */ + copy(from, to) { + return new _Decoration(from, to, this.type); + } + /** + @internal + */ + eq(other, offset = 0) { + return this.type.eq(other.type) && this.from + offset == other.from && this.to + offset == other.to; + } + /** + @internal + */ + map(mapping, offset, oldOffset) { + return this.type.map(mapping, this, offset, oldOffset); + } + /** + Creates a widget decoration, which is a DOM node that's shown in + the document at the given position. It is recommended that you + delay rendering the widget by passing a function that will be + called when the widget is actually drawn in a view, but you can + also directly pass a DOM node. `getPos` can be used to find the + widget's current document position. + */ + static widget(pos, toDOM, spec) { + return new _Decoration(pos, pos, new WidgetType(toDOM, spec)); + } + /** + Creates an inline decoration, which adds the given attributes to + each inline node between `from` and `to`. + */ + static inline(from, to, attrs, spec) { + return new _Decoration(from, to, new InlineType(attrs, spec)); + } + /** + Creates a node decoration. `from` and `to` should point precisely + before and after a node in the document. That node, and only that + node, will receive the given attributes. + */ + static node(from, to, attrs, spec) { + return new _Decoration(from, to, new NodeType2(attrs, spec)); + } + /** + The spec provided when creating this decoration. Can be useful + if you've stored extra information in that object. + */ + get spec() { + return this.type.spec; + } + /** + @internal + */ + get inline() { + return this.type instanceof InlineType; + } + /** + @internal + */ + get widget() { + return this.type instanceof WidgetType; + } +}; +var none = []; +var noSpec = {}; +var DecorationSet = class _DecorationSet { + /** + @internal + */ + constructor(local, children) { + this.local = local.length ? local : none; + this.children = children.length ? children : none; + } + /** + Create a set of decorations, using the structure of the given + document. This will consume (modify) the `decorations` array, so + you must make a copy if you want need to preserve that. + */ + static create(doc3, decorations) { + return decorations.length ? buildTree(decorations, doc3, 0, noSpec) : empty; + } + /** + Find all decorations in this set which touch the given range + (including decorations that start or end directly at the + boundaries) and match the given predicate on their spec. When + `start` and `end` are omitted, all decorations in the set are + considered. When `predicate` isn't given, all decorations are + assumed to match. + */ + find(start, end, predicate) { + let result = []; + this.findInner(start == null ? 0 : start, end == null ? 1e9 : end, result, 0, predicate); + return result; + } + findInner(start, end, result, offset, predicate) { + for (let i5 = 0; i5 < this.local.length; i5++) { + let span = this.local[i5]; + if (span.from <= end && span.to >= start && (!predicate || predicate(span.spec))) + result.push(span.copy(span.from + offset, span.to + offset)); + } + for (let i5 = 0; i5 < this.children.length; i5 += 3) { + if (this.children[i5] < end && this.children[i5 + 1] > start) { + let childOff = this.children[i5] + 1; + this.children[i5 + 2].findInner(start - childOff, end - childOff, result, offset + childOff, predicate); + } + } + } + /** + Map the set of decorations in response to a change in the + document. + */ + map(mapping, doc3, options) { + if (this == empty || mapping.maps.length == 0) + return this; + return this.mapInner(mapping, doc3, 0, 0, options || noSpec); + } + /** + @internal + */ + mapInner(mapping, node, offset, oldOffset, options) { + let newLocal; + for (let i5 = 0; i5 < this.local.length; i5++) { + let mapped = this.local[i5].map(mapping, offset, oldOffset); + if (mapped && mapped.type.valid(node, mapped)) + (newLocal || (newLocal = [])).push(mapped); + else if (options.onRemove) + options.onRemove(this.local[i5].spec); + } + if (this.children.length) + return mapChildren(this.children, newLocal || [], mapping, node, offset, oldOffset, options); + else + return newLocal ? new _DecorationSet(newLocal.sort(byPos), none) : empty; + } + /** + Add the given array of decorations to the ones in the set, + producing a new set. Consumes the `decorations` array. Needs + access to the current document to create the appropriate tree + structure. + */ + add(doc3, decorations) { + if (!decorations.length) + return this; + if (this == empty) + return _DecorationSet.create(doc3, decorations); + return this.addInner(doc3, decorations, 0); + } + addInner(doc3, decorations, offset) { + let children, childIndex = 0; + doc3.forEach((childNode, childOffset) => { + let baseOffset = childOffset + offset, found2; + if (!(found2 = takeSpansForNode(decorations, childNode, baseOffset))) + return; + if (!children) + children = this.children.slice(); + while (childIndex < children.length && children[childIndex] < childOffset) + childIndex += 3; + if (children[childIndex] == childOffset) + children[childIndex + 2] = children[childIndex + 2].addInner(childNode, found2, baseOffset + 1); + else + children.splice(childIndex, 0, childOffset, childOffset + childNode.nodeSize, buildTree(found2, childNode, baseOffset + 1, noSpec)); + childIndex += 3; + }); + let local = moveSpans(childIndex ? withoutNulls(decorations) : decorations, -offset); + for (let i5 = 0; i5 < local.length; i5++) + if (!local[i5].type.valid(doc3, local[i5])) + local.splice(i5--, 1); + return new _DecorationSet(local.length ? this.local.concat(local).sort(byPos) : this.local, children || this.children); + } + /** + Create a new set that contains the decorations in this set, minus + the ones in the given array. + */ + remove(decorations) { + if (decorations.length == 0 || this == empty) + return this; + return this.removeInner(decorations, 0); + } + removeInner(decorations, offset) { + let children = this.children, local = this.local; + for (let i5 = 0; i5 < children.length; i5 += 3) { + let found2; + let from = children[i5] + offset, to = children[i5 + 1] + offset; + for (let j2 = 0, span; j2 < decorations.length; j2++) + if (span = decorations[j2]) { + if (span.from > from && span.to < to) { + decorations[j2] = null; + (found2 || (found2 = [])).push(span); + } + } + if (!found2) + continue; + if (children == this.children) + children = this.children.slice(); + let removed = children[i5 + 2].removeInner(found2, from + 1); + if (removed != empty) { + children[i5 + 2] = removed; + } else { + children.splice(i5, 3); + i5 -= 3; + } + } + if (local.length) { + for (let i5 = 0, span; i5 < decorations.length; i5++) + if (span = decorations[i5]) { + for (let j2 = 0; j2 < local.length; j2++) + if (local[j2].eq(span, offset)) { + if (local == this.local) + local = this.local.slice(); + local.splice(j2--, 1); + } + } + } + if (children == this.children && local == this.local) + return this; + return local.length || children.length ? new _DecorationSet(local, children) : empty; + } + forChild(offset, node) { + if (this == empty) + return this; + if (node.isLeaf) + return _DecorationSet.empty; + let child, local; + for (let i5 = 0; i5 < this.children.length; i5 += 3) + if (this.children[i5] >= offset) { + if (this.children[i5] == offset) + child = this.children[i5 + 2]; + break; + } + let start = offset + 1, end = start + node.content.size; + for (let i5 = 0; i5 < this.local.length; i5++) { + let dec = this.local[i5]; + if (dec.from < end && dec.to > start && dec.type instanceof InlineType) { + let from = Math.max(start, dec.from) - start, to = Math.min(end, dec.to) - start; + if (from < to) + (local || (local = [])).push(dec.copy(from, to)); + } + } + if (local) { + let localSet = new _DecorationSet(local.sort(byPos), none); + return child ? new DecorationGroup([localSet, child]) : localSet; + } + return child || empty; + } + /** + @internal + */ + eq(other) { + if (this == other) + return true; + if (!(other instanceof _DecorationSet) || this.local.length != other.local.length || this.children.length != other.children.length) + return false; + for (let i5 = 0; i5 < this.local.length; i5++) + if (!this.local[i5].eq(other.local[i5])) + return false; + for (let i5 = 0; i5 < this.children.length; i5 += 3) + if (this.children[i5] != other.children[i5] || this.children[i5 + 1] != other.children[i5 + 1] || !this.children[i5 + 2].eq(other.children[i5 + 2])) + return false; + return true; + } + /** + @internal + */ + locals(node) { + return removeOverlap(this.localsInner(node)); + } + /** + @internal + */ + localsInner(node) { + if (this == empty) + return none; + if (node.inlineContent || !this.local.some(InlineType.is)) + return this.local; + let result = []; + for (let i5 = 0; i5 < this.local.length; i5++) { + if (!(this.local[i5].type instanceof InlineType)) + result.push(this.local[i5]); + } + return result; + } + forEachSet(f3) { + f3(this); + } +}; +DecorationSet.empty = new DecorationSet([], []); +DecorationSet.removeOverlap = removeOverlap; +var empty = DecorationSet.empty; +var DecorationGroup = class _DecorationGroup { + constructor(members) { + this.members = members; + } + map(mapping, doc3) { + const mappedDecos = this.members.map((member) => member.map(mapping, doc3, noSpec)); + return _DecorationGroup.from(mappedDecos); + } + forChild(offset, child) { + if (child.isLeaf) + return DecorationSet.empty; + let found2 = []; + for (let i5 = 0; i5 < this.members.length; i5++) { + let result = this.members[i5].forChild(offset, child); + if (result == empty) + continue; + if (result instanceof _DecorationGroup) + found2 = found2.concat(result.members); + else + found2.push(result); + } + return _DecorationGroup.from(found2); + } + eq(other) { + if (!(other instanceof _DecorationGroup) || other.members.length != this.members.length) + return false; + for (let i5 = 0; i5 < this.members.length; i5++) + if (!this.members[i5].eq(other.members[i5])) + return false; + return true; + } + locals(node) { + let result, sorted = true; + for (let i5 = 0; i5 < this.members.length; i5++) { + let locals = this.members[i5].localsInner(node); + if (!locals.length) + continue; + if (!result) { + result = locals; + } else { + if (sorted) { + result = result.slice(); + sorted = false; + } + for (let j2 = 0; j2 < locals.length; j2++) + result.push(locals[j2]); + } + } + return result ? removeOverlap(sorted ? result : result.sort(byPos)) : none; + } + // Create a group for the given array of decoration sets, or return + // a single set when possible. + static from(members) { + switch (members.length) { + case 0: + return empty; + case 1: + return members[0]; + default: + return new _DecorationGroup(members.every((m2) => m2 instanceof DecorationSet) ? members : members.reduce((r4, m2) => r4.concat(m2 instanceof DecorationSet ? m2 : m2.members), [])); + } + } + forEachSet(f3) { + for (let i5 = 0; i5 < this.members.length; i5++) + this.members[i5].forEachSet(f3); + } +}; +function mapChildren(oldChildren, newLocal, mapping, node, offset, oldOffset, options) { + let children = oldChildren.slice(); + for (let i5 = 0, baseOffset = oldOffset; i5 < mapping.maps.length; i5++) { + let moved = 0; + mapping.maps[i5].forEach((oldStart, oldEnd, newStart, newEnd) => { + let dSize = newEnd - newStart - (oldEnd - oldStart); + for (let i6 = 0; i6 < children.length; i6 += 3) { + let end = children[i6 + 1]; + if (end < 0 || oldStart > end + baseOffset - moved) + continue; + let start = children[i6] + baseOffset - moved; + if (oldEnd >= start) { + children[i6 + 1] = oldStart <= start ? -2 : -1; + } else if (oldStart >= baseOffset && dSize) { + children[i6] += dSize; + children[i6 + 1] += dSize; + } + } + moved += dSize; + }); + baseOffset = mapping.maps[i5].map(baseOffset, -1); + } + let mustRebuild = false; + for (let i5 = 0; i5 < children.length; i5 += 3) + if (children[i5 + 1] < 0) { + if (children[i5 + 1] == -2) { + mustRebuild = true; + children[i5 + 1] = -1; + continue; + } + let from = mapping.map(oldChildren[i5] + oldOffset), fromLocal = from - offset; + if (fromLocal < 0 || fromLocal >= node.content.size) { + mustRebuild = true; + continue; + } + let to = mapping.map(oldChildren[i5 + 1] + oldOffset, -1), toLocal = to - offset; + let { index, offset: childOffset } = node.content.findIndex(fromLocal); + let childNode = node.maybeChild(index); + if (childNode && childOffset == fromLocal && childOffset + childNode.nodeSize == toLocal) { + let mapped = children[i5 + 2].mapInner(mapping, childNode, from + 1, oldChildren[i5] + oldOffset + 1, options); + if (mapped != empty) { + children[i5] = fromLocal; + children[i5 + 1] = toLocal; + children[i5 + 2] = mapped; + } else { + children[i5 + 1] = -2; + mustRebuild = true; + } + } else { + mustRebuild = true; + } + } + if (mustRebuild) { + let decorations = mapAndGatherRemainingDecorations(children, oldChildren, newLocal, mapping, offset, oldOffset, options); + let built = buildTree(decorations, node, 0, options); + newLocal = built.local; + for (let i5 = 0; i5 < children.length; i5 += 3) + if (children[i5 + 1] < 0) { + children.splice(i5, 3); + i5 -= 3; + } + for (let i5 = 0, j2 = 0; i5 < built.children.length; i5 += 3) { + let from = built.children[i5]; + while (j2 < children.length && children[j2] < from) + j2 += 3; + children.splice(j2, 0, built.children[i5], built.children[i5 + 1], built.children[i5 + 2]); + } + } + return new DecorationSet(newLocal.sort(byPos), children); +} +function moveSpans(spans, offset) { + if (!offset || !spans.length) + return spans; + let result = []; + for (let i5 = 0; i5 < spans.length; i5++) { + let span = spans[i5]; + result.push(new Decoration(span.from + offset, span.to + offset, span.type)); + } + return result; +} +function mapAndGatherRemainingDecorations(children, oldChildren, decorations, mapping, offset, oldOffset, options) { + function gather(set, oldOffset2) { + for (let i5 = 0; i5 < set.local.length; i5++) { + let mapped = set.local[i5].map(mapping, offset, oldOffset2); + if (mapped) + decorations.push(mapped); + else if (options.onRemove) + options.onRemove(set.local[i5].spec); + } + for (let i5 = 0; i5 < set.children.length; i5 += 3) + gather(set.children[i5 + 2], set.children[i5] + oldOffset2 + 1); + } + for (let i5 = 0; i5 < children.length; i5 += 3) + if (children[i5 + 1] == -1) + gather(children[i5 + 2], oldChildren[i5] + oldOffset + 1); + return decorations; +} +function takeSpansForNode(spans, node, offset) { + if (node.isLeaf) + return null; + let end = offset + node.nodeSize, found2 = null; + for (let i5 = 0, span; i5 < spans.length; i5++) { + if ((span = spans[i5]) && span.from > offset && span.to < end) { + (found2 || (found2 = [])).push(span); + spans[i5] = null; + } + } + return found2; +} +function withoutNulls(array) { + let result = []; + for (let i5 = 0; i5 < array.length; i5++) + if (array[i5] != null) + result.push(array[i5]); + return result; +} +function buildTree(spans, node, offset, options) { + let children = [], hasNulls = false; + node.forEach((childNode, localStart) => { + let found2 = takeSpansForNode(spans, childNode, localStart + offset); + if (found2) { + hasNulls = true; + let subtree = buildTree(found2, childNode, offset + localStart + 1, options); + if (subtree != empty) + children.push(localStart, localStart + childNode.nodeSize, subtree); + } + }); + let locals = moveSpans(hasNulls ? withoutNulls(spans) : spans, -offset).sort(byPos); + for (let i5 = 0; i5 < locals.length; i5++) + if (!locals[i5].type.valid(node, locals[i5])) { + if (options.onRemove) + options.onRemove(locals[i5].spec); + locals.splice(i5--, 1); + } + return locals.length || children.length ? new DecorationSet(locals, children) : empty; +} +function byPos(a3, b3) { + return a3.from - b3.from || a3.to - b3.to; +} +function removeOverlap(spans) { + let working = spans; + for (let i5 = 0; i5 < working.length - 1; i5++) { + let span = working[i5]; + if (span.from != span.to) + for (let j2 = i5 + 1; j2 < working.length; j2++) { + let next = working[j2]; + if (next.from == span.from) { + if (next.to != span.to) { + if (working == spans) + working = spans.slice(); + working[j2] = next.copy(next.from, span.to); + insertAhead(working, j2 + 1, next.copy(span.to, next.to)); + } + continue; + } else { + if (next.from < span.to) { + if (working == spans) + working = spans.slice(); + working[i5] = span.copy(span.from, next.from); + insertAhead(working, j2, span.copy(next.from, span.to)); + } + break; + } + } + } + return working; +} +function insertAhead(array, i5, deco) { + while (i5 < array.length && byPos(deco, array[i5]) > 0) + i5++; + array.splice(i5, 0, deco); +} +function viewDecorations(view) { + let found2 = []; + view.someProp("decorations", (f3) => { + let result = f3(view.state); + if (result && result != empty) + found2.push(result); + }); + if (view.cursorWrapper) + found2.push(DecorationSet.create(view.state.doc, [view.cursorWrapper.deco])); + return DecorationGroup.from(found2); +} +var observeOptions = { + childList: true, + characterData: true, + characterDataOldValue: true, + attributes: true, + attributeOldValue: true, + subtree: true +}; +var useCharData = ie && ie_version <= 11; +var SelectionState = class { + constructor() { + this.anchorNode = null; + this.anchorOffset = 0; + this.focusNode = null; + this.focusOffset = 0; + } + set(sel) { + this.anchorNode = sel.anchorNode; + this.anchorOffset = sel.anchorOffset; + this.focusNode = sel.focusNode; + this.focusOffset = sel.focusOffset; + } + clear() { + this.anchorNode = this.focusNode = null; + } + eq(sel) { + return sel.anchorNode == this.anchorNode && sel.anchorOffset == this.anchorOffset && sel.focusNode == this.focusNode && sel.focusOffset == this.focusOffset; + } +}; +var DOMObserver = class { + constructor(view, handleDOMChange) { + this.view = view; + this.handleDOMChange = handleDOMChange; + this.queue = []; + this.flushingSoon = -1; + this.observer = null; + this.currentSelection = new SelectionState(); + this.onCharData = null; + this.suppressingSelectionUpdates = false; + this.lastChangedTextNode = null; + this.observer = window.MutationObserver && new window.MutationObserver((mutations) => { + for (let i5 = 0; i5 < mutations.length; i5++) + this.queue.push(mutations[i5]); + if (ie && ie_version <= 11 && mutations.some((m2) => m2.type == "childList" && m2.removedNodes.length || m2.type == "characterData" && m2.oldValue.length > m2.target.nodeValue.length)) + this.flushSoon(); + else + this.flush(); + }); + if (useCharData) { + this.onCharData = (e4) => { + this.queue.push({ target: e4.target, type: "characterData", oldValue: e4.prevValue }); + this.flushSoon(); + }; + } + this.onSelectionChange = this.onSelectionChange.bind(this); + } + flushSoon() { + if (this.flushingSoon < 0) + this.flushingSoon = window.setTimeout(() => { + this.flushingSoon = -1; + this.flush(); + }, 20); + } + forceFlush() { + if (this.flushingSoon > -1) { + window.clearTimeout(this.flushingSoon); + this.flushingSoon = -1; + this.flush(); + } + } + start() { + if (this.observer) { + this.observer.takeRecords(); + this.observer.observe(this.view.dom, observeOptions); + } + if (this.onCharData) + this.view.dom.addEventListener("DOMCharacterDataModified", this.onCharData); + this.connectSelection(); + } + stop() { + if (this.observer) { + let take = this.observer.takeRecords(); + if (take.length) { + for (let i5 = 0; i5 < take.length; i5++) + this.queue.push(take[i5]); + window.setTimeout(() => this.flush(), 20); + } + this.observer.disconnect(); + } + if (this.onCharData) + this.view.dom.removeEventListener("DOMCharacterDataModified", this.onCharData); + this.disconnectSelection(); + } + connectSelection() { + this.view.dom.ownerDocument.addEventListener("selectionchange", this.onSelectionChange); + } + disconnectSelection() { + this.view.dom.ownerDocument.removeEventListener("selectionchange", this.onSelectionChange); + } + suppressSelectionUpdates() { + this.suppressingSelectionUpdates = true; + setTimeout(() => this.suppressingSelectionUpdates = false, 50); + } + onSelectionChange() { + if (!hasFocusAndSelection(this.view)) + return; + if (this.suppressingSelectionUpdates) + return selectionToDOM(this.view); + if (ie && ie_version <= 11 && !this.view.state.selection.empty) { + let sel = this.view.domSelectionRange(); + if (sel.focusNode && isEquivalentPosition(sel.focusNode, sel.focusOffset, sel.anchorNode, sel.anchorOffset)) + return this.flushSoon(); + } + this.flush(); + } + setCurSelection() { + this.currentSelection.set(this.view.domSelectionRange()); + } + ignoreSelectionChange(sel) { + if (!sel.focusNode) + return true; + let ancestors = /* @__PURE__ */ new Set(), container; + for (let scan = sel.focusNode; scan; scan = parentNode(scan)) + ancestors.add(scan); + for (let scan = sel.anchorNode; scan; scan = parentNode(scan)) + if (ancestors.has(scan)) { + container = scan; + break; + } + let desc = container && this.view.docView.nearestDesc(container); + if (desc && desc.ignoreMutation({ + type: "selection", + target: container.nodeType == 3 ? container.parentNode : container + })) { + this.setCurSelection(); + return true; + } + } + pendingRecords() { + if (this.observer) + for (let mut of this.observer.takeRecords()) + this.queue.push(mut); + return this.queue; + } + flush() { + let { view } = this; + if (!view.docView || this.flushingSoon > -1) + return; + let mutations = this.pendingRecords(); + if (mutations.length) + this.queue = []; + let sel = view.domSelectionRange(); + let newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasFocusAndSelection(view) && !this.ignoreSelectionChange(sel); + let from = -1, to = -1, typeOver = false, added = []; + if (view.editable) { + for (let i5 = 0; i5 < mutations.length; i5++) { + let result = this.registerMutation(mutations[i5], added); + if (result) { + from = from < 0 ? result.from : Math.min(result.from, from); + to = to < 0 ? result.to : Math.max(result.to, to); + if (result.typeOver) + typeOver = true; + } + } + } + if (gecko && added.length) { + let brs = added.filter((n4) => n4.nodeName == "BR"); + if (brs.length == 2) { + let [a3, b3] = brs; + if (a3.parentNode && a3.parentNode.parentNode == b3.parentNode) + b3.remove(); + else + a3.remove(); + } else { + let { focusNode } = this.currentSelection; + for (let br of brs) { + let parent = br.parentNode; + if (parent && parent.nodeName == "LI" && (!focusNode || blockParent(view, focusNode) != parent)) + br.remove(); + } + } + } + let readSel = null; + if (from < 0 && newSel && view.input.lastFocus > Date.now() - 200 && Math.max(view.input.lastTouch, view.input.lastClick.time) < Date.now() - 300 && selectionCollapsed(sel) && (readSel = selectionFromDOM(view)) && readSel.eq(Selection.near(view.state.doc.resolve(0), 1))) { + view.input.lastFocus = 0; + selectionToDOM(view); + this.currentSelection.set(sel); + view.scrollToSelection(); + } else if (from > -1 || newSel) { + if (from > -1) { + view.docView.markDirty(from, to); + checkCSS(view); + } + this.handleDOMChange(from, to, typeOver, added); + if (view.docView && view.docView.dirty) + view.updateState(view.state); + else if (!this.currentSelection.eq(sel)) + selectionToDOM(view); + this.currentSelection.set(sel); + } + } + registerMutation(mut, added) { + if (added.indexOf(mut.target) > -1) + return null; + let desc = this.view.docView.nearestDesc(mut.target); + if (mut.type == "attributes" && (desc == this.view.docView || mut.attributeName == "contenteditable" || // Firefox sometimes fires spurious events for null/empty styles + mut.attributeName == "style" && !mut.oldValue && !mut.target.getAttribute("style"))) + return null; + if (!desc || desc.ignoreMutation(mut)) + return null; + if (mut.type == "childList") { + for (let i5 = 0; i5 < mut.addedNodes.length; i5++) { + let node = mut.addedNodes[i5]; + added.push(node); + if (node.nodeType == 3) + this.lastChangedTextNode = node; + } + if (desc.contentDOM && desc.contentDOM != desc.dom && !desc.contentDOM.contains(mut.target)) + return { from: desc.posBefore, to: desc.posAfter }; + let prev = mut.previousSibling, next = mut.nextSibling; + if (ie && ie_version <= 11 && mut.addedNodes.length) { + for (let i5 = 0; i5 < mut.addedNodes.length; i5++) { + let { previousSibling, nextSibling } = mut.addedNodes[i5]; + if (!previousSibling || Array.prototype.indexOf.call(mut.addedNodes, previousSibling) < 0) + prev = previousSibling; + if (!nextSibling || Array.prototype.indexOf.call(mut.addedNodes, nextSibling) < 0) + next = nextSibling; + } + } + let fromOffset = prev && prev.parentNode == mut.target ? domIndex(prev) + 1 : 0; + let from = desc.localPosFromDOM(mut.target, fromOffset, -1); + let toOffset = next && next.parentNode == mut.target ? domIndex(next) : mut.target.childNodes.length; + let to = desc.localPosFromDOM(mut.target, toOffset, 1); + return { from, to }; + } else if (mut.type == "attributes") { + return { from: desc.posAtStart - desc.border, to: desc.posAtEnd + desc.border }; + } else { + this.lastChangedTextNode = mut.target; + return { + from: desc.posAtStart, + to: desc.posAtEnd, + // An event was generated for a text change that didn't change + // any text. Mark the dom change to fall back to assuming the + // selection was typed over with an identical value if it can't + // find another change. + typeOver: mut.target.nodeValue == mut.oldValue + }; + } + } +}; +var cssChecked = /* @__PURE__ */ new WeakMap(); +var cssCheckWarned = false; +function checkCSS(view) { + if (cssChecked.has(view)) + return; + cssChecked.set(view, null); + if (["normal", "nowrap", "pre-line"].indexOf(getComputedStyle(view.dom).whiteSpace) !== -1) { + view.requiresGeckoHackNode = gecko; + if (cssCheckWarned) + return; + console["warn"]("ProseMirror expects the CSS white-space property to be set, preferably to 'pre-wrap'. It is recommended to load style/prosemirror.css from the prosemirror-view package."); + cssCheckWarned = true; + } +} +function rangeToSelectionRange(view, range) { + let anchorNode = range.startContainer, anchorOffset = range.startOffset; + let focusNode = range.endContainer, focusOffset = range.endOffset; + let currentAnchor = view.domAtPos(view.state.selection.anchor); + if (isEquivalentPosition(currentAnchor.node, currentAnchor.offset, focusNode, focusOffset)) + [anchorNode, anchorOffset, focusNode, focusOffset] = [focusNode, focusOffset, anchorNode, anchorOffset]; + return { anchorNode, anchorOffset, focusNode, focusOffset }; +} +function safariShadowSelectionRange(view, selection) { + if (selection.getComposedRanges) { + let range = selection.getComposedRanges(view.root)[0]; + if (range) + return rangeToSelectionRange(view, range); + } + let found2; + function read(event) { + event.preventDefault(); + event.stopImmediatePropagation(); + found2 = event.getTargetRanges()[0]; + } + view.dom.addEventListener("beforeinput", read, true); + document.execCommand("indent"); + view.dom.removeEventListener("beforeinput", read, true); + return found2 ? rangeToSelectionRange(view, found2) : null; +} +function blockParent(view, node) { + for (let p3 = node.parentNode; p3 && p3 != view.dom; p3 = p3.parentNode) { + let desc = view.docView.nearestDesc(p3, true); + if (desc && desc.node.isBlock) + return p3; + } + return null; +} +function parseBetween(view, from_, to_) { + let { node: parent, fromOffset, toOffset, from, to } = view.docView.parseRange(from_, to_); + let domSel = view.domSelectionRange(); + let find; + let anchor = domSel.anchorNode; + if (anchor && view.dom.contains(anchor.nodeType == 1 ? anchor : anchor.parentNode)) { + find = [{ node: anchor, offset: domSel.anchorOffset }]; + if (!selectionCollapsed(domSel)) + find.push({ node: domSel.focusNode, offset: domSel.focusOffset }); + } + if (chrome && view.input.lastKeyCode === 8) { + for (let off = toOffset; off > fromOffset; off--) { + let node = parent.childNodes[off - 1], desc = node.pmViewDesc; + if (node.nodeName == "BR" && !desc) { + toOffset = off; + break; + } + if (!desc || desc.size) + break; + } + } + let startDoc = view.state.doc; + let parser = view.someProp("domParser") || DOMParser.fromSchema(view.state.schema); + let $from = startDoc.resolve(from); + let sel = null, doc3 = parser.parse(parent, { + topNode: $from.parent, + topMatch: $from.parent.contentMatchAt($from.index()), + topOpen: true, + from: fromOffset, + to: toOffset, + preserveWhitespace: $from.parent.type.whitespace == "pre" ? "full" : true, + findPositions: find, + ruleFromNode, + context: $from + }); + if (find && find[0].pos != null) { + let anchor2 = find[0].pos, head = find[1] && find[1].pos; + if (head == null) + head = anchor2; + sel = { anchor: anchor2 + from, head: head + from }; + } + return { doc: doc3, sel, from, to }; +} +function ruleFromNode(dom) { + let desc = dom.pmViewDesc; + if (desc) { + return desc.parseRule(); + } else if (dom.nodeName == "BR" && dom.parentNode) { + if (safari && /^(ul|ol)$/i.test(dom.parentNode.nodeName)) { + let skip = document.createElement("div"); + skip.appendChild(document.createElement("li")); + return { skip }; + } else if (dom.parentNode.lastChild == dom || safari && /^(tr|table)$/i.test(dom.parentNode.nodeName)) { + return { ignore: true }; + } + } else if (dom.nodeName == "IMG" && dom.getAttribute("mark-placeholder")) { + return { ignore: true }; + } + return null; +} +var isInline = /^(a|abbr|acronym|b|bd[io]|big|br|button|cite|code|data(list)?|del|dfn|em|i|ins|kbd|label|map|mark|meter|output|q|ruby|s|samp|small|span|strong|su[bp]|time|u|tt|var)$/i; +function readDOMChange(view, from, to, typeOver, addedNodes) { + let compositionID = view.input.compositionPendingChanges || (view.composing ? view.input.compositionID : 0); + view.input.compositionPendingChanges = 0; + if (from < 0) { + let origin = view.input.lastSelectionTime > Date.now() - 50 ? view.input.lastSelectionOrigin : null; + let newSel = selectionFromDOM(view, origin); + if (newSel && !view.state.selection.eq(newSel)) { + if (chrome && android && view.input.lastKeyCode === 13 && Date.now() - 100 < view.input.lastKeyCodeTime && view.someProp("handleKeyDown", (f3) => f3(view, keyEvent(13, "Enter")))) + return; + let tr2 = view.state.tr.setSelection(newSel); + if (origin == "pointer") + tr2.setMeta("pointer", true); + else if (origin == "key") + tr2.scrollIntoView(); + if (compositionID) + tr2.setMeta("composition", compositionID); + view.dispatch(tr2); + } + return; + } + let $before = view.state.doc.resolve(from); + let shared = $before.sharedDepth(to); + from = $before.before(shared + 1); + to = view.state.doc.resolve(to).after(shared + 1); + let sel = view.state.selection; + let parse = parseBetween(view, from, to); + let doc3 = view.state.doc, compare = doc3.slice(parse.from, parse.to); + let preferredPos, preferredSide; + if (view.input.lastKeyCode === 8 && Date.now() - 100 < view.input.lastKeyCodeTime) { + preferredPos = view.state.selection.to; + preferredSide = "end"; + } else { + preferredPos = view.state.selection.from; + preferredSide = "start"; + } + view.input.lastKeyCode = null; + let change = findDiff(compare.content, parse.doc.content, parse.from, preferredPos, preferredSide); + if (change) + view.input.domChangeCount++; + if ((ios && view.input.lastIOSEnter > Date.now() - 225 || android) && addedNodes.some((n4) => n4.nodeType == 1 && !isInline.test(n4.nodeName)) && (!change || change.endA >= change.endB) && view.someProp("handleKeyDown", (f3) => f3(view, keyEvent(13, "Enter")))) { + view.input.lastIOSEnter = 0; + return; + } + if (!change) { + if (typeOver && sel instanceof TextSelection && !sel.empty && sel.$head.sameParent(sel.$anchor) && !view.composing && !(parse.sel && parse.sel.anchor != parse.sel.head)) { + change = { start: sel.from, endA: sel.to, endB: sel.to }; + } else { + if (parse.sel) { + let sel2 = resolveSelection(view, view.state.doc, parse.sel); + if (sel2 && !sel2.eq(view.state.selection)) { + let tr2 = view.state.tr.setSelection(sel2); + if (compositionID) + tr2.setMeta("composition", compositionID); + view.dispatch(tr2); + } + } + return; + } + } + if (view.state.selection.from < view.state.selection.to && change.start == change.endB && view.state.selection instanceof TextSelection) { + if (change.start > view.state.selection.from && change.start <= view.state.selection.from + 2 && view.state.selection.from >= parse.from) { + change.start = view.state.selection.from; + } else if (change.endA < view.state.selection.to && change.endA >= view.state.selection.to - 2 && view.state.selection.to <= parse.to) { + change.endB += view.state.selection.to - change.endA; + change.endA = view.state.selection.to; + } + } + if (ie && ie_version <= 11 && change.endB == change.start + 1 && change.endA == change.start && change.start > parse.from && parse.doc.textBetween(change.start - parse.from - 1, change.start - parse.from + 1) == " \xA0") { + change.start--; + change.endA--; + change.endB--; + } + let $from = parse.doc.resolveNoCache(change.start - parse.from); + let $to = parse.doc.resolveNoCache(change.endB - parse.from); + let $fromA = doc3.resolve(change.start); + let inlineChange = $from.sameParent($to) && $from.parent.inlineContent && $fromA.end() >= change.endA; + let nextSel; + if ((ios && view.input.lastIOSEnter > Date.now() - 225 && (!inlineChange || addedNodes.some((n4) => n4.nodeName == "DIV" || n4.nodeName == "P")) || !inlineChange && $from.pos < parse.doc.content.size && (!$from.sameParent($to) || !$from.parent.inlineContent) && !/\S/.test(parse.doc.textBetween($from.pos, $to.pos, "", "")) && (nextSel = Selection.findFrom(parse.doc.resolve($from.pos + 1), 1, true)) && nextSel.head > $from.pos) && view.someProp("handleKeyDown", (f3) => f3(view, keyEvent(13, "Enter")))) { + view.input.lastIOSEnter = 0; + return; + } + if (view.state.selection.anchor > change.start && looksLikeBackspace(doc3, change.start, change.endA, $from, $to) && view.someProp("handleKeyDown", (f3) => f3(view, keyEvent(8, "Backspace")))) { + if (android && chrome) + view.domObserver.suppressSelectionUpdates(); + return; + } + if (chrome && change.endB == change.start) + view.input.lastChromeDelete = Date.now(); + if (android && !inlineChange && $from.start() != $to.start() && $to.parentOffset == 0 && $from.depth == $to.depth && parse.sel && parse.sel.anchor == parse.sel.head && parse.sel.head == change.endA) { + change.endB -= 2; + $to = parse.doc.resolveNoCache(change.endB - parse.from); + setTimeout(() => { + view.someProp("handleKeyDown", function(f3) { + return f3(view, keyEvent(13, "Enter")); + }); + }, 20); + } + let chFrom = change.start, chTo = change.endA; + let tr, storedMarks, markChange; + if (inlineChange) { + if ($from.pos == $to.pos) { + if (ie && ie_version <= 11 && $from.parentOffset == 0) { + view.domObserver.suppressSelectionUpdates(); + setTimeout(() => selectionToDOM(view), 20); + } + tr = view.state.tr.delete(chFrom, chTo); + storedMarks = doc3.resolve(change.start).marksAcross(doc3.resolve(change.endA)); + } else if ( + // Adding or removing a mark + change.endA == change.endB && (markChange = isMarkChange($from.parent.content.cut($from.parentOffset, $to.parentOffset), $fromA.parent.content.cut($fromA.parentOffset, change.endA - $fromA.start()))) + ) { + tr = view.state.tr; + if (markChange.type == "add") + tr.addMark(chFrom, chTo, markChange.mark); + else + tr.removeMark(chFrom, chTo, markChange.mark); + } else if ($from.parent.child($from.index()).isText && $from.index() == $to.index() - ($to.textOffset ? 0 : 1)) { + let text = $from.parent.textBetween($from.parentOffset, $to.parentOffset); + if (view.someProp("handleTextInput", (f3) => f3(view, chFrom, chTo, text))) + return; + tr = view.state.tr.insertText(text, chFrom, chTo); + } + } + if (!tr) + tr = view.state.tr.replace(chFrom, chTo, parse.doc.slice(change.start - parse.from, change.endB - parse.from)); + if (parse.sel) { + let sel2 = resolveSelection(view, tr.doc, parse.sel); + if (sel2 && !(chrome && view.composing && sel2.empty && (change.start != change.endB || view.input.lastChromeDelete < Date.now() - 100) && (sel2.head == chFrom || sel2.head == tr.mapping.map(chTo) - 1) || ie && sel2.empty && sel2.head == chFrom)) + tr.setSelection(sel2); + } + if (storedMarks) + tr.ensureMarks(storedMarks); + if (compositionID) + tr.setMeta("composition", compositionID); + view.dispatch(tr.scrollIntoView()); +} +function resolveSelection(view, doc3, parsedSel) { + if (Math.max(parsedSel.anchor, parsedSel.head) > doc3.content.size) + return null; + return selectionBetween(view, doc3.resolve(parsedSel.anchor), doc3.resolve(parsedSel.head)); +} +function isMarkChange(cur, prev) { + let curMarks = cur.firstChild.marks, prevMarks = prev.firstChild.marks; + let added = curMarks, removed = prevMarks, type, mark, update; + for (let i5 = 0; i5 < prevMarks.length; i5++) + added = prevMarks[i5].removeFromSet(added); + for (let i5 = 0; i5 < curMarks.length; i5++) + removed = curMarks[i5].removeFromSet(removed); + if (added.length == 1 && removed.length == 0) { + mark = added[0]; + type = "add"; + update = (node) => node.mark(mark.addToSet(node.marks)); + } else if (added.length == 0 && removed.length == 1) { + mark = removed[0]; + type = "remove"; + update = (node) => node.mark(mark.removeFromSet(node.marks)); + } else { + return null; + } + let updated = []; + for (let i5 = 0; i5 < prev.childCount; i5++) + updated.push(update(prev.child(i5))); + if (Fragment.from(updated).eq(cur)) + return { mark, type }; +} +function looksLikeBackspace(old, start, end, $newStart, $newEnd) { + if ( + // The content must have shrunk + end - start <= $newEnd.pos - $newStart.pos || // newEnd must point directly at or after the end of the block that newStart points into + skipClosingAndOpening($newStart, true, false) < $newEnd.pos + ) + return false; + let $start = old.resolve(start); + if (!$newStart.parent.isTextblock) { + let after = $start.nodeAfter; + return after != null && end == start + after.nodeSize; + } + if ($start.parentOffset < $start.parent.content.size || !$start.parent.isTextblock) + return false; + let $next = old.resolve(skipClosingAndOpening($start, true, true)); + if (!$next.parent.isTextblock || $next.pos > end || skipClosingAndOpening($next, true, false) < end) + return false; + return $newStart.parent.content.cut($newStart.parentOffset).eq($next.parent.content); +} +function skipClosingAndOpening($pos, fromEnd, mayOpen) { + let depth = $pos.depth, end = fromEnd ? $pos.end() : $pos.pos; + while (depth > 0 && (fromEnd || $pos.indexAfter(depth) == $pos.node(depth).childCount)) { + depth--; + end++; + fromEnd = false; + } + if (mayOpen) { + let next = $pos.node(depth).maybeChild($pos.indexAfter(depth)); + while (next && !next.isLeaf) { + next = next.firstChild; + end++; + } + } + return end; +} +function findDiff(a3, b3, pos, preferredPos, preferredSide) { + let start = a3.findDiffStart(b3, pos); + if (start == null) + return null; + let { a: endA, b: endB } = a3.findDiffEnd(b3, pos + a3.size, pos + b3.size); + if (preferredSide == "end") { + let adjust = Math.max(0, start - Math.min(endA, endB)); + preferredPos -= endA + adjust - start; + } + if (endA < start && a3.size < b3.size) { + let move = preferredPos <= start && preferredPos >= endA ? start - preferredPos : 0; + start -= move; + if (start && start < b3.size && isSurrogatePair(b3.textBetween(start - 1, start + 1))) + start += move ? 1 : -1; + endB = start + (endB - endA); + endA = start; + } else if (endB < start) { + let move = preferredPos <= start && preferredPos >= endB ? start - preferredPos : 0; + start -= move; + if (start && start < a3.size && isSurrogatePair(a3.textBetween(start - 1, start + 1))) + start += move ? 1 : -1; + endA = start + (endA - endB); + endB = start; + } + return { start, endA, endB }; +} +function isSurrogatePair(str) { + if (str.length != 2) + return false; + let a3 = str.charCodeAt(0), b3 = str.charCodeAt(1); + return a3 >= 56320 && a3 <= 57343 && b3 >= 55296 && b3 <= 56319; +} +var EditorView = class { + /** + Create a view. `place` may be a DOM node that the editor should + be appended to, a function that will place it into the document, + or an object whose `mount` property holds the node to use as the + document container. If it is `null`, the editor will not be + added to the document. + */ + constructor(place, props) { + this._root = null; + this.focused = false; + this.trackWrites = null; + this.mounted = false; + this.markCursor = null; + this.cursorWrapper = null; + this.lastSelectedViewDesc = void 0; + this.input = new InputState(); + this.prevDirectPlugins = []; + this.pluginViews = []; + this.requiresGeckoHackNode = false; + this.dragging = null; + this._props = props; + this.state = props.state; + this.directPlugins = props.plugins || []; + this.directPlugins.forEach(checkStateComponent); + this.dispatch = this.dispatch.bind(this); + this.dom = place && place.mount || document.createElement("div"); + if (place) { + if (place.appendChild) + place.appendChild(this.dom); + else if (typeof place == "function") + place(this.dom); + else if (place.mount) + this.mounted = true; + } + this.editable = getEditable(this); + updateCursorWrapper(this); + this.nodeViews = buildNodeViews(this); + this.docView = docViewDesc(this.state.doc, computeDocDeco(this), viewDecorations(this), this.dom, this); + this.domObserver = new DOMObserver(this, (from, to, typeOver, added) => readDOMChange(this, from, to, typeOver, added)); + this.domObserver.start(); + initInput(this); + this.updatePluginViews(); + } + /** + Holds `true` when a + [composition](https://w3c.github.io/uievents/#events-compositionevents) + is active. + */ + get composing() { + return this.input.composing; + } + /** + The view's current [props](https://prosemirror.net/docs/ref/#view.EditorProps). + */ + get props() { + if (this._props.state != this.state) { + let prev = this._props; + this._props = {}; + for (let name in prev) + this._props[name] = prev[name]; + this._props.state = this.state; + } + return this._props; + } + /** + Update the view's props. Will immediately cause an update to + the DOM. + */ + update(props) { + if (props.handleDOMEvents != this._props.handleDOMEvents) + ensureListeners(this); + let prevProps = this._props; + this._props = props; + if (props.plugins) { + props.plugins.forEach(checkStateComponent); + this.directPlugins = props.plugins; + } + this.updateStateInner(props.state, prevProps); + } + /** + Update the view by updating existing props object with the object + given as argument. Equivalent to `view.update(Object.assign({}, + view.props, props))`. + */ + setProps(props) { + let updated = {}; + for (let name in this._props) + updated[name] = this._props[name]; + updated.state = this.state; + for (let name in props) + updated[name] = props[name]; + this.update(updated); + } + /** + Update the editor's `state` prop, without touching any of the + other props. + */ + updateState(state) { + this.updateStateInner(state, this._props); + } + updateStateInner(state, prevProps) { + var _a; + let prev = this.state, redraw = false, updateSel = false; + if (state.storedMarks && this.composing) { + clearComposition(this); + updateSel = true; + } + this.state = state; + let pluginsChanged = prev.plugins != state.plugins || this._props.plugins != prevProps.plugins; + if (pluginsChanged || this._props.plugins != prevProps.plugins || this._props.nodeViews != prevProps.nodeViews) { + let nodeViews = buildNodeViews(this); + if (changedNodeViews(nodeViews, this.nodeViews)) { + this.nodeViews = nodeViews; + redraw = true; + } + } + if (pluginsChanged || prevProps.handleDOMEvents != this._props.handleDOMEvents) { + ensureListeners(this); + } + this.editable = getEditable(this); + updateCursorWrapper(this); + let innerDeco = viewDecorations(this), outerDeco = computeDocDeco(this); + let scroll = prev.plugins != state.plugins && !prev.doc.eq(state.doc) ? "reset" : state.scrollToSelection > prev.scrollToSelection ? "to selection" : "preserve"; + let updateDoc = redraw || !this.docView.matchesNode(state.doc, outerDeco, innerDeco); + if (updateDoc || !state.selection.eq(prev.selection)) + updateSel = true; + let oldScrollPos = scroll == "preserve" && updateSel && this.dom.style.overflowAnchor == null && storeScrollPos(this); + if (updateSel) { + this.domObserver.stop(); + let forceSelUpdate = updateDoc && (ie || chrome) && !this.composing && !prev.selection.empty && !state.selection.empty && selectionContextChanged(prev.selection, state.selection); + if (updateDoc) { + let chromeKludge = chrome ? this.trackWrites = this.domSelectionRange().focusNode : null; + if (this.composing) + this.input.compositionNode = findCompositionNode(this); + if (redraw || !this.docView.update(state.doc, outerDeco, innerDeco, this)) { + this.docView.updateOuterDeco(outerDeco); + this.docView.destroy(); + this.docView = docViewDesc(state.doc, outerDeco, innerDeco, this.dom, this); + } + if (chromeKludge && !this.trackWrites) + forceSelUpdate = true; + } + if (forceSelUpdate || !(this.input.mouseDown && this.domObserver.currentSelection.eq(this.domSelectionRange()) && anchorInRightPlace(this))) { + selectionToDOM(this, forceSelUpdate); + } else { + syncNodeSelection(this, state.selection); + this.domObserver.setCurSelection(); + } + this.domObserver.start(); + } + this.updatePluginViews(prev); + if (((_a = this.dragging) === null || _a === void 0 ? void 0 : _a.node) && !prev.doc.eq(state.doc)) + this.updateDraggedNode(this.dragging, prev); + if (scroll == "reset") { + this.dom.scrollTop = 0; + } else if (scroll == "to selection") { + this.scrollToSelection(); + } else if (oldScrollPos) { + resetScrollPos(oldScrollPos); + } + } + /** + @internal + */ + scrollToSelection() { + let startDOM = this.domSelectionRange().focusNode; + if (!startDOM || !this.dom.contains(startDOM.nodeType == 1 ? startDOM : startDOM.parentNode)) ; + else if (this.someProp("handleScrollToSelection", (f3) => f3(this))) ; + else if (this.state.selection instanceof NodeSelection) { + let target = this.docView.domAfterPos(this.state.selection.from); + if (target.nodeType == 1) + scrollRectIntoView(this, target.getBoundingClientRect(), startDOM); + } else { + scrollRectIntoView(this, this.coordsAtPos(this.state.selection.head, 1), startDOM); + } + } + destroyPluginViews() { + let view; + while (view = this.pluginViews.pop()) + if (view.destroy) + view.destroy(); + } + updatePluginViews(prevState) { + if (!prevState || prevState.plugins != this.state.plugins || this.directPlugins != this.prevDirectPlugins) { + this.prevDirectPlugins = this.directPlugins; + this.destroyPluginViews(); + for (let i5 = 0; i5 < this.directPlugins.length; i5++) { + let plugin = this.directPlugins[i5]; + if (plugin.spec.view) + this.pluginViews.push(plugin.spec.view(this)); + } + for (let i5 = 0; i5 < this.state.plugins.length; i5++) { + let plugin = this.state.plugins[i5]; + if (plugin.spec.view) + this.pluginViews.push(plugin.spec.view(this)); + } + } else { + for (let i5 = 0; i5 < this.pluginViews.length; i5++) { + let pluginView = this.pluginViews[i5]; + if (pluginView.update) + pluginView.update(this, prevState); + } + } + } + updateDraggedNode(dragging, prev) { + let sel = dragging.node, found2 = -1; + if (this.state.doc.nodeAt(sel.from) == sel.node) { + found2 = sel.from; + } else { + let movedPos = sel.from + (this.state.doc.content.size - prev.doc.content.size); + let moved = movedPos > 0 && this.state.doc.nodeAt(movedPos); + if (moved == sel.node) + found2 = movedPos; + } + this.dragging = new Dragging(dragging.slice, dragging.move, found2 < 0 ? void 0 : NodeSelection.create(this.state.doc, found2)); + } + someProp(propName, f3) { + let prop = this._props && this._props[propName], value; + if (prop != null && (value = f3 ? f3(prop) : prop)) + return value; + for (let i5 = 0; i5 < this.directPlugins.length; i5++) { + let prop2 = this.directPlugins[i5].props[propName]; + if (prop2 != null && (value = f3 ? f3(prop2) : prop2)) + return value; + } + let plugins = this.state.plugins; + if (plugins) + for (let i5 = 0; i5 < plugins.length; i5++) { + let prop2 = plugins[i5].props[propName]; + if (prop2 != null && (value = f3 ? f3(prop2) : prop2)) + return value; + } + } + /** + Query whether the view has focus. + */ + hasFocus() { + if (ie) { + let node = this.root.activeElement; + if (node == this.dom) + return true; + if (!node || !this.dom.contains(node)) + return false; + while (node && this.dom != node && this.dom.contains(node)) { + if (node.contentEditable == "false") + return false; + node = node.parentElement; + } + return true; + } + return this.root.activeElement == this.dom; + } + /** + Focus the editor. + */ + focus() { + this.domObserver.stop(); + if (this.editable) + focusPreventScroll(this.dom); + selectionToDOM(this); + this.domObserver.start(); + } + /** + Get the document root in which the editor exists. This will + usually be the top-level `document`, but might be a [shadow + DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Shadow_DOM) + root if the editor is inside one. + */ + get root() { + let cached = this._root; + if (cached == null) + for (let search = this.dom.parentNode; search; search = search.parentNode) { + if (search.nodeType == 9 || search.nodeType == 11 && search.host) { + if (!search.getSelection) + Object.getPrototypeOf(search).getSelection = () => search.ownerDocument.getSelection(); + return this._root = search; + } + } + return cached || document; + } + /** + When an existing editor view is moved to a new document or + shadow tree, call this to make it recompute its root. + */ + updateRoot() { + this._root = null; + } + /** + Given a pair of viewport coordinates, return the document + position that corresponds to them. May return null if the given + coordinates aren't inside of the editor. When an object is + returned, its `pos` property is the position nearest to the + coordinates, and its `inside` property holds the position of the + inner node that the position falls inside of, or -1 if it is at + the top level, not in any node. + */ + posAtCoords(coords) { + return posAtCoords(this, coords); + } + /** + Returns the viewport rectangle at a given document position. + `left` and `right` will be the same number, as this returns a + flat cursor-ish rectangle. If the position is between two things + that aren't directly adjacent, `side` determines which element + is used. When < 0, the element before the position is used, + otherwise the element after. + */ + coordsAtPos(pos, side = 1) { + return coordsAtPos(this, pos, side); + } + /** + Find the DOM position that corresponds to the given document + position. When `side` is negative, find the position as close as + possible to the content before the position. When positive, + prefer positions close to the content after the position. When + zero, prefer as shallow a position as possible. + + Note that you should **not** mutate the editor's internal DOM, + only inspect it (and even that is usually not necessary). + */ + domAtPos(pos, side = 0) { + return this.docView.domFromPos(pos, side); + } + /** + Find the DOM node that represents the document node after the + given position. May return `null` when the position doesn't point + in front of a node or if the node is inside an opaque node view. + + This is intended to be able to call things like + `getBoundingClientRect` on that DOM node. Do **not** mutate the + editor DOM directly, or add styling this way, since that will be + immediately overriden by the editor as it redraws the node. + */ + nodeDOM(pos) { + let desc = this.docView.descAt(pos); + return desc ? desc.nodeDOM : null; + } + /** + Find the document position that corresponds to a given DOM + position. (Whenever possible, it is preferable to inspect the + document structure directly, rather than poking around in the + DOM, but sometimes—for example when interpreting an event + target—you don't have a choice.) + + The `bias` parameter can be used to influence which side of a DOM + node to use when the position is inside a leaf node. + */ + posAtDOM(node, offset, bias = -1) { + let pos = this.docView.posFromDOM(node, offset, bias); + if (pos == null) + throw new RangeError("DOM position not inside the editor"); + return pos; + } + /** + Find out whether the selection is at the end of a textblock when + moving in a given direction. When, for example, given `"left"`, + it will return true if moving left from the current cursor + position would leave that position's parent textblock. Will apply + to the view's current state by default, but it is possible to + pass a different state. + */ + endOfTextblock(dir, state) { + return endOfTextblock(this, state || this.state, dir); + } + /** + Run the editor's paste logic with the given HTML string. The + `event`, if given, will be passed to the + [`handlePaste`](https://prosemirror.net/docs/ref/#view.EditorProps.handlePaste) hook. + */ + pasteHTML(html, event) { + return doPaste(this, "", html, false, event || new ClipboardEvent("paste")); + } + /** + Run the editor's paste logic with the given plain-text input. + */ + pasteText(text, event) { + return doPaste(this, text, null, true, event || new ClipboardEvent("paste")); + } + /** + Serialize the given slice as it would be if it was copied from + this editor. Returns a DOM element that contains a + representation of the slice as its children, a textual + representation, and the transformed slice (which can be + different from the given input due to hooks like + [`transformCopied`](https://prosemirror.net/docs/ref/#view.EditorProps.transformCopied)). + */ + serializeForClipboard(slice) { + return serializeForClipboard(this, slice); + } + /** + Removes the editor from the DOM and destroys all [node + views](https://prosemirror.net/docs/ref/#view.NodeView). + */ + destroy() { + if (!this.docView) + return; + destroyInput(this); + this.destroyPluginViews(); + if (this.mounted) { + this.docView.update(this.state.doc, [], viewDecorations(this), this); + this.dom.textContent = ""; + } else if (this.dom.parentNode) { + this.dom.parentNode.removeChild(this.dom); + } + this.docView.destroy(); + this.docView = null; + clearReusedRange(); + } + /** + This is true when the view has been + [destroyed](https://prosemirror.net/docs/ref/#view.EditorView.destroy) (and thus should not be + used anymore). + */ + get isDestroyed() { + return this.docView == null; + } + /** + Used for testing. + */ + dispatchEvent(event) { + return dispatchEvent(this, event); + } + /** + Dispatch a transaction. Will call + [`dispatchTransaction`](https://prosemirror.net/docs/ref/#view.DirectEditorProps.dispatchTransaction) + when given, and otherwise defaults to applying the transaction to + the current state and calling + [`updateState`](https://prosemirror.net/docs/ref/#view.EditorView.updateState) with the result. + This method is bound to the view instance, so that it can be + easily passed around. + */ + dispatch(tr) { + let dispatchTransaction = this._props.dispatchTransaction; + if (dispatchTransaction) + dispatchTransaction.call(this, tr); + else + this.updateState(this.state.apply(tr)); + } + /** + @internal + */ + domSelectionRange() { + let sel = this.domSelection(); + if (!sel) + return { focusNode: null, focusOffset: 0, anchorNode: null, anchorOffset: 0 }; + return safari && this.root.nodeType === 11 && deepActiveElement(this.dom.ownerDocument) == this.dom && safariShadowSelectionRange(this, sel) || sel; + } + /** + @internal + */ + domSelection() { + return this.root.getSelection(); + } +}; +function computeDocDeco(view) { + let attrs = /* @__PURE__ */ Object.create(null); + attrs.class = "ProseMirror"; + attrs.contenteditable = String(view.editable); + view.someProp("attributes", (value) => { + if (typeof value == "function") + value = value(view.state); + if (value) + for (let attr in value) { + if (attr == "class") + attrs.class += " " + value[attr]; + else if (attr == "style") + attrs.style = (attrs.style ? attrs.style + ";" : "") + value[attr]; + else if (!attrs[attr] && attr != "contenteditable" && attr != "nodeName") + attrs[attr] = String(value[attr]); + } + }); + if (!attrs.translate) + attrs.translate = "no"; + return [Decoration.node(0, view.state.doc.content.size, attrs)]; +} +function updateCursorWrapper(view) { + if (view.markCursor) { + let dom = document.createElement("img"); + dom.className = "ProseMirror-separator"; + dom.setAttribute("mark-placeholder", "true"); + dom.setAttribute("alt", ""); + view.cursorWrapper = { dom, deco: Decoration.widget(view.state.selection.from, dom, { raw: true, marks: view.markCursor }) }; + } else { + view.cursorWrapper = null; + } +} +function getEditable(view) { + return !view.someProp("editable", (value) => value(view.state) === false); +} +function selectionContextChanged(sel1, sel2) { + let depth = Math.min(sel1.$anchor.sharedDepth(sel1.head), sel2.$anchor.sharedDepth(sel2.head)); + return sel1.$anchor.start(depth) != sel2.$anchor.start(depth); +} +function buildNodeViews(view) { + let result = /* @__PURE__ */ Object.create(null); + function add(obj) { + for (let prop in obj) + if (!Object.prototype.hasOwnProperty.call(result, prop)) + result[prop] = obj[prop]; + } + view.someProp("nodeViews", add); + view.someProp("markViews", add); + return result; +} +function changedNodeViews(a3, b3) { + let nA = 0, nB = 0; + for (let prop in a3) { + if (a3[prop] != b3[prop]) + return true; + nA++; + } + for (let _2 in b3) + nB++; + return nA != nB; +} +function checkStateComponent(plugin) { + if (plugin.spec.state || plugin.spec.filterTransaction || plugin.spec.appendTransaction) + throw new RangeError("Plugins passed directly to the view must not have a state component"); +} + +// node_modules/w3c-keyname/index.js +var base = { + 8: "Backspace", + 9: "Tab", + 10: "Enter", + 12: "NumLock", + 13: "Enter", + 16: "Shift", + 17: "Control", + 18: "Alt", + 20: "CapsLock", + 27: "Escape", + 32: " ", + 33: "PageUp", + 34: "PageDown", + 35: "End", + 36: "Home", + 37: "ArrowLeft", + 38: "ArrowUp", + 39: "ArrowRight", + 40: "ArrowDown", + 44: "PrintScreen", + 45: "Insert", + 46: "Delete", + 59: ";", + 61: "=", + 91: "Meta", + 92: "Meta", + 106: "*", + 107: "+", + 108: ",", + 109: "-", + 110: ".", + 111: "/", + 144: "NumLock", + 145: "ScrollLock", + 160: "Shift", + 161: "Shift", + 162: "Control", + 163: "Control", + 164: "Alt", + 165: "Alt", + 173: "-", + 186: ";", + 187: "=", + 188: ",", + 189: "-", + 190: ".", + 191: "/", + 192: "`", + 219: "[", + 220: "\\", + 221: "]", + 222: "'" +}; +var shift = { + 48: ")", + 49: "!", + 50: "@", + 51: "#", + 52: "$", + 53: "%", + 54: "^", + 55: "&", + 56: "*", + 57: "(", + 59: ":", + 61: "+", + 173: "_", + 186: ":", + 187: "+", + 188: "<", + 189: "_", + 190: ">", + 191: "?", + 192: "~", + 219: "{", + 220: "|", + 221: "}", + 222: '"' +}; +var mac2 = typeof navigator != "undefined" && /Mac/.test(navigator.platform); +var ie2 = typeof navigator != "undefined" && /MSIE \d|Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent); +for (i5 = 0; i5 < 10; i5++) base[48 + i5] = base[96 + i5] = String(i5); +var i5; +for (i5 = 1; i5 <= 24; i5++) base[i5 + 111] = "F" + i5; +var i5; +for (i5 = 65; i5 <= 90; i5++) { + base[i5] = String.fromCharCode(i5 + 32); + shift[i5] = String.fromCharCode(i5); +} +var i5; +for (code in base) if (!shift.hasOwnProperty(code)) shift[code] = base[code]; +var code; +function keyName(event) { + var ignoreKey = mac2 && event.metaKey && event.shiftKey && !event.ctrlKey && !event.altKey || ie2 && event.shiftKey && event.key && event.key.length == 1 || event.key == "Unidentified"; + var name = !ignoreKey && event.key || (event.shiftKey ? shift : base)[event.keyCode] || event.key || "Unidentified"; + if (name == "Esc") name = "Escape"; + if (name == "Del") name = "Delete"; + if (name == "Left") name = "ArrowLeft"; + if (name == "Up") name = "ArrowUp"; + if (name == "Right") name = "ArrowRight"; + if (name == "Down") name = "ArrowDown"; + return name; +} + +// node_modules/prosemirror-keymap/dist/index.js +var mac3 = typeof navigator != "undefined" && /Mac|iP(hone|[oa]d)/.test(navigator.platform); +var windows2 = typeof navigator != "undefined" && /Win/.test(navigator.platform); +function normalizeKeyName(name) { + let parts = name.split(/-(?!$)/), result = parts[parts.length - 1]; + if (result == "Space") + result = " "; + let alt, ctrl, shift2, meta; + for (let i5 = 0; i5 < parts.length - 1; i5++) { + let mod = parts[i5]; + if (/^(cmd|meta|m)$/i.test(mod)) + meta = true; + else if (/^a(lt)?$/i.test(mod)) + alt = true; + else if (/^(c|ctrl|control)$/i.test(mod)) + ctrl = true; + else if (/^s(hift)?$/i.test(mod)) + shift2 = true; + else if (/^mod$/i.test(mod)) { + if (mac3) + meta = true; + else + ctrl = true; + } else + throw new Error("Unrecognized modifier name: " + mod); + } + if (alt) + result = "Alt-" + result; + if (ctrl) + result = "Ctrl-" + result; + if (meta) + result = "Meta-" + result; + if (shift2) + result = "Shift-" + result; + return result; +} +function normalize(map) { + let copy2 = /* @__PURE__ */ Object.create(null); + for (let prop in map) + copy2[normalizeKeyName(prop)] = map[prop]; + return copy2; +} +function modifiers(name, event, shift2 = true) { + if (event.altKey) + name = "Alt-" + name; + if (event.ctrlKey) + name = "Ctrl-" + name; + if (event.metaKey) + name = "Meta-" + name; + if (shift2 && event.shiftKey) + name = "Shift-" + name; + return name; +} +function keymap(bindings) { + return new Plugin({ props: { handleKeyDown: keydownHandler(bindings) } }); +} +function keydownHandler(bindings) { + let map = normalize(bindings); + return function(view, event) { + let name = keyName(event), baseName, direct = map[modifiers(name, event)]; + if (direct && direct(view.state, view.dispatch, view)) + return true; + if (name.length == 1 && name != " ") { + if (event.shiftKey) { + let noShift = map[modifiers(name, event, false)]; + if (noShift && noShift(view.state, view.dispatch, view)) + return true; + } + if ((event.altKey || event.metaKey || event.ctrlKey) && // Ctrl-Alt may be used for AltGr on Windows + !(windows2 && event.ctrlKey && event.altKey) && (baseName = base[event.keyCode]) && baseName != name) { + let fromCode = map[modifiers(baseName, event)]; + if (fromCode && fromCode(view.state, view.dispatch, view)) + return true; + } + } + return false; + }; +} + +// node_modules/prosemirror-commands/dist/index.js +var deleteSelection = (state, dispatch) => { + if (state.selection.empty) + return false; + if (dispatch) + dispatch(state.tr.deleteSelection().scrollIntoView()); + return true; +}; +function atBlockStart(state, view) { + let { $cursor } = state.selection; + if (!$cursor || (view ? !view.endOfTextblock("backward", state) : $cursor.parentOffset > 0)) + return null; + return $cursor; +} +var joinBackward = (state, dispatch, view) => { + let $cursor = atBlockStart(state, view); + if (!$cursor) + return false; + let $cut = findCutBefore($cursor); + if (!$cut) { + let range = $cursor.blockRange(), target = range && liftTarget(range); + if (target == null) + return false; + if (dispatch) + dispatch(state.tr.lift(range, target).scrollIntoView()); + return true; + } + let before = $cut.nodeBefore; + if (deleteBarrier(state, $cut, dispatch, -1)) + return true; + if ($cursor.parent.content.size == 0 && (textblockAt(before, "end") || NodeSelection.isSelectable(before))) { + for (let depth = $cursor.depth; ; depth--) { + let delStep = replaceStep(state.doc, $cursor.before(depth), $cursor.after(depth), Slice.empty); + if (delStep && delStep.slice.size < delStep.to - delStep.from) { + if (dispatch) { + let tr = state.tr.step(delStep); + tr.setSelection(textblockAt(before, "end") ? Selection.findFrom(tr.doc.resolve(tr.mapping.map($cut.pos, -1)), -1) : NodeSelection.create(tr.doc, $cut.pos - before.nodeSize)); + dispatch(tr.scrollIntoView()); + } + return true; + } + if (depth == 1 || $cursor.node(depth - 1).childCount > 1) + break; + } + } + if (before.isAtom && $cut.depth == $cursor.depth - 1) { + if (dispatch) + dispatch(state.tr.delete($cut.pos - before.nodeSize, $cut.pos).scrollIntoView()); + return true; + } + return false; +}; +var joinTextblockBackward = (state, dispatch, view) => { + let $cursor = atBlockStart(state, view); + if (!$cursor) + return false; + let $cut = findCutBefore($cursor); + return $cut ? joinTextblocksAround(state, $cut, dispatch) : false; +}; +var joinTextblockForward = (state, dispatch, view) => { + let $cursor = atBlockEnd(state, view); + if (!$cursor) + return false; + let $cut = findCutAfter($cursor); + return $cut ? joinTextblocksAround(state, $cut, dispatch) : false; +}; +function joinTextblocksAround(state, $cut, dispatch) { + let before = $cut.nodeBefore, beforeText = before, beforePos = $cut.pos - 1; + for (; !beforeText.isTextblock; beforePos--) { + if (beforeText.type.spec.isolating) + return false; + let child = beforeText.lastChild; + if (!child) + return false; + beforeText = child; + } + let after = $cut.nodeAfter, afterText = after, afterPos = $cut.pos + 1; + for (; !afterText.isTextblock; afterPos++) { + if (afterText.type.spec.isolating) + return false; + let child = afterText.firstChild; + if (!child) + return false; + afterText = child; + } + let step = replaceStep(state.doc, beforePos, afterPos, Slice.empty); + if (!step || step.from != beforePos || step instanceof ReplaceStep && step.slice.size >= afterPos - beforePos) + return false; + if (dispatch) { + let tr = state.tr.step(step); + tr.setSelection(TextSelection.create(tr.doc, beforePos)); + dispatch(tr.scrollIntoView()); + } + return true; +} +function textblockAt(node, side, only = false) { + for (let scan = node; scan; scan = side == "start" ? scan.firstChild : scan.lastChild) { + if (scan.isTextblock) + return true; + if (only && scan.childCount != 1) + return false; + } + return false; +} +var selectNodeBackward = (state, dispatch, view) => { + let { $head, empty: empty2 } = state.selection, $cut = $head; + if (!empty2) + return false; + if ($head.parent.isTextblock) { + if (view ? !view.endOfTextblock("backward", state) : $head.parentOffset > 0) + return false; + $cut = findCutBefore($head); + } + let node = $cut && $cut.nodeBefore; + if (!node || !NodeSelection.isSelectable(node)) + return false; + if (dispatch) + dispatch(state.tr.setSelection(NodeSelection.create(state.doc, $cut.pos - node.nodeSize)).scrollIntoView()); + return true; +}; +function findCutBefore($pos) { + if (!$pos.parent.type.spec.isolating) + for (let i5 = $pos.depth - 1; i5 >= 0; i5--) { + if ($pos.index(i5) > 0) + return $pos.doc.resolve($pos.before(i5 + 1)); + if ($pos.node(i5).type.spec.isolating) + break; + } + return null; +} +function atBlockEnd(state, view) { + let { $cursor } = state.selection; + if (!$cursor || (view ? !view.endOfTextblock("forward", state) : $cursor.parentOffset < $cursor.parent.content.size)) + return null; + return $cursor; +} +var joinForward = (state, dispatch, view) => { + let $cursor = atBlockEnd(state, view); + if (!$cursor) + return false; + let $cut = findCutAfter($cursor); + if (!$cut) + return false; + let after = $cut.nodeAfter; + if (deleteBarrier(state, $cut, dispatch, 1)) + return true; + if ($cursor.parent.content.size == 0 && (textblockAt(after, "start") || NodeSelection.isSelectable(after))) { + let delStep = replaceStep(state.doc, $cursor.before(), $cursor.after(), Slice.empty); + if (delStep && delStep.slice.size < delStep.to - delStep.from) { + if (dispatch) { + let tr = state.tr.step(delStep); + tr.setSelection(textblockAt(after, "start") ? Selection.findFrom(tr.doc.resolve(tr.mapping.map($cut.pos)), 1) : NodeSelection.create(tr.doc, tr.mapping.map($cut.pos))); + dispatch(tr.scrollIntoView()); + } + return true; + } + } + if (after.isAtom && $cut.depth == $cursor.depth - 1) { + if (dispatch) + dispatch(state.tr.delete($cut.pos, $cut.pos + after.nodeSize).scrollIntoView()); + return true; + } + return false; +}; +var selectNodeForward = (state, dispatch, view) => { + let { $head, empty: empty2 } = state.selection, $cut = $head; + if (!empty2) + return false; + if ($head.parent.isTextblock) { + if (view ? !view.endOfTextblock("forward", state) : $head.parentOffset < $head.parent.content.size) + return false; + $cut = findCutAfter($head); + } + let node = $cut && $cut.nodeAfter; + if (!node || !NodeSelection.isSelectable(node)) + return false; + if (dispatch) + dispatch(state.tr.setSelection(NodeSelection.create(state.doc, $cut.pos)).scrollIntoView()); + return true; +}; +function findCutAfter($pos) { + if (!$pos.parent.type.spec.isolating) + for (let i5 = $pos.depth - 1; i5 >= 0; i5--) { + let parent = $pos.node(i5); + if ($pos.index(i5) + 1 < parent.childCount) + return $pos.doc.resolve($pos.after(i5 + 1)); + if (parent.type.spec.isolating) + break; + } + return null; +} +var joinUp = (state, dispatch) => { + let sel = state.selection, nodeSel = sel instanceof NodeSelection, point; + if (nodeSel) { + if (sel.node.isTextblock || !canJoin(state.doc, sel.from)) + return false; + point = sel.from; + } else { + point = joinPoint(state.doc, sel.from, -1); + if (point == null) + return false; + } + if (dispatch) { + let tr = state.tr.join(point); + if (nodeSel) + tr.setSelection(NodeSelection.create(tr.doc, point - state.doc.resolve(point).nodeBefore.nodeSize)); + dispatch(tr.scrollIntoView()); + } + return true; +}; +var joinDown = (state, dispatch) => { + let sel = state.selection, point; + if (sel instanceof NodeSelection) { + if (sel.node.isTextblock || !canJoin(state.doc, sel.to)) + return false; + point = sel.to; + } else { + point = joinPoint(state.doc, sel.to, 1); + if (point == null) + return false; + } + if (dispatch) + dispatch(state.tr.join(point).scrollIntoView()); + return true; +}; +var lift2 = (state, dispatch) => { + let { $from, $to } = state.selection; + let range = $from.blockRange($to), target = range && liftTarget(range); + if (target == null) + return false; + if (dispatch) + dispatch(state.tr.lift(range, target).scrollIntoView()); + return true; +}; +var newlineInCode = (state, dispatch) => { + let { $head, $anchor } = state.selection; + if (!$head.parent.type.spec.code || !$head.sameParent($anchor)) + return false; + if (dispatch) + dispatch(state.tr.insertText("\n").scrollIntoView()); + return true; +}; +function defaultBlockAt(match) { + for (let i5 = 0; i5 < match.edgeCount; i5++) { + let { type } = match.edge(i5); + if (type.isTextblock && !type.hasRequiredAttrs()) + return type; + } + return null; +} +var exitCode = (state, dispatch) => { + let { $head, $anchor } = state.selection; + if (!$head.parent.type.spec.code || !$head.sameParent($anchor)) + return false; + let above = $head.node(-1), after = $head.indexAfter(-1), type = defaultBlockAt(above.contentMatchAt(after)); + if (!type || !above.canReplaceWith(after, after, type)) + return false; + if (dispatch) { + let pos = $head.after(), tr = state.tr.replaceWith(pos, pos, type.createAndFill()); + tr.setSelection(Selection.near(tr.doc.resolve(pos), 1)); + dispatch(tr.scrollIntoView()); + } + return true; +}; +var createParagraphNear = (state, dispatch) => { + let sel = state.selection, { $from, $to } = sel; + if (sel instanceof AllSelection || $from.parent.inlineContent || $to.parent.inlineContent) + return false; + let type = defaultBlockAt($to.parent.contentMatchAt($to.indexAfter())); + if (!type || !type.isTextblock) + return false; + if (dispatch) { + let side = (!$from.parentOffset && $to.index() < $to.parent.childCount ? $from : $to).pos; + let tr = state.tr.insert(side, type.createAndFill()); + tr.setSelection(TextSelection.create(tr.doc, side + 1)); + dispatch(tr.scrollIntoView()); + } + return true; +}; +var liftEmptyBlock = (state, dispatch) => { + let { $cursor } = state.selection; + if (!$cursor || $cursor.parent.content.size) + return false; + if ($cursor.depth > 1 && $cursor.after() != $cursor.end(-1)) { + let before = $cursor.before(); + if (canSplit(state.doc, before)) { + if (dispatch) + dispatch(state.tr.split(before).scrollIntoView()); + return true; + } + } + let range = $cursor.blockRange(), target = range && liftTarget(range); + if (target == null) + return false; + if (dispatch) + dispatch(state.tr.lift(range, target).scrollIntoView()); + return true; +}; +function splitBlockAs(splitNode) { + return (state, dispatch) => { + let { $from, $to } = state.selection; + if (state.selection instanceof NodeSelection && state.selection.node.isBlock) { + if (!$from.parentOffset || !canSplit(state.doc, $from.pos)) + return false; + if (dispatch) + dispatch(state.tr.split($from.pos).scrollIntoView()); + return true; + } + if (!$from.depth) + return false; + let types = []; + let splitDepth, deflt, atEnd = false, atStart = false; + for (let d3 = $from.depth; ; d3--) { + let node = $from.node(d3); + if (node.isBlock) { + atEnd = $from.end(d3) == $from.pos + ($from.depth - d3); + atStart = $from.start(d3) == $from.pos - ($from.depth - d3); + deflt = defaultBlockAt($from.node(d3 - 1).contentMatchAt($from.indexAfter(d3 - 1))); + let splitType = splitNode && splitNode($to.parent, atEnd, $from); + types.unshift(splitType || (atEnd && deflt ? { type: deflt } : null)); + splitDepth = d3; + break; + } else { + if (d3 == 1) + return false; + types.unshift(null); + } + } + let tr = state.tr; + if (state.selection instanceof TextSelection || state.selection instanceof AllSelection) + tr.deleteSelection(); + let splitPos = tr.mapping.map($from.pos); + let can = canSplit(tr.doc, splitPos, types.length, types); + if (!can) { + types[0] = deflt ? { type: deflt } : null; + can = canSplit(tr.doc, splitPos, types.length, types); + } + if (!can) + return false; + tr.split(splitPos, types.length, types); + if (!atEnd && atStart && $from.node(splitDepth).type != deflt) { + let first2 = tr.mapping.map($from.before(splitDepth)), $first = tr.doc.resolve(first2); + if (deflt && $from.node(splitDepth - 1).canReplaceWith($first.index(), $first.index() + 1, deflt)) + tr.setNodeMarkup(tr.mapping.map($from.before(splitDepth)), deflt); + } + if (dispatch) + dispatch(tr.scrollIntoView()); + return true; + }; +} +var splitBlock = splitBlockAs(); +var selectParentNode = (state, dispatch) => { + let { $from, to } = state.selection, pos; + let same = $from.sharedDepth(to); + if (same == 0) + return false; + pos = $from.before(same); + if (dispatch) + dispatch(state.tr.setSelection(NodeSelection.create(state.doc, pos))); + return true; +}; +var selectAll = (state, dispatch) => { + if (dispatch) + dispatch(state.tr.setSelection(new AllSelection(state.doc))); + return true; +}; +function joinMaybeClear(state, $pos, dispatch) { + let before = $pos.nodeBefore, after = $pos.nodeAfter, index = $pos.index(); + if (!before || !after || !before.type.compatibleContent(after.type)) + return false; + if (!before.content.size && $pos.parent.canReplace(index - 1, index)) { + if (dispatch) + dispatch(state.tr.delete($pos.pos - before.nodeSize, $pos.pos).scrollIntoView()); + return true; + } + if (!$pos.parent.canReplace(index, index + 1) || !(after.isTextblock || canJoin(state.doc, $pos.pos))) + return false; + if (dispatch) + dispatch(state.tr.join($pos.pos).scrollIntoView()); + return true; +} +function deleteBarrier(state, $cut, dispatch, dir) { + let before = $cut.nodeBefore, after = $cut.nodeAfter, conn, match; + let isolated = before.type.spec.isolating || after.type.spec.isolating; + if (!isolated && joinMaybeClear(state, $cut, dispatch)) + return true; + let canDelAfter = !isolated && $cut.parent.canReplace($cut.index(), $cut.index() + 1); + if (canDelAfter && (conn = (match = before.contentMatchAt(before.childCount)).findWrapping(after.type)) && match.matchType(conn[0] || after.type).validEnd) { + if (dispatch) { + let end = $cut.pos + after.nodeSize, wrap2 = Fragment.empty; + for (let i5 = conn.length - 1; i5 >= 0; i5--) + wrap2 = Fragment.from(conn[i5].create(null, wrap2)); + wrap2 = Fragment.from(before.copy(wrap2)); + let tr = state.tr.step(new ReplaceAroundStep($cut.pos - 1, end, $cut.pos, end, new Slice(wrap2, 1, 0), conn.length, true)); + let $joinAt = tr.doc.resolve(end + 2 * conn.length); + if ($joinAt.nodeAfter && $joinAt.nodeAfter.type == before.type && canJoin(tr.doc, $joinAt.pos)) + tr.join($joinAt.pos); + dispatch(tr.scrollIntoView()); + } + return true; + } + let selAfter = after.type.spec.isolating || dir > 0 && isolated ? null : Selection.findFrom($cut, 1); + let range = selAfter && selAfter.$from.blockRange(selAfter.$to), target = range && liftTarget(range); + if (target != null && target >= $cut.depth) { + if (dispatch) + dispatch(state.tr.lift(range, target).scrollIntoView()); + return true; + } + if (canDelAfter && textblockAt(after, "start", true) && textblockAt(before, "end")) { + let at = before, wrap2 = []; + for (; ; ) { + wrap2.push(at); + if (at.isTextblock) + break; + at = at.lastChild; + } + let afterText = after, afterDepth = 1; + for (; !afterText.isTextblock; afterText = afterText.firstChild) + afterDepth++; + if (at.canReplace(at.childCount, at.childCount, afterText.content)) { + if (dispatch) { + let end = Fragment.empty; + for (let i5 = wrap2.length - 1; i5 >= 0; i5--) + end = Fragment.from(wrap2[i5].copy(end)); + let tr = state.tr.step(new ReplaceAroundStep($cut.pos - wrap2.length, $cut.pos + after.nodeSize, $cut.pos + afterDepth, $cut.pos + after.nodeSize - afterDepth, new Slice(end, wrap2.length, 0), 0, true)); + dispatch(tr.scrollIntoView()); + } + return true; + } + } + return false; +} +function selectTextblockSide(side) { + return function(state, dispatch) { + let sel = state.selection, $pos = side < 0 ? sel.$from : sel.$to; + let depth = $pos.depth; + while ($pos.node(depth).isInline) { + if (!depth) + return false; + depth--; + } + if (!$pos.node(depth).isTextblock) + return false; + if (dispatch) + dispatch(state.tr.setSelection(TextSelection.create(state.doc, side < 0 ? $pos.start(depth) : $pos.end(depth)))); + return true; + }; +} +var selectTextblockStart = selectTextblockSide(-1); +var selectTextblockEnd = selectTextblockSide(1); +function wrapIn(nodeType, attrs = null) { + return function(state, dispatch) { + let { $from, $to } = state.selection; + let range = $from.blockRange($to), wrapping = range && findWrapping(range, nodeType, attrs); + if (!wrapping) + return false; + if (dispatch) + dispatch(state.tr.wrap(range, wrapping).scrollIntoView()); + return true; + }; +} +function setBlockType2(nodeType, attrs = null) { + return function(state, dispatch) { + let applicable = false; + for (let i5 = 0; i5 < state.selection.ranges.length && !applicable; i5++) { + let { $from: { pos: from }, $to: { pos: to } } = state.selection.ranges[i5]; + state.doc.nodesBetween(from, to, (node, pos) => { + if (applicable) + return false; + if (!node.isTextblock || node.hasMarkup(nodeType, attrs)) + return; + if (node.type == nodeType) { + applicable = true; + } else { + let $pos = state.doc.resolve(pos), index = $pos.index(); + applicable = $pos.parent.canReplaceWith(index, index + 1, nodeType); + } + }); + } + if (!applicable) + return false; + if (dispatch) { + let tr = state.tr; + for (let i5 = 0; i5 < state.selection.ranges.length; i5++) { + let { $from: { pos: from }, $to: { pos: to } } = state.selection.ranges[i5]; + tr.setBlockType(from, to, nodeType, attrs); + } + dispatch(tr.scrollIntoView()); + } + return true; + }; +} +function chainCommands(...commands2) { + return function(state, dispatch, view) { + for (let i5 = 0; i5 < commands2.length; i5++) + if (commands2[i5](state, dispatch, view)) + return true; + return false; + }; +} +var backspace = chainCommands(deleteSelection, joinBackward, selectNodeBackward); +var del = chainCommands(deleteSelection, joinForward, selectNodeForward); +var pcBaseKeymap = { + "Enter": chainCommands(newlineInCode, createParagraphNear, liftEmptyBlock, splitBlock), + "Mod-Enter": exitCode, + "Backspace": backspace, + "Mod-Backspace": backspace, + "Shift-Backspace": backspace, + "Delete": del, + "Mod-Delete": del, + "Mod-a": selectAll +}; +var macBaseKeymap = { + "Ctrl-h": pcBaseKeymap["Backspace"], + "Alt-Backspace": pcBaseKeymap["Mod-Backspace"], + "Ctrl-d": pcBaseKeymap["Delete"], + "Ctrl-Alt-Backspace": pcBaseKeymap["Mod-Delete"], + "Alt-Delete": pcBaseKeymap["Mod-Delete"], + "Alt-d": pcBaseKeymap["Mod-Delete"], + "Ctrl-a": selectTextblockStart, + "Ctrl-e": selectTextblockEnd +}; +for (let key in pcBaseKeymap) + macBaseKeymap[key] = pcBaseKeymap[key]; +var mac4 = typeof navigator != "undefined" ? /Mac|iP(hone|[oa]d)/.test(navigator.platform) : typeof os != "undefined" && os.platform ? os.platform() == "darwin" : false; + +// node_modules/prosemirror-schema-list/dist/index.js +function wrapInList(listType, attrs = null) { + return function(state, dispatch) { + let { $from, $to } = state.selection; + let range = $from.blockRange($to); + if (!range) + return false; + let tr = dispatch ? state.tr : null; + if (!wrapRangeInList(tr, range, listType, attrs)) + return false; + if (dispatch) + dispatch(tr.scrollIntoView()); + return true; + }; +} +function wrapRangeInList(tr, range, listType, attrs = null) { + let doJoin = false, outerRange = range, doc3 = range.$from.doc; + if (range.depth >= 2 && range.$from.node(range.depth - 1).type.compatibleContent(listType) && range.startIndex == 0) { + if (range.$from.index(range.depth - 1) == 0) + return false; + let $insert = doc3.resolve(range.start - 2); + outerRange = new NodeRange($insert, $insert, range.depth); + if (range.endIndex < range.parent.childCount) + range = new NodeRange(range.$from, doc3.resolve(range.$to.end(range.depth)), range.depth); + doJoin = true; + } + let wrap2 = findWrapping(outerRange, listType, attrs, range); + if (!wrap2) + return false; + if (tr) + doWrapInList(tr, range, wrap2, doJoin, listType); + return true; +} +function doWrapInList(tr, range, wrappers, joinBefore, listType) { + let content = Fragment.empty; + for (let i5 = wrappers.length - 1; i5 >= 0; i5--) + content = Fragment.from(wrappers[i5].type.create(wrappers[i5].attrs, content)); + tr.step(new ReplaceAroundStep(range.start - (joinBefore ? 2 : 0), range.end, range.start, range.end, new Slice(content, 0, 0), wrappers.length, true)); + let found2 = 0; + for (let i5 = 0; i5 < wrappers.length; i5++) + if (wrappers[i5].type == listType) + found2 = i5 + 1; + let splitDepth = wrappers.length - found2; + let splitPos = range.start + wrappers.length - (joinBefore ? 2 : 0), parent = range.parent; + for (let i5 = range.startIndex, e4 = range.endIndex, first2 = true; i5 < e4; i5++, first2 = false) { + if (!first2 && canSplit(tr.doc, splitPos, splitDepth)) { + tr.split(splitPos, splitDepth); + splitPos += 2 * splitDepth; + } + splitPos += parent.child(i5).nodeSize; + } + return tr; +} +function liftListItem(itemType) { + return function(state, dispatch) { + let { $from, $to } = state.selection; + let range = $from.blockRange($to, (node) => node.childCount > 0 && node.firstChild.type == itemType); + if (!range) + return false; + if (!dispatch) + return true; + if ($from.node(range.depth - 1).type == itemType) + return liftToOuterList(state, dispatch, itemType, range); + else + return liftOutOfList(state, dispatch, range); + }; +} +function liftToOuterList(state, dispatch, itemType, range) { + let tr = state.tr, end = range.end, endOfList = range.$to.end(range.depth); + if (end < endOfList) { + tr.step(new ReplaceAroundStep(end - 1, endOfList, end, endOfList, new Slice(Fragment.from(itemType.create(null, range.parent.copy())), 1, 0), 1, true)); + range = new NodeRange(tr.doc.resolve(range.$from.pos), tr.doc.resolve(endOfList), range.depth); + } + const target = liftTarget(range); + if (target == null) + return false; + tr.lift(range, target); + let $after = tr.doc.resolve(tr.mapping.map(end, -1) - 1); + if (canJoin(tr.doc, $after.pos) && $after.nodeBefore.type == $after.nodeAfter.type) + tr.join($after.pos); + dispatch(tr.scrollIntoView()); + return true; +} +function liftOutOfList(state, dispatch, range) { + let tr = state.tr, list = range.parent; + for (let pos = range.end, i5 = range.endIndex - 1, e4 = range.startIndex; i5 > e4; i5--) { + pos -= list.child(i5).nodeSize; + tr.delete(pos - 1, pos + 1); + } + let $start = tr.doc.resolve(range.start), item = $start.nodeAfter; + if (tr.mapping.map(range.end) != range.start + $start.nodeAfter.nodeSize) + return false; + let atStart = range.startIndex == 0, atEnd = range.endIndex == list.childCount; + let parent = $start.node(-1), indexBefore = $start.index(-1); + if (!parent.canReplace(indexBefore + (atStart ? 0 : 1), indexBefore + 1, item.content.append(atEnd ? Fragment.empty : Fragment.from(list)))) + return false; + let start = $start.pos, end = start + item.nodeSize; + tr.step(new ReplaceAroundStep(start - (atStart ? 1 : 0), end + (atEnd ? 1 : 0), start + 1, end - 1, new Slice((atStart ? Fragment.empty : Fragment.from(list.copy(Fragment.empty))).append(atEnd ? Fragment.empty : Fragment.from(list.copy(Fragment.empty))), atStart ? 0 : 1, atEnd ? 0 : 1), atStart ? 0 : 1)); + dispatch(tr.scrollIntoView()); + return true; +} +function sinkListItem(itemType) { + return function(state, dispatch) { + let { $from, $to } = state.selection; + let range = $from.blockRange($to, (node) => node.childCount > 0 && node.firstChild.type == itemType); + if (!range) + return false; + let startIndex = range.startIndex; + if (startIndex == 0) + return false; + let parent = range.parent, nodeBefore = parent.child(startIndex - 1); + if (nodeBefore.type != itemType) + return false; + if (dispatch) { + let nestedBefore = nodeBefore.lastChild && nodeBefore.lastChild.type == parent.type; + let inner = Fragment.from(nestedBefore ? itemType.create() : null); + let slice = new Slice(Fragment.from(itemType.create(null, Fragment.from(parent.type.create(null, inner)))), nestedBefore ? 3 : 1, 0); + let before = range.start, after = range.end; + dispatch(state.tr.step(new ReplaceAroundStep(before - (nestedBefore ? 3 : 1), after, before, after, slice, 1, true)).scrollIntoView()); + } + return true; + }; +} + +// node_modules/@tiptap/core/dist/index.js +function createChainableState(config) { + const { state, transaction } = config; + let { selection } = transaction; + let { doc: doc3 } = transaction; + let { storedMarks } = transaction; + return { + ...state, + apply: state.apply.bind(state), + applyTransaction: state.applyTransaction.bind(state), + plugins: state.plugins, + schema: state.schema, + reconfigure: state.reconfigure.bind(state), + toJSON: state.toJSON.bind(state), + get storedMarks() { + return storedMarks; + }, + get selection() { + return selection; + }, + get doc() { + return doc3; + }, + get tr() { + selection = transaction.selection; + doc3 = transaction.doc; + storedMarks = transaction.storedMarks; + return transaction; + } + }; +} +var CommandManager = class { + constructor(props) { + this.editor = props.editor; + this.rawCommands = this.editor.extensionManager.commands; + this.customState = props.state; + } + get hasCustomState() { + return !!this.customState; + } + get state() { + return this.customState || this.editor.state; + } + get commands() { + const { rawCommands, editor, state } = this; + const { view } = editor; + const { tr } = state; + const props = this.buildProps(tr); + return Object.fromEntries(Object.entries(rawCommands).map(([name, command2]) => { + const method = (...args) => { + const callback = command2(...args)(props); + if (!tr.getMeta("preventDispatch") && !this.hasCustomState) { + view.dispatch(tr); + } + return callback; + }; + return [name, method]; + })); + } + get chain() { + return () => this.createChain(); + } + get can() { + return () => this.createCan(); + } + createChain(startTr, shouldDispatch = true) { + const { rawCommands, editor, state } = this; + const { view } = editor; + const callbacks = []; + const hasStartTransaction = !!startTr; + const tr = startTr || state.tr; + const run2 = () => { + if (!hasStartTransaction && shouldDispatch && !tr.getMeta("preventDispatch") && !this.hasCustomState) { + view.dispatch(tr); + } + return callbacks.every((callback) => callback === true); + }; + const chain = { + ...Object.fromEntries(Object.entries(rawCommands).map(([name, command2]) => { + const chainedCommand = (...args) => { + const props = this.buildProps(tr, shouldDispatch); + const callback = command2(...args)(props); + callbacks.push(callback); + return chain; + }; + return [name, chainedCommand]; + })), + run: run2 + }; + return chain; + } + createCan(startTr) { + const { rawCommands, state } = this; + const dispatch = false; + const tr = startTr || state.tr; + const props = this.buildProps(tr, dispatch); + const formattedCommands = Object.fromEntries(Object.entries(rawCommands).map(([name, command2]) => { + return [name, (...args) => command2(...args)({ ...props, dispatch: void 0 })]; + })); + return { + ...formattedCommands, + chain: () => this.createChain(tr, dispatch) + }; + } + buildProps(tr, shouldDispatch = true) { + const { rawCommands, editor, state } = this; + const { view } = editor; + const props = { + tr, + editor, + view, + state: createChainableState({ + state, + transaction: tr + }), + dispatch: shouldDispatch ? () => void 0 : void 0, + chain: () => this.createChain(tr, shouldDispatch), + can: () => this.createCan(tr), + get commands() { + return Object.fromEntries(Object.entries(rawCommands).map(([name, command2]) => { + return [name, (...args) => command2(...args)(props)]; + })); + } + }; + return props; + } +}; +var EventEmitter = class { + constructor() { + this.callbacks = {}; + } + on(event, fn) { + if (!this.callbacks[event]) { + this.callbacks[event] = []; + } + this.callbacks[event].push(fn); + return this; + } + emit(event, ...args) { + const callbacks = this.callbacks[event]; + if (callbacks) { + callbacks.forEach((callback) => callback.apply(this, args)); + } + return this; + } + off(event, fn) { + const callbacks = this.callbacks[event]; + if (callbacks) { + if (fn) { + this.callbacks[event] = callbacks.filter((callback) => callback !== fn); + } else { + delete this.callbacks[event]; + } + } + return this; + } + once(event, fn) { + const onceFn = (...args) => { + this.off(event, onceFn); + fn.apply(this, args); + }; + return this.on(event, onceFn); + } + removeAllListeners() { + this.callbacks = {}; + } +}; +function getExtensionField(extension, field, context) { + if (extension.config[field] === void 0 && extension.parent) { + return getExtensionField(extension.parent, field, context); + } + if (typeof extension.config[field] === "function") { + const value = extension.config[field].bind({ + ...context, + parent: extension.parent ? getExtensionField(extension.parent, field, context) : null + }); + return value; + } + return extension.config[field]; +} +function splitExtensions(extensions) { + const baseExtensions = extensions.filter((extension) => extension.type === "extension"); + const nodeExtensions = extensions.filter((extension) => extension.type === "node"); + const markExtensions = extensions.filter((extension) => extension.type === "mark"); + return { + baseExtensions, + nodeExtensions, + markExtensions + }; +} +function getAttributesFromExtensions(extensions) { + const extensionAttributes = []; + const { nodeExtensions, markExtensions } = splitExtensions(extensions); + const nodeAndMarkExtensions = [...nodeExtensions, ...markExtensions]; + const defaultAttribute = { + default: null, + rendered: true, + renderHTML: null, + parseHTML: null, + keepOnSplit: true, + isRequired: false + }; + extensions.forEach((extension) => { + const context = { + name: extension.name, + options: extension.options, + storage: extension.storage, + extensions: nodeAndMarkExtensions + }; + const addGlobalAttributes = getExtensionField(extension, "addGlobalAttributes", context); + if (!addGlobalAttributes) { + return; + } + const globalAttributes = addGlobalAttributes(); + globalAttributes.forEach((globalAttribute) => { + globalAttribute.types.forEach((type) => { + Object.entries(globalAttribute.attributes).forEach(([name, attribute]) => { + extensionAttributes.push({ + type, + name, + attribute: { + ...defaultAttribute, + ...attribute + } + }); + }); + }); + }); + }); + nodeAndMarkExtensions.forEach((extension) => { + const context = { + name: extension.name, + options: extension.options, + storage: extension.storage + }; + const addAttributes = getExtensionField(extension, "addAttributes", context); + if (!addAttributes) { + return; + } + const attributes = addAttributes(); + Object.entries(attributes).forEach(([name, attribute]) => { + const mergedAttr = { + ...defaultAttribute, + ...attribute + }; + if (typeof (mergedAttr === null || mergedAttr === void 0 ? void 0 : mergedAttr.default) === "function") { + mergedAttr.default = mergedAttr.default(); + } + if ((mergedAttr === null || mergedAttr === void 0 ? void 0 : mergedAttr.isRequired) && (mergedAttr === null || mergedAttr === void 0 ? void 0 : mergedAttr.default) === void 0) { + delete mergedAttr.default; + } + extensionAttributes.push({ + type: extension.name, + name, + attribute: mergedAttr + }); + }); + }); + return extensionAttributes; +} +function getNodeType(nameOrType, schema) { + if (typeof nameOrType === "string") { + if (!schema.nodes[nameOrType]) { + throw Error(`There is no node type named '${nameOrType}'. Maybe you forgot to add the extension?`); + } + return schema.nodes[nameOrType]; + } + return nameOrType; +} +function mergeAttributes(...objects) { + return objects.filter((item) => !!item).reduce((items, item) => { + const mergedAttributes = { ...items }; + Object.entries(item).forEach(([key, value]) => { + const exists = mergedAttributes[key]; + if (!exists) { + mergedAttributes[key] = value; + return; + } + if (key === "class") { + const valueClasses = value ? String(value).split(" ") : []; + const existingClasses = mergedAttributes[key] ? mergedAttributes[key].split(" ") : []; + const insertClasses = valueClasses.filter((valueClass) => !existingClasses.includes(valueClass)); + mergedAttributes[key] = [...existingClasses, ...insertClasses].join(" "); + } else if (key === "style") { + const newStyles = value ? value.split(";").map((style2) => style2.trim()).filter(Boolean) : []; + const existingStyles = mergedAttributes[key] ? mergedAttributes[key].split(";").map((style2) => style2.trim()).filter(Boolean) : []; + const styleMap = /* @__PURE__ */ new Map(); + existingStyles.forEach((style2) => { + const [property, val] = style2.split(":").map((part) => part.trim()); + styleMap.set(property, val); + }); + newStyles.forEach((style2) => { + const [property, val] = style2.split(":").map((part) => part.trim()); + styleMap.set(property, val); + }); + mergedAttributes[key] = Array.from(styleMap.entries()).map(([property, val]) => `${property}: ${val}`).join("; "); + } else { + mergedAttributes[key] = value; + } + }); + return mergedAttributes; + }, {}); +} +function getRenderedAttributes(nodeOrMark, extensionAttributes) { + return extensionAttributes.filter((attribute) => attribute.type === nodeOrMark.type.name).filter((item) => item.attribute.rendered).map((item) => { + if (!item.attribute.renderHTML) { + return { + [item.name]: nodeOrMark.attrs[item.name] + }; + } + return item.attribute.renderHTML(nodeOrMark.attrs) || {}; + }).reduce((attributes, attribute) => mergeAttributes(attributes, attribute), {}); +} +function isFunction(value) { + return typeof value === "function"; +} +function callOrReturn(value, context = void 0, ...props) { + if (isFunction(value)) { + if (context) { + return value.bind(context)(...props); + } + return value(...props); + } + return value; +} +function isEmptyObject(value = {}) { + return Object.keys(value).length === 0 && value.constructor === Object; +} +function fromString(value) { + if (typeof value !== "string") { + return value; + } + if (value.match(/^[+-]?(?:\d*\.)?\d+$/)) { + return Number(value); + } + if (value === "true") { + return true; + } + if (value === "false") { + return false; + } + return value; +} +function injectExtensionAttributesToParseRule(parseRule, extensionAttributes) { + if ("style" in parseRule) { + return parseRule; + } + return { + ...parseRule, + getAttrs: (node) => { + const oldAttributes = parseRule.getAttrs ? parseRule.getAttrs(node) : parseRule.attrs; + if (oldAttributes === false) { + return false; + } + const newAttributes = extensionAttributes.reduce((items, item) => { + const value = item.attribute.parseHTML ? item.attribute.parseHTML(node) : fromString(node.getAttribute(item.name)); + if (value === null || value === void 0) { + return items; + } + return { + ...items, + [item.name]: value + }; + }, {}); + return { ...oldAttributes, ...newAttributes }; + } + }; +} +function cleanUpSchemaItem(data) { + return Object.fromEntries( + // @ts-ignore + Object.entries(data).filter(([key, value]) => { + if (key === "attrs" && isEmptyObject(value)) { + return false; + } + return value !== null && value !== void 0; + }) + ); +} +function getSchemaByResolvedExtensions(extensions, editor) { + var _a; + const allAttributes = getAttributesFromExtensions(extensions); + const { nodeExtensions, markExtensions } = splitExtensions(extensions); + const topNode = (_a = nodeExtensions.find((extension) => getExtensionField(extension, "topNode"))) === null || _a === void 0 ? void 0 : _a.name; + const nodes = Object.fromEntries(nodeExtensions.map((extension) => { + const extensionAttributes = allAttributes.filter((attribute) => attribute.type === extension.name); + const context = { + name: extension.name, + options: extension.options, + storage: extension.storage, + editor + }; + const extraNodeFields = extensions.reduce((fields, e4) => { + const extendNodeSchema = getExtensionField(e4, "extendNodeSchema", context); + return { + ...fields, + ...extendNodeSchema ? extendNodeSchema(extension) : {} + }; + }, {}); + const schema = cleanUpSchemaItem({ + ...extraNodeFields, + content: callOrReturn(getExtensionField(extension, "content", context)), + marks: callOrReturn(getExtensionField(extension, "marks", context)), + group: callOrReturn(getExtensionField(extension, "group", context)), + inline: callOrReturn(getExtensionField(extension, "inline", context)), + atom: callOrReturn(getExtensionField(extension, "atom", context)), + selectable: callOrReturn(getExtensionField(extension, "selectable", context)), + draggable: callOrReturn(getExtensionField(extension, "draggable", context)), + code: callOrReturn(getExtensionField(extension, "code", context)), + whitespace: callOrReturn(getExtensionField(extension, "whitespace", context)), + linebreakReplacement: callOrReturn(getExtensionField(extension, "linebreakReplacement", context)), + defining: callOrReturn(getExtensionField(extension, "defining", context)), + isolating: callOrReturn(getExtensionField(extension, "isolating", context)), + attrs: Object.fromEntries(extensionAttributes.map((extensionAttribute) => { + var _a2; + return [extensionAttribute.name, { default: (_a2 = extensionAttribute === null || extensionAttribute === void 0 ? void 0 : extensionAttribute.attribute) === null || _a2 === void 0 ? void 0 : _a2.default }]; + })) + }); + const parseHTML = callOrReturn(getExtensionField(extension, "parseHTML", context)); + if (parseHTML) { + schema.parseDOM = parseHTML.map((parseRule) => injectExtensionAttributesToParseRule(parseRule, extensionAttributes)); + } + const renderHTML = getExtensionField(extension, "renderHTML", context); + if (renderHTML) { + schema.toDOM = (node) => renderHTML({ + node, + HTMLAttributes: getRenderedAttributes(node, extensionAttributes) + }); + } + const renderText = getExtensionField(extension, "renderText", context); + if (renderText) { + schema.toText = renderText; + } + return [extension.name, schema]; + })); + const marks = Object.fromEntries(markExtensions.map((extension) => { + const extensionAttributes = allAttributes.filter((attribute) => attribute.type === extension.name); + const context = { + name: extension.name, + options: extension.options, + storage: extension.storage, + editor + }; + const extraMarkFields = extensions.reduce((fields, e4) => { + const extendMarkSchema = getExtensionField(e4, "extendMarkSchema", context); + return { + ...fields, + ...extendMarkSchema ? extendMarkSchema(extension) : {} + }; + }, {}); + const schema = cleanUpSchemaItem({ + ...extraMarkFields, + inclusive: callOrReturn(getExtensionField(extension, "inclusive", context)), + excludes: callOrReturn(getExtensionField(extension, "excludes", context)), + group: callOrReturn(getExtensionField(extension, "group", context)), + spanning: callOrReturn(getExtensionField(extension, "spanning", context)), + code: callOrReturn(getExtensionField(extension, "code", context)), + attrs: Object.fromEntries(extensionAttributes.map((extensionAttribute) => { + var _a2; + return [extensionAttribute.name, { default: (_a2 = extensionAttribute === null || extensionAttribute === void 0 ? void 0 : extensionAttribute.attribute) === null || _a2 === void 0 ? void 0 : _a2.default }]; + })) + }); + const parseHTML = callOrReturn(getExtensionField(extension, "parseHTML", context)); + if (parseHTML) { + schema.parseDOM = parseHTML.map((parseRule) => injectExtensionAttributesToParseRule(parseRule, extensionAttributes)); + } + const renderHTML = getExtensionField(extension, "renderHTML", context); + if (renderHTML) { + schema.toDOM = (mark) => renderHTML({ + mark, + HTMLAttributes: getRenderedAttributes(mark, extensionAttributes) + }); + } + return [extension.name, schema]; + })); + return new Schema({ + topNode, + nodes, + marks + }); +} +function getSchemaTypeByName(name, schema) { + return schema.nodes[name] || schema.marks[name] || null; +} +function isExtensionRulesEnabled(extension, enabled) { + if (Array.isArray(enabled)) { + return enabled.some((enabledExtension) => { + const name = typeof enabledExtension === "string" ? enabledExtension : enabledExtension.name; + return name === extension.name; + }); + } + return enabled; +} +function getHTMLFromFragment(fragment, schema) { + const documentFragment = DOMSerializer.fromSchema(schema).serializeFragment(fragment); + const temporaryDocument = document.implementation.createHTMLDocument(); + const container = temporaryDocument.createElement("div"); + container.appendChild(documentFragment); + return container.innerHTML; +} +var getTextContentFromNodes = ($from, maxMatch = 500) => { + let textBefore = ""; + const sliceEndPos = $from.parentOffset; + $from.parent.nodesBetween(Math.max(0, sliceEndPos - maxMatch), sliceEndPos, (node, pos, parent, index) => { + var _a, _b; + const chunk = ((_b = (_a = node.type.spec).toText) === null || _b === void 0 ? void 0 : _b.call(_a, { + node, + pos, + parent, + index + })) || node.textContent || "%leaf%"; + textBefore += node.isAtom && !node.isText ? chunk : chunk.slice(0, Math.max(0, sliceEndPos - pos)); + }); + return textBefore; +}; +function isRegExp(value) { + return Object.prototype.toString.call(value) === "[object RegExp]"; +} +var InputRule = class { + constructor(config) { + this.find = config.find; + this.handler = config.handler; + } +}; +var inputRuleMatcherHandler = (text, find) => { + if (isRegExp(find)) { + return find.exec(text); + } + const inputRuleMatch = find(text); + if (!inputRuleMatch) { + return null; + } + const result = [inputRuleMatch.text]; + result.index = inputRuleMatch.index; + result.input = text; + result.data = inputRuleMatch.data; + if (inputRuleMatch.replaceWith) { + if (!inputRuleMatch.text.includes(inputRuleMatch.replaceWith)) { + console.warn('[tiptap warn]: "inputRuleMatch.replaceWith" must be part of "inputRuleMatch.text".'); + } + result.push(inputRuleMatch.replaceWith); + } + return result; +}; +function run$1(config) { + var _a; + const { editor, from, to, text, rules, plugin } = config; + const { view } = editor; + if (view.composing) { + return false; + } + const $from = view.state.doc.resolve(from); + if ( + // check for code node + $from.parent.type.spec.code || !!((_a = $from.nodeBefore || $from.nodeAfter) === null || _a === void 0 ? void 0 : _a.marks.find((mark) => mark.type.spec.code)) + ) { + return false; + } + let matched = false; + const textBefore = getTextContentFromNodes($from) + text; + rules.forEach((rule) => { + if (matched) { + return; + } + const match = inputRuleMatcherHandler(textBefore, rule.find); + if (!match) { + return; + } + const tr = view.state.tr; + const state = createChainableState({ + state: view.state, + transaction: tr + }); + const range = { + from: from - (match[0].length - text.length), + to + }; + const { commands: commands2, chain, can } = new CommandManager({ + editor, + state + }); + const handler = rule.handler({ + state, + range, + match, + commands: commands2, + chain, + can + }); + if (handler === null || !tr.steps.length) { + return; + } + tr.setMeta(plugin, { + transform: tr, + from, + to, + text + }); + view.dispatch(tr); + matched = true; + }); + return matched; +} +function inputRulesPlugin(props) { + const { editor, rules } = props; + const plugin = new Plugin({ + state: { + init() { + return null; + }, + apply(tr, prev, state) { + const stored = tr.getMeta(plugin); + if (stored) { + return stored; + } + const simulatedInputMeta = tr.getMeta("applyInputRules"); + const isSimulatedInput = !!simulatedInputMeta; + if (isSimulatedInput) { + setTimeout(() => { + let { text } = simulatedInputMeta; + if (typeof text === "string") { + text = text; + } else { + text = getHTMLFromFragment(Fragment.from(text), state.schema); + } + const { from } = simulatedInputMeta; + const to = from + text.length; + run$1({ + editor, + from, + to, + text, + rules, + plugin + }); + }); + } + return tr.selectionSet || tr.docChanged ? null : prev; + } + }, + props: { + handleTextInput(view, from, to, text) { + return run$1({ + editor, + from, + to, + text, + rules, + plugin + }); + }, + handleDOMEvents: { + compositionend: (view) => { + setTimeout(() => { + const { $cursor } = view.state.selection; + if ($cursor) { + run$1({ + editor, + from: $cursor.pos, + to: $cursor.pos, + text: "", + rules, + plugin + }); + } + }); + return false; + } + }, + // add support for input rules to trigger on enter + // this is useful for example for code blocks + handleKeyDown(view, event) { + if (event.key !== "Enter") { + return false; + } + const { $cursor } = view.state.selection; + if ($cursor) { + return run$1({ + editor, + from: $cursor.pos, + to: $cursor.pos, + text: "\n", + rules, + plugin + }); + } + return false; + } + }, + // @ts-ignore + isInputRules: true + }); + return plugin; +} +function getType(value) { + return Object.prototype.toString.call(value).slice(8, -1); +} +function isPlainObject(value) { + if (getType(value) !== "Object") { + return false; + } + return value.constructor === Object && Object.getPrototypeOf(value) === Object.prototype; +} +function mergeDeep(target, source) { + const output = { ...target }; + if (isPlainObject(target) && isPlainObject(source)) { + Object.keys(source).forEach((key) => { + if (isPlainObject(source[key]) && isPlainObject(target[key])) { + output[key] = mergeDeep(target[key], source[key]); + } else { + output[key] = source[key]; + } + }); + } + return output; +} +var Mark2 = class _Mark { + constructor(config = {}) { + this.type = "mark"; + this.name = "mark"; + this.parent = null; + this.child = null; + this.config = { + name: this.name, + defaultOptions: {} + }; + this.config = { + ...this.config, + ...config + }; + this.name = this.config.name; + if (config.defaultOptions && Object.keys(config.defaultOptions).length > 0) { + console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${this.name}".`); + } + this.options = this.config.defaultOptions; + if (this.config.addOptions) { + this.options = callOrReturn(getExtensionField(this, "addOptions", { + name: this.name + })); + } + this.storage = callOrReturn(getExtensionField(this, "addStorage", { + name: this.name, + options: this.options + })) || {}; + } + static create(config = {}) { + return new _Mark(config); + } + configure(options = {}) { + const extension = this.extend({ + ...this.config, + addOptions: () => { + return mergeDeep(this.options, options); + } + }); + extension.name = this.name; + extension.parent = this.parent; + return extension; + } + extend(extendedConfig = {}) { + const extension = new _Mark(extendedConfig); + extension.parent = this; + this.child = extension; + extension.name = extendedConfig.name ? extendedConfig.name : extension.parent.name; + if (extendedConfig.defaultOptions && Object.keys(extendedConfig.defaultOptions).length > 0) { + console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${extension.name}".`); + } + extension.options = callOrReturn(getExtensionField(extension, "addOptions", { + name: extension.name + })); + extension.storage = callOrReturn(getExtensionField(extension, "addStorage", { + name: extension.name, + options: extension.options + })); + return extension; + } + static handleExit({ editor, mark }) { + const { tr } = editor.state; + const currentPos = editor.state.selection.$from; + const isAtEnd = currentPos.pos === currentPos.end(); + if (isAtEnd) { + const currentMarks = currentPos.marks(); + const isInMark = !!currentMarks.find((m2) => (m2 === null || m2 === void 0 ? void 0 : m2.type.name) === mark.name); + if (!isInMark) { + return false; + } + const removeMark2 = currentMarks.find((m2) => (m2 === null || m2 === void 0 ? void 0 : m2.type.name) === mark.name); + if (removeMark2) { + tr.removeStoredMark(removeMark2); + } + tr.insertText(" ", currentPos.pos); + editor.view.dispatch(tr); + return true; + } + return false; + } +}; +function isNumber(value) { + return typeof value === "number"; +} +var PasteRule = class { + constructor(config) { + this.find = config.find; + this.handler = config.handler; + } +}; +var pasteRuleMatcherHandler = (text, find, event) => { + if (isRegExp(find)) { + return [...text.matchAll(find)]; + } + const matches2 = find(text, event); + if (!matches2) { + return []; + } + return matches2.map((pasteRuleMatch) => { + const result = [pasteRuleMatch.text]; + result.index = pasteRuleMatch.index; + result.input = text; + result.data = pasteRuleMatch.data; + if (pasteRuleMatch.replaceWith) { + if (!pasteRuleMatch.text.includes(pasteRuleMatch.replaceWith)) { + console.warn('[tiptap warn]: "pasteRuleMatch.replaceWith" must be part of "pasteRuleMatch.text".'); + } + result.push(pasteRuleMatch.replaceWith); + } + return result; + }); +}; +function run(config) { + const { editor, state, from, to, rule, pasteEvent, dropEvent } = config; + const { commands: commands2, chain, can } = new CommandManager({ + editor, + state + }); + const handlers2 = []; + state.doc.nodesBetween(from, to, (node, pos) => { + if (!node.isTextblock || node.type.spec.code) { + return; + } + const resolvedFrom = Math.max(from, pos); + const resolvedTo = Math.min(to, pos + node.content.size); + const textToMatch = node.textBetween(resolvedFrom - pos, resolvedTo - pos, void 0, "\uFFFC"); + const matches2 = pasteRuleMatcherHandler(textToMatch, rule.find, pasteEvent); + matches2.forEach((match) => { + if (match.index === void 0) { + return; + } + const start = resolvedFrom + match.index + 1; + const end = start + match[0].length; + const range = { + from: state.tr.mapping.map(start), + to: state.tr.mapping.map(end) + }; + const handler = rule.handler({ + state, + range, + match, + commands: commands2, + chain, + can, + pasteEvent, + dropEvent + }); + handlers2.push(handler); + }); + }); + const success = handlers2.every((handler) => handler !== null); + return success; +} +var tiptapDragFromOtherEditor = null; +var createClipboardPasteEvent = (text) => { + var _a; + const event = new ClipboardEvent("paste", { + clipboardData: new DataTransfer() + }); + (_a = event.clipboardData) === null || _a === void 0 ? void 0 : _a.setData("text/html", text); + return event; +}; +function pasteRulesPlugin(props) { + const { editor, rules } = props; + let dragSourceElement = null; + let isPastedFromProseMirror = false; + let isDroppedFromProseMirror = false; + let pasteEvent = typeof ClipboardEvent !== "undefined" ? new ClipboardEvent("paste") : null; + let dropEvent; + try { + dropEvent = typeof DragEvent !== "undefined" ? new DragEvent("drop") : null; + } catch { + dropEvent = null; + } + const processEvent = ({ state, from, to, rule, pasteEvt }) => { + const tr = state.tr; + const chainableState = createChainableState({ + state, + transaction: tr + }); + const handler = run({ + editor, + state: chainableState, + from: Math.max(from - 1, 0), + to: to.b - 1, + rule, + pasteEvent: pasteEvt, + dropEvent + }); + if (!handler || !tr.steps.length) { + return; + } + try { + dropEvent = typeof DragEvent !== "undefined" ? new DragEvent("drop") : null; + } catch { + dropEvent = null; + } + pasteEvent = typeof ClipboardEvent !== "undefined" ? new ClipboardEvent("paste") : null; + return tr; + }; + const plugins = rules.map((rule) => { + return new Plugin({ + // we register a global drag handler to track the current drag source element + view(view) { + const handleDragstart = (event) => { + var _a; + dragSourceElement = ((_a = view.dom.parentElement) === null || _a === void 0 ? void 0 : _a.contains(event.target)) ? view.dom.parentElement : null; + if (dragSourceElement) { + tiptapDragFromOtherEditor = editor; + } + }; + const handleDragend = () => { + if (tiptapDragFromOtherEditor) { + tiptapDragFromOtherEditor = null; + } + }; + window.addEventListener("dragstart", handleDragstart); + window.addEventListener("dragend", handleDragend); + return { + destroy() { + window.removeEventListener("dragstart", handleDragstart); + window.removeEventListener("dragend", handleDragend); + } + }; + }, + props: { + handleDOMEvents: { + drop: (view, event) => { + isDroppedFromProseMirror = dragSourceElement === view.dom.parentElement; + dropEvent = event; + if (!isDroppedFromProseMirror) { + const dragFromOtherEditor = tiptapDragFromOtherEditor; + if (dragFromOtherEditor) { + setTimeout(() => { + const selection = dragFromOtherEditor.state.selection; + if (selection) { + dragFromOtherEditor.commands.deleteRange({ from: selection.from, to: selection.to }); + } + }, 10); + } + } + return false; + }, + paste: (_view, event) => { + var _a; + const html = (_a = event.clipboardData) === null || _a === void 0 ? void 0 : _a.getData("text/html"); + pasteEvent = event; + isPastedFromProseMirror = !!(html === null || html === void 0 ? void 0 : html.includes("data-pm-slice")); + return false; + } + } + }, + appendTransaction: (transactions, oldState, state) => { + const transaction = transactions[0]; + const isPaste = transaction.getMeta("uiEvent") === "paste" && !isPastedFromProseMirror; + const isDrop = transaction.getMeta("uiEvent") === "drop" && !isDroppedFromProseMirror; + const simulatedPasteMeta = transaction.getMeta("applyPasteRules"); + const isSimulatedPaste = !!simulatedPasteMeta; + if (!isPaste && !isDrop && !isSimulatedPaste) { + return; + } + if (isSimulatedPaste) { + let { text } = simulatedPasteMeta; + if (typeof text === "string") { + text = text; + } else { + text = getHTMLFromFragment(Fragment.from(text), state.schema); + } + const { from: from2 } = simulatedPasteMeta; + const to2 = from2 + text.length; + const pasteEvt = createClipboardPasteEvent(text); + return processEvent({ + rule, + state, + from: from2, + to: { b: to2 }, + pasteEvt + }); + } + const from = oldState.doc.content.findDiffStart(state.doc.content); + const to = oldState.doc.content.findDiffEnd(state.doc.content); + if (!isNumber(from) || !to || from === to.b) { + return; + } + return processEvent({ + rule, + state, + from, + to, + pasteEvt: pasteEvent + }); + } + }); + }); + return plugins; +} +function findDuplicates(items) { + const filtered = items.filter((el, index) => items.indexOf(el) !== index); + return Array.from(new Set(filtered)); +} +var ExtensionManager = class _ExtensionManager { + constructor(extensions, editor) { + this.splittableMarks = []; + this.editor = editor; + this.extensions = _ExtensionManager.resolve(extensions); + this.schema = getSchemaByResolvedExtensions(this.extensions, editor); + this.setupExtensions(); + } + /** + * Returns a flattened and sorted extension list while + * also checking for duplicated extensions and warns the user. + * @param extensions An array of Tiptap extensions + * @returns An flattened and sorted array of Tiptap extensions + */ + static resolve(extensions) { + const resolvedExtensions = _ExtensionManager.sort(_ExtensionManager.flatten(extensions)); + const duplicatedNames = findDuplicates(resolvedExtensions.map((extension) => extension.name)); + if (duplicatedNames.length) { + console.warn(`[tiptap warn]: Duplicate extension names found: [${duplicatedNames.map((item) => `'${item}'`).join(", ")}]. This can lead to issues.`); + } + return resolvedExtensions; + } + /** + * Create a flattened array of extensions by traversing the `addExtensions` field. + * @param extensions An array of Tiptap extensions + * @returns A flattened array of Tiptap extensions + */ + static flatten(extensions) { + return extensions.map((extension) => { + const context = { + name: extension.name, + options: extension.options, + storage: extension.storage + }; + const addExtensions = getExtensionField(extension, "addExtensions", context); + if (addExtensions) { + return [extension, ...this.flatten(addExtensions())]; + } + return extension; + }).flat(10); + } + /** + * Sort extensions by priority. + * @param extensions An array of Tiptap extensions + * @returns A sorted array of Tiptap extensions by priority + */ + static sort(extensions) { + const defaultPriority = 100; + return extensions.sort((a3, b3) => { + const priorityA = getExtensionField(a3, "priority") || defaultPriority; + const priorityB = getExtensionField(b3, "priority") || defaultPriority; + if (priorityA > priorityB) { + return -1; + } + if (priorityA < priorityB) { + return 1; + } + return 0; + }); + } + /** + * Get all commands from the extensions. + * @returns An object with all commands where the key is the command name and the value is the command function + */ + get commands() { + return this.extensions.reduce((commands2, extension) => { + const context = { + name: extension.name, + options: extension.options, + storage: extension.storage, + editor: this.editor, + type: getSchemaTypeByName(extension.name, this.schema) + }; + const addCommands = getExtensionField(extension, "addCommands", context); + if (!addCommands) { + return commands2; + } + return { + ...commands2, + ...addCommands() + }; + }, {}); + } + /** + * Get all registered Prosemirror plugins from the extensions. + * @returns An array of Prosemirror plugins + */ + get plugins() { + const { editor } = this; + const extensions = _ExtensionManager.sort([...this.extensions].reverse()); + const inputRules = []; + const pasteRules = []; + const allPlugins = extensions.map((extension) => { + const context = { + name: extension.name, + options: extension.options, + storage: extension.storage, + editor, + type: getSchemaTypeByName(extension.name, this.schema) + }; + const plugins = []; + const addKeyboardShortcuts = getExtensionField(extension, "addKeyboardShortcuts", context); + let defaultBindings = {}; + if (extension.type === "mark" && getExtensionField(extension, "exitable", context)) { + defaultBindings.ArrowRight = () => Mark2.handleExit({ editor, mark: extension }); + } + if (addKeyboardShortcuts) { + const bindings = Object.fromEntries(Object.entries(addKeyboardShortcuts()).map(([shortcut, method]) => { + return [shortcut, () => method({ editor })]; + })); + defaultBindings = { ...defaultBindings, ...bindings }; + } + const keyMapPlugin = keymap(defaultBindings); + plugins.push(keyMapPlugin); + const addInputRules = getExtensionField(extension, "addInputRules", context); + if (isExtensionRulesEnabled(extension, editor.options.enableInputRules) && addInputRules) { + inputRules.push(...addInputRules()); + } + const addPasteRules = getExtensionField(extension, "addPasteRules", context); + if (isExtensionRulesEnabled(extension, editor.options.enablePasteRules) && addPasteRules) { + pasteRules.push(...addPasteRules()); + } + const addProseMirrorPlugins = getExtensionField(extension, "addProseMirrorPlugins", context); + if (addProseMirrorPlugins) { + const proseMirrorPlugins = addProseMirrorPlugins(); + plugins.push(...proseMirrorPlugins); + } + return plugins; + }).flat(); + return [ + inputRulesPlugin({ + editor, + rules: inputRules + }), + ...pasteRulesPlugin({ + editor, + rules: pasteRules + }), + ...allPlugins + ]; + } + /** + * Get all attributes from the extensions. + * @returns An array of attributes + */ + get attributes() { + return getAttributesFromExtensions(this.extensions); + } + /** + * Get all node views from the extensions. + * @returns An object with all node views where the key is the node name and the value is the node view function + */ + get nodeViews() { + const { editor } = this; + const { nodeExtensions } = splitExtensions(this.extensions); + return Object.fromEntries(nodeExtensions.filter((extension) => !!getExtensionField(extension, "addNodeView")).map((extension) => { + const extensionAttributes = this.attributes.filter((attribute) => attribute.type === extension.name); + const context = { + name: extension.name, + options: extension.options, + storage: extension.storage, + editor, + type: getNodeType(extension.name, this.schema) + }; + const addNodeView = getExtensionField(extension, "addNodeView", context); + if (!addNodeView) { + return []; + } + const nodeview = (node, view, getPos, decorations, innerDecorations) => { + const HTMLAttributes = getRenderedAttributes(node, extensionAttributes); + return addNodeView()({ + // pass-through + node, + view, + getPos, + decorations, + innerDecorations, + // tiptap-specific + editor, + extension, + HTMLAttributes + }); + }; + return [extension.name, nodeview]; + })); + } + /** + * Go through all extensions, create extension storages & setup marks + * & bind editor event listener. + */ + setupExtensions() { + this.extensions.forEach((extension) => { + var _a; + this.editor.extensionStorage[extension.name] = extension.storage; + const context = { + name: extension.name, + options: extension.options, + storage: extension.storage, + editor: this.editor, + type: getSchemaTypeByName(extension.name, this.schema) + }; + if (extension.type === "mark") { + const keepOnSplit = (_a = callOrReturn(getExtensionField(extension, "keepOnSplit", context))) !== null && _a !== void 0 ? _a : true; + if (keepOnSplit) { + this.splittableMarks.push(extension.name); + } + } + const onBeforeCreate = getExtensionField(extension, "onBeforeCreate", context); + const onCreate = getExtensionField(extension, "onCreate", context); + const onUpdate = getExtensionField(extension, "onUpdate", context); + const onSelectionUpdate = getExtensionField(extension, "onSelectionUpdate", context); + const onTransaction = getExtensionField(extension, "onTransaction", context); + const onFocus = getExtensionField(extension, "onFocus", context); + const onBlur = getExtensionField(extension, "onBlur", context); + const onDestroy = getExtensionField(extension, "onDestroy", context); + if (onBeforeCreate) { + this.editor.on("beforeCreate", onBeforeCreate); + } + if (onCreate) { + this.editor.on("create", onCreate); + } + if (onUpdate) { + this.editor.on("update", onUpdate); + } + if (onSelectionUpdate) { + this.editor.on("selectionUpdate", onSelectionUpdate); + } + if (onTransaction) { + this.editor.on("transaction", onTransaction); + } + if (onFocus) { + this.editor.on("focus", onFocus); + } + if (onBlur) { + this.editor.on("blur", onBlur); + } + if (onDestroy) { + this.editor.on("destroy", onDestroy); + } + }); + } +}; +var Extension = class _Extension { + constructor(config = {}) { + this.type = "extension"; + this.name = "extension"; + this.parent = null; + this.child = null; + this.config = { + name: this.name, + defaultOptions: {} + }; + this.config = { + ...this.config, + ...config + }; + this.name = this.config.name; + if (config.defaultOptions && Object.keys(config.defaultOptions).length > 0) { + console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${this.name}".`); + } + this.options = this.config.defaultOptions; + if (this.config.addOptions) { + this.options = callOrReturn(getExtensionField(this, "addOptions", { + name: this.name + })); + } + this.storage = callOrReturn(getExtensionField(this, "addStorage", { + name: this.name, + options: this.options + })) || {}; + } + static create(config = {}) { + return new _Extension(config); + } + configure(options = {}) { + const extension = this.extend({ + ...this.config, + addOptions: () => { + return mergeDeep(this.options, options); + } + }); + extension.name = this.name; + extension.parent = this.parent; + return extension; + } + extend(extendedConfig = {}) { + const extension = new _Extension({ ...this.config, ...extendedConfig }); + extension.parent = this; + this.child = extension; + extension.name = extendedConfig.name ? extendedConfig.name : extension.parent.name; + if (extendedConfig.defaultOptions && Object.keys(extendedConfig.defaultOptions).length > 0) { + console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${extension.name}".`); + } + extension.options = callOrReturn(getExtensionField(extension, "addOptions", { + name: extension.name + })); + extension.storage = callOrReturn(getExtensionField(extension, "addStorage", { + name: extension.name, + options: extension.options + })); + return extension; + } +}; +function getTextBetween(startNode, range, options) { + const { from, to } = range; + const { blockSeparator = "\n\n", textSerializers = {} } = options || {}; + let text = ""; + startNode.nodesBetween(from, to, (node, pos, parent, index) => { + var _a; + if (node.isBlock && pos > from) { + text += blockSeparator; + } + const textSerializer = textSerializers === null || textSerializers === void 0 ? void 0 : textSerializers[node.type.name]; + if (textSerializer) { + if (parent) { + text += textSerializer({ + node, + pos, + parent, + index, + range + }); + } + return false; + } + if (node.isText) { + text += (_a = node === null || node === void 0 ? void 0 : node.text) === null || _a === void 0 ? void 0 : _a.slice(Math.max(from, pos) - pos, to - pos); + } + }); + return text; +} +function getTextSerializersFromSchema(schema) { + return Object.fromEntries(Object.entries(schema.nodes).filter(([, node]) => node.spec.toText).map(([name, node]) => [name, node.spec.toText])); +} +var ClipboardTextSerializer = Extension.create({ + name: "clipboardTextSerializer", + addOptions() { + return { + blockSeparator: void 0 + }; + }, + addProseMirrorPlugins() { + return [ + new Plugin({ + key: new PluginKey("clipboardTextSerializer"), + props: { + clipboardTextSerializer: () => { + const { editor } = this; + const { state, schema } = editor; + const { doc: doc3, selection } = state; + const { ranges } = selection; + const from = Math.min(...ranges.map((range2) => range2.$from.pos)); + const to = Math.max(...ranges.map((range2) => range2.$to.pos)); + const textSerializers = getTextSerializersFromSchema(schema); + const range = { from, to }; + return getTextBetween(doc3, range, { + ...this.options.blockSeparator !== void 0 ? { blockSeparator: this.options.blockSeparator } : {}, + textSerializers + }); + } + } + }) + ]; + } +}); +var blur = () => ({ editor, view }) => { + requestAnimationFrame(() => { + var _a; + if (!editor.isDestroyed) { + view.dom.blur(); + (_a = window === null || window === void 0 ? void 0 : window.getSelection()) === null || _a === void 0 ? void 0 : _a.removeAllRanges(); + } + }); + return true; +}; +var clearContent = (emitUpdate = false) => ({ commands: commands2 }) => { + return commands2.setContent("", emitUpdate); +}; +var clearNodes = () => ({ state, tr, dispatch }) => { + const { selection } = tr; + const { ranges } = selection; + if (!dispatch) { + return true; + } + ranges.forEach(({ $from, $to }) => { + state.doc.nodesBetween($from.pos, $to.pos, (node, pos) => { + if (node.type.isText) { + return; + } + const { doc: doc3, mapping } = tr; + const $mappedFrom = doc3.resolve(mapping.map(pos)); + const $mappedTo = doc3.resolve(mapping.map(pos + node.nodeSize)); + const nodeRange = $mappedFrom.blockRange($mappedTo); + if (!nodeRange) { + return; + } + const targetLiftDepth = liftTarget(nodeRange); + if (node.type.isTextblock) { + const { defaultType } = $mappedFrom.parent.contentMatchAt($mappedFrom.index()); + tr.setNodeMarkup(nodeRange.start, defaultType); + } + if (targetLiftDepth || targetLiftDepth === 0) { + tr.lift(nodeRange, targetLiftDepth); + } + }); + }); + return true; +}; +var command = (fn) => (props) => { + return fn(props); +}; +var createParagraphNear2 = () => ({ state, dispatch }) => { + return createParagraphNear(state, dispatch); +}; +var cut = (originRange, targetPos) => ({ editor, tr }) => { + const { state } = editor; + const contentSlice = state.doc.slice(originRange.from, originRange.to); + tr.deleteRange(originRange.from, originRange.to); + const newPos = tr.mapping.map(targetPos); + tr.insert(newPos, contentSlice.content); + tr.setSelection(new TextSelection(tr.doc.resolve(newPos - 1))); + return true; +}; +var deleteCurrentNode = () => ({ tr, dispatch }) => { + const { selection } = tr; + const currentNode = selection.$anchor.node(); + if (currentNode.content.size > 0) { + return false; + } + const $pos = tr.selection.$anchor; + for (let depth = $pos.depth; depth > 0; depth -= 1) { + const node = $pos.node(depth); + if (node.type === currentNode.type) { + if (dispatch) { + const from = $pos.before(depth); + const to = $pos.after(depth); + tr.delete(from, to).scrollIntoView(); + } + return true; + } + } + return false; +}; +var deleteNode = (typeOrName) => ({ tr, state, dispatch }) => { + const type = getNodeType(typeOrName, state.schema); + const $pos = tr.selection.$anchor; + for (let depth = $pos.depth; depth > 0; depth -= 1) { + const node = $pos.node(depth); + if (node.type === type) { + if (dispatch) { + const from = $pos.before(depth); + const to = $pos.after(depth); + tr.delete(from, to).scrollIntoView(); + } + return true; + } + } + return false; +}; +var deleteRange2 = (range) => ({ tr, dispatch }) => { + const { from, to } = range; + if (dispatch) { + tr.delete(from, to); + } + return true; +}; +var deleteSelection2 = () => ({ state, dispatch }) => { + return deleteSelection(state, dispatch); +}; +var enter = () => ({ commands: commands2 }) => { + return commands2.keyboardShortcut("Enter"); +}; +var exitCode2 = () => ({ state, dispatch }) => { + return exitCode(state, dispatch); +}; +function objectIncludes(object1, object2, options = { strict: true }) { + const keys2 = Object.keys(object2); + if (!keys2.length) { + return true; + } + return keys2.every((key) => { + if (options.strict) { + return object2[key] === object1[key]; + } + if (isRegExp(object2[key])) { + return object2[key].test(object1[key]); + } + return object2[key] === object1[key]; + }); +} +function findMarkInSet(marks, type, attributes = {}) { + return marks.find((item) => { + return item.type === type && objectIncludes( + // Only check equality for the attributes that are provided + Object.fromEntries(Object.keys(attributes).map((k2) => [k2, item.attrs[k2]])), + attributes + ); + }); +} +function isMarkInSet(marks, type, attributes = {}) { + return !!findMarkInSet(marks, type, attributes); +} +function getMarkRange($pos, type, attributes) { + var _a; + if (!$pos || !type) { + return; + } + let start = $pos.parent.childAfter($pos.parentOffset); + if (!start.node || !start.node.marks.some((mark2) => mark2.type === type)) { + start = $pos.parent.childBefore($pos.parentOffset); + } + if (!start.node || !start.node.marks.some((mark2) => mark2.type === type)) { + return; + } + attributes = attributes || ((_a = start.node.marks[0]) === null || _a === void 0 ? void 0 : _a.attrs); + const mark = findMarkInSet([...start.node.marks], type, attributes); + if (!mark) { + return; + } + let startIndex = start.index; + let startPos = $pos.start() + start.offset; + let endIndex = startIndex + 1; + let endPos = startPos + start.node.nodeSize; + while (startIndex > 0 && isMarkInSet([...$pos.parent.child(startIndex - 1).marks], type, attributes)) { + startIndex -= 1; + startPos -= $pos.parent.child(startIndex).nodeSize; + } + while (endIndex < $pos.parent.childCount && isMarkInSet([...$pos.parent.child(endIndex).marks], type, attributes)) { + endPos += $pos.parent.child(endIndex).nodeSize; + endIndex += 1; + } + return { + from: startPos, + to: endPos + }; +} +function getMarkType(nameOrType, schema) { + if (typeof nameOrType === "string") { + if (!schema.marks[nameOrType]) { + throw Error(`There is no mark type named '${nameOrType}'. Maybe you forgot to add the extension?`); + } + return schema.marks[nameOrType]; + } + return nameOrType; +} +var extendMarkRange = (typeOrName, attributes = {}) => ({ tr, state, dispatch }) => { + const type = getMarkType(typeOrName, state.schema); + const { doc: doc3, selection } = tr; + const { $from, from, to } = selection; + if (dispatch) { + const range = getMarkRange($from, type, attributes); + if (range && range.from <= from && range.to >= to) { + const newSelection = TextSelection.create(doc3, range.from, range.to); + tr.setSelection(newSelection); + } + } + return true; +}; +var first = (commands2) => (props) => { + const items = typeof commands2 === "function" ? commands2(props) : commands2; + for (let i5 = 0; i5 < items.length; i5 += 1) { + if (items[i5](props)) { + return true; + } + } + return false; +}; +function isTextSelection(value) { + return value instanceof TextSelection; +} +function minMax(value = 0, min = 0, max = 0) { + return Math.min(Math.max(value, min), max); +} +function resolveFocusPosition(doc3, position = null) { + if (!position) { + return null; + } + const selectionAtStart = Selection.atStart(doc3); + const selectionAtEnd = Selection.atEnd(doc3); + if (position === "start" || position === true) { + return selectionAtStart; + } + if (position === "end") { + return selectionAtEnd; + } + const minPos = selectionAtStart.from; + const maxPos = selectionAtEnd.to; + if (position === "all") { + return TextSelection.create(doc3, minMax(0, minPos, maxPos), minMax(doc3.content.size, minPos, maxPos)); + } + return TextSelection.create(doc3, minMax(position, minPos, maxPos), minMax(position, minPos, maxPos)); +} +function isAndroid() { + return navigator.platform === "Android" || /android/i.test(navigator.userAgent); +} +function isiOS() { + return [ + "iPad Simulator", + "iPhone Simulator", + "iPod Simulator", + "iPad", + "iPhone", + "iPod" + ].includes(navigator.platform) || navigator.userAgent.includes("Mac") && "ontouchend" in document; +} +var focus = (position = null, options = {}) => ({ editor, view, tr, dispatch }) => { + options = { + scrollIntoView: true, + ...options + }; + const delayedFocus = () => { + if (isiOS() || isAndroid()) { + view.dom.focus(); + } + requestAnimationFrame(() => { + if (!editor.isDestroyed) { + view.focus(); + if (options === null || options === void 0 ? void 0 : options.scrollIntoView) { + editor.commands.scrollIntoView(); + } + } + }); + }; + if (view.hasFocus() && position === null || position === false) { + return true; + } + if (dispatch && position === null && !isTextSelection(editor.state.selection)) { + delayedFocus(); + return true; + } + const selection = resolveFocusPosition(tr.doc, position) || editor.state.selection; + const isSameSelection = editor.state.selection.eq(selection); + if (dispatch) { + if (!isSameSelection) { + tr.setSelection(selection); + } + if (isSameSelection && tr.storedMarks) { + tr.setStoredMarks(tr.storedMarks); + } + delayedFocus(); + } + return true; +}; +var forEach = (items, fn) => (props) => { + return items.every((item, index) => fn(item, { ...props, index })); +}; +var insertContent = (value, options) => ({ tr, commands: commands2 }) => { + return commands2.insertContentAt({ from: tr.selection.from, to: tr.selection.to }, value, options); +}; +var removeWhitespaces = (node) => { + const children = node.childNodes; + for (let i5 = children.length - 1; i5 >= 0; i5 -= 1) { + const child = children[i5]; + if (child.nodeType === 3 && child.nodeValue && /^(\n\s\s|\n)$/.test(child.nodeValue)) { + node.removeChild(child); + } else if (child.nodeType === 1) { + removeWhitespaces(child); + } + } + return node; +}; +function elementFromString(value) { + const wrappedValue = `${value}`; + const html = new window.DOMParser().parseFromString(wrappedValue, "text/html").body; + return removeWhitespaces(html); +} +function createNodeFromContent(content, schema, options) { + if (content instanceof Node || content instanceof Fragment) { + return content; + } + options = { + slice: true, + parseOptions: {}, + ...options + }; + const isJSONContent = typeof content === "object" && content !== null; + const isTextContent = typeof content === "string"; + if (isJSONContent) { + try { + const isArrayContent = Array.isArray(content) && content.length > 0; + if (isArrayContent) { + return Fragment.fromArray(content.map((item) => schema.nodeFromJSON(item))); + } + const node = schema.nodeFromJSON(content); + if (options.errorOnInvalidContent) { + node.check(); + } + return node; + } catch (error) { + if (options.errorOnInvalidContent) { + throw new Error("[tiptap error]: Invalid JSON content", { cause: error }); + } + console.warn("[tiptap warn]: Invalid content.", "Passed value:", content, "Error:", error); + return createNodeFromContent("", schema, options); + } + } + if (isTextContent) { + if (options.errorOnInvalidContent) { + let hasInvalidContent = false; + let invalidContent = ""; + const contentCheckSchema = new Schema({ + topNode: schema.spec.topNode, + marks: schema.spec.marks, + // Prosemirror's schemas are executed such that: the last to execute, matches last + // This means that we can add a catch-all node at the end of the schema to catch any content that we don't know how to handle + nodes: schema.spec.nodes.append({ + __tiptap__private__unknown__catch__all__node: { + content: "inline*", + group: "block", + parseDOM: [ + { + tag: "*", + getAttrs: (e4) => { + hasInvalidContent = true; + invalidContent = typeof e4 === "string" ? e4 : e4.outerHTML; + return null; + } + } + ] + } + }) + }); + if (options.slice) { + DOMParser.fromSchema(contentCheckSchema).parseSlice(elementFromString(content), options.parseOptions); + } else { + DOMParser.fromSchema(contentCheckSchema).parse(elementFromString(content), options.parseOptions); + } + if (options.errorOnInvalidContent && hasInvalidContent) { + throw new Error("[tiptap error]: Invalid HTML content", { cause: new Error(`Invalid element found: ${invalidContent}`) }); + } + } + const parser = DOMParser.fromSchema(schema); + if (options.slice) { + return parser.parseSlice(elementFromString(content), options.parseOptions).content; + } + return parser.parse(elementFromString(content), options.parseOptions); + } + return createNodeFromContent("", schema, options); +} +function selectionToInsertionEnd2(tr, startLen, bias) { + const last = tr.steps.length - 1; + if (last < startLen) { + return; + } + const step = tr.steps[last]; + if (!(step instanceof ReplaceStep || step instanceof ReplaceAroundStep)) { + return; + } + const map = tr.mapping.maps[last]; + let end = 0; + map.forEach((_from, _to, _newFrom, newTo) => { + if (end === 0) { + end = newTo; + } + }); + tr.setSelection(Selection.near(tr.doc.resolve(end), bias)); +} +var isFragment = (nodeOrFragment) => { + return !("type" in nodeOrFragment); +}; +var insertContentAt = (position, value, options) => ({ tr, dispatch, editor }) => { + var _a; + if (dispatch) { + options = { + parseOptions: editor.options.parseOptions, + updateSelection: true, + applyInputRules: false, + applyPasteRules: false, + ...options + }; + let content; + try { + content = createNodeFromContent(value, editor.schema, { + parseOptions: { + preserveWhitespace: "full", + ...options.parseOptions + }, + errorOnInvalidContent: (_a = options.errorOnInvalidContent) !== null && _a !== void 0 ? _a : editor.options.enableContentCheck + }); + } catch (e4) { + editor.emit("contentError", { + editor, + error: e4, + disableCollaboration: () => { + if (editor.storage.collaboration) { + editor.storage.collaboration.isDisabled = true; + } + } + }); + return false; + } + let { from, to } = typeof position === "number" ? { from: position, to: position } : { from: position.from, to: position.to }; + let isOnlyTextContent = true; + let isOnlyBlockContent = true; + const nodes = isFragment(content) ? content : [content]; + nodes.forEach((node) => { + node.check(); + isOnlyTextContent = isOnlyTextContent ? node.isText && node.marks.length === 0 : false; + isOnlyBlockContent = isOnlyBlockContent ? node.isBlock : false; + }); + if (from === to && isOnlyBlockContent) { + const { parent } = tr.doc.resolve(from); + const isEmptyTextBlock = parent.isTextblock && !parent.type.spec.code && !parent.childCount; + if (isEmptyTextBlock) { + from -= 1; + to += 1; + } + } + let newContent; + if (isOnlyTextContent) { + if (Array.isArray(value)) { + newContent = value.map((v2) => v2.text || "").join(""); + } else if (value instanceof Fragment) { + let text = ""; + value.forEach((node) => { + if (node.text) { + text += node.text; + } + }); + newContent = text; + } else if (typeof value === "object" && !!value && !!value.text) { + newContent = value.text; + } else { + newContent = value; + } + tr.insertText(newContent, from, to); + } else { + newContent = content; + tr.replaceWith(from, to, newContent); + } + if (options.updateSelection) { + selectionToInsertionEnd2(tr, tr.steps.length - 1, -1); + } + if (options.applyInputRules) { + tr.setMeta("applyInputRules", { from, text: newContent }); + } + if (options.applyPasteRules) { + tr.setMeta("applyPasteRules", { from, text: newContent }); + } + } + return true; +}; +var joinUp2 = () => ({ state, dispatch }) => { + return joinUp(state, dispatch); +}; +var joinDown2 = () => ({ state, dispatch }) => { + return joinDown(state, dispatch); +}; +var joinBackward2 = () => ({ state, dispatch }) => { + return joinBackward(state, dispatch); +}; +var joinForward2 = () => ({ state, dispatch }) => { + return joinForward(state, dispatch); +}; +var joinItemBackward = () => ({ state, dispatch, tr }) => { + try { + const point = joinPoint(state.doc, state.selection.$from.pos, -1); + if (point === null || point === void 0) { + return false; + } + tr.join(point, 2); + if (dispatch) { + dispatch(tr); + } + return true; + } catch { + return false; + } +}; +var joinItemForward = () => ({ state, dispatch, tr }) => { + try { + const point = joinPoint(state.doc, state.selection.$from.pos, 1); + if (point === null || point === void 0) { + return false; + } + tr.join(point, 2); + if (dispatch) { + dispatch(tr); + } + return true; + } catch { + return false; + } +}; +var joinTextblockBackward2 = () => ({ state, dispatch }) => { + return joinTextblockBackward(state, dispatch); +}; +var joinTextblockForward2 = () => ({ state, dispatch }) => { + return joinTextblockForward(state, dispatch); +}; +function isMacOS() { + return typeof navigator !== "undefined" ? /Mac/.test(navigator.platform) : false; +} +function normalizeKeyName2(name) { + const parts = name.split(/-(?!$)/); + let result = parts[parts.length - 1]; + if (result === "Space") { + result = " "; + } + let alt; + let ctrl; + let shift2; + let meta; + for (let i5 = 0; i5 < parts.length - 1; i5 += 1) { + const mod = parts[i5]; + if (/^(cmd|meta|m)$/i.test(mod)) { + meta = true; + } else if (/^a(lt)?$/i.test(mod)) { + alt = true; + } else if (/^(c|ctrl|control)$/i.test(mod)) { + ctrl = true; + } else if (/^s(hift)?$/i.test(mod)) { + shift2 = true; + } else if (/^mod$/i.test(mod)) { + if (isiOS() || isMacOS()) { + meta = true; + } else { + ctrl = true; + } + } else { + throw new Error(`Unrecognized modifier name: ${mod}`); + } + } + if (alt) { + result = `Alt-${result}`; + } + if (ctrl) { + result = `Ctrl-${result}`; + } + if (meta) { + result = `Meta-${result}`; + } + if (shift2) { + result = `Shift-${result}`; + } + return result; +} +var keyboardShortcut = (name) => ({ editor, view, tr, dispatch }) => { + const keys2 = normalizeKeyName2(name).split(/-(?!$)/); + const key = keys2.find((item) => !["Alt", "Ctrl", "Meta", "Shift"].includes(item)); + const event = new KeyboardEvent("keydown", { + key: key === "Space" ? " " : key, + altKey: keys2.includes("Alt"), + ctrlKey: keys2.includes("Ctrl"), + metaKey: keys2.includes("Meta"), + shiftKey: keys2.includes("Shift"), + bubbles: true, + cancelable: true + }); + const capturedTransaction = editor.captureTransaction(() => { + view.someProp("handleKeyDown", (f3) => f3(view, event)); + }); + capturedTransaction === null || capturedTransaction === void 0 ? void 0 : capturedTransaction.steps.forEach((step) => { + const newStep = step.map(tr.mapping); + if (newStep && dispatch) { + tr.maybeStep(newStep); + } + }); + return true; +}; +function isNodeActive(state, typeOrName, attributes = {}) { + const { from, to, empty: empty2 } = state.selection; + const type = typeOrName ? getNodeType(typeOrName, state.schema) : null; + const nodeRanges = []; + state.doc.nodesBetween(from, to, (node, pos) => { + if (node.isText) { + return; + } + const relativeFrom = Math.max(from, pos); + const relativeTo = Math.min(to, pos + node.nodeSize); + nodeRanges.push({ + node, + from: relativeFrom, + to: relativeTo + }); + }); + const selectionRange = to - from; + const matchedNodeRanges = nodeRanges.filter((nodeRange) => { + if (!type) { + return true; + } + return type.name === nodeRange.node.type.name; + }).filter((nodeRange) => objectIncludes(nodeRange.node.attrs, attributes, { strict: false })); + if (empty2) { + return !!matchedNodeRanges.length; + } + const range = matchedNodeRanges.reduce((sum, nodeRange) => sum + nodeRange.to - nodeRange.from, 0); + return range >= selectionRange; +} +var lift3 = (typeOrName, attributes = {}) => ({ state, dispatch }) => { + const type = getNodeType(typeOrName, state.schema); + const isActive2 = isNodeActive(state, type, attributes); + if (!isActive2) { + return false; + } + return lift2(state, dispatch); +}; +var liftEmptyBlock2 = () => ({ state, dispatch }) => { + return liftEmptyBlock(state, dispatch); +}; +var liftListItem2 = (typeOrName) => ({ state, dispatch }) => { + const type = getNodeType(typeOrName, state.schema); + return liftListItem(type)(state, dispatch); +}; +var newlineInCode2 = () => ({ state, dispatch }) => { + return newlineInCode(state, dispatch); +}; +function getSchemaTypeNameByName(name, schema) { + if (schema.nodes[name]) { + return "node"; + } + if (schema.marks[name]) { + return "mark"; + } + return null; +} +function deleteProps(obj, propOrProps) { + const props = typeof propOrProps === "string" ? [propOrProps] : propOrProps; + return Object.keys(obj).reduce((newObj, prop) => { + if (!props.includes(prop)) { + newObj[prop] = obj[prop]; + } + return newObj; + }, {}); +} +var resetAttributes = (typeOrName, attributes) => ({ tr, state, dispatch }) => { + let nodeType = null; + let markType = null; + const schemaType = getSchemaTypeNameByName(typeof typeOrName === "string" ? typeOrName : typeOrName.name, state.schema); + if (!schemaType) { + return false; + } + if (schemaType === "node") { + nodeType = getNodeType(typeOrName, state.schema); + } + if (schemaType === "mark") { + markType = getMarkType(typeOrName, state.schema); + } + if (dispatch) { + tr.selection.ranges.forEach((range) => { + state.doc.nodesBetween(range.$from.pos, range.$to.pos, (node, pos) => { + if (nodeType && nodeType === node.type) { + tr.setNodeMarkup(pos, void 0, deleteProps(node.attrs, attributes)); + } + if (markType && node.marks.length) { + node.marks.forEach((mark) => { + if (markType === mark.type) { + tr.addMark(pos, pos + node.nodeSize, markType.create(deleteProps(mark.attrs, attributes))); + } + }); + } + }); + }); + } + return true; +}; +var scrollIntoView = () => ({ tr, dispatch }) => { + if (dispatch) { + tr.scrollIntoView(); + } + return true; +}; +var selectAll2 = () => ({ tr, dispatch }) => { + if (dispatch) { + const selection = new AllSelection(tr.doc); + tr.setSelection(selection); + } + return true; +}; +var selectNodeBackward2 = () => ({ state, dispatch }) => { + return selectNodeBackward(state, dispatch); +}; +var selectNodeForward2 = () => ({ state, dispatch }) => { + return selectNodeForward(state, dispatch); +}; +var selectParentNode2 = () => ({ state, dispatch }) => { + return selectParentNode(state, dispatch); +}; +var selectTextblockEnd2 = () => ({ state, dispatch }) => { + return selectTextblockEnd(state, dispatch); +}; +var selectTextblockStart2 = () => ({ state, dispatch }) => { + return selectTextblockStart(state, dispatch); +}; +function createDocument(content, schema, parseOptions = {}, options = {}) { + return createNodeFromContent(content, schema, { + slice: false, + parseOptions, + errorOnInvalidContent: options.errorOnInvalidContent + }); +} +var setContent = (content, emitUpdate = false, parseOptions = {}, options = {}) => ({ editor, tr, dispatch, commands: commands2 }) => { + var _a, _b; + const { doc: doc3 } = tr; + if (parseOptions.preserveWhitespace !== "full") { + const document2 = createDocument(content, editor.schema, parseOptions, { + errorOnInvalidContent: (_a = options.errorOnInvalidContent) !== null && _a !== void 0 ? _a : editor.options.enableContentCheck + }); + if (dispatch) { + tr.replaceWith(0, doc3.content.size, document2).setMeta("preventUpdate", !emitUpdate); + } + return true; + } + if (dispatch) { + tr.setMeta("preventUpdate", !emitUpdate); + } + return commands2.insertContentAt({ from: 0, to: doc3.content.size }, content, { + parseOptions, + errorOnInvalidContent: (_b = options.errorOnInvalidContent) !== null && _b !== void 0 ? _b : editor.options.enableContentCheck + }); +}; +function getMarkAttributes(state, typeOrName) { + const type = getMarkType(typeOrName, state.schema); + const { from, to, empty: empty2 } = state.selection; + const marks = []; + if (empty2) { + if (state.storedMarks) { + marks.push(...state.storedMarks); + } + marks.push(...state.selection.$head.marks()); + } else { + state.doc.nodesBetween(from, to, (node) => { + marks.push(...node.marks); + }); + } + const mark = marks.find((markItem) => markItem.type.name === type.name); + if (!mark) { + return {}; + } + return { ...mark.attrs }; +} +function defaultBlockAt2(match) { + for (let i5 = 0; i5 < match.edgeCount; i5 += 1) { + const { type } = match.edge(i5); + if (type.isTextblock && !type.hasRequiredAttrs()) { + return type; + } + } + return null; +} +function findParentNodeClosestToPos($pos, predicate) { + for (let i5 = $pos.depth; i5 > 0; i5 -= 1) { + const node = $pos.node(i5); + if (predicate(node)) { + return { + pos: i5 > 0 ? $pos.before(i5) : 0, + start: $pos.start(i5), + depth: i5, + node + }; + } + } +} +function findParentNode(predicate) { + return (selection) => findParentNodeClosestToPos(selection.$from, predicate); +} +function getText2(node, options) { + const range = { + from: 0, + to: node.content.size + }; + return getTextBetween(node, range, options); +} +function getNodeAttributes(state, typeOrName) { + const type = getNodeType(typeOrName, state.schema); + const { from, to } = state.selection; + const nodes = []; + state.doc.nodesBetween(from, to, (node2) => { + nodes.push(node2); + }); + const node = nodes.reverse().find((nodeItem) => nodeItem.type.name === type.name); + if (!node) { + return {}; + } + return { ...node.attrs }; +} +function getAttributes(state, typeOrName) { + const schemaType = getSchemaTypeNameByName(typeof typeOrName === "string" ? typeOrName : typeOrName.name, state.schema); + if (schemaType === "node") { + return getNodeAttributes(state, typeOrName); + } + if (schemaType === "mark") { + return getMarkAttributes(state, typeOrName); + } + return {}; +} +function getMarksBetween(from, to, doc3) { + const marks = []; + if (from === to) { + doc3.resolve(from).marks().forEach((mark) => { + const $pos = doc3.resolve(from); + const range = getMarkRange($pos, mark.type); + if (!range) { + return; + } + marks.push({ + mark, + ...range + }); + }); + } else { + doc3.nodesBetween(from, to, (node, pos) => { + if (!node || (node === null || node === void 0 ? void 0 : node.nodeSize) === void 0) { + return; + } + marks.push(...node.marks.map((mark) => ({ + from: pos, + to: pos + node.nodeSize, + mark + }))); + }); + } + return marks; +} +function getSplittedAttributes(extensionAttributes, typeName, attributes) { + return Object.fromEntries(Object.entries(attributes).filter(([name]) => { + const extensionAttribute = extensionAttributes.find((item) => { + return item.type === typeName && item.name === name; + }); + if (!extensionAttribute) { + return false; + } + return extensionAttribute.attribute.keepOnSplit; + })); +} +function isMarkActive(state, typeOrName, attributes = {}) { + const { empty: empty2, ranges } = state.selection; + const type = typeOrName ? getMarkType(typeOrName, state.schema) : null; + if (empty2) { + return !!(state.storedMarks || state.selection.$from.marks()).filter((mark) => { + if (!type) { + return true; + } + return type.name === mark.type.name; + }).find((mark) => objectIncludes(mark.attrs, attributes, { strict: false })); + } + let selectionRange = 0; + const markRanges = []; + ranges.forEach(({ $from, $to }) => { + const from = $from.pos; + const to = $to.pos; + state.doc.nodesBetween(from, to, (node, pos) => { + if (!node.isText && !node.marks.length) { + return; + } + const relativeFrom = Math.max(from, pos); + const relativeTo = Math.min(to, pos + node.nodeSize); + const range2 = relativeTo - relativeFrom; + selectionRange += range2; + markRanges.push(...node.marks.map((mark) => ({ + mark, + from: relativeFrom, + to: relativeTo + }))); + }); + }); + if (selectionRange === 0) { + return false; + } + const matchedRange = markRanges.filter((markRange) => { + if (!type) { + return true; + } + return type.name === markRange.mark.type.name; + }).filter((markRange) => objectIncludes(markRange.mark.attrs, attributes, { strict: false })).reduce((sum, markRange) => sum + markRange.to - markRange.from, 0); + const excludedRange = markRanges.filter((markRange) => { + if (!type) { + return true; + } + return markRange.mark.type !== type && markRange.mark.type.excludes(type); + }).reduce((sum, markRange) => sum + markRange.to - markRange.from, 0); + const range = matchedRange > 0 ? matchedRange + excludedRange : matchedRange; + return range >= selectionRange; +} +function isActive(state, name, attributes = {}) { + if (!name) { + return isNodeActive(state, null, attributes) || isMarkActive(state, null, attributes); + } + const schemaType = getSchemaTypeNameByName(name, state.schema); + if (schemaType === "node") { + return isNodeActive(state, name, attributes); + } + if (schemaType === "mark") { + return isMarkActive(state, name, attributes); + } + return false; +} +function isList(name, extensions) { + const { nodeExtensions } = splitExtensions(extensions); + const extension = nodeExtensions.find((item) => item.name === name); + if (!extension) { + return false; + } + const context = { + name: extension.name, + options: extension.options, + storage: extension.storage + }; + const group = callOrReturn(getExtensionField(extension, "group", context)); + if (typeof group !== "string") { + return false; + } + return group.split(" ").includes("list"); +} +function isNodeEmpty(node, { checkChildren = true, ignoreWhitespace = false } = {}) { + var _a; + if (ignoreWhitespace) { + if (node.type.name === "hardBreak") { + return true; + } + if (node.isText) { + return /^\s*$/m.test((_a = node.text) !== null && _a !== void 0 ? _a : ""); + } + } + if (node.isText) { + return !node.text; + } + if (node.isAtom || node.isLeaf) { + return false; + } + if (node.content.childCount === 0) { + return true; + } + if (checkChildren) { + let isContentEmpty = true; + node.content.forEach((childNode) => { + if (isContentEmpty === false) { + return; + } + if (!isNodeEmpty(childNode, { ignoreWhitespace, checkChildren })) { + isContentEmpty = false; + } + }); + return isContentEmpty; + } + return false; +} +function canSetMark(state, tr, newMarkType) { + var _a; + const { selection } = tr; + let cursor = null; + if (isTextSelection(selection)) { + cursor = selection.$cursor; + } + if (cursor) { + const currentMarks = (_a = state.storedMarks) !== null && _a !== void 0 ? _a : cursor.marks(); + return !!newMarkType.isInSet(currentMarks) || !currentMarks.some((mark) => mark.type.excludes(newMarkType)); + } + const { ranges } = selection; + return ranges.some(({ $from, $to }) => { + let someNodeSupportsMark = $from.depth === 0 ? state.doc.inlineContent && state.doc.type.allowsMarkType(newMarkType) : false; + state.doc.nodesBetween($from.pos, $to.pos, (node, _pos, parent) => { + if (someNodeSupportsMark) { + return false; + } + if (node.isInline) { + const parentAllowsMarkType = !parent || parent.type.allowsMarkType(newMarkType); + const currentMarksAllowMarkType = !!newMarkType.isInSet(node.marks) || !node.marks.some((otherMark) => otherMark.type.excludes(newMarkType)); + someNodeSupportsMark = parentAllowsMarkType && currentMarksAllowMarkType; + } + return !someNodeSupportsMark; + }); + return someNodeSupportsMark; + }); +} +var setMark = (typeOrName, attributes = {}) => ({ tr, state, dispatch }) => { + const { selection } = tr; + const { empty: empty2, ranges } = selection; + const type = getMarkType(typeOrName, state.schema); + if (dispatch) { + if (empty2) { + const oldAttributes = getMarkAttributes(state, type); + tr.addStoredMark(type.create({ + ...oldAttributes, + ...attributes + })); + } else { + ranges.forEach((range) => { + const from = range.$from.pos; + const to = range.$to.pos; + state.doc.nodesBetween(from, to, (node, pos) => { + const trimmedFrom = Math.max(pos, from); + const trimmedTo = Math.min(pos + node.nodeSize, to); + const someHasMark = node.marks.find((mark) => mark.type === type); + if (someHasMark) { + node.marks.forEach((mark) => { + if (type === mark.type) { + tr.addMark(trimmedFrom, trimmedTo, type.create({ + ...mark.attrs, + ...attributes + })); + } + }); + } else { + tr.addMark(trimmedFrom, trimmedTo, type.create(attributes)); + } + }); + }); + } + } + return canSetMark(state, tr, type); +}; +var setMeta = (key, value) => ({ tr }) => { + tr.setMeta(key, value); + return true; +}; +var setNode = (typeOrName, attributes = {}) => ({ state, dispatch, chain }) => { + const type = getNodeType(typeOrName, state.schema); + let attributesToCopy; + if (state.selection.$anchor.sameParent(state.selection.$head)) { + attributesToCopy = state.selection.$anchor.parent.attrs; + } + if (!type.isTextblock) { + console.warn('[tiptap warn]: Currently "setNode()" only supports text block nodes.'); + return false; + } + return chain().command(({ commands: commands2 }) => { + const canSetBlock = setBlockType2(type, { ...attributesToCopy, ...attributes })(state); + if (canSetBlock) { + return true; + } + return commands2.clearNodes(); + }).command(({ state: updatedState }) => { + return setBlockType2(type, { ...attributesToCopy, ...attributes })(updatedState, dispatch); + }).run(); +}; +var setNodeSelection = (position) => ({ tr, dispatch }) => { + if (dispatch) { + const { doc: doc3 } = tr; + const from = minMax(position, 0, doc3.content.size); + const selection = NodeSelection.create(doc3, from); + tr.setSelection(selection); + } + return true; +}; +var setTextSelection = (position) => ({ tr, dispatch }) => { + if (dispatch) { + const { doc: doc3 } = tr; + const { from, to } = typeof position === "number" ? { from: position, to: position } : position; + const minPos = TextSelection.atStart(doc3).from; + const maxPos = TextSelection.atEnd(doc3).to; + const resolvedFrom = minMax(from, minPos, maxPos); + const resolvedEnd = minMax(to, minPos, maxPos); + const selection = TextSelection.create(doc3, resolvedFrom, resolvedEnd); + tr.setSelection(selection); + } + return true; +}; +var sinkListItem2 = (typeOrName) => ({ state, dispatch }) => { + const type = getNodeType(typeOrName, state.schema); + return sinkListItem(type)(state, dispatch); +}; +function ensureMarks(state, splittableMarks) { + const marks = state.storedMarks || state.selection.$to.parentOffset && state.selection.$from.marks(); + if (marks) { + const filteredMarks = marks.filter((mark) => splittableMarks === null || splittableMarks === void 0 ? void 0 : splittableMarks.includes(mark.type.name)); + state.tr.ensureMarks(filteredMarks); + } +} +var splitBlock2 = ({ keepMarks = true } = {}) => ({ tr, state, dispatch, editor }) => { + const { selection, doc: doc3 } = tr; + const { $from, $to } = selection; + const extensionAttributes = editor.extensionManager.attributes; + const newAttributes = getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs); + if (selection instanceof NodeSelection && selection.node.isBlock) { + if (!$from.parentOffset || !canSplit(doc3, $from.pos)) { + return false; + } + if (dispatch) { + if (keepMarks) { + ensureMarks(state, editor.extensionManager.splittableMarks); + } + tr.split($from.pos).scrollIntoView(); + } + return true; + } + if (!$from.parent.isBlock) { + return false; + } + const atEnd = $to.parentOffset === $to.parent.content.size; + const deflt = $from.depth === 0 ? void 0 : defaultBlockAt2($from.node(-1).contentMatchAt($from.indexAfter(-1))); + let types = atEnd && deflt ? [ + { + type: deflt, + attrs: newAttributes + } + ] : void 0; + let can = canSplit(tr.doc, tr.mapping.map($from.pos), 1, types); + if (!types && !can && canSplit(tr.doc, tr.mapping.map($from.pos), 1, deflt ? [{ type: deflt }] : void 0)) { + can = true; + types = deflt ? [ + { + type: deflt, + attrs: newAttributes + } + ] : void 0; + } + if (dispatch) { + if (can) { + if (selection instanceof TextSelection) { + tr.deleteSelection(); + } + tr.split(tr.mapping.map($from.pos), 1, types); + if (deflt && !atEnd && !$from.parentOffset && $from.parent.type !== deflt) { + const first2 = tr.mapping.map($from.before()); + const $first = tr.doc.resolve(first2); + if ($from.node(-1).canReplaceWith($first.index(), $first.index() + 1, deflt)) { + tr.setNodeMarkup(tr.mapping.map($from.before()), deflt); + } + } + } + if (keepMarks) { + ensureMarks(state, editor.extensionManager.splittableMarks); + } + tr.scrollIntoView(); + } + return can; +}; +var splitListItem = (typeOrName, overrideAttrs = {}) => ({ tr, state, dispatch, editor }) => { + var _a; + const type = getNodeType(typeOrName, state.schema); + const { $from, $to } = state.selection; + const node = state.selection.node; + if (node && node.isBlock || $from.depth < 2 || !$from.sameParent($to)) { + return false; + } + const grandParent = $from.node(-1); + if (grandParent.type !== type) { + return false; + } + const extensionAttributes = editor.extensionManager.attributes; + if ($from.parent.content.size === 0 && $from.node(-1).childCount === $from.indexAfter(-1)) { + if ($from.depth === 2 || $from.node(-3).type !== type || $from.index(-2) !== $from.node(-2).childCount - 1) { + return false; + } + if (dispatch) { + let wrap2 = Fragment.empty; + const depthBefore = $from.index(-1) ? 1 : $from.index(-2) ? 2 : 3; + for (let d3 = $from.depth - depthBefore; d3 >= $from.depth - 3; d3 -= 1) { + wrap2 = Fragment.from($from.node(d3).copy(wrap2)); + } + const depthAfter = $from.indexAfter(-1) < $from.node(-2).childCount ? 1 : $from.indexAfter(-2) < $from.node(-3).childCount ? 2 : 3; + const newNextTypeAttributes2 = { + ...getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs), + ...overrideAttrs + }; + const nextType2 = ((_a = type.contentMatch.defaultType) === null || _a === void 0 ? void 0 : _a.createAndFill(newNextTypeAttributes2)) || void 0; + wrap2 = wrap2.append(Fragment.from(type.createAndFill(null, nextType2) || void 0)); + const start = $from.before($from.depth - (depthBefore - 1)); + tr.replace(start, $from.after(-depthAfter), new Slice(wrap2, 4 - depthBefore, 0)); + let sel = -1; + tr.doc.nodesBetween(start, tr.doc.content.size, (n4, pos) => { + if (sel > -1) { + return false; + } + if (n4.isTextblock && n4.content.size === 0) { + sel = pos + 1; + } + }); + if (sel > -1) { + tr.setSelection(TextSelection.near(tr.doc.resolve(sel))); + } + tr.scrollIntoView(); + } + return true; + } + const nextType = $to.pos === $from.end() ? grandParent.contentMatchAt(0).defaultType : null; + const newTypeAttributes = { + ...getSplittedAttributes(extensionAttributes, grandParent.type.name, grandParent.attrs), + ...overrideAttrs + }; + const newNextTypeAttributes = { + ...getSplittedAttributes(extensionAttributes, $from.node().type.name, $from.node().attrs), + ...overrideAttrs + }; + tr.delete($from.pos, $to.pos); + const types = nextType ? [ + { type, attrs: newTypeAttributes }, + { type: nextType, attrs: newNextTypeAttributes } + ] : [{ type, attrs: newTypeAttributes }]; + if (!canSplit(tr.doc, $from.pos, 2)) { + return false; + } + if (dispatch) { + const { selection, storedMarks } = state; + const { splittableMarks } = editor.extensionManager; + const marks = storedMarks || selection.$to.parentOffset && selection.$from.marks(); + tr.split($from.pos, 2, types).scrollIntoView(); + if (!marks || !dispatch) { + return true; + } + const filteredMarks = marks.filter((mark) => splittableMarks.includes(mark.type.name)); + tr.ensureMarks(filteredMarks); + } + return true; +}; +var joinListBackwards = (tr, listType) => { + const list = findParentNode((node) => node.type === listType)(tr.selection); + if (!list) { + return true; + } + const before = tr.doc.resolve(Math.max(0, list.pos - 1)).before(list.depth); + if (before === void 0) { + return true; + } + const nodeBefore = tr.doc.nodeAt(before); + const canJoinBackwards = list.node.type === (nodeBefore === null || nodeBefore === void 0 ? void 0 : nodeBefore.type) && canJoin(tr.doc, list.pos); + if (!canJoinBackwards) { + return true; + } + tr.join(list.pos); + return true; +}; +var joinListForwards = (tr, listType) => { + const list = findParentNode((node) => node.type === listType)(tr.selection); + if (!list) { + return true; + } + const after = tr.doc.resolve(list.start).after(list.depth); + if (after === void 0) { + return true; + } + const nodeAfter = tr.doc.nodeAt(after); + const canJoinForwards = list.node.type === (nodeAfter === null || nodeAfter === void 0 ? void 0 : nodeAfter.type) && canJoin(tr.doc, after); + if (!canJoinForwards) { + return true; + } + tr.join(after); + return true; +}; +var toggleList = (listTypeOrName, itemTypeOrName, keepMarks, attributes = {}) => ({ editor, tr, state, dispatch, chain, commands: commands2, can }) => { + const { extensions, splittableMarks } = editor.extensionManager; + const listType = getNodeType(listTypeOrName, state.schema); + const itemType = getNodeType(itemTypeOrName, state.schema); + const { selection, storedMarks } = state; + const { $from, $to } = selection; + const range = $from.blockRange($to); + const marks = storedMarks || selection.$to.parentOffset && selection.$from.marks(); + if (!range) { + return false; + } + const parentList = findParentNode((node) => isList(node.type.name, extensions))(selection); + if (range.depth >= 1 && parentList && range.depth - parentList.depth <= 1) { + if (parentList.node.type === listType) { + return commands2.liftListItem(itemType); + } + if (isList(parentList.node.type.name, extensions) && listType.validContent(parentList.node.content) && dispatch) { + return chain().command(() => { + tr.setNodeMarkup(parentList.pos, listType); + return true; + }).command(() => joinListBackwards(tr, listType)).command(() => joinListForwards(tr, listType)).run(); + } + } + if (!keepMarks || !marks || !dispatch) { + return chain().command(() => { + const canWrapInList = can().wrapInList(listType, attributes); + if (canWrapInList) { + return true; + } + return commands2.clearNodes(); + }).wrapInList(listType, attributes).command(() => joinListBackwards(tr, listType)).command(() => joinListForwards(tr, listType)).run(); + } + return chain().command(() => { + const canWrapInList = can().wrapInList(listType, attributes); + const filteredMarks = marks.filter((mark) => splittableMarks.includes(mark.type.name)); + tr.ensureMarks(filteredMarks); + if (canWrapInList) { + return true; + } + return commands2.clearNodes(); + }).wrapInList(listType, attributes).command(() => joinListBackwards(tr, listType)).command(() => joinListForwards(tr, listType)).run(); +}; +var toggleMark = (typeOrName, attributes = {}, options = {}) => ({ state, commands: commands2 }) => { + const { extendEmptyMarkRange = false } = options; + const type = getMarkType(typeOrName, state.schema); + const isActive2 = isMarkActive(state, type, attributes); + if (isActive2) { + return commands2.unsetMark(type, { extendEmptyMarkRange }); + } + return commands2.setMark(type, attributes); +}; +var toggleNode = (typeOrName, toggleTypeOrName, attributes = {}) => ({ state, commands: commands2 }) => { + const type = getNodeType(typeOrName, state.schema); + const toggleType = getNodeType(toggleTypeOrName, state.schema); + const isActive2 = isNodeActive(state, type, attributes); + let attributesToCopy; + if (state.selection.$anchor.sameParent(state.selection.$head)) { + attributesToCopy = state.selection.$anchor.parent.attrs; + } + if (isActive2) { + return commands2.setNode(toggleType, attributesToCopy); + } + return commands2.setNode(type, { ...attributesToCopy, ...attributes }); +}; +var toggleWrap = (typeOrName, attributes = {}) => ({ state, commands: commands2 }) => { + const type = getNodeType(typeOrName, state.schema); + const isActive2 = isNodeActive(state, type, attributes); + if (isActive2) { + return commands2.lift(type); + } + return commands2.wrapIn(type, attributes); +}; +var undoInputRule = () => ({ state, dispatch }) => { + const plugins = state.plugins; + for (let i5 = 0; i5 < plugins.length; i5 += 1) { + const plugin = plugins[i5]; + let undoable; + if (plugin.spec.isInputRules && (undoable = plugin.getState(state))) { + if (dispatch) { + const tr = state.tr; + const toUndo = undoable.transform; + for (let j2 = toUndo.steps.length - 1; j2 >= 0; j2 -= 1) { + tr.step(toUndo.steps[j2].invert(toUndo.docs[j2])); + } + if (undoable.text) { + const marks = tr.doc.resolve(undoable.from).marks(); + tr.replaceWith(undoable.from, undoable.to, state.schema.text(undoable.text, marks)); + } else { + tr.delete(undoable.from, undoable.to); + } + } + return true; + } + } + return false; +}; +var unsetAllMarks = () => ({ tr, dispatch }) => { + const { selection } = tr; + const { empty: empty2, ranges } = selection; + if (empty2) { + return true; + } + if (dispatch) { + ranges.forEach((range) => { + tr.removeMark(range.$from.pos, range.$to.pos); + }); + } + return true; +}; +var unsetMark = (typeOrName, options = {}) => ({ tr, state, dispatch }) => { + var _a; + const { extendEmptyMarkRange = false } = options; + const { selection } = tr; + const type = getMarkType(typeOrName, state.schema); + const { $from, empty: empty2, ranges } = selection; + if (!dispatch) { + return true; + } + if (empty2 && extendEmptyMarkRange) { + let { from, to } = selection; + const attrs = (_a = $from.marks().find((mark) => mark.type === type)) === null || _a === void 0 ? void 0 : _a.attrs; + const range = getMarkRange($from, type, attrs); + if (range) { + from = range.from; + to = range.to; + } + tr.removeMark(from, to, type); + } else { + ranges.forEach((range) => { + tr.removeMark(range.$from.pos, range.$to.pos, type); + }); + } + tr.removeStoredMark(type); + return true; +}; +var updateAttributes = (typeOrName, attributes = {}) => ({ tr, state, dispatch }) => { + let nodeType = null; + let markType = null; + const schemaType = getSchemaTypeNameByName(typeof typeOrName === "string" ? typeOrName : typeOrName.name, state.schema); + if (!schemaType) { + return false; + } + if (schemaType === "node") { + nodeType = getNodeType(typeOrName, state.schema); + } + if (schemaType === "mark") { + markType = getMarkType(typeOrName, state.schema); + } + if (dispatch) { + tr.selection.ranges.forEach((range) => { + const from = range.$from.pos; + const to = range.$to.pos; + let lastPos; + let lastNode; + let trimmedFrom; + let trimmedTo; + if (tr.selection.empty) { + state.doc.nodesBetween(from, to, (node, pos) => { + if (nodeType && nodeType === node.type) { + trimmedFrom = Math.max(pos, from); + trimmedTo = Math.min(pos + node.nodeSize, to); + lastPos = pos; + lastNode = node; + } + }); + } else { + state.doc.nodesBetween(from, to, (node, pos) => { + if (pos < from && nodeType && nodeType === node.type) { + trimmedFrom = Math.max(pos, from); + trimmedTo = Math.min(pos + node.nodeSize, to); + lastPos = pos; + lastNode = node; + } + if (pos >= from && pos <= to) { + if (nodeType && nodeType === node.type) { + tr.setNodeMarkup(pos, void 0, { + ...node.attrs, + ...attributes + }); + } + if (markType && node.marks.length) { + node.marks.forEach((mark) => { + if (markType === mark.type) { + const trimmedFrom2 = Math.max(pos, from); + const trimmedTo2 = Math.min(pos + node.nodeSize, to); + tr.addMark(trimmedFrom2, trimmedTo2, markType.create({ + ...mark.attrs, + ...attributes + })); + } + }); + } + } + }); + } + if (lastNode) { + if (lastPos !== void 0) { + tr.setNodeMarkup(lastPos, void 0, { + ...lastNode.attrs, + ...attributes + }); + } + if (markType && lastNode.marks.length) { + lastNode.marks.forEach((mark) => { + if (markType === mark.type) { + tr.addMark(trimmedFrom, trimmedTo, markType.create({ + ...mark.attrs, + ...attributes + })); + } + }); + } + } + }); + } + return true; +}; +var wrapIn2 = (typeOrName, attributes = {}) => ({ state, dispatch }) => { + const type = getNodeType(typeOrName, state.schema); + return wrapIn(type, attributes)(state, dispatch); +}; +var wrapInList2 = (typeOrName, attributes = {}) => ({ state, dispatch }) => { + const type = getNodeType(typeOrName, state.schema); + return wrapInList(type, attributes)(state, dispatch); +}; +var commands = /* @__PURE__ */ Object.freeze({ + __proto__: null, + blur, + clearContent, + clearNodes, + command, + createParagraphNear: createParagraphNear2, + cut, + deleteCurrentNode, + deleteNode, + deleteRange: deleteRange2, + deleteSelection: deleteSelection2, + enter, + exitCode: exitCode2, + extendMarkRange, + first, + focus, + forEach, + insertContent, + insertContentAt, + joinBackward: joinBackward2, + joinDown: joinDown2, + joinForward: joinForward2, + joinItemBackward, + joinItemForward, + joinTextblockBackward: joinTextblockBackward2, + joinTextblockForward: joinTextblockForward2, + joinUp: joinUp2, + keyboardShortcut, + lift: lift3, + liftEmptyBlock: liftEmptyBlock2, + liftListItem: liftListItem2, + newlineInCode: newlineInCode2, + resetAttributes, + scrollIntoView, + selectAll: selectAll2, + selectNodeBackward: selectNodeBackward2, + selectNodeForward: selectNodeForward2, + selectParentNode: selectParentNode2, + selectTextblockEnd: selectTextblockEnd2, + selectTextblockStart: selectTextblockStart2, + setContent, + setMark, + setMeta, + setNode, + setNodeSelection, + setTextSelection, + sinkListItem: sinkListItem2, + splitBlock: splitBlock2, + splitListItem, + toggleList, + toggleMark, + toggleNode, + toggleWrap, + undoInputRule, + unsetAllMarks, + unsetMark, + updateAttributes, + wrapIn: wrapIn2, + wrapInList: wrapInList2 +}); +var Commands = Extension.create({ + name: "commands", + addCommands() { + return { + ...commands + }; + } +}); +var Drop = Extension.create({ + name: "drop", + addProseMirrorPlugins() { + return [ + new Plugin({ + key: new PluginKey("tiptapDrop"), + props: { + handleDrop: (_2, e4, slice, moved) => { + this.editor.emit("drop", { + editor: this.editor, + event: e4, + slice, + moved + }); + } + } + }) + ]; + } +}); +var Editable = Extension.create({ + name: "editable", + addProseMirrorPlugins() { + return [ + new Plugin({ + key: new PluginKey("editable"), + props: { + editable: () => this.editor.options.editable + } + }) + ]; + } +}); +var focusEventsPluginKey = new PluginKey("focusEvents"); +var FocusEvents = Extension.create({ + name: "focusEvents", + addProseMirrorPlugins() { + const { editor } = this; + return [ + new Plugin({ + key: focusEventsPluginKey, + props: { + handleDOMEvents: { + focus: (view, event) => { + editor.isFocused = true; + const transaction = editor.state.tr.setMeta("focus", { event }).setMeta("addToHistory", false); + view.dispatch(transaction); + return false; + }, + blur: (view, event) => { + editor.isFocused = false; + const transaction = editor.state.tr.setMeta("blur", { event }).setMeta("addToHistory", false); + view.dispatch(transaction); + return false; + } + } + } + }) + ]; + } +}); +var Keymap = Extension.create({ + name: "keymap", + addKeyboardShortcuts() { + const handleBackspace = () => this.editor.commands.first(({ commands: commands2 }) => [ + () => commands2.undoInputRule(), + // maybe convert first text block node to default node + () => commands2.command(({ tr }) => { + const { selection, doc: doc3 } = tr; + const { empty: empty2, $anchor } = selection; + const { pos, parent } = $anchor; + const $parentPos = $anchor.parent.isTextblock && pos > 0 ? tr.doc.resolve(pos - 1) : $anchor; + const parentIsIsolating = $parentPos.parent.type.spec.isolating; + const parentPos = $anchor.pos - $anchor.parentOffset; + const isAtStart = parentIsIsolating && $parentPos.parent.childCount === 1 ? parentPos === $anchor.pos : Selection.atStart(doc3).from === pos; + if (!empty2 || !parent.type.isTextblock || parent.textContent.length || !isAtStart || isAtStart && $anchor.parent.type.name === "paragraph") { + return false; + } + return commands2.clearNodes(); + }), + () => commands2.deleteSelection(), + () => commands2.joinBackward(), + () => commands2.selectNodeBackward() + ]); + const handleDelete = () => this.editor.commands.first(({ commands: commands2 }) => [ + () => commands2.deleteSelection(), + () => commands2.deleteCurrentNode(), + () => commands2.joinForward(), + () => commands2.selectNodeForward() + ]); + const handleEnter = () => this.editor.commands.first(({ commands: commands2 }) => [ + () => commands2.newlineInCode(), + () => commands2.createParagraphNear(), + () => commands2.liftEmptyBlock(), + () => commands2.splitBlock() + ]); + const baseKeymap = { + Enter: handleEnter, + "Mod-Enter": () => this.editor.commands.exitCode(), + Backspace: handleBackspace, + "Mod-Backspace": handleBackspace, + "Shift-Backspace": handleBackspace, + Delete: handleDelete, + "Mod-Delete": handleDelete, + "Mod-a": () => this.editor.commands.selectAll() + }; + const pcKeymap = { + ...baseKeymap + }; + const macKeymap = { + ...baseKeymap, + "Ctrl-h": handleBackspace, + "Alt-Backspace": handleBackspace, + "Ctrl-d": handleDelete, + "Ctrl-Alt-Backspace": handleDelete, + "Alt-Delete": handleDelete, + "Alt-d": handleDelete, + "Ctrl-a": () => this.editor.commands.selectTextblockStart(), + "Ctrl-e": () => this.editor.commands.selectTextblockEnd() + }; + if (isiOS() || isMacOS()) { + return macKeymap; + } + return pcKeymap; + }, + addProseMirrorPlugins() { + return [ + // With this plugin we check if the whole document was selected and deleted. + // In this case we will additionally call `clearNodes()` to convert e.g. a heading + // to a paragraph if necessary. + // This is an alternative to ProseMirror's `AllSelection`, which doesn’t work well + // with many other commands. + new Plugin({ + key: new PluginKey("clearDocument"), + appendTransaction: (transactions, oldState, newState) => { + if (transactions.some((tr2) => tr2.getMeta("composition"))) { + return; + } + const docChanges = transactions.some((transaction) => transaction.docChanged) && !oldState.doc.eq(newState.doc); + const ignoreTr = transactions.some((transaction) => transaction.getMeta("preventClearDocument")); + if (!docChanges || ignoreTr) { + return; + } + const { empty: empty2, from, to } = oldState.selection; + const allFrom = Selection.atStart(oldState.doc).from; + const allEnd = Selection.atEnd(oldState.doc).to; + const allWasSelected = from === allFrom && to === allEnd; + if (empty2 || !allWasSelected) { + return; + } + const isEmpty = isNodeEmpty(newState.doc); + if (!isEmpty) { + return; + } + const tr = newState.tr; + const state = createChainableState({ + state: newState, + transaction: tr + }); + const { commands: commands2 } = new CommandManager({ + editor: this.editor, + state + }); + commands2.clearNodes(); + if (!tr.steps.length) { + return; + } + return tr; + } + }) + ]; + } +}); +var Paste = Extension.create({ + name: "paste", + addProseMirrorPlugins() { + return [ + new Plugin({ + key: new PluginKey("tiptapPaste"), + props: { + handlePaste: (_view, e4, slice) => { + this.editor.emit("paste", { + editor: this.editor, + event: e4, + slice + }); + } + } + }) + ]; + } +}); +var Tabindex = Extension.create({ + name: "tabindex", + addProseMirrorPlugins() { + return [ + new Plugin({ + key: new PluginKey("tabindex"), + props: { + attributes: () => this.editor.isEditable ? { tabindex: "0" } : {} + } + }) + ]; + } +}); +var NodePos = class _NodePos { + get name() { + return this.node.type.name; + } + constructor(pos, editor, isBlock = false, node = null) { + this.currentNode = null; + this.actualDepth = null; + this.isBlock = isBlock; + this.resolvedPos = pos; + this.editor = editor; + this.currentNode = node; + } + get node() { + return this.currentNode || this.resolvedPos.node(); + } + get element() { + return this.editor.view.domAtPos(this.pos).node; + } + get depth() { + var _a; + return (_a = this.actualDepth) !== null && _a !== void 0 ? _a : this.resolvedPos.depth; + } + get pos() { + return this.resolvedPos.pos; + } + get content() { + return this.node.content; + } + set content(content) { + let from = this.from; + let to = this.to; + if (this.isBlock) { + if (this.content.size === 0) { + console.error(`You can\u2019t set content on a block node. Tried to set content on ${this.name} at ${this.pos}`); + return; + } + from = this.from + 1; + to = this.to - 1; + } + this.editor.commands.insertContentAt({ from, to }, content); + } + get attributes() { + return this.node.attrs; + } + get textContent() { + return this.node.textContent; + } + get size() { + return this.node.nodeSize; + } + get from() { + if (this.isBlock) { + return this.pos; + } + return this.resolvedPos.start(this.resolvedPos.depth); + } + get range() { + return { + from: this.from, + to: this.to + }; + } + get to() { + if (this.isBlock) { + return this.pos + this.size; + } + return this.resolvedPos.end(this.resolvedPos.depth) + (this.node.isText ? 0 : 1); + } + get parent() { + if (this.depth === 0) { + return null; + } + const parentPos = this.resolvedPos.start(this.resolvedPos.depth - 1); + const $pos = this.resolvedPos.doc.resolve(parentPos); + return new _NodePos($pos, this.editor); + } + get before() { + let $pos = this.resolvedPos.doc.resolve(this.from - (this.isBlock ? 1 : 2)); + if ($pos.depth !== this.depth) { + $pos = this.resolvedPos.doc.resolve(this.from - 3); + } + return new _NodePos($pos, this.editor); + } + get after() { + let $pos = this.resolvedPos.doc.resolve(this.to + (this.isBlock ? 2 : 1)); + if ($pos.depth !== this.depth) { + $pos = this.resolvedPos.doc.resolve(this.to + 3); + } + return new _NodePos($pos, this.editor); + } + get children() { + const children = []; + this.node.content.forEach((node, offset) => { + const isBlock = node.isBlock && !node.isTextblock; + const isNonTextAtom = node.isAtom && !node.isText; + const targetPos = this.pos + offset + (isNonTextAtom ? 0 : 1); + const $pos = this.resolvedPos.doc.resolve(targetPos); + if (!isBlock && $pos.depth <= this.depth) { + return; + } + const childNodePos = new _NodePos($pos, this.editor, isBlock, isBlock ? node : null); + if (isBlock) { + childNodePos.actualDepth = this.depth + 1; + } + children.push(new _NodePos($pos, this.editor, isBlock, isBlock ? node : null)); + }); + return children; + } + get firstChild() { + return this.children[0] || null; + } + get lastChild() { + const children = this.children; + return children[children.length - 1] || null; + } + closest(selector, attributes = {}) { + let node = null; + let currentNode = this.parent; + while (currentNode && !node) { + if (currentNode.node.type.name === selector) { + if (Object.keys(attributes).length > 0) { + const nodeAttributes = currentNode.node.attrs; + const attrKeys = Object.keys(attributes); + for (let index = 0; index < attrKeys.length; index += 1) { + const key = attrKeys[index]; + if (nodeAttributes[key] !== attributes[key]) { + break; + } + } + } else { + node = currentNode; + } + } + currentNode = currentNode.parent; + } + return node; + } + querySelector(selector, attributes = {}) { + return this.querySelectorAll(selector, attributes, true)[0] || null; + } + querySelectorAll(selector, attributes = {}, firstItemOnly = false) { + let nodes = []; + if (!this.children || this.children.length === 0) { + return nodes; + } + const attrKeys = Object.keys(attributes); + this.children.forEach((childPos) => { + if (firstItemOnly && nodes.length > 0) { + return; + } + if (childPos.node.type.name === selector) { + const doesAllAttributesMatch = attrKeys.every((key) => attributes[key] === childPos.node.attrs[key]); + if (doesAllAttributesMatch) { + nodes.push(childPos); + } + } + if (firstItemOnly && nodes.length > 0) { + return; + } + nodes = nodes.concat(childPos.querySelectorAll(selector, attributes, firstItemOnly)); + }); + return nodes; + } + setAttribute(attributes) { + const { tr } = this.editor.state; + tr.setNodeMarkup(this.from, void 0, { + ...this.node.attrs, + ...attributes + }); + this.editor.view.dispatch(tr); + } +}; +var style = `.ProseMirror { + position: relative; +} + +.ProseMirror { + word-wrap: break-word; + white-space: pre-wrap; + white-space: break-spaces; + -webkit-font-variant-ligatures: none; + font-variant-ligatures: none; + font-feature-settings: "liga" 0; /* the above doesn't seem to work in Edge */ +} + +.ProseMirror [contenteditable="false"] { + white-space: normal; +} + +.ProseMirror [contenteditable="false"] [contenteditable="true"] { + white-space: pre-wrap; +} + +.ProseMirror pre { + white-space: pre-wrap; +} + +img.ProseMirror-separator { + display: inline !important; + border: none !important; + margin: 0 !important; + width: 0 !important; + height: 0 !important; +} + +.ProseMirror-gapcursor { + display: none; + pointer-events: none; + position: absolute; + margin: 0; +} + +.ProseMirror-gapcursor:after { + content: ""; + display: block; + position: absolute; + top: -2px; + width: 20px; + border-top: 1px solid black; + animation: ProseMirror-cursor-blink 1.1s steps(2, start) infinite; +} + +@keyframes ProseMirror-cursor-blink { + to { + visibility: hidden; + } +} + +.ProseMirror-hideselection *::selection { + background: transparent; +} + +.ProseMirror-hideselection *::-moz-selection { + background: transparent; +} + +.ProseMirror-hideselection * { + caret-color: transparent; +} + +.ProseMirror-focused .ProseMirror-gapcursor { + display: block; +} + +.tippy-box[data-animation=fade][data-state=hidden] { + opacity: 0 +}`; +function createStyleTag(style2, nonce, suffix) { + const tiptapStyleTag = document.querySelector(`style[data-tiptap-style${suffix ? `-${suffix}` : ""}]`); + if (tiptapStyleTag !== null) { + return tiptapStyleTag; + } + const styleNode = document.createElement("style"); + if (nonce) { + styleNode.setAttribute("nonce", nonce); + } + styleNode.setAttribute(`data-tiptap-style${suffix ? `-${suffix}` : ""}`, ""); + styleNode.innerHTML = style2; + document.getElementsByTagName("head")[0].appendChild(styleNode); + return styleNode; +} +var Editor = class extends EventEmitter { + constructor(options = {}) { + super(); + this.isFocused = false; + this.isInitialized = false; + this.extensionStorage = {}; + this.options = { + element: document.createElement("div"), + content: "", + injectCSS: true, + injectNonce: void 0, + extensions: [], + autofocus: false, + editable: true, + editorProps: {}, + parseOptions: {}, + coreExtensionOptions: {}, + enableInputRules: true, + enablePasteRules: true, + enableCoreExtensions: true, + enableContentCheck: false, + onBeforeCreate: () => null, + onCreate: () => null, + onUpdate: () => null, + onSelectionUpdate: () => null, + onTransaction: () => null, + onFocus: () => null, + onBlur: () => null, + onDestroy: () => null, + onContentError: ({ error }) => { + throw error; + }, + onPaste: () => null, + onDrop: () => null + }; + this.isCapturingTransaction = false; + this.capturedTransaction = null; + this.setOptions(options); + this.createExtensionManager(); + this.createCommandManager(); + this.createSchema(); + this.on("beforeCreate", this.options.onBeforeCreate); + this.emit("beforeCreate", { editor: this }); + this.on("contentError", this.options.onContentError); + this.createView(); + this.injectCSS(); + this.on("create", this.options.onCreate); + this.on("update", this.options.onUpdate); + this.on("selectionUpdate", this.options.onSelectionUpdate); + this.on("transaction", this.options.onTransaction); + this.on("focus", this.options.onFocus); + this.on("blur", this.options.onBlur); + this.on("destroy", this.options.onDestroy); + this.on("drop", ({ event, slice, moved }) => this.options.onDrop(event, slice, moved)); + this.on("paste", ({ event, slice }) => this.options.onPaste(event, slice)); + window.setTimeout(() => { + if (this.isDestroyed) { + return; + } + this.commands.focus(this.options.autofocus); + this.emit("create", { editor: this }); + this.isInitialized = true; + }, 0); + } + /** + * Returns the editor storage. + */ + get storage() { + return this.extensionStorage; + } + /** + * An object of all registered commands. + */ + get commands() { + return this.commandManager.commands; + } + /** + * Create a command chain to call multiple commands at once. + */ + chain() { + return this.commandManager.chain(); + } + /** + * Check if a command or a command chain can be executed. Without executing it. + */ + can() { + return this.commandManager.can(); + } + /** + * Inject CSS styles. + */ + injectCSS() { + if (this.options.injectCSS && document) { + this.css = createStyleTag(style, this.options.injectNonce); + } + } + /** + * Update editor options. + * + * @param options A list of options + */ + setOptions(options = {}) { + this.options = { + ...this.options, + ...options + }; + if (!this.view || !this.state || this.isDestroyed) { + return; + } + if (this.options.editorProps) { + this.view.setProps(this.options.editorProps); + } + this.view.updateState(this.state); + } + /** + * Update editable state of the editor. + */ + setEditable(editable, emitUpdate = true) { + this.setOptions({ editable }); + if (emitUpdate) { + this.emit("update", { editor: this, transaction: this.state.tr }); + } + } + /** + * Returns whether the editor is editable. + */ + get isEditable() { + return this.options.editable && this.view && this.view.editable; + } + /** + * Returns the editor state. + */ + get state() { + return this.view.state; + } + /** + * Register a ProseMirror plugin. + * + * @param plugin A ProseMirror plugin + * @param handlePlugins Control how to merge the plugin into the existing plugins. + * @returns The new editor state + */ + registerPlugin(plugin, handlePlugins) { + const plugins = isFunction(handlePlugins) ? handlePlugins(plugin, [...this.state.plugins]) : [...this.state.plugins, plugin]; + const state = this.state.reconfigure({ plugins }); + this.view.updateState(state); + return state; + } + /** + * Unregister a ProseMirror plugin. + * + * @param nameOrPluginKeyToRemove The plugins name + * @returns The new editor state or undefined if the editor is destroyed + */ + unregisterPlugin(nameOrPluginKeyToRemove) { + if (this.isDestroyed) { + return void 0; + } + const prevPlugins = this.state.plugins; + let plugins = prevPlugins; + [].concat(nameOrPluginKeyToRemove).forEach((nameOrPluginKey) => { + const name = typeof nameOrPluginKey === "string" ? `${nameOrPluginKey}$` : nameOrPluginKey.key; + plugins = plugins.filter((plugin) => !plugin.key.startsWith(name)); + }); + if (prevPlugins.length === plugins.length) { + return void 0; + } + const state = this.state.reconfigure({ + plugins + }); + this.view.updateState(state); + return state; + } + /** + * Creates an extension manager. + */ + createExtensionManager() { + var _a, _b; + const coreExtensions = this.options.enableCoreExtensions ? [ + Editable, + ClipboardTextSerializer.configure({ + blockSeparator: (_b = (_a = this.options.coreExtensionOptions) === null || _a === void 0 ? void 0 : _a.clipboardTextSerializer) === null || _b === void 0 ? void 0 : _b.blockSeparator + }), + Commands, + FocusEvents, + Keymap, + Tabindex, + Drop, + Paste + ].filter((ext) => { + if (typeof this.options.enableCoreExtensions === "object") { + return this.options.enableCoreExtensions[ext.name] !== false; + } + return true; + }) : []; + const allExtensions = [...coreExtensions, ...this.options.extensions].filter((extension) => { + return ["extension", "node", "mark"].includes(extension === null || extension === void 0 ? void 0 : extension.type); + }); + this.extensionManager = new ExtensionManager(allExtensions, this); + } + /** + * Creates an command manager. + */ + createCommandManager() { + this.commandManager = new CommandManager({ + editor: this + }); + } + /** + * Creates a ProseMirror schema. + */ + createSchema() { + this.schema = this.extensionManager.schema; + } + /** + * Creates a ProseMirror view. + */ + createView() { + var _a; + let doc3; + try { + doc3 = createDocument(this.options.content, this.schema, this.options.parseOptions, { errorOnInvalidContent: this.options.enableContentCheck }); + } catch (e4) { + if (!(e4 instanceof Error) || !["[tiptap error]: Invalid JSON content", "[tiptap error]: Invalid HTML content"].includes(e4.message)) { + throw e4; + } + this.emit("contentError", { + editor: this, + error: e4, + disableCollaboration: () => { + if (this.storage.collaboration) { + this.storage.collaboration.isDisabled = true; + } + this.options.extensions = this.options.extensions.filter((extension) => extension.name !== "collaboration"); + this.createExtensionManager(); + } + }); + doc3 = createDocument(this.options.content, this.schema, this.options.parseOptions, { errorOnInvalidContent: false }); + } + const selection = resolveFocusPosition(doc3, this.options.autofocus); + this.view = new EditorView(this.options.element, { + ...this.options.editorProps, + attributes: { + // add `role="textbox"` to the editor element + role: "textbox", + ...(_a = this.options.editorProps) === null || _a === void 0 ? void 0 : _a.attributes + }, + dispatchTransaction: this.dispatchTransaction.bind(this), + state: EditorState.create({ + doc: doc3, + selection: selection || void 0 + }) + }); + const newState = this.state.reconfigure({ + plugins: this.extensionManager.plugins + }); + this.view.updateState(newState); + this.createNodeViews(); + this.prependClass(); + const dom = this.view.dom; + dom.editor = this; + } + /** + * Creates all node views. + */ + createNodeViews() { + if (this.view.isDestroyed) { + return; + } + this.view.setProps({ + nodeViews: this.extensionManager.nodeViews + }); + } + /** + * Prepend class name to element. + */ + prependClass() { + this.view.dom.className = `tiptap ${this.view.dom.className}`; + } + captureTransaction(fn) { + this.isCapturingTransaction = true; + fn(); + this.isCapturingTransaction = false; + const tr = this.capturedTransaction; + this.capturedTransaction = null; + return tr; + } + /** + * The callback over which to send transactions (state updates) produced by the view. + * + * @param transaction An editor state transaction + */ + dispatchTransaction(transaction) { + if (this.view.isDestroyed) { + return; + } + if (this.isCapturingTransaction) { + if (!this.capturedTransaction) { + this.capturedTransaction = transaction; + return; + } + transaction.steps.forEach((step) => { + var _a; + return (_a = this.capturedTransaction) === null || _a === void 0 ? void 0 : _a.step(step); + }); + return; + } + const state = this.state.apply(transaction); + const selectionHasChanged = !this.state.selection.eq(state.selection); + this.emit("beforeTransaction", { + editor: this, + transaction, + nextState: state + }); + this.view.updateState(state); + this.emit("transaction", { + editor: this, + transaction + }); + if (selectionHasChanged) { + this.emit("selectionUpdate", { + editor: this, + transaction + }); + } + const focus2 = transaction.getMeta("focus"); + const blur2 = transaction.getMeta("blur"); + if (focus2) { + this.emit("focus", { + editor: this, + event: focus2.event, + transaction + }); + } + if (blur2) { + this.emit("blur", { + editor: this, + event: blur2.event, + transaction + }); + } + if (!transaction.docChanged || transaction.getMeta("preventUpdate")) { + return; + } + this.emit("update", { + editor: this, + transaction + }); + } + /** + * Get attributes of the currently selected node or mark. + */ + getAttributes(nameOrType) { + return getAttributes(this.state, nameOrType); + } + isActive(nameOrAttributes, attributesOrUndefined) { + const name = typeof nameOrAttributes === "string" ? nameOrAttributes : null; + const attributes = typeof nameOrAttributes === "string" ? attributesOrUndefined : nameOrAttributes; + return isActive(this.state, name, attributes); + } + /** + * Get the document as JSON. + */ + getJSON() { + return this.state.doc.toJSON(); + } + /** + * Get the document as HTML. + */ + getHTML() { + return getHTMLFromFragment(this.state.doc.content, this.schema); + } + /** + * Get the document as text. + */ + getText(options) { + const { blockSeparator = "\n\n", textSerializers = {} } = options || {}; + return getText2(this.state.doc, { + blockSeparator, + textSerializers: { + ...getTextSerializersFromSchema(this.schema), + ...textSerializers + } + }); + } + /** + * Check if there is no content. + */ + get isEmpty() { + return isNodeEmpty(this.state.doc); + } + /** + * Get the number of characters for the current document. + * + * @deprecated + */ + getCharacterCount() { + console.warn('[tiptap warn]: "editor.getCharacterCount()" is deprecated. Please use "editor.storage.characterCount.characters()" instead.'); + return this.state.doc.content.size - 2; + } + /** + * Destroy the editor. + */ + destroy() { + this.emit("destroy"); + if (this.view) { + const dom = this.view.dom; + if (dom && dom.editor) { + delete dom.editor; + } + this.view.destroy(); + } + this.removeAllListeners(); + } + /** + * Check if the editor is already destroyed. + */ + get isDestroyed() { + var _a; + return !((_a = this.view) === null || _a === void 0 ? void 0 : _a.docView); + } + $node(selector, attributes) { + var _a; + return ((_a = this.$doc) === null || _a === void 0 ? void 0 : _a.querySelector(selector, attributes)) || null; + } + $nodes(selector, attributes) { + var _a; + return ((_a = this.$doc) === null || _a === void 0 ? void 0 : _a.querySelectorAll(selector, attributes)) || null; + } + $pos(pos) { + const $pos = this.state.doc.resolve(pos); + return new NodePos($pos, this); + } + get $doc() { + return this.$pos(0); + } +}; +function markInputRule(config) { + return new InputRule({ + find: config.find, + handler: ({ state, range, match }) => { + const attributes = callOrReturn(config.getAttributes, void 0, match); + if (attributes === false || attributes === null) { + return null; + } + const { tr } = state; + const captureGroup = match[match.length - 1]; + const fullMatch = match[0]; + if (captureGroup) { + const startSpaces = fullMatch.search(/\S/); + const textStart = range.from + fullMatch.indexOf(captureGroup); + const textEnd = textStart + captureGroup.length; + const excludedMarks = getMarksBetween(range.from, range.to, state.doc).filter((item) => { + const excluded = item.mark.type.excluded; + return excluded.find((type) => type === config.type && type !== item.mark.type); + }).filter((item) => item.to > textStart); + if (excludedMarks.length) { + return null; + } + if (textEnd < range.to) { + tr.delete(textEnd, range.to); + } + if (textStart > range.from) { + tr.delete(range.from + startSpaces, textStart); + } + const markEnd = range.from + startSpaces + captureGroup.length; + tr.addMark(range.from + startSpaces, markEnd, config.type.create(attributes || {})); + tr.removeStoredMark(config.type); + } + } + }); +} +var Node2 = class _Node { + constructor(config = {}) { + this.type = "node"; + this.name = "node"; + this.parent = null; + this.child = null; + this.config = { + name: this.name, + defaultOptions: {} + }; + this.config = { + ...this.config, + ...config + }; + this.name = this.config.name; + if (config.defaultOptions && Object.keys(config.defaultOptions).length > 0) { + console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${this.name}".`); + } + this.options = this.config.defaultOptions; + if (this.config.addOptions) { + this.options = callOrReturn(getExtensionField(this, "addOptions", { + name: this.name + })); + } + this.storage = callOrReturn(getExtensionField(this, "addStorage", { + name: this.name, + options: this.options + })) || {}; + } + static create(config = {}) { + return new _Node(config); + } + configure(options = {}) { + const extension = this.extend({ + ...this.config, + addOptions: () => { + return mergeDeep(this.options, options); + } + }); + extension.name = this.name; + extension.parent = this.parent; + return extension; + } + extend(extendedConfig = {}) { + const extension = new _Node(extendedConfig); + extension.parent = this; + this.child = extension; + extension.name = extendedConfig.name ? extendedConfig.name : extension.parent.name; + if (extendedConfig.defaultOptions && Object.keys(extendedConfig.defaultOptions).length > 0) { + console.warn(`[tiptap warn]: BREAKING CHANGE: "defaultOptions" is deprecated. Please use "addOptions" instead. Found in extension: "${extension.name}".`); + } + extension.options = callOrReturn(getExtensionField(extension, "addOptions", { + name: extension.name + })); + extension.storage = callOrReturn(getExtensionField(extension, "addStorage", { + name: extension.name, + options: extension.options + })); + return extension; + } +}; +function markPasteRule(config) { + return new PasteRule({ + find: config.find, + handler: ({ state, range, match, pasteEvent }) => { + const attributes = callOrReturn(config.getAttributes, void 0, match, pasteEvent); + if (attributes === false || attributes === null) { + return null; + } + const { tr } = state; + const captureGroup = match[match.length - 1]; + const fullMatch = match[0]; + let markEnd = range.to; + if (captureGroup) { + const startSpaces = fullMatch.search(/\S/); + const textStart = range.from + fullMatch.indexOf(captureGroup); + const textEnd = textStart + captureGroup.length; + const excludedMarks = getMarksBetween(range.from, range.to, state.doc).filter((item) => { + const excluded = item.mark.type.excluded; + return excluded.find((type) => type === config.type && type !== item.mark.type); + }).filter((item) => item.to > textStart); + if (excludedMarks.length) { + return null; + } + if (textEnd < range.to) { + tr.delete(textEnd, range.to); + } + if (textStart > range.from) { + tr.delete(range.from + startSpaces, textStart); + } + markEnd = range.from + startSpaces + captureGroup.length; + tr.addMark(range.from + startSpaces, markEnd, config.type.create(attributes || {})); + tr.removeStoredMark(config.type); + } + } + }); +} + +// node_modules/@tiptap/extension-document/dist/index.js +var Document2 = Node2.create({ + name: "doc", + topNode: true, + content: "block+" +}); + +// node_modules/@tiptap/extension-paragraph/dist/index.js +var Paragraph = Node2.create({ + name: "paragraph", + priority: 1e3, + addOptions() { + return { + HTMLAttributes: {} + }; + }, + group: "block", + content: "inline*", + parseHTML() { + return [ + { tag: "p" } + ]; + }, + renderHTML({ HTMLAttributes }) { + return ["p", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; + }, + addCommands() { + return { + setParagraph: () => ({ commands: commands2 }) => { + return commands2.setNode(this.name); + } + }; + }, + addKeyboardShortcuts() { + return { + "Mod-Alt-0": () => this.editor.commands.setParagraph() + }; + } +}); + +// node_modules/@tiptap/extension-text/dist/index.js +var Text = Node2.create({ + name: "text", + group: "inline" +}); + +// node_modules/@tiptap/extension-hard-break/dist/index.js +var HardBreak = Node2.create({ + name: "hardBreak", + addOptions() { + return { + keepMarks: true, + HTMLAttributes: {} + }; + }, + inline: true, + group: "inline", + selectable: false, + linebreakReplacement: true, + parseHTML() { + return [ + { tag: "br" } + ]; + }, + renderHTML({ HTMLAttributes }) { + return ["br", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes)]; + }, + renderText() { + return "\n"; + }, + addCommands() { + return { + setHardBreak: () => ({ commands: commands2, chain, state, editor }) => { + return commands2.first([ + () => commands2.exitCode(), + () => commands2.command(() => { + const { selection, storedMarks } = state; + if (selection.$from.parent.type.spec.isolating) { + return false; + } + const { keepMarks } = this.options; + const { splittableMarks } = editor.extensionManager; + const marks = storedMarks || selection.$to.parentOffset && selection.$from.marks(); + return chain().insertContent({ type: this.name }).command(({ tr, dispatch }) => { + if (dispatch && marks && keepMarks) { + const filteredMarks = marks.filter((mark) => splittableMarks.includes(mark.type.name)); + tr.ensureMarks(filteredMarks); + } + return true; + }).run(); + }) + ]); + } + }; + }, + addKeyboardShortcuts() { + return { + "Mod-Enter": () => this.editor.commands.setHardBreak(), + "Shift-Enter": () => this.editor.commands.setHardBreak() + }; + } +}); + +// tp-rich-text-box.js +var TpRichTextBox = class extends i4 { + static get styles() { + return [ + i` + :host { + display: flex; + flex-direction: column; + border: 1px solid #ccc; + min-height: 100px; + position: relative; + } + + #editor { + padding: 8px; + flex-grow: 1; + } + + .custom-floating-menu { + display: flex; + padding: 4px; + background-color: #fff; + border: 1px solid #ccc; + border-radius: 4px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + position: absolute; + top: 0; + left: 0; + z-index: 100; + } + + .custom-floating-menu[hidden] { + display: none; + } + ` + ]; + } + constructor() { + super(); + this.extensions = []; + this._slotObserver = new MutationObserver(this._processSlotChanges.bind(this)); + } + render() { + return x` + +
+ `; + } + static get properties() { + return { + editor: { type: Object }, + extensions: { type: Array } + }; + } + firstUpdated() { + this._processChildExtensions(); + this._initEditor(); + this._slotObserver.observe(this, { + childList: true, + subtree: false + }); + } + _initEditor() { + if (this.editor) { + this.editor.destroy(); + } + this.editor = new Editor({ + element: this.shadowRoot.querySelector("#editor"), + extensions: this.extensions, + content: "

Hello World!

" + }); + const children = Array.from(this.children); + children.forEach((child) => { + if (child._editorReady && typeof child._editorReady === "function") { + child._editorReady(this.editor); + } + }); + this.editor.on("selectionUpdate", this._handleSelectionUpdate.bind(this)); + this.editor.on("blur", this._handleSelectionUpdate.bind(this)); + } + _handleSelectionUpdate() { + const { editor } = this; + const menu = this.shadowRoot.querySelector(".custom-floating-menu"); + if (!editor || !menu) { + console.log("Editor or menu element not found."); + return; + } + const { empty: empty2, from, to } = editor.state.selection; + if (empty2 || from === to) { + menu.hidden = true; + console.log("Selection is empty or a caret. Hiding menu."); + return; + } + menu.hidden = false; + requestAnimationFrame(() => { + this._positionMenu(menu, editor); + console.log("Text selected. Showing menu."); + }); + } + _positionMenu(menuElement, editorInstance) { + const { view } = editorInstance; + const { selection } = editorInstance.state; + const { from, to } = selection; + const start = view.coordsAtPos(from); + const end = view.coordsAtPos(to); + let left = (start.left + end.left) / 2; + console.log("Menu offsetHeight:", menuElement.offsetHeight); + let top = start.top - menuElement.offsetHeight - 10; + if (top < 0) { + top = end.bottom + 10; + } + const viewportWidth = window.innerWidth; + const menuWidth = menuElement.offsetWidth; + if (left + menuWidth > viewportWidth) { + left = viewportWidth - menuWidth - 10; + } + if (left < 0) { + left = 10; + } + menuElement.style.left = `${left}px`; + menuElement.style.top = `${top}px`; + console.log(`Menu positioned at: left=${left}px, top=${top}px`); + } + _handleSlotChange(e4) { + this._processChildExtensions(); + } + _processSlotChanges(mutations) { + let needsUpdate = false; + mutations.forEach((mutation) => { + if (mutation.type === "childList") { + needsUpdate = true; + } + }); + if (needsUpdate) { + this._processChildExtensions(); + } + } + _processChildExtensions() { + this.extensions = [ + Document2, + Paragraph, + Text, + HardBreak + ]; + const children = Array.from(this.children); + children.forEach((child) => { + if (child.getExtension && typeof child.getExtension === "function") { + const extension = child.getExtension(); + if (extension) { + this.extensions.push(extension); + } + } + }); + if (this.editor) { + this._initEditor(); + } + } + disconnectedCallback() { + super.disconnectedCallback(); + if (this._slotObserver) { + this._slotObserver.disconnect(); + } + if (this.editor) { + this.editor.destroy(); + } + } +}; +window.customElements.define("tp-rich-text-box", TpRichTextBox); + +// tp-rtb-base-extension.js +var TpRtbBaseExtension = class extends i4 { + static get styles() { + return i` + :host { + display: inline-block; + } + + button { + margin: 0 2px; + padding: 4px 8px; + background: none; + border: 1px solid #ccc; + border-radius: 3px; + cursor: pointer; + } + + button:hover { + background-color: #f0f0f0; + } + + button.active { + background-color: #e0e0e0; + } + `; + } + static get properties() { + return { + label: { type: String }, + active: { type: Boolean, reflect: true } + }; + } + constructor() { + super(); + this.label = ""; + this.active = false; + } + render() { + return x` + + `; + } + connectedCallback() { + super.connectedCallback(); + this._findParentEditor(); + } + _findParentEditor() { + this.parentEditor = this.closest("tp-rich-text-box"); + } + _editorReady(editorInstance) { + this.parentEditor.editor = editorInstance; + this._setupEditorListeners(); + } + _setupEditorListeners() { + } + _handleClick() { + } + getExtension() { + return null; + } +}; + +// node_modules/@tiptap/extension-bold/dist/index.js +var starInputRegex = /(?:^|\s)(\*\*(?!\s+\*\*)((?:[^*]+))\*\*(?!\s+\*\*))$/; +var starPasteRegex = /(?:^|\s)(\*\*(?!\s+\*\*)((?:[^*]+))\*\*(?!\s+\*\*))/g; +var underscoreInputRegex = /(?:^|\s)(__(?!\s+__)((?:[^_]+))__(?!\s+__))$/; +var underscorePasteRegex = /(?:^|\s)(__(?!\s+__)((?:[^_]+))__(?!\s+__))/g; +var Bold = Mark2.create({ + name: "bold", + addOptions() { + return { + HTMLAttributes: {} + }; + }, + parseHTML() { + return [ + { + tag: "strong" + }, + { + tag: "b", + getAttrs: (node) => node.style.fontWeight !== "normal" && null + }, + { + style: "font-weight=400", + clearMark: (mark) => mark.type.name === this.name + }, + { + style: "font-weight", + getAttrs: (value) => /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null + } + ]; + }, + renderHTML({ HTMLAttributes }) { + return ["strong", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; + }, + addCommands() { + return { + setBold: () => ({ commands: commands2 }) => { + return commands2.setMark(this.name); + }, + toggleBold: () => ({ commands: commands2 }) => { + return commands2.toggleMark(this.name); + }, + unsetBold: () => ({ commands: commands2 }) => { + return commands2.unsetMark(this.name); + } + }; + }, + addKeyboardShortcuts() { + return { + "Mod-b": () => this.editor.commands.toggleBold(), + "Mod-B": () => this.editor.commands.toggleBold() + }; + }, + addInputRules() { + return [ + markInputRule({ + find: starInputRegex, + type: this.type + }), + markInputRule({ + find: underscoreInputRegex, + type: this.type + }) + ]; + }, + addPasteRules() { + return [ + markPasteRule({ + find: starPasteRegex, + type: this.type + }), + markPasteRule({ + find: underscorePasteRegex, + type: this.type + }) + ]; + } +}); + +// tp-rtb-bold.js +var TpRtbBold = class extends TpRtbBaseExtension { + constructor() { + super(); + this.label = "Bold"; + } + getExtension() { + return Bold; + } + _handleClick() { + if (this.parentEditor && this.parentEditor.editor) { + this.parentEditor.editor.chain().focus().toggleBold().run(); + } + } + _setupEditorListeners() { + const { editor } = this.parentEditor; + editor.on("selectionUpdate", () => { + this.active = editor.isActive("bold"); + }); + editor.on("focus", () => { + this.active = editor.isActive("bold"); + }); + } +}; +customElements.define("tp-rtb-bold", TpRtbBold); + +// node_modules/@tiptap/extension-italic/dist/index.js +var starInputRegex2 = /(?:^|\s)(\*(?!\s+\*)((?:[^*]+))\*(?!\s+\*))$/; +var starPasteRegex2 = /(?:^|\s)(\*(?!\s+\*)((?:[^*]+))\*(?!\s+\*))/g; +var underscoreInputRegex2 = /(?:^|\s)(_(?!\s+_)((?:[^_]+))_(?!\s+_))$/; +var underscorePasteRegex2 = /(?:^|\s)(_(?!\s+_)((?:[^_]+))_(?!\s+_))/g; +var Italic = Mark2.create({ + name: "italic", + addOptions() { + return { + HTMLAttributes: {} + }; + }, + parseHTML() { + return [ + { + tag: "em" + }, + { + tag: "i", + getAttrs: (node) => node.style.fontStyle !== "normal" && null + }, + { + style: "font-style=normal", + clearMark: (mark) => mark.type.name === this.name + }, + { + style: "font-style=italic" + } + ]; + }, + renderHTML({ HTMLAttributes }) { + return ["em", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; + }, + addCommands() { + return { + setItalic: () => ({ commands: commands2 }) => { + return commands2.setMark(this.name); + }, + toggleItalic: () => ({ commands: commands2 }) => { + return commands2.toggleMark(this.name); + }, + unsetItalic: () => ({ commands: commands2 }) => { + return commands2.unsetMark(this.name); + } + }; + }, + addKeyboardShortcuts() { + return { + "Mod-i": () => this.editor.commands.toggleItalic(), + "Mod-I": () => this.editor.commands.toggleItalic() + }; + }, + addInputRules() { + return [ + markInputRule({ + find: starInputRegex2, + type: this.type + }), + markInputRule({ + find: underscoreInputRegex2, + type: this.type + }) + ]; + }, + addPasteRules() { + return [ + markPasteRule({ + find: starPasteRegex2, + type: this.type + }), + markPasteRule({ + find: underscorePasteRegex2, + type: this.type + }) + ]; + } +}); + +// tp-rtb-italic.js +var TpRtbItalic = class extends TpRtbBaseExtension { + constructor() { + super(); + this.label = "Italic"; + } + getExtension() { + return Italic; + } + _handleClick() { + if (this.parentEditor && this.parentEditor.editor) { + this.parentEditor.editor.chain().focus().toggleItalic().run(); + } + } + _setupEditorListeners() { + const { editor } = this.parentEditor; + editor.on("selectionUpdate", () => { + this.active = editor.isActive("italic"); + }); + editor.on("focus", () => { + this.active = editor.isActive("italic"); + }); + } +}; +customElements.define("tp-rtb-italic", TpRtbItalic); + +// node_modules/@tiptap/extension-strike/dist/index.js +var inputRegex = /(?:^|\s)(~~(?!\s+~~)((?:[^~]+))~~(?!\s+~~))$/; +var pasteRegex = /(?:^|\s)(~~(?!\s+~~)((?:[^~]+))~~(?!\s+~~))/g; +var Strike = Mark2.create({ + name: "strike", + addOptions() { + return { + HTMLAttributes: {} + }; + }, + parseHTML() { + return [ + { + tag: "s" + }, + { + tag: "del" + }, + { + tag: "strike" + }, + { + style: "text-decoration", + consuming: false, + getAttrs: (style2) => style2.includes("line-through") ? {} : false + } + ]; + }, + renderHTML({ HTMLAttributes }) { + return ["s", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; + }, + addCommands() { + return { + setStrike: () => ({ commands: commands2 }) => { + return commands2.setMark(this.name); + }, + toggleStrike: () => ({ commands: commands2 }) => { + return commands2.toggleMark(this.name); + }, + unsetStrike: () => ({ commands: commands2 }) => { + return commands2.unsetMark(this.name); + } + }; + }, + addKeyboardShortcuts() { + return { + "Mod-Shift-s": () => this.editor.commands.toggleStrike() + }; + }, + addInputRules() { + return [ + markInputRule({ + find: inputRegex, + type: this.type + }) + ]; + }, + addPasteRules() { + return [ + markPasteRule({ + find: pasteRegex, + type: this.type + }) + ]; + } +}); + +// tp-rtb-strike.js +var TpRtbStrike = class extends TpRtbBaseExtension { + constructor() { + super(); + this.label = "Strike"; + } + getExtension() { + return Strike; + } + _handleClick() { + if (this.parentEditor && this.parentEditor.editor) { + this.parentEditor.editor.chain().focus().toggleStrike().run(); + } + } + _setupEditorListeners() { + const { editor } = this.parentEditor; + editor.on("selectionUpdate", () => { + this.active = editor.isActive("strike"); + }); + editor.on("focus", () => { + this.active = editor.isActive("strike"); + }); + } +}; +customElements.define("tp-rtb-strike", TpRtbStrike); + +// node_modules/@tiptap/extension-underline/dist/index.js +var Underline = Mark2.create({ + name: "underline", + addOptions() { + return { + HTMLAttributes: {} + }; + }, + parseHTML() { + return [ + { + tag: "u" + }, + { + style: "text-decoration", + consuming: false, + getAttrs: (style2) => style2.includes("underline") ? {} : false + } + ]; + }, + renderHTML({ HTMLAttributes }) { + return ["u", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; + }, + addCommands() { + return { + setUnderline: () => ({ commands: commands2 }) => { + return commands2.setMark(this.name); + }, + toggleUnderline: () => ({ commands: commands2 }) => { + return commands2.toggleMark(this.name); + }, + unsetUnderline: () => ({ commands: commands2 }) => { + return commands2.unsetMark(this.name); + } + }; + }, + addKeyboardShortcuts() { + return { + "Mod-u": () => this.editor.commands.toggleUnderline(), + "Mod-U": () => this.editor.commands.toggleUnderline() + }; + } +}); + +// tp-rtb-underline.js +var TpRtbUnderline = class extends TpRtbBaseExtension { + constructor() { + super(); + this.label = "Underline"; + } + getExtension() { + return Underline; + } + _handleClick() { + if (this.parentEditor && this.parentEditor.editor) { + this.parentEditor.editor.chain().focus().toggleUnderline().run(); + } + } + _setupEditorListeners() { + const { editor } = this.parentEditor; + editor.on("selectionUpdate", () => { + this.active = editor.isActive("underline"); + }); + editor.on("focus", () => { + this.active = editor.isActive("underline"); + }); + } +}; +customElements.define("tp-rtb-underline", TpRtbUnderline); + +// node_modules/@tiptap/extension-code/dist/index.js +var inputRegex2 = /(^|[^`])`([^`]+)`(?!`)/; +var pasteRegex2 = /(^|[^`])`([^`]+)`(?!`)/g; +var Code = Mark2.create({ + name: "code", + addOptions() { + return { + HTMLAttributes: {} + }; + }, + excludes: "_", + code: true, + exitable: true, + parseHTML() { + return [ + { tag: "code" } + ]; + }, + renderHTML({ HTMLAttributes }) { + return ["code", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), 0]; + }, + addCommands() { + return { + setCode: () => ({ commands: commands2 }) => { + return commands2.setMark(this.name); + }, + toggleCode: () => ({ commands: commands2 }) => { + return commands2.toggleMark(this.name); + }, + unsetCode: () => ({ commands: commands2 }) => { + return commands2.unsetMark(this.name); + } + }; + }, + addKeyboardShortcuts() { + return { + "Mod-e": () => this.editor.commands.toggleCode() + }; + }, + addInputRules() { + return [ + markInputRule({ + find: inputRegex2, + type: this.type + }) + ]; + }, + addPasteRules() { + return [ + markPasteRule({ + find: pasteRegex2, + type: this.type + }) + ]; + } +}); + +// tp-rtb-code.js +var TpRtbCode = class extends TpRtbBaseExtension { + constructor() { + super(); + this.label = "Code"; + } + getExtension() { + return Code; + } + _handleClick() { + if (this.parentEditor && this.parentEditor.editor) { + this.parentEditor.editor.chain().focus().toggleCode().run(); + } + } + _setupEditorListeners() { + const { editor } = this.parentEditor; + editor.on("selectionUpdate", () => { + this.active = editor.isActive("code"); + }); + editor.on("focus", () => { + this.active = editor.isActive("code"); + }); + } +}; +customElements.define("tp-rtb-code", TpRtbCode); + +// tp-rtb-clear-format.js +var TpRtbClearFormat = class extends TpRtbBaseExtension { + constructor() { + super(); + this.label = "Clear Format"; + } + _handleClick() { + if (this.parentEditor && this.parentEditor.editor) { + this.parentEditor.editor.chain().focus().unsetAllMarks().run(); + } + } +}; +customElements.define("tp-rtb-clear-format", TpRtbClearFormat); + +// demo/src/the-app.js +var TheApp = class extends i4 { + static get styles() { + return [ + i` + :host { + display: flex; + flex-direction: column; + position: absolute; + inset: 0; + font-family: sans-serif; + } + ` + ]; + } + render() { + return x` + + + + + + + + + `; + } + static get properties() { + return {}; + } + constructor() { + super(); + } +}; +window.customElements.define("the-app", TheApp); +/** +@license +Copyright (c) 2025 trading_peter +This program is available under Apache License Version 2.0 +*/ +/*! Bundled license information: + +@lit/reactive-element/css-tag.js: + (** + * @license + * Copyright 2019 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + *) + +@lit/reactive-element/reactive-element.js: +lit-html/lit-html.js: +lit-element/lit-element.js: + (** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + *) + +lit-html/is-server.js: + (** + * @license + * Copyright 2022 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + *) +*/ +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vbm9kZV9tb2R1bGVzL0BsaXQvcmVhY3RpdmUtZWxlbWVudC9zcmMvY3NzLXRhZy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQGxpdC9yZWFjdGl2ZS1lbGVtZW50L3NyYy9yZWFjdGl2ZS1lbGVtZW50LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9saXQtaHRtbC9zcmMvbGl0LWh0bWwudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL2xpdC1lbGVtZW50L3NyYy9saXQtZWxlbWVudC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvb3JkZXJlZG1hcC9kaXN0L2luZGV4LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9wcm9zZW1pcnJvci1tb2RlbC9kaXN0L2luZGV4LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9wcm9zZW1pcnJvci10cmFuc2Zvcm0vZGlzdC9pbmRleC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvcHJvc2VtaXJyb3Itc3RhdGUvZGlzdC9pbmRleC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvcHJvc2VtaXJyb3Itdmlldy9kaXN0L2luZGV4LmpzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy93M2Mta2V5bmFtZS9pbmRleC5qcyIsICIuLi8uLi9ub2RlX21vZHVsZXMvcHJvc2VtaXJyb3Ita2V5bWFwL2Rpc3QvaW5kZXguanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL3Byb3NlbWlycm9yLWNvbW1hbmRzL2Rpc3QvaW5kZXguanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL3Byb3NlbWlycm9yLXNjaGVtYS1saXN0L2Rpc3QvaW5kZXguanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9jcmVhdGVDaGFpbmFibGVTdGF0ZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9Db21tYW5kTWFuYWdlci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9FdmVudEVtaXR0ZXIudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9nZXRFeHRlbnNpb25GaWVsZC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL3NwbGl0RXh0ZW5zaW9ucy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2dldEF0dHJpYnV0ZXNGcm9tRXh0ZW5zaW9ucy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2dldE5vZGVUeXBlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL3V0aWxpdGllcy9tZXJnZUF0dHJpYnV0ZXMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9nZXRSZW5kZXJlZEF0dHJpYnV0ZXMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvdXRpbGl0aWVzL2lzRnVuY3Rpb24udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvdXRpbGl0aWVzL2NhbGxPclJldHVybi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy91dGlsaXRpZXMvaXNFbXB0eU9iamVjdC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy91dGlsaXRpZXMvZnJvbVN0cmluZy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2luamVjdEV4dGVuc2lvbkF0dHJpYnV0ZXNUb1BhcnNlUnVsZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2dldFNjaGVtYUJ5UmVzb2x2ZWRFeHRlbnNpb25zLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvZ2V0U2NoZW1hVHlwZUJ5TmFtZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2lzRXh0ZW5zaW9uUnVsZXNFbmFibGVkLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvZ2V0SFRNTEZyb21GcmFnbWVudC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2dldFRleHRDb250ZW50RnJvbU5vZGVzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL3V0aWxpdGllcy9pc1JlZ0V4cC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9JbnB1dFJ1bGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvdXRpbGl0aWVzL2lzUGxhaW5PYmplY3QudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvdXRpbGl0aWVzL21lcmdlRGVlcC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9NYXJrLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL3V0aWxpdGllcy9pc051bWJlci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9QYXN0ZVJ1bGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvdXRpbGl0aWVzL2ZpbmREdXBsaWNhdGVzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL0V4dGVuc2lvbk1hbmFnZXIudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvRXh0ZW5zaW9uLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvZ2V0VGV4dEJldHdlZW4udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9nZXRUZXh0U2VyaWFsaXplcnNGcm9tU2NoZW1hLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2V4dGVuc2lvbnMvY2xpcGJvYXJkVGV4dFNlcmlhbGl6ZXIudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvYmx1ci50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9jbGVhckNvbnRlbnQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvY2xlYXJOb2Rlcy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9jb21tYW5kLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL2NyZWF0ZVBhcmFncmFwaE5lYXIudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvY3V0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL2RlbGV0ZUN1cnJlbnROb2RlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL2RlbGV0ZU5vZGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvZGVsZXRlUmFuZ2UudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvZGVsZXRlU2VsZWN0aW9uLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL2VudGVyLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL2V4aXRDb2RlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL3V0aWxpdGllcy9vYmplY3RJbmNsdWRlcy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2dldE1hcmtSYW5nZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2dldE1hcmtUeXBlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL2V4dGVuZE1hcmtSYW5nZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9maXJzdC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2lzVGV4dFNlbGVjdGlvbi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy91dGlsaXRpZXMvbWluTWF4LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvcmVzb2x2ZUZvY3VzUG9zaXRpb24udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvdXRpbGl0aWVzL2lzQW5kcm9pZC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy91dGlsaXRpZXMvaXNpT1MudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvZm9jdXMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvZm9yRWFjaC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9pbnNlcnRDb250ZW50LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL3V0aWxpdGllcy9lbGVtZW50RnJvbVN0cmluZy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2NyZWF0ZU5vZGVGcm9tQ29udGVudC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL3NlbGVjdGlvblRvSW5zZXJ0aW9uRW5kLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL2luc2VydENvbnRlbnRBdC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9qb2luLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL2pvaW5JdGVtQmFja3dhcmQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvam9pbkl0ZW1Gb3J3YXJkLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL2pvaW5UZXh0YmxvY2tCYWNrd2FyZC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9qb2luVGV4dGJsb2NrRm9yd2FyZC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy91dGlsaXRpZXMvaXNNYWNPUy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9rZXlib2FyZFNob3J0Y3V0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvaXNOb2RlQWN0aXZlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL2xpZnQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvbGlmdEVtcHR5QmxvY2sudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvbGlmdExpc3RJdGVtLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL25ld2xpbmVJbkNvZGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9nZXRTY2hlbWFUeXBlTmFtZUJ5TmFtZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy91dGlsaXRpZXMvZGVsZXRlUHJvcHMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvcmVzZXRBdHRyaWJ1dGVzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL3Njcm9sbEludG9WaWV3LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL3NlbGVjdEFsbC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9zZWxlY3ROb2RlQmFja3dhcmQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvc2VsZWN0Tm9kZUZvcndhcmQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvc2VsZWN0UGFyZW50Tm9kZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9zZWxlY3RUZXh0YmxvY2tFbmQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvc2VsZWN0VGV4dGJsb2NrU3RhcnQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9jcmVhdGVEb2N1bWVudC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9zZXRDb250ZW50LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvZ2V0TWFya0F0dHJpYnV0ZXMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9jb21iaW5lVHJhbnNhY3Rpb25TdGVwcy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2RlZmF1bHRCbG9ja0F0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvZmluZENoaWxkcmVuLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvZmluZENoaWxkcmVuSW5SYW5nZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2ZpbmRQYXJlbnROb2RlQ2xvc2VzdFRvUG9zLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvZmluZFBhcmVudE5vZGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9nZXRTY2hlbWEudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9nZW5lcmF0ZUhUTUwudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9nZW5lcmF0ZUpTT04udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9nZXRUZXh0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvZ2VuZXJhdGVUZXh0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvZ2V0Tm9kZUF0dHJpYnV0ZXMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9nZXRBdHRyaWJ1dGVzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL3V0aWxpdGllcy9yZW1vdmVEdXBsaWNhdGVzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvZ2V0Q2hhbmdlZFJhbmdlcy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2dldERlYnVnSlNPTi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2dldE1hcmtzQmV0d2Vlbi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9oZWxwZXJzL2dldE5vZGVBdFBvc2l0aW9uLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvZ2V0U3BsaXR0ZWRBdHRyaWJ1dGVzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvaXNNYXJrQWN0aXZlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvaXNBY3RpdmUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9pc0F0RW5kT2ZOb2RlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvaXNBdFN0YXJ0T2ZOb2RlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvaXNMaXN0LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2hlbHBlcnMvaXNOb2RlRW1wdHkudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9pc05vZGVTZWxlY3Rpb24udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9wb3NUb0RPTVJlY3QudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaGVscGVycy9yZXdyaXRlVW5rbm93bkNvbnRlbnQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvc2V0TWFyay50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9zZXRNZXRhLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL3NldE5vZGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvc2V0Tm9kZVNlbGVjdGlvbi50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9zZXRUZXh0U2VsZWN0aW9uLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL3NpbmtMaXN0SXRlbS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy9zcGxpdEJsb2NrLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL3NwbGl0TGlzdEl0ZW0udHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvdG9nZ2xlTGlzdC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy90b2dnbGVNYXJrLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL3RvZ2dsZU5vZGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvdG9nZ2xlV3JhcC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9jb21tYW5kcy91bmRvSW5wdXRSdWxlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL3Vuc2V0QWxsTWFya3MudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvdW5zZXRNYXJrLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL3VwZGF0ZUF0dHJpYnV0ZXMudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvY29tbWFuZHMvd3JhcEluLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2NvbW1hbmRzL3dyYXBJbkxpc3QudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvZXh0ZW5zaW9ucy9jb21tYW5kcy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9leHRlbnNpb25zL2Ryb3AudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvZXh0ZW5zaW9ucy9lZGl0YWJsZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9leHRlbnNpb25zL2ZvY3VzRXZlbnRzLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2V4dGVuc2lvbnMva2V5bWFwLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2V4dGVuc2lvbnMvcGFzdGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvZXh0ZW5zaW9ucy90YWJpbmRleC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9Ob2RlUG9zLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL3N0eWxlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL3V0aWxpdGllcy9jcmVhdGVTdHlsZVRhZy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9FZGl0b3IudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaW5wdXRSdWxlcy9tYXJrSW5wdXRSdWxlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2lucHV0UnVsZXMvbm9kZUlucHV0UnVsZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9pbnB1dFJ1bGVzL3RleHRibG9ja1R5cGVJbnB1dFJ1bGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvaW5wdXRSdWxlcy90ZXh0SW5wdXRSdWxlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL2lucHV0UnVsZXMvd3JhcHBpbmdJbnB1dFJ1bGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvTm9kZS50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9Ob2RlVmlldy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9wYXN0ZVJ1bGVzL21hcmtQYXN0ZVJ1bGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvdXRpbGl0aWVzL2VzY2FwZUZvclJlZ0V4LnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL3V0aWxpdGllcy9pc1N0cmluZy50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9jb3JlL3NyYy9wYXN0ZVJ1bGVzL25vZGVQYXN0ZVJ1bGUudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvY29yZS9zcmMvcGFzdGVSdWxlcy90ZXh0UGFzdGVSdWxlLnRzIiwgIi4uLy4uL25vZGVfbW9kdWxlcy9AdGlwdGFwL2NvcmUvc3JjL1RyYWNrZXIudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLWRvY3VtZW50L3NyYy9kb2N1bWVudC50cyIsICIuLi8uLi9ub2RlX21vZHVsZXMvQHRpcHRhcC9leHRlbnNpb24tcGFyYWdyYXBoL3NyYy9wYXJhZ3JhcGgudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLXRleHQvc3JjL3RleHQudHMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLWhhcmQtYnJlYWsvc3JjL2hhcmQtYnJlYWsudHMiLCAiLi4vLi4vdHAtcmljaC10ZXh0LWJveC5qcyIsICIuLi8uLi90cC1ydGItYmFzZS1leHRlbnNpb24uanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLWJvbGQvc3JjL2JvbGQudHMiLCAiLi4vLi4vdHAtcnRiLWJvbGQuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLWl0YWxpYy9zcmMvaXRhbGljLnRzIiwgIi4uLy4uL3RwLXJ0Yi1pdGFsaWMuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLXN0cmlrZS9zcmMvc3RyaWtlLnRzIiwgIi4uLy4uL3RwLXJ0Yi1zdHJpa2UuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLXVuZGVybGluZS9zcmMvdW5kZXJsaW5lLnRzIiwgIi4uLy4uL3RwLXJ0Yi11bmRlcmxpbmUuanMiLCAiLi4vLi4vbm9kZV9tb2R1bGVzL0B0aXB0YXAvZXh0ZW5zaW9uLWNvZGUvc3JjL2NvZGUudHMiLCAiLi4vLi4vdHAtcnRiLWNvZGUuanMiLCAiLi4vLi4vdHAtcnRiLWNsZWFyLWZvcm1hdC5qcyIsICIuLi9zcmMvdGhlLWFwcC5qcyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIExMQ1xuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZVxuICovXG5cbmNvbnN0IE5PREVfTU9ERSA9IGZhbHNlO1xuXG4vLyBBbGxvd3MgbWluaWZpZXJzIHRvIHJlbmFtZSByZWZlcmVuY2VzIHRvIGdsb2JhbFRoaXNcbmNvbnN0IGdsb2JhbCA9IGdsb2JhbFRoaXM7XG5cbi8qKlxuICogV2hldGhlciB0aGUgY3VycmVudCBicm93c2VyIHN1cHBvcnRzIGBhZG9wdGVkU3R5bGVTaGVldHNgLlxuICovXG5leHBvcnQgY29uc3Qgc3VwcG9ydHNBZG9wdGluZ1N0eWxlU2hlZXRzOiBib29sZWFuID1cbiAgZ2xvYmFsLlNoYWRvd1Jvb3QgJiZcbiAgKGdsb2JhbC5TaGFkeUNTUyA9PT0gdW5kZWZpbmVkIHx8IGdsb2JhbC5TaGFkeUNTUy5uYXRpdmVTaGFkb3cpICYmXG4gICdhZG9wdGVkU3R5bGVTaGVldHMnIGluIERvY3VtZW50LnByb3RvdHlwZSAmJlxuICAncmVwbGFjZScgaW4gQ1NTU3R5bGVTaGVldC5wcm90b3R5cGU7XG5cbi8qKlxuICogQSBDU1NSZXN1bHQgb3IgbmF0aXZlIENTU1N0eWxlU2hlZXQuXG4gKlxuICogSW4gYnJvd3NlcnMgdGhhdCBzdXBwb3J0IGNvbnN0cnVjdGlibGUgQ1NTIHN0eWxlIHNoZWV0cywgQ1NTU3R5bGVTaGVldFxuICogb2JqZWN0IGNhbiBiZSB1c2VkIGZvciBzdHlsaW5nIGFsb25nIHNpZGUgQ1NTUmVzdWx0IGZyb20gdGhlIGBjc3NgXG4gKiB0ZW1wbGF0ZSB0YWcuXG4gKi9cbmV4cG9ydCB0eXBlIENTU1Jlc3VsdE9yTmF0aXZlID0gQ1NTUmVzdWx0IHwgQ1NTU3R5bGVTaGVldDtcblxuZXhwb3J0IHR5cGUgQ1NTUmVzdWx0QXJyYXkgPSBBcnJheTxDU1NSZXN1bHRPck5hdGl2ZSB8IENTU1Jlc3VsdEFycmF5PjtcblxuLyoqXG4gKiBBIHNpbmdsZSBDU1NSZXN1bHQsIENTU1N0eWxlU2hlZXQsIG9yIGFuIGFycmF5IG9yIG5lc3RlZCBhcnJheXMgb2YgdGhvc2UuXG4gKi9cbmV4cG9ydCB0eXBlIENTU1Jlc3VsdEdyb3VwID0gQ1NTUmVzdWx0T3JOYXRpdmUgfCBDU1NSZXN1bHRBcnJheTtcblxuY29uc3QgY29uc3RydWN0aW9uVG9rZW4gPSBTeW1ib2woKTtcblxuY29uc3QgY3NzVGFnQ2FjaGUgPSBuZXcgV2Vha01hcDxUZW1wbGF0ZVN0cmluZ3NBcnJheSwgQ1NTU3R5bGVTaGVldD4oKTtcblxuLyoqXG4gKiBBIGNvbnRhaW5lciBmb3IgYSBzdHJpbmcgb2YgQ1NTIHRleHQsIHRoYXQgbWF5IGJlIHVzZWQgdG8gY3JlYXRlIGEgQ1NTU3R5bGVTaGVldC5cbiAqXG4gKiBDU1NSZXN1bHQgaXMgdGhlIHJldHVybiB2YWx1ZSBvZiBgY3NzYC10YWdnZWQgdGVtcGxhdGUgbGl0ZXJhbHMgYW5kXG4gKiBgdW5zYWZlQ1NTKClgLiBJbiBvcmRlciB0byBlbnN1cmUgdGhhdCBDU1NSZXN1bHRzIGFyZSBvbmx5IGNyZWF0ZWQgdmlhIHRoZVxuICogYGNzc2AgdGFnIGFuZCBgdW5zYWZlQ1NTKClgLCBDU1NSZXN1bHQgY2Fubm90IGJlIGNvbnN0cnVjdGVkIGRpcmVjdGx5LlxuICovXG5leHBvcnQgY2xhc3MgQ1NTUmVzdWx0IHtcbiAgLy8gVGhpcyBwcm9wZXJ0eSBuZWVkcyB0byByZW1haW4gdW5taW5pZmllZC5cbiAgWydfJGNzc1Jlc3VsdCQnXSA9IHRydWU7XG4gIHJlYWRvbmx5IGNzc1RleHQ6IHN0cmluZztcbiAgcHJpdmF0ZSBfc3R5bGVTaGVldD86IENTU1N0eWxlU2hlZXQ7XG4gIHByaXZhdGUgX3N0cmluZ3M6IFRlbXBsYXRlU3RyaW5nc0FycmF5IHwgdW5kZWZpbmVkO1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoXG4gICAgY3NzVGV4dDogc3RyaW5nLFxuICAgIHN0cmluZ3M6IFRlbXBsYXRlU3RyaW5nc0FycmF5IHwgdW5kZWZpbmVkLFxuICAgIHNhZmVUb2tlbjogc3ltYm9sXG4gICkge1xuICAgIGlmIChzYWZlVG9rZW4gIT09IGNvbnN0cnVjdGlvblRva2VuKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdDU1NSZXN1bHQgaXMgbm90IGNvbnN0cnVjdGFibGUuIFVzZSBgdW5zYWZlQ1NTYCBvciBgY3NzYCBpbnN0ZWFkLidcbiAgICAgICk7XG4gICAgfVxuICAgIHRoaXMuY3NzVGV4dCA9IGNzc1RleHQ7XG4gICAgdGhpcy5fc3RyaW5ncyA9IHN0cmluZ3M7XG4gIH1cblxuICAvLyBUaGlzIGlzIGEgZ2V0dGVyIHNvIHRoYXQgaXQncyBsYXp5LiBJbiBwcmFjdGljZSwgdGhpcyBtZWFucyBzdHlsZXNoZWV0c1xuICAvLyBhcmUgbm90IGNyZWF0ZWQgdW50aWwgdGhlIGZpcnN0IGVsZW1lbnQgaW5zdGFuY2UgaXMgbWFkZS5cbiAgZ2V0IHN0eWxlU2hlZXQoKTogQ1NTU3R5bGVTaGVldCB8IHVuZGVmaW5lZCB7XG4gICAgLy8gSWYgYHN1cHBvcnRzQWRvcHRpbmdTdHlsZVNoZWV0c2AgaXMgdHJ1ZSB0aGVuIHdlIGFzc3VtZSBDU1NTdHlsZVNoZWV0IGlzXG4gICAgLy8gY29uc3RydWN0YWJsZS5cbiAgICBsZXQgc3R5bGVTaGVldCA9IHRoaXMuX3N0eWxlU2hlZXQ7XG4gICAgY29uc3Qgc3RyaW5ncyA9IHRoaXMuX3N0cmluZ3M7XG4gICAgaWYgKHN1cHBvcnRzQWRvcHRpbmdTdHlsZVNoZWV0cyAmJiBzdHlsZVNoZWV0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IGNhY2hlYWJsZSA9IHN0cmluZ3MgIT09IHVuZGVmaW5lZCAmJiBzdHJpbmdzLmxlbmd0aCA9PT0gMTtcbiAgICAgIGlmIChjYWNoZWFibGUpIHtcbiAgICAgICAgc3R5bGVTaGVldCA9IGNzc1RhZ0NhY2hlLmdldChzdHJpbmdzKTtcbiAgICAgIH1cbiAgICAgIGlmIChzdHlsZVNoZWV0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgKHRoaXMuX3N0eWxlU2hlZXQgPSBzdHlsZVNoZWV0ID0gbmV3IENTU1N0eWxlU2hlZXQoKSkucmVwbGFjZVN5bmMoXG4gICAgICAgICAgdGhpcy5jc3NUZXh0XG4gICAgICAgICk7XG4gICAgICAgIGlmIChjYWNoZWFibGUpIHtcbiAgICAgICAgICBjc3NUYWdDYWNoZS5zZXQoc3RyaW5ncywgc3R5bGVTaGVldCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHN0eWxlU2hlZXQ7XG4gIH1cblxuICB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmNzc1RleHQ7XG4gIH1cbn1cblxudHlwZSBDb25zdHJ1Y3RhYmxlQ1NTUmVzdWx0ID0gQ1NTUmVzdWx0ICYge1xuICBuZXcgKFxuICAgIGNzc1RleHQ6IHN0cmluZyxcbiAgICBzdHJpbmdzOiBUZW1wbGF0ZVN0cmluZ3NBcnJheSB8IHVuZGVmaW5lZCxcbiAgICBzYWZlVG9rZW46IHN5bWJvbFxuICApOiBDU1NSZXN1bHQ7XG59O1xuXG5jb25zdCB0ZXh0RnJvbUNTU1Jlc3VsdCA9ICh2YWx1ZTogQ1NTUmVzdWx0R3JvdXAgfCBudW1iZXIpID0+IHtcbiAgLy8gVGhpcyBwcm9wZXJ0eSBuZWVkcyB0byByZW1haW4gdW5taW5pZmllZC5cbiAgaWYgKCh2YWx1ZSBhcyBDU1NSZXN1bHQpWydfJGNzc1Jlc3VsdCQnXSA9PT0gdHJ1ZSkge1xuICAgIHJldHVybiAodmFsdWUgYXMgQ1NTUmVzdWx0KS5jc3NUZXh0O1xuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYFZhbHVlIHBhc3NlZCB0byAnY3NzJyBmdW5jdGlvbiBtdXN0IGJlIGEgJ2NzcycgZnVuY3Rpb24gcmVzdWx0OiBgICtcbiAgICAgICAgYCR7dmFsdWV9LiBVc2UgJ3Vuc2FmZUNTUycgdG8gcGFzcyBub24tbGl0ZXJhbCB2YWx1ZXMsIGJ1dCB0YWtlIGNhcmUgYCArXG4gICAgICAgIGB0byBlbnN1cmUgcGFnZSBzZWN1cml0eS5gXG4gICAgKTtcbiAgfVxufTtcblxuLyoqXG4gKiBXcmFwIGEgdmFsdWUgZm9yIGludGVycG9sYXRpb24gaW4gYSB7QGxpbmtjb2RlIGNzc30gdGFnZ2VkIHRlbXBsYXRlIGxpdGVyYWwuXG4gKlxuICogVGhpcyBpcyB1bnNhZmUgYmVjYXVzZSB1bnRydXN0ZWQgQ1NTIHRleHQgY2FuIGJlIHVzZWQgdG8gcGhvbmUgaG9tZVxuICogb3IgZXhmaWx0cmF0ZSBkYXRhIHRvIGFuIGF0dGFja2VyIGNvbnRyb2xsZWQgc2l0ZS4gVGFrZSBjYXJlIHRvIG9ubHkgdXNlXG4gKiB0aGlzIHdpdGggdHJ1c3RlZCBpbnB1dC5cbiAqL1xuZXhwb3J0IGNvbnN0IHVuc2FmZUNTUyA9ICh2YWx1ZTogdW5rbm93bikgPT5cbiAgbmV3IChDU1NSZXN1bHQgYXMgQ29uc3RydWN0YWJsZUNTU1Jlc3VsdCkoXG4gICAgdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyA/IHZhbHVlIDogU3RyaW5nKHZhbHVlKSxcbiAgICB1bmRlZmluZWQsXG4gICAgY29uc3RydWN0aW9uVG9rZW5cbiAgKTtcblxuLyoqXG4gKiBBIHRlbXBsYXRlIGxpdGVyYWwgdGFnIHdoaWNoIGNhbiBiZSB1c2VkIHdpdGggTGl0RWxlbWVudCdzXG4gKiB7QGxpbmtjb2RlIExpdEVsZW1lbnQuc3R5bGVzfSBwcm9wZXJ0eSB0byBzZXQgZWxlbWVudCBzdHlsZXMuXG4gKlxuICogRm9yIHNlY3VyaXR5IHJlYXNvbnMsIG9ubHkgbGl0ZXJhbCBzdHJpbmcgdmFsdWVzIGFuZCBudW1iZXIgbWF5IGJlIHVzZWQgaW5cbiAqIGVtYmVkZGVkIGV4cHJlc3Npb25zLiBUbyBpbmNvcnBvcmF0ZSBub24tbGl0ZXJhbCB2YWx1ZXMge0BsaW5rY29kZSB1bnNhZmVDU1N9XG4gKiBtYXkgYmUgdXNlZCBpbnNpZGUgYW4gZXhwcmVzc2lvbi5cbiAqL1xuZXhwb3J0IGNvbnN0IGNzcyA9IChcbiAgc3RyaW5nczogVGVtcGxhdGVTdHJpbmdzQXJyYXksXG4gIC4uLnZhbHVlczogKENTU1Jlc3VsdEdyb3VwIHwgbnVtYmVyKVtdXG4pOiBDU1NSZXN1bHQgPT4ge1xuICBjb25zdCBjc3NUZXh0ID1cbiAgICBzdHJpbmdzLmxlbmd0aCA9PT0gMVxuICAgICAgPyBzdHJpbmdzWzBdXG4gICAgICA6IHZhbHVlcy5yZWR1Y2UoXG4gICAgICAgICAgKGFjYywgdiwgaWR4KSA9PiBhY2MgKyB0ZXh0RnJvbUNTU1Jlc3VsdCh2KSArIHN0cmluZ3NbaWR4ICsgMV0sXG4gICAgICAgICAgc3RyaW5nc1swXVxuICAgICAgICApO1xuICByZXR1cm4gbmV3IChDU1NSZXN1bHQgYXMgQ29uc3RydWN0YWJsZUNTU1Jlc3VsdCkoXG4gICAgY3NzVGV4dCxcbiAgICBzdHJpbmdzLFxuICAgIGNvbnN0cnVjdGlvblRva2VuXG4gICk7XG59O1xuXG4vKipcbiAqIEFwcGxpZXMgdGhlIGdpdmVuIHN0eWxlcyB0byBhIGBzaGFkb3dSb290YC4gV2hlbiBTaGFkb3cgRE9NIGlzXG4gKiBhdmFpbGFibGUgYnV0IGBhZG9wdGVkU3R5bGVTaGVldHNgIGlzIG5vdCwgc3R5bGVzIGFyZSBhcHBlbmRlZCB0byB0aGVcbiAqIGBzaGFkb3dSb290YCB0byBbbWltaWMgdGhlIG5hdGl2ZSBmZWF0dXJlXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvU2hhZG93Um9vdC9hZG9wdGVkU3R5bGVTaGVldHMpLlxuICogTm90ZSwgd2hlbiBzaGltbWluZyBpcyB1c2VkLCBhbnkgc3R5bGVzIHRoYXQgYXJlIHN1YnNlcXVlbnRseSBwbGFjZWQgaW50b1xuICogdGhlIHNoYWRvd1Jvb3Qgc2hvdWxkIGJlIHBsYWNlZCAqYmVmb3JlKiBhbnkgc2hpbW1lZCBhZG9wdGVkIHN0eWxlcy4gVGhpc1xuICogd2lsbCBtYXRjaCBzcGVjIGJlaGF2aW9yIHRoYXQgZ2l2ZXMgYWRvcHRlZCBzaGVldHMgcHJlY2VkZW5jZSBvdmVyIHN0eWxlcyBpblxuICogc2hhZG93Um9vdC5cbiAqL1xuZXhwb3J0IGNvbnN0IGFkb3B0U3R5bGVzID0gKFxuICByZW5kZXJSb290OiBTaGFkb3dSb290LFxuICBzdHlsZXM6IEFycmF5PENTU1Jlc3VsdE9yTmF0aXZlPlxuKSA9PiB7XG4gIGlmIChzdXBwb3J0c0Fkb3B0aW5nU3R5bGVTaGVldHMpIHtcbiAgICAocmVuZGVyUm9vdCBhcyBTaGFkb3dSb290KS5hZG9wdGVkU3R5bGVTaGVldHMgPSBzdHlsZXMubWFwKChzKSA9PlxuICAgICAgcyBpbnN0YW5jZW9mIENTU1N0eWxlU2hlZXQgPyBzIDogcy5zdHlsZVNoZWV0IVxuICAgICk7XG4gIH0gZWxzZSB7XG4gICAgZm9yIChjb25zdCBzIG9mIHN0eWxlcykge1xuICAgICAgY29uc3Qgc3R5bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzdHlsZScpO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgIGNvbnN0IG5vbmNlID0gKGdsb2JhbCBhcyBhbnkpWydsaXROb25jZSddO1xuICAgICAgaWYgKG5vbmNlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgc3R5bGUuc2V0QXR0cmlidXRlKCdub25jZScsIG5vbmNlKTtcbiAgICAgIH1cbiAgICAgIHN0eWxlLnRleHRDb250ZW50ID0gKHMgYXMgQ1NTUmVzdWx0KS5jc3NUZXh0O1xuICAgICAgcmVuZGVyUm9vdC5hcHBlbmRDaGlsZChzdHlsZSk7XG4gICAgfVxuICB9XG59O1xuXG5jb25zdCBjc3NSZXN1bHRGcm9tU3R5bGVTaGVldCA9IChzaGVldDogQ1NTU3R5bGVTaGVldCkgPT4ge1xuICBsZXQgY3NzVGV4dCA9ICcnO1xuICBmb3IgKGNvbnN0IHJ1bGUgb2Ygc2hlZXQuY3NzUnVsZXMpIHtcbiAgICBjc3NUZXh0ICs9IHJ1bGUuY3NzVGV4dDtcbiAgfVxuICByZXR1cm4gdW5zYWZlQ1NTKGNzc1RleHQpO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldENvbXBhdGlibGVTdHlsZSA9XG4gIHN1cHBvcnRzQWRvcHRpbmdTdHlsZVNoZWV0cyB8fFxuICAoTk9ERV9NT0RFICYmIGdsb2JhbC5DU1NTdHlsZVNoZWV0ID09PSB1bmRlZmluZWQpXG4gICAgPyAoczogQ1NTUmVzdWx0T3JOYXRpdmUpID0+IHNcbiAgICA6IChzOiBDU1NSZXN1bHRPck5hdGl2ZSkgPT5cbiAgICAgICAgcyBpbnN0YW5jZW9mIENTU1N0eWxlU2hlZXQgPyBjc3NSZXN1bHRGcm9tU3R5bGVTaGVldChzKSA6IHM7XG4iLCAiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQ1xuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZVxuICovXG5cbi8qKlxuICogVXNlIHRoaXMgbW9kdWxlIGlmIHlvdSB3YW50IHRvIGNyZWF0ZSB5b3VyIG93biBiYXNlIGNsYXNzIGV4dGVuZGluZ1xuICoge0BsaW5rIFJlYWN0aXZlRWxlbWVudH0uXG4gKiBAcGFja2FnZURvY3VtZW50YXRpb25cbiAqL1xuXG5pbXBvcnQge1xuICBnZXRDb21wYXRpYmxlU3R5bGUsXG4gIGFkb3B0U3R5bGVzLFxuICBDU1NSZXN1bHRHcm91cCxcbiAgQ1NTUmVzdWx0T3JOYXRpdmUsXG59IGZyb20gJy4vY3NzLXRhZy5qcyc7XG5pbXBvcnQgdHlwZSB7XG4gIFJlYWN0aXZlQ29udHJvbGxlcixcbiAgUmVhY3RpdmVDb250cm9sbGVySG9zdCxcbn0gZnJvbSAnLi9yZWFjdGl2ZS1jb250cm9sbGVyLmpzJztcblxuLy8gSW4gdGhlIE5vZGUgYnVpbGQsIHRoaXMgaW1wb3J0IHdpbGwgYmUgaW5qZWN0ZWQgYnkgUm9sbHVwOlxuLy8gaW1wb3J0IHtIVE1MRWxlbWVudCwgY3VzdG9tRWxlbWVudHN9IGZyb20gJ0BsaXQtbGFicy9zc3ItZG9tLXNoaW0nO1xuXG5leHBvcnQgKiBmcm9tICcuL2Nzcy10YWcuanMnO1xuZXhwb3J0IHR5cGUge1xuICBSZWFjdGl2ZUNvbnRyb2xsZXIsXG4gIFJlYWN0aXZlQ29udHJvbGxlckhvc3QsXG59IGZyb20gJy4vcmVhY3RpdmUtY29udHJvbGxlci5qcyc7XG5cbi8qKlxuICogUmVtb3ZlcyB0aGUgYHJlYWRvbmx5YCBtb2RpZmllciBmcm9tIHByb3BlcnRpZXMgaW4gdGhlIHVuaW9uIEsuXG4gKlxuICogVGhpcyBpcyBhIHNhZmVyIHdheSB0byBjYXN0IGEgdmFsdWUgdG8gYSB0eXBlIHdpdGggYSBtdXRhYmxlIHZlcnNpb24gb2YgYVxuICogcmVhZG9ubHkgZmllbGQsIHRoYW4gY2FzdGluZyB0byBhbiBpbnRlcmZhY2Ugd2l0aCB0aGUgZmllbGQgcmUtZGVjbGFyZWRcbiAqIGJlY2F1c2UgaXQgcHJlc2VydmVzIHRoZSB0eXBlIG9mIGFsbCB0aGUgZmllbGRzIGFuZCB3YXJucyBvbiB0eXBvcy5cbiAqL1xudHlwZSBNdXRhYmxlPFQsIEsgZXh0ZW5kcyBrZXlvZiBUPiA9IE9taXQ8VCwgSz4gJiB7XG4gIC1yZWFkb25seSBbUCBpbiBrZXlvZiBQaWNrPFQsIEs+XTogUCBleHRlbmRzIEsgPyBUW1BdIDogbmV2ZXI7XG59O1xuXG4vLyBUT0RPIChqdXN0aW5mYWduYW5pKTogQWRkIGBoYXNPd25gIGhlcmUgd2hlbiB3ZSBzaGlwIEVTMjAyMlxuY29uc3Qge1xuICBpcyxcbiAgZGVmaW5lUHJvcGVydHksXG4gIGdldE93blByb3BlcnR5RGVzY3JpcHRvcixcbiAgZ2V0T3duUHJvcGVydHlOYW1lcyxcbiAgZ2V0T3duUHJvcGVydHlTeW1ib2xzLFxuICBnZXRQcm90b3R5cGVPZixcbn0gPSBPYmplY3Q7XG5cbmNvbnN0IE5PREVfTU9ERSA9IGZhbHNlO1xuXG4vLyBMZXRzIGEgbWluaWZpZXIgcmVwbGFjZSBnbG9iYWxUaGlzIHJlZmVyZW5jZXMgd2l0aCBhIG1pbmlmaWVkIG5hbWVcbmNvbnN0IGdsb2JhbCA9IGdsb2JhbFRoaXM7XG5cbmlmIChOT0RFX01PREUpIHtcbiAgZ2xvYmFsLmN1c3RvbUVsZW1lbnRzID8/PSBjdXN0b21FbGVtZW50cztcbn1cblxuY29uc3QgREVWX01PREUgPSB0cnVlO1xuXG5sZXQgaXNzdWVXYXJuaW5nOiAoY29kZTogc3RyaW5nLCB3YXJuaW5nOiBzdHJpbmcpID0+IHZvaWQ7XG5cbmNvbnN0IHRydXN0ZWRUeXBlcyA9IChnbG9iYWwgYXMgdW5rbm93biBhcyB7dHJ1c3RlZFR5cGVzPzoge2VtcHR5U2NyaXB0OiAnJ319KVxuICAudHJ1c3RlZFR5cGVzO1xuXG4vLyBUZW1wb3Jhcnkgd29ya2Fyb3VuZCBmb3IgaHR0cHM6Ly9jcmJ1Zy5jb20vOTkzMjY4XG4vLyBDdXJyZW50bHksIGFueSBhdHRyaWJ1dGUgc3RhcnRpbmcgd2l0aCBcIm9uXCIgaXMgY29uc2lkZXJlZCB0byBiZSBhXG4vLyBUcnVzdGVkU2NyaXB0IHNvdXJjZS4gU3VjaCBib29sZWFuIGF0dHJpYnV0ZXMgbXVzdCBiZSBzZXQgdG8gdGhlIGVxdWl2YWxlbnRcbi8vIHRydXN0ZWQgZW1wdHlTY3JpcHQgdmFsdWUuXG5jb25zdCBlbXB0eVN0cmluZ0ZvckJvb2xlYW5BdHRyaWJ1dGUgPSB0cnVzdGVkVHlwZXNcbiAgPyAodHJ1c3RlZFR5cGVzLmVtcHR5U2NyaXB0IGFzIHVua25vd24gYXMgJycpXG4gIDogJyc7XG5cbmNvbnN0IHBvbHlmaWxsU3VwcG9ydCA9IERFVl9NT0RFXG4gID8gZ2xvYmFsLnJlYWN0aXZlRWxlbWVudFBvbHlmaWxsU3VwcG9ydERldk1vZGVcbiAgOiBnbG9iYWwucmVhY3RpdmVFbGVtZW50UG9seWZpbGxTdXBwb3J0O1xuXG5pZiAoREVWX01PREUpIHtcbiAgLy8gRW5zdXJlIHdhcm5pbmdzIGFyZSBpc3N1ZWQgb25seSAxeCwgZXZlbiBpZiBtdWx0aXBsZSB2ZXJzaW9ucyBvZiBMaXRcbiAgLy8gYXJlIGxvYWRlZC5cbiAgZ2xvYmFsLmxpdElzc3VlZFdhcm5pbmdzID8/PSBuZXcgU2V0KCk7XG5cbiAgLyoqXG4gICAqIElzc3VlIGEgd2FybmluZyBpZiB3ZSBoYXZlbid0IGFscmVhZHksIGJhc2VkIGVpdGhlciBvbiBgY29kZWAgb3IgYHdhcm5pbmdgLlxuICAgKiBXYXJuaW5ncyBhcmUgZGlzYWJsZWQgYXV0b21hdGljYWxseSBvbmx5IGJ5IGB3YXJuaW5nYDsgZGlzYWJsaW5nIHZpYSBgY29kZWBcbiAgICogY2FuIGJlIGRvbmUgYnkgdXNlcnMuXG4gICAqL1xuICBpc3N1ZVdhcm5pbmcgPSAoY29kZTogc3RyaW5nLCB3YXJuaW5nOiBzdHJpbmcpID0+IHtcbiAgICB3YXJuaW5nICs9IGAgU2VlIGh0dHBzOi8vbGl0LmRldi9tc2cvJHtjb2RlfSBmb3IgbW9yZSBpbmZvcm1hdGlvbi5gO1xuICAgIGlmIChcbiAgICAgICFnbG9iYWwubGl0SXNzdWVkV2FybmluZ3MhLmhhcyh3YXJuaW5nKSAmJlxuICAgICAgIWdsb2JhbC5saXRJc3N1ZWRXYXJuaW5ncyEuaGFzKGNvZGUpXG4gICAgKSB7XG4gICAgICBjb25zb2xlLndhcm4od2FybmluZyk7XG4gICAgICBnbG9iYWwubGl0SXNzdWVkV2FybmluZ3MhLmFkZCh3YXJuaW5nKTtcbiAgICB9XG4gIH07XG5cbiAgcXVldWVNaWNyb3Rhc2soKCkgPT4ge1xuICAgIGlzc3VlV2FybmluZyhcbiAgICAgICdkZXYtbW9kZScsXG4gICAgICBgTGl0IGlzIGluIGRldiBtb2RlLiBOb3QgcmVjb21tZW5kZWQgZm9yIHByb2R1Y3Rpb24hYFxuICAgICk7XG5cbiAgICAvLyBJc3N1ZSBwb2x5ZmlsbCBzdXBwb3J0IHdhcm5pbmcuXG4gICAgaWYgKGdsb2JhbC5TaGFkeURPTT8uaW5Vc2UgJiYgcG9seWZpbGxTdXBwb3J0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGlzc3VlV2FybmluZyhcbiAgICAgICAgJ3BvbHlmaWxsLXN1cHBvcnQtbWlzc2luZycsXG4gICAgICAgIGBTaGFkb3cgRE9NIGlzIGJlaW5nIHBvbHlmaWxsZWQgdmlhIFxcYFNoYWR5RE9NXFxgIGJ1dCBgICtcbiAgICAgICAgICBgdGhlIFxcYHBvbHlmaWxsLXN1cHBvcnRcXGAgbW9kdWxlIGhhcyBub3QgYmVlbiBsb2FkZWQuYFxuICAgICAgKTtcbiAgICB9XG4gIH0pO1xufVxuXG4vKipcbiAqIENvbnRhaW5zIHR5cGVzIHRoYXQgYXJlIHBhcnQgb2YgdGhlIHVuc3RhYmxlIGRlYnVnIEFQSS5cbiAqXG4gKiBFdmVyeXRoaW5nIGluIHRoaXMgQVBJIGlzIG5vdCBzdGFibGUgYW5kIG1heSBjaGFuZ2Ugb3IgYmUgcmVtb3ZlZCBpbiB0aGUgZnV0dXJlLFxuICogZXZlbiBvbiBwYXRjaCByZWxlYXNlcy5cbiAqL1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1uYW1lc3BhY2VcbmV4cG9ydCBuYW1lc3BhY2UgUmVhY3RpdmVVbnN0YWJsZSB7XG4gIC8qKlxuICAgKiBXaGVuIExpdCBpcyBydW5uaW5nIGluIGRldiBtb2RlIGFuZCBgd2luZG93LmVtaXRMaXREZWJ1Z0xvZ0V2ZW50c2AgaXMgdHJ1ZSxcbiAgICogd2Ugd2lsbCBlbWl0ICdsaXQtZGVidWcnIGV2ZW50cyB0byB3aW5kb3csIHdpdGggbGl2ZSBkZXRhaWxzIGFib3V0IHRoZSB1cGRhdGUgYW5kIHJlbmRlclxuICAgKiBsaWZlY3ljbGUuIFRoZXNlIGNhbiBiZSB1c2VmdWwgZm9yIHdyaXRpbmcgZGVidWcgdG9vbGluZyBhbmQgdmlzdWFsaXphdGlvbnMuXG4gICAqXG4gICAqIFBsZWFzZSBiZSBhd2FyZSB0aGF0IHJ1bm5pbmcgd2l0aCB3aW5kb3cuZW1pdExpdERlYnVnTG9nRXZlbnRzIGhhcyBwZXJmb3JtYW5jZSBvdmVyaGVhZCxcbiAgICogbWFraW5nIGNlcnRhaW4gb3BlcmF0aW9ucyB0aGF0IGFyZSBub3JtYWxseSB2ZXJ5IGNoZWFwIChsaWtlIGEgbm8tb3AgcmVuZGVyKSBtdWNoIHNsb3dlcixcbiAgICogYmVjYXVzZSB3ZSBtdXN0IGNvcHkgZGF0YSBhbmQgZGlzcGF0Y2ggZXZlbnRzLlxuICAgKi9cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1uYW1lc3BhY2VcbiAgZXhwb3J0IG5hbWVzcGFjZSBEZWJ1Z0xvZyB7XG4gICAgZXhwb3J0IHR5cGUgRW50cnkgPSBVcGRhdGU7XG4gICAgZXhwb3J0IGludGVyZmFjZSBVcGRhdGUge1xuICAgICAga2luZDogJ3VwZGF0ZSc7XG4gICAgfVxuICB9XG59XG5cbmludGVyZmFjZSBEZWJ1Z0xvZ2dpbmdXaW5kb3cge1xuICAvLyBFdmVuIGluIGRldiBtb2RlLCB3ZSBnZW5lcmFsbHkgZG9uJ3Qgd2FudCB0byBlbWl0IHRoZXNlIGV2ZW50cywgYXMgdGhhdCdzXG4gIC8vIGFub3RoZXIgbGV2ZWwgb2YgY29zdCwgc28gb25seSBlbWl0IHRoZW0gd2hlbiBERVZfTU9ERSBpcyB0cnVlIF9hbmRfIHdoZW5cbiAgLy8gd2luZG93LmVtaXRMaXREZWJ1Z0V2ZW50cyBpcyB0cnVlLlxuICBlbWl0TGl0RGVidWdMb2dFdmVudHM/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIFVzZWZ1bCBmb3IgdmlzdWFsaXppbmcgYW5kIGxvZ2dpbmcgaW5zaWdodHMgaW50byB3aGF0IHRoZSBMaXQgdGVtcGxhdGUgc3lzdGVtIGlzIGRvaW5nLlxuICpcbiAqIENvbXBpbGVkIG91dCBvZiBwcm9kIG1vZGUgYnVpbGRzLlxuICovXG5jb25zdCBkZWJ1Z0xvZ0V2ZW50ID0gREVWX01PREVcbiAgPyAoZXZlbnQ6IFJlYWN0aXZlVW5zdGFibGUuRGVidWdMb2cuRW50cnkpID0+IHtcbiAgICAgIGNvbnN0IHNob3VsZEVtaXQgPSAoZ2xvYmFsIGFzIHVua25vd24gYXMgRGVidWdMb2dnaW5nV2luZG93KVxuICAgICAgICAuZW1pdExpdERlYnVnTG9nRXZlbnRzO1xuICAgICAgaWYgKCFzaG91bGRFbWl0KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGdsb2JhbC5kaXNwYXRjaEV2ZW50KFxuICAgICAgICBuZXcgQ3VzdG9tRXZlbnQ8UmVhY3RpdmVVbnN0YWJsZS5EZWJ1Z0xvZy5FbnRyeT4oJ2xpdC1kZWJ1ZycsIHtcbiAgICAgICAgICBkZXRhaWw6IGV2ZW50LFxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9XG4gIDogdW5kZWZpbmVkO1xuXG4vKlxuICogV2hlbiB1c2luZyBDbG9zdXJlIENvbXBpbGVyLCBKU0NvbXBpbGVyX3JlbmFtZVByb3BlcnR5KHByb3BlcnR5LCBvYmplY3QpIGlzXG4gKiByZXBsYWNlZCBhdCBjb21waWxlIHRpbWUgYnkgdGhlIG11bmdlZCBuYW1lIGZvciBvYmplY3RbcHJvcGVydHldLiBXZSBjYW5ub3RcbiAqIGFsaWFzIHRoaXMgZnVuY3Rpb24sIHNvIHdlIGhhdmUgdG8gdXNlIGEgc21hbGwgc2hpbSB0aGF0IGhhcyB0aGUgc2FtZVxuICogYmVoYXZpb3Igd2hlbiBub3QgY29tcGlsaW5nLlxuICovXG4vKkBfX0lOTElORV9fKi9cbmNvbnN0IEpTQ29tcGlsZXJfcmVuYW1lUHJvcGVydHkgPSA8UCBleHRlbmRzIFByb3BlcnR5S2V5PihcbiAgcHJvcDogUCxcbiAgX29iajogdW5rbm93blxuKTogUCA9PiBwcm9wO1xuXG4vKipcbiAqIENvbnZlcnRzIHByb3BlcnR5IHZhbHVlcyB0byBhbmQgZnJvbSBhdHRyaWJ1dGUgdmFsdWVzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbXBsZXhBdHRyaWJ1dGVDb252ZXJ0ZXI8VHlwZSA9IHVua25vd24sIFR5cGVIaW50ID0gdW5rbm93bj4ge1xuICAvKipcbiAgICogQ2FsbGVkIHRvIGNvbnZlcnQgYW4gYXR0cmlidXRlIHZhbHVlIHRvIGEgcHJvcGVydHlcbiAgICogdmFsdWUuXG4gICAqL1xuICBmcm9tQXR0cmlidXRlPyh2YWx1ZTogc3RyaW5nIHwgbnVsbCwgdHlwZT86IFR5cGVIaW50KTogVHlwZTtcblxuICAvKipcbiAgICogQ2FsbGVkIHRvIGNvbnZlcnQgYSBwcm9wZXJ0eSB2YWx1ZSB0byBhbiBhdHRyaWJ1dGVcbiAgICogdmFsdWUuXG4gICAqXG4gICAqIEl0IHJldHVybnMgdW5rbm93biBpbnN0ZWFkIG9mIHN0cmluZywgdG8gYmUgY29tcGF0aWJsZSB3aXRoXG4gICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9XSUNHL3RydXN0ZWQtdHlwZXMgKGFuZCBzaW1pbGFyIGVmZm9ydHMpLlxuICAgKi9cbiAgdG9BdHRyaWJ1dGU/KHZhbHVlOiBUeXBlLCB0eXBlPzogVHlwZUhpbnQpOiB1bmtub3duO1xufVxuXG50eXBlIEF0dHJpYnV0ZUNvbnZlcnRlcjxUeXBlID0gdW5rbm93biwgVHlwZUhpbnQgPSB1bmtub3duPiA9XG4gIHwgQ29tcGxleEF0dHJpYnV0ZUNvbnZlcnRlcjxUeXBlPlxuICB8ICgodmFsdWU6IHN0cmluZyB8IG51bGwsIHR5cGU/OiBUeXBlSGludCkgPT4gVHlwZSk7XG5cbi8qKlxuICogRGVmaW5lcyBvcHRpb25zIGZvciBhIHByb3BlcnR5IGFjY2Vzc29yLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFByb3BlcnR5RGVjbGFyYXRpb248VHlwZSA9IHVua25vd24sIFR5cGVIaW50ID0gdW5rbm93bj4ge1xuICAvKipcbiAgICogV2hlbiBzZXQgdG8gYHRydWVgLCBpbmRpY2F0ZXMgdGhlIHByb3BlcnR5IGlzIGludGVybmFsIHByaXZhdGUgc3RhdGUuIFRoZVxuICAgKiBwcm9wZXJ0eSBzaG91bGQgbm90IGJlIHNldCBieSB1c2Vycy4gV2hlbiB1c2luZyBUeXBlU2NyaXB0LCB0aGlzIHByb3BlcnR5XG4gICAqIHNob3VsZCBiZSBtYXJrZWQgYXMgYHByaXZhdGVgIG9yIGBwcm90ZWN0ZWRgLCBhbmQgaXQgaXMgYWxzbyBhIGNvbW1vblxuICAgKiBwcmFjdGljZSB0byB1c2UgYSBsZWFkaW5nIGBfYCBpbiB0aGUgbmFtZS4gVGhlIHByb3BlcnR5IGlzIG5vdCBhZGRlZCB0b1xuICAgKiBgb2JzZXJ2ZWRBdHRyaWJ1dGVzYC5cbiAgICovXG4gIHJlYWRvbmx5IHN0YXRlPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogSW5kaWNhdGVzIGhvdyBhbmQgd2hldGhlciB0aGUgcHJvcGVydHkgYmVjb21lcyBhbiBvYnNlcnZlZCBhdHRyaWJ1dGUuXG4gICAqIElmIHRoZSB2YWx1ZSBpcyBgZmFsc2VgLCB0aGUgcHJvcGVydHkgaXMgbm90IGFkZGVkIHRvIGBvYnNlcnZlZEF0dHJpYnV0ZXNgLlxuICAgKiBJZiB0cnVlIG9yIGFic2VudCwgdGhlIGxvd2VyY2FzZWQgcHJvcGVydHkgbmFtZSBpcyBvYnNlcnZlZCAoZS5nLiBgZm9vQmFyYFxuICAgKiBiZWNvbWVzIGBmb29iYXJgKS4gSWYgYSBzdHJpbmcsIHRoZSBzdHJpbmcgdmFsdWUgaXMgb2JzZXJ2ZWQgKGUuZ1xuICAgKiBgYXR0cmlidXRlOiAnZm9vLWJhcidgKS5cbiAgICovXG4gIHJlYWRvbmx5IGF0dHJpYnV0ZT86IGJvb2xlYW4gfCBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyB0aGUgdHlwZSBvZiB0aGUgcHJvcGVydHkuIFRoaXMgaXMgdXNlZCBvbmx5IGFzIGEgaGludCBmb3IgdGhlXG4gICAqIGBjb252ZXJ0ZXJgIHRvIGRldGVybWluZSBob3cgdG8gY29udmVydCB0aGUgYXR0cmlidXRlXG4gICAqIHRvL2Zyb20gYSBwcm9wZXJ0eS5cbiAgICovXG4gIHJlYWRvbmx5IHR5cGU/OiBUeXBlSGludDtcblxuICAvKipcbiAgICogSW5kaWNhdGVzIGhvdyB0byBjb252ZXJ0IHRoZSBhdHRyaWJ1dGUgdG8vZnJvbSBhIHByb3BlcnR5LiBJZiB0aGlzIHZhbHVlXG4gICAqIGlzIGEgZnVuY3Rpb24sIGl0IGlzIHVzZWQgdG8gY29udmVydCB0aGUgYXR0cmlidXRlIHZhbHVlIGEgdGhlIHByb3BlcnR5XG4gICAqIHZhbHVlLiBJZiBpdCdzIGFuIG9iamVjdCwgaXQgY2FuIGhhdmUga2V5cyBmb3IgYGZyb21BdHRyaWJ1dGVgIGFuZFxuICAgKiBgdG9BdHRyaWJ1dGVgLiBJZiBubyBgdG9BdHRyaWJ1dGVgIGZ1bmN0aW9uIGlzIHByb3ZpZGVkIGFuZFxuICAgKiBgcmVmbGVjdGAgaXMgc2V0IHRvIGB0cnVlYCwgdGhlIHByb3BlcnR5IHZhbHVlIGlzIHNldCBkaXJlY3RseSB0byB0aGVcbiAgICogYXR0cmlidXRlLiBBIGRlZmF1bHQgYGNvbnZlcnRlcmAgaXMgdXNlZCBpZiBub25lIGlzIHByb3ZpZGVkOyBpdCBzdXBwb3J0c1xuICAgKiBgQm9vbGVhbmAsIGBTdHJpbmdgLCBgTnVtYmVyYCwgYE9iamVjdGAsIGFuZCBgQXJyYXlgLiBOb3RlLFxuICAgKiB3aGVuIGEgcHJvcGVydHkgY2hhbmdlcyBhbmQgdGhlIGNvbnZlcnRlciBpcyB1c2VkIHRvIHVwZGF0ZSB0aGUgYXR0cmlidXRlLFxuICAgKiB0aGUgcHJvcGVydHkgaXMgbmV2ZXIgdXBkYXRlZCBhZ2FpbiBhcyBhIHJlc3VsdCBvZiB0aGUgYXR0cmlidXRlIGNoYW5naW5nLFxuICAgKiBhbmQgdmljZSB2ZXJzYS5cbiAgICovXG4gIHJlYWRvbmx5IGNvbnZlcnRlcj86IEF0dHJpYnV0ZUNvbnZlcnRlcjxUeXBlLCBUeXBlSGludD47XG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyBpZiB0aGUgcHJvcGVydHkgc2hvdWxkIHJlZmxlY3QgdG8gYW4gYXR0cmlidXRlLlxuICAgKiBJZiBgdHJ1ZWAsIHdoZW4gdGhlIHByb3BlcnR5IGlzIHNldCwgdGhlIGF0dHJpYnV0ZSBpcyBzZXQgdXNpbmcgdGhlXG4gICAqIGF0dHJpYnV0ZSBuYW1lIGRldGVybWluZWQgYWNjb3JkaW5nIHRvIHRoZSBydWxlcyBmb3IgdGhlIGBhdHRyaWJ1dGVgXG4gICAqIHByb3BlcnR5IG9wdGlvbiBhbmQgdGhlIHZhbHVlIG9mIHRoZSBwcm9wZXJ0eSBjb252ZXJ0ZWQgdXNpbmcgdGhlIHJ1bGVzXG4gICAqIGZyb20gdGhlIGBjb252ZXJ0ZXJgIHByb3BlcnR5IG9wdGlvbi5cbiAgICovXG4gIHJlYWRvbmx5IHJlZmxlY3Q/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBBIGZ1bmN0aW9uIHRoYXQgaW5kaWNhdGVzIGlmIGEgcHJvcGVydHkgc2hvdWxkIGJlIGNvbnNpZGVyZWQgY2hhbmdlZCB3aGVuXG4gICAqIGl0IGlzIHNldC4gVGhlIGZ1bmN0aW9uIHNob3VsZCB0YWtlIHRoZSBgbmV3VmFsdWVgIGFuZCBgb2xkVmFsdWVgIGFuZFxuICAgKiByZXR1cm4gYHRydWVgIGlmIGFuIHVwZGF0ZSBzaG91bGQgYmUgcmVxdWVzdGVkLlxuICAgKi9cbiAgaGFzQ2hhbmdlZD8odmFsdWU6IFR5cGUsIG9sZFZhbHVlOiBUeXBlKTogYm9vbGVhbjtcblxuICAvKipcbiAgICogSW5kaWNhdGVzIHdoZXRoZXIgYW4gYWNjZXNzb3Igd2lsbCBiZSBjcmVhdGVkIGZvciB0aGlzIHByb3BlcnR5LiBCeVxuICAgKiBkZWZhdWx0LCBhbiBhY2Nlc3NvciB3aWxsIGJlIGdlbmVyYXRlZCBmb3IgdGhpcyBwcm9wZXJ0eSB0aGF0IHJlcXVlc3RzIGFuXG4gICAqIHVwZGF0ZSB3aGVuIHNldC4gSWYgdGhpcyBmbGFnIGlzIGB0cnVlYCwgbm8gYWNjZXNzb3Igd2lsbCBiZSBjcmVhdGVkLCBhbmRcbiAgICogaXQgd2lsbCBiZSB0aGUgdXNlcidzIHJlc3BvbnNpYmlsaXR5IHRvIGNhbGxcbiAgICogYHRoaXMucmVxdWVzdFVwZGF0ZShwcm9wZXJ0eU5hbWUsIG9sZFZhbHVlKWAgdG8gcmVxdWVzdCBhbiB1cGRhdGUgd2hlblxuICAgKiB0aGUgcHJvcGVydHkgY2hhbmdlcy5cbiAgICovXG4gIHJlYWRvbmx5IG5vQWNjZXNzb3I/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoaXMgcHJvcGVydHkgaXMgd3JhcHBpbmcgYWNjZXNzb3JzLiBUaGlzIGlzIHNldCBieSBgQHByb3BlcnR5YFxuICAgKiB0byBjb250cm9sIHRoZSBpbml0aWFsIHZhbHVlIGNoYW5nZSBhbmQgcmVmbGVjdGlvbiBsb2dpYy5cbiAgICpcbiAgICogQGludGVybmFsXG4gICAqL1xuICB3cmFwcGVkPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogV2hlbiBgdHJ1ZWAsIHVzZXMgdGhlIGluaXRpYWwgdmFsdWUgb2YgdGhlIHByb3BlcnR5IGFzIHRoZSBkZWZhdWx0IHZhbHVlLFxuICAgKiB3aGljaCBjaGFuZ2VzIGhvdyBhdHRyaWJ1dGVzIGFyZSBoYW5kbGVkOlxuICAgKiAgLSBUaGUgaW5pdGlhbCB2YWx1ZSBkb2VzICpub3QqIHJlZmxlY3QsIGV2ZW4gaWYgdGhlIGByZWZsZWN0YCBvcHRpb24gaXMgYHRydWVgLlxuICAgKiAgICBTdWJzZXF1ZW50IGNoYW5nZXMgdG8gdGhlIHByb3BlcnR5IHdpbGwgcmVmbGVjdCwgZXZlbiBpZiB0aGV5IGFyZSBlcXVhbCB0byB0aGVcbiAgICogICAgIGRlZmF1bHQgdmFsdWUuXG4gICAqICAtIFdoZW4gdGhlIGF0dHJpYnV0ZSBpcyByZW1vdmVkLCB0aGUgcHJvcGVydHkgaXMgc2V0IHRvIHRoZSBkZWZhdWx0IHZhbHVlXG4gICAqICAtIFRoZSBpbml0aWFsIHZhbHVlIHdpbGwgbm90IHRyaWdnZXIgYW4gb2xkIHZhbHVlIGluIHRoZSBgY2hhbmdlZFByb3BlcnRpZXNgIG1hcFxuICAgKiAgICBhcmd1bWVudCB0byB1cGRhdGUgbGlmZWN5Y2xlIG1ldGhvZHMuXG4gICAqXG4gICAqIFdoZW4gc2V0LCBwcm9wZXJ0aWVzIG11c3QgYmUgaW5pdGlhbGl6ZWQsIGVpdGhlciB3aXRoIGEgZmllbGQgaW5pdGlhbGl6ZXIsIG9yIGFuXG4gICAqIGFzc2lnbm1lbnQgaW4gdGhlIGNvbnN0cnVjdG9yLiBOb3QgaW5pdGlhbGl6aW5nIHRoZSBwcm9wZXJ0eSBtYXkgbGVhZCB0b1xuICAgKiBpbXByb3BlciBoYW5kbGluZyBvZiBzdWJzZXF1ZW50IHByb3BlcnR5IGFzc2lnbm1lbnRzLlxuICAgKlxuICAgKiBXaGlsZSB0aGlzIGJlaGF2aW9yIGlzIG9wdC1pbiwgbW9zdCBwcm9wZXJ0aWVzIHRoYXQgcmVmbGVjdCB0byBhdHRyaWJ1dGVzIHNob3VsZFxuICAgKiB1c2UgYHVzZURlZmF1bHQ6IHRydWVgIHNvIHRoYXQgdGhlaXIgaW5pdGlhbCB2YWx1ZXMgZG8gbm90IHJlZmxlY3QuXG4gICAqL1xuICB1c2VEZWZhdWx0PzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBNYXAgb2YgcHJvcGVydGllcyB0byBQcm9wZXJ0eURlY2xhcmF0aW9uIG9wdGlvbnMuIEZvciBlYWNoIHByb3BlcnR5IGFuXG4gKiBhY2Nlc3NvciBpcyBtYWRlLCBhbmQgdGhlIHByb3BlcnR5IGlzIHByb2Nlc3NlZCBhY2NvcmRpbmcgdG8gdGhlXG4gKiBQcm9wZXJ0eURlY2xhcmF0aW9uIG9wdGlvbnMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHJvcGVydHlEZWNsYXJhdGlvbnMge1xuICByZWFkb25seSBba2V5OiBzdHJpbmddOiBQcm9wZXJ0eURlY2xhcmF0aW9uO1xufVxuXG50eXBlIFByb3BlcnR5RGVjbGFyYXRpb25NYXAgPSBNYXA8UHJvcGVydHlLZXksIFByb3BlcnR5RGVjbGFyYXRpb24+O1xuXG50eXBlIEF0dHJpYnV0ZU1hcCA9IE1hcDxzdHJpbmcsIFByb3BlcnR5S2V5PjtcblxuLyoqXG4gKiBBIE1hcCBvZiBwcm9wZXJ0eSBrZXlzIHRvIHZhbHVlcy5cbiAqXG4gKiBUYWtlcyBhbiBvcHRpb25hbCB0eXBlIHBhcmFtZXRlciBULCB3aGljaCB3aGVuIHNwZWNpZmllZCBhcyBhIG5vbi1hbnksXG4gKiBub24tdW5rbm93biB0eXBlLCB3aWxsIG1ha2UgdGhlIE1hcCBtb3JlIHN0cm9uZ2x5LXR5cGVkLCBhc3NvY2lhdGluZyB0aGUgbWFwXG4gKiBrZXlzIHdpdGggdGhlaXIgY29ycmVzcG9uZGluZyB2YWx1ZSB0eXBlIG9uIFQuXG4gKlxuICogVXNlIGBQcm9wZXJ0eVZhbHVlczx0aGlzPmAgd2hlbiBvdmVycmlkaW5nIFJlYWN0aXZlRWxlbWVudC51cGRhdGUoKSBhbmRcbiAqIG90aGVyIGxpZmVjeWNsZSBtZXRob2RzIGluIG9yZGVyIHRvIGdldCBzdHJvbmdlciB0eXBlLWNoZWNraW5nIG9uIGtleXNcbiAqIGFuZCB2YWx1ZXMuXG4gKi9cbi8vIFRoaXMgdHlwZSBpcyBjb25kaXRpb25hbCBzbyB0aGF0IGlmIHRoZSBwYXJhbWV0ZXIgVCBpcyBub3Qgc3BlY2lmaWVkLCBvclxuLy8gaXMgYGFueWAsIHRoZSB0eXBlIHdpbGwgaW5jbHVkZSBgTWFwPFByb3BlcnR5S2V5LCB1bmtub3duPmAuIFNpbmNlIFQgaXMgbm90XG4vLyBnaXZlbiBpbiB0aGUgdXNlcyBvZiBQcm9wZXJ0eVZhbHVlcyBpbiB0aGlzIGZpbGUsIGFsbCB1c2VzIGhlcmUgZmFsbGJhY2sgdG9cbi8vIG1lYW5pbmcgYE1hcDxQcm9wZXJ0eUtleSwgdW5rbm93bj5gLCBidXQgaWYgYSBkZXZlbG9wZXIgdXNlc1xuLy8gYFByb3BlcnR5VmFsdWVzPHRoaXM+YCAob3IgYW55IG90aGVyIHZhbHVlIGZvciBUKSB0aGV5IHdpbGwgZ2V0IGFcbi8vIHN0cm9uZ2x5LXR5cGVkIE1hcCB0eXBlLlxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbmV4cG9ydCB0eXBlIFByb3BlcnR5VmFsdWVzPFQgPSBhbnk+ID0gVCBleHRlbmRzIG9iamVjdFxuICA/IFByb3BlcnR5VmFsdWVNYXA8VD5cbiAgOiBNYXA8UHJvcGVydHlLZXksIHVua25vd24+O1xuXG4vKipcbiAqIERvIG5vdCB1c2UsIGluc3RlYWQgcHJlZmVyIHtAbGlua2NvZGUgUHJvcGVydHlWYWx1ZXN9LlxuICovXG4vLyBUaGlzIHR5cGUgbXVzdCBiZSBleHBvcnRlZCBzdWNoIHRoYXQgSmF2YVNjcmlwdCBnZW5lcmF0ZWQgYnkgdGhlIEdvb2dsZVxuLy8gQ2xvc3VyZSBDb21waWxlciBjYW4gaW1wb3J0IGEgdHlwZSByZWZlcmVuY2UuXG5leHBvcnQgaW50ZXJmYWNlIFByb3BlcnR5VmFsdWVNYXA8VD4gZXh0ZW5kcyBNYXA8UHJvcGVydHlLZXksIHVua25vd24+IHtcbiAgZ2V0PEsgZXh0ZW5kcyBrZXlvZiBUPihrOiBLKTogVFtLXSB8IHVuZGVmaW5lZDtcbiAgc2V0PEsgZXh0ZW5kcyBrZXlvZiBUPihrZXk6IEssIHZhbHVlOiBUW0tdKTogdGhpcztcbiAgaGFzPEsgZXh0ZW5kcyBrZXlvZiBUPihrOiBLKTogYm9vbGVhbjtcbiAgZGVsZXRlPEsgZXh0ZW5kcyBrZXlvZiBUPihrOiBLKTogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGNvbnN0IGRlZmF1bHRDb252ZXJ0ZXI6IENvbXBsZXhBdHRyaWJ1dGVDb252ZXJ0ZXIgPSB7XG4gIHRvQXR0cmlidXRlKHZhbHVlOiB1bmtub3duLCB0eXBlPzogdW5rbm93bik6IHVua25vd24ge1xuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgY2FzZSBCb29sZWFuOlxuICAgICAgICB2YWx1ZSA9IHZhbHVlID8gZW1wdHlTdHJpbmdGb3JCb29sZWFuQXR0cmlidXRlIDogbnVsbDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIE9iamVjdDpcbiAgICAgIGNhc2UgQXJyYXk6XG4gICAgICAgIC8vIGlmIHRoZSB2YWx1ZSBpcyBgbnVsbGAgb3IgYHVuZGVmaW5lZGAgcGFzcyB0aGlzIHRocm91Z2hcbiAgICAgICAgLy8gdG8gYWxsb3cgcmVtb3Zpbmcvbm8gY2hhbmdlIGJlaGF2aW9yLlxuICAgICAgICB2YWx1ZSA9IHZhbHVlID09IG51bGwgPyB2YWx1ZSA6IEpTT04uc3RyaW5naWZ5KHZhbHVlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbiAgfSxcblxuICBmcm9tQXR0cmlidXRlKHZhbHVlOiBzdHJpbmcgfCBudWxsLCB0eXBlPzogdW5rbm93bikge1xuICAgIGxldCBmcm9tVmFsdWU6IHVua25vd24gPSB2YWx1ZTtcbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgIGNhc2UgQm9vbGVhbjpcbiAgICAgICAgZnJvbVZhbHVlID0gdmFsdWUgIT09IG51bGw7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBOdW1iZXI6XG4gICAgICAgIGZyb21WYWx1ZSA9IHZhbHVlID09PSBudWxsID8gbnVsbCA6IE51bWJlcih2YWx1ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBPYmplY3Q6XG4gICAgICBjYXNlIEFycmF5OlxuICAgICAgICAvLyBEbyAqbm90KiBnZW5lcmF0ZSBleGNlcHRpb24gd2hlbiBpbnZhbGlkIEpTT04gaXMgc2V0IGFzIGVsZW1lbnRzXG4gICAgICAgIC8vIGRvbid0IG5vcm1hbGx5IGNvbXBsYWluIG9uIGJlaW5nIG1pcy1jb25maWd1cmVkLlxuICAgICAgICAvLyBUT0RPKHNvcnZlbGwpOiBEbyBnZW5lcmF0ZSBleGNlcHRpb24gaW4gKmRldiBtb2RlKi5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBBc3NlcnQgdG8gYWRoZXJlIHRvIEJhemVsJ3MgXCJtdXN0IHR5cGUgYXNzZXJ0IEpTT04gcGFyc2VcIiBydWxlLlxuICAgICAgICAgIGZyb21WYWx1ZSA9IEpTT04ucGFyc2UodmFsdWUhKSBhcyB1bmtub3duO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgZnJvbVZhbHVlID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIGZyb21WYWx1ZTtcbiAgfSxcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgSGFzQ2hhbmdlZCB7XG4gICh2YWx1ZTogdW5rbm93biwgb2xkOiB1bmtub3duKTogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBDaGFuZ2UgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRydWUgaWYgYHZhbHVlYCBpcyBkaWZmZXJlbnQgZnJvbSBgb2xkVmFsdWVgLlxuICogVGhpcyBtZXRob2QgaXMgdXNlZCBhcyB0aGUgZGVmYXVsdCBmb3IgYSBwcm9wZXJ0eSdzIGBoYXNDaGFuZ2VkYCBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IGNvbnN0IG5vdEVxdWFsOiBIYXNDaGFuZ2VkID0gKHZhbHVlOiB1bmtub3duLCBvbGQ6IHVua25vd24pOiBib29sZWFuID0+XG4gICFpcyh2YWx1ZSwgb2xkKTtcblxuY29uc3QgZGVmYXVsdFByb3BlcnR5RGVjbGFyYXRpb246IFByb3BlcnR5RGVjbGFyYXRpb24gPSB7XG4gIGF0dHJpYnV0ZTogdHJ1ZSxcbiAgdHlwZTogU3RyaW5nLFxuICBjb252ZXJ0ZXI6IGRlZmF1bHRDb252ZXJ0ZXIsXG4gIHJlZmxlY3Q6IGZhbHNlLFxuICB1c2VEZWZhdWx0OiBmYWxzZSxcbiAgaGFzQ2hhbmdlZDogbm90RXF1YWwsXG59O1xuXG4vKipcbiAqIEEgc3RyaW5nIHJlcHJlc2VudGluZyBvbmUgb2YgdGhlIHN1cHBvcnRlZCBkZXYgbW9kZSB3YXJuaW5nIGNhdGVnb3JpZXMuXG4gKi9cbmV4cG9ydCB0eXBlIFdhcm5pbmdLaW5kID1cbiAgfCAnY2hhbmdlLWluLXVwZGF0ZSdcbiAgfCAnbWlncmF0aW9uJ1xuICB8ICdhc3luYy1wZXJmb3JtLXVwZGF0ZSc7XG5cbmV4cG9ydCB0eXBlIEluaXRpYWxpemVyID0gKGVsZW1lbnQ6IFJlYWN0aXZlRWxlbWVudCkgPT4gdm9pZDtcblxuLy8gVGVtcG9yYXJ5LCB1bnRpbCBnb29nbGUzIGlzIG9uIFR5cGVTY3JpcHQgNS4yXG5kZWNsYXJlIGdsb2JhbCB7XG4gIGludGVyZmFjZSBTeW1ib2xDb25zdHJ1Y3RvciB7XG4gICAgcmVhZG9ubHkgbWV0YWRhdGE6IHVuaXF1ZSBzeW1ib2w7XG4gIH1cbn1cblxuLy8gRW5zdXJlIG1ldGFkYXRhIGlzIGVuYWJsZWQuIFR5cGVTY3JpcHQgZG9lcyBub3QgcG9seWZpbGxcbi8vIFN5bWJvbC5tZXRhZGF0YSwgc28gd2UgbXVzdCBlbnN1cmUgdGhhdCBpdCBleGlzdHMuXG4oU3ltYm9sIGFzIHttZXRhZGF0YTogc3ltYm9sfSkubWV0YWRhdGEgPz89IFN5bWJvbCgnbWV0YWRhdGEnKTtcblxuZGVjbGFyZSBnbG9iYWwge1xuICAvLyBUaGlzIGlzIHB1YmxpYyBnbG9iYWwgQVBJLCBkbyBub3QgY2hhbmdlIVxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdmFyXG4gIHZhciBsaXRQcm9wZXJ0eU1ldGFkYXRhOiBXZWFrTWFwPFxuICAgIG9iamVjdCxcbiAgICBNYXA8UHJvcGVydHlLZXksIFByb3BlcnR5RGVjbGFyYXRpb24+XG4gID47XG59XG5cbi8vIE1hcCBmcm9tIGEgY2xhc3MncyBtZXRhZGF0YSBvYmplY3QgdG8gcHJvcGVydHkgb3B0aW9uc1xuLy8gTm90ZSB0aGF0IHdlIG11c3QgdXNlIG51bGxpc2gtY29hbGVzY2luZyBhc3NpZ25tZW50IHNvIHRoYXQgd2Ugb25seSB1c2Ugb25lXG4vLyBtYXAgZXZlbiBpZiB3ZSBsb2FkIG11bHRpcGxlIHZlcnNpb24gb2YgdGhpcyBtb2R1bGUuXG5nbG9iYWwubGl0UHJvcGVydHlNZXRhZGF0YSA/Pz0gbmV3IFdlYWtNYXA8XG4gIG9iamVjdCxcbiAgTWFwPFByb3BlcnR5S2V5LCBQcm9wZXJ0eURlY2xhcmF0aW9uPlxuPigpO1xuXG4vKipcbiAqIEJhc2UgZWxlbWVudCBjbGFzcyB3aGljaCBtYW5hZ2VzIGVsZW1lbnQgcHJvcGVydGllcyBhbmQgYXR0cmlidXRlcy4gV2hlblxuICogcHJvcGVydGllcyBjaGFuZ2UsIHRoZSBgdXBkYXRlYCBtZXRob2QgaXMgYXN5bmNocm9ub3VzbHkgY2FsbGVkLiBUaGlzIG1ldGhvZFxuICogc2hvdWxkIGJlIHN1cHBsaWVkIGJ5IHN1YmNsYXNzZXMgdG8gcmVuZGVyIHVwZGF0ZXMgYXMgZGVzaXJlZC5cbiAqIEBub0luaGVyaXREb2NcbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFJlYWN0aXZlRWxlbWVudFxuICAvLyBJbiB0aGUgTm9kZSBidWlsZCwgdGhpcyBgZXh0ZW5kc2AgY2xhdXNlIHdpbGwgYmUgc3Vic3RpdHV0ZWQgd2l0aFxuICAvLyBgKGdsb2JhbFRoaXMuSFRNTEVsZW1lbnQgPz8gSFRNTEVsZW1lbnQpYC5cbiAgLy9cbiAgLy8gVGhpcyB3YXksIHdlIHdpbGwgZmlyc3QgcHJlZmVyIGFueSBnbG9iYWwgYEhUTUxFbGVtZW50YCBwb2x5ZmlsbCB0aGF0IHRoZVxuICAvLyB1c2VyIGhhcyBhc3NpZ25lZCwgYW5kIHRoZW4gZmFsbCBiYWNrIHRvIHRoZSBgSFRNTEVsZW1lbnRgIHNoaW0gd2hpY2ggaGFzXG4gIC8vIGJlZW4gaW1wb3J0ZWQgKHNlZSBub3RlIGF0IHRoZSB0b3Agb2YgdGhpcyBmaWxlIGFib3V0IGhvdyB0aGlzIGltcG9ydCBpc1xuICAvLyBnZW5lcmF0ZWQgYnkgUm9sbHVwKS4gTm90ZSB0aGF0IHRoZSBgSFRNTEVsZW1lbnRgIHZhcmlhYmxlIGhhcyBiZWVuXG4gIC8vIHNoYWRvd2VkIGJ5IHRoaXMgaW1wb3J0LCBzbyBpdCBubyBsb25nZXIgcmVmZXJzIHRvIHRoZSBnbG9iYWwuXG4gIGV4dGVuZHMgSFRNTEVsZW1lbnRcbiAgaW1wbGVtZW50cyBSZWFjdGl2ZUNvbnRyb2xsZXJIb3N0XG57XG4gIC8vIE5vdGU6IHRoZXNlIGFyZSBwYXRjaGVkIGluIG9ubHkgaW4gREVWX01PREUuXG4gIC8qKlxuICAgKiBSZWFkIG9yIHNldCBhbGwgdGhlIGVuYWJsZWQgd2FybmluZyBjYXRlZ29yaWVzIGZvciB0aGlzIGNsYXNzLlxuICAgKlxuICAgKiBUaGlzIHByb3BlcnR5IGlzIG9ubHkgdXNlZCBpbiBkZXZlbG9wbWVudCBidWlsZHMuXG4gICAqXG4gICAqIEBub2NvbGxhcHNlXG4gICAqIEBjYXRlZ29yeSBkZXYtbW9kZVxuICAgKi9cbiAgc3RhdGljIGVuYWJsZWRXYXJuaW5ncz86IFdhcm5pbmdLaW5kW107XG5cbiAgLyoqXG4gICAqIEVuYWJsZSB0aGUgZ2l2ZW4gd2FybmluZyBjYXRlZ29yeSBmb3IgdGhpcyBjbGFzcy5cbiAgICpcbiAgICogVGhpcyBtZXRob2Qgb25seSBleGlzdHMgaW4gZGV2ZWxvcG1lbnQgYnVpbGRzLCBzbyBpdCBzaG91bGQgYmUgYWNjZXNzZWRcbiAgICogd2l0aCBhIGd1YXJkIGxpa2U6XG4gICAqXG4gICAqIGBgYHRzXG4gICAqIC8vIEVuYWJsZSBmb3IgYWxsIFJlYWN0aXZlRWxlbWVudCBzdWJjbGFzc2VzXG4gICAqIFJlYWN0aXZlRWxlbWVudC5lbmFibGVXYXJuaW5nPy4oJ21pZ3JhdGlvbicpO1xuICAgKlxuICAgKiAvLyBFbmFibGUgZm9yIG9ubHkgTXlFbGVtZW50IGFuZCBzdWJjbGFzc2VzXG4gICAqIE15RWxlbWVudC5lbmFibGVXYXJuaW5nPy4oJ21pZ3JhdGlvbicpO1xuICAgKiBgYGBcbiAgICpcbiAgICogQG5vY29sbGFwc2VcbiAgICogQGNhdGVnb3J5IGRldi1tb2RlXG4gICAqL1xuICBzdGF0aWMgZW5hYmxlV2FybmluZz86ICh3YXJuaW5nS2luZDogV2FybmluZ0tpbmQpID0+IHZvaWQ7XG5cbiAgLyoqXG4gICAqIERpc2FibGUgdGhlIGdpdmVuIHdhcm5pbmcgY2F0ZWdvcnkgZm9yIHRoaXMgY2xhc3MuXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIG9ubHkgZXhpc3RzIGluIGRldmVsb3BtZW50IGJ1aWxkcywgc28gaXQgc2hvdWxkIGJlIGFjY2Vzc2VkXG4gICAqIHdpdGggYSBndWFyZCBsaWtlOlxuICAgKlxuICAgKiBgYGB0c1xuICAgKiAvLyBEaXNhYmxlIGZvciBhbGwgUmVhY3RpdmVFbGVtZW50IHN1YmNsYXNzZXNcbiAgICogUmVhY3RpdmVFbGVtZW50LmRpc2FibGVXYXJuaW5nPy4oJ21pZ3JhdGlvbicpO1xuICAgKlxuICAgKiAvLyBEaXNhYmxlIGZvciBvbmx5IE15RWxlbWVudCBhbmQgc3ViY2xhc3Nlc1xuICAgKiBNeUVsZW1lbnQuZGlzYWJsZVdhcm5pbmc/LignbWlncmF0aW9uJyk7XG4gICAqIGBgYFxuICAgKlxuICAgKiBAbm9jb2xsYXBzZVxuICAgKiBAY2F0ZWdvcnkgZGV2LW1vZGVcbiAgICovXG4gIHN0YXRpYyBkaXNhYmxlV2FybmluZz86ICh3YXJuaW5nS2luZDogV2FybmluZ0tpbmQpID0+IHZvaWQ7XG5cbiAgLyoqXG4gICAqIEFkZHMgYW4gaW5pdGlhbGl6ZXIgZnVuY3Rpb24gdG8gdGhlIGNsYXNzIHRoYXQgaXMgY2FsbGVkIGR1cmluZyBpbnN0YW5jZVxuICAgKiBjb25zdHJ1Y3Rpb24uXG4gICAqXG4gICAqIFRoaXMgaXMgdXNlZnVsIGZvciBjb2RlIHRoYXQgcnVucyBhZ2FpbnN0IGEgYFJlYWN0aXZlRWxlbWVudGBcbiAgICogc3ViY2xhc3MsIHN1Y2ggYXMgYSBkZWNvcmF0b3IsIHRoYXQgbmVlZHMgdG8gZG8gd29yayBmb3IgZWFjaFxuICAgKiBpbnN0YW5jZSwgc3VjaCBhcyBzZXR0aW5nIHVwIGEgYFJlYWN0aXZlQ29udHJvbGxlcmAuXG4gICAqXG4gICAqIGBgYHRzXG4gICAqIGNvbnN0IG15RGVjb3JhdG9yID0gKHRhcmdldDogdHlwZW9mIFJlYWN0aXZlRWxlbWVudCwga2V5OiBzdHJpbmcpID0+IHtcbiAgICogICB0YXJnZXQuYWRkSW5pdGlhbGl6ZXIoKGluc3RhbmNlOiBSZWFjdGl2ZUVsZW1lbnQpID0+IHtcbiAgICogICAgIC8vIFRoaXMgaXMgcnVuIGR1cmluZyBjb25zdHJ1Y3Rpb24gb2YgdGhlIGVsZW1lbnRcbiAgICogICAgIG5ldyBNeUNvbnRyb2xsZXIoaW5zdGFuY2UpO1xuICAgKiAgIH0pO1xuICAgKiB9XG4gICAqIGBgYFxuICAgKlxuICAgKiBEZWNvcmF0aW5nIGEgZmllbGQgd2lsbCB0aGVuIGNhdXNlIGVhY2ggaW5zdGFuY2UgdG8gcnVuIGFuIGluaXRpYWxpemVyXG4gICAqIHRoYXQgYWRkcyBhIGNvbnRyb2xsZXI6XG4gICAqXG4gICAqIGBgYHRzXG4gICAqIGNsYXNzIE15RWxlbWVudCBleHRlbmRzIExpdEVsZW1lbnQge1xuICAgKiAgIEBteURlY29yYXRvciBmb287XG4gICAqIH1cbiAgICogYGBgXG4gICAqXG4gICAqIEluaXRpYWxpemVycyBhcmUgc3RvcmVkIHBlci1jb25zdHJ1Y3Rvci4gQWRkaW5nIGFuIGluaXRpYWxpemVyIHRvIGFcbiAgICogc3ViY2xhc3MgZG9lcyBub3QgYWRkIGl0IHRvIGEgc3VwZXJjbGFzcy4gU2luY2UgaW5pdGlhbGl6ZXJzIGFyZSBydW4gaW5cbiAgICogY29uc3RydWN0b3JzLCBpbml0aWFsaXplcnMgd2lsbCBydW4gaW4gb3JkZXIgb2YgdGhlIGNsYXNzIGhpZXJhcmNoeSxcbiAgICogc3RhcnRpbmcgd2l0aCBzdXBlcmNsYXNzZXMgYW5kIHByb2dyZXNzaW5nIHRvIHRoZSBpbnN0YW5jZSdzIGNsYXNzLlxuICAgKlxuICAgKiBAbm9jb2xsYXBzZVxuICAgKi9cbiAgc3RhdGljIGFkZEluaXRpYWxpemVyKGluaXRpYWxpemVyOiBJbml0aWFsaXplcikge1xuICAgIHRoaXMuX19wcmVwYXJlKCk7XG4gICAgKHRoaXMuX2luaXRpYWxpemVycyA/Pz0gW10pLnB1c2goaW5pdGlhbGl6ZXIpO1xuICB9XG5cbiAgc3RhdGljIF9pbml0aWFsaXplcnM/OiBJbml0aWFsaXplcltdO1xuXG4gIC8qXG4gICAqIER1ZSB0byBjbG9zdXJlIGNvbXBpbGVyIEVTNiBjb21waWxhdGlvbiBidWdzLCBAbm9jb2xsYXBzZSBpcyByZXF1aXJlZCBvblxuICAgKiBhbGwgc3RhdGljIG1ldGhvZHMgYW5kIHByb3BlcnRpZXMgd2l0aCBpbml0aWFsaXplcnMuICBSZWZlcmVuY2U6XG4gICAqIC0gaHR0cHM6Ly9naXRodWIuY29tL2dvb2dsZS9jbG9zdXJlLWNvbXBpbGVyL2lzc3Vlcy8xNzc2XG4gICAqL1xuXG4gIC8qKlxuICAgKiBNYXBzIGF0dHJpYnV0ZSBuYW1lcyB0byBwcm9wZXJ0aWVzOyBmb3IgZXhhbXBsZSBgZm9vYmFyYCBhdHRyaWJ1dGUgdG9cbiAgICogYGZvb0JhcmAgcHJvcGVydHkuIENyZWF0ZWQgbGF6aWx5IG9uIHVzZXIgc3ViY2xhc3NlcyB3aGVuIGZpbmFsaXppbmcgdGhlXG4gICAqIGNsYXNzLlxuICAgKiBAbm9jb2xsYXBzZVxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgX19hdHRyaWJ1dGVUb1Byb3BlcnR5TWFwOiBBdHRyaWJ1dGVNYXA7XG5cbiAgLyoqXG4gICAqIE1hcmtzIGNsYXNzIGFzIGhhdmluZyBiZWVuIGZpbmFsaXplZCwgd2hpY2ggaW5jbHVkZXMgY3JlYXRpbmcgcHJvcGVydGllc1xuICAgKiBmcm9tIGBzdGF0aWMgcHJvcGVydGllc2AsIGJ1dCBkb2VzICpub3QqIGluY2x1ZGUgYWxsIHByb3BlcnRpZXMgY3JlYXRlZFxuICAgKiBmcm9tIGRlY29yYXRvcnMuXG4gICAqIEBub2NvbGxhcHNlXG4gICAqL1xuICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsaXplZDogdHJ1ZSB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogTWVtb2l6ZWQgbGlzdCBvZiBhbGwgZWxlbWVudCBwcm9wZXJ0aWVzLCBpbmNsdWRpbmcgYW55IHN1cGVyY2xhc3NcbiAgICogcHJvcGVydGllcy4gQ3JlYXRlZCBsYXppbHkgb24gdXNlciBzdWJjbGFzc2VzIHdoZW4gZmluYWxpemluZyB0aGUgY2xhc3MuXG4gICAqXG4gICAqIEBub2NvbGxhcHNlXG4gICAqIEBjYXRlZ29yeSBwcm9wZXJ0aWVzXG4gICAqL1xuICBzdGF0aWMgZWxlbWVudFByb3BlcnRpZXM6IFByb3BlcnR5RGVjbGFyYXRpb25NYXA7XG5cbiAgLyoqXG4gICAqIFVzZXItc3VwcGxpZWQgb2JqZWN0IHRoYXQgbWFwcyBwcm9wZXJ0eSBuYW1lcyB0byBgUHJvcGVydHlEZWNsYXJhdGlvbmBcbiAgICogb2JqZWN0cyBjb250YWluaW5nIG9wdGlvbnMgZm9yIGNvbmZpZ3VyaW5nIHJlYWN0aXZlIHByb3BlcnRpZXMuIFdoZW5cbiAgICogYSByZWFjdGl2ZSBwcm9wZXJ0eSBpcyBzZXQgdGhlIGVsZW1lbnQgd2lsbCB1cGRhdGUgYW5kIHJlbmRlci5cbiAgICpcbiAgICogQnkgZGVmYXVsdCBwcm9wZXJ0aWVzIGFyZSBwdWJsaWMgZmllbGRzLCBhbmQgYXMgc3VjaCwgdGhleSBzaG91bGQgYmVcbiAgICogY29uc2lkZXJlZCBhcyBwcmltYXJpbHkgc2V0dGFibGUgYnkgZWxlbWVudCB1c2VycywgZWl0aGVyIHZpYSBhdHRyaWJ1dGUgb3JcbiAgICogdGhlIHByb3BlcnR5IGl0c2VsZi5cbiAgICpcbiAgICogR2VuZXJhbGx5LCBwcm9wZXJ0aWVzIHRoYXQgYXJlIGNoYW5nZWQgYnkgdGhlIGVsZW1lbnQgc2hvdWxkIGJlIHByaXZhdGUgb3JcbiAgICogcHJvdGVjdGVkIGZpZWxkcyBhbmQgc2hvdWxkIHVzZSB0aGUgYHN0YXRlOiB0cnVlYCBvcHRpb24uIFByb3BlcnRpZXNcbiAgICogbWFya2VkIGFzIGBzdGF0ZWAgZG8gbm90IHJlZmxlY3QgZnJvbSB0aGUgY29ycmVzcG9uZGluZyBhdHRyaWJ1dGVcbiAgICpcbiAgICogSG93ZXZlciwgc29tZXRpbWVzIGVsZW1lbnQgY29kZSBkb2VzIG5lZWQgdG8gc2V0IGEgcHVibGljIHByb3BlcnR5LiBUaGlzXG4gICAqIHNob3VsZCB0eXBpY2FsbHkgb25seSBiZSBkb25lIGluIHJlc3BvbnNlIHRvIHVzZXIgaW50ZXJhY3Rpb24sIGFuZCBhbiBldmVudFxuICAgKiBzaG91bGQgYmUgZmlyZWQgaW5mb3JtaW5nIHRoZSB1c2VyOyBmb3IgZXhhbXBsZSwgYSBjaGVja2JveCBzZXRzIGl0c1xuICAgKiBgY2hlY2tlZGAgcHJvcGVydHkgd2hlbiBjbGlja2VkIGFuZCBmaXJlcyBhIGBjaGFuZ2VkYCBldmVudC4gTXV0YXRpbmdcbiAgICogcHVibGljIHByb3BlcnRpZXMgc2hvdWxkIHR5cGljYWxseSBub3QgYmUgZG9uZSBmb3Igbm9uLXByaW1pdGl2ZSAob2JqZWN0IG9yXG4gICAqIGFycmF5KSBwcm9wZXJ0aWVzLiBJbiBvdGhlciBjYXNlcyB3aGVuIGFuIGVsZW1lbnQgbmVlZHMgdG8gbWFuYWdlIHN0YXRlLCBhXG4gICAqIHByaXZhdGUgcHJvcGVydHkgc2V0IHdpdGggdGhlIGBzdGF0ZTogdHJ1ZWAgb3B0aW9uIHNob3VsZCBiZSB1c2VkLiBXaGVuXG4gICAqIG5lZWRlZCwgc3RhdGUgcHJvcGVydGllcyBjYW4gYmUgaW5pdGlhbGl6ZWQgdmlhIHB1YmxpYyBwcm9wZXJ0aWVzIHRvXG4gICAqIGZhY2lsaXRhdGUgY29tcGxleCBpbnRlcmFjdGlvbnMuXG4gICAqIEBub2NvbGxhcHNlXG4gICAqIEBjYXRlZ29yeSBwcm9wZXJ0aWVzXG4gICAqL1xuICBzdGF0aWMgcHJvcGVydGllczogUHJvcGVydHlEZWNsYXJhdGlvbnM7XG5cbiAgLyoqXG4gICAqIE1lbW9pemVkIGxpc3Qgb2YgYWxsIGVsZW1lbnQgc3R5bGVzLlxuICAgKiBDcmVhdGVkIGxhemlseSBvbiB1c2VyIHN1YmNsYXNzZXMgd2hlbiBmaW5hbGl6aW5nIHRoZSBjbGFzcy5cbiAgICogQG5vY29sbGFwc2VcbiAgICogQGNhdGVnb3J5IHN0eWxlc1xuICAgKi9cbiAgc3RhdGljIGVsZW1lbnRTdHlsZXM6IEFycmF5PENTU1Jlc3VsdE9yTmF0aXZlPiA9IFtdO1xuXG4gIC8qKlxuICAgKiBBcnJheSBvZiBzdHlsZXMgdG8gYXBwbHkgdG8gdGhlIGVsZW1lbnQuIFRoZSBzdHlsZXMgc2hvdWxkIGJlIGRlZmluZWRcbiAgICogdXNpbmcgdGhlIHtAbGlua2NvZGUgY3NzfSB0YWcgZnVuY3Rpb24sIHZpYSBjb25zdHJ1Y3RpYmxlIHN0eWxlc2hlZXRzLCBvclxuICAgKiBpbXBvcnRlZCBmcm9tIG5hdGl2ZSBDU1MgbW9kdWxlIHNjcmlwdHMuXG4gICAqXG4gICAqIE5vdGUgb24gQ29udGVudCBTZWN1cml0eSBQb2xpY3k6XG4gICAqXG4gICAqIEVsZW1lbnQgc3R5bGVzIGFyZSBpbXBsZW1lbnRlZCB3aXRoIGA8c3R5bGU+YCB0YWdzIHdoZW4gdGhlIGJyb3dzZXIgZG9lc24ndFxuICAgKiBzdXBwb3J0IGFkb3B0ZWQgU3R5bGVTaGVldHMuIFRvIHVzZSBzdWNoIGA8c3R5bGU+YCB0YWdzIHdpdGggdGhlIHN0eWxlLXNyY1xuICAgKiBDU1AgZGlyZWN0aXZlLCB0aGUgc3R5bGUtc3JjIHZhbHVlIG11c3QgZWl0aGVyIGluY2x1ZGUgJ3Vuc2FmZS1pbmxpbmUnIG9yXG4gICAqIGBub25jZS08YmFzZTY0LXZhbHVlPmAgd2l0aCBgPGJhc2U2NC12YWx1ZT5gIHJlcGxhY2VkIGJlIGEgc2VydmVyLWdlbmVyYXRlZFxuICAgKiBub25jZS5cbiAgICpcbiAgICogVG8gcHJvdmlkZSBhIG5vbmNlIHRvIHVzZSBvbiBnZW5lcmF0ZWQgYDxzdHlsZT5gIGVsZW1lbnRzLCBzZXRcbiAgICogYHdpbmRvdy5saXROb25jZWAgdG8gYSBzZXJ2ZXItZ2VuZXJhdGVkIG5vbmNlIGluIHlvdXIgcGFnZSdzIEhUTUwsIGJlZm9yZVxuICAgKiBsb2FkaW5nIGFwcGxpY2F0aW9uIGNvZGU6XG4gICAqXG4gICAqIGBgYGh0bWxcbiAgICogPHNjcmlwdD5cbiAgICogICAvLyBHZW5lcmF0ZWQgYW5kIHVuaXF1ZSBwZXIgcmVxdWVzdDpcbiAgICogICB3aW5kb3cubGl0Tm9uY2UgPSAnYTFiMmMzZDQnO1xuICAgKiA8L3NjcmlwdD5cbiAgICogYGBgXG4gICAqIEBub2NvbGxhcHNlXG4gICAqIEBjYXRlZ29yeSBzdHlsZXNcbiAgICovXG4gIHN0YXRpYyBzdHlsZXM/OiBDU1NSZXN1bHRHcm91cDtcblxuICAvKipcbiAgICogUmV0dXJucyBhIGxpc3Qgb2YgYXR0cmlidXRlcyBjb3JyZXNwb25kaW5nIHRvIHRoZSByZWdpc3RlcmVkIHByb3BlcnRpZXMuXG4gICAqIEBub2NvbGxhcHNlXG4gICAqIEBjYXRlZ29yeSBhdHRyaWJ1dGVzXG4gICAqL1xuICBzdGF0aWMgZ2V0IG9ic2VydmVkQXR0cmlidXRlcygpIHtcbiAgICAvLyBFbnN1cmUgd2UndmUgY3JlYXRlZCBhbGwgcHJvcGVydGllc1xuICAgIHRoaXMuZmluYWxpemUoKTtcbiAgICAvLyB0aGlzLl9fYXR0cmlidXRlVG9Qcm9wZXJ0eU1hcCBpcyBvbmx5IHVuZGVmaW5lZCBhZnRlciBmaW5hbGl6ZSgpIGluXG4gICAgLy8gUmVhY3RpdmVFbGVtZW50IGl0c2VsZi4gUmVhY3RpdmVFbGVtZW50Lm9ic2VydmVkQXR0cmlidXRlcyBpcyBvbmx5XG4gICAgLy8gYWNjZXNzZWQgd2l0aCBSZWFjdGl2ZUVsZW1lbnQgYXMgdGhlIHJlY2VpdmVyIHdoZW4gYSBzdWJjbGFzcyBvciBtaXhpblxuICAgIC8vIGNhbGxzIHN1cGVyLm9ic2VydmVkQXR0cmlidXRlc1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLl9fYXR0cmlidXRlVG9Qcm9wZXJ0eU1hcCAmJiBbLi4udGhpcy5fX2F0dHJpYnV0ZVRvUHJvcGVydHlNYXAua2V5cygpXVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIF9faW5zdGFuY2VQcm9wZXJ0aWVzPzogUHJvcGVydHlWYWx1ZXMgPSB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBwcm9wZXJ0eSBhY2Nlc3NvciBvbiB0aGUgZWxlbWVudCBwcm90b3R5cGUgaWYgb25lIGRvZXMgbm90IGV4aXN0XG4gICAqIGFuZCBzdG9yZXMgYSB7QGxpbmtjb2RlIFByb3BlcnR5RGVjbGFyYXRpb259IGZvciB0aGUgcHJvcGVydHkgd2l0aCB0aGVcbiAgICogZ2l2ZW4gb3B0aW9ucy4gVGhlIHByb3BlcnR5IHNldHRlciBjYWxscyB0aGUgcHJvcGVydHkncyBgaGFzQ2hhbmdlZGBcbiAgICogcHJvcGVydHkgb3B0aW9uIG9yIHVzZXMgYSBzdHJpY3QgaWRlbnRpdHkgY2hlY2sgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgb3Igbm90XG4gICAqIHRvIHJlcXVlc3QgYW4gdXBkYXRlLlxuICAgKlxuICAgKiBUaGlzIG1ldGhvZCBtYXkgYmUgb3ZlcnJpZGRlbiB0byBjdXN0b21pemUgcHJvcGVydGllczsgaG93ZXZlcixcbiAgICogd2hlbiBkb2luZyBzbywgaXQncyBpbXBvcnRhbnQgdG8gY2FsbCBgc3VwZXIuY3JlYXRlUHJvcGVydHlgIHRvIGVuc3VyZVxuICAgKiB0aGUgcHJvcGVydHkgaXMgc2V0dXAgY29ycmVjdGx5LiBUaGlzIG1ldGhvZCBjYWxsc1xuICAgKiBgZ2V0UHJvcGVydHlEZXNjcmlwdG9yYCBpbnRlcm5hbGx5IHRvIGdldCBhIGRlc2NyaXB0b3IgdG8gaW5zdGFsbC5cbiAgICogVG8gY3VzdG9taXplIHdoYXQgcHJvcGVydGllcyBkbyB3aGVuIHRoZXkgYXJlIGdldCBvciBzZXQsIG92ZXJyaWRlXG4gICAqIGBnZXRQcm9wZXJ0eURlc2NyaXB0b3JgLiBUbyBjdXN0b21pemUgdGhlIG9wdGlvbnMgZm9yIGEgcHJvcGVydHksXG4gICAqIGltcGxlbWVudCBgY3JlYXRlUHJvcGVydHlgIGxpa2UgdGhpczpcbiAgICpcbiAgICogYGBgdHNcbiAgICogc3RhdGljIGNyZWF0ZVByb3BlcnR5KG5hbWUsIG9wdGlvbnMpIHtcbiAgICogICBvcHRpb25zID0gT2JqZWN0LmFzc2lnbihvcHRpb25zLCB7bXlPcHRpb246IHRydWV9KTtcbiAgICogICBzdXBlci5jcmVhdGVQcm9wZXJ0eShuYW1lLCBvcHRpb25zKTtcbiAgICogfVxuICAgKiBgYGBcbiAgICpcbiAgICogQG5vY29sbGFwc2VcbiAgICogQGNhdGVnb3J5IHByb3BlcnRpZXNcbiAgICovXG4gIHN0YXRpYyBjcmVhdGVQcm9wZXJ0eShcbiAgICBuYW1lOiBQcm9wZXJ0eUtleSxcbiAgICBvcHRpb25zOiBQcm9wZXJ0eURlY2xhcmF0aW9uID0gZGVmYXVsdFByb3BlcnR5RGVjbGFyYXRpb25cbiAgKSB7XG4gICAgLy8gSWYgdGhpcyBpcyBhIHN0YXRlIHByb3BlcnR5LCBmb3JjZSB0aGUgYXR0cmlidXRlIHRvIGZhbHNlLlxuICAgIGlmIChvcHRpb25zLnN0YXRlKSB7XG4gICAgICAob3B0aW9ucyBhcyBNdXRhYmxlPFByb3BlcnR5RGVjbGFyYXRpb24sICdhdHRyaWJ1dGUnPikuYXR0cmlidXRlID0gZmFsc2U7XG4gICAgfVxuICAgIHRoaXMuX19wcmVwYXJlKCk7XG4gICAgLy8gV2hldGhlciB0aGlzIHByb3BlcnR5IGlzIHdyYXBwaW5nIGFjY2Vzc29ycy5cbiAgICAvLyBIZWxwcyBjb250cm9sIHRoZSBpbml0aWFsIHZhbHVlIGNoYW5nZSBhbmQgcmVmbGVjdGlvbiBsb2dpYy5cbiAgICBpZiAodGhpcy5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICAgIG9wdGlvbnMgPSBPYmplY3QuY3JlYXRlKG9wdGlvbnMpO1xuICAgICAgb3B0aW9ucy53cmFwcGVkID0gdHJ1ZTtcbiAgICB9XG4gICAgdGhpcy5lbGVtZW50UHJvcGVydGllcy5zZXQobmFtZSwgb3B0aW9ucyk7XG4gICAgaWYgKCFvcHRpb25zLm5vQWNjZXNzb3IpIHtcbiAgICAgIGNvbnN0IGtleSA9IERFVl9NT0RFXG4gICAgICAgID8gLy8gVXNlIFN5bWJvbC5mb3IgaW4gZGV2IG1vZGUgdG8gbWFrZSBpdCBlYXNpZXIgdG8gbWFpbnRhaW4gc3RhdGVcbiAgICAgICAgICAvLyB3aGVuIGRvaW5nIEhNUi5cbiAgICAgICAgICBTeW1ib2wuZm9yKGAke1N0cmluZyhuYW1lKX0gKEBwcm9wZXJ0eSgpIGNhY2hlKWApXG4gICAgICAgIDogU3ltYm9sKCk7XG4gICAgICBjb25zdCBkZXNjcmlwdG9yID0gdGhpcy5nZXRQcm9wZXJ0eURlc2NyaXB0b3IobmFtZSwga2V5LCBvcHRpb25zKTtcbiAgICAgIGlmIChkZXNjcmlwdG9yICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZGVmaW5lUHJvcGVydHkodGhpcy5wcm90b3R5cGUsIG5hbWUsIGRlc2NyaXB0b3IpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgcHJvcGVydHkgZGVzY3JpcHRvciB0byBiZSBkZWZpbmVkIG9uIHRoZSBnaXZlbiBuYW1lZCBwcm9wZXJ0eS5cbiAgICogSWYgbm8gZGVzY3JpcHRvciBpcyByZXR1cm5lZCwgdGhlIHByb3BlcnR5IHdpbGwgbm90IGJlY29tZSBhbiBhY2Nlc3Nvci5cbiAgICogRm9yIGV4YW1wbGUsXG4gICAqXG4gICAqIGBgYHRzXG4gICAqIGNsYXNzIE15RWxlbWVudCBleHRlbmRzIExpdEVsZW1lbnQge1xuICAgKiAgIHN0YXRpYyBnZXRQcm9wZXJ0eURlc2NyaXB0b3IobmFtZSwga2V5LCBvcHRpb25zKSB7XG4gICAqICAgICBjb25zdCBkZWZhdWx0RGVzY3JpcHRvciA9XG4gICAqICAgICAgICAgc3VwZXIuZ2V0UHJvcGVydHlEZXNjcmlwdG9yKG5hbWUsIGtleSwgb3B0aW9ucyk7XG4gICAqICAgICBjb25zdCBzZXR0ZXIgPSBkZWZhdWx0RGVzY3JpcHRvci5zZXQ7XG4gICAqICAgICByZXR1cm4ge1xuICAgKiAgICAgICBnZXQ6IGRlZmF1bHREZXNjcmlwdG9yLmdldCxcbiAgICogICAgICAgc2V0KHZhbHVlKSB7XG4gICAqICAgICAgICAgc2V0dGVyLmNhbGwodGhpcywgdmFsdWUpO1xuICAgKiAgICAgICAgIC8vIGN1c3RvbSBhY3Rpb24uXG4gICAqICAgICAgIH0sXG4gICAqICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICogICAgICAgZW51bWVyYWJsZTogdHJ1ZVxuICAgKiAgICAgfVxuICAgKiAgIH1cbiAgICogfVxuICAgKiBgYGBcbiAgICpcbiAgICogQG5vY29sbGFwc2VcbiAgICogQGNhdGVnb3J5IHByb3BlcnRpZXNcbiAgICovXG4gIHByb3RlY3RlZCBzdGF0aWMgZ2V0UHJvcGVydHlEZXNjcmlwdG9yKFxuICAgIG5hbWU6IFByb3BlcnR5S2V5LFxuICAgIGtleTogc3RyaW5nIHwgc3ltYm9sLFxuICAgIG9wdGlvbnM6IFByb3BlcnR5RGVjbGFyYXRpb25cbiAgKTogUHJvcGVydHlEZXNjcmlwdG9yIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCB7Z2V0LCBzZXR9ID0gZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRoaXMucHJvdG90eXBlLCBuYW1lKSA/PyB7XG4gICAgICBnZXQodGhpczogUmVhY3RpdmVFbGVtZW50KSB7XG4gICAgICAgIHJldHVybiB0aGlzW2tleSBhcyBrZXlvZiB0eXBlb2YgdGhpc107XG4gICAgICB9LFxuICAgICAgc2V0KHRoaXM6IFJlYWN0aXZlRWxlbWVudCwgdjogdW5rbm93bikge1xuICAgICAgICAodGhpcyBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcgfCBzeW1ib2wsIHVua25vd24+KVtrZXldID0gdjtcbiAgICAgIH0sXG4gICAgfTtcbiAgICBpZiAoREVWX01PREUgJiYgZ2V0ID09IG51bGwpIHtcbiAgICAgIGlmICgndmFsdWUnIGluIChnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGhpcy5wcm90b3R5cGUsIG5hbWUpID8/IHt9KSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYEZpZWxkICR7SlNPTi5zdHJpbmdpZnkoU3RyaW5nKG5hbWUpKX0gb24gYCArXG4gICAgICAgICAgICBgJHt0aGlzLm5hbWV9IHdhcyBkZWNsYXJlZCBhcyBhIHJlYWN0aXZlIHByb3BlcnR5IGAgK1xuICAgICAgICAgICAgYGJ1dCBpdCdzIGFjdHVhbGx5IGRlY2xhcmVkIGFzIGEgdmFsdWUgb24gdGhlIHByb3RvdHlwZS4gYCArXG4gICAgICAgICAgICBgVXN1YWxseSB0aGlzIGlzIGR1ZSB0byB1c2luZyBAcHJvcGVydHkgb3IgQHN0YXRlIG9uIGEgbWV0aG9kLmBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlzc3VlV2FybmluZyhcbiAgICAgICAgJ3JlYWN0aXZlLXByb3BlcnR5LXdpdGhvdXQtZ2V0dGVyJyxcbiAgICAgICAgYEZpZWxkICR7SlNPTi5zdHJpbmdpZnkoU3RyaW5nKG5hbWUpKX0gb24gYCArXG4gICAgICAgICAgYCR7dGhpcy5uYW1lfSB3YXMgZGVjbGFyZWQgYXMgYSByZWFjdGl2ZSBwcm9wZXJ0eSBgICtcbiAgICAgICAgICBgYnV0IGl0IGRvZXMgbm90IGhhdmUgYSBnZXR0ZXIuIFRoaXMgd2lsbCBiZSBhbiBlcnJvciBpbiBhIGAgK1xuICAgICAgICAgIGBmdXR1cmUgdmVyc2lvbiBvZiBMaXQuYFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIGdldCxcbiAgICAgIHNldCh0aGlzOiBSZWFjdGl2ZUVsZW1lbnQsIHZhbHVlOiB1bmtub3duKSB7XG4gICAgICAgIGNvbnN0IG9sZFZhbHVlID0gZ2V0Py5jYWxsKHRoaXMpO1xuICAgICAgICBzZXQ/LmNhbGwodGhpcywgdmFsdWUpO1xuICAgICAgICB0aGlzLnJlcXVlc3RVcGRhdGUobmFtZSwgb2xkVmFsdWUsIG9wdGlvbnMpO1xuICAgICAgfSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBwcm9wZXJ0eSBvcHRpb25zIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gcHJvcGVydHkuXG4gICAqIFRoZXNlIG9wdGlvbnMgYXJlIGRlZmluZWQgd2l0aCBhIGBQcm9wZXJ0eURlY2xhcmF0aW9uYCB2aWEgdGhlIGBwcm9wZXJ0aWVzYFxuICAgKiBvYmplY3Qgb3IgdGhlIGBAcHJvcGVydHlgIGRlY29yYXRvciBhbmQgYXJlIHJlZ2lzdGVyZWQgaW5cbiAgICogYGNyZWF0ZVByb3BlcnR5KC4uLilgLlxuICAgKlxuICAgKiBOb3RlLCB0aGlzIG1ldGhvZCBzaG91bGQgYmUgY29uc2lkZXJlZCBcImZpbmFsXCIgYW5kIG5vdCBvdmVycmlkZGVuLiBUb1xuICAgKiBjdXN0b21pemUgdGhlIG9wdGlvbnMgZm9yIGEgZ2l2ZW4gcHJvcGVydHksIG92ZXJyaWRlXG4gICAqIHtAbGlua2NvZGUgY3JlYXRlUHJvcGVydHl9LlxuICAgKlxuICAgKiBAbm9jb2xsYXBzZVxuICAgKiBAZmluYWxcbiAgICogQGNhdGVnb3J5IHByb3BlcnRpZXNcbiAgICovXG4gIHN0YXRpYyBnZXRQcm9wZXJ0eU9wdGlvbnMobmFtZTogUHJvcGVydHlLZXkpIHtcbiAgICByZXR1cm4gdGhpcy5lbGVtZW50UHJvcGVydGllcy5nZXQobmFtZSkgPz8gZGVmYXVsdFByb3BlcnR5RGVjbGFyYXRpb247XG4gIH1cblxuICAvLyBUZW1wb3JhcnksIHVudGlsIGdvb2dsZTMgaXMgb24gVHlwZVNjcmlwdCA1LjJcbiAgZGVjbGFyZSBzdGF0aWMgW1N5bWJvbC5tZXRhZGF0YV06IG9iamVjdCAmIFJlY29yZDxQcm9wZXJ0eUtleSwgdW5rbm93bj47XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemVzIHN0YXRpYyBvd24gcHJvcGVydGllcyBvZiB0aGUgY2xhc3MgdXNlZCBpbiBib29ra2VlcGluZ1xuICAgKiBmb3IgZWxlbWVudCBwcm9wZXJ0aWVzLCBpbml0aWFsaXplcnMsIGV0Yy5cbiAgICpcbiAgICogQ2FuIGJlIGNhbGxlZCBtdWx0aXBsZSB0aW1lcyBieSBjb2RlIHRoYXQgbmVlZHMgdG8gZW5zdXJlIHRoZXNlXG4gICAqIHByb3BlcnRpZXMgZXhpc3QgYmVmb3JlIHVzaW5nIHRoZW0uXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIGVuc3VyZXMgdGhlIHN1cGVyY2xhc3MgaXMgZmluYWxpemVkIHNvIHRoYXQgaW5oZXJpdGVkXG4gICAqIHByb3BlcnR5IG1ldGFkYXRhIGNhbiBiZSBjb3BpZWQgZG93bi5cbiAgICogQG5vY29sbGFwc2VcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIF9fcHJlcGFyZSgpIHtcbiAgICBpZiAoXG4gICAgICB0aGlzLmhhc093blByb3BlcnR5KEpTQ29tcGlsZXJfcmVuYW1lUHJvcGVydHkoJ2VsZW1lbnRQcm9wZXJ0aWVzJywgdGhpcykpXG4gICAgKSB7XG4gICAgICAvLyBBbHJlYWR5IHByZXBhcmVkXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIEZpbmFsaXplIGFueSBzdXBlcmNsYXNzZXNcbiAgICBjb25zdCBzdXBlckN0b3IgPSBnZXRQcm90b3R5cGVPZih0aGlzKSBhcyB0eXBlb2YgUmVhY3RpdmVFbGVtZW50O1xuICAgIHN1cGVyQ3Rvci5maW5hbGl6ZSgpO1xuXG4gICAgLy8gQ3JlYXRlIG93biBzZXQgb2YgaW5pdGlhbGl6ZXJzIGZvciB0aGlzIGNsYXNzIGlmIGFueSBleGlzdCBvbiB0aGVcbiAgICAvLyBzdXBlcmNsYXNzIGFuZCBjb3B5IHRoZW0gZG93bi4gTm90ZSwgZm9yIGEgc21hbGwgcGVyZiBib29zdCwgYXZvaWRcbiAgICAvLyBjcmVhdGluZyBpbml0aWFsaXplcnMgdW5sZXNzIG5lZWRlZC5cbiAgICBpZiAoc3VwZXJDdG9yLl9pbml0aWFsaXplcnMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5faW5pdGlhbGl6ZXJzID0gWy4uLnN1cGVyQ3Rvci5faW5pdGlhbGl6ZXJzXTtcbiAgICB9XG4gICAgLy8gSW5pdGlhbGl6ZSBlbGVtZW50UHJvcGVydGllcyBmcm9tIHRoZSBzdXBlcmNsYXNzXG4gICAgdGhpcy5lbGVtZW50UHJvcGVydGllcyA9IG5ldyBNYXAoc3VwZXJDdG9yLmVsZW1lbnRQcm9wZXJ0aWVzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5pc2hlcyBzZXR0aW5nIHVwIHRoZSBjbGFzcyBzbyB0aGF0IGl0J3MgcmVhZHkgdG8gYmUgcmVnaXN0ZXJlZFxuICAgKiBhcyBhIGN1c3RvbSBlbGVtZW50IGFuZCBpbnN0YW50aWF0ZWQuXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgUmVhY3RpdmVFbGVtZW50Lm9ic2VydmVkQXR0cmlidXRlcyBnZXR0ZXIuXG4gICAqIElmIHlvdSBvdmVycmlkZSB0aGUgb2JzZXJ2ZWRBdHRyaWJ1dGVzIGdldHRlciwgeW91IG11c3QgZWl0aGVyIGNhbGxcbiAgICogc3VwZXIub2JzZXJ2ZWRBdHRyaWJ1dGVzIHRvIHRyaWdnZXIgZmluYWxpemF0aW9uLCBvciBjYWxsIGZpbmFsaXplKClcbiAgICogeW91cnNlbGYuXG4gICAqXG4gICAqIEBub2NvbGxhcHNlXG4gICAqL1xuICBwcm90ZWN0ZWQgc3RhdGljIGZpbmFsaXplKCkge1xuICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KEpTQ29tcGlsZXJfcmVuYW1lUHJvcGVydHkoJ2ZpbmFsaXplZCcsIHRoaXMpKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmZpbmFsaXplZCA9IHRydWU7XG4gICAgdGhpcy5fX3ByZXBhcmUoKTtcblxuICAgIC8vIENyZWF0ZSBwcm9wZXJ0aWVzIGZyb20gdGhlIHN0YXRpYyBwcm9wZXJ0aWVzIGJsb2NrOlxuICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KEpTQ29tcGlsZXJfcmVuYW1lUHJvcGVydHkoJ3Byb3BlcnRpZXMnLCB0aGlzKSkpIHtcbiAgICAgIGNvbnN0IHByb3BzID0gdGhpcy5wcm9wZXJ0aWVzO1xuICAgICAgY29uc3QgcHJvcEtleXMgPSBbXG4gICAgICAgIC4uLmdldE93blByb3BlcnR5TmFtZXMocHJvcHMpLFxuICAgICAgICAuLi5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocHJvcHMpLFxuICAgICAgXSBhcyBBcnJheTxrZXlvZiB0eXBlb2YgcHJvcHM+O1xuICAgICAgZm9yIChjb25zdCBwIG9mIHByb3BLZXlzKSB7XG4gICAgICAgIHRoaXMuY3JlYXRlUHJvcGVydHkocCwgcHJvcHNbcF0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIENyZWF0ZSBwcm9wZXJ0aWVzIGZyb20gc3RhbmRhcmQgZGVjb3JhdG9yIG1ldGFkYXRhOlxuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpc1tTeW1ib2wubWV0YWRhdGFdO1xuICAgIGlmIChtZXRhZGF0YSAhPT0gbnVsbCkge1xuICAgICAgY29uc3QgcHJvcGVydGllcyA9IGxpdFByb3BlcnR5TWV0YWRhdGEuZ2V0KG1ldGFkYXRhKTtcbiAgICAgIGlmIChwcm9wZXJ0aWVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZm9yIChjb25zdCBbcCwgb3B0aW9uc10gb2YgcHJvcGVydGllcykge1xuICAgICAgICAgIHRoaXMuZWxlbWVudFByb3BlcnRpZXMuc2V0KHAsIG9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ3JlYXRlIHRoZSBhdHRyaWJ1dGUtdG8tcHJvcGVydHkgbWFwXG4gICAgdGhpcy5fX2F0dHJpYnV0ZVRvUHJvcGVydHlNYXAgPSBuZXcgTWFwKCk7XG4gICAgZm9yIChjb25zdCBbcCwgb3B0aW9uc10gb2YgdGhpcy5lbGVtZW50UHJvcGVydGllcykge1xuICAgICAgY29uc3QgYXR0ciA9IHRoaXMuX19hdHRyaWJ1dGVOYW1lRm9yUHJvcGVydHkocCwgb3B0aW9ucyk7XG4gICAgICBpZiAoYXR0ciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMuX19hdHRyaWJ1dGVUb1Byb3BlcnR5TWFwLnNldChhdHRyLCBwKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmVsZW1lbnRTdHlsZXMgPSB0aGlzLmZpbmFsaXplU3R5bGVzKHRoaXMuc3R5bGVzKTtcblxuICAgIGlmIChERVZfTU9ERSkge1xuICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoJ2NyZWF0ZVByb3BlcnR5JykpIHtcbiAgICAgICAgaXNzdWVXYXJuaW5nKFxuICAgICAgICAgICduby1vdmVycmlkZS1jcmVhdGUtcHJvcGVydHknLFxuICAgICAgICAgICdPdmVycmlkaW5nIFJlYWN0aXZlRWxlbWVudC5jcmVhdGVQcm9wZXJ0eSgpIGlzIGRlcHJlY2F0ZWQuICcgK1xuICAgICAgICAgICAgJ1RoZSBvdmVycmlkZSB3aWxsIG5vdCBiZSBjYWxsZWQgd2l0aCBzdGFuZGFyZCBkZWNvcmF0b3JzJ1xuICAgICAgICApO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuaGFzT3duUHJvcGVydHkoJ2dldFByb3BlcnR5RGVzY3JpcHRvcicpKSB7XG4gICAgICAgIGlzc3VlV2FybmluZyhcbiAgICAgICAgICAnbm8tb3ZlcnJpZGUtZ2V0LXByb3BlcnR5LWRlc2NyaXB0b3InLFxuICAgICAgICAgICdPdmVycmlkaW5nIFJlYWN0aXZlRWxlbWVudC5nZXRQcm9wZXJ0eURlc2NyaXB0b3IoKSBpcyBkZXByZWNhdGVkLiAnICtcbiAgICAgICAgICAgICdUaGUgb3ZlcnJpZGUgd2lsbCBub3QgYmUgY2FsbGVkIHdpdGggc3RhbmRhcmQgZGVjb3JhdG9ycydcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogT3B0aW9ucyB1c2VkIHdoZW4gY2FsbGluZyBgYXR0YWNoU2hhZG93YC4gU2V0IHRoaXMgcHJvcGVydHkgdG8gY3VzdG9taXplXG4gICAqIHRoZSBvcHRpb25zIGZvciB0aGUgc2hhZG93Um9vdDsgZm9yIGV4YW1wbGUsIHRvIGNyZWF0ZSBhIGNsb3NlZFxuICAgKiBzaGFkb3dSb290OiBge21vZGU6ICdjbG9zZWQnfWAuXG4gICAqXG4gICAqIE5vdGUsIHRoZXNlIG9wdGlvbnMgYXJlIHVzZWQgaW4gYGNyZWF0ZVJlbmRlclJvb3RgLiBJZiB0aGlzIG1ldGhvZFxuICAgKiBpcyBjdXN0b21pemVkLCBvcHRpb25zIHNob3VsZCBiZSByZXNwZWN0ZWQgaWYgcG9zc2libGUuXG4gICAqIEBub2NvbGxhcHNlXG4gICAqIEBjYXRlZ29yeSByZW5kZXJpbmdcbiAgICovXG4gIHN0YXRpYyBzaGFkb3dSb290T3B0aW9uczogU2hhZG93Um9vdEluaXQgPSB7bW9kZTogJ29wZW4nfTtcblxuICAvKipcbiAgICogVGFrZXMgdGhlIHN0eWxlcyB0aGUgdXNlciBzdXBwbGllZCB2aWEgdGhlIGBzdGF0aWMgc3R5bGVzYCBwcm9wZXJ0eSBhbmRcbiAgICogcmV0dXJucyB0aGUgYXJyYXkgb2Ygc3R5bGVzIHRvIGFwcGx5IHRvIHRoZSBlbGVtZW50LlxuICAgKiBPdmVycmlkZSB0aGlzIG1ldGhvZCB0byBpbnRlZ3JhdGUgaW50byBhIHN0eWxlIG1hbmFnZW1lbnQgc3lzdGVtLlxuICAgKlxuICAgKiBTdHlsZXMgYXJlIGRlZHVwbGljYXRlZCBwcmVzZXJ2aW5nIHRoZSBfbGFzdF8gaW5zdGFuY2UgaW4gdGhlIGxpc3QuIFRoaXNcbiAgICogaXMgYSBwZXJmb3JtYW5jZSBvcHRpbWl6YXRpb24gdG8gYXZvaWQgZHVwbGljYXRlZCBzdHlsZXMgdGhhdCBjYW4gb2NjdXJcbiAgICogZXNwZWNpYWxseSB3aGVuIGNvbXBvc2luZyB2aWEgc3ViY2xhc3NpbmcuIFRoZSBsYXN0IGl0ZW0gaXMga2VwdCB0byB0cnlcbiAgICogdG8gcHJlc2VydmUgdGhlIGNhc2NhZGUgb3JkZXIgd2l0aCB0aGUgYXNzdW1wdGlvbiB0aGF0IGl0J3MgbW9zdCBpbXBvcnRhbnRcbiAgICogdGhhdCBsYXN0IGFkZGVkIHN0eWxlcyBvdmVycmlkZSBwcmV2aW91cyBzdHlsZXMuXG4gICAqXG4gICAqIEBub2NvbGxhcHNlXG4gICAqIEBjYXRlZ29yeSBzdHlsZXNcbiAgICovXG4gIHByb3RlY3RlZCBzdGF0aWMgZmluYWxpemVTdHlsZXMoXG4gICAgc3R5bGVzPzogQ1NTUmVzdWx0R3JvdXBcbiAgKTogQXJyYXk8Q1NTUmVzdWx0T3JOYXRpdmU+IHtcbiAgICBjb25zdCBlbGVtZW50U3R5bGVzID0gW107XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoc3R5bGVzKSkge1xuICAgICAgLy8gRGVkdXBlIHRoZSBmbGF0dGVuZWQgYXJyYXkgaW4gcmV2ZXJzZSBvcmRlciB0byBwcmVzZXJ2ZSB0aGUgbGFzdCBpdGVtcy5cbiAgICAgIC8vIENhc3RpbmcgdG8gQXJyYXk8dW5rbm93bj4gd29ya3MgYXJvdW5kIFRTIGVycm9yIHRoYXRcbiAgICAgIC8vIGFwcGVhcnMgdG8gY29tZSBmcm9tIHRyeWluZyB0byBmbGF0dGVuIGEgdHlwZSBDU1NSZXN1bHRBcnJheS5cbiAgICAgIGNvbnN0IHNldCA9IG5ldyBTZXQoKHN0eWxlcyBhcyBBcnJheTx1bmtub3duPikuZmxhdChJbmZpbml0eSkucmV2ZXJzZSgpKTtcbiAgICAgIC8vIFRoZW4gcHJlc2VydmUgb3JpZ2luYWwgb3JkZXIgYnkgYWRkaW5nIHRoZSBzZXQgaXRlbXMgaW4gcmV2ZXJzZSBvcmRlci5cbiAgICAgIGZvciAoY29uc3QgcyBvZiBzZXQpIHtcbiAgICAgICAgZWxlbWVudFN0eWxlcy51bnNoaWZ0KGdldENvbXBhdGlibGVTdHlsZShzIGFzIENTU1Jlc3VsdE9yTmF0aXZlKSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChzdHlsZXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgZWxlbWVudFN0eWxlcy5wdXNoKGdldENvbXBhdGlibGVTdHlsZShzdHlsZXMpKTtcbiAgICB9XG4gICAgcmV0dXJuIGVsZW1lbnRTdHlsZXM7XG4gIH1cblxuICAvKipcbiAgICogTm9kZSBvciBTaGFkb3dSb290IGludG8gd2hpY2ggZWxlbWVudCBET00gc2hvdWxkIGJlIHJlbmRlcmVkLiBEZWZhdWx0c1xuICAgKiB0byBhbiBvcGVuIHNoYWRvd1Jvb3QuXG4gICAqIEBjYXRlZ29yeSByZW5kZXJpbmdcbiAgICovXG4gIHJlYWRvbmx5IHJlbmRlclJvb3QhOiBIVE1MRWxlbWVudCB8IERvY3VtZW50RnJhZ21lbnQ7XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHByb3BlcnR5IG5hbWUgZm9yIHRoZSBnaXZlbiBhdHRyaWJ1dGUgYG5hbWVgLlxuICAgKiBAbm9jb2xsYXBzZVxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgX19hdHRyaWJ1dGVOYW1lRm9yUHJvcGVydHkoXG4gICAgbmFtZTogUHJvcGVydHlLZXksXG4gICAgb3B0aW9uczogUHJvcGVydHlEZWNsYXJhdGlvblxuICApIHtcbiAgICBjb25zdCBhdHRyaWJ1dGUgPSBvcHRpb25zLmF0dHJpYnV0ZTtcbiAgICByZXR1cm4gYXR0cmlidXRlID09PSBmYWxzZVxuICAgICAgPyB1bmRlZmluZWRcbiAgICAgIDogdHlwZW9mIGF0dHJpYnV0ZSA9PT0gJ3N0cmluZydcbiAgICAgICAgPyBhdHRyaWJ1dGVcbiAgICAgICAgOiB0eXBlb2YgbmFtZSA9PT0gJ3N0cmluZydcbiAgICAgICAgICA/IG5hbWUudG9Mb3dlckNhc2UoKVxuICAgICAgICAgIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgLy8gSW5pdGlhbGl6ZSB0byBhbiB1bnJlc29sdmVkIFByb21pc2Ugc28gd2UgY2FuIG1ha2Ugc3VyZSB0aGUgZWxlbWVudCBoYXNcbiAgLy8gY29ubmVjdGVkIGJlZm9yZSBmaXJzdCB1cGRhdGUuXG4gIHByaXZhdGUgX191cGRhdGVQcm9taXNlITogUHJvbWlzZTxib29sZWFuPjtcblxuICAvKipcbiAgICogVHJ1ZSBpZiB0aGVyZSBpcyBhIHBlbmRpbmcgdXBkYXRlIGFzIGEgcmVzdWx0IG9mIGNhbGxpbmcgYHJlcXVlc3RVcGRhdGUoKWAuXG4gICAqIFNob3VsZCBvbmx5IGJlIHJlYWQuXG4gICAqIEBjYXRlZ29yeSB1cGRhdGVzXG4gICAqL1xuICBpc1VwZGF0ZVBlbmRpbmcgPSBmYWxzZTtcblxuICAvKipcbiAgICogSXMgc2V0IHRvIGB0cnVlYCBhZnRlciB0aGUgZmlyc3QgdXBkYXRlLiBUaGUgZWxlbWVudCBjb2RlIGNhbm5vdCBhc3N1bWVcbiAgICogdGhhdCBgcmVuZGVyUm9vdGAgZXhpc3RzIGJlZm9yZSB0aGUgZWxlbWVudCBgaGFzVXBkYXRlZGAuXG4gICAqIEBjYXRlZ29yeSB1cGRhdGVzXG4gICAqL1xuICBoYXNVcGRhdGVkID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIE1hcCB3aXRoIGtleXMgZm9yIGFueSBwcm9wZXJ0aWVzIHRoYXQgaGF2ZSBjaGFuZ2VkIHNpbmNlIHRoZSBsYXN0XG4gICAqIHVwZGF0ZSBjeWNsZSB3aXRoIHByZXZpb3VzIHZhbHVlcy5cbiAgICpcbiAgICogQGludGVybmFsXG4gICAqL1xuICBfJGNoYW5nZWRQcm9wZXJ0aWVzITogUHJvcGVydHlWYWx1ZXM7XG5cbiAgLyoqXG4gICAqIFJlY29yZHMgcHJvcGVydHkgZGVmYXVsdCB2YWx1ZXMgd2hlbiB0aGVcbiAgICogYHVzZURlZmF1bHRgIG9wdGlvbiBpcyB1c2VkLlxuICAgKi9cbiAgcHJpdmF0ZSBfX2RlZmF1bHRWYWx1ZXM/OiBNYXA8UHJvcGVydHlLZXksIHVua25vd24+O1xuXG4gIC8qKlxuICAgKiBQcm9wZXJ0aWVzIHRoYXQgc2hvdWxkIGJlIHJlZmxlY3RlZCB3aGVuIHVwZGF0ZWQuXG4gICAqL1xuICBwcml2YXRlIF9fcmVmbGVjdGluZ1Byb3BlcnRpZXM/OiBTZXQ8UHJvcGVydHlLZXk+O1xuXG4gIC8qKlxuICAgKiBOYW1lIG9mIGN1cnJlbnRseSByZWZsZWN0aW5nIHByb3BlcnR5XG4gICAqL1xuICBwcml2YXRlIF9fcmVmbGVjdGluZ1Byb3BlcnR5OiBQcm9wZXJ0eUtleSB8IG51bGwgPSBudWxsO1xuXG4gIC8qKlxuICAgKiBTZXQgb2YgY29udHJvbGxlcnMuXG4gICAqL1xuICBwcml2YXRlIF9fY29udHJvbGxlcnM/OiBTZXQ8UmVhY3RpdmVDb250cm9sbGVyPjtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuX19pbml0aWFsaXplKCk7XG4gIH1cblxuICAvKipcbiAgICogSW50ZXJuYWwgb25seSBvdmVycmlkZSBwb2ludCBmb3IgY3VzdG9taXppbmcgd29yayBkb25lIHdoZW4gZWxlbWVudHNcbiAgICogYXJlIGNvbnN0cnVjdGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBfX2luaXRpYWxpemUoKSB7XG4gICAgdGhpcy5fX3VwZGF0ZVByb21pc2UgPSBuZXcgUHJvbWlzZTxib29sZWFuPihcbiAgICAgIChyZXMpID0+ICh0aGlzLmVuYWJsZVVwZGF0aW5nID0gcmVzKVxuICAgICk7XG4gICAgdGhpcy5fJGNoYW5nZWRQcm9wZXJ0aWVzID0gbmV3IE1hcCgpO1xuICAgIC8vIFRoaXMgZW5xdWV1ZXMgYSBtaWNyb3Rhc2sgdGhhdCBtdXN0IHJ1biBiZWZvcmUgdGhlIGZpcnN0IHVwZGF0ZSwgc28gaXRcbiAgICAvLyBtdXN0IGJlIGNhbGxlZCBiZWZvcmUgcmVxdWVzdFVwZGF0ZSgpXG4gICAgdGhpcy5fX3NhdmVJbnN0YW5jZVByb3BlcnRpZXMoKTtcbiAgICAvLyBlbnN1cmVzIGZpcnN0IHVwZGF0ZSB3aWxsIGJlIGNhdWdodCBieSBhbiBlYXJseSBhY2Nlc3Mgb2ZcbiAgICAvLyBgdXBkYXRlQ29tcGxldGVgXG4gICAgdGhpcy5yZXF1ZXN0VXBkYXRlKCk7XG4gICAgKHRoaXMuY29uc3RydWN0b3IgYXMgdHlwZW9mIFJlYWN0aXZlRWxlbWVudCkuX2luaXRpYWxpemVycz8uZm9yRWFjaCgoaSkgPT5cbiAgICAgIGkodGhpcylcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVycyBhIGBSZWFjdGl2ZUNvbnRyb2xsZXJgIHRvIHBhcnRpY2lwYXRlIGluIHRoZSBlbGVtZW50J3MgcmVhY3RpdmVcbiAgICogdXBkYXRlIGN5Y2xlLiBUaGUgZWxlbWVudCBhdXRvbWF0aWNhbGx5IGNhbGxzIGludG8gYW55IHJlZ2lzdGVyZWRcbiAgICogY29udHJvbGxlcnMgZHVyaW5nIGl0cyBsaWZlY3ljbGUgY2FsbGJhY2tzLlxuICAgKlxuICAgKiBJZiB0aGUgZWxlbWVudCBpcyBjb25uZWN0ZWQgd2hlbiBgYWRkQ29udHJvbGxlcigpYCBpcyBjYWxsZWQsIHRoZVxuICAgKiBjb250cm9sbGVyJ3MgYGhvc3RDb25uZWN0ZWQoKWAgY2FsbGJhY2sgd2lsbCBiZSBpbW1lZGlhdGVseSBjYWxsZWQuXG4gICAqIEBjYXRlZ29yeSBjb250cm9sbGVyc1xuICAgKi9cbiAgYWRkQ29udHJvbGxlcihjb250cm9sbGVyOiBSZWFjdGl2ZUNvbnRyb2xsZXIpIHtcbiAgICAodGhpcy5fX2NvbnRyb2xsZXJzID8/PSBuZXcgU2V0KCkpLmFkZChjb250cm9sbGVyKTtcbiAgICAvLyBJZiBhIGNvbnRyb2xsZXIgaXMgYWRkZWQgYWZ0ZXIgdGhlIGVsZW1lbnQgaGFzIGJlZW4gY29ubmVjdGVkLFxuICAgIC8vIGNhbGwgaG9zdENvbm5lY3RlZC4gTm90ZSwgcmUtdXNpbmcgZXhpc3RlbmNlIG9mIGByZW5kZXJSb290YCBoZXJlXG4gICAgLy8gKHdoaWNoIGlzIHNldCBpbiBjb25uZWN0ZWRDYWxsYmFjaykgdG8gYXZvaWQgdGhlIG5lZWQgdG8gdHJhY2sgYVxuICAgIC8vIGZpcnN0IGNvbm5lY3RlZCBzdGF0ZS5cbiAgICBpZiAodGhpcy5yZW5kZXJSb290ICE9PSB1bmRlZmluZWQgJiYgdGhpcy5pc0Nvbm5lY3RlZCkge1xuICAgICAgY29udHJvbGxlci5ob3N0Q29ubmVjdGVkPy4oKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBhIGBSZWFjdGl2ZUNvbnRyb2xsZXJgIGZyb20gdGhlIGVsZW1lbnQuXG4gICAqIEBjYXRlZ29yeSBjb250cm9sbGVyc1xuICAgKi9cbiAgcmVtb3ZlQ29udHJvbGxlcihjb250cm9sbGVyOiBSZWFjdGl2ZUNvbnRyb2xsZXIpIHtcbiAgICB0aGlzLl9fY29udHJvbGxlcnM/LmRlbGV0ZShjb250cm9sbGVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaXhlcyBhbnkgcHJvcGVydGllcyBzZXQgb24gdGhlIGluc3RhbmNlIGJlZm9yZSB1cGdyYWRlIHRpbWUuXG4gICAqIE90aGVyd2lzZSB0aGVzZSB3b3VsZCBzaGFkb3cgdGhlIGFjY2Vzc29yIGFuZCBicmVhayB0aGVzZSBwcm9wZXJ0aWVzLlxuICAgKiBUaGUgcHJvcGVydGllcyBhcmUgc3RvcmVkIGluIGEgTWFwIHdoaWNoIGlzIHBsYXllZCBiYWNrIGFmdGVyIHRoZVxuICAgKiBjb25zdHJ1Y3RvciBydW5zLlxuICAgKi9cbiAgcHJpdmF0ZSBfX3NhdmVJbnN0YW5jZVByb3BlcnRpZXMoKSB7XG4gICAgY29uc3QgaW5zdGFuY2VQcm9wZXJ0aWVzID0gbmV3IE1hcDxQcm9wZXJ0eUtleSwgdW5rbm93bj4oKTtcbiAgICBjb25zdCBlbGVtZW50UHJvcGVydGllcyA9ICh0aGlzLmNvbnN0cnVjdG9yIGFzIHR5cGVvZiBSZWFjdGl2ZUVsZW1lbnQpXG4gICAgICAuZWxlbWVudFByb3BlcnRpZXM7XG4gICAgZm9yIChjb25zdCBwIG9mIGVsZW1lbnRQcm9wZXJ0aWVzLmtleXMoKSBhcyBJdGVyYWJsZUl0ZXJhdG9yPGtleW9mIHRoaXM+KSB7XG4gICAgICBpZiAodGhpcy5oYXNPd25Qcm9wZXJ0eShwKSkge1xuICAgICAgICBpbnN0YW5jZVByb3BlcnRpZXMuc2V0KHAsIHRoaXNbcF0pO1xuICAgICAgICBkZWxldGUgdGhpc1twXTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGluc3RhbmNlUHJvcGVydGllcy5zaXplID4gMCkge1xuICAgICAgdGhpcy5fX2luc3RhbmNlUHJvcGVydGllcyA9IGluc3RhbmNlUHJvcGVydGllcztcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgbm9kZSBpbnRvIHdoaWNoIHRoZSBlbGVtZW50IHNob3VsZCByZW5kZXIgYW5kIGJ5IGRlZmF1bHRcbiAgICogY3JlYXRlcyBhbmQgcmV0dXJucyBhbiBvcGVuIHNoYWRvd1Jvb3QuIEltcGxlbWVudCB0byBjdXN0b21pemUgd2hlcmUgdGhlXG4gICAqIGVsZW1lbnQncyBET00gaXMgcmVuZGVyZWQuIEZvciBleGFtcGxlLCB0byByZW5kZXIgaW50byB0aGUgZWxlbWVudCdzXG4gICAqIGNoaWxkTm9kZXMsIHJldHVybiBgdGhpc2AuXG4gICAqXG4gICAqIEByZXR1cm4gUmV0dXJucyBhIG5vZGUgaW50byB3aGljaCB0byByZW5kZXIuXG4gICAqIEBjYXRlZ29yeSByZW5kZXJpbmdcbiAgICovXG4gIHByb3RlY3RlZCBjcmVhdGVSZW5kZXJSb290KCk6IEhUTUxFbGVtZW50IHwgRG9jdW1lbnRGcmFnbWVudCB7XG4gICAgY29uc3QgcmVuZGVyUm9vdCA9XG4gICAgICB0aGlzLnNoYWRvd1Jvb3QgPz9cbiAgICAgIHRoaXMuYXR0YWNoU2hhZG93KFxuICAgICAgICAodGhpcy5jb25zdHJ1Y3RvciBhcyB0eXBlb2YgUmVhY3RpdmVFbGVtZW50KS5zaGFkb3dSb290T3B0aW9uc1xuICAgICAgKTtcbiAgICBhZG9wdFN0eWxlcyhcbiAgICAgIHJlbmRlclJvb3QsXG4gICAgICAodGhpcy5jb25zdHJ1Y3RvciBhcyB0eXBlb2YgUmVhY3RpdmVFbGVtZW50KS5lbGVtZW50U3R5bGVzXG4gICAgKTtcbiAgICByZXR1cm4gcmVuZGVyUm9vdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBPbiBmaXJzdCBjb25uZWN0aW9uLCBjcmVhdGVzIHRoZSBlbGVtZW50J3MgcmVuZGVyUm9vdCwgc2V0cyB1cFxuICAgKiBlbGVtZW50IHN0eWxpbmcsIGFuZCBlbmFibGVzIHVwZGF0aW5nLlxuICAgKiBAY2F0ZWdvcnkgbGlmZWN5Y2xlXG4gICAqL1xuICBjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICAvLyBDcmVhdGUgcmVuZGVyUm9vdCBiZWZvcmUgY29udHJvbGxlcnMgYGhvc3RDb25uZWN0ZWRgXG4gICAgKHRoaXMgYXMgTXV0YWJsZTx0eXBlb2YgdGhpcywgJ3JlbmRlclJvb3QnPikucmVuZGVyUm9vdCA/Pz1cbiAgICAgIHRoaXMuY3JlYXRlUmVuZGVyUm9vdCgpO1xuICAgIHRoaXMuZW5hYmxlVXBkYXRpbmcodHJ1ZSk7XG4gICAgdGhpcy5fX2NvbnRyb2xsZXJzPy5mb3JFYWNoKChjKSA9PiBjLmhvc3RDb25uZWN0ZWQ/LigpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBOb3RlLCB0aGlzIG1ldGhvZCBzaG91bGQgYmUgY29uc2lkZXJlZCBmaW5hbCBhbmQgbm90IG92ZXJyaWRkZW4uIEl0IGlzXG4gICAqIG92ZXJyaWRkZW4gb24gdGhlIGVsZW1lbnQgaW5zdGFuY2Ugd2l0aCBhIGZ1bmN0aW9uIHRoYXQgdHJpZ2dlcnMgdGhlIGZpcnN0XG4gICAqIHVwZGF0ZS5cbiAgICogQGNhdGVnb3J5IHVwZGF0ZXNcbiAgICovXG4gIHByb3RlY3RlZCBlbmFibGVVcGRhdGluZyhfcmVxdWVzdGVkVXBkYXRlOiBib29sZWFuKSB7fVxuXG4gIC8qKlxuICAgKiBBbGxvd3MgZm9yIGBzdXBlci5kaXNjb25uZWN0ZWRDYWxsYmFjaygpYCBpbiBleHRlbnNpb25zIHdoaWxlXG4gICAqIHJlc2VydmluZyB0aGUgcG9zc2liaWxpdHkgb2YgbWFraW5nIG5vbi1icmVha2luZyBmZWF0dXJlIGFkZGl0aW9uc1xuICAgKiB3aGVuIGRpc2Nvbm5lY3RpbmcgYXQgc29tZSBwb2ludCBpbiB0aGUgZnV0dXJlLlxuICAgKiBAY2F0ZWdvcnkgbGlmZWN5Y2xlXG4gICAqL1xuICBkaXNjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICB0aGlzLl9fY29udHJvbGxlcnM/LmZvckVhY2goKGMpID0+IGMuaG9zdERpc2Nvbm5lY3RlZD8uKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN5bmNocm9uaXplcyBwcm9wZXJ0eSB2YWx1ZXMgd2hlbiBhdHRyaWJ1dGVzIGNoYW5nZS5cbiAgICpcbiAgICogU3BlY2lmaWNhbGx5LCB3aGVuIGFuIGF0dHJpYnV0ZSBpcyBzZXQsIHRoZSBjb3JyZXNwb25kaW5nIHByb3BlcnR5IGlzIHNldC5cbiAgICogWW91IHNob3VsZCByYXJlbHkgbmVlZCB0byBpbXBsZW1lbnQgdGhpcyBjYWxsYmFjay4gSWYgdGhpcyBtZXRob2QgaXNcbiAgICogb3ZlcnJpZGRlbiwgYHN1cGVyLmF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhuYW1lLCBfb2xkLCB2YWx1ZSlgIG11c3QgYmVcbiAgICogY2FsbGVkLlxuICAgKlxuICAgKiBTZWUgW3Jlc3BvbmRpbmcgdG8gYXR0cmlidXRlIGNoYW5nZXNdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9XZWJfY29tcG9uZW50cy9Vc2luZ19jdXN0b21fZWxlbWVudHMjcmVzcG9uZGluZ190b19hdHRyaWJ1dGVfY2hhbmdlcylcbiAgICogb24gTUROIGZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBgYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrYC5cbiAgICogQGNhdGVnb3J5IGF0dHJpYnV0ZXNcbiAgICovXG4gIGF0dHJpYnV0ZUNoYW5nZWRDYWxsYmFjayhcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgX29sZDogc3RyaW5nIHwgbnVsbCxcbiAgICB2YWx1ZTogc3RyaW5nIHwgbnVsbFxuICApIHtcbiAgICB0aGlzLl8kYXR0cmlidXRlVG9Qcm9wZXJ0eShuYW1lLCB2YWx1ZSk7XG4gIH1cblxuICBwcml2YXRlIF9fcHJvcGVydHlUb0F0dHJpYnV0ZShuYW1lOiBQcm9wZXJ0eUtleSwgdmFsdWU6IHVua25vd24pIHtcbiAgICBjb25zdCBlbGVtUHJvcGVydGllczogUHJvcGVydHlEZWNsYXJhdGlvbk1hcCA9IChcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgYXMgdHlwZW9mIFJlYWN0aXZlRWxlbWVudFxuICAgICkuZWxlbWVudFByb3BlcnRpZXM7XG4gICAgY29uc3Qgb3B0aW9ucyA9IGVsZW1Qcm9wZXJ0aWVzLmdldChuYW1lKSE7XG4gICAgY29uc3QgYXR0ciA9IChcbiAgICAgIHRoaXMuY29uc3RydWN0b3IgYXMgdHlwZW9mIFJlYWN0aXZlRWxlbWVudFxuICAgICkuX19hdHRyaWJ1dGVOYW1lRm9yUHJvcGVydHkobmFtZSwgb3B0aW9ucyk7XG4gICAgaWYgKGF0dHIgIT09IHVuZGVmaW5lZCAmJiBvcHRpb25zLnJlZmxlY3QgPT09IHRydWUpIHtcbiAgICAgIGNvbnN0IGNvbnZlcnRlciA9XG4gICAgICAgIChvcHRpb25zLmNvbnZlcnRlciBhcyBDb21wbGV4QXR0cmlidXRlQ29udmVydGVyKT8udG9BdHRyaWJ1dGUgIT09XG4gICAgICAgIHVuZGVmaW5lZFxuICAgICAgICAgID8gKG9wdGlvbnMuY29udmVydGVyIGFzIENvbXBsZXhBdHRyaWJ1dGVDb252ZXJ0ZXIpXG4gICAgICAgICAgOiBkZWZhdWx0Q29udmVydGVyO1xuICAgICAgY29uc3QgYXR0clZhbHVlID0gY29udmVydGVyLnRvQXR0cmlidXRlISh2YWx1ZSwgb3B0aW9ucy50eXBlKTtcbiAgICAgIGlmIChcbiAgICAgICAgREVWX01PREUgJiZcbiAgICAgICAgKHRoaXMuY29uc3RydWN0b3IgYXMgdHlwZW9mIFJlYWN0aXZlRWxlbWVudCkuZW5hYmxlZFdhcm5pbmdzIS5pbmNsdWRlcyhcbiAgICAgICAgICAnbWlncmF0aW9uJ1xuICAgICAgICApICYmXG4gICAgICAgIGF0dHJWYWx1ZSA9PT0gdW5kZWZpbmVkXG4gICAgICApIHtcbiAgICAgICAgaXNzdWVXYXJuaW5nKFxuICAgICAgICAgICd1bmRlZmluZWQtYXR0cmlidXRlLXZhbHVlJyxcbiAgICAgICAgICBgVGhlIGF0dHJpYnV0ZSB2YWx1ZSBmb3IgdGhlICR7bmFtZSBhcyBzdHJpbmd9IHByb3BlcnR5IGlzIGAgK1xuICAgICAgICAgICAgYHVuZGVmaW5lZCBvbiBlbGVtZW50ICR7dGhpcy5sb2NhbE5hbWV9LiBUaGUgYXR0cmlidXRlIHdpbGwgYmUgYCArXG4gICAgICAgICAgICBgcmVtb3ZlZCwgYnV0IGluIHRoZSBwcmV2aW91cyB2ZXJzaW9uIG9mIFxcYFJlYWN0aXZlRWxlbWVudFxcYCwgYCArXG4gICAgICAgICAgICBgdGhlIGF0dHJpYnV0ZSB3b3VsZCBub3QgaGF2ZSBjaGFuZ2VkLmBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIC8vIFRyYWNrIGlmIHRoZSBwcm9wZXJ0eSBpcyBiZWluZyByZWZsZWN0ZWQgdG8gYXZvaWRcbiAgICAgIC8vIHNldHRpbmcgdGhlIHByb3BlcnR5IGFnYWluIHZpYSBgYXR0cmlidXRlQ2hhbmdlZENhbGxiYWNrYC4gTm90ZTpcbiAgICAgIC8vIDEuIHRoaXMgdGFrZXMgYWR2YW50YWdlIG9mIHRoZSBmYWN0IHRoYXQgdGhlIGNhbGxiYWNrIGlzIHN5bmNocm9ub3VzLlxuICAgICAgLy8gMi4gd2lsbCBiZWhhdmUgaW5jb3JyZWN0bHkgaWYgbXVsdGlwbGUgYXR0cmlidXRlcyBhcmUgaW4gdGhlIHJlYWN0aW9uXG4gICAgICAvLyBzdGFjayBhdCB0aW1lIG9mIGNhbGxpbmcuIEhvd2V2ZXIsIHNpbmNlIHdlIHByb2Nlc3MgYXR0cmlidXRlc1xuICAgICAgLy8gaW4gYHVwZGF0ZWAgdGhpcyBzaG91bGQgbm90IGJlIHBvc3NpYmxlIChvciBhbiBleHRyZW1lIGNvcm5lciBjYXNlXG4gICAgICAvLyB0aGF0IHdlJ2QgbGlrZSB0byBkaXNjb3ZlcikuXG4gICAgICAvLyBtYXJrIHN0YXRlIHJlZmxlY3RpbmdcbiAgICAgIHRoaXMuX19yZWZsZWN0aW5nUHJvcGVydHkgPSBuYW1lO1xuICAgICAgaWYgKGF0dHJWYWx1ZSA9PSBudWxsKSB7XG4gICAgICAgIHRoaXMucmVtb3ZlQXR0cmlidXRlKGF0dHIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUoYXR0ciwgYXR0clZhbHVlIGFzIHN0cmluZyk7XG4gICAgICB9XG4gICAgICAvLyBtYXJrIHN0YXRlIG5vdCByZWZsZWN0aW5nXG4gICAgICB0aGlzLl9fcmVmbGVjdGluZ1Byb3BlcnR5ID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICAvKiogQGludGVybmFsICovXG4gIF8kYXR0cmlidXRlVG9Qcm9wZXJ0eShuYW1lOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcgfCBudWxsKSB7XG4gICAgY29uc3QgY3RvciA9IHRoaXMuY29uc3RydWN0b3IgYXMgdHlwZW9mIFJlYWN0aXZlRWxlbWVudDtcbiAgICAvLyBOb3RlLCBoaW50IHRoaXMgYXMgYW4gYEF0dHJpYnV0ZU1hcGAgc28gY2xvc3VyZSBjbGVhcmx5IHVuZGVyc3RhbmRzXG4gICAgLy8gdGhlIHR5cGU7IGl0IGhhcyBpc3N1ZXMgd2l0aCB0cmFja2luZyB0eXBlcyB0aHJvdWdoIHN0YXRpY3NcbiAgICBjb25zdCBwcm9wTmFtZSA9IChjdG9yLl9fYXR0cmlidXRlVG9Qcm9wZXJ0eU1hcCBhcyBBdHRyaWJ1dGVNYXApLmdldChuYW1lKTtcbiAgICAvLyBVc2UgdHJhY2tpbmcgaW5mbyB0byBhdm9pZCByZWZsZWN0aW5nIGEgcHJvcGVydHkgdmFsdWUgdG8gYW4gYXR0cmlidXRlXG4gICAgLy8gaWYgaXQgd2FzIGp1c3Qgc2V0IGJlY2F1c2UgdGhlIGF0dHJpYnV0ZSBjaGFuZ2VkLlxuICAgIGlmIChwcm9wTmFtZSAhPT0gdW5kZWZpbmVkICYmIHRoaXMuX19yZWZsZWN0aW5nUHJvcGVydHkgIT09IHByb3BOYW1lKSB7XG4gICAgICBjb25zdCBvcHRpb25zID0gY3Rvci5nZXRQcm9wZXJ0eU9wdGlvbnMocHJvcE5hbWUpO1xuICAgICAgY29uc3QgY29udmVydGVyID1cbiAgICAgICAgdHlwZW9mIG9wdGlvbnMuY29udmVydGVyID09PSAnZnVuY3Rpb24nXG4gICAgICAgICAgPyB7ZnJvbUF0dHJpYnV0ZTogb3B0aW9ucy5jb252ZXJ0ZXJ9XG4gICAgICAgICAgOiBvcHRpb25zLmNvbnZlcnRlcj8uZnJvbUF0dHJpYnV0ZSAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICA/IG9wdGlvbnMuY29udmVydGVyXG4gICAgICAgICAgICA6IGRlZmF1bHRDb252ZXJ0ZXI7XG4gICAgICAvLyBtYXJrIHN0YXRlIHJlZmxlY3RpbmdcbiAgICAgIHRoaXMuX19yZWZsZWN0aW5nUHJvcGVydHkgPSBwcm9wTmFtZTtcbiAgICAgIHRoaXNbcHJvcE5hbWUgYXMga2V5b2YgdGhpc10gPVxuICAgICAgICBjb252ZXJ0ZXIuZnJvbUF0dHJpYnV0ZSEodmFsdWUsIG9wdGlvbnMudHlwZSkgPz9cbiAgICAgICAgdGhpcy5fX2RlZmF1bHRWYWx1ZXM/LmdldChwcm9wTmFtZSkgPz9cbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgICAgKG51bGwgYXMgYW55KTtcbiAgICAgIC8vIG1hcmsgc3RhdGUgbm90IHJlZmxlY3RpbmdcbiAgICAgIHRoaXMuX19yZWZsZWN0aW5nUHJvcGVydHkgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXF1ZXN0cyBhbiB1cGRhdGUgd2hpY2ggaXMgcHJvY2Vzc2VkIGFzeW5jaHJvbm91c2x5LiBUaGlzIHNob3VsZCBiZSBjYWxsZWRcbiAgICogd2hlbiBhbiBlbGVtZW50IHNob3VsZCB1cGRhdGUgYmFzZWQgb24gc29tZSBzdGF0ZSBub3QgdHJpZ2dlcmVkIGJ5IHNldHRpbmdcbiAgICogYSByZWFjdGl2ZSBwcm9wZXJ0eS4gSW4gdGhpcyBjYXNlLCBwYXNzIG5vIGFyZ3VtZW50cy4gSXQgc2hvdWxkIGFsc28gYmVcbiAgICogY2FsbGVkIHdoZW4gbWFudWFsbHkgaW1wbGVtZW50aW5nIGEgcHJvcGVydHkgc2V0dGVyLiBJbiB0aGlzIGNhc2UsIHBhc3MgdGhlXG4gICAqIHByb3BlcnR5IGBuYW1lYCBhbmQgYG9sZFZhbHVlYCB0byBlbnN1cmUgdGhhdCBhbnkgY29uZmlndXJlZCBwcm9wZXJ0eVxuICAgKiBvcHRpb25zIGFyZSBob25vcmVkLlxuICAgKlxuICAgKiBAcGFyYW0gbmFtZSBuYW1lIG9mIHJlcXVlc3RpbmcgcHJvcGVydHlcbiAgICogQHBhcmFtIG9sZFZhbHVlIG9sZCB2YWx1ZSBvZiByZXF1ZXN0aW5nIHByb3BlcnR5XG4gICAqIEBwYXJhbSBvcHRpb25zIHByb3BlcnR5IG9wdGlvbnMgdG8gdXNlIGluc3RlYWQgb2YgdGhlIHByZXZpb3VzbHlcbiAgICogICAgIGNvbmZpZ3VyZWQgb3B0aW9uc1xuICAgKiBAY2F0ZWdvcnkgdXBkYXRlc1xuICAgKi9cbiAgcmVxdWVzdFVwZGF0ZShcbiAgICBuYW1lPzogUHJvcGVydHlLZXksXG4gICAgb2xkVmFsdWU/OiB1bmtub3duLFxuICAgIG9wdGlvbnM/OiBQcm9wZXJ0eURlY2xhcmF0aW9uXG4gICk6IHZvaWQge1xuICAgIC8vIElmIHdlIGhhdmUgYSBwcm9wZXJ0eSBrZXksIHBlcmZvcm0gcHJvcGVydHkgdXBkYXRlIHN0ZXBzLlxuICAgIGlmIChuYW1lICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChERVZfTU9ERSAmJiAobmFtZSBhcyB1bmtub3duKSBpbnN0YW5jZW9mIEV2ZW50KSB7XG4gICAgICAgIGlzc3VlV2FybmluZyhcbiAgICAgICAgICBgYCxcbiAgICAgICAgICBgVGhlIHJlcXVlc3RVcGRhdGUoKSBtZXRob2Qgd2FzIGNhbGxlZCB3aXRoIGFuIEV2ZW50IGFzIHRoZSBwcm9wZXJ0eSBuYW1lLiBUaGlzIGlzIHByb2JhYmx5IGEgbWlzdGFrZSBjYXVzZWQgYnkgYmluZGluZyB0aGlzLnJlcXVlc3RVcGRhdGUgYXMgYW4gZXZlbnQgbGlzdGVuZXIuIEluc3RlYWQgYmluZCBhIGZ1bmN0aW9uIHRoYXQgd2lsbCBjYWxsIGl0IHdpdGggbm8gYXJndW1lbnRzOiAoKSA9PiB0aGlzLnJlcXVlc3RVcGRhdGUoKWBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGN0b3IgPSB0aGlzLmNvbnN0cnVjdG9yIGFzIHR5cGVvZiBSZWFjdGl2ZUVsZW1lbnQ7XG4gICAgICBjb25zdCBuZXdWYWx1ZSA9IHRoaXNbbmFtZSBhcyBrZXlvZiB0aGlzXTtcbiAgICAgIG9wdGlvbnMgPz89IGN0b3IuZ2V0UHJvcGVydHlPcHRpb25zKG5hbWUpO1xuICAgICAgY29uc3QgY2hhbmdlZCA9XG4gICAgICAgIChvcHRpb25zLmhhc0NoYW5nZWQgPz8gbm90RXF1YWwpKG5ld1ZhbHVlLCBvbGRWYWx1ZSkgfHxcbiAgICAgICAgLy8gV2hlbiB0aGVyZSBpcyBubyBjaGFuZ2UsIGNoZWNrIGEgY29ybmVyIGNhc2UgdGhhdCBjYW4gb2NjdXIgd2hlblxuICAgICAgICAvLyAxLiB0aGVyZSdzIGEgaW5pdGlhbCB2YWx1ZSB3aGljaCB3YXMgbm90IHJlZmxlY3RlZFxuICAgICAgICAvLyAyLiB0aGUgcHJvcGVydHkgaXMgc3Vic2VxdWVudGx5IHNldCB0byB0aGlzIHZhbHVlLlxuICAgICAgICAvLyBGb3IgZXhhbXBsZSwgYHByb3A6IHt1c2VEZWZhdWx0OiB0cnVlLCByZWZsZWN0OiB0cnVlfWBcbiAgICAgICAgLy8gYW5kIGVsLnByb3AgPSAnZm9vJy4gVGhpcyBzaG91bGQgYmUgY29uc2lkZXJlZCBhIGNoYW5nZSBpZiB0aGVcbiAgICAgICAgLy8gYXR0cmlidXRlIGlzIG5vdCBzZXQgYmVjYXVzZSB3ZSB3aWxsIG5vdyByZWZsZWN0IHRoZSBwcm9wZXJ0eSB0byB0aGUgYXR0cmlidXRlLlxuICAgICAgICAob3B0aW9ucy51c2VEZWZhdWx0ICYmXG4gICAgICAgICAgb3B0aW9ucy5yZWZsZWN0ICYmXG4gICAgICAgICAgbmV3VmFsdWUgPT09IHRoaXMuX19kZWZhdWx0VmFsdWVzPy5nZXQobmFtZSkgJiZcbiAgICAgICAgICAhdGhpcy5oYXNBdHRyaWJ1dGUoY3Rvci5fX2F0dHJpYnV0ZU5hbWVGb3JQcm9wZXJ0eShuYW1lLCBvcHRpb25zKSEpKTtcbiAgICAgIGlmIChjaGFuZ2VkKSB7XG4gICAgICAgIHRoaXMuXyRjaGFuZ2VQcm9wZXJ0eShuYW1lLCBvbGRWYWx1ZSwgb3B0aW9ucyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBBYm9ydCB0aGUgcmVxdWVzdCBpZiB0aGUgcHJvcGVydHkgc2hvdWxkIG5vdCBiZSBjb25zaWRlcmVkIGNoYW5nZWQuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHRoaXMuaXNVcGRhdGVQZW5kaW5nID09PSBmYWxzZSkge1xuICAgICAgdGhpcy5fX3VwZGF0ZVByb21pc2UgPSB0aGlzLl9fZW5xdWV1ZVVwZGF0ZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIF8kY2hhbmdlUHJvcGVydHkoXG4gICAgbmFtZTogUHJvcGVydHlLZXksXG4gICAgb2xkVmFsdWU6IHVua25vd24sXG4gICAge3VzZURlZmF1bHQsIHJlZmxlY3QsIHdyYXBwZWR9OiBQcm9wZXJ0eURlY2xhcmF0aW9uLFxuICAgIGluaXRpYWxpemVWYWx1ZT86IHVua25vd25cbiAgKSB7XG4gICAgLy8gUmVjb3JkIGRlZmF1bHQgdmFsdWUgd2hlbiB1c2VEZWZhdWx0IGlzIHVzZWQuIFRoaXMgYWxsb3dzIHVzIHRvXG4gICAgLy8gcmVzdG9yZSB0aGlzIHZhbHVlIHdoZW4gdGhlIGF0dHJpYnV0ZSBpcyByZW1vdmVkLlxuICAgIGlmICh1c2VEZWZhdWx0ICYmICEodGhpcy5fX2RlZmF1bHRWYWx1ZXMgPz89IG5ldyBNYXAoKSkuaGFzKG5hbWUpKSB7XG4gICAgICB0aGlzLl9fZGVmYXVsdFZhbHVlcy5zZXQoXG4gICAgICAgIG5hbWUsXG4gICAgICAgIGluaXRpYWxpemVWYWx1ZSA/PyBvbGRWYWx1ZSA/PyB0aGlzW25hbWUgYXMga2V5b2YgdGhpc11cbiAgICAgICk7XG4gICAgICAvLyBpZiB0aGlzIGlzIG5vdCB3cmFwcGluZyBhbiBhY2Nlc3NvciwgaXQgbXVzdCBiZSBhbiBpbml0aWFsIHNldHRpbmdcbiAgICAgIC8vIGFuZCBpbiB0aGlzIGNhc2Ugd2UgZG8gbm90IHdhbnQgdG8gcmVjb3JkIHRoZSBjaGFuZ2Ugb3IgcmVmbGVjdC5cbiAgICAgIGlmICh3cmFwcGVkICE9PSB0cnVlIHx8IGluaXRpYWxpemVWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gVE9ETyAoanVzdGluZmFnbmFuaSk6IENyZWF0ZSBhIGJlbmNobWFyayBvZiBNYXAuaGFzKCkgKyBNYXAuc2V0KFxuICAgIC8vIHZzIGp1c3QgTWFwLnNldCgpXG4gICAgaWYgKCF0aGlzLl8kY2hhbmdlZFByb3BlcnRpZXMuaGFzKG5hbWUpKSB7XG4gICAgICAvLyBPbiB0aGUgaW5pdGlhbCBjaGFuZ2UsIHRoZSBvbGQgdmFsdWUgc2hvdWxkIGJlIGB1bmRlZmluZWRgLCBleGNlcHRcbiAgICAgIC8vIHdpdGggYHVzZURlZmF1bHRgXG4gICAgICBpZiAoIXRoaXMuaGFzVXBkYXRlZCAmJiAhdXNlRGVmYXVsdCkge1xuICAgICAgICBvbGRWYWx1ZSA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHRoaXMuXyRjaGFuZ2VkUHJvcGVydGllcy5zZXQobmFtZSwgb2xkVmFsdWUpO1xuICAgIH1cbiAgICAvLyBBZGQgdG8gcmVmbGVjdGluZyBwcm9wZXJ0aWVzIHNldC5cbiAgICAvLyBOb3RlLCBpdCdzIGltcG9ydGFudCB0aGF0IGV2ZXJ5IGNoYW5nZSBoYXMgYSBjaGFuY2UgdG8gYWRkIHRoZVxuICAgIC8vIHByb3BlcnR5IHRvIGBfX3JlZmxlY3RpbmdQcm9wZXJ0aWVzYC4gVGhpcyBlbnN1cmVzIHNldHRpbmdcbiAgICAvLyBhdHRyaWJ1dGUgKyBwcm9wZXJ0eSByZWZsZWN0cyBjb3JyZWN0bHkuXG4gICAgaWYgKHJlZmxlY3QgPT09IHRydWUgJiYgdGhpcy5fX3JlZmxlY3RpbmdQcm9wZXJ0eSAhPT0gbmFtZSkge1xuICAgICAgKHRoaXMuX19yZWZsZWN0aW5nUHJvcGVydGllcyA/Pz0gbmV3IFNldDxQcm9wZXJ0eUtleT4oKSkuYWRkKG5hbWUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHVwIHRoZSBlbGVtZW50IHRvIGFzeW5jaHJvbm91c2x5IHVwZGF0ZS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgX19lbnF1ZXVlVXBkYXRlKCkge1xuICAgIHRoaXMuaXNVcGRhdGVQZW5kaW5nID0gdHJ1ZTtcbiAgICB0cnkge1xuICAgICAgLy8gRW5zdXJlIGFueSBwcmV2aW91cyB1cGRhdGUgaGFzIHJlc29sdmVkIGJlZm9yZSB1cGRhdGluZy5cbiAgICAgIC8vIFRoaXMgYGF3YWl0YCBhbHNvIGVuc3VyZXMgdGhhdCBwcm9wZXJ0eSBjaGFuZ2VzIGFyZSBiYXRjaGVkLlxuICAgICAgYXdhaXQgdGhpcy5fX3VwZGF0ZVByb21pc2U7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy8gUmVmaXJlIGFueSBwcmV2aW91cyBlcnJvcnMgYXN5bmMgc28gdGhleSBkbyBub3QgZGlzcnVwdCB0aGUgdXBkYXRlXG4gICAgICAvLyBjeWNsZS4gRXJyb3JzIGFyZSByZWZpcmVkIHNvIGRldmVsb3BlcnMgaGF2ZSBhIGNoYW5jZSB0byBvYnNlcnZlXG4gICAgICAvLyB0aGVtLCBhbmQgdGhpcyBjYW4gYmUgZG9uZSBieSBpbXBsZW1lbnRpbmdcbiAgICAgIC8vIGB3aW5kb3cub251bmhhbmRsZWRyZWplY3Rpb25gLlxuICAgICAgUHJvbWlzZS5yZWplY3QoZSk7XG4gICAgfVxuICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuc2NoZWR1bGVVcGRhdGUoKTtcbiAgICAvLyBJZiBgc2NoZWR1bGVVcGRhdGVgIHJldHVybnMgYSBQcm9taXNlLCB3ZSBhd2FpdCBpdC4gVGhpcyBpcyBkb25lIHRvXG4gICAgLy8gZW5hYmxlIGNvb3JkaW5hdGluZyB1cGRhdGVzIHdpdGggYSBzY2hlZHVsZXIuIE5vdGUsIHRoZSByZXN1bHQgaXNcbiAgICAvLyBjaGVja2VkIHRvIGF2b2lkIGRlbGF5aW5nIGFuIGFkZGl0aW9uYWwgbWljcm90YXNrIHVubGVzcyB3ZSBuZWVkIHRvLlxuICAgIGlmIChyZXN1bHQgIT0gbnVsbCkge1xuICAgICAgYXdhaXQgcmVzdWx0O1xuICAgIH1cbiAgICByZXR1cm4gIXRoaXMuaXNVcGRhdGVQZW5kaW5nO1xuICB9XG5cbiAgLyoqXG4gICAqIFNjaGVkdWxlcyBhbiBlbGVtZW50IHVwZGF0ZS4gWW91IGNhbiBvdmVycmlkZSB0aGlzIG1ldGhvZCB0byBjaGFuZ2UgdGhlXG4gICAqIHRpbWluZyBvZiB1cGRhdGVzIGJ5IHJldHVybmluZyBhIFByb21pc2UuIFRoZSB1cGRhdGUgd2lsbCBhd2FpdCB0aGVcbiAgICogcmV0dXJuZWQgUHJvbWlzZSwgYW5kIHlvdSBzaG91bGQgcmVzb2x2ZSB0aGUgUHJvbWlzZSB0byBhbGxvdyB0aGUgdXBkYXRlXG4gICAqIHRvIHByb2NlZWQuIElmIHRoaXMgbWV0aG9kIGlzIG92ZXJyaWRkZW4sIGBzdXBlci5zY2hlZHVsZVVwZGF0ZSgpYFxuICAgKiBtdXN0IGJlIGNhbGxlZC5cbiAgICpcbiAgICogRm9yIGluc3RhbmNlLCB0byBzY2hlZHVsZSB1cGRhdGVzIHRvIG9jY3VyIGp1c3QgYmVmb3JlIHRoZSBuZXh0IGZyYW1lOlxuICAgKlxuICAgKiBgYGB0c1xuICAgKiBvdmVycmlkZSBwcm90ZWN0ZWQgYXN5bmMgc2NoZWR1bGVVcGRhdGUoKTogUHJvbWlzZTx1bmtub3duPiB7XG4gICAqICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiByZXNvbHZlKCkpKTtcbiAgICogICBzdXBlci5zY2hlZHVsZVVwZGF0ZSgpO1xuICAgKiB9XG4gICAqIGBgYFxuICAgKiBAY2F0ZWdvcnkgdXBkYXRlc1xuICAgKi9cbiAgcHJvdGVjdGVkIHNjaGVkdWxlVXBkYXRlKCk6IHZvaWQgfCBQcm9taXNlPHVua25vd24+IHtcbiAgICBjb25zdCByZXN1bHQgPSB0aGlzLnBlcmZvcm1VcGRhdGUoKTtcbiAgICBpZiAoXG4gICAgICBERVZfTU9ERSAmJlxuICAgICAgKHRoaXMuY29uc3RydWN0b3IgYXMgdHlwZW9mIFJlYWN0aXZlRWxlbWVudCkuZW5hYmxlZFdhcm5pbmdzIS5pbmNsdWRlcyhcbiAgICAgICAgJ2FzeW5jLXBlcmZvcm0tdXBkYXRlJ1xuICAgICAgKSAmJlxuICAgICAgdHlwZW9mIChyZXN1bHQgYXMgdW5rbm93biBhcyBQcm9taXNlPHVua25vd24+IHwgdW5kZWZpbmVkKT8udGhlbiA9PT1cbiAgICAgICAgJ2Z1bmN0aW9uJ1xuICAgICkge1xuICAgICAgaXNzdWVXYXJuaW5nKFxuICAgICAgICAnYXN5bmMtcGVyZm9ybS11cGRhdGUnLFxuICAgICAgICBgRWxlbWVudCAke3RoaXMubG9jYWxOYW1lfSByZXR1cm5lZCBhIFByb21pc2UgZnJvbSBwZXJmb3JtVXBkYXRlKCkuIGAgK1xuICAgICAgICAgIGBUaGlzIGJlaGF2aW9yIGlzIGRlcHJlY2F0ZWQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiBhIGZ1dHVyZSBgICtcbiAgICAgICAgICBgdmVyc2lvbiBvZiBSZWFjdGl2ZUVsZW1lbnQuYFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBQZXJmb3JtcyBhbiBlbGVtZW50IHVwZGF0ZS4gTm90ZSwgaWYgYW4gZXhjZXB0aW9uIGlzIHRocm93biBkdXJpbmcgdGhlXG4gICAqIHVwZGF0ZSwgYGZpcnN0VXBkYXRlZGAgYW5kIGB1cGRhdGVkYCB3aWxsIG5vdCBiZSBjYWxsZWQuXG4gICAqXG4gICAqIENhbGwgYHBlcmZvcm1VcGRhdGUoKWAgdG8gaW1tZWRpYXRlbHkgcHJvY2VzcyBhIHBlbmRpbmcgdXBkYXRlLiBUaGlzIHNob3VsZFxuICAgKiBnZW5lcmFsbHkgbm90IGJlIG5lZWRlZCwgYnV0IGl0IGNhbiBiZSBkb25lIGluIHJhcmUgY2FzZXMgd2hlbiB5b3UgbmVlZCB0b1xuICAgKiB1cGRhdGUgc3luY2hyb25vdXNseS5cbiAgICpcbiAgICogQGNhdGVnb3J5IHVwZGF0ZXNcbiAgICovXG4gIHByb3RlY3RlZCBwZXJmb3JtVXBkYXRlKCk6IHZvaWQge1xuICAgIC8vIEFib3J0IGFueSB1cGRhdGUgaWYgb25lIGlzIG5vdCBwZW5kaW5nIHdoZW4gdGhpcyBpcyBjYWxsZWQuXG4gICAgLy8gVGhpcyBjYW4gaGFwcGVuIGlmIGBwZXJmb3JtVXBkYXRlYCBpcyBjYWxsZWQgZWFybHkgdG8gXCJmbHVzaFwiXG4gICAgLy8gdGhlIHVwZGF0ZS5cbiAgICBpZiAoIXRoaXMuaXNVcGRhdGVQZW5kaW5nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGRlYnVnTG9nRXZlbnQ/Lih7a2luZDogJ3VwZGF0ZSd9KTtcbiAgICBpZiAoIXRoaXMuaGFzVXBkYXRlZCkge1xuICAgICAgLy8gQ3JlYXRlIHJlbmRlclJvb3QgYmVmb3JlIGZpcnN0IHVwZGF0ZS4gVGhpcyBvY2N1cnMgaW4gYGNvbm5lY3RlZENhbGxiYWNrYFxuICAgICAgLy8gYnV0IGlzIGRvbmUgaGVyZSB0byBzdXBwb3J0IG91dCBvZiB0cmVlIGNhbGxzIHRvIGBlbmFibGVVcGRhdGluZ2AvYHBlcmZvcm1VcGRhdGVgLlxuICAgICAgKHRoaXMgYXMgTXV0YWJsZTx0eXBlb2YgdGhpcywgJ3JlbmRlclJvb3QnPikucmVuZGVyUm9vdCA/Pz1cbiAgICAgICAgdGhpcy5jcmVhdGVSZW5kZXJSb290KCk7XG4gICAgICBpZiAoREVWX01PREUpIHtcbiAgICAgICAgLy8gUHJvZHVjZSB3YXJuaW5nIGlmIGFueSByZWFjdGl2ZSBwcm9wZXJ0aWVzIG9uIHRoZSBwcm90b3R5cGUgYXJlXG4gICAgICAgIC8vIHNoYWRvd2VkIGJ5IGNsYXNzIGZpZWxkcy4gSW5zdGFuY2UgZmllbGRzIHNldCBiZWZvcmUgdXBncmFkZSBhcmVcbiAgICAgICAgLy8gZGVsZXRlZCBieSB0aGlzIHBvaW50LCBzbyBhbnkgb3duIHByb3BlcnR5IGlzIGNhdXNlZCBieSBjbGFzcyBmaWVsZFxuICAgICAgICAvLyBpbml0aWFsaXphdGlvbiBpbiB0aGUgY29uc3RydWN0b3IuXG4gICAgICAgIGNvbnN0IGN0b3IgPSB0aGlzLmNvbnN0cnVjdG9yIGFzIHR5cGVvZiBSZWFjdGl2ZUVsZW1lbnQ7XG4gICAgICAgIGNvbnN0IHNoYWRvd2VkUHJvcGVydGllcyA9IFsuLi5jdG9yLmVsZW1lbnRQcm9wZXJ0aWVzLmtleXMoKV0uZmlsdGVyKFxuICAgICAgICAgIChwKSA9PiB0aGlzLmhhc093blByb3BlcnR5KHApICYmIHAgaW4gZ2V0UHJvdG90eXBlT2YodGhpcylcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKHNoYWRvd2VkUHJvcGVydGllcy5sZW5ndGgpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICBgVGhlIGZvbGxvd2luZyBwcm9wZXJ0aWVzIG9uIGVsZW1lbnQgJHt0aGlzLmxvY2FsTmFtZX0gd2lsbCBub3QgYCArXG4gICAgICAgICAgICAgIGB0cmlnZ2VyIHVwZGF0ZXMgYXMgZXhwZWN0ZWQgYmVjYXVzZSB0aGV5IGFyZSBzZXQgdXNpbmcgY2xhc3MgYCArXG4gICAgICAgICAgICAgIGBmaWVsZHM6ICR7c2hhZG93ZWRQcm9wZXJ0aWVzLmpvaW4oJywgJyl9LiBgICtcbiAgICAgICAgICAgICAgYE5hdGl2ZSBjbGFzcyBmaWVsZHMgYW5kIHNvbWUgY29tcGlsZWQgb3V0cHV0IHdpbGwgb3ZlcndyaXRlIGAgK1xuICAgICAgICAgICAgICBgYWNjZXNzb3JzIHVzZWQgZm9yIGRldGVjdGluZyBjaGFuZ2VzLiBTZWUgYCArXG4gICAgICAgICAgICAgIGBodHRwczovL2xpdC5kZXYvbXNnL2NsYXNzLWZpZWxkLXNoYWRvd2luZyBgICtcbiAgICAgICAgICAgICAgYGZvciBtb3JlIGluZm9ybWF0aW9uLmBcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBNaXhpbiBpbnN0YW5jZSBwcm9wZXJ0aWVzIG9uY2UsIGlmIHRoZXkgZXhpc3QuXG4gICAgICBpZiAodGhpcy5fX2luc3RhbmNlUHJvcGVydGllcykge1xuICAgICAgICAvLyBUT0RPIChqdXN0aW5mYWduYW5pKTogc2hvdWxkIHdlIHVzZSB0aGUgc3RvcmVkIHZhbHVlPyBDb3VsZCBhIG5ldyB2YWx1ZVxuICAgICAgICAvLyBoYXZlIGJlZW4gc2V0IHNpbmNlIHdlIHN0b3JlZCB0aGUgb3duIHByb3BlcnR5IHZhbHVlP1xuICAgICAgICBmb3IgKGNvbnN0IFtwLCB2YWx1ZV0gb2YgdGhpcy5fX2luc3RhbmNlUHJvcGVydGllcykge1xuICAgICAgICAgIHRoaXNbcCBhcyBrZXlvZiB0aGlzXSA9IHZhbHVlIGFzIHRoaXNba2V5b2YgdGhpc107XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fX2luc3RhbmNlUHJvcGVydGllcyA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIC8vIFRyaWdnZXIgaW5pdGlhbCB2YWx1ZSByZWZsZWN0aW9uIGFuZCBwb3B1bGF0ZSB0aGUgaW5pdGlhbFxuICAgICAgLy8gYGNoYW5nZWRQcm9wZXJ0aWVzYCBtYXAsIGJ1dCBvbmx5IGZvciB0aGUgY2FzZSBvZiBwcm9wZXJ0aWVzIGNyZWF0ZWRcbiAgICAgIC8vIHZpYSBgY3JlYXRlUHJvcGVydHlgIG9uIGFjY2Vzc29ycywgd2hpY2ggd2lsbCBub3QgaGF2ZSBhbHJlYWR5XG4gICAgICAvLyBwb3B1bGF0ZWQgdGhlIGBjaGFuZ2VkUHJvcGVydGllc2AgbWFwIHNpbmNlIHRoZXkgYXJlIG5vdCBzZXQuXG4gICAgICAvLyBXZSBjYW4ndCBrbm93IGlmIHRoZXNlIGFjY2Vzc29ycyBoYWQgaW5pdGlhbGl6ZXJzLCBzbyB3ZSBqdXN0IHNldFxuICAgICAgLy8gdGhlbSBhbnl3YXkgLSBhIGRpZmZlcmVuY2UgZnJvbSBleHBlcmltZW50YWwgZGVjb3JhdG9ycyBvbiBmaWVsZHMgYW5kXG4gICAgICAvLyBzdGFuZGFyZCBkZWNvcmF0b3JzIG9uIGF1dG8tYWNjZXNzb3JzLlxuICAgICAgLy8gRm9yIGNvbnRleHQgc2VlOlxuICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2xpdC9saXQvcHVsbC80MTgzI2lzc3VlY29tbWVudC0xNzExOTU5NjM1XG4gICAgICBjb25zdCBlbGVtZW50UHJvcGVydGllcyA9ICh0aGlzLmNvbnN0cnVjdG9yIGFzIHR5cGVvZiBSZWFjdGl2ZUVsZW1lbnQpXG4gICAgICAgIC5lbGVtZW50UHJvcGVydGllcztcbiAgICAgIGlmIChlbGVtZW50UHJvcGVydGllcy5zaXplID4gMCkge1xuICAgICAgICBmb3IgKGNvbnN0IFtwLCBvcHRpb25zXSBvZiBlbGVtZW50UHJvcGVydGllcykge1xuICAgICAgICAgIGNvbnN0IHt3cmFwcGVkfSA9IG9wdGlvbnM7XG4gICAgICAgICAgY29uc3QgdmFsdWUgPSB0aGlzW3AgYXMga2V5b2YgdGhpc107XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgd3JhcHBlZCA9PT0gdHJ1ZSAmJlxuICAgICAgICAgICAgIXRoaXMuXyRjaGFuZ2VkUHJvcGVydGllcy5oYXMocCkgJiZcbiAgICAgICAgICAgIHZhbHVlICE9PSB1bmRlZmluZWRcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHRoaXMuXyRjaGFuZ2VQcm9wZXJ0eShwLCB1bmRlZmluZWQsIG9wdGlvbnMsIHZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgbGV0IHNob3VsZFVwZGF0ZSA9IGZhbHNlO1xuICAgIGNvbnN0IGNoYW5nZWRQcm9wZXJ0aWVzID0gdGhpcy5fJGNoYW5nZWRQcm9wZXJ0aWVzO1xuICAgIHRyeSB7XG4gICAgICBzaG91bGRVcGRhdGUgPSB0aGlzLnNob3VsZFVwZGF0ZShjaGFuZ2VkUHJvcGVydGllcyk7XG4gICAgICBpZiAoc2hvdWxkVXBkYXRlKSB7XG4gICAgICAgIHRoaXMud2lsbFVwZGF0ZShjaGFuZ2VkUHJvcGVydGllcyk7XG4gICAgICAgIHRoaXMuX19jb250cm9sbGVycz8uZm9yRWFjaCgoYykgPT4gYy5ob3N0VXBkYXRlPy4oKSk7XG4gICAgICAgIHRoaXMudXBkYXRlKGNoYW5nZWRQcm9wZXJ0aWVzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX19tYXJrVXBkYXRlZCgpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIC8vIFByZXZlbnQgYGZpcnN0VXBkYXRlZGAgYW5kIGB1cGRhdGVkYCBmcm9tIHJ1bm5pbmcgd2hlbiB0aGVyZSdzIGFuXG4gICAgICAvLyB1cGRhdGUgZXhjZXB0aW9uLlxuICAgICAgc2hvdWxkVXBkYXRlID0gZmFsc2U7XG4gICAgICAvLyBFbnN1cmUgZWxlbWVudCBjYW4gYWNjZXB0IGFkZGl0aW9uYWwgdXBkYXRlcyBhZnRlciBhbiBleGNlcHRpb24uXG4gICAgICB0aGlzLl9fbWFya1VwZGF0ZWQoKTtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuICAgIC8vIFRoZSB1cGRhdGUgaXMgbm8gbG9uZ2VyIGNvbnNpZGVyZWQgcGVuZGluZyBhbmQgZnVydGhlciB1cGRhdGVzIGFyZSBub3cgYWxsb3dlZC5cbiAgICBpZiAoc2hvdWxkVXBkYXRlKSB7XG4gICAgICB0aGlzLl8kZGlkVXBkYXRlKGNoYW5nZWRQcm9wZXJ0aWVzKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSW52b2tlZCBiZWZvcmUgYHVwZGF0ZSgpYCB0byBjb21wdXRlIHZhbHVlcyBuZWVkZWQgZHVyaW5nIHRoZSB1cGRhdGUuXG4gICAqXG4gICAqIEltcGxlbWVudCBgd2lsbFVwZGF0ZWAgdG8gY29tcHV0ZSBwcm9wZXJ0eSB2YWx1ZXMgdGhhdCBkZXBlbmQgb24gb3RoZXJcbiAgICogcHJvcGVydGllcyBhbmQgYXJlIHVzZWQgaW4gdGhlIHJlc3Qgb2YgdGhlIHVwZGF0ZSBwcm9jZXNzLlxuICAgKlxuICAgKiBgYGB0c1xuICAgKiB3aWxsVXBkYXRlKGNoYW5nZWRQcm9wZXJ0aWVzKSB7XG4gICAqICAgLy8gb25seSBuZWVkIHRvIGNoZWNrIGNoYW5nZWQgcHJvcGVydGllcyBmb3IgYW4gZXhwZW5zaXZlIGNvbXB1dGF0aW9uLlxuICAgKiAgIGlmIChjaGFuZ2VkUHJvcGVydGllcy5oYXMoJ2ZpcnN0TmFtZScpIHx8IGNoYW5nZWRQcm9wZXJ0aWVzLmhhcygnbGFzdE5hbWUnKSkge1xuICAgKiAgICAgdGhpcy5zaGEgPSBjb21wdXRlU0hBKGAke3RoaXMuZmlyc3ROYW1lfSAke3RoaXMubGFzdE5hbWV9YCk7XG4gICAqICAgfVxuICAgKiB9XG4gICAqXG4gICAqIHJlbmRlcigpIHtcbiAgICogICByZXR1cm4gaHRtbGBTSEE6ICR7dGhpcy5zaGF9YDtcbiAgICogfVxuICAgKiBgYGBcbiAgICpcbiAgICogQGNhdGVnb3J5IHVwZGF0ZXNcbiAgICovXG4gIHByb3RlY3RlZCB3aWxsVXBkYXRlKF9jaGFuZ2VkUHJvcGVydGllczogUHJvcGVydHlWYWx1ZXMpOiB2b2lkIHt9XG5cbiAgLy8gTm90ZSwgdGhpcyBpcyBhbiBvdmVycmlkZSBwb2ludCBmb3IgcG9seWZpbGwtc3VwcG9ydC5cbiAgLy8gQGludGVybmFsXG4gIF8kZGlkVXBkYXRlKGNoYW5nZWRQcm9wZXJ0aWVzOiBQcm9wZXJ0eVZhbHVlcykge1xuICAgIHRoaXMuX19jb250cm9sbGVycz8uZm9yRWFjaCgoYykgPT4gYy5ob3N0VXBkYXRlZD8uKCkpO1xuICAgIGlmICghdGhpcy5oYXNVcGRhdGVkKSB7XG4gICAgICB0aGlzLmhhc1VwZGF0ZWQgPSB0cnVlO1xuICAgICAgdGhpcy5maXJzdFVwZGF0ZWQoY2hhbmdlZFByb3BlcnRpZXMpO1xuICAgIH1cbiAgICB0aGlzLnVwZGF0ZWQoY2hhbmdlZFByb3BlcnRpZXMpO1xuICAgIGlmIChcbiAgICAgIERFVl9NT0RFICYmXG4gICAgICB0aGlzLmlzVXBkYXRlUGVuZGluZyAmJlxuICAgICAgKHRoaXMuY29uc3RydWN0b3IgYXMgdHlwZW9mIFJlYWN0aXZlRWxlbWVudCkuZW5hYmxlZFdhcm5pbmdzIS5pbmNsdWRlcyhcbiAgICAgICAgJ2NoYW5nZS1pbi11cGRhdGUnXG4gICAgICApXG4gICAgKSB7XG4gICAgICBpc3N1ZVdhcm5pbmcoXG4gICAgICAgICdjaGFuZ2UtaW4tdXBkYXRlJyxcbiAgICAgICAgYEVsZW1lbnQgJHt0aGlzLmxvY2FsTmFtZX0gc2NoZWR1bGVkIGFuIHVwZGF0ZSBgICtcbiAgICAgICAgICBgKGdlbmVyYWxseSBiZWNhdXNlIGEgcHJvcGVydHkgd2FzIHNldCkgYCArXG4gICAgICAgICAgYGFmdGVyIGFuIHVwZGF0ZSBjb21wbGV0ZWQsIGNhdXNpbmcgYSBuZXcgdXBkYXRlIHRvIGJlIHNjaGVkdWxlZC4gYCArXG4gICAgICAgICAgYFRoaXMgaXMgaW5lZmZpY2llbnQgYW5kIHNob3VsZCBiZSBhdm9pZGVkIHVubGVzcyB0aGUgbmV4dCB1cGRhdGUgYCArXG4gICAgICAgICAgYGNhbiBvbmx5IGJlIHNjaGVkdWxlZCBhcyBhIHNpZGUgZWZmZWN0IG9mIHRoZSBwcmV2aW91cyB1cGRhdGUuYFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9fbWFya1VwZGF0ZWQoKSB7XG4gICAgdGhpcy5fJGNoYW5nZWRQcm9wZXJ0aWVzID0gbmV3IE1hcCgpO1xuICAgIHRoaXMuaXNVcGRhdGVQZW5kaW5nID0gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBlbGVtZW50IGhhcyBjb21wbGV0ZWQgdXBkYXRpbmcuXG4gICAqIFRoZSBQcm9taXNlIHZhbHVlIGlzIGEgYm9vbGVhbiB0aGF0IGlzIGB0cnVlYCBpZiB0aGUgZWxlbWVudCBjb21wbGV0ZWQgdGhlXG4gICAqIHVwZGF0ZSB3aXRob3V0IHRyaWdnZXJpbmcgYW5vdGhlciB1cGRhdGUuIFRoZSBQcm9taXNlIHJlc3VsdCBpcyBgZmFsc2VgIGlmXG4gICAqIGEgcHJvcGVydHkgd2FzIHNldCBpbnNpZGUgYHVwZGF0ZWQoKWAuIElmIHRoZSBQcm9taXNlIGlzIHJlamVjdGVkLCBhblxuICAgKiBleGNlcHRpb24gd2FzIHRocm93biBkdXJpbmcgdGhlIHVwZGF0ZS5cbiAgICpcbiAgICogVG8gYXdhaXQgYWRkaXRpb25hbCBhc3luY2hyb25vdXMgd29yaywgb3ZlcnJpZGUgdGhlIGBnZXRVcGRhdGVDb21wbGV0ZWBcbiAgICogbWV0aG9kLiBGb3IgZXhhbXBsZSwgaXQgaXMgc29tZXRpbWVzIHVzZWZ1bCB0byBhd2FpdCBhIHJlbmRlcmVkIGVsZW1lbnRcbiAgICogYmVmb3JlIGZ1bGZpbGxpbmcgdGhpcyBQcm9taXNlLiBUbyBkbyB0aGlzLCBmaXJzdCBhd2FpdFxuICAgKiBgc3VwZXIuZ2V0VXBkYXRlQ29tcGxldGUoKWAsIHRoZW4gYW55IHN1YnNlcXVlbnQgc3RhdGUuXG4gICAqXG4gICAqIEByZXR1cm4gQSBwcm9taXNlIG9mIGEgYm9vbGVhbiB0aGF0IHJlc29sdmVzIHRvIHRydWUgaWYgdGhlIHVwZGF0ZSBjb21wbGV0ZWRcbiAgICogICAgIHdpdGhvdXQgdHJpZ2dlcmluZyBhbm90aGVyIHVwZGF0ZS5cbiAgICogQGNhdGVnb3J5IHVwZGF0ZXNcbiAgICovXG4gIGdldCB1cGRhdGVDb21wbGV0ZSgpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gdGhpcy5nZXRVcGRhdGVDb21wbGV0ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIE92ZXJyaWRlIHBvaW50IGZvciB0aGUgYHVwZGF0ZUNvbXBsZXRlYCBwcm9taXNlLlxuICAgKlxuICAgKiBJdCBpcyBub3Qgc2FmZSB0byBvdmVycmlkZSB0aGUgYHVwZGF0ZUNvbXBsZXRlYCBnZXR0ZXIgZGlyZWN0bHkgZHVlIHRvIGFcbiAgICogbGltaXRhdGlvbiBpbiBUeXBlU2NyaXB0IHdoaWNoIG1lYW5zIGl0IGlzIG5vdCBwb3NzaWJsZSB0byBjYWxsIGFcbiAgICogc3VwZXJjbGFzcyBnZXR0ZXIgKGUuZy4gYHN1cGVyLnVwZGF0ZUNvbXBsZXRlLnRoZW4oLi4uKWApIHdoZW4gdGhlIHRhcmdldFxuICAgKiBsYW5ndWFnZSBpcyBFUzUgKGh0dHBzOi8vZ2l0aHViLmNvbS9taWNyb3NvZnQvVHlwZVNjcmlwdC9pc3N1ZXMvMzM4KS5cbiAgICogVGhpcyBtZXRob2Qgc2hvdWxkIGJlIG92ZXJyaWRkZW4gaW5zdGVhZC4gRm9yIGV4YW1wbGU6XG4gICAqXG4gICAqIGBgYHRzXG4gICAqIGNsYXNzIE15RWxlbWVudCBleHRlbmRzIExpdEVsZW1lbnQge1xuICAgKiAgIG92ZXJyaWRlIGFzeW5jIGdldFVwZGF0ZUNvbXBsZXRlKCkge1xuICAgKiAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc3VwZXIuZ2V0VXBkYXRlQ29tcGxldGUoKTtcbiAgICogICAgIGF3YWl0IHRoaXMuX215Q2hpbGQudXBkYXRlQ29tcGxldGU7XG4gICAqICAgICByZXR1cm4gcmVzdWx0O1xuICAgKiAgIH1cbiAgICogfVxuICAgKiBgYGBcbiAgICpcbiAgICogQHJldHVybiBBIHByb21pc2Ugb2YgYSBib29sZWFuIHRoYXQgcmVzb2x2ZXMgdG8gdHJ1ZSBpZiB0aGUgdXBkYXRlIGNvbXBsZXRlZFxuICAgKiAgICAgd2l0aG91dCB0cmlnZ2VyaW5nIGFub3RoZXIgdXBkYXRlLlxuICAgKiBAY2F0ZWdvcnkgdXBkYXRlc1xuICAgKi9cbiAgcHJvdGVjdGVkIGdldFVwZGF0ZUNvbXBsZXRlKCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0aGlzLl9fdXBkYXRlUHJvbWlzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb250cm9scyB3aGV0aGVyIG9yIG5vdCBgdXBkYXRlKClgIHNob3VsZCBiZSBjYWxsZWQgd2hlbiB0aGUgZWxlbWVudCByZXF1ZXN0c1xuICAgKiBhbiB1cGRhdGUuIEJ5IGRlZmF1bHQsIHRoaXMgbWV0aG9kIGFsd2F5cyByZXR1cm5zIGB0cnVlYCwgYnV0IHRoaXMgY2FuIGJlXG4gICAqIGN1c3RvbWl6ZWQgdG8gY29udHJvbCB3aGVuIHRvIHVwZGF0ZS5cbiAgICpcbiAgICogQHBhcmFtIF9jaGFuZ2VkUHJvcGVydGllcyBNYXAgb2YgY2hhbmdlZCBwcm9wZXJ0aWVzIHdpdGggb2xkIHZhbHVlc1xuICAgKiBAY2F0ZWdvcnkgdXBkYXRlc1xuICAgKi9cbiAgcHJvdGVjdGVkIHNob3VsZFVwZGF0ZShfY2hhbmdlZFByb3BlcnRpZXM6IFByb3BlcnR5VmFsdWVzKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlcyB0aGUgZWxlbWVudC4gVGhpcyBtZXRob2QgcmVmbGVjdHMgcHJvcGVydHkgdmFsdWVzIHRvIGF0dHJpYnV0ZXMuXG4gICAqIEl0IGNhbiBiZSBvdmVycmlkZGVuIHRvIHJlbmRlciBhbmQga2VlcCB1cGRhdGVkIGVsZW1lbnQgRE9NLlxuICAgKiBTZXR0aW5nIHByb3BlcnRpZXMgaW5zaWRlIHRoaXMgbWV0aG9kIHdpbGwgKm5vdCogdHJpZ2dlclxuICAgKiBhbm90aGVyIHVwZGF0ZS5cbiAgICpcbiAgICogQHBhcmFtIF9jaGFuZ2VkUHJvcGVydGllcyBNYXAgb2YgY2hhbmdlZCBwcm9wZXJ0aWVzIHdpdGggb2xkIHZhbHVlc1xuICAgKiBAY2F0ZWdvcnkgdXBkYXRlc1xuICAgKi9cbiAgcHJvdGVjdGVkIHVwZGF0ZShfY2hhbmdlZFByb3BlcnRpZXM6IFByb3BlcnR5VmFsdWVzKSB7XG4gICAgLy8gVGhlIGZvckVhY2goKSBleHByZXNzaW9uIHdpbGwgb25seSBydW4gd2hlbiBfX3JlZmxlY3RpbmdQcm9wZXJ0aWVzIGlzXG4gICAgLy8gZGVmaW5lZCwgYW5kIGl0IHJldHVybnMgdW5kZWZpbmVkLCBzZXR0aW5nIF9fcmVmbGVjdGluZ1Byb3BlcnRpZXMgdG9cbiAgICAvLyB1bmRlZmluZWRcbiAgICB0aGlzLl9fcmVmbGVjdGluZ1Byb3BlcnRpZXMgJiY9IHRoaXMuX19yZWZsZWN0aW5nUHJvcGVydGllcy5mb3JFYWNoKChwKSA9PlxuICAgICAgdGhpcy5fX3Byb3BlcnR5VG9BdHRyaWJ1dGUocCwgdGhpc1twIGFzIGtleW9mIHRoaXNdKVxuICAgICkgYXMgdW5kZWZpbmVkO1xuICAgIHRoaXMuX19tYXJrVXBkYXRlZCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEludm9rZWQgd2hlbmV2ZXIgdGhlIGVsZW1lbnQgaXMgdXBkYXRlZC4gSW1wbGVtZW50IHRvIHBlcmZvcm1cbiAgICogcG9zdC11cGRhdGluZyB0YXNrcyB2aWEgRE9NIEFQSXMsIGZvciBleGFtcGxlLCBmb2N1c2luZyBhbiBlbGVtZW50LlxuICAgKlxuICAgKiBTZXR0aW5nIHByb3BlcnRpZXMgaW5zaWRlIHRoaXMgbWV0aG9kIHdpbGwgdHJpZ2dlciB0aGUgZWxlbWVudCB0byB1cGRhdGVcbiAgICogYWdhaW4gYWZ0ZXIgdGhpcyB1cGRhdGUgY3ljbGUgY29tcGxldGVzLlxuICAgKlxuICAgKiBAcGFyYW0gX2NoYW5nZWRQcm9wZXJ0aWVzIE1hcCBvZiBjaGFuZ2VkIHByb3BlcnRpZXMgd2l0aCBvbGQgdmFsdWVzXG4gICAqIEBjYXRlZ29yeSB1cGRhdGVzXG4gICAqL1xuICBwcm90ZWN0ZWQgdXBkYXRlZChfY2hhbmdlZFByb3BlcnRpZXM6IFByb3BlcnR5VmFsdWVzKSB7fVxuXG4gIC8qKlxuICAgKiBJbnZva2VkIHdoZW4gdGhlIGVsZW1lbnQgaXMgZmlyc3QgdXBkYXRlZC4gSW1wbGVtZW50IHRvIHBlcmZvcm0gb25lIHRpbWVcbiAgICogd29yayBvbiB0aGUgZWxlbWVudCBhZnRlciB1cGRhdGUuXG4gICAqXG4gICAqIGBgYHRzXG4gICAqIGZpcnN0VXBkYXRlZCgpIHtcbiAgICogICB0aGlzLnJlbmRlclJvb3QuZ2V0RWxlbWVudEJ5SWQoJ215LXRleHQtYXJlYScpLmZvY3VzKCk7XG4gICAqIH1cbiAgICogYGBgXG4gICAqXG4gICAqIFNldHRpbmcgcHJvcGVydGllcyBpbnNpZGUgdGhpcyBtZXRob2Qgd2lsbCB0cmlnZ2VyIHRoZSBlbGVtZW50IHRvIHVwZGF0ZVxuICAgKiBhZ2FpbiBhZnRlciB0aGlzIHVwZGF0ZSBjeWNsZSBjb21wbGV0ZXMuXG4gICAqXG4gICAqIEBwYXJhbSBfY2hhbmdlZFByb3BlcnRpZXMgTWFwIG9mIGNoYW5nZWQgcHJvcGVydGllcyB3aXRoIG9sZCB2YWx1ZXNcbiAgICogQGNhdGVnb3J5IHVwZGF0ZXNcbiAgICovXG4gIHByb3RlY3RlZCBmaXJzdFVwZGF0ZWQoX2NoYW5nZWRQcm9wZXJ0aWVzOiBQcm9wZXJ0eVZhbHVlcykge31cbn1cbi8vIEFzc2lnbmVkIGhlcmUgdG8gd29yayBhcm91bmQgYSBqc2NvbXBpbGVyIGJ1ZyB3aXRoIHN0YXRpYyBmaWVsZHNcbi8vIHdoZW4gY29tcGlsaW5nIHRvIEVTNS5cbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvY2xvc3VyZS1jb21waWxlci9pc3N1ZXMvMzE3N1xuKFJlYWN0aXZlRWxlbWVudCBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KVtcbiAgSlNDb21waWxlcl9yZW5hbWVQcm9wZXJ0eSgnZWxlbWVudFByb3BlcnRpZXMnLCBSZWFjdGl2ZUVsZW1lbnQpXG5dID0gbmV3IE1hcCgpO1xuKFJlYWN0aXZlRWxlbWVudCBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KVtcbiAgSlNDb21waWxlcl9yZW5hbWVQcm9wZXJ0eSgnZmluYWxpemVkJywgUmVhY3RpdmVFbGVtZW50KVxuXSA9IG5ldyBNYXAoKTtcblxuLy8gQXBwbHkgcG9seWZpbGxzIGlmIGF2YWlsYWJsZVxucG9seWZpbGxTdXBwb3J0Py4oe1JlYWN0aXZlRWxlbWVudH0pO1xuXG4vLyBEZXYgbW9kZSB3YXJuaW5ncy4uLlxuaWYgKERFVl9NT0RFKSB7XG4gIC8vIERlZmF1bHQgd2FybmluZyBzZXQuXG4gIFJlYWN0aXZlRWxlbWVudC5lbmFibGVkV2FybmluZ3MgPSBbXG4gICAgJ2NoYW5nZS1pbi11cGRhdGUnLFxuICAgICdhc3luYy1wZXJmb3JtLXVwZGF0ZScsXG4gIF07XG4gIGNvbnN0IGVuc3VyZU93bldhcm5pbmdzID0gZnVuY3Rpb24gKGN0b3I6IHR5cGVvZiBSZWFjdGl2ZUVsZW1lbnQpIHtcbiAgICBpZiAoXG4gICAgICAhY3Rvci5oYXNPd25Qcm9wZXJ0eShKU0NvbXBpbGVyX3JlbmFtZVByb3BlcnR5KCdlbmFibGVkV2FybmluZ3MnLCBjdG9yKSlcbiAgICApIHtcbiAgICAgIGN0b3IuZW5hYmxlZFdhcm5pbmdzID0gY3Rvci5lbmFibGVkV2FybmluZ3MhLnNsaWNlKCk7XG4gICAgfVxuICB9O1xuICBSZWFjdGl2ZUVsZW1lbnQuZW5hYmxlV2FybmluZyA9IGZ1bmN0aW9uIChcbiAgICB0aGlzOiB0eXBlb2YgUmVhY3RpdmVFbGVtZW50LFxuICAgIHdhcm5pbmc6IFdhcm5pbmdLaW5kXG4gICkge1xuICAgIGVuc3VyZU93bldhcm5pbmdzKHRoaXMpO1xuICAgIGlmICghdGhpcy5lbmFibGVkV2FybmluZ3MhLmluY2x1ZGVzKHdhcm5pbmcpKSB7XG4gICAgICB0aGlzLmVuYWJsZWRXYXJuaW5ncyEucHVzaCh3YXJuaW5nKTtcbiAgICB9XG4gIH07XG4gIFJlYWN0aXZlRWxlbWVudC5kaXNhYmxlV2FybmluZyA9IGZ1bmN0aW9uIChcbiAgICB0aGlzOiB0eXBlb2YgUmVhY3RpdmVFbGVtZW50LFxuICAgIHdhcm5pbmc6IFdhcm5pbmdLaW5kXG4gICkge1xuICAgIGVuc3VyZU93bldhcm5pbmdzKHRoaXMpO1xuICAgIGNvbnN0IGkgPSB0aGlzLmVuYWJsZWRXYXJuaW5ncyEuaW5kZXhPZih3YXJuaW5nKTtcbiAgICBpZiAoaSA+PSAwKSB7XG4gICAgICB0aGlzLmVuYWJsZWRXYXJuaW5ncyEuc3BsaWNlKGksIDEpO1xuICAgIH1cbiAgfTtcbn1cblxuLy8gSU1QT1JUQU5UOiBkbyBub3QgY2hhbmdlIHRoZSBwcm9wZXJ0eSBuYW1lIG9yIHRoZSBhc3NpZ25tZW50IGV4cHJlc3Npb24uXG4vLyBUaGlzIGxpbmUgd2lsbCBiZSB1c2VkIGluIHJlZ2V4ZXMgdG8gc2VhcmNoIGZvciBSZWFjdGl2ZUVsZW1lbnQgdXNhZ2UuXG4oZ2xvYmFsLnJlYWN0aXZlRWxlbWVudFZlcnNpb25zID8/PSBbXSkucHVzaCgnMi4xLjAnKTtcbmlmIChERVZfTU9ERSAmJiBnbG9iYWwucmVhY3RpdmVFbGVtZW50VmVyc2lvbnMubGVuZ3RoID4gMSkge1xuICBxdWV1ZU1pY3JvdGFzaygoKSA9PiB7XG4gICAgaXNzdWVXYXJuaW5nIShcbiAgICAgICdtdWx0aXBsZS12ZXJzaW9ucycsXG4gICAgICBgTXVsdGlwbGUgdmVyc2lvbnMgb2YgTGl0IGxvYWRlZC4gTG9hZGluZyBtdWx0aXBsZSB2ZXJzaW9ucyBgICtcbiAgICAgICAgYGlzIG5vdCByZWNvbW1lbmRlZC5gXG4gICAgKTtcbiAgfSk7XG59XG4iLCAiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQ1xuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZVxuICovXG5cbi8vIElNUE9SVEFOVDogdGhlc2UgaW1wb3J0cyBtdXN0IGJlIHR5cGUtb25seVxuaW1wb3J0IHR5cGUge0RpcmVjdGl2ZSwgRGlyZWN0aXZlUmVzdWx0LCBQYXJ0SW5mb30gZnJvbSAnLi9kaXJlY3RpdmUuanMnO1xuaW1wb3J0IHR5cGUge1RydXN0ZWRIVE1MLCBUcnVzdGVkVHlwZXNXaW5kb3d9IGZyb20gJ3RydXN0ZWQtdHlwZXMvbGliL2luZGV4LmpzJztcblxuY29uc3QgREVWX01PREUgPSB0cnVlO1xuY29uc3QgRU5BQkxFX0VYVFJBX1NFQ1VSSVRZX0hPT0tTID0gdHJ1ZTtcbmNvbnN0IEVOQUJMRV9TSEFEWURPTV9OT1BBVENIID0gdHJ1ZTtcbmNvbnN0IE5PREVfTU9ERSA9IGZhbHNlO1xuXG4vLyBBbGxvd3MgbWluaWZpZXJzIHRvIHJlbmFtZSByZWZlcmVuY2VzIHRvIGdsb2JhbFRoaXNcbmNvbnN0IGdsb2JhbCA9IGdsb2JhbFRoaXM7XG5cbi8qKlxuICogQ29udGFpbnMgdHlwZXMgdGhhdCBhcmUgcGFydCBvZiB0aGUgdW5zdGFibGUgZGVidWcgQVBJLlxuICpcbiAqIEV2ZXJ5dGhpbmcgaW4gdGhpcyBBUEkgaXMgbm90IHN0YWJsZSBhbmQgbWF5IGNoYW5nZSBvciBiZSByZW1vdmVkIGluIHRoZSBmdXR1cmUsXG4gKiBldmVuIG9uIHBhdGNoIHJlbGVhc2VzLlxuICovXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5hbWVzcGFjZVxuZXhwb3J0IG5hbWVzcGFjZSBMaXRVbnN0YWJsZSB7XG4gIC8qKlxuICAgKiBXaGVuIExpdCBpcyBydW5uaW5nIGluIGRldiBtb2RlIGFuZCBgd2luZG93LmVtaXRMaXREZWJ1Z0xvZ0V2ZW50c2AgaXMgdHJ1ZSxcbiAgICogd2Ugd2lsbCBlbWl0ICdsaXQtZGVidWcnIGV2ZW50cyB0byB3aW5kb3csIHdpdGggbGl2ZSBkZXRhaWxzIGFib3V0IHRoZSB1cGRhdGUgYW5kIHJlbmRlclxuICAgKiBsaWZlY3ljbGUuIFRoZXNlIGNhbiBiZSB1c2VmdWwgZm9yIHdyaXRpbmcgZGVidWcgdG9vbGluZyBhbmQgdmlzdWFsaXphdGlvbnMuXG4gICAqXG4gICAqIFBsZWFzZSBiZSBhd2FyZSB0aGF0IHJ1bm5pbmcgd2l0aCB3aW5kb3cuZW1pdExpdERlYnVnTG9nRXZlbnRzIGhhcyBwZXJmb3JtYW5jZSBvdmVyaGVhZCxcbiAgICogbWFraW5nIGNlcnRhaW4gb3BlcmF0aW9ucyB0aGF0IGFyZSBub3JtYWxseSB2ZXJ5IGNoZWFwIChsaWtlIGEgbm8tb3AgcmVuZGVyKSBtdWNoIHNsb3dlcixcbiAgICogYmVjYXVzZSB3ZSBtdXN0IGNvcHkgZGF0YSBhbmQgZGlzcGF0Y2ggZXZlbnRzLlxuICAgKi9cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1uYW1lc3BhY2VcbiAgZXhwb3J0IG5hbWVzcGFjZSBEZWJ1Z0xvZyB7XG4gICAgZXhwb3J0IHR5cGUgRW50cnkgPVxuICAgICAgfCBUZW1wbGF0ZVByZXBcbiAgICAgIHwgVGVtcGxhdGVJbnN0YW50aWF0ZWRcbiAgICAgIHwgVGVtcGxhdGVJbnN0YW50aWF0ZWRBbmRVcGRhdGVkXG4gICAgICB8IFRlbXBsYXRlVXBkYXRpbmdcbiAgICAgIHwgQmVnaW5SZW5kZXJcbiAgICAgIHwgRW5kUmVuZGVyXG4gICAgICB8IENvbW1pdFBhcnRFbnRyeVxuICAgICAgfCBTZXRQYXJ0VmFsdWU7XG4gICAgZXhwb3J0IGludGVyZmFjZSBUZW1wbGF0ZVByZXAge1xuICAgICAga2luZDogJ3RlbXBsYXRlIHByZXAnO1xuICAgICAgdGVtcGxhdGU6IFRlbXBsYXRlO1xuICAgICAgc3RyaW5nczogVGVtcGxhdGVTdHJpbmdzQXJyYXk7XG4gICAgICBjbG9uYWJsZVRlbXBsYXRlOiBIVE1MVGVtcGxhdGVFbGVtZW50O1xuICAgICAgcGFydHM6IFRlbXBsYXRlUGFydFtdO1xuICAgIH1cbiAgICBleHBvcnQgaW50ZXJmYWNlIEJlZ2luUmVuZGVyIHtcbiAgICAgIGtpbmQ6ICdiZWdpbiByZW5kZXInO1xuICAgICAgaWQ6IG51bWJlcjtcbiAgICAgIHZhbHVlOiB1bmtub3duO1xuICAgICAgY29udGFpbmVyOiBIVE1MRWxlbWVudCB8IERvY3VtZW50RnJhZ21lbnQ7XG4gICAgICBvcHRpb25zOiBSZW5kZXJPcHRpb25zIHwgdW5kZWZpbmVkO1xuICAgICAgcGFydDogQ2hpbGRQYXJ0IHwgdW5kZWZpbmVkO1xuICAgIH1cbiAgICBleHBvcnQgaW50ZXJmYWNlIEVuZFJlbmRlciB7XG4gICAgICBraW5kOiAnZW5kIHJlbmRlcic7XG4gICAgICBpZDogbnVtYmVyO1xuICAgICAgdmFsdWU6IHVua25vd247XG4gICAgICBjb250YWluZXI6IEhUTUxFbGVtZW50IHwgRG9jdW1lbnRGcmFnbWVudDtcbiAgICAgIG9wdGlvbnM6IFJlbmRlck9wdGlvbnMgfCB1bmRlZmluZWQ7XG4gICAgICBwYXJ0OiBDaGlsZFBhcnQ7XG4gICAgfVxuICAgIGV4cG9ydCBpbnRlcmZhY2UgVGVtcGxhdGVJbnN0YW50aWF0ZWQge1xuICAgICAga2luZDogJ3RlbXBsYXRlIGluc3RhbnRpYXRlZCc7XG4gICAgICB0ZW1wbGF0ZTogVGVtcGxhdGUgfCBDb21waWxlZFRlbXBsYXRlO1xuICAgICAgaW5zdGFuY2U6IFRlbXBsYXRlSW5zdGFuY2U7XG4gICAgICBvcHRpb25zOiBSZW5kZXJPcHRpb25zIHwgdW5kZWZpbmVkO1xuICAgICAgZnJhZ21lbnQ6IE5vZGU7XG4gICAgICBwYXJ0czogQXJyYXk8UGFydCB8IHVuZGVmaW5lZD47XG4gICAgICB2YWx1ZXM6IHVua25vd25bXTtcbiAgICB9XG4gICAgZXhwb3J0IGludGVyZmFjZSBUZW1wbGF0ZUluc3RhbnRpYXRlZEFuZFVwZGF0ZWQge1xuICAgICAga2luZDogJ3RlbXBsYXRlIGluc3RhbnRpYXRlZCBhbmQgdXBkYXRlZCc7XG4gICAgICB0ZW1wbGF0ZTogVGVtcGxhdGUgfCBDb21waWxlZFRlbXBsYXRlO1xuICAgICAgaW5zdGFuY2U6IFRlbXBsYXRlSW5zdGFuY2U7XG4gICAgICBvcHRpb25zOiBSZW5kZXJPcHRpb25zIHwgdW5kZWZpbmVkO1xuICAgICAgZnJhZ21lbnQ6IE5vZGU7XG4gICAgICBwYXJ0czogQXJyYXk8UGFydCB8IHVuZGVmaW5lZD47XG4gICAgICB2YWx1ZXM6IHVua25vd25bXTtcbiAgICB9XG4gICAgZXhwb3J0IGludGVyZmFjZSBUZW1wbGF0ZVVwZGF0aW5nIHtcbiAgICAgIGtpbmQ6ICd0ZW1wbGF0ZSB1cGRhdGluZyc7XG4gICAgICB0ZW1wbGF0ZTogVGVtcGxhdGUgfCBDb21waWxlZFRlbXBsYXRlO1xuICAgICAgaW5zdGFuY2U6IFRlbXBsYXRlSW5zdGFuY2U7XG4gICAgICBvcHRpb25zOiBSZW5kZXJPcHRpb25zIHwgdW5kZWZpbmVkO1xuICAgICAgcGFydHM6IEFycmF5PFBhcnQgfCB1bmRlZmluZWQ+O1xuICAgICAgdmFsdWVzOiB1bmtub3duW107XG4gICAgfVxuICAgIGV4cG9ydCBpbnRlcmZhY2UgU2V0UGFydFZhbHVlIHtcbiAgICAgIGtpbmQ6ICdzZXQgcGFydCc7XG4gICAgICBwYXJ0OiBQYXJ0O1xuICAgICAgdmFsdWU6IHVua25vd247XG4gICAgICB2YWx1ZUluZGV4OiBudW1iZXI7XG4gICAgICB2YWx1ZXM6IHVua25vd25bXTtcbiAgICAgIHRlbXBsYXRlSW5zdGFuY2U6IFRlbXBsYXRlSW5zdGFuY2U7XG4gICAgfVxuXG4gICAgZXhwb3J0IHR5cGUgQ29tbWl0UGFydEVudHJ5ID1cbiAgICAgIHwgQ29tbWl0Tm90aGluZ1RvQ2hpbGRFbnRyeVxuICAgICAgfCBDb21taXRUZXh0XG4gICAgICB8IENvbW1pdE5vZGVcbiAgICAgIHwgQ29tbWl0QXR0cmlidXRlXG4gICAgICB8IENvbW1pdFByb3BlcnR5XG4gICAgICB8IENvbW1pdEJvb2xlYW5BdHRyaWJ1dGVcbiAgICAgIHwgQ29tbWl0RXZlbnRMaXN0ZW5lclxuICAgICAgfCBDb21taXRUb0VsZW1lbnRCaW5kaW5nO1xuXG4gICAgZXhwb3J0IGludGVyZmFjZSBDb21taXROb3RoaW5nVG9DaGlsZEVudHJ5IHtcbiAgICAgIGtpbmQ6ICdjb21taXQgbm90aGluZyB0byBjaGlsZCc7XG4gICAgICBzdGFydDogQ2hpbGROb2RlO1xuICAgICAgZW5kOiBDaGlsZE5vZGUgfCBudWxsO1xuICAgICAgcGFyZW50OiBEaXNjb25uZWN0YWJsZSB8IHVuZGVmaW5lZDtcbiAgICAgIG9wdGlvbnM6IFJlbmRlck9wdGlvbnMgfCB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgZXhwb3J0IGludGVyZmFjZSBDb21taXRUZXh0IHtcbiAgICAgIGtpbmQ6ICdjb21taXQgdGV4dCc7XG4gICAgICBub2RlOiBUZXh0O1xuICAgICAgdmFsdWU6IHVua25vd247XG4gICAgICBvcHRpb25zOiBSZW5kZXJPcHRpb25zIHwgdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGV4cG9ydCBpbnRlcmZhY2UgQ29tbWl0Tm9kZSB7XG4gICAgICBraW5kOiAnY29tbWl0IG5vZGUnO1xuICAgICAgc3RhcnQ6IE5vZGU7XG4gICAgICBwYXJlbnQ6IERpc2Nvbm5lY3RhYmxlIHwgdW5kZWZpbmVkO1xuICAgICAgdmFsdWU6IE5vZGU7XG4gICAgICBvcHRpb25zOiBSZW5kZXJPcHRpb25zIHwgdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGV4cG9ydCBpbnRlcmZhY2UgQ29tbWl0QXR0cmlidXRlIHtcbiAgICAgIGtpbmQ6ICdjb21taXQgYXR0cmlidXRlJztcbiAgICAgIGVsZW1lbnQ6IEVsZW1lbnQ7XG4gICAgICBuYW1lOiBzdHJpbmc7XG4gICAgICB2YWx1ZTogdW5rbm93bjtcbiAgICAgIG9wdGlvbnM6IFJlbmRlck9wdGlvbnMgfCB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgZXhwb3J0IGludGVyZmFjZSBDb21taXRQcm9wZXJ0eSB7XG4gICAgICBraW5kOiAnY29tbWl0IHByb3BlcnR5JztcbiAgICAgIGVsZW1lbnQ6IEVsZW1lbnQ7XG4gICAgICBuYW1lOiBzdHJpbmc7XG4gICAgICB2YWx1ZTogdW5rbm93bjtcbiAgICAgIG9wdGlvbnM6IFJlbmRlck9wdGlvbnMgfCB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgZXhwb3J0IGludGVyZmFjZSBDb21taXRCb29sZWFuQXR0cmlidXRlIHtcbiAgICAgIGtpbmQ6ICdjb21taXQgYm9vbGVhbiBhdHRyaWJ1dGUnO1xuICAgICAgZWxlbWVudDogRWxlbWVudDtcbiAgICAgIG5hbWU6IHN0cmluZztcbiAgICAgIHZhbHVlOiBib29sZWFuO1xuICAgICAgb3B0aW9uczogUmVuZGVyT3B0aW9ucyB8IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBleHBvcnQgaW50ZXJmYWNlIENvbW1pdEV2ZW50TGlzdGVuZXIge1xuICAgICAga2luZDogJ2NvbW1pdCBldmVudCBsaXN0ZW5lcic7XG4gICAgICBlbGVtZW50OiBFbGVtZW50O1xuICAgICAgbmFtZTogc3RyaW5nO1xuICAgICAgdmFsdWU6IHVua25vd247XG4gICAgICBvbGRMaXN0ZW5lcjogdW5rbm93bjtcbiAgICAgIG9wdGlvbnM6IFJlbmRlck9wdGlvbnMgfCB1bmRlZmluZWQ7XG4gICAgICAvLyBUcnVlIGlmIHdlJ3JlIHJlbW92aW5nIHRoZSBvbGQgZXZlbnQgbGlzdGVuZXIgKGUuZy4gYmVjYXVzZSBzZXR0aW5ncyBjaGFuZ2VkLCBvciB2YWx1ZSBpcyBub3RoaW5nKVxuICAgICAgcmVtb3ZlTGlzdGVuZXI6IGJvb2xlYW47XG4gICAgICAvLyBUcnVlIGlmIHdlJ3JlIGFkZGluZyBhIG5ldyBldmVudCBsaXN0ZW5lciAoZS5nLiBiZWNhdXNlIGZpcnN0IHJlbmRlciwgb3Igc2V0dGluZ3MgY2hhbmdlZClcbiAgICAgIGFkZExpc3RlbmVyOiBib29sZWFuO1xuICAgIH1cblxuICAgIGV4cG9ydCBpbnRlcmZhY2UgQ29tbWl0VG9FbGVtZW50QmluZGluZyB7XG4gICAgICBraW5kOiAnY29tbWl0IHRvIGVsZW1lbnQgYmluZGluZyc7XG4gICAgICBlbGVtZW50OiBFbGVtZW50O1xuICAgICAgdmFsdWU6IHVua25vd247XG4gICAgICBvcHRpb25zOiBSZW5kZXJPcHRpb25zIHwgdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxufVxuXG5pbnRlcmZhY2UgRGVidWdMb2dnaW5nV2luZG93IHtcbiAgLy8gRXZlbiBpbiBkZXYgbW9kZSwgd2UgZ2VuZXJhbGx5IGRvbid0IHdhbnQgdG8gZW1pdCB0aGVzZSBldmVudHMsIGFzIHRoYXQnc1xuICAvLyBhbm90aGVyIGxldmVsIG9mIGNvc3QsIHNvIG9ubHkgZW1pdCB0aGVtIHdoZW4gREVWX01PREUgaXMgdHJ1ZSBfYW5kXyB3aGVuXG4gIC8vIHdpbmRvdy5lbWl0TGl0RGVidWdFdmVudHMgaXMgdHJ1ZS5cbiAgZW1pdExpdERlYnVnTG9nRXZlbnRzPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBVc2VmdWwgZm9yIHZpc3VhbGl6aW5nIGFuZCBsb2dnaW5nIGluc2lnaHRzIGludG8gd2hhdCB0aGUgTGl0IHRlbXBsYXRlIHN5c3RlbSBpcyBkb2luZy5cbiAqXG4gKiBDb21waWxlZCBvdXQgb2YgcHJvZCBtb2RlIGJ1aWxkcy5cbiAqL1xuY29uc3QgZGVidWdMb2dFdmVudCA9IERFVl9NT0RFXG4gID8gKGV2ZW50OiBMaXRVbnN0YWJsZS5EZWJ1Z0xvZy5FbnRyeSkgPT4ge1xuICAgICAgY29uc3Qgc2hvdWxkRW1pdCA9IChnbG9iYWwgYXMgdW5rbm93biBhcyBEZWJ1Z0xvZ2dpbmdXaW5kb3cpXG4gICAgICAgIC5lbWl0TGl0RGVidWdMb2dFdmVudHM7XG4gICAgICBpZiAoIXNob3VsZEVtaXQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgZ2xvYmFsLmRpc3BhdGNoRXZlbnQoXG4gICAgICAgIG5ldyBDdXN0b21FdmVudDxMaXRVbnN0YWJsZS5EZWJ1Z0xvZy5FbnRyeT4oJ2xpdC1kZWJ1ZycsIHtcbiAgICAgICAgICBkZXRhaWw6IGV2ZW50LFxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9XG4gIDogdW5kZWZpbmVkO1xuLy8gVXNlZCBmb3IgY29ubmVjdGluZyBiZWdpblJlbmRlciBhbmQgZW5kUmVuZGVyIGV2ZW50cyB3aGVuIHRoZXJlIGFyZSBuZXN0ZWRcbi8vIHJlbmRlcnMgd2hlbiBlcnJvcnMgYXJlIHRocm93biBwcmV2ZW50aW5nIGFuIGVuZFJlbmRlciBldmVudCBmcm9tIGJlaW5nXG4vLyBjYWxsZWQuXG5sZXQgZGVidWdMb2dSZW5kZXJJZCA9IDA7XG5cbmxldCBpc3N1ZVdhcm5pbmc6IChjb2RlOiBzdHJpbmcsIHdhcm5pbmc6IHN0cmluZykgPT4gdm9pZDtcblxuaWYgKERFVl9NT0RFKSB7XG4gIGdsb2JhbC5saXRJc3N1ZWRXYXJuaW5ncyA/Pz0gbmV3IFNldCgpO1xuXG4gIC8qKlxuICAgKiBJc3N1ZSBhIHdhcm5pbmcgaWYgd2UgaGF2ZW4ndCBhbHJlYWR5LCBiYXNlZCBlaXRoZXIgb24gYGNvZGVgIG9yIGB3YXJuaW5nYC5cbiAgICogV2FybmluZ3MgYXJlIGRpc2FibGVkIGF1dG9tYXRpY2FsbHkgb25seSBieSBgd2FybmluZ2A7IGRpc2FibGluZyB2aWEgYGNvZGVgXG4gICAqIGNhbiBiZSBkb25lIGJ5IHVzZXJzLlxuICAgKi9cbiAgaXNzdWVXYXJuaW5nID0gKGNvZGU6IHN0cmluZywgd2FybmluZzogc3RyaW5nKSA9PiB7XG4gICAgd2FybmluZyArPSBjb2RlXG4gICAgICA/IGAgU2VlIGh0dHBzOi8vbGl0LmRldi9tc2cvJHtjb2RlfSBmb3IgbW9yZSBpbmZvcm1hdGlvbi5gXG4gICAgICA6ICcnO1xuICAgIGlmIChcbiAgICAgICFnbG9iYWwubGl0SXNzdWVkV2FybmluZ3MhLmhhcyh3YXJuaW5nKSAmJlxuICAgICAgIWdsb2JhbC5saXRJc3N1ZWRXYXJuaW5ncyEuaGFzKGNvZGUpXG4gICAgKSB7XG4gICAgICBjb25zb2xlLndhcm4od2FybmluZyk7XG4gICAgICBnbG9iYWwubGl0SXNzdWVkV2FybmluZ3MhLmFkZCh3YXJuaW5nKTtcbiAgICB9XG4gIH07XG5cbiAgcXVldWVNaWNyb3Rhc2soKCkgPT4ge1xuICAgIGlzc3VlV2FybmluZyhcbiAgICAgICdkZXYtbW9kZScsXG4gICAgICBgTGl0IGlzIGluIGRldiBtb2RlLiBOb3QgcmVjb21tZW5kZWQgZm9yIHByb2R1Y3Rpb24hYFxuICAgICk7XG4gIH0pO1xufVxuXG5jb25zdCB3cmFwID1cbiAgRU5BQkxFX1NIQURZRE9NX05PUEFUQ0ggJiZcbiAgZ2xvYmFsLlNoYWR5RE9NPy5pblVzZSAmJlxuICBnbG9iYWwuU2hhZHlET00/Lm5vUGF0Y2ggPT09IHRydWVcbiAgICA/IChnbG9iYWwuU2hhZHlET00hLndyYXAgYXMgPFQgZXh0ZW5kcyBOb2RlPihub2RlOiBUKSA9PiBUKVxuICAgIDogPFQgZXh0ZW5kcyBOb2RlPihub2RlOiBUKSA9PiBub2RlO1xuXG5jb25zdCB0cnVzdGVkVHlwZXMgPSAoZ2xvYmFsIGFzIHVua25vd24gYXMgVHJ1c3RlZFR5cGVzV2luZG93KS50cnVzdGVkVHlwZXM7XG5cbi8qKlxuICogT3VyIFRydXN0ZWRUeXBlUG9saWN5IGZvciBIVE1MIHdoaWNoIGlzIGRlY2xhcmVkIHVzaW5nIHRoZSBodG1sIHRlbXBsYXRlXG4gKiB0YWcgZnVuY3Rpb24uXG4gKlxuICogVGhhdCBIVE1MIGlzIGEgZGV2ZWxvcGVyLWF1dGhvcmVkIGNvbnN0YW50LCBhbmQgaXMgcGFyc2VkIHdpdGggaW5uZXJIVE1MXG4gKiBiZWZvcmUgYW55IHVudHJ1c3RlZCBleHByZXNzaW9ucyBoYXZlIGJlZW4gbWl4ZWQgaW4uIFRoZXJlZm9yIGl0IGlzXG4gKiBjb25zaWRlcmVkIHNhZmUgYnkgY29uc3RydWN0aW9uLlxuICovXG5jb25zdCBwb2xpY3kgPSB0cnVzdGVkVHlwZXNcbiAgPyB0cnVzdGVkVHlwZXMuY3JlYXRlUG9saWN5KCdsaXQtaHRtbCcsIHtcbiAgICAgIGNyZWF0ZUhUTUw6IChzKSA9PiBzLFxuICAgIH0pXG4gIDogdW5kZWZpbmVkO1xuXG4vKipcbiAqIFVzZWQgdG8gc2FuaXRpemUgYW55IHZhbHVlIGJlZm9yZSBpdCBpcyB3cml0dGVuIGludG8gdGhlIERPTS4gVGhpcyBjYW4gYmVcbiAqIHVzZWQgdG8gaW1wbGVtZW50IGEgc2VjdXJpdHkgcG9saWN5IG9mIGFsbG93ZWQgYW5kIGRpc2FsbG93ZWQgdmFsdWVzIGluXG4gKiBvcmRlciB0byBwcmV2ZW50IFhTUyBhdHRhY2tzLlxuICpcbiAqIE9uZSB3YXkgb2YgdXNpbmcgdGhpcyBjYWxsYmFjayB3b3VsZCBiZSB0byBjaGVjayBhdHRyaWJ1dGVzIGFuZCBwcm9wZXJ0aWVzXG4gKiBhZ2FpbnN0IGEgbGlzdCBvZiBoaWdoIHJpc2sgZmllbGRzLCBhbmQgcmVxdWlyZSB0aGF0IHZhbHVlcyB3cml0dGVuIHRvIHN1Y2hcbiAqIGZpZWxkcyBiZSBpbnN0YW5jZXMgb2YgYSBjbGFzcyB3aGljaCBpcyBzYWZlIGJ5IGNvbnN0cnVjdGlvbi4gQ2xvc3VyZSdzIFNhZmVcbiAqIEhUTUwgVHlwZXMgaXMgb25lIGltcGxlbWVudGF0aW9uIG9mIHRoaXMgdGVjaG5pcXVlIChcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9nb29nbGUvc2FmZS1odG1sLXR5cGVzL2Jsb2IvbWFzdGVyL2RvYy9zYWZlaHRtbC10eXBlcy5tZCkuXG4gKiBUaGUgVHJ1c3RlZFR5cGVzIHBvbHlmaWxsIGluIEFQSS1vbmx5IG1vZGUgY291bGQgYWxzbyBiZSB1c2VkIGFzIGEgYmFzaXNcbiAqIGZvciB0aGlzIHRlY2huaXF1ZSAoaHR0cHM6Ly9naXRodWIuY29tL1dJQ0cvdHJ1c3RlZC10eXBlcykuXG4gKlxuICogQHBhcmFtIG5vZGUgVGhlIEhUTUwgbm9kZSAodXN1YWxseSBlaXRoZXIgYSAjdGV4dCBub2RlIG9yIGFuIEVsZW1lbnQpIHRoYXRcbiAqICAgICBpcyBiZWluZyB3cml0dGVuIHRvLiBOb3RlIHRoYXQgdGhpcyBpcyBqdXN0IGFuIGV4ZW1wbGFyIG5vZGUsIHRoZSB3cml0ZVxuICogICAgIG1heSB0YWtlIHBsYWNlIGFnYWluc3QgYW5vdGhlciBpbnN0YW5jZSBvZiB0aGUgc2FtZSBjbGFzcyBvZiBub2RlLlxuICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgYW4gYXR0cmlidXRlIG9yIHByb3BlcnR5IChmb3IgZXhhbXBsZSwgJ2hyZWYnKS5cbiAqIEBwYXJhbSB0eXBlIEluZGljYXRlcyB3aGV0aGVyIHRoZSB3cml0ZSB0aGF0J3MgYWJvdXQgdG8gYmUgcGVyZm9ybWVkIHdpbGxcbiAqICAgICBiZSB0byBhIHByb3BlcnR5IG9yIGEgbm9kZS5cbiAqIEByZXR1cm4gQSBmdW5jdGlvbiB0aGF0IHdpbGwgc2FuaXRpemUgdGhpcyBjbGFzcyBvZiB3cml0ZXMuXG4gKi9cbmV4cG9ydCB0eXBlIFNhbml0aXplckZhY3RvcnkgPSAoXG4gIG5vZGU6IE5vZGUsXG4gIG5hbWU6IHN0cmluZyxcbiAgdHlwZTogJ3Byb3BlcnR5JyB8ICdhdHRyaWJ1dGUnXG4pID0+IFZhbHVlU2FuaXRpemVyO1xuXG4vKipcbiAqIEEgZnVuY3Rpb24gd2hpY2ggY2FuIHNhbml0aXplIHZhbHVlcyB0aGF0IHdpbGwgYmUgd3JpdHRlbiB0byBhIHNwZWNpZmljIGtpbmRcbiAqIG9mIERPTSBzaW5rLlxuICpcbiAqIFNlZSBTYW5pdGl6ZXJGYWN0b3J5LlxuICpcbiAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2FuaXRpemUuIFdpbGwgYmUgdGhlIGFjdHVhbCB2YWx1ZSBwYXNzZWQgaW50b1xuICogICAgIHRoZSBsaXQtaHRtbCB0ZW1wbGF0ZSBsaXRlcmFsLCBzbyB0aGlzIGNvdWxkIGJlIG9mIGFueSB0eXBlLlxuICogQHJldHVybiBUaGUgdmFsdWUgdG8gd3JpdGUgdG8gdGhlIERPTS4gVXN1YWxseSB0aGUgc2FtZSBhcyB0aGUgaW5wdXQgdmFsdWUsXG4gKiAgICAgdW5sZXNzIHNhbml0aXphdGlvbiBpcyBuZWVkZWQuXG4gKi9cbmV4cG9ydCB0eXBlIFZhbHVlU2FuaXRpemVyID0gKHZhbHVlOiB1bmtub3duKSA9PiB1bmtub3duO1xuXG5jb25zdCBpZGVudGl0eUZ1bmN0aW9uOiBWYWx1ZVNhbml0aXplciA9ICh2YWx1ZTogdW5rbm93bikgPT4gdmFsdWU7XG5jb25zdCBub29wU2FuaXRpemVyOiBTYW5pdGl6ZXJGYWN0b3J5ID0gKFxuICBfbm9kZTogTm9kZSxcbiAgX25hbWU6IHN0cmluZyxcbiAgX3R5cGU6ICdwcm9wZXJ0eScgfCAnYXR0cmlidXRlJ1xuKSA9PiBpZGVudGl0eUZ1bmN0aW9uO1xuXG4vKiogU2V0cyB0aGUgZ2xvYmFsIHNhbml0aXplciBmYWN0b3J5LiAqL1xuY29uc3Qgc2V0U2FuaXRpemVyID0gKG5ld1Nhbml0aXplcjogU2FuaXRpemVyRmFjdG9yeSkgPT4ge1xuICBpZiAoIUVOQUJMRV9FWFRSQV9TRUNVUklUWV9IT09LUykge1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAoc2FuaXRpemVyRmFjdG9yeUludGVybmFsICE9PSBub29wU2FuaXRpemVyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYEF0dGVtcHRlZCB0byBvdmVyd3JpdGUgZXhpc3RpbmcgbGl0LWh0bWwgc2VjdXJpdHkgcG9saWN5LmAgK1xuICAgICAgICBgIHNldFNhbml0aXplRE9NVmFsdWVGYWN0b3J5IHNob3VsZCBiZSBjYWxsZWQgYXQgbW9zdCBvbmNlLmBcbiAgICApO1xuICB9XG4gIHNhbml0aXplckZhY3RvcnlJbnRlcm5hbCA9IG5ld1Nhbml0aXplcjtcbn07XG5cbi8qKlxuICogT25seSB1c2VkIGluIGludGVybmFsIHRlc3RzLCBub3QgYSBwYXJ0IG9mIHRoZSBwdWJsaWMgQVBJLlxuICovXG5jb25zdCBfdGVzdE9ubHlDbGVhclNhbml0aXplckZhY3RvcnlEb05vdENhbGxPckVsc2UgPSAoKSA9PiB7XG4gIHNhbml0aXplckZhY3RvcnlJbnRlcm5hbCA9IG5vb3BTYW5pdGl6ZXI7XG59O1xuXG5jb25zdCBjcmVhdGVTYW5pdGl6ZXI6IFNhbml0aXplckZhY3RvcnkgPSAobm9kZSwgbmFtZSwgdHlwZSkgPT4ge1xuICByZXR1cm4gc2FuaXRpemVyRmFjdG9yeUludGVybmFsKG5vZGUsIG5hbWUsIHR5cGUpO1xufTtcblxuLy8gQWRkZWQgdG8gYW4gYXR0cmlidXRlIG5hbWUgdG8gbWFyayB0aGUgYXR0cmlidXRlIGFzIGJvdW5kIHNvIHdlIGNhbiBmaW5kXG4vLyBpdCBlYXNpbHkuXG5jb25zdCBib3VuZEF0dHJpYnV0ZVN1ZmZpeCA9ICckbGl0JCc7XG5cbi8vIFRoaXMgbWFya2VyIGlzIHVzZWQgaW4gbWFueSBzeW50YWN0aWMgcG9zaXRpb25zIGluIEhUTUwsIHNvIGl0IG11c3QgYmVcbi8vIGEgdmFsaWQgZWxlbWVudCBuYW1lIGFuZCBhdHRyaWJ1dGUgbmFtZS4gV2UgZG9uJ3Qgc3VwcG9ydCBkeW5hbWljIG5hbWVzICh5ZXQpXG4vLyBidXQgdGhpcyBhdCBsZWFzdCBlbnN1cmVzIHRoYXQgdGhlIHBhcnNlIHRyZWUgaXMgY2xvc2VyIHRvIHRoZSB0ZW1wbGF0ZVxuLy8gaW50ZW50aW9uLlxuY29uc3QgbWFya2VyID0gYGxpdCQke01hdGgucmFuZG9tKCkudG9GaXhlZCg5KS5zbGljZSgyKX0kYDtcblxuLy8gU3RyaW5nIHVzZWQgdG8gdGVsbCBpZiBhIGNvbW1lbnQgaXMgYSBtYXJrZXIgY29tbWVudFxuY29uc3QgbWFya2VyTWF0Y2ggPSAnPycgKyBtYXJrZXI7XG5cbi8vIFRleHQgdXNlZCB0byBpbnNlcnQgYSBjb21tZW50IG1hcmtlciBub2RlLiBXZSB1c2UgcHJvY2Vzc2luZyBpbnN0cnVjdGlvblxuLy8gc3ludGF4IGJlY2F1c2UgaXQncyBzbGlnaHRseSBzbWFsbGVyLCBidXQgcGFyc2VzIGFzIGEgY29tbWVudCBub2RlLlxuY29uc3Qgbm9kZU1hcmtlciA9IGA8JHttYXJrZXJNYXRjaH0+YDtcblxuY29uc3QgZCA9XG4gIE5PREVfTU9ERSAmJiBnbG9iYWwuZG9jdW1lbnQgPT09IHVuZGVmaW5lZFxuICAgID8gKHtcbiAgICAgICAgY3JlYXRlVHJlZVdhbGtlcigpIHtcbiAgICAgICAgICByZXR1cm4ge307XG4gICAgICAgIH0sXG4gICAgICB9IGFzIHVua25vd24gYXMgRG9jdW1lbnQpXG4gICAgOiBkb2N1bWVudDtcblxuLy8gQ3JlYXRlcyBhIGR5bmFtaWMgbWFya2VyLiBXZSBuZXZlciBoYXZlIHRvIHNlYXJjaCBmb3IgdGhlc2UgaW4gdGhlIERPTS5cbmNvbnN0IGNyZWF0ZU1hcmtlciA9ICgpID0+IGQuY3JlYXRlQ29tbWVudCgnJyk7XG5cbi8vIGh0dHBzOi8vdGMzOS5naXRodWIuaW8vZWNtYTI2Mi8jc2VjLXR5cGVvZi1vcGVyYXRvclxudHlwZSBQcmltaXRpdmUgPSBudWxsIHwgdW5kZWZpbmVkIHwgYm9vbGVhbiB8IG51bWJlciB8IHN0cmluZyB8IHN5bWJvbCB8IGJpZ2ludDtcbmNvbnN0IGlzUHJpbWl0aXZlID0gKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgUHJpbWl0aXZlID0+XG4gIHZhbHVlID09PSBudWxsIHx8ICh0eXBlb2YgdmFsdWUgIT0gJ29iamVjdCcgJiYgdHlwZW9mIHZhbHVlICE9ICdmdW5jdGlvbicpO1xuY29uc3QgaXNBcnJheSA9IEFycmF5LmlzQXJyYXk7XG5jb25zdCBpc0l0ZXJhYmxlID0gKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgSXRlcmFibGU8dW5rbm93bj4gPT5cbiAgaXNBcnJheSh2YWx1ZSkgfHxcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgdHlwZW9mICh2YWx1ZSBhcyBhbnkpPy5bU3ltYm9sLml0ZXJhdG9yXSA9PT0gJ2Z1bmN0aW9uJztcblxuY29uc3QgU1BBQ0VfQ0hBUiA9IGBbIFxcdFxcblxcZlxccl1gO1xuY29uc3QgQVRUUl9WQUxVRV9DSEFSID0gYFteIFxcdFxcblxcZlxcclwiJ1xcYDw+PV1gO1xuY29uc3QgTkFNRV9DSEFSID0gYFteXFxcXHNcIic+PS9dYDtcblxuLy8gVGhlc2UgcmVnZXhlcyByZXByZXNlbnQgdGhlIGZpdmUgcGFyc2luZyBzdGF0ZXMgdGhhdCB3ZSBjYXJlIGFib3V0IGluIHRoZVxuLy8gVGVtcGxhdGUncyBIVE1MIHNjYW5uZXIuIFRoZXkgbWF0Y2ggdGhlICplbmQqIG9mIHRoZSBzdGF0ZSB0aGV5J3JlIG5hbWVkXG4vLyBhZnRlci5cbi8vIERlcGVuZGluZyBvbiB0aGUgbWF0Y2gsIHdlIHRyYW5zaXRpb24gdG8gYSBuZXcgc3RhdGUuIElmIHRoZXJlJ3Mgbm8gbWF0Y2gsXG4vLyB3ZSBzdGF5IGluIHRoZSBzYW1lIHN0YXRlLlxuLy8gTm90ZSB0aGF0IHRoZSByZWdleGVzIGFyZSBzdGF0ZWZ1bC4gV2UgdXRpbGl6ZSBsYXN0SW5kZXggYW5kIHN5bmMgaXRcbi8vIGFjcm9zcyB0aGUgbXVsdGlwbGUgcmVnZXhlcyB1c2VkLiBJbiBhZGRpdGlvbiB0byB0aGUgZml2ZSByZWdleGVzIGJlbG93XG4vLyB3ZSBhbHNvIGR5bmFtaWNhbGx5IGNyZWF0ZSBhIHJlZ2V4IHRvIGZpbmQgdGhlIG1hdGNoaW5nIGVuZCB0YWdzIGZvciByYXdcbi8vIHRleHQgZWxlbWVudHMuXG5cbi8qKlxuICogRW5kIG9mIHRleHQgaXM6IGA8YCBmb2xsb3dlZCBieTpcbiAqICAgKGNvbW1lbnQgc3RhcnQpIG9yICh0YWcpIG9yIChkeW5hbWljIHRhZyBiaW5kaW5nKVxuICovXG5jb25zdCB0ZXh0RW5kUmVnZXggPSAvPCg/OighLS18XFwvW15hLXpBLVpdKXwoXFwvP1thLXpBLVpdW14+XFxzXSopfChcXC8/JCkpL2c7XG5jb25zdCBDT01NRU5UX1NUQVJUID0gMTtcbmNvbnN0IFRBR19OQU1FID0gMjtcbmNvbnN0IERZTkFNSUNfVEFHX05BTUUgPSAzO1xuXG5jb25zdCBjb21tZW50RW5kUmVnZXggPSAvLS0+L2c7XG4vKipcbiAqIENvbW1lbnRzIG5vdCBzdGFydGVkIHdpdGggPCEtLSwgbGlrZSA8L3ssIGNhbiBiZSBlbmRlZCBieSBhIHNpbmdsZSBgPmBcbiAqL1xuY29uc3QgY29tbWVudDJFbmRSZWdleCA9IC8+L2c7XG5cbi8qKlxuICogVGhlIHRhZ0VuZCByZWdleCBtYXRjaGVzIHRoZSBlbmQgb2YgdGhlIFwiaW5zaWRlIGFuIG9wZW5pbmdcIiB0YWcgc3ludGF4XG4gKiBwb3NpdGlvbi4gSXQgZWl0aGVyIG1hdGNoZXMgYSBgPmAsIGFuIGF0dHJpYnV0ZS1saWtlIHNlcXVlbmNlLCBvciB0aGUgZW5kXG4gKiBvZiB0aGUgc3RyaW5nIGFmdGVyIGEgc3BhY2UgKGF0dHJpYnV0ZS1uYW1lIHBvc2l0aW9uIGVuZGluZykuXG4gKlxuICogU2VlIGF0dHJpYnV0ZXMgaW4gdGhlIEhUTUwgc3BlYzpcbiAqIGh0dHBzOi8vd3d3LnczLm9yZy9UUi9odG1sNS9zeW50YXguaHRtbCNlbGVtZW50cy1hdHRyaWJ1dGVzXG4gKlxuICogXCIgXFx0XFxuXFxmXFxyXCIgYXJlIEhUTUwgc3BhY2UgY2hhcmFjdGVyczpcbiAqIGh0dHBzOi8vaW5mcmEuc3BlYy53aGF0d2cub3JnLyNhc2NpaS13aGl0ZXNwYWNlXG4gKlxuICogU28gYW4gYXR0cmlidXRlIGlzOlxuICogICogVGhlIG5hbWU6IGFueSBjaGFyYWN0ZXIgZXhjZXB0IGEgd2hpdGVzcGFjZSBjaGFyYWN0ZXIsIChcIiksICgnKSwgXCI+XCIsXG4gKiAgICBcIj1cIiwgb3IgXCIvXCIuIE5vdGU6IHRoaXMgaXMgZGlmZmVyZW50IGZyb20gdGhlIEhUTUwgc3BlYyB3aGljaCBhbHNvIGV4Y2x1ZGVzIGNvbnRyb2wgY2hhcmFjdGVycy5cbiAqICAqIEZvbGxvd2VkIGJ5IHplcm8gb3IgbW9yZSBzcGFjZSBjaGFyYWN0ZXJzXG4gKiAgKiBGb2xsb3dlZCBieSBcIj1cIlxuICogICogRm9sbG93ZWQgYnkgemVybyBvciBtb3JlIHNwYWNlIGNoYXJhY3RlcnNcbiAqICAqIEZvbGxvd2VkIGJ5OlxuICogICAgKiBBbnkgY2hhcmFjdGVyIGV4Y2VwdCBzcGFjZSwgKCcpLCAoXCIpLCBcIjxcIiwgXCI+XCIsIFwiPVwiLCAoYCksIG9yXG4gKiAgICAqIChcIikgdGhlbiBhbnkgbm9uLShcIiksIG9yXG4gKiAgICAqICgnKSB0aGVuIGFueSBub24tKCcpXG4gKi9cbmNvbnN0IHRhZ0VuZFJlZ2V4ID0gbmV3IFJlZ0V4cChcbiAgYD58JHtTUEFDRV9DSEFSfSg/Oigke05BTUVfQ0hBUn0rKSgke1NQQUNFX0NIQVJ9Kj0ke1NQQUNFX0NIQVJ9Kig/OiR7QVRUUl9WQUxVRV9DSEFSfXwoXCJ8Jyl8KSl8JClgLFxuICAnZydcbik7XG5jb25zdCBFTlRJUkVfTUFUQ0ggPSAwO1xuY29uc3QgQVRUUklCVVRFX05BTUUgPSAxO1xuY29uc3QgU1BBQ0VTX0FORF9FUVVBTFMgPSAyO1xuY29uc3QgUVVPVEVfQ0hBUiA9IDM7XG5cbmNvbnN0IHNpbmdsZVF1b3RlQXR0ckVuZFJlZ2V4ID0gLycvZztcbmNvbnN0IGRvdWJsZVF1b3RlQXR0ckVuZFJlZ2V4ID0gL1wiL2c7XG4vKipcbiAqIE1hdGNoZXMgdGhlIHJhdyB0ZXh0IGVsZW1lbnRzLlxuICpcbiAqIENvbW1lbnRzIGFyZSBub3QgcGFyc2VkIHdpdGhpbiByYXcgdGV4dCBlbGVtZW50cywgc28gd2UgbmVlZCB0byBzZWFyY2ggdGhlaXJcbiAqIHRleHQgY29udGVudCBmb3IgbWFya2VyIHN0cmluZ3MuXG4gKi9cbmNvbnN0IHJhd1RleHRFbGVtZW50ID0gL14oPzpzY3JpcHR8c3R5bGV8dGV4dGFyZWF8dGl0bGUpJC9pO1xuXG4vKiogVGVtcGxhdGVSZXN1bHQgdHlwZXMgKi9cbmNvbnN0IEhUTUxfUkVTVUxUID0gMTtcbmNvbnN0IFNWR19SRVNVTFQgPSAyO1xuY29uc3QgTUFUSE1MX1JFU1VMVCA9IDM7XG5cbnR5cGUgUmVzdWx0VHlwZSA9IHR5cGVvZiBIVE1MX1JFU1VMVCB8IHR5cGVvZiBTVkdfUkVTVUxUIHwgdHlwZW9mIE1BVEhNTF9SRVNVTFQ7XG5cbi8vIFRlbXBsYXRlUGFydCB0eXBlc1xuLy8gSU1QT1JUQU5UOiB0aGVzZSBtdXN0IG1hdGNoIHRoZSB2YWx1ZXMgaW4gUGFydFR5cGVcbmNvbnN0IEFUVFJJQlVURV9QQVJUID0gMTtcbmNvbnN0IENISUxEX1BBUlQgPSAyO1xuY29uc3QgUFJPUEVSVFlfUEFSVCA9IDM7XG5jb25zdCBCT09MRUFOX0FUVFJJQlVURV9QQVJUID0gNDtcbmNvbnN0IEVWRU5UX1BBUlQgPSA1O1xuY29uc3QgRUxFTUVOVF9QQVJUID0gNjtcbmNvbnN0IENPTU1FTlRfUEFSVCA9IDc7XG5cbi8qKlxuICogVGhlIHJldHVybiB0eXBlIG9mIHRoZSB0ZW1wbGF0ZSB0YWcgZnVuY3Rpb25zLCB7QGxpbmtjb2RlIGh0bWx9IGFuZFxuICoge0BsaW5rY29kZSBzdmd9IHdoZW4gaXQgaGFzbid0IGJlZW4gY29tcGlsZWQgYnkgQGxpdC1sYWJzL2NvbXBpbGVyLlxuICpcbiAqIEEgYFRlbXBsYXRlUmVzdWx0YCBvYmplY3QgaG9sZHMgYWxsIHRoZSBpbmZvcm1hdGlvbiBhYm91dCBhIHRlbXBsYXRlXG4gKiBleHByZXNzaW9uIHJlcXVpcmVkIHRvIHJlbmRlciBpdDogdGhlIHRlbXBsYXRlIHN0cmluZ3MsIGV4cHJlc3Npb24gdmFsdWVzLFxuICogYW5kIHR5cGUgb2YgdGVtcGxhdGUgKGh0bWwgb3Igc3ZnKS5cbiAqXG4gKiBgVGVtcGxhdGVSZXN1bHRgIG9iamVjdHMgZG8gbm90IGNyZWF0ZSBhbnkgRE9NIG9uIHRoZWlyIG93bi4gVG8gY3JlYXRlIG9yXG4gKiB1cGRhdGUgRE9NIHlvdSBuZWVkIHRvIHJlbmRlciB0aGUgYFRlbXBsYXRlUmVzdWx0YC4gU2VlXG4gKiBbUmVuZGVyaW5nXShodHRwczovL2xpdC5kZXYvZG9jcy9jb21wb25lbnRzL3JlbmRlcmluZykgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4gKlxuICovXG5leHBvcnQgdHlwZSBVbmNvbXBpbGVkVGVtcGxhdGVSZXN1bHQ8VCBleHRlbmRzIFJlc3VsdFR5cGUgPSBSZXN1bHRUeXBlPiA9IHtcbiAgLy8gVGhpcyBwcm9wZXJ0eSBuZWVkcyB0byByZW1haW4gdW5taW5pZmllZC5cbiAgWydfJGxpdFR5cGUkJ106IFQ7XG4gIHN0cmluZ3M6IFRlbXBsYXRlU3RyaW5nc0FycmF5O1xuICB2YWx1ZXM6IHVua25vd25bXTtcbn07XG5cbi8qKlxuICogVGhpcyBpcyBhIHRlbXBsYXRlIHJlc3VsdCB0aGF0IG1heSBiZSBlaXRoZXIgdW5jb21waWxlZCBvciBjb21waWxlZC5cbiAqXG4gKiBJbiB0aGUgZnV0dXJlLCBUZW1wbGF0ZVJlc3VsdCB3aWxsIGJlIHRoaXMgdHlwZS4gSWYgeW91IHdhbnQgdG8gZXhwbGljaXRseVxuICogbm90ZSB0aGF0IGEgdGVtcGxhdGUgcmVzdWx0IGlzIHBvdGVudGlhbGx5IGNvbXBpbGVkLCB5b3UgY2FuIHJlZmVyZW5jZSB0aGlzXG4gKiB0eXBlIGFuZCBpdCB3aWxsIGNvbnRpbnVlIHRvIGJlaGF2ZSB0aGUgc2FtZSB0aHJvdWdoIHRoZSBuZXh0IG1ham9yIHZlcnNpb25cbiAqIG9mIExpdC4gVGhpcyBjYW4gYmUgdXNlZnVsIGZvciBjb2RlIHRoYXQgd2FudHMgdG8gcHJlcGFyZSBmb3IgdGhlIG5leHRcbiAqIG1ham9yIHZlcnNpb24gb2YgTGl0LlxuICovXG5leHBvcnQgdHlwZSBNYXliZUNvbXBpbGVkVGVtcGxhdGVSZXN1bHQ8VCBleHRlbmRzIFJlc3VsdFR5cGUgPSBSZXN1bHRUeXBlPiA9XG4gIHwgVW5jb21waWxlZFRlbXBsYXRlUmVzdWx0PFQ+XG4gIHwgQ29tcGlsZWRUZW1wbGF0ZVJlc3VsdDtcblxuLyoqXG4gKiBUaGUgcmV0dXJuIHR5cGUgb2YgdGhlIHRlbXBsYXRlIHRhZyBmdW5jdGlvbnMsIHtAbGlua2NvZGUgaHRtbH0gYW5kXG4gKiB7QGxpbmtjb2RlIHN2Z30uXG4gKlxuICogQSBgVGVtcGxhdGVSZXN1bHRgIG9iamVjdCBob2xkcyBhbGwgdGhlIGluZm9ybWF0aW9uIGFib3V0IGEgdGVtcGxhdGVcbiAqIGV4cHJlc3Npb24gcmVxdWlyZWQgdG8gcmVuZGVyIGl0OiB0aGUgdGVtcGxhdGUgc3RyaW5ncywgZXhwcmVzc2lvbiB2YWx1ZXMsXG4gKiBhbmQgdHlwZSBvZiB0ZW1wbGF0ZSAoaHRtbCBvciBzdmcpLlxuICpcbiAqIGBUZW1wbGF0ZVJlc3VsdGAgb2JqZWN0cyBkbyBub3QgY3JlYXRlIGFueSBET00gb24gdGhlaXIgb3duLiBUbyBjcmVhdGUgb3JcbiAqIHVwZGF0ZSBET00geW91IG5lZWQgdG8gcmVuZGVyIHRoZSBgVGVtcGxhdGVSZXN1bHRgLiBTZWVcbiAqIFtSZW5kZXJpbmddKGh0dHBzOi8vbGl0LmRldi9kb2NzL2NvbXBvbmVudHMvcmVuZGVyaW5nKSBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cbiAqXG4gKiBJbiBMaXQgNCwgdGhpcyB0eXBlIHdpbGwgYmUgYW4gYWxpYXMgb2ZcbiAqIE1heWJlQ29tcGlsZWRUZW1wbGF0ZVJlc3VsdCwgc28gdGhhdCBjb2RlIHdpbGwgZ2V0IHR5cGUgZXJyb3JzIGlmIGl0IGFzc3VtZXNcbiAqIHRoYXQgTGl0IHRlbXBsYXRlcyBhcmUgbm90IGNvbXBpbGVkLiBXaGVuIGRlbGliZXJhdGVseSB3b3JraW5nIHdpdGggb25seVxuICogb25lLCB1c2UgZWl0aGVyIHtAbGlua2NvZGUgQ29tcGlsZWRUZW1wbGF0ZVJlc3VsdH0gb3JcbiAqIHtAbGlua2NvZGUgVW5jb21waWxlZFRlbXBsYXRlUmVzdWx0fSBleHBsaWNpdGx5LlxuICovXG5leHBvcnQgdHlwZSBUZW1wbGF0ZVJlc3VsdDxUIGV4dGVuZHMgUmVzdWx0VHlwZSA9IFJlc3VsdFR5cGU+ID1cbiAgVW5jb21waWxlZFRlbXBsYXRlUmVzdWx0PFQ+O1xuXG5leHBvcnQgdHlwZSBIVE1MVGVtcGxhdGVSZXN1bHQgPSBUZW1wbGF0ZVJlc3VsdDx0eXBlb2YgSFRNTF9SRVNVTFQ+O1xuXG5leHBvcnQgdHlwZSBTVkdUZW1wbGF0ZVJlc3VsdCA9IFRlbXBsYXRlUmVzdWx0PHR5cGVvZiBTVkdfUkVTVUxUPjtcblxuZXhwb3J0IHR5cGUgTWF0aE1MVGVtcGxhdGVSZXN1bHQgPSBUZW1wbGF0ZVJlc3VsdDx0eXBlb2YgTUFUSE1MX1JFU1VMVD47XG5cbi8qKlxuICogQSBUZW1wbGF0ZVJlc3VsdCB0aGF0IGhhcyBiZWVuIGNvbXBpbGVkIGJ5IEBsaXQtbGFicy9jb21waWxlciwgc2tpcHBpbmcgdGhlXG4gKiBwcmVwYXJlIHN0ZXAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29tcGlsZWRUZW1wbGF0ZVJlc3VsdCB7XG4gIC8vIFRoaXMgaXMgYSBmYWN0b3J5IGluIG9yZGVyIHRvIG1ha2UgdGVtcGxhdGUgaW5pdGlhbGl6YXRpb24gbGF6eVxuICAvLyBhbmQgYWxsb3cgU2hhZHlSZW5kZXJPcHRpb25zIHNjb3BlIHRvIGJlIHBhc3NlZCBpbi5cbiAgLy8gVGhpcyBwcm9wZXJ0eSBuZWVkcyB0byByZW1haW4gdW5taW5pZmllZC5cbiAgWydfJGxpdFR5cGUkJ106IENvbXBpbGVkVGVtcGxhdGU7XG4gIHZhbHVlczogdW5rbm93bltdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvbXBpbGVkVGVtcGxhdGUgZXh0ZW5kcyBPbWl0PFRlbXBsYXRlLCAnZWwnPiB7XG4gIC8vIGVsIGlzIG92ZXJyaWRkZW4gdG8gYmUgb3B0aW9uYWwuIFdlIGluaXRpYWxpemUgaXQgb24gZmlyc3QgcmVuZGVyXG4gIGVsPzogSFRNTFRlbXBsYXRlRWxlbWVudDtcblxuICAvLyBUaGUgcHJlcGFyZWQgSFRNTCBzdHJpbmcgdG8gY3JlYXRlIGEgdGVtcGxhdGUgZWxlbWVudCBmcm9tLlxuICAvLyBUaGUgdHlwZSBpcyBhIFRlbXBsYXRlU3RyaW5nc0FycmF5IHRvIGd1YXJhbnRlZSB0aGF0IHRoZSB2YWx1ZSBjYW1lIGZyb21cbiAgLy8gc291cmNlIGNvZGUsIHByZXZlbnRpbmcgYSBKU09OIGluamVjdGlvbiBhdHRhY2suXG4gIGg6IFRlbXBsYXRlU3RyaW5nc0FycmF5O1xufVxuXG4vKipcbiAqIEdlbmVyYXRlcyBhIHRlbXBsYXRlIGxpdGVyYWwgdGFnIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBhIFRlbXBsYXRlUmVzdWx0IHdpdGhcbiAqIHRoZSBnaXZlbiByZXN1bHQgdHlwZS5cbiAqL1xuY29uc3QgdGFnID1cbiAgPFQgZXh0ZW5kcyBSZXN1bHRUeXBlPih0eXBlOiBUKSA9PlxuICAoc3RyaW5nczogVGVtcGxhdGVTdHJpbmdzQXJyYXksIC4uLnZhbHVlczogdW5rbm93bltdKTogVGVtcGxhdGVSZXN1bHQ8VD4gPT4ge1xuICAgIC8vIFdhcm4gYWdhaW5zdCB0ZW1wbGF0ZXMgb2N0YWwgZXNjYXBlIHNlcXVlbmNlc1xuICAgIC8vIFdlIGRvIHRoaXMgaGVyZSByYXRoZXIgdGhhbiBpbiByZW5kZXIgc28gdGhhdCB0aGUgd2FybmluZyBpcyBjbG9zZXIgdG8gdGhlXG4gICAgLy8gdGVtcGxhdGUgZGVmaW5pdGlvbi5cbiAgICBpZiAoREVWX01PREUgJiYgc3RyaW5ncy5zb21lKChzKSA9PiBzID09PSB1bmRlZmluZWQpKSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICdTb21lIHRlbXBsYXRlIHN0cmluZ3MgYXJlIHVuZGVmaW5lZC5cXG4nICtcbiAgICAgICAgICAnVGhpcyBpcyBwcm9iYWJseSBjYXVzZWQgYnkgaWxsZWdhbCBvY3RhbCBlc2NhcGUgc2VxdWVuY2VzLidcbiAgICAgICk7XG4gICAgfVxuICAgIGlmIChERVZfTU9ERSkge1xuICAgICAgLy8gSW1wb3J0IHN0YXRpYy1odG1sLmpzIHJlc3VsdHMgaW4gYSBjaXJjdWxhciBkZXBlbmRlbmN5IHdoaWNoIGczIGRvZXNuJ3RcbiAgICAgIC8vIGhhbmRsZS4gSW5zdGVhZCB3ZSBrbm93IHRoYXQgc3RhdGljIHZhbHVlcyBtdXN0IGhhdmUgdGhlIGZpZWxkXG4gICAgICAvLyBgXyRsaXRTdGF0aWMkYC5cbiAgICAgIGlmIChcbiAgICAgICAgdmFsdWVzLnNvbWUoKHZhbCkgPT4gKHZhbCBhcyB7XyRsaXRTdGF0aWMkOiB1bmtub3dufSk/LlsnXyRsaXRTdGF0aWMkJ10pXG4gICAgICApIHtcbiAgICAgICAgaXNzdWVXYXJuaW5nKFxuICAgICAgICAgICcnLFxuICAgICAgICAgIGBTdGF0aWMgdmFsdWVzICdsaXRlcmFsJyBvciAndW5zYWZlU3RhdGljJyBjYW5ub3QgYmUgdXNlZCBhcyB2YWx1ZXMgdG8gbm9uLXN0YXRpYyB0ZW1wbGF0ZXMuXFxuYCArXG4gICAgICAgICAgICBgUGxlYXNlIHVzZSB0aGUgc3RhdGljICdodG1sJyB0YWcgZnVuY3Rpb24uIFNlZSBodHRwczovL2xpdC5kZXYvZG9jcy90ZW1wbGF0ZXMvZXhwcmVzc2lvbnMvI3N0YXRpYy1leHByZXNzaW9uc2BcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIC8vIFRoaXMgcHJvcGVydHkgbmVlZHMgdG8gcmVtYWluIHVubWluaWZpZWQuXG4gICAgICBbJ18kbGl0VHlwZSQnXTogdHlwZSxcbiAgICAgIHN0cmluZ3MsXG4gICAgICB2YWx1ZXMsXG4gICAgfTtcbiAgfTtcblxuLyoqXG4gKiBJbnRlcnByZXRzIGEgdGVtcGxhdGUgbGl0ZXJhbCBhcyBhbiBIVE1MIHRlbXBsYXRlIHRoYXQgY2FuIGVmZmljaWVudGx5XG4gKiByZW5kZXIgdG8gYW5kIHVwZGF0ZSBhIGNvbnRhaW5lci5cbiAqXG4gKiBgYGB0c1xuICogY29uc3QgaGVhZGVyID0gKHRpdGxlOiBzdHJpbmcpID0+IGh0bWxgPGgxPiR7dGl0bGV9PC9oMT5gO1xuICogYGBgXG4gKlxuICogVGhlIGBodG1sYCB0YWcgcmV0dXJucyBhIGRlc2NyaXB0aW9uIG9mIHRoZSBET00gdG8gcmVuZGVyIGFzIGEgdmFsdWUuIEl0IGlzXG4gKiBsYXp5LCBtZWFuaW5nIG5vIHdvcmsgaXMgZG9uZSB1bnRpbCB0aGUgdGVtcGxhdGUgaXMgcmVuZGVyZWQuIFdoZW4gcmVuZGVyaW5nLFxuICogaWYgYSB0ZW1wbGF0ZSBjb21lcyBmcm9tIHRoZSBzYW1lIGV4cHJlc3Npb24gYXMgYSBwcmV2aW91c2x5IHJlbmRlcmVkIHJlc3VsdCxcbiAqIGl0J3MgZWZmaWNpZW50bHkgdXBkYXRlZCBpbnN0ZWFkIG9mIHJlcGxhY2VkLlxuICovXG5leHBvcnQgY29uc3QgaHRtbCA9IHRhZyhIVE1MX1JFU1VMVCk7XG5cbi8qKlxuICogSW50ZXJwcmV0cyBhIHRlbXBsYXRlIGxpdGVyYWwgYXMgYW4gU1ZHIGZyYWdtZW50IHRoYXQgY2FuIGVmZmljaWVudGx5IHJlbmRlclxuICogdG8gYW5kIHVwZGF0ZSBhIGNvbnRhaW5lci5cbiAqXG4gKiBgYGB0c1xuICogY29uc3QgcmVjdCA9IHN2Z2A8cmVjdCB3aWR0aD1cIjEwXCIgaGVpZ2h0PVwiMTBcIj48L3JlY3Q+YDtcbiAqXG4gKiBjb25zdCBteUltYWdlID0gaHRtbGBcbiAqICAgPHN2ZyB2aWV3Qm94PVwiMCAwIDEwIDEwXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiPlxuICogICAgICR7cmVjdH1cbiAqICAgPC9zdmc+YDtcbiAqIGBgYFxuICpcbiAqIFRoZSBgc3ZnYCAqdGFnIGZ1bmN0aW9uKiBzaG91bGQgb25seSBiZSB1c2VkIGZvciBTVkcgZnJhZ21lbnRzLCBvciBlbGVtZW50c1xuICogdGhhdCB3b3VsZCBiZSBjb250YWluZWQgKippbnNpZGUqKiBhbiBgPHN2Zz5gIEhUTUwgZWxlbWVudC4gQSBjb21tb24gZXJyb3IgaXNcbiAqIHBsYWNpbmcgYW4gYDxzdmc+YCAqZWxlbWVudCogaW4gYSB0ZW1wbGF0ZSB0YWdnZWQgd2l0aCB0aGUgYHN2Z2AgdGFnXG4gKiBmdW5jdGlvbi4gVGhlIGA8c3ZnPmAgZWxlbWVudCBpcyBhbiBIVE1MIGVsZW1lbnQgYW5kIHNob3VsZCBiZSB1c2VkIHdpdGhpbiBhXG4gKiB0ZW1wbGF0ZSB0YWdnZWQgd2l0aCB0aGUge0BsaW5rY29kZSBodG1sfSB0YWcgZnVuY3Rpb24uXG4gKlxuICogSW4gTGl0RWxlbWVudCB1c2FnZSwgaXQncyBpbnZhbGlkIHRvIHJldHVybiBhbiBTVkcgZnJhZ21lbnQgZnJvbSB0aGVcbiAqIGByZW5kZXIoKWAgbWV0aG9kLCBhcyB0aGUgU1ZHIGZyYWdtZW50IHdpbGwgYmUgY29udGFpbmVkIHdpdGhpbiB0aGUgZWxlbWVudCdzXG4gKiBzaGFkb3cgcm9vdCBhbmQgdGh1cyBub3QgYmUgcHJvcGVybHkgY29udGFpbmVkIHdpdGhpbiBhbiBgPHN2Zz5gIEhUTUxcbiAqIGVsZW1lbnQuXG4gKi9cbmV4cG9ydCBjb25zdCBzdmcgPSB0YWcoU1ZHX1JFU1VMVCk7XG5cbi8qKlxuICogSW50ZXJwcmV0cyBhIHRlbXBsYXRlIGxpdGVyYWwgYXMgTWF0aE1MIGZyYWdtZW50IHRoYXQgY2FuIGVmZmljaWVudGx5IHJlbmRlclxuICogdG8gYW5kIHVwZGF0ZSBhIGNvbnRhaW5lci5cbiAqXG4gKiBgYGB0c1xuICogY29uc3QgbnVtID0gbWF0aG1sYDxtbj4xPC9tbj5gO1xuICpcbiAqIGNvbnN0IGVxID0gaHRtbGBcbiAqICAgPG1hdGg+XG4gKiAgICAgJHtudW19XG4gKiAgIDwvbWF0aD5gO1xuICogYGBgXG4gKlxuICogVGhlIGBtYXRobWxgICp0YWcgZnVuY3Rpb24qIHNob3VsZCBvbmx5IGJlIHVzZWQgZm9yIE1hdGhNTCBmcmFnbWVudHMsIG9yXG4gKiBlbGVtZW50cyB0aGF0IHdvdWxkIGJlIGNvbnRhaW5lZCAqKmluc2lkZSoqIGEgYDxtYXRoPmAgSFRNTCBlbGVtZW50LiBBIGNvbW1vblxuICogZXJyb3IgaXMgcGxhY2luZyBhIGA8bWF0aD5gICplbGVtZW50KiBpbiBhIHRlbXBsYXRlIHRhZ2dlZCB3aXRoIHRoZSBgbWF0aG1sYFxuICogdGFnIGZ1bmN0aW9uLiBUaGUgYDxtYXRoPmAgZWxlbWVudCBpcyBhbiBIVE1MIGVsZW1lbnQgYW5kIHNob3VsZCBiZSB1c2VkXG4gKiB3aXRoaW4gYSB0ZW1wbGF0ZSB0YWdnZWQgd2l0aCB0aGUge0BsaW5rY29kZSBodG1sfSB0YWcgZnVuY3Rpb24uXG4gKlxuICogSW4gTGl0RWxlbWVudCB1c2FnZSwgaXQncyBpbnZhbGlkIHRvIHJldHVybiBhbiBNYXRoTUwgZnJhZ21lbnQgZnJvbSB0aGVcbiAqIGByZW5kZXIoKWAgbWV0aG9kLCBhcyB0aGUgTWF0aE1MIGZyYWdtZW50IHdpbGwgYmUgY29udGFpbmVkIHdpdGhpbiB0aGVcbiAqIGVsZW1lbnQncyBzaGFkb3cgcm9vdCBhbmQgdGh1cyBub3QgYmUgcHJvcGVybHkgY29udGFpbmVkIHdpdGhpbiBhIGA8bWF0aD5gXG4gKiBIVE1MIGVsZW1lbnQuXG4gKi9cbmV4cG9ydCBjb25zdCBtYXRobWwgPSB0YWcoTUFUSE1MX1JFU1VMVCk7XG5cbi8qKlxuICogQSBzZW50aW5lbCB2YWx1ZSB0aGF0IHNpZ25hbHMgdGhhdCBhIHZhbHVlIHdhcyBoYW5kbGVkIGJ5IGEgZGlyZWN0aXZlIGFuZFxuICogc2hvdWxkIG5vdCBiZSB3cml0dGVuIHRvIHRoZSBET00uXG4gKi9cbmV4cG9ydCBjb25zdCBub0NoYW5nZSA9IFN5bWJvbC5mb3IoJ2xpdC1ub0NoYW5nZScpO1xuXG4vKipcbiAqIEEgc2VudGluZWwgdmFsdWUgdGhhdCBzaWduYWxzIGEgQ2hpbGRQYXJ0IHRvIGZ1bGx5IGNsZWFyIGl0cyBjb250ZW50LlxuICpcbiAqIGBgYHRzXG4gKiBjb25zdCBidXR0b24gPSBodG1sYCR7XG4gKiAgdXNlci5pc0FkbWluXG4gKiAgICA/IGh0bWxgPGJ1dHRvbj5ERUxFVEU8L2J1dHRvbj5gXG4gKiAgICA6IG5vdGhpbmdcbiAqIH1gO1xuICogYGBgXG4gKlxuICogUHJlZmVyIHVzaW5nIGBub3RoaW5nYCBvdmVyIG90aGVyIGZhbHN5IHZhbHVlcyBhcyBpdCBwcm92aWRlcyBhIGNvbnNpc3RlbnRcbiAqIGJlaGF2aW9yIGJldHdlZW4gdmFyaW91cyBleHByZXNzaW9uIGJpbmRpbmcgY29udGV4dHMuXG4gKlxuICogSW4gY2hpbGQgZXhwcmVzc2lvbnMsIGB1bmRlZmluZWRgLCBgbnVsbGAsIGAnJ2AsIGFuZCBgbm90aGluZ2AgYWxsIGJlaGF2ZSB0aGVcbiAqIHNhbWUgYW5kIHJlbmRlciBubyBub2Rlcy4gSW4gYXR0cmlidXRlIGV4cHJlc3Npb25zLCBgbm90aGluZ2AgX3JlbW92ZXNfIHRoZVxuICogYXR0cmlidXRlLCB3aGlsZSBgdW5kZWZpbmVkYCBhbmQgYG51bGxgIHdpbGwgcmVuZGVyIGFuIGVtcHR5IHN0cmluZy4gSW5cbiAqIHByb3BlcnR5IGV4cHJlc3Npb25zIGBub3RoaW5nYCBiZWNvbWVzIGB1bmRlZmluZWRgLlxuICovXG5leHBvcnQgY29uc3Qgbm90aGluZyA9IFN5bWJvbC5mb3IoJ2xpdC1ub3RoaW5nJyk7XG5cbi8qKlxuICogVGhlIGNhY2hlIG9mIHByZXBhcmVkIHRlbXBsYXRlcywga2V5ZWQgYnkgdGhlIHRhZ2dlZCBUZW1wbGF0ZVN0cmluZ3NBcnJheVxuICogYW5kIF9ub3RfIGFjY291bnRpbmcgZm9yIHRoZSBzcGVjaWZpYyB0ZW1wbGF0ZSB0YWcgdXNlZC4gVGhpcyBtZWFucyB0aGF0XG4gKiB0ZW1wbGF0ZSB0YWdzIGNhbm5vdCBiZSBkeW5hbWljIC0gdGhleSBtdXN0IHN0YXRpY2FsbHkgYmUgb25lIG9mIGh0bWwsIHN2ZyxcbiAqIG9yIGF0dHIuIFRoaXMgcmVzdHJpY3Rpb24gc2ltcGxpZmllcyB0aGUgY2FjaGUgbG9va3VwLCB3aGljaCBpcyBvbiB0aGUgaG90XG4gKiBwYXRoIGZvciByZW5kZXJpbmcuXG4gKi9cbmNvbnN0IHRlbXBsYXRlQ2FjaGUgPSBuZXcgV2Vha01hcDxUZW1wbGF0ZVN0cmluZ3NBcnJheSwgVGVtcGxhdGU+KCk7XG5cbi8qKlxuICogT2JqZWN0IHNwZWNpZnlpbmcgb3B0aW9ucyBmb3IgY29udHJvbGxpbmcgbGl0LWh0bWwgcmVuZGVyaW5nLiBOb3RlIHRoYXRcbiAqIHdoaWxlIGByZW5kZXJgIG1heSBiZSBjYWxsZWQgbXVsdGlwbGUgdGltZXMgb24gdGhlIHNhbWUgYGNvbnRhaW5lcmAgKGFuZFxuICogYHJlbmRlckJlZm9yZWAgcmVmZXJlbmNlIG5vZGUpIHRvIGVmZmljaWVudGx5IHVwZGF0ZSB0aGUgcmVuZGVyZWQgY29udGVudCxcbiAqIG9ubHkgdGhlIG9wdGlvbnMgcGFzc2VkIGluIGR1cmluZyB0aGUgZmlyc3QgcmVuZGVyIGFyZSByZXNwZWN0ZWQgZHVyaW5nXG4gKiB0aGUgbGlmZXRpbWUgb2YgcmVuZGVycyB0byB0aGF0IHVuaXF1ZSBgY29udGFpbmVyYCArIGByZW5kZXJCZWZvcmVgXG4gKiBjb21iaW5hdGlvbi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZW5kZXJPcHRpb25zIHtcbiAgLyoqXG4gICAqIEFuIG9iamVjdCB0byB1c2UgYXMgdGhlIGB0aGlzYCB2YWx1ZSBmb3IgZXZlbnQgbGlzdGVuZXJzLiBJdCdzIG9mdGVuXG4gICAqIHVzZWZ1bCB0byBzZXQgdGhpcyB0byB0aGUgaG9zdCBjb21wb25lbnQgcmVuZGVyaW5nIGEgdGVtcGxhdGUuXG4gICAqL1xuICBob3N0Pzogb2JqZWN0O1xuICAvKipcbiAgICogQSBET00gbm9kZSBiZWZvcmUgd2hpY2ggdG8gcmVuZGVyIGNvbnRlbnQgaW4gdGhlIGNvbnRhaW5lci5cbiAgICovXG4gIHJlbmRlckJlZm9yZT86IENoaWxkTm9kZSB8IG51bGw7XG4gIC8qKlxuICAgKiBOb2RlIHVzZWQgZm9yIGNsb25pbmcgdGhlIHRlbXBsYXRlIChgaW1wb3J0Tm9kZWAgd2lsbCBiZSBjYWxsZWQgb24gdGhpc1xuICAgKiBub2RlKS4gVGhpcyBjb250cm9scyB0aGUgYG93bmVyRG9jdW1lbnRgIG9mIHRoZSByZW5kZXJlZCBET00sIGFsb25nIHdpdGhcbiAgICogYW55IGluaGVyaXRlZCBjb250ZXh0LiBEZWZhdWx0cyB0byB0aGUgZ2xvYmFsIGBkb2N1bWVudGAuXG4gICAqL1xuICBjcmVhdGlvblNjb3BlPzoge2ltcG9ydE5vZGUobm9kZTogTm9kZSwgZGVlcD86IGJvb2xlYW4pOiBOb2RlfTtcbiAgLyoqXG4gICAqIFRoZSBpbml0aWFsIGNvbm5lY3RlZCBzdGF0ZSBmb3IgdGhlIHRvcC1sZXZlbCBwYXJ0IGJlaW5nIHJlbmRlcmVkLiBJZiBub1xuICAgKiBgaXNDb25uZWN0ZWRgIG9wdGlvbiBpcyBzZXQsIGBBc3luY0RpcmVjdGl2ZWBzIHdpbGwgYmUgY29ubmVjdGVkIGJ5XG4gICAqIGRlZmF1bHQuIFNldCB0byBgZmFsc2VgIGlmIHRoZSBpbml0aWFsIHJlbmRlciBvY2N1cnMgaW4gYSBkaXNjb25uZWN0ZWQgdHJlZVxuICAgKiBhbmQgYEFzeW5jRGlyZWN0aXZlYHMgc2hvdWxkIHNlZSBgaXNDb25uZWN0ZWQgPT09IGZhbHNlYCBmb3IgdGhlaXIgaW5pdGlhbFxuICAgKiByZW5kZXIuIFRoZSBgcGFydC5zZXRDb25uZWN0ZWQoKWAgbWV0aG9kIG11c3QgYmUgdXNlZCBzdWJzZXF1ZW50IHRvIGluaXRpYWxcbiAgICogcmVuZGVyIHRvIGNoYW5nZSB0aGUgY29ubmVjdGVkIHN0YXRlIG9mIHRoZSBwYXJ0LlxuICAgKi9cbiAgaXNDb25uZWN0ZWQ/OiBib29sZWFuO1xufVxuXG5jb25zdCB3YWxrZXIgPSBkLmNyZWF0ZVRyZWVXYWxrZXIoXG4gIGQsXG4gIDEyOSAvKiBOb2RlRmlsdGVyLlNIT1dfe0VMRU1FTlR8Q09NTUVOVH0gKi9cbik7XG5cbmxldCBzYW5pdGl6ZXJGYWN0b3J5SW50ZXJuYWw6IFNhbml0aXplckZhY3RvcnkgPSBub29wU2FuaXRpemVyO1xuXG4vL1xuLy8gQ2xhc3NlcyBvbmx5IGJlbG93IGhlcmUsIGNvbnN0IHZhcmlhYmxlIGRlY2xhcmF0aW9ucyBvbmx5IGFib3ZlIGhlcmUuLi5cbi8vXG4vLyBLZWVwaW5nIHZhcmlhYmxlIGRlY2xhcmF0aW9ucyBhbmQgY2xhc3NlcyB0b2dldGhlciBpbXByb3ZlcyBtaW5pZmljYXRpb24uXG4vLyBJbnRlcmZhY2VzIGFuZCB0eXBlIGFsaWFzZXMgY2FuIGJlIGludGVybGVhdmVkIGZyZWVseS5cbi8vXG5cbi8vIFR5cGUgZm9yIGNsYXNzZXMgdGhhdCBoYXZlIGEgYF9kaXJlY3RpdmVgIG9yIGBfZGlyZWN0aXZlc1tdYCBmaWVsZCwgdXNlZCBieVxuLy8gYHJlc29sdmVEaXJlY3RpdmVgXG5leHBvcnQgaW50ZXJmYWNlIERpcmVjdGl2ZVBhcmVudCB7XG4gIF8kcGFyZW50PzogRGlyZWN0aXZlUGFyZW50O1xuICBfJGlzQ29ubmVjdGVkOiBib29sZWFuO1xuICBfX2RpcmVjdGl2ZT86IERpcmVjdGl2ZTtcbiAgX19kaXJlY3RpdmVzPzogQXJyYXk8RGlyZWN0aXZlIHwgdW5kZWZpbmVkPjtcbn1cblxuZnVuY3Rpb24gdHJ1c3RGcm9tVGVtcGxhdGVTdHJpbmcoXG4gIHRzYTogVGVtcGxhdGVTdHJpbmdzQXJyYXksXG4gIHN0cmluZ0Zyb21UU0E6IHN0cmluZ1xuKTogVHJ1c3RlZEhUTUwge1xuICAvLyBBIHNlY3VyaXR5IGNoZWNrIHRvIHByZXZlbnQgc3Bvb2Zpbmcgb2YgTGl0IHRlbXBsYXRlIHJlc3VsdHMuXG4gIC8vIEluIHRoZSBmdXR1cmUsIHdlIG1heSBiZSBhYmxlIHRvIHJlcGxhY2UgdGhpcyB3aXRoIEFycmF5LmlzVGVtcGxhdGVPYmplY3QsXG4gIC8vIHRob3VnaCB3ZSBtaWdodCBuZWVkIHRvIG1ha2UgdGhhdCBjaGVjayBpbnNpZGUgb2YgdGhlIGh0bWwgYW5kIHN2Z1xuICAvLyBmdW5jdGlvbnMsIGJlY2F1c2UgcHJlY29tcGlsZWQgdGVtcGxhdGVzIGRvbid0IGNvbWUgaW4gYXNcbiAgLy8gVGVtcGxhdGVTdHJpbmdBcnJheSBvYmplY3RzLlxuICBpZiAoIWlzQXJyYXkodHNhKSB8fCAhdHNhLmhhc093blByb3BlcnR5KCdyYXcnKSkge1xuICAgIGxldCBtZXNzYWdlID0gJ2ludmFsaWQgdGVtcGxhdGUgc3RyaW5ncyBhcnJheSc7XG4gICAgaWYgKERFVl9NT0RFKSB7XG4gICAgICBtZXNzYWdlID0gYFxuICAgICAgICAgIEludGVybmFsIEVycm9yOiBleHBlY3RlZCB0ZW1wbGF0ZSBzdHJpbmdzIHRvIGJlIGFuIGFycmF5XG4gICAgICAgICAgd2l0aCBhICdyYXcnIGZpZWxkLiBGYWtpbmcgYSB0ZW1wbGF0ZSBzdHJpbmdzIGFycmF5IGJ5XG4gICAgICAgICAgY2FsbGluZyBodG1sIG9yIHN2ZyBsaWtlIGFuIG9yZGluYXJ5IGZ1bmN0aW9uIGlzIGVmZmVjdGl2ZWx5XG4gICAgICAgICAgdGhlIHNhbWUgYXMgY2FsbGluZyB1bnNhZmVIdG1sIGFuZCBjYW4gbGVhZCB0byBtYWpvciBzZWN1cml0eVxuICAgICAgICAgIGlzc3VlcywgZS5nLiBvcGVuaW5nIHlvdXIgY29kZSB1cCB0byBYU1MgYXR0YWNrcy5cbiAgICAgICAgICBJZiB5b3UncmUgdXNpbmcgdGhlIGh0bWwgb3Igc3ZnIHRhZ2dlZCB0ZW1wbGF0ZSBmdW5jdGlvbnMgbm9ybWFsbHlcbiAgICAgICAgICBhbmQgc3RpbGwgc2VlaW5nIHRoaXMgZXJyb3IsIHBsZWFzZSBmaWxlIGEgYnVnIGF0XG4gICAgICAgICAgaHR0cHM6Ly9naXRodWIuY29tL2xpdC9saXQvaXNzdWVzL25ldz90ZW1wbGF0ZT1idWdfcmVwb3J0Lm1kXG4gICAgICAgICAgYW5kIGluY2x1ZGUgaW5mb3JtYXRpb24gYWJvdXQgeW91ciBidWlsZCB0b29saW5nLCBpZiBhbnkuXG4gICAgICAgIGBcbiAgICAgICAgLnRyaW0oKVxuICAgICAgICAucmVwbGFjZSgvXFxuICovZywgJ1xcbicpO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSk7XG4gIH1cbiAgcmV0dXJuIHBvbGljeSAhPT0gdW5kZWZpbmVkXG4gICAgPyBwb2xpY3kuY3JlYXRlSFRNTChzdHJpbmdGcm9tVFNBKVxuICAgIDogKHN0cmluZ0Zyb21UU0EgYXMgdW5rbm93biBhcyBUcnVzdGVkSFRNTCk7XG59XG5cbi8qKlxuICogUmV0dXJucyBhbiBIVE1MIHN0cmluZyBmb3IgdGhlIGdpdmVuIFRlbXBsYXRlU3RyaW5nc0FycmF5IGFuZCByZXN1bHQgdHlwZVxuICogKEhUTUwgb3IgU1ZHKSwgYWxvbmcgd2l0aCB0aGUgY2FzZS1zZW5zaXRpdmUgYm91bmQgYXR0cmlidXRlIG5hbWVzIGluXG4gKiB0ZW1wbGF0ZSBvcmRlci4gVGhlIEhUTUwgY29udGFpbnMgY29tbWVudCBtYXJrZXJzIGRlbm90aW5nIHRoZSBgQ2hpbGRQYXJ0YHNcbiAqIGFuZCBzdWZmaXhlcyBvbiBib3VuZCBhdHRyaWJ1dGVzIGRlbm90aW5nIHRoZSBgQXR0cmlidXRlUGFydHNgLlxuICpcbiAqIEBwYXJhbSBzdHJpbmdzIHRlbXBsYXRlIHN0cmluZ3MgYXJyYXlcbiAqIEBwYXJhbSB0eXBlIEhUTUwgb3IgU1ZHXG4gKiBAcmV0dXJuIEFycmF5IGNvbnRhaW5pbmcgYFtodG1sLCBhdHRyTmFtZXNdYCAoYXJyYXkgcmV0dXJuZWQgZm9yIHRlcnNlbmVzcyxcbiAqICAgICB0byBhdm9pZCBvYmplY3QgZmllbGRzIHNpbmNlIHRoaXMgY29kZSBpcyBzaGFyZWQgd2l0aCBub24tbWluaWZpZWQgU1NSXG4gKiAgICAgY29kZSlcbiAqL1xuY29uc3QgZ2V0VGVtcGxhdGVIdG1sID0gKFxuICBzdHJpbmdzOiBUZW1wbGF0ZVN0cmluZ3NBcnJheSxcbiAgdHlwZTogUmVzdWx0VHlwZVxuKTogW1RydXN0ZWRIVE1MLCBBcnJheTxzdHJpbmc+XSA9PiB7XG4gIC8vIEluc2VydCBtYWtlcnMgaW50byB0aGUgdGVtcGxhdGUgSFRNTCB0byByZXByZXNlbnQgdGhlIHBvc2l0aW9uIG9mXG4gIC8vIGJpbmRpbmdzLiBUaGUgZm9sbG93aW5nIGNvZGUgc2NhbnMgdGhlIHRlbXBsYXRlIHN0cmluZ3MgdG8gZGV0ZXJtaW5lIHRoZVxuICAvLyBzeW50YWN0aWMgcG9zaXRpb24gb2YgdGhlIGJpbmRpbmdzLiBUaGV5IGNhbiBiZSBpbiB0ZXh0IHBvc2l0aW9uLCB3aGVyZVxuICAvLyB3ZSBpbnNlcnQgYW4gSFRNTCBjb21tZW50LCBhdHRyaWJ1dGUgdmFsdWUgcG9zaXRpb24sIHdoZXJlIHdlIGluc2VydCBhXG4gIC8vIHNlbnRpbmVsIHN0cmluZyBhbmQgcmUtd3JpdGUgdGhlIGF0dHJpYnV0ZSBuYW1lLCBvciBpbnNpZGUgYSB0YWcgd2hlcmVcbiAgLy8gd2UgaW5zZXJ0IHRoZSBzZW50aW5lbCBzdHJpbmcuXG4gIGNvbnN0IGwgPSBzdHJpbmdzLmxlbmd0aCAtIDE7XG4gIC8vIFN0b3JlcyB0aGUgY2FzZS1zZW5zaXRpdmUgYm91bmQgYXR0cmlidXRlIG5hbWVzIGluIHRoZSBvcmRlciBvZiB0aGVpclxuICAvLyBwYXJ0cy4gRWxlbWVudFBhcnRzIGFyZSBhbHNvIHJlZmxlY3RlZCBpbiB0aGlzIGFycmF5IGFzIHVuZGVmaW5lZFxuICAvLyByYXRoZXIgdGhhbiBhIHN0cmluZywgdG8gZGlzYW1iaWd1YXRlIGZyb20gYXR0cmlidXRlIGJpbmRpbmdzLlxuICBjb25zdCBhdHRyTmFtZXM6IEFycmF5PHN0cmluZz4gPSBbXTtcbiAgbGV0IGh0bWwgPVxuICAgIHR5cGUgPT09IFNWR19SRVNVTFQgPyAnPHN2Zz4nIDogdHlwZSA9PT0gTUFUSE1MX1JFU1VMVCA/ICc8bWF0aD4nIDogJyc7XG5cbiAgLy8gV2hlbiB3ZSdyZSBpbnNpZGUgYSByYXcgdGV4dCB0YWcgKG5vdCBpdCdzIHRleHQgY29udGVudCksIHRoZSByZWdleFxuICAvLyB3aWxsIHN0aWxsIGJlIHRhZ1JlZ2V4IHNvIHdlIGNhbiBmaW5kIGF0dHJpYnV0ZXMsIGJ1dCB3aWxsIHN3aXRjaCB0b1xuICAvLyB0aGlzIHJlZ2V4IHdoZW4gdGhlIHRhZyBlbmRzLlxuICBsZXQgcmF3VGV4dEVuZFJlZ2V4OiBSZWdFeHAgfCB1bmRlZmluZWQ7XG5cbiAgLy8gVGhlIGN1cnJlbnQgcGFyc2luZyBzdGF0ZSwgcmVwcmVzZW50ZWQgYXMgYSByZWZlcmVuY2UgdG8gb25lIG9mIHRoZVxuICAvLyByZWdleGVzXG4gIGxldCByZWdleCA9IHRleHRFbmRSZWdleDtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGw7IGkrKykge1xuICAgIGNvbnN0IHMgPSBzdHJpbmdzW2ldO1xuICAgIC8vIFRoZSBpbmRleCBvZiB0aGUgZW5kIG9mIHRoZSBsYXN0IGF0dHJpYnV0ZSBuYW1lLiBXaGVuIHRoaXMgaXNcbiAgICAvLyBwb3NpdGl2ZSBhdCBlbmQgb2YgYSBzdHJpbmcsIGl0IG1lYW5zIHdlJ3JlIGluIGFuIGF0dHJpYnV0ZSB2YWx1ZVxuICAgIC8vIHBvc2l0aW9uIGFuZCBuZWVkIHRvIHJld3JpdGUgdGhlIGF0dHJpYnV0ZSBuYW1lLlxuICAgIC8vIFdlIGFsc28gdXNlIGEgc3BlY2lhbCB2YWx1ZSBvZiAtMiB0byBpbmRpY2F0ZSB0aGF0IHdlIGVuY291bnRlcmVkXG4gICAgLy8gdGhlIGVuZCBvZiBhIHN0cmluZyBpbiBhdHRyaWJ1dGUgbmFtZSBwb3NpdGlvbi5cbiAgICBsZXQgYXR0ck5hbWVFbmRJbmRleCA9IC0xO1xuICAgIGxldCBhdHRyTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIGxldCBsYXN0SW5kZXggPSAwO1xuICAgIGxldCBtYXRjaCE6IFJlZ0V4cEV4ZWNBcnJheSB8IG51bGw7XG5cbiAgICAvLyBUaGUgY29uZGl0aW9ucyBpbiB0aGlzIGxvb3AgaGFuZGxlIHRoZSBjdXJyZW50IHBhcnNlIHN0YXRlLCBhbmQgdGhlXG4gICAgLy8gYXNzaWdubWVudHMgdG8gdGhlIGByZWdleGAgdmFyaWFibGUgYXJlIHRoZSBzdGF0ZSB0cmFuc2l0aW9ucy5cbiAgICB3aGlsZSAobGFzdEluZGV4IDwgcy5sZW5ndGgpIHtcbiAgICAgIC8vIE1ha2Ugc3VyZSB3ZSBzdGFydCBzZWFyY2hpbmcgZnJvbSB3aGVyZSB3ZSBwcmV2aW91c2x5IGxlZnQgb2ZmXG4gICAgICByZWdleC5sYXN0SW5kZXggPSBsYXN0SW5kZXg7XG4gICAgICBtYXRjaCA9IHJlZ2V4LmV4ZWMocyk7XG4gICAgICBpZiAobWF0Y2ggPT09IG51bGwpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBsYXN0SW5kZXggPSByZWdleC5sYXN0SW5kZXg7XG4gICAgICBpZiAocmVnZXggPT09IHRleHRFbmRSZWdleCkge1xuICAgICAgICBpZiAobWF0Y2hbQ09NTUVOVF9TVEFSVF0gPT09ICchLS0nKSB7XG4gICAgICAgICAgcmVnZXggPSBjb21tZW50RW5kUmVnZXg7XG4gICAgICAgIH0gZWxzZSBpZiAobWF0Y2hbQ09NTUVOVF9TVEFSVF0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIC8vIFdlIHN0YXJ0ZWQgYSB3ZWlyZCBjb21tZW50LCBsaWtlIDwve1xuICAgICAgICAgIHJlZ2V4ID0gY29tbWVudDJFbmRSZWdleDtcbiAgICAgICAgfSBlbHNlIGlmIChtYXRjaFtUQUdfTkFNRV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGlmIChyYXdUZXh0RWxlbWVudC50ZXN0KG1hdGNoW1RBR19OQU1FXSkpIHtcbiAgICAgICAgICAgIC8vIFJlY29yZCBpZiB3ZSBlbmNvdW50ZXIgYSByYXctdGV4dCBlbGVtZW50LiBXZSdsbCBzd2l0Y2ggdG9cbiAgICAgICAgICAgIC8vIHRoaXMgcmVnZXggYXQgdGhlIGVuZCBvZiB0aGUgdGFnLlxuICAgICAgICAgICAgcmF3VGV4dEVuZFJlZ2V4ID0gbmV3IFJlZ0V4cChgPC8ke21hdGNoW1RBR19OQU1FXX1gLCAnZycpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZWdleCA9IHRhZ0VuZFJlZ2V4O1xuICAgICAgICB9IGVsc2UgaWYgKG1hdGNoW0RZTkFNSUNfVEFHX05BTUVdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBpZiAoREVWX01PREUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgJ0JpbmRpbmdzIGluIHRhZyBuYW1lcyBhcmUgbm90IHN1cHBvcnRlZC4gUGxlYXNlIHVzZSBzdGF0aWMgdGVtcGxhdGVzIGluc3RlYWQuICcgK1xuICAgICAgICAgICAgICAgICdTZWUgaHR0cHM6Ly9saXQuZGV2L2RvY3MvdGVtcGxhdGVzL2V4cHJlc3Npb25zLyNzdGF0aWMtZXhwcmVzc2lvbnMnXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZWdleCA9IHRhZ0VuZFJlZ2V4O1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHJlZ2V4ID09PSB0YWdFbmRSZWdleCkge1xuICAgICAgICBpZiAobWF0Y2hbRU5USVJFX01BVENIXSA9PT0gJz4nKSB7XG4gICAgICAgICAgLy8gRW5kIG9mIGEgdGFnLiBJZiB3ZSBoYWQgc3RhcnRlZCBhIHJhdy10ZXh0IGVsZW1lbnQsIHVzZSB0aGF0XG4gICAgICAgICAgLy8gcmVnZXhcbiAgICAgICAgICByZWdleCA9IHJhd1RleHRFbmRSZWdleCA/PyB0ZXh0RW5kUmVnZXg7XG4gICAgICAgICAgLy8gV2UgbWF5IGJlIGVuZGluZyBhbiB1bnF1b3RlZCBhdHRyaWJ1dGUgdmFsdWUsIHNvIG1ha2Ugc3VyZSB3ZVxuICAgICAgICAgIC8vIGNsZWFyIGFueSBwZW5kaW5nIGF0dHJOYW1lRW5kSW5kZXhcbiAgICAgICAgICBhdHRyTmFtZUVuZEluZGV4ID0gLTE7XG4gICAgICAgIH0gZWxzZSBpZiAobWF0Y2hbQVRUUklCVVRFX05BTUVdID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAvLyBBdHRyaWJ1dGUgbmFtZSBwb3NpdGlvblxuICAgICAgICAgIGF0dHJOYW1lRW5kSW5kZXggPSAtMjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhdHRyTmFtZUVuZEluZGV4ID0gcmVnZXgubGFzdEluZGV4IC0gbWF0Y2hbU1BBQ0VTX0FORF9FUVVBTFNdLmxlbmd0aDtcbiAgICAgICAgICBhdHRyTmFtZSA9IG1hdGNoW0FUVFJJQlVURV9OQU1FXTtcbiAgICAgICAgICByZWdleCA9XG4gICAgICAgICAgICBtYXRjaFtRVU9URV9DSEFSXSA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgID8gdGFnRW5kUmVnZXhcbiAgICAgICAgICAgICAgOiBtYXRjaFtRVU9URV9DSEFSXSA9PT0gJ1wiJ1xuICAgICAgICAgICAgICAgID8gZG91YmxlUXVvdGVBdHRyRW5kUmVnZXhcbiAgICAgICAgICAgICAgICA6IHNpbmdsZVF1b3RlQXR0ckVuZFJlZ2V4O1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICByZWdleCA9PT0gZG91YmxlUXVvdGVBdHRyRW5kUmVnZXggfHxcbiAgICAgICAgcmVnZXggPT09IHNpbmdsZVF1b3RlQXR0ckVuZFJlZ2V4XG4gICAgICApIHtcbiAgICAgICAgcmVnZXggPSB0YWdFbmRSZWdleDtcbiAgICAgIH0gZWxzZSBpZiAocmVnZXggPT09IGNvbW1lbnRFbmRSZWdleCB8fCByZWdleCA9PT0gY29tbWVudDJFbmRSZWdleCkge1xuICAgICAgICByZWdleCA9IHRleHRFbmRSZWdleDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIE5vdCBvbmUgb2YgdGhlIGZpdmUgc3RhdGUgcmVnZXhlcywgc28gaXQgbXVzdCBiZSB0aGUgZHluYW1pY2FsbHlcbiAgICAgICAgLy8gY3JlYXRlZCByYXcgdGV4dCByZWdleCBhbmQgd2UncmUgYXQgdGhlIGNsb3NlIG9mIHRoYXQgZWxlbWVudC5cbiAgICAgICAgcmVnZXggPSB0YWdFbmRSZWdleDtcbiAgICAgICAgcmF3VGV4dEVuZFJlZ2V4ID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChERVZfTU9ERSkge1xuICAgICAgLy8gSWYgd2UgaGF2ZSBhIGF0dHJOYW1lRW5kSW5kZXgsIHdoaWNoIGluZGljYXRlcyB0aGF0IHdlIHNob3VsZFxuICAgICAgLy8gcmV3cml0ZSB0aGUgYXR0cmlidXRlIG5hbWUsIGFzc2VydCB0aGF0IHdlJ3JlIGluIGEgdmFsaWQgYXR0cmlidXRlXG4gICAgICAvLyBwb3NpdGlvbiAtIGVpdGhlciBpbiBhIHRhZywgb3IgYSBxdW90ZWQgYXR0cmlidXRlIHZhbHVlLlxuICAgICAgY29uc29sZS5hc3NlcnQoXG4gICAgICAgIGF0dHJOYW1lRW5kSW5kZXggPT09IC0xIHx8XG4gICAgICAgICAgcmVnZXggPT09IHRhZ0VuZFJlZ2V4IHx8XG4gICAgICAgICAgcmVnZXggPT09IHNpbmdsZVF1b3RlQXR0ckVuZFJlZ2V4IHx8XG4gICAgICAgICAgcmVnZXggPT09IGRvdWJsZVF1b3RlQXR0ckVuZFJlZ2V4LFxuICAgICAgICAndW5leHBlY3RlZCBwYXJzZSBzdGF0ZSBCJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBXZSBoYXZlIGZvdXIgY2FzZXM6XG4gICAgLy8gIDEuIFdlJ3JlIGluIHRleHQgcG9zaXRpb24sIGFuZCBub3QgaW4gYSByYXcgdGV4dCBlbGVtZW50XG4gICAgLy8gICAgIChyZWdleCA9PT0gdGV4dEVuZFJlZ2V4KTogaW5zZXJ0IGEgY29tbWVudCBtYXJrZXIuXG4gICAgLy8gIDIuIFdlIGhhdmUgYSBub24tbmVnYXRpdmUgYXR0ck5hbWVFbmRJbmRleCB3aGljaCBtZWFucyB3ZSBuZWVkIHRvXG4gICAgLy8gICAgIHJld3JpdGUgdGhlIGF0dHJpYnV0ZSBuYW1lIHRvIGFkZCBhIGJvdW5kIGF0dHJpYnV0ZSBzdWZmaXguXG4gICAgLy8gIDMuIFdlJ3JlIGF0IHRoZSBub24tZmlyc3QgYmluZGluZyBpbiBhIG11bHRpLWJpbmRpbmcgYXR0cmlidXRlLCB1c2UgYVxuICAgIC8vICAgICBwbGFpbiBtYXJrZXIuXG4gICAgLy8gIDQuIFdlJ3JlIHNvbWV3aGVyZSBlbHNlIGluc2lkZSB0aGUgdGFnLiBJZiB3ZSdyZSBpbiBhdHRyaWJ1dGUgbmFtZVxuICAgIC8vICAgICBwb3NpdGlvbiAoYXR0ck5hbWVFbmRJbmRleCA9PT0gLTIpLCBhZGQgYSBzZXF1ZW50aWFsIHN1ZmZpeCB0b1xuICAgIC8vICAgICBnZW5lcmF0ZSBhIHVuaXF1ZSBhdHRyaWJ1dGUgbmFtZS5cblxuICAgIC8vIERldGVjdCBhIGJpbmRpbmcgbmV4dCB0byBzZWxmLWNsb3NpbmcgdGFnIGVuZCBhbmQgaW5zZXJ0IGEgc3BhY2UgdG9cbiAgICAvLyBzZXBhcmF0ZSB0aGUgbWFya2VyIGZyb20gdGhlIHRhZyBlbmQ6XG4gICAgY29uc3QgZW5kID1cbiAgICAgIHJlZ2V4ID09PSB0YWdFbmRSZWdleCAmJiBzdHJpbmdzW2kgKyAxXS5zdGFydHNXaXRoKCcvPicpID8gJyAnIDogJyc7XG4gICAgaHRtbCArPVxuICAgICAgcmVnZXggPT09IHRleHRFbmRSZWdleFxuICAgICAgICA/IHMgKyBub2RlTWFya2VyXG4gICAgICAgIDogYXR0ck5hbWVFbmRJbmRleCA+PSAwXG4gICAgICAgICAgPyAoYXR0ck5hbWVzLnB1c2goYXR0ck5hbWUhKSxcbiAgICAgICAgICAgIHMuc2xpY2UoMCwgYXR0ck5hbWVFbmRJbmRleCkgK1xuICAgICAgICAgICAgICBib3VuZEF0dHJpYnV0ZVN1ZmZpeCArXG4gICAgICAgICAgICAgIHMuc2xpY2UoYXR0ck5hbWVFbmRJbmRleCkpICtcbiAgICAgICAgICAgIG1hcmtlciArXG4gICAgICAgICAgICBlbmRcbiAgICAgICAgICA6IHMgKyBtYXJrZXIgKyAoYXR0ck5hbWVFbmRJbmRleCA9PT0gLTIgPyBpIDogZW5kKTtcbiAgfVxuXG4gIGNvbnN0IGh0bWxSZXN1bHQ6IHN0cmluZyB8IFRydXN0ZWRIVE1MID1cbiAgICBodG1sICtcbiAgICAoc3RyaW5nc1tsXSB8fCAnPD8+JykgK1xuICAgICh0eXBlID09PSBTVkdfUkVTVUxUID8gJzwvc3ZnPicgOiB0eXBlID09PSBNQVRITUxfUkVTVUxUID8gJzwvbWF0aD4nIDogJycpO1xuXG4gIC8vIFJldHVybmVkIGFzIGFuIGFycmF5IGZvciB0ZXJzZW5lc3NcbiAgcmV0dXJuIFt0cnVzdEZyb21UZW1wbGF0ZVN0cmluZyhzdHJpbmdzLCBodG1sUmVzdWx0KSwgYXR0ck5hbWVzXTtcbn07XG5cbi8qKiBAaW50ZXJuYWwgKi9cbmV4cG9ydCB0eXBlIHtUZW1wbGF0ZX07XG5jbGFzcyBUZW1wbGF0ZSB7XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgZWwhOiBIVE1MVGVtcGxhdGVFbGVtZW50O1xuXG4gIHBhcnRzOiBBcnJheTxUZW1wbGF0ZVBhcnQ+ID0gW107XG5cbiAgY29uc3RydWN0b3IoXG4gICAgLy8gVGhpcyBwcm9wZXJ0eSBuZWVkcyB0byByZW1haW4gdW5taW5pZmllZC5cbiAgICB7c3RyaW5ncywgWydfJGxpdFR5cGUkJ106IHR5cGV9OiBVbmNvbXBpbGVkVGVtcGxhdGVSZXN1bHQsXG4gICAgb3B0aW9ucz86IFJlbmRlck9wdGlvbnNcbiAgKSB7XG4gICAgbGV0IG5vZGU6IE5vZGUgfCBudWxsO1xuICAgIGxldCBub2RlSW5kZXggPSAwO1xuICAgIGxldCBhdHRyTmFtZUluZGV4ID0gMDtcbiAgICBjb25zdCBwYXJ0Q291bnQgPSBzdHJpbmdzLmxlbmd0aCAtIDE7XG4gICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzO1xuXG4gICAgLy8gQ3JlYXRlIHRlbXBsYXRlIGVsZW1lbnRcbiAgICBjb25zdCBbaHRtbCwgYXR0ck5hbWVzXSA9IGdldFRlbXBsYXRlSHRtbChzdHJpbmdzLCB0eXBlKTtcbiAgICB0aGlzLmVsID0gVGVtcGxhdGUuY3JlYXRlRWxlbWVudChodG1sLCBvcHRpb25zKTtcbiAgICB3YWxrZXIuY3VycmVudE5vZGUgPSB0aGlzLmVsLmNvbnRlbnQ7XG5cbiAgICAvLyBSZS1wYXJlbnQgU1ZHIG9yIE1hdGhNTCBub2RlcyBpbnRvIHRlbXBsYXRlIHJvb3RcbiAgICBpZiAodHlwZSA9PT0gU1ZHX1JFU1VMVCB8fCB0eXBlID09PSBNQVRITUxfUkVTVUxUKSB7XG4gICAgICBjb25zdCB3cmFwcGVyID0gdGhpcy5lbC5jb250ZW50LmZpcnN0Q2hpbGQhO1xuICAgICAgd3JhcHBlci5yZXBsYWNlV2l0aCguLi53cmFwcGVyLmNoaWxkTm9kZXMpO1xuICAgIH1cblxuICAgIC8vIFdhbGsgdGhlIHRlbXBsYXRlIHRvIGZpbmQgYmluZGluZyBtYXJrZXJzIGFuZCBjcmVhdGUgVGVtcGxhdGVQYXJ0c1xuICAgIHdoaWxlICgobm9kZSA9IHdhbGtlci5uZXh0Tm9kZSgpKSAhPT0gbnVsbCAmJiBwYXJ0cy5sZW5ndGggPCBwYXJ0Q291bnQpIHtcbiAgICAgIGlmIChub2RlLm5vZGVUeXBlID09PSAxKSB7XG4gICAgICAgIGlmIChERVZfTU9ERSkge1xuICAgICAgICAgIGNvbnN0IHRhZyA9IChub2RlIGFzIEVsZW1lbnQpLmxvY2FsTmFtZTtcbiAgICAgICAgICAvLyBXYXJuIGlmIGB0ZXh0YXJlYWAgaW5jbHVkZXMgYW4gZXhwcmVzc2lvbiBhbmQgdGhyb3cgaWYgYHRlbXBsYXRlYFxuICAgICAgICAgIC8vIGRvZXMgc2luY2UgdGhlc2UgYXJlIG5vdCBzdXBwb3J0ZWQuIFdlIGRvIHRoaXMgYnkgY2hlY2tpbmdcbiAgICAgICAgICAvLyBpbm5lckhUTUwgZm9yIGFueXRoaW5nIHRoYXQgbG9va3MgbGlrZSBhIG1hcmtlci4gVGhpcyBjYXRjaGVzXG4gICAgICAgICAgLy8gY2FzZXMgbGlrZSBiaW5kaW5ncyBpbiB0ZXh0YXJlYSB0aGVyZSBtYXJrZXJzIHR1cm4gaW50byB0ZXh0IG5vZGVzLlxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIC9eKD86dGV4dGFyZWF8dGVtcGxhdGUpJC9pIS50ZXN0KHRhZykgJiZcbiAgICAgICAgICAgIChub2RlIGFzIEVsZW1lbnQpLmlubmVySFRNTC5pbmNsdWRlcyhtYXJrZXIpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBjb25zdCBtID1cbiAgICAgICAgICAgICAgYEV4cHJlc3Npb25zIGFyZSBub3Qgc3VwcG9ydGVkIGluc2lkZSBcXGAke3RhZ31cXGAgYCArXG4gICAgICAgICAgICAgIGBlbGVtZW50cy4gU2VlIGh0dHBzOi8vbGl0LmRldi9tc2cvZXhwcmVzc2lvbi1pbi0ke3RhZ30gZm9yIG1vcmUgYCArXG4gICAgICAgICAgICAgIGBpbmZvcm1hdGlvbi5gO1xuICAgICAgICAgICAgaWYgKHRhZyA9PT0gJ3RlbXBsYXRlJykge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IobSk7XG4gICAgICAgICAgICB9IGVsc2UgaXNzdWVXYXJuaW5nKCcnLCBtKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gVE9ETyAoanVzdGluZmFnbmFuaSk6IGZvciBhdHRlbXB0ZWQgZHluYW1pYyB0YWcgbmFtZXMsIHdlIGRvbid0XG4gICAgICAgIC8vIGluY3JlbWVudCB0aGUgYmluZGluZ0luZGV4LCBhbmQgaXQnbGwgYmUgb2ZmIGJ5IDEgaW4gdGhlIGVsZW1lbnRcbiAgICAgICAgLy8gYW5kIG9mZiBieSB0d28gYWZ0ZXIgaXQuXG4gICAgICAgIGlmICgobm9kZSBhcyBFbGVtZW50KS5oYXNBdHRyaWJ1dGVzKCkpIHtcbiAgICAgICAgICBmb3IgKGNvbnN0IG5hbWUgb2YgKG5vZGUgYXMgRWxlbWVudCkuZ2V0QXR0cmlidXRlTmFtZXMoKSkge1xuICAgICAgICAgICAgaWYgKG5hbWUuZW5kc1dpdGgoYm91bmRBdHRyaWJ1dGVTdWZmaXgpKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHJlYWxOYW1lID0gYXR0ck5hbWVzW2F0dHJOYW1lSW5kZXgrK107XG4gICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gKG5vZGUgYXMgRWxlbWVudCkuZ2V0QXR0cmlidXRlKG5hbWUpITtcbiAgICAgICAgICAgICAgY29uc3Qgc3RhdGljcyA9IHZhbHVlLnNwbGl0KG1hcmtlcik7XG4gICAgICAgICAgICAgIGNvbnN0IG0gPSAvKFsuP0BdKT8oLiopLy5leGVjKHJlYWxOYW1lKSE7XG4gICAgICAgICAgICAgIHBhcnRzLnB1c2goe1xuICAgICAgICAgICAgICAgIHR5cGU6IEFUVFJJQlVURV9QQVJULFxuICAgICAgICAgICAgICAgIGluZGV4OiBub2RlSW5kZXgsXG4gICAgICAgICAgICAgICAgbmFtZTogbVsyXSxcbiAgICAgICAgICAgICAgICBzdHJpbmdzOiBzdGF0aWNzLFxuICAgICAgICAgICAgICAgIGN0b3I6XG4gICAgICAgICAgICAgICAgICBtWzFdID09PSAnLidcbiAgICAgICAgICAgICAgICAgICAgPyBQcm9wZXJ0eVBhcnRcbiAgICAgICAgICAgICAgICAgICAgOiBtWzFdID09PSAnPydcbiAgICAgICAgICAgICAgICAgICAgICA/IEJvb2xlYW5BdHRyaWJ1dGVQYXJ0XG4gICAgICAgICAgICAgICAgICAgICAgOiBtWzFdID09PSAnQCdcbiAgICAgICAgICAgICAgICAgICAgICAgID8gRXZlbnRQYXJ0XG4gICAgICAgICAgICAgICAgICAgICAgICA6IEF0dHJpYnV0ZVBhcnQsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAobm9kZSBhcyBFbGVtZW50KS5yZW1vdmVBdHRyaWJ1dGUobmFtZSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKG5hbWUuc3RhcnRzV2l0aChtYXJrZXIpKSB7XG4gICAgICAgICAgICAgIHBhcnRzLnB1c2goe1xuICAgICAgICAgICAgICAgIHR5cGU6IEVMRU1FTlRfUEFSVCxcbiAgICAgICAgICAgICAgICBpbmRleDogbm9kZUluZGV4LFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgKG5vZGUgYXMgRWxlbWVudCkucmVtb3ZlQXR0cmlidXRlKG5hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBUT0RPIChqdXN0aW5mYWduYW5pKTogYmVuY2htYXJrIHRoZSByZWdleCBhZ2FpbnN0IHRlc3RpbmcgZm9yIGVhY2hcbiAgICAgICAgLy8gb2YgdGhlIDMgcmF3IHRleHQgZWxlbWVudCBuYW1lcy5cbiAgICAgICAgaWYgKHJhd1RleHRFbGVtZW50LnRlc3QoKG5vZGUgYXMgRWxlbWVudCkudGFnTmFtZSkpIHtcbiAgICAgICAgICAvLyBGb3IgcmF3IHRleHQgZWxlbWVudHMgd2UgbmVlZCB0byBzcGxpdCB0aGUgdGV4dCBjb250ZW50IG9uXG4gICAgICAgICAgLy8gbWFya2VycywgY3JlYXRlIGEgVGV4dCBub2RlIGZvciBlYWNoIHNlZ21lbnQsIGFuZCBjcmVhdGVcbiAgICAgICAgICAvLyBhIFRlbXBsYXRlUGFydCBmb3IgZWFjaCBtYXJrZXIuXG4gICAgICAgICAgY29uc3Qgc3RyaW5ncyA9IChub2RlIGFzIEVsZW1lbnQpLnRleHRDb250ZW50IS5zcGxpdChtYXJrZXIpO1xuICAgICAgICAgIGNvbnN0IGxhc3RJbmRleCA9IHN0cmluZ3MubGVuZ3RoIC0gMTtcbiAgICAgICAgICBpZiAobGFzdEluZGV4ID4gMCkge1xuICAgICAgICAgICAgKG5vZGUgYXMgRWxlbWVudCkudGV4dENvbnRlbnQgPSB0cnVzdGVkVHlwZXNcbiAgICAgICAgICAgICAgPyAodHJ1c3RlZFR5cGVzLmVtcHR5U2NyaXB0IGFzIHVua25vd24gYXMgJycpXG4gICAgICAgICAgICAgIDogJyc7XG4gICAgICAgICAgICAvLyBHZW5lcmF0ZSBhIG5ldyB0ZXh0IG5vZGUgZm9yIGVhY2ggbGl0ZXJhbCBzZWN0aW9uXG4gICAgICAgICAgICAvLyBUaGVzZSBub2RlcyBhcmUgYWxzbyB1c2VkIGFzIHRoZSBtYXJrZXJzIGZvciBjaGlsZCBwYXJ0c1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsYXN0SW5kZXg7IGkrKykge1xuICAgICAgICAgICAgICAobm9kZSBhcyBFbGVtZW50KS5hcHBlbmQoc3RyaW5nc1tpXSwgY3JlYXRlTWFya2VyKCkpO1xuICAgICAgICAgICAgICAvLyBXYWxrIHBhc3QgdGhlIG1hcmtlciBub2RlIHdlIGp1c3QgYWRkZWRcbiAgICAgICAgICAgICAgd2Fsa2VyLm5leHROb2RlKCk7XG4gICAgICAgICAgICAgIHBhcnRzLnB1c2goe3R5cGU6IENISUxEX1BBUlQsIGluZGV4OiArK25vZGVJbmRleH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gTm90ZSBiZWNhdXNlIHRoaXMgbWFya2VyIGlzIGFkZGVkIGFmdGVyIHRoZSB3YWxrZXIncyBjdXJyZW50XG4gICAgICAgICAgICAvLyBub2RlLCBpdCB3aWxsIGJlIHdhbGtlZCB0byBpbiB0aGUgb3V0ZXIgbG9vcCAoYW5kIGlnbm9yZWQpLCBzb1xuICAgICAgICAgICAgLy8gd2UgZG9uJ3QgbmVlZCB0byBhZGp1c3Qgbm9kZUluZGV4IGhlcmVcbiAgICAgICAgICAgIChub2RlIGFzIEVsZW1lbnQpLmFwcGVuZChzdHJpbmdzW2xhc3RJbmRleF0sIGNyZWF0ZU1hcmtlcigpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAobm9kZS5ub2RlVHlwZSA9PT0gOCkge1xuICAgICAgICBjb25zdCBkYXRhID0gKG5vZGUgYXMgQ29tbWVudCkuZGF0YTtcbiAgICAgICAgaWYgKGRhdGEgPT09IG1hcmtlck1hdGNoKSB7XG4gICAgICAgICAgcGFydHMucHVzaCh7dHlwZTogQ0hJTERfUEFSVCwgaW5kZXg6IG5vZGVJbmRleH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGxldCBpID0gLTE7XG4gICAgICAgICAgd2hpbGUgKChpID0gKG5vZGUgYXMgQ29tbWVudCkuZGF0YS5pbmRleE9mKG1hcmtlciwgaSArIDEpKSAhPT0gLTEpIHtcbiAgICAgICAgICAgIC8vIENvbW1lbnQgbm9kZSBoYXMgYSBiaW5kaW5nIG1hcmtlciBpbnNpZGUsIG1ha2UgYW4gaW5hY3RpdmUgcGFydFxuICAgICAgICAgICAgLy8gVGhlIGJpbmRpbmcgd29uJ3Qgd29yaywgYnV0IHN1YnNlcXVlbnQgYmluZGluZ3Mgd2lsbFxuICAgICAgICAgICAgcGFydHMucHVzaCh7dHlwZTogQ09NTUVOVF9QQVJULCBpbmRleDogbm9kZUluZGV4fSk7XG4gICAgICAgICAgICAvLyBNb3ZlIHRvIHRoZSBlbmQgb2YgdGhlIG1hdGNoXG4gICAgICAgICAgICBpICs9IG1hcmtlci5sZW5ndGggLSAxO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbm9kZUluZGV4Kys7XG4gICAgfVxuXG4gICAgaWYgKERFVl9NT0RFKSB7XG4gICAgICAvLyBJZiB0aGVyZSB3YXMgYSBkdXBsaWNhdGUgYXR0cmlidXRlIG9uIGEgdGFnLCB0aGVuIHdoZW4gdGhlIHRhZyBpc1xuICAgICAgLy8gcGFyc2VkIGludG8gYW4gZWxlbWVudCB0aGUgYXR0cmlidXRlIGdldHMgZGUtZHVwbGljYXRlZC4gV2UgY2FuIGRldGVjdFxuICAgICAgLy8gdGhpcyBtaXNtYXRjaCBpZiB3ZSBoYXZlbid0IHByZWNpc2VseSBjb25zdW1lZCBldmVyeSBhdHRyaWJ1dGUgbmFtZVxuICAgICAgLy8gd2hlbiBwcmVwYXJpbmcgdGhlIHRlbXBsYXRlLiBUaGlzIHdvcmtzIGJlY2F1c2UgYGF0dHJOYW1lc2AgaXMgYnVpbHRcbiAgICAgIC8vIGZyb20gdGhlIHRlbXBsYXRlIHN0cmluZyBhbmQgYGF0dHJOYW1lSW5kZXhgIGNvbWVzIGZyb20gcHJvY2Vzc2luZyB0aGVcbiAgICAgIC8vIHJlc3VsdGluZyBET00uXG4gICAgICBpZiAoYXR0ck5hbWVzLmxlbmd0aCAhPT0gYXR0ck5hbWVJbmRleCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYERldGVjdGVkIGR1cGxpY2F0ZSBhdHRyaWJ1dGUgYmluZGluZ3MuIFRoaXMgb2NjdXJzIGlmIHlvdXIgdGVtcGxhdGUgYCArXG4gICAgICAgICAgICBgaGFzIGR1cGxpY2F0ZSBhdHRyaWJ1dGVzIG9uIGFuIGVsZW1lbnQgdGFnLiBGb3IgZXhhbXBsZSBgICtcbiAgICAgICAgICAgIGBcIjxpbnB1dCA/ZGlzYWJsZWQ9XFwke3RydWV9ID9kaXNhYmxlZD1cXCR7ZmFsc2V9PlwiIGNvbnRhaW5zIGEgYCArXG4gICAgICAgICAgICBgZHVwbGljYXRlIFwiZGlzYWJsZWRcIiBhdHRyaWJ1dGUuIFRoZSBlcnJvciB3YXMgZGV0ZWN0ZWQgaW4gYCArXG4gICAgICAgICAgICBgdGhlIGZvbGxvd2luZyB0ZW1wbGF0ZTogXFxuYCArXG4gICAgICAgICAgICAnYCcgK1xuICAgICAgICAgICAgc3RyaW5ncy5qb2luKCckey4uLn0nKSArXG4gICAgICAgICAgICAnYCdcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBXZSBjb3VsZCBzZXQgd2Fsa2VyLmN1cnJlbnROb2RlIHRvIGFub3RoZXIgbm9kZSBoZXJlIHRvIHByZXZlbnQgYSBtZW1vcnlcbiAgICAvLyBsZWFrLCBidXQgZXZlcnkgdGltZSB3ZSBwcmVwYXJlIGEgdGVtcGxhdGUsIHdlIGltbWVkaWF0ZWx5IHJlbmRlciBpdFxuICAgIC8vIGFuZCByZS11c2UgdGhlIHdhbGtlciBpbiBuZXcgVGVtcGxhdGVJbnN0YW5jZS5fY2xvbmUoKS5cbiAgICBkZWJ1Z0xvZ0V2ZW50ICYmXG4gICAgICBkZWJ1Z0xvZ0V2ZW50KHtcbiAgICAgICAga2luZDogJ3RlbXBsYXRlIHByZXAnLFxuICAgICAgICB0ZW1wbGF0ZTogdGhpcyxcbiAgICAgICAgY2xvbmFibGVUZW1wbGF0ZTogdGhpcy5lbCxcbiAgICAgICAgcGFydHM6IHRoaXMucGFydHMsXG4gICAgICAgIHN0cmluZ3MsXG4gICAgICB9KTtcbiAgfVxuXG4gIC8vIE92ZXJyaWRkZW4gdmlhIGBsaXRIdG1sUG9seWZpbGxTdXBwb3J0YCB0byBwcm92aWRlIHBsYXRmb3JtIHN1cHBvcnQuXG4gIC8qKiBAbm9jb2xsYXBzZSAqL1xuICBzdGF0aWMgY3JlYXRlRWxlbWVudChodG1sOiBUcnVzdGVkSFRNTCwgX29wdGlvbnM/OiBSZW5kZXJPcHRpb25zKSB7XG4gICAgY29uc3QgZWwgPSBkLmNyZWF0ZUVsZW1lbnQoJ3RlbXBsYXRlJyk7XG4gICAgZWwuaW5uZXJIVE1MID0gaHRtbCBhcyB1bmtub3duIGFzIHN0cmluZztcbiAgICByZXR1cm4gZWw7XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBEaXNjb25uZWN0YWJsZSB7XG4gIF8kcGFyZW50PzogRGlzY29ubmVjdGFibGU7XG4gIF8kZGlzY29ubmVjdGFibGVDaGlsZHJlbj86IFNldDxEaXNjb25uZWN0YWJsZT47XG4gIC8vIFJhdGhlciB0aGFuIGhvbGQgY29ubmVjdGlvbiBzdGF0ZSBvbiBpbnN0YW5jZXMsIERpc2Nvbm5lY3RhYmxlcyByZWN1cnNpdmVseVxuICAvLyBmZXRjaCB0aGUgY29ubmVjdGlvbiBzdGF0ZSBmcm9tIHRoZSBSb290UGFydCB0aGV5IGFyZSBjb25uZWN0ZWQgaW4gdmlhXG4gIC8vIGdldHRlcnMgdXAgdGhlIERpc2Nvbm5lY3RhYmxlIHRyZWUgdmlhIF8kcGFyZW50IHJlZmVyZW5jZXMuIFRoaXMgcHVzaGVzIHRoZVxuICAvLyBjb3N0IG9mIHRyYWNraW5nIHRoZSBpc0Nvbm5lY3RlZCBzdGF0ZSB0byBgQXN5bmNEaXJlY3RpdmVzYCwgYW5kIGF2b2lkc1xuICAvLyBuZWVkaW5nIHRvIHBhc3MgYWxsIERpc2Nvbm5lY3RhYmxlcyAocGFydHMsIHRlbXBsYXRlIGluc3RhbmNlcywgYW5kXG4gIC8vIGRpcmVjdGl2ZXMpIHRoZWlyIGNvbm5lY3Rpb24gc3RhdGUgZWFjaCB0aW1lIGl0IGNoYW5nZXMsIHdoaWNoIHdvdWxkIGJlXG4gIC8vIGNvc3RseSBmb3IgdHJlZXMgdGhhdCBoYXZlIG5vIEFzeW5jRGlyZWN0aXZlcy5cbiAgXyRpc0Nvbm5lY3RlZDogYm9vbGVhbjtcbn1cblxuZnVuY3Rpb24gcmVzb2x2ZURpcmVjdGl2ZShcbiAgcGFydDogQ2hpbGRQYXJ0IHwgQXR0cmlidXRlUGFydCB8IEVsZW1lbnRQYXJ0LFxuICB2YWx1ZTogdW5rbm93bixcbiAgcGFyZW50OiBEaXJlY3RpdmVQYXJlbnQgPSBwYXJ0LFxuICBhdHRyaWJ1dGVJbmRleD86IG51bWJlclxuKTogdW5rbm93biB7XG4gIC8vIEJhaWwgZWFybHkgaWYgdGhlIHZhbHVlIGlzIGV4cGxpY2l0bHkgbm9DaGFuZ2UuIE5vdGUsIHRoaXMgbWVhbnMgYW55XG4gIC8vIG5lc3RlZCBkaXJlY3RpdmUgaXMgc3RpbGwgYXR0YWNoZWQgYW5kIGlzIG5vdCBydW4uXG4gIGlmICh2YWx1ZSA9PT0gbm9DaGFuZ2UpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgbGV0IGN1cnJlbnREaXJlY3RpdmUgPVxuICAgIGF0dHJpYnV0ZUluZGV4ICE9PSB1bmRlZmluZWRcbiAgICAgID8gKHBhcmVudCBhcyBBdHRyaWJ1dGVQYXJ0KS5fX2RpcmVjdGl2ZXM/LlthdHRyaWJ1dGVJbmRleF1cbiAgICAgIDogKHBhcmVudCBhcyBDaGlsZFBhcnQgfCBFbGVtZW50UGFydCB8IERpcmVjdGl2ZSkuX19kaXJlY3RpdmU7XG4gIGNvbnN0IG5leHREaXJlY3RpdmVDb25zdHJ1Y3RvciA9IGlzUHJpbWl0aXZlKHZhbHVlKVxuICAgID8gdW5kZWZpbmVkXG4gICAgOiAvLyBUaGlzIHByb3BlcnR5IG5lZWRzIHRvIHJlbWFpbiB1bm1pbmlmaWVkLlxuICAgICAgKHZhbHVlIGFzIERpcmVjdGl2ZVJlc3VsdClbJ18kbGl0RGlyZWN0aXZlJCddO1xuICBpZiAoY3VycmVudERpcmVjdGl2ZT8uY29uc3RydWN0b3IgIT09IG5leHREaXJlY3RpdmVDb25zdHJ1Y3Rvcikge1xuICAgIC8vIFRoaXMgcHJvcGVydHkgbmVlZHMgdG8gcmVtYWluIHVubWluaWZpZWQuXG4gICAgY3VycmVudERpcmVjdGl2ZT8uWydfJG5vdGlmeURpcmVjdGl2ZUNvbm5lY3Rpb25DaGFuZ2VkJ10/LihmYWxzZSk7XG4gICAgaWYgKG5leHREaXJlY3RpdmVDb25zdHJ1Y3RvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBjdXJyZW50RGlyZWN0aXZlID0gdW5kZWZpbmVkO1xuICAgIH0gZWxzZSB7XG4gICAgICBjdXJyZW50RGlyZWN0aXZlID0gbmV3IG5leHREaXJlY3RpdmVDb25zdHJ1Y3RvcihwYXJ0IGFzIFBhcnRJbmZvKTtcbiAgICAgIGN1cnJlbnREaXJlY3RpdmUuXyRpbml0aWFsaXplKHBhcnQsIHBhcmVudCwgYXR0cmlidXRlSW5kZXgpO1xuICAgIH1cbiAgICBpZiAoYXR0cmlidXRlSW5kZXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgKChwYXJlbnQgYXMgQXR0cmlidXRlUGFydCkuX19kaXJlY3RpdmVzID8/PSBbXSlbYXR0cmlidXRlSW5kZXhdID1cbiAgICAgICAgY3VycmVudERpcmVjdGl2ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgKHBhcmVudCBhcyBDaGlsZFBhcnQgfCBEaXJlY3RpdmUpLl9fZGlyZWN0aXZlID0gY3VycmVudERpcmVjdGl2ZTtcbiAgICB9XG4gIH1cbiAgaWYgKGN1cnJlbnREaXJlY3RpdmUgIT09IHVuZGVmaW5lZCkge1xuICAgIHZhbHVlID0gcmVzb2x2ZURpcmVjdGl2ZShcbiAgICAgIHBhcnQsXG4gICAgICBjdXJyZW50RGlyZWN0aXZlLl8kcmVzb2x2ZShwYXJ0LCAodmFsdWUgYXMgRGlyZWN0aXZlUmVzdWx0KS52YWx1ZXMpLFxuICAgICAgY3VycmVudERpcmVjdGl2ZSxcbiAgICAgIGF0dHJpYnV0ZUluZGV4XG4gICAgKTtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59XG5cbmV4cG9ydCB0eXBlIHtUZW1wbGF0ZUluc3RhbmNlfTtcbi8qKlxuICogQW4gdXBkYXRlYWJsZSBpbnN0YW5jZSBvZiBhIFRlbXBsYXRlLiBIb2xkcyByZWZlcmVuY2VzIHRvIHRoZSBQYXJ0cyB1c2VkIHRvXG4gKiB1cGRhdGUgdGhlIHRlbXBsYXRlIGluc3RhbmNlLlxuICovXG5jbGFzcyBUZW1wbGF0ZUluc3RhbmNlIGltcGxlbWVudHMgRGlzY29ubmVjdGFibGUge1xuICBfJHRlbXBsYXRlOiBUZW1wbGF0ZTtcbiAgXyRwYXJ0czogQXJyYXk8UGFydCB8IHVuZGVmaW5lZD4gPSBbXTtcblxuICAvKiogQGludGVybmFsICovXG4gIF8kcGFyZW50OiBDaGlsZFBhcnQ7XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgXyRkaXNjb25uZWN0YWJsZUNoaWxkcmVuPzogU2V0PERpc2Nvbm5lY3RhYmxlPiA9IHVuZGVmaW5lZDtcblxuICBjb25zdHJ1Y3Rvcih0ZW1wbGF0ZTogVGVtcGxhdGUsIHBhcmVudDogQ2hpbGRQYXJ0KSB7XG4gICAgdGhpcy5fJHRlbXBsYXRlID0gdGVtcGxhdGU7XG4gICAgdGhpcy5fJHBhcmVudCA9IHBhcmVudDtcbiAgfVxuXG4gIC8vIENhbGxlZCBieSBDaGlsZFBhcnQgcGFyZW50Tm9kZSBnZXR0ZXJcbiAgZ2V0IHBhcmVudE5vZGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuXyRwYXJlbnQucGFyZW50Tm9kZTtcbiAgfVxuXG4gIC8vIFNlZSBjb21tZW50IGluIERpc2Nvbm5lY3RhYmxlIGludGVyZmFjZSBmb3Igd2h5IHRoaXMgaXMgYSBnZXR0ZXJcbiAgZ2V0IF8kaXNDb25uZWN0ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuXyRwYXJlbnQuXyRpc0Nvbm5lY3RlZDtcbiAgfVxuXG4gIC8vIFRoaXMgbWV0aG9kIGlzIHNlcGFyYXRlIGZyb20gdGhlIGNvbnN0cnVjdG9yIGJlY2F1c2Ugd2UgbmVlZCB0byByZXR1cm4gYVxuICAvLyBEb2N1bWVudEZyYWdtZW50IGFuZCB3ZSBkb24ndCB3YW50IHRvIGhvbGQgb250byBpdCB3aXRoIGFuIGluc3RhbmNlIGZpZWxkLlxuICBfY2xvbmUob3B0aW9uczogUmVuZGVyT3B0aW9ucyB8IHVuZGVmaW5lZCkge1xuICAgIGNvbnN0IHtcbiAgICAgIGVsOiB7Y29udGVudH0sXG4gICAgICBwYXJ0czogcGFydHMsXG4gICAgfSA9IHRoaXMuXyR0ZW1wbGF0ZTtcbiAgICBjb25zdCBmcmFnbWVudCA9IChvcHRpb25zPy5jcmVhdGlvblNjb3BlID8/IGQpLmltcG9ydE5vZGUoY29udGVudCwgdHJ1ZSk7XG4gICAgd2Fsa2VyLmN1cnJlbnROb2RlID0gZnJhZ21lbnQ7XG5cbiAgICBsZXQgbm9kZSA9IHdhbGtlci5uZXh0Tm9kZSgpITtcbiAgICBsZXQgbm9kZUluZGV4ID0gMDtcbiAgICBsZXQgcGFydEluZGV4ID0gMDtcbiAgICBsZXQgdGVtcGxhdGVQYXJ0ID0gcGFydHNbMF07XG5cbiAgICB3aGlsZSAodGVtcGxhdGVQYXJ0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChub2RlSW5kZXggPT09IHRlbXBsYXRlUGFydC5pbmRleCkge1xuICAgICAgICBsZXQgcGFydDogUGFydCB8IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKHRlbXBsYXRlUGFydC50eXBlID09PSBDSElMRF9QQVJUKSB7XG4gICAgICAgICAgcGFydCA9IG5ldyBDaGlsZFBhcnQoXG4gICAgICAgICAgICBub2RlIGFzIEhUTUxFbGVtZW50LFxuICAgICAgICAgICAgbm9kZS5uZXh0U2libGluZyxcbiAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICBvcHRpb25zXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIGlmICh0ZW1wbGF0ZVBhcnQudHlwZSA9PT0gQVRUUklCVVRFX1BBUlQpIHtcbiAgICAgICAgICBwYXJ0ID0gbmV3IHRlbXBsYXRlUGFydC5jdG9yKFxuICAgICAgICAgICAgbm9kZSBhcyBIVE1MRWxlbWVudCxcbiAgICAgICAgICAgIHRlbXBsYXRlUGFydC5uYW1lLFxuICAgICAgICAgICAgdGVtcGxhdGVQYXJ0LnN0cmluZ3MsXG4gICAgICAgICAgICB0aGlzLFxuICAgICAgICAgICAgb3B0aW9uc1xuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSBpZiAodGVtcGxhdGVQYXJ0LnR5cGUgPT09IEVMRU1FTlRfUEFSVCkge1xuICAgICAgICAgIHBhcnQgPSBuZXcgRWxlbWVudFBhcnQobm9kZSBhcyBIVE1MRWxlbWVudCwgdGhpcywgb3B0aW9ucyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fJHBhcnRzLnB1c2gocGFydCk7XG4gICAgICAgIHRlbXBsYXRlUGFydCA9IHBhcnRzWysrcGFydEluZGV4XTtcbiAgICAgIH1cbiAgICAgIGlmIChub2RlSW5kZXggIT09IHRlbXBsYXRlUGFydD8uaW5kZXgpIHtcbiAgICAgICAgbm9kZSA9IHdhbGtlci5uZXh0Tm9kZSgpITtcbiAgICAgICAgbm9kZUluZGV4Kys7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIFdlIG5lZWQgdG8gc2V0IHRoZSBjdXJyZW50Tm9kZSBhd2F5IGZyb20gdGhlIGNsb25lZCB0cmVlIHNvIHRoYXQgd2VcbiAgICAvLyBkb24ndCBob2xkIG9udG8gdGhlIHRyZWUgZXZlbiBpZiB0aGUgdHJlZSBpcyBkZXRhY2hlZCBhbmQgc2hvdWxkIGJlXG4gICAgLy8gZnJlZWQuXG4gICAgd2Fsa2VyLmN1cnJlbnROb2RlID0gZDtcbiAgICByZXR1cm4gZnJhZ21lbnQ7XG4gIH1cblxuICBfdXBkYXRlKHZhbHVlczogQXJyYXk8dW5rbm93bj4pIHtcbiAgICBsZXQgaSA9IDA7XG4gICAgZm9yIChjb25zdCBwYXJ0IG9mIHRoaXMuXyRwYXJ0cykge1xuICAgICAgaWYgKHBhcnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBkZWJ1Z0xvZ0V2ZW50ICYmXG4gICAgICAgICAgZGVidWdMb2dFdmVudCh7XG4gICAgICAgICAgICBraW5kOiAnc2V0IHBhcnQnLFxuICAgICAgICAgICAgcGFydCxcbiAgICAgICAgICAgIHZhbHVlOiB2YWx1ZXNbaV0sXG4gICAgICAgICAgICB2YWx1ZUluZGV4OiBpLFxuICAgICAgICAgICAgdmFsdWVzLFxuICAgICAgICAgICAgdGVtcGxhdGVJbnN0YW5jZTogdGhpcyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgaWYgKChwYXJ0IGFzIEF0dHJpYnV0ZVBhcnQpLnN0cmluZ3MgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIChwYXJ0IGFzIEF0dHJpYnV0ZVBhcnQpLl8kc2V0VmFsdWUodmFsdWVzLCBwYXJ0IGFzIEF0dHJpYnV0ZVBhcnQsIGkpO1xuICAgICAgICAgIC8vIFRoZSBudW1iZXIgb2YgdmFsdWVzIHRoZSBwYXJ0IGNvbnN1bWVzIGlzIHBhcnQuc3RyaW5ncy5sZW5ndGggLSAxXG4gICAgICAgICAgLy8gc2luY2UgdmFsdWVzIGFyZSBpbiBiZXR3ZWVuIHRlbXBsYXRlIHNwYW5zLiBXZSBpbmNyZW1lbnQgaSBieSAxXG4gICAgICAgICAgLy8gbGF0ZXIgaW4gdGhlIGxvb3AsIHNvIGluY3JlbWVudCBpdCBieSBwYXJ0LnN0cmluZ3MubGVuZ3RoIC0gMiBoZXJlXG4gICAgICAgICAgaSArPSAocGFydCBhcyBBdHRyaWJ1dGVQYXJ0KS5zdHJpbmdzIS5sZW5ndGggLSAyO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHBhcnQuXyRzZXRWYWx1ZSh2YWx1ZXNbaV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpKys7XG4gICAgfVxuICB9XG59XG5cbi8qXG4gKiBQYXJ0c1xuICovXG50eXBlIEF0dHJpYnV0ZVRlbXBsYXRlUGFydCA9IHtcbiAgcmVhZG9ubHkgdHlwZTogdHlwZW9mIEFUVFJJQlVURV9QQVJUO1xuICByZWFkb25seSBpbmRleDogbnVtYmVyO1xuICByZWFkb25seSBuYW1lOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGN0b3I6IHR5cGVvZiBBdHRyaWJ1dGVQYXJ0O1xuICByZWFkb25seSBzdHJpbmdzOiBSZWFkb25seUFycmF5PHN0cmluZz47XG59O1xudHlwZSBDaGlsZFRlbXBsYXRlUGFydCA9IHtcbiAgcmVhZG9ubHkgdHlwZTogdHlwZW9mIENISUxEX1BBUlQ7XG4gIHJlYWRvbmx5IGluZGV4OiBudW1iZXI7XG59O1xudHlwZSBFbGVtZW50VGVtcGxhdGVQYXJ0ID0ge1xuICByZWFkb25seSB0eXBlOiB0eXBlb2YgRUxFTUVOVF9QQVJUO1xuICByZWFkb25seSBpbmRleDogbnVtYmVyO1xufTtcbnR5cGUgQ29tbWVudFRlbXBsYXRlUGFydCA9IHtcbiAgcmVhZG9ubHkgdHlwZTogdHlwZW9mIENPTU1FTlRfUEFSVDtcbiAgcmVhZG9ubHkgaW5kZXg6IG51bWJlcjtcbn07XG5cbi8qKlxuICogQSBUZW1wbGF0ZVBhcnQgcmVwcmVzZW50cyBhIGR5bmFtaWMgcGFydCBpbiBhIHRlbXBsYXRlLCBiZWZvcmUgdGhlIHRlbXBsYXRlXG4gKiBpcyBpbnN0YW50aWF0ZWQuIFdoZW4gYSB0ZW1wbGF0ZSBpcyBpbnN0YW50aWF0ZWQgUGFydHMgYXJlIGNyZWF0ZWQgZnJvbVxuICogVGVtcGxhdGVQYXJ0cy5cbiAqL1xudHlwZSBUZW1wbGF0ZVBhcnQgPVxuICB8IENoaWxkVGVtcGxhdGVQYXJ0XG4gIHwgQXR0cmlidXRlVGVtcGxhdGVQYXJ0XG4gIHwgRWxlbWVudFRlbXBsYXRlUGFydFxuICB8IENvbW1lbnRUZW1wbGF0ZVBhcnQ7XG5cbmV4cG9ydCB0eXBlIFBhcnQgPVxuICB8IENoaWxkUGFydFxuICB8IEF0dHJpYnV0ZVBhcnRcbiAgfCBQcm9wZXJ0eVBhcnRcbiAgfCBCb29sZWFuQXR0cmlidXRlUGFydFxuICB8IEVsZW1lbnRQYXJ0XG4gIHwgRXZlbnRQYXJ0O1xuXG5leHBvcnQgdHlwZSB7Q2hpbGRQYXJ0fTtcbmNsYXNzIENoaWxkUGFydCBpbXBsZW1lbnRzIERpc2Nvbm5lY3RhYmxlIHtcbiAgcmVhZG9ubHkgdHlwZSA9IENISUxEX1BBUlQ7XG4gIHJlYWRvbmx5IG9wdGlvbnM6IFJlbmRlck9wdGlvbnMgfCB1bmRlZmluZWQ7XG4gIF8kY29tbWl0dGVkVmFsdWU6IHVua25vd24gPSBub3RoaW5nO1xuICAvKiogQGludGVybmFsICovXG4gIF9fZGlyZWN0aXZlPzogRGlyZWN0aXZlO1xuICAvKiogQGludGVybmFsICovXG4gIF8kc3RhcnROb2RlOiBDaGlsZE5vZGU7XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgXyRlbmROb2RlOiBDaGlsZE5vZGUgfCBudWxsO1xuICBwcml2YXRlIF90ZXh0U2FuaXRpemVyOiBWYWx1ZVNhbml0aXplciB8IHVuZGVmaW5lZDtcbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBfJHBhcmVudDogRGlzY29ubmVjdGFibGUgfCB1bmRlZmluZWQ7XG4gIC8qKlxuICAgKiBDb25uZWN0aW9uIHN0YXRlIGZvciBSb290UGFydHMgb25seSAoaS5lLiBDaGlsZFBhcnQgd2l0aG91dCBfJHBhcmVudFxuICAgKiByZXR1cm5lZCBmcm9tIHRvcC1sZXZlbCBgcmVuZGVyYCkuIFRoaXMgZmllbGQgaXMgdW51c2VkIG90aGVyd2lzZS4gVGhlXG4gICAqIGludGVudGlvbiB3b3VsZCBiZSBjbGVhcmVyIGlmIHdlIG1hZGUgYFJvb3RQYXJ0YCBhIHN1YmNsYXNzIG9mIGBDaGlsZFBhcnRgXG4gICAqIHdpdGggdGhpcyBmaWVsZCAoYW5kIGEgZGlmZmVyZW50IF8kaXNDb25uZWN0ZWQgZ2V0dGVyKSwgYnV0IHRoZSBzdWJjbGFzc1xuICAgKiBjYXVzZWQgYSBwZXJmIHJlZ3Jlc3Npb24sIHBvc3NpYmx5IGR1ZSB0byBtYWtpbmcgY2FsbCBzaXRlcyBwb2x5bW9ycGhpYy5cbiAgICogQGludGVybmFsXG4gICAqL1xuICBfX2lzQ29ubmVjdGVkOiBib29sZWFuO1xuXG4gIC8vIFNlZSBjb21tZW50IGluIERpc2Nvbm5lY3RhYmxlIGludGVyZmFjZSBmb3Igd2h5IHRoaXMgaXMgYSBnZXR0ZXJcbiAgZ2V0IF8kaXNDb25uZWN0ZWQoKSB7XG4gICAgLy8gQ2hpbGRQYXJ0cyB0aGF0IGFyZSBub3QgYXQgdGhlIHJvb3Qgc2hvdWxkIGFsd2F5cyBiZSBjcmVhdGVkIHdpdGggYVxuICAgIC8vIHBhcmVudDsgb25seSBSb290Q2hpbGROb2RlJ3Mgd29uJ3QsIHNvIHRoZXkgcmV0dXJuIHRoZSBsb2NhbCBpc0Nvbm5lY3RlZFxuICAgIC8vIHN0YXRlXG4gICAgcmV0dXJuIHRoaXMuXyRwYXJlbnQ/Ll8kaXNDb25uZWN0ZWQgPz8gdGhpcy5fX2lzQ29ubmVjdGVkO1xuICB9XG5cbiAgLy8gVGhlIGZvbGxvd2luZyBmaWVsZHMgd2lsbCBiZSBwYXRjaGVkIG9udG8gQ2hpbGRQYXJ0cyB3aGVuIHJlcXVpcmVkIGJ5XG4gIC8vIEFzeW5jRGlyZWN0aXZlXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgXyRkaXNjb25uZWN0YWJsZUNoaWxkcmVuPzogU2V0PERpc2Nvbm5lY3RhYmxlPiA9IHVuZGVmaW5lZDtcbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBfJG5vdGlmeUNvbm5lY3Rpb25DaGFuZ2VkPyhcbiAgICBpc0Nvbm5lY3RlZDogYm9vbGVhbixcbiAgICByZW1vdmVGcm9tUGFyZW50PzogYm9vbGVhbixcbiAgICBmcm9tPzogbnVtYmVyXG4gICk6IHZvaWQ7XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgXyRyZXBhcmVudERpc2Nvbm5lY3RhYmxlcz8ocGFyZW50OiBEaXNjb25uZWN0YWJsZSk6IHZvaWQ7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgc3RhcnROb2RlOiBDaGlsZE5vZGUsXG4gICAgZW5kTm9kZTogQ2hpbGROb2RlIHwgbnVsbCxcbiAgICBwYXJlbnQ6IFRlbXBsYXRlSW5zdGFuY2UgfCBDaGlsZFBhcnQgfCB1bmRlZmluZWQsXG4gICAgb3B0aW9uczogUmVuZGVyT3B0aW9ucyB8IHVuZGVmaW5lZFxuICApIHtcbiAgICB0aGlzLl8kc3RhcnROb2RlID0gc3RhcnROb2RlO1xuICAgIHRoaXMuXyRlbmROb2RlID0gZW5kTm9kZTtcbiAgICB0aGlzLl8kcGFyZW50ID0gcGFyZW50O1xuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgLy8gTm90ZSBfX2lzQ29ubmVjdGVkIGlzIG9ubHkgZXZlciBhY2Nlc3NlZCBvbiBSb290UGFydHMgKGkuZS4gd2hlbiB0aGVyZSBpc1xuICAgIC8vIG5vIF8kcGFyZW50KTsgdGhlIHZhbHVlIG9uIGEgbm9uLXJvb3QtcGFydCBpcyBcImRvbid0IGNhcmVcIiwgYnV0IGNoZWNraW5nXG4gICAgLy8gZm9yIHBhcmVudCB3b3VsZCBiZSBtb3JlIGNvZGVcbiAgICB0aGlzLl9faXNDb25uZWN0ZWQgPSBvcHRpb25zPy5pc0Nvbm5lY3RlZCA/PyB0cnVlO1xuICAgIGlmIChFTkFCTEVfRVhUUkFfU0VDVVJJVFlfSE9PS1MpIHtcbiAgICAgIC8vIEV4cGxpY2l0bHkgaW5pdGlhbGl6ZSBmb3IgY29uc2lzdGVudCBjbGFzcyBzaGFwZS5cbiAgICAgIHRoaXMuX3RleHRTYW5pdGl6ZXIgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBwYXJlbnQgbm9kZSBpbnRvIHdoaWNoIHRoZSBwYXJ0IHJlbmRlcnMgaXRzIGNvbnRlbnQuXG4gICAqXG4gICAqIEEgQ2hpbGRQYXJ0J3MgY29udGVudCBjb25zaXN0cyBvZiBhIHJhbmdlIG9mIGFkamFjZW50IGNoaWxkIG5vZGVzIG9mXG4gICAqIGAucGFyZW50Tm9kZWAsIHBvc3NpYmx5IGJvcmRlcmVkIGJ5ICdtYXJrZXIgbm9kZXMnIChgLnN0YXJ0Tm9kZWAgYW5kXG4gICAqIGAuZW5kTm9kZWApLlxuICAgKlxuICAgKiAtIElmIGJvdGggYC5zdGFydE5vZGVgIGFuZCBgLmVuZE5vZGVgIGFyZSBub24tbnVsbCwgdGhlbiB0aGUgcGFydCdzIGNvbnRlbnRcbiAgICogY29uc2lzdHMgb2YgYWxsIHNpYmxpbmdzIGJldHdlZW4gYC5zdGFydE5vZGVgIGFuZCBgLmVuZE5vZGVgLCBleGNsdXNpdmVseS5cbiAgICpcbiAgICogLSBJZiBgLnN0YXJ0Tm9kZWAgaXMgbm9uLW51bGwgYnV0IGAuZW5kTm9kZWAgaXMgbnVsbCwgdGhlbiB0aGUgcGFydCdzXG4gICAqIGNvbnRlbnQgY29uc2lzdHMgb2YgYWxsIHNpYmxpbmdzIGZvbGxvd2luZyBgLnN0YXJ0Tm9kZWAsIHVwIHRvIGFuZFxuICAgKiBpbmNsdWRpbmcgdGhlIGxhc3QgY2hpbGQgb2YgYC5wYXJlbnROb2RlYC4gSWYgYC5lbmROb2RlYCBpcyBub24tbnVsbCwgdGhlblxuICAgKiBgLnN0YXJ0Tm9kZWAgd2lsbCBhbHdheXMgYmUgbm9uLW51bGwuXG4gICAqXG4gICAqIC0gSWYgYm90aCBgLmVuZE5vZGVgIGFuZCBgLnN0YXJ0Tm9kZWAgYXJlIG51bGwsIHRoZW4gdGhlIHBhcnQncyBjb250ZW50XG4gICAqIGNvbnNpc3RzIG9mIGFsbCBjaGlsZCBub2RlcyBvZiBgLnBhcmVudE5vZGVgLlxuICAgKi9cbiAgZ2V0IHBhcmVudE5vZGUoKTogTm9kZSB7XG4gICAgbGV0IHBhcmVudE5vZGU6IE5vZGUgPSB3cmFwKHRoaXMuXyRzdGFydE5vZGUpLnBhcmVudE5vZGUhO1xuICAgIGNvbnN0IHBhcmVudCA9IHRoaXMuXyRwYXJlbnQ7XG4gICAgaWYgKFxuICAgICAgcGFyZW50ICE9PSB1bmRlZmluZWQgJiZcbiAgICAgIHBhcmVudE5vZGU/Lm5vZGVUeXBlID09PSAxMSAvKiBOb2RlLkRPQ1VNRU5UX0ZSQUdNRU5UICovXG4gICAgKSB7XG4gICAgICAvLyBJZiB0aGUgcGFyZW50Tm9kZSBpcyBhIERvY3VtZW50RnJhZ21lbnQsIGl0IG1heSBiZSBiZWNhdXNlIHRoZSBET00gaXNcbiAgICAgIC8vIHN0aWxsIGluIHRoZSBjbG9uZWQgZnJhZ21lbnQgZHVyaW5nIGluaXRpYWwgcmVuZGVyOyBpZiBzbywgZ2V0IHRoZSByZWFsXG4gICAgICAvLyBwYXJlbnROb2RlIHRoZSBwYXJ0IHdpbGwgYmUgY29tbWl0dGVkIGludG8gYnkgYXNraW5nIHRoZSBwYXJlbnQuXG4gICAgICBwYXJlbnROb2RlID0gKHBhcmVudCBhcyBDaGlsZFBhcnQgfCBUZW1wbGF0ZUluc3RhbmNlKS5wYXJlbnROb2RlO1xuICAgIH1cbiAgICByZXR1cm4gcGFyZW50Tm9kZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgcGFydCdzIGxlYWRpbmcgbWFya2VyIG5vZGUsIGlmIGFueS4gU2VlIGAucGFyZW50Tm9kZWAgZm9yIG1vcmVcbiAgICogaW5mb3JtYXRpb24uXG4gICAqL1xuICBnZXQgc3RhcnROb2RlKCk6IE5vZGUgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5fJHN0YXJ0Tm9kZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgcGFydCdzIHRyYWlsaW5nIG1hcmtlciBub2RlLCBpZiBhbnkuIFNlZSBgLnBhcmVudE5vZGVgIGZvciBtb3JlXG4gICAqIGluZm9ybWF0aW9uLlxuICAgKi9cbiAgZ2V0IGVuZE5vZGUoKTogTm9kZSB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLl8kZW5kTm9kZTtcbiAgfVxuXG4gIF8kc2V0VmFsdWUodmFsdWU6IHVua25vd24sIGRpcmVjdGl2ZVBhcmVudDogRGlyZWN0aXZlUGFyZW50ID0gdGhpcyk6IHZvaWQge1xuICAgIGlmIChERVZfTU9ERSAmJiB0aGlzLnBhcmVudE5vZGUgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYFRoaXMgXFxgQ2hpbGRQYXJ0XFxgIGhhcyBubyBcXGBwYXJlbnROb2RlXFxgIGFuZCB0aGVyZWZvcmUgY2Fubm90IGFjY2VwdCBhIHZhbHVlLiBUaGlzIGxpa2VseSBtZWFucyB0aGUgZWxlbWVudCBjb250YWluaW5nIHRoZSBwYXJ0IHdhcyBtYW5pcHVsYXRlZCBpbiBhbiB1bnN1cHBvcnRlZCB3YXkgb3V0c2lkZSBvZiBMaXQncyBjb250cm9sIHN1Y2ggdGhhdCB0aGUgcGFydCdzIG1hcmtlciBub2RlcyB3ZXJlIGVqZWN0ZWQgZnJvbSBET00uIEZvciBleGFtcGxlLCBzZXR0aW5nIHRoZSBlbGVtZW50J3MgXFxgaW5uZXJIVE1MXFxgIG9yIFxcYHRleHRDb250ZW50XFxgIGNhbiBkbyB0aGlzLmBcbiAgICAgICk7XG4gICAgfVxuICAgIHZhbHVlID0gcmVzb2x2ZURpcmVjdGl2ZSh0aGlzLCB2YWx1ZSwgZGlyZWN0aXZlUGFyZW50KTtcbiAgICBpZiAoaXNQcmltaXRpdmUodmFsdWUpKSB7XG4gICAgICAvLyBOb24tcmVuZGVyaW5nIGNoaWxkIHZhbHVlcy4gSXQncyBpbXBvcnRhbnQgdGhhdCB0aGVzZSBkbyBub3QgcmVuZGVyXG4gICAgICAvLyBlbXB0eSB0ZXh0IG5vZGVzIHRvIGF2b2lkIGlzc3VlcyB3aXRoIHByZXZlbnRpbmcgZGVmYXVsdCA8c2xvdD5cbiAgICAgIC8vIGZhbGxiYWNrIGNvbnRlbnQuXG4gICAgICBpZiAodmFsdWUgPT09IG5vdGhpbmcgfHwgdmFsdWUgPT0gbnVsbCB8fCB2YWx1ZSA9PT0gJycpIHtcbiAgICAgICAgaWYgKHRoaXMuXyRjb21taXR0ZWRWYWx1ZSAhPT0gbm90aGluZykge1xuICAgICAgICAgIGRlYnVnTG9nRXZlbnQgJiZcbiAgICAgICAgICAgIGRlYnVnTG9nRXZlbnQoe1xuICAgICAgICAgICAgICBraW5kOiAnY29tbWl0IG5vdGhpbmcgdG8gY2hpbGQnLFxuICAgICAgICAgICAgICBzdGFydDogdGhpcy5fJHN0YXJ0Tm9kZSxcbiAgICAgICAgICAgICAgZW5kOiB0aGlzLl8kZW5kTm9kZSxcbiAgICAgICAgICAgICAgcGFyZW50OiB0aGlzLl8kcGFyZW50LFxuICAgICAgICAgICAgICBvcHRpb25zOiB0aGlzLm9wdGlvbnMsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB0aGlzLl8kY2xlYXIoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl8kY29tbWl0dGVkVmFsdWUgPSBub3RoaW5nO1xuICAgICAgfSBlbHNlIGlmICh2YWx1ZSAhPT0gdGhpcy5fJGNvbW1pdHRlZFZhbHVlICYmIHZhbHVlICE9PSBub0NoYW5nZSkge1xuICAgICAgICB0aGlzLl9jb21taXRUZXh0KHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIC8vIFRoaXMgcHJvcGVydHkgbmVlZHMgdG8gcmVtYWluIHVubWluaWZpZWQuXG4gICAgfSBlbHNlIGlmICgodmFsdWUgYXMgVGVtcGxhdGVSZXN1bHQpWydfJGxpdFR5cGUkJ10gIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5fY29tbWl0VGVtcGxhdGVSZXN1bHQodmFsdWUgYXMgVGVtcGxhdGVSZXN1bHQpO1xuICAgIH0gZWxzZSBpZiAoKHZhbHVlIGFzIE5vZGUpLm5vZGVUeXBlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChERVZfTU9ERSAmJiB0aGlzLm9wdGlvbnM/Lmhvc3QgPT09IHZhbHVlKSB7XG4gICAgICAgIHRoaXMuX2NvbW1pdFRleHQoXG4gICAgICAgICAgYFtwcm9iYWJsZSBtaXN0YWtlOiByZW5kZXJlZCBhIHRlbXBsYXRlJ3MgaG9zdCBpbiBpdHNlbGYgYCArXG4gICAgICAgICAgICBgKGNvbW1vbmx5IGNhdXNlZCBieSB3cml0aW5nIFxcJHt0aGlzfSBpbiBhIHRlbXBsYXRlXWBcbiAgICAgICAgKTtcbiAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgIGBBdHRlbXB0ZWQgdG8gcmVuZGVyIHRoZSB0ZW1wbGF0ZSBob3N0YCxcbiAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICBgaW5zaWRlIGl0c2VsZi4gVGhpcyBpcyBhbG1vc3QgYWx3YXlzIGEgbWlzdGFrZSwgYW5kIGluIGRldiBtb2RlIGAsXG4gICAgICAgICAgYHdlIHJlbmRlciBzb21lIHdhcm5pbmcgdGV4dC4gSW4gcHJvZHVjdGlvbiBob3dldmVyLCB3ZSdsbCBgLFxuICAgICAgICAgIGByZW5kZXIgaXQsIHdoaWNoIHdpbGwgdXN1YWxseSByZXN1bHQgaW4gYW4gZXJyb3IsIGFuZCBzb21ldGltZXMgYCxcbiAgICAgICAgICBgaW4gdGhlIGVsZW1lbnQgZGlzYXBwZWFyaW5nIGZyb20gdGhlIERPTS5gXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuX2NvbW1pdE5vZGUodmFsdWUgYXMgTm9kZSk7XG4gICAgfSBlbHNlIGlmIChpc0l0ZXJhYmxlKHZhbHVlKSkge1xuICAgICAgdGhpcy5fY29tbWl0SXRlcmFibGUodmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBGYWxsYmFjaywgd2lsbCByZW5kZXIgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvblxuICAgICAgdGhpcy5fY29tbWl0VGV4dCh2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfaW5zZXJ0PFQgZXh0ZW5kcyBOb2RlPihub2RlOiBUKSB7XG4gICAgcmV0dXJuIHdyYXAod3JhcCh0aGlzLl8kc3RhcnROb2RlKS5wYXJlbnROb2RlISkuaW5zZXJ0QmVmb3JlKFxuICAgICAgbm9kZSxcbiAgICAgIHRoaXMuXyRlbmROb2RlXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgX2NvbW1pdE5vZGUodmFsdWU6IE5vZGUpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fJGNvbW1pdHRlZFZhbHVlICE9PSB2YWx1ZSkge1xuICAgICAgdGhpcy5fJGNsZWFyKCk7XG4gICAgICBpZiAoXG4gICAgICAgIEVOQUJMRV9FWFRSQV9TRUNVUklUWV9IT09LUyAmJlxuICAgICAgICBzYW5pdGl6ZXJGYWN0b3J5SW50ZXJuYWwgIT09IG5vb3BTYW5pdGl6ZXJcbiAgICAgICkge1xuICAgICAgICBjb25zdCBwYXJlbnROb2RlTmFtZSA9IHRoaXMuXyRzdGFydE5vZGUucGFyZW50Tm9kZT8ubm9kZU5hbWU7XG4gICAgICAgIGlmIChwYXJlbnROb2RlTmFtZSA9PT0gJ1NUWUxFJyB8fCBwYXJlbnROb2RlTmFtZSA9PT0gJ1NDUklQVCcpIHtcbiAgICAgICAgICBsZXQgbWVzc2FnZSA9ICdGb3JiaWRkZW4nO1xuICAgICAgICAgIGlmIChERVZfTU9ERSkge1xuICAgICAgICAgICAgaWYgKHBhcmVudE5vZGVOYW1lID09PSAnU1RZTEUnKSB7XG4gICAgICAgICAgICAgIG1lc3NhZ2UgPVxuICAgICAgICAgICAgICAgIGBMaXQgZG9lcyBub3Qgc3VwcG9ydCBiaW5kaW5nIGluc2lkZSBzdHlsZSBub2Rlcy4gYCArXG4gICAgICAgICAgICAgICAgYFRoaXMgaXMgYSBzZWN1cml0eSByaXNrLCBhcyBzdHlsZSBpbmplY3Rpb24gYXR0YWNrcyBjYW4gYCArXG4gICAgICAgICAgICAgICAgYGV4ZmlsdHJhdGUgZGF0YSBhbmQgc3Bvb2YgVUlzLiBgICtcbiAgICAgICAgICAgICAgICBgQ29uc2lkZXIgaW5zdGVhZCB1c2luZyBjc3NcXGAuLi5cXGAgbGl0ZXJhbHMgYCArXG4gICAgICAgICAgICAgICAgYHRvIGNvbXBvc2Ugc3R5bGVzLCBhbmQgZG8gZHluYW1pYyBzdHlsaW5nIHdpdGggYCArXG4gICAgICAgICAgICAgICAgYGNzcyBjdXN0b20gcHJvcGVydGllcywgOjpwYXJ0cywgPHNsb3Q+cywgYCArXG4gICAgICAgICAgICAgICAgYGFuZCBieSBtdXRhdGluZyB0aGUgRE9NIHJhdGhlciB0aGFuIHN0eWxlc2hlZXRzLmA7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBtZXNzYWdlID1cbiAgICAgICAgICAgICAgICBgTGl0IGRvZXMgbm90IHN1cHBvcnQgYmluZGluZyBpbnNpZGUgc2NyaXB0IG5vZGVzLiBgICtcbiAgICAgICAgICAgICAgICBgVGhpcyBpcyBhIHNlY3VyaXR5IHJpc2ssIGFzIGl0IGNvdWxkIGFsbG93IGFyYml0cmFyeSBgICtcbiAgICAgICAgICAgICAgICBgY29kZSBleGVjdXRpb24uYDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBkZWJ1Z0xvZ0V2ZW50ICYmXG4gICAgICAgIGRlYnVnTG9nRXZlbnQoe1xuICAgICAgICAgIGtpbmQ6ICdjb21taXQgbm9kZScsXG4gICAgICAgICAgc3RhcnQ6IHRoaXMuXyRzdGFydE5vZGUsXG4gICAgICAgICAgcGFyZW50OiB0aGlzLl8kcGFyZW50LFxuICAgICAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICBvcHRpb25zOiB0aGlzLm9wdGlvbnMsXG4gICAgICAgIH0pO1xuICAgICAgdGhpcy5fJGNvbW1pdHRlZFZhbHVlID0gdGhpcy5faW5zZXJ0KHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9jb21taXRUZXh0KHZhbHVlOiB1bmtub3duKTogdm9pZCB7XG4gICAgLy8gSWYgdGhlIGNvbW1pdHRlZCB2YWx1ZSBpcyBhIHByaW1pdGl2ZSBpdCBtZWFucyB3ZSBjYWxsZWQgX2NvbW1pdFRleHQgb25cbiAgICAvLyB0aGUgcHJldmlvdXMgcmVuZGVyLCBhbmQgd2Uga25vdyB0aGF0IHRoaXMuXyRzdGFydE5vZGUubmV4dFNpYmxpbmcgaXMgYVxuICAgIC8vIFRleHQgbm9kZS4gV2UgY2FuIG5vdyBqdXN0IHJlcGxhY2UgdGhlIHRleHQgY29udGVudCAoLmRhdGEpIG9mIHRoZSBub2RlLlxuICAgIGlmIChcbiAgICAgIHRoaXMuXyRjb21taXR0ZWRWYWx1ZSAhPT0gbm90aGluZyAmJlxuICAgICAgaXNQcmltaXRpdmUodGhpcy5fJGNvbW1pdHRlZFZhbHVlKVxuICAgICkge1xuICAgICAgY29uc3Qgbm9kZSA9IHdyYXAodGhpcy5fJHN0YXJ0Tm9kZSkubmV4dFNpYmxpbmcgYXMgVGV4dDtcbiAgICAgIGlmIChFTkFCTEVfRVhUUkFfU0VDVVJJVFlfSE9PS1MpIHtcbiAgICAgICAgaWYgKHRoaXMuX3RleHRTYW5pdGl6ZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRoaXMuX3RleHRTYW5pdGl6ZXIgPSBjcmVhdGVTYW5pdGl6ZXIobm9kZSwgJ2RhdGEnLCAncHJvcGVydHknKTtcbiAgICAgICAgfVxuICAgICAgICB2YWx1ZSA9IHRoaXMuX3RleHRTYW5pdGl6ZXIodmFsdWUpO1xuICAgICAgfVxuICAgICAgZGVidWdMb2dFdmVudCAmJlxuICAgICAgICBkZWJ1Z0xvZ0V2ZW50KHtcbiAgICAgICAgICBraW5kOiAnY29tbWl0IHRleHQnLFxuICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgb3B0aW9uczogdGhpcy5vcHRpb25zLFxuICAgICAgICB9KTtcbiAgICAgIChub2RlIGFzIFRleHQpLmRhdGEgPSB2YWx1ZSBhcyBzdHJpbmc7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChFTkFCTEVfRVhUUkFfU0VDVVJJVFlfSE9PS1MpIHtcbiAgICAgICAgY29uc3QgdGV4dE5vZGUgPSBkLmNyZWF0ZVRleHROb2RlKCcnKTtcbiAgICAgICAgdGhpcy5fY29tbWl0Tm9kZSh0ZXh0Tm9kZSk7XG4gICAgICAgIC8vIFdoZW4gc2V0dGluZyB0ZXh0IGNvbnRlbnQsIGZvciBzZWN1cml0eSBwdXJwb3NlcyBpdCBtYXR0ZXJzIGEgbG90XG4gICAgICAgIC8vIHdoYXQgdGhlIHBhcmVudCBpcy4gRm9yIGV4YW1wbGUsIDxzdHlsZT4gYW5kIDxzY3JpcHQ+IG5lZWQgdG8gYmVcbiAgICAgICAgLy8gaGFuZGxlZCB3aXRoIGNhcmUsIHdoaWxlIDxzcGFuPiBkb2VzIG5vdC4gU28gZmlyc3Qgd2UgbmVlZCB0byBwdXQgYVxuICAgICAgICAvLyB0ZXh0IG5vZGUgaW50byB0aGUgZG9jdW1lbnQsIHRoZW4gd2UgY2FuIHNhbml0aXplIGl0cyBjb250ZW50LlxuICAgICAgICBpZiAodGhpcy5fdGV4dFNhbml0aXplciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhpcy5fdGV4dFNhbml0aXplciA9IGNyZWF0ZVNhbml0aXplcih0ZXh0Tm9kZSwgJ2RhdGEnLCAncHJvcGVydHknKTtcbiAgICAgICAgfVxuICAgICAgICB2YWx1ZSA9IHRoaXMuX3RleHRTYW5pdGl6ZXIodmFsdWUpO1xuICAgICAgICBkZWJ1Z0xvZ0V2ZW50ICYmXG4gICAgICAgICAgZGVidWdMb2dFdmVudCh7XG4gICAgICAgICAgICBraW5kOiAnY29tbWl0IHRleHQnLFxuICAgICAgICAgICAgbm9kZTogdGV4dE5vZGUsXG4gICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgIG9wdGlvbnM6IHRoaXMub3B0aW9ucyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgdGV4dE5vZGUuZGF0YSA9IHZhbHVlIGFzIHN0cmluZztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX2NvbW1pdE5vZGUoZC5jcmVhdGVUZXh0Tm9kZSh2YWx1ZSBhcyBzdHJpbmcpKTtcbiAgICAgICAgZGVidWdMb2dFdmVudCAmJlxuICAgICAgICAgIGRlYnVnTG9nRXZlbnQoe1xuICAgICAgICAgICAga2luZDogJ2NvbW1pdCB0ZXh0JyxcbiAgICAgICAgICAgIG5vZGU6IHdyYXAodGhpcy5fJHN0YXJ0Tm9kZSkubmV4dFNpYmxpbmcgYXMgVGV4dCxcbiAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICAgICAgb3B0aW9uczogdGhpcy5vcHRpb25zLFxuICAgICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLl8kY29tbWl0dGVkVmFsdWUgPSB2YWx1ZTtcbiAgfVxuXG4gIHByaXZhdGUgX2NvbW1pdFRlbXBsYXRlUmVzdWx0KFxuICAgIHJlc3VsdDogVGVtcGxhdGVSZXN1bHQgfCBDb21waWxlZFRlbXBsYXRlUmVzdWx0XG4gICk6IHZvaWQge1xuICAgIC8vIFRoaXMgcHJvcGVydHkgbmVlZHMgdG8gcmVtYWluIHVubWluaWZpZWQuXG4gICAgY29uc3Qge3ZhbHVlcywgWydfJGxpdFR5cGUkJ106IHR5cGV9ID0gcmVzdWx0O1xuICAgIC8vIElmICRsaXRUeXBlJCBpcyBhIG51bWJlciwgcmVzdWx0IGlzIGEgcGxhaW4gVGVtcGxhdGVSZXN1bHQgYW5kIHdlIGdldFxuICAgIC8vIHRoZSB0ZW1wbGF0ZSBmcm9tIHRoZSB0ZW1wbGF0ZSBjYWNoZS4gSWYgbm90LCByZXN1bHQgaXMgYVxuICAgIC8vIENvbXBpbGVkVGVtcGxhdGVSZXN1bHQgYW5kIF8kbGl0VHlwZSQgaXMgYSBDb21waWxlZFRlbXBsYXRlIGFuZCB3ZSBuZWVkXG4gICAgLy8gdG8gY3JlYXRlIHRoZSA8dGVtcGxhdGU+IGVsZW1lbnQgdGhlIGZpcnN0IHRpbWUgd2Ugc2VlIGl0LlxuICAgIGNvbnN0IHRlbXBsYXRlOiBUZW1wbGF0ZSB8IENvbXBpbGVkVGVtcGxhdGUgPVxuICAgICAgdHlwZW9mIHR5cGUgPT09ICdudW1iZXInXG4gICAgICAgID8gdGhpcy5fJGdldFRlbXBsYXRlKHJlc3VsdCBhcyBVbmNvbXBpbGVkVGVtcGxhdGVSZXN1bHQpXG4gICAgICAgIDogKHR5cGUuZWwgPT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgICAgKHR5cGUuZWwgPSBUZW1wbGF0ZS5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICB0cnVzdEZyb21UZW1wbGF0ZVN0cmluZyh0eXBlLmgsIHR5cGUuaFswXSksXG4gICAgICAgICAgICAgIHRoaXMub3B0aW9uc1xuICAgICAgICAgICAgKSksXG4gICAgICAgICAgdHlwZSk7XG5cbiAgICBpZiAoKHRoaXMuXyRjb21taXR0ZWRWYWx1ZSBhcyBUZW1wbGF0ZUluc3RhbmNlKT8uXyR0ZW1wbGF0ZSA9PT0gdGVtcGxhdGUpIHtcbiAgICAgIGRlYnVnTG9nRXZlbnQgJiZcbiAgICAgICAgZGVidWdMb2dFdmVudCh7XG4gICAgICAgICAga2luZDogJ3RlbXBsYXRlIHVwZGF0aW5nJyxcbiAgICAgICAgICB0ZW1wbGF0ZSxcbiAgICAgICAgICBpbnN0YW5jZTogdGhpcy5fJGNvbW1pdHRlZFZhbHVlIGFzIFRlbXBsYXRlSW5zdGFuY2UsXG4gICAgICAgICAgcGFydHM6ICh0aGlzLl8kY29tbWl0dGVkVmFsdWUgYXMgVGVtcGxhdGVJbnN0YW5jZSkuXyRwYXJ0cyxcbiAgICAgICAgICBvcHRpb25zOiB0aGlzLm9wdGlvbnMsXG4gICAgICAgICAgdmFsdWVzLFxuICAgICAgICB9KTtcbiAgICAgICh0aGlzLl8kY29tbWl0dGVkVmFsdWUgYXMgVGVtcGxhdGVJbnN0YW5jZSkuX3VwZGF0ZSh2YWx1ZXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBpbnN0YW5jZSA9IG5ldyBUZW1wbGF0ZUluc3RhbmNlKHRlbXBsYXRlIGFzIFRlbXBsYXRlLCB0aGlzKTtcbiAgICAgIGNvbnN0IGZyYWdtZW50ID0gaW5zdGFuY2UuX2Nsb25lKHRoaXMub3B0aW9ucyk7XG4gICAgICBkZWJ1Z0xvZ0V2ZW50ICYmXG4gICAgICAgIGRlYnVnTG9nRXZlbnQoe1xuICAgICAgICAgIGtpbmQ6ICd0ZW1wbGF0ZSBpbnN0YW50aWF0ZWQnLFxuICAgICAgICAgIHRlbXBsYXRlLFxuICAgICAgICAgIGluc3RhbmNlLFxuICAgICAgICAgIHBhcnRzOiBpbnN0YW5jZS5fJHBhcnRzLFxuICAgICAgICAgIG9wdGlvbnM6IHRoaXMub3B0aW9ucyxcbiAgICAgICAgICBmcmFnbWVudCxcbiAgICAgICAgICB2YWx1ZXMsXG4gICAgICAgIH0pO1xuICAgICAgaW5zdGFuY2UuX3VwZGF0ZSh2YWx1ZXMpO1xuICAgICAgZGVidWdMb2dFdmVudCAmJlxuICAgICAgICBkZWJ1Z0xvZ0V2ZW50KHtcbiAgICAgICAgICBraW5kOiAndGVtcGxhdGUgaW5zdGFudGlhdGVkIGFuZCB1cGRhdGVkJyxcbiAgICAgICAgICB0ZW1wbGF0ZSxcbiAgICAgICAgICBpbnN0YW5jZSxcbiAgICAgICAgICBwYXJ0czogaW5zdGFuY2UuXyRwYXJ0cyxcbiAgICAgICAgICBvcHRpb25zOiB0aGlzLm9wdGlvbnMsXG4gICAgICAgICAgZnJhZ21lbnQsXG4gICAgICAgICAgdmFsdWVzLFxuICAgICAgICB9KTtcbiAgICAgIHRoaXMuX2NvbW1pdE5vZGUoZnJhZ21lbnQpO1xuICAgICAgdGhpcy5fJGNvbW1pdHRlZFZhbHVlID0gaW5zdGFuY2U7XG4gICAgfVxuICB9XG5cbiAgLy8gT3ZlcnJpZGRlbiB2aWEgYGxpdEh0bWxQb2x5ZmlsbFN1cHBvcnRgIHRvIHByb3ZpZGUgcGxhdGZvcm0gc3VwcG9ydC5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBfJGdldFRlbXBsYXRlKHJlc3VsdDogVW5jb21waWxlZFRlbXBsYXRlUmVzdWx0KSB7XG4gICAgbGV0IHRlbXBsYXRlID0gdGVtcGxhdGVDYWNoZS5nZXQocmVzdWx0LnN0cmluZ3MpO1xuICAgIGlmICh0ZW1wbGF0ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0ZW1wbGF0ZUNhY2hlLnNldChyZXN1bHQuc3RyaW5ncywgKHRlbXBsYXRlID0gbmV3IFRlbXBsYXRlKHJlc3VsdCkpKTtcbiAgICB9XG4gICAgcmV0dXJuIHRlbXBsYXRlO1xuICB9XG5cbiAgcHJpdmF0ZSBfY29tbWl0SXRlcmFibGUodmFsdWU6IEl0ZXJhYmxlPHVua25vd24+KTogdm9pZCB7XG4gICAgLy8gRm9yIGFuIEl0ZXJhYmxlLCB3ZSBjcmVhdGUgYSBuZXcgSW5zdGFuY2VQYXJ0IHBlciBpdGVtLCB0aGVuIHNldCBpdHNcbiAgICAvLyB2YWx1ZSB0byB0aGUgaXRlbS4gVGhpcyBpcyBhIGxpdHRsZSBiaXQgb2Ygb3ZlcmhlYWQgZm9yIGV2ZXJ5IGl0ZW0gaW5cbiAgICAvLyBhbiBJdGVyYWJsZSwgYnV0IGl0IGxldHMgdXMgcmVjdXJzZSBlYXNpbHkgYW5kIGVmZmljaWVudGx5IHVwZGF0ZSBBcnJheXNcbiAgICAvLyBvZiBUZW1wbGF0ZVJlc3VsdHMgdGhhdCB3aWxsIGJlIGNvbW1vbmx5IHJldHVybmVkIGZyb20gZXhwcmVzc2lvbnMgbGlrZTpcbiAgICAvLyBhcnJheS5tYXAoKGkpID0+IGh0bWxgJHtpfWApLCBieSByZXVzaW5nIGV4aXN0aW5nIFRlbXBsYXRlSW5zdGFuY2VzLlxuXG4gICAgLy8gSWYgdmFsdWUgaXMgYW4gYXJyYXksIHRoZW4gdGhlIHByZXZpb3VzIHJlbmRlciB3YXMgb2YgYW5cbiAgICAvLyBpdGVyYWJsZSBhbmQgdmFsdWUgd2lsbCBjb250YWluIHRoZSBDaGlsZFBhcnRzIGZyb20gdGhlIHByZXZpb3VzXG4gICAgLy8gcmVuZGVyLiBJZiB2YWx1ZSBpcyBub3QgYW4gYXJyYXksIGNsZWFyIHRoaXMgcGFydCBhbmQgbWFrZSBhIG5ld1xuICAgIC8vIGFycmF5IGZvciBDaGlsZFBhcnRzLlxuICAgIGlmICghaXNBcnJheSh0aGlzLl8kY29tbWl0dGVkVmFsdWUpKSB7XG4gICAgICB0aGlzLl8kY29tbWl0dGVkVmFsdWUgPSBbXTtcbiAgICAgIHRoaXMuXyRjbGVhcigpO1xuICAgIH1cblxuICAgIC8vIExldHMgdXMga2VlcCB0cmFjayBvZiBob3cgbWFueSBpdGVtcyB3ZSBzdGFtcGVkIHNvIHdlIGNhbiBjbGVhciBsZWZ0b3ZlclxuICAgIC8vIGl0ZW1zIGZyb20gYSBwcmV2aW91cyByZW5kZXJcbiAgICBjb25zdCBpdGVtUGFydHMgPSB0aGlzLl8kY29tbWl0dGVkVmFsdWUgYXMgQ2hpbGRQYXJ0W107XG4gICAgbGV0IHBhcnRJbmRleCA9IDA7XG4gICAgbGV0IGl0ZW1QYXJ0OiBDaGlsZFBhcnQgfCB1bmRlZmluZWQ7XG5cbiAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgdmFsdWUpIHtcbiAgICAgIGlmIChwYXJ0SW5kZXggPT09IGl0ZW1QYXJ0cy5sZW5ndGgpIHtcbiAgICAgICAgLy8gSWYgbm8gZXhpc3RpbmcgcGFydCwgY3JlYXRlIGEgbmV3IG9uZVxuICAgICAgICAvLyBUT0RPIChqdXN0aW5mYWduYW5pKTogdGVzdCBwZXJmIGltcGFjdCBvZiBhbHdheXMgY3JlYXRpbmcgdHdvIHBhcnRzXG4gICAgICAgIC8vIGluc3RlYWQgb2Ygc2hhcmluZyBwYXJ0cyBiZXR3ZWVuIG5vZGVzXG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9saXQvbGl0L2lzc3Vlcy8xMjY2XG4gICAgICAgIGl0ZW1QYXJ0cy5wdXNoKFxuICAgICAgICAgIChpdGVtUGFydCA9IG5ldyBDaGlsZFBhcnQoXG4gICAgICAgICAgICB0aGlzLl9pbnNlcnQoY3JlYXRlTWFya2VyKCkpLFxuICAgICAgICAgICAgdGhpcy5faW5zZXJ0KGNyZWF0ZU1hcmtlcigpKSxcbiAgICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgICB0aGlzLm9wdGlvbnNcbiAgICAgICAgICApKVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gUmV1c2UgYW4gZXhpc3RpbmcgcGFydFxuICAgICAgICBpdGVtUGFydCA9IGl0ZW1QYXJ0c1twYXJ0SW5kZXhdO1xuICAgICAgfVxuICAgICAgaXRlbVBhcnQuXyRzZXRWYWx1ZShpdGVtKTtcbiAgICAgIHBhcnRJbmRleCsrO1xuICAgIH1cblxuICAgIGlmIChwYXJ0SW5kZXggPCBpdGVtUGFydHMubGVuZ3RoKSB7XG4gICAgICAvLyBpdGVtUGFydHMgYWx3YXlzIGhhdmUgZW5kIG5vZGVzXG4gICAgICB0aGlzLl8kY2xlYXIoXG4gICAgICAgIGl0ZW1QYXJ0ICYmIHdyYXAoaXRlbVBhcnQuXyRlbmROb2RlISkubmV4dFNpYmxpbmcsXG4gICAgICAgIHBhcnRJbmRleFxuICAgICAgKTtcbiAgICAgIC8vIFRydW5jYXRlIHRoZSBwYXJ0cyBhcnJheSBzbyBfdmFsdWUgcmVmbGVjdHMgdGhlIGN1cnJlbnQgc3RhdGVcbiAgICAgIGl0ZW1QYXJ0cy5sZW5ndGggPSBwYXJ0SW5kZXg7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgdGhlIG5vZGVzIGNvbnRhaW5lZCB3aXRoaW4gdGhpcyBQYXJ0IGZyb20gdGhlIERPTS5cbiAgICpcbiAgICogQHBhcmFtIHN0YXJ0IFN0YXJ0IG5vZGUgdG8gY2xlYXIgZnJvbSwgZm9yIGNsZWFyaW5nIGEgc3Vic2V0IG9mIHRoZSBwYXJ0J3NcbiAgICogICAgIERPTSAodXNlZCB3aGVuIHRydW5jYXRpbmcgaXRlcmFibGVzKVxuICAgKiBAcGFyYW0gZnJvbSAgV2hlbiBgc3RhcnRgIGlzIHNwZWNpZmllZCwgdGhlIGluZGV4IHdpdGhpbiB0aGUgaXRlcmFibGUgZnJvbVxuICAgKiAgICAgd2hpY2ggQ2hpbGRQYXJ0cyBhcmUgYmVpbmcgcmVtb3ZlZCwgdXNlZCBmb3IgZGlzY29ubmVjdGluZyBkaXJlY3RpdmVzIGluXG4gICAqICAgICB0aG9zZSBQYXJ0cy5cbiAgICpcbiAgICogQGludGVybmFsXG4gICAqL1xuICBfJGNsZWFyKFxuICAgIHN0YXJ0OiBDaGlsZE5vZGUgfCBudWxsID0gd3JhcCh0aGlzLl8kc3RhcnROb2RlKS5uZXh0U2libGluZyxcbiAgICBmcm9tPzogbnVtYmVyXG4gICkge1xuICAgIHRoaXMuXyRub3RpZnlDb25uZWN0aW9uQ2hhbmdlZD8uKGZhbHNlLCB0cnVlLCBmcm9tKTtcbiAgICB3aGlsZSAoc3RhcnQgJiYgc3RhcnQgIT09IHRoaXMuXyRlbmROb2RlKSB7XG4gICAgICBjb25zdCBuID0gd3JhcChzdGFydCEpLm5leHRTaWJsaW5nO1xuICAgICAgKHdyYXAoc3RhcnQhKSBhcyBFbGVtZW50KS5yZW1vdmUoKTtcbiAgICAgIHN0YXJ0ID0gbjtcbiAgICB9XG4gIH1cbiAgLyoqXG4gICAqIEltcGxlbWVudGF0aW9uIG9mIFJvb3RQYXJ0J3MgYGlzQ29ubmVjdGVkYC4gTm90ZSB0aGF0IHRoaXMgbWV0aG9kXG4gICAqIHNob3VsZCBvbmx5IGJlIGNhbGxlZCBvbiBgUm9vdFBhcnRgcyAodGhlIGBDaGlsZFBhcnRgIHJldHVybmVkIGZyb20gYVxuICAgKiB0b3AtbGV2ZWwgYHJlbmRlcigpYCBjYWxsKS4gSXQgaGFzIG5vIGVmZmVjdCBvbiBub24tcm9vdCBDaGlsZFBhcnRzLlxuICAgKiBAcGFyYW0gaXNDb25uZWN0ZWQgV2hldGhlciB0byBzZXRcbiAgICogQGludGVybmFsXG4gICAqL1xuICBzZXRDb25uZWN0ZWQoaXNDb25uZWN0ZWQ6IGJvb2xlYW4pIHtcbiAgICBpZiAodGhpcy5fJHBhcmVudCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLl9faXNDb25uZWN0ZWQgPSBpc0Nvbm5lY3RlZDtcbiAgICAgIHRoaXMuXyRub3RpZnlDb25uZWN0aW9uQ2hhbmdlZD8uKGlzQ29ubmVjdGVkKTtcbiAgICB9IGVsc2UgaWYgKERFVl9NT0RFKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdwYXJ0LnNldENvbm5lY3RlZCgpIG1heSBvbmx5IGJlIGNhbGxlZCBvbiBhICcgK1xuICAgICAgICAgICdSb290UGFydCByZXR1cm5lZCBmcm9tIHJlbmRlcigpLidcbiAgICAgICk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQSB0b3AtbGV2ZWwgYENoaWxkUGFydGAgcmV0dXJuZWQgZnJvbSBgcmVuZGVyYCB0aGF0IG1hbmFnZXMgdGhlIGNvbm5lY3RlZFxuICogc3RhdGUgb2YgYEFzeW5jRGlyZWN0aXZlYHMgY3JlYXRlZCB0aHJvdWdob3V0IHRoZSB0cmVlIGJlbG93IGl0LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJvb3RQYXJ0IGV4dGVuZHMgQ2hpbGRQYXJ0IHtcbiAgLyoqXG4gICAqIFNldHMgdGhlIGNvbm5lY3Rpb24gc3RhdGUgZm9yIGBBc3luY0RpcmVjdGl2ZWBzIGNvbnRhaW5lZCB3aXRoaW4gdGhpcyByb290XG4gICAqIENoaWxkUGFydC5cbiAgICpcbiAgICogbGl0LWh0bWwgZG9lcyBub3QgYXV0b21hdGljYWxseSBtb25pdG9yIHRoZSBjb25uZWN0ZWRuZXNzIG9mIERPTSByZW5kZXJlZDtcbiAgICogYXMgc3VjaCwgaXQgaXMgdGhlIHJlc3BvbnNpYmlsaXR5IG9mIHRoZSBjYWxsZXIgdG8gYHJlbmRlcmAgdG8gZW5zdXJlIHRoYXRcbiAgICogYHBhcnQuc2V0Q29ubmVjdGVkKGZhbHNlKWAgaXMgY2FsbGVkIGJlZm9yZSB0aGUgcGFydCBvYmplY3QgaXMgcG90ZW50aWFsbHlcbiAgICogZGlzY2FyZGVkLCB0byBlbnN1cmUgdGhhdCBgQXN5bmNEaXJlY3RpdmVgcyBoYXZlIGEgY2hhbmNlIHRvIGRpc3Bvc2Ugb2ZcbiAgICogYW55IHJlc291cmNlcyBiZWluZyBoZWxkLiBJZiBhIGBSb290UGFydGAgdGhhdCB3YXMgcHJldmlvdXNseVxuICAgKiBkaXNjb25uZWN0ZWQgaXMgc3Vic2VxdWVudGx5IHJlLWNvbm5lY3RlZCAoYW5kIGl0cyBgQXN5bmNEaXJlY3RpdmVgcyBzaG91bGRcbiAgICogcmUtY29ubmVjdCksIGBzZXRDb25uZWN0ZWQodHJ1ZSlgIHNob3VsZCBiZSBjYWxsZWQuXG4gICAqXG4gICAqIEBwYXJhbSBpc0Nvbm5lY3RlZCBXaGV0aGVyIGRpcmVjdGl2ZXMgd2l0aGluIHRoaXMgdHJlZSBzaG91bGQgYmUgY29ubmVjdGVkXG4gICAqIG9yIG5vdFxuICAgKi9cbiAgc2V0Q29ubmVjdGVkKGlzQ29ubmVjdGVkOiBib29sZWFuKTogdm9pZDtcbn1cblxuZXhwb3J0IHR5cGUge0F0dHJpYnV0ZVBhcnR9O1xuY2xhc3MgQXR0cmlidXRlUGFydCBpbXBsZW1lbnRzIERpc2Nvbm5lY3RhYmxlIHtcbiAgcmVhZG9ubHkgdHlwZTpcbiAgICB8IHR5cGVvZiBBVFRSSUJVVEVfUEFSVFxuICAgIHwgdHlwZW9mIFBST1BFUlRZX1BBUlRcbiAgICB8IHR5cGVvZiBCT09MRUFOX0FUVFJJQlVURV9QQVJUXG4gICAgfCB0eXBlb2YgRVZFTlRfUEFSVCA9IEFUVFJJQlVURV9QQVJUO1xuICByZWFkb25seSBlbGVtZW50OiBIVE1MRWxlbWVudDtcbiAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuICByZWFkb25seSBvcHRpb25zOiBSZW5kZXJPcHRpb25zIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBJZiB0aGlzIGF0dHJpYnV0ZSBwYXJ0IHJlcHJlc2VudHMgYW4gaW50ZXJwb2xhdGlvbiwgdGhpcyBjb250YWlucyB0aGVcbiAgICogc3RhdGljIHN0cmluZ3Mgb2YgdGhlIGludGVycG9sYXRpb24uIEZvciBzaW5nbGUtdmFsdWUsIGNvbXBsZXRlIGJpbmRpbmdzLFxuICAgKiB0aGlzIGlzIHVuZGVmaW5lZC5cbiAgICovXG4gIHJlYWRvbmx5IHN0cmluZ3M/OiBSZWFkb25seUFycmF5PHN0cmluZz47XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgXyRjb21taXR0ZWRWYWx1ZTogdW5rbm93biB8IEFycmF5PHVua25vd24+ID0gbm90aGluZztcbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBfX2RpcmVjdGl2ZXM/OiBBcnJheTxEaXJlY3RpdmUgfCB1bmRlZmluZWQ+O1xuICAvKiogQGludGVybmFsICovXG4gIF8kcGFyZW50OiBEaXNjb25uZWN0YWJsZTtcbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBfJGRpc2Nvbm5lY3RhYmxlQ2hpbGRyZW4/OiBTZXQ8RGlzY29ubmVjdGFibGU+ID0gdW5kZWZpbmVkO1xuXG4gIHByb3RlY3RlZCBfc2FuaXRpemVyOiBWYWx1ZVNhbml0aXplciB8IHVuZGVmaW5lZDtcblxuICBnZXQgdGFnTmFtZSgpIHtcbiAgICByZXR1cm4gdGhpcy5lbGVtZW50LnRhZ05hbWU7XG4gIH1cblxuICAvLyBTZWUgY29tbWVudCBpbiBEaXNjb25uZWN0YWJsZSBpbnRlcmZhY2UgZm9yIHdoeSB0aGlzIGlzIGEgZ2V0dGVyXG4gIGdldCBfJGlzQ29ubmVjdGVkKCkge1xuICAgIHJldHVybiB0aGlzLl8kcGFyZW50Ll8kaXNDb25uZWN0ZWQ7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBlbGVtZW50OiBIVE1MRWxlbWVudCxcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgc3RyaW5nczogUmVhZG9ubHlBcnJheTxzdHJpbmc+LFxuICAgIHBhcmVudDogRGlzY29ubmVjdGFibGUsXG4gICAgb3B0aW9uczogUmVuZGVyT3B0aW9ucyB8IHVuZGVmaW5lZFxuICApIHtcbiAgICB0aGlzLmVsZW1lbnQgPSBlbGVtZW50O1xuICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgdGhpcy5fJHBhcmVudCA9IHBhcmVudDtcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgIGlmIChzdHJpbmdzLmxlbmd0aCA+IDIgfHwgc3RyaW5nc1swXSAhPT0gJycgfHwgc3RyaW5nc1sxXSAhPT0gJycpIHtcbiAgICAgIHRoaXMuXyRjb21taXR0ZWRWYWx1ZSA9IG5ldyBBcnJheShzdHJpbmdzLmxlbmd0aCAtIDEpLmZpbGwobmV3IFN0cmluZygpKTtcbiAgICAgIHRoaXMuc3RyaW5ncyA9IHN0cmluZ3M7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuXyRjb21taXR0ZWRWYWx1ZSA9IG5vdGhpbmc7XG4gICAgfVxuICAgIGlmIChFTkFCTEVfRVhUUkFfU0VDVVJJVFlfSE9PS1MpIHtcbiAgICAgIHRoaXMuX3Nhbml0aXplciA9IHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgdmFsdWUgb2YgdGhpcyBwYXJ0IGJ5IHJlc29sdmluZyB0aGUgdmFsdWUgZnJvbSBwb3NzaWJseSBtdWx0aXBsZVxuICAgKiB2YWx1ZXMgYW5kIHN0YXRpYyBzdHJpbmdzIGFuZCBjb21taXR0aW5nIGl0IHRvIHRoZSBET00uXG4gICAqIElmIHRoaXMgcGFydCBpcyBzaW5nbGUtdmFsdWVkLCBgdGhpcy5fc3RyaW5nc2Agd2lsbCBiZSB1bmRlZmluZWQsIGFuZCB0aGVcbiAgICogbWV0aG9kIHdpbGwgYmUgY2FsbGVkIHdpdGggYSBzaW5nbGUgdmFsdWUgYXJndW1lbnQuIElmIHRoaXMgcGFydCBpc1xuICAgKiBtdWx0aS12YWx1ZSwgYHRoaXMuX3N0cmluZ3NgIHdpbGwgYmUgZGVmaW5lZCwgYW5kIHRoZSBtZXRob2QgaXMgY2FsbGVkXG4gICAqIHdpdGggdGhlIHZhbHVlIGFycmF5IG9mIHRoZSBwYXJ0J3Mgb3duaW5nIFRlbXBsYXRlSW5zdGFuY2UsIGFuZCBhbiBvZmZzZXRcbiAgICogaW50byB0aGUgdmFsdWUgYXJyYXkgZnJvbSB3aGljaCB0aGUgdmFsdWVzIHNob3VsZCBiZSByZWFkLlxuICAgKiBUaGlzIG1ldGhvZCBpcyBvdmVybG9hZGVkIHRoaXMgd2F5IHRvIGVsaW1pbmF0ZSBzaG9ydC1saXZlZCBhcnJheSBzbGljZXNcbiAgICogb2YgdGhlIHRlbXBsYXRlIGluc3RhbmNlIHZhbHVlcywgYW5kIGFsbG93IGEgZmFzdC1wYXRoIGZvciBzaW5nbGUtdmFsdWVkXG4gICAqIHBhcnRzLlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHBhcnQgdmFsdWUsIG9yIGFuIGFycmF5IG9mIHZhbHVlcyBmb3IgbXVsdGktdmFsdWVkIHBhcnRzXG4gICAqIEBwYXJhbSB2YWx1ZUluZGV4IHRoZSBpbmRleCB0byBzdGFydCByZWFkaW5nIHZhbHVlcyBmcm9tLiBgdW5kZWZpbmVkYCBmb3JcbiAgICogICBzaW5nbGUtdmFsdWVkIHBhcnRzXG4gICAqIEBwYXJhbSBub0NvbW1pdCBjYXVzZXMgdGhlIHBhcnQgdG8gbm90IGNvbW1pdCBpdHMgdmFsdWUgdG8gdGhlIERPTS4gVXNlZFxuICAgKiAgIGluIGh5ZHJhdGlvbiB0byBwcmltZSBhdHRyaWJ1dGUgcGFydHMgd2l0aCB0aGVpciBmaXJzdC1yZW5kZXJlZCB2YWx1ZSxcbiAgICogICBidXQgbm90IHNldCB0aGUgYXR0cmlidXRlLCBhbmQgaW4gU1NSIHRvIG5vLW9wIHRoZSBET00gb3BlcmF0aW9uIGFuZFxuICAgKiAgIGNhcHR1cmUgdGhlIHZhbHVlIGZvciBzZXJpYWxpemF0aW9uLlxuICAgKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIF8kc2V0VmFsdWUoXG4gICAgdmFsdWU6IHVua25vd24gfCBBcnJheTx1bmtub3duPixcbiAgICBkaXJlY3RpdmVQYXJlbnQ6IERpcmVjdGl2ZVBhcmVudCA9IHRoaXMsXG4gICAgdmFsdWVJbmRleD86IG51bWJlcixcbiAgICBub0NvbW1pdD86IGJvb2xlYW5cbiAgKSB7XG4gICAgY29uc3Qgc3RyaW5ncyA9IHRoaXMuc3RyaW5ncztcblxuICAgIC8vIFdoZXRoZXIgYW55IG9mIHRoZSB2YWx1ZXMgaGFzIGNoYW5nZWQsIGZvciBkaXJ0eS1jaGVja2luZ1xuICAgIGxldCBjaGFuZ2UgPSBmYWxzZTtcblxuICAgIGlmIChzdHJpbmdzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIC8vIFNpbmdsZS12YWx1ZSBiaW5kaW5nIGNhc2VcbiAgICAgIHZhbHVlID0gcmVzb2x2ZURpcmVjdGl2ZSh0aGlzLCB2YWx1ZSwgZGlyZWN0aXZlUGFyZW50LCAwKTtcbiAgICAgIGNoYW5nZSA9XG4gICAgICAgICFpc1ByaW1pdGl2ZSh2YWx1ZSkgfHxcbiAgICAgICAgKHZhbHVlICE9PSB0aGlzLl8kY29tbWl0dGVkVmFsdWUgJiYgdmFsdWUgIT09IG5vQ2hhbmdlKTtcbiAgICAgIGlmIChjaGFuZ2UpIHtcbiAgICAgICAgdGhpcy5fJGNvbW1pdHRlZFZhbHVlID0gdmFsdWU7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEludGVycG9sYXRpb24gY2FzZVxuICAgICAgY29uc3QgdmFsdWVzID0gdmFsdWUgYXMgQXJyYXk8dW5rbm93bj47XG4gICAgICB2YWx1ZSA9IHN0cmluZ3NbMF07XG5cbiAgICAgIGxldCBpLCB2O1xuICAgICAgZm9yIChpID0gMDsgaSA8IHN0cmluZ3MubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgIHYgPSByZXNvbHZlRGlyZWN0aXZlKHRoaXMsIHZhbHVlc1t2YWx1ZUluZGV4ISArIGldLCBkaXJlY3RpdmVQYXJlbnQsIGkpO1xuXG4gICAgICAgIGlmICh2ID09PSBub0NoYW5nZSkge1xuICAgICAgICAgIC8vIElmIHRoZSB1c2VyLXByb3ZpZGVkIHZhbHVlIGlzIGBub0NoYW5nZWAsIHVzZSB0aGUgcHJldmlvdXMgdmFsdWVcbiAgICAgICAgICB2ID0gKHRoaXMuXyRjb21taXR0ZWRWYWx1ZSBhcyBBcnJheTx1bmtub3duPilbaV07XG4gICAgICAgIH1cbiAgICAgICAgY2hhbmdlIHx8PVxuICAgICAgICAgICFpc1ByaW1pdGl2ZSh2KSB8fCB2ICE9PSAodGhpcy5fJGNvbW1pdHRlZFZhbHVlIGFzIEFycmF5PHVua25vd24+KVtpXTtcbiAgICAgICAgaWYgKHYgPT09IG5vdGhpbmcpIHtcbiAgICAgICAgICB2YWx1ZSA9IG5vdGhpbmc7XG4gICAgICAgIH0gZWxzZSBpZiAodmFsdWUgIT09IG5vdGhpbmcpIHtcbiAgICAgICAgICB2YWx1ZSArPSAodiA/PyAnJykgKyBzdHJpbmdzW2kgKyAxXTtcbiAgICAgICAgfVxuICAgICAgICAvLyBXZSBhbHdheXMgcmVjb3JkIGVhY2ggdmFsdWUsIGV2ZW4gaWYgb25lIGlzIGBub3RoaW5nYCwgZm9yIGZ1dHVyZVxuICAgICAgICAvLyBjaGFuZ2UgZGV0ZWN0aW9uLlxuICAgICAgICAodGhpcy5fJGNvbW1pdHRlZFZhbHVlIGFzIEFycmF5PHVua25vd24+KVtpXSA9IHY7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChjaGFuZ2UgJiYgIW5vQ29tbWl0KSB7XG4gICAgICB0aGlzLl9jb21taXRWYWx1ZSh2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBfY29tbWl0VmFsdWUodmFsdWU6IHVua25vd24pIHtcbiAgICBpZiAodmFsdWUgPT09IG5vdGhpbmcpIHtcbiAgICAgICh3cmFwKHRoaXMuZWxlbWVudCkgYXMgRWxlbWVudCkucmVtb3ZlQXR0cmlidXRlKHRoaXMubmFtZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChFTkFCTEVfRVhUUkFfU0VDVVJJVFlfSE9PS1MpIHtcbiAgICAgICAgaWYgKHRoaXMuX3Nhbml0aXplciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhpcy5fc2FuaXRpemVyID0gc2FuaXRpemVyRmFjdG9yeUludGVybmFsKFxuICAgICAgICAgICAgdGhpcy5lbGVtZW50LFxuICAgICAgICAgICAgdGhpcy5uYW1lLFxuICAgICAgICAgICAgJ2F0dHJpYnV0ZSdcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHZhbHVlID0gdGhpcy5fc2FuaXRpemVyKHZhbHVlID8/ICcnKTtcbiAgICAgIH1cbiAgICAgIGRlYnVnTG9nRXZlbnQgJiZcbiAgICAgICAgZGVidWdMb2dFdmVudCh7XG4gICAgICAgICAga2luZDogJ2NvbW1pdCBhdHRyaWJ1dGUnLFxuICAgICAgICAgIGVsZW1lbnQ6IHRoaXMuZWxlbWVudCxcbiAgICAgICAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgb3B0aW9uczogdGhpcy5vcHRpb25zLFxuICAgICAgICB9KTtcbiAgICAgICh3cmFwKHRoaXMuZWxlbWVudCkgYXMgRWxlbWVudCkuc2V0QXR0cmlidXRlKFxuICAgICAgICB0aGlzLm5hbWUsXG4gICAgICAgICh2YWx1ZSA/PyAnJykgYXMgc3RyaW5nXG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgdHlwZSB7UHJvcGVydHlQYXJ0fTtcbmNsYXNzIFByb3BlcnR5UGFydCBleHRlbmRzIEF0dHJpYnV0ZVBhcnQge1xuICBvdmVycmlkZSByZWFkb25seSB0eXBlID0gUFJPUEVSVFlfUEFSVDtcblxuICAvKiogQGludGVybmFsICovXG4gIG92ZXJyaWRlIF9jb21taXRWYWx1ZSh2YWx1ZTogdW5rbm93bikge1xuICAgIGlmIChFTkFCTEVfRVhUUkFfU0VDVVJJVFlfSE9PS1MpIHtcbiAgICAgIGlmICh0aGlzLl9zYW5pdGl6ZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICB0aGlzLl9zYW5pdGl6ZXIgPSBzYW5pdGl6ZXJGYWN0b3J5SW50ZXJuYWwoXG4gICAgICAgICAgdGhpcy5lbGVtZW50LFxuICAgICAgICAgIHRoaXMubmFtZSxcbiAgICAgICAgICAncHJvcGVydHknXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICB2YWx1ZSA9IHRoaXMuX3Nhbml0aXplcih2YWx1ZSk7XG4gICAgfVxuICAgIGRlYnVnTG9nRXZlbnQgJiZcbiAgICAgIGRlYnVnTG9nRXZlbnQoe1xuICAgICAgICBraW5kOiAnY29tbWl0IHByb3BlcnR5JyxcbiAgICAgICAgZWxlbWVudDogdGhpcy5lbGVtZW50LFxuICAgICAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgICAgIHZhbHVlLFxuICAgICAgICBvcHRpb25zOiB0aGlzLm9wdGlvbnMsXG4gICAgICB9KTtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICh0aGlzLmVsZW1lbnQgYXMgYW55KVt0aGlzLm5hbWVdID0gdmFsdWUgPT09IG5vdGhpbmcgPyB1bmRlZmluZWQgOiB2YWx1ZTtcbiAgfVxufVxuXG5leHBvcnQgdHlwZSB7Qm9vbGVhbkF0dHJpYnV0ZVBhcnR9O1xuY2xhc3MgQm9vbGVhbkF0dHJpYnV0ZVBhcnQgZXh0ZW5kcyBBdHRyaWJ1dGVQYXJ0IHtcbiAgb3ZlcnJpZGUgcmVhZG9ubHkgdHlwZSA9IEJPT0xFQU5fQVRUUklCVVRFX1BBUlQ7XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBvdmVycmlkZSBfY29tbWl0VmFsdWUodmFsdWU6IHVua25vd24pIHtcbiAgICBkZWJ1Z0xvZ0V2ZW50ICYmXG4gICAgICBkZWJ1Z0xvZ0V2ZW50KHtcbiAgICAgICAga2luZDogJ2NvbW1pdCBib29sZWFuIGF0dHJpYnV0ZScsXG4gICAgICAgIGVsZW1lbnQ6IHRoaXMuZWxlbWVudCxcbiAgICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgICB2YWx1ZTogISEodmFsdWUgJiYgdmFsdWUgIT09IG5vdGhpbmcpLFxuICAgICAgICBvcHRpb25zOiB0aGlzLm9wdGlvbnMsXG4gICAgICB9KTtcbiAgICAod3JhcCh0aGlzLmVsZW1lbnQpIGFzIEVsZW1lbnQpLnRvZ2dsZUF0dHJpYnV0ZShcbiAgICAgIHRoaXMubmFtZSxcbiAgICAgICEhdmFsdWUgJiYgdmFsdWUgIT09IG5vdGhpbmdcbiAgICApO1xuICB9XG59XG5cbnR5cGUgRXZlbnRMaXN0ZW5lcldpdGhPcHRpb25zID0gRXZlbnRMaXN0ZW5lck9yRXZlbnRMaXN0ZW5lck9iamVjdCAmXG4gIFBhcnRpYWw8QWRkRXZlbnRMaXN0ZW5lck9wdGlvbnM+O1xuXG4vKipcbiAqIEFuIEF0dHJpYnV0ZVBhcnQgdGhhdCBtYW5hZ2VzIGFuIGV2ZW50IGxpc3RlbmVyIHZpYSBhZGQvcmVtb3ZlRXZlbnRMaXN0ZW5lci5cbiAqXG4gKiBUaGlzIHBhcnQgd29ya3MgYnkgYWRkaW5nIGl0c2VsZiBhcyB0aGUgZXZlbnQgbGlzdGVuZXIgb24gYW4gZWxlbWVudCwgdGhlblxuICogZGVsZWdhdGluZyB0byB0aGUgdmFsdWUgcGFzc2VkIHRvIGl0LiBUaGlzIHJlZHVjZXMgdGhlIG51bWJlciBvZiBjYWxscyB0b1xuICogYWRkL3JlbW92ZUV2ZW50TGlzdGVuZXIgaWYgdGhlIGxpc3RlbmVyIGNoYW5nZXMgZnJlcXVlbnRseSwgc3VjaCBhcyB3aGVuIGFuXG4gKiBpbmxpbmUgZnVuY3Rpb24gaXMgdXNlZCBhcyBhIGxpc3RlbmVyLlxuICpcbiAqIEJlY2F1c2UgZXZlbnQgb3B0aW9ucyBhcmUgcGFzc2VkIHdoZW4gYWRkaW5nIGxpc3RlbmVycywgd2UgbXVzdCB0YWtlIGNhc2VcbiAqIHRvIGFkZCBhbmQgcmVtb3ZlIHRoZSBwYXJ0IGFzIGEgbGlzdGVuZXIgd2hlbiB0aGUgZXZlbnQgb3B0aW9ucyBjaGFuZ2UuXG4gKi9cbmV4cG9ydCB0eXBlIHtFdmVudFBhcnR9O1xuY2xhc3MgRXZlbnRQYXJ0IGV4dGVuZHMgQXR0cmlidXRlUGFydCB7XG4gIG92ZXJyaWRlIHJlYWRvbmx5IHR5cGUgPSBFVkVOVF9QQVJUO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIGVsZW1lbnQ6IEhUTUxFbGVtZW50LFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBzdHJpbmdzOiBSZWFkb25seUFycmF5PHN0cmluZz4sXG4gICAgcGFyZW50OiBEaXNjb25uZWN0YWJsZSxcbiAgICBvcHRpb25zOiBSZW5kZXJPcHRpb25zIHwgdW5kZWZpbmVkXG4gICkge1xuICAgIHN1cGVyKGVsZW1lbnQsIG5hbWUsIHN0cmluZ3MsIHBhcmVudCwgb3B0aW9ucyk7XG5cbiAgICBpZiAoREVWX01PREUgJiYgdGhpcy5zdHJpbmdzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEEgXFxgPCR7ZWxlbWVudC5sb2NhbE5hbWV9PlxcYCBoYXMgYSBcXGBAJHtuYW1lfT0uLi5cXGAgbGlzdGVuZXIgd2l0aCBgICtcbiAgICAgICAgICAnaW52YWxpZCBjb250ZW50LiBFdmVudCBsaXN0ZW5lcnMgaW4gdGVtcGxhdGVzIG11c3QgaGF2ZSBleGFjdGx5ICcgK1xuICAgICAgICAgICdvbmUgZXhwcmVzc2lvbiBhbmQgbm8gc3Vycm91bmRpbmcgdGV4dC4nXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8vIEV2ZW50UGFydCBkb2VzIG5vdCB1c2UgdGhlIGJhc2UgXyRzZXRWYWx1ZS9fcmVzb2x2ZVZhbHVlIGltcGxlbWVudGF0aW9uXG4gIC8vIHNpbmNlIHRoZSBkaXJ0eSBjaGVja2luZyBpcyBtb3JlIGNvbXBsZXhcbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBvdmVycmlkZSBfJHNldFZhbHVlKFxuICAgIG5ld0xpc3RlbmVyOiB1bmtub3duLFxuICAgIGRpcmVjdGl2ZVBhcmVudDogRGlyZWN0aXZlUGFyZW50ID0gdGhpc1xuICApIHtcbiAgICBuZXdMaXN0ZW5lciA9XG4gICAgICByZXNvbHZlRGlyZWN0aXZlKHRoaXMsIG5ld0xpc3RlbmVyLCBkaXJlY3RpdmVQYXJlbnQsIDApID8/IG5vdGhpbmc7XG4gICAgaWYgKG5ld0xpc3RlbmVyID09PSBub0NoYW5nZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBvbGRMaXN0ZW5lciA9IHRoaXMuXyRjb21taXR0ZWRWYWx1ZTtcblxuICAgIC8vIElmIHRoZSBuZXcgdmFsdWUgaXMgbm90aGluZyBvciBhbnkgb3B0aW9ucyBjaGFuZ2Ugd2UgaGF2ZSB0byByZW1vdmUgdGhlXG4gICAgLy8gcGFydCBhcyBhIGxpc3RlbmVyLlxuICAgIGNvbnN0IHNob3VsZFJlbW92ZUxpc3RlbmVyID1cbiAgICAgIChuZXdMaXN0ZW5lciA9PT0gbm90aGluZyAmJiBvbGRMaXN0ZW5lciAhPT0gbm90aGluZykgfHxcbiAgICAgIChuZXdMaXN0ZW5lciBhcyBFdmVudExpc3RlbmVyV2l0aE9wdGlvbnMpLmNhcHR1cmUgIT09XG4gICAgICAgIChvbGRMaXN0ZW5lciBhcyBFdmVudExpc3RlbmVyV2l0aE9wdGlvbnMpLmNhcHR1cmUgfHxcbiAgICAgIChuZXdMaXN0ZW5lciBhcyBFdmVudExpc3RlbmVyV2l0aE9wdGlvbnMpLm9uY2UgIT09XG4gICAgICAgIChvbGRMaXN0ZW5lciBhcyBFdmVudExpc3RlbmVyV2l0aE9wdGlvbnMpLm9uY2UgfHxcbiAgICAgIChuZXdMaXN0ZW5lciBhcyBFdmVudExpc3RlbmVyV2l0aE9wdGlvbnMpLnBhc3NpdmUgIT09XG4gICAgICAgIChvbGRMaXN0ZW5lciBhcyBFdmVudExpc3RlbmVyV2l0aE9wdGlvbnMpLnBhc3NpdmU7XG5cbiAgICAvLyBJZiB0aGUgbmV3IHZhbHVlIGlzIG5vdCBub3RoaW5nIGFuZCB3ZSByZW1vdmVkIHRoZSBsaXN0ZW5lciwgd2UgaGF2ZVxuICAgIC8vIHRvIGFkZCB0aGUgcGFydCBhcyBhIGxpc3RlbmVyLlxuICAgIGNvbnN0IHNob3VsZEFkZExpc3RlbmVyID1cbiAgICAgIG5ld0xpc3RlbmVyICE9PSBub3RoaW5nICYmXG4gICAgICAob2xkTGlzdGVuZXIgPT09IG5vdGhpbmcgfHwgc2hvdWxkUmVtb3ZlTGlzdGVuZXIpO1xuXG4gICAgZGVidWdMb2dFdmVudCAmJlxuICAgICAgZGVidWdMb2dFdmVudCh7XG4gICAgICAgIGtpbmQ6ICdjb21taXQgZXZlbnQgbGlzdGVuZXInLFxuICAgICAgICBlbGVtZW50OiB0aGlzLmVsZW1lbnQsXG4gICAgICAgIG5hbWU6IHRoaXMubmFtZSxcbiAgICAgICAgdmFsdWU6IG5ld0xpc3RlbmVyLFxuICAgICAgICBvcHRpb25zOiB0aGlzLm9wdGlvbnMsXG4gICAgICAgIHJlbW92ZUxpc3RlbmVyOiBzaG91bGRSZW1vdmVMaXN0ZW5lcixcbiAgICAgICAgYWRkTGlzdGVuZXI6IHNob3VsZEFkZExpc3RlbmVyLFxuICAgICAgICBvbGRMaXN0ZW5lcixcbiAgICAgIH0pO1xuICAgIGlmIChzaG91bGRSZW1vdmVMaXN0ZW5lcikge1xuICAgICAgdGhpcy5lbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXG4gICAgICAgIHRoaXMubmFtZSxcbiAgICAgICAgdGhpcyxcbiAgICAgICAgb2xkTGlzdGVuZXIgYXMgRXZlbnRMaXN0ZW5lcldpdGhPcHRpb25zXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAoc2hvdWxkQWRkTGlzdGVuZXIpIHtcbiAgICAgIHRoaXMuZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKFxuICAgICAgICB0aGlzLm5hbWUsXG4gICAgICAgIHRoaXMsXG4gICAgICAgIG5ld0xpc3RlbmVyIGFzIEV2ZW50TGlzdGVuZXJXaXRoT3B0aW9uc1xuICAgICAgKTtcbiAgICB9XG4gICAgdGhpcy5fJGNvbW1pdHRlZFZhbHVlID0gbmV3TGlzdGVuZXI7XG4gIH1cblxuICBoYW5kbGVFdmVudChldmVudDogRXZlbnQpIHtcbiAgICBpZiAodHlwZW9mIHRoaXMuXyRjb21taXR0ZWRWYWx1ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhpcy5fJGNvbW1pdHRlZFZhbHVlLmNhbGwodGhpcy5vcHRpb25zPy5ob3N0ID8/IHRoaXMuZWxlbWVudCwgZXZlbnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICAodGhpcy5fJGNvbW1pdHRlZFZhbHVlIGFzIEV2ZW50TGlzdGVuZXJPYmplY3QpLmhhbmRsZUV2ZW50KGV2ZW50KTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IHR5cGUge0VsZW1lbnRQYXJ0fTtcbmNsYXNzIEVsZW1lbnRQYXJ0IGltcGxlbWVudHMgRGlzY29ubmVjdGFibGUge1xuICByZWFkb25seSB0eXBlID0gRUxFTUVOVF9QQVJUO1xuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX19kaXJlY3RpdmU/OiBEaXJlY3RpdmU7XG5cbiAgLy8gVGhpcyBpcyB0byBlbnN1cmUgdGhhdCBldmVyeSBQYXJ0IGhhcyBhIF8kY29tbWl0dGVkVmFsdWVcbiAgXyRjb21taXR0ZWRWYWx1ZTogdW5kZWZpbmVkO1xuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgXyRwYXJlbnQhOiBEaXNjb25uZWN0YWJsZTtcblxuICAvKiogQGludGVybmFsICovXG4gIF8kZGlzY29ubmVjdGFibGVDaGlsZHJlbj86IFNldDxEaXNjb25uZWN0YWJsZT4gPSB1bmRlZmluZWQ7XG5cbiAgb3B0aW9uczogUmVuZGVyT3B0aW9ucyB8IHVuZGVmaW5lZDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgZWxlbWVudDogRWxlbWVudCxcbiAgICBwYXJlbnQ6IERpc2Nvbm5lY3RhYmxlLFxuICAgIG9wdGlvbnM6IFJlbmRlck9wdGlvbnMgfCB1bmRlZmluZWRcbiAgKSB7XG4gICAgdGhpcy5fJHBhcmVudCA9IHBhcmVudDtcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICB9XG5cbiAgLy8gU2VlIGNvbW1lbnQgaW4gRGlzY29ubmVjdGFibGUgaW50ZXJmYWNlIGZvciB3aHkgdGhpcyBpcyBhIGdldHRlclxuICBnZXQgXyRpc0Nvbm5lY3RlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fJHBhcmVudC5fJGlzQ29ubmVjdGVkO1xuICB9XG5cbiAgXyRzZXRWYWx1ZSh2YWx1ZTogdW5rbm93bik6IHZvaWQge1xuICAgIGRlYnVnTG9nRXZlbnQgJiZcbiAgICAgIGRlYnVnTG9nRXZlbnQoe1xuICAgICAgICBraW5kOiAnY29tbWl0IHRvIGVsZW1lbnQgYmluZGluZycsXG4gICAgICAgIGVsZW1lbnQ6IHRoaXMuZWxlbWVudCxcbiAgICAgICAgdmFsdWUsXG4gICAgICAgIG9wdGlvbnM6IHRoaXMub3B0aW9ucyxcbiAgICAgIH0pO1xuICAgIHJlc29sdmVEaXJlY3RpdmUodGhpcywgdmFsdWUpO1xuICB9XG59XG5cbi8qKlxuICogRU5EIFVTRVJTIFNIT1VMRCBOT1QgUkVMWSBPTiBUSElTIE9CSkVDVC5cbiAqXG4gKiBQcml2YXRlIGV4cG9ydHMgZm9yIHVzZSBieSBvdGhlciBMaXQgcGFja2FnZXMsIG5vdCBpbnRlbmRlZCBmb3IgdXNlIGJ5XG4gKiBleHRlcm5hbCB1c2Vycy5cbiAqXG4gKiBXZSBjdXJyZW50bHkgZG8gbm90IG1ha2UgYSBtYW5nbGVkIHJvbGx1cCBidWlsZCBvZiB0aGUgbGl0LXNzciBjb2RlLiBJbiBvcmRlclxuICogdG8ga2VlcCBhIG51bWJlciBvZiAob3RoZXJ3aXNlIHByaXZhdGUpIHRvcC1sZXZlbCBleHBvcnRzIG1hbmdsZWQgaW4gdGhlXG4gKiBjbGllbnQgc2lkZSBjb2RlLCB3ZSBleHBvcnQgYSBfJExIIG9iamVjdCBjb250YWluaW5nIHRob3NlIG1lbWJlcnMgKG9yXG4gKiBoZWxwZXIgbWV0aG9kcyBmb3IgYWNjZXNzaW5nIHByaXZhdGUgZmllbGRzIG9mIHRob3NlIG1lbWJlcnMpLCBhbmQgdGhlblxuICogcmUtZXhwb3J0IHRoZW0gZm9yIHVzZSBpbiBsaXQtc3NyLiBUaGlzIGtlZXBzIGxpdC1zc3IgYWdub3N0aWMgdG8gd2hldGhlciB0aGVcbiAqIGNsaWVudC1zaWRlIGNvZGUgaXMgYmVpbmcgdXNlZCBpbiBgZGV2YCBtb2RlIG9yIGBwcm9kYCBtb2RlLlxuICpcbiAqIFRoaXMgaGFzIGEgdW5pcXVlIG5hbWUsIHRvIGRpc2FtYmlndWF0ZSBpdCBmcm9tIHByaXZhdGUgZXhwb3J0cyBpblxuICogbGl0LWVsZW1lbnQsIHdoaWNoIHJlLWV4cG9ydHMgYWxsIG9mIGxpdC1odG1sLlxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmV4cG9ydCBjb25zdCBfJExIID0ge1xuICAvLyBVc2VkIGluIGxpdC1zc3JcbiAgX2JvdW5kQXR0cmlidXRlU3VmZml4OiBib3VuZEF0dHJpYnV0ZVN1ZmZpeCxcbiAgX21hcmtlcjogbWFya2VyLFxuICBfbWFya2VyTWF0Y2g6IG1hcmtlck1hdGNoLFxuICBfSFRNTF9SRVNVTFQ6IEhUTUxfUkVTVUxULFxuICBfZ2V0VGVtcGxhdGVIdG1sOiBnZXRUZW1wbGF0ZUh0bWwsXG4gIC8vIFVzZWQgaW4gdGVzdHMgYW5kIHByaXZhdGUtc3NyLXN1cHBvcnRcbiAgX1RlbXBsYXRlSW5zdGFuY2U6IFRlbXBsYXRlSW5zdGFuY2UsXG4gIF9pc0l0ZXJhYmxlOiBpc0l0ZXJhYmxlLFxuICBfcmVzb2x2ZURpcmVjdGl2ZTogcmVzb2x2ZURpcmVjdGl2ZSxcbiAgX0NoaWxkUGFydDogQ2hpbGRQYXJ0LFxuICBfQXR0cmlidXRlUGFydDogQXR0cmlidXRlUGFydCxcbiAgX0Jvb2xlYW5BdHRyaWJ1dGVQYXJ0OiBCb29sZWFuQXR0cmlidXRlUGFydCxcbiAgX0V2ZW50UGFydDogRXZlbnRQYXJ0LFxuICBfUHJvcGVydHlQYXJ0OiBQcm9wZXJ0eVBhcnQsXG4gIF9FbGVtZW50UGFydDogRWxlbWVudFBhcnQsXG59O1xuXG4vLyBBcHBseSBwb2x5ZmlsbHMgaWYgYXZhaWxhYmxlXG5jb25zdCBwb2x5ZmlsbFN1cHBvcnQgPSBERVZfTU9ERVxuICA/IGdsb2JhbC5saXRIdG1sUG9seWZpbGxTdXBwb3J0RGV2TW9kZVxuICA6IGdsb2JhbC5saXRIdG1sUG9seWZpbGxTdXBwb3J0O1xucG9seWZpbGxTdXBwb3J0Py4oVGVtcGxhdGUsIENoaWxkUGFydCk7XG5cbi8vIElNUE9SVEFOVDogZG8gbm90IGNoYW5nZSB0aGUgcHJvcGVydHkgbmFtZSBvciB0aGUgYXNzaWdubWVudCBleHByZXNzaW9uLlxuLy8gVGhpcyBsaW5lIHdpbGwgYmUgdXNlZCBpbiByZWdleGVzIHRvIHNlYXJjaCBmb3IgbGl0LWh0bWwgdXNhZ2UuXG4oZ2xvYmFsLmxpdEh0bWxWZXJzaW9ucyA/Pz0gW10pLnB1c2goJzMuMy4wJyk7XG5pZiAoREVWX01PREUgJiYgZ2xvYmFsLmxpdEh0bWxWZXJzaW9ucy5sZW5ndGggPiAxKSB7XG4gIHF1ZXVlTWljcm90YXNrKCgpID0+IHtcbiAgICBpc3N1ZVdhcm5pbmchKFxuICAgICAgJ211bHRpcGxlLXZlcnNpb25zJyxcbiAgICAgIGBNdWx0aXBsZSB2ZXJzaW9ucyBvZiBMaXQgbG9hZGVkLiBgICtcbiAgICAgICAgYExvYWRpbmcgbXVsdGlwbGUgdmVyc2lvbnMgaXMgbm90IHJlY29tbWVuZGVkLmBcbiAgICApO1xuICB9KTtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIGEgdmFsdWUsIHVzdWFsbHkgYSBsaXQtaHRtbCBUZW1wbGF0ZVJlc3VsdCwgdG8gdGhlIGNvbnRhaW5lci5cbiAqXG4gKiBUaGlzIGV4YW1wbGUgcmVuZGVycyB0aGUgdGV4dCBcIkhlbGxvLCBab2UhXCIgaW5zaWRlIGEgcGFyYWdyYXBoIHRhZywgYXBwZW5kaW5nXG4gKiBpdCB0byB0aGUgY29udGFpbmVyIGBkb2N1bWVudC5ib2R5YC5cbiAqXG4gKiBgYGBqc1xuICogaW1wb3J0IHtodG1sLCByZW5kZXJ9IGZyb20gJ2xpdCc7XG4gKlxuICogY29uc3QgbmFtZSA9IFwiWm9lXCI7XG4gKiByZW5kZXIoaHRtbGA8cD5IZWxsbywgJHtuYW1lfSE8L3A+YCwgZG9jdW1lbnQuYm9keSk7XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0gdmFsdWUgQW55IFtyZW5kZXJhYmxlXG4gKiAgIHZhbHVlXShodHRwczovL2xpdC5kZXYvZG9jcy90ZW1wbGF0ZXMvZXhwcmVzc2lvbnMvI2NoaWxkLWV4cHJlc3Npb25zKSxcbiAqICAgdHlwaWNhbGx5IGEge0BsaW5rY29kZSBUZW1wbGF0ZVJlc3VsdH0gY3JlYXRlZCBieSBldmFsdWF0aW5nIGEgdGVtcGxhdGUgdGFnXG4gKiAgIGxpa2Uge0BsaW5rY29kZSBodG1sfSBvciB7QGxpbmtjb2RlIHN2Z30uXG4gKiBAcGFyYW0gY29udGFpbmVyIEEgRE9NIGNvbnRhaW5lciB0byByZW5kZXIgdG8uIFRoZSBmaXJzdCByZW5kZXIgd2lsbCBhcHBlbmRcbiAqICAgdGhlIHJlbmRlcmVkIHZhbHVlIHRvIHRoZSBjb250YWluZXIsIGFuZCBzdWJzZXF1ZW50IHJlbmRlcnMgd2lsbFxuICogICBlZmZpY2llbnRseSB1cGRhdGUgdGhlIHJlbmRlcmVkIHZhbHVlIGlmIHRoZSBzYW1lIHJlc3VsdCB0eXBlIHdhc1xuICogICBwcmV2aW91c2x5IHJlbmRlcmVkIHRoZXJlLlxuICogQHBhcmFtIG9wdGlvbnMgU2VlIHtAbGlua2NvZGUgUmVuZGVyT3B0aW9uc30gZm9yIG9wdGlvbnMgZG9jdW1lbnRhdGlvbi5cbiAqIEBzZWVcbiAqIHtAbGluayBodHRwczovL2xpdC5kZXYvZG9jcy9saWJyYXJpZXMvc3RhbmRhbG9uZS10ZW1wbGF0ZXMvI3JlbmRlcmluZy1saXQtaHRtbC10ZW1wbGF0ZXN8IFJlbmRlcmluZyBMaXQgSFRNTCBUZW1wbGF0ZXN9XG4gKi9cbmV4cG9ydCBjb25zdCByZW5kZXIgPSAoXG4gIHZhbHVlOiB1bmtub3duLFxuICBjb250YWluZXI6IEhUTUxFbGVtZW50IHwgRG9jdW1lbnRGcmFnbWVudCxcbiAgb3B0aW9ucz86IFJlbmRlck9wdGlvbnNcbik6IFJvb3RQYXJ0ID0+IHtcbiAgaWYgKERFVl9NT0RFICYmIGNvbnRhaW5lciA9PSBudWxsKSB7XG4gICAgLy8gR2l2ZSBhIGNsZWFyZXIgZXJyb3IgbWVzc2FnZSB0aGFuXG4gICAgLy8gICAgIFVuY2F1Z2h0IFR5cGVFcnJvcjogQ2Fubm90IHJlYWQgcHJvcGVydGllcyBvZiBudWxsIChyZWFkaW5nXG4gICAgLy8gICAgICdfJGxpdFBhcnQkJylcbiAgICAvLyB3aGljaCByZWFkcyBsaWtlIGFuIGludGVybmFsIExpdCBlcnJvci5cbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBUaGUgY29udGFpbmVyIHRvIHJlbmRlciBpbnRvIG1heSBub3QgYmUgJHtjb250YWluZXJ9YCk7XG4gIH1cbiAgY29uc3QgcmVuZGVySWQgPSBERVZfTU9ERSA/IGRlYnVnTG9nUmVuZGVySWQrKyA6IDA7XG4gIGNvbnN0IHBhcnRPd25lck5vZGUgPSBvcHRpb25zPy5yZW5kZXJCZWZvcmUgPz8gY29udGFpbmVyO1xuICAvLyBUaGlzIHByb3BlcnR5IG5lZWRzIHRvIHJlbWFpbiB1bm1pbmlmaWVkLlxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICBsZXQgcGFydDogQ2hpbGRQYXJ0ID0gKHBhcnRPd25lck5vZGUgYXMgYW55KVsnXyRsaXRQYXJ0JCddO1xuICBkZWJ1Z0xvZ0V2ZW50ICYmXG4gICAgZGVidWdMb2dFdmVudCh7XG4gICAgICBraW5kOiAnYmVnaW4gcmVuZGVyJyxcbiAgICAgIGlkOiByZW5kZXJJZCxcbiAgICAgIHZhbHVlLFxuICAgICAgY29udGFpbmVyLFxuICAgICAgb3B0aW9ucyxcbiAgICAgIHBhcnQsXG4gICAgfSk7XG4gIGlmIChwYXJ0ID09PSB1bmRlZmluZWQpIHtcbiAgICBjb25zdCBlbmROb2RlID0gb3B0aW9ucz8ucmVuZGVyQmVmb3JlID8/IG51bGw7XG4gICAgLy8gVGhpcyBwcm9wZXJ0eSBuZWVkcyB0byByZW1haW4gdW5taW5pZmllZC5cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgIChwYXJ0T3duZXJOb2RlIGFzIGFueSlbJ18kbGl0UGFydCQnXSA9IHBhcnQgPSBuZXcgQ2hpbGRQYXJ0KFxuICAgICAgY29udGFpbmVyLmluc2VydEJlZm9yZShjcmVhdGVNYXJrZXIoKSwgZW5kTm9kZSksXG4gICAgICBlbmROb2RlLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgb3B0aW9ucyA/PyB7fVxuICAgICk7XG4gIH1cbiAgcGFydC5fJHNldFZhbHVlKHZhbHVlKTtcbiAgZGVidWdMb2dFdmVudCAmJlxuICAgIGRlYnVnTG9nRXZlbnQoe1xuICAgICAga2luZDogJ2VuZCByZW5kZXInLFxuICAgICAgaWQ6IHJlbmRlcklkLFxuICAgICAgdmFsdWUsXG4gICAgICBjb250YWluZXIsXG4gICAgICBvcHRpb25zLFxuICAgICAgcGFydCxcbiAgICB9KTtcbiAgcmV0dXJuIHBhcnQgYXMgUm9vdFBhcnQ7XG59O1xuXG5pZiAoRU5BQkxFX0VYVFJBX1NFQ1VSSVRZX0hPT0tTKSB7XG4gIHJlbmRlci5zZXRTYW5pdGl6ZXIgPSBzZXRTYW5pdGl6ZXI7XG4gIHJlbmRlci5jcmVhdGVTYW5pdGl6ZXIgPSBjcmVhdGVTYW5pdGl6ZXI7XG4gIGlmIChERVZfTU9ERSkge1xuICAgIHJlbmRlci5fdGVzdE9ubHlDbGVhclNhbml0aXplckZhY3RvcnlEb05vdENhbGxPckVsc2UgPVxuICAgICAgX3Rlc3RPbmx5Q2xlYXJTYW5pdGl6ZXJGYWN0b3J5RG9Ob3RDYWxsT3JFbHNlO1xuICB9XG59XG4iLCAiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQ1xuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEJTRC0zLUNsYXVzZVxuICovXG5cbi8qKlxuICogVGhlIG1haW4gTGl0RWxlbWVudCBtb2R1bGUsIHdoaWNoIGRlZmluZXMgdGhlIHtAbGlua2NvZGUgTGl0RWxlbWVudH0gYmFzZVxuICogY2xhc3MgYW5kIHJlbGF0ZWQgQVBJcy5cbiAqXG4gKiBMaXRFbGVtZW50IGNvbXBvbmVudHMgY2FuIGRlZmluZSBhIHRlbXBsYXRlIGFuZCBhIHNldCBvZiBvYnNlcnZlZFxuICogcHJvcGVydGllcy4gQ2hhbmdpbmcgYW4gb2JzZXJ2ZWQgcHJvcGVydHkgdHJpZ2dlcnMgYSByZS1yZW5kZXIgb2YgdGhlXG4gKiBlbGVtZW50LlxuICpcbiAqIEltcG9ydCB7QGxpbmtjb2RlIExpdEVsZW1lbnR9IGFuZCB7QGxpbmtjb2RlIGh0bWx9IGZyb20gdGhpcyBtb2R1bGUgdG9cbiAqIGNyZWF0ZSBhIGNvbXBvbmVudDpcbiAqXG4gKiAgYGBganNcbiAqIGltcG9ydCB7TGl0RWxlbWVudCwgaHRtbH0gZnJvbSAnbGl0LWVsZW1lbnQnO1xuICpcbiAqIGNsYXNzIE15RWxlbWVudCBleHRlbmRzIExpdEVsZW1lbnQge1xuICpcbiAqICAgLy8gRGVjbGFyZSBvYnNlcnZlZCBwcm9wZXJ0aWVzXG4gKiAgIHN0YXRpYyBnZXQgcHJvcGVydGllcygpIHtcbiAqICAgICByZXR1cm4ge1xuICogICAgICAgYWRqZWN0aXZlOiB7fVxuICogICAgIH1cbiAqICAgfVxuICpcbiAqICAgY29uc3RydWN0b3IoKSB7XG4gKiAgICAgdGhpcy5hZGplY3RpdmUgPSAnYXdlc29tZSc7XG4gKiAgIH1cbiAqXG4gKiAgIC8vIERlZmluZSB0aGUgZWxlbWVudCdzIHRlbXBsYXRlXG4gKiAgIHJlbmRlcigpIHtcbiAqICAgICByZXR1cm4gaHRtbGA8cD55b3VyICR7YWRqZWN0aXZlfSB0ZW1wbGF0ZSBoZXJlPC9wPmA7XG4gKiAgIH1cbiAqIH1cbiAqXG4gKiBjdXN0b21FbGVtZW50cy5kZWZpbmUoJ215LWVsZW1lbnQnLCBNeUVsZW1lbnQpO1xuICogYGBgXG4gKlxuICogYExpdEVsZW1lbnRgIGV4dGVuZHMge0BsaW5rY29kZSBSZWFjdGl2ZUVsZW1lbnR9IGFuZCBhZGRzIGxpdC1odG1sXG4gKiB0ZW1wbGF0aW5nLiBUaGUgYFJlYWN0aXZlRWxlbWVudGAgY2xhc3MgaXMgcHJvdmlkZWQgZm9yIHVzZXJzIHRoYXQgd2FudCB0b1xuICogYnVpbGQgdGhlaXIgb3duIGN1c3RvbSBlbGVtZW50IGJhc2UgY2xhc3NlcyB0aGF0IGRvbid0IHVzZSBsaXQtaHRtbC5cbiAqXG4gKiBAcGFja2FnZURvY3VtZW50YXRpb25cbiAqL1xuaW1wb3J0IHtQcm9wZXJ0eVZhbHVlcywgUmVhY3RpdmVFbGVtZW50fSBmcm9tICdAbGl0L3JlYWN0aXZlLWVsZW1lbnQnO1xuaW1wb3J0IHtyZW5kZXIsIFJlbmRlck9wdGlvbnMsIG5vQ2hhbmdlLCBSb290UGFydH0gZnJvbSAnbGl0LWh0bWwnO1xuZXhwb3J0ICogZnJvbSAnQGxpdC9yZWFjdGl2ZS1lbGVtZW50JztcbmV4cG9ydCAqIGZyb20gJ2xpdC1odG1sJztcblxuaW1wb3J0IHtMaXRVbnN0YWJsZX0gZnJvbSAnbGl0LWh0bWwnO1xuaW1wb3J0IHtSZWFjdGl2ZVVuc3RhYmxlfSBmcm9tICdAbGl0L3JlYWN0aXZlLWVsZW1lbnQnO1xuXG4vKipcbiAqIENvbnRhaW5zIHR5cGVzIHRoYXQgYXJlIHBhcnQgb2YgdGhlIHVuc3RhYmxlIGRlYnVnIEFQSS5cbiAqXG4gKiBFdmVyeXRoaW5nIGluIHRoaXMgQVBJIGlzIG5vdCBzdGFibGUgYW5kIG1heSBjaGFuZ2Ugb3IgYmUgcmVtb3ZlZCBpbiB0aGUgZnV0dXJlLFxuICogZXZlbiBvbiBwYXRjaCByZWxlYXNlcy5cbiAqL1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1uYW1lc3BhY2VcbmV4cG9ydCBuYW1lc3BhY2UgVW5zdGFibGUge1xuICAvKipcbiAgICogV2hlbiBMaXQgaXMgcnVubmluZyBpbiBkZXYgbW9kZSBhbmQgYHdpbmRvdy5lbWl0TGl0RGVidWdMb2dFdmVudHNgIGlzIHRydWUsXG4gICAqIHdlIHdpbGwgZW1pdCAnbGl0LWRlYnVnJyBldmVudHMgdG8gd2luZG93LCB3aXRoIGxpdmUgZGV0YWlscyBhYm91dCB0aGUgdXBkYXRlIGFuZCByZW5kZXJcbiAgICogbGlmZWN5Y2xlLiBUaGVzZSBjYW4gYmUgdXNlZnVsIGZvciB3cml0aW5nIGRlYnVnIHRvb2xpbmcgYW5kIHZpc3VhbGl6YXRpb25zLlxuICAgKlxuICAgKiBQbGVhc2UgYmUgYXdhcmUgdGhhdCBydW5uaW5nIHdpdGggd2luZG93LmVtaXRMaXREZWJ1Z0xvZ0V2ZW50cyBoYXMgcGVyZm9ybWFuY2Ugb3ZlcmhlYWQsXG4gICAqIG1ha2luZyBjZXJ0YWluIG9wZXJhdGlvbnMgdGhhdCBhcmUgbm9ybWFsbHkgdmVyeSBjaGVhcCAobGlrZSBhIG5vLW9wIHJlbmRlcikgbXVjaCBzbG93ZXIsXG4gICAqIGJlY2F1c2Ugd2UgbXVzdCBjb3B5IGRhdGEgYW5kIGRpc3BhdGNoIGV2ZW50cy5cbiAgICovXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbmFtZXNwYWNlXG4gIGV4cG9ydCBuYW1lc3BhY2UgRGVidWdMb2cge1xuICAgIGV4cG9ydCB0eXBlIEVudHJ5ID1cbiAgICAgIHwgTGl0VW5zdGFibGUuRGVidWdMb2cuRW50cnlcbiAgICAgIHwgUmVhY3RpdmVVbnN0YWJsZS5EZWJ1Z0xvZy5FbnRyeTtcbiAgfVxufVxuLypcbiAqIFdoZW4gdXNpbmcgQ2xvc3VyZSBDb21waWxlciwgSlNDb21waWxlcl9yZW5hbWVQcm9wZXJ0eShwcm9wZXJ0eSwgb2JqZWN0KSBpc1xuICogcmVwbGFjZWQgYXQgY29tcGlsZSB0aW1lIGJ5IHRoZSBtdW5nZWQgbmFtZSBmb3Igb2JqZWN0W3Byb3BlcnR5XS4gV2UgY2Fubm90XG4gKiBhbGlhcyB0aGlzIGZ1bmN0aW9uLCBzbyB3ZSBoYXZlIHRvIHVzZSBhIHNtYWxsIHNoaW0gdGhhdCBoYXMgdGhlIHNhbWVcbiAqIGJlaGF2aW9yIHdoZW4gbm90IGNvbXBpbGluZy5cbiAqL1xuLypAX19JTkxJTkVfXyovXG5jb25zdCBKU0NvbXBpbGVyX3JlbmFtZVByb3BlcnR5ID0gPFAgZXh0ZW5kcyBQcm9wZXJ0eUtleT4oXG4gIHByb3A6IFAsXG4gIF9vYmo6IHVua25vd25cbik6IFAgPT4gcHJvcDtcblxuY29uc3QgREVWX01PREUgPSB0cnVlO1xuLy8gQWxsb3dzIG1pbmlmaWVycyB0byByZW5hbWUgcmVmZXJlbmNlcyB0byBnbG9iYWxUaGlzXG5jb25zdCBnbG9iYWwgPSBnbG9iYWxUaGlzO1xuXG5sZXQgaXNzdWVXYXJuaW5nOiAoY29kZTogc3RyaW5nLCB3YXJuaW5nOiBzdHJpbmcpID0+IHZvaWQ7XG5cbmlmIChERVZfTU9ERSkge1xuICAvLyBFbnN1cmUgd2FybmluZ3MgYXJlIGlzc3VlZCBvbmx5IDF4LCBldmVuIGlmIG11bHRpcGxlIHZlcnNpb25zIG9mIExpdFxuICAvLyBhcmUgbG9hZGVkLlxuICBnbG9iYWwubGl0SXNzdWVkV2FybmluZ3MgPz89IG5ldyBTZXQoKTtcblxuICAvKipcbiAgICogSXNzdWUgYSB3YXJuaW5nIGlmIHdlIGhhdmVuJ3QgYWxyZWFkeSwgYmFzZWQgZWl0aGVyIG9uIGBjb2RlYCBvciBgd2FybmluZ2AuXG4gICAqIFdhcm5pbmdzIGFyZSBkaXNhYmxlZCBhdXRvbWF0aWNhbGx5IG9ubHkgYnkgYHdhcm5pbmdgOyBkaXNhYmxpbmcgdmlhIGBjb2RlYFxuICAgKiBjYW4gYmUgZG9uZSBieSB1c2Vycy5cbiAgICovXG4gIGlzc3VlV2FybmluZyA9IChjb2RlOiBzdHJpbmcsIHdhcm5pbmc6IHN0cmluZykgPT4ge1xuICAgIHdhcm5pbmcgKz0gYCBTZWUgaHR0cHM6Ly9saXQuZGV2L21zZy8ke2NvZGV9IGZvciBtb3JlIGluZm9ybWF0aW9uLmA7XG4gICAgaWYgKFxuICAgICAgIWdsb2JhbC5saXRJc3N1ZWRXYXJuaW5ncyEuaGFzKHdhcm5pbmcpICYmXG4gICAgICAhZ2xvYmFsLmxpdElzc3VlZFdhcm5pbmdzIS5oYXMoY29kZSlcbiAgICApIHtcbiAgICAgIGNvbnNvbGUud2Fybih3YXJuaW5nKTtcbiAgICAgIGdsb2JhbC5saXRJc3N1ZWRXYXJuaW5ncyEuYWRkKHdhcm5pbmcpO1xuICAgIH1cbiAgfTtcbn1cblxuLyoqXG4gKiBCYXNlIGVsZW1lbnQgY2xhc3MgdGhhdCBtYW5hZ2VzIGVsZW1lbnQgcHJvcGVydGllcyBhbmQgYXR0cmlidXRlcywgYW5kXG4gKiByZW5kZXJzIGEgbGl0LWh0bWwgdGVtcGxhdGUuXG4gKlxuICogVG8gZGVmaW5lIGEgY29tcG9uZW50LCBzdWJjbGFzcyBgTGl0RWxlbWVudGAgYW5kIGltcGxlbWVudCBhXG4gKiBgcmVuZGVyYCBtZXRob2QgdG8gcHJvdmlkZSB0aGUgY29tcG9uZW50J3MgdGVtcGxhdGUuIERlZmluZSBwcm9wZXJ0aWVzXG4gKiB1c2luZyB0aGUge0BsaW5rY29kZSBMaXRFbGVtZW50LnByb3BlcnRpZXMgcHJvcGVydGllc30gcHJvcGVydHkgb3IgdGhlXG4gKiB7QGxpbmtjb2RlIHByb3BlcnR5fSBkZWNvcmF0b3IuXG4gKi9cbmV4cG9ydCBjbGFzcyBMaXRFbGVtZW50IGV4dGVuZHMgUmVhY3RpdmVFbGVtZW50IHtcbiAgLy8gVGhpcyBwcm9wZXJ0eSBuZWVkcyB0byByZW1haW4gdW5taW5pZmllZC5cbiAgc3RhdGljIFsnXyRsaXRFbGVtZW50JCddID0gdHJ1ZTtcblxuICAvKipcbiAgICogQGNhdGVnb3J5IHJlbmRlcmluZ1xuICAgKi9cbiAgcmVhZG9ubHkgcmVuZGVyT3B0aW9uczogUmVuZGVyT3B0aW9ucyA9IHtob3N0OiB0aGlzfTtcblxuICBwcml2YXRlIF9fY2hpbGRQYXJ0OiBSb290UGFydCB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogQGNhdGVnb3J5IHJlbmRlcmluZ1xuICAgKi9cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIGNyZWF0ZVJlbmRlclJvb3QoKSB7XG4gICAgY29uc3QgcmVuZGVyUm9vdCA9IHN1cGVyLmNyZWF0ZVJlbmRlclJvb3QoKTtcbiAgICAvLyBXaGVuIGFkb3B0ZWRTdHlsZVNoZWV0cyBhcmUgc2hpbW1lZCwgdGhleSBhcmUgaW5zZXJ0ZWQgaW50byB0aGVcbiAgICAvLyBzaGFkb3dSb290IGJ5IGNyZWF0ZVJlbmRlclJvb3QuIEFkanVzdCB0aGUgcmVuZGVyQmVmb3JlIG5vZGUgc28gdGhhdFxuICAgIC8vIGFueSBzdHlsZXMgaW4gTGl0IGNvbnRlbnQgcmVuZGVyIGJlZm9yZSBhZG9wdGVkU3R5bGVTaGVldHMuIFRoaXMgaXNcbiAgICAvLyBpbXBvcnRhbnQgc28gdGhhdCBhZG9wdGVkU3R5bGVTaGVldHMgaGF2ZSBwcmVjZWRlbmNlIG92ZXIgc3R5bGVzIGluXG4gICAgLy8gdGhlIHNoYWRvd1Jvb3QuXG4gICAgdGhpcy5yZW5kZXJPcHRpb25zLnJlbmRlckJlZm9yZSA/Pz0gcmVuZGVyUm9vdCEuZmlyc3RDaGlsZCBhcyBDaGlsZE5vZGU7XG4gICAgcmV0dXJuIHJlbmRlclJvb3Q7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlcyB0aGUgZWxlbWVudC4gVGhpcyBtZXRob2QgcmVmbGVjdHMgcHJvcGVydHkgdmFsdWVzIHRvIGF0dHJpYnV0ZXNcbiAgICogYW5kIGNhbGxzIGByZW5kZXJgIHRvIHJlbmRlciBET00gdmlhIGxpdC1odG1sLiBTZXR0aW5nIHByb3BlcnRpZXMgaW5zaWRlXG4gICAqIHRoaXMgbWV0aG9kIHdpbGwgKm5vdCogdHJpZ2dlciBhbm90aGVyIHVwZGF0ZS5cbiAgICogQHBhcmFtIGNoYW5nZWRQcm9wZXJ0aWVzIE1hcCBvZiBjaGFuZ2VkIHByb3BlcnRpZXMgd2l0aCBvbGQgdmFsdWVzXG4gICAqIEBjYXRlZ29yeSB1cGRhdGVzXG4gICAqL1xuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgdXBkYXRlKGNoYW5nZWRQcm9wZXJ0aWVzOiBQcm9wZXJ0eVZhbHVlcykge1xuICAgIC8vIFNldHRpbmcgcHJvcGVydGllcyBpbiBgcmVuZGVyYCBzaG91bGQgbm90IHRyaWdnZXIgYW4gdXBkYXRlLiBTaW5jZVxuICAgIC8vIHVwZGF0ZXMgYXJlIGFsbG93ZWQgYWZ0ZXIgc3VwZXIudXBkYXRlLCBpdCdzIGltcG9ydGFudCB0byBjYWxsIGByZW5kZXJgXG4gICAgLy8gYmVmb3JlIHRoYXQuXG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLnJlbmRlcigpO1xuICAgIGlmICghdGhpcy5oYXNVcGRhdGVkKSB7XG4gICAgICB0aGlzLnJlbmRlck9wdGlvbnMuaXNDb25uZWN0ZWQgPSB0aGlzLmlzQ29ubmVjdGVkO1xuICAgIH1cbiAgICBzdXBlci51cGRhdGUoY2hhbmdlZFByb3BlcnRpZXMpO1xuICAgIHRoaXMuX19jaGlsZFBhcnQgPSByZW5kZXIodmFsdWUsIHRoaXMucmVuZGVyUm9vdCwgdGhpcy5yZW5kZXJPcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbnZva2VkIHdoZW4gdGhlIGNvbXBvbmVudCBpcyBhZGRlZCB0byB0aGUgZG9jdW1lbnQncyBET00uXG4gICAqXG4gICAqIEluIGBjb25uZWN0ZWRDYWxsYmFjaygpYCB5b3Ugc2hvdWxkIHNldHVwIHRhc2tzIHRoYXQgc2hvdWxkIG9ubHkgb2NjdXIgd2hlblxuICAgKiB0aGUgZWxlbWVudCBpcyBjb25uZWN0ZWQgdG8gdGhlIGRvY3VtZW50LiBUaGUgbW9zdCBjb21tb24gb2YgdGhlc2UgaXNcbiAgICogYWRkaW5nIGV2ZW50IGxpc3RlbmVycyB0byBub2RlcyBleHRlcm5hbCB0byB0aGUgZWxlbWVudCwgbGlrZSBhIGtleWRvd25cbiAgICogZXZlbnQgaGFuZGxlciBhZGRlZCB0byB0aGUgd2luZG93LlxuICAgKlxuICAgKiBgYGB0c1xuICAgKiBjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICogICBzdXBlci5jb25uZWN0ZWRDYWxsYmFjaygpO1xuICAgKiAgIGFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCB0aGlzLl9oYW5kbGVLZXlkb3duKTtcbiAgICogfVxuICAgKiBgYGBcbiAgICpcbiAgICogVHlwaWNhbGx5LCBhbnl0aGluZyBkb25lIGluIGBjb25uZWN0ZWRDYWxsYmFjaygpYCBzaG91bGQgYmUgdW5kb25lIHdoZW4gdGhlXG4gICAqIGVsZW1lbnQgaXMgZGlzY29ubmVjdGVkLCBpbiBgZGlzY29ubmVjdGVkQ2FsbGJhY2soKWAuXG4gICAqXG4gICAqIEBjYXRlZ29yeSBsaWZlY3ljbGVcbiAgICovXG4gIG92ZXJyaWRlIGNvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgIHN1cGVyLmNvbm5lY3RlZENhbGxiYWNrKCk7XG4gICAgdGhpcy5fX2NoaWxkUGFydD8uc2V0Q29ubmVjdGVkKHRydWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEludm9rZWQgd2hlbiB0aGUgY29tcG9uZW50IGlzIHJlbW92ZWQgZnJvbSB0aGUgZG9jdW1lbnQncyBET00uXG4gICAqXG4gICAqIFRoaXMgY2FsbGJhY2sgaXMgdGhlIG1haW4gc2lnbmFsIHRvIHRoZSBlbGVtZW50IHRoYXQgaXQgbWF5IG5vIGxvbmdlciBiZVxuICAgKiB1c2VkLiBgZGlzY29ubmVjdGVkQ2FsbGJhY2soKWAgc2hvdWxkIGVuc3VyZSB0aGF0IG5vdGhpbmcgaXMgaG9sZGluZyBhXG4gICAqIHJlZmVyZW5jZSB0byB0aGUgZWxlbWVudCAoc3VjaCBhcyBldmVudCBsaXN0ZW5lcnMgYWRkZWQgdG8gbm9kZXMgZXh0ZXJuYWxcbiAgICogdG8gdGhlIGVsZW1lbnQpLCBzbyB0aGF0IGl0IGlzIGZyZWUgdG8gYmUgZ2FyYmFnZSBjb2xsZWN0ZWQuXG4gICAqXG4gICAqIGBgYHRzXG4gICAqIGRpc2Nvbm5lY3RlZENhbGxiYWNrKCkge1xuICAgKiAgIHN1cGVyLmRpc2Nvbm5lY3RlZENhbGxiYWNrKCk7XG4gICAqICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCB0aGlzLl9oYW5kbGVLZXlkb3duKTtcbiAgICogfVxuICAgKiBgYGBcbiAgICpcbiAgICogQW4gZWxlbWVudCBtYXkgYmUgcmUtY29ubmVjdGVkIGFmdGVyIGJlaW5nIGRpc2Nvbm5lY3RlZC5cbiAgICpcbiAgICogQGNhdGVnb3J5IGxpZmVjeWNsZVxuICAgKi9cbiAgb3ZlcnJpZGUgZGlzY29ubmVjdGVkQ2FsbGJhY2soKSB7XG4gICAgc3VwZXIuZGlzY29ubmVjdGVkQ2FsbGJhY2soKTtcbiAgICB0aGlzLl9fY2hpbGRQYXJ0Py5zZXRDb25uZWN0ZWQoZmFsc2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEludm9rZWQgb24gZWFjaCB1cGRhdGUgdG8gcGVyZm9ybSByZW5kZXJpbmcgdGFza3MuIFRoaXMgbWV0aG9kIG1heSByZXR1cm5cbiAgICogYW55IHZhbHVlIHJlbmRlcmFibGUgYnkgbGl0LWh0bWwncyBgQ2hpbGRQYXJ0YCAtIHR5cGljYWxseSBhXG4gICAqIGBUZW1wbGF0ZVJlc3VsdGAuIFNldHRpbmcgcHJvcGVydGllcyBpbnNpZGUgdGhpcyBtZXRob2Qgd2lsbCAqbm90KiB0cmlnZ2VyXG4gICAqIHRoZSBlbGVtZW50IHRvIHVwZGF0ZS5cbiAgICogQGNhdGVnb3J5IHJlbmRlcmluZ1xuICAgKi9cbiAgcHJvdGVjdGVkIHJlbmRlcigpOiB1bmtub3duIHtcbiAgICByZXR1cm4gbm9DaGFuZ2U7XG4gIH1cbn1cblxuLyoqXG4gKiBFbnN1cmUgdGhpcyBjbGFzcyBpcyBtYXJrZWQgYXMgYGZpbmFsaXplZGAgYXMgYW4gb3B0aW1pemF0aW9uIGVuc3VyaW5nXG4gKiBpdCB3aWxsIG5vdCBuZWVkbGVzc2x5IHRyeSB0byBgZmluYWxpemVgLlxuICpcbiAqIE5vdGUgdGhpcyBwcm9wZXJ0eSBuYW1lIGlzIGEgc3RyaW5nIHRvIHByZXZlbnQgYnJlYWtpbmcgQ2xvc3VyZSBKUyBDb21waWxlclxuICogb3B0aW1pemF0aW9ucy4gU2VlIEBsaXQvcmVhY3RpdmUtZWxlbWVudCBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cbiAqL1xuKExpdEVsZW1lbnQgYXMgdW5rbm93biBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilbXG4gIEpTQ29tcGlsZXJfcmVuYW1lUHJvcGVydHkoJ2ZpbmFsaXplZCcsIExpdEVsZW1lbnQpXG5dID0gdHJ1ZTtcblxuLy8gSW5zdGFsbCBoeWRyYXRpb24gaWYgYXZhaWxhYmxlXG5nbG9iYWwubGl0RWxlbWVudEh5ZHJhdGVTdXBwb3J0Py4oe0xpdEVsZW1lbnR9KTtcblxuLy8gQXBwbHkgcG9seWZpbGxzIGlmIGF2YWlsYWJsZVxuY29uc3QgcG9seWZpbGxTdXBwb3J0ID0gREVWX01PREVcbiAgPyBnbG9iYWwubGl0RWxlbWVudFBvbHlmaWxsU3VwcG9ydERldk1vZGVcbiAgOiBnbG9iYWwubGl0RWxlbWVudFBvbHlmaWxsU3VwcG9ydDtcbnBvbHlmaWxsU3VwcG9ydD8uKHtMaXRFbGVtZW50fSk7XG5cbi8qKlxuICogRU5EIFVTRVJTIFNIT1VMRCBOT1QgUkVMWSBPTiBUSElTIE9CSkVDVC5cbiAqXG4gKiBQcml2YXRlIGV4cG9ydHMgZm9yIHVzZSBieSBvdGhlciBMaXQgcGFja2FnZXMsIG5vdCBpbnRlbmRlZCBmb3IgdXNlIGJ5XG4gKiBleHRlcm5hbCB1c2Vycy5cbiAqXG4gKiBXZSBjdXJyZW50bHkgZG8gbm90IG1ha2UgYSBtYW5nbGVkIHJvbGx1cCBidWlsZCBvZiB0aGUgbGl0LXNzciBjb2RlLiBJbiBvcmRlclxuICogdG8ga2VlcCBhIG51bWJlciBvZiAob3RoZXJ3aXNlIHByaXZhdGUpIHRvcC1sZXZlbCBleHBvcnRzICBtYW5nbGVkIGluIHRoZVxuICogY2xpZW50IHNpZGUgY29kZSwgd2UgZXhwb3J0IGEgXyRMRSBvYmplY3QgY29udGFpbmluZyB0aG9zZSBtZW1iZXJzIChvclxuICogaGVscGVyIG1ldGhvZHMgZm9yIGFjY2Vzc2luZyBwcml2YXRlIGZpZWxkcyBvZiB0aG9zZSBtZW1iZXJzKSwgYW5kIHRoZW5cbiAqIHJlLWV4cG9ydCB0aGVtIGZvciB1c2UgaW4gbGl0LXNzci4gVGhpcyBrZWVwcyBsaXQtc3NyIGFnbm9zdGljIHRvIHdoZXRoZXIgdGhlXG4gKiBjbGllbnQtc2lkZSBjb2RlIGlzIGJlaW5nIHVzZWQgaW4gYGRldmAgbW9kZSBvciBgcHJvZGAgbW9kZS5cbiAqXG4gKiBUaGlzIGhhcyBhIHVuaXF1ZSBuYW1lLCB0byBkaXNhbWJpZ3VhdGUgaXQgZnJvbSBwcml2YXRlIGV4cG9ydHMgaW5cbiAqIGxpdC1odG1sLCBzaW5jZSB0aGlzIG1vZHVsZSByZS1leHBvcnRzIGFsbCBvZiBsaXQtaHRtbC5cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgY29uc3QgXyRMRSA9IHtcbiAgXyRhdHRyaWJ1dGVUb1Byb3BlcnR5OiAoXG4gICAgZWw6IExpdEVsZW1lbnQsXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIHZhbHVlOiBzdHJpbmcgfCBudWxsXG4gICkgPT4ge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgIChlbCBhcyBhbnkpLl8kYXR0cmlidXRlVG9Qcm9wZXJ0eShuYW1lLCB2YWx1ZSk7XG4gIH0sXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICBfJGNoYW5nZWRQcm9wZXJ0aWVzOiAoZWw6IExpdEVsZW1lbnQpID0+IChlbCBhcyBhbnkpLl8kY2hhbmdlZFByb3BlcnRpZXMsXG59O1xuXG4vLyBJTVBPUlRBTlQ6IGRvIG5vdCBjaGFuZ2UgdGhlIHByb3BlcnR5IG5hbWUgb3IgdGhlIGFzc2lnbm1lbnQgZXhwcmVzc2lvbi5cbi8vIFRoaXMgbGluZSB3aWxsIGJlIHVzZWQgaW4gcmVnZXhlcyB0byBzZWFyY2ggZm9yIExpdEVsZW1lbnQgdXNhZ2UuXG4oZ2xvYmFsLmxpdEVsZW1lbnRWZXJzaW9ucyA/Pz0gW10pLnB1c2goJzQuMi4wJyk7XG5pZiAoREVWX01PREUgJiYgZ2xvYmFsLmxpdEVsZW1lbnRWZXJzaW9ucy5sZW5ndGggPiAxKSB7XG4gIHF1ZXVlTWljcm90YXNrKCgpID0+IHtcbiAgICBpc3N1ZVdhcm5pbmchKFxuICAgICAgJ211bHRpcGxlLXZlcnNpb25zJyxcbiAgICAgIGBNdWx0aXBsZSB2ZXJzaW9ucyBvZiBMaXQgbG9hZGVkLiBMb2FkaW5nIG11bHRpcGxlIHZlcnNpb25zIGAgK1xuICAgICAgICBgaXMgbm90IHJlY29tbWVuZGVkLmBcbiAgICApO1xuICB9KTtcbn1cbiIsICIvLyA6Oi0gUGVyc2lzdGVudCBkYXRhIHN0cnVjdHVyZSByZXByZXNlbnRpbmcgYW4gb3JkZXJlZCBtYXBwaW5nIGZyb21cbi8vIHN0cmluZ3MgdG8gdmFsdWVzLCB3aXRoIHNvbWUgY29udmVuaWVudCB1cGRhdGUgbWV0aG9kcy5cbmZ1bmN0aW9uIE9yZGVyZWRNYXAoY29udGVudCkge1xuICB0aGlzLmNvbnRlbnQgPSBjb250ZW50O1xufVxuXG5PcmRlcmVkTWFwLnByb3RvdHlwZSA9IHtcbiAgY29uc3RydWN0b3I6IE9yZGVyZWRNYXAsXG5cbiAgZmluZDogZnVuY3Rpb24oa2V5KSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmNvbnRlbnQubGVuZ3RoOyBpICs9IDIpXG4gICAgICBpZiAodGhpcy5jb250ZW50W2ldID09PSBrZXkpIHJldHVybiBpXG4gICAgcmV0dXJuIC0xXG4gIH0sXG5cbiAgLy8gOjogKHN0cmluZykgXHUyMTkyID9hbnlcbiAgLy8gUmV0cmlldmUgdGhlIHZhbHVlIHN0b3JlZCB1bmRlciBga2V5YCwgb3IgcmV0dXJuIHVuZGVmaW5lZCB3aGVuXG4gIC8vIG5vIHN1Y2gga2V5IGV4aXN0cy5cbiAgZ2V0OiBmdW5jdGlvbihrZXkpIHtcbiAgICB2YXIgZm91bmQgPSB0aGlzLmZpbmQoa2V5KTtcbiAgICByZXR1cm4gZm91bmQgPT0gLTEgPyB1bmRlZmluZWQgOiB0aGlzLmNvbnRlbnRbZm91bmQgKyAxXVxuICB9LFxuXG4gIC8vIDo6IChzdHJpbmcsIGFueSwgP3N0cmluZykgXHUyMTkyIE9yZGVyZWRNYXBcbiAgLy8gQ3JlYXRlIGEgbmV3IG1hcCBieSByZXBsYWNpbmcgdGhlIHZhbHVlIG9mIGBrZXlgIHdpdGggYSBuZXdcbiAgLy8gdmFsdWUsIG9yIGFkZGluZyBhIGJpbmRpbmcgdG8gdGhlIGVuZCBvZiB0aGUgbWFwLiBJZiBgbmV3S2V5YCBpc1xuICAvLyBnaXZlbiwgdGhlIGtleSBvZiB0aGUgYmluZGluZyB3aWxsIGJlIHJlcGxhY2VkIHdpdGggdGhhdCBrZXkuXG4gIHVwZGF0ZTogZnVuY3Rpb24oa2V5LCB2YWx1ZSwgbmV3S2V5KSB7XG4gICAgdmFyIHNlbGYgPSBuZXdLZXkgJiYgbmV3S2V5ICE9IGtleSA/IHRoaXMucmVtb3ZlKG5ld0tleSkgOiB0aGlzO1xuICAgIHZhciBmb3VuZCA9IHNlbGYuZmluZChrZXkpLCBjb250ZW50ID0gc2VsZi5jb250ZW50LnNsaWNlKCk7XG4gICAgaWYgKGZvdW5kID09IC0xKSB7XG4gICAgICBjb250ZW50LnB1c2gobmV3S2V5IHx8IGtleSwgdmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb250ZW50W2ZvdW5kICsgMV0gPSB2YWx1ZTtcbiAgICAgIGlmIChuZXdLZXkpIGNvbnRlbnRbZm91bmRdID0gbmV3S2V5O1xuICAgIH1cbiAgICByZXR1cm4gbmV3IE9yZGVyZWRNYXAoY29udGVudClcbiAgfSxcblxuICAvLyA6OiAoc3RyaW5nKSBcdTIxOTIgT3JkZXJlZE1hcFxuICAvLyBSZXR1cm4gYSBtYXAgd2l0aCB0aGUgZ2l2ZW4ga2V5IHJlbW92ZWQsIGlmIGl0IGV4aXN0ZWQuXG4gIHJlbW92ZTogZnVuY3Rpb24oa2V5KSB7XG4gICAgdmFyIGZvdW5kID0gdGhpcy5maW5kKGtleSk7XG4gICAgaWYgKGZvdW5kID09IC0xKSByZXR1cm4gdGhpc1xuICAgIHZhciBjb250ZW50ID0gdGhpcy5jb250ZW50LnNsaWNlKCk7XG4gICAgY29udGVudC5zcGxpY2UoZm91bmQsIDIpO1xuICAgIHJldHVybiBuZXcgT3JkZXJlZE1hcChjb250ZW50KVxuICB9LFxuXG4gIC8vIDo6IChzdHJpbmcsIGFueSkgXHUyMTkyIE9yZGVyZWRNYXBcbiAgLy8gQWRkIGEgbmV3IGtleSB0byB0aGUgc3RhcnQgb2YgdGhlIG1hcC5cbiAgYWRkVG9TdGFydDogZnVuY3Rpb24oa2V5LCB2YWx1ZSkge1xuICAgIHJldHVybiBuZXcgT3JkZXJlZE1hcChba2V5LCB2YWx1ZV0uY29uY2F0KHRoaXMucmVtb3ZlKGtleSkuY29udGVudCkpXG4gIH0sXG5cbiAgLy8gOjogKHN0cmluZywgYW55KSBcdTIxOTIgT3JkZXJlZE1hcFxuICAvLyBBZGQgYSBuZXcga2V5IHRvIHRoZSBlbmQgb2YgdGhlIG1hcC5cbiAgYWRkVG9FbmQ6IGZ1bmN0aW9uKGtleSwgdmFsdWUpIHtcbiAgICB2YXIgY29udGVudCA9IHRoaXMucmVtb3ZlKGtleSkuY29udGVudC5zbGljZSgpO1xuICAgIGNvbnRlbnQucHVzaChrZXksIHZhbHVlKTtcbiAgICByZXR1cm4gbmV3IE9yZGVyZWRNYXAoY29udGVudClcbiAgfSxcblxuICAvLyA6OiAoc3RyaW5nLCBzdHJpbmcsIGFueSkgXHUyMTkyIE9yZGVyZWRNYXBcbiAgLy8gQWRkIGEga2V5IGFmdGVyIHRoZSBnaXZlbiBrZXkuIElmIGBwbGFjZWAgaXMgbm90IGZvdW5kLCB0aGUgbmV3XG4gIC8vIGtleSBpcyBhZGRlZCB0byB0aGUgZW5kLlxuICBhZGRCZWZvcmU6IGZ1bmN0aW9uKHBsYWNlLCBrZXksIHZhbHVlKSB7XG4gICAgdmFyIHdpdGhvdXQgPSB0aGlzLnJlbW92ZShrZXkpLCBjb250ZW50ID0gd2l0aG91dC5jb250ZW50LnNsaWNlKCk7XG4gICAgdmFyIGZvdW5kID0gd2l0aG91dC5maW5kKHBsYWNlKTtcbiAgICBjb250ZW50LnNwbGljZShmb3VuZCA9PSAtMSA/IGNvbnRlbnQubGVuZ3RoIDogZm91bmQsIDAsIGtleSwgdmFsdWUpO1xuICAgIHJldHVybiBuZXcgT3JkZXJlZE1hcChjb250ZW50KVxuICB9LFxuXG4gIC8vIDo6ICgoa2V5OiBzdHJpbmcsIHZhbHVlOiBhbnkpKVxuICAvLyBDYWxsIHRoZSBnaXZlbiBmdW5jdGlvbiBmb3IgZWFjaCBrZXkvdmFsdWUgcGFpciBpbiB0aGUgbWFwLCBpblxuICAvLyBvcmRlci5cbiAgZm9yRWFjaDogZnVuY3Rpb24oZikge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5jb250ZW50Lmxlbmd0aDsgaSArPSAyKVxuICAgICAgZih0aGlzLmNvbnRlbnRbaV0sIHRoaXMuY29udGVudFtpICsgMV0pO1xuICB9LFxuXG4gIC8vIDo6ICh1bmlvbjxPYmplY3QsIE9yZGVyZWRNYXA+KSBcdTIxOTIgT3JkZXJlZE1hcFxuICAvLyBDcmVhdGUgYSBuZXcgbWFwIGJ5IHByZXBlbmRpbmcgdGhlIGtleXMgaW4gdGhpcyBtYXAgdGhhdCBkb24ndFxuICAvLyBhcHBlYXIgaW4gYG1hcGAgYmVmb3JlIHRoZSBrZXlzIGluIGBtYXBgLlxuICBwcmVwZW5kOiBmdW5jdGlvbihtYXApIHtcbiAgICBtYXAgPSBPcmRlcmVkTWFwLmZyb20obWFwKTtcbiAgICBpZiAoIW1hcC5zaXplKSByZXR1cm4gdGhpc1xuICAgIHJldHVybiBuZXcgT3JkZXJlZE1hcChtYXAuY29udGVudC5jb25jYXQodGhpcy5zdWJ0cmFjdChtYXApLmNvbnRlbnQpKVxuICB9LFxuXG4gIC8vIDo6ICh1bmlvbjxPYmplY3QsIE9yZGVyZWRNYXA+KSBcdTIxOTIgT3JkZXJlZE1hcFxuICAvLyBDcmVhdGUgYSBuZXcgbWFwIGJ5IGFwcGVuZGluZyB0aGUga2V5cyBpbiB0aGlzIG1hcCB0aGF0IGRvbid0XG4gIC8vIGFwcGVhciBpbiBgbWFwYCBhZnRlciB0aGUga2V5cyBpbiBgbWFwYC5cbiAgYXBwZW5kOiBmdW5jdGlvbihtYXApIHtcbiAgICBtYXAgPSBPcmRlcmVkTWFwLmZyb20obWFwKTtcbiAgICBpZiAoIW1hcC5zaXplKSByZXR1cm4gdGhpc1xuICAgIHJldHVybiBuZXcgT3JkZXJlZE1hcCh0aGlzLnN1YnRyYWN0KG1hcCkuY29udGVudC5jb25jYXQobWFwLmNvbnRlbnQpKVxuICB9LFxuXG4gIC8vIDo6ICh1bmlvbjxPYmplY3QsIE9yZGVyZWRNYXA+KSBcdTIxOTIgT3JkZXJlZE1hcFxuICAvLyBDcmVhdGUgYSBtYXAgY29udGFpbmluZyBhbGwgdGhlIGtleXMgaW4gdGhpcyBtYXAgdGhhdCBkb24ndFxuICAvLyBhcHBlYXIgaW4gYG1hcGAuXG4gIHN1YnRyYWN0OiBmdW5jdGlvbihtYXApIHtcbiAgICB2YXIgcmVzdWx0ID0gdGhpcztcbiAgICBtYXAgPSBPcmRlcmVkTWFwLmZyb20obWFwKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1hcC5jb250ZW50Lmxlbmd0aDsgaSArPSAyKVxuICAgICAgcmVzdWx0ID0gcmVzdWx0LnJlbW92ZShtYXAuY29udGVudFtpXSk7XG4gICAgcmV0dXJuIHJlc3VsdFxuICB9LFxuXG4gIC8vIDo6ICgpIFx1MjE5MiBPYmplY3RcbiAgLy8gVHVybiBvcmRlcmVkIG1hcCBpbnRvIGEgcGxhaW4gb2JqZWN0LlxuICB0b09iamVjdDogZnVuY3Rpb24oKSB7XG4gICAgdmFyIHJlc3VsdCA9IHt9O1xuICAgIHRoaXMuZm9yRWFjaChmdW5jdGlvbihrZXksIHZhbHVlKSB7IHJlc3VsdFtrZXldID0gdmFsdWU7IH0pO1xuICAgIHJldHVybiByZXN1bHRcbiAgfSxcblxuICAvLyA6OiBudW1iZXJcbiAgLy8gVGhlIGFtb3VudCBvZiBrZXlzIGluIHRoaXMgbWFwLlxuICBnZXQgc2l6ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5jb250ZW50Lmxlbmd0aCA+PiAxXG4gIH1cbn07XG5cbi8vIDo6ICg/dW5pb248T2JqZWN0LCBPcmRlcmVkTWFwPikgXHUyMTkyIE9yZGVyZWRNYXBcbi8vIFJldHVybiBhIG1hcCB3aXRoIHRoZSBnaXZlbiBjb250ZW50LiBJZiBudWxsLCBjcmVhdGUgYW4gZW1wdHlcbi8vIG1hcC4gSWYgZ2l2ZW4gYW4gb3JkZXJlZCBtYXAsIHJldHVybiB0aGF0IG1hcCBpdHNlbGYuIElmIGdpdmVuIGFuXG4vLyBvYmplY3QsIGNyZWF0ZSBhIG1hcCBmcm9tIHRoZSBvYmplY3QncyBwcm9wZXJ0aWVzLlxuT3JkZXJlZE1hcC5mcm9tID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgaWYgKHZhbHVlIGluc3RhbmNlb2YgT3JkZXJlZE1hcCkgcmV0dXJuIHZhbHVlXG4gIHZhciBjb250ZW50ID0gW107XG4gIGlmICh2YWx1ZSkgZm9yICh2YXIgcHJvcCBpbiB2YWx1ZSkgY29udGVudC5wdXNoKHByb3AsIHZhbHVlW3Byb3BdKTtcbiAgcmV0dXJuIG5ldyBPcmRlcmVkTWFwKGNvbnRlbnQpXG59O1xuXG5leHBvcnQgZGVmYXVsdCBPcmRlcmVkTWFwO1xuIiwgImltcG9ydCBPcmRlcmVkTWFwIGZyb20gJ29yZGVyZWRtYXAnO1xuXG5mdW5jdGlvbiBmaW5kRGlmZlN0YXJ0KGEsIGIsIHBvcykge1xuICAgIGZvciAobGV0IGkgPSAwOzsgaSsrKSB7XG4gICAgICAgIGlmIChpID09IGEuY2hpbGRDb3VudCB8fCBpID09IGIuY2hpbGRDb3VudClcbiAgICAgICAgICAgIHJldHVybiBhLmNoaWxkQ291bnQgPT0gYi5jaGlsZENvdW50ID8gbnVsbCA6IHBvcztcbiAgICAgICAgbGV0IGNoaWxkQSA9IGEuY2hpbGQoaSksIGNoaWxkQiA9IGIuY2hpbGQoaSk7XG4gICAgICAgIGlmIChjaGlsZEEgPT0gY2hpbGRCKSB7XG4gICAgICAgICAgICBwb3MgKz0gY2hpbGRBLm5vZGVTaXplO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFjaGlsZEEuc2FtZU1hcmt1cChjaGlsZEIpKVxuICAgICAgICAgICAgcmV0dXJuIHBvcztcbiAgICAgICAgaWYgKGNoaWxkQS5pc1RleHQgJiYgY2hpbGRBLnRleHQgIT0gY2hpbGRCLnRleHQpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBjaGlsZEEudGV4dFtqXSA9PSBjaGlsZEIudGV4dFtqXTsgaisrKVxuICAgICAgICAgICAgICAgIHBvcysrO1xuICAgICAgICAgICAgcmV0dXJuIHBvcztcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2hpbGRBLmNvbnRlbnQuc2l6ZSB8fCBjaGlsZEIuY29udGVudC5zaXplKSB7XG4gICAgICAgICAgICBsZXQgaW5uZXIgPSBmaW5kRGlmZlN0YXJ0KGNoaWxkQS5jb250ZW50LCBjaGlsZEIuY29udGVudCwgcG9zICsgMSk7XG4gICAgICAgICAgICBpZiAoaW5uZXIgIT0gbnVsbClcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5uZXI7XG4gICAgICAgIH1cbiAgICAgICAgcG9zICs9IGNoaWxkQS5ub2RlU2l6ZTtcbiAgICB9XG59XG5mdW5jdGlvbiBmaW5kRGlmZkVuZChhLCBiLCBwb3NBLCBwb3NCKSB7XG4gICAgZm9yIChsZXQgaUEgPSBhLmNoaWxkQ291bnQsIGlCID0gYi5jaGlsZENvdW50OzspIHtcbiAgICAgICAgaWYgKGlBID09IDAgfHwgaUIgPT0gMClcbiAgICAgICAgICAgIHJldHVybiBpQSA9PSBpQiA/IG51bGwgOiB7IGE6IHBvc0EsIGI6IHBvc0IgfTtcbiAgICAgICAgbGV0IGNoaWxkQSA9IGEuY2hpbGQoLS1pQSksIGNoaWxkQiA9IGIuY2hpbGQoLS1pQiksIHNpemUgPSBjaGlsZEEubm9kZVNpemU7XG4gICAgICAgIGlmIChjaGlsZEEgPT0gY2hpbGRCKSB7XG4gICAgICAgICAgICBwb3NBIC09IHNpemU7XG4gICAgICAgICAgICBwb3NCIC09IHNpemU7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWNoaWxkQS5zYW1lTWFya3VwKGNoaWxkQikpXG4gICAgICAgICAgICByZXR1cm4geyBhOiBwb3NBLCBiOiBwb3NCIH07XG4gICAgICAgIGlmIChjaGlsZEEuaXNUZXh0ICYmIGNoaWxkQS50ZXh0ICE9IGNoaWxkQi50ZXh0KSB7XG4gICAgICAgICAgICBsZXQgc2FtZSA9IDAsIG1pblNpemUgPSBNYXRoLm1pbihjaGlsZEEudGV4dC5sZW5ndGgsIGNoaWxkQi50ZXh0Lmxlbmd0aCk7XG4gICAgICAgICAgICB3aGlsZSAoc2FtZSA8IG1pblNpemUgJiYgY2hpbGRBLnRleHRbY2hpbGRBLnRleHQubGVuZ3RoIC0gc2FtZSAtIDFdID09IGNoaWxkQi50ZXh0W2NoaWxkQi50ZXh0Lmxlbmd0aCAtIHNhbWUgLSAxXSkge1xuICAgICAgICAgICAgICAgIHNhbWUrKztcbiAgICAgICAgICAgICAgICBwb3NBLS07XG4gICAgICAgICAgICAgICAgcG9zQi0tO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHsgYTogcG9zQSwgYjogcG9zQiB9O1xuICAgICAgICB9XG4gICAgICAgIGlmIChjaGlsZEEuY29udGVudC5zaXplIHx8IGNoaWxkQi5jb250ZW50LnNpemUpIHtcbiAgICAgICAgICAgIGxldCBpbm5lciA9IGZpbmREaWZmRW5kKGNoaWxkQS5jb250ZW50LCBjaGlsZEIuY29udGVudCwgcG9zQSAtIDEsIHBvc0IgLSAxKTtcbiAgICAgICAgICAgIGlmIChpbm5lcilcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5uZXI7XG4gICAgICAgIH1cbiAgICAgICAgcG9zQSAtPSBzaXplO1xuICAgICAgICBwb3NCIC09IHNpemU7XG4gICAgfVxufVxuXG4vKipcbkEgZnJhZ21lbnQgcmVwcmVzZW50cyBhIG5vZGUncyBjb2xsZWN0aW9uIG9mIGNoaWxkIG5vZGVzLlxuXG5MaWtlIG5vZGVzLCBmcmFnbWVudHMgYXJlIHBlcnNpc3RlbnQgZGF0YSBzdHJ1Y3R1cmVzLCBhbmQgeW91XG5zaG91bGQgbm90IG11dGF0ZSB0aGVtIG9yIHRoZWlyIGNvbnRlbnQuIFJhdGhlciwgeW91IGNyZWF0ZSBuZXdcbmluc3RhbmNlcyB3aGVuZXZlciBuZWVkZWQuIFRoZSBBUEkgdHJpZXMgdG8gbWFrZSB0aGlzIGVhc3kuXG4qL1xuY2xhc3MgRnJhZ21lbnQge1xuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgVGhlIGNoaWxkIG5vZGVzIGluIHRoaXMgZnJhZ21lbnQuXG4gICAgKi9cbiAgICBjb250ZW50LCBzaXplKSB7XG4gICAgICAgIHRoaXMuY29udGVudCA9IGNvbnRlbnQ7XG4gICAgICAgIHRoaXMuc2l6ZSA9IHNpemUgfHwgMDtcbiAgICAgICAgaWYgKHNpemUgPT0gbnVsbClcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY29udGVudC5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgICAgICB0aGlzLnNpemUgKz0gY29udGVudFtpXS5ub2RlU2l6ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgSW52b2tlIGEgY2FsbGJhY2sgZm9yIGFsbCBkZXNjZW5kYW50IG5vZGVzIGJldHdlZW4gdGhlIGdpdmVuIHR3b1xuICAgIHBvc2l0aW9ucyAocmVsYXRpdmUgdG8gc3RhcnQgb2YgdGhpcyBmcmFnbWVudCkuIERvZXNuJ3QgZGVzY2VuZFxuICAgIGludG8gYSBub2RlIHdoZW4gdGhlIGNhbGxiYWNrIHJldHVybnMgYGZhbHNlYC5cbiAgICAqL1xuICAgIG5vZGVzQmV0d2Vlbihmcm9tLCB0bywgZiwgbm9kZVN0YXJ0ID0gMCwgcGFyZW50KSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBwb3MgPSAwOyBwb3MgPCB0bzsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgY2hpbGQgPSB0aGlzLmNvbnRlbnRbaV0sIGVuZCA9IHBvcyArIGNoaWxkLm5vZGVTaXplO1xuICAgICAgICAgICAgaWYgKGVuZCA+IGZyb20gJiYgZihjaGlsZCwgbm9kZVN0YXJ0ICsgcG9zLCBwYXJlbnQgfHwgbnVsbCwgaSkgIT09IGZhbHNlICYmIGNoaWxkLmNvbnRlbnQuc2l6ZSkge1xuICAgICAgICAgICAgICAgIGxldCBzdGFydCA9IHBvcyArIDE7XG4gICAgICAgICAgICAgICAgY2hpbGQubm9kZXNCZXR3ZWVuKE1hdGgubWF4KDAsIGZyb20gLSBzdGFydCksIE1hdGgubWluKGNoaWxkLmNvbnRlbnQuc2l6ZSwgdG8gLSBzdGFydCksIGYsIG5vZGVTdGFydCArIHN0YXJ0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBvcyA9IGVuZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICBDYWxsIHRoZSBnaXZlbiBjYWxsYmFjayBmb3IgZXZlcnkgZGVzY2VuZGFudCBub2RlLiBgcG9zYCB3aWxsIGJlXG4gICAgcmVsYXRpdmUgdG8gdGhlIHN0YXJ0IG9mIHRoZSBmcmFnbWVudC4gVGhlIGNhbGxiYWNrIG1heSByZXR1cm5cbiAgICBgZmFsc2VgIHRvIHByZXZlbnQgdHJhdmVyc2FsIG9mIGEgZ2l2ZW4gbm9kZSdzIGNoaWxkcmVuLlxuICAgICovXG4gICAgZGVzY2VuZGFudHMoZikge1xuICAgICAgICB0aGlzLm5vZGVzQmV0d2VlbigwLCB0aGlzLnNpemUsIGYpO1xuICAgIH1cbiAgICAvKipcbiAgICBFeHRyYWN0IHRoZSB0ZXh0IGJldHdlZW4gYGZyb21gIGFuZCBgdG9gLiBTZWUgdGhlIHNhbWUgbWV0aG9kIG9uXG4gICAgW2BOb2RlYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGUudGV4dEJldHdlZW4pLlxuICAgICovXG4gICAgdGV4dEJldHdlZW4oZnJvbSwgdG8sIGJsb2NrU2VwYXJhdG9yLCBsZWFmVGV4dCkge1xuICAgICAgICBsZXQgdGV4dCA9IFwiXCIsIGZpcnN0ID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5ub2Rlc0JldHdlZW4oZnJvbSwgdG8sIChub2RlLCBwb3MpID0+IHtcbiAgICAgICAgICAgIGxldCBub2RlVGV4dCA9IG5vZGUuaXNUZXh0ID8gbm9kZS50ZXh0LnNsaWNlKE1hdGgubWF4KGZyb20sIHBvcykgLSBwb3MsIHRvIC0gcG9zKVxuICAgICAgICAgICAgICAgIDogIW5vZGUuaXNMZWFmID8gXCJcIlxuICAgICAgICAgICAgICAgICAgICA6IGxlYWZUZXh0ID8gKHR5cGVvZiBsZWFmVGV4dCA9PT0gXCJmdW5jdGlvblwiID8gbGVhZlRleHQobm9kZSkgOiBsZWFmVGV4dClcbiAgICAgICAgICAgICAgICAgICAgICAgIDogbm9kZS50eXBlLnNwZWMubGVhZlRleHQgPyBub2RlLnR5cGUuc3BlYy5sZWFmVGV4dChub2RlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogXCJcIjtcbiAgICAgICAgICAgIGlmIChub2RlLmlzQmxvY2sgJiYgKG5vZGUuaXNMZWFmICYmIG5vZGVUZXh0IHx8IG5vZGUuaXNUZXh0YmxvY2spICYmIGJsb2NrU2VwYXJhdG9yKSB7XG4gICAgICAgICAgICAgICAgaWYgKGZpcnN0KVxuICAgICAgICAgICAgICAgICAgICBmaXJzdCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgdGV4dCArPSBibG9ja1NlcGFyYXRvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRleHQgKz0gbm9kZVRleHQ7XG4gICAgICAgIH0sIDApO1xuICAgICAgICByZXR1cm4gdGV4dDtcbiAgICB9XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgbmV3IGZyYWdtZW50IGNvbnRhaW5pbmcgdGhlIGNvbWJpbmVkIGNvbnRlbnQgb2YgdGhpc1xuICAgIGZyYWdtZW50IGFuZCB0aGUgb3RoZXIuXG4gICAgKi9cbiAgICBhcHBlbmQob3RoZXIpIHtcbiAgICAgICAgaWYgKCFvdGhlci5zaXplKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIGlmICghdGhpcy5zaXplKVxuICAgICAgICAgICAgcmV0dXJuIG90aGVyO1xuICAgICAgICBsZXQgbGFzdCA9IHRoaXMubGFzdENoaWxkLCBmaXJzdCA9IG90aGVyLmZpcnN0Q2hpbGQsIGNvbnRlbnQgPSB0aGlzLmNvbnRlbnQuc2xpY2UoKSwgaSA9IDA7XG4gICAgICAgIGlmIChsYXN0LmlzVGV4dCAmJiBsYXN0LnNhbWVNYXJrdXAoZmlyc3QpKSB7XG4gICAgICAgICAgICBjb250ZW50W2NvbnRlbnQubGVuZ3RoIC0gMV0gPSBsYXN0LndpdGhUZXh0KGxhc3QudGV4dCArIGZpcnN0LnRleHQpO1xuICAgICAgICAgICAgaSA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgZm9yICg7IGkgPCBvdGhlci5jb250ZW50Lmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgY29udGVudC5wdXNoKG90aGVyLmNvbnRlbnRbaV0pO1xuICAgICAgICByZXR1cm4gbmV3IEZyYWdtZW50KGNvbnRlbnQsIHRoaXMuc2l6ZSArIG90aGVyLnNpemUpO1xuICAgIH1cbiAgICAvKipcbiAgICBDdXQgb3V0IHRoZSBzdWItZnJhZ21lbnQgYmV0d2VlbiB0aGUgdHdvIGdpdmVuIHBvc2l0aW9ucy5cbiAgICAqL1xuICAgIGN1dChmcm9tLCB0byA9IHRoaXMuc2l6ZSkge1xuICAgICAgICBpZiAoZnJvbSA9PSAwICYmIHRvID09IHRoaXMuc2l6ZSlcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICBsZXQgcmVzdWx0ID0gW10sIHNpemUgPSAwO1xuICAgICAgICBpZiAodG8gPiBmcm9tKVxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDAsIHBvcyA9IDA7IHBvcyA8IHRvOyBpKyspIHtcbiAgICAgICAgICAgICAgICBsZXQgY2hpbGQgPSB0aGlzLmNvbnRlbnRbaV0sIGVuZCA9IHBvcyArIGNoaWxkLm5vZGVTaXplO1xuICAgICAgICAgICAgICAgIGlmIChlbmQgPiBmcm9tKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChwb3MgPCBmcm9tIHx8IGVuZCA+IHRvKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGQuaXNUZXh0KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkID0gY2hpbGQuY3V0KE1hdGgubWF4KDAsIGZyb20gLSBwb3MpLCBNYXRoLm1pbihjaGlsZC50ZXh0Lmxlbmd0aCwgdG8gLSBwb3MpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZCA9IGNoaWxkLmN1dChNYXRoLm1heCgwLCBmcm9tIC0gcG9zIC0gMSksIE1hdGgubWluKGNoaWxkLmNvbnRlbnQuc2l6ZSwgdG8gLSBwb3MgLSAxKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goY2hpbGQpO1xuICAgICAgICAgICAgICAgICAgICBzaXplICs9IGNoaWxkLm5vZGVTaXplO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBwb3MgPSBlbmQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgRnJhZ21lbnQocmVzdWx0LCBzaXplKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBjdXRCeUluZGV4KGZyb20sIHRvKSB7XG4gICAgICAgIGlmIChmcm9tID09IHRvKVxuICAgICAgICAgICAgcmV0dXJuIEZyYWdtZW50LmVtcHR5O1xuICAgICAgICBpZiAoZnJvbSA9PSAwICYmIHRvID09IHRoaXMuY29udGVudC5sZW5ndGgpXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgcmV0dXJuIG5ldyBGcmFnbWVudCh0aGlzLmNvbnRlbnQuc2xpY2UoZnJvbSwgdG8pKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgbmV3IGZyYWdtZW50IGluIHdoaWNoIHRoZSBub2RlIGF0IHRoZSBnaXZlbiBpbmRleCBpc1xuICAgIHJlcGxhY2VkIGJ5IHRoZSBnaXZlbiBub2RlLlxuICAgICovXG4gICAgcmVwbGFjZUNoaWxkKGluZGV4LCBub2RlKSB7XG4gICAgICAgIGxldCBjdXJyZW50ID0gdGhpcy5jb250ZW50W2luZGV4XTtcbiAgICAgICAgaWYgKGN1cnJlbnQgPT0gbm9kZSlcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICBsZXQgY29weSA9IHRoaXMuY29udGVudC5zbGljZSgpO1xuICAgICAgICBsZXQgc2l6ZSA9IHRoaXMuc2l6ZSArIG5vZGUubm9kZVNpemUgLSBjdXJyZW50Lm5vZGVTaXplO1xuICAgICAgICBjb3B5W2luZGV4XSA9IG5vZGU7XG4gICAgICAgIHJldHVybiBuZXcgRnJhZ21lbnQoY29weSwgc2l6ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgIENyZWF0ZSBhIG5ldyBmcmFnbWVudCBieSBwcmVwZW5kaW5nIHRoZSBnaXZlbiBub2RlIHRvIHRoaXNcbiAgICBmcmFnbWVudC5cbiAgICAqL1xuICAgIGFkZFRvU3RhcnQobm9kZSkge1xuICAgICAgICByZXR1cm4gbmV3IEZyYWdtZW50KFtub2RlXS5jb25jYXQodGhpcy5jb250ZW50KSwgdGhpcy5zaXplICsgbm9kZS5ub2RlU2l6ZSk7XG4gICAgfVxuICAgIC8qKlxuICAgIENyZWF0ZSBhIG5ldyBmcmFnbWVudCBieSBhcHBlbmRpbmcgdGhlIGdpdmVuIG5vZGUgdG8gdGhpc1xuICAgIGZyYWdtZW50LlxuICAgICovXG4gICAgYWRkVG9FbmQobm9kZSkge1xuICAgICAgICByZXR1cm4gbmV3IEZyYWdtZW50KHRoaXMuY29udGVudC5jb25jYXQobm9kZSksIHRoaXMuc2l6ZSArIG5vZGUubm9kZVNpemUpO1xuICAgIH1cbiAgICAvKipcbiAgICBDb21wYXJlIHRoaXMgZnJhZ21lbnQgdG8gYW5vdGhlciBvbmUuXG4gICAgKi9cbiAgICBlcShvdGhlcikge1xuICAgICAgICBpZiAodGhpcy5jb250ZW50Lmxlbmd0aCAhPSBvdGhlci5jb250ZW50Lmxlbmd0aClcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmNvbnRlbnQubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICBpZiAoIXRoaXMuY29udGVudFtpXS5lcShvdGhlci5jb250ZW50W2ldKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICAvKipcbiAgICBUaGUgZmlyc3QgY2hpbGQgb2YgdGhlIGZyYWdtZW50LCBvciBgbnVsbGAgaWYgaXQgaXMgZW1wdHkuXG4gICAgKi9cbiAgICBnZXQgZmlyc3RDaGlsZCgpIHsgcmV0dXJuIHRoaXMuY29udGVudC5sZW5ndGggPyB0aGlzLmNvbnRlbnRbMF0gOiBudWxsOyB9XG4gICAgLyoqXG4gICAgVGhlIGxhc3QgY2hpbGQgb2YgdGhlIGZyYWdtZW50LCBvciBgbnVsbGAgaWYgaXQgaXMgZW1wdHkuXG4gICAgKi9cbiAgICBnZXQgbGFzdENoaWxkKCkgeyByZXR1cm4gdGhpcy5jb250ZW50Lmxlbmd0aCA/IHRoaXMuY29udGVudFt0aGlzLmNvbnRlbnQubGVuZ3RoIC0gMV0gOiBudWxsOyB9XG4gICAgLyoqXG4gICAgVGhlIG51bWJlciBvZiBjaGlsZCBub2RlcyBpbiB0aGlzIGZyYWdtZW50LlxuICAgICovXG4gICAgZ2V0IGNoaWxkQ291bnQoKSB7IHJldHVybiB0aGlzLmNvbnRlbnQubGVuZ3RoOyB9XG4gICAgLyoqXG4gICAgR2V0IHRoZSBjaGlsZCBub2RlIGF0IHRoZSBnaXZlbiBpbmRleC4gUmFpc2UgYW4gZXJyb3Igd2hlbiB0aGVcbiAgICBpbmRleCBpcyBvdXQgb2YgcmFuZ2UuXG4gICAgKi9cbiAgICBjaGlsZChpbmRleCkge1xuICAgICAgICBsZXQgZm91bmQgPSB0aGlzLmNvbnRlbnRbaW5kZXhdO1xuICAgICAgICBpZiAoIWZvdW5kKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbmRleCBcIiArIGluZGV4ICsgXCIgb3V0IG9mIHJhbmdlIGZvciBcIiArIHRoaXMpO1xuICAgICAgICByZXR1cm4gZm91bmQ7XG4gICAgfVxuICAgIC8qKlxuICAgIEdldCB0aGUgY2hpbGQgbm9kZSBhdCB0aGUgZ2l2ZW4gaW5kZXgsIGlmIGl0IGV4aXN0cy5cbiAgICAqL1xuICAgIG1heWJlQ2hpbGQoaW5kZXgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGVudFtpbmRleF0gfHwgbnVsbDtcbiAgICB9XG4gICAgLyoqXG4gICAgQ2FsbCBgZmAgZm9yIGV2ZXJ5IGNoaWxkIG5vZGUsIHBhc3NpbmcgdGhlIG5vZGUsIGl0cyBvZmZzZXRcbiAgICBpbnRvIHRoaXMgcGFyZW50IG5vZGUsIGFuZCBpdHMgaW5kZXguXG4gICAgKi9cbiAgICBmb3JFYWNoKGYpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIHAgPSAwOyBpIDwgdGhpcy5jb250ZW50Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgY2hpbGQgPSB0aGlzLmNvbnRlbnRbaV07XG4gICAgICAgICAgICBmKGNoaWxkLCBwLCBpKTtcbiAgICAgICAgICAgIHAgKz0gY2hpbGQubm9kZVNpemU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgRmluZCB0aGUgZmlyc3QgcG9zaXRpb24gYXQgd2hpY2ggdGhpcyBmcmFnbWVudCBhbmQgYW5vdGhlclxuICAgIGZyYWdtZW50IGRpZmZlciwgb3IgYG51bGxgIGlmIHRoZXkgYXJlIHRoZSBzYW1lLlxuICAgICovXG4gICAgZmluZERpZmZTdGFydChvdGhlciwgcG9zID0gMCkge1xuICAgICAgICByZXR1cm4gZmluZERpZmZTdGFydCh0aGlzLCBvdGhlciwgcG9zKTtcbiAgICB9XG4gICAgLyoqXG4gICAgRmluZCB0aGUgZmlyc3QgcG9zaXRpb24sIHNlYXJjaGluZyBmcm9tIHRoZSBlbmQsIGF0IHdoaWNoIHRoaXNcbiAgICBmcmFnbWVudCBhbmQgdGhlIGdpdmVuIGZyYWdtZW50IGRpZmZlciwgb3IgYG51bGxgIGlmIHRoZXkgYXJlXG4gICAgdGhlIHNhbWUuIFNpbmNlIHRoaXMgcG9zaXRpb24gd2lsbCBub3QgYmUgdGhlIHNhbWUgaW4gYm90aFxuICAgIG5vZGVzLCBhbiBvYmplY3Qgd2l0aCB0d28gc2VwYXJhdGUgcG9zaXRpb25zIGlzIHJldHVybmVkLlxuICAgICovXG4gICAgZmluZERpZmZFbmQob3RoZXIsIHBvcyA9IHRoaXMuc2l6ZSwgb3RoZXJQb3MgPSBvdGhlci5zaXplKSB7XG4gICAgICAgIHJldHVybiBmaW5kRGlmZkVuZCh0aGlzLCBvdGhlciwgcG9zLCBvdGhlclBvcyk7XG4gICAgfVxuICAgIC8qKlxuICAgIEZpbmQgdGhlIGluZGV4IGFuZCBpbm5lciBvZmZzZXQgY29ycmVzcG9uZGluZyB0byBhIGdpdmVuIHJlbGF0aXZlXG4gICAgcG9zaXRpb24gaW4gdGhpcyBmcmFnbWVudC4gVGhlIHJlc3VsdCBvYmplY3Qgd2lsbCBiZSByZXVzZWRcbiAgICAob3ZlcndyaXR0ZW4pIHRoZSBuZXh0IHRpbWUgdGhlIGZ1bmN0aW9uIGlzIGNhbGxlZC4gQGludGVybmFsXG4gICAgKi9cbiAgICBmaW5kSW5kZXgocG9zLCByb3VuZCA9IC0xKSB7XG4gICAgICAgIGlmIChwb3MgPT0gMClcbiAgICAgICAgICAgIHJldHVybiByZXRJbmRleCgwLCBwb3MpO1xuICAgICAgICBpZiAocG9zID09IHRoaXMuc2l6ZSlcbiAgICAgICAgICAgIHJldHVybiByZXRJbmRleCh0aGlzLmNvbnRlbnQubGVuZ3RoLCBwb3MpO1xuICAgICAgICBpZiAocG9zID4gdGhpcy5zaXplIHx8IHBvcyA8IDApXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgUG9zaXRpb24gJHtwb3N9IG91dHNpZGUgb2YgZnJhZ21lbnQgKCR7dGhpc30pYCk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBjdXJQb3MgPSAwOzsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgY3VyID0gdGhpcy5jaGlsZChpKSwgZW5kID0gY3VyUG9zICsgY3VyLm5vZGVTaXplO1xuICAgICAgICAgICAgaWYgKGVuZCA+PSBwb3MpIHtcbiAgICAgICAgICAgICAgICBpZiAoZW5kID09IHBvcyB8fCByb3VuZCA+IDApXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXRJbmRleChpICsgMSwgZW5kKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmV0SW5kZXgoaSwgY3VyUG9zKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGN1clBvcyA9IGVuZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICBSZXR1cm4gYSBkZWJ1Z2dpbmcgc3RyaW5nIHRoYXQgZGVzY3JpYmVzIHRoaXMgZnJhZ21lbnQuXG4gICAgKi9cbiAgICB0b1N0cmluZygpIHsgcmV0dXJuIFwiPFwiICsgdGhpcy50b1N0cmluZ0lubmVyKCkgKyBcIj5cIjsgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgdG9TdHJpbmdJbm5lcigpIHsgcmV0dXJuIHRoaXMuY29udGVudC5qb2luKFwiLCBcIik7IH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSBKU09OLXNlcmlhbGl6ZWFibGUgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBmcmFnbWVudC5cbiAgICAqL1xuICAgIHRvSlNPTigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGVudC5sZW5ndGggPyB0aGlzLmNvbnRlbnQubWFwKG4gPT4gbi50b0pTT04oKSkgOiBudWxsO1xuICAgIH1cbiAgICAvKipcbiAgICBEZXNlcmlhbGl6ZSBhIGZyYWdtZW50IGZyb20gaXRzIEpTT04gcmVwcmVzZW50YXRpb24uXG4gICAgKi9cbiAgICBzdGF0aWMgZnJvbUpTT04oc2NoZW1hLCB2YWx1ZSkge1xuICAgICAgICBpZiAoIXZhbHVlKVxuICAgICAgICAgICAgcmV0dXJuIEZyYWdtZW50LmVtcHR5O1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkodmFsdWUpKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIGlucHV0IGZvciBGcmFnbWVudC5mcm9tSlNPTlwiKTtcbiAgICAgICAgcmV0dXJuIG5ldyBGcmFnbWVudCh2YWx1ZS5tYXAoc2NoZW1hLm5vZGVGcm9tSlNPTikpO1xuICAgIH1cbiAgICAvKipcbiAgICBCdWlsZCBhIGZyYWdtZW50IGZyb20gYW4gYXJyYXkgb2Ygbm9kZXMuIEVuc3VyZXMgdGhhdCBhZGphY2VudFxuICAgIHRleHQgbm9kZXMgd2l0aCB0aGUgc2FtZSBtYXJrcyBhcmUgam9pbmVkIHRvZ2V0aGVyLlxuICAgICovXG4gICAgc3RhdGljIGZyb21BcnJheShhcnJheSkge1xuICAgICAgICBpZiAoIWFycmF5Lmxlbmd0aClcbiAgICAgICAgICAgIHJldHVybiBGcmFnbWVudC5lbXB0eTtcbiAgICAgICAgbGV0IGpvaW5lZCwgc2l6ZSA9IDA7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBub2RlID0gYXJyYXlbaV07XG4gICAgICAgICAgICBzaXplICs9IG5vZGUubm9kZVNpemU7XG4gICAgICAgICAgICBpZiAoaSAmJiBub2RlLmlzVGV4dCAmJiBhcnJheVtpIC0gMV0uc2FtZU1hcmt1cChub2RlKSkge1xuICAgICAgICAgICAgICAgIGlmICgham9pbmVkKVxuICAgICAgICAgICAgICAgICAgICBqb2luZWQgPSBhcnJheS5zbGljZSgwLCBpKTtcbiAgICAgICAgICAgICAgICBqb2luZWRbam9pbmVkLmxlbmd0aCAtIDFdID0gbm9kZVxuICAgICAgICAgICAgICAgICAgICAud2l0aFRleHQoam9pbmVkW2pvaW5lZC5sZW5ndGggLSAxXS50ZXh0ICsgbm9kZS50ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGpvaW5lZCkge1xuICAgICAgICAgICAgICAgIGpvaW5lZC5wdXNoKG5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgRnJhZ21lbnQoam9pbmVkIHx8IGFycmF5LCBzaXplKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgZnJhZ21lbnQgZnJvbSBzb21ldGhpbmcgdGhhdCBjYW4gYmUgaW50ZXJwcmV0ZWQgYXMgYVxuICAgIHNldCBvZiBub2Rlcy4gRm9yIGBudWxsYCwgaXQgcmV0dXJucyB0aGUgZW1wdHkgZnJhZ21lbnQuIEZvciBhXG4gICAgZnJhZ21lbnQsIHRoZSBmcmFnbWVudCBpdHNlbGYuIEZvciBhIG5vZGUgb3IgYXJyYXkgb2Ygbm9kZXMsIGFcbiAgICBmcmFnbWVudCBjb250YWluaW5nIHRob3NlIG5vZGVzLlxuICAgICovXG4gICAgc3RhdGljIGZyb20obm9kZXMpIHtcbiAgICAgICAgaWYgKCFub2RlcylcbiAgICAgICAgICAgIHJldHVybiBGcmFnbWVudC5lbXB0eTtcbiAgICAgICAgaWYgKG5vZGVzIGluc3RhbmNlb2YgRnJhZ21lbnQpXG4gICAgICAgICAgICByZXR1cm4gbm9kZXM7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KG5vZGVzKSlcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmZyb21BcnJheShub2Rlcyk7XG4gICAgICAgIGlmIChub2Rlcy5hdHRycylcbiAgICAgICAgICAgIHJldHVybiBuZXcgRnJhZ21lbnQoW25vZGVzXSwgbm9kZXMubm9kZVNpemUpO1xuICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkNhbiBub3QgY29udmVydCBcIiArIG5vZGVzICsgXCIgdG8gYSBGcmFnbWVudFwiICtcbiAgICAgICAgICAgIChub2Rlcy5ub2Rlc0JldHdlZW4gPyBcIiAobG9va3MgbGlrZSBtdWx0aXBsZSB2ZXJzaW9ucyBvZiBwcm9zZW1pcnJvci1tb2RlbCB3ZXJlIGxvYWRlZClcIiA6IFwiXCIpKTtcbiAgICB9XG59XG4vKipcbkFuIGVtcHR5IGZyYWdtZW50LiBJbnRlbmRlZCB0byBiZSByZXVzZWQgd2hlbmV2ZXIgYSBub2RlIGRvZXNuJ3RcbmNvbnRhaW4gYW55dGhpbmcgKHJhdGhlciB0aGFuIGFsbG9jYXRpbmcgYSBuZXcgZW1wdHkgZnJhZ21lbnQgZm9yXG5lYWNoIGxlYWYgbm9kZSkuXG4qL1xuRnJhZ21lbnQuZW1wdHkgPSBuZXcgRnJhZ21lbnQoW10sIDApO1xuY29uc3QgZm91bmQgPSB7IGluZGV4OiAwLCBvZmZzZXQ6IDAgfTtcbmZ1bmN0aW9uIHJldEluZGV4KGluZGV4LCBvZmZzZXQpIHtcbiAgICBmb3VuZC5pbmRleCA9IGluZGV4O1xuICAgIGZvdW5kLm9mZnNldCA9IG9mZnNldDtcbiAgICByZXR1cm4gZm91bmQ7XG59XG5cbmZ1bmN0aW9uIGNvbXBhcmVEZWVwKGEsIGIpIHtcbiAgICBpZiAoYSA9PT0gYilcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgaWYgKCEoYSAmJiB0eXBlb2YgYSA9PSBcIm9iamVjdFwiKSB8fFxuICAgICAgICAhKGIgJiYgdHlwZW9mIGIgPT0gXCJvYmplY3RcIikpXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICBsZXQgYXJyYXkgPSBBcnJheS5pc0FycmF5KGEpO1xuICAgIGlmIChBcnJheS5pc0FycmF5KGIpICE9IGFycmF5KVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgaWYgKGFycmF5KSB7XG4gICAgICAgIGlmIChhLmxlbmd0aCAhPSBiLmxlbmd0aClcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgaWYgKCFjb21wYXJlRGVlcChhW2ldLCBiW2ldKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBmb3IgKGxldCBwIGluIGEpXG4gICAgICAgICAgICBpZiAoIShwIGluIGIpIHx8ICFjb21wYXJlRGVlcChhW3BdLCBiW3BdKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGZvciAobGV0IHAgaW4gYilcbiAgICAgICAgICAgIGlmICghKHAgaW4gYSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG5BIG1hcmsgaXMgYSBwaWVjZSBvZiBpbmZvcm1hdGlvbiB0aGF0IGNhbiBiZSBhdHRhY2hlZCB0byBhIG5vZGUsXG5zdWNoIGFzIGl0IGJlaW5nIGVtcGhhc2l6ZWQsIGluIGNvZGUgZm9udCwgb3IgYSBsaW5rLiBJdCBoYXMgYVxudHlwZSBhbmQgb3B0aW9uYWxseSBhIHNldCBvZiBhdHRyaWJ1dGVzIHRoYXQgcHJvdmlkZSBmdXJ0aGVyXG5pbmZvcm1hdGlvbiAoc3VjaCBhcyB0aGUgdGFyZ2V0IG9mIHRoZSBsaW5rKS4gTWFya3MgYXJlIGNyZWF0ZWRcbnRocm91Z2ggYSBgU2NoZW1hYCwgd2hpY2ggY29udHJvbHMgd2hpY2ggdHlwZXMgZXhpc3QgYW5kIHdoaWNoXG5hdHRyaWJ1dGVzIHRoZXkgaGF2ZS5cbiovXG5jbGFzcyBNYXJrIHtcbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgIFRoZSB0eXBlIG9mIHRoaXMgbWFyay5cbiAgICAqL1xuICAgIHR5cGUsIFxuICAgIC8qKlxuICAgIFRoZSBhdHRyaWJ1dGVzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIG1hcmsuXG4gICAgKi9cbiAgICBhdHRycykge1xuICAgICAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgICAgICB0aGlzLmF0dHJzID0gYXR0cnM7XG4gICAgfVxuICAgIC8qKlxuICAgIEdpdmVuIGEgc2V0IG9mIG1hcmtzLCBjcmVhdGUgYSBuZXcgc2V0IHdoaWNoIGNvbnRhaW5zIHRoaXMgb25lIGFzXG4gICAgd2VsbCwgaW4gdGhlIHJpZ2h0IHBvc2l0aW9uLiBJZiB0aGlzIG1hcmsgaXMgYWxyZWFkeSBpbiB0aGUgc2V0LFxuICAgIHRoZSBzZXQgaXRzZWxmIGlzIHJldHVybmVkLiBJZiBhbnkgbWFya3MgdGhhdCBhcmUgc2V0IHRvIGJlXG4gICAgW2V4Y2x1c2l2ZV0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk1hcmtTcGVjLmV4Y2x1ZGVzKSB3aXRoIHRoaXMgbWFyayBhcmUgcHJlc2VudCxcbiAgICB0aG9zZSBhcmUgcmVwbGFjZWQgYnkgdGhpcyBvbmUuXG4gICAgKi9cbiAgICBhZGRUb1NldChzZXQpIHtcbiAgICAgICAgbGV0IGNvcHksIHBsYWNlZCA9IGZhbHNlO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNldC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IG90aGVyID0gc2V0W2ldO1xuICAgICAgICAgICAgaWYgKHRoaXMuZXEob3RoZXIpKVxuICAgICAgICAgICAgICAgIHJldHVybiBzZXQ7XG4gICAgICAgICAgICBpZiAodGhpcy50eXBlLmV4Y2x1ZGVzKG90aGVyLnR5cGUpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFjb3B5KVxuICAgICAgICAgICAgICAgICAgICBjb3B5ID0gc2V0LnNsaWNlKDAsIGkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAob3RoZXIudHlwZS5leGNsdWRlcyh0aGlzLnR5cGUpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNldDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmICghcGxhY2VkICYmIG90aGVyLnR5cGUucmFuayA+IHRoaXMudHlwZS5yYW5rKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghY29weSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvcHkgPSBzZXQuc2xpY2UoMCwgaSk7XG4gICAgICAgICAgICAgICAgICAgIGNvcHkucHVzaCh0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgcGxhY2VkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGNvcHkpXG4gICAgICAgICAgICAgICAgICAgIGNvcHkucHVzaChvdGhlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFjb3B5KVxuICAgICAgICAgICAgY29weSA9IHNldC5zbGljZSgpO1xuICAgICAgICBpZiAoIXBsYWNlZClcbiAgICAgICAgICAgIGNvcHkucHVzaCh0aGlzKTtcbiAgICAgICAgcmV0dXJuIGNvcHk7XG4gICAgfVxuICAgIC8qKlxuICAgIFJlbW92ZSB0aGlzIG1hcmsgZnJvbSB0aGUgZ2l2ZW4gc2V0LCByZXR1cm5pbmcgYSBuZXcgc2V0LiBJZiB0aGlzXG4gICAgbWFyayBpcyBub3QgaW4gdGhlIHNldCwgdGhlIHNldCBpdHNlbGYgaXMgcmV0dXJuZWQuXG4gICAgKi9cbiAgICByZW1vdmVGcm9tU2V0KHNldCkge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNldC5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIGlmICh0aGlzLmVxKHNldFtpXSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHNldC5zbGljZSgwLCBpKS5jb25jYXQoc2V0LnNsaWNlKGkgKyAxKSk7XG4gICAgICAgIHJldHVybiBzZXQ7XG4gICAgfVxuICAgIC8qKlxuICAgIFRlc3Qgd2hldGhlciB0aGlzIG1hcmsgaXMgaW4gdGhlIGdpdmVuIHNldCBvZiBtYXJrcy5cbiAgICAqL1xuICAgIGlzSW5TZXQoc2V0KSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2V0Lmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgaWYgKHRoaXMuZXEoc2V0W2ldKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICAvKipcbiAgICBUZXN0IHdoZXRoZXIgdGhpcyBtYXJrIGhhcyB0aGUgc2FtZSB0eXBlIGFuZCBhdHRyaWJ1dGVzIGFzXG4gICAgYW5vdGhlciBtYXJrLlxuICAgICovXG4gICAgZXEob3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMgPT0gb3RoZXIgfHxcbiAgICAgICAgICAgICh0aGlzLnR5cGUgPT0gb3RoZXIudHlwZSAmJiBjb21wYXJlRGVlcCh0aGlzLmF0dHJzLCBvdGhlci5hdHRycykpO1xuICAgIH1cbiAgICAvKipcbiAgICBDb252ZXJ0IHRoaXMgbWFyayB0byBhIEpTT04tc2VyaWFsaXplYWJsZSByZXByZXNlbnRhdGlvbi5cbiAgICAqL1xuICAgIHRvSlNPTigpIHtcbiAgICAgICAgbGV0IG9iaiA9IHsgdHlwZTogdGhpcy50eXBlLm5hbWUgfTtcbiAgICAgICAgZm9yIChsZXQgXyBpbiB0aGlzLmF0dHJzKSB7XG4gICAgICAgICAgICBvYmouYXR0cnMgPSB0aGlzLmF0dHJzO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9iajtcbiAgICB9XG4gICAgLyoqXG4gICAgRGVzZXJpYWxpemUgYSBtYXJrIGZyb20gSlNPTi5cbiAgICAqL1xuICAgIHN0YXRpYyBmcm9tSlNPTihzY2hlbWEsIGpzb24pIHtcbiAgICAgICAgaWYgKCFqc29uKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIGlucHV0IGZvciBNYXJrLmZyb21KU09OXCIpO1xuICAgICAgICBsZXQgdHlwZSA9IHNjaGVtYS5tYXJrc1tqc29uLnR5cGVdO1xuICAgICAgICBpZiAoIXR5cGUpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgVGhlcmUgaXMgbm8gbWFyayB0eXBlICR7anNvbi50eXBlfSBpbiB0aGlzIHNjaGVtYWApO1xuICAgICAgICBsZXQgbWFyayA9IHR5cGUuY3JlYXRlKGpzb24uYXR0cnMpO1xuICAgICAgICB0eXBlLmNoZWNrQXR0cnMobWFyay5hdHRycyk7XG4gICAgICAgIHJldHVybiBtYXJrO1xuICAgIH1cbiAgICAvKipcbiAgICBUZXN0IHdoZXRoZXIgdHdvIHNldHMgb2YgbWFya3MgYXJlIGlkZW50aWNhbC5cbiAgICAqL1xuICAgIHN0YXRpYyBzYW1lU2V0KGEsIGIpIHtcbiAgICAgICAgaWYgKGEgPT0gYilcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICBpZiAoYS5sZW5ndGggIT0gYi5sZW5ndGgpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIGlmICghYVtpXS5lcShiW2ldKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSBwcm9wZXJseSBzb3J0ZWQgbWFyayBzZXQgZnJvbSBudWxsLCBhIHNpbmdsZSBtYXJrLCBvciBhblxuICAgIHVuc29ydGVkIGFycmF5IG9mIG1hcmtzLlxuICAgICovXG4gICAgc3RhdGljIHNldEZyb20obWFya3MpIHtcbiAgICAgICAgaWYgKCFtYXJrcyB8fCBBcnJheS5pc0FycmF5KG1hcmtzKSAmJiBtYXJrcy5sZW5ndGggPT0gMClcbiAgICAgICAgICAgIHJldHVybiBNYXJrLm5vbmU7XG4gICAgICAgIGlmIChtYXJrcyBpbnN0YW5jZW9mIE1hcmspXG4gICAgICAgICAgICByZXR1cm4gW21hcmtzXTtcbiAgICAgICAgbGV0IGNvcHkgPSBtYXJrcy5zbGljZSgpO1xuICAgICAgICBjb3B5LnNvcnQoKGEsIGIpID0+IGEudHlwZS5yYW5rIC0gYi50eXBlLnJhbmspO1xuICAgICAgICByZXR1cm4gY29weTtcbiAgICB9XG59XG4vKipcblRoZSBlbXB0eSBzZXQgb2YgbWFya3MuXG4qL1xuTWFyay5ub25lID0gW107XG5cbi8qKlxuRXJyb3IgdHlwZSByYWlzZWQgYnkgW2BOb2RlLnJlcGxhY2VgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZS5yZXBsYWNlKSB3aGVuXG5naXZlbiBhbiBpbnZhbGlkIHJlcGxhY2VtZW50LlxuKi9cbmNsYXNzIFJlcGxhY2VFcnJvciBleHRlbmRzIEVycm9yIHtcbn1cbi8qXG5SZXBsYWNlRXJyb3IgPSBmdW5jdGlvbih0aGlzOiBhbnksIG1lc3NhZ2U6IHN0cmluZykge1xuICBsZXQgZXJyID0gRXJyb3IuY2FsbCh0aGlzLCBtZXNzYWdlKVxuICA7KGVyciBhcyBhbnkpLl9fcHJvdG9fXyA9IFJlcGxhY2VFcnJvci5wcm90b3R5cGVcbiAgcmV0dXJuIGVyclxufSBhcyBhbnlcblxuUmVwbGFjZUVycm9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoRXJyb3IucHJvdG90eXBlKVxuUmVwbGFjZUVycm9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFJlcGxhY2VFcnJvclxuUmVwbGFjZUVycm9yLnByb3RvdHlwZS5uYW1lID0gXCJSZXBsYWNlRXJyb3JcIlxuKi9cbi8qKlxuQSBzbGljZSByZXByZXNlbnRzIGEgcGllY2UgY3V0IG91dCBvZiBhIGxhcmdlciBkb2N1bWVudC4gSXRcbnN0b3JlcyBub3Qgb25seSBhIGZyYWdtZW50LCBidXQgYWxzbyB0aGUgZGVwdGggdXAgdG8gd2hpY2ggbm9kZXMgb25cbmJvdGggc2lkZSBhcmUgXHUyMDE4b3Blblx1MjAxOSAoY3V0IHRocm91Z2gpLlxuKi9cbmNsYXNzIFNsaWNlIHtcbiAgICAvKipcbiAgICBDcmVhdGUgYSBzbGljZS4gV2hlbiBzcGVjaWZ5aW5nIGEgbm9uLXplcm8gb3BlbiBkZXB0aCwgeW91IG11c3RcbiAgICBtYWtlIHN1cmUgdGhhdCB0aGVyZSBhcmUgbm9kZXMgb2YgYXQgbGVhc3QgdGhhdCBkZXB0aCBhdCB0aGVcbiAgICBhcHByb3ByaWF0ZSBzaWRlIG9mIHRoZSBmcmFnbWVudFx1MjAxNGkuZS4gaWYgdGhlIGZyYWdtZW50IGlzIGFuXG4gICAgZW1wdHkgcGFyYWdyYXBoIG5vZGUsIGBvcGVuU3RhcnRgIGFuZCBgb3BlbkVuZGAgY2FuJ3QgYmUgZ3JlYXRlclxuICAgIHRoYW4gMS5cbiAgICBcbiAgICBJdCBpcyBub3QgbmVjZXNzYXJ5IGZvciB0aGUgY29udGVudCBvZiBvcGVuIG5vZGVzIHRvIGNvbmZvcm0gdG9cbiAgICB0aGUgc2NoZW1hJ3MgY29udGVudCBjb25zdHJhaW50cywgdGhvdWdoIGl0IHNob3VsZCBiZSBhIHZhbGlkXG4gICAgc3RhcnQvZW5kL21pZGRsZSBmb3Igc3VjaCBhIG5vZGUsIGRlcGVuZGluZyBvbiB3aGljaCBzaWRlcyBhcmVcbiAgICBvcGVuLlxuICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgVGhlIHNsaWNlJ3MgY29udGVudC5cbiAgICAqL1xuICAgIGNvbnRlbnQsIFxuICAgIC8qKlxuICAgIFRoZSBvcGVuIGRlcHRoIGF0IHRoZSBzdGFydCBvZiB0aGUgZnJhZ21lbnQuXG4gICAgKi9cbiAgICBvcGVuU3RhcnQsIFxuICAgIC8qKlxuICAgIFRoZSBvcGVuIGRlcHRoIGF0IHRoZSBlbmQuXG4gICAgKi9cbiAgICBvcGVuRW5kKSB7XG4gICAgICAgIHRoaXMuY29udGVudCA9IGNvbnRlbnQ7XG4gICAgICAgIHRoaXMub3BlblN0YXJ0ID0gb3BlblN0YXJ0O1xuICAgICAgICB0aGlzLm9wZW5FbmQgPSBvcGVuRW5kO1xuICAgIH1cbiAgICAvKipcbiAgICBUaGUgc2l6ZSB0aGlzIHNsaWNlIHdvdWxkIGFkZCB3aGVuIGluc2VydGVkIGludG8gYSBkb2N1bWVudC5cbiAgICAqL1xuICAgIGdldCBzaXplKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250ZW50LnNpemUgLSB0aGlzLm9wZW5TdGFydCAtIHRoaXMub3BlbkVuZDtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBpbnNlcnRBdChwb3MsIGZyYWdtZW50KSB7XG4gICAgICAgIGxldCBjb250ZW50ID0gaW5zZXJ0SW50byh0aGlzLmNvbnRlbnQsIHBvcyArIHRoaXMub3BlblN0YXJ0LCBmcmFnbWVudCk7XG4gICAgICAgIHJldHVybiBjb250ZW50ICYmIG5ldyBTbGljZShjb250ZW50LCB0aGlzLm9wZW5TdGFydCwgdGhpcy5vcGVuRW5kKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICByZW1vdmVCZXR3ZWVuKGZyb20sIHRvKSB7XG4gICAgICAgIHJldHVybiBuZXcgU2xpY2UocmVtb3ZlUmFuZ2UodGhpcy5jb250ZW50LCBmcm9tICsgdGhpcy5vcGVuU3RhcnQsIHRvICsgdGhpcy5vcGVuU3RhcnQpLCB0aGlzLm9wZW5TdGFydCwgdGhpcy5vcGVuRW5kKTtcbiAgICB9XG4gICAgLyoqXG4gICAgVGVzdHMgd2hldGhlciB0aGlzIHNsaWNlIGlzIGVxdWFsIHRvIGFub3RoZXIgc2xpY2UuXG4gICAgKi9cbiAgICBlcShvdGhlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5jb250ZW50LmVxKG90aGVyLmNvbnRlbnQpICYmIHRoaXMub3BlblN0YXJ0ID09IG90aGVyLm9wZW5TdGFydCAmJiB0aGlzLm9wZW5FbmQgPT0gb3RoZXIub3BlbkVuZDtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICB0b1N0cmluZygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGVudCArIFwiKFwiICsgdGhpcy5vcGVuU3RhcnQgKyBcIixcIiArIHRoaXMub3BlbkVuZCArIFwiKVwiO1xuICAgIH1cbiAgICAvKipcbiAgICBDb252ZXJ0IGEgc2xpY2UgdG8gYSBKU09OLXNlcmlhbGl6YWJsZSByZXByZXNlbnRhdGlvbi5cbiAgICAqL1xuICAgIHRvSlNPTigpIHtcbiAgICAgICAgaWYgKCF0aGlzLmNvbnRlbnQuc2l6ZSlcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICBsZXQganNvbiA9IHsgY29udGVudDogdGhpcy5jb250ZW50LnRvSlNPTigpIH07XG4gICAgICAgIGlmICh0aGlzLm9wZW5TdGFydCA+IDApXG4gICAgICAgICAgICBqc29uLm9wZW5TdGFydCA9IHRoaXMub3BlblN0YXJ0O1xuICAgICAgICBpZiAodGhpcy5vcGVuRW5kID4gMClcbiAgICAgICAgICAgIGpzb24ub3BlbkVuZCA9IHRoaXMub3BlbkVuZDtcbiAgICAgICAgcmV0dXJuIGpzb247XG4gICAgfVxuICAgIC8qKlxuICAgIERlc2VyaWFsaXplIGEgc2xpY2UgZnJvbSBpdHMgSlNPTiByZXByZXNlbnRhdGlvbi5cbiAgICAqL1xuICAgIHN0YXRpYyBmcm9tSlNPTihzY2hlbWEsIGpzb24pIHtcbiAgICAgICAgaWYgKCFqc29uKVxuICAgICAgICAgICAgcmV0dXJuIFNsaWNlLmVtcHR5O1xuICAgICAgICBsZXQgb3BlblN0YXJ0ID0ganNvbi5vcGVuU3RhcnQgfHwgMCwgb3BlbkVuZCA9IGpzb24ub3BlbkVuZCB8fCAwO1xuICAgICAgICBpZiAodHlwZW9mIG9wZW5TdGFydCAhPSBcIm51bWJlclwiIHx8IHR5cGVvZiBvcGVuRW5kICE9IFwibnVtYmVyXCIpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkludmFsaWQgaW5wdXQgZm9yIFNsaWNlLmZyb21KU09OXCIpO1xuICAgICAgICByZXR1cm4gbmV3IFNsaWNlKEZyYWdtZW50LmZyb21KU09OKHNjaGVtYSwganNvbi5jb250ZW50KSwgb3BlblN0YXJ0LCBvcGVuRW5kKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgc2xpY2UgZnJvbSBhIGZyYWdtZW50IGJ5IHRha2luZyB0aGUgbWF4aW11bSBwb3NzaWJsZVxuICAgIG9wZW4gdmFsdWUgb24gYm90aCBzaWRlIG9mIHRoZSBmcmFnbWVudC5cbiAgICAqL1xuICAgIHN0YXRpYyBtYXhPcGVuKGZyYWdtZW50LCBvcGVuSXNvbGF0aW5nID0gdHJ1ZSkge1xuICAgICAgICBsZXQgb3BlblN0YXJ0ID0gMCwgb3BlbkVuZCA9IDA7XG4gICAgICAgIGZvciAobGV0IG4gPSBmcmFnbWVudC5maXJzdENoaWxkOyBuICYmICFuLmlzTGVhZiAmJiAob3Blbklzb2xhdGluZyB8fCAhbi50eXBlLnNwZWMuaXNvbGF0aW5nKTsgbiA9IG4uZmlyc3RDaGlsZClcbiAgICAgICAgICAgIG9wZW5TdGFydCsrO1xuICAgICAgICBmb3IgKGxldCBuID0gZnJhZ21lbnQubGFzdENoaWxkOyBuICYmICFuLmlzTGVhZiAmJiAob3Blbklzb2xhdGluZyB8fCAhbi50eXBlLnNwZWMuaXNvbGF0aW5nKTsgbiA9IG4ubGFzdENoaWxkKVxuICAgICAgICAgICAgb3BlbkVuZCsrO1xuICAgICAgICByZXR1cm4gbmV3IFNsaWNlKGZyYWdtZW50LCBvcGVuU3RhcnQsIG9wZW5FbmQpO1xuICAgIH1cbn1cbi8qKlxuVGhlIGVtcHR5IHNsaWNlLlxuKi9cblNsaWNlLmVtcHR5ID0gbmV3IFNsaWNlKEZyYWdtZW50LmVtcHR5LCAwLCAwKTtcbmZ1bmN0aW9uIHJlbW92ZVJhbmdlKGNvbnRlbnQsIGZyb20sIHRvKSB7XG4gICAgbGV0IHsgaW5kZXgsIG9mZnNldCB9ID0gY29udGVudC5maW5kSW5kZXgoZnJvbSksIGNoaWxkID0gY29udGVudC5tYXliZUNoaWxkKGluZGV4KTtcbiAgICBsZXQgeyBpbmRleDogaW5kZXhUbywgb2Zmc2V0OiBvZmZzZXRUbyB9ID0gY29udGVudC5maW5kSW5kZXgodG8pO1xuICAgIGlmIChvZmZzZXQgPT0gZnJvbSB8fCBjaGlsZC5pc1RleHQpIHtcbiAgICAgICAgaWYgKG9mZnNldFRvICE9IHRvICYmICFjb250ZW50LmNoaWxkKGluZGV4VG8pLmlzVGV4dClcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiUmVtb3Zpbmcgbm9uLWZsYXQgcmFuZ2VcIik7XG4gICAgICAgIHJldHVybiBjb250ZW50LmN1dCgwLCBmcm9tKS5hcHBlbmQoY29udGVudC5jdXQodG8pKTtcbiAgICB9XG4gICAgaWYgKGluZGV4ICE9IGluZGV4VG8pXG4gICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiUmVtb3Zpbmcgbm9uLWZsYXQgcmFuZ2VcIik7XG4gICAgcmV0dXJuIGNvbnRlbnQucmVwbGFjZUNoaWxkKGluZGV4LCBjaGlsZC5jb3B5KHJlbW92ZVJhbmdlKGNoaWxkLmNvbnRlbnQsIGZyb20gLSBvZmZzZXQgLSAxLCB0byAtIG9mZnNldCAtIDEpKSk7XG59XG5mdW5jdGlvbiBpbnNlcnRJbnRvKGNvbnRlbnQsIGRpc3QsIGluc2VydCwgcGFyZW50KSB7XG4gICAgbGV0IHsgaW5kZXgsIG9mZnNldCB9ID0gY29udGVudC5maW5kSW5kZXgoZGlzdCksIGNoaWxkID0gY29udGVudC5tYXliZUNoaWxkKGluZGV4KTtcbiAgICBpZiAob2Zmc2V0ID09IGRpc3QgfHwgY2hpbGQuaXNUZXh0KSB7XG4gICAgICAgIGlmIChwYXJlbnQgJiYgIXBhcmVudC5jYW5SZXBsYWNlKGluZGV4LCBpbmRleCwgaW5zZXJ0KSlcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICByZXR1cm4gY29udGVudC5jdXQoMCwgZGlzdCkuYXBwZW5kKGluc2VydCkuYXBwZW5kKGNvbnRlbnQuY3V0KGRpc3QpKTtcbiAgICB9XG4gICAgbGV0IGlubmVyID0gaW5zZXJ0SW50byhjaGlsZC5jb250ZW50LCBkaXN0IC0gb2Zmc2V0IC0gMSwgaW5zZXJ0KTtcbiAgICByZXR1cm4gaW5uZXIgJiYgY29udGVudC5yZXBsYWNlQ2hpbGQoaW5kZXgsIGNoaWxkLmNvcHkoaW5uZXIpKTtcbn1cbmZ1bmN0aW9uIHJlcGxhY2UoJGZyb20sICR0bywgc2xpY2UpIHtcbiAgICBpZiAoc2xpY2Uub3BlblN0YXJ0ID4gJGZyb20uZGVwdGgpXG4gICAgICAgIHRocm93IG5ldyBSZXBsYWNlRXJyb3IoXCJJbnNlcnRlZCBjb250ZW50IGRlZXBlciB0aGFuIGluc2VydGlvbiBwb3NpdGlvblwiKTtcbiAgICBpZiAoJGZyb20uZGVwdGggLSBzbGljZS5vcGVuU3RhcnQgIT0gJHRvLmRlcHRoIC0gc2xpY2Uub3BlbkVuZClcbiAgICAgICAgdGhyb3cgbmV3IFJlcGxhY2VFcnJvcihcIkluY29uc2lzdGVudCBvcGVuIGRlcHRoc1wiKTtcbiAgICByZXR1cm4gcmVwbGFjZU91dGVyKCRmcm9tLCAkdG8sIHNsaWNlLCAwKTtcbn1cbmZ1bmN0aW9uIHJlcGxhY2VPdXRlcigkZnJvbSwgJHRvLCBzbGljZSwgZGVwdGgpIHtcbiAgICBsZXQgaW5kZXggPSAkZnJvbS5pbmRleChkZXB0aCksIG5vZGUgPSAkZnJvbS5ub2RlKGRlcHRoKTtcbiAgICBpZiAoaW5kZXggPT0gJHRvLmluZGV4KGRlcHRoKSAmJiBkZXB0aCA8ICRmcm9tLmRlcHRoIC0gc2xpY2Uub3BlblN0YXJ0KSB7XG4gICAgICAgIGxldCBpbm5lciA9IHJlcGxhY2VPdXRlcigkZnJvbSwgJHRvLCBzbGljZSwgZGVwdGggKyAxKTtcbiAgICAgICAgcmV0dXJuIG5vZGUuY29weShub2RlLmNvbnRlbnQucmVwbGFjZUNoaWxkKGluZGV4LCBpbm5lcikpO1xuICAgIH1cbiAgICBlbHNlIGlmICghc2xpY2UuY29udGVudC5zaXplKSB7XG4gICAgICAgIHJldHVybiBjbG9zZShub2RlLCByZXBsYWNlVHdvV2F5KCRmcm9tLCAkdG8sIGRlcHRoKSk7XG4gICAgfVxuICAgIGVsc2UgaWYgKCFzbGljZS5vcGVuU3RhcnQgJiYgIXNsaWNlLm9wZW5FbmQgJiYgJGZyb20uZGVwdGggPT0gZGVwdGggJiYgJHRvLmRlcHRoID09IGRlcHRoKSB7IC8vIFNpbXBsZSwgZmxhdCBjYXNlXG4gICAgICAgIGxldCBwYXJlbnQgPSAkZnJvbS5wYXJlbnQsIGNvbnRlbnQgPSBwYXJlbnQuY29udGVudDtcbiAgICAgICAgcmV0dXJuIGNsb3NlKHBhcmVudCwgY29udGVudC5jdXQoMCwgJGZyb20ucGFyZW50T2Zmc2V0KS5hcHBlbmQoc2xpY2UuY29udGVudCkuYXBwZW5kKGNvbnRlbnQuY3V0KCR0by5wYXJlbnRPZmZzZXQpKSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBsZXQgeyBzdGFydCwgZW5kIH0gPSBwcmVwYXJlU2xpY2VGb3JSZXBsYWNlKHNsaWNlLCAkZnJvbSk7XG4gICAgICAgIHJldHVybiBjbG9zZShub2RlLCByZXBsYWNlVGhyZWVXYXkoJGZyb20sIHN0YXJ0LCBlbmQsICR0bywgZGVwdGgpKTtcbiAgICB9XG59XG5mdW5jdGlvbiBjaGVja0pvaW4obWFpbiwgc3ViKSB7XG4gICAgaWYgKCFzdWIudHlwZS5jb21wYXRpYmxlQ29udGVudChtYWluLnR5cGUpKVxuICAgICAgICB0aHJvdyBuZXcgUmVwbGFjZUVycm9yKFwiQ2Fubm90IGpvaW4gXCIgKyBzdWIudHlwZS5uYW1lICsgXCIgb250byBcIiArIG1haW4udHlwZS5uYW1lKTtcbn1cbmZ1bmN0aW9uIGpvaW5hYmxlKCRiZWZvcmUsICRhZnRlciwgZGVwdGgpIHtcbiAgICBsZXQgbm9kZSA9ICRiZWZvcmUubm9kZShkZXB0aCk7XG4gICAgY2hlY2tKb2luKG5vZGUsICRhZnRlci5ub2RlKGRlcHRoKSk7XG4gICAgcmV0dXJuIG5vZGU7XG59XG5mdW5jdGlvbiBhZGROb2RlKGNoaWxkLCB0YXJnZXQpIHtcbiAgICBsZXQgbGFzdCA9IHRhcmdldC5sZW5ndGggLSAxO1xuICAgIGlmIChsYXN0ID49IDAgJiYgY2hpbGQuaXNUZXh0ICYmIGNoaWxkLnNhbWVNYXJrdXAodGFyZ2V0W2xhc3RdKSlcbiAgICAgICAgdGFyZ2V0W2xhc3RdID0gY2hpbGQud2l0aFRleHQodGFyZ2V0W2xhc3RdLnRleHQgKyBjaGlsZC50ZXh0KTtcbiAgICBlbHNlXG4gICAgICAgIHRhcmdldC5wdXNoKGNoaWxkKTtcbn1cbmZ1bmN0aW9uIGFkZFJhbmdlKCRzdGFydCwgJGVuZCwgZGVwdGgsIHRhcmdldCkge1xuICAgIGxldCBub2RlID0gKCRlbmQgfHwgJHN0YXJ0KS5ub2RlKGRlcHRoKTtcbiAgICBsZXQgc3RhcnRJbmRleCA9IDAsIGVuZEluZGV4ID0gJGVuZCA/ICRlbmQuaW5kZXgoZGVwdGgpIDogbm9kZS5jaGlsZENvdW50O1xuICAgIGlmICgkc3RhcnQpIHtcbiAgICAgICAgc3RhcnRJbmRleCA9ICRzdGFydC5pbmRleChkZXB0aCk7XG4gICAgICAgIGlmICgkc3RhcnQuZGVwdGggPiBkZXB0aCkge1xuICAgICAgICAgICAgc3RhcnRJbmRleCsrO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKCRzdGFydC50ZXh0T2Zmc2V0KSB7XG4gICAgICAgICAgICBhZGROb2RlKCRzdGFydC5ub2RlQWZ0ZXIsIHRhcmdldCk7XG4gICAgICAgICAgICBzdGFydEluZGV4Kys7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZm9yIChsZXQgaSA9IHN0YXJ0SW5kZXg7IGkgPCBlbmRJbmRleDsgaSsrKVxuICAgICAgICBhZGROb2RlKG5vZGUuY2hpbGQoaSksIHRhcmdldCk7XG4gICAgaWYgKCRlbmQgJiYgJGVuZC5kZXB0aCA9PSBkZXB0aCAmJiAkZW5kLnRleHRPZmZzZXQpXG4gICAgICAgIGFkZE5vZGUoJGVuZC5ub2RlQmVmb3JlLCB0YXJnZXQpO1xufVxuZnVuY3Rpb24gY2xvc2Uobm9kZSwgY29udGVudCkge1xuICAgIG5vZGUudHlwZS5jaGVja0NvbnRlbnQoY29udGVudCk7XG4gICAgcmV0dXJuIG5vZGUuY29weShjb250ZW50KTtcbn1cbmZ1bmN0aW9uIHJlcGxhY2VUaHJlZVdheSgkZnJvbSwgJHN0YXJ0LCAkZW5kLCAkdG8sIGRlcHRoKSB7XG4gICAgbGV0IG9wZW5TdGFydCA9ICRmcm9tLmRlcHRoID4gZGVwdGggJiYgam9pbmFibGUoJGZyb20sICRzdGFydCwgZGVwdGggKyAxKTtcbiAgICBsZXQgb3BlbkVuZCA9ICR0by5kZXB0aCA+IGRlcHRoICYmIGpvaW5hYmxlKCRlbmQsICR0bywgZGVwdGggKyAxKTtcbiAgICBsZXQgY29udGVudCA9IFtdO1xuICAgIGFkZFJhbmdlKG51bGwsICRmcm9tLCBkZXB0aCwgY29udGVudCk7XG4gICAgaWYgKG9wZW5TdGFydCAmJiBvcGVuRW5kICYmICRzdGFydC5pbmRleChkZXB0aCkgPT0gJGVuZC5pbmRleChkZXB0aCkpIHtcbiAgICAgICAgY2hlY2tKb2luKG9wZW5TdGFydCwgb3BlbkVuZCk7XG4gICAgICAgIGFkZE5vZGUoY2xvc2Uob3BlblN0YXJ0LCByZXBsYWNlVGhyZWVXYXkoJGZyb20sICRzdGFydCwgJGVuZCwgJHRvLCBkZXB0aCArIDEpKSwgY29udGVudCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBpZiAob3BlblN0YXJ0KVxuICAgICAgICAgICAgYWRkTm9kZShjbG9zZShvcGVuU3RhcnQsIHJlcGxhY2VUd29XYXkoJGZyb20sICRzdGFydCwgZGVwdGggKyAxKSksIGNvbnRlbnQpO1xuICAgICAgICBhZGRSYW5nZSgkc3RhcnQsICRlbmQsIGRlcHRoLCBjb250ZW50KTtcbiAgICAgICAgaWYgKG9wZW5FbmQpXG4gICAgICAgICAgICBhZGROb2RlKGNsb3NlKG9wZW5FbmQsIHJlcGxhY2VUd29XYXkoJGVuZCwgJHRvLCBkZXB0aCArIDEpKSwgY29udGVudCk7XG4gICAgfVxuICAgIGFkZFJhbmdlKCR0bywgbnVsbCwgZGVwdGgsIGNvbnRlbnQpO1xuICAgIHJldHVybiBuZXcgRnJhZ21lbnQoY29udGVudCk7XG59XG5mdW5jdGlvbiByZXBsYWNlVHdvV2F5KCRmcm9tLCAkdG8sIGRlcHRoKSB7XG4gICAgbGV0IGNvbnRlbnQgPSBbXTtcbiAgICBhZGRSYW5nZShudWxsLCAkZnJvbSwgZGVwdGgsIGNvbnRlbnQpO1xuICAgIGlmICgkZnJvbS5kZXB0aCA+IGRlcHRoKSB7XG4gICAgICAgIGxldCB0eXBlID0gam9pbmFibGUoJGZyb20sICR0bywgZGVwdGggKyAxKTtcbiAgICAgICAgYWRkTm9kZShjbG9zZSh0eXBlLCByZXBsYWNlVHdvV2F5KCRmcm9tLCAkdG8sIGRlcHRoICsgMSkpLCBjb250ZW50KTtcbiAgICB9XG4gICAgYWRkUmFuZ2UoJHRvLCBudWxsLCBkZXB0aCwgY29udGVudCk7XG4gICAgcmV0dXJuIG5ldyBGcmFnbWVudChjb250ZW50KTtcbn1cbmZ1bmN0aW9uIHByZXBhcmVTbGljZUZvclJlcGxhY2Uoc2xpY2UsICRhbG9uZykge1xuICAgIGxldCBleHRyYSA9ICRhbG9uZy5kZXB0aCAtIHNsaWNlLm9wZW5TdGFydCwgcGFyZW50ID0gJGFsb25nLm5vZGUoZXh0cmEpO1xuICAgIGxldCBub2RlID0gcGFyZW50LmNvcHkoc2xpY2UuY29udGVudCk7XG4gICAgZm9yIChsZXQgaSA9IGV4dHJhIC0gMTsgaSA+PSAwOyBpLS0pXG4gICAgICAgIG5vZGUgPSAkYWxvbmcubm9kZShpKS5jb3B5KEZyYWdtZW50LmZyb20obm9kZSkpO1xuICAgIHJldHVybiB7IHN0YXJ0OiBub2RlLnJlc29sdmVOb0NhY2hlKHNsaWNlLm9wZW5TdGFydCArIGV4dHJhKSxcbiAgICAgICAgZW5kOiBub2RlLnJlc29sdmVOb0NhY2hlKG5vZGUuY29udGVudC5zaXplIC0gc2xpY2Uub3BlbkVuZCAtIGV4dHJhKSB9O1xufVxuXG4vKipcbllvdSBjYW4gW19yZXNvbHZlX10oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGUucmVzb2x2ZSkgYSBwb3NpdGlvbiB0byBnZXQgbW9yZVxuaW5mb3JtYXRpb24gYWJvdXQgaXQuIE9iamVjdHMgb2YgdGhpcyBjbGFzcyByZXByZXNlbnQgc3VjaCBhXG5yZXNvbHZlZCBwb3NpdGlvbiwgcHJvdmlkaW5nIHZhcmlvdXMgcGllY2VzIG9mIGNvbnRleHRcbmluZm9ybWF0aW9uLCBhbmQgc29tZSBoZWxwZXIgbWV0aG9kcy5cblxuVGhyb3VnaG91dCB0aGlzIGludGVyZmFjZSwgbWV0aG9kcyB0aGF0IHRha2UgYW4gb3B0aW9uYWwgYGRlcHRoYFxucGFyYW1ldGVyIHdpbGwgaW50ZXJwcmV0IHVuZGVmaW5lZCBhcyBgdGhpcy5kZXB0aGAgYW5kIG5lZ2F0aXZlXG5udW1iZXJzIGFzIGB0aGlzLmRlcHRoICsgdmFsdWVgLlxuKi9cbmNsYXNzIFJlc29sdmVkUG9zIHtcbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgIFRoZSBwb3NpdGlvbiB0aGF0IHdhcyByZXNvbHZlZC5cbiAgICAqL1xuICAgIHBvcywgXG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBwYXRoLCBcbiAgICAvKipcbiAgICBUaGUgb2Zmc2V0IHRoaXMgcG9zaXRpb24gaGFzIGludG8gaXRzIHBhcmVudCBub2RlLlxuICAgICovXG4gICAgcGFyZW50T2Zmc2V0KSB7XG4gICAgICAgIHRoaXMucG9zID0gcG9zO1xuICAgICAgICB0aGlzLnBhdGggPSBwYXRoO1xuICAgICAgICB0aGlzLnBhcmVudE9mZnNldCA9IHBhcmVudE9mZnNldDtcbiAgICAgICAgdGhpcy5kZXB0aCA9IHBhdGgubGVuZ3RoIC8gMyAtIDE7XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgcmVzb2x2ZURlcHRoKHZhbCkge1xuICAgICAgICBpZiAodmFsID09IG51bGwpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kZXB0aDtcbiAgICAgICAgaWYgKHZhbCA8IDApXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kZXB0aCArIHZhbDtcbiAgICAgICAgcmV0dXJuIHZhbDtcbiAgICB9XG4gICAgLyoqXG4gICAgVGhlIHBhcmVudCBub2RlIHRoYXQgdGhlIHBvc2l0aW9uIHBvaW50cyBpbnRvLiBOb3RlIHRoYXQgZXZlbiBpZlxuICAgIGEgcG9zaXRpb24gcG9pbnRzIGludG8gYSB0ZXh0IG5vZGUsIHRoYXQgbm9kZSBpcyBub3QgY29uc2lkZXJlZFxuICAgIHRoZSBwYXJlbnRcdTIwMTR0ZXh0IG5vZGVzIGFyZSBcdTIwMThmbGF0XHUyMDE5IGluIHRoaXMgbW9kZWwsIGFuZCBoYXZlIG5vIGNvbnRlbnQuXG4gICAgKi9cbiAgICBnZXQgcGFyZW50KCkgeyByZXR1cm4gdGhpcy5ub2RlKHRoaXMuZGVwdGgpOyB9XG4gICAgLyoqXG4gICAgVGhlIHJvb3Qgbm9kZSBpbiB3aGljaCB0aGUgcG9zaXRpb24gd2FzIHJlc29sdmVkLlxuICAgICovXG4gICAgZ2V0IGRvYygpIHsgcmV0dXJuIHRoaXMubm9kZSgwKTsgfVxuICAgIC8qKlxuICAgIFRoZSBhbmNlc3RvciBub2RlIGF0IHRoZSBnaXZlbiBsZXZlbC4gYHAubm9kZShwLmRlcHRoKWAgaXMgdGhlXG4gICAgc2FtZSBhcyBgcC5wYXJlbnRgLlxuICAgICovXG4gICAgbm9kZShkZXB0aCkgeyByZXR1cm4gdGhpcy5wYXRoW3RoaXMucmVzb2x2ZURlcHRoKGRlcHRoKSAqIDNdOyB9XG4gICAgLyoqXG4gICAgVGhlIGluZGV4IGludG8gdGhlIGFuY2VzdG9yIGF0IHRoZSBnaXZlbiBsZXZlbC4gSWYgdGhpcyBwb2ludHNcbiAgICBhdCB0aGUgM3JkIG5vZGUgaW4gdGhlIDJuZCBwYXJhZ3JhcGggb24gdGhlIHRvcCBsZXZlbCwgZm9yXG4gICAgZXhhbXBsZSwgYHAuaW5kZXgoMClgIGlzIDEgYW5kIGBwLmluZGV4KDEpYCBpcyAyLlxuICAgICovXG4gICAgaW5kZXgoZGVwdGgpIHsgcmV0dXJuIHRoaXMucGF0aFt0aGlzLnJlc29sdmVEZXB0aChkZXB0aCkgKiAzICsgMV07IH1cbiAgICAvKipcbiAgICBUaGUgaW5kZXggcG9pbnRpbmcgYWZ0ZXIgdGhpcyBwb3NpdGlvbiBpbnRvIHRoZSBhbmNlc3RvciBhdCB0aGVcbiAgICBnaXZlbiBsZXZlbC5cbiAgICAqL1xuICAgIGluZGV4QWZ0ZXIoZGVwdGgpIHtcbiAgICAgICAgZGVwdGggPSB0aGlzLnJlc29sdmVEZXB0aChkZXB0aCk7XG4gICAgICAgIHJldHVybiB0aGlzLmluZGV4KGRlcHRoKSArIChkZXB0aCA9PSB0aGlzLmRlcHRoICYmICF0aGlzLnRleHRPZmZzZXQgPyAwIDogMSk7XG4gICAgfVxuICAgIC8qKlxuICAgIFRoZSAoYWJzb2x1dGUpIHBvc2l0aW9uIGF0IHRoZSBzdGFydCBvZiB0aGUgbm9kZSBhdCB0aGUgZ2l2ZW5cbiAgICBsZXZlbC5cbiAgICAqL1xuICAgIHN0YXJ0KGRlcHRoKSB7XG4gICAgICAgIGRlcHRoID0gdGhpcy5yZXNvbHZlRGVwdGgoZGVwdGgpO1xuICAgICAgICByZXR1cm4gZGVwdGggPT0gMCA/IDAgOiB0aGlzLnBhdGhbZGVwdGggKiAzIC0gMV0gKyAxO1xuICAgIH1cbiAgICAvKipcbiAgICBUaGUgKGFic29sdXRlKSBwb3NpdGlvbiBhdCB0aGUgZW5kIG9mIHRoZSBub2RlIGF0IHRoZSBnaXZlblxuICAgIGxldmVsLlxuICAgICovXG4gICAgZW5kKGRlcHRoKSB7XG4gICAgICAgIGRlcHRoID0gdGhpcy5yZXNvbHZlRGVwdGgoZGVwdGgpO1xuICAgICAgICByZXR1cm4gdGhpcy5zdGFydChkZXB0aCkgKyB0aGlzLm5vZGUoZGVwdGgpLmNvbnRlbnQuc2l6ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgVGhlIChhYnNvbHV0ZSkgcG9zaXRpb24gZGlyZWN0bHkgYmVmb3JlIHRoZSB3cmFwcGluZyBub2RlIGF0IHRoZVxuICAgIGdpdmVuIGxldmVsLCBvciwgd2hlbiBgZGVwdGhgIGlzIGB0aGlzLmRlcHRoICsgMWAsIHRoZSBvcmlnaW5hbFxuICAgIHBvc2l0aW9uLlxuICAgICovXG4gICAgYmVmb3JlKGRlcHRoKSB7XG4gICAgICAgIGRlcHRoID0gdGhpcy5yZXNvbHZlRGVwdGgoZGVwdGgpO1xuICAgICAgICBpZiAoIWRlcHRoKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJUaGVyZSBpcyBubyBwb3NpdGlvbiBiZWZvcmUgdGhlIHRvcC1sZXZlbCBub2RlXCIpO1xuICAgICAgICByZXR1cm4gZGVwdGggPT0gdGhpcy5kZXB0aCArIDEgPyB0aGlzLnBvcyA6IHRoaXMucGF0aFtkZXB0aCAqIDMgLSAxXTtcbiAgICB9XG4gICAgLyoqXG4gICAgVGhlIChhYnNvbHV0ZSkgcG9zaXRpb24gZGlyZWN0bHkgYWZ0ZXIgdGhlIHdyYXBwaW5nIG5vZGUgYXQgdGhlXG4gICAgZ2l2ZW4gbGV2ZWwsIG9yIHRoZSBvcmlnaW5hbCBwb3NpdGlvbiB3aGVuIGBkZXB0aGAgaXMgYHRoaXMuZGVwdGggKyAxYC5cbiAgICAqL1xuICAgIGFmdGVyKGRlcHRoKSB7XG4gICAgICAgIGRlcHRoID0gdGhpcy5yZXNvbHZlRGVwdGgoZGVwdGgpO1xuICAgICAgICBpZiAoIWRlcHRoKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJUaGVyZSBpcyBubyBwb3NpdGlvbiBhZnRlciB0aGUgdG9wLWxldmVsIG5vZGVcIik7XG4gICAgICAgIHJldHVybiBkZXB0aCA9PSB0aGlzLmRlcHRoICsgMSA/IHRoaXMucG9zIDogdGhpcy5wYXRoW2RlcHRoICogMyAtIDFdICsgdGhpcy5wYXRoW2RlcHRoICogM10ubm9kZVNpemU7XG4gICAgfVxuICAgIC8qKlxuICAgIFdoZW4gdGhpcyBwb3NpdGlvbiBwb2ludHMgaW50byBhIHRleHQgbm9kZSwgdGhpcyByZXR1cm5zIHRoZVxuICAgIGRpc3RhbmNlIGJldHdlZW4gdGhlIHBvc2l0aW9uIGFuZCB0aGUgc3RhcnQgb2YgdGhlIHRleHQgbm9kZS5cbiAgICBXaWxsIGJlIHplcm8gZm9yIHBvc2l0aW9ucyB0aGF0IHBvaW50IGJldHdlZW4gbm9kZXMuXG4gICAgKi9cbiAgICBnZXQgdGV4dE9mZnNldCgpIHsgcmV0dXJuIHRoaXMucG9zIC0gdGhpcy5wYXRoW3RoaXMucGF0aC5sZW5ndGggLSAxXTsgfVxuICAgIC8qKlxuICAgIEdldCB0aGUgbm9kZSBkaXJlY3RseSBhZnRlciB0aGUgcG9zaXRpb24sIGlmIGFueS4gSWYgdGhlIHBvc2l0aW9uXG4gICAgcG9pbnRzIGludG8gYSB0ZXh0IG5vZGUsIG9ubHkgdGhlIHBhcnQgb2YgdGhhdCBub2RlIGFmdGVyIHRoZVxuICAgIHBvc2l0aW9uIGlzIHJldHVybmVkLlxuICAgICovXG4gICAgZ2V0IG5vZGVBZnRlcigpIHtcbiAgICAgICAgbGV0IHBhcmVudCA9IHRoaXMucGFyZW50LCBpbmRleCA9IHRoaXMuaW5kZXgodGhpcy5kZXB0aCk7XG4gICAgICAgIGlmIChpbmRleCA9PSBwYXJlbnQuY2hpbGRDb3VudClcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICBsZXQgZE9mZiA9IHRoaXMucG9zIC0gdGhpcy5wYXRoW3RoaXMucGF0aC5sZW5ndGggLSAxXSwgY2hpbGQgPSBwYXJlbnQuY2hpbGQoaW5kZXgpO1xuICAgICAgICByZXR1cm4gZE9mZiA/IHBhcmVudC5jaGlsZChpbmRleCkuY3V0KGRPZmYpIDogY2hpbGQ7XG4gICAgfVxuICAgIC8qKlxuICAgIEdldCB0aGUgbm9kZSBkaXJlY3RseSBiZWZvcmUgdGhlIHBvc2l0aW9uLCBpZiBhbnkuIElmIHRoZVxuICAgIHBvc2l0aW9uIHBvaW50cyBpbnRvIGEgdGV4dCBub2RlLCBvbmx5IHRoZSBwYXJ0IG9mIHRoYXQgbm9kZVxuICAgIGJlZm9yZSB0aGUgcG9zaXRpb24gaXMgcmV0dXJuZWQuXG4gICAgKi9cbiAgICBnZXQgbm9kZUJlZm9yZSgpIHtcbiAgICAgICAgbGV0IGluZGV4ID0gdGhpcy5pbmRleCh0aGlzLmRlcHRoKTtcbiAgICAgICAgbGV0IGRPZmYgPSB0aGlzLnBvcyAtIHRoaXMucGF0aFt0aGlzLnBhdGgubGVuZ3RoIC0gMV07XG4gICAgICAgIGlmIChkT2ZmKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMucGFyZW50LmNoaWxkKGluZGV4KS5jdXQoMCwgZE9mZik7XG4gICAgICAgIHJldHVybiBpbmRleCA9PSAwID8gbnVsbCA6IHRoaXMucGFyZW50LmNoaWxkKGluZGV4IC0gMSk7XG4gICAgfVxuICAgIC8qKlxuICAgIEdldCB0aGUgcG9zaXRpb24gYXQgdGhlIGdpdmVuIGluZGV4IGluIHRoZSBwYXJlbnQgbm9kZSBhdCB0aGVcbiAgICBnaXZlbiBkZXB0aCAod2hpY2ggZGVmYXVsdHMgdG8gYHRoaXMuZGVwdGhgKS5cbiAgICAqL1xuICAgIHBvc0F0SW5kZXgoaW5kZXgsIGRlcHRoKSB7XG4gICAgICAgIGRlcHRoID0gdGhpcy5yZXNvbHZlRGVwdGgoZGVwdGgpO1xuICAgICAgICBsZXQgbm9kZSA9IHRoaXMucGF0aFtkZXB0aCAqIDNdLCBwb3MgPSBkZXB0aCA9PSAwID8gMCA6IHRoaXMucGF0aFtkZXB0aCAqIDMgLSAxXSArIDE7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5kZXg7IGkrKylcbiAgICAgICAgICAgIHBvcyArPSBub2RlLmNoaWxkKGkpLm5vZGVTaXplO1xuICAgICAgICByZXR1cm4gcG9zO1xuICAgIH1cbiAgICAvKipcbiAgICBHZXQgdGhlIG1hcmtzIGF0IHRoaXMgcG9zaXRpb24sIGZhY3RvcmluZyBpbiB0aGUgc3Vycm91bmRpbmdcbiAgICBtYXJrcycgW2BpbmNsdXNpdmVgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTWFya1NwZWMuaW5jbHVzaXZlKSBwcm9wZXJ0eS4gSWYgdGhlXG4gICAgcG9zaXRpb24gaXMgYXQgdGhlIHN0YXJ0IG9mIGEgbm9uLWVtcHR5IG5vZGUsIHRoZSBtYXJrcyBvZiB0aGVcbiAgICBub2RlIGFmdGVyIGl0IChpZiBhbnkpIGFyZSByZXR1cm5lZC5cbiAgICAqL1xuICAgIG1hcmtzKCkge1xuICAgICAgICBsZXQgcGFyZW50ID0gdGhpcy5wYXJlbnQsIGluZGV4ID0gdGhpcy5pbmRleCgpO1xuICAgICAgICAvLyBJbiBhbiBlbXB0eSBwYXJlbnQsIHJldHVybiB0aGUgZW1wdHkgYXJyYXlcbiAgICAgICAgaWYgKHBhcmVudC5jb250ZW50LnNpemUgPT0gMClcbiAgICAgICAgICAgIHJldHVybiBNYXJrLm5vbmU7XG4gICAgICAgIC8vIFdoZW4gaW5zaWRlIGEgdGV4dCBub2RlLCBqdXN0IHJldHVybiB0aGUgdGV4dCBub2RlJ3MgbWFya3NcbiAgICAgICAgaWYgKHRoaXMudGV4dE9mZnNldClcbiAgICAgICAgICAgIHJldHVybiBwYXJlbnQuY2hpbGQoaW5kZXgpLm1hcmtzO1xuICAgICAgICBsZXQgbWFpbiA9IHBhcmVudC5tYXliZUNoaWxkKGluZGV4IC0gMSksIG90aGVyID0gcGFyZW50Lm1heWJlQ2hpbGQoaW5kZXgpO1xuICAgICAgICAvLyBJZiB0aGUgYGFmdGVyYCBmbGFnIGlzIHRydWUgb2YgdGhlcmUgaXMgbm8gbm9kZSBiZWZvcmUsIG1ha2VcbiAgICAgICAgLy8gdGhlIG5vZGUgYWZ0ZXIgdGhpcyBwb3NpdGlvbiB0aGUgbWFpbiByZWZlcmVuY2UuXG4gICAgICAgIGlmICghbWFpbikge1xuICAgICAgICAgICAgbGV0IHRtcCA9IG1haW47XG4gICAgICAgICAgICBtYWluID0gb3RoZXI7XG4gICAgICAgICAgICBvdGhlciA9IHRtcDtcbiAgICAgICAgfVxuICAgICAgICAvLyBVc2UgYWxsIG1hcmtzIGluIHRoZSBtYWluIG5vZGUsIGV4Y2VwdCB0aG9zZSB0aGF0IGhhdmVcbiAgICAgICAgLy8gYGluY2x1c2l2ZWAgc2V0IHRvIGZhbHNlIGFuZCBhcmUgbm90IHByZXNlbnQgaW4gdGhlIG90aGVyIG5vZGUuXG4gICAgICAgIGxldCBtYXJrcyA9IG1haW4ubWFya3M7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWFya3MubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICBpZiAobWFya3NbaV0udHlwZS5zcGVjLmluY2x1c2l2ZSA9PT0gZmFsc2UgJiYgKCFvdGhlciB8fCAhbWFya3NbaV0uaXNJblNldChvdGhlci5tYXJrcykpKVxuICAgICAgICAgICAgICAgIG1hcmtzID0gbWFya3NbaS0tXS5yZW1vdmVGcm9tU2V0KG1hcmtzKTtcbiAgICAgICAgcmV0dXJuIG1hcmtzO1xuICAgIH1cbiAgICAvKipcbiAgICBHZXQgdGhlIG1hcmtzIGFmdGVyIHRoZSBjdXJyZW50IHBvc2l0aW9uLCBpZiBhbnksIGV4Y2VwdCB0aG9zZVxuICAgIHRoYXQgYXJlIG5vbi1pbmNsdXNpdmUgYW5kIG5vdCBwcmVzZW50IGF0IHBvc2l0aW9uIGAkZW5kYC4gVGhpc1xuICAgIGlzIG1vc3RseSB1c2VmdWwgZm9yIGdldHRpbmcgdGhlIHNldCBvZiBtYXJrcyB0byBwcmVzZXJ2ZSBhZnRlciBhXG4gICAgZGVsZXRpb24uIFdpbGwgcmV0dXJuIGBudWxsYCBpZiB0aGlzIHBvc2l0aW9uIGlzIGF0IHRoZSBlbmQgb2ZcbiAgICBpdHMgcGFyZW50IG5vZGUgb3IgaXRzIHBhcmVudCBub2RlIGlzbid0IGEgdGV4dGJsb2NrIChpbiB3aGljaFxuICAgIGNhc2Ugbm8gbWFya3Mgc2hvdWxkIGJlIHByZXNlcnZlZCkuXG4gICAgKi9cbiAgICBtYXJrc0Fjcm9zcygkZW5kKSB7XG4gICAgICAgIGxldCBhZnRlciA9IHRoaXMucGFyZW50Lm1heWJlQ2hpbGQodGhpcy5pbmRleCgpKTtcbiAgICAgICAgaWYgKCFhZnRlciB8fCAhYWZ0ZXIuaXNJbmxpbmUpXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgbGV0IG1hcmtzID0gYWZ0ZXIubWFya3MsIG5leHQgPSAkZW5kLnBhcmVudC5tYXliZUNoaWxkKCRlbmQuaW5kZXgoKSk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWFya3MubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICBpZiAobWFya3NbaV0udHlwZS5zcGVjLmluY2x1c2l2ZSA9PT0gZmFsc2UgJiYgKCFuZXh0IHx8ICFtYXJrc1tpXS5pc0luU2V0KG5leHQubWFya3MpKSlcbiAgICAgICAgICAgICAgICBtYXJrcyA9IG1hcmtzW2ktLV0ucmVtb3ZlRnJvbVNldChtYXJrcyk7XG4gICAgICAgIHJldHVybiBtYXJrcztcbiAgICB9XG4gICAgLyoqXG4gICAgVGhlIGRlcHRoIHVwIHRvIHdoaWNoIHRoaXMgcG9zaXRpb24gYW5kIHRoZSBnaXZlbiAobm9uLXJlc29sdmVkKVxuICAgIHBvc2l0aW9uIHNoYXJlIHRoZSBzYW1lIHBhcmVudCBub2Rlcy5cbiAgICAqL1xuICAgIHNoYXJlZERlcHRoKHBvcykge1xuICAgICAgICBmb3IgKGxldCBkZXB0aCA9IHRoaXMuZGVwdGg7IGRlcHRoID4gMDsgZGVwdGgtLSlcbiAgICAgICAgICAgIGlmICh0aGlzLnN0YXJ0KGRlcHRoKSA8PSBwb3MgJiYgdGhpcy5lbmQoZGVwdGgpID49IHBvcylcbiAgICAgICAgICAgICAgICByZXR1cm4gZGVwdGg7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICAvKipcbiAgICBSZXR1cm5zIGEgcmFuZ2UgYmFzZWQgb24gdGhlIHBsYWNlIHdoZXJlIHRoaXMgcG9zaXRpb24gYW5kIHRoZVxuICAgIGdpdmVuIHBvc2l0aW9uIGRpdmVyZ2UgYXJvdW5kIGJsb2NrIGNvbnRlbnQuIElmIGJvdGggcG9pbnQgaW50b1xuICAgIHRoZSBzYW1lIHRleHRibG9jaywgZm9yIGV4YW1wbGUsIGEgcmFuZ2UgYXJvdW5kIHRoYXQgdGV4dGJsb2NrXG4gICAgd2lsbCBiZSByZXR1cm5lZC4gSWYgdGhleSBwb2ludCBpbnRvIGRpZmZlcmVudCBibG9ja3MsIHRoZSByYW5nZVxuICAgIGFyb3VuZCB0aG9zZSBibG9ja3MgaW4gdGhlaXIgc2hhcmVkIGFuY2VzdG9yIGlzIHJldHVybmVkLiBZb3UgY2FuXG4gICAgcGFzcyBpbiBhbiBvcHRpb25hbCBwcmVkaWNhdGUgdGhhdCB3aWxsIGJlIGNhbGxlZCB3aXRoIGEgcGFyZW50XG4gICAgbm9kZSB0byBzZWUgaWYgYSByYW5nZSBpbnRvIHRoYXQgcGFyZW50IGlzIGFjY2VwdGFibGUuXG4gICAgKi9cbiAgICBibG9ja1JhbmdlKG90aGVyID0gdGhpcywgcHJlZCkge1xuICAgICAgICBpZiAob3RoZXIucG9zIDwgdGhpcy5wb3MpXG4gICAgICAgICAgICByZXR1cm4gb3RoZXIuYmxvY2tSYW5nZSh0aGlzKTtcbiAgICAgICAgZm9yIChsZXQgZCA9IHRoaXMuZGVwdGggLSAodGhpcy5wYXJlbnQuaW5saW5lQ29udGVudCB8fCB0aGlzLnBvcyA9PSBvdGhlci5wb3MgPyAxIDogMCk7IGQgPj0gMDsgZC0tKVxuICAgICAgICAgICAgaWYgKG90aGVyLnBvcyA8PSB0aGlzLmVuZChkKSAmJiAoIXByZWQgfHwgcHJlZCh0aGlzLm5vZGUoZCkpKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IE5vZGVSYW5nZSh0aGlzLCBvdGhlciwgZCk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICAvKipcbiAgICBRdWVyeSB3aGV0aGVyIHRoZSBnaXZlbiBwb3NpdGlvbiBzaGFyZXMgdGhlIHNhbWUgcGFyZW50IG5vZGUuXG4gICAgKi9cbiAgICBzYW1lUGFyZW50KG90aGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBvcyAtIHRoaXMucGFyZW50T2Zmc2V0ID09IG90aGVyLnBvcyAtIG90aGVyLnBhcmVudE9mZnNldDtcbiAgICB9XG4gICAgLyoqXG4gICAgUmV0dXJuIHRoZSBncmVhdGVyIG9mIHRoaXMgYW5kIHRoZSBnaXZlbiBwb3NpdGlvbi5cbiAgICAqL1xuICAgIG1heChvdGhlcikge1xuICAgICAgICByZXR1cm4gb3RoZXIucG9zID4gdGhpcy5wb3MgPyBvdGhlciA6IHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIFJldHVybiB0aGUgc21hbGxlciBvZiB0aGlzIGFuZCB0aGUgZ2l2ZW4gcG9zaXRpb24uXG4gICAgKi9cbiAgICBtaW4ob3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIG90aGVyLnBvcyA8IHRoaXMucG9zID8gb3RoZXIgOiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICBsZXQgc3RyID0gXCJcIjtcbiAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPD0gdGhpcy5kZXB0aDsgaSsrKVxuICAgICAgICAgICAgc3RyICs9IChzdHIgPyBcIi9cIiA6IFwiXCIpICsgdGhpcy5ub2RlKGkpLnR5cGUubmFtZSArIFwiX1wiICsgdGhpcy5pbmRleChpIC0gMSk7XG4gICAgICAgIHJldHVybiBzdHIgKyBcIjpcIiArIHRoaXMucGFyZW50T2Zmc2V0O1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHN0YXRpYyByZXNvbHZlKGRvYywgcG9zKSB7XG4gICAgICAgIGlmICghKHBvcyA+PSAwICYmIHBvcyA8PSBkb2MuY29udGVudC5zaXplKSlcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiUG9zaXRpb24gXCIgKyBwb3MgKyBcIiBvdXQgb2YgcmFuZ2VcIik7XG4gICAgICAgIGxldCBwYXRoID0gW107XG4gICAgICAgIGxldCBzdGFydCA9IDAsIHBhcmVudE9mZnNldCA9IHBvcztcbiAgICAgICAgZm9yIChsZXQgbm9kZSA9IGRvYzs7KSB7XG4gICAgICAgICAgICBsZXQgeyBpbmRleCwgb2Zmc2V0IH0gPSBub2RlLmNvbnRlbnQuZmluZEluZGV4KHBhcmVudE9mZnNldCk7XG4gICAgICAgICAgICBsZXQgcmVtID0gcGFyZW50T2Zmc2V0IC0gb2Zmc2V0O1xuICAgICAgICAgICAgcGF0aC5wdXNoKG5vZGUsIGluZGV4LCBzdGFydCArIG9mZnNldCk7XG4gICAgICAgICAgICBpZiAoIXJlbSlcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIG5vZGUgPSBub2RlLmNoaWxkKGluZGV4KTtcbiAgICAgICAgICAgIGlmIChub2RlLmlzVGV4dClcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIHBhcmVudE9mZnNldCA9IHJlbSAtIDE7XG4gICAgICAgICAgICBzdGFydCArPSBvZmZzZXQgKyAxO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgUmVzb2x2ZWRQb3MocG9zLCBwYXRoLCBwYXJlbnRPZmZzZXQpO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHN0YXRpYyByZXNvbHZlQ2FjaGVkKGRvYywgcG9zKSB7XG4gICAgICAgIGxldCBjYWNoZSA9IHJlc29sdmVDYWNoZS5nZXQoZG9jKTtcbiAgICAgICAgaWYgKGNhY2hlKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNhY2hlLmVsdHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBsZXQgZWx0ID0gY2FjaGUuZWx0c1tpXTtcbiAgICAgICAgICAgICAgICBpZiAoZWx0LnBvcyA9PSBwb3MpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBlbHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXNvbHZlQ2FjaGUuc2V0KGRvYywgY2FjaGUgPSBuZXcgUmVzb2x2ZUNhY2hlKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcmVzdWx0ID0gY2FjaGUuZWx0c1tjYWNoZS5pXSA9IFJlc29sdmVkUG9zLnJlc29sdmUoZG9jLCBwb3MpO1xuICAgICAgICBjYWNoZS5pID0gKGNhY2hlLmkgKyAxKSAlIHJlc29sdmVDYWNoZVNpemU7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxufVxuY2xhc3MgUmVzb2x2ZUNhY2hlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5lbHRzID0gW107XG4gICAgICAgIHRoaXMuaSA9IDA7XG4gICAgfVxufVxuY29uc3QgcmVzb2x2ZUNhY2hlU2l6ZSA9IDEyLCByZXNvbHZlQ2FjaGUgPSBuZXcgV2Vha01hcCgpO1xuLyoqXG5SZXByZXNlbnRzIGEgZmxhdCByYW5nZSBvZiBjb250ZW50LCBpLmUuIG9uZSB0aGF0IHN0YXJ0cyBhbmRcbmVuZHMgaW4gdGhlIHNhbWUgbm9kZS5cbiovXG5jbGFzcyBOb2RlUmFuZ2Uge1xuICAgIC8qKlxuICAgIENvbnN0cnVjdCBhIG5vZGUgcmFuZ2UuIGAkZnJvbWAgYW5kIGAkdG9gIHNob3VsZCBwb2ludCBpbnRvIHRoZVxuICAgIHNhbWUgbm9kZSB1bnRpbCBhdCBsZWFzdCB0aGUgZ2l2ZW4gYGRlcHRoYCwgc2luY2UgYSBub2RlIHJhbmdlXG4gICAgZGVub3RlcyBhbiBhZGphY2VudCBzZXQgb2Ygbm9kZXMgaW4gYSBzaW5nbGUgcGFyZW50IG5vZGUuXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBBIHJlc29sdmVkIHBvc2l0aW9uIGFsb25nIHRoZSBzdGFydCBvZiB0aGUgY29udGVudC4gTWF5IGhhdmUgYVxuICAgIGBkZXB0aGAgZ3JlYXRlciB0aGFuIHRoaXMgb2JqZWN0J3MgYGRlcHRoYCBwcm9wZXJ0eSwgc2luY2VcbiAgICB0aGVzZSBhcmUgdGhlIHBvc2l0aW9ucyB0aGF0IHdlcmUgdXNlZCB0byBjb21wdXRlIHRoZSByYW5nZSxcbiAgICBub3QgcmUtcmVzb2x2ZWQgcG9zaXRpb25zIGRpcmVjdGx5IGF0IGl0cyBib3VuZGFyaWVzLlxuICAgICovXG4gICAgJGZyb20sIFxuICAgIC8qKlxuICAgIEEgcG9zaXRpb24gYWxvbmcgdGhlIGVuZCBvZiB0aGUgY29udGVudC4gU2VlXG4gICAgY2F2ZWF0IGZvciBbYCRmcm9tYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGVSYW5nZS4kZnJvbSkuXG4gICAgKi9cbiAgICAkdG8sIFxuICAgIC8qKlxuICAgIFRoZSBkZXB0aCBvZiB0aGUgbm9kZSB0aGF0IHRoaXMgcmFuZ2UgcG9pbnRzIGludG8uXG4gICAgKi9cbiAgICBkZXB0aCkge1xuICAgICAgICB0aGlzLiRmcm9tID0gJGZyb207XG4gICAgICAgIHRoaXMuJHRvID0gJHRvO1xuICAgICAgICB0aGlzLmRlcHRoID0gZGVwdGg7XG4gICAgfVxuICAgIC8qKlxuICAgIFRoZSBwb3NpdGlvbiBhdCB0aGUgc3RhcnQgb2YgdGhlIHJhbmdlLlxuICAgICovXG4gICAgZ2V0IHN0YXJ0KCkgeyByZXR1cm4gdGhpcy4kZnJvbS5iZWZvcmUodGhpcy5kZXB0aCArIDEpOyB9XG4gICAgLyoqXG4gICAgVGhlIHBvc2l0aW9uIGF0IHRoZSBlbmQgb2YgdGhlIHJhbmdlLlxuICAgICovXG4gICAgZ2V0IGVuZCgpIHsgcmV0dXJuIHRoaXMuJHRvLmFmdGVyKHRoaXMuZGVwdGggKyAxKTsgfVxuICAgIC8qKlxuICAgIFRoZSBwYXJlbnQgbm9kZSB0aGF0IHRoZSByYW5nZSBwb2ludHMgaW50by5cbiAgICAqL1xuICAgIGdldCBwYXJlbnQoKSB7IHJldHVybiB0aGlzLiRmcm9tLm5vZGUodGhpcy5kZXB0aCk7IH1cbiAgICAvKipcbiAgICBUaGUgc3RhcnQgaW5kZXggb2YgdGhlIHJhbmdlIGluIHRoZSBwYXJlbnQgbm9kZS5cbiAgICAqL1xuICAgIGdldCBzdGFydEluZGV4KCkgeyByZXR1cm4gdGhpcy4kZnJvbS5pbmRleCh0aGlzLmRlcHRoKTsgfVxuICAgIC8qKlxuICAgIFRoZSBlbmQgaW5kZXggb2YgdGhlIHJhbmdlIGluIHRoZSBwYXJlbnQgbm9kZS5cbiAgICAqL1xuICAgIGdldCBlbmRJbmRleCgpIHsgcmV0dXJuIHRoaXMuJHRvLmluZGV4QWZ0ZXIodGhpcy5kZXB0aCk7IH1cbn1cblxuY29uc3QgZW1wdHlBdHRycyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4vKipcblRoaXMgY2xhc3MgcmVwcmVzZW50cyBhIG5vZGUgaW4gdGhlIHRyZWUgdGhhdCBtYWtlcyB1cCBhXG5Qcm9zZU1pcnJvciBkb2N1bWVudC4gU28gYSBkb2N1bWVudCBpcyBhbiBpbnN0YW5jZSBvZiBgTm9kZWAsIHdpdGhcbmNoaWxkcmVuIHRoYXQgYXJlIGFsc28gaW5zdGFuY2VzIG9mIGBOb2RlYC5cblxuTm9kZXMgYXJlIHBlcnNpc3RlbnQgZGF0YSBzdHJ1Y3R1cmVzLiBJbnN0ZWFkIG9mIGNoYW5naW5nIHRoZW0sIHlvdVxuY3JlYXRlIG5ldyBvbmVzIHdpdGggdGhlIGNvbnRlbnQgeW91IHdhbnQuIE9sZCBvbmVzIGtlZXAgcG9pbnRpbmdcbmF0IHRoZSBvbGQgZG9jdW1lbnQgc2hhcGUuIFRoaXMgaXMgbWFkZSBjaGVhcGVyIGJ5IHNoYXJpbmdcbnN0cnVjdHVyZSBiZXR3ZWVuIHRoZSBvbGQgYW5kIG5ldyBkYXRhIGFzIG11Y2ggYXMgcG9zc2libGUsIHdoaWNoIGFcbnRyZWUgc2hhcGUgbGlrZSB0aGlzICh3aXRob3V0IGJhY2sgcG9pbnRlcnMpIG1ha2VzIGVhc3kuXG5cbioqRG8gbm90KiogZGlyZWN0bHkgbXV0YXRlIHRoZSBwcm9wZXJ0aWVzIG9mIGEgYE5vZGVgIG9iamVjdC4gU2VlXG5bdGhlIGd1aWRlXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL2d1aWRlLyNkb2MpIGZvciBtb3JlIGluZm9ybWF0aW9uLlxuKi9cbmNsYXNzIE5vZGUge1xuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgVGhlIHR5cGUgb2Ygbm9kZSB0aGF0IHRoaXMgaXMuXG4gICAgKi9cbiAgICB0eXBlLCBcbiAgICAvKipcbiAgICBBbiBvYmplY3QgbWFwcGluZyBhdHRyaWJ1dGUgbmFtZXMgdG8gdmFsdWVzLiBUaGUga2luZCBvZlxuICAgIGF0dHJpYnV0ZXMgYWxsb3dlZCBhbmQgcmVxdWlyZWQgYXJlXG4gICAgW2RldGVybWluZWRdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5Ob2RlU3BlYy5hdHRycykgYnkgdGhlIG5vZGUgdHlwZS5cbiAgICAqL1xuICAgIGF0dHJzLCBcbiAgICAvLyBBIGZyYWdtZW50IGhvbGRpbmcgdGhlIG5vZGUncyBjaGlsZHJlbi5cbiAgICBjb250ZW50LCBcbiAgICAvKipcbiAgICBUaGUgbWFya3MgKHRoaW5ncyBsaWtlIHdoZXRoZXIgaXQgaXMgZW1waGFzaXplZCBvciBwYXJ0IG9mIGFcbiAgICBsaW5rKSBhcHBsaWVkIHRvIHRoaXMgbm9kZS5cbiAgICAqL1xuICAgIG1hcmtzID0gTWFyay5ub25lKSB7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuYXR0cnMgPSBhdHRycztcbiAgICAgICAgdGhpcy5tYXJrcyA9IG1hcmtzO1xuICAgICAgICB0aGlzLmNvbnRlbnQgPSBjb250ZW50IHx8IEZyYWdtZW50LmVtcHR5O1xuICAgIH1cbiAgICAvKipcbiAgICBUaGUgYXJyYXkgb2YgdGhpcyBub2RlJ3MgY2hpbGQgbm9kZXMuXG4gICAgKi9cbiAgICBnZXQgY2hpbGRyZW4oKSB7IHJldHVybiB0aGlzLmNvbnRlbnQuY29udGVudDsgfVxuICAgIC8qKlxuICAgIFRoZSBzaXplIG9mIHRoaXMgbm9kZSwgYXMgZGVmaW5lZCBieSB0aGUgaW50ZWdlci1iYXNlZCBbaW5kZXhpbmdcbiAgICBzY2hlbWVdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvZ3VpZGUvI2RvYy5pbmRleGluZykuIEZvciB0ZXh0IG5vZGVzLCB0aGlzIGlzIHRoZVxuICAgIGFtb3VudCBvZiBjaGFyYWN0ZXJzLiBGb3Igb3RoZXIgbGVhZiBub2RlcywgaXQgaXMgb25lLiBGb3JcbiAgICBub24tbGVhZiBub2RlcywgaXQgaXMgdGhlIHNpemUgb2YgdGhlIGNvbnRlbnQgcGx1cyB0d28gKHRoZVxuICAgIHN0YXJ0IGFuZCBlbmQgdG9rZW4pLlxuICAgICovXG4gICAgZ2V0IG5vZGVTaXplKCkgeyByZXR1cm4gdGhpcy5pc0xlYWYgPyAxIDogMiArIHRoaXMuY29udGVudC5zaXplOyB9XG4gICAgLyoqXG4gICAgVGhlIG51bWJlciBvZiBjaGlsZHJlbiB0aGF0IHRoZSBub2RlIGhhcy5cbiAgICAqL1xuICAgIGdldCBjaGlsZENvdW50KCkgeyByZXR1cm4gdGhpcy5jb250ZW50LmNoaWxkQ291bnQ7IH1cbiAgICAvKipcbiAgICBHZXQgdGhlIGNoaWxkIG5vZGUgYXQgdGhlIGdpdmVuIGluZGV4LiBSYWlzZXMgYW4gZXJyb3Igd2hlbiB0aGVcbiAgICBpbmRleCBpcyBvdXQgb2YgcmFuZ2UuXG4gICAgKi9cbiAgICBjaGlsZChpbmRleCkgeyByZXR1cm4gdGhpcy5jb250ZW50LmNoaWxkKGluZGV4KTsgfVxuICAgIC8qKlxuICAgIEdldCB0aGUgY2hpbGQgbm9kZSBhdCB0aGUgZ2l2ZW4gaW5kZXgsIGlmIGl0IGV4aXN0cy5cbiAgICAqL1xuICAgIG1heWJlQ2hpbGQoaW5kZXgpIHsgcmV0dXJuIHRoaXMuY29udGVudC5tYXliZUNoaWxkKGluZGV4KTsgfVxuICAgIC8qKlxuICAgIENhbGwgYGZgIGZvciBldmVyeSBjaGlsZCBub2RlLCBwYXNzaW5nIHRoZSBub2RlLCBpdHMgb2Zmc2V0XG4gICAgaW50byB0aGlzIHBhcmVudCBub2RlLCBhbmQgaXRzIGluZGV4LlxuICAgICovXG4gICAgZm9yRWFjaChmKSB7IHRoaXMuY29udGVudC5mb3JFYWNoKGYpOyB9XG4gICAgLyoqXG4gICAgSW52b2tlIGEgY2FsbGJhY2sgZm9yIGFsbCBkZXNjZW5kYW50IG5vZGVzIHJlY3Vyc2l2ZWx5IGJldHdlZW5cbiAgICB0aGUgZ2l2ZW4gdHdvIHBvc2l0aW9ucyB0aGF0IGFyZSByZWxhdGl2ZSB0byBzdGFydCBvZiB0aGlzXG4gICAgbm9kZSdzIGNvbnRlbnQuIFRoZSBjYWxsYmFjayBpcyBpbnZva2VkIHdpdGggdGhlIG5vZGUsIGl0c1xuICAgIHBvc2l0aW9uIHJlbGF0aXZlIHRvIHRoZSBvcmlnaW5hbCBub2RlIChtZXRob2QgcmVjZWl2ZXIpLFxuICAgIGl0cyBwYXJlbnQgbm9kZSwgYW5kIGl0cyBjaGlsZCBpbmRleC4gV2hlbiB0aGUgY2FsbGJhY2sgcmV0dXJuc1xuICAgIGZhbHNlIGZvciBhIGdpdmVuIG5vZGUsIHRoYXQgbm9kZSdzIGNoaWxkcmVuIHdpbGwgbm90IGJlXG4gICAgcmVjdXJzZWQgb3Zlci4gVGhlIGxhc3QgcGFyYW1ldGVyIGNhbiBiZSB1c2VkIHRvIHNwZWNpZnkgYVxuICAgIHN0YXJ0aW5nIHBvc2l0aW9uIHRvIGNvdW50IGZyb20uXG4gICAgKi9cbiAgICBub2Rlc0JldHdlZW4oZnJvbSwgdG8sIGYsIHN0YXJ0UG9zID0gMCkge1xuICAgICAgICB0aGlzLmNvbnRlbnQubm9kZXNCZXR3ZWVuKGZyb20sIHRvLCBmLCBzdGFydFBvcywgdGhpcyk7XG4gICAgfVxuICAgIC8qKlxuICAgIENhbGwgdGhlIGdpdmVuIGNhbGxiYWNrIGZvciBldmVyeSBkZXNjZW5kYW50IG5vZGUuIERvZXNuJ3RcbiAgICBkZXNjZW5kIGludG8gYSBub2RlIHdoZW4gdGhlIGNhbGxiYWNrIHJldHVybnMgYGZhbHNlYC5cbiAgICAqL1xuICAgIGRlc2NlbmRhbnRzKGYpIHtcbiAgICAgICAgdGhpcy5ub2Rlc0JldHdlZW4oMCwgdGhpcy5jb250ZW50LnNpemUsIGYpO1xuICAgIH1cbiAgICAvKipcbiAgICBDb25jYXRlbmF0ZXMgYWxsIHRoZSB0ZXh0IG5vZGVzIGZvdW5kIGluIHRoaXMgZnJhZ21lbnQgYW5kIGl0c1xuICAgIGNoaWxkcmVuLlxuICAgICovXG4gICAgZ2V0IHRleHRDb250ZW50KCkge1xuICAgICAgICByZXR1cm4gKHRoaXMuaXNMZWFmICYmIHRoaXMudHlwZS5zcGVjLmxlYWZUZXh0KVxuICAgICAgICAgICAgPyB0aGlzLnR5cGUuc3BlYy5sZWFmVGV4dCh0aGlzKVxuICAgICAgICAgICAgOiB0aGlzLnRleHRCZXR3ZWVuKDAsIHRoaXMuY29udGVudC5zaXplLCBcIlwiKTtcbiAgICB9XG4gICAgLyoqXG4gICAgR2V0IGFsbCB0ZXh0IGJldHdlZW4gcG9zaXRpb25zIGBmcm9tYCBhbmQgYHRvYC4gV2hlblxuICAgIGBibG9ja1NlcGFyYXRvcmAgaXMgZ2l2ZW4sIGl0IHdpbGwgYmUgaW5zZXJ0ZWQgdG8gc2VwYXJhdGUgdGV4dFxuICAgIGZyb20gZGlmZmVyZW50IGJsb2NrIG5vZGVzLiBJZiBgbGVhZlRleHRgIGlzIGdpdmVuLCBpdCdsbCBiZVxuICAgIGluc2VydGVkIGZvciBldmVyeSBub24tdGV4dCBsZWFmIG5vZGUgZW5jb3VudGVyZWQsIG90aGVyd2lzZVxuICAgIFtgbGVhZlRleHRgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZVNwZWNebGVhZlRleHQpIHdpbGwgYmUgdXNlZC5cbiAgICAqL1xuICAgIHRleHRCZXR3ZWVuKGZyb20sIHRvLCBibG9ja1NlcGFyYXRvciwgbGVhZlRleHQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGVudC50ZXh0QmV0d2Vlbihmcm9tLCB0bywgYmxvY2tTZXBhcmF0b3IsIGxlYWZUZXh0KTtcbiAgICB9XG4gICAgLyoqXG4gICAgUmV0dXJucyB0aGlzIG5vZGUncyBmaXJzdCBjaGlsZCwgb3IgYG51bGxgIGlmIHRoZXJlIGFyZSBub1xuICAgIGNoaWxkcmVuLlxuICAgICovXG4gICAgZ2V0IGZpcnN0Q2hpbGQoKSB7IHJldHVybiB0aGlzLmNvbnRlbnQuZmlyc3RDaGlsZDsgfVxuICAgIC8qKlxuICAgIFJldHVybnMgdGhpcyBub2RlJ3MgbGFzdCBjaGlsZCwgb3IgYG51bGxgIGlmIHRoZXJlIGFyZSBub1xuICAgIGNoaWxkcmVuLlxuICAgICovXG4gICAgZ2V0IGxhc3RDaGlsZCgpIHsgcmV0dXJuIHRoaXMuY29udGVudC5sYXN0Q2hpbGQ7IH1cbiAgICAvKipcbiAgICBUZXN0IHdoZXRoZXIgdHdvIG5vZGVzIHJlcHJlc2VudCB0aGUgc2FtZSBwaWVjZSBvZiBkb2N1bWVudC5cbiAgICAqL1xuICAgIGVxKG90aGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzID09IG90aGVyIHx8ICh0aGlzLnNhbWVNYXJrdXAob3RoZXIpICYmIHRoaXMuY29udGVudC5lcShvdGhlci5jb250ZW50KSk7XG4gICAgfVxuICAgIC8qKlxuICAgIENvbXBhcmUgdGhlIG1hcmt1cCAodHlwZSwgYXR0cmlidXRlcywgYW5kIG1hcmtzKSBvZiB0aGlzIG5vZGUgdG9cbiAgICB0aG9zZSBvZiBhbm90aGVyLiBSZXR1cm5zIGB0cnVlYCBpZiBib3RoIGhhdmUgdGhlIHNhbWUgbWFya3VwLlxuICAgICovXG4gICAgc2FtZU1hcmt1cChvdGhlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5oYXNNYXJrdXAob3RoZXIudHlwZSwgb3RoZXIuYXR0cnMsIG90aGVyLm1hcmtzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ2hlY2sgd2hldGhlciB0aGlzIG5vZGUncyBtYXJrdXAgY29ycmVzcG9uZCB0byB0aGUgZ2l2ZW4gdHlwZSxcbiAgICBhdHRyaWJ1dGVzLCBhbmQgbWFya3MuXG4gICAgKi9cbiAgICBoYXNNYXJrdXAodHlwZSwgYXR0cnMsIG1hcmtzKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT0gdHlwZSAmJlxuICAgICAgICAgICAgY29tcGFyZURlZXAodGhpcy5hdHRycywgYXR0cnMgfHwgdHlwZS5kZWZhdWx0QXR0cnMgfHwgZW1wdHlBdHRycykgJiZcbiAgICAgICAgICAgIE1hcmsuc2FtZVNldCh0aGlzLm1hcmtzLCBtYXJrcyB8fCBNYXJrLm5vbmUpO1xuICAgIH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSBuZXcgbm9kZSB3aXRoIHRoZSBzYW1lIG1hcmt1cCBhcyB0aGlzIG5vZGUsIGNvbnRhaW5pbmdcbiAgICB0aGUgZ2l2ZW4gY29udGVudCAob3IgZW1wdHksIGlmIG5vIGNvbnRlbnQgaXMgZ2l2ZW4pLlxuICAgICovXG4gICAgY29weShjb250ZW50ID0gbnVsbCkge1xuICAgICAgICBpZiAoY29udGVudCA9PSB0aGlzLmNvbnRlbnQpXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgcmV0dXJuIG5ldyBOb2RlKHRoaXMudHlwZSwgdGhpcy5hdHRycywgY29udGVudCwgdGhpcy5tYXJrcyk7XG4gICAgfVxuICAgIC8qKlxuICAgIENyZWF0ZSBhIGNvcHkgb2YgdGhpcyBub2RlLCB3aXRoIHRoZSBnaXZlbiBzZXQgb2YgbWFya3MgaW5zdGVhZFxuICAgIG9mIHRoZSBub2RlJ3Mgb3duIG1hcmtzLlxuICAgICovXG4gICAgbWFyayhtYXJrcykge1xuICAgICAgICByZXR1cm4gbWFya3MgPT0gdGhpcy5tYXJrcyA/IHRoaXMgOiBuZXcgTm9kZSh0aGlzLnR5cGUsIHRoaXMuYXR0cnMsIHRoaXMuY29udGVudCwgbWFya3MpO1xuICAgIH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSBjb3B5IG9mIHRoaXMgbm9kZSB3aXRoIG9ubHkgdGhlIGNvbnRlbnQgYmV0d2VlbiB0aGVcbiAgICBnaXZlbiBwb3NpdGlvbnMuIElmIGB0b2AgaXMgbm90IGdpdmVuLCBpdCBkZWZhdWx0cyB0byB0aGUgZW5kIG9mXG4gICAgdGhlIG5vZGUuXG4gICAgKi9cbiAgICBjdXQoZnJvbSwgdG8gPSB0aGlzLmNvbnRlbnQuc2l6ZSkge1xuICAgICAgICBpZiAoZnJvbSA9PSAwICYmIHRvID09IHRoaXMuY29udGVudC5zaXplKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIHJldHVybiB0aGlzLmNvcHkodGhpcy5jb250ZW50LmN1dChmcm9tLCB0bykpO1xuICAgIH1cbiAgICAvKipcbiAgICBDdXQgb3V0IHRoZSBwYXJ0IG9mIHRoZSBkb2N1bWVudCBiZXR3ZWVuIHRoZSBnaXZlbiBwb3NpdGlvbnMsIGFuZFxuICAgIHJldHVybiBpdCBhcyBhIGBTbGljZWAgb2JqZWN0LlxuICAgICovXG4gICAgc2xpY2UoZnJvbSwgdG8gPSB0aGlzLmNvbnRlbnQuc2l6ZSwgaW5jbHVkZVBhcmVudHMgPSBmYWxzZSkge1xuICAgICAgICBpZiAoZnJvbSA9PSB0bylcbiAgICAgICAgICAgIHJldHVybiBTbGljZS5lbXB0eTtcbiAgICAgICAgbGV0ICRmcm9tID0gdGhpcy5yZXNvbHZlKGZyb20pLCAkdG8gPSB0aGlzLnJlc29sdmUodG8pO1xuICAgICAgICBsZXQgZGVwdGggPSBpbmNsdWRlUGFyZW50cyA/IDAgOiAkZnJvbS5zaGFyZWREZXB0aCh0byk7XG4gICAgICAgIGxldCBzdGFydCA9ICRmcm9tLnN0YXJ0KGRlcHRoKSwgbm9kZSA9ICRmcm9tLm5vZGUoZGVwdGgpO1xuICAgICAgICBsZXQgY29udGVudCA9IG5vZGUuY29udGVudC5jdXQoJGZyb20ucG9zIC0gc3RhcnQsICR0by5wb3MgLSBzdGFydCk7XG4gICAgICAgIHJldHVybiBuZXcgU2xpY2UoY29udGVudCwgJGZyb20uZGVwdGggLSBkZXB0aCwgJHRvLmRlcHRoIC0gZGVwdGgpO1xuICAgIH1cbiAgICAvKipcbiAgICBSZXBsYWNlIHRoZSBwYXJ0IG9mIHRoZSBkb2N1bWVudCBiZXR3ZWVuIHRoZSBnaXZlbiBwb3NpdGlvbnMgd2l0aFxuICAgIHRoZSBnaXZlbiBzbGljZS4gVGhlIHNsaWNlIG11c3QgJ2ZpdCcsIG1lYW5pbmcgaXRzIG9wZW4gc2lkZXNcbiAgICBtdXN0IGJlIGFibGUgdG8gY29ubmVjdCB0byB0aGUgc3Vycm91bmRpbmcgY29udGVudCwgYW5kIGl0c1xuICAgIGNvbnRlbnQgbm9kZXMgbXVzdCBiZSB2YWxpZCBjaGlsZHJlbiBmb3IgdGhlIG5vZGUgdGhleSBhcmUgcGxhY2VkXG4gICAgaW50by4gSWYgYW55IG9mIHRoaXMgaXMgdmlvbGF0ZWQsIGFuIGVycm9yIG9mIHR5cGVcbiAgICBbYFJlcGxhY2VFcnJvcmBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5SZXBsYWNlRXJyb3IpIGlzIHRocm93bi5cbiAgICAqL1xuICAgIHJlcGxhY2UoZnJvbSwgdG8sIHNsaWNlKSB7XG4gICAgICAgIHJldHVybiByZXBsYWNlKHRoaXMucmVzb2x2ZShmcm9tKSwgdGhpcy5yZXNvbHZlKHRvKSwgc2xpY2UpO1xuICAgIH1cbiAgICAvKipcbiAgICBGaW5kIHRoZSBub2RlIGRpcmVjdGx5IGFmdGVyIHRoZSBnaXZlbiBwb3NpdGlvbi5cbiAgICAqL1xuICAgIG5vZGVBdChwb3MpIHtcbiAgICAgICAgZm9yIChsZXQgbm9kZSA9IHRoaXM7Oykge1xuICAgICAgICAgICAgbGV0IHsgaW5kZXgsIG9mZnNldCB9ID0gbm9kZS5jb250ZW50LmZpbmRJbmRleChwb3MpO1xuICAgICAgICAgICAgbm9kZSA9IG5vZGUubWF5YmVDaGlsZChpbmRleCk7XG4gICAgICAgICAgICBpZiAoIW5vZGUpXG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICBpZiAob2Zmc2V0ID09IHBvcyB8fCBub2RlLmlzVGV4dClcbiAgICAgICAgICAgICAgICByZXR1cm4gbm9kZTtcbiAgICAgICAgICAgIHBvcyAtPSBvZmZzZXQgKyAxO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgIEZpbmQgdGhlIChkaXJlY3QpIGNoaWxkIG5vZGUgYWZ0ZXIgdGhlIGdpdmVuIG9mZnNldCwgaWYgYW55LFxuICAgIGFuZCByZXR1cm4gaXQgYWxvbmcgd2l0aCBpdHMgaW5kZXggYW5kIG9mZnNldCByZWxhdGl2ZSB0byB0aGlzXG4gICAgbm9kZS5cbiAgICAqL1xuICAgIGNoaWxkQWZ0ZXIocG9zKSB7XG4gICAgICAgIGxldCB7IGluZGV4LCBvZmZzZXQgfSA9IHRoaXMuY29udGVudC5maW5kSW5kZXgocG9zKTtcbiAgICAgICAgcmV0dXJuIHsgbm9kZTogdGhpcy5jb250ZW50Lm1heWJlQ2hpbGQoaW5kZXgpLCBpbmRleCwgb2Zmc2V0IH07XG4gICAgfVxuICAgIC8qKlxuICAgIEZpbmQgdGhlIChkaXJlY3QpIGNoaWxkIG5vZGUgYmVmb3JlIHRoZSBnaXZlbiBvZmZzZXQsIGlmIGFueSxcbiAgICBhbmQgcmV0dXJuIGl0IGFsb25nIHdpdGggaXRzIGluZGV4IGFuZCBvZmZzZXQgcmVsYXRpdmUgdG8gdGhpc1xuICAgIG5vZGUuXG4gICAgKi9cbiAgICBjaGlsZEJlZm9yZShwb3MpIHtcbiAgICAgICAgaWYgKHBvcyA9PSAwKVxuICAgICAgICAgICAgcmV0dXJuIHsgbm9kZTogbnVsbCwgaW5kZXg6IDAsIG9mZnNldDogMCB9O1xuICAgICAgICBsZXQgeyBpbmRleCwgb2Zmc2V0IH0gPSB0aGlzLmNvbnRlbnQuZmluZEluZGV4KHBvcyk7XG4gICAgICAgIGlmIChvZmZzZXQgPCBwb3MpXG4gICAgICAgICAgICByZXR1cm4geyBub2RlOiB0aGlzLmNvbnRlbnQuY2hpbGQoaW5kZXgpLCBpbmRleCwgb2Zmc2V0IH07XG4gICAgICAgIGxldCBub2RlID0gdGhpcy5jb250ZW50LmNoaWxkKGluZGV4IC0gMSk7XG4gICAgICAgIHJldHVybiB7IG5vZGUsIGluZGV4OiBpbmRleCAtIDEsIG9mZnNldDogb2Zmc2V0IC0gbm9kZS5ub2RlU2l6ZSB9O1xuICAgIH1cbiAgICAvKipcbiAgICBSZXNvbHZlIHRoZSBnaXZlbiBwb3NpdGlvbiBpbiB0aGUgZG9jdW1lbnQsIHJldHVybmluZyBhblxuICAgIFtvYmplY3RdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5SZXNvbHZlZFBvcykgd2l0aCBpbmZvcm1hdGlvbiBhYm91dCBpdHMgY29udGV4dC5cbiAgICAqL1xuICAgIHJlc29sdmUocG9zKSB7IHJldHVybiBSZXNvbHZlZFBvcy5yZXNvbHZlQ2FjaGVkKHRoaXMsIHBvcyk7IH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHJlc29sdmVOb0NhY2hlKHBvcykgeyByZXR1cm4gUmVzb2x2ZWRQb3MucmVzb2x2ZSh0aGlzLCBwb3MpOyB9XG4gICAgLyoqXG4gICAgVGVzdCB3aGV0aGVyIGEgZ2l2ZW4gbWFyayBvciBtYXJrIHR5cGUgb2NjdXJzIGluIHRoaXMgZG9jdW1lbnRcbiAgICBiZXR3ZWVuIHRoZSB0d28gZ2l2ZW4gcG9zaXRpb25zLlxuICAgICovXG4gICAgcmFuZ2VIYXNNYXJrKGZyb20sIHRvLCB0eXBlKSB7XG4gICAgICAgIGxldCBmb3VuZCA9IGZhbHNlO1xuICAgICAgICBpZiAodG8gPiBmcm9tKVxuICAgICAgICAgICAgdGhpcy5ub2Rlc0JldHdlZW4oZnJvbSwgdG8sIG5vZGUgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlLmlzSW5TZXQobm9kZS5tYXJrcykpXG4gICAgICAgICAgICAgICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICByZXR1cm4gIWZvdW5kO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBmb3VuZDtcbiAgICB9XG4gICAgLyoqXG4gICAgVHJ1ZSB3aGVuIHRoaXMgaXMgYSBibG9jayAobm9uLWlubGluZSBub2RlKVxuICAgICovXG4gICAgZ2V0IGlzQmxvY2soKSB7IHJldHVybiB0aGlzLnR5cGUuaXNCbG9jazsgfVxuICAgIC8qKlxuICAgIFRydWUgd2hlbiB0aGlzIGlzIGEgdGV4dGJsb2NrIG5vZGUsIGEgYmxvY2sgbm9kZSB3aXRoIGlubGluZVxuICAgIGNvbnRlbnQuXG4gICAgKi9cbiAgICBnZXQgaXNUZXh0YmxvY2soKSB7IHJldHVybiB0aGlzLnR5cGUuaXNUZXh0YmxvY2s7IH1cbiAgICAvKipcbiAgICBUcnVlIHdoZW4gdGhpcyBub2RlIGFsbG93cyBpbmxpbmUgY29udGVudC5cbiAgICAqL1xuICAgIGdldCBpbmxpbmVDb250ZW50KCkgeyByZXR1cm4gdGhpcy50eXBlLmlubGluZUNvbnRlbnQ7IH1cbiAgICAvKipcbiAgICBUcnVlIHdoZW4gdGhpcyBpcyBhbiBpbmxpbmUgbm9kZSAoYSB0ZXh0IG5vZGUgb3IgYSBub2RlIHRoYXQgY2FuXG4gICAgYXBwZWFyIGFtb25nIHRleHQpLlxuICAgICovXG4gICAgZ2V0IGlzSW5saW5lKCkgeyByZXR1cm4gdGhpcy50eXBlLmlzSW5saW5lOyB9XG4gICAgLyoqXG4gICAgVHJ1ZSB3aGVuIHRoaXMgaXMgYSB0ZXh0IG5vZGUuXG4gICAgKi9cbiAgICBnZXQgaXNUZXh0KCkgeyByZXR1cm4gdGhpcy50eXBlLmlzVGV4dDsgfVxuICAgIC8qKlxuICAgIFRydWUgd2hlbiB0aGlzIGlzIGEgbGVhZiBub2RlLlxuICAgICovXG4gICAgZ2V0IGlzTGVhZigpIHsgcmV0dXJuIHRoaXMudHlwZS5pc0xlYWY7IH1cbiAgICAvKipcbiAgICBUcnVlIHdoZW4gdGhpcyBpcyBhbiBhdG9tLCBpLmUuIHdoZW4gaXQgZG9lcyBub3QgaGF2ZSBkaXJlY3RseVxuICAgIGVkaXRhYmxlIGNvbnRlbnQuIFRoaXMgaXMgdXN1YWxseSB0aGUgc2FtZSBhcyBgaXNMZWFmYCwgYnV0IGNhblxuICAgIGJlIGNvbmZpZ3VyZWQgd2l0aCB0aGUgW2BhdG9tYCBwcm9wZXJ0eV0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGVTcGVjLmF0b20pXG4gICAgb24gYSBub2RlJ3Mgc3BlYyAodHlwaWNhbGx5IHVzZWQgd2hlbiB0aGUgbm9kZSBpcyBkaXNwbGF5ZWQgYXNcbiAgICBhbiB1bmVkaXRhYmxlIFtub2RlIHZpZXddKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyN2aWV3Lk5vZGVWaWV3KSkuXG4gICAgKi9cbiAgICBnZXQgaXNBdG9tKCkgeyByZXR1cm4gdGhpcy50eXBlLmlzQXRvbTsgfVxuICAgIC8qKlxuICAgIFJldHVybiBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGlzIG5vZGUgZm9yIGRlYnVnZ2luZ1xuICAgIHB1cnBvc2VzLlxuICAgICovXG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIGlmICh0aGlzLnR5cGUuc3BlYy50b0RlYnVnU3RyaW5nKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudHlwZS5zcGVjLnRvRGVidWdTdHJpbmcodGhpcyk7XG4gICAgICAgIGxldCBuYW1lID0gdGhpcy50eXBlLm5hbWU7XG4gICAgICAgIGlmICh0aGlzLmNvbnRlbnQuc2l6ZSlcbiAgICAgICAgICAgIG5hbWUgKz0gXCIoXCIgKyB0aGlzLmNvbnRlbnQudG9TdHJpbmdJbm5lcigpICsgXCIpXCI7XG4gICAgICAgIHJldHVybiB3cmFwTWFya3ModGhpcy5tYXJrcywgbmFtZSk7XG4gICAgfVxuICAgIC8qKlxuICAgIEdldCB0aGUgY29udGVudCBtYXRjaCBpbiB0aGlzIG5vZGUgYXQgdGhlIGdpdmVuIGluZGV4LlxuICAgICovXG4gICAgY29udGVudE1hdGNoQXQoaW5kZXgpIHtcbiAgICAgICAgbGV0IG1hdGNoID0gdGhpcy50eXBlLmNvbnRlbnRNYXRjaC5tYXRjaEZyYWdtZW50KHRoaXMuY29udGVudCwgMCwgaW5kZXgpO1xuICAgICAgICBpZiAoIW1hdGNoKVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FsbGVkIGNvbnRlbnRNYXRjaEF0IG9uIGEgbm9kZSB3aXRoIGludmFsaWQgY29udGVudFwiKTtcbiAgICAgICAgcmV0dXJuIG1hdGNoO1xuICAgIH1cbiAgICAvKipcbiAgICBUZXN0IHdoZXRoZXIgcmVwbGFjaW5nIHRoZSByYW5nZSBiZXR3ZWVuIGBmcm9tYCBhbmQgYHRvYCAoYnlcbiAgICBjaGlsZCBpbmRleCkgd2l0aCB0aGUgZ2l2ZW4gcmVwbGFjZW1lbnQgZnJhZ21lbnQgKHdoaWNoIGRlZmF1bHRzXG4gICAgdG8gdGhlIGVtcHR5IGZyYWdtZW50KSB3b3VsZCBsZWF2ZSB0aGUgbm9kZSdzIGNvbnRlbnQgdmFsaWQuIFlvdVxuICAgIGNhbiBvcHRpb25hbGx5IHBhc3MgYHN0YXJ0YCBhbmQgYGVuZGAgaW5kaWNlcyBpbnRvIHRoZVxuICAgIHJlcGxhY2VtZW50IGZyYWdtZW50LlxuICAgICovXG4gICAgY2FuUmVwbGFjZShmcm9tLCB0bywgcmVwbGFjZW1lbnQgPSBGcmFnbWVudC5lbXB0eSwgc3RhcnQgPSAwLCBlbmQgPSByZXBsYWNlbWVudC5jaGlsZENvdW50KSB7XG4gICAgICAgIGxldCBvbmUgPSB0aGlzLmNvbnRlbnRNYXRjaEF0KGZyb20pLm1hdGNoRnJhZ21lbnQocmVwbGFjZW1lbnQsIHN0YXJ0LCBlbmQpO1xuICAgICAgICBsZXQgdHdvID0gb25lICYmIG9uZS5tYXRjaEZyYWdtZW50KHRoaXMuY29udGVudCwgdG8pO1xuICAgICAgICBpZiAoIXR3byB8fCAhdHdvLnZhbGlkRW5kKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKylcbiAgICAgICAgICAgIGlmICghdGhpcy50eXBlLmFsbG93c01hcmtzKHJlcGxhY2VtZW50LmNoaWxkKGkpLm1hcmtzKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICAvKipcbiAgICBUZXN0IHdoZXRoZXIgcmVwbGFjaW5nIHRoZSByYW5nZSBgZnJvbWAgdG8gYHRvYCAoYnkgaW5kZXgpIHdpdGhcbiAgICBhIG5vZGUgb2YgdGhlIGdpdmVuIHR5cGUgd291bGQgbGVhdmUgdGhlIG5vZGUncyBjb250ZW50IHZhbGlkLlxuICAgICovXG4gICAgY2FuUmVwbGFjZVdpdGgoZnJvbSwgdG8sIHR5cGUsIG1hcmtzKSB7XG4gICAgICAgIGlmIChtYXJrcyAmJiAhdGhpcy50eXBlLmFsbG93c01hcmtzKG1hcmtzKSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgbGV0IHN0YXJ0ID0gdGhpcy5jb250ZW50TWF0Y2hBdChmcm9tKS5tYXRjaFR5cGUodHlwZSk7XG4gICAgICAgIGxldCBlbmQgPSBzdGFydCAmJiBzdGFydC5tYXRjaEZyYWdtZW50KHRoaXMuY29udGVudCwgdG8pO1xuICAgICAgICByZXR1cm4gZW5kID8gZW5kLnZhbGlkRW5kIDogZmFsc2U7XG4gICAgfVxuICAgIC8qKlxuICAgIFRlc3Qgd2hldGhlciB0aGUgZ2l2ZW4gbm9kZSdzIGNvbnRlbnQgY291bGQgYmUgYXBwZW5kZWQgdG8gdGhpc1xuICAgIG5vZGUuIElmIHRoYXQgbm9kZSBpcyBlbXB0eSwgdGhpcyB3aWxsIG9ubHkgcmV0dXJuIHRydWUgaWYgdGhlcmVcbiAgICBpcyBhdCBsZWFzdCBvbmUgbm9kZSB0eXBlIHRoYXQgY2FuIGFwcGVhciBpbiBib3RoIG5vZGVzICh0byBhdm9pZFxuICAgIG1lcmdpbmcgY29tcGxldGVseSBpbmNvbXBhdGlibGUgbm9kZXMpLlxuICAgICovXG4gICAgY2FuQXBwZW5kKG90aGVyKSB7XG4gICAgICAgIGlmIChvdGhlci5jb250ZW50LnNpemUpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jYW5SZXBsYWNlKHRoaXMuY2hpbGRDb3VudCwgdGhpcy5jaGlsZENvdW50LCBvdGhlci5jb250ZW50KTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudHlwZS5jb21wYXRpYmxlQ29udGVudChvdGhlci50eXBlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ2hlY2sgd2hldGhlciB0aGlzIG5vZGUgYW5kIGl0cyBkZXNjZW5kYW50cyBjb25mb3JtIHRvIHRoZVxuICAgIHNjaGVtYSwgYW5kIHJhaXNlIGFuIGV4Y2VwdGlvbiB3aGVuIHRoZXkgZG8gbm90LlxuICAgICovXG4gICAgY2hlY2soKSB7XG4gICAgICAgIHRoaXMudHlwZS5jaGVja0NvbnRlbnQodGhpcy5jb250ZW50KTtcbiAgICAgICAgdGhpcy50eXBlLmNoZWNrQXR0cnModGhpcy5hdHRycyk7XG4gICAgICAgIGxldCBjb3B5ID0gTWFyay5ub25lO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubWFya3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBtYXJrID0gdGhpcy5tYXJrc1tpXTtcbiAgICAgICAgICAgIG1hcmsudHlwZS5jaGVja0F0dHJzKG1hcmsuYXR0cnMpO1xuICAgICAgICAgICAgY29weSA9IG1hcmsuYWRkVG9TZXQoY29weSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFNYXJrLnNhbWVTZXQoY29weSwgdGhpcy5tYXJrcykpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgSW52YWxpZCBjb2xsZWN0aW9uIG9mIG1hcmtzIGZvciBub2RlICR7dGhpcy50eXBlLm5hbWV9OiAke3RoaXMubWFya3MubWFwKG0gPT4gbS50eXBlLm5hbWUpfWApO1xuICAgICAgICB0aGlzLmNvbnRlbnQuZm9yRWFjaChub2RlID0+IG5vZGUuY2hlY2soKSk7XG4gICAgfVxuICAgIC8qKlxuICAgIFJldHVybiBhIEpTT04tc2VyaWFsaXplYWJsZSByZXByZXNlbnRhdGlvbiBvZiB0aGlzIG5vZGUuXG4gICAgKi9cbiAgICB0b0pTT04oKSB7XG4gICAgICAgIGxldCBvYmogPSB7IHR5cGU6IHRoaXMudHlwZS5uYW1lIH07XG4gICAgICAgIGZvciAobGV0IF8gaW4gdGhpcy5hdHRycykge1xuICAgICAgICAgICAgb2JqLmF0dHJzID0gdGhpcy5hdHRycztcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmNvbnRlbnQuc2l6ZSlcbiAgICAgICAgICAgIG9iai5jb250ZW50ID0gdGhpcy5jb250ZW50LnRvSlNPTigpO1xuICAgICAgICBpZiAodGhpcy5tYXJrcy5sZW5ndGgpXG4gICAgICAgICAgICBvYmoubWFya3MgPSB0aGlzLm1hcmtzLm1hcChuID0+IG4udG9KU09OKCkpO1xuICAgICAgICByZXR1cm4gb2JqO1xuICAgIH1cbiAgICAvKipcbiAgICBEZXNlcmlhbGl6ZSBhIG5vZGUgZnJvbSBpdHMgSlNPTiByZXByZXNlbnRhdGlvbi5cbiAgICAqL1xuICAgIHN0YXRpYyBmcm9tSlNPTihzY2hlbWEsIGpzb24pIHtcbiAgICAgICAgaWYgKCFqc29uKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIGlucHV0IGZvciBOb2RlLmZyb21KU09OXCIpO1xuICAgICAgICBsZXQgbWFya3MgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChqc29uLm1hcmtzKSB7XG4gICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkoanNvbi5tYXJrcykpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIG1hcmsgZGF0YSBmb3IgTm9kZS5mcm9tSlNPTlwiKTtcbiAgICAgICAgICAgIG1hcmtzID0ganNvbi5tYXJrcy5tYXAoc2NoZW1hLm1hcmtGcm9tSlNPTik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGpzb24udHlwZSA9PSBcInRleHRcIikge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBqc29uLnRleHQgIT0gXCJzdHJpbmdcIilcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkludmFsaWQgdGV4dCBub2RlIGluIEpTT05cIik7XG4gICAgICAgICAgICByZXR1cm4gc2NoZW1hLnRleHQoanNvbi50ZXh0LCBtYXJrcyk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGNvbnRlbnQgPSBGcmFnbWVudC5mcm9tSlNPTihzY2hlbWEsIGpzb24uY29udGVudCk7XG4gICAgICAgIGxldCBub2RlID0gc2NoZW1hLm5vZGVUeXBlKGpzb24udHlwZSkuY3JlYXRlKGpzb24uYXR0cnMsIGNvbnRlbnQsIG1hcmtzKTtcbiAgICAgICAgbm9kZS50eXBlLmNoZWNrQXR0cnMobm9kZS5hdHRycyk7XG4gICAgICAgIHJldHVybiBub2RlO1xuICAgIH1cbn1cbk5vZGUucHJvdG90eXBlLnRleHQgPSB1bmRlZmluZWQ7XG5jbGFzcyBUZXh0Tm9kZSBleHRlbmRzIE5vZGUge1xuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgY29uc3RydWN0b3IodHlwZSwgYXR0cnMsIGNvbnRlbnQsIG1hcmtzKSB7XG4gICAgICAgIHN1cGVyKHR5cGUsIGF0dHJzLCBudWxsLCBtYXJrcyk7XG4gICAgICAgIGlmICghY29udGVudClcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiRW1wdHkgdGV4dCBub2RlcyBhcmUgbm90IGFsbG93ZWRcIik7XG4gICAgICAgIHRoaXMudGV4dCA9IGNvbnRlbnQ7XG4gICAgfVxuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICBpZiAodGhpcy50eXBlLnNwZWMudG9EZWJ1Z1N0cmluZylcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnR5cGUuc3BlYy50b0RlYnVnU3RyaW5nKHRoaXMpO1xuICAgICAgICByZXR1cm4gd3JhcE1hcmtzKHRoaXMubWFya3MsIEpTT04uc3RyaW5naWZ5KHRoaXMudGV4dCkpO1xuICAgIH1cbiAgICBnZXQgdGV4dENvbnRlbnQoKSB7IHJldHVybiB0aGlzLnRleHQ7IH1cbiAgICB0ZXh0QmV0d2Vlbihmcm9tLCB0bykgeyByZXR1cm4gdGhpcy50ZXh0LnNsaWNlKGZyb20sIHRvKTsgfVxuICAgIGdldCBub2RlU2l6ZSgpIHsgcmV0dXJuIHRoaXMudGV4dC5sZW5ndGg7IH1cbiAgICBtYXJrKG1hcmtzKSB7XG4gICAgICAgIHJldHVybiBtYXJrcyA9PSB0aGlzLm1hcmtzID8gdGhpcyA6IG5ldyBUZXh0Tm9kZSh0aGlzLnR5cGUsIHRoaXMuYXR0cnMsIHRoaXMudGV4dCwgbWFya3MpO1xuICAgIH1cbiAgICB3aXRoVGV4dCh0ZXh0KSB7XG4gICAgICAgIGlmICh0ZXh0ID09IHRoaXMudGV4dClcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICByZXR1cm4gbmV3IFRleHROb2RlKHRoaXMudHlwZSwgdGhpcy5hdHRycywgdGV4dCwgdGhpcy5tYXJrcyk7XG4gICAgfVxuICAgIGN1dChmcm9tID0gMCwgdG8gPSB0aGlzLnRleHQubGVuZ3RoKSB7XG4gICAgICAgIGlmIChmcm9tID09IDAgJiYgdG8gPT0gdGhpcy50ZXh0Lmxlbmd0aClcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICByZXR1cm4gdGhpcy53aXRoVGV4dCh0aGlzLnRleHQuc2xpY2UoZnJvbSwgdG8pKTtcbiAgICB9XG4gICAgZXEob3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2FtZU1hcmt1cChvdGhlcikgJiYgdGhpcy50ZXh0ID09IG90aGVyLnRleHQ7XG4gICAgfVxuICAgIHRvSlNPTigpIHtcbiAgICAgICAgbGV0IGJhc2UgPSBzdXBlci50b0pTT04oKTtcbiAgICAgICAgYmFzZS50ZXh0ID0gdGhpcy50ZXh0O1xuICAgICAgICByZXR1cm4gYmFzZTtcbiAgICB9XG59XG5mdW5jdGlvbiB3cmFwTWFya3MobWFya3MsIHN0cikge1xuICAgIGZvciAobGV0IGkgPSBtYXJrcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSlcbiAgICAgICAgc3RyID0gbWFya3NbaV0udHlwZS5uYW1lICsgXCIoXCIgKyBzdHIgKyBcIilcIjtcbiAgICByZXR1cm4gc3RyO1xufVxuXG4vKipcbkluc3RhbmNlcyBvZiB0aGlzIGNsYXNzIHJlcHJlc2VudCBhIG1hdGNoIHN0YXRlIG9mIGEgbm9kZSB0eXBlJ3Ncbltjb250ZW50IGV4cHJlc3Npb25dKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5Ob2RlU3BlYy5jb250ZW50KSwgYW5kIGNhbiBiZSB1c2VkIHRvXG5maW5kIG91dCB3aGV0aGVyIGZ1cnRoZXIgY29udGVudCBtYXRjaGVzIGhlcmUsIGFuZCB3aGV0aGVyIGEgZ2l2ZW5cbnBvc2l0aW9uIGlzIGEgdmFsaWQgZW5kIG9mIHRoZSBub2RlLlxuKi9cbmNsYXNzIENvbnRlbnRNYXRjaCB7XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBUcnVlIHdoZW4gdGhpcyBtYXRjaCBzdGF0ZSByZXByZXNlbnRzIGEgdmFsaWQgZW5kIG9mIHRoZSBub2RlLlxuICAgICovXG4gICAgdmFsaWRFbmQpIHtcbiAgICAgICAgdGhpcy52YWxpZEVuZCA9IHZhbGlkRW5kO1xuICAgICAgICAvKipcbiAgICAgICAgQGludGVybmFsXG4gICAgICAgICovXG4gICAgICAgIHRoaXMubmV4dCA9IFtdO1xuICAgICAgICAvKipcbiAgICAgICAgQGludGVybmFsXG4gICAgICAgICovXG4gICAgICAgIHRoaXMud3JhcENhY2hlID0gW107XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgc3RhdGljIHBhcnNlKHN0cmluZywgbm9kZVR5cGVzKSB7XG4gICAgICAgIGxldCBzdHJlYW0gPSBuZXcgVG9rZW5TdHJlYW0oc3RyaW5nLCBub2RlVHlwZXMpO1xuICAgICAgICBpZiAoc3RyZWFtLm5leHQgPT0gbnVsbClcbiAgICAgICAgICAgIHJldHVybiBDb250ZW50TWF0Y2guZW1wdHk7XG4gICAgICAgIGxldCBleHByID0gcGFyc2VFeHByKHN0cmVhbSk7XG4gICAgICAgIGlmIChzdHJlYW0ubmV4dClcbiAgICAgICAgICAgIHN0cmVhbS5lcnIoXCJVbmV4cGVjdGVkIHRyYWlsaW5nIHRleHRcIik7XG4gICAgICAgIGxldCBtYXRjaCA9IGRmYShuZmEoZXhwcikpO1xuICAgICAgICBjaGVja0ZvckRlYWRFbmRzKG1hdGNoLCBzdHJlYW0pO1xuICAgICAgICByZXR1cm4gbWF0Y2g7XG4gICAgfVxuICAgIC8qKlxuICAgIE1hdGNoIGEgbm9kZSB0eXBlLCByZXR1cm5pbmcgYSBtYXRjaCBhZnRlciB0aGF0IG5vZGUgaWZcbiAgICBzdWNjZXNzZnVsLlxuICAgICovXG4gICAgbWF0Y2hUeXBlKHR5cGUpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5leHQubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICBpZiAodGhpcy5uZXh0W2ldLnR5cGUgPT0gdHlwZSlcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5uZXh0W2ldLm5leHQ7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICAvKipcbiAgICBUcnkgdG8gbWF0Y2ggYSBmcmFnbWVudC4gUmV0dXJucyB0aGUgcmVzdWx0aW5nIG1hdGNoIHdoZW5cbiAgICBzdWNjZXNzZnVsLlxuICAgICovXG4gICAgbWF0Y2hGcmFnbWVudChmcmFnLCBzdGFydCA9IDAsIGVuZCA9IGZyYWcuY2hpbGRDb3VudCkge1xuICAgICAgICBsZXQgY3VyID0gdGhpcztcbiAgICAgICAgZm9yIChsZXQgaSA9IHN0YXJ0OyBjdXIgJiYgaSA8IGVuZDsgaSsrKVxuICAgICAgICAgICAgY3VyID0gY3VyLm1hdGNoVHlwZShmcmFnLmNoaWxkKGkpLnR5cGUpO1xuICAgICAgICByZXR1cm4gY3VyO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGdldCBpbmxpbmVDb250ZW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5uZXh0Lmxlbmd0aCAhPSAwICYmIHRoaXMubmV4dFswXS50eXBlLmlzSW5saW5lO1xuICAgIH1cbiAgICAvKipcbiAgICBHZXQgdGhlIGZpcnN0IG1hdGNoaW5nIG5vZGUgdHlwZSBhdCB0aGlzIG1hdGNoIHBvc2l0aW9uIHRoYXQgY2FuXG4gICAgYmUgZ2VuZXJhdGVkLlxuICAgICovXG4gICAgZ2V0IGRlZmF1bHRUeXBlKCkge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubmV4dC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IHsgdHlwZSB9ID0gdGhpcy5uZXh0W2ldO1xuICAgICAgICAgICAgaWYgKCEodHlwZS5pc1RleHQgfHwgdHlwZS5oYXNSZXF1aXJlZEF0dHJzKCkpKVxuICAgICAgICAgICAgICAgIHJldHVybiB0eXBlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGNvbXBhdGlibGUob3RoZXIpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5leHQubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IG90aGVyLm5leHQubGVuZ3RoOyBqKyspXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMubmV4dFtpXS50eXBlID09IG90aGVyLm5leHRbal0udHlwZSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgLyoqXG4gICAgVHJ5IHRvIG1hdGNoIHRoZSBnaXZlbiBmcmFnbWVudCwgYW5kIGlmIHRoYXQgZmFpbHMsIHNlZSBpZiBpdCBjYW5cbiAgICBiZSBtYWRlIHRvIG1hdGNoIGJ5IGluc2VydGluZyBub2RlcyBpbiBmcm9udCBvZiBpdC4gV2hlblxuICAgIHN1Y2Nlc3NmdWwsIHJldHVybiBhIGZyYWdtZW50IG9mIGluc2VydGVkIG5vZGVzICh3aGljaCBtYXkgYmVcbiAgICBlbXB0eSBpZiBub3RoaW5nIGhhZCB0byBiZSBpbnNlcnRlZCkuIFdoZW4gYHRvRW5kYCBpcyB0cnVlLCBvbmx5XG4gICAgcmV0dXJuIGEgZnJhZ21lbnQgaWYgdGhlIHJlc3VsdGluZyBtYXRjaCBnb2VzIHRvIHRoZSBlbmQgb2YgdGhlXG4gICAgY29udGVudCBleHByZXNzaW9uLlxuICAgICovXG4gICAgZmlsbEJlZm9yZShhZnRlciwgdG9FbmQgPSBmYWxzZSwgc3RhcnRJbmRleCA9IDApIHtcbiAgICAgICAgbGV0IHNlZW4gPSBbdGhpc107XG4gICAgICAgIGZ1bmN0aW9uIHNlYXJjaChtYXRjaCwgdHlwZXMpIHtcbiAgICAgICAgICAgIGxldCBmaW5pc2hlZCA9IG1hdGNoLm1hdGNoRnJhZ21lbnQoYWZ0ZXIsIHN0YXJ0SW5kZXgpO1xuICAgICAgICAgICAgaWYgKGZpbmlzaGVkICYmICghdG9FbmQgfHwgZmluaXNoZWQudmFsaWRFbmQpKVxuICAgICAgICAgICAgICAgIHJldHVybiBGcmFnbWVudC5mcm9tKHR5cGVzLm1hcCh0cCA9PiB0cC5jcmVhdGVBbmRGaWxsKCkpKTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbWF0Y2gubmV4dC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGxldCB7IHR5cGUsIG5leHQgfSA9IG1hdGNoLm5leHRbaV07XG4gICAgICAgICAgICAgICAgaWYgKCEodHlwZS5pc1RleHQgfHwgdHlwZS5oYXNSZXF1aXJlZEF0dHJzKCkpICYmIHNlZW4uaW5kZXhPZihuZXh0KSA9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICBzZWVuLnB1c2gobmV4dCk7XG4gICAgICAgICAgICAgICAgICAgIGxldCBmb3VuZCA9IHNlYXJjaChuZXh0LCB0eXBlcy5jb25jYXQodHlwZSkpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZm91bmQpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZm91bmQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNlYXJjaCh0aGlzLCBbXSk7XG4gICAgfVxuICAgIC8qKlxuICAgIEZpbmQgYSBzZXQgb2Ygd3JhcHBpbmcgbm9kZSB0eXBlcyB0aGF0IHdvdWxkIGFsbG93IGEgbm9kZSBvZiB0aGVcbiAgICBnaXZlbiB0eXBlIHRvIGFwcGVhciBhdCB0aGlzIHBvc2l0aW9uLiBUaGUgcmVzdWx0IG1heSBiZSBlbXB0eVxuICAgICh3aGVuIGl0IGZpdHMgZGlyZWN0bHkpIGFuZCB3aWxsIGJlIG51bGwgd2hlbiBubyBzdWNoIHdyYXBwaW5nXG4gICAgZXhpc3RzLlxuICAgICovXG4gICAgZmluZFdyYXBwaW5nKHRhcmdldCkge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMud3JhcENhY2hlLmxlbmd0aDsgaSArPSAyKVxuICAgICAgICAgICAgaWYgKHRoaXMud3JhcENhY2hlW2ldID09IHRhcmdldClcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy53cmFwQ2FjaGVbaSArIDFdO1xuICAgICAgICBsZXQgY29tcHV0ZWQgPSB0aGlzLmNvbXB1dGVXcmFwcGluZyh0YXJnZXQpO1xuICAgICAgICB0aGlzLndyYXBDYWNoZS5wdXNoKHRhcmdldCwgY29tcHV0ZWQpO1xuICAgICAgICByZXR1cm4gY29tcHV0ZWQ7XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgY29tcHV0ZVdyYXBwaW5nKHRhcmdldCkge1xuICAgICAgICBsZXQgc2VlbiA9IE9iamVjdC5jcmVhdGUobnVsbCksIGFjdGl2ZSA9IFt7IG1hdGNoOiB0aGlzLCB0eXBlOiBudWxsLCB2aWE6IG51bGwgfV07XG4gICAgICAgIHdoaWxlIChhY3RpdmUubGVuZ3RoKSB7XG4gICAgICAgICAgICBsZXQgY3VycmVudCA9IGFjdGl2ZS5zaGlmdCgpLCBtYXRjaCA9IGN1cnJlbnQubWF0Y2g7XG4gICAgICAgICAgICBpZiAobWF0Y2gubWF0Y2hUeXBlKHRhcmdldCkpIHtcbiAgICAgICAgICAgICAgICBsZXQgcmVzdWx0ID0gW107XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgb2JqID0gY3VycmVudDsgb2JqLnR5cGU7IG9iaiA9IG9iai52aWEpXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKG9iai50eXBlKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0LnJldmVyc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbWF0Y2gubmV4dC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGxldCB7IHR5cGUsIG5leHQgfSA9IG1hdGNoLm5leHRbaV07XG4gICAgICAgICAgICAgICAgaWYgKCF0eXBlLmlzTGVhZiAmJiAhdHlwZS5oYXNSZXF1aXJlZEF0dHJzKCkgJiYgISh0eXBlLm5hbWUgaW4gc2VlbikgJiYgKCFjdXJyZW50LnR5cGUgfHwgbmV4dC52YWxpZEVuZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgYWN0aXZlLnB1c2goeyBtYXRjaDogdHlwZS5jb250ZW50TWF0Y2gsIHR5cGUsIHZpYTogY3VycmVudCB9KTtcbiAgICAgICAgICAgICAgICAgICAgc2Vlblt0eXBlLm5hbWVdID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIC8qKlxuICAgIFRoZSBudW1iZXIgb2Ygb3V0Z29pbmcgZWRnZXMgdGhpcyBub2RlIGhhcyBpbiB0aGUgZmluaXRlXG4gICAgYXV0b21hdG9uIHRoYXQgZGVzY3JpYmVzIHRoZSBjb250ZW50IGV4cHJlc3Npb24uXG4gICAgKi9cbiAgICBnZXQgZWRnZUNvdW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5uZXh0Lmxlbmd0aDtcbiAgICB9XG4gICAgLyoqXG4gICAgR2V0IHRoZSBfbl9cdTIwMEJ0aCBvdXRnb2luZyBlZGdlIGZyb20gdGhpcyBub2RlIGluIHRoZSBmaW5pdGVcbiAgICBhdXRvbWF0b24gdGhhdCBkZXNjcmliZXMgdGhlIGNvbnRlbnQgZXhwcmVzc2lvbi5cbiAgICAqL1xuICAgIGVkZ2Uobikge1xuICAgICAgICBpZiAobiA+PSB0aGlzLm5leHQubGVuZ3RoKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoYFRoZXJlJ3Mgbm8gJHtufXRoIGVkZ2UgaW4gdGhpcyBjb250ZW50IG1hdGNoYCk7XG4gICAgICAgIHJldHVybiB0aGlzLm5leHRbbl07XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIGxldCBzZWVuID0gW107XG4gICAgICAgIGZ1bmN0aW9uIHNjYW4obSkge1xuICAgICAgICAgICAgc2Vlbi5wdXNoKG0pO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtLm5leHQubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICAgICAgaWYgKHNlZW4uaW5kZXhPZihtLm5leHRbaV0ubmV4dCkgPT0gLTEpXG4gICAgICAgICAgICAgICAgICAgIHNjYW4obS5uZXh0W2ldLm5leHQpO1xuICAgICAgICB9XG4gICAgICAgIHNjYW4odGhpcyk7XG4gICAgICAgIHJldHVybiBzZWVuLm1hcCgobSwgaSkgPT4ge1xuICAgICAgICAgICAgbGV0IG91dCA9IGkgKyAobS52YWxpZEVuZCA/IFwiKlwiIDogXCIgXCIpICsgXCIgXCI7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG0ubmV4dC5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgICAgICBvdXQgKz0gKGkgPyBcIiwgXCIgOiBcIlwiKSArIG0ubmV4dFtpXS50eXBlLm5hbWUgKyBcIi0+XCIgKyBzZWVuLmluZGV4T2YobS5uZXh0W2ldLm5leHQpO1xuICAgICAgICAgICAgcmV0dXJuIG91dDtcbiAgICAgICAgfSkuam9pbihcIlxcblwiKTtcbiAgICB9XG59XG4vKipcbkBpbnRlcm5hbFxuKi9cbkNvbnRlbnRNYXRjaC5lbXB0eSA9IG5ldyBDb250ZW50TWF0Y2godHJ1ZSk7XG5jbGFzcyBUb2tlblN0cmVhbSB7XG4gICAgY29uc3RydWN0b3Ioc3RyaW5nLCBub2RlVHlwZXMpIHtcbiAgICAgICAgdGhpcy5zdHJpbmcgPSBzdHJpbmc7XG4gICAgICAgIHRoaXMubm9kZVR5cGVzID0gbm9kZVR5cGVzO1xuICAgICAgICB0aGlzLmlubGluZSA9IG51bGw7XG4gICAgICAgIHRoaXMucG9zID0gMDtcbiAgICAgICAgdGhpcy50b2tlbnMgPSBzdHJpbmcuc3BsaXQoL1xccyooPz1cXGJ8XFxXfCQpLyk7XG4gICAgICAgIGlmICh0aGlzLnRva2Vuc1t0aGlzLnRva2Vucy5sZW5ndGggLSAxXSA9PSBcIlwiKVxuICAgICAgICAgICAgdGhpcy50b2tlbnMucG9wKCk7XG4gICAgICAgIGlmICh0aGlzLnRva2Vuc1swXSA9PSBcIlwiKVxuICAgICAgICAgICAgdGhpcy50b2tlbnMuc2hpZnQoKTtcbiAgICB9XG4gICAgZ2V0IG5leHQoKSB7IHJldHVybiB0aGlzLnRva2Vuc1t0aGlzLnBvc107IH1cbiAgICBlYXQodG9rKSB7IHJldHVybiB0aGlzLm5leHQgPT0gdG9rICYmICh0aGlzLnBvcysrIHx8IHRydWUpOyB9XG4gICAgZXJyKHN0cikgeyB0aHJvdyBuZXcgU3ludGF4RXJyb3Ioc3RyICsgXCIgKGluIGNvbnRlbnQgZXhwcmVzc2lvbiAnXCIgKyB0aGlzLnN0cmluZyArIFwiJylcIik7IH1cbn1cbmZ1bmN0aW9uIHBhcnNlRXhwcihzdHJlYW0pIHtcbiAgICBsZXQgZXhwcnMgPSBbXTtcbiAgICBkbyB7XG4gICAgICAgIGV4cHJzLnB1c2gocGFyc2VFeHByU2VxKHN0cmVhbSkpO1xuICAgIH0gd2hpbGUgKHN0cmVhbS5lYXQoXCJ8XCIpKTtcbiAgICByZXR1cm4gZXhwcnMubGVuZ3RoID09IDEgPyBleHByc1swXSA6IHsgdHlwZTogXCJjaG9pY2VcIiwgZXhwcnMgfTtcbn1cbmZ1bmN0aW9uIHBhcnNlRXhwclNlcShzdHJlYW0pIHtcbiAgICBsZXQgZXhwcnMgPSBbXTtcbiAgICBkbyB7XG4gICAgICAgIGV4cHJzLnB1c2gocGFyc2VFeHByU3Vic2NyaXB0KHN0cmVhbSkpO1xuICAgIH0gd2hpbGUgKHN0cmVhbS5uZXh0ICYmIHN0cmVhbS5uZXh0ICE9IFwiKVwiICYmIHN0cmVhbS5uZXh0ICE9IFwifFwiKTtcbiAgICByZXR1cm4gZXhwcnMubGVuZ3RoID09IDEgPyBleHByc1swXSA6IHsgdHlwZTogXCJzZXFcIiwgZXhwcnMgfTtcbn1cbmZ1bmN0aW9uIHBhcnNlRXhwclN1YnNjcmlwdChzdHJlYW0pIHtcbiAgICBsZXQgZXhwciA9IHBhcnNlRXhwckF0b20oc3RyZWFtKTtcbiAgICBmb3IgKDs7KSB7XG4gICAgICAgIGlmIChzdHJlYW0uZWF0KFwiK1wiKSlcbiAgICAgICAgICAgIGV4cHIgPSB7IHR5cGU6IFwicGx1c1wiLCBleHByIH07XG4gICAgICAgIGVsc2UgaWYgKHN0cmVhbS5lYXQoXCIqXCIpKVxuICAgICAgICAgICAgZXhwciA9IHsgdHlwZTogXCJzdGFyXCIsIGV4cHIgfTtcbiAgICAgICAgZWxzZSBpZiAoc3RyZWFtLmVhdChcIj9cIikpXG4gICAgICAgICAgICBleHByID0geyB0eXBlOiBcIm9wdFwiLCBleHByIH07XG4gICAgICAgIGVsc2UgaWYgKHN0cmVhbS5lYXQoXCJ7XCIpKVxuICAgICAgICAgICAgZXhwciA9IHBhcnNlRXhwclJhbmdlKHN0cmVhbSwgZXhwcik7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICByZXR1cm4gZXhwcjtcbn1cbmZ1bmN0aW9uIHBhcnNlTnVtKHN0cmVhbSkge1xuICAgIGlmICgvXFxELy50ZXN0KHN0cmVhbS5uZXh0KSlcbiAgICAgICAgc3RyZWFtLmVycihcIkV4cGVjdGVkIG51bWJlciwgZ290ICdcIiArIHN0cmVhbS5uZXh0ICsgXCInXCIpO1xuICAgIGxldCByZXN1bHQgPSBOdW1iZXIoc3RyZWFtLm5leHQpO1xuICAgIHN0cmVhbS5wb3MrKztcbiAgICByZXR1cm4gcmVzdWx0O1xufVxuZnVuY3Rpb24gcGFyc2VFeHByUmFuZ2Uoc3RyZWFtLCBleHByKSB7XG4gICAgbGV0IG1pbiA9IHBhcnNlTnVtKHN0cmVhbSksIG1heCA9IG1pbjtcbiAgICBpZiAoc3RyZWFtLmVhdChcIixcIikpIHtcbiAgICAgICAgaWYgKHN0cmVhbS5uZXh0ICE9IFwifVwiKVxuICAgICAgICAgICAgbWF4ID0gcGFyc2VOdW0oc3RyZWFtKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgbWF4ID0gLTE7XG4gICAgfVxuICAgIGlmICghc3RyZWFtLmVhdChcIn1cIikpXG4gICAgICAgIHN0cmVhbS5lcnIoXCJVbmNsb3NlZCBicmFjZWQgcmFuZ2VcIik7XG4gICAgcmV0dXJuIHsgdHlwZTogXCJyYW5nZVwiLCBtaW4sIG1heCwgZXhwciB9O1xufVxuZnVuY3Rpb24gcmVzb2x2ZU5hbWUoc3RyZWFtLCBuYW1lKSB7XG4gICAgbGV0IHR5cGVzID0gc3RyZWFtLm5vZGVUeXBlcywgdHlwZSA9IHR5cGVzW25hbWVdO1xuICAgIGlmICh0eXBlKVxuICAgICAgICByZXR1cm4gW3R5cGVdO1xuICAgIGxldCByZXN1bHQgPSBbXTtcbiAgICBmb3IgKGxldCB0eXBlTmFtZSBpbiB0eXBlcykge1xuICAgICAgICBsZXQgdHlwZSA9IHR5cGVzW3R5cGVOYW1lXTtcbiAgICAgICAgaWYgKHR5cGUuaXNJbkdyb3VwKG5hbWUpKVxuICAgICAgICAgICAgcmVzdWx0LnB1c2godHlwZSk7XG4gICAgfVxuICAgIGlmIChyZXN1bHQubGVuZ3RoID09IDApXG4gICAgICAgIHN0cmVhbS5lcnIoXCJObyBub2RlIHR5cGUgb3IgZ3JvdXAgJ1wiICsgbmFtZSArIFwiJyBmb3VuZFwiKTtcbiAgICByZXR1cm4gcmVzdWx0O1xufVxuZnVuY3Rpb24gcGFyc2VFeHByQXRvbShzdHJlYW0pIHtcbiAgICBpZiAoc3RyZWFtLmVhdChcIihcIikpIHtcbiAgICAgICAgbGV0IGV4cHIgPSBwYXJzZUV4cHIoc3RyZWFtKTtcbiAgICAgICAgaWYgKCFzdHJlYW0uZWF0KFwiKVwiKSlcbiAgICAgICAgICAgIHN0cmVhbS5lcnIoXCJNaXNzaW5nIGNsb3NpbmcgcGFyZW5cIik7XG4gICAgICAgIHJldHVybiBleHByO1xuICAgIH1cbiAgICBlbHNlIGlmICghL1xcVy8udGVzdChzdHJlYW0ubmV4dCkpIHtcbiAgICAgICAgbGV0IGV4cHJzID0gcmVzb2x2ZU5hbWUoc3RyZWFtLCBzdHJlYW0ubmV4dCkubWFwKHR5cGUgPT4ge1xuICAgICAgICAgICAgaWYgKHN0cmVhbS5pbmxpbmUgPT0gbnVsbClcbiAgICAgICAgICAgICAgICBzdHJlYW0uaW5saW5lID0gdHlwZS5pc0lubGluZTtcbiAgICAgICAgICAgIGVsc2UgaWYgKHN0cmVhbS5pbmxpbmUgIT0gdHlwZS5pc0lubGluZSlcbiAgICAgICAgICAgICAgICBzdHJlYW0uZXJyKFwiTWl4aW5nIGlubGluZSBhbmQgYmxvY2sgY29udGVudFwiKTtcbiAgICAgICAgICAgIHJldHVybiB7IHR5cGU6IFwibmFtZVwiLCB2YWx1ZTogdHlwZSB9O1xuICAgICAgICB9KTtcbiAgICAgICAgc3RyZWFtLnBvcysrO1xuICAgICAgICByZXR1cm4gZXhwcnMubGVuZ3RoID09IDEgPyBleHByc1swXSA6IHsgdHlwZTogXCJjaG9pY2VcIiwgZXhwcnMgfTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHN0cmVhbS5lcnIoXCJVbmV4cGVjdGVkIHRva2VuICdcIiArIHN0cmVhbS5uZXh0ICsgXCInXCIpO1xuICAgIH1cbn1cbi8vIENvbnN0cnVjdCBhbiBORkEgZnJvbSBhbiBleHByZXNzaW9uIGFzIHJldHVybmVkIGJ5IHRoZSBwYXJzZXIuIFRoZVxuLy8gTkZBIGlzIHJlcHJlc2VudGVkIGFzIGFuIGFycmF5IG9mIHN0YXRlcywgd2hpY2ggYXJlIHRoZW1zZWx2ZXNcbi8vIGFycmF5cyBvZiBlZGdlcywgd2hpY2ggYXJlIGB7dGVybSwgdG99YCBvYmplY3RzLiBUaGUgZmlyc3Qgc3RhdGUgaXNcbi8vIHRoZSBlbnRyeSBzdGF0ZSBhbmQgdGhlIGxhc3Qgbm9kZSBpcyB0aGUgc3VjY2VzcyBzdGF0ZS5cbi8vXG4vLyBOb3RlIHRoYXQgdW5saWtlIHR5cGljYWwgTkZBcywgdGhlIGVkZ2Ugb3JkZXJpbmcgaW4gdGhpcyBvbmUgaXNcbi8vIHNpZ25pZmljYW50LCBpbiB0aGF0IGl0IGlzIHVzZWQgdG8gY29udHJ1Y3QgZmlsbGVyIGNvbnRlbnQgd2hlblxuLy8gbmVjZXNzYXJ5LlxuZnVuY3Rpb24gbmZhKGV4cHIpIHtcbiAgICBsZXQgbmZhID0gW1tdXTtcbiAgICBjb25uZWN0KGNvbXBpbGUoZXhwciwgMCksIG5vZGUoKSk7XG4gICAgcmV0dXJuIG5mYTtcbiAgICBmdW5jdGlvbiBub2RlKCkgeyByZXR1cm4gbmZhLnB1c2goW10pIC0gMTsgfVxuICAgIGZ1bmN0aW9uIGVkZ2UoZnJvbSwgdG8sIHRlcm0pIHtcbiAgICAgICAgbGV0IGVkZ2UgPSB7IHRlcm0sIHRvIH07XG4gICAgICAgIG5mYVtmcm9tXS5wdXNoKGVkZ2UpO1xuICAgICAgICByZXR1cm4gZWRnZTtcbiAgICB9XG4gICAgZnVuY3Rpb24gY29ubmVjdChlZGdlcywgdG8pIHtcbiAgICAgICAgZWRnZXMuZm9yRWFjaChlZGdlID0+IGVkZ2UudG8gPSB0byk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGNvbXBpbGUoZXhwciwgZnJvbSkge1xuICAgICAgICBpZiAoZXhwci50eXBlID09IFwiY2hvaWNlXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBleHByLmV4cHJzLnJlZHVjZSgob3V0LCBleHByKSA9PiBvdXQuY29uY2F0KGNvbXBpbGUoZXhwciwgZnJvbSkpLCBbXSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZXhwci50eXBlID09IFwic2VxXCIpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOzsgaSsrKSB7XG4gICAgICAgICAgICAgICAgbGV0IG5leHQgPSBjb21waWxlKGV4cHIuZXhwcnNbaV0sIGZyb20pO1xuICAgICAgICAgICAgICAgIGlmIChpID09IGV4cHIuZXhwcnMubGVuZ3RoIC0gMSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5leHQ7XG4gICAgICAgICAgICAgICAgY29ubmVjdChuZXh0LCBmcm9tID0gbm9kZSgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChleHByLnR5cGUgPT0gXCJzdGFyXCIpIHtcbiAgICAgICAgICAgIGxldCBsb29wID0gbm9kZSgpO1xuICAgICAgICAgICAgZWRnZShmcm9tLCBsb29wKTtcbiAgICAgICAgICAgIGNvbm5lY3QoY29tcGlsZShleHByLmV4cHIsIGxvb3ApLCBsb29wKTtcbiAgICAgICAgICAgIHJldHVybiBbZWRnZShsb29wKV07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZXhwci50eXBlID09IFwicGx1c1wiKSB7XG4gICAgICAgICAgICBsZXQgbG9vcCA9IG5vZGUoKTtcbiAgICAgICAgICAgIGNvbm5lY3QoY29tcGlsZShleHByLmV4cHIsIGZyb20pLCBsb29wKTtcbiAgICAgICAgICAgIGNvbm5lY3QoY29tcGlsZShleHByLmV4cHIsIGxvb3ApLCBsb29wKTtcbiAgICAgICAgICAgIHJldHVybiBbZWRnZShsb29wKV07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZXhwci50eXBlID09IFwib3B0XCIpIHtcbiAgICAgICAgICAgIHJldHVybiBbZWRnZShmcm9tKV0uY29uY2F0KGNvbXBpbGUoZXhwci5leHByLCBmcm9tKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZXhwci50eXBlID09IFwicmFuZ2VcIikge1xuICAgICAgICAgICAgbGV0IGN1ciA9IGZyb207XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV4cHIubWluOyBpKyspIHtcbiAgICAgICAgICAgICAgICBsZXQgbmV4dCA9IG5vZGUoKTtcbiAgICAgICAgICAgICAgICBjb25uZWN0KGNvbXBpbGUoZXhwci5leHByLCBjdXIpLCBuZXh0KTtcbiAgICAgICAgICAgICAgICBjdXIgPSBuZXh0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGV4cHIubWF4ID09IC0xKSB7XG4gICAgICAgICAgICAgICAgY29ubmVjdChjb21waWxlKGV4cHIuZXhwciwgY3VyKSwgY3VyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSBleHByLm1pbjsgaSA8IGV4cHIubWF4OyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG5leHQgPSBub2RlKCk7XG4gICAgICAgICAgICAgICAgICAgIGVkZ2UoY3VyLCBuZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgY29ubmVjdChjb21waWxlKGV4cHIuZXhwciwgY3VyKSwgbmV4dCk7XG4gICAgICAgICAgICAgICAgICAgIGN1ciA9IG5leHQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIFtlZGdlKGN1cildO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGV4cHIudHlwZSA9PSBcIm5hbWVcIikge1xuICAgICAgICAgICAgcmV0dXJuIFtlZGdlKGZyb20sIHVuZGVmaW5lZCwgZXhwci52YWx1ZSldO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBleHByIHR5cGVcIik7XG4gICAgICAgIH1cbiAgICB9XG59XG5mdW5jdGlvbiBjbXAoYSwgYikgeyByZXR1cm4gYiAtIGE7IH1cbi8vIEdldCB0aGUgc2V0IG9mIG5vZGVzIHJlYWNoYWJsZSBieSBudWxsIGVkZ2VzIGZyb20gYG5vZGVgLiBPbWl0XG4vLyBub2RlcyB3aXRoIG9ubHkgYSBzaW5nbGUgbnVsbC1vdXQtZWRnZSwgc2luY2UgdGhleSBtYXkgbGVhZCB0b1xuLy8gbmVlZGxlc3MgZHVwbGljYXRlZCBub2Rlcy5cbmZ1bmN0aW9uIG51bGxGcm9tKG5mYSwgbm9kZSkge1xuICAgIGxldCByZXN1bHQgPSBbXTtcbiAgICBzY2FuKG5vZGUpO1xuICAgIHJldHVybiByZXN1bHQuc29ydChjbXApO1xuICAgIGZ1bmN0aW9uIHNjYW4obm9kZSkge1xuICAgICAgICBsZXQgZWRnZXMgPSBuZmFbbm9kZV07XG4gICAgICAgIGlmIChlZGdlcy5sZW5ndGggPT0gMSAmJiAhZWRnZXNbMF0udGVybSlcbiAgICAgICAgICAgIHJldHVybiBzY2FuKGVkZ2VzWzBdLnRvKTtcbiAgICAgICAgcmVzdWx0LnB1c2gobm9kZSk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZWRnZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCB7IHRlcm0sIHRvIH0gPSBlZGdlc1tpXTtcbiAgICAgICAgICAgIGlmICghdGVybSAmJiByZXN1bHQuaW5kZXhPZih0bykgPT0gLTEpXG4gICAgICAgICAgICAgICAgc2Nhbih0byk7XG4gICAgICAgIH1cbiAgICB9XG59XG4vLyBDb21waWxlcyBhbiBORkEgYXMgcHJvZHVjZWQgYnkgYG5mYWAgaW50byBhIERGQSwgbW9kZWxlZCBhcyBhIHNldFxuLy8gb2Ygc3RhdGUgb2JqZWN0cyAoYENvbnRlbnRNYXRjaGAgaW5zdGFuY2VzKSB3aXRoIHRyYW5zaXRpb25zXG4vLyBiZXR3ZWVuIHRoZW0uXG5mdW5jdGlvbiBkZmEobmZhKSB7XG4gICAgbGV0IGxhYmVsZWQgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHJldHVybiBleHBsb3JlKG51bGxGcm9tKG5mYSwgMCkpO1xuICAgIGZ1bmN0aW9uIGV4cGxvcmUoc3RhdGVzKSB7XG4gICAgICAgIGxldCBvdXQgPSBbXTtcbiAgICAgICAgc3RhdGVzLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgICAgICBuZmFbbm9kZV0uZm9yRWFjaCgoeyB0ZXJtLCB0byB9KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCF0ZXJtKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgbGV0IHNldDtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG91dC5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgICAgICAgICAgaWYgKG91dFtpXVswXSA9PSB0ZXJtKVxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0ID0gb3V0W2ldWzFdO1xuICAgICAgICAgICAgICAgIG51bGxGcm9tKG5mYSwgdG8pLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghc2V0KVxuICAgICAgICAgICAgICAgICAgICAgICAgb3V0LnB1c2goW3Rlcm0sIHNldCA9IFtdXSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzZXQuaW5kZXhPZihub2RlKSA9PSAtMSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldC5wdXNoKG5vZGUpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICBsZXQgc3RhdGUgPSBsYWJlbGVkW3N0YXRlcy5qb2luKFwiLFwiKV0gPSBuZXcgQ29udGVudE1hdGNoKHN0YXRlcy5pbmRleE9mKG5mYS5sZW5ndGggLSAxKSA+IC0xKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvdXQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBzdGF0ZXMgPSBvdXRbaV1bMV0uc29ydChjbXApO1xuICAgICAgICAgICAgc3RhdGUubmV4dC5wdXNoKHsgdHlwZTogb3V0W2ldWzBdLCBuZXh0OiBsYWJlbGVkW3N0YXRlcy5qb2luKFwiLFwiKV0gfHwgZXhwbG9yZShzdGF0ZXMpIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdGF0ZTtcbiAgICB9XG59XG5mdW5jdGlvbiBjaGVja0ZvckRlYWRFbmRzKG1hdGNoLCBzdHJlYW0pIHtcbiAgICBmb3IgKGxldCBpID0gMCwgd29yayA9IFttYXRjaF07IGkgPCB3b3JrLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxldCBzdGF0ZSA9IHdvcmtbaV0sIGRlYWQgPSAhc3RhdGUudmFsaWRFbmQsIG5vZGVzID0gW107XG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgc3RhdGUubmV4dC5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgbGV0IHsgdHlwZSwgbmV4dCB9ID0gc3RhdGUubmV4dFtqXTtcbiAgICAgICAgICAgIG5vZGVzLnB1c2godHlwZS5uYW1lKTtcbiAgICAgICAgICAgIGlmIChkZWFkICYmICEodHlwZS5pc1RleHQgfHwgdHlwZS5oYXNSZXF1aXJlZEF0dHJzKCkpKVxuICAgICAgICAgICAgICAgIGRlYWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmICh3b3JrLmluZGV4T2YobmV4dCkgPT0gLTEpXG4gICAgICAgICAgICAgICAgd29yay5wdXNoKG5leHQpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkZWFkKVxuICAgICAgICAgICAgc3RyZWFtLmVycihcIk9ubHkgbm9uLWdlbmVyYXRhYmxlIG5vZGVzIChcIiArIG5vZGVzLmpvaW4oXCIsIFwiKSArIFwiKSBpbiBhIHJlcXVpcmVkIHBvc2l0aW9uIChzZWUgaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9ndWlkZS8jZ2VuZXJhdGFibGUpXCIpO1xuICAgIH1cbn1cblxuLy8gRm9yIG5vZGUgdHlwZXMgd2hlcmUgYWxsIGF0dHJzIGhhdmUgYSBkZWZhdWx0IHZhbHVlIChvciB3aGljaCBkb24ndFxuLy8gaGF2ZSBhbnkgYXR0cmlidXRlcyksIGJ1aWxkIHVwIGEgc2luZ2xlIHJldXNhYmxlIGRlZmF1bHQgYXR0cmlidXRlXG4vLyBvYmplY3QsIGFuZCB1c2UgaXQgZm9yIGFsbCBub2RlcyB0aGF0IGRvbid0IHNwZWNpZnkgc3BlY2lmaWNcbi8vIGF0dHJpYnV0ZXMuXG5mdW5jdGlvbiBkZWZhdWx0QXR0cnMoYXR0cnMpIHtcbiAgICBsZXQgZGVmYXVsdHMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIGZvciAobGV0IGF0dHJOYW1lIGluIGF0dHJzKSB7XG4gICAgICAgIGxldCBhdHRyID0gYXR0cnNbYXR0ck5hbWVdO1xuICAgICAgICBpZiAoIWF0dHIuaGFzRGVmYXVsdClcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICBkZWZhdWx0c1thdHRyTmFtZV0gPSBhdHRyLmRlZmF1bHQ7XG4gICAgfVxuICAgIHJldHVybiBkZWZhdWx0cztcbn1cbmZ1bmN0aW9uIGNvbXB1dGVBdHRycyhhdHRycywgdmFsdWUpIHtcbiAgICBsZXQgYnVpbHQgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIGZvciAobGV0IG5hbWUgaW4gYXR0cnMpIHtcbiAgICAgICAgbGV0IGdpdmVuID0gdmFsdWUgJiYgdmFsdWVbbmFtZV07XG4gICAgICAgIGlmIChnaXZlbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBsZXQgYXR0ciA9IGF0dHJzW25hbWVdO1xuICAgICAgICAgICAgaWYgKGF0dHIuaGFzRGVmYXVsdClcbiAgICAgICAgICAgICAgICBnaXZlbiA9IGF0dHIuZGVmYXVsdDtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIk5vIHZhbHVlIHN1cHBsaWVkIGZvciBhdHRyaWJ1dGUgXCIgKyBuYW1lKTtcbiAgICAgICAgfVxuICAgICAgICBidWlsdFtuYW1lXSA9IGdpdmVuO1xuICAgIH1cbiAgICByZXR1cm4gYnVpbHQ7XG59XG5mdW5jdGlvbiBjaGVja0F0dHJzKGF0dHJzLCB2YWx1ZXMsIHR5cGUsIG5hbWUpIHtcbiAgICBmb3IgKGxldCBuYW1lIGluIHZhbHVlcylcbiAgICAgICAgaWYgKCEobmFtZSBpbiBhdHRycykpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgVW5zdXBwb3J0ZWQgYXR0cmlidXRlICR7bmFtZX0gZm9yICR7dHlwZX0gb2YgdHlwZSAke25hbWV9YCk7XG4gICAgZm9yIChsZXQgbmFtZSBpbiBhdHRycykge1xuICAgICAgICBsZXQgYXR0ciA9IGF0dHJzW25hbWVdO1xuICAgICAgICBpZiAoYXR0ci52YWxpZGF0ZSlcbiAgICAgICAgICAgIGF0dHIudmFsaWRhdGUodmFsdWVzW25hbWVdKTtcbiAgICB9XG59XG5mdW5jdGlvbiBpbml0QXR0cnModHlwZU5hbWUsIGF0dHJzKSB7XG4gICAgbGV0IHJlc3VsdCA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgaWYgKGF0dHJzKVxuICAgICAgICBmb3IgKGxldCBuYW1lIGluIGF0dHJzKVxuICAgICAgICAgICAgcmVzdWx0W25hbWVdID0gbmV3IEF0dHJpYnV0ZSh0eXBlTmFtZSwgbmFtZSwgYXR0cnNbbmFtZV0pO1xuICAgIHJldHVybiByZXN1bHQ7XG59XG4vKipcbk5vZGUgdHlwZXMgYXJlIG9iamVjdHMgYWxsb2NhdGVkIG9uY2UgcGVyIGBTY2hlbWFgIGFuZCB1c2VkIHRvXG5bdGFnXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZS50eXBlKSBgTm9kZWAgaW5zdGFuY2VzLiBUaGV5IGNvbnRhaW4gaW5mb3JtYXRpb25cbmFib3V0IHRoZSBub2RlIHR5cGUsIHN1Y2ggYXMgaXRzIG5hbWUgYW5kIHdoYXQga2luZCBvZiBub2RlIGl0XG5yZXByZXNlbnRzLlxuKi9cbmNsYXNzIE5vZGVUeXBlIHtcbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgIFRoZSBuYW1lIHRoZSBub2RlIHR5cGUgaGFzIGluIHRoaXMgc2NoZW1hLlxuICAgICovXG4gICAgbmFtZSwgXG4gICAgLyoqXG4gICAgQSBsaW5rIGJhY2sgdG8gdGhlIGBTY2hlbWFgIHRoZSBub2RlIHR5cGUgYmVsb25ncyB0by5cbiAgICAqL1xuICAgIHNjaGVtYSwgXG4gICAgLyoqXG4gICAgVGhlIHNwZWMgdGhhdCB0aGlzIHR5cGUgaXMgYmFzZWQgb25cbiAgICAqL1xuICAgIHNwZWMpIHtcbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICAgICAgdGhpcy5zY2hlbWEgPSBzY2hlbWE7XG4gICAgICAgIHRoaXMuc3BlYyA9IHNwZWM7XG4gICAgICAgIC8qKlxuICAgICAgICBUaGUgc2V0IG9mIG1hcmtzIGFsbG93ZWQgaW4gdGhpcyBub2RlLiBgbnVsbGAgbWVhbnMgYWxsIG1hcmtzXG4gICAgICAgIGFyZSBhbGxvd2VkLlxuICAgICAgICAqL1xuICAgICAgICB0aGlzLm1hcmtTZXQgPSBudWxsO1xuICAgICAgICB0aGlzLmdyb3VwcyA9IHNwZWMuZ3JvdXAgPyBzcGVjLmdyb3VwLnNwbGl0KFwiIFwiKSA6IFtdO1xuICAgICAgICB0aGlzLmF0dHJzID0gaW5pdEF0dHJzKG5hbWUsIHNwZWMuYXR0cnMpO1xuICAgICAgICB0aGlzLmRlZmF1bHRBdHRycyA9IGRlZmF1bHRBdHRycyh0aGlzLmF0dHJzKTtcbiAgICAgICAgdGhpcy5jb250ZW50TWF0Y2ggPSBudWxsO1xuICAgICAgICB0aGlzLmlubGluZUNvbnRlbnQgPSBudWxsO1xuICAgICAgICB0aGlzLmlzQmxvY2sgPSAhKHNwZWMuaW5saW5lIHx8IG5hbWUgPT0gXCJ0ZXh0XCIpO1xuICAgICAgICB0aGlzLmlzVGV4dCA9IG5hbWUgPT0gXCJ0ZXh0XCI7XG4gICAgfVxuICAgIC8qKlxuICAgIFRydWUgaWYgdGhpcyBpcyBhbiBpbmxpbmUgdHlwZS5cbiAgICAqL1xuICAgIGdldCBpc0lubGluZSgpIHsgcmV0dXJuICF0aGlzLmlzQmxvY2s7IH1cbiAgICAvKipcbiAgICBUcnVlIGlmIHRoaXMgaXMgYSB0ZXh0YmxvY2sgdHlwZSwgYSBibG9jayB0aGF0IGNvbnRhaW5zIGlubGluZVxuICAgIGNvbnRlbnQuXG4gICAgKi9cbiAgICBnZXQgaXNUZXh0YmxvY2soKSB7IHJldHVybiB0aGlzLmlzQmxvY2sgJiYgdGhpcy5pbmxpbmVDb250ZW50OyB9XG4gICAgLyoqXG4gICAgVHJ1ZSBmb3Igbm9kZSB0eXBlcyB0aGF0IGFsbG93IG5vIGNvbnRlbnQuXG4gICAgKi9cbiAgICBnZXQgaXNMZWFmKCkgeyByZXR1cm4gdGhpcy5jb250ZW50TWF0Y2ggPT0gQ29udGVudE1hdGNoLmVtcHR5OyB9XG4gICAgLyoqXG4gICAgVHJ1ZSB3aGVuIHRoaXMgbm9kZSBpcyBhbiBhdG9tLCBpLmUuIHdoZW4gaXQgZG9lcyBub3QgaGF2ZVxuICAgIGRpcmVjdGx5IGVkaXRhYmxlIGNvbnRlbnQuXG4gICAgKi9cbiAgICBnZXQgaXNBdG9tKCkgeyByZXR1cm4gdGhpcy5pc0xlYWYgfHwgISF0aGlzLnNwZWMuYXRvbTsgfVxuICAgIC8qKlxuICAgIFJldHVybiB0cnVlIHdoZW4gdGhpcyBub2RlIHR5cGUgaXMgcGFydCBvZiB0aGUgZ2l2ZW5cbiAgICBbZ3JvdXBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5Ob2RlU3BlYy5ncm91cCkuXG4gICAgKi9cbiAgICBpc0luR3JvdXAoZ3JvdXApIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ3JvdXBzLmluZGV4T2YoZ3JvdXApID4gLTE7XG4gICAgfVxuICAgIC8qKlxuICAgIFRoZSBub2RlIHR5cGUncyBbd2hpdGVzcGFjZV0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGVTcGVjLndoaXRlc3BhY2UpIG9wdGlvbi5cbiAgICAqL1xuICAgIGdldCB3aGl0ZXNwYWNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zcGVjLndoaXRlc3BhY2UgfHwgKHRoaXMuc3BlYy5jb2RlID8gXCJwcmVcIiA6IFwibm9ybWFsXCIpO1xuICAgIH1cbiAgICAvKipcbiAgICBUZWxscyB5b3Ugd2hldGhlciB0aGlzIG5vZGUgdHlwZSBoYXMgYW55IHJlcXVpcmVkIGF0dHJpYnV0ZXMuXG4gICAgKi9cbiAgICBoYXNSZXF1aXJlZEF0dHJzKCkge1xuICAgICAgICBmb3IgKGxldCBuIGluIHRoaXMuYXR0cnMpXG4gICAgICAgICAgICBpZiAodGhpcy5hdHRyc1tuXS5pc1JlcXVpcmVkKVxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIC8qKlxuICAgIEluZGljYXRlcyB3aGV0aGVyIHRoaXMgbm9kZSBhbGxvd3Mgc29tZSBvZiB0aGUgc2FtZSBjb250ZW50IGFzXG4gICAgdGhlIGdpdmVuIG5vZGUgdHlwZS5cbiAgICAqL1xuICAgIGNvbXBhdGlibGVDb250ZW50KG90aGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzID09IG90aGVyIHx8IHRoaXMuY29udGVudE1hdGNoLmNvbXBhdGlibGUob3RoZXIuY29udGVudE1hdGNoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBjb21wdXRlQXR0cnMoYXR0cnMpIHtcbiAgICAgICAgaWYgKCFhdHRycyAmJiB0aGlzLmRlZmF1bHRBdHRycylcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmRlZmF1bHRBdHRycztcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgcmV0dXJuIGNvbXB1dGVBdHRycyh0aGlzLmF0dHJzLCBhdHRycyk7XG4gICAgfVxuICAgIC8qKlxuICAgIENyZWF0ZSBhIGBOb2RlYCBvZiB0aGlzIHR5cGUuIFRoZSBnaXZlbiBhdHRyaWJ1dGVzIGFyZVxuICAgIGNoZWNrZWQgYW5kIGRlZmF1bHRlZCAoeW91IGNhbiBwYXNzIGBudWxsYCB0byB1c2UgdGhlIHR5cGUnc1xuICAgIGRlZmF1bHRzIGVudGlyZWx5LCBpZiBubyByZXF1aXJlZCBhdHRyaWJ1dGVzIGV4aXN0KS4gYGNvbnRlbnRgXG4gICAgbWF5IGJlIGEgYEZyYWdtZW50YCwgYSBub2RlLCBhbiBhcnJheSBvZiBub2Rlcywgb3JcbiAgICBgbnVsbGAuIFNpbWlsYXJseSBgbWFya3NgIG1heSBiZSBgbnVsbGAgdG8gZGVmYXVsdCB0byB0aGUgZW1wdHlcbiAgICBzZXQgb2YgbWFya3MuXG4gICAgKi9cbiAgICBjcmVhdGUoYXR0cnMgPSBudWxsLCBjb250ZW50LCBtYXJrcykge1xuICAgICAgICBpZiAodGhpcy5pc1RleHQpXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJOb2RlVHlwZS5jcmVhdGUgY2FuJ3QgY29uc3RydWN0IHRleHQgbm9kZXNcIik7XG4gICAgICAgIHJldHVybiBuZXcgTm9kZSh0aGlzLCB0aGlzLmNvbXB1dGVBdHRycyhhdHRycyksIEZyYWdtZW50LmZyb20oY29udGVudCksIE1hcmsuc2V0RnJvbShtYXJrcykpO1xuICAgIH1cbiAgICAvKipcbiAgICBMaWtlIFtgY3JlYXRlYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGVUeXBlLmNyZWF0ZSksIGJ1dCBjaGVjayB0aGUgZ2l2ZW4gY29udGVudFxuICAgIGFnYWluc3QgdGhlIG5vZGUgdHlwZSdzIGNvbnRlbnQgcmVzdHJpY3Rpb25zLCBhbmQgdGhyb3cgYW4gZXJyb3JcbiAgICBpZiBpdCBkb2Vzbid0IG1hdGNoLlxuICAgICovXG4gICAgY3JlYXRlQ2hlY2tlZChhdHRycyA9IG51bGwsIGNvbnRlbnQsIG1hcmtzKSB7XG4gICAgICAgIGNvbnRlbnQgPSBGcmFnbWVudC5mcm9tKGNvbnRlbnQpO1xuICAgICAgICB0aGlzLmNoZWNrQ29udGVudChjb250ZW50KTtcbiAgICAgICAgcmV0dXJuIG5ldyBOb2RlKHRoaXMsIHRoaXMuY29tcHV0ZUF0dHJzKGF0dHJzKSwgY29udGVudCwgTWFyay5zZXRGcm9tKG1hcmtzKSk7XG4gICAgfVxuICAgIC8qKlxuICAgIExpa2UgW2BjcmVhdGVgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZVR5cGUuY3JlYXRlKSwgYnV0IHNlZSBpZiBpdCBpc1xuICAgIG5lY2Vzc2FyeSB0byBhZGQgbm9kZXMgdG8gdGhlIHN0YXJ0IG9yIGVuZCBvZiB0aGUgZ2l2ZW4gZnJhZ21lbnRcbiAgICB0byBtYWtlIGl0IGZpdCB0aGUgbm9kZS4gSWYgbm8gZml0dGluZyB3cmFwcGluZyBjYW4gYmUgZm91bmQsXG4gICAgcmV0dXJuIG51bGwuIE5vdGUgdGhhdCwgZHVlIHRvIHRoZSBmYWN0IHRoYXQgcmVxdWlyZWQgbm9kZXMgY2FuXG4gICAgYWx3YXlzIGJlIGNyZWF0ZWQsIHRoaXMgd2lsbCBhbHdheXMgc3VjY2VlZCBpZiB5b3UgcGFzcyBudWxsIG9yXG4gICAgYEZyYWdtZW50LmVtcHR5YCBhcyBjb250ZW50LlxuICAgICovXG4gICAgY3JlYXRlQW5kRmlsbChhdHRycyA9IG51bGwsIGNvbnRlbnQsIG1hcmtzKSB7XG4gICAgICAgIGF0dHJzID0gdGhpcy5jb21wdXRlQXR0cnMoYXR0cnMpO1xuICAgICAgICBjb250ZW50ID0gRnJhZ21lbnQuZnJvbShjb250ZW50KTtcbiAgICAgICAgaWYgKGNvbnRlbnQuc2l6ZSkge1xuICAgICAgICAgICAgbGV0IGJlZm9yZSA9IHRoaXMuY29udGVudE1hdGNoLmZpbGxCZWZvcmUoY29udGVudCk7XG4gICAgICAgICAgICBpZiAoIWJlZm9yZSlcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIGNvbnRlbnQgPSBiZWZvcmUuYXBwZW5kKGNvbnRlbnQpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBtYXRjaGVkID0gdGhpcy5jb250ZW50TWF0Y2gubWF0Y2hGcmFnbWVudChjb250ZW50KTtcbiAgICAgICAgbGV0IGFmdGVyID0gbWF0Y2hlZCAmJiBtYXRjaGVkLmZpbGxCZWZvcmUoRnJhZ21lbnQuZW1wdHksIHRydWUpO1xuICAgICAgICBpZiAoIWFmdGVyKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIHJldHVybiBuZXcgTm9kZSh0aGlzLCBhdHRycywgY29udGVudC5hcHBlbmQoYWZ0ZXIpLCBNYXJrLnNldEZyb20obWFya3MpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBmcmFnbWVudCBpcyB2YWxpZCBjb250ZW50IGZvciB0aGlzIG5vZGVcbiAgICB0eXBlLlxuICAgICovXG4gICAgdmFsaWRDb250ZW50KGNvbnRlbnQpIHtcbiAgICAgICAgbGV0IHJlc3VsdCA9IHRoaXMuY29udGVudE1hdGNoLm1hdGNoRnJhZ21lbnQoY29udGVudCk7XG4gICAgICAgIGlmICghcmVzdWx0IHx8ICFyZXN1bHQudmFsaWRFbmQpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY29udGVudC5jaGlsZENvdW50OyBpKyspXG4gICAgICAgICAgICBpZiAoIXRoaXMuYWxsb3dzTWFya3MoY29udGVudC5jaGlsZChpKS5tYXJrcykpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgVGhyb3dzIGEgUmFuZ2VFcnJvciBpZiB0aGUgZ2l2ZW4gZnJhZ21lbnQgaXMgbm90IHZhbGlkIGNvbnRlbnQgZm9yIHRoaXNcbiAgICBub2RlIHR5cGUuXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBjaGVja0NvbnRlbnQoY29udGVudCkge1xuICAgICAgICBpZiAoIXRoaXMudmFsaWRDb250ZW50KGNvbnRlbnQpKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoYEludmFsaWQgY29udGVudCBmb3Igbm9kZSAke3RoaXMubmFtZX06ICR7Y29udGVudC50b1N0cmluZygpLnNsaWNlKDAsIDUwKX1gKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBjaGVja0F0dHJzKGF0dHJzKSB7XG4gICAgICAgIGNoZWNrQXR0cnModGhpcy5hdHRycywgYXR0cnMsIFwibm9kZVwiLCB0aGlzLm5hbWUpO1xuICAgIH1cbiAgICAvKipcbiAgICBDaGVjayB3aGV0aGVyIHRoZSBnaXZlbiBtYXJrIHR5cGUgaXMgYWxsb3dlZCBpbiB0aGlzIG5vZGUuXG4gICAgKi9cbiAgICBhbGxvd3NNYXJrVHlwZShtYXJrVHlwZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXJrU2V0ID09IG51bGwgfHwgdGhpcy5tYXJrU2V0LmluZGV4T2YobWFya1R5cGUpID4gLTE7XG4gICAgfVxuICAgIC8qKlxuICAgIFRlc3Qgd2hldGhlciB0aGUgZ2l2ZW4gc2V0IG9mIG1hcmtzIGFyZSBhbGxvd2VkIGluIHRoaXMgbm9kZS5cbiAgICAqL1xuICAgIGFsbG93c01hcmtzKG1hcmtzKSB7XG4gICAgICAgIGlmICh0aGlzLm1hcmtTZXQgPT0gbnVsbClcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1hcmtzLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgaWYgKCF0aGlzLmFsbG93c01hcmtUeXBlKG1hcmtzW2ldLnR5cGUpKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIC8qKlxuICAgIFJlbW92ZXMgdGhlIG1hcmtzIHRoYXQgYXJlIG5vdCBhbGxvd2VkIGluIHRoaXMgbm9kZSBmcm9tIHRoZSBnaXZlbiBzZXQuXG4gICAgKi9cbiAgICBhbGxvd2VkTWFya3MobWFya3MpIHtcbiAgICAgICAgaWYgKHRoaXMubWFya1NldCA9PSBudWxsKVxuICAgICAgICAgICAgcmV0dXJuIG1hcmtzO1xuICAgICAgICBsZXQgY29weTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtYXJrcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKCF0aGlzLmFsbG93c01hcmtUeXBlKG1hcmtzW2ldLnR5cGUpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFjb3B5KVxuICAgICAgICAgICAgICAgICAgICBjb3B5ID0gbWFya3Muc2xpY2UoMCwgaSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjb3B5KSB7XG4gICAgICAgICAgICAgICAgY29weS5wdXNoKG1hcmtzW2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gIWNvcHkgPyBtYXJrcyA6IGNvcHkubGVuZ3RoID8gY29weSA6IE1hcmsubm9uZTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBzdGF0aWMgY29tcGlsZShub2Rlcywgc2NoZW1hKSB7XG4gICAgICAgIGxldCByZXN1bHQgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICBub2Rlcy5mb3JFYWNoKChuYW1lLCBzcGVjKSA9PiByZXN1bHRbbmFtZV0gPSBuZXcgTm9kZVR5cGUobmFtZSwgc2NoZW1hLCBzcGVjKSk7XG4gICAgICAgIGxldCB0b3BUeXBlID0gc2NoZW1hLnNwZWMudG9wTm9kZSB8fCBcImRvY1wiO1xuICAgICAgICBpZiAoIXJlc3VsdFt0b3BUeXBlXSlcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiU2NoZW1hIGlzIG1pc3NpbmcgaXRzIHRvcCBub2RlIHR5cGUgKCdcIiArIHRvcFR5cGUgKyBcIicpXCIpO1xuICAgICAgICBpZiAoIXJlc3VsdC50ZXh0KVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJFdmVyeSBzY2hlbWEgbmVlZHMgYSAndGV4dCcgdHlwZVwiKTtcbiAgICAgICAgZm9yIChsZXQgXyBpbiByZXN1bHQudGV4dC5hdHRycylcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiVGhlIHRleHQgbm9kZSB0eXBlIHNob3VsZCBub3QgaGF2ZSBhdHRyaWJ1dGVzXCIpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbn1cbmZ1bmN0aW9uIHZhbGlkYXRlVHlwZSh0eXBlTmFtZSwgYXR0ck5hbWUsIHR5cGUpIHtcbiAgICBsZXQgdHlwZXMgPSB0eXBlLnNwbGl0KFwifFwiKTtcbiAgICByZXR1cm4gKHZhbHVlKSA9PiB7XG4gICAgICAgIGxldCBuYW1lID0gdmFsdWUgPT09IG51bGwgPyBcIm51bGxcIiA6IHR5cGVvZiB2YWx1ZTtcbiAgICAgICAgaWYgKHR5cGVzLmluZGV4T2YobmFtZSkgPCAwKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoYEV4cGVjdGVkIHZhbHVlIG9mIHR5cGUgJHt0eXBlc30gZm9yIGF0dHJpYnV0ZSAke2F0dHJOYW1lfSBvbiB0eXBlICR7dHlwZU5hbWV9LCBnb3QgJHtuYW1lfWApO1xuICAgIH07XG59XG4vLyBBdHRyaWJ1dGUgZGVzY3JpcHRvcnNcbmNsYXNzIEF0dHJpYnV0ZSB7XG4gICAgY29uc3RydWN0b3IodHlwZU5hbWUsIGF0dHJOYW1lLCBvcHRpb25zKSB7XG4gICAgICAgIHRoaXMuaGFzRGVmYXVsdCA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvcHRpb25zLCBcImRlZmF1bHRcIik7XG4gICAgICAgIHRoaXMuZGVmYXVsdCA9IG9wdGlvbnMuZGVmYXVsdDtcbiAgICAgICAgdGhpcy52YWxpZGF0ZSA9IHR5cGVvZiBvcHRpb25zLnZhbGlkYXRlID09IFwic3RyaW5nXCIgPyB2YWxpZGF0ZVR5cGUodHlwZU5hbWUsIGF0dHJOYW1lLCBvcHRpb25zLnZhbGlkYXRlKSA6IG9wdGlvbnMudmFsaWRhdGU7XG4gICAgfVxuICAgIGdldCBpc1JlcXVpcmVkKCkge1xuICAgICAgICByZXR1cm4gIXRoaXMuaGFzRGVmYXVsdDtcbiAgICB9XG59XG4vLyBNYXJrc1xuLyoqXG5MaWtlIG5vZGVzLCBtYXJrcyAod2hpY2ggYXJlIGFzc29jaWF0ZWQgd2l0aCBub2RlcyB0byBzaWduaWZ5XG50aGluZ3MgbGlrZSBlbXBoYXNpcyBvciBiZWluZyBwYXJ0IG9mIGEgbGluaykgYXJlXG5bdGFnZ2VkXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTWFyay50eXBlKSB3aXRoIHR5cGUgb2JqZWN0cywgd2hpY2ggYXJlXG5pbnN0YW50aWF0ZWQgb25jZSBwZXIgYFNjaGVtYWAuXG4qL1xuY2xhc3MgTWFya1R5cGUge1xuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgVGhlIG5hbWUgb2YgdGhlIG1hcmsgdHlwZS5cbiAgICAqL1xuICAgIG5hbWUsIFxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgcmFuaywgXG4gICAgLyoqXG4gICAgVGhlIHNjaGVtYSB0aGF0IHRoaXMgbWFyayB0eXBlIGluc3RhbmNlIGlzIHBhcnQgb2YuXG4gICAgKi9cbiAgICBzY2hlbWEsIFxuICAgIC8qKlxuICAgIFRoZSBzcGVjIG9uIHdoaWNoIHRoZSB0eXBlIGlzIGJhc2VkLlxuICAgICovXG4gICAgc3BlYykge1xuICAgICAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgICAgICB0aGlzLnJhbmsgPSByYW5rO1xuICAgICAgICB0aGlzLnNjaGVtYSA9IHNjaGVtYTtcbiAgICAgICAgdGhpcy5zcGVjID0gc3BlYztcbiAgICAgICAgdGhpcy5hdHRycyA9IGluaXRBdHRycyhuYW1lLCBzcGVjLmF0dHJzKTtcbiAgICAgICAgdGhpcy5leGNsdWRlZCA9IG51bGw7XG4gICAgICAgIGxldCBkZWZhdWx0cyA9IGRlZmF1bHRBdHRycyh0aGlzLmF0dHJzKTtcbiAgICAgICAgdGhpcy5pbnN0YW5jZSA9IGRlZmF1bHRzID8gbmV3IE1hcmsodGhpcywgZGVmYXVsdHMpIDogbnVsbDtcbiAgICB9XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgbWFyayBvZiB0aGlzIHR5cGUuIGBhdHRyc2AgbWF5IGJlIGBudWxsYCBvciBhbiBvYmplY3RcbiAgICBjb250YWluaW5nIG9ubHkgc29tZSBvZiB0aGUgbWFyaydzIGF0dHJpYnV0ZXMuIFRoZSBvdGhlcnMsIGlmXG4gICAgdGhleSBoYXZlIGRlZmF1bHRzLCB3aWxsIGJlIGFkZGVkLlxuICAgICovXG4gICAgY3JlYXRlKGF0dHJzID0gbnVsbCkge1xuICAgICAgICBpZiAoIWF0dHJzICYmIHRoaXMuaW5zdGFuY2UpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5pbnN0YW5jZTtcbiAgICAgICAgcmV0dXJuIG5ldyBNYXJrKHRoaXMsIGNvbXB1dGVBdHRycyh0aGlzLmF0dHJzLCBhdHRycykpO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHN0YXRpYyBjb21waWxlKG1hcmtzLCBzY2hlbWEpIHtcbiAgICAgICAgbGV0IHJlc3VsdCA9IE9iamVjdC5jcmVhdGUobnVsbCksIHJhbmsgPSAwO1xuICAgICAgICBtYXJrcy5mb3JFYWNoKChuYW1lLCBzcGVjKSA9PiByZXN1bHRbbmFtZV0gPSBuZXcgTWFya1R5cGUobmFtZSwgcmFuaysrLCBzY2hlbWEsIHNwZWMpKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgLyoqXG4gICAgV2hlbiB0aGVyZSBpcyBhIG1hcmsgb2YgdGhpcyB0eXBlIGluIHRoZSBnaXZlbiBzZXQsIGEgbmV3IHNldFxuICAgIHdpdGhvdXQgaXQgaXMgcmV0dXJuZWQuIE90aGVyd2lzZSwgdGhlIGlucHV0IHNldCBpcyByZXR1cm5lZC5cbiAgICAqL1xuICAgIHJlbW92ZUZyb21TZXQoc2V0KSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2V0Lmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgaWYgKHNldFtpXS50eXBlID09IHRoaXMpIHtcbiAgICAgICAgICAgICAgICBzZXQgPSBzZXQuc2xpY2UoMCwgaSkuY29uY2F0KHNldC5zbGljZShpICsgMSkpO1xuICAgICAgICAgICAgICAgIGktLTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNldDtcbiAgICB9XG4gICAgLyoqXG4gICAgVGVzdHMgd2hldGhlciB0aGVyZSBpcyBhIG1hcmsgb2YgdGhpcyB0eXBlIGluIHRoZSBnaXZlbiBzZXQuXG4gICAgKi9cbiAgICBpc0luU2V0KHNldCkge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNldC5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIGlmIChzZXRbaV0udHlwZSA9PSB0aGlzKVxuICAgICAgICAgICAgICAgIHJldHVybiBzZXRbaV07XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgY2hlY2tBdHRycyhhdHRycykge1xuICAgICAgICBjaGVja0F0dHJzKHRoaXMuYXR0cnMsIGF0dHJzLCBcIm1hcmtcIiwgdGhpcy5uYW1lKTtcbiAgICB9XG4gICAgLyoqXG4gICAgUXVlcmllcyB3aGV0aGVyIGEgZ2l2ZW4gbWFyayB0eXBlIGlzXG4gICAgW2V4Y2x1ZGVkXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTWFya1NwZWMuZXhjbHVkZXMpIGJ5IHRoaXMgb25lLlxuICAgICovXG4gICAgZXhjbHVkZXMob3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZXhjbHVkZWQuaW5kZXhPZihvdGhlcikgPiAtMTtcbiAgICB9XG59XG4vKipcbkEgZG9jdW1lbnQgc2NoZW1hLiBIb2xkcyBbbm9kZV0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGVUeXBlKSBhbmQgW21hcmtcbnR5cGVdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5NYXJrVHlwZSkgb2JqZWN0cyBmb3IgdGhlIG5vZGVzIGFuZCBtYXJrcyB0aGF0IG1heVxub2NjdXIgaW4gY29uZm9ybWluZyBkb2N1bWVudHMsIGFuZCBwcm92aWRlcyBmdW5jdGlvbmFsaXR5IGZvclxuY3JlYXRpbmcgYW5kIGRlc2VyaWFsaXppbmcgc3VjaCBkb2N1bWVudHMuXG5cbldoZW4gZ2l2ZW4sIHRoZSB0eXBlIHBhcmFtZXRlcnMgcHJvdmlkZSB0aGUgbmFtZXMgb2YgdGhlIG5vZGVzIGFuZFxubWFya3MgaW4gdGhpcyBzY2hlbWEuXG4qL1xuY2xhc3MgU2NoZW1hIHtcbiAgICAvKipcbiAgICBDb25zdHJ1Y3QgYSBzY2hlbWEgZnJvbSBhIHNjaGVtYSBbc3BlY2lmaWNhdGlvbl0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLlNjaGVtYVNwZWMpLlxuICAgICovXG4gICAgY29uc3RydWN0b3Ioc3BlYykge1xuICAgICAgICAvKipcbiAgICAgICAgVGhlIFtsaW5lYnJlYWtcbiAgICAgICAgcmVwbGFjZW1lbnRdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5Ob2RlU3BlYy5saW5lYnJlYWtSZXBsYWNlbWVudCkgbm9kZSBkZWZpbmVkXG4gICAgICAgIGluIHRoaXMgc2NoZW1hLCBpZiBhbnkuXG4gICAgICAgICovXG4gICAgICAgIHRoaXMubGluZWJyZWFrUmVwbGFjZW1lbnQgPSBudWxsO1xuICAgICAgICAvKipcbiAgICAgICAgQW4gb2JqZWN0IGZvciBzdG9yaW5nIHdoYXRldmVyIHZhbHVlcyBtb2R1bGVzIG1heSB3YW50IHRvXG4gICAgICAgIGNvbXB1dGUgYW5kIGNhY2hlIHBlciBzY2hlbWEuIChJZiB5b3Ugd2FudCB0byBzdG9yZSBzb21ldGhpbmdcbiAgICAgICAgaW4gaXQsIHRyeSB0byB1c2UgcHJvcGVydHkgbmFtZXMgdW5saWtlbHkgdG8gY2xhc2guKVxuICAgICAgICAqL1xuICAgICAgICB0aGlzLmNhY2hlZCA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgICAgIGxldCBpbnN0YW5jZVNwZWMgPSB0aGlzLnNwZWMgPSB7fTtcbiAgICAgICAgZm9yIChsZXQgcHJvcCBpbiBzcGVjKVxuICAgICAgICAgICAgaW5zdGFuY2VTcGVjW3Byb3BdID0gc3BlY1twcm9wXTtcbiAgICAgICAgaW5zdGFuY2VTcGVjLm5vZGVzID0gT3JkZXJlZE1hcC5mcm9tKHNwZWMubm9kZXMpLFxuICAgICAgICAgICAgaW5zdGFuY2VTcGVjLm1hcmtzID0gT3JkZXJlZE1hcC5mcm9tKHNwZWMubWFya3MgfHwge30pLFxuICAgICAgICAgICAgdGhpcy5ub2RlcyA9IE5vZGVUeXBlLmNvbXBpbGUodGhpcy5zcGVjLm5vZGVzLCB0aGlzKTtcbiAgICAgICAgdGhpcy5tYXJrcyA9IE1hcmtUeXBlLmNvbXBpbGUodGhpcy5zcGVjLm1hcmtzLCB0aGlzKTtcbiAgICAgICAgbGV0IGNvbnRlbnRFeHByQ2FjaGUgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICBmb3IgKGxldCBwcm9wIGluIHRoaXMubm9kZXMpIHtcbiAgICAgICAgICAgIGlmIChwcm9wIGluIHRoaXMubWFya3MpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IocHJvcCArIFwiIGNhbiBub3QgYmUgYm90aCBhIG5vZGUgYW5kIGEgbWFya1wiKTtcbiAgICAgICAgICAgIGxldCB0eXBlID0gdGhpcy5ub2Rlc1twcm9wXSwgY29udGVudEV4cHIgPSB0eXBlLnNwZWMuY29udGVudCB8fCBcIlwiLCBtYXJrRXhwciA9IHR5cGUuc3BlYy5tYXJrcztcbiAgICAgICAgICAgIHR5cGUuY29udGVudE1hdGNoID0gY29udGVudEV4cHJDYWNoZVtjb250ZW50RXhwcl0gfHxcbiAgICAgICAgICAgICAgICAoY29udGVudEV4cHJDYWNoZVtjb250ZW50RXhwcl0gPSBDb250ZW50TWF0Y2gucGFyc2UoY29udGVudEV4cHIsIHRoaXMubm9kZXMpKTtcbiAgICAgICAgICAgIHR5cGUuaW5saW5lQ29udGVudCA9IHR5cGUuY29udGVudE1hdGNoLmlubGluZUNvbnRlbnQ7XG4gICAgICAgICAgICBpZiAodHlwZS5zcGVjLmxpbmVicmVha1JlcGxhY2VtZW50KSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMubGluZWJyZWFrUmVwbGFjZW1lbnQpXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiTXVsdGlwbGUgbGluZWJyZWFrIG5vZGVzIGRlZmluZWRcIik7XG4gICAgICAgICAgICAgICAgaWYgKCF0eXBlLmlzSW5saW5lIHx8ICF0eXBlLmlzTGVhZilcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJMaW5lYnJlYWsgcmVwbGFjZW1lbnQgbm9kZXMgbXVzdCBiZSBpbmxpbmUgbGVhZiBub2Rlc1wiKTtcbiAgICAgICAgICAgICAgICB0aGlzLmxpbmVicmVha1JlcGxhY2VtZW50ID0gdHlwZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHR5cGUubWFya1NldCA9IG1hcmtFeHByID09IFwiX1wiID8gbnVsbCA6XG4gICAgICAgICAgICAgICAgbWFya0V4cHIgPyBnYXRoZXJNYXJrcyh0aGlzLCBtYXJrRXhwci5zcGxpdChcIiBcIikpIDpcbiAgICAgICAgICAgICAgICAgICAgbWFya0V4cHIgPT0gXCJcIiB8fCAhdHlwZS5pbmxpbmVDb250ZW50ID8gW10gOiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IHByb3AgaW4gdGhpcy5tYXJrcykge1xuICAgICAgICAgICAgbGV0IHR5cGUgPSB0aGlzLm1hcmtzW3Byb3BdLCBleGNsID0gdHlwZS5zcGVjLmV4Y2x1ZGVzO1xuICAgICAgICAgICAgdHlwZS5leGNsdWRlZCA9IGV4Y2wgPT0gbnVsbCA/IFt0eXBlXSA6IGV4Y2wgPT0gXCJcIiA/IFtdIDogZ2F0aGVyTWFya3ModGhpcywgZXhjbC5zcGxpdChcIiBcIikpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubm9kZUZyb21KU09OID0gdGhpcy5ub2RlRnJvbUpTT04uYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5tYXJrRnJvbUpTT04gPSB0aGlzLm1hcmtGcm9tSlNPTi5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLnRvcE5vZGVUeXBlID0gdGhpcy5ub2Rlc1t0aGlzLnNwZWMudG9wTm9kZSB8fCBcImRvY1wiXTtcbiAgICAgICAgdGhpcy5jYWNoZWQud3JhcHBpbmdzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgbm9kZSBpbiB0aGlzIHNjaGVtYS4gVGhlIGB0eXBlYCBtYXkgYmUgYSBzdHJpbmcgb3IgYVxuICAgIGBOb2RlVHlwZWAgaW5zdGFuY2UuIEF0dHJpYnV0ZXMgd2lsbCBiZSBleHRlbmRlZCB3aXRoIGRlZmF1bHRzLFxuICAgIGBjb250ZW50YCBtYXkgYmUgYSBgRnJhZ21lbnRgLCBgbnVsbGAsIGEgYE5vZGVgLCBvciBhbiBhcnJheSBvZlxuICAgIG5vZGVzLlxuICAgICovXG4gICAgbm9kZSh0eXBlLCBhdHRycyA9IG51bGwsIGNvbnRlbnQsIG1hcmtzKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdHlwZSA9PSBcInN0cmluZ1wiKVxuICAgICAgICAgICAgdHlwZSA9IHRoaXMubm9kZVR5cGUodHlwZSk7XG4gICAgICAgIGVsc2UgaWYgKCEodHlwZSBpbnN0YW5jZW9mIE5vZGVUeXBlKSlcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiSW52YWxpZCBub2RlIHR5cGU6IFwiICsgdHlwZSk7XG4gICAgICAgIGVsc2UgaWYgKHR5cGUuc2NoZW1hICE9IHRoaXMpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIk5vZGUgdHlwZSBmcm9tIGRpZmZlcmVudCBzY2hlbWEgdXNlZCAoXCIgKyB0eXBlLm5hbWUgKyBcIilcIik7XG4gICAgICAgIHJldHVybiB0eXBlLmNyZWF0ZUNoZWNrZWQoYXR0cnMsIGNvbnRlbnQsIG1hcmtzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgdGV4dCBub2RlIGluIHRoZSBzY2hlbWEuIEVtcHR5IHRleHQgbm9kZXMgYXJlIG5vdFxuICAgIGFsbG93ZWQuXG4gICAgKi9cbiAgICB0ZXh0KHRleHQsIG1hcmtzKSB7XG4gICAgICAgIGxldCB0eXBlID0gdGhpcy5ub2Rlcy50ZXh0O1xuICAgICAgICByZXR1cm4gbmV3IFRleHROb2RlKHR5cGUsIHR5cGUuZGVmYXVsdEF0dHJzLCB0ZXh0LCBNYXJrLnNldEZyb20obWFya3MpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgbWFyayB3aXRoIHRoZSBnaXZlbiB0eXBlIGFuZCBhdHRyaWJ1dGVzLlxuICAgICovXG4gICAgbWFyayh0eXBlLCBhdHRycykge1xuICAgICAgICBpZiAodHlwZW9mIHR5cGUgPT0gXCJzdHJpbmdcIilcbiAgICAgICAgICAgIHR5cGUgPSB0aGlzLm1hcmtzW3R5cGVdO1xuICAgICAgICByZXR1cm4gdHlwZS5jcmVhdGUoYXR0cnMpO1xuICAgIH1cbiAgICAvKipcbiAgICBEZXNlcmlhbGl6ZSBhIG5vZGUgZnJvbSBpdHMgSlNPTiByZXByZXNlbnRhdGlvbi4gVGhpcyBtZXRob2QgaXNcbiAgICBib3VuZC5cbiAgICAqL1xuICAgIG5vZGVGcm9tSlNPTihqc29uKSB7XG4gICAgICAgIHJldHVybiBOb2RlLmZyb21KU09OKHRoaXMsIGpzb24pO1xuICAgIH1cbiAgICAvKipcbiAgICBEZXNlcmlhbGl6ZSBhIG1hcmsgZnJvbSBpdHMgSlNPTiByZXByZXNlbnRhdGlvbi4gVGhpcyBtZXRob2QgaXNcbiAgICBib3VuZC5cbiAgICAqL1xuICAgIG1hcmtGcm9tSlNPTihqc29uKSB7XG4gICAgICAgIHJldHVybiBNYXJrLmZyb21KU09OKHRoaXMsIGpzb24pO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIG5vZGVUeXBlKG5hbWUpIHtcbiAgICAgICAgbGV0IGZvdW5kID0gdGhpcy5ub2Rlc1tuYW1lXTtcbiAgICAgICAgaWYgKCFmb3VuZClcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiVW5rbm93biBub2RlIHR5cGU6IFwiICsgbmFtZSk7XG4gICAgICAgIHJldHVybiBmb3VuZDtcbiAgICB9XG59XG5mdW5jdGlvbiBnYXRoZXJNYXJrcyhzY2hlbWEsIG1hcmtzKSB7XG4gICAgbGV0IGZvdW5kID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtYXJrcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBsZXQgbmFtZSA9IG1hcmtzW2ldLCBtYXJrID0gc2NoZW1hLm1hcmtzW25hbWVdLCBvayA9IG1hcms7XG4gICAgICAgIGlmIChtYXJrKSB7XG4gICAgICAgICAgICBmb3VuZC5wdXNoKG1hcmspO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZm9yIChsZXQgcHJvcCBpbiBzY2hlbWEubWFya3MpIHtcbiAgICAgICAgICAgICAgICBsZXQgbWFyayA9IHNjaGVtYS5tYXJrc1twcm9wXTtcbiAgICAgICAgICAgICAgICBpZiAobmFtZSA9PSBcIl9cIiB8fCAobWFyay5zcGVjLmdyb3VwICYmIG1hcmsuc3BlYy5ncm91cC5zcGxpdChcIiBcIikuaW5kZXhPZihuYW1lKSA+IC0xKSlcbiAgICAgICAgICAgICAgICAgICAgZm91bmQucHVzaChvayA9IG1hcmspO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICghb2spXG4gICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJVbmtub3duIG1hcmsgdHlwZTogJ1wiICsgbWFya3NbaV0gKyBcIidcIik7XG4gICAgfVxuICAgIHJldHVybiBmb3VuZDtcbn1cblxuZnVuY3Rpb24gaXNUYWdSdWxlKHJ1bGUpIHsgcmV0dXJuIHJ1bGUudGFnICE9IG51bGw7IH1cbmZ1bmN0aW9uIGlzU3R5bGVSdWxlKHJ1bGUpIHsgcmV0dXJuIHJ1bGUuc3R5bGUgIT0gbnVsbDsgfVxuLyoqXG5BIERPTSBwYXJzZXIgcmVwcmVzZW50cyBhIHN0cmF0ZWd5IGZvciBwYXJzaW5nIERPTSBjb250ZW50IGludG8gYVxuUHJvc2VNaXJyb3IgZG9jdW1lbnQgY29uZm9ybWluZyB0byBhIGdpdmVuIHNjaGVtYS4gSXRzIGJlaGF2aW9yIGlzXG5kZWZpbmVkIGJ5IGFuIGFycmF5IG9mIFtydWxlc10oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLlBhcnNlUnVsZSkuXG4qL1xuY2xhc3MgRE9NUGFyc2VyIHtcbiAgICAvKipcbiAgICBDcmVhdGUgYSBwYXJzZXIgdGhhdCB0YXJnZXRzIHRoZSBnaXZlbiBzY2hlbWEsIHVzaW5nIHRoZSBnaXZlblxuICAgIHBhcnNpbmcgcnVsZXMuXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBUaGUgc2NoZW1hIGludG8gd2hpY2ggdGhlIHBhcnNlciBwYXJzZXMuXG4gICAgKi9cbiAgICBzY2hlbWEsIFxuICAgIC8qKlxuICAgIFRoZSBzZXQgb2YgW3BhcnNlIHJ1bGVzXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuUGFyc2VSdWxlKSB0aGF0IHRoZSBwYXJzZXJcbiAgICB1c2VzLCBpbiBvcmRlciBvZiBwcmVjZWRlbmNlLlxuICAgICovXG4gICAgcnVsZXMpIHtcbiAgICAgICAgdGhpcy5zY2hlbWEgPSBzY2hlbWE7XG4gICAgICAgIHRoaXMucnVsZXMgPSBydWxlcztcbiAgICAgICAgLyoqXG4gICAgICAgIEBpbnRlcm5hbFxuICAgICAgICAqL1xuICAgICAgICB0aGlzLnRhZ3MgPSBbXTtcbiAgICAgICAgLyoqXG4gICAgICAgIEBpbnRlcm5hbFxuICAgICAgICAqL1xuICAgICAgICB0aGlzLnN0eWxlcyA9IFtdO1xuICAgICAgICBsZXQgbWF0Y2hlZFN0eWxlcyA9IHRoaXMubWF0Y2hlZFN0eWxlcyA9IFtdO1xuICAgICAgICBydWxlcy5mb3JFYWNoKHJ1bGUgPT4ge1xuICAgICAgICAgICAgaWYgKGlzVGFnUnVsZShydWxlKSkge1xuICAgICAgICAgICAgICAgIHRoaXMudGFncy5wdXNoKHJ1bGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoaXNTdHlsZVJ1bGUocnVsZSkpIHtcbiAgICAgICAgICAgICAgICBsZXQgcHJvcCA9IC9bXj1dKi8uZXhlYyhydWxlLnN0eWxlKVswXTtcbiAgICAgICAgICAgICAgICBpZiAobWF0Y2hlZFN0eWxlcy5pbmRleE9mKHByb3ApIDwgMClcbiAgICAgICAgICAgICAgICAgICAgbWF0Y2hlZFN0eWxlcy5wdXNoKHByb3ApO1xuICAgICAgICAgICAgICAgIHRoaXMuc3R5bGVzLnB1c2gocnVsZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBPbmx5IG5vcm1hbGl6ZSBsaXN0IGVsZW1lbnRzIHdoZW4gbGlzdHMgaW4gdGhlIHNjaGVtYSBjYW4ndCBkaXJlY3RseSBjb250YWluIHRoZW1zZWx2ZXNcbiAgICAgICAgdGhpcy5ub3JtYWxpemVMaXN0cyA9ICF0aGlzLnRhZ3Muc29tZShyID0+IHtcbiAgICAgICAgICAgIGlmICghL14odWx8b2wpXFxiLy50ZXN0KHIudGFnKSB8fCAhci5ub2RlKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIGxldCBub2RlID0gc2NoZW1hLm5vZGVzW3Iubm9kZV07XG4gICAgICAgICAgICByZXR1cm4gbm9kZS5jb250ZW50TWF0Y2gubWF0Y2hUeXBlKG5vZGUpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgLyoqXG4gICAgUGFyc2UgYSBkb2N1bWVudCBmcm9tIHRoZSBjb250ZW50IG9mIGEgRE9NIG5vZGUuXG4gICAgKi9cbiAgICBwYXJzZShkb20sIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICBsZXQgY29udGV4dCA9IG5ldyBQYXJzZUNvbnRleHQodGhpcywgb3B0aW9ucywgZmFsc2UpO1xuICAgICAgICBjb250ZXh0LmFkZEFsbChkb20sIE1hcmsubm9uZSwgb3B0aW9ucy5mcm9tLCBvcHRpb25zLnRvKTtcbiAgICAgICAgcmV0dXJuIGNvbnRleHQuZmluaXNoKCk7XG4gICAgfVxuICAgIC8qKlxuICAgIFBhcnNlcyB0aGUgY29udGVudCBvZiB0aGUgZ2l2ZW4gRE9NIG5vZGUsIGxpa2VcbiAgICBbYHBhcnNlYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLkRPTVBhcnNlci5wYXJzZSksIGFuZCB0YWtlcyB0aGUgc2FtZSBzZXQgb2ZcbiAgICBvcHRpb25zLiBCdXQgdW5saWtlIHRoYXQgbWV0aG9kLCB3aGljaCBwcm9kdWNlcyBhIHdob2xlIG5vZGUsXG4gICAgdGhpcyBvbmUgcmV0dXJucyBhIHNsaWNlIHRoYXQgaXMgb3BlbiBhdCB0aGUgc2lkZXMsIG1lYW5pbmcgdGhhdFxuICAgIHRoZSBzY2hlbWEgY29uc3RyYWludHMgYXJlbid0IGFwcGxpZWQgdG8gdGhlIHN0YXJ0IG9mIG5vZGVzIHRvXG4gICAgdGhlIGxlZnQgb2YgdGhlIGlucHV0IGFuZCB0aGUgZW5kIG9mIG5vZGVzIGF0IHRoZSBlbmQuXG4gICAgKi9cbiAgICBwYXJzZVNsaWNlKGRvbSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIGxldCBjb250ZXh0ID0gbmV3IFBhcnNlQ29udGV4dCh0aGlzLCBvcHRpb25zLCB0cnVlKTtcbiAgICAgICAgY29udGV4dC5hZGRBbGwoZG9tLCBNYXJrLm5vbmUsIG9wdGlvbnMuZnJvbSwgb3B0aW9ucy50byk7XG4gICAgICAgIHJldHVybiBTbGljZS5tYXhPcGVuKGNvbnRleHQuZmluaXNoKCkpO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIG1hdGNoVGFnKGRvbSwgY29udGV4dCwgYWZ0ZXIpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IGFmdGVyID8gdGhpcy50YWdzLmluZGV4T2YoYWZ0ZXIpICsgMSA6IDA7IGkgPCB0aGlzLnRhZ3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBydWxlID0gdGhpcy50YWdzW2ldO1xuICAgICAgICAgICAgaWYgKG1hdGNoZXMoZG9tLCBydWxlLnRhZykgJiZcbiAgICAgICAgICAgICAgICAocnVsZS5uYW1lc3BhY2UgPT09IHVuZGVmaW5lZCB8fCBkb20ubmFtZXNwYWNlVVJJID09IHJ1bGUubmFtZXNwYWNlKSAmJlxuICAgICAgICAgICAgICAgICghcnVsZS5jb250ZXh0IHx8IGNvbnRleHQubWF0Y2hlc0NvbnRleHQocnVsZS5jb250ZXh0KSkpIHtcbiAgICAgICAgICAgICAgICBpZiAocnVsZS5nZXRBdHRycykge1xuICAgICAgICAgICAgICAgICAgICBsZXQgcmVzdWx0ID0gcnVsZS5nZXRBdHRycyhkb20pO1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0ID09PSBmYWxzZSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgICAgICBydWxlLmF0dHJzID0gcmVzdWx0IHx8IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJ1bGU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBtYXRjaFN0eWxlKHByb3AsIHZhbHVlLCBjb250ZXh0LCBhZnRlcikge1xuICAgICAgICBmb3IgKGxldCBpID0gYWZ0ZXIgPyB0aGlzLnN0eWxlcy5pbmRleE9mKGFmdGVyKSArIDEgOiAwOyBpIDwgdGhpcy5zdHlsZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBydWxlID0gdGhpcy5zdHlsZXNbaV0sIHN0eWxlID0gcnVsZS5zdHlsZTtcbiAgICAgICAgICAgIGlmIChzdHlsZS5pbmRleE9mKHByb3ApICE9IDAgfHxcbiAgICAgICAgICAgICAgICBydWxlLmNvbnRleHQgJiYgIWNvbnRleHQubWF0Y2hlc0NvbnRleHQocnVsZS5jb250ZXh0KSB8fFxuICAgICAgICAgICAgICAgIC8vIFRlc3QgdGhhdCB0aGUgc3R5bGUgc3RyaW5nIGVpdGhlciBwcmVjaXNlbHkgbWF0Y2hlcyB0aGUgcHJvcCxcbiAgICAgICAgICAgICAgICAvLyBvciBoYXMgYW4gJz0nIHNpZ24gYWZ0ZXIgdGhlIHByb3AsIGZvbGxvd2VkIGJ5IHRoZSBnaXZlblxuICAgICAgICAgICAgICAgIC8vIHZhbHVlLlxuICAgICAgICAgICAgICAgIHN0eWxlLmxlbmd0aCA+IHByb3AubGVuZ3RoICYmXG4gICAgICAgICAgICAgICAgICAgIChzdHlsZS5jaGFyQ29kZUF0KHByb3AubGVuZ3RoKSAhPSA2MSB8fCBzdHlsZS5zbGljZShwcm9wLmxlbmd0aCArIDEpICE9IHZhbHVlKSlcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIGlmIChydWxlLmdldEF0dHJzKSB7XG4gICAgICAgICAgICAgICAgbGV0IHJlc3VsdCA9IHJ1bGUuZ2V0QXR0cnModmFsdWUpO1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IGZhbHNlKVxuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICBydWxlLmF0dHJzID0gcmVzdWx0IHx8IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBydWxlO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgc3RhdGljIHNjaGVtYVJ1bGVzKHNjaGVtYSkge1xuICAgICAgICBsZXQgcmVzdWx0ID0gW107XG4gICAgICAgIGZ1bmN0aW9uIGluc2VydChydWxlKSB7XG4gICAgICAgICAgICBsZXQgcHJpb3JpdHkgPSBydWxlLnByaW9yaXR5ID09IG51bGwgPyA1MCA6IHJ1bGUucHJpb3JpdHksIGkgPSAwO1xuICAgICAgICAgICAgZm9yICg7IGkgPCByZXN1bHQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBsZXQgbmV4dCA9IHJlc3VsdFtpXSwgbmV4dFByaW9yaXR5ID0gbmV4dC5wcmlvcml0eSA9PSBudWxsID8gNTAgOiBuZXh0LnByaW9yaXR5O1xuICAgICAgICAgICAgICAgIGlmIChuZXh0UHJpb3JpdHkgPCBwcmlvcml0eSlcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXN1bHQuc3BsaWNlKGksIDAsIHJ1bGUpO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IG5hbWUgaW4gc2NoZW1hLm1hcmtzKSB7XG4gICAgICAgICAgICBsZXQgcnVsZXMgPSBzY2hlbWEubWFya3NbbmFtZV0uc3BlYy5wYXJzZURPTTtcbiAgICAgICAgICAgIGlmIChydWxlcylcbiAgICAgICAgICAgICAgICBydWxlcy5mb3JFYWNoKHJ1bGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpbnNlcnQocnVsZSA9IGNvcHkocnVsZSkpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIShydWxlLm1hcmsgfHwgcnVsZS5pZ25vcmUgfHwgcnVsZS5jbGVhck1hcmspKVxuICAgICAgICAgICAgICAgICAgICAgICAgcnVsZS5tYXJrID0gbmFtZTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBuYW1lIGluIHNjaGVtYS5ub2Rlcykge1xuICAgICAgICAgICAgbGV0IHJ1bGVzID0gc2NoZW1hLm5vZGVzW25hbWVdLnNwZWMucGFyc2VET007XG4gICAgICAgICAgICBpZiAocnVsZXMpXG4gICAgICAgICAgICAgICAgcnVsZXMuZm9yRWFjaChydWxlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaW5zZXJ0KHJ1bGUgPSBjb3B5KHJ1bGUpKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEocnVsZS5ub2RlIHx8IHJ1bGUuaWdub3JlIHx8IHJ1bGUubWFyaykpXG4gICAgICAgICAgICAgICAgICAgICAgICBydWxlLm5vZGUgPSBuYW1lO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICAgIC8qKlxuICAgIENvbnN0cnVjdCBhIERPTSBwYXJzZXIgdXNpbmcgdGhlIHBhcnNpbmcgcnVsZXMgbGlzdGVkIGluIGFcbiAgICBzY2hlbWEncyBbbm9kZSBzcGVjc10oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGVTcGVjLnBhcnNlRE9NKSwgcmVvcmRlcmVkIGJ5XG4gICAgW3ByaW9yaXR5XShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuUGFyc2VSdWxlLnByaW9yaXR5KS5cbiAgICAqL1xuICAgIHN0YXRpYyBmcm9tU2NoZW1hKHNjaGVtYSkge1xuICAgICAgICByZXR1cm4gc2NoZW1hLmNhY2hlZC5kb21QYXJzZXIgfHxcbiAgICAgICAgICAgIChzY2hlbWEuY2FjaGVkLmRvbVBhcnNlciA9IG5ldyBET01QYXJzZXIoc2NoZW1hLCBET01QYXJzZXIuc2NoZW1hUnVsZXMoc2NoZW1hKSkpO1xuICAgIH1cbn1cbmNvbnN0IGJsb2NrVGFncyA9IHtcbiAgICBhZGRyZXNzOiB0cnVlLCBhcnRpY2xlOiB0cnVlLCBhc2lkZTogdHJ1ZSwgYmxvY2txdW90ZTogdHJ1ZSwgY2FudmFzOiB0cnVlLFxuICAgIGRkOiB0cnVlLCBkaXY6IHRydWUsIGRsOiB0cnVlLCBmaWVsZHNldDogdHJ1ZSwgZmlnY2FwdGlvbjogdHJ1ZSwgZmlndXJlOiB0cnVlLFxuICAgIGZvb3RlcjogdHJ1ZSwgZm9ybTogdHJ1ZSwgaDE6IHRydWUsIGgyOiB0cnVlLCBoMzogdHJ1ZSwgaDQ6IHRydWUsIGg1OiB0cnVlLFxuICAgIGg2OiB0cnVlLCBoZWFkZXI6IHRydWUsIGhncm91cDogdHJ1ZSwgaHI6IHRydWUsIGxpOiB0cnVlLCBub3NjcmlwdDogdHJ1ZSwgb2w6IHRydWUsXG4gICAgb3V0cHV0OiB0cnVlLCBwOiB0cnVlLCBwcmU6IHRydWUsIHNlY3Rpb246IHRydWUsIHRhYmxlOiB0cnVlLCB0Zm9vdDogdHJ1ZSwgdWw6IHRydWVcbn07XG5jb25zdCBpZ25vcmVUYWdzID0ge1xuICAgIGhlYWQ6IHRydWUsIG5vc2NyaXB0OiB0cnVlLCBvYmplY3Q6IHRydWUsIHNjcmlwdDogdHJ1ZSwgc3R5bGU6IHRydWUsIHRpdGxlOiB0cnVlXG59O1xuY29uc3QgbGlzdFRhZ3MgPSB7IG9sOiB0cnVlLCB1bDogdHJ1ZSB9O1xuLy8gVXNpbmcgYSBiaXRmaWVsZCBmb3Igbm9kZSBjb250ZXh0IG9wdGlvbnNcbmNvbnN0IE9QVF9QUkVTRVJWRV9XUyA9IDEsIE9QVF9QUkVTRVJWRV9XU19GVUxMID0gMiwgT1BUX09QRU5fTEVGVCA9IDQ7XG5mdW5jdGlvbiB3c09wdGlvbnNGb3IodHlwZSwgcHJlc2VydmVXaGl0ZXNwYWNlLCBiYXNlKSB7XG4gICAgaWYgKHByZXNlcnZlV2hpdGVzcGFjZSAhPSBudWxsKVxuICAgICAgICByZXR1cm4gKHByZXNlcnZlV2hpdGVzcGFjZSA/IE9QVF9QUkVTRVJWRV9XUyA6IDApIHxcbiAgICAgICAgICAgIChwcmVzZXJ2ZVdoaXRlc3BhY2UgPT09IFwiZnVsbFwiID8gT1BUX1BSRVNFUlZFX1dTX0ZVTEwgOiAwKTtcbiAgICByZXR1cm4gdHlwZSAmJiB0eXBlLndoaXRlc3BhY2UgPT0gXCJwcmVcIiA/IE9QVF9QUkVTRVJWRV9XUyB8IE9QVF9QUkVTRVJWRV9XU19GVUxMIDogYmFzZSAmIH5PUFRfT1BFTl9MRUZUO1xufVxuY2xhc3MgTm9kZUNvbnRleHQge1xuICAgIGNvbnN0cnVjdG9yKHR5cGUsIGF0dHJzLCBtYXJrcywgc29saWQsIG1hdGNoLCBvcHRpb25zKSB7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuYXR0cnMgPSBhdHRycztcbiAgICAgICAgdGhpcy5tYXJrcyA9IG1hcmtzO1xuICAgICAgICB0aGlzLnNvbGlkID0gc29saWQ7XG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgICAgIHRoaXMuY29udGVudCA9IFtdO1xuICAgICAgICAvLyBNYXJrcyBhcHBsaWVkIHRvIHRoZSBub2RlJ3MgY2hpbGRyZW5cbiAgICAgICAgdGhpcy5hY3RpdmVNYXJrcyA9IE1hcmsubm9uZTtcbiAgICAgICAgdGhpcy5tYXRjaCA9IG1hdGNoIHx8IChvcHRpb25zICYgT1BUX09QRU5fTEVGVCA/IG51bGwgOiB0eXBlLmNvbnRlbnRNYXRjaCk7XG4gICAgfVxuICAgIGZpbmRXcmFwcGluZyhub2RlKSB7XG4gICAgICAgIGlmICghdGhpcy5tYXRjaCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzLnR5cGUpXG4gICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgbGV0IGZpbGwgPSB0aGlzLnR5cGUuY29udGVudE1hdGNoLmZpbGxCZWZvcmUoRnJhZ21lbnQuZnJvbShub2RlKSk7XG4gICAgICAgICAgICBpZiAoZmlsbCkge1xuICAgICAgICAgICAgICAgIHRoaXMubWF0Y2ggPSB0aGlzLnR5cGUuY29udGVudE1hdGNoLm1hdGNoRnJhZ21lbnQoZmlsbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBsZXQgc3RhcnQgPSB0aGlzLnR5cGUuY29udGVudE1hdGNoLCB3cmFwO1xuICAgICAgICAgICAgICAgIGlmICh3cmFwID0gc3RhcnQuZmluZFdyYXBwaW5nKG5vZGUudHlwZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tYXRjaCA9IHN0YXJ0O1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gd3JhcDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5tYXRjaC5maW5kV3JhcHBpbmcobm9kZS50eXBlKTtcbiAgICB9XG4gICAgZmluaXNoKG9wZW5FbmQpIHtcbiAgICAgICAgaWYgKCEodGhpcy5vcHRpb25zICYgT1BUX1BSRVNFUlZFX1dTKSkgeyAvLyBTdHJpcCB0cmFpbGluZyB3aGl0ZXNwYWNlXG4gICAgICAgICAgICBsZXQgbGFzdCA9IHRoaXMuY29udGVudFt0aGlzLmNvbnRlbnQubGVuZ3RoIC0gMV0sIG07XG4gICAgICAgICAgICBpZiAobGFzdCAmJiBsYXN0LmlzVGV4dCAmJiAobSA9IC9bIFxcdFxcclxcblxcdTAwMGNdKyQvLmV4ZWMobGFzdC50ZXh0KSkpIHtcbiAgICAgICAgICAgICAgICBsZXQgdGV4dCA9IGxhc3Q7XG4gICAgICAgICAgICAgICAgaWYgKGxhc3QudGV4dC5sZW5ndGggPT0gbVswXS5sZW5ndGgpXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29udGVudC5wb3AoKTtcbiAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29udGVudFt0aGlzLmNvbnRlbnQubGVuZ3RoIC0gMV0gPSB0ZXh0LndpdGhUZXh0KHRleHQudGV4dC5zbGljZSgwLCB0ZXh0LnRleHQubGVuZ3RoIC0gbVswXS5sZW5ndGgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgY29udGVudCA9IEZyYWdtZW50LmZyb20odGhpcy5jb250ZW50KTtcbiAgICAgICAgaWYgKCFvcGVuRW5kICYmIHRoaXMubWF0Y2gpXG4gICAgICAgICAgICBjb250ZW50ID0gY29udGVudC5hcHBlbmQodGhpcy5tYXRjaC5maWxsQmVmb3JlKEZyYWdtZW50LmVtcHR5LCB0cnVlKSk7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPyB0aGlzLnR5cGUuY3JlYXRlKHRoaXMuYXR0cnMsIGNvbnRlbnQsIHRoaXMubWFya3MpIDogY29udGVudDtcbiAgICB9XG4gICAgaW5saW5lQ29udGV4dChub2RlKSB7XG4gICAgICAgIGlmICh0aGlzLnR5cGUpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy50eXBlLmlubGluZUNvbnRlbnQ7XG4gICAgICAgIGlmICh0aGlzLmNvbnRlbnQubGVuZ3RoKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29udGVudFswXS5pc0lubGluZTtcbiAgICAgICAgcmV0dXJuIG5vZGUucGFyZW50Tm9kZSAmJiAhYmxvY2tUYWdzLmhhc093blByb3BlcnR5KG5vZGUucGFyZW50Tm9kZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpKTtcbiAgICB9XG59XG5jbGFzcyBQYXJzZUNvbnRleHQge1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8vIFRoZSBwYXJzZXIgd2UgYXJlIHVzaW5nLlxuICAgIHBhcnNlciwgXG4gICAgLy8gVGhlIG9wdGlvbnMgcGFzc2VkIHRvIHRoaXMgcGFyc2UuXG4gICAgb3B0aW9ucywgaXNPcGVuKSB7XG4gICAgICAgIHRoaXMucGFyc2VyID0gcGFyc2VyO1xuICAgICAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgICAgICB0aGlzLmlzT3BlbiA9IGlzT3BlbjtcbiAgICAgICAgdGhpcy5vcGVuID0gMDtcbiAgICAgICAgdGhpcy5sb2NhbFByZXNlcnZlV1MgPSBmYWxzZTtcbiAgICAgICAgbGV0IHRvcE5vZGUgPSBvcHRpb25zLnRvcE5vZGUsIHRvcENvbnRleHQ7XG4gICAgICAgIGxldCB0b3BPcHRpb25zID0gd3NPcHRpb25zRm9yKG51bGwsIG9wdGlvbnMucHJlc2VydmVXaGl0ZXNwYWNlLCAwKSB8IChpc09wZW4gPyBPUFRfT1BFTl9MRUZUIDogMCk7XG4gICAgICAgIGlmICh0b3BOb2RlKVxuICAgICAgICAgICAgdG9wQ29udGV4dCA9IG5ldyBOb2RlQ29udGV4dCh0b3BOb2RlLnR5cGUsIHRvcE5vZGUuYXR0cnMsIE1hcmsubm9uZSwgdHJ1ZSwgb3B0aW9ucy50b3BNYXRjaCB8fCB0b3BOb2RlLnR5cGUuY29udGVudE1hdGNoLCB0b3BPcHRpb25zKTtcbiAgICAgICAgZWxzZSBpZiAoaXNPcGVuKVxuICAgICAgICAgICAgdG9wQ29udGV4dCA9IG5ldyBOb2RlQ29udGV4dChudWxsLCBudWxsLCBNYXJrLm5vbmUsIHRydWUsIG51bGwsIHRvcE9wdGlvbnMpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICB0b3BDb250ZXh0ID0gbmV3IE5vZGVDb250ZXh0KHBhcnNlci5zY2hlbWEudG9wTm9kZVR5cGUsIG51bGwsIE1hcmsubm9uZSwgdHJ1ZSwgbnVsbCwgdG9wT3B0aW9ucyk7XG4gICAgICAgIHRoaXMubm9kZXMgPSBbdG9wQ29udGV4dF07XG4gICAgICAgIHRoaXMuZmluZCA9IG9wdGlvbnMuZmluZFBvc2l0aW9ucztcbiAgICAgICAgdGhpcy5uZWVkc0Jsb2NrID0gZmFsc2U7XG4gICAgfVxuICAgIGdldCB0b3AoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm5vZGVzW3RoaXMub3Blbl07XG4gICAgfVxuICAgIC8vIEFkZCBhIERPTSBub2RlIHRvIHRoZSBjb250ZW50LiBUZXh0IGlzIGluc2VydGVkIGFzIHRleHQgbm9kZSxcbiAgICAvLyBvdGhlcndpc2UsIHRoZSBub2RlIGlzIHBhc3NlZCB0byBgYWRkRWxlbWVudGAgb3IsIGlmIGl0IGhhcyBhXG4gICAgLy8gYHN0eWxlYCBhdHRyaWJ1dGUsIGBhZGRFbGVtZW50V2l0aFN0eWxlc2AuXG4gICAgYWRkRE9NKGRvbSwgbWFya3MpIHtcbiAgICAgICAgaWYgKGRvbS5ub2RlVHlwZSA9PSAzKVxuICAgICAgICAgICAgdGhpcy5hZGRUZXh0Tm9kZShkb20sIG1hcmtzKTtcbiAgICAgICAgZWxzZSBpZiAoZG9tLm5vZGVUeXBlID09IDEpXG4gICAgICAgICAgICB0aGlzLmFkZEVsZW1lbnQoZG9tLCBtYXJrcyk7XG4gICAgfVxuICAgIGFkZFRleHROb2RlKGRvbSwgbWFya3MpIHtcbiAgICAgICAgbGV0IHZhbHVlID0gZG9tLm5vZGVWYWx1ZTtcbiAgICAgICAgbGV0IHRvcCA9IHRoaXMudG9wLCBwcmVzZXJ2ZVdTID0gKHRvcC5vcHRpb25zICYgT1BUX1BSRVNFUlZFX1dTX0ZVTEwpID8gXCJmdWxsXCJcbiAgICAgICAgICAgIDogdGhpcy5sb2NhbFByZXNlcnZlV1MgfHwgKHRvcC5vcHRpb25zICYgT1BUX1BSRVNFUlZFX1dTKSA+IDA7XG4gICAgICAgIGlmIChwcmVzZXJ2ZVdTID09PSBcImZ1bGxcIiB8fFxuICAgICAgICAgICAgdG9wLmlubGluZUNvbnRleHQoZG9tKSB8fFxuICAgICAgICAgICAgL1teIFxcdFxcclxcblxcdTAwMGNdLy50ZXN0KHZhbHVlKSkge1xuICAgICAgICAgICAgaWYgKCFwcmVzZXJ2ZVdTKSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKC9bIFxcdFxcclxcblxcdTAwMGNdKy9nLCBcIiBcIik7XG4gICAgICAgICAgICAgICAgLy8gSWYgdGhpcyBzdGFydHMgd2l0aCB3aGl0ZXNwYWNlLCBhbmQgdGhlcmUgaXMgbm8gbm9kZSBiZWZvcmUgaXQsIG9yXG4gICAgICAgICAgICAgICAgLy8gYSBoYXJkIGJyZWFrLCBvciBhIHRleHQgbm9kZSB0aGF0IGVuZHMgd2l0aCB3aGl0ZXNwYWNlLCBzdHJpcCB0aGVcbiAgICAgICAgICAgICAgICAvLyBsZWFkaW5nIHNwYWNlLlxuICAgICAgICAgICAgICAgIGlmICgvXlsgXFx0XFxyXFxuXFx1MDAwY10vLnRlc3QodmFsdWUpICYmIHRoaXMub3BlbiA9PSB0aGlzLm5vZGVzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG5vZGVCZWZvcmUgPSB0b3AuY29udGVudFt0b3AuY29udGVudC5sZW5ndGggLSAxXTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGRvbU5vZGVCZWZvcmUgPSBkb20ucHJldmlvdXNTaWJsaW5nO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIW5vZGVCZWZvcmUgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIChkb21Ob2RlQmVmb3JlICYmIGRvbU5vZGVCZWZvcmUubm9kZU5hbWUgPT0gJ0JSJykgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIChub2RlQmVmb3JlLmlzVGV4dCAmJiAvWyBcXHRcXHJcXG5cXHUwMDBjXSQvLnRlc3Qobm9kZUJlZm9yZS50ZXh0KSkpXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnNsaWNlKDEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHByZXNlcnZlV1MgIT09IFwiZnVsbFwiKSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKC9cXHI/XFxufFxcci9nLCBcIiBcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnJlcGxhY2UoL1xcclxcbj8vZywgXCJcXG5cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodmFsdWUpXG4gICAgICAgICAgICAgICAgdGhpcy5pbnNlcnROb2RlKHRoaXMucGFyc2VyLnNjaGVtYS50ZXh0KHZhbHVlKSwgbWFya3MsICEvXFxTLy50ZXN0KHZhbHVlKSk7XG4gICAgICAgICAgICB0aGlzLmZpbmRJblRleHQoZG9tKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZmluZEluc2lkZShkb20pO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIFRyeSB0byBmaW5kIGEgaGFuZGxlciBmb3IgdGhlIGdpdmVuIHRhZyBhbmQgdXNlIHRoYXQgdG8gcGFyc2UuIElmXG4gICAgLy8gbm9uZSBpcyBmb3VuZCwgdGhlIGVsZW1lbnQncyBjb250ZW50IG5vZGVzIGFyZSBhZGRlZCBkaXJlY3RseS5cbiAgICBhZGRFbGVtZW50KGRvbSwgbWFya3MsIG1hdGNoQWZ0ZXIpIHtcbiAgICAgICAgbGV0IG91dGVyV1MgPSB0aGlzLmxvY2FsUHJlc2VydmVXUywgdG9wID0gdGhpcy50b3A7XG4gICAgICAgIGlmIChkb20udGFnTmFtZSA9PSBcIlBSRVwiIHx8IC9wcmUvLnRlc3QoZG9tLnN0eWxlICYmIGRvbS5zdHlsZS53aGl0ZVNwYWNlKSlcbiAgICAgICAgICAgIHRoaXMubG9jYWxQcmVzZXJ2ZVdTID0gdHJ1ZTtcbiAgICAgICAgbGV0IG5hbWUgPSBkb20ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSwgcnVsZUlEO1xuICAgICAgICBpZiAobGlzdFRhZ3MuaGFzT3duUHJvcGVydHkobmFtZSkgJiYgdGhpcy5wYXJzZXIubm9ybWFsaXplTGlzdHMpXG4gICAgICAgICAgICBub3JtYWxpemVMaXN0KGRvbSk7XG4gICAgICAgIGxldCBydWxlID0gKHRoaXMub3B0aW9ucy5ydWxlRnJvbU5vZGUgJiYgdGhpcy5vcHRpb25zLnJ1bGVGcm9tTm9kZShkb20pKSB8fFxuICAgICAgICAgICAgKHJ1bGVJRCA9IHRoaXMucGFyc2VyLm1hdGNoVGFnKGRvbSwgdGhpcywgbWF0Y2hBZnRlcikpO1xuICAgICAgICBvdXQ6IGlmIChydWxlID8gcnVsZS5pZ25vcmUgOiBpZ25vcmVUYWdzLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgICAgICAgICB0aGlzLmZpbmRJbnNpZGUoZG9tKTtcbiAgICAgICAgICAgIHRoaXMuaWdub3JlRmFsbGJhY2soZG9tLCBtYXJrcyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIXJ1bGUgfHwgcnVsZS5za2lwIHx8IHJ1bGUuY2xvc2VQYXJlbnQpIHtcbiAgICAgICAgICAgIGlmIChydWxlICYmIHJ1bGUuY2xvc2VQYXJlbnQpXG4gICAgICAgICAgICAgICAgdGhpcy5vcGVuID0gTWF0aC5tYXgoMCwgdGhpcy5vcGVuIC0gMSk7XG4gICAgICAgICAgICBlbHNlIGlmIChydWxlICYmIHJ1bGUuc2tpcC5ub2RlVHlwZSlcbiAgICAgICAgICAgICAgICBkb20gPSBydWxlLnNraXA7XG4gICAgICAgICAgICBsZXQgc3luYywgb2xkTmVlZHNCbG9jayA9IHRoaXMubmVlZHNCbG9jaztcbiAgICAgICAgICAgIGlmIChibG9ja1RhZ3MuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICAgICAgICAgICAgICBpZiAodG9wLmNvbnRlbnQubGVuZ3RoICYmIHRvcC5jb250ZW50WzBdLmlzSW5saW5lICYmIHRoaXMub3Blbikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9wZW4tLTtcbiAgICAgICAgICAgICAgICAgICAgdG9wID0gdGhpcy50b3A7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHN5bmMgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGlmICghdG9wLnR5cGUpXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubmVlZHNCbG9jayA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICghZG9tLmZpcnN0Q2hpbGQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxlYWZGYWxsYmFjayhkb20sIG1hcmtzKTtcbiAgICAgICAgICAgICAgICBicmVhayBvdXQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgaW5uZXJNYXJrcyA9IHJ1bGUgJiYgcnVsZS5za2lwID8gbWFya3MgOiB0aGlzLnJlYWRTdHlsZXMoZG9tLCBtYXJrcyk7XG4gICAgICAgICAgICBpZiAoaW5uZXJNYXJrcylcbiAgICAgICAgICAgICAgICB0aGlzLmFkZEFsbChkb20sIGlubmVyTWFya3MpO1xuICAgICAgICAgICAgaWYgKHN5bmMpXG4gICAgICAgICAgICAgICAgdGhpcy5zeW5jKHRvcCk7XG4gICAgICAgICAgICB0aGlzLm5lZWRzQmxvY2sgPSBvbGROZWVkc0Jsb2NrO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbGV0IGlubmVyTWFya3MgPSB0aGlzLnJlYWRTdHlsZXMoZG9tLCBtYXJrcyk7XG4gICAgICAgICAgICBpZiAoaW5uZXJNYXJrcylcbiAgICAgICAgICAgICAgICB0aGlzLmFkZEVsZW1lbnRCeVJ1bGUoZG9tLCBydWxlLCBpbm5lck1hcmtzLCBydWxlLmNvbnN1bWluZyA9PT0gZmFsc2UgPyBydWxlSUQgOiB1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubG9jYWxQcmVzZXJ2ZVdTID0gb3V0ZXJXUztcbiAgICB9XG4gICAgLy8gQ2FsbGVkIGZvciBsZWFmIERPTSBub2RlcyB0aGF0IHdvdWxkIG90aGVyd2lzZSBiZSBpZ25vcmVkXG4gICAgbGVhZkZhbGxiYWNrKGRvbSwgbWFya3MpIHtcbiAgICAgICAgaWYgKGRvbS5ub2RlTmFtZSA9PSBcIkJSXCIgJiYgdGhpcy50b3AudHlwZSAmJiB0aGlzLnRvcC50eXBlLmlubGluZUNvbnRlbnQpXG4gICAgICAgICAgICB0aGlzLmFkZFRleHROb2RlKGRvbS5vd25lckRvY3VtZW50LmNyZWF0ZVRleHROb2RlKFwiXFxuXCIpLCBtYXJrcyk7XG4gICAgfVxuICAgIC8vIENhbGxlZCBmb3IgaWdub3JlZCBub2Rlc1xuICAgIGlnbm9yZUZhbGxiYWNrKGRvbSwgbWFya3MpIHtcbiAgICAgICAgLy8gSWdub3JlZCBCUiBub2RlcyBzaG91bGQgYXQgbGVhc3QgY3JlYXRlIGFuIGlubGluZSBjb250ZXh0XG4gICAgICAgIGlmIChkb20ubm9kZU5hbWUgPT0gXCJCUlwiICYmICghdGhpcy50b3AudHlwZSB8fCAhdGhpcy50b3AudHlwZS5pbmxpbmVDb250ZW50KSlcbiAgICAgICAgICAgIHRoaXMuZmluZFBsYWNlKHRoaXMucGFyc2VyLnNjaGVtYS50ZXh0KFwiLVwiKSwgbWFya3MsIHRydWUpO1xuICAgIH1cbiAgICAvLyBSdW4gYW55IHN0eWxlIHBhcnNlciBhc3NvY2lhdGVkIHdpdGggdGhlIG5vZGUncyBzdHlsZXMuIEVpdGhlclxuICAgIC8vIHJldHVybiBhbiB1cGRhdGVkIGFycmF5IG9mIG1hcmtzLCBvciBudWxsIHRvIGluZGljYXRlIHNvbWUgb2YgdGhlXG4gICAgLy8gc3R5bGVzIGhhZCBhIHJ1bGUgd2l0aCBgaWdub3JlYCBzZXQuXG4gICAgcmVhZFN0eWxlcyhkb20sIG1hcmtzKSB7XG4gICAgICAgIGxldCBzdHlsZXMgPSBkb20uc3R5bGU7XG4gICAgICAgIC8vIEJlY2F1c2UgbWFueSBwcm9wZXJ0aWVzIHdpbGwgb25seSBzaG93IHVwIGluICdub3JtYWxpemVkJyBmb3JtXG4gICAgICAgIC8vIGluIGBzdHlsZS5pdGVtYCAoaS5lLiB0ZXh0LWRlY29yYXRpb24gYmVjb21lc1xuICAgICAgICAvLyB0ZXh0LWRlY29yYXRpb24tbGluZSwgdGV4dC1kZWNvcmF0aW9uLWNvbG9yLCBldGMpLCB3ZSBkaXJlY3RseVxuICAgICAgICAvLyBxdWVyeSB0aGUgc3R5bGVzIG1lbnRpb25lZCBpbiBvdXIgcnVsZXMgaW5zdGVhZCBvZiBpdGVyYXRpbmdcbiAgICAgICAgLy8gb3ZlciB0aGUgaXRlbXMuXG4gICAgICAgIGlmIChzdHlsZXMgJiYgc3R5bGVzLmxlbmd0aClcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5wYXJzZXIubWF0Y2hlZFN0eWxlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGxldCBuYW1lID0gdGhpcy5wYXJzZXIubWF0Y2hlZFN0eWxlc1tpXSwgdmFsdWUgPSBzdHlsZXMuZ2V0UHJvcGVydHlWYWx1ZShuYW1lKTtcbiAgICAgICAgICAgICAgICBpZiAodmFsdWUpXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGFmdGVyID0gdW5kZWZpbmVkOzspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBydWxlID0gdGhpcy5wYXJzZXIubWF0Y2hTdHlsZShuYW1lLCB2YWx1ZSwgdGhpcywgYWZ0ZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFydWxlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJ1bGUuaWdub3JlKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJ1bGUuY2xlYXJNYXJrKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmtzID0gbWFya3MuZmlsdGVyKG0gPT4gIXJ1bGUuY2xlYXJNYXJrKG0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJrcyA9IG1hcmtzLmNvbmNhdCh0aGlzLnBhcnNlci5zY2hlbWEubWFya3NbcnVsZS5tYXJrXS5jcmVhdGUocnVsZS5hdHRycykpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJ1bGUuY29uc3VtaW5nID09PSBmYWxzZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZnRlciA9IHJ1bGU7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1hcmtzO1xuICAgIH1cbiAgICAvLyBMb29rIHVwIGEgaGFuZGxlciBmb3IgdGhlIGdpdmVuIG5vZGUuIElmIG5vbmUgYXJlIGZvdW5kLCByZXR1cm5cbiAgICAvLyBmYWxzZS4gT3RoZXJ3aXNlLCBhcHBseSBpdCwgdXNlIGl0cyByZXR1cm4gdmFsdWUgdG8gZHJpdmUgdGhlIHdheVxuICAgIC8vIHRoZSBub2RlJ3MgY29udGVudCBpcyB3cmFwcGVkLCBhbmQgcmV0dXJuIHRydWUuXG4gICAgYWRkRWxlbWVudEJ5UnVsZShkb20sIHJ1bGUsIG1hcmtzLCBjb250aW51ZUFmdGVyKSB7XG4gICAgICAgIGxldCBzeW5jLCBub2RlVHlwZTtcbiAgICAgICAgaWYgKHJ1bGUubm9kZSkge1xuICAgICAgICAgICAgbm9kZVR5cGUgPSB0aGlzLnBhcnNlci5zY2hlbWEubm9kZXNbcnVsZS5ub2RlXTtcbiAgICAgICAgICAgIGlmICghbm9kZVR5cGUuaXNMZWFmKSB7XG4gICAgICAgICAgICAgICAgbGV0IGlubmVyID0gdGhpcy5lbnRlcihub2RlVHlwZSwgcnVsZS5hdHRycyB8fCBudWxsLCBtYXJrcywgcnVsZS5wcmVzZXJ2ZVdoaXRlc3BhY2UpO1xuICAgICAgICAgICAgICAgIGlmIChpbm5lcikge1xuICAgICAgICAgICAgICAgICAgICBzeW5jID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgbWFya3MgPSBpbm5lcjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICghdGhpcy5pbnNlcnROb2RlKG5vZGVUeXBlLmNyZWF0ZShydWxlLmF0dHJzKSwgbWFya3MsIGRvbS5ub2RlTmFtZSA9PSBcIkJSXCIpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sZWFmRmFsbGJhY2soZG9tLCBtYXJrcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBsZXQgbWFya1R5cGUgPSB0aGlzLnBhcnNlci5zY2hlbWEubWFya3NbcnVsZS5tYXJrXTtcbiAgICAgICAgICAgIG1hcmtzID0gbWFya3MuY29uY2F0KG1hcmtUeXBlLmNyZWF0ZShydWxlLmF0dHJzKSk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHN0YXJ0SW4gPSB0aGlzLnRvcDtcbiAgICAgICAgaWYgKG5vZGVUeXBlICYmIG5vZGVUeXBlLmlzTGVhZikge1xuICAgICAgICAgICAgdGhpcy5maW5kSW5zaWRlKGRvbSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoY29udGludWVBZnRlcikge1xuICAgICAgICAgICAgdGhpcy5hZGRFbGVtZW50KGRvbSwgbWFya3MsIGNvbnRpbnVlQWZ0ZXIpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHJ1bGUuZ2V0Q29udGVudCkge1xuICAgICAgICAgICAgdGhpcy5maW5kSW5zaWRlKGRvbSk7XG4gICAgICAgICAgICBydWxlLmdldENvbnRlbnQoZG9tLCB0aGlzLnBhcnNlci5zY2hlbWEpLmZvckVhY2gobm9kZSA9PiB0aGlzLmluc2VydE5vZGUobm9kZSwgbWFya3MsIGZhbHNlKSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBsZXQgY29udGVudERPTSA9IGRvbTtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcnVsZS5jb250ZW50RWxlbWVudCA9PSBcInN0cmluZ1wiKVxuICAgICAgICAgICAgICAgIGNvbnRlbnRET00gPSBkb20ucXVlcnlTZWxlY3RvcihydWxlLmNvbnRlbnRFbGVtZW50KTtcbiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBydWxlLmNvbnRlbnRFbGVtZW50ID09IFwiZnVuY3Rpb25cIilcbiAgICAgICAgICAgICAgICBjb250ZW50RE9NID0gcnVsZS5jb250ZW50RWxlbWVudChkb20pO1xuICAgICAgICAgICAgZWxzZSBpZiAocnVsZS5jb250ZW50RWxlbWVudClcbiAgICAgICAgICAgICAgICBjb250ZW50RE9NID0gcnVsZS5jb250ZW50RWxlbWVudDtcbiAgICAgICAgICAgIHRoaXMuZmluZEFyb3VuZChkb20sIGNvbnRlbnRET00sIHRydWUpO1xuICAgICAgICAgICAgdGhpcy5hZGRBbGwoY29udGVudERPTSwgbWFya3MpO1xuICAgICAgICAgICAgdGhpcy5maW5kQXJvdW5kKGRvbSwgY29udGVudERPTSwgZmFsc2UpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzeW5jICYmIHRoaXMuc3luYyhzdGFydEluKSlcbiAgICAgICAgICAgIHRoaXMub3Blbi0tO1xuICAgIH1cbiAgICAvLyBBZGQgYWxsIGNoaWxkIG5vZGVzIGJldHdlZW4gYHN0YXJ0SW5kZXhgIGFuZCBgZW5kSW5kZXhgIChvciB0aGVcbiAgICAvLyB3aG9sZSBub2RlLCBpZiBub3QgZ2l2ZW4pLiBJZiBgc3luY2AgaXMgcGFzc2VkLCB1c2UgaXQgdG9cbiAgICAvLyBzeW5jaHJvbml6ZSBhZnRlciBldmVyeSBibG9jayBlbGVtZW50LlxuICAgIGFkZEFsbChwYXJlbnQsIG1hcmtzLCBzdGFydEluZGV4LCBlbmRJbmRleCkge1xuICAgICAgICBsZXQgaW5kZXggPSBzdGFydEluZGV4IHx8IDA7XG4gICAgICAgIGZvciAobGV0IGRvbSA9IHN0YXJ0SW5kZXggPyBwYXJlbnQuY2hpbGROb2Rlc1tzdGFydEluZGV4XSA6IHBhcmVudC5maXJzdENoaWxkLCBlbmQgPSBlbmRJbmRleCA9PSBudWxsID8gbnVsbCA6IHBhcmVudC5jaGlsZE5vZGVzW2VuZEluZGV4XTsgZG9tICE9IGVuZDsgZG9tID0gZG9tLm5leHRTaWJsaW5nLCArK2luZGV4KSB7XG4gICAgICAgICAgICB0aGlzLmZpbmRBdFBvaW50KHBhcmVudCwgaW5kZXgpO1xuICAgICAgICAgICAgdGhpcy5hZGRET00oZG9tLCBtYXJrcyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5maW5kQXRQb2ludChwYXJlbnQsIGluZGV4KTtcbiAgICB9XG4gICAgLy8gVHJ5IHRvIGZpbmQgYSB3YXkgdG8gZml0IHRoZSBnaXZlbiBub2RlIHR5cGUgaW50byB0aGUgY3VycmVudFxuICAgIC8vIGNvbnRleHQuIE1heSBhZGQgaW50ZXJtZWRpYXRlIHdyYXBwZXJzIGFuZC9vciBsZWF2ZSBub24tc29saWRcbiAgICAvLyBub2RlcyB0aGF0IHdlJ3JlIGluLlxuICAgIGZpbmRQbGFjZShub2RlLCBtYXJrcywgY2F1dGlvdXMpIHtcbiAgICAgICAgbGV0IHJvdXRlLCBzeW5jO1xuICAgICAgICBmb3IgKGxldCBkZXB0aCA9IHRoaXMub3BlbiwgcGVuYWx0eSA9IDA7IGRlcHRoID49IDA7IGRlcHRoLS0pIHtcbiAgICAgICAgICAgIGxldCBjeCA9IHRoaXMubm9kZXNbZGVwdGhdO1xuICAgICAgICAgICAgbGV0IGZvdW5kID0gY3guZmluZFdyYXBwaW5nKG5vZGUpO1xuICAgICAgICAgICAgaWYgKGZvdW5kICYmICghcm91dGUgfHwgcm91dGUubGVuZ3RoID4gZm91bmQubGVuZ3RoICsgcGVuYWx0eSkpIHtcbiAgICAgICAgICAgICAgICByb3V0ZSA9IGZvdW5kO1xuICAgICAgICAgICAgICAgIHN5bmMgPSBjeDtcbiAgICAgICAgICAgICAgICBpZiAoIWZvdW5kLmxlbmd0aClcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY3guc29saWQpIHtcbiAgICAgICAgICAgICAgICBpZiAoY2F1dGlvdXMpXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIHBlbmFsdHkgKz0gMjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoIXJvdXRlKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIHRoaXMuc3luYyhzeW5jKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3V0ZS5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIG1hcmtzID0gdGhpcy5lbnRlcklubmVyKHJvdXRlW2ldLCBudWxsLCBtYXJrcywgZmFsc2UpO1xuICAgICAgICByZXR1cm4gbWFya3M7XG4gICAgfVxuICAgIC8vIFRyeSB0byBpbnNlcnQgdGhlIGdpdmVuIG5vZGUsIGFkanVzdGluZyB0aGUgY29udGV4dCB3aGVuIG5lZWRlZC5cbiAgICBpbnNlcnROb2RlKG5vZGUsIG1hcmtzLCBjYXV0aW91cykge1xuICAgICAgICBpZiAobm9kZS5pc0lubGluZSAmJiB0aGlzLm5lZWRzQmxvY2sgJiYgIXRoaXMudG9wLnR5cGUpIHtcbiAgICAgICAgICAgIGxldCBibG9jayA9IHRoaXMudGV4dGJsb2NrRnJvbUNvbnRleHQoKTtcbiAgICAgICAgICAgIGlmIChibG9jaylcbiAgICAgICAgICAgICAgICBtYXJrcyA9IHRoaXMuZW50ZXJJbm5lcihibG9jaywgbnVsbCwgbWFya3MpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBpbm5lck1hcmtzID0gdGhpcy5maW5kUGxhY2Uobm9kZSwgbWFya3MsIGNhdXRpb3VzKTtcbiAgICAgICAgaWYgKGlubmVyTWFya3MpIHtcbiAgICAgICAgICAgIHRoaXMuY2xvc2VFeHRyYSgpO1xuICAgICAgICAgICAgbGV0IHRvcCA9IHRoaXMudG9wO1xuICAgICAgICAgICAgaWYgKHRvcC5tYXRjaClcbiAgICAgICAgICAgICAgICB0b3AubWF0Y2ggPSB0b3AubWF0Y2gubWF0Y2hUeXBlKG5vZGUudHlwZSk7XG4gICAgICAgICAgICBsZXQgbm9kZU1hcmtzID0gTWFyay5ub25lO1xuICAgICAgICAgICAgZm9yIChsZXQgbSBvZiBpbm5lck1hcmtzLmNvbmNhdChub2RlLm1hcmtzKSlcbiAgICAgICAgICAgICAgICBpZiAodG9wLnR5cGUgPyB0b3AudHlwZS5hbGxvd3NNYXJrVHlwZShtLnR5cGUpIDogbWFya01heUFwcGx5KG0udHlwZSwgbm9kZS50eXBlKSlcbiAgICAgICAgICAgICAgICAgICAgbm9kZU1hcmtzID0gbS5hZGRUb1NldChub2RlTWFya3MpO1xuICAgICAgICAgICAgdG9wLmNvbnRlbnQucHVzaChub2RlLm1hcmsobm9kZU1hcmtzKSk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIC8vIFRyeSB0byBzdGFydCBhIG5vZGUgb2YgdGhlIGdpdmVuIHR5cGUsIGFkanVzdGluZyB0aGUgY29udGV4dCB3aGVuXG4gICAgLy8gbmVjZXNzYXJ5LlxuICAgIGVudGVyKHR5cGUsIGF0dHJzLCBtYXJrcywgcHJlc2VydmVXUykge1xuICAgICAgICBsZXQgaW5uZXJNYXJrcyA9IHRoaXMuZmluZFBsYWNlKHR5cGUuY3JlYXRlKGF0dHJzKSwgbWFya3MsIGZhbHNlKTtcbiAgICAgICAgaWYgKGlubmVyTWFya3MpXG4gICAgICAgICAgICBpbm5lck1hcmtzID0gdGhpcy5lbnRlcklubmVyKHR5cGUsIGF0dHJzLCBtYXJrcywgdHJ1ZSwgcHJlc2VydmVXUyk7XG4gICAgICAgIHJldHVybiBpbm5lck1hcmtzO1xuICAgIH1cbiAgICAvLyBPcGVuIGEgbm9kZSBvZiB0aGUgZ2l2ZW4gdHlwZVxuICAgIGVudGVySW5uZXIodHlwZSwgYXR0cnMsIG1hcmtzLCBzb2xpZCA9IGZhbHNlLCBwcmVzZXJ2ZVdTKSB7XG4gICAgICAgIHRoaXMuY2xvc2VFeHRyYSgpO1xuICAgICAgICBsZXQgdG9wID0gdGhpcy50b3A7XG4gICAgICAgIHRvcC5tYXRjaCA9IHRvcC5tYXRjaCAmJiB0b3AubWF0Y2gubWF0Y2hUeXBlKHR5cGUpO1xuICAgICAgICBsZXQgb3B0aW9ucyA9IHdzT3B0aW9uc0Zvcih0eXBlLCBwcmVzZXJ2ZVdTLCB0b3Aub3B0aW9ucyk7XG4gICAgICAgIGlmICgodG9wLm9wdGlvbnMgJiBPUFRfT1BFTl9MRUZUKSAmJiB0b3AuY29udGVudC5sZW5ndGggPT0gMClcbiAgICAgICAgICAgIG9wdGlvbnMgfD0gT1BUX09QRU5fTEVGVDtcbiAgICAgICAgbGV0IGFwcGx5TWFya3MgPSBNYXJrLm5vbmU7XG4gICAgICAgIG1hcmtzID0gbWFya3MuZmlsdGVyKG0gPT4ge1xuICAgICAgICAgICAgaWYgKHRvcC50eXBlID8gdG9wLnR5cGUuYWxsb3dzTWFya1R5cGUobS50eXBlKSA6IG1hcmtNYXlBcHBseShtLnR5cGUsIHR5cGUpKSB7XG4gICAgICAgICAgICAgICAgYXBwbHlNYXJrcyA9IG0uYWRkVG9TZXQoYXBwbHlNYXJrcyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm5vZGVzLnB1c2gobmV3IE5vZGVDb250ZXh0KHR5cGUsIGF0dHJzLCBhcHBseU1hcmtzLCBzb2xpZCwgbnVsbCwgb3B0aW9ucykpO1xuICAgICAgICB0aGlzLm9wZW4rKztcbiAgICAgICAgcmV0dXJuIG1hcmtzO1xuICAgIH1cbiAgICAvLyBNYWtlIHN1cmUgYWxsIG5vZGVzIGFib3ZlIHRoaXMub3BlbiBhcmUgZmluaXNoZWQgYW5kIGFkZGVkIHRvXG4gICAgLy8gdGhlaXIgcGFyZW50c1xuICAgIGNsb3NlRXh0cmEob3BlbkVuZCA9IGZhbHNlKSB7XG4gICAgICAgIGxldCBpID0gdGhpcy5ub2Rlcy5sZW5ndGggLSAxO1xuICAgICAgICBpZiAoaSA+IHRoaXMub3Blbikge1xuICAgICAgICAgICAgZm9yICg7IGkgPiB0aGlzLm9wZW47IGktLSlcbiAgICAgICAgICAgICAgICB0aGlzLm5vZGVzW2kgLSAxXS5jb250ZW50LnB1c2godGhpcy5ub2Rlc1tpXS5maW5pc2gob3BlbkVuZCkpO1xuICAgICAgICAgICAgdGhpcy5ub2Rlcy5sZW5ndGggPSB0aGlzLm9wZW4gKyAxO1xuICAgICAgICB9XG4gICAgfVxuICAgIGZpbmlzaCgpIHtcbiAgICAgICAgdGhpcy5vcGVuID0gMDtcbiAgICAgICAgdGhpcy5jbG9zZUV4dHJhKHRoaXMuaXNPcGVuKTtcbiAgICAgICAgcmV0dXJuIHRoaXMubm9kZXNbMF0uZmluaXNoKCEhKHRoaXMuaXNPcGVuIHx8IHRoaXMub3B0aW9ucy50b3BPcGVuKSk7XG4gICAgfVxuICAgIHN5bmModG8pIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IHRoaXMub3BlbjsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIGlmICh0aGlzLm5vZGVzW2ldID09IHRvKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVuID0gaTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHRoaXMubG9jYWxQcmVzZXJ2ZVdTKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5ub2Rlc1tpXS5vcHRpb25zIHw9IE9QVF9QUkVTRVJWRV9XUztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGdldCBjdXJyZW50UG9zKCkge1xuICAgICAgICB0aGlzLmNsb3NlRXh0cmEoKTtcbiAgICAgICAgbGV0IHBvcyA9IDA7XG4gICAgICAgIGZvciAobGV0IGkgPSB0aGlzLm9wZW47IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICBsZXQgY29udGVudCA9IHRoaXMubm9kZXNbaV0uY29udGVudDtcbiAgICAgICAgICAgIGZvciAobGV0IGogPSBjb250ZW50Lmxlbmd0aCAtIDE7IGogPj0gMDsgai0tKVxuICAgICAgICAgICAgICAgIHBvcyArPSBjb250ZW50W2pdLm5vZGVTaXplO1xuICAgICAgICAgICAgaWYgKGkpXG4gICAgICAgICAgICAgICAgcG9zKys7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBvcztcbiAgICB9XG4gICAgZmluZEF0UG9pbnQocGFyZW50LCBvZmZzZXQpIHtcbiAgICAgICAgaWYgKHRoaXMuZmluZClcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5maW5kLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZmluZFtpXS5ub2RlID09IHBhcmVudCAmJiB0aGlzLmZpbmRbaV0ub2Zmc2V0ID09IG9mZnNldClcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5maW5kW2ldLnBvcyA9IHRoaXMuY3VycmVudFBvcztcbiAgICAgICAgICAgIH1cbiAgICB9XG4gICAgZmluZEluc2lkZShwYXJlbnQpIHtcbiAgICAgICAgaWYgKHRoaXMuZmluZClcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5maW5kLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZmluZFtpXS5wb3MgPT0gbnVsbCAmJiBwYXJlbnQubm9kZVR5cGUgPT0gMSAmJiBwYXJlbnQuY29udGFpbnModGhpcy5maW5kW2ldLm5vZGUpKVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbmRbaV0ucG9zID0gdGhpcy5jdXJyZW50UG9zO1xuICAgICAgICAgICAgfVxuICAgIH1cbiAgICBmaW5kQXJvdW5kKHBhcmVudCwgY29udGVudCwgYmVmb3JlKSB7XG4gICAgICAgIGlmIChwYXJlbnQgIT0gY29udGVudCAmJiB0aGlzLmZpbmQpXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZmluZC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmZpbmRbaV0ucG9zID09IG51bGwgJiYgcGFyZW50Lm5vZGVUeXBlID09IDEgJiYgcGFyZW50LmNvbnRhaW5zKHRoaXMuZmluZFtpXS5ub2RlKSkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgcG9zID0gY29udGVudC5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbih0aGlzLmZpbmRbaV0ubm9kZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChwb3MgJiAoYmVmb3JlID8gMiA6IDQpKVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maW5kW2ldLnBvcyA9IHRoaXMuY3VycmVudFBvcztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgfVxuICAgIGZpbmRJblRleHQodGV4dE5vZGUpIHtcbiAgICAgICAgaWYgKHRoaXMuZmluZClcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5maW5kLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZmluZFtpXS5ub2RlID09IHRleHROb2RlKVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbmRbaV0ucG9zID0gdGhpcy5jdXJyZW50UG9zIC0gKHRleHROb2RlLm5vZGVWYWx1ZS5sZW5ndGggLSB0aGlzLmZpbmRbaV0ub2Zmc2V0KTtcbiAgICAgICAgICAgIH1cbiAgICB9XG4gICAgLy8gRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBnaXZlbiBjb250ZXh0IHN0cmluZyBtYXRjaGVzIHRoaXMgY29udGV4dC5cbiAgICBtYXRjaGVzQ29udGV4dChjb250ZXh0KSB7XG4gICAgICAgIGlmIChjb250ZXh0LmluZGV4T2YoXCJ8XCIpID4gLTEpXG4gICAgICAgICAgICByZXR1cm4gY29udGV4dC5zcGxpdCgvXFxzKlxcfFxccyovKS5zb21lKHRoaXMubWF0Y2hlc0NvbnRleHQsIHRoaXMpO1xuICAgICAgICBsZXQgcGFydHMgPSBjb250ZXh0LnNwbGl0KFwiL1wiKTtcbiAgICAgICAgbGV0IG9wdGlvbiA9IHRoaXMub3B0aW9ucy5jb250ZXh0O1xuICAgICAgICBsZXQgdXNlUm9vdCA9ICF0aGlzLmlzT3BlbiAmJiAoIW9wdGlvbiB8fCBvcHRpb24ucGFyZW50LnR5cGUgPT0gdGhpcy5ub2Rlc1swXS50eXBlKTtcbiAgICAgICAgbGV0IG1pbkRlcHRoID0gLShvcHRpb24gPyBvcHRpb24uZGVwdGggKyAxIDogMCkgKyAodXNlUm9vdCA/IDAgOiAxKTtcbiAgICAgICAgbGV0IG1hdGNoID0gKGksIGRlcHRoKSA9PiB7XG4gICAgICAgICAgICBmb3IgKDsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgICAgICBsZXQgcGFydCA9IHBhcnRzW2ldO1xuICAgICAgICAgICAgICAgIGlmIChwYXJ0ID09IFwiXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPT0gcGFydHMubGVuZ3RoIC0gMSB8fCBpID09IDApXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgZm9yICg7IGRlcHRoID49IG1pbkRlcHRoOyBkZXB0aC0tKVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1hdGNoKGkgLSAxLCBkZXB0aCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBuZXh0ID0gZGVwdGggPiAwIHx8IChkZXB0aCA9PSAwICYmIHVzZVJvb3QpID8gdGhpcy5ub2Rlc1tkZXB0aF0udHlwZVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBvcHRpb24gJiYgZGVwdGggPj0gbWluRGVwdGggPyBvcHRpb24ubm9kZShkZXB0aCAtIG1pbkRlcHRoKS50eXBlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBudWxsO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIW5leHQgfHwgKG5leHQubmFtZSAhPSBwYXJ0ICYmICFuZXh0LmlzSW5Hcm91cChwYXJ0KSkpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGRlcHRoLS07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBtYXRjaChwYXJ0cy5sZW5ndGggLSAxLCB0aGlzLm9wZW4pO1xuICAgIH1cbiAgICB0ZXh0YmxvY2tGcm9tQ29udGV4dCgpIHtcbiAgICAgICAgbGV0ICRjb250ZXh0ID0gdGhpcy5vcHRpb25zLmNvbnRleHQ7XG4gICAgICAgIGlmICgkY29udGV4dClcbiAgICAgICAgICAgIGZvciAobGV0IGQgPSAkY29udGV4dC5kZXB0aDsgZCA+PSAwOyBkLS0pIHtcbiAgICAgICAgICAgICAgICBsZXQgZGVmbHQgPSAkY29udGV4dC5ub2RlKGQpLmNvbnRlbnRNYXRjaEF0KCRjb250ZXh0LmluZGV4QWZ0ZXIoZCkpLmRlZmF1bHRUeXBlO1xuICAgICAgICAgICAgICAgIGlmIChkZWZsdCAmJiBkZWZsdC5pc1RleHRibG9jayAmJiBkZWZsdC5kZWZhdWx0QXR0cnMpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBkZWZsdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgbmFtZSBpbiB0aGlzLnBhcnNlci5zY2hlbWEubm9kZXMpIHtcbiAgICAgICAgICAgIGxldCB0eXBlID0gdGhpcy5wYXJzZXIuc2NoZW1hLm5vZGVzW25hbWVdO1xuICAgICAgICAgICAgaWYgKHR5cGUuaXNUZXh0YmxvY2sgJiYgdHlwZS5kZWZhdWx0QXR0cnMpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHR5cGU7XG4gICAgICAgIH1cbiAgICB9XG59XG4vLyBLbHVkZ2UgdG8gd29yayBhcm91bmQgZGlyZWN0bHkgbmVzdGVkIGxpc3Qgbm9kZXMgcHJvZHVjZWQgYnkgc29tZVxuLy8gdG9vbHMgYW5kIGFsbG93ZWQgYnkgYnJvd3NlcnMgdG8gbWVhbiB0aGF0IHRoZSBuZXN0ZWQgbGlzdCBpc1xuLy8gYWN0dWFsbHkgcGFydCBvZiB0aGUgbGlzdCBpdGVtIGFib3ZlIGl0LlxuZnVuY3Rpb24gbm9ybWFsaXplTGlzdChkb20pIHtcbiAgICBmb3IgKGxldCBjaGlsZCA9IGRvbS5maXJzdENoaWxkLCBwcmV2SXRlbSA9IG51bGw7IGNoaWxkOyBjaGlsZCA9IGNoaWxkLm5leHRTaWJsaW5nKSB7XG4gICAgICAgIGxldCBuYW1lID0gY2hpbGQubm9kZVR5cGUgPT0gMSA/IGNoaWxkLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgOiBudWxsO1xuICAgICAgICBpZiAobmFtZSAmJiBsaXN0VGFncy5oYXNPd25Qcm9wZXJ0eShuYW1lKSAmJiBwcmV2SXRlbSkge1xuICAgICAgICAgICAgcHJldkl0ZW0uYXBwZW5kQ2hpbGQoY2hpbGQpO1xuICAgICAgICAgICAgY2hpbGQgPSBwcmV2SXRlbTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChuYW1lID09IFwibGlcIikge1xuICAgICAgICAgICAgcHJldkl0ZW0gPSBjaGlsZDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChuYW1lKSB7XG4gICAgICAgICAgICBwcmV2SXRlbSA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9XG59XG4vLyBBcHBseSBhIENTUyBzZWxlY3Rvci5cbmZ1bmN0aW9uIG1hdGNoZXMoZG9tLCBzZWxlY3Rvcikge1xuICAgIHJldHVybiAoZG9tLm1hdGNoZXMgfHwgZG9tLm1zTWF0Y2hlc1NlbGVjdG9yIHx8IGRvbS53ZWJraXRNYXRjaGVzU2VsZWN0b3IgfHwgZG9tLm1vek1hdGNoZXNTZWxlY3RvcikuY2FsbChkb20sIHNlbGVjdG9yKTtcbn1cbmZ1bmN0aW9uIGNvcHkob2JqKSB7XG4gICAgbGV0IGNvcHkgPSB7fTtcbiAgICBmb3IgKGxldCBwcm9wIGluIG9iailcbiAgICAgICAgY29weVtwcm9wXSA9IG9ialtwcm9wXTtcbiAgICByZXR1cm4gY29weTtcbn1cbi8vIFVzZWQgd2hlbiBmaW5kaW5nIGEgbWFyayBhdCB0aGUgdG9wIGxldmVsIG9mIGEgZnJhZ21lbnQgcGFyc2UuXG4vLyBDaGVja3Mgd2hldGhlciBpdCB3b3VsZCBiZSByZWFzb25hYmxlIHRvIGFwcGx5IGEgZ2l2ZW4gbWFyayB0eXBlIHRvXG4vLyBhIGdpdmVuIG5vZGUsIGJ5IGxvb2tpbmcgYXQgdGhlIHdheSB0aGUgbWFyayBvY2N1cnMgaW4gdGhlIHNjaGVtYS5cbmZ1bmN0aW9uIG1hcmtNYXlBcHBseShtYXJrVHlwZSwgbm9kZVR5cGUpIHtcbiAgICBsZXQgbm9kZXMgPSBub2RlVHlwZS5zY2hlbWEubm9kZXM7XG4gICAgZm9yIChsZXQgbmFtZSBpbiBub2Rlcykge1xuICAgICAgICBsZXQgcGFyZW50ID0gbm9kZXNbbmFtZV07XG4gICAgICAgIGlmICghcGFyZW50LmFsbG93c01hcmtUeXBlKG1hcmtUeXBlKSlcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICBsZXQgc2VlbiA9IFtdLCBzY2FuID0gKG1hdGNoKSA9PiB7XG4gICAgICAgICAgICBzZWVuLnB1c2gobWF0Y2gpO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBtYXRjaC5lZGdlQ291bnQ7IGkrKykge1xuICAgICAgICAgICAgICAgIGxldCB7IHR5cGUsIG5leHQgfSA9IG1hdGNoLmVkZ2UoaSk7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGUgPT0gbm9kZVR5cGUpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIGlmIChzZWVuLmluZGV4T2YobmV4dCkgPCAwICYmIHNjYW4obmV4dCkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBpZiAoc2NhbihwYXJlbnQuY29udGVudE1hdGNoKSlcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbn1cblxuLyoqXG5BIERPTSBzZXJpYWxpemVyIGtub3dzIGhvdyB0byBjb252ZXJ0IFByb3NlTWlycm9yIG5vZGVzIGFuZFxubWFya3Mgb2YgdmFyaW91cyB0eXBlcyB0byBET00gbm9kZXMuXG4qL1xuY2xhc3MgRE9NU2VyaWFsaXplciB7XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgc2VyaWFsaXplci4gYG5vZGVzYCBzaG91bGQgbWFwIG5vZGUgbmFtZXMgdG8gZnVuY3Rpb25zXG4gICAgdGhhdCB0YWtlIGEgbm9kZSBhbmQgcmV0dXJuIGEgZGVzY3JpcHRpb24gb2YgdGhlIGNvcnJlc3BvbmRpbmdcbiAgICBET00uIGBtYXJrc2AgZG9lcyB0aGUgc2FtZSBmb3IgbWFyayBuYW1lcywgYnV0IGFsc28gZ2V0cyBhblxuICAgIGFyZ3VtZW50IHRoYXQgdGVsbHMgaXQgd2hldGhlciB0aGUgbWFyaydzIGNvbnRlbnQgaXMgYmxvY2sgb3JcbiAgICBpbmxpbmUgY29udGVudCAoZm9yIHR5cGljYWwgdXNlLCBpdCdsbCBhbHdheXMgYmUgaW5saW5lKS4gQSBtYXJrXG4gICAgc2VyaWFsaXplciBtYXkgYmUgYG51bGxgIHRvIGluZGljYXRlIHRoYXQgbWFya3Mgb2YgdGhhdCB0eXBlXG4gICAgc2hvdWxkIG5vdCBiZSBzZXJpYWxpemVkLlxuICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgVGhlIG5vZGUgc2VyaWFsaXphdGlvbiBmdW5jdGlvbnMuXG4gICAgKi9cbiAgICBub2RlcywgXG4gICAgLyoqXG4gICAgVGhlIG1hcmsgc2VyaWFsaXphdGlvbiBmdW5jdGlvbnMuXG4gICAgKi9cbiAgICBtYXJrcykge1xuICAgICAgICB0aGlzLm5vZGVzID0gbm9kZXM7XG4gICAgICAgIHRoaXMubWFya3MgPSBtYXJrcztcbiAgICB9XG4gICAgLyoqXG4gICAgU2VyaWFsaXplIHRoZSBjb250ZW50IG9mIHRoaXMgZnJhZ21lbnQgdG8gYSBET00gZnJhZ21lbnQuIFdoZW5cbiAgICBub3QgaW4gdGhlIGJyb3dzZXIsIHRoZSBgZG9jdW1lbnRgIG9wdGlvbiwgY29udGFpbmluZyBhIERPTVxuICAgIGRvY3VtZW50LCBzaG91bGQgYmUgcGFzc2VkIHNvIHRoYXQgdGhlIHNlcmlhbGl6ZXIgY2FuIGNyZWF0ZVxuICAgIG5vZGVzLlxuICAgICovXG4gICAgc2VyaWFsaXplRnJhZ21lbnQoZnJhZ21lbnQsIG9wdGlvbnMgPSB7fSwgdGFyZ2V0KSB7XG4gICAgICAgIGlmICghdGFyZ2V0KVxuICAgICAgICAgICAgdGFyZ2V0ID0gZG9jKG9wdGlvbnMpLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcbiAgICAgICAgbGV0IHRvcCA9IHRhcmdldCwgYWN0aXZlID0gW107XG4gICAgICAgIGZyYWdtZW50LmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgICAgICBpZiAoYWN0aXZlLmxlbmd0aCB8fCBub2RlLm1hcmtzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGxldCBrZWVwID0gMCwgcmVuZGVyZWQgPSAwO1xuICAgICAgICAgICAgICAgIHdoaWxlIChrZWVwIDwgYWN0aXZlLmxlbmd0aCAmJiByZW5kZXJlZCA8IG5vZGUubWFya3MubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBuZXh0ID0gbm9kZS5tYXJrc1tyZW5kZXJlZF07XG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5tYXJrc1tuZXh0LnR5cGUubmFtZV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbmRlcmVkKys7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoIW5leHQuZXEoYWN0aXZlW2tlZXBdWzBdKSB8fCBuZXh0LnR5cGUuc3BlYy5zcGFubmluZyA9PT0gZmFsc2UpXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAga2VlcCsrO1xuICAgICAgICAgICAgICAgICAgICByZW5kZXJlZCsrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB3aGlsZSAoa2VlcCA8IGFjdGl2ZS5sZW5ndGgpXG4gICAgICAgICAgICAgICAgICAgIHRvcCA9IGFjdGl2ZS5wb3AoKVsxXTtcbiAgICAgICAgICAgICAgICB3aGlsZSAocmVuZGVyZWQgPCBub2RlLm1hcmtzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgYWRkID0gbm9kZS5tYXJrc1tyZW5kZXJlZCsrXTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG1hcmtET00gPSB0aGlzLnNlcmlhbGl6ZU1hcmsoYWRkLCBub2RlLmlzSW5saW5lLCBvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG1hcmtET00pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFjdGl2ZS5wdXNoKFthZGQsIHRvcF0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgdG9wLmFwcGVuZENoaWxkKG1hcmtET00uZG9tKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvcCA9IG1hcmtET00uY29udGVudERPTSB8fCBtYXJrRE9NLmRvbTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRvcC5hcHBlbmRDaGlsZCh0aGlzLnNlcmlhbGl6ZU5vZGVJbm5lcihub2RlLCBvcHRpb25zKSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGFyZ2V0O1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHNlcmlhbGl6ZU5vZGVJbm5lcihub2RlLCBvcHRpb25zKSB7XG4gICAgICAgIGxldCB7IGRvbSwgY29udGVudERPTSB9ID0gcmVuZGVyU3BlYyhkb2Mob3B0aW9ucyksIHRoaXMubm9kZXNbbm9kZS50eXBlLm5hbWVdKG5vZGUpLCBudWxsLCBub2RlLmF0dHJzKTtcbiAgICAgICAgaWYgKGNvbnRlbnRET00pIHtcbiAgICAgICAgICAgIGlmIChub2RlLmlzTGVhZilcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkNvbnRlbnQgaG9sZSBub3QgYWxsb3dlZCBpbiBhIGxlYWYgbm9kZSBzcGVjXCIpO1xuICAgICAgICAgICAgdGhpcy5zZXJpYWxpemVGcmFnbWVudChub2RlLmNvbnRlbnQsIG9wdGlvbnMsIGNvbnRlbnRET00pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkb207XG4gICAgfVxuICAgIC8qKlxuICAgIFNlcmlhbGl6ZSB0aGlzIG5vZGUgdG8gYSBET00gbm9kZS4gVGhpcyBjYW4gYmUgdXNlZnVsIHdoZW4geW91XG4gICAgbmVlZCB0byBzZXJpYWxpemUgYSBwYXJ0IG9mIGEgZG9jdW1lbnQsIGFzIG9wcG9zZWQgdG8gdGhlIHdob2xlXG4gICAgZG9jdW1lbnQuIFRvIHNlcmlhbGl6ZSBhIHdob2xlIGRvY3VtZW50LCB1c2VcbiAgICBbYHNlcmlhbGl6ZUZyYWdtZW50YF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLkRPTVNlcmlhbGl6ZXIuc2VyaWFsaXplRnJhZ21lbnQpIG9uXG4gICAgaXRzIFtjb250ZW50XShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZS5jb250ZW50KS5cbiAgICAqL1xuICAgIHNlcmlhbGl6ZU5vZGUobm9kZSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIGxldCBkb20gPSB0aGlzLnNlcmlhbGl6ZU5vZGVJbm5lcihub2RlLCBvcHRpb25zKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IG5vZGUubWFya3MubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIGxldCB3cmFwID0gdGhpcy5zZXJpYWxpemVNYXJrKG5vZGUubWFya3NbaV0sIG5vZGUuaXNJbmxpbmUsIG9wdGlvbnMpO1xuICAgICAgICAgICAgaWYgKHdyYXApIHtcbiAgICAgICAgICAgICAgICAod3JhcC5jb250ZW50RE9NIHx8IHdyYXAuZG9tKS5hcHBlbmRDaGlsZChkb20pO1xuICAgICAgICAgICAgICAgIGRvbSA9IHdyYXAuZG9tO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkb207XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgc2VyaWFsaXplTWFyayhtYXJrLCBpbmxpbmUsIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICBsZXQgdG9ET00gPSB0aGlzLm1hcmtzW21hcmsudHlwZS5uYW1lXTtcbiAgICAgICAgcmV0dXJuIHRvRE9NICYmIHJlbmRlclNwZWMoZG9jKG9wdGlvbnMpLCB0b0RPTShtYXJrLCBpbmxpbmUpLCBudWxsLCBtYXJrLmF0dHJzKTtcbiAgICB9XG4gICAgc3RhdGljIHJlbmRlclNwZWMoZG9jLCBzdHJ1Y3R1cmUsIHhtbE5TID0gbnVsbCwgYmxvY2tBcnJheXNJbikge1xuICAgICAgICByZXR1cm4gcmVuZGVyU3BlYyhkb2MsIHN0cnVjdHVyZSwgeG1sTlMsIGJsb2NrQXJyYXlzSW4pO1xuICAgIH1cbiAgICAvKipcbiAgICBCdWlsZCBhIHNlcmlhbGl6ZXIgdXNpbmcgdGhlIFtgdG9ET01gXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZVNwZWMudG9ET00pXG4gICAgcHJvcGVydGllcyBpbiBhIHNjaGVtYSdzIG5vZGUgYW5kIG1hcmsgc3BlY3MuXG4gICAgKi9cbiAgICBzdGF0aWMgZnJvbVNjaGVtYShzY2hlbWEpIHtcbiAgICAgICAgcmV0dXJuIHNjaGVtYS5jYWNoZWQuZG9tU2VyaWFsaXplciB8fFxuICAgICAgICAgICAgKHNjaGVtYS5jYWNoZWQuZG9tU2VyaWFsaXplciA9IG5ldyBET01TZXJpYWxpemVyKHRoaXMubm9kZXNGcm9tU2NoZW1hKHNjaGVtYSksIHRoaXMubWFya3NGcm9tU2NoZW1hKHNjaGVtYSkpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgR2F0aGVyIHRoZSBzZXJpYWxpemVycyBpbiBhIHNjaGVtYSdzIG5vZGUgc3BlY3MgaW50byBhbiBvYmplY3QuXG4gICAgVGhpcyBjYW4gYmUgdXNlZnVsIGFzIGEgYmFzZSB0byBidWlsZCBhIGN1c3RvbSBzZXJpYWxpemVyIGZyb20uXG4gICAgKi9cbiAgICBzdGF0aWMgbm9kZXNGcm9tU2NoZW1hKHNjaGVtYSkge1xuICAgICAgICBsZXQgcmVzdWx0ID0gZ2F0aGVyVG9ET00oc2NoZW1hLm5vZGVzKTtcbiAgICAgICAgaWYgKCFyZXN1bHQudGV4dClcbiAgICAgICAgICAgIHJlc3VsdC50ZXh0ID0gbm9kZSA9PiBub2RlLnRleHQ7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICAgIC8qKlxuICAgIEdhdGhlciB0aGUgc2VyaWFsaXplcnMgaW4gYSBzY2hlbWEncyBtYXJrIHNwZWNzIGludG8gYW4gb2JqZWN0LlxuICAgICovXG4gICAgc3RhdGljIG1hcmtzRnJvbVNjaGVtYShzY2hlbWEpIHtcbiAgICAgICAgcmV0dXJuIGdhdGhlclRvRE9NKHNjaGVtYS5tYXJrcyk7XG4gICAgfVxufVxuZnVuY3Rpb24gZ2F0aGVyVG9ET00ob2JqKSB7XG4gICAgbGV0IHJlc3VsdCA9IHt9O1xuICAgIGZvciAobGV0IG5hbWUgaW4gb2JqKSB7XG4gICAgICAgIGxldCB0b0RPTSA9IG9ialtuYW1lXS5zcGVjLnRvRE9NO1xuICAgICAgICBpZiAodG9ET00pXG4gICAgICAgICAgICByZXN1bHRbbmFtZV0gPSB0b0RPTTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbmZ1bmN0aW9uIGRvYyhvcHRpb25zKSB7XG4gICAgcmV0dXJuIG9wdGlvbnMuZG9jdW1lbnQgfHwgd2luZG93LmRvY3VtZW50O1xufVxuY29uc3Qgc3VzcGljaW91c0F0dHJpYnV0ZUNhY2hlID0gbmV3IFdlYWtNYXAoKTtcbmZ1bmN0aW9uIHN1c3BpY2lvdXNBdHRyaWJ1dGVzKGF0dHJzKSB7XG4gICAgbGV0IHZhbHVlID0gc3VzcGljaW91c0F0dHJpYnV0ZUNhY2hlLmdldChhdHRycyk7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpXG4gICAgICAgIHN1c3BpY2lvdXNBdHRyaWJ1dGVDYWNoZS5zZXQoYXR0cnMsIHZhbHVlID0gc3VzcGljaW91c0F0dHJpYnV0ZXNJbm5lcihhdHRycykpO1xuICAgIHJldHVybiB2YWx1ZTtcbn1cbmZ1bmN0aW9uIHN1c3BpY2lvdXNBdHRyaWJ1dGVzSW5uZXIoYXR0cnMpIHtcbiAgICBsZXQgcmVzdWx0ID0gbnVsbDtcbiAgICBmdW5jdGlvbiBzY2FuKHZhbHVlKSB7XG4gICAgICAgIGlmICh2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT0gXCJvYmplY3RcIikge1xuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZVswXSA9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghcmVzdWx0KVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gW107XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICAgICAgICAgICAgICBzY2FuKHZhbHVlW2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBwcm9wIGluIHZhbHVlKVxuICAgICAgICAgICAgICAgICAgICBzY2FuKHZhbHVlW3Byb3BdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBzY2FuKGF0dHJzKTtcbiAgICByZXR1cm4gcmVzdWx0O1xufVxuZnVuY3Rpb24gcmVuZGVyU3BlYyhkb2MsIHN0cnVjdHVyZSwgeG1sTlMsIGJsb2NrQXJyYXlzSW4pIHtcbiAgICBpZiAodHlwZW9mIHN0cnVjdHVyZSA9PSBcInN0cmluZ1wiKVxuICAgICAgICByZXR1cm4geyBkb206IGRvYy5jcmVhdGVUZXh0Tm9kZShzdHJ1Y3R1cmUpIH07XG4gICAgaWYgKHN0cnVjdHVyZS5ub2RlVHlwZSAhPSBudWxsKVxuICAgICAgICByZXR1cm4geyBkb206IHN0cnVjdHVyZSB9O1xuICAgIGlmIChzdHJ1Y3R1cmUuZG9tICYmIHN0cnVjdHVyZS5kb20ubm9kZVR5cGUgIT0gbnVsbClcbiAgICAgICAgcmV0dXJuIHN0cnVjdHVyZTtcbiAgICBsZXQgdGFnTmFtZSA9IHN0cnVjdHVyZVswXSwgc3VzcGljaW91cztcbiAgICBpZiAodHlwZW9mIHRhZ05hbWUgIT0gXCJzdHJpbmdcIilcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIGFycmF5IHBhc3NlZCB0byByZW5kZXJTcGVjXCIpO1xuICAgIGlmIChibG9ja0FycmF5c0luICYmIChzdXNwaWNpb3VzID0gc3VzcGljaW91c0F0dHJpYnV0ZXMoYmxvY2tBcnJheXNJbikpICYmXG4gICAgICAgIHN1c3BpY2lvdXMuaW5kZXhPZihzdHJ1Y3R1cmUpID4gLTEpXG4gICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiVXNpbmcgYW4gYXJyYXkgZnJvbSBhbiBhdHRyaWJ1dGUgb2JqZWN0IGFzIGEgRE9NIHNwZWMuIFRoaXMgbWF5IGJlIGFuIGF0dGVtcHRlZCBjcm9zcyBzaXRlIHNjcmlwdGluZyBhdHRhY2suXCIpO1xuICAgIGxldCBzcGFjZSA9IHRhZ05hbWUuaW5kZXhPZihcIiBcIik7XG4gICAgaWYgKHNwYWNlID4gMCkge1xuICAgICAgICB4bWxOUyA9IHRhZ05hbWUuc2xpY2UoMCwgc3BhY2UpO1xuICAgICAgICB0YWdOYW1lID0gdGFnTmFtZS5zbGljZShzcGFjZSArIDEpO1xuICAgIH1cbiAgICBsZXQgY29udGVudERPTTtcbiAgICBsZXQgZG9tID0gKHhtbE5TID8gZG9jLmNyZWF0ZUVsZW1lbnROUyh4bWxOUywgdGFnTmFtZSkgOiBkb2MuY3JlYXRlRWxlbWVudCh0YWdOYW1lKSk7XG4gICAgbGV0IGF0dHJzID0gc3RydWN0dXJlWzFdLCBzdGFydCA9IDE7XG4gICAgaWYgKGF0dHJzICYmIHR5cGVvZiBhdHRycyA9PSBcIm9iamVjdFwiICYmIGF0dHJzLm5vZGVUeXBlID09IG51bGwgJiYgIUFycmF5LmlzQXJyYXkoYXR0cnMpKSB7XG4gICAgICAgIHN0YXJ0ID0gMjtcbiAgICAgICAgZm9yIChsZXQgbmFtZSBpbiBhdHRycylcbiAgICAgICAgICAgIGlmIChhdHRyc1tuYW1lXSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgbGV0IHNwYWNlID0gbmFtZS5pbmRleE9mKFwiIFwiKTtcbiAgICAgICAgICAgICAgICBpZiAoc3BhY2UgPiAwKVxuICAgICAgICAgICAgICAgICAgICBkb20uc2V0QXR0cmlidXRlTlMobmFtZS5zbGljZSgwLCBzcGFjZSksIG5hbWUuc2xpY2Uoc3BhY2UgKyAxKSwgYXR0cnNbbmFtZV0pO1xuICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgZG9tLnNldEF0dHJpYnV0ZShuYW1lLCBhdHRyc1tuYW1lXSk7XG4gICAgICAgICAgICB9XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSBzdGFydDsgaSA8IHN0cnVjdHVyZS5sZW5ndGg7IGkrKykge1xuICAgICAgICBsZXQgY2hpbGQgPSBzdHJ1Y3R1cmVbaV07XG4gICAgICAgIGlmIChjaGlsZCA9PT0gMCkge1xuICAgICAgICAgICAgaWYgKGkgPCBzdHJ1Y3R1cmUubGVuZ3RoIC0gMSB8fCBpID4gc3RhcnQpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJDb250ZW50IGhvbGUgbXVzdCBiZSB0aGUgb25seSBjaGlsZCBvZiBpdHMgcGFyZW50IG5vZGVcIik7XG4gICAgICAgICAgICByZXR1cm4geyBkb20sIGNvbnRlbnRET006IGRvbSB9O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbGV0IHsgZG9tOiBpbm5lciwgY29udGVudERPTTogaW5uZXJDb250ZW50IH0gPSByZW5kZXJTcGVjKGRvYywgY2hpbGQsIHhtbE5TLCBibG9ja0FycmF5c0luKTtcbiAgICAgICAgICAgIGRvbS5hcHBlbmRDaGlsZChpbm5lcik7XG4gICAgICAgICAgICBpZiAoaW5uZXJDb250ZW50KSB7XG4gICAgICAgICAgICAgICAgaWYgKGNvbnRlbnRET00pXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiTXVsdGlwbGUgY29udGVudCBob2xlc1wiKTtcbiAgICAgICAgICAgICAgICBjb250ZW50RE9NID0gaW5uZXJDb250ZW50O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7IGRvbSwgY29udGVudERPTSB9O1xufVxuXG5leHBvcnQgeyBDb250ZW50TWF0Y2gsIERPTVBhcnNlciwgRE9NU2VyaWFsaXplciwgRnJhZ21lbnQsIE1hcmssIE1hcmtUeXBlLCBOb2RlLCBOb2RlUmFuZ2UsIE5vZGVUeXBlLCBSZXBsYWNlRXJyb3IsIFJlc29sdmVkUG9zLCBTY2hlbWEsIFNsaWNlIH07XG4iLCAiaW1wb3J0IHsgUmVwbGFjZUVycm9yLCBTbGljZSwgRnJhZ21lbnQsIE1hcmtUeXBlLCBNYXJrIH0gZnJvbSAncHJvc2VtaXJyb3ItbW9kZWwnO1xuXG4vLyBSZWNvdmVyeSB2YWx1ZXMgZW5jb2RlIGEgcmFuZ2UgaW5kZXggYW5kIGFuIG9mZnNldC4gVGhleSBhcmVcbi8vIHJlcHJlc2VudGVkIGFzIG51bWJlcnMsIGJlY2F1c2UgdG9ucyBvZiB0aGVtIHdpbGwgYmUgY3JlYXRlZCB3aGVuXG4vLyBtYXBwaW5nLCBmb3IgZXhhbXBsZSwgYSBsYXJnZSBudW1iZXIgb2YgZGVjb3JhdGlvbnMuIFRoZSBudW1iZXInc1xuLy8gbG93ZXIgMTYgYml0cyBwcm92aWRlIHRoZSBpbmRleCwgdGhlIHJlbWFpbmluZyBiaXRzIHRoZSBvZmZzZXQuXG4vL1xuLy8gTm90ZTogV2UgaW50ZW50aW9uYWxseSBkb24ndCB1c2UgYml0IHNoaWZ0IG9wZXJhdG9ycyB0byBlbi0gYW5kXG4vLyBkZWNvZGUgdGhlc2UsIHNpbmNlIHRob3NlIGNsaXAgdG8gMzIgYml0cywgd2hpY2ggd2UgbWlnaHQgaW4gcmFyZVxuLy8gY2FzZXMgd2FudCB0byBvdmVyZmxvdy4gQSA2NC1iaXQgZmxvYXQgY2FuIHJlcHJlc2VudCA0OC1iaXRcbi8vIGludGVnZXJzIHByZWNpc2VseS5cbmNvbnN0IGxvd2VyMTYgPSAweGZmZmY7XG5jb25zdCBmYWN0b3IxNiA9IE1hdGgucG93KDIsIDE2KTtcbmZ1bmN0aW9uIG1ha2VSZWNvdmVyKGluZGV4LCBvZmZzZXQpIHsgcmV0dXJuIGluZGV4ICsgb2Zmc2V0ICogZmFjdG9yMTY7IH1cbmZ1bmN0aW9uIHJlY292ZXJJbmRleCh2YWx1ZSkgeyByZXR1cm4gdmFsdWUgJiBsb3dlcjE2OyB9XG5mdW5jdGlvbiByZWNvdmVyT2Zmc2V0KHZhbHVlKSB7IHJldHVybiAodmFsdWUgLSAodmFsdWUgJiBsb3dlcjE2KSkgLyBmYWN0b3IxNjsgfVxuY29uc3QgREVMX0JFRk9SRSA9IDEsIERFTF9BRlRFUiA9IDIsIERFTF9BQ1JPU1MgPSA0LCBERUxfU0lERSA9IDg7XG4vKipcbkFuIG9iamVjdCByZXByZXNlbnRpbmcgYSBtYXBwZWQgcG9zaXRpb24gd2l0aCBleHRyYVxuaW5mb3JtYXRpb24uXG4qL1xuY2xhc3MgTWFwUmVzdWx0IHtcbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgIFRoZSBtYXBwZWQgdmVyc2lvbiBvZiB0aGUgcG9zaXRpb24uXG4gICAgKi9cbiAgICBwb3MsIFxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgZGVsSW5mbywgXG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICByZWNvdmVyKSB7XG4gICAgICAgIHRoaXMucG9zID0gcG9zO1xuICAgICAgICB0aGlzLmRlbEluZm8gPSBkZWxJbmZvO1xuICAgICAgICB0aGlzLnJlY292ZXIgPSByZWNvdmVyO1xuICAgIH1cbiAgICAvKipcbiAgICBUZWxscyB5b3Ugd2hldGhlciB0aGUgcG9zaXRpb24gd2FzIGRlbGV0ZWQsIHRoYXQgaXMsIHdoZXRoZXIgdGhlXG4gICAgc3RlcCByZW1vdmVkIHRoZSB0b2tlbiBvbiB0aGUgc2lkZSBxdWVyaWVkICh2aWEgdGhlIGBhc3NvY2ApXG4gICAgYXJndW1lbnQgZnJvbSB0aGUgZG9jdW1lbnQuXG4gICAgKi9cbiAgICBnZXQgZGVsZXRlZCgpIHsgcmV0dXJuICh0aGlzLmRlbEluZm8gJiBERUxfU0lERSkgPiAwOyB9XG4gICAgLyoqXG4gICAgVGVsbHMgeW91IHdoZXRoZXIgdGhlIHRva2VuIGJlZm9yZSB0aGUgbWFwcGVkIHBvc2l0aW9uIHdhcyBkZWxldGVkLlxuICAgICovXG4gICAgZ2V0IGRlbGV0ZWRCZWZvcmUoKSB7IHJldHVybiAodGhpcy5kZWxJbmZvICYgKERFTF9CRUZPUkUgfCBERUxfQUNST1NTKSkgPiAwOyB9XG4gICAgLyoqXG4gICAgVHJ1ZSB3aGVuIHRoZSB0b2tlbiBhZnRlciB0aGUgbWFwcGVkIHBvc2l0aW9uIHdhcyBkZWxldGVkLlxuICAgICovXG4gICAgZ2V0IGRlbGV0ZWRBZnRlcigpIHsgcmV0dXJuICh0aGlzLmRlbEluZm8gJiAoREVMX0FGVEVSIHwgREVMX0FDUk9TUykpID4gMDsgfVxuICAgIC8qKlxuICAgIFRlbGxzIHdoZXRoZXIgYW55IG9mIHRoZSBzdGVwcyBtYXBwZWQgdGhyb3VnaCBkZWxldGVzIGFjcm9zcyB0aGVcbiAgICBwb3NpdGlvbiAoaW5jbHVkaW5nIGJvdGggdGhlIHRva2VuIGJlZm9yZSBhbmQgYWZ0ZXIgdGhlXG4gICAgcG9zaXRpb24pLlxuICAgICovXG4gICAgZ2V0IGRlbGV0ZWRBY3Jvc3MoKSB7IHJldHVybiAodGhpcy5kZWxJbmZvICYgREVMX0FDUk9TUykgPiAwOyB9XG59XG4vKipcbkEgbWFwIGRlc2NyaWJpbmcgdGhlIGRlbGV0aW9ucyBhbmQgaW5zZXJ0aW9ucyBtYWRlIGJ5IGEgc3RlcCwgd2hpY2hcbmNhbiBiZSB1c2VkIHRvIGZpbmQgdGhlIGNvcnJlc3BvbmRlbmNlIGJldHdlZW4gcG9zaXRpb25zIGluIHRoZVxucHJlLXN0ZXAgdmVyc2lvbiBvZiBhIGRvY3VtZW50IGFuZCB0aGUgc2FtZSBwb3NpdGlvbiBpbiB0aGVcbnBvc3Qtc3RlcCB2ZXJzaW9uLlxuKi9cbmNsYXNzIFN0ZXBNYXAge1xuICAgIC8qKlxuICAgIENyZWF0ZSBhIHBvc2l0aW9uIG1hcC4gVGhlIG1vZGlmaWNhdGlvbnMgdG8gdGhlIGRvY3VtZW50IGFyZVxuICAgIHJlcHJlc2VudGVkIGFzIGFuIGFycmF5IG9mIG51bWJlcnMsIGluIHdoaWNoIGVhY2ggZ3JvdXAgb2YgdGhyZWVcbiAgICByZXByZXNlbnRzIGEgbW9kaWZpZWQgY2h1bmsgYXMgYFtzdGFydCwgb2xkU2l6ZSwgbmV3U2l6ZV1gLlxuICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICByYW5nZXMsIFxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgaW52ZXJ0ZWQgPSBmYWxzZSkge1xuICAgICAgICB0aGlzLnJhbmdlcyA9IHJhbmdlcztcbiAgICAgICAgdGhpcy5pbnZlcnRlZCA9IGludmVydGVkO1xuICAgICAgICBpZiAoIXJhbmdlcy5sZW5ndGggJiYgU3RlcE1hcC5lbXB0eSlcbiAgICAgICAgICAgIHJldHVybiBTdGVwTWFwLmVtcHR5O1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHJlY292ZXIodmFsdWUpIHtcbiAgICAgICAgbGV0IGRpZmYgPSAwLCBpbmRleCA9IHJlY292ZXJJbmRleCh2YWx1ZSk7XG4gICAgICAgIGlmICghdGhpcy5pbnZlcnRlZClcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5kZXg7IGkrKylcbiAgICAgICAgICAgICAgICBkaWZmICs9IHRoaXMucmFuZ2VzW2kgKiAzICsgMl0gLSB0aGlzLnJhbmdlc1tpICogMyArIDFdO1xuICAgICAgICByZXR1cm4gdGhpcy5yYW5nZXNbaW5kZXggKiAzXSArIGRpZmYgKyByZWNvdmVyT2Zmc2V0KHZhbHVlKTtcbiAgICB9XG4gICAgbWFwUmVzdWx0KHBvcywgYXNzb2MgPSAxKSB7IHJldHVybiB0aGlzLl9tYXAocG9zLCBhc3NvYywgZmFsc2UpOyB9XG4gICAgbWFwKHBvcywgYXNzb2MgPSAxKSB7IHJldHVybiB0aGlzLl9tYXAocG9zLCBhc3NvYywgdHJ1ZSk7IH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIF9tYXAocG9zLCBhc3NvYywgc2ltcGxlKSB7XG4gICAgICAgIGxldCBkaWZmID0gMCwgb2xkSW5kZXggPSB0aGlzLmludmVydGVkID8gMiA6IDEsIG5ld0luZGV4ID0gdGhpcy5pbnZlcnRlZCA/IDEgOiAyO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMucmFuZ2VzLmxlbmd0aDsgaSArPSAzKSB7XG4gICAgICAgICAgICBsZXQgc3RhcnQgPSB0aGlzLnJhbmdlc1tpXSAtICh0aGlzLmludmVydGVkID8gZGlmZiA6IDApO1xuICAgICAgICAgICAgaWYgKHN0YXJ0ID4gcG9zKVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgbGV0IG9sZFNpemUgPSB0aGlzLnJhbmdlc1tpICsgb2xkSW5kZXhdLCBuZXdTaXplID0gdGhpcy5yYW5nZXNbaSArIG5ld0luZGV4XSwgZW5kID0gc3RhcnQgKyBvbGRTaXplO1xuICAgICAgICAgICAgaWYgKHBvcyA8PSBlbmQpIHtcbiAgICAgICAgICAgICAgICBsZXQgc2lkZSA9ICFvbGRTaXplID8gYXNzb2MgOiBwb3MgPT0gc3RhcnQgPyAtMSA6IHBvcyA9PSBlbmQgPyAxIDogYXNzb2M7XG4gICAgICAgICAgICAgICAgbGV0IHJlc3VsdCA9IHN0YXJ0ICsgZGlmZiArIChzaWRlIDwgMCA/IDAgOiBuZXdTaXplKTtcbiAgICAgICAgICAgICAgICBpZiAoc2ltcGxlKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICAgIGxldCByZWNvdmVyID0gcG9zID09IChhc3NvYyA8IDAgPyBzdGFydCA6IGVuZCkgPyBudWxsIDogbWFrZVJlY292ZXIoaSAvIDMsIHBvcyAtIHN0YXJ0KTtcbiAgICAgICAgICAgICAgICBsZXQgZGVsID0gcG9zID09IHN0YXJ0ID8gREVMX0FGVEVSIDogcG9zID09IGVuZCA/IERFTF9CRUZPUkUgOiBERUxfQUNST1NTO1xuICAgICAgICAgICAgICAgIGlmIChhc3NvYyA8IDAgPyBwb3MgIT0gc3RhcnQgOiBwb3MgIT0gZW5kKVxuICAgICAgICAgICAgICAgICAgICBkZWwgfD0gREVMX1NJREU7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBNYXBSZXN1bHQocmVzdWx0LCBkZWwsIHJlY292ZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGlmZiArPSBuZXdTaXplIC0gb2xkU2l6ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc2ltcGxlID8gcG9zICsgZGlmZiA6IG5ldyBNYXBSZXN1bHQocG9zICsgZGlmZiwgMCwgbnVsbCk7XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgdG91Y2hlcyhwb3MsIHJlY292ZXIpIHtcbiAgICAgICAgbGV0IGRpZmYgPSAwLCBpbmRleCA9IHJlY292ZXJJbmRleChyZWNvdmVyKTtcbiAgICAgICAgbGV0IG9sZEluZGV4ID0gdGhpcy5pbnZlcnRlZCA/IDIgOiAxLCBuZXdJbmRleCA9IHRoaXMuaW52ZXJ0ZWQgPyAxIDogMjtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnJhbmdlcy5sZW5ndGg7IGkgKz0gMykge1xuICAgICAgICAgICAgbGV0IHN0YXJ0ID0gdGhpcy5yYW5nZXNbaV0gLSAodGhpcy5pbnZlcnRlZCA/IGRpZmYgOiAwKTtcbiAgICAgICAgICAgIGlmIChzdGFydCA+IHBvcylcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGxldCBvbGRTaXplID0gdGhpcy5yYW5nZXNbaSArIG9sZEluZGV4XSwgZW5kID0gc3RhcnQgKyBvbGRTaXplO1xuICAgICAgICAgICAgaWYgKHBvcyA8PSBlbmQgJiYgaSA9PSBpbmRleCAqIDMpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICBkaWZmICs9IHRoaXMucmFuZ2VzW2kgKyBuZXdJbmRleF0gLSBvbGRTaXplO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ2FsbHMgdGhlIGdpdmVuIGZ1bmN0aW9uIG9uIGVhY2ggb2YgdGhlIGNoYW5nZWQgcmFuZ2VzIGluY2x1ZGVkIGluXG4gICAgdGhpcyBtYXAuXG4gICAgKi9cbiAgICBmb3JFYWNoKGYpIHtcbiAgICAgICAgbGV0IG9sZEluZGV4ID0gdGhpcy5pbnZlcnRlZCA/IDIgOiAxLCBuZXdJbmRleCA9IHRoaXMuaW52ZXJ0ZWQgPyAxIDogMjtcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGRpZmYgPSAwOyBpIDwgdGhpcy5yYW5nZXMubGVuZ3RoOyBpICs9IDMpIHtcbiAgICAgICAgICAgIGxldCBzdGFydCA9IHRoaXMucmFuZ2VzW2ldLCBvbGRTdGFydCA9IHN0YXJ0IC0gKHRoaXMuaW52ZXJ0ZWQgPyBkaWZmIDogMCksIG5ld1N0YXJ0ID0gc3RhcnQgKyAodGhpcy5pbnZlcnRlZCA/IDAgOiBkaWZmKTtcbiAgICAgICAgICAgIGxldCBvbGRTaXplID0gdGhpcy5yYW5nZXNbaSArIG9sZEluZGV4XSwgbmV3U2l6ZSA9IHRoaXMucmFuZ2VzW2kgKyBuZXdJbmRleF07XG4gICAgICAgICAgICBmKG9sZFN0YXJ0LCBvbGRTdGFydCArIG9sZFNpemUsIG5ld1N0YXJ0LCBuZXdTdGFydCArIG5ld1NpemUpO1xuICAgICAgICAgICAgZGlmZiArPSBuZXdTaXplIC0gb2xkU2l6ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICBDcmVhdGUgYW4gaW52ZXJ0ZWQgdmVyc2lvbiBvZiB0aGlzIG1hcC4gVGhlIHJlc3VsdCBjYW4gYmUgdXNlZCB0b1xuICAgIG1hcCBwb3NpdGlvbnMgaW4gdGhlIHBvc3Qtc3RlcCBkb2N1bWVudCB0byB0aGUgcHJlLXN0ZXAgZG9jdW1lbnQuXG4gICAgKi9cbiAgICBpbnZlcnQoKSB7XG4gICAgICAgIHJldHVybiBuZXcgU3RlcE1hcCh0aGlzLnJhbmdlcywgIXRoaXMuaW52ZXJ0ZWQpO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHRvU3RyaW5nKCkge1xuICAgICAgICByZXR1cm4gKHRoaXMuaW52ZXJ0ZWQgPyBcIi1cIiA6IFwiXCIpICsgSlNPTi5zdHJpbmdpZnkodGhpcy5yYW5nZXMpO1xuICAgIH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSBtYXAgdGhhdCBtb3ZlcyBhbGwgcG9zaXRpb25zIGJ5IG9mZnNldCBgbmAgKHdoaWNoIG1heSBiZVxuICAgIG5lZ2F0aXZlKS4gVGhpcyBjYW4gYmUgdXNlZnVsIHdoZW4gYXBwbHlpbmcgc3RlcHMgbWVhbnQgZm9yIGFcbiAgICBzdWItZG9jdW1lbnQgdG8gYSBsYXJnZXIgZG9jdW1lbnQsIG9yIHZpY2UtdmVyc2EuXG4gICAgKi9cbiAgICBzdGF0aWMgb2Zmc2V0KG4pIHtcbiAgICAgICAgcmV0dXJuIG4gPT0gMCA/IFN0ZXBNYXAuZW1wdHkgOiBuZXcgU3RlcE1hcChuIDwgMCA/IFswLCAtbiwgMF0gOiBbMCwgMCwgbl0pO1xuICAgIH1cbn1cbi8qKlxuQSBTdGVwTWFwIHRoYXQgY29udGFpbnMgbm8gY2hhbmdlZCByYW5nZXMuXG4qL1xuU3RlcE1hcC5lbXB0eSA9IG5ldyBTdGVwTWFwKFtdKTtcbi8qKlxuQSBtYXBwaW5nIHJlcHJlc2VudHMgYSBwaXBlbGluZSBvZiB6ZXJvIG9yIG1vcmUgW3N0ZXBcbm1hcHNdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyN0cmFuc2Zvcm0uU3RlcE1hcCkuIEl0IGhhcyBzcGVjaWFsIHByb3Zpc2lvbnMgZm9yIGxvc3NsZXNzbHlcbmhhbmRsaW5nIG1hcHBpbmcgcG9zaXRpb25zIHRocm91Z2ggYSBzZXJpZXMgb2Ygc3RlcHMgaW4gd2hpY2ggc29tZVxuc3RlcHMgYXJlIGludmVydGVkIHZlcnNpb25zIG9mIGVhcmxpZXIgc3RlcHMuIChUaGlzIGNvbWVzIHVwIHdoZW5cblx1MjAxOFtyZWJhc2luZ10oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9ndWlkZS8jdHJhbnNmb3JtLnJlYmFzaW5nKVx1MjAxOSBzdGVwcyBmb3JcbmNvbGxhYm9yYXRpb24gb3IgaGlzdG9yeSBtYW5hZ2VtZW50LilcbiovXG5jbGFzcyBNYXBwaW5nIHtcbiAgICAvKipcbiAgICBDcmVhdGUgYSBuZXcgbWFwcGluZyB3aXRoIHRoZSBnaXZlbiBwb3NpdGlvbiBtYXBzLlxuICAgICovXG4gICAgY29uc3RydWN0b3IobWFwcywgXG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBtaXJyb3IsIFxuICAgIC8qKlxuICAgIFRoZSBzdGFydGluZyBwb3NpdGlvbiBpbiB0aGUgYG1hcHNgIGFycmF5LCB1c2VkIHdoZW4gYG1hcGAgb3JcbiAgICBgbWFwUmVzdWx0YCBpcyBjYWxsZWQuXG4gICAgKi9cbiAgICBmcm9tID0gMCwgXG4gICAgLyoqXG4gICAgVGhlIGVuZCBwb3NpdGlvbiBpbiB0aGUgYG1hcHNgIGFycmF5LlxuICAgICovXG4gICAgdG8gPSBtYXBzID8gbWFwcy5sZW5ndGggOiAwKSB7XG4gICAgICAgIHRoaXMubWlycm9yID0gbWlycm9yO1xuICAgICAgICB0aGlzLmZyb20gPSBmcm9tO1xuICAgICAgICB0aGlzLnRvID0gdG87XG4gICAgICAgIHRoaXMuX21hcHMgPSBtYXBzIHx8IFtdO1xuICAgICAgICB0aGlzLm93bkRhdGEgPSAhKG1hcHMgfHwgbWlycm9yKTtcbiAgICB9XG4gICAgLyoqXG4gICAgVGhlIHN0ZXAgbWFwcyBpbiB0aGlzIG1hcHBpbmcuXG4gICAgKi9cbiAgICBnZXQgbWFwcygpIHsgcmV0dXJuIHRoaXMuX21hcHM7IH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSBtYXBwaW5nIHRoYXQgbWFwcyBvbmx5IHRocm91Z2ggYSBwYXJ0IG9mIHRoaXMgb25lLlxuICAgICovXG4gICAgc2xpY2UoZnJvbSA9IDAsIHRvID0gdGhpcy5tYXBzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gbmV3IE1hcHBpbmcodGhpcy5fbWFwcywgdGhpcy5taXJyb3IsIGZyb20sIHRvKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQWRkIGEgc3RlcCBtYXAgdG8gdGhlIGVuZCBvZiB0aGlzIG1hcHBpbmcuIElmIGBtaXJyb3JzYCBpc1xuICAgIGdpdmVuLCBpdCBzaG91bGQgYmUgdGhlIGluZGV4IG9mIHRoZSBzdGVwIG1hcCB0aGF0IGlzIHRoZSBtaXJyb3JcbiAgICBpbWFnZSBvZiB0aGlzIG9uZS5cbiAgICAqL1xuICAgIGFwcGVuZE1hcChtYXAsIG1pcnJvcnMpIHtcbiAgICAgICAgaWYgKCF0aGlzLm93bkRhdGEpIHtcbiAgICAgICAgICAgIHRoaXMuX21hcHMgPSB0aGlzLl9tYXBzLnNsaWNlKCk7XG4gICAgICAgICAgICB0aGlzLm1pcnJvciA9IHRoaXMubWlycm9yICYmIHRoaXMubWlycm9yLnNsaWNlKCk7XG4gICAgICAgICAgICB0aGlzLm93bkRhdGEgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudG8gPSB0aGlzLl9tYXBzLnB1c2gobWFwKTtcbiAgICAgICAgaWYgKG1pcnJvcnMgIT0gbnVsbClcbiAgICAgICAgICAgIHRoaXMuc2V0TWlycm9yKHRoaXMuX21hcHMubGVuZ3RoIC0gMSwgbWlycm9ycyk7XG4gICAgfVxuICAgIC8qKlxuICAgIEFkZCBhbGwgdGhlIHN0ZXAgbWFwcyBpbiBhIGdpdmVuIG1hcHBpbmcgdG8gdGhpcyBvbmUgKHByZXNlcnZpbmdcbiAgICBtaXJyb3JpbmcgaW5mb3JtYXRpb24pLlxuICAgICovXG4gICAgYXBwZW5kTWFwcGluZyhtYXBwaW5nKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBzdGFydFNpemUgPSB0aGlzLl9tYXBzLmxlbmd0aDsgaSA8IG1hcHBpbmcuX21hcHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBtaXJyID0gbWFwcGluZy5nZXRNaXJyb3IoaSk7XG4gICAgICAgICAgICB0aGlzLmFwcGVuZE1hcChtYXBwaW5nLl9tYXBzW2ldLCBtaXJyICE9IG51bGwgJiYgbWlyciA8IGkgPyBzdGFydFNpemUgKyBtaXJyIDogdW5kZWZpbmVkKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICBGaW5kcyB0aGUgb2Zmc2V0IG9mIHRoZSBzdGVwIG1hcCB0aGF0IG1pcnJvcnMgdGhlIG1hcCBhdCB0aGVcbiAgICBnaXZlbiBvZmZzZXQsIGluIHRoaXMgbWFwcGluZyAoYXMgcGVyIHRoZSBzZWNvbmQgYXJndW1lbnQgdG9cbiAgICBgYXBwZW5kTWFwYCkuXG4gICAgKi9cbiAgICBnZXRNaXJyb3Iobikge1xuICAgICAgICBpZiAodGhpcy5taXJyb3IpXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubWlycm9yLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLm1pcnJvcltpXSA9PSBuKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5taXJyb3JbaSArIChpICUgMiA/IC0xIDogMSldO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHNldE1pcnJvcihuLCBtKSB7XG4gICAgICAgIGlmICghdGhpcy5taXJyb3IpXG4gICAgICAgICAgICB0aGlzLm1pcnJvciA9IFtdO1xuICAgICAgICB0aGlzLm1pcnJvci5wdXNoKG4sIG0pO1xuICAgIH1cbiAgICAvKipcbiAgICBBcHBlbmQgdGhlIGludmVyc2Ugb2YgdGhlIGdpdmVuIG1hcHBpbmcgdG8gdGhpcyBvbmUuXG4gICAgKi9cbiAgICBhcHBlbmRNYXBwaW5nSW52ZXJ0ZWQobWFwcGluZykge1xuICAgICAgICBmb3IgKGxldCBpID0gbWFwcGluZy5tYXBzLmxlbmd0aCAtIDEsIHRvdGFsU2l6ZSA9IHRoaXMuX21hcHMubGVuZ3RoICsgbWFwcGluZy5fbWFwcy5sZW5ndGg7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICBsZXQgbWlyciA9IG1hcHBpbmcuZ2V0TWlycm9yKGkpO1xuICAgICAgICAgICAgdGhpcy5hcHBlbmRNYXAobWFwcGluZy5fbWFwc1tpXS5pbnZlcnQoKSwgbWlyciAhPSBudWxsICYmIG1pcnIgPiBpID8gdG90YWxTaXplIC0gbWlyciAtIDEgOiB1bmRlZmluZWQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgIENyZWF0ZSBhbiBpbnZlcnRlZCB2ZXJzaW9uIG9mIHRoaXMgbWFwcGluZy5cbiAgICAqL1xuICAgIGludmVydCgpIHtcbiAgICAgICAgbGV0IGludmVyc2UgPSBuZXcgTWFwcGluZztcbiAgICAgICAgaW52ZXJzZS5hcHBlbmRNYXBwaW5nSW52ZXJ0ZWQodGhpcyk7XG4gICAgICAgIHJldHVybiBpbnZlcnNlO1xuICAgIH1cbiAgICAvKipcbiAgICBNYXAgYSBwb3NpdGlvbiB0aHJvdWdoIHRoaXMgbWFwcGluZy5cbiAgICAqL1xuICAgIG1hcChwb3MsIGFzc29jID0gMSkge1xuICAgICAgICBpZiAodGhpcy5taXJyb3IpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fbWFwKHBvcywgYXNzb2MsIHRydWUpO1xuICAgICAgICBmb3IgKGxldCBpID0gdGhpcy5mcm9tOyBpIDwgdGhpcy50bzsgaSsrKVxuICAgICAgICAgICAgcG9zID0gdGhpcy5fbWFwc1tpXS5tYXAocG9zLCBhc3NvYyk7XG4gICAgICAgIHJldHVybiBwb3M7XG4gICAgfVxuICAgIC8qKlxuICAgIE1hcCBhIHBvc2l0aW9uIHRocm91Z2ggdGhpcyBtYXBwaW5nLCByZXR1cm5pbmcgYSBtYXBwaW5nXG4gICAgcmVzdWx0LlxuICAgICovXG4gICAgbWFwUmVzdWx0KHBvcywgYXNzb2MgPSAxKSB7IHJldHVybiB0aGlzLl9tYXAocG9zLCBhc3NvYywgZmFsc2UpOyB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBfbWFwKHBvcywgYXNzb2MsIHNpbXBsZSkge1xuICAgICAgICBsZXQgZGVsSW5mbyA9IDA7XG4gICAgICAgIGZvciAobGV0IGkgPSB0aGlzLmZyb207IGkgPCB0aGlzLnRvOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBtYXAgPSB0aGlzLl9tYXBzW2ldLCByZXN1bHQgPSBtYXAubWFwUmVzdWx0KHBvcywgYXNzb2MpO1xuICAgICAgICAgICAgaWYgKHJlc3VsdC5yZWNvdmVyICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICBsZXQgY29yciA9IHRoaXMuZ2V0TWlycm9yKGkpO1xuICAgICAgICAgICAgICAgIGlmIChjb3JyICE9IG51bGwgJiYgY29yciA+IGkgJiYgY29yciA8IHRoaXMudG8pIHtcbiAgICAgICAgICAgICAgICAgICAgaSA9IGNvcnI7XG4gICAgICAgICAgICAgICAgICAgIHBvcyA9IHRoaXMuX21hcHNbY29ycl0ucmVjb3ZlcihyZXN1bHQucmVjb3Zlcik7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRlbEluZm8gfD0gcmVzdWx0LmRlbEluZm87XG4gICAgICAgICAgICBwb3MgPSByZXN1bHQucG9zO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzaW1wbGUgPyBwb3MgOiBuZXcgTWFwUmVzdWx0KHBvcywgZGVsSW5mbywgbnVsbCk7XG4gICAgfVxufVxuXG5jb25zdCBzdGVwc0J5SUQgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuLyoqXG5BIHN0ZXAgb2JqZWN0IHJlcHJlc2VudHMgYW4gYXRvbWljIGNoYW5nZS4gSXQgZ2VuZXJhbGx5IGFwcGxpZXNcbm9ubHkgdG8gdGhlIGRvY3VtZW50IGl0IHdhcyBjcmVhdGVkIGZvciwgc2luY2UgdGhlIHBvc2l0aW9uc1xuc3RvcmVkIGluIGl0IHdpbGwgb25seSBtYWtlIHNlbnNlIGZvciB0aGF0IGRvY3VtZW50LlxuXG5OZXcgc3RlcHMgYXJlIGRlZmluZWQgYnkgY3JlYXRpbmcgY2xhc3NlcyB0aGF0IGV4dGVuZCBgU3RlcGAsXG5vdmVycmlkaW5nIHRoZSBgYXBwbHlgLCBgaW52ZXJ0YCwgYG1hcGAsIGBnZXRNYXBgIGFuZCBgZnJvbUpTT05gXG5tZXRob2RzLCBhbmQgcmVnaXN0ZXJpbmcgeW91ciBjbGFzcyB3aXRoIGEgdW5pcXVlXG5KU09OLXNlcmlhbGl6YXRpb24gaWRlbnRpZmllciB1c2luZ1xuW2BTdGVwLmpzb25JRGBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyN0cmFuc2Zvcm0uU3RlcF5qc29uSUQpLlxuKi9cbmNsYXNzIFN0ZXAge1xuICAgIC8qKlxuICAgIEdldCB0aGUgc3RlcCBtYXAgdGhhdCByZXByZXNlbnRzIHRoZSBjaGFuZ2VzIG1hZGUgYnkgdGhpcyBzdGVwLFxuICAgIGFuZCB3aGljaCBjYW4gYmUgdXNlZCB0byB0cmFuc2Zvcm0gYmV0d2VlbiBwb3NpdGlvbnMgaW4gdGhlIG9sZFxuICAgIGFuZCB0aGUgbmV3IGRvY3VtZW50LlxuICAgICovXG4gICAgZ2V0TWFwKCkgeyByZXR1cm4gU3RlcE1hcC5lbXB0eTsgfVxuICAgIC8qKlxuICAgIFRyeSB0byBtZXJnZSB0aGlzIHN0ZXAgd2l0aCBhbm90aGVyIG9uZSwgdG8gYmUgYXBwbGllZCBkaXJlY3RseVxuICAgIGFmdGVyIGl0LiBSZXR1cm5zIHRoZSBtZXJnZWQgc3RlcCB3aGVuIHBvc3NpYmxlLCBudWxsIGlmIHRoZVxuICAgIHN0ZXBzIGNhbid0IGJlIG1lcmdlZC5cbiAgICAqL1xuICAgIG1lcmdlKG90aGVyKSB7IHJldHVybiBudWxsOyB9XG4gICAgLyoqXG4gICAgRGVzZXJpYWxpemUgYSBzdGVwIGZyb20gaXRzIEpTT04gcmVwcmVzZW50YXRpb24uIFdpbGwgY2FsbFxuICAgIHRocm91Z2ggdG8gdGhlIHN0ZXAgY2xhc3MnIG93biBpbXBsZW1lbnRhdGlvbiBvZiB0aGlzIG1ldGhvZC5cbiAgICAqL1xuICAgIHN0YXRpYyBmcm9tSlNPTihzY2hlbWEsIGpzb24pIHtcbiAgICAgICAgaWYgKCFqc29uIHx8ICFqc29uLnN0ZXBUeXBlKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIGlucHV0IGZvciBTdGVwLmZyb21KU09OXCIpO1xuICAgICAgICBsZXQgdHlwZSA9IHN0ZXBzQnlJRFtqc29uLnN0ZXBUeXBlXTtcbiAgICAgICAgaWYgKCF0eXBlKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoYE5vIHN0ZXAgdHlwZSAke2pzb24uc3RlcFR5cGV9IGRlZmluZWRgKTtcbiAgICAgICAgcmV0dXJuIHR5cGUuZnJvbUpTT04oc2NoZW1hLCBqc29uKTtcbiAgICB9XG4gICAgLyoqXG4gICAgVG8gYmUgYWJsZSB0byBzZXJpYWxpemUgc3RlcHMgdG8gSlNPTiwgZWFjaCBzdGVwIG5lZWRzIGEgc3RyaW5nXG4gICAgSUQgdG8gYXR0YWNoIHRvIGl0cyBKU09OIHJlcHJlc2VudGF0aW9uLiBVc2UgdGhpcyBtZXRob2QgdG9cbiAgICByZWdpc3RlciBhbiBJRCBmb3IgeW91ciBzdGVwIGNsYXNzZXMuIFRyeSB0byBwaWNrIHNvbWV0aGluZ1xuICAgIHRoYXQncyB1bmxpa2VseSB0byBjbGFzaCB3aXRoIHN0ZXBzIGZyb20gb3RoZXIgbW9kdWxlcy5cbiAgICAqL1xuICAgIHN0YXRpYyBqc29uSUQoaWQsIHN0ZXBDbGFzcykge1xuICAgICAgICBpZiAoaWQgaW4gc3RlcHNCeUlEKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJEdXBsaWNhdGUgdXNlIG9mIHN0ZXAgSlNPTiBJRCBcIiArIGlkKTtcbiAgICAgICAgc3RlcHNCeUlEW2lkXSA9IHN0ZXBDbGFzcztcbiAgICAgICAgc3RlcENsYXNzLnByb3RvdHlwZS5qc29uSUQgPSBpZDtcbiAgICAgICAgcmV0dXJuIHN0ZXBDbGFzcztcbiAgICB9XG59XG4vKipcblRoZSByZXN1bHQgb2YgW2FwcGx5aW5nXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jdHJhbnNmb3JtLlN0ZXAuYXBwbHkpIGEgc3RlcC4gQ29udGFpbnMgZWl0aGVyIGFcbm5ldyBkb2N1bWVudCBvciBhIGZhaWx1cmUgdmFsdWUuXG4qL1xuY2xhc3MgU3RlcFJlc3VsdCB7XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBUaGUgdHJhbnNmb3JtZWQgZG9jdW1lbnQsIGlmIHN1Y2Nlc3NmdWwuXG4gICAgKi9cbiAgICBkb2MsIFxuICAgIC8qKlxuICAgIFRoZSBmYWlsdXJlIG1lc3NhZ2UsIGlmIHVuc3VjY2Vzc2Z1bC5cbiAgICAqL1xuICAgIGZhaWxlZCkge1xuICAgICAgICB0aGlzLmRvYyA9IGRvYztcbiAgICAgICAgdGhpcy5mYWlsZWQgPSBmYWlsZWQ7XG4gICAgfVxuICAgIC8qKlxuICAgIENyZWF0ZSBhIHN1Y2Nlc3NmdWwgc3RlcCByZXN1bHQuXG4gICAgKi9cbiAgICBzdGF0aWMgb2soZG9jKSB7IHJldHVybiBuZXcgU3RlcFJlc3VsdChkb2MsIG51bGwpOyB9XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgZmFpbGVkIHN0ZXAgcmVzdWx0LlxuICAgICovXG4gICAgc3RhdGljIGZhaWwobWVzc2FnZSkgeyByZXR1cm4gbmV3IFN0ZXBSZXN1bHQobnVsbCwgbWVzc2FnZSk7IH1cbiAgICAvKipcbiAgICBDYWxsIFtgTm9kZS5yZXBsYWNlYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGUucmVwbGFjZSkgd2l0aCB0aGUgZ2l2ZW5cbiAgICBhcmd1bWVudHMuIENyZWF0ZSBhIHN1Y2Nlc3NmdWwgcmVzdWx0IGlmIGl0IHN1Y2NlZWRzLCBhbmQgYVxuICAgIGZhaWxlZCBvbmUgaWYgaXQgdGhyb3dzIGEgYFJlcGxhY2VFcnJvcmAuXG4gICAgKi9cbiAgICBzdGF0aWMgZnJvbVJlcGxhY2UoZG9jLCBmcm9tLCB0bywgc2xpY2UpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBTdGVwUmVzdWx0Lm9rKGRvYy5yZXBsYWNlKGZyb20sIHRvLCBzbGljZSkpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIFJlcGxhY2VFcnJvcilcbiAgICAgICAgICAgICAgICByZXR1cm4gU3RlcFJlc3VsdC5mYWlsKGUubWVzc2FnZSk7XG4gICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBtYXBGcmFnbWVudChmcmFnbWVudCwgZiwgcGFyZW50KSB7XG4gICAgbGV0IG1hcHBlZCA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZnJhZ21lbnQuY2hpbGRDb3VudDsgaSsrKSB7XG4gICAgICAgIGxldCBjaGlsZCA9IGZyYWdtZW50LmNoaWxkKGkpO1xuICAgICAgICBpZiAoY2hpbGQuY29udGVudC5zaXplKVxuICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC5jb3B5KG1hcEZyYWdtZW50KGNoaWxkLmNvbnRlbnQsIGYsIGNoaWxkKSk7XG4gICAgICAgIGlmIChjaGlsZC5pc0lubGluZSlcbiAgICAgICAgICAgIGNoaWxkID0gZihjaGlsZCwgcGFyZW50LCBpKTtcbiAgICAgICAgbWFwcGVkLnB1c2goY2hpbGQpO1xuICAgIH1cbiAgICByZXR1cm4gRnJhZ21lbnQuZnJvbUFycmF5KG1hcHBlZCk7XG59XG4vKipcbkFkZCBhIG1hcmsgdG8gYWxsIGlubGluZSBjb250ZW50IGJldHdlZW4gdHdvIHBvc2l0aW9ucy5cbiovXG5jbGFzcyBBZGRNYXJrU3RlcCBleHRlbmRzIFN0ZXAge1xuICAgIC8qKlxuICAgIENyZWF0ZSBhIG1hcmsgc3RlcC5cbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgIFRoZSBzdGFydCBvZiB0aGUgbWFya2VkIHJhbmdlLlxuICAgICovXG4gICAgZnJvbSwgXG4gICAgLyoqXG4gICAgVGhlIGVuZCBvZiB0aGUgbWFya2VkIHJhbmdlLlxuICAgICovXG4gICAgdG8sIFxuICAgIC8qKlxuICAgIFRoZSBtYXJrIHRvIGFkZC5cbiAgICAqL1xuICAgIG1hcmspIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5mcm9tID0gZnJvbTtcbiAgICAgICAgdGhpcy50byA9IHRvO1xuICAgICAgICB0aGlzLm1hcmsgPSBtYXJrO1xuICAgIH1cbiAgICBhcHBseShkb2MpIHtcbiAgICAgICAgbGV0IG9sZFNsaWNlID0gZG9jLnNsaWNlKHRoaXMuZnJvbSwgdGhpcy50byksICRmcm9tID0gZG9jLnJlc29sdmUodGhpcy5mcm9tKTtcbiAgICAgICAgbGV0IHBhcmVudCA9ICRmcm9tLm5vZGUoJGZyb20uc2hhcmVkRGVwdGgodGhpcy50bykpO1xuICAgICAgICBsZXQgc2xpY2UgPSBuZXcgU2xpY2UobWFwRnJhZ21lbnQob2xkU2xpY2UuY29udGVudCwgKG5vZGUsIHBhcmVudCkgPT4ge1xuICAgICAgICAgICAgaWYgKCFub2RlLmlzQXRvbSB8fCAhcGFyZW50LnR5cGUuYWxsb3dzTWFya1R5cGUodGhpcy5tYXJrLnR5cGUpKVxuICAgICAgICAgICAgICAgIHJldHVybiBub2RlO1xuICAgICAgICAgICAgcmV0dXJuIG5vZGUubWFyayh0aGlzLm1hcmsuYWRkVG9TZXQobm9kZS5tYXJrcykpO1xuICAgICAgICB9LCBwYXJlbnQpLCBvbGRTbGljZS5vcGVuU3RhcnQsIG9sZFNsaWNlLm9wZW5FbmQpO1xuICAgICAgICByZXR1cm4gU3RlcFJlc3VsdC5mcm9tUmVwbGFjZShkb2MsIHRoaXMuZnJvbSwgdGhpcy50bywgc2xpY2UpO1xuICAgIH1cbiAgICBpbnZlcnQoKSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVtb3ZlTWFya1N0ZXAodGhpcy5mcm9tLCB0aGlzLnRvLCB0aGlzLm1hcmspO1xuICAgIH1cbiAgICBtYXAobWFwcGluZykge1xuICAgICAgICBsZXQgZnJvbSA9IG1hcHBpbmcubWFwUmVzdWx0KHRoaXMuZnJvbSwgMSksIHRvID0gbWFwcGluZy5tYXBSZXN1bHQodGhpcy50bywgLTEpO1xuICAgICAgICBpZiAoZnJvbS5kZWxldGVkICYmIHRvLmRlbGV0ZWQgfHwgZnJvbS5wb3MgPj0gdG8ucG9zKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIHJldHVybiBuZXcgQWRkTWFya1N0ZXAoZnJvbS5wb3MsIHRvLnBvcywgdGhpcy5tYXJrKTtcbiAgICB9XG4gICAgbWVyZ2Uob3RoZXIpIHtcbiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgQWRkTWFya1N0ZXAgJiZcbiAgICAgICAgICAgIG90aGVyLm1hcmsuZXEodGhpcy5tYXJrKSAmJlxuICAgICAgICAgICAgdGhpcy5mcm9tIDw9IG90aGVyLnRvICYmIHRoaXMudG8gPj0gb3RoZXIuZnJvbSlcbiAgICAgICAgICAgIHJldHVybiBuZXcgQWRkTWFya1N0ZXAoTWF0aC5taW4odGhpcy5mcm9tLCBvdGhlci5mcm9tKSwgTWF0aC5tYXgodGhpcy50bywgb3RoZXIudG8pLCB0aGlzLm1hcmspO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgdG9KU09OKCkge1xuICAgICAgICByZXR1cm4geyBzdGVwVHlwZTogXCJhZGRNYXJrXCIsIG1hcms6IHRoaXMubWFyay50b0pTT04oKSxcbiAgICAgICAgICAgIGZyb206IHRoaXMuZnJvbSwgdG86IHRoaXMudG8gfTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBzdGF0aWMgZnJvbUpTT04oc2NoZW1hLCBqc29uKSB7XG4gICAgICAgIGlmICh0eXBlb2YganNvbi5mcm9tICE9IFwibnVtYmVyXCIgfHwgdHlwZW9mIGpzb24udG8gIT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiSW52YWxpZCBpbnB1dCBmb3IgQWRkTWFya1N0ZXAuZnJvbUpTT05cIik7XG4gICAgICAgIHJldHVybiBuZXcgQWRkTWFya1N0ZXAoanNvbi5mcm9tLCBqc29uLnRvLCBzY2hlbWEubWFya0Zyb21KU09OKGpzb24ubWFyaykpO1xuICAgIH1cbn1cblN0ZXAuanNvbklEKFwiYWRkTWFya1wiLCBBZGRNYXJrU3RlcCk7XG4vKipcblJlbW92ZSBhIG1hcmsgZnJvbSBhbGwgaW5saW5lIGNvbnRlbnQgYmV0d2VlbiB0d28gcG9zaXRpb25zLlxuKi9cbmNsYXNzIFJlbW92ZU1hcmtTdGVwIGV4dGVuZHMgU3RlcCB7XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgbWFyay1yZW1vdmluZyBzdGVwLlxuICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgVGhlIHN0YXJ0IG9mIHRoZSB1bm1hcmtlZCByYW5nZS5cbiAgICAqL1xuICAgIGZyb20sIFxuICAgIC8qKlxuICAgIFRoZSBlbmQgb2YgdGhlIHVubWFya2VkIHJhbmdlLlxuICAgICovXG4gICAgdG8sIFxuICAgIC8qKlxuICAgIFRoZSBtYXJrIHRvIHJlbW92ZS5cbiAgICAqL1xuICAgIG1hcmspIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5mcm9tID0gZnJvbTtcbiAgICAgICAgdGhpcy50byA9IHRvO1xuICAgICAgICB0aGlzLm1hcmsgPSBtYXJrO1xuICAgIH1cbiAgICBhcHBseShkb2MpIHtcbiAgICAgICAgbGV0IG9sZFNsaWNlID0gZG9jLnNsaWNlKHRoaXMuZnJvbSwgdGhpcy50byk7XG4gICAgICAgIGxldCBzbGljZSA9IG5ldyBTbGljZShtYXBGcmFnbWVudChvbGRTbGljZS5jb250ZW50LCBub2RlID0+IHtcbiAgICAgICAgICAgIHJldHVybiBub2RlLm1hcmsodGhpcy5tYXJrLnJlbW92ZUZyb21TZXQobm9kZS5tYXJrcykpO1xuICAgICAgICB9LCBkb2MpLCBvbGRTbGljZS5vcGVuU3RhcnQsIG9sZFNsaWNlLm9wZW5FbmQpO1xuICAgICAgICByZXR1cm4gU3RlcFJlc3VsdC5mcm9tUmVwbGFjZShkb2MsIHRoaXMuZnJvbSwgdGhpcy50bywgc2xpY2UpO1xuICAgIH1cbiAgICBpbnZlcnQoKSB7XG4gICAgICAgIHJldHVybiBuZXcgQWRkTWFya1N0ZXAodGhpcy5mcm9tLCB0aGlzLnRvLCB0aGlzLm1hcmspO1xuICAgIH1cbiAgICBtYXAobWFwcGluZykge1xuICAgICAgICBsZXQgZnJvbSA9IG1hcHBpbmcubWFwUmVzdWx0KHRoaXMuZnJvbSwgMSksIHRvID0gbWFwcGluZy5tYXBSZXN1bHQodGhpcy50bywgLTEpO1xuICAgICAgICBpZiAoZnJvbS5kZWxldGVkICYmIHRvLmRlbGV0ZWQgfHwgZnJvbS5wb3MgPj0gdG8ucG9zKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIHJldHVybiBuZXcgUmVtb3ZlTWFya1N0ZXAoZnJvbS5wb3MsIHRvLnBvcywgdGhpcy5tYXJrKTtcbiAgICB9XG4gICAgbWVyZ2Uob3RoZXIpIHtcbiAgICAgICAgaWYgKG90aGVyIGluc3RhbmNlb2YgUmVtb3ZlTWFya1N0ZXAgJiZcbiAgICAgICAgICAgIG90aGVyLm1hcmsuZXEodGhpcy5tYXJrKSAmJlxuICAgICAgICAgICAgdGhpcy5mcm9tIDw9IG90aGVyLnRvICYmIHRoaXMudG8gPj0gb3RoZXIuZnJvbSlcbiAgICAgICAgICAgIHJldHVybiBuZXcgUmVtb3ZlTWFya1N0ZXAoTWF0aC5taW4odGhpcy5mcm9tLCBvdGhlci5mcm9tKSwgTWF0aC5tYXgodGhpcy50bywgb3RoZXIudG8pLCB0aGlzLm1hcmspO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgdG9KU09OKCkge1xuICAgICAgICByZXR1cm4geyBzdGVwVHlwZTogXCJyZW1vdmVNYXJrXCIsIG1hcms6IHRoaXMubWFyay50b0pTT04oKSxcbiAgICAgICAgICAgIGZyb206IHRoaXMuZnJvbSwgdG86IHRoaXMudG8gfTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBzdGF0aWMgZnJvbUpTT04oc2NoZW1hLCBqc29uKSB7XG4gICAgICAgIGlmICh0eXBlb2YganNvbi5mcm9tICE9IFwibnVtYmVyXCIgfHwgdHlwZW9mIGpzb24udG8gIT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiSW52YWxpZCBpbnB1dCBmb3IgUmVtb3ZlTWFya1N0ZXAuZnJvbUpTT05cIik7XG4gICAgICAgIHJldHVybiBuZXcgUmVtb3ZlTWFya1N0ZXAoanNvbi5mcm9tLCBqc29uLnRvLCBzY2hlbWEubWFya0Zyb21KU09OKGpzb24ubWFyaykpO1xuICAgIH1cbn1cblN0ZXAuanNvbklEKFwicmVtb3ZlTWFya1wiLCBSZW1vdmVNYXJrU3RlcCk7XG4vKipcbkFkZCBhIG1hcmsgdG8gYSBzcGVjaWZpYyBub2RlLlxuKi9cbmNsYXNzIEFkZE5vZGVNYXJrU3RlcCBleHRlbmRzIFN0ZXAge1xuICAgIC8qKlxuICAgIENyZWF0ZSBhIG5vZGUgbWFyayBzdGVwLlxuICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgVGhlIHBvc2l0aW9uIG9mIHRoZSB0YXJnZXQgbm9kZS5cbiAgICAqL1xuICAgIHBvcywgXG4gICAgLyoqXG4gICAgVGhlIG1hcmsgdG8gYWRkLlxuICAgICovXG4gICAgbWFyaykge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLnBvcyA9IHBvcztcbiAgICAgICAgdGhpcy5tYXJrID0gbWFyaztcbiAgICB9XG4gICAgYXBwbHkoZG9jKSB7XG4gICAgICAgIGxldCBub2RlID0gZG9jLm5vZGVBdCh0aGlzLnBvcyk7XG4gICAgICAgIGlmICghbm9kZSlcbiAgICAgICAgICAgIHJldHVybiBTdGVwUmVzdWx0LmZhaWwoXCJObyBub2RlIGF0IG1hcmsgc3RlcCdzIHBvc2l0aW9uXCIpO1xuICAgICAgICBsZXQgdXBkYXRlZCA9IG5vZGUudHlwZS5jcmVhdGUobm9kZS5hdHRycywgbnVsbCwgdGhpcy5tYXJrLmFkZFRvU2V0KG5vZGUubWFya3MpKTtcbiAgICAgICAgcmV0dXJuIFN0ZXBSZXN1bHQuZnJvbVJlcGxhY2UoZG9jLCB0aGlzLnBvcywgdGhpcy5wb3MgKyAxLCBuZXcgU2xpY2UoRnJhZ21lbnQuZnJvbSh1cGRhdGVkKSwgMCwgbm9kZS5pc0xlYWYgPyAwIDogMSkpO1xuICAgIH1cbiAgICBpbnZlcnQoZG9jKSB7XG4gICAgICAgIGxldCBub2RlID0gZG9jLm5vZGVBdCh0aGlzLnBvcyk7XG4gICAgICAgIGlmIChub2RlKSB7XG4gICAgICAgICAgICBsZXQgbmV3U2V0ID0gdGhpcy5tYXJrLmFkZFRvU2V0KG5vZGUubWFya3MpO1xuICAgICAgICAgICAgaWYgKG5ld1NldC5sZW5ndGggPT0gbm9kZS5tYXJrcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vZGUubWFya3MubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICAgICAgICAgIGlmICghbm9kZS5tYXJrc1tpXS5pc0luU2V0KG5ld1NldCkpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEFkZE5vZGVNYXJrU3RlcCh0aGlzLnBvcywgbm9kZS5tYXJrc1tpXSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBBZGROb2RlTWFya1N0ZXAodGhpcy5wb3MsIHRoaXMubWFyayk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBSZW1vdmVOb2RlTWFya1N0ZXAodGhpcy5wb3MsIHRoaXMubWFyayk7XG4gICAgfVxuICAgIG1hcChtYXBwaW5nKSB7XG4gICAgICAgIGxldCBwb3MgPSBtYXBwaW5nLm1hcFJlc3VsdCh0aGlzLnBvcywgMSk7XG4gICAgICAgIHJldHVybiBwb3MuZGVsZXRlZEFmdGVyID8gbnVsbCA6IG5ldyBBZGROb2RlTWFya1N0ZXAocG9zLnBvcywgdGhpcy5tYXJrKTtcbiAgICB9XG4gICAgdG9KU09OKCkge1xuICAgICAgICByZXR1cm4geyBzdGVwVHlwZTogXCJhZGROb2RlTWFya1wiLCBwb3M6IHRoaXMucG9zLCBtYXJrOiB0aGlzLm1hcmsudG9KU09OKCkgfTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBzdGF0aWMgZnJvbUpTT04oc2NoZW1hLCBqc29uKSB7XG4gICAgICAgIGlmICh0eXBlb2YganNvbi5wb3MgIT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiSW52YWxpZCBpbnB1dCBmb3IgQWRkTm9kZU1hcmtTdGVwLmZyb21KU09OXCIpO1xuICAgICAgICByZXR1cm4gbmV3IEFkZE5vZGVNYXJrU3RlcChqc29uLnBvcywgc2NoZW1hLm1hcmtGcm9tSlNPTihqc29uLm1hcmspKTtcbiAgICB9XG59XG5TdGVwLmpzb25JRChcImFkZE5vZGVNYXJrXCIsIEFkZE5vZGVNYXJrU3RlcCk7XG4vKipcblJlbW92ZSBhIG1hcmsgZnJvbSBhIHNwZWNpZmljIG5vZGUuXG4qL1xuY2xhc3MgUmVtb3ZlTm9kZU1hcmtTdGVwIGV4dGVuZHMgU3RlcCB7XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgbWFyay1yZW1vdmluZyBzdGVwLlxuICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgLyoqXG4gICAgVGhlIHBvc2l0aW9uIG9mIHRoZSB0YXJnZXQgbm9kZS5cbiAgICAqL1xuICAgIHBvcywgXG4gICAgLyoqXG4gICAgVGhlIG1hcmsgdG8gcmVtb3ZlLlxuICAgICovXG4gICAgbWFyaykge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLnBvcyA9IHBvcztcbiAgICAgICAgdGhpcy5tYXJrID0gbWFyaztcbiAgICB9XG4gICAgYXBwbHkoZG9jKSB7XG4gICAgICAgIGxldCBub2RlID0gZG9jLm5vZGVBdCh0aGlzLnBvcyk7XG4gICAgICAgIGlmICghbm9kZSlcbiAgICAgICAgICAgIHJldHVybiBTdGVwUmVzdWx0LmZhaWwoXCJObyBub2RlIGF0IG1hcmsgc3RlcCdzIHBvc2l0aW9uXCIpO1xuICAgICAgICBsZXQgdXBkYXRlZCA9IG5vZGUudHlwZS5jcmVhdGUobm9kZS5hdHRycywgbnVsbCwgdGhpcy5tYXJrLnJlbW92ZUZyb21TZXQobm9kZS5tYXJrcykpO1xuICAgICAgICByZXR1cm4gU3RlcFJlc3VsdC5mcm9tUmVwbGFjZShkb2MsIHRoaXMucG9zLCB0aGlzLnBvcyArIDEsIG5ldyBTbGljZShGcmFnbWVudC5mcm9tKHVwZGF0ZWQpLCAwLCBub2RlLmlzTGVhZiA/IDAgOiAxKSk7XG4gICAgfVxuICAgIGludmVydChkb2MpIHtcbiAgICAgICAgbGV0IG5vZGUgPSBkb2Mubm9kZUF0KHRoaXMucG9zKTtcbiAgICAgICAgaWYgKCFub2RlIHx8ICF0aGlzLm1hcmsuaXNJblNldChub2RlLm1hcmtzKSlcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICByZXR1cm4gbmV3IEFkZE5vZGVNYXJrU3RlcCh0aGlzLnBvcywgdGhpcy5tYXJrKTtcbiAgICB9XG4gICAgbWFwKG1hcHBpbmcpIHtcbiAgICAgICAgbGV0IHBvcyA9IG1hcHBpbmcubWFwUmVzdWx0KHRoaXMucG9zLCAxKTtcbiAgICAgICAgcmV0dXJuIHBvcy5kZWxldGVkQWZ0ZXIgPyBudWxsIDogbmV3IFJlbW92ZU5vZGVNYXJrU3RlcChwb3MucG9zLCB0aGlzLm1hcmspO1xuICAgIH1cbiAgICB0b0pTT04oKSB7XG4gICAgICAgIHJldHVybiB7IHN0ZXBUeXBlOiBcInJlbW92ZU5vZGVNYXJrXCIsIHBvczogdGhpcy5wb3MsIG1hcms6IHRoaXMubWFyay50b0pTT04oKSB9O1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHN0YXRpYyBmcm9tSlNPTihzY2hlbWEsIGpzb24pIHtcbiAgICAgICAgaWYgKHR5cGVvZiBqc29uLnBvcyAhPSBcIm51bWJlclwiKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIGlucHV0IGZvciBSZW1vdmVOb2RlTWFya1N0ZXAuZnJvbUpTT05cIik7XG4gICAgICAgIHJldHVybiBuZXcgUmVtb3ZlTm9kZU1hcmtTdGVwKGpzb24ucG9zLCBzY2hlbWEubWFya0Zyb21KU09OKGpzb24ubWFyaykpO1xuICAgIH1cbn1cblN0ZXAuanNvbklEKFwicmVtb3ZlTm9kZU1hcmtcIiwgUmVtb3ZlTm9kZU1hcmtTdGVwKTtcblxuLyoqXG5SZXBsYWNlIGEgcGFydCBvZiB0aGUgZG9jdW1lbnQgd2l0aCBhIHNsaWNlIG9mIG5ldyBjb250ZW50LlxuKi9cbmNsYXNzIFJlcGxhY2VTdGVwIGV4dGVuZHMgU3RlcCB7XG4gICAgLyoqXG4gICAgVGhlIGdpdmVuIGBzbGljZWAgc2hvdWxkIGZpdCB0aGUgJ2dhcCcgYmV0d2VlbiBgZnJvbWAgYW5kXG4gICAgYHRvYFx1MjAxNHRoZSBkZXB0aHMgbXVzdCBsaW5lIHVwLCBhbmQgdGhlIHN1cnJvdW5kaW5nIG5vZGVzIG11c3QgYmVcbiAgICBhYmxlIHRvIGJlIGpvaW5lZCB3aXRoIHRoZSBvcGVuIHNpZGVzIG9mIHRoZSBzbGljZS4gV2hlblxuICAgIGBzdHJ1Y3R1cmVgIGlzIHRydWUsIHRoZSBzdGVwIHdpbGwgZmFpbCBpZiB0aGUgY29udGVudCBiZXR3ZWVuXG4gICAgZnJvbSBhbmQgdG8gaXMgbm90IGp1c3QgYSBzZXF1ZW5jZSBvZiBjbG9zaW5nIGFuZCB0aGVuIG9wZW5pbmdcbiAgICB0b2tlbnMgKHRoaXMgaXMgdG8gZ3VhcmQgYWdhaW5zdCByZWJhc2VkIHJlcGxhY2Ugc3RlcHNcbiAgICBvdmVyd3JpdGluZyBzb21ldGhpbmcgdGhleSB3ZXJlbid0IHN1cHBvc2VkIHRvKS5cbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgIFRoZSBzdGFydCBwb3NpdGlvbiBvZiB0aGUgcmVwbGFjZWQgcmFuZ2UuXG4gICAgKi9cbiAgICBmcm9tLCBcbiAgICAvKipcbiAgICBUaGUgZW5kIHBvc2l0aW9uIG9mIHRoZSByZXBsYWNlZCByYW5nZS5cbiAgICAqL1xuICAgIHRvLCBcbiAgICAvKipcbiAgICBUaGUgc2xpY2UgdG8gaW5zZXJ0LlxuICAgICovXG4gICAgc2xpY2UsIFxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgc3RydWN0dXJlID0gZmFsc2UpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5mcm9tID0gZnJvbTtcbiAgICAgICAgdGhpcy50byA9IHRvO1xuICAgICAgICB0aGlzLnNsaWNlID0gc2xpY2U7XG4gICAgICAgIHRoaXMuc3RydWN0dXJlID0gc3RydWN0dXJlO1xuICAgIH1cbiAgICBhcHBseShkb2MpIHtcbiAgICAgICAgaWYgKHRoaXMuc3RydWN0dXJlICYmIGNvbnRlbnRCZXR3ZWVuKGRvYywgdGhpcy5mcm9tLCB0aGlzLnRvKSlcbiAgICAgICAgICAgIHJldHVybiBTdGVwUmVzdWx0LmZhaWwoXCJTdHJ1Y3R1cmUgcmVwbGFjZSB3b3VsZCBvdmVyd3JpdGUgY29udGVudFwiKTtcbiAgICAgICAgcmV0dXJuIFN0ZXBSZXN1bHQuZnJvbVJlcGxhY2UoZG9jLCB0aGlzLmZyb20sIHRoaXMudG8sIHRoaXMuc2xpY2UpO1xuICAgIH1cbiAgICBnZXRNYXAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgU3RlcE1hcChbdGhpcy5mcm9tLCB0aGlzLnRvIC0gdGhpcy5mcm9tLCB0aGlzLnNsaWNlLnNpemVdKTtcbiAgICB9XG4gICAgaW52ZXJ0KGRvYykge1xuICAgICAgICByZXR1cm4gbmV3IFJlcGxhY2VTdGVwKHRoaXMuZnJvbSwgdGhpcy5mcm9tICsgdGhpcy5zbGljZS5zaXplLCBkb2Muc2xpY2UodGhpcy5mcm9tLCB0aGlzLnRvKSk7XG4gICAgfVxuICAgIG1hcChtYXBwaW5nKSB7XG4gICAgICAgIGxldCBmcm9tID0gbWFwcGluZy5tYXBSZXN1bHQodGhpcy5mcm9tLCAxKSwgdG8gPSBtYXBwaW5nLm1hcFJlc3VsdCh0aGlzLnRvLCAtMSk7XG4gICAgICAgIGlmIChmcm9tLmRlbGV0ZWRBY3Jvc3MgJiYgdG8uZGVsZXRlZEFjcm9zcylcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICByZXR1cm4gbmV3IFJlcGxhY2VTdGVwKGZyb20ucG9zLCBNYXRoLm1heChmcm9tLnBvcywgdG8ucG9zKSwgdGhpcy5zbGljZSwgdGhpcy5zdHJ1Y3R1cmUpO1xuICAgIH1cbiAgICBtZXJnZShvdGhlcikge1xuICAgICAgICBpZiAoIShvdGhlciBpbnN0YW5jZW9mIFJlcGxhY2VTdGVwKSB8fCBvdGhlci5zdHJ1Y3R1cmUgfHwgdGhpcy5zdHJ1Y3R1cmUpXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgaWYgKHRoaXMuZnJvbSArIHRoaXMuc2xpY2Uuc2l6ZSA9PSBvdGhlci5mcm9tICYmICF0aGlzLnNsaWNlLm9wZW5FbmQgJiYgIW90aGVyLnNsaWNlLm9wZW5TdGFydCkge1xuICAgICAgICAgICAgbGV0IHNsaWNlID0gdGhpcy5zbGljZS5zaXplICsgb3RoZXIuc2xpY2Uuc2l6ZSA9PSAwID8gU2xpY2UuZW1wdHlcbiAgICAgICAgICAgICAgICA6IG5ldyBTbGljZSh0aGlzLnNsaWNlLmNvbnRlbnQuYXBwZW5kKG90aGVyLnNsaWNlLmNvbnRlbnQpLCB0aGlzLnNsaWNlLm9wZW5TdGFydCwgb3RoZXIuc2xpY2Uub3BlbkVuZCk7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFJlcGxhY2VTdGVwKHRoaXMuZnJvbSwgdGhpcy50byArIChvdGhlci50byAtIG90aGVyLmZyb20pLCBzbGljZSwgdGhpcy5zdHJ1Y3R1cmUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG90aGVyLnRvID09IHRoaXMuZnJvbSAmJiAhdGhpcy5zbGljZS5vcGVuU3RhcnQgJiYgIW90aGVyLnNsaWNlLm9wZW5FbmQpIHtcbiAgICAgICAgICAgIGxldCBzbGljZSA9IHRoaXMuc2xpY2Uuc2l6ZSArIG90aGVyLnNsaWNlLnNpemUgPT0gMCA/IFNsaWNlLmVtcHR5XG4gICAgICAgICAgICAgICAgOiBuZXcgU2xpY2Uob3RoZXIuc2xpY2UuY29udGVudC5hcHBlbmQodGhpcy5zbGljZS5jb250ZW50KSwgb3RoZXIuc2xpY2Uub3BlblN0YXJ0LCB0aGlzLnNsaWNlLm9wZW5FbmQpO1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBSZXBsYWNlU3RlcChvdGhlci5mcm9tLCB0aGlzLnRvLCBzbGljZSwgdGhpcy5zdHJ1Y3R1cmUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgdG9KU09OKCkge1xuICAgICAgICBsZXQganNvbiA9IHsgc3RlcFR5cGU6IFwicmVwbGFjZVwiLCBmcm9tOiB0aGlzLmZyb20sIHRvOiB0aGlzLnRvIH07XG4gICAgICAgIGlmICh0aGlzLnNsaWNlLnNpemUpXG4gICAgICAgICAgICBqc29uLnNsaWNlID0gdGhpcy5zbGljZS50b0pTT04oKTtcbiAgICAgICAgaWYgKHRoaXMuc3RydWN0dXJlKVxuICAgICAgICAgICAganNvbi5zdHJ1Y3R1cmUgPSB0cnVlO1xuICAgICAgICByZXR1cm4ganNvbjtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBzdGF0aWMgZnJvbUpTT04oc2NoZW1hLCBqc29uKSB7XG4gICAgICAgIGlmICh0eXBlb2YganNvbi5mcm9tICE9IFwibnVtYmVyXCIgfHwgdHlwZW9mIGpzb24udG8gIT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiSW52YWxpZCBpbnB1dCBmb3IgUmVwbGFjZVN0ZXAuZnJvbUpTT05cIik7XG4gICAgICAgIHJldHVybiBuZXcgUmVwbGFjZVN0ZXAoanNvbi5mcm9tLCBqc29uLnRvLCBTbGljZS5mcm9tSlNPTihzY2hlbWEsIGpzb24uc2xpY2UpLCAhIWpzb24uc3RydWN0dXJlKTtcbiAgICB9XG59XG5TdGVwLmpzb25JRChcInJlcGxhY2VcIiwgUmVwbGFjZVN0ZXApO1xuLyoqXG5SZXBsYWNlIGEgcGFydCBvZiB0aGUgZG9jdW1lbnQgd2l0aCBhIHNsaWNlIG9mIGNvbnRlbnQsIGJ1dFxucHJlc2VydmUgYSByYW5nZSBvZiB0aGUgcmVwbGFjZWQgY29udGVudCBieSBtb3ZpbmcgaXQgaW50byB0aGVcbnNsaWNlLlxuKi9cbmNsYXNzIFJlcGxhY2VBcm91bmRTdGVwIGV4dGVuZHMgU3RlcCB7XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgcmVwbGFjZS1hcm91bmQgc3RlcCB3aXRoIHRoZSBnaXZlbiByYW5nZSBhbmQgZ2FwLlxuICAgIGBpbnNlcnRgIHNob3VsZCBiZSB0aGUgcG9pbnQgaW4gdGhlIHNsaWNlIGludG8gd2hpY2ggdGhlIGNvbnRlbnRcbiAgICBvZiB0aGUgZ2FwIHNob3VsZCBiZSBtb3ZlZC4gYHN0cnVjdHVyZWAgaGFzIHRoZSBzYW1lIG1lYW5pbmcgYXNcbiAgICBpdCBoYXMgaW4gdGhlIFtgUmVwbGFjZVN0ZXBgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jdHJhbnNmb3JtLlJlcGxhY2VTdGVwKSBjbGFzcy5cbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgIFRoZSBzdGFydCBwb3NpdGlvbiBvZiB0aGUgcmVwbGFjZWQgcmFuZ2UuXG4gICAgKi9cbiAgICBmcm9tLCBcbiAgICAvKipcbiAgICBUaGUgZW5kIHBvc2l0aW9uIG9mIHRoZSByZXBsYWNlZCByYW5nZS5cbiAgICAqL1xuICAgIHRvLCBcbiAgICAvKipcbiAgICBUaGUgc3RhcnQgb2YgcHJlc2VydmVkIHJhbmdlLlxuICAgICovXG4gICAgZ2FwRnJvbSwgXG4gICAgLyoqXG4gICAgVGhlIGVuZCBvZiBwcmVzZXJ2ZWQgcmFuZ2UuXG4gICAgKi9cbiAgICBnYXBUbywgXG4gICAgLyoqXG4gICAgVGhlIHNsaWNlIHRvIGluc2VydC5cbiAgICAqL1xuICAgIHNsaWNlLCBcbiAgICAvKipcbiAgICBUaGUgcG9zaXRpb24gaW4gdGhlIHNsaWNlIHdoZXJlIHRoZSBwcmVzZXJ2ZWQgcmFuZ2Ugc2hvdWxkIGJlXG4gICAgaW5zZXJ0ZWQuXG4gICAgKi9cbiAgICBpbnNlcnQsIFxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgc3RydWN0dXJlID0gZmFsc2UpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5mcm9tID0gZnJvbTtcbiAgICAgICAgdGhpcy50byA9IHRvO1xuICAgICAgICB0aGlzLmdhcEZyb20gPSBnYXBGcm9tO1xuICAgICAgICB0aGlzLmdhcFRvID0gZ2FwVG87XG4gICAgICAgIHRoaXMuc2xpY2UgPSBzbGljZTtcbiAgICAgICAgdGhpcy5pbnNlcnQgPSBpbnNlcnQ7XG4gICAgICAgIHRoaXMuc3RydWN0dXJlID0gc3RydWN0dXJlO1xuICAgIH1cbiAgICBhcHBseShkb2MpIHtcbiAgICAgICAgaWYgKHRoaXMuc3RydWN0dXJlICYmIChjb250ZW50QmV0d2Vlbihkb2MsIHRoaXMuZnJvbSwgdGhpcy5nYXBGcm9tKSB8fFxuICAgICAgICAgICAgY29udGVudEJldHdlZW4oZG9jLCB0aGlzLmdhcFRvLCB0aGlzLnRvKSkpXG4gICAgICAgICAgICByZXR1cm4gU3RlcFJlc3VsdC5mYWlsKFwiU3RydWN0dXJlIGdhcC1yZXBsYWNlIHdvdWxkIG92ZXJ3cml0ZSBjb250ZW50XCIpO1xuICAgICAgICBsZXQgZ2FwID0gZG9jLnNsaWNlKHRoaXMuZ2FwRnJvbSwgdGhpcy5nYXBUbyk7XG4gICAgICAgIGlmIChnYXAub3BlblN0YXJ0IHx8IGdhcC5vcGVuRW5kKVxuICAgICAgICAgICAgcmV0dXJuIFN0ZXBSZXN1bHQuZmFpbChcIkdhcCBpcyBub3QgYSBmbGF0IHJhbmdlXCIpO1xuICAgICAgICBsZXQgaW5zZXJ0ZWQgPSB0aGlzLnNsaWNlLmluc2VydEF0KHRoaXMuaW5zZXJ0LCBnYXAuY29udGVudCk7XG4gICAgICAgIGlmICghaW5zZXJ0ZWQpXG4gICAgICAgICAgICByZXR1cm4gU3RlcFJlc3VsdC5mYWlsKFwiQ29udGVudCBkb2VzIG5vdCBmaXQgaW4gZ2FwXCIpO1xuICAgICAgICByZXR1cm4gU3RlcFJlc3VsdC5mcm9tUmVwbGFjZShkb2MsIHRoaXMuZnJvbSwgdGhpcy50bywgaW5zZXJ0ZWQpO1xuICAgIH1cbiAgICBnZXRNYXAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgU3RlcE1hcChbdGhpcy5mcm9tLCB0aGlzLmdhcEZyb20gLSB0aGlzLmZyb20sIHRoaXMuaW5zZXJ0LFxuICAgICAgICAgICAgdGhpcy5nYXBUbywgdGhpcy50byAtIHRoaXMuZ2FwVG8sIHRoaXMuc2xpY2Uuc2l6ZSAtIHRoaXMuaW5zZXJ0XSk7XG4gICAgfVxuICAgIGludmVydChkb2MpIHtcbiAgICAgICAgbGV0IGdhcCA9IHRoaXMuZ2FwVG8gLSB0aGlzLmdhcEZyb207XG4gICAgICAgIHJldHVybiBuZXcgUmVwbGFjZUFyb3VuZFN0ZXAodGhpcy5mcm9tLCB0aGlzLmZyb20gKyB0aGlzLnNsaWNlLnNpemUgKyBnYXAsIHRoaXMuZnJvbSArIHRoaXMuaW5zZXJ0LCB0aGlzLmZyb20gKyB0aGlzLmluc2VydCArIGdhcCwgZG9jLnNsaWNlKHRoaXMuZnJvbSwgdGhpcy50bykucmVtb3ZlQmV0d2Vlbih0aGlzLmdhcEZyb20gLSB0aGlzLmZyb20sIHRoaXMuZ2FwVG8gLSB0aGlzLmZyb20pLCB0aGlzLmdhcEZyb20gLSB0aGlzLmZyb20sIHRoaXMuc3RydWN0dXJlKTtcbiAgICB9XG4gICAgbWFwKG1hcHBpbmcpIHtcbiAgICAgICAgbGV0IGZyb20gPSBtYXBwaW5nLm1hcFJlc3VsdCh0aGlzLmZyb20sIDEpLCB0byA9IG1hcHBpbmcubWFwUmVzdWx0KHRoaXMudG8sIC0xKTtcbiAgICAgICAgbGV0IGdhcEZyb20gPSB0aGlzLmZyb20gPT0gdGhpcy5nYXBGcm9tID8gZnJvbS5wb3MgOiBtYXBwaW5nLm1hcCh0aGlzLmdhcEZyb20sIC0xKTtcbiAgICAgICAgbGV0IGdhcFRvID0gdGhpcy50byA9PSB0aGlzLmdhcFRvID8gdG8ucG9zIDogbWFwcGluZy5tYXAodGhpcy5nYXBUbywgMSk7XG4gICAgICAgIGlmICgoZnJvbS5kZWxldGVkQWNyb3NzICYmIHRvLmRlbGV0ZWRBY3Jvc3MpIHx8IGdhcEZyb20gPCBmcm9tLnBvcyB8fCBnYXBUbyA+IHRvLnBvcylcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICByZXR1cm4gbmV3IFJlcGxhY2VBcm91bmRTdGVwKGZyb20ucG9zLCB0by5wb3MsIGdhcEZyb20sIGdhcFRvLCB0aGlzLnNsaWNlLCB0aGlzLmluc2VydCwgdGhpcy5zdHJ1Y3R1cmUpO1xuICAgIH1cbiAgICB0b0pTT04oKSB7XG4gICAgICAgIGxldCBqc29uID0geyBzdGVwVHlwZTogXCJyZXBsYWNlQXJvdW5kXCIsIGZyb206IHRoaXMuZnJvbSwgdG86IHRoaXMudG8sXG4gICAgICAgICAgICBnYXBGcm9tOiB0aGlzLmdhcEZyb20sIGdhcFRvOiB0aGlzLmdhcFRvLCBpbnNlcnQ6IHRoaXMuaW5zZXJ0IH07XG4gICAgICAgIGlmICh0aGlzLnNsaWNlLnNpemUpXG4gICAgICAgICAgICBqc29uLnNsaWNlID0gdGhpcy5zbGljZS50b0pTT04oKTtcbiAgICAgICAgaWYgKHRoaXMuc3RydWN0dXJlKVxuICAgICAgICAgICAganNvbi5zdHJ1Y3R1cmUgPSB0cnVlO1xuICAgICAgICByZXR1cm4ganNvbjtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBzdGF0aWMgZnJvbUpTT04oc2NoZW1hLCBqc29uKSB7XG4gICAgICAgIGlmICh0eXBlb2YganNvbi5mcm9tICE9IFwibnVtYmVyXCIgfHwgdHlwZW9mIGpzb24udG8gIT0gXCJudW1iZXJcIiB8fFxuICAgICAgICAgICAgdHlwZW9mIGpzb24uZ2FwRnJvbSAhPSBcIm51bWJlclwiIHx8IHR5cGVvZiBqc29uLmdhcFRvICE9IFwibnVtYmVyXCIgfHwgdHlwZW9mIGpzb24uaW5zZXJ0ICE9IFwibnVtYmVyXCIpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkludmFsaWQgaW5wdXQgZm9yIFJlcGxhY2VBcm91bmRTdGVwLmZyb21KU09OXCIpO1xuICAgICAgICByZXR1cm4gbmV3IFJlcGxhY2VBcm91bmRTdGVwKGpzb24uZnJvbSwganNvbi50bywganNvbi5nYXBGcm9tLCBqc29uLmdhcFRvLCBTbGljZS5mcm9tSlNPTihzY2hlbWEsIGpzb24uc2xpY2UpLCBqc29uLmluc2VydCwgISFqc29uLnN0cnVjdHVyZSk7XG4gICAgfVxufVxuU3RlcC5qc29uSUQoXCJyZXBsYWNlQXJvdW5kXCIsIFJlcGxhY2VBcm91bmRTdGVwKTtcbmZ1bmN0aW9uIGNvbnRlbnRCZXR3ZWVuKGRvYywgZnJvbSwgdG8pIHtcbiAgICBsZXQgJGZyb20gPSBkb2MucmVzb2x2ZShmcm9tKSwgZGlzdCA9IHRvIC0gZnJvbSwgZGVwdGggPSAkZnJvbS5kZXB0aDtcbiAgICB3aGlsZSAoZGlzdCA+IDAgJiYgZGVwdGggPiAwICYmICRmcm9tLmluZGV4QWZ0ZXIoZGVwdGgpID09ICRmcm9tLm5vZGUoZGVwdGgpLmNoaWxkQ291bnQpIHtcbiAgICAgICAgZGVwdGgtLTtcbiAgICAgICAgZGlzdC0tO1xuICAgIH1cbiAgICBpZiAoZGlzdCA+IDApIHtcbiAgICAgICAgbGV0IG5leHQgPSAkZnJvbS5ub2RlKGRlcHRoKS5tYXliZUNoaWxkKCRmcm9tLmluZGV4QWZ0ZXIoZGVwdGgpKTtcbiAgICAgICAgd2hpbGUgKGRpc3QgPiAwKSB7XG4gICAgICAgICAgICBpZiAoIW5leHQgfHwgbmV4dC5pc0xlYWYpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICBuZXh0ID0gbmV4dC5maXJzdENoaWxkO1xuICAgICAgICAgICAgZGlzdC0tO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gYWRkTWFyayh0ciwgZnJvbSwgdG8sIG1hcmspIHtcbiAgICBsZXQgcmVtb3ZlZCA9IFtdLCBhZGRlZCA9IFtdO1xuICAgIGxldCByZW1vdmluZywgYWRkaW5nO1xuICAgIHRyLmRvYy5ub2Rlc0JldHdlZW4oZnJvbSwgdG8sIChub2RlLCBwb3MsIHBhcmVudCkgPT4ge1xuICAgICAgICBpZiAoIW5vZGUuaXNJbmxpbmUpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIGxldCBtYXJrcyA9IG5vZGUubWFya3M7XG4gICAgICAgIGlmICghbWFyay5pc0luU2V0KG1hcmtzKSAmJiBwYXJlbnQudHlwZS5hbGxvd3NNYXJrVHlwZShtYXJrLnR5cGUpKSB7XG4gICAgICAgICAgICBsZXQgc3RhcnQgPSBNYXRoLm1heChwb3MsIGZyb20pLCBlbmQgPSBNYXRoLm1pbihwb3MgKyBub2RlLm5vZGVTaXplLCB0byk7XG4gICAgICAgICAgICBsZXQgbmV3U2V0ID0gbWFyay5hZGRUb1NldChtYXJrcyk7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1hcmtzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFtYXJrc1tpXS5pc0luU2V0KG5ld1NldCkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlbW92aW5nICYmIHJlbW92aW5nLnRvID09IHN0YXJ0ICYmIHJlbW92aW5nLm1hcmsuZXEobWFya3NbaV0pKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZpbmcudG8gPSBlbmQ7XG4gICAgICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZWQucHVzaChyZW1vdmluZyA9IG5ldyBSZW1vdmVNYXJrU3RlcChzdGFydCwgZW5kLCBtYXJrc1tpXSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChhZGRpbmcgJiYgYWRkaW5nLnRvID09IHN0YXJ0KVxuICAgICAgICAgICAgICAgIGFkZGluZy50byA9IGVuZDtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBhZGRlZC5wdXNoKGFkZGluZyA9IG5ldyBBZGRNYXJrU3RlcChzdGFydCwgZW5kLCBtYXJrKSk7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZW1vdmVkLmZvckVhY2gocyA9PiB0ci5zdGVwKHMpKTtcbiAgICBhZGRlZC5mb3JFYWNoKHMgPT4gdHIuc3RlcChzKSk7XG59XG5mdW5jdGlvbiByZW1vdmVNYXJrKHRyLCBmcm9tLCB0bywgbWFyaykge1xuICAgIGxldCBtYXRjaGVkID0gW10sIHN0ZXAgPSAwO1xuICAgIHRyLmRvYy5ub2Rlc0JldHdlZW4oZnJvbSwgdG8sIChub2RlLCBwb3MpID0+IHtcbiAgICAgICAgaWYgKCFub2RlLmlzSW5saW5lKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBzdGVwKys7XG4gICAgICAgIGxldCB0b1JlbW92ZSA9IG51bGw7XG4gICAgICAgIGlmIChtYXJrIGluc3RhbmNlb2YgTWFya1R5cGUpIHtcbiAgICAgICAgICAgIGxldCBzZXQgPSBub2RlLm1hcmtzLCBmb3VuZDtcbiAgICAgICAgICAgIHdoaWxlIChmb3VuZCA9IG1hcmsuaXNJblNldChzZXQpKSB7XG4gICAgICAgICAgICAgICAgKHRvUmVtb3ZlIHx8ICh0b1JlbW92ZSA9IFtdKSkucHVzaChmb3VuZCk7XG4gICAgICAgICAgICAgICAgc2V0ID0gZm91bmQucmVtb3ZlRnJvbVNldChzZXQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG1hcmspIHtcbiAgICAgICAgICAgIGlmIChtYXJrLmlzSW5TZXQobm9kZS5tYXJrcykpXG4gICAgICAgICAgICAgICAgdG9SZW1vdmUgPSBbbWFya107XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0b1JlbW92ZSA9IG5vZGUubWFya3M7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRvUmVtb3ZlICYmIHRvUmVtb3ZlLmxlbmd0aCkge1xuICAgICAgICAgICAgbGV0IGVuZCA9IE1hdGgubWluKHBvcyArIG5vZGUubm9kZVNpemUsIHRvKTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdG9SZW1vdmUubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBsZXQgc3R5bGUgPSB0b1JlbW92ZVtpXSwgZm91bmQ7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBtYXRjaGVkLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBtID0gbWF0Y2hlZFtqXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG0uc3RlcCA9PSBzdGVwIC0gMSAmJiBzdHlsZS5lcShtYXRjaGVkW2pdLnN0eWxlKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvdW5kID0gbTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGZvdW5kKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvdW5kLnRvID0gZW5kO1xuICAgICAgICAgICAgICAgICAgICBmb3VuZC5zdGVwID0gc3RlcDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIG1hdGNoZWQucHVzaCh7IHN0eWxlLCBmcm9tOiBNYXRoLm1heChwb3MsIGZyb20pLCB0bzogZW5kLCBzdGVwIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0pO1xuICAgIG1hdGNoZWQuZm9yRWFjaChtID0+IHRyLnN0ZXAobmV3IFJlbW92ZU1hcmtTdGVwKG0uZnJvbSwgbS50bywgbS5zdHlsZSkpKTtcbn1cbmZ1bmN0aW9uIGNsZWFySW5jb21wYXRpYmxlKHRyLCBwb3MsIHBhcmVudFR5cGUsIG1hdGNoID0gcGFyZW50VHlwZS5jb250ZW50TWF0Y2gsIGNsZWFyTmV3bGluZXMgPSB0cnVlKSB7XG4gICAgbGV0IG5vZGUgPSB0ci5kb2Mubm9kZUF0KHBvcyk7XG4gICAgbGV0IHJlcGxTdGVwcyA9IFtdLCBjdXIgPSBwb3MgKyAxO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbm9kZS5jaGlsZENvdW50OyBpKyspIHtcbiAgICAgICAgbGV0IGNoaWxkID0gbm9kZS5jaGlsZChpKSwgZW5kID0gY3VyICsgY2hpbGQubm9kZVNpemU7XG4gICAgICAgIGxldCBhbGxvd2VkID0gbWF0Y2gubWF0Y2hUeXBlKGNoaWxkLnR5cGUpO1xuICAgICAgICBpZiAoIWFsbG93ZWQpIHtcbiAgICAgICAgICAgIHJlcGxTdGVwcy5wdXNoKG5ldyBSZXBsYWNlU3RlcChjdXIsIGVuZCwgU2xpY2UuZW1wdHkpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIG1hdGNoID0gYWxsb3dlZDtcbiAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgY2hpbGQubWFya3MubGVuZ3RoOyBqKyspXG4gICAgICAgICAgICAgICAgaWYgKCFwYXJlbnRUeXBlLmFsbG93c01hcmtUeXBlKGNoaWxkLm1hcmtzW2pdLnR5cGUpKVxuICAgICAgICAgICAgICAgICAgICB0ci5zdGVwKG5ldyBSZW1vdmVNYXJrU3RlcChjdXIsIGVuZCwgY2hpbGQubWFya3Nbal0pKTtcbiAgICAgICAgICAgIGlmIChjbGVhck5ld2xpbmVzICYmIGNoaWxkLmlzVGV4dCAmJiBwYXJlbnRUeXBlLndoaXRlc3BhY2UgIT0gXCJwcmVcIikge1xuICAgICAgICAgICAgICAgIGxldCBtLCBuZXdsaW5lID0gL1xccj9cXG58XFxyL2csIHNsaWNlO1xuICAgICAgICAgICAgICAgIHdoaWxlIChtID0gbmV3bGluZS5leGVjKGNoaWxkLnRleHQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghc2xpY2UpXG4gICAgICAgICAgICAgICAgICAgICAgICBzbGljZSA9IG5ldyBTbGljZShGcmFnbWVudC5mcm9tKHBhcmVudFR5cGUuc2NoZW1hLnRleHQoXCIgXCIsIHBhcmVudFR5cGUuYWxsb3dlZE1hcmtzKGNoaWxkLm1hcmtzKSkpLCAwLCAwKTtcbiAgICAgICAgICAgICAgICAgICAgcmVwbFN0ZXBzLnB1c2gobmV3IFJlcGxhY2VTdGVwKGN1ciArIG0uaW5kZXgsIGN1ciArIG0uaW5kZXggKyBtWzBdLmxlbmd0aCwgc2xpY2UpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY3VyID0gZW5kO1xuICAgIH1cbiAgICBpZiAoIW1hdGNoLnZhbGlkRW5kKSB7XG4gICAgICAgIGxldCBmaWxsID0gbWF0Y2guZmlsbEJlZm9yZShGcmFnbWVudC5lbXB0eSwgdHJ1ZSk7XG4gICAgICAgIHRyLnJlcGxhY2UoY3VyLCBjdXIsIG5ldyBTbGljZShmaWxsLCAwLCAwKSk7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSByZXBsU3RlcHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pXG4gICAgICAgIHRyLnN0ZXAocmVwbFN0ZXBzW2ldKTtcbn1cblxuZnVuY3Rpb24gY2FuQ3V0KG5vZGUsIHN0YXJ0LCBlbmQpIHtcbiAgICByZXR1cm4gKHN0YXJ0ID09IDAgfHwgbm9kZS5jYW5SZXBsYWNlKHN0YXJ0LCBub2RlLmNoaWxkQ291bnQpKSAmJlxuICAgICAgICAoZW5kID09IG5vZGUuY2hpbGRDb3VudCB8fCBub2RlLmNhblJlcGxhY2UoMCwgZW5kKSk7XG59XG4vKipcblRyeSB0byBmaW5kIGEgdGFyZ2V0IGRlcHRoIHRvIHdoaWNoIHRoZSBjb250ZW50IGluIHRoZSBnaXZlbiByYW5nZVxuY2FuIGJlIGxpZnRlZC4gV2lsbCBub3QgZ28gYWNyb3NzXG5baXNvbGF0aW5nXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZVNwZWMuaXNvbGF0aW5nKSBwYXJlbnQgbm9kZXMuXG4qL1xuZnVuY3Rpb24gbGlmdFRhcmdldChyYW5nZSkge1xuICAgIGxldCBwYXJlbnQgPSByYW5nZS5wYXJlbnQ7XG4gICAgbGV0IGNvbnRlbnQgPSBwYXJlbnQuY29udGVudC5jdXRCeUluZGV4KHJhbmdlLnN0YXJ0SW5kZXgsIHJhbmdlLmVuZEluZGV4KTtcbiAgICBmb3IgKGxldCBkZXB0aCA9IHJhbmdlLmRlcHRoOzsgLS1kZXB0aCkge1xuICAgICAgICBsZXQgbm9kZSA9IHJhbmdlLiRmcm9tLm5vZGUoZGVwdGgpO1xuICAgICAgICBsZXQgaW5kZXggPSByYW5nZS4kZnJvbS5pbmRleChkZXB0aCksIGVuZEluZGV4ID0gcmFuZ2UuJHRvLmluZGV4QWZ0ZXIoZGVwdGgpO1xuICAgICAgICBpZiAoZGVwdGggPCByYW5nZS5kZXB0aCAmJiBub2RlLmNhblJlcGxhY2UoaW5kZXgsIGVuZEluZGV4LCBjb250ZW50KSlcbiAgICAgICAgICAgIHJldHVybiBkZXB0aDtcbiAgICAgICAgaWYgKGRlcHRoID09IDAgfHwgbm9kZS50eXBlLnNwZWMuaXNvbGF0aW5nIHx8ICFjYW5DdXQobm9kZSwgaW5kZXgsIGVuZEluZGV4KSlcbiAgICAgICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn1cbmZ1bmN0aW9uIGxpZnQodHIsIHJhbmdlLCB0YXJnZXQpIHtcbiAgICBsZXQgeyAkZnJvbSwgJHRvLCBkZXB0aCB9ID0gcmFuZ2U7XG4gICAgbGV0IGdhcFN0YXJ0ID0gJGZyb20uYmVmb3JlKGRlcHRoICsgMSksIGdhcEVuZCA9ICR0by5hZnRlcihkZXB0aCArIDEpO1xuICAgIGxldCBzdGFydCA9IGdhcFN0YXJ0LCBlbmQgPSBnYXBFbmQ7XG4gICAgbGV0IGJlZm9yZSA9IEZyYWdtZW50LmVtcHR5LCBvcGVuU3RhcnQgPSAwO1xuICAgIGZvciAobGV0IGQgPSBkZXB0aCwgc3BsaXR0aW5nID0gZmFsc2U7IGQgPiB0YXJnZXQ7IGQtLSlcbiAgICAgICAgaWYgKHNwbGl0dGluZyB8fCAkZnJvbS5pbmRleChkKSA+IDApIHtcbiAgICAgICAgICAgIHNwbGl0dGluZyA9IHRydWU7XG4gICAgICAgICAgICBiZWZvcmUgPSBGcmFnbWVudC5mcm9tKCRmcm9tLm5vZGUoZCkuY29weShiZWZvcmUpKTtcbiAgICAgICAgICAgIG9wZW5TdGFydCsrO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgc3RhcnQtLTtcbiAgICAgICAgfVxuICAgIGxldCBhZnRlciA9IEZyYWdtZW50LmVtcHR5LCBvcGVuRW5kID0gMDtcbiAgICBmb3IgKGxldCBkID0gZGVwdGgsIHNwbGl0dGluZyA9IGZhbHNlOyBkID4gdGFyZ2V0OyBkLS0pXG4gICAgICAgIGlmIChzcGxpdHRpbmcgfHwgJHRvLmFmdGVyKGQgKyAxKSA8ICR0by5lbmQoZCkpIHtcbiAgICAgICAgICAgIHNwbGl0dGluZyA9IHRydWU7XG4gICAgICAgICAgICBhZnRlciA9IEZyYWdtZW50LmZyb20oJHRvLm5vZGUoZCkuY29weShhZnRlcikpO1xuICAgICAgICAgICAgb3BlbkVuZCsrO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZW5kKys7XG4gICAgICAgIH1cbiAgICB0ci5zdGVwKG5ldyBSZXBsYWNlQXJvdW5kU3RlcChzdGFydCwgZW5kLCBnYXBTdGFydCwgZ2FwRW5kLCBuZXcgU2xpY2UoYmVmb3JlLmFwcGVuZChhZnRlciksIG9wZW5TdGFydCwgb3BlbkVuZCksIGJlZm9yZS5zaXplIC0gb3BlblN0YXJ0LCB0cnVlKSk7XG59XG4vKipcblRyeSB0byBmaW5kIGEgdmFsaWQgd2F5IHRvIHdyYXAgdGhlIGNvbnRlbnQgaW4gdGhlIGdpdmVuIHJhbmdlIGluIGFcbm5vZGUgb2YgdGhlIGdpdmVuIHR5cGUuIE1heSBpbnRyb2R1Y2UgZXh0cmEgbm9kZXMgYXJvdW5kIGFuZCBpbnNpZGVcbnRoZSB3cmFwcGVyIG5vZGUsIGlmIG5lY2Vzc2FyeS4gUmV0dXJucyBudWxsIGlmIG5vIHZhbGlkIHdyYXBwaW5nXG5jb3VsZCBiZSBmb3VuZC4gV2hlbiBgaW5uZXJSYW5nZWAgaXMgZ2l2ZW4sIHRoYXQgcmFuZ2UncyBjb250ZW50IGlzXG51c2VkIGFzIHRoZSBjb250ZW50IHRvIGZpdCBpbnRvIHRoZSB3cmFwcGluZywgaW5zdGVhZCBvZiB0aGVcbmNvbnRlbnQgb2YgYHJhbmdlYC5cbiovXG5mdW5jdGlvbiBmaW5kV3JhcHBpbmcocmFuZ2UsIG5vZGVUeXBlLCBhdHRycyA9IG51bGwsIGlubmVyUmFuZ2UgPSByYW5nZSkge1xuICAgIGxldCBhcm91bmQgPSBmaW5kV3JhcHBpbmdPdXRzaWRlKHJhbmdlLCBub2RlVHlwZSk7XG4gICAgbGV0IGlubmVyID0gYXJvdW5kICYmIGZpbmRXcmFwcGluZ0luc2lkZShpbm5lclJhbmdlLCBub2RlVHlwZSk7XG4gICAgaWYgKCFpbm5lcilcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIGFyb3VuZC5tYXAod2l0aEF0dHJzKVxuICAgICAgICAuY29uY2F0KHsgdHlwZTogbm9kZVR5cGUsIGF0dHJzIH0pLmNvbmNhdChpbm5lci5tYXAod2l0aEF0dHJzKSk7XG59XG5mdW5jdGlvbiB3aXRoQXR0cnModHlwZSkgeyByZXR1cm4geyB0eXBlLCBhdHRyczogbnVsbCB9OyB9XG5mdW5jdGlvbiBmaW5kV3JhcHBpbmdPdXRzaWRlKHJhbmdlLCB0eXBlKSB7XG4gICAgbGV0IHsgcGFyZW50LCBzdGFydEluZGV4LCBlbmRJbmRleCB9ID0gcmFuZ2U7XG4gICAgbGV0IGFyb3VuZCA9IHBhcmVudC5jb250ZW50TWF0Y2hBdChzdGFydEluZGV4KS5maW5kV3JhcHBpbmcodHlwZSk7XG4gICAgaWYgKCFhcm91bmQpXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIGxldCBvdXRlciA9IGFyb3VuZC5sZW5ndGggPyBhcm91bmRbMF0gOiB0eXBlO1xuICAgIHJldHVybiBwYXJlbnQuY2FuUmVwbGFjZVdpdGgoc3RhcnRJbmRleCwgZW5kSW5kZXgsIG91dGVyKSA/IGFyb3VuZCA6IG51bGw7XG59XG5mdW5jdGlvbiBmaW5kV3JhcHBpbmdJbnNpZGUocmFuZ2UsIHR5cGUpIHtcbiAgICBsZXQgeyBwYXJlbnQsIHN0YXJ0SW5kZXgsIGVuZEluZGV4IH0gPSByYW5nZTtcbiAgICBsZXQgaW5uZXIgPSBwYXJlbnQuY2hpbGQoc3RhcnRJbmRleCk7XG4gICAgbGV0IGluc2lkZSA9IHR5cGUuY29udGVudE1hdGNoLmZpbmRXcmFwcGluZyhpbm5lci50eXBlKTtcbiAgICBpZiAoIWluc2lkZSlcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgbGV0IGxhc3RUeXBlID0gaW5zaWRlLmxlbmd0aCA/IGluc2lkZVtpbnNpZGUubGVuZ3RoIC0gMV0gOiB0eXBlO1xuICAgIGxldCBpbm5lck1hdGNoID0gbGFzdFR5cGUuY29udGVudE1hdGNoO1xuICAgIGZvciAobGV0IGkgPSBzdGFydEluZGV4OyBpbm5lck1hdGNoICYmIGkgPCBlbmRJbmRleDsgaSsrKVxuICAgICAgICBpbm5lck1hdGNoID0gaW5uZXJNYXRjaC5tYXRjaFR5cGUocGFyZW50LmNoaWxkKGkpLnR5cGUpO1xuICAgIGlmICghaW5uZXJNYXRjaCB8fCAhaW5uZXJNYXRjaC52YWxpZEVuZClcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIGluc2lkZTtcbn1cbmZ1bmN0aW9uIHdyYXAodHIsIHJhbmdlLCB3cmFwcGVycykge1xuICAgIGxldCBjb250ZW50ID0gRnJhZ21lbnQuZW1wdHk7XG4gICAgZm9yIChsZXQgaSA9IHdyYXBwZXJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIGlmIChjb250ZW50LnNpemUpIHtcbiAgICAgICAgICAgIGxldCBtYXRjaCA9IHdyYXBwZXJzW2ldLnR5cGUuY29udGVudE1hdGNoLm1hdGNoRnJhZ21lbnQoY29udGVudCk7XG4gICAgICAgICAgICBpZiAoIW1hdGNoIHx8ICFtYXRjaC52YWxpZEVuZClcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIldyYXBwZXIgdHlwZSBnaXZlbiB0byBUcmFuc2Zvcm0ud3JhcCBkb2VzIG5vdCBmb3JtIHZhbGlkIGNvbnRlbnQgb2YgaXRzIHBhcmVudCB3cmFwcGVyXCIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRlbnQgPSBGcmFnbWVudC5mcm9tKHdyYXBwZXJzW2ldLnR5cGUuY3JlYXRlKHdyYXBwZXJzW2ldLmF0dHJzLCBjb250ZW50KSk7XG4gICAgfVxuICAgIGxldCBzdGFydCA9IHJhbmdlLnN0YXJ0LCBlbmQgPSByYW5nZS5lbmQ7XG4gICAgdHIuc3RlcChuZXcgUmVwbGFjZUFyb3VuZFN0ZXAoc3RhcnQsIGVuZCwgc3RhcnQsIGVuZCwgbmV3IFNsaWNlKGNvbnRlbnQsIDAsIDApLCB3cmFwcGVycy5sZW5ndGgsIHRydWUpKTtcbn1cbmZ1bmN0aW9uIHNldEJsb2NrVHlwZSh0ciwgZnJvbSwgdG8sIHR5cGUsIGF0dHJzKSB7XG4gICAgaWYgKCF0eXBlLmlzVGV4dGJsb2NrKVxuICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIlR5cGUgZ2l2ZW4gdG8gc2V0QmxvY2tUeXBlIHNob3VsZCBiZSBhIHRleHRibG9ja1wiKTtcbiAgICBsZXQgbWFwRnJvbSA9IHRyLnN0ZXBzLmxlbmd0aDtcbiAgICB0ci5kb2Mubm9kZXNCZXR3ZWVuKGZyb20sIHRvLCAobm9kZSwgcG9zKSA9PiB7XG4gICAgICAgIGxldCBhdHRyc0hlcmUgPSB0eXBlb2YgYXR0cnMgPT0gXCJmdW5jdGlvblwiID8gYXR0cnMobm9kZSkgOiBhdHRycztcbiAgICAgICAgaWYgKG5vZGUuaXNUZXh0YmxvY2sgJiYgIW5vZGUuaGFzTWFya3VwKHR5cGUsIGF0dHJzSGVyZSkgJiZcbiAgICAgICAgICAgIGNhbkNoYW5nZVR5cGUodHIuZG9jLCB0ci5tYXBwaW5nLnNsaWNlKG1hcEZyb20pLm1hcChwb3MpLCB0eXBlKSkge1xuICAgICAgICAgICAgbGV0IGNvbnZlcnROZXdsaW5lcyA9IG51bGw7XG4gICAgICAgICAgICBpZiAodHlwZS5zY2hlbWEubGluZWJyZWFrUmVwbGFjZW1lbnQpIHtcbiAgICAgICAgICAgICAgICBsZXQgcHJlID0gdHlwZS53aGl0ZXNwYWNlID09IFwicHJlXCIsIHN1cHBvcnRMaW5lYnJlYWsgPSAhIXR5cGUuY29udGVudE1hdGNoLm1hdGNoVHlwZSh0eXBlLnNjaGVtYS5saW5lYnJlYWtSZXBsYWNlbWVudCk7XG4gICAgICAgICAgICAgICAgaWYgKHByZSAmJiAhc3VwcG9ydExpbmVicmVhaylcbiAgICAgICAgICAgICAgICAgICAgY29udmVydE5ld2xpbmVzID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoIXByZSAmJiBzdXBwb3J0TGluZWJyZWFrKVxuICAgICAgICAgICAgICAgICAgICBjb252ZXJ0TmV3bGluZXMgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gRW5zdXJlIGFsbCBtYXJrdXAgdGhhdCBpc24ndCBhbGxvd2VkIGluIHRoZSBuZXcgbm9kZSB0eXBlIGlzIGNsZWFyZWRcbiAgICAgICAgICAgIGlmIChjb252ZXJ0TmV3bGluZXMgPT09IGZhbHNlKVxuICAgICAgICAgICAgICAgIHJlcGxhY2VMaW5lYnJlYWtzKHRyLCBub2RlLCBwb3MsIG1hcEZyb20pO1xuICAgICAgICAgICAgY2xlYXJJbmNvbXBhdGlibGUodHIsIHRyLm1hcHBpbmcuc2xpY2UobWFwRnJvbSkubWFwKHBvcywgMSksIHR5cGUsIHVuZGVmaW5lZCwgY29udmVydE5ld2xpbmVzID09PSBudWxsKTtcbiAgICAgICAgICAgIGxldCBtYXBwaW5nID0gdHIubWFwcGluZy5zbGljZShtYXBGcm9tKTtcbiAgICAgICAgICAgIGxldCBzdGFydE0gPSBtYXBwaW5nLm1hcChwb3MsIDEpLCBlbmRNID0gbWFwcGluZy5tYXAocG9zICsgbm9kZS5ub2RlU2l6ZSwgMSk7XG4gICAgICAgICAgICB0ci5zdGVwKG5ldyBSZXBsYWNlQXJvdW5kU3RlcChzdGFydE0sIGVuZE0sIHN0YXJ0TSArIDEsIGVuZE0gLSAxLCBuZXcgU2xpY2UoRnJhZ21lbnQuZnJvbSh0eXBlLmNyZWF0ZShhdHRyc0hlcmUsIG51bGwsIG5vZGUubWFya3MpKSwgMCwgMCksIDEsIHRydWUpKTtcbiAgICAgICAgICAgIGlmIChjb252ZXJ0TmV3bGluZXMgPT09IHRydWUpXG4gICAgICAgICAgICAgICAgcmVwbGFjZU5ld2xpbmVzKHRyLCBub2RlLCBwb3MsIG1hcEZyb20pO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfSk7XG59XG5mdW5jdGlvbiByZXBsYWNlTmV3bGluZXModHIsIG5vZGUsIHBvcywgbWFwRnJvbSkge1xuICAgIG5vZGUuZm9yRWFjaCgoY2hpbGQsIG9mZnNldCkgPT4ge1xuICAgICAgICBpZiAoY2hpbGQuaXNUZXh0KSB7XG4gICAgICAgICAgICBsZXQgbSwgbmV3bGluZSA9IC9cXHI/XFxufFxcci9nO1xuICAgICAgICAgICAgd2hpbGUgKG0gPSBuZXdsaW5lLmV4ZWMoY2hpbGQudGV4dCkpIHtcbiAgICAgICAgICAgICAgICBsZXQgc3RhcnQgPSB0ci5tYXBwaW5nLnNsaWNlKG1hcEZyb20pLm1hcChwb3MgKyAxICsgb2Zmc2V0ICsgbS5pbmRleCk7XG4gICAgICAgICAgICAgICAgdHIucmVwbGFjZVdpdGgoc3RhcnQsIHN0YXJ0ICsgMSwgbm9kZS50eXBlLnNjaGVtYS5saW5lYnJlYWtSZXBsYWNlbWVudC5jcmVhdGUoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9KTtcbn1cbmZ1bmN0aW9uIHJlcGxhY2VMaW5lYnJlYWtzKHRyLCBub2RlLCBwb3MsIG1hcEZyb20pIHtcbiAgICBub2RlLmZvckVhY2goKGNoaWxkLCBvZmZzZXQpID0+IHtcbiAgICAgICAgaWYgKGNoaWxkLnR5cGUgPT0gY2hpbGQudHlwZS5zY2hlbWEubGluZWJyZWFrUmVwbGFjZW1lbnQpIHtcbiAgICAgICAgICAgIGxldCBzdGFydCA9IHRyLm1hcHBpbmcuc2xpY2UobWFwRnJvbSkubWFwKHBvcyArIDEgKyBvZmZzZXQpO1xuICAgICAgICAgICAgdHIucmVwbGFjZVdpdGgoc3RhcnQsIHN0YXJ0ICsgMSwgbm9kZS50eXBlLnNjaGVtYS50ZXh0KFwiXFxuXCIpKTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuZnVuY3Rpb24gY2FuQ2hhbmdlVHlwZShkb2MsIHBvcywgdHlwZSkge1xuICAgIGxldCAkcG9zID0gZG9jLnJlc29sdmUocG9zKSwgaW5kZXggPSAkcG9zLmluZGV4KCk7XG4gICAgcmV0dXJuICRwb3MucGFyZW50LmNhblJlcGxhY2VXaXRoKGluZGV4LCBpbmRleCArIDEsIHR5cGUpO1xufVxuLyoqXG5DaGFuZ2UgdGhlIHR5cGUsIGF0dHJpYnV0ZXMsIGFuZC9vciBtYXJrcyBvZiB0aGUgbm9kZSBhdCBgcG9zYC5cbldoZW4gYHR5cGVgIGlzbid0IGdpdmVuLCB0aGUgZXhpc3Rpbmcgbm9kZSB0eXBlIGlzIHByZXNlcnZlZCxcbiovXG5mdW5jdGlvbiBzZXROb2RlTWFya3VwKHRyLCBwb3MsIHR5cGUsIGF0dHJzLCBtYXJrcykge1xuICAgIGxldCBub2RlID0gdHIuZG9jLm5vZGVBdChwb3MpO1xuICAgIGlmICghbm9kZSlcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJObyBub2RlIGF0IGdpdmVuIHBvc2l0aW9uXCIpO1xuICAgIGlmICghdHlwZSlcbiAgICAgICAgdHlwZSA9IG5vZGUudHlwZTtcbiAgICBsZXQgbmV3Tm9kZSA9IHR5cGUuY3JlYXRlKGF0dHJzLCBudWxsLCBtYXJrcyB8fCBub2RlLm1hcmtzKTtcbiAgICBpZiAobm9kZS5pc0xlYWYpXG4gICAgICAgIHJldHVybiB0ci5yZXBsYWNlV2l0aChwb3MsIHBvcyArIG5vZGUubm9kZVNpemUsIG5ld05vZGUpO1xuICAgIGlmICghdHlwZS52YWxpZENvbnRlbnQobm9kZS5jb250ZW50KSlcbiAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIGNvbnRlbnQgZm9yIG5vZGUgdHlwZSBcIiArIHR5cGUubmFtZSk7XG4gICAgdHIuc3RlcChuZXcgUmVwbGFjZUFyb3VuZFN0ZXAocG9zLCBwb3MgKyBub2RlLm5vZGVTaXplLCBwb3MgKyAxLCBwb3MgKyBub2RlLm5vZGVTaXplIC0gMSwgbmV3IFNsaWNlKEZyYWdtZW50LmZyb20obmV3Tm9kZSksIDAsIDApLCAxLCB0cnVlKSk7XG59XG4vKipcbkNoZWNrIHdoZXRoZXIgc3BsaXR0aW5nIGF0IHRoZSBnaXZlbiBwb3NpdGlvbiBpcyBhbGxvd2VkLlxuKi9cbmZ1bmN0aW9uIGNhblNwbGl0KGRvYywgcG9zLCBkZXB0aCA9IDEsIHR5cGVzQWZ0ZXIpIHtcbiAgICBsZXQgJHBvcyA9IGRvYy5yZXNvbHZlKHBvcyksIGJhc2UgPSAkcG9zLmRlcHRoIC0gZGVwdGg7XG4gICAgbGV0IGlubmVyVHlwZSA9ICh0eXBlc0FmdGVyICYmIHR5cGVzQWZ0ZXJbdHlwZXNBZnRlci5sZW5ndGggLSAxXSkgfHwgJHBvcy5wYXJlbnQ7XG4gICAgaWYgKGJhc2UgPCAwIHx8ICRwb3MucGFyZW50LnR5cGUuc3BlYy5pc29sYXRpbmcgfHxcbiAgICAgICAgISRwb3MucGFyZW50LmNhblJlcGxhY2UoJHBvcy5pbmRleCgpLCAkcG9zLnBhcmVudC5jaGlsZENvdW50KSB8fFxuICAgICAgICAhaW5uZXJUeXBlLnR5cGUudmFsaWRDb250ZW50KCRwb3MucGFyZW50LmNvbnRlbnQuY3V0QnlJbmRleCgkcG9zLmluZGV4KCksICRwb3MucGFyZW50LmNoaWxkQ291bnQpKSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGZvciAobGV0IGQgPSAkcG9zLmRlcHRoIC0gMSwgaSA9IGRlcHRoIC0gMjsgZCA+IGJhc2U7IGQtLSwgaS0tKSB7XG4gICAgICAgIGxldCBub2RlID0gJHBvcy5ub2RlKGQpLCBpbmRleCA9ICRwb3MuaW5kZXgoZCk7XG4gICAgICAgIGlmIChub2RlLnR5cGUuc3BlYy5pc29sYXRpbmcpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGxldCByZXN0ID0gbm9kZS5jb250ZW50LmN1dEJ5SW5kZXgoaW5kZXgsIG5vZGUuY2hpbGRDb3VudCk7XG4gICAgICAgIGxldCBvdmVycmlkZUNoaWxkID0gdHlwZXNBZnRlciAmJiB0eXBlc0FmdGVyW2kgKyAxXTtcbiAgICAgICAgaWYgKG92ZXJyaWRlQ2hpbGQpXG4gICAgICAgICAgICByZXN0ID0gcmVzdC5yZXBsYWNlQ2hpbGQoMCwgb3ZlcnJpZGVDaGlsZC50eXBlLmNyZWF0ZShvdmVycmlkZUNoaWxkLmF0dHJzKSk7XG4gICAgICAgIGxldCBhZnRlciA9ICh0eXBlc0FmdGVyICYmIHR5cGVzQWZ0ZXJbaV0pIHx8IG5vZGU7XG4gICAgICAgIGlmICghbm9kZS5jYW5SZXBsYWNlKGluZGV4ICsgMSwgbm9kZS5jaGlsZENvdW50KSB8fCAhYWZ0ZXIudHlwZS52YWxpZENvbnRlbnQocmVzdCkpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGxldCBpbmRleCA9ICRwb3MuaW5kZXhBZnRlcihiYXNlKTtcbiAgICBsZXQgYmFzZVR5cGUgPSB0eXBlc0FmdGVyICYmIHR5cGVzQWZ0ZXJbMF07XG4gICAgcmV0dXJuICRwb3Mubm9kZShiYXNlKS5jYW5SZXBsYWNlV2l0aChpbmRleCwgaW5kZXgsIGJhc2VUeXBlID8gYmFzZVR5cGUudHlwZSA6ICRwb3Mubm9kZShiYXNlICsgMSkudHlwZSk7XG59XG5mdW5jdGlvbiBzcGxpdCh0ciwgcG9zLCBkZXB0aCA9IDEsIHR5cGVzQWZ0ZXIpIHtcbiAgICBsZXQgJHBvcyA9IHRyLmRvYy5yZXNvbHZlKHBvcyksIGJlZm9yZSA9IEZyYWdtZW50LmVtcHR5LCBhZnRlciA9IEZyYWdtZW50LmVtcHR5O1xuICAgIGZvciAobGV0IGQgPSAkcG9zLmRlcHRoLCBlID0gJHBvcy5kZXB0aCAtIGRlcHRoLCBpID0gZGVwdGggLSAxOyBkID4gZTsgZC0tLCBpLS0pIHtcbiAgICAgICAgYmVmb3JlID0gRnJhZ21lbnQuZnJvbSgkcG9zLm5vZGUoZCkuY29weShiZWZvcmUpKTtcbiAgICAgICAgbGV0IHR5cGVBZnRlciA9IHR5cGVzQWZ0ZXIgJiYgdHlwZXNBZnRlcltpXTtcbiAgICAgICAgYWZ0ZXIgPSBGcmFnbWVudC5mcm9tKHR5cGVBZnRlciA/IHR5cGVBZnRlci50eXBlLmNyZWF0ZSh0eXBlQWZ0ZXIuYXR0cnMsIGFmdGVyKSA6ICRwb3Mubm9kZShkKS5jb3B5KGFmdGVyKSk7XG4gICAgfVxuICAgIHRyLnN0ZXAobmV3IFJlcGxhY2VTdGVwKHBvcywgcG9zLCBuZXcgU2xpY2UoYmVmb3JlLmFwcGVuZChhZnRlciksIGRlcHRoLCBkZXB0aCksIHRydWUpKTtcbn1cbi8qKlxuVGVzdCB3aGV0aGVyIHRoZSBibG9ja3MgYmVmb3JlIGFuZCBhZnRlciBhIGdpdmVuIHBvc2l0aW9uIGNhbiBiZVxuam9pbmVkLlxuKi9cbmZ1bmN0aW9uIGNhbkpvaW4oZG9jLCBwb3MpIHtcbiAgICBsZXQgJHBvcyA9IGRvYy5yZXNvbHZlKHBvcyksIGluZGV4ID0gJHBvcy5pbmRleCgpO1xuICAgIHJldHVybiBqb2luYWJsZSgkcG9zLm5vZGVCZWZvcmUsICRwb3Mubm9kZUFmdGVyKSAmJlxuICAgICAgICAkcG9zLnBhcmVudC5jYW5SZXBsYWNlKGluZGV4LCBpbmRleCArIDEpO1xufVxuZnVuY3Rpb24gY2FuQXBwZW5kV2l0aFN1YnN0aXR1dGVkTGluZWJyZWFrcyhhLCBiKSB7XG4gICAgaWYgKCFiLmNvbnRlbnQuc2l6ZSlcbiAgICAgICAgYS50eXBlLmNvbXBhdGlibGVDb250ZW50KGIudHlwZSk7XG4gICAgbGV0IG1hdGNoID0gYS5jb250ZW50TWF0Y2hBdChhLmNoaWxkQ291bnQpO1xuICAgIGxldCB7IGxpbmVicmVha1JlcGxhY2VtZW50IH0gPSBhLnR5cGUuc2NoZW1hO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYi5jaGlsZENvdW50OyBpKyspIHtcbiAgICAgICAgbGV0IGNoaWxkID0gYi5jaGlsZChpKTtcbiAgICAgICAgbGV0IHR5cGUgPSBjaGlsZC50eXBlID09IGxpbmVicmVha1JlcGxhY2VtZW50ID8gYS50eXBlLnNjaGVtYS5ub2Rlcy50ZXh0IDogY2hpbGQudHlwZTtcbiAgICAgICAgbWF0Y2ggPSBtYXRjaC5tYXRjaFR5cGUodHlwZSk7XG4gICAgICAgIGlmICghbWF0Y2gpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGlmICghYS50eXBlLmFsbG93c01hcmtzKGNoaWxkLm1hcmtzKSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIG1hdGNoLnZhbGlkRW5kO1xufVxuZnVuY3Rpb24gam9pbmFibGUoYSwgYikge1xuICAgIHJldHVybiAhIShhICYmIGIgJiYgIWEuaXNMZWFmICYmIGNhbkFwcGVuZFdpdGhTdWJzdGl0dXRlZExpbmVicmVha3MoYSwgYikpO1xufVxuLyoqXG5GaW5kIGFuIGFuY2VzdG9yIG9mIHRoZSBnaXZlbiBwb3NpdGlvbiB0aGF0IGNhbiBiZSBqb2luZWQgdG8gdGhlXG5ibG9jayBiZWZvcmUgKG9yIGFmdGVyIGlmIGBkaXJgIGlzIHBvc2l0aXZlKS4gUmV0dXJucyB0aGUgam9pbmFibGVcbnBvaW50LCBpZiBhbnkuXG4qL1xuZnVuY3Rpb24gam9pblBvaW50KGRvYywgcG9zLCBkaXIgPSAtMSkge1xuICAgIGxldCAkcG9zID0gZG9jLnJlc29sdmUocG9zKTtcbiAgICBmb3IgKGxldCBkID0gJHBvcy5kZXB0aDs7IGQtLSkge1xuICAgICAgICBsZXQgYmVmb3JlLCBhZnRlciwgaW5kZXggPSAkcG9zLmluZGV4KGQpO1xuICAgICAgICBpZiAoZCA9PSAkcG9zLmRlcHRoKSB7XG4gICAgICAgICAgICBiZWZvcmUgPSAkcG9zLm5vZGVCZWZvcmU7XG4gICAgICAgICAgICBhZnRlciA9ICRwb3Mubm9kZUFmdGVyO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGRpciA+IDApIHtcbiAgICAgICAgICAgIGJlZm9yZSA9ICRwb3Mubm9kZShkICsgMSk7XG4gICAgICAgICAgICBpbmRleCsrO1xuICAgICAgICAgICAgYWZ0ZXIgPSAkcG9zLm5vZGUoZCkubWF5YmVDaGlsZChpbmRleCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBiZWZvcmUgPSAkcG9zLm5vZGUoZCkubWF5YmVDaGlsZChpbmRleCAtIDEpO1xuICAgICAgICAgICAgYWZ0ZXIgPSAkcG9zLm5vZGUoZCArIDEpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChiZWZvcmUgJiYgIWJlZm9yZS5pc1RleHRibG9jayAmJiBqb2luYWJsZShiZWZvcmUsIGFmdGVyKSAmJlxuICAgICAgICAgICAgJHBvcy5ub2RlKGQpLmNhblJlcGxhY2UoaW5kZXgsIGluZGV4ICsgMSkpXG4gICAgICAgICAgICByZXR1cm4gcG9zO1xuICAgICAgICBpZiAoZCA9PSAwKVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIHBvcyA9IGRpciA8IDAgPyAkcG9zLmJlZm9yZShkKSA6ICRwb3MuYWZ0ZXIoZCk7XG4gICAgfVxufVxuZnVuY3Rpb24gam9pbih0ciwgcG9zLCBkZXB0aCkge1xuICAgIGxldCBjb252ZXJ0TmV3bGluZXMgPSBudWxsO1xuICAgIGxldCB7IGxpbmVicmVha1JlcGxhY2VtZW50IH0gPSB0ci5kb2MudHlwZS5zY2hlbWE7XG4gICAgbGV0ICRiZWZvcmUgPSB0ci5kb2MucmVzb2x2ZShwb3MgLSBkZXB0aCksIGJlZm9yZVR5cGUgPSAkYmVmb3JlLm5vZGUoKS50eXBlO1xuICAgIGlmIChsaW5lYnJlYWtSZXBsYWNlbWVudCAmJiBiZWZvcmVUeXBlLmlubGluZUNvbnRlbnQpIHtcbiAgICAgICAgbGV0IHByZSA9IGJlZm9yZVR5cGUud2hpdGVzcGFjZSA9PSBcInByZVwiO1xuICAgICAgICBsZXQgc3VwcG9ydExpbmVicmVhayA9ICEhYmVmb3JlVHlwZS5jb250ZW50TWF0Y2gubWF0Y2hUeXBlKGxpbmVicmVha1JlcGxhY2VtZW50KTtcbiAgICAgICAgaWYgKHByZSAmJiAhc3VwcG9ydExpbmVicmVhaylcbiAgICAgICAgICAgIGNvbnZlcnROZXdsaW5lcyA9IGZhbHNlO1xuICAgICAgICBlbHNlIGlmICghcHJlICYmIHN1cHBvcnRMaW5lYnJlYWspXG4gICAgICAgICAgICBjb252ZXJ0TmV3bGluZXMgPSB0cnVlO1xuICAgIH1cbiAgICBsZXQgbWFwRnJvbSA9IHRyLnN0ZXBzLmxlbmd0aDtcbiAgICBpZiAoY29udmVydE5ld2xpbmVzID09PSBmYWxzZSkge1xuICAgICAgICBsZXQgJGFmdGVyID0gdHIuZG9jLnJlc29sdmUocG9zICsgZGVwdGgpO1xuICAgICAgICByZXBsYWNlTGluZWJyZWFrcyh0ciwgJGFmdGVyLm5vZGUoKSwgJGFmdGVyLmJlZm9yZSgpLCBtYXBGcm9tKTtcbiAgICB9XG4gICAgaWYgKGJlZm9yZVR5cGUuaW5saW5lQ29udGVudClcbiAgICAgICAgY2xlYXJJbmNvbXBhdGlibGUodHIsIHBvcyArIGRlcHRoIC0gMSwgYmVmb3JlVHlwZSwgJGJlZm9yZS5ub2RlKCkuY29udGVudE1hdGNoQXQoJGJlZm9yZS5pbmRleCgpKSwgY29udmVydE5ld2xpbmVzID09IG51bGwpO1xuICAgIGxldCBtYXBwaW5nID0gdHIubWFwcGluZy5zbGljZShtYXBGcm9tKSwgc3RhcnQgPSBtYXBwaW5nLm1hcChwb3MgLSBkZXB0aCk7XG4gICAgdHIuc3RlcChuZXcgUmVwbGFjZVN0ZXAoc3RhcnQsIG1hcHBpbmcubWFwKHBvcyArIGRlcHRoLCAtMSksIFNsaWNlLmVtcHR5LCB0cnVlKSk7XG4gICAgaWYgKGNvbnZlcnROZXdsaW5lcyA9PT0gdHJ1ZSkge1xuICAgICAgICBsZXQgJGZ1bGwgPSB0ci5kb2MucmVzb2x2ZShzdGFydCk7XG4gICAgICAgIHJlcGxhY2VOZXdsaW5lcyh0ciwgJGZ1bGwubm9kZSgpLCAkZnVsbC5iZWZvcmUoKSwgdHIuc3RlcHMubGVuZ3RoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRyO1xufVxuLyoqXG5UcnkgdG8gZmluZCBhIHBvaW50IHdoZXJlIGEgbm9kZSBvZiB0aGUgZ2l2ZW4gdHlwZSBjYW4gYmUgaW5zZXJ0ZWRcbm5lYXIgYHBvc2AsIGJ5IHNlYXJjaGluZyB1cCB0aGUgbm9kZSBoaWVyYXJjaHkgd2hlbiBgcG9zYCBpdHNlbGZcbmlzbid0IGEgdmFsaWQgcGxhY2UgYnV0IGlzIGF0IHRoZSBzdGFydCBvciBlbmQgb2YgYSBub2RlLiBSZXR1cm5cbm51bGwgaWYgbm8gcG9zaXRpb24gd2FzIGZvdW5kLlxuKi9cbmZ1bmN0aW9uIGluc2VydFBvaW50KGRvYywgcG9zLCBub2RlVHlwZSkge1xuICAgIGxldCAkcG9zID0gZG9jLnJlc29sdmUocG9zKTtcbiAgICBpZiAoJHBvcy5wYXJlbnQuY2FuUmVwbGFjZVdpdGgoJHBvcy5pbmRleCgpLCAkcG9zLmluZGV4KCksIG5vZGVUeXBlKSlcbiAgICAgICAgcmV0dXJuIHBvcztcbiAgICBpZiAoJHBvcy5wYXJlbnRPZmZzZXQgPT0gMClcbiAgICAgICAgZm9yIChsZXQgZCA9ICRwb3MuZGVwdGggLSAxOyBkID49IDA7IGQtLSkge1xuICAgICAgICAgICAgbGV0IGluZGV4ID0gJHBvcy5pbmRleChkKTtcbiAgICAgICAgICAgIGlmICgkcG9zLm5vZGUoZCkuY2FuUmVwbGFjZVdpdGgoaW5kZXgsIGluZGV4LCBub2RlVHlwZSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuICRwb3MuYmVmb3JlKGQgKyAxKTtcbiAgICAgICAgICAgIGlmIChpbmRleCA+IDApXG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICBpZiAoJHBvcy5wYXJlbnRPZmZzZXQgPT0gJHBvcy5wYXJlbnQuY29udGVudC5zaXplKVxuICAgICAgICBmb3IgKGxldCBkID0gJHBvcy5kZXB0aCAtIDE7IGQgPj0gMDsgZC0tKSB7XG4gICAgICAgICAgICBsZXQgaW5kZXggPSAkcG9zLmluZGV4QWZ0ZXIoZCk7XG4gICAgICAgICAgICBpZiAoJHBvcy5ub2RlKGQpLmNhblJlcGxhY2VXaXRoKGluZGV4LCBpbmRleCwgbm9kZVR5cGUpKVxuICAgICAgICAgICAgICAgIHJldHVybiAkcG9zLmFmdGVyKGQgKyAxKTtcbiAgICAgICAgICAgIGlmIChpbmRleCA8ICRwb3Mubm9kZShkKS5jaGlsZENvdW50KVxuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG4vKipcbkZpbmRzIGEgcG9zaXRpb24gYXQgb3IgYXJvdW5kIHRoZSBnaXZlbiBwb3NpdGlvbiB3aGVyZSB0aGUgZ2l2ZW5cbnNsaWNlIGNhbiBiZSBpbnNlcnRlZC4gV2lsbCBsb29rIGF0IHBhcmVudCBub2RlcycgbmVhcmVzdCBib3VuZGFyeVxuYW5kIHRyeSB0aGVyZSwgZXZlbiBpZiB0aGUgb3JpZ2luYWwgcG9zaXRpb24gd2Fzbid0IGRpcmVjdGx5IGF0IHRoZVxuc3RhcnQgb3IgZW5kIG9mIHRoYXQgbm9kZS4gUmV0dXJucyBudWxsIHdoZW4gbm8gcG9zaXRpb24gd2FzIGZvdW5kLlxuKi9cbmZ1bmN0aW9uIGRyb3BQb2ludChkb2MsIHBvcywgc2xpY2UpIHtcbiAgICBsZXQgJHBvcyA9IGRvYy5yZXNvbHZlKHBvcyk7XG4gICAgaWYgKCFzbGljZS5jb250ZW50LnNpemUpXG4gICAgICAgIHJldHVybiBwb3M7XG4gICAgbGV0IGNvbnRlbnQgPSBzbGljZS5jb250ZW50O1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2xpY2Uub3BlblN0YXJ0OyBpKyspXG4gICAgICAgIGNvbnRlbnQgPSBjb250ZW50LmZpcnN0Q2hpbGQuY29udGVudDtcbiAgICBmb3IgKGxldCBwYXNzID0gMTsgcGFzcyA8PSAoc2xpY2Uub3BlblN0YXJ0ID09IDAgJiYgc2xpY2Uuc2l6ZSA/IDIgOiAxKTsgcGFzcysrKSB7XG4gICAgICAgIGZvciAobGV0IGQgPSAkcG9zLmRlcHRoOyBkID49IDA7IGQtLSkge1xuICAgICAgICAgICAgbGV0IGJpYXMgPSBkID09ICRwb3MuZGVwdGggPyAwIDogJHBvcy5wb3MgPD0gKCRwb3Muc3RhcnQoZCArIDEpICsgJHBvcy5lbmQoZCArIDEpKSAvIDIgPyAtMSA6IDE7XG4gICAgICAgICAgICBsZXQgaW5zZXJ0UG9zID0gJHBvcy5pbmRleChkKSArIChiaWFzID4gMCA/IDEgOiAwKTtcbiAgICAgICAgICAgIGxldCBwYXJlbnQgPSAkcG9zLm5vZGUoZCksIGZpdHMgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmIChwYXNzID09IDEpIHtcbiAgICAgICAgICAgICAgICBmaXRzID0gcGFyZW50LmNhblJlcGxhY2UoaW5zZXJ0UG9zLCBpbnNlcnRQb3MsIGNvbnRlbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgbGV0IHdyYXBwaW5nID0gcGFyZW50LmNvbnRlbnRNYXRjaEF0KGluc2VydFBvcykuZmluZFdyYXBwaW5nKGNvbnRlbnQuZmlyc3RDaGlsZC50eXBlKTtcbiAgICAgICAgICAgICAgICBmaXRzID0gd3JhcHBpbmcgJiYgcGFyZW50LmNhblJlcGxhY2VXaXRoKGluc2VydFBvcywgaW5zZXJ0UG9zLCB3cmFwcGluZ1swXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZml0cylcbiAgICAgICAgICAgICAgICByZXR1cm4gYmlhcyA9PSAwID8gJHBvcy5wb3MgOiBiaWFzIDwgMCA/ICRwb3MuYmVmb3JlKGQgKyAxKSA6ICRwb3MuYWZ0ZXIoZCArIDEpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuXG4vKipcblx1MjAxOEZpdFx1MjAxOSBhIHNsaWNlIGludG8gYSBnaXZlbiBwb3NpdGlvbiBpbiB0aGUgZG9jdW1lbnQsIHByb2R1Y2luZyBhXG5bc3RlcF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3RyYW5zZm9ybS5TdGVwKSB0aGF0IGluc2VydHMgaXQuIFdpbGwgcmV0dXJuIG51bGwgaWZcbnRoZXJlJ3Mgbm8gbWVhbmluZ2Z1bCB3YXkgdG8gaW5zZXJ0IHRoZSBzbGljZSBoZXJlLCBvciBpbnNlcnRpbmcgaXRcbndvdWxkIGJlIGEgbm8tb3AgKGFuIGVtcHR5IHNsaWNlIG92ZXIgYW4gZW1wdHkgcmFuZ2UpLlxuKi9cbmZ1bmN0aW9uIHJlcGxhY2VTdGVwKGRvYywgZnJvbSwgdG8gPSBmcm9tLCBzbGljZSA9IFNsaWNlLmVtcHR5KSB7XG4gICAgaWYgKGZyb20gPT0gdG8gJiYgIXNsaWNlLnNpemUpXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIGxldCAkZnJvbSA9IGRvYy5yZXNvbHZlKGZyb20pLCAkdG8gPSBkb2MucmVzb2x2ZSh0byk7XG4gICAgLy8gT3B0aW1pemF0aW9uIC0tIGF2b2lkIHdvcmsgaWYgaXQncyBvYnZpb3VzIHRoYXQgaXQncyBub3QgbmVlZGVkLlxuICAgIGlmIChmaXRzVHJpdmlhbGx5KCRmcm9tLCAkdG8sIHNsaWNlKSlcbiAgICAgICAgcmV0dXJuIG5ldyBSZXBsYWNlU3RlcChmcm9tLCB0bywgc2xpY2UpO1xuICAgIHJldHVybiBuZXcgRml0dGVyKCRmcm9tLCAkdG8sIHNsaWNlKS5maXQoKTtcbn1cbmZ1bmN0aW9uIGZpdHNUcml2aWFsbHkoJGZyb20sICR0bywgc2xpY2UpIHtcbiAgICByZXR1cm4gIXNsaWNlLm9wZW5TdGFydCAmJiAhc2xpY2Uub3BlbkVuZCAmJiAkZnJvbS5zdGFydCgpID09ICR0by5zdGFydCgpICYmXG4gICAgICAgICRmcm9tLnBhcmVudC5jYW5SZXBsYWNlKCRmcm9tLmluZGV4KCksICR0by5pbmRleCgpLCBzbGljZS5jb250ZW50KTtcbn1cbi8vIEFsZ29yaXRobSBmb3IgJ3BsYWNpbmcnIHRoZSBlbGVtZW50cyBvZiBhIHNsaWNlIGludG8gYSBnYXA6XG4vL1xuLy8gV2UgY29uc2lkZXIgdGhlIGNvbnRlbnQgb2YgZWFjaCBub2RlIHRoYXQgaXMgb3BlbiB0byB0aGUgbGVmdCB0byBiZVxuLy8gaW5kZXBlbmRlbnRseSBwbGFjZWFibGUuIEkuZS4gaW4gPHAoXCJmb29cIiksIHAoXCJiYXJcIik+LCB3aGVuIHRoZVxuLy8gcGFyYWdyYXBoIG9uIHRoZSBsZWZ0IGlzIG9wZW4sIFwiZm9vXCIgY2FuIGJlIHBsYWNlZCAoc29tZXdoZXJlIG9uXG4vLyB0aGUgbGVmdCBzaWRlIG9mIHRoZSByZXBsYWNlbWVudCBnYXApIGluZGVwZW5kZW50bHkgZnJvbSBwKFwiYmFyXCIpLlxuLy9cbi8vIFRoaXMgY2xhc3MgdHJhY2tzIHRoZSBzdGF0ZSBvZiB0aGUgcGxhY2VtZW50IHByb2dyZXNzIGluIHRoZVxuLy8gZm9sbG93aW5nIHByb3BlcnRpZXM6XG4vL1xuLy8gIC0gYGZyb250aWVyYCBob2xkcyBhIHN0YWNrIG9mIGB7dHlwZSwgbWF0Y2h9YCBvYmplY3RzIHRoYXRcbi8vICAgIHJlcHJlc2VudCB0aGUgb3BlbiBzaWRlIG9mIHRoZSByZXBsYWNlbWVudC4gSXQgc3RhcnRzIGF0XG4vLyAgICBgJGZyb21gLCB0aGVuIG1vdmVzIGZvcndhcmQgYXMgY29udGVudCBpcyBwbGFjZWQsIGFuZCBpcyBmaW5hbGx5XG4vLyAgICByZWNvbmNpbGVkIHdpdGggYCR0b2AuXG4vL1xuLy8gIC0gYHVucGxhY2VkYCBpcyBhIHNsaWNlIHRoYXQgcmVwcmVzZW50cyB0aGUgY29udGVudCB0aGF0IGhhc24ndFxuLy8gICAgYmVlbiBwbGFjZWQgeWV0LlxuLy9cbi8vICAtIGBwbGFjZWRgIGlzIGEgZnJhZ21lbnQgb2YgcGxhY2VkIGNvbnRlbnQuIEl0cyBvcGVuLXN0YXJ0IHZhbHVlXG4vLyAgICBpcyBpbXBsaWNpdCBpbiBgJGZyb21gLCBhbmQgaXRzIG9wZW4tZW5kIHZhbHVlIGluIGBmcm9udGllcmAuXG5jbGFzcyBGaXR0ZXIge1xuICAgIGNvbnN0cnVjdG9yKCRmcm9tLCAkdG8sIHVucGxhY2VkKSB7XG4gICAgICAgIHRoaXMuJGZyb20gPSAkZnJvbTtcbiAgICAgICAgdGhpcy4kdG8gPSAkdG87XG4gICAgICAgIHRoaXMudW5wbGFjZWQgPSB1bnBsYWNlZDtcbiAgICAgICAgdGhpcy5mcm9udGllciA9IFtdO1xuICAgICAgICB0aGlzLnBsYWNlZCA9IEZyYWdtZW50LmVtcHR5O1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8PSAkZnJvbS5kZXB0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgbm9kZSA9ICRmcm9tLm5vZGUoaSk7XG4gICAgICAgICAgICB0aGlzLmZyb250aWVyLnB1c2goe1xuICAgICAgICAgICAgICAgIHR5cGU6IG5vZGUudHlwZSxcbiAgICAgICAgICAgICAgICBtYXRjaDogbm9kZS5jb250ZW50TWF0Y2hBdCgkZnJvbS5pbmRleEFmdGVyKGkpKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgaSA9ICRmcm9tLmRlcHRoOyBpID4gMDsgaS0tKVxuICAgICAgICAgICAgdGhpcy5wbGFjZWQgPSBGcmFnbWVudC5mcm9tKCRmcm9tLm5vZGUoaSkuY29weSh0aGlzLnBsYWNlZCkpO1xuICAgIH1cbiAgICBnZXQgZGVwdGgoKSB7IHJldHVybiB0aGlzLmZyb250aWVyLmxlbmd0aCAtIDE7IH1cbiAgICBmaXQoKSB7XG4gICAgICAgIC8vIEFzIGxvbmcgYXMgdGhlcmUncyB1bnBsYWNlZCBjb250ZW50LCB0cnkgdG8gcGxhY2Ugc29tZSBvZiBpdC5cbiAgICAgICAgLy8gSWYgdGhhdCBmYWlscywgZWl0aGVyIGluY3JlYXNlIHRoZSBvcGVuIHNjb3JlIG9mIHRoZSB1bnBsYWNlZFxuICAgICAgICAvLyBzbGljZSwgb3IgZHJvcCBub2RlcyBmcm9tIGl0LCBhbmQgdGhlbiB0cnkgYWdhaW4uXG4gICAgICAgIHdoaWxlICh0aGlzLnVucGxhY2VkLnNpemUpIHtcbiAgICAgICAgICAgIGxldCBmaXQgPSB0aGlzLmZpbmRGaXR0YWJsZSgpO1xuICAgICAgICAgICAgaWYgKGZpdClcbiAgICAgICAgICAgICAgICB0aGlzLnBsYWNlTm9kZXMoZml0KTtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW5Nb3JlKCkgfHwgdGhpcy5kcm9wTm9kZSgpO1xuICAgICAgICB9XG4gICAgICAgIC8vIFdoZW4gdGhlcmUncyBpbmxpbmUgY29udGVudCBkaXJlY3RseSBhZnRlciB0aGUgZnJvbnRpZXIgX2FuZF9cbiAgICAgICAgLy8gZGlyZWN0bHkgYWZ0ZXIgYHRoaXMuJHRvYCwgd2UgbXVzdCBnZW5lcmF0ZSBhIGBSZXBsYWNlQXJvdW5kYFxuICAgICAgICAvLyBzdGVwIHRoYXQgcHVsbHMgdGhhdCBjb250ZW50IGludG8gdGhlIG5vZGUgYWZ0ZXIgdGhlIGZyb250aWVyLlxuICAgICAgICAvLyBUaGF0IG1lYW5zIHRoZSBmaXR0aW5nIG11c3QgYmUgZG9uZSB0byB0aGUgZW5kIG9mIHRoZSB0ZXh0YmxvY2tcbiAgICAgICAgLy8gbm9kZSBhZnRlciBgdGhpcy4kdG9gLCBub3QgYHRoaXMuJHRvYCBpdHNlbGYuXG4gICAgICAgIGxldCBtb3ZlSW5saW5lID0gdGhpcy5tdXN0TW92ZUlubGluZSgpLCBwbGFjZWRTaXplID0gdGhpcy5wbGFjZWQuc2l6ZSAtIHRoaXMuZGVwdGggLSB0aGlzLiRmcm9tLmRlcHRoO1xuICAgICAgICBsZXQgJGZyb20gPSB0aGlzLiRmcm9tLCAkdG8gPSB0aGlzLmNsb3NlKG1vdmVJbmxpbmUgPCAwID8gdGhpcy4kdG8gOiAkZnJvbS5kb2MucmVzb2x2ZShtb3ZlSW5saW5lKSk7XG4gICAgICAgIGlmICghJHRvKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIC8vIElmIGNsb3NpbmcgdG8gYCR0b2Agc3VjY2VlZGVkLCBjcmVhdGUgYSBzdGVwXG4gICAgICAgIGxldCBjb250ZW50ID0gdGhpcy5wbGFjZWQsIG9wZW5TdGFydCA9ICRmcm9tLmRlcHRoLCBvcGVuRW5kID0gJHRvLmRlcHRoO1xuICAgICAgICB3aGlsZSAob3BlblN0YXJ0ICYmIG9wZW5FbmQgJiYgY29udGVudC5jaGlsZENvdW50ID09IDEpIHsgLy8gTm9ybWFsaXplIGJ5IGRyb3BwaW5nIG9wZW4gcGFyZW50IG5vZGVzXG4gICAgICAgICAgICBjb250ZW50ID0gY29udGVudC5maXJzdENoaWxkLmNvbnRlbnQ7XG4gICAgICAgICAgICBvcGVuU3RhcnQtLTtcbiAgICAgICAgICAgIG9wZW5FbmQtLTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgc2xpY2UgPSBuZXcgU2xpY2UoY29udGVudCwgb3BlblN0YXJ0LCBvcGVuRW5kKTtcbiAgICAgICAgaWYgKG1vdmVJbmxpbmUgPiAtMSlcbiAgICAgICAgICAgIHJldHVybiBuZXcgUmVwbGFjZUFyb3VuZFN0ZXAoJGZyb20ucG9zLCBtb3ZlSW5saW5lLCB0aGlzLiR0by5wb3MsIHRoaXMuJHRvLmVuZCgpLCBzbGljZSwgcGxhY2VkU2l6ZSk7XG4gICAgICAgIGlmIChzbGljZS5zaXplIHx8ICRmcm9tLnBvcyAhPSB0aGlzLiR0by5wb3MpIC8vIERvbid0IGdlbmVyYXRlIG5vLW9wIHN0ZXBzXG4gICAgICAgICAgICByZXR1cm4gbmV3IFJlcGxhY2VTdGVwKCRmcm9tLnBvcywgJHRvLnBvcywgc2xpY2UpO1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgLy8gRmluZCBhIHBvc2l0aW9uIG9uIHRoZSBzdGFydCBzcGluZSBvZiBgdGhpcy51bnBsYWNlZGAgdGhhdCBoYXNcbiAgICAvLyBjb250ZW50IHRoYXQgY2FuIGJlIG1vdmVkIHNvbWV3aGVyZSBvbiB0aGUgZnJvbnRpZXIuIFJldHVybnMgdHdvXG4gICAgLy8gZGVwdGhzLCBvbmUgZm9yIHRoZSBzbGljZSBhbmQgb25lIGZvciB0aGUgZnJvbnRpZXIuXG4gICAgZmluZEZpdHRhYmxlKCkge1xuICAgICAgICBsZXQgc3RhcnREZXB0aCA9IHRoaXMudW5wbGFjZWQub3BlblN0YXJ0O1xuICAgICAgICBmb3IgKGxldCBjdXIgPSB0aGlzLnVucGxhY2VkLmNvbnRlbnQsIGQgPSAwLCBvcGVuRW5kID0gdGhpcy51bnBsYWNlZC5vcGVuRW5kOyBkIDwgc3RhcnREZXB0aDsgZCsrKSB7XG4gICAgICAgICAgICBsZXQgbm9kZSA9IGN1ci5maXJzdENoaWxkO1xuICAgICAgICAgICAgaWYgKGN1ci5jaGlsZENvdW50ID4gMSlcbiAgICAgICAgICAgICAgICBvcGVuRW5kID0gMDtcbiAgICAgICAgICAgIGlmIChub2RlLnR5cGUuc3BlYy5pc29sYXRpbmcgJiYgb3BlbkVuZCA8PSBkKSB7XG4gICAgICAgICAgICAgICAgc3RhcnREZXB0aCA9IGQ7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjdXIgPSBub2RlLmNvbnRlbnQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gT25seSB0cnkgd3JhcHBpbmcgbm9kZXMgKHBhc3MgMikgYWZ0ZXIgZmluZGluZyBhIHBsYWNlIHdpdGhvdXRcbiAgICAgICAgLy8gd3JhcHBpbmcgZmFpbGVkLlxuICAgICAgICBmb3IgKGxldCBwYXNzID0gMTsgcGFzcyA8PSAyOyBwYXNzKyspIHtcbiAgICAgICAgICAgIGZvciAobGV0IHNsaWNlRGVwdGggPSBwYXNzID09IDEgPyBzdGFydERlcHRoIDogdGhpcy51bnBsYWNlZC5vcGVuU3RhcnQ7IHNsaWNlRGVwdGggPj0gMDsgc2xpY2VEZXB0aC0tKSB7XG4gICAgICAgICAgICAgICAgbGV0IGZyYWdtZW50LCBwYXJlbnQgPSBudWxsO1xuICAgICAgICAgICAgICAgIGlmIChzbGljZURlcHRoKSB7XG4gICAgICAgICAgICAgICAgICAgIHBhcmVudCA9IGNvbnRlbnRBdCh0aGlzLnVucGxhY2VkLmNvbnRlbnQsIHNsaWNlRGVwdGggLSAxKS5maXJzdENoaWxkO1xuICAgICAgICAgICAgICAgICAgICBmcmFnbWVudCA9IHBhcmVudC5jb250ZW50O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZnJhZ21lbnQgPSB0aGlzLnVucGxhY2VkLmNvbnRlbnQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxldCBmaXJzdCA9IGZyYWdtZW50LmZpcnN0Q2hpbGQ7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgZnJvbnRpZXJEZXB0aCA9IHRoaXMuZGVwdGg7IGZyb250aWVyRGVwdGggPj0gMDsgZnJvbnRpZXJEZXB0aC0tKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCB7IHR5cGUsIG1hdGNoIH0gPSB0aGlzLmZyb250aWVyW2Zyb250aWVyRGVwdGhdLCB3cmFwLCBpbmplY3QgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICAvLyBJbiBwYXNzIDEsIGlmIHRoZSBuZXh0IG5vZGUgbWF0Y2hlcywgb3IgdGhlcmUgaXMgbm8gbmV4dFxuICAgICAgICAgICAgICAgICAgICAvLyBub2RlIGJ1dCB0aGUgcGFyZW50cyBsb29rIGNvbXBhdGlibGUsIHdlJ3ZlIGZvdW5kIGFcbiAgICAgICAgICAgICAgICAgICAgLy8gcGxhY2UuXG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXNzID09IDEgJiYgKGZpcnN0ID8gbWF0Y2gubWF0Y2hUeXBlKGZpcnN0LnR5cGUpIHx8IChpbmplY3QgPSBtYXRjaC5maWxsQmVmb3JlKEZyYWdtZW50LmZyb20oZmlyc3QpLCBmYWxzZSkpXG4gICAgICAgICAgICAgICAgICAgICAgICA6IHBhcmVudCAmJiB0eXBlLmNvbXBhdGlibGVDb250ZW50KHBhcmVudC50eXBlKSkpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4geyBzbGljZURlcHRoLCBmcm9udGllckRlcHRoLCBwYXJlbnQsIGluamVjdCB9O1xuICAgICAgICAgICAgICAgICAgICAvLyBJbiBwYXNzIDIsIGxvb2sgZm9yIGEgc2V0IG9mIHdyYXBwaW5nIG5vZGVzIHRoYXQgbWFrZVxuICAgICAgICAgICAgICAgICAgICAvLyBgZmlyc3RgIGZpdCBoZXJlLlxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChwYXNzID09IDIgJiYgZmlyc3QgJiYgKHdyYXAgPSBtYXRjaC5maW5kV3JhcHBpbmcoZmlyc3QudHlwZSkpKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgc2xpY2VEZXB0aCwgZnJvbnRpZXJEZXB0aCwgcGFyZW50LCB3cmFwIH07XG4gICAgICAgICAgICAgICAgICAgIC8vIERvbid0IGNvbnRpbnVlIGxvb2tpbmcgZnVydGhlciB1cCBpZiB0aGUgcGFyZW50IG5vZGVcbiAgICAgICAgICAgICAgICAgICAgLy8gd291bGQgZml0IGhlcmUuXG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnQgJiYgbWF0Y2gubWF0Y2hUeXBlKHBhcmVudC50eXBlKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBvcGVuTW9yZSgpIHtcbiAgICAgICAgbGV0IHsgY29udGVudCwgb3BlblN0YXJ0LCBvcGVuRW5kIH0gPSB0aGlzLnVucGxhY2VkO1xuICAgICAgICBsZXQgaW5uZXIgPSBjb250ZW50QXQoY29udGVudCwgb3BlblN0YXJ0KTtcbiAgICAgICAgaWYgKCFpbm5lci5jaGlsZENvdW50IHx8IGlubmVyLmZpcnN0Q2hpbGQuaXNMZWFmKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB0aGlzLnVucGxhY2VkID0gbmV3IFNsaWNlKGNvbnRlbnQsIG9wZW5TdGFydCArIDEsIE1hdGgubWF4KG9wZW5FbmQsIGlubmVyLnNpemUgKyBvcGVuU3RhcnQgPj0gY29udGVudC5zaXplIC0gb3BlbkVuZCA/IG9wZW5TdGFydCArIDEgOiAwKSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBkcm9wTm9kZSgpIHtcbiAgICAgICAgbGV0IHsgY29udGVudCwgb3BlblN0YXJ0LCBvcGVuRW5kIH0gPSB0aGlzLnVucGxhY2VkO1xuICAgICAgICBsZXQgaW5uZXIgPSBjb250ZW50QXQoY29udGVudCwgb3BlblN0YXJ0KTtcbiAgICAgICAgaWYgKGlubmVyLmNoaWxkQ291bnQgPD0gMSAmJiBvcGVuU3RhcnQgPiAwKSB7XG4gICAgICAgICAgICBsZXQgb3BlbkF0RW5kID0gY29udGVudC5zaXplIC0gb3BlblN0YXJ0IDw9IG9wZW5TdGFydCArIGlubmVyLnNpemU7XG4gICAgICAgICAgICB0aGlzLnVucGxhY2VkID0gbmV3IFNsaWNlKGRyb3BGcm9tRnJhZ21lbnQoY29udGVudCwgb3BlblN0YXJ0IC0gMSwgMSksIG9wZW5TdGFydCAtIDEsIG9wZW5BdEVuZCA/IG9wZW5TdGFydCAtIDEgOiBvcGVuRW5kKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudW5wbGFjZWQgPSBuZXcgU2xpY2UoZHJvcEZyb21GcmFnbWVudChjb250ZW50LCBvcGVuU3RhcnQsIDEpLCBvcGVuU3RhcnQsIG9wZW5FbmQpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIE1vdmUgY29udGVudCBmcm9tIHRoZSB1bnBsYWNlZCBzbGljZSBhdCBgc2xpY2VEZXB0aGAgdG8gdGhlXG4gICAgLy8gZnJvbnRpZXIgbm9kZSBhdCBgZnJvbnRpZXJEZXB0aGAuIENsb3NlIHRoYXQgZnJvbnRpZXIgbm9kZSB3aGVuXG4gICAgLy8gYXBwbGljYWJsZS5cbiAgICBwbGFjZU5vZGVzKHsgc2xpY2VEZXB0aCwgZnJvbnRpZXJEZXB0aCwgcGFyZW50LCBpbmplY3QsIHdyYXAgfSkge1xuICAgICAgICB3aGlsZSAodGhpcy5kZXB0aCA+IGZyb250aWVyRGVwdGgpXG4gICAgICAgICAgICB0aGlzLmNsb3NlRnJvbnRpZXJOb2RlKCk7XG4gICAgICAgIGlmICh3cmFwKVxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB3cmFwLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgICAgIHRoaXMub3BlbkZyb250aWVyTm9kZSh3cmFwW2ldKTtcbiAgICAgICAgbGV0IHNsaWNlID0gdGhpcy51bnBsYWNlZCwgZnJhZ21lbnQgPSBwYXJlbnQgPyBwYXJlbnQuY29udGVudCA6IHNsaWNlLmNvbnRlbnQ7XG4gICAgICAgIGxldCBvcGVuU3RhcnQgPSBzbGljZS5vcGVuU3RhcnQgLSBzbGljZURlcHRoO1xuICAgICAgICBsZXQgdGFrZW4gPSAwLCBhZGQgPSBbXTtcbiAgICAgICAgbGV0IHsgbWF0Y2gsIHR5cGUgfSA9IHRoaXMuZnJvbnRpZXJbZnJvbnRpZXJEZXB0aF07XG4gICAgICAgIGlmIChpbmplY3QpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5qZWN0LmNoaWxkQ291bnQ7IGkrKylcbiAgICAgICAgICAgICAgICBhZGQucHVzaChpbmplY3QuY2hpbGQoaSkpO1xuICAgICAgICAgICAgbWF0Y2ggPSBtYXRjaC5tYXRjaEZyYWdtZW50KGluamVjdCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQ29tcHV0ZXMgdGhlIGFtb3VudCBvZiAoZW5kKSBvcGVuIG5vZGVzIGF0IHRoZSBlbmQgb2YgdGhlXG4gICAgICAgIC8vIGZyYWdtZW50LiBXaGVuIDAsIHRoZSBwYXJlbnQgaXMgb3BlbiwgYnV0IG5vIG1vcmUuIFdoZW5cbiAgICAgICAgLy8gbmVnYXRpdmUsIG5vdGhpbmcgaXMgb3Blbi5cbiAgICAgICAgbGV0IG9wZW5FbmRDb3VudCA9IChmcmFnbWVudC5zaXplICsgc2xpY2VEZXB0aCkgLSAoc2xpY2UuY29udGVudC5zaXplIC0gc2xpY2Uub3BlbkVuZCk7XG4gICAgICAgIC8vIFNjYW4gb3ZlciB0aGUgZnJhZ21lbnQsIGZpdHRpbmcgYXMgbWFueSBjaGlsZCBub2RlcyBhc1xuICAgICAgICAvLyBwb3NzaWJsZS5cbiAgICAgICAgd2hpbGUgKHRha2VuIDwgZnJhZ21lbnQuY2hpbGRDb3VudCkge1xuICAgICAgICAgICAgbGV0IG5leHQgPSBmcmFnbWVudC5jaGlsZCh0YWtlbiksIG1hdGNoZXMgPSBtYXRjaC5tYXRjaFR5cGUobmV4dC50eXBlKTtcbiAgICAgICAgICAgIGlmICghbWF0Y2hlcylcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIHRha2VuKys7XG4gICAgICAgICAgICBpZiAodGFrZW4gPiAxIHx8IG9wZW5TdGFydCA9PSAwIHx8IG5leHQuY29udGVudC5zaXplKSB7IC8vIERyb3AgZW1wdHkgb3BlbiBub2Rlc1xuICAgICAgICAgICAgICAgIG1hdGNoID0gbWF0Y2hlcztcbiAgICAgICAgICAgICAgICBhZGQucHVzaChjbG9zZU5vZGVTdGFydChuZXh0Lm1hcmsodHlwZS5hbGxvd2VkTWFya3MobmV4dC5tYXJrcykpLCB0YWtlbiA9PSAxID8gb3BlblN0YXJ0IDogMCwgdGFrZW4gPT0gZnJhZ21lbnQuY2hpbGRDb3VudCA/IG9wZW5FbmRDb3VudCA6IC0xKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHRvRW5kID0gdGFrZW4gPT0gZnJhZ21lbnQuY2hpbGRDb3VudDtcbiAgICAgICAgaWYgKCF0b0VuZClcbiAgICAgICAgICAgIG9wZW5FbmRDb3VudCA9IC0xO1xuICAgICAgICB0aGlzLnBsYWNlZCA9IGFkZFRvRnJhZ21lbnQodGhpcy5wbGFjZWQsIGZyb250aWVyRGVwdGgsIEZyYWdtZW50LmZyb20oYWRkKSk7XG4gICAgICAgIHRoaXMuZnJvbnRpZXJbZnJvbnRpZXJEZXB0aF0ubWF0Y2ggPSBtYXRjaDtcbiAgICAgICAgLy8gSWYgdGhlIHBhcmVudCB0eXBlcyBtYXRjaCwgYW5kIHRoZSBlbnRpcmUgbm9kZSB3YXMgbW92ZWQsIGFuZFxuICAgICAgICAvLyBpdCdzIG5vdCBvcGVuLCBjbG9zZSB0aGlzIGZyb250aWVyIG5vZGUgcmlnaHQgYXdheS5cbiAgICAgICAgaWYgKHRvRW5kICYmIG9wZW5FbmRDb3VudCA8IDAgJiYgcGFyZW50ICYmIHBhcmVudC50eXBlID09IHRoaXMuZnJvbnRpZXJbdGhpcy5kZXB0aF0udHlwZSAmJiB0aGlzLmZyb250aWVyLmxlbmd0aCA+IDEpXG4gICAgICAgICAgICB0aGlzLmNsb3NlRnJvbnRpZXJOb2RlKCk7XG4gICAgICAgIC8vIEFkZCBuZXcgZnJvbnRpZXIgbm9kZXMgZm9yIGFueSBvcGVuIG5vZGVzIGF0IHRoZSBlbmQuXG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBjdXIgPSBmcmFnbWVudDsgaSA8IG9wZW5FbmRDb3VudDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgbm9kZSA9IGN1ci5sYXN0Q2hpbGQ7XG4gICAgICAgICAgICB0aGlzLmZyb250aWVyLnB1c2goeyB0eXBlOiBub2RlLnR5cGUsIG1hdGNoOiBub2RlLmNvbnRlbnRNYXRjaEF0KG5vZGUuY2hpbGRDb3VudCkgfSk7XG4gICAgICAgICAgICBjdXIgPSBub2RlLmNvbnRlbnQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gVXBkYXRlIGB0aGlzLnVucGxhY2VkYC4gRHJvcCB0aGUgZW50aXJlIG5vZGUgZnJvbSB3aGljaCB3ZVxuICAgICAgICAvLyBwbGFjZWQgaXQgd2UgZ290IHRvIGl0cyBlbmQsIG90aGVyd2lzZSBqdXN0IGRyb3AgdGhlIHBsYWNlZFxuICAgICAgICAvLyBub2Rlcy5cbiAgICAgICAgdGhpcy51bnBsYWNlZCA9ICF0b0VuZCA/IG5ldyBTbGljZShkcm9wRnJvbUZyYWdtZW50KHNsaWNlLmNvbnRlbnQsIHNsaWNlRGVwdGgsIHRha2VuKSwgc2xpY2Uub3BlblN0YXJ0LCBzbGljZS5vcGVuRW5kKVxuICAgICAgICAgICAgOiBzbGljZURlcHRoID09IDAgPyBTbGljZS5lbXB0eVxuICAgICAgICAgICAgICAgIDogbmV3IFNsaWNlKGRyb3BGcm9tRnJhZ21lbnQoc2xpY2UuY29udGVudCwgc2xpY2VEZXB0aCAtIDEsIDEpLCBzbGljZURlcHRoIC0gMSwgb3BlbkVuZENvdW50IDwgMCA/IHNsaWNlLm9wZW5FbmQgOiBzbGljZURlcHRoIC0gMSk7XG4gICAgfVxuICAgIG11c3RNb3ZlSW5saW5lKCkge1xuICAgICAgICBpZiAoIXRoaXMuJHRvLnBhcmVudC5pc1RleHRibG9jaylcbiAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgbGV0IHRvcCA9IHRoaXMuZnJvbnRpZXJbdGhpcy5kZXB0aF0sIGxldmVsO1xuICAgICAgICBpZiAoIXRvcC50eXBlLmlzVGV4dGJsb2NrIHx8ICFjb250ZW50QWZ0ZXJGaXRzKHRoaXMuJHRvLCB0aGlzLiR0by5kZXB0aCwgdG9wLnR5cGUsIHRvcC5tYXRjaCwgZmFsc2UpIHx8XG4gICAgICAgICAgICAodGhpcy4kdG8uZGVwdGggPT0gdGhpcy5kZXB0aCAmJiAobGV2ZWwgPSB0aGlzLmZpbmRDbG9zZUxldmVsKHRoaXMuJHRvKSkgJiYgbGV2ZWwuZGVwdGggPT0gdGhpcy5kZXB0aCkpXG4gICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIGxldCB7IGRlcHRoIH0gPSB0aGlzLiR0bywgYWZ0ZXIgPSB0aGlzLiR0by5hZnRlcihkZXB0aCk7XG4gICAgICAgIHdoaWxlIChkZXB0aCA+IDEgJiYgYWZ0ZXIgPT0gdGhpcy4kdG8uZW5kKC0tZGVwdGgpKVxuICAgICAgICAgICAgKythZnRlcjtcbiAgICAgICAgcmV0dXJuIGFmdGVyO1xuICAgIH1cbiAgICBmaW5kQ2xvc2VMZXZlbCgkdG8pIHtcbiAgICAgICAgc2NhbjogZm9yIChsZXQgaSA9IE1hdGgubWluKHRoaXMuZGVwdGgsICR0by5kZXB0aCk7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICBsZXQgeyBtYXRjaCwgdHlwZSB9ID0gdGhpcy5mcm9udGllcltpXTtcbiAgICAgICAgICAgIGxldCBkcm9wSW5uZXIgPSBpIDwgJHRvLmRlcHRoICYmICR0by5lbmQoaSArIDEpID09ICR0by5wb3MgKyAoJHRvLmRlcHRoIC0gKGkgKyAxKSk7XG4gICAgICAgICAgICBsZXQgZml0ID0gY29udGVudEFmdGVyRml0cygkdG8sIGksIHR5cGUsIG1hdGNoLCBkcm9wSW5uZXIpO1xuICAgICAgICAgICAgaWYgKCFmaXQpXG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICBmb3IgKGxldCBkID0gaSAtIDE7IGQgPj0gMDsgZC0tKSB7XG4gICAgICAgICAgICAgICAgbGV0IHsgbWF0Y2gsIHR5cGUgfSA9IHRoaXMuZnJvbnRpZXJbZF07XG4gICAgICAgICAgICAgICAgbGV0IG1hdGNoZXMgPSBjb250ZW50QWZ0ZXJGaXRzKCR0bywgZCwgdHlwZSwgbWF0Y2gsIHRydWUpO1xuICAgICAgICAgICAgICAgIGlmICghbWF0Y2hlcyB8fCBtYXRjaGVzLmNoaWxkQ291bnQpXG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlIHNjYW47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4geyBkZXB0aDogaSwgZml0LCBtb3ZlOiBkcm9wSW5uZXIgPyAkdG8uZG9jLnJlc29sdmUoJHRvLmFmdGVyKGkgKyAxKSkgOiAkdG8gfTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjbG9zZSgkdG8pIHtcbiAgICAgICAgbGV0IGNsb3NlID0gdGhpcy5maW5kQ2xvc2VMZXZlbCgkdG8pO1xuICAgICAgICBpZiAoIWNsb3NlKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIHdoaWxlICh0aGlzLmRlcHRoID4gY2xvc2UuZGVwdGgpXG4gICAgICAgICAgICB0aGlzLmNsb3NlRnJvbnRpZXJOb2RlKCk7XG4gICAgICAgIGlmIChjbG9zZS5maXQuY2hpbGRDb3VudClcbiAgICAgICAgICAgIHRoaXMucGxhY2VkID0gYWRkVG9GcmFnbWVudCh0aGlzLnBsYWNlZCwgY2xvc2UuZGVwdGgsIGNsb3NlLmZpdCk7XG4gICAgICAgICR0byA9IGNsb3NlLm1vdmU7XG4gICAgICAgIGZvciAobGV0IGQgPSBjbG9zZS5kZXB0aCArIDE7IGQgPD0gJHRvLmRlcHRoOyBkKyspIHtcbiAgICAgICAgICAgIGxldCBub2RlID0gJHRvLm5vZGUoZCksIGFkZCA9IG5vZGUudHlwZS5jb250ZW50TWF0Y2guZmlsbEJlZm9yZShub2RlLmNvbnRlbnQsIHRydWUsICR0by5pbmRleChkKSk7XG4gICAgICAgICAgICB0aGlzLm9wZW5Gcm9udGllck5vZGUobm9kZS50eXBlLCBub2RlLmF0dHJzLCBhZGQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAkdG87XG4gICAgfVxuICAgIG9wZW5Gcm9udGllck5vZGUodHlwZSwgYXR0cnMgPSBudWxsLCBjb250ZW50KSB7XG4gICAgICAgIGxldCB0b3AgPSB0aGlzLmZyb250aWVyW3RoaXMuZGVwdGhdO1xuICAgICAgICB0b3AubWF0Y2ggPSB0b3AubWF0Y2gubWF0Y2hUeXBlKHR5cGUpO1xuICAgICAgICB0aGlzLnBsYWNlZCA9IGFkZFRvRnJhZ21lbnQodGhpcy5wbGFjZWQsIHRoaXMuZGVwdGgsIEZyYWdtZW50LmZyb20odHlwZS5jcmVhdGUoYXR0cnMsIGNvbnRlbnQpKSk7XG4gICAgICAgIHRoaXMuZnJvbnRpZXIucHVzaCh7IHR5cGUsIG1hdGNoOiB0eXBlLmNvbnRlbnRNYXRjaCB9KTtcbiAgICB9XG4gICAgY2xvc2VGcm9udGllck5vZGUoKSB7XG4gICAgICAgIGxldCBvcGVuID0gdGhpcy5mcm9udGllci5wb3AoKTtcbiAgICAgICAgbGV0IGFkZCA9IG9wZW4ubWF0Y2guZmlsbEJlZm9yZShGcmFnbWVudC5lbXB0eSwgdHJ1ZSk7XG4gICAgICAgIGlmIChhZGQuY2hpbGRDb3VudClcbiAgICAgICAgICAgIHRoaXMucGxhY2VkID0gYWRkVG9GcmFnbWVudCh0aGlzLnBsYWNlZCwgdGhpcy5mcm9udGllci5sZW5ndGgsIGFkZCk7XG4gICAgfVxufVxuZnVuY3Rpb24gZHJvcEZyb21GcmFnbWVudChmcmFnbWVudCwgZGVwdGgsIGNvdW50KSB7XG4gICAgaWYgKGRlcHRoID09IDApXG4gICAgICAgIHJldHVybiBmcmFnbWVudC5jdXRCeUluZGV4KGNvdW50LCBmcmFnbWVudC5jaGlsZENvdW50KTtcbiAgICByZXR1cm4gZnJhZ21lbnQucmVwbGFjZUNoaWxkKDAsIGZyYWdtZW50LmZpcnN0Q2hpbGQuY29weShkcm9wRnJvbUZyYWdtZW50KGZyYWdtZW50LmZpcnN0Q2hpbGQuY29udGVudCwgZGVwdGggLSAxLCBjb3VudCkpKTtcbn1cbmZ1bmN0aW9uIGFkZFRvRnJhZ21lbnQoZnJhZ21lbnQsIGRlcHRoLCBjb250ZW50KSB7XG4gICAgaWYgKGRlcHRoID09IDApXG4gICAgICAgIHJldHVybiBmcmFnbWVudC5hcHBlbmQoY29udGVudCk7XG4gICAgcmV0dXJuIGZyYWdtZW50LnJlcGxhY2VDaGlsZChmcmFnbWVudC5jaGlsZENvdW50IC0gMSwgZnJhZ21lbnQubGFzdENoaWxkLmNvcHkoYWRkVG9GcmFnbWVudChmcmFnbWVudC5sYXN0Q2hpbGQuY29udGVudCwgZGVwdGggLSAxLCBjb250ZW50KSkpO1xufVxuZnVuY3Rpb24gY29udGVudEF0KGZyYWdtZW50LCBkZXB0aCkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGVwdGg7IGkrKylcbiAgICAgICAgZnJhZ21lbnQgPSBmcmFnbWVudC5maXJzdENoaWxkLmNvbnRlbnQ7XG4gICAgcmV0dXJuIGZyYWdtZW50O1xufVxuZnVuY3Rpb24gY2xvc2VOb2RlU3RhcnQobm9kZSwgb3BlblN0YXJ0LCBvcGVuRW5kKSB7XG4gICAgaWYgKG9wZW5TdGFydCA8PSAwKVxuICAgICAgICByZXR1cm4gbm9kZTtcbiAgICBsZXQgZnJhZyA9IG5vZGUuY29udGVudDtcbiAgICBpZiAob3BlblN0YXJ0ID4gMSlcbiAgICAgICAgZnJhZyA9IGZyYWcucmVwbGFjZUNoaWxkKDAsIGNsb3NlTm9kZVN0YXJ0KGZyYWcuZmlyc3RDaGlsZCwgb3BlblN0YXJ0IC0gMSwgZnJhZy5jaGlsZENvdW50ID09IDEgPyBvcGVuRW5kIC0gMSA6IDApKTtcbiAgICBpZiAob3BlblN0YXJ0ID4gMCkge1xuICAgICAgICBmcmFnID0gbm9kZS50eXBlLmNvbnRlbnRNYXRjaC5maWxsQmVmb3JlKGZyYWcpLmFwcGVuZChmcmFnKTtcbiAgICAgICAgaWYgKG9wZW5FbmQgPD0gMClcbiAgICAgICAgICAgIGZyYWcgPSBmcmFnLmFwcGVuZChub2RlLnR5cGUuY29udGVudE1hdGNoLm1hdGNoRnJhZ21lbnQoZnJhZykuZmlsbEJlZm9yZShGcmFnbWVudC5lbXB0eSwgdHJ1ZSkpO1xuICAgIH1cbiAgICByZXR1cm4gbm9kZS5jb3B5KGZyYWcpO1xufVxuZnVuY3Rpb24gY29udGVudEFmdGVyRml0cygkdG8sIGRlcHRoLCB0eXBlLCBtYXRjaCwgb3Blbikge1xuICAgIGxldCBub2RlID0gJHRvLm5vZGUoZGVwdGgpLCBpbmRleCA9IG9wZW4gPyAkdG8uaW5kZXhBZnRlcihkZXB0aCkgOiAkdG8uaW5kZXgoZGVwdGgpO1xuICAgIGlmIChpbmRleCA9PSBub2RlLmNoaWxkQ291bnQgJiYgIXR5cGUuY29tcGF0aWJsZUNvbnRlbnQobm9kZS50eXBlKSlcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgbGV0IGZpdCA9IG1hdGNoLmZpbGxCZWZvcmUobm9kZS5jb250ZW50LCB0cnVlLCBpbmRleCk7XG4gICAgcmV0dXJuIGZpdCAmJiAhaW52YWxpZE1hcmtzKHR5cGUsIG5vZGUuY29udGVudCwgaW5kZXgpID8gZml0IDogbnVsbDtcbn1cbmZ1bmN0aW9uIGludmFsaWRNYXJrcyh0eXBlLCBmcmFnbWVudCwgc3RhcnQpIHtcbiAgICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPCBmcmFnbWVudC5jaGlsZENvdW50OyBpKyspXG4gICAgICAgIGlmICghdHlwZS5hbGxvd3NNYXJrcyhmcmFnbWVudC5jaGlsZChpKS5tYXJrcykpXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICByZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiBkZWZpbmVzQ29udGVudCh0eXBlKSB7XG4gICAgcmV0dXJuIHR5cGUuc3BlYy5kZWZpbmluZyB8fCB0eXBlLnNwZWMuZGVmaW5pbmdGb3JDb250ZW50O1xufVxuZnVuY3Rpb24gcmVwbGFjZVJhbmdlKHRyLCBmcm9tLCB0bywgc2xpY2UpIHtcbiAgICBpZiAoIXNsaWNlLnNpemUpXG4gICAgICAgIHJldHVybiB0ci5kZWxldGVSYW5nZShmcm9tLCB0byk7XG4gICAgbGV0ICRmcm9tID0gdHIuZG9jLnJlc29sdmUoZnJvbSksICR0byA9IHRyLmRvYy5yZXNvbHZlKHRvKTtcbiAgICBpZiAoZml0c1RyaXZpYWxseSgkZnJvbSwgJHRvLCBzbGljZSkpXG4gICAgICAgIHJldHVybiB0ci5zdGVwKG5ldyBSZXBsYWNlU3RlcChmcm9tLCB0bywgc2xpY2UpKTtcbiAgICBsZXQgdGFyZ2V0RGVwdGhzID0gY292ZXJlZERlcHRocygkZnJvbSwgdHIuZG9jLnJlc29sdmUodG8pKTtcbiAgICAvLyBDYW4ndCByZXBsYWNlIHRoZSB3aG9sZSBkb2N1bWVudCwgc28gcmVtb3ZlIDAgaWYgaXQncyBwcmVzZW50XG4gICAgaWYgKHRhcmdldERlcHRoc1t0YXJnZXREZXB0aHMubGVuZ3RoIC0gMV0gPT0gMClcbiAgICAgICAgdGFyZ2V0RGVwdGhzLnBvcCgpO1xuICAgIC8vIE5lZ2F0aXZlIG51bWJlcnMgcmVwcmVzZW50IG5vdCBleHBhbnNpb24gb3ZlciB0aGUgd2hvbGUgbm9kZSBhdFxuICAgIC8vIHRoYXQgZGVwdGgsIGJ1dCByZXBsYWNpbmcgZnJvbSAkZnJvbS5iZWZvcmUoLUQpIHRvICR0by5wb3MuXG4gICAgbGV0IHByZWZlcnJlZFRhcmdldCA9IC0oJGZyb20uZGVwdGggKyAxKTtcbiAgICB0YXJnZXREZXB0aHMudW5zaGlmdChwcmVmZXJyZWRUYXJnZXQpO1xuICAgIC8vIFRoaXMgbG9vcCBwaWNrcyBhIHByZWZlcnJlZCB0YXJnZXQgZGVwdGgsIGlmIG9uZSBvZiB0aGUgY292ZXJpbmdcbiAgICAvLyBkZXB0aHMgaXMgbm90IG91dHNpZGUgb2YgYSBkZWZpbmluZyBub2RlLCBhbmQgYWRkcyBuZWdhdGl2ZVxuICAgIC8vIGRlcHRocyBmb3IgYW55IGRlcHRoIHRoYXQgaGFzICRmcm9tIGF0IGl0cyBzdGFydCBhbmQgZG9lcyBub3RcbiAgICAvLyBjcm9zcyBhIGRlZmluaW5nIG5vZGUuXG4gICAgZm9yIChsZXQgZCA9ICRmcm9tLmRlcHRoLCBwb3MgPSAkZnJvbS5wb3MgLSAxOyBkID4gMDsgZC0tLCBwb3MtLSkge1xuICAgICAgICBsZXQgc3BlYyA9ICRmcm9tLm5vZGUoZCkudHlwZS5zcGVjO1xuICAgICAgICBpZiAoc3BlYy5kZWZpbmluZyB8fCBzcGVjLmRlZmluaW5nQXNDb250ZXh0IHx8IHNwZWMuaXNvbGF0aW5nKVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGlmICh0YXJnZXREZXB0aHMuaW5kZXhPZihkKSA+IC0xKVxuICAgICAgICAgICAgcHJlZmVycmVkVGFyZ2V0ID0gZDtcbiAgICAgICAgZWxzZSBpZiAoJGZyb20uYmVmb3JlKGQpID09IHBvcylcbiAgICAgICAgICAgIHRhcmdldERlcHRocy5zcGxpY2UoMSwgMCwgLWQpO1xuICAgIH1cbiAgICAvLyBUcnkgdG8gZml0IGVhY2ggcG9zc2libGUgZGVwdGggb2YgdGhlIHNsaWNlIGludG8gZWFjaCBwb3NzaWJsZVxuICAgIC8vIHRhcmdldCBkZXB0aCwgc3RhcnRpbmcgd2l0aCB0aGUgcHJlZmVycmVkIGRlcHRocy5cbiAgICBsZXQgcHJlZmVycmVkVGFyZ2V0SW5kZXggPSB0YXJnZXREZXB0aHMuaW5kZXhPZihwcmVmZXJyZWRUYXJnZXQpO1xuICAgIGxldCBsZWZ0Tm9kZXMgPSBbXSwgcHJlZmVycmVkRGVwdGggPSBzbGljZS5vcGVuU3RhcnQ7XG4gICAgZm9yIChsZXQgY29udGVudCA9IHNsaWNlLmNvbnRlbnQsIGkgPSAwOzsgaSsrKSB7XG4gICAgICAgIGxldCBub2RlID0gY29udGVudC5maXJzdENoaWxkO1xuICAgICAgICBsZWZ0Tm9kZXMucHVzaChub2RlKTtcbiAgICAgICAgaWYgKGkgPT0gc2xpY2Uub3BlblN0YXJ0KVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNvbnRlbnQgPSBub2RlLmNvbnRlbnQ7XG4gICAgfVxuICAgIC8vIEJhY2sgdXAgcHJlZmVycmVkRGVwdGggdG8gY292ZXIgZGVmaW5pbmcgdGV4dGJsb2NrcyBkaXJlY3RseVxuICAgIC8vIGFib3ZlIGl0LCBwb3NzaWJseSBza2lwcGluZyBhIG5vbi1kZWZpbmluZyB0ZXh0YmxvY2suXG4gICAgZm9yIChsZXQgZCA9IHByZWZlcnJlZERlcHRoIC0gMTsgZCA+PSAwOyBkLS0pIHtcbiAgICAgICAgbGV0IGxlZnROb2RlID0gbGVmdE5vZGVzW2RdLCBkZWYgPSBkZWZpbmVzQ29udGVudChsZWZ0Tm9kZS50eXBlKTtcbiAgICAgICAgaWYgKGRlZiAmJiAhbGVmdE5vZGUuc2FtZU1hcmt1cCgkZnJvbS5ub2RlKE1hdGguYWJzKHByZWZlcnJlZFRhcmdldCkgLSAxKSkpXG4gICAgICAgICAgICBwcmVmZXJyZWREZXB0aCA9IGQ7XG4gICAgICAgIGVsc2UgaWYgKGRlZiB8fCAhbGVmdE5vZGUudHlwZS5pc1RleHRibG9jaylcbiAgICAgICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBmb3IgKGxldCBqID0gc2xpY2Uub3BlblN0YXJ0OyBqID49IDA7IGotLSkge1xuICAgICAgICBsZXQgb3BlbkRlcHRoID0gKGogKyBwcmVmZXJyZWREZXB0aCArIDEpICUgKHNsaWNlLm9wZW5TdGFydCArIDEpO1xuICAgICAgICBsZXQgaW5zZXJ0ID0gbGVmdE5vZGVzW29wZW5EZXB0aF07XG4gICAgICAgIGlmICghaW5zZXJ0KVxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGFyZ2V0RGVwdGhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAvLyBMb29wIG92ZXIgcG9zc2libGUgZXhwYW5zaW9uIGxldmVscywgc3RhcnRpbmcgd2l0aCB0aGVcbiAgICAgICAgICAgIC8vIHByZWZlcnJlZCBvbmVcbiAgICAgICAgICAgIGxldCB0YXJnZXREZXB0aCA9IHRhcmdldERlcHRoc1soaSArIHByZWZlcnJlZFRhcmdldEluZGV4KSAlIHRhcmdldERlcHRocy5sZW5ndGhdLCBleHBhbmQgPSB0cnVlO1xuICAgICAgICAgICAgaWYgKHRhcmdldERlcHRoIDwgMCkge1xuICAgICAgICAgICAgICAgIGV4cGFuZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHRhcmdldERlcHRoID0gLXRhcmdldERlcHRoO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IHBhcmVudCA9ICRmcm9tLm5vZGUodGFyZ2V0RGVwdGggLSAxKSwgaW5kZXggPSAkZnJvbS5pbmRleCh0YXJnZXREZXB0aCAtIDEpO1xuICAgICAgICAgICAgaWYgKHBhcmVudC5jYW5SZXBsYWNlV2l0aChpbmRleCwgaW5kZXgsIGluc2VydC50eXBlLCBpbnNlcnQubWFya3MpKVxuICAgICAgICAgICAgICAgIHJldHVybiB0ci5yZXBsYWNlKCRmcm9tLmJlZm9yZSh0YXJnZXREZXB0aCksIGV4cGFuZCA/ICR0by5hZnRlcih0YXJnZXREZXB0aCkgOiB0bywgbmV3IFNsaWNlKGNsb3NlRnJhZ21lbnQoc2xpY2UuY29udGVudCwgMCwgc2xpY2Uub3BlblN0YXJ0LCBvcGVuRGVwdGgpLCBvcGVuRGVwdGgsIHNsaWNlLm9wZW5FbmQpKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBsZXQgc3RhcnRTdGVwcyA9IHRyLnN0ZXBzLmxlbmd0aDtcbiAgICBmb3IgKGxldCBpID0gdGFyZ2V0RGVwdGhzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgIHRyLnJlcGxhY2UoZnJvbSwgdG8sIHNsaWNlKTtcbiAgICAgICAgaWYgKHRyLnN0ZXBzLmxlbmd0aCA+IHN0YXJ0U3RlcHMpXG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgbGV0IGRlcHRoID0gdGFyZ2V0RGVwdGhzW2ldO1xuICAgICAgICBpZiAoZGVwdGggPCAwKVxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIGZyb20gPSAkZnJvbS5iZWZvcmUoZGVwdGgpO1xuICAgICAgICB0byA9ICR0by5hZnRlcihkZXB0aCk7XG4gICAgfVxufVxuZnVuY3Rpb24gY2xvc2VGcmFnbWVudChmcmFnbWVudCwgZGVwdGgsIG9sZE9wZW4sIG5ld09wZW4sIHBhcmVudCkge1xuICAgIGlmIChkZXB0aCA8IG9sZE9wZW4pIHtcbiAgICAgICAgbGV0IGZpcnN0ID0gZnJhZ21lbnQuZmlyc3RDaGlsZDtcbiAgICAgICAgZnJhZ21lbnQgPSBmcmFnbWVudC5yZXBsYWNlQ2hpbGQoMCwgZmlyc3QuY29weShjbG9zZUZyYWdtZW50KGZpcnN0LmNvbnRlbnQsIGRlcHRoICsgMSwgb2xkT3BlbiwgbmV3T3BlbiwgZmlyc3QpKSk7XG4gICAgfVxuICAgIGlmIChkZXB0aCA+IG5ld09wZW4pIHtcbiAgICAgICAgbGV0IG1hdGNoID0gcGFyZW50LmNvbnRlbnRNYXRjaEF0KDApO1xuICAgICAgICBsZXQgc3RhcnQgPSBtYXRjaC5maWxsQmVmb3JlKGZyYWdtZW50KS5hcHBlbmQoZnJhZ21lbnQpO1xuICAgICAgICBmcmFnbWVudCA9IHN0YXJ0LmFwcGVuZChtYXRjaC5tYXRjaEZyYWdtZW50KHN0YXJ0KS5maWxsQmVmb3JlKEZyYWdtZW50LmVtcHR5LCB0cnVlKSk7XG4gICAgfVxuICAgIHJldHVybiBmcmFnbWVudDtcbn1cbmZ1bmN0aW9uIHJlcGxhY2VSYW5nZVdpdGgodHIsIGZyb20sIHRvLCBub2RlKSB7XG4gICAgaWYgKCFub2RlLmlzSW5saW5lICYmIGZyb20gPT0gdG8gJiYgdHIuZG9jLnJlc29sdmUoZnJvbSkucGFyZW50LmNvbnRlbnQuc2l6ZSkge1xuICAgICAgICBsZXQgcG9pbnQgPSBpbnNlcnRQb2ludCh0ci5kb2MsIGZyb20sIG5vZGUudHlwZSk7XG4gICAgICAgIGlmIChwb2ludCAhPSBudWxsKVxuICAgICAgICAgICAgZnJvbSA9IHRvID0gcG9pbnQ7XG4gICAgfVxuICAgIHRyLnJlcGxhY2VSYW5nZShmcm9tLCB0bywgbmV3IFNsaWNlKEZyYWdtZW50LmZyb20obm9kZSksIDAsIDApKTtcbn1cbmZ1bmN0aW9uIGRlbGV0ZVJhbmdlKHRyLCBmcm9tLCB0bykge1xuICAgIGxldCAkZnJvbSA9IHRyLmRvYy5yZXNvbHZlKGZyb20pLCAkdG8gPSB0ci5kb2MucmVzb2x2ZSh0byk7XG4gICAgbGV0IGNvdmVyZWQgPSBjb3ZlcmVkRGVwdGhzKCRmcm9tLCAkdG8pO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY292ZXJlZC5sZW5ndGg7IGkrKykge1xuICAgICAgICBsZXQgZGVwdGggPSBjb3ZlcmVkW2ldLCBsYXN0ID0gaSA9PSBjb3ZlcmVkLmxlbmd0aCAtIDE7XG4gICAgICAgIGlmICgobGFzdCAmJiBkZXB0aCA9PSAwKSB8fCAkZnJvbS5ub2RlKGRlcHRoKS50eXBlLmNvbnRlbnRNYXRjaC52YWxpZEVuZClcbiAgICAgICAgICAgIHJldHVybiB0ci5kZWxldGUoJGZyb20uc3RhcnQoZGVwdGgpLCAkdG8uZW5kKGRlcHRoKSk7XG4gICAgICAgIGlmIChkZXB0aCA+IDAgJiYgKGxhc3QgfHwgJGZyb20ubm9kZShkZXB0aCAtIDEpLmNhblJlcGxhY2UoJGZyb20uaW5kZXgoZGVwdGggLSAxKSwgJHRvLmluZGV4QWZ0ZXIoZGVwdGggLSAxKSkpKVxuICAgICAgICAgICAgcmV0dXJuIHRyLmRlbGV0ZSgkZnJvbS5iZWZvcmUoZGVwdGgpLCAkdG8uYWZ0ZXIoZGVwdGgpKTtcbiAgICB9XG4gICAgZm9yIChsZXQgZCA9IDE7IGQgPD0gJGZyb20uZGVwdGggJiYgZCA8PSAkdG8uZGVwdGg7IGQrKykge1xuICAgICAgICBpZiAoZnJvbSAtICRmcm9tLnN0YXJ0KGQpID09ICRmcm9tLmRlcHRoIC0gZCAmJiB0byA+ICRmcm9tLmVuZChkKSAmJiAkdG8uZW5kKGQpIC0gdG8gIT0gJHRvLmRlcHRoIC0gZCAmJlxuICAgICAgICAgICAgJGZyb20uc3RhcnQoZCAtIDEpID09ICR0by5zdGFydChkIC0gMSkgJiYgJGZyb20ubm9kZShkIC0gMSkuY2FuUmVwbGFjZSgkZnJvbS5pbmRleChkIC0gMSksICR0by5pbmRleChkIC0gMSkpKVxuICAgICAgICAgICAgcmV0dXJuIHRyLmRlbGV0ZSgkZnJvbS5iZWZvcmUoZCksIHRvKTtcbiAgICB9XG4gICAgdHIuZGVsZXRlKGZyb20sIHRvKTtcbn1cbi8vIFJldHVybnMgYW4gYXJyYXkgb2YgYWxsIGRlcHRocyBmb3Igd2hpY2ggJGZyb20gLSAkdG8gc3BhbnMgdGhlXG4vLyB3aG9sZSBjb250ZW50IG9mIHRoZSBub2RlcyBhdCB0aGF0IGRlcHRoLlxuZnVuY3Rpb24gY292ZXJlZERlcHRocygkZnJvbSwgJHRvKSB7XG4gICAgbGV0IHJlc3VsdCA9IFtdLCBtaW5EZXB0aCA9IE1hdGgubWluKCRmcm9tLmRlcHRoLCAkdG8uZGVwdGgpO1xuICAgIGZvciAobGV0IGQgPSBtaW5EZXB0aDsgZCA+PSAwOyBkLS0pIHtcbiAgICAgICAgbGV0IHN0YXJ0ID0gJGZyb20uc3RhcnQoZCk7XG4gICAgICAgIGlmIChzdGFydCA8ICRmcm9tLnBvcyAtICgkZnJvbS5kZXB0aCAtIGQpIHx8XG4gICAgICAgICAgICAkdG8uZW5kKGQpID4gJHRvLnBvcyArICgkdG8uZGVwdGggLSBkKSB8fFxuICAgICAgICAgICAgJGZyb20ubm9kZShkKS50eXBlLnNwZWMuaXNvbGF0aW5nIHx8XG4gICAgICAgICAgICAkdG8ubm9kZShkKS50eXBlLnNwZWMuaXNvbGF0aW5nKVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGlmIChzdGFydCA9PSAkdG8uc3RhcnQoZCkgfHxcbiAgICAgICAgICAgIChkID09ICRmcm9tLmRlcHRoICYmIGQgPT0gJHRvLmRlcHRoICYmICRmcm9tLnBhcmVudC5pbmxpbmVDb250ZW50ICYmICR0by5wYXJlbnQuaW5saW5lQ29udGVudCAmJlxuICAgICAgICAgICAgICAgIGQgJiYgJHRvLnN0YXJ0KGQgLSAxKSA9PSBzdGFydCAtIDEpKVxuICAgICAgICAgICAgcmVzdWx0LnB1c2goZCk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuVXBkYXRlIGFuIGF0dHJpYnV0ZSBpbiBhIHNwZWNpZmljIG5vZGUuXG4qL1xuY2xhc3MgQXR0clN0ZXAgZXh0ZW5kcyBTdGVwIHtcbiAgICAvKipcbiAgICBDb25zdHJ1Y3QgYW4gYXR0cmlidXRlIHN0ZXAuXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBUaGUgcG9zaXRpb24gb2YgdGhlIHRhcmdldCBub2RlLlxuICAgICovXG4gICAgcG9zLCBcbiAgICAvKipcbiAgICBUaGUgYXR0cmlidXRlIHRvIHNldC5cbiAgICAqL1xuICAgIGF0dHIsIFxuICAgIC8vIFRoZSBhdHRyaWJ1dGUncyBuZXcgdmFsdWUuXG4gICAgdmFsdWUpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5wb3MgPSBwb3M7XG4gICAgICAgIHRoaXMuYXR0ciA9IGF0dHI7XG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICB9XG4gICAgYXBwbHkoZG9jKSB7XG4gICAgICAgIGxldCBub2RlID0gZG9jLm5vZGVBdCh0aGlzLnBvcyk7XG4gICAgICAgIGlmICghbm9kZSlcbiAgICAgICAgICAgIHJldHVybiBTdGVwUmVzdWx0LmZhaWwoXCJObyBub2RlIGF0IGF0dHJpYnV0ZSBzdGVwJ3MgcG9zaXRpb25cIik7XG4gICAgICAgIGxldCBhdHRycyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgICAgIGZvciAobGV0IG5hbWUgaW4gbm9kZS5hdHRycylcbiAgICAgICAgICAgIGF0dHJzW25hbWVdID0gbm9kZS5hdHRyc1tuYW1lXTtcbiAgICAgICAgYXR0cnNbdGhpcy5hdHRyXSA9IHRoaXMudmFsdWU7XG4gICAgICAgIGxldCB1cGRhdGVkID0gbm9kZS50eXBlLmNyZWF0ZShhdHRycywgbnVsbCwgbm9kZS5tYXJrcyk7XG4gICAgICAgIHJldHVybiBTdGVwUmVzdWx0LmZyb21SZXBsYWNlKGRvYywgdGhpcy5wb3MsIHRoaXMucG9zICsgMSwgbmV3IFNsaWNlKEZyYWdtZW50LmZyb20odXBkYXRlZCksIDAsIG5vZGUuaXNMZWFmID8gMCA6IDEpKTtcbiAgICB9XG4gICAgZ2V0TWFwKCkge1xuICAgICAgICByZXR1cm4gU3RlcE1hcC5lbXB0eTtcbiAgICB9XG4gICAgaW52ZXJ0KGRvYykge1xuICAgICAgICByZXR1cm4gbmV3IEF0dHJTdGVwKHRoaXMucG9zLCB0aGlzLmF0dHIsIGRvYy5ub2RlQXQodGhpcy5wb3MpLmF0dHJzW3RoaXMuYXR0cl0pO1xuICAgIH1cbiAgICBtYXAobWFwcGluZykge1xuICAgICAgICBsZXQgcG9zID0gbWFwcGluZy5tYXBSZXN1bHQodGhpcy5wb3MsIDEpO1xuICAgICAgICByZXR1cm4gcG9zLmRlbGV0ZWRBZnRlciA/IG51bGwgOiBuZXcgQXR0clN0ZXAocG9zLnBvcywgdGhpcy5hdHRyLCB0aGlzLnZhbHVlKTtcbiAgICB9XG4gICAgdG9KU09OKCkge1xuICAgICAgICByZXR1cm4geyBzdGVwVHlwZTogXCJhdHRyXCIsIHBvczogdGhpcy5wb3MsIGF0dHI6IHRoaXMuYXR0ciwgdmFsdWU6IHRoaXMudmFsdWUgfTtcbiAgICB9XG4gICAgc3RhdGljIGZyb21KU09OKHNjaGVtYSwganNvbikge1xuICAgICAgICBpZiAodHlwZW9mIGpzb24ucG9zICE9IFwibnVtYmVyXCIgfHwgdHlwZW9mIGpzb24uYXR0ciAhPSBcInN0cmluZ1wiKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIGlucHV0IGZvciBBdHRyU3RlcC5mcm9tSlNPTlwiKTtcbiAgICAgICAgcmV0dXJuIG5ldyBBdHRyU3RlcChqc29uLnBvcywganNvbi5hdHRyLCBqc29uLnZhbHVlKTtcbiAgICB9XG59XG5TdGVwLmpzb25JRChcImF0dHJcIiwgQXR0clN0ZXApO1xuLyoqXG5VcGRhdGUgYW4gYXR0cmlidXRlIGluIHRoZSBkb2Mgbm9kZS5cbiovXG5jbGFzcyBEb2NBdHRyU3RlcCBleHRlbmRzIFN0ZXAge1xuICAgIC8qKlxuICAgIENvbnN0cnVjdCBhbiBhdHRyaWJ1dGUgc3RlcC5cbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgIFRoZSBhdHRyaWJ1dGUgdG8gc2V0LlxuICAgICovXG4gICAgYXR0ciwgXG4gICAgLy8gVGhlIGF0dHJpYnV0ZSdzIG5ldyB2YWx1ZS5cbiAgICB2YWx1ZSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLmF0dHIgPSBhdHRyO1xuICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgfVxuICAgIGFwcGx5KGRvYykge1xuICAgICAgICBsZXQgYXR0cnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICBmb3IgKGxldCBuYW1lIGluIGRvYy5hdHRycylcbiAgICAgICAgICAgIGF0dHJzW25hbWVdID0gZG9jLmF0dHJzW25hbWVdO1xuICAgICAgICBhdHRyc1t0aGlzLmF0dHJdID0gdGhpcy52YWx1ZTtcbiAgICAgICAgbGV0IHVwZGF0ZWQgPSBkb2MudHlwZS5jcmVhdGUoYXR0cnMsIGRvYy5jb250ZW50LCBkb2MubWFya3MpO1xuICAgICAgICByZXR1cm4gU3RlcFJlc3VsdC5vayh1cGRhdGVkKTtcbiAgICB9XG4gICAgZ2V0TWFwKCkge1xuICAgICAgICByZXR1cm4gU3RlcE1hcC5lbXB0eTtcbiAgICB9XG4gICAgaW52ZXJ0KGRvYykge1xuICAgICAgICByZXR1cm4gbmV3IERvY0F0dHJTdGVwKHRoaXMuYXR0ciwgZG9jLmF0dHJzW3RoaXMuYXR0cl0pO1xuICAgIH1cbiAgICBtYXAobWFwcGluZykge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgdG9KU09OKCkge1xuICAgICAgICByZXR1cm4geyBzdGVwVHlwZTogXCJkb2NBdHRyXCIsIGF0dHI6IHRoaXMuYXR0ciwgdmFsdWU6IHRoaXMudmFsdWUgfTtcbiAgICB9XG4gICAgc3RhdGljIGZyb21KU09OKHNjaGVtYSwganNvbikge1xuICAgICAgICBpZiAodHlwZW9mIGpzb24uYXR0ciAhPSBcInN0cmluZ1wiKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJJbnZhbGlkIGlucHV0IGZvciBEb2NBdHRyU3RlcC5mcm9tSlNPTlwiKTtcbiAgICAgICAgcmV0dXJuIG5ldyBEb2NBdHRyU3RlcChqc29uLmF0dHIsIGpzb24udmFsdWUpO1xuICAgIH1cbn1cblN0ZXAuanNvbklEKFwiZG9jQXR0clwiLCBEb2NBdHRyU3RlcCk7XG5cbi8qKlxuQGludGVybmFsXG4qL1xubGV0IFRyYW5zZm9ybUVycm9yID0gY2xhc3MgZXh0ZW5kcyBFcnJvciB7XG59O1xuVHJhbnNmb3JtRXJyb3IgPSBmdW5jdGlvbiBUcmFuc2Zvcm1FcnJvcihtZXNzYWdlKSB7XG4gICAgbGV0IGVyciA9IEVycm9yLmNhbGwodGhpcywgbWVzc2FnZSk7XG4gICAgZXJyLl9fcHJvdG9fXyA9IFRyYW5zZm9ybUVycm9yLnByb3RvdHlwZTtcbiAgICByZXR1cm4gZXJyO1xufTtcblRyYW5zZm9ybUVycm9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoRXJyb3IucHJvdG90eXBlKTtcblRyYW5zZm9ybUVycm9yLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IFRyYW5zZm9ybUVycm9yO1xuVHJhbnNmb3JtRXJyb3IucHJvdG90eXBlLm5hbWUgPSBcIlRyYW5zZm9ybUVycm9yXCI7XG4vKipcbkFic3RyYWN0aW9uIHRvIGJ1aWxkIHVwIGFuZCB0cmFjayBhbiBhcnJheSBvZlxuW3N0ZXBzXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jdHJhbnNmb3JtLlN0ZXApIHJlcHJlc2VudGluZyBhIGRvY3VtZW50IHRyYW5zZm9ybWF0aW9uLlxuXG5Nb3N0IHRyYW5zZm9ybWluZyBtZXRob2RzIHJldHVybiB0aGUgYFRyYW5zZm9ybWAgb2JqZWN0IGl0c2VsZiwgc29cbnRoYXQgdGhleSBjYW4gYmUgY2hhaW5lZC5cbiovXG5jbGFzcyBUcmFuc2Zvcm0ge1xuICAgIC8qKlxuICAgIENyZWF0ZSBhIHRyYW5zZm9ybSB0aGF0IHN0YXJ0cyB3aXRoIHRoZSBnaXZlbiBkb2N1bWVudC5cbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgIFRoZSBjdXJyZW50IGRvY3VtZW50ICh0aGUgcmVzdWx0IG9mIGFwcGx5aW5nIHRoZSBzdGVwcyBpbiB0aGVcbiAgICB0cmFuc2Zvcm0pLlxuICAgICovXG4gICAgZG9jKSB7XG4gICAgICAgIHRoaXMuZG9jID0gZG9jO1xuICAgICAgICAvKipcbiAgICAgICAgVGhlIHN0ZXBzIGluIHRoaXMgdHJhbnNmb3JtLlxuICAgICAgICAqL1xuICAgICAgICB0aGlzLnN0ZXBzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICBUaGUgZG9jdW1lbnRzIGJlZm9yZSBlYWNoIG9mIHRoZSBzdGVwcy5cbiAgICAgICAgKi9cbiAgICAgICAgdGhpcy5kb2NzID0gW107XG4gICAgICAgIC8qKlxuICAgICAgICBBIG1hcHBpbmcgd2l0aCB0aGUgbWFwcyBmb3IgZWFjaCBvZiB0aGUgc3RlcHMgaW4gdGhpcyB0cmFuc2Zvcm0uXG4gICAgICAgICovXG4gICAgICAgIHRoaXMubWFwcGluZyA9IG5ldyBNYXBwaW5nO1xuICAgIH1cbiAgICAvKipcbiAgICBUaGUgc3RhcnRpbmcgZG9jdW1lbnQuXG4gICAgKi9cbiAgICBnZXQgYmVmb3JlKCkgeyByZXR1cm4gdGhpcy5kb2NzLmxlbmd0aCA/IHRoaXMuZG9jc1swXSA6IHRoaXMuZG9jOyB9XG4gICAgLyoqXG4gICAgQXBwbHkgYSBuZXcgc3RlcCBpbiB0aGlzIHRyYW5zZm9ybSwgc2F2aW5nIHRoZSByZXN1bHQuIFRocm93cyBhblxuICAgIGVycm9yIHdoZW4gdGhlIHN0ZXAgZmFpbHMuXG4gICAgKi9cbiAgICBzdGVwKHN0ZXApIHtcbiAgICAgICAgbGV0IHJlc3VsdCA9IHRoaXMubWF5YmVTdGVwKHN0ZXApO1xuICAgICAgICBpZiAocmVzdWx0LmZhaWxlZClcbiAgICAgICAgICAgIHRocm93IG5ldyBUcmFuc2Zvcm1FcnJvcihyZXN1bHQuZmFpbGVkKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIFRyeSB0byBhcHBseSBhIHN0ZXAgaW4gdGhpcyB0cmFuc2Zvcm1hdGlvbiwgaWdub3JpbmcgaXQgaWYgaXRcbiAgICBmYWlscy4gUmV0dXJucyB0aGUgc3RlcCByZXN1bHQuXG4gICAgKi9cbiAgICBtYXliZVN0ZXAoc3RlcCkge1xuICAgICAgICBsZXQgcmVzdWx0ID0gc3RlcC5hcHBseSh0aGlzLmRvYyk7XG4gICAgICAgIGlmICghcmVzdWx0LmZhaWxlZClcbiAgICAgICAgICAgIHRoaXMuYWRkU3RlcChzdGVwLCByZXN1bHQuZG9jKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgLyoqXG4gICAgVHJ1ZSB3aGVuIHRoZSBkb2N1bWVudCBoYXMgYmVlbiBjaGFuZ2VkICh3aGVuIHRoZXJlIGFyZSBhbnlcbiAgICBzdGVwcykuXG4gICAgKi9cbiAgICBnZXQgZG9jQ2hhbmdlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RlcHMubGVuZ3RoID4gMDtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBhZGRTdGVwKHN0ZXAsIGRvYykge1xuICAgICAgICB0aGlzLmRvY3MucHVzaCh0aGlzLmRvYyk7XG4gICAgICAgIHRoaXMuc3RlcHMucHVzaChzdGVwKTtcbiAgICAgICAgdGhpcy5tYXBwaW5nLmFwcGVuZE1hcChzdGVwLmdldE1hcCgpKTtcbiAgICAgICAgdGhpcy5kb2MgPSBkb2M7XG4gICAgfVxuICAgIC8qKlxuICAgIFJlcGxhY2UgdGhlIHBhcnQgb2YgdGhlIGRvY3VtZW50IGJldHdlZW4gYGZyb21gIGFuZCBgdG9gIHdpdGggdGhlXG4gICAgZ2l2ZW4gYHNsaWNlYC5cbiAgICAqL1xuICAgIHJlcGxhY2UoZnJvbSwgdG8gPSBmcm9tLCBzbGljZSA9IFNsaWNlLmVtcHR5KSB7XG4gICAgICAgIGxldCBzdGVwID0gcmVwbGFjZVN0ZXAodGhpcy5kb2MsIGZyb20sIHRvLCBzbGljZSk7XG4gICAgICAgIGlmIChzdGVwKVxuICAgICAgICAgICAgdGhpcy5zdGVwKHN0ZXApO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgUmVwbGFjZSB0aGUgZ2l2ZW4gcmFuZ2Ugd2l0aCB0aGUgZ2l2ZW4gY29udGVudCwgd2hpY2ggbWF5IGJlIGFcbiAgICBmcmFnbWVudCwgbm9kZSwgb3IgYXJyYXkgb2Ygbm9kZXMuXG4gICAgKi9cbiAgICByZXBsYWNlV2l0aChmcm9tLCB0bywgY29udGVudCkge1xuICAgICAgICByZXR1cm4gdGhpcy5yZXBsYWNlKGZyb20sIHRvLCBuZXcgU2xpY2UoRnJhZ21lbnQuZnJvbShjb250ZW50KSwgMCwgMCkpO1xuICAgIH1cbiAgICAvKipcbiAgICBEZWxldGUgdGhlIGNvbnRlbnQgYmV0d2VlbiB0aGUgZ2l2ZW4gcG9zaXRpb25zLlxuICAgICovXG4gICAgZGVsZXRlKGZyb20sIHRvKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlcGxhY2UoZnJvbSwgdG8sIFNsaWNlLmVtcHR5KTtcbiAgICB9XG4gICAgLyoqXG4gICAgSW5zZXJ0IHRoZSBnaXZlbiBjb250ZW50IGF0IHRoZSBnaXZlbiBwb3NpdGlvbi5cbiAgICAqL1xuICAgIGluc2VydChwb3MsIGNvbnRlbnQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVwbGFjZVdpdGgocG9zLCBwb3MsIGNvbnRlbnQpO1xuICAgIH1cbiAgICAvKipcbiAgICBSZXBsYWNlIGEgcmFuZ2Ugb2YgdGhlIGRvY3VtZW50IHdpdGggYSBnaXZlbiBzbGljZSwgdXNpbmdcbiAgICBgZnJvbWAsIGB0b2AsIGFuZCB0aGUgc2xpY2Unc1xuICAgIFtgb3BlblN0YXJ0YF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLlNsaWNlLm9wZW5TdGFydCkgcHJvcGVydHkgYXMgaGludHMsIHJhdGhlclxuICAgIHRoYW4gZml4ZWQgc3RhcnQgYW5kIGVuZCBwb2ludHMuIFRoaXMgbWV0aG9kIG1heSBncm93IHRoZVxuICAgIHJlcGxhY2VkIGFyZWEgb3IgY2xvc2Ugb3BlbiBub2RlcyBpbiB0aGUgc2xpY2UgaW4gb3JkZXIgdG8gZ2V0IGFcbiAgICBmaXQgdGhhdCBpcyBtb3JlIGluIGxpbmUgd2l0aCBXWVNJV1lHIGV4cGVjdGF0aW9ucywgYnkgZHJvcHBpbmdcbiAgICBmdWxseSBjb3ZlcmVkIHBhcmVudCBub2RlcyBvZiB0aGUgcmVwbGFjZWQgcmVnaW9uIHdoZW4gdGhleSBhcmVcbiAgICBtYXJrZWQgW25vbi1kZWZpbmluZyBhc1xuICAgIGNvbnRleHRdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5Ob2RlU3BlYy5kZWZpbmluZ0FzQ29udGV4dCksIG9yIGluY2x1ZGluZyBhblxuICAgIG9wZW4gcGFyZW50IG5vZGUgZnJvbSB0aGUgc2xpY2UgdGhhdCBfaXNfIG1hcmtlZCBhcyBbZGVmaW5pbmdcbiAgICBpdHMgY29udGVudF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI21vZGVsLk5vZGVTcGVjLmRlZmluaW5nRm9yQ29udGVudCkuXG4gICAgXG4gICAgVGhpcyBpcyB0aGUgbWV0aG9kLCBmb3IgZXhhbXBsZSwgdG8gaGFuZGxlIHBhc3RlLiBUaGUgc2ltaWxhclxuICAgIFtgcmVwbGFjZWBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyN0cmFuc2Zvcm0uVHJhbnNmb3JtLnJlcGxhY2UpIG1ldGhvZCBpcyBhIG1vcmVcbiAgICBwcmltaXRpdmUgdG9vbCB3aGljaCB3aWxsIF9ub3RfIG1vdmUgdGhlIHN0YXJ0IGFuZCBlbmQgb2YgaXRzIGdpdmVuXG4gICAgcmFuZ2UsIGFuZCBpcyB1c2VmdWwgaW4gc2l0dWF0aW9ucyB3aGVyZSB5b3UgbmVlZCBtb3JlIHByZWNpc2VcbiAgICBjb250cm9sIG92ZXIgd2hhdCBoYXBwZW5zLlxuICAgICovXG4gICAgcmVwbGFjZVJhbmdlKGZyb20sIHRvLCBzbGljZSkge1xuICAgICAgICByZXBsYWNlUmFuZ2UodGhpcywgZnJvbSwgdG8sIHNsaWNlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIFJlcGxhY2UgdGhlIGdpdmVuIHJhbmdlIHdpdGggYSBub2RlLCBidXQgdXNlIGBmcm9tYCBhbmQgYHRvYCBhc1xuICAgIGhpbnRzLCByYXRoZXIgdGhhbiBwcmVjaXNlIHBvc2l0aW9ucy4gV2hlbiBmcm9tIGFuZCB0byBhcmUgdGhlIHNhbWVcbiAgICBhbmQgYXJlIGF0IHRoZSBzdGFydCBvciBlbmQgb2YgYSBwYXJlbnQgbm9kZSBpbiB3aGljaCB0aGUgZ2l2ZW5cbiAgICBub2RlIGRvZXNuJ3QgZml0LCB0aGlzIG1ldGhvZCBtYXkgX21vdmVfIHRoZW0gb3V0IHRvd2FyZHMgYSBwYXJlbnRcbiAgICB0aGF0IGRvZXMgYWxsb3cgdGhlIGdpdmVuIG5vZGUgdG8gYmUgcGxhY2VkLiBXaGVuIHRoZSBnaXZlbiByYW5nZVxuICAgIGNvbXBsZXRlbHkgY292ZXJzIGEgcGFyZW50IG5vZGUsIHRoaXMgbWV0aG9kIG1heSBjb21wbGV0ZWx5IHJlcGxhY2VcbiAgICB0aGF0IHBhcmVudCBub2RlLlxuICAgICovXG4gICAgcmVwbGFjZVJhbmdlV2l0aChmcm9tLCB0bywgbm9kZSkge1xuICAgICAgICByZXBsYWNlUmFuZ2VXaXRoKHRoaXMsIGZyb20sIHRvLCBub2RlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIERlbGV0ZSB0aGUgZ2l2ZW4gcmFuZ2UsIGV4cGFuZGluZyBpdCB0byBjb3ZlciBmdWxseSBjb3ZlcmVkXG4gICAgcGFyZW50IG5vZGVzIHVudGlsIGEgdmFsaWQgcmVwbGFjZSBpcyBmb3VuZC5cbiAgICAqL1xuICAgIGRlbGV0ZVJhbmdlKGZyb20sIHRvKSB7XG4gICAgICAgIGRlbGV0ZVJhbmdlKHRoaXMsIGZyb20sIHRvKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIFNwbGl0IHRoZSBjb250ZW50IGluIHRoZSBnaXZlbiByYW5nZSBvZmYgZnJvbSBpdHMgcGFyZW50LCBpZiB0aGVyZVxuICAgIGlzIHNpYmxpbmcgY29udGVudCBiZWZvcmUgb3IgYWZ0ZXIgaXQsIGFuZCBtb3ZlIGl0IHVwIHRoZSB0cmVlIHRvXG4gICAgdGhlIGRlcHRoIHNwZWNpZmllZCBieSBgdGFyZ2V0YC4gWW91J2xsIHByb2JhYmx5IHdhbnQgdG8gdXNlXG4gICAgW2BsaWZ0VGFyZ2V0YF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3RyYW5zZm9ybS5saWZ0VGFyZ2V0KSB0byBjb21wdXRlIGB0YXJnZXRgLCB0byBtYWtlXG4gICAgc3VyZSB0aGUgbGlmdCBpcyB2YWxpZC5cbiAgICAqL1xuICAgIGxpZnQocmFuZ2UsIHRhcmdldCkge1xuICAgICAgICBsaWZ0KHRoaXMsIHJhbmdlLCB0YXJnZXQpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgSm9pbiB0aGUgYmxvY2tzIGFyb3VuZCB0aGUgZ2l2ZW4gcG9zaXRpb24uIElmIGRlcHRoIGlzIDIsIHRoZWlyXG4gICAgbGFzdCBhbmQgZmlyc3Qgc2libGluZ3MgYXJlIGFsc28gam9pbmVkLCBhbmQgc28gb24uXG4gICAgKi9cbiAgICBqb2luKHBvcywgZGVwdGggPSAxKSB7XG4gICAgICAgIGpvaW4odGhpcywgcG9zLCBkZXB0aCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICBXcmFwIHRoZSBnaXZlbiBbcmFuZ2VdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5Ob2RlUmFuZ2UpIGluIHRoZSBnaXZlbiBzZXQgb2Ygd3JhcHBlcnMuXG4gICAgVGhlIHdyYXBwZXJzIGFyZSBhc3N1bWVkIHRvIGJlIHZhbGlkIGluIHRoaXMgcG9zaXRpb24sIGFuZCBzaG91bGRcbiAgICBwcm9iYWJseSBiZSBjb21wdXRlZCB3aXRoIFtgZmluZFdyYXBwaW5nYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3RyYW5zZm9ybS5maW5kV3JhcHBpbmcpLlxuICAgICovXG4gICAgd3JhcChyYW5nZSwgd3JhcHBlcnMpIHtcbiAgICAgICAgd3JhcCh0aGlzLCByYW5nZSwgd3JhcHBlcnMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgU2V0IHRoZSB0eXBlIG9mIGFsbCB0ZXh0YmxvY2tzIChwYXJ0bHkpIGJldHdlZW4gYGZyb21gIGFuZCBgdG9gIHRvXG4gICAgdGhlIGdpdmVuIG5vZGUgdHlwZSB3aXRoIHRoZSBnaXZlbiBhdHRyaWJ1dGVzLlxuICAgICovXG4gICAgc2V0QmxvY2tUeXBlKGZyb20sIHRvID0gZnJvbSwgdHlwZSwgYXR0cnMgPSBudWxsKSB7XG4gICAgICAgIHNldEJsb2NrVHlwZSh0aGlzLCBmcm9tLCB0bywgdHlwZSwgYXR0cnMpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgQ2hhbmdlIHRoZSB0eXBlLCBhdHRyaWJ1dGVzLCBhbmQvb3IgbWFya3Mgb2YgdGhlIG5vZGUgYXQgYHBvc2AuXG4gICAgV2hlbiBgdHlwZWAgaXNuJ3QgZ2l2ZW4sIHRoZSBleGlzdGluZyBub2RlIHR5cGUgaXMgcHJlc2VydmVkLFxuICAgICovXG4gICAgc2V0Tm9kZU1hcmt1cChwb3MsIHR5cGUsIGF0dHJzID0gbnVsbCwgbWFya3MpIHtcbiAgICAgICAgc2V0Tm9kZU1hcmt1cCh0aGlzLCBwb3MsIHR5cGUsIGF0dHJzLCBtYXJrcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICBTZXQgYSBzaW5nbGUgYXR0cmlidXRlIG9uIGEgZ2l2ZW4gbm9kZSB0byBhIG5ldyB2YWx1ZS5cbiAgICBUaGUgYHBvc2AgYWRkcmVzc2VzIHRoZSBkb2N1bWVudCBjb250ZW50LiBVc2UgYHNldERvY0F0dHJpYnV0ZWBcbiAgICB0byBzZXQgYXR0cmlidXRlcyBvbiB0aGUgZG9jdW1lbnQgaXRzZWxmLlxuICAgICovXG4gICAgc2V0Tm9kZUF0dHJpYnV0ZShwb3MsIGF0dHIsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMuc3RlcChuZXcgQXR0clN0ZXAocG9zLCBhdHRyLCB2YWx1ZSkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgU2V0IGEgc2luZ2xlIGF0dHJpYnV0ZSBvbiB0aGUgZG9jdW1lbnQgdG8gYSBuZXcgdmFsdWUuXG4gICAgKi9cbiAgICBzZXREb2NBdHRyaWJ1dGUoYXR0ciwgdmFsdWUpIHtcbiAgICAgICAgdGhpcy5zdGVwKG5ldyBEb2NBdHRyU3RlcChhdHRyLCB2YWx1ZSkpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgQWRkIGEgbWFyayB0byB0aGUgbm9kZSBhdCBwb3NpdGlvbiBgcG9zYC5cbiAgICAqL1xuICAgIGFkZE5vZGVNYXJrKHBvcywgbWFyaykge1xuICAgICAgICB0aGlzLnN0ZXAobmV3IEFkZE5vZGVNYXJrU3RlcChwb3MsIG1hcmspKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIFJlbW92ZSBhIG1hcmsgKG9yIGFsbCBtYXJrcyBvZiB0aGUgZ2l2ZW4gdHlwZSkgZnJvbSB0aGUgbm9kZSBhdFxuICAgIHBvc2l0aW9uIGBwb3NgLlxuICAgICovXG4gICAgcmVtb3ZlTm9kZU1hcmsocG9zLCBtYXJrKSB7XG4gICAgICAgIGxldCBub2RlID0gdGhpcy5kb2Mubm9kZUF0KHBvcyk7XG4gICAgICAgIGlmICghbm9kZSlcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiTm8gbm9kZSBhdCBwb3NpdGlvbiBcIiArIHBvcyk7XG4gICAgICAgIGlmIChtYXJrIGluc3RhbmNlb2YgTWFyaykge1xuICAgICAgICAgICAgaWYgKG1hcmsuaXNJblNldChub2RlLm1hcmtzKSlcbiAgICAgICAgICAgICAgICB0aGlzLnN0ZXAobmV3IFJlbW92ZU5vZGVNYXJrU3RlcChwb3MsIG1hcmspKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGxldCBzZXQgPSBub2RlLm1hcmtzLCBmb3VuZCwgc3RlcHMgPSBbXTtcbiAgICAgICAgICAgIHdoaWxlIChmb3VuZCA9IG1hcmsuaXNJblNldChzZXQpKSB7XG4gICAgICAgICAgICAgICAgc3RlcHMucHVzaChuZXcgUmVtb3ZlTm9kZU1hcmtTdGVwKHBvcywgZm91bmQpKTtcbiAgICAgICAgICAgICAgICBzZXQgPSBmb3VuZC5yZW1vdmVGcm9tU2V0KHNldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gc3RlcHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pXG4gICAgICAgICAgICAgICAgdGhpcy5zdGVwKHN0ZXBzW2ldKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgU3BsaXQgdGhlIG5vZGUgYXQgdGhlIGdpdmVuIHBvc2l0aW9uLCBhbmQgb3B0aW9uYWxseSwgaWYgYGRlcHRoYCBpc1xuICAgIGdyZWF0ZXIgdGhhbiBvbmUsIGFueSBudW1iZXIgb2Ygbm9kZXMgYWJvdmUgdGhhdC4gQnkgZGVmYXVsdCwgdGhlXG4gICAgcGFydHMgc3BsaXQgb2ZmIHdpbGwgaW5oZXJpdCB0aGUgbm9kZSB0eXBlIG9mIHRoZSBvcmlnaW5hbCBub2RlLlxuICAgIFRoaXMgY2FuIGJlIGNoYW5nZWQgYnkgcGFzc2luZyBhbiBhcnJheSBvZiB0eXBlcyBhbmQgYXR0cmlidXRlcyB0b1xuICAgIHVzZSBhZnRlciB0aGUgc3BsaXQgKHdpdGggdGhlIG91dGVybW9zdCBub2RlcyBjb21pbmcgZmlyc3QpLlxuICAgICovXG4gICAgc3BsaXQocG9zLCBkZXB0aCA9IDEsIHR5cGVzQWZ0ZXIpIHtcbiAgICAgICAgc3BsaXQodGhpcywgcG9zLCBkZXB0aCwgdHlwZXNBZnRlcik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICBBZGQgdGhlIGdpdmVuIG1hcmsgdG8gdGhlIGlubGluZSBjb250ZW50IGJldHdlZW4gYGZyb21gIGFuZCBgdG9gLlxuICAgICovXG4gICAgYWRkTWFyayhmcm9tLCB0bywgbWFyaykge1xuICAgICAgICBhZGRNYXJrKHRoaXMsIGZyb20sIHRvLCBtYXJrKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIFJlbW92ZSBtYXJrcyBmcm9tIGlubGluZSBub2RlcyBiZXR3ZWVuIGBmcm9tYCBhbmQgYHRvYC4gV2hlblxuICAgIGBtYXJrYCBpcyBhIHNpbmdsZSBtYXJrLCByZW1vdmUgcHJlY2lzZWx5IHRoYXQgbWFyay4gV2hlbiBpdCBpc1xuICAgIGEgbWFyayB0eXBlLCByZW1vdmUgYWxsIG1hcmtzIG9mIHRoYXQgdHlwZS4gV2hlbiBpdCBpcyBudWxsLFxuICAgIHJlbW92ZSBhbGwgbWFya3Mgb2YgYW55IHR5cGUuXG4gICAgKi9cbiAgICByZW1vdmVNYXJrKGZyb20sIHRvLCBtYXJrKSB7XG4gICAgICAgIHJlbW92ZU1hcmsodGhpcywgZnJvbSwgdG8sIG1hcmspO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgUmVtb3ZlcyBhbGwgbWFya3MgYW5kIG5vZGVzIGZyb20gdGhlIGNvbnRlbnQgb2YgdGhlIG5vZGUgYXRcbiAgICBgcG9zYCB0aGF0IGRvbid0IG1hdGNoIHRoZSBnaXZlbiBuZXcgcGFyZW50IG5vZGUgdHlwZS4gQWNjZXB0c1xuICAgIGFuIG9wdGlvbmFsIHN0YXJ0aW5nIFtjb250ZW50IG1hdGNoXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuQ29udGVudE1hdGNoKSBhc1xuICAgIHRoaXJkIGFyZ3VtZW50LlxuICAgICovXG4gICAgY2xlYXJJbmNvbXBhdGlibGUocG9zLCBwYXJlbnRUeXBlLCBtYXRjaCkge1xuICAgICAgICBjbGVhckluY29tcGF0aWJsZSh0aGlzLCBwb3MsIHBhcmVudFR5cGUsIG1hdGNoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxufVxuXG5leHBvcnQgeyBBZGRNYXJrU3RlcCwgQWRkTm9kZU1hcmtTdGVwLCBBdHRyU3RlcCwgRG9jQXR0clN0ZXAsIE1hcFJlc3VsdCwgTWFwcGluZywgUmVtb3ZlTWFya1N0ZXAsIFJlbW92ZU5vZGVNYXJrU3RlcCwgUmVwbGFjZUFyb3VuZFN0ZXAsIFJlcGxhY2VTdGVwLCBTdGVwLCBTdGVwTWFwLCBTdGVwUmVzdWx0LCBUcmFuc2Zvcm0sIFRyYW5zZm9ybUVycm9yLCBjYW5Kb2luLCBjYW5TcGxpdCwgZHJvcFBvaW50LCBmaW5kV3JhcHBpbmcsIGluc2VydFBvaW50LCBqb2luUG9pbnQsIGxpZnRUYXJnZXQsIHJlcGxhY2VTdGVwIH07XG4iLCAiaW1wb3J0IHsgU2xpY2UsIEZyYWdtZW50LCBNYXJrLCBOb2RlIH0gZnJvbSAncHJvc2VtaXJyb3ItbW9kZWwnO1xuaW1wb3J0IHsgUmVwbGFjZVN0ZXAsIFJlcGxhY2VBcm91bmRTdGVwLCBUcmFuc2Zvcm0gfSBmcm9tICdwcm9zZW1pcnJvci10cmFuc2Zvcm0nO1xuXG5jb25zdCBjbGFzc2VzQnlJZCA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4vKipcblN1cGVyY2xhc3MgZm9yIGVkaXRvciBzZWxlY3Rpb25zLiBFdmVyeSBzZWxlY3Rpb24gdHlwZSBzaG91bGRcbmV4dGVuZCB0aGlzLiBTaG91bGQgbm90IGJlIGluc3RhbnRpYXRlZCBkaXJlY3RseS5cbiovXG5jbGFzcyBTZWxlY3Rpb24ge1xuICAgIC8qKlxuICAgIEluaXRpYWxpemUgYSBzZWxlY3Rpb24gd2l0aCB0aGUgaGVhZCBhbmQgYW5jaG9yIGFuZCByYW5nZXMuIElmIG5vXG4gICAgcmFuZ2VzIGFyZSBnaXZlbiwgY29uc3RydWN0cyBhIHNpbmdsZSByYW5nZSBhY3Jvc3MgYCRhbmNob3JgIGFuZFxuICAgIGAkaGVhZGAuXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBUaGUgcmVzb2x2ZWQgYW5jaG9yIG9mIHRoZSBzZWxlY3Rpb24gKHRoZSBzaWRlIHRoYXQgc3RheXMgaW5cbiAgICBwbGFjZSB3aGVuIHRoZSBzZWxlY3Rpb24gaXMgbW9kaWZpZWQpLlxuICAgICovXG4gICAgJGFuY2hvciwgXG4gICAgLyoqXG4gICAgVGhlIHJlc29sdmVkIGhlYWQgb2YgdGhlIHNlbGVjdGlvbiAodGhlIHNpZGUgdGhhdCBtb3ZlcyB3aGVuXG4gICAgdGhlIHNlbGVjdGlvbiBpcyBtb2RpZmllZCkuXG4gICAgKi9cbiAgICAkaGVhZCwgcmFuZ2VzKSB7XG4gICAgICAgIHRoaXMuJGFuY2hvciA9ICRhbmNob3I7XG4gICAgICAgIHRoaXMuJGhlYWQgPSAkaGVhZDtcbiAgICAgICAgdGhpcy5yYW5nZXMgPSByYW5nZXMgfHwgW25ldyBTZWxlY3Rpb25SYW5nZSgkYW5jaG9yLm1pbigkaGVhZCksICRhbmNob3IubWF4KCRoZWFkKSldO1xuICAgIH1cbiAgICAvKipcbiAgICBUaGUgc2VsZWN0aW9uJ3MgYW5jaG9yLCBhcyBhbiB1bnJlc29sdmVkIHBvc2l0aW9uLlxuICAgICovXG4gICAgZ2V0IGFuY2hvcigpIHsgcmV0dXJuIHRoaXMuJGFuY2hvci5wb3M7IH1cbiAgICAvKipcbiAgICBUaGUgc2VsZWN0aW9uJ3MgaGVhZC5cbiAgICAqL1xuICAgIGdldCBoZWFkKCkgeyByZXR1cm4gdGhpcy4kaGVhZC5wb3M7IH1cbiAgICAvKipcbiAgICBUaGUgbG93ZXIgYm91bmQgb2YgdGhlIHNlbGVjdGlvbidzIG1haW4gcmFuZ2UuXG4gICAgKi9cbiAgICBnZXQgZnJvbSgpIHsgcmV0dXJuIHRoaXMuJGZyb20ucG9zOyB9XG4gICAgLyoqXG4gICAgVGhlIHVwcGVyIGJvdW5kIG9mIHRoZSBzZWxlY3Rpb24ncyBtYWluIHJhbmdlLlxuICAgICovXG4gICAgZ2V0IHRvKCkgeyByZXR1cm4gdGhpcy4kdG8ucG9zOyB9XG4gICAgLyoqXG4gICAgVGhlIHJlc29sdmVkIGxvd2VyICBib3VuZCBvZiB0aGUgc2VsZWN0aW9uJ3MgbWFpbiByYW5nZS5cbiAgICAqL1xuICAgIGdldCAkZnJvbSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmFuZ2VzWzBdLiRmcm9tO1xuICAgIH1cbiAgICAvKipcbiAgICBUaGUgcmVzb2x2ZWQgdXBwZXIgYm91bmQgb2YgdGhlIHNlbGVjdGlvbidzIG1haW4gcmFuZ2UuXG4gICAgKi9cbiAgICBnZXQgJHRvKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5yYW5nZXNbMF0uJHRvO1xuICAgIH1cbiAgICAvKipcbiAgICBJbmRpY2F0ZXMgd2hldGhlciB0aGUgc2VsZWN0aW9uIGNvbnRhaW5zIGFueSBjb250ZW50LlxuICAgICovXG4gICAgZ2V0IGVtcHR5KCkge1xuICAgICAgICBsZXQgcmFuZ2VzID0gdGhpcy5yYW5nZXM7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuZ2VzLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgaWYgKHJhbmdlc1tpXS4kZnJvbS5wb3MgIT0gcmFuZ2VzW2ldLiR0by5wb3MpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgR2V0IHRoZSBjb250ZW50IG9mIHRoaXMgc2VsZWN0aW9uIGFzIGEgc2xpY2UuXG4gICAgKi9cbiAgICBjb250ZW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy4kZnJvbS5kb2Muc2xpY2UodGhpcy5mcm9tLCB0aGlzLnRvLCB0cnVlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgUmVwbGFjZSB0aGUgc2VsZWN0aW9uIHdpdGggYSBzbGljZSBvciwgaWYgbm8gc2xpY2UgaXMgZ2l2ZW4sXG4gICAgZGVsZXRlIHRoZSBzZWxlY3Rpb24uIFdpbGwgYXBwZW5kIHRvIHRoZSBnaXZlbiB0cmFuc2FjdGlvbi5cbiAgICAqL1xuICAgIHJlcGxhY2UodHIsIGNvbnRlbnQgPSBTbGljZS5lbXB0eSkge1xuICAgICAgICAvLyBQdXQgdGhlIG5ldyBzZWxlY3Rpb24gYXQgdGhlIHBvc2l0aW9uIGFmdGVyIHRoZSBpbnNlcnRlZFxuICAgICAgICAvLyBjb250ZW50LiBXaGVuIHRoYXQgZW5kZWQgaW4gYW4gaW5saW5lIG5vZGUsIHNlYXJjaCBiYWNrd2FyZHMsXG4gICAgICAgIC8vIHRvIGdldCB0aGUgcG9zaXRpb24gYWZ0ZXIgdGhhdCBub2RlLiBJZiBub3QsIHNlYXJjaCBmb3J3YXJkLlxuICAgICAgICBsZXQgbGFzdE5vZGUgPSBjb250ZW50LmNvbnRlbnQubGFzdENoaWxkLCBsYXN0UGFyZW50ID0gbnVsbDtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb250ZW50Lm9wZW5FbmQ7IGkrKykge1xuICAgICAgICAgICAgbGFzdFBhcmVudCA9IGxhc3ROb2RlO1xuICAgICAgICAgICAgbGFzdE5vZGUgPSBsYXN0Tm9kZS5sYXN0Q2hpbGQ7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IG1hcEZyb20gPSB0ci5zdGVwcy5sZW5ndGgsIHJhbmdlcyA9IHRoaXMucmFuZ2VzO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IHsgJGZyb20sICR0byB9ID0gcmFuZ2VzW2ldLCBtYXBwaW5nID0gdHIubWFwcGluZy5zbGljZShtYXBGcm9tKTtcbiAgICAgICAgICAgIHRyLnJlcGxhY2VSYW5nZShtYXBwaW5nLm1hcCgkZnJvbS5wb3MpLCBtYXBwaW5nLm1hcCgkdG8ucG9zKSwgaSA/IFNsaWNlLmVtcHR5IDogY29udGVudCk7XG4gICAgICAgICAgICBpZiAoaSA9PSAwKVxuICAgICAgICAgICAgICAgIHNlbGVjdGlvblRvSW5zZXJ0aW9uRW5kKHRyLCBtYXBGcm9tLCAobGFzdE5vZGUgPyBsYXN0Tm9kZS5pc0lubGluZSA6IGxhc3RQYXJlbnQgJiYgbGFzdFBhcmVudC5pc1RleHRibG9jaykgPyAtMSA6IDEpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgIFJlcGxhY2UgdGhlIHNlbGVjdGlvbiB3aXRoIHRoZSBnaXZlbiBub2RlLCBhcHBlbmRpbmcgdGhlIGNoYW5nZXNcbiAgICB0byB0aGUgZ2l2ZW4gdHJhbnNhY3Rpb24uXG4gICAgKi9cbiAgICByZXBsYWNlV2l0aCh0ciwgbm9kZSkge1xuICAgICAgICBsZXQgbWFwRnJvbSA9IHRyLnN0ZXBzLmxlbmd0aCwgcmFuZ2VzID0gdGhpcy5yYW5nZXM7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgeyAkZnJvbSwgJHRvIH0gPSByYW5nZXNbaV0sIG1hcHBpbmcgPSB0ci5tYXBwaW5nLnNsaWNlKG1hcEZyb20pO1xuICAgICAgICAgICAgbGV0IGZyb20gPSBtYXBwaW5nLm1hcCgkZnJvbS5wb3MpLCB0byA9IG1hcHBpbmcubWFwKCR0by5wb3MpO1xuICAgICAgICAgICAgaWYgKGkpIHtcbiAgICAgICAgICAgICAgICB0ci5kZWxldGVSYW5nZShmcm9tLCB0byk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0ci5yZXBsYWNlUmFuZ2VXaXRoKGZyb20sIHRvLCBub2RlKTtcbiAgICAgICAgICAgICAgICBzZWxlY3Rpb25Ub0luc2VydGlvbkVuZCh0ciwgbWFwRnJvbSwgbm9kZS5pc0lubGluZSA/IC0xIDogMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgRmluZCBhIHZhbGlkIGN1cnNvciBvciBsZWFmIG5vZGUgc2VsZWN0aW9uIHN0YXJ0aW5nIGF0IHRoZSBnaXZlblxuICAgIHBvc2l0aW9uIGFuZCBzZWFyY2hpbmcgYmFjayBpZiBgZGlyYCBpcyBuZWdhdGl2ZSwgYW5kIGZvcndhcmQgaWZcbiAgICBwb3NpdGl2ZS4gV2hlbiBgdGV4dE9ubHlgIGlzIHRydWUsIG9ubHkgY29uc2lkZXIgY3Vyc29yXG4gICAgc2VsZWN0aW9ucy4gV2lsbCByZXR1cm4gbnVsbCB3aGVuIG5vIHZhbGlkIHNlbGVjdGlvbiBwb3NpdGlvbiBpc1xuICAgIGZvdW5kLlxuICAgICovXG4gICAgc3RhdGljIGZpbmRGcm9tKCRwb3MsIGRpciwgdGV4dE9ubHkgPSBmYWxzZSkge1xuICAgICAgICBsZXQgaW5uZXIgPSAkcG9zLnBhcmVudC5pbmxpbmVDb250ZW50ID8gbmV3IFRleHRTZWxlY3Rpb24oJHBvcylcbiAgICAgICAgICAgIDogZmluZFNlbGVjdGlvbkluKCRwb3Mubm9kZSgwKSwgJHBvcy5wYXJlbnQsICRwb3MucG9zLCAkcG9zLmluZGV4KCksIGRpciwgdGV4dE9ubHkpO1xuICAgICAgICBpZiAoaW5uZXIpXG4gICAgICAgICAgICByZXR1cm4gaW5uZXI7XG4gICAgICAgIGZvciAobGV0IGRlcHRoID0gJHBvcy5kZXB0aCAtIDE7IGRlcHRoID49IDA7IGRlcHRoLS0pIHtcbiAgICAgICAgICAgIGxldCBmb3VuZCA9IGRpciA8IDBcbiAgICAgICAgICAgICAgICA/IGZpbmRTZWxlY3Rpb25JbigkcG9zLm5vZGUoMCksICRwb3Mubm9kZShkZXB0aCksICRwb3MuYmVmb3JlKGRlcHRoICsgMSksICRwb3MuaW5kZXgoZGVwdGgpLCBkaXIsIHRleHRPbmx5KVxuICAgICAgICAgICAgICAgIDogZmluZFNlbGVjdGlvbkluKCRwb3Mubm9kZSgwKSwgJHBvcy5ub2RlKGRlcHRoKSwgJHBvcy5hZnRlcihkZXB0aCArIDEpLCAkcG9zLmluZGV4KGRlcHRoKSArIDEsIGRpciwgdGV4dE9ubHkpO1xuICAgICAgICAgICAgaWYgKGZvdW5kKVxuICAgICAgICAgICAgICAgIHJldHVybiBmb3VuZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgLyoqXG4gICAgRmluZCBhIHZhbGlkIGN1cnNvciBvciBsZWFmIG5vZGUgc2VsZWN0aW9uIG5lYXIgdGhlIGdpdmVuXG4gICAgcG9zaXRpb24uIFNlYXJjaGVzIGZvcndhcmQgZmlyc3QgYnkgZGVmYXVsdCwgYnV0IGlmIGBiaWFzYCBpc1xuICAgIG5lZ2F0aXZlLCBpdCB3aWxsIHNlYXJjaCBiYWNrd2FyZHMgZmlyc3QuXG4gICAgKi9cbiAgICBzdGF0aWMgbmVhcigkcG9zLCBiaWFzID0gMSkge1xuICAgICAgICByZXR1cm4gdGhpcy5maW5kRnJvbSgkcG9zLCBiaWFzKSB8fCB0aGlzLmZpbmRGcm9tKCRwb3MsIC1iaWFzKSB8fCBuZXcgQWxsU2VsZWN0aW9uKCRwb3Mubm9kZSgwKSk7XG4gICAgfVxuICAgIC8qKlxuICAgIEZpbmQgdGhlIGN1cnNvciBvciBsZWFmIG5vZGUgc2VsZWN0aW9uIGNsb3Nlc3QgdG8gdGhlIHN0YXJ0IG9mXG4gICAgdGhlIGdpdmVuIGRvY3VtZW50LiBXaWxsIHJldHVybiBhblxuICAgIFtgQWxsU2VsZWN0aW9uYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3N0YXRlLkFsbFNlbGVjdGlvbikgaWYgbm8gdmFsaWQgcG9zaXRpb25cbiAgICBleGlzdHMuXG4gICAgKi9cbiAgICBzdGF0aWMgYXRTdGFydChkb2MpIHtcbiAgICAgICAgcmV0dXJuIGZpbmRTZWxlY3Rpb25Jbihkb2MsIGRvYywgMCwgMCwgMSkgfHwgbmV3IEFsbFNlbGVjdGlvbihkb2MpO1xuICAgIH1cbiAgICAvKipcbiAgICBGaW5kIHRoZSBjdXJzb3Igb3IgbGVhZiBub2RlIHNlbGVjdGlvbiBjbG9zZXN0IHRvIHRoZSBlbmQgb2YgdGhlXG4gICAgZ2l2ZW4gZG9jdW1lbnQuXG4gICAgKi9cbiAgICBzdGF0aWMgYXRFbmQoZG9jKSB7XG4gICAgICAgIHJldHVybiBmaW5kU2VsZWN0aW9uSW4oZG9jLCBkb2MsIGRvYy5jb250ZW50LnNpemUsIGRvYy5jaGlsZENvdW50LCAtMSkgfHwgbmV3IEFsbFNlbGVjdGlvbihkb2MpO1xuICAgIH1cbiAgICAvKipcbiAgICBEZXNlcmlhbGl6ZSB0aGUgSlNPTiByZXByZXNlbnRhdGlvbiBvZiBhIHNlbGVjdGlvbi4gTXVzdCBiZVxuICAgIGltcGxlbWVudGVkIGZvciBjdXN0b20gY2xhc3NlcyAoYXMgYSBzdGF0aWMgY2xhc3MgbWV0aG9kKS5cbiAgICAqL1xuICAgIHN0YXRpYyBmcm9tSlNPTihkb2MsIGpzb24pIHtcbiAgICAgICAgaWYgKCFqc29uIHx8ICFqc29uLnR5cGUpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkludmFsaWQgaW5wdXQgZm9yIFNlbGVjdGlvbi5mcm9tSlNPTlwiKTtcbiAgICAgICAgbGV0IGNscyA9IGNsYXNzZXNCeUlkW2pzb24udHlwZV07XG4gICAgICAgIGlmICghY2xzKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoYE5vIHNlbGVjdGlvbiB0eXBlICR7anNvbi50eXBlfSBkZWZpbmVkYCk7XG4gICAgICAgIHJldHVybiBjbHMuZnJvbUpTT04oZG9jLCBqc29uKTtcbiAgICB9XG4gICAgLyoqXG4gICAgVG8gYmUgYWJsZSB0byBkZXNlcmlhbGl6ZSBzZWxlY3Rpb25zIGZyb20gSlNPTiwgY3VzdG9tIHNlbGVjdGlvblxuICAgIGNsYXNzZXMgbXVzdCByZWdpc3RlciB0aGVtc2VsdmVzIHdpdGggYW4gSUQgc3RyaW5nLCBzbyB0aGF0IHRoZXlcbiAgICBjYW4gYmUgZGlzYW1iaWd1YXRlZC4gVHJ5IHRvIHBpY2sgc29tZXRoaW5nIHRoYXQncyB1bmxpa2VseSB0b1xuICAgIGNsYXNoIHdpdGggY2xhc3NlcyBmcm9tIG90aGVyIG1vZHVsZXMuXG4gICAgKi9cbiAgICBzdGF0aWMganNvbklEKGlkLCBzZWxlY3Rpb25DbGFzcykge1xuICAgICAgICBpZiAoaWQgaW4gY2xhc3Nlc0J5SWQpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkR1cGxpY2F0ZSB1c2Ugb2Ygc2VsZWN0aW9uIEpTT04gSUQgXCIgKyBpZCk7XG4gICAgICAgIGNsYXNzZXNCeUlkW2lkXSA9IHNlbGVjdGlvbkNsYXNzO1xuICAgICAgICBzZWxlY3Rpb25DbGFzcy5wcm90b3R5cGUuanNvbklEID0gaWQ7XG4gICAgICAgIHJldHVybiBzZWxlY3Rpb25DbGFzcztcbiAgICB9XG4gICAgLyoqXG4gICAgR2V0IGEgW2Jvb2ttYXJrXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jc3RhdGUuU2VsZWN0aW9uQm9va21hcmspIGZvciB0aGlzIHNlbGVjdGlvbixcbiAgICB3aGljaCBpcyBhIHZhbHVlIHRoYXQgY2FuIGJlIG1hcHBlZCB3aXRob3V0IGhhdmluZyBhY2Nlc3MgdG8gYVxuICAgIGN1cnJlbnQgZG9jdW1lbnQsIGFuZCBsYXRlciByZXNvbHZlZCB0byBhIHJlYWwgc2VsZWN0aW9uIGZvciBhXG4gICAgZ2l2ZW4gZG9jdW1lbnQgYWdhaW4uIChUaGlzIGlzIHVzZWQgbW9zdGx5IGJ5IHRoZSBoaXN0b3J5IHRvXG4gICAgdHJhY2sgYW5kIHJlc3RvcmUgb2xkIHNlbGVjdGlvbnMuKSBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBvZlxuICAgIHRoaXMgbWV0aG9kIGp1c3QgY29udmVydHMgdGhlIHNlbGVjdGlvbiB0byBhIHRleHQgc2VsZWN0aW9uIGFuZFxuICAgIHJldHVybnMgdGhlIGJvb2ttYXJrIGZvciB0aGF0LlxuICAgICovXG4gICAgZ2V0Qm9va21hcmsoKSB7XG4gICAgICAgIHJldHVybiBUZXh0U2VsZWN0aW9uLmJldHdlZW4odGhpcy4kYW5jaG9yLCB0aGlzLiRoZWFkKS5nZXRCb29rbWFyaygpO1xuICAgIH1cbn1cblNlbGVjdGlvbi5wcm90b3R5cGUudmlzaWJsZSA9IHRydWU7XG4vKipcblJlcHJlc2VudHMgYSBzZWxlY3RlZCByYW5nZSBpbiBhIGRvY3VtZW50LlxuKi9cbmNsYXNzIFNlbGVjdGlvblJhbmdlIHtcbiAgICAvKipcbiAgICBDcmVhdGUgYSByYW5nZS5cbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgIC8qKlxuICAgIFRoZSBsb3dlciBib3VuZCBvZiB0aGUgcmFuZ2UuXG4gICAgKi9cbiAgICAkZnJvbSwgXG4gICAgLyoqXG4gICAgVGhlIHVwcGVyIGJvdW5kIG9mIHRoZSByYW5nZS5cbiAgICAqL1xuICAgICR0bykge1xuICAgICAgICB0aGlzLiRmcm9tID0gJGZyb207XG4gICAgICAgIHRoaXMuJHRvID0gJHRvO1xuICAgIH1cbn1cbmxldCB3YXJuZWRBYm91dFRleHRTZWxlY3Rpb24gPSBmYWxzZTtcbmZ1bmN0aW9uIGNoZWNrVGV4dFNlbGVjdGlvbigkcG9zKSB7XG4gICAgaWYgKCF3YXJuZWRBYm91dFRleHRTZWxlY3Rpb24gJiYgISRwb3MucGFyZW50LmlubGluZUNvbnRlbnQpIHtcbiAgICAgICAgd2FybmVkQWJvdXRUZXh0U2VsZWN0aW9uID0gdHJ1ZTtcbiAgICAgICAgY29uc29sZVtcIndhcm5cIl0oXCJUZXh0U2VsZWN0aW9uIGVuZHBvaW50IG5vdCBwb2ludGluZyBpbnRvIGEgbm9kZSB3aXRoIGlubGluZSBjb250ZW50IChcIiArICRwb3MucGFyZW50LnR5cGUubmFtZSArIFwiKVwiKTtcbiAgICB9XG59XG4vKipcbkEgdGV4dCBzZWxlY3Rpb24gcmVwcmVzZW50cyBhIGNsYXNzaWNhbCBlZGl0b3Igc2VsZWN0aW9uLCB3aXRoIGFcbmhlYWQgKHRoZSBtb3Zpbmcgc2lkZSkgYW5kIGFuY2hvciAoaW1tb2JpbGUgc2lkZSksIGJvdGggb2Ygd2hpY2hcbnBvaW50IGludG8gdGV4dGJsb2NrIG5vZGVzLiBJdCBjYW4gYmUgZW1wdHkgKGEgcmVndWxhciBjdXJzb3JcbnBvc2l0aW9uKS5cbiovXG5jbGFzcyBUZXh0U2VsZWN0aW9uIGV4dGVuZHMgU2VsZWN0aW9uIHtcbiAgICAvKipcbiAgICBDb25zdHJ1Y3QgYSB0ZXh0IHNlbGVjdGlvbiBiZXR3ZWVuIHRoZSBnaXZlbiBwb2ludHMuXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcigkYW5jaG9yLCAkaGVhZCA9ICRhbmNob3IpIHtcbiAgICAgICAgY2hlY2tUZXh0U2VsZWN0aW9uKCRhbmNob3IpO1xuICAgICAgICBjaGVja1RleHRTZWxlY3Rpb24oJGhlYWQpO1xuICAgICAgICBzdXBlcigkYW5jaG9yLCAkaGVhZCk7XG4gICAgfVxuICAgIC8qKlxuICAgIFJldHVybnMgYSByZXNvbHZlZCBwb3NpdGlvbiBpZiB0aGlzIGlzIGEgY3Vyc29yIHNlbGVjdGlvbiAoYW5cbiAgICBlbXB0eSB0ZXh0IHNlbGVjdGlvbiksIGFuZCBudWxsIG90aGVyd2lzZS5cbiAgICAqL1xuICAgIGdldCAkY3Vyc29yKCkgeyByZXR1cm4gdGhpcy4kYW5jaG9yLnBvcyA9PSB0aGlzLiRoZWFkLnBvcyA/IHRoaXMuJGhlYWQgOiBudWxsOyB9XG4gICAgbWFwKGRvYywgbWFwcGluZykge1xuICAgICAgICBsZXQgJGhlYWQgPSBkb2MucmVzb2x2ZShtYXBwaW5nLm1hcCh0aGlzLmhlYWQpKTtcbiAgICAgICAgaWYgKCEkaGVhZC5wYXJlbnQuaW5saW5lQ29udGVudClcbiAgICAgICAgICAgIHJldHVybiBTZWxlY3Rpb24ubmVhcigkaGVhZCk7XG4gICAgICAgIGxldCAkYW5jaG9yID0gZG9jLnJlc29sdmUobWFwcGluZy5tYXAodGhpcy5hbmNob3IpKTtcbiAgICAgICAgcmV0dXJuIG5ldyBUZXh0U2VsZWN0aW9uKCRhbmNob3IucGFyZW50LmlubGluZUNvbnRlbnQgPyAkYW5jaG9yIDogJGhlYWQsICRoZWFkKTtcbiAgICB9XG4gICAgcmVwbGFjZSh0ciwgY29udGVudCA9IFNsaWNlLmVtcHR5KSB7XG4gICAgICAgIHN1cGVyLnJlcGxhY2UodHIsIGNvbnRlbnQpO1xuICAgICAgICBpZiAoY29udGVudCA9PSBTbGljZS5lbXB0eSkge1xuICAgICAgICAgICAgbGV0IG1hcmtzID0gdGhpcy4kZnJvbS5tYXJrc0Fjcm9zcyh0aGlzLiR0byk7XG4gICAgICAgICAgICBpZiAobWFya3MpXG4gICAgICAgICAgICAgICAgdHIuZW5zdXJlTWFya3MobWFya3MpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGVxKG90aGVyKSB7XG4gICAgICAgIHJldHVybiBvdGhlciBpbnN0YW5jZW9mIFRleHRTZWxlY3Rpb24gJiYgb3RoZXIuYW5jaG9yID09IHRoaXMuYW5jaG9yICYmIG90aGVyLmhlYWQgPT0gdGhpcy5oZWFkO1xuICAgIH1cbiAgICBnZXRCb29rbWFyaygpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUZXh0Qm9va21hcmsodGhpcy5hbmNob3IsIHRoaXMuaGVhZCk7XG4gICAgfVxuICAgIHRvSlNPTigpIHtcbiAgICAgICAgcmV0dXJuIHsgdHlwZTogXCJ0ZXh0XCIsIGFuY2hvcjogdGhpcy5hbmNob3IsIGhlYWQ6IHRoaXMuaGVhZCB9O1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHN0YXRpYyBmcm9tSlNPTihkb2MsIGpzb24pIHtcbiAgICAgICAgaWYgKHR5cGVvZiBqc29uLmFuY2hvciAhPSBcIm51bWJlclwiIHx8IHR5cGVvZiBqc29uLmhlYWQgIT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiSW52YWxpZCBpbnB1dCBmb3IgVGV4dFNlbGVjdGlvbi5mcm9tSlNPTlwiKTtcbiAgICAgICAgcmV0dXJuIG5ldyBUZXh0U2VsZWN0aW9uKGRvYy5yZXNvbHZlKGpzb24uYW5jaG9yKSwgZG9jLnJlc29sdmUoanNvbi5oZWFkKSk7XG4gICAgfVxuICAgIC8qKlxuICAgIENyZWF0ZSBhIHRleHQgc2VsZWN0aW9uIGZyb20gbm9uLXJlc29sdmVkIHBvc2l0aW9ucy5cbiAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGUoZG9jLCBhbmNob3IsIGhlYWQgPSBhbmNob3IpIHtcbiAgICAgICAgbGV0ICRhbmNob3IgPSBkb2MucmVzb2x2ZShhbmNob3IpO1xuICAgICAgICByZXR1cm4gbmV3IHRoaXMoJGFuY2hvciwgaGVhZCA9PSBhbmNob3IgPyAkYW5jaG9yIDogZG9jLnJlc29sdmUoaGVhZCkpO1xuICAgIH1cbiAgICAvKipcbiAgICBSZXR1cm4gYSB0ZXh0IHNlbGVjdGlvbiB0aGF0IHNwYW5zIHRoZSBnaXZlbiBwb3NpdGlvbnMgb3IsIGlmXG4gICAgdGhleSBhcmVuJ3QgdGV4dCBwb3NpdGlvbnMsIGZpbmQgYSB0ZXh0IHNlbGVjdGlvbiBuZWFyIHRoZW0uXG4gICAgYGJpYXNgIGRldGVybWluZXMgd2hldGhlciB0aGUgbWV0aG9kIHNlYXJjaGVzIGZvcndhcmQgKGRlZmF1bHQpXG4gICAgb3IgYmFja3dhcmRzIChuZWdhdGl2ZSBudW1iZXIpIGZpcnN0LiBXaWxsIGZhbGwgYmFjayB0byBjYWxsaW5nXG4gICAgW2BTZWxlY3Rpb24ubmVhcmBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNzdGF0ZS5TZWxlY3Rpb25ebmVhcikgd2hlbiB0aGUgZG9jdW1lbnRcbiAgICBkb2Vzbid0IGNvbnRhaW4gYSB2YWxpZCB0ZXh0IHBvc2l0aW9uLlxuICAgICovXG4gICAgc3RhdGljIGJldHdlZW4oJGFuY2hvciwgJGhlYWQsIGJpYXMpIHtcbiAgICAgICAgbGV0IGRQb3MgPSAkYW5jaG9yLnBvcyAtICRoZWFkLnBvcztcbiAgICAgICAgaWYgKCFiaWFzIHx8IGRQb3MpXG4gICAgICAgICAgICBiaWFzID0gZFBvcyA+PSAwID8gMSA6IC0xO1xuICAgICAgICBpZiAoISRoZWFkLnBhcmVudC5pbmxpbmVDb250ZW50KSB7XG4gICAgICAgICAgICBsZXQgZm91bmQgPSBTZWxlY3Rpb24uZmluZEZyb20oJGhlYWQsIGJpYXMsIHRydWUpIHx8IFNlbGVjdGlvbi5maW5kRnJvbSgkaGVhZCwgLWJpYXMsIHRydWUpO1xuICAgICAgICAgICAgaWYgKGZvdW5kKVxuICAgICAgICAgICAgICAgICRoZWFkID0gZm91bmQuJGhlYWQ7XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgcmV0dXJuIFNlbGVjdGlvbi5uZWFyKCRoZWFkLCBiaWFzKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoISRhbmNob3IucGFyZW50LmlubGluZUNvbnRlbnQpIHtcbiAgICAgICAgICAgIGlmIChkUG9zID09IDApIHtcbiAgICAgICAgICAgICAgICAkYW5jaG9yID0gJGhlYWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAkYW5jaG9yID0gKFNlbGVjdGlvbi5maW5kRnJvbSgkYW5jaG9yLCAtYmlhcywgdHJ1ZSkgfHwgU2VsZWN0aW9uLmZpbmRGcm9tKCRhbmNob3IsIGJpYXMsIHRydWUpKS4kYW5jaG9yO1xuICAgICAgICAgICAgICAgIGlmICgoJGFuY2hvci5wb3MgPCAkaGVhZC5wb3MpICE9IChkUG9zIDwgMCkpXG4gICAgICAgICAgICAgICAgICAgICRhbmNob3IgPSAkaGVhZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFRleHRTZWxlY3Rpb24oJGFuY2hvciwgJGhlYWQpO1xuICAgIH1cbn1cblNlbGVjdGlvbi5qc29uSUQoXCJ0ZXh0XCIsIFRleHRTZWxlY3Rpb24pO1xuY2xhc3MgVGV4dEJvb2ttYXJrIHtcbiAgICBjb25zdHJ1Y3RvcihhbmNob3IsIGhlYWQpIHtcbiAgICAgICAgdGhpcy5hbmNob3IgPSBhbmNob3I7XG4gICAgICAgIHRoaXMuaGVhZCA9IGhlYWQ7XG4gICAgfVxuICAgIG1hcChtYXBwaW5nKSB7XG4gICAgICAgIHJldHVybiBuZXcgVGV4dEJvb2ttYXJrKG1hcHBpbmcubWFwKHRoaXMuYW5jaG9yKSwgbWFwcGluZy5tYXAodGhpcy5oZWFkKSk7XG4gICAgfVxuICAgIHJlc29sdmUoZG9jKSB7XG4gICAgICAgIHJldHVybiBUZXh0U2VsZWN0aW9uLmJldHdlZW4oZG9jLnJlc29sdmUodGhpcy5hbmNob3IpLCBkb2MucmVzb2x2ZSh0aGlzLmhlYWQpKTtcbiAgICB9XG59XG4vKipcbkEgbm9kZSBzZWxlY3Rpb24gaXMgYSBzZWxlY3Rpb24gdGhhdCBwb2ludHMgYXQgYSBzaW5nbGUgbm9kZS4gQWxsXG5ub2RlcyBtYXJrZWQgW3NlbGVjdGFibGVdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5Ob2RlU3BlYy5zZWxlY3RhYmxlKSBjYW4gYmUgdGhlXG50YXJnZXQgb2YgYSBub2RlIHNlbGVjdGlvbi4gSW4gc3VjaCBhIHNlbGVjdGlvbiwgYGZyb21gIGFuZCBgdG9gXG5wb2ludCBkaXJlY3RseSBiZWZvcmUgYW5kIGFmdGVyIHRoZSBzZWxlY3RlZCBub2RlLCBgYW5jaG9yYCBlcXVhbHNcbmBmcm9tYCwgYW5kIGBoZWFkYCBlcXVhbHMgYHRvYC4uXG4qL1xuY2xhc3MgTm9kZVNlbGVjdGlvbiBleHRlbmRzIFNlbGVjdGlvbiB7XG4gICAgLyoqXG4gICAgQ3JlYXRlIGEgbm9kZSBzZWxlY3Rpb24uIERvZXMgbm90IHZlcmlmeSB0aGUgdmFsaWRpdHkgb2YgaXRzXG4gICAgYXJndW1lbnQuXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcigkcG9zKSB7XG4gICAgICAgIGxldCBub2RlID0gJHBvcy5ub2RlQWZ0ZXI7XG4gICAgICAgIGxldCAkZW5kID0gJHBvcy5ub2RlKDApLnJlc29sdmUoJHBvcy5wb3MgKyBub2RlLm5vZGVTaXplKTtcbiAgICAgICAgc3VwZXIoJHBvcywgJGVuZCk7XG4gICAgICAgIHRoaXMubm9kZSA9IG5vZGU7XG4gICAgfVxuICAgIG1hcChkb2MsIG1hcHBpbmcpIHtcbiAgICAgICAgbGV0IHsgZGVsZXRlZCwgcG9zIH0gPSBtYXBwaW5nLm1hcFJlc3VsdCh0aGlzLmFuY2hvcik7XG4gICAgICAgIGxldCAkcG9zID0gZG9jLnJlc29sdmUocG9zKTtcbiAgICAgICAgaWYgKGRlbGV0ZWQpXG4gICAgICAgICAgICByZXR1cm4gU2VsZWN0aW9uLm5lYXIoJHBvcyk7XG4gICAgICAgIHJldHVybiBuZXcgTm9kZVNlbGVjdGlvbigkcG9zKTtcbiAgICB9XG4gICAgY29udGVudCgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTbGljZShGcmFnbWVudC5mcm9tKHRoaXMubm9kZSksIDAsIDApO1xuICAgIH1cbiAgICBlcShvdGhlcikge1xuICAgICAgICByZXR1cm4gb3RoZXIgaW5zdGFuY2VvZiBOb2RlU2VsZWN0aW9uICYmIG90aGVyLmFuY2hvciA9PSB0aGlzLmFuY2hvcjtcbiAgICB9XG4gICAgdG9KU09OKCkge1xuICAgICAgICByZXR1cm4geyB0eXBlOiBcIm5vZGVcIiwgYW5jaG9yOiB0aGlzLmFuY2hvciB9O1xuICAgIH1cbiAgICBnZXRCb29rbWFyaygpIHsgcmV0dXJuIG5ldyBOb2RlQm9va21hcmsodGhpcy5hbmNob3IpOyB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBzdGF0aWMgZnJvbUpTT04oZG9jLCBqc29uKSB7XG4gICAgICAgIGlmICh0eXBlb2YganNvbi5hbmNob3IgIT0gXCJudW1iZXJcIilcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiSW52YWxpZCBpbnB1dCBmb3IgTm9kZVNlbGVjdGlvbi5mcm9tSlNPTlwiKTtcbiAgICAgICAgcmV0dXJuIG5ldyBOb2RlU2VsZWN0aW9uKGRvYy5yZXNvbHZlKGpzb24uYW5jaG9yKSk7XG4gICAgfVxuICAgIC8qKlxuICAgIENyZWF0ZSBhIG5vZGUgc2VsZWN0aW9uIGZyb20gbm9uLXJlc29sdmVkIHBvc2l0aW9ucy5cbiAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGUoZG9jLCBmcm9tKSB7XG4gICAgICAgIHJldHVybiBuZXcgTm9kZVNlbGVjdGlvbihkb2MucmVzb2x2ZShmcm9tKSk7XG4gICAgfVxuICAgIC8qKlxuICAgIERldGVybWluZXMgd2hldGhlciB0aGUgZ2l2ZW4gbm9kZSBtYXkgYmUgc2VsZWN0ZWQgYXMgYSBub2RlXG4gICAgc2VsZWN0aW9uLlxuICAgICovXG4gICAgc3RhdGljIGlzU2VsZWN0YWJsZShub2RlKSB7XG4gICAgICAgIHJldHVybiAhbm9kZS5pc1RleHQgJiYgbm9kZS50eXBlLnNwZWMuc2VsZWN0YWJsZSAhPT0gZmFsc2U7XG4gICAgfVxufVxuTm9kZVNlbGVjdGlvbi5wcm90b3R5cGUudmlzaWJsZSA9IGZhbHNlO1xuU2VsZWN0aW9uLmpzb25JRChcIm5vZGVcIiwgTm9kZVNlbGVjdGlvbik7XG5jbGFzcyBOb2RlQm9va21hcmsge1xuICAgIGNvbnN0cnVjdG9yKGFuY2hvcikge1xuICAgICAgICB0aGlzLmFuY2hvciA9IGFuY2hvcjtcbiAgICB9XG4gICAgbWFwKG1hcHBpbmcpIHtcbiAgICAgICAgbGV0IHsgZGVsZXRlZCwgcG9zIH0gPSBtYXBwaW5nLm1hcFJlc3VsdCh0aGlzLmFuY2hvcik7XG4gICAgICAgIHJldHVybiBkZWxldGVkID8gbmV3IFRleHRCb29rbWFyayhwb3MsIHBvcykgOiBuZXcgTm9kZUJvb2ttYXJrKHBvcyk7XG4gICAgfVxuICAgIHJlc29sdmUoZG9jKSB7XG4gICAgICAgIGxldCAkcG9zID0gZG9jLnJlc29sdmUodGhpcy5hbmNob3IpLCBub2RlID0gJHBvcy5ub2RlQWZ0ZXI7XG4gICAgICAgIGlmIChub2RlICYmIE5vZGVTZWxlY3Rpb24uaXNTZWxlY3RhYmxlKG5vZGUpKVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBOb2RlU2VsZWN0aW9uKCRwb3MpO1xuICAgICAgICByZXR1cm4gU2VsZWN0aW9uLm5lYXIoJHBvcyk7XG4gICAgfVxufVxuLyoqXG5BIHNlbGVjdGlvbiB0eXBlIHRoYXQgcmVwcmVzZW50cyBzZWxlY3RpbmcgdGhlIHdob2xlIGRvY3VtZW50XG4od2hpY2ggY2FuIG5vdCBuZWNlc3NhcmlseSBiZSBleHByZXNzZWQgd2l0aCBhIHRleHQgc2VsZWN0aW9uLCB3aGVuXG50aGVyZSBhcmUgZm9yIGV4YW1wbGUgbGVhZiBibG9jayBub2RlcyBhdCB0aGUgc3RhcnQgb3IgZW5kIG9mIHRoZVxuZG9jdW1lbnQpLlxuKi9cbmNsYXNzIEFsbFNlbGVjdGlvbiBleHRlbmRzIFNlbGVjdGlvbiB7XG4gICAgLyoqXG4gICAgQ3JlYXRlIGFuIGFsbC1zZWxlY3Rpb24gb3ZlciB0aGUgZ2l2ZW4gZG9jdW1lbnQuXG4gICAgKi9cbiAgICBjb25zdHJ1Y3Rvcihkb2MpIHtcbiAgICAgICAgc3VwZXIoZG9jLnJlc29sdmUoMCksIGRvYy5yZXNvbHZlKGRvYy5jb250ZW50LnNpemUpKTtcbiAgICB9XG4gICAgcmVwbGFjZSh0ciwgY29udGVudCA9IFNsaWNlLmVtcHR5KSB7XG4gICAgICAgIGlmIChjb250ZW50ID09IFNsaWNlLmVtcHR5KSB7XG4gICAgICAgICAgICB0ci5kZWxldGUoMCwgdHIuZG9jLmNvbnRlbnQuc2l6ZSk7XG4gICAgICAgICAgICBsZXQgc2VsID0gU2VsZWN0aW9uLmF0U3RhcnQodHIuZG9jKTtcbiAgICAgICAgICAgIGlmICghc2VsLmVxKHRyLnNlbGVjdGlvbikpXG4gICAgICAgICAgICAgICAgdHIuc2V0U2VsZWN0aW9uKHNlbCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBzdXBlci5yZXBsYWNlKHRyLCBjb250ZW50KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICB0b0pTT04oKSB7IHJldHVybiB7IHR5cGU6IFwiYWxsXCIgfTsgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgc3RhdGljIGZyb21KU09OKGRvYykgeyByZXR1cm4gbmV3IEFsbFNlbGVjdGlvbihkb2MpOyB9XG4gICAgbWFwKGRvYykgeyByZXR1cm4gbmV3IEFsbFNlbGVjdGlvbihkb2MpOyB9XG4gICAgZXEob3RoZXIpIHsgcmV0dXJuIG90aGVyIGluc3RhbmNlb2YgQWxsU2VsZWN0aW9uOyB9XG4gICAgZ2V0Qm9va21hcmsoKSB7IHJldHVybiBBbGxCb29rbWFyazsgfVxufVxuU2VsZWN0aW9uLmpzb25JRChcImFsbFwiLCBBbGxTZWxlY3Rpb24pO1xuY29uc3QgQWxsQm9va21hcmsgPSB7XG4gICAgbWFwKCkgeyByZXR1cm4gdGhpczsgfSxcbiAgICByZXNvbHZlKGRvYykgeyByZXR1cm4gbmV3IEFsbFNlbGVjdGlvbihkb2MpOyB9XG59O1xuLy8gRklYTUUgd2UnbGwgbmVlZCBzb21lIGF3YXJlbmVzcyBvZiB0ZXh0IGRpcmVjdGlvbiB3aGVuIHNjYW5uaW5nIGZvciBzZWxlY3Rpb25zXG4vLyBUcnkgdG8gZmluZCBhIHNlbGVjdGlvbiBpbnNpZGUgdGhlIGdpdmVuIG5vZGUuIGBwb3NgIHBvaW50cyBhdCB0aGVcbi8vIHBvc2l0aW9uIHdoZXJlIHRoZSBzZWFyY2ggc3RhcnRzLiBXaGVuIGB0ZXh0YCBpcyB0cnVlLCBvbmx5IHJldHVyblxuLy8gdGV4dCBzZWxlY3Rpb25zLlxuZnVuY3Rpb24gZmluZFNlbGVjdGlvbkluKGRvYywgbm9kZSwgcG9zLCBpbmRleCwgZGlyLCB0ZXh0ID0gZmFsc2UpIHtcbiAgICBpZiAobm9kZS5pbmxpbmVDb250ZW50KVxuICAgICAgICByZXR1cm4gVGV4dFNlbGVjdGlvbi5jcmVhdGUoZG9jLCBwb3MpO1xuICAgIGZvciAobGV0IGkgPSBpbmRleCAtIChkaXIgPiAwID8gMCA6IDEpOyBkaXIgPiAwID8gaSA8IG5vZGUuY2hpbGRDb3VudCA6IGkgPj0gMDsgaSArPSBkaXIpIHtcbiAgICAgICAgbGV0IGNoaWxkID0gbm9kZS5jaGlsZChpKTtcbiAgICAgICAgaWYgKCFjaGlsZC5pc0F0b20pIHtcbiAgICAgICAgICAgIGxldCBpbm5lciA9IGZpbmRTZWxlY3Rpb25Jbihkb2MsIGNoaWxkLCBwb3MgKyBkaXIsIGRpciA8IDAgPyBjaGlsZC5jaGlsZENvdW50IDogMCwgZGlyLCB0ZXh0KTtcbiAgICAgICAgICAgIGlmIChpbm5lcilcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5uZXI7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIXRleHQgJiYgTm9kZVNlbGVjdGlvbi5pc1NlbGVjdGFibGUoY2hpbGQpKSB7XG4gICAgICAgICAgICByZXR1cm4gTm9kZVNlbGVjdGlvbi5jcmVhdGUoZG9jLCBwb3MgLSAoZGlyIDwgMCA/IGNoaWxkLm5vZGVTaXplIDogMCkpO1xuICAgICAgICB9XG4gICAgICAgIHBvcyArPSBjaGlsZC5ub2RlU2l6ZSAqIGRpcjtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5mdW5jdGlvbiBzZWxlY3Rpb25Ub0luc2VydGlvbkVuZCh0ciwgc3RhcnRMZW4sIGJpYXMpIHtcbiAgICBsZXQgbGFzdCA9IHRyLnN0ZXBzLmxlbmd0aCAtIDE7XG4gICAgaWYgKGxhc3QgPCBzdGFydExlbilcbiAgICAgICAgcmV0dXJuO1xuICAgIGxldCBzdGVwID0gdHIuc3RlcHNbbGFzdF07XG4gICAgaWYgKCEoc3RlcCBpbnN0YW5jZW9mIFJlcGxhY2VTdGVwIHx8IHN0ZXAgaW5zdGFuY2VvZiBSZXBsYWNlQXJvdW5kU3RlcCkpXG4gICAgICAgIHJldHVybjtcbiAgICBsZXQgbWFwID0gdHIubWFwcGluZy5tYXBzW2xhc3RdLCBlbmQ7XG4gICAgbWFwLmZvckVhY2goKF9mcm9tLCBfdG8sIF9uZXdGcm9tLCBuZXdUbykgPT4geyBpZiAoZW5kID09IG51bGwpXG4gICAgICAgIGVuZCA9IG5ld1RvOyB9KTtcbiAgICB0ci5zZXRTZWxlY3Rpb24oU2VsZWN0aW9uLm5lYXIodHIuZG9jLnJlc29sdmUoZW5kKSwgYmlhcykpO1xufVxuXG5jb25zdCBVUERBVEVEX1NFTCA9IDEsIFVQREFURURfTUFSS1MgPSAyLCBVUERBVEVEX1NDUk9MTCA9IDQ7XG4vKipcbkFuIGVkaXRvciBzdGF0ZSB0cmFuc2FjdGlvbiwgd2hpY2ggY2FuIGJlIGFwcGxpZWQgdG8gYSBzdGF0ZSB0b1xuY3JlYXRlIGFuIHVwZGF0ZWQgc3RhdGUuIFVzZVxuW2BFZGl0b3JTdGF0ZS50cmBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNzdGF0ZS5FZGl0b3JTdGF0ZS50cikgdG8gY3JlYXRlIGFuIGluc3RhbmNlLlxuXG5UcmFuc2FjdGlvbnMgdHJhY2sgY2hhbmdlcyB0byB0aGUgZG9jdW1lbnQgKHRoZXkgYXJlIGEgc3ViY2xhc3Mgb2ZcbltgVHJhbnNmb3JtYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3RyYW5zZm9ybS5UcmFuc2Zvcm0pKSwgYnV0IGFsc28gb3RoZXIgc3RhdGUgY2hhbmdlcyxcbmxpa2Ugc2VsZWN0aW9uIHVwZGF0ZXMgYW5kIGFkanVzdG1lbnRzIG9mIHRoZSBzZXQgb2YgW3N0b3JlZFxubWFya3NdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNzdGF0ZS5FZGl0b3JTdGF0ZS5zdG9yZWRNYXJrcykuIEluIGFkZGl0aW9uLCB5b3UgY2FuIHN0b3JlXG5tZXRhZGF0YSBwcm9wZXJ0aWVzIGluIGEgdHJhbnNhY3Rpb24sIHdoaWNoIGFyZSBleHRyYSBwaWVjZXMgb2ZcbmluZm9ybWF0aW9uIHRoYXQgY2xpZW50IGNvZGUgb3IgcGx1Z2lucyBjYW4gdXNlIHRvIGRlc2NyaWJlIHdoYXQgYVxudHJhbnNhY3Rpb24gcmVwcmVzZW50cywgc28gdGhhdCB0aGV5IGNhbiB1cGRhdGUgdGhlaXIgW293blxuc3RhdGVdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNzdGF0ZS5TdGF0ZUZpZWxkKSBhY2NvcmRpbmdseS5cblxuVGhlIFtlZGl0b3Igdmlld10oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3ZpZXcuRWRpdG9yVmlldykgdXNlcyBhIGZldyBtZXRhZGF0YVxucHJvcGVydGllczogaXQgd2lsbCBhdHRhY2ggYSBwcm9wZXJ0eSBgXCJwb2ludGVyXCJgIHdpdGggdGhlIHZhbHVlXG5gdHJ1ZWAgdG8gc2VsZWN0aW9uIHRyYW5zYWN0aW9ucyBkaXJlY3RseSBjYXVzZWQgYnkgbW91c2Ugb3IgdG91Y2hcbmlucHV0LCBhIGBcImNvbXBvc2l0aW9uXCJgIHByb3BlcnR5IGhvbGRpbmcgYW4gSUQgaWRlbnRpZnlpbmcgdGhlXG5jb21wb3NpdGlvbiB0aGF0IGNhdXNlZCBpdCB0byB0cmFuc2FjdGlvbnMgY2F1c2VkIGJ5IGNvbXBvc2VkIERPTVxuaW5wdXQsIGFuZCBhIGBcInVpRXZlbnRcImAgcHJvcGVydHkgb2YgdGhhdCBtYXkgYmUgYFwicGFzdGVcImAsXG5gXCJjdXRcImAsIG9yIGBcImRyb3BcImAuXG4qL1xuY2xhc3MgVHJhbnNhY3Rpb24gZXh0ZW5kcyBUcmFuc2Zvcm0ge1xuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgY29uc3RydWN0b3Ioc3RhdGUpIHtcbiAgICAgICAgc3VwZXIoc3RhdGUuZG9jKTtcbiAgICAgICAgLy8gVGhlIHN0ZXAgY291bnQgZm9yIHdoaWNoIHRoZSBjdXJyZW50IHNlbGVjdGlvbiBpcyB2YWxpZC5cbiAgICAgICAgdGhpcy5jdXJTZWxlY3Rpb25Gb3IgPSAwO1xuICAgICAgICAvLyBCaXRmaWVsZCB0byB0cmFjayB3aGljaCBhc3BlY3RzIG9mIHRoZSBzdGF0ZSB3ZXJlIHVwZGF0ZWQgYnlcbiAgICAgICAgLy8gdGhpcyB0cmFuc2FjdGlvbi5cbiAgICAgICAgdGhpcy51cGRhdGVkID0gMDtcbiAgICAgICAgLy8gT2JqZWN0IHVzZWQgdG8gc3RvcmUgbWV0YWRhdGEgcHJvcGVydGllcyBmb3IgdGhlIHRyYW5zYWN0aW9uLlxuICAgICAgICB0aGlzLm1ldGEgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICB0aGlzLnRpbWUgPSBEYXRlLm5vdygpO1xuICAgICAgICB0aGlzLmN1clNlbGVjdGlvbiA9IHN0YXRlLnNlbGVjdGlvbjtcbiAgICAgICAgdGhpcy5zdG9yZWRNYXJrcyA9IHN0YXRlLnN0b3JlZE1hcmtzO1xuICAgIH1cbiAgICAvKipcbiAgICBUaGUgdHJhbnNhY3Rpb24ncyBjdXJyZW50IHNlbGVjdGlvbi4gVGhpcyBkZWZhdWx0cyB0byB0aGUgZWRpdG9yXG4gICAgc2VsZWN0aW9uIFttYXBwZWRdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNzdGF0ZS5TZWxlY3Rpb24ubWFwKSB0aHJvdWdoIHRoZSBzdGVwcyBpbiB0aGVcbiAgICB0cmFuc2FjdGlvbiwgYnV0IGNhbiBiZSBvdmVyd3JpdHRlbiB3aXRoXG4gICAgW2BzZXRTZWxlY3Rpb25gXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jc3RhdGUuVHJhbnNhY3Rpb24uc2V0U2VsZWN0aW9uKS5cbiAgICAqL1xuICAgIGdldCBzZWxlY3Rpb24oKSB7XG4gICAgICAgIGlmICh0aGlzLmN1clNlbGVjdGlvbkZvciA8IHRoaXMuc3RlcHMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLmN1clNlbGVjdGlvbiA9IHRoaXMuY3VyU2VsZWN0aW9uLm1hcCh0aGlzLmRvYywgdGhpcy5tYXBwaW5nLnNsaWNlKHRoaXMuY3VyU2VsZWN0aW9uRm9yKSk7XG4gICAgICAgICAgICB0aGlzLmN1clNlbGVjdGlvbkZvciA9IHRoaXMuc3RlcHMubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmN1clNlbGVjdGlvbjtcbiAgICB9XG4gICAgLyoqXG4gICAgVXBkYXRlIHRoZSB0cmFuc2FjdGlvbidzIGN1cnJlbnQgc2VsZWN0aW9uLiBXaWxsIGRldGVybWluZSB0aGVcbiAgICBzZWxlY3Rpb24gdGhhdCB0aGUgZWRpdG9yIGdldHMgd2hlbiB0aGUgdHJhbnNhY3Rpb24gaXMgYXBwbGllZC5cbiAgICAqL1xuICAgIHNldFNlbGVjdGlvbihzZWxlY3Rpb24pIHtcbiAgICAgICAgaWYgKHNlbGVjdGlvbi4kZnJvbS5kb2MgIT0gdGhpcy5kb2MpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIlNlbGVjdGlvbiBwYXNzZWQgdG8gc2V0U2VsZWN0aW9uIG11c3QgcG9pbnQgYXQgdGhlIGN1cnJlbnQgZG9jdW1lbnRcIik7XG4gICAgICAgIHRoaXMuY3VyU2VsZWN0aW9uID0gc2VsZWN0aW9uO1xuICAgICAgICB0aGlzLmN1clNlbGVjdGlvbkZvciA9IHRoaXMuc3RlcHMubGVuZ3RoO1xuICAgICAgICB0aGlzLnVwZGF0ZWQgPSAodGhpcy51cGRhdGVkIHwgVVBEQVRFRF9TRUwpICYgflVQREFURURfTUFSS1M7XG4gICAgICAgIHRoaXMuc3RvcmVkTWFya3MgPSBudWxsO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgV2hldGhlciB0aGUgc2VsZWN0aW9uIHdhcyBleHBsaWNpdGx5IHVwZGF0ZWQgYnkgdGhpcyB0cmFuc2FjdGlvbi5cbiAgICAqL1xuICAgIGdldCBzZWxlY3Rpb25TZXQoKSB7XG4gICAgICAgIHJldHVybiAodGhpcy51cGRhdGVkICYgVVBEQVRFRF9TRUwpID4gMDtcbiAgICB9XG4gICAgLyoqXG4gICAgU2V0IHRoZSBjdXJyZW50IHN0b3JlZCBtYXJrcy5cbiAgICAqL1xuICAgIHNldFN0b3JlZE1hcmtzKG1hcmtzKSB7XG4gICAgICAgIHRoaXMuc3RvcmVkTWFya3MgPSBtYXJrcztcbiAgICAgICAgdGhpcy51cGRhdGVkIHw9IFVQREFURURfTUFSS1M7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICBNYWtlIHN1cmUgdGhlIGN1cnJlbnQgc3RvcmVkIG1hcmtzIG9yLCBpZiB0aGF0IGlzIG51bGwsIHRoZSBtYXJrc1xuICAgIGF0IHRoZSBzZWxlY3Rpb24sIG1hdGNoIHRoZSBnaXZlbiBzZXQgb2YgbWFya3MuIERvZXMgbm90aGluZyBpZlxuICAgIHRoaXMgaXMgYWxyZWFkeSB0aGUgY2FzZS5cbiAgICAqL1xuICAgIGVuc3VyZU1hcmtzKG1hcmtzKSB7XG4gICAgICAgIGlmICghTWFyay5zYW1lU2V0KHRoaXMuc3RvcmVkTWFya3MgfHwgdGhpcy5zZWxlY3Rpb24uJGZyb20ubWFya3MoKSwgbWFya3MpKVxuICAgICAgICAgICAgdGhpcy5zZXRTdG9yZWRNYXJrcyhtYXJrcyk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICBBZGQgYSBtYXJrIHRvIHRoZSBzZXQgb2Ygc3RvcmVkIG1hcmtzLlxuICAgICovXG4gICAgYWRkU3RvcmVkTWFyayhtYXJrKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVuc3VyZU1hcmtzKG1hcmsuYWRkVG9TZXQodGhpcy5zdG9yZWRNYXJrcyB8fCB0aGlzLnNlbGVjdGlvbi4kaGVhZC5tYXJrcygpKSk7XG4gICAgfVxuICAgIC8qKlxuICAgIFJlbW92ZSBhIG1hcmsgb3IgbWFyayB0eXBlIGZyb20gdGhlIHNldCBvZiBzdG9yZWQgbWFya3MuXG4gICAgKi9cbiAgICByZW1vdmVTdG9yZWRNYXJrKG1hcmspIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZW5zdXJlTWFya3MobWFyay5yZW1vdmVGcm9tU2V0KHRoaXMuc3RvcmVkTWFya3MgfHwgdGhpcy5zZWxlY3Rpb24uJGhlYWQubWFya3MoKSkpO1xuICAgIH1cbiAgICAvKipcbiAgICBXaGV0aGVyIHRoZSBzdG9yZWQgbWFya3Mgd2VyZSBleHBsaWNpdGx5IHNldCBmb3IgdGhpcyB0cmFuc2FjdGlvbi5cbiAgICAqL1xuICAgIGdldCBzdG9yZWRNYXJrc1NldCgpIHtcbiAgICAgICAgcmV0dXJuICh0aGlzLnVwZGF0ZWQgJiBVUERBVEVEX01BUktTKSA+IDA7XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgYWRkU3RlcChzdGVwLCBkb2MpIHtcbiAgICAgICAgc3VwZXIuYWRkU3RlcChzdGVwLCBkb2MpO1xuICAgICAgICB0aGlzLnVwZGF0ZWQgPSB0aGlzLnVwZGF0ZWQgJiB+VVBEQVRFRF9NQVJLUztcbiAgICAgICAgdGhpcy5zdG9yZWRNYXJrcyA9IG51bGw7XG4gICAgfVxuICAgIC8qKlxuICAgIFVwZGF0ZSB0aGUgdGltZXN0YW1wIGZvciB0aGUgdHJhbnNhY3Rpb24uXG4gICAgKi9cbiAgICBzZXRUaW1lKHRpbWUpIHtcbiAgICAgICAgdGhpcy50aW1lID0gdGltZTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIFJlcGxhY2UgdGhlIGN1cnJlbnQgc2VsZWN0aW9uIHdpdGggdGhlIGdpdmVuIHNsaWNlLlxuICAgICovXG4gICAgcmVwbGFjZVNlbGVjdGlvbihzbGljZSkge1xuICAgICAgICB0aGlzLnNlbGVjdGlvbi5yZXBsYWNlKHRoaXMsIHNsaWNlKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIFJlcGxhY2UgdGhlIHNlbGVjdGlvbiB3aXRoIHRoZSBnaXZlbiBub2RlLiBXaGVuIGBpbmhlcml0TWFya3NgIGlzXG4gICAgdHJ1ZSBhbmQgdGhlIGNvbnRlbnQgaXMgaW5saW5lLCBpdCBpbmhlcml0cyB0aGUgbWFya3MgZnJvbSB0aGVcbiAgICBwbGFjZSB3aGVyZSBpdCBpcyBpbnNlcnRlZC5cbiAgICAqL1xuICAgIHJlcGxhY2VTZWxlY3Rpb25XaXRoKG5vZGUsIGluaGVyaXRNYXJrcyA9IHRydWUpIHtcbiAgICAgICAgbGV0IHNlbGVjdGlvbiA9IHRoaXMuc2VsZWN0aW9uO1xuICAgICAgICBpZiAoaW5oZXJpdE1hcmtzKVxuICAgICAgICAgICAgbm9kZSA9IG5vZGUubWFyayh0aGlzLnN0b3JlZE1hcmtzIHx8IChzZWxlY3Rpb24uZW1wdHkgPyBzZWxlY3Rpb24uJGZyb20ubWFya3MoKSA6IChzZWxlY3Rpb24uJGZyb20ubWFya3NBY3Jvc3Moc2VsZWN0aW9uLiR0bykgfHwgTWFyay5ub25lKSkpO1xuICAgICAgICBzZWxlY3Rpb24ucmVwbGFjZVdpdGgodGhpcywgbm9kZSk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgICAvKipcbiAgICBEZWxldGUgdGhlIHNlbGVjdGlvbi5cbiAgICAqL1xuICAgIGRlbGV0ZVNlbGVjdGlvbigpIHtcbiAgICAgICAgdGhpcy5zZWxlY3Rpb24ucmVwbGFjZSh0aGlzKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgIFJlcGxhY2UgdGhlIGdpdmVuIHJhbmdlLCBvciB0aGUgc2VsZWN0aW9uIGlmIG5vIHJhbmdlIGlzIGdpdmVuLFxuICAgIHdpdGggYSB0ZXh0IG5vZGUgY29udGFpbmluZyB0aGUgZ2l2ZW4gc3RyaW5nLlxuICAgICovXG4gICAgaW5zZXJ0VGV4dCh0ZXh0LCBmcm9tLCB0bykge1xuICAgICAgICBsZXQgc2NoZW1hID0gdGhpcy5kb2MudHlwZS5zY2hlbWE7XG4gICAgICAgIGlmIChmcm9tID09IG51bGwpIHtcbiAgICAgICAgICAgIGlmICghdGV4dClcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5kZWxldGVTZWxlY3Rpb24oKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnJlcGxhY2VTZWxlY3Rpb25XaXRoKHNjaGVtYS50ZXh0KHRleHQpLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmICh0byA9PSBudWxsKVxuICAgICAgICAgICAgICAgIHRvID0gZnJvbTtcbiAgICAgICAgICAgIHRvID0gdG8gPT0gbnVsbCA/IGZyb20gOiB0bztcbiAgICAgICAgICAgIGlmICghdGV4dClcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5kZWxldGVSYW5nZShmcm9tLCB0byk7XG4gICAgICAgICAgICBsZXQgbWFya3MgPSB0aGlzLnN0b3JlZE1hcmtzO1xuICAgICAgICAgICAgaWYgKCFtYXJrcykge1xuICAgICAgICAgICAgICAgIGxldCAkZnJvbSA9IHRoaXMuZG9jLnJlc29sdmUoZnJvbSk7XG4gICAgICAgICAgICAgICAgbWFya3MgPSB0byA9PSBmcm9tID8gJGZyb20ubWFya3MoKSA6ICRmcm9tLm1hcmtzQWNyb3NzKHRoaXMuZG9jLnJlc29sdmUodG8pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMucmVwbGFjZVJhbmdlV2l0aChmcm9tLCB0bywgc2NoZW1hLnRleHQodGV4dCwgbWFya3MpKTtcbiAgICAgICAgICAgIGlmICghdGhpcy5zZWxlY3Rpb24uZW1wdHkpXG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTZWxlY3Rpb24oU2VsZWN0aW9uLm5lYXIodGhpcy5zZWxlY3Rpb24uJHRvKSk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICBTdG9yZSBhIG1ldGFkYXRhIHByb3BlcnR5IGluIHRoaXMgdHJhbnNhY3Rpb24sIGtleWVkIGVpdGhlciBieVxuICAgIG5hbWUgb3IgYnkgcGx1Z2luLlxuICAgICovXG4gICAgc2V0TWV0YShrZXksIHZhbHVlKSB7XG4gICAgICAgIHRoaXMubWV0YVt0eXBlb2Yga2V5ID09IFwic3RyaW5nXCIgPyBrZXkgOiBrZXkua2V5XSA9IHZhbHVlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgUmV0cmlldmUgYSBtZXRhZGF0YSBwcm9wZXJ0eSBmb3IgYSBnaXZlbiBuYW1lIG9yIHBsdWdpbi5cbiAgICAqL1xuICAgIGdldE1ldGEoa2V5KSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1ldGFbdHlwZW9mIGtleSA9PSBcInN0cmluZ1wiID8ga2V5IDoga2V5LmtleV07XG4gICAgfVxuICAgIC8qKlxuICAgIFJldHVybnMgdHJ1ZSBpZiB0aGlzIHRyYW5zYWN0aW9uIGRvZXNuJ3QgY29udGFpbiBhbnkgbWV0YWRhdGEsXG4gICAgYW5kIGNhbiB0aHVzIHNhZmVseSBiZSBleHRlbmRlZC5cbiAgICAqL1xuICAgIGdldCBpc0dlbmVyaWMoKSB7XG4gICAgICAgIGZvciAobGV0IF8gaW4gdGhpcy5tZXRhKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgSW5kaWNhdGUgdGhhdCB0aGUgZWRpdG9yIHNob3VsZCBzY3JvbGwgdGhlIHNlbGVjdGlvbiBpbnRvIHZpZXdcbiAgICB3aGVuIHVwZGF0ZWQgdG8gdGhlIHN0YXRlIHByb2R1Y2VkIGJ5IHRoaXMgdHJhbnNhY3Rpb24uXG4gICAgKi9cbiAgICBzY3JvbGxJbnRvVmlldygpIHtcbiAgICAgICAgdGhpcy51cGRhdGVkIHw9IFVQREFURURfU0NST0xMO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgLyoqXG4gICAgVHJ1ZSB3aGVuIHRoaXMgdHJhbnNhY3Rpb24gaGFzIGhhZCBgc2Nyb2xsSW50b1ZpZXdgIGNhbGxlZCBvbiBpdC5cbiAgICAqL1xuICAgIGdldCBzY3JvbGxlZEludG9WaWV3KCkge1xuICAgICAgICByZXR1cm4gKHRoaXMudXBkYXRlZCAmIFVQREFURURfU0NST0xMKSA+IDA7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBiaW5kKGYsIHNlbGYpIHtcbiAgICByZXR1cm4gIXNlbGYgfHwgIWYgPyBmIDogZi5iaW5kKHNlbGYpO1xufVxuY2xhc3MgRmllbGREZXNjIHtcbiAgICBjb25zdHJ1Y3RvcihuYW1lLCBkZXNjLCBzZWxmKSB7XG4gICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgICAgIHRoaXMuaW5pdCA9IGJpbmQoZGVzYy5pbml0LCBzZWxmKTtcbiAgICAgICAgdGhpcy5hcHBseSA9IGJpbmQoZGVzYy5hcHBseSwgc2VsZik7XG4gICAgfVxufVxuY29uc3QgYmFzZUZpZWxkcyA9IFtcbiAgICBuZXcgRmllbGREZXNjKFwiZG9jXCIsIHtcbiAgICAgICAgaW5pdChjb25maWcpIHsgcmV0dXJuIGNvbmZpZy5kb2MgfHwgY29uZmlnLnNjaGVtYS50b3BOb2RlVHlwZS5jcmVhdGVBbmRGaWxsKCk7IH0sXG4gICAgICAgIGFwcGx5KHRyKSB7IHJldHVybiB0ci5kb2M7IH1cbiAgICB9KSxcbiAgICBuZXcgRmllbGREZXNjKFwic2VsZWN0aW9uXCIsIHtcbiAgICAgICAgaW5pdChjb25maWcsIGluc3RhbmNlKSB7IHJldHVybiBjb25maWcuc2VsZWN0aW9uIHx8IFNlbGVjdGlvbi5hdFN0YXJ0KGluc3RhbmNlLmRvYyk7IH0sXG4gICAgICAgIGFwcGx5KHRyKSB7IHJldHVybiB0ci5zZWxlY3Rpb247IH1cbiAgICB9KSxcbiAgICBuZXcgRmllbGREZXNjKFwic3RvcmVkTWFya3NcIiwge1xuICAgICAgICBpbml0KGNvbmZpZykgeyByZXR1cm4gY29uZmlnLnN0b3JlZE1hcmtzIHx8IG51bGw7IH0sXG4gICAgICAgIGFwcGx5KHRyLCBfbWFya3MsIF9vbGQsIHN0YXRlKSB7IHJldHVybiBzdGF0ZS5zZWxlY3Rpb24uJGN1cnNvciA/IHRyLnN0b3JlZE1hcmtzIDogbnVsbDsgfVxuICAgIH0pLFxuICAgIG5ldyBGaWVsZERlc2MoXCJzY3JvbGxUb1NlbGVjdGlvblwiLCB7XG4gICAgICAgIGluaXQoKSB7IHJldHVybiAwOyB9LFxuICAgICAgICBhcHBseSh0ciwgcHJldikgeyByZXR1cm4gdHIuc2Nyb2xsZWRJbnRvVmlldyA/IHByZXYgKyAxIDogcHJldjsgfVxuICAgIH0pXG5dO1xuLy8gT2JqZWN0IHdyYXBwaW5nIHRoZSBwYXJ0IG9mIGEgc3RhdGUgb2JqZWN0IHRoYXQgc3RheXMgdGhlIHNhbWVcbi8vIGFjcm9zcyB0cmFuc2FjdGlvbnMuIFN0b3JlZCBpbiB0aGUgc3RhdGUncyBgY29uZmlnYCBwcm9wZXJ0eS5cbmNsYXNzIENvbmZpZ3VyYXRpb24ge1xuICAgIGNvbnN0cnVjdG9yKHNjaGVtYSwgcGx1Z2lucykge1xuICAgICAgICB0aGlzLnNjaGVtYSA9IHNjaGVtYTtcbiAgICAgICAgdGhpcy5wbHVnaW5zID0gW107XG4gICAgICAgIHRoaXMucGx1Z2luc0J5S2V5ID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgdGhpcy5maWVsZHMgPSBiYXNlRmllbGRzLnNsaWNlKCk7XG4gICAgICAgIGlmIChwbHVnaW5zKVxuICAgICAgICAgICAgcGx1Z2lucy5mb3JFYWNoKHBsdWdpbiA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucGx1Z2luc0J5S2V5W3BsdWdpbi5rZXldKVxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkFkZGluZyBkaWZmZXJlbnQgaW5zdGFuY2VzIG9mIGEga2V5ZWQgcGx1Z2luIChcIiArIHBsdWdpbi5rZXkgKyBcIilcIik7XG4gICAgICAgICAgICAgICAgdGhpcy5wbHVnaW5zLnB1c2gocGx1Z2luKTtcbiAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbnNCeUtleVtwbHVnaW4ua2V5XSA9IHBsdWdpbjtcbiAgICAgICAgICAgICAgICBpZiAocGx1Z2luLnNwZWMuc3RhdGUpXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZmllbGRzLnB1c2gobmV3IEZpZWxkRGVzYyhwbHVnaW4ua2V5LCBwbHVnaW4uc3BlYy5zdGF0ZSwgcGx1Z2luKSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG59XG4vKipcblRoZSBzdGF0ZSBvZiBhIFByb3NlTWlycm9yIGVkaXRvciBpcyByZXByZXNlbnRlZCBieSBhbiBvYmplY3Qgb2ZcbnRoaXMgdHlwZS4gQSBzdGF0ZSBpcyBhIHBlcnNpc3RlbnQgZGF0YSBzdHJ1Y3R1cmVcdTIwMTRpdCBpc24ndFxudXBkYXRlZCwgYnV0IHJhdGhlciBhIG5ldyBzdGF0ZSB2YWx1ZSBpcyBjb21wdXRlZCBmcm9tIGFuIG9sZCBvbmVcbnVzaW5nIHRoZSBbYGFwcGx5YF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3N0YXRlLkVkaXRvclN0YXRlLmFwcGx5KSBtZXRob2QuXG5cbkEgc3RhdGUgaG9sZHMgYSBudW1iZXIgb2YgYnVpbHQtaW4gZmllbGRzLCBhbmQgcGx1Z2lucyBjYW5cbltkZWZpbmVdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNzdGF0ZS5QbHVnaW5TcGVjLnN0YXRlKSBhZGRpdGlvbmFsIGZpZWxkcy5cbiovXG5jbGFzcyBFZGl0b3JTdGF0ZSB7XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGNvbmZpZykge1xuICAgICAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgICB9XG4gICAgLyoqXG4gICAgVGhlIHNjaGVtYSBvZiB0aGUgc3RhdGUncyBkb2N1bWVudC5cbiAgICAqL1xuICAgIGdldCBzY2hlbWEoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5zY2hlbWE7XG4gICAgfVxuICAgIC8qKlxuICAgIFRoZSBwbHVnaW5zIHRoYXQgYXJlIGFjdGl2ZSBpbiB0aGlzIHN0YXRlLlxuICAgICovXG4gICAgZ2V0IHBsdWdpbnMoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5wbHVnaW5zO1xuICAgIH1cbiAgICAvKipcbiAgICBBcHBseSB0aGUgZ2l2ZW4gdHJhbnNhY3Rpb24gdG8gcHJvZHVjZSBhIG5ldyBzdGF0ZS5cbiAgICAqL1xuICAgIGFwcGx5KHRyKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmFwcGx5VHJhbnNhY3Rpb24odHIpLnN0YXRlO1xuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGZpbHRlclRyYW5zYWN0aW9uKHRyLCBpZ25vcmUgPSAtMSkge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuY29uZmlnLnBsdWdpbnMubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICBpZiAoaSAhPSBpZ25vcmUpIHtcbiAgICAgICAgICAgICAgICBsZXQgcGx1Z2luID0gdGhpcy5jb25maWcucGx1Z2luc1tpXTtcbiAgICAgICAgICAgICAgICBpZiAocGx1Z2luLnNwZWMuZmlsdGVyVHJhbnNhY3Rpb24gJiYgIXBsdWdpbi5zcGVjLmZpbHRlclRyYW5zYWN0aW9uLmNhbGwocGx1Z2luLCB0ciwgdGhpcykpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIC8qKlxuICAgIFZlcmJvc2UgdmFyaWFudCBvZiBbYGFwcGx5YF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3N0YXRlLkVkaXRvclN0YXRlLmFwcGx5KSB0aGF0XG4gICAgcmV0dXJucyB0aGUgcHJlY2lzZSB0cmFuc2FjdGlvbnMgdGhhdCB3ZXJlIGFwcGxpZWQgKHdoaWNoIG1pZ2h0XG4gICAgYmUgaW5mbHVlbmNlZCBieSB0aGUgW3RyYW5zYWN0aW9uXG4gICAgaG9va3NdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNzdGF0ZS5QbHVnaW5TcGVjLmZpbHRlclRyYW5zYWN0aW9uKSBvZlxuICAgIHBsdWdpbnMpIGFsb25nIHdpdGggdGhlIG5ldyBzdGF0ZS5cbiAgICAqL1xuICAgIGFwcGx5VHJhbnNhY3Rpb24ocm9vdFRyKSB7XG4gICAgICAgIGlmICghdGhpcy5maWx0ZXJUcmFuc2FjdGlvbihyb290VHIpKVxuICAgICAgICAgICAgcmV0dXJuIHsgc3RhdGU6IHRoaXMsIHRyYW5zYWN0aW9uczogW10gfTtcbiAgICAgICAgbGV0IHRycyA9IFtyb290VHJdLCBuZXdTdGF0ZSA9IHRoaXMuYXBwbHlJbm5lcihyb290VHIpLCBzZWVuID0gbnVsbDtcbiAgICAgICAgLy8gVGhpcyBsb29wIHJlcGVhdGVkbHkgZ2l2ZXMgcGx1Z2lucyBhIGNoYW5jZSB0byByZXNwb25kIHRvXG4gICAgICAgIC8vIHRyYW5zYWN0aW9ucyBhcyBuZXcgdHJhbnNhY3Rpb25zIGFyZSBhZGRlZCwgbWFraW5nIHN1cmUgdG8gb25seVxuICAgICAgICAvLyBwYXNzIHRoZSB0cmFuc2FjdGlvbnMgdGhlIHBsdWdpbiBkaWQgbm90IHNlZSBiZWZvcmUuXG4gICAgICAgIGZvciAoOzspIHtcbiAgICAgICAgICAgIGxldCBoYXZlTmV3ID0gZmFsc2U7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuY29uZmlnLnBsdWdpbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBsZXQgcGx1Z2luID0gdGhpcy5jb25maWcucGx1Z2luc1tpXTtcbiAgICAgICAgICAgICAgICBpZiAocGx1Z2luLnNwZWMuYXBwZW5kVHJhbnNhY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG4gPSBzZWVuID8gc2VlbltpXS5uIDogMCwgb2xkU3RhdGUgPSBzZWVuID8gc2VlbltpXS5zdGF0ZSA6IHRoaXM7XG4gICAgICAgICAgICAgICAgICAgIGxldCB0ciA9IG4gPCB0cnMubGVuZ3RoICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBwbHVnaW4uc3BlYy5hcHBlbmRUcmFuc2FjdGlvbi5jYWxsKHBsdWdpbiwgbiA/IHRycy5zbGljZShuKSA6IHRycywgb2xkU3RhdGUsIG5ld1N0YXRlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRyICYmIG5ld1N0YXRlLmZpbHRlclRyYW5zYWN0aW9uKHRyLCBpKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHIuc2V0TWV0YShcImFwcGVuZGVkVHJhbnNhY3Rpb25cIiwgcm9vdFRyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghc2Vlbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZW4gPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRoaXMuY29uZmlnLnBsdWdpbnMubGVuZ3RoOyBqKyspXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZW4ucHVzaChqIDwgaSA/IHsgc3RhdGU6IG5ld1N0YXRlLCBuOiB0cnMubGVuZ3RoIH0gOiB7IHN0YXRlOiB0aGlzLCBuOiAwIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgdHJzLnB1c2godHIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV3U3RhdGUgPSBuZXdTdGF0ZS5hcHBseUlubmVyKHRyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGhhdmVOZXcgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWVuKVxuICAgICAgICAgICAgICAgICAgICAgICAgc2VlbltpXSA9IHsgc3RhdGU6IG5ld1N0YXRlLCBuOiB0cnMubGVuZ3RoIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFoYXZlTmV3KVxuICAgICAgICAgICAgICAgIHJldHVybiB7IHN0YXRlOiBuZXdTdGF0ZSwgdHJhbnNhY3Rpb25zOiB0cnMgfTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGFwcGx5SW5uZXIodHIpIHtcbiAgICAgICAgaWYgKCF0ci5iZWZvcmUuZXEodGhpcy5kb2MpKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJBcHBseWluZyBhIG1pc21hdGNoZWQgdHJhbnNhY3Rpb25cIik7XG4gICAgICAgIGxldCBuZXdJbnN0YW5jZSA9IG5ldyBFZGl0b3JTdGF0ZSh0aGlzLmNvbmZpZyksIGZpZWxkcyA9IHRoaXMuY29uZmlnLmZpZWxkcztcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmaWVsZHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBmaWVsZCA9IGZpZWxkc1tpXTtcbiAgICAgICAgICAgIG5ld0luc3RhbmNlW2ZpZWxkLm5hbWVdID0gZmllbGQuYXBwbHkodHIsIHRoaXNbZmllbGQubmFtZV0sIHRoaXMsIG5ld0luc3RhbmNlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3SW5zdGFuY2U7XG4gICAgfVxuICAgIC8qKlxuICAgIFN0YXJ0IGEgW3RyYW5zYWN0aW9uXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jc3RhdGUuVHJhbnNhY3Rpb24pIGZyb20gdGhpcyBzdGF0ZS5cbiAgICAqL1xuICAgIGdldCB0cigpIHsgcmV0dXJuIG5ldyBUcmFuc2FjdGlvbih0aGlzKTsgfVxuICAgIC8qKlxuICAgIENyZWF0ZSBhIG5ldyBzdGF0ZS5cbiAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGUoY29uZmlnKSB7XG4gICAgICAgIGxldCAkY29uZmlnID0gbmV3IENvbmZpZ3VyYXRpb24oY29uZmlnLmRvYyA/IGNvbmZpZy5kb2MudHlwZS5zY2hlbWEgOiBjb25maWcuc2NoZW1hLCBjb25maWcucGx1Z2lucyk7XG4gICAgICAgIGxldCBpbnN0YW5jZSA9IG5ldyBFZGl0b3JTdGF0ZSgkY29uZmlnKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCAkY29uZmlnLmZpZWxkcy5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIGluc3RhbmNlWyRjb25maWcuZmllbGRzW2ldLm5hbWVdID0gJGNvbmZpZy5maWVsZHNbaV0uaW5pdChjb25maWcsIGluc3RhbmNlKTtcbiAgICAgICAgcmV0dXJuIGluc3RhbmNlO1xuICAgIH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSBuZXcgc3RhdGUgYmFzZWQgb24gdGhpcyBvbmUsIGJ1dCB3aXRoIGFuIGFkanVzdGVkIHNldFxuICAgIG9mIGFjdGl2ZSBwbHVnaW5zLiBTdGF0ZSBmaWVsZHMgdGhhdCBleGlzdCBpbiBib3RoIHNldHMgb2ZcbiAgICBwbHVnaW5zIGFyZSBrZXB0IHVuY2hhbmdlZC4gVGhvc2UgdGhhdCBubyBsb25nZXIgZXhpc3QgYXJlXG4gICAgZHJvcHBlZCwgYW5kIHRob3NlIHRoYXQgYXJlIG5ldyBhcmUgaW5pdGlhbGl6ZWQgdXNpbmcgdGhlaXJcbiAgICBbYGluaXRgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jc3RhdGUuU3RhdGVGaWVsZC5pbml0KSBtZXRob2QsIHBhc3NpbmcgaW4gdGhlIG5ld1xuICAgIGNvbmZpZ3VyYXRpb24gb2JqZWN0Li5cbiAgICAqL1xuICAgIHJlY29uZmlndXJlKGNvbmZpZykge1xuICAgICAgICBsZXQgJGNvbmZpZyA9IG5ldyBDb25maWd1cmF0aW9uKHRoaXMuc2NoZW1hLCBjb25maWcucGx1Z2lucyk7XG4gICAgICAgIGxldCBmaWVsZHMgPSAkY29uZmlnLmZpZWxkcywgaW5zdGFuY2UgPSBuZXcgRWRpdG9yU3RhdGUoJGNvbmZpZyk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZmllbGRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgbmFtZSA9IGZpZWxkc1tpXS5uYW1lO1xuICAgICAgICAgICAgaW5zdGFuY2VbbmFtZV0gPSB0aGlzLmhhc093blByb3BlcnR5KG5hbWUpID8gdGhpc1tuYW1lXSA6IGZpZWxkc1tpXS5pbml0KGNvbmZpZywgaW5zdGFuY2UpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpbnN0YW5jZTtcbiAgICB9XG4gICAgLyoqXG4gICAgU2VyaWFsaXplIHRoaXMgc3RhdGUgdG8gSlNPTi4gSWYgeW91IHdhbnQgdG8gc2VyaWFsaXplIHRoZSBzdGF0ZVxuICAgIG9mIHBsdWdpbnMsIHBhc3MgYW4gb2JqZWN0IG1hcHBpbmcgcHJvcGVydHkgbmFtZXMgdG8gdXNlIGluIHRoZVxuICAgIHJlc3VsdGluZyBKU09OIG9iamVjdCB0byBwbHVnaW4gb2JqZWN0cy4gVGhlIGFyZ3VtZW50IG1heSBhbHNvIGJlXG4gICAgYSBzdHJpbmcgb3IgbnVtYmVyLCBpbiB3aGljaCBjYXNlIGl0IGlzIGlnbm9yZWQsIHRvIHN1cHBvcnQgdGhlXG4gICAgd2F5IGBKU09OLnN0cmluZ2lmeWAgY2FsbHMgYHRvU3RyaW5nYCBtZXRob2RzLlxuICAgICovXG4gICAgdG9KU09OKHBsdWdpbkZpZWxkcykge1xuICAgICAgICBsZXQgcmVzdWx0ID0geyBkb2M6IHRoaXMuZG9jLnRvSlNPTigpLCBzZWxlY3Rpb246IHRoaXMuc2VsZWN0aW9uLnRvSlNPTigpIH07XG4gICAgICAgIGlmICh0aGlzLnN0b3JlZE1hcmtzKVxuICAgICAgICAgICAgcmVzdWx0LnN0b3JlZE1hcmtzID0gdGhpcy5zdG9yZWRNYXJrcy5tYXAobSA9PiBtLnRvSlNPTigpKTtcbiAgICAgICAgaWYgKHBsdWdpbkZpZWxkcyAmJiB0eXBlb2YgcGx1Z2luRmllbGRzID09ICdvYmplY3QnKVxuICAgICAgICAgICAgZm9yIChsZXQgcHJvcCBpbiBwbHVnaW5GaWVsZHMpIHtcbiAgICAgICAgICAgICAgICBpZiAocHJvcCA9PSBcImRvY1wiIHx8IHByb3AgPT0gXCJzZWxlY3Rpb25cIilcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJUaGUgSlNPTiBmaWVsZHMgYGRvY2AgYW5kIGBzZWxlY3Rpb25gIGFyZSByZXNlcnZlZFwiKTtcbiAgICAgICAgICAgICAgICBsZXQgcGx1Z2luID0gcGx1Z2luRmllbGRzW3Byb3BdLCBzdGF0ZSA9IHBsdWdpbi5zcGVjLnN0YXRlO1xuICAgICAgICAgICAgICAgIGlmIChzdGF0ZSAmJiBzdGF0ZS50b0pTT04pXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdFtwcm9wXSA9IHN0YXRlLnRvSlNPTi5jYWxsKHBsdWdpbiwgdGhpc1twbHVnaW4ua2V5XSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICAgIC8qKlxuICAgIERlc2VyaWFsaXplIGEgSlNPTiByZXByZXNlbnRhdGlvbiBvZiBhIHN0YXRlLiBgY29uZmlnYCBzaG91bGRcbiAgICBoYXZlIGF0IGxlYXN0IGEgYHNjaGVtYWAgZmllbGQsIGFuZCBzaG91bGQgY29udGFpbiBhcnJheSBvZlxuICAgIHBsdWdpbnMgdG8gaW5pdGlhbGl6ZSB0aGUgc3RhdGUgd2l0aC4gYHBsdWdpbkZpZWxkc2AgY2FuIGJlIHVzZWRcbiAgICB0byBkZXNlcmlhbGl6ZSB0aGUgc3RhdGUgb2YgcGx1Z2lucywgYnkgYXNzb2NpYXRpbmcgcGx1Z2luXG4gICAgaW5zdGFuY2VzIHdpdGggdGhlIHByb3BlcnR5IG5hbWVzIHRoZXkgdXNlIGluIHRoZSBKU09OIG9iamVjdC5cbiAgICAqL1xuICAgIHN0YXRpYyBmcm9tSlNPTihjb25maWcsIGpzb24sIHBsdWdpbkZpZWxkcykge1xuICAgICAgICBpZiAoIWpzb24pXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIkludmFsaWQgaW5wdXQgZm9yIEVkaXRvclN0YXRlLmZyb21KU09OXCIpO1xuICAgICAgICBpZiAoIWNvbmZpZy5zY2hlbWEpXG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIlJlcXVpcmVkIGNvbmZpZyBmaWVsZCAnc2NoZW1hJyBtaXNzaW5nXCIpO1xuICAgICAgICBsZXQgJGNvbmZpZyA9IG5ldyBDb25maWd1cmF0aW9uKGNvbmZpZy5zY2hlbWEsIGNvbmZpZy5wbHVnaW5zKTtcbiAgICAgICAgbGV0IGluc3RhbmNlID0gbmV3IEVkaXRvclN0YXRlKCRjb25maWcpO1xuICAgICAgICAkY29uZmlnLmZpZWxkcy5mb3JFYWNoKGZpZWxkID0+IHtcbiAgICAgICAgICAgIGlmIChmaWVsZC5uYW1lID09IFwiZG9jXCIpIHtcbiAgICAgICAgICAgICAgICBpbnN0YW5jZS5kb2MgPSBOb2RlLmZyb21KU09OKGNvbmZpZy5zY2hlbWEsIGpzb24uZG9jKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGZpZWxkLm5hbWUgPT0gXCJzZWxlY3Rpb25cIikge1xuICAgICAgICAgICAgICAgIGluc3RhbmNlLnNlbGVjdGlvbiA9IFNlbGVjdGlvbi5mcm9tSlNPTihpbnN0YW5jZS5kb2MsIGpzb24uc2VsZWN0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGZpZWxkLm5hbWUgPT0gXCJzdG9yZWRNYXJrc1wiKSB7XG4gICAgICAgICAgICAgICAgaWYgKGpzb24uc3RvcmVkTWFya3MpXG4gICAgICAgICAgICAgICAgICAgIGluc3RhbmNlLnN0b3JlZE1hcmtzID0ganNvbi5zdG9yZWRNYXJrcy5tYXAoY29uZmlnLnNjaGVtYS5tYXJrRnJvbUpTT04pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKHBsdWdpbkZpZWxkcylcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgcHJvcCBpbiBwbHVnaW5GaWVsZHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBwbHVnaW4gPSBwbHVnaW5GaWVsZHNbcHJvcF0sIHN0YXRlID0gcGx1Z2luLnNwZWMuc3RhdGU7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocGx1Z2luLmtleSA9PSBmaWVsZC5uYW1lICYmIHN0YXRlICYmIHN0YXRlLmZyb21KU09OICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGpzb24sIHByb3ApKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFuY2VbZmllbGQubmFtZV0gPSBzdGF0ZS5mcm9tSlNPTi5jYWxsKHBsdWdpbiwgY29uZmlnLCBqc29uW3Byb3BdLCBpbnN0YW5jZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaW5zdGFuY2VbZmllbGQubmFtZV0gPSBmaWVsZC5pbml0KGNvbmZpZywgaW5zdGFuY2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGluc3RhbmNlO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gYmluZFByb3BzKG9iaiwgc2VsZiwgdGFyZ2V0KSB7XG4gICAgZm9yIChsZXQgcHJvcCBpbiBvYmopIHtcbiAgICAgICAgbGV0IHZhbCA9IG9ialtwcm9wXTtcbiAgICAgICAgaWYgKHZhbCBpbnN0YW5jZW9mIEZ1bmN0aW9uKVxuICAgICAgICAgICAgdmFsID0gdmFsLmJpbmQoc2VsZik7XG4gICAgICAgIGVsc2UgaWYgKHByb3AgPT0gXCJoYW5kbGVET01FdmVudHNcIilcbiAgICAgICAgICAgIHZhbCA9IGJpbmRQcm9wcyh2YWwsIHNlbGYsIHt9KTtcbiAgICAgICAgdGFyZ2V0W3Byb3BdID0gdmFsO1xuICAgIH1cbiAgICByZXR1cm4gdGFyZ2V0O1xufVxuLyoqXG5QbHVnaW5zIGJ1bmRsZSBmdW5jdGlvbmFsaXR5IHRoYXQgY2FuIGJlIGFkZGVkIHRvIGFuIGVkaXRvci5cblRoZXkgYXJlIHBhcnQgb2YgdGhlIFtlZGl0b3Igc3RhdGVdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNzdGF0ZS5FZGl0b3JTdGF0ZSkgYW5kXG5tYXkgaW5mbHVlbmNlIHRoYXQgc3RhdGUgYW5kIHRoZSB2aWV3IHRoYXQgY29udGFpbnMgaXQuXG4qL1xuY2xhc3MgUGx1Z2luIHtcbiAgICAvKipcbiAgICBDcmVhdGUgYSBwbHVnaW4uXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBUaGUgcGx1Z2luJ3MgW3NwZWMgb2JqZWN0XShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jc3RhdGUuUGx1Z2luU3BlYykuXG4gICAgKi9cbiAgICBzcGVjKSB7XG4gICAgICAgIHRoaXMuc3BlYyA9IHNwZWM7XG4gICAgICAgIC8qKlxuICAgICAgICBUaGUgW3Byb3BzXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jdmlldy5FZGl0b3JQcm9wcykgZXhwb3J0ZWQgYnkgdGhpcyBwbHVnaW4uXG4gICAgICAgICovXG4gICAgICAgIHRoaXMucHJvcHMgPSB7fTtcbiAgICAgICAgaWYgKHNwZWMucHJvcHMpXG4gICAgICAgICAgICBiaW5kUHJvcHMoc3BlYy5wcm9wcywgdGhpcywgdGhpcy5wcm9wcyk7XG4gICAgICAgIHRoaXMua2V5ID0gc3BlYy5rZXkgPyBzcGVjLmtleS5rZXkgOiBjcmVhdGVLZXkoXCJwbHVnaW5cIik7XG4gICAgfVxuICAgIC8qKlxuICAgIEV4dHJhY3QgdGhlIHBsdWdpbidzIHN0YXRlIGZpZWxkIGZyb20gYW4gZWRpdG9yIHN0YXRlLlxuICAgICovXG4gICAgZ2V0U3RhdGUoc3RhdGUpIHsgcmV0dXJuIHN0YXRlW3RoaXMua2V5XTsgfVxufVxuY29uc3Qga2V5cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5mdW5jdGlvbiBjcmVhdGVLZXkobmFtZSkge1xuICAgIGlmIChuYW1lIGluIGtleXMpXG4gICAgICAgIHJldHVybiBuYW1lICsgXCIkXCIgKyArK2tleXNbbmFtZV07XG4gICAga2V5c1tuYW1lXSA9IDA7XG4gICAgcmV0dXJuIG5hbWUgKyBcIiRcIjtcbn1cbi8qKlxuQSBrZXkgaXMgdXNlZCB0byBbdGFnXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jc3RhdGUuUGx1Z2luU3BlYy5rZXkpIHBsdWdpbnMgaW4gYSB3YXlcbnRoYXQgbWFrZXMgaXQgcG9zc2libGUgdG8gZmluZCB0aGVtLCBnaXZlbiBhbiBlZGl0b3Igc3RhdGUuXG5Bc3NpZ25pbmcgYSBrZXkgZG9lcyBtZWFuIG9ubHkgb25lIHBsdWdpbiBvZiB0aGF0IHR5cGUgY2FuIGJlXG5hY3RpdmUgaW4gYSBzdGF0ZS5cbiovXG5jbGFzcyBQbHVnaW5LZXkge1xuICAgIC8qKlxuICAgIENyZWF0ZSBhIHBsdWdpbiBrZXkuXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihuYW1lID0gXCJrZXlcIikgeyB0aGlzLmtleSA9IGNyZWF0ZUtleShuYW1lKTsgfVxuICAgIC8qKlxuICAgIEdldCB0aGUgYWN0aXZlIHBsdWdpbiB3aXRoIHRoaXMga2V5LCBpZiBhbnksIGZyb20gYW4gZWRpdG9yXG4gICAgc3RhdGUuXG4gICAgKi9cbiAgICBnZXQoc3RhdGUpIHsgcmV0dXJuIHN0YXRlLmNvbmZpZy5wbHVnaW5zQnlLZXlbdGhpcy5rZXldOyB9XG4gICAgLyoqXG4gICAgR2V0IHRoZSBwbHVnaW4ncyBzdGF0ZSBmcm9tIGFuIGVkaXRvciBzdGF0ZS5cbiAgICAqL1xuICAgIGdldFN0YXRlKHN0YXRlKSB7IHJldHVybiBzdGF0ZVt0aGlzLmtleV07IH1cbn1cblxuZXhwb3J0IHsgQWxsU2VsZWN0aW9uLCBFZGl0b3JTdGF0ZSwgTm9kZVNlbGVjdGlvbiwgUGx1Z2luLCBQbHVnaW5LZXksIFNlbGVjdGlvbiwgU2VsZWN0aW9uUmFuZ2UsIFRleHRTZWxlY3Rpb24sIFRyYW5zYWN0aW9uIH07XG4iLCAiaW1wb3J0IHsgVGV4dFNlbGVjdGlvbiwgTm9kZVNlbGVjdGlvbiwgQWxsU2VsZWN0aW9uLCBTZWxlY3Rpb24gfSBmcm9tICdwcm9zZW1pcnJvci1zdGF0ZSc7XG5pbXBvcnQgeyBET01TZXJpYWxpemVyLCBGcmFnbWVudCwgTWFyaywgU2xpY2UsIERPTVBhcnNlciB9IGZyb20gJ3Byb3NlbWlycm9yLW1vZGVsJztcbmltcG9ydCB7IGRyb3BQb2ludCB9IGZyb20gJ3Byb3NlbWlycm9yLXRyYW5zZm9ybSc7XG5cbmNvbnN0IGRvbUluZGV4ID0gZnVuY3Rpb24gKG5vZGUpIHtcbiAgICBmb3IgKHZhciBpbmRleCA9IDA7OyBpbmRleCsrKSB7XG4gICAgICAgIG5vZGUgPSBub2RlLnByZXZpb3VzU2libGluZztcbiAgICAgICAgaWYgKCFub2RlKVxuICAgICAgICAgICAgcmV0dXJuIGluZGV4O1xuICAgIH1cbn07XG5jb25zdCBwYXJlbnROb2RlID0gZnVuY3Rpb24gKG5vZGUpIHtcbiAgICBsZXQgcGFyZW50ID0gbm9kZS5hc3NpZ25lZFNsb3QgfHwgbm9kZS5wYXJlbnROb2RlO1xuICAgIHJldHVybiBwYXJlbnQgJiYgcGFyZW50Lm5vZGVUeXBlID09IDExID8gcGFyZW50Lmhvc3QgOiBwYXJlbnQ7XG59O1xubGV0IHJldXNlZFJhbmdlID0gbnVsbDtcbi8vIE5vdGUgdGhhdCB0aGlzIHdpbGwgYWx3YXlzIHJldHVybiB0aGUgc2FtZSByYW5nZSwgYmVjYXVzZSBET00gcmFuZ2Vcbi8vIG9iamVjdHMgYXJlIGV2ZXJ5IGV4cGVuc2l2ZSwgYW5kIGtlZXAgc2xvd2luZyBkb3duIHN1YnNlcXVlbnQgRE9NXG4vLyB1cGRhdGVzLCBmb3Igc29tZSByZWFzb24uXG5jb25zdCB0ZXh0UmFuZ2UgPSBmdW5jdGlvbiAobm9kZSwgZnJvbSwgdG8pIHtcbiAgICBsZXQgcmFuZ2UgPSByZXVzZWRSYW5nZSB8fCAocmV1c2VkUmFuZ2UgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpKTtcbiAgICByYW5nZS5zZXRFbmQobm9kZSwgdG8gPT0gbnVsbCA/IG5vZGUubm9kZVZhbHVlLmxlbmd0aCA6IHRvKTtcbiAgICByYW5nZS5zZXRTdGFydChub2RlLCBmcm9tIHx8IDApO1xuICAgIHJldHVybiByYW5nZTtcbn07XG5jb25zdCBjbGVhclJldXNlZFJhbmdlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldXNlZFJhbmdlID0gbnVsbDtcbn07XG4vLyBTY2FucyBmb3J3YXJkIGFuZCBiYWNrd2FyZCB0aHJvdWdoIERPTSBwb3NpdGlvbnMgZXF1aXZhbGVudCB0byB0aGVcbi8vIGdpdmVuIG9uZSB0byBzZWUgaWYgdGhlIHR3byBhcmUgaW4gdGhlIHNhbWUgcGxhY2UgKGkuZS4gYWZ0ZXIgYVxuLy8gdGV4dCBub2RlIHZzIGF0IHRoZSBlbmQgb2YgdGhhdCB0ZXh0IG5vZGUpXG5jb25zdCBpc0VxdWl2YWxlbnRQb3NpdGlvbiA9IGZ1bmN0aW9uIChub2RlLCBvZmYsIHRhcmdldE5vZGUsIHRhcmdldE9mZikge1xuICAgIHJldHVybiB0YXJnZXROb2RlICYmIChzY2FuRm9yKG5vZGUsIG9mZiwgdGFyZ2V0Tm9kZSwgdGFyZ2V0T2ZmLCAtMSkgfHxcbiAgICAgICAgc2NhbkZvcihub2RlLCBvZmYsIHRhcmdldE5vZGUsIHRhcmdldE9mZiwgMSkpO1xufTtcbmNvbnN0IGF0b21FbGVtZW50cyA9IC9eKGltZ3xicnxpbnB1dHx0ZXh0YXJlYXxocikkL2k7XG5mdW5jdGlvbiBzY2FuRm9yKG5vZGUsIG9mZiwgdGFyZ2V0Tm9kZSwgdGFyZ2V0T2ZmLCBkaXIpIHtcbiAgICBmb3IgKDs7KSB7XG4gICAgICAgIGlmIChub2RlID09IHRhcmdldE5vZGUgJiYgb2ZmID09IHRhcmdldE9mZilcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICBpZiAob2ZmID09IChkaXIgPCAwID8gMCA6IG5vZGVTaXplKG5vZGUpKSkge1xuICAgICAgICAgICAgbGV0IHBhcmVudCA9IG5vZGUucGFyZW50Tm9kZTtcbiAgICAgICAgICAgIGlmICghcGFyZW50IHx8IHBhcmVudC5ub2RlVHlwZSAhPSAxIHx8IGhhc0Jsb2NrRGVzYyhub2RlKSB8fCBhdG9tRWxlbWVudHMudGVzdChub2RlLm5vZGVOYW1lKSB8fFxuICAgICAgICAgICAgICAgIG5vZGUuY29udGVudEVkaXRhYmxlID09IFwiZmFsc2VcIilcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICBvZmYgPSBkb21JbmRleChub2RlKSArIChkaXIgPCAwID8gMCA6IDEpO1xuICAgICAgICAgICAgbm9kZSA9IHBhcmVudDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChub2RlLm5vZGVUeXBlID09IDEpIHtcbiAgICAgICAgICAgIG5vZGUgPSBub2RlLmNoaWxkTm9kZXNbb2ZmICsgKGRpciA8IDAgPyAtMSA6IDApXTtcbiAgICAgICAgICAgIGlmIChub2RlLmNvbnRlbnRFZGl0YWJsZSA9PSBcImZhbHNlXCIpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgb2ZmID0gZGlyIDwgMCA/IG5vZGVTaXplKG5vZGUpIDogMDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmZ1bmN0aW9uIG5vZGVTaXplKG5vZGUpIHtcbiAgICByZXR1cm4gbm9kZS5ub2RlVHlwZSA9PSAzID8gbm9kZS5ub2RlVmFsdWUubGVuZ3RoIDogbm9kZS5jaGlsZE5vZGVzLmxlbmd0aDtcbn1cbmZ1bmN0aW9uIHRleHROb2RlQmVmb3JlJDEobm9kZSwgb2Zmc2V0KSB7XG4gICAgZm9yICg7Oykge1xuICAgICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PSAzICYmIG9mZnNldClcbiAgICAgICAgICAgIHJldHVybiBub2RlO1xuICAgICAgICBpZiAobm9kZS5ub2RlVHlwZSA9PSAxICYmIG9mZnNldCA+IDApIHtcbiAgICAgICAgICAgIGlmIChub2RlLmNvbnRlbnRFZGl0YWJsZSA9PSBcImZhbHNlXCIpXG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICBub2RlID0gbm9kZS5jaGlsZE5vZGVzW29mZnNldCAtIDFdO1xuICAgICAgICAgICAgb2Zmc2V0ID0gbm9kZVNpemUobm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAobm9kZS5wYXJlbnROb2RlICYmICFoYXNCbG9ja0Rlc2Mobm9kZSkpIHtcbiAgICAgICAgICAgIG9mZnNldCA9IGRvbUluZGV4KG5vZGUpO1xuICAgICAgICAgICAgbm9kZSA9IG5vZGUucGFyZW50Tm9kZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gdGV4dE5vZGVBZnRlciQxKG5vZGUsIG9mZnNldCkge1xuICAgIGZvciAoOzspIHtcbiAgICAgICAgaWYgKG5vZGUubm9kZVR5cGUgPT0gMyAmJiBvZmZzZXQgPCBub2RlLm5vZGVWYWx1ZS5sZW5ndGgpXG4gICAgICAgICAgICByZXR1cm4gbm9kZTtcbiAgICAgICAgaWYgKG5vZGUubm9kZVR5cGUgPT0gMSAmJiBvZmZzZXQgPCBub2RlLmNoaWxkTm9kZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICBpZiAobm9kZS5jb250ZW50RWRpdGFibGUgPT0gXCJmYWxzZVwiKVxuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgbm9kZSA9IG5vZGUuY2hpbGROb2Rlc1tvZmZzZXRdO1xuICAgICAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChub2RlLnBhcmVudE5vZGUgJiYgIWhhc0Jsb2NrRGVzYyhub2RlKSkge1xuICAgICAgICAgICAgb2Zmc2V0ID0gZG9tSW5kZXgobm9kZSkgKyAxO1xuICAgICAgICAgICAgbm9kZSA9IG5vZGUucGFyZW50Tm9kZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gaXNPbkVkZ2Uobm9kZSwgb2Zmc2V0LCBwYXJlbnQpIHtcbiAgICBmb3IgKGxldCBhdFN0YXJ0ID0gb2Zmc2V0ID09IDAsIGF0RW5kID0gb2Zmc2V0ID09IG5vZGVTaXplKG5vZGUpOyBhdFN0YXJ0IHx8IGF0RW5kOykge1xuICAgICAgICBpZiAobm9kZSA9PSBwYXJlbnQpXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgbGV0IGluZGV4ID0gZG9tSW5kZXgobm9kZSk7XG4gICAgICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGU7XG4gICAgICAgIGlmICghbm9kZSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgYXRTdGFydCA9IGF0U3RhcnQgJiYgaW5kZXggPT0gMDtcbiAgICAgICAgYXRFbmQgPSBhdEVuZCAmJiBpbmRleCA9PSBub2RlU2l6ZShub2RlKTtcbiAgICB9XG59XG5mdW5jdGlvbiBoYXNCbG9ja0Rlc2MoZG9tKSB7XG4gICAgbGV0IGRlc2M7XG4gICAgZm9yIChsZXQgY3VyID0gZG9tOyBjdXI7IGN1ciA9IGN1ci5wYXJlbnROb2RlKVxuICAgICAgICBpZiAoZGVzYyA9IGN1ci5wbVZpZXdEZXNjKVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgcmV0dXJuIGRlc2MgJiYgZGVzYy5ub2RlICYmIGRlc2Mubm9kZS5pc0Jsb2NrICYmIChkZXNjLmRvbSA9PSBkb20gfHwgZGVzYy5jb250ZW50RE9NID09IGRvbSk7XG59XG4vLyBXb3JrIGFyb3VuZCBDaHJvbWUgaXNzdWUgaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9NDQ3NTIzXG4vLyAoaXNDb2xsYXBzZWQgaW5hcHByb3ByaWF0ZWx5IHJldHVybnMgdHJ1ZSBpbiBzaGFkb3cgZG9tKVxuY29uc3Qgc2VsZWN0aW9uQ29sbGFwc2VkID0gZnVuY3Rpb24gKGRvbVNlbCkge1xuICAgIHJldHVybiBkb21TZWwuZm9jdXNOb2RlICYmIGlzRXF1aXZhbGVudFBvc2l0aW9uKGRvbVNlbC5mb2N1c05vZGUsIGRvbVNlbC5mb2N1c09mZnNldCwgZG9tU2VsLmFuY2hvck5vZGUsIGRvbVNlbC5hbmNob3JPZmZzZXQpO1xufTtcbmZ1bmN0aW9uIGtleUV2ZW50KGtleUNvZGUsIGtleSkge1xuICAgIGxldCBldmVudCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KFwiRXZlbnRcIik7XG4gICAgZXZlbnQuaW5pdEV2ZW50KFwia2V5ZG93blwiLCB0cnVlLCB0cnVlKTtcbiAgICBldmVudC5rZXlDb2RlID0ga2V5Q29kZTtcbiAgICBldmVudC5rZXkgPSBldmVudC5jb2RlID0ga2V5O1xuICAgIHJldHVybiBldmVudDtcbn1cbmZ1bmN0aW9uIGRlZXBBY3RpdmVFbGVtZW50KGRvYykge1xuICAgIGxldCBlbHQgPSBkb2MuYWN0aXZlRWxlbWVudDtcbiAgICB3aGlsZSAoZWx0ICYmIGVsdC5zaGFkb3dSb290KVxuICAgICAgICBlbHQgPSBlbHQuc2hhZG93Um9vdC5hY3RpdmVFbGVtZW50O1xuICAgIHJldHVybiBlbHQ7XG59XG5mdW5jdGlvbiBjYXJldEZyb21Qb2ludChkb2MsIHgsIHkpIHtcbiAgICBpZiAoZG9jLmNhcmV0UG9zaXRpb25Gcm9tUG9pbnQpIHtcbiAgICAgICAgdHJ5IHsgLy8gRmlyZWZveCB0aHJvd3MgZm9yIHRoaXMgY2FsbCBpbiBoYXJkLXRvLXByZWRpY3QgY2lyY3Vtc3RhbmNlcyAoIzk5NClcbiAgICAgICAgICAgIGxldCBwb3MgPSBkb2MuY2FyZXRQb3NpdGlvbkZyb21Qb2ludCh4LCB5KTtcbiAgICAgICAgICAgIC8vIENsaXAgdGhlIG9mZnNldCwgYmVjYXVzZSBDaHJvbWUgd2lsbCByZXR1cm4gYSB0ZXh0IG9mZnNldFxuICAgICAgICAgICAgLy8gaW50byA8aW5wdXQ+IG5vZGVzLCB3aGljaCBjYW4ndCBiZSB0cmVhdGVkIGFzIGEgcmVndWxhciBET01cbiAgICAgICAgICAgIC8vIG9mZnNldFxuICAgICAgICAgICAgaWYgKHBvcylcbiAgICAgICAgICAgICAgICByZXR1cm4geyBub2RlOiBwb3Mub2Zmc2V0Tm9kZSwgb2Zmc2V0OiBNYXRoLm1pbihub2RlU2l6ZShwb3Mub2Zmc2V0Tm9kZSksIHBvcy5vZmZzZXQpIH07XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKF8pIHsgfVxuICAgIH1cbiAgICBpZiAoZG9jLmNhcmV0UmFuZ2VGcm9tUG9pbnQpIHtcbiAgICAgICAgbGV0IHJhbmdlID0gZG9jLmNhcmV0UmFuZ2VGcm9tUG9pbnQoeCwgeSk7XG4gICAgICAgIGlmIChyYW5nZSlcbiAgICAgICAgICAgIHJldHVybiB7IG5vZGU6IHJhbmdlLnN0YXJ0Q29udGFpbmVyLCBvZmZzZXQ6IE1hdGgubWluKG5vZGVTaXplKHJhbmdlLnN0YXJ0Q29udGFpbmVyKSwgcmFuZ2Uuc3RhcnRPZmZzZXQpIH07XG4gICAgfVxufVxuXG5jb25zdCBuYXYgPSB0eXBlb2YgbmF2aWdhdG9yICE9IFwidW5kZWZpbmVkXCIgPyBuYXZpZ2F0b3IgOiBudWxsO1xuY29uc3QgZG9jID0gdHlwZW9mIGRvY3VtZW50ICE9IFwidW5kZWZpbmVkXCIgPyBkb2N1bWVudCA6IG51bGw7XG5jb25zdCBhZ2VudCA9IChuYXYgJiYgbmF2LnVzZXJBZ2VudCkgfHwgXCJcIjtcbmNvbnN0IGllX2VkZ2UgPSAvRWRnZVxcLyhcXGQrKS8uZXhlYyhhZ2VudCk7XG5jb25zdCBpZV91cHRvMTAgPSAvTVNJRSBcXGQvLmV4ZWMoYWdlbnQpO1xuY29uc3QgaWVfMTF1cCA9IC9UcmlkZW50XFwvKD86WzctOV18XFxkezIsfSlcXC4uKnJ2OihcXGQrKS8uZXhlYyhhZ2VudCk7XG5jb25zdCBpZSA9ICEhKGllX3VwdG8xMCB8fCBpZV8xMXVwIHx8IGllX2VkZ2UpO1xuY29uc3QgaWVfdmVyc2lvbiA9IGllX3VwdG8xMCA/IGRvY3VtZW50LmRvY3VtZW50TW9kZSA6IGllXzExdXAgPyAraWVfMTF1cFsxXSA6IGllX2VkZ2UgPyAraWVfZWRnZVsxXSA6IDA7XG5jb25zdCBnZWNrbyA9ICFpZSAmJiAvZ2Vja29cXC8oXFxkKykvaS50ZXN0KGFnZW50KTtcbmdlY2tvICYmICsoL0ZpcmVmb3hcXC8oXFxkKykvLmV4ZWMoYWdlbnQpIHx8IFswLCAwXSlbMV07XG5jb25zdCBfY2hyb21lID0gIWllICYmIC9DaHJvbWVcXC8oXFxkKykvLmV4ZWMoYWdlbnQpO1xuY29uc3QgY2hyb21lID0gISFfY2hyb21lO1xuY29uc3QgY2hyb21lX3ZlcnNpb24gPSBfY2hyb21lID8gK19jaHJvbWVbMV0gOiAwO1xuY29uc3Qgc2FmYXJpID0gIWllICYmICEhbmF2ICYmIC9BcHBsZSBDb21wdXRlci8udGVzdChuYXYudmVuZG9yKTtcbi8vIElzIHRydWUgZm9yIGJvdGggaU9TIGFuZCBpUGFkT1MgZm9yIGNvbnZlbmllbmNlXG5jb25zdCBpb3MgPSBzYWZhcmkgJiYgKC9Nb2JpbGVcXC9cXHcrLy50ZXN0KGFnZW50KSB8fCAhIW5hdiAmJiBuYXYubWF4VG91Y2hQb2ludHMgPiAyKTtcbmNvbnN0IG1hYyA9IGlvcyB8fCAobmF2ID8gL01hYy8udGVzdChuYXYucGxhdGZvcm0pIDogZmFsc2UpO1xuY29uc3Qgd2luZG93cyA9IG5hdiA/IC9XaW4vLnRlc3QobmF2LnBsYXRmb3JtKSA6IGZhbHNlO1xuY29uc3QgYW5kcm9pZCA9IC9BbmRyb2lkIFxcZC8udGVzdChhZ2VudCk7XG5jb25zdCB3ZWJraXQgPSAhIWRvYyAmJiBcIndlYmtpdEZvbnRTbW9vdGhpbmdcIiBpbiBkb2MuZG9jdW1lbnRFbGVtZW50LnN0eWxlO1xuY29uc3Qgd2Via2l0X3ZlcnNpb24gPSB3ZWJraXQgPyArKC9cXGJBcHBsZVdlYktpdFxcLyhcXGQrKS8uZXhlYyhuYXZpZ2F0b3IudXNlckFnZW50KSB8fCBbMCwgMF0pWzFdIDogMDtcblxuZnVuY3Rpb24gd2luZG93UmVjdChkb2MpIHtcbiAgICBsZXQgdnAgPSBkb2MuZGVmYXVsdFZpZXcgJiYgZG9jLmRlZmF1bHRWaWV3LnZpc3VhbFZpZXdwb3J0O1xuICAgIGlmICh2cClcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGxlZnQ6IDAsIHJpZ2h0OiB2cC53aWR0aCxcbiAgICAgICAgICAgIHRvcDogMCwgYm90dG9tOiB2cC5oZWlnaHRcbiAgICAgICAgfTtcbiAgICByZXR1cm4geyBsZWZ0OiAwLCByaWdodDogZG9jLmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aCxcbiAgICAgICAgdG9wOiAwLCBib3R0b206IGRvYy5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0IH07XG59XG5mdW5jdGlvbiBnZXRTaWRlKHZhbHVlLCBzaWRlKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSBcIm51bWJlclwiID8gdmFsdWUgOiB2YWx1ZVtzaWRlXTtcbn1cbmZ1bmN0aW9uIGNsaWVudFJlY3Qobm9kZSkge1xuICAgIGxldCByZWN0ID0gbm9kZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAvLyBBZGp1c3QgZm9yIGVsZW1lbnRzIHdpdGggc3R5bGUgXCJ0cmFuc2Zvcm06IHNjYWxlKClcIlxuICAgIGxldCBzY2FsZVggPSAocmVjdC53aWR0aCAvIG5vZGUub2Zmc2V0V2lkdGgpIHx8IDE7XG4gICAgbGV0IHNjYWxlWSA9IChyZWN0LmhlaWdodCAvIG5vZGUub2Zmc2V0SGVpZ2h0KSB8fCAxO1xuICAgIC8vIE1ha2Ugc3VyZSBzY3JvbGxiYXIgd2lkdGggaXNuJ3QgaW5jbHVkZWQgaW4gdGhlIHJlY3RhbmdsZVxuICAgIHJldHVybiB7IGxlZnQ6IHJlY3QubGVmdCwgcmlnaHQ6IHJlY3QubGVmdCArIG5vZGUuY2xpZW50V2lkdGggKiBzY2FsZVgsXG4gICAgICAgIHRvcDogcmVjdC50b3AsIGJvdHRvbTogcmVjdC50b3AgKyBub2RlLmNsaWVudEhlaWdodCAqIHNjYWxlWSB9O1xufVxuZnVuY3Rpb24gc2Nyb2xsUmVjdEludG9WaWV3KHZpZXcsIHJlY3QsIHN0YXJ0RE9NKSB7XG4gICAgbGV0IHNjcm9sbFRocmVzaG9sZCA9IHZpZXcuc29tZVByb3AoXCJzY3JvbGxUaHJlc2hvbGRcIikgfHwgMCwgc2Nyb2xsTWFyZ2luID0gdmlldy5zb21lUHJvcChcInNjcm9sbE1hcmdpblwiKSB8fCA1O1xuICAgIGxldCBkb2MgPSB2aWV3LmRvbS5vd25lckRvY3VtZW50O1xuICAgIGZvciAobGV0IHBhcmVudCA9IHN0YXJ0RE9NIHx8IHZpZXcuZG9tOzspIHtcbiAgICAgICAgaWYgKCFwYXJlbnQpXG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgaWYgKHBhcmVudC5ub2RlVHlwZSAhPSAxKSB7XG4gICAgICAgICAgICBwYXJlbnQgPSBwYXJlbnROb2RlKHBhcmVudCk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgZWx0ID0gcGFyZW50O1xuICAgICAgICBsZXQgYXRUb3AgPSBlbHQgPT0gZG9jLmJvZHk7XG4gICAgICAgIGxldCBib3VuZGluZyA9IGF0VG9wID8gd2luZG93UmVjdChkb2MpIDogY2xpZW50UmVjdChlbHQpO1xuICAgICAgICBsZXQgbW92ZVggPSAwLCBtb3ZlWSA9IDA7XG4gICAgICAgIGlmIChyZWN0LnRvcCA8IGJvdW5kaW5nLnRvcCArIGdldFNpZGUoc2Nyb2xsVGhyZXNob2xkLCBcInRvcFwiKSlcbiAgICAgICAgICAgIG1vdmVZID0gLShib3VuZGluZy50b3AgLSByZWN0LnRvcCArIGdldFNpZGUoc2Nyb2xsTWFyZ2luLCBcInRvcFwiKSk7XG4gICAgICAgIGVsc2UgaWYgKHJlY3QuYm90dG9tID4gYm91bmRpbmcuYm90dG9tIC0gZ2V0U2lkZShzY3JvbGxUaHJlc2hvbGQsIFwiYm90dG9tXCIpKVxuICAgICAgICAgICAgbW92ZVkgPSByZWN0LmJvdHRvbSAtIHJlY3QudG9wID4gYm91bmRpbmcuYm90dG9tIC0gYm91bmRpbmcudG9wXG4gICAgICAgICAgICAgICAgPyByZWN0LnRvcCArIGdldFNpZGUoc2Nyb2xsTWFyZ2luLCBcInRvcFwiKSAtIGJvdW5kaW5nLnRvcFxuICAgICAgICAgICAgICAgIDogcmVjdC5ib3R0b20gLSBib3VuZGluZy5ib3R0b20gKyBnZXRTaWRlKHNjcm9sbE1hcmdpbiwgXCJib3R0b21cIik7XG4gICAgICAgIGlmIChyZWN0LmxlZnQgPCBib3VuZGluZy5sZWZ0ICsgZ2V0U2lkZShzY3JvbGxUaHJlc2hvbGQsIFwibGVmdFwiKSlcbiAgICAgICAgICAgIG1vdmVYID0gLShib3VuZGluZy5sZWZ0IC0gcmVjdC5sZWZ0ICsgZ2V0U2lkZShzY3JvbGxNYXJnaW4sIFwibGVmdFwiKSk7XG4gICAgICAgIGVsc2UgaWYgKHJlY3QucmlnaHQgPiBib3VuZGluZy5yaWdodCAtIGdldFNpZGUoc2Nyb2xsVGhyZXNob2xkLCBcInJpZ2h0XCIpKVxuICAgICAgICAgICAgbW92ZVggPSByZWN0LnJpZ2h0IC0gYm91bmRpbmcucmlnaHQgKyBnZXRTaWRlKHNjcm9sbE1hcmdpbiwgXCJyaWdodFwiKTtcbiAgICAgICAgaWYgKG1vdmVYIHx8IG1vdmVZKSB7XG4gICAgICAgICAgICBpZiAoYXRUb3ApIHtcbiAgICAgICAgICAgICAgICBkb2MuZGVmYXVsdFZpZXcuc2Nyb2xsQnkobW92ZVgsIG1vdmVZKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGxldCBzdGFydFggPSBlbHQuc2Nyb2xsTGVmdCwgc3RhcnRZID0gZWx0LnNjcm9sbFRvcDtcbiAgICAgICAgICAgICAgICBpZiAobW92ZVkpXG4gICAgICAgICAgICAgICAgICAgIGVsdC5zY3JvbGxUb3AgKz0gbW92ZVk7XG4gICAgICAgICAgICAgICAgaWYgKG1vdmVYKVxuICAgICAgICAgICAgICAgICAgICBlbHQuc2Nyb2xsTGVmdCArPSBtb3ZlWDtcbiAgICAgICAgICAgICAgICBsZXQgZFggPSBlbHQuc2Nyb2xsTGVmdCAtIHN0YXJ0WCwgZFkgPSBlbHQuc2Nyb2xsVG9wIC0gc3RhcnRZO1xuICAgICAgICAgICAgICAgIHJlY3QgPSB7IGxlZnQ6IHJlY3QubGVmdCAtIGRYLCB0b3A6IHJlY3QudG9wIC0gZFksIHJpZ2h0OiByZWN0LnJpZ2h0IC0gZFgsIGJvdHRvbTogcmVjdC5ib3R0b20gLSBkWSB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxldCBwb3MgPSBhdFRvcCA/IFwiZml4ZWRcIiA6IGdldENvbXB1dGVkU3R5bGUocGFyZW50KS5wb3NpdGlvbjtcbiAgICAgICAgaWYgKC9eKGZpeGVkfHN0aWNreSkkLy50ZXN0KHBvcykpXG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgcGFyZW50ID0gcG9zID09IFwiYWJzb2x1dGVcIiA/IHBhcmVudC5vZmZzZXRQYXJlbnQgOiBwYXJlbnROb2RlKHBhcmVudCk7XG4gICAgfVxufVxuLy8gU3RvcmUgdGhlIHNjcm9sbCBwb3NpdGlvbiBvZiB0aGUgZWRpdG9yJ3MgcGFyZW50IG5vZGVzLCBhbG9uZyB3aXRoXG4vLyB0aGUgdG9wIHBvc2l0aW9uIG9mIGFuIGVsZW1lbnQgbmVhciB0aGUgdG9wIG9mIHRoZSBlZGl0b3IsIHdoaWNoXG4vLyB3aWxsIGJlIHVzZWQgdG8gbWFrZSBzdXJlIHRoZSB2aXNpYmxlIHZpZXdwb3J0IHJlbWFpbnMgc3RhYmxlIGV2ZW5cbi8vIHdoZW4gdGhlIHNpemUgb2YgdGhlIGNvbnRlbnQgYWJvdmUgY2hhbmdlcy5cbmZ1bmN0aW9uIHN0b3JlU2Nyb2xsUG9zKHZpZXcpIHtcbiAgICBsZXQgcmVjdCA9IHZpZXcuZG9tLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLCBzdGFydFkgPSBNYXRoLm1heCgwLCByZWN0LnRvcCk7XG4gICAgbGV0IHJlZkRPTSwgcmVmVG9wO1xuICAgIGZvciAobGV0IHggPSAocmVjdC5sZWZ0ICsgcmVjdC5yaWdodCkgLyAyLCB5ID0gc3RhcnRZICsgMTsgeSA8IE1hdGgubWluKGlubmVySGVpZ2h0LCByZWN0LmJvdHRvbSk7IHkgKz0gNSkge1xuICAgICAgICBsZXQgZG9tID0gdmlldy5yb290LmVsZW1lbnRGcm9tUG9pbnQoeCwgeSk7XG4gICAgICAgIGlmICghZG9tIHx8IGRvbSA9PSB2aWV3LmRvbSB8fCAhdmlldy5kb20uY29udGFpbnMoZG9tKSlcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICBsZXQgbG9jYWxSZWN0ID0gZG9tLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICBpZiAobG9jYWxSZWN0LnRvcCA+PSBzdGFydFkgLSAyMCkge1xuICAgICAgICAgICAgcmVmRE9NID0gZG9tO1xuICAgICAgICAgICAgcmVmVG9wID0gbG9jYWxSZWN0LnRvcDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7IHJlZkRPTTogcmVmRE9NLCByZWZUb3A6IHJlZlRvcCwgc3RhY2s6IHNjcm9sbFN0YWNrKHZpZXcuZG9tKSB9O1xufVxuZnVuY3Rpb24gc2Nyb2xsU3RhY2soZG9tKSB7XG4gICAgbGV0IHN0YWNrID0gW10sIGRvYyA9IGRvbS5vd25lckRvY3VtZW50O1xuICAgIGZvciAobGV0IGN1ciA9IGRvbTsgY3VyOyBjdXIgPSBwYXJlbnROb2RlKGN1cikpIHtcbiAgICAgICAgc3RhY2sucHVzaCh7IGRvbTogY3VyLCB0b3A6IGN1ci5zY3JvbGxUb3AsIGxlZnQ6IGN1ci5zY3JvbGxMZWZ0IH0pO1xuICAgICAgICBpZiAoZG9tID09IGRvYylcbiAgICAgICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICByZXR1cm4gc3RhY2s7XG59XG4vLyBSZXNldCB0aGUgc2Nyb2xsIHBvc2l0aW9uIG9mIHRoZSBlZGl0b3IncyBwYXJlbnQgbm9kZXMgdG8gdGhhdCB3aGF0XG4vLyBpdCB3YXMgYmVmb3JlLCB3aGVuIHN0b3JlU2Nyb2xsUG9zIHdhcyBjYWxsZWQuXG5mdW5jdGlvbiByZXNldFNjcm9sbFBvcyh7IHJlZkRPTSwgcmVmVG9wLCBzdGFjayB9KSB7XG4gICAgbGV0IG5ld1JlZlRvcCA9IHJlZkRPTSA/IHJlZkRPTS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS50b3AgOiAwO1xuICAgIHJlc3RvcmVTY3JvbGxTdGFjayhzdGFjaywgbmV3UmVmVG9wID09IDAgPyAwIDogbmV3UmVmVG9wIC0gcmVmVG9wKTtcbn1cbmZ1bmN0aW9uIHJlc3RvcmVTY3JvbGxTdGFjayhzdGFjaywgZFRvcCkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3RhY2subGVuZ3RoOyBpKyspIHtcbiAgICAgICAgbGV0IHsgZG9tLCB0b3AsIGxlZnQgfSA9IHN0YWNrW2ldO1xuICAgICAgICBpZiAoZG9tLnNjcm9sbFRvcCAhPSB0b3AgKyBkVG9wKVxuICAgICAgICAgICAgZG9tLnNjcm9sbFRvcCA9IHRvcCArIGRUb3A7XG4gICAgICAgIGlmIChkb20uc2Nyb2xsTGVmdCAhPSBsZWZ0KVxuICAgICAgICAgICAgZG9tLnNjcm9sbExlZnQgPSBsZWZ0O1xuICAgIH1cbn1cbmxldCBwcmV2ZW50U2Nyb2xsU3VwcG9ydGVkID0gbnVsbDtcbi8vIEZlYXR1cmUtZGV0ZWN0cyBzdXBwb3J0IGZvciAuZm9jdXMoe3ByZXZlbnRTY3JvbGw6IHRydWV9KSwgYW5kIHVzZXNcbi8vIGEgZmFsbGJhY2sga2x1ZGdlIHdoZW4gbm90IHN1cHBvcnRlZC5cbmZ1bmN0aW9uIGZvY3VzUHJldmVudFNjcm9sbChkb20pIHtcbiAgICBpZiAoZG9tLnNldEFjdGl2ZSlcbiAgICAgICAgcmV0dXJuIGRvbS5zZXRBY3RpdmUoKTsgLy8gaW4gSUVcbiAgICBpZiAocHJldmVudFNjcm9sbFN1cHBvcnRlZClcbiAgICAgICAgcmV0dXJuIGRvbS5mb2N1cyhwcmV2ZW50U2Nyb2xsU3VwcG9ydGVkKTtcbiAgICBsZXQgc3RvcmVkID0gc2Nyb2xsU3RhY2soZG9tKTtcbiAgICBkb20uZm9jdXMocHJldmVudFNjcm9sbFN1cHBvcnRlZCA9PSBudWxsID8ge1xuICAgICAgICBnZXQgcHJldmVudFNjcm9sbCgpIHtcbiAgICAgICAgICAgIHByZXZlbnRTY3JvbGxTdXBwb3J0ZWQgPSB7IHByZXZlbnRTY3JvbGw6IHRydWUgfTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfSA6IHVuZGVmaW5lZCk7XG4gICAgaWYgKCFwcmV2ZW50U2Nyb2xsU3VwcG9ydGVkKSB7XG4gICAgICAgIHByZXZlbnRTY3JvbGxTdXBwb3J0ZWQgPSBmYWxzZTtcbiAgICAgICAgcmVzdG9yZVNjcm9sbFN0YWNrKHN0b3JlZCwgMCk7XG4gICAgfVxufVxuZnVuY3Rpb24gZmluZE9mZnNldEluTm9kZShub2RlLCBjb29yZHMpIHtcbiAgICBsZXQgY2xvc2VzdCwgZHhDbG9zZXN0ID0gMmU4LCBjb29yZHNDbG9zZXN0LCBvZmZzZXQgPSAwO1xuICAgIGxldCByb3dCb3QgPSBjb29yZHMudG9wLCByb3dUb3AgPSBjb29yZHMudG9wO1xuICAgIGxldCBmaXJzdEJlbG93LCBjb29yZHNCZWxvdztcbiAgICBmb3IgKGxldCBjaGlsZCA9IG5vZGUuZmlyc3RDaGlsZCwgY2hpbGRJbmRleCA9IDA7IGNoaWxkOyBjaGlsZCA9IGNoaWxkLm5leHRTaWJsaW5nLCBjaGlsZEluZGV4KyspIHtcbiAgICAgICAgbGV0IHJlY3RzO1xuICAgICAgICBpZiAoY2hpbGQubm9kZVR5cGUgPT0gMSlcbiAgICAgICAgICAgIHJlY3RzID0gY2hpbGQuZ2V0Q2xpZW50UmVjdHMoKTtcbiAgICAgICAgZWxzZSBpZiAoY2hpbGQubm9kZVR5cGUgPT0gMylcbiAgICAgICAgICAgIHJlY3RzID0gdGV4dFJhbmdlKGNoaWxkKS5nZXRDbGllbnRSZWN0cygpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByZWN0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IHJlY3QgPSByZWN0c1tpXTtcbiAgICAgICAgICAgIGlmIChyZWN0LnRvcCA8PSByb3dCb3QgJiYgcmVjdC5ib3R0b20gPj0gcm93VG9wKSB7XG4gICAgICAgICAgICAgICAgcm93Qm90ID0gTWF0aC5tYXgocmVjdC5ib3R0b20sIHJvd0JvdCk7XG4gICAgICAgICAgICAgICAgcm93VG9wID0gTWF0aC5taW4ocmVjdC50b3AsIHJvd1RvcCk7XG4gICAgICAgICAgICAgICAgbGV0IGR4ID0gcmVjdC5sZWZ0ID4gY29vcmRzLmxlZnQgPyByZWN0LmxlZnQgLSBjb29yZHMubGVmdFxuICAgICAgICAgICAgICAgICAgICA6IHJlY3QucmlnaHQgPCBjb29yZHMubGVmdCA/IGNvb3Jkcy5sZWZ0IC0gcmVjdC5yaWdodCA6IDA7XG4gICAgICAgICAgICAgICAgaWYgKGR4IDwgZHhDbG9zZXN0KSB7XG4gICAgICAgICAgICAgICAgICAgIGNsb3Nlc3QgPSBjaGlsZDtcbiAgICAgICAgICAgICAgICAgICAgZHhDbG9zZXN0ID0gZHg7XG4gICAgICAgICAgICAgICAgICAgIGNvb3Jkc0Nsb3Nlc3QgPSBkeCAmJiBjbG9zZXN0Lm5vZGVUeXBlID09IDMgPyB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZWZ0OiByZWN0LnJpZ2h0IDwgY29vcmRzLmxlZnQgPyByZWN0LnJpZ2h0IDogcmVjdC5sZWZ0LFxuICAgICAgICAgICAgICAgICAgICAgICAgdG9wOiBjb29yZHMudG9wXG4gICAgICAgICAgICAgICAgICAgIH0gOiBjb29yZHM7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjaGlsZC5ub2RlVHlwZSA9PSAxICYmIGR4KVxuICAgICAgICAgICAgICAgICAgICAgICAgb2Zmc2V0ID0gY2hpbGRJbmRleCArIChjb29yZHMubGVmdCA+PSAocmVjdC5sZWZ0ICsgcmVjdC5yaWdodCkgLyAyID8gMSA6IDApO1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChyZWN0LnRvcCA+IGNvb3Jkcy50b3AgJiYgIWZpcnN0QmVsb3cgJiYgcmVjdC5sZWZ0IDw9IGNvb3Jkcy5sZWZ0ICYmIHJlY3QucmlnaHQgPj0gY29vcmRzLmxlZnQpIHtcbiAgICAgICAgICAgICAgICBmaXJzdEJlbG93ID0gY2hpbGQ7XG4gICAgICAgICAgICAgICAgY29vcmRzQmVsb3cgPSB7IGxlZnQ6IE1hdGgubWF4KHJlY3QubGVmdCwgTWF0aC5taW4ocmVjdC5yaWdodCwgY29vcmRzLmxlZnQpKSwgdG9wOiByZWN0LnRvcCB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFjbG9zZXN0ICYmIChjb29yZHMubGVmdCA+PSByZWN0LnJpZ2h0ICYmIGNvb3Jkcy50b3AgPj0gcmVjdC50b3AgfHxcbiAgICAgICAgICAgICAgICBjb29yZHMubGVmdCA+PSByZWN0LmxlZnQgJiYgY29vcmRzLnRvcCA+PSByZWN0LmJvdHRvbSkpXG4gICAgICAgICAgICAgICAgb2Zmc2V0ID0gY2hpbGRJbmRleCArIDE7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKCFjbG9zZXN0ICYmIGZpcnN0QmVsb3cpIHtcbiAgICAgICAgY2xvc2VzdCA9IGZpcnN0QmVsb3c7XG4gICAgICAgIGNvb3Jkc0Nsb3Nlc3QgPSBjb29yZHNCZWxvdztcbiAgICAgICAgZHhDbG9zZXN0ID0gMDtcbiAgICB9XG4gICAgaWYgKGNsb3Nlc3QgJiYgY2xvc2VzdC5ub2RlVHlwZSA9PSAzKVxuICAgICAgICByZXR1cm4gZmluZE9mZnNldEluVGV4dChjbG9zZXN0LCBjb29yZHNDbG9zZXN0KTtcbiAgICBpZiAoIWNsb3Nlc3QgfHwgKGR4Q2xvc2VzdCAmJiBjbG9zZXN0Lm5vZGVUeXBlID09IDEpKVxuICAgICAgICByZXR1cm4geyBub2RlLCBvZmZzZXQgfTtcbiAgICByZXR1cm4gZmluZE9mZnNldEluTm9kZShjbG9zZXN0LCBjb29yZHNDbG9zZXN0KTtcbn1cbmZ1bmN0aW9uIGZpbmRPZmZzZXRJblRleHQobm9kZSwgY29vcmRzKSB7XG4gICAgbGV0IGxlbiA9IG5vZGUubm9kZVZhbHVlLmxlbmd0aDtcbiAgICBsZXQgcmFuZ2UgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgcmFuZ2Uuc2V0RW5kKG5vZGUsIGkgKyAxKTtcbiAgICAgICAgcmFuZ2Uuc2V0U3RhcnQobm9kZSwgaSk7XG4gICAgICAgIGxldCByZWN0ID0gc2luZ2xlUmVjdChyYW5nZSwgMSk7XG4gICAgICAgIGlmIChyZWN0LnRvcCA9PSByZWN0LmJvdHRvbSlcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICBpZiAoaW5SZWN0KGNvb3JkcywgcmVjdCkpXG4gICAgICAgICAgICByZXR1cm4geyBub2RlLCBvZmZzZXQ6IGkgKyAoY29vcmRzLmxlZnQgPj0gKHJlY3QubGVmdCArIHJlY3QucmlnaHQpIC8gMiA/IDEgOiAwKSB9O1xuICAgIH1cbiAgICByZXR1cm4geyBub2RlLCBvZmZzZXQ6IDAgfTtcbn1cbmZ1bmN0aW9uIGluUmVjdChjb29yZHMsIHJlY3QpIHtcbiAgICByZXR1cm4gY29vcmRzLmxlZnQgPj0gcmVjdC5sZWZ0IC0gMSAmJiBjb29yZHMubGVmdCA8PSByZWN0LnJpZ2h0ICsgMSAmJlxuICAgICAgICBjb29yZHMudG9wID49IHJlY3QudG9wIC0gMSAmJiBjb29yZHMudG9wIDw9IHJlY3QuYm90dG9tICsgMTtcbn1cbmZ1bmN0aW9uIHRhcmdldEtsdWRnZShkb20sIGNvb3Jkcykge1xuICAgIGxldCBwYXJlbnQgPSBkb20ucGFyZW50Tm9kZTtcbiAgICBpZiAocGFyZW50ICYmIC9ebGkkL2kudGVzdChwYXJlbnQubm9kZU5hbWUpICYmIGNvb3Jkcy5sZWZ0IDwgZG9tLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmxlZnQpXG4gICAgICAgIHJldHVybiBwYXJlbnQ7XG4gICAgcmV0dXJuIGRvbTtcbn1cbmZ1bmN0aW9uIHBvc0Zyb21FbGVtZW50KHZpZXcsIGVsdCwgY29vcmRzKSB7XG4gICAgbGV0IHsgbm9kZSwgb2Zmc2V0IH0gPSBmaW5kT2Zmc2V0SW5Ob2RlKGVsdCwgY29vcmRzKSwgYmlhcyA9IC0xO1xuICAgIGlmIChub2RlLm5vZGVUeXBlID09IDEgJiYgIW5vZGUuZmlyc3RDaGlsZCkge1xuICAgICAgICBsZXQgcmVjdCA9IG5vZGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIGJpYXMgPSByZWN0LmxlZnQgIT0gcmVjdC5yaWdodCAmJiBjb29yZHMubGVmdCA+IChyZWN0LmxlZnQgKyByZWN0LnJpZ2h0KSAvIDIgPyAxIDogLTE7XG4gICAgfVxuICAgIHJldHVybiB2aWV3LmRvY1ZpZXcucG9zRnJvbURPTShub2RlLCBvZmZzZXQsIGJpYXMpO1xufVxuZnVuY3Rpb24gcG9zRnJvbUNhcmV0KHZpZXcsIG5vZGUsIG9mZnNldCwgY29vcmRzKSB7XG4gICAgLy8gQnJvd3NlciAoaW4gY2FyZXRQb3NpdGlvbi9SYW5nZUZyb21Qb2ludCkgd2lsbCBhZ3Jlc3NpdmVseVxuICAgIC8vIG5vcm1hbGl6ZSB0b3dhcmRzIG5lYXJieSBpbmxpbmUgbm9kZXMuIFNpbmNlIHdlIGFyZSBpbnRlcmVzdGVkIGluXG4gICAgLy8gcG9zaXRpb25zIGJldHdlZW4gYmxvY2sgbm9kZXMgdG9vLCB3ZSBmaXJzdCB3YWxrIHVwIHRoZSBoaWVyYXJjaHlcbiAgICAvLyBvZiBub2RlcyB0byBzZWUgaWYgdGhlcmUgYXJlIGJsb2NrIG5vZGVzIHRoYXQgdGhlIGNvb3JkaW5hdGVzXG4gICAgLy8gZmFsbCBvdXRzaWRlIG9mLiBJZiBzbywgd2UgdGFrZSB0aGUgcG9zaXRpb24gYmVmb3JlL2FmdGVyIHRoYXRcbiAgICAvLyBibG9jay4gSWYgbm90LCB3ZSBjYWxsIGBwb3NGcm9tRE9NYCBvbiB0aGUgcmF3IG5vZGUvb2Zmc2V0LlxuICAgIGxldCBvdXRzaWRlQmxvY2sgPSAtMTtcbiAgICBmb3IgKGxldCBjdXIgPSBub2RlLCBzYXdCbG9jayA9IGZhbHNlOzspIHtcbiAgICAgICAgaWYgKGN1ciA9PSB2aWV3LmRvbSlcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBsZXQgZGVzYyA9IHZpZXcuZG9jVmlldy5uZWFyZXN0RGVzYyhjdXIsIHRydWUpLCByZWN0O1xuICAgICAgICBpZiAoIWRlc2MpXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgaWYgKGRlc2MuZG9tLm5vZGVUeXBlID09IDEgJiYgKGRlc2Mubm9kZS5pc0Jsb2NrICYmIGRlc2MucGFyZW50IHx8ICFkZXNjLmNvbnRlbnRET00pICYmXG4gICAgICAgICAgICAvLyBJZ25vcmUgZWxlbWVudHMgd2l0aCB6ZXJvLXNpemUgYm91bmRpbmcgcmVjdGFuZ2xlc1xuICAgICAgICAgICAgKChyZWN0ID0gZGVzYy5kb20uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkpLndpZHRoIHx8IHJlY3QuaGVpZ2h0KSkge1xuICAgICAgICAgICAgaWYgKGRlc2Mubm9kZS5pc0Jsb2NrICYmIGRlc2MucGFyZW50KSB7XG4gICAgICAgICAgICAgICAgLy8gT25seSBhcHBseSB0aGUgaG9yaXpvbnRhbCB0ZXN0IHRvIHRoZSBpbm5lcm1vc3QgYmxvY2suIFZlcnRpY2FsIGZvciBhbnkgcGFyZW50LlxuICAgICAgICAgICAgICAgIGlmICghc2F3QmxvY2sgJiYgcmVjdC5sZWZ0ID4gY29vcmRzLmxlZnQgfHwgcmVjdC50b3AgPiBjb29yZHMudG9wKVxuICAgICAgICAgICAgICAgICAgICBvdXRzaWRlQmxvY2sgPSBkZXNjLnBvc0JlZm9yZTtcbiAgICAgICAgICAgICAgICBlbHNlIGlmICghc2F3QmxvY2sgJiYgcmVjdC5yaWdodCA8IGNvb3Jkcy5sZWZ0IHx8IHJlY3QuYm90dG9tIDwgY29vcmRzLnRvcClcbiAgICAgICAgICAgICAgICAgICAgb3V0c2lkZUJsb2NrID0gZGVzYy5wb3NBZnRlcjtcbiAgICAgICAgICAgICAgICBzYXdCbG9jayA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIWRlc2MuY29udGVudERPTSAmJiBvdXRzaWRlQmxvY2sgPCAwICYmICFkZXNjLm5vZGUuaXNUZXh0KSB7XG4gICAgICAgICAgICAgICAgLy8gSWYgd2UgYXJlIGluc2lkZSBhIGxlYWYsIHJldHVybiB0aGUgc2lkZSBvZiB0aGUgbGVhZiBjbG9zZXIgdG8gdGhlIGNvb3Jkc1xuICAgICAgICAgICAgICAgIGxldCBiZWZvcmUgPSBkZXNjLm5vZGUuaXNCbG9jayA/IGNvb3Jkcy50b3AgPCAocmVjdC50b3AgKyByZWN0LmJvdHRvbSkgLyAyXG4gICAgICAgICAgICAgICAgICAgIDogY29vcmRzLmxlZnQgPCAocmVjdC5sZWZ0ICsgcmVjdC5yaWdodCkgLyAyO1xuICAgICAgICAgICAgICAgIHJldHVybiBiZWZvcmUgPyBkZXNjLnBvc0JlZm9yZSA6IGRlc2MucG9zQWZ0ZXI7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY3VyID0gZGVzYy5kb20ucGFyZW50Tm9kZTtcbiAgICB9XG4gICAgcmV0dXJuIG91dHNpZGVCbG9jayA+IC0xID8gb3V0c2lkZUJsb2NrIDogdmlldy5kb2NWaWV3LnBvc0Zyb21ET00obm9kZSwgb2Zmc2V0LCAtMSk7XG59XG5mdW5jdGlvbiBlbGVtZW50RnJvbVBvaW50KGVsZW1lbnQsIGNvb3JkcywgYm94KSB7XG4gICAgbGV0IGxlbiA9IGVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGg7XG4gICAgaWYgKGxlbiAmJiBib3gudG9wIDwgYm94LmJvdHRvbSkge1xuICAgICAgICBmb3IgKGxldCBzdGFydEkgPSBNYXRoLm1heCgwLCBNYXRoLm1pbihsZW4gLSAxLCBNYXRoLmZsb29yKGxlbiAqIChjb29yZHMudG9wIC0gYm94LnRvcCkgLyAoYm94LmJvdHRvbSAtIGJveC50b3ApKSAtIDIpKSwgaSA9IHN0YXJ0STs7KSB7XG4gICAgICAgICAgICBsZXQgY2hpbGQgPSBlbGVtZW50LmNoaWxkTm9kZXNbaV07XG4gICAgICAgICAgICBpZiAoY2hpbGQubm9kZVR5cGUgPT0gMSkge1xuICAgICAgICAgICAgICAgIGxldCByZWN0cyA9IGNoaWxkLmdldENsaWVudFJlY3RzKCk7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCByZWN0cy5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAgICAgICBsZXQgcmVjdCA9IHJlY3RzW2pdO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaW5SZWN0KGNvb3JkcywgcmVjdCkpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZWxlbWVudEZyb21Qb2ludChjaGlsZCwgY29vcmRzLCByZWN0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoKGkgPSAoaSArIDEpICUgbGVuKSA9PSBzdGFydEkpXG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGVsZW1lbnQ7XG59XG4vLyBHaXZlbiBhbiB4LHkgcG9zaXRpb24gb24gdGhlIGVkaXRvciwgZ2V0IHRoZSBwb3NpdGlvbiBpbiB0aGUgZG9jdW1lbnQuXG5mdW5jdGlvbiBwb3NBdENvb3Jkcyh2aWV3LCBjb29yZHMpIHtcbiAgICBsZXQgZG9jID0gdmlldy5kb20ub3duZXJEb2N1bWVudCwgbm9kZSwgb2Zmc2V0ID0gMDtcbiAgICBsZXQgY2FyZXQgPSBjYXJldEZyb21Qb2ludChkb2MsIGNvb3Jkcy5sZWZ0LCBjb29yZHMudG9wKTtcbiAgICBpZiAoY2FyZXQpXG4gICAgICAgICh7IG5vZGUsIG9mZnNldCB9ID0gY2FyZXQpO1xuICAgIGxldCBlbHQgPSAodmlldy5yb290LmVsZW1lbnRGcm9tUG9pbnQgPyB2aWV3LnJvb3QgOiBkb2MpXG4gICAgICAgIC5lbGVtZW50RnJvbVBvaW50KGNvb3Jkcy5sZWZ0LCBjb29yZHMudG9wKTtcbiAgICBsZXQgcG9zO1xuICAgIGlmICghZWx0IHx8ICF2aWV3LmRvbS5jb250YWlucyhlbHQubm9kZVR5cGUgIT0gMSA/IGVsdC5wYXJlbnROb2RlIDogZWx0KSkge1xuICAgICAgICBsZXQgYm94ID0gdmlldy5kb20uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIGlmICghaW5SZWN0KGNvb3JkcywgYm94KSlcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICBlbHQgPSBlbGVtZW50RnJvbVBvaW50KHZpZXcuZG9tLCBjb29yZHMsIGJveCk7XG4gICAgICAgIGlmICghZWx0KVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIC8vIFNhZmFyaSdzIGNhcmV0UmFuZ2VGcm9tUG9pbnQgcmV0dXJucyBub25zZW5zZSB3aGVuIG9uIGEgZHJhZ2dhYmxlIGVsZW1lbnRcbiAgICBpZiAoc2FmYXJpKSB7XG4gICAgICAgIGZvciAobGV0IHAgPSBlbHQ7IG5vZGUgJiYgcDsgcCA9IHBhcmVudE5vZGUocCkpXG4gICAgICAgICAgICBpZiAocC5kcmFnZ2FibGUpXG4gICAgICAgICAgICAgICAgbm9kZSA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgZWx0ID0gdGFyZ2V0S2x1ZGdlKGVsdCwgY29vcmRzKTtcbiAgICBpZiAobm9kZSkge1xuICAgICAgICBpZiAoZ2Vja28gJiYgbm9kZS5ub2RlVHlwZSA9PSAxKSB7XG4gICAgICAgICAgICAvLyBGaXJlZm94IHdpbGwgc29tZXRpbWVzIHJldHVybiBvZmZzZXRzIGludG8gPGlucHV0PiBub2Rlcywgd2hpY2hcbiAgICAgICAgICAgIC8vIGhhdmUgbm8gYWN0dWFsIGNoaWxkcmVuLCBmcm9tIGNhcmV0UG9zaXRpb25Gcm9tUG9pbnQgKCM5NTMpXG4gICAgICAgICAgICBvZmZzZXQgPSBNYXRoLm1pbihvZmZzZXQsIG5vZGUuY2hpbGROb2Rlcy5sZW5ndGgpO1xuICAgICAgICAgICAgLy8gSXQnbGwgYWxzbyBtb3ZlIHRoZSByZXR1cm5lZCBwb3NpdGlvbiBiZWZvcmUgaW1hZ2Ugbm9kZXMsXG4gICAgICAgICAgICAvLyBldmVuIGlmIHRob3NlIGFyZSBiZWhpbmQgaXQuXG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgbm9kZS5jaGlsZE5vZGVzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGxldCBuZXh0ID0gbm9kZS5jaGlsZE5vZGVzW29mZnNldF0sIGJveDtcbiAgICAgICAgICAgICAgICBpZiAobmV4dC5ub2RlTmFtZSA9PSBcIklNR1wiICYmIChib3ggPSBuZXh0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpKS5yaWdodCA8PSBjb29yZHMubGVmdCAmJlxuICAgICAgICAgICAgICAgICAgICBib3guYm90dG9tID4gY29vcmRzLnRvcClcbiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0Kys7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHByZXY7XG4gICAgICAgIC8vIFdoZW4gY2xpY2tpbmcgYWJvdmUgdGhlIHJpZ2h0IHNpZGUgb2YgYW4gdW5lZGl0YWJsZSBub2RlLCBDaHJvbWUgd2lsbCByZXBvcnQgYSBjdXJzb3IgcG9zaXRpb24gYWZ0ZXIgdGhhdCBub2RlLlxuICAgICAgICBpZiAod2Via2l0ICYmIG9mZnNldCAmJiBub2RlLm5vZGVUeXBlID09IDEgJiYgKHByZXYgPSBub2RlLmNoaWxkTm9kZXNbb2Zmc2V0IC0gMV0pLm5vZGVUeXBlID09IDEgJiZcbiAgICAgICAgICAgIHByZXYuY29udGVudEVkaXRhYmxlID09IFwiZmFsc2VcIiAmJiBwcmV2LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvcCA+PSBjb29yZHMudG9wKVxuICAgICAgICAgICAgb2Zmc2V0LS07XG4gICAgICAgIC8vIFN1c3BpY2lvdXNseSBzcGVjaWZpYyBrbHVkZ2UgdG8gd29yayBhcm91bmQgY2FyZXQqRnJvbVBvaW50XG4gICAgICAgIC8vIG5ldmVyIHJldHVybmluZyBhIHBvc2l0aW9uIGF0IHRoZSBlbmQgb2YgdGhlIGRvY3VtZW50XG4gICAgICAgIGlmIChub2RlID09IHZpZXcuZG9tICYmIG9mZnNldCA9PSBub2RlLmNoaWxkTm9kZXMubGVuZ3RoIC0gMSAmJiBub2RlLmxhc3RDaGlsZC5ub2RlVHlwZSA9PSAxICYmXG4gICAgICAgICAgICBjb29yZHMudG9wID4gbm9kZS5sYXN0Q2hpbGQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkuYm90dG9tKVxuICAgICAgICAgICAgcG9zID0gdmlldy5zdGF0ZS5kb2MuY29udGVudC5zaXplO1xuICAgICAgICAvLyBJZ25vcmUgcG9zaXRpb25zIGRpcmVjdGx5IGFmdGVyIGEgQlIsIHNpbmNlIGNhcmV0KkZyb21Qb2ludFxuICAgICAgICAvLyAncm91bmQgdXAnIHBvc2l0aW9ucyB0aGF0IHdvdWxkIGJlIG1vcmUgYWNjdXJhdGVseSBwbGFjZWRcbiAgICAgICAgLy8gYmVmb3JlIHRoZSBCUiBub2RlLlxuICAgICAgICBlbHNlIGlmIChvZmZzZXQgPT0gMCB8fCBub2RlLm5vZGVUeXBlICE9IDEgfHwgbm9kZS5jaGlsZE5vZGVzW29mZnNldCAtIDFdLm5vZGVOYW1lICE9IFwiQlJcIilcbiAgICAgICAgICAgIHBvcyA9IHBvc0Zyb21DYXJldCh2aWV3LCBub2RlLCBvZmZzZXQsIGNvb3Jkcyk7XG4gICAgfVxuICAgIGlmIChwb3MgPT0gbnVsbClcbiAgICAgICAgcG9zID0gcG9zRnJvbUVsZW1lbnQodmlldywgZWx0LCBjb29yZHMpO1xuICAgIGxldCBkZXNjID0gdmlldy5kb2NWaWV3Lm5lYXJlc3REZXNjKGVsdCwgdHJ1ZSk7XG4gICAgcmV0dXJuIHsgcG9zLCBpbnNpZGU6IGRlc2MgPyBkZXNjLnBvc0F0U3RhcnQgLSBkZXNjLmJvcmRlciA6IC0xIH07XG59XG5mdW5jdGlvbiBub25aZXJvKHJlY3QpIHtcbiAgICByZXR1cm4gcmVjdC50b3AgPCByZWN0LmJvdHRvbSB8fCByZWN0LmxlZnQgPCByZWN0LnJpZ2h0O1xufVxuZnVuY3Rpb24gc2luZ2xlUmVjdCh0YXJnZXQsIGJpYXMpIHtcbiAgICBsZXQgcmVjdHMgPSB0YXJnZXQuZ2V0Q2xpZW50UmVjdHMoKTtcbiAgICBpZiAocmVjdHMubGVuZ3RoKSB7XG4gICAgICAgIGxldCBmaXJzdCA9IHJlY3RzW2JpYXMgPCAwID8gMCA6IHJlY3RzLmxlbmd0aCAtIDFdO1xuICAgICAgICBpZiAobm9uWmVybyhmaXJzdCkpXG4gICAgICAgICAgICByZXR1cm4gZmlyc3Q7XG4gICAgfVxuICAgIHJldHVybiBBcnJheS5wcm90b3R5cGUuZmluZC5jYWxsKHJlY3RzLCBub25aZXJvKSB8fCB0YXJnZXQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG59XG5jb25zdCBCSURJID0gL1tcXHUwNTkwLVxcdTA1ZjRcXHUwNjAwLVxcdTA2ZmZcXHUwNzAwLVxcdTA4YWNdLztcbi8vIEdpdmVuIGEgcG9zaXRpb24gaW4gdGhlIGRvY3VtZW50IG1vZGVsLCBnZXQgYSBib3VuZGluZyBib3ggb2YgdGhlXG4vLyBjaGFyYWN0ZXIgYXQgdGhhdCBwb3NpdGlvbiwgcmVsYXRpdmUgdG8gdGhlIHdpbmRvdy5cbmZ1bmN0aW9uIGNvb3Jkc0F0UG9zKHZpZXcsIHBvcywgc2lkZSkge1xuICAgIGxldCB7IG5vZGUsIG9mZnNldCwgYXRvbSB9ID0gdmlldy5kb2NWaWV3LmRvbUZyb21Qb3MocG9zLCBzaWRlIDwgMCA/IC0xIDogMSk7XG4gICAgbGV0IHN1cHBvcnRFbXB0eVJhbmdlID0gd2Via2l0IHx8IGdlY2tvO1xuICAgIGlmIChub2RlLm5vZGVUeXBlID09IDMpIHtcbiAgICAgICAgLy8gVGhlc2UgYnJvd3NlcnMgc3VwcG9ydCBxdWVyeWluZyBlbXB0eSB0ZXh0IHJhbmdlcy4gUHJlZmVyIHRoYXQgaW5cbiAgICAgICAgLy8gYmlkaSBjb250ZXh0IG9yIHdoZW4gYXQgdGhlIGVuZCBvZiBhIG5vZGUuXG4gICAgICAgIGlmIChzdXBwb3J0RW1wdHlSYW5nZSAmJiAoQklESS50ZXN0KG5vZGUubm9kZVZhbHVlKSB8fCAoc2lkZSA8IDAgPyAhb2Zmc2V0IDogb2Zmc2V0ID09IG5vZGUubm9kZVZhbHVlLmxlbmd0aCkpKSB7XG4gICAgICAgICAgICBsZXQgcmVjdCA9IHNpbmdsZVJlY3QodGV4dFJhbmdlKG5vZGUsIG9mZnNldCwgb2Zmc2V0KSwgc2lkZSk7XG4gICAgICAgICAgICAvLyBGaXJlZm94IHJldHVybnMgYmFkIHJlc3VsdHMgKHRoZSBwb3NpdGlvbiBiZWZvcmUgdGhlIHNwYWNlKVxuICAgICAgICAgICAgLy8gd2hlbiBxdWVyeWluZyBhIHBvc2l0aW9uIGRpcmVjdGx5IGFmdGVyIGxpbmUtYnJva2VuXG4gICAgICAgICAgICAvLyB3aGl0ZXNwYWNlLiBEZXRlY3QgdGhpcyBzaXR1YXRpb24gYW5kIGFuZCBrbHVkZ2UgYXJvdW5kIGl0XG4gICAgICAgICAgICBpZiAoZ2Vja28gJiYgb2Zmc2V0ICYmIC9cXHMvLnRlc3Qobm9kZS5ub2RlVmFsdWVbb2Zmc2V0IC0gMV0pICYmIG9mZnNldCA8IG5vZGUubm9kZVZhbHVlLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGxldCByZWN0QmVmb3JlID0gc2luZ2xlUmVjdCh0ZXh0UmFuZ2Uobm9kZSwgb2Zmc2V0IC0gMSwgb2Zmc2V0IC0gMSksIC0xKTtcbiAgICAgICAgICAgICAgICBpZiAocmVjdEJlZm9yZS50b3AgPT0gcmVjdC50b3ApIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHJlY3RBZnRlciA9IHNpbmdsZVJlY3QodGV4dFJhbmdlKG5vZGUsIG9mZnNldCwgb2Zmc2V0ICsgMSksIC0xKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlY3RBZnRlci50b3AgIT0gcmVjdC50b3ApXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmxhdHRlblYocmVjdEFmdGVyLCByZWN0QWZ0ZXIubGVmdCA8IHJlY3RCZWZvcmUubGVmdCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlY3Q7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBsZXQgZnJvbSA9IG9mZnNldCwgdG8gPSBvZmZzZXQsIHRha2VTaWRlID0gc2lkZSA8IDAgPyAxIDogLTE7XG4gICAgICAgICAgICBpZiAoc2lkZSA8IDAgJiYgIW9mZnNldCkge1xuICAgICAgICAgICAgICAgIHRvKys7XG4gICAgICAgICAgICAgICAgdGFrZVNpZGUgPSAtMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHNpZGUgPj0gMCAmJiBvZmZzZXQgPT0gbm9kZS5ub2RlVmFsdWUubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgZnJvbS0tO1xuICAgICAgICAgICAgICAgIHRha2VTaWRlID0gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHNpZGUgPCAwKSB7XG4gICAgICAgICAgICAgICAgZnJvbS0tO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdG8rKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBmbGF0dGVuVihzaW5nbGVSZWN0KHRleHRSYW5nZShub2RlLCBmcm9tLCB0byksIHRha2VTaWRlKSwgdGFrZVNpZGUgPCAwKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBsZXQgJGRvbSA9IHZpZXcuc3RhdGUuZG9jLnJlc29sdmUocG9zIC0gKGF0b20gfHwgMCkpO1xuICAgIC8vIFJldHVybiBhIGhvcml6b250YWwgbGluZSBpbiBibG9jayBjb250ZXh0XG4gICAgaWYgKCEkZG9tLnBhcmVudC5pbmxpbmVDb250ZW50KSB7XG4gICAgICAgIGlmIChhdG9tID09IG51bGwgJiYgb2Zmc2V0ICYmIChzaWRlIDwgMCB8fCBvZmZzZXQgPT0gbm9kZVNpemUobm9kZSkpKSB7XG4gICAgICAgICAgICBsZXQgYmVmb3JlID0gbm9kZS5jaGlsZE5vZGVzW29mZnNldCAtIDFdO1xuICAgICAgICAgICAgaWYgKGJlZm9yZS5ub2RlVHlwZSA9PSAxKVxuICAgICAgICAgICAgICAgIHJldHVybiBmbGF0dGVuSChiZWZvcmUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksIGZhbHNlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYXRvbSA9PSBudWxsICYmIG9mZnNldCA8IG5vZGVTaXplKG5vZGUpKSB7XG4gICAgICAgICAgICBsZXQgYWZ0ZXIgPSBub2RlLmNoaWxkTm9kZXNbb2Zmc2V0XTtcbiAgICAgICAgICAgIGlmIChhZnRlci5ub2RlVHlwZSA9PSAxKVxuICAgICAgICAgICAgICAgIHJldHVybiBmbGF0dGVuSChhZnRlci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSwgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZsYXR0ZW5IKG5vZGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksIHNpZGUgPj0gMCk7XG4gICAgfVxuICAgIC8vIElubGluZSwgbm90IGluIHRleHQgbm9kZSAodGhpcyBpcyBub3QgQmlkaS1zYWZlKVxuICAgIGlmIChhdG9tID09IG51bGwgJiYgb2Zmc2V0ICYmIChzaWRlIDwgMCB8fCBvZmZzZXQgPT0gbm9kZVNpemUobm9kZSkpKSB7XG4gICAgICAgIGxldCBiZWZvcmUgPSBub2RlLmNoaWxkTm9kZXNbb2Zmc2V0IC0gMV07XG4gICAgICAgIGxldCB0YXJnZXQgPSBiZWZvcmUubm9kZVR5cGUgPT0gMyA/IHRleHRSYW5nZShiZWZvcmUsIG5vZGVTaXplKGJlZm9yZSkgLSAoc3VwcG9ydEVtcHR5UmFuZ2UgPyAwIDogMSkpXG4gICAgICAgICAgICAvLyBCUiBub2RlcyB0ZW5kIHRvIG9ubHkgcmV0dXJuIHRoZSByZWN0YW5nbGUgYmVmb3JlIHRoZW0uXG4gICAgICAgICAgICAvLyBPbmx5IHVzZSB0aGVtIGlmIHRoZXkgYXJlIHRoZSBsYXN0IGVsZW1lbnQgaW4gdGhlaXIgcGFyZW50XG4gICAgICAgICAgICA6IGJlZm9yZS5ub2RlVHlwZSA9PSAxICYmIChiZWZvcmUubm9kZU5hbWUgIT0gXCJCUlwiIHx8ICFiZWZvcmUubmV4dFNpYmxpbmcpID8gYmVmb3JlIDogbnVsbDtcbiAgICAgICAgaWYgKHRhcmdldClcbiAgICAgICAgICAgIHJldHVybiBmbGF0dGVuVihzaW5nbGVSZWN0KHRhcmdldCwgMSksIGZhbHNlKTtcbiAgICB9XG4gICAgaWYgKGF0b20gPT0gbnVsbCAmJiBvZmZzZXQgPCBub2RlU2l6ZShub2RlKSkge1xuICAgICAgICBsZXQgYWZ0ZXIgPSBub2RlLmNoaWxkTm9kZXNbb2Zmc2V0XTtcbiAgICAgICAgd2hpbGUgKGFmdGVyLnBtVmlld0Rlc2MgJiYgYWZ0ZXIucG1WaWV3RGVzYy5pZ25vcmVGb3JDb29yZHMpXG4gICAgICAgICAgICBhZnRlciA9IGFmdGVyLm5leHRTaWJsaW5nO1xuICAgICAgICBsZXQgdGFyZ2V0ID0gIWFmdGVyID8gbnVsbCA6IGFmdGVyLm5vZGVUeXBlID09IDMgPyB0ZXh0UmFuZ2UoYWZ0ZXIsIDAsIChzdXBwb3J0RW1wdHlSYW5nZSA/IDAgOiAxKSlcbiAgICAgICAgICAgIDogYWZ0ZXIubm9kZVR5cGUgPT0gMSA/IGFmdGVyIDogbnVsbDtcbiAgICAgICAgaWYgKHRhcmdldClcbiAgICAgICAgICAgIHJldHVybiBmbGF0dGVuVihzaW5nbGVSZWN0KHRhcmdldCwgLTEpLCB0cnVlKTtcbiAgICB9XG4gICAgLy8gQWxsIGVsc2UgZmFpbGVkLCBqdXN0IHRyeSB0byBnZXQgYSByZWN0YW5nbGUgZm9yIHRoZSB0YXJnZXQgbm9kZVxuICAgIHJldHVybiBmbGF0dGVuVihzaW5nbGVSZWN0KG5vZGUubm9kZVR5cGUgPT0gMyA/IHRleHRSYW5nZShub2RlKSA6IG5vZGUsIC1zaWRlKSwgc2lkZSA+PSAwKTtcbn1cbmZ1bmN0aW9uIGZsYXR0ZW5WKHJlY3QsIGxlZnQpIHtcbiAgICBpZiAocmVjdC53aWR0aCA9PSAwKVxuICAgICAgICByZXR1cm4gcmVjdDtcbiAgICBsZXQgeCA9IGxlZnQgPyByZWN0LmxlZnQgOiByZWN0LnJpZ2h0O1xuICAgIHJldHVybiB7IHRvcDogcmVjdC50b3AsIGJvdHRvbTogcmVjdC5ib3R0b20sIGxlZnQ6IHgsIHJpZ2h0OiB4IH07XG59XG5mdW5jdGlvbiBmbGF0dGVuSChyZWN0LCB0b3ApIHtcbiAgICBpZiAocmVjdC5oZWlnaHQgPT0gMClcbiAgICAgICAgcmV0dXJuIHJlY3Q7XG4gICAgbGV0IHkgPSB0b3AgPyByZWN0LnRvcCA6IHJlY3QuYm90dG9tO1xuICAgIHJldHVybiB7IHRvcDogeSwgYm90dG9tOiB5LCBsZWZ0OiByZWN0LmxlZnQsIHJpZ2h0OiByZWN0LnJpZ2h0IH07XG59XG5mdW5jdGlvbiB3aXRoRmx1c2hlZFN0YXRlKHZpZXcsIHN0YXRlLCBmKSB7XG4gICAgbGV0IHZpZXdTdGF0ZSA9IHZpZXcuc3RhdGUsIGFjdGl2ZSA9IHZpZXcucm9vdC5hY3RpdmVFbGVtZW50O1xuICAgIGlmICh2aWV3U3RhdGUgIT0gc3RhdGUpXG4gICAgICAgIHZpZXcudXBkYXRlU3RhdGUoc3RhdGUpO1xuICAgIGlmIChhY3RpdmUgIT0gdmlldy5kb20pXG4gICAgICAgIHZpZXcuZm9jdXMoKTtcbiAgICB0cnkge1xuICAgICAgICByZXR1cm4gZigpO1xuICAgIH1cbiAgICBmaW5hbGx5IHtcbiAgICAgICAgaWYgKHZpZXdTdGF0ZSAhPSBzdGF0ZSlcbiAgICAgICAgICAgIHZpZXcudXBkYXRlU3RhdGUodmlld1N0YXRlKTtcbiAgICAgICAgaWYgKGFjdGl2ZSAhPSB2aWV3LmRvbSAmJiBhY3RpdmUpXG4gICAgICAgICAgICBhY3RpdmUuZm9jdXMoKTtcbiAgICB9XG59XG4vLyBXaGV0aGVyIHZlcnRpY2FsIHBvc2l0aW9uIG1vdGlvbiBpbiBhIGdpdmVuIGRpcmVjdGlvblxuLy8gZnJvbSBhIHBvc2l0aW9uIHdvdWxkIGxlYXZlIGEgdGV4dCBibG9jay5cbmZ1bmN0aW9uIGVuZE9mVGV4dGJsb2NrVmVydGljYWwodmlldywgc3RhdGUsIGRpcikge1xuICAgIGxldCBzZWwgPSBzdGF0ZS5zZWxlY3Rpb247XG4gICAgbGV0ICRwb3MgPSBkaXIgPT0gXCJ1cFwiID8gc2VsLiRmcm9tIDogc2VsLiR0bztcbiAgICByZXR1cm4gd2l0aEZsdXNoZWRTdGF0ZSh2aWV3LCBzdGF0ZSwgKCkgPT4ge1xuICAgICAgICBsZXQgeyBub2RlOiBkb20gfSA9IHZpZXcuZG9jVmlldy5kb21Gcm9tUG9zKCRwb3MucG9zLCBkaXIgPT0gXCJ1cFwiID8gLTEgOiAxKTtcbiAgICAgICAgZm9yICg7Oykge1xuICAgICAgICAgICAgbGV0IG5lYXJlc3QgPSB2aWV3LmRvY1ZpZXcubmVhcmVzdERlc2MoZG9tLCB0cnVlKTtcbiAgICAgICAgICAgIGlmICghbmVhcmVzdClcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGlmIChuZWFyZXN0Lm5vZGUuaXNCbG9jaykge1xuICAgICAgICAgICAgICAgIGRvbSA9IG5lYXJlc3QuY29udGVudERPTSB8fCBuZWFyZXN0LmRvbTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRvbSA9IG5lYXJlc3QuZG9tLnBhcmVudE5vZGU7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGNvb3JkcyA9IGNvb3Jkc0F0UG9zKHZpZXcsICRwb3MucG9zLCAxKTtcbiAgICAgICAgZm9yIChsZXQgY2hpbGQgPSBkb20uZmlyc3RDaGlsZDsgY2hpbGQ7IGNoaWxkID0gY2hpbGQubmV4dFNpYmxpbmcpIHtcbiAgICAgICAgICAgIGxldCBib3hlcztcbiAgICAgICAgICAgIGlmIChjaGlsZC5ub2RlVHlwZSA9PSAxKVxuICAgICAgICAgICAgICAgIGJveGVzID0gY2hpbGQuZ2V0Q2xpZW50UmVjdHMoKTtcbiAgICAgICAgICAgIGVsc2UgaWYgKGNoaWxkLm5vZGVUeXBlID09IDMpXG4gICAgICAgICAgICAgICAgYm94ZXMgPSB0ZXh0UmFuZ2UoY2hpbGQsIDAsIGNoaWxkLm5vZGVWYWx1ZS5sZW5ndGgpLmdldENsaWVudFJlY3RzKCk7XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJveGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgbGV0IGJveCA9IGJveGVzW2ldO1xuICAgICAgICAgICAgICAgIGlmIChib3guYm90dG9tID4gYm94LnRvcCArIDEgJiZcbiAgICAgICAgICAgICAgICAgICAgKGRpciA9PSBcInVwXCIgPyBjb29yZHMudG9wIC0gYm94LnRvcCA+IChib3guYm90dG9tIC0gY29vcmRzLnRvcCkgKiAyXG4gICAgICAgICAgICAgICAgICAgICAgICA6IGJveC5ib3R0b20gLSBjb29yZHMuYm90dG9tID4gKGNvb3Jkcy5ib3R0b20gLSBib3gudG9wKSAqIDIpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSk7XG59XG5jb25zdCBtYXliZVJUTCA9IC9bXFx1MDU5MC1cXHUwOGFjXS87XG5mdW5jdGlvbiBlbmRPZlRleHRibG9ja0hvcml6b250YWwodmlldywgc3RhdGUsIGRpcikge1xuICAgIGxldCB7ICRoZWFkIH0gPSBzdGF0ZS5zZWxlY3Rpb247XG4gICAgaWYgKCEkaGVhZC5wYXJlbnQuaXNUZXh0YmxvY2spXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICBsZXQgb2Zmc2V0ID0gJGhlYWQucGFyZW50T2Zmc2V0LCBhdFN0YXJ0ID0gIW9mZnNldCwgYXRFbmQgPSBvZmZzZXQgPT0gJGhlYWQucGFyZW50LmNvbnRlbnQuc2l6ZTtcbiAgICBsZXQgc2VsID0gdmlldy5kb21TZWxlY3Rpb24oKTtcbiAgICBpZiAoIXNlbClcbiAgICAgICAgcmV0dXJuICRoZWFkLnBvcyA9PSAkaGVhZC5zdGFydCgpIHx8ICRoZWFkLnBvcyA9PSAkaGVhZC5lbmQoKTtcbiAgICAvLyBJZiB0aGUgdGV4dGJsb2NrIGlzIGFsbCBMVFIsIG9yIHRoZSBicm93c2VyIGRvZXNuJ3Qgc3VwcG9ydFxuICAgIC8vIFNlbGVjdGlvbi5tb2RpZnkgKEVkZ2UpLCBmYWxsIGJhY2sgdG8gYSBwcmltaXRpdmUgYXBwcm9hY2hcbiAgICBpZiAoIW1heWJlUlRMLnRlc3QoJGhlYWQucGFyZW50LnRleHRDb250ZW50KSB8fCAhc2VsLm1vZGlmeSlcbiAgICAgICAgcmV0dXJuIGRpciA9PSBcImxlZnRcIiB8fCBkaXIgPT0gXCJiYWNrd2FyZFwiID8gYXRTdGFydCA6IGF0RW5kO1xuICAgIHJldHVybiB3aXRoRmx1c2hlZFN0YXRlKHZpZXcsIHN0YXRlLCAoKSA9PiB7XG4gICAgICAgIC8vIFRoaXMgaXMgYSBodWdlIGhhY2ssIGJ1dCBhcHBlYXJzIHRvIGJlIHRoZSBiZXN0IHdlIGNhblxuICAgICAgICAvLyBjdXJyZW50bHkgZG86IHVzZSBgU2VsZWN0aW9uLm1vZGlmeWAgdG8gbW92ZSB0aGUgc2VsZWN0aW9uIGJ5XG4gICAgICAgIC8vIG9uZSBjaGFyYWN0ZXIsIGFuZCBzZWUgaWYgdGhhdCBtb3ZlcyB0aGUgY3Vyc29yIG91dCBvZiB0aGVcbiAgICAgICAgLy8gdGV4dGJsb2NrIChvciBkb2Vzbid0IG1vdmUgaXQgYXQgYWxsLCB3aGVuIGF0IHRoZSBzdGFydC9lbmQgb2ZcbiAgICAgICAgLy8gdGhlIGRvY3VtZW50KS5cbiAgICAgICAgbGV0IHsgZm9jdXNOb2RlOiBvbGROb2RlLCBmb2N1c09mZnNldDogb2xkT2ZmLCBhbmNob3JOb2RlLCBhbmNob3JPZmZzZXQgfSA9IHZpZXcuZG9tU2VsZWN0aW9uUmFuZ2UoKTtcbiAgICAgICAgbGV0IG9sZEJpZGlMZXZlbCA9IHNlbC5jYXJldEJpZGlMZXZlbCAvLyBPbmx5IGZvciBGaXJlZm94XG4gICAgICAgIDtcbiAgICAgICAgc2VsLm1vZGlmeShcIm1vdmVcIiwgZGlyLCBcImNoYXJhY3RlclwiKTtcbiAgICAgICAgbGV0IHBhcmVudERPTSA9ICRoZWFkLmRlcHRoID8gdmlldy5kb2NWaWV3LmRvbUFmdGVyUG9zKCRoZWFkLmJlZm9yZSgpKSA6IHZpZXcuZG9tO1xuICAgICAgICBsZXQgeyBmb2N1c05vZGU6IG5ld05vZGUsIGZvY3VzT2Zmc2V0OiBuZXdPZmYgfSA9IHZpZXcuZG9tU2VsZWN0aW9uUmFuZ2UoKTtcbiAgICAgICAgbGV0IHJlc3VsdCA9IG5ld05vZGUgJiYgIXBhcmVudERPTS5jb250YWlucyhuZXdOb2RlLm5vZGVUeXBlID09IDEgPyBuZXdOb2RlIDogbmV3Tm9kZS5wYXJlbnROb2RlKSB8fFxuICAgICAgICAgICAgKG9sZE5vZGUgPT0gbmV3Tm9kZSAmJiBvbGRPZmYgPT0gbmV3T2ZmKTtcbiAgICAgICAgLy8gUmVzdG9yZSB0aGUgcHJldmlvdXMgc2VsZWN0aW9uXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBzZWwuY29sbGFwc2UoYW5jaG9yTm9kZSwgYW5jaG9yT2Zmc2V0KTtcbiAgICAgICAgICAgIGlmIChvbGROb2RlICYmIChvbGROb2RlICE9IGFuY2hvck5vZGUgfHwgb2xkT2ZmICE9IGFuY2hvck9mZnNldCkgJiYgc2VsLmV4dGVuZClcbiAgICAgICAgICAgICAgICBzZWwuZXh0ZW5kKG9sZE5vZGUsIG9sZE9mZik7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKF8pIHsgfVxuICAgICAgICBpZiAob2xkQmlkaUxldmVsICE9IG51bGwpXG4gICAgICAgICAgICBzZWwuY2FyZXRCaWRpTGV2ZWwgPSBvbGRCaWRpTGV2ZWw7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSk7XG59XG5sZXQgY2FjaGVkU3RhdGUgPSBudWxsO1xubGV0IGNhY2hlZERpciA9IG51bGw7XG5sZXQgY2FjaGVkUmVzdWx0ID0gZmFsc2U7XG5mdW5jdGlvbiBlbmRPZlRleHRibG9jayh2aWV3LCBzdGF0ZSwgZGlyKSB7XG4gICAgaWYgKGNhY2hlZFN0YXRlID09IHN0YXRlICYmIGNhY2hlZERpciA9PSBkaXIpXG4gICAgICAgIHJldHVybiBjYWNoZWRSZXN1bHQ7XG4gICAgY2FjaGVkU3RhdGUgPSBzdGF0ZTtcbiAgICBjYWNoZWREaXIgPSBkaXI7XG4gICAgcmV0dXJuIGNhY2hlZFJlc3VsdCA9IGRpciA9PSBcInVwXCIgfHwgZGlyID09IFwiZG93blwiXG4gICAgICAgID8gZW5kT2ZUZXh0YmxvY2tWZXJ0aWNhbCh2aWV3LCBzdGF0ZSwgZGlyKVxuICAgICAgICA6IGVuZE9mVGV4dGJsb2NrSG9yaXpvbnRhbCh2aWV3LCBzdGF0ZSwgZGlyKTtcbn1cblxuLy8gVmlldyBkZXNjcmlwdGlvbnMgYXJlIGRhdGEgc3RydWN0dXJlcyB0aGF0IGRlc2NyaWJlIHRoZSBET00gdGhhdCBpc1xuLy8gdXNlZCB0byByZXByZXNlbnQgdGhlIGVkaXRvcidzIGNvbnRlbnQuIFRoZXkgYXJlIHVzZWQgZm9yOlxuLy9cbi8vIC0gSW5jcmVtZW50YWwgcmVkcmF3aW5nIHdoZW4gdGhlIGRvY3VtZW50IGNoYW5nZXNcbi8vXG4vLyAtIEZpZ3VyaW5nIG91dCB3aGF0IHBhcnQgb2YgdGhlIGRvY3VtZW50IGEgZ2l2ZW4gRE9NIHBvc2l0aW9uXG4vLyAgIGNvcnJlc3BvbmRzIHRvXG4vL1xuLy8gLSBXaXJpbmcgaW4gY3VzdG9tIGltcGxlbWVudGF0aW9ucyBvZiB0aGUgZWRpdGluZyBpbnRlcmZhY2UgZm9yIGFcbi8vICAgZ2l2ZW4gbm9kZVxuLy9cbi8vIFRoZXkgZm9ybSBhIGRvdWJseS1saW5rZWQgbXV0YWJsZSB0cmVlLCBzdGFydGluZyBhdCBgdmlldy5kb2NWaWV3YC5cbmNvbnN0IE5PVF9ESVJUWSA9IDAsIENISUxEX0RJUlRZID0gMSwgQ09OVEVOVF9ESVJUWSA9IDIsIE5PREVfRElSVFkgPSAzO1xuLy8gU3VwZXJjbGFzcyBmb3IgdGhlIHZhcmlvdXMga2luZHMgb2YgZGVzY3JpcHRpb25zLiBEZWZpbmVzIHRoZWlyXG4vLyBiYXNpYyBzdHJ1Y3R1cmUgYW5kIHNoYXJlZCBtZXRob2RzLlxuY2xhc3MgVmlld0Rlc2Mge1xuICAgIGNvbnN0cnVjdG9yKHBhcmVudCwgY2hpbGRyZW4sIGRvbSwgXG4gICAgLy8gVGhpcyBpcyB0aGUgbm9kZSB0aGF0IGhvbGRzIHRoZSBjaGlsZCB2aWV3cy4gSXQgbWF5IGJlIG51bGwgZm9yXG4gICAgLy8gZGVzY3MgdGhhdCBkb24ndCBoYXZlIGNoaWxkcmVuLlxuICAgIGNvbnRlbnRET00pIHtcbiAgICAgICAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7XG4gICAgICAgIHRoaXMuY2hpbGRyZW4gPSBjaGlsZHJlbjtcbiAgICAgICAgdGhpcy5kb20gPSBkb207XG4gICAgICAgIHRoaXMuY29udGVudERPTSA9IGNvbnRlbnRET007XG4gICAgICAgIHRoaXMuZGlydHkgPSBOT1RfRElSVFk7XG4gICAgICAgIC8vIEFuIGV4cGFuZG8gcHJvcGVydHkgb24gdGhlIERPTSBub2RlIHByb3ZpZGVzIGEgbGluayBiYWNrIHRvIGl0c1xuICAgICAgICAvLyBkZXNjcmlwdGlvbi5cbiAgICAgICAgZG9tLnBtVmlld0Rlc2MgPSB0aGlzO1xuICAgIH1cbiAgICAvLyBVc2VkIHRvIGNoZWNrIHdoZXRoZXIgYSBnaXZlbiBkZXNjcmlwdGlvbiBjb3JyZXNwb25kcyB0byBhXG4gICAgLy8gd2lkZ2V0L21hcmsvbm9kZS5cbiAgICBtYXRjaGVzV2lkZ2V0KHdpZGdldCkgeyByZXR1cm4gZmFsc2U7IH1cbiAgICBtYXRjaGVzTWFyayhtYXJrKSB7IHJldHVybiBmYWxzZTsgfVxuICAgIG1hdGNoZXNOb2RlKG5vZGUsIG91dGVyRGVjbywgaW5uZXJEZWNvKSB7IHJldHVybiBmYWxzZTsgfVxuICAgIG1hdGNoZXNIYWNrKG5vZGVOYW1lKSB7IHJldHVybiBmYWxzZTsgfVxuICAgIC8vIFdoZW4gcGFyc2luZyBpbi1lZGl0b3IgY29udGVudCAoaW4gZG9tY2hhbmdlLmpzKSwgd2UgYWxsb3dcbiAgICAvLyBkZXNjcmlwdGlvbnMgdG8gZGV0ZXJtaW5lIHRoZSBwYXJzZSBydWxlcyB0aGF0IHNob3VsZCBiZSB1c2VkIHRvXG4gICAgLy8gcGFyc2UgdGhlbS5cbiAgICBwYXJzZVJ1bGUoKSB7IHJldHVybiBudWxsOyB9XG4gICAgLy8gVXNlZCBieSB0aGUgZWRpdG9yJ3MgZXZlbnQgaGFuZGxlciB0byBpZ25vcmUgZXZlbnRzIHRoYXQgY29tZVxuICAgIC8vIGZyb20gY2VydGFpbiBkZXNjcy5cbiAgICBzdG9wRXZlbnQoZXZlbnQpIHsgcmV0dXJuIGZhbHNlOyB9XG4gICAgLy8gVGhlIHNpemUgb2YgdGhlIGNvbnRlbnQgcmVwcmVzZW50ZWQgYnkgdGhpcyBkZXNjLlxuICAgIGdldCBzaXplKCkge1xuICAgICAgICBsZXQgc2l6ZSA9IDA7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5jaGlsZHJlbi5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIHNpemUgKz0gdGhpcy5jaGlsZHJlbltpXS5zaXplO1xuICAgICAgICByZXR1cm4gc2l6ZTtcbiAgICB9XG4gICAgLy8gRm9yIGJsb2NrIG5vZGVzLCB0aGlzIHJlcHJlc2VudHMgdGhlIHNwYWNlIHRha2VuIHVwIGJ5IHRoZWlyXG4gICAgLy8gc3RhcnQvZW5kIHRva2Vucy5cbiAgICBnZXQgYm9yZGVyKCkgeyByZXR1cm4gMDsgfVxuICAgIGRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMucGFyZW50ID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAodGhpcy5kb20ucG1WaWV3RGVzYyA9PSB0aGlzKVxuICAgICAgICAgICAgdGhpcy5kb20ucG1WaWV3RGVzYyA9IHVuZGVmaW5lZDtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmNoaWxkcmVuLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgdGhpcy5jaGlsZHJlbltpXS5kZXN0cm95KCk7XG4gICAgfVxuICAgIHBvc0JlZm9yZUNoaWxkKGNoaWxkKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBwb3MgPSB0aGlzLnBvc0F0U3RhcnQ7OyBpKyspIHtcbiAgICAgICAgICAgIGxldCBjdXIgPSB0aGlzLmNoaWxkcmVuW2ldO1xuICAgICAgICAgICAgaWYgKGN1ciA9PSBjaGlsZClcbiAgICAgICAgICAgICAgICByZXR1cm4gcG9zO1xuICAgICAgICAgICAgcG9zICs9IGN1ci5zaXplO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBwb3NCZWZvcmUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBhcmVudC5wb3NCZWZvcmVDaGlsZCh0aGlzKTtcbiAgICB9XG4gICAgZ2V0IHBvc0F0U3RhcnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBhcmVudCA/IHRoaXMucGFyZW50LnBvc0JlZm9yZUNoaWxkKHRoaXMpICsgdGhpcy5ib3JkZXIgOiAwO1xuICAgIH1cbiAgICBnZXQgcG9zQWZ0ZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBvc0JlZm9yZSArIHRoaXMuc2l6ZTtcbiAgICB9XG4gICAgZ2V0IHBvc0F0RW5kKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wb3NBdFN0YXJ0ICsgdGhpcy5zaXplIC0gMiAqIHRoaXMuYm9yZGVyO1xuICAgIH1cbiAgICBsb2NhbFBvc0Zyb21ET00oZG9tLCBvZmZzZXQsIGJpYXMpIHtcbiAgICAgICAgLy8gSWYgdGhlIERPTSBwb3NpdGlvbiBpcyBpbiB0aGUgY29udGVudCwgdXNlIHRoZSBjaGlsZCBkZXNjIGFmdGVyXG4gICAgICAgIC8vIGl0IHRvIGZpZ3VyZSBvdXQgYSBwb3NpdGlvbi5cbiAgICAgICAgaWYgKHRoaXMuY29udGVudERPTSAmJiB0aGlzLmNvbnRlbnRET00uY29udGFpbnMoZG9tLm5vZGVUeXBlID09IDEgPyBkb20gOiBkb20ucGFyZW50Tm9kZSkpIHtcbiAgICAgICAgICAgIGlmIChiaWFzIDwgMCkge1xuICAgICAgICAgICAgICAgIGxldCBkb21CZWZvcmUsIGRlc2M7XG4gICAgICAgICAgICAgICAgaWYgKGRvbSA9PSB0aGlzLmNvbnRlbnRET00pIHtcbiAgICAgICAgICAgICAgICAgICAgZG9tQmVmb3JlID0gZG9tLmNoaWxkTm9kZXNbb2Zmc2V0IC0gMV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB3aGlsZSAoZG9tLnBhcmVudE5vZGUgIT0gdGhpcy5jb250ZW50RE9NKVxuICAgICAgICAgICAgICAgICAgICAgICAgZG9tID0gZG9tLnBhcmVudE5vZGU7XG4gICAgICAgICAgICAgICAgICAgIGRvbUJlZm9yZSA9IGRvbS5wcmV2aW91c1NpYmxpbmc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHdoaWxlIChkb21CZWZvcmUgJiYgISgoZGVzYyA9IGRvbUJlZm9yZS5wbVZpZXdEZXNjKSAmJiBkZXNjLnBhcmVudCA9PSB0aGlzKSlcbiAgICAgICAgICAgICAgICAgICAgZG9tQmVmb3JlID0gZG9tQmVmb3JlLnByZXZpb3VzU2libGluZztcbiAgICAgICAgICAgICAgICByZXR1cm4gZG9tQmVmb3JlID8gdGhpcy5wb3NCZWZvcmVDaGlsZChkZXNjKSArIGRlc2Muc2l6ZSA6IHRoaXMucG9zQXRTdGFydDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGxldCBkb21BZnRlciwgZGVzYztcbiAgICAgICAgICAgICAgICBpZiAoZG9tID09IHRoaXMuY29udGVudERPTSkge1xuICAgICAgICAgICAgICAgICAgICBkb21BZnRlciA9IGRvbS5jaGlsZE5vZGVzW29mZnNldF07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB3aGlsZSAoZG9tLnBhcmVudE5vZGUgIT0gdGhpcy5jb250ZW50RE9NKVxuICAgICAgICAgICAgICAgICAgICAgICAgZG9tID0gZG9tLnBhcmVudE5vZGU7XG4gICAgICAgICAgICAgICAgICAgIGRvbUFmdGVyID0gZG9tLm5leHRTaWJsaW5nO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB3aGlsZSAoZG9tQWZ0ZXIgJiYgISgoZGVzYyA9IGRvbUFmdGVyLnBtVmlld0Rlc2MpICYmIGRlc2MucGFyZW50ID09IHRoaXMpKVxuICAgICAgICAgICAgICAgICAgICBkb21BZnRlciA9IGRvbUFmdGVyLm5leHRTaWJsaW5nO1xuICAgICAgICAgICAgICAgIHJldHVybiBkb21BZnRlciA/IHRoaXMucG9zQmVmb3JlQ2hpbGQoZGVzYykgOiB0aGlzLnBvc0F0RW5kO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIE90aGVyd2lzZSwgdXNlIHZhcmlvdXMgaGV1cmlzdGljcywgZmFsbGluZyBiYWNrIG9uIHRoZSBiaWFzXG4gICAgICAgIC8vIHBhcmFtZXRlciwgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdG8gcmV0dXJuIHRoZSBwb3NpdGlvbiBhdCB0aGVcbiAgICAgICAgLy8gc3RhcnQgb3IgYXQgdGhlIGVuZCBvZiB0aGlzIHZpZXcgZGVzYy5cbiAgICAgICAgbGV0IGF0RW5kO1xuICAgICAgICBpZiAoZG9tID09IHRoaXMuZG9tICYmIHRoaXMuY29udGVudERPTSkge1xuICAgICAgICAgICAgYXRFbmQgPSBvZmZzZXQgPiBkb21JbmRleCh0aGlzLmNvbnRlbnRET00pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHRoaXMuY29udGVudERPTSAmJiB0aGlzLmNvbnRlbnRET00gIT0gdGhpcy5kb20gJiYgdGhpcy5kb20uY29udGFpbnModGhpcy5jb250ZW50RE9NKSkge1xuICAgICAgICAgICAgYXRFbmQgPSBkb20uY29tcGFyZURvY3VtZW50UG9zaXRpb24odGhpcy5jb250ZW50RE9NKSAmIDI7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5kb20uZmlyc3RDaGlsZCkge1xuICAgICAgICAgICAgaWYgKG9mZnNldCA9PSAwKVxuICAgICAgICAgICAgICAgIGZvciAobGV0IHNlYXJjaCA9IGRvbTs7IHNlYXJjaCA9IHNlYXJjaC5wYXJlbnROb2RlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWFyY2ggPT0gdGhpcy5kb20pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF0RW5kID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VhcmNoLnByZXZpb3VzU2libGluZylcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChhdEVuZCA9PSBudWxsICYmIG9mZnNldCA9PSBkb20uY2hpbGROb2Rlcy5sZW5ndGgpXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgc2VhcmNoID0gZG9tOzsgc2VhcmNoID0gc2VhcmNoLnBhcmVudE5vZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlYXJjaCA9PSB0aGlzLmRvbSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXRFbmQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlYXJjaC5uZXh0U2libGluZylcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKGF0RW5kID09IG51bGwgPyBiaWFzID4gMCA6IGF0RW5kKSA/IHRoaXMucG9zQXRFbmQgOiB0aGlzLnBvc0F0U3RhcnQ7XG4gICAgfVxuICAgIG5lYXJlc3REZXNjKGRvbSwgb25seU5vZGVzID0gZmFsc2UpIHtcbiAgICAgICAgZm9yIChsZXQgZmlyc3QgPSB0cnVlLCBjdXIgPSBkb207IGN1cjsgY3VyID0gY3VyLnBhcmVudE5vZGUpIHtcbiAgICAgICAgICAgIGxldCBkZXNjID0gdGhpcy5nZXREZXNjKGN1ciksIG5vZGVET007XG4gICAgICAgICAgICBpZiAoZGVzYyAmJiAoIW9ubHlOb2RlcyB8fCBkZXNjLm5vZGUpKSB7XG4gICAgICAgICAgICAgICAgLy8gSWYgZG9tIGlzIG91dHNpZGUgb2YgdGhpcyBkZXNjJ3Mgbm9kZURPTSwgZG9uJ3QgY291bnQgaXQuXG4gICAgICAgICAgICAgICAgaWYgKGZpcnN0ICYmIChub2RlRE9NID0gZGVzYy5ub2RlRE9NKSAmJlxuICAgICAgICAgICAgICAgICAgICAhKG5vZGVET00ubm9kZVR5cGUgPT0gMSA/IG5vZGVET00uY29udGFpbnMoZG9tLm5vZGVUeXBlID09IDEgPyBkb20gOiBkb20ucGFyZW50Tm9kZSkgOiBub2RlRE9NID09IGRvbSkpXG4gICAgICAgICAgICAgICAgICAgIGZpcnN0ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGVzYztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXREZXNjKGRvbSkge1xuICAgICAgICBsZXQgZGVzYyA9IGRvbS5wbVZpZXdEZXNjO1xuICAgICAgICBmb3IgKGxldCBjdXIgPSBkZXNjOyBjdXI7IGN1ciA9IGN1ci5wYXJlbnQpXG4gICAgICAgICAgICBpZiAoY3VyID09IHRoaXMpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGRlc2M7XG4gICAgfVxuICAgIHBvc0Zyb21ET00oZG9tLCBvZmZzZXQsIGJpYXMpIHtcbiAgICAgICAgZm9yIChsZXQgc2NhbiA9IGRvbTsgc2Nhbjsgc2NhbiA9IHNjYW4ucGFyZW50Tm9kZSkge1xuICAgICAgICAgICAgbGV0IGRlc2MgPSB0aGlzLmdldERlc2Moc2Nhbik7XG4gICAgICAgICAgICBpZiAoZGVzYylcbiAgICAgICAgICAgICAgICByZXR1cm4gZGVzYy5sb2NhbFBvc0Zyb21ET00oZG9tLCBvZmZzZXQsIGJpYXMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAtMTtcbiAgICB9XG4gICAgLy8gRmluZCB0aGUgZGVzYyBmb3IgdGhlIG5vZGUgYWZ0ZXIgdGhlIGdpdmVuIHBvcywgaWYgYW55LiAoV2hlbiBhXG4gICAgLy8gcGFyZW50IG5vZGUgb3ZlcnJvZGUgcmVuZGVyaW5nLCB0aGVyZSBtaWdodCBub3QgYmUgb25lLilcbiAgICBkZXNjQXQocG9zKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwLCBvZmZzZXQgPSAwOyBpIDwgdGhpcy5jaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IGNoaWxkID0gdGhpcy5jaGlsZHJlbltpXSwgZW5kID0gb2Zmc2V0ICsgY2hpbGQuc2l6ZTtcbiAgICAgICAgICAgIGlmIChvZmZzZXQgPT0gcG9zICYmIGVuZCAhPSBvZmZzZXQpIHtcbiAgICAgICAgICAgICAgICB3aGlsZSAoIWNoaWxkLmJvcmRlciAmJiBjaGlsZC5jaGlsZHJlbi5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGlsZC5jaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGlubmVyID0gY2hpbGQuY2hpbGRyZW5baV07XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5uZXIuc2l6ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkID0gaW5uZXI7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNoaWxkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHBvcyA8IGVuZClcbiAgICAgICAgICAgICAgICByZXR1cm4gY2hpbGQuZGVzY0F0KHBvcyAtIG9mZnNldCAtIGNoaWxkLmJvcmRlcik7XG4gICAgICAgICAgICBvZmZzZXQgPSBlbmQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZG9tRnJvbVBvcyhwb3MsIHNpZGUpIHtcbiAgICAgICAgaWYgKCF0aGlzLmNvbnRlbnRET00pXG4gICAgICAgICAgICByZXR1cm4geyBub2RlOiB0aGlzLmRvbSwgb2Zmc2V0OiAwLCBhdG9tOiBwb3MgKyAxIH07XG4gICAgICAgIC8vIEZpcnN0IGZpbmQgdGhlIHBvc2l0aW9uIGluIHRoZSBjaGlsZCBhcnJheVxuICAgICAgICBsZXQgaSA9IDAsIG9mZnNldCA9IDA7XG4gICAgICAgIGZvciAobGV0IGN1clBvcyA9IDA7IGkgPCB0aGlzLmNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgY2hpbGQgPSB0aGlzLmNoaWxkcmVuW2ldLCBlbmQgPSBjdXJQb3MgKyBjaGlsZC5zaXplO1xuICAgICAgICAgICAgaWYgKGVuZCA+IHBvcyB8fCBjaGlsZCBpbnN0YW5jZW9mIFRyYWlsaW5nSGFja1ZpZXdEZXNjKSB7XG4gICAgICAgICAgICAgICAgb2Zmc2V0ID0gcG9zIC0gY3VyUG9zO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY3VyUG9zID0gZW5kO1xuICAgICAgICB9XG4gICAgICAgIC8vIElmIHRoaXMgcG9pbnRzIGludG8gdGhlIG1pZGRsZSBvZiBhIGNoaWxkLCBjYWxsIHRocm91Z2hcbiAgICAgICAgaWYgKG9mZnNldClcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNoaWxkcmVuW2ldLmRvbUZyb21Qb3Mob2Zmc2V0IC0gdGhpcy5jaGlsZHJlbltpXS5ib3JkZXIsIHNpZGUpO1xuICAgICAgICAvLyBHbyBiYWNrIGlmIHRoZXJlIHdlcmUgYW55IHplcm8tbGVuZ3RoIHdpZGdldHMgd2l0aCBzaWRlID49IDAgYmVmb3JlIHRoaXMgcG9pbnRcbiAgICAgICAgZm9yIChsZXQgcHJldjsgaSAmJiAhKHByZXYgPSB0aGlzLmNoaWxkcmVuW2kgLSAxXSkuc2l6ZSAmJiBwcmV2IGluc3RhbmNlb2YgV2lkZ2V0Vmlld0Rlc2MgJiYgcHJldi5zaWRlID49IDA7IGktLSkgeyB9XG4gICAgICAgIC8vIFNjYW4gdG93YXJkcyB0aGUgZmlyc3QgdXNlYWJsZSBub2RlXG4gICAgICAgIGlmIChzaWRlIDw9IDApIHtcbiAgICAgICAgICAgIGxldCBwcmV2LCBlbnRlciA9IHRydWU7XG4gICAgICAgICAgICBmb3IgKDs7IGktLSwgZW50ZXIgPSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIHByZXYgPSBpID8gdGhpcy5jaGlsZHJlbltpIC0gMV0gOiBudWxsO1xuICAgICAgICAgICAgICAgIGlmICghcHJldiB8fCBwcmV2LmRvbS5wYXJlbnROb2RlID09IHRoaXMuY29udGVudERPTSlcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocHJldiAmJiBzaWRlICYmIGVudGVyICYmICFwcmV2LmJvcmRlciAmJiAhcHJldi5kb21BdG9tKVxuICAgICAgICAgICAgICAgIHJldHVybiBwcmV2LmRvbUZyb21Qb3MocHJldi5zaXplLCBzaWRlKTtcbiAgICAgICAgICAgIHJldHVybiB7IG5vZGU6IHRoaXMuY29udGVudERPTSwgb2Zmc2V0OiBwcmV2ID8gZG9tSW5kZXgocHJldi5kb20pICsgMSA6IDAgfTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGxldCBuZXh0LCBlbnRlciA9IHRydWU7XG4gICAgICAgICAgICBmb3IgKDs7IGkrKywgZW50ZXIgPSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIG5leHQgPSBpIDwgdGhpcy5jaGlsZHJlbi5sZW5ndGggPyB0aGlzLmNoaWxkcmVuW2ldIDogbnVsbDtcbiAgICAgICAgICAgICAgICBpZiAoIW5leHQgfHwgbmV4dC5kb20ucGFyZW50Tm9kZSA9PSB0aGlzLmNvbnRlbnRET00pXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG5leHQgJiYgZW50ZXIgJiYgIW5leHQuYm9yZGVyICYmICFuZXh0LmRvbUF0b20pXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5leHQuZG9tRnJvbVBvcygwLCBzaWRlKTtcbiAgICAgICAgICAgIHJldHVybiB7IG5vZGU6IHRoaXMuY29udGVudERPTSwgb2Zmc2V0OiBuZXh0ID8gZG9tSW5kZXgobmV4dC5kb20pIDogdGhpcy5jb250ZW50RE9NLmNoaWxkTm9kZXMubGVuZ3RoIH07XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gVXNlZCB0byBmaW5kIGEgRE9NIHJhbmdlIGluIGEgc2luZ2xlIHBhcmVudCBmb3IgYSBnaXZlbiBjaGFuZ2VkXG4gICAgLy8gcmFuZ2UuXG4gICAgcGFyc2VSYW5nZShmcm9tLCB0bywgYmFzZSA9IDApIHtcbiAgICAgICAgaWYgKHRoaXMuY2hpbGRyZW4ubGVuZ3RoID09IDApXG4gICAgICAgICAgICByZXR1cm4geyBub2RlOiB0aGlzLmNvbnRlbnRET00sIGZyb20sIHRvLCBmcm9tT2Zmc2V0OiAwLCB0b09mZnNldDogdGhpcy5jb250ZW50RE9NLmNoaWxkTm9kZXMubGVuZ3RoIH07XG4gICAgICAgIGxldCBmcm9tT2Zmc2V0ID0gLTEsIHRvT2Zmc2V0ID0gLTE7XG4gICAgICAgIGZvciAobGV0IG9mZnNldCA9IGJhc2UsIGkgPSAwOzsgaSsrKSB7XG4gICAgICAgICAgICBsZXQgY2hpbGQgPSB0aGlzLmNoaWxkcmVuW2ldLCBlbmQgPSBvZmZzZXQgKyBjaGlsZC5zaXplO1xuICAgICAgICAgICAgaWYgKGZyb21PZmZzZXQgPT0gLTEgJiYgZnJvbSA8PSBlbmQpIHtcbiAgICAgICAgICAgICAgICBsZXQgY2hpbGRCYXNlID0gb2Zmc2V0ICsgY2hpbGQuYm9yZGVyO1xuICAgICAgICAgICAgICAgIC8vIEZJWE1FIG1heWJlIGRlc2NlbmQgbWFyayB2aWV3cyB0byBwYXJzZSBhIG5hcnJvd2VyIHJhbmdlP1xuICAgICAgICAgICAgICAgIGlmIChmcm9tID49IGNoaWxkQmFzZSAmJiB0byA8PSBlbmQgLSBjaGlsZC5ib3JkZXIgJiYgY2hpbGQubm9kZSAmJlxuICAgICAgICAgICAgICAgICAgICBjaGlsZC5jb250ZW50RE9NICYmIHRoaXMuY29udGVudERPTS5jb250YWlucyhjaGlsZC5jb250ZW50RE9NKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNoaWxkLnBhcnNlUmFuZ2UoZnJvbSwgdG8sIGNoaWxkQmFzZSk7XG4gICAgICAgICAgICAgICAgZnJvbSA9IG9mZnNldDtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gaTsgaiA+IDA7IGotLSkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgcHJldiA9IHRoaXMuY2hpbGRyZW5baiAtIDFdO1xuICAgICAgICAgICAgICAgICAgICBpZiAocHJldi5zaXplICYmIHByZXYuZG9tLnBhcmVudE5vZGUgPT0gdGhpcy5jb250ZW50RE9NICYmICFwcmV2LmVtcHR5Q2hpbGRBdCgxKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZnJvbU9mZnNldCA9IGRvbUluZGV4KHByZXYuZG9tKSArIDE7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBmcm9tIC09IHByZXYuc2l6ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGZyb21PZmZzZXQgPT0gLTEpXG4gICAgICAgICAgICAgICAgICAgIGZyb21PZmZzZXQgPSAwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGZyb21PZmZzZXQgPiAtMSAmJiAoZW5kID4gdG8gfHwgaSA9PSB0aGlzLmNoaWxkcmVuLmxlbmd0aCAtIDEpKSB7XG4gICAgICAgICAgICAgICAgdG8gPSBlbmQ7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IGkgKyAxOyBqIDwgdGhpcy5jaGlsZHJlbi5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAgICAgICBsZXQgbmV4dCA9IHRoaXMuY2hpbGRyZW5bal07XG4gICAgICAgICAgICAgICAgICAgIGlmIChuZXh0LnNpemUgJiYgbmV4dC5kb20ucGFyZW50Tm9kZSA9PSB0aGlzLmNvbnRlbnRET00gJiYgIW5leHQuZW1wdHlDaGlsZEF0KC0xKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdG9PZmZzZXQgPSBkb21JbmRleChuZXh0LmRvbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0byArPSBuZXh0LnNpemU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0b09mZnNldCA9PSAtMSlcbiAgICAgICAgICAgICAgICAgICAgdG9PZmZzZXQgPSB0aGlzLmNvbnRlbnRET00uY2hpbGROb2Rlcy5sZW5ndGg7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBvZmZzZXQgPSBlbmQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgbm9kZTogdGhpcy5jb250ZW50RE9NLCBmcm9tLCB0bywgZnJvbU9mZnNldCwgdG9PZmZzZXQgfTtcbiAgICB9XG4gICAgZW1wdHlDaGlsZEF0KHNpZGUpIHtcbiAgICAgICAgaWYgKHRoaXMuYm9yZGVyIHx8ICF0aGlzLmNvbnRlbnRET00gfHwgIXRoaXMuY2hpbGRyZW4ubGVuZ3RoKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBsZXQgY2hpbGQgPSB0aGlzLmNoaWxkcmVuW3NpZGUgPCAwID8gMCA6IHRoaXMuY2hpbGRyZW4ubGVuZ3RoIC0gMV07XG4gICAgICAgIHJldHVybiBjaGlsZC5zaXplID09IDAgfHwgY2hpbGQuZW1wdHlDaGlsZEF0KHNpZGUpO1xuICAgIH1cbiAgICBkb21BZnRlclBvcyhwb3MpIHtcbiAgICAgICAgbGV0IHsgbm9kZSwgb2Zmc2V0IH0gPSB0aGlzLmRvbUZyb21Qb3MocG9zLCAwKTtcbiAgICAgICAgaWYgKG5vZGUubm9kZVR5cGUgIT0gMSB8fCBvZmZzZXQgPT0gbm9kZS5jaGlsZE5vZGVzLmxlbmd0aClcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFwiTm8gbm9kZSBhZnRlciBwb3MgXCIgKyBwb3MpO1xuICAgICAgICByZXR1cm4gbm9kZS5jaGlsZE5vZGVzW29mZnNldF07XG4gICAgfVxuICAgIC8vIFZpZXcgZGVzY3MgYXJlIHJlc3BvbnNpYmxlIGZvciBzZXR0aW5nIGFueSBzZWxlY3Rpb24gdGhhdCBmYWxsc1xuICAgIC8vIGVudGlyZWx5IGluc2lkZSBvZiB0aGVtLCBzbyB0aGF0IGN1c3RvbSBpbXBsZW1lbnRhdGlvbnMgY2FuIGRvXG4gICAgLy8gY3VzdG9tIHRoaW5ncyB3aXRoIHRoZSBzZWxlY3Rpb24uIE5vdGUgdGhhdCB0aGlzIGZhbGxzIGFwYXJ0IHdoZW5cbiAgICAvLyBhIHNlbGVjdGlvbiBzdGFydHMgaW4gc3VjaCBhIG5vZGUgYW5kIGVuZHMgaW4gYW5vdGhlciwgaW4gd2hpY2hcbiAgICAvLyBjYXNlIHdlIGp1c3QgdXNlIHdoYXRldmVyIGRvbUZyb21Qb3MgcHJvZHVjZXMgYXMgYSBiZXN0IGVmZm9ydC5cbiAgICBzZXRTZWxlY3Rpb24oYW5jaG9yLCBoZWFkLCB2aWV3LCBmb3JjZSA9IGZhbHNlKSB7XG4gICAgICAgIC8vIElmIHRoZSBzZWxlY3Rpb24gZmFsbHMgZW50aXJlbHkgaW4gYSBjaGlsZCwgZ2l2ZSBpdCB0byB0aGF0IGNoaWxkXG4gICAgICAgIGxldCBmcm9tID0gTWF0aC5taW4oYW5jaG9yLCBoZWFkKSwgdG8gPSBNYXRoLm1heChhbmNob3IsIGhlYWQpO1xuICAgICAgICBmb3IgKGxldCBpID0gMCwgb2Zmc2V0ID0gMDsgaSA8IHRoaXMuY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBjaGlsZCA9IHRoaXMuY2hpbGRyZW5baV0sIGVuZCA9IG9mZnNldCArIGNoaWxkLnNpemU7XG4gICAgICAgICAgICBpZiAoZnJvbSA+IG9mZnNldCAmJiB0byA8IGVuZClcbiAgICAgICAgICAgICAgICByZXR1cm4gY2hpbGQuc2V0U2VsZWN0aW9uKGFuY2hvciAtIG9mZnNldCAtIGNoaWxkLmJvcmRlciwgaGVhZCAtIG9mZnNldCAtIGNoaWxkLmJvcmRlciwgdmlldywgZm9yY2UpO1xuICAgICAgICAgICAgb2Zmc2V0ID0gZW5kO1xuICAgICAgICB9XG4gICAgICAgIGxldCBhbmNob3JET00gPSB0aGlzLmRvbUZyb21Qb3MoYW5jaG9yLCBhbmNob3IgPyAtMSA6IDEpO1xuICAgICAgICBsZXQgaGVhZERPTSA9IGhlYWQgPT0gYW5jaG9yID8gYW5jaG9yRE9NIDogdGhpcy5kb21Gcm9tUG9zKGhlYWQsIGhlYWQgPyAtMSA6IDEpO1xuICAgICAgICBsZXQgZG9tU2VsID0gdmlldy5yb290LmdldFNlbGVjdGlvbigpO1xuICAgICAgICBsZXQgc2VsUmFuZ2UgPSB2aWV3LmRvbVNlbGVjdGlvblJhbmdlKCk7XG4gICAgICAgIGxldCBicktsdWRnZSA9IGZhbHNlO1xuICAgICAgICAvLyBPbiBGaXJlZm94LCB1c2luZyBTZWxlY3Rpb24uY29sbGFwc2UgdG8gcHV0IHRoZSBjdXJzb3IgYWZ0ZXIgYVxuICAgICAgICAvLyBCUiBub2RlIGZvciBzb21lIHJlYXNvbiBkb2Vzbid0IGFsd2F5cyB3b3JrICgjMTA3MykuIE9uIFNhZmFyaSxcbiAgICAgICAgLy8gdGhlIGN1cnNvciBzb21ldGltZXMgaW5leHBsaWNhYmxlIHZpc3VhbGx5IGxhZ3MgYmVoaW5kIGl0c1xuICAgICAgICAvLyByZXBvcnRlZCBwb3NpdGlvbiBpbiBzdWNoIHNpdHVhdGlvbnMgKCMxMDkyKS5cbiAgICAgICAgaWYgKChnZWNrbyB8fCBzYWZhcmkpICYmIGFuY2hvciA9PSBoZWFkKSB7XG4gICAgICAgICAgICBsZXQgeyBub2RlLCBvZmZzZXQgfSA9IGFuY2hvckRPTTtcbiAgICAgICAgICAgIGlmIChub2RlLm5vZGVUeXBlID09IDMpIHtcbiAgICAgICAgICAgICAgICBicktsdWRnZSA9ICEhKG9mZnNldCAmJiBub2RlLm5vZGVWYWx1ZVtvZmZzZXQgLSAxXSA9PSBcIlxcblwiKTtcbiAgICAgICAgICAgICAgICAvLyBJc3N1ZSAjMTEyOFxuICAgICAgICAgICAgICAgIGlmIChicktsdWRnZSAmJiBvZmZzZXQgPT0gbm9kZS5ub2RlVmFsdWUubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IHNjYW4gPSBub2RlLCBhZnRlcjsgc2Nhbjsgc2NhbiA9IHNjYW4ucGFyZW50Tm9kZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFmdGVyID0gc2Nhbi5uZXh0U2libGluZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhZnRlci5ub2RlTmFtZSA9PSBcIkJSXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuY2hvckRPTSA9IGhlYWRET00gPSB7IG5vZGU6IGFmdGVyLnBhcmVudE5vZGUsIG9mZnNldDogZG9tSW5kZXgoYWZ0ZXIpICsgMSB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGRlc2MgPSBzY2FuLnBtVmlld0Rlc2M7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZGVzYyAmJiBkZXNjLm5vZGUgJiYgZGVzYy5ub2RlLmlzQmxvY2spXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBsZXQgcHJldiA9IG5vZGUuY2hpbGROb2Rlc1tvZmZzZXQgLSAxXTtcbiAgICAgICAgICAgICAgICBicktsdWRnZSA9IHByZXYgJiYgKHByZXYubm9kZU5hbWUgPT0gXCJCUlwiIHx8IHByZXYuY29udGVudEVkaXRhYmxlID09IFwiZmFsc2VcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gRmlyZWZveCBjYW4gYWN0IHN0cmFuZ2VseSB3aGVuIHRoZSBzZWxlY3Rpb24gaXMgaW4gZnJvbnQgb2YgYW5cbiAgICAgICAgLy8gdW5lZGl0YWJsZSBub2RlLiBTZWUgIzExNjMgYW5kIGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTE3MDk1MzZcbiAgICAgICAgaWYgKGdlY2tvICYmIHNlbFJhbmdlLmZvY3VzTm9kZSAmJiBzZWxSYW5nZS5mb2N1c05vZGUgIT0gaGVhZERPTS5ub2RlICYmIHNlbFJhbmdlLmZvY3VzTm9kZS5ub2RlVHlwZSA9PSAxKSB7XG4gICAgICAgICAgICBsZXQgYWZ0ZXIgPSBzZWxSYW5nZS5mb2N1c05vZGUuY2hpbGROb2Rlc1tzZWxSYW5nZS5mb2N1c09mZnNldF07XG4gICAgICAgICAgICBpZiAoYWZ0ZXIgJiYgYWZ0ZXIuY29udGVudEVkaXRhYmxlID09IFwiZmFsc2VcIilcbiAgICAgICAgICAgICAgICBmb3JjZSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEoZm9yY2UgfHwgYnJLbHVkZ2UgJiYgc2FmYXJpKSAmJlxuICAgICAgICAgICAgaXNFcXVpdmFsZW50UG9zaXRpb24oYW5jaG9yRE9NLm5vZGUsIGFuY2hvckRPTS5vZmZzZXQsIHNlbFJhbmdlLmFuY2hvck5vZGUsIHNlbFJhbmdlLmFuY2hvck9mZnNldCkgJiZcbiAgICAgICAgICAgIGlzRXF1aXZhbGVudFBvc2l0aW9uKGhlYWRET00ubm9kZSwgaGVhZERPTS5vZmZzZXQsIHNlbFJhbmdlLmZvY3VzTm9kZSwgc2VsUmFuZ2UuZm9jdXNPZmZzZXQpKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAvLyBTZWxlY3Rpb24uZXh0ZW5kIGNhbiBiZSB1c2VkIHRvIGNyZWF0ZSBhbiAnaW52ZXJ0ZWQnIHNlbGVjdGlvblxuICAgICAgICAvLyAob25lIHdoZXJlIHRoZSBmb2N1cyBpcyBiZWZvcmUgdGhlIGFuY2hvciksIGJ1dCBub3QgYWxsXG4gICAgICAgIC8vIGJyb3dzZXJzIHN1cHBvcnQgaXQgeWV0LlxuICAgICAgICBsZXQgZG9tU2VsRXh0ZW5kZWQgPSBmYWxzZTtcbiAgICAgICAgaWYgKChkb21TZWwuZXh0ZW5kIHx8IGFuY2hvciA9PSBoZWFkKSAmJiAhYnJLbHVkZ2UpIHtcbiAgICAgICAgICAgIGRvbVNlbC5jb2xsYXBzZShhbmNob3JET00ubm9kZSwgYW5jaG9yRE9NLm9mZnNldCk7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmIChhbmNob3IgIT0gaGVhZClcbiAgICAgICAgICAgICAgICAgICAgZG9tU2VsLmV4dGVuZChoZWFkRE9NLm5vZGUsIGhlYWRET00ub2Zmc2V0KTtcbiAgICAgICAgICAgICAgICBkb21TZWxFeHRlbmRlZCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoXykge1xuICAgICAgICAgICAgICAgIC8vIEluIHNvbWUgY2FzZXMgd2l0aCBDaHJvbWUgdGhlIHNlbGVjdGlvbiBpcyBlbXB0eSBhZnRlciBjYWxsaW5nXG4gICAgICAgICAgICAgICAgLy8gY29sbGFwc2UsIGV2ZW4gd2hlbiBpdCBzaG91bGQgYmUgdmFsaWQuIFRoaXMgYXBwZWFycyB0byBiZSBhIGJ1ZywgYnV0XG4gICAgICAgICAgICAgICAgLy8gaXQgaXMgZGlmZmljdWx0IHRvIGlzb2xhdGUuIElmIHRoaXMgaGFwcGVucyBmYWxsYmFjayB0byB0aGUgb2xkIHBhdGhcbiAgICAgICAgICAgICAgICAvLyB3aXRob3V0IHVzaW5nIGV4dGVuZC5cbiAgICAgICAgICAgICAgICAvLyBTaW1pbGFybHksIHRoaXMgY291bGQgY3Jhc2ggb24gU2FmYXJpIGlmIHRoZSBlZGl0b3IgaXMgaGlkZGVuLCBhbmRcbiAgICAgICAgICAgICAgICAvLyB0aGVyZSB3YXMgbm8gc2VsZWN0aW9uLlxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICghZG9tU2VsRXh0ZW5kZWQpIHtcbiAgICAgICAgICAgIGlmIChhbmNob3IgPiBoZWFkKSB7XG4gICAgICAgICAgICAgICAgbGV0IHRtcCA9IGFuY2hvckRPTTtcbiAgICAgICAgICAgICAgICBhbmNob3JET00gPSBoZWFkRE9NO1xuICAgICAgICAgICAgICAgIGhlYWRET00gPSB0bXA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgcmFuZ2UgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpO1xuICAgICAgICAgICAgcmFuZ2Uuc2V0RW5kKGhlYWRET00ubm9kZSwgaGVhZERPTS5vZmZzZXQpO1xuICAgICAgICAgICAgcmFuZ2Uuc2V0U3RhcnQoYW5jaG9yRE9NLm5vZGUsIGFuY2hvckRPTS5vZmZzZXQpO1xuICAgICAgICAgICAgZG9tU2VsLnJlbW92ZUFsbFJhbmdlcygpO1xuICAgICAgICAgICAgZG9tU2VsLmFkZFJhbmdlKHJhbmdlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZ25vcmVNdXRhdGlvbihtdXRhdGlvbikge1xuICAgICAgICByZXR1cm4gIXRoaXMuY29udGVudERPTSAmJiBtdXRhdGlvbi50eXBlICE9IFwic2VsZWN0aW9uXCI7XG4gICAgfVxuICAgIGdldCBjb250ZW50TG9zdCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGVudERPTSAmJiB0aGlzLmNvbnRlbnRET00gIT0gdGhpcy5kb20gJiYgIXRoaXMuZG9tLmNvbnRhaW5zKHRoaXMuY29udGVudERPTSk7XG4gICAgfVxuICAgIC8vIFJlbW92ZSBhIHN1YnRyZWUgb2YgdGhlIGVsZW1lbnQgdHJlZSB0aGF0IGhhcyBiZWVuIHRvdWNoZWRcbiAgICAvLyBieSBhIERPTSBjaGFuZ2UsIHNvIHRoYXQgdGhlIG5leHQgdXBkYXRlIHdpbGwgcmVkcmF3IGl0LlxuICAgIG1hcmtEaXJ0eShmcm9tLCB0bykge1xuICAgICAgICBmb3IgKGxldCBvZmZzZXQgPSAwLCBpID0gMDsgaSA8IHRoaXMuY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBjaGlsZCA9IHRoaXMuY2hpbGRyZW5baV0sIGVuZCA9IG9mZnNldCArIGNoaWxkLnNpemU7XG4gICAgICAgICAgICBpZiAob2Zmc2V0ID09IGVuZCA/IGZyb20gPD0gZW5kICYmIHRvID49IG9mZnNldCA6IGZyb20gPCBlbmQgJiYgdG8gPiBvZmZzZXQpIHtcbiAgICAgICAgICAgICAgICBsZXQgc3RhcnRJbnNpZGUgPSBvZmZzZXQgKyBjaGlsZC5ib3JkZXIsIGVuZEluc2lkZSA9IGVuZCAtIGNoaWxkLmJvcmRlcjtcbiAgICAgICAgICAgICAgICBpZiAoZnJvbSA+PSBzdGFydEluc2lkZSAmJiB0byA8PSBlbmRJbnNpZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kaXJ0eSA9IGZyb20gPT0gb2Zmc2V0IHx8IHRvID09IGVuZCA/IENPTlRFTlRfRElSVFkgOiBDSElMRF9ESVJUWTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZyb20gPT0gc3RhcnRJbnNpZGUgJiYgdG8gPT0gZW5kSW5zaWRlICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2hpbGQuY29udGVudExvc3QgfHwgY2hpbGQuZG9tLnBhcmVudE5vZGUgIT0gdGhpcy5jb250ZW50RE9NKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkLmRpcnR5ID0gTk9ERV9ESVJUWTtcbiAgICAgICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGQubWFya0RpcnR5KGZyb20gLSBzdGFydEluc2lkZSwgdG8gLSBzdGFydEluc2lkZSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNoaWxkLmRpcnR5ID0gY2hpbGQuZG9tID09IGNoaWxkLmNvbnRlbnRET00gJiYgY2hpbGQuZG9tLnBhcmVudE5vZGUgPT0gdGhpcy5jb250ZW50RE9NICYmICFjaGlsZC5jaGlsZHJlbi5sZW5ndGhcbiAgICAgICAgICAgICAgICAgICAgICAgID8gQ09OVEVOVF9ESVJUWSA6IE5PREVfRElSVFk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgb2Zmc2V0ID0gZW5kO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZGlydHkgPSBDT05URU5UX0RJUlRZO1xuICAgIH1cbiAgICBtYXJrUGFyZW50c0RpcnR5KCkge1xuICAgICAgICBsZXQgbGV2ZWwgPSAxO1xuICAgICAgICBmb3IgKGxldCBub2RlID0gdGhpcy5wYXJlbnQ7IG5vZGU7IG5vZGUgPSBub2RlLnBhcmVudCwgbGV2ZWwrKykge1xuICAgICAgICAgICAgbGV0IGRpcnR5ID0gbGV2ZWwgPT0gMSA/IENPTlRFTlRfRElSVFkgOiBDSElMRF9ESVJUWTtcbiAgICAgICAgICAgIGlmIChub2RlLmRpcnR5IDwgZGlydHkpXG4gICAgICAgICAgICAgICAgbm9kZS5kaXJ0eSA9IGRpcnR5O1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBkb21BdG9tKCkgeyByZXR1cm4gZmFsc2U7IH1cbiAgICBnZXQgaWdub3JlRm9yQ29vcmRzKCkgeyByZXR1cm4gZmFsc2U7IH1cbiAgICBpc1RleHQodGV4dCkgeyByZXR1cm4gZmFsc2U7IH1cbn1cbi8vIEEgd2lkZ2V0IGRlc2MgcmVwcmVzZW50cyBhIHdpZGdldCBkZWNvcmF0aW9uLCB3aGljaCBpcyBhIERPTSBub2RlXG4vLyBkcmF3biBiZXR3ZWVuIHRoZSBkb2N1bWVudCBub2Rlcy5cbmNsYXNzIFdpZGdldFZpZXdEZXNjIGV4dGVuZHMgVmlld0Rlc2Mge1xuICAgIGNvbnN0cnVjdG9yKHBhcmVudCwgd2lkZ2V0LCB2aWV3LCBwb3MpIHtcbiAgICAgICAgbGV0IHNlbGYsIGRvbSA9IHdpZGdldC50eXBlLnRvRE9NO1xuICAgICAgICBpZiAodHlwZW9mIGRvbSA9PSBcImZ1bmN0aW9uXCIpXG4gICAgICAgICAgICBkb20gPSBkb20odmlldywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICghc2VsZilcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHBvcztcbiAgICAgICAgICAgICAgICBpZiAoc2VsZi5wYXJlbnQpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzZWxmLnBhcmVudC5wb3NCZWZvcmVDaGlsZChzZWxmKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICBpZiAoIXdpZGdldC50eXBlLnNwZWMucmF3KSB7XG4gICAgICAgICAgICBpZiAoZG9tLm5vZGVUeXBlICE9IDEpIHtcbiAgICAgICAgICAgICAgICBsZXQgd3JhcCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIpO1xuICAgICAgICAgICAgICAgIHdyYXAuYXBwZW5kQ2hpbGQoZG9tKTtcbiAgICAgICAgICAgICAgICBkb20gPSB3cmFwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZG9tLmNvbnRlbnRFZGl0YWJsZSA9IFwiZmFsc2VcIjtcbiAgICAgICAgICAgIGRvbS5jbGFzc0xpc3QuYWRkKFwiUHJvc2VNaXJyb3Itd2lkZ2V0XCIpO1xuICAgICAgICB9XG4gICAgICAgIHN1cGVyKHBhcmVudCwgW10sIGRvbSwgbnVsbCk7XG4gICAgICAgIHRoaXMud2lkZ2V0ID0gd2lkZ2V0O1xuICAgICAgICB0aGlzLndpZGdldCA9IHdpZGdldDtcbiAgICAgICAgc2VsZiA9IHRoaXM7XG4gICAgfVxuICAgIG1hdGNoZXNXaWRnZXQod2lkZ2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRpcnR5ID09IE5PVF9ESVJUWSAmJiB3aWRnZXQudHlwZS5lcSh0aGlzLndpZGdldC50eXBlKTtcbiAgICB9XG4gICAgcGFyc2VSdWxlKCkgeyByZXR1cm4geyBpZ25vcmU6IHRydWUgfTsgfVxuICAgIHN0b3BFdmVudChldmVudCkge1xuICAgICAgICBsZXQgc3RvcCA9IHRoaXMud2lkZ2V0LnNwZWMuc3RvcEV2ZW50O1xuICAgICAgICByZXR1cm4gc3RvcCA/IHN0b3AoZXZlbnQpIDogZmFsc2U7XG4gICAgfVxuICAgIGlnbm9yZU11dGF0aW9uKG11dGF0aW9uKSB7XG4gICAgICAgIHJldHVybiBtdXRhdGlvbi50eXBlICE9IFwic2VsZWN0aW9uXCIgfHwgdGhpcy53aWRnZXQuc3BlYy5pZ25vcmVTZWxlY3Rpb247XG4gICAgfVxuICAgIGRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMud2lkZ2V0LnR5cGUuZGVzdHJveSh0aGlzLmRvbSk7XG4gICAgICAgIHN1cGVyLmRlc3Ryb3koKTtcbiAgICB9XG4gICAgZ2V0IGRvbUF0b20oKSB7IHJldHVybiB0cnVlOyB9XG4gICAgZ2V0IHNpZGUoKSB7IHJldHVybiB0aGlzLndpZGdldC50eXBlLnNpZGU7IH1cbn1cbmNsYXNzIENvbXBvc2l0aW9uVmlld0Rlc2MgZXh0ZW5kcyBWaWV3RGVzYyB7XG4gICAgY29uc3RydWN0b3IocGFyZW50LCBkb20sIHRleHRET00sIHRleHQpIHtcbiAgICAgICAgc3VwZXIocGFyZW50LCBbXSwgZG9tLCBudWxsKTtcbiAgICAgICAgdGhpcy50ZXh0RE9NID0gdGV4dERPTTtcbiAgICAgICAgdGhpcy50ZXh0ID0gdGV4dDtcbiAgICB9XG4gICAgZ2V0IHNpemUoKSB7IHJldHVybiB0aGlzLnRleHQubGVuZ3RoOyB9XG4gICAgbG9jYWxQb3NGcm9tRE9NKGRvbSwgb2Zmc2V0KSB7XG4gICAgICAgIGlmIChkb20gIT0gdGhpcy50ZXh0RE9NKVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMucG9zQXRTdGFydCArIChvZmZzZXQgPyB0aGlzLnNpemUgOiAwKTtcbiAgICAgICAgcmV0dXJuIHRoaXMucG9zQXRTdGFydCArIG9mZnNldDtcbiAgICB9XG4gICAgZG9tRnJvbVBvcyhwb3MpIHtcbiAgICAgICAgcmV0dXJuIHsgbm9kZTogdGhpcy50ZXh0RE9NLCBvZmZzZXQ6IHBvcyB9O1xuICAgIH1cbiAgICBpZ25vcmVNdXRhdGlvbihtdXQpIHtcbiAgICAgICAgcmV0dXJuIG11dC50eXBlID09PSAnY2hhcmFjdGVyRGF0YScgJiYgbXV0LnRhcmdldC5ub2RlVmFsdWUgPT0gbXV0Lm9sZFZhbHVlO1xuICAgIH1cbn1cbi8vIEEgbWFyayBkZXNjIHJlcHJlc2VudHMgYSBtYXJrLiBNYXkgaGF2ZSBtdWx0aXBsZSBjaGlsZHJlbixcbi8vIGRlcGVuZGluZyBvbiBob3cgdGhlIG1hcmsgaXMgc3BsaXQuIE5vdGUgdGhhdCBtYXJrcyBhcmUgZHJhd24gdXNpbmdcbi8vIGEgZml4ZWQgbmVzdGluZyBvcmRlciwgZm9yIHNpbXBsaWNpdHkgYW5kIHByZWRpY3RhYmlsaXR5LCBzbyBpblxuLy8gc29tZSBjYXNlcyB0aGV5IHdpbGwgYmUgc3BsaXQgbW9yZSBvZnRlbiB0aGFuIHdvdWxkIGFwcGVhclxuLy8gbmVjZXNzYXJ5LlxuY2xhc3MgTWFya1ZpZXdEZXNjIGV4dGVuZHMgVmlld0Rlc2Mge1xuICAgIGNvbnN0cnVjdG9yKHBhcmVudCwgbWFyaywgZG9tLCBjb250ZW50RE9NLCBzcGVjKSB7XG4gICAgICAgIHN1cGVyKHBhcmVudCwgW10sIGRvbSwgY29udGVudERPTSk7XG4gICAgICAgIHRoaXMubWFyayA9IG1hcms7XG4gICAgICAgIHRoaXMuc3BlYyA9IHNwZWM7XG4gICAgfVxuICAgIHN0YXRpYyBjcmVhdGUocGFyZW50LCBtYXJrLCBpbmxpbmUsIHZpZXcpIHtcbiAgICAgICAgbGV0IGN1c3RvbSA9IHZpZXcubm9kZVZpZXdzW21hcmsudHlwZS5uYW1lXTtcbiAgICAgICAgbGV0IHNwZWMgPSBjdXN0b20gJiYgY3VzdG9tKG1hcmssIHZpZXcsIGlubGluZSk7XG4gICAgICAgIGlmICghc3BlYyB8fCAhc3BlYy5kb20pXG4gICAgICAgICAgICBzcGVjID0gRE9NU2VyaWFsaXplci5yZW5kZXJTcGVjKGRvY3VtZW50LCBtYXJrLnR5cGUuc3BlYy50b0RPTShtYXJrLCBpbmxpbmUpLCBudWxsLCBtYXJrLmF0dHJzKTtcbiAgICAgICAgcmV0dXJuIG5ldyBNYXJrVmlld0Rlc2MocGFyZW50LCBtYXJrLCBzcGVjLmRvbSwgc3BlYy5jb250ZW50RE9NIHx8IHNwZWMuZG9tLCBzcGVjKTtcbiAgICB9XG4gICAgcGFyc2VSdWxlKCkge1xuICAgICAgICBpZiAoKHRoaXMuZGlydHkgJiBOT0RFX0RJUlRZKSB8fCB0aGlzLm1hcmsudHlwZS5zcGVjLnJlcGFyc2VJblZpZXcpXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgcmV0dXJuIHsgbWFyazogdGhpcy5tYXJrLnR5cGUubmFtZSwgYXR0cnM6IHRoaXMubWFyay5hdHRycywgY29udGVudEVsZW1lbnQ6IHRoaXMuY29udGVudERPTSB9O1xuICAgIH1cbiAgICBtYXRjaGVzTWFyayhtYXJrKSB7IHJldHVybiB0aGlzLmRpcnR5ICE9IE5PREVfRElSVFkgJiYgdGhpcy5tYXJrLmVxKG1hcmspOyB9XG4gICAgbWFya0RpcnR5KGZyb20sIHRvKSB7XG4gICAgICAgIHN1cGVyLm1hcmtEaXJ0eShmcm9tLCB0byk7XG4gICAgICAgIC8vIE1vdmUgZGlydHkgaW5mbyB0byBuZWFyZXN0IG5vZGUgdmlld1xuICAgICAgICBpZiAodGhpcy5kaXJ0eSAhPSBOT1RfRElSVFkpIHtcbiAgICAgICAgICAgIGxldCBwYXJlbnQgPSB0aGlzLnBhcmVudDtcbiAgICAgICAgICAgIHdoaWxlICghcGFyZW50Lm5vZGUpXG4gICAgICAgICAgICAgICAgcGFyZW50ID0gcGFyZW50LnBhcmVudDtcbiAgICAgICAgICAgIGlmIChwYXJlbnQuZGlydHkgPCB0aGlzLmRpcnR5KVxuICAgICAgICAgICAgICAgIHBhcmVudC5kaXJ0eSA9IHRoaXMuZGlydHk7XG4gICAgICAgICAgICB0aGlzLmRpcnR5ID0gTk9UX0RJUlRZO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNsaWNlKGZyb20sIHRvLCB2aWV3KSB7XG4gICAgICAgIGxldCBjb3B5ID0gTWFya1ZpZXdEZXNjLmNyZWF0ZSh0aGlzLnBhcmVudCwgdGhpcy5tYXJrLCB0cnVlLCB2aWV3KTtcbiAgICAgICAgbGV0IG5vZGVzID0gdGhpcy5jaGlsZHJlbiwgc2l6ZSA9IHRoaXMuc2l6ZTtcbiAgICAgICAgaWYgKHRvIDwgc2l6ZSlcbiAgICAgICAgICAgIG5vZGVzID0gcmVwbGFjZU5vZGVzKG5vZGVzLCB0bywgc2l6ZSwgdmlldyk7XG4gICAgICAgIGlmIChmcm9tID4gMClcbiAgICAgICAgICAgIG5vZGVzID0gcmVwbGFjZU5vZGVzKG5vZGVzLCAwLCBmcm9tLCB2aWV3KTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBub2Rlcy5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIG5vZGVzW2ldLnBhcmVudCA9IGNvcHk7XG4gICAgICAgIGNvcHkuY2hpbGRyZW4gPSBub2RlcztcbiAgICAgICAgcmV0dXJuIGNvcHk7XG4gICAgfVxuICAgIGlnbm9yZU11dGF0aW9uKG11dGF0aW9uKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNwZWMuaWdub3JlTXV0YXRpb24gPyB0aGlzLnNwZWMuaWdub3JlTXV0YXRpb24obXV0YXRpb24pIDogc3VwZXIuaWdub3JlTXV0YXRpb24obXV0YXRpb24pO1xuICAgIH1cbiAgICBkZXN0cm95KCkge1xuICAgICAgICBpZiAodGhpcy5zcGVjLmRlc3Ryb3kpXG4gICAgICAgICAgICB0aGlzLnNwZWMuZGVzdHJveSgpO1xuICAgICAgICBzdXBlci5kZXN0cm95KCk7XG4gICAgfVxufVxuLy8gTm9kZSB2aWV3IGRlc2NzIGFyZSB0aGUgbWFpbiwgbW9zdCBjb21tb24gdHlwZSBvZiB2aWV3IGRlc2MsIGFuZFxuLy8gY29ycmVzcG9uZCB0byBhbiBhY3R1YWwgbm9kZSBpbiB0aGUgZG9jdW1lbnQuIFVubGlrZSBtYXJrIGRlc2NzLFxuLy8gdGhleSBwb3B1bGF0ZSB0aGVpciBjaGlsZCBhcnJheSB0aGVtc2VsdmVzLlxuY2xhc3MgTm9kZVZpZXdEZXNjIGV4dGVuZHMgVmlld0Rlc2Mge1xuICAgIGNvbnN0cnVjdG9yKHBhcmVudCwgbm9kZSwgb3V0ZXJEZWNvLCBpbm5lckRlY28sIGRvbSwgY29udGVudERPTSwgbm9kZURPTSwgdmlldywgcG9zKSB7XG4gICAgICAgIHN1cGVyKHBhcmVudCwgW10sIGRvbSwgY29udGVudERPTSk7XG4gICAgICAgIHRoaXMubm9kZSA9IG5vZGU7XG4gICAgICAgIHRoaXMub3V0ZXJEZWNvID0gb3V0ZXJEZWNvO1xuICAgICAgICB0aGlzLmlubmVyRGVjbyA9IGlubmVyRGVjbztcbiAgICAgICAgdGhpcy5ub2RlRE9NID0gbm9kZURPTTtcbiAgICB9XG4gICAgLy8gQnkgZGVmYXVsdCwgYSBub2RlIGlzIHJlbmRlcmVkIHVzaW5nIHRoZSBgdG9ET01gIG1ldGhvZCBmcm9tIHRoZVxuICAgIC8vIG5vZGUgdHlwZSBzcGVjLiBCdXQgY2xpZW50IGNvZGUgY2FuIHVzZSB0aGUgYG5vZGVWaWV3c2Agc3BlYyB0b1xuICAgIC8vIHN1cHBseSBhIGN1c3RvbSBub2RlIHZpZXcsIHdoaWNoIGNhbiBpbmZsdWVuY2UgdmFyaW91cyBhc3BlY3RzIG9mXG4gICAgLy8gdGhlIHdheSB0aGUgbm9kZSB3b3Jrcy5cbiAgICAvL1xuICAgIC8vIChVc2luZyBzdWJjbGFzc2luZyBmb3IgdGhpcyB3YXMgaW50ZW50aW9uYWxseSBkZWNpZGVkIGFnYWluc3QsXG4gICAgLy8gc2luY2UgaXQnZCByZXF1aXJlIGV4cG9zaW5nIGEgd2hvbGUgc2xldyBvZiBmaW5pY2t5XG4gICAgLy8gaW1wbGVtZW50YXRpb24gZGV0YWlscyB0byB0aGUgdXNlciBjb2RlIHRoYXQgdGhleSBwcm9iYWJseSB3aWxsXG4gICAgLy8gbmV2ZXIgbmVlZC4pXG4gICAgc3RhdGljIGNyZWF0ZShwYXJlbnQsIG5vZGUsIG91dGVyRGVjbywgaW5uZXJEZWNvLCB2aWV3LCBwb3MpIHtcbiAgICAgICAgbGV0IGN1c3RvbSA9IHZpZXcubm9kZVZpZXdzW25vZGUudHlwZS5uYW1lXSwgZGVzY09iajtcbiAgICAgICAgbGV0IHNwZWMgPSBjdXN0b20gJiYgY3VzdG9tKG5vZGUsIHZpZXcsICgpID0+IHtcbiAgICAgICAgICAgIC8vIChUaGlzIGlzIGEgZnVuY3Rpb24gdGhhdCBhbGxvd3MgdGhlIGN1c3RvbSB2aWV3IHRvIGZpbmQgaXRzXG4gICAgICAgICAgICAvLyBvd24gcG9zaXRpb24pXG4gICAgICAgICAgICBpZiAoIWRlc2NPYmopXG4gICAgICAgICAgICAgICAgcmV0dXJuIHBvcztcbiAgICAgICAgICAgIGlmIChkZXNjT2JqLnBhcmVudClcbiAgICAgICAgICAgICAgICByZXR1cm4gZGVzY09iai5wYXJlbnQucG9zQmVmb3JlQ2hpbGQoZGVzY09iaik7XG4gICAgICAgIH0sIG91dGVyRGVjbywgaW5uZXJEZWNvKTtcbiAgICAgICAgbGV0IGRvbSA9IHNwZWMgJiYgc3BlYy5kb20sIGNvbnRlbnRET00gPSBzcGVjICYmIHNwZWMuY29udGVudERPTTtcbiAgICAgICAgaWYgKG5vZGUuaXNUZXh0KSB7XG4gICAgICAgICAgICBpZiAoIWRvbSlcbiAgICAgICAgICAgICAgICBkb20gPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShub2RlLnRleHQpO1xuICAgICAgICAgICAgZWxzZSBpZiAoZG9tLm5vZGVUeXBlICE9IDMpXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJUZXh0IG11c3QgYmUgcmVuZGVyZWQgYXMgYSBET00gdGV4dCBub2RlXCIpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKCFkb20pIHtcbiAgICAgICAgICAgIGxldCBzcGVjID0gRE9NU2VyaWFsaXplci5yZW5kZXJTcGVjKGRvY3VtZW50LCBub2RlLnR5cGUuc3BlYy50b0RPTShub2RlKSwgbnVsbCwgbm9kZS5hdHRycyk7XG4gICAgICAgICAgICAoeyBkb20sIGNvbnRlbnRET00gfSA9IHNwZWMpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghY29udGVudERPTSAmJiAhbm9kZS5pc1RleHQgJiYgZG9tLm5vZGVOYW1lICE9IFwiQlJcIikgeyAvLyBDaHJvbWUgZ2V0cyBjb25mdXNlZCBieSA8YnIgY29udGVudGVkaXRhYmxlPWZhbHNlPlxuICAgICAgICAgICAgaWYgKCFkb20uaGFzQXR0cmlidXRlKFwiY29udGVudGVkaXRhYmxlXCIpKVxuICAgICAgICAgICAgICAgIGRvbS5jb250ZW50RWRpdGFibGUgPSBcImZhbHNlXCI7XG4gICAgICAgICAgICBpZiAobm9kZS50eXBlLnNwZWMuZHJhZ2dhYmxlKVxuICAgICAgICAgICAgICAgIGRvbS5kcmFnZ2FibGUgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGxldCBub2RlRE9NID0gZG9tO1xuICAgICAgICBkb20gPSBhcHBseU91dGVyRGVjbyhkb20sIG91dGVyRGVjbywgbm9kZSk7XG4gICAgICAgIGlmIChzcGVjKVxuICAgICAgICAgICAgcmV0dXJuIGRlc2NPYmogPSBuZXcgQ3VzdG9tTm9kZVZpZXdEZXNjKHBhcmVudCwgbm9kZSwgb3V0ZXJEZWNvLCBpbm5lckRlY28sIGRvbSwgY29udGVudERPTSB8fCBudWxsLCBub2RlRE9NLCBzcGVjLCB2aWV3LCBwb3MgKyAxKTtcbiAgICAgICAgZWxzZSBpZiAobm9kZS5pc1RleHQpXG4gICAgICAgICAgICByZXR1cm4gbmV3IFRleHRWaWV3RGVzYyhwYXJlbnQsIG5vZGUsIG91dGVyRGVjbywgaW5uZXJEZWNvLCBkb20sIG5vZGVET00sIHZpZXcpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICByZXR1cm4gbmV3IE5vZGVWaWV3RGVzYyhwYXJlbnQsIG5vZGUsIG91dGVyRGVjbywgaW5uZXJEZWNvLCBkb20sIGNvbnRlbnRET00gfHwgbnVsbCwgbm9kZURPTSwgdmlldywgcG9zICsgMSk7XG4gICAgfVxuICAgIHBhcnNlUnVsZSgpIHtcbiAgICAgICAgLy8gRXhwZXJpbWVudGFsIGtsdWRnZSB0byBhbGxvdyBvcHQtaW4gcmUtcGFyc2luZyBvZiBub2Rlc1xuICAgICAgICBpZiAodGhpcy5ub2RlLnR5cGUuc3BlYy5yZXBhcnNlSW5WaWV3KVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIC8vIEZJWE1FIHRoZSBhc3N1bXB0aW9uIHRoYXQgdGhpcyBjYW4gYWx3YXlzIHJldHVybiB0aGUgY3VycmVudFxuICAgICAgICAvLyBhdHRycyBtZWFucyB0aGF0IGlmIHRoZSB1c2VyIHNvbWVob3cgbWFuYWdlcyB0byBjaGFuZ2UgdGhlXG4gICAgICAgIC8vIGF0dHJzIGluIHRoZSBkb20sIHRoYXQgd29uJ3QgYmUgcGlja2VkIHVwLiBOb3QgZW50aXJlbHkgc3VyZVxuICAgICAgICAvLyB3aGV0aGVyIHRoaXMgaXMgYSBwcm9ibGVtXG4gICAgICAgIGxldCBydWxlID0geyBub2RlOiB0aGlzLm5vZGUudHlwZS5uYW1lLCBhdHRyczogdGhpcy5ub2RlLmF0dHJzIH07XG4gICAgICAgIGlmICh0aGlzLm5vZGUudHlwZS53aGl0ZXNwYWNlID09IFwicHJlXCIpXG4gICAgICAgICAgICBydWxlLnByZXNlcnZlV2hpdGVzcGFjZSA9IFwiZnVsbFwiO1xuICAgICAgICBpZiAoIXRoaXMuY29udGVudERPTSkge1xuICAgICAgICAgICAgcnVsZS5nZXRDb250ZW50ID0gKCkgPT4gdGhpcy5ub2RlLmNvbnRlbnQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIXRoaXMuY29udGVudExvc3QpIHtcbiAgICAgICAgICAgIHJ1bGUuY29udGVudEVsZW1lbnQgPSB0aGlzLmNvbnRlbnRET007XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAvLyBDaHJvbWUgbGlrZXMgdG8gcmFuZG9tbHkgcmVjcmVhdGUgcGFyZW50IG5vZGVzIHdoZW5cbiAgICAgICAgICAgIC8vIGJhY2tzcGFjaW5nIHRoaW5ncy4gV2hlbiB0aGF0IGhhcHBlbnMsIHRoaXMgdHJpZXMgdG8gZmluZCB0aGVcbiAgICAgICAgICAgIC8vIG5ldyBwYXJlbnQuXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gdGhpcy5jaGlsZHJlbi5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgICAgIGxldCBjaGlsZCA9IHRoaXMuY2hpbGRyZW5baV07XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZG9tLmNvbnRhaW5zKGNoaWxkLmRvbS5wYXJlbnROb2RlKSkge1xuICAgICAgICAgICAgICAgICAgICBydWxlLmNvbnRlbnRFbGVtZW50ID0gY2hpbGQuZG9tLnBhcmVudE5vZGU7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghcnVsZS5jb250ZW50RWxlbWVudClcbiAgICAgICAgICAgICAgICBydWxlLmdldENvbnRlbnQgPSAoKSA9PiBGcmFnbWVudC5lbXB0eTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcnVsZTtcbiAgICB9XG4gICAgbWF0Y2hlc05vZGUobm9kZSwgb3V0ZXJEZWNvLCBpbm5lckRlY28pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGlydHkgPT0gTk9UX0RJUlRZICYmIG5vZGUuZXEodGhpcy5ub2RlKSAmJlxuICAgICAgICAgICAgc2FtZU91dGVyRGVjbyhvdXRlckRlY28sIHRoaXMub3V0ZXJEZWNvKSAmJiBpbm5lckRlY28uZXEodGhpcy5pbm5lckRlY28pO1xuICAgIH1cbiAgICBnZXQgc2l6ZSgpIHsgcmV0dXJuIHRoaXMubm9kZS5ub2RlU2l6ZTsgfVxuICAgIGdldCBib3JkZXIoKSB7IHJldHVybiB0aGlzLm5vZGUuaXNMZWFmID8gMCA6IDE7IH1cbiAgICAvLyBTeW5jcyBgdGhpcy5jaGlsZHJlbmAgdG8gbWF0Y2ggYHRoaXMubm9kZS5jb250ZW50YCBhbmQgdGhlIGxvY2FsXG4gICAgLy8gZGVjb3JhdGlvbnMsIHBvc3NpYmx5IGludHJvZHVjaW5nIG5lc3RpbmcgZm9yIG1hcmtzLiBUaGVuLCBpbiBhXG4gICAgLy8gc2VwYXJhdGUgc3RlcCwgc3luY3MgdGhlIERPTSBpbnNpZGUgYHRoaXMuY29udGVudERPTWAgdG9cbiAgICAvLyBgdGhpcy5jaGlsZHJlbmAuXG4gICAgdXBkYXRlQ2hpbGRyZW4odmlldywgcG9zKSB7XG4gICAgICAgIGxldCBpbmxpbmUgPSB0aGlzLm5vZGUuaW5saW5lQ29udGVudCwgb2ZmID0gcG9zO1xuICAgICAgICBsZXQgY29tcG9zaXRpb24gPSB2aWV3LmNvbXBvc2luZyA/IHRoaXMubG9jYWxDb21wb3NpdGlvbkluZm8odmlldywgcG9zKSA6IG51bGw7XG4gICAgICAgIGxldCBsb2NhbENvbXBvc2l0aW9uID0gY29tcG9zaXRpb24gJiYgY29tcG9zaXRpb24ucG9zID4gLTEgPyBjb21wb3NpdGlvbiA6IG51bGw7XG4gICAgICAgIGxldCBjb21wb3NpdGlvbkluQ2hpbGQgPSBjb21wb3NpdGlvbiAmJiBjb21wb3NpdGlvbi5wb3MgPCAwO1xuICAgICAgICBsZXQgdXBkYXRlciA9IG5ldyBWaWV3VHJlZVVwZGF0ZXIodGhpcywgbG9jYWxDb21wb3NpdGlvbiAmJiBsb2NhbENvbXBvc2l0aW9uLm5vZGUsIHZpZXcpO1xuICAgICAgICBpdGVyRGVjbyh0aGlzLm5vZGUsIHRoaXMuaW5uZXJEZWNvLCAod2lkZ2V0LCBpLCBpbnNpZGVOb2RlKSA9PiB7XG4gICAgICAgICAgICBpZiAod2lkZ2V0LnNwZWMubWFya3MpXG4gICAgICAgICAgICAgICAgdXBkYXRlci5zeW5jVG9NYXJrcyh3aWRnZXQuc3BlYy5tYXJrcywgaW5saW5lLCB2aWV3KTtcbiAgICAgICAgICAgIGVsc2UgaWYgKHdpZGdldC50eXBlLnNpZGUgPj0gMCAmJiAhaW5zaWRlTm9kZSlcbiAgICAgICAgICAgICAgICB1cGRhdGVyLnN5bmNUb01hcmtzKGkgPT0gdGhpcy5ub2RlLmNoaWxkQ291bnQgPyBNYXJrLm5vbmUgOiB0aGlzLm5vZGUuY2hpbGQoaSkubWFya3MsIGlubGluZSwgdmlldyk7XG4gICAgICAgICAgICAvLyBJZiB0aGUgbmV4dCBub2RlIGlzIGEgZGVzYyBtYXRjaGluZyB0aGlzIHdpZGdldCwgcmV1c2UgaXQsXG4gICAgICAgICAgICAvLyBvdGhlcndpc2UgaW5zZXJ0IHRoZSB3aWRnZXQgYXMgYSBuZXcgdmlldyBkZXNjLlxuICAgICAgICAgICAgdXBkYXRlci5wbGFjZVdpZGdldCh3aWRnZXQsIHZpZXcsIG9mZik7XG4gICAgICAgIH0sIChjaGlsZCwgb3V0ZXJEZWNvLCBpbm5lckRlY28sIGkpID0+IHtcbiAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSB0aGUgd3JhcHBpbmcgbWFyayBkZXNjcyBtYXRjaCB0aGUgbm9kZSdzIG1hcmtzLlxuICAgICAgICAgICAgdXBkYXRlci5zeW5jVG9NYXJrcyhjaGlsZC5tYXJrcywgaW5saW5lLCB2aWV3KTtcbiAgICAgICAgICAgIC8vIFRyeSBzZXZlcmFsIHN0cmF0ZWdpZXMgZm9yIGRyYXdpbmcgdGhpcyBub2RlXG4gICAgICAgICAgICBsZXQgY29tcEluZGV4O1xuICAgICAgICAgICAgaWYgKHVwZGF0ZXIuZmluZE5vZGVNYXRjaChjaGlsZCwgb3V0ZXJEZWNvLCBpbm5lckRlY28sIGkpKSA7XG4gICAgICAgICAgICBlbHNlIGlmIChjb21wb3NpdGlvbkluQ2hpbGQgJiYgdmlldy5zdGF0ZS5zZWxlY3Rpb24uZnJvbSA+IG9mZiAmJlxuICAgICAgICAgICAgICAgIHZpZXcuc3RhdGUuc2VsZWN0aW9uLnRvIDwgb2ZmICsgY2hpbGQubm9kZVNpemUgJiZcbiAgICAgICAgICAgICAgICAoY29tcEluZGV4ID0gdXBkYXRlci5maW5kSW5kZXhXaXRoQ2hpbGQoY29tcG9zaXRpb24ubm9kZSkpID4gLTEgJiZcbiAgICAgICAgICAgICAgICB1cGRhdGVyLnVwZGF0ZU5vZGVBdChjaGlsZCwgb3V0ZXJEZWNvLCBpbm5lckRlY28sIGNvbXBJbmRleCwgdmlldykpIDtcbiAgICAgICAgICAgIGVsc2UgaWYgKHVwZGF0ZXIudXBkYXRlTmV4dE5vZGUoY2hpbGQsIG91dGVyRGVjbywgaW5uZXJEZWNvLCB2aWV3LCBpLCBvZmYpKSA7XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBBZGQgaXQgYXMgYSBuZXcgdmlld1xuICAgICAgICAgICAgICAgIHVwZGF0ZXIuYWRkTm9kZShjaGlsZCwgb3V0ZXJEZWNvLCBpbm5lckRlY28sIHZpZXcsIG9mZik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBvZmYgKz0gY2hpbGQubm9kZVNpemU7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBEcm9wIGFsbCByZW1haW5pbmcgZGVzY3MgYWZ0ZXIgdGhlIGN1cnJlbnQgcG9zaXRpb24uXG4gICAgICAgIHVwZGF0ZXIuc3luY1RvTWFya3MoW10sIGlubGluZSwgdmlldyk7XG4gICAgICAgIGlmICh0aGlzLm5vZGUuaXNUZXh0YmxvY2spXG4gICAgICAgICAgICB1cGRhdGVyLmFkZFRleHRibG9ja0hhY2tzKCk7XG4gICAgICAgIHVwZGF0ZXIuZGVzdHJveVJlc3QoKTtcbiAgICAgICAgLy8gU3luYyB0aGUgRE9NIGlmIGFueXRoaW5nIGNoYW5nZWRcbiAgICAgICAgaWYgKHVwZGF0ZXIuY2hhbmdlZCB8fCB0aGlzLmRpcnR5ID09IENPTlRFTlRfRElSVFkpIHtcbiAgICAgICAgICAgIC8vIE1heSBoYXZlIHRvIHByb3RlY3QgZm9jdXNlZCBET00gZnJvbSBiZWluZyBjaGFuZ2VkIGlmIGEgY29tcG9zaXRpb24gaXMgYWN0aXZlXG4gICAgICAgICAgICBpZiAobG9jYWxDb21wb3NpdGlvbilcbiAgICAgICAgICAgICAgICB0aGlzLnByb3RlY3RMb2NhbENvbXBvc2l0aW9uKHZpZXcsIGxvY2FsQ29tcG9zaXRpb24pO1xuICAgICAgICAgICAgcmVuZGVyRGVzY3ModGhpcy5jb250ZW50RE9NLCB0aGlzLmNoaWxkcmVuLCB2aWV3KTtcbiAgICAgICAgICAgIGlmIChpb3MpXG4gICAgICAgICAgICAgICAgaW9zSGFja3ModGhpcy5kb20pO1xuICAgICAgICB9XG4gICAgfVxuICAgIGxvY2FsQ29tcG9zaXRpb25JbmZvKHZpZXcsIHBvcykge1xuICAgICAgICAvLyBPbmx5IGRvIHNvbWV0aGluZyBpZiBib3RoIHRoZSBzZWxlY3Rpb24gYW5kIGEgZm9jdXNlZCB0ZXh0IG5vZGVcbiAgICAgICAgLy8gYXJlIGluc2lkZSBvZiB0aGlzIG5vZGVcbiAgICAgICAgbGV0IHsgZnJvbSwgdG8gfSA9IHZpZXcuc3RhdGUuc2VsZWN0aW9uO1xuICAgICAgICBpZiAoISh2aWV3LnN0YXRlLnNlbGVjdGlvbiBpbnN0YW5jZW9mIFRleHRTZWxlY3Rpb24pIHx8IGZyb20gPCBwb3MgfHwgdG8gPiBwb3MgKyB0aGlzLm5vZGUuY29udGVudC5zaXplKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIGxldCB0ZXh0Tm9kZSA9IHZpZXcuaW5wdXQuY29tcG9zaXRpb25Ob2RlO1xuICAgICAgICBpZiAoIXRleHROb2RlIHx8ICF0aGlzLmRvbS5jb250YWlucyh0ZXh0Tm9kZS5wYXJlbnROb2RlKSlcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICBpZiAodGhpcy5ub2RlLmlubGluZUNvbnRlbnQpIHtcbiAgICAgICAgICAgIC8vIEZpbmQgdGhlIHRleHQgaW4gdGhlIGZvY3VzZWQgbm9kZSBpbiB0aGUgbm9kZSwgc3RvcCBpZiBpdCdzIG5vdFxuICAgICAgICAgICAgLy8gdGhlcmUgKG1heSBoYXZlIGJlZW4gbW9kaWZpZWQgdGhyb3VnaCBvdGhlciBtZWFucywgaW4gd2hpY2hcbiAgICAgICAgICAgIC8vIGNhc2UgaXQgc2hvdWxkIG92ZXJ3cml0dGVuKVxuICAgICAgICAgICAgbGV0IHRleHQgPSB0ZXh0Tm9kZS5ub2RlVmFsdWU7XG4gICAgICAgICAgICBsZXQgdGV4dFBvcyA9IGZpbmRUZXh0SW5GcmFnbWVudCh0aGlzLm5vZGUuY29udGVudCwgdGV4dCwgZnJvbSAtIHBvcywgdG8gLSBwb3MpO1xuICAgICAgICAgICAgcmV0dXJuIHRleHRQb3MgPCAwID8gbnVsbCA6IHsgbm9kZTogdGV4dE5vZGUsIHBvczogdGV4dFBvcywgdGV4dCB9O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHsgbm9kZTogdGV4dE5vZGUsIHBvczogLTEsIHRleHQ6IFwiXCIgfTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBwcm90ZWN0TG9jYWxDb21wb3NpdGlvbih2aWV3LCB7IG5vZGUsIHBvcywgdGV4dCB9KSB7XG4gICAgICAgIC8vIFRoZSBub2RlIGlzIGFscmVhZHkgcGFydCBvZiBhIGxvY2FsIHZpZXcgZGVzYywgbGVhdmUgaXQgdGhlcmVcbiAgICAgICAgaWYgKHRoaXMuZ2V0RGVzYyhub2RlKSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgLy8gQ3JlYXRlIGEgY29tcG9zaXRpb24gdmlldyBmb3IgdGhlIG9ycGhhbmVkIG5vZGVzXG4gICAgICAgIGxldCB0b3BOb2RlID0gbm9kZTtcbiAgICAgICAgZm9yICg7OyB0b3BOb2RlID0gdG9wTm9kZS5wYXJlbnROb2RlKSB7XG4gICAgICAgICAgICBpZiAodG9wTm9kZS5wYXJlbnROb2RlID09IHRoaXMuY29udGVudERPTSlcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIHdoaWxlICh0b3BOb2RlLnByZXZpb3VzU2libGluZylcbiAgICAgICAgICAgICAgICB0b3BOb2RlLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodG9wTm9kZS5wcmV2aW91c1NpYmxpbmcpO1xuICAgICAgICAgICAgd2hpbGUgKHRvcE5vZGUubmV4dFNpYmxpbmcpXG4gICAgICAgICAgICAgICAgdG9wTm9kZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRvcE5vZGUubmV4dFNpYmxpbmcpO1xuICAgICAgICAgICAgaWYgKHRvcE5vZGUucG1WaWV3RGVzYylcbiAgICAgICAgICAgICAgICB0b3BOb2RlLnBtVmlld0Rlc2MgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGRlc2MgPSBuZXcgQ29tcG9zaXRpb25WaWV3RGVzYyh0aGlzLCB0b3BOb2RlLCBub2RlLCB0ZXh0KTtcbiAgICAgICAgdmlldy5pbnB1dC5jb21wb3NpdGlvbk5vZGVzLnB1c2goZGVzYyk7XG4gICAgICAgIC8vIFBhdGNoIHVwIHRoaXMuY2hpbGRyZW4gdG8gY29udGFpbiB0aGUgY29tcG9zaXRpb24gdmlld1xuICAgICAgICB0aGlzLmNoaWxkcmVuID0gcmVwbGFjZU5vZGVzKHRoaXMuY2hpbGRyZW4sIHBvcywgcG9zICsgdGV4dC5sZW5ndGgsIHZpZXcsIGRlc2MpO1xuICAgIH1cbiAgICAvLyBJZiB0aGlzIGRlc2MgbXVzdCBiZSB1cGRhdGVkIHRvIG1hdGNoIHRoZSBnaXZlbiBub2RlIGRlY29yYXRpb24sXG4gICAgLy8gZG8gc28gYW5kIHJldHVybiB0cnVlLlxuICAgIHVwZGF0ZShub2RlLCBvdXRlckRlY28sIGlubmVyRGVjbywgdmlldykge1xuICAgICAgICBpZiAodGhpcy5kaXJ0eSA9PSBOT0RFX0RJUlRZIHx8XG4gICAgICAgICAgICAhbm9kZS5zYW1lTWFya3VwKHRoaXMubm9kZSkpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIHRoaXMudXBkYXRlSW5uZXIobm9kZSwgb3V0ZXJEZWNvLCBpbm5lckRlY28sIHZpZXcpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgdXBkYXRlSW5uZXIobm9kZSwgb3V0ZXJEZWNvLCBpbm5lckRlY28sIHZpZXcpIHtcbiAgICAgICAgdGhpcy51cGRhdGVPdXRlckRlY28ob3V0ZXJEZWNvKTtcbiAgICAgICAgdGhpcy5ub2RlID0gbm9kZTtcbiAgICAgICAgdGhpcy5pbm5lckRlY28gPSBpbm5lckRlY287XG4gICAgICAgIGlmICh0aGlzLmNvbnRlbnRET00pXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUNoaWxkcmVuKHZpZXcsIHRoaXMucG9zQXRTdGFydCk7XG4gICAgICAgIHRoaXMuZGlydHkgPSBOT1RfRElSVFk7XG4gICAgfVxuICAgIHVwZGF0ZU91dGVyRGVjbyhvdXRlckRlY28pIHtcbiAgICAgICAgaWYgKHNhbWVPdXRlckRlY28ob3V0ZXJEZWNvLCB0aGlzLm91dGVyRGVjbykpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIGxldCBuZWVkc1dyYXAgPSB0aGlzLm5vZGVET00ubm9kZVR5cGUgIT0gMTtcbiAgICAgICAgbGV0IG9sZERPTSA9IHRoaXMuZG9tO1xuICAgICAgICB0aGlzLmRvbSA9IHBhdGNoT3V0ZXJEZWNvKHRoaXMuZG9tLCB0aGlzLm5vZGVET00sIGNvbXB1dGVPdXRlckRlY28odGhpcy5vdXRlckRlY28sIHRoaXMubm9kZSwgbmVlZHNXcmFwKSwgY29tcHV0ZU91dGVyRGVjbyhvdXRlckRlY28sIHRoaXMubm9kZSwgbmVlZHNXcmFwKSk7XG4gICAgICAgIGlmICh0aGlzLmRvbSAhPSBvbGRET00pIHtcbiAgICAgICAgICAgIG9sZERPTS5wbVZpZXdEZXNjID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgdGhpcy5kb20ucG1WaWV3RGVzYyA9IHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vdXRlckRlY28gPSBvdXRlckRlY287XG4gICAgfVxuICAgIC8vIE1hcmsgdGhpcyBub2RlIGFzIGJlaW5nIHRoZSBzZWxlY3RlZCBub2RlLlxuICAgIHNlbGVjdE5vZGUoKSB7XG4gICAgICAgIGlmICh0aGlzLm5vZGVET00ubm9kZVR5cGUgPT0gMSlcbiAgICAgICAgICAgIHRoaXMubm9kZURPTS5jbGFzc0xpc3QuYWRkKFwiUHJvc2VNaXJyb3Itc2VsZWN0ZWRub2RlXCIpO1xuICAgICAgICBpZiAodGhpcy5jb250ZW50RE9NIHx8ICF0aGlzLm5vZGUudHlwZS5zcGVjLmRyYWdnYWJsZSlcbiAgICAgICAgICAgIHRoaXMuZG9tLmRyYWdnYWJsZSA9IHRydWU7XG4gICAgfVxuICAgIC8vIFJlbW92ZSBzZWxlY3RlZCBub2RlIG1hcmtpbmcgZnJvbSB0aGlzIG5vZGUuXG4gICAgZGVzZWxlY3ROb2RlKCkge1xuICAgICAgICBpZiAodGhpcy5ub2RlRE9NLm5vZGVUeXBlID09IDEpIHtcbiAgICAgICAgICAgIHRoaXMubm9kZURPTS5jbGFzc0xpc3QucmVtb3ZlKFwiUHJvc2VNaXJyb3Itc2VsZWN0ZWRub2RlXCIpO1xuICAgICAgICAgICAgaWYgKHRoaXMuY29udGVudERPTSB8fCAhdGhpcy5ub2RlLnR5cGUuc3BlYy5kcmFnZ2FibGUpXG4gICAgICAgICAgICAgICAgdGhpcy5kb20ucmVtb3ZlQXR0cmlidXRlKFwiZHJhZ2dhYmxlXCIpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldCBkb21BdG9tKCkgeyByZXR1cm4gdGhpcy5ub2RlLmlzQXRvbTsgfVxufVxuLy8gQ3JlYXRlIGEgdmlldyBkZXNjIGZvciB0aGUgdG9wLWxldmVsIGRvY3VtZW50IG5vZGUsIHRvIGJlIGV4cG9ydGVkXG4vLyBhbmQgdXNlZCBieSB0aGUgdmlldyBjbGFzcy5cbmZ1bmN0aW9uIGRvY1ZpZXdEZXNjKGRvYywgb3V0ZXJEZWNvLCBpbm5lckRlY28sIGRvbSwgdmlldykge1xuICAgIGFwcGx5T3V0ZXJEZWNvKGRvbSwgb3V0ZXJEZWNvLCBkb2MpO1xuICAgIGxldCBkb2NWaWV3ID0gbmV3IE5vZGVWaWV3RGVzYyh1bmRlZmluZWQsIGRvYywgb3V0ZXJEZWNvLCBpbm5lckRlY28sIGRvbSwgZG9tLCBkb20sIHZpZXcsIDApO1xuICAgIGlmIChkb2NWaWV3LmNvbnRlbnRET00pXG4gICAgICAgIGRvY1ZpZXcudXBkYXRlQ2hpbGRyZW4odmlldywgMCk7XG4gICAgcmV0dXJuIGRvY1ZpZXc7XG59XG5jbGFzcyBUZXh0Vmlld0Rlc2MgZXh0ZW5kcyBOb2RlVmlld0Rlc2Mge1xuICAgIGNvbnN0cnVjdG9yKHBhcmVudCwgbm9kZSwgb3V0ZXJEZWNvLCBpbm5lckRlY28sIGRvbSwgbm9kZURPTSwgdmlldykge1xuICAgICAgICBzdXBlcihwYXJlbnQsIG5vZGUsIG91dGVyRGVjbywgaW5uZXJEZWNvLCBkb20sIG51bGwsIG5vZGVET00sIHZpZXcsIDApO1xuICAgIH1cbiAgICBwYXJzZVJ1bGUoKSB7XG4gICAgICAgIGxldCBza2lwID0gdGhpcy5ub2RlRE9NLnBhcmVudE5vZGU7XG4gICAgICAgIHdoaWxlIChza2lwICYmIHNraXAgIT0gdGhpcy5kb20gJiYgIXNraXAucG1Jc0RlY28pXG4gICAgICAgICAgICBza2lwID0gc2tpcC5wYXJlbnROb2RlO1xuICAgICAgICByZXR1cm4geyBza2lwOiAoc2tpcCB8fCB0cnVlKSB9O1xuICAgIH1cbiAgICB1cGRhdGUobm9kZSwgb3V0ZXJEZWNvLCBpbm5lckRlY28sIHZpZXcpIHtcbiAgICAgICAgaWYgKHRoaXMuZGlydHkgPT0gTk9ERV9ESVJUWSB8fCAodGhpcy5kaXJ0eSAhPSBOT1RfRElSVFkgJiYgIXRoaXMuaW5QYXJlbnQoKSkgfHxcbiAgICAgICAgICAgICFub2RlLnNhbWVNYXJrdXAodGhpcy5ub2RlKSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgdGhpcy51cGRhdGVPdXRlckRlY28ob3V0ZXJEZWNvKTtcbiAgICAgICAgaWYgKCh0aGlzLmRpcnR5ICE9IE5PVF9ESVJUWSB8fCBub2RlLnRleHQgIT0gdGhpcy5ub2RlLnRleHQpICYmIG5vZGUudGV4dCAhPSB0aGlzLm5vZGVET00ubm9kZVZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLm5vZGVET00ubm9kZVZhbHVlID0gbm9kZS50ZXh0O1xuICAgICAgICAgICAgaWYgKHZpZXcudHJhY2tXcml0ZXMgPT0gdGhpcy5ub2RlRE9NKVxuICAgICAgICAgICAgICAgIHZpZXcudHJhY2tXcml0ZXMgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubm9kZSA9IG5vZGU7XG4gICAgICAgIHRoaXMuZGlydHkgPSBOT1RfRElSVFk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpblBhcmVudCgpIHtcbiAgICAgICAgbGV0IHBhcmVudERPTSA9IHRoaXMucGFyZW50LmNvbnRlbnRET007XG4gICAgICAgIGZvciAobGV0IG4gPSB0aGlzLm5vZGVET007IG47IG4gPSBuLnBhcmVudE5vZGUpXG4gICAgICAgICAgICBpZiAobiA9PSBwYXJlbnRET00pXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgZG9tRnJvbVBvcyhwb3MpIHtcbiAgICAgICAgcmV0dXJuIHsgbm9kZTogdGhpcy5ub2RlRE9NLCBvZmZzZXQ6IHBvcyB9O1xuICAgIH1cbiAgICBsb2NhbFBvc0Zyb21ET00oZG9tLCBvZmZzZXQsIGJpYXMpIHtcbiAgICAgICAgaWYgKGRvbSA9PSB0aGlzLm5vZGVET00pXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5wb3NBdFN0YXJ0ICsgTWF0aC5taW4ob2Zmc2V0LCB0aGlzLm5vZGUudGV4dC5sZW5ndGgpO1xuICAgICAgICByZXR1cm4gc3VwZXIubG9jYWxQb3NGcm9tRE9NKGRvbSwgb2Zmc2V0LCBiaWFzKTtcbiAgICB9XG4gICAgaWdub3JlTXV0YXRpb24obXV0YXRpb24pIHtcbiAgICAgICAgcmV0dXJuIG11dGF0aW9uLnR5cGUgIT0gXCJjaGFyYWN0ZXJEYXRhXCIgJiYgbXV0YXRpb24udHlwZSAhPSBcInNlbGVjdGlvblwiO1xuICAgIH1cbiAgICBzbGljZShmcm9tLCB0bywgdmlldykge1xuICAgICAgICBsZXQgbm9kZSA9IHRoaXMubm9kZS5jdXQoZnJvbSwgdG8pLCBkb20gPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShub2RlLnRleHQpO1xuICAgICAgICByZXR1cm4gbmV3IFRleHRWaWV3RGVzYyh0aGlzLnBhcmVudCwgbm9kZSwgdGhpcy5vdXRlckRlY28sIHRoaXMuaW5uZXJEZWNvLCBkb20sIGRvbSwgdmlldyk7XG4gICAgfVxuICAgIG1hcmtEaXJ0eShmcm9tLCB0bykge1xuICAgICAgICBzdXBlci5tYXJrRGlydHkoZnJvbSwgdG8pO1xuICAgICAgICBpZiAodGhpcy5kb20gIT0gdGhpcy5ub2RlRE9NICYmIChmcm9tID09IDAgfHwgdG8gPT0gdGhpcy5ub2RlRE9NLm5vZGVWYWx1ZS5sZW5ndGgpKVxuICAgICAgICAgICAgdGhpcy5kaXJ0eSA9IE5PREVfRElSVFk7XG4gICAgfVxuICAgIGdldCBkb21BdG9tKCkgeyByZXR1cm4gZmFsc2U7IH1cbiAgICBpc1RleHQodGV4dCkgeyByZXR1cm4gdGhpcy5ub2RlLnRleHQgPT0gdGV4dDsgfVxufVxuLy8gQSBkdW1teSBkZXNjIHVzZWQgdG8gdGFnIHRyYWlsaW5nIEJSIG9yIElNRyBub2RlcyBjcmVhdGVkIHRvIHdvcmtcbi8vIGFyb3VuZCBjb250ZW50RWRpdGFibGUgdGVycmlibGVuZXNzLlxuY2xhc3MgVHJhaWxpbmdIYWNrVmlld0Rlc2MgZXh0ZW5kcyBWaWV3RGVzYyB7XG4gICAgcGFyc2VSdWxlKCkgeyByZXR1cm4geyBpZ25vcmU6IHRydWUgfTsgfVxuICAgIG1hdGNoZXNIYWNrKG5vZGVOYW1lKSB7IHJldHVybiB0aGlzLmRpcnR5ID09IE5PVF9ESVJUWSAmJiB0aGlzLmRvbS5ub2RlTmFtZSA9PSBub2RlTmFtZTsgfVxuICAgIGdldCBkb21BdG9tKCkgeyByZXR1cm4gdHJ1ZTsgfVxuICAgIGdldCBpZ25vcmVGb3JDb29yZHMoKSB7IHJldHVybiB0aGlzLmRvbS5ub2RlTmFtZSA9PSBcIklNR1wiOyB9XG59XG4vLyBBIHNlcGFyYXRlIHN1YmNsYXNzIGlzIHVzZWQgZm9yIGN1c3RvbWl6ZWQgbm9kZSB2aWV3cywgc28gdGhhdCB0aGVcbi8vIGV4dHJhIGNoZWNrcyBvbmx5IGhhdmUgdG8gYmUgbWFkZSBmb3Igbm9kZXMgdGhhdCBhcmUgYWN0dWFsbHlcbi8vIGN1c3RvbWl6ZWQuXG5jbGFzcyBDdXN0b21Ob2RlVmlld0Rlc2MgZXh0ZW5kcyBOb2RlVmlld0Rlc2Mge1xuICAgIGNvbnN0cnVjdG9yKHBhcmVudCwgbm9kZSwgb3V0ZXJEZWNvLCBpbm5lckRlY28sIGRvbSwgY29udGVudERPTSwgbm9kZURPTSwgc3BlYywgdmlldywgcG9zKSB7XG4gICAgICAgIHN1cGVyKHBhcmVudCwgbm9kZSwgb3V0ZXJEZWNvLCBpbm5lckRlY28sIGRvbSwgY29udGVudERPTSwgbm9kZURPTSwgdmlldywgcG9zKTtcbiAgICAgICAgdGhpcy5zcGVjID0gc3BlYztcbiAgICB9XG4gICAgLy8gQSBjdXN0b20gYHVwZGF0ZWAgbWV0aG9kIGdldHMgdG8gZGVjaWRlIHdoZXRoZXIgdGhlIHVwZGF0ZSBnb2VzXG4gICAgLy8gdGhyb3VnaC4gSWYgaXQgZG9lcywgYW5kIHRoZXJlJ3MgYSBgY29udGVudERPTWAgbm9kZSwgb3VyIGxvZ2ljXG4gICAgLy8gdXBkYXRlcyB0aGUgY2hpbGRyZW4uXG4gICAgdXBkYXRlKG5vZGUsIG91dGVyRGVjbywgaW5uZXJEZWNvLCB2aWV3KSB7XG4gICAgICAgIGlmICh0aGlzLmRpcnR5ID09IE5PREVfRElSVFkpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGlmICh0aGlzLnNwZWMudXBkYXRlICYmICh0aGlzLm5vZGUudHlwZSA9PSBub2RlLnR5cGUgfHwgdGhpcy5zcGVjLm11bHRpVHlwZSkpIHtcbiAgICAgICAgICAgIGxldCByZXN1bHQgPSB0aGlzLnNwZWMudXBkYXRlKG5vZGUsIG91dGVyRGVjbywgaW5uZXJEZWNvKTtcbiAgICAgICAgICAgIGlmIChyZXN1bHQpXG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVJbm5lcihub2RlLCBvdXRlckRlY28sIGlubmVyRGVjbywgdmlldyk7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKCF0aGlzLmNvbnRlbnRET00gJiYgIW5vZGUuaXNMZWFmKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gc3VwZXIudXBkYXRlKG5vZGUsIG91dGVyRGVjbywgaW5uZXJEZWNvLCB2aWV3KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBzZWxlY3ROb2RlKCkge1xuICAgICAgICB0aGlzLnNwZWMuc2VsZWN0Tm9kZSA/IHRoaXMuc3BlYy5zZWxlY3ROb2RlKCkgOiBzdXBlci5zZWxlY3ROb2RlKCk7XG4gICAgfVxuICAgIGRlc2VsZWN0Tm9kZSgpIHtcbiAgICAgICAgdGhpcy5zcGVjLmRlc2VsZWN0Tm9kZSA/IHRoaXMuc3BlYy5kZXNlbGVjdE5vZGUoKSA6IHN1cGVyLmRlc2VsZWN0Tm9kZSgpO1xuICAgIH1cbiAgICBzZXRTZWxlY3Rpb24oYW5jaG9yLCBoZWFkLCB2aWV3LCBmb3JjZSkge1xuICAgICAgICB0aGlzLnNwZWMuc2V0U2VsZWN0aW9uID8gdGhpcy5zcGVjLnNldFNlbGVjdGlvbihhbmNob3IsIGhlYWQsIHZpZXcucm9vdClcbiAgICAgICAgICAgIDogc3VwZXIuc2V0U2VsZWN0aW9uKGFuY2hvciwgaGVhZCwgdmlldywgZm9yY2UpO1xuICAgIH1cbiAgICBkZXN0cm95KCkge1xuICAgICAgICBpZiAodGhpcy5zcGVjLmRlc3Ryb3kpXG4gICAgICAgICAgICB0aGlzLnNwZWMuZGVzdHJveSgpO1xuICAgICAgICBzdXBlci5kZXN0cm95KCk7XG4gICAgfVxuICAgIHN0b3BFdmVudChldmVudCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zcGVjLnN0b3BFdmVudCA/IHRoaXMuc3BlYy5zdG9wRXZlbnQoZXZlbnQpIDogZmFsc2U7XG4gICAgfVxuICAgIGlnbm9yZU11dGF0aW9uKG11dGF0aW9uKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNwZWMuaWdub3JlTXV0YXRpb24gPyB0aGlzLnNwZWMuaWdub3JlTXV0YXRpb24obXV0YXRpb24pIDogc3VwZXIuaWdub3JlTXV0YXRpb24obXV0YXRpb24pO1xuICAgIH1cbn1cbi8vIFN5bmMgdGhlIGNvbnRlbnQgb2YgdGhlIGdpdmVuIERPTSBub2RlIHdpdGggdGhlIG5vZGVzIGFzc29jaWF0ZWRcbi8vIHdpdGggdGhlIGdpdmVuIGFycmF5IG9mIHZpZXcgZGVzY3MsIHJlY3Vyc2luZyBpbnRvIG1hcmsgZGVzY3Ncbi8vIGJlY2F1c2UgdGhpcyBzaG91bGQgc3luYyB0aGUgc3VidHJlZSBmb3IgYSB3aG9sZSBub2RlIGF0IGEgdGltZS5cbmZ1bmN0aW9uIHJlbmRlckRlc2NzKHBhcmVudERPTSwgZGVzY3MsIHZpZXcpIHtcbiAgICBsZXQgZG9tID0gcGFyZW50RE9NLmZpcnN0Q2hpbGQsIHdyaXR0ZW4gPSBmYWxzZTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRlc2NzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxldCBkZXNjID0gZGVzY3NbaV0sIGNoaWxkRE9NID0gZGVzYy5kb207XG4gICAgICAgIGlmIChjaGlsZERPTS5wYXJlbnROb2RlID09IHBhcmVudERPTSkge1xuICAgICAgICAgICAgd2hpbGUgKGNoaWxkRE9NICE9IGRvbSkge1xuICAgICAgICAgICAgICAgIGRvbSA9IHJtKGRvbSk7XG4gICAgICAgICAgICAgICAgd3JpdHRlbiA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkb20gPSBkb20ubmV4dFNpYmxpbmc7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB3cml0dGVuID0gdHJ1ZTtcbiAgICAgICAgICAgIHBhcmVudERPTS5pbnNlcnRCZWZvcmUoY2hpbGRET00sIGRvbSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRlc2MgaW5zdGFuY2VvZiBNYXJrVmlld0Rlc2MpIHtcbiAgICAgICAgICAgIGxldCBwb3MgPSBkb20gPyBkb20ucHJldmlvdXNTaWJsaW5nIDogcGFyZW50RE9NLmxhc3RDaGlsZDtcbiAgICAgICAgICAgIHJlbmRlckRlc2NzKGRlc2MuY29udGVudERPTSwgZGVzYy5jaGlsZHJlbiwgdmlldyk7XG4gICAgICAgICAgICBkb20gPSBwb3MgPyBwb3MubmV4dFNpYmxpbmcgOiBwYXJlbnRET00uZmlyc3RDaGlsZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICB3aGlsZSAoZG9tKSB7XG4gICAgICAgIGRvbSA9IHJtKGRvbSk7XG4gICAgICAgIHdyaXR0ZW4gPSB0cnVlO1xuICAgIH1cbiAgICBpZiAod3JpdHRlbiAmJiB2aWV3LnRyYWNrV3JpdGVzID09IHBhcmVudERPTSlcbiAgICAgICAgdmlldy50cmFja1dyaXRlcyA9IG51bGw7XG59XG5jb25zdCBPdXRlckRlY29MZXZlbCA9IGZ1bmN0aW9uIChub2RlTmFtZSkge1xuICAgIGlmIChub2RlTmFtZSlcbiAgICAgICAgdGhpcy5ub2RlTmFtZSA9IG5vZGVOYW1lO1xufTtcbk91dGVyRGVjb0xldmVsLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG5jb25zdCBub0RlY28gPSBbbmV3IE91dGVyRGVjb0xldmVsXTtcbmZ1bmN0aW9uIGNvbXB1dGVPdXRlckRlY28ob3V0ZXJEZWNvLCBub2RlLCBuZWVkc1dyYXApIHtcbiAgICBpZiAob3V0ZXJEZWNvLmxlbmd0aCA9PSAwKVxuICAgICAgICByZXR1cm4gbm9EZWNvO1xuICAgIGxldCB0b3AgPSBuZWVkc1dyYXAgPyBub0RlY29bMF0gOiBuZXcgT3V0ZXJEZWNvTGV2ZWwsIHJlc3VsdCA9IFt0b3BdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb3V0ZXJEZWNvLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxldCBhdHRycyA9IG91dGVyRGVjb1tpXS50eXBlLmF0dHJzO1xuICAgICAgICBpZiAoIWF0dHJzKVxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIGlmIChhdHRycy5ub2RlTmFtZSlcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKHRvcCA9IG5ldyBPdXRlckRlY29MZXZlbChhdHRycy5ub2RlTmFtZSkpO1xuICAgICAgICBmb3IgKGxldCBuYW1lIGluIGF0dHJzKSB7XG4gICAgICAgICAgICBsZXQgdmFsID0gYXR0cnNbbmFtZV07XG4gICAgICAgICAgICBpZiAodmFsID09IG51bGwpXG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICBpZiAobmVlZHNXcmFwICYmIHJlc3VsdC5sZW5ndGggPT0gMSlcbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaCh0b3AgPSBuZXcgT3V0ZXJEZWNvTGV2ZWwobm9kZS5pc0lubGluZSA/IFwic3BhblwiIDogXCJkaXZcIikpO1xuICAgICAgICAgICAgaWYgKG5hbWUgPT0gXCJjbGFzc1wiKVxuICAgICAgICAgICAgICAgIHRvcC5jbGFzcyA9ICh0b3AuY2xhc3MgPyB0b3AuY2xhc3MgKyBcIiBcIiA6IFwiXCIpICsgdmFsO1xuICAgICAgICAgICAgZWxzZSBpZiAobmFtZSA9PSBcInN0eWxlXCIpXG4gICAgICAgICAgICAgICAgdG9wLnN0eWxlID0gKHRvcC5zdHlsZSA/IHRvcC5zdHlsZSArIFwiO1wiIDogXCJcIikgKyB2YWw7XG4gICAgICAgICAgICBlbHNlIGlmIChuYW1lICE9IFwibm9kZU5hbWVcIilcbiAgICAgICAgICAgICAgICB0b3BbbmFtZV0gPSB2YWw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbmZ1bmN0aW9uIHBhdGNoT3V0ZXJEZWNvKG91dGVyRE9NLCBub2RlRE9NLCBwcmV2Q29tcHV0ZWQsIGN1ckNvbXB1dGVkKSB7XG4gICAgLy8gU2hvcnRjdXQgZm9yIHRyaXZpYWwgY2FzZVxuICAgIGlmIChwcmV2Q29tcHV0ZWQgPT0gbm9EZWNvICYmIGN1ckNvbXB1dGVkID09IG5vRGVjbylcbiAgICAgICAgcmV0dXJuIG5vZGVET007XG4gICAgbGV0IGN1ckRPTSA9IG5vZGVET007XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjdXJDb21wdXRlZC5sZW5ndGg7IGkrKykge1xuICAgICAgICBsZXQgZGVjbyA9IGN1ckNvbXB1dGVkW2ldLCBwcmV2ID0gcHJldkNvbXB1dGVkW2ldO1xuICAgICAgICBpZiAoaSkge1xuICAgICAgICAgICAgbGV0IHBhcmVudDtcbiAgICAgICAgICAgIGlmIChwcmV2ICYmIHByZXYubm9kZU5hbWUgPT0gZGVjby5ub2RlTmFtZSAmJiBjdXJET00gIT0gb3V0ZXJET00gJiZcbiAgICAgICAgICAgICAgICAocGFyZW50ID0gY3VyRE9NLnBhcmVudE5vZGUpICYmIHBhcmVudC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09IGRlY28ubm9kZU5hbWUpIHtcbiAgICAgICAgICAgICAgICBjdXJET00gPSBwYXJlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBwYXJlbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KGRlY28ubm9kZU5hbWUpO1xuICAgICAgICAgICAgICAgIHBhcmVudC5wbUlzRGVjbyA9IHRydWU7XG4gICAgICAgICAgICAgICAgcGFyZW50LmFwcGVuZENoaWxkKGN1ckRPTSk7XG4gICAgICAgICAgICAgICAgcHJldiA9IG5vRGVjb1swXTtcbiAgICAgICAgICAgICAgICBjdXJET00gPSBwYXJlbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcGF0Y2hBdHRyaWJ1dGVzKGN1ckRPTSwgcHJldiB8fCBub0RlY29bMF0sIGRlY28pO1xuICAgIH1cbiAgICByZXR1cm4gY3VyRE9NO1xufVxuZnVuY3Rpb24gcGF0Y2hBdHRyaWJ1dGVzKGRvbSwgcHJldiwgY3VyKSB7XG4gICAgZm9yIChsZXQgbmFtZSBpbiBwcmV2KVxuICAgICAgICBpZiAobmFtZSAhPSBcImNsYXNzXCIgJiYgbmFtZSAhPSBcInN0eWxlXCIgJiYgbmFtZSAhPSBcIm5vZGVOYW1lXCIgJiYgIShuYW1lIGluIGN1cikpXG4gICAgICAgICAgICBkb20ucmVtb3ZlQXR0cmlidXRlKG5hbWUpO1xuICAgIGZvciAobGV0IG5hbWUgaW4gY3VyKVxuICAgICAgICBpZiAobmFtZSAhPSBcImNsYXNzXCIgJiYgbmFtZSAhPSBcInN0eWxlXCIgJiYgbmFtZSAhPSBcIm5vZGVOYW1lXCIgJiYgY3VyW25hbWVdICE9IHByZXZbbmFtZV0pXG4gICAgICAgICAgICBkb20uc2V0QXR0cmlidXRlKG5hbWUsIGN1cltuYW1lXSk7XG4gICAgaWYgKHByZXYuY2xhc3MgIT0gY3VyLmNsYXNzKSB7XG4gICAgICAgIGxldCBwcmV2TGlzdCA9IHByZXYuY2xhc3MgPyBwcmV2LmNsYXNzLnNwbGl0KFwiIFwiKS5maWx0ZXIoQm9vbGVhbikgOiBbXTtcbiAgICAgICAgbGV0IGN1ckxpc3QgPSBjdXIuY2xhc3MgPyBjdXIuY2xhc3Muc3BsaXQoXCIgXCIpLmZpbHRlcihCb29sZWFuKSA6IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHByZXZMaXN0Lmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgaWYgKGN1ckxpc3QuaW5kZXhPZihwcmV2TGlzdFtpXSkgPT0gLTEpXG4gICAgICAgICAgICAgICAgZG9tLmNsYXNzTGlzdC5yZW1vdmUocHJldkxpc3RbaV0pO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGN1ckxpc3QubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICBpZiAocHJldkxpc3QuaW5kZXhPZihjdXJMaXN0W2ldKSA9PSAtMSlcbiAgICAgICAgICAgICAgICBkb20uY2xhc3NMaXN0LmFkZChjdXJMaXN0W2ldKTtcbiAgICAgICAgaWYgKGRvbS5jbGFzc0xpc3QubGVuZ3RoID09IDApXG4gICAgICAgICAgICBkb20ucmVtb3ZlQXR0cmlidXRlKFwiY2xhc3NcIik7XG4gICAgfVxuICAgIGlmIChwcmV2LnN0eWxlICE9IGN1ci5zdHlsZSkge1xuICAgICAgICBpZiAocHJldi5zdHlsZSkge1xuICAgICAgICAgICAgbGV0IHByb3AgPSAvXFxzKihbXFx3XFwtXFx4YTEtXFx1ZmZmZl0rKVxccyo6KD86XCIoPzpcXFxcLnxbXlwiXSkqXCJ8Jyg/OlxcXFwufFteJ10pKid8XFwoLio/XFwpfFteO10pKi9nLCBtO1xuICAgICAgICAgICAgd2hpbGUgKG0gPSBwcm9wLmV4ZWMocHJldi5zdHlsZSkpXG4gICAgICAgICAgICAgICAgZG9tLnN0eWxlLnJlbW92ZVByb3BlcnR5KG1bMV0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjdXIuc3R5bGUpXG4gICAgICAgICAgICBkb20uc3R5bGUuY3NzVGV4dCArPSBjdXIuc3R5bGU7XG4gICAgfVxufVxuZnVuY3Rpb24gYXBwbHlPdXRlckRlY28oZG9tLCBkZWNvLCBub2RlKSB7XG4gICAgcmV0dXJuIHBhdGNoT3V0ZXJEZWNvKGRvbSwgZG9tLCBub0RlY28sIGNvbXB1dGVPdXRlckRlY28oZGVjbywgbm9kZSwgZG9tLm5vZGVUeXBlICE9IDEpKTtcbn1cbmZ1bmN0aW9uIHNhbWVPdXRlckRlY28oYSwgYikge1xuICAgIGlmIChhLmxlbmd0aCAhPSBiLmxlbmd0aClcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKylcbiAgICAgICAgaWYgKCFhW2ldLnR5cGUuZXEoYltpXS50eXBlKSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gdHJ1ZTtcbn1cbi8vIFJlbW92ZSBhIERPTSBub2RlIGFuZCByZXR1cm4gaXRzIG5leHQgc2libGluZy5cbmZ1bmN0aW9uIHJtKGRvbSkge1xuICAgIGxldCBuZXh0ID0gZG9tLm5leHRTaWJsaW5nO1xuICAgIGRvbS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGRvbSk7XG4gICAgcmV0dXJuIG5leHQ7XG59XG4vLyBIZWxwZXIgY2xhc3MgZm9yIGluY3JlbWVudGFsbHkgdXBkYXRpbmcgYSB0cmVlIG9mIG1hcmsgZGVzY3MgYW5kXG4vLyB0aGUgd2lkZ2V0IGFuZCBub2RlIGRlc2NzIGluc2lkZSBvZiB0aGVtLlxuY2xhc3MgVmlld1RyZWVVcGRhdGVyIHtcbiAgICBjb25zdHJ1Y3Rvcih0b3AsIGxvY2ssIHZpZXcpIHtcbiAgICAgICAgdGhpcy5sb2NrID0gbG9jaztcbiAgICAgICAgdGhpcy52aWV3ID0gdmlldztcbiAgICAgICAgLy8gSW5kZXggaW50byBgdGhpcy50b3BgJ3MgY2hpbGQgYXJyYXksIHJlcHJlc2VudHMgdGhlIGN1cnJlbnRcbiAgICAgICAgLy8gdXBkYXRlIHBvc2l0aW9uLlxuICAgICAgICB0aGlzLmluZGV4ID0gMDtcbiAgICAgICAgLy8gV2hlbiBlbnRlcmluZyBhIG1hcmssIHRoZSBjdXJyZW50IHRvcCBhbmQgaW5kZXggYXJlIHB1c2hlZFxuICAgICAgICAvLyBvbnRvIHRoaXMuXG4gICAgICAgIHRoaXMuc3RhY2sgPSBbXTtcbiAgICAgICAgLy8gVHJhY2tzIHdoZXRoZXIgYW55dGhpbmcgd2FzIGNoYW5nZWRcbiAgICAgICAgdGhpcy5jaGFuZ2VkID0gZmFsc2U7XG4gICAgICAgIHRoaXMudG9wID0gdG9wO1xuICAgICAgICB0aGlzLnByZU1hdGNoID0gcHJlTWF0Y2godG9wLm5vZGUuY29udGVudCwgdG9wKTtcbiAgICB9XG4gICAgLy8gRGVzdHJveSBhbmQgcmVtb3ZlIHRoZSBjaGlsZHJlbiBiZXR3ZWVuIHRoZSBnaXZlbiBpbmRpY2VzIGluXG4gICAgLy8gYHRoaXMudG9wYC5cbiAgICBkZXN0cm95QmV0d2VlbihzdGFydCwgZW5kKSB7XG4gICAgICAgIGlmIChzdGFydCA9PSBlbmQpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIGZvciAobGV0IGkgPSBzdGFydDsgaSA8IGVuZDsgaSsrKVxuICAgICAgICAgICAgdGhpcy50b3AuY2hpbGRyZW5baV0uZGVzdHJveSgpO1xuICAgICAgICB0aGlzLnRvcC5jaGlsZHJlbi5zcGxpY2Uoc3RhcnQsIGVuZCAtIHN0YXJ0KTtcbiAgICAgICAgdGhpcy5jaGFuZ2VkID0gdHJ1ZTtcbiAgICB9XG4gICAgLy8gRGVzdHJveSBhbGwgcmVtYWluaW5nIGNoaWxkcmVuIGluIGB0aGlzLnRvcGAuXG4gICAgZGVzdHJveVJlc3QoKSB7XG4gICAgICAgIHRoaXMuZGVzdHJveUJldHdlZW4odGhpcy5pbmRleCwgdGhpcy50b3AuY2hpbGRyZW4ubGVuZ3RoKTtcbiAgICB9XG4gICAgLy8gU3luYyB0aGUgY3VycmVudCBzdGFjayBvZiBtYXJrIGRlc2NzIHdpdGggdGhlIGdpdmVuIGFycmF5IG9mXG4gICAgLy8gbWFya3MsIHJldXNpbmcgZXhpc3RpbmcgbWFyayBkZXNjcyB3aGVuIHBvc3NpYmxlLlxuICAgIHN5bmNUb01hcmtzKG1hcmtzLCBpbmxpbmUsIHZpZXcpIHtcbiAgICAgICAgbGV0IGtlZXAgPSAwLCBkZXB0aCA9IHRoaXMuc3RhY2subGVuZ3RoID4+IDE7XG4gICAgICAgIGxldCBtYXhLZWVwID0gTWF0aC5taW4oZGVwdGgsIG1hcmtzLmxlbmd0aCk7XG4gICAgICAgIHdoaWxlIChrZWVwIDwgbWF4S2VlcCAmJlxuICAgICAgICAgICAgKGtlZXAgPT0gZGVwdGggLSAxID8gdGhpcy50b3AgOiB0aGlzLnN0YWNrWyhrZWVwICsgMSkgPDwgMV0pXG4gICAgICAgICAgICAgICAgLm1hdGNoZXNNYXJrKG1hcmtzW2tlZXBdKSAmJiBtYXJrc1trZWVwXS50eXBlLnNwZWMuc3Bhbm5pbmcgIT09IGZhbHNlKVxuICAgICAgICAgICAga2VlcCsrO1xuICAgICAgICB3aGlsZSAoa2VlcCA8IGRlcHRoKSB7XG4gICAgICAgICAgICB0aGlzLmRlc3Ryb3lSZXN0KCk7XG4gICAgICAgICAgICB0aGlzLnRvcC5kaXJ0eSA9IE5PVF9ESVJUWTtcbiAgICAgICAgICAgIHRoaXMuaW5kZXggPSB0aGlzLnN0YWNrLnBvcCgpO1xuICAgICAgICAgICAgdGhpcy50b3AgPSB0aGlzLnN0YWNrLnBvcCgpO1xuICAgICAgICAgICAgZGVwdGgtLTtcbiAgICAgICAgfVxuICAgICAgICB3aGlsZSAoZGVwdGggPCBtYXJrcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoaXMuc3RhY2sucHVzaCh0aGlzLnRvcCwgdGhpcy5pbmRleCArIDEpO1xuICAgICAgICAgICAgbGV0IGZvdW5kID0gLTE7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gdGhpcy5pbmRleDsgaSA8IE1hdGgubWluKHRoaXMuaW5kZXggKyAzLCB0aGlzLnRvcC5jaGlsZHJlbi5sZW5ndGgpOyBpKyspIHtcbiAgICAgICAgICAgICAgICBsZXQgbmV4dCA9IHRoaXMudG9wLmNoaWxkcmVuW2ldO1xuICAgICAgICAgICAgICAgIGlmIChuZXh0Lm1hdGNoZXNNYXJrKG1hcmtzW2RlcHRoXSkgJiYgIXRoaXMuaXNMb2NrZWQobmV4dC5kb20pKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvdW5kID0gaTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGZvdW5kID4gLTEpIHtcbiAgICAgICAgICAgICAgICBpZiAoZm91bmQgPiB0aGlzLmluZGV4KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2hhbmdlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGVzdHJveUJldHdlZW4odGhpcy5pbmRleCwgZm91bmQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnRvcCA9IHRoaXMudG9wLmNoaWxkcmVuW3RoaXMuaW5kZXhdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgbGV0IG1hcmtEZXNjID0gTWFya1ZpZXdEZXNjLmNyZWF0ZSh0aGlzLnRvcCwgbWFya3NbZGVwdGhdLCBpbmxpbmUsIHZpZXcpO1xuICAgICAgICAgICAgICAgIHRoaXMudG9wLmNoaWxkcmVuLnNwbGljZSh0aGlzLmluZGV4LCAwLCBtYXJrRGVzYyk7XG4gICAgICAgICAgICAgICAgdGhpcy50b3AgPSBtYXJrRGVzYztcbiAgICAgICAgICAgICAgICB0aGlzLmNoYW5nZWQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5pbmRleCA9IDA7XG4gICAgICAgICAgICBkZXB0aCsrO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIFRyeSB0byBmaW5kIGEgbm9kZSBkZXNjIG1hdGNoaW5nIHRoZSBnaXZlbiBkYXRhLiBTa2lwIG92ZXIgaXQgYW5kXG4gICAgLy8gcmV0dXJuIHRydWUgd2hlbiBzdWNjZXNzZnVsLlxuICAgIGZpbmROb2RlTWF0Y2gobm9kZSwgb3V0ZXJEZWNvLCBpbm5lckRlY28sIGluZGV4KSB7XG4gICAgICAgIGxldCBmb3VuZCA9IC0xLCB0YXJnZXREZXNjO1xuICAgICAgICBpZiAoaW5kZXggPj0gdGhpcy5wcmVNYXRjaC5pbmRleCAmJlxuICAgICAgICAgICAgKHRhcmdldERlc2MgPSB0aGlzLnByZU1hdGNoLm1hdGNoZXNbaW5kZXggLSB0aGlzLnByZU1hdGNoLmluZGV4XSkucGFyZW50ID09IHRoaXMudG9wICYmXG4gICAgICAgICAgICB0YXJnZXREZXNjLm1hdGNoZXNOb2RlKG5vZGUsIG91dGVyRGVjbywgaW5uZXJEZWNvKSkge1xuICAgICAgICAgICAgZm91bmQgPSB0aGlzLnRvcC5jaGlsZHJlbi5pbmRleE9mKHRhcmdldERlc2MsIHRoaXMuaW5kZXgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IHRoaXMuaW5kZXgsIGUgPSBNYXRoLm1pbih0aGlzLnRvcC5jaGlsZHJlbi5sZW5ndGgsIGkgKyA1KTsgaSA8IGU7IGkrKykge1xuICAgICAgICAgICAgICAgIGxldCBjaGlsZCA9IHRoaXMudG9wLmNoaWxkcmVuW2ldO1xuICAgICAgICAgICAgICAgIGlmIChjaGlsZC5tYXRjaGVzTm9kZShub2RlLCBvdXRlckRlY28sIGlubmVyRGVjbykgJiYgIXRoaXMucHJlTWF0Y2gubWF0Y2hlZC5oYXMoY2hpbGQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvdW5kID0gaTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChmb3VuZCA8IDApXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIHRoaXMuZGVzdHJveUJldHdlZW4odGhpcy5pbmRleCwgZm91bmQpO1xuICAgICAgICB0aGlzLmluZGV4Kys7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICB1cGRhdGVOb2RlQXQobm9kZSwgb3V0ZXJEZWNvLCBpbm5lckRlY28sIGluZGV4LCB2aWV3KSB7XG4gICAgICAgIGxldCBjaGlsZCA9IHRoaXMudG9wLmNoaWxkcmVuW2luZGV4XTtcbiAgICAgICAgaWYgKGNoaWxkLmRpcnR5ID09IE5PREVfRElSVFkgJiYgY2hpbGQuZG9tID09IGNoaWxkLmNvbnRlbnRET00pXG4gICAgICAgICAgICBjaGlsZC5kaXJ0eSA9IENPTlRFTlRfRElSVFk7XG4gICAgICAgIGlmICghY2hpbGQudXBkYXRlKG5vZGUsIG91dGVyRGVjbywgaW5uZXJEZWNvLCB2aWV3KSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgdGhpcy5kZXN0cm95QmV0d2Vlbih0aGlzLmluZGV4LCBpbmRleCk7XG4gICAgICAgIHRoaXMuaW5kZXgrKztcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGZpbmRJbmRleFdpdGhDaGlsZChkb21Ob2RlKSB7XG4gICAgICAgIGZvciAoOzspIHtcbiAgICAgICAgICAgIGxldCBwYXJlbnQgPSBkb21Ob2RlLnBhcmVudE5vZGU7XG4gICAgICAgICAgICBpZiAoIXBhcmVudClcbiAgICAgICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgICAgICBpZiAocGFyZW50ID09IHRoaXMudG9wLmNvbnRlbnRET00pIHtcbiAgICAgICAgICAgICAgICBsZXQgZGVzYyA9IGRvbU5vZGUucG1WaWV3RGVzYztcbiAgICAgICAgICAgICAgICBpZiAoZGVzYylcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IHRoaXMuaW5kZXg7IGkgPCB0aGlzLnRvcC5jaGlsZHJlbi5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMudG9wLmNoaWxkcmVuW2ldID09IGRlc2MpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkb21Ob2RlID0gcGFyZW50O1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIFRyeSB0byB1cGRhdGUgdGhlIG5leHQgbm9kZSwgaWYgYW55LCB0byB0aGUgZ2l2ZW4gZGF0YS4gQ2hlY2tzXG4gICAgLy8gcHJlLW1hdGNoZXMgdG8gYXZvaWQgb3ZlcndyaXRpbmcgbm9kZXMgdGhhdCBjb3VsZCBzdGlsbCBiZSB1c2VkLlxuICAgIHVwZGF0ZU5leHROb2RlKG5vZGUsIG91dGVyRGVjbywgaW5uZXJEZWNvLCB2aWV3LCBpbmRleCwgcG9zKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSB0aGlzLmluZGV4OyBpIDwgdGhpcy50b3AuY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBuZXh0ID0gdGhpcy50b3AuY2hpbGRyZW5baV07XG4gICAgICAgICAgICBpZiAobmV4dCBpbnN0YW5jZW9mIE5vZGVWaWV3RGVzYykge1xuICAgICAgICAgICAgICAgIGxldCBwcmVNYXRjaCA9IHRoaXMucHJlTWF0Y2gubWF0Y2hlZC5nZXQobmV4dCk7XG4gICAgICAgICAgICAgICAgaWYgKHByZU1hdGNoICE9IG51bGwgJiYgcHJlTWF0Y2ggIT0gaW5kZXgpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICBsZXQgbmV4dERPTSA9IG5leHQuZG9tLCB1cGRhdGVkO1xuICAgICAgICAgICAgICAgIC8vIENhbid0IHVwZGF0ZSBpZiBuZXh0RE9NIGlzIG9yIGNvbnRhaW5zIHRoaXMubG9jaywgZXhjZXB0IGlmXG4gICAgICAgICAgICAgICAgLy8gaXQncyBhIHRleHQgbm9kZSB3aG9zZSBjb250ZW50IGFscmVhZHkgbWF0Y2hlcyB0aGUgbmV3IHRleHRcbiAgICAgICAgICAgICAgICAvLyBhbmQgd2hvc2UgZGVjb3JhdGlvbnMgbWF0Y2ggdGhlIG5ldyBvbmVzLlxuICAgICAgICAgICAgICAgIGxldCBsb2NrZWQgPSB0aGlzLmlzTG9ja2VkKG5leHRET00pICYmXG4gICAgICAgICAgICAgICAgICAgICEobm9kZS5pc1RleHQgJiYgbmV4dC5ub2RlICYmIG5leHQubm9kZS5pc1RleHQgJiYgbmV4dC5ub2RlRE9NLm5vZGVWYWx1ZSA9PSBub2RlLnRleHQgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIG5leHQuZGlydHkgIT0gTk9ERV9ESVJUWSAmJiBzYW1lT3V0ZXJEZWNvKG91dGVyRGVjbywgbmV4dC5vdXRlckRlY28pKTtcbiAgICAgICAgICAgICAgICBpZiAoIWxvY2tlZCAmJiBuZXh0LnVwZGF0ZShub2RlLCBvdXRlckRlY28sIGlubmVyRGVjbywgdmlldykpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kZXN0cm95QmV0d2Vlbih0aGlzLmluZGV4LCBpKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5leHQuZG9tICE9IG5leHRET00pXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNoYW5nZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmluZGV4Kys7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIGlmICghbG9ja2VkICYmICh1cGRhdGVkID0gdGhpcy5yZWNyZWF0ZVdyYXBwZXIobmV4dCwgbm9kZSwgb3V0ZXJEZWNvLCBpbm5lckRlY28sIHZpZXcsIHBvcykpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGVzdHJveUJldHdlZW4odGhpcy5pbmRleCwgaSk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudG9wLmNoaWxkcmVuW3RoaXMuaW5kZXhdID0gdXBkYXRlZDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHVwZGF0ZWQuY29udGVudERPTSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlZC5kaXJ0eSA9IENPTlRFTlRfRElSVFk7XG4gICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVkLnVwZGF0ZUNoaWxkcmVuKHZpZXcsIHBvcyArIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlZC5kaXJ0eSA9IE5PVF9ESVJUWTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNoYW5nZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmluZGV4Kys7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIC8vIFdoZW4gYSBub2RlIHdpdGggY29udGVudCBpcyByZXBsYWNlZCBieSBhIGRpZmZlcmVudCBub2RlIHdpdGhcbiAgICAvLyBpZGVudGljYWwgY29udGVudCwgbW92ZSBvdmVyIGl0cyBjaGlsZHJlbi5cbiAgICByZWNyZWF0ZVdyYXBwZXIobmV4dCwgbm9kZSwgb3V0ZXJEZWNvLCBpbm5lckRlY28sIHZpZXcsIHBvcykge1xuICAgICAgICBpZiAobmV4dC5kaXJ0eSB8fCBub2RlLmlzQXRvbSB8fCAhbmV4dC5jaGlsZHJlbi5sZW5ndGggfHxcbiAgICAgICAgICAgICFuZXh0Lm5vZGUuY29udGVudC5lcShub2RlLmNvbnRlbnQpIHx8XG4gICAgICAgICAgICAhc2FtZU91dGVyRGVjbyhvdXRlckRlY28sIG5leHQub3V0ZXJEZWNvKSB8fCAhaW5uZXJEZWNvLmVxKG5leHQuaW5uZXJEZWNvKSlcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICBsZXQgd3JhcHBlciA9IE5vZGVWaWV3RGVzYy5jcmVhdGUodGhpcy50b3AsIG5vZGUsIG91dGVyRGVjbywgaW5uZXJEZWNvLCB2aWV3LCBwb3MpO1xuICAgICAgICBpZiAod3JhcHBlci5jb250ZW50RE9NKSB7XG4gICAgICAgICAgICB3cmFwcGVyLmNoaWxkcmVuID0gbmV4dC5jaGlsZHJlbjtcbiAgICAgICAgICAgIG5leHQuY2hpbGRyZW4gPSBbXTtcbiAgICAgICAgICAgIGZvciAobGV0IGNoIG9mIHdyYXBwZXIuY2hpbGRyZW4pXG4gICAgICAgICAgICAgICAgY2gucGFyZW50ID0gd3JhcHBlcjtcbiAgICAgICAgfVxuICAgICAgICBuZXh0LmRlc3Ryb3koKTtcbiAgICAgICAgcmV0dXJuIHdyYXBwZXI7XG4gICAgfVxuICAgIC8vIEluc2VydCB0aGUgbm9kZSBhcyBhIG5ld2x5IGNyZWF0ZWQgbm9kZSBkZXNjLlxuICAgIGFkZE5vZGUobm9kZSwgb3V0ZXJEZWNvLCBpbm5lckRlY28sIHZpZXcsIHBvcykge1xuICAgICAgICBsZXQgZGVzYyA9IE5vZGVWaWV3RGVzYy5jcmVhdGUodGhpcy50b3AsIG5vZGUsIG91dGVyRGVjbywgaW5uZXJEZWNvLCB2aWV3LCBwb3MpO1xuICAgICAgICBpZiAoZGVzYy5jb250ZW50RE9NKVxuICAgICAgICAgICAgZGVzYy51cGRhdGVDaGlsZHJlbih2aWV3LCBwb3MgKyAxKTtcbiAgICAgICAgdGhpcy50b3AuY2hpbGRyZW4uc3BsaWNlKHRoaXMuaW5kZXgrKywgMCwgZGVzYyk7XG4gICAgICAgIHRoaXMuY2hhbmdlZCA9IHRydWU7XG4gICAgfVxuICAgIHBsYWNlV2lkZ2V0KHdpZGdldCwgdmlldywgcG9zKSB7XG4gICAgICAgIGxldCBuZXh0ID0gdGhpcy5pbmRleCA8IHRoaXMudG9wLmNoaWxkcmVuLmxlbmd0aCA/IHRoaXMudG9wLmNoaWxkcmVuW3RoaXMuaW5kZXhdIDogbnVsbDtcbiAgICAgICAgaWYgKG5leHQgJiYgbmV4dC5tYXRjaGVzV2lkZ2V0KHdpZGdldCkgJiZcbiAgICAgICAgICAgICh3aWRnZXQgPT0gbmV4dC53aWRnZXQgfHwgIW5leHQud2lkZ2V0LnR5cGUudG9ET00ucGFyZW50Tm9kZSkpIHtcbiAgICAgICAgICAgIHRoaXMuaW5kZXgrKztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGxldCBkZXNjID0gbmV3IFdpZGdldFZpZXdEZXNjKHRoaXMudG9wLCB3aWRnZXQsIHZpZXcsIHBvcyk7XG4gICAgICAgICAgICB0aGlzLnRvcC5jaGlsZHJlbi5zcGxpY2UodGhpcy5pbmRleCsrLCAwLCBkZXNjKTtcbiAgICAgICAgICAgIHRoaXMuY2hhbmdlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gTWFrZSBzdXJlIGEgdGV4dGJsb2NrIGxvb2tzIGFuZCBiZWhhdmVzIGNvcnJlY3RseSBpblxuICAgIC8vIGNvbnRlbnRFZGl0YWJsZS5cbiAgICBhZGRUZXh0YmxvY2tIYWNrcygpIHtcbiAgICAgICAgbGV0IGxhc3RDaGlsZCA9IHRoaXMudG9wLmNoaWxkcmVuW3RoaXMuaW5kZXggLSAxXSwgcGFyZW50ID0gdGhpcy50b3A7XG4gICAgICAgIHdoaWxlIChsYXN0Q2hpbGQgaW5zdGFuY2VvZiBNYXJrVmlld0Rlc2MpIHtcbiAgICAgICAgICAgIHBhcmVudCA9IGxhc3RDaGlsZDtcbiAgICAgICAgICAgIGxhc3RDaGlsZCA9IHBhcmVudC5jaGlsZHJlbltwYXJlbnQuY2hpbGRyZW4ubGVuZ3RoIC0gMV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFsYXN0Q2hpbGQgfHwgLy8gRW1wdHkgdGV4dGJsb2NrXG4gICAgICAgICAgICAhKGxhc3RDaGlsZCBpbnN0YW5jZW9mIFRleHRWaWV3RGVzYykgfHxcbiAgICAgICAgICAgIC9cXG4kLy50ZXN0KGxhc3RDaGlsZC5ub2RlLnRleHQpIHx8XG4gICAgICAgICAgICAodGhpcy52aWV3LnJlcXVpcmVzR2Vja29IYWNrTm9kZSAmJiAvXFxzJC8udGVzdChsYXN0Q2hpbGQubm9kZS50ZXh0KSkpIHtcbiAgICAgICAgICAgIC8vIEF2b2lkIGJ1Z3MgaW4gU2FmYXJpJ3MgY3Vyc29yIGRyYXdpbmcgKCMxMTY1KSBhbmQgQ2hyb21lJ3MgbW91c2Ugc2VsZWN0aW9uICgjMTE1MilcbiAgICAgICAgICAgIGlmICgoc2FmYXJpIHx8IGNocm9tZSkgJiYgbGFzdENoaWxkICYmIGxhc3RDaGlsZC5kb20uY29udGVudEVkaXRhYmxlID09IFwiZmFsc2VcIilcbiAgICAgICAgICAgICAgICB0aGlzLmFkZEhhY2tOb2RlKFwiSU1HXCIsIHBhcmVudCk7XG4gICAgICAgICAgICB0aGlzLmFkZEhhY2tOb2RlKFwiQlJcIiwgdGhpcy50b3ApO1xuICAgICAgICB9XG4gICAgfVxuICAgIGFkZEhhY2tOb2RlKG5vZGVOYW1lLCBwYXJlbnQpIHtcbiAgICAgICAgaWYgKHBhcmVudCA9PSB0aGlzLnRvcCAmJiB0aGlzLmluZGV4IDwgcGFyZW50LmNoaWxkcmVuLmxlbmd0aCAmJiBwYXJlbnQuY2hpbGRyZW5bdGhpcy5pbmRleF0ubWF0Y2hlc0hhY2sobm9kZU5hbWUpKSB7XG4gICAgICAgICAgICB0aGlzLmluZGV4Kys7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBsZXQgZG9tID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChub2RlTmFtZSk7XG4gICAgICAgICAgICBpZiAobm9kZU5hbWUgPT0gXCJJTUdcIikge1xuICAgICAgICAgICAgICAgIGRvbS5jbGFzc05hbWUgPSBcIlByb3NlTWlycm9yLXNlcGFyYXRvclwiO1xuICAgICAgICAgICAgICAgIGRvbS5hbHQgPSBcIlwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG5vZGVOYW1lID09IFwiQlJcIilcbiAgICAgICAgICAgICAgICBkb20uY2xhc3NOYW1lID0gXCJQcm9zZU1pcnJvci10cmFpbGluZ0JyZWFrXCI7XG4gICAgICAgICAgICBsZXQgaGFjayA9IG5ldyBUcmFpbGluZ0hhY2tWaWV3RGVzYyh0aGlzLnRvcCwgW10sIGRvbSwgbnVsbCk7XG4gICAgICAgICAgICBpZiAocGFyZW50ICE9IHRoaXMudG9wKVxuICAgICAgICAgICAgICAgIHBhcmVudC5jaGlsZHJlbi5wdXNoKGhhY2spO1xuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIHBhcmVudC5jaGlsZHJlbi5zcGxpY2UodGhpcy5pbmRleCsrLCAwLCBoYWNrKTtcbiAgICAgICAgICAgIHRoaXMuY2hhbmdlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaXNMb2NrZWQobm9kZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5sb2NrICYmIChub2RlID09IHRoaXMubG9jayB8fCBub2RlLm5vZGVUeXBlID09IDEgJiYgbm9kZS5jb250YWlucyh0aGlzLmxvY2sucGFyZW50Tm9kZSkpO1xuICAgIH1cbn1cbi8vIEl0ZXJhdGUgZnJvbSB0aGUgZW5kIG9mIHRoZSBmcmFnbWVudCBhbmQgYXJyYXkgb2YgZGVzY3MgdG8gZmluZFxuLy8gZGlyZWN0bHkgbWF0Y2hpbmcgb25lcywgaW4gb3JkZXIgdG8gYXZvaWQgb3ZlcmVhZ2VybHkgcmV1c2luZyB0aG9zZVxuLy8gZm9yIG90aGVyIG5vZGVzLiBSZXR1cm5zIHRoZSBmcmFnbWVudCBpbmRleCBvZiB0aGUgZmlyc3Qgbm9kZSB0aGF0XG4vLyBpcyBwYXJ0IG9mIHRoZSBzZXF1ZW5jZSBvZiBtYXRjaGVkIG5vZGVzIGF0IHRoZSBlbmQgb2YgdGhlXG4vLyBmcmFnbWVudC5cbmZ1bmN0aW9uIHByZU1hdGNoKGZyYWcsIHBhcmVudERlc2MpIHtcbiAgICBsZXQgY3VyRGVzYyA9IHBhcmVudERlc2MsIGRlc2NJID0gY3VyRGVzYy5jaGlsZHJlbi5sZW5ndGg7XG4gICAgbGV0IGZJID0gZnJhZy5jaGlsZENvdW50LCBtYXRjaGVkID0gbmV3IE1hcCwgbWF0Y2hlcyA9IFtdO1xuICAgIG91dGVyOiB3aGlsZSAoZkkgPiAwKSB7XG4gICAgICAgIGxldCBkZXNjO1xuICAgICAgICBmb3IgKDs7KSB7XG4gICAgICAgICAgICBpZiAoZGVzY0kpIHtcbiAgICAgICAgICAgICAgICBsZXQgbmV4dCA9IGN1ckRlc2MuY2hpbGRyZW5bZGVzY0kgLSAxXTtcbiAgICAgICAgICAgICAgICBpZiAobmV4dCBpbnN0YW5jZW9mIE1hcmtWaWV3RGVzYykge1xuICAgICAgICAgICAgICAgICAgICBjdXJEZXNjID0gbmV4dDtcbiAgICAgICAgICAgICAgICAgICAgZGVzY0kgPSBuZXh0LmNoaWxkcmVuLmxlbmd0aDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGRlc2MgPSBuZXh0O1xuICAgICAgICAgICAgICAgICAgICBkZXNjSS0tO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChjdXJEZXNjID09IHBhcmVudERlc2MpIHtcbiAgICAgICAgICAgICAgICBicmVhayBvdXRlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIEZJWE1FXG4gICAgICAgICAgICAgICAgZGVzY0kgPSBjdXJEZXNjLnBhcmVudC5jaGlsZHJlbi5pbmRleE9mKGN1ckRlc2MpO1xuICAgICAgICAgICAgICAgIGN1ckRlc2MgPSBjdXJEZXNjLnBhcmVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgbm9kZSA9IGRlc2Mubm9kZTtcbiAgICAgICAgaWYgKCFub2RlKVxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIGlmIChub2RlICE9IGZyYWcuY2hpbGQoZkkgLSAxKSlcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAtLWZJO1xuICAgICAgICBtYXRjaGVkLnNldChkZXNjLCBmSSk7XG4gICAgICAgIG1hdGNoZXMucHVzaChkZXNjKTtcbiAgICB9XG4gICAgcmV0dXJuIHsgaW5kZXg6IGZJLCBtYXRjaGVkLCBtYXRjaGVzOiBtYXRjaGVzLnJldmVyc2UoKSB9O1xufVxuZnVuY3Rpb24gY29tcGFyZVNpZGUoYSwgYikge1xuICAgIHJldHVybiBhLnR5cGUuc2lkZSAtIGIudHlwZS5zaWRlO1xufVxuLy8gVGhpcyBmdW5jdGlvbiBhYnN0cmFjdHMgaXRlcmF0aW5nIG92ZXIgdGhlIG5vZGVzIGFuZCBkZWNvcmF0aW9ucyBpblxuLy8gYSBmcmFnbWVudC4gQ2FsbHMgYG9uTm9kZWAgZm9yIGVhY2ggbm9kZSwgd2l0aCBpdHMgbG9jYWwgYW5kIGNoaWxkXG4vLyBkZWNvcmF0aW9ucy4gU3BsaXRzIHRleHQgbm9kZXMgd2hlbiB0aGVyZSBpcyBhIGRlY29yYXRpb24gc3RhcnRpbmdcbi8vIG9yIGVuZGluZyBpbnNpZGUgb2YgdGhlbS4gQ2FsbHMgYG9uV2lkZ2V0YCBmb3IgZWFjaCB3aWRnZXQuXG5mdW5jdGlvbiBpdGVyRGVjbyhwYXJlbnQsIGRlY28sIG9uV2lkZ2V0LCBvbk5vZGUpIHtcbiAgICBsZXQgbG9jYWxzID0gZGVjby5sb2NhbHMocGFyZW50KSwgb2Zmc2V0ID0gMDtcbiAgICAvLyBTaW1wbGUsIGNoZWFwIHZhcmlhbnQgZm9yIHdoZW4gdGhlcmUgYXJlIG5vIGxvY2FsIGRlY29yYXRpb25zXG4gICAgaWYgKGxvY2Fscy5sZW5ndGggPT0gMCkge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcmVudC5jaGlsZENvdW50OyBpKyspIHtcbiAgICAgICAgICAgIGxldCBjaGlsZCA9IHBhcmVudC5jaGlsZChpKTtcbiAgICAgICAgICAgIG9uTm9kZShjaGlsZCwgbG9jYWxzLCBkZWNvLmZvckNoaWxkKG9mZnNldCwgY2hpbGQpLCBpKTtcbiAgICAgICAgICAgIG9mZnNldCArPSBjaGlsZC5ub2RlU2l6ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGxldCBkZWNvSW5kZXggPSAwLCBhY3RpdmUgPSBbXSwgcmVzdE5vZGUgPSBudWxsO1xuICAgIGZvciAobGV0IHBhcmVudEluZGV4ID0gMDs7KSB7XG4gICAgICAgIGxldCB3aWRnZXQsIHdpZGdldHM7XG4gICAgICAgIHdoaWxlIChkZWNvSW5kZXggPCBsb2NhbHMubGVuZ3RoICYmIGxvY2Fsc1tkZWNvSW5kZXhdLnRvID09IG9mZnNldCkge1xuICAgICAgICAgICAgbGV0IG5leHQgPSBsb2NhbHNbZGVjb0luZGV4KytdO1xuICAgICAgICAgICAgaWYgKG5leHQud2lkZ2V0KSB7XG4gICAgICAgICAgICAgICAgaWYgKCF3aWRnZXQpXG4gICAgICAgICAgICAgICAgICAgIHdpZGdldCA9IG5leHQ7XG4gICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgICAod2lkZ2V0cyB8fCAod2lkZ2V0cyA9IFt3aWRnZXRdKSkucHVzaChuZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAod2lkZ2V0KSB7XG4gICAgICAgICAgICBpZiAod2lkZ2V0cykge1xuICAgICAgICAgICAgICAgIHdpZGdldHMuc29ydChjb21wYXJlU2lkZSk7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB3aWRnZXRzLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgICAgICAgICBvbldpZGdldCh3aWRnZXRzW2ldLCBwYXJlbnRJbmRleCwgISFyZXN0Tm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBvbldpZGdldCh3aWRnZXQsIHBhcmVudEluZGV4LCAhIXJlc3ROb2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgY2hpbGQsIGluZGV4O1xuICAgICAgICBpZiAocmVzdE5vZGUpIHtcbiAgICAgICAgICAgIGluZGV4ID0gLTE7XG4gICAgICAgICAgICBjaGlsZCA9IHJlc3ROb2RlO1xuICAgICAgICAgICAgcmVzdE5vZGUgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHBhcmVudEluZGV4IDwgcGFyZW50LmNoaWxkQ291bnQpIHtcbiAgICAgICAgICAgIGluZGV4ID0gcGFyZW50SW5kZXg7XG4gICAgICAgICAgICBjaGlsZCA9IHBhcmVudC5jaGlsZChwYXJlbnRJbmRleCsrKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYWN0aXZlLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgaWYgKGFjdGl2ZVtpXS50byA8PSBvZmZzZXQpXG4gICAgICAgICAgICAgICAgYWN0aXZlLnNwbGljZShpLS0sIDEpO1xuICAgICAgICB3aGlsZSAoZGVjb0luZGV4IDwgbG9jYWxzLmxlbmd0aCAmJiBsb2NhbHNbZGVjb0luZGV4XS5mcm9tIDw9IG9mZnNldCAmJiBsb2NhbHNbZGVjb0luZGV4XS50byA+IG9mZnNldClcbiAgICAgICAgICAgIGFjdGl2ZS5wdXNoKGxvY2Fsc1tkZWNvSW5kZXgrK10pO1xuICAgICAgICBsZXQgZW5kID0gb2Zmc2V0ICsgY2hpbGQubm9kZVNpemU7XG4gICAgICAgIGlmIChjaGlsZC5pc1RleHQpIHtcbiAgICAgICAgICAgIGxldCBjdXRBdCA9IGVuZDtcbiAgICAgICAgICAgIGlmIChkZWNvSW5kZXggPCBsb2NhbHMubGVuZ3RoICYmIGxvY2Fsc1tkZWNvSW5kZXhdLmZyb20gPCBjdXRBdClcbiAgICAgICAgICAgICAgICBjdXRBdCA9IGxvY2Fsc1tkZWNvSW5kZXhdLmZyb207XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFjdGl2ZS5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgICAgICBpZiAoYWN0aXZlW2ldLnRvIDwgY3V0QXQpXG4gICAgICAgICAgICAgICAgICAgIGN1dEF0ID0gYWN0aXZlW2ldLnRvO1xuICAgICAgICAgICAgaWYgKGN1dEF0IDwgZW5kKSB7XG4gICAgICAgICAgICAgICAgcmVzdE5vZGUgPSBjaGlsZC5jdXQoY3V0QXQgLSBvZmZzZXQpO1xuICAgICAgICAgICAgICAgIGNoaWxkID0gY2hpbGQuY3V0KDAsIGN1dEF0IC0gb2Zmc2V0KTtcbiAgICAgICAgICAgICAgICBlbmQgPSBjdXRBdDtcbiAgICAgICAgICAgICAgICBpbmRleCA9IC0xO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgd2hpbGUgKGRlY29JbmRleCA8IGxvY2Fscy5sZW5ndGggJiYgbG9jYWxzW2RlY29JbmRleF0udG8gPCBlbmQpXG4gICAgICAgICAgICAgICAgZGVjb0luZGV4Kys7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IG91dGVyRGVjbyA9IGNoaWxkLmlzSW5saW5lICYmICFjaGlsZC5pc0xlYWYgPyBhY3RpdmUuZmlsdGVyKGQgPT4gIWQuaW5saW5lKSA6IGFjdGl2ZS5zbGljZSgpO1xuICAgICAgICBvbk5vZGUoY2hpbGQsIG91dGVyRGVjbywgZGVjby5mb3JDaGlsZChvZmZzZXQsIGNoaWxkKSwgaW5kZXgpO1xuICAgICAgICBvZmZzZXQgPSBlbmQ7XG4gICAgfVxufVxuLy8gTGlzdCBtYXJrZXJzIGluIE1vYmlsZSBTYWZhcmkgd2lsbCBteXN0ZXJpb3VzbHkgZGlzYXBwZWFyXG4vLyBzb21ldGltZXMuIFRoaXMgd29ya3MgYXJvdW5kIHRoYXQuXG5mdW5jdGlvbiBpb3NIYWNrcyhkb20pIHtcbiAgICBpZiAoZG9tLm5vZGVOYW1lID09IFwiVUxcIiB8fCBkb20ubm9kZU5hbWUgPT0gXCJPTFwiKSB7XG4gICAgICAgIGxldCBvbGRDU1MgPSBkb20uc3R5bGUuY3NzVGV4dDtcbiAgICAgICAgZG9tLnN0eWxlLmNzc1RleHQgPSBvbGRDU1MgKyBcIjsgbGlzdC1zdHlsZTogc3F1YXJlICFpbXBvcnRhbnRcIjtcbiAgICAgICAgd2luZG93LmdldENvbXB1dGVkU3R5bGUoZG9tKS5saXN0U3R5bGU7XG4gICAgICAgIGRvbS5zdHlsZS5jc3NUZXh0ID0gb2xkQ1NTO1xuICAgIH1cbn1cbi8vIEZpbmQgYSBwaWVjZSBvZiB0ZXh0IGluIGFuIGlubGluZSBmcmFnbWVudCwgb3ZlcmxhcHBpbmcgZnJvbS10b1xuZnVuY3Rpb24gZmluZFRleHRJbkZyYWdtZW50KGZyYWcsIHRleHQsIGZyb20sIHRvKSB7XG4gICAgZm9yIChsZXQgaSA9IDAsIHBvcyA9IDA7IGkgPCBmcmFnLmNoaWxkQ291bnQgJiYgcG9zIDw9IHRvOykge1xuICAgICAgICBsZXQgY2hpbGQgPSBmcmFnLmNoaWxkKGkrKyksIGNoaWxkU3RhcnQgPSBwb3M7XG4gICAgICAgIHBvcyArPSBjaGlsZC5ub2RlU2l6ZTtcbiAgICAgICAgaWYgKCFjaGlsZC5pc1RleHQpXG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgbGV0IHN0ciA9IGNoaWxkLnRleHQ7XG4gICAgICAgIHdoaWxlIChpIDwgZnJhZy5jaGlsZENvdW50KSB7XG4gICAgICAgICAgICBsZXQgbmV4dCA9IGZyYWcuY2hpbGQoaSsrKTtcbiAgICAgICAgICAgIHBvcyArPSBuZXh0Lm5vZGVTaXplO1xuICAgICAgICAgICAgaWYgKCFuZXh0LmlzVGV4dClcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIHN0ciArPSBuZXh0LnRleHQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBvcyA+PSBmcm9tKSB7XG4gICAgICAgICAgICBpZiAocG9zID49IHRvICYmIHN0ci5zbGljZSh0byAtIHRleHQubGVuZ3RoIC0gY2hpbGRTdGFydCwgdG8gLSBjaGlsZFN0YXJ0KSA9PSB0ZXh0KVxuICAgICAgICAgICAgICAgIHJldHVybiB0byAtIHRleHQubGVuZ3RoO1xuICAgICAgICAgICAgbGV0IGZvdW5kID0gY2hpbGRTdGFydCA8IHRvID8gc3RyLmxhc3RJbmRleE9mKHRleHQsIHRvIC0gY2hpbGRTdGFydCAtIDEpIDogLTE7XG4gICAgICAgICAgICBpZiAoZm91bmQgPj0gMCAmJiBmb3VuZCArIHRleHQubGVuZ3RoICsgY2hpbGRTdGFydCA+PSBmcm9tKVxuICAgICAgICAgICAgICAgIHJldHVybiBjaGlsZFN0YXJ0ICsgZm91bmQ7XG4gICAgICAgICAgICBpZiAoZnJvbSA9PSB0byAmJiBzdHIubGVuZ3RoID49ICh0byArIHRleHQubGVuZ3RoKSAtIGNoaWxkU3RhcnQgJiZcbiAgICAgICAgICAgICAgICBzdHIuc2xpY2UodG8gLSBjaGlsZFN0YXJ0LCB0byAtIGNoaWxkU3RhcnQgKyB0ZXh0Lmxlbmd0aCkgPT0gdGV4dClcbiAgICAgICAgICAgICAgICByZXR1cm4gdG87XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIC0xO1xufVxuLy8gUmVwbGFjZSByYW5nZSBmcm9tLXRvIGluIGFuIGFycmF5IG9mIHZpZXcgZGVzY3Mgd2l0aCByZXBsYWNlbWVudFxuLy8gKG1heSBiZSBudWxsIHRvIGp1c3QgZGVsZXRlKS4gVGhpcyBnb2VzIHZlcnkgbXVjaCBhZ2FpbnN0IHRoZSBncmFpblxuLy8gb2YgdGhlIHJlc3Qgb2YgdGhpcyBjb2RlLCB3aGljaCB0ZW5kcyB0byBjcmVhdGUgbm9kZXMgd2l0aCB0aGVcbi8vIHJpZ2h0IHNoYXBlIGluIG9uZSBnbywgcmF0aGVyIHRoYW4gbWVzc2luZyB3aXRoIHRoZW0gYWZ0ZXJcbi8vIGNyZWF0aW9uLCBidXQgaXMgbmVjZXNzYXJ5IGluIHRoZSBjb21wb3NpdGlvbiBoYWNrLlxuZnVuY3Rpb24gcmVwbGFjZU5vZGVzKG5vZGVzLCBmcm9tLCB0bywgdmlldywgcmVwbGFjZW1lbnQpIHtcbiAgICBsZXQgcmVzdWx0ID0gW107XG4gICAgZm9yIChsZXQgaSA9IDAsIG9mZiA9IDA7IGkgPCBub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBsZXQgY2hpbGQgPSBub2Rlc1tpXSwgc3RhcnQgPSBvZmYsIGVuZCA9IG9mZiArPSBjaGlsZC5zaXplO1xuICAgICAgICBpZiAoc3RhcnQgPj0gdG8gfHwgZW5kIDw9IGZyb20pIHtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKGNoaWxkKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGlmIChzdGFydCA8IGZyb20pXG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goY2hpbGQuc2xpY2UoMCwgZnJvbSAtIHN0YXJ0LCB2aWV3KSk7XG4gICAgICAgICAgICBpZiAocmVwbGFjZW1lbnQpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaChyZXBsYWNlbWVudCk7XG4gICAgICAgICAgICAgICAgcmVwbGFjZW1lbnQgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZW5kID4gdG8pXG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goY2hpbGQuc2xpY2UodG8gLSBzdGFydCwgY2hpbGQuc2l6ZSwgdmlldykpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIHNlbGVjdGlvbkZyb21ET00odmlldywgb3JpZ2luID0gbnVsbCkge1xuICAgIGxldCBkb21TZWwgPSB2aWV3LmRvbVNlbGVjdGlvblJhbmdlKCksIGRvYyA9IHZpZXcuc3RhdGUuZG9jO1xuICAgIGlmICghZG9tU2VsLmZvY3VzTm9kZSlcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgbGV0IG5lYXJlc3REZXNjID0gdmlldy5kb2NWaWV3Lm5lYXJlc3REZXNjKGRvbVNlbC5mb2N1c05vZGUpLCBpbldpZGdldCA9IG5lYXJlc3REZXNjICYmIG5lYXJlc3REZXNjLnNpemUgPT0gMDtcbiAgICBsZXQgaGVhZCA9IHZpZXcuZG9jVmlldy5wb3NGcm9tRE9NKGRvbVNlbC5mb2N1c05vZGUsIGRvbVNlbC5mb2N1c09mZnNldCwgMSk7XG4gICAgaWYgKGhlYWQgPCAwKVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICBsZXQgJGhlYWQgPSBkb2MucmVzb2x2ZShoZWFkKSwgYW5jaG9yLCBzZWxlY3Rpb247XG4gICAgaWYgKHNlbGVjdGlvbkNvbGxhcHNlZChkb21TZWwpKSB7XG4gICAgICAgIGFuY2hvciA9IGhlYWQ7XG4gICAgICAgIHdoaWxlIChuZWFyZXN0RGVzYyAmJiAhbmVhcmVzdERlc2Mubm9kZSlcbiAgICAgICAgICAgIG5lYXJlc3REZXNjID0gbmVhcmVzdERlc2MucGFyZW50O1xuICAgICAgICBsZXQgbmVhcmVzdERlc2NOb2RlID0gbmVhcmVzdERlc2Mubm9kZTtcbiAgICAgICAgaWYgKG5lYXJlc3REZXNjICYmIG5lYXJlc3REZXNjTm9kZS5pc0F0b20gJiYgTm9kZVNlbGVjdGlvbi5pc1NlbGVjdGFibGUobmVhcmVzdERlc2NOb2RlKSAmJiBuZWFyZXN0RGVzYy5wYXJlbnRcbiAgICAgICAgICAgICYmICEobmVhcmVzdERlc2NOb2RlLmlzSW5saW5lICYmIGlzT25FZGdlKGRvbVNlbC5mb2N1c05vZGUsIGRvbVNlbC5mb2N1c09mZnNldCwgbmVhcmVzdERlc2MuZG9tKSkpIHtcbiAgICAgICAgICAgIGxldCBwb3MgPSBuZWFyZXN0RGVzYy5wb3NCZWZvcmU7XG4gICAgICAgICAgICBzZWxlY3Rpb24gPSBuZXcgTm9kZVNlbGVjdGlvbihoZWFkID09IHBvcyA/ICRoZWFkIDogZG9jLnJlc29sdmUocG9zKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGlmIChkb21TZWwgaW5zdGFuY2VvZiB2aWV3LmRvbS5vd25lckRvY3VtZW50LmRlZmF1bHRWaWV3LlNlbGVjdGlvbiAmJiBkb21TZWwucmFuZ2VDb3VudCA+IDEpIHtcbiAgICAgICAgICAgIGxldCBtaW4gPSBoZWFkLCBtYXggPSBoZWFkO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkb21TZWwucmFuZ2VDb3VudDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgbGV0IHJhbmdlID0gZG9tU2VsLmdldFJhbmdlQXQoaSk7XG4gICAgICAgICAgICAgICAgbWluID0gTWF0aC5taW4obWluLCB2aWV3LmRvY1ZpZXcucG9zRnJvbURPTShyYW5nZS5zdGFydENvbnRhaW5lciwgcmFuZ2Uuc3RhcnRPZmZzZXQsIDEpKTtcbiAgICAgICAgICAgICAgICBtYXggPSBNYXRoLm1heChtYXgsIHZpZXcuZG9jVmlldy5wb3NGcm9tRE9NKHJhbmdlLmVuZENvbnRhaW5lciwgcmFuZ2UuZW5kT2Zmc2V0LCAtMSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG1pbiA8IDApXG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICBbYW5jaG9yLCBoZWFkXSA9IG1heCA9PSB2aWV3LnN0YXRlLnNlbGVjdGlvbi5hbmNob3IgPyBbbWF4LCBtaW5dIDogW21pbiwgbWF4XTtcbiAgICAgICAgICAgICRoZWFkID0gZG9jLnJlc29sdmUoaGVhZCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBhbmNob3IgPSB2aWV3LmRvY1ZpZXcucG9zRnJvbURPTShkb21TZWwuYW5jaG9yTm9kZSwgZG9tU2VsLmFuY2hvck9mZnNldCwgMSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGFuY2hvciA8IDApXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgbGV0ICRhbmNob3IgPSBkb2MucmVzb2x2ZShhbmNob3IpO1xuICAgIGlmICghc2VsZWN0aW9uKSB7XG4gICAgICAgIGxldCBiaWFzID0gb3JpZ2luID09IFwicG9pbnRlclwiIHx8ICh2aWV3LnN0YXRlLnNlbGVjdGlvbi5oZWFkIDwgJGhlYWQucG9zICYmICFpbldpZGdldCkgPyAxIDogLTE7XG4gICAgICAgIHNlbGVjdGlvbiA9IHNlbGVjdGlvbkJldHdlZW4odmlldywgJGFuY2hvciwgJGhlYWQsIGJpYXMpO1xuICAgIH1cbiAgICByZXR1cm4gc2VsZWN0aW9uO1xufVxuZnVuY3Rpb24gZWRpdG9yT3duc1NlbGVjdGlvbih2aWV3KSB7XG4gICAgcmV0dXJuIHZpZXcuZWRpdGFibGUgPyB2aWV3Lmhhc0ZvY3VzKCkgOlxuICAgICAgICBoYXNTZWxlY3Rpb24odmlldykgJiYgZG9jdW1lbnQuYWN0aXZlRWxlbWVudCAmJiBkb2N1bWVudC5hY3RpdmVFbGVtZW50LmNvbnRhaW5zKHZpZXcuZG9tKTtcbn1cbmZ1bmN0aW9uIHNlbGVjdGlvblRvRE9NKHZpZXcsIGZvcmNlID0gZmFsc2UpIHtcbiAgICBsZXQgc2VsID0gdmlldy5zdGF0ZS5zZWxlY3Rpb247XG4gICAgc3luY05vZGVTZWxlY3Rpb24odmlldywgc2VsKTtcbiAgICBpZiAoIWVkaXRvck93bnNTZWxlY3Rpb24odmlldykpXG4gICAgICAgIHJldHVybjtcbiAgICAvLyBUaGUgZGVsYXllZCBkcmFnIHNlbGVjdGlvbiBjYXVzZXMgaXNzdWVzIHdpdGggQ2VsbCBTZWxlY3Rpb25zXG4gICAgLy8gaW4gU2FmYXJpLiBBbmQgdGhlIGRyYWcgc2VsZWN0aW9uIGRlbGF5IGlzIHRvIHdvcmthcm9uZCBpc3N1ZXNcbiAgICAvLyB3aGljaCBvbmx5IHByZXNlbnQgaW4gQ2hyb21lLlxuICAgIGlmICghZm9yY2UgJiYgdmlldy5pbnB1dC5tb3VzZURvd24gJiYgdmlldy5pbnB1dC5tb3VzZURvd24uYWxsb3dEZWZhdWx0ICYmIGNocm9tZSkge1xuICAgICAgICBsZXQgZG9tU2VsID0gdmlldy5kb21TZWxlY3Rpb25SYW5nZSgpLCBjdXJTZWwgPSB2aWV3LmRvbU9ic2VydmVyLmN1cnJlbnRTZWxlY3Rpb247XG4gICAgICAgIGlmIChkb21TZWwuYW5jaG9yTm9kZSAmJiBjdXJTZWwuYW5jaG9yTm9kZSAmJlxuICAgICAgICAgICAgaXNFcXVpdmFsZW50UG9zaXRpb24oZG9tU2VsLmFuY2hvck5vZGUsIGRvbVNlbC5hbmNob3JPZmZzZXQsIGN1clNlbC5hbmNob3JOb2RlLCBjdXJTZWwuYW5jaG9yT2Zmc2V0KSkge1xuICAgICAgICAgICAgdmlldy5pbnB1dC5tb3VzZURvd24uZGVsYXllZFNlbGVjdGlvblN5bmMgPSB0cnVlO1xuICAgICAgICAgICAgdmlldy5kb21PYnNlcnZlci5zZXRDdXJTZWxlY3Rpb24oKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgIH1cbiAgICB2aWV3LmRvbU9ic2VydmVyLmRpc2Nvbm5lY3RTZWxlY3Rpb24oKTtcbiAgICBpZiAodmlldy5jdXJzb3JXcmFwcGVyKSB7XG4gICAgICAgIHNlbGVjdEN1cnNvcldyYXBwZXIodmlldyk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBsZXQgeyBhbmNob3IsIGhlYWQgfSA9IHNlbCwgcmVzZXRFZGl0YWJsZUZyb20sIHJlc2V0RWRpdGFibGVUbztcbiAgICAgICAgaWYgKGJyb2tlblNlbGVjdEJldHdlZW5VbmVkaXRhYmxlICYmICEoc2VsIGluc3RhbmNlb2YgVGV4dFNlbGVjdGlvbikpIHtcbiAgICAgICAgICAgIGlmICghc2VsLiRmcm9tLnBhcmVudC5pbmxpbmVDb250ZW50KVxuICAgICAgICAgICAgICAgIHJlc2V0RWRpdGFibGVGcm9tID0gdGVtcG9yYXJpbHlFZGl0YWJsZU5lYXIodmlldywgc2VsLmZyb20pO1xuICAgICAgICAgICAgaWYgKCFzZWwuZW1wdHkgJiYgIXNlbC4kZnJvbS5wYXJlbnQuaW5saW5lQ29udGVudClcbiAgICAgICAgICAgICAgICByZXNldEVkaXRhYmxlVG8gPSB0ZW1wb3JhcmlseUVkaXRhYmxlTmVhcih2aWV3LCBzZWwudG8pO1xuICAgICAgICB9XG4gICAgICAgIHZpZXcuZG9jVmlldy5zZXRTZWxlY3Rpb24oYW5jaG9yLCBoZWFkLCB2aWV3LCBmb3JjZSk7XG4gICAgICAgIGlmIChicm9rZW5TZWxlY3RCZXR3ZWVuVW5lZGl0YWJsZSkge1xuICAgICAgICAgICAgaWYgKHJlc2V0RWRpdGFibGVGcm9tKVxuICAgICAgICAgICAgICAgIHJlc2V0RWRpdGFibGUocmVzZXRFZGl0YWJsZUZyb20pO1xuICAgICAgICAgICAgaWYgKHJlc2V0RWRpdGFibGVUbylcbiAgICAgICAgICAgICAgICByZXNldEVkaXRhYmxlKHJlc2V0RWRpdGFibGVUbyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNlbC52aXNpYmxlKSB7XG4gICAgICAgICAgICB2aWV3LmRvbS5jbGFzc0xpc3QucmVtb3ZlKFwiUHJvc2VNaXJyb3ItaGlkZXNlbGVjdGlvblwiKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZpZXcuZG9tLmNsYXNzTGlzdC5hZGQoXCJQcm9zZU1pcnJvci1oaWRlc2VsZWN0aW9uXCIpO1xuICAgICAgICAgICAgaWYgKFwib25zZWxlY3Rpb25jaGFuZ2VcIiBpbiBkb2N1bWVudClcbiAgICAgICAgICAgICAgICByZW1vdmVDbGFzc09uU2VsZWN0aW9uQ2hhbmdlKHZpZXcpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHZpZXcuZG9tT2JzZXJ2ZXIuc2V0Q3VyU2VsZWN0aW9uKCk7XG4gICAgdmlldy5kb21PYnNlcnZlci5jb25uZWN0U2VsZWN0aW9uKCk7XG59XG4vLyBLbHVkZ2UgdG8gd29yayBhcm91bmQgV2Via2l0IG5vdCBhbGxvd2luZyBhIHNlbGVjdGlvbiB0byBzdGFydC9lbmRcbi8vIGJldHdlZW4gbm9uLWVkaXRhYmxlIGJsb2NrIG5vZGVzLiBXZSBicmllZmx5IG1ha2Ugc29tZXRoaW5nXG4vLyBlZGl0YWJsZSwgc2V0IHRoZSBzZWxlY3Rpb24sIHRoZW4gc2V0IGl0IHVuZWRpdGFibGUgYWdhaW4uXG5jb25zdCBicm9rZW5TZWxlY3RCZXR3ZWVuVW5lZGl0YWJsZSA9IHNhZmFyaSB8fCBjaHJvbWUgJiYgY2hyb21lX3ZlcnNpb24gPCA2MztcbmZ1bmN0aW9uIHRlbXBvcmFyaWx5RWRpdGFibGVOZWFyKHZpZXcsIHBvcykge1xuICAgIGxldCB7IG5vZGUsIG9mZnNldCB9ID0gdmlldy5kb2NWaWV3LmRvbUZyb21Qb3MocG9zLCAwKTtcbiAgICBsZXQgYWZ0ZXIgPSBvZmZzZXQgPCBub2RlLmNoaWxkTm9kZXMubGVuZ3RoID8gbm9kZS5jaGlsZE5vZGVzW29mZnNldF0gOiBudWxsO1xuICAgIGxldCBiZWZvcmUgPSBvZmZzZXQgPyBub2RlLmNoaWxkTm9kZXNbb2Zmc2V0IC0gMV0gOiBudWxsO1xuICAgIGlmIChzYWZhcmkgJiYgYWZ0ZXIgJiYgYWZ0ZXIuY29udGVudEVkaXRhYmxlID09IFwiZmFsc2VcIilcbiAgICAgICAgcmV0dXJuIHNldEVkaXRhYmxlKGFmdGVyKTtcbiAgICBpZiAoKCFhZnRlciB8fCBhZnRlci5jb250ZW50RWRpdGFibGUgPT0gXCJmYWxzZVwiKSAmJlxuICAgICAgICAoIWJlZm9yZSB8fCBiZWZvcmUuY29udGVudEVkaXRhYmxlID09IFwiZmFsc2VcIikpIHtcbiAgICAgICAgaWYgKGFmdGVyKVxuICAgICAgICAgICAgcmV0dXJuIHNldEVkaXRhYmxlKGFmdGVyKTtcbiAgICAgICAgZWxzZSBpZiAoYmVmb3JlKVxuICAgICAgICAgICAgcmV0dXJuIHNldEVkaXRhYmxlKGJlZm9yZSk7XG4gICAgfVxufVxuZnVuY3Rpb24gc2V0RWRpdGFibGUoZWxlbWVudCkge1xuICAgIGVsZW1lbnQuY29udGVudEVkaXRhYmxlID0gXCJ0cnVlXCI7XG4gICAgaWYgKHNhZmFyaSAmJiBlbGVtZW50LmRyYWdnYWJsZSkge1xuICAgICAgICBlbGVtZW50LmRyYWdnYWJsZSA9IGZhbHNlO1xuICAgICAgICBlbGVtZW50Lndhc0RyYWdnYWJsZSA9IHRydWU7XG4gICAgfVxuICAgIHJldHVybiBlbGVtZW50O1xufVxuZnVuY3Rpb24gcmVzZXRFZGl0YWJsZShlbGVtZW50KSB7XG4gICAgZWxlbWVudC5jb250ZW50RWRpdGFibGUgPSBcImZhbHNlXCI7XG4gICAgaWYgKGVsZW1lbnQud2FzRHJhZ2dhYmxlKSB7XG4gICAgICAgIGVsZW1lbnQuZHJhZ2dhYmxlID0gdHJ1ZTtcbiAgICAgICAgZWxlbWVudC53YXNEcmFnZ2FibGUgPSBudWxsO1xuICAgIH1cbn1cbmZ1bmN0aW9uIHJlbW92ZUNsYXNzT25TZWxlY3Rpb25DaGFuZ2Uodmlldykge1xuICAgIGxldCBkb2MgPSB2aWV3LmRvbS5vd25lckRvY3VtZW50O1xuICAgIGRvYy5yZW1vdmVFdmVudExpc3RlbmVyKFwic2VsZWN0aW9uY2hhbmdlXCIsIHZpZXcuaW5wdXQuaGlkZVNlbGVjdGlvbkd1YXJkKTtcbiAgICBsZXQgZG9tU2VsID0gdmlldy5kb21TZWxlY3Rpb25SYW5nZSgpO1xuICAgIGxldCBub2RlID0gZG9tU2VsLmFuY2hvck5vZGUsIG9mZnNldCA9IGRvbVNlbC5hbmNob3JPZmZzZXQ7XG4gICAgZG9jLmFkZEV2ZW50TGlzdGVuZXIoXCJzZWxlY3Rpb25jaGFuZ2VcIiwgdmlldy5pbnB1dC5oaWRlU2VsZWN0aW9uR3VhcmQgPSAoKSA9PiB7XG4gICAgICAgIGlmIChkb21TZWwuYW5jaG9yTm9kZSAhPSBub2RlIHx8IGRvbVNlbC5hbmNob3JPZmZzZXQgIT0gb2Zmc2V0KSB7XG4gICAgICAgICAgICBkb2MucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInNlbGVjdGlvbmNoYW5nZVwiLCB2aWV3LmlucHV0LmhpZGVTZWxlY3Rpb25HdWFyZCk7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIWVkaXRvck93bnNTZWxlY3Rpb24odmlldykgfHwgdmlldy5zdGF0ZS5zZWxlY3Rpb24udmlzaWJsZSlcbiAgICAgICAgICAgICAgICAgICAgdmlldy5kb20uY2xhc3NMaXN0LnJlbW92ZShcIlByb3NlTWlycm9yLWhpZGVzZWxlY3Rpb25cIik7XG4gICAgICAgICAgICB9LCAyMCk7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cbmZ1bmN0aW9uIHNlbGVjdEN1cnNvcldyYXBwZXIodmlldykge1xuICAgIGxldCBkb21TZWwgPSB2aWV3LmRvbVNlbGVjdGlvbigpLCByYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gICAgaWYgKCFkb21TZWwpXG4gICAgICAgIHJldHVybjtcbiAgICBsZXQgbm9kZSA9IHZpZXcuY3Vyc29yV3JhcHBlci5kb20sIGltZyA9IG5vZGUubm9kZU5hbWUgPT0gXCJJTUdcIjtcbiAgICBpZiAoaW1nKVxuICAgICAgICByYW5nZS5zZXRTdGFydChub2RlLnBhcmVudE5vZGUsIGRvbUluZGV4KG5vZGUpICsgMSk7XG4gICAgZWxzZVxuICAgICAgICByYW5nZS5zZXRTdGFydChub2RlLCAwKTtcbiAgICByYW5nZS5jb2xsYXBzZSh0cnVlKTtcbiAgICBkb21TZWwucmVtb3ZlQWxsUmFuZ2VzKCk7XG4gICAgZG9tU2VsLmFkZFJhbmdlKHJhbmdlKTtcbiAgICAvLyBLbHVkZ2UgdG8ga2lsbCAnY29udHJvbCBzZWxlY3Rpb24nIGluIElFMTEgd2hlbiBzZWxlY3RpbmcgYW5cbiAgICAvLyBpbnZpc2libGUgY3Vyc29yIHdyYXBwZXIsIHNpbmNlIHRoYXQgd291bGQgcmVzdWx0IGluIHRob3NlIHdlaXJkXG4gICAgLy8gcmVzaXplIGhhbmRsZXMgYW5kIGEgc2VsZWN0aW9uIHRoYXQgY29uc2lkZXJzIHRoZSBhYnNvbHV0ZWx5XG4gICAgLy8gcG9zaXRpb25lZCB3cmFwcGVyLCByYXRoZXIgdGhhbiB0aGUgcm9vdCBlZGl0YWJsZSBub2RlLCB0aGVcbiAgICAvLyBmb2N1c2VkIGVsZW1lbnQuXG4gICAgaWYgKCFpbWcgJiYgIXZpZXcuc3RhdGUuc2VsZWN0aW9uLnZpc2libGUgJiYgaWUgJiYgaWVfdmVyc2lvbiA8PSAxMSkge1xuICAgICAgICBub2RlLmRpc2FibGVkID0gdHJ1ZTtcbiAgICAgICAgbm9kZS5kaXNhYmxlZCA9IGZhbHNlO1xuICAgIH1cbn1cbmZ1bmN0aW9uIHN5bmNOb2RlU2VsZWN0aW9uKHZpZXcsIHNlbCkge1xuICAgIGlmIChzZWwgaW5zdGFuY2VvZiBOb2RlU2VsZWN0aW9uKSB7XG4gICAgICAgIGxldCBkZXNjID0gdmlldy5kb2NWaWV3LmRlc2NBdChzZWwuZnJvbSk7XG4gICAgICAgIGlmIChkZXNjICE9IHZpZXcubGFzdFNlbGVjdGVkVmlld0Rlc2MpIHtcbiAgICAgICAgICAgIGNsZWFyTm9kZVNlbGVjdGlvbih2aWV3KTtcbiAgICAgICAgICAgIGlmIChkZXNjKVxuICAgICAgICAgICAgICAgIGRlc2Muc2VsZWN0Tm9kZSgpO1xuICAgICAgICAgICAgdmlldy5sYXN0U2VsZWN0ZWRWaWV3RGVzYyA9IGRlc2M7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGNsZWFyTm9kZVNlbGVjdGlvbih2aWV3KTtcbiAgICB9XG59XG4vLyBDbGVhciBhbGwgRE9NIHN0YXRlZnVsbmVzcyBvZiB0aGUgbGFzdCBub2RlIHNlbGVjdGlvbi5cbmZ1bmN0aW9uIGNsZWFyTm9kZVNlbGVjdGlvbih2aWV3KSB7XG4gICAgaWYgKHZpZXcubGFzdFNlbGVjdGVkVmlld0Rlc2MpIHtcbiAgICAgICAgaWYgKHZpZXcubGFzdFNlbGVjdGVkVmlld0Rlc2MucGFyZW50KVxuICAgICAgICAgICAgdmlldy5sYXN0U2VsZWN0ZWRWaWV3RGVzYy5kZXNlbGVjdE5vZGUoKTtcbiAgICAgICAgdmlldy5sYXN0U2VsZWN0ZWRWaWV3RGVzYyA9IHVuZGVmaW5lZDtcbiAgICB9XG59XG5mdW5jdGlvbiBzZWxlY3Rpb25CZXR3ZWVuKHZpZXcsICRhbmNob3IsICRoZWFkLCBiaWFzKSB7XG4gICAgcmV0dXJuIHZpZXcuc29tZVByb3AoXCJjcmVhdGVTZWxlY3Rpb25CZXR3ZWVuXCIsIGYgPT4gZih2aWV3LCAkYW5jaG9yLCAkaGVhZCkpXG4gICAgICAgIHx8IFRleHRTZWxlY3Rpb24uYmV0d2VlbigkYW5jaG9yLCAkaGVhZCwgYmlhcyk7XG59XG5mdW5jdGlvbiBoYXNGb2N1c0FuZFNlbGVjdGlvbih2aWV3KSB7XG4gICAgaWYgKHZpZXcuZWRpdGFibGUgJiYgIXZpZXcuaGFzRm9jdXMoKSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiBoYXNTZWxlY3Rpb24odmlldyk7XG59XG5mdW5jdGlvbiBoYXNTZWxlY3Rpb24odmlldykge1xuICAgIGxldCBzZWwgPSB2aWV3LmRvbVNlbGVjdGlvblJhbmdlKCk7XG4gICAgaWYgKCFzZWwuYW5jaG9yTm9kZSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIHRyeSB7XG4gICAgICAgIC8vIEZpcmVmb3ggd2lsbCByYWlzZSAncGVybWlzc2lvbiBkZW5pZWQnIGVycm9ycyB3aGVuIGFjY2Vzc2luZ1xuICAgICAgICAvLyBwcm9wZXJ0aWVzIG9mIGBzZWwuYW5jaG9yTm9kZWAgd2hlbiBpdCdzIGluIGEgZ2VuZXJhdGVkIENTU1xuICAgICAgICAvLyBlbGVtZW50LlxuICAgICAgICByZXR1cm4gdmlldy5kb20uY29udGFpbnMoc2VsLmFuY2hvck5vZGUubm9kZVR5cGUgPT0gMyA/IHNlbC5hbmNob3JOb2RlLnBhcmVudE5vZGUgOiBzZWwuYW5jaG9yTm9kZSkgJiZcbiAgICAgICAgICAgICh2aWV3LmVkaXRhYmxlIHx8IHZpZXcuZG9tLmNvbnRhaW5zKHNlbC5mb2N1c05vZGUubm9kZVR5cGUgPT0gMyA/IHNlbC5mb2N1c05vZGUucGFyZW50Tm9kZSA6IHNlbC5mb2N1c05vZGUpKTtcbiAgICB9XG4gICAgY2F0Y2ggKF8pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGFuY2hvckluUmlnaHRQbGFjZSh2aWV3KSB7XG4gICAgbGV0IGFuY2hvckRPTSA9IHZpZXcuZG9jVmlldy5kb21Gcm9tUG9zKHZpZXcuc3RhdGUuc2VsZWN0aW9uLmFuY2hvciwgMCk7XG4gICAgbGV0IGRvbVNlbCA9IHZpZXcuZG9tU2VsZWN0aW9uUmFuZ2UoKTtcbiAgICByZXR1cm4gaXNFcXVpdmFsZW50UG9zaXRpb24oYW5jaG9yRE9NLm5vZGUsIGFuY2hvckRPTS5vZmZzZXQsIGRvbVNlbC5hbmNob3JOb2RlLCBkb21TZWwuYW5jaG9yT2Zmc2V0KTtcbn1cblxuZnVuY3Rpb24gbW92ZVNlbGVjdGlvbkJsb2NrKHN0YXRlLCBkaXIpIHtcbiAgICBsZXQgeyAkYW5jaG9yLCAkaGVhZCB9ID0gc3RhdGUuc2VsZWN0aW9uO1xuICAgIGxldCAkc2lkZSA9IGRpciA+IDAgPyAkYW5jaG9yLm1heCgkaGVhZCkgOiAkYW5jaG9yLm1pbigkaGVhZCk7XG4gICAgbGV0ICRzdGFydCA9ICEkc2lkZS5wYXJlbnQuaW5saW5lQ29udGVudCA/ICRzaWRlIDogJHNpZGUuZGVwdGggPyBzdGF0ZS5kb2MucmVzb2x2ZShkaXIgPiAwID8gJHNpZGUuYWZ0ZXIoKSA6ICRzaWRlLmJlZm9yZSgpKSA6IG51bGw7XG4gICAgcmV0dXJuICRzdGFydCAmJiBTZWxlY3Rpb24uZmluZEZyb20oJHN0YXJ0LCBkaXIpO1xufVxuZnVuY3Rpb24gYXBwbHkodmlldywgc2VsKSB7XG4gICAgdmlldy5kaXNwYXRjaCh2aWV3LnN0YXRlLnRyLnNldFNlbGVjdGlvbihzZWwpLnNjcm9sbEludG9WaWV3KCkpO1xuICAgIHJldHVybiB0cnVlO1xufVxuZnVuY3Rpb24gc2VsZWN0SG9yaXpvbnRhbGx5KHZpZXcsIGRpciwgbW9kcykge1xuICAgIGxldCBzZWwgPSB2aWV3LnN0YXRlLnNlbGVjdGlvbjtcbiAgICBpZiAoc2VsIGluc3RhbmNlb2YgVGV4dFNlbGVjdGlvbikge1xuICAgICAgICBpZiAobW9kcy5pbmRleE9mKFwic1wiKSA+IC0xKSB7XG4gICAgICAgICAgICBsZXQgeyAkaGVhZCB9ID0gc2VsLCBub2RlID0gJGhlYWQudGV4dE9mZnNldCA/IG51bGwgOiBkaXIgPCAwID8gJGhlYWQubm9kZUJlZm9yZSA6ICRoZWFkLm5vZGVBZnRlcjtcbiAgICAgICAgICAgIGlmICghbm9kZSB8fCBub2RlLmlzVGV4dCB8fCAhbm9kZS5pc0xlYWYpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgbGV0ICRuZXdIZWFkID0gdmlldy5zdGF0ZS5kb2MucmVzb2x2ZSgkaGVhZC5wb3MgKyBub2RlLm5vZGVTaXplICogKGRpciA8IDAgPyAtMSA6IDEpKTtcbiAgICAgICAgICAgIHJldHVybiBhcHBseSh2aWV3LCBuZXcgVGV4dFNlbGVjdGlvbihzZWwuJGFuY2hvciwgJG5ld0hlYWQpKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICghc2VsLmVtcHR5KSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodmlldy5lbmRPZlRleHRibG9jayhkaXIgPiAwID8gXCJmb3J3YXJkXCIgOiBcImJhY2t3YXJkXCIpKSB7XG4gICAgICAgICAgICBsZXQgbmV4dCA9IG1vdmVTZWxlY3Rpb25CbG9jayh2aWV3LnN0YXRlLCBkaXIpO1xuICAgICAgICAgICAgaWYgKG5leHQgJiYgKG5leHQgaW5zdGFuY2VvZiBOb2RlU2VsZWN0aW9uKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gYXBwbHkodmlldywgbmV4dCk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIShtYWMgJiYgbW9kcy5pbmRleE9mKFwibVwiKSA+IC0xKSkge1xuICAgICAgICAgICAgbGV0ICRoZWFkID0gc2VsLiRoZWFkLCBub2RlID0gJGhlYWQudGV4dE9mZnNldCA/IG51bGwgOiBkaXIgPCAwID8gJGhlYWQubm9kZUJlZm9yZSA6ICRoZWFkLm5vZGVBZnRlciwgZGVzYztcbiAgICAgICAgICAgIGlmICghbm9kZSB8fCBub2RlLmlzVGV4dClcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICBsZXQgbm9kZVBvcyA9IGRpciA8IDAgPyAkaGVhZC5wb3MgLSBub2RlLm5vZGVTaXplIDogJGhlYWQucG9zO1xuICAgICAgICAgICAgaWYgKCEobm9kZS5pc0F0b20gfHwgKGRlc2MgPSB2aWV3LmRvY1ZpZXcuZGVzY0F0KG5vZGVQb3MpKSAmJiAhZGVzYy5jb250ZW50RE9NKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICBpZiAoTm9kZVNlbGVjdGlvbi5pc1NlbGVjdGFibGUobm9kZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXBwbHkodmlldywgbmV3IE5vZGVTZWxlY3Rpb24oZGlyIDwgMCA/IHZpZXcuc3RhdGUuZG9jLnJlc29sdmUoJGhlYWQucG9zIC0gbm9kZS5ub2RlU2l6ZSkgOiAkaGVhZCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAod2Via2l0KSB7XG4gICAgICAgICAgICAgICAgLy8gQ2hyb21lIGFuZCBTYWZhcmkgd2lsbCBpbnRyb2R1Y2UgZXh0cmEgcG9pbnRsZXNzIGN1cnNvclxuICAgICAgICAgICAgICAgIC8vIHBvc2l0aW9ucyBhcm91bmQgaW5saW5lIHVuZWRpdGFibGUgbm9kZXMsIHNvIHdlIGhhdmUgdG9cbiAgICAgICAgICAgICAgICAvLyB0YWtlIG92ZXIgYW5kIG1vdmUgdGhlIGN1cnNvciBwYXN0IHRoZW0gKCM5MzcpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGFwcGx5KHZpZXcsIG5ldyBUZXh0U2VsZWN0aW9uKHZpZXcuc3RhdGUuZG9jLnJlc29sdmUoZGlyIDwgMCA/IG5vZGVQb3MgOiBub2RlUG9zICsgbm9kZS5ub2RlU2l6ZSkpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIGlmIChzZWwgaW5zdGFuY2VvZiBOb2RlU2VsZWN0aW9uICYmIHNlbC5ub2RlLmlzSW5saW5lKSB7XG4gICAgICAgIHJldHVybiBhcHBseSh2aWV3LCBuZXcgVGV4dFNlbGVjdGlvbihkaXIgPiAwID8gc2VsLiR0byA6IHNlbC4kZnJvbSkpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgbGV0IG5leHQgPSBtb3ZlU2VsZWN0aW9uQmxvY2sodmlldy5zdGF0ZSwgZGlyKTtcbiAgICAgICAgaWYgKG5leHQpXG4gICAgICAgICAgICByZXR1cm4gYXBwbHkodmlldywgbmV4dCk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG59XG5mdW5jdGlvbiBub2RlTGVuKG5vZGUpIHtcbiAgICByZXR1cm4gbm9kZS5ub2RlVHlwZSA9PSAzID8gbm9kZS5ub2RlVmFsdWUubGVuZ3RoIDogbm9kZS5jaGlsZE5vZGVzLmxlbmd0aDtcbn1cbmZ1bmN0aW9uIGlzSWdub3JhYmxlKGRvbSwgZGlyKSB7XG4gICAgbGV0IGRlc2MgPSBkb20ucG1WaWV3RGVzYztcbiAgICByZXR1cm4gZGVzYyAmJiBkZXNjLnNpemUgPT0gMCAmJiAoZGlyIDwgMCB8fCBkb20ubmV4dFNpYmxpbmcgfHwgZG9tLm5vZGVOYW1lICE9IFwiQlJcIik7XG59XG5mdW5jdGlvbiBza2lwSWdub3JlZE5vZGVzKHZpZXcsIGRpcikge1xuICAgIHJldHVybiBkaXIgPCAwID8gc2tpcElnbm9yZWROb2Rlc0JlZm9yZSh2aWV3KSA6IHNraXBJZ25vcmVkTm9kZXNBZnRlcih2aWV3KTtcbn1cbi8vIE1ha2Ugc3VyZSB0aGUgY3Vyc29yIGlzbid0IGRpcmVjdGx5IGFmdGVyIG9uZSBvciBtb3JlIGlnbm9yZWRcbi8vIG5vZGVzLCB3aGljaCB3aWxsIGNvbmZ1c2UgdGhlIGJyb3dzZXIncyBjdXJzb3IgbW90aW9uIGxvZ2ljLlxuZnVuY3Rpb24gc2tpcElnbm9yZWROb2Rlc0JlZm9yZSh2aWV3KSB7XG4gICAgbGV0IHNlbCA9IHZpZXcuZG9tU2VsZWN0aW9uUmFuZ2UoKTtcbiAgICBsZXQgbm9kZSA9IHNlbC5mb2N1c05vZGUsIG9mZnNldCA9IHNlbC5mb2N1c09mZnNldDtcbiAgICBpZiAoIW5vZGUpXG4gICAgICAgIHJldHVybjtcbiAgICBsZXQgbW92ZU5vZGUsIG1vdmVPZmZzZXQsIGZvcmNlID0gZmFsc2U7XG4gICAgLy8gR2Vja28gd2lsbCBkbyBvZGQgdGhpbmdzIHdoZW4gdGhlIHNlbGVjdGlvbiBpcyBkaXJlY3RseSBpbiBmcm9udFxuICAgIC8vIG9mIGEgbm9uLWVkaXRhYmxlIG5vZGUsIHNvIGluIHRoYXQgY2FzZSwgbW92ZSBpdCBpbnRvIHRoZSBuZXh0XG4gICAgLy8gbm9kZSBpZiBwb3NzaWJsZS4gSXNzdWUgcHJvc2VtaXJyb3IvcHJvc2VtaXJyb3IjODMyLlxuICAgIGlmIChnZWNrbyAmJiBub2RlLm5vZGVUeXBlID09IDEgJiYgb2Zmc2V0IDwgbm9kZUxlbihub2RlKSAmJiBpc0lnbm9yYWJsZShub2RlLmNoaWxkTm9kZXNbb2Zmc2V0XSwgLTEpKVxuICAgICAgICBmb3JjZSA9IHRydWU7XG4gICAgZm9yICg7Oykge1xuICAgICAgICBpZiAob2Zmc2V0ID4gMCkge1xuICAgICAgICAgICAgaWYgKG5vZGUubm9kZVR5cGUgIT0gMSkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgbGV0IGJlZm9yZSA9IG5vZGUuY2hpbGROb2Rlc1tvZmZzZXQgLSAxXTtcbiAgICAgICAgICAgICAgICBpZiAoaXNJZ25vcmFibGUoYmVmb3JlLCAtMSkpIHtcbiAgICAgICAgICAgICAgICAgICAgbW92ZU5vZGUgPSBub2RlO1xuICAgICAgICAgICAgICAgICAgICBtb3ZlT2Zmc2V0ID0gLS1vZmZzZXQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGJlZm9yZS5ub2RlVHlwZSA9PSAzKSB7XG4gICAgICAgICAgICAgICAgICAgIG5vZGUgPSBiZWZvcmU7XG4gICAgICAgICAgICAgICAgICAgIG9mZnNldCA9IG5vZGUubm9kZVZhbHVlLmxlbmd0aDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpc0Jsb2NrTm9kZShub2RlKSkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBsZXQgcHJldiA9IG5vZGUucHJldmlvdXNTaWJsaW5nO1xuICAgICAgICAgICAgd2hpbGUgKHByZXYgJiYgaXNJZ25vcmFibGUocHJldiwgLTEpKSB7XG4gICAgICAgICAgICAgICAgbW92ZU5vZGUgPSBub2RlLnBhcmVudE5vZGU7XG4gICAgICAgICAgICAgICAgbW92ZU9mZnNldCA9IGRvbUluZGV4KHByZXYpO1xuICAgICAgICAgICAgICAgIHByZXYgPSBwcmV2LnByZXZpb3VzU2libGluZztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghcHJldikge1xuICAgICAgICAgICAgICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGU7XG4gICAgICAgICAgICAgICAgaWYgKG5vZGUgPT0gdmlldy5kb20pXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIG9mZnNldCA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBub2RlID0gcHJldjtcbiAgICAgICAgICAgICAgICBvZmZzZXQgPSBub2RlTGVuKG5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChmb3JjZSlcbiAgICAgICAgc2V0U2VsRm9jdXModmlldywgbm9kZSwgb2Zmc2V0KTtcbiAgICBlbHNlIGlmIChtb3ZlTm9kZSlcbiAgICAgICAgc2V0U2VsRm9jdXModmlldywgbW92ZU5vZGUsIG1vdmVPZmZzZXQpO1xufVxuLy8gTWFrZSBzdXJlIHRoZSBjdXJzb3IgaXNuJ3QgZGlyZWN0bHkgYmVmb3JlIG9uZSBvciBtb3JlIGlnbm9yZWRcbi8vIG5vZGVzLlxuZnVuY3Rpb24gc2tpcElnbm9yZWROb2Rlc0FmdGVyKHZpZXcpIHtcbiAgICBsZXQgc2VsID0gdmlldy5kb21TZWxlY3Rpb25SYW5nZSgpO1xuICAgIGxldCBub2RlID0gc2VsLmZvY3VzTm9kZSwgb2Zmc2V0ID0gc2VsLmZvY3VzT2Zmc2V0O1xuICAgIGlmICghbm9kZSlcbiAgICAgICAgcmV0dXJuO1xuICAgIGxldCBsZW4gPSBub2RlTGVuKG5vZGUpO1xuICAgIGxldCBtb3ZlTm9kZSwgbW92ZU9mZnNldDtcbiAgICBmb3IgKDs7KSB7XG4gICAgICAgIGlmIChvZmZzZXQgPCBsZW4pIHtcbiAgICAgICAgICAgIGlmIChub2RlLm5vZGVUeXBlICE9IDEpXG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBsZXQgYWZ0ZXIgPSBub2RlLmNoaWxkTm9kZXNbb2Zmc2V0XTtcbiAgICAgICAgICAgIGlmIChpc0lnbm9yYWJsZShhZnRlciwgMSkpIHtcbiAgICAgICAgICAgICAgICBtb3ZlTm9kZSA9IG5vZGU7XG4gICAgICAgICAgICAgICAgbW92ZU9mZnNldCA9ICsrb2Zmc2V0O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGlzQmxvY2tOb2RlKG5vZGUpKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGxldCBuZXh0ID0gbm9kZS5uZXh0U2libGluZztcbiAgICAgICAgICAgIHdoaWxlIChuZXh0ICYmIGlzSWdub3JhYmxlKG5leHQsIDEpKSB7XG4gICAgICAgICAgICAgICAgbW92ZU5vZGUgPSBuZXh0LnBhcmVudE5vZGU7XG4gICAgICAgICAgICAgICAgbW92ZU9mZnNldCA9IGRvbUluZGV4KG5leHQpICsgMTtcbiAgICAgICAgICAgICAgICBuZXh0ID0gbmV4dC5uZXh0U2libGluZztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghbmV4dCkge1xuICAgICAgICAgICAgICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGU7XG4gICAgICAgICAgICAgICAgaWYgKG5vZGUgPT0gdmlldy5kb20pXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIG9mZnNldCA9IGxlbiA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBub2RlID0gbmV4dDtcbiAgICAgICAgICAgICAgICBvZmZzZXQgPSAwO1xuICAgICAgICAgICAgICAgIGxlbiA9IG5vZGVMZW4obm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKG1vdmVOb2RlKVxuICAgICAgICBzZXRTZWxGb2N1cyh2aWV3LCBtb3ZlTm9kZSwgbW92ZU9mZnNldCk7XG59XG5mdW5jdGlvbiBpc0Jsb2NrTm9kZShkb20pIHtcbiAgICBsZXQgZGVzYyA9IGRvbS5wbVZpZXdEZXNjO1xuICAgIHJldHVybiBkZXNjICYmIGRlc2Mubm9kZSAmJiBkZXNjLm5vZGUuaXNCbG9jaztcbn1cbmZ1bmN0aW9uIHRleHROb2RlQWZ0ZXIobm9kZSwgb2Zmc2V0KSB7XG4gICAgd2hpbGUgKG5vZGUgJiYgb2Zmc2V0ID09IG5vZGUuY2hpbGROb2Rlcy5sZW5ndGggJiYgIWhhc0Jsb2NrRGVzYyhub2RlKSkge1xuICAgICAgICBvZmZzZXQgPSBkb21JbmRleChub2RlKSArIDE7XG4gICAgICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGU7XG4gICAgfVxuICAgIHdoaWxlIChub2RlICYmIG9mZnNldCA8IG5vZGUuY2hpbGROb2Rlcy5sZW5ndGgpIHtcbiAgICAgICAgbGV0IG5leHQgPSBub2RlLmNoaWxkTm9kZXNbb2Zmc2V0XTtcbiAgICAgICAgaWYgKG5leHQubm9kZVR5cGUgPT0gMylcbiAgICAgICAgICAgIHJldHVybiBuZXh0O1xuICAgICAgICBpZiAobmV4dC5ub2RlVHlwZSA9PSAxICYmIG5leHQuY29udGVudEVkaXRhYmxlID09IFwiZmFsc2VcIilcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBub2RlID0gbmV4dDtcbiAgICAgICAgb2Zmc2V0ID0gMDtcbiAgICB9XG59XG5mdW5jdGlvbiB0ZXh0Tm9kZUJlZm9yZShub2RlLCBvZmZzZXQpIHtcbiAgICB3aGlsZSAobm9kZSAmJiAhb2Zmc2V0ICYmICFoYXNCbG9ja0Rlc2Mobm9kZSkpIHtcbiAgICAgICAgb2Zmc2V0ID0gZG9tSW5kZXgobm9kZSk7XG4gICAgICAgIG5vZGUgPSBub2RlLnBhcmVudE5vZGU7XG4gICAgfVxuICAgIHdoaWxlIChub2RlICYmIG9mZnNldCkge1xuICAgICAgICBsZXQgbmV4dCA9IG5vZGUuY2hpbGROb2Rlc1tvZmZzZXQgLSAxXTtcbiAgICAgICAgaWYgKG5leHQubm9kZVR5cGUgPT0gMylcbiAgICAgICAgICAgIHJldHVybiBuZXh0O1xuICAgICAgICBpZiAobmV4dC5ub2RlVHlwZSA9PSAxICYmIG5leHQuY29udGVudEVkaXRhYmxlID09IFwiZmFsc2VcIilcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBub2RlID0gbmV4dDtcbiAgICAgICAgb2Zmc2V0ID0gbm9kZS5jaGlsZE5vZGVzLmxlbmd0aDtcbiAgICB9XG59XG5mdW5jdGlvbiBzZXRTZWxGb2N1cyh2aWV3LCBub2RlLCBvZmZzZXQpIHtcbiAgICBpZiAobm9kZS5ub2RlVHlwZSAhPSAzKSB7XG4gICAgICAgIGxldCBiZWZvcmUsIGFmdGVyO1xuICAgICAgICBpZiAoYWZ0ZXIgPSB0ZXh0Tm9kZUFmdGVyKG5vZGUsIG9mZnNldCkpIHtcbiAgICAgICAgICAgIG5vZGUgPSBhZnRlcjtcbiAgICAgICAgICAgIG9mZnNldCA9IDA7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoYmVmb3JlID0gdGV4dE5vZGVCZWZvcmUobm9kZSwgb2Zmc2V0KSkge1xuICAgICAgICAgICAgbm9kZSA9IGJlZm9yZTtcbiAgICAgICAgICAgIG9mZnNldCA9IGJlZm9yZS5ub2RlVmFsdWUubGVuZ3RoO1xuICAgICAgICB9XG4gICAgfVxuICAgIGxldCBzZWwgPSB2aWV3LmRvbVNlbGVjdGlvbigpO1xuICAgIGlmICghc2VsKVxuICAgICAgICByZXR1cm47XG4gICAgaWYgKHNlbGVjdGlvbkNvbGxhcHNlZChzZWwpKSB7XG4gICAgICAgIGxldCByYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gICAgICAgIHJhbmdlLnNldEVuZChub2RlLCBvZmZzZXQpO1xuICAgICAgICByYW5nZS5zZXRTdGFydChub2RlLCBvZmZzZXQpO1xuICAgICAgICBzZWwucmVtb3ZlQWxsUmFuZ2VzKCk7XG4gICAgICAgIHNlbC5hZGRSYW5nZShyYW5nZSk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHNlbC5leHRlbmQpIHtcbiAgICAgICAgc2VsLmV4dGVuZChub2RlLCBvZmZzZXQpO1xuICAgIH1cbiAgICB2aWV3LmRvbU9ic2VydmVyLnNldEN1clNlbGVjdGlvbigpO1xuICAgIGxldCB7IHN0YXRlIH0gPSB2aWV3O1xuICAgIC8vIElmIG5vIHN0YXRlIHVwZGF0ZSBlbmRzIHVwIGhhcHBlbmluZywgcmVzZXQgdGhlIHNlbGVjdGlvbi5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgaWYgKHZpZXcuc3RhdGUgPT0gc3RhdGUpXG4gICAgICAgICAgICBzZWxlY3Rpb25Ub0RPTSh2aWV3KTtcbiAgICB9LCA1MCk7XG59XG5mdW5jdGlvbiBmaW5kRGlyZWN0aW9uKHZpZXcsIHBvcykge1xuICAgIGxldCAkcG9zID0gdmlldy5zdGF0ZS5kb2MucmVzb2x2ZShwb3MpO1xuICAgIGlmICghKGNocm9tZSB8fCB3aW5kb3dzKSAmJiAkcG9zLnBhcmVudC5pbmxpbmVDb250ZW50KSB7XG4gICAgICAgIGxldCBjb29yZHMgPSB2aWV3LmNvb3Jkc0F0UG9zKHBvcyk7XG4gICAgICAgIGlmIChwb3MgPiAkcG9zLnN0YXJ0KCkpIHtcbiAgICAgICAgICAgIGxldCBiZWZvcmUgPSB2aWV3LmNvb3Jkc0F0UG9zKHBvcyAtIDEpO1xuICAgICAgICAgICAgbGV0IG1pZCA9IChiZWZvcmUudG9wICsgYmVmb3JlLmJvdHRvbSkgLyAyO1xuICAgICAgICAgICAgaWYgKG1pZCA+IGNvb3Jkcy50b3AgJiYgbWlkIDwgY29vcmRzLmJvdHRvbSAmJiBNYXRoLmFicyhiZWZvcmUubGVmdCAtIGNvb3Jkcy5sZWZ0KSA+IDEpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGJlZm9yZS5sZWZ0IDwgY29vcmRzLmxlZnQgPyBcImx0clwiIDogXCJydGxcIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAocG9zIDwgJHBvcy5lbmQoKSkge1xuICAgICAgICAgICAgbGV0IGFmdGVyID0gdmlldy5jb29yZHNBdFBvcyhwb3MgKyAxKTtcbiAgICAgICAgICAgIGxldCBtaWQgPSAoYWZ0ZXIudG9wICsgYWZ0ZXIuYm90dG9tKSAvIDI7XG4gICAgICAgICAgICBpZiAobWlkID4gY29vcmRzLnRvcCAmJiBtaWQgPCBjb29yZHMuYm90dG9tICYmIE1hdGguYWJzKGFmdGVyLmxlZnQgLSBjb29yZHMubGVmdCkgPiAxKVxuICAgICAgICAgICAgICAgIHJldHVybiBhZnRlci5sZWZ0ID4gY29vcmRzLmxlZnQgPyBcImx0clwiIDogXCJydGxcIjtcbiAgICAgICAgfVxuICAgIH1cbiAgICBsZXQgY29tcHV0ZWQgPSBnZXRDb21wdXRlZFN0eWxlKHZpZXcuZG9tKS5kaXJlY3Rpb247XG4gICAgcmV0dXJuIGNvbXB1dGVkID09IFwicnRsXCIgPyBcInJ0bFwiIDogXCJsdHJcIjtcbn1cbi8vIENoZWNrIHdoZXRoZXIgdmVydGljYWwgc2VsZWN0aW9uIG1vdGlvbiB3b3VsZCBpbnZvbHZlIG5vZGVcbi8vIHNlbGVjdGlvbnMuIElmIHNvLCBhcHBseSBpdCAoaWYgbm90LCB0aGUgcmVzdWx0IGlzIGxlZnQgdG8gdGhlXG4vLyBicm93c2VyKVxuZnVuY3Rpb24gc2VsZWN0VmVydGljYWxseSh2aWV3LCBkaXIsIG1vZHMpIHtcbiAgICBsZXQgc2VsID0gdmlldy5zdGF0ZS5zZWxlY3Rpb247XG4gICAgaWYgKHNlbCBpbnN0YW5jZW9mIFRleHRTZWxlY3Rpb24gJiYgIXNlbC5lbXB0eSB8fCBtb2RzLmluZGV4T2YoXCJzXCIpID4gLTEpXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICBpZiAobWFjICYmIG1vZHMuaW5kZXhPZihcIm1cIikgPiAtMSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGxldCB7ICRmcm9tLCAkdG8gfSA9IHNlbDtcbiAgICBpZiAoISRmcm9tLnBhcmVudC5pbmxpbmVDb250ZW50IHx8IHZpZXcuZW5kT2ZUZXh0YmxvY2soZGlyIDwgMCA/IFwidXBcIiA6IFwiZG93blwiKSkge1xuICAgICAgICBsZXQgbmV4dCA9IG1vdmVTZWxlY3Rpb25CbG9jayh2aWV3LnN0YXRlLCBkaXIpO1xuICAgICAgICBpZiAobmV4dCAmJiAobmV4dCBpbnN0YW5jZW9mIE5vZGVTZWxlY3Rpb24pKVxuICAgICAgICAgICAgcmV0dXJuIGFwcGx5KHZpZXcsIG5leHQpO1xuICAgIH1cbiAgICBpZiAoISRmcm9tLnBhcmVudC5pbmxpbmVDb250ZW50KSB7XG4gICAgICAgIGxldCBzaWRlID0gZGlyIDwgMCA/ICRmcm9tIDogJHRvO1xuICAgICAgICBsZXQgYmV5b25kID0gc2VsIGluc3RhbmNlb2YgQWxsU2VsZWN0aW9uID8gU2VsZWN0aW9uLm5lYXIoc2lkZSwgZGlyKSA6IFNlbGVjdGlvbi5maW5kRnJvbShzaWRlLCBkaXIpO1xuICAgICAgICByZXR1cm4gYmV5b25kID8gYXBwbHkodmlldywgYmV5b25kKSA6IGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiBzdG9wTmF0aXZlSG9yaXpvbnRhbERlbGV0ZSh2aWV3LCBkaXIpIHtcbiAgICBpZiAoISh2aWV3LnN0YXRlLnNlbGVjdGlvbiBpbnN0YW5jZW9mIFRleHRTZWxlY3Rpb24pKVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICBsZXQgeyAkaGVhZCwgJGFuY2hvciwgZW1wdHkgfSA9IHZpZXcuc3RhdGUuc2VsZWN0aW9uO1xuICAgIGlmICghJGhlYWQuc2FtZVBhcmVudCgkYW5jaG9yKSlcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgaWYgKCFlbXB0eSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGlmICh2aWV3LmVuZE9mVGV4dGJsb2NrKGRpciA+IDAgPyBcImZvcndhcmRcIiA6IFwiYmFja3dhcmRcIikpXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIGxldCBuZXh0Tm9kZSA9ICEkaGVhZC50ZXh0T2Zmc2V0ICYmIChkaXIgPCAwID8gJGhlYWQubm9kZUJlZm9yZSA6ICRoZWFkLm5vZGVBZnRlcik7XG4gICAgaWYgKG5leHROb2RlICYmICFuZXh0Tm9kZS5pc1RleHQpIHtcbiAgICAgICAgbGV0IHRyID0gdmlldy5zdGF0ZS50cjtcbiAgICAgICAgaWYgKGRpciA8IDApXG4gICAgICAgICAgICB0ci5kZWxldGUoJGhlYWQucG9zIC0gbmV4dE5vZGUubm9kZVNpemUsICRoZWFkLnBvcyk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHRyLmRlbGV0ZSgkaGVhZC5wb3MsICRoZWFkLnBvcyArIG5leHROb2RlLm5vZGVTaXplKTtcbiAgICAgICAgdmlldy5kaXNwYXRjaCh0cik7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiBzd2l0Y2hFZGl0YWJsZSh2aWV3LCBub2RlLCBzdGF0ZSkge1xuICAgIHZpZXcuZG9tT2JzZXJ2ZXIuc3RvcCgpO1xuICAgIG5vZGUuY29udGVudEVkaXRhYmxlID0gc3RhdGU7XG4gICAgdmlldy5kb21PYnNlcnZlci5zdGFydCgpO1xufVxuLy8gSXNzdWUgIzg2NyAvICMxMDkwIC8gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9OTAzODIxXG4vLyBJbiB3aGljaCBTYWZhcmkgKGFuZCBhdCBzb21lIHBvaW50IGluIHRoZSBwYXN0LCBDaHJvbWUpIGRvZXMgcmVhbGx5XG4vLyB3cm9uZyB0aGluZ3Mgd2hlbiB0aGUgZG93biBhcnJvdyBpcyBwcmVzc2VkIHdoZW4gdGhlIGN1cnNvciBpc1xuLy8gZGlyZWN0bHkgYXQgdGhlIHN0YXJ0IG9mIGEgdGV4dGJsb2NrIGFuZCBoYXMgYW4gdW5lZGl0YWJsZSBub2RlXG4vLyBhZnRlciBpdFxuZnVuY3Rpb24gc2FmYXJpRG93bkFycm93QnVnKHZpZXcpIHtcbiAgICBpZiAoIXNhZmFyaSB8fCB2aWV3LnN0YXRlLnNlbGVjdGlvbi4kaGVhZC5wYXJlbnRPZmZzZXQgPiAwKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgbGV0IHsgZm9jdXNOb2RlLCBmb2N1c09mZnNldCB9ID0gdmlldy5kb21TZWxlY3Rpb25SYW5nZSgpO1xuICAgIGlmIChmb2N1c05vZGUgJiYgZm9jdXNOb2RlLm5vZGVUeXBlID09IDEgJiYgZm9jdXNPZmZzZXQgPT0gMCAmJlxuICAgICAgICBmb2N1c05vZGUuZmlyc3RDaGlsZCAmJiBmb2N1c05vZGUuZmlyc3RDaGlsZC5jb250ZW50RWRpdGFibGUgPT0gXCJmYWxzZVwiKSB7XG4gICAgICAgIGxldCBjaGlsZCA9IGZvY3VzTm9kZS5maXJzdENoaWxkO1xuICAgICAgICBzd2l0Y2hFZGl0YWJsZSh2aWV3LCBjaGlsZCwgXCJ0cnVlXCIpO1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHN3aXRjaEVkaXRhYmxlKHZpZXcsIGNoaWxkLCBcImZhbHNlXCIpLCAyMCk7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbi8vIEEgYmFja2Ryb3Aga2V5IG1hcHBpbmcgdXNlZCB0byBtYWtlIHN1cmUgd2UgYWx3YXlzIHN1cHByZXNzIGtleXNcbi8vIHRoYXQgaGF2ZSBhIGRhbmdlcm91cyBkZWZhdWx0IGVmZmVjdCwgZXZlbiBpZiB0aGUgY29tbWFuZHMgdGhleSBhcmVcbi8vIGJvdW5kIHRvIHJldHVybiBmYWxzZSwgYW5kIHRvIG1ha2Ugc3VyZSB0aGF0IGN1cnNvci1tb3Rpb24ga2V5c1xuLy8gZmluZCBhIGN1cnNvciAoYXMgb3Bwb3NlZCB0byBhIG5vZGUgc2VsZWN0aW9uKSB3aGVuIHByZXNzZWQuIEZvclxuLy8gY3Vyc29yLW1vdGlvbiBrZXlzLCB0aGUgY29kZSBpbiB0aGUgaGFuZGxlcnMgYWxzbyB0YWtlcyBjYXJlIG9mXG4vLyBibG9jayBzZWxlY3Rpb25zLlxuZnVuY3Rpb24gZ2V0TW9kcyhldmVudCkge1xuICAgIGxldCByZXN1bHQgPSBcIlwiO1xuICAgIGlmIChldmVudC5jdHJsS2V5KVxuICAgICAgICByZXN1bHQgKz0gXCJjXCI7XG4gICAgaWYgKGV2ZW50Lm1ldGFLZXkpXG4gICAgICAgIHJlc3VsdCArPSBcIm1cIjtcbiAgICBpZiAoZXZlbnQuYWx0S2V5KVxuICAgICAgICByZXN1bHQgKz0gXCJhXCI7XG4gICAgaWYgKGV2ZW50LnNoaWZ0S2V5KVxuICAgICAgICByZXN1bHQgKz0gXCJzXCI7XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbmZ1bmN0aW9uIGNhcHR1cmVLZXlEb3duKHZpZXcsIGV2ZW50KSB7XG4gICAgbGV0IGNvZGUgPSBldmVudC5rZXlDb2RlLCBtb2RzID0gZ2V0TW9kcyhldmVudCk7XG4gICAgaWYgKGNvZGUgPT0gOCB8fCAobWFjICYmIGNvZGUgPT0gNzIgJiYgbW9kcyA9PSBcImNcIikpIHsgLy8gQmFja3NwYWNlLCBDdHJsLWggb24gTWFjXG4gICAgICAgIHJldHVybiBzdG9wTmF0aXZlSG9yaXpvbnRhbERlbGV0ZSh2aWV3LCAtMSkgfHwgc2tpcElnbm9yZWROb2Rlcyh2aWV3LCAtMSk7XG4gICAgfVxuICAgIGVsc2UgaWYgKChjb2RlID09IDQ2ICYmICFldmVudC5zaGlmdEtleSkgfHwgKG1hYyAmJiBjb2RlID09IDY4ICYmIG1vZHMgPT0gXCJjXCIpKSB7IC8vIERlbGV0ZSwgQ3RybC1kIG9uIE1hY1xuICAgICAgICByZXR1cm4gc3RvcE5hdGl2ZUhvcml6b250YWxEZWxldGUodmlldywgMSkgfHwgc2tpcElnbm9yZWROb2Rlcyh2aWV3LCAxKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoY29kZSA9PSAxMyB8fCBjb2RlID09IDI3KSB7IC8vIEVudGVyLCBFc2NcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGVsc2UgaWYgKGNvZGUgPT0gMzcgfHwgKG1hYyAmJiBjb2RlID09IDY2ICYmIG1vZHMgPT0gXCJjXCIpKSB7IC8vIExlZnQgYXJyb3csIEN0cmwtYiBvbiBNYWNcbiAgICAgICAgbGV0IGRpciA9IGNvZGUgPT0gMzcgPyAoZmluZERpcmVjdGlvbih2aWV3LCB2aWV3LnN0YXRlLnNlbGVjdGlvbi5mcm9tKSA9PSBcImx0clwiID8gLTEgOiAxKSA6IC0xO1xuICAgICAgICByZXR1cm4gc2VsZWN0SG9yaXpvbnRhbGx5KHZpZXcsIGRpciwgbW9kcykgfHwgc2tpcElnbm9yZWROb2Rlcyh2aWV3LCBkaXIpO1xuICAgIH1cbiAgICBlbHNlIGlmIChjb2RlID09IDM5IHx8IChtYWMgJiYgY29kZSA9PSA3MCAmJiBtb2RzID09IFwiY1wiKSkgeyAvLyBSaWdodCBhcnJvdywgQ3RybC1mIG9uIE1hY1xuICAgICAgICBsZXQgZGlyID0gY29kZSA9PSAzOSA/IChmaW5kRGlyZWN0aW9uKHZpZXcsIHZpZXcuc3RhdGUuc2VsZWN0aW9uLmZyb20pID09IFwibHRyXCIgPyAxIDogLTEpIDogMTtcbiAgICAgICAgcmV0dXJuIHNlbGVjdEhvcml6b250YWxseSh2aWV3LCBkaXIsIG1vZHMpIHx8IHNraXBJZ25vcmVkTm9kZXModmlldywgZGlyKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoY29kZSA9PSAzOCB8fCAobWFjICYmIGNvZGUgPT0gODAgJiYgbW9kcyA9PSBcImNcIikpIHsgLy8gVXAgYXJyb3csIEN0cmwtcCBvbiBNYWNcbiAgICAgICAgcmV0dXJuIHNlbGVjdFZlcnRpY2FsbHkodmlldywgLTEsIG1vZHMpIHx8IHNraXBJZ25vcmVkTm9kZXModmlldywgLTEpO1xuICAgIH1cbiAgICBlbHNlIGlmIChjb2RlID09IDQwIHx8IChtYWMgJiYgY29kZSA9PSA3OCAmJiBtb2RzID09IFwiY1wiKSkgeyAvLyBEb3duIGFycm93LCBDdHJsLW4gb24gTWFjXG4gICAgICAgIHJldHVybiBzYWZhcmlEb3duQXJyb3dCdWcodmlldykgfHwgc2VsZWN0VmVydGljYWxseSh2aWV3LCAxLCBtb2RzKSB8fCBza2lwSWdub3JlZE5vZGVzKHZpZXcsIDEpO1xuICAgIH1cbiAgICBlbHNlIGlmIChtb2RzID09IChtYWMgPyBcIm1cIiA6IFwiY1wiKSAmJlxuICAgICAgICAoY29kZSA9PSA2NiB8fCBjb2RlID09IDczIHx8IGNvZGUgPT0gODkgfHwgY29kZSA9PSA5MCkpIHsgLy8gTW9kLVtiaXl6XVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBzZXJpYWxpemVGb3JDbGlwYm9hcmQodmlldywgc2xpY2UpIHtcbiAgICB2aWV3LnNvbWVQcm9wKFwidHJhbnNmb3JtQ29waWVkXCIsIGYgPT4geyBzbGljZSA9IGYoc2xpY2UsIHZpZXcpOyB9KTtcbiAgICBsZXQgY29udGV4dCA9IFtdLCB7IGNvbnRlbnQsIG9wZW5TdGFydCwgb3BlbkVuZCB9ID0gc2xpY2U7XG4gICAgd2hpbGUgKG9wZW5TdGFydCA+IDEgJiYgb3BlbkVuZCA+IDEgJiYgY29udGVudC5jaGlsZENvdW50ID09IDEgJiYgY29udGVudC5maXJzdENoaWxkLmNoaWxkQ291bnQgPT0gMSkge1xuICAgICAgICBvcGVuU3RhcnQtLTtcbiAgICAgICAgb3BlbkVuZC0tO1xuICAgICAgICBsZXQgbm9kZSA9IGNvbnRlbnQuZmlyc3RDaGlsZDtcbiAgICAgICAgY29udGV4dC5wdXNoKG5vZGUudHlwZS5uYW1lLCBub2RlLmF0dHJzICE9IG5vZGUudHlwZS5kZWZhdWx0QXR0cnMgPyBub2RlLmF0dHJzIDogbnVsbCk7XG4gICAgICAgIGNvbnRlbnQgPSBub2RlLmNvbnRlbnQ7XG4gICAgfVxuICAgIGxldCBzZXJpYWxpemVyID0gdmlldy5zb21lUHJvcChcImNsaXBib2FyZFNlcmlhbGl6ZXJcIikgfHwgRE9NU2VyaWFsaXplci5mcm9tU2NoZW1hKHZpZXcuc3RhdGUuc2NoZW1hKTtcbiAgICBsZXQgZG9jID0gZGV0YWNoZWREb2MoKSwgd3JhcCA9IGRvYy5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICAgIHdyYXAuYXBwZW5kQ2hpbGQoc2VyaWFsaXplci5zZXJpYWxpemVGcmFnbWVudChjb250ZW50LCB7IGRvY3VtZW50OiBkb2MgfSkpO1xuICAgIGxldCBmaXJzdENoaWxkID0gd3JhcC5maXJzdENoaWxkLCBuZWVkc1dyYXAsIHdyYXBwZXJzID0gMDtcbiAgICB3aGlsZSAoZmlyc3RDaGlsZCAmJiBmaXJzdENoaWxkLm5vZGVUeXBlID09IDEgJiYgKG5lZWRzV3JhcCA9IHdyYXBNYXBbZmlyc3RDaGlsZC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpXSkpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IG5lZWRzV3JhcC5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgbGV0IHdyYXBwZXIgPSBkb2MuY3JlYXRlRWxlbWVudChuZWVkc1dyYXBbaV0pO1xuICAgICAgICAgICAgd2hpbGUgKHdyYXAuZmlyc3RDaGlsZClcbiAgICAgICAgICAgICAgICB3cmFwcGVyLmFwcGVuZENoaWxkKHdyYXAuZmlyc3RDaGlsZCk7XG4gICAgICAgICAgICB3cmFwLmFwcGVuZENoaWxkKHdyYXBwZXIpO1xuICAgICAgICAgICAgd3JhcHBlcnMrKztcbiAgICAgICAgfVxuICAgICAgICBmaXJzdENoaWxkID0gd3JhcC5maXJzdENoaWxkO1xuICAgIH1cbiAgICBpZiAoZmlyc3RDaGlsZCAmJiBmaXJzdENoaWxkLm5vZGVUeXBlID09IDEpXG4gICAgICAgIGZpcnN0Q2hpbGQuc2V0QXR0cmlidXRlKFwiZGF0YS1wbS1zbGljZVwiLCBgJHtvcGVuU3RhcnR9ICR7b3BlbkVuZH0ke3dyYXBwZXJzID8gYCAtJHt3cmFwcGVyc31gIDogXCJcIn0gJHtKU09OLnN0cmluZ2lmeShjb250ZXh0KX1gKTtcbiAgICBsZXQgdGV4dCA9IHZpZXcuc29tZVByb3AoXCJjbGlwYm9hcmRUZXh0U2VyaWFsaXplclwiLCBmID0+IGYoc2xpY2UsIHZpZXcpKSB8fFxuICAgICAgICBzbGljZS5jb250ZW50LnRleHRCZXR3ZWVuKDAsIHNsaWNlLmNvbnRlbnQuc2l6ZSwgXCJcXG5cXG5cIik7XG4gICAgcmV0dXJuIHsgZG9tOiB3cmFwLCB0ZXh0LCBzbGljZSB9O1xufVxuLy8gUmVhZCBhIHNsaWNlIG9mIGNvbnRlbnQgZnJvbSB0aGUgY2xpcGJvYXJkIChvciBkcm9wIGRhdGEpLlxuZnVuY3Rpb24gcGFyc2VGcm9tQ2xpcGJvYXJkKHZpZXcsIHRleHQsIGh0bWwsIHBsYWluVGV4dCwgJGNvbnRleHQpIHtcbiAgICBsZXQgaW5Db2RlID0gJGNvbnRleHQucGFyZW50LnR5cGUuc3BlYy5jb2RlO1xuICAgIGxldCBkb20sIHNsaWNlO1xuICAgIGlmICghaHRtbCAmJiAhdGV4dClcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgbGV0IGFzVGV4dCA9IHRleHQgJiYgKHBsYWluVGV4dCB8fCBpbkNvZGUgfHwgIWh0bWwpO1xuICAgIGlmIChhc1RleHQpIHtcbiAgICAgICAgdmlldy5zb21lUHJvcChcInRyYW5zZm9ybVBhc3RlZFRleHRcIiwgZiA9PiB7IHRleHQgPSBmKHRleHQsIGluQ29kZSB8fCBwbGFpblRleHQsIHZpZXcpOyB9KTtcbiAgICAgICAgaWYgKGluQ29kZSlcbiAgICAgICAgICAgIHJldHVybiB0ZXh0ID8gbmV3IFNsaWNlKEZyYWdtZW50LmZyb20odmlldy5zdGF0ZS5zY2hlbWEudGV4dCh0ZXh0LnJlcGxhY2UoL1xcclxcbj8vZywgXCJcXG5cIikpKSwgMCwgMCkgOiBTbGljZS5lbXB0eTtcbiAgICAgICAgbGV0IHBhcnNlZCA9IHZpZXcuc29tZVByb3AoXCJjbGlwYm9hcmRUZXh0UGFyc2VyXCIsIGYgPT4gZih0ZXh0LCAkY29udGV4dCwgcGxhaW5UZXh0LCB2aWV3KSk7XG4gICAgICAgIGlmIChwYXJzZWQpIHtcbiAgICAgICAgICAgIHNsaWNlID0gcGFyc2VkO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbGV0IG1hcmtzID0gJGNvbnRleHQubWFya3MoKTtcbiAgICAgICAgICAgIGxldCB7IHNjaGVtYSB9ID0gdmlldy5zdGF0ZSwgc2VyaWFsaXplciA9IERPTVNlcmlhbGl6ZXIuZnJvbVNjaGVtYShzY2hlbWEpO1xuICAgICAgICAgICAgZG9tID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgICAgICAgIHRleHQuc3BsaXQoLyg/Olxcclxcbj98XFxuKSsvKS5mb3JFYWNoKGJsb2NrID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgcCA9IGRvbS5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwicFwiKSk7XG4gICAgICAgICAgICAgICAgaWYgKGJsb2NrKVxuICAgICAgICAgICAgICAgICAgICBwLmFwcGVuZENoaWxkKHNlcmlhbGl6ZXIuc2VyaWFsaXplTm9kZShzY2hlbWEudGV4dChibG9jaywgbWFya3MpKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgdmlldy5zb21lUHJvcChcInRyYW5zZm9ybVBhc3RlZEhUTUxcIiwgZiA9PiB7IGh0bWwgPSBmKGh0bWwsIHZpZXcpOyB9KTtcbiAgICAgICAgZG9tID0gcmVhZEhUTUwoaHRtbCk7XG4gICAgICAgIGlmICh3ZWJraXQpXG4gICAgICAgICAgICByZXN0b3JlUmVwbGFjZWRTcGFjZXMoZG9tKTtcbiAgICB9XG4gICAgbGV0IGNvbnRleHROb2RlID0gZG9tICYmIGRvbS5xdWVyeVNlbGVjdG9yKFwiW2RhdGEtcG0tc2xpY2VdXCIpO1xuICAgIGxldCBzbGljZURhdGEgPSBjb250ZXh0Tm9kZSAmJiAvXihcXGQrKSAoXFxkKykoPzogLShcXGQrKSk/ICguKikvLmV4ZWMoY29udGV4dE5vZGUuZ2V0QXR0cmlidXRlKFwiZGF0YS1wbS1zbGljZVwiKSB8fCBcIlwiKTtcbiAgICBpZiAoc2xpY2VEYXRhICYmIHNsaWNlRGF0YVszXSlcbiAgICAgICAgZm9yIChsZXQgaSA9ICtzbGljZURhdGFbM107IGkgPiAwOyBpLS0pIHtcbiAgICAgICAgICAgIGxldCBjaGlsZCA9IGRvbS5maXJzdENoaWxkO1xuICAgICAgICAgICAgd2hpbGUgKGNoaWxkICYmIGNoaWxkLm5vZGVUeXBlICE9IDEpXG4gICAgICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC5uZXh0U2libGluZztcbiAgICAgICAgICAgIGlmICghY2hpbGQpXG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkb20gPSBjaGlsZDtcbiAgICAgICAgfVxuICAgIGlmICghc2xpY2UpIHtcbiAgICAgICAgbGV0IHBhcnNlciA9IHZpZXcuc29tZVByb3AoXCJjbGlwYm9hcmRQYXJzZXJcIikgfHwgdmlldy5zb21lUHJvcChcImRvbVBhcnNlclwiKSB8fCBET01QYXJzZXIuZnJvbVNjaGVtYSh2aWV3LnN0YXRlLnNjaGVtYSk7XG4gICAgICAgIHNsaWNlID0gcGFyc2VyLnBhcnNlU2xpY2UoZG9tLCB7XG4gICAgICAgICAgICBwcmVzZXJ2ZVdoaXRlc3BhY2U6ICEhKGFzVGV4dCB8fCBzbGljZURhdGEpLFxuICAgICAgICAgICAgY29udGV4dDogJGNvbnRleHQsXG4gICAgICAgICAgICBydWxlRnJvbU5vZGUoZG9tKSB7XG4gICAgICAgICAgICAgICAgaWYgKGRvbS5ub2RlTmFtZSA9PSBcIkJSXCIgJiYgIWRvbS5uZXh0U2libGluZyAmJlxuICAgICAgICAgICAgICAgICAgICBkb20ucGFyZW50Tm9kZSAmJiAhaW5saW5lUGFyZW50cy50ZXN0KGRvbS5wYXJlbnROb2RlLm5vZGVOYW1lKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgaWdub3JlOiB0cnVlIH07XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoc2xpY2VEYXRhKSB7XG4gICAgICAgIHNsaWNlID0gYWRkQ29udGV4dChjbG9zZVNsaWNlKHNsaWNlLCArc2xpY2VEYXRhWzFdLCArc2xpY2VEYXRhWzJdKSwgc2xpY2VEYXRhWzRdKTtcbiAgICB9XG4gICAgZWxzZSB7IC8vIEhUTUwgd2Fzbid0IGNyZWF0ZWQgYnkgUHJvc2VNaXJyb3IuIE1ha2Ugc3VyZSB0b3AtbGV2ZWwgc2libGluZ3MgYXJlIGNvaGVyZW50XG4gICAgICAgIHNsaWNlID0gU2xpY2UubWF4T3Blbihub3JtYWxpemVTaWJsaW5ncyhzbGljZS5jb250ZW50LCAkY29udGV4dCksIHRydWUpO1xuICAgICAgICBpZiAoc2xpY2Uub3BlblN0YXJ0IHx8IHNsaWNlLm9wZW5FbmQpIHtcbiAgICAgICAgICAgIGxldCBvcGVuU3RhcnQgPSAwLCBvcGVuRW5kID0gMDtcbiAgICAgICAgICAgIGZvciAobGV0IG5vZGUgPSBzbGljZS5jb250ZW50LmZpcnN0Q2hpbGQ7IG9wZW5TdGFydCA8IHNsaWNlLm9wZW5TdGFydCAmJiAhbm9kZS50eXBlLnNwZWMuaXNvbGF0aW5nOyBvcGVuU3RhcnQrKywgbm9kZSA9IG5vZGUuZmlyc3RDaGlsZCkgeyB9XG4gICAgICAgICAgICBmb3IgKGxldCBub2RlID0gc2xpY2UuY29udGVudC5sYXN0Q2hpbGQ7IG9wZW5FbmQgPCBzbGljZS5vcGVuRW5kICYmICFub2RlLnR5cGUuc3BlYy5pc29sYXRpbmc7IG9wZW5FbmQrKywgbm9kZSA9IG5vZGUubGFzdENoaWxkKSB7IH1cbiAgICAgICAgICAgIHNsaWNlID0gY2xvc2VTbGljZShzbGljZSwgb3BlblN0YXJ0LCBvcGVuRW5kKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICB2aWV3LnNvbWVQcm9wKFwidHJhbnNmb3JtUGFzdGVkXCIsIGYgPT4geyBzbGljZSA9IGYoc2xpY2UsIHZpZXcpOyB9KTtcbiAgICByZXR1cm4gc2xpY2U7XG59XG5jb25zdCBpbmxpbmVQYXJlbnRzID0gL14oYXxhYmJyfGFjcm9ueW18YnxjaXRlfGNvZGV8ZGVsfGVtfGl8aW5zfGtiZHxsYWJlbHxvdXRwdXR8cXxydWJ5fHN8c2FtcHxzcGFufHN0cm9uZ3xzdWJ8c3VwfHRpbWV8dXx0dHx2YXIpJC9pO1xuLy8gVGFrZXMgYSBzbGljZSBwYXJzZWQgd2l0aCBwYXJzZVNsaWNlLCB3aGljaCBtZWFucyB0aGVyZSBoYXNuJ3QgYmVlblxuLy8gYW55IGNvbnRlbnQtZXhwcmVzc2lvbiBjaGVja2luZyBkb25lIG9uIHRoZSB0b3Agbm9kZXMsIHRyaWVzIHRvXG4vLyBmaW5kIGEgcGFyZW50IG5vZGUgaW4gdGhlIGN1cnJlbnQgY29udGV4dCB0aGF0IG1pZ2h0IGZpdCB0aGUgbm9kZXMsXG4vLyBhbmQgaWYgc3VjY2Vzc2Z1bCwgcmVidWlsZHMgdGhlIHNsaWNlIHNvIHRoYXQgaXQgZml0cyBpbnRvIHRoYXQgcGFyZW50LlxuLy9cbi8vIFRoaXMgYWRkcmVzc2VzIHRoZSBwcm9ibGVtIHRoYXQgVHJhbnNmb3JtLnJlcGxhY2UgZXhwZWN0cyBhXG4vLyBjb2hlcmVudCBzbGljZSwgYW5kIHdpbGwgZmFpbCB0byBwbGFjZSBhIHNldCBvZiBzaWJsaW5ncyB0aGF0IGRvbid0XG4vLyBmaXQgYW55d2hlcmUgaW4gdGhlIHNjaGVtYS5cbmZ1bmN0aW9uIG5vcm1hbGl6ZVNpYmxpbmdzKGZyYWdtZW50LCAkY29udGV4dCkge1xuICAgIGlmIChmcmFnbWVudC5jaGlsZENvdW50IDwgMilcbiAgICAgICAgcmV0dXJuIGZyYWdtZW50O1xuICAgIGZvciAobGV0IGQgPSAkY29udGV4dC5kZXB0aDsgZCA+PSAwOyBkLS0pIHtcbiAgICAgICAgbGV0IHBhcmVudCA9ICRjb250ZXh0Lm5vZGUoZCk7XG4gICAgICAgIGxldCBtYXRjaCA9IHBhcmVudC5jb250ZW50TWF0Y2hBdCgkY29udGV4dC5pbmRleChkKSk7XG4gICAgICAgIGxldCBsYXN0V3JhcCwgcmVzdWx0ID0gW107XG4gICAgICAgIGZyYWdtZW50LmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgICAgICBpZiAoIXJlc3VsdClcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICBsZXQgd3JhcCA9IG1hdGNoLmZpbmRXcmFwcGluZyhub2RlLnR5cGUpLCBpbkxhc3Q7XG4gICAgICAgICAgICBpZiAoIXdyYXApXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdCA9IG51bGw7XG4gICAgICAgICAgICBpZiAoaW5MYXN0ID0gcmVzdWx0Lmxlbmd0aCAmJiBsYXN0V3JhcC5sZW5ndGggJiYgYWRkVG9TaWJsaW5nKHdyYXAsIGxhc3RXcmFwLCBub2RlLCByZXN1bHRbcmVzdWx0Lmxlbmd0aCAtIDFdLCAwKSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdFtyZXN1bHQubGVuZ3RoIC0gMV0gPSBpbkxhc3Q7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0Lmxlbmd0aClcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0W3Jlc3VsdC5sZW5ndGggLSAxXSA9IGNsb3NlUmlnaHQocmVzdWx0W3Jlc3VsdC5sZW5ndGggLSAxXSwgbGFzdFdyYXAubGVuZ3RoKTtcbiAgICAgICAgICAgICAgICBsZXQgd3JhcHBlZCA9IHdpdGhXcmFwcGVycyhub2RlLCB3cmFwKTtcbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaCh3cmFwcGVkKTtcbiAgICAgICAgICAgICAgICBtYXRjaCA9IG1hdGNoLm1hdGNoVHlwZSh3cmFwcGVkLnR5cGUpO1xuICAgICAgICAgICAgICAgIGxhc3RXcmFwID0gd3JhcDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChyZXN1bHQpXG4gICAgICAgICAgICByZXR1cm4gRnJhZ21lbnQuZnJvbShyZXN1bHQpO1xuICAgIH1cbiAgICByZXR1cm4gZnJhZ21lbnQ7XG59XG5mdW5jdGlvbiB3aXRoV3JhcHBlcnMobm9kZSwgd3JhcCwgZnJvbSA9IDApIHtcbiAgICBmb3IgKGxldCBpID0gd3JhcC5sZW5ndGggLSAxOyBpID49IGZyb207IGktLSlcbiAgICAgICAgbm9kZSA9IHdyYXBbaV0uY3JlYXRlKG51bGwsIEZyYWdtZW50LmZyb20obm9kZSkpO1xuICAgIHJldHVybiBub2RlO1xufVxuLy8gVXNlZCB0byBncm91cCBhZGphY2VudCBub2RlcyB3cmFwcGVkIGluIHNpbWlsYXIgcGFyZW50cyBieVxuLy8gbm9ybWFsaXplU2libGluZ3MgaW50byB0aGUgc2FtZSBwYXJlbnQgbm9kZVxuZnVuY3Rpb24gYWRkVG9TaWJsaW5nKHdyYXAsIGxhc3RXcmFwLCBub2RlLCBzaWJsaW5nLCBkZXB0aCkge1xuICAgIGlmIChkZXB0aCA8IHdyYXAubGVuZ3RoICYmIGRlcHRoIDwgbGFzdFdyYXAubGVuZ3RoICYmIHdyYXBbZGVwdGhdID09IGxhc3RXcmFwW2RlcHRoXSkge1xuICAgICAgICBsZXQgaW5uZXIgPSBhZGRUb1NpYmxpbmcod3JhcCwgbGFzdFdyYXAsIG5vZGUsIHNpYmxpbmcubGFzdENoaWxkLCBkZXB0aCArIDEpO1xuICAgICAgICBpZiAoaW5uZXIpXG4gICAgICAgICAgICByZXR1cm4gc2libGluZy5jb3B5KHNpYmxpbmcuY29udGVudC5yZXBsYWNlQ2hpbGQoc2libGluZy5jaGlsZENvdW50IC0gMSwgaW5uZXIpKTtcbiAgICAgICAgbGV0IG1hdGNoID0gc2libGluZy5jb250ZW50TWF0Y2hBdChzaWJsaW5nLmNoaWxkQ291bnQpO1xuICAgICAgICBpZiAobWF0Y2gubWF0Y2hUeXBlKGRlcHRoID09IHdyYXAubGVuZ3RoIC0gMSA/IG5vZGUudHlwZSA6IHdyYXBbZGVwdGggKyAxXSkpXG4gICAgICAgICAgICByZXR1cm4gc2libGluZy5jb3B5KHNpYmxpbmcuY29udGVudC5hcHBlbmQoRnJhZ21lbnQuZnJvbSh3aXRoV3JhcHBlcnMobm9kZSwgd3JhcCwgZGVwdGggKyAxKSkpKTtcbiAgICB9XG59XG5mdW5jdGlvbiBjbG9zZVJpZ2h0KG5vZGUsIGRlcHRoKSB7XG4gICAgaWYgKGRlcHRoID09IDApXG4gICAgICAgIHJldHVybiBub2RlO1xuICAgIGxldCBmcmFnbWVudCA9IG5vZGUuY29udGVudC5yZXBsYWNlQ2hpbGQobm9kZS5jaGlsZENvdW50IC0gMSwgY2xvc2VSaWdodChub2RlLmxhc3RDaGlsZCwgZGVwdGggLSAxKSk7XG4gICAgbGV0IGZpbGwgPSBub2RlLmNvbnRlbnRNYXRjaEF0KG5vZGUuY2hpbGRDb3VudCkuZmlsbEJlZm9yZShGcmFnbWVudC5lbXB0eSwgdHJ1ZSk7XG4gICAgcmV0dXJuIG5vZGUuY29weShmcmFnbWVudC5hcHBlbmQoZmlsbCkpO1xufVxuZnVuY3Rpb24gY2xvc2VSYW5nZShmcmFnbWVudCwgc2lkZSwgZnJvbSwgdG8sIGRlcHRoLCBvcGVuRW5kKSB7XG4gICAgbGV0IG5vZGUgPSBzaWRlIDwgMCA/IGZyYWdtZW50LmZpcnN0Q2hpbGQgOiBmcmFnbWVudC5sYXN0Q2hpbGQsIGlubmVyID0gbm9kZS5jb250ZW50O1xuICAgIGlmIChmcmFnbWVudC5jaGlsZENvdW50ID4gMSlcbiAgICAgICAgb3BlbkVuZCA9IDA7XG4gICAgaWYgKGRlcHRoIDwgdG8gLSAxKVxuICAgICAgICBpbm5lciA9IGNsb3NlUmFuZ2UoaW5uZXIsIHNpZGUsIGZyb20sIHRvLCBkZXB0aCArIDEsIG9wZW5FbmQpO1xuICAgIGlmIChkZXB0aCA+PSBmcm9tKVxuICAgICAgICBpbm5lciA9IHNpZGUgPCAwID8gbm9kZS5jb250ZW50TWF0Y2hBdCgwKS5maWxsQmVmb3JlKGlubmVyLCBvcGVuRW5kIDw9IGRlcHRoKS5hcHBlbmQoaW5uZXIpXG4gICAgICAgICAgICA6IGlubmVyLmFwcGVuZChub2RlLmNvbnRlbnRNYXRjaEF0KG5vZGUuY2hpbGRDb3VudCkuZmlsbEJlZm9yZShGcmFnbWVudC5lbXB0eSwgdHJ1ZSkpO1xuICAgIHJldHVybiBmcmFnbWVudC5yZXBsYWNlQ2hpbGQoc2lkZSA8IDAgPyAwIDogZnJhZ21lbnQuY2hpbGRDb3VudCAtIDEsIG5vZGUuY29weShpbm5lcikpO1xufVxuZnVuY3Rpb24gY2xvc2VTbGljZShzbGljZSwgb3BlblN0YXJ0LCBvcGVuRW5kKSB7XG4gICAgaWYgKG9wZW5TdGFydCA8IHNsaWNlLm9wZW5TdGFydClcbiAgICAgICAgc2xpY2UgPSBuZXcgU2xpY2UoY2xvc2VSYW5nZShzbGljZS5jb250ZW50LCAtMSwgb3BlblN0YXJ0LCBzbGljZS5vcGVuU3RhcnQsIDAsIHNsaWNlLm9wZW5FbmQpLCBvcGVuU3RhcnQsIHNsaWNlLm9wZW5FbmQpO1xuICAgIGlmIChvcGVuRW5kIDwgc2xpY2Uub3BlbkVuZClcbiAgICAgICAgc2xpY2UgPSBuZXcgU2xpY2UoY2xvc2VSYW5nZShzbGljZS5jb250ZW50LCAxLCBvcGVuRW5kLCBzbGljZS5vcGVuRW5kLCAwLCAwKSwgc2xpY2Uub3BlblN0YXJ0LCBvcGVuRW5kKTtcbiAgICByZXR1cm4gc2xpY2U7XG59XG4vLyBUcmljayBmcm9tIGpRdWVyeSAtLSBzb21lIGVsZW1lbnRzIG11c3QgYmUgd3JhcHBlZCBpbiBvdGhlclxuLy8gZWxlbWVudHMgZm9yIGlubmVySFRNTCB0byB3b3JrLiBJLmUuIGlmIHlvdSBkbyBgZGl2LmlubmVySFRNTCA9XG4vLyBcIjx0ZD4uLjwvdGQ+XCJgIHRoZSB0YWJsZSBjZWxscyBhcmUgaWdub3JlZC5cbmNvbnN0IHdyYXBNYXAgPSB7XG4gICAgdGhlYWQ6IFtcInRhYmxlXCJdLFxuICAgIHRib2R5OiBbXCJ0YWJsZVwiXSxcbiAgICB0Zm9vdDogW1widGFibGVcIl0sXG4gICAgY2FwdGlvbjogW1widGFibGVcIl0sXG4gICAgY29sZ3JvdXA6IFtcInRhYmxlXCJdLFxuICAgIGNvbDogW1widGFibGVcIiwgXCJjb2xncm91cFwiXSxcbiAgICB0cjogW1widGFibGVcIiwgXCJ0Ym9keVwiXSxcbiAgICB0ZDogW1widGFibGVcIiwgXCJ0Ym9keVwiLCBcInRyXCJdLFxuICAgIHRoOiBbXCJ0YWJsZVwiLCBcInRib2R5XCIsIFwidHJcIl1cbn07XG5sZXQgX2RldGFjaGVkRG9jID0gbnVsbDtcbmZ1bmN0aW9uIGRldGFjaGVkRG9jKCkge1xuICAgIHJldHVybiBfZGV0YWNoZWREb2MgfHwgKF9kZXRhY2hlZERvYyA9IGRvY3VtZW50LmltcGxlbWVudGF0aW9uLmNyZWF0ZUhUTUxEb2N1bWVudChcInRpdGxlXCIpKTtcbn1cbmxldCBfcG9saWN5ID0gbnVsbDtcbmZ1bmN0aW9uIG1heWJlV3JhcFRydXN0ZWQoaHRtbCkge1xuICAgIGxldCB0cnVzdGVkVHlwZXMgPSB3aW5kb3cudHJ1c3RlZFR5cGVzO1xuICAgIGlmICghdHJ1c3RlZFR5cGVzKVxuICAgICAgICByZXR1cm4gaHRtbDtcbiAgICAvLyBXaXRoIHRoZSByZXF1aXJlLXRydXN0ZWQtdHlwZXMtZm9yIENTUCwgQ2hyb21lIHdpbGwgYmxvY2tcbiAgICAvLyBpbm5lckhUTUwsIGV2ZW4gb24gYSBkZXRhY2hlZCBkb2N1bWVudC4gVGhpcyB3cmFwcyB0aGUgc3RyaW5nIGluXG4gICAgLy8gYSB3YXkgdGhhdCBtYWtlcyB0aGUgYnJvd3NlciBhbGxvdyB1cyB0byB1c2UgaXRzIHBhcnNlciBhZ2Fpbi5cbiAgICBpZiAoIV9wb2xpY3kpXG4gICAgICAgIF9wb2xpY3kgPSB0cnVzdGVkVHlwZXMuZGVmYXVsdFBvbGljeSB8fCB0cnVzdGVkVHlwZXMuY3JlYXRlUG9saWN5KFwiUHJvc2VNaXJyb3JDbGlwYm9hcmRcIiwgeyBjcmVhdGVIVE1MOiAocykgPT4gcyB9KTtcbiAgICByZXR1cm4gX3BvbGljeS5jcmVhdGVIVE1MKGh0bWwpO1xufVxuZnVuY3Rpb24gcmVhZEhUTUwoaHRtbCkge1xuICAgIGxldCBtZXRhcyA9IC9eKFxccyo8bWV0YSBbXj5dKj4pKi8uZXhlYyhodG1sKTtcbiAgICBpZiAobWV0YXMpXG4gICAgICAgIGh0bWwgPSBodG1sLnNsaWNlKG1ldGFzWzBdLmxlbmd0aCk7XG4gICAgbGV0IGVsdCA9IGRldGFjaGVkRG9jKCkuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICBsZXQgZmlyc3RUYWcgPSAvPChbYS16XVtePlxcc10rKS9pLmV4ZWMoaHRtbCksIHdyYXA7XG4gICAgaWYgKHdyYXAgPSBmaXJzdFRhZyAmJiB3cmFwTWFwW2ZpcnN0VGFnWzFdLnRvTG93ZXJDYXNlKCldKVxuICAgICAgICBodG1sID0gd3JhcC5tYXAobiA9PiBcIjxcIiArIG4gKyBcIj5cIikuam9pbihcIlwiKSArIGh0bWwgKyB3cmFwLm1hcChuID0+IFwiPC9cIiArIG4gKyBcIj5cIikucmV2ZXJzZSgpLmpvaW4oXCJcIik7XG4gICAgZWx0LmlubmVySFRNTCA9IG1heWJlV3JhcFRydXN0ZWQoaHRtbCk7XG4gICAgaWYgKHdyYXApXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgd3JhcC5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIGVsdCA9IGVsdC5xdWVyeVNlbGVjdG9yKHdyYXBbaV0pIHx8IGVsdDtcbiAgICByZXR1cm4gZWx0O1xufVxuLy8gV2Via2l0IGJyb3dzZXJzIGRvIHNvbWUgaGFyZC10by1wcmVkaWN0IHJlcGxhY2VtZW50IG9mIHJlZ3VsYXJcbi8vIHNwYWNlcyB3aXRoIG5vbi1icmVha2luZyBzcGFjZXMgd2hlbiBwdXR0aW5nIGNvbnRlbnQgb24gdGhlXG4vLyBjbGlwYm9hcmQuIFRoaXMgdHJpZXMgdG8gY29udmVydCBzdWNoIG5vbi1icmVha2luZyBzcGFjZXMgKHdoaWNoXG4vLyB3aWxsIGJlIHdyYXBwZWQgaW4gYSBwbGFpbiBzcGFuIG9uIENocm9tZSwgYSBzcGFuIHdpdGggY2xhc3Ncbi8vIEFwcGxlLWNvbnZlcnRlZC1zcGFjZSBvbiBTYWZhcmkpIGJhY2sgdG8gcmVndWxhciBzcGFjZXMuXG5mdW5jdGlvbiByZXN0b3JlUmVwbGFjZWRTcGFjZXMoZG9tKSB7XG4gICAgbGV0IG5vZGVzID0gZG9tLnF1ZXJ5U2VsZWN0b3JBbGwoY2hyb21lID8gXCJzcGFuOm5vdChbY2xhc3NdKTpub3QoW3N0eWxlXSlcIiA6IFwic3Bhbi5BcHBsZS1jb252ZXJ0ZWQtc3BhY2VcIik7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBub2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBsZXQgbm9kZSA9IG5vZGVzW2ldO1xuICAgICAgICBpZiAobm9kZS5jaGlsZE5vZGVzLmxlbmd0aCA9PSAxICYmIG5vZGUudGV4dENvbnRlbnQgPT0gXCJcXHUwMGEwXCIgJiYgbm9kZS5wYXJlbnROb2RlKVxuICAgICAgICAgICAgbm9kZS5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChkb20ub3duZXJEb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShcIiBcIiksIG5vZGUpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGFkZENvbnRleHQoc2xpY2UsIGNvbnRleHQpIHtcbiAgICBpZiAoIXNsaWNlLnNpemUpXG4gICAgICAgIHJldHVybiBzbGljZTtcbiAgICBsZXQgc2NoZW1hID0gc2xpY2UuY29udGVudC5maXJzdENoaWxkLnR5cGUuc2NoZW1hLCBhcnJheTtcbiAgICB0cnkge1xuICAgICAgICBhcnJheSA9IEpTT04ucGFyc2UoY29udGV4dCk7XG4gICAgfVxuICAgIGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiBzbGljZTtcbiAgICB9XG4gICAgbGV0IHsgY29udGVudCwgb3BlblN0YXJ0LCBvcGVuRW5kIH0gPSBzbGljZTtcbiAgICBmb3IgKGxldCBpID0gYXJyYXkubGVuZ3RoIC0gMjsgaSA+PSAwOyBpIC09IDIpIHtcbiAgICAgICAgbGV0IHR5cGUgPSBzY2hlbWEubm9kZXNbYXJyYXlbaV1dO1xuICAgICAgICBpZiAoIXR5cGUgfHwgdHlwZS5oYXNSZXF1aXJlZEF0dHJzKCkpXG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY29udGVudCA9IEZyYWdtZW50LmZyb20odHlwZS5jcmVhdGUoYXJyYXlbaSArIDFdLCBjb250ZW50KSk7XG4gICAgICAgIG9wZW5TdGFydCsrO1xuICAgICAgICBvcGVuRW5kKys7XG4gICAgfVxuICAgIHJldHVybiBuZXcgU2xpY2UoY29udGVudCwgb3BlblN0YXJ0LCBvcGVuRW5kKTtcbn1cblxuLy8gQSBjb2xsZWN0aW9uIG9mIERPTSBldmVudHMgdGhhdCBvY2N1ciB3aXRoaW4gdGhlIGVkaXRvciwgYW5kIGNhbGxiYWNrIGZ1bmN0aW9uc1xuLy8gdG8gaW52b2tlIHdoZW4gdGhlIGV2ZW50IGZpcmVzLlxuY29uc3QgaGFuZGxlcnMgPSB7fTtcbmNvbnN0IGVkaXRIYW5kbGVycyA9IHt9O1xuY29uc3QgcGFzc2l2ZUhhbmRsZXJzID0geyB0b3VjaHN0YXJ0OiB0cnVlLCB0b3VjaG1vdmU6IHRydWUgfTtcbmNsYXNzIElucHV0U3RhdGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnNoaWZ0S2V5ID0gZmFsc2U7XG4gICAgICAgIHRoaXMubW91c2VEb3duID0gbnVsbDtcbiAgICAgICAgdGhpcy5sYXN0S2V5Q29kZSA9IG51bGw7XG4gICAgICAgIHRoaXMubGFzdEtleUNvZGVUaW1lID0gMDtcbiAgICAgICAgdGhpcy5sYXN0Q2xpY2sgPSB7IHRpbWU6IDAsIHg6IDAsIHk6IDAsIHR5cGU6IFwiXCIsIGJ1dHRvbjogMCB9O1xuICAgICAgICB0aGlzLmxhc3RTZWxlY3Rpb25PcmlnaW4gPSBudWxsO1xuICAgICAgICB0aGlzLmxhc3RTZWxlY3Rpb25UaW1lID0gMDtcbiAgICAgICAgdGhpcy5sYXN0SU9TRW50ZXIgPSAwO1xuICAgICAgICB0aGlzLmxhc3RJT1NFbnRlckZhbGxiYWNrVGltZW91dCA9IC0xO1xuICAgICAgICB0aGlzLmxhc3RGb2N1cyA9IDA7XG4gICAgICAgIHRoaXMubGFzdFRvdWNoID0gMDtcbiAgICAgICAgdGhpcy5sYXN0Q2hyb21lRGVsZXRlID0gMDtcbiAgICAgICAgdGhpcy5jb21wb3NpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5jb21wb3NpdGlvbk5vZGUgPSBudWxsO1xuICAgICAgICB0aGlzLmNvbXBvc2luZ1RpbWVvdXQgPSAtMTtcbiAgICAgICAgdGhpcy5jb21wb3NpdGlvbk5vZGVzID0gW107XG4gICAgICAgIHRoaXMuY29tcG9zaXRpb25FbmRlZEF0ID0gLTJlODtcbiAgICAgICAgdGhpcy5jb21wb3NpdGlvbklEID0gMTtcbiAgICAgICAgLy8gU2V0IHRvIGEgY29tcG9zaXRpb24gSUQgd2hlbiB0aGVyZSBhcmUgcGVuZGluZyBjaGFuZ2VzIGF0IGNvbXBvc2l0aW9uZW5kXG4gICAgICAgIHRoaXMuY29tcG9zaXRpb25QZW5kaW5nQ2hhbmdlcyA9IDA7XG4gICAgICAgIHRoaXMuZG9tQ2hhbmdlQ291bnQgPSAwO1xuICAgICAgICB0aGlzLmV2ZW50SGFuZGxlcnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgICB0aGlzLmhpZGVTZWxlY3Rpb25HdWFyZCA9IG51bGw7XG4gICAgfVxufVxuZnVuY3Rpb24gaW5pdElucHV0KHZpZXcpIHtcbiAgICBmb3IgKGxldCBldmVudCBpbiBoYW5kbGVycykge1xuICAgICAgICBsZXQgaGFuZGxlciA9IGhhbmRsZXJzW2V2ZW50XTtcbiAgICAgICAgdmlldy5kb20uYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgdmlldy5pbnB1dC5ldmVudEhhbmRsZXJzW2V2ZW50XSA9IChldmVudCkgPT4ge1xuICAgICAgICAgICAgaWYgKGV2ZW50QmVsb25nc1RvVmlldyh2aWV3LCBldmVudCkgJiYgIXJ1bkN1c3RvbUhhbmRsZXIodmlldywgZXZlbnQpICYmXG4gICAgICAgICAgICAgICAgKHZpZXcuZWRpdGFibGUgfHwgIShldmVudC50eXBlIGluIGVkaXRIYW5kbGVycykpKVxuICAgICAgICAgICAgICAgIGhhbmRsZXIodmlldywgZXZlbnQpO1xuICAgICAgICB9LCBwYXNzaXZlSGFuZGxlcnNbZXZlbnRdID8geyBwYXNzaXZlOiB0cnVlIH0gOiB1bmRlZmluZWQpO1xuICAgIH1cbiAgICAvLyBPbiBTYWZhcmksIGZvciByZWFzb25zIGJleW9uZCBteSB1bmRlcnN0YW5kaW5nLCBhZGRpbmcgYW4gaW5wdXRcbiAgICAvLyBldmVudCBoYW5kbGVyIG1ha2VzIGFuIGlzc3VlIHdoZXJlIHRoZSBjb21wb3NpdGlvbiB2YW5pc2hlcyB3aGVuXG4gICAgLy8geW91IHByZXNzIGVudGVyIGdvIGF3YXkuXG4gICAgaWYgKHNhZmFyaSlcbiAgICAgICAgdmlldy5kb20uYWRkRXZlbnRMaXN0ZW5lcihcImlucHV0XCIsICgpID0+IG51bGwpO1xuICAgIGVuc3VyZUxpc3RlbmVycyh2aWV3KTtcbn1cbmZ1bmN0aW9uIHNldFNlbGVjdGlvbk9yaWdpbih2aWV3LCBvcmlnaW4pIHtcbiAgICB2aWV3LmlucHV0Lmxhc3RTZWxlY3Rpb25PcmlnaW4gPSBvcmlnaW47XG4gICAgdmlldy5pbnB1dC5sYXN0U2VsZWN0aW9uVGltZSA9IERhdGUubm93KCk7XG59XG5mdW5jdGlvbiBkZXN0cm95SW5wdXQodmlldykge1xuICAgIHZpZXcuZG9tT2JzZXJ2ZXIuc3RvcCgpO1xuICAgIGZvciAobGV0IHR5cGUgaW4gdmlldy5pbnB1dC5ldmVudEhhbmRsZXJzKVxuICAgICAgICB2aWV3LmRvbS5yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIHZpZXcuaW5wdXQuZXZlbnRIYW5kbGVyc1t0eXBlXSk7XG4gICAgY2xlYXJUaW1lb3V0KHZpZXcuaW5wdXQuY29tcG9zaW5nVGltZW91dCk7XG4gICAgY2xlYXJUaW1lb3V0KHZpZXcuaW5wdXQubGFzdElPU0VudGVyRmFsbGJhY2tUaW1lb3V0KTtcbn1cbmZ1bmN0aW9uIGVuc3VyZUxpc3RlbmVycyh2aWV3KSB7XG4gICAgdmlldy5zb21lUHJvcChcImhhbmRsZURPTUV2ZW50c1wiLCBjdXJyZW50SGFuZGxlcnMgPT4ge1xuICAgICAgICBmb3IgKGxldCB0eXBlIGluIGN1cnJlbnRIYW5kbGVycylcbiAgICAgICAgICAgIGlmICghdmlldy5pbnB1dC5ldmVudEhhbmRsZXJzW3R5cGVdKVxuICAgICAgICAgICAgICAgIHZpZXcuZG9tLmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgdmlldy5pbnB1dC5ldmVudEhhbmRsZXJzW3R5cGVdID0gZXZlbnQgPT4gcnVuQ3VzdG9tSGFuZGxlcih2aWV3LCBldmVudCkpO1xuICAgIH0pO1xufVxuZnVuY3Rpb24gcnVuQ3VzdG9tSGFuZGxlcih2aWV3LCBldmVudCkge1xuICAgIHJldHVybiB2aWV3LnNvbWVQcm9wKFwiaGFuZGxlRE9NRXZlbnRzXCIsIGhhbmRsZXJzID0+IHtcbiAgICAgICAgbGV0IGhhbmRsZXIgPSBoYW5kbGVyc1tldmVudC50eXBlXTtcbiAgICAgICAgcmV0dXJuIGhhbmRsZXIgPyBoYW5kbGVyKHZpZXcsIGV2ZW50KSB8fCBldmVudC5kZWZhdWx0UHJldmVudGVkIDogZmFsc2U7XG4gICAgfSk7XG59XG5mdW5jdGlvbiBldmVudEJlbG9uZ3NUb1ZpZXcodmlldywgZXZlbnQpIHtcbiAgICBpZiAoIWV2ZW50LmJ1YmJsZXMpXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIGlmIChldmVudC5kZWZhdWx0UHJldmVudGVkKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgZm9yIChsZXQgbm9kZSA9IGV2ZW50LnRhcmdldDsgbm9kZSAhPSB2aWV3LmRvbTsgbm9kZSA9IG5vZGUucGFyZW50Tm9kZSlcbiAgICAgICAgaWYgKCFub2RlIHx8IG5vZGUubm9kZVR5cGUgPT0gMTEgfHxcbiAgICAgICAgICAgIChub2RlLnBtVmlld0Rlc2MgJiYgbm9kZS5wbVZpZXdEZXNjLnN0b3BFdmVudChldmVudCkpKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiB0cnVlO1xufVxuZnVuY3Rpb24gZGlzcGF0Y2hFdmVudCh2aWV3LCBldmVudCkge1xuICAgIGlmICghcnVuQ3VzdG9tSGFuZGxlcih2aWV3LCBldmVudCkgJiYgaGFuZGxlcnNbZXZlbnQudHlwZV0gJiZcbiAgICAgICAgKHZpZXcuZWRpdGFibGUgfHwgIShldmVudC50eXBlIGluIGVkaXRIYW5kbGVycykpKVxuICAgICAgICBoYW5kbGVyc1tldmVudC50eXBlXSh2aWV3LCBldmVudCk7XG59XG5lZGl0SGFuZGxlcnMua2V5ZG93biA9ICh2aWV3LCBfZXZlbnQpID0+IHtcbiAgICBsZXQgZXZlbnQgPSBfZXZlbnQ7XG4gICAgdmlldy5pbnB1dC5zaGlmdEtleSA9IGV2ZW50LmtleUNvZGUgPT0gMTYgfHwgZXZlbnQuc2hpZnRLZXk7XG4gICAgaWYgKGluT3JOZWFyQ29tcG9zaXRpb24odmlldywgZXZlbnQpKVxuICAgICAgICByZXR1cm47XG4gICAgdmlldy5pbnB1dC5sYXN0S2V5Q29kZSA9IGV2ZW50LmtleUNvZGU7XG4gICAgdmlldy5pbnB1dC5sYXN0S2V5Q29kZVRpbWUgPSBEYXRlLm5vdygpO1xuICAgIC8vIFN1cHByZXNzIGVudGVyIGtleSBldmVudHMgb24gQ2hyb21lIEFuZHJvaWQsIGJlY2F1c2UgdGhvc2UgdGVuZFxuICAgIC8vIHRvIGJlIHBhcnQgb2YgYSBjb25mdXNlZCBzZXF1ZW5jZSBvZiBjb21wb3NpdGlvbiBldmVudHMgZmlyZWQsXG4gICAgLy8gYW5kIGhhbmRsaW5nIHRoZW0gZWFnZXJseSB0ZW5kcyB0byBjb3JydXB0IHRoZSBpbnB1dC5cbiAgICBpZiAoYW5kcm9pZCAmJiBjaHJvbWUgJiYgZXZlbnQua2V5Q29kZSA9PSAxMylcbiAgICAgICAgcmV0dXJuO1xuICAgIGlmIChldmVudC5rZXlDb2RlICE9IDIyOSlcbiAgICAgICAgdmlldy5kb21PYnNlcnZlci5mb3JjZUZsdXNoKCk7XG4gICAgLy8gT24gaU9TLCBpZiB3ZSBwcmV2ZW50RGVmYXVsdCBlbnRlciBrZXkgcHJlc3NlcywgdGhlIHZpcnR1YWxcbiAgICAvLyBrZXlib2FyZCBnZXRzIGNvbmZ1c2VkLiBTbyB0aGUgaGFjayBoZXJlIGlzIHRvIHNldCBhIGZsYWcgdGhhdFxuICAgIC8vIG1ha2VzIHRoZSBET00gY2hhbmdlIGNvZGUgcmVjb2duaXplIHRoYXQgd2hhdCBqdXN0IGhhcHBlbnMgc2hvdWxkXG4gICAgLy8gYmUgcmVwbGFjZWQgYnkgd2hhdGV2ZXIgdGhlIEVudGVyIGtleSBoYW5kbGVycyBkby5cbiAgICBpZiAoaW9zICYmIGV2ZW50LmtleUNvZGUgPT0gMTMgJiYgIWV2ZW50LmN0cmxLZXkgJiYgIWV2ZW50LmFsdEtleSAmJiAhZXZlbnQubWV0YUtleSkge1xuICAgICAgICBsZXQgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgdmlldy5pbnB1dC5sYXN0SU9TRW50ZXIgPSBub3c7XG4gICAgICAgIHZpZXcuaW5wdXQubGFzdElPU0VudGVyRmFsbGJhY2tUaW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICBpZiAodmlldy5pbnB1dC5sYXN0SU9TRW50ZXIgPT0gbm93KSB7XG4gICAgICAgICAgICAgICAgdmlldy5zb21lUHJvcChcImhhbmRsZUtleURvd25cIiwgZiA9PiBmKHZpZXcsIGtleUV2ZW50KDEzLCBcIkVudGVyXCIpKSk7XG4gICAgICAgICAgICAgICAgdmlldy5pbnB1dC5sYXN0SU9TRW50ZXIgPSAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCAyMDApO1xuICAgIH1cbiAgICBlbHNlIGlmICh2aWV3LnNvbWVQcm9wKFwiaGFuZGxlS2V5RG93blwiLCBmID0+IGYodmlldywgZXZlbnQpKSB8fCBjYXB0dXJlS2V5RG93bih2aWV3LCBldmVudCkpIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHNldFNlbGVjdGlvbk9yaWdpbih2aWV3LCBcImtleVwiKTtcbiAgICB9XG59O1xuZWRpdEhhbmRsZXJzLmtleXVwID0gKHZpZXcsIGV2ZW50KSA9PiB7XG4gICAgaWYgKGV2ZW50LmtleUNvZGUgPT0gMTYpXG4gICAgICAgIHZpZXcuaW5wdXQuc2hpZnRLZXkgPSBmYWxzZTtcbn07XG5lZGl0SGFuZGxlcnMua2V5cHJlc3MgPSAodmlldywgX2V2ZW50KSA9PiB7XG4gICAgbGV0IGV2ZW50ID0gX2V2ZW50O1xuICAgIGlmIChpbk9yTmVhckNvbXBvc2l0aW9uKHZpZXcsIGV2ZW50KSB8fCAhZXZlbnQuY2hhckNvZGUgfHxcbiAgICAgICAgZXZlbnQuY3RybEtleSAmJiAhZXZlbnQuYWx0S2V5IHx8IG1hYyAmJiBldmVudC5tZXRhS2V5KVxuICAgICAgICByZXR1cm47XG4gICAgaWYgKHZpZXcuc29tZVByb3AoXCJoYW5kbGVLZXlQcmVzc1wiLCBmID0+IGYodmlldywgZXZlbnQpKSkge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGxldCBzZWwgPSB2aWV3LnN0YXRlLnNlbGVjdGlvbjtcbiAgICBpZiAoIShzZWwgaW5zdGFuY2VvZiBUZXh0U2VsZWN0aW9uKSB8fCAhc2VsLiRmcm9tLnNhbWVQYXJlbnQoc2VsLiR0bykpIHtcbiAgICAgICAgbGV0IHRleHQgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGV2ZW50LmNoYXJDb2RlKTtcbiAgICAgICAgaWYgKCEvW1xcclxcbl0vLnRlc3QodGV4dCkgJiYgIXZpZXcuc29tZVByb3AoXCJoYW5kbGVUZXh0SW5wdXRcIiwgZiA9PiBmKHZpZXcsIHNlbC4kZnJvbS5wb3MsIHNlbC4kdG8ucG9zLCB0ZXh0KSkpXG4gICAgICAgICAgICB2aWV3LmRpc3BhdGNoKHZpZXcuc3RhdGUudHIuaW5zZXJ0VGV4dCh0ZXh0KS5zY3JvbGxJbnRvVmlldygpKTtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG59O1xuZnVuY3Rpb24gZXZlbnRDb29yZHMoZXZlbnQpIHsgcmV0dXJuIHsgbGVmdDogZXZlbnQuY2xpZW50WCwgdG9wOiBldmVudC5jbGllbnRZIH07IH1cbmZ1bmN0aW9uIGlzTmVhcihldmVudCwgY2xpY2spIHtcbiAgICBsZXQgZHggPSBjbGljay54IC0gZXZlbnQuY2xpZW50WCwgZHkgPSBjbGljay55IC0gZXZlbnQuY2xpZW50WTtcbiAgICByZXR1cm4gZHggKiBkeCArIGR5ICogZHkgPCAxMDA7XG59XG5mdW5jdGlvbiBydW5IYW5kbGVyT25Db250ZXh0KHZpZXcsIHByb3BOYW1lLCBwb3MsIGluc2lkZSwgZXZlbnQpIHtcbiAgICBpZiAoaW5zaWRlID09IC0xKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgbGV0ICRwb3MgPSB2aWV3LnN0YXRlLmRvYy5yZXNvbHZlKGluc2lkZSk7XG4gICAgZm9yIChsZXQgaSA9ICRwb3MuZGVwdGggKyAxOyBpID4gMDsgaS0tKSB7XG4gICAgICAgIGlmICh2aWV3LnNvbWVQcm9wKHByb3BOYW1lLCBmID0+IGkgPiAkcG9zLmRlcHRoID8gZih2aWV3LCBwb3MsICRwb3Mubm9kZUFmdGVyLCAkcG9zLmJlZm9yZShpKSwgZXZlbnQsIHRydWUpXG4gICAgICAgICAgICA6IGYodmlldywgcG9zLCAkcG9zLm5vZGUoaSksICRwb3MuYmVmb3JlKGkpLCBldmVudCwgZmFsc2UpKSlcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiB1cGRhdGVTZWxlY3Rpb24odmlldywgc2VsZWN0aW9uLCBvcmlnaW4pIHtcbiAgICBpZiAoIXZpZXcuZm9jdXNlZClcbiAgICAgICAgdmlldy5mb2N1cygpO1xuICAgIGlmICh2aWV3LnN0YXRlLnNlbGVjdGlvbi5lcShzZWxlY3Rpb24pKVxuICAgICAgICByZXR1cm47XG4gICAgbGV0IHRyID0gdmlldy5zdGF0ZS50ci5zZXRTZWxlY3Rpb24oc2VsZWN0aW9uKTtcbiAgICBpZiAob3JpZ2luID09IFwicG9pbnRlclwiKVxuICAgICAgICB0ci5zZXRNZXRhKFwicG9pbnRlclwiLCB0cnVlKTtcbiAgICB2aWV3LmRpc3BhdGNoKHRyKTtcbn1cbmZ1bmN0aW9uIHNlbGVjdENsaWNrZWRMZWFmKHZpZXcsIGluc2lkZSkge1xuICAgIGlmIChpbnNpZGUgPT0gLTEpXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICBsZXQgJHBvcyA9IHZpZXcuc3RhdGUuZG9jLnJlc29sdmUoaW5zaWRlKSwgbm9kZSA9ICRwb3Mubm9kZUFmdGVyO1xuICAgIGlmIChub2RlICYmIG5vZGUuaXNBdG9tICYmIE5vZGVTZWxlY3Rpb24uaXNTZWxlY3RhYmxlKG5vZGUpKSB7XG4gICAgICAgIHVwZGF0ZVNlbGVjdGlvbih2aWV3LCBuZXcgTm9kZVNlbGVjdGlvbigkcG9zKSwgXCJwb2ludGVyXCIpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuZnVuY3Rpb24gc2VsZWN0Q2xpY2tlZE5vZGUodmlldywgaW5zaWRlKSB7XG4gICAgaWYgKGluc2lkZSA9PSAtMSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGxldCBzZWwgPSB2aWV3LnN0YXRlLnNlbGVjdGlvbiwgc2VsZWN0ZWROb2RlLCBzZWxlY3RBdDtcbiAgICBpZiAoc2VsIGluc3RhbmNlb2YgTm9kZVNlbGVjdGlvbilcbiAgICAgICAgc2VsZWN0ZWROb2RlID0gc2VsLm5vZGU7XG4gICAgbGV0ICRwb3MgPSB2aWV3LnN0YXRlLmRvYy5yZXNvbHZlKGluc2lkZSk7XG4gICAgZm9yIChsZXQgaSA9ICRwb3MuZGVwdGggKyAxOyBpID4gMDsgaS0tKSB7XG4gICAgICAgIGxldCBub2RlID0gaSA+ICRwb3MuZGVwdGggPyAkcG9zLm5vZGVBZnRlciA6ICRwb3Mubm9kZShpKTtcbiAgICAgICAgaWYgKE5vZGVTZWxlY3Rpb24uaXNTZWxlY3RhYmxlKG5vZGUpKSB7XG4gICAgICAgICAgICBpZiAoc2VsZWN0ZWROb2RlICYmIHNlbC4kZnJvbS5kZXB0aCA+IDAgJiZcbiAgICAgICAgICAgICAgICBpID49IHNlbC4kZnJvbS5kZXB0aCAmJiAkcG9zLmJlZm9yZShzZWwuJGZyb20uZGVwdGggKyAxKSA9PSBzZWwuJGZyb20ucG9zKVxuICAgICAgICAgICAgICAgIHNlbGVjdEF0ID0gJHBvcy5iZWZvcmUoc2VsLiRmcm9tLmRlcHRoKTtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBzZWxlY3RBdCA9ICRwb3MuYmVmb3JlKGkpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKHNlbGVjdEF0ICE9IG51bGwpIHtcbiAgICAgICAgdXBkYXRlU2VsZWN0aW9uKHZpZXcsIE5vZGVTZWxlY3Rpb24uY3JlYXRlKHZpZXcuc3RhdGUuZG9jLCBzZWxlY3RBdCksIFwicG9pbnRlclwiKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuZnVuY3Rpb24gaGFuZGxlU2luZ2xlQ2xpY2sodmlldywgcG9zLCBpbnNpZGUsIGV2ZW50LCBzZWxlY3ROb2RlKSB7XG4gICAgcmV0dXJuIHJ1bkhhbmRsZXJPbkNvbnRleHQodmlldywgXCJoYW5kbGVDbGlja09uXCIsIHBvcywgaW5zaWRlLCBldmVudCkgfHxcbiAgICAgICAgdmlldy5zb21lUHJvcChcImhhbmRsZUNsaWNrXCIsIGYgPT4gZih2aWV3LCBwb3MsIGV2ZW50KSkgfHxcbiAgICAgICAgKHNlbGVjdE5vZGUgPyBzZWxlY3RDbGlja2VkTm9kZSh2aWV3LCBpbnNpZGUpIDogc2VsZWN0Q2xpY2tlZExlYWYodmlldywgaW5zaWRlKSk7XG59XG5mdW5jdGlvbiBoYW5kbGVEb3VibGVDbGljayh2aWV3LCBwb3MsIGluc2lkZSwgZXZlbnQpIHtcbiAgICByZXR1cm4gcnVuSGFuZGxlck9uQ29udGV4dCh2aWV3LCBcImhhbmRsZURvdWJsZUNsaWNrT25cIiwgcG9zLCBpbnNpZGUsIGV2ZW50KSB8fFxuICAgICAgICB2aWV3LnNvbWVQcm9wKFwiaGFuZGxlRG91YmxlQ2xpY2tcIiwgZiA9PiBmKHZpZXcsIHBvcywgZXZlbnQpKTtcbn1cbmZ1bmN0aW9uIGhhbmRsZVRyaXBsZUNsaWNrKHZpZXcsIHBvcywgaW5zaWRlLCBldmVudCkge1xuICAgIHJldHVybiBydW5IYW5kbGVyT25Db250ZXh0KHZpZXcsIFwiaGFuZGxlVHJpcGxlQ2xpY2tPblwiLCBwb3MsIGluc2lkZSwgZXZlbnQpIHx8XG4gICAgICAgIHZpZXcuc29tZVByb3AoXCJoYW5kbGVUcmlwbGVDbGlja1wiLCBmID0+IGYodmlldywgcG9zLCBldmVudCkpIHx8XG4gICAgICAgIGRlZmF1bHRUcmlwbGVDbGljayh2aWV3LCBpbnNpZGUsIGV2ZW50KTtcbn1cbmZ1bmN0aW9uIGRlZmF1bHRUcmlwbGVDbGljayh2aWV3LCBpbnNpZGUsIGV2ZW50KSB7XG4gICAgaWYgKGV2ZW50LmJ1dHRvbiAhPSAwKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgbGV0IGRvYyA9IHZpZXcuc3RhdGUuZG9jO1xuICAgIGlmIChpbnNpZGUgPT0gLTEpIHtcbiAgICAgICAgaWYgKGRvYy5pbmxpbmVDb250ZW50KSB7XG4gICAgICAgICAgICB1cGRhdGVTZWxlY3Rpb24odmlldywgVGV4dFNlbGVjdGlvbi5jcmVhdGUoZG9jLCAwLCBkb2MuY29udGVudC5zaXplKSwgXCJwb2ludGVyXCIpO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBsZXQgJHBvcyA9IGRvYy5yZXNvbHZlKGluc2lkZSk7XG4gICAgZm9yIChsZXQgaSA9ICRwb3MuZGVwdGggKyAxOyBpID4gMDsgaS0tKSB7XG4gICAgICAgIGxldCBub2RlID0gaSA+ICRwb3MuZGVwdGggPyAkcG9zLm5vZGVBZnRlciA6ICRwb3Mubm9kZShpKTtcbiAgICAgICAgbGV0IG5vZGVQb3MgPSAkcG9zLmJlZm9yZShpKTtcbiAgICAgICAgaWYgKG5vZGUuaW5saW5lQ29udGVudClcbiAgICAgICAgICAgIHVwZGF0ZVNlbGVjdGlvbih2aWV3LCBUZXh0U2VsZWN0aW9uLmNyZWF0ZShkb2MsIG5vZGVQb3MgKyAxLCBub2RlUG9zICsgMSArIG5vZGUuY29udGVudC5zaXplKSwgXCJwb2ludGVyXCIpO1xuICAgICAgICBlbHNlIGlmIChOb2RlU2VsZWN0aW9uLmlzU2VsZWN0YWJsZShub2RlKSlcbiAgICAgICAgICAgIHVwZGF0ZVNlbGVjdGlvbih2aWV3LCBOb2RlU2VsZWN0aW9uLmNyZWF0ZShkb2MsIG5vZGVQb3MpLCBcInBvaW50ZXJcIik7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG59XG5mdW5jdGlvbiBmb3JjZURPTUZsdXNoKHZpZXcpIHtcbiAgICByZXR1cm4gZW5kQ29tcG9zaXRpb24odmlldyk7XG59XG5jb25zdCBzZWxlY3ROb2RlTW9kaWZpZXIgPSBtYWMgPyBcIm1ldGFLZXlcIiA6IFwiY3RybEtleVwiO1xuaGFuZGxlcnMubW91c2Vkb3duID0gKHZpZXcsIF9ldmVudCkgPT4ge1xuICAgIGxldCBldmVudCA9IF9ldmVudDtcbiAgICB2aWV3LmlucHV0LnNoaWZ0S2V5ID0gZXZlbnQuc2hpZnRLZXk7XG4gICAgbGV0IGZsdXNoZWQgPSBmb3JjZURPTUZsdXNoKHZpZXcpO1xuICAgIGxldCBub3cgPSBEYXRlLm5vdygpLCB0eXBlID0gXCJzaW5nbGVDbGlja1wiO1xuICAgIGlmIChub3cgLSB2aWV3LmlucHV0Lmxhc3RDbGljay50aW1lIDwgNTAwICYmIGlzTmVhcihldmVudCwgdmlldy5pbnB1dC5sYXN0Q2xpY2spICYmICFldmVudFtzZWxlY3ROb2RlTW9kaWZpZXJdICYmXG4gICAgICAgIHZpZXcuaW5wdXQubGFzdENsaWNrLmJ1dHRvbiA9PSBldmVudC5idXR0b24pIHtcbiAgICAgICAgaWYgKHZpZXcuaW5wdXQubGFzdENsaWNrLnR5cGUgPT0gXCJzaW5nbGVDbGlja1wiKVxuICAgICAgICAgICAgdHlwZSA9IFwiZG91YmxlQ2xpY2tcIjtcbiAgICAgICAgZWxzZSBpZiAodmlldy5pbnB1dC5sYXN0Q2xpY2sudHlwZSA9PSBcImRvdWJsZUNsaWNrXCIpXG4gICAgICAgICAgICB0eXBlID0gXCJ0cmlwbGVDbGlja1wiO1xuICAgIH1cbiAgICB2aWV3LmlucHV0Lmxhc3RDbGljayA9IHsgdGltZTogbm93LCB4OiBldmVudC5jbGllbnRYLCB5OiBldmVudC5jbGllbnRZLCB0eXBlLCBidXR0b246IGV2ZW50LmJ1dHRvbiB9O1xuICAgIGxldCBwb3MgPSB2aWV3LnBvc0F0Q29vcmRzKGV2ZW50Q29vcmRzKGV2ZW50KSk7XG4gICAgaWYgKCFwb3MpXG4gICAgICAgIHJldHVybjtcbiAgICBpZiAodHlwZSA9PSBcInNpbmdsZUNsaWNrXCIpIHtcbiAgICAgICAgaWYgKHZpZXcuaW5wdXQubW91c2VEb3duKVxuICAgICAgICAgICAgdmlldy5pbnB1dC5tb3VzZURvd24uZG9uZSgpO1xuICAgICAgICB2aWV3LmlucHV0Lm1vdXNlRG93biA9IG5ldyBNb3VzZURvd24odmlldywgcG9zLCBldmVudCwgISFmbHVzaGVkKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoKHR5cGUgPT0gXCJkb3VibGVDbGlja1wiID8gaGFuZGxlRG91YmxlQ2xpY2sgOiBoYW5kbGVUcmlwbGVDbGljaykodmlldywgcG9zLnBvcywgcG9zLmluc2lkZSwgZXZlbnQpKSB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBzZXRTZWxlY3Rpb25PcmlnaW4odmlldywgXCJwb2ludGVyXCIpO1xuICAgIH1cbn07XG5jbGFzcyBNb3VzZURvd24ge1xuICAgIGNvbnN0cnVjdG9yKHZpZXcsIHBvcywgZXZlbnQsIGZsdXNoZWQpIHtcbiAgICAgICAgdGhpcy52aWV3ID0gdmlldztcbiAgICAgICAgdGhpcy5wb3MgPSBwb3M7XG4gICAgICAgIHRoaXMuZXZlbnQgPSBldmVudDtcbiAgICAgICAgdGhpcy5mbHVzaGVkID0gZmx1c2hlZDtcbiAgICAgICAgdGhpcy5kZWxheWVkU2VsZWN0aW9uU3luYyA9IGZhbHNlO1xuICAgICAgICB0aGlzLm1pZ2h0RHJhZyA9IG51bGw7XG4gICAgICAgIHRoaXMuc3RhcnREb2MgPSB2aWV3LnN0YXRlLmRvYztcbiAgICAgICAgdGhpcy5zZWxlY3ROb2RlID0gISFldmVudFtzZWxlY3ROb2RlTW9kaWZpZXJdO1xuICAgICAgICB0aGlzLmFsbG93RGVmYXVsdCA9IGV2ZW50LnNoaWZ0S2V5O1xuICAgICAgICBsZXQgdGFyZ2V0Tm9kZSwgdGFyZ2V0UG9zO1xuICAgICAgICBpZiAocG9zLmluc2lkZSA+IC0xKSB7XG4gICAgICAgICAgICB0YXJnZXROb2RlID0gdmlldy5zdGF0ZS5kb2Mubm9kZUF0KHBvcy5pbnNpZGUpO1xuICAgICAgICAgICAgdGFyZ2V0UG9zID0gcG9zLmluc2lkZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGxldCAkcG9zID0gdmlldy5zdGF0ZS5kb2MucmVzb2x2ZShwb3MucG9zKTtcbiAgICAgICAgICAgIHRhcmdldE5vZGUgPSAkcG9zLnBhcmVudDtcbiAgICAgICAgICAgIHRhcmdldFBvcyA9ICRwb3MuZGVwdGggPyAkcG9zLmJlZm9yZSgpIDogMDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB0YXJnZXQgPSBmbHVzaGVkID8gbnVsbCA6IGV2ZW50LnRhcmdldDtcbiAgICAgICAgY29uc3QgdGFyZ2V0RGVzYyA9IHRhcmdldCA/IHZpZXcuZG9jVmlldy5uZWFyZXN0RGVzYyh0YXJnZXQsIHRydWUpIDogbnVsbDtcbiAgICAgICAgdGhpcy50YXJnZXQgPSB0YXJnZXREZXNjICYmIHRhcmdldERlc2MuZG9tLm5vZGVUeXBlID09IDEgPyB0YXJnZXREZXNjLmRvbSA6IG51bGw7XG4gICAgICAgIGxldCB7IHNlbGVjdGlvbiB9ID0gdmlldy5zdGF0ZTtcbiAgICAgICAgaWYgKGV2ZW50LmJ1dHRvbiA9PSAwICYmXG4gICAgICAgICAgICB0YXJnZXROb2RlLnR5cGUuc3BlYy5kcmFnZ2FibGUgJiYgdGFyZ2V0Tm9kZS50eXBlLnNwZWMuc2VsZWN0YWJsZSAhPT0gZmFsc2UgfHxcbiAgICAgICAgICAgIHNlbGVjdGlvbiBpbnN0YW5jZW9mIE5vZGVTZWxlY3Rpb24gJiYgc2VsZWN0aW9uLmZyb20gPD0gdGFyZ2V0UG9zICYmIHNlbGVjdGlvbi50byA+IHRhcmdldFBvcylcbiAgICAgICAgICAgIHRoaXMubWlnaHREcmFnID0ge1xuICAgICAgICAgICAgICAgIG5vZGU6IHRhcmdldE5vZGUsXG4gICAgICAgICAgICAgICAgcG9zOiB0YXJnZXRQb3MsXG4gICAgICAgICAgICAgICAgYWRkQXR0cjogISEodGhpcy50YXJnZXQgJiYgIXRoaXMudGFyZ2V0LmRyYWdnYWJsZSksXG4gICAgICAgICAgICAgICAgc2V0VW5lZGl0YWJsZTogISEodGhpcy50YXJnZXQgJiYgZ2Vja28gJiYgIXRoaXMudGFyZ2V0Lmhhc0F0dHJpYnV0ZShcImNvbnRlbnRFZGl0YWJsZVwiKSlcbiAgICAgICAgICAgIH07XG4gICAgICAgIGlmICh0aGlzLnRhcmdldCAmJiB0aGlzLm1pZ2h0RHJhZyAmJiAodGhpcy5taWdodERyYWcuYWRkQXR0ciB8fCB0aGlzLm1pZ2h0RHJhZy5zZXRVbmVkaXRhYmxlKSkge1xuICAgICAgICAgICAgdGhpcy52aWV3LmRvbU9ic2VydmVyLnN0b3AoKTtcbiAgICAgICAgICAgIGlmICh0aGlzLm1pZ2h0RHJhZy5hZGRBdHRyKVxuICAgICAgICAgICAgICAgIHRoaXMudGFyZ2V0LmRyYWdnYWJsZSA9IHRydWU7XG4gICAgICAgICAgICBpZiAodGhpcy5taWdodERyYWcuc2V0VW5lZGl0YWJsZSlcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMudmlldy5pbnB1dC5tb3VzZURvd24gPT0gdGhpcylcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudGFyZ2V0LnNldEF0dHJpYnV0ZShcImNvbnRlbnRFZGl0YWJsZVwiLCBcImZhbHNlXCIpO1xuICAgICAgICAgICAgICAgIH0sIDIwKTtcbiAgICAgICAgICAgIHRoaXMudmlldy5kb21PYnNlcnZlci5zdGFydCgpO1xuICAgICAgICB9XG4gICAgICAgIHZpZXcucm9vdC5hZGRFdmVudExpc3RlbmVyKFwibW91c2V1cFwiLCB0aGlzLnVwID0gdGhpcy51cC5iaW5kKHRoaXMpKTtcbiAgICAgICAgdmlldy5yb290LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZW1vdmVcIiwgdGhpcy5tb3ZlID0gdGhpcy5tb3ZlLmJpbmQodGhpcykpO1xuICAgICAgICBzZXRTZWxlY3Rpb25PcmlnaW4odmlldywgXCJwb2ludGVyXCIpO1xuICAgIH1cbiAgICBkb25lKCkge1xuICAgICAgICB0aGlzLnZpZXcucm9vdC5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2V1cFwiLCB0aGlzLnVwKTtcbiAgICAgICAgdGhpcy52aWV3LnJvb3QucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIm1vdXNlbW92ZVwiLCB0aGlzLm1vdmUpO1xuICAgICAgICBpZiAodGhpcy5taWdodERyYWcgJiYgdGhpcy50YXJnZXQpIHtcbiAgICAgICAgICAgIHRoaXMudmlldy5kb21PYnNlcnZlci5zdG9wKCk7XG4gICAgICAgICAgICBpZiAodGhpcy5taWdodERyYWcuYWRkQXR0cilcbiAgICAgICAgICAgICAgICB0aGlzLnRhcmdldC5yZW1vdmVBdHRyaWJ1dGUoXCJkcmFnZ2FibGVcIik7XG4gICAgICAgICAgICBpZiAodGhpcy5taWdodERyYWcuc2V0VW5lZGl0YWJsZSlcbiAgICAgICAgICAgICAgICB0aGlzLnRhcmdldC5yZW1vdmVBdHRyaWJ1dGUoXCJjb250ZW50RWRpdGFibGVcIik7XG4gICAgICAgICAgICB0aGlzLnZpZXcuZG9tT2JzZXJ2ZXIuc3RhcnQoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5kZWxheWVkU2VsZWN0aW9uU3luYylcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gc2VsZWN0aW9uVG9ET00odGhpcy52aWV3KSk7XG4gICAgICAgIHRoaXMudmlldy5pbnB1dC5tb3VzZURvd24gPSBudWxsO1xuICAgIH1cbiAgICB1cChldmVudCkge1xuICAgICAgICB0aGlzLmRvbmUoKTtcbiAgICAgICAgaWYgKCF0aGlzLnZpZXcuZG9tLmNvbnRhaW5zKGV2ZW50LnRhcmdldCkpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIGxldCBwb3MgPSB0aGlzLnBvcztcbiAgICAgICAgaWYgKHRoaXMudmlldy5zdGF0ZS5kb2MgIT0gdGhpcy5zdGFydERvYylcbiAgICAgICAgICAgIHBvcyA9IHRoaXMudmlldy5wb3NBdENvb3JkcyhldmVudENvb3JkcyhldmVudCkpO1xuICAgICAgICB0aGlzLnVwZGF0ZUFsbG93RGVmYXVsdChldmVudCk7XG4gICAgICAgIGlmICh0aGlzLmFsbG93RGVmYXVsdCB8fCAhcG9zKSB7XG4gICAgICAgICAgICBzZXRTZWxlY3Rpb25PcmlnaW4odGhpcy52aWV3LCBcInBvaW50ZXJcIik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaGFuZGxlU2luZ2xlQ2xpY2sodGhpcy52aWV3LCBwb3MucG9zLCBwb3MuaW5zaWRlLCBldmVudCwgdGhpcy5zZWxlY3ROb2RlKSkge1xuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChldmVudC5idXR0b24gPT0gMCAmJlxuICAgICAgICAgICAgKHRoaXMuZmx1c2hlZCB8fFxuICAgICAgICAgICAgICAgIC8vIFNhZmFyaSBpZ25vcmVzIGNsaWNrcyBvbiBkcmFnZ2FibGUgZWxlbWVudHNcbiAgICAgICAgICAgICAgICAoc2FmYXJpICYmIHRoaXMubWlnaHREcmFnICYmICF0aGlzLm1pZ2h0RHJhZy5ub2RlLmlzQXRvbSkgfHxcbiAgICAgICAgICAgICAgICAvLyBDaHJvbWUgd2lsbCBzb21ldGltZXMgdHJlYXQgYSBub2RlIHNlbGVjdGlvbiBhcyBhXG4gICAgICAgICAgICAgICAgLy8gY3Vyc29yLCBidXQgc3RpbGwgcmVwb3J0IHRoYXQgdGhlIG5vZGUgaXMgc2VsZWN0ZWRcbiAgICAgICAgICAgICAgICAvLyB3aGVuIGFza2VkIHRocm91Z2ggZ2V0U2VsZWN0aW9uLiBZb3UnbGwgdGhlbiBnZXQgYVxuICAgICAgICAgICAgICAgIC8vIHNpdHVhdGlvbiB3aGVyZSBjbGlja2luZyBhdCB0aGUgcG9pbnQgd2hlcmUgdGhhdFxuICAgICAgICAgICAgICAgIC8vIChoaWRkZW4pIGN1cnNvciBpcyBkb2Vzbid0IGNoYW5nZSB0aGUgc2VsZWN0aW9uLCBhbmRcbiAgICAgICAgICAgICAgICAvLyB0aHVzIGRvZXNuJ3QgZ2V0IGEgcmVhY3Rpb24gZnJvbSBQcm9zZU1pcnJvci4gVGhpc1xuICAgICAgICAgICAgICAgIC8vIHdvcmtzIGFyb3VuZCB0aGF0LlxuICAgICAgICAgICAgICAgIChjaHJvbWUgJiYgIXRoaXMudmlldy5zdGF0ZS5zZWxlY3Rpb24udmlzaWJsZSAmJlxuICAgICAgICAgICAgICAgICAgICBNYXRoLm1pbihNYXRoLmFicyhwb3MucG9zIC0gdGhpcy52aWV3LnN0YXRlLnNlbGVjdGlvbi5mcm9tKSwgTWF0aC5hYnMocG9zLnBvcyAtIHRoaXMudmlldy5zdGF0ZS5zZWxlY3Rpb24udG8pKSA8PSAyKSkpIHtcbiAgICAgICAgICAgIHVwZGF0ZVNlbGVjdGlvbih0aGlzLnZpZXcsIFNlbGVjdGlvbi5uZWFyKHRoaXMudmlldy5zdGF0ZS5kb2MucmVzb2x2ZShwb3MucG9zKSksIFwicG9pbnRlclwiKTtcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBzZXRTZWxlY3Rpb25PcmlnaW4odGhpcy52aWV3LCBcInBvaW50ZXJcIik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgbW92ZShldmVudCkge1xuICAgICAgICB0aGlzLnVwZGF0ZUFsbG93RGVmYXVsdChldmVudCk7XG4gICAgICAgIHNldFNlbGVjdGlvbk9yaWdpbih0aGlzLnZpZXcsIFwicG9pbnRlclwiKTtcbiAgICAgICAgaWYgKGV2ZW50LmJ1dHRvbnMgPT0gMClcbiAgICAgICAgICAgIHRoaXMuZG9uZSgpO1xuICAgIH1cbiAgICB1cGRhdGVBbGxvd0RlZmF1bHQoZXZlbnQpIHtcbiAgICAgICAgaWYgKCF0aGlzLmFsbG93RGVmYXVsdCAmJiAoTWF0aC5hYnModGhpcy5ldmVudC54IC0gZXZlbnQuY2xpZW50WCkgPiA0IHx8XG4gICAgICAgICAgICBNYXRoLmFicyh0aGlzLmV2ZW50LnkgLSBldmVudC5jbGllbnRZKSA+IDQpKVxuICAgICAgICAgICAgdGhpcy5hbGxvd0RlZmF1bHQgPSB0cnVlO1xuICAgIH1cbn1cbmhhbmRsZXJzLnRvdWNoc3RhcnQgPSB2aWV3ID0+IHtcbiAgICB2aWV3LmlucHV0Lmxhc3RUb3VjaCA9IERhdGUubm93KCk7XG4gICAgZm9yY2VET01GbHVzaCh2aWV3KTtcbiAgICBzZXRTZWxlY3Rpb25PcmlnaW4odmlldywgXCJwb2ludGVyXCIpO1xufTtcbmhhbmRsZXJzLnRvdWNobW92ZSA9IHZpZXcgPT4ge1xuICAgIHZpZXcuaW5wdXQubGFzdFRvdWNoID0gRGF0ZS5ub3coKTtcbiAgICBzZXRTZWxlY3Rpb25PcmlnaW4odmlldywgXCJwb2ludGVyXCIpO1xufTtcbmhhbmRsZXJzLmNvbnRleHRtZW51ID0gdmlldyA9PiBmb3JjZURPTUZsdXNoKHZpZXcpO1xuZnVuY3Rpb24gaW5Pck5lYXJDb21wb3NpdGlvbih2aWV3LCBldmVudCkge1xuICAgIGlmICh2aWV3LmNvbXBvc2luZylcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgLy8gU2VlIGh0dHBzOi8vd3d3LnN0dW0uZGUvMjAxNi8wNi8yNC9oYW5kbGluZy1pbWUtZXZlbnRzLWluLWphdmFzY3JpcHQvLlxuICAgIC8vIE9uIEphcGFuZXNlIGlucHV0IG1ldGhvZCBlZGl0b3JzIChJTUVzKSwgdGhlIEVudGVyIGtleSBpcyB1c2VkIHRvIGNvbmZpcm0gY2hhcmFjdGVyXG4gICAgLy8gc2VsZWN0aW9uLiBPbiBTYWZhcmksIHdoZW4gRW50ZXIgaXMgcHJlc3NlZCwgY29tcG9zaXRpb25lbmQgYW5kIGtleWRvd24gZXZlbnRzIGFyZVxuICAgIC8vIGVtaXR0ZWQuIFRoZSBrZXlkb3duIGV2ZW50IHRyaWdnZXJzIG5ld2xpbmUgaW5zZXJ0aW9uLCB3aGljaCB3ZSBkb24ndCB3YW50LlxuICAgIC8vIFRoaXMgbWV0aG9kIHJldHVybnMgdHJ1ZSBpZiB0aGUga2V5ZG93biBldmVudCBzaG91bGQgYmUgaWdub3JlZC5cbiAgICAvLyBXZSBvbmx5IGlnbm9yZSBpdCBvbmNlLCBhcyBwcmVzc2luZyBFbnRlciBhIHNlY29uZCB0aW1lICpzaG91bGQqIGluc2VydCBhIG5ld2xpbmUuXG4gICAgLy8gRnVydGhlcm1vcmUsIHRoZSBrZXlkb3duIGV2ZW50IHRpbWVzdGFtcCBtdXN0IGJlIGNsb3NlIHRvIHRoZSBjb21wb3NpdGlvbkVuZGVkQXQgdGltZXN0YW1wLlxuICAgIC8vIFRoaXMgZ3VhcmRzIGFnYWluc3QgdGhlIGNhc2Ugd2hlcmUgY29tcG9zaXRpb25lbmQgaXMgdHJpZ2dlcmVkIHdpdGhvdXQgdGhlIGtleWJvYXJkXG4gICAgLy8gKGUuZy4gY2hhcmFjdGVyIGNvbmZpcm1hdGlvbiBtYXkgYmUgZG9uZSB3aXRoIHRoZSBtb3VzZSksIGFuZCBrZXlkb3duIGlzIHRyaWdnZXJlZFxuICAgIC8vIGFmdGVyd2FyZHMtIHdlIHdvdWxkbid0IHdhbnQgdG8gaWdub3JlIHRoZSBrZXlkb3duIGV2ZW50IGluIHRoaXMgY2FzZS5cbiAgICBpZiAoc2FmYXJpICYmIE1hdGguYWJzKGV2ZW50LnRpbWVTdGFtcCAtIHZpZXcuaW5wdXQuY29tcG9zaXRpb25FbmRlZEF0KSA8IDUwMCkge1xuICAgICAgICB2aWV3LmlucHV0LmNvbXBvc2l0aW9uRW5kZWRBdCA9IC0yZTg7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG4vLyBEcm9wIGFjdGl2ZSBjb21wb3NpdGlvbiBhZnRlciA1IHNlY29uZHMgb2YgaW5hY3Rpdml0eSBvbiBBbmRyb2lkXG5jb25zdCB0aW1lb3V0Q29tcG9zaXRpb24gPSBhbmRyb2lkID8gNTAwMCA6IC0xO1xuZWRpdEhhbmRsZXJzLmNvbXBvc2l0aW9uc3RhcnQgPSBlZGl0SGFuZGxlcnMuY29tcG9zaXRpb251cGRhdGUgPSB2aWV3ID0+IHtcbiAgICBpZiAoIXZpZXcuY29tcG9zaW5nKSB7XG4gICAgICAgIHZpZXcuZG9tT2JzZXJ2ZXIuZmx1c2goKTtcbiAgICAgICAgbGV0IHsgc3RhdGUgfSA9IHZpZXcsICRwb3MgPSBzdGF0ZS5zZWxlY3Rpb24uJHRvO1xuICAgICAgICBpZiAoc3RhdGUuc2VsZWN0aW9uIGluc3RhbmNlb2YgVGV4dFNlbGVjdGlvbiAmJlxuICAgICAgICAgICAgKHN0YXRlLnN0b3JlZE1hcmtzIHx8XG4gICAgICAgICAgICAgICAgKCEkcG9zLnRleHRPZmZzZXQgJiYgJHBvcy5wYXJlbnRPZmZzZXQgJiYgJHBvcy5ub2RlQmVmb3JlLm1hcmtzLnNvbWUobSA9PiBtLnR5cGUuc3BlYy5pbmNsdXNpdmUgPT09IGZhbHNlKSkpKSB7XG4gICAgICAgICAgICAvLyBOZWVkIHRvIHdyYXAgdGhlIGN1cnNvciBpbiBtYXJrIG5vZGVzIGRpZmZlcmVudCBmcm9tIHRoZSBvbmVzIGluIHRoZSBET00gY29udGV4dFxuICAgICAgICAgICAgdmlldy5tYXJrQ3Vyc29yID0gdmlldy5zdGF0ZS5zdG9yZWRNYXJrcyB8fCAkcG9zLm1hcmtzKCk7XG4gICAgICAgICAgICBlbmRDb21wb3NpdGlvbih2aWV3LCB0cnVlKTtcbiAgICAgICAgICAgIHZpZXcubWFya0N1cnNvciA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBlbmRDb21wb3NpdGlvbih2aWV3LCAhc3RhdGUuc2VsZWN0aW9uLmVtcHR5KTtcbiAgICAgICAgICAgIC8vIEluIGZpcmVmb3gsIGlmIHRoZSBjdXJzb3IgaXMgYWZ0ZXIgYnV0IG91dHNpZGUgYSBtYXJrZWQgbm9kZSxcbiAgICAgICAgICAgIC8vIHRoZSBpbnNlcnRlZCB0ZXh0IHdvbid0IGluaGVyaXQgdGhlIG1hcmtzLiBTbyB0aGlzIG1vdmVzIGl0XG4gICAgICAgICAgICAvLyBpbnNpZGUgaWYgbmVjZXNzYXJ5LlxuICAgICAgICAgICAgaWYgKGdlY2tvICYmIHN0YXRlLnNlbGVjdGlvbi5lbXB0eSAmJiAkcG9zLnBhcmVudE9mZnNldCAmJiAhJHBvcy50ZXh0T2Zmc2V0ICYmICRwb3Mubm9kZUJlZm9yZS5tYXJrcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBsZXQgc2VsID0gdmlldy5kb21TZWxlY3Rpb25SYW5nZSgpO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IG5vZGUgPSBzZWwuZm9jdXNOb2RlLCBvZmZzZXQgPSBzZWwuZm9jdXNPZmZzZXQ7IG5vZGUgJiYgbm9kZS5ub2RlVHlwZSA9PSAxICYmIG9mZnNldCAhPSAwOykge1xuICAgICAgICAgICAgICAgICAgICBsZXQgYmVmb3JlID0gb2Zmc2V0IDwgMCA/IG5vZGUubGFzdENoaWxkIDogbm9kZS5jaGlsZE5vZGVzW29mZnNldCAtIDFdO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWJlZm9yZSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYmVmb3JlLm5vZGVUeXBlID09IDMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBzZWwgPSB2aWV3LmRvbVNlbGVjdGlvbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlbClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWwuY29sbGFwc2UoYmVmb3JlLCBiZWZvcmUubm9kZVZhbHVlLmxlbmd0aCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUgPSBiZWZvcmU7XG4gICAgICAgICAgICAgICAgICAgICAgICBvZmZzZXQgPSAtMTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2aWV3LmlucHV0LmNvbXBvc2luZyA9IHRydWU7XG4gICAgfVxuICAgIHNjaGVkdWxlQ29tcG9zZUVuZCh2aWV3LCB0aW1lb3V0Q29tcG9zaXRpb24pO1xufTtcbmVkaXRIYW5kbGVycy5jb21wb3NpdGlvbmVuZCA9ICh2aWV3LCBldmVudCkgPT4ge1xuICAgIGlmICh2aWV3LmNvbXBvc2luZykge1xuICAgICAgICB2aWV3LmlucHV0LmNvbXBvc2luZyA9IGZhbHNlO1xuICAgICAgICB2aWV3LmlucHV0LmNvbXBvc2l0aW9uRW5kZWRBdCA9IGV2ZW50LnRpbWVTdGFtcDtcbiAgICAgICAgdmlldy5pbnB1dC5jb21wb3NpdGlvblBlbmRpbmdDaGFuZ2VzID0gdmlldy5kb21PYnNlcnZlci5wZW5kaW5nUmVjb3JkcygpLmxlbmd0aCA/IHZpZXcuaW5wdXQuY29tcG9zaXRpb25JRCA6IDA7XG4gICAgICAgIHZpZXcuaW5wdXQuY29tcG9zaXRpb25Ob2RlID0gbnVsbDtcbiAgICAgICAgaWYgKHZpZXcuaW5wdXQuY29tcG9zaXRpb25QZW5kaW5nQ2hhbmdlcylcbiAgICAgICAgICAgIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oKCkgPT4gdmlldy5kb21PYnNlcnZlci5mbHVzaCgpKTtcbiAgICAgICAgdmlldy5pbnB1dC5jb21wb3NpdGlvbklEKys7XG4gICAgICAgIHNjaGVkdWxlQ29tcG9zZUVuZCh2aWV3LCAyMCk7XG4gICAgfVxufTtcbmZ1bmN0aW9uIHNjaGVkdWxlQ29tcG9zZUVuZCh2aWV3LCBkZWxheSkge1xuICAgIGNsZWFyVGltZW91dCh2aWV3LmlucHV0LmNvbXBvc2luZ1RpbWVvdXQpO1xuICAgIGlmIChkZWxheSA+IC0xKVxuICAgICAgICB2aWV3LmlucHV0LmNvbXBvc2luZ1RpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IGVuZENvbXBvc2l0aW9uKHZpZXcpLCBkZWxheSk7XG59XG5mdW5jdGlvbiBjbGVhckNvbXBvc2l0aW9uKHZpZXcpIHtcbiAgICBpZiAodmlldy5jb21wb3NpbmcpIHtcbiAgICAgICAgdmlldy5pbnB1dC5jb21wb3NpbmcgPSBmYWxzZTtcbiAgICAgICAgdmlldy5pbnB1dC5jb21wb3NpdGlvbkVuZGVkQXQgPSB0aW1lc3RhbXBGcm9tQ3VzdG9tRXZlbnQoKTtcbiAgICB9XG4gICAgd2hpbGUgKHZpZXcuaW5wdXQuY29tcG9zaXRpb25Ob2Rlcy5sZW5ndGggPiAwKVxuICAgICAgICB2aWV3LmlucHV0LmNvbXBvc2l0aW9uTm9kZXMucG9wKCkubWFya1BhcmVudHNEaXJ0eSgpO1xufVxuZnVuY3Rpb24gZmluZENvbXBvc2l0aW9uTm9kZSh2aWV3KSB7XG4gICAgbGV0IHNlbCA9IHZpZXcuZG9tU2VsZWN0aW9uUmFuZ2UoKTtcbiAgICBpZiAoIXNlbC5mb2N1c05vZGUpXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIGxldCB0ZXh0QmVmb3JlID0gdGV4dE5vZGVCZWZvcmUkMShzZWwuZm9jdXNOb2RlLCBzZWwuZm9jdXNPZmZzZXQpO1xuICAgIGxldCB0ZXh0QWZ0ZXIgPSB0ZXh0Tm9kZUFmdGVyJDEoc2VsLmZvY3VzTm9kZSwgc2VsLmZvY3VzT2Zmc2V0KTtcbiAgICBpZiAodGV4dEJlZm9yZSAmJiB0ZXh0QWZ0ZXIgJiYgdGV4dEJlZm9yZSAhPSB0ZXh0QWZ0ZXIpIHtcbiAgICAgICAgbGV0IGRlc2NBZnRlciA9IHRleHRBZnRlci5wbVZpZXdEZXNjLCBsYXN0Q2hhbmdlZCA9IHZpZXcuZG9tT2JzZXJ2ZXIubGFzdENoYW5nZWRUZXh0Tm9kZTtcbiAgICAgICAgaWYgKHRleHRCZWZvcmUgPT0gbGFzdENoYW5nZWQgfHwgdGV4dEFmdGVyID09IGxhc3RDaGFuZ2VkKVxuICAgICAgICAgICAgcmV0dXJuIGxhc3RDaGFuZ2VkO1xuICAgICAgICBpZiAoIWRlc2NBZnRlciB8fCAhZGVzY0FmdGVyLmlzVGV4dCh0ZXh0QWZ0ZXIubm9kZVZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRleHRBZnRlcjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh2aWV3LmlucHV0LmNvbXBvc2l0aW9uTm9kZSA9PSB0ZXh0QWZ0ZXIpIHtcbiAgICAgICAgICAgIGxldCBkZXNjQmVmb3JlID0gdGV4dEJlZm9yZS5wbVZpZXdEZXNjO1xuICAgICAgICAgICAgaWYgKCEoIWRlc2NCZWZvcmUgfHwgIWRlc2NCZWZvcmUuaXNUZXh0KHRleHRCZWZvcmUubm9kZVZhbHVlKSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRleHRBZnRlcjtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGV4dEJlZm9yZSB8fCB0ZXh0QWZ0ZXI7XG59XG5mdW5jdGlvbiB0aW1lc3RhbXBGcm9tQ3VzdG9tRXZlbnQoKSB7XG4gICAgbGV0IGV2ZW50ID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoXCJFdmVudFwiKTtcbiAgICBldmVudC5pbml0RXZlbnQoXCJldmVudFwiLCB0cnVlLCB0cnVlKTtcbiAgICByZXR1cm4gZXZlbnQudGltZVN0YW1wO1xufVxuLyoqXG5AaW50ZXJuYWxcbiovXG5mdW5jdGlvbiBlbmRDb21wb3NpdGlvbih2aWV3LCByZXN0YXJ0aW5nID0gZmFsc2UpIHtcbiAgICBpZiAoYW5kcm9pZCAmJiB2aWV3LmRvbU9ic2VydmVyLmZsdXNoaW5nU29vbiA+PSAwKVxuICAgICAgICByZXR1cm47XG4gICAgdmlldy5kb21PYnNlcnZlci5mb3JjZUZsdXNoKCk7XG4gICAgY2xlYXJDb21wb3NpdGlvbih2aWV3KTtcbiAgICBpZiAocmVzdGFydGluZyB8fCB2aWV3LmRvY1ZpZXcgJiYgdmlldy5kb2NWaWV3LmRpcnR5KSB7XG4gICAgICAgIGxldCBzZWwgPSBzZWxlY3Rpb25Gcm9tRE9NKHZpZXcpLCBjdXIgPSB2aWV3LnN0YXRlLnNlbGVjdGlvbjtcbiAgICAgICAgaWYgKHNlbCAmJiAhc2VsLmVxKGN1cikpXG4gICAgICAgICAgICB2aWV3LmRpc3BhdGNoKHZpZXcuc3RhdGUudHIuc2V0U2VsZWN0aW9uKHNlbCkpO1xuICAgICAgICBlbHNlIGlmICgodmlldy5tYXJrQ3Vyc29yIHx8IHJlc3RhcnRpbmcpICYmICFjdXIuJGZyb20ubm9kZShjdXIuJGZyb20uc2hhcmVkRGVwdGgoY3VyLnRvKSkuaW5saW5lQ29udGVudClcbiAgICAgICAgICAgIHZpZXcuZGlzcGF0Y2godmlldy5zdGF0ZS50ci5kZWxldGVTZWxlY3Rpb24oKSk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHZpZXcudXBkYXRlU3RhdGUodmlldy5zdGF0ZSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiBjYXB0dXJlQ29weSh2aWV3LCBkb20pIHtcbiAgICAvLyBUaGUgZXh0cmEgd3JhcHBlciBpcyBzb21laG93IG5lY2Vzc2FyeSBvbiBJRS9FZGdlIHRvIHByZXZlbnQgdGhlXG4gICAgLy8gY29udGVudCBmcm9tIGJlaW5nIG1hbmdsZWQgd2hlbiBpdCBpcyBwdXQgb250byB0aGUgY2xpcGJvYXJkXG4gICAgaWYgKCF2aWV3LmRvbS5wYXJlbnROb2RlKVxuICAgICAgICByZXR1cm47XG4gICAgbGV0IHdyYXAgPSB2aWV3LmRvbS5wYXJlbnROb2RlLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIikpO1xuICAgIHdyYXAuYXBwZW5kQ2hpbGQoZG9tKTtcbiAgICB3cmFwLnN0eWxlLmNzc1RleHQgPSBcInBvc2l0aW9uOiBmaXhlZDsgbGVmdDogLTEwMDAwcHg7IHRvcDogMTBweFwiO1xuICAgIGxldCBzZWwgPSBnZXRTZWxlY3Rpb24oKSwgcmFuZ2UgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpO1xuICAgIHJhbmdlLnNlbGVjdE5vZGVDb250ZW50cyhkb20pO1xuICAgIC8vIERvbmUgYmVjYXVzZSBJRSB3aWxsIGZpcmUgYSBzZWxlY3Rpb25jaGFuZ2UgbW92aW5nIHRoZSBzZWxlY3Rpb25cbiAgICAvLyB0byBpdHMgc3RhcnQgd2hlbiByZW1vdmVBbGxSYW5nZXMgaXMgY2FsbGVkIGFuZCB0aGUgZWRpdG9yIHN0aWxsXG4gICAgLy8gaGFzIGZvY3VzICh3aGljaCB3aWxsIG1lc3MgdXAgdGhlIGVkaXRvcidzIHNlbGVjdGlvbiBzdGF0ZSkuXG4gICAgdmlldy5kb20uYmx1cigpO1xuICAgIHNlbC5yZW1vdmVBbGxSYW5nZXMoKTtcbiAgICBzZWwuYWRkUmFuZ2UocmFuZ2UpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBpZiAod3JhcC5wYXJlbnROb2RlKVxuICAgICAgICAgICAgd3JhcC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHdyYXApO1xuICAgICAgICB2aWV3LmZvY3VzKCk7XG4gICAgfSwgNTApO1xufVxuLy8gVGhpcyBpcyB2ZXJ5IGNydWRlLCBidXQgdW5mb3J0dW5hdGVseSBib3RoIHRoZXNlIGJyb3dzZXJzIF9wcmV0ZW5kX1xuLy8gdGhhdCB0aGV5IGhhdmUgYSBjbGlwYm9hcmQgQVBJXHUyMDE0YWxsIHRoZSBvYmplY3RzIGFuZCBtZXRob2RzIGFyZVxuLy8gdGhlcmUsIHRoZXkganVzdCBkb24ndCB3b3JrLCBhbmQgdGhleSBhcmUgaGFyZCB0byB0ZXN0LlxuY29uc3QgYnJva2VuQ2xpcGJvYXJkQVBJID0gKGllICYmIGllX3ZlcnNpb24gPCAxNSkgfHxcbiAgICAoaW9zICYmIHdlYmtpdF92ZXJzaW9uIDwgNjA0KTtcbmhhbmRsZXJzLmNvcHkgPSBlZGl0SGFuZGxlcnMuY3V0ID0gKHZpZXcsIF9ldmVudCkgPT4ge1xuICAgIGxldCBldmVudCA9IF9ldmVudDtcbiAgICBsZXQgc2VsID0gdmlldy5zdGF0ZS5zZWxlY3Rpb24sIGN1dCA9IGV2ZW50LnR5cGUgPT0gXCJjdXRcIjtcbiAgICBpZiAoc2VsLmVtcHR5KVxuICAgICAgICByZXR1cm47XG4gICAgLy8gSUUgYW5kIEVkZ2UncyBjbGlwYm9hcmQgaW50ZXJmYWNlIGlzIGNvbXBsZXRlbHkgYnJva2VuXG4gICAgbGV0IGRhdGEgPSBicm9rZW5DbGlwYm9hcmRBUEkgPyBudWxsIDogZXZlbnQuY2xpcGJvYXJkRGF0YTtcbiAgICBsZXQgc2xpY2UgPSBzZWwuY29udGVudCgpLCB7IGRvbSwgdGV4dCB9ID0gc2VyaWFsaXplRm9yQ2xpcGJvYXJkKHZpZXcsIHNsaWNlKTtcbiAgICBpZiAoZGF0YSkge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBkYXRhLmNsZWFyRGF0YSgpO1xuICAgICAgICBkYXRhLnNldERhdGEoXCJ0ZXh0L2h0bWxcIiwgZG9tLmlubmVySFRNTCk7XG4gICAgICAgIGRhdGEuc2V0RGF0YShcInRleHQvcGxhaW5cIiwgdGV4dCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBjYXB0dXJlQ29weSh2aWV3LCBkb20pO1xuICAgIH1cbiAgICBpZiAoY3V0KVxuICAgICAgICB2aWV3LmRpc3BhdGNoKHZpZXcuc3RhdGUudHIuZGVsZXRlU2VsZWN0aW9uKCkuc2Nyb2xsSW50b1ZpZXcoKS5zZXRNZXRhKFwidWlFdmVudFwiLCBcImN1dFwiKSk7XG59O1xuZnVuY3Rpb24gc2xpY2VTaW5nbGVOb2RlKHNsaWNlKSB7XG4gICAgcmV0dXJuIHNsaWNlLm9wZW5TdGFydCA9PSAwICYmIHNsaWNlLm9wZW5FbmQgPT0gMCAmJiBzbGljZS5jb250ZW50LmNoaWxkQ291bnQgPT0gMSA/IHNsaWNlLmNvbnRlbnQuZmlyc3RDaGlsZCA6IG51bGw7XG59XG5mdW5jdGlvbiBjYXB0dXJlUGFzdGUodmlldywgZXZlbnQpIHtcbiAgICBpZiAoIXZpZXcuZG9tLnBhcmVudE5vZGUpXG4gICAgICAgIHJldHVybjtcbiAgICBsZXQgcGxhaW5UZXh0ID0gdmlldy5pbnB1dC5zaGlmdEtleSB8fCB2aWV3LnN0YXRlLnNlbGVjdGlvbi4kZnJvbS5wYXJlbnQudHlwZS5zcGVjLmNvZGU7XG4gICAgbGV0IHRhcmdldCA9IHZpZXcuZG9tLnBhcmVudE5vZGUuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlRWxlbWVudChwbGFpblRleHQgPyBcInRleHRhcmVhXCIgOiBcImRpdlwiKSk7XG4gICAgaWYgKCFwbGFpblRleHQpXG4gICAgICAgIHRhcmdldC5jb250ZW50RWRpdGFibGUgPSBcInRydWVcIjtcbiAgICB0YXJnZXQuc3R5bGUuY3NzVGV4dCA9IFwicG9zaXRpb246IGZpeGVkOyBsZWZ0OiAtMTAwMDBweDsgdG9wOiAxMHB4XCI7XG4gICAgdGFyZ2V0LmZvY3VzKCk7XG4gICAgbGV0IHBsYWluID0gdmlldy5pbnB1dC5zaGlmdEtleSAmJiB2aWV3LmlucHV0Lmxhc3RLZXlDb2RlICE9IDQ1O1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICB2aWV3LmZvY3VzKCk7XG4gICAgICAgIGlmICh0YXJnZXQucGFyZW50Tm9kZSlcbiAgICAgICAgICAgIHRhcmdldC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRhcmdldCk7XG4gICAgICAgIGlmIChwbGFpblRleHQpXG4gICAgICAgICAgICBkb1Bhc3RlKHZpZXcsIHRhcmdldC52YWx1ZSwgbnVsbCwgcGxhaW4sIGV2ZW50KTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgZG9QYXN0ZSh2aWV3LCB0YXJnZXQudGV4dENvbnRlbnQsIHRhcmdldC5pbm5lckhUTUwsIHBsYWluLCBldmVudCk7XG4gICAgfSwgNTApO1xufVxuZnVuY3Rpb24gZG9QYXN0ZSh2aWV3LCB0ZXh0LCBodG1sLCBwcmVmZXJQbGFpbiwgZXZlbnQpIHtcbiAgICBsZXQgc2xpY2UgPSBwYXJzZUZyb21DbGlwYm9hcmQodmlldywgdGV4dCwgaHRtbCwgcHJlZmVyUGxhaW4sIHZpZXcuc3RhdGUuc2VsZWN0aW9uLiRmcm9tKTtcbiAgICBpZiAodmlldy5zb21lUHJvcChcImhhbmRsZVBhc3RlXCIsIGYgPT4gZih2aWV3LCBldmVudCwgc2xpY2UgfHwgU2xpY2UuZW1wdHkpKSlcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgaWYgKCFzbGljZSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGxldCBzaW5nbGVOb2RlID0gc2xpY2VTaW5nbGVOb2RlKHNsaWNlKTtcbiAgICBsZXQgdHIgPSBzaW5nbGVOb2RlXG4gICAgICAgID8gdmlldy5zdGF0ZS50ci5yZXBsYWNlU2VsZWN0aW9uV2l0aChzaW5nbGVOb2RlLCBwcmVmZXJQbGFpbilcbiAgICAgICAgOiB2aWV3LnN0YXRlLnRyLnJlcGxhY2VTZWxlY3Rpb24oc2xpY2UpO1xuICAgIHZpZXcuZGlzcGF0Y2godHIuc2Nyb2xsSW50b1ZpZXcoKS5zZXRNZXRhKFwicGFzdGVcIiwgdHJ1ZSkuc2V0TWV0YShcInVpRXZlbnRcIiwgXCJwYXN0ZVwiKSk7XG4gICAgcmV0dXJuIHRydWU7XG59XG5mdW5jdGlvbiBnZXRUZXh0KGNsaXBib2FyZERhdGEpIHtcbiAgICBsZXQgdGV4dCA9IGNsaXBib2FyZERhdGEuZ2V0RGF0YShcInRleHQvcGxhaW5cIikgfHwgY2xpcGJvYXJkRGF0YS5nZXREYXRhKFwiVGV4dFwiKTtcbiAgICBpZiAodGV4dClcbiAgICAgICAgcmV0dXJuIHRleHQ7XG4gICAgbGV0IHVyaXMgPSBjbGlwYm9hcmREYXRhLmdldERhdGEoXCJ0ZXh0L3VyaS1saXN0XCIpO1xuICAgIHJldHVybiB1cmlzID8gdXJpcy5yZXBsYWNlKC9cXHI/XFxuL2csIFwiIFwiKSA6IFwiXCI7XG59XG5lZGl0SGFuZGxlcnMucGFzdGUgPSAodmlldywgX2V2ZW50KSA9PiB7XG4gICAgbGV0IGV2ZW50ID0gX2V2ZW50O1xuICAgIC8vIEhhbmRsaW5nIHBhc3RlIGZyb20gSmF2YVNjcmlwdCBkdXJpbmcgY29tcG9zaXRpb24gaXMgdmVyeSBwb29ybHlcbiAgICAvLyBoYW5kbGVkIGJ5IGJyb3dzZXJzLCBzbyBhcyBhIGRvZGd5IGJ1dCBwcmVmZXJhYmxlIGtsdWRnZSwgd2UganVzdFxuICAgIC8vIGxldCB0aGUgYnJvd3NlciBkbyBpdHMgbmF0aXZlIHRoaW5nIHRoZXJlLCBleGNlcHQgb24gQW5kcm9pZCxcbiAgICAvLyB3aGVyZSB0aGUgZWRpdG9yIGlzIGFsbW9zdCBhbHdheXMgY29tcG9zaW5nLlxuICAgIGlmICh2aWV3LmNvbXBvc2luZyAmJiAhYW5kcm9pZClcbiAgICAgICAgcmV0dXJuO1xuICAgIGxldCBkYXRhID0gYnJva2VuQ2xpcGJvYXJkQVBJID8gbnVsbCA6IGV2ZW50LmNsaXBib2FyZERhdGE7XG4gICAgbGV0IHBsYWluID0gdmlldy5pbnB1dC5zaGlmdEtleSAmJiB2aWV3LmlucHV0Lmxhc3RLZXlDb2RlICE9IDQ1O1xuICAgIGlmIChkYXRhICYmIGRvUGFzdGUodmlldywgZ2V0VGV4dChkYXRhKSwgZGF0YS5nZXREYXRhKFwidGV4dC9odG1sXCIpLCBwbGFpbiwgZXZlbnQpKVxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGVsc2VcbiAgICAgICAgY2FwdHVyZVBhc3RlKHZpZXcsIGV2ZW50KTtcbn07XG5jbGFzcyBEcmFnZ2luZyB7XG4gICAgY29uc3RydWN0b3Ioc2xpY2UsIG1vdmUsIG5vZGUpIHtcbiAgICAgICAgdGhpcy5zbGljZSA9IHNsaWNlO1xuICAgICAgICB0aGlzLm1vdmUgPSBtb3ZlO1xuICAgICAgICB0aGlzLm5vZGUgPSBub2RlO1xuICAgIH1cbn1cbmNvbnN0IGRyYWdDb3B5TW9kaWZpZXIgPSBtYWMgPyBcImFsdEtleVwiIDogXCJjdHJsS2V5XCI7XG5mdW5jdGlvbiBkcmFnTW92ZXModmlldywgZXZlbnQpIHtcbiAgICBsZXQgbW92ZXMgPSB2aWV3LnNvbWVQcm9wKFwiZHJhZ0NvcGllc1wiLCB0ZXN0ID0+ICF0ZXN0KGV2ZW50KSk7XG4gICAgcmV0dXJuIG1vdmVzICE9IG51bGwgPyBtb3ZlcyA6ICFldmVudFtkcmFnQ29weU1vZGlmaWVyXTtcbn1cbmhhbmRsZXJzLmRyYWdzdGFydCA9ICh2aWV3LCBfZXZlbnQpID0+IHtcbiAgICBsZXQgZXZlbnQgPSBfZXZlbnQ7XG4gICAgbGV0IG1vdXNlRG93biA9IHZpZXcuaW5wdXQubW91c2VEb3duO1xuICAgIGlmIChtb3VzZURvd24pXG4gICAgICAgIG1vdXNlRG93bi5kb25lKCk7XG4gICAgaWYgKCFldmVudC5kYXRhVHJhbnNmZXIpXG4gICAgICAgIHJldHVybjtcbiAgICBsZXQgc2VsID0gdmlldy5zdGF0ZS5zZWxlY3Rpb247XG4gICAgbGV0IHBvcyA9IHNlbC5lbXB0eSA/IG51bGwgOiB2aWV3LnBvc0F0Q29vcmRzKGV2ZW50Q29vcmRzKGV2ZW50KSk7XG4gICAgbGV0IG5vZGU7XG4gICAgaWYgKHBvcyAmJiBwb3MucG9zID49IHNlbC5mcm9tICYmIHBvcy5wb3MgPD0gKHNlbCBpbnN0YW5jZW9mIE5vZGVTZWxlY3Rpb24gPyBzZWwudG8gLSAxIDogc2VsLnRvKSkgO1xuICAgIGVsc2UgaWYgKG1vdXNlRG93biAmJiBtb3VzZURvd24ubWlnaHREcmFnKSB7XG4gICAgICAgIG5vZGUgPSBOb2RlU2VsZWN0aW9uLmNyZWF0ZSh2aWV3LnN0YXRlLmRvYywgbW91c2VEb3duLm1pZ2h0RHJhZy5wb3MpO1xuICAgIH1cbiAgICBlbHNlIGlmIChldmVudC50YXJnZXQgJiYgZXZlbnQudGFyZ2V0Lm5vZGVUeXBlID09IDEpIHtcbiAgICAgICAgbGV0IGRlc2MgPSB2aWV3LmRvY1ZpZXcubmVhcmVzdERlc2MoZXZlbnQudGFyZ2V0LCB0cnVlKTtcbiAgICAgICAgaWYgKGRlc2MgJiYgZGVzYy5ub2RlLnR5cGUuc3BlYy5kcmFnZ2FibGUgJiYgZGVzYyAhPSB2aWV3LmRvY1ZpZXcpXG4gICAgICAgICAgICBub2RlID0gTm9kZVNlbGVjdGlvbi5jcmVhdGUodmlldy5zdGF0ZS5kb2MsIGRlc2MucG9zQmVmb3JlKTtcbiAgICB9XG4gICAgbGV0IGRyYWdnZWRTbGljZSA9IChub2RlIHx8IHZpZXcuc3RhdGUuc2VsZWN0aW9uKS5jb250ZW50KCk7XG4gICAgbGV0IHsgZG9tLCB0ZXh0LCBzbGljZSB9ID0gc2VyaWFsaXplRm9yQ2xpcGJvYXJkKHZpZXcsIGRyYWdnZWRTbGljZSk7XG4gICAgLy8gUHJlLTEyMCBDaHJvbWUgdmVyc2lvbnMgY2xlYXIgZmlsZXMgd2hlbiBjYWxsaW5nIGBjbGVhckRhdGFgICgjMTQ3MilcbiAgICBpZiAoIWV2ZW50LmRhdGFUcmFuc2Zlci5maWxlcy5sZW5ndGggfHwgIWNocm9tZSB8fCBjaHJvbWVfdmVyc2lvbiA+IDEyMClcbiAgICAgICAgZXZlbnQuZGF0YVRyYW5zZmVyLmNsZWFyRGF0YSgpO1xuICAgIGV2ZW50LmRhdGFUcmFuc2Zlci5zZXREYXRhKGJyb2tlbkNsaXBib2FyZEFQSSA/IFwiVGV4dFwiIDogXCJ0ZXh0L2h0bWxcIiwgZG9tLmlubmVySFRNTCk7XG4gICAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9Qcm9zZU1pcnJvci9wcm9zZW1pcnJvci9pc3N1ZXMvMTE1NlxuICAgIGV2ZW50LmRhdGFUcmFuc2Zlci5lZmZlY3RBbGxvd2VkID0gXCJjb3B5TW92ZVwiO1xuICAgIGlmICghYnJva2VuQ2xpcGJvYXJkQVBJKVxuICAgICAgICBldmVudC5kYXRhVHJhbnNmZXIuc2V0RGF0YShcInRleHQvcGxhaW5cIiwgdGV4dCk7XG4gICAgdmlldy5kcmFnZ2luZyA9IG5ldyBEcmFnZ2luZyhzbGljZSwgZHJhZ01vdmVzKHZpZXcsIGV2ZW50KSwgbm9kZSk7XG59O1xuaGFuZGxlcnMuZHJhZ2VuZCA9IHZpZXcgPT4ge1xuICAgIGxldCBkcmFnZ2luZyA9IHZpZXcuZHJhZ2dpbmc7XG4gICAgd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBpZiAodmlldy5kcmFnZ2luZyA9PSBkcmFnZ2luZylcbiAgICAgICAgICAgIHZpZXcuZHJhZ2dpbmcgPSBudWxsO1xuICAgIH0sIDUwKTtcbn07XG5lZGl0SGFuZGxlcnMuZHJhZ292ZXIgPSBlZGl0SGFuZGxlcnMuZHJhZ2VudGVyID0gKF8sIGUpID0+IGUucHJldmVudERlZmF1bHQoKTtcbmVkaXRIYW5kbGVycy5kcm9wID0gKHZpZXcsIF9ldmVudCkgPT4ge1xuICAgIGxldCBldmVudCA9IF9ldmVudDtcbiAgICBsZXQgZHJhZ2dpbmcgPSB2aWV3LmRyYWdnaW5nO1xuICAgIHZpZXcuZHJhZ2dpbmcgPSBudWxsO1xuICAgIGlmICghZXZlbnQuZGF0YVRyYW5zZmVyKVxuICAgICAgICByZXR1cm47XG4gICAgbGV0IGV2ZW50UG9zID0gdmlldy5wb3NBdENvb3JkcyhldmVudENvb3JkcyhldmVudCkpO1xuICAgIGlmICghZXZlbnRQb3MpXG4gICAgICAgIHJldHVybjtcbiAgICBsZXQgJG1vdXNlID0gdmlldy5zdGF0ZS5kb2MucmVzb2x2ZShldmVudFBvcy5wb3MpO1xuICAgIGxldCBzbGljZSA9IGRyYWdnaW5nICYmIGRyYWdnaW5nLnNsaWNlO1xuICAgIGlmIChzbGljZSkge1xuICAgICAgICB2aWV3LnNvbWVQcm9wKFwidHJhbnNmb3JtUGFzdGVkXCIsIGYgPT4geyBzbGljZSA9IGYoc2xpY2UsIHZpZXcpOyB9KTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHNsaWNlID0gcGFyc2VGcm9tQ2xpcGJvYXJkKHZpZXcsIGdldFRleHQoZXZlbnQuZGF0YVRyYW5zZmVyKSwgYnJva2VuQ2xpcGJvYXJkQVBJID8gbnVsbCA6IGV2ZW50LmRhdGFUcmFuc2Zlci5nZXREYXRhKFwidGV4dC9odG1sXCIpLCBmYWxzZSwgJG1vdXNlKTtcbiAgICB9XG4gICAgbGV0IG1vdmUgPSAhIShkcmFnZ2luZyAmJiBkcmFnTW92ZXModmlldywgZXZlbnQpKTtcbiAgICBpZiAodmlldy5zb21lUHJvcChcImhhbmRsZURyb3BcIiwgZiA9PiBmKHZpZXcsIGV2ZW50LCBzbGljZSB8fCBTbGljZS5lbXB0eSwgbW92ZSkpKSB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCFzbGljZSlcbiAgICAgICAgcmV0dXJuO1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgbGV0IGluc2VydFBvcyA9IHNsaWNlID8gZHJvcFBvaW50KHZpZXcuc3RhdGUuZG9jLCAkbW91c2UucG9zLCBzbGljZSkgOiAkbW91c2UucG9zO1xuICAgIGlmIChpbnNlcnRQb3MgPT0gbnVsbClcbiAgICAgICAgaW5zZXJ0UG9zID0gJG1vdXNlLnBvcztcbiAgICBsZXQgdHIgPSB2aWV3LnN0YXRlLnRyO1xuICAgIGlmIChtb3ZlKSB7XG4gICAgICAgIGxldCB7IG5vZGUgfSA9IGRyYWdnaW5nO1xuICAgICAgICBpZiAobm9kZSlcbiAgICAgICAgICAgIG5vZGUucmVwbGFjZSh0cik7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHRyLmRlbGV0ZVNlbGVjdGlvbigpO1xuICAgIH1cbiAgICBsZXQgcG9zID0gdHIubWFwcGluZy5tYXAoaW5zZXJ0UG9zKTtcbiAgICBsZXQgaXNOb2RlID0gc2xpY2Uub3BlblN0YXJ0ID09IDAgJiYgc2xpY2Uub3BlbkVuZCA9PSAwICYmIHNsaWNlLmNvbnRlbnQuY2hpbGRDb3VudCA9PSAxO1xuICAgIGxldCBiZWZvcmVJbnNlcnQgPSB0ci5kb2M7XG4gICAgaWYgKGlzTm9kZSlcbiAgICAgICAgdHIucmVwbGFjZVJhbmdlV2l0aChwb3MsIHBvcywgc2xpY2UuY29udGVudC5maXJzdENoaWxkKTtcbiAgICBlbHNlXG4gICAgICAgIHRyLnJlcGxhY2VSYW5nZShwb3MsIHBvcywgc2xpY2UpO1xuICAgIGlmICh0ci5kb2MuZXEoYmVmb3JlSW5zZXJ0KSlcbiAgICAgICAgcmV0dXJuO1xuICAgIGxldCAkcG9zID0gdHIuZG9jLnJlc29sdmUocG9zKTtcbiAgICBpZiAoaXNOb2RlICYmIE5vZGVTZWxlY3Rpb24uaXNTZWxlY3RhYmxlKHNsaWNlLmNvbnRlbnQuZmlyc3RDaGlsZCkgJiZcbiAgICAgICAgJHBvcy5ub2RlQWZ0ZXIgJiYgJHBvcy5ub2RlQWZ0ZXIuc2FtZU1hcmt1cChzbGljZS5jb250ZW50LmZpcnN0Q2hpbGQpKSB7XG4gICAgICAgIHRyLnNldFNlbGVjdGlvbihuZXcgTm9kZVNlbGVjdGlvbigkcG9zKSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBsZXQgZW5kID0gdHIubWFwcGluZy5tYXAoaW5zZXJ0UG9zKTtcbiAgICAgICAgdHIubWFwcGluZy5tYXBzW3RyLm1hcHBpbmcubWFwcy5sZW5ndGggLSAxXS5mb3JFYWNoKChfZnJvbSwgX3RvLCBfbmV3RnJvbSwgbmV3VG8pID0+IGVuZCA9IG5ld1RvKTtcbiAgICAgICAgdHIuc2V0U2VsZWN0aW9uKHNlbGVjdGlvbkJldHdlZW4odmlldywgJHBvcywgdHIuZG9jLnJlc29sdmUoZW5kKSkpO1xuICAgIH1cbiAgICB2aWV3LmZvY3VzKCk7XG4gICAgdmlldy5kaXNwYXRjaCh0ci5zZXRNZXRhKFwidWlFdmVudFwiLCBcImRyb3BcIikpO1xufTtcbmhhbmRsZXJzLmZvY3VzID0gdmlldyA9PiB7XG4gICAgdmlldy5pbnB1dC5sYXN0Rm9jdXMgPSBEYXRlLm5vdygpO1xuICAgIGlmICghdmlldy5mb2N1c2VkKSB7XG4gICAgICAgIHZpZXcuZG9tT2JzZXJ2ZXIuc3RvcCgpO1xuICAgICAgICB2aWV3LmRvbS5jbGFzc0xpc3QuYWRkKFwiUHJvc2VNaXJyb3ItZm9jdXNlZFwiKTtcbiAgICAgICAgdmlldy5kb21PYnNlcnZlci5zdGFydCgpO1xuICAgICAgICB2aWV3LmZvY3VzZWQgPSB0cnVlO1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGlmICh2aWV3LmRvY1ZpZXcgJiYgdmlldy5oYXNGb2N1cygpICYmICF2aWV3LmRvbU9ic2VydmVyLmN1cnJlbnRTZWxlY3Rpb24uZXEodmlldy5kb21TZWxlY3Rpb25SYW5nZSgpKSlcbiAgICAgICAgICAgICAgICBzZWxlY3Rpb25Ub0RPTSh2aWV3KTtcbiAgICAgICAgfSwgMjApO1xuICAgIH1cbn07XG5oYW5kbGVycy5ibHVyID0gKHZpZXcsIF9ldmVudCkgPT4ge1xuICAgIGxldCBldmVudCA9IF9ldmVudDtcbiAgICBpZiAodmlldy5mb2N1c2VkKSB7XG4gICAgICAgIHZpZXcuZG9tT2JzZXJ2ZXIuc3RvcCgpO1xuICAgICAgICB2aWV3LmRvbS5jbGFzc0xpc3QucmVtb3ZlKFwiUHJvc2VNaXJyb3ItZm9jdXNlZFwiKTtcbiAgICAgICAgdmlldy5kb21PYnNlcnZlci5zdGFydCgpO1xuICAgICAgICBpZiAoZXZlbnQucmVsYXRlZFRhcmdldCAmJiB2aWV3LmRvbS5jb250YWlucyhldmVudC5yZWxhdGVkVGFyZ2V0KSlcbiAgICAgICAgICAgIHZpZXcuZG9tT2JzZXJ2ZXIuY3VycmVudFNlbGVjdGlvbi5jbGVhcigpO1xuICAgICAgICB2aWV3LmZvY3VzZWQgPSBmYWxzZTtcbiAgICB9XG59O1xuaGFuZGxlcnMuYmVmb3JlaW5wdXQgPSAodmlldywgX2V2ZW50KSA9PiB7XG4gICAgbGV0IGV2ZW50ID0gX2V2ZW50O1xuICAgIC8vIFdlIHNob3VsZCBwcm9iYWJseSBkbyBtb3JlIHdpdGggYmVmb3JlaW5wdXQgZXZlbnRzLCBidXQgc3VwcG9ydFxuICAgIC8vIGlzIHNvIHNwb3R0eSB0aGF0IEknbSBzdGlsbCB3YWl0aW5nIHRvIHNlZSB3aGVyZSB0aGV5IGFyZSBnb2luZy5cbiAgICAvLyBWZXJ5IHNwZWNpZmljIGhhY2sgdG8gZGVhbCB3aXRoIGJhY2tzcGFjZSBzb21ldGltZXMgZmFpbGluZyBvblxuICAgIC8vIENocm9tZSBBbmRyb2lkIHdoZW4gYWZ0ZXIgYW4gdW5lZGl0YWJsZSBub2RlLlxuICAgIGlmIChjaHJvbWUgJiYgYW5kcm9pZCAmJiBldmVudC5pbnB1dFR5cGUgPT0gXCJkZWxldGVDb250ZW50QmFja3dhcmRcIikge1xuICAgICAgICB2aWV3LmRvbU9ic2VydmVyLmZsdXNoU29vbigpO1xuICAgICAgICBsZXQgeyBkb21DaGFuZ2VDb3VudCB9ID0gdmlldy5pbnB1dDtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICBpZiAodmlldy5pbnB1dC5kb21DaGFuZ2VDb3VudCAhPSBkb21DaGFuZ2VDb3VudClcbiAgICAgICAgICAgICAgICByZXR1cm47IC8vIEV2ZW50IGFscmVhZHkgaGFkIHNvbWUgZWZmZWN0XG4gICAgICAgICAgICAvLyBUaGlzIGJ1ZyB0ZW5kcyB0byBjbG9zZSB0aGUgdmlydHVhbCBrZXlib2FyZCwgc28gd2UgcmVmb2N1c1xuICAgICAgICAgICAgdmlldy5kb20uYmx1cigpO1xuICAgICAgICAgICAgdmlldy5mb2N1cygpO1xuICAgICAgICAgICAgaWYgKHZpZXcuc29tZVByb3AoXCJoYW5kbGVLZXlEb3duXCIsIGYgPT4gZih2aWV3LCBrZXlFdmVudCg4LCBcIkJhY2tzcGFjZVwiKSkpKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIGxldCB7ICRjdXJzb3IgfSA9IHZpZXcuc3RhdGUuc2VsZWN0aW9uO1xuICAgICAgICAgICAgLy8gQ3J1ZGUgYXBwcm94aW1hdGlvbiBvZiBiYWNrc3BhY2UgYmVoYXZpb3Igd2hlbiBubyBjb21tYW5kIGhhbmRsZWQgaXRcbiAgICAgICAgICAgIGlmICgkY3Vyc29yICYmICRjdXJzb3IucG9zID4gMClcbiAgICAgICAgICAgICAgICB2aWV3LmRpc3BhdGNoKHZpZXcuc3RhdGUudHIuZGVsZXRlKCRjdXJzb3IucG9zIC0gMSwgJGN1cnNvci5wb3MpLnNjcm9sbEludG9WaWV3KCkpO1xuICAgICAgICB9LCA1MCk7XG4gICAgfVxufTtcbi8vIE1ha2Ugc3VyZSBhbGwgaGFuZGxlcnMgZ2V0IHJlZ2lzdGVyZWRcbmZvciAobGV0IHByb3AgaW4gZWRpdEhhbmRsZXJzKVxuICAgIGhhbmRsZXJzW3Byb3BdID0gZWRpdEhhbmRsZXJzW3Byb3BdO1xuXG5mdW5jdGlvbiBjb21wYXJlT2JqcyhhLCBiKSB7XG4gICAgaWYgKGEgPT0gYilcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgZm9yIChsZXQgcCBpbiBhKVxuICAgICAgICBpZiAoYVtwXSAhPT0gYltwXSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICBmb3IgKGxldCBwIGluIGIpXG4gICAgICAgIGlmICghKHAgaW4gYSkpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIHRydWU7XG59XG5jbGFzcyBXaWRnZXRUeXBlIHtcbiAgICBjb25zdHJ1Y3Rvcih0b0RPTSwgc3BlYykge1xuICAgICAgICB0aGlzLnRvRE9NID0gdG9ET007XG4gICAgICAgIHRoaXMuc3BlYyA9IHNwZWMgfHwgbm9TcGVjO1xuICAgICAgICB0aGlzLnNpZGUgPSB0aGlzLnNwZWMuc2lkZSB8fCAwO1xuICAgIH1cbiAgICBtYXAobWFwcGluZywgc3Bhbiwgb2Zmc2V0LCBvbGRPZmZzZXQpIHtcbiAgICAgICAgbGV0IHsgcG9zLCBkZWxldGVkIH0gPSBtYXBwaW5nLm1hcFJlc3VsdChzcGFuLmZyb20gKyBvbGRPZmZzZXQsIHRoaXMuc2lkZSA8IDAgPyAtMSA6IDEpO1xuICAgICAgICByZXR1cm4gZGVsZXRlZCA/IG51bGwgOiBuZXcgRGVjb3JhdGlvbihwb3MgLSBvZmZzZXQsIHBvcyAtIG9mZnNldCwgdGhpcyk7XG4gICAgfVxuICAgIHZhbGlkKCkgeyByZXR1cm4gdHJ1ZTsgfVxuICAgIGVxKG90aGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzID09IG90aGVyIHx8XG4gICAgICAgICAgICAob3RoZXIgaW5zdGFuY2VvZiBXaWRnZXRUeXBlICYmXG4gICAgICAgICAgICAgICAgKHRoaXMuc3BlYy5rZXkgJiYgdGhpcy5zcGVjLmtleSA9PSBvdGhlci5zcGVjLmtleSB8fFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnRvRE9NID09IG90aGVyLnRvRE9NICYmIGNvbXBhcmVPYmpzKHRoaXMuc3BlYywgb3RoZXIuc3BlYykpKTtcbiAgICB9XG4gICAgZGVzdHJveShub2RlKSB7XG4gICAgICAgIGlmICh0aGlzLnNwZWMuZGVzdHJveSlcbiAgICAgICAgICAgIHRoaXMuc3BlYy5kZXN0cm95KG5vZGUpO1xuICAgIH1cbn1cbmNsYXNzIElubGluZVR5cGUge1xuICAgIGNvbnN0cnVjdG9yKGF0dHJzLCBzcGVjKSB7XG4gICAgICAgIHRoaXMuYXR0cnMgPSBhdHRycztcbiAgICAgICAgdGhpcy5zcGVjID0gc3BlYyB8fCBub1NwZWM7XG4gICAgfVxuICAgIG1hcChtYXBwaW5nLCBzcGFuLCBvZmZzZXQsIG9sZE9mZnNldCkge1xuICAgICAgICBsZXQgZnJvbSA9IG1hcHBpbmcubWFwKHNwYW4uZnJvbSArIG9sZE9mZnNldCwgdGhpcy5zcGVjLmluY2x1c2l2ZVN0YXJ0ID8gLTEgOiAxKSAtIG9mZnNldDtcbiAgICAgICAgbGV0IHRvID0gbWFwcGluZy5tYXAoc3Bhbi50byArIG9sZE9mZnNldCwgdGhpcy5zcGVjLmluY2x1c2l2ZUVuZCA/IDEgOiAtMSkgLSBvZmZzZXQ7XG4gICAgICAgIHJldHVybiBmcm9tID49IHRvID8gbnVsbCA6IG5ldyBEZWNvcmF0aW9uKGZyb20sIHRvLCB0aGlzKTtcbiAgICB9XG4gICAgdmFsaWQoXywgc3BhbikgeyByZXR1cm4gc3Bhbi5mcm9tIDwgc3Bhbi50bzsgfVxuICAgIGVxKG90aGVyKSB7XG4gICAgICAgIHJldHVybiB0aGlzID09IG90aGVyIHx8XG4gICAgICAgICAgICAob3RoZXIgaW5zdGFuY2VvZiBJbmxpbmVUeXBlICYmIGNvbXBhcmVPYmpzKHRoaXMuYXR0cnMsIG90aGVyLmF0dHJzKSAmJlxuICAgICAgICAgICAgICAgIGNvbXBhcmVPYmpzKHRoaXMuc3BlYywgb3RoZXIuc3BlYykpO1xuICAgIH1cbiAgICBzdGF0aWMgaXMoc3BhbikgeyByZXR1cm4gc3Bhbi50eXBlIGluc3RhbmNlb2YgSW5saW5lVHlwZTsgfVxuICAgIGRlc3Ryb3koKSB7IH1cbn1cbmNsYXNzIE5vZGVUeXBlIHtcbiAgICBjb25zdHJ1Y3RvcihhdHRycywgc3BlYykge1xuICAgICAgICB0aGlzLmF0dHJzID0gYXR0cnM7XG4gICAgICAgIHRoaXMuc3BlYyA9IHNwZWMgfHwgbm9TcGVjO1xuICAgIH1cbiAgICBtYXAobWFwcGluZywgc3Bhbiwgb2Zmc2V0LCBvbGRPZmZzZXQpIHtcbiAgICAgICAgbGV0IGZyb20gPSBtYXBwaW5nLm1hcFJlc3VsdChzcGFuLmZyb20gKyBvbGRPZmZzZXQsIDEpO1xuICAgICAgICBpZiAoZnJvbS5kZWxldGVkKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIGxldCB0byA9IG1hcHBpbmcubWFwUmVzdWx0KHNwYW4udG8gKyBvbGRPZmZzZXQsIC0xKTtcbiAgICAgICAgaWYgKHRvLmRlbGV0ZWQgfHwgdG8ucG9zIDw9IGZyb20ucG9zKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIHJldHVybiBuZXcgRGVjb3JhdGlvbihmcm9tLnBvcyAtIG9mZnNldCwgdG8ucG9zIC0gb2Zmc2V0LCB0aGlzKTtcbiAgICB9XG4gICAgdmFsaWQobm9kZSwgc3Bhbikge1xuICAgICAgICBsZXQgeyBpbmRleCwgb2Zmc2V0IH0gPSBub2RlLmNvbnRlbnQuZmluZEluZGV4KHNwYW4uZnJvbSksIGNoaWxkO1xuICAgICAgICByZXR1cm4gb2Zmc2V0ID09IHNwYW4uZnJvbSAmJiAhKGNoaWxkID0gbm9kZS5jaGlsZChpbmRleCkpLmlzVGV4dCAmJiBvZmZzZXQgKyBjaGlsZC5ub2RlU2l6ZSA9PSBzcGFuLnRvO1xuICAgIH1cbiAgICBlcShvdGhlcikge1xuICAgICAgICByZXR1cm4gdGhpcyA9PSBvdGhlciB8fFxuICAgICAgICAgICAgKG90aGVyIGluc3RhbmNlb2YgTm9kZVR5cGUgJiYgY29tcGFyZU9ianModGhpcy5hdHRycywgb3RoZXIuYXR0cnMpICYmXG4gICAgICAgICAgICAgICAgY29tcGFyZU9ianModGhpcy5zcGVjLCBvdGhlci5zcGVjKSk7XG4gICAgfVxuICAgIGRlc3Ryb3koKSB7IH1cbn1cbi8qKlxuRGVjb3JhdGlvbiBvYmplY3RzIGNhbiBiZSBwcm92aWRlZCB0byB0aGUgdmlldyB0aHJvdWdoIHRoZVxuW2BkZWNvcmF0aW9uc2AgcHJvcF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3ZpZXcuRWRpdG9yUHJvcHMuZGVjb3JhdGlvbnMpLiBUaGV5IGNvbWUgaW5cbnNldmVyYWwgdmFyaWFudHNcdTIwMTRzZWUgdGhlIHN0YXRpYyBtZW1iZXJzIG9mIHRoaXMgY2xhc3MgZm9yIGRldGFpbHMuXG4qL1xuY2xhc3MgRGVjb3JhdGlvbiB7XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAvKipcbiAgICBUaGUgc3RhcnQgcG9zaXRpb24gb2YgdGhlIGRlY29yYXRpb24uXG4gICAgKi9cbiAgICBmcm9tLCBcbiAgICAvKipcbiAgICBUaGUgZW5kIHBvc2l0aW9uLiBXaWxsIGJlIHRoZSBzYW1lIGFzIGBmcm9tYCBmb3IgW3dpZGdldFxuICAgIGRlY29yYXRpb25zXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jdmlldy5EZWNvcmF0aW9uXndpZGdldCkuXG4gICAgKi9cbiAgICB0bywgXG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICB0eXBlKSB7XG4gICAgICAgIHRoaXMuZnJvbSA9IGZyb207XG4gICAgICAgIHRoaXMudG8gPSB0bztcbiAgICAgICAgdGhpcy50eXBlID0gdHlwZTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBjb3B5KGZyb20sIHRvKSB7XG4gICAgICAgIHJldHVybiBuZXcgRGVjb3JhdGlvbihmcm9tLCB0bywgdGhpcy50eXBlKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBlcShvdGhlciwgb2Zmc2V0ID0gMCkge1xuICAgICAgICByZXR1cm4gdGhpcy50eXBlLmVxKG90aGVyLnR5cGUpICYmIHRoaXMuZnJvbSArIG9mZnNldCA9PSBvdGhlci5mcm9tICYmIHRoaXMudG8gKyBvZmZzZXQgPT0gb3RoZXIudG87XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgbWFwKG1hcHBpbmcsIG9mZnNldCwgb2xkT2Zmc2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUubWFwKG1hcHBpbmcsIHRoaXMsIG9mZnNldCwgb2xkT2Zmc2V0KTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ3JlYXRlcyBhIHdpZGdldCBkZWNvcmF0aW9uLCB3aGljaCBpcyBhIERPTSBub2RlIHRoYXQncyBzaG93biBpblxuICAgIHRoZSBkb2N1bWVudCBhdCB0aGUgZ2l2ZW4gcG9zaXRpb24uIEl0IGlzIHJlY29tbWVuZGVkIHRoYXQgeW91XG4gICAgZGVsYXkgcmVuZGVyaW5nIHRoZSB3aWRnZXQgYnkgcGFzc2luZyBhIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZVxuICAgIGNhbGxlZCB3aGVuIHRoZSB3aWRnZXQgaXMgYWN0dWFsbHkgZHJhd24gaW4gYSB2aWV3LCBidXQgeW91IGNhblxuICAgIGFsc28gZGlyZWN0bHkgcGFzcyBhIERPTSBub2RlLiBgZ2V0UG9zYCBjYW4gYmUgdXNlZCB0byBmaW5kIHRoZVxuICAgIHdpZGdldCdzIGN1cnJlbnQgZG9jdW1lbnQgcG9zaXRpb24uXG4gICAgKi9cbiAgICBzdGF0aWMgd2lkZ2V0KHBvcywgdG9ET00sIHNwZWMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBEZWNvcmF0aW9uKHBvcywgcG9zLCBuZXcgV2lkZ2V0VHlwZSh0b0RPTSwgc3BlYykpO1xuICAgIH1cbiAgICAvKipcbiAgICBDcmVhdGVzIGFuIGlubGluZSBkZWNvcmF0aW9uLCB3aGljaCBhZGRzIHRoZSBnaXZlbiBhdHRyaWJ1dGVzIHRvXG4gICAgZWFjaCBpbmxpbmUgbm9kZSBiZXR3ZWVuIGBmcm9tYCBhbmQgYHRvYC5cbiAgICAqL1xuICAgIHN0YXRpYyBpbmxpbmUoZnJvbSwgdG8sIGF0dHJzLCBzcGVjKSB7XG4gICAgICAgIHJldHVybiBuZXcgRGVjb3JhdGlvbihmcm9tLCB0bywgbmV3IElubGluZVR5cGUoYXR0cnMsIHNwZWMpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQ3JlYXRlcyBhIG5vZGUgZGVjb3JhdGlvbi4gYGZyb21gIGFuZCBgdG9gIHNob3VsZCBwb2ludCBwcmVjaXNlbHlcbiAgICBiZWZvcmUgYW5kIGFmdGVyIGEgbm9kZSBpbiB0aGUgZG9jdW1lbnQuIFRoYXQgbm9kZSwgYW5kIG9ubHkgdGhhdFxuICAgIG5vZGUsIHdpbGwgcmVjZWl2ZSB0aGUgZ2l2ZW4gYXR0cmlidXRlcy5cbiAgICAqL1xuICAgIHN0YXRpYyBub2RlKGZyb20sIHRvLCBhdHRycywgc3BlYykge1xuICAgICAgICByZXR1cm4gbmV3IERlY29yYXRpb24oZnJvbSwgdG8sIG5ldyBOb2RlVHlwZShhdHRycywgc3BlYykpO1xuICAgIH1cbiAgICAvKipcbiAgICBUaGUgc3BlYyBwcm92aWRlZCB3aGVuIGNyZWF0aW5nIHRoaXMgZGVjb3JhdGlvbi4gQ2FuIGJlIHVzZWZ1bFxuICAgIGlmIHlvdSd2ZSBzdG9yZWQgZXh0cmEgaW5mb3JtYXRpb24gaW4gdGhhdCBvYmplY3QuXG4gICAgKi9cbiAgICBnZXQgc3BlYygpIHsgcmV0dXJuIHRoaXMudHlwZS5zcGVjOyB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBnZXQgaW5saW5lKCkgeyByZXR1cm4gdGhpcy50eXBlIGluc3RhbmNlb2YgSW5saW5lVHlwZTsgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgZ2V0IHdpZGdldCgpIHsgcmV0dXJuIHRoaXMudHlwZSBpbnN0YW5jZW9mIFdpZGdldFR5cGU7IH1cbn1cbmNvbnN0IG5vbmUgPSBbXSwgbm9TcGVjID0ge307XG4vKipcbkEgY29sbGVjdGlvbiBvZiBbZGVjb3JhdGlvbnNdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyN2aWV3LkRlY29yYXRpb24pLCBvcmdhbml6ZWQgaW4gc3VjaFxuYSB3YXkgdGhhdCB0aGUgZHJhd2luZyBhbGdvcml0aG0gY2FuIGVmZmljaWVudGx5IHVzZSBhbmQgY29tcGFyZVxudGhlbS4gVGhpcyBpcyBhIHBlcnNpc3RlbnQgZGF0YSBzdHJ1Y3R1cmVcdTIwMTRpdCBpcyBub3QgbW9kaWZpZWQsXG51cGRhdGVzIGNyZWF0ZSBhIG5ldyB2YWx1ZS5cbiovXG5jbGFzcyBEZWNvcmF0aW9uU2V0IHtcbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGxvY2FsLCBjaGlsZHJlbikge1xuICAgICAgICB0aGlzLmxvY2FsID0gbG9jYWwubGVuZ3RoID8gbG9jYWwgOiBub25lO1xuICAgICAgICB0aGlzLmNoaWxkcmVuID0gY2hpbGRyZW4ubGVuZ3RoID8gY2hpbGRyZW4gOiBub25lO1xuICAgIH1cbiAgICAvKipcbiAgICBDcmVhdGUgYSBzZXQgb2YgZGVjb3JhdGlvbnMsIHVzaW5nIHRoZSBzdHJ1Y3R1cmUgb2YgdGhlIGdpdmVuXG4gICAgZG9jdW1lbnQuIFRoaXMgd2lsbCBjb25zdW1lIChtb2RpZnkpIHRoZSBgZGVjb3JhdGlvbnNgIGFycmF5LCBzb1xuICAgIHlvdSBtdXN0IG1ha2UgYSBjb3B5IGlmIHlvdSB3YW50IG5lZWQgdG8gcHJlc2VydmUgdGhhdC5cbiAgICAqL1xuICAgIHN0YXRpYyBjcmVhdGUoZG9jLCBkZWNvcmF0aW9ucykge1xuICAgICAgICByZXR1cm4gZGVjb3JhdGlvbnMubGVuZ3RoID8gYnVpbGRUcmVlKGRlY29yYXRpb25zLCBkb2MsIDAsIG5vU3BlYykgOiBlbXB0eTtcbiAgICB9XG4gICAgLyoqXG4gICAgRmluZCBhbGwgZGVjb3JhdGlvbnMgaW4gdGhpcyBzZXQgd2hpY2ggdG91Y2ggdGhlIGdpdmVuIHJhbmdlXG4gICAgKGluY2x1ZGluZyBkZWNvcmF0aW9ucyB0aGF0IHN0YXJ0IG9yIGVuZCBkaXJlY3RseSBhdCB0aGVcbiAgICBib3VuZGFyaWVzKSBhbmQgbWF0Y2ggdGhlIGdpdmVuIHByZWRpY2F0ZSBvbiB0aGVpciBzcGVjLiBXaGVuXG4gICAgYHN0YXJ0YCBhbmQgYGVuZGAgYXJlIG9taXR0ZWQsIGFsbCBkZWNvcmF0aW9ucyBpbiB0aGUgc2V0IGFyZVxuICAgIGNvbnNpZGVyZWQuIFdoZW4gYHByZWRpY2F0ZWAgaXNuJ3QgZ2l2ZW4sIGFsbCBkZWNvcmF0aW9ucyBhcmVcbiAgICBhc3N1bWVkIHRvIG1hdGNoLlxuICAgICovXG4gICAgZmluZChzdGFydCwgZW5kLCBwcmVkaWNhdGUpIHtcbiAgICAgICAgbGV0IHJlc3VsdCA9IFtdO1xuICAgICAgICB0aGlzLmZpbmRJbm5lcihzdGFydCA9PSBudWxsID8gMCA6IHN0YXJ0LCBlbmQgPT0gbnVsbCA/IDFlOSA6IGVuZCwgcmVzdWx0LCAwLCBwcmVkaWNhdGUpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICBmaW5kSW5uZXIoc3RhcnQsIGVuZCwgcmVzdWx0LCBvZmZzZXQsIHByZWRpY2F0ZSkge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubG9jYWwubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBzcGFuID0gdGhpcy5sb2NhbFtpXTtcbiAgICAgICAgICAgIGlmIChzcGFuLmZyb20gPD0gZW5kICYmIHNwYW4udG8gPj0gc3RhcnQgJiYgKCFwcmVkaWNhdGUgfHwgcHJlZGljYXRlKHNwYW4uc3BlYykpKVxuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKHNwYW4uY29weShzcGFuLmZyb20gKyBvZmZzZXQsIHNwYW4udG8gKyBvZmZzZXQpKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuY2hpbGRyZW4ubGVuZ3RoOyBpICs9IDMpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmNoaWxkcmVuW2ldIDwgZW5kICYmIHRoaXMuY2hpbGRyZW5baSArIDFdID4gc3RhcnQpIHtcbiAgICAgICAgICAgICAgICBsZXQgY2hpbGRPZmYgPSB0aGlzLmNoaWxkcmVuW2ldICsgMTtcbiAgICAgICAgICAgICAgICB0aGlzLmNoaWxkcmVuW2kgKyAyXS5maW5kSW5uZXIoc3RhcnQgLSBjaGlsZE9mZiwgZW5kIC0gY2hpbGRPZmYsIHJlc3VsdCwgb2Zmc2V0ICsgY2hpbGRPZmYsIHByZWRpY2F0ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgTWFwIHRoZSBzZXQgb2YgZGVjb3JhdGlvbnMgaW4gcmVzcG9uc2UgdG8gYSBjaGFuZ2UgaW4gdGhlXG4gICAgZG9jdW1lbnQuXG4gICAgKi9cbiAgICBtYXAobWFwcGluZywgZG9jLCBvcHRpb25zKSB7XG4gICAgICAgIGlmICh0aGlzID09IGVtcHR5IHx8IG1hcHBpbmcubWFwcy5sZW5ndGggPT0gMClcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICByZXR1cm4gdGhpcy5tYXBJbm5lcihtYXBwaW5nLCBkb2MsIDAsIDAsIG9wdGlvbnMgfHwgbm9TcGVjKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBtYXBJbm5lcihtYXBwaW5nLCBub2RlLCBvZmZzZXQsIG9sZE9mZnNldCwgb3B0aW9ucykge1xuICAgICAgICBsZXQgbmV3TG9jYWw7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5sb2NhbC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IG1hcHBlZCA9IHRoaXMubG9jYWxbaV0ubWFwKG1hcHBpbmcsIG9mZnNldCwgb2xkT2Zmc2V0KTtcbiAgICAgICAgICAgIGlmIChtYXBwZWQgJiYgbWFwcGVkLnR5cGUudmFsaWQobm9kZSwgbWFwcGVkKSlcbiAgICAgICAgICAgICAgICAobmV3TG9jYWwgfHwgKG5ld0xvY2FsID0gW10pKS5wdXNoKG1hcHBlZCk7XG4gICAgICAgICAgICBlbHNlIGlmIChvcHRpb25zLm9uUmVtb3ZlKVxuICAgICAgICAgICAgICAgIG9wdGlvbnMub25SZW1vdmUodGhpcy5sb2NhbFtpXS5zcGVjKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5jaGlsZHJlbi5sZW5ndGgpXG4gICAgICAgICAgICByZXR1cm4gbWFwQ2hpbGRyZW4odGhpcy5jaGlsZHJlbiwgbmV3TG9jYWwgfHwgW10sIG1hcHBpbmcsIG5vZGUsIG9mZnNldCwgb2xkT2Zmc2V0LCBvcHRpb25zKTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgcmV0dXJuIG5ld0xvY2FsID8gbmV3IERlY29yYXRpb25TZXQobmV3TG9jYWwuc29ydChieVBvcyksIG5vbmUpIDogZW1wdHk7XG4gICAgfVxuICAgIC8qKlxuICAgIEFkZCB0aGUgZ2l2ZW4gYXJyYXkgb2YgZGVjb3JhdGlvbnMgdG8gdGhlIG9uZXMgaW4gdGhlIHNldCxcbiAgICBwcm9kdWNpbmcgYSBuZXcgc2V0LiBDb25zdW1lcyB0aGUgYGRlY29yYXRpb25zYCBhcnJheS4gTmVlZHNcbiAgICBhY2Nlc3MgdG8gdGhlIGN1cnJlbnQgZG9jdW1lbnQgdG8gY3JlYXRlIHRoZSBhcHByb3ByaWF0ZSB0cmVlXG4gICAgc3RydWN0dXJlLlxuICAgICovXG4gICAgYWRkKGRvYywgZGVjb3JhdGlvbnMpIHtcbiAgICAgICAgaWYgKCFkZWNvcmF0aW9ucy5sZW5ndGgpXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgaWYgKHRoaXMgPT0gZW1wdHkpXG4gICAgICAgICAgICByZXR1cm4gRGVjb3JhdGlvblNldC5jcmVhdGUoZG9jLCBkZWNvcmF0aW9ucyk7XG4gICAgICAgIHJldHVybiB0aGlzLmFkZElubmVyKGRvYywgZGVjb3JhdGlvbnMsIDApO1xuICAgIH1cbiAgICBhZGRJbm5lcihkb2MsIGRlY29yYXRpb25zLCBvZmZzZXQpIHtcbiAgICAgICAgbGV0IGNoaWxkcmVuLCBjaGlsZEluZGV4ID0gMDtcbiAgICAgICAgZG9jLmZvckVhY2goKGNoaWxkTm9kZSwgY2hpbGRPZmZzZXQpID0+IHtcbiAgICAgICAgICAgIGxldCBiYXNlT2Zmc2V0ID0gY2hpbGRPZmZzZXQgKyBvZmZzZXQsIGZvdW5kO1xuICAgICAgICAgICAgaWYgKCEoZm91bmQgPSB0YWtlU3BhbnNGb3JOb2RlKGRlY29yYXRpb25zLCBjaGlsZE5vZGUsIGJhc2VPZmZzZXQpKSlcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICBpZiAoIWNoaWxkcmVuKVxuICAgICAgICAgICAgICAgIGNoaWxkcmVuID0gdGhpcy5jaGlsZHJlbi5zbGljZSgpO1xuICAgICAgICAgICAgd2hpbGUgKGNoaWxkSW5kZXggPCBjaGlsZHJlbi5sZW5ndGggJiYgY2hpbGRyZW5bY2hpbGRJbmRleF0gPCBjaGlsZE9mZnNldClcbiAgICAgICAgICAgICAgICBjaGlsZEluZGV4ICs9IDM7XG4gICAgICAgICAgICBpZiAoY2hpbGRyZW5bY2hpbGRJbmRleF0gPT0gY2hpbGRPZmZzZXQpXG4gICAgICAgICAgICAgICAgY2hpbGRyZW5bY2hpbGRJbmRleCArIDJdID0gY2hpbGRyZW5bY2hpbGRJbmRleCArIDJdLmFkZElubmVyKGNoaWxkTm9kZSwgZm91bmQsIGJhc2VPZmZzZXQgKyAxKTtcbiAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICBjaGlsZHJlbi5zcGxpY2UoY2hpbGRJbmRleCwgMCwgY2hpbGRPZmZzZXQsIGNoaWxkT2Zmc2V0ICsgY2hpbGROb2RlLm5vZGVTaXplLCBidWlsZFRyZWUoZm91bmQsIGNoaWxkTm9kZSwgYmFzZU9mZnNldCArIDEsIG5vU3BlYykpO1xuICAgICAgICAgICAgY2hpbGRJbmRleCArPSAzO1xuICAgICAgICB9KTtcbiAgICAgICAgbGV0IGxvY2FsID0gbW92ZVNwYW5zKGNoaWxkSW5kZXggPyB3aXRob3V0TnVsbHMoZGVjb3JhdGlvbnMpIDogZGVjb3JhdGlvbnMsIC1vZmZzZXQpO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxvY2FsLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgaWYgKCFsb2NhbFtpXS50eXBlLnZhbGlkKGRvYywgbG9jYWxbaV0pKVxuICAgICAgICAgICAgICAgIGxvY2FsLnNwbGljZShpLS0sIDEpO1xuICAgICAgICByZXR1cm4gbmV3IERlY29yYXRpb25TZXQobG9jYWwubGVuZ3RoID8gdGhpcy5sb2NhbC5jb25jYXQobG9jYWwpLnNvcnQoYnlQb3MpIDogdGhpcy5sb2NhbCwgY2hpbGRyZW4gfHwgdGhpcy5jaGlsZHJlbik7XG4gICAgfVxuICAgIC8qKlxuICAgIENyZWF0ZSBhIG5ldyBzZXQgdGhhdCBjb250YWlucyB0aGUgZGVjb3JhdGlvbnMgaW4gdGhpcyBzZXQsIG1pbnVzXG4gICAgdGhlIG9uZXMgaW4gdGhlIGdpdmVuIGFycmF5LlxuICAgICovXG4gICAgcmVtb3ZlKGRlY29yYXRpb25zKSB7XG4gICAgICAgIGlmIChkZWNvcmF0aW9ucy5sZW5ndGggPT0gMCB8fCB0aGlzID09IGVtcHR5KVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIHJldHVybiB0aGlzLnJlbW92ZUlubmVyKGRlY29yYXRpb25zLCAwKTtcbiAgICB9XG4gICAgcmVtb3ZlSW5uZXIoZGVjb3JhdGlvbnMsIG9mZnNldCkge1xuICAgICAgICBsZXQgY2hpbGRyZW4gPSB0aGlzLmNoaWxkcmVuLCBsb2NhbCA9IHRoaXMubG9jYWw7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpICs9IDMpIHtcbiAgICAgICAgICAgIGxldCBmb3VuZDtcbiAgICAgICAgICAgIGxldCBmcm9tID0gY2hpbGRyZW5baV0gKyBvZmZzZXQsIHRvID0gY2hpbGRyZW5baSArIDFdICsgb2Zmc2V0O1xuICAgICAgICAgICAgZm9yIChsZXQgaiA9IDAsIHNwYW47IGogPCBkZWNvcmF0aW9ucy5sZW5ndGg7IGorKylcbiAgICAgICAgICAgICAgICBpZiAoc3BhbiA9IGRlY29yYXRpb25zW2pdKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzcGFuLmZyb20gPiBmcm9tICYmIHNwYW4udG8gPCB0bykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVjb3JhdGlvbnNbal0gPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgKGZvdW5kIHx8IChmb3VuZCA9IFtdKSkucHVzaChzcGFuKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghZm91bmQpXG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICBpZiAoY2hpbGRyZW4gPT0gdGhpcy5jaGlsZHJlbilcbiAgICAgICAgICAgICAgICBjaGlsZHJlbiA9IHRoaXMuY2hpbGRyZW4uc2xpY2UoKTtcbiAgICAgICAgICAgIGxldCByZW1vdmVkID0gY2hpbGRyZW5baSArIDJdLnJlbW92ZUlubmVyKGZvdW5kLCBmcm9tICsgMSk7XG4gICAgICAgICAgICBpZiAocmVtb3ZlZCAhPSBlbXB0eSkge1xuICAgICAgICAgICAgICAgIGNoaWxkcmVuW2kgKyAyXSA9IHJlbW92ZWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBjaGlsZHJlbi5zcGxpY2UoaSwgMyk7XG4gICAgICAgICAgICAgICAgaSAtPSAzO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChsb2NhbC5sZW5ndGgpXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMCwgc3BhbjsgaSA8IGRlY29yYXRpb25zLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgICAgIGlmIChzcGFuID0gZGVjb3JhdGlvbnNbaV0pIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBsb2NhbC5sZW5ndGg7IGorKylcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsb2NhbFtqXS5lcShzcGFuLCBvZmZzZXQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxvY2FsID09IHRoaXMubG9jYWwpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsID0gdGhpcy5sb2NhbC5zbGljZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2FsLnNwbGljZShqLS0sIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgaWYgKGNoaWxkcmVuID09IHRoaXMuY2hpbGRyZW4gJiYgbG9jYWwgPT0gdGhpcy5sb2NhbClcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICByZXR1cm4gbG9jYWwubGVuZ3RoIHx8IGNoaWxkcmVuLmxlbmd0aCA/IG5ldyBEZWNvcmF0aW9uU2V0KGxvY2FsLCBjaGlsZHJlbikgOiBlbXB0eTtcbiAgICB9XG4gICAgZm9yQ2hpbGQob2Zmc2V0LCBub2RlKSB7XG4gICAgICAgIGlmICh0aGlzID09IGVtcHR5KVxuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIGlmIChub2RlLmlzTGVhZilcbiAgICAgICAgICAgIHJldHVybiBEZWNvcmF0aW9uU2V0LmVtcHR5O1xuICAgICAgICBsZXQgY2hpbGQsIGxvY2FsO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuY2hpbGRyZW4ubGVuZ3RoOyBpICs9IDMpXG4gICAgICAgICAgICBpZiAodGhpcy5jaGlsZHJlbltpXSA+PSBvZmZzZXQpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jaGlsZHJlbltpXSA9PSBvZmZzZXQpXG4gICAgICAgICAgICAgICAgICAgIGNoaWxkID0gdGhpcy5jaGlsZHJlbltpICsgMl07XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIGxldCBzdGFydCA9IG9mZnNldCArIDEsIGVuZCA9IHN0YXJ0ICsgbm9kZS5jb250ZW50LnNpemU7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5sb2NhbC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IGRlYyA9IHRoaXMubG9jYWxbaV07XG4gICAgICAgICAgICBpZiAoZGVjLmZyb20gPCBlbmQgJiYgZGVjLnRvID4gc3RhcnQgJiYgKGRlYy50eXBlIGluc3RhbmNlb2YgSW5saW5lVHlwZSkpIHtcbiAgICAgICAgICAgICAgICBsZXQgZnJvbSA9IE1hdGgubWF4KHN0YXJ0LCBkZWMuZnJvbSkgLSBzdGFydCwgdG8gPSBNYXRoLm1pbihlbmQsIGRlYy50bykgLSBzdGFydDtcbiAgICAgICAgICAgICAgICBpZiAoZnJvbSA8IHRvKVxuICAgICAgICAgICAgICAgICAgICAobG9jYWwgfHwgKGxvY2FsID0gW10pKS5wdXNoKGRlYy5jb3B5KGZyb20sIHRvKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxvY2FsKSB7XG4gICAgICAgICAgICBsZXQgbG9jYWxTZXQgPSBuZXcgRGVjb3JhdGlvblNldChsb2NhbC5zb3J0KGJ5UG9zKSwgbm9uZSk7XG4gICAgICAgICAgICByZXR1cm4gY2hpbGQgPyBuZXcgRGVjb3JhdGlvbkdyb3VwKFtsb2NhbFNldCwgY2hpbGRdKSA6IGxvY2FsU2V0O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjaGlsZCB8fCBlbXB0eTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBlcShvdGhlcikge1xuICAgICAgICBpZiAodGhpcyA9PSBvdGhlcilcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICBpZiAoIShvdGhlciBpbnN0YW5jZW9mIERlY29yYXRpb25TZXQpIHx8XG4gICAgICAgICAgICB0aGlzLmxvY2FsLmxlbmd0aCAhPSBvdGhlci5sb2NhbC5sZW5ndGggfHxcbiAgICAgICAgICAgIHRoaXMuY2hpbGRyZW4ubGVuZ3RoICE9IG90aGVyLmNoaWxkcmVuLmxlbmd0aClcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmxvY2FsLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgaWYgKCF0aGlzLmxvY2FsW2ldLmVxKG90aGVyLmxvY2FsW2ldKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5jaGlsZHJlbi5sZW5ndGg7IGkgKz0gMylcbiAgICAgICAgICAgIGlmICh0aGlzLmNoaWxkcmVuW2ldICE9IG90aGVyLmNoaWxkcmVuW2ldIHx8XG4gICAgICAgICAgICAgICAgdGhpcy5jaGlsZHJlbltpICsgMV0gIT0gb3RoZXIuY2hpbGRyZW5baSArIDFdIHx8XG4gICAgICAgICAgICAgICAgIXRoaXMuY2hpbGRyZW5baSArIDJdLmVxKG90aGVyLmNoaWxkcmVuW2kgKyAyXSkpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBsb2NhbHMobm9kZSkge1xuICAgICAgICByZXR1cm4gcmVtb3ZlT3ZlcmxhcCh0aGlzLmxvY2Fsc0lubmVyKG5vZGUpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBsb2NhbHNJbm5lcihub2RlKSB7XG4gICAgICAgIGlmICh0aGlzID09IGVtcHR5KVxuICAgICAgICAgICAgcmV0dXJuIG5vbmU7XG4gICAgICAgIGlmIChub2RlLmlubGluZUNvbnRlbnQgfHwgIXRoaXMubG9jYWwuc29tZShJbmxpbmVUeXBlLmlzKSlcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxvY2FsO1xuICAgICAgICBsZXQgcmVzdWx0ID0gW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5sb2NhbC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKCEodGhpcy5sb2NhbFtpXS50eXBlIGluc3RhbmNlb2YgSW5saW5lVHlwZSkpXG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2godGhpcy5sb2NhbFtpXSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgZm9yRWFjaFNldChmKSB7IGYodGhpcyk7IH1cbn1cbi8qKlxuVGhlIGVtcHR5IHNldCBvZiBkZWNvcmF0aW9ucy5cbiovXG5EZWNvcmF0aW9uU2V0LmVtcHR5ID0gbmV3IERlY29yYXRpb25TZXQoW10sIFtdKTtcbi8qKlxuQGludGVybmFsXG4qL1xuRGVjb3JhdGlvblNldC5yZW1vdmVPdmVybGFwID0gcmVtb3ZlT3ZlcmxhcDtcbmNvbnN0IGVtcHR5ID0gRGVjb3JhdGlvblNldC5lbXB0eTtcbi8vIEFuIGFic3RyYWN0aW9uIHRoYXQgYWxsb3dzIHRoZSBjb2RlIGRlYWxpbmcgd2l0aCBkZWNvcmF0aW9ucyB0b1xuLy8gdHJlYXQgbXVsdGlwbGUgRGVjb3JhdGlvblNldCBvYmplY3RzIGFzIGlmIGl0IHdlcmUgYSBzaW5nbGUgb2JqZWN0XG4vLyB3aXRoIChhIHN1YnNldCBvZikgdGhlIHNhbWUgaW50ZXJmYWNlLlxuY2xhc3MgRGVjb3JhdGlvbkdyb3VwIHtcbiAgICBjb25zdHJ1Y3RvcihtZW1iZXJzKSB7XG4gICAgICAgIHRoaXMubWVtYmVycyA9IG1lbWJlcnM7XG4gICAgfVxuICAgIG1hcChtYXBwaW5nLCBkb2MpIHtcbiAgICAgICAgY29uc3QgbWFwcGVkRGVjb3MgPSB0aGlzLm1lbWJlcnMubWFwKG1lbWJlciA9PiBtZW1iZXIubWFwKG1hcHBpbmcsIGRvYywgbm9TcGVjKSk7XG4gICAgICAgIHJldHVybiBEZWNvcmF0aW9uR3JvdXAuZnJvbShtYXBwZWREZWNvcyk7XG4gICAgfVxuICAgIGZvckNoaWxkKG9mZnNldCwgY2hpbGQpIHtcbiAgICAgICAgaWYgKGNoaWxkLmlzTGVhZilcbiAgICAgICAgICAgIHJldHVybiBEZWNvcmF0aW9uU2V0LmVtcHR5O1xuICAgICAgICBsZXQgZm91bmQgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm1lbWJlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCByZXN1bHQgPSB0aGlzLm1lbWJlcnNbaV0uZm9yQ2hpbGQob2Zmc2V0LCBjaGlsZCk7XG4gICAgICAgICAgICBpZiAocmVzdWx0ID09IGVtcHR5KVxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIERlY29yYXRpb25Hcm91cClcbiAgICAgICAgICAgICAgICBmb3VuZCA9IGZvdW5kLmNvbmNhdChyZXN1bHQubWVtYmVycyk7XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgZm91bmQucHVzaChyZXN1bHQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBEZWNvcmF0aW9uR3JvdXAuZnJvbShmb3VuZCk7XG4gICAgfVxuICAgIGVxKG90aGVyKSB7XG4gICAgICAgIGlmICghKG90aGVyIGluc3RhbmNlb2YgRGVjb3JhdGlvbkdyb3VwKSB8fFxuICAgICAgICAgICAgb3RoZXIubWVtYmVycy5sZW5ndGggIT0gdGhpcy5tZW1iZXJzLmxlbmd0aClcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm1lbWJlcnMubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICBpZiAoIXRoaXMubWVtYmVyc1tpXS5lcShvdGhlci5tZW1iZXJzW2ldKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBsb2NhbHMobm9kZSkge1xuICAgICAgICBsZXQgcmVzdWx0LCBzb3J0ZWQgPSB0cnVlO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubWVtYmVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IGxvY2FscyA9IHRoaXMubWVtYmVyc1tpXS5sb2NhbHNJbm5lcihub2RlKTtcbiAgICAgICAgICAgIGlmICghbG9jYWxzLmxlbmd0aClcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIGlmICghcmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gbG9jYWxzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKHNvcnRlZCkge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHQuc2xpY2UoKTtcbiAgICAgICAgICAgICAgICAgICAgc29ydGVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbG9jYWxzLmxlbmd0aDsgaisrKVxuICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaChsb2NhbHNbal0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQgPyByZW1vdmVPdmVybGFwKHNvcnRlZCA/IHJlc3VsdCA6IHJlc3VsdC5zb3J0KGJ5UG9zKSkgOiBub25lO1xuICAgIH1cbiAgICAvLyBDcmVhdGUgYSBncm91cCBmb3IgdGhlIGdpdmVuIGFycmF5IG9mIGRlY29yYXRpb24gc2V0cywgb3IgcmV0dXJuXG4gICAgLy8gYSBzaW5nbGUgc2V0IHdoZW4gcG9zc2libGUuXG4gICAgc3RhdGljIGZyb20obWVtYmVycykge1xuICAgICAgICBzd2l0Y2ggKG1lbWJlcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICBjYXNlIDA6IHJldHVybiBlbXB0eTtcbiAgICAgICAgICAgIGNhc2UgMTogcmV0dXJuIG1lbWJlcnNbMF07XG4gICAgICAgICAgICBkZWZhdWx0OiByZXR1cm4gbmV3IERlY29yYXRpb25Hcm91cChtZW1iZXJzLmV2ZXJ5KG0gPT4gbSBpbnN0YW5jZW9mIERlY29yYXRpb25TZXQpID8gbWVtYmVycyA6XG4gICAgICAgICAgICAgICAgbWVtYmVycy5yZWR1Y2UoKHIsIG0pID0+IHIuY29uY2F0KG0gaW5zdGFuY2VvZiBEZWNvcmF0aW9uU2V0ID8gbSA6IG0ubWVtYmVycyksIFtdKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZm9yRWFjaFNldChmKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5tZW1iZXJzLmxlbmd0aDsgaSsrKVxuICAgICAgICAgICAgdGhpcy5tZW1iZXJzW2ldLmZvckVhY2hTZXQoZik7XG4gICAgfVxufVxuZnVuY3Rpb24gbWFwQ2hpbGRyZW4ob2xkQ2hpbGRyZW4sIG5ld0xvY2FsLCBtYXBwaW5nLCBub2RlLCBvZmZzZXQsIG9sZE9mZnNldCwgb3B0aW9ucykge1xuICAgIGxldCBjaGlsZHJlbiA9IG9sZENoaWxkcmVuLnNsaWNlKCk7XG4gICAgLy8gTWFyayB0aGUgY2hpbGRyZW4gdGhhdCBhcmUgZGlyZWN0bHkgdG91Y2hlZCBieSBjaGFuZ2VzLCBhbmRcbiAgICAvLyBtb3ZlIHRob3NlIHRoYXQgYXJlIGFmdGVyIHRoZSBjaGFuZ2VzLlxuICAgIGZvciAobGV0IGkgPSAwLCBiYXNlT2Zmc2V0ID0gb2xkT2Zmc2V0OyBpIDwgbWFwcGluZy5tYXBzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxldCBtb3ZlZCA9IDA7XG4gICAgICAgIG1hcHBpbmcubWFwc1tpXS5mb3JFYWNoKChvbGRTdGFydCwgb2xkRW5kLCBuZXdTdGFydCwgbmV3RW5kKSA9PiB7XG4gICAgICAgICAgICBsZXQgZFNpemUgPSAobmV3RW5kIC0gbmV3U3RhcnQpIC0gKG9sZEVuZCAtIG9sZFN0YXJ0KTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpICs9IDMpIHtcbiAgICAgICAgICAgICAgICBsZXQgZW5kID0gY2hpbGRyZW5baSArIDFdO1xuICAgICAgICAgICAgICAgIGlmIChlbmQgPCAwIHx8IG9sZFN0YXJ0ID4gZW5kICsgYmFzZU9mZnNldCAtIG1vdmVkKVxuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICBsZXQgc3RhcnQgPSBjaGlsZHJlbltpXSArIGJhc2VPZmZzZXQgLSBtb3ZlZDtcbiAgICAgICAgICAgICAgICBpZiAob2xkRW5kID49IHN0YXJ0KSB7XG4gICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuW2kgKyAxXSA9IG9sZFN0YXJ0IDw9IHN0YXJ0ID8gLTIgOiAtMTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAob2xkU3RhcnQgPj0gYmFzZU9mZnNldCAmJiBkU2l6ZSkge1xuICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbltpXSArPSBkU2l6ZTtcbiAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW5baSArIDFdICs9IGRTaXplO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG1vdmVkICs9IGRTaXplO1xuICAgICAgICB9KTtcbiAgICAgICAgYmFzZU9mZnNldCA9IG1hcHBpbmcubWFwc1tpXS5tYXAoYmFzZU9mZnNldCwgLTEpO1xuICAgIH1cbiAgICAvLyBGaW5kIHRoZSBjaGlsZCBub2RlcyB0aGF0IHN0aWxsIGNvcnJlc3BvbmQgdG8gYSBzaW5nbGUgbm9kZSxcbiAgICAvLyByZWN1cnNpdmVseSBjYWxsIG1hcElubmVyIG9uIHRoZW0gYW5kIHVwZGF0ZSB0aGVpciBwb3NpdGlvbnMuXG4gICAgbGV0IG11c3RSZWJ1aWxkID0gZmFsc2U7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkgKz0gMylcbiAgICAgICAgaWYgKGNoaWxkcmVuW2kgKyAxXSA8IDApIHsgLy8gVG91Y2hlZCBub2Rlc1xuICAgICAgICAgICAgaWYgKGNoaWxkcmVuW2kgKyAxXSA9PSAtMikge1xuICAgICAgICAgICAgICAgIG11c3RSZWJ1aWxkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBjaGlsZHJlbltpICsgMV0gPSAtMTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCBmcm9tID0gbWFwcGluZy5tYXAob2xkQ2hpbGRyZW5baV0gKyBvbGRPZmZzZXQpLCBmcm9tTG9jYWwgPSBmcm9tIC0gb2Zmc2V0O1xuICAgICAgICAgICAgaWYgKGZyb21Mb2NhbCA8IDAgfHwgZnJvbUxvY2FsID49IG5vZGUuY29udGVudC5zaXplKSB7XG4gICAgICAgICAgICAgICAgbXVzdFJlYnVpbGQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gTXVzdCByZWFkIG9sZENoaWxkcmVuIGJlY2F1c2UgY2hpbGRyZW4gd2FzIHRhZ2dlZCB3aXRoIC0xXG4gICAgICAgICAgICBsZXQgdG8gPSBtYXBwaW5nLm1hcChvbGRDaGlsZHJlbltpICsgMV0gKyBvbGRPZmZzZXQsIC0xKSwgdG9Mb2NhbCA9IHRvIC0gb2Zmc2V0O1xuICAgICAgICAgICAgbGV0IHsgaW5kZXgsIG9mZnNldDogY2hpbGRPZmZzZXQgfSA9IG5vZGUuY29udGVudC5maW5kSW5kZXgoZnJvbUxvY2FsKTtcbiAgICAgICAgICAgIGxldCBjaGlsZE5vZGUgPSBub2RlLm1heWJlQ2hpbGQoaW5kZXgpO1xuICAgICAgICAgICAgaWYgKGNoaWxkTm9kZSAmJiBjaGlsZE9mZnNldCA9PSBmcm9tTG9jYWwgJiYgY2hpbGRPZmZzZXQgKyBjaGlsZE5vZGUubm9kZVNpemUgPT0gdG9Mb2NhbCkge1xuICAgICAgICAgICAgICAgIGxldCBtYXBwZWQgPSBjaGlsZHJlbltpICsgMl1cbiAgICAgICAgICAgICAgICAgICAgLm1hcElubmVyKG1hcHBpbmcsIGNoaWxkTm9kZSwgZnJvbSArIDEsIG9sZENoaWxkcmVuW2ldICsgb2xkT2Zmc2V0ICsgMSwgb3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgaWYgKG1hcHBlZCAhPSBlbXB0eSkge1xuICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbltpXSA9IGZyb21Mb2NhbDtcbiAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW5baSArIDFdID0gdG9Mb2NhbDtcbiAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW5baSArIDJdID0gbWFwcGVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW5baSArIDFdID0gLTI7XG4gICAgICAgICAgICAgICAgICAgIG11c3RSZWJ1aWxkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBtdXN0UmVidWlsZCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAvLyBSZW1haW5pbmcgY2hpbGRyZW4gbXVzdCBiZSBjb2xsZWN0ZWQgYW5kIHJlYnVpbHQgaW50byB0aGUgYXBwcm9wcmlhdGUgc3RydWN0dXJlXG4gICAgaWYgKG11c3RSZWJ1aWxkKSB7XG4gICAgICAgIGxldCBkZWNvcmF0aW9ucyA9IG1hcEFuZEdhdGhlclJlbWFpbmluZ0RlY29yYXRpb25zKGNoaWxkcmVuLCBvbGRDaGlsZHJlbiwgbmV3TG9jYWwsIG1hcHBpbmcsIG9mZnNldCwgb2xkT2Zmc2V0LCBvcHRpb25zKTtcbiAgICAgICAgbGV0IGJ1aWx0ID0gYnVpbGRUcmVlKGRlY29yYXRpb25zLCBub2RlLCAwLCBvcHRpb25zKTtcbiAgICAgICAgbmV3TG9jYWwgPSBidWlsdC5sb2NhbDtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkgKz0gMylcbiAgICAgICAgICAgIGlmIChjaGlsZHJlbltpICsgMV0gPCAwKSB7XG4gICAgICAgICAgICAgICAgY2hpbGRyZW4uc3BsaWNlKGksIDMpO1xuICAgICAgICAgICAgICAgIGkgLT0gMztcbiAgICAgICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGogPSAwOyBpIDwgYnVpbHQuY2hpbGRyZW4ubGVuZ3RoOyBpICs9IDMpIHtcbiAgICAgICAgICAgIGxldCBmcm9tID0gYnVpbHQuY2hpbGRyZW5baV07XG4gICAgICAgICAgICB3aGlsZSAoaiA8IGNoaWxkcmVuLmxlbmd0aCAmJiBjaGlsZHJlbltqXSA8IGZyb20pXG4gICAgICAgICAgICAgICAgaiArPSAzO1xuICAgICAgICAgICAgY2hpbGRyZW4uc3BsaWNlKGosIDAsIGJ1aWx0LmNoaWxkcmVuW2ldLCBidWlsdC5jaGlsZHJlbltpICsgMV0sIGJ1aWx0LmNoaWxkcmVuW2kgKyAyXSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG5ldyBEZWNvcmF0aW9uU2V0KG5ld0xvY2FsLnNvcnQoYnlQb3MpLCBjaGlsZHJlbik7XG59XG5mdW5jdGlvbiBtb3ZlU3BhbnMoc3BhbnMsIG9mZnNldCkge1xuICAgIGlmICghb2Zmc2V0IHx8ICFzcGFucy5sZW5ndGgpXG4gICAgICAgIHJldHVybiBzcGFucztcbiAgICBsZXQgcmVzdWx0ID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzcGFucy5sZW5ndGg7IGkrKykge1xuICAgICAgICBsZXQgc3BhbiA9IHNwYW5zW2ldO1xuICAgICAgICByZXN1bHQucHVzaChuZXcgRGVjb3JhdGlvbihzcGFuLmZyb20gKyBvZmZzZXQsIHNwYW4udG8gKyBvZmZzZXQsIHNwYW4udHlwZSkpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuZnVuY3Rpb24gbWFwQW5kR2F0aGVyUmVtYWluaW5nRGVjb3JhdGlvbnMoY2hpbGRyZW4sIG9sZENoaWxkcmVuLCBkZWNvcmF0aW9ucywgbWFwcGluZywgb2Zmc2V0LCBvbGRPZmZzZXQsIG9wdGlvbnMpIHtcbiAgICAvLyBHYXRoZXIgYWxsIGRlY29yYXRpb25zIGZyb20gdGhlIHJlbWFpbmluZyBtYXJrZWQgY2hpbGRyZW5cbiAgICBmdW5jdGlvbiBnYXRoZXIoc2V0LCBvbGRPZmZzZXQpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZXQubG9jYWwubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBtYXBwZWQgPSBzZXQubG9jYWxbaV0ubWFwKG1hcHBpbmcsIG9mZnNldCwgb2xkT2Zmc2V0KTtcbiAgICAgICAgICAgIGlmIChtYXBwZWQpXG4gICAgICAgICAgICAgICAgZGVjb3JhdGlvbnMucHVzaChtYXBwZWQpO1xuICAgICAgICAgICAgZWxzZSBpZiAob3B0aW9ucy5vblJlbW92ZSlcbiAgICAgICAgICAgICAgICBvcHRpb25zLm9uUmVtb3ZlKHNldC5sb2NhbFtpXS5zcGVjKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNldC5jaGlsZHJlbi5sZW5ndGg7IGkgKz0gMylcbiAgICAgICAgICAgIGdhdGhlcihzZXQuY2hpbGRyZW5baSArIDJdLCBzZXQuY2hpbGRyZW5baV0gKyBvbGRPZmZzZXQgKyAxKTtcbiAgICB9XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkgKz0gMylcbiAgICAgICAgaWYgKGNoaWxkcmVuW2kgKyAxXSA9PSAtMSlcbiAgICAgICAgICAgIGdhdGhlcihjaGlsZHJlbltpICsgMl0sIG9sZENoaWxkcmVuW2ldICsgb2xkT2Zmc2V0ICsgMSk7XG4gICAgcmV0dXJuIGRlY29yYXRpb25zO1xufVxuZnVuY3Rpb24gdGFrZVNwYW5zRm9yTm9kZShzcGFucywgbm9kZSwgb2Zmc2V0KSB7XG4gICAgaWYgKG5vZGUuaXNMZWFmKVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICBsZXQgZW5kID0gb2Zmc2V0ICsgbm9kZS5ub2RlU2l6ZSwgZm91bmQgPSBudWxsO1xuICAgIGZvciAobGV0IGkgPSAwLCBzcGFuOyBpIDwgc3BhbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKChzcGFuID0gc3BhbnNbaV0pICYmIHNwYW4uZnJvbSA+IG9mZnNldCAmJiBzcGFuLnRvIDwgZW5kKSB7XG4gICAgICAgICAgICAoZm91bmQgfHwgKGZvdW5kID0gW10pKS5wdXNoKHNwYW4pO1xuICAgICAgICAgICAgc3BhbnNbaV0gPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmb3VuZDtcbn1cbmZ1bmN0aW9uIHdpdGhvdXROdWxscyhhcnJheSkge1xuICAgIGxldCByZXN1bHQgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKVxuICAgICAgICBpZiAoYXJyYXlbaV0gIT0gbnVsbClcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKGFycmF5W2ldKTtcbiAgICByZXR1cm4gcmVzdWx0O1xufVxuLy8gQnVpbGQgdXAgYSB0cmVlIHRoYXQgY29ycmVzcG9uZHMgdG8gYSBzZXQgb2YgZGVjb3JhdGlvbnMuIGBvZmZzZXRgXG4vLyBpcyBhIGJhc2Ugb2Zmc2V0IHRoYXQgc2hvdWxkIGJlIHN1YnRyYWN0ZWQgZnJvbSB0aGUgYGZyb21gIGFuZCBgdG9gXG4vLyBwb3NpdGlvbnMgaW4gdGhlIHNwYW5zIChzbyB0aGF0IHdlIGRvbid0IGhhdmUgdG8gYWxsb2NhdGUgbmV3IHNwYW5zXG4vLyBmb3IgcmVjdXJzaXZlIGNhbGxzKS5cbmZ1bmN0aW9uIGJ1aWxkVHJlZShzcGFucywgbm9kZSwgb2Zmc2V0LCBvcHRpb25zKSB7XG4gICAgbGV0IGNoaWxkcmVuID0gW10sIGhhc051bGxzID0gZmFsc2U7XG4gICAgbm9kZS5mb3JFYWNoKChjaGlsZE5vZGUsIGxvY2FsU3RhcnQpID0+IHtcbiAgICAgICAgbGV0IGZvdW5kID0gdGFrZVNwYW5zRm9yTm9kZShzcGFucywgY2hpbGROb2RlLCBsb2NhbFN0YXJ0ICsgb2Zmc2V0KTtcbiAgICAgICAgaWYgKGZvdW5kKSB7XG4gICAgICAgICAgICBoYXNOdWxscyA9IHRydWU7XG4gICAgICAgICAgICBsZXQgc3VidHJlZSA9IGJ1aWxkVHJlZShmb3VuZCwgY2hpbGROb2RlLCBvZmZzZXQgKyBsb2NhbFN0YXJ0ICsgMSwgb3B0aW9ucyk7XG4gICAgICAgICAgICBpZiAoc3VidHJlZSAhPSBlbXB0eSlcbiAgICAgICAgICAgICAgICBjaGlsZHJlbi5wdXNoKGxvY2FsU3RhcnQsIGxvY2FsU3RhcnQgKyBjaGlsZE5vZGUubm9kZVNpemUsIHN1YnRyZWUpO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgbGV0IGxvY2FscyA9IG1vdmVTcGFucyhoYXNOdWxscyA/IHdpdGhvdXROdWxscyhzcGFucykgOiBzcGFucywgLW9mZnNldCkuc29ydChieVBvcyk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsb2NhbHMubGVuZ3RoOyBpKyspXG4gICAgICAgIGlmICghbG9jYWxzW2ldLnR5cGUudmFsaWQobm9kZSwgbG9jYWxzW2ldKSkge1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMub25SZW1vdmUpXG4gICAgICAgICAgICAgICAgb3B0aW9ucy5vblJlbW92ZShsb2NhbHNbaV0uc3BlYyk7XG4gICAgICAgICAgICBsb2NhbHMuc3BsaWNlKGktLSwgMSk7XG4gICAgICAgIH1cbiAgICByZXR1cm4gbG9jYWxzLmxlbmd0aCB8fCBjaGlsZHJlbi5sZW5ndGggPyBuZXcgRGVjb3JhdGlvblNldChsb2NhbHMsIGNoaWxkcmVuKSA6IGVtcHR5O1xufVxuLy8gVXNlZCB0byBzb3J0IGRlY29yYXRpb25zIHNvIHRoYXQgb25lcyB3aXRoIGEgbG93IHN0YXJ0IHBvc2l0aW9uXG4vLyBjb21lIGZpcnN0LCBhbmQgd2l0aGluIGEgc2V0IHdpdGggdGhlIHNhbWUgc3RhcnQgcG9zaXRpb24sIHRob3NlXG4vLyB3aXRoIGFuIHNtYWxsZXIgZW5kIHBvc2l0aW9uIGNvbWUgZmlyc3QuXG5mdW5jdGlvbiBieVBvcyhhLCBiKSB7XG4gICAgcmV0dXJuIGEuZnJvbSAtIGIuZnJvbSB8fCBhLnRvIC0gYi50bztcbn1cbi8vIFNjYW4gYSBzb3J0ZWQgYXJyYXkgb2YgZGVjb3JhdGlvbnMgZm9yIHBhcnRpYWxseSBvdmVybGFwcGluZyBzcGFucyxcbi8vIGFuZCBzcGxpdCB0aG9zZSBzbyB0aGF0IG9ubHkgZnVsbHkgb3ZlcmxhcHBpbmcgc3BhbnMgYXJlIGxlZnQgKHRvXG4vLyBtYWtlIHN1YnNlcXVlbnQgcmVuZGVyaW5nIGVhc2llcikuIFdpbGwgcmV0dXJuIHRoZSBpbnB1dCBhcnJheSBpZlxuLy8gbm8gcGFydGlhbGx5IG92ZXJsYXBwaW5nIHNwYW5zIGFyZSBmb3VuZCAodGhlIGNvbW1vbiBjYXNlKS5cbmZ1bmN0aW9uIHJlbW92ZU92ZXJsYXAoc3BhbnMpIHtcbiAgICBsZXQgd29ya2luZyA9IHNwYW5zO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgd29ya2luZy5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgbGV0IHNwYW4gPSB3b3JraW5nW2ldO1xuICAgICAgICBpZiAoc3Bhbi5mcm9tICE9IHNwYW4udG8pXG4gICAgICAgICAgICBmb3IgKGxldCBqID0gaSArIDE7IGogPCB3b3JraW5nLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgICAgICAgbGV0IG5leHQgPSB3b3JraW5nW2pdO1xuICAgICAgICAgICAgICAgIGlmIChuZXh0LmZyb20gPT0gc3Bhbi5mcm9tKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuZXh0LnRvICE9IHNwYW4udG8pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh3b3JraW5nID09IHNwYW5zKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdvcmtpbmcgPSBzcGFucy5zbGljZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gRm9sbG93ZWQgYnkgYSBwYXJ0aWFsbHkgb3ZlcmxhcHBpbmcgbGFyZ2VyIHNwYW4uIFNwbGl0IHRoYXRcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNwYW4uXG4gICAgICAgICAgICAgICAgICAgICAgICB3b3JraW5nW2pdID0gbmV4dC5jb3B5KG5leHQuZnJvbSwgc3Bhbi50byk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbnNlcnRBaGVhZCh3b3JraW5nLCBqICsgMSwgbmV4dC5jb3B5KHNwYW4udG8sIG5leHQudG8pKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuZXh0LmZyb20gPCBzcGFuLnRvKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAod29ya2luZyA9PSBzcGFucylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3b3JraW5nID0gc3BhbnMuc2xpY2UoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBlbmQgb2YgdGhpcyBvbmUgb3ZlcmxhcHMgd2l0aCBhIHN1YnNlcXVlbnQgc3Bhbi4gU3BsaXRcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRoaXMgb25lLlxuICAgICAgICAgICAgICAgICAgICAgICAgd29ya2luZ1tpXSA9IHNwYW4uY29weShzcGFuLmZyb20sIG5leHQuZnJvbSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbnNlcnRBaGVhZCh3b3JraW5nLCBqLCBzcGFuLmNvcHkobmV4dC5mcm9tLCBzcGFuLnRvKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gd29ya2luZztcbn1cbmZ1bmN0aW9uIGluc2VydEFoZWFkKGFycmF5LCBpLCBkZWNvKSB7XG4gICAgd2hpbGUgKGkgPCBhcnJheS5sZW5ndGggJiYgYnlQb3MoZGVjbywgYXJyYXlbaV0pID4gMClcbiAgICAgICAgaSsrO1xuICAgIGFycmF5LnNwbGljZShpLCAwLCBkZWNvKTtcbn1cbi8vIEdldCB0aGUgZGVjb3JhdGlvbnMgYXNzb2NpYXRlZCB3aXRoIHRoZSBjdXJyZW50IHByb3BzIG9mIGEgdmlldy5cbmZ1bmN0aW9uIHZpZXdEZWNvcmF0aW9ucyh2aWV3KSB7XG4gICAgbGV0IGZvdW5kID0gW107XG4gICAgdmlldy5zb21lUHJvcChcImRlY29yYXRpb25zXCIsIGYgPT4ge1xuICAgICAgICBsZXQgcmVzdWx0ID0gZih2aWV3LnN0YXRlKTtcbiAgICAgICAgaWYgKHJlc3VsdCAmJiByZXN1bHQgIT0gZW1wdHkpXG4gICAgICAgICAgICBmb3VuZC5wdXNoKHJlc3VsdCk7XG4gICAgfSk7XG4gICAgaWYgKHZpZXcuY3Vyc29yV3JhcHBlcilcbiAgICAgICAgZm91bmQucHVzaChEZWNvcmF0aW9uU2V0LmNyZWF0ZSh2aWV3LnN0YXRlLmRvYywgW3ZpZXcuY3Vyc29yV3JhcHBlci5kZWNvXSkpO1xuICAgIHJldHVybiBEZWNvcmF0aW9uR3JvdXAuZnJvbShmb3VuZCk7XG59XG5cbmNvbnN0IG9ic2VydmVPcHRpb25zID0ge1xuICAgIGNoaWxkTGlzdDogdHJ1ZSxcbiAgICBjaGFyYWN0ZXJEYXRhOiB0cnVlLFxuICAgIGNoYXJhY3RlckRhdGFPbGRWYWx1ZTogdHJ1ZSxcbiAgICBhdHRyaWJ1dGVzOiB0cnVlLFxuICAgIGF0dHJpYnV0ZU9sZFZhbHVlOiB0cnVlLFxuICAgIHN1YnRyZWU6IHRydWVcbn07XG4vLyBJRTExIGhhcyB2ZXJ5IGJyb2tlbiBtdXRhdGlvbiBvYnNlcnZlcnMsIHNvIHdlIGFsc28gbGlzdGVuIHRvIERPTUNoYXJhY3RlckRhdGFNb2RpZmllZFxuY29uc3QgdXNlQ2hhckRhdGEgPSBpZSAmJiBpZV92ZXJzaW9uIDw9IDExO1xuY2xhc3MgU2VsZWN0aW9uU3RhdGUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLmFuY2hvck5vZGUgPSBudWxsO1xuICAgICAgICB0aGlzLmFuY2hvck9mZnNldCA9IDA7XG4gICAgICAgIHRoaXMuZm9jdXNOb2RlID0gbnVsbDtcbiAgICAgICAgdGhpcy5mb2N1c09mZnNldCA9IDA7XG4gICAgfVxuICAgIHNldChzZWwpIHtcbiAgICAgICAgdGhpcy5hbmNob3JOb2RlID0gc2VsLmFuY2hvck5vZGU7XG4gICAgICAgIHRoaXMuYW5jaG9yT2Zmc2V0ID0gc2VsLmFuY2hvck9mZnNldDtcbiAgICAgICAgdGhpcy5mb2N1c05vZGUgPSBzZWwuZm9jdXNOb2RlO1xuICAgICAgICB0aGlzLmZvY3VzT2Zmc2V0ID0gc2VsLmZvY3VzT2Zmc2V0O1xuICAgIH1cbiAgICBjbGVhcigpIHtcbiAgICAgICAgdGhpcy5hbmNob3JOb2RlID0gdGhpcy5mb2N1c05vZGUgPSBudWxsO1xuICAgIH1cbiAgICBlcShzZWwpIHtcbiAgICAgICAgcmV0dXJuIHNlbC5hbmNob3JOb2RlID09IHRoaXMuYW5jaG9yTm9kZSAmJiBzZWwuYW5jaG9yT2Zmc2V0ID09IHRoaXMuYW5jaG9yT2Zmc2V0ICYmXG4gICAgICAgICAgICBzZWwuZm9jdXNOb2RlID09IHRoaXMuZm9jdXNOb2RlICYmIHNlbC5mb2N1c09mZnNldCA9PSB0aGlzLmZvY3VzT2Zmc2V0O1xuICAgIH1cbn1cbmNsYXNzIERPTU9ic2VydmVyIHtcbiAgICBjb25zdHJ1Y3Rvcih2aWV3LCBoYW5kbGVET01DaGFuZ2UpIHtcbiAgICAgICAgdGhpcy52aWV3ID0gdmlldztcbiAgICAgICAgdGhpcy5oYW5kbGVET01DaGFuZ2UgPSBoYW5kbGVET01DaGFuZ2U7XG4gICAgICAgIHRoaXMucXVldWUgPSBbXTtcbiAgICAgICAgdGhpcy5mbHVzaGluZ1Nvb24gPSAtMTtcbiAgICAgICAgdGhpcy5vYnNlcnZlciA9IG51bGw7XG4gICAgICAgIHRoaXMuY3VycmVudFNlbGVjdGlvbiA9IG5ldyBTZWxlY3Rpb25TdGF0ZTtcbiAgICAgICAgdGhpcy5vbkNoYXJEYXRhID0gbnVsbDtcbiAgICAgICAgdGhpcy5zdXBwcmVzc2luZ1NlbGVjdGlvblVwZGF0ZXMgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5sYXN0Q2hhbmdlZFRleHROb2RlID0gbnVsbDtcbiAgICAgICAgdGhpcy5vYnNlcnZlciA9IHdpbmRvdy5NdXRhdGlvbk9ic2VydmVyICYmXG4gICAgICAgICAgICBuZXcgd2luZG93Lk11dGF0aW9uT2JzZXJ2ZXIobXV0YXRpb25zID0+IHtcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG11dGF0aW9ucy5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5xdWV1ZS5wdXNoKG11dGF0aW9uc1tpXSk7XG4gICAgICAgICAgICAgICAgLy8gSUUxMSB3aWxsIHNvbWV0aW1lcyAob24gYmFja3NwYWNpbmcgb3V0IGEgc2luZ2xlIGNoYXJhY3RlclxuICAgICAgICAgICAgICAgIC8vIHRleHQgbm9kZSBhZnRlciBhIEJSIG5vZGUpIGNhbGwgdGhlIG9ic2VydmVyIGNhbGxiYWNrXG4gICAgICAgICAgICAgICAgLy8gYmVmb3JlIGFjdHVhbGx5IHVwZGF0aW5nIHRoZSBET00sIHdoaWNoIHdpbGwgY2F1c2VcbiAgICAgICAgICAgICAgICAvLyBQcm9zZU1pcnJvciB0byBtaXNzIHRoZSBjaGFuZ2UgKHNlZSAjOTMwKVxuICAgICAgICAgICAgICAgIGlmIChpZSAmJiBpZV92ZXJzaW9uIDw9IDExICYmIG11dGF0aW9ucy5zb21lKG0gPT4gbS50eXBlID09IFwiY2hpbGRMaXN0XCIgJiYgbS5yZW1vdmVkTm9kZXMubGVuZ3RoIHx8XG4gICAgICAgICAgICAgICAgICAgIG0udHlwZSA9PSBcImNoYXJhY3RlckRhdGFcIiAmJiBtLm9sZFZhbHVlLmxlbmd0aCA+IG0udGFyZ2V0Lm5vZGVWYWx1ZS5sZW5ndGgpKVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZsdXNoU29vbigpO1xuICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mbHVzaCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIGlmICh1c2VDaGFyRGF0YSkge1xuICAgICAgICAgICAgdGhpcy5vbkNoYXJEYXRhID0gZSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5xdWV1ZS5wdXNoKHsgdGFyZ2V0OiBlLnRhcmdldCwgdHlwZTogXCJjaGFyYWN0ZXJEYXRhXCIsIG9sZFZhbHVlOiBlLnByZXZWYWx1ZSB9KTtcbiAgICAgICAgICAgICAgICB0aGlzLmZsdXNoU29vbigpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9uU2VsZWN0aW9uQ2hhbmdlID0gdGhpcy5vblNlbGVjdGlvbkNoYW5nZS5iaW5kKHRoaXMpO1xuICAgIH1cbiAgICBmbHVzaFNvb24oKSB7XG4gICAgICAgIGlmICh0aGlzLmZsdXNoaW5nU29vbiA8IDApXG4gICAgICAgICAgICB0aGlzLmZsdXNoaW5nU29vbiA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHsgdGhpcy5mbHVzaGluZ1Nvb24gPSAtMTsgdGhpcy5mbHVzaCgpOyB9LCAyMCk7XG4gICAgfVxuICAgIGZvcmNlRmx1c2goKSB7XG4gICAgICAgIGlmICh0aGlzLmZsdXNoaW5nU29vbiA+IC0xKSB7XG4gICAgICAgICAgICB3aW5kb3cuY2xlYXJUaW1lb3V0KHRoaXMuZmx1c2hpbmdTb29uKTtcbiAgICAgICAgICAgIHRoaXMuZmx1c2hpbmdTb29uID0gLTE7XG4gICAgICAgICAgICB0aGlzLmZsdXNoKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc3RhcnQoKSB7XG4gICAgICAgIGlmICh0aGlzLm9ic2VydmVyKSB7XG4gICAgICAgICAgICB0aGlzLm9ic2VydmVyLnRha2VSZWNvcmRzKCk7XG4gICAgICAgICAgICB0aGlzLm9ic2VydmVyLm9ic2VydmUodGhpcy52aWV3LmRvbSwgb2JzZXJ2ZU9wdGlvbnMpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLm9uQ2hhckRhdGEpXG4gICAgICAgICAgICB0aGlzLnZpZXcuZG9tLmFkZEV2ZW50TGlzdGVuZXIoXCJET01DaGFyYWN0ZXJEYXRhTW9kaWZpZWRcIiwgdGhpcy5vbkNoYXJEYXRhKTtcbiAgICAgICAgdGhpcy5jb25uZWN0U2VsZWN0aW9uKCk7XG4gICAgfVxuICAgIHN0b3AoKSB7XG4gICAgICAgIGlmICh0aGlzLm9ic2VydmVyKSB7XG4gICAgICAgICAgICBsZXQgdGFrZSA9IHRoaXMub2JzZXJ2ZXIudGFrZVJlY29yZHMoKTtcbiAgICAgICAgICAgIGlmICh0YWtlLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGFrZS5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5xdWV1ZS5wdXNoKHRha2VbaV0pO1xuICAgICAgICAgICAgICAgIHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHRoaXMuZmx1c2goKSwgMjApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5vYnNlcnZlci5kaXNjb25uZWN0KCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMub25DaGFyRGF0YSlcbiAgICAgICAgICAgIHRoaXMudmlldy5kb20ucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIkRPTUNoYXJhY3RlckRhdGFNb2RpZmllZFwiLCB0aGlzLm9uQ2hhckRhdGEpO1xuICAgICAgICB0aGlzLmRpc2Nvbm5lY3RTZWxlY3Rpb24oKTtcbiAgICB9XG4gICAgY29ubmVjdFNlbGVjdGlvbigpIHtcbiAgICAgICAgdGhpcy52aWV3LmRvbS5vd25lckRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJzZWxlY3Rpb25jaGFuZ2VcIiwgdGhpcy5vblNlbGVjdGlvbkNoYW5nZSk7XG4gICAgfVxuICAgIGRpc2Nvbm5lY3RTZWxlY3Rpb24oKSB7XG4gICAgICAgIHRoaXMudmlldy5kb20ub3duZXJEb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwic2VsZWN0aW9uY2hhbmdlXCIsIHRoaXMub25TZWxlY3Rpb25DaGFuZ2UpO1xuICAgIH1cbiAgICBzdXBwcmVzc1NlbGVjdGlvblVwZGF0ZXMoKSB7XG4gICAgICAgIHRoaXMuc3VwcHJlc3NpbmdTZWxlY3Rpb25VcGRhdGVzID0gdHJ1ZTtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLnN1cHByZXNzaW5nU2VsZWN0aW9uVXBkYXRlcyA9IGZhbHNlLCA1MCk7XG4gICAgfVxuICAgIG9uU2VsZWN0aW9uQ2hhbmdlKCkge1xuICAgICAgICBpZiAoIWhhc0ZvY3VzQW5kU2VsZWN0aW9uKHRoaXMudmlldykpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIGlmICh0aGlzLnN1cHByZXNzaW5nU2VsZWN0aW9uVXBkYXRlcylcbiAgICAgICAgICAgIHJldHVybiBzZWxlY3Rpb25Ub0RPTSh0aGlzLnZpZXcpO1xuICAgICAgICAvLyBEZWxldGlvbnMgb24gSUUxMSBmaXJlIHRoZWlyIGV2ZW50cyBpbiB0aGUgd3Jvbmcgb3JkZXIsIGdpdmluZ1xuICAgICAgICAvLyB1cyBhIHNlbGVjdGlvbiBjaGFuZ2UgZXZlbnQgYmVmb3JlIHRoZSBET00gY2hhbmdlcyBhcmVcbiAgICAgICAgLy8gcmVwb3J0ZWQuXG4gICAgICAgIGlmIChpZSAmJiBpZV92ZXJzaW9uIDw9IDExICYmICF0aGlzLnZpZXcuc3RhdGUuc2VsZWN0aW9uLmVtcHR5KSB7XG4gICAgICAgICAgICBsZXQgc2VsID0gdGhpcy52aWV3LmRvbVNlbGVjdGlvblJhbmdlKCk7XG4gICAgICAgICAgICAvLyBTZWxlY3Rpb24uaXNDb2xsYXBzZWQgaXNuJ3QgcmVsaWFibGUgb24gSUVcbiAgICAgICAgICAgIGlmIChzZWwuZm9jdXNOb2RlICYmIGlzRXF1aXZhbGVudFBvc2l0aW9uKHNlbC5mb2N1c05vZGUsIHNlbC5mb2N1c09mZnNldCwgc2VsLmFuY2hvck5vZGUsIHNlbC5hbmNob3JPZmZzZXQpKVxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZsdXNoU29vbigpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZmx1c2goKTtcbiAgICB9XG4gICAgc2V0Q3VyU2VsZWN0aW9uKCkge1xuICAgICAgICB0aGlzLmN1cnJlbnRTZWxlY3Rpb24uc2V0KHRoaXMudmlldy5kb21TZWxlY3Rpb25SYW5nZSgpKTtcbiAgICB9XG4gICAgaWdub3JlU2VsZWN0aW9uQ2hhbmdlKHNlbCkge1xuICAgICAgICBpZiAoIXNlbC5mb2N1c05vZGUpXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgbGV0IGFuY2VzdG9ycyA9IG5ldyBTZXQsIGNvbnRhaW5lcjtcbiAgICAgICAgZm9yIChsZXQgc2NhbiA9IHNlbC5mb2N1c05vZGU7IHNjYW47IHNjYW4gPSBwYXJlbnROb2RlKHNjYW4pKVxuICAgICAgICAgICAgYW5jZXN0b3JzLmFkZChzY2FuKTtcbiAgICAgICAgZm9yIChsZXQgc2NhbiA9IHNlbC5hbmNob3JOb2RlOyBzY2FuOyBzY2FuID0gcGFyZW50Tm9kZShzY2FuKSlcbiAgICAgICAgICAgIGlmIChhbmNlc3RvcnMuaGFzKHNjYW4pKSB7XG4gICAgICAgICAgICAgICAgY29udGFpbmVyID0gc2NhbjtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgbGV0IGRlc2MgPSBjb250YWluZXIgJiYgdGhpcy52aWV3LmRvY1ZpZXcubmVhcmVzdERlc2MoY29udGFpbmVyKTtcbiAgICAgICAgaWYgKGRlc2MgJiYgZGVzYy5pZ25vcmVNdXRhdGlvbih7XG4gICAgICAgICAgICB0eXBlOiBcInNlbGVjdGlvblwiLFxuICAgICAgICAgICAgdGFyZ2V0OiBjb250YWluZXIubm9kZVR5cGUgPT0gMyA/IGNvbnRhaW5lci5wYXJlbnROb2RlIDogY29udGFpbmVyXG4gICAgICAgIH0pKSB7XG4gICAgICAgICAgICB0aGlzLnNldEN1clNlbGVjdGlvbigpO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcGVuZGluZ1JlY29yZHMoKSB7XG4gICAgICAgIGlmICh0aGlzLm9ic2VydmVyKVxuICAgICAgICAgICAgZm9yIChsZXQgbXV0IG9mIHRoaXMub2JzZXJ2ZXIudGFrZVJlY29yZHMoKSlcbiAgICAgICAgICAgICAgICB0aGlzLnF1ZXVlLnB1c2gobXV0KTtcbiAgICAgICAgcmV0dXJuIHRoaXMucXVldWU7XG4gICAgfVxuICAgIGZsdXNoKCkge1xuICAgICAgICBsZXQgeyB2aWV3IH0gPSB0aGlzO1xuICAgICAgICBpZiAoIXZpZXcuZG9jVmlldyB8fCB0aGlzLmZsdXNoaW5nU29vbiA+IC0xKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBsZXQgbXV0YXRpb25zID0gdGhpcy5wZW5kaW5nUmVjb3JkcygpO1xuICAgICAgICBpZiAobXV0YXRpb25zLmxlbmd0aClcbiAgICAgICAgICAgIHRoaXMucXVldWUgPSBbXTtcbiAgICAgICAgbGV0IHNlbCA9IHZpZXcuZG9tU2VsZWN0aW9uUmFuZ2UoKTtcbiAgICAgICAgbGV0IG5ld1NlbCA9ICF0aGlzLnN1cHByZXNzaW5nU2VsZWN0aW9uVXBkYXRlcyAmJiAhdGhpcy5jdXJyZW50U2VsZWN0aW9uLmVxKHNlbCkgJiYgaGFzRm9jdXNBbmRTZWxlY3Rpb24odmlldykgJiYgIXRoaXMuaWdub3JlU2VsZWN0aW9uQ2hhbmdlKHNlbCk7XG4gICAgICAgIGxldCBmcm9tID0gLTEsIHRvID0gLTEsIHR5cGVPdmVyID0gZmFsc2UsIGFkZGVkID0gW107XG4gICAgICAgIGlmICh2aWV3LmVkaXRhYmxlKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG11dGF0aW9ucy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGxldCByZXN1bHQgPSB0aGlzLnJlZ2lzdGVyTXV0YXRpb24obXV0YXRpb25zW2ldLCBhZGRlZCk7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgICAgICAgICAgICBmcm9tID0gZnJvbSA8IDAgPyByZXN1bHQuZnJvbSA6IE1hdGgubWluKHJlc3VsdC5mcm9tLCBmcm9tKTtcbiAgICAgICAgICAgICAgICAgICAgdG8gPSB0byA8IDAgPyByZXN1bHQudG8gOiBNYXRoLm1heChyZXN1bHQudG8sIHRvKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdC50eXBlT3ZlcilcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVPdmVyID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGdlY2tvICYmIGFkZGVkLmxlbmd0aCkge1xuICAgICAgICAgICAgbGV0IGJycyA9IGFkZGVkLmZpbHRlcihuID0+IG4ubm9kZU5hbWUgPT0gXCJCUlwiKTtcbiAgICAgICAgICAgIGlmIChicnMubGVuZ3RoID09IDIpIHtcbiAgICAgICAgICAgICAgICBsZXQgW2EsIGJdID0gYnJzO1xuICAgICAgICAgICAgICAgIGlmIChhLnBhcmVudE5vZGUgJiYgYS5wYXJlbnROb2RlLnBhcmVudE5vZGUgPT0gYi5wYXJlbnROb2RlKVxuICAgICAgICAgICAgICAgICAgICBiLnJlbW92ZSgpO1xuICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgYS5yZW1vdmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGxldCB7IGZvY3VzTm9kZSB9ID0gdGhpcy5jdXJyZW50U2VsZWN0aW9uO1xuICAgICAgICAgICAgICAgIGZvciAobGV0IGJyIG9mIGJycykge1xuICAgICAgICAgICAgICAgICAgICBsZXQgcGFyZW50ID0gYnIucGFyZW50Tm9kZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmVudCAmJiBwYXJlbnQubm9kZU5hbWUgPT0gXCJMSVwiICYmICghZm9jdXNOb2RlIHx8IGJsb2NrUGFyZW50KHZpZXcsIGZvY3VzTm9kZSkgIT0gcGFyZW50KSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyLnJlbW92ZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgcmVhZFNlbCA9IG51bGw7XG4gICAgICAgIC8vIElmIGl0IGxvb2tzIGxpa2UgdGhlIGJyb3dzZXIgaGFzIHJlc2V0IHRoZSBzZWxlY3Rpb24gdG8gdGhlXG4gICAgICAgIC8vIHN0YXJ0IG9mIHRoZSBkb2N1bWVudCBhZnRlciBmb2N1cywgcmVzdG9yZSB0aGUgc2VsZWN0aW9uIGZyb21cbiAgICAgICAgLy8gdGhlIHN0YXRlXG4gICAgICAgIGlmIChmcm9tIDwgMCAmJiBuZXdTZWwgJiYgdmlldy5pbnB1dC5sYXN0Rm9jdXMgPiBEYXRlLm5vdygpIC0gMjAwICYmXG4gICAgICAgICAgICBNYXRoLm1heCh2aWV3LmlucHV0Lmxhc3RUb3VjaCwgdmlldy5pbnB1dC5sYXN0Q2xpY2sudGltZSkgPCBEYXRlLm5vdygpIC0gMzAwICYmXG4gICAgICAgICAgICBzZWxlY3Rpb25Db2xsYXBzZWQoc2VsKSAmJiAocmVhZFNlbCA9IHNlbGVjdGlvbkZyb21ET00odmlldykpICYmXG4gICAgICAgICAgICByZWFkU2VsLmVxKFNlbGVjdGlvbi5uZWFyKHZpZXcuc3RhdGUuZG9jLnJlc29sdmUoMCksIDEpKSkge1xuICAgICAgICAgICAgdmlldy5pbnB1dC5sYXN0Rm9jdXMgPSAwO1xuICAgICAgICAgICAgc2VsZWN0aW9uVG9ET00odmlldyk7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRTZWxlY3Rpb24uc2V0KHNlbCk7XG4gICAgICAgICAgICB2aWV3LnNjcm9sbFRvU2VsZWN0aW9uKCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZnJvbSA+IC0xIHx8IG5ld1NlbCkge1xuICAgICAgICAgICAgaWYgKGZyb20gPiAtMSkge1xuICAgICAgICAgICAgICAgIHZpZXcuZG9jVmlldy5tYXJrRGlydHkoZnJvbSwgdG8pO1xuICAgICAgICAgICAgICAgIGNoZWNrQ1NTKHZpZXcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5oYW5kbGVET01DaGFuZ2UoZnJvbSwgdG8sIHR5cGVPdmVyLCBhZGRlZCk7XG4gICAgICAgICAgICBpZiAodmlldy5kb2NWaWV3ICYmIHZpZXcuZG9jVmlldy5kaXJ0eSlcbiAgICAgICAgICAgICAgICB2aWV3LnVwZGF0ZVN0YXRlKHZpZXcuc3RhdGUpO1xuICAgICAgICAgICAgZWxzZSBpZiAoIXRoaXMuY3VycmVudFNlbGVjdGlvbi5lcShzZWwpKVxuICAgICAgICAgICAgICAgIHNlbGVjdGlvblRvRE9NKHZpZXcpO1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50U2VsZWN0aW9uLnNldChzZWwpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJlZ2lzdGVyTXV0YXRpb24obXV0LCBhZGRlZCkge1xuICAgICAgICAvLyBJZ25vcmUgbXV0YXRpb25zIGluc2lkZSBub2RlcyB0aGF0IHdlcmUgYWxyZWFkeSBub3RlZCBhcyBpbnNlcnRlZFxuICAgICAgICBpZiAoYWRkZWQuaW5kZXhPZihtdXQudGFyZ2V0KSA+IC0xKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIGxldCBkZXNjID0gdGhpcy52aWV3LmRvY1ZpZXcubmVhcmVzdERlc2MobXV0LnRhcmdldCk7XG4gICAgICAgIGlmIChtdXQudHlwZSA9PSBcImF0dHJpYnV0ZXNcIiAmJlxuICAgICAgICAgICAgKGRlc2MgPT0gdGhpcy52aWV3LmRvY1ZpZXcgfHwgbXV0LmF0dHJpYnV0ZU5hbWUgPT0gXCJjb250ZW50ZWRpdGFibGVcIiB8fFxuICAgICAgICAgICAgICAgIC8vIEZpcmVmb3ggc29tZXRpbWVzIGZpcmVzIHNwdXJpb3VzIGV2ZW50cyBmb3IgbnVsbC9lbXB0eSBzdHlsZXNcbiAgICAgICAgICAgICAgICAobXV0LmF0dHJpYnV0ZU5hbWUgPT0gXCJzdHlsZVwiICYmICFtdXQub2xkVmFsdWUgJiYgIW11dC50YXJnZXQuZ2V0QXR0cmlidXRlKFwic3R5bGVcIikpKSlcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICBpZiAoIWRlc2MgfHwgZGVzYy5pZ25vcmVNdXRhdGlvbihtdXQpKVxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIGlmIChtdXQudHlwZSA9PSBcImNoaWxkTGlzdFwiKSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG11dC5hZGRlZE5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgbGV0IG5vZGUgPSBtdXQuYWRkZWROb2Rlc1tpXTtcbiAgICAgICAgICAgICAgICBhZGRlZC5wdXNoKG5vZGUpO1xuICAgICAgICAgICAgICAgIGlmIChub2RlLm5vZGVUeXBlID09IDMpXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubGFzdENoYW5nZWRUZXh0Tm9kZSA9IG5vZGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZGVzYy5jb250ZW50RE9NICYmIGRlc2MuY29udGVudERPTSAhPSBkZXNjLmRvbSAmJiAhZGVzYy5jb250ZW50RE9NLmNvbnRhaW5zKG11dC50YXJnZXQpKVxuICAgICAgICAgICAgICAgIHJldHVybiB7IGZyb206IGRlc2MucG9zQmVmb3JlLCB0bzogZGVzYy5wb3NBZnRlciB9O1xuICAgICAgICAgICAgbGV0IHByZXYgPSBtdXQucHJldmlvdXNTaWJsaW5nLCBuZXh0ID0gbXV0Lm5leHRTaWJsaW5nO1xuICAgICAgICAgICAgaWYgKGllICYmIGllX3ZlcnNpb24gPD0gMTEgJiYgbXV0LmFkZGVkTm9kZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgLy8gSUUxMSBnaXZlcyB1cyBpbmNvcnJlY3QgbmV4dC9wcmV2IHNpYmxpbmdzIGZvciBzb21lXG4gICAgICAgICAgICAgICAgLy8gaW5zZXJ0aW9ucywgc28gaWYgdGhlcmUgYXJlIGFkZGVkIG5vZGVzLCByZWNvbXB1dGUgdGhvc2VcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG11dC5hZGRlZE5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCB7IHByZXZpb3VzU2libGluZywgbmV4dFNpYmxpbmcgfSA9IG11dC5hZGRlZE5vZGVzW2ldO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXByZXZpb3VzU2libGluZyB8fCBBcnJheS5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKG11dC5hZGRlZE5vZGVzLCBwcmV2aW91c1NpYmxpbmcpIDwgMClcbiAgICAgICAgICAgICAgICAgICAgICAgIHByZXYgPSBwcmV2aW91c1NpYmxpbmc7XG4gICAgICAgICAgICAgICAgICAgIGlmICghbmV4dFNpYmxpbmcgfHwgQXJyYXkucHJvdG90eXBlLmluZGV4T2YuY2FsbChtdXQuYWRkZWROb2RlcywgbmV4dFNpYmxpbmcpIDwgMClcbiAgICAgICAgICAgICAgICAgICAgICAgIG5leHQgPSBuZXh0U2libGluZztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgZnJvbU9mZnNldCA9IHByZXYgJiYgcHJldi5wYXJlbnROb2RlID09IG11dC50YXJnZXRcbiAgICAgICAgICAgICAgICA/IGRvbUluZGV4KHByZXYpICsgMSA6IDA7XG4gICAgICAgICAgICBsZXQgZnJvbSA9IGRlc2MubG9jYWxQb3NGcm9tRE9NKG11dC50YXJnZXQsIGZyb21PZmZzZXQsIC0xKTtcbiAgICAgICAgICAgIGxldCB0b09mZnNldCA9IG5leHQgJiYgbmV4dC5wYXJlbnROb2RlID09IG11dC50YXJnZXRcbiAgICAgICAgICAgICAgICA/IGRvbUluZGV4KG5leHQpIDogbXV0LnRhcmdldC5jaGlsZE5vZGVzLmxlbmd0aDtcbiAgICAgICAgICAgIGxldCB0byA9IGRlc2MubG9jYWxQb3NGcm9tRE9NKG11dC50YXJnZXQsIHRvT2Zmc2V0LCAxKTtcbiAgICAgICAgICAgIHJldHVybiB7IGZyb20sIHRvIH07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAobXV0LnR5cGUgPT0gXCJhdHRyaWJ1dGVzXCIpIHtcbiAgICAgICAgICAgIHJldHVybiB7IGZyb206IGRlc2MucG9zQXRTdGFydCAtIGRlc2MuYm9yZGVyLCB0bzogZGVzYy5wb3NBdEVuZCArIGRlc2MuYm9yZGVyIH07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7IC8vIFwiY2hhcmFjdGVyRGF0YVwiXG4gICAgICAgICAgICB0aGlzLmxhc3RDaGFuZ2VkVGV4dE5vZGUgPSBtdXQudGFyZ2V0O1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBmcm9tOiBkZXNjLnBvc0F0U3RhcnQsXG4gICAgICAgICAgICAgICAgdG86IGRlc2MucG9zQXRFbmQsXG4gICAgICAgICAgICAgICAgLy8gQW4gZXZlbnQgd2FzIGdlbmVyYXRlZCBmb3IgYSB0ZXh0IGNoYW5nZSB0aGF0IGRpZG4ndCBjaGFuZ2VcbiAgICAgICAgICAgICAgICAvLyBhbnkgdGV4dC4gTWFyayB0aGUgZG9tIGNoYW5nZSB0byBmYWxsIGJhY2sgdG8gYXNzdW1pbmcgdGhlXG4gICAgICAgICAgICAgICAgLy8gc2VsZWN0aW9uIHdhcyB0eXBlZCBvdmVyIHdpdGggYW4gaWRlbnRpY2FsIHZhbHVlIGlmIGl0IGNhbid0XG4gICAgICAgICAgICAgICAgLy8gZmluZCBhbm90aGVyIGNoYW5nZS5cbiAgICAgICAgICAgICAgICB0eXBlT3ZlcjogbXV0LnRhcmdldC5ub2RlVmFsdWUgPT0gbXV0Lm9sZFZhbHVlXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfVxufVxubGV0IGNzc0NoZWNrZWQgPSBuZXcgV2Vha01hcCgpO1xubGV0IGNzc0NoZWNrV2FybmVkID0gZmFsc2U7XG5mdW5jdGlvbiBjaGVja0NTUyh2aWV3KSB7XG4gICAgaWYgKGNzc0NoZWNrZWQuaGFzKHZpZXcpKVxuICAgICAgICByZXR1cm47XG4gICAgY3NzQ2hlY2tlZC5zZXQodmlldywgbnVsbCk7XG4gICAgaWYgKFsnbm9ybWFsJywgJ25vd3JhcCcsICdwcmUtbGluZSddLmluZGV4T2YoZ2V0Q29tcHV0ZWRTdHlsZSh2aWV3LmRvbSkud2hpdGVTcGFjZSkgIT09IC0xKSB7XG4gICAgICAgIHZpZXcucmVxdWlyZXNHZWNrb0hhY2tOb2RlID0gZ2Vja287XG4gICAgICAgIGlmIChjc3NDaGVja1dhcm5lZClcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgY29uc29sZVtcIndhcm5cIl0oXCJQcm9zZU1pcnJvciBleHBlY3RzIHRoZSBDU1Mgd2hpdGUtc3BhY2UgcHJvcGVydHkgdG8gYmUgc2V0LCBwcmVmZXJhYmx5IHRvICdwcmUtd3JhcCcuIEl0IGlzIHJlY29tbWVuZGVkIHRvIGxvYWQgc3R5bGUvcHJvc2VtaXJyb3IuY3NzIGZyb20gdGhlIHByb3NlbWlycm9yLXZpZXcgcGFja2FnZS5cIik7XG4gICAgICAgIGNzc0NoZWNrV2FybmVkID0gdHJ1ZTtcbiAgICB9XG59XG5mdW5jdGlvbiByYW5nZVRvU2VsZWN0aW9uUmFuZ2UodmlldywgcmFuZ2UpIHtcbiAgICBsZXQgYW5jaG9yTm9kZSA9IHJhbmdlLnN0YXJ0Q29udGFpbmVyLCBhbmNob3JPZmZzZXQgPSByYW5nZS5zdGFydE9mZnNldDtcbiAgICBsZXQgZm9jdXNOb2RlID0gcmFuZ2UuZW5kQ29udGFpbmVyLCBmb2N1c09mZnNldCA9IHJhbmdlLmVuZE9mZnNldDtcbiAgICBsZXQgY3VycmVudEFuY2hvciA9IHZpZXcuZG9tQXRQb3Modmlldy5zdGF0ZS5zZWxlY3Rpb24uYW5jaG9yKTtcbiAgICAvLyBTaW5jZSBzdWNoIGEgcmFuZ2UgZG9lc24ndCBkaXN0aW5ndWlzaCBiZXR3ZWVuIGFuY2hvciBhbmQgaGVhZCxcbiAgICAvLyB1c2UgYSBoZXVyaXN0aWMgdGhhdCBmbGlwcyBpdCBhcm91bmQgaWYgaXRzIGVuZCBtYXRjaGVzIHRoZVxuICAgIC8vIGN1cnJlbnQgYW5jaG9yLlxuICAgIGlmIChpc0VxdWl2YWxlbnRQb3NpdGlvbihjdXJyZW50QW5jaG9yLm5vZGUsIGN1cnJlbnRBbmNob3Iub2Zmc2V0LCBmb2N1c05vZGUsIGZvY3VzT2Zmc2V0KSlcbiAgICAgICAgW2FuY2hvck5vZGUsIGFuY2hvck9mZnNldCwgZm9jdXNOb2RlLCBmb2N1c09mZnNldF0gPSBbZm9jdXNOb2RlLCBmb2N1c09mZnNldCwgYW5jaG9yTm9kZSwgYW5jaG9yT2Zmc2V0XTtcbiAgICByZXR1cm4geyBhbmNob3JOb2RlLCBhbmNob3JPZmZzZXQsIGZvY3VzTm9kZSwgZm9jdXNPZmZzZXQgfTtcbn1cbi8vIFVzZWQgdG8gd29yayBhcm91bmQgYSBTYWZhcmkgU2VsZWN0aW9uL3NoYWRvdyBET00gYnVnXG4vLyBCYXNlZCBvbiBodHRwczovL2dpdGh1Yi5jb20vY29kZW1pcnJvci9kZXYvaXNzdWVzLzQxNCBmaXhcbmZ1bmN0aW9uIHNhZmFyaVNoYWRvd1NlbGVjdGlvblJhbmdlKHZpZXcsIHNlbGVjdGlvbikge1xuICAgIGlmIChzZWxlY3Rpb24uZ2V0Q29tcG9zZWRSYW5nZXMpIHtcbiAgICAgICAgbGV0IHJhbmdlID0gc2VsZWN0aW9uLmdldENvbXBvc2VkUmFuZ2VzKHZpZXcucm9vdClbMF07XG4gICAgICAgIGlmIChyYW5nZSlcbiAgICAgICAgICAgIHJldHVybiByYW5nZVRvU2VsZWN0aW9uUmFuZ2UodmlldywgcmFuZ2UpO1xuICAgIH1cbiAgICBsZXQgZm91bmQ7XG4gICAgZnVuY3Rpb24gcmVhZChldmVudCkge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcbiAgICAgICAgZm91bmQgPSBldmVudC5nZXRUYXJnZXRSYW5nZXMoKVswXTtcbiAgICB9XG4gICAgLy8gQmVjYXVzZSBTYWZhcmkgKGF0IGxlYXN0IGluIDIwMTgtMjAyMikgZG9lc24ndCBwcm92aWRlIHJlZ3VsYXJcbiAgICAvLyBhY2Nlc3MgdG8gdGhlIHNlbGVjdGlvbiBpbnNpZGUgYSBzaGFkb3dSb290LCB3ZSBoYXZlIHRvIHBlcmZvcm0gYVxuICAgIC8vIHJpZGljdWxvdXMgaGFjayB0byBnZXQgYXQgaXRcdTIwMTR1c2luZyBgZXhlY0NvbW1hbmRgIHRvIHRyaWdnZXIgYVxuICAgIC8vIGBiZWZvcmVJbnB1dGAgZXZlbnQgc28gdGhhdCB3ZSBjYW4gcmVhZCB0aGUgdGFyZ2V0IHJhbmdlIGZyb20gdGhlXG4gICAgLy8gZXZlbnQuXG4gICAgdmlldy5kb20uYWRkRXZlbnRMaXN0ZW5lcihcImJlZm9yZWlucHV0XCIsIHJlYWQsIHRydWUpO1xuICAgIGRvY3VtZW50LmV4ZWNDb21tYW5kKFwiaW5kZW50XCIpO1xuICAgIHZpZXcuZG9tLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJiZWZvcmVpbnB1dFwiLCByZWFkLCB0cnVlKTtcbiAgICByZXR1cm4gZm91bmQgPyByYW5nZVRvU2VsZWN0aW9uUmFuZ2UodmlldywgZm91bmQpIDogbnVsbDtcbn1cbmZ1bmN0aW9uIGJsb2NrUGFyZW50KHZpZXcsIG5vZGUpIHtcbiAgICBmb3IgKGxldCBwID0gbm9kZS5wYXJlbnROb2RlOyBwICYmIHAgIT0gdmlldy5kb207IHAgPSBwLnBhcmVudE5vZGUpIHtcbiAgICAgICAgbGV0IGRlc2MgPSB2aWV3LmRvY1ZpZXcubmVhcmVzdERlc2MocCwgdHJ1ZSk7XG4gICAgICAgIGlmIChkZXNjICYmIGRlc2Mubm9kZS5pc0Jsb2NrKVxuICAgICAgICAgICAgcmV0dXJuIHA7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuXG4vLyBOb3RlIHRoYXQgYWxsIHJlZmVyZW5jaW5nIGFuZCBwYXJzaW5nIGlzIGRvbmUgd2l0aCB0aGVcbi8vIHN0YXJ0LW9mLW9wZXJhdGlvbiBzZWxlY3Rpb24gYW5kIGRvY3VtZW50LCBzaW5jZSB0aGF0J3MgdGhlIG9uZVxuLy8gdGhhdCB0aGUgRE9NIHJlcHJlc2VudHMuIElmIGFueSBjaGFuZ2VzIGNhbWUgaW4gaW4gdGhlIG1lYW50aW1lLFxuLy8gdGhlIG1vZGlmaWNhdGlvbiBpcyBtYXBwZWQgb3ZlciB0aG9zZSBiZWZvcmUgaXQgaXMgYXBwbGllZCwgaW5cbi8vIHJlYWRET01DaGFuZ2UuXG5mdW5jdGlvbiBwYXJzZUJldHdlZW4odmlldywgZnJvbV8sIHRvXykge1xuICAgIGxldCB7IG5vZGU6IHBhcmVudCwgZnJvbU9mZnNldCwgdG9PZmZzZXQsIGZyb20sIHRvIH0gPSB2aWV3LmRvY1ZpZXcucGFyc2VSYW5nZShmcm9tXywgdG9fKTtcbiAgICBsZXQgZG9tU2VsID0gdmlldy5kb21TZWxlY3Rpb25SYW5nZSgpO1xuICAgIGxldCBmaW5kO1xuICAgIGxldCBhbmNob3IgPSBkb21TZWwuYW5jaG9yTm9kZTtcbiAgICBpZiAoYW5jaG9yICYmIHZpZXcuZG9tLmNvbnRhaW5zKGFuY2hvci5ub2RlVHlwZSA9PSAxID8gYW5jaG9yIDogYW5jaG9yLnBhcmVudE5vZGUpKSB7XG4gICAgICAgIGZpbmQgPSBbeyBub2RlOiBhbmNob3IsIG9mZnNldDogZG9tU2VsLmFuY2hvck9mZnNldCB9XTtcbiAgICAgICAgaWYgKCFzZWxlY3Rpb25Db2xsYXBzZWQoZG9tU2VsKSlcbiAgICAgICAgICAgIGZpbmQucHVzaCh7IG5vZGU6IGRvbVNlbC5mb2N1c05vZGUsIG9mZnNldDogZG9tU2VsLmZvY3VzT2Zmc2V0IH0pO1xuICAgIH1cbiAgICAvLyBXb3JrIGFyb3VuZCBpc3N1ZSBpbiBDaHJvbWUgd2hlcmUgYmFja3NwYWNpbmcgc29tZXRpbWVzIHJlcGxhY2VzXG4gICAgLy8gdGhlIGRlbGV0ZWQgY29udGVudCB3aXRoIGEgcmFuZG9tIEJSIG5vZGUgKGlzc3VlcyAjNzk5LCAjODMxKVxuICAgIGlmIChjaHJvbWUgJiYgdmlldy5pbnB1dC5sYXN0S2V5Q29kZSA9PT0gOCkge1xuICAgICAgICBmb3IgKGxldCBvZmYgPSB0b09mZnNldDsgb2ZmID4gZnJvbU9mZnNldDsgb2ZmLS0pIHtcbiAgICAgICAgICAgIGxldCBub2RlID0gcGFyZW50LmNoaWxkTm9kZXNbb2ZmIC0gMV0sIGRlc2MgPSBub2RlLnBtVmlld0Rlc2M7XG4gICAgICAgICAgICBpZiAobm9kZS5ub2RlTmFtZSA9PSBcIkJSXCIgJiYgIWRlc2MpIHtcbiAgICAgICAgICAgICAgICB0b09mZnNldCA9IG9mZjtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghZGVzYyB8fCBkZXNjLnNpemUpXG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG4gICAgbGV0IHN0YXJ0RG9jID0gdmlldy5zdGF0ZS5kb2M7XG4gICAgbGV0IHBhcnNlciA9IHZpZXcuc29tZVByb3AoXCJkb21QYXJzZXJcIikgfHwgRE9NUGFyc2VyLmZyb21TY2hlbWEodmlldy5zdGF0ZS5zY2hlbWEpO1xuICAgIGxldCAkZnJvbSA9IHN0YXJ0RG9jLnJlc29sdmUoZnJvbSk7XG4gICAgbGV0IHNlbCA9IG51bGwsIGRvYyA9IHBhcnNlci5wYXJzZShwYXJlbnQsIHtcbiAgICAgICAgdG9wTm9kZTogJGZyb20ucGFyZW50LFxuICAgICAgICB0b3BNYXRjaDogJGZyb20ucGFyZW50LmNvbnRlbnRNYXRjaEF0KCRmcm9tLmluZGV4KCkpLFxuICAgICAgICB0b3BPcGVuOiB0cnVlLFxuICAgICAgICBmcm9tOiBmcm9tT2Zmc2V0LFxuICAgICAgICB0bzogdG9PZmZzZXQsXG4gICAgICAgIHByZXNlcnZlV2hpdGVzcGFjZTogJGZyb20ucGFyZW50LnR5cGUud2hpdGVzcGFjZSA9PSBcInByZVwiID8gXCJmdWxsXCIgOiB0cnVlLFxuICAgICAgICBmaW5kUG9zaXRpb25zOiBmaW5kLFxuICAgICAgICBydWxlRnJvbU5vZGUsXG4gICAgICAgIGNvbnRleHQ6ICRmcm9tXG4gICAgfSk7XG4gICAgaWYgKGZpbmQgJiYgZmluZFswXS5wb3MgIT0gbnVsbCkge1xuICAgICAgICBsZXQgYW5jaG9yID0gZmluZFswXS5wb3MsIGhlYWQgPSBmaW5kWzFdICYmIGZpbmRbMV0ucG9zO1xuICAgICAgICBpZiAoaGVhZCA9PSBudWxsKVxuICAgICAgICAgICAgaGVhZCA9IGFuY2hvcjtcbiAgICAgICAgc2VsID0geyBhbmNob3I6IGFuY2hvciArIGZyb20sIGhlYWQ6IGhlYWQgKyBmcm9tIH07XG4gICAgfVxuICAgIHJldHVybiB7IGRvYywgc2VsLCBmcm9tLCB0byB9O1xufVxuZnVuY3Rpb24gcnVsZUZyb21Ob2RlKGRvbSkge1xuICAgIGxldCBkZXNjID0gZG9tLnBtVmlld0Rlc2M7XG4gICAgaWYgKGRlc2MpIHtcbiAgICAgICAgcmV0dXJuIGRlc2MucGFyc2VSdWxlKCk7XG4gICAgfVxuICAgIGVsc2UgaWYgKGRvbS5ub2RlTmFtZSA9PSBcIkJSXCIgJiYgZG9tLnBhcmVudE5vZGUpIHtcbiAgICAgICAgLy8gU2FmYXJpIHJlcGxhY2VzIHRoZSBsaXN0IGl0ZW0gb3IgdGFibGUgY2VsbCB3aXRoIGEgQlJcbiAgICAgICAgLy8gZGlyZWN0bHkgaW4gdGhlIGxpc3Qgbm9kZSAoPyEpIGlmIHlvdSBkZWxldGUgdGhlIGxhc3RcbiAgICAgICAgLy8gY2hhcmFjdGVyIGluIGEgbGlzdCBpdGVtIG9yIHRhYmxlIGNlbGwgKCM3MDgsICM4NjIpXG4gICAgICAgIGlmIChzYWZhcmkgJiYgL14odWx8b2wpJC9pLnRlc3QoZG9tLnBhcmVudE5vZGUubm9kZU5hbWUpKSB7XG4gICAgICAgICAgICBsZXQgc2tpcCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICAgICAgICBza2lwLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJsaVwiKSk7XG4gICAgICAgICAgICByZXR1cm4geyBza2lwIH07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZG9tLnBhcmVudE5vZGUubGFzdENoaWxkID09IGRvbSB8fCBzYWZhcmkgJiYgL14odHJ8dGFibGUpJC9pLnRlc3QoZG9tLnBhcmVudE5vZGUubm9kZU5hbWUpKSB7XG4gICAgICAgICAgICByZXR1cm4geyBpZ25vcmU6IHRydWUgfTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIGlmIChkb20ubm9kZU5hbWUgPT0gXCJJTUdcIiAmJiBkb20uZ2V0QXR0cmlidXRlKFwibWFyay1wbGFjZWhvbGRlclwiKSkge1xuICAgICAgICByZXR1cm4geyBpZ25vcmU6IHRydWUgfTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5jb25zdCBpc0lubGluZSA9IC9eKGF8YWJicnxhY3JvbnltfGJ8YmRbaW9dfGJpZ3xicnxidXR0b258Y2l0ZXxjb2RlfGRhdGEobGlzdCk/fGRlbHxkZm58ZW18aXxpbnN8a2JkfGxhYmVsfG1hcHxtYXJrfG1ldGVyfG91dHB1dHxxfHJ1Ynl8c3xzYW1wfHNtYWxsfHNwYW58c3Ryb25nfHN1W2JwXXx0aW1lfHV8dHR8dmFyKSQvaTtcbmZ1bmN0aW9uIHJlYWRET01DaGFuZ2UodmlldywgZnJvbSwgdG8sIHR5cGVPdmVyLCBhZGRlZE5vZGVzKSB7XG4gICAgbGV0IGNvbXBvc2l0aW9uSUQgPSB2aWV3LmlucHV0LmNvbXBvc2l0aW9uUGVuZGluZ0NoYW5nZXMgfHwgKHZpZXcuY29tcG9zaW5nID8gdmlldy5pbnB1dC5jb21wb3NpdGlvbklEIDogMCk7XG4gICAgdmlldy5pbnB1dC5jb21wb3NpdGlvblBlbmRpbmdDaGFuZ2VzID0gMDtcbiAgICBpZiAoZnJvbSA8IDApIHtcbiAgICAgICAgbGV0IG9yaWdpbiA9IHZpZXcuaW5wdXQubGFzdFNlbGVjdGlvblRpbWUgPiBEYXRlLm5vdygpIC0gNTAgPyB2aWV3LmlucHV0Lmxhc3RTZWxlY3Rpb25PcmlnaW4gOiBudWxsO1xuICAgICAgICBsZXQgbmV3U2VsID0gc2VsZWN0aW9uRnJvbURPTSh2aWV3LCBvcmlnaW4pO1xuICAgICAgICBpZiAobmV3U2VsICYmICF2aWV3LnN0YXRlLnNlbGVjdGlvbi5lcShuZXdTZWwpKSB7XG4gICAgICAgICAgICBpZiAoY2hyb21lICYmIGFuZHJvaWQgJiZcbiAgICAgICAgICAgICAgICB2aWV3LmlucHV0Lmxhc3RLZXlDb2RlID09PSAxMyAmJiBEYXRlLm5vdygpIC0gMTAwIDwgdmlldy5pbnB1dC5sYXN0S2V5Q29kZVRpbWUgJiZcbiAgICAgICAgICAgICAgICB2aWV3LnNvbWVQcm9wKFwiaGFuZGxlS2V5RG93blwiLCBmID0+IGYodmlldywga2V5RXZlbnQoMTMsIFwiRW50ZXJcIikpKSlcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICBsZXQgdHIgPSB2aWV3LnN0YXRlLnRyLnNldFNlbGVjdGlvbihuZXdTZWwpO1xuICAgICAgICAgICAgaWYgKG9yaWdpbiA9PSBcInBvaW50ZXJcIilcbiAgICAgICAgICAgICAgICB0ci5zZXRNZXRhKFwicG9pbnRlclwiLCB0cnVlKTtcbiAgICAgICAgICAgIGVsc2UgaWYgKG9yaWdpbiA9PSBcImtleVwiKVxuICAgICAgICAgICAgICAgIHRyLnNjcm9sbEludG9WaWV3KCk7XG4gICAgICAgICAgICBpZiAoY29tcG9zaXRpb25JRClcbiAgICAgICAgICAgICAgICB0ci5zZXRNZXRhKFwiY29tcG9zaXRpb25cIiwgY29tcG9zaXRpb25JRCk7XG4gICAgICAgICAgICB2aWV3LmRpc3BhdGNoKHRyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGxldCAkYmVmb3JlID0gdmlldy5zdGF0ZS5kb2MucmVzb2x2ZShmcm9tKTtcbiAgICBsZXQgc2hhcmVkID0gJGJlZm9yZS5zaGFyZWREZXB0aCh0byk7XG4gICAgZnJvbSA9ICRiZWZvcmUuYmVmb3JlKHNoYXJlZCArIDEpO1xuICAgIHRvID0gdmlldy5zdGF0ZS5kb2MucmVzb2x2ZSh0bykuYWZ0ZXIoc2hhcmVkICsgMSk7XG4gICAgbGV0IHNlbCA9IHZpZXcuc3RhdGUuc2VsZWN0aW9uO1xuICAgIGxldCBwYXJzZSA9IHBhcnNlQmV0d2Vlbih2aWV3LCBmcm9tLCB0byk7XG4gICAgbGV0IGRvYyA9IHZpZXcuc3RhdGUuZG9jLCBjb21wYXJlID0gZG9jLnNsaWNlKHBhcnNlLmZyb20sIHBhcnNlLnRvKTtcbiAgICBsZXQgcHJlZmVycmVkUG9zLCBwcmVmZXJyZWRTaWRlO1xuICAgIC8vIFByZWZlciBhbmNob3JpbmcgdG8gZW5kIHdoZW4gQmFja3NwYWNlIGlzIHByZXNzZWRcbiAgICBpZiAodmlldy5pbnB1dC5sYXN0S2V5Q29kZSA9PT0gOCAmJiBEYXRlLm5vdygpIC0gMTAwIDwgdmlldy5pbnB1dC5sYXN0S2V5Q29kZVRpbWUpIHtcbiAgICAgICAgcHJlZmVycmVkUG9zID0gdmlldy5zdGF0ZS5zZWxlY3Rpb24udG87XG4gICAgICAgIHByZWZlcnJlZFNpZGUgPSBcImVuZFwiO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgcHJlZmVycmVkUG9zID0gdmlldy5zdGF0ZS5zZWxlY3Rpb24uZnJvbTtcbiAgICAgICAgcHJlZmVycmVkU2lkZSA9IFwic3RhcnRcIjtcbiAgICB9XG4gICAgdmlldy5pbnB1dC5sYXN0S2V5Q29kZSA9IG51bGw7XG4gICAgbGV0IGNoYW5nZSA9IGZpbmREaWZmKGNvbXBhcmUuY29udGVudCwgcGFyc2UuZG9jLmNvbnRlbnQsIHBhcnNlLmZyb20sIHByZWZlcnJlZFBvcywgcHJlZmVycmVkU2lkZSk7XG4gICAgaWYgKGNoYW5nZSlcbiAgICAgICAgdmlldy5pbnB1dC5kb21DaGFuZ2VDb3VudCsrO1xuICAgIGlmICgoaW9zICYmIHZpZXcuaW5wdXQubGFzdElPU0VudGVyID4gRGF0ZS5ub3coKSAtIDIyNSB8fCBhbmRyb2lkKSAmJlxuICAgICAgICBhZGRlZE5vZGVzLnNvbWUobiA9PiBuLm5vZGVUeXBlID09IDEgJiYgIWlzSW5saW5lLnRlc3Qobi5ub2RlTmFtZSkpICYmXG4gICAgICAgICghY2hhbmdlIHx8IGNoYW5nZS5lbmRBID49IGNoYW5nZS5lbmRCKSAmJlxuICAgICAgICB2aWV3LnNvbWVQcm9wKFwiaGFuZGxlS2V5RG93blwiLCBmID0+IGYodmlldywga2V5RXZlbnQoMTMsIFwiRW50ZXJcIikpKSkge1xuICAgICAgICB2aWV3LmlucHV0Lmxhc3RJT1NFbnRlciA9IDA7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCFjaGFuZ2UpIHtcbiAgICAgICAgaWYgKHR5cGVPdmVyICYmIHNlbCBpbnN0YW5jZW9mIFRleHRTZWxlY3Rpb24gJiYgIXNlbC5lbXB0eSAmJiBzZWwuJGhlYWQuc2FtZVBhcmVudChzZWwuJGFuY2hvcikgJiZcbiAgICAgICAgICAgICF2aWV3LmNvbXBvc2luZyAmJiAhKHBhcnNlLnNlbCAmJiBwYXJzZS5zZWwuYW5jaG9yICE9IHBhcnNlLnNlbC5oZWFkKSkge1xuICAgICAgICAgICAgY2hhbmdlID0geyBzdGFydDogc2VsLmZyb20sIGVuZEE6IHNlbC50bywgZW5kQjogc2VsLnRvIH07XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpZiAocGFyc2Uuc2VsKSB7XG4gICAgICAgICAgICAgICAgbGV0IHNlbCA9IHJlc29sdmVTZWxlY3Rpb24odmlldywgdmlldy5zdGF0ZS5kb2MsIHBhcnNlLnNlbCk7XG4gICAgICAgICAgICAgICAgaWYgKHNlbCAmJiAhc2VsLmVxKHZpZXcuc3RhdGUuc2VsZWN0aW9uKSkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgdHIgPSB2aWV3LnN0YXRlLnRyLnNldFNlbGVjdGlvbihzZWwpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoY29tcG9zaXRpb25JRClcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyLnNldE1ldGEoXCJjb21wb3NpdGlvblwiLCBjb21wb3NpdGlvbklEKTtcbiAgICAgICAgICAgICAgICAgICAgdmlldy5kaXNwYXRjaCh0cik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIEhhbmRsZSB0aGUgY2FzZSB3aGVyZSBvdmVyd3JpdGluZyBhIHNlbGVjdGlvbiBieSB0eXBpbmcgbWF0Y2hlc1xuICAgIC8vIHRoZSBzdGFydCBvciBlbmQgb2YgdGhlIHNlbGVjdGVkIGNvbnRlbnQsIGNyZWF0aW5nIGEgY2hhbmdlXG4gICAgLy8gdGhhdCdzIHNtYWxsZXIgdGhhbiB3aGF0IHdhcyBhY3R1YWxseSBvdmVyd3JpdHRlbi5cbiAgICBpZiAodmlldy5zdGF0ZS5zZWxlY3Rpb24uZnJvbSA8IHZpZXcuc3RhdGUuc2VsZWN0aW9uLnRvICYmXG4gICAgICAgIGNoYW5nZS5zdGFydCA9PSBjaGFuZ2UuZW5kQiAmJlxuICAgICAgICB2aWV3LnN0YXRlLnNlbGVjdGlvbiBpbnN0YW5jZW9mIFRleHRTZWxlY3Rpb24pIHtcbiAgICAgICAgaWYgKGNoYW5nZS5zdGFydCA+IHZpZXcuc3RhdGUuc2VsZWN0aW9uLmZyb20gJiYgY2hhbmdlLnN0YXJ0IDw9IHZpZXcuc3RhdGUuc2VsZWN0aW9uLmZyb20gKyAyICYmXG4gICAgICAgICAgICB2aWV3LnN0YXRlLnNlbGVjdGlvbi5mcm9tID49IHBhcnNlLmZyb20pIHtcbiAgICAgICAgICAgIGNoYW5nZS5zdGFydCA9IHZpZXcuc3RhdGUuc2VsZWN0aW9uLmZyb207XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoY2hhbmdlLmVuZEEgPCB2aWV3LnN0YXRlLnNlbGVjdGlvbi50byAmJiBjaGFuZ2UuZW5kQSA+PSB2aWV3LnN0YXRlLnNlbGVjdGlvbi50byAtIDIgJiZcbiAgICAgICAgICAgIHZpZXcuc3RhdGUuc2VsZWN0aW9uLnRvIDw9IHBhcnNlLnRvKSB7XG4gICAgICAgICAgICBjaGFuZ2UuZW5kQiArPSAodmlldy5zdGF0ZS5zZWxlY3Rpb24udG8gLSBjaGFuZ2UuZW5kQSk7XG4gICAgICAgICAgICBjaGFuZ2UuZW5kQSA9IHZpZXcuc3RhdGUuc2VsZWN0aW9uLnRvO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIElFMTEgd2lsbCBpbnNlcnQgYSBub24tYnJlYWtpbmcgc3BhY2UgX2FoZWFkXyBvZiB0aGUgc3BhY2UgYWZ0ZXJcbiAgICAvLyB0aGUgY3Vyc29yIHNwYWNlIHdoZW4gYWRkaW5nIGEgc3BhY2UgYmVmb3JlIGFub3RoZXIgc3BhY2UuIFdoZW5cbiAgICAvLyB0aGF0IGhhcHBlbmVkLCBhZGp1c3QgdGhlIGNoYW5nZSB0byBjb3ZlciB0aGUgc3BhY2UgaW5zdGVhZC5cbiAgICBpZiAoaWUgJiYgaWVfdmVyc2lvbiA8PSAxMSAmJiBjaGFuZ2UuZW5kQiA9PSBjaGFuZ2Uuc3RhcnQgKyAxICYmXG4gICAgICAgIGNoYW5nZS5lbmRBID09IGNoYW5nZS5zdGFydCAmJiBjaGFuZ2Uuc3RhcnQgPiBwYXJzZS5mcm9tICYmXG4gICAgICAgIHBhcnNlLmRvYy50ZXh0QmV0d2VlbihjaGFuZ2Uuc3RhcnQgLSBwYXJzZS5mcm9tIC0gMSwgY2hhbmdlLnN0YXJ0IC0gcGFyc2UuZnJvbSArIDEpID09IFwiIFxcdTAwYTBcIikge1xuICAgICAgICBjaGFuZ2Uuc3RhcnQtLTtcbiAgICAgICAgY2hhbmdlLmVuZEEtLTtcbiAgICAgICAgY2hhbmdlLmVuZEItLTtcbiAgICB9XG4gICAgbGV0ICRmcm9tID0gcGFyc2UuZG9jLnJlc29sdmVOb0NhY2hlKGNoYW5nZS5zdGFydCAtIHBhcnNlLmZyb20pO1xuICAgIGxldCAkdG8gPSBwYXJzZS5kb2MucmVzb2x2ZU5vQ2FjaGUoY2hhbmdlLmVuZEIgLSBwYXJzZS5mcm9tKTtcbiAgICBsZXQgJGZyb21BID0gZG9jLnJlc29sdmUoY2hhbmdlLnN0YXJ0KTtcbiAgICBsZXQgaW5saW5lQ2hhbmdlID0gJGZyb20uc2FtZVBhcmVudCgkdG8pICYmICRmcm9tLnBhcmVudC5pbmxpbmVDb250ZW50ICYmICRmcm9tQS5lbmQoKSA+PSBjaGFuZ2UuZW5kQTtcbiAgICBsZXQgbmV4dFNlbDtcbiAgICAvLyBJZiB0aGlzIGxvb2tzIGxpa2UgdGhlIGVmZmVjdCBvZiBwcmVzc2luZyBFbnRlciAob3Igd2FzIHJlY29yZGVkXG4gICAgLy8gYXMgYmVpbmcgYW4gaU9TIGVudGVyIHByZXNzKSwganVzdCBkaXNwYXRjaCBhbiBFbnRlciBrZXkgaW5zdGVhZC5cbiAgICBpZiAoKChpb3MgJiYgdmlldy5pbnB1dC5sYXN0SU9TRW50ZXIgPiBEYXRlLm5vdygpIC0gMjI1ICYmXG4gICAgICAgICghaW5saW5lQ2hhbmdlIHx8IGFkZGVkTm9kZXMuc29tZShuID0+IG4ubm9kZU5hbWUgPT0gXCJESVZcIiB8fCBuLm5vZGVOYW1lID09IFwiUFwiKSkpIHx8XG4gICAgICAgICghaW5saW5lQ2hhbmdlICYmICRmcm9tLnBvcyA8IHBhcnNlLmRvYy5jb250ZW50LnNpemUgJiZcbiAgICAgICAgICAgICghJGZyb20uc2FtZVBhcmVudCgkdG8pIHx8ICEkZnJvbS5wYXJlbnQuaW5saW5lQ29udGVudCkgJiZcbiAgICAgICAgICAgICEvXFxTLy50ZXN0KHBhcnNlLmRvYy50ZXh0QmV0d2VlbigkZnJvbS5wb3MsICR0by5wb3MsIFwiXCIsIFwiXCIpKSAmJlxuICAgICAgICAgICAgKG5leHRTZWwgPSBTZWxlY3Rpb24uZmluZEZyb20ocGFyc2UuZG9jLnJlc29sdmUoJGZyb20ucG9zICsgMSksIDEsIHRydWUpKSAmJlxuICAgICAgICAgICAgbmV4dFNlbC5oZWFkID4gJGZyb20ucG9zKSkgJiZcbiAgICAgICAgdmlldy5zb21lUHJvcChcImhhbmRsZUtleURvd25cIiwgZiA9PiBmKHZpZXcsIGtleUV2ZW50KDEzLCBcIkVudGVyXCIpKSkpIHtcbiAgICAgICAgdmlldy5pbnB1dC5sYXN0SU9TRW50ZXIgPSAwO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIFNhbWUgZm9yIGJhY2tzcGFjZVxuICAgIGlmICh2aWV3LnN0YXRlLnNlbGVjdGlvbi5hbmNob3IgPiBjaGFuZ2Uuc3RhcnQgJiZcbiAgICAgICAgbG9va3NMaWtlQmFja3NwYWNlKGRvYywgY2hhbmdlLnN0YXJ0LCBjaGFuZ2UuZW5kQSwgJGZyb20sICR0bykgJiZcbiAgICAgICAgdmlldy5zb21lUHJvcChcImhhbmRsZUtleURvd25cIiwgZiA9PiBmKHZpZXcsIGtleUV2ZW50KDgsIFwiQmFja3NwYWNlXCIpKSkpIHtcbiAgICAgICAgaWYgKGFuZHJvaWQgJiYgY2hyb21lKVxuICAgICAgICAgICAgdmlldy5kb21PYnNlcnZlci5zdXBwcmVzc1NlbGVjdGlvblVwZGF0ZXMoKTsgLy8gIzgyMFxuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIENocm9tZSB3aWxsIG9jY2FzaW9uYWxseSwgZHVyaW5nIGNvbXBvc2l0aW9uLCBkZWxldGUgdGhlXG4gICAgLy8gZW50aXJlIGNvbXBvc2l0aW9uIGFuZCB0aGVuIGltbWVkaWF0ZWx5IGluc2VydCBpdCBhZ2Fpbi4gVGhpcyBpc1xuICAgIC8vIHVzZWQgdG8gZGV0ZWN0IHRoYXQgc2l0dWF0aW9uLlxuICAgIGlmIChjaHJvbWUgJiYgY2hhbmdlLmVuZEIgPT0gY2hhbmdlLnN0YXJ0KVxuICAgICAgICB2aWV3LmlucHV0Lmxhc3RDaHJvbWVEZWxldGUgPSBEYXRlLm5vdygpO1xuICAgIC8vIFRoaXMgdHJpZXMgdG8gZGV0ZWN0IEFuZHJvaWQgdmlydHVhbCBrZXlib2FyZFxuICAgIC8vIGVudGVyLWFuZC1waWNrLXN1Z2dlc3Rpb24gYWN0aW9uLiBUaGF0IHNvbWV0aW1lcyAoc2VlIGlzc3VlXG4gICAgLy8gIzEwNTkpIGZpcnN0IGZpcmVzIGEgRE9NIG11dGF0aW9uLCBiZWZvcmUgbW92aW5nIHRoZSBzZWxlY3Rpb24gdG9cbiAgICAvLyB0aGUgbmV3bHkgY3JlYXRlZCBibG9jay4gQW5kIHRoZW4sIGJlY2F1c2UgUHJvc2VNaXJyb3IgY2xlYW5zIHVwXG4gICAgLy8gdGhlIERPTSBzZWxlY3Rpb24sIGl0IGdpdmVzIHVwIG1vdmluZyB0aGUgc2VsZWN0aW9uIGVudGlyZWx5LFxuICAgIC8vIGxlYXZpbmcgdGhlIGN1cnNvciBpbiB0aGUgd3JvbmcgcGxhY2UuIFdoZW4gdGhhdCBoYXBwZW5zLCB3ZSBkcm9wXG4gICAgLy8gdGhlIG5ldyBwYXJhZ3JhcGggZnJvbSB0aGUgaW5pdGlhbCBjaGFuZ2UsIGFuZCBmaXJlIGEgc2ltdWxhdGVkXG4gICAgLy8gZW50ZXIga2V5IGFmdGVyd2FyZHMuXG4gICAgaWYgKGFuZHJvaWQgJiYgIWlubGluZUNoYW5nZSAmJiAkZnJvbS5zdGFydCgpICE9ICR0by5zdGFydCgpICYmICR0by5wYXJlbnRPZmZzZXQgPT0gMCAmJiAkZnJvbS5kZXB0aCA9PSAkdG8uZGVwdGggJiZcbiAgICAgICAgcGFyc2Uuc2VsICYmIHBhcnNlLnNlbC5hbmNob3IgPT0gcGFyc2Uuc2VsLmhlYWQgJiYgcGFyc2Uuc2VsLmhlYWQgPT0gY2hhbmdlLmVuZEEpIHtcbiAgICAgICAgY2hhbmdlLmVuZEIgLT0gMjtcbiAgICAgICAgJHRvID0gcGFyc2UuZG9jLnJlc29sdmVOb0NhY2hlKGNoYW5nZS5lbmRCIC0gcGFyc2UuZnJvbSk7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgdmlldy5zb21lUHJvcChcImhhbmRsZUtleURvd25cIiwgZnVuY3Rpb24gKGYpIHsgcmV0dXJuIGYodmlldywga2V5RXZlbnQoMTMsIFwiRW50ZXJcIikpOyB9KTtcbiAgICAgICAgfSwgMjApO1xuICAgIH1cbiAgICBsZXQgY2hGcm9tID0gY2hhbmdlLnN0YXJ0LCBjaFRvID0gY2hhbmdlLmVuZEE7XG4gICAgbGV0IHRyLCBzdG9yZWRNYXJrcywgbWFya0NoYW5nZTtcbiAgICBpZiAoaW5saW5lQ2hhbmdlKSB7XG4gICAgICAgIGlmICgkZnJvbS5wb3MgPT0gJHRvLnBvcykgeyAvLyBEZWxldGlvblxuICAgICAgICAgICAgLy8gSUUxMSBzb21ldGltZXMgd2VpcmRseSBtb3ZlcyB0aGUgRE9NIHNlbGVjdGlvbiBhcm91bmQgYWZ0ZXJcbiAgICAgICAgICAgIC8vIGJhY2tzcGFjaW5nIG91dCB0aGUgZmlyc3QgZWxlbWVudCBpbiBhIHRleHRibG9ja1xuICAgICAgICAgICAgaWYgKGllICYmIGllX3ZlcnNpb24gPD0gMTEgJiYgJGZyb20ucGFyZW50T2Zmc2V0ID09IDApIHtcbiAgICAgICAgICAgICAgICB2aWV3LmRvbU9ic2VydmVyLnN1cHByZXNzU2VsZWN0aW9uVXBkYXRlcygpO1xuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gc2VsZWN0aW9uVG9ET00odmlldyksIDIwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRyID0gdmlldy5zdGF0ZS50ci5kZWxldGUoY2hGcm9tLCBjaFRvKTtcbiAgICAgICAgICAgIHN0b3JlZE1hcmtzID0gZG9jLnJlc29sdmUoY2hhbmdlLnN0YXJ0KS5tYXJrc0Fjcm9zcyhkb2MucmVzb2x2ZShjaGFuZ2UuZW5kQSkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKCAvLyBBZGRpbmcgb3IgcmVtb3ZpbmcgYSBtYXJrXG4gICAgICAgIGNoYW5nZS5lbmRBID09IGNoYW5nZS5lbmRCICYmXG4gICAgICAgICAgICAobWFya0NoYW5nZSA9IGlzTWFya0NoYW5nZSgkZnJvbS5wYXJlbnQuY29udGVudC5jdXQoJGZyb20ucGFyZW50T2Zmc2V0LCAkdG8ucGFyZW50T2Zmc2V0KSwgJGZyb21BLnBhcmVudC5jb250ZW50LmN1dCgkZnJvbUEucGFyZW50T2Zmc2V0LCBjaGFuZ2UuZW5kQSAtICRmcm9tQS5zdGFydCgpKSkpKSB7XG4gICAgICAgICAgICB0ciA9IHZpZXcuc3RhdGUudHI7XG4gICAgICAgICAgICBpZiAobWFya0NoYW5nZS50eXBlID09IFwiYWRkXCIpXG4gICAgICAgICAgICAgICAgdHIuYWRkTWFyayhjaEZyb20sIGNoVG8sIG1hcmtDaGFuZ2UubWFyayk7XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgdHIucmVtb3ZlTWFyayhjaEZyb20sIGNoVG8sIG1hcmtDaGFuZ2UubWFyayk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoJGZyb20ucGFyZW50LmNoaWxkKCRmcm9tLmluZGV4KCkpLmlzVGV4dCAmJiAkZnJvbS5pbmRleCgpID09ICR0by5pbmRleCgpIC0gKCR0by50ZXh0T2Zmc2V0ID8gMCA6IDEpKSB7XG4gICAgICAgICAgICAvLyBCb3RoIHBvc2l0aW9ucyBpbiB0aGUgc2FtZSB0ZXh0IG5vZGUgLS0gc2ltcGx5IGluc2VydCB0ZXh0XG4gICAgICAgICAgICBsZXQgdGV4dCA9ICRmcm9tLnBhcmVudC50ZXh0QmV0d2VlbigkZnJvbS5wYXJlbnRPZmZzZXQsICR0by5wYXJlbnRPZmZzZXQpO1xuICAgICAgICAgICAgaWYgKHZpZXcuc29tZVByb3AoXCJoYW5kbGVUZXh0SW5wdXRcIiwgZiA9PiBmKHZpZXcsIGNoRnJvbSwgY2hUbywgdGV4dCkpKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIHRyID0gdmlldy5zdGF0ZS50ci5pbnNlcnRUZXh0KHRleHQsIGNoRnJvbSwgY2hUbyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKCF0cilcbiAgICAgICAgdHIgPSB2aWV3LnN0YXRlLnRyLnJlcGxhY2UoY2hGcm9tLCBjaFRvLCBwYXJzZS5kb2Muc2xpY2UoY2hhbmdlLnN0YXJ0IC0gcGFyc2UuZnJvbSwgY2hhbmdlLmVuZEIgLSBwYXJzZS5mcm9tKSk7XG4gICAgaWYgKHBhcnNlLnNlbCkge1xuICAgICAgICBsZXQgc2VsID0gcmVzb2x2ZVNlbGVjdGlvbih2aWV3LCB0ci5kb2MsIHBhcnNlLnNlbCk7XG4gICAgICAgIC8vIENocm9tZSB3aWxsIHNvbWV0aW1lcywgZHVyaW5nIGNvbXBvc2l0aW9uLCByZXBvcnQgdGhlXG4gICAgICAgIC8vIHNlbGVjdGlvbiBpbiB0aGUgd3JvbmcgcGxhY2UuIElmIGl0IGxvb2tzIGxpa2UgdGhhdCBpc1xuICAgICAgICAvLyBoYXBwZW5pbmcsIGRvbid0IHVwZGF0ZSB0aGUgc2VsZWN0aW9uLlxuICAgICAgICAvLyBFZGdlIGp1c3QgZG9lc24ndCBtb3ZlIHRoZSBjdXJzb3IgZm9yd2FyZCB3aGVuIHlvdSBzdGFydCB0eXBpbmdcbiAgICAgICAgLy8gaW4gYW4gZW1wdHkgYmxvY2sgb3IgYmV0d2VlbiBiciBub2Rlcy5cbiAgICAgICAgaWYgKHNlbCAmJiAhKGNocm9tZSAmJiB2aWV3LmNvbXBvc2luZyAmJiBzZWwuZW1wdHkgJiZcbiAgICAgICAgICAgIChjaGFuZ2Uuc3RhcnQgIT0gY2hhbmdlLmVuZEIgfHwgdmlldy5pbnB1dC5sYXN0Q2hyb21lRGVsZXRlIDwgRGF0ZS5ub3coKSAtIDEwMCkgJiZcbiAgICAgICAgICAgIChzZWwuaGVhZCA9PSBjaEZyb20gfHwgc2VsLmhlYWQgPT0gdHIubWFwcGluZy5tYXAoY2hUbykgLSAxKSB8fFxuICAgICAgICAgICAgaWUgJiYgc2VsLmVtcHR5ICYmIHNlbC5oZWFkID09IGNoRnJvbSkpXG4gICAgICAgICAgICB0ci5zZXRTZWxlY3Rpb24oc2VsKTtcbiAgICB9XG4gICAgaWYgKHN0b3JlZE1hcmtzKVxuICAgICAgICB0ci5lbnN1cmVNYXJrcyhzdG9yZWRNYXJrcyk7XG4gICAgaWYgKGNvbXBvc2l0aW9uSUQpXG4gICAgICAgIHRyLnNldE1ldGEoXCJjb21wb3NpdGlvblwiLCBjb21wb3NpdGlvbklEKTtcbiAgICB2aWV3LmRpc3BhdGNoKHRyLnNjcm9sbEludG9WaWV3KCkpO1xufVxuZnVuY3Rpb24gcmVzb2x2ZVNlbGVjdGlvbih2aWV3LCBkb2MsIHBhcnNlZFNlbCkge1xuICAgIGlmIChNYXRoLm1heChwYXJzZWRTZWwuYW5jaG9yLCBwYXJzZWRTZWwuaGVhZCkgPiBkb2MuY29udGVudC5zaXplKVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4gc2VsZWN0aW9uQmV0d2Vlbih2aWV3LCBkb2MucmVzb2x2ZShwYXJzZWRTZWwuYW5jaG9yKSwgZG9jLnJlc29sdmUocGFyc2VkU2VsLmhlYWQpKTtcbn1cbi8vIEdpdmVuIHR3byBzYW1lLWxlbmd0aCwgbm9uLWVtcHR5IGZyYWdtZW50cyBvZiBpbmxpbmUgY29udGVudCxcbi8vIGRldGVybWluZSB3aGV0aGVyIHRoZSBmaXJzdCBjb3VsZCBiZSBjcmVhdGVkIGZyb20gdGhlIHNlY29uZCBieVxuLy8gcmVtb3Zpbmcgb3IgYWRkaW5nIGEgc2luZ2xlIG1hcmsgdHlwZS5cbmZ1bmN0aW9uIGlzTWFya0NoYW5nZShjdXIsIHByZXYpIHtcbiAgICBsZXQgY3VyTWFya3MgPSBjdXIuZmlyc3RDaGlsZC5tYXJrcywgcHJldk1hcmtzID0gcHJldi5maXJzdENoaWxkLm1hcmtzO1xuICAgIGxldCBhZGRlZCA9IGN1ck1hcmtzLCByZW1vdmVkID0gcHJldk1hcmtzLCB0eXBlLCBtYXJrLCB1cGRhdGU7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwcmV2TWFya3MubGVuZ3RoOyBpKyspXG4gICAgICAgIGFkZGVkID0gcHJldk1hcmtzW2ldLnJlbW92ZUZyb21TZXQoYWRkZWQpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY3VyTWFya3MubGVuZ3RoOyBpKyspXG4gICAgICAgIHJlbW92ZWQgPSBjdXJNYXJrc1tpXS5yZW1vdmVGcm9tU2V0KHJlbW92ZWQpO1xuICAgIGlmIChhZGRlZC5sZW5ndGggPT0gMSAmJiByZW1vdmVkLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgIG1hcmsgPSBhZGRlZFswXTtcbiAgICAgICAgdHlwZSA9IFwiYWRkXCI7XG4gICAgICAgIHVwZGF0ZSA9IChub2RlKSA9PiBub2RlLm1hcmsobWFyay5hZGRUb1NldChub2RlLm1hcmtzKSk7XG4gICAgfVxuICAgIGVsc2UgaWYgKGFkZGVkLmxlbmd0aCA9PSAwICYmIHJlbW92ZWQubGVuZ3RoID09IDEpIHtcbiAgICAgICAgbWFyayA9IHJlbW92ZWRbMF07XG4gICAgICAgIHR5cGUgPSBcInJlbW92ZVwiO1xuICAgICAgICB1cGRhdGUgPSAobm9kZSkgPT4gbm9kZS5tYXJrKG1hcmsucmVtb3ZlRnJvbVNldChub2RlLm1hcmtzKSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgbGV0IHVwZGF0ZWQgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHByZXYuY2hpbGRDb3VudDsgaSsrKVxuICAgICAgICB1cGRhdGVkLnB1c2godXBkYXRlKHByZXYuY2hpbGQoaSkpKTtcbiAgICBpZiAoRnJhZ21lbnQuZnJvbSh1cGRhdGVkKS5lcShjdXIpKVxuICAgICAgICByZXR1cm4geyBtYXJrLCB0eXBlIH07XG59XG5mdW5jdGlvbiBsb29rc0xpa2VCYWNrc3BhY2Uob2xkLCBzdGFydCwgZW5kLCAkbmV3U3RhcnQsICRuZXdFbmQpIHtcbiAgICBpZiAoIC8vIFRoZSBjb250ZW50IG11c3QgaGF2ZSBzaHJ1bmtcbiAgICBlbmQgLSBzdGFydCA8PSAkbmV3RW5kLnBvcyAtICRuZXdTdGFydC5wb3MgfHxcbiAgICAgICAgLy8gbmV3RW5kIG11c3QgcG9pbnQgZGlyZWN0bHkgYXQgb3IgYWZ0ZXIgdGhlIGVuZCBvZiB0aGUgYmxvY2sgdGhhdCBuZXdTdGFydCBwb2ludHMgaW50b1xuICAgICAgICBza2lwQ2xvc2luZ0FuZE9wZW5pbmcoJG5ld1N0YXJ0LCB0cnVlLCBmYWxzZSkgPCAkbmV3RW5kLnBvcylcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGxldCAkc3RhcnQgPSBvbGQucmVzb2x2ZShzdGFydCk7XG4gICAgLy8gSGFuZGxlIHRoZSBjYXNlIHdoZXJlLCByYXRoZXIgdGhhbiBqb2luaW5nIGJsb2NrcywgdGhlIGNoYW5nZSBqdXN0IHJlbW92ZWQgYW4gZW50aXJlIGJsb2NrXG4gICAgaWYgKCEkbmV3U3RhcnQucGFyZW50LmlzVGV4dGJsb2NrKSB7XG4gICAgICAgIGxldCBhZnRlciA9ICRzdGFydC5ub2RlQWZ0ZXI7XG4gICAgICAgIHJldHVybiBhZnRlciAhPSBudWxsICYmIGVuZCA9PSBzdGFydCArIGFmdGVyLm5vZGVTaXplO1xuICAgIH1cbiAgICAvLyBTdGFydCBtdXN0IGJlIGF0IHRoZSBlbmQgb2YgYSBibG9ja1xuICAgIGlmICgkc3RhcnQucGFyZW50T2Zmc2V0IDwgJHN0YXJ0LnBhcmVudC5jb250ZW50LnNpemUgfHwgISRzdGFydC5wYXJlbnQuaXNUZXh0YmxvY2spXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICBsZXQgJG5leHQgPSBvbGQucmVzb2x2ZShza2lwQ2xvc2luZ0FuZE9wZW5pbmcoJHN0YXJ0LCB0cnVlLCB0cnVlKSk7XG4gICAgLy8gVGhlIG5leHQgdGV4dGJsb2NrIG11c3Qgc3RhcnQgYmVmb3JlIGVuZCBhbmQgZW5kIG5lYXIgaXRcbiAgICBpZiAoISRuZXh0LnBhcmVudC5pc1RleHRibG9jayB8fCAkbmV4dC5wb3MgPiBlbmQgfHxcbiAgICAgICAgc2tpcENsb3NpbmdBbmRPcGVuaW5nKCRuZXh0LCB0cnVlLCBmYWxzZSkgPCBlbmQpXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAvLyBUaGUgZnJhZ21lbnRzIGFmdGVyIHRoZSBqb2luIHBvaW50IG11c3QgbWF0Y2hcbiAgICByZXR1cm4gJG5ld1N0YXJ0LnBhcmVudC5jb250ZW50LmN1dCgkbmV3U3RhcnQucGFyZW50T2Zmc2V0KS5lcSgkbmV4dC5wYXJlbnQuY29udGVudCk7XG59XG5mdW5jdGlvbiBza2lwQ2xvc2luZ0FuZE9wZW5pbmcoJHBvcywgZnJvbUVuZCwgbWF5T3Blbikge1xuICAgIGxldCBkZXB0aCA9ICRwb3MuZGVwdGgsIGVuZCA9IGZyb21FbmQgPyAkcG9zLmVuZCgpIDogJHBvcy5wb3M7XG4gICAgd2hpbGUgKGRlcHRoID4gMCAmJiAoZnJvbUVuZCB8fCAkcG9zLmluZGV4QWZ0ZXIoZGVwdGgpID09ICRwb3Mubm9kZShkZXB0aCkuY2hpbGRDb3VudCkpIHtcbiAgICAgICAgZGVwdGgtLTtcbiAgICAgICAgZW5kKys7XG4gICAgICAgIGZyb21FbmQgPSBmYWxzZTtcbiAgICB9XG4gICAgaWYgKG1heU9wZW4pIHtcbiAgICAgICAgbGV0IG5leHQgPSAkcG9zLm5vZGUoZGVwdGgpLm1heWJlQ2hpbGQoJHBvcy5pbmRleEFmdGVyKGRlcHRoKSk7XG4gICAgICAgIHdoaWxlIChuZXh0ICYmICFuZXh0LmlzTGVhZikge1xuICAgICAgICAgICAgbmV4dCA9IG5leHQuZmlyc3RDaGlsZDtcbiAgICAgICAgICAgIGVuZCsrO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBlbmQ7XG59XG5mdW5jdGlvbiBmaW5kRGlmZihhLCBiLCBwb3MsIHByZWZlcnJlZFBvcywgcHJlZmVycmVkU2lkZSkge1xuICAgIGxldCBzdGFydCA9IGEuZmluZERpZmZTdGFydChiLCBwb3MpO1xuICAgIGlmIChzdGFydCA9PSBudWxsKVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICBsZXQgeyBhOiBlbmRBLCBiOiBlbmRCIH0gPSBhLmZpbmREaWZmRW5kKGIsIHBvcyArIGEuc2l6ZSwgcG9zICsgYi5zaXplKTtcbiAgICBpZiAocHJlZmVycmVkU2lkZSA9PSBcImVuZFwiKSB7XG4gICAgICAgIGxldCBhZGp1c3QgPSBNYXRoLm1heCgwLCBzdGFydCAtIE1hdGgubWluKGVuZEEsIGVuZEIpKTtcbiAgICAgICAgcHJlZmVycmVkUG9zIC09IGVuZEEgKyBhZGp1c3QgLSBzdGFydDtcbiAgICB9XG4gICAgaWYgKGVuZEEgPCBzdGFydCAmJiBhLnNpemUgPCBiLnNpemUpIHtcbiAgICAgICAgbGV0IG1vdmUgPSBwcmVmZXJyZWRQb3MgPD0gc3RhcnQgJiYgcHJlZmVycmVkUG9zID49IGVuZEEgPyBzdGFydCAtIHByZWZlcnJlZFBvcyA6IDA7XG4gICAgICAgIHN0YXJ0IC09IG1vdmU7XG4gICAgICAgIGlmIChzdGFydCAmJiBzdGFydCA8IGIuc2l6ZSAmJiBpc1N1cnJvZ2F0ZVBhaXIoYi50ZXh0QmV0d2VlbihzdGFydCAtIDEsIHN0YXJ0ICsgMSkpKVxuICAgICAgICAgICAgc3RhcnQgKz0gbW92ZSA/IDEgOiAtMTtcbiAgICAgICAgZW5kQiA9IHN0YXJ0ICsgKGVuZEIgLSBlbmRBKTtcbiAgICAgICAgZW5kQSA9IHN0YXJ0O1xuICAgIH1cbiAgICBlbHNlIGlmIChlbmRCIDwgc3RhcnQpIHtcbiAgICAgICAgbGV0IG1vdmUgPSBwcmVmZXJyZWRQb3MgPD0gc3RhcnQgJiYgcHJlZmVycmVkUG9zID49IGVuZEIgPyBzdGFydCAtIHByZWZlcnJlZFBvcyA6IDA7XG4gICAgICAgIHN0YXJ0IC09IG1vdmU7XG4gICAgICAgIGlmIChzdGFydCAmJiBzdGFydCA8IGEuc2l6ZSAmJiBpc1N1cnJvZ2F0ZVBhaXIoYS50ZXh0QmV0d2VlbihzdGFydCAtIDEsIHN0YXJ0ICsgMSkpKVxuICAgICAgICAgICAgc3RhcnQgKz0gbW92ZSA/IDEgOiAtMTtcbiAgICAgICAgZW5kQSA9IHN0YXJ0ICsgKGVuZEEgLSBlbmRCKTtcbiAgICAgICAgZW5kQiA9IHN0YXJ0O1xuICAgIH1cbiAgICByZXR1cm4geyBzdGFydCwgZW5kQSwgZW5kQiB9O1xufVxuZnVuY3Rpb24gaXNTdXJyb2dhdGVQYWlyKHN0cikge1xuICAgIGlmIChzdHIubGVuZ3RoICE9IDIpXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICBsZXQgYSA9IHN0ci5jaGFyQ29kZUF0KDApLCBiID0gc3RyLmNoYXJDb2RlQXQoMSk7XG4gICAgcmV0dXJuIGEgPj0gMHhEQzAwICYmIGEgPD0gMHhERkZGICYmIGIgPj0gMHhEODAwICYmIGIgPD0gMHhEQkZGO1xufVxuXG4vKipcbkBpbnRlcm5hbFxuKi9cbmNvbnN0IF9fcGFyc2VGcm9tQ2xpcGJvYXJkID0gcGFyc2VGcm9tQ2xpcGJvYXJkO1xuLyoqXG5AaW50ZXJuYWxcbiovXG5jb25zdCBfX2VuZENvbXBvc2l0aW9uID0gZW5kQ29tcG9zaXRpb247XG4vKipcbkFuIGVkaXRvciB2aWV3IG1hbmFnZXMgdGhlIERPTSBzdHJ1Y3R1cmUgdGhhdCByZXByZXNlbnRzIGFuXG5lZGl0YWJsZSBkb2N1bWVudC4gSXRzIHN0YXRlIGFuZCBiZWhhdmlvciBhcmUgZGV0ZXJtaW5lZCBieSBpdHNcbltwcm9wc10oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3ZpZXcuRGlyZWN0RWRpdG9yUHJvcHMpLlxuKi9cbmNsYXNzIEVkaXRvclZpZXcge1xuICAgIC8qKlxuICAgIENyZWF0ZSBhIHZpZXcuIGBwbGFjZWAgbWF5IGJlIGEgRE9NIG5vZGUgdGhhdCB0aGUgZWRpdG9yIHNob3VsZFxuICAgIGJlIGFwcGVuZGVkIHRvLCBhIGZ1bmN0aW9uIHRoYXQgd2lsbCBwbGFjZSBpdCBpbnRvIHRoZSBkb2N1bWVudCxcbiAgICBvciBhbiBvYmplY3Qgd2hvc2UgYG1vdW50YCBwcm9wZXJ0eSBob2xkcyB0aGUgbm9kZSB0byB1c2UgYXMgdGhlXG4gICAgZG9jdW1lbnQgY29udGFpbmVyLiBJZiBpdCBpcyBgbnVsbGAsIHRoZSBlZGl0b3Igd2lsbCBub3QgYmVcbiAgICBhZGRlZCB0byB0aGUgZG9jdW1lbnQuXG4gICAgKi9cbiAgICBjb25zdHJ1Y3RvcihwbGFjZSwgcHJvcHMpIHtcbiAgICAgICAgdGhpcy5fcm9vdCA9IG51bGw7XG4gICAgICAgIC8qKlxuICAgICAgICBAaW50ZXJuYWxcbiAgICAgICAgKi9cbiAgICAgICAgdGhpcy5mb2N1c2VkID0gZmFsc2U7XG4gICAgICAgIC8qKlxuICAgICAgICBLbHVkZ2UgdXNlZCB0byB3b3JrIGFyb3VuZCBhIENocm9tZSBidWcgQGludGVybmFsXG4gICAgICAgICovXG4gICAgICAgIHRoaXMudHJhY2tXcml0ZXMgPSBudWxsO1xuICAgICAgICB0aGlzLm1vdW50ZWQgPSBmYWxzZTtcbiAgICAgICAgLyoqXG4gICAgICAgIEBpbnRlcm5hbFxuICAgICAgICAqL1xuICAgICAgICB0aGlzLm1hcmtDdXJzb3IgPSBudWxsO1xuICAgICAgICAvKipcbiAgICAgICAgQGludGVybmFsXG4gICAgICAgICovXG4gICAgICAgIHRoaXMuY3Vyc29yV3JhcHBlciA9IG51bGw7XG4gICAgICAgIC8qKlxuICAgICAgICBAaW50ZXJuYWxcbiAgICAgICAgKi9cbiAgICAgICAgdGhpcy5sYXN0U2VsZWN0ZWRWaWV3RGVzYyA9IHVuZGVmaW5lZDtcbiAgICAgICAgLyoqXG4gICAgICAgIEBpbnRlcm5hbFxuICAgICAgICAqL1xuICAgICAgICB0aGlzLmlucHV0ID0gbmV3IElucHV0U3RhdGU7XG4gICAgICAgIHRoaXMucHJldkRpcmVjdFBsdWdpbnMgPSBbXTtcbiAgICAgICAgdGhpcy5wbHVnaW5WaWV3cyA9IFtdO1xuICAgICAgICAvKipcbiAgICAgICAgSG9sZHMgYHRydWVgIHdoZW4gYSBoYWNrIG5vZGUgaXMgbmVlZGVkIGluIEZpcmVmb3ggdG8gcHJldmVudCB0aGVcbiAgICAgICAgW3NwYWNlIGlzIGVhdGVuIGlzc3VlXShodHRwczovL2dpdGh1Yi5jb20vUHJvc2VNaXJyb3IvcHJvc2VtaXJyb3IvaXNzdWVzLzY1MSlcbiAgICAgICAgQGludGVybmFsXG4gICAgICAgICovXG4gICAgICAgIHRoaXMucmVxdWlyZXNHZWNrb0hhY2tOb2RlID0gZmFsc2U7XG4gICAgICAgIC8qKlxuICAgICAgICBXaGVuIGVkaXRvciBjb250ZW50IGlzIGJlaW5nIGRyYWdnZWQsIHRoaXMgb2JqZWN0IGNvbnRhaW5zXG4gICAgICAgIGluZm9ybWF0aW9uIGFib3V0IHRoZSBkcmFnZ2VkIHNsaWNlIGFuZCB3aGV0aGVyIGl0IGlzIGJlaW5nXG4gICAgICAgIGNvcGllZCBvciBtb3ZlZC4gQXQgYW55IG90aGVyIHRpbWUsIGl0IGlzIG51bGwuXG4gICAgICAgICovXG4gICAgICAgIHRoaXMuZHJhZ2dpbmcgPSBudWxsO1xuICAgICAgICB0aGlzLl9wcm9wcyA9IHByb3BzO1xuICAgICAgICB0aGlzLnN0YXRlID0gcHJvcHMuc3RhdGU7XG4gICAgICAgIHRoaXMuZGlyZWN0UGx1Z2lucyA9IHByb3BzLnBsdWdpbnMgfHwgW107XG4gICAgICAgIHRoaXMuZGlyZWN0UGx1Z2lucy5mb3JFYWNoKGNoZWNrU3RhdGVDb21wb25lbnQpO1xuICAgICAgICB0aGlzLmRpc3BhdGNoID0gdGhpcy5kaXNwYXRjaC5iaW5kKHRoaXMpO1xuICAgICAgICB0aGlzLmRvbSA9IChwbGFjZSAmJiBwbGFjZS5tb3VudCkgfHwgZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgICAgICAgaWYgKHBsYWNlKSB7XG4gICAgICAgICAgICBpZiAocGxhY2UuYXBwZW5kQ2hpbGQpXG4gICAgICAgICAgICAgICAgcGxhY2UuYXBwZW5kQ2hpbGQodGhpcy5kb20pO1xuICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIHBsYWNlID09IFwiZnVuY3Rpb25cIilcbiAgICAgICAgICAgICAgICBwbGFjZSh0aGlzLmRvbSk7XG4gICAgICAgICAgICBlbHNlIGlmIChwbGFjZS5tb3VudClcbiAgICAgICAgICAgICAgICB0aGlzLm1vdW50ZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZWRpdGFibGUgPSBnZXRFZGl0YWJsZSh0aGlzKTtcbiAgICAgICAgdXBkYXRlQ3Vyc29yV3JhcHBlcih0aGlzKTtcbiAgICAgICAgdGhpcy5ub2RlVmlld3MgPSBidWlsZE5vZGVWaWV3cyh0aGlzKTtcbiAgICAgICAgdGhpcy5kb2NWaWV3ID0gZG9jVmlld0Rlc2ModGhpcy5zdGF0ZS5kb2MsIGNvbXB1dGVEb2NEZWNvKHRoaXMpLCB2aWV3RGVjb3JhdGlvbnModGhpcyksIHRoaXMuZG9tLCB0aGlzKTtcbiAgICAgICAgdGhpcy5kb21PYnNlcnZlciA9IG5ldyBET01PYnNlcnZlcih0aGlzLCAoZnJvbSwgdG8sIHR5cGVPdmVyLCBhZGRlZCkgPT4gcmVhZERPTUNoYW5nZSh0aGlzLCBmcm9tLCB0bywgdHlwZU92ZXIsIGFkZGVkKSk7XG4gICAgICAgIHRoaXMuZG9tT2JzZXJ2ZXIuc3RhcnQoKTtcbiAgICAgICAgaW5pdElucHV0KHRoaXMpO1xuICAgICAgICB0aGlzLnVwZGF0ZVBsdWdpblZpZXdzKCk7XG4gICAgfVxuICAgIC8qKlxuICAgIEhvbGRzIGB0cnVlYCB3aGVuIGFcbiAgICBbY29tcG9zaXRpb25dKGh0dHBzOi8vdzNjLmdpdGh1Yi5pby91aWV2ZW50cy8jZXZlbnRzLWNvbXBvc2l0aW9uZXZlbnRzKVxuICAgIGlzIGFjdGl2ZS5cbiAgICAqL1xuICAgIGdldCBjb21wb3NpbmcoKSB7IHJldHVybiB0aGlzLmlucHV0LmNvbXBvc2luZzsgfVxuICAgIC8qKlxuICAgIFRoZSB2aWV3J3MgY3VycmVudCBbcHJvcHNdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyN2aWV3LkVkaXRvclByb3BzKS5cbiAgICAqL1xuICAgIGdldCBwcm9wcygpIHtcbiAgICAgICAgaWYgKHRoaXMuX3Byb3BzLnN0YXRlICE9IHRoaXMuc3RhdGUpIHtcbiAgICAgICAgICAgIGxldCBwcmV2ID0gdGhpcy5fcHJvcHM7XG4gICAgICAgICAgICB0aGlzLl9wcm9wcyA9IHt9O1xuICAgICAgICAgICAgZm9yIChsZXQgbmFtZSBpbiBwcmV2KVxuICAgICAgICAgICAgICAgIHRoaXMuX3Byb3BzW25hbWVdID0gcHJldltuYW1lXTtcbiAgICAgICAgICAgIHRoaXMuX3Byb3BzLnN0YXRlID0gdGhpcy5zdGF0ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fcHJvcHM7XG4gICAgfVxuICAgIC8qKlxuICAgIFVwZGF0ZSB0aGUgdmlldydzIHByb3BzLiBXaWxsIGltbWVkaWF0ZWx5IGNhdXNlIGFuIHVwZGF0ZSB0b1xuICAgIHRoZSBET00uXG4gICAgKi9cbiAgICB1cGRhdGUocHJvcHMpIHtcbiAgICAgICAgaWYgKHByb3BzLmhhbmRsZURPTUV2ZW50cyAhPSB0aGlzLl9wcm9wcy5oYW5kbGVET01FdmVudHMpXG4gICAgICAgICAgICBlbnN1cmVMaXN0ZW5lcnModGhpcyk7XG4gICAgICAgIGxldCBwcmV2UHJvcHMgPSB0aGlzLl9wcm9wcztcbiAgICAgICAgdGhpcy5fcHJvcHMgPSBwcm9wcztcbiAgICAgICAgaWYgKHByb3BzLnBsdWdpbnMpIHtcbiAgICAgICAgICAgIHByb3BzLnBsdWdpbnMuZm9yRWFjaChjaGVja1N0YXRlQ29tcG9uZW50KTtcbiAgICAgICAgICAgIHRoaXMuZGlyZWN0UGx1Z2lucyA9IHByb3BzLnBsdWdpbnM7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy51cGRhdGVTdGF0ZUlubmVyKHByb3BzLnN0YXRlLCBwcmV2UHJvcHMpO1xuICAgIH1cbiAgICAvKipcbiAgICBVcGRhdGUgdGhlIHZpZXcgYnkgdXBkYXRpbmcgZXhpc3RpbmcgcHJvcHMgb2JqZWN0IHdpdGggdGhlIG9iamVjdFxuICAgIGdpdmVuIGFzIGFyZ3VtZW50LiBFcXVpdmFsZW50IHRvIGB2aWV3LnVwZGF0ZShPYmplY3QuYXNzaWduKHt9LFxuICAgIHZpZXcucHJvcHMsIHByb3BzKSlgLlxuICAgICovXG4gICAgc2V0UHJvcHMocHJvcHMpIHtcbiAgICAgICAgbGV0IHVwZGF0ZWQgPSB7fTtcbiAgICAgICAgZm9yIChsZXQgbmFtZSBpbiB0aGlzLl9wcm9wcylcbiAgICAgICAgICAgIHVwZGF0ZWRbbmFtZV0gPSB0aGlzLl9wcm9wc1tuYW1lXTtcbiAgICAgICAgdXBkYXRlZC5zdGF0ZSA9IHRoaXMuc3RhdGU7XG4gICAgICAgIGZvciAobGV0IG5hbWUgaW4gcHJvcHMpXG4gICAgICAgICAgICB1cGRhdGVkW25hbWVdID0gcHJvcHNbbmFtZV07XG4gICAgICAgIHRoaXMudXBkYXRlKHVwZGF0ZWQpO1xuICAgIH1cbiAgICAvKipcbiAgICBVcGRhdGUgdGhlIGVkaXRvcidzIGBzdGF0ZWAgcHJvcCwgd2l0aG91dCB0b3VjaGluZyBhbnkgb2YgdGhlXG4gICAgb3RoZXIgcHJvcHMuXG4gICAgKi9cbiAgICB1cGRhdGVTdGF0ZShzdGF0ZSkge1xuICAgICAgICB0aGlzLnVwZGF0ZVN0YXRlSW5uZXIoc3RhdGUsIHRoaXMuX3Byb3BzKTtcbiAgICB9XG4gICAgdXBkYXRlU3RhdGVJbm5lcihzdGF0ZSwgcHJldlByb3BzKSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgbGV0IHByZXYgPSB0aGlzLnN0YXRlLCByZWRyYXcgPSBmYWxzZSwgdXBkYXRlU2VsID0gZmFsc2U7XG4gICAgICAgIC8vIFdoZW4gc3RvcmVkIG1hcmtzIGFyZSBhZGRlZCwgc3RvcCBjb21wb3NpdGlvbiwgc28gdGhhdCB0aGV5IGNhblxuICAgICAgICAvLyBiZSBkaXNwbGF5ZWQuXG4gICAgICAgIGlmIChzdGF0ZS5zdG9yZWRNYXJrcyAmJiB0aGlzLmNvbXBvc2luZykge1xuICAgICAgICAgICAgY2xlYXJDb21wb3NpdGlvbih0aGlzKTtcbiAgICAgICAgICAgIHVwZGF0ZVNlbCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zdGF0ZSA9IHN0YXRlO1xuICAgICAgICBsZXQgcGx1Z2luc0NoYW5nZWQgPSBwcmV2LnBsdWdpbnMgIT0gc3RhdGUucGx1Z2lucyB8fCB0aGlzLl9wcm9wcy5wbHVnaW5zICE9IHByZXZQcm9wcy5wbHVnaW5zO1xuICAgICAgICBpZiAocGx1Z2luc0NoYW5nZWQgfHwgdGhpcy5fcHJvcHMucGx1Z2lucyAhPSBwcmV2UHJvcHMucGx1Z2lucyB8fCB0aGlzLl9wcm9wcy5ub2RlVmlld3MgIT0gcHJldlByb3BzLm5vZGVWaWV3cykge1xuICAgICAgICAgICAgbGV0IG5vZGVWaWV3cyA9IGJ1aWxkTm9kZVZpZXdzKHRoaXMpO1xuICAgICAgICAgICAgaWYgKGNoYW5nZWROb2RlVmlld3Mobm9kZVZpZXdzLCB0aGlzLm5vZGVWaWV3cykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm5vZGVWaWV3cyA9IG5vZGVWaWV3cztcbiAgICAgICAgICAgICAgICByZWRyYXcgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChwbHVnaW5zQ2hhbmdlZCB8fCBwcmV2UHJvcHMuaGFuZGxlRE9NRXZlbnRzICE9IHRoaXMuX3Byb3BzLmhhbmRsZURPTUV2ZW50cykge1xuICAgICAgICAgICAgZW5zdXJlTGlzdGVuZXJzKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZWRpdGFibGUgPSBnZXRFZGl0YWJsZSh0aGlzKTtcbiAgICAgICAgdXBkYXRlQ3Vyc29yV3JhcHBlcih0aGlzKTtcbiAgICAgICAgbGV0IGlubmVyRGVjbyA9IHZpZXdEZWNvcmF0aW9ucyh0aGlzKSwgb3V0ZXJEZWNvID0gY29tcHV0ZURvY0RlY28odGhpcyk7XG4gICAgICAgIGxldCBzY3JvbGwgPSBwcmV2LnBsdWdpbnMgIT0gc3RhdGUucGx1Z2lucyAmJiAhcHJldi5kb2MuZXEoc3RhdGUuZG9jKSA/IFwicmVzZXRcIlxuICAgICAgICAgICAgOiBzdGF0ZS5zY3JvbGxUb1NlbGVjdGlvbiA+IHByZXYuc2Nyb2xsVG9TZWxlY3Rpb24gPyBcInRvIHNlbGVjdGlvblwiIDogXCJwcmVzZXJ2ZVwiO1xuICAgICAgICBsZXQgdXBkYXRlRG9jID0gcmVkcmF3IHx8ICF0aGlzLmRvY1ZpZXcubWF0Y2hlc05vZGUoc3RhdGUuZG9jLCBvdXRlckRlY28sIGlubmVyRGVjbyk7XG4gICAgICAgIGlmICh1cGRhdGVEb2MgfHwgIXN0YXRlLnNlbGVjdGlvbi5lcShwcmV2LnNlbGVjdGlvbikpXG4gICAgICAgICAgICB1cGRhdGVTZWwgPSB0cnVlO1xuICAgICAgICBsZXQgb2xkU2Nyb2xsUG9zID0gc2Nyb2xsID09IFwicHJlc2VydmVcIiAmJiB1cGRhdGVTZWwgJiYgdGhpcy5kb20uc3R5bGUub3ZlcmZsb3dBbmNob3IgPT0gbnVsbCAmJiBzdG9yZVNjcm9sbFBvcyh0aGlzKTtcbiAgICAgICAgaWYgKHVwZGF0ZVNlbCkge1xuICAgICAgICAgICAgdGhpcy5kb21PYnNlcnZlci5zdG9wKCk7XG4gICAgICAgICAgICAvLyBXb3JrIGFyb3VuZCBhbiBpc3N1ZSBpbiBDaHJvbWUsIElFLCBhbmQgRWRnZSB3aGVyZSBjaGFuZ2luZ1xuICAgICAgICAgICAgLy8gdGhlIERPTSBhcm91bmQgYW4gYWN0aXZlIHNlbGVjdGlvbiBwdXRzIGl0IGludG8gYSBicm9rZW5cbiAgICAgICAgICAgIC8vIHN0YXRlIHdoZXJlIHRoZSB0aGluZyB0aGUgdXNlciBzZWVzIGRpZmZlcnMgZnJvbSB0aGVcbiAgICAgICAgICAgIC8vIHNlbGVjdGlvbiByZXBvcnRlZCBieSB0aGUgU2VsZWN0aW9uIG9iamVjdCAoIzcxMCwgIzk3MyxcbiAgICAgICAgICAgIC8vICMxMDExLCAjMTAxMywgIzEwMzUpLlxuICAgICAgICAgICAgbGV0IGZvcmNlU2VsVXBkYXRlID0gdXBkYXRlRG9jICYmIChpZSB8fCBjaHJvbWUpICYmICF0aGlzLmNvbXBvc2luZyAmJlxuICAgICAgICAgICAgICAgICFwcmV2LnNlbGVjdGlvbi5lbXB0eSAmJiAhc3RhdGUuc2VsZWN0aW9uLmVtcHR5ICYmIHNlbGVjdGlvbkNvbnRleHRDaGFuZ2VkKHByZXYuc2VsZWN0aW9uLCBzdGF0ZS5zZWxlY3Rpb24pO1xuICAgICAgICAgICAgaWYgKHVwZGF0ZURvYykge1xuICAgICAgICAgICAgICAgIC8vIElmIHRoZSBub2RlIHRoYXQgdGhlIHNlbGVjdGlvbiBwb2ludHMgaW50byBpcyB3cml0dGVuIHRvLFxuICAgICAgICAgICAgICAgIC8vIENocm9tZSBzb21ldGltZXMgc3RhcnRzIG1pc3JlcG9ydGluZyB0aGUgc2VsZWN0aW9uLCBzbyB0aGlzXG4gICAgICAgICAgICAgICAgLy8gdHJhY2tzIHRoYXQgYW5kIGZvcmNlcyBhIHNlbGVjdGlvbiByZXNldCB3aGVuIG91ciB1cGRhdGVcbiAgICAgICAgICAgICAgICAvLyBkaWQgd3JpdGUgdG8gdGhlIG5vZGUuXG4gICAgICAgICAgICAgICAgbGV0IGNocm9tZUtsdWRnZSA9IGNocm9tZSA/ICh0aGlzLnRyYWNrV3JpdGVzID0gdGhpcy5kb21TZWxlY3Rpb25SYW5nZSgpLmZvY3VzTm9kZSkgOiBudWxsO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbXBvc2luZylcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pbnB1dC5jb21wb3NpdGlvbk5vZGUgPSBmaW5kQ29tcG9zaXRpb25Ob2RlKHRoaXMpO1xuICAgICAgICAgICAgICAgIGlmIChyZWRyYXcgfHwgIXRoaXMuZG9jVmlldy51cGRhdGUoc3RhdGUuZG9jLCBvdXRlckRlY28sIGlubmVyRGVjbywgdGhpcykpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kb2NWaWV3LnVwZGF0ZU91dGVyRGVjbyhvdXRlckRlY28pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRvY1ZpZXcuZGVzdHJveSgpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRvY1ZpZXcgPSBkb2NWaWV3RGVzYyhzdGF0ZS5kb2MsIG91dGVyRGVjbywgaW5uZXJEZWNvLCB0aGlzLmRvbSwgdGhpcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChjaHJvbWVLbHVkZ2UgJiYgIXRoaXMudHJhY2tXcml0ZXMpXG4gICAgICAgICAgICAgICAgICAgIGZvcmNlU2VsVXBkYXRlID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFdvcmsgYXJvdW5kIGZvciBhbiBpc3N1ZSB3aGVyZSBhbiB1cGRhdGUgYXJyaXZpbmcgcmlnaHQgYmV0d2VlblxuICAgICAgICAgICAgLy8gYSBET00gc2VsZWN0aW9uIGNoYW5nZSBhbmQgdGhlIFwic2VsZWN0aW9uY2hhbmdlXCIgZXZlbnQgZm9yIGl0XG4gICAgICAgICAgICAvLyBjYW4gY2F1c2UgYSBzcHVyaW91cyBET00gc2VsZWN0aW9uIHVwZGF0ZSwgZGlzcnVwdGluZyBtb3VzZVxuICAgICAgICAgICAgLy8gZHJhZyBzZWxlY3Rpb24uXG4gICAgICAgICAgICBpZiAoZm9yY2VTZWxVcGRhdGUgfHxcbiAgICAgICAgICAgICAgICAhKHRoaXMuaW5wdXQubW91c2VEb3duICYmIHRoaXMuZG9tT2JzZXJ2ZXIuY3VycmVudFNlbGVjdGlvbi5lcSh0aGlzLmRvbVNlbGVjdGlvblJhbmdlKCkpICYmXG4gICAgICAgICAgICAgICAgICAgIGFuY2hvckluUmlnaHRQbGFjZSh0aGlzKSkpIHtcbiAgICAgICAgICAgICAgICBzZWxlY3Rpb25Ub0RPTSh0aGlzLCBmb3JjZVNlbFVwZGF0ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBzeW5jTm9kZVNlbGVjdGlvbih0aGlzLCBzdGF0ZS5zZWxlY3Rpb24pO1xuICAgICAgICAgICAgICAgIHRoaXMuZG9tT2JzZXJ2ZXIuc2V0Q3VyU2VsZWN0aW9uKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmRvbU9ic2VydmVyLnN0YXJ0KCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy51cGRhdGVQbHVnaW5WaWV3cyhwcmV2KTtcbiAgICAgICAgaWYgKCgoX2EgPSB0aGlzLmRyYWdnaW5nKSA9PT0gbnVsbCB8fCBfYSA9PT0gdm9pZCAwID8gdm9pZCAwIDogX2Eubm9kZSkgJiYgIXByZXYuZG9jLmVxKHN0YXRlLmRvYykpXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZURyYWdnZWROb2RlKHRoaXMuZHJhZ2dpbmcsIHByZXYpO1xuICAgICAgICBpZiAoc2Nyb2xsID09IFwicmVzZXRcIikge1xuICAgICAgICAgICAgdGhpcy5kb20uc2Nyb2xsVG9wID0gMDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChzY3JvbGwgPT0gXCJ0byBzZWxlY3Rpb25cIikge1xuICAgICAgICAgICAgdGhpcy5zY3JvbGxUb1NlbGVjdGlvbigpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG9sZFNjcm9sbFBvcykge1xuICAgICAgICAgICAgcmVzZXRTY3JvbGxQb3Mob2xkU2Nyb2xsUG9zKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICBAaW50ZXJuYWxcbiAgICAqL1xuICAgIHNjcm9sbFRvU2VsZWN0aW9uKCkge1xuICAgICAgICBsZXQgc3RhcnRET00gPSB0aGlzLmRvbVNlbGVjdGlvblJhbmdlKCkuZm9jdXNOb2RlO1xuICAgICAgICBpZiAoIXN0YXJ0RE9NIHx8ICF0aGlzLmRvbS5jb250YWlucyhzdGFydERPTS5ub2RlVHlwZSA9PSAxID8gc3RhcnRET00gOiBzdGFydERPTS5wYXJlbnROb2RlKSkgO1xuICAgICAgICBlbHNlIGlmICh0aGlzLnNvbWVQcm9wKFwiaGFuZGxlU2Nyb2xsVG9TZWxlY3Rpb25cIiwgZiA9PiBmKHRoaXMpKSkgO1xuICAgICAgICBlbHNlIGlmICh0aGlzLnN0YXRlLnNlbGVjdGlvbiBpbnN0YW5jZW9mIE5vZGVTZWxlY3Rpb24pIHtcbiAgICAgICAgICAgIGxldCB0YXJnZXQgPSB0aGlzLmRvY1ZpZXcuZG9tQWZ0ZXJQb3ModGhpcy5zdGF0ZS5zZWxlY3Rpb24uZnJvbSk7XG4gICAgICAgICAgICBpZiAodGFyZ2V0Lm5vZGVUeXBlID09IDEpXG4gICAgICAgICAgICAgICAgc2Nyb2xsUmVjdEludG9WaWV3KHRoaXMsIHRhcmdldC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSwgc3RhcnRET00pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgc2Nyb2xsUmVjdEludG9WaWV3KHRoaXMsIHRoaXMuY29vcmRzQXRQb3ModGhpcy5zdGF0ZS5zZWxlY3Rpb24uaGVhZCwgMSksIHN0YXJ0RE9NKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBkZXN0cm95UGx1Z2luVmlld3MoKSB7XG4gICAgICAgIGxldCB2aWV3O1xuICAgICAgICB3aGlsZSAodmlldyA9IHRoaXMucGx1Z2luVmlld3MucG9wKCkpXG4gICAgICAgICAgICBpZiAodmlldy5kZXN0cm95KVxuICAgICAgICAgICAgICAgIHZpZXcuZGVzdHJveSgpO1xuICAgIH1cbiAgICB1cGRhdGVQbHVnaW5WaWV3cyhwcmV2U3RhdGUpIHtcbiAgICAgICAgaWYgKCFwcmV2U3RhdGUgfHwgcHJldlN0YXRlLnBsdWdpbnMgIT0gdGhpcy5zdGF0ZS5wbHVnaW5zIHx8IHRoaXMuZGlyZWN0UGx1Z2lucyAhPSB0aGlzLnByZXZEaXJlY3RQbHVnaW5zKSB7XG4gICAgICAgICAgICB0aGlzLnByZXZEaXJlY3RQbHVnaW5zID0gdGhpcy5kaXJlY3RQbHVnaW5zO1xuICAgICAgICAgICAgdGhpcy5kZXN0cm95UGx1Z2luVmlld3MoKTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5kaXJlY3RQbHVnaW5zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgbGV0IHBsdWdpbiA9IHRoaXMuZGlyZWN0UGx1Z2luc1tpXTtcbiAgICAgICAgICAgICAgICBpZiAocGx1Z2luLnNwZWMudmlldylcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW5WaWV3cy5wdXNoKHBsdWdpbi5zcGVjLnZpZXcodGhpcykpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnN0YXRlLnBsdWdpbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBsZXQgcGx1Z2luID0gdGhpcy5zdGF0ZS5wbHVnaW5zW2ldO1xuICAgICAgICAgICAgICAgIGlmIChwbHVnaW4uc3BlYy52aWV3KVxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpblZpZXdzLnB1c2gocGx1Z2luLnNwZWMudmlldyh0aGlzKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMucGx1Z2luVmlld3MubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBsZXQgcGx1Z2luVmlldyA9IHRoaXMucGx1Z2luVmlld3NbaV07XG4gICAgICAgICAgICAgICAgaWYgKHBsdWdpblZpZXcudXBkYXRlKVxuICAgICAgICAgICAgICAgICAgICBwbHVnaW5WaWV3LnVwZGF0ZSh0aGlzLCBwcmV2U3RhdGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHVwZGF0ZURyYWdnZWROb2RlKGRyYWdnaW5nLCBwcmV2KSB7XG4gICAgICAgIGxldCBzZWwgPSBkcmFnZ2luZy5ub2RlLCBmb3VuZCA9IC0xO1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5kb2Mubm9kZUF0KHNlbC5mcm9tKSA9PSBzZWwubm9kZSkge1xuICAgICAgICAgICAgZm91bmQgPSBzZWwuZnJvbTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGxldCBtb3ZlZFBvcyA9IHNlbC5mcm9tICsgKHRoaXMuc3RhdGUuZG9jLmNvbnRlbnQuc2l6ZSAtIHByZXYuZG9jLmNvbnRlbnQuc2l6ZSk7XG4gICAgICAgICAgICBsZXQgbW92ZWQgPSBtb3ZlZFBvcyA+IDAgJiYgdGhpcy5zdGF0ZS5kb2Mubm9kZUF0KG1vdmVkUG9zKTtcbiAgICAgICAgICAgIGlmIChtb3ZlZCA9PSBzZWwubm9kZSlcbiAgICAgICAgICAgICAgICBmb3VuZCA9IG1vdmVkUG9zO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZHJhZ2dpbmcgPSBuZXcgRHJhZ2dpbmcoZHJhZ2dpbmcuc2xpY2UsIGRyYWdnaW5nLm1vdmUsIGZvdW5kIDwgMCA/IHVuZGVmaW5lZCA6IE5vZGVTZWxlY3Rpb24uY3JlYXRlKHRoaXMuc3RhdGUuZG9jLCBmb3VuZCkpO1xuICAgIH1cbiAgICBzb21lUHJvcChwcm9wTmFtZSwgZikge1xuICAgICAgICBsZXQgcHJvcCA9IHRoaXMuX3Byb3BzICYmIHRoaXMuX3Byb3BzW3Byb3BOYW1lXSwgdmFsdWU7XG4gICAgICAgIGlmIChwcm9wICE9IG51bGwgJiYgKHZhbHVlID0gZiA/IGYocHJvcCkgOiBwcm9wKSlcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmRpcmVjdFBsdWdpbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGxldCBwcm9wID0gdGhpcy5kaXJlY3RQbHVnaW5zW2ldLnByb3BzW3Byb3BOYW1lXTtcbiAgICAgICAgICAgIGlmIChwcm9wICE9IG51bGwgJiYgKHZhbHVlID0gZiA/IGYocHJvcCkgOiBwcm9wKSlcbiAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHBsdWdpbnMgPSB0aGlzLnN0YXRlLnBsdWdpbnM7XG4gICAgICAgIGlmIChwbHVnaW5zKVxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwbHVnaW5zLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgbGV0IHByb3AgPSBwbHVnaW5zW2ldLnByb3BzW3Byb3BOYW1lXTtcbiAgICAgICAgICAgICAgICBpZiAocHJvcCAhPSBudWxsICYmICh2YWx1ZSA9IGYgPyBmKHByb3ApIDogcHJvcCkpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgUXVlcnkgd2hldGhlciB0aGUgdmlldyBoYXMgZm9jdXMuXG4gICAgKi9cbiAgICBoYXNGb2N1cygpIHtcbiAgICAgICAgLy8gV29yayBhcm91bmQgSUUgbm90IGhhbmRsaW5nIGZvY3VzIGNvcnJlY3RseSBpZiByZXNpemUgaGFuZGxlcyBhcmUgc2hvd24uXG4gICAgICAgIC8vIElmIHRoZSBjdXJzb3IgaXMgaW5zaWRlIGFuIGVsZW1lbnQgd2l0aCByZXNpemUgaGFuZGxlcywgYWN0aXZlRWxlbWVudFxuICAgICAgICAvLyB3aWxsIGJlIHRoYXQgZWxlbWVudCBpbnN0ZWFkIG9mIHRoaXMuZG9tLlxuICAgICAgICBpZiAoaWUpIHtcbiAgICAgICAgICAgIC8vIElmIGFjdGl2ZUVsZW1lbnQgaXMgd2l0aGluIHRoaXMuZG9tLCBhbmQgdGhlcmUgYXJlIG5vIG90aGVyIGVsZW1lbnRzXG4gICAgICAgICAgICAvLyBzZXR0aW5nIGBjb250ZW50ZWRpdGFibGVgIHRvIGZhbHNlIGluIGJldHdlZW4sIHRyZWF0IGl0IGFzIGZvY3VzZWQuXG4gICAgICAgICAgICBsZXQgbm9kZSA9IHRoaXMucm9vdC5hY3RpdmVFbGVtZW50O1xuICAgICAgICAgICAgaWYgKG5vZGUgPT0gdGhpcy5kb20pXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICBpZiAoIW5vZGUgfHwgIXRoaXMuZG9tLmNvbnRhaW5zKG5vZGUpKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIHdoaWxlIChub2RlICYmIHRoaXMuZG9tICE9IG5vZGUgJiYgdGhpcy5kb20uY29udGFpbnMobm9kZSkpIHtcbiAgICAgICAgICAgICAgICBpZiAobm9kZS5jb250ZW50RWRpdGFibGUgPT0gJ2ZhbHNlJylcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIG5vZGUgPSBub2RlLnBhcmVudEVsZW1lbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5yb290LmFjdGl2ZUVsZW1lbnQgPT0gdGhpcy5kb207XG4gICAgfVxuICAgIC8qKlxuICAgIEZvY3VzIHRoZSBlZGl0b3IuXG4gICAgKi9cbiAgICBmb2N1cygpIHtcbiAgICAgICAgdGhpcy5kb21PYnNlcnZlci5zdG9wKCk7XG4gICAgICAgIGlmICh0aGlzLmVkaXRhYmxlKVxuICAgICAgICAgICAgZm9jdXNQcmV2ZW50U2Nyb2xsKHRoaXMuZG9tKTtcbiAgICAgICAgc2VsZWN0aW9uVG9ET00odGhpcyk7XG4gICAgICAgIHRoaXMuZG9tT2JzZXJ2ZXIuc3RhcnQoKTtcbiAgICB9XG4gICAgLyoqXG4gICAgR2V0IHRoZSBkb2N1bWVudCByb290IGluIHdoaWNoIHRoZSBlZGl0b3IgZXhpc3RzLiBUaGlzIHdpbGxcbiAgICB1c3VhbGx5IGJlIHRoZSB0b3AtbGV2ZWwgYGRvY3VtZW50YCwgYnV0IG1pZ2h0IGJlIGEgW3NoYWRvd1xuICAgIERPTV0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvV2ViX0NvbXBvbmVudHMvU2hhZG93X0RPTSlcbiAgICByb290IGlmIHRoZSBlZGl0b3IgaXMgaW5zaWRlIG9uZS5cbiAgICAqL1xuICAgIGdldCByb290KCkge1xuICAgICAgICBsZXQgY2FjaGVkID0gdGhpcy5fcm9vdDtcbiAgICAgICAgaWYgKGNhY2hlZCA9PSBudWxsKVxuICAgICAgICAgICAgZm9yIChsZXQgc2VhcmNoID0gdGhpcy5kb20ucGFyZW50Tm9kZTsgc2VhcmNoOyBzZWFyY2ggPSBzZWFyY2gucGFyZW50Tm9kZSkge1xuICAgICAgICAgICAgICAgIGlmIChzZWFyY2gubm9kZVR5cGUgPT0gOSB8fCAoc2VhcmNoLm5vZGVUeXBlID09IDExICYmIHNlYXJjaC5ob3N0KSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXNlYXJjaC5nZXRTZWxlY3Rpb24pXG4gICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QuZ2V0UHJvdG90eXBlT2Yoc2VhcmNoKS5nZXRTZWxlY3Rpb24gPSAoKSA9PiBzZWFyY2gub3duZXJEb2N1bWVudC5nZXRTZWxlY3Rpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Jvb3QgPSBzZWFyY2g7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2FjaGVkIHx8IGRvY3VtZW50O1xuICAgIH1cbiAgICAvKipcbiAgICBXaGVuIGFuIGV4aXN0aW5nIGVkaXRvciB2aWV3IGlzIG1vdmVkIHRvIGEgbmV3IGRvY3VtZW50IG9yXG4gICAgc2hhZG93IHRyZWUsIGNhbGwgdGhpcyB0byBtYWtlIGl0IHJlY29tcHV0ZSBpdHMgcm9vdC5cbiAgICAqL1xuICAgIHVwZGF0ZVJvb3QoKSB7XG4gICAgICAgIHRoaXMuX3Jvb3QgPSBudWxsO1xuICAgIH1cbiAgICAvKipcbiAgICBHaXZlbiBhIHBhaXIgb2Ygdmlld3BvcnQgY29vcmRpbmF0ZXMsIHJldHVybiB0aGUgZG9jdW1lbnRcbiAgICBwb3NpdGlvbiB0aGF0IGNvcnJlc3BvbmRzIHRvIHRoZW0uIE1heSByZXR1cm4gbnVsbCBpZiB0aGUgZ2l2ZW5cbiAgICBjb29yZGluYXRlcyBhcmVuJ3QgaW5zaWRlIG9mIHRoZSBlZGl0b3IuIFdoZW4gYW4gb2JqZWN0IGlzXG4gICAgcmV0dXJuZWQsIGl0cyBgcG9zYCBwcm9wZXJ0eSBpcyB0aGUgcG9zaXRpb24gbmVhcmVzdCB0byB0aGVcbiAgICBjb29yZGluYXRlcywgYW5kIGl0cyBgaW5zaWRlYCBwcm9wZXJ0eSBob2xkcyB0aGUgcG9zaXRpb24gb2YgdGhlXG4gICAgaW5uZXIgbm9kZSB0aGF0IHRoZSBwb3NpdGlvbiBmYWxscyBpbnNpZGUgb2YsIG9yIC0xIGlmIGl0IGlzIGF0XG4gICAgdGhlIHRvcCBsZXZlbCwgbm90IGluIGFueSBub2RlLlxuICAgICovXG4gICAgcG9zQXRDb29yZHMoY29vcmRzKSB7XG4gICAgICAgIHJldHVybiBwb3NBdENvb3Jkcyh0aGlzLCBjb29yZHMpO1xuICAgIH1cbiAgICAvKipcbiAgICBSZXR1cm5zIHRoZSB2aWV3cG9ydCByZWN0YW5nbGUgYXQgYSBnaXZlbiBkb2N1bWVudCBwb3NpdGlvbi5cbiAgICBgbGVmdGAgYW5kIGByaWdodGAgd2lsbCBiZSB0aGUgc2FtZSBudW1iZXIsIGFzIHRoaXMgcmV0dXJucyBhXG4gICAgZmxhdCBjdXJzb3ItaXNoIHJlY3RhbmdsZS4gSWYgdGhlIHBvc2l0aW9uIGlzIGJldHdlZW4gdHdvIHRoaW5nc1xuICAgIHRoYXQgYXJlbid0IGRpcmVjdGx5IGFkamFjZW50LCBgc2lkZWAgZGV0ZXJtaW5lcyB3aGljaCBlbGVtZW50XG4gICAgaXMgdXNlZC4gV2hlbiA8IDAsIHRoZSBlbGVtZW50IGJlZm9yZSB0aGUgcG9zaXRpb24gaXMgdXNlZCxcbiAgICBvdGhlcndpc2UgdGhlIGVsZW1lbnQgYWZ0ZXIuXG4gICAgKi9cbiAgICBjb29yZHNBdFBvcyhwb3MsIHNpZGUgPSAxKSB7XG4gICAgICAgIHJldHVybiBjb29yZHNBdFBvcyh0aGlzLCBwb3MsIHNpZGUpO1xuICAgIH1cbiAgICAvKipcbiAgICBGaW5kIHRoZSBET00gcG9zaXRpb24gdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgZ2l2ZW4gZG9jdW1lbnRcbiAgICBwb3NpdGlvbi4gV2hlbiBgc2lkZWAgaXMgbmVnYXRpdmUsIGZpbmQgdGhlIHBvc2l0aW9uIGFzIGNsb3NlIGFzXG4gICAgcG9zc2libGUgdG8gdGhlIGNvbnRlbnQgYmVmb3JlIHRoZSBwb3NpdGlvbi4gV2hlbiBwb3NpdGl2ZSxcbiAgICBwcmVmZXIgcG9zaXRpb25zIGNsb3NlIHRvIHRoZSBjb250ZW50IGFmdGVyIHRoZSBwb3NpdGlvbi4gV2hlblxuICAgIHplcm8sIHByZWZlciBhcyBzaGFsbG93IGEgcG9zaXRpb24gYXMgcG9zc2libGUuXG4gICAgXG4gICAgTm90ZSB0aGF0IHlvdSBzaG91bGQgKipub3QqKiBtdXRhdGUgdGhlIGVkaXRvcidzIGludGVybmFsIERPTSxcbiAgICBvbmx5IGluc3BlY3QgaXQgKGFuZCBldmVuIHRoYXQgaXMgdXN1YWxseSBub3QgbmVjZXNzYXJ5KS5cbiAgICAqL1xuICAgIGRvbUF0UG9zKHBvcywgc2lkZSA9IDApIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZG9jVmlldy5kb21Gcm9tUG9zKHBvcywgc2lkZSk7XG4gICAgfVxuICAgIC8qKlxuICAgIEZpbmQgdGhlIERPTSBub2RlIHRoYXQgcmVwcmVzZW50cyB0aGUgZG9jdW1lbnQgbm9kZSBhZnRlciB0aGVcbiAgICBnaXZlbiBwb3NpdGlvbi4gTWF5IHJldHVybiBgbnVsbGAgd2hlbiB0aGUgcG9zaXRpb24gZG9lc24ndCBwb2ludFxuICAgIGluIGZyb250IG9mIGEgbm9kZSBvciBpZiB0aGUgbm9kZSBpcyBpbnNpZGUgYW4gb3BhcXVlIG5vZGUgdmlldy5cbiAgICBcbiAgICBUaGlzIGlzIGludGVuZGVkIHRvIGJlIGFibGUgdG8gY2FsbCB0aGluZ3MgbGlrZVxuICAgIGBnZXRCb3VuZGluZ0NsaWVudFJlY3RgIG9uIHRoYXQgRE9NIG5vZGUuIERvICoqbm90KiogbXV0YXRlIHRoZVxuICAgIGVkaXRvciBET00gZGlyZWN0bHksIG9yIGFkZCBzdHlsaW5nIHRoaXMgd2F5LCBzaW5jZSB0aGF0IHdpbGwgYmVcbiAgICBpbW1lZGlhdGVseSBvdmVycmlkZW4gYnkgdGhlIGVkaXRvciBhcyBpdCByZWRyYXdzIHRoZSBub2RlLlxuICAgICovXG4gICAgbm9kZURPTShwb3MpIHtcbiAgICAgICAgbGV0IGRlc2MgPSB0aGlzLmRvY1ZpZXcuZGVzY0F0KHBvcyk7XG4gICAgICAgIHJldHVybiBkZXNjID8gZGVzYy5ub2RlRE9NIDogbnVsbDtcbiAgICB9XG4gICAgLyoqXG4gICAgRmluZCB0aGUgZG9jdW1lbnQgcG9zaXRpb24gdGhhdCBjb3JyZXNwb25kcyB0byBhIGdpdmVuIERPTVxuICAgIHBvc2l0aW9uLiAoV2hlbmV2ZXIgcG9zc2libGUsIGl0IGlzIHByZWZlcmFibGUgdG8gaW5zcGVjdCB0aGVcbiAgICBkb2N1bWVudCBzdHJ1Y3R1cmUgZGlyZWN0bHksIHJhdGhlciB0aGFuIHBva2luZyBhcm91bmQgaW4gdGhlXG4gICAgRE9NLCBidXQgc29tZXRpbWVzXHUyMDE0Zm9yIGV4YW1wbGUgd2hlbiBpbnRlcnByZXRpbmcgYW4gZXZlbnRcbiAgICB0YXJnZXRcdTIwMTR5b3UgZG9uJ3QgaGF2ZSBhIGNob2ljZS4pXG4gICAgXG4gICAgVGhlIGBiaWFzYCBwYXJhbWV0ZXIgY2FuIGJlIHVzZWQgdG8gaW5mbHVlbmNlIHdoaWNoIHNpZGUgb2YgYSBET01cbiAgICBub2RlIHRvIHVzZSB3aGVuIHRoZSBwb3NpdGlvbiBpcyBpbnNpZGUgYSBsZWFmIG5vZGUuXG4gICAgKi9cbiAgICBwb3NBdERPTShub2RlLCBvZmZzZXQsIGJpYXMgPSAtMSkge1xuICAgICAgICBsZXQgcG9zID0gdGhpcy5kb2NWaWV3LnBvc0Zyb21ET00obm9kZSwgb2Zmc2V0LCBiaWFzKTtcbiAgICAgICAgaWYgKHBvcyA9PSBudWxsKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXCJET00gcG9zaXRpb24gbm90IGluc2lkZSB0aGUgZWRpdG9yXCIpO1xuICAgICAgICByZXR1cm4gcG9zO1xuICAgIH1cbiAgICAvKipcbiAgICBGaW5kIG91dCB3aGV0aGVyIHRoZSBzZWxlY3Rpb24gaXMgYXQgdGhlIGVuZCBvZiBhIHRleHRibG9jayB3aGVuXG4gICAgbW92aW5nIGluIGEgZ2l2ZW4gZGlyZWN0aW9uLiBXaGVuLCBmb3IgZXhhbXBsZSwgZ2l2ZW4gYFwibGVmdFwiYCxcbiAgICBpdCB3aWxsIHJldHVybiB0cnVlIGlmIG1vdmluZyBsZWZ0IGZyb20gdGhlIGN1cnJlbnQgY3Vyc29yXG4gICAgcG9zaXRpb24gd291bGQgbGVhdmUgdGhhdCBwb3NpdGlvbidzIHBhcmVudCB0ZXh0YmxvY2suIFdpbGwgYXBwbHlcbiAgICB0byB0aGUgdmlldydzIGN1cnJlbnQgc3RhdGUgYnkgZGVmYXVsdCwgYnV0IGl0IGlzIHBvc3NpYmxlIHRvXG4gICAgcGFzcyBhIGRpZmZlcmVudCBzdGF0ZS5cbiAgICAqL1xuICAgIGVuZE9mVGV4dGJsb2NrKGRpciwgc3RhdGUpIHtcbiAgICAgICAgcmV0dXJuIGVuZE9mVGV4dGJsb2NrKHRoaXMsIHN0YXRlIHx8IHRoaXMuc3RhdGUsIGRpcik7XG4gICAgfVxuICAgIC8qKlxuICAgIFJ1biB0aGUgZWRpdG9yJ3MgcGFzdGUgbG9naWMgd2l0aCB0aGUgZ2l2ZW4gSFRNTCBzdHJpbmcuIFRoZVxuICAgIGBldmVudGAsIGlmIGdpdmVuLCB3aWxsIGJlIHBhc3NlZCB0byB0aGVcbiAgICBbYGhhbmRsZVBhc3RlYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3ZpZXcuRWRpdG9yUHJvcHMuaGFuZGxlUGFzdGUpIGhvb2suXG4gICAgKi9cbiAgICBwYXN0ZUhUTUwoaHRtbCwgZXZlbnQpIHtcbiAgICAgICAgcmV0dXJuIGRvUGFzdGUodGhpcywgXCJcIiwgaHRtbCwgZmFsc2UsIGV2ZW50IHx8IG5ldyBDbGlwYm9hcmRFdmVudChcInBhc3RlXCIpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgUnVuIHRoZSBlZGl0b3IncyBwYXN0ZSBsb2dpYyB3aXRoIHRoZSBnaXZlbiBwbGFpbi10ZXh0IGlucHV0LlxuICAgICovXG4gICAgcGFzdGVUZXh0KHRleHQsIGV2ZW50KSB7XG4gICAgICAgIHJldHVybiBkb1Bhc3RlKHRoaXMsIHRleHQsIG51bGwsIHRydWUsIGV2ZW50IHx8IG5ldyBDbGlwYm9hcmRFdmVudChcInBhc3RlXCIpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgU2VyaWFsaXplIHRoZSBnaXZlbiBzbGljZSBhcyBpdCB3b3VsZCBiZSBpZiBpdCB3YXMgY29waWVkIGZyb21cbiAgICB0aGlzIGVkaXRvci4gUmV0dXJucyBhIERPTSBlbGVtZW50IHRoYXQgY29udGFpbnMgYVxuICAgIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzbGljZSBhcyBpdHMgY2hpbGRyZW4sIGEgdGV4dHVhbFxuICAgIHJlcHJlc2VudGF0aW9uLCBhbmQgdGhlIHRyYW5zZm9ybWVkIHNsaWNlICh3aGljaCBjYW4gYmVcbiAgICBkaWZmZXJlbnQgZnJvbSB0aGUgZ2l2ZW4gaW5wdXQgZHVlIHRvIGhvb2tzIGxpa2VcbiAgICBbYHRyYW5zZm9ybUNvcGllZGBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyN2aWV3LkVkaXRvclByb3BzLnRyYW5zZm9ybUNvcGllZCkpLlxuICAgICovXG4gICAgc2VyaWFsaXplRm9yQ2xpcGJvYXJkKHNsaWNlKSB7XG4gICAgICAgIHJldHVybiBzZXJpYWxpemVGb3JDbGlwYm9hcmQodGhpcywgc2xpY2UpO1xuICAgIH1cbiAgICAvKipcbiAgICBSZW1vdmVzIHRoZSBlZGl0b3IgZnJvbSB0aGUgRE9NIGFuZCBkZXN0cm95cyBhbGwgW25vZGVcbiAgICB2aWV3c10oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3ZpZXcuTm9kZVZpZXcpLlxuICAgICovXG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmRvY1ZpZXcpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIGRlc3Ryb3lJbnB1dCh0aGlzKTtcbiAgICAgICAgdGhpcy5kZXN0cm95UGx1Z2luVmlld3MoKTtcbiAgICAgICAgaWYgKHRoaXMubW91bnRlZCkge1xuICAgICAgICAgICAgdGhpcy5kb2NWaWV3LnVwZGF0ZSh0aGlzLnN0YXRlLmRvYywgW10sIHZpZXdEZWNvcmF0aW9ucyh0aGlzKSwgdGhpcyk7XG4gICAgICAgICAgICB0aGlzLmRvbS50ZXh0Q29udGVudCA9IFwiXCI7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5kb20ucGFyZW50Tm9kZSkge1xuICAgICAgICAgICAgdGhpcy5kb20ucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzLmRvbSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5kb2NWaWV3LmRlc3Ryb3koKTtcbiAgICAgICAgdGhpcy5kb2NWaWV3ID0gbnVsbDtcbiAgICAgICAgY2xlYXJSZXVzZWRSYW5nZSgpO1xuICAgIH1cbiAgICAvKipcbiAgICBUaGlzIGlzIHRydWUgd2hlbiB0aGUgdmlldyBoYXMgYmVlblxuICAgIFtkZXN0cm95ZWRdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyN2aWV3LkVkaXRvclZpZXcuZGVzdHJveSkgKGFuZCB0aHVzIHNob3VsZCBub3QgYmVcbiAgICB1c2VkIGFueW1vcmUpLlxuICAgICovXG4gICAgZ2V0IGlzRGVzdHJveWVkKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5kb2NWaWV3ID09IG51bGw7XG4gICAgfVxuICAgIC8qKlxuICAgIFVzZWQgZm9yIHRlc3RpbmcuXG4gICAgKi9cbiAgICBkaXNwYXRjaEV2ZW50KGV2ZW50KSB7XG4gICAgICAgIHJldHVybiBkaXNwYXRjaEV2ZW50KHRoaXMsIGV2ZW50KTtcbiAgICB9XG4gICAgLyoqXG4gICAgRGlzcGF0Y2ggYSB0cmFuc2FjdGlvbi4gV2lsbCBjYWxsXG4gICAgW2BkaXNwYXRjaFRyYW5zYWN0aW9uYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3ZpZXcuRGlyZWN0RWRpdG9yUHJvcHMuZGlzcGF0Y2hUcmFuc2FjdGlvbilcbiAgICB3aGVuIGdpdmVuLCBhbmQgb3RoZXJ3aXNlIGRlZmF1bHRzIHRvIGFwcGx5aW5nIHRoZSB0cmFuc2FjdGlvbiB0b1xuICAgIHRoZSBjdXJyZW50IHN0YXRlIGFuZCBjYWxsaW5nXG4gICAgW2B1cGRhdGVTdGF0ZWBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyN2aWV3LkVkaXRvclZpZXcudXBkYXRlU3RhdGUpIHdpdGggdGhlIHJlc3VsdC5cbiAgICBUaGlzIG1ldGhvZCBpcyBib3VuZCB0byB0aGUgdmlldyBpbnN0YW5jZSwgc28gdGhhdCBpdCBjYW4gYmVcbiAgICBlYXNpbHkgcGFzc2VkIGFyb3VuZC5cbiAgICAqL1xuICAgIGRpc3BhdGNoKHRyKSB7XG4gICAgICAgIGxldCBkaXNwYXRjaFRyYW5zYWN0aW9uID0gdGhpcy5fcHJvcHMuZGlzcGF0Y2hUcmFuc2FjdGlvbjtcbiAgICAgICAgaWYgKGRpc3BhdGNoVHJhbnNhY3Rpb24pXG4gICAgICAgICAgICBkaXNwYXRjaFRyYW5zYWN0aW9uLmNhbGwodGhpcywgdHIpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZVN0YXRlKHRoaXMuc3RhdGUuYXBwbHkodHIpKTtcbiAgICB9XG4gICAgLyoqXG4gICAgQGludGVybmFsXG4gICAgKi9cbiAgICBkb21TZWxlY3Rpb25SYW5nZSgpIHtcbiAgICAgICAgbGV0IHNlbCA9IHRoaXMuZG9tU2VsZWN0aW9uKCk7XG4gICAgICAgIGlmICghc2VsKVxuICAgICAgICAgICAgcmV0dXJuIHsgZm9jdXNOb2RlOiBudWxsLCBmb2N1c09mZnNldDogMCwgYW5jaG9yTm9kZTogbnVsbCwgYW5jaG9yT2Zmc2V0OiAwIH07XG4gICAgICAgIHJldHVybiBzYWZhcmkgJiYgdGhpcy5yb290Lm5vZGVUeXBlID09PSAxMSAmJlxuICAgICAgICAgICAgZGVlcEFjdGl2ZUVsZW1lbnQodGhpcy5kb20ub3duZXJEb2N1bWVudCkgPT0gdGhpcy5kb20gJiYgc2FmYXJpU2hhZG93U2VsZWN0aW9uUmFuZ2UodGhpcywgc2VsKSB8fCBzZWw7XG4gICAgfVxuICAgIC8qKlxuICAgIEBpbnRlcm5hbFxuICAgICovXG4gICAgZG9tU2VsZWN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5yb290LmdldFNlbGVjdGlvbigpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGNvbXB1dGVEb2NEZWNvKHZpZXcpIHtcbiAgICBsZXQgYXR0cnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIGF0dHJzLmNsYXNzID0gXCJQcm9zZU1pcnJvclwiO1xuICAgIGF0dHJzLmNvbnRlbnRlZGl0YWJsZSA9IFN0cmluZyh2aWV3LmVkaXRhYmxlKTtcbiAgICB2aWV3LnNvbWVQcm9wKFwiYXR0cmlidXRlc1wiLCB2YWx1ZSA9PiB7XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gXCJmdW5jdGlvblwiKVxuICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZSh2aWV3LnN0YXRlKTtcbiAgICAgICAgaWYgKHZhbHVlKVxuICAgICAgICAgICAgZm9yIChsZXQgYXR0ciBpbiB2YWx1ZSkge1xuICAgICAgICAgICAgICAgIGlmIChhdHRyID09IFwiY2xhc3NcIilcbiAgICAgICAgICAgICAgICAgICAgYXR0cnMuY2xhc3MgKz0gXCIgXCIgKyB2YWx1ZVthdHRyXTtcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChhdHRyID09IFwic3R5bGVcIilcbiAgICAgICAgICAgICAgICAgICAgYXR0cnMuc3R5bGUgPSAoYXR0cnMuc3R5bGUgPyBhdHRycy5zdHlsZSArIFwiO1wiIDogXCJcIikgKyB2YWx1ZVthdHRyXTtcbiAgICAgICAgICAgICAgICBlbHNlIGlmICghYXR0cnNbYXR0cl0gJiYgYXR0ciAhPSBcImNvbnRlbnRlZGl0YWJsZVwiICYmIGF0dHIgIT0gXCJub2RlTmFtZVwiKVxuICAgICAgICAgICAgICAgICAgICBhdHRyc1thdHRyXSA9IFN0cmluZyh2YWx1ZVthdHRyXSk7XG4gICAgICAgICAgICB9XG4gICAgfSk7XG4gICAgaWYgKCFhdHRycy50cmFuc2xhdGUpXG4gICAgICAgIGF0dHJzLnRyYW5zbGF0ZSA9IFwibm9cIjtcbiAgICByZXR1cm4gW0RlY29yYXRpb24ubm9kZSgwLCB2aWV3LnN0YXRlLmRvYy5jb250ZW50LnNpemUsIGF0dHJzKV07XG59XG5mdW5jdGlvbiB1cGRhdGVDdXJzb3JXcmFwcGVyKHZpZXcpIHtcbiAgICBpZiAodmlldy5tYXJrQ3Vyc29yKSB7XG4gICAgICAgIGxldCBkb20gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaW1nXCIpO1xuICAgICAgICBkb20uY2xhc3NOYW1lID0gXCJQcm9zZU1pcnJvci1zZXBhcmF0b3JcIjtcbiAgICAgICAgZG9tLnNldEF0dHJpYnV0ZShcIm1hcmstcGxhY2Vob2xkZXJcIiwgXCJ0cnVlXCIpO1xuICAgICAgICBkb20uc2V0QXR0cmlidXRlKFwiYWx0XCIsIFwiXCIpO1xuICAgICAgICB2aWV3LmN1cnNvcldyYXBwZXIgPSB7IGRvbSwgZGVjbzogRGVjb3JhdGlvbi53aWRnZXQodmlldy5zdGF0ZS5zZWxlY3Rpb24uZnJvbSwgZG9tLCB7IHJhdzogdHJ1ZSwgbWFya3M6IHZpZXcubWFya0N1cnNvciB9KSB9O1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgdmlldy5jdXJzb3JXcmFwcGVyID0gbnVsbDtcbiAgICB9XG59XG5mdW5jdGlvbiBnZXRFZGl0YWJsZSh2aWV3KSB7XG4gICAgcmV0dXJuICF2aWV3LnNvbWVQcm9wKFwiZWRpdGFibGVcIiwgdmFsdWUgPT4gdmFsdWUodmlldy5zdGF0ZSkgPT09IGZhbHNlKTtcbn1cbmZ1bmN0aW9uIHNlbGVjdGlvbkNvbnRleHRDaGFuZ2VkKHNlbDEsIHNlbDIpIHtcbiAgICBsZXQgZGVwdGggPSBNYXRoLm1pbihzZWwxLiRhbmNob3Iuc2hhcmVkRGVwdGgoc2VsMS5oZWFkKSwgc2VsMi4kYW5jaG9yLnNoYXJlZERlcHRoKHNlbDIuaGVhZCkpO1xuICAgIHJldHVybiBzZWwxLiRhbmNob3Iuc3RhcnQoZGVwdGgpICE9IHNlbDIuJGFuY2hvci5zdGFydChkZXB0aCk7XG59XG5mdW5jdGlvbiBidWlsZE5vZGVWaWV3cyh2aWV3KSB7XG4gICAgbGV0IHJlc3VsdCA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gICAgZnVuY3Rpb24gYWRkKG9iaikge1xuICAgICAgICBmb3IgKGxldCBwcm9wIGluIG9iailcbiAgICAgICAgICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHJlc3VsdCwgcHJvcCkpXG4gICAgICAgICAgICAgICAgcmVzdWx0W3Byb3BdID0gb2JqW3Byb3BdO1xuICAgIH1cbiAgICB2aWV3LnNvbWVQcm9wKFwibm9kZVZpZXdzXCIsIGFkZCk7XG4gICAgdmlldy5zb21lUHJvcChcIm1hcmtWaWV3c1wiLCBhZGQpO1xuICAgIHJldHVybiByZXN1bHQ7XG59XG5mdW5jdGlvbiBjaGFuZ2VkTm9kZVZpZXdzKGEsIGIpIHtcbiAgICBsZXQgbkEgPSAwLCBuQiA9IDA7XG4gICAgZm9yIChsZXQgcHJvcCBpbiBhKSB7XG4gICAgICAgIGlmIChhW3Byb3BdICE9IGJbcHJvcF0pXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgbkErKztcbiAgICB9XG4gICAgZm9yIChsZXQgXyBpbiBiKVxuICAgICAgICBuQisrO1xuICAgIHJldHVybiBuQSAhPSBuQjtcbn1cbmZ1bmN0aW9uIGNoZWNrU3RhdGVDb21wb25lbnQocGx1Z2luKSB7XG4gICAgaWYgKHBsdWdpbi5zcGVjLnN0YXRlIHx8IHBsdWdpbi5zcGVjLmZpbHRlclRyYW5zYWN0aW9uIHx8IHBsdWdpbi5zcGVjLmFwcGVuZFRyYW5zYWN0aW9uKVxuICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcIlBsdWdpbnMgcGFzc2VkIGRpcmVjdGx5IHRvIHRoZSB2aWV3IG11c3Qgbm90IGhhdmUgYSBzdGF0ZSBjb21wb25lbnRcIik7XG59XG5cbmV4cG9ydCB7IERlY29yYXRpb24sIERlY29yYXRpb25TZXQsIEVkaXRvclZpZXcsIF9fZW5kQ29tcG9zaXRpb24sIF9fcGFyc2VGcm9tQ2xpcGJvYXJkIH07XG4iLCAiZXhwb3J0IHZhciBiYXNlID0ge1xuICA4OiBcIkJhY2tzcGFjZVwiLFxuICA5OiBcIlRhYlwiLFxuICAxMDogXCJFbnRlclwiLFxuICAxMjogXCJOdW1Mb2NrXCIsXG4gIDEzOiBcIkVudGVyXCIsXG4gIDE2OiBcIlNoaWZ0XCIsXG4gIDE3OiBcIkNvbnRyb2xcIixcbiAgMTg6IFwiQWx0XCIsXG4gIDIwOiBcIkNhcHNMb2NrXCIsXG4gIDI3OiBcIkVzY2FwZVwiLFxuICAzMjogXCIgXCIsXG4gIDMzOiBcIlBhZ2VVcFwiLFxuICAzNDogXCJQYWdlRG93blwiLFxuICAzNTogXCJFbmRcIixcbiAgMzY6IFwiSG9tZVwiLFxuICAzNzogXCJBcnJvd0xlZnRcIixcbiAgMzg6IFwiQXJyb3dVcFwiLFxuICAzOTogXCJBcnJvd1JpZ2h0XCIsXG4gIDQwOiBcIkFycm93RG93blwiLFxuICA0NDogXCJQcmludFNjcmVlblwiLFxuICA0NTogXCJJbnNlcnRcIixcbiAgNDY6IFwiRGVsZXRlXCIsXG4gIDU5OiBcIjtcIixcbiAgNjE6IFwiPVwiLFxuICA5MTogXCJNZXRhXCIsXG4gIDkyOiBcIk1ldGFcIixcbiAgMTA2OiBcIipcIixcbiAgMTA3OiBcIitcIixcbiAgMTA4OiBcIixcIixcbiAgMTA5OiBcIi1cIixcbiAgMTEwOiBcIi5cIixcbiAgMTExOiBcIi9cIixcbiAgMTQ0OiBcIk51bUxvY2tcIixcbiAgMTQ1OiBcIlNjcm9sbExvY2tcIixcbiAgMTYwOiBcIlNoaWZ0XCIsXG4gIDE2MTogXCJTaGlmdFwiLFxuICAxNjI6IFwiQ29udHJvbFwiLFxuICAxNjM6IFwiQ29udHJvbFwiLFxuICAxNjQ6IFwiQWx0XCIsXG4gIDE2NTogXCJBbHRcIixcbiAgMTczOiBcIi1cIixcbiAgMTg2OiBcIjtcIixcbiAgMTg3OiBcIj1cIixcbiAgMTg4OiBcIixcIixcbiAgMTg5OiBcIi1cIixcbiAgMTkwOiBcIi5cIixcbiAgMTkxOiBcIi9cIixcbiAgMTkyOiBcImBcIixcbiAgMjE5OiBcIltcIixcbiAgMjIwOiBcIlxcXFxcIixcbiAgMjIxOiBcIl1cIixcbiAgMjIyOiBcIidcIlxufVxuXG5leHBvcnQgdmFyIHNoaWZ0ID0ge1xuICA0ODogXCIpXCIsXG4gIDQ5OiBcIiFcIixcbiAgNTA6IFwiQFwiLFxuICA1MTogXCIjXCIsXG4gIDUyOiBcIiRcIixcbiAgNTM6IFwiJVwiLFxuICA1NDogXCJeXCIsXG4gIDU1OiBcIiZcIixcbiAgNTY6IFwiKlwiLFxuICA1NzogXCIoXCIsXG4gIDU5OiBcIjpcIixcbiAgNjE6IFwiK1wiLFxuICAxNzM6IFwiX1wiLFxuICAxODY6IFwiOlwiLFxuICAxODc6IFwiK1wiLFxuICAxODg6IFwiPFwiLFxuICAxODk6IFwiX1wiLFxuICAxOTA6IFwiPlwiLFxuICAxOTE6IFwiP1wiLFxuICAxOTI6IFwiflwiLFxuICAyMTk6IFwie1wiLFxuICAyMjA6IFwifFwiLFxuICAyMjE6IFwifVwiLFxuICAyMjI6IFwiXFxcIlwiXG59XG5cbnZhciBtYWMgPSB0eXBlb2YgbmF2aWdhdG9yICE9IFwidW5kZWZpbmVkXCIgJiYgL01hYy8udGVzdChuYXZpZ2F0b3IucGxhdGZvcm0pXG52YXIgaWUgPSB0eXBlb2YgbmF2aWdhdG9yICE9IFwidW5kZWZpbmVkXCIgJiYgL01TSUUgXFxkfFRyaWRlbnRcXC8oPzpbNy05XXxcXGR7Mix9KVxcLi4qcnY6KFxcZCspLy5leGVjKG5hdmlnYXRvci51c2VyQWdlbnQpXG5cbi8vIEZpbGwgaW4gdGhlIGRpZ2l0IGtleXNcbmZvciAodmFyIGkgPSAwOyBpIDwgMTA7IGkrKykgYmFzZVs0OCArIGldID0gYmFzZVs5NiArIGldID0gU3RyaW5nKGkpXG5cbi8vIFRoZSBmdW5jdGlvbiBrZXlzXG5mb3IgKHZhciBpID0gMTsgaSA8PSAyNDsgaSsrKSBiYXNlW2kgKyAxMTFdID0gXCJGXCIgKyBpXG5cbi8vIEFuZCB0aGUgYWxwaGFiZXRpYyBrZXlzXG5mb3IgKHZhciBpID0gNjU7IGkgPD0gOTA7IGkrKykge1xuICBiYXNlW2ldID0gU3RyaW5nLmZyb21DaGFyQ29kZShpICsgMzIpXG4gIHNoaWZ0W2ldID0gU3RyaW5nLmZyb21DaGFyQ29kZShpKVxufVxuXG4vLyBGb3IgZWFjaCBjb2RlIHRoYXQgZG9lc24ndCBoYXZlIGEgc2hpZnQtZXF1aXZhbGVudCwgY29weSB0aGUgYmFzZSBuYW1lXG5mb3IgKHZhciBjb2RlIGluIGJhc2UpIGlmICghc2hpZnQuaGFzT3duUHJvcGVydHkoY29kZSkpIHNoaWZ0W2NvZGVdID0gYmFzZVtjb2RlXVxuXG5leHBvcnQgZnVuY3Rpb24ga2V5TmFtZShldmVudCkge1xuICAvLyBPbiBtYWNPUywga2V5cyBoZWxkIHdpdGggU2hpZnQgYW5kIENtZCBkb24ndCByZWZsZWN0IHRoZSBlZmZlY3Qgb2YgU2hpZnQgaW4gYC5rZXlgLlxuICAvLyBPbiBJRSwgc2hpZnQgZWZmZWN0IGlzIG5ldmVyIGluY2x1ZGVkIGluIGAua2V5YC5cbiAgdmFyIGlnbm9yZUtleSA9IG1hYyAmJiBldmVudC5tZXRhS2V5ICYmIGV2ZW50LnNoaWZ0S2V5ICYmICFldmVudC5jdHJsS2V5ICYmICFldmVudC5hbHRLZXkgfHxcbiAgICAgIGllICYmIGV2ZW50LnNoaWZ0S2V5ICYmIGV2ZW50LmtleSAmJiBldmVudC5rZXkubGVuZ3RoID09IDEgfHxcbiAgICAgIGV2ZW50LmtleSA9PSBcIlVuaWRlbnRpZmllZFwiXG4gIHZhciBuYW1lID0gKCFpZ25vcmVLZXkgJiYgZXZlbnQua2V5KSB8fFxuICAgIChldmVudC5zaGlmdEtleSA/IHNoaWZ0IDogYmFzZSlbZXZlbnQua2V5Q29kZV0gfHxcbiAgICBldmVudC5rZXkgfHwgXCJVbmlkZW50aWZpZWRcIlxuICAvLyBFZGdlIHNvbWV0aW1lcyBwcm9kdWNlcyB3cm9uZyBuYW1lcyAoSXNzdWUgIzMpXG4gIGlmIChuYW1lID09IFwiRXNjXCIpIG5hbWUgPSBcIkVzY2FwZVwiXG4gIGlmIChuYW1lID09IFwiRGVsXCIpIG5hbWUgPSBcIkRlbGV0ZVwiXG4gIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1pY3Jvc29mdC5jb20vZW4tdXMvbWljcm9zb2Z0LWVkZ2UvcGxhdGZvcm0vaXNzdWVzLzg4NjA1NzEvXG4gIGlmIChuYW1lID09IFwiTGVmdFwiKSBuYW1lID0gXCJBcnJvd0xlZnRcIlxuICBpZiAobmFtZSA9PSBcIlVwXCIpIG5hbWUgPSBcIkFycm93VXBcIlxuICBpZiAobmFtZSA9PSBcIlJpZ2h0XCIpIG5hbWUgPSBcIkFycm93UmlnaHRcIlxuICBpZiAobmFtZSA9PSBcIkRvd25cIikgbmFtZSA9IFwiQXJyb3dEb3duXCJcbiAgcmV0dXJuIG5hbWVcbn1cbiIsICJpbXBvcnQgeyBrZXlOYW1lLCBiYXNlIH0gZnJvbSAndzNjLWtleW5hbWUnO1xuaW1wb3J0IHsgUGx1Z2luIH0gZnJvbSAncHJvc2VtaXJyb3Itc3RhdGUnO1xuXG5jb25zdCBtYWMgPSB0eXBlb2YgbmF2aWdhdG9yICE9IFwidW5kZWZpbmVkXCIgJiYgL01hY3xpUChob25lfFtvYV1kKS8udGVzdChuYXZpZ2F0b3IucGxhdGZvcm0pO1xuY29uc3Qgd2luZG93cyA9IHR5cGVvZiBuYXZpZ2F0b3IgIT0gXCJ1bmRlZmluZWRcIiAmJiAvV2luLy50ZXN0KG5hdmlnYXRvci5wbGF0Zm9ybSk7XG5mdW5jdGlvbiBub3JtYWxpemVLZXlOYW1lKG5hbWUpIHtcbiAgICBsZXQgcGFydHMgPSBuYW1lLnNwbGl0KC8tKD8hJCkvKSwgcmVzdWx0ID0gcGFydHNbcGFydHMubGVuZ3RoIC0gMV07XG4gICAgaWYgKHJlc3VsdCA9PSBcIlNwYWNlXCIpXG4gICAgICAgIHJlc3VsdCA9IFwiIFwiO1xuICAgIGxldCBhbHQsIGN0cmwsIHNoaWZ0LCBtZXRhO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGFydHMubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgIGxldCBtb2QgPSBwYXJ0c1tpXTtcbiAgICAgICAgaWYgKC9eKGNtZHxtZXRhfG0pJC9pLnRlc3QobW9kKSlcbiAgICAgICAgICAgIG1ldGEgPSB0cnVlO1xuICAgICAgICBlbHNlIGlmICgvXmEobHQpPyQvaS50ZXN0KG1vZCkpXG4gICAgICAgICAgICBhbHQgPSB0cnVlO1xuICAgICAgICBlbHNlIGlmICgvXihjfGN0cmx8Y29udHJvbCkkL2kudGVzdChtb2QpKVxuICAgICAgICAgICAgY3RybCA9IHRydWU7XG4gICAgICAgIGVsc2UgaWYgKC9ecyhoaWZ0KT8kL2kudGVzdChtb2QpKVxuICAgICAgICAgICAgc2hpZnQgPSB0cnVlO1xuICAgICAgICBlbHNlIGlmICgvXm1vZCQvaS50ZXN0KG1vZCkpIHtcbiAgICAgICAgICAgIGlmIChtYWMpXG4gICAgICAgICAgICAgICAgbWV0YSA9IHRydWU7XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgY3RybCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5yZWNvZ25pemVkIG1vZGlmaWVyIG5hbWU6IFwiICsgbW9kKTtcbiAgICB9XG4gICAgaWYgKGFsdClcbiAgICAgICAgcmVzdWx0ID0gXCJBbHQtXCIgKyByZXN1bHQ7XG4gICAgaWYgKGN0cmwpXG4gICAgICAgIHJlc3VsdCA9IFwiQ3RybC1cIiArIHJlc3VsdDtcbiAgICBpZiAobWV0YSlcbiAgICAgICAgcmVzdWx0ID0gXCJNZXRhLVwiICsgcmVzdWx0O1xuICAgIGlmIChzaGlmdClcbiAgICAgICAgcmVzdWx0ID0gXCJTaGlmdC1cIiArIHJlc3VsdDtcbiAgICByZXR1cm4gcmVzdWx0O1xufVxuZnVuY3Rpb24gbm9ybWFsaXplKG1hcCkge1xuICAgIGxldCBjb3B5ID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICBmb3IgKGxldCBwcm9wIGluIG1hcClcbiAgICAgICAgY29weVtub3JtYWxpemVLZXlOYW1lKHByb3ApXSA9IG1hcFtwcm9wXTtcbiAgICByZXR1cm4gY29weTtcbn1cbmZ1bmN0aW9uIG1vZGlmaWVycyhuYW1lLCBldmVudCwgc2hpZnQgPSB0cnVlKSB7XG4gICAgaWYgKGV2ZW50LmFsdEtleSlcbiAgICAgICAgbmFtZSA9IFwiQWx0LVwiICsgbmFtZTtcbiAgICBpZiAoZXZlbnQuY3RybEtleSlcbiAgICAgICAgbmFtZSA9IFwiQ3RybC1cIiArIG5hbWU7XG4gICAgaWYgKGV2ZW50Lm1ldGFLZXkpXG4gICAgICAgIG5hbWUgPSBcIk1ldGEtXCIgKyBuYW1lO1xuICAgIGlmIChzaGlmdCAmJiBldmVudC5zaGlmdEtleSlcbiAgICAgICAgbmFtZSA9IFwiU2hpZnQtXCIgKyBuYW1lO1xuICAgIHJldHVybiBuYW1lO1xufVxuLyoqXG5DcmVhdGUgYSBrZXltYXAgcGx1Z2luIGZvciB0aGUgZ2l2ZW4gc2V0IG9mIGJpbmRpbmdzLlxuXG5CaW5kaW5ncyBzaG91bGQgbWFwIGtleSBuYW1lcyB0byBbY29tbWFuZF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI2NvbW1hbmRzKS1zdHlsZVxuZnVuY3Rpb25zLCB3aGljaCB3aWxsIGJlIGNhbGxlZCB3aXRoIGAoRWRpdG9yU3RhdGUsIGRpc3BhdGNoLFxuRWRpdG9yVmlldylgIGFyZ3VtZW50cywgYW5kIHNob3VsZCByZXR1cm4gdHJ1ZSB3aGVuIHRoZXkndmUgaGFuZGxlZFxudGhlIGtleS4gTm90ZSB0aGF0IHRoZSB2aWV3IGFyZ3VtZW50IGlzbid0IHBhcnQgb2YgdGhlIGNvbW1hbmRcbnByb3RvY29sLCBidXQgY2FuIGJlIHVzZWQgYXMgYW4gZXNjYXBlIGhhdGNoIGlmIGEgYmluZGluZyBuZWVkcyB0b1xuZGlyZWN0bHkgaW50ZXJhY3Qgd2l0aCB0aGUgVUkuXG5cbktleSBuYW1lcyBtYXkgYmUgc3RyaW5ncyBsaWtlIGBcIlNoaWZ0LUN0cmwtRW50ZXJcImBcdTIwMTRhIGtleVxuaWRlbnRpZmllciBwcmVmaXhlZCB3aXRoIHplcm8gb3IgbW9yZSBtb2RpZmllcnMuIEtleSBpZGVudGlmaWVyc1xuYXJlIGJhc2VkIG9uIHRoZSBzdHJpbmdzIHRoYXQgY2FuIGFwcGVhciBpblxuW2BLZXlFdmVudC5rZXlgXShodHRwczpkZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0tleWJvYXJkRXZlbnQva2V5KS5cblVzZSBsb3dlcmNhc2UgbGV0dGVycyB0byByZWZlciB0byBsZXR0ZXIga2V5cyAob3IgdXBwZXJjYXNlIGxldHRlcnNcbmlmIHlvdSB3YW50IHNoaWZ0IHRvIGJlIGhlbGQpLiBZb3UgbWF5IHVzZSBgXCJTcGFjZVwiYCBhcyBhbiBhbGlhc1xuZm9yIHRoZSBgXCIgXCJgIG5hbWUuXG5cbk1vZGlmaWVycyBjYW4gYmUgZ2l2ZW4gaW4gYW55IG9yZGVyLiBgU2hpZnQtYCAob3IgYHMtYCksIGBBbHQtYCAob3JcbmBhLWApLCBgQ3RybC1gIChvciBgYy1gIG9yIGBDb250cm9sLWApIGFuZCBgQ21kLWAgKG9yIGBtLWAgb3JcbmBNZXRhLWApIGFyZSByZWNvZ25pemVkLiBGb3IgY2hhcmFjdGVycyB0aGF0IGFyZSBjcmVhdGVkIGJ5IGhvbGRpbmdcbnNoaWZ0LCB0aGUgYFNoaWZ0LWAgcHJlZml4IGlzIGltcGxpZWQsIGFuZCBzaG91bGQgbm90IGJlIGFkZGVkXG5leHBsaWNpdGx5LlxuXG5Zb3UgY2FuIHVzZSBgTW9kLWAgYXMgYSBzaG9ydGhhbmQgZm9yIGBDbWQtYCBvbiBNYWMgYW5kIGBDdHJsLWAgb25cbm90aGVyIHBsYXRmb3Jtcy5cblxuWW91IGNhbiBhZGQgbXVsdGlwbGUga2V5bWFwIHBsdWdpbnMgdG8gYW4gZWRpdG9yLiBUaGUgb3JkZXIgaW5cbndoaWNoIHRoZXkgYXBwZWFyIGRldGVybWluZXMgdGhlaXIgcHJlY2VkZW5jZSAodGhlIG9uZXMgZWFybHkgaW5cbnRoZSBhcnJheSBnZXQgdG8gZGlzcGF0Y2ggZmlyc3QpLlxuKi9cbmZ1bmN0aW9uIGtleW1hcChiaW5kaW5ncykge1xuICAgIHJldHVybiBuZXcgUGx1Z2luKHsgcHJvcHM6IHsgaGFuZGxlS2V5RG93bjoga2V5ZG93bkhhbmRsZXIoYmluZGluZ3MpIH0gfSk7XG59XG4vKipcbkdpdmVuIGEgc2V0IG9mIGJpbmRpbmdzICh1c2luZyB0aGUgc2FtZSBmb3JtYXQgYXNcbltga2V5bWFwYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI2tleW1hcC5rZXltYXApKSwgcmV0dXJuIGEgW2tleWRvd25cbmhhbmRsZXJdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyN2aWV3LkVkaXRvclByb3BzLmhhbmRsZUtleURvd24pIHRoYXQgaGFuZGxlcyB0aGVtLlxuKi9cbmZ1bmN0aW9uIGtleWRvd25IYW5kbGVyKGJpbmRpbmdzKSB7XG4gICAgbGV0IG1hcCA9IG5vcm1hbGl6ZShiaW5kaW5ncyk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICh2aWV3LCBldmVudCkge1xuICAgICAgICBsZXQgbmFtZSA9IGtleU5hbWUoZXZlbnQpLCBiYXNlTmFtZSwgZGlyZWN0ID0gbWFwW21vZGlmaWVycyhuYW1lLCBldmVudCldO1xuICAgICAgICBpZiAoZGlyZWN0ICYmIGRpcmVjdCh2aWV3LnN0YXRlLCB2aWV3LmRpc3BhdGNoLCB2aWV3KSlcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAvLyBBIGNoYXJhY3RlciBrZXlcbiAgICAgICAgaWYgKG5hbWUubGVuZ3RoID09IDEgJiYgbmFtZSAhPSBcIiBcIikge1xuICAgICAgICAgICAgaWYgKGV2ZW50LnNoaWZ0S2V5KSB7XG4gICAgICAgICAgICAgICAgLy8gSW4gY2FzZSB0aGUgbmFtZSB3YXMgYWxyZWFkeSBtb2RpZmllZCBieSBzaGlmdCwgdHJ5IGxvb2tpbmdcbiAgICAgICAgICAgICAgICAvLyBpdCB1cCB3aXRob3V0IGl0cyBzaGlmdCBtb2RpZmllclxuICAgICAgICAgICAgICAgIGxldCBub1NoaWZ0ID0gbWFwW21vZGlmaWVycyhuYW1lLCBldmVudCwgZmFsc2UpXTtcbiAgICAgICAgICAgICAgICBpZiAobm9TaGlmdCAmJiBub1NoaWZ0KHZpZXcuc3RhdGUsIHZpZXcuZGlzcGF0Y2gsIHZpZXcpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICgoZXZlbnQuYWx0S2V5IHx8IGV2ZW50Lm1ldGFLZXkgfHwgZXZlbnQuY3RybEtleSkgJiZcbiAgICAgICAgICAgICAgICAvLyBDdHJsLUFsdCBtYXkgYmUgdXNlZCBmb3IgQWx0R3Igb24gV2luZG93c1xuICAgICAgICAgICAgICAgICEod2luZG93cyAmJiBldmVudC5jdHJsS2V5ICYmIGV2ZW50LmFsdEtleSkgJiZcbiAgICAgICAgICAgICAgICAoYmFzZU5hbWUgPSBiYXNlW2V2ZW50LmtleUNvZGVdKSAmJiBiYXNlTmFtZSAhPSBuYW1lKSB7XG4gICAgICAgICAgICAgICAgLy8gVHJ5IGZhbGxpbmcgYmFjayB0byB0aGUga2V5Q29kZSB3aGVuIHRoZXJlJ3MgYSBtb2RpZmllclxuICAgICAgICAgICAgICAgIC8vIGFjdGl2ZSBvciB0aGUgY2hhcmFjdGVyIHByb2R1Y2VkIGlzbid0IEFTQ0lJLCBhbmQgb3VyIHRhYmxlXG4gICAgICAgICAgICAgICAgLy8gcHJvZHVjZXMgYSBkaWZmZXJlbnQgbmFtZSBmcm9tIHRoZSB0aGUga2V5Q29kZS4gU2VlICM2NjgsXG4gICAgICAgICAgICAgICAgLy8gIzEwNjAsICMxNTI5LlxuICAgICAgICAgICAgICAgIGxldCBmcm9tQ29kZSA9IG1hcFttb2RpZmllcnMoYmFzZU5hbWUsIGV2ZW50KV07XG4gICAgICAgICAgICAgICAgaWYgKGZyb21Db2RlICYmIGZyb21Db2RlKHZpZXcuc3RhdGUsIHZpZXcuZGlzcGF0Y2gsIHZpZXcpKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcbn1cblxuZXhwb3J0IHsga2V5ZG93bkhhbmRsZXIsIGtleW1hcCB9O1xuIiwgImltcG9ydCB7IGxpZnRUYXJnZXQsIHJlcGxhY2VTdGVwLCBSZXBsYWNlU3RlcCwgY2FuSm9pbiwgam9pblBvaW50LCBjYW5TcGxpdCwgUmVwbGFjZUFyb3VuZFN0ZXAsIGZpbmRXcmFwcGluZyB9IGZyb20gJ3Byb3NlbWlycm9yLXRyYW5zZm9ybSc7XG5pbXBvcnQgeyBTbGljZSwgRnJhZ21lbnQgfSBmcm9tICdwcm9zZW1pcnJvci1tb2RlbCc7XG5pbXBvcnQgeyBOb2RlU2VsZWN0aW9uLCBTZWxlY3Rpb24sIFRleHRTZWxlY3Rpb24sIEFsbFNlbGVjdGlvbiwgU2VsZWN0aW9uUmFuZ2UgfSBmcm9tICdwcm9zZW1pcnJvci1zdGF0ZSc7XG5cbi8qKlxuRGVsZXRlIHRoZSBzZWxlY3Rpb24sIGlmIHRoZXJlIGlzIG9uZS5cbiovXG5jb25zdCBkZWxldGVTZWxlY3Rpb24gPSAoc3RhdGUsIGRpc3BhdGNoKSA9PiB7XG4gICAgaWYgKHN0YXRlLnNlbGVjdGlvbi5lbXB0eSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChkaXNwYXRjaClcbiAgICAgICAgZGlzcGF0Y2goc3RhdGUudHIuZGVsZXRlU2VsZWN0aW9uKCkuc2Nyb2xsSW50b1ZpZXcoKSk7XG4gICAgcmV0dXJuIHRydWU7XG59O1xuZnVuY3Rpb24gYXRCbG9ja1N0YXJ0KHN0YXRlLCB2aWV3KSB7XG4gICAgbGV0IHsgJGN1cnNvciB9ID0gc3RhdGUuc2VsZWN0aW9uO1xuICAgIGlmICghJGN1cnNvciB8fCAodmlldyA/ICF2aWV3LmVuZE9mVGV4dGJsb2NrKFwiYmFja3dhcmRcIiwgc3RhdGUpXG4gICAgICAgIDogJGN1cnNvci5wYXJlbnRPZmZzZXQgPiAwKSlcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuICRjdXJzb3I7XG59XG4vKipcbklmIHRoZSBzZWxlY3Rpb24gaXMgZW1wdHkgYW5kIGF0IHRoZSBzdGFydCBvZiBhIHRleHRibG9jaywgdHJ5IHRvXG5yZWR1Y2UgdGhlIGRpc3RhbmNlIGJldHdlZW4gdGhhdCBibG9jayBhbmQgdGhlIG9uZSBiZWZvcmUgaXRcdTIwMTRpZlxudGhlcmUncyBhIGJsb2NrIGRpcmVjdGx5IGJlZm9yZSBpdCB0aGF0IGNhbiBiZSBqb2luZWQsIGpvaW4gdGhlbS5cbklmIG5vdCwgdHJ5IHRvIG1vdmUgdGhlIHNlbGVjdGVkIGJsb2NrIGNsb3NlciB0byB0aGUgbmV4dCBvbmUgaW5cbnRoZSBkb2N1bWVudCBzdHJ1Y3R1cmUgYnkgbGlmdGluZyBpdCBvdXQgb2YgaXRzIHBhcmVudCBvciBtb3ZpbmcgaXRcbmludG8gYSBwYXJlbnQgb2YgdGhlIHByZXZpb3VzIGJsb2NrLiBXaWxsIHVzZSB0aGUgdmlldyBmb3IgYWNjdXJhdGVcbihiaWRpLWF3YXJlKSBzdGFydC1vZi10ZXh0YmxvY2sgZGV0ZWN0aW9uIGlmIGdpdmVuLlxuKi9cbmNvbnN0IGpvaW5CYWNrd2FyZCA9IChzdGF0ZSwgZGlzcGF0Y2gsIHZpZXcpID0+IHtcbiAgICBsZXQgJGN1cnNvciA9IGF0QmxvY2tTdGFydChzdGF0ZSwgdmlldyk7XG4gICAgaWYgKCEkY3Vyc29yKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgbGV0ICRjdXQgPSBmaW5kQ3V0QmVmb3JlKCRjdXJzb3IpO1xuICAgIC8vIElmIHRoZXJlIGlzIG5vIG5vZGUgYmVmb3JlIHRoaXMsIHRyeSB0byBsaWZ0XG4gICAgaWYgKCEkY3V0KSB7XG4gICAgICAgIGxldCByYW5nZSA9ICRjdXJzb3IuYmxvY2tSYW5nZSgpLCB0YXJnZXQgPSByYW5nZSAmJiBsaWZ0VGFyZ2V0KHJhbmdlKTtcbiAgICAgICAgaWYgKHRhcmdldCA9PSBudWxsKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBpZiAoZGlzcGF0Y2gpXG4gICAgICAgICAgICBkaXNwYXRjaChzdGF0ZS50ci5saWZ0KHJhbmdlLCB0YXJnZXQpLnNjcm9sbEludG9WaWV3KCkpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgbGV0IGJlZm9yZSA9ICRjdXQubm9kZUJlZm9yZTtcbiAgICAvLyBBcHBseSB0aGUgam9pbmluZyBhbGdvcml0aG1cbiAgICBpZiAoZGVsZXRlQmFycmllcihzdGF0ZSwgJGN1dCwgZGlzcGF0Y2gsIC0xKSlcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgLy8gSWYgdGhlIG5vZGUgYmVsb3cgaGFzIG5vIGNvbnRlbnQgYW5kIHRoZSBub2RlIGFib3ZlIGlzXG4gICAgLy8gc2VsZWN0YWJsZSwgZGVsZXRlIHRoZSBub2RlIGJlbG93IGFuZCBzZWxlY3QgdGhlIG9uZSBhYm92ZS5cbiAgICBpZiAoJGN1cnNvci5wYXJlbnQuY29udGVudC5zaXplID09IDAgJiZcbiAgICAgICAgKHRleHRibG9ja0F0KGJlZm9yZSwgXCJlbmRcIikgfHwgTm9kZVNlbGVjdGlvbi5pc1NlbGVjdGFibGUoYmVmb3JlKSkpIHtcbiAgICAgICAgZm9yIChsZXQgZGVwdGggPSAkY3Vyc29yLmRlcHRoOzsgZGVwdGgtLSkge1xuICAgICAgICAgICAgbGV0IGRlbFN0ZXAgPSByZXBsYWNlU3RlcChzdGF0ZS5kb2MsICRjdXJzb3IuYmVmb3JlKGRlcHRoKSwgJGN1cnNvci5hZnRlcihkZXB0aCksIFNsaWNlLmVtcHR5KTtcbiAgICAgICAgICAgIGlmIChkZWxTdGVwICYmIGRlbFN0ZXAuc2xpY2Uuc2l6ZSA8IGRlbFN0ZXAudG8gLSBkZWxTdGVwLmZyb20pIHtcbiAgICAgICAgICAgICAgICBpZiAoZGlzcGF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHRyID0gc3RhdGUudHIuc3RlcChkZWxTdGVwKTtcbiAgICAgICAgICAgICAgICAgICAgdHIuc2V0U2VsZWN0aW9uKHRleHRibG9ja0F0KGJlZm9yZSwgXCJlbmRcIilcbiAgICAgICAgICAgICAgICAgICAgICAgID8gU2VsZWN0aW9uLmZpbmRGcm9tKHRyLmRvYy5yZXNvbHZlKHRyLm1hcHBpbmcubWFwKCRjdXQucG9zLCAtMSkpLCAtMSlcbiAgICAgICAgICAgICAgICAgICAgICAgIDogTm9kZVNlbGVjdGlvbi5jcmVhdGUodHIuZG9jLCAkY3V0LnBvcyAtIGJlZm9yZS5ub2RlU2l6ZSkpO1xuICAgICAgICAgICAgICAgICAgICBkaXNwYXRjaCh0ci5zY3JvbGxJbnRvVmlldygpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZGVwdGggPT0gMSB8fCAkY3Vyc29yLm5vZGUoZGVwdGggLSAxKS5jaGlsZENvdW50ID4gMSlcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBJZiB0aGUgbm9kZSBiZWZvcmUgaXMgYW4gYXRvbSwgZGVsZXRlIGl0XG4gICAgaWYgKGJlZm9yZS5pc0F0b20gJiYgJGN1dC5kZXB0aCA9PSAkY3Vyc29yLmRlcHRoIC0gMSkge1xuICAgICAgICBpZiAoZGlzcGF0Y2gpXG4gICAgICAgICAgICBkaXNwYXRjaChzdGF0ZS50ci5kZWxldGUoJGN1dC5wb3MgLSBiZWZvcmUubm9kZVNpemUsICRjdXQucG9zKS5zY3JvbGxJbnRvVmlldygpKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn07XG4vKipcbkEgbW9yZSBsaW1pdGVkIGZvcm0gb2YgW2Bqb2luQmFja3dhcmRgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jY29tbWFuZHMuam9pbkJhY2t3YXJkKVxudGhhdCBvbmx5IHRyaWVzIHRvIGpvaW4gdGhlIGN1cnJlbnQgdGV4dGJsb2NrIHRvIHRoZSBvbmUgYmVmb3JlXG5pdCwgaWYgdGhlIGN1cnNvciBpcyBhdCB0aGUgc3RhcnQgb2YgYSB0ZXh0YmxvY2suXG4qL1xuY29uc3Qgam9pblRleHRibG9ja0JhY2t3YXJkID0gKHN0YXRlLCBkaXNwYXRjaCwgdmlldykgPT4ge1xuICAgIGxldCAkY3Vyc29yID0gYXRCbG9ja1N0YXJ0KHN0YXRlLCB2aWV3KTtcbiAgICBpZiAoISRjdXJzb3IpXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICBsZXQgJGN1dCA9IGZpbmRDdXRCZWZvcmUoJGN1cnNvcik7XG4gICAgcmV0dXJuICRjdXQgPyBqb2luVGV4dGJsb2Nrc0Fyb3VuZChzdGF0ZSwgJGN1dCwgZGlzcGF0Y2gpIDogZmFsc2U7XG59O1xuLyoqXG5BIG1vcmUgbGltaXRlZCBmb3JtIG9mIFtgam9pbkZvcndhcmRgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jY29tbWFuZHMuam9pbkZvcndhcmQpXG50aGF0IG9ubHkgdHJpZXMgdG8gam9pbiB0aGUgY3VycmVudCB0ZXh0YmxvY2sgdG8gdGhlIG9uZSBhZnRlclxuaXQsIGlmIHRoZSBjdXJzb3IgaXMgYXQgdGhlIGVuZCBvZiBhIHRleHRibG9jay5cbiovXG5jb25zdCBqb2luVGV4dGJsb2NrRm9yd2FyZCA9IChzdGF0ZSwgZGlzcGF0Y2gsIHZpZXcpID0+IHtcbiAgICBsZXQgJGN1cnNvciA9IGF0QmxvY2tFbmQoc3RhdGUsIHZpZXcpO1xuICAgIGlmICghJGN1cnNvcilcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGxldCAkY3V0ID0gZmluZEN1dEFmdGVyKCRjdXJzb3IpO1xuICAgIHJldHVybiAkY3V0ID8gam9pblRleHRibG9ja3NBcm91bmQoc3RhdGUsICRjdXQsIGRpc3BhdGNoKSA6IGZhbHNlO1xufTtcbmZ1bmN0aW9uIGpvaW5UZXh0YmxvY2tzQXJvdW5kKHN0YXRlLCAkY3V0LCBkaXNwYXRjaCkge1xuICAgIGxldCBiZWZvcmUgPSAkY3V0Lm5vZGVCZWZvcmUsIGJlZm9yZVRleHQgPSBiZWZvcmUsIGJlZm9yZVBvcyA9ICRjdXQucG9zIC0gMTtcbiAgICBmb3IgKDsgIWJlZm9yZVRleHQuaXNUZXh0YmxvY2s7IGJlZm9yZVBvcy0tKSB7XG4gICAgICAgIGlmIChiZWZvcmVUZXh0LnR5cGUuc3BlYy5pc29sYXRpbmcpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGxldCBjaGlsZCA9IGJlZm9yZVRleHQubGFzdENoaWxkO1xuICAgICAgICBpZiAoIWNoaWxkKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBiZWZvcmVUZXh0ID0gY2hpbGQ7XG4gICAgfVxuICAgIGxldCBhZnRlciA9ICRjdXQubm9kZUFmdGVyLCBhZnRlclRleHQgPSBhZnRlciwgYWZ0ZXJQb3MgPSAkY3V0LnBvcyArIDE7XG4gICAgZm9yICg7ICFhZnRlclRleHQuaXNUZXh0YmxvY2s7IGFmdGVyUG9zKyspIHtcbiAgICAgICAgaWYgKGFmdGVyVGV4dC50eXBlLnNwZWMuaXNvbGF0aW5nKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBsZXQgY2hpbGQgPSBhZnRlclRleHQuZmlyc3RDaGlsZDtcbiAgICAgICAgaWYgKCFjaGlsZClcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgYWZ0ZXJUZXh0ID0gY2hpbGQ7XG4gICAgfVxuICAgIGxldCBzdGVwID0gcmVwbGFjZVN0ZXAoc3RhdGUuZG9jLCBiZWZvcmVQb3MsIGFmdGVyUG9zLCBTbGljZS5lbXB0eSk7XG4gICAgaWYgKCFzdGVwIHx8IHN0ZXAuZnJvbSAhPSBiZWZvcmVQb3MgfHxcbiAgICAgICAgc3RlcCBpbnN0YW5jZW9mIFJlcGxhY2VTdGVwICYmIHN0ZXAuc2xpY2Uuc2l6ZSA+PSBhZnRlclBvcyAtIGJlZm9yZVBvcylcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChkaXNwYXRjaCkge1xuICAgICAgICBsZXQgdHIgPSBzdGF0ZS50ci5zdGVwKHN0ZXApO1xuICAgICAgICB0ci5zZXRTZWxlY3Rpb24oVGV4dFNlbGVjdGlvbi5jcmVhdGUodHIuZG9jLCBiZWZvcmVQb3MpKTtcbiAgICAgICAgZGlzcGF0Y2godHIuc2Nyb2xsSW50b1ZpZXcoKSk7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuZnVuY3Rpb24gdGV4dGJsb2NrQXQobm9kZSwgc2lkZSwgb25seSA9IGZhbHNlKSB7XG4gICAgZm9yIChsZXQgc2NhbiA9IG5vZGU7IHNjYW47IHNjYW4gPSAoc2lkZSA9PSBcInN0YXJ0XCIgPyBzY2FuLmZpcnN0Q2hpbGQgOiBzY2FuLmxhc3RDaGlsZCkpIHtcbiAgICAgICAgaWYgKHNjYW4uaXNUZXh0YmxvY2spXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgaWYgKG9ubHkgJiYgc2Nhbi5jaGlsZENvdW50ICE9IDEpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbi8qKlxuV2hlbiB0aGUgc2VsZWN0aW9uIGlzIGVtcHR5IGFuZCBhdCB0aGUgc3RhcnQgb2YgYSB0ZXh0YmxvY2ssIHNlbGVjdFxudGhlIG5vZGUgYmVmb3JlIHRoYXQgdGV4dGJsb2NrLCBpZiBwb3NzaWJsZS4gVGhpcyBpcyBpbnRlbmRlZCB0byBiZVxuYm91bmQgdG8ga2V5cyBsaWtlIGJhY2tzcGFjZSwgYWZ0ZXJcbltgam9pbkJhY2t3YXJkYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI2NvbW1hbmRzLmpvaW5CYWNrd2FyZCkgb3Igb3RoZXIgZGVsZXRpbmdcbmNvbW1hbmRzLCBhcyBhIGZhbGwtYmFjayBiZWhhdmlvciB3aGVuIHRoZSBzY2hlbWEgZG9lc24ndCBhbGxvd1xuZGVsZXRpb24gYXQgdGhlIHNlbGVjdGVkIHBvaW50LlxuKi9cbmNvbnN0IHNlbGVjdE5vZGVCYWNrd2FyZCA9IChzdGF0ZSwgZGlzcGF0Y2gsIHZpZXcpID0+IHtcbiAgICBsZXQgeyAkaGVhZCwgZW1wdHkgfSA9IHN0YXRlLnNlbGVjdGlvbiwgJGN1dCA9ICRoZWFkO1xuICAgIGlmICghZW1wdHkpXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICBpZiAoJGhlYWQucGFyZW50LmlzVGV4dGJsb2NrKSB7XG4gICAgICAgIGlmICh2aWV3ID8gIXZpZXcuZW5kT2ZUZXh0YmxvY2soXCJiYWNrd2FyZFwiLCBzdGF0ZSkgOiAkaGVhZC5wYXJlbnRPZmZzZXQgPiAwKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAkY3V0ID0gZmluZEN1dEJlZm9yZSgkaGVhZCk7XG4gICAgfVxuICAgIGxldCBub2RlID0gJGN1dCAmJiAkY3V0Lm5vZGVCZWZvcmU7XG4gICAgaWYgKCFub2RlIHx8ICFOb2RlU2VsZWN0aW9uLmlzU2VsZWN0YWJsZShub2RlKSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChkaXNwYXRjaClcbiAgICAgICAgZGlzcGF0Y2goc3RhdGUudHIuc2V0U2VsZWN0aW9uKE5vZGVTZWxlY3Rpb24uY3JlYXRlKHN0YXRlLmRvYywgJGN1dC5wb3MgLSBub2RlLm5vZGVTaXplKSkuc2Nyb2xsSW50b1ZpZXcoKSk7XG4gICAgcmV0dXJuIHRydWU7XG59O1xuZnVuY3Rpb24gZmluZEN1dEJlZm9yZSgkcG9zKSB7XG4gICAgaWYgKCEkcG9zLnBhcmVudC50eXBlLnNwZWMuaXNvbGF0aW5nKVxuICAgICAgICBmb3IgKGxldCBpID0gJHBvcy5kZXB0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICBpZiAoJHBvcy5pbmRleChpKSA+IDApXG4gICAgICAgICAgICAgICAgcmV0dXJuICRwb3MuZG9jLnJlc29sdmUoJHBvcy5iZWZvcmUoaSArIDEpKTtcbiAgICAgICAgICAgIGlmICgkcG9zLm5vZGUoaSkudHlwZS5zcGVjLmlzb2xhdGluZylcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuZnVuY3Rpb24gYXRCbG9ja0VuZChzdGF0ZSwgdmlldykge1xuICAgIGxldCB7ICRjdXJzb3IgfSA9IHN0YXRlLnNlbGVjdGlvbjtcbiAgICBpZiAoISRjdXJzb3IgfHwgKHZpZXcgPyAhdmlldy5lbmRPZlRleHRibG9jayhcImZvcndhcmRcIiwgc3RhdGUpXG4gICAgICAgIDogJGN1cnNvci5wYXJlbnRPZmZzZXQgPCAkY3Vyc29yLnBhcmVudC5jb250ZW50LnNpemUpKVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4gJGN1cnNvcjtcbn1cbi8qKlxuSWYgdGhlIHNlbGVjdGlvbiBpcyBlbXB0eSBhbmQgdGhlIGN1cnNvciBpcyBhdCB0aGUgZW5kIG9mIGFcbnRleHRibG9jaywgdHJ5IHRvIHJlZHVjZSBvciByZW1vdmUgdGhlIGJvdW5kYXJ5IGJldHdlZW4gdGhhdCBibG9ja1xuYW5kIHRoZSBvbmUgYWZ0ZXIgaXQsIGVpdGhlciBieSBqb2luaW5nIHRoZW0gb3IgYnkgbW92aW5nIHRoZSBvdGhlclxuYmxvY2sgY2xvc2VyIHRvIHRoaXMgb25lIGluIHRoZSB0cmVlIHN0cnVjdHVyZS4gV2lsbCB1c2UgdGhlIHZpZXdcbmZvciBhY2N1cmF0ZSBzdGFydC1vZi10ZXh0YmxvY2sgZGV0ZWN0aW9uIGlmIGdpdmVuLlxuKi9cbmNvbnN0IGpvaW5Gb3J3YXJkID0gKHN0YXRlLCBkaXNwYXRjaCwgdmlldykgPT4ge1xuICAgIGxldCAkY3Vyc29yID0gYXRCbG9ja0VuZChzdGF0ZSwgdmlldyk7XG4gICAgaWYgKCEkY3Vyc29yKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgbGV0ICRjdXQgPSBmaW5kQ3V0QWZ0ZXIoJGN1cnNvcik7XG4gICAgLy8gSWYgdGhlcmUgaXMgbm8gbm9kZSBhZnRlciB0aGlzLCB0aGVyZSdzIG5vdGhpbmcgdG8gZG9cbiAgICBpZiAoISRjdXQpXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICBsZXQgYWZ0ZXIgPSAkY3V0Lm5vZGVBZnRlcjtcbiAgICAvLyBUcnkgdGhlIGpvaW5pbmcgYWxnb3JpdGhtXG4gICAgaWYgKGRlbGV0ZUJhcnJpZXIoc3RhdGUsICRjdXQsIGRpc3BhdGNoLCAxKSlcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgLy8gSWYgdGhlIG5vZGUgYWJvdmUgaGFzIG5vIGNvbnRlbnQgYW5kIHRoZSBub2RlIGJlbG93IGlzXG4gICAgLy8gc2VsZWN0YWJsZSwgZGVsZXRlIHRoZSBub2RlIGFib3ZlIGFuZCBzZWxlY3QgdGhlIG9uZSBiZWxvdy5cbiAgICBpZiAoJGN1cnNvci5wYXJlbnQuY29udGVudC5zaXplID09IDAgJiZcbiAgICAgICAgKHRleHRibG9ja0F0KGFmdGVyLCBcInN0YXJ0XCIpIHx8IE5vZGVTZWxlY3Rpb24uaXNTZWxlY3RhYmxlKGFmdGVyKSkpIHtcbiAgICAgICAgbGV0IGRlbFN0ZXAgPSByZXBsYWNlU3RlcChzdGF0ZS5kb2MsICRjdXJzb3IuYmVmb3JlKCksICRjdXJzb3IuYWZ0ZXIoKSwgU2xpY2UuZW1wdHkpO1xuICAgICAgICBpZiAoZGVsU3RlcCAmJiBkZWxTdGVwLnNsaWNlLnNpemUgPCBkZWxTdGVwLnRvIC0gZGVsU3RlcC5mcm9tKSB7XG4gICAgICAgICAgICBpZiAoZGlzcGF0Y2gpIHtcbiAgICAgICAgICAgICAgICBsZXQgdHIgPSBzdGF0ZS50ci5zdGVwKGRlbFN0ZXApO1xuICAgICAgICAgICAgICAgIHRyLnNldFNlbGVjdGlvbih0ZXh0YmxvY2tBdChhZnRlciwgXCJzdGFydFwiKSA/IFNlbGVjdGlvbi5maW5kRnJvbSh0ci5kb2MucmVzb2x2ZSh0ci5tYXBwaW5nLm1hcCgkY3V0LnBvcykpLCAxKVxuICAgICAgICAgICAgICAgICAgICA6IE5vZGVTZWxlY3Rpb24uY3JlYXRlKHRyLmRvYywgdHIubWFwcGluZy5tYXAoJGN1dC5wb3MpKSk7XG4gICAgICAgICAgICAgICAgZGlzcGF0Y2godHIuc2Nyb2xsSW50b1ZpZXcoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBJZiB0aGUgbmV4dCBub2RlIGlzIGFuIGF0b20sIGRlbGV0ZSBpdFxuICAgIGlmIChhZnRlci5pc0F0b20gJiYgJGN1dC5kZXB0aCA9PSAkY3Vyc29yLmRlcHRoIC0gMSkge1xuICAgICAgICBpZiAoZGlzcGF0Y2gpXG4gICAgICAgICAgICBkaXNwYXRjaChzdGF0ZS50ci5kZWxldGUoJGN1dC5wb3MsICRjdXQucG9zICsgYWZ0ZXIubm9kZVNpemUpLnNjcm9sbEludG9WaWV3KCkpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufTtcbi8qKlxuV2hlbiB0aGUgc2VsZWN0aW9uIGlzIGVtcHR5IGFuZCBhdCB0aGUgZW5kIG9mIGEgdGV4dGJsb2NrLCBzZWxlY3RcbnRoZSBub2RlIGNvbWluZyBhZnRlciB0aGF0IHRleHRibG9jaywgaWYgcG9zc2libGUuIFRoaXMgaXMgaW50ZW5kZWRcbnRvIGJlIGJvdW5kIHRvIGtleXMgbGlrZSBkZWxldGUsIGFmdGVyXG5bYGpvaW5Gb3J3YXJkYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI2NvbW1hbmRzLmpvaW5Gb3J3YXJkKSBhbmQgc2ltaWxhciBkZWxldGluZ1xuY29tbWFuZHMsIHRvIHByb3ZpZGUgYSBmYWxsLWJhY2sgYmVoYXZpb3Igd2hlbiB0aGUgc2NoZW1hIGRvZXNuJ3RcbmFsbG93IGRlbGV0aW9uIGF0IHRoZSBzZWxlY3RlZCBwb2ludC5cbiovXG5jb25zdCBzZWxlY3ROb2RlRm9yd2FyZCA9IChzdGF0ZSwgZGlzcGF0Y2gsIHZpZXcpID0+IHtcbiAgICBsZXQgeyAkaGVhZCwgZW1wdHkgfSA9IHN0YXRlLnNlbGVjdGlvbiwgJGN1dCA9ICRoZWFkO1xuICAgIGlmICghZW1wdHkpXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICBpZiAoJGhlYWQucGFyZW50LmlzVGV4dGJsb2NrKSB7XG4gICAgICAgIGlmICh2aWV3ID8gIXZpZXcuZW5kT2ZUZXh0YmxvY2soXCJmb3J3YXJkXCIsIHN0YXRlKSA6ICRoZWFkLnBhcmVudE9mZnNldCA8ICRoZWFkLnBhcmVudC5jb250ZW50LnNpemUpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICRjdXQgPSBmaW5kQ3V0QWZ0ZXIoJGhlYWQpO1xuICAgIH1cbiAgICBsZXQgbm9kZSA9ICRjdXQgJiYgJGN1dC5ub2RlQWZ0ZXI7XG4gICAgaWYgKCFub2RlIHx8ICFOb2RlU2VsZWN0aW9uLmlzU2VsZWN0YWJsZShub2RlKSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChkaXNwYXRjaClcbiAgICAgICAgZGlzcGF0Y2goc3RhdGUudHIuc2V0U2VsZWN0aW9uKE5vZGVTZWxlY3Rpb24uY3JlYXRlKHN0YXRlLmRvYywgJGN1dC5wb3MpKS5zY3JvbGxJbnRvVmlldygpKTtcbiAgICByZXR1cm4gdHJ1ZTtcbn07XG5mdW5jdGlvbiBmaW5kQ3V0QWZ0ZXIoJHBvcykge1xuICAgIGlmICghJHBvcy5wYXJlbnQudHlwZS5zcGVjLmlzb2xhdGluZylcbiAgICAgICAgZm9yIChsZXQgaSA9ICRwb3MuZGVwdGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgICAgbGV0IHBhcmVudCA9ICRwb3Mubm9kZShpKTtcbiAgICAgICAgICAgIGlmICgkcG9zLmluZGV4KGkpICsgMSA8IHBhcmVudC5jaGlsZENvdW50KVxuICAgICAgICAgICAgICAgIHJldHVybiAkcG9zLmRvYy5yZXNvbHZlKCRwb3MuYWZ0ZXIoaSArIDEpKTtcbiAgICAgICAgICAgIGlmIChwYXJlbnQudHlwZS5zcGVjLmlzb2xhdGluZylcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuLyoqXG5Kb2luIHRoZSBzZWxlY3RlZCBibG9jayBvciwgaWYgdGhlcmUgaXMgYSB0ZXh0IHNlbGVjdGlvbiwgdGhlXG5jbG9zZXN0IGFuY2VzdG9yIGJsb2NrIG9mIHRoZSBzZWxlY3Rpb24gdGhhdCBjYW4gYmUgam9pbmVkLCB3aXRoXG50aGUgc2libGluZyBhYm92ZSBpdC5cbiovXG5jb25zdCBqb2luVXAgPSAoc3RhdGUsIGRpc3BhdGNoKSA9PiB7XG4gICAgbGV0IHNlbCA9IHN0YXRlLnNlbGVjdGlvbiwgbm9kZVNlbCA9IHNlbCBpbnN0YW5jZW9mIE5vZGVTZWxlY3Rpb24sIHBvaW50O1xuICAgIGlmIChub2RlU2VsKSB7XG4gICAgICAgIGlmIChzZWwubm9kZS5pc1RleHRibG9jayB8fCAhY2FuSm9pbihzdGF0ZS5kb2MsIHNlbC5mcm9tKSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgcG9pbnQgPSBzZWwuZnJvbTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHBvaW50ID0gam9pblBvaW50KHN0YXRlLmRvYywgc2VsLmZyb20sIC0xKTtcbiAgICAgICAgaWYgKHBvaW50ID09IG51bGwpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmIChkaXNwYXRjaCkge1xuICAgICAgICBsZXQgdHIgPSBzdGF0ZS50ci5qb2luKHBvaW50KTtcbiAgICAgICAgaWYgKG5vZGVTZWwpXG4gICAgICAgICAgICB0ci5zZXRTZWxlY3Rpb24oTm9kZVNlbGVjdGlvbi5jcmVhdGUodHIuZG9jLCBwb2ludCAtIHN0YXRlLmRvYy5yZXNvbHZlKHBvaW50KS5ub2RlQmVmb3JlLm5vZGVTaXplKSk7XG4gICAgICAgIGRpc3BhdGNoKHRyLnNjcm9sbEludG9WaWV3KCkpO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn07XG4vKipcbkpvaW4gdGhlIHNlbGVjdGVkIGJsb2NrLCBvciB0aGUgY2xvc2VzdCBhbmNlc3RvciBvZiB0aGUgc2VsZWN0aW9uXG50aGF0IGNhbiBiZSBqb2luZWQsIHdpdGggdGhlIHNpYmxpbmcgYWZ0ZXIgaXQuXG4qL1xuY29uc3Qgam9pbkRvd24gPSAoc3RhdGUsIGRpc3BhdGNoKSA9PiB7XG4gICAgbGV0IHNlbCA9IHN0YXRlLnNlbGVjdGlvbiwgcG9pbnQ7XG4gICAgaWYgKHNlbCBpbnN0YW5jZW9mIE5vZGVTZWxlY3Rpb24pIHtcbiAgICAgICAgaWYgKHNlbC5ub2RlLmlzVGV4dGJsb2NrIHx8ICFjYW5Kb2luKHN0YXRlLmRvYywgc2VsLnRvKSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgcG9pbnQgPSBzZWwudG87XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBwb2ludCA9IGpvaW5Qb2ludChzdGF0ZS5kb2MsIHNlbC50bywgMSk7XG4gICAgICAgIGlmIChwb2ludCA9PSBudWxsKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoZGlzcGF0Y2gpXG4gICAgICAgIGRpc3BhdGNoKHN0YXRlLnRyLmpvaW4ocG9pbnQpLnNjcm9sbEludG9WaWV3KCkpO1xuICAgIHJldHVybiB0cnVlO1xufTtcbi8qKlxuTGlmdCB0aGUgc2VsZWN0ZWQgYmxvY2ssIG9yIHRoZSBjbG9zZXN0IGFuY2VzdG9yIGJsb2NrIG9mIHRoZVxuc2VsZWN0aW9uIHRoYXQgY2FuIGJlIGxpZnRlZCwgb3V0IG9mIGl0cyBwYXJlbnQgbm9kZS5cbiovXG5jb25zdCBsaWZ0ID0gKHN0YXRlLCBkaXNwYXRjaCkgPT4ge1xuICAgIGxldCB7ICRmcm9tLCAkdG8gfSA9IHN0YXRlLnNlbGVjdGlvbjtcbiAgICBsZXQgcmFuZ2UgPSAkZnJvbS5ibG9ja1JhbmdlKCR0byksIHRhcmdldCA9IHJhbmdlICYmIGxpZnRUYXJnZXQocmFuZ2UpO1xuICAgIGlmICh0YXJnZXQgPT0gbnVsbClcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChkaXNwYXRjaClcbiAgICAgICAgZGlzcGF0Y2goc3RhdGUudHIubGlmdChyYW5nZSwgdGFyZ2V0KS5zY3JvbGxJbnRvVmlldygpKTtcbiAgICByZXR1cm4gdHJ1ZTtcbn07XG4vKipcbklmIHRoZSBzZWxlY3Rpb24gaXMgaW4gYSBub2RlIHdob3NlIHR5cGUgaGFzIGEgdHJ1dGh5XG5bYGNvZGVgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZVNwZWMuY29kZSkgcHJvcGVydHkgaW4gaXRzIHNwZWMsIHJlcGxhY2UgdGhlXG5zZWxlY3Rpb24gd2l0aCBhIG5ld2xpbmUgY2hhcmFjdGVyLlxuKi9cbmNvbnN0IG5ld2xpbmVJbkNvZGUgPSAoc3RhdGUsIGRpc3BhdGNoKSA9PiB7XG4gICAgbGV0IHsgJGhlYWQsICRhbmNob3IgfSA9IHN0YXRlLnNlbGVjdGlvbjtcbiAgICBpZiAoISRoZWFkLnBhcmVudC50eXBlLnNwZWMuY29kZSB8fCAhJGhlYWQuc2FtZVBhcmVudCgkYW5jaG9yKSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChkaXNwYXRjaClcbiAgICAgICAgZGlzcGF0Y2goc3RhdGUudHIuaW5zZXJ0VGV4dChcIlxcblwiKS5zY3JvbGxJbnRvVmlldygpKTtcbiAgICByZXR1cm4gdHJ1ZTtcbn07XG5mdW5jdGlvbiBkZWZhdWx0QmxvY2tBdChtYXRjaCkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbWF0Y2guZWRnZUNvdW50OyBpKyspIHtcbiAgICAgICAgbGV0IHsgdHlwZSB9ID0gbWF0Y2guZWRnZShpKTtcbiAgICAgICAgaWYgKHR5cGUuaXNUZXh0YmxvY2sgJiYgIXR5cGUuaGFzUmVxdWlyZWRBdHRycygpKVxuICAgICAgICAgICAgcmV0dXJuIHR5cGU7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuLyoqXG5XaGVuIHRoZSBzZWxlY3Rpb24gaXMgaW4gYSBub2RlIHdpdGggYSB0cnV0aHlcbltgY29kZWBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5Ob2RlU3BlYy5jb2RlKSBwcm9wZXJ0eSBpbiBpdHMgc3BlYywgY3JlYXRlIGFcbmRlZmF1bHQgYmxvY2sgYWZ0ZXIgdGhlIGNvZGUgYmxvY2ssIGFuZCBtb3ZlIHRoZSBjdXJzb3IgdGhlcmUuXG4qL1xuY29uc3QgZXhpdENvZGUgPSAoc3RhdGUsIGRpc3BhdGNoKSA9PiB7XG4gICAgbGV0IHsgJGhlYWQsICRhbmNob3IgfSA9IHN0YXRlLnNlbGVjdGlvbjtcbiAgICBpZiAoISRoZWFkLnBhcmVudC50eXBlLnNwZWMuY29kZSB8fCAhJGhlYWQuc2FtZVBhcmVudCgkYW5jaG9yKSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGxldCBhYm92ZSA9ICRoZWFkLm5vZGUoLTEpLCBhZnRlciA9ICRoZWFkLmluZGV4QWZ0ZXIoLTEpLCB0eXBlID0gZGVmYXVsdEJsb2NrQXQoYWJvdmUuY29udGVudE1hdGNoQXQoYWZ0ZXIpKTtcbiAgICBpZiAoIXR5cGUgfHwgIWFib3ZlLmNhblJlcGxhY2VXaXRoKGFmdGVyLCBhZnRlciwgdHlwZSkpXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICBpZiAoZGlzcGF0Y2gpIHtcbiAgICAgICAgbGV0IHBvcyA9ICRoZWFkLmFmdGVyKCksIHRyID0gc3RhdGUudHIucmVwbGFjZVdpdGgocG9zLCBwb3MsIHR5cGUuY3JlYXRlQW5kRmlsbCgpKTtcbiAgICAgICAgdHIuc2V0U2VsZWN0aW9uKFNlbGVjdGlvbi5uZWFyKHRyLmRvYy5yZXNvbHZlKHBvcyksIDEpKTtcbiAgICAgICAgZGlzcGF0Y2godHIuc2Nyb2xsSW50b1ZpZXcoKSk7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufTtcbi8qKlxuSWYgYSBibG9jayBub2RlIGlzIHNlbGVjdGVkLCBjcmVhdGUgYW4gZW1wdHkgcGFyYWdyYXBoIGJlZm9yZSAoaWZcbml0IGlzIGl0cyBwYXJlbnQncyBmaXJzdCBjaGlsZCkgb3IgYWZ0ZXIgaXQuXG4qL1xuY29uc3QgY3JlYXRlUGFyYWdyYXBoTmVhciA9IChzdGF0ZSwgZGlzcGF0Y2gpID0+IHtcbiAgICBsZXQgc2VsID0gc3RhdGUuc2VsZWN0aW9uLCB7ICRmcm9tLCAkdG8gfSA9IHNlbDtcbiAgICBpZiAoc2VsIGluc3RhbmNlb2YgQWxsU2VsZWN0aW9uIHx8ICRmcm9tLnBhcmVudC5pbmxpbmVDb250ZW50IHx8ICR0by5wYXJlbnQuaW5saW5lQ29udGVudClcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGxldCB0eXBlID0gZGVmYXVsdEJsb2NrQXQoJHRvLnBhcmVudC5jb250ZW50TWF0Y2hBdCgkdG8uaW5kZXhBZnRlcigpKSk7XG4gICAgaWYgKCF0eXBlIHx8ICF0eXBlLmlzVGV4dGJsb2NrKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgaWYgKGRpc3BhdGNoKSB7XG4gICAgICAgIGxldCBzaWRlID0gKCEkZnJvbS5wYXJlbnRPZmZzZXQgJiYgJHRvLmluZGV4KCkgPCAkdG8ucGFyZW50LmNoaWxkQ291bnQgPyAkZnJvbSA6ICR0bykucG9zO1xuICAgICAgICBsZXQgdHIgPSBzdGF0ZS50ci5pbnNlcnQoc2lkZSwgdHlwZS5jcmVhdGVBbmRGaWxsKCkpO1xuICAgICAgICB0ci5zZXRTZWxlY3Rpb24oVGV4dFNlbGVjdGlvbi5jcmVhdGUodHIuZG9jLCBzaWRlICsgMSkpO1xuICAgICAgICBkaXNwYXRjaCh0ci5zY3JvbGxJbnRvVmlldygpKTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59O1xuLyoqXG5JZiB0aGUgY3Vyc29yIGlzIGluIGFuIGVtcHR5IHRleHRibG9jayB0aGF0IGNhbiBiZSBsaWZ0ZWQsIGxpZnQgdGhlXG5ibG9jay5cbiovXG5jb25zdCBsaWZ0RW1wdHlCbG9jayA9IChzdGF0ZSwgZGlzcGF0Y2gpID0+IHtcbiAgICBsZXQgeyAkY3Vyc29yIH0gPSBzdGF0ZS5zZWxlY3Rpb247XG4gICAgaWYgKCEkY3Vyc29yIHx8ICRjdXJzb3IucGFyZW50LmNvbnRlbnQuc2l6ZSlcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIGlmICgkY3Vyc29yLmRlcHRoID4gMSAmJiAkY3Vyc29yLmFmdGVyKCkgIT0gJGN1cnNvci5lbmQoLTEpKSB7XG4gICAgICAgIGxldCBiZWZvcmUgPSAkY3Vyc29yLmJlZm9yZSgpO1xuICAgICAgICBpZiAoY2FuU3BsaXQoc3RhdGUuZG9jLCBiZWZvcmUpKSB7XG4gICAgICAgICAgICBpZiAoZGlzcGF0Y2gpXG4gICAgICAgICAgICAgICAgZGlzcGF0Y2goc3RhdGUudHIuc3BsaXQoYmVmb3JlKS5zY3JvbGxJbnRvVmlldygpKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIGxldCByYW5nZSA9ICRjdXJzb3IuYmxvY2tSYW5nZSgpLCB0YXJnZXQgPSByYW5nZSAmJiBsaWZ0VGFyZ2V0KHJhbmdlKTtcbiAgICBpZiAodGFyZ2V0ID09IG51bGwpXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICBpZiAoZGlzcGF0Y2gpXG4gICAgICAgIGRpc3BhdGNoKHN0YXRlLnRyLmxpZnQocmFuZ2UsIHRhcmdldCkuc2Nyb2xsSW50b1ZpZXcoKSk7XG4gICAgcmV0dXJuIHRydWU7XG59O1xuLyoqXG5DcmVhdGUgYSB2YXJpYW50IG9mIFtgc3BsaXRCbG9ja2BdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNjb21tYW5kcy5zcGxpdEJsb2NrKSB0aGF0IHVzZXNcbmEgY3VzdG9tIGZ1bmN0aW9uIHRvIGRldGVybWluZSB0aGUgdHlwZSBvZiB0aGUgbmV3bHkgc3BsaXQgb2ZmIGJsb2NrLlxuKi9cbmZ1bmN0aW9uIHNwbGl0QmxvY2tBcyhzcGxpdE5vZGUpIHtcbiAgICByZXR1cm4gKHN0YXRlLCBkaXNwYXRjaCkgPT4ge1xuICAgICAgICBsZXQgeyAkZnJvbSwgJHRvIH0gPSBzdGF0ZS5zZWxlY3Rpb247XG4gICAgICAgIGlmIChzdGF0ZS5zZWxlY3Rpb24gaW5zdGFuY2VvZiBOb2RlU2VsZWN0aW9uICYmIHN0YXRlLnNlbGVjdGlvbi5ub2RlLmlzQmxvY2spIHtcbiAgICAgICAgICAgIGlmICghJGZyb20ucGFyZW50T2Zmc2V0IHx8ICFjYW5TcGxpdChzdGF0ZS5kb2MsICRmcm9tLnBvcykpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgaWYgKGRpc3BhdGNoKVxuICAgICAgICAgICAgICAgIGRpc3BhdGNoKHN0YXRlLnRyLnNwbGl0KCRmcm9tLnBvcykuc2Nyb2xsSW50b1ZpZXcoKSk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoISRmcm9tLmRlcHRoKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBsZXQgdHlwZXMgPSBbXTtcbiAgICAgICAgbGV0IHNwbGl0RGVwdGgsIGRlZmx0LCBhdEVuZCA9IGZhbHNlLCBhdFN0YXJ0ID0gZmFsc2U7XG4gICAgICAgIGZvciAobGV0IGQgPSAkZnJvbS5kZXB0aDs7IGQtLSkge1xuICAgICAgICAgICAgbGV0IG5vZGUgPSAkZnJvbS5ub2RlKGQpO1xuICAgICAgICAgICAgaWYgKG5vZGUuaXNCbG9jaykge1xuICAgICAgICAgICAgICAgIGF0RW5kID0gJGZyb20uZW5kKGQpID09ICRmcm9tLnBvcyArICgkZnJvbS5kZXB0aCAtIGQpO1xuICAgICAgICAgICAgICAgIGF0U3RhcnQgPSAkZnJvbS5zdGFydChkKSA9PSAkZnJvbS5wb3MgLSAoJGZyb20uZGVwdGggLSBkKTtcbiAgICAgICAgICAgICAgICBkZWZsdCA9IGRlZmF1bHRCbG9ja0F0KCRmcm9tLm5vZGUoZCAtIDEpLmNvbnRlbnRNYXRjaEF0KCRmcm9tLmluZGV4QWZ0ZXIoZCAtIDEpKSk7XG4gICAgICAgICAgICAgICAgbGV0IHNwbGl0VHlwZSA9IHNwbGl0Tm9kZSAmJiBzcGxpdE5vZGUoJHRvLnBhcmVudCwgYXRFbmQsICRmcm9tKTtcbiAgICAgICAgICAgICAgICB0eXBlcy51bnNoaWZ0KHNwbGl0VHlwZSB8fCAoYXRFbmQgJiYgZGVmbHQgPyB7IHR5cGU6IGRlZmx0IH0gOiBudWxsKSk7XG4gICAgICAgICAgICAgICAgc3BsaXREZXB0aCA9IGQ7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAoZCA9PSAxKVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgdHlwZXMudW5zaGlmdChudWxsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgdHIgPSBzdGF0ZS50cjtcbiAgICAgICAgaWYgKHN0YXRlLnNlbGVjdGlvbiBpbnN0YW5jZW9mIFRleHRTZWxlY3Rpb24gfHwgc3RhdGUuc2VsZWN0aW9uIGluc3RhbmNlb2YgQWxsU2VsZWN0aW9uKVxuICAgICAgICAgICAgdHIuZGVsZXRlU2VsZWN0aW9uKCk7XG4gICAgICAgIGxldCBzcGxpdFBvcyA9IHRyLm1hcHBpbmcubWFwKCRmcm9tLnBvcyk7XG4gICAgICAgIGxldCBjYW4gPSBjYW5TcGxpdCh0ci5kb2MsIHNwbGl0UG9zLCB0eXBlcy5sZW5ndGgsIHR5cGVzKTtcbiAgICAgICAgaWYgKCFjYW4pIHtcbiAgICAgICAgICAgIHR5cGVzWzBdID0gZGVmbHQgPyB7IHR5cGU6IGRlZmx0IH0gOiBudWxsO1xuICAgICAgICAgICAgY2FuID0gY2FuU3BsaXQodHIuZG9jLCBzcGxpdFBvcywgdHlwZXMubGVuZ3RoLCB0eXBlcyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFjYW4pXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIHRyLnNwbGl0KHNwbGl0UG9zLCB0eXBlcy5sZW5ndGgsIHR5cGVzKTtcbiAgICAgICAgaWYgKCFhdEVuZCAmJiBhdFN0YXJ0ICYmICRmcm9tLm5vZGUoc3BsaXREZXB0aCkudHlwZSAhPSBkZWZsdCkge1xuICAgICAgICAgICAgbGV0IGZpcnN0ID0gdHIubWFwcGluZy5tYXAoJGZyb20uYmVmb3JlKHNwbGl0RGVwdGgpKSwgJGZpcnN0ID0gdHIuZG9jLnJlc29sdmUoZmlyc3QpO1xuICAgICAgICAgICAgaWYgKGRlZmx0ICYmICRmcm9tLm5vZGUoc3BsaXREZXB0aCAtIDEpLmNhblJlcGxhY2VXaXRoKCRmaXJzdC5pbmRleCgpLCAkZmlyc3QuaW5kZXgoKSArIDEsIGRlZmx0KSlcbiAgICAgICAgICAgICAgICB0ci5zZXROb2RlTWFya3VwKHRyLm1hcHBpbmcubWFwKCRmcm9tLmJlZm9yZShzcGxpdERlcHRoKSksIGRlZmx0KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGlzcGF0Y2gpXG4gICAgICAgICAgICBkaXNwYXRjaCh0ci5zY3JvbGxJbnRvVmlldygpKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcbn1cbi8qKlxuU3BsaXQgdGhlIHBhcmVudCBibG9jayBvZiB0aGUgc2VsZWN0aW9uLiBJZiB0aGUgc2VsZWN0aW9uIGlzIGEgdGV4dFxuc2VsZWN0aW9uLCBhbHNvIGRlbGV0ZSBpdHMgY29udGVudC5cbiovXG5jb25zdCBzcGxpdEJsb2NrID0gc3BsaXRCbG9ja0FzKCk7XG4vKipcbkFjdHMgbGlrZSBbYHNwbGl0QmxvY2tgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jY29tbWFuZHMuc3BsaXRCbG9jayksIGJ1dCB3aXRob3V0XG5yZXNldHRpbmcgdGhlIHNldCBvZiBhY3RpdmUgbWFya3MgYXQgdGhlIGN1cnNvci5cbiovXG5jb25zdCBzcGxpdEJsb2NrS2VlcE1hcmtzID0gKHN0YXRlLCBkaXNwYXRjaCkgPT4ge1xuICAgIHJldHVybiBzcGxpdEJsb2NrKHN0YXRlLCBkaXNwYXRjaCAmJiAodHIgPT4ge1xuICAgICAgICBsZXQgbWFya3MgPSBzdGF0ZS5zdG9yZWRNYXJrcyB8fCAoc3RhdGUuc2VsZWN0aW9uLiR0by5wYXJlbnRPZmZzZXQgJiYgc3RhdGUuc2VsZWN0aW9uLiRmcm9tLm1hcmtzKCkpO1xuICAgICAgICBpZiAobWFya3MpXG4gICAgICAgICAgICB0ci5lbnN1cmVNYXJrcyhtYXJrcyk7XG4gICAgICAgIGRpc3BhdGNoKHRyKTtcbiAgICB9KSk7XG59O1xuLyoqXG5Nb3ZlIHRoZSBzZWxlY3Rpb24gdG8gdGhlIG5vZGUgd3JhcHBpbmcgdGhlIGN1cnJlbnQgc2VsZWN0aW9uLCBpZlxuYW55LiAoV2lsbCBub3Qgc2VsZWN0IHRoZSBkb2N1bWVudCBub2RlLilcbiovXG5jb25zdCBzZWxlY3RQYXJlbnROb2RlID0gKHN0YXRlLCBkaXNwYXRjaCkgPT4ge1xuICAgIGxldCB7ICRmcm9tLCB0byB9ID0gc3RhdGUuc2VsZWN0aW9uLCBwb3M7XG4gICAgbGV0IHNhbWUgPSAkZnJvbS5zaGFyZWREZXB0aCh0byk7XG4gICAgaWYgKHNhbWUgPT0gMClcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIHBvcyA9ICRmcm9tLmJlZm9yZShzYW1lKTtcbiAgICBpZiAoZGlzcGF0Y2gpXG4gICAgICAgIGRpc3BhdGNoKHN0YXRlLnRyLnNldFNlbGVjdGlvbihOb2RlU2VsZWN0aW9uLmNyZWF0ZShzdGF0ZS5kb2MsIHBvcykpKTtcbiAgICByZXR1cm4gdHJ1ZTtcbn07XG4vKipcblNlbGVjdCB0aGUgd2hvbGUgZG9jdW1lbnQuXG4qL1xuY29uc3Qgc2VsZWN0QWxsID0gKHN0YXRlLCBkaXNwYXRjaCkgPT4ge1xuICAgIGlmIChkaXNwYXRjaClcbiAgICAgICAgZGlzcGF0Y2goc3RhdGUudHIuc2V0U2VsZWN0aW9uKG5ldyBBbGxTZWxlY3Rpb24oc3RhdGUuZG9jKSkpO1xuICAgIHJldHVybiB0cnVlO1xufTtcbmZ1bmN0aW9uIGpvaW5NYXliZUNsZWFyKHN0YXRlLCAkcG9zLCBkaXNwYXRjaCkge1xuICAgIGxldCBiZWZvcmUgPSAkcG9zLm5vZGVCZWZvcmUsIGFmdGVyID0gJHBvcy5ub2RlQWZ0ZXIsIGluZGV4ID0gJHBvcy5pbmRleCgpO1xuICAgIGlmICghYmVmb3JlIHx8ICFhZnRlciB8fCAhYmVmb3JlLnR5cGUuY29tcGF0aWJsZUNvbnRlbnQoYWZ0ZXIudHlwZSkpXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICBpZiAoIWJlZm9yZS5jb250ZW50LnNpemUgJiYgJHBvcy5wYXJlbnQuY2FuUmVwbGFjZShpbmRleCAtIDEsIGluZGV4KSkge1xuICAgICAgICBpZiAoZGlzcGF0Y2gpXG4gICAgICAgICAgICBkaXNwYXRjaChzdGF0ZS50ci5kZWxldGUoJHBvcy5wb3MgLSBiZWZvcmUubm9kZVNpemUsICRwb3MucG9zKS5zY3JvbGxJbnRvVmlldygpKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmICghJHBvcy5wYXJlbnQuY2FuUmVwbGFjZShpbmRleCwgaW5kZXggKyAxKSB8fCAhKGFmdGVyLmlzVGV4dGJsb2NrIHx8IGNhbkpvaW4oc3RhdGUuZG9jLCAkcG9zLnBvcykpKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgaWYgKGRpc3BhdGNoKVxuICAgICAgICBkaXNwYXRjaChzdGF0ZS50ci5qb2luKCRwb3MucG9zKS5zY3JvbGxJbnRvVmlldygpKTtcbiAgICByZXR1cm4gdHJ1ZTtcbn1cbmZ1bmN0aW9uIGRlbGV0ZUJhcnJpZXIoc3RhdGUsICRjdXQsIGRpc3BhdGNoLCBkaXIpIHtcbiAgICBsZXQgYmVmb3JlID0gJGN1dC5ub2RlQmVmb3JlLCBhZnRlciA9ICRjdXQubm9kZUFmdGVyLCBjb25uLCBtYXRjaDtcbiAgICBsZXQgaXNvbGF0ZWQgPSBiZWZvcmUudHlwZS5zcGVjLmlzb2xhdGluZyB8fCBhZnRlci50eXBlLnNwZWMuaXNvbGF0aW5nO1xuICAgIGlmICghaXNvbGF0ZWQgJiYgam9pbk1heWJlQ2xlYXIoc3RhdGUsICRjdXQsIGRpc3BhdGNoKSlcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgbGV0IGNhbkRlbEFmdGVyID0gIWlzb2xhdGVkICYmICRjdXQucGFyZW50LmNhblJlcGxhY2UoJGN1dC5pbmRleCgpLCAkY3V0LmluZGV4KCkgKyAxKTtcbiAgICBpZiAoY2FuRGVsQWZ0ZXIgJiZcbiAgICAgICAgKGNvbm4gPSAobWF0Y2ggPSBiZWZvcmUuY29udGVudE1hdGNoQXQoYmVmb3JlLmNoaWxkQ291bnQpKS5maW5kV3JhcHBpbmcoYWZ0ZXIudHlwZSkpICYmXG4gICAgICAgIG1hdGNoLm1hdGNoVHlwZShjb25uWzBdIHx8IGFmdGVyLnR5cGUpLnZhbGlkRW5kKSB7XG4gICAgICAgIGlmIChkaXNwYXRjaCkge1xuICAgICAgICAgICAgbGV0IGVuZCA9ICRjdXQucG9zICsgYWZ0ZXIubm9kZVNpemUsIHdyYXAgPSBGcmFnbWVudC5lbXB0eTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSBjb25uLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKVxuICAgICAgICAgICAgICAgIHdyYXAgPSBGcmFnbWVudC5mcm9tKGNvbm5baV0uY3JlYXRlKG51bGwsIHdyYXApKTtcbiAgICAgICAgICAgIHdyYXAgPSBGcmFnbWVudC5mcm9tKGJlZm9yZS5jb3B5KHdyYXApKTtcbiAgICAgICAgICAgIGxldCB0ciA9IHN0YXRlLnRyLnN0ZXAobmV3IFJlcGxhY2VBcm91bmRTdGVwKCRjdXQucG9zIC0gMSwgZW5kLCAkY3V0LnBvcywgZW5kLCBuZXcgU2xpY2Uod3JhcCwgMSwgMCksIGNvbm4ubGVuZ3RoLCB0cnVlKSk7XG4gICAgICAgICAgICBsZXQgJGpvaW5BdCA9IHRyLmRvYy5yZXNvbHZlKGVuZCArIDIgKiBjb25uLmxlbmd0aCk7XG4gICAgICAgICAgICBpZiAoJGpvaW5BdC5ub2RlQWZ0ZXIgJiYgJGpvaW5BdC5ub2RlQWZ0ZXIudHlwZSA9PSBiZWZvcmUudHlwZSAmJlxuICAgICAgICAgICAgICAgIGNhbkpvaW4odHIuZG9jLCAkam9pbkF0LnBvcykpXG4gICAgICAgICAgICAgICAgdHIuam9pbigkam9pbkF0LnBvcyk7XG4gICAgICAgICAgICBkaXNwYXRjaCh0ci5zY3JvbGxJbnRvVmlldygpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgbGV0IHNlbEFmdGVyID0gYWZ0ZXIudHlwZS5zcGVjLmlzb2xhdGluZyB8fCAoZGlyID4gMCAmJiBpc29sYXRlZCkgPyBudWxsIDogU2VsZWN0aW9uLmZpbmRGcm9tKCRjdXQsIDEpO1xuICAgIGxldCByYW5nZSA9IHNlbEFmdGVyICYmIHNlbEFmdGVyLiRmcm9tLmJsb2NrUmFuZ2Uoc2VsQWZ0ZXIuJHRvKSwgdGFyZ2V0ID0gcmFuZ2UgJiYgbGlmdFRhcmdldChyYW5nZSk7XG4gICAgaWYgKHRhcmdldCAhPSBudWxsICYmIHRhcmdldCA+PSAkY3V0LmRlcHRoKSB7XG4gICAgICAgIGlmIChkaXNwYXRjaClcbiAgICAgICAgICAgIGRpc3BhdGNoKHN0YXRlLnRyLmxpZnQocmFuZ2UsIHRhcmdldCkuc2Nyb2xsSW50b1ZpZXcoKSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAoY2FuRGVsQWZ0ZXIgJiYgdGV4dGJsb2NrQXQoYWZ0ZXIsIFwic3RhcnRcIiwgdHJ1ZSkgJiYgdGV4dGJsb2NrQXQoYmVmb3JlLCBcImVuZFwiKSkge1xuICAgICAgICBsZXQgYXQgPSBiZWZvcmUsIHdyYXAgPSBbXTtcbiAgICAgICAgZm9yICg7Oykge1xuICAgICAgICAgICAgd3JhcC5wdXNoKGF0KTtcbiAgICAgICAgICAgIGlmIChhdC5pc1RleHRibG9jaylcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGF0ID0gYXQubGFzdENoaWxkO1xuICAgICAgICB9XG4gICAgICAgIGxldCBhZnRlclRleHQgPSBhZnRlciwgYWZ0ZXJEZXB0aCA9IDE7XG4gICAgICAgIGZvciAoOyAhYWZ0ZXJUZXh0LmlzVGV4dGJsb2NrOyBhZnRlclRleHQgPSBhZnRlclRleHQuZmlyc3RDaGlsZClcbiAgICAgICAgICAgIGFmdGVyRGVwdGgrKztcbiAgICAgICAgaWYgKGF0LmNhblJlcGxhY2UoYXQuY2hpbGRDb3VudCwgYXQuY2hpbGRDb3VudCwgYWZ0ZXJUZXh0LmNvbnRlbnQpKSB7XG4gICAgICAgICAgICBpZiAoZGlzcGF0Y2gpIHtcbiAgICAgICAgICAgICAgICBsZXQgZW5kID0gRnJhZ21lbnQuZW1wdHk7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IHdyYXAubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pXG4gICAgICAgICAgICAgICAgICAgIGVuZCA9IEZyYWdtZW50LmZyb20od3JhcFtpXS5jb3B5KGVuZCkpO1xuICAgICAgICAgICAgICAgIGxldCB0ciA9IHN0YXRlLnRyLnN0ZXAobmV3IFJlcGxhY2VBcm91bmRTdGVwKCRjdXQucG9zIC0gd3JhcC5sZW5ndGgsICRjdXQucG9zICsgYWZ0ZXIubm9kZVNpemUsICRjdXQucG9zICsgYWZ0ZXJEZXB0aCwgJGN1dC5wb3MgKyBhZnRlci5ub2RlU2l6ZSAtIGFmdGVyRGVwdGgsIG5ldyBTbGljZShlbmQsIHdyYXAubGVuZ3RoLCAwKSwgMCwgdHJ1ZSkpO1xuICAgICAgICAgICAgICAgIGRpc3BhdGNoKHRyLnNjcm9sbEludG9WaWV3KCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuZnVuY3Rpb24gc2VsZWN0VGV4dGJsb2NrU2lkZShzaWRlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChzdGF0ZSwgZGlzcGF0Y2gpIHtcbiAgICAgICAgbGV0IHNlbCA9IHN0YXRlLnNlbGVjdGlvbiwgJHBvcyA9IHNpZGUgPCAwID8gc2VsLiRmcm9tIDogc2VsLiR0bztcbiAgICAgICAgbGV0IGRlcHRoID0gJHBvcy5kZXB0aDtcbiAgICAgICAgd2hpbGUgKCRwb3Mubm9kZShkZXB0aCkuaXNJbmxpbmUpIHtcbiAgICAgICAgICAgIGlmICghZGVwdGgpXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgZGVwdGgtLTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoISRwb3Mubm9kZShkZXB0aCkuaXNUZXh0YmxvY2spXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGlmIChkaXNwYXRjaClcbiAgICAgICAgICAgIGRpc3BhdGNoKHN0YXRlLnRyLnNldFNlbGVjdGlvbihUZXh0U2VsZWN0aW9uLmNyZWF0ZShzdGF0ZS5kb2MsIHNpZGUgPCAwID8gJHBvcy5zdGFydChkZXB0aCkgOiAkcG9zLmVuZChkZXB0aCkpKSk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG59XG4vKipcbk1vdmVzIHRoZSBjdXJzb3IgdG8gdGhlIHN0YXJ0IG9mIGN1cnJlbnQgdGV4dCBibG9jay5cbiovXG5jb25zdCBzZWxlY3RUZXh0YmxvY2tTdGFydCA9IHNlbGVjdFRleHRibG9ja1NpZGUoLTEpO1xuLyoqXG5Nb3ZlcyB0aGUgY3Vyc29yIHRvIHRoZSBlbmQgb2YgY3VycmVudCB0ZXh0IGJsb2NrLlxuKi9cbmNvbnN0IHNlbGVjdFRleHRibG9ja0VuZCA9IHNlbGVjdFRleHRibG9ja1NpZGUoMSk7XG4vLyBQYXJhbWV0ZXJpemVkIGNvbW1hbmRzXG4vKipcbldyYXAgdGhlIHNlbGVjdGlvbiBpbiBhIG5vZGUgb2YgdGhlIGdpdmVuIHR5cGUgd2l0aCB0aGUgZ2l2ZW5cbmF0dHJpYnV0ZXMuXG4qL1xuZnVuY3Rpb24gd3JhcEluKG5vZGVUeXBlLCBhdHRycyA9IG51bGwpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHN0YXRlLCBkaXNwYXRjaCkge1xuICAgICAgICBsZXQgeyAkZnJvbSwgJHRvIH0gPSBzdGF0ZS5zZWxlY3Rpb247XG4gICAgICAgIGxldCByYW5nZSA9ICRmcm9tLmJsb2NrUmFuZ2UoJHRvKSwgd3JhcHBpbmcgPSByYW5nZSAmJiBmaW5kV3JhcHBpbmcocmFuZ2UsIG5vZGVUeXBlLCBhdHRycyk7XG4gICAgICAgIGlmICghd3JhcHBpbmcpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGlmIChkaXNwYXRjaClcbiAgICAgICAgICAgIGRpc3BhdGNoKHN0YXRlLnRyLndyYXAocmFuZ2UsIHdyYXBwaW5nKS5zY3JvbGxJbnRvVmlldygpKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcbn1cbi8qKlxuUmV0dXJucyBhIGNvbW1hbmQgdGhhdCB0cmllcyB0byBzZXQgdGhlIHNlbGVjdGVkIHRleHRibG9ja3MgdG8gdGhlXG5naXZlbiBub2RlIHR5cGUgd2l0aCB0aGUgZ2l2ZW4gYXR0cmlidXRlcy5cbiovXG5mdW5jdGlvbiBzZXRCbG9ja1R5cGUobm9kZVR5cGUsIGF0dHJzID0gbnVsbCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoc3RhdGUsIGRpc3BhdGNoKSB7XG4gICAgICAgIGxldCBhcHBsaWNhYmxlID0gZmFsc2U7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3RhdGUuc2VsZWN0aW9uLnJhbmdlcy5sZW5ndGggJiYgIWFwcGxpY2FibGU7IGkrKykge1xuICAgICAgICAgICAgbGV0IHsgJGZyb206IHsgcG9zOiBmcm9tIH0sICR0bzogeyBwb3M6IHRvIH0gfSA9IHN0YXRlLnNlbGVjdGlvbi5yYW5nZXNbaV07XG4gICAgICAgICAgICBzdGF0ZS5kb2Mubm9kZXNCZXR3ZWVuKGZyb20sIHRvLCAobm9kZSwgcG9zKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGFwcGxpY2FibGUpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICBpZiAoIW5vZGUuaXNUZXh0YmxvY2sgfHwgbm9kZS5oYXNNYXJrdXAobm9kZVR5cGUsIGF0dHJzKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIGlmIChub2RlLnR5cGUgPT0gbm9kZVR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgYXBwbGljYWJsZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBsZXQgJHBvcyA9IHN0YXRlLmRvYy5yZXNvbHZlKHBvcyksIGluZGV4ID0gJHBvcy5pbmRleCgpO1xuICAgICAgICAgICAgICAgICAgICBhcHBsaWNhYmxlID0gJHBvcy5wYXJlbnQuY2FuUmVwbGFjZVdpdGgoaW5kZXgsIGluZGV4ICsgMSwgbm9kZVR5cGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICghYXBwbGljYWJsZSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgaWYgKGRpc3BhdGNoKSB7XG4gICAgICAgICAgICBsZXQgdHIgPSBzdGF0ZS50cjtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3RhdGUuc2VsZWN0aW9uLnJhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGxldCB7ICRmcm9tOiB7IHBvczogZnJvbSB9LCAkdG86IHsgcG9zOiB0byB9IH0gPSBzdGF0ZS5zZWxlY3Rpb24ucmFuZ2VzW2ldO1xuICAgICAgICAgICAgICAgIHRyLnNldEJsb2NrVHlwZShmcm9tLCB0bywgbm9kZVR5cGUsIGF0dHJzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRpc3BhdGNoKHRyLnNjcm9sbEludG9WaWV3KCkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG59XG5mdW5jdGlvbiBtYXJrQXBwbGllcyhkb2MsIHJhbmdlcywgdHlwZSwgZW50ZXJBdG9tcykge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxldCB7ICRmcm9tLCAkdG8gfSA9IHJhbmdlc1tpXTtcbiAgICAgICAgbGV0IGNhbiA9ICRmcm9tLmRlcHRoID09IDAgPyBkb2MuaW5saW5lQ29udGVudCAmJiBkb2MudHlwZS5hbGxvd3NNYXJrVHlwZSh0eXBlKSA6IGZhbHNlO1xuICAgICAgICBkb2Mubm9kZXNCZXR3ZWVuKCRmcm9tLnBvcywgJHRvLnBvcywgKG5vZGUsIHBvcykgPT4ge1xuICAgICAgICAgICAgaWYgKGNhbiB8fCAhZW50ZXJBdG9tcyAmJiBub2RlLmlzQXRvbSAmJiBub2RlLmlzSW5saW5lICYmIHBvcyA+PSAkZnJvbS5wb3MgJiYgcG9zICsgbm9kZS5ub2RlU2l6ZSA8PSAkdG8ucG9zKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIGNhbiA9IG5vZGUuaW5saW5lQ29udGVudCAmJiBub2RlLnR5cGUuYWxsb3dzTWFya1R5cGUodHlwZSk7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoY2FuKVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbmZ1bmN0aW9uIHJlbW92ZUlubGluZUF0b21zKHJhbmdlcykge1xuICAgIGxldCByZXN1bHQgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBsZXQgeyAkZnJvbSwgJHRvIH0gPSByYW5nZXNbaV07XG4gICAgICAgICRmcm9tLmRvYy5ub2Rlc0JldHdlZW4oJGZyb20ucG9zLCAkdG8ucG9zLCAobm9kZSwgcG9zKSA9PiB7XG4gICAgICAgICAgICBpZiAobm9kZS5pc0F0b20gJiYgbm9kZS5jb250ZW50LnNpemUgJiYgbm9kZS5pc0lubGluZSAmJiBwb3MgPj0gJGZyb20ucG9zICYmIHBvcyArIG5vZGUubm9kZVNpemUgPD0gJHRvLnBvcykge1xuICAgICAgICAgICAgICAgIGlmIChwb3MgKyAxID4gJGZyb20ucG9zKVxuICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaChuZXcgU2VsZWN0aW9uUmFuZ2UoJGZyb20sICRmcm9tLmRvYy5yZXNvbHZlKHBvcyArIDEpKSk7XG4gICAgICAgICAgICAgICAgJGZyb20gPSAkZnJvbS5kb2MucmVzb2x2ZShwb3MgKyAxICsgbm9kZS5jb250ZW50LnNpemUpO1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGlmICgkZnJvbS5wb3MgPCAkdG8ucG9zKVxuICAgICAgICAgICAgcmVzdWx0LnB1c2gobmV3IFNlbGVjdGlvblJhbmdlKCRmcm9tLCAkdG8pKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbi8qKlxuQ3JlYXRlIGEgY29tbWFuZCBmdW5jdGlvbiB0aGF0IHRvZ2dsZXMgdGhlIGdpdmVuIG1hcmsgd2l0aCB0aGVcbmdpdmVuIGF0dHJpYnV0ZXMuIFdpbGwgcmV0dXJuIGBmYWxzZWAgd2hlbiB0aGUgY3VycmVudCBzZWxlY3Rpb25cbmRvZXNuJ3Qgc3VwcG9ydCB0aGF0IG1hcmsuIFRoaXMgd2lsbCByZW1vdmUgdGhlIG1hcmsgaWYgYW55IG1hcmtzXG5vZiB0aGF0IHR5cGUgZXhpc3QgaW4gdGhlIHNlbGVjdGlvbiwgb3IgYWRkIGl0IG90aGVyd2lzZS4gSWYgdGhlXG5zZWxlY3Rpb24gaXMgZW1wdHksIHRoaXMgYXBwbGllcyB0byB0aGUgW3N0b3JlZFxubWFya3NdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNzdGF0ZS5FZGl0b3JTdGF0ZS5zdG9yZWRNYXJrcykgaW5zdGVhZCBvZiBhIHJhbmdlIG9mIHRoZVxuZG9jdW1lbnQuXG4qL1xuZnVuY3Rpb24gdG9nZ2xlTWFyayhtYXJrVHlwZSwgYXR0cnMgPSBudWxsLCBvcHRpb25zKSB7XG4gICAgbGV0IHJlbW92ZVdoZW5QcmVzZW50ID0gKG9wdGlvbnMgJiYgb3B0aW9ucy5yZW1vdmVXaGVuUHJlc2VudCkgIT09IGZhbHNlO1xuICAgIGxldCBlbnRlckF0b21zID0gKG9wdGlvbnMgJiYgb3B0aW9ucy5lbnRlcklubGluZUF0b21zKSAhPT0gZmFsc2U7XG4gICAgbGV0IGRyb3BTcGFjZSA9ICEob3B0aW9ucyAmJiBvcHRpb25zLmluY2x1ZGVXaGl0ZXNwYWNlKTtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHN0YXRlLCBkaXNwYXRjaCkge1xuICAgICAgICBsZXQgeyBlbXB0eSwgJGN1cnNvciwgcmFuZ2VzIH0gPSBzdGF0ZS5zZWxlY3Rpb247XG4gICAgICAgIGlmICgoZW1wdHkgJiYgISRjdXJzb3IpIHx8ICFtYXJrQXBwbGllcyhzdGF0ZS5kb2MsIHJhbmdlcywgbWFya1R5cGUsIGVudGVyQXRvbXMpKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBpZiAoZGlzcGF0Y2gpIHtcbiAgICAgICAgICAgIGlmICgkY3Vyc29yKSB7XG4gICAgICAgICAgICAgICAgaWYgKG1hcmtUeXBlLmlzSW5TZXQoc3RhdGUuc3RvcmVkTWFya3MgfHwgJGN1cnNvci5tYXJrcygpKSlcbiAgICAgICAgICAgICAgICAgICAgZGlzcGF0Y2goc3RhdGUudHIucmVtb3ZlU3RvcmVkTWFyayhtYXJrVHlwZSkpO1xuICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgZGlzcGF0Y2goc3RhdGUudHIuYWRkU3RvcmVkTWFyayhtYXJrVHlwZS5jcmVhdGUoYXR0cnMpKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBsZXQgYWRkLCB0ciA9IHN0YXRlLnRyO1xuICAgICAgICAgICAgICAgIGlmICghZW50ZXJBdG9tcylcbiAgICAgICAgICAgICAgICAgICAgcmFuZ2VzID0gcmVtb3ZlSW5saW5lQXRvbXMocmFuZ2VzKTtcbiAgICAgICAgICAgICAgICBpZiAocmVtb3ZlV2hlblByZXNlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgYWRkID0gIXJhbmdlcy5zb21lKHIgPT4gc3RhdGUuZG9jLnJhbmdlSGFzTWFyayhyLiRmcm9tLnBvcywgci4kdG8ucG9zLCBtYXJrVHlwZSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYWRkID0gIXJhbmdlcy5ldmVyeShyID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBtaXNzaW5nID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICB0ci5kb2Mubm9kZXNCZXR3ZWVuKHIuJGZyb20ucG9zLCByLiR0by5wb3MsIChub2RlLCBwb3MsIHBhcmVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtaXNzaW5nKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWlzc2luZyA9ICFtYXJrVHlwZS5pc0luU2V0KG5vZGUubWFya3MpICYmICEhcGFyZW50ICYmIHBhcmVudC50eXBlLmFsbG93c01hcmtUeXBlKG1hcmtUeXBlKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhKG5vZGUuaXNUZXh0ICYmIC9eXFxzKiQvLnRlc3Qobm9kZS50ZXh0QmV0d2VlbihNYXRoLm1heCgwLCByLiRmcm9tLnBvcyAtIHBvcyksIE1hdGgubWluKG5vZGUubm9kZVNpemUsIHIuJHRvLnBvcyAtIHBvcykpKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAhbWlzc2luZztcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCB7ICRmcm9tLCAkdG8gfSA9IHJhbmdlc1tpXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFhZGQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyLnJlbW92ZU1hcmsoJGZyb20ucG9zLCAkdG8ucG9zLCBtYXJrVHlwZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgZnJvbSA9ICRmcm9tLnBvcywgdG8gPSAkdG8ucG9zLCBzdGFydCA9ICRmcm9tLm5vZGVBZnRlciwgZW5kID0gJHRvLm5vZGVCZWZvcmU7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgc3BhY2VTdGFydCA9IGRyb3BTcGFjZSAmJiBzdGFydCAmJiBzdGFydC5pc1RleHQgPyAvXlxccyovLmV4ZWMoc3RhcnQudGV4dClbMF0ubGVuZ3RoIDogMDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBzcGFjZUVuZCA9IGRyb3BTcGFjZSAmJiBlbmQgJiYgZW5kLmlzVGV4dCA/IC9cXHMqJC8uZXhlYyhlbmQudGV4dClbMF0ubGVuZ3RoIDogMDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmcm9tICsgc3BhY2VTdGFydCA8IHRvKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbSArPSBzcGFjZVN0YXJ0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvIC09IHNwYWNlRW5kO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgdHIuYWRkTWFyayhmcm9tLCB0bywgbWFya1R5cGUuY3JlYXRlKGF0dHJzKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGlzcGF0Y2godHIuc2Nyb2xsSW50b1ZpZXcoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcbn1cbmZ1bmN0aW9uIHdyYXBEaXNwYXRjaEZvckpvaW4oZGlzcGF0Y2gsIGlzSm9pbmFibGUpIHtcbiAgICByZXR1cm4gKHRyKSA9PiB7XG4gICAgICAgIGlmICghdHIuaXNHZW5lcmljKVxuICAgICAgICAgICAgcmV0dXJuIGRpc3BhdGNoKHRyKTtcbiAgICAgICAgbGV0IHJhbmdlcyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRyLm1hcHBpbmcubWFwcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgbGV0IG1hcCA9IHRyLm1hcHBpbmcubWFwc1tpXTtcbiAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgcmFuZ2VzLmxlbmd0aDsgaisrKVxuICAgICAgICAgICAgICAgIHJhbmdlc1tqXSA9IG1hcC5tYXAocmFuZ2VzW2pdKTtcbiAgICAgICAgICAgIG1hcC5mb3JFYWNoKChfcywgX2UsIGZyb20sIHRvKSA9PiByYW5nZXMucHVzaChmcm9tLCB0bykpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEZpZ3VyZSBvdXQgd2hpY2ggam9pbmFibGUgcG9pbnRzIGV4aXN0IGluc2lkZSB0aG9zZSByYW5nZXMsXG4gICAgICAgIC8vIGJ5IGNoZWNraW5nIGFsbCBub2RlIGJvdW5kYXJpZXMgaW4gdGhlaXIgcGFyZW50IG5vZGVzLlxuICAgICAgICBsZXQgam9pbmFibGUgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByYW5nZXMubGVuZ3RoOyBpICs9IDIpIHtcbiAgICAgICAgICAgIGxldCBmcm9tID0gcmFuZ2VzW2ldLCB0byA9IHJhbmdlc1tpICsgMV07XG4gICAgICAgICAgICBsZXQgJGZyb20gPSB0ci5kb2MucmVzb2x2ZShmcm9tKSwgZGVwdGggPSAkZnJvbS5zaGFyZWREZXB0aCh0byksIHBhcmVudCA9ICRmcm9tLm5vZGUoZGVwdGgpO1xuICAgICAgICAgICAgZm9yIChsZXQgaW5kZXggPSAkZnJvbS5pbmRleEFmdGVyKGRlcHRoKSwgcG9zID0gJGZyb20uYWZ0ZXIoZGVwdGggKyAxKTsgcG9zIDw9IHRvOyArK2luZGV4KSB7XG4gICAgICAgICAgICAgICAgbGV0IGFmdGVyID0gcGFyZW50Lm1heWJlQ2hpbGQoaW5kZXgpO1xuICAgICAgICAgICAgICAgIGlmICghYWZ0ZXIpXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGlmIChpbmRleCAmJiBqb2luYWJsZS5pbmRleE9mKHBvcykgPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGJlZm9yZSA9IHBhcmVudC5jaGlsZChpbmRleCAtIDEpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYmVmb3JlLnR5cGUgPT0gYWZ0ZXIudHlwZSAmJiBpc0pvaW5hYmxlKGJlZm9yZSwgYWZ0ZXIpKVxuICAgICAgICAgICAgICAgICAgICAgICAgam9pbmFibGUucHVzaChwb3MpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBwb3MgKz0gYWZ0ZXIubm9kZVNpemU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gSm9pbiB0aGUgam9pbmFibGUgcG9pbnRzXG4gICAgICAgIGpvaW5hYmxlLnNvcnQoKGEsIGIpID0+IGEgLSBiKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IGpvaW5hYmxlLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgICBpZiAoY2FuSm9pbih0ci5kb2MsIGpvaW5hYmxlW2ldKSlcbiAgICAgICAgICAgICAgICB0ci5qb2luKGpvaW5hYmxlW2ldKTtcbiAgICAgICAgfVxuICAgICAgICBkaXNwYXRjaCh0cik7XG4gICAgfTtcbn1cbi8qKlxuV3JhcCBhIGNvbW1hbmQgc28gdGhhdCwgd2hlbiBpdCBwcm9kdWNlcyBhIHRyYW5zZm9ybSB0aGF0IGNhdXNlc1xudHdvIGpvaW5hYmxlIG5vZGVzIHRvIGVuZCB1cCBuZXh0IHRvIGVhY2ggb3RoZXIsIHRob3NlIGFyZSBqb2luZWQuXG5Ob2RlcyBhcmUgY29uc2lkZXJlZCBqb2luYWJsZSB3aGVuIHRoZXkgYXJlIG9mIHRoZSBzYW1lIHR5cGUgYW5kXG53aGVuIHRoZSBgaXNKb2luYWJsZWAgcHJlZGljYXRlIHJldHVybnMgdHJ1ZSBmb3IgdGhlbSBvciwgaWYgYW5cbmFycmF5IG9mIHN0cmluZ3Mgd2FzIHBhc3NlZCwgaWYgdGhlaXIgbm9kZSB0eXBlIG5hbWUgaXMgaW4gdGhhdFxuYXJyYXkuXG4qL1xuZnVuY3Rpb24gYXV0b0pvaW4oY29tbWFuZCwgaXNKb2luYWJsZSkge1xuICAgIGxldCBjYW5Kb2luID0gQXJyYXkuaXNBcnJheShpc0pvaW5hYmxlKSA/IChub2RlKSA9PiBpc0pvaW5hYmxlLmluZGV4T2Yobm9kZS50eXBlLm5hbWUpID4gLTFcbiAgICAgICAgOiBpc0pvaW5hYmxlO1xuICAgIHJldHVybiAoc3RhdGUsIGRpc3BhdGNoLCB2aWV3KSA9PiBjb21tYW5kKHN0YXRlLCBkaXNwYXRjaCAmJiB3cmFwRGlzcGF0Y2hGb3JKb2luKGRpc3BhdGNoLCBjYW5Kb2luKSwgdmlldyk7XG59XG4vKipcbkNvbWJpbmUgYSBudW1iZXIgb2YgY29tbWFuZCBmdW5jdGlvbnMgaW50byBhIHNpbmdsZSBmdW5jdGlvbiAod2hpY2hcbmNhbGxzIHRoZW0gb25lIGJ5IG9uZSB1bnRpbCBvbmUgcmV0dXJucyB0cnVlKS5cbiovXG5mdW5jdGlvbiBjaGFpbkNvbW1hbmRzKC4uLmNvbW1hbmRzKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChzdGF0ZSwgZGlzcGF0Y2gsIHZpZXcpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb21tYW5kcy5sZW5ndGg7IGkrKylcbiAgICAgICAgICAgIGlmIChjb21tYW5kc1tpXShzdGF0ZSwgZGlzcGF0Y2gsIHZpZXcpKVxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcbn1cbmxldCBiYWNrc3BhY2UgPSBjaGFpbkNvbW1hbmRzKGRlbGV0ZVNlbGVjdGlvbiwgam9pbkJhY2t3YXJkLCBzZWxlY3ROb2RlQmFja3dhcmQpO1xubGV0IGRlbCA9IGNoYWluQ29tbWFuZHMoZGVsZXRlU2VsZWN0aW9uLCBqb2luRm9yd2FyZCwgc2VsZWN0Tm9kZUZvcndhcmQpO1xuLyoqXG5BIGJhc2ljIGtleW1hcCBjb250YWluaW5nIGJpbmRpbmdzIG5vdCBzcGVjaWZpYyB0byBhbnkgc2NoZW1hLlxuQmluZHMgdGhlIGZvbGxvd2luZyBrZXlzICh3aGVuIG11bHRpcGxlIGNvbW1hbmRzIGFyZSBsaXN0ZWQsIHRoZXlcbmFyZSBjaGFpbmVkIHdpdGggW2BjaGFpbkNvbW1hbmRzYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI2NvbW1hbmRzLmNoYWluQ29tbWFuZHMpKTpcblxuKiAqKkVudGVyKiogdG8gYG5ld2xpbmVJbkNvZGVgLCBgY3JlYXRlUGFyYWdyYXBoTmVhcmAsIGBsaWZ0RW1wdHlCbG9ja2AsIGBzcGxpdEJsb2NrYFxuKiAqKk1vZC1FbnRlcioqIHRvIGBleGl0Q29kZWBcbiogKipCYWNrc3BhY2UqKiBhbmQgKipNb2QtQmFja3NwYWNlKiogdG8gYGRlbGV0ZVNlbGVjdGlvbmAsIGBqb2luQmFja3dhcmRgLCBgc2VsZWN0Tm9kZUJhY2t3YXJkYFxuKiAqKkRlbGV0ZSoqIGFuZCAqKk1vZC1EZWxldGUqKiB0byBgZGVsZXRlU2VsZWN0aW9uYCwgYGpvaW5Gb3J3YXJkYCwgYHNlbGVjdE5vZGVGb3J3YXJkYFxuKiAqKk1vZC1EZWxldGUqKiB0byBgZGVsZXRlU2VsZWN0aW9uYCwgYGpvaW5Gb3J3YXJkYCwgYHNlbGVjdE5vZGVGb3J3YXJkYFxuKiAqKk1vZC1hKiogdG8gYHNlbGVjdEFsbGBcbiovXG5jb25zdCBwY0Jhc2VLZXltYXAgPSB7XG4gICAgXCJFbnRlclwiOiBjaGFpbkNvbW1hbmRzKG5ld2xpbmVJbkNvZGUsIGNyZWF0ZVBhcmFncmFwaE5lYXIsIGxpZnRFbXB0eUJsb2NrLCBzcGxpdEJsb2NrKSxcbiAgICBcIk1vZC1FbnRlclwiOiBleGl0Q29kZSxcbiAgICBcIkJhY2tzcGFjZVwiOiBiYWNrc3BhY2UsXG4gICAgXCJNb2QtQmFja3NwYWNlXCI6IGJhY2tzcGFjZSxcbiAgICBcIlNoaWZ0LUJhY2tzcGFjZVwiOiBiYWNrc3BhY2UsXG4gICAgXCJEZWxldGVcIjogZGVsLFxuICAgIFwiTW9kLURlbGV0ZVwiOiBkZWwsXG4gICAgXCJNb2QtYVwiOiBzZWxlY3RBbGxcbn07XG4vKipcbkEgY29weSBvZiBgcGNCYXNlS2V5bWFwYCB0aGF0IGFsc28gYmluZHMgKipDdHJsLWgqKiBsaWtlIEJhY2tzcGFjZSxcbioqQ3RybC1kKiogbGlrZSBEZWxldGUsICoqQWx0LUJhY2tzcGFjZSoqIGxpa2UgQ3RybC1CYWNrc3BhY2UsIGFuZFxuKipDdHJsLUFsdC1CYWNrc3BhY2UqKiwgKipBbHQtRGVsZXRlKiosIGFuZCAqKkFsdC1kKiogbGlrZVxuQ3RybC1EZWxldGUuXG4qL1xuY29uc3QgbWFjQmFzZUtleW1hcCA9IHtcbiAgICBcIkN0cmwtaFwiOiBwY0Jhc2VLZXltYXBbXCJCYWNrc3BhY2VcIl0sXG4gICAgXCJBbHQtQmFja3NwYWNlXCI6IHBjQmFzZUtleW1hcFtcIk1vZC1CYWNrc3BhY2VcIl0sXG4gICAgXCJDdHJsLWRcIjogcGNCYXNlS2V5bWFwW1wiRGVsZXRlXCJdLFxuICAgIFwiQ3RybC1BbHQtQmFja3NwYWNlXCI6IHBjQmFzZUtleW1hcFtcIk1vZC1EZWxldGVcIl0sXG4gICAgXCJBbHQtRGVsZXRlXCI6IHBjQmFzZUtleW1hcFtcIk1vZC1EZWxldGVcIl0sXG4gICAgXCJBbHQtZFwiOiBwY0Jhc2VLZXltYXBbXCJNb2QtRGVsZXRlXCJdLFxuICAgIFwiQ3RybC1hXCI6IHNlbGVjdFRleHRibG9ja1N0YXJ0LFxuICAgIFwiQ3RybC1lXCI6IHNlbGVjdFRleHRibG9ja0VuZFxufTtcbmZvciAobGV0IGtleSBpbiBwY0Jhc2VLZXltYXApXG4gICAgbWFjQmFzZUtleW1hcFtrZXldID0gcGNCYXNlS2V5bWFwW2tleV07XG5jb25zdCBtYWMgPSB0eXBlb2YgbmF2aWdhdG9yICE9IFwidW5kZWZpbmVkXCIgPyAvTWFjfGlQKGhvbmV8W29hXWQpLy50ZXN0KG5hdmlnYXRvci5wbGF0Zm9ybSlcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgOiB0eXBlb2Ygb3MgIT0gXCJ1bmRlZmluZWRcIiAmJiBvcy5wbGF0Zm9ybSA/IG9zLnBsYXRmb3JtKCkgPT0gXCJkYXJ3aW5cIiA6IGZhbHNlO1xuLyoqXG5EZXBlbmRpbmcgb24gdGhlIGRldGVjdGVkIHBsYXRmb3JtLCB0aGlzIHdpbGwgaG9sZFxuW2BwY0Jhc2VrZXltYXBgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jY29tbWFuZHMucGNCYXNlS2V5bWFwKSBvclxuW2BtYWNCYXNlS2V5bWFwYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI2NvbW1hbmRzLm1hY0Jhc2VLZXltYXApLlxuKi9cbmNvbnN0IGJhc2VLZXltYXAgPSBtYWMgPyBtYWNCYXNlS2V5bWFwIDogcGNCYXNlS2V5bWFwO1xuXG5leHBvcnQgeyBhdXRvSm9pbiwgYmFzZUtleW1hcCwgY2hhaW5Db21tYW5kcywgY3JlYXRlUGFyYWdyYXBoTmVhciwgZGVsZXRlU2VsZWN0aW9uLCBleGl0Q29kZSwgam9pbkJhY2t3YXJkLCBqb2luRG93biwgam9pbkZvcndhcmQsIGpvaW5UZXh0YmxvY2tCYWNrd2FyZCwgam9pblRleHRibG9ja0ZvcndhcmQsIGpvaW5VcCwgbGlmdCwgbGlmdEVtcHR5QmxvY2ssIG1hY0Jhc2VLZXltYXAsIG5ld2xpbmVJbkNvZGUsIHBjQmFzZUtleW1hcCwgc2VsZWN0QWxsLCBzZWxlY3ROb2RlQmFja3dhcmQsIHNlbGVjdE5vZGVGb3J3YXJkLCBzZWxlY3RQYXJlbnROb2RlLCBzZWxlY3RUZXh0YmxvY2tFbmQsIHNlbGVjdFRleHRibG9ja1N0YXJ0LCBzZXRCbG9ja1R5cGUsIHNwbGl0QmxvY2ssIHNwbGl0QmxvY2tBcywgc3BsaXRCbG9ja0tlZXBNYXJrcywgdG9nZ2xlTWFyaywgd3JhcEluIH07XG4iLCAiaW1wb3J0IHsgZmluZFdyYXBwaW5nLCBSZXBsYWNlQXJvdW5kU3RlcCwgY2FuU3BsaXQsIGxpZnRUYXJnZXQsIGNhbkpvaW4gfSBmcm9tICdwcm9zZW1pcnJvci10cmFuc2Zvcm0nO1xuaW1wb3J0IHsgTm9kZVJhbmdlLCBGcmFnbWVudCwgU2xpY2UgfSBmcm9tICdwcm9zZW1pcnJvci1tb2RlbCc7XG5pbXBvcnQgeyBTZWxlY3Rpb24gfSBmcm9tICdwcm9zZW1pcnJvci1zdGF0ZSc7XG5cbmNvbnN0IG9sRE9NID0gW1wib2xcIiwgMF0sIHVsRE9NID0gW1widWxcIiwgMF0sIGxpRE9NID0gW1wibGlcIiwgMF07XG4vKipcbkFuIG9yZGVyZWQgbGlzdCBbbm9kZSBzcGVjXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZVNwZWMpLiBIYXMgYSBzaW5nbGVcbmF0dHJpYnV0ZSwgYG9yZGVyYCwgd2hpY2ggZGV0ZXJtaW5lcyB0aGUgbnVtYmVyIGF0IHdoaWNoIHRoZSBsaXN0XG5zdGFydHMgY291bnRpbmcsIGFuZCBkZWZhdWx0cyB0byAxLiBSZXByZXNlbnRlZCBhcyBhbiBgPG9sPmBcbmVsZW1lbnQuXG4qL1xuY29uc3Qgb3JkZXJlZExpc3QgPSB7XG4gICAgYXR0cnM6IHsgb3JkZXI6IHsgZGVmYXVsdDogMSwgdmFsaWRhdGU6IFwibnVtYmVyXCIgfSB9LFxuICAgIHBhcnNlRE9NOiBbeyB0YWc6IFwib2xcIiwgZ2V0QXR0cnMoZG9tKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgb3JkZXI6IGRvbS5oYXNBdHRyaWJ1dGUoXCJzdGFydFwiKSA/ICtkb20uZ2V0QXR0cmlidXRlKFwic3RhcnRcIikgOiAxIH07XG4gICAgICAgICAgICB9IH1dLFxuICAgIHRvRE9NKG5vZGUpIHtcbiAgICAgICAgcmV0dXJuIG5vZGUuYXR0cnMub3JkZXIgPT0gMSA/IG9sRE9NIDogW1wib2xcIiwgeyBzdGFydDogbm9kZS5hdHRycy5vcmRlciB9LCAwXTtcbiAgICB9XG59O1xuLyoqXG5BIGJ1bGxldCBsaXN0IG5vZGUgc3BlYywgcmVwcmVzZW50ZWQgaW4gdGhlIERPTSBhcyBgPHVsPmAuXG4qL1xuY29uc3QgYnVsbGV0TGlzdCA9IHtcbiAgICBwYXJzZURPTTogW3sgdGFnOiBcInVsXCIgfV0sXG4gICAgdG9ET00oKSB7IHJldHVybiB1bERPTTsgfVxufTtcbi8qKlxuQSBsaXN0IGl0ZW0gKGA8bGk+YCkgc3BlYy5cbiovXG5jb25zdCBsaXN0SXRlbSA9IHtcbiAgICBwYXJzZURPTTogW3sgdGFnOiBcImxpXCIgfV0sXG4gICAgdG9ET00oKSB7IHJldHVybiBsaURPTTsgfSxcbiAgICBkZWZpbmluZzogdHJ1ZVxufTtcbmZ1bmN0aW9uIGFkZChvYmosIHByb3BzKSB7XG4gICAgbGV0IGNvcHkgPSB7fTtcbiAgICBmb3IgKGxldCBwcm9wIGluIG9iailcbiAgICAgICAgY29weVtwcm9wXSA9IG9ialtwcm9wXTtcbiAgICBmb3IgKGxldCBwcm9wIGluIHByb3BzKVxuICAgICAgICBjb3B5W3Byb3BdID0gcHJvcHNbcHJvcF07XG4gICAgcmV0dXJuIGNvcHk7XG59XG4vKipcbkNvbnZlbmllbmNlIGZ1bmN0aW9uIGZvciBhZGRpbmcgbGlzdC1yZWxhdGVkIG5vZGUgdHlwZXMgdG8gYSBtYXBcbnNwZWNpZnlpbmcgdGhlIG5vZGVzIGZvciBhIHNjaGVtYS4gQWRkc1xuW2BvcmRlcmVkTGlzdGBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNzY2hlbWEtbGlzdC5vcmRlcmVkTGlzdCkgYXMgYFwib3JkZXJlZF9saXN0XCJgLFxuW2BidWxsZXRMaXN0YF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3NjaGVtYS1saXN0LmJ1bGxldExpc3QpIGFzIGBcImJ1bGxldF9saXN0XCJgLCBhbmRcbltgbGlzdEl0ZW1gXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jc2NoZW1hLWxpc3QubGlzdEl0ZW0pIGFzIGBcImxpc3RfaXRlbVwiYC5cblxuYGl0ZW1Db250ZW50YCBkZXRlcm1pbmVzIHRoZSBjb250ZW50IGV4cHJlc3Npb24gZm9yIHRoZSBsaXN0IGl0ZW1zLlxuSWYgeW91IHdhbnQgdGhlIGNvbW1hbmRzIGRlZmluZWQgaW4gdGhpcyBtb2R1bGUgdG8gYXBwbHkgdG8geW91clxubGlzdCBzdHJ1Y3R1cmUsIGl0IHNob3VsZCBoYXZlIGEgc2hhcGUgbGlrZSBgXCJwYXJhZ3JhcGggYmxvY2sqXCJgIG9yXG5gXCJwYXJhZ3JhcGggKG9yZGVyZWRfbGlzdCB8IGJ1bGxldF9saXN0KSpcImAuIGBsaXN0R3JvdXBgIGNhbiBiZVxuZ2l2ZW4gdG8gYXNzaWduIGEgZ3JvdXAgbmFtZSB0byB0aGUgbGlzdCBub2RlIHR5cGVzLCBmb3IgZXhhbXBsZVxuYFwiYmxvY2tcImAuXG4qL1xuZnVuY3Rpb24gYWRkTGlzdE5vZGVzKG5vZGVzLCBpdGVtQ29udGVudCwgbGlzdEdyb3VwKSB7XG4gICAgcmV0dXJuIG5vZGVzLmFwcGVuZCh7XG4gICAgICAgIG9yZGVyZWRfbGlzdDogYWRkKG9yZGVyZWRMaXN0LCB7IGNvbnRlbnQ6IFwibGlzdF9pdGVtK1wiLCBncm91cDogbGlzdEdyb3VwIH0pLFxuICAgICAgICBidWxsZXRfbGlzdDogYWRkKGJ1bGxldExpc3QsIHsgY29udGVudDogXCJsaXN0X2l0ZW0rXCIsIGdyb3VwOiBsaXN0R3JvdXAgfSksXG4gICAgICAgIGxpc3RfaXRlbTogYWRkKGxpc3RJdGVtLCB7IGNvbnRlbnQ6IGl0ZW1Db250ZW50IH0pXG4gICAgfSk7XG59XG4vKipcblJldHVybnMgYSBjb21tYW5kIGZ1bmN0aW9uIHRoYXQgd3JhcHMgdGhlIHNlbGVjdGlvbiBpbiBhIGxpc3Qgd2l0aFxudGhlIGdpdmVuIHR5cGUgYW4gYXR0cmlidXRlcy4gSWYgYGRpc3BhdGNoYCBpcyBudWxsLCBvbmx5IHJldHVybiBhXG52YWx1ZSB0byBpbmRpY2F0ZSB3aGV0aGVyIHRoaXMgaXMgcG9zc2libGUsIGJ1dCBkb24ndCBhY3R1YWxseVxucGVyZm9ybSB0aGUgY2hhbmdlLlxuKi9cbmZ1bmN0aW9uIHdyYXBJbkxpc3QobGlzdFR5cGUsIGF0dHJzID0gbnVsbCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAoc3RhdGUsIGRpc3BhdGNoKSB7XG4gICAgICAgIGxldCB7ICRmcm9tLCAkdG8gfSA9IHN0YXRlLnNlbGVjdGlvbjtcbiAgICAgICAgbGV0IHJhbmdlID0gJGZyb20uYmxvY2tSYW5nZSgkdG8pO1xuICAgICAgICBpZiAoIXJhbmdlKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBsZXQgdHIgPSBkaXNwYXRjaCA/IHN0YXRlLnRyIDogbnVsbDtcbiAgICAgICAgaWYgKCF3cmFwUmFuZ2VJbkxpc3QodHIsIHJhbmdlLCBsaXN0VHlwZSwgYXR0cnMpKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBpZiAoZGlzcGF0Y2gpXG4gICAgICAgICAgICBkaXNwYXRjaCh0ci5zY3JvbGxJbnRvVmlldygpKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfTtcbn1cbi8qKlxuVHJ5IHRvIHdyYXAgdGhlIGdpdmVuIG5vZGUgcmFuZ2UgaW4gYSBsaXN0IG9mIHRoZSBnaXZlbiB0eXBlLlxuUmV0dXJuIGB0cnVlYCB3aGVuIHRoaXMgaXMgcG9zc2libGUsIGBmYWxzZWAgb3RoZXJ3aXNlLiBXaGVuIGB0cmBcbmlzIG5vbi1udWxsLCB0aGUgd3JhcHBpbmcgaXMgYWRkZWQgdG8gdGhhdCB0cmFuc2FjdGlvbi4gV2hlbiBpdCBpc1xuYG51bGxgLCB0aGUgZnVuY3Rpb24gb25seSBxdWVyaWVzIHdoZXRoZXIgdGhlIHdyYXBwaW5nIGlzXG5wb3NzaWJsZS5cbiovXG5mdW5jdGlvbiB3cmFwUmFuZ2VJbkxpc3QodHIsIHJhbmdlLCBsaXN0VHlwZSwgYXR0cnMgPSBudWxsKSB7XG4gICAgbGV0IGRvSm9pbiA9IGZhbHNlLCBvdXRlclJhbmdlID0gcmFuZ2UsIGRvYyA9IHJhbmdlLiRmcm9tLmRvYztcbiAgICAvLyBUaGlzIGlzIGF0IHRoZSB0b3Agb2YgYW4gZXhpc3RpbmcgbGlzdCBpdGVtXG4gICAgaWYgKHJhbmdlLmRlcHRoID49IDIgJiYgcmFuZ2UuJGZyb20ubm9kZShyYW5nZS5kZXB0aCAtIDEpLnR5cGUuY29tcGF0aWJsZUNvbnRlbnQobGlzdFR5cGUpICYmIHJhbmdlLnN0YXJ0SW5kZXggPT0gMCkge1xuICAgICAgICAvLyBEb24ndCBkbyBhbnl0aGluZyBpZiB0aGlzIGlzIHRoZSB0b3Agb2YgdGhlIGxpc3RcbiAgICAgICAgaWYgKHJhbmdlLiRmcm9tLmluZGV4KHJhbmdlLmRlcHRoIC0gMSkgPT0gMClcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgbGV0ICRpbnNlcnQgPSBkb2MucmVzb2x2ZShyYW5nZS5zdGFydCAtIDIpO1xuICAgICAgICBvdXRlclJhbmdlID0gbmV3IE5vZGVSYW5nZSgkaW5zZXJ0LCAkaW5zZXJ0LCByYW5nZS5kZXB0aCk7XG4gICAgICAgIGlmIChyYW5nZS5lbmRJbmRleCA8IHJhbmdlLnBhcmVudC5jaGlsZENvdW50KVxuICAgICAgICAgICAgcmFuZ2UgPSBuZXcgTm9kZVJhbmdlKHJhbmdlLiRmcm9tLCBkb2MucmVzb2x2ZShyYW5nZS4kdG8uZW5kKHJhbmdlLmRlcHRoKSksIHJhbmdlLmRlcHRoKTtcbiAgICAgICAgZG9Kb2luID0gdHJ1ZTtcbiAgICB9XG4gICAgbGV0IHdyYXAgPSBmaW5kV3JhcHBpbmcob3V0ZXJSYW5nZSwgbGlzdFR5cGUsIGF0dHJzLCByYW5nZSk7XG4gICAgaWYgKCF3cmFwKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgaWYgKHRyKVxuICAgICAgICBkb1dyYXBJbkxpc3QodHIsIHJhbmdlLCB3cmFwLCBkb0pvaW4sIGxpc3RUeXBlKTtcbiAgICByZXR1cm4gdHJ1ZTtcbn1cbmZ1bmN0aW9uIGRvV3JhcEluTGlzdCh0ciwgcmFuZ2UsIHdyYXBwZXJzLCBqb2luQmVmb3JlLCBsaXN0VHlwZSkge1xuICAgIGxldCBjb250ZW50ID0gRnJhZ21lbnQuZW1wdHk7XG4gICAgZm9yIChsZXQgaSA9IHdyYXBwZXJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKVxuICAgICAgICBjb250ZW50ID0gRnJhZ21lbnQuZnJvbSh3cmFwcGVyc1tpXS50eXBlLmNyZWF0ZSh3cmFwcGVyc1tpXS5hdHRycywgY29udGVudCkpO1xuICAgIHRyLnN0ZXAobmV3IFJlcGxhY2VBcm91bmRTdGVwKHJhbmdlLnN0YXJ0IC0gKGpvaW5CZWZvcmUgPyAyIDogMCksIHJhbmdlLmVuZCwgcmFuZ2Uuc3RhcnQsIHJhbmdlLmVuZCwgbmV3IFNsaWNlKGNvbnRlbnQsIDAsIDApLCB3cmFwcGVycy5sZW5ndGgsIHRydWUpKTtcbiAgICBsZXQgZm91bmQgPSAwO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgd3JhcHBlcnMubGVuZ3RoOyBpKyspXG4gICAgICAgIGlmICh3cmFwcGVyc1tpXS50eXBlID09IGxpc3RUeXBlKVxuICAgICAgICAgICAgZm91bmQgPSBpICsgMTtcbiAgICBsZXQgc3BsaXREZXB0aCA9IHdyYXBwZXJzLmxlbmd0aCAtIGZvdW5kO1xuICAgIGxldCBzcGxpdFBvcyA9IHJhbmdlLnN0YXJ0ICsgd3JhcHBlcnMubGVuZ3RoIC0gKGpvaW5CZWZvcmUgPyAyIDogMCksIHBhcmVudCA9IHJhbmdlLnBhcmVudDtcbiAgICBmb3IgKGxldCBpID0gcmFuZ2Uuc3RhcnRJbmRleCwgZSA9IHJhbmdlLmVuZEluZGV4LCBmaXJzdCA9IHRydWU7IGkgPCBlOyBpKyssIGZpcnN0ID0gZmFsc2UpIHtcbiAgICAgICAgaWYgKCFmaXJzdCAmJiBjYW5TcGxpdCh0ci5kb2MsIHNwbGl0UG9zLCBzcGxpdERlcHRoKSkge1xuICAgICAgICAgICAgdHIuc3BsaXQoc3BsaXRQb3MsIHNwbGl0RGVwdGgpO1xuICAgICAgICAgICAgc3BsaXRQb3MgKz0gMiAqIHNwbGl0RGVwdGg7XG4gICAgICAgIH1cbiAgICAgICAgc3BsaXRQb3MgKz0gcGFyZW50LmNoaWxkKGkpLm5vZGVTaXplO1xuICAgIH1cbiAgICByZXR1cm4gdHI7XG59XG4vKipcbkJ1aWxkIGEgY29tbWFuZCB0aGF0IHNwbGl0cyBhIG5vbi1lbXB0eSB0ZXh0YmxvY2sgYXQgdGhlIHRvcCBsZXZlbFxub2YgYSBsaXN0IGl0ZW0gYnkgYWxzbyBzcGxpdHRpbmcgdGhhdCBsaXN0IGl0ZW0uXG4qL1xuZnVuY3Rpb24gc3BsaXRMaXN0SXRlbShpdGVtVHlwZSwgaXRlbUF0dHJzKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChzdGF0ZSwgZGlzcGF0Y2gpIHtcbiAgICAgICAgbGV0IHsgJGZyb20sICR0bywgbm9kZSB9ID0gc3RhdGUuc2VsZWN0aW9uO1xuICAgICAgICBpZiAoKG5vZGUgJiYgbm9kZS5pc0Jsb2NrKSB8fCAkZnJvbS5kZXB0aCA8IDIgfHwgISRmcm9tLnNhbWVQYXJlbnQoJHRvKSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgbGV0IGdyYW5kUGFyZW50ID0gJGZyb20ubm9kZSgtMSk7XG4gICAgICAgIGlmIChncmFuZFBhcmVudC50eXBlICE9IGl0ZW1UeXBlKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBpZiAoJGZyb20ucGFyZW50LmNvbnRlbnQuc2l6ZSA9PSAwICYmICRmcm9tLm5vZGUoLTEpLmNoaWxkQ291bnQgPT0gJGZyb20uaW5kZXhBZnRlcigtMSkpIHtcbiAgICAgICAgICAgIC8vIEluIGFuIGVtcHR5IGJsb2NrLiBJZiB0aGlzIGlzIGEgbmVzdGVkIGxpc3QsIHRoZSB3cmFwcGluZ1xuICAgICAgICAgICAgLy8gbGlzdCBpdGVtIHNob3VsZCBiZSBzcGxpdC4gT3RoZXJ3aXNlLCBiYWlsIG91dCBhbmQgbGV0IG5leHRcbiAgICAgICAgICAgIC8vIGNvbW1hbmQgaGFuZGxlIGxpZnRpbmcuXG4gICAgICAgICAgICBpZiAoJGZyb20uZGVwdGggPT0gMyB8fCAkZnJvbS5ub2RlKC0zKS50eXBlICE9IGl0ZW1UeXBlIHx8XG4gICAgICAgICAgICAgICAgJGZyb20uaW5kZXgoLTIpICE9ICRmcm9tLm5vZGUoLTIpLmNoaWxkQ291bnQgLSAxKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIGlmIChkaXNwYXRjaCkge1xuICAgICAgICAgICAgICAgIGxldCB3cmFwID0gRnJhZ21lbnQuZW1wdHk7XG4gICAgICAgICAgICAgICAgbGV0IGRlcHRoQmVmb3JlID0gJGZyb20uaW5kZXgoLTEpID8gMSA6ICRmcm9tLmluZGV4KC0yKSA/IDIgOiAzO1xuICAgICAgICAgICAgICAgIC8vIEJ1aWxkIGEgZnJhZ21lbnQgY29udGFpbmluZyBlbXB0eSB2ZXJzaW9ucyBvZiB0aGUgc3RydWN0dXJlXG4gICAgICAgICAgICAgICAgLy8gZnJvbSB0aGUgb3V0ZXIgbGlzdCBpdGVtIHRvIHRoZSBwYXJlbnQgbm9kZSBvZiB0aGUgY3Vyc29yXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgZCA9ICRmcm9tLmRlcHRoIC0gZGVwdGhCZWZvcmU7IGQgPj0gJGZyb20uZGVwdGggLSAzOyBkLS0pXG4gICAgICAgICAgICAgICAgICAgIHdyYXAgPSBGcmFnbWVudC5mcm9tKCRmcm9tLm5vZGUoZCkuY29weSh3cmFwKSk7XG4gICAgICAgICAgICAgICAgbGV0IGRlcHRoQWZ0ZXIgPSAkZnJvbS5pbmRleEFmdGVyKC0xKSA8ICRmcm9tLm5vZGUoLTIpLmNoaWxkQ291bnQgPyAxXG4gICAgICAgICAgICAgICAgICAgIDogJGZyb20uaW5kZXhBZnRlcigtMikgPCAkZnJvbS5ub2RlKC0zKS5jaGlsZENvdW50ID8gMiA6IDM7XG4gICAgICAgICAgICAgICAgLy8gQWRkIGEgc2Vjb25kIGxpc3QgaXRlbSB3aXRoIGFuIGVtcHR5IGRlZmF1bHQgc3RhcnQgbm9kZVxuICAgICAgICAgICAgICAgIHdyYXAgPSB3cmFwLmFwcGVuZChGcmFnbWVudC5mcm9tKGl0ZW1UeXBlLmNyZWF0ZUFuZEZpbGwoKSkpO1xuICAgICAgICAgICAgICAgIGxldCBzdGFydCA9ICRmcm9tLmJlZm9yZSgkZnJvbS5kZXB0aCAtIChkZXB0aEJlZm9yZSAtIDEpKTtcbiAgICAgICAgICAgICAgICBsZXQgdHIgPSBzdGF0ZS50ci5yZXBsYWNlKHN0YXJ0LCAkZnJvbS5hZnRlcigtZGVwdGhBZnRlciksIG5ldyBTbGljZSh3cmFwLCA0IC0gZGVwdGhCZWZvcmUsIDApKTtcbiAgICAgICAgICAgICAgICBsZXQgc2VsID0gLTE7XG4gICAgICAgICAgICAgICAgdHIuZG9jLm5vZGVzQmV0d2VlbihzdGFydCwgdHIuZG9jLmNvbnRlbnQuc2l6ZSwgKG5vZGUsIHBvcykgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsID4gLTEpXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIGlmIChub2RlLmlzVGV4dGJsb2NrICYmIG5vZGUuY29udGVudC5zaXplID09IDApXG4gICAgICAgICAgICAgICAgICAgICAgICBzZWwgPSBwb3MgKyAxO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGlmIChzZWwgPiAtMSlcbiAgICAgICAgICAgICAgICAgICAgdHIuc2V0U2VsZWN0aW9uKFNlbGVjdGlvbi5uZWFyKHRyLmRvYy5yZXNvbHZlKHNlbCkpKTtcbiAgICAgICAgICAgICAgICBkaXNwYXRjaCh0ci5zY3JvbGxJbnRvVmlldygpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGxldCBuZXh0VHlwZSA9ICR0by5wb3MgPT0gJGZyb20uZW5kKCkgPyBncmFuZFBhcmVudC5jb250ZW50TWF0Y2hBdCgwKS5kZWZhdWx0VHlwZSA6IG51bGw7XG4gICAgICAgIGxldCB0ciA9IHN0YXRlLnRyLmRlbGV0ZSgkZnJvbS5wb3MsICR0by5wb3MpO1xuICAgICAgICBsZXQgdHlwZXMgPSBuZXh0VHlwZSA/IFtpdGVtQXR0cnMgPyB7IHR5cGU6IGl0ZW1UeXBlLCBhdHRyczogaXRlbUF0dHJzIH0gOiBudWxsLCB7IHR5cGU6IG5leHRUeXBlIH1dIDogdW5kZWZpbmVkO1xuICAgICAgICBpZiAoIWNhblNwbGl0KHRyLmRvYywgJGZyb20ucG9zLCAyLCB0eXBlcykpXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIGlmIChkaXNwYXRjaClcbiAgICAgICAgICAgIGRpc3BhdGNoKHRyLnNwbGl0KCRmcm9tLnBvcywgMiwgdHlwZXMpLnNjcm9sbEludG9WaWV3KCkpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xufVxuLyoqXG5BY3RzIGxpa2UgW2BzcGxpdExpc3RJdGVtYF0oaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9yZWYvI3NjaGVtYS1saXN0LnNwbGl0TGlzdEl0ZW0pLCBidXRcbndpdGhvdXQgcmVzZXR0aW5nIHRoZSBzZXQgb2YgYWN0aXZlIG1hcmtzIGF0IHRoZSBjdXJzb3IuXG4qL1xuZnVuY3Rpb24gc3BsaXRMaXN0SXRlbUtlZXBNYXJrcyhpdGVtVHlwZSwgaXRlbUF0dHJzKSB7XG4gICAgbGV0IHNwbGl0ID0gc3BsaXRMaXN0SXRlbShpdGVtVHlwZSwgaXRlbUF0dHJzKTtcbiAgICByZXR1cm4gKHN0YXRlLCBkaXNwYXRjaCkgPT4ge1xuICAgICAgICByZXR1cm4gc3BsaXQoc3RhdGUsIGRpc3BhdGNoICYmICh0ciA9PiB7XG4gICAgICAgICAgICBsZXQgbWFya3MgPSBzdGF0ZS5zdG9yZWRNYXJrcyB8fCAoc3RhdGUuc2VsZWN0aW9uLiR0by5wYXJlbnRPZmZzZXQgJiYgc3RhdGUuc2VsZWN0aW9uLiRmcm9tLm1hcmtzKCkpO1xuICAgICAgICAgICAgaWYgKG1hcmtzKVxuICAgICAgICAgICAgICAgIHRyLmVuc3VyZU1hcmtzKG1hcmtzKTtcbiAgICAgICAgICAgIGRpc3BhdGNoKHRyKTtcbiAgICAgICAgfSkpO1xuICAgIH07XG59XG4vKipcbkNyZWF0ZSBhIGNvbW1hbmQgdG8gbGlmdCB0aGUgbGlzdCBpdGVtIGFyb3VuZCB0aGUgc2VsZWN0aW9uIHVwIGludG9cbmEgd3JhcHBpbmcgbGlzdC5cbiovXG5mdW5jdGlvbiBsaWZ0TGlzdEl0ZW0oaXRlbVR5cGUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHN0YXRlLCBkaXNwYXRjaCkge1xuICAgICAgICBsZXQgeyAkZnJvbSwgJHRvIH0gPSBzdGF0ZS5zZWxlY3Rpb247XG4gICAgICAgIGxldCByYW5nZSA9ICRmcm9tLmJsb2NrUmFuZ2UoJHRvLCBub2RlID0+IG5vZGUuY2hpbGRDb3VudCA+IDAgJiYgbm9kZS5maXJzdENoaWxkLnR5cGUgPT0gaXRlbVR5cGUpO1xuICAgICAgICBpZiAoIXJhbmdlKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBpZiAoIWRpc3BhdGNoKVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIGlmICgkZnJvbS5ub2RlKHJhbmdlLmRlcHRoIC0gMSkudHlwZSA9PSBpdGVtVHlwZSkgLy8gSW5zaWRlIGEgcGFyZW50IGxpc3RcbiAgICAgICAgICAgIHJldHVybiBsaWZ0VG9PdXRlckxpc3Qoc3RhdGUsIGRpc3BhdGNoLCBpdGVtVHlwZSwgcmFuZ2UpO1xuICAgICAgICBlbHNlIC8vIE91dGVyIGxpc3Qgbm9kZVxuICAgICAgICAgICAgcmV0dXJuIGxpZnRPdXRPZkxpc3Qoc3RhdGUsIGRpc3BhdGNoLCByYW5nZSk7XG4gICAgfTtcbn1cbmZ1bmN0aW9uIGxpZnRUb091dGVyTGlzdChzdGF0ZSwgZGlzcGF0Y2gsIGl0ZW1UeXBlLCByYW5nZSkge1xuICAgIGxldCB0ciA9IHN0YXRlLnRyLCBlbmQgPSByYW5nZS5lbmQsIGVuZE9mTGlzdCA9IHJhbmdlLiR0by5lbmQocmFuZ2UuZGVwdGgpO1xuICAgIGlmIChlbmQgPCBlbmRPZkxpc3QpIHtcbiAgICAgICAgLy8gVGhlcmUgYXJlIHNpYmxpbmdzIGFmdGVyIHRoZSBsaWZ0ZWQgaXRlbXMsIHdoaWNoIG11c3QgYmVjb21lXG4gICAgICAgIC8vIGNoaWxkcmVuIG9mIHRoZSBsYXN0IGl0ZW1cbiAgICAgICAgdHIuc3RlcChuZXcgUmVwbGFjZUFyb3VuZFN0ZXAoZW5kIC0gMSwgZW5kT2ZMaXN0LCBlbmQsIGVuZE9mTGlzdCwgbmV3IFNsaWNlKEZyYWdtZW50LmZyb20oaXRlbVR5cGUuY3JlYXRlKG51bGwsIHJhbmdlLnBhcmVudC5jb3B5KCkpKSwgMSwgMCksIDEsIHRydWUpKTtcbiAgICAgICAgcmFuZ2UgPSBuZXcgTm9kZVJhbmdlKHRyLmRvYy5yZXNvbHZlKHJhbmdlLiRmcm9tLnBvcyksIHRyLmRvYy5yZXNvbHZlKGVuZE9mTGlzdCksIHJhbmdlLmRlcHRoKTtcbiAgICB9XG4gICAgY29uc3QgdGFyZ2V0ID0gbGlmdFRhcmdldChyYW5nZSk7XG4gICAgaWYgKHRhcmdldCA9PSBudWxsKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgdHIubGlmdChyYW5nZSwgdGFyZ2V0KTtcbiAgICBsZXQgJGFmdGVyID0gdHIuZG9jLnJlc29sdmUodHIubWFwcGluZy5tYXAoZW5kLCAtMSkgLSAxKTtcbiAgICBpZiAoY2FuSm9pbih0ci5kb2MsICRhZnRlci5wb3MpICYmICRhZnRlci5ub2RlQmVmb3JlLnR5cGUgPT0gJGFmdGVyLm5vZGVBZnRlci50eXBlKVxuICAgICAgICB0ci5qb2luKCRhZnRlci5wb3MpO1xuICAgIGRpc3BhdGNoKHRyLnNjcm9sbEludG9WaWV3KCkpO1xuICAgIHJldHVybiB0cnVlO1xufVxuZnVuY3Rpb24gbGlmdE91dE9mTGlzdChzdGF0ZSwgZGlzcGF0Y2gsIHJhbmdlKSB7XG4gICAgbGV0IHRyID0gc3RhdGUudHIsIGxpc3QgPSByYW5nZS5wYXJlbnQ7XG4gICAgLy8gTWVyZ2UgdGhlIGxpc3QgaXRlbXMgaW50byBhIHNpbmdsZSBiaWcgaXRlbVxuICAgIGZvciAobGV0IHBvcyA9IHJhbmdlLmVuZCwgaSA9IHJhbmdlLmVuZEluZGV4IC0gMSwgZSA9IHJhbmdlLnN0YXJ0SW5kZXg7IGkgPiBlOyBpLS0pIHtcbiAgICAgICAgcG9zIC09IGxpc3QuY2hpbGQoaSkubm9kZVNpemU7XG4gICAgICAgIHRyLmRlbGV0ZShwb3MgLSAxLCBwb3MgKyAxKTtcbiAgICB9XG4gICAgbGV0ICRzdGFydCA9IHRyLmRvYy5yZXNvbHZlKHJhbmdlLnN0YXJ0KSwgaXRlbSA9ICRzdGFydC5ub2RlQWZ0ZXI7XG4gICAgaWYgKHRyLm1hcHBpbmcubWFwKHJhbmdlLmVuZCkgIT0gcmFuZ2Uuc3RhcnQgKyAkc3RhcnQubm9kZUFmdGVyLm5vZGVTaXplKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgbGV0IGF0U3RhcnQgPSByYW5nZS5zdGFydEluZGV4ID09IDAsIGF0RW5kID0gcmFuZ2UuZW5kSW5kZXggPT0gbGlzdC5jaGlsZENvdW50O1xuICAgIGxldCBwYXJlbnQgPSAkc3RhcnQubm9kZSgtMSksIGluZGV4QmVmb3JlID0gJHN0YXJ0LmluZGV4KC0xKTtcbiAgICBpZiAoIXBhcmVudC5jYW5SZXBsYWNlKGluZGV4QmVmb3JlICsgKGF0U3RhcnQgPyAwIDogMSksIGluZGV4QmVmb3JlICsgMSwgaXRlbS5jb250ZW50LmFwcGVuZChhdEVuZCA/IEZyYWdtZW50LmVtcHR5IDogRnJhZ21lbnQuZnJvbShsaXN0KSkpKVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgbGV0IHN0YXJ0ID0gJHN0YXJ0LnBvcywgZW5kID0gc3RhcnQgKyBpdGVtLm5vZGVTaXplO1xuICAgIC8vIFN0cmlwIG9mZiB0aGUgc3Vycm91bmRpbmcgbGlzdC4gQXQgdGhlIHNpZGVzIHdoZXJlIHdlJ3JlIG5vdCBhdFxuICAgIC8vIHRoZSBlbmQgb2YgdGhlIGxpc3QsIHRoZSBleGlzdGluZyBsaXN0IGlzIGNsb3NlZC4gQXQgc2lkZXMgd2hlcmVcbiAgICAvLyB0aGlzIGlzIHRoZSBlbmQsIGl0IGlzIG92ZXJ3cml0dGVuIHRvIGl0cyBlbmQuXG4gICAgdHIuc3RlcChuZXcgUmVwbGFjZUFyb3VuZFN0ZXAoc3RhcnQgLSAoYXRTdGFydCA/IDEgOiAwKSwgZW5kICsgKGF0RW5kID8gMSA6IDApLCBzdGFydCArIDEsIGVuZCAtIDEsIG5ldyBTbGljZSgoYXRTdGFydCA/IEZyYWdtZW50LmVtcHR5IDogRnJhZ21lbnQuZnJvbShsaXN0LmNvcHkoRnJhZ21lbnQuZW1wdHkpKSlcbiAgICAgICAgLmFwcGVuZChhdEVuZCA/IEZyYWdtZW50LmVtcHR5IDogRnJhZ21lbnQuZnJvbShsaXN0LmNvcHkoRnJhZ21lbnQuZW1wdHkpKSksIGF0U3RhcnQgPyAwIDogMSwgYXRFbmQgPyAwIDogMSksIGF0U3RhcnQgPyAwIDogMSkpO1xuICAgIGRpc3BhdGNoKHRyLnNjcm9sbEludG9WaWV3KCkpO1xuICAgIHJldHVybiB0cnVlO1xufVxuLyoqXG5DcmVhdGUgYSBjb21tYW5kIHRvIHNpbmsgdGhlIGxpc3QgaXRlbSBhcm91bmQgdGhlIHNlbGVjdGlvbiBkb3duXG5pbnRvIGFuIGlubmVyIGxpc3QuXG4qL1xuZnVuY3Rpb24gc2lua0xpc3RJdGVtKGl0ZW1UeXBlKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChzdGF0ZSwgZGlzcGF0Y2gpIHtcbiAgICAgICAgbGV0IHsgJGZyb20sICR0byB9ID0gc3RhdGUuc2VsZWN0aW9uO1xuICAgICAgICBsZXQgcmFuZ2UgPSAkZnJvbS5ibG9ja1JhbmdlKCR0bywgbm9kZSA9PiBub2RlLmNoaWxkQ291bnQgPiAwICYmIG5vZGUuZmlyc3RDaGlsZC50eXBlID09IGl0ZW1UeXBlKTtcbiAgICAgICAgaWYgKCFyYW5nZSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgbGV0IHN0YXJ0SW5kZXggPSByYW5nZS5zdGFydEluZGV4O1xuICAgICAgICBpZiAoc3RhcnRJbmRleCA9PSAwKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICBsZXQgcGFyZW50ID0gcmFuZ2UucGFyZW50LCBub2RlQmVmb3JlID0gcGFyZW50LmNoaWxkKHN0YXJ0SW5kZXggLSAxKTtcbiAgICAgICAgaWYgKG5vZGVCZWZvcmUudHlwZSAhPSBpdGVtVHlwZSlcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgaWYgKGRpc3BhdGNoKSB7XG4gICAgICAgICAgICBsZXQgbmVzdGVkQmVmb3JlID0gbm9kZUJlZm9yZS5sYXN0Q2hpbGQgJiYgbm9kZUJlZm9yZS5sYXN0Q2hpbGQudHlwZSA9PSBwYXJlbnQudHlwZTtcbiAgICAgICAgICAgIGxldCBpbm5lciA9IEZyYWdtZW50LmZyb20obmVzdGVkQmVmb3JlID8gaXRlbVR5cGUuY3JlYXRlKCkgOiBudWxsKTtcbiAgICAgICAgICAgIGxldCBzbGljZSA9IG5ldyBTbGljZShGcmFnbWVudC5mcm9tKGl0ZW1UeXBlLmNyZWF0ZShudWxsLCBGcmFnbWVudC5mcm9tKHBhcmVudC50eXBlLmNyZWF0ZShudWxsLCBpbm5lcikpKSksIG5lc3RlZEJlZm9yZSA/IDMgOiAxLCAwKTtcbiAgICAgICAgICAgIGxldCBiZWZvcmUgPSByYW5nZS5zdGFydCwgYWZ0ZXIgPSByYW5nZS5lbmQ7XG4gICAgICAgICAgICBkaXNwYXRjaChzdGF0ZS50ci5zdGVwKG5ldyBSZXBsYWNlQXJvdW5kU3RlcChiZWZvcmUgLSAobmVzdGVkQmVmb3JlID8gMyA6IDEpLCBhZnRlciwgYmVmb3JlLCBhZnRlciwgc2xpY2UsIDEsIHRydWUpKVxuICAgICAgICAgICAgICAgIC5zY3JvbGxJbnRvVmlldygpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9O1xufVxuXG5leHBvcnQgeyBhZGRMaXN0Tm9kZXMsIGJ1bGxldExpc3QsIGxpZnRMaXN0SXRlbSwgbGlzdEl0ZW0sIG9yZGVyZWRMaXN0LCBzaW5rTGlzdEl0ZW0sIHNwbGl0TGlzdEl0ZW0sIHNwbGl0TGlzdEl0ZW1LZWVwTWFya3MsIHdyYXBJbkxpc3QsIHdyYXBSYW5nZUluTGlzdCB9O1xuIiwgImltcG9ydCB7IEVkaXRvclN0YXRlLCBUcmFuc2FjdGlvbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbi8qKlxuICogVGFrZXMgYSBUcmFuc2FjdGlvbiAmIEVkaXRvciBTdGF0ZSBhbmQgdHVybnMgaXQgaW50byBhIGNoYWluYWJsZSBzdGF0ZSBvYmplY3RcbiAqIEBwYXJhbSBjb25maWcgVGhlIHRyYW5zYWN0aW9uIGFuZCBzdGF0ZSB0byBjcmVhdGUgdGhlIGNoYWluYWJsZSBzdGF0ZSBmcm9tXG4gKiBAcmV0dXJucyBBIGNoYWluYWJsZSBFZGl0b3Igc3RhdGUgb2JqZWN0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVDaGFpbmFibGVTdGF0ZShjb25maWc6IHtcbiAgdHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uXG4gIHN0YXRlOiBFZGl0b3JTdGF0ZVxufSk6IEVkaXRvclN0YXRlIHtcbiAgY29uc3QgeyBzdGF0ZSwgdHJhbnNhY3Rpb24gfSA9IGNvbmZpZ1xuICBsZXQgeyBzZWxlY3Rpb24gfSA9IHRyYW5zYWN0aW9uXG4gIGxldCB7IGRvYyB9ID0gdHJhbnNhY3Rpb25cbiAgbGV0IHsgc3RvcmVkTWFya3MgfSA9IHRyYW5zYWN0aW9uXG5cbiAgcmV0dXJuIHtcbiAgICAuLi5zdGF0ZSxcbiAgICBhcHBseTogc3RhdGUuYXBwbHkuYmluZChzdGF0ZSksXG4gICAgYXBwbHlUcmFuc2FjdGlvbjogc3RhdGUuYXBwbHlUcmFuc2FjdGlvbi5iaW5kKHN0YXRlKSxcbiAgICBwbHVnaW5zOiBzdGF0ZS5wbHVnaW5zLFxuICAgIHNjaGVtYTogc3RhdGUuc2NoZW1hLFxuICAgIHJlY29uZmlndXJlOiBzdGF0ZS5yZWNvbmZpZ3VyZS5iaW5kKHN0YXRlKSxcbiAgICB0b0pTT046IHN0YXRlLnRvSlNPTi5iaW5kKHN0YXRlKSxcbiAgICBnZXQgc3RvcmVkTWFya3MoKSB7XG4gICAgICByZXR1cm4gc3RvcmVkTWFya3NcbiAgICB9LFxuICAgIGdldCBzZWxlY3Rpb24oKSB7XG4gICAgICByZXR1cm4gc2VsZWN0aW9uXG4gICAgfSxcbiAgICBnZXQgZG9jKCkge1xuICAgICAgcmV0dXJuIGRvY1xuICAgIH0sXG4gICAgZ2V0IHRyKCkge1xuICAgICAgc2VsZWN0aW9uID0gdHJhbnNhY3Rpb24uc2VsZWN0aW9uXG4gICAgICBkb2MgPSB0cmFuc2FjdGlvbi5kb2NcbiAgICAgIHN0b3JlZE1hcmtzID0gdHJhbnNhY3Rpb24uc3RvcmVkTWFya3NcblxuICAgICAgcmV0dXJuIHRyYW5zYWN0aW9uXG4gICAgfSxcbiAgfVxufVxuIiwgImltcG9ydCB7IEVkaXRvclN0YXRlLCBUcmFuc2FjdGlvbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmltcG9ydCB7IEVkaXRvciB9IGZyb20gJy4vRWRpdG9yLmpzJ1xuaW1wb3J0IHsgY3JlYXRlQ2hhaW5hYmxlU3RhdGUgfSBmcm9tICcuL2hlbHBlcnMvY3JlYXRlQ2hhaW5hYmxlU3RhdGUuanMnXG5pbXBvcnQge1xuICBBbnlDb21tYW5kcywgQ2FuQ29tbWFuZHMsIENoYWluZWRDb21tYW5kcywgQ29tbWFuZFByb3BzLCBTaW5nbGVDb21tYW5kcyxcbn0gZnJvbSAnLi90eXBlcy5qcydcblxuZXhwb3J0IGNsYXNzIENvbW1hbmRNYW5hZ2VyIHtcbiAgZWRpdG9yOiBFZGl0b3JcblxuICByYXdDb21tYW5kczogQW55Q29tbWFuZHNcblxuICBjdXN0b21TdGF0ZT86IEVkaXRvclN0YXRlXG5cbiAgY29uc3RydWN0b3IocHJvcHM6IHsgZWRpdG9yOiBFZGl0b3I7IHN0YXRlPzogRWRpdG9yU3RhdGUgfSkge1xuICAgIHRoaXMuZWRpdG9yID0gcHJvcHMuZWRpdG9yXG4gICAgdGhpcy5yYXdDb21tYW5kcyA9IHRoaXMuZWRpdG9yLmV4dGVuc2lvbk1hbmFnZXIuY29tbWFuZHNcbiAgICB0aGlzLmN1c3RvbVN0YXRlID0gcHJvcHMuc3RhdGVcbiAgfVxuXG4gIGdldCBoYXNDdXN0b21TdGF0ZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmN1c3RvbVN0YXRlXG4gIH1cblxuICBnZXQgc3RhdGUoKTogRWRpdG9yU3RhdGUge1xuICAgIHJldHVybiB0aGlzLmN1c3RvbVN0YXRlIHx8IHRoaXMuZWRpdG9yLnN0YXRlXG4gIH1cblxuICBnZXQgY29tbWFuZHMoKTogU2luZ2xlQ29tbWFuZHMge1xuICAgIGNvbnN0IHsgcmF3Q29tbWFuZHMsIGVkaXRvciwgc3RhdGUgfSA9IHRoaXNcbiAgICBjb25zdCB7IHZpZXcgfSA9IGVkaXRvclxuICAgIGNvbnN0IHsgdHIgfSA9IHN0YXRlXG4gICAgY29uc3QgcHJvcHMgPSB0aGlzLmJ1aWxkUHJvcHModHIpXG5cbiAgICByZXR1cm4gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgT2JqZWN0LmVudHJpZXMocmF3Q29tbWFuZHMpLm1hcCgoW25hbWUsIGNvbW1hbmRdKSA9PiB7XG4gICAgICAgIGNvbnN0IG1ldGhvZCA9ICguLi5hcmdzOiBhbnlbXSkgPT4ge1xuICAgICAgICAgIGNvbnN0IGNhbGxiYWNrID0gY29tbWFuZCguLi5hcmdzKShwcm9wcylcblxuICAgICAgICAgIGlmICghdHIuZ2V0TWV0YSgncHJldmVudERpc3BhdGNoJykgJiYgIXRoaXMuaGFzQ3VzdG9tU3RhdGUpIHtcbiAgICAgICAgICAgIHZpZXcuZGlzcGF0Y2godHIpXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gW25hbWUsIG1ldGhvZF1cbiAgICAgIH0pLFxuICAgICkgYXMgdW5rbm93biBhcyBTaW5nbGVDb21tYW5kc1xuICB9XG5cbiAgZ2V0IGNoYWluKCk6ICgpID0+IENoYWluZWRDb21tYW5kcyB7XG4gICAgcmV0dXJuICgpID0+IHRoaXMuY3JlYXRlQ2hhaW4oKVxuICB9XG5cbiAgZ2V0IGNhbigpOiAoKSA9PiBDYW5Db21tYW5kcyB7XG4gICAgcmV0dXJuICgpID0+IHRoaXMuY3JlYXRlQ2FuKClcbiAgfVxuXG4gIHB1YmxpYyBjcmVhdGVDaGFpbihzdGFydFRyPzogVHJhbnNhY3Rpb24sIHNob3VsZERpc3BhdGNoID0gdHJ1ZSk6IENoYWluZWRDb21tYW5kcyB7XG4gICAgY29uc3QgeyByYXdDb21tYW5kcywgZWRpdG9yLCBzdGF0ZSB9ID0gdGhpc1xuICAgIGNvbnN0IHsgdmlldyB9ID0gZWRpdG9yXG4gICAgY29uc3QgY2FsbGJhY2tzOiBib29sZWFuW10gPSBbXVxuICAgIGNvbnN0IGhhc1N0YXJ0VHJhbnNhY3Rpb24gPSAhIXN0YXJ0VHJcbiAgICBjb25zdCB0ciA9IHN0YXJ0VHIgfHwgc3RhdGUudHJcblxuICAgIGNvbnN0IHJ1biA9ICgpID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgIWhhc1N0YXJ0VHJhbnNhY3Rpb25cbiAgICAgICAgJiYgc2hvdWxkRGlzcGF0Y2hcbiAgICAgICAgJiYgIXRyLmdldE1ldGEoJ3ByZXZlbnREaXNwYXRjaCcpXG4gICAgICAgICYmICF0aGlzLmhhc0N1c3RvbVN0YXRlXG4gICAgICApIHtcbiAgICAgICAgdmlldy5kaXNwYXRjaCh0cilcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGNhbGxiYWNrcy5ldmVyeShjYWxsYmFjayA9PiBjYWxsYmFjayA9PT0gdHJ1ZSlcbiAgICB9XG5cbiAgICBjb25zdCBjaGFpbiA9IHtcbiAgICAgIC4uLk9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgICAgT2JqZWN0LmVudHJpZXMocmF3Q29tbWFuZHMpLm1hcCgoW25hbWUsIGNvbW1hbmRdKSA9PiB7XG4gICAgICAgICAgY29uc3QgY2hhaW5lZENvbW1hbmQgPSAoLi4uYXJnczogbmV2ZXJbXSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcHJvcHMgPSB0aGlzLmJ1aWxkUHJvcHModHIsIHNob3VsZERpc3BhdGNoKVxuICAgICAgICAgICAgY29uc3QgY2FsbGJhY2sgPSBjb21tYW5kKC4uLmFyZ3MpKHByb3BzKVxuXG4gICAgICAgICAgICBjYWxsYmFja3MucHVzaChjYWxsYmFjaylcblxuICAgICAgICAgICAgcmV0dXJuIGNoYWluXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIFtuYW1lLCBjaGFpbmVkQ29tbWFuZF1cbiAgICAgICAgfSksXG4gICAgICApLFxuICAgICAgcnVuLFxuICAgIH0gYXMgdW5rbm93biBhcyBDaGFpbmVkQ29tbWFuZHNcblxuICAgIHJldHVybiBjaGFpblxuICB9XG5cbiAgcHVibGljIGNyZWF0ZUNhbihzdGFydFRyPzogVHJhbnNhY3Rpb24pOiBDYW5Db21tYW5kcyB7XG4gICAgY29uc3QgeyByYXdDb21tYW5kcywgc3RhdGUgfSA9IHRoaXNcbiAgICBjb25zdCBkaXNwYXRjaCA9IGZhbHNlXG4gICAgY29uc3QgdHIgPSBzdGFydFRyIHx8IHN0YXRlLnRyXG4gICAgY29uc3QgcHJvcHMgPSB0aGlzLmJ1aWxkUHJvcHModHIsIGRpc3BhdGNoKVxuICAgIGNvbnN0IGZvcm1hdHRlZENvbW1hbmRzID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgT2JqZWN0LmVudHJpZXMocmF3Q29tbWFuZHMpLm1hcCgoW25hbWUsIGNvbW1hbmRdKSA9PiB7XG4gICAgICAgIHJldHVybiBbbmFtZSwgKC4uLmFyZ3M6IG5ldmVyW10pID0+IGNvbW1hbmQoLi4uYXJncykoeyAuLi5wcm9wcywgZGlzcGF0Y2g6IHVuZGVmaW5lZCB9KV1cbiAgICAgIH0pLFxuICAgICkgYXMgdW5rbm93biBhcyBTaW5nbGVDb21tYW5kc1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmZvcm1hdHRlZENvbW1hbmRzLFxuICAgICAgY2hhaW46ICgpID0+IHRoaXMuY3JlYXRlQ2hhaW4odHIsIGRpc3BhdGNoKSxcbiAgICB9IGFzIENhbkNvbW1hbmRzXG4gIH1cblxuICBwdWJsaWMgYnVpbGRQcm9wcyh0cjogVHJhbnNhY3Rpb24sIHNob3VsZERpc3BhdGNoID0gdHJ1ZSk6IENvbW1hbmRQcm9wcyB7XG4gICAgY29uc3QgeyByYXdDb21tYW5kcywgZWRpdG9yLCBzdGF0ZSB9ID0gdGhpc1xuICAgIGNvbnN0IHsgdmlldyB9ID0gZWRpdG9yXG5cbiAgICBjb25zdCBwcm9wczogQ29tbWFuZFByb3BzID0ge1xuICAgICAgdHIsXG4gICAgICBlZGl0b3IsXG4gICAgICB2aWV3LFxuICAgICAgc3RhdGU6IGNyZWF0ZUNoYWluYWJsZVN0YXRlKHtcbiAgICAgICAgc3RhdGUsXG4gICAgICAgIHRyYW5zYWN0aW9uOiB0cixcbiAgICAgIH0pLFxuICAgICAgZGlzcGF0Y2g6IHNob3VsZERpc3BhdGNoID8gKCkgPT4gdW5kZWZpbmVkIDogdW5kZWZpbmVkLFxuICAgICAgY2hhaW46ICgpID0+IHRoaXMuY3JlYXRlQ2hhaW4odHIsIHNob3VsZERpc3BhdGNoKSxcbiAgICAgIGNhbjogKCkgPT4gdGhpcy5jcmVhdGVDYW4odHIpLFxuICAgICAgZ2V0IGNvbW1hbmRzKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICAgIE9iamVjdC5lbnRyaWVzKHJhd0NvbW1hbmRzKS5tYXAoKFtuYW1lLCBjb21tYW5kXSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIFtuYW1lLCAoLi4uYXJnczogbmV2ZXJbXSkgPT4gY29tbWFuZCguLi5hcmdzKShwcm9wcyldXG4gICAgICAgICAgfSksXG4gICAgICAgICkgYXMgdW5rbm93biBhcyBTaW5nbGVDb21tYW5kc1xuICAgICAgfSxcbiAgICB9XG5cbiAgICByZXR1cm4gcHJvcHNcbiAgfVxufVxuIiwgInR5cGUgU3RyaW5nS2V5T2Y8VD4gPSBFeHRyYWN0PGtleW9mIFQsIHN0cmluZz5cbnR5cGUgQ2FsbGJhY2tUeXBlPFxuICBUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgYW55PixcbiAgRXZlbnROYW1lIGV4dGVuZHMgU3RyaW5nS2V5T2Y8VD4sXG4+ID0gVFtFdmVudE5hbWVdIGV4dGVuZHMgYW55W10gPyBUW0V2ZW50TmFtZV0gOiBbVFtFdmVudE5hbWVdXVxudHlwZSBDYWxsYmFja0Z1bmN0aW9uPFxuICBUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgYW55PixcbiAgRXZlbnROYW1lIGV4dGVuZHMgU3RyaW5nS2V5T2Y8VD4sXG4+ID0gKC4uLnByb3BzOiBDYWxsYmFja1R5cGU8VCwgRXZlbnROYW1lPikgPT4gYW55XG5cbmV4cG9ydCBjbGFzcyBFdmVudEVtaXR0ZXI8VCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIGFueT4+IHtcblxuICBwcml2YXRlIGNhbGxiYWNrczogeyBba2V5OiBzdHJpbmddOiBBcnJheTwoLi4uYXJnczogYW55W10pPT52b2lkPiB9ID0ge31cblxuICBwdWJsaWMgb248RXZlbnROYW1lIGV4dGVuZHMgU3RyaW5nS2V5T2Y8VD4+KGV2ZW50OiBFdmVudE5hbWUsIGZuOiBDYWxsYmFja0Z1bmN0aW9uPFQsIEV2ZW50TmFtZT4pOiB0aGlzIHtcbiAgICBpZiAoIXRoaXMuY2FsbGJhY2tzW2V2ZW50XSkge1xuICAgICAgdGhpcy5jYWxsYmFja3NbZXZlbnRdID0gW11cbiAgICB9XG5cbiAgICB0aGlzLmNhbGxiYWNrc1tldmVudF0ucHVzaChmbilcblxuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICBwdWJsaWMgZW1pdDxFdmVudE5hbWUgZXh0ZW5kcyBTdHJpbmdLZXlPZjxUPj4oZXZlbnQ6IEV2ZW50TmFtZSwgLi4uYXJnczogQ2FsbGJhY2tUeXBlPFQsIEV2ZW50TmFtZT4pOiB0aGlzIHtcbiAgICBjb25zdCBjYWxsYmFja3MgPSB0aGlzLmNhbGxiYWNrc1tldmVudF1cblxuICAgIGlmIChjYWxsYmFja3MpIHtcbiAgICAgIGNhbGxiYWNrcy5mb3JFYWNoKGNhbGxiYWNrID0+IGNhbGxiYWNrLmFwcGx5KHRoaXMsIGFyZ3MpKVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICBwdWJsaWMgb2ZmPEV2ZW50TmFtZSBleHRlbmRzIFN0cmluZ0tleU9mPFQ+PihldmVudDogRXZlbnROYW1lLCBmbj86IENhbGxiYWNrRnVuY3Rpb248VCwgRXZlbnROYW1lPik6IHRoaXMge1xuICAgIGNvbnN0IGNhbGxiYWNrcyA9IHRoaXMuY2FsbGJhY2tzW2V2ZW50XVxuXG4gICAgaWYgKGNhbGxiYWNrcykge1xuICAgICAgaWYgKGZuKSB7XG4gICAgICAgIHRoaXMuY2FsbGJhY2tzW2V2ZW50XSA9IGNhbGxiYWNrcy5maWx0ZXIoY2FsbGJhY2sgPT4gY2FsbGJhY2sgIT09IGZuKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVsZXRlIHRoaXMuY2FsbGJhY2tzW2V2ZW50XVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICBwdWJsaWMgb25jZTxFdmVudE5hbWUgZXh0ZW5kcyBTdHJpbmdLZXlPZjxUPj4oZXZlbnQ6IEV2ZW50TmFtZSwgZm46IENhbGxiYWNrRnVuY3Rpb248VCwgRXZlbnROYW1lPik6IHRoaXMge1xuICAgIGNvbnN0IG9uY2VGbiA9ICguLi5hcmdzOiBDYWxsYmFja1R5cGU8VCwgRXZlbnROYW1lPikgPT4ge1xuICAgICAgdGhpcy5vZmYoZXZlbnQsIG9uY2VGbilcbiAgICAgIGZuLmFwcGx5KHRoaXMsIGFyZ3MpXG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMub24oZXZlbnQsIG9uY2VGbilcbiAgfVxuXG4gIHB1YmxpYyByZW1vdmVBbGxMaXN0ZW5lcnMoKTogdm9pZCB7XG4gICAgdGhpcy5jYWxsYmFja3MgPSB7fVxuICB9XG59XG4iLCAiaW1wb3J0IHsgQW55RXh0ZW5zaW9uLCBNYXliZVRoaXNQYXJhbWV0ZXJUeXBlLCBSZW1vdmVUaGlzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbi8qKlxuICogUmV0dXJucyBhIGZpZWxkIGZyb20gYW4gZXh0ZW5zaW9uXG4gKiBAcGFyYW0gZXh0ZW5zaW9uIFRoZSBUaXB0YXAgZXh0ZW5zaW9uXG4gKiBAcGFyYW0gZmllbGQgVGhlIGZpZWxkLCBmb3IgZXhhbXBsZSBgcmVuZGVySFRNTGAgb3IgYHByaW9yaXR5YFxuICogQHBhcmFtIGNvbnRleHQgVGhlIGNvbnRleHQgb2JqZWN0IHRoYXQgc2hvdWxkIGJlIHBhc3NlZCBhcyBgdGhpc2AgaW50byB0aGUgZnVuY3Rpb25cbiAqIEByZXR1cm5zIFRoZSBmaWVsZCB2YWx1ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RXh0ZW5zaW9uRmllbGQ8VCA9IGFueT4oXG4gIGV4dGVuc2lvbjogQW55RXh0ZW5zaW9uLFxuICBmaWVsZDogc3RyaW5nLFxuICBjb250ZXh0PzogT21pdDxNYXliZVRoaXNQYXJhbWV0ZXJUeXBlPFQ+LCAncGFyZW50Jz4sXG4pOiBSZW1vdmVUaGlzPFQ+IHtcblxuICBpZiAoZXh0ZW5zaW9uLmNvbmZpZ1tmaWVsZF0gPT09IHVuZGVmaW5lZCAmJiBleHRlbnNpb24ucGFyZW50KSB7XG4gICAgcmV0dXJuIGdldEV4dGVuc2lvbkZpZWxkKGV4dGVuc2lvbi5wYXJlbnQsIGZpZWxkLCBjb250ZXh0KVxuICB9XG5cbiAgaWYgKHR5cGVvZiBleHRlbnNpb24uY29uZmlnW2ZpZWxkXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNvbnN0IHZhbHVlID0gZXh0ZW5zaW9uLmNvbmZpZ1tmaWVsZF0uYmluZCh7XG4gICAgICAuLi5jb250ZXh0LFxuICAgICAgcGFyZW50OiBleHRlbnNpb24ucGFyZW50XG4gICAgICAgID8gZ2V0RXh0ZW5zaW9uRmllbGQoZXh0ZW5zaW9uLnBhcmVudCwgZmllbGQsIGNvbnRleHQpXG4gICAgICAgIDogbnVsbCxcbiAgICB9KVxuXG4gICAgcmV0dXJuIHZhbHVlXG4gIH1cblxuICByZXR1cm4gZXh0ZW5zaW9uLmNvbmZpZ1tmaWVsZF1cbn1cbiIsICJpbXBvcnQgeyBFeHRlbnNpb24gfSBmcm9tICcuLi9FeHRlbnNpb24uanMnXG5pbXBvcnQgeyBNYXJrIH0gZnJvbSAnLi4vTWFyay5qcydcbmltcG9ydCB7IE5vZGUgfSBmcm9tICcuLi9Ob2RlLmpzJ1xuaW1wb3J0IHsgRXh0ZW5zaW9ucyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5leHBvcnQgZnVuY3Rpb24gc3BsaXRFeHRlbnNpb25zKGV4dGVuc2lvbnM6IEV4dGVuc2lvbnMpIHtcbiAgY29uc3QgYmFzZUV4dGVuc2lvbnMgPSBleHRlbnNpb25zLmZpbHRlcihleHRlbnNpb24gPT4gZXh0ZW5zaW9uLnR5cGUgPT09ICdleHRlbnNpb24nKSBhcyBFeHRlbnNpb25bXVxuICBjb25zdCBub2RlRXh0ZW5zaW9ucyA9IGV4dGVuc2lvbnMuZmlsdGVyKGV4dGVuc2lvbiA9PiBleHRlbnNpb24udHlwZSA9PT0gJ25vZGUnKSBhcyBOb2RlW11cbiAgY29uc3QgbWFya0V4dGVuc2lvbnMgPSBleHRlbnNpb25zLmZpbHRlcihleHRlbnNpb24gPT4gZXh0ZW5zaW9uLnR5cGUgPT09ICdtYXJrJykgYXMgTWFya1tdXG5cbiAgcmV0dXJuIHtcbiAgICBiYXNlRXh0ZW5zaW9ucyxcbiAgICBub2RlRXh0ZW5zaW9ucyxcbiAgICBtYXJrRXh0ZW5zaW9ucyxcbiAgfVxufVxuIiwgImltcG9ydCB7IE1hcmtDb25maWcsIE5vZGVDb25maWcgfSBmcm9tICcuLi9pbmRleC5qcydcbmltcG9ydCB7XG4gIEFueUNvbmZpZyxcbiAgQXR0cmlidXRlLFxuICBBdHRyaWJ1dGVzLFxuICBFeHRlbnNpb25BdHRyaWJ1dGUsXG4gIEV4dGVuc2lvbnMsXG59IGZyb20gJy4uL3R5cGVzLmpzJ1xuaW1wb3J0IHsgZ2V0RXh0ZW5zaW9uRmllbGQgfSBmcm9tICcuL2dldEV4dGVuc2lvbkZpZWxkLmpzJ1xuaW1wb3J0IHsgc3BsaXRFeHRlbnNpb25zIH0gZnJvbSAnLi9zcGxpdEV4dGVuc2lvbnMuanMnXG5cbi8qKlxuICogR2V0IGEgbGlzdCBvZiBhbGwgZXh0ZW5zaW9uIGF0dHJpYnV0ZXMgZGVmaW5lZCBpbiBgYWRkQXR0cmlidXRlYCBhbmQgYGFkZEdsb2JhbEF0dHJpYnV0ZWAuXG4gKiBAcGFyYW0gZXh0ZW5zaW9ucyBMaXN0IG9mIGV4dGVuc2lvbnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEF0dHJpYnV0ZXNGcm9tRXh0ZW5zaW9ucyhleHRlbnNpb25zOiBFeHRlbnNpb25zKTogRXh0ZW5zaW9uQXR0cmlidXRlW10ge1xuICBjb25zdCBleHRlbnNpb25BdHRyaWJ1dGVzOiBFeHRlbnNpb25BdHRyaWJ1dGVbXSA9IFtdXG4gIGNvbnN0IHsgbm9kZUV4dGVuc2lvbnMsIG1hcmtFeHRlbnNpb25zIH0gPSBzcGxpdEV4dGVuc2lvbnMoZXh0ZW5zaW9ucylcbiAgY29uc3Qgbm9kZUFuZE1hcmtFeHRlbnNpb25zID0gWy4uLm5vZGVFeHRlbnNpb25zLCAuLi5tYXJrRXh0ZW5zaW9uc11cbiAgY29uc3QgZGVmYXVsdEF0dHJpYnV0ZTogUmVxdWlyZWQ8QXR0cmlidXRlPiA9IHtcbiAgICBkZWZhdWx0OiBudWxsLFxuICAgIHJlbmRlcmVkOiB0cnVlLFxuICAgIHJlbmRlckhUTUw6IG51bGwsXG4gICAgcGFyc2VIVE1MOiBudWxsLFxuICAgIGtlZXBPblNwbGl0OiB0cnVlLFxuICAgIGlzUmVxdWlyZWQ6IGZhbHNlLFxuICB9XG5cbiAgZXh0ZW5zaW9ucy5mb3JFYWNoKGV4dGVuc2lvbiA9PiB7XG4gICAgY29uc3QgY29udGV4dCA9IHtcbiAgICAgIG5hbWU6IGV4dGVuc2lvbi5uYW1lLFxuICAgICAgb3B0aW9uczogZXh0ZW5zaW9uLm9wdGlvbnMsXG4gICAgICBzdG9yYWdlOiBleHRlbnNpb24uc3RvcmFnZSxcbiAgICAgIGV4dGVuc2lvbnM6IG5vZGVBbmRNYXJrRXh0ZW5zaW9ucyxcbiAgICB9XG5cbiAgICBjb25zdCBhZGRHbG9iYWxBdHRyaWJ1dGVzID0gZ2V0RXh0ZW5zaW9uRmllbGQ8QW55Q29uZmlnWydhZGRHbG9iYWxBdHRyaWJ1dGVzJ10+KFxuICAgICAgZXh0ZW5zaW9uLFxuICAgICAgJ2FkZEdsb2JhbEF0dHJpYnV0ZXMnLFxuICAgICAgY29udGV4dCxcbiAgICApXG5cbiAgICBpZiAoIWFkZEdsb2JhbEF0dHJpYnV0ZXMpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IGdsb2JhbEF0dHJpYnV0ZXMgPSBhZGRHbG9iYWxBdHRyaWJ1dGVzKClcblxuICAgIGdsb2JhbEF0dHJpYnV0ZXMuZm9yRWFjaChnbG9iYWxBdHRyaWJ1dGUgPT4ge1xuICAgICAgZ2xvYmFsQXR0cmlidXRlLnR5cGVzLmZvckVhY2godHlwZSA9PiB7XG4gICAgICAgIE9iamVjdFxuICAgICAgICAgIC5lbnRyaWVzKGdsb2JhbEF0dHJpYnV0ZS5hdHRyaWJ1dGVzKVxuICAgICAgICAgIC5mb3JFYWNoKChbbmFtZSwgYXR0cmlidXRlXSkgPT4ge1xuICAgICAgICAgICAgZXh0ZW5zaW9uQXR0cmlidXRlcy5wdXNoKHtcbiAgICAgICAgICAgICAgdHlwZSxcbiAgICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgICAgYXR0cmlidXRlOiB7XG4gICAgICAgICAgICAgICAgLi4uZGVmYXVsdEF0dHJpYnV0ZSxcbiAgICAgICAgICAgICAgICAuLi5hdHRyaWJ1dGUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIH0pXG4gICAgICB9KVxuICAgIH0pXG4gIH0pXG5cbiAgbm9kZUFuZE1hcmtFeHRlbnNpb25zLmZvckVhY2goZXh0ZW5zaW9uID0+IHtcbiAgICBjb25zdCBjb250ZXh0ID0ge1xuICAgICAgbmFtZTogZXh0ZW5zaW9uLm5hbWUsXG4gICAgICBvcHRpb25zOiBleHRlbnNpb24ub3B0aW9ucyxcbiAgICAgIHN0b3JhZ2U6IGV4dGVuc2lvbi5zdG9yYWdlLFxuICAgIH1cblxuICAgIGNvbnN0IGFkZEF0dHJpYnV0ZXMgPSBnZXRFeHRlbnNpb25GaWVsZDxOb2RlQ29uZmlnWydhZGRBdHRyaWJ1dGVzJ10gfCBNYXJrQ29uZmlnWydhZGRBdHRyaWJ1dGVzJ10+KFxuICAgICAgZXh0ZW5zaW9uLFxuICAgICAgJ2FkZEF0dHJpYnV0ZXMnLFxuICAgICAgY29udGV4dCxcbiAgICApXG5cbiAgICBpZiAoIWFkZEF0dHJpYnV0ZXMpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIC8vIFRPRE86IHJlbW92ZSBgYXMgQXR0cmlidXRlc2BcbiAgICBjb25zdCBhdHRyaWJ1dGVzID0gYWRkQXR0cmlidXRlcygpIGFzIEF0dHJpYnV0ZXNcblxuICAgIE9iamVjdFxuICAgICAgLmVudHJpZXMoYXR0cmlidXRlcylcbiAgICAgIC5mb3JFYWNoKChbbmFtZSwgYXR0cmlidXRlXSkgPT4ge1xuICAgICAgICBjb25zdCBtZXJnZWRBdHRyID0ge1xuICAgICAgICAgIC4uLmRlZmF1bHRBdHRyaWJ1dGUsXG4gICAgICAgICAgLi4uYXR0cmlidXRlLFxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVvZiBtZXJnZWRBdHRyPy5kZWZhdWx0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgbWVyZ2VkQXR0ci5kZWZhdWx0ID0gbWVyZ2VkQXR0ci5kZWZhdWx0KClcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChtZXJnZWRBdHRyPy5pc1JlcXVpcmVkICYmIG1lcmdlZEF0dHI/LmRlZmF1bHQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGRlbGV0ZSBtZXJnZWRBdHRyLmRlZmF1bHRcbiAgICAgICAgfVxuXG4gICAgICAgIGV4dGVuc2lvbkF0dHJpYnV0ZXMucHVzaCh7XG4gICAgICAgICAgdHlwZTogZXh0ZW5zaW9uLm5hbWUsXG4gICAgICAgICAgbmFtZSxcbiAgICAgICAgICBhdHRyaWJ1dGU6IG1lcmdlZEF0dHIsXG4gICAgICAgIH0pXG4gICAgICB9KVxuICB9KVxuXG4gIHJldHVybiBleHRlbnNpb25BdHRyaWJ1dGVzXG59XG4iLCAiaW1wb3J0IHsgTm9kZVR5cGUsIFNjaGVtYSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXROb2RlVHlwZShuYW1lT3JUeXBlOiBzdHJpbmcgfCBOb2RlVHlwZSwgc2NoZW1hOiBTY2hlbWEpOiBOb2RlVHlwZSB7XG4gIGlmICh0eXBlb2YgbmFtZU9yVHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICBpZiAoIXNjaGVtYS5ub2Rlc1tuYW1lT3JUeXBlXSkge1xuICAgICAgdGhyb3cgRXJyb3IoXG4gICAgICAgIGBUaGVyZSBpcyBubyBub2RlIHR5cGUgbmFtZWQgJyR7bmFtZU9yVHlwZX0nLiBNYXliZSB5b3UgZm9yZ290IHRvIGFkZCB0aGUgZXh0ZW5zaW9uP2AsXG4gICAgICApXG4gICAgfVxuXG4gICAgcmV0dXJuIHNjaGVtYS5ub2Rlc1tuYW1lT3JUeXBlXVxuICB9XG5cbiAgcmV0dXJuIG5hbWVPclR5cGVcbn1cbiIsICJleHBvcnQgZnVuY3Rpb24gbWVyZ2VBdHRyaWJ1dGVzKC4uLm9iamVjdHM6IFJlY29yZDxzdHJpbmcsIGFueT5bXSk6IFJlY29yZDxzdHJpbmcsIGFueT4ge1xuICByZXR1cm4gb2JqZWN0c1xuICAgIC5maWx0ZXIoaXRlbSA9PiAhIWl0ZW0pXG4gICAgLnJlZHVjZSgoaXRlbXMsIGl0ZW0pID0+IHtcbiAgICAgIGNvbnN0IG1lcmdlZEF0dHJpYnV0ZXMgPSB7IC4uLml0ZW1zIH1cblxuICAgICAgT2JqZWN0LmVudHJpZXMoaXRlbSkuZm9yRWFjaCgoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICAgIGNvbnN0IGV4aXN0cyA9IG1lcmdlZEF0dHJpYnV0ZXNba2V5XVxuXG4gICAgICAgIGlmICghZXhpc3RzKSB7XG4gICAgICAgICAgbWVyZ2VkQXR0cmlidXRlc1trZXldID0gdmFsdWVcblxuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGtleSA9PT0gJ2NsYXNzJykge1xuICAgICAgICAgIGNvbnN0IHZhbHVlQ2xhc3Nlczogc3RyaW5nW10gPSB2YWx1ZSA/IFN0cmluZyh2YWx1ZSkuc3BsaXQoJyAnKSA6IFtdXG4gICAgICAgICAgY29uc3QgZXhpc3RpbmdDbGFzc2VzOiBzdHJpbmdbXSA9IG1lcmdlZEF0dHJpYnV0ZXNba2V5XSA/IG1lcmdlZEF0dHJpYnV0ZXNba2V5XS5zcGxpdCgnICcpIDogW11cblxuICAgICAgICAgIGNvbnN0IGluc2VydENsYXNzZXMgPSB2YWx1ZUNsYXNzZXMuZmlsdGVyKFxuICAgICAgICAgICAgdmFsdWVDbGFzcyA9PiAhZXhpc3RpbmdDbGFzc2VzLmluY2x1ZGVzKHZhbHVlQ2xhc3MpLFxuICAgICAgICAgIClcblxuICAgICAgICAgIG1lcmdlZEF0dHJpYnV0ZXNba2V5XSA9IFsuLi5leGlzdGluZ0NsYXNzZXMsIC4uLmluc2VydENsYXNzZXNdLmpvaW4oJyAnKVxuICAgICAgICB9IGVsc2UgaWYgKGtleSA9PT0gJ3N0eWxlJykge1xuICAgICAgICAgIGNvbnN0IG5ld1N0eWxlczogc3RyaW5nW10gPSB2YWx1ZSA/IHZhbHVlLnNwbGl0KCc7JykubWFwKChzdHlsZTogc3RyaW5nKSA9PiBzdHlsZS50cmltKCkpLmZpbHRlcihCb29sZWFuKSA6IFtdXG4gICAgICAgICAgY29uc3QgZXhpc3RpbmdTdHlsZXM6IHN0cmluZ1tdID0gbWVyZ2VkQXR0cmlidXRlc1trZXldID8gbWVyZ2VkQXR0cmlidXRlc1trZXldLnNwbGl0KCc7JykubWFwKChzdHlsZTogc3RyaW5nKSA9PiBzdHlsZS50cmltKCkpLmZpbHRlcihCb29sZWFuKSA6IFtdXG5cbiAgICAgICAgICBjb25zdCBzdHlsZU1hcCA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KClcblxuICAgICAgICAgIGV4aXN0aW5nU3R5bGVzLmZvckVhY2goc3R5bGUgPT4ge1xuICAgICAgICAgICAgY29uc3QgW3Byb3BlcnR5LCB2YWxdID0gc3R5bGUuc3BsaXQoJzonKS5tYXAocGFydCA9PiBwYXJ0LnRyaW0oKSlcblxuICAgICAgICAgICAgc3R5bGVNYXAuc2V0KHByb3BlcnR5LCB2YWwpXG4gICAgICAgICAgfSlcblxuICAgICAgICAgIG5ld1N0eWxlcy5mb3JFYWNoKHN0eWxlID0+IHtcbiAgICAgICAgICAgIGNvbnN0IFtwcm9wZXJ0eSwgdmFsXSA9IHN0eWxlLnNwbGl0KCc6JykubWFwKHBhcnQgPT4gcGFydC50cmltKCkpXG5cbiAgICAgICAgICAgIHN0eWxlTWFwLnNldChwcm9wZXJ0eSwgdmFsKVxuICAgICAgICAgIH0pXG5cbiAgICAgICAgICBtZXJnZWRBdHRyaWJ1dGVzW2tleV0gPSBBcnJheS5mcm9tKHN0eWxlTWFwLmVudHJpZXMoKSkubWFwKChbcHJvcGVydHksIHZhbF0pID0+IGAke3Byb3BlcnR5fTogJHt2YWx9YCkuam9pbignOyAnKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG1lcmdlZEF0dHJpYnV0ZXNba2V5XSA9IHZhbHVlXG4gICAgICAgIH1cbiAgICAgIH0pXG5cbiAgICAgIHJldHVybiBtZXJnZWRBdHRyaWJ1dGVzXG4gICAgfSwge30pXG59XG4iLCAiaW1wb3J0IHsgTWFyaywgTm9kZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmltcG9ydCB7IEV4dGVuc2lvbkF0dHJpYnV0ZSB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuaW1wb3J0IHsgbWVyZ2VBdHRyaWJ1dGVzIH0gZnJvbSAnLi4vdXRpbGl0aWVzL21lcmdlQXR0cmlidXRlcy5qcydcblxuZXhwb3J0IGZ1bmN0aW9uIGdldFJlbmRlcmVkQXR0cmlidXRlcyhcbiAgbm9kZU9yTWFyazogTm9kZSB8IE1hcmssXG4gIGV4dGVuc2lvbkF0dHJpYnV0ZXM6IEV4dGVuc2lvbkF0dHJpYnV0ZVtdLFxuKTogUmVjb3JkPHN0cmluZywgYW55PiB7XG4gIHJldHVybiBleHRlbnNpb25BdHRyaWJ1dGVzXG4gICAgLmZpbHRlcihcbiAgICAgIGF0dHJpYnV0ZSA9PiBhdHRyaWJ1dGUudHlwZSA9PT0gbm9kZU9yTWFyay50eXBlLm5hbWUsXG4gICAgKVxuICAgIC5maWx0ZXIoaXRlbSA9PiBpdGVtLmF0dHJpYnV0ZS5yZW5kZXJlZClcbiAgICAubWFwKGl0ZW0gPT4ge1xuICAgICAgaWYgKCFpdGVtLmF0dHJpYnV0ZS5yZW5kZXJIVE1MKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgW2l0ZW0ubmFtZV06IG5vZGVPck1hcmsuYXR0cnNbaXRlbS5uYW1lXSxcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gaXRlbS5hdHRyaWJ1dGUucmVuZGVySFRNTChub2RlT3JNYXJrLmF0dHJzKSB8fCB7fVxuICAgIH0pXG4gICAgLnJlZHVjZSgoYXR0cmlidXRlcywgYXR0cmlidXRlKSA9PiBtZXJnZUF0dHJpYnV0ZXMoYXR0cmlidXRlcywgYXR0cmlidXRlKSwge30pXG59XG4iLCAiLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtZnVuY3Rpb24tdHlwZVxuZXhwb3J0IGZ1bmN0aW9uIGlzRnVuY3Rpb24odmFsdWU6IGFueSk6IHZhbHVlIGlzIEZ1bmN0aW9uIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJ1xufVxuIiwgImltcG9ydCB7IE1heWJlUmV0dXJuVHlwZSB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuaW1wb3J0IHsgaXNGdW5jdGlvbiB9IGZyb20gJy4vaXNGdW5jdGlvbi5qcydcblxuLyoqXG4gKiBPcHRpb25hbGx5IGNhbGxzIGB2YWx1ZWAgYXMgYSBmdW5jdGlvbi5cbiAqIE90aGVyd2lzZSBpdCBpcyByZXR1cm5lZCBkaXJlY3RseS5cbiAqIEBwYXJhbSB2YWx1ZSBGdW5jdGlvbiBvciBhbnkgdmFsdWUuXG4gKiBAcGFyYW0gY29udGV4dCBPcHRpb25hbCBjb250ZXh0IHRvIGJpbmQgdG8gZnVuY3Rpb24uXG4gKiBAcGFyYW0gcHJvcHMgT3B0aW9uYWwgcHJvcHMgdG8gcGFzcyB0byBmdW5jdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhbGxPclJldHVybjxUPih2YWx1ZTogVCwgY29udGV4dDogYW55ID0gdW5kZWZpbmVkLCAuLi5wcm9wczogYW55W10pOiBNYXliZVJldHVyblR5cGU8VD4ge1xuICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHtcbiAgICBpZiAoY29udGV4dCkge1xuICAgICAgcmV0dXJuIHZhbHVlLmJpbmQoY29udGV4dCkoLi4ucHJvcHMpXG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlKC4uLnByb3BzKVxuICB9XG5cbiAgcmV0dXJuIHZhbHVlIGFzIE1heWJlUmV0dXJuVHlwZTxUPlxufVxuIiwgImV4cG9ydCBmdW5jdGlvbiBpc0VtcHR5T2JqZWN0KHZhbHVlID0ge30pOiBib29sZWFuIHtcbiAgcmV0dXJuIE9iamVjdC5rZXlzKHZhbHVlKS5sZW5ndGggPT09IDAgJiYgdmFsdWUuY29uc3RydWN0b3IgPT09IE9iamVjdFxufVxuIiwgImV4cG9ydCBmdW5jdGlvbiBmcm9tU3RyaW5nKHZhbHVlOiBhbnkpOiBhbnkge1xuICBpZiAodHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJykge1xuICAgIHJldHVybiB2YWx1ZVxuICB9XG5cbiAgaWYgKHZhbHVlLm1hdGNoKC9eWystXT8oPzpcXGQqXFwuKT9cXGQrJC8pKSB7XG4gICAgcmV0dXJuIE51bWJlcih2YWx1ZSlcbiAgfVxuXG4gIGlmICh2YWx1ZSA9PT0gJ3RydWUnKSB7XG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIGlmICh2YWx1ZSA9PT0gJ2ZhbHNlJykge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgcmV0dXJuIHZhbHVlXG59XG4iLCAiaW1wb3J0IHsgUGFyc2VSdWxlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuaW1wb3J0IHsgRXh0ZW5zaW9uQXR0cmlidXRlIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5pbXBvcnQgeyBmcm9tU3RyaW5nIH0gZnJvbSAnLi4vdXRpbGl0aWVzL2Zyb21TdHJpbmcuanMnXG5cbi8qKlxuICogVGhpcyBmdW5jdGlvbiBtZXJnZXMgZXh0ZW5zaW9uIGF0dHJpYnV0ZXMgaW50byBwYXJzZXJ1bGUgYXR0cmlidXRlcyAoYGF0dHJzYCBvciBgZ2V0QXR0cnNgKS5cbiAqIENhbmNlbHMgd2hlbiBgZ2V0QXR0cnNgIHJldHVybmVkIGBmYWxzZWAuXG4gKiBAcGFyYW0gcGFyc2VSdWxlIFByb3NlTWlycm9yIFBhcnNlUnVsZVxuICogQHBhcmFtIGV4dGVuc2lvbkF0dHJpYnV0ZXMgTGlzdCBvZiBhdHRyaWJ1dGVzIHRvIGluamVjdFxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5qZWN0RXh0ZW5zaW9uQXR0cmlidXRlc1RvUGFyc2VSdWxlKFxuICBwYXJzZVJ1bGU6IFBhcnNlUnVsZSxcbiAgZXh0ZW5zaW9uQXR0cmlidXRlczogRXh0ZW5zaW9uQXR0cmlidXRlW10sXG4pOiBQYXJzZVJ1bGUge1xuICBpZiAoJ3N0eWxlJyBpbiBwYXJzZVJ1bGUpIHtcbiAgICByZXR1cm4gcGFyc2VSdWxlXG4gIH1cblxuICByZXR1cm4ge1xuICAgIC4uLnBhcnNlUnVsZSxcbiAgICBnZXRBdHRyczogKG5vZGU6IEhUTUxFbGVtZW50KSA9PiB7XG4gICAgICBjb25zdCBvbGRBdHRyaWJ1dGVzID0gcGFyc2VSdWxlLmdldEF0dHJzID8gcGFyc2VSdWxlLmdldEF0dHJzKG5vZGUpIDogcGFyc2VSdWxlLmF0dHJzXG5cbiAgICAgIGlmIChvbGRBdHRyaWJ1dGVzID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgIH1cblxuICAgICAgY29uc3QgbmV3QXR0cmlidXRlcyA9IGV4dGVuc2lvbkF0dHJpYnV0ZXMucmVkdWNlKChpdGVtcywgaXRlbSkgPT4ge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IGl0ZW0uYXR0cmlidXRlLnBhcnNlSFRNTFxuICAgICAgICAgID8gaXRlbS5hdHRyaWJ1dGUucGFyc2VIVE1MKG5vZGUpXG4gICAgICAgICAgOiBmcm9tU3RyaW5nKChub2RlKS5nZXRBdHRyaWJ1dGUoaXRlbS5uYW1lKSlcblxuICAgICAgICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHJldHVybiBpdGVtc1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAuLi5pdGVtcyxcbiAgICAgICAgICBbaXRlbS5uYW1lXTogdmFsdWUsXG4gICAgICAgIH1cbiAgICAgIH0sIHt9KVxuXG4gICAgICByZXR1cm4geyAuLi5vbGRBdHRyaWJ1dGVzLCAuLi5uZXdBdHRyaWJ1dGVzIH1cbiAgICB9LFxuICB9XG59XG4iLCAiaW1wb3J0IHtcbiAgTWFya1NwZWMsIE5vZGVTcGVjLCBTY2hlbWEsIFRhZ1BhcnNlUnVsZSxcbn0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuaW1wb3J0IHsgRWRpdG9yLCBNYXJrQ29uZmlnLCBOb2RlQ29uZmlnIH0gZnJvbSAnLi4vaW5kZXguanMnXG5pbXBvcnQgeyBBbnlDb25maWcsIEV4dGVuc2lvbnMgfSBmcm9tICcuLi90eXBlcy5qcydcbmltcG9ydCB7IGNhbGxPclJldHVybiB9IGZyb20gJy4uL3V0aWxpdGllcy9jYWxsT3JSZXR1cm4uanMnXG5pbXBvcnQgeyBpc0VtcHR5T2JqZWN0IH0gZnJvbSAnLi4vdXRpbGl0aWVzL2lzRW1wdHlPYmplY3QuanMnXG5pbXBvcnQgeyBnZXRBdHRyaWJ1dGVzRnJvbUV4dGVuc2lvbnMgfSBmcm9tICcuL2dldEF0dHJpYnV0ZXNGcm9tRXh0ZW5zaW9ucy5qcydcbmltcG9ydCB7IGdldEV4dGVuc2lvbkZpZWxkIH0gZnJvbSAnLi9nZXRFeHRlbnNpb25GaWVsZC5qcydcbmltcG9ydCB7IGdldFJlbmRlcmVkQXR0cmlidXRlcyB9IGZyb20gJy4vZ2V0UmVuZGVyZWRBdHRyaWJ1dGVzLmpzJ1xuaW1wb3J0IHsgaW5qZWN0RXh0ZW5zaW9uQXR0cmlidXRlc1RvUGFyc2VSdWxlIH0gZnJvbSAnLi9pbmplY3RFeHRlbnNpb25BdHRyaWJ1dGVzVG9QYXJzZVJ1bGUuanMnXG5pbXBvcnQgeyBzcGxpdEV4dGVuc2lvbnMgfSBmcm9tICcuL3NwbGl0RXh0ZW5zaW9ucy5qcydcblxuZnVuY3Rpb24gY2xlYW5VcFNjaGVtYUl0ZW08VD4oZGF0YTogVCkge1xuICByZXR1cm4gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgIC8vIEB0cy1pZ25vcmVcbiAgICBPYmplY3QuZW50cmllcyhkYXRhKS5maWx0ZXIoKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgaWYgKGtleSA9PT0gJ2F0dHJzJyAmJiBpc0VtcHR5T2JqZWN0KHZhbHVlIGFzIG9iamVjdCB8IHVuZGVmaW5lZCkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9XG5cbiAgICAgIHJldHVybiB2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZSAhPT0gdW5kZWZpbmVkXG4gICAgfSksXG4gICkgYXMgVFxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgUHJvc2VtaXJyb3Igc2NoZW1hIGJhc2VkIG9uIHRoZSBnaXZlbiBleHRlbnNpb25zLlxuICogQHBhcmFtIGV4dGVuc2lvbnMgQW4gYXJyYXkgb2YgVGlwdGFwIGV4dGVuc2lvbnNcbiAqIEBwYXJhbSBlZGl0b3IgVGhlIGVkaXRvciBpbnN0YW5jZVxuICogQHJldHVybnMgQSBQcm9zZW1pcnJvciBzY2hlbWFcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFNjaGVtYUJ5UmVzb2x2ZWRFeHRlbnNpb25zKGV4dGVuc2lvbnM6IEV4dGVuc2lvbnMsIGVkaXRvcj86IEVkaXRvcik6IFNjaGVtYSB7XG4gIGNvbnN0IGFsbEF0dHJpYnV0ZXMgPSBnZXRBdHRyaWJ1dGVzRnJvbUV4dGVuc2lvbnMoZXh0ZW5zaW9ucylcbiAgY29uc3QgeyBub2RlRXh0ZW5zaW9ucywgbWFya0V4dGVuc2lvbnMgfSA9IHNwbGl0RXh0ZW5zaW9ucyhleHRlbnNpb25zKVxuICBjb25zdCB0b3BOb2RlID0gbm9kZUV4dGVuc2lvbnMuZmluZChleHRlbnNpb24gPT4gZ2V0RXh0ZW5zaW9uRmllbGQoZXh0ZW5zaW9uLCAndG9wTm9kZScpKT8ubmFtZVxuXG4gIGNvbnN0IG5vZGVzID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgIG5vZGVFeHRlbnNpb25zLm1hcChleHRlbnNpb24gPT4ge1xuICAgICAgY29uc3QgZXh0ZW5zaW9uQXR0cmlidXRlcyA9IGFsbEF0dHJpYnV0ZXMuZmlsdGVyKFxuICAgICAgICBhdHRyaWJ1dGUgPT4gYXR0cmlidXRlLnR5cGUgPT09IGV4dGVuc2lvbi5uYW1lLFxuICAgICAgKVxuICAgICAgY29uc3QgY29udGV4dCA9IHtcbiAgICAgICAgbmFtZTogZXh0ZW5zaW9uLm5hbWUsXG4gICAgICAgIG9wdGlvbnM6IGV4dGVuc2lvbi5vcHRpb25zLFxuICAgICAgICBzdG9yYWdlOiBleHRlbnNpb24uc3RvcmFnZSxcbiAgICAgICAgZWRpdG9yLFxuICAgICAgfVxuXG4gICAgICBjb25zdCBleHRyYU5vZGVGaWVsZHMgPSBleHRlbnNpb25zLnJlZHVjZSgoZmllbGRzLCBlKSA9PiB7XG4gICAgICAgIGNvbnN0IGV4dGVuZE5vZGVTY2hlbWEgPSBnZXRFeHRlbnNpb25GaWVsZDxBbnlDb25maWdbJ2V4dGVuZE5vZGVTY2hlbWEnXT4oXG4gICAgICAgICAgZSxcbiAgICAgICAgICAnZXh0ZW5kTm9kZVNjaGVtYScsXG4gICAgICAgICAgY29udGV4dCxcbiAgICAgICAgKVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgLi4uZmllbGRzLFxuICAgICAgICAgIC4uLihleHRlbmROb2RlU2NoZW1hID8gZXh0ZW5kTm9kZVNjaGVtYShleHRlbnNpb24pIDoge30pLFxuICAgICAgICB9XG4gICAgICB9LCB7fSlcblxuICAgICAgY29uc3Qgc2NoZW1hOiBOb2RlU3BlYyA9IGNsZWFuVXBTY2hlbWFJdGVtKHtcbiAgICAgICAgLi4uZXh0cmFOb2RlRmllbGRzLFxuICAgICAgICBjb250ZW50OiBjYWxsT3JSZXR1cm4oXG4gICAgICAgICAgZ2V0RXh0ZW5zaW9uRmllbGQ8Tm9kZUNvbmZpZ1snY29udGVudCddPihleHRlbnNpb24sICdjb250ZW50JywgY29udGV4dCksXG4gICAgICAgICksXG4gICAgICAgIG1hcmtzOiBjYWxsT3JSZXR1cm4oZ2V0RXh0ZW5zaW9uRmllbGQ8Tm9kZUNvbmZpZ1snbWFya3MnXT4oZXh0ZW5zaW9uLCAnbWFya3MnLCBjb250ZXh0KSksXG4gICAgICAgIGdyb3VwOiBjYWxsT3JSZXR1cm4oZ2V0RXh0ZW5zaW9uRmllbGQ8Tm9kZUNvbmZpZ1snZ3JvdXAnXT4oZXh0ZW5zaW9uLCAnZ3JvdXAnLCBjb250ZXh0KSksXG4gICAgICAgIGlubGluZTogY2FsbE9yUmV0dXJuKGdldEV4dGVuc2lvbkZpZWxkPE5vZGVDb25maWdbJ2lubGluZSddPihleHRlbnNpb24sICdpbmxpbmUnLCBjb250ZXh0KSksXG4gICAgICAgIGF0b206IGNhbGxPclJldHVybihnZXRFeHRlbnNpb25GaWVsZDxOb2RlQ29uZmlnWydhdG9tJ10+KGV4dGVuc2lvbiwgJ2F0b20nLCBjb250ZXh0KSksXG4gICAgICAgIHNlbGVjdGFibGU6IGNhbGxPclJldHVybihcbiAgICAgICAgICBnZXRFeHRlbnNpb25GaWVsZDxOb2RlQ29uZmlnWydzZWxlY3RhYmxlJ10+KGV4dGVuc2lvbiwgJ3NlbGVjdGFibGUnLCBjb250ZXh0KSxcbiAgICAgICAgKSxcbiAgICAgICAgZHJhZ2dhYmxlOiBjYWxsT3JSZXR1cm4oXG4gICAgICAgICAgZ2V0RXh0ZW5zaW9uRmllbGQ8Tm9kZUNvbmZpZ1snZHJhZ2dhYmxlJ10+KGV4dGVuc2lvbiwgJ2RyYWdnYWJsZScsIGNvbnRleHQpLFxuICAgICAgICApLFxuICAgICAgICBjb2RlOiBjYWxsT3JSZXR1cm4oZ2V0RXh0ZW5zaW9uRmllbGQ8Tm9kZUNvbmZpZ1snY29kZSddPihleHRlbnNpb24sICdjb2RlJywgY29udGV4dCkpLFxuICAgICAgICB3aGl0ZXNwYWNlOiBjYWxsT3JSZXR1cm4oZ2V0RXh0ZW5zaW9uRmllbGQ8Tm9kZUNvbmZpZ1snd2hpdGVzcGFjZSddPihleHRlbnNpb24sICd3aGl0ZXNwYWNlJywgY29udGV4dCkpLFxuICAgICAgICBsaW5lYnJlYWtSZXBsYWNlbWVudDogY2FsbE9yUmV0dXJuKGdldEV4dGVuc2lvbkZpZWxkPE5vZGVDb25maWdbJ2xpbmVicmVha1JlcGxhY2VtZW50J10+KGV4dGVuc2lvbiwgJ2xpbmVicmVha1JlcGxhY2VtZW50JywgY29udGV4dCkpLFxuICAgICAgICBkZWZpbmluZzogY2FsbE9yUmV0dXJuKFxuICAgICAgICAgIGdldEV4dGVuc2lvbkZpZWxkPE5vZGVDb25maWdbJ2RlZmluaW5nJ10+KGV4dGVuc2lvbiwgJ2RlZmluaW5nJywgY29udGV4dCksXG4gICAgICAgICksXG4gICAgICAgIGlzb2xhdGluZzogY2FsbE9yUmV0dXJuKFxuICAgICAgICAgIGdldEV4dGVuc2lvbkZpZWxkPE5vZGVDb25maWdbJ2lzb2xhdGluZyddPihleHRlbnNpb24sICdpc29sYXRpbmcnLCBjb250ZXh0KSxcbiAgICAgICAgKSxcbiAgICAgICAgYXR0cnM6IE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgICAgICBleHRlbnNpb25BdHRyaWJ1dGVzLm1hcChleHRlbnNpb25BdHRyaWJ1dGUgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIFtleHRlbnNpb25BdHRyaWJ1dGUubmFtZSwgeyBkZWZhdWx0OiBleHRlbnNpb25BdHRyaWJ1dGU/LmF0dHJpYnV0ZT8uZGVmYXVsdCB9XVxuICAgICAgICAgIH0pLFxuICAgICAgICApLFxuICAgICAgfSlcblxuICAgICAgY29uc3QgcGFyc2VIVE1MID0gY2FsbE9yUmV0dXJuKFxuICAgICAgICBnZXRFeHRlbnNpb25GaWVsZDxOb2RlQ29uZmlnWydwYXJzZUhUTUwnXT4oZXh0ZW5zaW9uLCAncGFyc2VIVE1MJywgY29udGV4dCksXG4gICAgICApXG5cbiAgICAgIGlmIChwYXJzZUhUTUwpIHtcbiAgICAgICAgc2NoZW1hLnBhcnNlRE9NID0gcGFyc2VIVE1MLm1hcChwYXJzZVJ1bGUgPT4gaW5qZWN0RXh0ZW5zaW9uQXR0cmlidXRlc1RvUGFyc2VSdWxlKHBhcnNlUnVsZSwgZXh0ZW5zaW9uQXR0cmlidXRlcykpIGFzIFRhZ1BhcnNlUnVsZVtdXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlbmRlckhUTUwgPSBnZXRFeHRlbnNpb25GaWVsZDxOb2RlQ29uZmlnWydyZW5kZXJIVE1MJ10+KFxuICAgICAgICBleHRlbnNpb24sXG4gICAgICAgICdyZW5kZXJIVE1MJyxcbiAgICAgICAgY29udGV4dCxcbiAgICAgIClcblxuICAgICAgaWYgKHJlbmRlckhUTUwpIHtcbiAgICAgICAgc2NoZW1hLnRvRE9NID0gbm9kZSA9PiByZW5kZXJIVE1MKHtcbiAgICAgICAgICBub2RlLFxuICAgICAgICAgIEhUTUxBdHRyaWJ1dGVzOiBnZXRSZW5kZXJlZEF0dHJpYnV0ZXMobm9kZSwgZXh0ZW5zaW9uQXR0cmlidXRlcyksXG4gICAgICAgIH0pXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlbmRlclRleHQgPSBnZXRFeHRlbnNpb25GaWVsZDxOb2RlQ29uZmlnWydyZW5kZXJUZXh0J10+KFxuICAgICAgICBleHRlbnNpb24sXG4gICAgICAgICdyZW5kZXJUZXh0JyxcbiAgICAgICAgY29udGV4dCxcbiAgICAgIClcblxuICAgICAgaWYgKHJlbmRlclRleHQpIHtcbiAgICAgICAgc2NoZW1hLnRvVGV4dCA9IHJlbmRlclRleHRcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIFtleHRlbnNpb24ubmFtZSwgc2NoZW1hXVxuICAgIH0pLFxuICApXG5cbiAgY29uc3QgbWFya3MgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgbWFya0V4dGVuc2lvbnMubWFwKGV4dGVuc2lvbiA9PiB7XG4gICAgICBjb25zdCBleHRlbnNpb25BdHRyaWJ1dGVzID0gYWxsQXR0cmlidXRlcy5maWx0ZXIoXG4gICAgICAgIGF0dHJpYnV0ZSA9PiBhdHRyaWJ1dGUudHlwZSA9PT0gZXh0ZW5zaW9uLm5hbWUsXG4gICAgICApXG4gICAgICBjb25zdCBjb250ZXh0ID0ge1xuICAgICAgICBuYW1lOiBleHRlbnNpb24ubmFtZSxcbiAgICAgICAgb3B0aW9uczogZXh0ZW5zaW9uLm9wdGlvbnMsXG4gICAgICAgIHN0b3JhZ2U6IGV4dGVuc2lvbi5zdG9yYWdlLFxuICAgICAgICBlZGl0b3IsXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGV4dHJhTWFya0ZpZWxkcyA9IGV4dGVuc2lvbnMucmVkdWNlKChmaWVsZHMsIGUpID0+IHtcbiAgICAgICAgY29uc3QgZXh0ZW5kTWFya1NjaGVtYSA9IGdldEV4dGVuc2lvbkZpZWxkPEFueUNvbmZpZ1snZXh0ZW5kTWFya1NjaGVtYSddPihcbiAgICAgICAgICBlLFxuICAgICAgICAgICdleHRlbmRNYXJrU2NoZW1hJyxcbiAgICAgICAgICBjb250ZXh0LFxuICAgICAgICApXG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAuLi5maWVsZHMsXG4gICAgICAgICAgLi4uKGV4dGVuZE1hcmtTY2hlbWEgPyBleHRlbmRNYXJrU2NoZW1hKGV4dGVuc2lvbiBhcyBhbnkpIDoge30pLFxuICAgICAgICB9XG4gICAgICB9LCB7fSlcblxuICAgICAgY29uc3Qgc2NoZW1hOiBNYXJrU3BlYyA9IGNsZWFuVXBTY2hlbWFJdGVtKHtcbiAgICAgICAgLi4uZXh0cmFNYXJrRmllbGRzLFxuICAgICAgICBpbmNsdXNpdmU6IGNhbGxPclJldHVybihcbiAgICAgICAgICBnZXRFeHRlbnNpb25GaWVsZDxNYXJrQ29uZmlnWydpbmNsdXNpdmUnXT4oZXh0ZW5zaW9uLCAnaW5jbHVzaXZlJywgY29udGV4dCksXG4gICAgICAgICksXG4gICAgICAgIGV4Y2x1ZGVzOiBjYWxsT3JSZXR1cm4oXG4gICAgICAgICAgZ2V0RXh0ZW5zaW9uRmllbGQ8TWFya0NvbmZpZ1snZXhjbHVkZXMnXT4oZXh0ZW5zaW9uLCAnZXhjbHVkZXMnLCBjb250ZXh0KSxcbiAgICAgICAgKSxcbiAgICAgICAgZ3JvdXA6IGNhbGxPclJldHVybihnZXRFeHRlbnNpb25GaWVsZDxNYXJrQ29uZmlnWydncm91cCddPihleHRlbnNpb24sICdncm91cCcsIGNvbnRleHQpKSxcbiAgICAgICAgc3Bhbm5pbmc6IGNhbGxPclJldHVybihcbiAgICAgICAgICBnZXRFeHRlbnNpb25GaWVsZDxNYXJrQ29uZmlnWydzcGFubmluZyddPihleHRlbnNpb24sICdzcGFubmluZycsIGNvbnRleHQpLFxuICAgICAgICApLFxuICAgICAgICBjb2RlOiBjYWxsT3JSZXR1cm4oZ2V0RXh0ZW5zaW9uRmllbGQ8TWFya0NvbmZpZ1snY29kZSddPihleHRlbnNpb24sICdjb2RlJywgY29udGV4dCkpLFxuICAgICAgICBhdHRyczogT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICAgIGV4dGVuc2lvbkF0dHJpYnV0ZXMubWFwKGV4dGVuc2lvbkF0dHJpYnV0ZSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gW2V4dGVuc2lvbkF0dHJpYnV0ZS5uYW1lLCB7IGRlZmF1bHQ6IGV4dGVuc2lvbkF0dHJpYnV0ZT8uYXR0cmlidXRlPy5kZWZhdWx0IH1dXG4gICAgICAgICAgfSksXG4gICAgICAgICksXG4gICAgICB9KVxuXG4gICAgICBjb25zdCBwYXJzZUhUTUwgPSBjYWxsT3JSZXR1cm4oXG4gICAgICAgIGdldEV4dGVuc2lvbkZpZWxkPE1hcmtDb25maWdbJ3BhcnNlSFRNTCddPihleHRlbnNpb24sICdwYXJzZUhUTUwnLCBjb250ZXh0KSxcbiAgICAgIClcblxuICAgICAgaWYgKHBhcnNlSFRNTCkge1xuICAgICAgICBzY2hlbWEucGFyc2VET00gPSBwYXJzZUhUTUwubWFwKHBhcnNlUnVsZSA9PiBpbmplY3RFeHRlbnNpb25BdHRyaWJ1dGVzVG9QYXJzZVJ1bGUocGFyc2VSdWxlLCBleHRlbnNpb25BdHRyaWJ1dGVzKSlcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVuZGVySFRNTCA9IGdldEV4dGVuc2lvbkZpZWxkPE1hcmtDb25maWdbJ3JlbmRlckhUTUwnXT4oXG4gICAgICAgIGV4dGVuc2lvbixcbiAgICAgICAgJ3JlbmRlckhUTUwnLFxuICAgICAgICBjb250ZXh0LFxuICAgICAgKVxuXG4gICAgICBpZiAocmVuZGVySFRNTCkge1xuICAgICAgICBzY2hlbWEudG9ET00gPSBtYXJrID0+IHJlbmRlckhUTUwoe1xuICAgICAgICAgIG1hcmssXG4gICAgICAgICAgSFRNTEF0dHJpYnV0ZXM6IGdldFJlbmRlcmVkQXR0cmlidXRlcyhtYXJrLCBleHRlbnNpb25BdHRyaWJ1dGVzKSxcbiAgICAgICAgfSlcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIFtleHRlbnNpb24ubmFtZSwgc2NoZW1hXVxuICAgIH0pLFxuICApXG5cbiAgcmV0dXJuIG5ldyBTY2hlbWEoe1xuICAgIHRvcE5vZGUsXG4gICAgbm9kZXMsXG4gICAgbWFya3MsXG4gIH0pXG59XG4iLCAiaW1wb3J0IHsgTWFya1R5cGUsIE5vZGVUeXBlLCBTY2hlbWEgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG4vKipcbiAqIFRyaWVzIHRvIGdldCBhIG5vZGUgb3IgbWFyayB0eXBlIGJ5IGl0cyBuYW1lLlxuICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIG5vZGUgb3IgbWFyayB0eXBlXG4gKiBAcGFyYW0gc2NoZW1hIFRoZSBQcm9zZW1pcm9yIHNjaGVtYSB0byBzZWFyY2ggaW5cbiAqIEByZXR1cm5zIFRoZSBub2RlIG9yIG1hcmsgdHlwZSwgb3IgbnVsbCBpZiBpdCBkb2Vzbid0IGV4aXN0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRTY2hlbWFUeXBlQnlOYW1lKG5hbWU6IHN0cmluZywgc2NoZW1hOiBTY2hlbWEpOiBOb2RlVHlwZSB8IE1hcmtUeXBlIHwgbnVsbCB7XG4gIHJldHVybiBzY2hlbWEubm9kZXNbbmFtZV0gfHwgc2NoZW1hLm1hcmtzW25hbWVdIHx8IG51bGxcbn1cbiIsICJpbXBvcnQgeyBBbnlFeHRlbnNpb24sIEVuYWJsZVJ1bGVzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmV4cG9ydCBmdW5jdGlvbiBpc0V4dGVuc2lvblJ1bGVzRW5hYmxlZChleHRlbnNpb246IEFueUV4dGVuc2lvbiwgZW5hYmxlZDogRW5hYmxlUnVsZXMpOiBib29sZWFuIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkoZW5hYmxlZCkpIHtcbiAgICByZXR1cm4gZW5hYmxlZC5zb21lKGVuYWJsZWRFeHRlbnNpb24gPT4ge1xuICAgICAgY29uc3QgbmFtZSA9IHR5cGVvZiBlbmFibGVkRXh0ZW5zaW9uID09PSAnc3RyaW5nJ1xuICAgICAgICA/IGVuYWJsZWRFeHRlbnNpb25cbiAgICAgICAgOiBlbmFibGVkRXh0ZW5zaW9uLm5hbWVcblxuICAgICAgcmV0dXJuIG5hbWUgPT09IGV4dGVuc2lvbi5uYW1lXG4gICAgfSlcbiAgfVxuXG4gIHJldHVybiBlbmFibGVkXG59XG4iLCAiaW1wb3J0IHsgRE9NU2VyaWFsaXplciwgRnJhZ21lbnQsIFNjaGVtYSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRIVE1MRnJvbUZyYWdtZW50KGZyYWdtZW50OiBGcmFnbWVudCwgc2NoZW1hOiBTY2hlbWEpOiBzdHJpbmcge1xuICBjb25zdCBkb2N1bWVudEZyYWdtZW50ID0gRE9NU2VyaWFsaXplci5mcm9tU2NoZW1hKHNjaGVtYSkuc2VyaWFsaXplRnJhZ21lbnQoZnJhZ21lbnQpXG5cbiAgY29uc3QgdGVtcG9yYXJ5RG9jdW1lbnQgPSBkb2N1bWVudC5pbXBsZW1lbnRhdGlvbi5jcmVhdGVIVE1MRG9jdW1lbnQoKVxuICBjb25zdCBjb250YWluZXIgPSB0ZW1wb3JhcnlEb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKVxuXG4gIGNvbnRhaW5lci5hcHBlbmRDaGlsZChkb2N1bWVudEZyYWdtZW50KVxuXG4gIHJldHVybiBjb250YWluZXIuaW5uZXJIVE1MXG59XG4iLCAiaW1wb3J0IHsgUmVzb2x2ZWRQb3MgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG4vKipcbiAqIFJldHVybnMgdGhlIHRleHQgY29udGVudCBvZiBhIHJlc29sdmVkIHByb3NlbWlycm9yIHBvc2l0aW9uXG4gKiBAcGFyYW0gJGZyb20gVGhlIHJlc29sdmVkIHBvc2l0aW9uIHRvIGdldCB0aGUgdGV4dCBjb250ZW50IGZyb21cbiAqIEBwYXJhbSBtYXhNYXRjaCBUaGUgbWF4aW11bSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byBtYXRjaFxuICogQHJldHVybnMgVGhlIHRleHQgY29udGVudFxuICovXG5leHBvcnQgY29uc3QgZ2V0VGV4dENvbnRlbnRGcm9tTm9kZXMgPSAoJGZyb206IFJlc29sdmVkUG9zLCBtYXhNYXRjaCA9IDUwMCkgPT4ge1xuICBsZXQgdGV4dEJlZm9yZSA9ICcnXG5cbiAgY29uc3Qgc2xpY2VFbmRQb3MgPSAkZnJvbS5wYXJlbnRPZmZzZXRcblxuICAkZnJvbS5wYXJlbnQubm9kZXNCZXR3ZWVuKFxuICAgIE1hdGgubWF4KDAsIHNsaWNlRW5kUG9zIC0gbWF4TWF0Y2gpLFxuICAgIHNsaWNlRW5kUG9zLFxuICAgIChub2RlLCBwb3MsIHBhcmVudCwgaW5kZXgpID0+IHtcbiAgICAgIGNvbnN0IGNodW5rID0gbm9kZS50eXBlLnNwZWMudG9UZXh0Py4oe1xuICAgICAgICBub2RlLFxuICAgICAgICBwb3MsXG4gICAgICAgIHBhcmVudCxcbiAgICAgICAgaW5kZXgsXG4gICAgICB9KVxuICAgICAgICB8fCBub2RlLnRleHRDb250ZW50XG4gICAgICAgIHx8ICclbGVhZiUnXG5cbiAgICAgIHRleHRCZWZvcmUgKz0gbm9kZS5pc0F0b20gJiYgIW5vZGUuaXNUZXh0ID8gY2h1bmsgOiBjaHVuay5zbGljZSgwLCBNYXRoLm1heCgwLCBzbGljZUVuZFBvcyAtIHBvcykpXG4gICAgfSxcbiAgKVxuXG4gIHJldHVybiB0ZXh0QmVmb3JlXG59XG4iLCAiZXhwb3J0IGZ1bmN0aW9uIGlzUmVnRXhwKHZhbHVlOiBhbnkpOiB2YWx1ZSBpcyBSZWdFeHAge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSA9PT0gJ1tvYmplY3QgUmVnRXhwXSdcbn1cbiIsICJpbXBvcnQgeyBGcmFnbWVudCwgTm9kZSBhcyBQcm9zZU1pcnJvck5vZGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuaW1wb3J0IHsgRWRpdG9yU3RhdGUsIFBsdWdpbiwgVGV4dFNlbGVjdGlvbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmltcG9ydCB7IENvbW1hbmRNYW5hZ2VyIH0gZnJvbSAnLi9Db21tYW5kTWFuYWdlci5qcydcbmltcG9ydCB7IEVkaXRvciB9IGZyb20gJy4vRWRpdG9yLmpzJ1xuaW1wb3J0IHsgY3JlYXRlQ2hhaW5hYmxlU3RhdGUgfSBmcm9tICcuL2hlbHBlcnMvY3JlYXRlQ2hhaW5hYmxlU3RhdGUuanMnXG5pbXBvcnQgeyBnZXRIVE1MRnJvbUZyYWdtZW50IH0gZnJvbSAnLi9oZWxwZXJzL2dldEhUTUxGcm9tRnJhZ21lbnQuanMnXG5pbXBvcnQgeyBnZXRUZXh0Q29udGVudEZyb21Ob2RlcyB9IGZyb20gJy4vaGVscGVycy9nZXRUZXh0Q29udGVudEZyb21Ob2Rlcy5qcydcbmltcG9ydCB7XG4gIENhbkNvbW1hbmRzLFxuICBDaGFpbmVkQ29tbWFuZHMsXG4gIEV4dGVuZGVkUmVnRXhwTWF0Y2hBcnJheSxcbiAgUmFuZ2UsXG4gIFNpbmdsZUNvbW1hbmRzLFxufSBmcm9tICcuL3R5cGVzLmpzJ1xuaW1wb3J0IHsgaXNSZWdFeHAgfSBmcm9tICcuL3V0aWxpdGllcy9pc1JlZ0V4cC5qcydcblxuZXhwb3J0IHR5cGUgSW5wdXRSdWxlTWF0Y2ggPSB7XG4gIGluZGV4OiBudW1iZXI7XG4gIHRleHQ6IHN0cmluZztcbiAgcmVwbGFjZVdpdGg/OiBzdHJpbmc7XG4gIG1hdGNoPzogUmVnRXhwTWF0Y2hBcnJheTtcbiAgZGF0YT86IFJlY29yZDxzdHJpbmcsIGFueT47XG59O1xuXG5leHBvcnQgdHlwZSBJbnB1dFJ1bGVGaW5kZXIgPSBSZWdFeHAgfCAoKHRleHQ6IHN0cmluZykgPT4gSW5wdXRSdWxlTWF0Y2ggfCBudWxsKTtcblxuZXhwb3J0IGNsYXNzIElucHV0UnVsZSB7XG4gIGZpbmQ6IElucHV0UnVsZUZpbmRlclxuXG4gIGhhbmRsZXI6IChwcm9wczoge1xuICAgIHN0YXRlOiBFZGl0b3JTdGF0ZTtcbiAgICByYW5nZTogUmFuZ2U7XG4gICAgbWF0Y2g6IEV4dGVuZGVkUmVnRXhwTWF0Y2hBcnJheTtcbiAgICBjb21tYW5kczogU2luZ2xlQ29tbWFuZHM7XG4gICAgY2hhaW46ICgpID0+IENoYWluZWRDb21tYW5kcztcbiAgICBjYW46ICgpID0+IENhbkNvbW1hbmRzO1xuICB9KSA9PiB2b2lkIHwgbnVsbFxuXG4gIGNvbnN0cnVjdG9yKGNvbmZpZzoge1xuICAgIGZpbmQ6IElucHV0UnVsZUZpbmRlcjtcbiAgICBoYW5kbGVyOiAocHJvcHM6IHtcbiAgICAgIHN0YXRlOiBFZGl0b3JTdGF0ZTtcbiAgICAgIHJhbmdlOiBSYW5nZTtcbiAgICAgIG1hdGNoOiBFeHRlbmRlZFJlZ0V4cE1hdGNoQXJyYXk7XG4gICAgICBjb21tYW5kczogU2luZ2xlQ29tbWFuZHM7XG4gICAgICBjaGFpbjogKCkgPT4gQ2hhaW5lZENvbW1hbmRzO1xuICAgICAgY2FuOiAoKSA9PiBDYW5Db21tYW5kcztcbiAgICB9KSA9PiB2b2lkIHwgbnVsbDtcbiAgfSkge1xuICAgIHRoaXMuZmluZCA9IGNvbmZpZy5maW5kXG4gICAgdGhpcy5oYW5kbGVyID0gY29uZmlnLmhhbmRsZXJcbiAgfVxufVxuXG5jb25zdCBpbnB1dFJ1bGVNYXRjaGVySGFuZGxlciA9IChcbiAgdGV4dDogc3RyaW5nLFxuICBmaW5kOiBJbnB1dFJ1bGVGaW5kZXIsXG4pOiBFeHRlbmRlZFJlZ0V4cE1hdGNoQXJyYXkgfCBudWxsID0+IHtcbiAgaWYgKGlzUmVnRXhwKGZpbmQpKSB7XG4gICAgcmV0dXJuIGZpbmQuZXhlYyh0ZXh0KVxuICB9XG5cbiAgY29uc3QgaW5wdXRSdWxlTWF0Y2ggPSBmaW5kKHRleHQpXG5cbiAgaWYgKCFpbnB1dFJ1bGVNYXRjaCkge1xuICAgIHJldHVybiBudWxsXG4gIH1cblxuICBjb25zdCByZXN1bHQ6IEV4dGVuZGVkUmVnRXhwTWF0Y2hBcnJheSA9IFtpbnB1dFJ1bGVNYXRjaC50ZXh0XVxuXG4gIHJlc3VsdC5pbmRleCA9IGlucHV0UnVsZU1hdGNoLmluZGV4XG4gIHJlc3VsdC5pbnB1dCA9IHRleHRcbiAgcmVzdWx0LmRhdGEgPSBpbnB1dFJ1bGVNYXRjaC5kYXRhXG5cbiAgaWYgKGlucHV0UnVsZU1hdGNoLnJlcGxhY2VXaXRoKSB7XG4gICAgaWYgKCFpbnB1dFJ1bGVNYXRjaC50ZXh0LmluY2x1ZGVzKGlucHV0UnVsZU1hdGNoLnJlcGxhY2VXaXRoKSkge1xuICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAnW3RpcHRhcCB3YXJuXTogXCJpbnB1dFJ1bGVNYXRjaC5yZXBsYWNlV2l0aFwiIG11c3QgYmUgcGFydCBvZiBcImlucHV0UnVsZU1hdGNoLnRleHRcIi4nLFxuICAgICAgKVxuICAgIH1cblxuICAgIHJlc3VsdC5wdXNoKGlucHV0UnVsZU1hdGNoLnJlcGxhY2VXaXRoKVxuICB9XG5cbiAgcmV0dXJuIHJlc3VsdFxufVxuXG5mdW5jdGlvbiBydW4oY29uZmlnOiB7XG4gIGVkaXRvcjogRWRpdG9yO1xuICBmcm9tOiBudW1iZXI7XG4gIHRvOiBudW1iZXI7XG4gIHRleHQ6IHN0cmluZztcbiAgcnVsZXM6IElucHV0UnVsZVtdO1xuICBwbHVnaW46IFBsdWdpbjtcbn0pOiBib29sZWFuIHtcbiAgY29uc3Qge1xuICAgIGVkaXRvciwgZnJvbSwgdG8sIHRleHQsIHJ1bGVzLCBwbHVnaW4sXG4gIH0gPSBjb25maWdcbiAgY29uc3QgeyB2aWV3IH0gPSBlZGl0b3JcblxuICBpZiAodmlldy5jb21wb3NpbmcpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIGNvbnN0ICRmcm9tID0gdmlldy5zdGF0ZS5kb2MucmVzb2x2ZShmcm9tKVxuXG4gIGlmIChcbiAgICAvLyBjaGVjayBmb3IgY29kZSBub2RlXG4gICAgJGZyb20ucGFyZW50LnR5cGUuc3BlYy5jb2RlXG4gICAgLy8gY2hlY2sgZm9yIGNvZGUgbWFya1xuICAgIHx8ICEhKCRmcm9tLm5vZGVCZWZvcmUgfHwgJGZyb20ubm9kZUFmdGVyKT8ubWFya3MuZmluZChtYXJrID0+IG1hcmsudHlwZS5zcGVjLmNvZGUpXG4gICkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgbGV0IG1hdGNoZWQgPSBmYWxzZVxuXG4gIGNvbnN0IHRleHRCZWZvcmUgPSBnZXRUZXh0Q29udGVudEZyb21Ob2RlcygkZnJvbSkgKyB0ZXh0XG5cbiAgcnVsZXMuZm9yRWFjaChydWxlID0+IHtcbiAgICBpZiAobWF0Y2hlZCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3QgbWF0Y2ggPSBpbnB1dFJ1bGVNYXRjaGVySGFuZGxlcih0ZXh0QmVmb3JlLCBydWxlLmZpbmQpXG5cbiAgICBpZiAoIW1hdGNoKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCB0ciA9IHZpZXcuc3RhdGUudHJcbiAgICBjb25zdCBzdGF0ZSA9IGNyZWF0ZUNoYWluYWJsZVN0YXRlKHtcbiAgICAgIHN0YXRlOiB2aWV3LnN0YXRlLFxuICAgICAgdHJhbnNhY3Rpb246IHRyLFxuICAgIH0pXG4gICAgY29uc3QgcmFuZ2UgPSB7XG4gICAgICBmcm9tOiBmcm9tIC0gKG1hdGNoWzBdLmxlbmd0aCAtIHRleHQubGVuZ3RoKSxcbiAgICAgIHRvLFxuICAgIH1cblxuICAgIGNvbnN0IHsgY29tbWFuZHMsIGNoYWluLCBjYW4gfSA9IG5ldyBDb21tYW5kTWFuYWdlcih7XG4gICAgICBlZGl0b3IsXG4gICAgICBzdGF0ZSxcbiAgICB9KVxuXG4gICAgY29uc3QgaGFuZGxlciA9IHJ1bGUuaGFuZGxlcih7XG4gICAgICBzdGF0ZSxcbiAgICAgIHJhbmdlLFxuICAgICAgbWF0Y2gsXG4gICAgICBjb21tYW5kcyxcbiAgICAgIGNoYWluLFxuICAgICAgY2FuLFxuICAgIH0pXG5cbiAgICAvLyBzdG9wIGlmIHRoZXJlIGFyZSBubyBjaGFuZ2VzXG4gICAgaWYgKGhhbmRsZXIgPT09IG51bGwgfHwgIXRyLnN0ZXBzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gc3RvcmUgdHJhbnNmb3JtIGFzIG1ldGEgZGF0YVxuICAgIC8vIHNvIHdlIGNhbiB1bmRvIGlucHV0IHJ1bGVzIHdpdGhpbiB0aGUgYHVuZG9JbnB1dFJ1bGVzYCBjb21tYW5kXG4gICAgdHIuc2V0TWV0YShwbHVnaW4sIHtcbiAgICAgIHRyYW5zZm9ybTogdHIsXG4gICAgICBmcm9tLFxuICAgICAgdG8sXG4gICAgICB0ZXh0LFxuICAgIH0pXG5cbiAgICB2aWV3LmRpc3BhdGNoKHRyKVxuICAgIG1hdGNoZWQgPSB0cnVlXG4gIH0pXG5cbiAgcmV0dXJuIG1hdGNoZWRcbn1cblxuLyoqXG4gKiBDcmVhdGUgYW4gaW5wdXQgcnVsZXMgcGx1Z2luLiBXaGVuIGVuYWJsZWQsIGl0IHdpbGwgY2F1c2UgdGV4dFxuICogaW5wdXQgdGhhdCBtYXRjaGVzIGFueSBvZiB0aGUgZ2l2ZW4gcnVsZXMgdG8gdHJpZ2dlciB0aGUgcnVsZeKAmXNcbiAqIGFjdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlucHV0UnVsZXNQbHVnaW4ocHJvcHM6IHsgZWRpdG9yOiBFZGl0b3I7IHJ1bGVzOiBJbnB1dFJ1bGVbXSB9KTogUGx1Z2luIHtcbiAgY29uc3QgeyBlZGl0b3IsIHJ1bGVzIH0gPSBwcm9wc1xuICBjb25zdCBwbHVnaW4gPSBuZXcgUGx1Z2luKHtcbiAgICBzdGF0ZToge1xuICAgICAgaW5pdCgpIHtcbiAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgIH0sXG4gICAgICBhcHBseSh0ciwgcHJldiwgc3RhdGUpIHtcbiAgICAgICAgY29uc3Qgc3RvcmVkID0gdHIuZ2V0TWV0YShwbHVnaW4pXG5cbiAgICAgICAgaWYgKHN0b3JlZCkge1xuICAgICAgICAgIHJldHVybiBzdG9yZWRcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGlmIElucHV0UnVsZSBpcyB0cmlnZ2VyZWQgYnkgaW5zZXJ0Q29udGVudCgpXG4gICAgICAgIGNvbnN0IHNpbXVsYXRlZElucHV0TWV0YSA9IHRyLmdldE1ldGEoJ2FwcGx5SW5wdXRSdWxlcycpIGFzXG4gICAgICAgICAgfCB1bmRlZmluZWRcbiAgICAgICAgICB8IHtcbiAgICAgICAgICAgICAgZnJvbTogbnVtYmVyO1xuICAgICAgICAgICAgICB0ZXh0OiBzdHJpbmcgfCBQcm9zZU1pcnJvck5vZGUgfCBGcmFnbWVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgY29uc3QgaXNTaW11bGF0ZWRJbnB1dCA9ICEhc2ltdWxhdGVkSW5wdXRNZXRhXG5cbiAgICAgICAgaWYgKGlzU2ltdWxhdGVkSW5wdXQpIHtcbiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGxldCB7IHRleHQgfSA9IHNpbXVsYXRlZElucHV0TWV0YVxuXG4gICAgICAgICAgICBpZiAodHlwZW9mIHRleHQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgIHRleHQgPSB0ZXh0IGFzIHN0cmluZ1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGV4dCA9IGdldEhUTUxGcm9tRnJhZ21lbnQoRnJhZ21lbnQuZnJvbSh0ZXh0KSwgc3RhdGUuc2NoZW1hKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCB7IGZyb20gfSA9IHNpbXVsYXRlZElucHV0TWV0YVxuICAgICAgICAgICAgY29uc3QgdG8gPSBmcm9tICsgdGV4dC5sZW5ndGhcblxuICAgICAgICAgICAgcnVuKHtcbiAgICAgICAgICAgICAgZWRpdG9yLFxuICAgICAgICAgICAgICBmcm9tLFxuICAgICAgICAgICAgICB0byxcbiAgICAgICAgICAgICAgdGV4dCxcbiAgICAgICAgICAgICAgcnVsZXMsXG4gICAgICAgICAgICAgIHBsdWdpbixcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0ci5zZWxlY3Rpb25TZXQgfHwgdHIuZG9jQ2hhbmdlZCA/IG51bGwgOiBwcmV2XG4gICAgICB9LFxuICAgIH0sXG5cbiAgICBwcm9wczoge1xuICAgICAgaGFuZGxlVGV4dElucHV0KHZpZXcsIGZyb20sIHRvLCB0ZXh0KSB7XG4gICAgICAgIHJldHVybiBydW4oe1xuICAgICAgICAgIGVkaXRvcixcbiAgICAgICAgICBmcm9tLFxuICAgICAgICAgIHRvLFxuICAgICAgICAgIHRleHQsXG4gICAgICAgICAgcnVsZXMsXG4gICAgICAgICAgcGx1Z2luLFxuICAgICAgICB9KVxuICAgICAgfSxcblxuICAgICAgaGFuZGxlRE9NRXZlbnRzOiB7XG4gICAgICAgIGNvbXBvc2l0aW9uZW5kOiB2aWV3ID0+IHtcbiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgJGN1cnNvciB9ID0gdmlldy5zdGF0ZS5zZWxlY3Rpb24gYXMgVGV4dFNlbGVjdGlvblxuXG4gICAgICAgICAgICBpZiAoJGN1cnNvcikge1xuICAgICAgICAgICAgICBydW4oe1xuICAgICAgICAgICAgICAgIGVkaXRvcixcbiAgICAgICAgICAgICAgICBmcm9tOiAkY3Vyc29yLnBvcyxcbiAgICAgICAgICAgICAgICB0bzogJGN1cnNvci5wb3MsXG4gICAgICAgICAgICAgICAgdGV4dDogJycsXG4gICAgICAgICAgICAgICAgcnVsZXMsXG4gICAgICAgICAgICAgICAgcGx1Z2luLFxuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pXG5cbiAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgfSxcbiAgICAgIH0sXG5cbiAgICAgIC8vIGFkZCBzdXBwb3J0IGZvciBpbnB1dCBydWxlcyB0byB0cmlnZ2VyIG9uIGVudGVyXG4gICAgICAvLyB0aGlzIGlzIHVzZWZ1bCBmb3IgZXhhbXBsZSBmb3IgY29kZSBibG9ja3NcbiAgICAgIGhhbmRsZUtleURvd24odmlldywgZXZlbnQpIHtcbiAgICAgICAgaWYgKGV2ZW50LmtleSAhPT0gJ0VudGVyJykge1xuICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgeyAkY3Vyc29yIH0gPSB2aWV3LnN0YXRlLnNlbGVjdGlvbiBhcyBUZXh0U2VsZWN0aW9uXG5cbiAgICAgICAgaWYgKCRjdXJzb3IpIHtcbiAgICAgICAgICByZXR1cm4gcnVuKHtcbiAgICAgICAgICAgIGVkaXRvcixcbiAgICAgICAgICAgIGZyb206ICRjdXJzb3IucG9zLFxuICAgICAgICAgICAgdG86ICRjdXJzb3IucG9zLFxuICAgICAgICAgICAgdGV4dDogJ1xcbicsXG4gICAgICAgICAgICBydWxlcyxcbiAgICAgICAgICAgIHBsdWdpbixcbiAgICAgICAgICB9KVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9LFxuICAgIH0sXG5cbiAgICAvLyBAdHMtaWdub3JlXG4gICAgaXNJbnB1dFJ1bGVzOiB0cnVlLFxuICB9KSBhcyBQbHVnaW5cblxuICByZXR1cm4gcGx1Z2luXG59XG4iLCAiLy8gc2VlOiBodHRwczovL2dpdGh1Yi5jb20vbWVzcXVlZWIvaXMtd2hhdC9ibG9iLzg4ZDZlNGNhOTJmYjJiYWFiNjAwM2M1NGUwMmVlZGY0ZTcyOWU1YWIvc3JjL2luZGV4LnRzXG5cbmZ1bmN0aW9uIGdldFR5cGUodmFsdWU6IGFueSk6IHN0cmluZyB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLnNsaWNlKDgsIC0xKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNQbGFpbk9iamVjdCh2YWx1ZTogYW55KTogdmFsdWUgaXMgUmVjb3JkPHN0cmluZywgYW55PiB7XG4gIGlmIChnZXRUeXBlKHZhbHVlKSAhPT0gJ09iamVjdCcpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIHJldHVybiB2YWx1ZS5jb25zdHJ1Y3RvciA9PT0gT2JqZWN0ICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZih2YWx1ZSkgPT09IE9iamVjdC5wcm90b3R5cGVcbn1cbiIsICJpbXBvcnQgeyBpc1BsYWluT2JqZWN0IH0gZnJvbSAnLi9pc1BsYWluT2JqZWN0LmpzJ1xuXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VEZWVwKHRhcmdldDogUmVjb3JkPHN0cmluZywgYW55Piwgc291cmNlOiBSZWNvcmQ8c3RyaW5nLCBhbnk+KTogUmVjb3JkPHN0cmluZywgYW55PiB7XG4gIGNvbnN0IG91dHB1dCA9IHsgLi4udGFyZ2V0IH1cblxuICBpZiAoaXNQbGFpbk9iamVjdCh0YXJnZXQpICYmIGlzUGxhaW5PYmplY3Qoc291cmNlKSkge1xuICAgIE9iamVjdC5rZXlzKHNvdXJjZSkuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgaWYgKGlzUGxhaW5PYmplY3Qoc291cmNlW2tleV0pICYmIGlzUGxhaW5PYmplY3QodGFyZ2V0W2tleV0pKSB7XG4gICAgICAgIG91dHB1dFtrZXldID0gbWVyZ2VEZWVwKHRhcmdldFtrZXldLCBzb3VyY2Vba2V5XSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG91dHB1dFtrZXldID0gc291cmNlW2tleV1cbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgcmV0dXJuIG91dHB1dFxufVxuIiwgImltcG9ydCB7XG4gIERPTU91dHB1dFNwZWMsIE1hcmsgYXMgUHJvc2VNaXJyb3JNYXJrLCBNYXJrU3BlYywgTWFya1R5cGUsXG59IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5pbXBvcnQgeyBQbHVnaW4sIFRyYW5zYWN0aW9uIH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcblxuaW1wb3J0IHsgRWRpdG9yIH0gZnJvbSAnLi9FZGl0b3IuanMnXG5pbXBvcnQgeyBnZXRFeHRlbnNpb25GaWVsZCB9IGZyb20gJy4vaGVscGVycy9nZXRFeHRlbnNpb25GaWVsZC5qcydcbmltcG9ydCB7IE1hcmtDb25maWcgfSBmcm9tICcuL2luZGV4LmpzJ1xuaW1wb3J0IHsgSW5wdXRSdWxlIH0gZnJvbSAnLi9JbnB1dFJ1bGUuanMnXG5pbXBvcnQgeyBOb2RlIH0gZnJvbSAnLi9Ob2RlLmpzJ1xuaW1wb3J0IHsgUGFzdGVSdWxlIH0gZnJvbSAnLi9QYXN0ZVJ1bGUuanMnXG5pbXBvcnQge1xuICBBbnlDb25maWcsXG4gIEF0dHJpYnV0ZXMsXG4gIEV4dGVuc2lvbnMsXG4gIEdsb2JhbEF0dHJpYnV0ZXMsXG4gIEtleWJvYXJkU2hvcnRjdXRDb21tYW5kLFxuICBQYXJlbnRDb25maWcsXG4gIFJhd0NvbW1hbmRzLFxufSBmcm9tICcuL3R5cGVzLmpzJ1xuaW1wb3J0IHsgY2FsbE9yUmV0dXJuIH0gZnJvbSAnLi91dGlsaXRpZXMvY2FsbE9yUmV0dXJuLmpzJ1xuaW1wb3J0IHsgbWVyZ2VEZWVwIH0gZnJvbSAnLi91dGlsaXRpZXMvbWVyZ2VEZWVwLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGV4cG9ydCBpbnRlcmZhY2UgTWFya0NvbmZpZzxPcHRpb25zID0gYW55LCBTdG9yYWdlID0gYW55PiB7XG4gICAgLy8gQHRzLWlnbm9yZSAtIHRoaXMgaXMgYSBkeW5hbWljIGtleVxuICAgIFtrZXk6IHN0cmluZ106IGFueVxuXG4gICAgLyoqXG4gICAgICogVGhlIGV4dGVuc2lvbiBuYW1lIC0gdGhpcyBtdXN0IGJlIHVuaXF1ZS5cbiAgICAgKiBJdCB3aWxsIGJlIHVzZWQgdG8gaWRlbnRpZnkgdGhlIGV4dGVuc2lvbi5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlICdteUV4dGVuc2lvbidcbiAgICAgKi9cbiAgICBuYW1lOiBzdHJpbmdcblxuICAgIC8qKlxuICAgICAqIFRoZSBwcmlvcml0eSBvZiB5b3VyIGV4dGVuc2lvbi4gVGhlIGhpZ2hlciwgdGhlIGVhcmxpZXIgaXQgd2lsbCBiZSBjYWxsZWRcbiAgICAgKiBhbmQgd2lsbCB0YWtlIHByZWNlZGVuY2Ugb3ZlciBvdGhlciBleHRlbnNpb25zIHdpdGggYSBsb3dlciBwcmlvcml0eS5cbiAgICAgKiBAZGVmYXVsdCAxMDBcbiAgICAgKiBAZXhhbXBsZSAxMDFcbiAgICAgKi9cbiAgICBwcmlvcml0eT86IG51bWJlclxuXG4gICAgLyoqXG4gICAgICogVGhlIGRlZmF1bHQgb3B0aW9ucyBmb3IgdGhpcyBleHRlbnNpb24uXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBkZWZhdWx0T3B0aW9uczoge1xuICAgICAqICAgbXlPcHRpb246ICdmb28nLFxuICAgICAqICAgbXlPdGhlck9wdGlvbjogMTAsXG4gICAgICogfVxuICAgICAqL1xuICAgIGRlZmF1bHRPcHRpb25zPzogT3B0aW9uc1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2Qgd2lsbCBhZGQgb3B0aW9ucyB0byB0aGlzIGV4dGVuc2lvblxuICAgICAqIEBzZWUgaHR0cHM6Ly90aXB0YXAuZGV2L2d1aWRlL2N1c3RvbS1leHRlbnNpb25zI3NldHRpbmdzXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBhZGRPcHRpb25zKCkge1xuICAgICAqICByZXR1cm4ge1xuICAgICAqICAgIG15T3B0aW9uOiAnZm9vJyxcbiAgICAgKiAgICBteU90aGVyT3B0aW9uOiAxMCxcbiAgICAgKiB9XG4gICAgICovXG4gICAgYWRkT3B0aW9ucz86ICh0aGlzOiB7XG4gICAgICBuYW1lOiBzdHJpbmdcbiAgICAgIHBhcmVudDogRXhjbHVkZTxQYXJlbnRDb25maWc8TWFya0NvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ2FkZE9wdGlvbnMnXSwgdW5kZWZpbmVkPlxuICAgIH0pID0+IE9wdGlvbnNcblxuICAgIC8qKlxuICAgICAqIFRoZSBkZWZhdWx0IHN0b3JhZ2UgdGhpcyBleHRlbnNpb24gY2FuIHNhdmUgZGF0YSB0by5cbiAgICAgKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9ndWlkZS9jdXN0b20tZXh0ZW5zaW9ucyNzdG9yYWdlXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBkZWZhdWx0U3RvcmFnZToge1xuICAgICAqICAgcHJlZmV0Y2hlZFVzZXJzOiBbXSxcbiAgICAgKiAgIGxvYWRpbmc6IGZhbHNlLFxuICAgICAqIH1cbiAgICAgKi9cbiAgICBhZGRTdG9yYWdlPzogKHRoaXM6IHtcbiAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgcGFyZW50OiBFeGNsdWRlPFBhcmVudENvbmZpZzxNYXJrQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsnYWRkU3RvcmFnZSddLCB1bmRlZmluZWQ+XG4gICAgfSkgPT4gU3RvcmFnZVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBmdW5jdGlvbiBhZGRzIGdsb2JhbEF0dHJpYnV0ZXMgdG8gc3BlY2lmaWMgbm9kZXMuXG4gICAgICogQHNlZSBodHRwczovL3RpcHRhcC5kZXYvZ3VpZGUvY3VzdG9tLWV4dGVuc2lvbnMjZ2xvYmFsLWF0dHJpYnV0ZXNcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGFkZEdsb2JhbEF0dHJpYnV0ZXMoKSB7XG4gICAgICogICByZXR1cm4gW1xuICAgICAqICAgICB7XG4gICAgICAgICAgICAgLy8gRXh0ZW5kIHRoZSBmb2xsb3dpbmcgZXh0ZW5zaW9uc1xuICAgICAqICAgICAgIHR5cGVzOiBbXG4gICAgICogICAgICAgICAnaGVhZGluZycsXG4gICAgICogICAgICAgICAncGFyYWdyYXBoJyxcbiAgICAgKiAgICAgICBdLFxuICAgICAqICAgICAgIC8vIOKApiB3aXRoIHRob3NlIGF0dHJpYnV0ZXNcbiAgICAgKiAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICogICAgICAgICB0ZXh0QWxpZ246IHtcbiAgICAgKiAgICAgICAgICAgZGVmYXVsdDogJ2xlZnQnLFxuICAgICAqICAgICAgICAgICByZW5kZXJIVE1MOiBhdHRyaWJ1dGVzID0+ICh7XG4gICAgICogICAgICAgICAgICAgc3R5bGU6IGB0ZXh0LWFsaWduOiAke2F0dHJpYnV0ZXMudGV4dEFsaWdufWAsXG4gICAgICogICAgICAgICAgIH0pLFxuICAgICAqICAgICAgICAgICBwYXJzZUhUTUw6IGVsZW1lbnQgPT4gZWxlbWVudC5zdHlsZS50ZXh0QWxpZ24gfHwgJ2xlZnQnLFxuICAgICAqICAgICAgICAgfSxcbiAgICAgKiAgICAgICB9LFxuICAgICAqICAgICB9LFxuICAgICAqICAgXVxuICAgICAqIH1cbiAgICAgKi9cbiAgICBhZGRHbG9iYWxBdHRyaWJ1dGVzPzogKHRoaXM6IHtcbiAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgZXh0ZW5zaW9uczogKE5vZGUgfCBNYXJrKVtdXG4gICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxNYXJrQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsnYWRkR2xvYmFsQXR0cmlidXRlcyddXG4gICAgfSkgPT4gR2xvYmFsQXR0cmlidXRlc1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBmdW5jdGlvbiBhZGRzIGNvbW1hbmRzIHRvIHRoZSBlZGl0b3JcbiAgICAgKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9ndWlkZS9jdXN0b20tZXh0ZW5zaW9ucyNrZXlib2FyZC1zaG9ydGN1dHNcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGFkZENvbW1hbmRzKCkge1xuICAgICAqICAgcmV0dXJuIHtcbiAgICAgKiAgICAgbXlDb21tYW5kOiAoKSA9PiAoeyBjaGFpbiB9KSA9PiBjaGFpbigpLnNldE1hcmsoJ3R5cGUnLCAnZm9vJykucnVuKCksXG4gICAgICogICB9XG4gICAgICogfVxuICAgICAqL1xuICAgIGFkZENvbW1hbmRzPzogKHRoaXM6IHtcbiAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgZWRpdG9yOiBFZGl0b3JcbiAgICAgIHR5cGU6IE1hcmtUeXBlXG4gICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxNYXJrQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsnYWRkQ29tbWFuZHMnXVxuICAgIH0pID0+IFBhcnRpYWw8UmF3Q29tbWFuZHM+XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIHJlZ2lzdGVycyBrZXlib2FyZCBzaG9ydGN1dHMuXG4gICAgICogQHNlZSBodHRwczovL3RpcHRhcC5kZXYvZ3VpZGUvY3VzdG9tLWV4dGVuc2lvbnMja2V5Ym9hcmQtc2hvcnRjdXRzXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBhZGRLZXlib2FyZFNob3J0Y3V0cygpIHtcbiAgICAgKiAgIHJldHVybiB7XG4gICAgICogICAgICdNb2QtbCc6ICgpID0+IHRoaXMuZWRpdG9yLmNvbW1hbmRzLnRvZ2dsZUJ1bGxldExpc3QoKSxcbiAgICAgKiAgIH1cbiAgICAgKiB9LFxuICAgICAqL1xuICAgIGFkZEtleWJvYXJkU2hvcnRjdXRzPzogKHRoaXM6IHtcbiAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgZWRpdG9yOiBFZGl0b3JcbiAgICAgIHR5cGU6IE1hcmtUeXBlXG4gICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxNYXJrQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsnYWRkS2V5Ym9hcmRTaG9ydGN1dHMnXVxuICAgIH0pID0+IHtcbiAgICAgIFtrZXk6IHN0cmluZ106IEtleWJvYXJkU2hvcnRjdXRDb21tYW5kXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBmdW5jdGlvbiBhZGRzIGlucHV0IHJ1bGVzIHRvIHRoZSBlZGl0b3IuXG4gICAgICogQHNlZSBodHRwczovL3RpcHRhcC5kZXYvZ3VpZGUvY3VzdG9tLWV4dGVuc2lvbnMjaW5wdXQtcnVsZXNcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGFkZElucHV0UnVsZXMoKSB7XG4gICAgICogICByZXR1cm4gW1xuICAgICAqICAgICBtYXJrSW5wdXRSdWxlKHtcbiAgICAgKiAgICAgICBmaW5kOiBpbnB1dFJlZ2V4LFxuICAgICAqICAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICAgKiAgICAgfSksXG4gICAgICogICBdXG4gICAgICogfSxcbiAgICAgKi9cbiAgICBhZGRJbnB1dFJ1bGVzPzogKHRoaXM6IHtcbiAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgZWRpdG9yOiBFZGl0b3JcbiAgICAgIHR5cGU6IE1hcmtUeXBlXG4gICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxNYXJrQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsnYWRkSW5wdXRSdWxlcyddXG4gICAgfSkgPT4gSW5wdXRSdWxlW11cblxuICAgIC8qKlxuICAgICAqIFRoaXMgZnVuY3Rpb24gYWRkcyBwYXN0ZSBydWxlcyB0byB0aGUgZWRpdG9yLlxuICAgICAqIEBzZWUgaHR0cHM6Ly90aXB0YXAuZGV2L2d1aWRlL2N1c3RvbS1leHRlbnNpb25zI3Bhc3RlLXJ1bGVzXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBhZGRQYXN0ZVJ1bGVzKCkge1xuICAgICAqICAgcmV0dXJuIFtcbiAgICAgKiAgICAgbWFya1Bhc3RlUnVsZSh7XG4gICAgICogICAgICAgZmluZDogcGFzdGVSZWdleCxcbiAgICAgKiAgICAgICB0eXBlOiB0aGlzLnR5cGUsXG4gICAgICogICAgIH0pLFxuICAgICAqICAgXVxuICAgICAqIH0sXG4gICAgICovXG4gICAgYWRkUGFzdGVSdWxlcz86ICh0aGlzOiB7XG4gICAgICBuYW1lOiBzdHJpbmdcbiAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgIGVkaXRvcjogRWRpdG9yXG4gICAgICB0eXBlOiBNYXJrVHlwZVxuICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8TWFya0NvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ2FkZFBhc3RlUnVsZXMnXVxuICAgIH0pID0+IFBhc3RlUnVsZVtdXG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGFkZHMgUHJvc2VtaXJyb3IgcGx1Z2lucyB0byB0aGUgZWRpdG9yXG4gICAgICogQHNlZSBodHRwczovL3RpcHRhcC5kZXYvZ3VpZGUvY3VzdG9tLWV4dGVuc2lvbnMjcHJvc2VtaXJyb3ItcGx1Z2luc1xuICAgICAqIEBleGFtcGxlXG4gICAgICogYWRkUHJvc2VNaXJyb3JQbHVnaW5zKCkge1xuICAgICAqICAgcmV0dXJuIFtcbiAgICAgKiAgICAgY3VzdG9tUGx1Z2luKCksXG4gICAgICogICBdXG4gICAgICogfVxuICAgICAqL1xuICAgIGFkZFByb3NlTWlycm9yUGx1Z2lucz86ICh0aGlzOiB7XG4gICAgICBuYW1lOiBzdHJpbmdcbiAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgIGVkaXRvcjogRWRpdG9yXG4gICAgICB0eXBlOiBNYXJrVHlwZVxuICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8TWFya0NvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ2FkZFByb3NlTWlycm9yUGx1Z2lucyddXG4gICAgfSkgPT4gUGx1Z2luW11cblxuICAgIC8qKlxuICAgICAqIFRoaXMgZnVuY3Rpb24gYWRkcyBhZGRpdGlvbmFsIGV4dGVuc2lvbnMgdG8gdGhlIGVkaXRvci4gVGhpcyBpcyB1c2VmdWwgZm9yXG4gICAgICogYnVpbGRpbmcgZXh0ZW5zaW9uIGtpdHMuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBhZGRFeHRlbnNpb25zKCkge1xuICAgICAqICAgcmV0dXJuIFtcbiAgICAgKiAgICAgQnVsbGV0TGlzdCxcbiAgICAgKiAgICAgT3JkZXJlZExpc3QsXG4gICAgICogICAgIExpc3RJdGVtXG4gICAgICogICBdXG4gICAgICogfVxuICAgICAqL1xuICAgIGFkZEV4dGVuc2lvbnM/OiAodGhpczoge1xuICAgICAgbmFtZTogc3RyaW5nXG4gICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxNYXJrQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsnYWRkRXh0ZW5zaW9ucyddXG4gICAgfSkgPT4gRXh0ZW5zaW9uc1xuXG4gICAgLyoqXG4gICAgICogVGhpcyBmdW5jdGlvbiBleHRlbmRzIHRoZSBzY2hlbWEgb2YgdGhlIG5vZGUuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBleHRlbmROb2RlU2NoZW1hKCkge1xuICAgICAqICAgcmV0dXJuIHtcbiAgICAgKiAgICAgZ3JvdXA6ICdpbmxpbmUnLFxuICAgICAqICAgICBzZWxlY3RhYmxlOiBmYWxzZSxcbiAgICAgKiAgIH1cbiAgICAgKiB9XG4gICAgICovXG4gICAgZXh0ZW5kTm9kZVNjaGVtYT86XG4gICAgICB8ICgoXG4gICAgICAgICAgdGhpczoge1xuICAgICAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICAgICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxNYXJrQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsnZXh0ZW5kTm9kZVNjaGVtYSddXG4gICAgICAgICAgfSxcbiAgICAgICAgICBleHRlbnNpb246IE5vZGUsXG4gICAgICAgICkgPT4gUmVjb3JkPHN0cmluZywgYW55PilcbiAgICAgIHwgbnVsbFxuXG4gICAgLyoqXG4gICAgICogVGhpcyBmdW5jdGlvbiBleHRlbmRzIHRoZSBzY2hlbWEgb2YgdGhlIG1hcmsuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBleHRlbmRNYXJrU2NoZW1hKCkge1xuICAgICAqICAgcmV0dXJuIHtcbiAgICAgKiAgICAgZ3JvdXA6ICdpbmxpbmUnLFxuICAgICAqICAgICBzZWxlY3RhYmxlOiBmYWxzZSxcbiAgICAgKiAgIH1cbiAgICAgKiB9XG4gICAgICovXG4gICAgZXh0ZW5kTWFya1NjaGVtYT86XG4gICAgICB8ICgoXG4gICAgICAgICAgdGhpczoge1xuICAgICAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICAgICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxNYXJrQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsnZXh0ZW5kTWFya1NjaGVtYSddXG4gICAgICAgICAgfSxcbiAgICAgICAgICBleHRlbnNpb246IE1hcmssXG4gICAgICAgICkgPT4gUmVjb3JkPHN0cmluZywgYW55PilcbiAgICAgIHwgbnVsbFxuXG4gICAgLyoqXG4gICAgICogVGhlIGVkaXRvciBpcyBub3QgcmVhZHkgeWV0LlxuICAgICAqL1xuICAgIG9uQmVmb3JlQ3JlYXRlPzpcbiAgICAgIHwgKCh0aGlzOiB7XG4gICAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgICBlZGl0b3I6IEVkaXRvclxuICAgICAgICAgIHR5cGU6IE1hcmtUeXBlXG4gICAgICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8TWFya0NvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ29uQmVmb3JlQ3JlYXRlJ11cbiAgICAgICAgfSkgPT4gdm9pZClcbiAgICAgIHwgbnVsbFxuXG4gICAgLyoqXG4gICAgICogVGhlIGVkaXRvciBpcyByZWFkeS5cbiAgICAgKi9cbiAgICBvbkNyZWF0ZT86XG4gICAgICB8ICgodGhpczoge1xuICAgICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICAgICAgZWRpdG9yOiBFZGl0b3JcbiAgICAgICAgICB0eXBlOiBNYXJrVHlwZVxuICAgICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE1hcmtDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydvbkNyZWF0ZSddXG4gICAgICAgIH0pID0+IHZvaWQpXG4gICAgICB8IG51bGxcblxuICAgIC8qKlxuICAgICAqIFRoZSBjb250ZW50IGhhcyBjaGFuZ2VkLlxuICAgICAqL1xuICAgIG9uVXBkYXRlPzpcbiAgICAgIHwgKCh0aGlzOiB7XG4gICAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgICBlZGl0b3I6IEVkaXRvclxuICAgICAgICAgIHR5cGU6IE1hcmtUeXBlXG4gICAgICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8TWFya0NvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ29uVXBkYXRlJ11cbiAgICAgICAgfSkgPT4gdm9pZClcbiAgICAgIHwgbnVsbFxuXG4gICAgLyoqXG4gICAgICogVGhlIHNlbGVjdGlvbiBoYXMgY2hhbmdlZC5cbiAgICAgKi9cbiAgICBvblNlbGVjdGlvblVwZGF0ZT86XG4gICAgICB8ICgodGhpczoge1xuICAgICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICAgICAgZWRpdG9yOiBFZGl0b3JcbiAgICAgICAgICB0eXBlOiBNYXJrVHlwZVxuICAgICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE1hcmtDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydvblNlbGVjdGlvblVwZGF0ZSddXG4gICAgICAgIH0pID0+IHZvaWQpXG4gICAgICB8IG51bGxcblxuICAgIC8qKlxuICAgICAqIFRoZSBlZGl0b3Igc3RhdGUgaGFzIGNoYW5nZWQuXG4gICAgICovXG4gICAgb25UcmFuc2FjdGlvbj86XG4gICAgICB8ICgoXG4gICAgICAgICAgdGhpczoge1xuICAgICAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICAgICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICAgICAgICBlZGl0b3I6IEVkaXRvclxuICAgICAgICAgICAgdHlwZTogTWFya1R5cGVcbiAgICAgICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE1hcmtDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydvblRyYW5zYWN0aW9uJ11cbiAgICAgICAgICB9LFxuICAgICAgICAgIHByb3BzOiB7XG4gICAgICAgICAgICBlZGl0b3I6IEVkaXRvclxuICAgICAgICAgICAgdHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uXG4gICAgICAgICAgfSxcbiAgICAgICAgKSA9PiB2b2lkKVxuICAgICAgfCBudWxsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgZWRpdG9yIGlzIGZvY3VzZWQuXG4gICAgICovXG4gICAgb25Gb2N1cz86XG4gICAgICB8ICgoXG4gICAgICAgICAgdGhpczoge1xuICAgICAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICAgICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICAgICAgICBlZGl0b3I6IEVkaXRvclxuICAgICAgICAgICAgdHlwZTogTWFya1R5cGVcbiAgICAgICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE1hcmtDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydvbkZvY3VzJ11cbiAgICAgICAgICB9LFxuICAgICAgICAgIHByb3BzOiB7XG4gICAgICAgICAgICBldmVudDogRm9jdXNFdmVudFxuICAgICAgICAgIH0sXG4gICAgICAgICkgPT4gdm9pZClcbiAgICAgIHwgbnVsbFxuXG4gICAgLyoqXG4gICAgICogVGhlIGVkaXRvciBpc27igJl0IGZvY3VzZWQgYW55bW9yZS5cbiAgICAgKi9cbiAgICBvbkJsdXI/OlxuICAgICAgfCAoKFxuICAgICAgICAgIHRoaXM6IHtcbiAgICAgICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgICAgICAgZWRpdG9yOiBFZGl0b3JcbiAgICAgICAgICAgIHR5cGU6IE1hcmtUeXBlXG4gICAgICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxNYXJrQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+Plsnb25CbHVyJ11cbiAgICAgICAgICB9LFxuICAgICAgICAgIHByb3BzOiB7XG4gICAgICAgICAgICBldmVudDogRm9jdXNFdmVudFxuICAgICAgICAgIH0sXG4gICAgICAgICkgPT4gdm9pZClcbiAgICAgIHwgbnVsbFxuXG4gICAgLyoqXG4gICAgICogVGhlIGVkaXRvciBpcyBkZXN0cm95ZWQuXG4gICAgICovXG4gICAgb25EZXN0cm95PzpcbiAgICAgIHwgKCh0aGlzOiB7XG4gICAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgICBlZGl0b3I6IEVkaXRvclxuICAgICAgICAgIHR5cGU6IE1hcmtUeXBlXG4gICAgICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8TWFya0NvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ29uRGVzdHJveSddXG4gICAgICAgIH0pID0+IHZvaWQpXG4gICAgICB8IG51bGxcblxuICAgIC8qKlxuICAgICAqIEtlZXAgbWFyayBhZnRlciBzcGxpdCBub2RlXG4gICAgICovXG4gICAga2VlcE9uU3BsaXQ/OiBib29sZWFuIHwgKCgpID0+IGJvb2xlYW4pXG5cbiAgICAvKipcbiAgICAgKiBJbmNsdXNpdmVcbiAgICAgKi9cbiAgICBpbmNsdXNpdmU/OlxuICAgICAgfCBNYXJrU3BlY1snaW5jbHVzaXZlJ11cbiAgICAgIHwgKCh0aGlzOiB7XG4gICAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxNYXJrQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsnaW5jbHVzaXZlJ11cbiAgICAgICAgICBlZGl0b3I/OiBFZGl0b3JcbiAgICAgICAgfSkgPT4gTWFya1NwZWNbJ2luY2x1c2l2ZSddKVxuXG4gICAgLyoqXG4gICAgICogRXhjbHVkZXNcbiAgICAgKi9cbiAgICBleGNsdWRlcz86XG4gICAgICB8IE1hcmtTcGVjWydleGNsdWRlcyddXG4gICAgICB8ICgodGhpczoge1xuICAgICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8TWFya0NvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ2V4Y2x1ZGVzJ11cbiAgICAgICAgICBlZGl0b3I/OiBFZGl0b3JcbiAgICAgICAgfSkgPT4gTWFya1NwZWNbJ2V4Y2x1ZGVzJ10pXG5cbiAgICAvKipcbiAgICAgKiBNYXJrcyB0aGlzIE1hcmsgYXMgZXhpdGFibGVcbiAgICAgKi9cbiAgICBleGl0YWJsZT86IGJvb2xlYW4gfCAoKCkgPT4gYm9vbGVhbilcblxuICAgIC8qKlxuICAgICAqIEdyb3VwXG4gICAgICovXG4gICAgZ3JvdXA/OlxuICAgICAgfCBNYXJrU3BlY1snZ3JvdXAnXVxuICAgICAgfCAoKHRoaXM6IHtcbiAgICAgICAgICBuYW1lOiBzdHJpbmdcbiAgICAgICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE1hcmtDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+Wydncm91cCddXG4gICAgICAgICAgZWRpdG9yPzogRWRpdG9yXG4gICAgICAgIH0pID0+IE1hcmtTcGVjWydncm91cCddKVxuXG4gICAgLyoqXG4gICAgICogU3Bhbm5pbmdcbiAgICAgKi9cbiAgICBzcGFubmluZz86XG4gICAgICB8IE1hcmtTcGVjWydzcGFubmluZyddXG4gICAgICB8ICgodGhpczoge1xuICAgICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8TWFya0NvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ3NwYW5uaW5nJ11cbiAgICAgICAgICBlZGl0b3I/OiBFZGl0b3JcbiAgICAgICAgfSkgPT4gTWFya1NwZWNbJ3NwYW5uaW5nJ10pXG5cbiAgICAvKipcbiAgICAgKiBDb2RlXG4gICAgICovXG4gICAgY29kZT86XG4gICAgICB8IGJvb2xlYW5cbiAgICAgIHwgKCh0aGlzOiB7XG4gICAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxNYXJrQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsnY29kZSddXG4gICAgICAgICAgZWRpdG9yPzogRWRpdG9yXG4gICAgICAgIH0pID0+IGJvb2xlYW4pXG5cbiAgICAvKipcbiAgICAgKiBQYXJzZSBIVE1MXG4gICAgICovXG4gICAgcGFyc2VIVE1MPzogKHRoaXM6IHtcbiAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8TWFya0NvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ3BhcnNlSFRNTCddXG4gICAgICBlZGl0b3I/OiBFZGl0b3JcbiAgICB9KSA9PiBNYXJrU3BlY1sncGFyc2VET00nXVxuXG4gICAgLyoqXG4gICAgICogUmVuZGVyIEhUTUxcbiAgICAgKi9cbiAgICByZW5kZXJIVE1MPzpcbiAgICAgIHwgKChcbiAgICAgICAgICB0aGlzOiB7XG4gICAgICAgICAgICBuYW1lOiBzdHJpbmdcbiAgICAgICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE1hcmtDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydyZW5kZXJIVE1MJ11cbiAgICAgICAgICAgIGVkaXRvcj86IEVkaXRvclxuICAgICAgICAgIH0sXG4gICAgICAgICAgcHJvcHM6IHtcbiAgICAgICAgICAgIG1hcms6IFByb3NlTWlycm9yTWFya1xuICAgICAgICAgICAgSFRNTEF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIGFueT5cbiAgICAgICAgICB9LFxuICAgICAgICApID0+IERPTU91dHB1dFNwZWMpXG4gICAgICB8IG51bGxcblxuICAgIC8qKlxuICAgICAqIEF0dHJpYnV0ZXNcbiAgICAgKi9cbiAgICBhZGRBdHRyaWJ1dGVzPzogKHRoaXM6IHtcbiAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8TWFya0NvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ2FkZEF0dHJpYnV0ZXMnXVxuICAgICAgZWRpdG9yPzogRWRpdG9yXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1lbXB0eS1vYmplY3QtdHlwZVxuICAgIH0pID0+IEF0dHJpYnV0ZXMgfCB7fVxuICB9XG59XG5cbi8qKlxuICogVGhlIE1hcmsgY2xhc3MgaXMgdXNlZCB0byBjcmVhdGUgY3VzdG9tIG1hcmsgZXh0ZW5zaW9ucy5cbiAqIEBzZWUgaHR0cHM6Ly90aXB0YXAuZGV2L2FwaS9leHRlbnNpb25zI2NyZWF0ZS1hLW5ldy1leHRlbnNpb25cbiAqL1xuZXhwb3J0IGNsYXNzIE1hcms8T3B0aW9ucyA9IGFueSwgU3RvcmFnZSA9IGFueT4ge1xuICB0eXBlID0gJ21hcmsnXG5cbiAgbmFtZSA9ICdtYXJrJ1xuXG4gIHBhcmVudDogTWFyayB8IG51bGwgPSBudWxsXG5cbiAgY2hpbGQ6IE1hcmsgfCBudWxsID0gbnVsbFxuXG4gIG9wdGlvbnM6IE9wdGlvbnNcblxuICBzdG9yYWdlOiBTdG9yYWdlXG5cbiAgY29uZmlnOiBNYXJrQ29uZmlnID0ge1xuICAgIG5hbWU6IHRoaXMubmFtZSxcbiAgICBkZWZhdWx0T3B0aW9uczoge30sXG4gIH1cblxuICBjb25zdHJ1Y3Rvcihjb25maWc6IFBhcnRpYWw8TWFya0NvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj4gPSB7fSkge1xuICAgIHRoaXMuY29uZmlnID0ge1xuICAgICAgLi4udGhpcy5jb25maWcsXG4gICAgICAuLi5jb25maWcsXG4gICAgfVxuXG4gICAgdGhpcy5uYW1lID0gdGhpcy5jb25maWcubmFtZVxuXG4gICAgaWYgKGNvbmZpZy5kZWZhdWx0T3B0aW9ucyAmJiBPYmplY3Qua2V5cyhjb25maWcuZGVmYXVsdE9wdGlvbnMpLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgYFt0aXB0YXAgd2Fybl06IEJSRUFLSU5HIENIQU5HRTogXCJkZWZhdWx0T3B0aW9uc1wiIGlzIGRlcHJlY2F0ZWQuIFBsZWFzZSB1c2UgXCJhZGRPcHRpb25zXCIgaW5zdGVhZC4gRm91bmQgaW4gZXh0ZW5zaW9uOiBcIiR7dGhpcy5uYW1lfVwiLmAsXG4gICAgICApXG4gICAgfVxuXG4gICAgLy8gVE9ETzogcmVtb3ZlIGBhZGRPcHRpb25zYCBmYWxsYmFja1xuICAgIHRoaXMub3B0aW9ucyA9IHRoaXMuY29uZmlnLmRlZmF1bHRPcHRpb25zXG5cbiAgICBpZiAodGhpcy5jb25maWcuYWRkT3B0aW9ucykge1xuICAgICAgdGhpcy5vcHRpb25zID0gY2FsbE9yUmV0dXJuKFxuICAgICAgICBnZXRFeHRlbnNpb25GaWVsZDxBbnlDb25maWdbJ2FkZE9wdGlvbnMnXT4odGhpcywgJ2FkZE9wdGlvbnMnLCB7XG4gICAgICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgICB9KSxcbiAgICAgIClcbiAgICB9XG5cbiAgICB0aGlzLnN0b3JhZ2UgPSBjYWxsT3JSZXR1cm4oXG4gICAgICBnZXRFeHRlbnNpb25GaWVsZDxBbnlDb25maWdbJ2FkZFN0b3JhZ2UnXT4odGhpcywgJ2FkZFN0b3JhZ2UnLCB7XG4gICAgICAgIG5hbWU6IHRoaXMubmFtZSxcbiAgICAgICAgb3B0aW9uczogdGhpcy5vcHRpb25zLFxuICAgICAgfSksXG4gICAgKSB8fCB7fVxuICB9XG5cbiAgc3RhdGljIGNyZWF0ZTxPID0gYW55LCBTID0gYW55Pihjb25maWc6IFBhcnRpYWw8TWFya0NvbmZpZzxPLCBTPj4gPSB7fSkge1xuICAgIHJldHVybiBuZXcgTWFyazxPLCBTPihjb25maWcpXG4gIH1cblxuICBjb25maWd1cmUob3B0aW9uczogUGFydGlhbDxPcHRpb25zPiA9IHt9KSB7XG4gICAgLy8gcmV0dXJuIGEgbmV3IGluc3RhbmNlIHNvIHdlIGNhbiB1c2UgdGhlIHNhbWUgZXh0ZW5zaW9uXG4gICAgLy8gd2l0aCBkaWZmZXJlbnQgY2FsbHMgb2YgYGNvbmZpZ3VyZWBcbiAgICBjb25zdCBleHRlbnNpb24gPSB0aGlzLmV4dGVuZDxPcHRpb25zLCBTdG9yYWdlPih7XG4gICAgICAuLi50aGlzLmNvbmZpZyxcbiAgICAgIGFkZE9wdGlvbnM6ICgpID0+IHtcbiAgICAgICAgcmV0dXJuIG1lcmdlRGVlcCh0aGlzLm9wdGlvbnMgYXMgUmVjb3JkPHN0cmluZywgYW55Piwgb3B0aW9ucykgYXMgT3B0aW9uc1xuICAgICAgfSxcbiAgICB9KVxuXG4gICAgLy8gQWx3YXlzIHByZXNlcnZlIHRoZSBjdXJyZW50IG5hbWVcbiAgICBleHRlbnNpb24ubmFtZSA9IHRoaXMubmFtZVxuICAgIC8vIFNldCB0aGUgcGFyZW50IHRvIGJlIG91ciBwYXJlbnRcbiAgICBleHRlbnNpb24ucGFyZW50ID0gdGhpcy5wYXJlbnRcblxuICAgIHJldHVybiBleHRlbnNpb25cbiAgfVxuXG4gIGV4dGVuZDxFeHRlbmRlZE9wdGlvbnMgPSBPcHRpb25zLCBFeHRlbmRlZFN0b3JhZ2UgPSBTdG9yYWdlPihcbiAgICBleHRlbmRlZENvbmZpZzogUGFydGlhbDxNYXJrQ29uZmlnPEV4dGVuZGVkT3B0aW9ucywgRXh0ZW5kZWRTdG9yYWdlPj4gPSB7fSxcbiAgKSB7XG4gICAgY29uc3QgZXh0ZW5zaW9uID0gbmV3IE1hcms8RXh0ZW5kZWRPcHRpb25zLCBFeHRlbmRlZFN0b3JhZ2U+KGV4dGVuZGVkQ29uZmlnKVxuXG4gICAgZXh0ZW5zaW9uLnBhcmVudCA9IHRoaXNcblxuICAgIHRoaXMuY2hpbGQgPSBleHRlbnNpb25cblxuICAgIGV4dGVuc2lvbi5uYW1lID0gZXh0ZW5kZWRDb25maWcubmFtZSA/IGV4dGVuZGVkQ29uZmlnLm5hbWUgOiBleHRlbnNpb24ucGFyZW50Lm5hbWVcblxuICAgIGlmIChleHRlbmRlZENvbmZpZy5kZWZhdWx0T3B0aW9ucyAmJiBPYmplY3Qua2V5cyhleHRlbmRlZENvbmZpZy5kZWZhdWx0T3B0aW9ucykubGVuZ3RoID4gMCkge1xuICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICBgW3RpcHRhcCB3YXJuXTogQlJFQUtJTkcgQ0hBTkdFOiBcImRlZmF1bHRPcHRpb25zXCIgaXMgZGVwcmVjYXRlZC4gUGxlYXNlIHVzZSBcImFkZE9wdGlvbnNcIiBpbnN0ZWFkLiBGb3VuZCBpbiBleHRlbnNpb246IFwiJHtleHRlbnNpb24ubmFtZX1cIi5gLFxuICAgICAgKVxuICAgIH1cblxuICAgIGV4dGVuc2lvbi5vcHRpb25zID0gY2FsbE9yUmV0dXJuKFxuICAgICAgZ2V0RXh0ZW5zaW9uRmllbGQ8QW55Q29uZmlnWydhZGRPcHRpb25zJ10+KGV4dGVuc2lvbiwgJ2FkZE9wdGlvbnMnLCB7XG4gICAgICAgIG5hbWU6IGV4dGVuc2lvbi5uYW1lLFxuICAgICAgfSksXG4gICAgKVxuXG4gICAgZXh0ZW5zaW9uLnN0b3JhZ2UgPSBjYWxsT3JSZXR1cm4oXG4gICAgICBnZXRFeHRlbnNpb25GaWVsZDxBbnlDb25maWdbJ2FkZFN0b3JhZ2UnXT4oZXh0ZW5zaW9uLCAnYWRkU3RvcmFnZScsIHtcbiAgICAgICAgbmFtZTogZXh0ZW5zaW9uLm5hbWUsXG4gICAgICAgIG9wdGlvbnM6IGV4dGVuc2lvbi5vcHRpb25zLFxuICAgICAgfSksXG4gICAgKVxuXG4gICAgcmV0dXJuIGV4dGVuc2lvblxuICB9XG5cbiAgc3RhdGljIGhhbmRsZUV4aXQoeyBlZGl0b3IsIG1hcmsgfTogeyBlZGl0b3I6IEVkaXRvcjsgbWFyazogTWFyayB9KSB7XG4gICAgY29uc3QgeyB0ciB9ID0gZWRpdG9yLnN0YXRlXG4gICAgY29uc3QgY3VycmVudFBvcyA9IGVkaXRvci5zdGF0ZS5zZWxlY3Rpb24uJGZyb21cbiAgICBjb25zdCBpc0F0RW5kID0gY3VycmVudFBvcy5wb3MgPT09IGN1cnJlbnRQb3MuZW5kKClcblxuICAgIGlmIChpc0F0RW5kKSB7XG4gICAgICBjb25zdCBjdXJyZW50TWFya3MgPSBjdXJyZW50UG9zLm1hcmtzKClcbiAgICAgIGNvbnN0IGlzSW5NYXJrID0gISFjdXJyZW50TWFya3MuZmluZChtID0+IG0/LnR5cGUubmFtZSA9PT0gbWFyay5uYW1lKVxuXG4gICAgICBpZiAoIWlzSW5NYXJrKSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfVxuXG4gICAgICBjb25zdCByZW1vdmVNYXJrID0gY3VycmVudE1hcmtzLmZpbmQobSA9PiBtPy50eXBlLm5hbWUgPT09IG1hcmsubmFtZSlcblxuICAgICAgaWYgKHJlbW92ZU1hcmspIHtcbiAgICAgICAgdHIucmVtb3ZlU3RvcmVkTWFyayhyZW1vdmVNYXJrKVxuICAgICAgfVxuICAgICAgdHIuaW5zZXJ0VGV4dCgnICcsIGN1cnJlbnRQb3MucG9zKVxuXG4gICAgICBlZGl0b3Iudmlldy5kaXNwYXRjaCh0cilcblxuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxufVxuIiwgImV4cG9ydCBmdW5jdGlvbiBpc051bWJlcih2YWx1ZTogYW55KTogdmFsdWUgaXMgbnVtYmVyIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcidcbn1cbiIsICJpbXBvcnQgeyBGcmFnbWVudCwgTm9kZSBhcyBQcm9zZU1pcnJvck5vZGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuaW1wb3J0IHsgRWRpdG9yU3RhdGUsIFBsdWdpbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmltcG9ydCB7IENvbW1hbmRNYW5hZ2VyIH0gZnJvbSAnLi9Db21tYW5kTWFuYWdlci5qcydcbmltcG9ydCB7IEVkaXRvciB9IGZyb20gJy4vRWRpdG9yLmpzJ1xuaW1wb3J0IHsgY3JlYXRlQ2hhaW5hYmxlU3RhdGUgfSBmcm9tICcuL2hlbHBlcnMvY3JlYXRlQ2hhaW5hYmxlU3RhdGUuanMnXG5pbXBvcnQgeyBnZXRIVE1MRnJvbUZyYWdtZW50IH0gZnJvbSAnLi9oZWxwZXJzL2dldEhUTUxGcm9tRnJhZ21lbnQuanMnXG5pbXBvcnQge1xuICBDYW5Db21tYW5kcyxcbiAgQ2hhaW5lZENvbW1hbmRzLFxuICBFeHRlbmRlZFJlZ0V4cE1hdGNoQXJyYXksXG4gIFJhbmdlLFxuICBTaW5nbGVDb21tYW5kcyxcbn0gZnJvbSAnLi90eXBlcy5qcydcbmltcG9ydCB7IGlzTnVtYmVyIH0gZnJvbSAnLi91dGlsaXRpZXMvaXNOdW1iZXIuanMnXG5pbXBvcnQgeyBpc1JlZ0V4cCB9IGZyb20gJy4vdXRpbGl0aWVzL2lzUmVnRXhwLmpzJ1xuXG5leHBvcnQgdHlwZSBQYXN0ZVJ1bGVNYXRjaCA9IHtcbiAgaW5kZXg6IG51bWJlcjtcbiAgdGV4dDogc3RyaW5nO1xuICByZXBsYWNlV2l0aD86IHN0cmluZztcbiAgbWF0Y2g/OiBSZWdFeHBNYXRjaEFycmF5O1xuICBkYXRhPzogUmVjb3JkPHN0cmluZywgYW55Pjtcbn07XG5cbmV4cG9ydCB0eXBlIFBhc3RlUnVsZUZpbmRlciA9XG4gIHwgUmVnRXhwXG4gIHwgKCh0ZXh0OiBzdHJpbmcsIGV2ZW50PzogQ2xpcGJvYXJkRXZlbnQgfCBudWxsKSA9PiBQYXN0ZVJ1bGVNYXRjaFtdIHwgbnVsbCB8IHVuZGVmaW5lZCk7XG5cbi8qKlxuICogUGFzdGUgcnVsZXMgYXJlIHVzZWQgdG8gcmVhY3QgdG8gcGFzdGVkIGNvbnRlbnQuXG4gKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9kb2NzL2VkaXRvci9leHRlbnNpb25zL2N1c3RvbS1leHRlbnNpb25zL2V4dGVuZC1leGlzdGluZyNwYXN0ZS1ydWxlc1xuICovXG5leHBvcnQgY2xhc3MgUGFzdGVSdWxlIHtcbiAgZmluZDogUGFzdGVSdWxlRmluZGVyXG5cbiAgaGFuZGxlcjogKHByb3BzOiB7XG4gICAgc3RhdGU6IEVkaXRvclN0YXRlO1xuICAgIHJhbmdlOiBSYW5nZTtcbiAgICBtYXRjaDogRXh0ZW5kZWRSZWdFeHBNYXRjaEFycmF5O1xuICAgIGNvbW1hbmRzOiBTaW5nbGVDb21tYW5kcztcbiAgICBjaGFpbjogKCkgPT4gQ2hhaW5lZENvbW1hbmRzO1xuICAgIGNhbjogKCkgPT4gQ2FuQ29tbWFuZHM7XG4gICAgcGFzdGVFdmVudDogQ2xpcGJvYXJkRXZlbnQgfCBudWxsO1xuICAgIGRyb3BFdmVudDogRHJhZ0V2ZW50IHwgbnVsbDtcbiAgfSkgPT4gdm9pZCB8IG51bGxcblxuICBjb25zdHJ1Y3Rvcihjb25maWc6IHtcbiAgICBmaW5kOiBQYXN0ZVJ1bGVGaW5kZXI7XG4gICAgaGFuZGxlcjogKHByb3BzOiB7XG4gICAgICBjYW46ICgpID0+IENhbkNvbW1hbmRzO1xuICAgICAgY2hhaW46ICgpID0+IENoYWluZWRDb21tYW5kcztcbiAgICAgIGNvbW1hbmRzOiBTaW5nbGVDb21tYW5kcztcbiAgICAgIGRyb3BFdmVudDogRHJhZ0V2ZW50IHwgbnVsbDtcbiAgICAgIG1hdGNoOiBFeHRlbmRlZFJlZ0V4cE1hdGNoQXJyYXk7XG4gICAgICBwYXN0ZUV2ZW50OiBDbGlwYm9hcmRFdmVudCB8IG51bGw7XG4gICAgICByYW5nZTogUmFuZ2U7XG4gICAgICBzdGF0ZTogRWRpdG9yU3RhdGU7XG4gICAgfSkgPT4gdm9pZCB8IG51bGw7XG4gIH0pIHtcbiAgICB0aGlzLmZpbmQgPSBjb25maWcuZmluZFxuICAgIHRoaXMuaGFuZGxlciA9IGNvbmZpZy5oYW5kbGVyXG4gIH1cbn1cblxuY29uc3QgcGFzdGVSdWxlTWF0Y2hlckhhbmRsZXIgPSAoXG4gIHRleHQ6IHN0cmluZyxcbiAgZmluZDogUGFzdGVSdWxlRmluZGVyLFxuICBldmVudD86IENsaXBib2FyZEV2ZW50IHwgbnVsbCxcbik6IEV4dGVuZGVkUmVnRXhwTWF0Y2hBcnJheVtdID0+IHtcbiAgaWYgKGlzUmVnRXhwKGZpbmQpKSB7XG4gICAgcmV0dXJuIFsuLi50ZXh0Lm1hdGNoQWxsKGZpbmQpXVxuICB9XG5cbiAgY29uc3QgbWF0Y2hlcyA9IGZpbmQodGV4dCwgZXZlbnQpXG5cbiAgaWYgKCFtYXRjaGVzKSB7XG4gICAgcmV0dXJuIFtdXG4gIH1cblxuICByZXR1cm4gbWF0Y2hlcy5tYXAocGFzdGVSdWxlTWF0Y2ggPT4ge1xuICAgIGNvbnN0IHJlc3VsdDogRXh0ZW5kZWRSZWdFeHBNYXRjaEFycmF5ID0gW3Bhc3RlUnVsZU1hdGNoLnRleHRdXG5cbiAgICByZXN1bHQuaW5kZXggPSBwYXN0ZVJ1bGVNYXRjaC5pbmRleFxuICAgIHJlc3VsdC5pbnB1dCA9IHRleHRcbiAgICByZXN1bHQuZGF0YSA9IHBhc3RlUnVsZU1hdGNoLmRhdGFcblxuICAgIGlmIChwYXN0ZVJ1bGVNYXRjaC5yZXBsYWNlV2l0aCkge1xuICAgICAgaWYgKCFwYXN0ZVJ1bGVNYXRjaC50ZXh0LmluY2x1ZGVzKHBhc3RlUnVsZU1hdGNoLnJlcGxhY2VXaXRoKSkge1xuICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgJ1t0aXB0YXAgd2Fybl06IFwicGFzdGVSdWxlTWF0Y2gucmVwbGFjZVdpdGhcIiBtdXN0IGJlIHBhcnQgb2YgXCJwYXN0ZVJ1bGVNYXRjaC50ZXh0XCIuJyxcbiAgICAgICAgKVxuICAgICAgfVxuXG4gICAgICByZXN1bHQucHVzaChwYXN0ZVJ1bGVNYXRjaC5yZXBsYWNlV2l0aClcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0XG4gIH0pXG59XG5cbmZ1bmN0aW9uIHJ1bihjb25maWc6IHtcbiAgZWRpdG9yOiBFZGl0b3I7XG4gIHN0YXRlOiBFZGl0b3JTdGF0ZTtcbiAgZnJvbTogbnVtYmVyO1xuICB0bzogbnVtYmVyO1xuICBydWxlOiBQYXN0ZVJ1bGU7XG4gIHBhc3RlRXZlbnQ6IENsaXBib2FyZEV2ZW50IHwgbnVsbDtcbiAgZHJvcEV2ZW50OiBEcmFnRXZlbnQgfCBudWxsO1xufSk6IGJvb2xlYW4ge1xuICBjb25zdCB7XG4gICAgZWRpdG9yLCBzdGF0ZSwgZnJvbSwgdG8sIHJ1bGUsIHBhc3RlRXZlbnQsIGRyb3BFdmVudCxcbiAgfSA9IGNvbmZpZ1xuXG4gIGNvbnN0IHsgY29tbWFuZHMsIGNoYWluLCBjYW4gfSA9IG5ldyBDb21tYW5kTWFuYWdlcih7XG4gICAgZWRpdG9yLFxuICAgIHN0YXRlLFxuICB9KVxuXG4gIGNvbnN0IGhhbmRsZXJzOiAodm9pZCB8IG51bGwpW10gPSBbXVxuXG4gIHN0YXRlLmRvYy5ub2Rlc0JldHdlZW4oZnJvbSwgdG8sIChub2RlLCBwb3MpID0+IHtcbiAgICBpZiAoIW5vZGUuaXNUZXh0YmxvY2sgfHwgbm9kZS50eXBlLnNwZWMuY29kZSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3QgcmVzb2x2ZWRGcm9tID0gTWF0aC5tYXgoZnJvbSwgcG9zKVxuICAgIGNvbnN0IHJlc29sdmVkVG8gPSBNYXRoLm1pbih0bywgcG9zICsgbm9kZS5jb250ZW50LnNpemUpXG4gICAgY29uc3QgdGV4dFRvTWF0Y2ggPSBub2RlLnRleHRCZXR3ZWVuKHJlc29sdmVkRnJvbSAtIHBvcywgcmVzb2x2ZWRUbyAtIHBvcywgdW5kZWZpbmVkLCAnXFx1ZmZmYycpXG5cbiAgICBjb25zdCBtYXRjaGVzID0gcGFzdGVSdWxlTWF0Y2hlckhhbmRsZXIodGV4dFRvTWF0Y2gsIHJ1bGUuZmluZCwgcGFzdGVFdmVudClcblxuICAgIG1hdGNoZXMuZm9yRWFjaChtYXRjaCA9PiB7XG4gICAgICBpZiAobWF0Y2guaW5kZXggPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgY29uc3Qgc3RhcnQgPSByZXNvbHZlZEZyb20gKyBtYXRjaC5pbmRleCArIDFcbiAgICAgIGNvbnN0IGVuZCA9IHN0YXJ0ICsgbWF0Y2hbMF0ubGVuZ3RoXG4gICAgICBjb25zdCByYW5nZSA9IHtcbiAgICAgICAgZnJvbTogc3RhdGUudHIubWFwcGluZy5tYXAoc3RhcnQpLFxuICAgICAgICB0bzogc3RhdGUudHIubWFwcGluZy5tYXAoZW5kKSxcbiAgICAgIH1cblxuICAgICAgY29uc3QgaGFuZGxlciA9IHJ1bGUuaGFuZGxlcih7XG4gICAgICAgIHN0YXRlLFxuICAgICAgICByYW5nZSxcbiAgICAgICAgbWF0Y2gsXG4gICAgICAgIGNvbW1hbmRzLFxuICAgICAgICBjaGFpbixcbiAgICAgICAgY2FuLFxuICAgICAgICBwYXN0ZUV2ZW50LFxuICAgICAgICBkcm9wRXZlbnQsXG4gICAgICB9KVxuXG4gICAgICBoYW5kbGVycy5wdXNoKGhhbmRsZXIpXG4gICAgfSlcbiAgfSlcblxuICBjb25zdCBzdWNjZXNzID0gaGFuZGxlcnMuZXZlcnkoaGFuZGxlciA9PiBoYW5kbGVyICE9PSBudWxsKVxuXG4gIHJldHVybiBzdWNjZXNzXG59XG5cbi8vIFdoZW4gZHJhZ2dpbmcgYWNyb3NzIGVkaXRvcnMsIG11c3QgZ2V0IGFub3RoZXIgZWRpdG9yIGluc3RhbmNlIHRvIGRlbGV0ZSBzZWxlY3Rpb24gY29udGVudC5cbmxldCB0aXB0YXBEcmFnRnJvbU90aGVyRWRpdG9yOiBFZGl0b3IgfCBudWxsID0gbnVsbFxuXG5jb25zdCBjcmVhdGVDbGlwYm9hcmRQYXN0ZUV2ZW50ID0gKHRleHQ6IHN0cmluZykgPT4ge1xuICBjb25zdCBldmVudCA9IG5ldyBDbGlwYm9hcmRFdmVudCgncGFzdGUnLCB7XG4gICAgY2xpcGJvYXJkRGF0YTogbmV3IERhdGFUcmFuc2ZlcigpLFxuICB9KVxuXG4gIGV2ZW50LmNsaXBib2FyZERhdGE/LnNldERhdGEoJ3RleHQvaHRtbCcsIHRleHQpXG5cbiAgcmV0dXJuIGV2ZW50XG59XG5cbi8qKlxuICogQ3JlYXRlIGFuIHBhc3RlIHJ1bGVzIHBsdWdpbi4gV2hlbiBlbmFibGVkLCBpdCB3aWxsIGNhdXNlIHBhc3RlZFxuICogdGV4dCB0aGF0IG1hdGNoZXMgYW55IG9mIHRoZSBnaXZlbiBydWxlcyB0byB0cmlnZ2VyIHRoZSBydWxl4oCZc1xuICogYWN0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFzdGVSdWxlc1BsdWdpbihwcm9wczogeyBlZGl0b3I6IEVkaXRvcjsgcnVsZXM6IFBhc3RlUnVsZVtdIH0pOiBQbHVnaW5bXSB7XG4gIGNvbnN0IHsgZWRpdG9yLCBydWxlcyB9ID0gcHJvcHNcbiAgbGV0IGRyYWdTb3VyY2VFbGVtZW50OiBFbGVtZW50IHwgbnVsbCA9IG51bGxcbiAgbGV0IGlzUGFzdGVkRnJvbVByb3NlTWlycm9yID0gZmFsc2VcbiAgbGV0IGlzRHJvcHBlZEZyb21Qcm9zZU1pcnJvciA9IGZhbHNlXG4gIGxldCBwYXN0ZUV2ZW50ID0gdHlwZW9mIENsaXBib2FyZEV2ZW50ICE9PSAndW5kZWZpbmVkJyA/IG5ldyBDbGlwYm9hcmRFdmVudCgncGFzdGUnKSA6IG51bGxcbiAgbGV0IGRyb3BFdmVudDogRHJhZ0V2ZW50IHwgbnVsbFxuXG4gIHRyeSB7XG4gICAgZHJvcEV2ZW50ID0gdHlwZW9mIERyYWdFdmVudCAhPT0gJ3VuZGVmaW5lZCcgPyBuZXcgRHJhZ0V2ZW50KCdkcm9wJykgOiBudWxsXG4gIH0gY2F0Y2gge1xuICAgIGRyb3BFdmVudCA9IG51bGxcbiAgfVxuXG4gIGNvbnN0IHByb2Nlc3NFdmVudCA9ICh7XG4gICAgc3RhdGUsXG4gICAgZnJvbSxcbiAgICB0byxcbiAgICBydWxlLFxuICAgIHBhc3RlRXZ0LFxuICB9OiB7XG4gICAgc3RhdGU6IEVkaXRvclN0YXRlO1xuICAgIGZyb206IG51bWJlcjtcbiAgICB0bzogeyBiOiBudW1iZXIgfTtcbiAgICBydWxlOiBQYXN0ZVJ1bGU7XG4gICAgcGFzdGVFdnQ6IENsaXBib2FyZEV2ZW50IHwgbnVsbDtcbiAgfSkgPT4ge1xuICAgIGNvbnN0IHRyID0gc3RhdGUudHJcbiAgICBjb25zdCBjaGFpbmFibGVTdGF0ZSA9IGNyZWF0ZUNoYWluYWJsZVN0YXRlKHtcbiAgICAgIHN0YXRlLFxuICAgICAgdHJhbnNhY3Rpb246IHRyLFxuICAgIH0pXG5cbiAgICBjb25zdCBoYW5kbGVyID0gcnVuKHtcbiAgICAgIGVkaXRvcixcbiAgICAgIHN0YXRlOiBjaGFpbmFibGVTdGF0ZSxcbiAgICAgIGZyb206IE1hdGgubWF4KGZyb20gLSAxLCAwKSxcbiAgICAgIHRvOiB0by5iIC0gMSxcbiAgICAgIHJ1bGUsXG4gICAgICBwYXN0ZUV2ZW50OiBwYXN0ZUV2dCxcbiAgICAgIGRyb3BFdmVudCxcbiAgICB9KVxuXG4gICAgaWYgKCFoYW5kbGVyIHx8ICF0ci5zdGVwcy5sZW5ndGgpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBkcm9wRXZlbnQgPSB0eXBlb2YgRHJhZ0V2ZW50ICE9PSAndW5kZWZpbmVkJyA/IG5ldyBEcmFnRXZlbnQoJ2Ryb3AnKSA6IG51bGxcbiAgICB9IGNhdGNoIHtcbiAgICAgIGRyb3BFdmVudCA9IG51bGxcbiAgICB9XG4gICAgcGFzdGVFdmVudCA9IHR5cGVvZiBDbGlwYm9hcmRFdmVudCAhPT0gJ3VuZGVmaW5lZCcgPyBuZXcgQ2xpcGJvYXJkRXZlbnQoJ3Bhc3RlJykgOiBudWxsXG5cbiAgICByZXR1cm4gdHJcbiAgfVxuXG4gIGNvbnN0IHBsdWdpbnMgPSBydWxlcy5tYXAocnVsZSA9PiB7XG4gICAgcmV0dXJuIG5ldyBQbHVnaW4oe1xuICAgICAgLy8gd2UgcmVnaXN0ZXIgYSBnbG9iYWwgZHJhZyBoYW5kbGVyIHRvIHRyYWNrIHRoZSBjdXJyZW50IGRyYWcgc291cmNlIGVsZW1lbnRcbiAgICAgIHZpZXcodmlldykge1xuICAgICAgICBjb25zdCBoYW5kbGVEcmFnc3RhcnQgPSAoZXZlbnQ6IERyYWdFdmVudCkgPT4ge1xuICAgICAgICAgIGRyYWdTb3VyY2VFbGVtZW50ID0gdmlldy5kb20ucGFyZW50RWxlbWVudD8uY29udGFpbnMoZXZlbnQudGFyZ2V0IGFzIEVsZW1lbnQpXG4gICAgICAgICAgICA/IHZpZXcuZG9tLnBhcmVudEVsZW1lbnRcbiAgICAgICAgICAgIDogbnVsbFxuXG4gICAgICAgICAgaWYgKGRyYWdTb3VyY2VFbGVtZW50KSB7XG4gICAgICAgICAgICB0aXB0YXBEcmFnRnJvbU90aGVyRWRpdG9yID0gZWRpdG9yXG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaGFuZGxlRHJhZ2VuZCA9ICgpID0+IHtcbiAgICAgICAgICBpZiAodGlwdGFwRHJhZ0Zyb21PdGhlckVkaXRvcikge1xuICAgICAgICAgICAgdGlwdGFwRHJhZ0Zyb21PdGhlckVkaXRvciA9IG51bGxcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignZHJhZ3N0YXJ0JywgaGFuZGxlRHJhZ3N0YXJ0KVxuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignZHJhZ2VuZCcsIGhhbmRsZURyYWdlbmQpXG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBkZXN0cm95KCkge1xuICAgICAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2RyYWdzdGFydCcsIGhhbmRsZURyYWdzdGFydClcbiAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdkcmFnZW5kJywgaGFuZGxlRHJhZ2VuZClcbiAgICAgICAgICB9LFxuICAgICAgICB9XG4gICAgICB9LFxuXG4gICAgICBwcm9wczoge1xuICAgICAgICBoYW5kbGVET01FdmVudHM6IHtcbiAgICAgICAgICBkcm9wOiAodmlldywgZXZlbnQ6IEV2ZW50KSA9PiB7XG4gICAgICAgICAgICBpc0Ryb3BwZWRGcm9tUHJvc2VNaXJyb3IgPSBkcmFnU291cmNlRWxlbWVudCA9PT0gdmlldy5kb20ucGFyZW50RWxlbWVudFxuICAgICAgICAgICAgZHJvcEV2ZW50ID0gZXZlbnQgYXMgRHJhZ0V2ZW50XG5cbiAgICAgICAgICAgIGlmICghaXNEcm9wcGVkRnJvbVByb3NlTWlycm9yKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGRyYWdGcm9tT3RoZXJFZGl0b3IgPSB0aXB0YXBEcmFnRnJvbU90aGVyRWRpdG9yXG5cbiAgICAgICAgICAgICAgaWYgKGRyYWdGcm9tT3RoZXJFZGl0b3IpIHtcbiAgICAgICAgICAgICAgICAvLyBzZXRUaW1lb3V0IHRvIGF2b2lkIHRoZSB3cm9uZyBjb250ZW50IGFmdGVyIGRyb3AsIHRpbWVvdXQgYXJnIGNhbid0IGJlIGVtcHR5IG9yIDBcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHNlbGVjdGlvbiA9IGRyYWdGcm9tT3RoZXJFZGl0b3Iuc3RhdGUuc2VsZWN0aW9uXG5cbiAgICAgICAgICAgICAgICAgIGlmIChzZWxlY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgZHJhZ0Zyb21PdGhlckVkaXRvci5jb21tYW5kcy5kZWxldGVSYW5nZSh7IGZyb206IHNlbGVjdGlvbi5mcm9tLCB0bzogc2VsZWN0aW9uLnRvIH0pXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSwgMTApXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgIH0sXG5cbiAgICAgICAgICBwYXN0ZTogKF92aWV3LCBldmVudDogRXZlbnQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGh0bWwgPSAoZXZlbnQgYXMgQ2xpcGJvYXJkRXZlbnQpLmNsaXBib2FyZERhdGE/LmdldERhdGEoJ3RleHQvaHRtbCcpXG5cbiAgICAgICAgICAgIHBhc3RlRXZlbnQgPSBldmVudCBhcyBDbGlwYm9hcmRFdmVudFxuXG4gICAgICAgICAgICBpc1Bhc3RlZEZyb21Qcm9zZU1pcnJvciA9ICEhaHRtbD8uaW5jbHVkZXMoJ2RhdGEtcG0tc2xpY2UnKVxuXG4gICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcblxuICAgICAgYXBwZW5kVHJhbnNhY3Rpb246ICh0cmFuc2FjdGlvbnMsIG9sZFN0YXRlLCBzdGF0ZSkgPT4ge1xuICAgICAgICBjb25zdCB0cmFuc2FjdGlvbiA9IHRyYW5zYWN0aW9uc1swXVxuICAgICAgICBjb25zdCBpc1Bhc3RlID0gdHJhbnNhY3Rpb24uZ2V0TWV0YSgndWlFdmVudCcpID09PSAncGFzdGUnICYmICFpc1Bhc3RlZEZyb21Qcm9zZU1pcnJvclxuICAgICAgICBjb25zdCBpc0Ryb3AgPSB0cmFuc2FjdGlvbi5nZXRNZXRhKCd1aUV2ZW50JykgPT09ICdkcm9wJyAmJiAhaXNEcm9wcGVkRnJvbVByb3NlTWlycm9yXG5cbiAgICAgICAgLy8gaWYgUGFzdGVSdWxlIGlzIHRyaWdnZXJlZCBieSBpbnNlcnRDb250ZW50KClcbiAgICAgICAgY29uc3Qgc2ltdWxhdGVkUGFzdGVNZXRhID0gdHJhbnNhY3Rpb24uZ2V0TWV0YSgnYXBwbHlQYXN0ZVJ1bGVzJykgYXNcbiAgICAgICAgICB8IHVuZGVmaW5lZFxuICAgICAgICAgIHwgeyBmcm9tOiBudW1iZXI7IHRleHQ6IHN0cmluZyB8IFByb3NlTWlycm9yTm9kZSB8IEZyYWdtZW50IH1cbiAgICAgICAgY29uc3QgaXNTaW11bGF0ZWRQYXN0ZSA9ICEhc2ltdWxhdGVkUGFzdGVNZXRhXG5cbiAgICAgICAgaWYgKCFpc1Bhc3RlICYmICFpc0Ryb3AgJiYgIWlzU2ltdWxhdGVkUGFzdGUpIHtcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEhhbmRsZSBzaW11bGF0ZWQgcGFzdGVcbiAgICAgICAgaWYgKGlzU2ltdWxhdGVkUGFzdGUpIHtcbiAgICAgICAgICBsZXQgeyB0ZXh0IH0gPSBzaW11bGF0ZWRQYXN0ZU1ldGFcblxuICAgICAgICAgIGlmICh0eXBlb2YgdGV4dCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHRleHQgPSB0ZXh0IGFzIHN0cmluZ1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0ZXh0ID0gZ2V0SFRNTEZyb21GcmFnbWVudChGcmFnbWVudC5mcm9tKHRleHQpLCBzdGF0ZS5zY2hlbWEpXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgeyBmcm9tIH0gPSBzaW11bGF0ZWRQYXN0ZU1ldGFcbiAgICAgICAgICBjb25zdCB0byA9IGZyb20gKyB0ZXh0Lmxlbmd0aFxuXG4gICAgICAgICAgY29uc3QgcGFzdGVFdnQgPSBjcmVhdGVDbGlwYm9hcmRQYXN0ZUV2ZW50KHRleHQpXG5cbiAgICAgICAgICByZXR1cm4gcHJvY2Vzc0V2ZW50KHtcbiAgICAgICAgICAgIHJ1bGUsXG4gICAgICAgICAgICBzdGF0ZSxcbiAgICAgICAgICAgIGZyb20sXG4gICAgICAgICAgICB0bzogeyBiOiB0byB9LFxuICAgICAgICAgICAgcGFzdGVFdnQsXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGhhbmRsZSBhY3R1YWwgcGFzdGUvZHJvcFxuICAgICAgICBjb25zdCBmcm9tID0gb2xkU3RhdGUuZG9jLmNvbnRlbnQuZmluZERpZmZTdGFydChzdGF0ZS5kb2MuY29udGVudClcbiAgICAgICAgY29uc3QgdG8gPSBvbGRTdGF0ZS5kb2MuY29udGVudC5maW5kRGlmZkVuZChzdGF0ZS5kb2MuY29udGVudClcblxuICAgICAgICAvLyBzdG9wIGlmIHRoZXJlIGlzIG5vIGNoYW5nZWQgcmFuZ2VcbiAgICAgICAgaWYgKCFpc051bWJlcihmcm9tKSB8fCAhdG8gfHwgZnJvbSA9PT0gdG8uYikge1xuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHByb2Nlc3NFdmVudCh7XG4gICAgICAgICAgcnVsZSxcbiAgICAgICAgICBzdGF0ZSxcbiAgICAgICAgICBmcm9tLFxuICAgICAgICAgIHRvLFxuICAgICAgICAgIHBhc3RlRXZ0OiBwYXN0ZUV2ZW50LFxuICAgICAgICB9KVxuICAgICAgfSxcbiAgICB9KVxuICB9KVxuXG4gIHJldHVybiBwbHVnaW5zXG59XG4iLCAiZXhwb3J0IGZ1bmN0aW9uIGZpbmREdXBsaWNhdGVzKGl0ZW1zOiBhbnlbXSk6IGFueVtdIHtcbiAgY29uc3QgZmlsdGVyZWQgPSBpdGVtcy5maWx0ZXIoKGVsLCBpbmRleCkgPT4gaXRlbXMuaW5kZXhPZihlbCkgIT09IGluZGV4KVxuXG4gIHJldHVybiBBcnJheS5mcm9tKG5ldyBTZXQoZmlsdGVyZWQpKVxufVxuIiwgImltcG9ydCB7IGtleW1hcCB9IGZyb20gJ0B0aXB0YXAvcG0va2V5bWFwJ1xuaW1wb3J0IHsgU2NoZW1hIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcbmltcG9ydCB7IFBsdWdpbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5pbXBvcnQgeyBOb2RlVmlld0NvbnN0cnVjdG9yIH0gZnJvbSAnQHRpcHRhcC9wbS92aWV3J1xuXG5pbXBvcnQgdHlwZSB7IEVkaXRvciB9IGZyb20gJy4vRWRpdG9yLmpzJ1xuaW1wb3J0IHsgZ2V0QXR0cmlidXRlc0Zyb21FeHRlbnNpb25zIH0gZnJvbSAnLi9oZWxwZXJzL2dldEF0dHJpYnV0ZXNGcm9tRXh0ZW5zaW9ucy5qcydcbmltcG9ydCB7IGdldEV4dGVuc2lvbkZpZWxkIH0gZnJvbSAnLi9oZWxwZXJzL2dldEV4dGVuc2lvbkZpZWxkLmpzJ1xuaW1wb3J0IHsgZ2V0Tm9kZVR5cGUgfSBmcm9tICcuL2hlbHBlcnMvZ2V0Tm9kZVR5cGUuanMnXG5pbXBvcnQgeyBnZXRSZW5kZXJlZEF0dHJpYnV0ZXMgfSBmcm9tICcuL2hlbHBlcnMvZ2V0UmVuZGVyZWRBdHRyaWJ1dGVzLmpzJ1xuaW1wb3J0IHsgZ2V0U2NoZW1hQnlSZXNvbHZlZEV4dGVuc2lvbnMgfSBmcm9tICcuL2hlbHBlcnMvZ2V0U2NoZW1hQnlSZXNvbHZlZEV4dGVuc2lvbnMuanMnXG5pbXBvcnQgeyBnZXRTY2hlbWFUeXBlQnlOYW1lIH0gZnJvbSAnLi9oZWxwZXJzL2dldFNjaGVtYVR5cGVCeU5hbWUuanMnXG5pbXBvcnQgeyBpc0V4dGVuc2lvblJ1bGVzRW5hYmxlZCB9IGZyb20gJy4vaGVscGVycy9pc0V4dGVuc2lvblJ1bGVzRW5hYmxlZC5qcydcbmltcG9ydCB7IHNwbGl0RXh0ZW5zaW9ucyB9IGZyb20gJy4vaGVscGVycy9zcGxpdEV4dGVuc2lvbnMuanMnXG5pbXBvcnQgdHlwZSB7IE5vZGVDb25maWcgfSBmcm9tICcuL2luZGV4LmpzJ1xuaW1wb3J0IHsgSW5wdXRSdWxlLCBpbnB1dFJ1bGVzUGx1Z2luIH0gZnJvbSAnLi9JbnB1dFJ1bGUuanMnXG5pbXBvcnQgeyBNYXJrIH0gZnJvbSAnLi9NYXJrLmpzJ1xuaW1wb3J0IHsgUGFzdGVSdWxlLCBwYXN0ZVJ1bGVzUGx1Z2luIH0gZnJvbSAnLi9QYXN0ZVJ1bGUuanMnXG5pbXBvcnQgeyBBbnlDb25maWcsIEV4dGVuc2lvbnMsIFJhd0NvbW1hbmRzIH0gZnJvbSAnLi90eXBlcy5qcydcbmltcG9ydCB7IGNhbGxPclJldHVybiB9IGZyb20gJy4vdXRpbGl0aWVzL2NhbGxPclJldHVybi5qcydcbmltcG9ydCB7IGZpbmREdXBsaWNhdGVzIH0gZnJvbSAnLi91dGlsaXRpZXMvZmluZER1cGxpY2F0ZXMuanMnXG5cbmV4cG9ydCBjbGFzcyBFeHRlbnNpb25NYW5hZ2VyIHtcbiAgZWRpdG9yOiBFZGl0b3JcblxuICBzY2hlbWE6IFNjaGVtYVxuXG4gIGV4dGVuc2lvbnM6IEV4dGVuc2lvbnNcblxuICBzcGxpdHRhYmxlTWFya3M6IHN0cmluZ1tdID0gW11cblxuICBjb25zdHJ1Y3RvcihleHRlbnNpb25zOiBFeHRlbnNpb25zLCBlZGl0b3I6IEVkaXRvcikge1xuICAgIHRoaXMuZWRpdG9yID0gZWRpdG9yXG4gICAgdGhpcy5leHRlbnNpb25zID0gRXh0ZW5zaW9uTWFuYWdlci5yZXNvbHZlKGV4dGVuc2lvbnMpXG4gICAgdGhpcy5zY2hlbWEgPSBnZXRTY2hlbWFCeVJlc29sdmVkRXh0ZW5zaW9ucyh0aGlzLmV4dGVuc2lvbnMsIGVkaXRvcilcbiAgICB0aGlzLnNldHVwRXh0ZW5zaW9ucygpXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhIGZsYXR0ZW5lZCBhbmQgc29ydGVkIGV4dGVuc2lvbiBsaXN0IHdoaWxlXG4gICAqIGFsc28gY2hlY2tpbmcgZm9yIGR1cGxpY2F0ZWQgZXh0ZW5zaW9ucyBhbmQgd2FybnMgdGhlIHVzZXIuXG4gICAqIEBwYXJhbSBleHRlbnNpb25zIEFuIGFycmF5IG9mIFRpcHRhcCBleHRlbnNpb25zXG4gICAqIEByZXR1cm5zIEFuIGZsYXR0ZW5lZCBhbmQgc29ydGVkIGFycmF5IG9mIFRpcHRhcCBleHRlbnNpb25zXG4gICAqL1xuICBzdGF0aWMgcmVzb2x2ZShleHRlbnNpb25zOiBFeHRlbnNpb25zKTogRXh0ZW5zaW9ucyB7XG4gICAgY29uc3QgcmVzb2x2ZWRFeHRlbnNpb25zID0gRXh0ZW5zaW9uTWFuYWdlci5zb3J0KEV4dGVuc2lvbk1hbmFnZXIuZmxhdHRlbihleHRlbnNpb25zKSlcbiAgICBjb25zdCBkdXBsaWNhdGVkTmFtZXMgPSBmaW5kRHVwbGljYXRlcyhyZXNvbHZlZEV4dGVuc2lvbnMubWFwKGV4dGVuc2lvbiA9PiBleHRlbnNpb24ubmFtZSkpXG5cbiAgICBpZiAoZHVwbGljYXRlZE5hbWVzLmxlbmd0aCkge1xuICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICBgW3RpcHRhcCB3YXJuXTogRHVwbGljYXRlIGV4dGVuc2lvbiBuYW1lcyBmb3VuZDogWyR7ZHVwbGljYXRlZE5hbWVzXG4gICAgICAgICAgLm1hcChpdGVtID0+IGAnJHtpdGVtfSdgKVxuICAgICAgICAgIC5qb2luKCcsICcpfV0uIFRoaXMgY2FuIGxlYWQgdG8gaXNzdWVzLmAsXG4gICAgICApXG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc29sdmVkRXh0ZW5zaW9uc1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIGZsYXR0ZW5lZCBhcnJheSBvZiBleHRlbnNpb25zIGJ5IHRyYXZlcnNpbmcgdGhlIGBhZGRFeHRlbnNpb25zYCBmaWVsZC5cbiAgICogQHBhcmFtIGV4dGVuc2lvbnMgQW4gYXJyYXkgb2YgVGlwdGFwIGV4dGVuc2lvbnNcbiAgICogQHJldHVybnMgQSBmbGF0dGVuZWQgYXJyYXkgb2YgVGlwdGFwIGV4dGVuc2lvbnNcbiAgICovXG4gIHN0YXRpYyBmbGF0dGVuKGV4dGVuc2lvbnM6IEV4dGVuc2lvbnMpOiBFeHRlbnNpb25zIHtcbiAgICByZXR1cm4gKFxuICAgICAgZXh0ZW5zaW9uc1xuICAgICAgICAubWFwKGV4dGVuc2lvbiA9PiB7XG4gICAgICAgICAgY29uc3QgY29udGV4dCA9IHtcbiAgICAgICAgICAgIG5hbWU6IGV4dGVuc2lvbi5uYW1lLFxuICAgICAgICAgICAgb3B0aW9uczogZXh0ZW5zaW9uLm9wdGlvbnMsXG4gICAgICAgICAgICBzdG9yYWdlOiBleHRlbnNpb24uc3RvcmFnZSxcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBhZGRFeHRlbnNpb25zID0gZ2V0RXh0ZW5zaW9uRmllbGQ8QW55Q29uZmlnWydhZGRFeHRlbnNpb25zJ10+KFxuICAgICAgICAgICAgZXh0ZW5zaW9uLFxuICAgICAgICAgICAgJ2FkZEV4dGVuc2lvbnMnLFxuICAgICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICApXG5cbiAgICAgICAgICBpZiAoYWRkRXh0ZW5zaW9ucykge1xuICAgICAgICAgICAgcmV0dXJuIFtleHRlbnNpb24sIC4uLnRoaXMuZmxhdHRlbihhZGRFeHRlbnNpb25zKCkpXVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBleHRlbnNpb25cbiAgICAgICAgfSlcbiAgICAgICAgLy8gYEluZmluaXR5YCB3aWxsIGJyZWFrIFR5cGVTY3JpcHQgc28gd2Ugc2V0IGEgbnVtYmVyIHRoYXQgaXMgcHJvYmFibHkgaGlnaCBlbm91Z2hcbiAgICAgICAgLmZsYXQoMTApXG4gICAgKVxuICB9XG5cbiAgLyoqXG4gICAqIFNvcnQgZXh0ZW5zaW9ucyBieSBwcmlvcml0eS5cbiAgICogQHBhcmFtIGV4dGVuc2lvbnMgQW4gYXJyYXkgb2YgVGlwdGFwIGV4dGVuc2lvbnNcbiAgICogQHJldHVybnMgQSBzb3J0ZWQgYXJyYXkgb2YgVGlwdGFwIGV4dGVuc2lvbnMgYnkgcHJpb3JpdHlcbiAgICovXG4gIHN0YXRpYyBzb3J0KGV4dGVuc2lvbnM6IEV4dGVuc2lvbnMpOiBFeHRlbnNpb25zIHtcbiAgICBjb25zdCBkZWZhdWx0UHJpb3JpdHkgPSAxMDBcblxuICAgIHJldHVybiBleHRlbnNpb25zLnNvcnQoKGEsIGIpID0+IHtcbiAgICAgIGNvbnN0IHByaW9yaXR5QSA9IGdldEV4dGVuc2lvbkZpZWxkPEFueUNvbmZpZ1sncHJpb3JpdHknXT4oYSwgJ3ByaW9yaXR5JykgfHwgZGVmYXVsdFByaW9yaXR5XG4gICAgICBjb25zdCBwcmlvcml0eUIgPSBnZXRFeHRlbnNpb25GaWVsZDxBbnlDb25maWdbJ3ByaW9yaXR5J10+KGIsICdwcmlvcml0eScpIHx8IGRlZmF1bHRQcmlvcml0eVxuXG4gICAgICBpZiAocHJpb3JpdHlBID4gcHJpb3JpdHlCKSB7XG4gICAgICAgIHJldHVybiAtMVxuICAgICAgfVxuXG4gICAgICBpZiAocHJpb3JpdHlBIDwgcHJpb3JpdHlCKSB7XG4gICAgICAgIHJldHVybiAxXG4gICAgICB9XG5cbiAgICAgIHJldHVybiAwXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYWxsIGNvbW1hbmRzIGZyb20gdGhlIGV4dGVuc2lvbnMuXG4gICAqIEByZXR1cm5zIEFuIG9iamVjdCB3aXRoIGFsbCBjb21tYW5kcyB3aGVyZSB0aGUga2V5IGlzIHRoZSBjb21tYW5kIG5hbWUgYW5kIHRoZSB2YWx1ZSBpcyB0aGUgY29tbWFuZCBmdW5jdGlvblxuICAgKi9cbiAgZ2V0IGNvbW1hbmRzKCk6IFJhd0NvbW1hbmRzIHtcbiAgICByZXR1cm4gdGhpcy5leHRlbnNpb25zLnJlZHVjZSgoY29tbWFuZHMsIGV4dGVuc2lvbikgPT4ge1xuICAgICAgY29uc3QgY29udGV4dCA9IHtcbiAgICAgICAgbmFtZTogZXh0ZW5zaW9uLm5hbWUsXG4gICAgICAgIG9wdGlvbnM6IGV4dGVuc2lvbi5vcHRpb25zLFxuICAgICAgICBzdG9yYWdlOiBleHRlbnNpb24uc3RvcmFnZSxcbiAgICAgICAgZWRpdG9yOiB0aGlzLmVkaXRvcixcbiAgICAgICAgdHlwZTogZ2V0U2NoZW1hVHlwZUJ5TmFtZShleHRlbnNpb24ubmFtZSwgdGhpcy5zY2hlbWEpLFxuICAgICAgfVxuXG4gICAgICBjb25zdCBhZGRDb21tYW5kcyA9IGdldEV4dGVuc2lvbkZpZWxkPEFueUNvbmZpZ1snYWRkQ29tbWFuZHMnXT4oXG4gICAgICAgIGV4dGVuc2lvbixcbiAgICAgICAgJ2FkZENvbW1hbmRzJyxcbiAgICAgICAgY29udGV4dCxcbiAgICAgIClcblxuICAgICAgaWYgKCFhZGRDb21tYW5kcykge1xuICAgICAgICByZXR1cm4gY29tbWFuZHNcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uY29tbWFuZHMsXG4gICAgICAgIC4uLmFkZENvbW1hbmRzKCksXG4gICAgICB9XG4gICAgfSwge30gYXMgUmF3Q29tbWFuZHMpXG4gIH1cblxuICAvKipcbiAgICogR2V0IGFsbCByZWdpc3RlcmVkIFByb3NlbWlycm9yIHBsdWdpbnMgZnJvbSB0aGUgZXh0ZW5zaW9ucy5cbiAgICogQHJldHVybnMgQW4gYXJyYXkgb2YgUHJvc2VtaXJyb3IgcGx1Z2luc1xuICAgKi9cbiAgZ2V0IHBsdWdpbnMoKTogUGx1Z2luW10ge1xuICAgIGNvbnN0IHsgZWRpdG9yIH0gPSB0aGlzXG5cbiAgICAvLyBXaXRoIFByb3NlTWlycm9yLCBmaXJzdCBwbHVnaW5zIHdpdGhpbiBhbiBhcnJheSBhcmUgZXhlY3V0ZWQgZmlyc3QuXG4gICAgLy8gSW4gVGlwdGFwLCB3ZSBwcm92aWRlIHRoZSBhYmlsaXR5IHRvIG92ZXJyaWRlIHBsdWdpbnMsXG4gICAgLy8gc28gaXQgZmVlbHMgbW9yZSBuYXR1cmFsIHRvIHJ1biBwbHVnaW5zIGF0IHRoZSBlbmQgb2YgYW4gYXJyYXkgZmlyc3QuXG4gICAgLy8gVGhhdOKAmXMgd2h5IHdlIGhhdmUgdG8gcmV2ZXJzZSB0aGUgYGV4dGVuc2lvbnNgIGFycmF5IGFuZCBzb3J0IGFnYWluXG4gICAgLy8gYmFzZWQgb24gdGhlIGBwcmlvcml0eWAgb3B0aW9uLlxuICAgIGNvbnN0IGV4dGVuc2lvbnMgPSBFeHRlbnNpb25NYW5hZ2VyLnNvcnQoWy4uLnRoaXMuZXh0ZW5zaW9uc10ucmV2ZXJzZSgpKVxuXG4gICAgY29uc3QgaW5wdXRSdWxlczogSW5wdXRSdWxlW10gPSBbXVxuICAgIGNvbnN0IHBhc3RlUnVsZXM6IFBhc3RlUnVsZVtdID0gW11cblxuICAgIGNvbnN0IGFsbFBsdWdpbnMgPSBleHRlbnNpb25zXG4gICAgICAubWFwKGV4dGVuc2lvbiA9PiB7XG4gICAgICAgIGNvbnN0IGNvbnRleHQgPSB7XG4gICAgICAgICAgbmFtZTogZXh0ZW5zaW9uLm5hbWUsXG4gICAgICAgICAgb3B0aW9uczogZXh0ZW5zaW9uLm9wdGlvbnMsXG4gICAgICAgICAgc3RvcmFnZTogZXh0ZW5zaW9uLnN0b3JhZ2UsXG4gICAgICAgICAgZWRpdG9yLFxuICAgICAgICAgIHR5cGU6IGdldFNjaGVtYVR5cGVCeU5hbWUoZXh0ZW5zaW9uLm5hbWUsIHRoaXMuc2NoZW1hKSxcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHBsdWdpbnM6IFBsdWdpbltdID0gW11cblxuICAgICAgICBjb25zdCBhZGRLZXlib2FyZFNob3J0Y3V0cyA9IGdldEV4dGVuc2lvbkZpZWxkPEFueUNvbmZpZ1snYWRkS2V5Ym9hcmRTaG9ydGN1dHMnXT4oXG4gICAgICAgICAgZXh0ZW5zaW9uLFxuICAgICAgICAgICdhZGRLZXlib2FyZFNob3J0Y3V0cycsXG4gICAgICAgICAgY29udGV4dCxcbiAgICAgICAgKVxuXG4gICAgICAgIGxldCBkZWZhdWx0QmluZGluZ3M6IFJlY29yZDxzdHJpbmcsICgpID0+IGJvb2xlYW4+ID0ge31cblxuICAgICAgICAvLyBiaW5kIGV4aXQgaGFuZGxpbmdcbiAgICAgICAgaWYgKGV4dGVuc2lvbi50eXBlID09PSAnbWFyaycgJiYgZ2V0RXh0ZW5zaW9uRmllbGQ8QW55Q29uZmlnWydleGl0YWJsZSddPihleHRlbnNpb24sICdleGl0YWJsZScsIGNvbnRleHQpKSB7XG4gICAgICAgICAgZGVmYXVsdEJpbmRpbmdzLkFycm93UmlnaHQgPSAoKSA9PiBNYXJrLmhhbmRsZUV4aXQoeyBlZGl0b3IsIG1hcms6IGV4dGVuc2lvbiBhcyBNYXJrIH0pXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYWRkS2V5Ym9hcmRTaG9ydGN1dHMpIHtcbiAgICAgICAgICBjb25zdCBiaW5kaW5ncyA9IE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgICAgICAgIE9iamVjdC5lbnRyaWVzKGFkZEtleWJvYXJkU2hvcnRjdXRzKCkpLm1hcCgoW3Nob3J0Y3V0LCBtZXRob2RdKSA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBbc2hvcnRjdXQsICgpID0+IG1ldGhvZCh7IGVkaXRvciB9KV1cbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgIClcblxuICAgICAgICAgIGRlZmF1bHRCaW5kaW5ncyA9IHsgLi4uZGVmYXVsdEJpbmRpbmdzLCAuLi5iaW5kaW5ncyB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBrZXlNYXBQbHVnaW4gPSBrZXltYXAoZGVmYXVsdEJpbmRpbmdzKVxuXG4gICAgICAgIHBsdWdpbnMucHVzaChrZXlNYXBQbHVnaW4pXG5cbiAgICAgICAgY29uc3QgYWRkSW5wdXRSdWxlcyA9IGdldEV4dGVuc2lvbkZpZWxkPEFueUNvbmZpZ1snYWRkSW5wdXRSdWxlcyddPihcbiAgICAgICAgICBleHRlbnNpb24sXG4gICAgICAgICAgJ2FkZElucHV0UnVsZXMnLFxuICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgIClcblxuICAgICAgICBpZiAoaXNFeHRlbnNpb25SdWxlc0VuYWJsZWQoZXh0ZW5zaW9uLCBlZGl0b3Iub3B0aW9ucy5lbmFibGVJbnB1dFJ1bGVzKSAmJiBhZGRJbnB1dFJ1bGVzKSB7XG4gICAgICAgICAgaW5wdXRSdWxlcy5wdXNoKC4uLmFkZElucHV0UnVsZXMoKSlcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGFkZFBhc3RlUnVsZXMgPSBnZXRFeHRlbnNpb25GaWVsZDxBbnlDb25maWdbJ2FkZFBhc3RlUnVsZXMnXT4oXG4gICAgICAgICAgZXh0ZW5zaW9uLFxuICAgICAgICAgICdhZGRQYXN0ZVJ1bGVzJyxcbiAgICAgICAgICBjb250ZXh0LFxuICAgICAgICApXG5cbiAgICAgICAgaWYgKGlzRXh0ZW5zaW9uUnVsZXNFbmFibGVkKGV4dGVuc2lvbiwgZWRpdG9yLm9wdGlvbnMuZW5hYmxlUGFzdGVSdWxlcykgJiYgYWRkUGFzdGVSdWxlcykge1xuICAgICAgICAgIHBhc3RlUnVsZXMucHVzaCguLi5hZGRQYXN0ZVJ1bGVzKCkpXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBhZGRQcm9zZU1pcnJvclBsdWdpbnMgPSBnZXRFeHRlbnNpb25GaWVsZDxBbnlDb25maWdbJ2FkZFByb3NlTWlycm9yUGx1Z2lucyddPihcbiAgICAgICAgICBleHRlbnNpb24sXG4gICAgICAgICAgJ2FkZFByb3NlTWlycm9yUGx1Z2lucycsXG4gICAgICAgICAgY29udGV4dCxcbiAgICAgICAgKVxuXG4gICAgICAgIGlmIChhZGRQcm9zZU1pcnJvclBsdWdpbnMpIHtcbiAgICAgICAgICBjb25zdCBwcm9zZU1pcnJvclBsdWdpbnMgPSBhZGRQcm9zZU1pcnJvclBsdWdpbnMoKVxuXG4gICAgICAgICAgcGx1Z2lucy5wdXNoKC4uLnByb3NlTWlycm9yUGx1Z2lucylcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBwbHVnaW5zXG4gICAgICB9KVxuICAgICAgLmZsYXQoKVxuXG4gICAgcmV0dXJuIFtcbiAgICAgIGlucHV0UnVsZXNQbHVnaW4oe1xuICAgICAgICBlZGl0b3IsXG4gICAgICAgIHJ1bGVzOiBpbnB1dFJ1bGVzLFxuICAgICAgfSksXG4gICAgICAuLi5wYXN0ZVJ1bGVzUGx1Z2luKHtcbiAgICAgICAgZWRpdG9yLFxuICAgICAgICBydWxlczogcGFzdGVSdWxlcyxcbiAgICAgIH0pLFxuICAgICAgLi4uYWxsUGx1Z2lucyxcbiAgICBdXG4gIH1cblxuICAvKipcbiAgICogR2V0IGFsbCBhdHRyaWJ1dGVzIGZyb20gdGhlIGV4dGVuc2lvbnMuXG4gICAqIEByZXR1cm5zIEFuIGFycmF5IG9mIGF0dHJpYnV0ZXNcbiAgICovXG4gIGdldCBhdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBnZXRBdHRyaWJ1dGVzRnJvbUV4dGVuc2lvbnModGhpcy5leHRlbnNpb25zKVxuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhbGwgbm9kZSB2aWV3cyBmcm9tIHRoZSBleHRlbnNpb25zLlxuICAgKiBAcmV0dXJucyBBbiBvYmplY3Qgd2l0aCBhbGwgbm9kZSB2aWV3cyB3aGVyZSB0aGUga2V5IGlzIHRoZSBub2RlIG5hbWUgYW5kIHRoZSB2YWx1ZSBpcyB0aGUgbm9kZSB2aWV3IGZ1bmN0aW9uXG4gICAqL1xuICBnZXQgbm9kZVZpZXdzKCk6IFJlY29yZDxzdHJpbmcsIE5vZGVWaWV3Q29uc3RydWN0b3I+IHtcbiAgICBjb25zdCB7IGVkaXRvciB9ID0gdGhpc1xuICAgIGNvbnN0IHsgbm9kZUV4dGVuc2lvbnMgfSA9IHNwbGl0RXh0ZW5zaW9ucyh0aGlzLmV4dGVuc2lvbnMpXG5cbiAgICByZXR1cm4gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgbm9kZUV4dGVuc2lvbnNcbiAgICAgICAgLmZpbHRlcihleHRlbnNpb24gPT4gISFnZXRFeHRlbnNpb25GaWVsZChleHRlbnNpb24sICdhZGROb2RlVmlldycpKVxuICAgICAgICAubWFwKGV4dGVuc2lvbiA9PiB7XG4gICAgICAgICAgY29uc3QgZXh0ZW5zaW9uQXR0cmlidXRlcyA9IHRoaXMuYXR0cmlidXRlcy5maWx0ZXIoXG4gICAgICAgICAgICBhdHRyaWJ1dGUgPT4gYXR0cmlidXRlLnR5cGUgPT09IGV4dGVuc2lvbi5uYW1lLFxuICAgICAgICAgIClcbiAgICAgICAgICBjb25zdCBjb250ZXh0ID0ge1xuICAgICAgICAgICAgbmFtZTogZXh0ZW5zaW9uLm5hbWUsXG4gICAgICAgICAgICBvcHRpb25zOiBleHRlbnNpb24ub3B0aW9ucyxcbiAgICAgICAgICAgIHN0b3JhZ2U6IGV4dGVuc2lvbi5zdG9yYWdlLFxuICAgICAgICAgICAgZWRpdG9yLFxuICAgICAgICAgICAgdHlwZTogZ2V0Tm9kZVR5cGUoZXh0ZW5zaW9uLm5hbWUsIHRoaXMuc2NoZW1hKSxcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgYWRkTm9kZVZpZXcgPSBnZXRFeHRlbnNpb25GaWVsZDxOb2RlQ29uZmlnWydhZGROb2RlVmlldyddPihcbiAgICAgICAgICAgIGV4dGVuc2lvbixcbiAgICAgICAgICAgICdhZGROb2RlVmlldycsXG4gICAgICAgICAgICBjb250ZXh0LFxuICAgICAgICAgIClcblxuICAgICAgICAgIGlmICghYWRkTm9kZVZpZXcpIHtcbiAgICAgICAgICAgIHJldHVybiBbXVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IG5vZGV2aWV3OiBOb2RlVmlld0NvbnN0cnVjdG9yID0gKFxuICAgICAgICAgICAgbm9kZSxcbiAgICAgICAgICAgIHZpZXcsXG4gICAgICAgICAgICBnZXRQb3MsXG4gICAgICAgICAgICBkZWNvcmF0aW9ucyxcbiAgICAgICAgICAgIGlubmVyRGVjb3JhdGlvbnMsXG4gICAgICAgICAgKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBIVE1MQXR0cmlidXRlcyA9IGdldFJlbmRlcmVkQXR0cmlidXRlcyhub2RlLCBleHRlbnNpb25BdHRyaWJ1dGVzKVxuXG4gICAgICAgICAgICByZXR1cm4gYWRkTm9kZVZpZXcoKSh7XG4gICAgICAgICAgICAgIC8vIHBhc3MtdGhyb3VnaFxuICAgICAgICAgICAgICBub2RlLFxuICAgICAgICAgICAgICB2aWV3LFxuICAgICAgICAgICAgICBnZXRQb3M6IGdldFBvcyBhcyAoKSA9PiBudW1iZXIsXG4gICAgICAgICAgICAgIGRlY29yYXRpb25zLFxuICAgICAgICAgICAgICBpbm5lckRlY29yYXRpb25zLFxuICAgICAgICAgICAgICAvLyB0aXB0YXAtc3BlY2lmaWNcbiAgICAgICAgICAgICAgZWRpdG9yLFxuICAgICAgICAgICAgICBleHRlbnNpb24sXG4gICAgICAgICAgICAgIEhUTUxBdHRyaWJ1dGVzLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gW2V4dGVuc2lvbi5uYW1lLCBub2Rldmlld11cbiAgICAgICAgfSksXG4gICAgKVxuICB9XG5cbiAgLyoqXG4gICAqIEdvIHRocm91Z2ggYWxsIGV4dGVuc2lvbnMsIGNyZWF0ZSBleHRlbnNpb24gc3RvcmFnZXMgJiBzZXR1cCBtYXJrc1xuICAgKiAmIGJpbmQgZWRpdG9yIGV2ZW50IGxpc3RlbmVyLlxuICAgKi9cbiAgcHJpdmF0ZSBzZXR1cEV4dGVuc2lvbnMoKSB7XG4gICAgdGhpcy5leHRlbnNpb25zLmZvckVhY2goZXh0ZW5zaW9uID0+IHtcbiAgICAgIC8vIHN0b3JlIGV4dGVuc2lvbiBzdG9yYWdlIGluIGVkaXRvclxuICAgICAgdGhpcy5lZGl0b3IuZXh0ZW5zaW9uU3RvcmFnZVtleHRlbnNpb24ubmFtZV0gPSBleHRlbnNpb24uc3RvcmFnZVxuXG4gICAgICBjb25zdCBjb250ZXh0ID0ge1xuICAgICAgICBuYW1lOiBleHRlbnNpb24ubmFtZSxcbiAgICAgICAgb3B0aW9uczogZXh0ZW5zaW9uLm9wdGlvbnMsXG4gICAgICAgIHN0b3JhZ2U6IGV4dGVuc2lvbi5zdG9yYWdlLFxuICAgICAgICBlZGl0b3I6IHRoaXMuZWRpdG9yLFxuICAgICAgICB0eXBlOiBnZXRTY2hlbWFUeXBlQnlOYW1lKGV4dGVuc2lvbi5uYW1lLCB0aGlzLnNjaGVtYSksXG4gICAgICB9XG5cbiAgICAgIGlmIChleHRlbnNpb24udHlwZSA9PT0gJ21hcmsnKSB7XG4gICAgICAgIGNvbnN0IGtlZXBPblNwbGl0ID0gY2FsbE9yUmV0dXJuKGdldEV4dGVuc2lvbkZpZWxkKGV4dGVuc2lvbiwgJ2tlZXBPblNwbGl0JywgY29udGV4dCkpID8/IHRydWVcblxuICAgICAgICBpZiAoa2VlcE9uU3BsaXQpIHtcbiAgICAgICAgICB0aGlzLnNwbGl0dGFibGVNYXJrcy5wdXNoKGV4dGVuc2lvbi5uYW1lKVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG9uQmVmb3JlQ3JlYXRlID0gZ2V0RXh0ZW5zaW9uRmllbGQ8QW55Q29uZmlnWydvbkJlZm9yZUNyZWF0ZSddPihcbiAgICAgICAgZXh0ZW5zaW9uLFxuICAgICAgICAnb25CZWZvcmVDcmVhdGUnLFxuICAgICAgICBjb250ZXh0LFxuICAgICAgKVxuICAgICAgY29uc3Qgb25DcmVhdGUgPSBnZXRFeHRlbnNpb25GaWVsZDxBbnlDb25maWdbJ29uQ3JlYXRlJ10+KGV4dGVuc2lvbiwgJ29uQ3JlYXRlJywgY29udGV4dClcbiAgICAgIGNvbnN0IG9uVXBkYXRlID0gZ2V0RXh0ZW5zaW9uRmllbGQ8QW55Q29uZmlnWydvblVwZGF0ZSddPihleHRlbnNpb24sICdvblVwZGF0ZScsIGNvbnRleHQpXG4gICAgICBjb25zdCBvblNlbGVjdGlvblVwZGF0ZSA9IGdldEV4dGVuc2lvbkZpZWxkPEFueUNvbmZpZ1snb25TZWxlY3Rpb25VcGRhdGUnXT4oXG4gICAgICAgIGV4dGVuc2lvbixcbiAgICAgICAgJ29uU2VsZWN0aW9uVXBkYXRlJyxcbiAgICAgICAgY29udGV4dCxcbiAgICAgIClcbiAgICAgIGNvbnN0IG9uVHJhbnNhY3Rpb24gPSBnZXRFeHRlbnNpb25GaWVsZDxBbnlDb25maWdbJ29uVHJhbnNhY3Rpb24nXT4oXG4gICAgICAgIGV4dGVuc2lvbixcbiAgICAgICAgJ29uVHJhbnNhY3Rpb24nLFxuICAgICAgICBjb250ZXh0LFxuICAgICAgKVxuICAgICAgY29uc3Qgb25Gb2N1cyA9IGdldEV4dGVuc2lvbkZpZWxkPEFueUNvbmZpZ1snb25Gb2N1cyddPihleHRlbnNpb24sICdvbkZvY3VzJywgY29udGV4dClcbiAgICAgIGNvbnN0IG9uQmx1ciA9IGdldEV4dGVuc2lvbkZpZWxkPEFueUNvbmZpZ1snb25CbHVyJ10+KGV4dGVuc2lvbiwgJ29uQmx1cicsIGNvbnRleHQpXG4gICAgICBjb25zdCBvbkRlc3Ryb3kgPSBnZXRFeHRlbnNpb25GaWVsZDxBbnlDb25maWdbJ29uRGVzdHJveSddPihleHRlbnNpb24sICdvbkRlc3Ryb3knLCBjb250ZXh0KVxuXG4gICAgICBpZiAob25CZWZvcmVDcmVhdGUpIHtcbiAgICAgICAgdGhpcy5lZGl0b3Iub24oJ2JlZm9yZUNyZWF0ZScsIG9uQmVmb3JlQ3JlYXRlKVxuICAgICAgfVxuXG4gICAgICBpZiAob25DcmVhdGUpIHtcbiAgICAgICAgdGhpcy5lZGl0b3Iub24oJ2NyZWF0ZScsIG9uQ3JlYXRlKVxuICAgICAgfVxuXG4gICAgICBpZiAob25VcGRhdGUpIHtcbiAgICAgICAgdGhpcy5lZGl0b3Iub24oJ3VwZGF0ZScsIG9uVXBkYXRlKVxuICAgICAgfVxuXG4gICAgICBpZiAob25TZWxlY3Rpb25VcGRhdGUpIHtcbiAgICAgICAgdGhpcy5lZGl0b3Iub24oJ3NlbGVjdGlvblVwZGF0ZScsIG9uU2VsZWN0aW9uVXBkYXRlKVxuICAgICAgfVxuXG4gICAgICBpZiAob25UcmFuc2FjdGlvbikge1xuICAgICAgICB0aGlzLmVkaXRvci5vbigndHJhbnNhY3Rpb24nLCBvblRyYW5zYWN0aW9uKVxuICAgICAgfVxuXG4gICAgICBpZiAob25Gb2N1cykge1xuICAgICAgICB0aGlzLmVkaXRvci5vbignZm9jdXMnLCBvbkZvY3VzKVxuICAgICAgfVxuXG4gICAgICBpZiAob25CbHVyKSB7XG4gICAgICAgIHRoaXMuZWRpdG9yLm9uKCdibHVyJywgb25CbHVyKVxuICAgICAgfVxuXG4gICAgICBpZiAob25EZXN0cm95KSB7XG4gICAgICAgIHRoaXMuZWRpdG9yLm9uKCdkZXN0cm95Jywgb25EZXN0cm95KVxuICAgICAgfVxuICAgIH0pXG4gIH1cbn1cbiIsICJpbXBvcnQgeyBQbHVnaW4sIFRyYW5zYWN0aW9uIH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcblxuaW1wb3J0IHsgRWRpdG9yIH0gZnJvbSAnLi9FZGl0b3IuanMnXG5pbXBvcnQgeyBnZXRFeHRlbnNpb25GaWVsZCB9IGZyb20gJy4vaGVscGVycy9nZXRFeHRlbnNpb25GaWVsZC5qcydcbmltcG9ydCB7IEV4dGVuc2lvbkNvbmZpZyB9IGZyb20gJy4vaW5kZXguanMnXG5pbXBvcnQgeyBJbnB1dFJ1bGUgfSBmcm9tICcuL0lucHV0UnVsZS5qcydcbmltcG9ydCB7IE1hcmsgfSBmcm9tICcuL01hcmsuanMnXG5pbXBvcnQgeyBOb2RlIH0gZnJvbSAnLi9Ob2RlLmpzJ1xuaW1wb3J0IHsgUGFzdGVSdWxlIH0gZnJvbSAnLi9QYXN0ZVJ1bGUuanMnXG5pbXBvcnQge1xuICBBbnlDb25maWcsXG4gIEV4dGVuc2lvbnMsXG4gIEdsb2JhbEF0dHJpYnV0ZXMsXG4gIEtleWJvYXJkU2hvcnRjdXRDb21tYW5kLFxuICBQYXJlbnRDb25maWcsXG4gIFJhd0NvbW1hbmRzLFxufSBmcm9tICcuL3R5cGVzLmpzJ1xuaW1wb3J0IHsgY2FsbE9yUmV0dXJuIH0gZnJvbSAnLi91dGlsaXRpZXMvY2FsbE9yUmV0dXJuLmpzJ1xuaW1wb3J0IHsgbWVyZ2VEZWVwIH0gZnJvbSAnLi91dGlsaXRpZXMvbWVyZ2VEZWVwLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBFeHRlbnNpb25Db25maWc8T3B0aW9ucyA9IGFueSwgU3RvcmFnZSA9IGFueT4ge1xuICAgIC8vIEB0cy1pZ25vcmUgLSB0aGlzIGlzIGEgZHluYW1pYyBrZXlcbiAgICBba2V5OiBzdHJpbmddOiBhbnlcblxuICAgIC8qKlxuICAgICAqIFRoZSBleHRlbnNpb24gbmFtZSAtIHRoaXMgbXVzdCBiZSB1bmlxdWUuXG4gICAgICogSXQgd2lsbCBiZSB1c2VkIHRvIGlkZW50aWZ5IHRoZSBleHRlbnNpb24uXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZSAnbXlFeHRlbnNpb24nXG4gICAgICovXG4gICAgbmFtZTogc3RyaW5nXG5cbiAgICAvKipcbiAgICAgKiBUaGUgcHJpb3JpdHkgb2YgeW91ciBleHRlbnNpb24uIFRoZSBoaWdoZXIsIHRoZSBlYXJsaWVyIGl0IHdpbGwgYmUgY2FsbGVkXG4gICAgICogYW5kIHdpbGwgdGFrZSBwcmVjZWRlbmNlIG92ZXIgb3RoZXIgZXh0ZW5zaW9ucyB3aXRoIGEgbG93ZXIgcHJpb3JpdHkuXG4gICAgICogQGRlZmF1bHQgMTAwXG4gICAgICogQGV4YW1wbGUgMTAxXG4gICAgICovXG4gICAgcHJpb3JpdHk/OiBudW1iZXJcblxuICAgIC8qKlxuICAgICAqIFRoZSBkZWZhdWx0IG9wdGlvbnMgZm9yIHRoaXMgZXh0ZW5zaW9uLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogZGVmYXVsdE9wdGlvbnM6IHtcbiAgICAgKiAgIG15T3B0aW9uOiAnZm9vJyxcbiAgICAgKiAgIG15T3RoZXJPcHRpb246IDEwLFxuICAgICAqIH1cbiAgICAgKi9cbiAgICBkZWZhdWx0T3B0aW9ucz86IE9wdGlvbnNcblxuICAgIC8qKlxuICAgICAqIFRoaXMgbWV0aG9kIHdpbGwgYWRkIG9wdGlvbnMgdG8gdGhpcyBleHRlbnNpb25cbiAgICAgKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9kb2NzL2VkaXRvci9ndWlkZS9jdXN0b20tZXh0ZW5zaW9ucyNzZXR0aW5nc1xuICAgICAqIEBleGFtcGxlXG4gICAgICogYWRkT3B0aW9ucygpIHtcbiAgICAgKiAgcmV0dXJuIHtcbiAgICAgKiAgICBteU9wdGlvbjogJ2ZvbycsXG4gICAgICogICAgbXlPdGhlck9wdGlvbjogMTAsXG4gICAgICogfVxuICAgICAqL1xuICAgIGFkZE9wdGlvbnM/OiAodGhpczoge1xuICAgICAgbmFtZTogc3RyaW5nXG4gICAgICBwYXJlbnQ6IEV4Y2x1ZGU8UGFyZW50Q29uZmlnPEV4dGVuc2lvbkNvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ2FkZE9wdGlvbnMnXSwgdW5kZWZpbmVkPlxuICAgIH0pID0+IE9wdGlvbnNcblxuICAgIC8qKlxuICAgICAqIFRoZSBkZWZhdWx0IHN0b3JhZ2UgdGhpcyBleHRlbnNpb24gY2FuIHNhdmUgZGF0YSB0by5cbiAgICAgKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9kb2NzL2VkaXRvci9ndWlkZS9jdXN0b20tZXh0ZW5zaW9ucyNzdG9yYWdlXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBkZWZhdWx0U3RvcmFnZToge1xuICAgICAqICAgcHJlZmV0Y2hlZFVzZXJzOiBbXSxcbiAgICAgKiAgIGxvYWRpbmc6IGZhbHNlLFxuICAgICAqIH1cbiAgICAgKi9cbiAgICBhZGRTdG9yYWdlPzogKHRoaXM6IHtcbiAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgcGFyZW50OiBFeGNsdWRlPFBhcmVudENvbmZpZzxFeHRlbnNpb25Db25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydhZGRTdG9yYWdlJ10sIHVuZGVmaW5lZD5cbiAgICB9KSA9PiBTdG9yYWdlXG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGFkZHMgZ2xvYmFsQXR0cmlidXRlcyB0byBzcGVjaWZpYyBub2Rlcy5cbiAgICAgKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9kb2NzL2VkaXRvci9ndWlkZS9jdXN0b20tZXh0ZW5zaW9ucyNnbG9iYWwtYXR0cmlidXRlc1xuICAgICAqIEBleGFtcGxlXG4gICAgICogYWRkR2xvYmFsQXR0cmlidXRlcygpIHtcbiAgICAgKiAgIHJldHVybiBbXG4gICAgICogICAgIHtcbiAgICAgICAgICAgICAvLyBFeHRlbmQgdGhlIGZvbGxvd2luZyBleHRlbnNpb25zXG4gICAgICogICAgICAgdHlwZXM6IFtcbiAgICAgKiAgICAgICAgICdoZWFkaW5nJyxcbiAgICAgKiAgICAgICAgICdwYXJhZ3JhcGgnLFxuICAgICAqICAgICAgIF0sXG4gICAgICogICAgICAgLy8g4oCmIHdpdGggdGhvc2UgYXR0cmlidXRlc1xuICAgICAqICAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgKiAgICAgICAgIHRleHRBbGlnbjoge1xuICAgICAqICAgICAgICAgICBkZWZhdWx0OiAnbGVmdCcsXG4gICAgICogICAgICAgICAgIHJlbmRlckhUTUw6IGF0dHJpYnV0ZXMgPT4gKHtcbiAgICAgKiAgICAgICAgICAgICBzdHlsZTogYHRleHQtYWxpZ246ICR7YXR0cmlidXRlcy50ZXh0QWxpZ259YCxcbiAgICAgKiAgICAgICAgICAgfSksXG4gICAgICogICAgICAgICAgIHBhcnNlSFRNTDogZWxlbWVudCA9PiBlbGVtZW50LnN0eWxlLnRleHRBbGlnbiB8fCAnbGVmdCcsXG4gICAgICogICAgICAgICB9LFxuICAgICAqICAgICAgIH0sXG4gICAgICogICAgIH0sXG4gICAgICogICBdXG4gICAgICogfVxuICAgICAqL1xuICAgIGFkZEdsb2JhbEF0dHJpYnV0ZXM/OiAodGhpczoge1xuICAgICAgbmFtZTogc3RyaW5nXG4gICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICBleHRlbnNpb25zOiAoTm9kZSB8IE1hcmspW11cbiAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPEV4dGVuc2lvbkNvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ2FkZEdsb2JhbEF0dHJpYnV0ZXMnXVxuICAgIH0pID0+IEdsb2JhbEF0dHJpYnV0ZXNcblxuICAgIC8qKlxuICAgICAqIFRoaXMgZnVuY3Rpb24gYWRkcyBjb21tYW5kcyB0byB0aGUgZWRpdG9yXG4gICAgICogQHNlZSBodHRwczovL3RpcHRhcC5kZXYvZG9jcy9lZGl0b3IvZ3VpZGUvY3VzdG9tLWV4dGVuc2lvbnMjY29tbWFuZHNcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGFkZENvbW1hbmRzKCkge1xuICAgICAqICAgcmV0dXJuIHtcbiAgICAgKiAgICAgbXlDb21tYW5kOiAoKSA9PiAoeyBjaGFpbiB9KSA9PiBjaGFpbigpLnNldE1hcmsoJ3R5cGUnLCAnZm9vJykucnVuKCksXG4gICAgICogICB9XG4gICAgICogfVxuICAgICAqL1xuICAgIGFkZENvbW1hbmRzPzogKHRoaXM6IHtcbiAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgZWRpdG9yOiBFZGl0b3JcbiAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPEV4dGVuc2lvbkNvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ2FkZENvbW1hbmRzJ11cbiAgICB9KSA9PiBQYXJ0aWFsPFJhd0NvbW1hbmRzPlxuXG4gICAgLyoqXG4gICAgICogVGhpcyBmdW5jdGlvbiByZWdpc3RlcnMga2V5Ym9hcmQgc2hvcnRjdXRzLlxuICAgICAqIEBzZWUgaHR0cHM6Ly90aXB0YXAuZGV2L2RvY3MvZWRpdG9yL2d1aWRlL2N1c3RvbS1leHRlbnNpb25zI2tleWJvYXJkLXNob3J0Y3V0c1xuICAgICAqIEBleGFtcGxlXG4gICAgICogYWRkS2V5Ym9hcmRTaG9ydGN1dHMoKSB7XG4gICAgICogICByZXR1cm4ge1xuICAgICAqICAgICAnTW9kLWwnOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy50b2dnbGVCdWxsZXRMaXN0KCksXG4gICAgICogICB9XG4gICAgICogfSxcbiAgICAgKi9cbiAgICBhZGRLZXlib2FyZFNob3J0Y3V0cz86ICh0aGlzOiB7XG4gICAgICBuYW1lOiBzdHJpbmdcbiAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgIGVkaXRvcjogRWRpdG9yXG4gICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxFeHRlbnNpb25Db25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydhZGRLZXlib2FyZFNob3J0Y3V0cyddXG4gICAgfSkgPT4ge1xuICAgICAgW2tleTogc3RyaW5nXTogS2V5Ym9hcmRTaG9ydGN1dENvbW1hbmRcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGFkZHMgaW5wdXQgcnVsZXMgdG8gdGhlIGVkaXRvci5cbiAgICAgKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9kb2NzL2VkaXRvci9ndWlkZS9jdXN0b20tZXh0ZW5zaW9ucyNpbnB1dC1ydWxlc1xuICAgICAqIEBleGFtcGxlXG4gICAgICogYWRkSW5wdXRSdWxlcygpIHtcbiAgICAgKiAgIHJldHVybiBbXG4gICAgICogICAgIG1hcmtJbnB1dFJ1bGUoe1xuICAgICAqICAgICAgIGZpbmQ6IGlucHV0UmVnZXgsXG4gICAgICogICAgICAgdHlwZTogdGhpcy50eXBlLFxuICAgICAqICAgICB9KSxcbiAgICAgKiAgIF1cbiAgICAgKiB9LFxuICAgICAqL1xuICAgIGFkZElucHV0UnVsZXM/OiAodGhpczoge1xuICAgICAgbmFtZTogc3RyaW5nXG4gICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICBlZGl0b3I6IEVkaXRvclxuICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8RXh0ZW5zaW9uQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsnYWRkSW5wdXRSdWxlcyddXG4gICAgfSkgPT4gSW5wdXRSdWxlW11cblxuICAgIC8qKlxuICAgICAqIFRoaXMgZnVuY3Rpb24gYWRkcyBwYXN0ZSBydWxlcyB0byB0aGUgZWRpdG9yLlxuICAgICAqIEBzZWUgaHR0cHM6Ly90aXB0YXAuZGV2L2RvY3MvZWRpdG9yL2d1aWRlL2N1c3RvbS1leHRlbnNpb25zI3Bhc3RlLXJ1bGVzXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBhZGRQYXN0ZVJ1bGVzKCkge1xuICAgICAqICAgcmV0dXJuIFtcbiAgICAgKiAgICAgbWFya1Bhc3RlUnVsZSh7XG4gICAgICogICAgICAgZmluZDogcGFzdGVSZWdleCxcbiAgICAgKiAgICAgICB0eXBlOiB0aGlzLnR5cGUsXG4gICAgICogICAgIH0pLFxuICAgICAqICAgXVxuICAgICAqIH0sXG4gICAgICovXG4gICAgYWRkUGFzdGVSdWxlcz86ICh0aGlzOiB7XG4gICAgICBuYW1lOiBzdHJpbmdcbiAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgIGVkaXRvcjogRWRpdG9yXG4gICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxFeHRlbnNpb25Db25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydhZGRQYXN0ZVJ1bGVzJ11cbiAgICB9KSA9PiBQYXN0ZVJ1bGVbXVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBmdW5jdGlvbiBhZGRzIFByb3NlbWlycm9yIHBsdWdpbnMgdG8gdGhlIGVkaXRvclxuICAgICAqIEBzZWUgaHR0cHM6Ly90aXB0YXAuZGV2L2RvY3MvZWRpdG9yL2d1aWRlL2N1c3RvbS1leHRlbnNpb25zI3Byb3NlbWlycm9yLXBsdWdpbnNcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGFkZFByb3NlTWlycm9yUGx1Z2lucygpIHtcbiAgICAgKiAgIHJldHVybiBbXG4gICAgICogICAgIGN1c3RvbVBsdWdpbigpLFxuICAgICAqICAgXVxuICAgICAqIH1cbiAgICAgKi9cbiAgICBhZGRQcm9zZU1pcnJvclBsdWdpbnM/OiAodGhpczoge1xuICAgICAgbmFtZTogc3RyaW5nXG4gICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICBlZGl0b3I6IEVkaXRvclxuICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8RXh0ZW5zaW9uQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsnYWRkUHJvc2VNaXJyb3JQbHVnaW5zJ11cbiAgICB9KSA9PiBQbHVnaW5bXVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBmdW5jdGlvbiBhZGRzIGFkZGl0aW9uYWwgZXh0ZW5zaW9ucyB0byB0aGUgZWRpdG9yLiBUaGlzIGlzIHVzZWZ1bCBmb3JcbiAgICAgKiBidWlsZGluZyBleHRlbnNpb24ga2l0cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGFkZEV4dGVuc2lvbnMoKSB7XG4gICAgICogICByZXR1cm4gW1xuICAgICAqICAgICBCdWxsZXRMaXN0LFxuICAgICAqICAgICBPcmRlcmVkTGlzdCxcbiAgICAgKiAgICAgTGlzdEl0ZW1cbiAgICAgKiAgIF1cbiAgICAgKiB9XG4gICAgICovXG4gICAgYWRkRXh0ZW5zaW9ucz86ICh0aGlzOiB7XG4gICAgICBuYW1lOiBzdHJpbmdcbiAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPEV4dGVuc2lvbkNvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ2FkZEV4dGVuc2lvbnMnXVxuICAgIH0pID0+IEV4dGVuc2lvbnNcblxuICAgIC8qKlxuICAgICAqIFRoaXMgZnVuY3Rpb24gZXh0ZW5kcyB0aGUgc2NoZW1hIG9mIHRoZSBub2RlLlxuICAgICAqIEBleGFtcGxlXG4gICAgICogZXh0ZW5kTm9kZVNjaGVtYSgpIHtcbiAgICAgKiAgIHJldHVybiB7XG4gICAgICogICAgIGdyb3VwOiAnaW5saW5lJyxcbiAgICAgKiAgICAgc2VsZWN0YWJsZTogZmFsc2UsXG4gICAgICogICB9XG4gICAgICogfVxuICAgICAqL1xuICAgIGV4dGVuZE5vZGVTY2hlbWE/OlxuICAgICAgfCAoKFxuICAgICAgICAgIHRoaXM6IHtcbiAgICAgICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8RXh0ZW5zaW9uQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsnZXh0ZW5kTm9kZVNjaGVtYSddXG4gICAgICAgICAgfSxcbiAgICAgICAgICBleHRlbnNpb246IE5vZGUsXG4gICAgICAgICkgPT4gUmVjb3JkPHN0cmluZywgYW55PilcbiAgICAgIHwgbnVsbFxuXG4gICAgLyoqXG4gICAgICogVGhpcyBmdW5jdGlvbiBleHRlbmRzIHRoZSBzY2hlbWEgb2YgdGhlIG1hcmsuXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBleHRlbmRNYXJrU2NoZW1hKCkge1xuICAgICAqICAgcmV0dXJuIHtcbiAgICAgKiAgICAgZ3JvdXA6ICdpbmxpbmUnLFxuICAgICAqICAgICBzZWxlY3RhYmxlOiBmYWxzZSxcbiAgICAgKiAgIH1cbiAgICAgKiB9XG4gICAgICovXG4gICAgZXh0ZW5kTWFya1NjaGVtYT86XG4gICAgICB8ICgoXG4gICAgICAgICAgdGhpczoge1xuICAgICAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICAgICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxFeHRlbnNpb25Db25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydleHRlbmRNYXJrU2NoZW1hJ11cbiAgICAgICAgICB9LFxuICAgICAgICAgIGV4dGVuc2lvbjogTWFyayxcbiAgICAgICAgKSA9PiBSZWNvcmQ8c3RyaW5nLCBhbnk+KVxuICAgICAgfCBudWxsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgZWRpdG9yIGlzIG5vdCByZWFkeSB5ZXQuXG4gICAgICovXG4gICAgb25CZWZvcmVDcmVhdGU/OlxuICAgICAgfCAoKHRoaXM6IHtcbiAgICAgICAgICBuYW1lOiBzdHJpbmdcbiAgICAgICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgICAgIGVkaXRvcjogRWRpdG9yXG4gICAgICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8RXh0ZW5zaW9uQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+Plsnb25CZWZvcmVDcmVhdGUnXVxuICAgICAgICB9KSA9PiB2b2lkKVxuICAgICAgfCBudWxsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgZWRpdG9yIGlzIHJlYWR5LlxuICAgICAqL1xuICAgIG9uQ3JlYXRlPzpcbiAgICAgIHwgKCh0aGlzOiB7XG4gICAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgICBlZGl0b3I6IEVkaXRvclxuICAgICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPEV4dGVuc2lvbkNvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ29uQ3JlYXRlJ11cbiAgICAgICAgfSkgPT4gdm9pZClcbiAgICAgIHwgbnVsbFxuXG4gICAgLyoqXG4gICAgICogVGhlIGNvbnRlbnQgaGFzIGNoYW5nZWQuXG4gICAgICovXG4gICAgb25VcGRhdGU/OlxuICAgICAgfCAoKHRoaXM6IHtcbiAgICAgICAgICBuYW1lOiBzdHJpbmdcbiAgICAgICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgICAgIGVkaXRvcjogRWRpdG9yXG4gICAgICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8RXh0ZW5zaW9uQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+Plsnb25VcGRhdGUnXVxuICAgICAgICB9KSA9PiB2b2lkKVxuICAgICAgfCBudWxsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgc2VsZWN0aW9uIGhhcyBjaGFuZ2VkLlxuICAgICAqL1xuICAgIG9uU2VsZWN0aW9uVXBkYXRlPzpcbiAgICAgIHwgKCh0aGlzOiB7XG4gICAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgICBlZGl0b3I6IEVkaXRvclxuICAgICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPEV4dGVuc2lvbkNvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ29uU2VsZWN0aW9uVXBkYXRlJ11cbiAgICAgICAgfSkgPT4gdm9pZClcbiAgICAgIHwgbnVsbFxuXG4gICAgLyoqXG4gICAgICogVGhlIGVkaXRvciBzdGF0ZSBoYXMgY2hhbmdlZC5cbiAgICAgKi9cbiAgICBvblRyYW5zYWN0aW9uPzpcbiAgICAgIHwgKChcbiAgICAgICAgICB0aGlzOiB7XG4gICAgICAgICAgICBuYW1lOiBzdHJpbmdcbiAgICAgICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgICAgIGVkaXRvcjogRWRpdG9yXG4gICAgICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxFeHRlbnNpb25Db25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydvblRyYW5zYWN0aW9uJ11cbiAgICAgICAgICB9LFxuICAgICAgICAgIHByb3BzOiB7XG4gICAgICAgICAgICBlZGl0b3I6IEVkaXRvclxuICAgICAgICAgICAgdHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uXG4gICAgICAgICAgfSxcbiAgICAgICAgKSA9PiB2b2lkKVxuICAgICAgfCBudWxsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgZWRpdG9yIGlzIGZvY3VzZWQuXG4gICAgICovXG4gICAgb25Gb2N1cz86XG4gICAgICB8ICgoXG4gICAgICAgICAgdGhpczoge1xuICAgICAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICAgICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICAgICAgICBlZGl0b3I6IEVkaXRvclxuICAgICAgICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8RXh0ZW5zaW9uQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+Plsnb25Gb2N1cyddXG4gICAgICAgICAgfSxcbiAgICAgICAgICBwcm9wczoge1xuICAgICAgICAgICAgZXZlbnQ6IEZvY3VzRXZlbnRcbiAgICAgICAgICB9LFxuICAgICAgICApID0+IHZvaWQpXG4gICAgICB8IG51bGxcblxuICAgIC8qKlxuICAgICAqIFRoZSBlZGl0b3IgaXNu4oCZdCBmb2N1c2VkIGFueW1vcmUuXG4gICAgICovXG4gICAgb25CbHVyPzpcbiAgICAgIHwgKChcbiAgICAgICAgICB0aGlzOiB7XG4gICAgICAgICAgICBuYW1lOiBzdHJpbmdcbiAgICAgICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgICAgIGVkaXRvcjogRWRpdG9yXG4gICAgICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxFeHRlbnNpb25Db25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydvbkJsdXInXVxuICAgICAgICAgIH0sXG4gICAgICAgICAgcHJvcHM6IHtcbiAgICAgICAgICAgIGV2ZW50OiBGb2N1c0V2ZW50XG4gICAgICAgICAgfSxcbiAgICAgICAgKSA9PiB2b2lkKVxuICAgICAgfCBudWxsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgZWRpdG9yIGlzIGRlc3Ryb3llZC5cbiAgICAgKi9cbiAgICBvbkRlc3Ryb3k/OlxuICAgICAgfCAoKHRoaXM6IHtcbiAgICAgICAgICBuYW1lOiBzdHJpbmdcbiAgICAgICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgICAgIGVkaXRvcjogRWRpdG9yXG4gICAgICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8RXh0ZW5zaW9uQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+Plsnb25EZXN0cm95J11cbiAgICAgICAgfSkgPT4gdm9pZClcbiAgICAgIHwgbnVsbFxuICB9XG59XG5cbi8qKlxuICogVGhlIEV4dGVuc2lvbiBjbGFzcyBpcyB0aGUgYmFzZSBjbGFzcyBmb3IgYWxsIGV4dGVuc2lvbnMuXG4gKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9hcGkvZXh0ZW5zaW9ucyNjcmVhdGUtYS1uZXctZXh0ZW5zaW9uXG4gKi9cbmV4cG9ydCBjbGFzcyBFeHRlbnNpb248T3B0aW9ucyA9IGFueSwgU3RvcmFnZSA9IGFueT4ge1xuICB0eXBlID0gJ2V4dGVuc2lvbidcblxuICBuYW1lID0gJ2V4dGVuc2lvbidcblxuICBwYXJlbnQ6IEV4dGVuc2lvbiB8IG51bGwgPSBudWxsXG5cbiAgY2hpbGQ6IEV4dGVuc2lvbiB8IG51bGwgPSBudWxsXG5cbiAgb3B0aW9uczogT3B0aW9uc1xuXG4gIHN0b3JhZ2U6IFN0b3JhZ2VcblxuICBjb25maWc6IEV4dGVuc2lvbkNvbmZpZyA9IHtcbiAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgZGVmYXVsdE9wdGlvbnM6IHt9LFxuICB9XG5cbiAgY29uc3RydWN0b3IoY29uZmlnOiBQYXJ0aWFsPEV4dGVuc2lvbkNvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj4gPSB7fSkge1xuICAgIHRoaXMuY29uZmlnID0ge1xuICAgICAgLi4udGhpcy5jb25maWcsXG4gICAgICAuLi5jb25maWcsXG4gICAgfVxuXG4gICAgdGhpcy5uYW1lID0gdGhpcy5jb25maWcubmFtZVxuXG4gICAgaWYgKGNvbmZpZy5kZWZhdWx0T3B0aW9ucyAmJiBPYmplY3Qua2V5cyhjb25maWcuZGVmYXVsdE9wdGlvbnMpLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgYFt0aXB0YXAgd2Fybl06IEJSRUFLSU5HIENIQU5HRTogXCJkZWZhdWx0T3B0aW9uc1wiIGlzIGRlcHJlY2F0ZWQuIFBsZWFzZSB1c2UgXCJhZGRPcHRpb25zXCIgaW5zdGVhZC4gRm91bmQgaW4gZXh0ZW5zaW9uOiBcIiR7dGhpcy5uYW1lfVwiLmAsXG4gICAgICApXG4gICAgfVxuXG4gICAgLy8gVE9ETzogcmVtb3ZlIGBhZGRPcHRpb25zYCBmYWxsYmFja1xuICAgIHRoaXMub3B0aW9ucyA9IHRoaXMuY29uZmlnLmRlZmF1bHRPcHRpb25zXG5cbiAgICBpZiAodGhpcy5jb25maWcuYWRkT3B0aW9ucykge1xuICAgICAgdGhpcy5vcHRpb25zID0gY2FsbE9yUmV0dXJuKFxuICAgICAgICBnZXRFeHRlbnNpb25GaWVsZDxBbnlDb25maWdbJ2FkZE9wdGlvbnMnXT4odGhpcywgJ2FkZE9wdGlvbnMnLCB7XG4gICAgICAgICAgbmFtZTogdGhpcy5uYW1lLFxuICAgICAgICB9KSxcbiAgICAgIClcbiAgICB9XG5cbiAgICB0aGlzLnN0b3JhZ2UgPSBjYWxsT3JSZXR1cm4oXG4gICAgICBnZXRFeHRlbnNpb25GaWVsZDxBbnlDb25maWdbJ2FkZFN0b3JhZ2UnXT4odGhpcywgJ2FkZFN0b3JhZ2UnLCB7XG4gICAgICAgIG5hbWU6IHRoaXMubmFtZSxcbiAgICAgICAgb3B0aW9uczogdGhpcy5vcHRpb25zLFxuICAgICAgfSksXG4gICAgKSB8fCB7fVxuICB9XG5cbiAgc3RhdGljIGNyZWF0ZTxPID0gYW55LCBTID0gYW55Pihjb25maWc6IFBhcnRpYWw8RXh0ZW5zaW9uQ29uZmlnPE8sIFM+PiA9IHt9KSB7XG4gICAgcmV0dXJuIG5ldyBFeHRlbnNpb248TywgUz4oY29uZmlnKVxuICB9XG5cbiAgY29uZmlndXJlKG9wdGlvbnM6IFBhcnRpYWw8T3B0aW9ucz4gPSB7fSkge1xuICAgIC8vIHJldHVybiBhIG5ldyBpbnN0YW5jZSBzbyB3ZSBjYW4gdXNlIHRoZSBzYW1lIGV4dGVuc2lvblxuICAgIC8vIHdpdGggZGlmZmVyZW50IGNhbGxzIG9mIGBjb25maWd1cmVgXG4gICAgY29uc3QgZXh0ZW5zaW9uID0gdGhpcy5leHRlbmQ8T3B0aW9ucywgU3RvcmFnZT4oe1xuICAgICAgLi4udGhpcy5jb25maWcsXG4gICAgICBhZGRPcHRpb25zOiAoKSA9PiB7XG4gICAgICAgIHJldHVybiBtZXJnZURlZXAodGhpcy5vcHRpb25zIGFzIFJlY29yZDxzdHJpbmcsIGFueT4sIG9wdGlvbnMpIGFzIE9wdGlvbnNcbiAgICAgIH0sXG4gICAgfSlcblxuICAgIC8vIEFsd2F5cyBwcmVzZXJ2ZSB0aGUgY3VycmVudCBuYW1lXG4gICAgZXh0ZW5zaW9uLm5hbWUgPSB0aGlzLm5hbWVcbiAgICAvLyBTZXQgdGhlIHBhcmVudCB0byBiZSBvdXIgcGFyZW50XG4gICAgZXh0ZW5zaW9uLnBhcmVudCA9IHRoaXMucGFyZW50XG5cbiAgICByZXR1cm4gZXh0ZW5zaW9uXG4gIH1cblxuICBleHRlbmQ8RXh0ZW5kZWRPcHRpb25zID0gT3B0aW9ucywgRXh0ZW5kZWRTdG9yYWdlID0gU3RvcmFnZT4oXG4gICAgZXh0ZW5kZWRDb25maWc6IFBhcnRpYWw8RXh0ZW5zaW9uQ29uZmlnPEV4dGVuZGVkT3B0aW9ucywgRXh0ZW5kZWRTdG9yYWdlPj4gPSB7fSxcbiAgKSB7XG4gICAgY29uc3QgZXh0ZW5zaW9uID0gbmV3IEV4dGVuc2lvbjxFeHRlbmRlZE9wdGlvbnMsIEV4dGVuZGVkU3RvcmFnZT4oeyAuLi50aGlzLmNvbmZpZywgLi4uZXh0ZW5kZWRDb25maWcgfSlcblxuICAgIGV4dGVuc2lvbi5wYXJlbnQgPSB0aGlzXG5cbiAgICB0aGlzLmNoaWxkID0gZXh0ZW5zaW9uXG5cbiAgICBleHRlbnNpb24ubmFtZSA9IGV4dGVuZGVkQ29uZmlnLm5hbWUgPyBleHRlbmRlZENvbmZpZy5uYW1lIDogZXh0ZW5zaW9uLnBhcmVudC5uYW1lXG5cbiAgICBpZiAoZXh0ZW5kZWRDb25maWcuZGVmYXVsdE9wdGlvbnMgJiYgT2JqZWN0LmtleXMoZXh0ZW5kZWRDb25maWcuZGVmYXVsdE9wdGlvbnMpLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgYFt0aXB0YXAgd2Fybl06IEJSRUFLSU5HIENIQU5HRTogXCJkZWZhdWx0T3B0aW9uc1wiIGlzIGRlcHJlY2F0ZWQuIFBsZWFzZSB1c2UgXCJhZGRPcHRpb25zXCIgaW5zdGVhZC4gRm91bmQgaW4gZXh0ZW5zaW9uOiBcIiR7ZXh0ZW5zaW9uLm5hbWV9XCIuYCxcbiAgICAgIClcbiAgICB9XG5cbiAgICBleHRlbnNpb24ub3B0aW9ucyA9IGNhbGxPclJldHVybihcbiAgICAgIGdldEV4dGVuc2lvbkZpZWxkPEFueUNvbmZpZ1snYWRkT3B0aW9ucyddPihleHRlbnNpb24sICdhZGRPcHRpb25zJywge1xuICAgICAgICBuYW1lOiBleHRlbnNpb24ubmFtZSxcbiAgICAgIH0pLFxuICAgIClcblxuICAgIGV4dGVuc2lvbi5zdG9yYWdlID0gY2FsbE9yUmV0dXJuKFxuICAgICAgZ2V0RXh0ZW5zaW9uRmllbGQ8QW55Q29uZmlnWydhZGRTdG9yYWdlJ10+KGV4dGVuc2lvbiwgJ2FkZFN0b3JhZ2UnLCB7XG4gICAgICAgIG5hbWU6IGV4dGVuc2lvbi5uYW1lLFxuICAgICAgICBvcHRpb25zOiBleHRlbnNpb24ub3B0aW9ucyxcbiAgICAgIH0pLFxuICAgIClcblxuICAgIHJldHVybiBleHRlbnNpb25cbiAgfVxufVxuIiwgImltcG9ydCB7IE5vZGUgYXMgUHJvc2VNaXJyb3JOb2RlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuaW1wb3J0IHsgUmFuZ2UsIFRleHRTZXJpYWxpemVyIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbi8qKlxuICogR2V0cyB0aGUgdGV4dCBiZXR3ZWVuIHR3byBwb3NpdGlvbnMgaW4gYSBQcm9zZW1pcnJvciBub2RlXG4gKiBhbmQgc2VyaWFsaXplcyBpdCB1c2luZyB0aGUgZ2l2ZW4gdGV4dCBzZXJpYWxpemVycyBhbmQgYmxvY2sgc2VwYXJhdG9yIChzZWUgZ2V0VGV4dClcbiAqIEBwYXJhbSBzdGFydE5vZGUgVGhlIFByb3NlbWlycm9yIG5vZGUgdG8gc3RhcnQgZnJvbVxuICogQHBhcmFtIHJhbmdlIFRoZSByYW5nZSBvZiB0aGUgdGV4dCB0byBnZXRcbiAqIEBwYXJhbSBvcHRpb25zIE9wdGlvbnMgZm9yIHRoZSB0ZXh0IHNlcmlhbGl6ZXIgJiBibG9jayBzZXBhcmF0b3JcbiAqIEByZXR1cm5zIFRoZSB0ZXh0IGJldHdlZW4gdGhlIHR3byBwb3NpdGlvbnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFRleHRCZXR3ZWVuKFxuICBzdGFydE5vZGU6IFByb3NlTWlycm9yTm9kZSxcbiAgcmFuZ2U6IFJhbmdlLFxuICBvcHRpb25zPzoge1xuICAgIGJsb2NrU2VwYXJhdG9yPzogc3RyaW5nXG4gICAgdGV4dFNlcmlhbGl6ZXJzPzogUmVjb3JkPHN0cmluZywgVGV4dFNlcmlhbGl6ZXI+XG4gIH0sXG4pOiBzdHJpbmcge1xuICBjb25zdCB7IGZyb20sIHRvIH0gPSByYW5nZVxuICBjb25zdCB7IGJsb2NrU2VwYXJhdG9yID0gJ1xcblxcbicsIHRleHRTZXJpYWxpemVycyA9IHt9IH0gPSBvcHRpb25zIHx8IHt9XG4gIGxldCB0ZXh0ID0gJydcblxuICBzdGFydE5vZGUubm9kZXNCZXR3ZWVuKGZyb20sIHRvLCAobm9kZSwgcG9zLCBwYXJlbnQsIGluZGV4KSA9PiB7XG4gICAgaWYgKG5vZGUuaXNCbG9jayAmJiBwb3MgPiBmcm9tKSB7XG4gICAgICB0ZXh0ICs9IGJsb2NrU2VwYXJhdG9yXG4gICAgfVxuXG4gICAgY29uc3QgdGV4dFNlcmlhbGl6ZXIgPSB0ZXh0U2VyaWFsaXplcnM/Lltub2RlLnR5cGUubmFtZV1cblxuICAgIGlmICh0ZXh0U2VyaWFsaXplcikge1xuICAgICAgaWYgKHBhcmVudCkge1xuICAgICAgICB0ZXh0ICs9IHRleHRTZXJpYWxpemVyKHtcbiAgICAgICAgICBub2RlLFxuICAgICAgICAgIHBvcyxcbiAgICAgICAgICBwYXJlbnQsXG4gICAgICAgICAgaW5kZXgsXG4gICAgICAgICAgcmFuZ2UsXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgICAvLyBkbyBub3QgZGVzY2VuZCBpbnRvIGNoaWxkIG5vZGVzIHdoZW4gdGhlcmUgZXhpc3RzIGEgc2VyaWFsaXplclxuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgaWYgKG5vZGUuaXNUZXh0KSB7XG4gICAgICB0ZXh0ICs9IG5vZGU/LnRleHQ/LnNsaWNlKE1hdGgubWF4KGZyb20sIHBvcykgLSBwb3MsIHRvIC0gcG9zKSAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG4gICAgfVxuICB9KVxuXG4gIHJldHVybiB0ZXh0XG59XG4iLCAiaW1wb3J0IHsgU2NoZW1hIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuaW1wb3J0IHsgVGV4dFNlcmlhbGl6ZXIgfSBmcm9tICcuLi90eXBlcy5qcydcblxuLyoqXG4gKiBGaW5kIHRleHQgc2VyaWFsaXplcnMgYHRvVGV4dGAgaW4gYSBQcm9zZW1pcnJvciBzY2hlbWFcbiAqIEBwYXJhbSBzY2hlbWEgVGhlIFByb3NlbWlycm9yIHNjaGVtYSB0byBzZWFyY2ggaW5cbiAqIEByZXR1cm5zIEEgcmVjb3JkIG9mIHRleHQgc2VyaWFsaXplcnMgYnkgbm9kZSBuYW1lXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRUZXh0U2VyaWFsaXplcnNGcm9tU2NoZW1hKHNjaGVtYTogU2NoZW1hKTogUmVjb3JkPHN0cmluZywgVGV4dFNlcmlhbGl6ZXI+IHtcbiAgcmV0dXJuIE9iamVjdC5mcm9tRW50cmllcyhcbiAgICBPYmplY3QuZW50cmllcyhzY2hlbWEubm9kZXMpXG4gICAgICAuZmlsdGVyKChbLCBub2RlXSkgPT4gbm9kZS5zcGVjLnRvVGV4dClcbiAgICAgIC5tYXAoKFtuYW1lLCBub2RlXSkgPT4gW25hbWUsIG5vZGUuc3BlYy50b1RleHRdKSxcbiAgKVxufVxuIiwgImltcG9ydCB7IFBsdWdpbiwgUGx1Z2luS2V5IH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcblxuaW1wb3J0IHsgRXh0ZW5zaW9uIH0gZnJvbSAnLi4vRXh0ZW5zaW9uLmpzJ1xuaW1wb3J0IHsgZ2V0VGV4dEJldHdlZW4gfSBmcm9tICcuLi9oZWxwZXJzL2dldFRleHRCZXR3ZWVuLmpzJ1xuaW1wb3J0IHsgZ2V0VGV4dFNlcmlhbGl6ZXJzRnJvbVNjaGVtYSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0VGV4dFNlcmlhbGl6ZXJzRnJvbVNjaGVtYS5qcydcblxuZXhwb3J0IHR5cGUgQ2xpcGJvYXJkVGV4dFNlcmlhbGl6ZXJPcHRpb25zID0ge1xuICBibG9ja1NlcGFyYXRvcj86IHN0cmluZyxcbn1cblxuZXhwb3J0IGNvbnN0IENsaXBib2FyZFRleHRTZXJpYWxpemVyID0gRXh0ZW5zaW9uLmNyZWF0ZTxDbGlwYm9hcmRUZXh0U2VyaWFsaXplck9wdGlvbnM+KHtcbiAgbmFtZTogJ2NsaXBib2FyZFRleHRTZXJpYWxpemVyJyxcblxuICBhZGRPcHRpb25zKCkge1xuICAgIHJldHVybiB7XG4gICAgICBibG9ja1NlcGFyYXRvcjogdW5kZWZpbmVkLFxuICAgIH1cbiAgfSxcblxuICBhZGRQcm9zZU1pcnJvclBsdWdpbnMoKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIG5ldyBQbHVnaW4oe1xuICAgICAgICBrZXk6IG5ldyBQbHVnaW5LZXkoJ2NsaXBib2FyZFRleHRTZXJpYWxpemVyJyksXG4gICAgICAgIHByb3BzOiB7XG4gICAgICAgICAgY2xpcGJvYXJkVGV4dFNlcmlhbGl6ZXI6ICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgZWRpdG9yIH0gPSB0aGlzXG4gICAgICAgICAgICBjb25zdCB7IHN0YXRlLCBzY2hlbWEgfSA9IGVkaXRvclxuICAgICAgICAgICAgY29uc3QgeyBkb2MsIHNlbGVjdGlvbiB9ID0gc3RhdGVcbiAgICAgICAgICAgIGNvbnN0IHsgcmFuZ2VzIH0gPSBzZWxlY3Rpb25cbiAgICAgICAgICAgIGNvbnN0IGZyb20gPSBNYXRoLm1pbiguLi5yYW5nZXMubWFwKHJhbmdlID0+IHJhbmdlLiRmcm9tLnBvcykpXG4gICAgICAgICAgICBjb25zdCB0byA9IE1hdGgubWF4KC4uLnJhbmdlcy5tYXAocmFuZ2UgPT4gcmFuZ2UuJHRvLnBvcykpXG4gICAgICAgICAgICBjb25zdCB0ZXh0U2VyaWFsaXplcnMgPSBnZXRUZXh0U2VyaWFsaXplcnNGcm9tU2NoZW1hKHNjaGVtYSlcbiAgICAgICAgICAgIGNvbnN0IHJhbmdlID0geyBmcm9tLCB0byB9XG5cbiAgICAgICAgICAgIHJldHVybiBnZXRUZXh0QmV0d2Vlbihkb2MsIHJhbmdlLCB7XG4gICAgICAgICAgICAgIC4uLih0aGlzLm9wdGlvbnMuYmxvY2tTZXBhcmF0b3IgIT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgID8geyBibG9ja1NlcGFyYXRvcjogdGhpcy5vcHRpb25zLmJsb2NrU2VwYXJhdG9yIH1cbiAgICAgICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgICAgICAgdGV4dFNlcmlhbGl6ZXJzLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSksXG4gICAgXVxuICB9LFxufSlcbiIsICJpbXBvcnQgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgYmx1cjoge1xuICAgICAgLyoqXG4gICAgICAgKiBSZW1vdmVzIGZvY3VzIGZyb20gdGhlIGVkaXRvci5cbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy5ibHVyKClcbiAgICAgICAqL1xuICAgICAgYmx1cjogKCkgPT4gUmV0dXJuVHlwZSxcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGJsdXI6IFJhd0NvbW1hbmRzWydibHVyJ10gPSAoKSA9PiAoeyBlZGl0b3IsIHZpZXcgfSkgPT4ge1xuICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgIGlmICghZWRpdG9yLmlzRGVzdHJveWVkKSB7XG4gICAgICAodmlldy5kb20gYXMgSFRNTEVsZW1lbnQpLmJsdXIoKVxuXG4gICAgICAvLyBCcm93c2VycyBzaG91bGQgcmVtb3ZlIHRoZSBjYXJldCBvbiBibHVyIGJ1dCBzYWZhcmkgZG9lcyBub3QuXG4gICAgICAvLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS91ZWJlcmRvc2lzL3RpcHRhcC9pc3N1ZXMvMjQwNVxuICAgICAgd2luZG93Py5nZXRTZWxlY3Rpb24oKT8ucmVtb3ZlQWxsUmFuZ2VzKClcbiAgICB9XG4gIH0pXG5cbiAgcmV0dXJuIHRydWVcbn1cbiIsICJpbXBvcnQgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgY2xlYXJDb250ZW50OiB7XG4gICAgICAvKipcbiAgICAgICAqIENsZWFyIHRoZSB3aG9sZSBkb2N1bWVudC5cbiAgICAgICAqIEBwYXJhbSBlbWl0VXBkYXRlIFdoZXRoZXIgdG8gZW1pdCBhbiB1cGRhdGUgZXZlbnQuXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuY2xlYXJDb250ZW50KClcbiAgICAgICAqL1xuICAgICAgY2xlYXJDb250ZW50OiAoZW1pdFVwZGF0ZT86IGJvb2xlYW4pID0+IFJldHVyblR5cGUsXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBjbGVhckNvbnRlbnQ6IFJhd0NvbW1hbmRzWydjbGVhckNvbnRlbnQnXSA9IChlbWl0VXBkYXRlID0gZmFsc2UpID0+ICh7IGNvbW1hbmRzIH0pID0+IHtcbiAgcmV0dXJuIGNvbW1hbmRzLnNldENvbnRlbnQoJycsIGVtaXRVcGRhdGUpXG59XG4iLCAiaW1wb3J0IHsgbGlmdFRhcmdldCB9IGZyb20gJ0B0aXB0YXAvcG0vdHJhbnNmb3JtJ1xuXG5pbXBvcnQgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgY2xlYXJOb2Rlczoge1xuICAgICAgLyoqXG4gICAgICAgKiBOb3JtYWxpemUgbm9kZXMgdG8gYSBzaW1wbGUgcGFyYWdyYXBoLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmNsZWFyTm9kZXMoKVxuICAgICAgICovXG4gICAgICBjbGVhck5vZGVzOiAoKSA9PiBSZXR1cm5UeXBlLFxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgY2xlYXJOb2RlczogUmF3Q29tbWFuZHNbJ2NsZWFyTm9kZXMnXSA9ICgpID0+ICh7IHN0YXRlLCB0ciwgZGlzcGF0Y2ggfSkgPT4ge1xuICBjb25zdCB7IHNlbGVjdGlvbiB9ID0gdHJcbiAgY29uc3QgeyByYW5nZXMgfSA9IHNlbGVjdGlvblxuXG4gIGlmICghZGlzcGF0Y2gpIHtcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgcmFuZ2VzLmZvckVhY2goKHsgJGZyb20sICR0byB9KSA9PiB7XG4gICAgc3RhdGUuZG9jLm5vZGVzQmV0d2VlbigkZnJvbS5wb3MsICR0by5wb3MsIChub2RlLCBwb3MpID0+IHtcbiAgICAgIGlmIChub2RlLnR5cGUuaXNUZXh0KSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICBjb25zdCB7IGRvYywgbWFwcGluZyB9ID0gdHJcbiAgICAgIGNvbnN0ICRtYXBwZWRGcm9tID0gZG9jLnJlc29sdmUobWFwcGluZy5tYXAocG9zKSlcbiAgICAgIGNvbnN0ICRtYXBwZWRUbyA9IGRvYy5yZXNvbHZlKG1hcHBpbmcubWFwKHBvcyArIG5vZGUubm9kZVNpemUpKVxuICAgICAgY29uc3Qgbm9kZVJhbmdlID0gJG1hcHBlZEZyb20uYmxvY2tSYW5nZSgkbWFwcGVkVG8pXG5cbiAgICAgIGlmICghbm9kZVJhbmdlKSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICBjb25zdCB0YXJnZXRMaWZ0RGVwdGggPSBsaWZ0VGFyZ2V0KG5vZGVSYW5nZSlcblxuICAgICAgaWYgKG5vZGUudHlwZS5pc1RleHRibG9jaykge1xuICAgICAgICBjb25zdCB7IGRlZmF1bHRUeXBlIH0gPSAkbWFwcGVkRnJvbS5wYXJlbnQuY29udGVudE1hdGNoQXQoJG1hcHBlZEZyb20uaW5kZXgoKSlcblxuICAgICAgICB0ci5zZXROb2RlTWFya3VwKG5vZGVSYW5nZS5zdGFydCwgZGVmYXVsdFR5cGUpXG4gICAgICB9XG5cbiAgICAgIGlmICh0YXJnZXRMaWZ0RGVwdGggfHwgdGFyZ2V0TGlmdERlcHRoID09PSAwKSB7XG4gICAgICAgIHRyLmxpZnQobm9kZVJhbmdlLCB0YXJnZXRMaWZ0RGVwdGgpXG4gICAgICB9XG4gICAgfSlcbiAgfSlcblxuICByZXR1cm4gdHJ1ZVxufVxuIiwgImltcG9ydCB7IENvbW1hbmQsIFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBjb21tYW5kOiB7XG4gICAgICAvKipcbiAgICAgICAqIERlZmluZSBhIGNvbW1hbmQgaW5saW5lLlxuICAgICAgICogQHBhcmFtIGZuIFRoZSBjb21tYW5kIGZ1bmN0aW9uLlxuICAgICAgICogQGV4YW1wbGVcbiAgICAgICAqIGVkaXRvci5jb21tYW5kcy5jb21tYW5kKCh7IHRyLCBzdGF0ZSB9KSA9PiB7XG4gICAgICAgKiAgIC4uLlxuICAgICAgICogICByZXR1cm4gdHJ1ZVxuICAgICAgICogfSlcbiAgICAgICAqL1xuICAgICAgY29tbWFuZDogKGZuOiAocHJvcHM6IFBhcmFtZXRlcnM8Q29tbWFuZD5bMF0pID0+IGJvb2xlYW4pID0+IFJldHVyblR5cGUsXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBjb21tYW5kOiBSYXdDb21tYW5kc1snY29tbWFuZCddID0gZm4gPT4gcHJvcHMgPT4ge1xuICByZXR1cm4gZm4ocHJvcHMpXG59XG4iLCAiaW1wb3J0IHsgY3JlYXRlUGFyYWdyYXBoTmVhciBhcyBvcmlnaW5hbENyZWF0ZVBhcmFncmFwaE5lYXIgfSBmcm9tICdAdGlwdGFwL3BtL2NvbW1hbmRzJ1xuXG5pbXBvcnQgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgY3JlYXRlUGFyYWdyYXBoTmVhcjoge1xuICAgICAgLyoqXG4gICAgICAgKiBDcmVhdGUgYSBwYXJhZ3JhcGggbmVhcmJ5LlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmNyZWF0ZVBhcmFncmFwaE5lYXIoKVxuICAgICAgICovXG4gICAgICBjcmVhdGVQYXJhZ3JhcGhOZWFyOiAoKSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVQYXJhZ3JhcGhOZWFyOiBSYXdDb21tYW5kc1snY3JlYXRlUGFyYWdyYXBoTmVhciddID0gKCkgPT4gKHsgc3RhdGUsIGRpc3BhdGNoIH0pID0+IHtcbiAgcmV0dXJuIG9yaWdpbmFsQ3JlYXRlUGFyYWdyYXBoTmVhcihzdGF0ZSwgZGlzcGF0Y2gpXG59XG4iLCAiaW1wb3J0IHsgVGV4dFNlbGVjdGlvbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmltcG9ydCB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBjdXQ6IHtcbiAgICAgIC8qKlxuICAgICAgICogQ3V0cyBjb250ZW50IGZyb20gYSByYW5nZSBhbmQgaW5zZXJ0cyBpdCBhdCBhIGdpdmVuIHBvc2l0aW9uLlxuICAgICAgICogQHBhcmFtIHJhbmdlIFRoZSByYW5nZSB0byBjdXQuXG4gICAgICAgKiBAcGFyYW0gcmFuZ2UuZnJvbSBUaGUgc3RhcnQgcG9zaXRpb24gb2YgdGhlIHJhbmdlLlxuICAgICAgICogQHBhcmFtIHJhbmdlLnRvIFRoZSBlbmQgcG9zaXRpb24gb2YgdGhlIHJhbmdlLlxuICAgICAgICogQHBhcmFtIHRhcmdldFBvcyBUaGUgcG9zaXRpb24gdG8gaW5zZXJ0IHRoZSBjb250ZW50IGF0LlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmN1dCh7IGZyb206IDEsIHRvOiAzIH0sIDUpXG4gICAgICAgKi9cbiAgICAgIGN1dDogKHsgZnJvbSwgdG8gfTogeyBmcm9tOiBudW1iZXIsIHRvOiBudW1iZXIgfSwgdGFyZ2V0UG9zOiBudW1iZXIpID0+IFJldHVyblR5cGUsXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBjdXQ6IFJhd0NvbW1hbmRzWydjdXQnXSA9IChvcmlnaW5SYW5nZSwgdGFyZ2V0UG9zKSA9PiAoeyBlZGl0b3IsIHRyIH0pID0+IHtcbiAgY29uc3QgeyBzdGF0ZSB9ID0gZWRpdG9yXG5cbiAgY29uc3QgY29udGVudFNsaWNlID0gc3RhdGUuZG9jLnNsaWNlKG9yaWdpblJhbmdlLmZyb20sIG9yaWdpblJhbmdlLnRvKVxuXG4gIHRyLmRlbGV0ZVJhbmdlKG9yaWdpblJhbmdlLmZyb20sIG9yaWdpblJhbmdlLnRvKVxuICBjb25zdCBuZXdQb3MgPSB0ci5tYXBwaW5nLm1hcCh0YXJnZXRQb3MpXG5cbiAgdHIuaW5zZXJ0KG5ld1BvcywgY29udGVudFNsaWNlLmNvbnRlbnQpXG5cbiAgdHIuc2V0U2VsZWN0aW9uKG5ldyBUZXh0U2VsZWN0aW9uKHRyLmRvYy5yZXNvbHZlKG5ld1BvcyAtIDEpKSlcblxuICByZXR1cm4gdHJ1ZVxufVxuIiwgImltcG9ydCB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBkZWxldGVDdXJyZW50Tm9kZToge1xuICAgICAgLyoqXG4gICAgICAgKiBEZWxldGUgdGhlIG5vZGUgdGhhdCBjdXJyZW50bHkgaGFzIHRoZSBzZWxlY3Rpb24gYW5jaG9yLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmRlbGV0ZUN1cnJlbnROb2RlKClcbiAgICAgICAqL1xuICAgICAgZGVsZXRlQ3VycmVudE5vZGU6ICgpID0+IFJldHVyblR5cGUsXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBkZWxldGVDdXJyZW50Tm9kZTogUmF3Q29tbWFuZHNbJ2RlbGV0ZUN1cnJlbnROb2RlJ10gPSAoKSA9PiAoeyB0ciwgZGlzcGF0Y2ggfSkgPT4ge1xuICBjb25zdCB7IHNlbGVjdGlvbiB9ID0gdHJcbiAgY29uc3QgY3VycmVudE5vZGUgPSBzZWxlY3Rpb24uJGFuY2hvci5ub2RlKClcblxuICAvLyBpZiB0aGVyZSBpcyBjb250ZW50IGluc2lkZSB0aGUgY3VycmVudCBub2RlLCBicmVhayBvdXQgb2YgdGhpcyBjb21tYW5kXG4gIGlmIChjdXJyZW50Tm9kZS5jb250ZW50LnNpemUgPiAwKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBjb25zdCAkcG9zID0gdHIuc2VsZWN0aW9uLiRhbmNob3JcblxuICBmb3IgKGxldCBkZXB0aCA9ICRwb3MuZGVwdGg7IGRlcHRoID4gMDsgZGVwdGggLT0gMSkge1xuICAgIGNvbnN0IG5vZGUgPSAkcG9zLm5vZGUoZGVwdGgpXG5cbiAgICBpZiAobm9kZS50eXBlID09PSBjdXJyZW50Tm9kZS50eXBlKSB7XG4gICAgICBpZiAoZGlzcGF0Y2gpIHtcbiAgICAgICAgY29uc3QgZnJvbSA9ICRwb3MuYmVmb3JlKGRlcHRoKVxuICAgICAgICBjb25zdCB0byA9ICRwb3MuYWZ0ZXIoZGVwdGgpXG5cbiAgICAgICAgdHIuZGVsZXRlKGZyb20sIHRvKS5zY3JvbGxJbnRvVmlldygpXG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlXG59XG4iLCAiaW1wb3J0IHsgTm9kZVR5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgeyBnZXROb2RlVHlwZSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0Tm9kZVR5cGUuanMnXG5pbXBvcnQgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgZGVsZXRlTm9kZToge1xuICAgICAgLyoqXG4gICAgICAgKiBEZWxldGUgYSBub2RlIHdpdGggYSBnaXZlbiB0eXBlIG9yIG5hbWUuXG4gICAgICAgKiBAcGFyYW0gdHlwZU9yTmFtZSBUaGUgdHlwZSBvciBuYW1lIG9mIHRoZSBub2RlLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmRlbGV0ZU5vZGUoJ3BhcmFncmFwaCcpXG4gICAgICAgKi9cbiAgICAgIGRlbGV0ZU5vZGU6ICh0eXBlT3JOYW1lOiBzdHJpbmcgfCBOb2RlVHlwZSkgPT4gUmV0dXJuVHlwZSxcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGRlbGV0ZU5vZGU6IFJhd0NvbW1hbmRzWydkZWxldGVOb2RlJ10gPSB0eXBlT3JOYW1lID0+ICh7IHRyLCBzdGF0ZSwgZGlzcGF0Y2ggfSkgPT4ge1xuICBjb25zdCB0eXBlID0gZ2V0Tm9kZVR5cGUodHlwZU9yTmFtZSwgc3RhdGUuc2NoZW1hKVxuICBjb25zdCAkcG9zID0gdHIuc2VsZWN0aW9uLiRhbmNob3JcblxuICBmb3IgKGxldCBkZXB0aCA9ICRwb3MuZGVwdGg7IGRlcHRoID4gMDsgZGVwdGggLT0gMSkge1xuICAgIGNvbnN0IG5vZGUgPSAkcG9zLm5vZGUoZGVwdGgpXG5cbiAgICBpZiAobm9kZS50eXBlID09PSB0eXBlKSB7XG4gICAgICBpZiAoZGlzcGF0Y2gpIHtcbiAgICAgICAgY29uc3QgZnJvbSA9ICRwb3MuYmVmb3JlKGRlcHRoKVxuICAgICAgICBjb25zdCB0byA9ICRwb3MuYWZ0ZXIoZGVwdGgpXG5cbiAgICAgICAgdHIuZGVsZXRlKGZyb20sIHRvKS5zY3JvbGxJbnRvVmlldygpXG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlXG59XG4iLCAiaW1wb3J0IHsgUmFuZ2UsIFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBkZWxldGVSYW5nZToge1xuICAgICAgLyoqXG4gICAgICAgKiBEZWxldGUgYSBnaXZlbiByYW5nZS5cbiAgICAgICAqIEBwYXJhbSByYW5nZSBUaGUgcmFuZ2UgdG8gZGVsZXRlLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmRlbGV0ZVJhbmdlKHsgZnJvbTogMSwgdG86IDMgfSlcbiAgICAgICAqL1xuICAgICAgZGVsZXRlUmFuZ2U6IChyYW5nZTogUmFuZ2UpID0+IFJldHVyblR5cGUsXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBkZWxldGVSYW5nZTogUmF3Q29tbWFuZHNbJ2RlbGV0ZVJhbmdlJ10gPSByYW5nZSA9PiAoeyB0ciwgZGlzcGF0Y2ggfSkgPT4ge1xuICBjb25zdCB7IGZyb20sIHRvIH0gPSByYW5nZVxuXG4gIGlmIChkaXNwYXRjaCkge1xuICAgIHRyLmRlbGV0ZShmcm9tLCB0bylcbiAgfVxuXG4gIHJldHVybiB0cnVlXG59XG4iLCAiaW1wb3J0IHsgZGVsZXRlU2VsZWN0aW9uIGFzIG9yaWdpbmFsRGVsZXRlU2VsZWN0aW9uIH0gZnJvbSAnQHRpcHRhcC9wbS9jb21tYW5kcydcblxuaW1wb3J0IHsgUmF3Q29tbWFuZHMgfSBmcm9tICcuLi90eXBlcy5qcydcblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIGRlbGV0ZVNlbGVjdGlvbjoge1xuICAgICAgLyoqXG4gICAgICAgKiBEZWxldGUgdGhlIHNlbGVjdGlvbiwgaWYgdGhlcmUgaXMgb25lLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmRlbGV0ZVNlbGVjdGlvbigpXG4gICAgICAgKi9cbiAgICAgIGRlbGV0ZVNlbGVjdGlvbjogKCkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgZGVsZXRlU2VsZWN0aW9uOiBSYXdDb21tYW5kc1snZGVsZXRlU2VsZWN0aW9uJ10gPSAoKSA9PiAoeyBzdGF0ZSwgZGlzcGF0Y2ggfSkgPT4ge1xuICByZXR1cm4gb3JpZ2luYWxEZWxldGVTZWxlY3Rpb24oc3RhdGUsIGRpc3BhdGNoKVxufVxuIiwgImltcG9ydCB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBlbnRlcjoge1xuICAgICAgLyoqXG4gICAgICAgKiBUcmlnZ2VyIGVudGVyLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmVudGVyKClcbiAgICAgICAqL1xuICAgICAgZW50ZXI6ICgpID0+IFJldHVyblR5cGUsXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBlbnRlcjogUmF3Q29tbWFuZHNbJ2VudGVyJ10gPSAoKSA9PiAoeyBjb21tYW5kcyB9KSA9PiB7XG4gIHJldHVybiBjb21tYW5kcy5rZXlib2FyZFNob3J0Y3V0KCdFbnRlcicpXG59XG4iLCAiaW1wb3J0IHsgZXhpdENvZGUgYXMgb3JpZ2luYWxFeGl0Q29kZSB9IGZyb20gJ0B0aXB0YXAvcG0vY29tbWFuZHMnXG5cbmltcG9ydCB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBleGl0Q29kZToge1xuICAgICAgLyoqXG4gICAgICAgKiBFeGl0IGZyb20gYSBjb2RlIGJsb2NrLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmV4aXRDb2RlKClcbiAgICAgICAqL1xuICAgICAgZXhpdENvZGU6ICgpID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGV4aXRDb2RlOiBSYXdDb21tYW5kc1snZXhpdENvZGUnXSA9ICgpID0+ICh7IHN0YXRlLCBkaXNwYXRjaCB9KSA9PiB7XG4gIHJldHVybiBvcmlnaW5hbEV4aXRDb2RlKHN0YXRlLCBkaXNwYXRjaClcbn1cbiIsICJpbXBvcnQgeyBpc1JlZ0V4cCB9IGZyb20gJy4vaXNSZWdFeHAuanMnXG5cbi8qKlxuICogQ2hlY2sgaWYgb2JqZWN0MSBpbmNsdWRlcyBvYmplY3QyXG4gKiBAcGFyYW0gb2JqZWN0MSBPYmplY3RcbiAqIEBwYXJhbSBvYmplY3QyIE9iamVjdFxuICovXG5leHBvcnQgZnVuY3Rpb24gb2JqZWN0SW5jbHVkZXMoXG4gIG9iamVjdDE6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gIG9iamVjdDI6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gIG9wdGlvbnM6IHsgc3RyaWN0OiBib29sZWFuIH0gPSB7IHN0cmljdDogdHJ1ZSB9LFxuKTogYm9vbGVhbiB7XG4gIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhvYmplY3QyKVxuXG4gIGlmICgha2V5cy5sZW5ndGgpIHtcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgcmV0dXJuIGtleXMuZXZlcnkoa2V5ID0+IHtcbiAgICBpZiAob3B0aW9ucy5zdHJpY3QpIHtcbiAgICAgIHJldHVybiBvYmplY3QyW2tleV0gPT09IG9iamVjdDFba2V5XVxuICAgIH1cblxuICAgIGlmIChpc1JlZ0V4cChvYmplY3QyW2tleV0pKSB7XG4gICAgICByZXR1cm4gb2JqZWN0MltrZXldLnRlc3Qob2JqZWN0MVtrZXldKVxuICAgIH1cblxuICAgIHJldHVybiBvYmplY3QyW2tleV0gPT09IG9iamVjdDFba2V5XVxuICB9KVxufVxuIiwgImltcG9ydCB7IE1hcmsgYXMgUHJvc2VNaXJyb3JNYXJrLCBNYXJrVHlwZSwgUmVzb2x2ZWRQb3MgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgeyBSYW5nZSB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuaW1wb3J0IHsgb2JqZWN0SW5jbHVkZXMgfSBmcm9tICcuLi91dGlsaXRpZXMvb2JqZWN0SW5jbHVkZXMuanMnXG5cbmZ1bmN0aW9uIGZpbmRNYXJrSW5TZXQoXG4gIG1hcmtzOiBQcm9zZU1pcnJvck1hcmtbXSxcbiAgdHlwZTogTWFya1R5cGUsXG4gIGF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fSxcbik6IFByb3NlTWlycm9yTWFyayB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiBtYXJrcy5maW5kKGl0ZW0gPT4ge1xuICAgIHJldHVybiAoXG4gICAgICBpdGVtLnR5cGUgPT09IHR5cGVcbiAgICAgICYmIG9iamVjdEluY2x1ZGVzKFxuICAgICAgICAvLyBPbmx5IGNoZWNrIGVxdWFsaXR5IGZvciB0aGUgYXR0cmlidXRlcyB0aGF0IGFyZSBwcm92aWRlZFxuICAgICAgICBPYmplY3QuZnJvbUVudHJpZXMoT2JqZWN0LmtleXMoYXR0cmlidXRlcykubWFwKGsgPT4gW2ssIGl0ZW0uYXR0cnNba11dKSksXG4gICAgICAgIGF0dHJpYnV0ZXMsXG4gICAgICApXG4gICAgKVxuICB9KVxufVxuXG5mdW5jdGlvbiBpc01hcmtJblNldChcbiAgbWFya3M6IFByb3NlTWlycm9yTWFya1tdLFxuICB0eXBlOiBNYXJrVHlwZSxcbiAgYXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9LFxuKTogYm9vbGVhbiB7XG4gIHJldHVybiAhIWZpbmRNYXJrSW5TZXQobWFya3MsIHR5cGUsIGF0dHJpYnV0ZXMpXG59XG5cbi8qKlxuICogR2V0IHRoZSByYW5nZSBvZiBhIG1hcmsgYXQgYSByZXNvbHZlZCBwb3NpdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldE1hcmtSYW5nZShcbiAgLyoqXG4gICAqIFRoZSBwb3NpdGlvbiB0byBnZXQgdGhlIG1hcmsgcmFuZ2UgZm9yLlxuICAgKi9cbiAgJHBvczogUmVzb2x2ZWRQb3MsXG4gIC8qKlxuICAgKiBUaGUgbWFyayB0eXBlIHRvIGdldCB0aGUgcmFuZ2UgZm9yLlxuICAgKi9cbiAgdHlwZTogTWFya1R5cGUsXG4gIC8qKlxuICAgKiBUaGUgYXR0cmlidXRlcyB0byBtYXRjaCBhZ2FpbnN0LlxuICAgKiBJZiBub3QgcHJvdmlkZWQsIG9ubHkgdGhlIGZpcnN0IG1hcmsgYXQgdGhlIHBvc2l0aW9uIHdpbGwgYmUgbWF0Y2hlZC5cbiAgICovXG4gIGF0dHJpYnV0ZXM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuKTogUmFuZ2UgfCB2b2lkIHtcbiAgaWYgKCEkcG9zIHx8ICF0eXBlKSB7XG4gICAgcmV0dXJuXG4gIH1cbiAgbGV0IHN0YXJ0ID0gJHBvcy5wYXJlbnQuY2hpbGRBZnRlcigkcG9zLnBhcmVudE9mZnNldClcblxuICAvLyBJZiB0aGUgY3Vyc29yIGlzIGF0IHRoZSBzdGFydCBvZiBhIHRleHQgbm9kZSB0aGF0IGRvZXMgbm90IGhhdmUgdGhlIG1hcmssIGxvb2sgYmFja3dhcmRcbiAgaWYgKCFzdGFydC5ub2RlIHx8ICFzdGFydC5ub2RlLm1hcmtzLnNvbWUobWFyayA9PiBtYXJrLnR5cGUgPT09IHR5cGUpKSB7XG4gICAgc3RhcnQgPSAkcG9zLnBhcmVudC5jaGlsZEJlZm9yZSgkcG9zLnBhcmVudE9mZnNldClcbiAgfVxuXG4gIC8vIElmIHRoZXJlIGlzIG5vIHRleHQgbm9kZSB3aXRoIHRoZSBtYXJrIGV2ZW4gYmFja3dhcmQsIHJldHVybiB1bmRlZmluZWRcbiAgaWYgKCFzdGFydC5ub2RlIHx8ICFzdGFydC5ub2RlLm1hcmtzLnNvbWUobWFyayA9PiBtYXJrLnR5cGUgPT09IHR5cGUpKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICAvLyBEZWZhdWx0IHRvIG9ubHkgbWF0Y2hpbmcgYWdhaW5zdCB0aGUgZmlyc3QgbWFyaydzIGF0dHJpYnV0ZXNcbiAgYXR0cmlidXRlcyA9IGF0dHJpYnV0ZXMgfHwgc3RhcnQubm9kZS5tYXJrc1swXT8uYXR0cnNcblxuICAvLyBXZSBub3cga25vdyB0aGF0IHRoZSBjdXJzb3IgaXMgZWl0aGVyIGF0IHRoZSBzdGFydCwgbWlkZGxlIG9yIGVuZCBvZiBhIHRleHQgbm9kZSB3aXRoIHRoZSBzcGVjaWZpZWQgbWFya1xuICAvLyBzbyB3ZSBjYW4gbG9vayBpdCB1cCBvbiB0aGUgdGFyZ2V0ZWQgbWFya1xuICBjb25zdCBtYXJrID0gZmluZE1hcmtJblNldChbLi4uc3RhcnQubm9kZS5tYXJrc10sIHR5cGUsIGF0dHJpYnV0ZXMpXG5cbiAgaWYgKCFtYXJrKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICBsZXQgc3RhcnRJbmRleCA9IHN0YXJ0LmluZGV4XG4gIGxldCBzdGFydFBvcyA9ICRwb3Muc3RhcnQoKSArIHN0YXJ0Lm9mZnNldFxuICBsZXQgZW5kSW5kZXggPSBzdGFydEluZGV4ICsgMVxuICBsZXQgZW5kUG9zID0gc3RhcnRQb3MgKyBzdGFydC5ub2RlLm5vZGVTaXplXG5cbiAgd2hpbGUgKFxuICAgIHN0YXJ0SW5kZXggPiAwXG4gICAgJiYgaXNNYXJrSW5TZXQoWy4uLiRwb3MucGFyZW50LmNoaWxkKHN0YXJ0SW5kZXggLSAxKS5tYXJrc10sIHR5cGUsIGF0dHJpYnV0ZXMpXG4gICkge1xuICAgIHN0YXJ0SW5kZXggLT0gMVxuICAgIHN0YXJ0UG9zIC09ICRwb3MucGFyZW50LmNoaWxkKHN0YXJ0SW5kZXgpLm5vZGVTaXplXG4gIH1cblxuICB3aGlsZSAoXG4gICAgZW5kSW5kZXggPCAkcG9zLnBhcmVudC5jaGlsZENvdW50XG4gICAgJiYgaXNNYXJrSW5TZXQoWy4uLiRwb3MucGFyZW50LmNoaWxkKGVuZEluZGV4KS5tYXJrc10sIHR5cGUsIGF0dHJpYnV0ZXMpXG4gICkge1xuICAgIGVuZFBvcyArPSAkcG9zLnBhcmVudC5jaGlsZChlbmRJbmRleCkubm9kZVNpemVcbiAgICBlbmRJbmRleCArPSAxXG4gIH1cblxuICByZXR1cm4ge1xuICAgIGZyb206IHN0YXJ0UG9zLFxuICAgIHRvOiBlbmRQb3MsXG4gIH1cbn1cbiIsICJpbXBvcnQgeyBNYXJrVHlwZSwgU2NoZW1hIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuZXhwb3J0IGZ1bmN0aW9uIGdldE1hcmtUeXBlKG5hbWVPclR5cGU6IHN0cmluZyB8IE1hcmtUeXBlLCBzY2hlbWE6IFNjaGVtYSk6IE1hcmtUeXBlIHtcbiAgaWYgKHR5cGVvZiBuYW1lT3JUeXBlID09PSAnc3RyaW5nJykge1xuICAgIGlmICghc2NoZW1hLm1hcmtzW25hbWVPclR5cGVdKSB7XG4gICAgICB0aHJvdyBFcnJvcihcbiAgICAgICAgYFRoZXJlIGlzIG5vIG1hcmsgdHlwZSBuYW1lZCAnJHtuYW1lT3JUeXBlfScuIE1heWJlIHlvdSBmb3Jnb3QgdG8gYWRkIHRoZSBleHRlbnNpb24/YCxcbiAgICAgIClcbiAgICB9XG5cbiAgICByZXR1cm4gc2NoZW1hLm1hcmtzW25hbWVPclR5cGVdXG4gIH1cblxuICByZXR1cm4gbmFtZU9yVHlwZVxufVxuIiwgImltcG9ydCB7IE1hcmtUeXBlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcbmltcG9ydCB7IFRleHRTZWxlY3Rpb24gfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5pbXBvcnQgeyBnZXRNYXJrUmFuZ2UgfSBmcm9tICcuLi9oZWxwZXJzL2dldE1hcmtSYW5nZS5qcydcbmltcG9ydCB7IGdldE1hcmtUeXBlIH0gZnJvbSAnLi4vaGVscGVycy9nZXRNYXJrVHlwZS5qcydcbmltcG9ydCB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBleHRlbmRNYXJrUmFuZ2U6IHtcbiAgICAgIC8qKlxuICAgICAgICogRXh0ZW5kcyB0aGUgdGV4dCBzZWxlY3Rpb24gdG8gdGhlIGN1cnJlbnQgbWFyayBieSB0eXBlIG9yIG5hbWUuXG4gICAgICAgKiBAcGFyYW0gdHlwZU9yTmFtZSBUaGUgdHlwZSBvciBuYW1lIG9mIHRoZSBtYXJrLlxuICAgICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGF0dHJpYnV0ZXMgb2YgdGhlIG1hcmsuXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuZXh0ZW5kTWFya1JhbmdlKCdib2xkJylcbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy5leHRlbmRNYXJrUmFuZ2UoJ21lbnRpb24nLCB7IHVzZXJJZDogXCIxXCIgfSlcbiAgICAgICAqL1xuICAgICAgZXh0ZW5kTWFya1JhbmdlOiAoXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgdHlwZSBvciBuYW1lIG9mIHRoZSBtYXJrLlxuICAgICAgICAgKi9cbiAgICAgICAgdHlwZU9yTmFtZTogc3RyaW5nIHwgTWFya1R5cGUsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBtYXJrLlxuICAgICAgICAgKi9cbiAgICAgICAgYXR0cmlidXRlcz86IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgICApID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGV4dGVuZE1hcmtSYW5nZTogUmF3Q29tbWFuZHNbJ2V4dGVuZE1hcmtSYW5nZSddID0gKHR5cGVPck5hbWUsIGF0dHJpYnV0ZXMgPSB7fSkgPT4gKHsgdHIsIHN0YXRlLCBkaXNwYXRjaCB9KSA9PiB7XG4gIGNvbnN0IHR5cGUgPSBnZXRNYXJrVHlwZSh0eXBlT3JOYW1lLCBzdGF0ZS5zY2hlbWEpXG4gIGNvbnN0IHsgZG9jLCBzZWxlY3Rpb24gfSA9IHRyXG4gIGNvbnN0IHsgJGZyb20sIGZyb20sIHRvIH0gPSBzZWxlY3Rpb25cblxuICBpZiAoZGlzcGF0Y2gpIHtcbiAgICBjb25zdCByYW5nZSA9IGdldE1hcmtSYW5nZSgkZnJvbSwgdHlwZSwgYXR0cmlidXRlcylcblxuICAgIGlmIChyYW5nZSAmJiByYW5nZS5mcm9tIDw9IGZyb20gJiYgcmFuZ2UudG8gPj0gdG8pIHtcbiAgICAgIGNvbnN0IG5ld1NlbGVjdGlvbiA9IFRleHRTZWxlY3Rpb24uY3JlYXRlKGRvYywgcmFuZ2UuZnJvbSwgcmFuZ2UudG8pXG5cbiAgICAgIHRyLnNldFNlbGVjdGlvbihuZXdTZWxlY3Rpb24pXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRydWVcbn1cbiIsICJpbXBvcnQgeyBDb21tYW5kLCBDb21tYW5kUHJvcHMsIFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBmaXJzdDoge1xuICAgICAgLyoqXG4gICAgICAgKiBSdW5zIG9uZSBjb21tYW5kIGFmdGVyIHRoZSBvdGhlciBhbmQgc3RvcHMgYXQgdGhlIGZpcnN0IHdoaWNoIHJldHVybnMgdHJ1ZS5cbiAgICAgICAqIEBwYXJhbSBjb21tYW5kcyBUaGUgY29tbWFuZHMgdG8gcnVuLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmZpcnN0KFtjb21tYW5kMSwgY29tbWFuZDJdKVxuICAgICAgICovXG4gICAgICBmaXJzdDogKGNvbW1hbmRzOiBDb21tYW5kW10gfCAoKHByb3BzOiBDb21tYW5kUHJvcHMpID0+IENvbW1hbmRbXSkpID0+IFJldHVyblR5cGUsXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBmaXJzdDogUmF3Q29tbWFuZHNbJ2ZpcnN0J10gPSBjb21tYW5kcyA9PiBwcm9wcyA9PiB7XG4gIGNvbnN0IGl0ZW1zID0gdHlwZW9mIGNvbW1hbmRzID09PSAnZnVuY3Rpb24nXG4gICAgPyBjb21tYW5kcyhwcm9wcylcbiAgICA6IGNvbW1hbmRzXG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBpdGVtcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgIGlmIChpdGVtc1tpXShwcm9wcykpIHtcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlXG59XG4iLCAiaW1wb3J0IHsgVGV4dFNlbGVjdGlvbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmV4cG9ydCBmdW5jdGlvbiBpc1RleHRTZWxlY3Rpb24odmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBUZXh0U2VsZWN0aW9uIHtcbiAgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgVGV4dFNlbGVjdGlvblxufVxuIiwgImV4cG9ydCBmdW5jdGlvbiBtaW5NYXgodmFsdWUgPSAwLCBtaW4gPSAwLCBtYXggPSAwKTogbnVtYmVyIHtcbiAgcmV0dXJuIE1hdGgubWluKE1hdGgubWF4KHZhbHVlLCBtaW4pLCBtYXgpXG59XG4iLCAiaW1wb3J0IHsgTm9kZSBhcyBQcm9zZU1pcnJvck5vZGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuaW1wb3J0IHsgU2VsZWN0aW9uLCBUZXh0U2VsZWN0aW9uIH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcblxuaW1wb3J0IHsgRm9jdXNQb3NpdGlvbiB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuaW1wb3J0IHsgbWluTWF4IH0gZnJvbSAnLi4vdXRpbGl0aWVzL21pbk1heC5qcydcblxuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVGb2N1c1Bvc2l0aW9uKFxuICBkb2M6IFByb3NlTWlycm9yTm9kZSxcbiAgcG9zaXRpb246IEZvY3VzUG9zaXRpb24gPSBudWxsLFxuKTogU2VsZWN0aW9uIHwgbnVsbCB7XG4gIGlmICghcG9zaXRpb24pIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgY29uc3Qgc2VsZWN0aW9uQXRTdGFydCA9IFNlbGVjdGlvbi5hdFN0YXJ0KGRvYylcbiAgY29uc3Qgc2VsZWN0aW9uQXRFbmQgPSBTZWxlY3Rpb24uYXRFbmQoZG9jKVxuXG4gIGlmIChwb3NpdGlvbiA9PT0gJ3N0YXJ0JyB8fCBwb3NpdGlvbiA9PT0gdHJ1ZSkge1xuICAgIHJldHVybiBzZWxlY3Rpb25BdFN0YXJ0XG4gIH1cblxuICBpZiAocG9zaXRpb24gPT09ICdlbmQnKSB7XG4gICAgcmV0dXJuIHNlbGVjdGlvbkF0RW5kXG4gIH1cblxuICBjb25zdCBtaW5Qb3MgPSBzZWxlY3Rpb25BdFN0YXJ0LmZyb21cbiAgY29uc3QgbWF4UG9zID0gc2VsZWN0aW9uQXRFbmQudG9cblxuICBpZiAocG9zaXRpb24gPT09ICdhbGwnKSB7XG4gICAgcmV0dXJuIFRleHRTZWxlY3Rpb24uY3JlYXRlKFxuICAgICAgZG9jLFxuICAgICAgbWluTWF4KDAsIG1pblBvcywgbWF4UG9zKSxcbiAgICAgIG1pbk1heChkb2MuY29udGVudC5zaXplLCBtaW5Qb3MsIG1heFBvcyksXG4gICAgKVxuICB9XG5cbiAgcmV0dXJuIFRleHRTZWxlY3Rpb24uY3JlYXRlKFxuICAgIGRvYyxcbiAgICBtaW5NYXgocG9zaXRpb24sIG1pblBvcywgbWF4UG9zKSxcbiAgICBtaW5NYXgocG9zaXRpb24sIG1pblBvcywgbWF4UG9zKSxcbiAgKVxufVxuIiwgImV4cG9ydCBmdW5jdGlvbiBpc0FuZHJvaWQoKTogYm9vbGVhbiB7XG4gIHJldHVybiBuYXZpZ2F0b3IucGxhdGZvcm0gPT09ICdBbmRyb2lkJyB8fCAvYW5kcm9pZC9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudClcbn1cbiIsICJleHBvcnQgZnVuY3Rpb24gaXNpT1MoKTogYm9vbGVhbiB7XG4gIHJldHVybiBbXG4gICAgJ2lQYWQgU2ltdWxhdG9yJyxcbiAgICAnaVBob25lIFNpbXVsYXRvcicsXG4gICAgJ2lQb2QgU2ltdWxhdG9yJyxcbiAgICAnaVBhZCcsXG4gICAgJ2lQaG9uZScsXG4gICAgJ2lQb2QnLFxuICBdLmluY2x1ZGVzKG5hdmlnYXRvci5wbGF0Zm9ybSlcbiAgLy8gaVBhZCBvbiBpT1MgMTMgZGV0ZWN0aW9uXG4gIHx8IChuYXZpZ2F0b3IudXNlckFnZW50LmluY2x1ZGVzKCdNYWMnKSAmJiAnb250b3VjaGVuZCcgaW4gZG9jdW1lbnQpXG59XG4iLCAiaW1wb3J0IHsgaXNUZXh0U2VsZWN0aW9uIH0gZnJvbSAnLi4vaGVscGVycy9pc1RleHRTZWxlY3Rpb24uanMnXG5pbXBvcnQgeyByZXNvbHZlRm9jdXNQb3NpdGlvbiB9IGZyb20gJy4uL2hlbHBlcnMvcmVzb2x2ZUZvY3VzUG9zaXRpb24uanMnXG5pbXBvcnQgeyBGb2N1c1Bvc2l0aW9uLCBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuaW1wb3J0IHsgaXNBbmRyb2lkIH0gZnJvbSAnLi4vdXRpbGl0aWVzL2lzQW5kcm9pZC5qcydcbmltcG9ydCB7IGlzaU9TIH0gZnJvbSAnLi4vdXRpbGl0aWVzL2lzaU9TLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgZm9jdXM6IHtcbiAgICAgIC8qKlxuICAgICAgICogRm9jdXMgdGhlIGVkaXRvciBhdCB0aGUgZ2l2ZW4gcG9zaXRpb24uXG4gICAgICAgKiBAcGFyYW0gcG9zaXRpb24gVGhlIHBvc2l0aW9uIHRvIGZvY3VzIGF0LlxuICAgICAgICogQHBhcmFtIG9wdGlvbnMuc2Nyb2xsSW50b1ZpZXcgU2Nyb2xsIHRoZSBmb2N1c2VkIHBvc2l0aW9uIGludG8gdmlldyBhZnRlciBmb2N1c2luZ1xuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmZvY3VzKClcbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy5mb2N1cygzMiwgeyBzY3JvbGxJbnRvVmlldzogZmFsc2UgfSlcbiAgICAgICAqL1xuICAgICAgZm9jdXM6IChcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBwb3NpdGlvbiB0byBmb2N1cyBhdC5cbiAgICAgICAgICovXG4gICAgICAgIHBvc2l0aW9uPzogRm9jdXNQb3NpdGlvbixcblxuICAgICAgICAvKipcbiAgICAgICAgICogT3B0aW9uYWwgb3B0aW9uc1xuICAgICAgICAgKiBAZGVmYXVsdCB7IHNjcm9sbEludG9WaWV3OiB0cnVlIH1cbiAgICAgICAgICovXG4gICAgICAgIG9wdGlvbnM/OiB7XG4gICAgICAgICAgc2Nyb2xsSW50b1ZpZXc/OiBib29sZWFuLFxuICAgICAgICB9LFxuICAgICAgKSA9PiBSZXR1cm5UeXBlLFxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgZm9jdXM6IFJhd0NvbW1hbmRzWydmb2N1cyddID0gKHBvc2l0aW9uID0gbnVsbCwgb3B0aW9ucyA9IHt9KSA9PiAoe1xuICBlZGl0b3IsXG4gIHZpZXcsXG4gIHRyLFxuICBkaXNwYXRjaCxcbn0pID0+IHtcbiAgb3B0aW9ucyA9IHtcbiAgICBzY3JvbGxJbnRvVmlldzogdHJ1ZSxcbiAgICAuLi5vcHRpb25zLFxuICB9XG5cbiAgY29uc3QgZGVsYXllZEZvY3VzID0gKCkgPT4ge1xuICAgIC8vIGZvY3VzIHdpdGhpbiBgcmVxdWVzdEFuaW1hdGlvbkZyYW1lYCBicmVha3MgZm9jdXMgb24gaU9TIGFuZCBBbmRyb2lkXG4gICAgLy8gc28gd2UgaGF2ZSB0byBjYWxsIHRoaXNcbiAgICBpZiAoaXNpT1MoKSB8fCBpc0FuZHJvaWQoKSkge1xuICAgICAgKHZpZXcuZG9tIGFzIEhUTUxFbGVtZW50KS5mb2N1cygpXG4gICAgfVxuXG4gICAgLy8gRm9yIFJlYWN0IHdlIGhhdmUgdG8gZm9jdXMgYXN5bmNocm9ub3VzbHkuIE90aGVyd2lzZSB3aWxkIHRoaW5ncyBoYXBwZW4uXG4gICAgLy8gc2VlOiBodHRwczovL2dpdGh1Yi5jb20vdWViZXJkb3Npcy90aXB0YXAvaXNzdWVzLzE1MjBcbiAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgaWYgKCFlZGl0b3IuaXNEZXN0cm95ZWQpIHtcbiAgICAgICAgdmlldy5mb2N1cygpXG5cbiAgICAgICAgaWYgKG9wdGlvbnM/LnNjcm9sbEludG9WaWV3KSB7XG4gICAgICAgICAgZWRpdG9yLmNvbW1hbmRzLnNjcm9sbEludG9WaWV3KClcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICBpZiAoKHZpZXcuaGFzRm9jdXMoKSAmJiBwb3NpdGlvbiA9PT0gbnVsbCkgfHwgcG9zaXRpb24gPT09IGZhbHNlKSB7XG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIC8vIHdlIGRvbuKAmXQgdHJ5IHRvIHJlc29sdmUgYSBOb2RlU2VsZWN0aW9uIG9yIENlbGxTZWxlY3Rpb25cbiAgaWYgKGRpc3BhdGNoICYmIHBvc2l0aW9uID09PSBudWxsICYmICFpc1RleHRTZWxlY3Rpb24oZWRpdG9yLnN0YXRlLnNlbGVjdGlvbikpIHtcbiAgICBkZWxheWVkRm9jdXMoKVxuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICAvLyBwYXNzIHRocm91Z2ggdHIuZG9jIGluc3RlYWQgb2YgZWRpdG9yLnN0YXRlLmRvY1xuICAvLyBzaW5jZSB0cmFuc2FjdGlvbnMgY291bGQgY2hhbmdlIHRoZSBlZGl0b3JzIHN0YXRlIGJlZm9yZSB0aGlzIGNvbW1hbmQgaGFzIGJlZW4gcnVuXG4gIGNvbnN0IHNlbGVjdGlvbiA9IHJlc29sdmVGb2N1c1Bvc2l0aW9uKHRyLmRvYywgcG9zaXRpb24pIHx8IGVkaXRvci5zdGF0ZS5zZWxlY3Rpb25cbiAgY29uc3QgaXNTYW1lU2VsZWN0aW9uID0gZWRpdG9yLnN0YXRlLnNlbGVjdGlvbi5lcShzZWxlY3Rpb24pXG5cbiAgaWYgKGRpc3BhdGNoKSB7XG4gICAgaWYgKCFpc1NhbWVTZWxlY3Rpb24pIHtcbiAgICAgIHRyLnNldFNlbGVjdGlvbihzZWxlY3Rpb24pXG4gICAgfVxuXG4gICAgLy8gYHRyLnNldFNlbGVjdGlvbmAgcmVzZXRzIHRoZSBzdG9yZWQgbWFya3NcbiAgICAvLyBzbyB3ZeKAmWxsIHJlc3RvcmUgdGhlbSBpZiB0aGUgc2VsZWN0aW9uIGlzIHRoZSBzYW1lIGFzIGJlZm9yZVxuICAgIGlmIChpc1NhbWVTZWxlY3Rpb24gJiYgdHIuc3RvcmVkTWFya3MpIHtcbiAgICAgIHRyLnNldFN0b3JlZE1hcmtzKHRyLnN0b3JlZE1hcmtzKVxuICAgIH1cblxuICAgIGRlbGF5ZWRGb2N1cygpXG4gIH1cblxuICByZXR1cm4gdHJ1ZVxufVxuIiwgImltcG9ydCB7IENvbW1hbmRQcm9wcywgUmF3Q29tbWFuZHMgfSBmcm9tICcuLi90eXBlcy5qcydcblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIGZvckVhY2g6IHtcbiAgICAgIC8qKlxuICAgICAgICogTG9vcCB0aHJvdWdoIGFuIGFycmF5IG9mIGl0ZW1zLlxuICAgICAgICovXG4gICAgICBmb3JFYWNoOiA8VD4oXG4gICAgICAgIGl0ZW1zOiBUW10sXG4gICAgICAgIGZuOiAoXG4gICAgICAgICAgaXRlbTogVCxcbiAgICAgICAgICBwcm9wczogQ29tbWFuZFByb3BzICYge1xuICAgICAgICAgICAgaW5kZXg6IG51bWJlcixcbiAgICAgICAgICB9LFxuICAgICAgICApID0+IGJvb2xlYW4sXG4gICAgICApID0+IFJldHVyblR5cGUsXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBmb3JFYWNoOiBSYXdDb21tYW5kc1snZm9yRWFjaCddID0gKGl0ZW1zLCBmbikgPT4gcHJvcHMgPT4ge1xuICByZXR1cm4gaXRlbXMuZXZlcnkoKGl0ZW0sIGluZGV4KSA9PiBmbihpdGVtLCB7IC4uLnByb3BzLCBpbmRleCB9KSlcbn1cbiIsICJpbXBvcnQgeyBGcmFnbWVudCwgTm9kZSBhcyBQcm9zZU1pcnJvck5vZGUsIFBhcnNlT3B0aW9ucyB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmltcG9ydCB7IENvbnRlbnQsIFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBpbnNlcnRDb250ZW50OiB7XG4gICAgICAvKipcbiAgICAgICAqIEluc2VydCBhIG5vZGUgb3Igc3RyaW5nIG9mIEhUTUwgYXQgdGhlIGN1cnJlbnQgcG9zaXRpb24uXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuaW5zZXJ0Q29udGVudCgnPGgxPkV4YW1wbGU8L2gxPicpXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuaW5zZXJ0Q29udGVudCgnPGgxPkV4YW1wbGU8L2gxPicsIHsgdXBkYXRlU2VsZWN0aW9uOiBmYWxzZSB9KVxuICAgICAgICovXG4gICAgICBpbnNlcnRDb250ZW50OiAoXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgUHJvc2VNaXJyb3IgY29udGVudCB0byBpbnNlcnQuXG4gICAgICAgICAqL1xuICAgICAgICB2YWx1ZTogQ29udGVudCB8IFByb3NlTWlycm9yTm9kZSB8IEZyYWdtZW50LFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBPcHRpb25hbCBvcHRpb25zXG4gICAgICAgICAqL1xuICAgICAgICBvcHRpb25zPzoge1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIE9wdGlvbnMgZm9yIHBhcnNpbmcgdGhlIGNvbnRlbnQuXG4gICAgICAgICAgICovXG4gICAgICAgICAgcGFyc2VPcHRpb25zPzogUGFyc2VPcHRpb25zO1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogV2hldGhlciB0byB1cGRhdGUgdGhlIHNlbGVjdGlvbiBhZnRlciBpbnNlcnRpbmcgdGhlIGNvbnRlbnQuXG4gICAgICAgICAgICovXG4gICAgICAgICAgdXBkYXRlU2VsZWN0aW9uPzogYm9vbGVhbjtcbiAgICAgICAgICBhcHBseUlucHV0UnVsZXM/OiBib29sZWFuO1xuICAgICAgICAgIGFwcGx5UGFzdGVSdWxlcz86IGJvb2xlYW47XG4gICAgICAgIH1cbiAgICAgICkgPT4gUmV0dXJuVHlwZTtcbiAgICB9O1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCBpbnNlcnRDb250ZW50OiBSYXdDb21tYW5kc1snaW5zZXJ0Q29udGVudCddID0gKHZhbHVlLCBvcHRpb25zKSA9PiAoeyB0ciwgY29tbWFuZHMgfSkgPT4ge1xuICByZXR1cm4gY29tbWFuZHMuaW5zZXJ0Q29udGVudEF0KFxuICAgIHsgZnJvbTogdHIuc2VsZWN0aW9uLmZyb20sIHRvOiB0ci5zZWxlY3Rpb24udG8gfSxcbiAgICB2YWx1ZSxcbiAgICBvcHRpb25zLFxuICApXG59XG4iLCAiY29uc3QgcmVtb3ZlV2hpdGVzcGFjZXMgPSAobm9kZTogSFRNTEVsZW1lbnQpID0+IHtcbiAgY29uc3QgY2hpbGRyZW4gPSBub2RlLmNoaWxkTm9kZXNcblxuICBmb3IgKGxldCBpID0gY2hpbGRyZW4ubGVuZ3RoIC0gMTsgaSA+PSAwOyBpIC09IDEpIHtcbiAgICBjb25zdCBjaGlsZCA9IGNoaWxkcmVuW2ldXG5cbiAgICBpZiAoY2hpbGQubm9kZVR5cGUgPT09IDMgJiYgY2hpbGQubm9kZVZhbHVlICYmIC9eKFxcblxcc1xcc3xcXG4pJC8udGVzdChjaGlsZC5ub2RlVmFsdWUpKSB7XG4gICAgICBub2RlLnJlbW92ZUNoaWxkKGNoaWxkKVxuICAgIH0gZWxzZSBpZiAoY2hpbGQubm9kZVR5cGUgPT09IDEpIHtcbiAgICAgIHJlbW92ZVdoaXRlc3BhY2VzKGNoaWxkIGFzIEhUTUxFbGVtZW50KVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBub2RlXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBlbGVtZW50RnJvbVN0cmluZyh2YWx1ZTogc3RyaW5nKTogSFRNTEVsZW1lbnQge1xuICAvLyBhZGQgYSB3cmFwcGVyIHRvIHByZXNlcnZlIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHdoaXRlc3BhY2VcbiAgY29uc3Qgd3JhcHBlZFZhbHVlID0gYDxib2R5PiR7dmFsdWV9PC9ib2R5PmBcblxuICBjb25zdCBodG1sID0gbmV3IHdpbmRvdy5ET01QYXJzZXIoKS5wYXJzZUZyb21TdHJpbmcod3JhcHBlZFZhbHVlLCAndGV4dC9odG1sJykuYm9keVxuXG4gIHJldHVybiByZW1vdmVXaGl0ZXNwYWNlcyhodG1sKVxufVxuIiwgImltcG9ydCB7XG4gIERPTVBhcnNlcixcbiAgRnJhZ21lbnQsXG4gIE5vZGUgYXMgUHJvc2VNaXJyb3JOb2RlLFxuICBQYXJzZU9wdGlvbnMsXG4gIFNjaGVtYSxcbn0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuaW1wb3J0IHsgQ29udGVudCB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuaW1wb3J0IHsgZWxlbWVudEZyb21TdHJpbmcgfSBmcm9tICcuLi91dGlsaXRpZXMvZWxlbWVudEZyb21TdHJpbmcuanMnXG5cbmV4cG9ydCB0eXBlIENyZWF0ZU5vZGVGcm9tQ29udGVudE9wdGlvbnMgPSB7XG4gIHNsaWNlPzogYm9vbGVhblxuICBwYXJzZU9wdGlvbnM/OiBQYXJzZU9wdGlvbnNcbiAgZXJyb3JPbkludmFsaWRDb250ZW50PzogYm9vbGVhblxufVxuXG4vKipcbiAqIFRha2VzIGEgSlNPTiBvciBIVE1MIGNvbnRlbnQgYW5kIGNyZWF0ZXMgYSBQcm9zZW1pcnJvciBub2RlIG9yIGZyYWdtZW50IGZyb20gaXQuXG4gKiBAcGFyYW0gY29udGVudCBUaGUgSlNPTiBvciBIVE1MIGNvbnRlbnQgdG8gY3JlYXRlIHRoZSBub2RlIGZyb21cbiAqIEBwYXJhbSBzY2hlbWEgVGhlIFByb3NlbWlycm9yIHNjaGVtYSB0byB1c2UgZm9yIHRoZSBub2RlXG4gKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25zIGZvciB0aGUgcGFyc2VyXG4gKiBAcmV0dXJucyBUaGUgY3JlYXRlZCBQcm9zZW1pcnJvciBub2RlIG9yIGZyYWdtZW50XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVOb2RlRnJvbUNvbnRlbnQoXG4gIGNvbnRlbnQ6IENvbnRlbnQgfCBQcm9zZU1pcnJvck5vZGUgfCBGcmFnbWVudCxcbiAgc2NoZW1hOiBTY2hlbWEsXG4gIG9wdGlvbnM/OiBDcmVhdGVOb2RlRnJvbUNvbnRlbnRPcHRpb25zLFxuKTogUHJvc2VNaXJyb3JOb2RlIHwgRnJhZ21lbnQge1xuICBpZiAoY29udGVudCBpbnN0YW5jZW9mIFByb3NlTWlycm9yTm9kZSB8fCBjb250ZW50IGluc3RhbmNlb2YgRnJhZ21lbnQpIHtcbiAgICByZXR1cm4gY29udGVudFxuICB9XG4gIG9wdGlvbnMgPSB7XG4gICAgc2xpY2U6IHRydWUsXG4gICAgcGFyc2VPcHRpb25zOiB7fSxcbiAgICAuLi5vcHRpb25zLFxuICB9XG5cbiAgY29uc3QgaXNKU09OQ29udGVudCA9IHR5cGVvZiBjb250ZW50ID09PSAnb2JqZWN0JyAmJiBjb250ZW50ICE9PSBudWxsXG4gIGNvbnN0IGlzVGV4dENvbnRlbnQgPSB0eXBlb2YgY29udGVudCA9PT0gJ3N0cmluZydcblxuICBpZiAoaXNKU09OQ29udGVudCkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBpc0FycmF5Q29udGVudCA9IEFycmF5LmlzQXJyYXkoY29udGVudCkgJiYgY29udGVudC5sZW5ndGggPiAwXG5cbiAgICAgIC8vIGlmIHRoZSBKU09OIENvbnRlbnQgaXMgYW4gYXJyYXkgb2Ygbm9kZXMsIGNyZWF0ZSBhIGZyYWdtZW50IGZvciBlYWNoIG5vZGVcbiAgICAgIGlmIChpc0FycmF5Q29udGVudCkge1xuICAgICAgICByZXR1cm4gRnJhZ21lbnQuZnJvbUFycmF5KGNvbnRlbnQubWFwKGl0ZW0gPT4gc2NoZW1hLm5vZGVGcm9tSlNPTihpdGVtKSkpXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG5vZGUgPSBzY2hlbWEubm9kZUZyb21KU09OKGNvbnRlbnQpXG5cbiAgICAgIGlmIChvcHRpb25zLmVycm9yT25JbnZhbGlkQ29udGVudCkge1xuICAgICAgICBub2RlLmNoZWNrKClcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG5vZGVcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKG9wdGlvbnMuZXJyb3JPbkludmFsaWRDb250ZW50KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignW3RpcHRhcCBlcnJvcl06IEludmFsaWQgSlNPTiBjb250ZW50JywgeyBjYXVzZTogZXJyb3IgYXMgRXJyb3IgfSlcbiAgICAgIH1cblxuICAgICAgY29uc29sZS53YXJuKCdbdGlwdGFwIHdhcm5dOiBJbnZhbGlkIGNvbnRlbnQuJywgJ1Bhc3NlZCB2YWx1ZTonLCBjb250ZW50LCAnRXJyb3I6JywgZXJyb3IpXG5cbiAgICAgIHJldHVybiBjcmVhdGVOb2RlRnJvbUNvbnRlbnQoJycsIHNjaGVtYSwgb3B0aW9ucylcbiAgICB9XG4gIH1cblxuICBpZiAoaXNUZXh0Q29udGVudCkge1xuXG4gICAgLy8gQ2hlY2sgZm9yIGludmFsaWQgY29udGVudFxuICAgIGlmIChvcHRpb25zLmVycm9yT25JbnZhbGlkQ29udGVudCkge1xuICAgICAgbGV0IGhhc0ludmFsaWRDb250ZW50ID0gZmFsc2VcbiAgICAgIGxldCBpbnZhbGlkQ29udGVudCA9ICcnXG5cbiAgICAgIC8vIEEgY29weSBvZiB0aGUgY3VycmVudCBzY2hlbWEgd2l0aCBhIGNhdGNoLWFsbCBub2RlIGF0IHRoZSBlbmRcbiAgICAgIGNvbnN0IGNvbnRlbnRDaGVja1NjaGVtYSA9IG5ldyBTY2hlbWEoe1xuICAgICAgICB0b3BOb2RlOiBzY2hlbWEuc3BlYy50b3BOb2RlLFxuICAgICAgICBtYXJrczogc2NoZW1hLnNwZWMubWFya3MsXG4gICAgICAgIC8vIFByb3NlbWlycm9yJ3Mgc2NoZW1hcyBhcmUgZXhlY3V0ZWQgc3VjaCB0aGF0OiB0aGUgbGFzdCB0byBleGVjdXRlLCBtYXRjaGVzIGxhc3RcbiAgICAgICAgLy8gVGhpcyBtZWFucyB0aGF0IHdlIGNhbiBhZGQgYSBjYXRjaC1hbGwgbm9kZSBhdCB0aGUgZW5kIG9mIHRoZSBzY2hlbWEgdG8gY2F0Y2ggYW55IGNvbnRlbnQgdGhhdCB3ZSBkb24ndCBrbm93IGhvdyB0byBoYW5kbGVcbiAgICAgICAgbm9kZXM6IHNjaGVtYS5zcGVjLm5vZGVzLmFwcGVuZCh7XG4gICAgICAgICAgX190aXB0YXBfX3ByaXZhdGVfX3Vua25vd25fX2NhdGNoX19hbGxfX25vZGU6IHtcbiAgICAgICAgICAgIGNvbnRlbnQ6ICdpbmxpbmUqJyxcbiAgICAgICAgICAgIGdyb3VwOiAnYmxvY2snLFxuICAgICAgICAgICAgcGFyc2VET006IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHRhZzogJyonLFxuICAgICAgICAgICAgICAgIGdldEF0dHJzOiBlID0+IHtcbiAgICAgICAgICAgICAgICAgIC8vIElmIHRoaXMgaXMgZXZlciBjYWxsZWQsIHdlIGtub3cgdGhhdCB0aGUgY29udGVudCBoYXMgc29tZXRoaW5nIHRoYXQgd2UgZG9uJ3Qga25vdyBob3cgdG8gaGFuZGxlIGluIHRoZSBzY2hlbWFcbiAgICAgICAgICAgICAgICAgIGhhc0ludmFsaWRDb250ZW50ID0gdHJ1ZVxuICAgICAgICAgICAgICAgICAgLy8gVHJ5IHRvIHN0cmluZ2lmeSB0aGUgZWxlbWVudCBmb3IgYSBtb3JlIGhlbHBmdWwgZXJyb3IgbWVzc2FnZVxuICAgICAgICAgICAgICAgICAgaW52YWxpZENvbnRlbnQgPSB0eXBlb2YgZSA9PT0gJ3N0cmluZycgPyBlIDogZS5vdXRlckhUTUxcbiAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICB9KVxuXG4gICAgICBpZiAob3B0aW9ucy5zbGljZSkge1xuICAgICAgICBET01QYXJzZXIuZnJvbVNjaGVtYShjb250ZW50Q2hlY2tTY2hlbWEpLnBhcnNlU2xpY2UoZWxlbWVudEZyb21TdHJpbmcoY29udGVudCksIG9wdGlvbnMucGFyc2VPcHRpb25zKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgRE9NUGFyc2VyLmZyb21TY2hlbWEoY29udGVudENoZWNrU2NoZW1hKS5wYXJzZShlbGVtZW50RnJvbVN0cmluZyhjb250ZW50KSwgb3B0aW9ucy5wYXJzZU9wdGlvbnMpXG4gICAgICB9XG5cbiAgICAgIGlmIChvcHRpb25zLmVycm9yT25JbnZhbGlkQ29udGVudCAmJiBoYXNJbnZhbGlkQ29udGVudCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1t0aXB0YXAgZXJyb3JdOiBJbnZhbGlkIEhUTUwgY29udGVudCcsIHsgY2F1c2U6IG5ldyBFcnJvcihgSW52YWxpZCBlbGVtZW50IGZvdW5kOiAke2ludmFsaWRDb250ZW50fWApIH0pXG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgcGFyc2VyID0gRE9NUGFyc2VyLmZyb21TY2hlbWEoc2NoZW1hKVxuXG4gICAgaWYgKG9wdGlvbnMuc2xpY2UpIHtcbiAgICAgIHJldHVybiBwYXJzZXIucGFyc2VTbGljZShlbGVtZW50RnJvbVN0cmluZyhjb250ZW50KSwgb3B0aW9ucy5wYXJzZU9wdGlvbnMpLmNvbnRlbnRcbiAgICB9XG5cbiAgICByZXR1cm4gcGFyc2VyLnBhcnNlKGVsZW1lbnRGcm9tU3RyaW5nKGNvbnRlbnQpLCBvcHRpb25zLnBhcnNlT3B0aW9ucylcblxuICB9XG5cbiAgcmV0dXJuIGNyZWF0ZU5vZGVGcm9tQ29udGVudCgnJywgc2NoZW1hLCBvcHRpb25zKVxufVxuIiwgImltcG9ydCB7IFNlbGVjdGlvbiwgVHJhbnNhY3Rpb24gfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuaW1wb3J0IHsgUmVwbGFjZUFyb3VuZFN0ZXAsIFJlcGxhY2VTdGVwIH0gZnJvbSAnQHRpcHRhcC9wbS90cmFuc2Zvcm0nXG5cbi8vIHNvdXJjZTogaHR0cHM6Ly9naXRodWIuY29tL1Byb3NlTWlycm9yL3Byb3NlbWlycm9yLXN0YXRlL2Jsb2IvbWFzdGVyL3NyYy9zZWxlY3Rpb24uanMjTDQ2NlxuZXhwb3J0IGZ1bmN0aW9uIHNlbGVjdGlvblRvSW5zZXJ0aW9uRW5kKHRyOiBUcmFuc2FjdGlvbiwgc3RhcnRMZW46IG51bWJlciwgYmlhczogbnVtYmVyKSB7XG4gIGNvbnN0IGxhc3QgPSB0ci5zdGVwcy5sZW5ndGggLSAxXG5cbiAgaWYgKGxhc3QgPCBzdGFydExlbikge1xuICAgIHJldHVyblxuICB9XG5cbiAgY29uc3Qgc3RlcCA9IHRyLnN0ZXBzW2xhc3RdXG5cbiAgaWYgKCEoc3RlcCBpbnN0YW5jZW9mIFJlcGxhY2VTdGVwIHx8IHN0ZXAgaW5zdGFuY2VvZiBSZXBsYWNlQXJvdW5kU3RlcCkpIHtcbiAgICByZXR1cm5cbiAgfVxuXG4gIGNvbnN0IG1hcCA9IHRyLm1hcHBpbmcubWFwc1tsYXN0XVxuICBsZXQgZW5kID0gMFxuXG4gIG1hcC5mb3JFYWNoKChfZnJvbSwgX3RvLCBfbmV3RnJvbSwgbmV3VG8pID0+IHtcbiAgICBpZiAoZW5kID09PSAwKSB7XG4gICAgICBlbmQgPSBuZXdUb1xuICAgIH1cbiAgfSlcblxuICB0ci5zZXRTZWxlY3Rpb24oU2VsZWN0aW9uLm5lYXIodHIuZG9jLnJlc29sdmUoZW5kKSwgYmlhcykpXG59XG4iLCAiaW1wb3J0IHsgRnJhZ21lbnQsIE5vZGUgYXMgUHJvc2VNaXJyb3JOb2RlLCBQYXJzZU9wdGlvbnMgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgeyBjcmVhdGVOb2RlRnJvbUNvbnRlbnQgfSBmcm9tICcuLi9oZWxwZXJzL2NyZWF0ZU5vZGVGcm9tQ29udGVudC5qcydcbmltcG9ydCB7IHNlbGVjdGlvblRvSW5zZXJ0aW9uRW5kIH0gZnJvbSAnLi4vaGVscGVycy9zZWxlY3Rpb25Ub0luc2VydGlvbkVuZC5qcydcbmltcG9ydCB7IENvbnRlbnQsIFJhbmdlLCBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgaW5zZXJ0Q29udGVudEF0OiB7XG4gICAgICAvKipcbiAgICAgICAqIEluc2VydCBhIG5vZGUgb3Igc3RyaW5nIG9mIEhUTUwgYXQgYSBzcGVjaWZpYyBwb3NpdGlvbi5cbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy5pbnNlcnRDb250ZW50QXQoMCwgJzxoMT5FeGFtcGxlPC9oMT4nKVxuICAgICAgICovXG4gICAgICBpbnNlcnRDb250ZW50QXQ6IChcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBwb3NpdGlvbiB0byBpbnNlcnQgdGhlIGNvbnRlbnQgYXQuXG4gICAgICAgICAqL1xuICAgICAgICBwb3NpdGlvbjogbnVtYmVyIHwgUmFuZ2UsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBQcm9zZU1pcnJvciBjb250ZW50IHRvIGluc2VydC5cbiAgICAgICAgICovXG4gICAgICAgIHZhbHVlOiBDb250ZW50IHwgUHJvc2VNaXJyb3JOb2RlIHwgRnJhZ21lbnQsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE9wdGlvbmFsIG9wdGlvbnNcbiAgICAgICAgICovXG4gICAgICAgIG9wdGlvbnM/OiB7XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogT3B0aW9ucyBmb3IgcGFyc2luZyB0aGUgY29udGVudC5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBwYXJzZU9wdGlvbnM/OiBQYXJzZU9wdGlvbnNcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFdoZXRoZXIgdG8gdXBkYXRlIHRoZSBzZWxlY3Rpb24gYWZ0ZXIgaW5zZXJ0aW5nIHRoZSBjb250ZW50LlxuICAgICAgICAgICAqL1xuICAgICAgICAgIHVwZGF0ZVNlbGVjdGlvbj86IGJvb2xlYW5cblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFdoZXRoZXIgdG8gYXBwbHkgaW5wdXQgcnVsZXMgYWZ0ZXIgaW5zZXJ0aW5nIHRoZSBjb250ZW50LlxuICAgICAgICAgICAqL1xuICAgICAgICAgIGFwcGx5SW5wdXRSdWxlcz86IGJvb2xlYW5cblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFdoZXRoZXIgdG8gYXBwbHkgcGFzdGUgcnVsZXMgYWZ0ZXIgaW5zZXJ0aW5nIHRoZSBjb250ZW50LlxuICAgICAgICAgICAqL1xuICAgICAgICAgIGFwcGx5UGFzdGVSdWxlcz86IGJvb2xlYW5cblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFdoZXRoZXIgdG8gdGhyb3cgYW4gZXJyb3IgaWYgdGhlIGNvbnRlbnQgaXMgaW52YWxpZC5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICBlcnJvck9uSW52YWxpZENvbnRlbnQ/OiBib29sZWFuXG4gICAgICAgIH0sXG4gICAgICApID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuY29uc3QgaXNGcmFnbWVudCA9IChub2RlT3JGcmFnbWVudDogUHJvc2VNaXJyb3JOb2RlIHwgRnJhZ21lbnQpOiBub2RlT3JGcmFnbWVudCBpcyBGcmFnbWVudCA9PiB7XG4gIHJldHVybiAhKCd0eXBlJyBpbiBub2RlT3JGcmFnbWVudClcbn1cblxuZXhwb3J0IGNvbnN0IGluc2VydENvbnRlbnRBdDogUmF3Q29tbWFuZHNbJ2luc2VydENvbnRlbnRBdCddID0gKHBvc2l0aW9uLCB2YWx1ZSwgb3B0aW9ucykgPT4gKHsgdHIsIGRpc3BhdGNoLCBlZGl0b3IgfSkgPT4ge1xuICBpZiAoZGlzcGF0Y2gpIHtcbiAgICBvcHRpb25zID0ge1xuICAgICAgcGFyc2VPcHRpb25zOiBlZGl0b3Iub3B0aW9ucy5wYXJzZU9wdGlvbnMsXG4gICAgICB1cGRhdGVTZWxlY3Rpb246IHRydWUsXG4gICAgICBhcHBseUlucHV0UnVsZXM6IGZhbHNlLFxuICAgICAgYXBwbHlQYXN0ZVJ1bGVzOiBmYWxzZSxcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgfVxuXG4gICAgbGV0IGNvbnRlbnQ6IEZyYWdtZW50IHwgUHJvc2VNaXJyb3JOb2RlXG5cbiAgICB0cnkge1xuICAgICAgY29udGVudCA9IGNyZWF0ZU5vZGVGcm9tQ29udGVudCh2YWx1ZSwgZWRpdG9yLnNjaGVtYSwge1xuICAgICAgICBwYXJzZU9wdGlvbnM6IHtcbiAgICAgICAgICBwcmVzZXJ2ZVdoaXRlc3BhY2U6ICdmdWxsJyxcbiAgICAgICAgICAuLi5vcHRpb25zLnBhcnNlT3B0aW9ucyxcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3JPbkludmFsaWRDb250ZW50OiBvcHRpb25zLmVycm9yT25JbnZhbGlkQ29udGVudCA/PyBlZGl0b3Iub3B0aW9ucy5lbmFibGVDb250ZW50Q2hlY2ssXG4gICAgICB9KVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGVkaXRvci5lbWl0KCdjb250ZW50RXJyb3InLCB7XG4gICAgICAgIGVkaXRvcixcbiAgICAgICAgZXJyb3I6IGUgYXMgRXJyb3IsXG4gICAgICAgIGRpc2FibGVDb2xsYWJvcmF0aW9uOiAoKSA9PiB7XG4gICAgICAgICAgaWYgKGVkaXRvci5zdG9yYWdlLmNvbGxhYm9yYXRpb24pIHtcbiAgICAgICAgICAgIGVkaXRvci5zdG9yYWdlLmNvbGxhYm9yYXRpb24uaXNEaXNhYmxlZCA9IHRydWVcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICB9KVxuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgbGV0IHsgZnJvbSwgdG8gfSA9IHR5cGVvZiBwb3NpdGlvbiA9PT0gJ251bWJlcicgPyB7IGZyb206IHBvc2l0aW9uLCB0bzogcG9zaXRpb24gfSA6IHsgZnJvbTogcG9zaXRpb24uZnJvbSwgdG86IHBvc2l0aW9uLnRvIH1cblxuICAgIGxldCBpc09ubHlUZXh0Q29udGVudCA9IHRydWVcbiAgICBsZXQgaXNPbmx5QmxvY2tDb250ZW50ID0gdHJ1ZVxuICAgIGNvbnN0IG5vZGVzID0gaXNGcmFnbWVudChjb250ZW50KSA/IGNvbnRlbnQgOiBbY29udGVudF1cblxuICAgIG5vZGVzLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAvLyBjaGVjayBpZiBhZGRlZCBub2RlIGlzIHZhbGlkXG4gICAgICBub2RlLmNoZWNrKClcblxuICAgICAgaXNPbmx5VGV4dENvbnRlbnQgPSBpc09ubHlUZXh0Q29udGVudCA/IG5vZGUuaXNUZXh0ICYmIG5vZGUubWFya3MubGVuZ3RoID09PSAwIDogZmFsc2VcblxuICAgICAgaXNPbmx5QmxvY2tDb250ZW50ID0gaXNPbmx5QmxvY2tDb250ZW50ID8gbm9kZS5pc0Jsb2NrIDogZmFsc2VcbiAgICB9KVxuXG4gICAgLy8gY2hlY2sgaWYgd2UgY2FuIHJlcGxhY2UgdGhlIHdyYXBwaW5nIG5vZGUgYnlcbiAgICAvLyB0aGUgbmV3bHkgaW5zZXJ0ZWQgY29udGVudFxuICAgIC8vIGV4YW1wbGU6XG4gICAgLy8gcmVwbGFjZSBhbiBlbXB0eSBwYXJhZ3JhcGggYnkgYW4gaW5zZXJ0ZWQgaW1hZ2VcbiAgICAvLyBpbnN0ZWFkIG9mIGluc2VydGluZyB0aGUgaW1hZ2UgYmVsb3cgdGhlIHBhcmFncmFwaFxuICAgIGlmIChmcm9tID09PSB0byAmJiBpc09ubHlCbG9ja0NvbnRlbnQpIHtcbiAgICAgIGNvbnN0IHsgcGFyZW50IH0gPSB0ci5kb2MucmVzb2x2ZShmcm9tKVxuICAgICAgY29uc3QgaXNFbXB0eVRleHRCbG9jayA9IHBhcmVudC5pc1RleHRibG9jayAmJiAhcGFyZW50LnR5cGUuc3BlYy5jb2RlICYmICFwYXJlbnQuY2hpbGRDb3VudFxuXG4gICAgICBpZiAoaXNFbXB0eVRleHRCbG9jaykge1xuICAgICAgICBmcm9tIC09IDFcbiAgICAgICAgdG8gKz0gMVxuICAgICAgfVxuICAgIH1cblxuICAgIGxldCBuZXdDb250ZW50XG5cbiAgICAvLyBpZiB0aGVyZSBpcyBvbmx5IHBsYWluIHRleHQgd2UgaGF2ZSB0byB1c2UgYGluc2VydFRleHRgXG4gICAgLy8gYmVjYXVzZSB0aGlzIHdpbGwga2VlcCB0aGUgY3VycmVudCBtYXJrc1xuICAgIGlmIChpc09ubHlUZXh0Q29udGVudCkge1xuICAgICAgLy8gaWYgdmFsdWUgaXMgc3RyaW5nLCB3ZSBjYW4gdXNlIGl0IGRpcmVjdGx5XG4gICAgICAvLyBvdGhlcndpc2UgaWYgaXQgaXMgYW4gYXJyYXksIHdlIGhhdmUgdG8gam9pbiBpdFxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgIG5ld0NvbnRlbnQgPSB2YWx1ZS5tYXAodiA9PiB2LnRleHQgfHwgJycpLmpvaW4oJycpXG4gICAgICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgRnJhZ21lbnQpIHtcbiAgICAgICAgbGV0IHRleHQgPSAnJ1xuXG4gICAgICAgIHZhbHVlLmZvckVhY2gobm9kZSA9PiB7XG4gICAgICAgICAgaWYgKG5vZGUudGV4dCkge1xuICAgICAgICAgICAgdGV4dCArPSBub2RlLnRleHRcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG5cbiAgICAgICAgbmV3Q29udGVudCA9IHRleHRcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiAhIXZhbHVlICYmICEhdmFsdWUudGV4dCkge1xuICAgICAgICBuZXdDb250ZW50ID0gdmFsdWUudGV4dFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmV3Q29udGVudCA9IHZhbHVlIGFzIHN0cmluZ1xuICAgICAgfVxuXG4gICAgICB0ci5pbnNlcnRUZXh0KG5ld0NvbnRlbnQsIGZyb20sIHRvKVxuICAgIH0gZWxzZSB7XG4gICAgICBuZXdDb250ZW50ID0gY29udGVudFxuXG4gICAgICB0ci5yZXBsYWNlV2l0aChmcm9tLCB0bywgbmV3Q29udGVudClcbiAgICB9XG5cbiAgICAvLyBzZXQgY3Vyc29yIGF0IGVuZCBvZiBpbnNlcnRlZCBjb250ZW50XG4gICAgaWYgKG9wdGlvbnMudXBkYXRlU2VsZWN0aW9uKSB7XG4gICAgICBzZWxlY3Rpb25Ub0luc2VydGlvbkVuZCh0ciwgdHIuc3RlcHMubGVuZ3RoIC0gMSwgLTEpXG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMuYXBwbHlJbnB1dFJ1bGVzKSB7XG4gICAgICB0ci5zZXRNZXRhKCdhcHBseUlucHV0UnVsZXMnLCB7IGZyb20sIHRleHQ6IG5ld0NvbnRlbnQgfSlcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5hcHBseVBhc3RlUnVsZXMpIHtcbiAgICAgIHRyLnNldE1ldGEoJ2FwcGx5UGFzdGVSdWxlcycsIHsgZnJvbSwgdGV4dDogbmV3Q29udGVudCB9KVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0cnVlXG59XG4iLCAiaW1wb3J0IHtcbiAgam9pbkJhY2t3YXJkIGFzIG9yaWdpbmFsSm9pbkJhY2t3YXJkLFxuICBqb2luRG93biBhcyBvcmlnaW5hbEpvaW5Eb3duLFxuICBqb2luRm9yd2FyZCBhcyBvcmlnaW5hbEpvaW5Gb3J3YXJkLFxuICBqb2luVXAgYXMgb3JpZ2luYWxKb2luVXAsXG59IGZyb20gJ0B0aXB0YXAvcG0vY29tbWFuZHMnXG5cbmltcG9ydCB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBqb2luVXA6IHtcbiAgICAgIC8qKlxuICAgICAgICogSm9pbiB0aGUgc2VsZWN0ZWQgYmxvY2sgb3IsIGlmIHRoZXJlIGlzIGEgdGV4dCBzZWxlY3Rpb24sIHRoZSBjbG9zZXN0IGFuY2VzdG9yIGJsb2NrIG9mIHRoZSBzZWxlY3Rpb24gdGhhdCBjYW4gYmUgam9pbmVkLCB3aXRoIHRoZSBzaWJsaW5nIGFib3ZlIGl0LlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmpvaW5VcCgpXG4gICAgICAgKi9cbiAgICAgIGpvaW5VcDogKCkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgICBqb2luRG93bjoge1xuICAgICAgLyoqXG4gICAgICAgKiBKb2luIHRoZSBzZWxlY3RlZCBibG9jaywgb3IgdGhlIGNsb3Nlc3QgYW5jZXN0b3Igb2YgdGhlIHNlbGVjdGlvbiB0aGF0IGNhbiBiZSBqb2luZWQsIHdpdGggdGhlIHNpYmxpbmcgYWZ0ZXIgaXQuXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuam9pbkRvd24oKVxuICAgICAgICovXG4gICAgICBqb2luRG93bjogKCkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgICBqb2luQmFja3dhcmQ6IHtcbiAgICAgIC8qKlxuICAgICAgICogSWYgdGhlIHNlbGVjdGlvbiBpcyBlbXB0eSBhbmQgYXQgdGhlIHN0YXJ0IG9mIGEgdGV4dGJsb2NrLCB0cnkgdG8gcmVkdWNlIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHRoYXQgYmxvY2sgYW5kIHRoZSBvbmUgYmVmb3JlIGl04oCUaWYgdGhlcmUncyBhIGJsb2NrIGRpcmVjdGx5IGJlZm9yZSBpdCB0aGF0IGNhbiBiZSBqb2luZWQsIGpvaW4gdGhlbS5cbiAgICAgICAqIElmIG5vdCwgdHJ5IHRvIG1vdmUgdGhlIHNlbGVjdGVkIGJsb2NrIGNsb3NlciB0byB0aGUgbmV4dCBvbmUgaW4gdGhlIGRvY3VtZW50IHN0cnVjdHVyZSBieSBsaWZ0aW5nIGl0IG91dCBvZiBpdHNcbiAgICAgICAqIHBhcmVudCBvciBtb3ZpbmcgaXQgaW50byBhIHBhcmVudCBvZiB0aGUgcHJldmlvdXMgYmxvY2suIFdpbGwgdXNlIHRoZSB2aWV3IGZvciBhY2N1cmF0ZSAoYmlkaS1hd2FyZSkgc3RhcnQtb2YtdGV4dGJsb2NrIGRldGVjdGlvbiBpZiBnaXZlbi5cbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy5qb2luQmFja3dhcmQoKVxuICAgICAgICovXG4gICAgICBqb2luQmFja3dhcmQ6ICgpID0+IFJldHVyblR5cGVcbiAgICB9XG4gICAgam9pbkZvcndhcmQ6IHtcbiAgICAgIC8qKlxuICAgICAgICogSWYgdGhlIHNlbGVjdGlvbiBpcyBlbXB0eSBhbmQgdGhlIGN1cnNvciBpcyBhdCB0aGUgZW5kIG9mIGEgdGV4dGJsb2NrLCB0cnkgdG8gcmVkdWNlIG9yIHJlbW92ZSB0aGUgYm91bmRhcnkgYmV0d2VlbiB0aGF0IGJsb2NrIGFuZCB0aGUgb25lIGFmdGVyIGl0LFxuICAgICAgICogZWl0aGVyIGJ5IGpvaW5pbmcgdGhlbSBvciBieSBtb3ZpbmcgdGhlIG90aGVyIGJsb2NrIGNsb3NlciB0byB0aGlzIG9uZSBpbiB0aGUgdHJlZSBzdHJ1Y3R1cmUuXG4gICAgICAgKiBXaWxsIHVzZSB0aGUgdmlldyBmb3IgYWNjdXJhdGUgc3RhcnQtb2YtdGV4dGJsb2NrIGRldGVjdGlvbiBpZiBnaXZlbi5cbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy5qb2luRm9yd2FyZCgpXG4gICAgICAgKi9cbiAgICAgIGpvaW5Gb3J3YXJkOiAoKSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBqb2luVXA6IFJhd0NvbW1hbmRzWydqb2luVXAnXSA9ICgpID0+ICh7IHN0YXRlLCBkaXNwYXRjaCB9KSA9PiB7XG4gIHJldHVybiBvcmlnaW5hbEpvaW5VcChzdGF0ZSwgZGlzcGF0Y2gpXG59XG5cbmV4cG9ydCBjb25zdCBqb2luRG93bjogUmF3Q29tbWFuZHNbJ2pvaW5Eb3duJ10gPSAoKSA9PiAoeyBzdGF0ZSwgZGlzcGF0Y2ggfSkgPT4ge1xuICByZXR1cm4gb3JpZ2luYWxKb2luRG93bihzdGF0ZSwgZGlzcGF0Y2gpXG59XG5cbmV4cG9ydCBjb25zdCBqb2luQmFja3dhcmQ6IFJhd0NvbW1hbmRzWydqb2luQmFja3dhcmQnXSA9ICgpID0+ICh7IHN0YXRlLCBkaXNwYXRjaCB9KSA9PiB7XG4gIHJldHVybiBvcmlnaW5hbEpvaW5CYWNrd2FyZChzdGF0ZSwgZGlzcGF0Y2gpXG59XG5cbmV4cG9ydCBjb25zdCBqb2luRm9yd2FyZDogUmF3Q29tbWFuZHNbJ2pvaW5Gb3J3YXJkJ10gPSAoKSA9PiAoeyBzdGF0ZSwgZGlzcGF0Y2ggfSkgPT4ge1xuICByZXR1cm4gb3JpZ2luYWxKb2luRm9yd2FyZChzdGF0ZSwgZGlzcGF0Y2gpXG59XG4iLCAiaW1wb3J0IHsgam9pblBvaW50IH0gZnJvbSAnQHRpcHRhcC9wbS90cmFuc2Zvcm0nXG5cbmltcG9ydCB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBqb2luSXRlbUJhY2t3YXJkOiB7XG4gICAgICAvKipcbiAgICAgICAqIEpvaW4gdHdvIGl0ZW1zIGJhY2t3YXJkLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmpvaW5JdGVtQmFja3dhcmQoKVxuICAgICAgICovXG4gICAgICBqb2luSXRlbUJhY2t3YXJkOiAoKSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBqb2luSXRlbUJhY2t3YXJkOiBSYXdDb21tYW5kc1snam9pbkl0ZW1CYWNrd2FyZCddID0gKCkgPT4gKHtcbiAgc3RhdGUsXG4gIGRpc3BhdGNoLFxuICB0cixcbn0pID0+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCBwb2ludCA9IGpvaW5Qb2ludChzdGF0ZS5kb2MsIHN0YXRlLnNlbGVjdGlvbi4kZnJvbS5wb3MsIC0xKVxuXG4gICAgaWYgKHBvaW50ID09PSBudWxsIHx8IHBvaW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIHRyLmpvaW4ocG9pbnQsIDIpXG5cbiAgICBpZiAoZGlzcGF0Y2gpIHtcbiAgICAgIGRpc3BhdGNoKHRyKVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlXG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG59XG4iLCAiaW1wb3J0IHsgam9pblBvaW50IH0gZnJvbSAnQHRpcHRhcC9wbS90cmFuc2Zvcm0nXG5cbmltcG9ydCB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBqb2luSXRlbUZvcndhcmQ6IHtcbiAgICAgIC8qKlxuICAgICAgICogSm9pbiB0d28gaXRlbXMgRm9yd2FyZHMuXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuam9pbkl0ZW1Gb3J3YXJkKClcbiAgICAgICAqL1xuICAgICAgam9pbkl0ZW1Gb3J3YXJkOiAoKSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBqb2luSXRlbUZvcndhcmQ6IFJhd0NvbW1hbmRzWydqb2luSXRlbUZvcndhcmQnXSA9ICgpID0+ICh7XG4gIHN0YXRlLFxuICBkaXNwYXRjaCxcbiAgdHIsXG59KSA9PiB7XG4gIHRyeSB7XG4gICAgY29uc3QgcG9pbnQgPSBqb2luUG9pbnQoc3RhdGUuZG9jLCBzdGF0ZS5zZWxlY3Rpb24uJGZyb20ucG9zLCArMSlcblxuICAgIGlmIChwb2ludCA9PT0gbnVsbCB8fCBwb2ludCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICB0ci5qb2luKHBvaW50LCAyKVxuXG4gICAgaWYgKGRpc3BhdGNoKSB7XG4gICAgICBkaXNwYXRjaCh0cilcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZVxuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxufVxuIiwgImltcG9ydCB7IGpvaW5UZXh0YmxvY2tCYWNrd2FyZCBhcyBvcmlnaW5hbENvbW1hbmQgfSBmcm9tICdAdGlwdGFwL3BtL2NvbW1hbmRzJ1xuXG5pbXBvcnQgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgam9pblRleHRibG9ja0JhY2t3YXJkOiB7XG4gICAgICAvKipcbiAgICAgICAqIEEgbW9yZSBsaW1pdGVkIGZvcm0gb2Ygam9pbkJhY2t3YXJkIHRoYXQgb25seSB0cmllcyB0byBqb2luIHRoZSBjdXJyZW50IHRleHRibG9jayB0byB0aGUgb25lIGJlZm9yZSBpdCwgaWYgdGhlIGN1cnNvciBpcyBhdCB0aGUgc3RhcnQgb2YgYSB0ZXh0YmxvY2suXG4gICAgICAgKi9cbiAgICAgIGpvaW5UZXh0YmxvY2tCYWNrd2FyZDogKCkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3Qgam9pblRleHRibG9ja0JhY2t3YXJkOiBSYXdDb21tYW5kc1snam9pblRleHRibG9ja0JhY2t3YXJkJ10gPSAoKSA9PiAoeyBzdGF0ZSwgZGlzcGF0Y2ggfSkgPT4ge1xuICByZXR1cm4gb3JpZ2luYWxDb21tYW5kKHN0YXRlLCBkaXNwYXRjaClcbn1cbiIsICJpbXBvcnQgeyBqb2luVGV4dGJsb2NrRm9yd2FyZCBhcyBvcmlnaW5hbENvbW1hbmQgfSBmcm9tICdAdGlwdGFwL3BtL2NvbW1hbmRzJ1xuXG5pbXBvcnQgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgam9pblRleHRibG9ja0ZvcndhcmQ6IHtcbiAgICAgIC8qKlxuICAgICAgICogQSBtb3JlIGxpbWl0ZWQgZm9ybSBvZiBqb2luRm9yd2FyZCB0aGF0IG9ubHkgdHJpZXMgdG8gam9pbiB0aGUgY3VycmVudCB0ZXh0YmxvY2sgdG8gdGhlIG9uZSBhZnRlciBpdCwgaWYgdGhlIGN1cnNvciBpcyBhdCB0aGUgZW5kIG9mIGEgdGV4dGJsb2NrLlxuICAgICAgICovXG4gICAgICBqb2luVGV4dGJsb2NrRm9yd2FyZDogKCkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3Qgam9pblRleHRibG9ja0ZvcndhcmQ6IFJhd0NvbW1hbmRzWydqb2luVGV4dGJsb2NrRm9yd2FyZCddID0gKCkgPT4gKHsgc3RhdGUsIGRpc3BhdGNoIH0pID0+IHtcbiAgcmV0dXJuIG9yaWdpbmFsQ29tbWFuZChzdGF0ZSwgZGlzcGF0Y2gpXG59XG4iLCAiZXhwb3J0IGZ1bmN0aW9uIGlzTWFjT1MoKTogYm9vbGVhbiB7XG4gIHJldHVybiB0eXBlb2YgbmF2aWdhdG9yICE9PSAndW5kZWZpbmVkJ1xuICAgID8gL01hYy8udGVzdChuYXZpZ2F0b3IucGxhdGZvcm0pXG4gICAgOiBmYWxzZVxufVxuIiwgImltcG9ydCB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5pbXBvcnQgeyBpc2lPUyB9IGZyb20gJy4uL3V0aWxpdGllcy9pc2lPUy5qcydcbmltcG9ydCB7IGlzTWFjT1MgfSBmcm9tICcuLi91dGlsaXRpZXMvaXNNYWNPUy5qcydcblxuZnVuY3Rpb24gbm9ybWFsaXplS2V5TmFtZShuYW1lOiBzdHJpbmcpIHtcbiAgY29uc3QgcGFydHMgPSBuYW1lLnNwbGl0KC8tKD8hJCkvKVxuICBsZXQgcmVzdWx0ID0gcGFydHNbcGFydHMubGVuZ3RoIC0gMV1cblxuICBpZiAocmVzdWx0ID09PSAnU3BhY2UnKSB7XG4gICAgcmVzdWx0ID0gJyAnXG4gIH1cblxuICBsZXQgYWx0XG4gIGxldCBjdHJsXG4gIGxldCBzaGlmdFxuICBsZXQgbWV0YVxuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcGFydHMubGVuZ3RoIC0gMTsgaSArPSAxKSB7XG4gICAgY29uc3QgbW9kID0gcGFydHNbaV1cblxuICAgIGlmICgvXihjbWR8bWV0YXxtKSQvaS50ZXN0KG1vZCkpIHtcbiAgICAgIG1ldGEgPSB0cnVlXG4gICAgfSBlbHNlIGlmICgvXmEobHQpPyQvaS50ZXN0KG1vZCkpIHtcbiAgICAgIGFsdCA9IHRydWVcbiAgICB9IGVsc2UgaWYgKC9eKGN8Y3RybHxjb250cm9sKSQvaS50ZXN0KG1vZCkpIHtcbiAgICAgIGN0cmwgPSB0cnVlXG4gICAgfSBlbHNlIGlmICgvXnMoaGlmdCk/JC9pLnRlc3QobW9kKSkge1xuICAgICAgc2hpZnQgPSB0cnVlXG4gICAgfSBlbHNlIGlmICgvXm1vZCQvaS50ZXN0KG1vZCkpIHtcbiAgICAgIGlmIChpc2lPUygpIHx8IGlzTWFjT1MoKSkge1xuICAgICAgICBtZXRhID0gdHJ1ZVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY3RybCA9IHRydWVcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnJlY29nbml6ZWQgbW9kaWZpZXIgbmFtZTogJHttb2R9YClcbiAgICB9XG4gIH1cblxuICBpZiAoYWx0KSB7XG4gICAgcmVzdWx0ID0gYEFsdC0ke3Jlc3VsdH1gXG4gIH1cblxuICBpZiAoY3RybCkge1xuICAgIHJlc3VsdCA9IGBDdHJsLSR7cmVzdWx0fWBcbiAgfVxuXG4gIGlmIChtZXRhKSB7XG4gICAgcmVzdWx0ID0gYE1ldGEtJHtyZXN1bHR9YFxuICB9XG5cbiAgaWYgKHNoaWZ0KSB7XG4gICAgcmVzdWx0ID0gYFNoaWZ0LSR7cmVzdWx0fWBcbiAgfVxuXG4gIHJldHVybiByZXN1bHRcbn1cblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIGtleWJvYXJkU2hvcnRjdXQ6IHtcbiAgICAgIC8qKlxuICAgICAgICogVHJpZ2dlciBhIGtleWJvYXJkIHNob3J0Y3V0LlxuICAgICAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIGtleWJvYXJkIHNob3J0Y3V0LlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmtleWJvYXJkU2hvcnRjdXQoJ01vZC1iJylcbiAgICAgICAqL1xuICAgICAga2V5Ym9hcmRTaG9ydGN1dDogKG5hbWU6IHN0cmluZykgPT4gUmV0dXJuVHlwZSxcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGtleWJvYXJkU2hvcnRjdXQ6IFJhd0NvbW1hbmRzWydrZXlib2FyZFNob3J0Y3V0J10gPSBuYW1lID0+ICh7XG4gIGVkaXRvcixcbiAgdmlldyxcbiAgdHIsXG4gIGRpc3BhdGNoLFxufSkgPT4ge1xuICBjb25zdCBrZXlzID0gbm9ybWFsaXplS2V5TmFtZShuYW1lKS5zcGxpdCgvLSg/ISQpLylcbiAgY29uc3Qga2V5ID0ga2V5cy5maW5kKGl0ZW0gPT4gIVsnQWx0JywgJ0N0cmwnLCAnTWV0YScsICdTaGlmdCddLmluY2x1ZGVzKGl0ZW0pKVxuICBjb25zdCBldmVudCA9IG5ldyBLZXlib2FyZEV2ZW50KCdrZXlkb3duJywge1xuICAgIGtleToga2V5ID09PSAnU3BhY2UnXG4gICAgICA/ICcgJ1xuICAgICAgOiBrZXksXG4gICAgYWx0S2V5OiBrZXlzLmluY2x1ZGVzKCdBbHQnKSxcbiAgICBjdHJsS2V5OiBrZXlzLmluY2x1ZGVzKCdDdHJsJyksXG4gICAgbWV0YUtleToga2V5cy5pbmNsdWRlcygnTWV0YScpLFxuICAgIHNoaWZ0S2V5OiBrZXlzLmluY2x1ZGVzKCdTaGlmdCcpLFxuICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgY2FuY2VsYWJsZTogdHJ1ZSxcbiAgfSlcblxuICBjb25zdCBjYXB0dXJlZFRyYW5zYWN0aW9uID0gZWRpdG9yLmNhcHR1cmVUcmFuc2FjdGlvbigoKSA9PiB7XG4gICAgdmlldy5zb21lUHJvcCgnaGFuZGxlS2V5RG93bicsIGYgPT4gZih2aWV3LCBldmVudCkpXG4gIH0pXG5cbiAgY2FwdHVyZWRUcmFuc2FjdGlvbj8uc3RlcHMuZm9yRWFjaChzdGVwID0+IHtcbiAgICBjb25zdCBuZXdTdGVwID0gc3RlcC5tYXAodHIubWFwcGluZylcblxuICAgIGlmIChuZXdTdGVwICYmIGRpc3BhdGNoKSB7XG4gICAgICB0ci5tYXliZVN0ZXAobmV3U3RlcClcbiAgICB9XG4gIH0pXG5cbiAgcmV0dXJuIHRydWVcbn1cbiIsICJpbXBvcnQgeyBOb2RlVHlwZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5pbXBvcnQgeyBFZGl0b3JTdGF0ZSB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmltcG9ydCB7IE5vZGVSYW5nZSB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuaW1wb3J0IHsgb2JqZWN0SW5jbHVkZXMgfSBmcm9tICcuLi91dGlsaXRpZXMvb2JqZWN0SW5jbHVkZXMuanMnXG5pbXBvcnQgeyBnZXROb2RlVHlwZSB9IGZyb20gJy4vZ2V0Tm9kZVR5cGUuanMnXG5cbmV4cG9ydCBmdW5jdGlvbiBpc05vZGVBY3RpdmUoXG4gIHN0YXRlOiBFZGl0b3JTdGF0ZSxcbiAgdHlwZU9yTmFtZTogTm9kZVR5cGUgfCBzdHJpbmcgfCBudWxsLFxuICBhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge30sXG4pOiBib29sZWFuIHtcbiAgY29uc3QgeyBmcm9tLCB0bywgZW1wdHkgfSA9IHN0YXRlLnNlbGVjdGlvblxuICBjb25zdCB0eXBlID0gdHlwZU9yTmFtZSA/IGdldE5vZGVUeXBlKHR5cGVPck5hbWUsIHN0YXRlLnNjaGVtYSkgOiBudWxsXG5cbiAgY29uc3Qgbm9kZVJhbmdlczogTm9kZVJhbmdlW10gPSBbXVxuXG4gIHN0YXRlLmRvYy5ub2Rlc0JldHdlZW4oZnJvbSwgdG8sIChub2RlLCBwb3MpID0+IHtcbiAgICBpZiAobm9kZS5pc1RleHQpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IHJlbGF0aXZlRnJvbSA9IE1hdGgubWF4KGZyb20sIHBvcylcbiAgICBjb25zdCByZWxhdGl2ZVRvID0gTWF0aC5taW4odG8sIHBvcyArIG5vZGUubm9kZVNpemUpXG5cbiAgICBub2RlUmFuZ2VzLnB1c2goe1xuICAgICAgbm9kZSxcbiAgICAgIGZyb206IHJlbGF0aXZlRnJvbSxcbiAgICAgIHRvOiByZWxhdGl2ZVRvLFxuICAgIH0pXG4gIH0pXG5cbiAgY29uc3Qgc2VsZWN0aW9uUmFuZ2UgPSB0byAtIGZyb21cbiAgY29uc3QgbWF0Y2hlZE5vZGVSYW5nZXMgPSBub2RlUmFuZ2VzXG4gICAgLmZpbHRlcihub2RlUmFuZ2UgPT4ge1xuICAgICAgaWYgKCF0eXBlKSB7XG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0eXBlLm5hbWUgPT09IG5vZGVSYW5nZS5ub2RlLnR5cGUubmFtZVxuICAgIH0pXG4gICAgLmZpbHRlcihub2RlUmFuZ2UgPT4gb2JqZWN0SW5jbHVkZXMobm9kZVJhbmdlLm5vZGUuYXR0cnMsIGF0dHJpYnV0ZXMsIHsgc3RyaWN0OiBmYWxzZSB9KSlcblxuICBpZiAoZW1wdHkpIHtcbiAgICByZXR1cm4gISFtYXRjaGVkTm9kZVJhbmdlcy5sZW5ndGhcbiAgfVxuXG4gIGNvbnN0IHJhbmdlID0gbWF0Y2hlZE5vZGVSYW5nZXMucmVkdWNlKChzdW0sIG5vZGVSYW5nZSkgPT4gc3VtICsgbm9kZVJhbmdlLnRvIC0gbm9kZVJhbmdlLmZyb20sIDApXG5cbiAgcmV0dXJuIHJhbmdlID49IHNlbGVjdGlvblJhbmdlXG59XG4iLCAiaW1wb3J0IHsgbGlmdCBhcyBvcmlnaW5hbExpZnQgfSBmcm9tICdAdGlwdGFwL3BtL2NvbW1hbmRzJ1xuaW1wb3J0IHsgTm9kZVR5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgeyBnZXROb2RlVHlwZSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0Tm9kZVR5cGUuanMnXG5pbXBvcnQgeyBpc05vZGVBY3RpdmUgfSBmcm9tICcuLi9oZWxwZXJzL2lzTm9kZUFjdGl2ZS5qcydcbmltcG9ydCB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBsaWZ0OiB7XG4gICAgICAvKipcbiAgICAgICAqIFJlbW92ZXMgYW4gZXhpc3Rpbmcgd3JhcCBpZiBwb3NzaWJsZSBsaWZ0aW5nIHRoZSBub2RlIG91dCBvZiBpdFxuICAgICAgICogQHBhcmFtIHR5cGVPck5hbWUgVGhlIHR5cGUgb3IgbmFtZSBvZiB0aGUgbm9kZS5cbiAgICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVzIFRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBub2RlLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmxpZnQoJ3BhcmFncmFwaCcpXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMubGlmdCgnaGVhZGluZycsIHsgbGV2ZWw6IDEgfSlcbiAgICAgICAqL1xuICAgICAgbGlmdDogKHR5cGVPck5hbWU6IHN0cmluZyB8IE5vZGVUeXBlLCBhdHRyaWJ1dGVzPzogUmVjb3JkPHN0cmluZywgYW55PikgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgbGlmdDogUmF3Q29tbWFuZHNbJ2xpZnQnXSA9ICh0eXBlT3JOYW1lLCBhdHRyaWJ1dGVzID0ge30pID0+ICh7IHN0YXRlLCBkaXNwYXRjaCB9KSA9PiB7XG4gIGNvbnN0IHR5cGUgPSBnZXROb2RlVHlwZSh0eXBlT3JOYW1lLCBzdGF0ZS5zY2hlbWEpXG4gIGNvbnN0IGlzQWN0aXZlID0gaXNOb2RlQWN0aXZlKHN0YXRlLCB0eXBlLCBhdHRyaWJ1dGVzKVxuXG4gIGlmICghaXNBY3RpdmUpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIHJldHVybiBvcmlnaW5hbExpZnQoc3RhdGUsIGRpc3BhdGNoKVxufVxuIiwgImltcG9ydCB7IGxpZnRFbXB0eUJsb2NrIGFzIG9yaWdpbmFsTGlmdEVtcHR5QmxvY2sgfSBmcm9tICdAdGlwdGFwL3BtL2NvbW1hbmRzJ1xuXG5pbXBvcnQgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgbGlmdEVtcHR5QmxvY2s6IHtcbiAgICAgIC8qKlxuICAgICAgICogSWYgdGhlIGN1cnNvciBpcyBpbiBhbiBlbXB0eSB0ZXh0YmxvY2sgdGhhdCBjYW4gYmUgbGlmdGVkLCBsaWZ0IHRoZSBibG9jay5cbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy5saWZ0RW1wdHlCbG9jaygpXG4gICAgICAgKi9cbiAgICAgIGxpZnRFbXB0eUJsb2NrOiAoKSA9PiBSZXR1cm5UeXBlLFxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgbGlmdEVtcHR5QmxvY2s6IFJhd0NvbW1hbmRzWydsaWZ0RW1wdHlCbG9jayddID0gKCkgPT4gKHsgc3RhdGUsIGRpc3BhdGNoIH0pID0+IHtcbiAgcmV0dXJuIG9yaWdpbmFsTGlmdEVtcHR5QmxvY2soc3RhdGUsIGRpc3BhdGNoKVxufVxuIiwgImltcG9ydCB7IE5vZGVUeXBlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcbmltcG9ydCB7IGxpZnRMaXN0SXRlbSBhcyBvcmlnaW5hbExpZnRMaXN0SXRlbSB9IGZyb20gJ0B0aXB0YXAvcG0vc2NoZW1hLWxpc3QnXG5cbmltcG9ydCB7IGdldE5vZGVUeXBlIH0gZnJvbSAnLi4vaGVscGVycy9nZXROb2RlVHlwZS5qcydcbmltcG9ydCB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBsaWZ0TGlzdEl0ZW06IHtcbiAgICAgIC8qKlxuICAgICAgICogQ3JlYXRlIGEgY29tbWFuZCB0byBsaWZ0IHRoZSBsaXN0IGl0ZW0gYXJvdW5kIHRoZSBzZWxlY3Rpb24gdXAgaW50byBhIHdyYXBwaW5nIGxpc3QuXG4gICAgICAgKiBAcGFyYW0gdHlwZU9yTmFtZSBUaGUgdHlwZSBvciBuYW1lIG9mIHRoZSBub2RlLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLmxpZnRMaXN0SXRlbSgnbGlzdEl0ZW0nKVxuICAgICAgICovXG4gICAgICBsaWZ0TGlzdEl0ZW06ICh0eXBlT3JOYW1lOiBzdHJpbmcgfCBOb2RlVHlwZSkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgbGlmdExpc3RJdGVtOiBSYXdDb21tYW5kc1snbGlmdExpc3RJdGVtJ10gPSB0eXBlT3JOYW1lID0+ICh7IHN0YXRlLCBkaXNwYXRjaCB9KSA9PiB7XG4gIGNvbnN0IHR5cGUgPSBnZXROb2RlVHlwZSh0eXBlT3JOYW1lLCBzdGF0ZS5zY2hlbWEpXG5cbiAgcmV0dXJuIG9yaWdpbmFsTGlmdExpc3RJdGVtKHR5cGUpKHN0YXRlLCBkaXNwYXRjaClcbn1cbiIsICJpbXBvcnQgeyBuZXdsaW5lSW5Db2RlIGFzIG9yaWdpbmFsTmV3bGluZUluQ29kZSB9IGZyb20gJ0B0aXB0YXAvcG0vY29tbWFuZHMnXG5cbmltcG9ydCB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBuZXdsaW5lSW5Db2RlOiB7XG4gICAgICAvKipcbiAgICAgICAqIEFkZCBhIG5ld2xpbmUgY2hhcmFjdGVyIGluIGNvZGUuXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMubmV3bGluZUluQ29kZSgpXG4gICAgICAgKi9cbiAgICAgIG5ld2xpbmVJbkNvZGU6ICgpID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IG5ld2xpbmVJbkNvZGU6IFJhd0NvbW1hbmRzWyduZXdsaW5lSW5Db2RlJ10gPSAoKSA9PiAoeyBzdGF0ZSwgZGlzcGF0Y2ggfSkgPT4ge1xuICByZXR1cm4gb3JpZ2luYWxOZXdsaW5lSW5Db2RlKHN0YXRlLCBkaXNwYXRjaClcbn1cbiIsICJpbXBvcnQgeyBTY2hlbWEgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG4vKipcbiAqIEdldCB0aGUgdHlwZSBvZiBhIHNjaGVtYSBpdGVtIGJ5IGl0cyBuYW1lLlxuICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIHNjaGVtYSBpdGVtXG4gKiBAcGFyYW0gc2NoZW1hIFRoZSBQcm9zZW1pcm9yIHNjaGVtYSB0byBzZWFyY2ggaW5cbiAqIEByZXR1cm5zIFRoZSB0eXBlIG9mIHRoZSBzY2hlbWEgaXRlbSAoYG5vZGVgIG9yIGBtYXJrYCksIG9yIG51bGwgaWYgaXQgZG9lc24ndCBleGlzdFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2NoZW1hVHlwZU5hbWVCeU5hbWUobmFtZTogc3RyaW5nLCBzY2hlbWE6IFNjaGVtYSk6ICdub2RlJyB8ICdtYXJrJyB8IG51bGwge1xuICBpZiAoc2NoZW1hLm5vZGVzW25hbWVdKSB7XG4gICAgcmV0dXJuICdub2RlJ1xuICB9XG5cbiAgaWYgKHNjaGVtYS5tYXJrc1tuYW1lXSkge1xuICAgIHJldHVybiAnbWFyaydcbiAgfVxuXG4gIHJldHVybiBudWxsXG59XG4iLCAiLyoqXG4gKiBSZW1vdmUgYSBwcm9wZXJ0eSBvciBhbiBhcnJheSBvZiBwcm9wZXJ0aWVzIGZyb20gYW4gb2JqZWN0XG4gKiBAcGFyYW0gb2JqIE9iamVjdFxuICogQHBhcmFtIGtleSBLZXkgdG8gcmVtb3ZlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWxldGVQcm9wcyhvYmo6IFJlY29yZDxzdHJpbmcsIGFueT4sIHByb3BPclByb3BzOiBzdHJpbmcgfCBzdHJpbmdbXSk6IFJlY29yZDxzdHJpbmcsIGFueT4ge1xuICBjb25zdCBwcm9wcyA9IHR5cGVvZiBwcm9wT3JQcm9wcyA9PT0gJ3N0cmluZydcbiAgICA/IFtwcm9wT3JQcm9wc11cbiAgICA6IHByb3BPclByb3BzXG5cbiAgcmV0dXJuIE9iamVjdFxuICAgIC5rZXlzKG9iailcbiAgICAucmVkdWNlKChuZXdPYmo6IFJlY29yZDxzdHJpbmcsIGFueT4sIHByb3ApID0+IHtcbiAgICAgIGlmICghcHJvcHMuaW5jbHVkZXMocHJvcCkpIHtcbiAgICAgICAgbmV3T2JqW3Byb3BdID0gb2JqW3Byb3BdXG4gICAgICB9XG5cbiAgICAgIHJldHVybiBuZXdPYmpcbiAgICB9LCB7fSlcbn1cbiIsICJpbXBvcnQgeyBNYXJrVHlwZSwgTm9kZVR5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgeyBnZXRNYXJrVHlwZSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0TWFya1R5cGUuanMnXG5pbXBvcnQgeyBnZXROb2RlVHlwZSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0Tm9kZVR5cGUuanMnXG5pbXBvcnQgeyBnZXRTY2hlbWFUeXBlTmFtZUJ5TmFtZSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0U2NoZW1hVHlwZU5hbWVCeU5hbWUuanMnXG5pbXBvcnQgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuaW1wb3J0IHsgZGVsZXRlUHJvcHMgfSBmcm9tICcuLi91dGlsaXRpZXMvZGVsZXRlUHJvcHMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICByZXNldEF0dHJpYnV0ZXM6IHtcbiAgICAgIC8qKlxuICAgICAgICogUmVzZXRzIHNvbWUgbm9kZSBhdHRyaWJ1dGVzIHRvIHRoZSBkZWZhdWx0IHZhbHVlLlxuICAgICAgICogQHBhcmFtIHR5cGVPck5hbWUgVGhlIHR5cGUgb3IgbmFtZSBvZiB0aGUgbm9kZS5cbiAgICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVzIFRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBub2RlIHRvIHJlc2V0LlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnJlc2V0QXR0cmlidXRlcygnaGVhZGluZycsICdsZXZlbCcpXG4gICAgICAgKi9cbiAgICAgIHJlc2V0QXR0cmlidXRlczogKFxuICAgICAgICB0eXBlT3JOYW1lOiBzdHJpbmcgfCBOb2RlVHlwZSB8IE1hcmtUeXBlLFxuICAgICAgICBhdHRyaWJ1dGVzOiBzdHJpbmcgfCBzdHJpbmdbXSxcbiAgICAgICkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgcmVzZXRBdHRyaWJ1dGVzOiBSYXdDb21tYW5kc1sncmVzZXRBdHRyaWJ1dGVzJ10gPSAodHlwZU9yTmFtZSwgYXR0cmlidXRlcykgPT4gKHsgdHIsIHN0YXRlLCBkaXNwYXRjaCB9KSA9PiB7XG4gIGxldCBub2RlVHlwZTogTm9kZVR5cGUgfCBudWxsID0gbnVsbFxuICBsZXQgbWFya1R5cGU6IE1hcmtUeXBlIHwgbnVsbCA9IG51bGxcblxuICBjb25zdCBzY2hlbWFUeXBlID0gZ2V0U2NoZW1hVHlwZU5hbWVCeU5hbWUoXG4gICAgdHlwZW9mIHR5cGVPck5hbWUgPT09ICdzdHJpbmcnID8gdHlwZU9yTmFtZSA6IHR5cGVPck5hbWUubmFtZSxcbiAgICBzdGF0ZS5zY2hlbWEsXG4gIClcblxuICBpZiAoIXNjaGVtYVR5cGUpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIGlmIChzY2hlbWFUeXBlID09PSAnbm9kZScpIHtcbiAgICBub2RlVHlwZSA9IGdldE5vZGVUeXBlKHR5cGVPck5hbWUgYXMgTm9kZVR5cGUsIHN0YXRlLnNjaGVtYSlcbiAgfVxuXG4gIGlmIChzY2hlbWFUeXBlID09PSAnbWFyaycpIHtcbiAgICBtYXJrVHlwZSA9IGdldE1hcmtUeXBlKHR5cGVPck5hbWUgYXMgTWFya1R5cGUsIHN0YXRlLnNjaGVtYSlcbiAgfVxuXG4gIGlmIChkaXNwYXRjaCkge1xuICAgIHRyLnNlbGVjdGlvbi5yYW5nZXMuZm9yRWFjaChyYW5nZSA9PiB7XG4gICAgICBzdGF0ZS5kb2Mubm9kZXNCZXR3ZWVuKHJhbmdlLiRmcm9tLnBvcywgcmFuZ2UuJHRvLnBvcywgKG5vZGUsIHBvcykgPT4ge1xuICAgICAgICBpZiAobm9kZVR5cGUgJiYgbm9kZVR5cGUgPT09IG5vZGUudHlwZSkge1xuICAgICAgICAgIHRyLnNldE5vZGVNYXJrdXAocG9zLCB1bmRlZmluZWQsIGRlbGV0ZVByb3BzKG5vZGUuYXR0cnMsIGF0dHJpYnV0ZXMpKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG1hcmtUeXBlICYmIG5vZGUubWFya3MubGVuZ3RoKSB7XG4gICAgICAgICAgbm9kZS5tYXJrcy5mb3JFYWNoKG1hcmsgPT4ge1xuICAgICAgICAgICAgaWYgKG1hcmtUeXBlID09PSBtYXJrLnR5cGUpIHtcbiAgICAgICAgICAgICAgdHIuYWRkTWFyayhcbiAgICAgICAgICAgICAgICBwb3MsXG4gICAgICAgICAgICAgICAgcG9zICsgbm9kZS5ub2RlU2l6ZSxcbiAgICAgICAgICAgICAgICBtYXJrVHlwZS5jcmVhdGUoZGVsZXRlUHJvcHMobWFyay5hdHRycywgYXR0cmlidXRlcykpLFxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cbiAgcmV0dXJuIHRydWVcbn1cbiIsICJpbXBvcnQgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgc2Nyb2xsSW50b1ZpZXc6IHtcbiAgICAgIC8qKlxuICAgICAgICogU2Nyb2xsIHRoZSBzZWxlY3Rpb24gaW50byB2aWV3LlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnNjcm9sbEludG9WaWV3KClcbiAgICAgICAqL1xuICAgICAgc2Nyb2xsSW50b1ZpZXc6ICgpID0+IFJldHVyblR5cGUsXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBzY3JvbGxJbnRvVmlldzogUmF3Q29tbWFuZHNbJ3Njcm9sbEludG9WaWV3J10gPSAoKSA9PiAoeyB0ciwgZGlzcGF0Y2ggfSkgPT4ge1xuICBpZiAoZGlzcGF0Y2gpIHtcbiAgICB0ci5zY3JvbGxJbnRvVmlldygpXG4gIH1cblxuICByZXR1cm4gdHJ1ZVxufVxuIiwgImltcG9ydCB7IEFsbFNlbGVjdGlvbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmltcG9ydCB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBzZWxlY3RBbGw6IHtcbiAgICAgIC8qKlxuICAgICAgICogU2VsZWN0IHRoZSB3aG9sZSBkb2N1bWVudC5cbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy5zZWxlY3RBbGwoKVxuICAgICAgICovXG4gICAgICBzZWxlY3RBbGw6ICgpID0+IFJldHVyblR5cGUsXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBzZWxlY3RBbGw6IFJhd0NvbW1hbmRzWydzZWxlY3RBbGwnXSA9ICgpID0+ICh7IHRyLCBkaXNwYXRjaCB9KSA9PiB7XG4gIGlmIChkaXNwYXRjaCkge1xuICAgIGNvbnN0IHNlbGVjdGlvbiA9IG5ldyBBbGxTZWxlY3Rpb24odHIuZG9jKVxuXG4gICAgdHIuc2V0U2VsZWN0aW9uKHNlbGVjdGlvbilcbiAgfVxuXG4gIHJldHVybiB0cnVlXG59XG4iLCAiaW1wb3J0IHsgc2VsZWN0Tm9kZUJhY2t3YXJkIGFzIG9yaWdpbmFsU2VsZWN0Tm9kZUJhY2t3YXJkIH0gZnJvbSAnQHRpcHRhcC9wbS9jb21tYW5kcydcblxuaW1wb3J0IHsgUmF3Q29tbWFuZHMgfSBmcm9tICcuLi90eXBlcy5qcydcblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIHNlbGVjdE5vZGVCYWNrd2FyZDoge1xuICAgICAgLyoqXG4gICAgICAgKiBTZWxlY3QgYSBub2RlIGJhY2t3YXJkLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnNlbGVjdE5vZGVCYWNrd2FyZCgpXG4gICAgICAgKi9cbiAgICAgIHNlbGVjdE5vZGVCYWNrd2FyZDogKCkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3Qgc2VsZWN0Tm9kZUJhY2t3YXJkOiBSYXdDb21tYW5kc1snc2VsZWN0Tm9kZUJhY2t3YXJkJ10gPSAoKSA9PiAoeyBzdGF0ZSwgZGlzcGF0Y2ggfSkgPT4ge1xuICByZXR1cm4gb3JpZ2luYWxTZWxlY3ROb2RlQmFja3dhcmQoc3RhdGUsIGRpc3BhdGNoKVxufVxuIiwgImltcG9ydCB7IHNlbGVjdE5vZGVGb3J3YXJkIGFzIG9yaWdpbmFsU2VsZWN0Tm9kZUZvcndhcmQgfSBmcm9tICdAdGlwdGFwL3BtL2NvbW1hbmRzJ1xuXG5pbXBvcnQgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgc2VsZWN0Tm9kZUZvcndhcmQ6IHtcbiAgICAgIC8qKlxuICAgICAgICogU2VsZWN0IGEgbm9kZSBmb3J3YXJkLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnNlbGVjdE5vZGVGb3J3YXJkKClcbiAgICAgICAqL1xuICAgICAgc2VsZWN0Tm9kZUZvcndhcmQ6ICgpID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHNlbGVjdE5vZGVGb3J3YXJkOiBSYXdDb21tYW5kc1snc2VsZWN0Tm9kZUZvcndhcmQnXSA9ICgpID0+ICh7IHN0YXRlLCBkaXNwYXRjaCB9KSA9PiB7XG4gIHJldHVybiBvcmlnaW5hbFNlbGVjdE5vZGVGb3J3YXJkKHN0YXRlLCBkaXNwYXRjaClcbn1cbiIsICJpbXBvcnQgeyBzZWxlY3RQYXJlbnROb2RlIGFzIG9yaWdpbmFsU2VsZWN0UGFyZW50Tm9kZSB9IGZyb20gJ0B0aXB0YXAvcG0vY29tbWFuZHMnXG5cbmltcG9ydCB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBzZWxlY3RQYXJlbnROb2RlOiB7XG4gICAgICAvKipcbiAgICAgICAqIFNlbGVjdCB0aGUgcGFyZW50IG5vZGUuXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuc2VsZWN0UGFyZW50Tm9kZSgpXG4gICAgICAgKi9cbiAgICAgIHNlbGVjdFBhcmVudE5vZGU6ICgpID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHNlbGVjdFBhcmVudE5vZGU6IFJhd0NvbW1hbmRzWydzZWxlY3RQYXJlbnROb2RlJ10gPSAoKSA9PiAoeyBzdGF0ZSwgZGlzcGF0Y2ggfSkgPT4ge1xuICByZXR1cm4gb3JpZ2luYWxTZWxlY3RQYXJlbnROb2RlKHN0YXRlLCBkaXNwYXRjaClcbn1cbiIsICIvLyBAdHMtaWdub3JlXG4vLyBUT0RPOiBhZGQgdHlwZXMgdG8gQHR5cGVzL3Byb3NlbWlycm9yLWNvbW1hbmRzXG5pbXBvcnQgeyBzZWxlY3RUZXh0YmxvY2tFbmQgYXMgb3JpZ2luYWxTZWxlY3RUZXh0YmxvY2tFbmQgfSBmcm9tICdAdGlwdGFwL3BtL2NvbW1hbmRzJ1xuXG5pbXBvcnQgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgc2VsZWN0VGV4dGJsb2NrRW5kOiB7XG4gICAgICAvKipcbiAgICAgICAqIE1vdmVzIHRoZSBjdXJzb3IgdG8gdGhlIGVuZCBvZiBjdXJyZW50IHRleHQgYmxvY2suXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuc2VsZWN0VGV4dGJsb2NrRW5kKClcbiAgICAgICAqL1xuICAgICAgc2VsZWN0VGV4dGJsb2NrRW5kOiAoKSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBzZWxlY3RUZXh0YmxvY2tFbmQ6IFJhd0NvbW1hbmRzWydzZWxlY3RUZXh0YmxvY2tFbmQnXSA9ICgpID0+ICh7IHN0YXRlLCBkaXNwYXRjaCB9KSA9PiB7XG4gIHJldHVybiBvcmlnaW5hbFNlbGVjdFRleHRibG9ja0VuZChzdGF0ZSwgZGlzcGF0Y2gpXG59XG4iLCAiLy8gQHRzLWlnbm9yZVxuLy8gVE9ETzogYWRkIHR5cGVzIHRvIEB0eXBlcy9wcm9zZW1pcnJvci1jb21tYW5kc1xuaW1wb3J0IHsgc2VsZWN0VGV4dGJsb2NrU3RhcnQgYXMgb3JpZ2luYWxTZWxlY3RUZXh0YmxvY2tTdGFydCB9IGZyb20gJ0B0aXB0YXAvcG0vY29tbWFuZHMnXG5cbmltcG9ydCB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBzZWxlY3RUZXh0YmxvY2tTdGFydDoge1xuICAgICAgLyoqXG4gICAgICAgKiBNb3ZlcyB0aGUgY3Vyc29yIHRvIHRoZSBzdGFydCBvZiBjdXJyZW50IHRleHQgYmxvY2suXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuc2VsZWN0VGV4dGJsb2NrU3RhcnQoKVxuICAgICAgICovXG4gICAgICBzZWxlY3RUZXh0YmxvY2tTdGFydDogKCkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3Qgc2VsZWN0VGV4dGJsb2NrU3RhcnQ6IFJhd0NvbW1hbmRzWydzZWxlY3RUZXh0YmxvY2tTdGFydCddID0gKCkgPT4gKHsgc3RhdGUsIGRpc3BhdGNoIH0pID0+IHtcbiAgcmV0dXJuIG9yaWdpbmFsU2VsZWN0VGV4dGJsb2NrU3RhcnQoc3RhdGUsIGRpc3BhdGNoKVxufVxuIiwgImltcG9ydCB7XG4gIEZyYWdtZW50LCBOb2RlIGFzIFByb3NlTWlycm9yTm9kZSwgUGFyc2VPcHRpb25zLCBTY2hlbWEsXG59IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmltcG9ydCB7IENvbnRlbnQgfSBmcm9tICcuLi90eXBlcy5qcydcbmltcG9ydCB7IGNyZWF0ZU5vZGVGcm9tQ29udGVudCB9IGZyb20gJy4vY3JlYXRlTm9kZUZyb21Db250ZW50LmpzJ1xuXG4vKipcbiAqIENyZWF0ZSBhIG5ldyBQcm9zZW1pcnJvciBkb2N1bWVudCBub2RlIGZyb20gY29udGVudC5cbiAqIEBwYXJhbSBjb250ZW50IFRoZSBKU09OIG9yIEhUTUwgY29udGVudCB0byBjcmVhdGUgdGhlIGRvY3VtZW50IGZyb21cbiAqIEBwYXJhbSBzY2hlbWEgVGhlIFByb3NlbWlycm9yIHNjaGVtYSB0byB1c2UgZm9yIHRoZSBkb2N1bWVudFxuICogQHBhcmFtIHBhcnNlT3B0aW9ucyBPcHRpb25zIGZvciB0aGUgcGFyc2VyXG4gKiBAcmV0dXJucyBUaGUgY3JlYXRlZCBQcm9zZW1pcnJvciBkb2N1bWVudCBub2RlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVEb2N1bWVudChcbiAgY29udGVudDogQ29udGVudCB8IFByb3NlTWlycm9yTm9kZSB8IEZyYWdtZW50LFxuICBzY2hlbWE6IFNjaGVtYSxcbiAgcGFyc2VPcHRpb25zOiBQYXJzZU9wdGlvbnMgPSB7fSxcbiAgb3B0aW9uczogeyBlcnJvck9uSW52YWxpZENvbnRlbnQ/OiBib29sZWFuIH0gPSB7fSxcbik6IFByb3NlTWlycm9yTm9kZSB7XG4gIHJldHVybiBjcmVhdGVOb2RlRnJvbUNvbnRlbnQoY29udGVudCwgc2NoZW1hLCB7XG4gICAgc2xpY2U6IGZhbHNlLFxuICAgIHBhcnNlT3B0aW9ucyxcbiAgICBlcnJvck9uSW52YWxpZENvbnRlbnQ6IG9wdGlvbnMuZXJyb3JPbkludmFsaWRDb250ZW50LFxuICB9KSBhcyBQcm9zZU1pcnJvck5vZGVcbn1cbiIsICJpbXBvcnQgeyBGcmFnbWVudCwgTm9kZSBhcyBQcm9zZU1pcnJvck5vZGUsIFBhcnNlT3B0aW9ucyB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmltcG9ydCB7IGNyZWF0ZURvY3VtZW50IH0gZnJvbSAnLi4vaGVscGVycy9jcmVhdGVEb2N1bWVudC5qcydcbmltcG9ydCB7IENvbnRlbnQsIFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBzZXRDb250ZW50OiB7XG4gICAgICAvKipcbiAgICAgICAqIFJlcGxhY2UgdGhlIHdob2xlIGRvY3VtZW50IHdpdGggbmV3IGNvbnRlbnQuXG4gICAgICAgKiBAcGFyYW0gY29udGVudCBUaGUgbmV3IGNvbnRlbnQuXG4gICAgICAgKiBAcGFyYW0gZW1pdFVwZGF0ZSBXaGV0aGVyIHRvIGVtaXQgYW4gdXBkYXRlIGV2ZW50LlxuICAgICAgICogQHBhcmFtIHBhcnNlT3B0aW9ucyBPcHRpb25zIGZvciBwYXJzaW5nIHRoZSBjb250ZW50LlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnNldENvbnRlbnQoJzxwPkV4YW1wbGUgdGV4dDwvcD4nKVxuICAgICAgICovXG4gICAgICBzZXRDb250ZW50OiAoXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgbmV3IGNvbnRlbnQuXG4gICAgICAgICAqL1xuICAgICAgICBjb250ZW50OiBDb250ZW50IHwgRnJhZ21lbnQgfCBQcm9zZU1pcnJvck5vZGUsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFdoZXRoZXIgdG8gZW1pdCBhbiB1cGRhdGUgZXZlbnQuXG4gICAgICAgICAqIEBkZWZhdWx0IGZhbHNlXG4gICAgICAgICAqL1xuICAgICAgICBlbWl0VXBkYXRlPzogYm9vbGVhbixcblxuICAgICAgICAvKipcbiAgICAgICAgICogT3B0aW9ucyBmb3IgcGFyc2luZyB0aGUgY29udGVudC5cbiAgICAgICAgICogQGRlZmF1bHQge31cbiAgICAgICAgICovXG4gICAgICAgIHBhcnNlT3B0aW9ucz86IFBhcnNlT3B0aW9ucyxcbiAgICAgICAgLyoqXG4gICAgICAgICAqIE9wdGlvbnMgZm9yIGBzZXRDb250ZW50YC5cbiAgICAgICAgICovXG4gICAgICAgIG9wdGlvbnM/OiB7XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogV2hldGhlciB0byB0aHJvdyBhbiBlcnJvciBpZiB0aGUgY29udGVudCBpcyBpbnZhbGlkLlxuICAgICAgICAgICAqL1xuICAgICAgICAgIGVycm9yT25JbnZhbGlkQ29udGVudD86IGJvb2xlYW47XG4gICAgICAgIH1cbiAgICAgICkgPT4gUmV0dXJuVHlwZTtcbiAgICB9O1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCBzZXRDb250ZW50OiBSYXdDb21tYW5kc1snc2V0Q29udGVudCddID0gKGNvbnRlbnQsIGVtaXRVcGRhdGUgPSBmYWxzZSwgcGFyc2VPcHRpb25zID0ge30sIG9wdGlvbnMgPSB7fSkgPT4gKHtcbiAgZWRpdG9yLCB0ciwgZGlzcGF0Y2gsIGNvbW1hbmRzLFxufSkgPT4ge1xuICBjb25zdCB7IGRvYyB9ID0gdHJcblxuICAvLyBUaGlzIGlzIHRvIGtlZXAgYmFja3dhcmQgY29tcGF0aWJpbGl0eSB3aXRoIHRoZSBwcmV2aW91cyBiZWhhdmlvclxuICAvLyBUT0RPIHJlbW92ZSB0aGlzIGluIHRoZSBuZXh0IG1ham9yIHZlcnNpb25cbiAgaWYgKHBhcnNlT3B0aW9ucy5wcmVzZXJ2ZVdoaXRlc3BhY2UgIT09ICdmdWxsJykge1xuICAgIGNvbnN0IGRvY3VtZW50ID0gY3JlYXRlRG9jdW1lbnQoY29udGVudCwgZWRpdG9yLnNjaGVtYSwgcGFyc2VPcHRpb25zLCB7XG4gICAgICBlcnJvck9uSW52YWxpZENvbnRlbnQ6IG9wdGlvbnMuZXJyb3JPbkludmFsaWRDb250ZW50ID8/IGVkaXRvci5vcHRpb25zLmVuYWJsZUNvbnRlbnRDaGVjayxcbiAgICB9KVxuXG4gICAgaWYgKGRpc3BhdGNoKSB7XG4gICAgICB0ci5yZXBsYWNlV2l0aCgwLCBkb2MuY29udGVudC5zaXplLCBkb2N1bWVudCkuc2V0TWV0YSgncHJldmVudFVwZGF0ZScsICFlbWl0VXBkYXRlKVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgaWYgKGRpc3BhdGNoKSB7XG4gICAgdHIuc2V0TWV0YSgncHJldmVudFVwZGF0ZScsICFlbWl0VXBkYXRlKVxuICB9XG5cbiAgcmV0dXJuIGNvbW1hbmRzLmluc2VydENvbnRlbnRBdCh7IGZyb206IDAsIHRvOiBkb2MuY29udGVudC5zaXplIH0sIGNvbnRlbnQsIHtcbiAgICBwYXJzZU9wdGlvbnMsXG4gICAgZXJyb3JPbkludmFsaWRDb250ZW50OiBvcHRpb25zLmVycm9yT25JbnZhbGlkQ29udGVudCA/PyBlZGl0b3Iub3B0aW9ucy5lbmFibGVDb250ZW50Q2hlY2ssXG4gIH0pXG59XG4iLCAiaW1wb3J0IHsgTWFyaywgTWFya1R5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuaW1wb3J0IHsgRWRpdG9yU3RhdGUgfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5pbXBvcnQgeyBnZXRNYXJrVHlwZSB9IGZyb20gJy4vZ2V0TWFya1R5cGUuanMnXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRNYXJrQXR0cmlidXRlcyhcbiAgc3RhdGU6IEVkaXRvclN0YXRlLFxuICB0eXBlT3JOYW1lOiBzdHJpbmcgfCBNYXJrVHlwZSxcbik6IFJlY29yZDxzdHJpbmcsIGFueT4ge1xuICBjb25zdCB0eXBlID0gZ2V0TWFya1R5cGUodHlwZU9yTmFtZSwgc3RhdGUuc2NoZW1hKVxuICBjb25zdCB7IGZyb20sIHRvLCBlbXB0eSB9ID0gc3RhdGUuc2VsZWN0aW9uXG4gIGNvbnN0IG1hcmtzOiBNYXJrW10gPSBbXVxuXG4gIGlmIChlbXB0eSkge1xuICAgIGlmIChzdGF0ZS5zdG9yZWRNYXJrcykge1xuICAgICAgbWFya3MucHVzaCguLi5zdGF0ZS5zdG9yZWRNYXJrcylcbiAgICB9XG5cbiAgICBtYXJrcy5wdXNoKC4uLnN0YXRlLnNlbGVjdGlvbi4kaGVhZC5tYXJrcygpKVxuICB9IGVsc2Uge1xuICAgIHN0YXRlLmRvYy5ub2Rlc0JldHdlZW4oZnJvbSwgdG8sIG5vZGUgPT4ge1xuICAgICAgbWFya3MucHVzaCguLi5ub2RlLm1hcmtzKVxuICAgIH0pXG4gIH1cblxuICBjb25zdCBtYXJrID0gbWFya3MuZmluZChtYXJrSXRlbSA9PiBtYXJrSXRlbS50eXBlLm5hbWUgPT09IHR5cGUubmFtZSlcblxuICBpZiAoIW1hcmspIHtcbiAgICByZXR1cm4ge31cbiAgfVxuXG4gIHJldHVybiB7IC4uLm1hcmsuYXR0cnMgfVxufVxuIiwgImltcG9ydCB7IE5vZGUgYXMgUHJvc2VNaXJyb3JOb2RlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcbmltcG9ydCB7IFRyYW5zYWN0aW9uIH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcbmltcG9ydCB7IFRyYW5zZm9ybSB9IGZyb20gJ0B0aXB0YXAvcG0vdHJhbnNmb3JtJ1xuXG4vKipcbiAqIFJldHVybnMgYSBuZXcgYFRyYW5zZm9ybWAgYmFzZWQgb24gYWxsIHN0ZXBzIG9mIHRoZSBwYXNzZWQgdHJhbnNhY3Rpb25zLlxuICogQHBhcmFtIG9sZERvYyBUaGUgUHJvc2VtaXJyb3Igbm9kZSB0byBzdGFydCBmcm9tXG4gKiBAcGFyYW0gdHJhbnNhY3Rpb25zIFRoZSB0cmFuc2FjdGlvbnMgdG8gY29tYmluZVxuICogQHJldHVybnMgQSBuZXcgYFRyYW5zZm9ybWAgd2l0aCBhbGwgc3RlcHMgb2YgdGhlIHBhc3NlZCB0cmFuc2FjdGlvbnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbWJpbmVUcmFuc2FjdGlvblN0ZXBzKFxuICBvbGREb2M6IFByb3NlTWlycm9yTm9kZSxcbiAgdHJhbnNhY3Rpb25zOiBUcmFuc2FjdGlvbltdLFxuKTogVHJhbnNmb3JtIHtcbiAgY29uc3QgdHJhbnNmb3JtID0gbmV3IFRyYW5zZm9ybShvbGREb2MpXG5cbiAgdHJhbnNhY3Rpb25zLmZvckVhY2godHJhbnNhY3Rpb24gPT4ge1xuICAgIHRyYW5zYWN0aW9uLnN0ZXBzLmZvckVhY2goc3RlcCA9PiB7XG4gICAgICB0cmFuc2Zvcm0uc3RlcChzdGVwKVxuICAgIH0pXG4gIH0pXG5cbiAgcmV0dXJuIHRyYW5zZm9ybVxufVxuIiwgImltcG9ydCB7IENvbnRlbnRNYXRjaCwgTm9kZVR5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG4vKipcbiAqIEdldHMgdGhlIGRlZmF1bHQgYmxvY2sgdHlwZSBhdCBhIGdpdmVuIG1hdGNoXG4gKiBAcGFyYW0gbWF0Y2ggVGhlIGNvbnRlbnQgbWF0Y2ggdG8gZ2V0IHRoZSBkZWZhdWx0IGJsb2NrIHR5cGUgZnJvbVxuICogQHJldHVybnMgVGhlIGRlZmF1bHQgYmxvY2sgdHlwZSBvciBudWxsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWZhdWx0QmxvY2tBdChtYXRjaDogQ29udGVudE1hdGNoKTogTm9kZVR5cGUgfCBudWxsIHtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBtYXRjaC5lZGdlQ291bnQ7IGkgKz0gMSkge1xuICAgIGNvbnN0IHsgdHlwZSB9ID0gbWF0Y2guZWRnZShpKVxuXG4gICAgaWYgKHR5cGUuaXNUZXh0YmxvY2sgJiYgIXR5cGUuaGFzUmVxdWlyZWRBdHRycygpKSB7XG4gICAgICByZXR1cm4gdHlwZVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsXG59XG4iLCAiaW1wb3J0IHsgTm9kZSBhcyBQcm9zZU1pcnJvck5vZGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgeyBOb2RlV2l0aFBvcywgUHJlZGljYXRlIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbi8qKlxuICogRmluZCBjaGlsZHJlbiBpbnNpZGUgYSBQcm9zZW1pcnJvciBub2RlIHRoYXQgbWF0Y2ggYSBwcmVkaWNhdGUuXG4gKiBAcGFyYW0gbm9kZSBUaGUgUHJvc2VtaXJyb3Igbm9kZSB0byBzZWFyY2ggaW5cbiAqIEBwYXJhbSBwcmVkaWNhdGUgVGhlIHByZWRpY2F0ZSB0byBtYXRjaFxuICogQHJldHVybnMgQW4gYXJyYXkgb2Ygbm9kZXMgd2l0aCB0aGVpciBwb3NpdGlvbnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbmRDaGlsZHJlbihub2RlOiBQcm9zZU1pcnJvck5vZGUsIHByZWRpY2F0ZTogUHJlZGljYXRlKTogTm9kZVdpdGhQb3NbXSB7XG4gIGNvbnN0IG5vZGVzV2l0aFBvczogTm9kZVdpdGhQb3NbXSA9IFtdXG5cbiAgbm9kZS5kZXNjZW5kYW50cygoY2hpbGQsIHBvcykgPT4ge1xuICAgIGlmIChwcmVkaWNhdGUoY2hpbGQpKSB7XG4gICAgICBub2Rlc1dpdGhQb3MucHVzaCh7XG4gICAgICAgIG5vZGU6IGNoaWxkLFxuICAgICAgICBwb3MsXG4gICAgICB9KVxuICAgIH1cbiAgfSlcblxuICByZXR1cm4gbm9kZXNXaXRoUG9zXG59XG4iLCAiaW1wb3J0IHsgTm9kZSBhcyBQcm9zZU1pcnJvck5vZGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgeyBOb2RlV2l0aFBvcywgUHJlZGljYXRlLCBSYW5nZSB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG4vKipcbiAqIFNhbWUgYXMgYGZpbmRDaGlsZHJlbmAgYnV0IHNlYXJjaGVzIG9ubHkgd2l0aGluIGEgYHJhbmdlYC5cbiAqIEBwYXJhbSBub2RlIFRoZSBQcm9zZW1pcnJvciBub2RlIHRvIHNlYXJjaCBpblxuICogQHBhcmFtIHJhbmdlIFRoZSByYW5nZSB0byBzZWFyY2ggaW5cbiAqIEBwYXJhbSBwcmVkaWNhdGUgVGhlIHByZWRpY2F0ZSB0byBtYXRjaFxuICogQHJldHVybnMgQW4gYXJyYXkgb2Ygbm9kZXMgd2l0aCB0aGVpciBwb3NpdGlvbnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZpbmRDaGlsZHJlbkluUmFuZ2UoXG4gIG5vZGU6IFByb3NlTWlycm9yTm9kZSxcbiAgcmFuZ2U6IFJhbmdlLFxuICBwcmVkaWNhdGU6IFByZWRpY2F0ZSxcbik6IE5vZGVXaXRoUG9zW10ge1xuICBjb25zdCBub2Rlc1dpdGhQb3M6IE5vZGVXaXRoUG9zW10gPSBbXVxuXG4gIC8vIGlmIChyYW5nZS5mcm9tID09PSByYW5nZS50bykge1xuICAvLyAgIGNvbnN0IG5vZGVBdCA9IG5vZGUubm9kZUF0KHJhbmdlLmZyb20pXG5cbiAgLy8gICBpZiAobm9kZUF0KSB7XG4gIC8vICAgICBub2Rlc1dpdGhQb3MucHVzaCh7XG4gIC8vICAgICAgIG5vZGU6IG5vZGVBdCxcbiAgLy8gICAgICAgcG9zOiByYW5nZS5mcm9tLFxuICAvLyAgICAgfSlcbiAgLy8gICB9XG4gIC8vIH1cblxuICBub2RlLm5vZGVzQmV0d2VlbihyYW5nZS5mcm9tLCByYW5nZS50bywgKGNoaWxkLCBwb3MpID0+IHtcbiAgICBpZiAocHJlZGljYXRlKGNoaWxkKSkge1xuICAgICAgbm9kZXNXaXRoUG9zLnB1c2goe1xuICAgICAgICBub2RlOiBjaGlsZCxcbiAgICAgICAgcG9zLFxuICAgICAgfSlcbiAgICB9XG4gIH0pXG5cbiAgcmV0dXJuIG5vZGVzV2l0aFBvc1xufVxuIiwgImltcG9ydCB7IE5vZGUgYXMgUHJvc2VNaXJyb3JOb2RlLCBSZXNvbHZlZFBvcyB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmltcG9ydCB7IFByZWRpY2F0ZSB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG4vKipcbiAqIEZpbmRzIHRoZSBjbG9zZXN0IHBhcmVudCBub2RlIHRvIGEgcmVzb2x2ZWQgcG9zaXRpb24gdGhhdCBtYXRjaGVzIGEgcHJlZGljYXRlLlxuICogQHBhcmFtICRwb3MgVGhlIHJlc29sdmVkIHBvc2l0aW9uIHRvIHNlYXJjaCBmcm9tXG4gKiBAcGFyYW0gcHJlZGljYXRlIFRoZSBwcmVkaWNhdGUgdG8gbWF0Y2hcbiAqIEByZXR1cm5zIFRoZSBjbG9zZXN0IHBhcmVudCBub2RlIHRvIHRoZSByZXNvbHZlZCBwb3NpdGlvbiB0aGF0IG1hdGNoZXMgdGhlIHByZWRpY2F0ZVxuICogQGV4YW1wbGUgYGBganNcbiAqIGZpbmRQYXJlbnROb2RlQ2xvc2VzdFRvUG9zKCRmcm9tLCBub2RlID0+IG5vZGUudHlwZS5uYW1lID09PSAncGFyYWdyYXBoJylcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gZmluZFBhcmVudE5vZGVDbG9zZXN0VG9Qb3MoXG4gICRwb3M6IFJlc29sdmVkUG9zLFxuICBwcmVkaWNhdGU6IFByZWRpY2F0ZSxcbik6XG4gIHwge1xuICAgICAgcG9zOiBudW1iZXJcbiAgICAgIHN0YXJ0OiBudW1iZXJcbiAgICAgIGRlcHRoOiBudW1iZXJcbiAgICAgIG5vZGU6IFByb3NlTWlycm9yTm9kZVxuICAgIH1cbiAgfCB1bmRlZmluZWQge1xuICBmb3IgKGxldCBpID0gJHBvcy5kZXB0aDsgaSA+IDA7IGkgLT0gMSkge1xuICAgIGNvbnN0IG5vZGUgPSAkcG9zLm5vZGUoaSlcblxuICAgIGlmIChwcmVkaWNhdGUobm9kZSkpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHBvczogaSA+IDAgPyAkcG9zLmJlZm9yZShpKSA6IDAsXG4gICAgICAgIHN0YXJ0OiAkcG9zLnN0YXJ0KGkpLFxuICAgICAgICBkZXB0aDogaSxcbiAgICAgICAgbm9kZSxcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBTZWxlY3Rpb24gfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5pbXBvcnQgeyBQcmVkaWNhdGUgfSBmcm9tICcuLi90eXBlcy5qcydcbmltcG9ydCB7IGZpbmRQYXJlbnROb2RlQ2xvc2VzdFRvUG9zIH0gZnJvbSAnLi9maW5kUGFyZW50Tm9kZUNsb3Nlc3RUb1Bvcy5qcydcblxuLyoqXG4gKiBGaW5kcyB0aGUgY2xvc2VzdCBwYXJlbnQgbm9kZSB0byB0aGUgY3VycmVudCBzZWxlY3Rpb24gdGhhdCBtYXRjaGVzIGEgcHJlZGljYXRlLlxuICogQHBhcmFtIHByZWRpY2F0ZSBUaGUgcHJlZGljYXRlIHRvIG1hdGNoXG4gKiBAcmV0dXJucyBBIGNvbW1hbmQgdGhhdCBmaW5kcyB0aGUgY2xvc2VzdCBwYXJlbnQgbm9kZSB0byB0aGUgY3VycmVudCBzZWxlY3Rpb24gdGhhdCBtYXRjaGVzIHRoZSBwcmVkaWNhdGVcbiAqIEBleGFtcGxlIGBgYGpzXG4gKiBmaW5kUGFyZW50Tm9kZShub2RlID0+IG5vZGUudHlwZS5uYW1lID09PSAncGFyYWdyYXBoJylcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gZmluZFBhcmVudE5vZGUocHJlZGljYXRlOiBQcmVkaWNhdGUpIHtcbiAgcmV0dXJuIChzZWxlY3Rpb246IFNlbGVjdGlvbikgPT4gZmluZFBhcmVudE5vZGVDbG9zZXN0VG9Qb3Moc2VsZWN0aW9uLiRmcm9tLCBwcmVkaWNhdGUpXG59XG4iLCAiaW1wb3J0IHsgU2NoZW1hIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuaW1wb3J0IHsgRWRpdG9yIH0gZnJvbSAnLi4vRWRpdG9yLmpzJ1xuaW1wb3J0IHsgRXh0ZW5zaW9uTWFuYWdlciB9IGZyb20gJy4uL0V4dGVuc2lvbk1hbmFnZXIuanMnXG5pbXBvcnQgeyBFeHRlbnNpb25zIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5pbXBvcnQgeyBnZXRTY2hlbWFCeVJlc29sdmVkRXh0ZW5zaW9ucyB9IGZyb20gJy4vZ2V0U2NoZW1hQnlSZXNvbHZlZEV4dGVuc2lvbnMuanMnXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTY2hlbWEoZXh0ZW5zaW9uczogRXh0ZW5zaW9ucywgZWRpdG9yPzogRWRpdG9yKTogU2NoZW1hIHtcbiAgY29uc3QgcmVzb2x2ZWRFeHRlbnNpb25zID0gRXh0ZW5zaW9uTWFuYWdlci5yZXNvbHZlKGV4dGVuc2lvbnMpXG5cbiAgcmV0dXJuIGdldFNjaGVtYUJ5UmVzb2x2ZWRFeHRlbnNpb25zKHJlc29sdmVkRXh0ZW5zaW9ucywgZWRpdG9yKVxufVxuIiwgImltcG9ydCB7IE5vZGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgeyBFeHRlbnNpb25zLCBKU09OQ29udGVudCB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuaW1wb3J0IHsgZ2V0SFRNTEZyb21GcmFnbWVudCB9IGZyb20gJy4vZ2V0SFRNTEZyb21GcmFnbWVudC5qcydcbmltcG9ydCB7IGdldFNjaGVtYSB9IGZyb20gJy4vZ2V0U2NoZW1hLmpzJ1xuXG4vKipcbiAqIEdlbmVyYXRlIEhUTUwgZnJvbSBhIEpTT05Db250ZW50XG4gKiBAcGFyYW0gZG9jIFRoZSBKU09OQ29udGVudCB0byBnZW5lcmF0ZSBIVE1MIGZyb21cbiAqIEBwYXJhbSBleHRlbnNpb25zIFRoZSBleHRlbnNpb25zIHRvIHVzZSBmb3IgdGhlIHNjaGVtYVxuICogQHJldHVybnMgVGhlIGdlbmVyYXRlZCBIVE1MXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZUhUTUwoZG9jOiBKU09OQ29udGVudCwgZXh0ZW5zaW9uczogRXh0ZW5zaW9ucyk6IHN0cmluZyB7XG4gIGNvbnN0IHNjaGVtYSA9IGdldFNjaGVtYShleHRlbnNpb25zKVxuICBjb25zdCBjb250ZW50Tm9kZSA9IE5vZGUuZnJvbUpTT04oc2NoZW1hLCBkb2MpXG5cbiAgcmV0dXJuIGdldEhUTUxGcm9tRnJhZ21lbnQoY29udGVudE5vZGUuY29udGVudCwgc2NoZW1hKVxufVxuIiwgImltcG9ydCB7IERPTVBhcnNlciB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmltcG9ydCB7IEV4dGVuc2lvbnMgfSBmcm9tICcuLi90eXBlcy5qcydcbmltcG9ydCB7IGVsZW1lbnRGcm9tU3RyaW5nIH0gZnJvbSAnLi4vdXRpbGl0aWVzL2VsZW1lbnRGcm9tU3RyaW5nLmpzJ1xuaW1wb3J0IHsgZ2V0U2NoZW1hIH0gZnJvbSAnLi9nZXRTY2hlbWEuanMnXG5cbi8qKlxuICogR2VuZXJhdGUgSlNPTkNvbnRlbnQgZnJvbSBIVE1MXG4gKiBAcGFyYW0gaHRtbCBUaGUgSFRNTCB0byBnZW5lcmF0ZSBKU09OQ29udGVudCBmcm9tXG4gKiBAcGFyYW0gZXh0ZW5zaW9ucyBUaGUgZXh0ZW5zaW9ucyB0byB1c2UgZm9yIHRoZSBzY2hlbWFcbiAqIEByZXR1cm5zIFRoZSBnZW5lcmF0ZWQgSlNPTkNvbnRlbnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlSlNPTihodG1sOiBzdHJpbmcsIGV4dGVuc2lvbnM6IEV4dGVuc2lvbnMpOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHtcbiAgY29uc3Qgc2NoZW1hID0gZ2V0U2NoZW1hKGV4dGVuc2lvbnMpXG4gIGNvbnN0IGRvbSA9IGVsZW1lbnRGcm9tU3RyaW5nKGh0bWwpXG5cbiAgcmV0dXJuIERPTVBhcnNlci5mcm9tU2NoZW1hKHNjaGVtYSkucGFyc2UoZG9tKS50b0pTT04oKVxufVxuIiwgImltcG9ydCB7IE5vZGUgYXMgUHJvc2VNaXJyb3JOb2RlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuaW1wb3J0IHsgVGV4dFNlcmlhbGl6ZXIgfSBmcm9tICcuLi90eXBlcy5qcydcbmltcG9ydCB7IGdldFRleHRCZXR3ZWVuIH0gZnJvbSAnLi9nZXRUZXh0QmV0d2Vlbi5qcydcblxuLyoqXG4gKiBHZXRzIHRoZSB0ZXh0IG9mIGEgUHJvc2VtaXJyb3Igbm9kZVxuICogQHBhcmFtIG5vZGUgVGhlIFByb3NlbWlycm9yIG5vZGVcbiAqIEBwYXJhbSBvcHRpb25zIE9wdGlvbnMgZm9yIHRoZSB0ZXh0IHNlcmlhbGl6ZXIgJiBibG9jayBzZXBhcmF0b3JcbiAqIEByZXR1cm5zIFRoZSB0ZXh0IG9mIHRoZSBub2RlXG4gKiBAZXhhbXBsZSBgYGBqc1xuICogY29uc3QgdGV4dCA9IGdldFRleHQobm9kZSwgeyBibG9ja1NlcGFyYXRvcjogJ1xcbicgfSlcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VGV4dChcbiAgbm9kZTogUHJvc2VNaXJyb3JOb2RlLFxuICBvcHRpb25zPzoge1xuICAgIGJsb2NrU2VwYXJhdG9yPzogc3RyaW5nXG4gICAgdGV4dFNlcmlhbGl6ZXJzPzogUmVjb3JkPHN0cmluZywgVGV4dFNlcmlhbGl6ZXI+XG4gIH0sXG4pIHtcbiAgY29uc3QgcmFuZ2UgPSB7XG4gICAgZnJvbTogMCxcbiAgICB0bzogbm9kZS5jb250ZW50LnNpemUsXG4gIH1cblxuICByZXR1cm4gZ2V0VGV4dEJldHdlZW4obm9kZSwgcmFuZ2UsIG9wdGlvbnMpXG59XG4iLCAiaW1wb3J0IHsgTm9kZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmltcG9ydCB7IEV4dGVuc2lvbnMsIEpTT05Db250ZW50LCBUZXh0U2VyaWFsaXplciB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuaW1wb3J0IHsgZ2V0U2NoZW1hIH0gZnJvbSAnLi9nZXRTY2hlbWEuanMnXG5pbXBvcnQgeyBnZXRUZXh0IH0gZnJvbSAnLi9nZXRUZXh0LmpzJ1xuaW1wb3J0IHsgZ2V0VGV4dFNlcmlhbGl6ZXJzRnJvbVNjaGVtYSB9IGZyb20gJy4vZ2V0VGV4dFNlcmlhbGl6ZXJzRnJvbVNjaGVtYS5qcydcblxuLyoqXG4gKiBHZW5lcmF0ZSByYXcgdGV4dCBmcm9tIGEgSlNPTkNvbnRlbnRcbiAqIEBwYXJhbSBkb2MgVGhlIEpTT05Db250ZW50IHRvIGdlbmVyYXRlIHRleHQgZnJvbVxuICogQHBhcmFtIGV4dGVuc2lvbnMgVGhlIGV4dGVuc2lvbnMgdG8gdXNlIGZvciB0aGUgc2NoZW1hXG4gKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25zIGZvciB0aGUgdGV4dCBnZW5lcmF0aW9uIGYuZS4gYmxvY2tTZXBhcmF0b3Igb3IgdGV4dFNlcmlhbGl6ZXJzXG4gKiBAcmV0dXJucyBUaGUgZ2VuZXJhdGVkIHRleHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlVGV4dChcbiAgZG9jOiBKU09OQ29udGVudCxcbiAgZXh0ZW5zaW9uczogRXh0ZW5zaW9ucyxcbiAgb3B0aW9ucz86IHtcbiAgICBibG9ja1NlcGFyYXRvcj86IHN0cmluZ1xuICAgIHRleHRTZXJpYWxpemVycz86IFJlY29yZDxzdHJpbmcsIFRleHRTZXJpYWxpemVyPlxuICB9LFxuKTogc3RyaW5nIHtcbiAgY29uc3QgeyBibG9ja1NlcGFyYXRvciA9ICdcXG5cXG4nLCB0ZXh0U2VyaWFsaXplcnMgPSB7fSB9ID0gb3B0aW9ucyB8fCB7fVxuICBjb25zdCBzY2hlbWEgPSBnZXRTY2hlbWEoZXh0ZW5zaW9ucylcbiAgY29uc3QgY29udGVudE5vZGUgPSBOb2RlLmZyb21KU09OKHNjaGVtYSwgZG9jKVxuXG4gIHJldHVybiBnZXRUZXh0KGNvbnRlbnROb2RlLCB7XG4gICAgYmxvY2tTZXBhcmF0b3IsXG4gICAgdGV4dFNlcmlhbGl6ZXJzOiB7XG4gICAgICAuLi5nZXRUZXh0U2VyaWFsaXplcnNGcm9tU2NoZW1hKHNjaGVtYSksXG4gICAgICAuLi50ZXh0U2VyaWFsaXplcnMsXG4gICAgfSxcbiAgfSlcbn1cbiIsICJpbXBvcnQgeyBOb2RlLCBOb2RlVHlwZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5pbXBvcnQgeyBFZGl0b3JTdGF0ZSB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmltcG9ydCB7IGdldE5vZGVUeXBlIH0gZnJvbSAnLi9nZXROb2RlVHlwZS5qcydcblxuZXhwb3J0IGZ1bmN0aW9uIGdldE5vZGVBdHRyaWJ1dGVzKFxuICBzdGF0ZTogRWRpdG9yU3RhdGUsXG4gIHR5cGVPck5hbWU6IHN0cmluZyB8IE5vZGVUeXBlLFxuKTogUmVjb3JkPHN0cmluZywgYW55PiB7XG4gIGNvbnN0IHR5cGUgPSBnZXROb2RlVHlwZSh0eXBlT3JOYW1lLCBzdGF0ZS5zY2hlbWEpXG4gIGNvbnN0IHsgZnJvbSwgdG8gfSA9IHN0YXRlLnNlbGVjdGlvblxuICBjb25zdCBub2RlczogTm9kZVtdID0gW11cblxuICBzdGF0ZS5kb2Mubm9kZXNCZXR3ZWVuKGZyb20sIHRvLCBub2RlID0+IHtcbiAgICBub2Rlcy5wdXNoKG5vZGUpXG4gIH0pXG5cbiAgY29uc3Qgbm9kZSA9IG5vZGVzLnJldmVyc2UoKS5maW5kKG5vZGVJdGVtID0+IG5vZGVJdGVtLnR5cGUubmFtZSA9PT0gdHlwZS5uYW1lKVxuXG4gIGlmICghbm9kZSkge1xuICAgIHJldHVybiB7fVxuICB9XG5cbiAgcmV0dXJuIHsgLi4ubm9kZS5hdHRycyB9XG59XG4iLCAiaW1wb3J0IHsgTWFya1R5cGUsIE5vZGVUeXBlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcbmltcG9ydCB7IEVkaXRvclN0YXRlIH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcblxuaW1wb3J0IHsgZ2V0TWFya0F0dHJpYnV0ZXMgfSBmcm9tICcuL2dldE1hcmtBdHRyaWJ1dGVzLmpzJ1xuaW1wb3J0IHsgZ2V0Tm9kZUF0dHJpYnV0ZXMgfSBmcm9tICcuL2dldE5vZGVBdHRyaWJ1dGVzLmpzJ1xuaW1wb3J0IHsgZ2V0U2NoZW1hVHlwZU5hbWVCeU5hbWUgfSBmcm9tICcuL2dldFNjaGVtYVR5cGVOYW1lQnlOYW1lLmpzJ1xuXG4vKipcbiAqIEdldCBub2RlIG9yIG1hcmsgYXR0cmlidXRlcyBieSB0eXBlIG9yIG5hbWUgb24gdGhlIGN1cnJlbnQgZWRpdG9yIHN0YXRlXG4gKiBAcGFyYW0gc3RhdGUgVGhlIGN1cnJlbnQgZWRpdG9yIHN0YXRlXG4gKiBAcGFyYW0gdHlwZU9yTmFtZSBUaGUgbm9kZSBvciBtYXJrIHR5cGUgb3IgbmFtZVxuICogQHJldHVybnMgVGhlIGF0dHJpYnV0ZXMgb2YgdGhlIG5vZGUgb3IgbWFyayBvciBhbiBlbXB0eSBvYmplY3RcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEF0dHJpYnV0ZXMoXG4gIHN0YXRlOiBFZGl0b3JTdGF0ZSxcbiAgdHlwZU9yTmFtZTogc3RyaW5nIHwgTm9kZVR5cGUgfCBNYXJrVHlwZSxcbik6IFJlY29yZDxzdHJpbmcsIGFueT4ge1xuICBjb25zdCBzY2hlbWFUeXBlID0gZ2V0U2NoZW1hVHlwZU5hbWVCeU5hbWUoXG4gICAgdHlwZW9mIHR5cGVPck5hbWUgPT09ICdzdHJpbmcnID8gdHlwZU9yTmFtZSA6IHR5cGVPck5hbWUubmFtZSxcbiAgICBzdGF0ZS5zY2hlbWEsXG4gIClcblxuICBpZiAoc2NoZW1hVHlwZSA9PT0gJ25vZGUnKSB7XG4gICAgcmV0dXJuIGdldE5vZGVBdHRyaWJ1dGVzKHN0YXRlLCB0eXBlT3JOYW1lIGFzIE5vZGVUeXBlKVxuICB9XG5cbiAgaWYgKHNjaGVtYVR5cGUgPT09ICdtYXJrJykge1xuICAgIHJldHVybiBnZXRNYXJrQXR0cmlidXRlcyhzdGF0ZSwgdHlwZU9yTmFtZSBhcyBNYXJrVHlwZSlcbiAgfVxuXG4gIHJldHVybiB7fVxufVxuIiwgIi8qKlxuICogUmVtb3ZlcyBkdXBsaWNhdGVkIHZhbHVlcyB3aXRoaW4gYW4gYXJyYXkuXG4gKiBTdXBwb3J0cyBudW1iZXJzLCBzdHJpbmdzIGFuZCBvYmplY3RzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlRHVwbGljYXRlczxUPihhcnJheTogVFtdLCBieSA9IEpTT04uc3RyaW5naWZ5KTogVFtdIHtcbiAgY29uc3Qgc2VlbjogUmVjb3JkPGFueSwgYW55PiA9IHt9XG5cbiAgcmV0dXJuIGFycmF5LmZpbHRlcihpdGVtID0+IHtcbiAgICBjb25zdCBrZXkgPSBieShpdGVtKVxuXG4gICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzZWVuLCBrZXkpXG4gICAgICA/IGZhbHNlXG4gICAgICA6IChzZWVuW2tleV0gPSB0cnVlKVxuICB9KVxufVxuIiwgImltcG9ydCB7IFN0ZXAsIFRyYW5zZm9ybSB9IGZyb20gJ0B0aXB0YXAvcG0vdHJhbnNmb3JtJ1xuXG5pbXBvcnQgeyBSYW5nZSB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuaW1wb3J0IHsgcmVtb3ZlRHVwbGljYXRlcyB9IGZyb20gJy4uL3V0aWxpdGllcy9yZW1vdmVEdXBsaWNhdGVzLmpzJ1xuXG5leHBvcnQgdHlwZSBDaGFuZ2VkUmFuZ2UgPSB7XG4gIG9sZFJhbmdlOiBSYW5nZSxcbiAgbmV3UmFuZ2U6IFJhbmdlLFxufVxuXG4vKipcbiAqIFJlbW92ZXMgZHVwbGljYXRlZCByYW5nZXMgYW5kIHJhbmdlcyB0aGF0IGFyZVxuICogZnVsbHkgY2FwdHVyZWQgYnkgb3RoZXIgcmFuZ2VzLlxuICovXG5mdW5jdGlvbiBzaW1wbGlmeUNoYW5nZWRSYW5nZXMoY2hhbmdlczogQ2hhbmdlZFJhbmdlW10pOiBDaGFuZ2VkUmFuZ2VbXSB7XG4gIGNvbnN0IHVuaXF1ZUNoYW5nZXMgPSByZW1vdmVEdXBsaWNhdGVzKGNoYW5nZXMpXG5cbiAgcmV0dXJuIHVuaXF1ZUNoYW5nZXMubGVuZ3RoID09PSAxXG4gICAgPyB1bmlxdWVDaGFuZ2VzXG4gICAgOiB1bmlxdWVDaGFuZ2VzLmZpbHRlcigoY2hhbmdlLCBpbmRleCkgPT4ge1xuICAgICAgY29uc3QgcmVzdCA9IHVuaXF1ZUNoYW5nZXMuZmlsdGVyKChfLCBpKSA9PiBpICE9PSBpbmRleClcblxuICAgICAgcmV0dXJuICFyZXN0LnNvbWUob3RoZXJDaGFuZ2UgPT4ge1xuICAgICAgICByZXR1cm4gY2hhbmdlLm9sZFJhbmdlLmZyb20gPj0gb3RoZXJDaGFuZ2Uub2xkUmFuZ2UuZnJvbVxuICAgICAgICAgICYmIGNoYW5nZS5vbGRSYW5nZS50byA8PSBvdGhlckNoYW5nZS5vbGRSYW5nZS50b1xuICAgICAgICAgICYmIGNoYW5nZS5uZXdSYW5nZS5mcm9tID49IG90aGVyQ2hhbmdlLm5ld1JhbmdlLmZyb21cbiAgICAgICAgICAmJiBjaGFuZ2UubmV3UmFuZ2UudG8gPD0gb3RoZXJDaGFuZ2UubmV3UmFuZ2UudG9cbiAgICAgIH0pXG4gICAgfSlcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgbGlzdCBvZiBjaGFuZ2VkIHJhbmdlc1xuICogYmFzZWQgb24gdGhlIGZpcnN0IGFuZCBsYXN0IHN0YXRlIG9mIGFsbCBzdGVwcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldENoYW5nZWRSYW5nZXModHJhbnNmb3JtOiBUcmFuc2Zvcm0pOiBDaGFuZ2VkUmFuZ2VbXSB7XG4gIGNvbnN0IHsgbWFwcGluZywgc3RlcHMgfSA9IHRyYW5zZm9ybVxuICBjb25zdCBjaGFuZ2VzOiBDaGFuZ2VkUmFuZ2VbXSA9IFtdXG5cbiAgbWFwcGluZy5tYXBzLmZvckVhY2goKHN0ZXBNYXAsIGluZGV4KSA9PiB7XG4gICAgY29uc3QgcmFuZ2VzOiBSYW5nZVtdID0gW11cblxuICAgIC8vIFRoaXMgYWNjb3VudHMgZm9yIHN0ZXAgY2hhbmdlcyB3aGVyZSBubyByYW5nZSB3YXMgYWN0dWFsbHkgYWx0ZXJlZFxuICAgIC8vIGUuZy4gd2hlbiBzZXR0aW5nIGEgbWFyaywgbm9kZSBhdHRyaWJ1dGUsIGV0Yy5cbiAgICAvLyBAdHMtaWdub3JlXG4gICAgaWYgKCFzdGVwTWFwLnJhbmdlcy5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IHsgZnJvbSwgdG8gfSA9IHN0ZXBzW2luZGV4XSBhcyBTdGVwICYge1xuICAgICAgICBmcm9tPzogbnVtYmVyLFxuICAgICAgICB0bz86IG51bWJlcixcbiAgICAgIH1cblxuICAgICAgaWYgKGZyb20gPT09IHVuZGVmaW5lZCB8fCB0byA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICByYW5nZXMucHVzaCh7IGZyb20sIHRvIH0pXG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ZXBNYXAuZm9yRWFjaCgoZnJvbSwgdG8pID0+IHtcbiAgICAgICAgcmFuZ2VzLnB1c2goeyBmcm9tLCB0byB9KVxuICAgICAgfSlcbiAgICB9XG5cbiAgICByYW5nZXMuZm9yRWFjaCgoeyBmcm9tLCB0byB9KSA9PiB7XG4gICAgICBjb25zdCBuZXdTdGFydCA9IG1hcHBpbmcuc2xpY2UoaW5kZXgpLm1hcChmcm9tLCAtMSlcbiAgICAgIGNvbnN0IG5ld0VuZCA9IG1hcHBpbmcuc2xpY2UoaW5kZXgpLm1hcCh0bylcbiAgICAgIGNvbnN0IG9sZFN0YXJ0ID0gbWFwcGluZy5pbnZlcnQoKS5tYXAobmV3U3RhcnQsIC0xKVxuICAgICAgY29uc3Qgb2xkRW5kID0gbWFwcGluZy5pbnZlcnQoKS5tYXAobmV3RW5kKVxuXG4gICAgICBjaGFuZ2VzLnB1c2goe1xuICAgICAgICBvbGRSYW5nZToge1xuICAgICAgICAgIGZyb206IG9sZFN0YXJ0LFxuICAgICAgICAgIHRvOiBvbGRFbmQsXG4gICAgICAgIH0sXG4gICAgICAgIG5ld1JhbmdlOiB7XG4gICAgICAgICAgZnJvbTogbmV3U3RhcnQsXG4gICAgICAgICAgdG86IG5ld0VuZCxcbiAgICAgICAgfSxcbiAgICAgIH0pXG4gICAgfSlcbiAgfSlcblxuICByZXR1cm4gc2ltcGxpZnlDaGFuZ2VkUmFuZ2VzKGNoYW5nZXMpXG59XG4iLCAiaW1wb3J0IHsgTm9kZSBhcyBQcm9zZU1pcnJvck5vZGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgeyBKU09OQ29udGVudCB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5pbnRlcmZhY2UgRGVidWdKU09OQ29udGVudCBleHRlbmRzIEpTT05Db250ZW50IHtcbiAgZnJvbTogbnVtYmVyXG4gIHRvOiBudW1iZXJcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldERlYnVnSlNPTihub2RlOiBQcm9zZU1pcnJvck5vZGUsIHN0YXJ0T2Zmc2V0ID0gMCk6IERlYnVnSlNPTkNvbnRlbnQge1xuICBjb25zdCBpc1RvcE5vZGUgPSBub2RlLnR5cGUgPT09IG5vZGUudHlwZS5zY2hlbWEudG9wTm9kZVR5cGVcbiAgY29uc3QgaW5jcmVtZW50ID0gaXNUb3BOb2RlID8gMCA6IDFcbiAgY29uc3QgZnJvbSA9IHN0YXJ0T2Zmc2V0XG4gIGNvbnN0IHRvID0gZnJvbSArIG5vZGUubm9kZVNpemVcbiAgY29uc3QgbWFya3MgPSBub2RlLm1hcmtzLm1hcChtYXJrID0+IHtcbiAgICBjb25zdCBvdXRwdXQ6IHsgdHlwZTogc3RyaW5nOyBhdHRycz86IFJlY29yZDxzdHJpbmcsIGFueT4gfSA9IHtcbiAgICAgIHR5cGU6IG1hcmsudHlwZS5uYW1lLFxuICAgIH1cblxuICAgIGlmIChPYmplY3Qua2V5cyhtYXJrLmF0dHJzKS5sZW5ndGgpIHtcbiAgICAgIG91dHB1dC5hdHRycyA9IHsgLi4ubWFyay5hdHRycyB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dHB1dFxuICB9KVxuICBjb25zdCBhdHRycyA9IHsgLi4ubm9kZS5hdHRycyB9XG4gIGNvbnN0IG91dHB1dDogRGVidWdKU09OQ29udGVudCA9IHtcbiAgICB0eXBlOiBub2RlLnR5cGUubmFtZSxcbiAgICBmcm9tLFxuICAgIHRvLFxuICB9XG5cbiAgaWYgKE9iamVjdC5rZXlzKGF0dHJzKS5sZW5ndGgpIHtcbiAgICBvdXRwdXQuYXR0cnMgPSBhdHRyc1xuICB9XG5cbiAgaWYgKG1hcmtzLmxlbmd0aCkge1xuICAgIG91dHB1dC5tYXJrcyA9IG1hcmtzXG4gIH1cblxuICBpZiAobm9kZS5jb250ZW50LmNoaWxkQ291bnQpIHtcbiAgICBvdXRwdXQuY29udGVudCA9IFtdXG5cbiAgICBub2RlLmZvckVhY2goKGNoaWxkLCBvZmZzZXQpID0+IHtcbiAgICAgIG91dHB1dC5jb250ZW50Py5wdXNoKGdldERlYnVnSlNPTihjaGlsZCwgc3RhcnRPZmZzZXQgKyBvZmZzZXQgKyBpbmNyZW1lbnQpKVxuICAgIH0pXG4gIH1cblxuICBpZiAobm9kZS50ZXh0KSB7XG4gICAgb3V0cHV0LnRleHQgPSBub2RlLnRleHRcbiAgfVxuXG4gIHJldHVybiBvdXRwdXRcbn1cbiIsICJpbXBvcnQgeyBOb2RlIGFzIFByb3NlTWlycm9yTm9kZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmltcG9ydCB7IE1hcmtSYW5nZSB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuaW1wb3J0IHsgZ2V0TWFya1JhbmdlIH0gZnJvbSAnLi9nZXRNYXJrUmFuZ2UuanMnXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRNYXJrc0JldHdlZW4oZnJvbTogbnVtYmVyLCB0bzogbnVtYmVyLCBkb2M6IFByb3NlTWlycm9yTm9kZSk6IE1hcmtSYW5nZVtdIHtcbiAgY29uc3QgbWFya3M6IE1hcmtSYW5nZVtdID0gW11cblxuICAvLyBnZXQgYWxsIGluY2x1c2l2ZSBtYXJrcyBvbiBlbXB0eSBzZWxlY3Rpb25cbiAgaWYgKGZyb20gPT09IHRvKSB7XG4gICAgZG9jXG4gICAgICAucmVzb2x2ZShmcm9tKVxuICAgICAgLm1hcmtzKClcbiAgICAgIC5mb3JFYWNoKG1hcmsgPT4ge1xuICAgICAgICBjb25zdCAkcG9zID0gZG9jLnJlc29sdmUoZnJvbSlcbiAgICAgICAgY29uc3QgcmFuZ2UgPSBnZXRNYXJrUmFuZ2UoJHBvcywgbWFyay50eXBlKVxuXG4gICAgICAgIGlmICghcmFuZ2UpIHtcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIG1hcmtzLnB1c2goe1xuICAgICAgICAgIG1hcmssXG4gICAgICAgICAgLi4ucmFuZ2UsXG4gICAgICAgIH0pXG4gICAgICB9KVxuICB9IGVsc2Uge1xuICAgIGRvYy5ub2Rlc0JldHdlZW4oZnJvbSwgdG8sIChub2RlLCBwb3MpID0+IHtcbiAgICAgIGlmICghbm9kZSB8fCBub2RlPy5ub2RlU2l6ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICBtYXJrcy5wdXNoKFxuICAgICAgICAuLi5ub2RlLm1hcmtzLm1hcChtYXJrID0+ICh7XG4gICAgICAgICAgZnJvbTogcG9zLFxuICAgICAgICAgIHRvOiBwb3MgKyBub2RlLm5vZGVTaXplLFxuICAgICAgICAgIG1hcmssXG4gICAgICAgIH0pKSxcbiAgICAgIClcbiAgICB9KVxuICB9XG5cbiAgcmV0dXJuIG1hcmtzXG59XG4iLCAiaW1wb3J0IHsgTm9kZSwgTm9kZVR5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuaW1wb3J0IHsgRWRpdG9yU3RhdGUgfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG4vKipcbiAqIEZpbmRzIHRoZSBmaXJzdCBub2RlIG9mIGEgZ2l2ZW4gdHlwZSBvciBuYW1lIGluIHRoZSBjdXJyZW50IHNlbGVjdGlvbi5cbiAqIEBwYXJhbSBzdGF0ZSBUaGUgZWRpdG9yIHN0YXRlLlxuICogQHBhcmFtIHR5cGVPck5hbWUgVGhlIG5vZGUgdHlwZSBvciBuYW1lLlxuICogQHBhcmFtIHBvcyBUaGUgcG9zaXRpb24gdG8gc3RhcnQgc2VhcmNoaW5nIGZyb20uXG4gKiBAcGFyYW0gbWF4RGVwdGggVGhlIG1heGltdW0gZGVwdGggdG8gc2VhcmNoLlxuICogQHJldHVybnMgVGhlIG5vZGUgYW5kIHRoZSBkZXB0aCBhcyBhbiBhcnJheS5cbiAqL1xuZXhwb3J0IGNvbnN0IGdldE5vZGVBdFBvc2l0aW9uID0gKHN0YXRlOiBFZGl0b3JTdGF0ZSwgdHlwZU9yTmFtZTogc3RyaW5nIHwgTm9kZVR5cGUsIHBvczogbnVtYmVyLCBtYXhEZXB0aCA9IDIwKSA9PiB7XG4gIGNvbnN0ICRwb3MgPSBzdGF0ZS5kb2MucmVzb2x2ZShwb3MpXG5cbiAgbGV0IGN1cnJlbnREZXB0aCA9IG1heERlcHRoXG4gIGxldCBub2RlOiBOb2RlIHwgbnVsbCA9IG51bGxcblxuICB3aGlsZSAoY3VycmVudERlcHRoID4gMCAmJiBub2RlID09PSBudWxsKSB7XG4gICAgY29uc3QgY3VycmVudE5vZGUgPSAkcG9zLm5vZGUoY3VycmVudERlcHRoKVxuXG4gICAgaWYgKGN1cnJlbnROb2RlPy50eXBlLm5hbWUgPT09IHR5cGVPck5hbWUpIHtcbiAgICAgIG5vZGUgPSBjdXJyZW50Tm9kZVxuICAgIH0gZWxzZSB7XG4gICAgICBjdXJyZW50RGVwdGggLT0gMVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBbbm9kZSwgY3VycmVudERlcHRoXSBhcyBbTm9kZSB8IG51bGwsIG51bWJlcl1cbn1cbiIsICJpbXBvcnQgeyBFeHRlbnNpb25BdHRyaWJ1dGUgfSBmcm9tICcuLi90eXBlcy5qcydcblxuLyoqXG4gKiBSZXR1cm4gYXR0cmlidXRlcyBvZiBhbiBleHRlbnNpb24gdGhhdCBzaG91bGQgYmUgc3BsaXR0ZWQgYnkga2VlcE9uU3BsaXQgZmxhZ1xuICogQHBhcmFtIGV4dGVuc2lvbkF0dHJpYnV0ZXMgQXJyYXkgb2YgZXh0ZW5zaW9uIGF0dHJpYnV0ZXNcbiAqIEBwYXJhbSB0eXBlTmFtZSBUaGUgdHlwZSBvZiB0aGUgZXh0ZW5zaW9uXG4gKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgYXR0cmlidXRlcyBvZiB0aGUgZXh0ZW5zaW9uXG4gKiBAcmV0dXJucyBUaGUgc3BsaXR0ZWQgYXR0cmlidXRlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U3BsaXR0ZWRBdHRyaWJ1dGVzKFxuICBleHRlbnNpb25BdHRyaWJ1dGVzOiBFeHRlbnNpb25BdHRyaWJ1dGVbXSxcbiAgdHlwZU5hbWU6IHN0cmluZyxcbiAgYXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgYW55Pixcbik6IFJlY29yZDxzdHJpbmcsIGFueT4ge1xuICByZXR1cm4gT2JqZWN0LmZyb21FbnRyaWVzKE9iamVjdFxuICAgIC5lbnRyaWVzKGF0dHJpYnV0ZXMpXG4gICAgLmZpbHRlcigoW25hbWVdKSA9PiB7XG4gICAgICBjb25zdCBleHRlbnNpb25BdHRyaWJ1dGUgPSBleHRlbnNpb25BdHRyaWJ1dGVzLmZpbmQoaXRlbSA9PiB7XG4gICAgICAgIHJldHVybiBpdGVtLnR5cGUgPT09IHR5cGVOYW1lICYmIGl0ZW0ubmFtZSA9PT0gbmFtZVxuICAgICAgfSlcblxuICAgICAgaWYgKCFleHRlbnNpb25BdHRyaWJ1dGUpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9XG5cbiAgICAgIHJldHVybiBleHRlbnNpb25BdHRyaWJ1dGUuYXR0cmlidXRlLmtlZXBPblNwbGl0XG4gICAgfSkpXG59XG4iLCAiaW1wb3J0IHsgTWFya1R5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuaW1wb3J0IHsgRWRpdG9yU3RhdGUgfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5pbXBvcnQgeyBNYXJrUmFuZ2UgfSBmcm9tICcuLi90eXBlcy5qcydcbmltcG9ydCB7IG9iamVjdEluY2x1ZGVzIH0gZnJvbSAnLi4vdXRpbGl0aWVzL29iamVjdEluY2x1ZGVzLmpzJ1xuaW1wb3J0IHsgZ2V0TWFya1R5cGUgfSBmcm9tICcuL2dldE1hcmtUeXBlLmpzJ1xuXG5leHBvcnQgZnVuY3Rpb24gaXNNYXJrQWN0aXZlKFxuICBzdGF0ZTogRWRpdG9yU3RhdGUsXG4gIHR5cGVPck5hbWU6IE1hcmtUeXBlIHwgc3RyaW5nIHwgbnVsbCxcbiAgYXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9LFxuKTogYm9vbGVhbiB7XG4gIGNvbnN0IHsgZW1wdHksIHJhbmdlcyB9ID0gc3RhdGUuc2VsZWN0aW9uXG4gIGNvbnN0IHR5cGUgPSB0eXBlT3JOYW1lID8gZ2V0TWFya1R5cGUodHlwZU9yTmFtZSwgc3RhdGUuc2NoZW1hKSA6IG51bGxcblxuICBpZiAoZW1wdHkpIHtcbiAgICByZXR1cm4gISEoc3RhdGUuc3RvcmVkTWFya3MgfHwgc3RhdGUuc2VsZWN0aW9uLiRmcm9tLm1hcmtzKCkpXG4gICAgICAuZmlsdGVyKG1hcmsgPT4ge1xuICAgICAgICBpZiAoIXR5cGUpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHR5cGUubmFtZSA9PT0gbWFyay50eXBlLm5hbWVcbiAgICAgIH0pXG4gICAgICAuZmluZChtYXJrID0+IG9iamVjdEluY2x1ZGVzKG1hcmsuYXR0cnMsIGF0dHJpYnV0ZXMsIHsgc3RyaWN0OiBmYWxzZSB9KSlcbiAgfVxuXG4gIGxldCBzZWxlY3Rpb25SYW5nZSA9IDBcbiAgY29uc3QgbWFya1JhbmdlczogTWFya1JhbmdlW10gPSBbXVxuXG4gIHJhbmdlcy5mb3JFYWNoKCh7ICRmcm9tLCAkdG8gfSkgPT4ge1xuICAgIGNvbnN0IGZyb20gPSAkZnJvbS5wb3NcbiAgICBjb25zdCB0byA9ICR0by5wb3NcblxuICAgIHN0YXRlLmRvYy5ub2Rlc0JldHdlZW4oZnJvbSwgdG8sIChub2RlLCBwb3MpID0+IHtcbiAgICAgIGlmICghbm9kZS5pc1RleHQgJiYgIW5vZGUubWFya3MubGVuZ3RoKSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICBjb25zdCByZWxhdGl2ZUZyb20gPSBNYXRoLm1heChmcm9tLCBwb3MpXG4gICAgICBjb25zdCByZWxhdGl2ZVRvID0gTWF0aC5taW4odG8sIHBvcyArIG5vZGUubm9kZVNpemUpXG4gICAgICBjb25zdCByYW5nZSA9IHJlbGF0aXZlVG8gLSByZWxhdGl2ZUZyb21cblxuICAgICAgc2VsZWN0aW9uUmFuZ2UgKz0gcmFuZ2VcblxuICAgICAgbWFya1Jhbmdlcy5wdXNoKFxuICAgICAgICAuLi5ub2RlLm1hcmtzLm1hcChtYXJrID0+ICh7XG4gICAgICAgICAgbWFyayxcbiAgICAgICAgICBmcm9tOiByZWxhdGl2ZUZyb20sXG4gICAgICAgICAgdG86IHJlbGF0aXZlVG8sXG4gICAgICAgIH0pKSxcbiAgICAgIClcbiAgICB9KVxuICB9KVxuXG4gIGlmIChzZWxlY3Rpb25SYW5nZSA9PT0gMCkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLy8gY2FsY3VsYXRlIHJhbmdlIG9mIG1hdGNoZWQgbWFya1xuICBjb25zdCBtYXRjaGVkUmFuZ2UgPSBtYXJrUmFuZ2VzXG4gICAgLmZpbHRlcihtYXJrUmFuZ2UgPT4ge1xuICAgICAgaWYgKCF0eXBlKSB7XG4gICAgICAgIHJldHVybiB0cnVlXG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0eXBlLm5hbWUgPT09IG1hcmtSYW5nZS5tYXJrLnR5cGUubmFtZVxuICAgIH0pXG4gICAgLmZpbHRlcihtYXJrUmFuZ2UgPT4gb2JqZWN0SW5jbHVkZXMobWFya1JhbmdlLm1hcmsuYXR0cnMsIGF0dHJpYnV0ZXMsIHsgc3RyaWN0OiBmYWxzZSB9KSlcbiAgICAucmVkdWNlKChzdW0sIG1hcmtSYW5nZSkgPT4gc3VtICsgbWFya1JhbmdlLnRvIC0gbWFya1JhbmdlLmZyb20sIDApXG5cbiAgLy8gY2FsY3VsYXRlIHJhbmdlIG9mIG1hcmtzIHRoYXQgZXhjbHVkZXMgdGhlIHNlYXJjaGVkIG1hcmtcbiAgLy8gZm9yIGV4YW1wbGUgYGNvZGVgIGRvZXNu4oCZdCBhbGxvdyBhbnkgb3RoZXIgbWFya3NcbiAgY29uc3QgZXhjbHVkZWRSYW5nZSA9IG1hcmtSYW5nZXNcbiAgICAuZmlsdGVyKG1hcmtSYW5nZSA9PiB7XG4gICAgICBpZiAoIXR5cGUpIHtcbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG1hcmtSYW5nZS5tYXJrLnR5cGUgIT09IHR5cGUgJiYgbWFya1JhbmdlLm1hcmsudHlwZS5leGNsdWRlcyh0eXBlKVxuICAgIH0pXG4gICAgLnJlZHVjZSgoc3VtLCBtYXJrUmFuZ2UpID0+IHN1bSArIG1hcmtSYW5nZS50byAtIG1hcmtSYW5nZS5mcm9tLCAwKVxuXG4gIC8vIHdlIG9ubHkgaW5jbHVkZSB0aGUgcmVzdWx0IG9mIGBleGNsdWRlZFJhbmdlYFxuICAvLyBpZiB0aGVyZSBpcyBhIG1hdGNoIGF0IGFsbFxuICBjb25zdCByYW5nZSA9IG1hdGNoZWRSYW5nZSA+IDAgPyBtYXRjaGVkUmFuZ2UgKyBleGNsdWRlZFJhbmdlIDogbWF0Y2hlZFJhbmdlXG5cbiAgcmV0dXJuIHJhbmdlID49IHNlbGVjdGlvblJhbmdlXG59XG4iLCAiaW1wb3J0IHsgRWRpdG9yU3RhdGUgfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5pbXBvcnQgeyBnZXRTY2hlbWFUeXBlTmFtZUJ5TmFtZSB9IGZyb20gJy4vZ2V0U2NoZW1hVHlwZU5hbWVCeU5hbWUuanMnXG5pbXBvcnQgeyBpc01hcmtBY3RpdmUgfSBmcm9tICcuL2lzTWFya0FjdGl2ZS5qcydcbmltcG9ydCB7IGlzTm9kZUFjdGl2ZSB9IGZyb20gJy4vaXNOb2RlQWN0aXZlLmpzJ1xuXG5leHBvcnQgZnVuY3Rpb24gaXNBY3RpdmUoXG4gIHN0YXRlOiBFZGl0b3JTdGF0ZSxcbiAgbmFtZTogc3RyaW5nIHwgbnVsbCxcbiAgYXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9LFxuKTogYm9vbGVhbiB7XG4gIGlmICghbmFtZSkge1xuICAgIHJldHVybiBpc05vZGVBY3RpdmUoc3RhdGUsIG51bGwsIGF0dHJpYnV0ZXMpIHx8IGlzTWFya0FjdGl2ZShzdGF0ZSwgbnVsbCwgYXR0cmlidXRlcylcbiAgfVxuXG4gIGNvbnN0IHNjaGVtYVR5cGUgPSBnZXRTY2hlbWFUeXBlTmFtZUJ5TmFtZShuYW1lLCBzdGF0ZS5zY2hlbWEpXG5cbiAgaWYgKHNjaGVtYVR5cGUgPT09ICdub2RlJykge1xuICAgIHJldHVybiBpc05vZGVBY3RpdmUoc3RhdGUsIG5hbWUsIGF0dHJpYnV0ZXMpXG4gIH1cblxuICBpZiAoc2NoZW1hVHlwZSA9PT0gJ21hcmsnKSB7XG4gICAgcmV0dXJuIGlzTWFya0FjdGl2ZShzdGF0ZSwgbmFtZSwgYXR0cmlidXRlcylcbiAgfVxuXG4gIHJldHVybiBmYWxzZVxufVxuIiwgImltcG9ydCB7IEVkaXRvclN0YXRlIH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcblxuaW1wb3J0IHsgZmluZFBhcmVudE5vZGUgfSBmcm9tICcuL2ZpbmRQYXJlbnROb2RlLmpzJ1xuXG5leHBvcnQgY29uc3QgaXNBdEVuZE9mTm9kZSA9IChzdGF0ZTogRWRpdG9yU3RhdGUsIG5vZGVUeXBlPzogc3RyaW5nKSA9PiB7XG4gIGNvbnN0IHsgJGZyb20sICR0bywgJGFuY2hvciB9ID0gc3RhdGUuc2VsZWN0aW9uXG5cbiAgaWYgKG5vZGVUeXBlKSB7XG4gICAgY29uc3QgcGFyZW50Tm9kZSA9IGZpbmRQYXJlbnROb2RlKG5vZGUgPT4gbm9kZS50eXBlLm5hbWUgPT09IG5vZGVUeXBlKShzdGF0ZS5zZWxlY3Rpb24pXG5cbiAgICBpZiAoIXBhcmVudE5vZGUpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIGNvbnN0ICRwYXJlbnRQb3MgPSBzdGF0ZS5kb2MucmVzb2x2ZShwYXJlbnROb2RlLnBvcyArIDEpXG5cbiAgICBpZiAoJGFuY2hvci5wb3MgKyAxID09PSAkcGFyZW50UG9zLmVuZCgpKSB7XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgaWYgKCR0by5wYXJlbnRPZmZzZXQgPCAkdG8ucGFyZW50Lm5vZGVTaXplIC0gMiB8fCAkZnJvbS5wb3MgIT09ICR0by5wb3MpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIHJldHVybiB0cnVlXG59XG4iLCAiaW1wb3J0IHsgRWRpdG9yU3RhdGUgfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5leHBvcnQgY29uc3QgaXNBdFN0YXJ0T2ZOb2RlID0gKHN0YXRlOiBFZGl0b3JTdGF0ZSkgPT4ge1xuICBjb25zdCB7ICRmcm9tLCAkdG8gfSA9IHN0YXRlLnNlbGVjdGlvblxuXG4gIGlmICgkZnJvbS5wYXJlbnRPZmZzZXQgPiAwIHx8ICRmcm9tLnBvcyAhPT0gJHRvLnBvcykge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgcmV0dXJuIHRydWVcbn1cbiIsICJpbXBvcnQgeyBnZXRFeHRlbnNpb25GaWVsZCB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0RXh0ZW5zaW9uRmllbGQuanMnXG5pbXBvcnQgeyBOb2RlQ29uZmlnIH0gZnJvbSAnLi4vaW5kZXguanMnXG5pbXBvcnQgeyBFeHRlbnNpb25zIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5pbXBvcnQgeyBjYWxsT3JSZXR1cm4gfSBmcm9tICcuLi91dGlsaXRpZXMvY2FsbE9yUmV0dXJuLmpzJ1xuaW1wb3J0IHsgc3BsaXRFeHRlbnNpb25zIH0gZnJvbSAnLi9zcGxpdEV4dGVuc2lvbnMuanMnXG5cbmV4cG9ydCBmdW5jdGlvbiBpc0xpc3QobmFtZTogc3RyaW5nLCBleHRlbnNpb25zOiBFeHRlbnNpb25zKTogYm9vbGVhbiB7XG4gIGNvbnN0IHsgbm9kZUV4dGVuc2lvbnMgfSA9IHNwbGl0RXh0ZW5zaW9ucyhleHRlbnNpb25zKVxuICBjb25zdCBleHRlbnNpb24gPSBub2RlRXh0ZW5zaW9ucy5maW5kKGl0ZW0gPT4gaXRlbS5uYW1lID09PSBuYW1lKVxuXG4gIGlmICghZXh0ZW5zaW9uKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBjb25zdCBjb250ZXh0ID0ge1xuICAgIG5hbWU6IGV4dGVuc2lvbi5uYW1lLFxuICAgIG9wdGlvbnM6IGV4dGVuc2lvbi5vcHRpb25zLFxuICAgIHN0b3JhZ2U6IGV4dGVuc2lvbi5zdG9yYWdlLFxuICB9XG4gIGNvbnN0IGdyb3VwID0gY2FsbE9yUmV0dXJuKGdldEV4dGVuc2lvbkZpZWxkPE5vZGVDb25maWdbJ2dyb3VwJ10+KGV4dGVuc2lvbiwgJ2dyb3VwJywgY29udGV4dCkpXG5cbiAgaWYgKHR5cGVvZiBncm91cCAhPT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIHJldHVybiBncm91cC5zcGxpdCgnICcpLmluY2x1ZGVzKCdsaXN0Jylcbn1cbiIsICJpbXBvcnQgeyBOb2RlIGFzIFByb3NlTWlycm9yTm9kZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBwcm9zZW1pcnJvciBub2RlIGlzIGVtcHR5LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNOb2RlRW1wdHkoXG4gIG5vZGU6IFByb3NlTWlycm9yTm9kZSxcbiAge1xuICAgIGNoZWNrQ2hpbGRyZW4gPSB0cnVlLFxuICAgIGlnbm9yZVdoaXRlc3BhY2UgPSBmYWxzZSxcbiAgfToge1xuICAgIC8qKlxuICAgICAqIFdoZW4gdHJ1ZSAoZGVmYXVsdCksIGl0IHdpbGwgYWxzbyBjaGVjayBpZiBhbGwgY2hpbGRyZW4gYXJlIGVtcHR5LlxuICAgICAqL1xuICAgIGNoZWNrQ2hpbGRyZW4/OiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIFdoZW4gdHJ1ZSwgaXQgd2lsbCBpZ25vcmUgd2hpdGVzcGFjZSB3aGVuIGNoZWNraW5nIGZvciBlbXB0aW5lc3MuXG4gICAgICovXG4gICAgaWdub3JlV2hpdGVzcGFjZT86IGJvb2xlYW47XG4gIH0gPSB7fSxcbik6IGJvb2xlYW4ge1xuICBpZiAoaWdub3JlV2hpdGVzcGFjZSkge1xuICAgIGlmIChub2RlLnR5cGUubmFtZSA9PT0gJ2hhcmRCcmVhaycpIHtcbiAgICAgIC8vIEhhcmQgYnJlYWtzIGFyZSBjb25zaWRlcmVkIGVtcHR5XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cbiAgICBpZiAobm9kZS5pc1RleHQpIHtcbiAgICAgIHJldHVybiAvXlxccyokL20udGVzdChub2RlLnRleHQgPz8gJycpXG4gICAgfVxuICB9XG5cbiAgaWYgKG5vZGUuaXNUZXh0KSB7XG4gICAgcmV0dXJuICFub2RlLnRleHRcbiAgfVxuXG4gIGlmIChub2RlLmlzQXRvbSB8fCBub2RlLmlzTGVhZikge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgaWYgKG5vZGUuY29udGVudC5jaGlsZENvdW50ID09PSAwKSB7XG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIGlmIChjaGVja0NoaWxkcmVuKSB7XG4gICAgbGV0IGlzQ29udGVudEVtcHR5ID0gdHJ1ZVxuXG4gICAgbm9kZS5jb250ZW50LmZvckVhY2goY2hpbGROb2RlID0+IHtcbiAgICAgIGlmIChpc0NvbnRlbnRFbXB0eSA9PT0gZmFsc2UpIHtcbiAgICAgICAgLy8gRXhpdCBlYXJseSBmb3IgcGVyZlxuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgaWYgKCFpc05vZGVFbXB0eShjaGlsZE5vZGUsIHsgaWdub3JlV2hpdGVzcGFjZSwgY2hlY2tDaGlsZHJlbiB9KSkge1xuICAgICAgICBpc0NvbnRlbnRFbXB0eSA9IGZhbHNlXG4gICAgICB9XG4gICAgfSlcblxuICAgIHJldHVybiBpc0NvbnRlbnRFbXB0eVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlXG59XG4iLCAiaW1wb3J0IHsgTm9kZVNlbGVjdGlvbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmV4cG9ydCBmdW5jdGlvbiBpc05vZGVTZWxlY3Rpb24odmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBOb2RlU2VsZWN0aW9uIHtcbiAgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgTm9kZVNlbGVjdGlvblxufVxuIiwgImltcG9ydCB7IEVkaXRvclZpZXcgfSBmcm9tICdAdGlwdGFwL3BtL3ZpZXcnXG5cbmltcG9ydCB7IG1pbk1heCB9IGZyb20gJy4uL3V0aWxpdGllcy9taW5NYXguanMnXG5cbmV4cG9ydCBmdW5jdGlvbiBwb3NUb0RPTVJlY3QodmlldzogRWRpdG9yVmlldywgZnJvbTogbnVtYmVyLCB0bzogbnVtYmVyKTogRE9NUmVjdCB7XG4gIGNvbnN0IG1pblBvcyA9IDBcbiAgY29uc3QgbWF4UG9zID0gdmlldy5zdGF0ZS5kb2MuY29udGVudC5zaXplXG4gIGNvbnN0IHJlc29sdmVkRnJvbSA9IG1pbk1heChmcm9tLCBtaW5Qb3MsIG1heFBvcylcbiAgY29uc3QgcmVzb2x2ZWRFbmQgPSBtaW5NYXgodG8sIG1pblBvcywgbWF4UG9zKVxuICBjb25zdCBzdGFydCA9IHZpZXcuY29vcmRzQXRQb3MocmVzb2x2ZWRGcm9tKVxuICBjb25zdCBlbmQgPSB2aWV3LmNvb3Jkc0F0UG9zKHJlc29sdmVkRW5kLCAtMSlcbiAgY29uc3QgdG9wID0gTWF0aC5taW4oc3RhcnQudG9wLCBlbmQudG9wKVxuICBjb25zdCBib3R0b20gPSBNYXRoLm1heChzdGFydC5ib3R0b20sIGVuZC5ib3R0b20pXG4gIGNvbnN0IGxlZnQgPSBNYXRoLm1pbihzdGFydC5sZWZ0LCBlbmQubGVmdClcbiAgY29uc3QgcmlnaHQgPSBNYXRoLm1heChzdGFydC5yaWdodCwgZW5kLnJpZ2h0KVxuICBjb25zdCB3aWR0aCA9IHJpZ2h0IC0gbGVmdFxuICBjb25zdCBoZWlnaHQgPSBib3R0b20gLSB0b3BcbiAgY29uc3QgeCA9IGxlZnRcbiAgY29uc3QgeSA9IHRvcFxuICBjb25zdCBkYXRhID0ge1xuICAgIHRvcCxcbiAgICBib3R0b20sXG4gICAgbGVmdCxcbiAgICByaWdodCxcbiAgICB3aWR0aCxcbiAgICBoZWlnaHQsXG4gICAgeCxcbiAgICB5LFxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5kYXRhLFxuICAgIHRvSlNPTjogKCkgPT4gZGF0YSxcbiAgfVxufVxuIiwgImltcG9ydCB0eXBlIHsgU2NoZW1hIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuaW1wb3J0IHR5cGUgeyBKU09OQ29udGVudCB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG50eXBlIFJld3JpdGVVbmtub3duQ29udGVudE9wdGlvbnMgPSB7XG4gIC8qKlxuICAgKiBJZiB0cnVlLCB1bmtub3duIG5vZGVzIHdpbGwgYmUgdHJlYXRlZCBhcyBwYXJhZ3JhcGhzXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIGZhbGxiYWNrVG9QYXJhZ3JhcGg/OiBib29sZWFuO1xufTtcblxudHlwZSBSZXdyaXR0ZW5Db250ZW50ID0ge1xuICAvKipcbiAgICogVGhlIG9yaWdpbmFsIEpTT04gY29udGVudCB0aGF0IHdhcyByZXdyaXR0ZW5cbiAgICovXG4gIG9yaWdpbmFsOiBKU09OQ29udGVudDtcbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBub2RlIG9yIG1hcmsgdGhhdCB3YXMgdW5zdXBwb3J0ZWRcbiAgICovXG4gIHVuc3VwcG9ydGVkOiBzdHJpbmc7XG59W107XG5cbi8qKlxuICogVGhlIGFjdHVhbCBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgcmV3cml0ZVVua25vd25Db250ZW50IGZ1bmN0aW9uXG4gKi9cbmZ1bmN0aW9uIHJld3JpdGVVbmtub3duQ29udGVudElubmVyKHtcbiAganNvbixcbiAgdmFsaWRNYXJrcyxcbiAgdmFsaWROb2RlcyxcbiAgb3B0aW9ucyxcbiAgcmV3cml0dGVuQ29udGVudCA9IFtdLFxufToge1xuICBqc29uOiBKU09OQ29udGVudDtcbiAgdmFsaWRNYXJrczogU2V0PHN0cmluZz47XG4gIHZhbGlkTm9kZXM6IFNldDxzdHJpbmc+O1xuICBvcHRpb25zPzogUmV3cml0ZVVua25vd25Db250ZW50T3B0aW9ucztcbiAgcmV3cml0dGVuQ29udGVudD86IFJld3JpdHRlbkNvbnRlbnQ7XG59KToge1xuICAvKipcbiAgICogVGhlIGNsZWFuZWQgSlNPTiBjb250ZW50XG4gICAqL1xuICBqc29uOiBKU09OQ29udGVudCB8IG51bGw7XG4gIC8qKlxuICAgKiBUaGUgYXJyYXkgb2Ygbm9kZXMgYW5kIG1hcmtzIHRoYXQgd2VyZSByZXdyaXR0ZW5cbiAgICovXG4gIHJld3JpdHRlbkNvbnRlbnQ6IFJld3JpdHRlbkNvbnRlbnQ7XG59IHtcbiAgaWYgKGpzb24ubWFya3MgJiYgQXJyYXkuaXNBcnJheShqc29uLm1hcmtzKSkge1xuICAgIGpzb24ubWFya3MgPSBqc29uLm1hcmtzLmZpbHRlcihtYXJrID0+IHtcbiAgICAgIGNvbnN0IG5hbWUgPSB0eXBlb2YgbWFyayA9PT0gJ3N0cmluZycgPyBtYXJrIDogbWFyay50eXBlXG5cbiAgICAgIGlmICh2YWxpZE1hcmtzLmhhcyhuYW1lKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgfVxuXG4gICAgICByZXdyaXR0ZW5Db250ZW50LnB1c2goe1xuICAgICAgICBvcmlnaW5hbDogSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShtYXJrKSksXG4gICAgICAgIHVuc3VwcG9ydGVkOiBuYW1lLFxuICAgICAgfSlcbiAgICAgIC8vIEp1c3QgaWdub3JlIGFueSB1bmtub3duIG1hcmtzXG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9KVxuICB9XG5cbiAgaWYgKGpzb24uY29udGVudCAmJiBBcnJheS5pc0FycmF5KGpzb24uY29udGVudCkpIHtcbiAgICBqc29uLmNvbnRlbnQgPSBqc29uLmNvbnRlbnRcbiAgICAgIC5tYXAoXG4gICAgICAgIHZhbHVlID0+IHJld3JpdGVVbmtub3duQ29udGVudElubmVyKHtcbiAgICAgICAgICBqc29uOiB2YWx1ZSxcbiAgICAgICAgICB2YWxpZE1hcmtzLFxuICAgICAgICAgIHZhbGlkTm9kZXMsXG4gICAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgICByZXdyaXR0ZW5Db250ZW50LFxuICAgICAgICB9KS5qc29uLFxuICAgICAgKVxuICAgICAgLmZpbHRlcihhID0+IGEgIT09IG51bGwgJiYgYSAhPT0gdW5kZWZpbmVkKVxuICB9XG5cbiAgaWYgKGpzb24udHlwZSAmJiAhdmFsaWROb2Rlcy5oYXMoanNvbi50eXBlKSkge1xuICAgIHJld3JpdHRlbkNvbnRlbnQucHVzaCh7XG4gICAgICBvcmlnaW5hbDogSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShqc29uKSksXG4gICAgICB1bnN1cHBvcnRlZDoganNvbi50eXBlLFxuICAgIH0pXG5cbiAgICBpZiAoanNvbi5jb250ZW50ICYmIEFycmF5LmlzQXJyYXkoanNvbi5jb250ZW50KSAmJiAob3B0aW9ucz8uZmFsbGJhY2tUb1BhcmFncmFwaCAhPT0gZmFsc2UpKSB7XG4gICAgICAvLyBKdXN0IHRyZWF0IGl0IGxpa2UgYSBwYXJhZ3JhcGggYW5kIGhvcGUgZm9yIHRoZSBiZXN0XG4gICAgICBqc29uLnR5cGUgPSAncGFyYWdyYXBoJ1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBqc29uLFxuICAgICAgICByZXdyaXR0ZW5Db250ZW50LFxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIG9yIGp1c3Qgb21pdCBpdCBlbnRpcmVseVxuICAgIHJldHVybiB7XG4gICAgICBqc29uOiBudWxsLFxuICAgICAgcmV3cml0dGVuQ29udGVudCxcbiAgICB9XG4gIH1cblxuICByZXR1cm4geyBqc29uLCByZXdyaXR0ZW5Db250ZW50IH1cbn1cblxuLyoqXG4gKiBSZXdyaXRlIHVua25vd24gbm9kZXMgYW5kIG1hcmtzIHdpdGhpbiBKU09OIGNvbnRlbnRcbiAqIEFsbG93aW5nIGZvciB1c2VyIHdpdGhpbiB0aGUgZWRpdG9yXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXdyaXRlVW5rbm93bkNvbnRlbnQoXG4gIC8qKlxuICAgKiBUaGUgSlNPTiBjb250ZW50IHRvIGNsZWFuIG9mIHVua25vd24gbm9kZXMgYW5kIG1hcmtzXG4gICAqL1xuICBqc29uOiBKU09OQ29udGVudCxcbiAgLyoqXG4gICAqIFRoZSBzY2hlbWEgdG8gdXNlIGZvciB2YWxpZGF0aW9uXG4gICAqL1xuICBzY2hlbWE6IFNjaGVtYSxcbiAgLyoqXG4gICAqIE9wdGlvbnMgZm9yIHRoZSBjbGVhbmluZyBwcm9jZXNzXG4gICAqL1xuICBvcHRpb25zPzogUmV3cml0ZVVua25vd25Db250ZW50T3B0aW9ucyxcbik6IHtcbiAgLyoqXG4gICAqIFRoZSBjbGVhbmVkIEpTT04gY29udGVudFxuICAgKi9cbiAganNvbjogSlNPTkNvbnRlbnQgfCBudWxsO1xuICAvKipcbiAgICogVGhlIGFycmF5IG9mIG5vZGVzIGFuZCBtYXJrcyB0aGF0IHdlcmUgcmV3cml0dGVuXG4gICAqL1xuICByZXdyaXR0ZW5Db250ZW50OiB7XG4gICAgLyoqXG4gICAgICogVGhlIG9yaWdpbmFsIEpTT04gY29udGVudCB0aGF0IHdhcyByZXdyaXR0ZW5cbiAgICAgKi9cbiAgICBvcmlnaW5hbDogSlNPTkNvbnRlbnQ7XG4gICAgLyoqXG4gICAgICogVGhlIG5hbWUgb2YgdGhlIG5vZGUgb3IgbWFyayB0aGF0IHdhcyB1bnN1cHBvcnRlZFxuICAgICAqL1xuICAgIHVuc3VwcG9ydGVkOiBzdHJpbmc7XG4gIH1bXTtcbn0ge1xuICByZXR1cm4gcmV3cml0ZVVua25vd25Db250ZW50SW5uZXIoe1xuICAgIGpzb24sXG4gICAgdmFsaWROb2RlczogbmV3IFNldChPYmplY3Qua2V5cyhzY2hlbWEubm9kZXMpKSxcbiAgICB2YWxpZE1hcmtzOiBuZXcgU2V0KE9iamVjdC5rZXlzKHNjaGVtYS5tYXJrcykpLFxuICAgIG9wdGlvbnMsXG4gIH0pXG59XG4iLCAiaW1wb3J0IHsgTWFya1R5cGUsIFJlc29sdmVkUG9zIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcbmltcG9ydCB7IEVkaXRvclN0YXRlLCBUcmFuc2FjdGlvbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmltcG9ydCB7IGdldE1hcmtBdHRyaWJ1dGVzIH0gZnJvbSAnLi4vaGVscGVycy9nZXRNYXJrQXR0cmlidXRlcy5qcydcbmltcG9ydCB7IGdldE1hcmtUeXBlIH0gZnJvbSAnLi4vaGVscGVycy9nZXRNYXJrVHlwZS5qcydcbmltcG9ydCB7IGlzVGV4dFNlbGVjdGlvbiB9IGZyb20gJy4uL2hlbHBlcnMvaW5kZXguanMnXG5pbXBvcnQgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgc2V0TWFyazoge1xuICAgICAgLyoqXG4gICAgICAgKiBBZGQgYSBtYXJrIHdpdGggbmV3IGF0dHJpYnV0ZXMuXG4gICAgICAgKiBAcGFyYW0gdHlwZU9yTmFtZSBUaGUgbWFyayB0eXBlIG9yIG5hbWUuXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuc2V0TWFyaygnYm9sZCcsIHsgbGV2ZWw6IDEgfSlcbiAgICAgICAqL1xuICAgICAgc2V0TWFyazogKHR5cGVPck5hbWU6IHN0cmluZyB8IE1hcmtUeXBlLCBhdHRyaWJ1dGVzPzogUmVjb3JkPHN0cmluZywgYW55PikgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjYW5TZXRNYXJrKHN0YXRlOiBFZGl0b3JTdGF0ZSwgdHI6IFRyYW5zYWN0aW9uLCBuZXdNYXJrVHlwZTogTWFya1R5cGUpIHtcbiAgY29uc3QgeyBzZWxlY3Rpb24gfSA9IHRyXG4gIGxldCBjdXJzb3I6IFJlc29sdmVkUG9zIHwgbnVsbCA9IG51bGxcblxuICBpZiAoaXNUZXh0U2VsZWN0aW9uKHNlbGVjdGlvbikpIHtcbiAgICBjdXJzb3IgPSBzZWxlY3Rpb24uJGN1cnNvclxuICB9XG5cbiAgaWYgKGN1cnNvcikge1xuICAgIGNvbnN0IGN1cnJlbnRNYXJrcyA9IHN0YXRlLnN0b3JlZE1hcmtzID8/IGN1cnNvci5tYXJrcygpXG5cbiAgICAvLyBUaGVyZSBjYW4gYmUgbm8gY3VycmVudCBtYXJrcyB0aGF0IGV4Y2x1ZGUgdGhlIG5ldyBtYXJrXG4gICAgcmV0dXJuIChcbiAgICAgICEhbmV3TWFya1R5cGUuaXNJblNldChjdXJyZW50TWFya3MpXG4gICAgICB8fCAhY3VycmVudE1hcmtzLnNvbWUobWFyayA9PiBtYXJrLnR5cGUuZXhjbHVkZXMobmV3TWFya1R5cGUpKVxuICAgIClcbiAgfVxuXG4gIGNvbnN0IHsgcmFuZ2VzIH0gPSBzZWxlY3Rpb25cblxuICByZXR1cm4gcmFuZ2VzLnNvbWUoKHsgJGZyb20sICR0byB9KSA9PiB7XG4gICAgbGV0IHNvbWVOb2RlU3VwcG9ydHNNYXJrID0gJGZyb20uZGVwdGggPT09IDBcbiAgICAgID8gc3RhdGUuZG9jLmlubGluZUNvbnRlbnQgJiYgc3RhdGUuZG9jLnR5cGUuYWxsb3dzTWFya1R5cGUobmV3TWFya1R5cGUpXG4gICAgICA6IGZhbHNlXG5cbiAgICBzdGF0ZS5kb2Mubm9kZXNCZXR3ZWVuKCRmcm9tLnBvcywgJHRvLnBvcywgKG5vZGUsIF9wb3MsIHBhcmVudCkgPT4ge1xuICAgICAgLy8gSWYgd2UgYWxyZWFkeSBmb3VuZCBhIG1hcmsgdGhhdCB3ZSBjYW4gZW5hYmxlLCByZXR1cm4gZmFsc2UgdG8gYnlwYXNzIHRoZSByZW1haW5pbmcgc2VhcmNoXG4gICAgICBpZiAoc29tZU5vZGVTdXBwb3J0c01hcmspIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9XG5cbiAgICAgIGlmIChub2RlLmlzSW5saW5lKSB7XG4gICAgICAgIGNvbnN0IHBhcmVudEFsbG93c01hcmtUeXBlID0gIXBhcmVudCB8fCBwYXJlbnQudHlwZS5hbGxvd3NNYXJrVHlwZShuZXdNYXJrVHlwZSlcbiAgICAgICAgY29uc3QgY3VycmVudE1hcmtzQWxsb3dNYXJrVHlwZSA9ICEhbmV3TWFya1R5cGUuaXNJblNldChub2RlLm1hcmtzKVxuICAgICAgICAgIHx8ICFub2RlLm1hcmtzLnNvbWUob3RoZXJNYXJrID0+IG90aGVyTWFyay50eXBlLmV4Y2x1ZGVzKG5ld01hcmtUeXBlKSlcblxuICAgICAgICBzb21lTm9kZVN1cHBvcnRzTWFyayA9IHBhcmVudEFsbG93c01hcmtUeXBlICYmIGN1cnJlbnRNYXJrc0FsbG93TWFya1R5cGVcbiAgICAgIH1cbiAgICAgIHJldHVybiAhc29tZU5vZGVTdXBwb3J0c01hcmtcbiAgICB9KVxuXG4gICAgcmV0dXJuIHNvbWVOb2RlU3VwcG9ydHNNYXJrXG4gIH0pXG59XG5leHBvcnQgY29uc3Qgc2V0TWFyazogUmF3Q29tbWFuZHNbJ3NldE1hcmsnXSA9ICh0eXBlT3JOYW1lLCBhdHRyaWJ1dGVzID0ge30pID0+ICh7IHRyLCBzdGF0ZSwgZGlzcGF0Y2ggfSkgPT4ge1xuICBjb25zdCB7IHNlbGVjdGlvbiB9ID0gdHJcbiAgY29uc3QgeyBlbXB0eSwgcmFuZ2VzIH0gPSBzZWxlY3Rpb25cbiAgY29uc3QgdHlwZSA9IGdldE1hcmtUeXBlKHR5cGVPck5hbWUsIHN0YXRlLnNjaGVtYSlcblxuICBpZiAoZGlzcGF0Y2gpIHtcbiAgICBpZiAoZW1wdHkpIHtcbiAgICAgIGNvbnN0IG9sZEF0dHJpYnV0ZXMgPSBnZXRNYXJrQXR0cmlidXRlcyhzdGF0ZSwgdHlwZSlcblxuICAgICAgdHIuYWRkU3RvcmVkTWFyayhcbiAgICAgICAgdHlwZS5jcmVhdGUoe1xuICAgICAgICAgIC4uLm9sZEF0dHJpYnV0ZXMsXG4gICAgICAgICAgLi4uYXR0cmlidXRlcyxcbiAgICAgICAgfSksXG4gICAgICApXG4gICAgfSBlbHNlIHtcbiAgICAgIHJhbmdlcy5mb3JFYWNoKHJhbmdlID0+IHtcbiAgICAgICAgY29uc3QgZnJvbSA9IHJhbmdlLiRmcm9tLnBvc1xuICAgICAgICBjb25zdCB0byA9IHJhbmdlLiR0by5wb3NcblxuICAgICAgICBzdGF0ZS5kb2Mubm9kZXNCZXR3ZWVuKGZyb20sIHRvLCAobm9kZSwgcG9zKSA9PiB7XG4gICAgICAgICAgY29uc3QgdHJpbW1lZEZyb20gPSBNYXRoLm1heChwb3MsIGZyb20pXG4gICAgICAgICAgY29uc3QgdHJpbW1lZFRvID0gTWF0aC5taW4ocG9zICsgbm9kZS5ub2RlU2l6ZSwgdG8pXG4gICAgICAgICAgY29uc3Qgc29tZUhhc01hcmsgPSBub2RlLm1hcmtzLmZpbmQobWFyayA9PiBtYXJrLnR5cGUgPT09IHR5cGUpXG5cbiAgICAgICAgICAvLyBpZiB0aGVyZSBpcyBhbHJlYWR5IGEgbWFyayBvZiB0aGlzIHR5cGVcbiAgICAgICAgICAvLyB3ZSBrbm93IHRoYXQgd2UgaGF2ZSB0byBtZXJnZSBpdHMgYXR0cmlidXRlc1xuICAgICAgICAgIC8vIG90aGVyd2lzZSB3ZSBhZGQgYSBmcmVzaCBuZXcgbWFya1xuICAgICAgICAgIGlmIChzb21lSGFzTWFyaykge1xuICAgICAgICAgICAgbm9kZS5tYXJrcy5mb3JFYWNoKG1hcmsgPT4ge1xuICAgICAgICAgICAgICBpZiAodHlwZSA9PT0gbWFyay50eXBlKSB7XG4gICAgICAgICAgICAgICAgdHIuYWRkTWFyayhcbiAgICAgICAgICAgICAgICAgIHRyaW1tZWRGcm9tLFxuICAgICAgICAgICAgICAgICAgdHJpbW1lZFRvLFxuICAgICAgICAgICAgICAgICAgdHlwZS5jcmVhdGUoe1xuICAgICAgICAgICAgICAgICAgICAuLi5tYXJrLmF0dHJzLFxuICAgICAgICAgICAgICAgICAgICAuLi5hdHRyaWJ1dGVzLFxuICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0ci5hZGRNYXJrKHRyaW1tZWRGcm9tLCB0cmltbWVkVG8sIHR5cGUuY3JlYXRlKGF0dHJpYnV0ZXMpKVxuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGNhblNldE1hcmsoc3RhdGUsIHRyLCB0eXBlKVxufVxuIiwgImltcG9ydCB0eXBlIHsgUGx1Z2luLCBQbHVnaW5LZXkgfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5pbXBvcnQgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgc2V0TWV0YToge1xuICAgICAgLyoqXG4gICAgICAgKiBTdG9yZSBhIG1ldGFkYXRhIHByb3BlcnR5IGluIHRoZSBjdXJyZW50IHRyYW5zYWN0aW9uLlxuICAgICAgICogQHBhcmFtIGtleSBUaGUga2V5IG9mIHRoZSBtZXRhZGF0YSBwcm9wZXJ0eS5cbiAgICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gc3RvcmUuXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuc2V0TWV0YSgnZm9vJywgJ2JhcicpXG4gICAgICAgKi9cbiAgICAgIHNldE1ldGE6IChrZXk6IHN0cmluZyB8IFBsdWdpbiB8IFBsdWdpbktleSwgdmFsdWU6IGFueSkgPT4gUmV0dXJuVHlwZSxcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHNldE1ldGE6IFJhd0NvbW1hbmRzWydzZXRNZXRhJ10gPSAoa2V5LCB2YWx1ZSkgPT4gKHsgdHIgfSkgPT4ge1xuICB0ci5zZXRNZXRhKGtleSwgdmFsdWUpXG5cbiAgcmV0dXJuIHRydWVcbn1cbiIsICJpbXBvcnQgeyBzZXRCbG9ja1R5cGUgfSBmcm9tICdAdGlwdGFwL3BtL2NvbW1hbmRzJ1xuaW1wb3J0IHsgTm9kZVR5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgeyBnZXROb2RlVHlwZSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0Tm9kZVR5cGUuanMnXG5pbXBvcnQgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgc2V0Tm9kZToge1xuICAgICAgLyoqXG4gICAgICAgKiBSZXBsYWNlIGEgZ2l2ZW4gcmFuZ2Ugd2l0aCBhIG5vZGUuXG4gICAgICAgKiBAcGFyYW0gdHlwZU9yTmFtZSBUaGUgdHlwZSBvciBuYW1lIG9mIHRoZSBub2RlXG4gICAgICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgYXR0cmlidXRlcyBvZiB0aGUgbm9kZVxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnNldE5vZGUoJ3BhcmFncmFwaCcpXG4gICAgICAgKi9cbiAgICAgIHNldE5vZGU6ICh0eXBlT3JOYW1lOiBzdHJpbmcgfCBOb2RlVHlwZSwgYXR0cmlidXRlcz86IFJlY29yZDxzdHJpbmcsIGFueT4pID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHNldE5vZGU6IFJhd0NvbW1hbmRzWydzZXROb2RlJ10gPSAodHlwZU9yTmFtZSwgYXR0cmlidXRlcyA9IHt9KSA9PiAoeyBzdGF0ZSwgZGlzcGF0Y2gsIGNoYWluIH0pID0+IHtcbiAgY29uc3QgdHlwZSA9IGdldE5vZGVUeXBlKHR5cGVPck5hbWUsIHN0YXRlLnNjaGVtYSlcblxuICBsZXQgYXR0cmlidXRlc1RvQ29weTogUmVjb3JkPHN0cmluZywgYW55PiB8IHVuZGVmaW5lZFxuXG4gIGlmIChzdGF0ZS5zZWxlY3Rpb24uJGFuY2hvci5zYW1lUGFyZW50KHN0YXRlLnNlbGVjdGlvbi4kaGVhZCkpIHtcbiAgICAvLyBvbmx5IGNvcHkgYXR0cmlidXRlcyBpZiB0aGUgc2VsZWN0aW9uIGlzIHBvaW50aW5nIHRvIGEgbm9kZSBvZiB0aGUgc2FtZSB0eXBlXG4gICAgYXR0cmlidXRlc1RvQ29weSA9IHN0YXRlLnNlbGVjdGlvbi4kYW5jaG9yLnBhcmVudC5hdHRyc1xuICB9XG5cbiAgLy8gVE9ETzogdXNlIGEgZmFsbGJhY2sgbGlrZSBpbnNlcnRDb250ZW50P1xuICBpZiAoIXR5cGUuaXNUZXh0YmxvY2spIHtcbiAgICBjb25zb2xlLndhcm4oJ1t0aXB0YXAgd2Fybl06IEN1cnJlbnRseSBcInNldE5vZGUoKVwiIG9ubHkgc3VwcG9ydHMgdGV4dCBibG9jayBub2Rlcy4nKVxuXG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICByZXR1cm4gKFxuICAgIGNoYWluKClcbiAgICAvLyB0cnkgdG8gY29udmVydCBub2RlIHRvIGRlZmF1bHQgbm9kZSBpZiBuZWVkZWRcbiAgICAgIC5jb21tYW5kKCh7IGNvbW1hbmRzIH0pID0+IHtcbiAgICAgICAgY29uc3QgY2FuU2V0QmxvY2sgPSBzZXRCbG9ja1R5cGUodHlwZSwgeyAuLi5hdHRyaWJ1dGVzVG9Db3B5LCAuLi5hdHRyaWJ1dGVzIH0pKHN0YXRlKVxuXG4gICAgICAgIGlmIChjYW5TZXRCbG9jaykge1xuICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY29tbWFuZHMuY2xlYXJOb2RlcygpXG4gICAgICB9KVxuICAgICAgLmNvbW1hbmQoKHsgc3RhdGU6IHVwZGF0ZWRTdGF0ZSB9KSA9PiB7XG4gICAgICAgIHJldHVybiBzZXRCbG9ja1R5cGUodHlwZSwgeyAuLi5hdHRyaWJ1dGVzVG9Db3B5LCAuLi5hdHRyaWJ1dGVzIH0pKHVwZGF0ZWRTdGF0ZSwgZGlzcGF0Y2gpXG4gICAgICB9KVxuICAgICAgLnJ1bigpXG4gIClcbn1cbiIsICJpbXBvcnQgeyBOb2RlU2VsZWN0aW9uIH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcblxuaW1wb3J0IHsgUmF3Q29tbWFuZHMgfSBmcm9tICcuLi90eXBlcy5qcydcbmltcG9ydCB7IG1pbk1heCB9IGZyb20gJy4uL3V0aWxpdGllcy9taW5NYXguanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBzZXROb2RlU2VsZWN0aW9uOiB7XG4gICAgICAvKipcbiAgICAgICAqIENyZWF0ZXMgYSBOb2RlU2VsZWN0aW9uLlxuICAgICAgICogQHBhcmFtIHBvc2l0aW9uIC0gUG9zaXRpb24gb2YgdGhlIG5vZGUuXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuc2V0Tm9kZVNlbGVjdGlvbigxMClcbiAgICAgICAqL1xuICAgICAgc2V0Tm9kZVNlbGVjdGlvbjogKHBvc2l0aW9uOiBudW1iZXIpID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHNldE5vZGVTZWxlY3Rpb246IFJhd0NvbW1hbmRzWydzZXROb2RlU2VsZWN0aW9uJ10gPSBwb3NpdGlvbiA9PiAoeyB0ciwgZGlzcGF0Y2ggfSkgPT4ge1xuICBpZiAoZGlzcGF0Y2gpIHtcbiAgICBjb25zdCB7IGRvYyB9ID0gdHJcbiAgICBjb25zdCBmcm9tID0gbWluTWF4KHBvc2l0aW9uLCAwLCBkb2MuY29udGVudC5zaXplKVxuICAgIGNvbnN0IHNlbGVjdGlvbiA9IE5vZGVTZWxlY3Rpb24uY3JlYXRlKGRvYywgZnJvbSlcblxuICAgIHRyLnNldFNlbGVjdGlvbihzZWxlY3Rpb24pXG4gIH1cblxuICByZXR1cm4gdHJ1ZVxufVxuIiwgImltcG9ydCB7IFRleHRTZWxlY3Rpb24gfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5pbXBvcnQgeyBSYW5nZSwgUmF3Q29tbWFuZHMgfSBmcm9tICcuLi90eXBlcy5qcydcbmltcG9ydCB7IG1pbk1heCB9IGZyb20gJy4uL3V0aWxpdGllcy9taW5NYXguanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBzZXRUZXh0U2VsZWN0aW9uOiB7XG4gICAgICAvKipcbiAgICAgICAqIENyZWF0ZXMgYSBUZXh0U2VsZWN0aW9uLlxuICAgICAgICogQHBhcmFtIHBvc2l0aW9uIFRoZSBwb3NpdGlvbiBvZiB0aGUgc2VsZWN0aW9uLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnNldFRleHRTZWxlY3Rpb24oMTApXG4gICAgICAgKi9cbiAgICAgIHNldFRleHRTZWxlY3Rpb246IChwb3NpdGlvbjogbnVtYmVyIHwgUmFuZ2UpID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHNldFRleHRTZWxlY3Rpb246IFJhd0NvbW1hbmRzWydzZXRUZXh0U2VsZWN0aW9uJ10gPSBwb3NpdGlvbiA9PiAoeyB0ciwgZGlzcGF0Y2ggfSkgPT4ge1xuICBpZiAoZGlzcGF0Y2gpIHtcbiAgICBjb25zdCB7IGRvYyB9ID0gdHJcbiAgICBjb25zdCB7IGZyb20sIHRvIH0gPSB0eXBlb2YgcG9zaXRpb24gPT09ICdudW1iZXInID8geyBmcm9tOiBwb3NpdGlvbiwgdG86IHBvc2l0aW9uIH0gOiBwb3NpdGlvblxuICAgIGNvbnN0IG1pblBvcyA9IFRleHRTZWxlY3Rpb24uYXRTdGFydChkb2MpLmZyb21cbiAgICBjb25zdCBtYXhQb3MgPSBUZXh0U2VsZWN0aW9uLmF0RW5kKGRvYykudG9cbiAgICBjb25zdCByZXNvbHZlZEZyb20gPSBtaW5NYXgoZnJvbSwgbWluUG9zLCBtYXhQb3MpXG4gICAgY29uc3QgcmVzb2x2ZWRFbmQgPSBtaW5NYXgodG8sIG1pblBvcywgbWF4UG9zKVxuICAgIGNvbnN0IHNlbGVjdGlvbiA9IFRleHRTZWxlY3Rpb24uY3JlYXRlKGRvYywgcmVzb2x2ZWRGcm9tLCByZXNvbHZlZEVuZClcblxuICAgIHRyLnNldFNlbGVjdGlvbihzZWxlY3Rpb24pXG4gIH1cblxuICByZXR1cm4gdHJ1ZVxufVxuIiwgImltcG9ydCB7IE5vZGVUeXBlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcbmltcG9ydCB7IHNpbmtMaXN0SXRlbSBhcyBvcmlnaW5hbFNpbmtMaXN0SXRlbSB9IGZyb20gJ0B0aXB0YXAvcG0vc2NoZW1hLWxpc3QnXG5cbmltcG9ydCB7IGdldE5vZGVUeXBlIH0gZnJvbSAnLi4vaGVscGVycy9nZXROb2RlVHlwZS5qcydcbmltcG9ydCB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBzaW5rTGlzdEl0ZW06IHtcbiAgICAgIC8qKlxuICAgICAgICogU2luayB0aGUgbGlzdCBpdGVtIGRvd24gaW50byBhbiBpbm5lciBsaXN0LlxuICAgICAgICogQHBhcmFtIHR5cGVPck5hbWUgVGhlIHR5cGUgb3IgbmFtZSBvZiB0aGUgbm9kZS5cbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy5zaW5rTGlzdEl0ZW0oJ2xpc3RJdGVtJylcbiAgICAgICAqL1xuICAgICAgc2lua0xpc3RJdGVtOiAodHlwZU9yTmFtZTogc3RyaW5nIHwgTm9kZVR5cGUpID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHNpbmtMaXN0SXRlbTogUmF3Q29tbWFuZHNbJ3NpbmtMaXN0SXRlbSddID0gdHlwZU9yTmFtZSA9PiAoeyBzdGF0ZSwgZGlzcGF0Y2ggfSkgPT4ge1xuICBjb25zdCB0eXBlID0gZ2V0Tm9kZVR5cGUodHlwZU9yTmFtZSwgc3RhdGUuc2NoZW1hKVxuXG4gIHJldHVybiBvcmlnaW5hbFNpbmtMaXN0SXRlbSh0eXBlKShzdGF0ZSwgZGlzcGF0Y2gpXG59XG4iLCAiaW1wb3J0IHsgRWRpdG9yU3RhdGUsIE5vZGVTZWxlY3Rpb24sIFRleHRTZWxlY3Rpb24gfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuaW1wb3J0IHsgY2FuU3BsaXQgfSBmcm9tICdAdGlwdGFwL3BtL3RyYW5zZm9ybSdcblxuaW1wb3J0IHsgZGVmYXVsdEJsb2NrQXQgfSBmcm9tICcuLi9oZWxwZXJzL2RlZmF1bHRCbG9ja0F0LmpzJ1xuaW1wb3J0IHsgZ2V0U3BsaXR0ZWRBdHRyaWJ1dGVzIH0gZnJvbSAnLi4vaGVscGVycy9nZXRTcGxpdHRlZEF0dHJpYnV0ZXMuanMnXG5pbXBvcnQgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5mdW5jdGlvbiBlbnN1cmVNYXJrcyhzdGF0ZTogRWRpdG9yU3RhdGUsIHNwbGl0dGFibGVNYXJrcz86IHN0cmluZ1tdKSB7XG4gIGNvbnN0IG1hcmtzID0gc3RhdGUuc3RvcmVkTWFya3MgfHwgKHN0YXRlLnNlbGVjdGlvbi4kdG8ucGFyZW50T2Zmc2V0ICYmIHN0YXRlLnNlbGVjdGlvbi4kZnJvbS5tYXJrcygpKVxuXG4gIGlmIChtYXJrcykge1xuICAgIGNvbnN0IGZpbHRlcmVkTWFya3MgPSBtYXJrcy5maWx0ZXIobWFyayA9PiBzcGxpdHRhYmxlTWFya3M/LmluY2x1ZGVzKG1hcmsudHlwZS5uYW1lKSlcblxuICAgIHN0YXRlLnRyLmVuc3VyZU1hcmtzKGZpbHRlcmVkTWFya3MpXG4gIH1cbn1cblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIHNwbGl0QmxvY2s6IHtcbiAgICAgIC8qKlxuICAgICAgICogRm9ya3MgYSBuZXcgbm9kZSBmcm9tIGFuIGV4aXN0aW5nIG5vZGUuXG4gICAgICAgKiBAcGFyYW0gb3B0aW9ucy5rZWVwTWFya3MgS2VlcCBtYXJrcyBmcm9tIHRoZSBwcmV2aW91cyBub2RlLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnNwbGl0QmxvY2soKVxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnNwbGl0QmxvY2soeyBrZWVwTWFya3M6IHRydWUgfSlcbiAgICAgICAqL1xuICAgICAgc3BsaXRCbG9jazogKG9wdGlvbnM/OiB7IGtlZXBNYXJrcz86IGJvb2xlYW4gfSkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3Qgc3BsaXRCbG9jazogUmF3Q29tbWFuZHNbJ3NwbGl0QmxvY2snXSA9ICh7IGtlZXBNYXJrcyA9IHRydWUgfSA9IHt9KSA9PiAoe1xuICB0ciwgc3RhdGUsIGRpc3BhdGNoLCBlZGl0b3IsXG59KSA9PiB7XG4gIGNvbnN0IHsgc2VsZWN0aW9uLCBkb2MgfSA9IHRyXG4gIGNvbnN0IHsgJGZyb20sICR0byB9ID0gc2VsZWN0aW9uXG4gIGNvbnN0IGV4dGVuc2lvbkF0dHJpYnV0ZXMgPSBlZGl0b3IuZXh0ZW5zaW9uTWFuYWdlci5hdHRyaWJ1dGVzXG4gIGNvbnN0IG5ld0F0dHJpYnV0ZXMgPSBnZXRTcGxpdHRlZEF0dHJpYnV0ZXMoXG4gICAgZXh0ZW5zaW9uQXR0cmlidXRlcyxcbiAgICAkZnJvbS5ub2RlKCkudHlwZS5uYW1lLFxuICAgICRmcm9tLm5vZGUoKS5hdHRycyxcbiAgKVxuXG4gIGlmIChzZWxlY3Rpb24gaW5zdGFuY2VvZiBOb2RlU2VsZWN0aW9uICYmIHNlbGVjdGlvbi5ub2RlLmlzQmxvY2spIHtcbiAgICBpZiAoISRmcm9tLnBhcmVudE9mZnNldCB8fCAhY2FuU3BsaXQoZG9jLCAkZnJvbS5wb3MpKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICBpZiAoZGlzcGF0Y2gpIHtcbiAgICAgIGlmIChrZWVwTWFya3MpIHtcbiAgICAgICAgZW5zdXJlTWFya3Moc3RhdGUsIGVkaXRvci5leHRlbnNpb25NYW5hZ2VyLnNwbGl0dGFibGVNYXJrcylcbiAgICAgIH1cblxuICAgICAgdHIuc3BsaXQoJGZyb20ucG9zKS5zY3JvbGxJbnRvVmlldygpXG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIGlmICghJGZyb20ucGFyZW50LmlzQmxvY2spIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIGNvbnN0IGF0RW5kID0gJHRvLnBhcmVudE9mZnNldCA9PT0gJHRvLnBhcmVudC5jb250ZW50LnNpemVcblxuICBjb25zdCBkZWZsdCA9ICRmcm9tLmRlcHRoID09PSAwXG4gICAgPyB1bmRlZmluZWRcbiAgICA6IGRlZmF1bHRCbG9ja0F0KCRmcm9tLm5vZGUoLTEpLmNvbnRlbnRNYXRjaEF0KCRmcm9tLmluZGV4QWZ0ZXIoLTEpKSlcblxuICBsZXQgdHlwZXMgPSBhdEVuZCAmJiBkZWZsdFxuICAgID8gW1xuICAgICAge1xuICAgICAgICB0eXBlOiBkZWZsdCxcbiAgICAgICAgYXR0cnM6IG5ld0F0dHJpYnV0ZXMsXG4gICAgICB9LFxuICAgIF1cbiAgICA6IHVuZGVmaW5lZFxuXG4gIGxldCBjYW4gPSBjYW5TcGxpdCh0ci5kb2MsIHRyLm1hcHBpbmcubWFwKCRmcm9tLnBvcyksIDEsIHR5cGVzKVxuXG4gIGlmIChcbiAgICAhdHlwZXNcbiAgICAgICYmICFjYW5cbiAgICAgICYmIGNhblNwbGl0KHRyLmRvYywgdHIubWFwcGluZy5tYXAoJGZyb20ucG9zKSwgMSwgZGVmbHQgPyBbeyB0eXBlOiBkZWZsdCB9XSA6IHVuZGVmaW5lZClcbiAgKSB7XG4gICAgY2FuID0gdHJ1ZVxuICAgIHR5cGVzID0gZGVmbHRcbiAgICAgID8gW1xuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogZGVmbHQsXG4gICAgICAgICAgYXR0cnM6IG5ld0F0dHJpYnV0ZXMsXG4gICAgICAgIH0sXG4gICAgICBdXG4gICAgICA6IHVuZGVmaW5lZFxuICB9XG5cbiAgaWYgKGRpc3BhdGNoKSB7XG4gICAgaWYgKGNhbikge1xuICAgICAgaWYgKHNlbGVjdGlvbiBpbnN0YW5jZW9mIFRleHRTZWxlY3Rpb24pIHtcbiAgICAgICAgdHIuZGVsZXRlU2VsZWN0aW9uKClcbiAgICAgIH1cblxuICAgICAgdHIuc3BsaXQodHIubWFwcGluZy5tYXAoJGZyb20ucG9zKSwgMSwgdHlwZXMpXG5cbiAgICAgIGlmIChkZWZsdCAmJiAhYXRFbmQgJiYgISRmcm9tLnBhcmVudE9mZnNldCAmJiAkZnJvbS5wYXJlbnQudHlwZSAhPT0gZGVmbHQpIHtcbiAgICAgICAgY29uc3QgZmlyc3QgPSB0ci5tYXBwaW5nLm1hcCgkZnJvbS5iZWZvcmUoKSlcbiAgICAgICAgY29uc3QgJGZpcnN0ID0gdHIuZG9jLnJlc29sdmUoZmlyc3QpXG5cbiAgICAgICAgaWYgKCRmcm9tLm5vZGUoLTEpLmNhblJlcGxhY2VXaXRoKCRmaXJzdC5pbmRleCgpLCAkZmlyc3QuaW5kZXgoKSArIDEsIGRlZmx0KSkge1xuICAgICAgICAgIHRyLnNldE5vZGVNYXJrdXAodHIubWFwcGluZy5tYXAoJGZyb20uYmVmb3JlKCkpLCBkZWZsdClcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChrZWVwTWFya3MpIHtcbiAgICAgIGVuc3VyZU1hcmtzKHN0YXRlLCBlZGl0b3IuZXh0ZW5zaW9uTWFuYWdlci5zcGxpdHRhYmxlTWFya3MpXG4gICAgfVxuXG4gICAgdHIuc2Nyb2xsSW50b1ZpZXcoKVxuICB9XG5cbiAgcmV0dXJuIGNhblxufVxuIiwgImltcG9ydCB7XG4gIEZyYWdtZW50LCBOb2RlIGFzIFByb3NlTWlycm9yTm9kZSwgTm9kZVR5cGUsIFNsaWNlLFxufSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuaW1wb3J0IHsgVGV4dFNlbGVjdGlvbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5pbXBvcnQgeyBjYW5TcGxpdCB9IGZyb20gJ0B0aXB0YXAvcG0vdHJhbnNmb3JtJ1xuXG5pbXBvcnQgeyBnZXROb2RlVHlwZSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0Tm9kZVR5cGUuanMnXG5pbXBvcnQgeyBnZXRTcGxpdHRlZEF0dHJpYnV0ZXMgfSBmcm9tICcuLi9oZWxwZXJzL2dldFNwbGl0dGVkQXR0cmlidXRlcy5qcydcbmltcG9ydCB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBzcGxpdExpc3RJdGVtOiB7XG4gICAgICAvKipcbiAgICAgICAqIFNwbGl0cyBvbmUgbGlzdCBpdGVtIGludG8gdHdvIGxpc3QgaXRlbXMuXG4gICAgICAgKiBAcGFyYW0gdHlwZU9yTmFtZSBUaGUgdHlwZSBvciBuYW1lIG9mIHRoZSBub2RlLlxuICAgICAgICogQHBhcmFtIG92ZXJyaWRlQXR0cnMgVGhlIGF0dHJpYnV0ZXMgdG8gZW5zdXJlIG9uIHRoZSBuZXcgbm9kZS5cbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy5zcGxpdExpc3RJdGVtKCdsaXN0SXRlbScpXG4gICAgICAgKi9cbiAgICAgIHNwbGl0TGlzdEl0ZW06ICh0eXBlT3JOYW1lOiBzdHJpbmcgfCBOb2RlVHlwZSwgb3ZlcnJpZGVBdHRycz86IFJlY29yZDxzdHJpbmcsIGFueT4pID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHNwbGl0TGlzdEl0ZW06IFJhd0NvbW1hbmRzWydzcGxpdExpc3RJdGVtJ10gPSAodHlwZU9yTmFtZSwgb3ZlcnJpZGVBdHRycyA9IHt9KSA9PiAoe1xuICB0ciwgc3RhdGUsIGRpc3BhdGNoLCBlZGl0b3IsXG59KSA9PiB7XG4gIGNvbnN0IHR5cGUgPSBnZXROb2RlVHlwZSh0eXBlT3JOYW1lLCBzdGF0ZS5zY2hlbWEpXG4gIGNvbnN0IHsgJGZyb20sICR0byB9ID0gc3RhdGUuc2VsZWN0aW9uXG5cbiAgLy8gQHRzLWlnbm9yZVxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgICBjb25zdCBub2RlOiBQcm9zZU1pcnJvck5vZGUgPSBzdGF0ZS5zZWxlY3Rpb24ubm9kZVxuXG4gIGlmICgobm9kZSAmJiBub2RlLmlzQmxvY2spIHx8ICRmcm9tLmRlcHRoIDwgMiB8fCAhJGZyb20uc2FtZVBhcmVudCgkdG8pKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBjb25zdCBncmFuZFBhcmVudCA9ICRmcm9tLm5vZGUoLTEpXG5cbiAgaWYgKGdyYW5kUGFyZW50LnR5cGUgIT09IHR5cGUpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIGNvbnN0IGV4dGVuc2lvbkF0dHJpYnV0ZXMgPSBlZGl0b3IuZXh0ZW5zaW9uTWFuYWdlci5hdHRyaWJ1dGVzXG5cbiAgaWYgKCRmcm9tLnBhcmVudC5jb250ZW50LnNpemUgPT09IDAgJiYgJGZyb20ubm9kZSgtMSkuY2hpbGRDb3VudCA9PT0gJGZyb20uaW5kZXhBZnRlcigtMSkpIHtcbiAgICAvLyBJbiBhbiBlbXB0eSBibG9jay4gSWYgdGhpcyBpcyBhIG5lc3RlZCBsaXN0LCB0aGUgd3JhcHBpbmdcbiAgICAvLyBsaXN0IGl0ZW0gc2hvdWxkIGJlIHNwbGl0LiBPdGhlcndpc2UsIGJhaWwgb3V0IGFuZCBsZXQgbmV4dFxuICAgIC8vIGNvbW1hbmQgaGFuZGxlIGxpZnRpbmcuXG4gICAgaWYgKFxuICAgICAgJGZyb20uZGVwdGggPT09IDJcbiAgICAgICAgfHwgJGZyb20ubm9kZSgtMykudHlwZSAhPT0gdHlwZVxuICAgICAgICB8fCAkZnJvbS5pbmRleCgtMikgIT09ICRmcm9tLm5vZGUoLTIpLmNoaWxkQ291bnQgLSAxXG4gICAgKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICBpZiAoZGlzcGF0Y2gpIHtcbiAgICAgIGxldCB3cmFwID0gRnJhZ21lbnQuZW1wdHlcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgICAgICBjb25zdCBkZXB0aEJlZm9yZSA9ICRmcm9tLmluZGV4KC0xKSA/IDEgOiAkZnJvbS5pbmRleCgtMikgPyAyIDogM1xuXG4gICAgICAvLyBCdWlsZCBhIGZyYWdtZW50IGNvbnRhaW5pbmcgZW1wdHkgdmVyc2lvbnMgb2YgdGhlIHN0cnVjdHVyZVxuICAgICAgLy8gZnJvbSB0aGUgb3V0ZXIgbGlzdCBpdGVtIHRvIHRoZSBwYXJlbnQgbm9kZSBvZiB0aGUgY3Vyc29yXG4gICAgICBmb3IgKGxldCBkID0gJGZyb20uZGVwdGggLSBkZXB0aEJlZm9yZTsgZCA+PSAkZnJvbS5kZXB0aCAtIDM7IGQgLT0gMSkge1xuICAgICAgICB3cmFwID0gRnJhZ21lbnQuZnJvbSgkZnJvbS5ub2RlKGQpLmNvcHkod3JhcCkpXG4gICAgICB9XG5cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgICAgICBjb25zdCBkZXB0aEFmdGVyID0gJGZyb20uaW5kZXhBZnRlcigtMSkgPCAkZnJvbS5ub2RlKC0yKS5jaGlsZENvdW50ID8gMSA6ICRmcm9tLmluZGV4QWZ0ZXIoLTIpIDwgJGZyb20ubm9kZSgtMykuY2hpbGRDb3VudCA/IDIgOiAzXG5cbiAgICAgIC8vIEFkZCBhIHNlY29uZCBsaXN0IGl0ZW0gd2l0aCBhbiBlbXB0eSBkZWZhdWx0IHN0YXJ0IG5vZGVcbiAgICAgIGNvbnN0IG5ld05leHRUeXBlQXR0cmlidXRlcyA9IHtcbiAgICAgICAgLi4uZ2V0U3BsaXR0ZWRBdHRyaWJ1dGVzKFxuICAgICAgICAgIGV4dGVuc2lvbkF0dHJpYnV0ZXMsXG4gICAgICAgICAgJGZyb20ubm9kZSgpLnR5cGUubmFtZSxcbiAgICAgICAgICAkZnJvbS5ub2RlKCkuYXR0cnMsXG4gICAgICAgICksXG4gICAgICAgIC4uLm92ZXJyaWRlQXR0cnMsXG4gICAgICB9XG4gICAgICBjb25zdCBuZXh0VHlwZSA9IHR5cGUuY29udGVudE1hdGNoLmRlZmF1bHRUeXBlPy5jcmVhdGVBbmRGaWxsKG5ld05leHRUeXBlQXR0cmlidXRlcykgfHwgdW5kZWZpbmVkXG5cbiAgICAgIHdyYXAgPSB3cmFwLmFwcGVuZChGcmFnbWVudC5mcm9tKHR5cGUuY3JlYXRlQW5kRmlsbChudWxsLCBuZXh0VHlwZSkgfHwgdW5kZWZpbmVkKSlcblxuICAgICAgY29uc3Qgc3RhcnQgPSAkZnJvbS5iZWZvcmUoJGZyb20uZGVwdGggLSAoZGVwdGhCZWZvcmUgLSAxKSlcblxuICAgICAgdHIucmVwbGFjZShzdGFydCwgJGZyb20uYWZ0ZXIoLWRlcHRoQWZ0ZXIpLCBuZXcgU2xpY2Uod3JhcCwgNCAtIGRlcHRoQmVmb3JlLCAwKSlcblxuICAgICAgbGV0IHNlbCA9IC0xXG5cbiAgICAgIHRyLmRvYy5ub2Rlc0JldHdlZW4oc3RhcnQsIHRyLmRvYy5jb250ZW50LnNpemUsIChuLCBwb3MpID0+IHtcbiAgICAgICAgaWYgKHNlbCA+IC0xKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cblxuICAgICAgICBpZiAobi5pc1RleHRibG9jayAmJiBuLmNvbnRlbnQuc2l6ZSA9PT0gMCkge1xuICAgICAgICAgIHNlbCA9IHBvcyArIDFcbiAgICAgICAgfVxuICAgICAgfSlcblxuICAgICAgaWYgKHNlbCA+IC0xKSB7XG4gICAgICAgIHRyLnNldFNlbGVjdGlvbihUZXh0U2VsZWN0aW9uLm5lYXIodHIuZG9jLnJlc29sdmUoc2VsKSkpXG4gICAgICB9XG5cbiAgICAgIHRyLnNjcm9sbEludG9WaWV3KClcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgY29uc3QgbmV4dFR5cGUgPSAkdG8ucG9zID09PSAkZnJvbS5lbmQoKSA/IGdyYW5kUGFyZW50LmNvbnRlbnRNYXRjaEF0KDApLmRlZmF1bHRUeXBlIDogbnVsbFxuXG4gIGNvbnN0IG5ld1R5cGVBdHRyaWJ1dGVzID0ge1xuICAgIC4uLmdldFNwbGl0dGVkQXR0cmlidXRlcyhcbiAgICAgIGV4dGVuc2lvbkF0dHJpYnV0ZXMsXG4gICAgICBncmFuZFBhcmVudC50eXBlLm5hbWUsXG4gICAgICBncmFuZFBhcmVudC5hdHRycyxcbiAgICApLFxuICAgIC4uLm92ZXJyaWRlQXR0cnMsXG4gIH1cbiAgY29uc3QgbmV3TmV4dFR5cGVBdHRyaWJ1dGVzID0ge1xuICAgIC4uLmdldFNwbGl0dGVkQXR0cmlidXRlcyhcbiAgICAgIGV4dGVuc2lvbkF0dHJpYnV0ZXMsXG4gICAgICAkZnJvbS5ub2RlKCkudHlwZS5uYW1lLFxuICAgICAgJGZyb20ubm9kZSgpLmF0dHJzLFxuICAgICksXG4gICAgLi4ub3ZlcnJpZGVBdHRycyxcbiAgfVxuXG4gIHRyLmRlbGV0ZSgkZnJvbS5wb3MsICR0by5wb3MpXG5cbiAgY29uc3QgdHlwZXMgPSBuZXh0VHlwZVxuICAgID8gW1xuICAgICAgeyB0eXBlLCBhdHRyczogbmV3VHlwZUF0dHJpYnV0ZXMgfSxcbiAgICAgIHsgdHlwZTogbmV4dFR5cGUsIGF0dHJzOiBuZXdOZXh0VHlwZUF0dHJpYnV0ZXMgfSxcbiAgICBdXG4gICAgOiBbeyB0eXBlLCBhdHRyczogbmV3VHlwZUF0dHJpYnV0ZXMgfV1cblxuICBpZiAoIWNhblNwbGl0KHRyLmRvYywgJGZyb20ucG9zLCAyKSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgaWYgKGRpc3BhdGNoKSB7XG4gICAgY29uc3QgeyBzZWxlY3Rpb24sIHN0b3JlZE1hcmtzIH0gPSBzdGF0ZVxuICAgIGNvbnN0IHsgc3BsaXR0YWJsZU1hcmtzIH0gPSBlZGl0b3IuZXh0ZW5zaW9uTWFuYWdlclxuICAgIGNvbnN0IG1hcmtzID0gc3RvcmVkTWFya3MgfHwgKHNlbGVjdGlvbi4kdG8ucGFyZW50T2Zmc2V0ICYmIHNlbGVjdGlvbi4kZnJvbS5tYXJrcygpKVxuXG4gICAgdHIuc3BsaXQoJGZyb20ucG9zLCAyLCB0eXBlcykuc2Nyb2xsSW50b1ZpZXcoKVxuXG4gICAgaWYgKCFtYXJrcyB8fCAhZGlzcGF0Y2gpIHtcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgY29uc3QgZmlsdGVyZWRNYXJrcyA9IG1hcmtzLmZpbHRlcihtYXJrID0+IHNwbGl0dGFibGVNYXJrcy5pbmNsdWRlcyhtYXJrLnR5cGUubmFtZSkpXG5cbiAgICB0ci5lbnN1cmVNYXJrcyhmaWx0ZXJlZE1hcmtzKVxuICB9XG5cbiAgcmV0dXJuIHRydWVcbn1cbiIsICJpbXBvcnQgeyBOb2RlVHlwZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5pbXBvcnQgeyBUcmFuc2FjdGlvbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5pbXBvcnQgeyBjYW5Kb2luIH0gZnJvbSAnQHRpcHRhcC9wbS90cmFuc2Zvcm0nXG5cbmltcG9ydCB7IGZpbmRQYXJlbnROb2RlIH0gZnJvbSAnLi4vaGVscGVycy9maW5kUGFyZW50Tm9kZS5qcydcbmltcG9ydCB7IGdldE5vZGVUeXBlIH0gZnJvbSAnLi4vaGVscGVycy9nZXROb2RlVHlwZS5qcydcbmltcG9ydCB7IGlzTGlzdCB9IGZyb20gJy4uL2hlbHBlcnMvaXNMaXN0LmpzJ1xuaW1wb3J0IHsgUmF3Q29tbWFuZHMgfSBmcm9tICcuLi90eXBlcy5qcydcblxuY29uc3Qgam9pbkxpc3RCYWNrd2FyZHMgPSAodHI6IFRyYW5zYWN0aW9uLCBsaXN0VHlwZTogTm9kZVR5cGUpOiBib29sZWFuID0+IHtcbiAgY29uc3QgbGlzdCA9IGZpbmRQYXJlbnROb2RlKG5vZGUgPT4gbm9kZS50eXBlID09PSBsaXN0VHlwZSkodHIuc2VsZWN0aW9uKVxuXG4gIGlmICghbGlzdCkge1xuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICBjb25zdCBiZWZvcmUgPSB0ci5kb2MucmVzb2x2ZShNYXRoLm1heCgwLCBsaXN0LnBvcyAtIDEpKS5iZWZvcmUobGlzdC5kZXB0aClcblxuICBpZiAoYmVmb3JlID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgY29uc3Qgbm9kZUJlZm9yZSA9IHRyLmRvYy5ub2RlQXQoYmVmb3JlKVxuICBjb25zdCBjYW5Kb2luQmFja3dhcmRzID0gbGlzdC5ub2RlLnR5cGUgPT09IG5vZGVCZWZvcmU/LnR5cGUgJiYgY2FuSm9pbih0ci5kb2MsIGxpc3QucG9zKVxuXG4gIGlmICghY2FuSm9pbkJhY2t3YXJkcykge1xuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICB0ci5qb2luKGxpc3QucG9zKVxuXG4gIHJldHVybiB0cnVlXG59XG5cbmNvbnN0IGpvaW5MaXN0Rm9yd2FyZHMgPSAodHI6IFRyYW5zYWN0aW9uLCBsaXN0VHlwZTogTm9kZVR5cGUpOiBib29sZWFuID0+IHtcbiAgY29uc3QgbGlzdCA9IGZpbmRQYXJlbnROb2RlKG5vZGUgPT4gbm9kZS50eXBlID09PSBsaXN0VHlwZSkodHIuc2VsZWN0aW9uKVxuXG4gIGlmICghbGlzdCkge1xuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICBjb25zdCBhZnRlciA9IHRyLmRvYy5yZXNvbHZlKGxpc3Quc3RhcnQpLmFmdGVyKGxpc3QuZGVwdGgpXG5cbiAgaWYgKGFmdGVyID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgY29uc3Qgbm9kZUFmdGVyID0gdHIuZG9jLm5vZGVBdChhZnRlcilcbiAgY29uc3QgY2FuSm9pbkZvcndhcmRzID0gbGlzdC5ub2RlLnR5cGUgPT09IG5vZGVBZnRlcj8udHlwZSAmJiBjYW5Kb2luKHRyLmRvYywgYWZ0ZXIpXG5cbiAgaWYgKCFjYW5Kb2luRm9yd2FyZHMpIHtcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgdHIuam9pbihhZnRlcilcblxuICByZXR1cm4gdHJ1ZVxufVxuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgdG9nZ2xlTGlzdDoge1xuICAgICAgLyoqXG4gICAgICAgKiBUb2dnbGUgYmV0d2VlbiBkaWZmZXJlbnQgbGlzdCB0eXBlcy5cbiAgICAgICAqIEBwYXJhbSBsaXN0VHlwZU9yTmFtZSBUaGUgdHlwZSBvciBuYW1lIG9mIHRoZSBsaXN0LlxuICAgICAgICogQHBhcmFtIGl0ZW1UeXBlT3JOYW1lIFRoZSB0eXBlIG9yIG5hbWUgb2YgdGhlIGxpc3QgaXRlbS5cbiAgICAgICAqIEBwYXJhbSBrZWVwTWFya3MgS2VlcCBtYXJrcyB3aGVuIHRvZ2dsaW5nLlxuICAgICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgQXR0cmlidXRlcyBmb3IgdGhlIG5ldyBsaXN0LlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnRvZ2dsZUxpc3QoJ2J1bGxldExpc3QnLCAnbGlzdEl0ZW0nKVxuICAgICAgICovXG4gICAgICB0b2dnbGVMaXN0OiAobGlzdFR5cGVPck5hbWU6IHN0cmluZyB8IE5vZGVUeXBlLCBpdGVtVHlwZU9yTmFtZTogc3RyaW5nIHwgTm9kZVR5cGUsIGtlZXBNYXJrcz86IGJvb2xlYW4sIGF0dHJpYnV0ZXM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSA9PiBSZXR1cm5UeXBlO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgdG9nZ2xlTGlzdDogUmF3Q29tbWFuZHNbJ3RvZ2dsZUxpc3QnXSA9IChsaXN0VHlwZU9yTmFtZSwgaXRlbVR5cGVPck5hbWUsIGtlZXBNYXJrcywgYXR0cmlidXRlcyA9IHt9KSA9PiAoe1xuICBlZGl0b3IsIHRyLCBzdGF0ZSwgZGlzcGF0Y2gsIGNoYWluLCBjb21tYW5kcywgY2FuLFxufSkgPT4ge1xuICBjb25zdCB7IGV4dGVuc2lvbnMsIHNwbGl0dGFibGVNYXJrcyB9ID0gZWRpdG9yLmV4dGVuc2lvbk1hbmFnZXJcbiAgY29uc3QgbGlzdFR5cGUgPSBnZXROb2RlVHlwZShsaXN0VHlwZU9yTmFtZSwgc3RhdGUuc2NoZW1hKVxuICBjb25zdCBpdGVtVHlwZSA9IGdldE5vZGVUeXBlKGl0ZW1UeXBlT3JOYW1lLCBzdGF0ZS5zY2hlbWEpXG4gIGNvbnN0IHsgc2VsZWN0aW9uLCBzdG9yZWRNYXJrcyB9ID0gc3RhdGVcbiAgY29uc3QgeyAkZnJvbSwgJHRvIH0gPSBzZWxlY3Rpb25cbiAgY29uc3QgcmFuZ2UgPSAkZnJvbS5ibG9ja1JhbmdlKCR0bylcblxuICBjb25zdCBtYXJrcyA9IHN0b3JlZE1hcmtzIHx8IChzZWxlY3Rpb24uJHRvLnBhcmVudE9mZnNldCAmJiBzZWxlY3Rpb24uJGZyb20ubWFya3MoKSlcblxuICBpZiAoIXJhbmdlKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBjb25zdCBwYXJlbnRMaXN0ID0gZmluZFBhcmVudE5vZGUobm9kZSA9PiBpc0xpc3Qobm9kZS50eXBlLm5hbWUsIGV4dGVuc2lvbnMpKShzZWxlY3Rpb24pXG5cbiAgaWYgKHJhbmdlLmRlcHRoID49IDEgJiYgcGFyZW50TGlzdCAmJiByYW5nZS5kZXB0aCAtIHBhcmVudExpc3QuZGVwdGggPD0gMSkge1xuICAgIC8vIHJlbW92ZSBsaXN0XG4gICAgaWYgKHBhcmVudExpc3Qubm9kZS50eXBlID09PSBsaXN0VHlwZSkge1xuICAgICAgcmV0dXJuIGNvbW1hbmRzLmxpZnRMaXN0SXRlbShpdGVtVHlwZSlcbiAgICB9XG5cbiAgICAvLyBjaGFuZ2UgbGlzdCB0eXBlXG4gICAgaWYgKFxuICAgICAgaXNMaXN0KHBhcmVudExpc3Qubm9kZS50eXBlLm5hbWUsIGV4dGVuc2lvbnMpXG4gICAgICAgICYmIGxpc3RUeXBlLnZhbGlkQ29udGVudChwYXJlbnRMaXN0Lm5vZGUuY29udGVudClcbiAgICAgICAgJiYgZGlzcGF0Y2hcbiAgICApIHtcbiAgICAgIHJldHVybiBjaGFpbigpXG4gICAgICAgIC5jb21tYW5kKCgpID0+IHtcbiAgICAgICAgICB0ci5zZXROb2RlTWFya3VwKHBhcmVudExpc3QucG9zLCBsaXN0VHlwZSlcblxuICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH0pXG4gICAgICAgIC5jb21tYW5kKCgpID0+IGpvaW5MaXN0QmFja3dhcmRzKHRyLCBsaXN0VHlwZSkpXG4gICAgICAgIC5jb21tYW5kKCgpID0+IGpvaW5MaXN0Rm9yd2FyZHModHIsIGxpc3RUeXBlKSlcbiAgICAgICAgLnJ1bigpXG4gICAgfVxuICB9XG4gIGlmICgha2VlcE1hcmtzIHx8ICFtYXJrcyB8fCAhZGlzcGF0Y2gpIHtcblxuICAgIHJldHVybiBjaGFpbigpXG4gICAgICAvLyB0cnkgdG8gY29udmVydCBub2RlIHRvIGRlZmF1bHQgbm9kZSBpZiBuZWVkZWRcbiAgICAgIC5jb21tYW5kKCgpID0+IHtcbiAgICAgICAgY29uc3QgY2FuV3JhcEluTGlzdCA9IGNhbigpLndyYXBJbkxpc3QobGlzdFR5cGUsIGF0dHJpYnV0ZXMpXG5cbiAgICAgICAgaWYgKGNhbldyYXBJbkxpc3QpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNvbW1hbmRzLmNsZWFyTm9kZXMoKVxuICAgICAgfSlcbiAgICAgIC53cmFwSW5MaXN0KGxpc3RUeXBlLCBhdHRyaWJ1dGVzKVxuICAgICAgLmNvbW1hbmQoKCkgPT4gam9pbkxpc3RCYWNrd2FyZHModHIsIGxpc3RUeXBlKSlcbiAgICAgIC5jb21tYW5kKCgpID0+IGpvaW5MaXN0Rm9yd2FyZHModHIsIGxpc3RUeXBlKSlcbiAgICAgIC5ydW4oKVxuICB9XG5cbiAgcmV0dXJuIChcbiAgICBjaGFpbigpXG4gICAgLy8gdHJ5IHRvIGNvbnZlcnQgbm9kZSB0byBkZWZhdWx0IG5vZGUgaWYgbmVlZGVkXG4gICAgICAuY29tbWFuZCgoKSA9PiB7XG4gICAgICAgIGNvbnN0IGNhbldyYXBJbkxpc3QgPSBjYW4oKS53cmFwSW5MaXN0KGxpc3RUeXBlLCBhdHRyaWJ1dGVzKVxuXG4gICAgICAgIGNvbnN0IGZpbHRlcmVkTWFya3MgPSBtYXJrcy5maWx0ZXIobWFyayA9PiBzcGxpdHRhYmxlTWFya3MuaW5jbHVkZXMobWFyay50eXBlLm5hbWUpKVxuXG4gICAgICAgIHRyLmVuc3VyZU1hcmtzKGZpbHRlcmVkTWFya3MpXG5cbiAgICAgICAgaWYgKGNhbldyYXBJbkxpc3QpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNvbW1hbmRzLmNsZWFyTm9kZXMoKVxuICAgICAgfSlcbiAgICAgIC53cmFwSW5MaXN0KGxpc3RUeXBlLCBhdHRyaWJ1dGVzKVxuICAgICAgLmNvbW1hbmQoKCkgPT4gam9pbkxpc3RCYWNrd2FyZHModHIsIGxpc3RUeXBlKSlcbiAgICAgIC5jb21tYW5kKCgpID0+IGpvaW5MaXN0Rm9yd2FyZHModHIsIGxpc3RUeXBlKSlcbiAgICAgIC5ydW4oKVxuICApXG59XG4iLCAiaW1wb3J0IHsgTWFya1R5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgeyBnZXRNYXJrVHlwZSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0TWFya1R5cGUuanMnXG5pbXBvcnQgeyBpc01hcmtBY3RpdmUgfSBmcm9tICcuLi9oZWxwZXJzL2lzTWFya0FjdGl2ZS5qcydcbmltcG9ydCB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICB0b2dnbGVNYXJrOiB7XG4gICAgICAvKipcbiAgICAgICAqIFRvZ2dsZSBhIG1hcmsgb24gYW5kIG9mZi5cbiAgICAgICAqIEBwYXJhbSB0eXBlT3JOYW1lIFRoZSBtYXJrIHR5cGUgb3IgbmFtZS5cbiAgICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVzIFRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBtYXJrLlxuICAgICAgICogQHBhcmFtIG9wdGlvbnMuZXh0ZW5kRW1wdHlNYXJrUmFuZ2UgUmVtb3ZlcyB0aGUgbWFyayBldmVuIGFjcm9zcyB0aGUgY3VycmVudCBzZWxlY3Rpb24uIERlZmF1bHRzIHRvIGBmYWxzZWAuXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMudG9nZ2xlTWFyaygnYm9sZCcpXG4gICAgICAgKi9cbiAgICAgIHRvZ2dsZU1hcms6IChcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBtYXJrIHR5cGUgb3IgbmFtZS5cbiAgICAgICAgICovXG4gICAgICAgIHR5cGVPck5hbWU6IHN0cmluZyB8IE1hcmtUeXBlLFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGUgYXR0cmlidXRlcyBvZiB0aGUgbWFyay5cbiAgICAgICAgICovXG4gICAgICAgIGF0dHJpYnV0ZXM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuXG4gICAgICAgIG9wdGlvbnM/OiB7XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogUmVtb3ZlcyB0aGUgbWFyayBldmVuIGFjcm9zcyB0aGUgY3VycmVudCBzZWxlY3Rpb24uIERlZmF1bHRzIHRvIGBmYWxzZWAuXG4gICAgICAgICAgICovXG4gICAgICAgICAgZXh0ZW5kRW1wdHlNYXJrUmFuZ2U/OiBib29sZWFuXG4gICAgICAgIH0sXG4gICAgICApID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHRvZ2dsZU1hcms6IFJhd0NvbW1hbmRzWyd0b2dnbGVNYXJrJ10gPSAodHlwZU9yTmFtZSwgYXR0cmlidXRlcyA9IHt9LCBvcHRpb25zID0ge30pID0+ICh7IHN0YXRlLCBjb21tYW5kcyB9KSA9PiB7XG4gIGNvbnN0IHsgZXh0ZW5kRW1wdHlNYXJrUmFuZ2UgPSBmYWxzZSB9ID0gb3B0aW9uc1xuICBjb25zdCB0eXBlID0gZ2V0TWFya1R5cGUodHlwZU9yTmFtZSwgc3RhdGUuc2NoZW1hKVxuICBjb25zdCBpc0FjdGl2ZSA9IGlzTWFya0FjdGl2ZShzdGF0ZSwgdHlwZSwgYXR0cmlidXRlcylcblxuICBpZiAoaXNBY3RpdmUpIHtcbiAgICByZXR1cm4gY29tbWFuZHMudW5zZXRNYXJrKHR5cGUsIHsgZXh0ZW5kRW1wdHlNYXJrUmFuZ2UgfSlcbiAgfVxuXG4gIHJldHVybiBjb21tYW5kcy5zZXRNYXJrKHR5cGUsIGF0dHJpYnV0ZXMpXG59XG4iLCAiaW1wb3J0IHsgTm9kZVR5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgeyBnZXROb2RlVHlwZSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0Tm9kZVR5cGUuanMnXG5pbXBvcnQgeyBpc05vZGVBY3RpdmUgfSBmcm9tICcuLi9oZWxwZXJzL2lzTm9kZUFjdGl2ZS5qcydcbmltcG9ydCB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICB0b2dnbGVOb2RlOiB7XG4gICAgICAvKipcbiAgICAgICAqIFRvZ2dsZSBhIG5vZGUgd2l0aCBhbm90aGVyIG5vZGUuXG4gICAgICAgKiBAcGFyYW0gdHlwZU9yTmFtZSBUaGUgdHlwZSBvciBuYW1lIG9mIHRoZSBub2RlLlxuICAgICAgICogQHBhcmFtIHRvZ2dsZVR5cGVPck5hbWUgVGhlIHR5cGUgb3IgbmFtZSBvZiB0aGUgbm9kZSB0byB0b2dnbGUuXG4gICAgICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgYXR0cmlidXRlcyBvZiB0aGUgbm9kZS5cbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy50b2dnbGVOb2RlKCdoZWFkaW5nJywgJ3BhcmFncmFwaCcpXG4gICAgICAgKi9cbiAgICAgIHRvZ2dsZU5vZGU6IChcbiAgICAgICAgdHlwZU9yTmFtZTogc3RyaW5nIHwgTm9kZVR5cGUsXG4gICAgICAgIHRvZ2dsZVR5cGVPck5hbWU6IHN0cmluZyB8IE5vZGVUeXBlLFxuICAgICAgICBhdHRyaWJ1dGVzPzogUmVjb3JkPHN0cmluZywgYW55PixcbiAgICAgICkgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgdG9nZ2xlTm9kZTogUmF3Q29tbWFuZHNbJ3RvZ2dsZU5vZGUnXSA9ICh0eXBlT3JOYW1lLCB0b2dnbGVUeXBlT3JOYW1lLCBhdHRyaWJ1dGVzID0ge30pID0+ICh7IHN0YXRlLCBjb21tYW5kcyB9KSA9PiB7XG4gIGNvbnN0IHR5cGUgPSBnZXROb2RlVHlwZSh0eXBlT3JOYW1lLCBzdGF0ZS5zY2hlbWEpXG4gIGNvbnN0IHRvZ2dsZVR5cGUgPSBnZXROb2RlVHlwZSh0b2dnbGVUeXBlT3JOYW1lLCBzdGF0ZS5zY2hlbWEpXG4gIGNvbnN0IGlzQWN0aXZlID0gaXNOb2RlQWN0aXZlKHN0YXRlLCB0eXBlLCBhdHRyaWJ1dGVzKVxuXG4gIGxldCBhdHRyaWJ1dGVzVG9Db3B5OiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHwgdW5kZWZpbmVkXG5cbiAgaWYgKHN0YXRlLnNlbGVjdGlvbi4kYW5jaG9yLnNhbWVQYXJlbnQoc3RhdGUuc2VsZWN0aW9uLiRoZWFkKSkge1xuICAgIC8vIG9ubHkgY29weSBhdHRyaWJ1dGVzIGlmIHRoZSBzZWxlY3Rpb24gaXMgcG9pbnRpbmcgdG8gYSBub2RlIG9mIHRoZSBzYW1lIHR5cGVcbiAgICBhdHRyaWJ1dGVzVG9Db3B5ID0gc3RhdGUuc2VsZWN0aW9uLiRhbmNob3IucGFyZW50LmF0dHJzXG4gIH1cblxuICBpZiAoaXNBY3RpdmUpIHtcbiAgICByZXR1cm4gY29tbWFuZHMuc2V0Tm9kZSh0b2dnbGVUeXBlLCBhdHRyaWJ1dGVzVG9Db3B5KVxuICB9XG5cbiAgLy8gSWYgdGhlIG5vZGUgaXMgbm90IGFjdGl2ZSwgd2Ugd2FudCB0byBzZXQgdGhlIG5ldyBub2RlIHR5cGUgd2l0aCB0aGUgZ2l2ZW4gYXR0cmlidXRlc1xuICAvLyBDb3B5aW5nIG92ZXIgdGhlIGF0dHJpYnV0ZXMgZnJvbSB0aGUgY3VycmVudCBub2RlIGlmIHRoZSBzZWxlY3Rpb24gaXMgcG9pbnRpbmcgdG8gYSBub2RlIG9mIHRoZSBzYW1lIHR5cGVcbiAgcmV0dXJuIGNvbW1hbmRzLnNldE5vZGUodHlwZSwgeyAuLi5hdHRyaWJ1dGVzVG9Db3B5LCAuLi5hdHRyaWJ1dGVzIH0pXG59XG4iLCAiaW1wb3J0IHsgTm9kZVR5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgeyBnZXROb2RlVHlwZSB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0Tm9kZVR5cGUuanMnXG5pbXBvcnQgeyBpc05vZGVBY3RpdmUgfSBmcm9tICcuLi9oZWxwZXJzL2lzTm9kZUFjdGl2ZS5qcydcbmltcG9ydCB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICB0b2dnbGVXcmFwOiB7XG4gICAgICAvKipcbiAgICAgICAqIFdyYXBzIG5vZGVzIGluIGFub3RoZXIgbm9kZSwgb3IgcmVtb3ZlcyBhbiBleGlzdGluZyB3cmFwLlxuICAgICAgICogQHBhcmFtIHR5cGVPck5hbWUgVGhlIHR5cGUgb3IgbmFtZSBvZiB0aGUgbm9kZS5cbiAgICAgICAqIEBwYXJhbSBhdHRyaWJ1dGVzIFRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBub2RlLlxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnRvZ2dsZVdyYXAoJ2Jsb2NrcXVvdGUnKVxuICAgICAgICovXG4gICAgICB0b2dnbGVXcmFwOiAodHlwZU9yTmFtZTogc3RyaW5nIHwgTm9kZVR5cGUsIGF0dHJpYnV0ZXM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCB0b2dnbGVXcmFwOiBSYXdDb21tYW5kc1sndG9nZ2xlV3JhcCddID0gKHR5cGVPck5hbWUsIGF0dHJpYnV0ZXMgPSB7fSkgPT4gKHsgc3RhdGUsIGNvbW1hbmRzIH0pID0+IHtcbiAgY29uc3QgdHlwZSA9IGdldE5vZGVUeXBlKHR5cGVPck5hbWUsIHN0YXRlLnNjaGVtYSlcbiAgY29uc3QgaXNBY3RpdmUgPSBpc05vZGVBY3RpdmUoc3RhdGUsIHR5cGUsIGF0dHJpYnV0ZXMpXG5cbiAgaWYgKGlzQWN0aXZlKSB7XG4gICAgcmV0dXJuIGNvbW1hbmRzLmxpZnQodHlwZSlcbiAgfVxuXG4gIHJldHVybiBjb21tYW5kcy53cmFwSW4odHlwZSwgYXR0cmlidXRlcylcbn1cbiIsICJpbXBvcnQgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgdW5kb0lucHV0UnVsZToge1xuICAgICAgLyoqXG4gICAgICAgKiBVbmRvIGFuIGlucHV0IHJ1bGUuXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMudW5kb0lucHV0UnVsZSgpXG4gICAgICAgKi9cbiAgICAgIHVuZG9JbnB1dFJ1bGU6ICgpID0+IFJldHVyblR5cGUsXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCB1bmRvSW5wdXRSdWxlOiBSYXdDb21tYW5kc1sndW5kb0lucHV0UnVsZSddID0gKCkgPT4gKHsgc3RhdGUsIGRpc3BhdGNoIH0pID0+IHtcbiAgY29uc3QgcGx1Z2lucyA9IHN0YXRlLnBsdWdpbnNcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHBsdWdpbnMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICBjb25zdCBwbHVnaW4gPSBwbHVnaW5zW2ldXG4gICAgbGV0IHVuZG9hYmxlXG5cbiAgICAvLyBAdHMtaWdub3JlXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG4gICAgaWYgKHBsdWdpbi5zcGVjLmlzSW5wdXRSdWxlcyAmJiAodW5kb2FibGUgPSBwbHVnaW4uZ2V0U3RhdGUoc3RhdGUpKSkge1xuICAgICAgaWYgKGRpc3BhdGNoKSB7XG4gICAgICAgIGNvbnN0IHRyID0gc3RhdGUudHJcbiAgICAgICAgY29uc3QgdG9VbmRvID0gdW5kb2FibGUudHJhbnNmb3JtXG5cbiAgICAgICAgZm9yIChsZXQgaiA9IHRvVW5kby5zdGVwcy5sZW5ndGggLSAxOyBqID49IDA7IGogLT0gMSkge1xuICAgICAgICAgIHRyLnN0ZXAodG9VbmRvLnN0ZXBzW2pdLmludmVydCh0b1VuZG8uZG9jc1tqXSkpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodW5kb2FibGUudGV4dCkge1xuICAgICAgICAgIGNvbnN0IG1hcmtzID0gdHIuZG9jLnJlc29sdmUodW5kb2FibGUuZnJvbSkubWFya3MoKVxuXG4gICAgICAgICAgdHIucmVwbGFjZVdpdGgodW5kb2FibGUuZnJvbSwgdW5kb2FibGUudG8sIHN0YXRlLnNjaGVtYS50ZXh0KHVuZG9hYmxlLnRleHQsIG1hcmtzKSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0ci5kZWxldGUodW5kb2FibGUuZnJvbSwgdW5kb2FibGUudG8pXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRydWVcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZmFsc2Vcbn1cbiIsICJpbXBvcnQgeyBSYXdDb21tYW5kcyB9IGZyb20gJy4uL3R5cGVzLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgdW5zZXRBbGxNYXJrczoge1xuICAgICAgLyoqXG4gICAgICAgKiBSZW1vdmUgYWxsIG1hcmtzIGluIHRoZSBjdXJyZW50IHNlbGVjdGlvbi5cbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy51bnNldEFsbE1hcmtzKClcbiAgICAgICAqL1xuICAgICAgdW5zZXRBbGxNYXJrczogKCkgPT4gUmV0dXJuVHlwZSxcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHVuc2V0QWxsTWFya3M6IFJhd0NvbW1hbmRzWyd1bnNldEFsbE1hcmtzJ10gPSAoKSA9PiAoeyB0ciwgZGlzcGF0Y2ggfSkgPT4ge1xuICBjb25zdCB7IHNlbGVjdGlvbiB9ID0gdHJcbiAgY29uc3QgeyBlbXB0eSwgcmFuZ2VzIH0gPSBzZWxlY3Rpb25cblxuICBpZiAoZW1wdHkpIHtcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgaWYgKGRpc3BhdGNoKSB7XG4gICAgcmFuZ2VzLmZvckVhY2gocmFuZ2UgPT4ge1xuICAgICAgdHIucmVtb3ZlTWFyayhyYW5nZS4kZnJvbS5wb3MsIHJhbmdlLiR0by5wb3MpXG4gICAgfSlcbiAgfVxuXG4gIHJldHVybiB0cnVlXG59XG4iLCAiaW1wb3J0IHsgTWFya1R5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgeyBnZXRNYXJrUmFuZ2UgfSBmcm9tICcuLi9oZWxwZXJzL2dldE1hcmtSYW5nZS5qcydcbmltcG9ydCB7IGdldE1hcmtUeXBlIH0gZnJvbSAnLi4vaGVscGVycy9nZXRNYXJrVHlwZS5qcydcbmltcG9ydCB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICB1bnNldE1hcms6IHtcbiAgICAgIC8qKlxuICAgICAgICogUmVtb3ZlIGFsbCBtYXJrcyBpbiB0aGUgY3VycmVudCBzZWxlY3Rpb24uXG4gICAgICAgKiBAcGFyYW0gdHlwZU9yTmFtZSBUaGUgbWFyayB0eXBlIG9yIG5hbWUuXG4gICAgICAgKiBAcGFyYW0gb3B0aW9ucy5leHRlbmRFbXB0eU1hcmtSYW5nZSBSZW1vdmVzIHRoZSBtYXJrIGV2ZW4gYWNyb3NzIHRoZSBjdXJyZW50IHNlbGVjdGlvbi4gRGVmYXVsdHMgdG8gYGZhbHNlYC5cbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy51bnNldE1hcmsoJ2JvbGQnKVxuICAgICAgICovXG4gICAgICB1bnNldE1hcms6IChcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBtYXJrIHR5cGUgb3IgbmFtZS5cbiAgICAgICAgICovXG4gICAgICAgIHR5cGVPck5hbWU6IHN0cmluZyB8IE1hcmtUeXBlLFxuXG4gICAgICAgIG9wdGlvbnM/OiB7XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogUmVtb3ZlcyB0aGUgbWFyayBldmVuIGFjcm9zcyB0aGUgY3VycmVudCBzZWxlY3Rpb24uIERlZmF1bHRzIHRvIGBmYWxzZWAuXG4gICAgICAgICAgICovXG4gICAgICAgICAgZXh0ZW5kRW1wdHlNYXJrUmFuZ2U/OiBib29sZWFuXG4gICAgICAgIH0sXG4gICAgICApID0+IFJldHVyblR5cGVcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IHVuc2V0TWFyazogUmF3Q29tbWFuZHNbJ3Vuc2V0TWFyayddID0gKHR5cGVPck5hbWUsIG9wdGlvbnMgPSB7fSkgPT4gKHsgdHIsIHN0YXRlLCBkaXNwYXRjaCB9KSA9PiB7XG4gIGNvbnN0IHsgZXh0ZW5kRW1wdHlNYXJrUmFuZ2UgPSBmYWxzZSB9ID0gb3B0aW9uc1xuICBjb25zdCB7IHNlbGVjdGlvbiB9ID0gdHJcbiAgY29uc3QgdHlwZSA9IGdldE1hcmtUeXBlKHR5cGVPck5hbWUsIHN0YXRlLnNjaGVtYSlcbiAgY29uc3QgeyAkZnJvbSwgZW1wdHksIHJhbmdlcyB9ID0gc2VsZWN0aW9uXG5cbiAgaWYgKCFkaXNwYXRjaCkge1xuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICBpZiAoZW1wdHkgJiYgZXh0ZW5kRW1wdHlNYXJrUmFuZ2UpIHtcbiAgICBsZXQgeyBmcm9tLCB0byB9ID0gc2VsZWN0aW9uXG4gICAgY29uc3QgYXR0cnMgPSAkZnJvbS5tYXJrcygpLmZpbmQobWFyayA9PiBtYXJrLnR5cGUgPT09IHR5cGUpPy5hdHRyc1xuICAgIGNvbnN0IHJhbmdlID0gZ2V0TWFya1JhbmdlKCRmcm9tLCB0eXBlLCBhdHRycylcblxuICAgIGlmIChyYW5nZSkge1xuICAgICAgZnJvbSA9IHJhbmdlLmZyb21cbiAgICAgIHRvID0gcmFuZ2UudG9cbiAgICB9XG5cbiAgICB0ci5yZW1vdmVNYXJrKGZyb20sIHRvLCB0eXBlKVxuICB9IGVsc2Uge1xuICAgIHJhbmdlcy5mb3JFYWNoKHJhbmdlID0+IHtcbiAgICAgIHRyLnJlbW92ZU1hcmsocmFuZ2UuJGZyb20ucG9zLCByYW5nZS4kdG8ucG9zLCB0eXBlKVxuICAgIH0pXG4gIH1cblxuICB0ci5yZW1vdmVTdG9yZWRNYXJrKHR5cGUpXG5cbiAgcmV0dXJuIHRydWVcbn1cbiIsICJpbXBvcnQge1xuICBNYXJrLCBNYXJrVHlwZSwgTm9kZSwgTm9kZVR5cGUsXG59IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5pbXBvcnQgeyBTZWxlY3Rpb25SYW5nZSB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmltcG9ydCB7IGdldE1hcmtUeXBlIH0gZnJvbSAnLi4vaGVscGVycy9nZXRNYXJrVHlwZS5qcydcbmltcG9ydCB7IGdldE5vZGVUeXBlIH0gZnJvbSAnLi4vaGVscGVycy9nZXROb2RlVHlwZS5qcydcbmltcG9ydCB7IGdldFNjaGVtYVR5cGVOYW1lQnlOYW1lIH0gZnJvbSAnLi4vaGVscGVycy9nZXRTY2hlbWFUeXBlTmFtZUJ5TmFtZS5qcydcbmltcG9ydCB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICB1cGRhdGVBdHRyaWJ1dGVzOiB7XG4gICAgICAvKipcbiAgICAgICAqIFVwZGF0ZSBhdHRyaWJ1dGVzIG9mIGEgbm9kZSBvciBtYXJrLlxuICAgICAgICogQHBhcmFtIHR5cGVPck5hbWUgVGhlIHR5cGUgb3IgbmFtZSBvZiB0aGUgbm9kZSBvciBtYXJrLlxuICAgICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGF0dHJpYnV0ZXMgb2YgdGhlIG5vZGUgb3IgbWFyay5cbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy51cGRhdGVBdHRyaWJ1dGVzKCdtZW50aW9uJywgeyB1c2VySWQ6IFwiMlwiIH0pXG4gICAgICAgKi9cbiAgICAgIHVwZGF0ZUF0dHJpYnV0ZXM6IChcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSB0eXBlIG9yIG5hbWUgb2YgdGhlIG5vZGUgb3IgbWFyay5cbiAgICAgICAgICovXG4gICAgICAgIHR5cGVPck5hbWU6IHN0cmluZyB8IE5vZGVUeXBlIHwgTWFya1R5cGUsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBub2RlIG9yIG1hcmsuXG4gICAgICAgICAqL1xuICAgICAgICBhdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICAgICAgKSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCB1cGRhdGVBdHRyaWJ1dGVzOiBSYXdDb21tYW5kc1sndXBkYXRlQXR0cmlidXRlcyddID0gKHR5cGVPck5hbWUsIGF0dHJpYnV0ZXMgPSB7fSkgPT4gKHsgdHIsIHN0YXRlLCBkaXNwYXRjaCB9KSA9PiB7XG5cbiAgbGV0IG5vZGVUeXBlOiBOb2RlVHlwZSB8IG51bGwgPSBudWxsXG4gIGxldCBtYXJrVHlwZTogTWFya1R5cGUgfCBudWxsID0gbnVsbFxuXG4gIGNvbnN0IHNjaGVtYVR5cGUgPSBnZXRTY2hlbWFUeXBlTmFtZUJ5TmFtZShcbiAgICB0eXBlb2YgdHlwZU9yTmFtZSA9PT0gJ3N0cmluZycgPyB0eXBlT3JOYW1lIDogdHlwZU9yTmFtZS5uYW1lLFxuICAgIHN0YXRlLnNjaGVtYSxcbiAgKVxuXG4gIGlmICghc2NoZW1hVHlwZSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgaWYgKHNjaGVtYVR5cGUgPT09ICdub2RlJykge1xuICAgIG5vZGVUeXBlID0gZ2V0Tm9kZVR5cGUodHlwZU9yTmFtZSBhcyBOb2RlVHlwZSwgc3RhdGUuc2NoZW1hKVxuICB9XG5cbiAgaWYgKHNjaGVtYVR5cGUgPT09ICdtYXJrJykge1xuICAgIG1hcmtUeXBlID0gZ2V0TWFya1R5cGUodHlwZU9yTmFtZSBhcyBNYXJrVHlwZSwgc3RhdGUuc2NoZW1hKVxuICB9XG5cbiAgaWYgKGRpc3BhdGNoKSB7XG4gICAgdHIuc2VsZWN0aW9uLnJhbmdlcy5mb3JFYWNoKChyYW5nZTogU2VsZWN0aW9uUmFuZ2UpID0+IHtcblxuICAgICAgY29uc3QgZnJvbSA9IHJhbmdlLiRmcm9tLnBvc1xuICAgICAgY29uc3QgdG8gPSByYW5nZS4kdG8ucG9zXG5cbiAgICAgIGxldCBsYXN0UG9zOiBudW1iZXIgfCB1bmRlZmluZWRcbiAgICAgIGxldCBsYXN0Tm9kZTogTm9kZSB8IHVuZGVmaW5lZFxuICAgICAgbGV0IHRyaW1tZWRGcm9tOiBudW1iZXJcbiAgICAgIGxldCB0cmltbWVkVG86IG51bWJlclxuXG4gICAgICBpZiAodHIuc2VsZWN0aW9uLmVtcHR5KSB7XG4gICAgICAgIHN0YXRlLmRvYy5ub2Rlc0JldHdlZW4oZnJvbSwgdG8sIChub2RlOiBOb2RlLCBwb3M6IG51bWJlcikgPT4ge1xuXG4gICAgICAgICAgaWYgKG5vZGVUeXBlICYmIG5vZGVUeXBlID09PSBub2RlLnR5cGUpIHtcbiAgICAgICAgICAgIHRyaW1tZWRGcm9tID0gTWF0aC5tYXgocG9zLCBmcm9tKVxuICAgICAgICAgICAgdHJpbW1lZFRvID0gTWF0aC5taW4ocG9zICsgbm9kZS5ub2RlU2l6ZSwgdG8pXG4gICAgICAgICAgICBsYXN0UG9zID0gcG9zXG4gICAgICAgICAgICBsYXN0Tm9kZSA9IG5vZGVcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdGF0ZS5kb2Mubm9kZXNCZXR3ZWVuKGZyb20sIHRvLCAobm9kZTogTm9kZSwgcG9zOiBudW1iZXIpID0+IHtcblxuICAgICAgICAgIGlmIChwb3MgPCBmcm9tICYmIG5vZGVUeXBlICYmIG5vZGVUeXBlID09PSBub2RlLnR5cGUpIHtcbiAgICAgICAgICAgIHRyaW1tZWRGcm9tID0gTWF0aC5tYXgocG9zLCBmcm9tKVxuICAgICAgICAgICAgdHJpbW1lZFRvID0gTWF0aC5taW4ocG9zICsgbm9kZS5ub2RlU2l6ZSwgdG8pXG4gICAgICAgICAgICBsYXN0UG9zID0gcG9zXG4gICAgICAgICAgICBsYXN0Tm9kZSA9IG5vZGVcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAocG9zID49IGZyb20gJiYgcG9zIDw9IHRvKSB7XG5cbiAgICAgICAgICAgIGlmIChub2RlVHlwZSAmJiBub2RlVHlwZSA9PT0gbm9kZS50eXBlKSB7XG4gICAgICAgICAgICAgIHRyLnNldE5vZGVNYXJrdXAocG9zLCB1bmRlZmluZWQsIHtcbiAgICAgICAgICAgICAgICAuLi5ub2RlLmF0dHJzLFxuICAgICAgICAgICAgICAgIC4uLmF0dHJpYnV0ZXMsXG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChtYXJrVHlwZSAmJiBub2RlLm1hcmtzLmxlbmd0aCkge1xuICAgICAgICAgICAgICBub2RlLm1hcmtzLmZvckVhY2goKG1hcms6IE1hcmspID0+IHtcblxuICAgICAgICAgICAgICAgIGlmIChtYXJrVHlwZSA9PT0gbWFyay50eXBlKSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCB0cmltbWVkRnJvbTIgPSBNYXRoLm1heChwb3MsIGZyb20pXG4gICAgICAgICAgICAgICAgICBjb25zdCB0cmltbWVkVG8yID0gTWF0aC5taW4ocG9zICsgbm9kZS5ub2RlU2l6ZSwgdG8pXG5cbiAgICAgICAgICAgICAgICAgIHRyLmFkZE1hcmsoXG4gICAgICAgICAgICAgICAgICAgIHRyaW1tZWRGcm9tMixcbiAgICAgICAgICAgICAgICAgICAgdHJpbW1lZFRvMixcbiAgICAgICAgICAgICAgICAgICAgbWFya1R5cGUuY3JlYXRlKHtcbiAgICAgICAgICAgICAgICAgICAgICAuLi5tYXJrLmF0dHJzLFxuICAgICAgICAgICAgICAgICAgICAgIC4uLmF0dHJpYnV0ZXMsXG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICB9XG5cbiAgICAgIGlmIChsYXN0Tm9kZSkge1xuXG4gICAgICAgIGlmIChsYXN0UG9zICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0ci5zZXROb2RlTWFya3VwKGxhc3RQb3MsIHVuZGVmaW5lZCwge1xuICAgICAgICAgICAgLi4ubGFzdE5vZGUuYXR0cnMsXG4gICAgICAgICAgICAuLi5hdHRyaWJ1dGVzLFxuICAgICAgICAgIH0pXG4gICAgICAgIH1cblxuICAgICAgICBpZiAobWFya1R5cGUgJiYgbGFzdE5vZGUubWFya3MubGVuZ3RoKSB7XG4gICAgICAgICAgbGFzdE5vZGUubWFya3MuZm9yRWFjaCgobWFyazogTWFyaykgPT4ge1xuXG4gICAgICAgICAgICBpZiAobWFya1R5cGUgPT09IG1hcmsudHlwZSkge1xuICAgICAgICAgICAgICB0ci5hZGRNYXJrKFxuICAgICAgICAgICAgICAgIHRyaW1tZWRGcm9tLFxuICAgICAgICAgICAgICAgIHRyaW1tZWRUbyxcbiAgICAgICAgICAgICAgICBtYXJrVHlwZS5jcmVhdGUoe1xuICAgICAgICAgICAgICAgICAgLi4ubWFyay5hdHRycyxcbiAgICAgICAgICAgICAgICAgIC4uLmF0dHJpYnV0ZXMsXG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIHJldHVybiB0cnVlXG59XG4iLCAiaW1wb3J0IHsgd3JhcEluIGFzIG9yaWdpbmFsV3JhcEluIH0gZnJvbSAnQHRpcHRhcC9wbS9jb21tYW5kcydcbmltcG9ydCB7IE5vZGVUeXBlIH0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuaW1wb3J0IHsgZ2V0Tm9kZVR5cGUgfSBmcm9tICcuLi9oZWxwZXJzL2dldE5vZGVUeXBlLmpzJ1xuaW1wb3J0IHsgUmF3Q29tbWFuZHMgfSBmcm9tICcuLi90eXBlcy5qcydcblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIHdyYXBJbjoge1xuICAgICAgLyoqXG4gICAgICAgKiBXcmFwcyBub2RlcyBpbiBhbm90aGVyIG5vZGUuXG4gICAgICAgKiBAcGFyYW0gdHlwZU9yTmFtZSBUaGUgdHlwZSBvciBuYW1lIG9mIHRoZSBub2RlLlxuICAgICAgICogQHBhcmFtIGF0dHJpYnV0ZXMgVGhlIGF0dHJpYnV0ZXMgb2YgdGhlIG5vZGUuXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMud3JhcEluKCdibG9ja3F1b3RlJylcbiAgICAgICAqL1xuICAgICAgd3JhcEluOiAodHlwZU9yTmFtZTogc3RyaW5nIHwgTm9kZVR5cGUsIGF0dHJpYnV0ZXM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSA9PiBSZXR1cm5UeXBlXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCB3cmFwSW46IFJhd0NvbW1hbmRzWyd3cmFwSW4nXSA9ICh0eXBlT3JOYW1lLCBhdHRyaWJ1dGVzID0ge30pID0+ICh7IHN0YXRlLCBkaXNwYXRjaCB9KSA9PiB7XG4gIGNvbnN0IHR5cGUgPSBnZXROb2RlVHlwZSh0eXBlT3JOYW1lLCBzdGF0ZS5zY2hlbWEpXG5cbiAgcmV0dXJuIG9yaWdpbmFsV3JhcEluKHR5cGUsIGF0dHJpYnV0ZXMpKHN0YXRlLCBkaXNwYXRjaClcbn1cbiIsICJpbXBvcnQgeyBOb2RlVHlwZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5pbXBvcnQgeyB3cmFwSW5MaXN0IGFzIG9yaWdpbmFsV3JhcEluTGlzdCB9IGZyb20gJ0B0aXB0YXAvcG0vc2NoZW1hLWxpc3QnXG5cbmltcG9ydCB7IGdldE5vZGVUeXBlIH0gZnJvbSAnLi4vaGVscGVycy9nZXROb2RlVHlwZS5qcydcbmltcG9ydCB7IFJhd0NvbW1hbmRzIH0gZnJvbSAnLi4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICB3cmFwSW5MaXN0OiB7XG4gICAgICAvKipcbiAgICAgICAqIFdyYXAgYSBub2RlIGluIGEgbGlzdC5cbiAgICAgICAqIEBwYXJhbSB0eXBlT3JOYW1lIFRoZSB0eXBlIG9yIG5hbWUgb2YgdGhlIG5vZGUuXG4gICAgICAgKiBAcGFyYW0gYXR0cmlidXRlcyBUaGUgYXR0cmlidXRlcyBvZiB0aGUgbm9kZS5cbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy53cmFwSW5MaXN0KCdidWxsZXRMaXN0JylcbiAgICAgICAqL1xuICAgICAgd3JhcEluTGlzdDogKHR5cGVPck5hbWU6IHN0cmluZyB8IE5vZGVUeXBlLCBhdHRyaWJ1dGVzPzogUmVjb3JkPHN0cmluZywgYW55PikgPT4gUmV0dXJuVHlwZVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3Qgd3JhcEluTGlzdDogUmF3Q29tbWFuZHNbJ3dyYXBJbkxpc3QnXSA9ICh0eXBlT3JOYW1lLCBhdHRyaWJ1dGVzID0ge30pID0+ICh7IHN0YXRlLCBkaXNwYXRjaCB9KSA9PiB7XG4gIGNvbnN0IHR5cGUgPSBnZXROb2RlVHlwZSh0eXBlT3JOYW1lLCBzdGF0ZS5zY2hlbWEpXG5cbiAgcmV0dXJuIG9yaWdpbmFsV3JhcEluTGlzdCh0eXBlLCBhdHRyaWJ1dGVzKShzdGF0ZSwgZGlzcGF0Y2gpXG59XG4iLCAiaW1wb3J0ICogYXMgY29tbWFuZHMgZnJvbSAnLi4vY29tbWFuZHMvaW5kZXguanMnXG5pbXBvcnQgeyBFeHRlbnNpb24gfSBmcm9tICcuLi9FeHRlbnNpb24uanMnXG5cbmV4cG9ydCAqIGZyb20gJy4uL2NvbW1hbmRzL2luZGV4LmpzJ1xuXG5leHBvcnQgY29uc3QgQ29tbWFuZHMgPSBFeHRlbnNpb24uY3JlYXRlKHtcbiAgbmFtZTogJ2NvbW1hbmRzJyxcblxuICBhZGRDb21tYW5kcygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uY29tbWFuZHMsXG4gICAgfVxuICB9LFxufSlcbiIsICJpbXBvcnQgeyBQbHVnaW4sIFBsdWdpbktleSB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmltcG9ydCB7IEV4dGVuc2lvbiB9IGZyb20gJy4uL0V4dGVuc2lvbi5qcydcblxuZXhwb3J0IGNvbnN0IERyb3AgPSBFeHRlbnNpb24uY3JlYXRlKHtcbiAgbmFtZTogJ2Ryb3AnLFxuXG4gIGFkZFByb3NlTWlycm9yUGx1Z2lucygpIHtcbiAgICByZXR1cm4gW1xuICAgICAgbmV3IFBsdWdpbih7XG4gICAgICAgIGtleTogbmV3IFBsdWdpbktleSgndGlwdGFwRHJvcCcpLFxuXG4gICAgICAgIHByb3BzOiB7XG4gICAgICAgICAgaGFuZGxlRHJvcDogKF8sIGUsIHNsaWNlLCBtb3ZlZCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5lZGl0b3IuZW1pdCgnZHJvcCcsIHtcbiAgICAgICAgICAgICAgZWRpdG9yOiB0aGlzLmVkaXRvcixcbiAgICAgICAgICAgICAgZXZlbnQ6IGUsXG4gICAgICAgICAgICAgIHNsaWNlLFxuICAgICAgICAgICAgICBtb3ZlZCxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgIF1cbiAgfSxcbn0pXG4iLCAiaW1wb3J0IHsgUGx1Z2luLCBQbHVnaW5LZXkgfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5pbXBvcnQgeyBFeHRlbnNpb24gfSBmcm9tICcuLi9FeHRlbnNpb24uanMnXG5cbmV4cG9ydCBjb25zdCBFZGl0YWJsZSA9IEV4dGVuc2lvbi5jcmVhdGUoe1xuICBuYW1lOiAnZWRpdGFibGUnLFxuXG4gIGFkZFByb3NlTWlycm9yUGx1Z2lucygpIHtcbiAgICByZXR1cm4gW1xuICAgICAgbmV3IFBsdWdpbih7XG4gICAgICAgIGtleTogbmV3IFBsdWdpbktleSgnZWRpdGFibGUnKSxcbiAgICAgICAgcHJvcHM6IHtcbiAgICAgICAgICBlZGl0YWJsZTogKCkgPT4gdGhpcy5lZGl0b3Iub3B0aW9ucy5lZGl0YWJsZSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgIF1cbiAgfSxcbn0pXG4iLCAiaW1wb3J0IHsgUGx1Z2luLCBQbHVnaW5LZXkgfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5pbXBvcnQgeyBFeHRlbnNpb24gfSBmcm9tICcuLi9FeHRlbnNpb24uanMnXG5cbmV4cG9ydCBjb25zdCBmb2N1c0V2ZW50c1BsdWdpbktleSA9IG5ldyBQbHVnaW5LZXkoJ2ZvY3VzRXZlbnRzJylcblxuZXhwb3J0IGNvbnN0IEZvY3VzRXZlbnRzID0gRXh0ZW5zaW9uLmNyZWF0ZSh7XG4gIG5hbWU6ICdmb2N1c0V2ZW50cycsXG5cbiAgYWRkUHJvc2VNaXJyb3JQbHVnaW5zKCkge1xuICAgIGNvbnN0IHsgZWRpdG9yIH0gPSB0aGlzXG5cbiAgICByZXR1cm4gW1xuICAgICAgbmV3IFBsdWdpbih7XG4gICAgICAgIGtleTogZm9jdXNFdmVudHNQbHVnaW5LZXksXG4gICAgICAgIHByb3BzOiB7XG4gICAgICAgICAgaGFuZGxlRE9NRXZlbnRzOiB7XG4gICAgICAgICAgICBmb2N1czogKHZpZXcsIGV2ZW50OiBFdmVudCkgPT4ge1xuICAgICAgICAgICAgICBlZGl0b3IuaXNGb2N1c2VkID0gdHJ1ZVxuXG4gICAgICAgICAgICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gZWRpdG9yLnN0YXRlLnRyXG4gICAgICAgICAgICAgICAgLnNldE1ldGEoJ2ZvY3VzJywgeyBldmVudCB9KVxuICAgICAgICAgICAgICAgIC5zZXRNZXRhKCdhZGRUb0hpc3RvcnknLCBmYWxzZSlcblxuICAgICAgICAgICAgICB2aWV3LmRpc3BhdGNoKHRyYW5zYWN0aW9uKVxuXG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGJsdXI6ICh2aWV3LCBldmVudDogRXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgZWRpdG9yLmlzRm9jdXNlZCA9IGZhbHNlXG5cbiAgICAgICAgICAgICAgY29uc3QgdHJhbnNhY3Rpb24gPSBlZGl0b3Iuc3RhdGUudHJcbiAgICAgICAgICAgICAgICAuc2V0TWV0YSgnYmx1cicsIHsgZXZlbnQgfSlcbiAgICAgICAgICAgICAgICAuc2V0TWV0YSgnYWRkVG9IaXN0b3J5JywgZmFsc2UpXG5cbiAgICAgICAgICAgICAgdmlldy5kaXNwYXRjaCh0cmFuc2FjdGlvbilcblxuICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgIF1cbiAgfSxcbn0pXG4iLCAiaW1wb3J0IHsgUGx1Z2luLCBQbHVnaW5LZXksIFNlbGVjdGlvbiB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmltcG9ydCB7IENvbW1hbmRNYW5hZ2VyIH0gZnJvbSAnLi4vQ29tbWFuZE1hbmFnZXIuanMnXG5pbXBvcnQgeyBFeHRlbnNpb24gfSBmcm9tICcuLi9FeHRlbnNpb24uanMnXG5pbXBvcnQgeyBjcmVhdGVDaGFpbmFibGVTdGF0ZSB9IGZyb20gJy4uL2hlbHBlcnMvY3JlYXRlQ2hhaW5hYmxlU3RhdGUuanMnXG5pbXBvcnQgeyBpc05vZGVFbXB0eSB9IGZyb20gJy4uL2hlbHBlcnMvaXNOb2RlRW1wdHkuanMnXG5pbXBvcnQgeyBpc2lPUyB9IGZyb20gJy4uL3V0aWxpdGllcy9pc2lPUy5qcydcbmltcG9ydCB7IGlzTWFjT1MgfSBmcm9tICcuLi91dGlsaXRpZXMvaXNNYWNPUy5qcydcblxuZXhwb3J0IGNvbnN0IEtleW1hcCA9IEV4dGVuc2lvbi5jcmVhdGUoe1xuICBuYW1lOiAna2V5bWFwJyxcblxuICBhZGRLZXlib2FyZFNob3J0Y3V0cygpIHtcbiAgICBjb25zdCBoYW5kbGVCYWNrc3BhY2UgPSAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy5maXJzdCgoeyBjb21tYW5kcyB9KSA9PiBbXG4gICAgICAoKSA9PiBjb21tYW5kcy51bmRvSW5wdXRSdWxlKCksXG5cbiAgICAgIC8vIG1heWJlIGNvbnZlcnQgZmlyc3QgdGV4dCBibG9jayBub2RlIHRvIGRlZmF1bHQgbm9kZVxuICAgICAgKCkgPT4gY29tbWFuZHMuY29tbWFuZCgoeyB0ciB9KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgc2VsZWN0aW9uLCBkb2MgfSA9IHRyXG4gICAgICAgIGNvbnN0IHsgZW1wdHksICRhbmNob3IgfSA9IHNlbGVjdGlvblxuICAgICAgICBjb25zdCB7IHBvcywgcGFyZW50IH0gPSAkYW5jaG9yXG4gICAgICAgIGNvbnN0ICRwYXJlbnRQb3MgPSAkYW5jaG9yLnBhcmVudC5pc1RleHRibG9jayAmJiBwb3MgPiAwID8gdHIuZG9jLnJlc29sdmUocG9zIC0gMSkgOiAkYW5jaG9yXG4gICAgICAgIGNvbnN0IHBhcmVudElzSXNvbGF0aW5nID0gJHBhcmVudFBvcy5wYXJlbnQudHlwZS5zcGVjLmlzb2xhdGluZ1xuXG4gICAgICAgIGNvbnN0IHBhcmVudFBvcyA9ICRhbmNob3IucG9zIC0gJGFuY2hvci5wYXJlbnRPZmZzZXRcblxuICAgICAgICBjb25zdCBpc0F0U3RhcnQgPSAocGFyZW50SXNJc29sYXRpbmcgJiYgJHBhcmVudFBvcy5wYXJlbnQuY2hpbGRDb3VudCA9PT0gMSlcbiAgICAgICAgICA/IHBhcmVudFBvcyA9PT0gJGFuY2hvci5wb3NcbiAgICAgICAgICA6IFNlbGVjdGlvbi5hdFN0YXJ0KGRvYykuZnJvbSA9PT0gcG9zXG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgICFlbXB0eVxuICAgICAgICAgIHx8ICFwYXJlbnQudHlwZS5pc1RleHRibG9ja1xuICAgICAgICAgIHx8IHBhcmVudC50ZXh0Q29udGVudC5sZW5ndGhcbiAgICAgICAgICB8fCAhaXNBdFN0YXJ0XG4gICAgICAgICAgfHwgKGlzQXRTdGFydCAmJiAkYW5jaG9yLnBhcmVudC50eXBlLm5hbWUgPT09ICdwYXJhZ3JhcGgnKSAvLyBwcmV2ZW50IGNsZWFyTm9kZXMgd2hlbiBubyBub2RlcyB0byBjbGVhciwgb3RoZXJ3aXNlIGhpc3Rvcnkgc3RhY2sgaXMgYXBwZW5kZWRcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY29tbWFuZHMuY2xlYXJOb2RlcygpXG4gICAgICB9KSxcblxuICAgICAgKCkgPT4gY29tbWFuZHMuZGVsZXRlU2VsZWN0aW9uKCksXG4gICAgICAoKSA9PiBjb21tYW5kcy5qb2luQmFja3dhcmQoKSxcbiAgICAgICgpID0+IGNvbW1hbmRzLnNlbGVjdE5vZGVCYWNrd2FyZCgpLFxuICAgIF0pXG5cbiAgICBjb25zdCBoYW5kbGVEZWxldGUgPSAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy5maXJzdCgoeyBjb21tYW5kcyB9KSA9PiBbXG4gICAgICAoKSA9PiBjb21tYW5kcy5kZWxldGVTZWxlY3Rpb24oKSxcbiAgICAgICgpID0+IGNvbW1hbmRzLmRlbGV0ZUN1cnJlbnROb2RlKCksXG4gICAgICAoKSA9PiBjb21tYW5kcy5qb2luRm9yd2FyZCgpLFxuICAgICAgKCkgPT4gY29tbWFuZHMuc2VsZWN0Tm9kZUZvcndhcmQoKSxcbiAgICBdKVxuXG4gICAgY29uc3QgaGFuZGxlRW50ZXIgPSAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy5maXJzdCgoeyBjb21tYW5kcyB9KSA9PiBbXG4gICAgICAoKSA9PiBjb21tYW5kcy5uZXdsaW5lSW5Db2RlKCksXG4gICAgICAoKSA9PiBjb21tYW5kcy5jcmVhdGVQYXJhZ3JhcGhOZWFyKCksXG4gICAgICAoKSA9PiBjb21tYW5kcy5saWZ0RW1wdHlCbG9jaygpLFxuICAgICAgKCkgPT4gY29tbWFuZHMuc3BsaXRCbG9jaygpLFxuICAgIF0pXG5cbiAgICBjb25zdCBiYXNlS2V5bWFwID0ge1xuICAgICAgRW50ZXI6IGhhbmRsZUVudGVyLFxuICAgICAgJ01vZC1FbnRlcic6ICgpID0+IHRoaXMuZWRpdG9yLmNvbW1hbmRzLmV4aXRDb2RlKCksXG4gICAgICBCYWNrc3BhY2U6IGhhbmRsZUJhY2tzcGFjZSxcbiAgICAgICdNb2QtQmFja3NwYWNlJzogaGFuZGxlQmFja3NwYWNlLFxuICAgICAgJ1NoaWZ0LUJhY2tzcGFjZSc6IGhhbmRsZUJhY2tzcGFjZSxcbiAgICAgIERlbGV0ZTogaGFuZGxlRGVsZXRlLFxuICAgICAgJ01vZC1EZWxldGUnOiBoYW5kbGVEZWxldGUsXG4gICAgICAnTW9kLWEnOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy5zZWxlY3RBbGwoKSxcbiAgICB9XG5cbiAgICBjb25zdCBwY0tleW1hcCA9IHtcbiAgICAgIC4uLmJhc2VLZXltYXAsXG4gICAgfVxuXG4gICAgY29uc3QgbWFjS2V5bWFwID0ge1xuICAgICAgLi4uYmFzZUtleW1hcCxcbiAgICAgICdDdHJsLWgnOiBoYW5kbGVCYWNrc3BhY2UsXG4gICAgICAnQWx0LUJhY2tzcGFjZSc6IGhhbmRsZUJhY2tzcGFjZSxcbiAgICAgICdDdHJsLWQnOiBoYW5kbGVEZWxldGUsXG4gICAgICAnQ3RybC1BbHQtQmFja3NwYWNlJzogaGFuZGxlRGVsZXRlLFxuICAgICAgJ0FsdC1EZWxldGUnOiBoYW5kbGVEZWxldGUsXG4gICAgICAnQWx0LWQnOiBoYW5kbGVEZWxldGUsXG4gICAgICAnQ3RybC1hJzogKCkgPT4gdGhpcy5lZGl0b3IuY29tbWFuZHMuc2VsZWN0VGV4dGJsb2NrU3RhcnQoKSxcbiAgICAgICdDdHJsLWUnOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy5zZWxlY3RUZXh0YmxvY2tFbmQoKSxcbiAgICB9XG5cbiAgICBpZiAoaXNpT1MoKSB8fCBpc01hY09TKCkpIHtcbiAgICAgIHJldHVybiBtYWNLZXltYXBcbiAgICB9XG5cbiAgICByZXR1cm4gcGNLZXltYXBcbiAgfSxcblxuICBhZGRQcm9zZU1pcnJvclBsdWdpbnMoKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIC8vIFdpdGggdGhpcyBwbHVnaW4gd2UgY2hlY2sgaWYgdGhlIHdob2xlIGRvY3VtZW50IHdhcyBzZWxlY3RlZCBhbmQgZGVsZXRlZC5cbiAgICAgIC8vIEluIHRoaXMgY2FzZSB3ZSB3aWxsIGFkZGl0aW9uYWxseSBjYWxsIGBjbGVhck5vZGVzKClgIHRvIGNvbnZlcnQgZS5nLiBhIGhlYWRpbmdcbiAgICAgIC8vIHRvIGEgcGFyYWdyYXBoIGlmIG5lY2Vzc2FyeS5cbiAgICAgIC8vIFRoaXMgaXMgYW4gYWx0ZXJuYXRpdmUgdG8gUHJvc2VNaXJyb3IncyBgQWxsU2VsZWN0aW9uYCwgd2hpY2ggZG9lc27igJl0IHdvcmsgd2VsbFxuICAgICAgLy8gd2l0aCBtYW55IG90aGVyIGNvbW1hbmRzLlxuICAgICAgbmV3IFBsdWdpbih7XG4gICAgICAgIGtleTogbmV3IFBsdWdpbktleSgnY2xlYXJEb2N1bWVudCcpLFxuICAgICAgICBhcHBlbmRUcmFuc2FjdGlvbjogKHRyYW5zYWN0aW9ucywgb2xkU3RhdGUsIG5ld1N0YXRlKSA9PiB7XG4gICAgICAgICAgaWYgKHRyYW5zYWN0aW9ucy5zb21lKHRyID0+IHRyLmdldE1ldGEoJ2NvbXBvc2l0aW9uJykpKSB7XG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBkb2NDaGFuZ2VzID0gdHJhbnNhY3Rpb25zLnNvbWUodHJhbnNhY3Rpb24gPT4gdHJhbnNhY3Rpb24uZG9jQ2hhbmdlZClcbiAgICAgICAgICAgICYmICFvbGRTdGF0ZS5kb2MuZXEobmV3U3RhdGUuZG9jKVxuXG4gICAgICAgICAgY29uc3QgaWdub3JlVHIgPSB0cmFuc2FjdGlvbnMuc29tZSh0cmFuc2FjdGlvbiA9PiB0cmFuc2FjdGlvbi5nZXRNZXRhKCdwcmV2ZW50Q2xlYXJEb2N1bWVudCcpKVxuXG4gICAgICAgICAgaWYgKCFkb2NDaGFuZ2VzIHx8IGlnbm9yZVRyKSB7XG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCB7IGVtcHR5LCBmcm9tLCB0byB9ID0gb2xkU3RhdGUuc2VsZWN0aW9uXG4gICAgICAgICAgY29uc3QgYWxsRnJvbSA9IFNlbGVjdGlvbi5hdFN0YXJ0KG9sZFN0YXRlLmRvYykuZnJvbVxuICAgICAgICAgIGNvbnN0IGFsbEVuZCA9IFNlbGVjdGlvbi5hdEVuZChvbGRTdGF0ZS5kb2MpLnRvXG4gICAgICAgICAgY29uc3QgYWxsV2FzU2VsZWN0ZWQgPSBmcm9tID09PSBhbGxGcm9tICYmIHRvID09PSBhbGxFbmRcblxuICAgICAgICAgIGlmIChlbXB0eSB8fCAhYWxsV2FzU2VsZWN0ZWQpIHtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGlzRW1wdHkgPSBpc05vZGVFbXB0eShuZXdTdGF0ZS5kb2MpXG5cbiAgICAgICAgICBpZiAoIWlzRW1wdHkpIHtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IHRyID0gbmV3U3RhdGUudHJcbiAgICAgICAgICBjb25zdCBzdGF0ZSA9IGNyZWF0ZUNoYWluYWJsZVN0YXRlKHtcbiAgICAgICAgICAgIHN0YXRlOiBuZXdTdGF0ZSxcbiAgICAgICAgICAgIHRyYW5zYWN0aW9uOiB0cixcbiAgICAgICAgICB9KVxuICAgICAgICAgIGNvbnN0IHsgY29tbWFuZHMgfSA9IG5ldyBDb21tYW5kTWFuYWdlcih7XG4gICAgICAgICAgICBlZGl0b3I6IHRoaXMuZWRpdG9yLFxuICAgICAgICAgICAgc3RhdGUsXG4gICAgICAgICAgfSlcblxuICAgICAgICAgIGNvbW1hbmRzLmNsZWFyTm9kZXMoKVxuXG4gICAgICAgICAgaWYgKCF0ci5zdGVwcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB0clxuICAgICAgICB9LFxuICAgICAgfSksXG4gICAgXVxuICB9LFxufSlcbiIsICJpbXBvcnQgeyBQbHVnaW4sIFBsdWdpbktleSB9IGZyb20gJ0B0aXB0YXAvcG0vc3RhdGUnXG5cbmltcG9ydCB7IEV4dGVuc2lvbiB9IGZyb20gJy4uL0V4dGVuc2lvbi5qcydcblxuZXhwb3J0IGNvbnN0IFBhc3RlID0gRXh0ZW5zaW9uLmNyZWF0ZSh7XG4gIG5hbWU6ICdwYXN0ZScsXG5cbiAgYWRkUHJvc2VNaXJyb3JQbHVnaW5zKCkge1xuXG4gICAgcmV0dXJuIFtcbiAgICAgIG5ldyBQbHVnaW4oe1xuICAgICAgICBrZXk6IG5ldyBQbHVnaW5LZXkoJ3RpcHRhcFBhc3RlJyksXG5cbiAgICAgICAgcHJvcHM6IHtcbiAgICAgICAgICBoYW5kbGVQYXN0ZTogKF92aWV3LCBlLCBzbGljZSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5lZGl0b3IuZW1pdCgncGFzdGUnLCB7XG4gICAgICAgICAgICAgIGVkaXRvcjogdGhpcy5lZGl0b3IsXG4gICAgICAgICAgICAgIGV2ZW50OiBlLFxuICAgICAgICAgICAgICBzbGljZSxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgIF1cbiAgfSxcbn0pXG4iLCAiaW1wb3J0IHsgUGx1Z2luLCBQbHVnaW5LZXkgfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5pbXBvcnQgeyBFeHRlbnNpb24gfSBmcm9tICcuLi9FeHRlbnNpb24uanMnXG5cbmV4cG9ydCBjb25zdCBUYWJpbmRleCA9IEV4dGVuc2lvbi5jcmVhdGUoe1xuICBuYW1lOiAndGFiaW5kZXgnLFxuXG4gIGFkZFByb3NlTWlycm9yUGx1Z2lucygpIHtcbiAgICByZXR1cm4gW1xuICAgICAgbmV3IFBsdWdpbih7XG4gICAgICAgIGtleTogbmV3IFBsdWdpbktleSgndGFiaW5kZXgnKSxcbiAgICAgICAgcHJvcHM6IHtcbiAgICAgICAgICBhdHRyaWJ1dGVzOiAoKTogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nOyB9ID0+ICh0aGlzLmVkaXRvci5pc0VkaXRhYmxlID8geyB0YWJpbmRleDogJzAnIH0gOiB7fSksXG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICBdXG4gIH0sXG59KVxuIiwgImltcG9ydCB7XG4gIEZyYWdtZW50LCBOb2RlLCBSZXNvbHZlZFBvcyxcbn0gZnJvbSAnQHRpcHRhcC9wbS9tb2RlbCdcblxuaW1wb3J0IHsgRWRpdG9yIH0gZnJvbSAnLi9FZGl0b3IuanMnXG5pbXBvcnQgeyBDb250ZW50LCBSYW5nZSB9IGZyb20gJy4vdHlwZXMuanMnXG5cbmV4cG9ydCBjbGFzcyBOb2RlUG9zIHtcbiAgcHJpdmF0ZSByZXNvbHZlZFBvczogUmVzb2x2ZWRQb3NcblxuICBwcml2YXRlIGlzQmxvY2s6IGJvb2xlYW5cblxuICBwcml2YXRlIGVkaXRvcjogRWRpdG9yXG5cbiAgcHJpdmF0ZSBnZXQgbmFtZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLm5vZGUudHlwZS5uYW1lXG4gIH1cblxuICBjb25zdHJ1Y3Rvcihwb3M6IFJlc29sdmVkUG9zLCBlZGl0b3I6IEVkaXRvciwgaXNCbG9jayA9IGZhbHNlLCBub2RlOiBOb2RlIHwgbnVsbCA9IG51bGwpIHtcbiAgICB0aGlzLmlzQmxvY2sgPSBpc0Jsb2NrXG4gICAgdGhpcy5yZXNvbHZlZFBvcyA9IHBvc1xuICAgIHRoaXMuZWRpdG9yID0gZWRpdG9yXG4gICAgdGhpcy5jdXJyZW50Tm9kZSA9IG5vZGVcbiAgfVxuXG4gIHByaXZhdGUgY3VycmVudE5vZGU6IE5vZGUgfCBudWxsID0gbnVsbFxuXG4gIGdldCBub2RlKCk6IE5vZGUge1xuICAgIHJldHVybiB0aGlzLmN1cnJlbnROb2RlIHx8IHRoaXMucmVzb2x2ZWRQb3Mubm9kZSgpXG4gIH1cblxuICBnZXQgZWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XG4gICAgcmV0dXJuIHRoaXMuZWRpdG9yLnZpZXcuZG9tQXRQb3ModGhpcy5wb3MpLm5vZGUgYXMgSFRNTEVsZW1lbnRcbiAgfVxuXG4gIHB1YmxpYyBhY3R1YWxEZXB0aDogbnVtYmVyIHwgbnVsbCA9IG51bGxcblxuICBnZXQgZGVwdGgoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5hY3R1YWxEZXB0aCA/PyB0aGlzLnJlc29sdmVkUG9zLmRlcHRoXG4gIH1cblxuICBnZXQgcG9zKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMucmVzb2x2ZWRQb3MucG9zXG4gIH1cblxuICBnZXQgY29udGVudCgpOiBGcmFnbWVudCB7XG4gICAgcmV0dXJuIHRoaXMubm9kZS5jb250ZW50XG4gIH1cblxuICBzZXQgY29udGVudChjb250ZW50OiBDb250ZW50KSB7XG4gICAgbGV0IGZyb20gPSB0aGlzLmZyb21cbiAgICBsZXQgdG8gPSB0aGlzLnRvXG5cbiAgICBpZiAodGhpcy5pc0Jsb2NrKSB7XG4gICAgICBpZiAodGhpcy5jb250ZW50LnNpemUgPT09IDApIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgWW91IGNhbuKAmXQgc2V0IGNvbnRlbnQgb24gYSBibG9jayBub2RlLiBUcmllZCB0byBzZXQgY29udGVudCBvbiAke3RoaXMubmFtZX0gYXQgJHt0aGlzLnBvc31gKVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgZnJvbSA9IHRoaXMuZnJvbSArIDFcbiAgICAgIHRvID0gdGhpcy50byAtIDFcbiAgICB9XG5cbiAgICB0aGlzLmVkaXRvci5jb21tYW5kcy5pbnNlcnRDb250ZW50QXQoeyBmcm9tLCB0byB9LCBjb250ZW50KVxuICB9XG5cbiAgZ2V0IGF0dHJpYnV0ZXMoKTogeyBba2V5OiBzdHJpbmddOiBhbnkgfSB7XG4gICAgcmV0dXJuIHRoaXMubm9kZS5hdHRyc1xuICB9XG5cbiAgZ2V0IHRleHRDb250ZW50KCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMubm9kZS50ZXh0Q29udGVudFxuICB9XG5cbiAgZ2V0IHNpemUoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5ub2RlLm5vZGVTaXplXG4gIH1cblxuICBnZXQgZnJvbSgpOiBudW1iZXIge1xuICAgIGlmICh0aGlzLmlzQmxvY2spIHtcbiAgICAgIHJldHVybiB0aGlzLnBvc1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnJlc29sdmVkUG9zLnN0YXJ0KHRoaXMucmVzb2x2ZWRQb3MuZGVwdGgpXG4gIH1cblxuICBnZXQgcmFuZ2UoKTogUmFuZ2Uge1xuICAgIHJldHVybiB7XG4gICAgICBmcm9tOiB0aGlzLmZyb20sXG4gICAgICB0bzogdGhpcy50byxcbiAgICB9XG4gIH1cblxuICBnZXQgdG8oKTogbnVtYmVyIHtcbiAgICBpZiAodGhpcy5pc0Jsb2NrKSB7XG4gICAgICByZXR1cm4gdGhpcy5wb3MgKyB0aGlzLnNpemVcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5yZXNvbHZlZFBvcy5lbmQodGhpcy5yZXNvbHZlZFBvcy5kZXB0aCkgKyAodGhpcy5ub2RlLmlzVGV4dCA/IDAgOiAxKVxuICB9XG5cbiAgZ2V0IHBhcmVudCgpOiBOb2RlUG9zIHwgbnVsbCB7XG4gICAgaWYgKHRoaXMuZGVwdGggPT09IDApIHtcbiAgICAgIHJldHVybiBudWxsXG4gICAgfVxuXG4gICAgY29uc3QgcGFyZW50UG9zID0gdGhpcy5yZXNvbHZlZFBvcy5zdGFydCh0aGlzLnJlc29sdmVkUG9zLmRlcHRoIC0gMSlcbiAgICBjb25zdCAkcG9zID0gdGhpcy5yZXNvbHZlZFBvcy5kb2MucmVzb2x2ZShwYXJlbnRQb3MpXG5cbiAgICByZXR1cm4gbmV3IE5vZGVQb3MoJHBvcywgdGhpcy5lZGl0b3IpXG4gIH1cblxuICBnZXQgYmVmb3JlKCk6IE5vZGVQb3MgfCBudWxsIHtcbiAgICBsZXQgJHBvcyA9IHRoaXMucmVzb2x2ZWRQb3MuZG9jLnJlc29sdmUodGhpcy5mcm9tIC0gKHRoaXMuaXNCbG9jayA/IDEgOiAyKSlcblxuICAgIGlmICgkcG9zLmRlcHRoICE9PSB0aGlzLmRlcHRoKSB7XG4gICAgICAkcG9zID0gdGhpcy5yZXNvbHZlZFBvcy5kb2MucmVzb2x2ZSh0aGlzLmZyb20gLSAzKVxuICAgIH1cblxuICAgIHJldHVybiBuZXcgTm9kZVBvcygkcG9zLCB0aGlzLmVkaXRvcilcbiAgfVxuXG4gIGdldCBhZnRlcigpOiBOb2RlUG9zIHwgbnVsbCB7XG4gICAgbGV0ICRwb3MgPSB0aGlzLnJlc29sdmVkUG9zLmRvYy5yZXNvbHZlKHRoaXMudG8gKyAodGhpcy5pc0Jsb2NrID8gMiA6IDEpKVxuXG4gICAgaWYgKCRwb3MuZGVwdGggIT09IHRoaXMuZGVwdGgpIHtcbiAgICAgICRwb3MgPSB0aGlzLnJlc29sdmVkUG9zLmRvYy5yZXNvbHZlKHRoaXMudG8gKyAzKVxuICAgIH1cblxuICAgIHJldHVybiBuZXcgTm9kZVBvcygkcG9zLCB0aGlzLmVkaXRvcilcbiAgfVxuXG4gIGdldCBjaGlsZHJlbigpOiBOb2RlUG9zW10ge1xuICAgIGNvbnN0IGNoaWxkcmVuOiBOb2RlUG9zW10gPSBbXVxuXG4gICAgdGhpcy5ub2RlLmNvbnRlbnQuZm9yRWFjaCgobm9kZSwgb2Zmc2V0KSA9PiB7XG4gICAgICBjb25zdCBpc0Jsb2NrID0gbm9kZS5pc0Jsb2NrICYmICFub2RlLmlzVGV4dGJsb2NrXG4gICAgICBjb25zdCBpc05vblRleHRBdG9tID0gbm9kZS5pc0F0b20gJiYgIW5vZGUuaXNUZXh0XG5cbiAgICAgIGNvbnN0IHRhcmdldFBvcyA9IHRoaXMucG9zICsgb2Zmc2V0ICsgKGlzTm9uVGV4dEF0b20gPyAwIDogMSlcbiAgICAgIGNvbnN0ICRwb3MgPSB0aGlzLnJlc29sdmVkUG9zLmRvYy5yZXNvbHZlKHRhcmdldFBvcylcblxuICAgICAgaWYgKCFpc0Jsb2NrICYmICRwb3MuZGVwdGggPD0gdGhpcy5kZXB0aCkge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgY29uc3QgY2hpbGROb2RlUG9zID0gbmV3IE5vZGVQb3MoJHBvcywgdGhpcy5lZGl0b3IsIGlzQmxvY2ssIGlzQmxvY2sgPyBub2RlIDogbnVsbClcblxuICAgICAgaWYgKGlzQmxvY2spIHtcbiAgICAgICAgY2hpbGROb2RlUG9zLmFjdHVhbERlcHRoID0gdGhpcy5kZXB0aCArIDFcbiAgICAgIH1cblxuICAgICAgY2hpbGRyZW4ucHVzaChuZXcgTm9kZVBvcygkcG9zLCB0aGlzLmVkaXRvciwgaXNCbG9jaywgaXNCbG9jayA/IG5vZGUgOiBudWxsKSlcbiAgICB9KVxuXG4gICAgcmV0dXJuIGNoaWxkcmVuXG4gIH1cblxuICBnZXQgZmlyc3RDaGlsZCgpOiBOb2RlUG9zIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuY2hpbGRyZW5bMF0gfHwgbnVsbFxuICB9XG5cbiAgZ2V0IGxhc3RDaGlsZCgpOiBOb2RlUG9zIHwgbnVsbCB7XG4gICAgY29uc3QgY2hpbGRyZW4gPSB0aGlzLmNoaWxkcmVuXG5cbiAgICByZXR1cm4gY2hpbGRyZW5bY2hpbGRyZW4ubGVuZ3RoIC0gMV0gfHwgbnVsbFxuICB9XG5cbiAgY2xvc2VzdChzZWxlY3Rvcjogc3RyaW5nLCBhdHRyaWJ1dGVzOiB7IFtrZXk6IHN0cmluZ106IGFueSB9ID0ge30pOiBOb2RlUG9zIHwgbnVsbCB7XG4gICAgbGV0IG5vZGU6IE5vZGVQb3MgfCBudWxsID0gbnVsbFxuICAgIGxldCBjdXJyZW50Tm9kZSA9IHRoaXMucGFyZW50XG5cbiAgICB3aGlsZSAoY3VycmVudE5vZGUgJiYgIW5vZGUpIHtcbiAgICAgIGlmIChjdXJyZW50Tm9kZS5ub2RlLnR5cGUubmFtZSA9PT0gc2VsZWN0b3IpIHtcbiAgICAgICAgaWYgKE9iamVjdC5rZXlzKGF0dHJpYnV0ZXMpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBjb25zdCBub2RlQXR0cmlidXRlcyA9IGN1cnJlbnROb2RlLm5vZGUuYXR0cnNcbiAgICAgICAgICBjb25zdCBhdHRyS2V5cyA9IE9iamVjdC5rZXlzKGF0dHJpYnV0ZXMpXG5cbiAgICAgICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgYXR0cktleXMubGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgICAgICAgICBjb25zdCBrZXkgPSBhdHRyS2V5c1tpbmRleF1cblxuICAgICAgICAgICAgaWYgKG5vZGVBdHRyaWJ1dGVzW2tleV0gIT09IGF0dHJpYnV0ZXNba2V5XSkge1xuICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBub2RlID0gY3VycmVudE5vZGVcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjdXJyZW50Tm9kZSA9IGN1cnJlbnROb2RlLnBhcmVudFxuICAgIH1cblxuICAgIHJldHVybiBub2RlXG4gIH1cblxuICBxdWVyeVNlbGVjdG9yKHNlbGVjdG9yOiBzdHJpbmcsIGF0dHJpYnV0ZXM6IHsgW2tleTogc3RyaW5nXTogYW55IH0gPSB7fSk6IE5vZGVQb3MgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yLCBhdHRyaWJ1dGVzLCB0cnVlKVswXSB8fCBudWxsXG4gIH1cblxuICBxdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yOiBzdHJpbmcsIGF0dHJpYnV0ZXM6IHsgW2tleTogc3RyaW5nXTogYW55IH0gPSB7fSwgZmlyc3RJdGVtT25seSA9IGZhbHNlKTogTm9kZVBvc1tdIHtcbiAgICBsZXQgbm9kZXM6IE5vZGVQb3NbXSA9IFtdXG5cbiAgICBpZiAoIXRoaXMuY2hpbGRyZW4gfHwgdGhpcy5jaGlsZHJlbi5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBub2Rlc1xuICAgIH1cbiAgICBjb25zdCBhdHRyS2V5cyA9IE9iamVjdC5rZXlzKGF0dHJpYnV0ZXMpXG5cbiAgICAvKipcbiAgICAgKiBGaW5kcyBhbGwgY2hpbGRyZW4gcmVjdXJzaXZlbHkgdGhhdCBtYXRjaCB0aGUgc2VsZWN0b3IgYW5kIGF0dHJpYnV0ZXNcbiAgICAgKiBJZiBmaXJzdEl0ZW1Pbmx5IGlzIHRydWUsIGl0IHdpbGwgcmV0dXJuIHRoZSBmaXJzdCBpdGVtIGZvdW5kXG4gICAgICovXG4gICAgdGhpcy5jaGlsZHJlbi5mb3JFYWNoKGNoaWxkUG9zID0+IHtcbiAgICAgIC8vIElmIHdlIGFscmVhZHkgZm91bmQgYSBub2RlIGFuZCB3ZSBvbmx5IHdhbnQgdGhlIGZpcnN0IGl0ZW0sIHdlIGRvbnQgbmVlZCB0byBrZWVwIGdvaW5nXG4gICAgICBpZiAoZmlyc3RJdGVtT25seSAmJiBub2Rlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICBpZiAoY2hpbGRQb3Mubm9kZS50eXBlLm5hbWUgPT09IHNlbGVjdG9yKSB7XG4gICAgICAgIGNvbnN0IGRvZXNBbGxBdHRyaWJ1dGVzTWF0Y2ggPSBhdHRyS2V5cy5ldmVyeShrZXkgPT4gYXR0cmlidXRlc1trZXldID09PSBjaGlsZFBvcy5ub2RlLmF0dHJzW2tleV0pXG5cbiAgICAgICAgaWYgKGRvZXNBbGxBdHRyaWJ1dGVzTWF0Y2gpIHtcbiAgICAgICAgICBub2Rlcy5wdXNoKGNoaWxkUG9zKVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIElmIHdlIGFscmVhZHkgZm91bmQgYSBub2RlIGFuZCB3ZSBvbmx5IHdhbnQgdGhlIGZpcnN0IGl0ZW0sIHdlIGNhbiBzdG9wIGhlcmUgYW5kIHNraXAgdGhlIHJlY3Vyc2lvblxuICAgICAgaWYgKGZpcnN0SXRlbU9ubHkgJiYgbm9kZXMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgbm9kZXMgPSBub2Rlcy5jb25jYXQoY2hpbGRQb3MucXVlcnlTZWxlY3RvckFsbChzZWxlY3RvciwgYXR0cmlidXRlcywgZmlyc3RJdGVtT25seSkpXG4gICAgfSlcblxuICAgIHJldHVybiBub2Rlc1xuICB9XG5cbiAgc2V0QXR0cmlidXRlKGF0dHJpYnV0ZXM6IHsgW2tleTogc3RyaW5nXTogYW55IH0pIHtcbiAgICBjb25zdCB7IHRyIH0gPSB0aGlzLmVkaXRvci5zdGF0ZVxuXG4gICAgdHIuc2V0Tm9kZU1hcmt1cCh0aGlzLmZyb20sIHVuZGVmaW5lZCwge1xuICAgICAgLi4udGhpcy5ub2RlLmF0dHJzLFxuICAgICAgLi4uYXR0cmlidXRlcyxcbiAgICB9KVxuXG4gICAgdGhpcy5lZGl0b3Iudmlldy5kaXNwYXRjaCh0cilcbiAgfVxufVxuIiwgImV4cG9ydCBjb25zdCBzdHlsZSA9IGAuUHJvc2VNaXJyb3Ige1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG59XG5cbi5Qcm9zZU1pcnJvciB7XG4gIHdvcmQtd3JhcDogYnJlYWstd29yZDtcbiAgd2hpdGUtc3BhY2U6IHByZS13cmFwO1xuICB3aGl0ZS1zcGFjZTogYnJlYWstc3BhY2VzO1xuICAtd2Via2l0LWZvbnQtdmFyaWFudC1saWdhdHVyZXM6IG5vbmU7XG4gIGZvbnQtdmFyaWFudC1saWdhdHVyZXM6IG5vbmU7XG4gIGZvbnQtZmVhdHVyZS1zZXR0aW5nczogXCJsaWdhXCIgMDsgLyogdGhlIGFib3ZlIGRvZXNuJ3Qgc2VlbSB0byB3b3JrIGluIEVkZ2UgKi9cbn1cblxuLlByb3NlTWlycm9yIFtjb250ZW50ZWRpdGFibGU9XCJmYWxzZVwiXSB7XG4gIHdoaXRlLXNwYWNlOiBub3JtYWw7XG59XG5cbi5Qcm9zZU1pcnJvciBbY29udGVudGVkaXRhYmxlPVwiZmFsc2VcIl0gW2NvbnRlbnRlZGl0YWJsZT1cInRydWVcIl0ge1xuICB3aGl0ZS1zcGFjZTogcHJlLXdyYXA7XG59XG5cbi5Qcm9zZU1pcnJvciBwcmUge1xuICB3aGl0ZS1zcGFjZTogcHJlLXdyYXA7XG59XG5cbmltZy5Qcm9zZU1pcnJvci1zZXBhcmF0b3Ige1xuICBkaXNwbGF5OiBpbmxpbmUgIWltcG9ydGFudDtcbiAgYm9yZGVyOiBub25lICFpbXBvcnRhbnQ7XG4gIG1hcmdpbjogMCAhaW1wb3J0YW50O1xuICB3aWR0aDogMCAhaW1wb3J0YW50O1xuICBoZWlnaHQ6IDAgIWltcG9ydGFudDtcbn1cblxuLlByb3NlTWlycm9yLWdhcGN1cnNvciB7XG4gIGRpc3BsYXk6IG5vbmU7XG4gIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIG1hcmdpbjogMDtcbn1cblxuLlByb3NlTWlycm9yLWdhcGN1cnNvcjphZnRlciB7XG4gIGNvbnRlbnQ6IFwiXCI7XG4gIGRpc3BsYXk6IGJsb2NrO1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHRvcDogLTJweDtcbiAgd2lkdGg6IDIwcHg7XG4gIGJvcmRlci10b3A6IDFweCBzb2xpZCBibGFjaztcbiAgYW5pbWF0aW9uOiBQcm9zZU1pcnJvci1jdXJzb3ItYmxpbmsgMS4xcyBzdGVwcygyLCBzdGFydCkgaW5maW5pdGU7XG59XG5cbkBrZXlmcmFtZXMgUHJvc2VNaXJyb3ItY3Vyc29yLWJsaW5rIHtcbiAgdG8ge1xuICAgIHZpc2liaWxpdHk6IGhpZGRlbjtcbiAgfVxufVxuXG4uUHJvc2VNaXJyb3ItaGlkZXNlbGVjdGlvbiAqOjpzZWxlY3Rpb24ge1xuICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbn1cblxuLlByb3NlTWlycm9yLWhpZGVzZWxlY3Rpb24gKjo6LW1vei1zZWxlY3Rpb24ge1xuICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbn1cblxuLlByb3NlTWlycm9yLWhpZGVzZWxlY3Rpb24gKiB7XG4gIGNhcmV0LWNvbG9yOiB0cmFuc3BhcmVudDtcbn1cblxuLlByb3NlTWlycm9yLWZvY3VzZWQgLlByb3NlTWlycm9yLWdhcGN1cnNvciB7XG4gIGRpc3BsYXk6IGJsb2NrO1xufVxuXG4udGlwcHktYm94W2RhdGEtYW5pbWF0aW9uPWZhZGVdW2RhdGEtc3RhdGU9aGlkZGVuXSB7XG4gIG9wYWNpdHk6IDBcbn1gXG4iLCAiZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVN0eWxlVGFnKHN0eWxlOiBzdHJpbmcsIG5vbmNlPzogc3RyaW5nLCBzdWZmaXg/OiBzdHJpbmcpOiBIVE1MU3R5bGVFbGVtZW50IHtcbiAgY29uc3QgdGlwdGFwU3R5bGVUYWcgPSAoPEhUTUxTdHlsZUVsZW1lbnQ+ZG9jdW1lbnQucXVlcnlTZWxlY3Rvcihgc3R5bGVbZGF0YS10aXB0YXAtc3R5bGUke3N1ZmZpeCA/IGAtJHtzdWZmaXh9YCA6ICcnfV1gKSlcblxuICBpZiAodGlwdGFwU3R5bGVUYWcgIT09IG51bGwpIHtcbiAgICByZXR1cm4gdGlwdGFwU3R5bGVUYWdcbiAgfVxuXG4gIGNvbnN0IHN0eWxlTm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJylcblxuICBpZiAobm9uY2UpIHtcbiAgICBzdHlsZU5vZGUuc2V0QXR0cmlidXRlKCdub25jZScsIG5vbmNlKVxuICB9XG5cbiAgc3R5bGVOb2RlLnNldEF0dHJpYnV0ZShgZGF0YS10aXB0YXAtc3R5bGUke3N1ZmZpeCA/IGAtJHtzdWZmaXh9YCA6ICcnfWAsICcnKVxuICBzdHlsZU5vZGUuaW5uZXJIVE1MID0gc3R5bGVcbiAgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2hlYWQnKVswXS5hcHBlbmRDaGlsZChzdHlsZU5vZGUpXG5cbiAgcmV0dXJuIHN0eWxlTm9kZVxufVxuIiwgIi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1lbXB0eS1vYmplY3QtdHlwZSAqL1xuaW1wb3J0IHtcbiAgTWFya1R5cGUsXG4gIE5vZGUgYXMgUHJvc2VNaXJyb3JOb2RlLFxuICBOb2RlVHlwZSxcbiAgU2NoZW1hLFxufSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuaW1wb3J0IHtcbiAgRWRpdG9yU3RhdGUsIFBsdWdpbiwgUGx1Z2luS2V5LCBUcmFuc2FjdGlvbixcbn0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcbmltcG9ydCB7IEVkaXRvclZpZXcgfSBmcm9tICdAdGlwdGFwL3BtL3ZpZXcnXG5cbmltcG9ydCB7IENvbW1hbmRNYW5hZ2VyIH0gZnJvbSAnLi9Db21tYW5kTWFuYWdlci5qcydcbmltcG9ydCB7IEV2ZW50RW1pdHRlciB9IGZyb20gJy4vRXZlbnRFbWl0dGVyLmpzJ1xuaW1wb3J0IHsgRXh0ZW5zaW9uTWFuYWdlciB9IGZyb20gJy4vRXh0ZW5zaW9uTWFuYWdlci5qcydcbmltcG9ydCB7XG4gIENsaXBib2FyZFRleHRTZXJpYWxpemVyLCBDb21tYW5kcywgRHJvcCwgRWRpdGFibGUsIEZvY3VzRXZlbnRzLCBLZXltYXAsIFBhc3RlLFxuICBUYWJpbmRleCxcbn0gZnJvbSAnLi9leHRlbnNpb25zL2luZGV4LmpzJ1xuaW1wb3J0IHsgY3JlYXRlRG9jdW1lbnQgfSBmcm9tICcuL2hlbHBlcnMvY3JlYXRlRG9jdW1lbnQuanMnXG5pbXBvcnQgeyBnZXRBdHRyaWJ1dGVzIH0gZnJvbSAnLi9oZWxwZXJzL2dldEF0dHJpYnV0ZXMuanMnXG5pbXBvcnQgeyBnZXRIVE1MRnJvbUZyYWdtZW50IH0gZnJvbSAnLi9oZWxwZXJzL2dldEhUTUxGcm9tRnJhZ21lbnQuanMnXG5pbXBvcnQgeyBnZXRUZXh0IH0gZnJvbSAnLi9oZWxwZXJzL2dldFRleHQuanMnXG5pbXBvcnQgeyBnZXRUZXh0U2VyaWFsaXplcnNGcm9tU2NoZW1hIH0gZnJvbSAnLi9oZWxwZXJzL2dldFRleHRTZXJpYWxpemVyc0Zyb21TY2hlbWEuanMnXG5pbXBvcnQgeyBpc0FjdGl2ZSB9IGZyb20gJy4vaGVscGVycy9pc0FjdGl2ZS5qcydcbmltcG9ydCB7IGlzTm9kZUVtcHR5IH0gZnJvbSAnLi9oZWxwZXJzL2lzTm9kZUVtcHR5LmpzJ1xuaW1wb3J0IHsgcmVzb2x2ZUZvY3VzUG9zaXRpb24gfSBmcm9tICcuL2hlbHBlcnMvcmVzb2x2ZUZvY3VzUG9zaXRpb24uanMnXG5pbXBvcnQgeyBOb2RlUG9zIH0gZnJvbSAnLi9Ob2RlUG9zLmpzJ1xuaW1wb3J0IHsgc3R5bGUgfSBmcm9tICcuL3N0eWxlLmpzJ1xuaW1wb3J0IHtcbiAgQ2FuQ29tbWFuZHMsXG4gIENoYWluZWRDb21tYW5kcyxcbiAgRWRpdG9yRXZlbnRzLFxuICBFZGl0b3JPcHRpb25zLFxuICBKU09OQ29udGVudCxcbiAgU2luZ2xlQ29tbWFuZHMsXG4gIFRleHRTZXJpYWxpemVyLFxufSBmcm9tICcuL3R5cGVzLmpzJ1xuaW1wb3J0IHsgY3JlYXRlU3R5bGVUYWcgfSBmcm9tICcuL3V0aWxpdGllcy9jcmVhdGVTdHlsZVRhZy5qcydcbmltcG9ydCB7IGlzRnVuY3Rpb24gfSBmcm9tICcuL3V0aWxpdGllcy9pc0Z1bmN0aW9uLmpzJ1xuXG5leHBvcnQgKiBhcyBleHRlbnNpb25zIGZyb20gJy4vZXh0ZW5zaW9ucy9pbmRleC5qcydcblxuLy8gQHRzLWlnbm9yZVxuZXhwb3J0IGludGVyZmFjZSBUaXB0YXBFZGl0b3JIVE1MRWxlbWVudCBleHRlbmRzIEhUTUxFbGVtZW50IHtcbiAgZWRpdG9yPzogRWRpdG9yXG59XG5cbmV4cG9ydCBjbGFzcyBFZGl0b3IgZXh0ZW5kcyBFdmVudEVtaXR0ZXI8RWRpdG9yRXZlbnRzPiB7XG4gIHByaXZhdGUgY29tbWFuZE1hbmFnZXIhOiBDb21tYW5kTWFuYWdlclxuXG4gIHB1YmxpYyBleHRlbnNpb25NYW5hZ2VyITogRXh0ZW5zaW9uTWFuYWdlclxuXG4gIHByaXZhdGUgY3NzITogSFRNTFN0eWxlRWxlbWVudFxuXG4gIHB1YmxpYyBzY2hlbWEhOiBTY2hlbWFcblxuICBwdWJsaWMgdmlldyE6IEVkaXRvclZpZXdcblxuICBwdWJsaWMgaXNGb2N1c2VkID0gZmFsc2VcblxuICAvKipcbiAgICogVGhlIGVkaXRvciBpcyBjb25zaWRlcmVkIGluaXRpYWxpemVkIGFmdGVyIHRoZSBgY3JlYXRlYCBldmVudCBoYXMgYmVlbiBlbWl0dGVkLlxuICAgKi9cbiAgcHVibGljIGlzSW5pdGlhbGl6ZWQgPSBmYWxzZVxuXG4gIHB1YmxpYyBleHRlbnNpb25TdG9yYWdlOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge31cblxuICBwdWJsaWMgb3B0aW9uczogRWRpdG9yT3B0aW9ucyA9IHtcbiAgICBlbGVtZW50OiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKSxcbiAgICBjb250ZW50OiAnJyxcbiAgICBpbmplY3RDU1M6IHRydWUsXG4gICAgaW5qZWN0Tm9uY2U6IHVuZGVmaW5lZCxcbiAgICBleHRlbnNpb25zOiBbXSxcbiAgICBhdXRvZm9jdXM6IGZhbHNlLFxuICAgIGVkaXRhYmxlOiB0cnVlLFxuICAgIGVkaXRvclByb3BzOiB7fSxcbiAgICBwYXJzZU9wdGlvbnM6IHt9LFxuICAgIGNvcmVFeHRlbnNpb25PcHRpb25zOiB7fSxcbiAgICBlbmFibGVJbnB1dFJ1bGVzOiB0cnVlLFxuICAgIGVuYWJsZVBhc3RlUnVsZXM6IHRydWUsXG4gICAgZW5hYmxlQ29yZUV4dGVuc2lvbnM6IHRydWUsXG4gICAgZW5hYmxlQ29udGVudENoZWNrOiBmYWxzZSxcbiAgICBvbkJlZm9yZUNyZWF0ZTogKCkgPT4gbnVsbCxcbiAgICBvbkNyZWF0ZTogKCkgPT4gbnVsbCxcbiAgICBvblVwZGF0ZTogKCkgPT4gbnVsbCxcbiAgICBvblNlbGVjdGlvblVwZGF0ZTogKCkgPT4gbnVsbCxcbiAgICBvblRyYW5zYWN0aW9uOiAoKSA9PiBudWxsLFxuICAgIG9uRm9jdXM6ICgpID0+IG51bGwsXG4gICAgb25CbHVyOiAoKSA9PiBudWxsLFxuICAgIG9uRGVzdHJveTogKCkgPT4gbnVsbCxcbiAgICBvbkNvbnRlbnRFcnJvcjogKHsgZXJyb3IgfSkgPT4geyB0aHJvdyBlcnJvciB9LFxuICAgIG9uUGFzdGU6ICgpID0+IG51bGwsXG4gICAgb25Ecm9wOiAoKSA9PiBudWxsLFxuICB9XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogUGFydGlhbDxFZGl0b3JPcHRpb25zPiA9IHt9KSB7XG4gICAgc3VwZXIoKVxuICAgIHRoaXMuc2V0T3B0aW9ucyhvcHRpb25zKVxuICAgIHRoaXMuY3JlYXRlRXh0ZW5zaW9uTWFuYWdlcigpXG4gICAgdGhpcy5jcmVhdGVDb21tYW5kTWFuYWdlcigpXG4gICAgdGhpcy5jcmVhdGVTY2hlbWEoKVxuICAgIHRoaXMub24oJ2JlZm9yZUNyZWF0ZScsIHRoaXMub3B0aW9ucy5vbkJlZm9yZUNyZWF0ZSlcbiAgICB0aGlzLmVtaXQoJ2JlZm9yZUNyZWF0ZScsIHsgZWRpdG9yOiB0aGlzIH0pXG4gICAgdGhpcy5vbignY29udGVudEVycm9yJywgdGhpcy5vcHRpb25zLm9uQ29udGVudEVycm9yKVxuICAgIHRoaXMuY3JlYXRlVmlldygpXG4gICAgdGhpcy5pbmplY3RDU1MoKVxuICAgIHRoaXMub24oJ2NyZWF0ZScsIHRoaXMub3B0aW9ucy5vbkNyZWF0ZSlcbiAgICB0aGlzLm9uKCd1cGRhdGUnLCB0aGlzLm9wdGlvbnMub25VcGRhdGUpXG4gICAgdGhpcy5vbignc2VsZWN0aW9uVXBkYXRlJywgdGhpcy5vcHRpb25zLm9uU2VsZWN0aW9uVXBkYXRlKVxuICAgIHRoaXMub24oJ3RyYW5zYWN0aW9uJywgdGhpcy5vcHRpb25zLm9uVHJhbnNhY3Rpb24pXG4gICAgdGhpcy5vbignZm9jdXMnLCB0aGlzLm9wdGlvbnMub25Gb2N1cylcbiAgICB0aGlzLm9uKCdibHVyJywgdGhpcy5vcHRpb25zLm9uQmx1cilcbiAgICB0aGlzLm9uKCdkZXN0cm95JywgdGhpcy5vcHRpb25zLm9uRGVzdHJveSlcbiAgICB0aGlzLm9uKCdkcm9wJywgKHsgZXZlbnQsIHNsaWNlLCBtb3ZlZCB9KSA9PiB0aGlzLm9wdGlvbnMub25Ecm9wKGV2ZW50LCBzbGljZSwgbW92ZWQpKVxuICAgIHRoaXMub24oJ3Bhc3RlJywgKHsgZXZlbnQsIHNsaWNlIH0pID0+IHRoaXMub3B0aW9ucy5vblBhc3RlKGV2ZW50LCBzbGljZSkpXG5cbiAgICB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBpZiAodGhpcy5pc0Rlc3Ryb3llZCkge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgdGhpcy5jb21tYW5kcy5mb2N1cyh0aGlzLm9wdGlvbnMuYXV0b2ZvY3VzKVxuICAgICAgdGhpcy5lbWl0KCdjcmVhdGUnLCB7IGVkaXRvcjogdGhpcyB9KVxuICAgICAgdGhpcy5pc0luaXRpYWxpemVkID0gdHJ1ZVxuICAgIH0sIDApXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgZWRpdG9yIHN0b3JhZ2UuXG4gICAqL1xuICBwdWJsaWMgZ2V0IHN0b3JhZ2UoKTogUmVjb3JkPHN0cmluZywgYW55PiB7XG4gICAgcmV0dXJuIHRoaXMuZXh0ZW5zaW9uU3RvcmFnZVxuICB9XG5cbiAgLyoqXG4gICAqIEFuIG9iamVjdCBvZiBhbGwgcmVnaXN0ZXJlZCBjb21tYW5kcy5cbiAgICovXG4gIHB1YmxpYyBnZXQgY29tbWFuZHMoKTogU2luZ2xlQ29tbWFuZHMge1xuICAgIHJldHVybiB0aGlzLmNvbW1hbmRNYW5hZ2VyLmNvbW1hbmRzXG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgY29tbWFuZCBjaGFpbiB0byBjYWxsIG11bHRpcGxlIGNvbW1hbmRzIGF0IG9uY2UuXG4gICAqL1xuICBwdWJsaWMgY2hhaW4oKTogQ2hhaW5lZENvbW1hbmRzIHtcbiAgICByZXR1cm4gdGhpcy5jb21tYW5kTWFuYWdlci5jaGFpbigpXG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgYSBjb21tYW5kIG9yIGEgY29tbWFuZCBjaGFpbiBjYW4gYmUgZXhlY3V0ZWQuIFdpdGhvdXQgZXhlY3V0aW5nIGl0LlxuICAgKi9cbiAgcHVibGljIGNhbigpOiBDYW5Db21tYW5kcyB7XG4gICAgcmV0dXJuIHRoaXMuY29tbWFuZE1hbmFnZXIuY2FuKClcbiAgfVxuXG4gIC8qKlxuICAgKiBJbmplY3QgQ1NTIHN0eWxlcy5cbiAgICovXG4gIHByaXZhdGUgaW5qZWN0Q1NTKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLm9wdGlvbnMuaW5qZWN0Q1NTICYmIGRvY3VtZW50KSB7XG4gICAgICB0aGlzLmNzcyA9IGNyZWF0ZVN0eWxlVGFnKHN0eWxlLCB0aGlzLm9wdGlvbnMuaW5qZWN0Tm9uY2UpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZSBlZGl0b3Igb3B0aW9ucy5cbiAgICpcbiAgICogQHBhcmFtIG9wdGlvbnMgQSBsaXN0IG9mIG9wdGlvbnNcbiAgICovXG4gIHB1YmxpYyBzZXRPcHRpb25zKG9wdGlvbnM6IFBhcnRpYWw8RWRpdG9yT3B0aW9ucz4gPSB7fSk6IHZvaWQge1xuICAgIHRoaXMub3B0aW9ucyA9IHtcbiAgICAgIC4uLnRoaXMub3B0aW9ucyxcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLnZpZXcgfHwgIXRoaXMuc3RhdGUgfHwgdGhpcy5pc0Rlc3Ryb3llZCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5lZGl0b3JQcm9wcykge1xuICAgICAgdGhpcy52aWV3LnNldFByb3BzKHRoaXMub3B0aW9ucy5lZGl0b3JQcm9wcylcbiAgICB9XG5cbiAgICB0aGlzLnZpZXcudXBkYXRlU3RhdGUodGhpcy5zdGF0ZSlcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgZWRpdGFibGUgc3RhdGUgb2YgdGhlIGVkaXRvci5cbiAgICovXG4gIHB1YmxpYyBzZXRFZGl0YWJsZShlZGl0YWJsZTogYm9vbGVhbiwgZW1pdFVwZGF0ZSA9IHRydWUpOiB2b2lkIHtcbiAgICB0aGlzLnNldE9wdGlvbnMoeyBlZGl0YWJsZSB9KVxuXG4gICAgaWYgKGVtaXRVcGRhdGUpIHtcbiAgICAgIHRoaXMuZW1pdCgndXBkYXRlJywgeyBlZGl0b3I6IHRoaXMsIHRyYW5zYWN0aW9uOiB0aGlzLnN0YXRlLnRyIH0pXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgd2hldGhlciB0aGUgZWRpdG9yIGlzIGVkaXRhYmxlLlxuICAgKi9cbiAgcHVibGljIGdldCBpc0VkaXRhYmxlKCk6IGJvb2xlYW4ge1xuICAgIC8vIHNpbmNlIHBsdWdpbnMgYXJlIGFwcGxpZWQgYWZ0ZXIgY3JlYXRpbmcgdGhlIHZpZXdcbiAgICAvLyBgZWRpdGFibGVgIGlzIGFsd2F5cyBgdHJ1ZWAgZm9yIG9uZSB0aWNrLlxuICAgIC8vIHRoYXTigJlzIHdoeSB3ZSBhbHNvIGhhdmUgdG8gY2hlY2sgZm9yIGBvcHRpb25zLmVkaXRhYmxlYFxuICAgIHJldHVybiB0aGlzLm9wdGlvbnMuZWRpdGFibGUgJiYgdGhpcy52aWV3ICYmIHRoaXMudmlldy5lZGl0YWJsZVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGVkaXRvciBzdGF0ZS5cbiAgICovXG4gIHB1YmxpYyBnZXQgc3RhdGUoKTogRWRpdG9yU3RhdGUge1xuICAgIHJldHVybiB0aGlzLnZpZXcuc3RhdGVcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlciBhIFByb3NlTWlycm9yIHBsdWdpbi5cbiAgICpcbiAgICogQHBhcmFtIHBsdWdpbiBBIFByb3NlTWlycm9yIHBsdWdpblxuICAgKiBAcGFyYW0gaGFuZGxlUGx1Z2lucyBDb250cm9sIGhvdyB0byBtZXJnZSB0aGUgcGx1Z2luIGludG8gdGhlIGV4aXN0aW5nIHBsdWdpbnMuXG4gICAqIEByZXR1cm5zIFRoZSBuZXcgZWRpdG9yIHN0YXRlXG4gICAqL1xuICBwdWJsaWMgcmVnaXN0ZXJQbHVnaW4oXG4gICAgcGx1Z2luOiBQbHVnaW4sXG4gICAgaGFuZGxlUGx1Z2lucz86IChuZXdQbHVnaW46IFBsdWdpbiwgcGx1Z2luczogUGx1Z2luW10pID0+IFBsdWdpbltdLFxuICApOiBFZGl0b3JTdGF0ZSB7XG4gICAgY29uc3QgcGx1Z2lucyA9IGlzRnVuY3Rpb24oaGFuZGxlUGx1Z2lucylcbiAgICAgID8gaGFuZGxlUGx1Z2lucyhwbHVnaW4sIFsuLi50aGlzLnN0YXRlLnBsdWdpbnNdKVxuICAgICAgOiBbLi4udGhpcy5zdGF0ZS5wbHVnaW5zLCBwbHVnaW5dXG5cbiAgICBjb25zdCBzdGF0ZSA9IHRoaXMuc3RhdGUucmVjb25maWd1cmUoeyBwbHVnaW5zIH0pXG5cbiAgICB0aGlzLnZpZXcudXBkYXRlU3RhdGUoc3RhdGUpXG5cbiAgICByZXR1cm4gc3RhdGVcbiAgfVxuXG4gIC8qKlxuICAgKiBVbnJlZ2lzdGVyIGEgUHJvc2VNaXJyb3IgcGx1Z2luLlxuICAgKlxuICAgKiBAcGFyYW0gbmFtZU9yUGx1Z2luS2V5VG9SZW1vdmUgVGhlIHBsdWdpbnMgbmFtZVxuICAgKiBAcmV0dXJucyBUaGUgbmV3IGVkaXRvciBzdGF0ZSBvciB1bmRlZmluZWQgaWYgdGhlIGVkaXRvciBpcyBkZXN0cm95ZWRcbiAgICovXG4gIHB1YmxpYyB1bnJlZ2lzdGVyUGx1Z2luKG5hbWVPclBsdWdpbktleVRvUmVtb3ZlOiBzdHJpbmcgfCBQbHVnaW5LZXkgfCAoc3RyaW5nIHwgUGx1Z2luS2V5KVtdKTogRWRpdG9yU3RhdGUgfCB1bmRlZmluZWQge1xuICAgIGlmICh0aGlzLmlzRGVzdHJveWVkKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgfVxuXG4gICAgY29uc3QgcHJldlBsdWdpbnMgPSB0aGlzLnN0YXRlLnBsdWdpbnNcbiAgICBsZXQgcGx1Z2lucyA9IHByZXZQbHVnaW5zO1xuXG4gICAgKFtdIGFzIChzdHJpbmcgfCBQbHVnaW5LZXkpW10pLmNvbmNhdChuYW1lT3JQbHVnaW5LZXlUb1JlbW92ZSkuZm9yRWFjaChuYW1lT3JQbHVnaW5LZXkgPT4ge1xuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgY29uc3QgbmFtZSA9IHR5cGVvZiBuYW1lT3JQbHVnaW5LZXkgPT09ICdzdHJpbmcnID8gYCR7bmFtZU9yUGx1Z2luS2V5fSRgIDogbmFtZU9yUGx1Z2luS2V5LmtleVxuXG4gICAgICAvLyBAdHMtaWdub3JlXG4gICAgICBwbHVnaW5zID0gcGx1Z2lucy5maWx0ZXIocGx1Z2luID0+ICFwbHVnaW4ua2V5LnN0YXJ0c1dpdGgobmFtZSkpXG4gICAgfSlcblxuICAgIGlmIChwcmV2UGx1Z2lucy5sZW5ndGggPT09IHBsdWdpbnMubGVuZ3RoKSB7XG4gICAgICAvLyBObyBwbHVnaW4gd2FzIHJlbW92ZWQsIHNvIHdlIGRvbuKAmXQgbmVlZCB0byB1cGRhdGUgdGhlIHN0YXRlXG4gICAgICByZXR1cm4gdW5kZWZpbmVkXG4gICAgfVxuXG4gICAgY29uc3Qgc3RhdGUgPSB0aGlzLnN0YXRlLnJlY29uZmlndXJlKHtcbiAgICAgIHBsdWdpbnMsXG4gICAgfSlcblxuICAgIHRoaXMudmlldy51cGRhdGVTdGF0ZShzdGF0ZSlcblxuICAgIHJldHVybiBzdGF0ZVxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYW4gZXh0ZW5zaW9uIG1hbmFnZXIuXG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZUV4dGVuc2lvbk1hbmFnZXIoKTogdm9pZCB7XG5cbiAgICBjb25zdCBjb3JlRXh0ZW5zaW9ucyA9IHRoaXMub3B0aW9ucy5lbmFibGVDb3JlRXh0ZW5zaW9ucyA/IFtcbiAgICAgIEVkaXRhYmxlLFxuICAgICAgQ2xpcGJvYXJkVGV4dFNlcmlhbGl6ZXIuY29uZmlndXJlKHtcbiAgICAgICAgYmxvY2tTZXBhcmF0b3I6IHRoaXMub3B0aW9ucy5jb3JlRXh0ZW5zaW9uT3B0aW9ucz8uY2xpcGJvYXJkVGV4dFNlcmlhbGl6ZXI/LmJsb2NrU2VwYXJhdG9yLFxuICAgICAgfSksXG4gICAgICBDb21tYW5kcyxcbiAgICAgIEZvY3VzRXZlbnRzLFxuICAgICAgS2V5bWFwLFxuICAgICAgVGFiaW5kZXgsXG4gICAgICBEcm9wLFxuICAgICAgUGFzdGUsXG4gICAgXS5maWx0ZXIoZXh0ID0+IHtcbiAgICAgIGlmICh0eXBlb2YgdGhpcy5vcHRpb25zLmVuYWJsZUNvcmVFeHRlbnNpb25zID09PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zLmVuYWJsZUNvcmVFeHRlbnNpb25zW2V4dC5uYW1lIGFzIGtleW9mIHR5cGVvZiB0aGlzLm9wdGlvbnMuZW5hYmxlQ29yZUV4dGVuc2lvbnNdICE9PSBmYWxzZVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWVcbiAgICB9KSA6IFtdXG4gICAgY29uc3QgYWxsRXh0ZW5zaW9ucyA9IFsuLi5jb3JlRXh0ZW5zaW9ucywgLi4udGhpcy5vcHRpb25zLmV4dGVuc2lvbnNdLmZpbHRlcihleHRlbnNpb24gPT4ge1xuICAgICAgcmV0dXJuIFsnZXh0ZW5zaW9uJywgJ25vZGUnLCAnbWFyayddLmluY2x1ZGVzKGV4dGVuc2lvbj8udHlwZSlcbiAgICB9KVxuXG4gICAgdGhpcy5leHRlbnNpb25NYW5hZ2VyID0gbmV3IEV4dGVuc2lvbk1hbmFnZXIoYWxsRXh0ZW5zaW9ucywgdGhpcylcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIGNvbW1hbmQgbWFuYWdlci5cbiAgICovXG4gIHByaXZhdGUgY3JlYXRlQ29tbWFuZE1hbmFnZXIoKTogdm9pZCB7XG4gICAgdGhpcy5jb21tYW5kTWFuYWdlciA9IG5ldyBDb21tYW5kTWFuYWdlcih7XG4gICAgICBlZGl0b3I6IHRoaXMsXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgUHJvc2VNaXJyb3Igc2NoZW1hLlxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVTY2hlbWEoKTogdm9pZCB7XG4gICAgdGhpcy5zY2hlbWEgPSB0aGlzLmV4dGVuc2lvbk1hbmFnZXIuc2NoZW1hXG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIFByb3NlTWlycm9yIHZpZXcuXG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZVZpZXcoKTogdm9pZCB7XG4gICAgbGV0IGRvYzogUHJvc2VNaXJyb3JOb2RlXG5cbiAgICB0cnkge1xuICAgICAgZG9jID0gY3JlYXRlRG9jdW1lbnQoXG4gICAgICAgIHRoaXMub3B0aW9ucy5jb250ZW50LFxuICAgICAgICB0aGlzLnNjaGVtYSxcbiAgICAgICAgdGhpcy5vcHRpb25zLnBhcnNlT3B0aW9ucyxcbiAgICAgICAgeyBlcnJvck9uSW52YWxpZENvbnRlbnQ6IHRoaXMub3B0aW9ucy5lbmFibGVDb250ZW50Q2hlY2sgfSxcbiAgICAgIClcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBpZiAoIShlIGluc3RhbmNlb2YgRXJyb3IpIHx8ICFbJ1t0aXB0YXAgZXJyb3JdOiBJbnZhbGlkIEpTT04gY29udGVudCcsICdbdGlwdGFwIGVycm9yXTogSW52YWxpZCBIVE1MIGNvbnRlbnQnXS5pbmNsdWRlcyhlLm1lc3NhZ2UpKSB7XG4gICAgICAgIC8vIE5vdCB0aGUgY29udGVudCBlcnJvciB3ZSB3ZXJlIGV4cGVjdGluZ1xuICAgICAgICB0aHJvdyBlXG4gICAgICB9XG4gICAgICB0aGlzLmVtaXQoJ2NvbnRlbnRFcnJvcicsIHtcbiAgICAgICAgZWRpdG9yOiB0aGlzLFxuICAgICAgICBlcnJvcjogZSBhcyBFcnJvcixcbiAgICAgICAgZGlzYWJsZUNvbGxhYm9yYXRpb246ICgpID0+IHtcbiAgICAgICAgICBpZiAodGhpcy5zdG9yYWdlLmNvbGxhYm9yYXRpb24pIHtcbiAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5jb2xsYWJvcmF0aW9uLmlzRGlzYWJsZWQgPSB0cnVlXG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIFRvIGF2b2lkIHN5bmNpbmcgYmFjayBpbnZhbGlkIGNvbnRlbnQsIHJlaW5pdGlhbGl6ZSB0aGUgZXh0ZW5zaW9ucyB3aXRob3V0IHRoZSBjb2xsYWJvcmF0aW9uIGV4dGVuc2lvblxuICAgICAgICAgIHRoaXMub3B0aW9ucy5leHRlbnNpb25zID0gdGhpcy5vcHRpb25zLmV4dGVuc2lvbnMuZmlsdGVyKGV4dGVuc2lvbiA9PiBleHRlbnNpb24ubmFtZSAhPT0gJ2NvbGxhYm9yYXRpb24nKVxuXG4gICAgICAgICAgLy8gUmVzdGFydCB0aGUgaW5pdGlhbGl6YXRpb24gcHJvY2VzcyBieSByZWNyZWF0aW5nIHRoZSBleHRlbnNpb24gbWFuYWdlciB3aXRoIHRoZSBuZXcgc2V0IG9mIGV4dGVuc2lvbnNcbiAgICAgICAgICB0aGlzLmNyZWF0ZUV4dGVuc2lvbk1hbmFnZXIoKVxuICAgICAgICB9LFxuICAgICAgfSlcblxuICAgICAgLy8gQ29udGVudCBpcyBpbnZhbGlkLCBidXQgYXR0ZW1wdCB0byBjcmVhdGUgaXQgYW55d2F5LCBzdHJpcHBpbmcgb3V0IHRoZSBpbnZhbGlkIHBhcnRzXG4gICAgICBkb2MgPSBjcmVhdGVEb2N1bWVudChcbiAgICAgICAgdGhpcy5vcHRpb25zLmNvbnRlbnQsXG4gICAgICAgIHRoaXMuc2NoZW1hLFxuICAgICAgICB0aGlzLm9wdGlvbnMucGFyc2VPcHRpb25zLFxuICAgICAgICB7IGVycm9yT25JbnZhbGlkQ29udGVudDogZmFsc2UgfSxcbiAgICAgIClcbiAgICB9XG4gICAgY29uc3Qgc2VsZWN0aW9uID0gcmVzb2x2ZUZvY3VzUG9zaXRpb24oZG9jLCB0aGlzLm9wdGlvbnMuYXV0b2ZvY3VzKVxuXG4gICAgdGhpcy52aWV3ID0gbmV3IEVkaXRvclZpZXcodGhpcy5vcHRpb25zLmVsZW1lbnQsIHtcbiAgICAgIC4uLnRoaXMub3B0aW9ucy5lZGl0b3JQcm9wcyxcbiAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgLy8gYWRkIGByb2xlPVwidGV4dGJveFwiYCB0byB0aGUgZWRpdG9yIGVsZW1lbnRcbiAgICAgICAgcm9sZTogJ3RleHRib3gnLFxuICAgICAgICAuLi50aGlzLm9wdGlvbnMuZWRpdG9yUHJvcHM/LmF0dHJpYnV0ZXMsXG4gICAgICB9LFxuICAgICAgZGlzcGF0Y2hUcmFuc2FjdGlvbjogdGhpcy5kaXNwYXRjaFRyYW5zYWN0aW9uLmJpbmQodGhpcyksXG4gICAgICBzdGF0ZTogRWRpdG9yU3RhdGUuY3JlYXRlKHtcbiAgICAgICAgZG9jLFxuICAgICAgICBzZWxlY3Rpb246IHNlbGVjdGlvbiB8fCB1bmRlZmluZWQsXG4gICAgICB9KSxcbiAgICB9KVxuXG4gICAgLy8gYGVkaXRvci52aWV3YCBpcyBub3QgeWV0IGF2YWlsYWJsZSBhdCB0aGlzIHRpbWUuXG4gICAgLy8gVGhlcmVmb3JlIHdlIHdpbGwgYWRkIGFsbCBwbHVnaW5zIGFuZCBub2RlIHZpZXdzIGRpcmVjdGx5IGFmdGVyd2FyZHMuXG4gICAgY29uc3QgbmV3U3RhdGUgPSB0aGlzLnN0YXRlLnJlY29uZmlndXJlKHtcbiAgICAgIHBsdWdpbnM6IHRoaXMuZXh0ZW5zaW9uTWFuYWdlci5wbHVnaW5zLFxuICAgIH0pXG5cbiAgICB0aGlzLnZpZXcudXBkYXRlU3RhdGUobmV3U3RhdGUpXG5cbiAgICB0aGlzLmNyZWF0ZU5vZGVWaWV3cygpXG4gICAgdGhpcy5wcmVwZW5kQ2xhc3MoKVxuXG4gICAgLy8gTGV04oCZcyBzdG9yZSB0aGUgZWRpdG9yIGluc3RhbmNlIGluIHRoZSBET00gZWxlbWVudC5cbiAgICAvLyBTbyB3ZeKAmWxsIGhhdmUgYWNjZXNzIHRvIGl0IGZvciB0ZXN0cy5cbiAgICAvLyBAdHMtaWdub3JlXG4gICAgY29uc3QgZG9tID0gdGhpcy52aWV3LmRvbSBhcyBUaXB0YXBFZGl0b3JIVE1MRWxlbWVudFxuXG4gICAgZG9tLmVkaXRvciA9IHRoaXNcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGFsbCBub2RlIHZpZXdzLlxuICAgKi9cbiAgcHVibGljIGNyZWF0ZU5vZGVWaWV3cygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy52aWV3LmlzRGVzdHJveWVkKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0aGlzLnZpZXcuc2V0UHJvcHMoe1xuICAgICAgbm9kZVZpZXdzOiB0aGlzLmV4dGVuc2lvbk1hbmFnZXIubm9kZVZpZXdzLFxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogUHJlcGVuZCBjbGFzcyBuYW1lIHRvIGVsZW1lbnQuXG4gICAqL1xuICBwdWJsaWMgcHJlcGVuZENsYXNzKCk6IHZvaWQge1xuICAgIHRoaXMudmlldy5kb20uY2xhc3NOYW1lID0gYHRpcHRhcCAke3RoaXMudmlldy5kb20uY2xhc3NOYW1lfWBcbiAgfVxuXG4gIHB1YmxpYyBpc0NhcHR1cmluZ1RyYW5zYWN0aW9uID0gZmFsc2VcblxuICBwcml2YXRlIGNhcHR1cmVkVHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uIHwgbnVsbCA9IG51bGxcblxuICBwdWJsaWMgY2FwdHVyZVRyYW5zYWN0aW9uKGZuOiAoKSA9PiB2b2lkKSB7XG4gICAgdGhpcy5pc0NhcHR1cmluZ1RyYW5zYWN0aW9uID0gdHJ1ZVxuICAgIGZuKClcbiAgICB0aGlzLmlzQ2FwdHVyaW5nVHJhbnNhY3Rpb24gPSBmYWxzZVxuXG4gICAgY29uc3QgdHIgPSB0aGlzLmNhcHR1cmVkVHJhbnNhY3Rpb25cblxuICAgIHRoaXMuY2FwdHVyZWRUcmFuc2FjdGlvbiA9IG51bGxcblxuICAgIHJldHVybiB0clxuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBjYWxsYmFjayBvdmVyIHdoaWNoIHRvIHNlbmQgdHJhbnNhY3Rpb25zIChzdGF0ZSB1cGRhdGVzKSBwcm9kdWNlZCBieSB0aGUgdmlldy5cbiAgICpcbiAgICogQHBhcmFtIHRyYW5zYWN0aW9uIEFuIGVkaXRvciBzdGF0ZSB0cmFuc2FjdGlvblxuICAgKi9cbiAgcHJpdmF0ZSBkaXNwYXRjaFRyYW5zYWN0aW9uKHRyYW5zYWN0aW9uOiBUcmFuc2FjdGlvbik6IHZvaWQge1xuICAgIC8vIGlmIHRoZSBlZGl0b3IgLyB0aGUgdmlldyBvZiB0aGUgZWRpdG9yIHdhcyBkZXN0cm95ZWRcbiAgICAvLyB0aGUgdHJhbnNhY3Rpb24gc2hvdWxkIG5vdCBiZSBkaXNwYXRjaGVkIGFzIHRoZXJlIGlzIG5vIHZpZXcgYW55bW9yZS5cbiAgICBpZiAodGhpcy52aWV3LmlzRGVzdHJveWVkKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAodGhpcy5pc0NhcHR1cmluZ1RyYW5zYWN0aW9uKSB7XG4gICAgICBpZiAoIXRoaXMuY2FwdHVyZWRUcmFuc2FjdGlvbikge1xuICAgICAgICB0aGlzLmNhcHR1cmVkVHJhbnNhY3Rpb24gPSB0cmFuc2FjdGlvblxuXG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICB0cmFuc2FjdGlvbi5zdGVwcy5mb3JFYWNoKHN0ZXAgPT4gdGhpcy5jYXB0dXJlZFRyYW5zYWN0aW9uPy5zdGVwKHN0ZXApKVxuXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBzdGF0ZSA9IHRoaXMuc3RhdGUuYXBwbHkodHJhbnNhY3Rpb24pXG4gICAgY29uc3Qgc2VsZWN0aW9uSGFzQ2hhbmdlZCA9ICF0aGlzLnN0YXRlLnNlbGVjdGlvbi5lcShzdGF0ZS5zZWxlY3Rpb24pXG5cbiAgICB0aGlzLmVtaXQoJ2JlZm9yZVRyYW5zYWN0aW9uJywge1xuICAgICAgZWRpdG9yOiB0aGlzLFxuICAgICAgdHJhbnNhY3Rpb24sXG4gICAgICBuZXh0U3RhdGU6IHN0YXRlLFxuICAgIH0pXG4gICAgdGhpcy52aWV3LnVwZGF0ZVN0YXRlKHN0YXRlKVxuICAgIHRoaXMuZW1pdCgndHJhbnNhY3Rpb24nLCB7XG4gICAgICBlZGl0b3I6IHRoaXMsXG4gICAgICB0cmFuc2FjdGlvbixcbiAgICB9KVxuXG4gICAgaWYgKHNlbGVjdGlvbkhhc0NoYW5nZWQpIHtcbiAgICAgIHRoaXMuZW1pdCgnc2VsZWN0aW9uVXBkYXRlJywge1xuICAgICAgICBlZGl0b3I6IHRoaXMsXG4gICAgICAgIHRyYW5zYWN0aW9uLFxuICAgICAgfSlcbiAgICB9XG5cbiAgICBjb25zdCBmb2N1cyA9IHRyYW5zYWN0aW9uLmdldE1ldGEoJ2ZvY3VzJylcbiAgICBjb25zdCBibHVyID0gdHJhbnNhY3Rpb24uZ2V0TWV0YSgnYmx1cicpXG5cbiAgICBpZiAoZm9jdXMpIHtcbiAgICAgIHRoaXMuZW1pdCgnZm9jdXMnLCB7XG4gICAgICAgIGVkaXRvcjogdGhpcyxcbiAgICAgICAgZXZlbnQ6IGZvY3VzLmV2ZW50LFxuICAgICAgICB0cmFuc2FjdGlvbixcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgaWYgKGJsdXIpIHtcbiAgICAgIHRoaXMuZW1pdCgnYmx1cicsIHtcbiAgICAgICAgZWRpdG9yOiB0aGlzLFxuICAgICAgICBldmVudDogYmx1ci5ldmVudCxcbiAgICAgICAgdHJhbnNhY3Rpb24sXG4gICAgICB9KVxuICAgIH1cblxuICAgIGlmICghdHJhbnNhY3Rpb24uZG9jQ2hhbmdlZCB8fCB0cmFuc2FjdGlvbi5nZXRNZXRhKCdwcmV2ZW50VXBkYXRlJykpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRoaXMuZW1pdCgndXBkYXRlJywge1xuICAgICAgZWRpdG9yOiB0aGlzLFxuICAgICAgdHJhbnNhY3Rpb24sXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYXR0cmlidXRlcyBvZiB0aGUgY3VycmVudGx5IHNlbGVjdGVkIG5vZGUgb3IgbWFyay5cbiAgICovXG4gIHB1YmxpYyBnZXRBdHRyaWJ1dGVzKG5hbWVPclR5cGU6IHN0cmluZyB8IE5vZGVUeXBlIHwgTWFya1R5cGUpOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHtcbiAgICByZXR1cm4gZ2V0QXR0cmlidXRlcyh0aGlzLnN0YXRlLCBuYW1lT3JUeXBlKVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgaWYgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBub2RlIG9yIG1hcmsgaXMgYWN0aXZlLlxuICAgKlxuICAgKiBAcGFyYW0gbmFtZSBOYW1lIG9mIHRoZSBub2RlIG9yIG1hcmtcbiAgICogQHBhcmFtIGF0dHJpYnV0ZXMgQXR0cmlidXRlcyBvZiB0aGUgbm9kZSBvciBtYXJrXG4gICAqL1xuICBwdWJsaWMgaXNBY3RpdmUobmFtZTogc3RyaW5nLCBhdHRyaWJ1dGVzPzoge30pOiBib29sZWFuXG4gIHB1YmxpYyBpc0FjdGl2ZShhdHRyaWJ1dGVzOiB7fSk6IGJvb2xlYW5cbiAgcHVibGljIGlzQWN0aXZlKG5hbWVPckF0dHJpYnV0ZXM6IHN0cmluZywgYXR0cmlidXRlc09yVW5kZWZpbmVkPzoge30pOiBib29sZWFuIHtcbiAgICBjb25zdCBuYW1lID0gdHlwZW9mIG5hbWVPckF0dHJpYnV0ZXMgPT09ICdzdHJpbmcnID8gbmFtZU9yQXR0cmlidXRlcyA6IG51bGxcblxuICAgIGNvbnN0IGF0dHJpYnV0ZXMgPSB0eXBlb2YgbmFtZU9yQXR0cmlidXRlcyA9PT0gJ3N0cmluZycgPyBhdHRyaWJ1dGVzT3JVbmRlZmluZWQgOiBuYW1lT3JBdHRyaWJ1dGVzXG5cbiAgICByZXR1cm4gaXNBY3RpdmUodGhpcy5zdGF0ZSwgbmFtZSwgYXR0cmlidXRlcylcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGRvY3VtZW50IGFzIEpTT04uXG4gICAqL1xuICBwdWJsaWMgZ2V0SlNPTigpOiBKU09OQ29udGVudCB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGUuZG9jLnRvSlNPTigpXG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBkb2N1bWVudCBhcyBIVE1MLlxuICAgKi9cbiAgcHVibGljIGdldEhUTUwoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gZ2V0SFRNTEZyb21GcmFnbWVudCh0aGlzLnN0YXRlLmRvYy5jb250ZW50LCB0aGlzLnNjaGVtYSlcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGRvY3VtZW50IGFzIHRleHQuXG4gICAqL1xuICBwdWJsaWMgZ2V0VGV4dChvcHRpb25zPzoge1xuICAgIGJsb2NrU2VwYXJhdG9yPzogc3RyaW5nXG4gICAgdGV4dFNlcmlhbGl6ZXJzPzogUmVjb3JkPHN0cmluZywgVGV4dFNlcmlhbGl6ZXI+XG4gIH0pOiBzdHJpbmcge1xuICAgIGNvbnN0IHsgYmxvY2tTZXBhcmF0b3IgPSAnXFxuXFxuJywgdGV4dFNlcmlhbGl6ZXJzID0ge30gfSA9IG9wdGlvbnMgfHwge31cblxuICAgIHJldHVybiBnZXRUZXh0KHRoaXMuc3RhdGUuZG9jLCB7XG4gICAgICBibG9ja1NlcGFyYXRvcixcbiAgICAgIHRleHRTZXJpYWxpemVyczoge1xuICAgICAgICAuLi5nZXRUZXh0U2VyaWFsaXplcnNGcm9tU2NoZW1hKHRoaXMuc2NoZW1hKSxcbiAgICAgICAgLi4udGV4dFNlcmlhbGl6ZXJzLFxuICAgICAgfSxcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIHRoZXJlIGlzIG5vIGNvbnRlbnQuXG4gICAqL1xuICBwdWJsaWMgZ2V0IGlzRW1wdHkoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGlzTm9kZUVtcHR5KHRoaXMuc3RhdGUuZG9jKVxuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgZm9yIHRoZSBjdXJyZW50IGRvY3VtZW50LlxuICAgKlxuICAgKiBAZGVwcmVjYXRlZFxuICAgKi9cbiAgcHVibGljIGdldENoYXJhY3RlckNvdW50KCk6IG51bWJlciB7XG4gICAgY29uc29sZS53YXJuKFxuICAgICAgJ1t0aXB0YXAgd2Fybl06IFwiZWRpdG9yLmdldENoYXJhY3RlckNvdW50KClcIiBpcyBkZXByZWNhdGVkLiBQbGVhc2UgdXNlIFwiZWRpdG9yLnN0b3JhZ2UuY2hhcmFjdGVyQ291bnQuY2hhcmFjdGVycygpXCIgaW5zdGVhZC4nLFxuICAgIClcblxuICAgIHJldHVybiB0aGlzLnN0YXRlLmRvYy5jb250ZW50LnNpemUgLSAyXG4gIH1cblxuICAvKipcbiAgICogRGVzdHJveSB0aGUgZWRpdG9yLlxuICAgKi9cbiAgcHVibGljIGRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5lbWl0KCdkZXN0cm95JylcblxuICAgIGlmICh0aGlzLnZpZXcpIHtcbiAgICAgIC8vIENsZWFudXAgb3VyIHJlZmVyZW5jZSB0byBwcmV2ZW50IGNpcmN1bGFyIHJlZmVyZW5jZXMgd2hpY2ggY2F1c2VkIG1lbW9yeSBsZWFrc1xuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgY29uc3QgZG9tID0gdGhpcy52aWV3LmRvbSBhcyBUaXB0YXBFZGl0b3JIVE1MRWxlbWVudFxuXG4gICAgICBpZiAoZG9tICYmIGRvbS5lZGl0b3IpIHtcbiAgICAgICAgZGVsZXRlIGRvbS5lZGl0b3JcbiAgICAgIH1cbiAgICAgIHRoaXMudmlldy5kZXN0cm95KClcbiAgICB9XG5cbiAgICB0aGlzLnJlbW92ZUFsbExpc3RlbmVycygpXG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgdGhlIGVkaXRvciBpcyBhbHJlYWR5IGRlc3Ryb3llZC5cbiAgICovXG4gIHB1YmxpYyBnZXQgaXNEZXN0cm95ZWQoKTogYm9vbGVhbiB7XG4gICAgLy8gQHRzLWlnbm9yZVxuICAgIHJldHVybiAhdGhpcy52aWV3Py5kb2NWaWV3XG4gIH1cblxuICBwdWJsaWMgJG5vZGUoc2VsZWN0b3I6IHN0cmluZywgYXR0cmlidXRlcz86IHsgW2tleTogc3RyaW5nXTogYW55IH0pOiBOb2RlUG9zIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuJGRvYz8ucXVlcnlTZWxlY3RvcihzZWxlY3RvciwgYXR0cmlidXRlcykgfHwgbnVsbFxuICB9XG5cbiAgcHVibGljICRub2RlcyhzZWxlY3Rvcjogc3RyaW5nLCBhdHRyaWJ1dGVzPzogeyBba2V5OiBzdHJpbmddOiBhbnkgfSk6IE5vZGVQb3NbXSB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLiRkb2M/LnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IsIGF0dHJpYnV0ZXMpIHx8IG51bGxcbiAgfVxuXG4gIHB1YmxpYyAkcG9zKHBvczogbnVtYmVyKSB7XG4gICAgY29uc3QgJHBvcyA9IHRoaXMuc3RhdGUuZG9jLnJlc29sdmUocG9zKVxuXG4gICAgcmV0dXJuIG5ldyBOb2RlUG9zKCRwb3MsIHRoaXMpXG4gIH1cblxuICBnZXQgJGRvYygpIHtcbiAgICByZXR1cm4gdGhpcy4kcG9zKDApXG4gIH1cbn1cbiIsICJpbXBvcnQgeyBNYXJrVHlwZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmltcG9ydCB7IGdldE1hcmtzQmV0d2VlbiB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0TWFya3NCZXR3ZWVuLmpzJ1xuaW1wb3J0IHsgSW5wdXRSdWxlLCBJbnB1dFJ1bGVGaW5kZXIgfSBmcm9tICcuLi9JbnB1dFJ1bGUuanMnXG5pbXBvcnQgeyBFeHRlbmRlZFJlZ0V4cE1hdGNoQXJyYXkgfSBmcm9tICcuLi90eXBlcy5qcydcbmltcG9ydCB7IGNhbGxPclJldHVybiB9IGZyb20gJy4uL3V0aWxpdGllcy9jYWxsT3JSZXR1cm4uanMnXG5cbi8qKlxuICogQnVpbGQgYW4gaW5wdXQgcnVsZSB0aGF0IGFkZHMgYSBtYXJrIHdoZW4gdGhlXG4gKiBtYXRjaGVkIHRleHQgaXMgdHlwZWQgaW50byBpdC5cbiAqIEBzZWUgaHR0cHM6Ly90aXB0YXAuZGV2L2RvY3MvZWRpdG9yL2V4dGVuc2lvbnMvY3VzdG9tLWV4dGVuc2lvbnMvZXh0ZW5kLWV4aXN0aW5nI2lucHV0LXJ1bGVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXJrSW5wdXRSdWxlKGNvbmZpZzoge1xuICBmaW5kOiBJbnB1dFJ1bGVGaW5kZXJcbiAgdHlwZTogTWFya1R5cGVcbiAgZ2V0QXR0cmlidXRlcz86XG4gICAgfCBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gICAgfCAoKG1hdGNoOiBFeHRlbmRlZFJlZ0V4cE1hdGNoQXJyYXkpID0+IFJlY29yZDxzdHJpbmcsIGFueT4pXG4gICAgfCBmYWxzZVxuICAgIHwgbnVsbFxufSkge1xuICByZXR1cm4gbmV3IElucHV0UnVsZSh7XG4gICAgZmluZDogY29uZmlnLmZpbmQsXG4gICAgaGFuZGxlcjogKHsgc3RhdGUsIHJhbmdlLCBtYXRjaCB9KSA9PiB7XG4gICAgICBjb25zdCBhdHRyaWJ1dGVzID0gY2FsbE9yUmV0dXJuKGNvbmZpZy5nZXRBdHRyaWJ1dGVzLCB1bmRlZmluZWQsIG1hdGNoKVxuXG4gICAgICBpZiAoYXR0cmlidXRlcyA9PT0gZmFsc2UgfHwgYXR0cmlidXRlcyA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgfVxuXG4gICAgICBjb25zdCB7IHRyIH0gPSBzdGF0ZVxuICAgICAgY29uc3QgY2FwdHVyZUdyb3VwID0gbWF0Y2hbbWF0Y2gubGVuZ3RoIC0gMV1cbiAgICAgIGNvbnN0IGZ1bGxNYXRjaCA9IG1hdGNoWzBdXG5cbiAgICAgIGlmIChjYXB0dXJlR3JvdXApIHtcbiAgICAgICAgY29uc3Qgc3RhcnRTcGFjZXMgPSBmdWxsTWF0Y2guc2VhcmNoKC9cXFMvKVxuICAgICAgICBjb25zdCB0ZXh0U3RhcnQgPSByYW5nZS5mcm9tICsgZnVsbE1hdGNoLmluZGV4T2YoY2FwdHVyZUdyb3VwKVxuICAgICAgICBjb25zdCB0ZXh0RW5kID0gdGV4dFN0YXJ0ICsgY2FwdHVyZUdyb3VwLmxlbmd0aFxuXG4gICAgICAgIGNvbnN0IGV4Y2x1ZGVkTWFya3MgPSBnZXRNYXJrc0JldHdlZW4ocmFuZ2UuZnJvbSwgcmFuZ2UudG8sIHN0YXRlLmRvYylcbiAgICAgICAgICAuZmlsdGVyKGl0ZW0gPT4ge1xuICAgICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgICAgY29uc3QgZXhjbHVkZWQgPSBpdGVtLm1hcmsudHlwZS5leGNsdWRlZCBhcyBNYXJrVHlwZVtdXG5cbiAgICAgICAgICAgIHJldHVybiBleGNsdWRlZC5maW5kKHR5cGUgPT4gdHlwZSA9PT0gY29uZmlnLnR5cGUgJiYgdHlwZSAhPT0gaXRlbS5tYXJrLnR5cGUpXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuZmlsdGVyKGl0ZW0gPT4gaXRlbS50byA+IHRleHRTdGFydClcblxuICAgICAgICBpZiAoZXhjbHVkZWRNYXJrcy5sZW5ndGgpIHtcbiAgICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRleHRFbmQgPCByYW5nZS50bykge1xuICAgICAgICAgIHRyLmRlbGV0ZSh0ZXh0RW5kLCByYW5nZS50bylcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0ZXh0U3RhcnQgPiByYW5nZS5mcm9tKSB7XG4gICAgICAgICAgdHIuZGVsZXRlKHJhbmdlLmZyb20gKyBzdGFydFNwYWNlcywgdGV4dFN0YXJ0KVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbWFya0VuZCA9IHJhbmdlLmZyb20gKyBzdGFydFNwYWNlcyArIGNhcHR1cmVHcm91cC5sZW5ndGhcblxuICAgICAgICB0ci5hZGRNYXJrKHJhbmdlLmZyb20gKyBzdGFydFNwYWNlcywgbWFya0VuZCwgY29uZmlnLnR5cGUuY3JlYXRlKGF0dHJpYnV0ZXMgfHwge30pKVxuXG4gICAgICAgIHRyLnJlbW92ZVN0b3JlZE1hcmsoY29uZmlnLnR5cGUpXG4gICAgICB9XG4gICAgfSxcbiAgfSlcbn1cbiIsICJpbXBvcnQgeyBOb2RlVHlwZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmltcG9ydCB7IElucHV0UnVsZSwgSW5wdXRSdWxlRmluZGVyIH0gZnJvbSAnLi4vSW5wdXRSdWxlLmpzJ1xuaW1wb3J0IHsgRXh0ZW5kZWRSZWdFeHBNYXRjaEFycmF5IH0gZnJvbSAnLi4vdHlwZXMuanMnXG5pbXBvcnQgeyBjYWxsT3JSZXR1cm4gfSBmcm9tICcuLi91dGlsaXRpZXMvY2FsbE9yUmV0dXJuLmpzJ1xuXG4vKipcbiAqIEJ1aWxkIGFuIGlucHV0IHJ1bGUgdGhhdCBhZGRzIGEgbm9kZSB3aGVuIHRoZVxuICogbWF0Y2hlZCB0ZXh0IGlzIHR5cGVkIGludG8gaXQuXG4gKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9kb2NzL2VkaXRvci9leHRlbnNpb25zL2N1c3RvbS1leHRlbnNpb25zL2V4dGVuZC1leGlzdGluZyNpbnB1dC1ydWxlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gbm9kZUlucHV0UnVsZShjb25maWc6IHtcbiAgLyoqXG4gICAqIFRoZSByZWdleCB0byBtYXRjaC5cbiAgICovXG4gIGZpbmQ6IElucHV0UnVsZUZpbmRlclxuXG4gIC8qKlxuICAgKiBUaGUgbm9kZSB0eXBlIHRvIGFkZC5cbiAgICovXG4gIHR5cGU6IE5vZGVUeXBlXG5cbiAgLyoqXG4gICAqIEEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSBhdHRyaWJ1dGVzIGZvciB0aGUgbm9kZVxuICAgKiBjYW4gYWxzbyBiZSBhbiBvYmplY3Qgb2YgYXR0cmlidXRlc1xuICAgKi9cbiAgZ2V0QXR0cmlidXRlcz86XG4gICAgfCBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gICAgfCAoKG1hdGNoOiBFeHRlbmRlZFJlZ0V4cE1hdGNoQXJyYXkpID0+IFJlY29yZDxzdHJpbmcsIGFueT4pXG4gICAgfCBmYWxzZVxuICAgIHwgbnVsbFxufSkge1xuICByZXR1cm4gbmV3IElucHV0UnVsZSh7XG4gICAgZmluZDogY29uZmlnLmZpbmQsXG4gICAgaGFuZGxlcjogKHsgc3RhdGUsIHJhbmdlLCBtYXRjaCB9KSA9PiB7XG4gICAgICBjb25zdCBhdHRyaWJ1dGVzID0gY2FsbE9yUmV0dXJuKGNvbmZpZy5nZXRBdHRyaWJ1dGVzLCB1bmRlZmluZWQsIG1hdGNoKSB8fCB7fVxuICAgICAgY29uc3QgeyB0ciB9ID0gc3RhdGVcbiAgICAgIGNvbnN0IHN0YXJ0ID0gcmFuZ2UuZnJvbVxuICAgICAgbGV0IGVuZCA9IHJhbmdlLnRvXG5cbiAgICAgIGNvbnN0IG5ld05vZGUgPSBjb25maWcudHlwZS5jcmVhdGUoYXR0cmlidXRlcylcblxuICAgICAgaWYgKG1hdGNoWzFdKSB7XG4gICAgICAgIGNvbnN0IG9mZnNldCA9IG1hdGNoWzBdLmxhc3RJbmRleE9mKG1hdGNoWzFdKVxuICAgICAgICBsZXQgbWF0Y2hTdGFydCA9IHN0YXJ0ICsgb2Zmc2V0XG5cbiAgICAgICAgaWYgKG1hdGNoU3RhcnQgPiBlbmQpIHtcbiAgICAgICAgICBtYXRjaFN0YXJ0ID0gZW5kXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZW5kID0gbWF0Y2hTdGFydCArIG1hdGNoWzFdLmxlbmd0aFxuICAgICAgICB9XG5cbiAgICAgICAgLy8gaW5zZXJ0IGxhc3QgdHlwZWQgY2hhcmFjdGVyXG4gICAgICAgIGNvbnN0IGxhc3RDaGFyID0gbWF0Y2hbMF1bbWF0Y2hbMF0ubGVuZ3RoIC0gMV1cblxuICAgICAgICB0ci5pbnNlcnRUZXh0KGxhc3RDaGFyLCBzdGFydCArIG1hdGNoWzBdLmxlbmd0aCAtIDEpXG5cbiAgICAgICAgLy8gaW5zZXJ0IG5vZGUgZnJvbSBpbnB1dCBydWxlXG4gICAgICAgIHRyLnJlcGxhY2VXaXRoKG1hdGNoU3RhcnQsIGVuZCwgbmV3Tm9kZSlcbiAgICAgIH0gZWxzZSBpZiAobWF0Y2hbMF0pIHtcbiAgICAgICAgY29uc3QgaW5zZXJ0aW9uU3RhcnQgPSBjb25maWcudHlwZS5pc0lubGluZSA/IHN0YXJ0IDogc3RhcnQgLSAxXG5cbiAgICAgICAgdHIuaW5zZXJ0KGluc2VydGlvblN0YXJ0LCBjb25maWcudHlwZS5jcmVhdGUoYXR0cmlidXRlcykpLmRlbGV0ZShcbiAgICAgICAgICB0ci5tYXBwaW5nLm1hcChzdGFydCksXG4gICAgICAgICAgdHIubWFwcGluZy5tYXAoZW5kKSxcbiAgICAgICAgKVxuICAgICAgfVxuXG4gICAgICB0ci5zY3JvbGxJbnRvVmlldygpXG4gICAgfSxcbiAgfSlcbn1cbiIsICJpbXBvcnQgeyBOb2RlVHlwZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmltcG9ydCB7IElucHV0UnVsZSwgSW5wdXRSdWxlRmluZGVyIH0gZnJvbSAnLi4vSW5wdXRSdWxlLmpzJ1xuaW1wb3J0IHsgRXh0ZW5kZWRSZWdFeHBNYXRjaEFycmF5IH0gZnJvbSAnLi4vdHlwZXMuanMnXG5pbXBvcnQgeyBjYWxsT3JSZXR1cm4gfSBmcm9tICcuLi91dGlsaXRpZXMvY2FsbE9yUmV0dXJuLmpzJ1xuXG4vKipcbiAqIEJ1aWxkIGFuIGlucHV0IHJ1bGUgdGhhdCBjaGFuZ2VzIHRoZSB0eXBlIG9mIGEgdGV4dGJsb2NrIHdoZW4gdGhlXG4gKiBtYXRjaGVkIHRleHQgaXMgdHlwZWQgaW50byBpdC4gV2hlbiB1c2luZyBhIHJlZ3VsYXIgZXhwcmVzaW9uIHlvdeKAmWxsXG4gKiBwcm9iYWJseSB3YW50IHRoZSByZWdleHAgdG8gc3RhcnQgd2l0aCBgXmAsIHNvIHRoYXQgdGhlIHBhdHRlcm4gY2FuXG4gKiBvbmx5IG9jY3VyIGF0IHRoZSBzdGFydCBvZiBhIHRleHRibG9jay5cbiAqIEBzZWUgaHR0cHM6Ly90aXB0YXAuZGV2L2RvY3MvZWRpdG9yL2V4dGVuc2lvbnMvY3VzdG9tLWV4dGVuc2lvbnMvZXh0ZW5kLWV4aXN0aW5nI2lucHV0LXJ1bGVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0ZXh0YmxvY2tUeXBlSW5wdXRSdWxlKGNvbmZpZzoge1xuICBmaW5kOiBJbnB1dFJ1bGVGaW5kZXJcbiAgdHlwZTogTm9kZVR5cGVcbiAgZ2V0QXR0cmlidXRlcz86XG4gICAgfCBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gICAgfCAoKG1hdGNoOiBFeHRlbmRlZFJlZ0V4cE1hdGNoQXJyYXkpID0+IFJlY29yZDxzdHJpbmcsIGFueT4pXG4gICAgfCBmYWxzZVxuICAgIHwgbnVsbFxufSkge1xuICByZXR1cm4gbmV3IElucHV0UnVsZSh7XG4gICAgZmluZDogY29uZmlnLmZpbmQsXG4gICAgaGFuZGxlcjogKHsgc3RhdGUsIHJhbmdlLCBtYXRjaCB9KSA9PiB7XG4gICAgICBjb25zdCAkc3RhcnQgPSBzdGF0ZS5kb2MucmVzb2x2ZShyYW5nZS5mcm9tKVxuICAgICAgY29uc3QgYXR0cmlidXRlcyA9IGNhbGxPclJldHVybihjb25maWcuZ2V0QXR0cmlidXRlcywgdW5kZWZpbmVkLCBtYXRjaCkgfHwge31cblxuICAgICAgaWYgKCEkc3RhcnQubm9kZSgtMSkuY2FuUmVwbGFjZVdpdGgoJHN0YXJ0LmluZGV4KC0xKSwgJHN0YXJ0LmluZGV4QWZ0ZXIoLTEpLCBjb25maWcudHlwZSkpIHtcbiAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgIH1cblxuICAgICAgc3RhdGUudHJcbiAgICAgICAgLmRlbGV0ZShyYW5nZS5mcm9tLCByYW5nZS50bylcbiAgICAgICAgLnNldEJsb2NrVHlwZShyYW5nZS5mcm9tLCByYW5nZS5mcm9tLCBjb25maWcudHlwZSwgYXR0cmlidXRlcylcbiAgICB9LFxuICB9KVxufVxuIiwgImltcG9ydCB7IElucHV0UnVsZSwgSW5wdXRSdWxlRmluZGVyIH0gZnJvbSAnLi4vSW5wdXRSdWxlLmpzJ1xuXG4vKipcbiAqIEJ1aWxkIGFuIGlucHV0IHJ1bGUgdGhhdCByZXBsYWNlcyB0ZXh0IHdoZW4gdGhlXG4gKiBtYXRjaGVkIHRleHQgaXMgdHlwZWQgaW50byBpdC5cbiAqIEBzZWUgaHR0cHM6Ly90aXB0YXAuZGV2L2RvY3MvZWRpdG9yL2V4dGVuc2lvbnMvY3VzdG9tLWV4dGVuc2lvbnMvZXh0ZW5kLWV4aXN0aW5nI2lucHV0LXJ1bGVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0ZXh0SW5wdXRSdWxlKGNvbmZpZzoge1xuICBmaW5kOiBJbnB1dFJ1bGVGaW5kZXIsXG4gIHJlcGxhY2U6IHN0cmluZyxcbn0pIHtcbiAgcmV0dXJuIG5ldyBJbnB1dFJ1bGUoe1xuICAgIGZpbmQ6IGNvbmZpZy5maW5kLFxuICAgIGhhbmRsZXI6ICh7IHN0YXRlLCByYW5nZSwgbWF0Y2ggfSkgPT4ge1xuICAgICAgbGV0IGluc2VydCA9IGNvbmZpZy5yZXBsYWNlXG4gICAgICBsZXQgc3RhcnQgPSByYW5nZS5mcm9tXG4gICAgICBjb25zdCBlbmQgPSByYW5nZS50b1xuXG4gICAgICBpZiAobWF0Y2hbMV0pIHtcbiAgICAgICAgY29uc3Qgb2Zmc2V0ID0gbWF0Y2hbMF0ubGFzdEluZGV4T2YobWF0Y2hbMV0pXG5cbiAgICAgICAgaW5zZXJ0ICs9IG1hdGNoWzBdLnNsaWNlKG9mZnNldCArIG1hdGNoWzFdLmxlbmd0aClcbiAgICAgICAgc3RhcnQgKz0gb2Zmc2V0XG5cbiAgICAgICAgY29uc3QgY3V0T2ZmID0gc3RhcnQgLSBlbmRcblxuICAgICAgICBpZiAoY3V0T2ZmID4gMCkge1xuICAgICAgICAgIGluc2VydCA9IG1hdGNoWzBdLnNsaWNlKG9mZnNldCAtIGN1dE9mZiwgb2Zmc2V0KSArIGluc2VydFxuICAgICAgICAgIHN0YXJ0ID0gZW5kXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgc3RhdGUudHIuaW5zZXJ0VGV4dChpbnNlcnQsIHN0YXJ0LCBlbmQpXG4gICAgfSxcbiAgfSlcbn1cbiIsICJpbXBvcnQgeyBOb2RlIGFzIFByb3NlTWlycm9yTm9kZSwgTm9kZVR5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuaW1wb3J0IHsgY2FuSm9pbiwgZmluZFdyYXBwaW5nIH0gZnJvbSAnQHRpcHRhcC9wbS90cmFuc2Zvcm0nXG5cbmltcG9ydCB7IEVkaXRvciB9IGZyb20gJy4uL0VkaXRvci5qcydcbmltcG9ydCB7IElucHV0UnVsZSwgSW5wdXRSdWxlRmluZGVyIH0gZnJvbSAnLi4vSW5wdXRSdWxlLmpzJ1xuaW1wb3J0IHsgRXh0ZW5kZWRSZWdFeHBNYXRjaEFycmF5IH0gZnJvbSAnLi4vdHlwZXMuanMnXG5pbXBvcnQgeyBjYWxsT3JSZXR1cm4gfSBmcm9tICcuLi91dGlsaXRpZXMvY2FsbE9yUmV0dXJuLmpzJ1xuXG4vKipcbiAqIEJ1aWxkIGFuIGlucHV0IHJ1bGUgZm9yIGF1dG9tYXRpY2FsbHkgd3JhcHBpbmcgYSB0ZXh0YmxvY2sgd2hlbiBhXG4gKiBnaXZlbiBzdHJpbmcgaXMgdHlwZWQuIFdoZW4gdXNpbmcgYSByZWd1bGFyIGV4cHJlc2lvbiB5b3XigJlsbFxuICogcHJvYmFibHkgd2FudCB0aGUgcmVnZXhwIHRvIHN0YXJ0IHdpdGggYF5gLCBzbyB0aGF0IHRoZSBwYXR0ZXJuIGNhblxuICogb25seSBvY2N1ciBhdCB0aGUgc3RhcnQgb2YgYSB0ZXh0YmxvY2suXG4gKlxuICogYHR5cGVgIGlzIHRoZSB0eXBlIG9mIG5vZGUgdG8gd3JhcCBpbi5cbiAqXG4gKiBCeSBkZWZhdWx0LCBpZiB0aGVyZeKAmXMgYSBub2RlIHdpdGggdGhlIHNhbWUgdHlwZSBhYm92ZSB0aGUgbmV3bHlcbiAqIHdyYXBwZWQgbm9kZSwgdGhlIHJ1bGUgd2lsbCB0cnkgdG8gam9pbiB0aG9zZVxuICogdHdvIG5vZGVzLiBZb3UgY2FuIHBhc3MgYSBqb2luIHByZWRpY2F0ZSwgd2hpY2ggdGFrZXMgYSByZWd1bGFyXG4gKiBleHByZXNzaW9uIG1hdGNoIGFuZCB0aGUgbm9kZSBiZWZvcmUgdGhlIHdyYXBwZWQgbm9kZSwgYW5kIGNhblxuICogcmV0dXJuIGEgYm9vbGVhbiB0byBpbmRpY2F0ZSB3aGV0aGVyIGEgam9pbiBzaG91bGQgaGFwcGVuLlxuICogQHNlZSBodHRwczovL3RpcHRhcC5kZXYvZG9jcy9lZGl0b3IvZXh0ZW5zaW9ucy9jdXN0b20tZXh0ZW5zaW9ucy9leHRlbmQtZXhpc3RpbmcjaW5wdXQtcnVsZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdyYXBwaW5nSW5wdXRSdWxlKGNvbmZpZzoge1xuICBmaW5kOiBJbnB1dFJ1bGVGaW5kZXIsXG4gIHR5cGU6IE5vZGVUeXBlLFxuICBrZWVwTWFya3M/OiBib29sZWFuLFxuICBrZWVwQXR0cmlidXRlcz86IGJvb2xlYW4sXG4gIGVkaXRvcj86IEVkaXRvclxuICBnZXRBdHRyaWJ1dGVzPzpcbiAgfCBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gIHwgKChtYXRjaDogRXh0ZW5kZWRSZWdFeHBNYXRjaEFycmF5KSA9PiBSZWNvcmQ8c3RyaW5nLCBhbnk+KVxuICB8IGZhbHNlXG4gIHwgbnVsbFxuICAsXG4gIGpvaW5QcmVkaWNhdGU/OiAobWF0Y2g6IEV4dGVuZGVkUmVnRXhwTWF0Y2hBcnJheSwgbm9kZTogUHJvc2VNaXJyb3JOb2RlKSA9PiBib29sZWFuLFxufSkge1xuICByZXR1cm4gbmV3IElucHV0UnVsZSh7XG4gICAgZmluZDogY29uZmlnLmZpbmQsXG4gICAgaGFuZGxlcjogKHtcbiAgICAgIHN0YXRlLCByYW5nZSwgbWF0Y2gsIGNoYWluLFxuICAgIH0pID0+IHtcbiAgICAgIGNvbnN0IGF0dHJpYnV0ZXMgPSBjYWxsT3JSZXR1cm4oY29uZmlnLmdldEF0dHJpYnV0ZXMsIHVuZGVmaW5lZCwgbWF0Y2gpIHx8IHt9XG4gICAgICBjb25zdCB0ciA9IHN0YXRlLnRyLmRlbGV0ZShyYW5nZS5mcm9tLCByYW5nZS50bylcbiAgICAgIGNvbnN0ICRzdGFydCA9IHRyLmRvYy5yZXNvbHZlKHJhbmdlLmZyb20pXG4gICAgICBjb25zdCBibG9ja1JhbmdlID0gJHN0YXJ0LmJsb2NrUmFuZ2UoKVxuICAgICAgY29uc3Qgd3JhcHBpbmcgPSBibG9ja1JhbmdlICYmIGZpbmRXcmFwcGluZyhibG9ja1JhbmdlLCBjb25maWcudHlwZSwgYXR0cmlidXRlcylcblxuICAgICAgaWYgKCF3cmFwcGluZykge1xuICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgfVxuXG4gICAgICB0ci53cmFwKGJsb2NrUmFuZ2UsIHdyYXBwaW5nKVxuXG4gICAgICBpZiAoY29uZmlnLmtlZXBNYXJrcyAmJiBjb25maWcuZWRpdG9yKSB7XG4gICAgICAgIGNvbnN0IHsgc2VsZWN0aW9uLCBzdG9yZWRNYXJrcyB9ID0gc3RhdGVcbiAgICAgICAgY29uc3QgeyBzcGxpdHRhYmxlTWFya3MgfSA9IGNvbmZpZy5lZGl0b3IuZXh0ZW5zaW9uTWFuYWdlclxuICAgICAgICBjb25zdCBtYXJrcyA9IHN0b3JlZE1hcmtzIHx8IChzZWxlY3Rpb24uJHRvLnBhcmVudE9mZnNldCAmJiBzZWxlY3Rpb24uJGZyb20ubWFya3MoKSlcblxuICAgICAgICBpZiAobWFya3MpIHtcbiAgICAgICAgICBjb25zdCBmaWx0ZXJlZE1hcmtzID0gbWFya3MuZmlsdGVyKG1hcmsgPT4gc3BsaXR0YWJsZU1hcmtzLmluY2x1ZGVzKG1hcmsudHlwZS5uYW1lKSlcblxuICAgICAgICAgIHRyLmVuc3VyZU1hcmtzKGZpbHRlcmVkTWFya3MpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChjb25maWcua2VlcEF0dHJpYnV0ZXMpIHtcbiAgICAgICAgLyoqIElmIHRoZSBub2RlVHlwZSBpcyBgYnVsbGV0TGlzdGAgb3IgYG9yZGVyZWRMaXN0YCBzZXQgdGhlIGBub2RlVHlwZWAgYXMgYGxpc3RJdGVtYCAqL1xuICAgICAgICBjb25zdCBub2RlVHlwZSA9IGNvbmZpZy50eXBlLm5hbWUgPT09ICdidWxsZXRMaXN0JyB8fCBjb25maWcudHlwZS5uYW1lID09PSAnb3JkZXJlZExpc3QnID8gJ2xpc3RJdGVtJyA6ICd0YXNrTGlzdCdcblxuICAgICAgICBjaGFpbigpLnVwZGF0ZUF0dHJpYnV0ZXMobm9kZVR5cGUsIGF0dHJpYnV0ZXMpLnJ1bigpXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGJlZm9yZSA9IHRyLmRvYy5yZXNvbHZlKHJhbmdlLmZyb20gLSAxKS5ub2RlQmVmb3JlXG5cbiAgICAgIGlmIChcbiAgICAgICAgYmVmb3JlXG4gICAgICAgICYmIGJlZm9yZS50eXBlID09PSBjb25maWcudHlwZVxuICAgICAgICAmJiBjYW5Kb2luKHRyLmRvYywgcmFuZ2UuZnJvbSAtIDEpXG4gICAgICAgICYmICghY29uZmlnLmpvaW5QcmVkaWNhdGUgfHwgY29uZmlnLmpvaW5QcmVkaWNhdGUobWF0Y2gsIGJlZm9yZSkpXG4gICAgICApIHtcbiAgICAgICAgdHIuam9pbihyYW5nZS5mcm9tIC0gMSlcbiAgICAgIH1cbiAgICB9LFxuICB9KVxufVxuIiwgImltcG9ydCB7XG4gIERPTU91dHB1dFNwZWMsIE5vZGUgYXMgUHJvc2VNaXJyb3JOb2RlLCBOb2RlU3BlYywgTm9kZVR5cGUsXG59IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5pbXBvcnQgeyBQbHVnaW4sIFRyYW5zYWN0aW9uIH0gZnJvbSAnQHRpcHRhcC9wbS9zdGF0ZSdcblxuaW1wb3J0IHsgRWRpdG9yIH0gZnJvbSAnLi9FZGl0b3IuanMnXG5pbXBvcnQgeyBnZXRFeHRlbnNpb25GaWVsZCB9IGZyb20gJy4vaGVscGVycy9nZXRFeHRlbnNpb25GaWVsZC5qcydcbmltcG9ydCB7IE5vZGVDb25maWcgfSBmcm9tICcuL2luZGV4LmpzJ1xuaW1wb3J0IHsgSW5wdXRSdWxlIH0gZnJvbSAnLi9JbnB1dFJ1bGUuanMnXG5pbXBvcnQgeyBNYXJrIH0gZnJvbSAnLi9NYXJrLmpzJ1xuaW1wb3J0IHsgUGFzdGVSdWxlIH0gZnJvbSAnLi9QYXN0ZVJ1bGUuanMnXG5pbXBvcnQge1xuICBBbnlDb25maWcsXG4gIEF0dHJpYnV0ZXMsXG4gIEV4dGVuc2lvbnMsXG4gIEdsb2JhbEF0dHJpYnV0ZXMsXG4gIEtleWJvYXJkU2hvcnRjdXRDb21tYW5kLFxuICBOb2RlVmlld1JlbmRlcmVyLFxuICBQYXJlbnRDb25maWcsXG4gIFJhd0NvbW1hbmRzLFxufSBmcm9tICcuL3R5cGVzLmpzJ1xuaW1wb3J0IHsgY2FsbE9yUmV0dXJuIH0gZnJvbSAnLi91dGlsaXRpZXMvY2FsbE9yUmV0dXJuLmpzJ1xuaW1wb3J0IHsgbWVyZ2VEZWVwIH0gZnJvbSAnLi91dGlsaXRpZXMvbWVyZ2VEZWVwLmpzJ1xuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBOb2RlQ29uZmlnPE9wdGlvbnMgPSBhbnksIFN0b3JhZ2UgPSBhbnk+IHtcbiAgICAvLyBAdHMtaWdub3JlIC0gdGhpcyBpcyBhIGR5bmFtaWMga2V5XG4gICAgW2tleTogc3RyaW5nXTogYW55XG5cbiAgICAvKipcbiAgICAgKiBUaGUgZXh0ZW5zaW9uIG5hbWUgLSB0aGlzIG11c3QgYmUgdW5pcXVlLlxuICAgICAqIEl0IHdpbGwgYmUgdXNlZCB0byBpZGVudGlmeSB0aGUgZXh0ZW5zaW9uLlxuICAgICAqXG4gICAgICogQGV4YW1wbGUgJ215RXh0ZW5zaW9uJ1xuICAgICAqL1xuICAgIG5hbWU6IHN0cmluZ1xuXG4gICAgLyoqXG4gICAgICogVGhlIHByaW9yaXR5IG9mIHlvdXIgZXh0ZW5zaW9uLiBUaGUgaGlnaGVyLCB0aGUgZWFybGllciBpdCB3aWxsIGJlIGNhbGxlZFxuICAgICAqIGFuZCB3aWxsIHRha2UgcHJlY2VkZW5jZSBvdmVyIG90aGVyIGV4dGVuc2lvbnMgd2l0aCBhIGxvd2VyIHByaW9yaXR5LlxuICAgICAqIEBkZWZhdWx0IDEwMFxuICAgICAqIEBleGFtcGxlIDEwMVxuICAgICAqL1xuICAgIHByaW9yaXR5PzogbnVtYmVyXG5cbiAgICAvKipcbiAgICAgKiBUaGUgZGVmYXVsdCBvcHRpb25zIGZvciB0aGlzIGV4dGVuc2lvbi5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGRlZmF1bHRPcHRpb25zOiB7XG4gICAgICogICBteU9wdGlvbjogJ2ZvbycsXG4gICAgICogICBteU90aGVyT3B0aW9uOiAxMCxcbiAgICAgKiB9XG4gICAgICovXG4gICAgZGVmYXVsdE9wdGlvbnM/OiBPcHRpb25zXG5cbiAgICAvKipcbiAgICAgKiBUaGlzIG1ldGhvZCB3aWxsIGFkZCBvcHRpb25zIHRvIHRoaXMgZXh0ZW5zaW9uXG4gICAgICogQHNlZSBodHRwczovL3RpcHRhcC5kZXYvZ3VpZGUvY3VzdG9tLWV4dGVuc2lvbnMjc2V0dGluZ3NcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGFkZE9wdGlvbnMoKSB7XG4gICAgICogIHJldHVybiB7XG4gICAgICogICAgbXlPcHRpb246ICdmb28nLFxuICAgICAqICAgIG15T3RoZXJPcHRpb246IDEwLFxuICAgICAqIH1cbiAgICAgKi9cbiAgICBhZGRPcHRpb25zPzogKHRoaXM6IHtcbiAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgcGFyZW50OiBFeGNsdWRlPFBhcmVudENvbmZpZzxOb2RlQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsnYWRkT3B0aW9ucyddLCB1bmRlZmluZWQ+XG4gICAgfSkgPT4gT3B0aW9uc1xuXG4gICAgLyoqXG4gICAgICogVGhlIGRlZmF1bHQgc3RvcmFnZSB0aGlzIGV4dGVuc2lvbiBjYW4gc2F2ZSBkYXRhIHRvLlxuICAgICAqIEBzZWUgaHR0cHM6Ly90aXB0YXAuZGV2L2d1aWRlL2N1c3RvbS1leHRlbnNpb25zI3N0b3JhZ2VcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGRlZmF1bHRTdG9yYWdlOiB7XG4gICAgICogICBwcmVmZXRjaGVkVXNlcnM6IFtdLFxuICAgICAqICAgbG9hZGluZzogZmFsc2UsXG4gICAgICogfVxuICAgICAqL1xuICAgIGFkZFN0b3JhZ2U/OiAodGhpczoge1xuICAgICAgbmFtZTogc3RyaW5nXG4gICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICBwYXJlbnQ6IEV4Y2x1ZGU8UGFyZW50Q29uZmlnPE5vZGVDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydhZGRTdG9yYWdlJ10sIHVuZGVmaW5lZD5cbiAgICB9KSA9PiBTdG9yYWdlXG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGFkZHMgZ2xvYmFsQXR0cmlidXRlcyB0byBzcGVjaWZpYyBub2Rlcy5cbiAgICAgKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9ndWlkZS9jdXN0b20tZXh0ZW5zaW9ucyNnbG9iYWwtYXR0cmlidXRlc1xuICAgICAqIEBleGFtcGxlXG4gICAgICogYWRkR2xvYmFsQXR0cmlidXRlcygpIHtcbiAgICAgKiAgIHJldHVybiBbXG4gICAgICogICAgIHtcbiAgICAgICAgICAgICAvLyBFeHRlbmQgdGhlIGZvbGxvd2luZyBleHRlbnNpb25zXG4gICAgICogICAgICAgdHlwZXM6IFtcbiAgICAgKiAgICAgICAgICdoZWFkaW5nJyxcbiAgICAgKiAgICAgICAgICdwYXJhZ3JhcGgnLFxuICAgICAqICAgICAgIF0sXG4gICAgICogICAgICAgLy8g4oCmIHdpdGggdGhvc2UgYXR0cmlidXRlc1xuICAgICAqICAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgKiAgICAgICAgIHRleHRBbGlnbjoge1xuICAgICAqICAgICAgICAgICBkZWZhdWx0OiAnbGVmdCcsXG4gICAgICogICAgICAgICAgIHJlbmRlckhUTUw6IGF0dHJpYnV0ZXMgPT4gKHtcbiAgICAgKiAgICAgICAgICAgICBzdHlsZTogYHRleHQtYWxpZ246ICR7YXR0cmlidXRlcy50ZXh0QWxpZ259YCxcbiAgICAgKiAgICAgICAgICAgfSksXG4gICAgICogICAgICAgICAgIHBhcnNlSFRNTDogZWxlbWVudCA9PiBlbGVtZW50LnN0eWxlLnRleHRBbGlnbiB8fCAnbGVmdCcsXG4gICAgICogICAgICAgICB9LFxuICAgICAqICAgICAgIH0sXG4gICAgICogICAgIH0sXG4gICAgICogICBdXG4gICAgICogfVxuICAgICAqL1xuICAgIGFkZEdsb2JhbEF0dHJpYnV0ZXM/OiAodGhpczoge1xuICAgICAgbmFtZTogc3RyaW5nXG4gICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICBleHRlbnNpb25zOiAoTm9kZSB8IE1hcmspW11cbiAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE5vZGVDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydhZGRHbG9iYWxBdHRyaWJ1dGVzJ11cbiAgICB9KSA9PiBHbG9iYWxBdHRyaWJ1dGVzXG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGFkZHMgY29tbWFuZHMgdG8gdGhlIGVkaXRvclxuICAgICAqIEBzZWUgaHR0cHM6Ly90aXB0YXAuZGV2L2d1aWRlL2N1c3RvbS1leHRlbnNpb25zI2tleWJvYXJkLXNob3J0Y3V0c1xuICAgICAqIEBleGFtcGxlXG4gICAgICogYWRkQ29tbWFuZHMoKSB7XG4gICAgICogICByZXR1cm4ge1xuICAgICAqICAgICBteUNvbW1hbmQ6ICgpID0+ICh7IGNoYWluIH0pID0+IGNoYWluKCkuc2V0TWFyaygndHlwZScsICdmb28nKS5ydW4oKSxcbiAgICAgKiAgIH1cbiAgICAgKiB9XG4gICAgICovXG4gICAgYWRkQ29tbWFuZHM/OiAodGhpczoge1xuICAgICAgbmFtZTogc3RyaW5nXG4gICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICBlZGl0b3I6IEVkaXRvclxuICAgICAgdHlwZTogTm9kZVR5cGVcbiAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE5vZGVDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydhZGRDb21tYW5kcyddXG4gICAgfSkgPT4gUGFydGlhbDxSYXdDb21tYW5kcz5cblxuICAgIC8qKlxuICAgICAqIFRoaXMgZnVuY3Rpb24gcmVnaXN0ZXJzIGtleWJvYXJkIHNob3J0Y3V0cy5cbiAgICAgKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9ndWlkZS9jdXN0b20tZXh0ZW5zaW9ucyNrZXlib2FyZC1zaG9ydGN1dHNcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGFkZEtleWJvYXJkU2hvcnRjdXRzKCkge1xuICAgICAqICAgcmV0dXJuIHtcbiAgICAgKiAgICAgJ01vZC1sJzogKCkgPT4gdGhpcy5lZGl0b3IuY29tbWFuZHMudG9nZ2xlQnVsbGV0TGlzdCgpLFxuICAgICAqICAgfVxuICAgICAqIH0sXG4gICAgICovXG4gICAgYWRkS2V5Ym9hcmRTaG9ydGN1dHM/OiAodGhpczoge1xuICAgICAgbmFtZTogc3RyaW5nXG4gICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICBlZGl0b3I6IEVkaXRvclxuICAgICAgdHlwZTogTm9kZVR5cGVcbiAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE5vZGVDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydhZGRLZXlib2FyZFNob3J0Y3V0cyddXG4gICAgfSkgPT4ge1xuICAgICAgW2tleTogc3RyaW5nXTogS2V5Ym9hcmRTaG9ydGN1dENvbW1hbmRcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGFkZHMgaW5wdXQgcnVsZXMgdG8gdGhlIGVkaXRvci5cbiAgICAgKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9ndWlkZS9jdXN0b20tZXh0ZW5zaW9ucyNpbnB1dC1ydWxlc1xuICAgICAqIEBleGFtcGxlXG4gICAgICogYWRkSW5wdXRSdWxlcygpIHtcbiAgICAgKiAgIHJldHVybiBbXG4gICAgICogICAgIG1hcmtJbnB1dFJ1bGUoe1xuICAgICAqICAgICAgIGZpbmQ6IGlucHV0UmVnZXgsXG4gICAgICogICAgICAgdHlwZTogdGhpcy50eXBlLFxuICAgICAqICAgICB9KSxcbiAgICAgKiAgIF1cbiAgICAgKiB9LFxuICAgICAqL1xuICAgIGFkZElucHV0UnVsZXM/OiAodGhpczoge1xuICAgICAgbmFtZTogc3RyaW5nXG4gICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICBlZGl0b3I6IEVkaXRvclxuICAgICAgdHlwZTogTm9kZVR5cGVcbiAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE5vZGVDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydhZGRJbnB1dFJ1bGVzJ11cbiAgICB9KSA9PiBJbnB1dFJ1bGVbXVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBmdW5jdGlvbiBhZGRzIHBhc3RlIHJ1bGVzIHRvIHRoZSBlZGl0b3IuXG4gICAgICogQHNlZSBodHRwczovL3RpcHRhcC5kZXYvZ3VpZGUvY3VzdG9tLWV4dGVuc2lvbnMjcGFzdGUtcnVsZXNcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGFkZFBhc3RlUnVsZXMoKSB7XG4gICAgICogICByZXR1cm4gW1xuICAgICAqICAgICBtYXJrUGFzdGVSdWxlKHtcbiAgICAgKiAgICAgICBmaW5kOiBwYXN0ZVJlZ2V4LFxuICAgICAqICAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICAgKiAgICAgfSksXG4gICAgICogICBdXG4gICAgICogfSxcbiAgICAgKi9cbiAgICBhZGRQYXN0ZVJ1bGVzPzogKHRoaXM6IHtcbiAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgZWRpdG9yOiBFZGl0b3JcbiAgICAgIHR5cGU6IE5vZGVUeXBlXG4gICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxOb2RlQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsnYWRkUGFzdGVSdWxlcyddXG4gICAgfSkgPT4gUGFzdGVSdWxlW11cblxuICAgIC8qKlxuICAgICAqIFRoaXMgZnVuY3Rpb24gYWRkcyBQcm9zZW1pcnJvciBwbHVnaW5zIHRvIHRoZSBlZGl0b3JcbiAgICAgKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9ndWlkZS9jdXN0b20tZXh0ZW5zaW9ucyNwcm9zZW1pcnJvci1wbHVnaW5zXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBhZGRQcm9zZU1pcnJvclBsdWdpbnMoKSB7XG4gICAgICogICByZXR1cm4gW1xuICAgICAqICAgICBjdXN0b21QbHVnaW4oKSxcbiAgICAgKiAgIF1cbiAgICAgKiB9XG4gICAgICovXG4gICAgYWRkUHJvc2VNaXJyb3JQbHVnaW5zPzogKHRoaXM6IHtcbiAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgZWRpdG9yOiBFZGl0b3JcbiAgICAgIHR5cGU6IE5vZGVUeXBlXG4gICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxOb2RlQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsnYWRkUHJvc2VNaXJyb3JQbHVnaW5zJ11cbiAgICB9KSA9PiBQbHVnaW5bXVxuXG4gICAgLyoqXG4gICAgICogVGhpcyBmdW5jdGlvbiBhZGRzIGFkZGl0aW9uYWwgZXh0ZW5zaW9ucyB0byB0aGUgZWRpdG9yLiBUaGlzIGlzIHVzZWZ1bCBmb3JcbiAgICAgKiBidWlsZGluZyBleHRlbnNpb24ga2l0cy5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGFkZEV4dGVuc2lvbnMoKSB7XG4gICAgICogICByZXR1cm4gW1xuICAgICAqICAgICBCdWxsZXRMaXN0LFxuICAgICAqICAgICBPcmRlcmVkTGlzdCxcbiAgICAgKiAgICAgTGlzdEl0ZW1cbiAgICAgKiAgIF1cbiAgICAgKiB9XG4gICAgICovXG4gICAgYWRkRXh0ZW5zaW9ucz86ICh0aGlzOiB7XG4gICAgICBuYW1lOiBzdHJpbmdcbiAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE5vZGVDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydhZGRFeHRlbnNpb25zJ11cbiAgICB9KSA9PiBFeHRlbnNpb25zXG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGV4dGVuZHMgdGhlIHNjaGVtYSBvZiB0aGUgbm9kZS5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGV4dGVuZE5vZGVTY2hlbWEoKSB7XG4gICAgICogICByZXR1cm4ge1xuICAgICAqICAgICBncm91cDogJ2lubGluZScsXG4gICAgICogICAgIHNlbGVjdGFibGU6IGZhbHNlLFxuICAgICAqICAgfVxuICAgICAqIH1cbiAgICAgKi9cbiAgICBleHRlbmROb2RlU2NoZW1hPzpcbiAgICAgIHwgKChcbiAgICAgICAgICB0aGlzOiB7XG4gICAgICAgICAgICBuYW1lOiBzdHJpbmdcbiAgICAgICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE5vZGVDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydleHRlbmROb2RlU2NoZW1hJ11cbiAgICAgICAgICB9LFxuICAgICAgICAgIGV4dGVuc2lvbjogTm9kZSxcbiAgICAgICAgKSA9PiBSZWNvcmQ8c3RyaW5nLCBhbnk+KVxuICAgICAgfCBudWxsXG5cbiAgICAvKipcbiAgICAgKiBUaGlzIGZ1bmN0aW9uIGV4dGVuZHMgdGhlIHNjaGVtYSBvZiB0aGUgbWFyay5cbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIGV4dGVuZE1hcmtTY2hlbWEoKSB7XG4gICAgICogICByZXR1cm4ge1xuICAgICAqICAgICBncm91cDogJ2lubGluZScsXG4gICAgICogICAgIHNlbGVjdGFibGU6IGZhbHNlLFxuICAgICAqICAgfVxuICAgICAqIH1cbiAgICAgKi9cbiAgICBleHRlbmRNYXJrU2NoZW1hPzpcbiAgICAgIHwgKChcbiAgICAgICAgICB0aGlzOiB7XG4gICAgICAgICAgICBuYW1lOiBzdHJpbmdcbiAgICAgICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE5vZGVDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydleHRlbmRNYXJrU2NoZW1hJ11cbiAgICAgICAgICAgIGVkaXRvcj86IEVkaXRvclxuICAgICAgICAgIH0sXG4gICAgICAgICAgZXh0ZW5zaW9uOiBOb2RlLFxuICAgICAgICApID0+IFJlY29yZDxzdHJpbmcsIGFueT4pXG4gICAgICB8IG51bGxcblxuICAgIC8qKlxuICAgICAqIFRoZSBlZGl0b3IgaXMgbm90IHJlYWR5IHlldC5cbiAgICAgKi9cbiAgICBvbkJlZm9yZUNyZWF0ZT86XG4gICAgICB8ICgodGhpczoge1xuICAgICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICAgICAgZWRpdG9yOiBFZGl0b3JcbiAgICAgICAgICB0eXBlOiBOb2RlVHlwZVxuICAgICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE5vZGVDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydvbkJlZm9yZUNyZWF0ZSddXG4gICAgICAgIH0pID0+IHZvaWQpXG4gICAgICB8IG51bGxcblxuICAgIC8qKlxuICAgICAqIFRoZSBlZGl0b3IgaXMgcmVhZHkuXG4gICAgICovXG4gICAgb25DcmVhdGU/OlxuICAgICAgfCAoKHRoaXM6IHtcbiAgICAgICAgICBuYW1lOiBzdHJpbmdcbiAgICAgICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgICAgIGVkaXRvcjogRWRpdG9yXG4gICAgICAgICAgdHlwZTogTm9kZVR5cGVcbiAgICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxOb2RlQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+Plsnb25DcmVhdGUnXVxuICAgICAgICB9KSA9PiB2b2lkKVxuICAgICAgfCBudWxsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgY29udGVudCBoYXMgY2hhbmdlZC5cbiAgICAgKi9cbiAgICBvblVwZGF0ZT86XG4gICAgICB8ICgodGhpczoge1xuICAgICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICAgICAgZWRpdG9yOiBFZGl0b3JcbiAgICAgICAgICB0eXBlOiBOb2RlVHlwZVxuICAgICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE5vZGVDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydvblVwZGF0ZSddXG4gICAgICAgIH0pID0+IHZvaWQpXG4gICAgICB8IG51bGxcblxuICAgIC8qKlxuICAgICAqIFRoZSBzZWxlY3Rpb24gaGFzIGNoYW5nZWQuXG4gICAgICovXG4gICAgb25TZWxlY3Rpb25VcGRhdGU/OlxuICAgICAgfCAoKHRoaXM6IHtcbiAgICAgICAgICBuYW1lOiBzdHJpbmdcbiAgICAgICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgICAgIGVkaXRvcjogRWRpdG9yXG4gICAgICAgICAgdHlwZTogTm9kZVR5cGVcbiAgICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxOb2RlQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+Plsnb25TZWxlY3Rpb25VcGRhdGUnXVxuICAgICAgICB9KSA9PiB2b2lkKVxuICAgICAgfCBudWxsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgZWRpdG9yIHN0YXRlIGhhcyBjaGFuZ2VkLlxuICAgICAqL1xuICAgIG9uVHJhbnNhY3Rpb24/OlxuICAgICAgfCAoKFxuICAgICAgICAgIHRoaXM6IHtcbiAgICAgICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgICAgICAgZWRpdG9yOiBFZGl0b3JcbiAgICAgICAgICAgIHR5cGU6IE5vZGVUeXBlXG4gICAgICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxOb2RlQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+Plsnb25UcmFuc2FjdGlvbiddXG4gICAgICAgICAgfSxcbiAgICAgICAgICBwcm9wczoge1xuICAgICAgICAgICAgZWRpdG9yOiBFZGl0b3JcbiAgICAgICAgICAgIHRyYW5zYWN0aW9uOiBUcmFuc2FjdGlvblxuICAgICAgICAgIH0sXG4gICAgICAgICkgPT4gdm9pZClcbiAgICAgIHwgbnVsbFxuXG4gICAgLyoqXG4gICAgICogVGhlIGVkaXRvciBpcyBmb2N1c2VkLlxuICAgICAqL1xuICAgIG9uRm9jdXM/OlxuICAgICAgfCAoKFxuICAgICAgICAgIHRoaXM6IHtcbiAgICAgICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgICAgICAgZWRpdG9yOiBFZGl0b3JcbiAgICAgICAgICAgIHR5cGU6IE5vZGVUeXBlXG4gICAgICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxOb2RlQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+Plsnb25Gb2N1cyddXG4gICAgICAgICAgfSxcbiAgICAgICAgICBwcm9wczoge1xuICAgICAgICAgICAgZXZlbnQ6IEZvY3VzRXZlbnRcbiAgICAgICAgICB9LFxuICAgICAgICApID0+IHZvaWQpXG4gICAgICB8IG51bGxcblxuICAgIC8qKlxuICAgICAqIFRoZSBlZGl0b3IgaXNu4oCZdCBmb2N1c2VkIGFueW1vcmUuXG4gICAgICovXG4gICAgb25CbHVyPzpcbiAgICAgIHwgKChcbiAgICAgICAgICB0aGlzOiB7XG4gICAgICAgICAgICBuYW1lOiBzdHJpbmdcbiAgICAgICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgICAgIGVkaXRvcjogRWRpdG9yXG4gICAgICAgICAgICB0eXBlOiBOb2RlVHlwZVxuICAgICAgICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8Tm9kZUNvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ29uQmx1ciddXG4gICAgICAgICAgfSxcbiAgICAgICAgICBwcm9wczoge1xuICAgICAgICAgICAgZXZlbnQ6IEZvY3VzRXZlbnRcbiAgICAgICAgICB9LFxuICAgICAgICApID0+IHZvaWQpXG4gICAgICB8IG51bGxcblxuICAgIC8qKlxuICAgICAqIFRoZSBlZGl0b3IgaXMgZGVzdHJveWVkLlxuICAgICAqL1xuICAgIG9uRGVzdHJveT86XG4gICAgICB8ICgodGhpczoge1xuICAgICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICAgICAgZWRpdG9yOiBFZGl0b3JcbiAgICAgICAgICB0eXBlOiBOb2RlVHlwZVxuICAgICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE5vZGVDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydvbkRlc3Ryb3knXVxuICAgICAgICB9KSA9PiB2b2lkKVxuICAgICAgfCBudWxsXG5cbiAgICAvKipcbiAgICAgKiBOb2RlIFZpZXdcbiAgICAgKi9cbiAgICBhZGROb2RlVmlldz86XG4gICAgICB8ICgodGhpczoge1xuICAgICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICAgICAgZWRpdG9yOiBFZGl0b3JcbiAgICAgICAgICB0eXBlOiBOb2RlVHlwZVxuICAgICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE5vZGVDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydhZGROb2RlVmlldyddXG4gICAgICAgIH0pID0+IE5vZGVWaWV3UmVuZGVyZXIpXG4gICAgICB8IG51bGxcblxuICAgIC8qKlxuICAgICAqIERlZmluZXMgaWYgdGhpcyBub2RlIHNob3VsZCBiZSBhIHRvcCBsZXZlbCBub2RlIChkb2MpXG4gICAgICogQGRlZmF1bHQgZmFsc2VcbiAgICAgKiBAZXhhbXBsZSB0cnVlXG4gICAgICovXG4gICAgdG9wTm9kZT86IGJvb2xlYW5cblxuICAgIC8qKlxuICAgICAqIFRoZSBjb250ZW50IGV4cHJlc3Npb24gZm9yIHRoaXMgbm9kZSwgYXMgZGVzY3JpYmVkIGluIHRoZSBbc2NoZW1hXG4gICAgICogZ3VpZGVdKC9kb2NzL2d1aWRlLyNzY2hlbWEuY29udGVudF9leHByZXNzaW9ucykuIFdoZW4gbm90IGdpdmVuLFxuICAgICAqIHRoZSBub2RlIGRvZXMgbm90IGFsbG93IGFueSBjb250ZW50LlxuICAgICAqXG4gICAgICogWW91IGNhbiByZWFkIG1vcmUgYWJvdXQgaXQgb24gdGhlIFByb3NlbWlycm9yIGRvY3VtZW50YXRpb24gaGVyZVxuICAgICAqIEBzZWUgaHR0cHM6Ly9wcm9zZW1pcnJvci5uZXQvZG9jcy9ndWlkZS8jc2NoZW1hLmNvbnRlbnRfZXhwcmVzc2lvbnNcbiAgICAgKiBAZGVmYXVsdCB1bmRlZmluZWRcbiAgICAgKiBAZXhhbXBsZSBjb250ZW50OiAnYmxvY2srJ1xuICAgICAqIEBleGFtcGxlIGNvbnRlbnQ6ICdoZWFkbGluZSBwYXJhZ3JhcGggYmxvY2sqJ1xuICAgICAqL1xuICAgIGNvbnRlbnQ/OlxuICAgICAgfCBOb2RlU3BlY1snY29udGVudCddXG4gICAgICB8ICgodGhpczoge1xuICAgICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8Tm9kZUNvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ2NvbnRlbnQnXVxuICAgICAgICAgIGVkaXRvcj86IEVkaXRvclxuICAgICAgICB9KSA9PiBOb2RlU3BlY1snY29udGVudCddKVxuXG4gICAgLyoqXG4gICAgICogVGhlIG1hcmtzIHRoYXQgYXJlIGFsbG93ZWQgaW5zaWRlIG9mIHRoaXMgbm9kZS4gTWF5IGJlIGFcbiAgICAgKiBzcGFjZS1zZXBhcmF0ZWQgc3RyaW5nIHJlZmVycmluZyB0byBtYXJrIG5hbWVzIG9yIGdyb3VwcywgYFwiX1wiYFxuICAgICAqIHRvIGV4cGxpY2l0bHkgYWxsb3cgYWxsIG1hcmtzLCBvciBgXCJcImAgdG8gZGlzYWxsb3cgbWFya3MuIFdoZW5cbiAgICAgKiBub3QgZ2l2ZW4sIG5vZGVzIHdpdGggaW5saW5lIGNvbnRlbnQgZGVmYXVsdCB0byBhbGxvd2luZyBhbGxcbiAgICAgKiBtYXJrcywgb3RoZXIgbm9kZXMgZGVmYXVsdCB0byBub3QgYWxsb3dpbmcgbWFya3MuXG4gICAgICpcbiAgICAgKiBAZXhhbXBsZSBtYXJrczogJ3N0cm9uZyBlbSdcbiAgICAgKi9cbiAgICBtYXJrcz86XG4gICAgICB8IE5vZGVTcGVjWydtYXJrcyddXG4gICAgICB8ICgodGhpczoge1xuICAgICAgICAgIG5hbWU6IHN0cmluZ1xuICAgICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICAgICAgcGFyZW50OiBQYXJlbnRDb25maWc8Tm9kZUNvbmZpZzxPcHRpb25zLCBTdG9yYWdlPj5bJ21hcmtzJ11cbiAgICAgICAgICBlZGl0b3I/OiBFZGl0b3JcbiAgICAgICAgfSkgPT4gTm9kZVNwZWNbJ21hcmtzJ10pXG5cbiAgICAvKipcbiAgICAgKiBUaGUgZ3JvdXAgb3Igc3BhY2Utc2VwYXJhdGVkIGdyb3VwcyB0byB3aGljaCB0aGlzIG5vZGUgYmVsb25ncyxcbiAgICAgKiB3aGljaCBjYW4gYmUgcmVmZXJyZWQgdG8gaW4gdGhlIGNvbnRlbnQgZXhwcmVzc2lvbnMgZm9yIHRoZVxuICAgICAqIHNjaGVtYS5cbiAgICAgKlxuICAgICAqIEJ5IGRlZmF1bHQgVGlwdGFwIHVzZXMgdGhlIGdyb3VwcyAnYmxvY2snIGFuZCAnaW5saW5lJyBmb3Igbm9kZXMuIFlvdVxuICAgICAqIGNhbiBhbHNvIHVzZSBjdXN0b20gZ3JvdXBzIGlmIHlvdSB3YW50IHRvIGdyb3VwIHNwZWNpZmljIG5vZGVzIHRvZ2V0aGVyXG4gICAgICogYW5kIGhhbmRsZSB0aGVtIGluIHlvdXIgc2NoZW1hLlxuICAgICAqIEBleGFtcGxlIGdyb3VwOiAnYmxvY2snXG4gICAgICogQGV4YW1wbGUgZ3JvdXA6ICdpbmxpbmUnXG4gICAgICogQGV4YW1wbGUgZ3JvdXA6ICdjdXN0b21CbG9jaycgLy8gdGhpcyB1c2VzIGEgY3VzdG9tIGdyb3VwXG4gICAgICovXG4gICAgZ3JvdXA/OlxuICAgICAgfCBOb2RlU3BlY1snZ3JvdXAnXVxuICAgICAgfCAoKHRoaXM6IHtcbiAgICAgICAgICBuYW1lOiBzdHJpbmdcbiAgICAgICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE5vZGVDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+Wydncm91cCddXG4gICAgICAgICAgZWRpdG9yPzogRWRpdG9yXG4gICAgICAgIH0pID0+IE5vZGVTcGVjWydncm91cCddKVxuXG4gICAgLyoqXG4gICAgICogU2hvdWxkIGJlIHNldCB0byB0cnVlIGZvciBpbmxpbmUgbm9kZXMuIChJbXBsaWVkIGZvciB0ZXh0IG5vZGVzLilcbiAgICAgKi9cbiAgICBpbmxpbmU/OlxuICAgICAgfCBOb2RlU3BlY1snaW5saW5lJ11cbiAgICAgIHwgKCh0aGlzOiB7XG4gICAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxOb2RlQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsnaW5saW5lJ11cbiAgICAgICAgICBlZGl0b3I/OiBFZGl0b3JcbiAgICAgICAgfSkgPT4gTm9kZVNwZWNbJ2lubGluZSddKVxuXG4gICAgLyoqXG4gICAgICogQ2FuIGJlIHNldCB0byB0cnVlIHRvIGluZGljYXRlIHRoYXQsIHRob3VnaCB0aGlzIGlzbid0IGEgW2xlYWZcbiAgICAgKiBub2RlXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZVR5cGUuaXNMZWFmKSwgaXQgZG9lc24ndCBoYXZlIGRpcmVjdGx5IGVkaXRhYmxlXG4gICAgICogY29udGVudCBhbmQgc2hvdWxkIGJlIHRyZWF0ZWQgYXMgYSBzaW5nbGUgdW5pdCBpbiB0aGUgdmlldy5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlIGF0b206IHRydWVcbiAgICAgKi9cbiAgICBhdG9tPzpcbiAgICAgIHwgTm9kZVNwZWNbJ2F0b20nXVxuICAgICAgfCAoKHRoaXM6IHtcbiAgICAgICAgICBuYW1lOiBzdHJpbmdcbiAgICAgICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE5vZGVDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydhdG9tJ11cbiAgICAgICAgICBlZGl0b3I/OiBFZGl0b3JcbiAgICAgICAgfSkgPT4gTm9kZVNwZWNbJ2F0b20nXSlcblxuICAgIC8qKlxuICAgICAqIENvbnRyb2xzIHdoZXRoZXIgbm9kZXMgb2YgdGhpcyB0eXBlIGNhbiBiZSBzZWxlY3RlZCBhcyBhIFtub2RlXG4gICAgICogc2VsZWN0aW9uXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jc3RhdGUuTm9kZVNlbGVjdGlvbikuIERlZmF1bHRzIHRvIHRydWUgZm9yIG5vbi10ZXh0XG4gICAgICogbm9kZXMuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdCB0cnVlXG4gICAgICogQGV4YW1wbGUgc2VsZWN0YWJsZTogZmFsc2VcbiAgICAgKi9cbiAgICBzZWxlY3RhYmxlPzpcbiAgICAgIHwgTm9kZVNwZWNbJ3NlbGVjdGFibGUnXVxuICAgICAgfCAoKHRoaXM6IHtcbiAgICAgICAgICBuYW1lOiBzdHJpbmdcbiAgICAgICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE5vZGVDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydzZWxlY3RhYmxlJ11cbiAgICAgICAgICBlZGl0b3I/OiBFZGl0b3JcbiAgICAgICAgfSkgPT4gTm9kZVNwZWNbJ3NlbGVjdGFibGUnXSlcblxuICAgIC8qKlxuICAgICAqIERldGVybWluZXMgd2hldGhlciBub2RlcyBvZiB0aGlzIHR5cGUgY2FuIGJlIGRyYWdnZWQgd2l0aG91dFxuICAgICAqIGJlaW5nIHNlbGVjdGVkLiBEZWZhdWx0cyB0byBmYWxzZS5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0OiBmYWxzZVxuICAgICAqIEBleGFtcGxlOiBkcmFnZ2FibGU6IHRydWVcbiAgICAgKi9cbiAgICBkcmFnZ2FibGU/OlxuICAgICAgfCBOb2RlU3BlY1snZHJhZ2dhYmxlJ11cbiAgICAgIHwgKCh0aGlzOiB7XG4gICAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxOb2RlQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsnZHJhZ2dhYmxlJ11cbiAgICAgICAgICBlZGl0b3I/OiBFZGl0b3JcbiAgICAgICAgfSkgPT4gTm9kZVNwZWNbJ2RyYWdnYWJsZSddKVxuXG4gICAgLyoqXG4gICAgICogQ2FuIGJlIHVzZWQgdG8gaW5kaWNhdGUgdGhhdCB0aGlzIG5vZGUgY29udGFpbnMgY29kZSwgd2hpY2hcbiAgICAgKiBjYXVzZXMgc29tZSBjb21tYW5kcyB0byBiZWhhdmUgZGlmZmVyZW50bHkuXG4gICAgICovXG4gICAgY29kZT86XG4gICAgICB8IE5vZGVTcGVjWydjb2RlJ11cbiAgICAgIHwgKCh0aGlzOiB7XG4gICAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxOb2RlQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsnY29kZSddXG4gICAgICAgICAgZWRpdG9yPzogRWRpdG9yXG4gICAgICAgIH0pID0+IE5vZGVTcGVjWydjb2RlJ10pXG5cbiAgICAvKipcbiAgICAgKiBDb250cm9scyB3YXkgd2hpdGVzcGFjZSBpbiB0aGlzIGEgbm9kZSBpcyBwYXJzZWQuIFRoZSBkZWZhdWx0IGlzXG4gICAgICogYFwibm9ybWFsXCJgLCB3aGljaCBjYXVzZXMgdGhlIFtET00gcGFyc2VyXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuRE9NUGFyc2VyKSB0b1xuICAgICAqIGNvbGxhcHNlIHdoaXRlc3BhY2UgaW4gbm9ybWFsIG1vZGUsIGFuZCBub3JtYWxpemUgaXQgKHJlcGxhY2luZ1xuICAgICAqIG5ld2xpbmVzIGFuZCBzdWNoIHdpdGggc3BhY2VzKSBvdGhlcndpc2UuIGBcInByZVwiYCBjYXVzZXMgdGhlXG4gICAgICogcGFyc2VyIHRvIHByZXNlcnZlIHNwYWNlcyBpbnNpZGUgdGhlIG5vZGUuIFdoZW4gdGhpcyBvcHRpb24gaXNuJ3RcbiAgICAgKiBnaXZlbiwgYnV0IFtgY29kZWBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5Ob2RlU3BlYy5jb2RlKSBpcyB0cnVlLCBgd2hpdGVzcGFjZWBcbiAgICAgKiB3aWxsIGRlZmF1bHQgdG8gYFwicHJlXCJgLiBOb3RlIHRoYXQgdGhpcyBvcHRpb24gZG9lc24ndCBpbmZsdWVuY2VcbiAgICAgKiB0aGUgd2F5IHRoZSBub2RlIGlzIHJlbmRlcmVk4oCUdGhhdCBzaG91bGQgYmUgaGFuZGxlZCBieSBgdG9ET01gXG4gICAgICogYW5kL29yIHN0eWxpbmcuXG4gICAgICovXG4gICAgd2hpdGVzcGFjZT86XG4gICAgICB8IE5vZGVTcGVjWyd3aGl0ZXNwYWNlJ11cbiAgICAgIHwgKCh0aGlzOiB7XG4gICAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxOb2RlQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+Plsnd2hpdGVzcGFjZSddXG4gICAgICAgICAgZWRpdG9yPzogRWRpdG9yXG4gICAgICAgIH0pID0+IE5vZGVTcGVjWyd3aGl0ZXNwYWNlJ10pXG5cbiAgICAvKipcbiAgICAgKiBBbGxvd3MgYSAqKnNpbmdsZSoqIG5vZGUgdG8gYmUgc2V0IGFzIGxpbmVicmVhayBlcXVpdmFsZW50IChlLmcuIGhhcmRCcmVhaykuXG4gICAgICogV2hlbiBjb252ZXJ0aW5nIGJldHdlZW4gYmxvY2sgdHlwZXMgdGhhdCBoYXZlIHdoaXRlc3BhY2Ugc2V0IHRvIFwicHJlXCJcbiAgICAgKiBhbmQgZG9uJ3Qgc3VwcG9ydCB0aGUgbGluZWJyZWFrIG5vZGUgKGUuZy4gY29kZUJsb2NrKSBhbmQgb3RoZXIgYmxvY2sgdHlwZXNcbiAgICAgKiB0aGF0IGRvIHN1cHBvcnQgdGhlIGxpbmVicmVhayBub2RlIChlLmcuIHBhcmFncmFwaHMpIC0gdGhpcyBub2RlIHdpbGwgYmUgdXNlZFxuICAgICAqIGFzIHRoZSBsaW5lYnJlYWsgaW5zdGVhZCBvZiBzdHJpcHBpbmcgdGhlIG5ld2xpbmUuXG4gICAgICpcbiAgICAgKiBTZWUgW2xpbmVicmVha1JlcGxhY2VtZW50XShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZVNwZWMubGluZWJyZWFrUmVwbGFjZW1lbnQpLlxuICAgICAqL1xuICAgIGxpbmVicmVha1JlcGxhY2VtZW50PzpcbiAgICAgIHwgTm9kZVNwZWNbJ2xpbmVicmVha1JlcGxhY2VtZW50J11cbiAgICAgIHwgKCh0aGlzOiB7XG4gICAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxOb2RlQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsnbGluZWJyZWFrUmVwbGFjZW1lbnQnXVxuICAgICAgICAgIGVkaXRvcj86IEVkaXRvclxuICAgICAgICB9KSA9PiBOb2RlU3BlY1snbGluZWJyZWFrUmVwbGFjZW1lbnQnXSlcblxuICAgIC8qKlxuICAgICAqIFdoZW4gZW5hYmxlZCwgZW5hYmxlcyBib3RoXG4gICAgICogW2BkZWZpbmluZ0FzQ29udGV4dGBdKGh0dHBzOi8vcHJvc2VtaXJyb3IubmV0L2RvY3MvcmVmLyNtb2RlbC5Ob2RlU3BlYy5kZWZpbmluZ0FzQ29udGV4dCkgYW5kXG4gICAgICogW2BkZWZpbmluZ0ZvckNvbnRlbnRgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuTm9kZVNwZWMuZGVmaW5pbmdGb3JDb250ZW50KS5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0IGZhbHNlXG4gICAgICogQGV4YW1wbGUgaXNvbGF0aW5nOiB0cnVlXG4gICAgICovXG4gICAgZGVmaW5pbmc/OlxuICAgICAgfCBOb2RlU3BlY1snZGVmaW5pbmcnXVxuICAgICAgfCAoKHRoaXM6IHtcbiAgICAgICAgICBuYW1lOiBzdHJpbmdcbiAgICAgICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICAgICAgc3RvcmFnZTogU3RvcmFnZVxuICAgICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE5vZGVDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydkZWZpbmluZyddXG4gICAgICAgICAgZWRpdG9yPzogRWRpdG9yXG4gICAgICAgIH0pID0+IE5vZGVTcGVjWydkZWZpbmluZyddKVxuXG4gICAgLyoqXG4gICAgICogV2hlbiBlbmFibGVkIChkZWZhdWx0IGlzIGZhbHNlKSwgdGhlIHNpZGVzIG9mIG5vZGVzIG9mIHRoaXMgdHlwZVxuICAgICAqIGNvdW50IGFzIGJvdW5kYXJpZXMgdGhhdCByZWd1bGFyIGVkaXRpbmcgb3BlcmF0aW9ucywgbGlrZVxuICAgICAqIGJhY2tzcGFjaW5nIG9yIGxpZnRpbmcsIHdvbid0IGNyb3NzLiBBbiBleGFtcGxlIG9mIGEgbm9kZSB0aGF0XG4gICAgICogc2hvdWxkIHByb2JhYmx5IGhhdmUgdGhpcyBlbmFibGVkIGlzIGEgdGFibGUgY2VsbC5cbiAgICAgKi9cbiAgICBpc29sYXRpbmc/OlxuICAgICAgfCBOb2RlU3BlY1snaXNvbGF0aW5nJ11cbiAgICAgIHwgKCh0aGlzOiB7XG4gICAgICAgICAgbmFtZTogc3RyaW5nXG4gICAgICAgICAgb3B0aW9uczogT3B0aW9uc1xuICAgICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxOb2RlQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsnaXNvbGF0aW5nJ11cbiAgICAgICAgICBlZGl0b3I/OiBFZGl0b3JcbiAgICAgICAgfSkgPT4gTm9kZVNwZWNbJ2lzb2xhdGluZyddKVxuXG4gICAgLyoqXG4gICAgICogQXNzb2NpYXRlcyBET00gcGFyc2VyIGluZm9ybWF0aW9uIHdpdGggdGhpcyBub2RlLCB3aGljaCBjYW4gYmVcbiAgICAgKiB1c2VkIGJ5IFtgRE9NUGFyc2VyLmZyb21TY2hlbWFgXShodHRwczovL3Byb3NlbWlycm9yLm5ldC9kb2NzL3JlZi8jbW9kZWwuRE9NUGFyc2VyXmZyb21TY2hlbWEpIHRvXG4gICAgICogYXV0b21hdGljYWxseSBkZXJpdmUgYSBwYXJzZXIuIFRoZSBgbm9kZWAgZmllbGQgaW4gdGhlIHJ1bGVzIGlzXG4gICAgICogaW1wbGllZCAodGhlIG5hbWUgb2YgdGhpcyBub2RlIHdpbGwgYmUgZmlsbGVkIGluIGF1dG9tYXRpY2FsbHkpLlxuICAgICAqIElmIHlvdSBzdXBwbHkgeW91ciBvd24gcGFyc2VyLCB5b3UgZG8gbm90IG5lZWQgdG8gYWxzbyBzcGVjaWZ5XG4gICAgICogcGFyc2luZyBydWxlcyBpbiB5b3VyIHNjaGVtYS5cbiAgICAgKlxuICAgICAqIEBleGFtcGxlIHBhcnNlSFRNTDogW3sgdGFnOiAnZGl2JywgYXR0cnM6IHsgJ2RhdGEtaWQnOiAnbXktYmxvY2snIH0gfV1cbiAgICAgKi9cbiAgICBwYXJzZUhUTUw/OiAodGhpczoge1xuICAgICAgbmFtZTogc3RyaW5nXG4gICAgICBvcHRpb25zOiBPcHRpb25zXG4gICAgICBzdG9yYWdlOiBTdG9yYWdlXG4gICAgICBwYXJlbnQ6IFBhcmVudENvbmZpZzxOb2RlQ29uZmlnPE9wdGlvbnMsIFN0b3JhZ2U+PlsncGFyc2VIVE1MJ11cbiAgICAgIGVkaXRvcj86IEVkaXRvclxuICAgIH0pID0+IE5vZGVTcGVjWydwYXJzZURPTSddXG5cbiAgICAvKipcbiAgICAgKiBBIGRlc2NyaXB0aW9uIG9mIGEgRE9NIHN0cnVjdHVyZS4gQ2FuIGJlIGVpdGhlciBhIHN0cmluZywgd2hpY2ggaXNcbiAgICAgKiBpbnRlcnByZXRlZCBhcyBhIHRleHQgbm9kZSwgYSBET00gbm9kZSwgd2hpY2ggaXMgaW50ZXJwcmV0ZWQgYXNcbiAgICAgKiBpdHNlbGYsIGEgYHtkb20sIGNvbnRlbnRET019YCBvYmplY3QsIG9yIGFuIGFycmF5LlxuICAgICAqXG4gICAgICogQW4gYXJyYXkgZGVzY3JpYmVzIGEgRE9NIGVsZW1lbnQuIFRoZSBmaXJzdCB2YWx1ZSBpbiB0aGUgYXJyYXlcbiAgICAgKiBzaG91bGQgYmUgYSBzdHJpbmfigJR0aGUgbmFtZSBvZiB0aGUgRE9NIGVsZW1lbnQsIG9wdGlvbmFsbHkgcHJlZml4ZWRcbiAgICAgKiBieSBhIG5hbWVzcGFjZSBVUkwgYW5kIGEgc3BhY2UuIElmIHRoZSBzZWNvbmQgZWxlbWVudCBpcyBwbGFpblxuICAgICAqIG9iamVjdCwgaXQgaXMgaW50ZXJwcmV0ZWQgYXMgYSBzZXQgb2YgYXR0cmlidXRlcyBmb3IgdGhlIGVsZW1lbnQuXG4gICAgICogQW55IGVsZW1lbnRzIGFmdGVyIHRoYXQgKGluY2x1ZGluZyB0aGUgMm5kIGlmIGl0J3Mgbm90IGFuIGF0dHJpYnV0ZVxuICAgICAqIG9iamVjdCkgYXJlIGludGVycHJldGVkIGFzIGNoaWxkcmVuIG9mIHRoZSBET00gZWxlbWVudHMsIGFuZCBtdXN0XG4gICAgICogZWl0aGVyIGJlIHZhbGlkIGBET01PdXRwdXRTcGVjYCB2YWx1ZXMsIG9yIHRoZSBudW1iZXIgemVyby5cbiAgICAgKlxuICAgICAqIFRoZSBudW1iZXIgemVybyAocHJvbm91bmNlZCDigJxob2xl4oCdKSBpcyB1c2VkIHRvIGluZGljYXRlIHRoZSBwbGFjZVxuICAgICAqIHdoZXJlIGEgbm9kZSdzIGNoaWxkIG5vZGVzIHNob3VsZCBiZSBpbnNlcnRlZC4gSWYgaXQgb2NjdXJzIGluIGFuXG4gICAgICogb3V0cHV0IHNwZWMsIGl0IHNob3VsZCBiZSB0aGUgb25seSBjaGlsZCBlbGVtZW50IGluIGl0cyBwYXJlbnRcbiAgICAgKiBub2RlLlxuICAgICAqXG4gICAgICogQGV4YW1wbGUgdG9ET006IFsnZGl2W2RhdGEtaWQ9XCJteS1ibG9ja1wiXScsIHsgY2xhc3M6ICdteS1ibG9jaycgfSwgMF1cbiAgICAgKi9cbiAgICByZW5kZXJIVE1MPzpcbiAgICAgIHwgKChcbiAgICAgICAgICB0aGlzOiB7XG4gICAgICAgICAgICBuYW1lOiBzdHJpbmdcbiAgICAgICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE5vZGVDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydyZW5kZXJIVE1MJ11cbiAgICAgICAgICAgIGVkaXRvcj86IEVkaXRvclxuICAgICAgICAgIH0sXG4gICAgICAgICAgcHJvcHM6IHtcbiAgICAgICAgICAgIG5vZGU6IFByb3NlTWlycm9yTm9kZVxuICAgICAgICAgICAgSFRNTEF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIGFueT5cbiAgICAgICAgICB9LFxuICAgICAgICApID0+IERPTU91dHB1dFNwZWMpXG4gICAgICB8IG51bGxcblxuICAgIC8qKlxuICAgICAqIHJlbmRlcnMgdGhlIG5vZGUgYXMgdGV4dFxuICAgICAqIEBleGFtcGxlIHJlbmRlclRleHQ6ICgpID0+ICdmb29cbiAgICAgKi9cbiAgICByZW5kZXJUZXh0PzpcbiAgICAgIHwgKChcbiAgICAgICAgICB0aGlzOiB7XG4gICAgICAgICAgICBuYW1lOiBzdHJpbmdcbiAgICAgICAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgICAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgICAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE5vZGVDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydyZW5kZXJUZXh0J11cbiAgICAgICAgICAgIGVkaXRvcj86IEVkaXRvclxuICAgICAgICAgIH0sXG4gICAgICAgICAgcHJvcHM6IHtcbiAgICAgICAgICAgIG5vZGU6IFByb3NlTWlycm9yTm9kZVxuICAgICAgICAgICAgcG9zOiBudW1iZXJcbiAgICAgICAgICAgIHBhcmVudDogUHJvc2VNaXJyb3JOb2RlXG4gICAgICAgICAgICBpbmRleDogbnVtYmVyXG4gICAgICAgICAgfSxcbiAgICAgICAgKSA9PiBzdHJpbmcpXG4gICAgICB8IG51bGxcblxuICAgIC8qKlxuICAgICAqIEFkZCBhdHRyaWJ1dGVzIHRvIHRoZSBub2RlXG4gICAgICogQGV4YW1wbGUgYWRkQXR0cmlidXRlczogKCkgPT4gKHsgY2xhc3M6ICdmb28nIH0pXG4gICAgICovXG4gICAgYWRkQXR0cmlidXRlcz86ICh0aGlzOiB7XG4gICAgICBuYW1lOiBzdHJpbmdcbiAgICAgIG9wdGlvbnM6IE9wdGlvbnNcbiAgICAgIHN0b3JhZ2U6IFN0b3JhZ2VcbiAgICAgIHBhcmVudDogUGFyZW50Q29uZmlnPE5vZGVDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+WydhZGRBdHRyaWJ1dGVzJ11cbiAgICAgIGVkaXRvcj86IEVkaXRvclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZW1wdHktb2JqZWN0LXR5cGVcbiAgICB9KSA9PiBBdHRyaWJ1dGVzIHwge31cbiAgfVxufVxuXG4vKipcbiAqIFRoZSBOb2RlIGNsYXNzIGlzIHVzZWQgdG8gY3JlYXRlIGN1c3RvbSBub2RlIGV4dGVuc2lvbnMuXG4gKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9hcGkvZXh0ZW5zaW9ucyNjcmVhdGUtYS1uZXctZXh0ZW5zaW9uXG4gKi9cbmV4cG9ydCBjbGFzcyBOb2RlPE9wdGlvbnMgPSBhbnksIFN0b3JhZ2UgPSBhbnk+IHtcbiAgdHlwZSA9ICdub2RlJ1xuXG4gIG5hbWUgPSAnbm9kZSdcblxuICBwYXJlbnQ6IE5vZGUgfCBudWxsID0gbnVsbFxuXG4gIGNoaWxkOiBOb2RlIHwgbnVsbCA9IG51bGxcblxuICBvcHRpb25zOiBPcHRpb25zXG5cbiAgc3RvcmFnZTogU3RvcmFnZVxuXG4gIGNvbmZpZzogTm9kZUNvbmZpZyA9IHtcbiAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgZGVmYXVsdE9wdGlvbnM6IHt9LFxuICB9XG5cbiAgY29uc3RydWN0b3IoY29uZmlnOiBQYXJ0aWFsPE5vZGVDb25maWc8T3B0aW9ucywgU3RvcmFnZT4+ID0ge30pIHtcbiAgICB0aGlzLmNvbmZpZyA9IHtcbiAgICAgIC4uLnRoaXMuY29uZmlnLFxuICAgICAgLi4uY29uZmlnLFxuICAgIH1cblxuICAgIHRoaXMubmFtZSA9IHRoaXMuY29uZmlnLm5hbWVcblxuICAgIGlmIChjb25maWcuZGVmYXVsdE9wdGlvbnMgJiYgT2JqZWN0LmtleXMoY29uZmlnLmRlZmF1bHRPcHRpb25zKS5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIGBbdGlwdGFwIHdhcm5dOiBCUkVBS0lORyBDSEFOR0U6IFwiZGVmYXVsdE9wdGlvbnNcIiBpcyBkZXByZWNhdGVkLiBQbGVhc2UgdXNlIFwiYWRkT3B0aW9uc1wiIGluc3RlYWQuIEZvdW5kIGluIGV4dGVuc2lvbjogXCIke3RoaXMubmFtZX1cIi5gLFxuICAgICAgKVxuICAgIH1cblxuICAgIC8vIFRPRE86IHJlbW92ZSBgYWRkT3B0aW9uc2AgZmFsbGJhY2tcbiAgICB0aGlzLm9wdGlvbnMgPSB0aGlzLmNvbmZpZy5kZWZhdWx0T3B0aW9uc1xuXG4gICAgaWYgKHRoaXMuY29uZmlnLmFkZE9wdGlvbnMpIHtcbiAgICAgIHRoaXMub3B0aW9ucyA9IGNhbGxPclJldHVybihcbiAgICAgICAgZ2V0RXh0ZW5zaW9uRmllbGQ8QW55Q29uZmlnWydhZGRPcHRpb25zJ10+KHRoaXMsICdhZGRPcHRpb25zJywge1xuICAgICAgICAgIG5hbWU6IHRoaXMubmFtZSxcbiAgICAgICAgfSksXG4gICAgICApXG4gICAgfVxuXG4gICAgdGhpcy5zdG9yYWdlID0gY2FsbE9yUmV0dXJuKFxuICAgICAgZ2V0RXh0ZW5zaW9uRmllbGQ8QW55Q29uZmlnWydhZGRTdG9yYWdlJ10+KHRoaXMsICdhZGRTdG9yYWdlJywge1xuICAgICAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgICAgIG9wdGlvbnM6IHRoaXMub3B0aW9ucyxcbiAgICAgIH0pLFxuICAgICkgfHwge31cbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGU8TyA9IGFueSwgUyA9IGFueT4oY29uZmlnOiBQYXJ0aWFsPE5vZGVDb25maWc8TywgUz4+ID0ge30pIHtcbiAgICByZXR1cm4gbmV3IE5vZGU8TywgUz4oY29uZmlnKVxuICB9XG5cbiAgY29uZmlndXJlKG9wdGlvbnM6IFBhcnRpYWw8T3B0aW9ucz4gPSB7fSkge1xuICAgIC8vIHJldHVybiBhIG5ldyBpbnN0YW5jZSBzbyB3ZSBjYW4gdXNlIHRoZSBzYW1lIGV4dGVuc2lvblxuICAgIC8vIHdpdGggZGlmZmVyZW50IGNhbGxzIG9mIGBjb25maWd1cmVgXG4gICAgY29uc3QgZXh0ZW5zaW9uID0gdGhpcy5leHRlbmQ8T3B0aW9ucywgU3RvcmFnZT4oe1xuICAgICAgLi4udGhpcy5jb25maWcsXG4gICAgICBhZGRPcHRpb25zOiAoKSA9PiB7XG4gICAgICAgIHJldHVybiBtZXJnZURlZXAodGhpcy5vcHRpb25zIGFzIFJlY29yZDxzdHJpbmcsIGFueT4sIG9wdGlvbnMpIGFzIE9wdGlvbnNcbiAgICAgIH0sXG4gICAgfSlcblxuICAgIC8vIEFsd2F5cyBwcmVzZXJ2ZSB0aGUgY3VycmVudCBuYW1lXG4gICAgZXh0ZW5zaW9uLm5hbWUgPSB0aGlzLm5hbWVcbiAgICAvLyBTZXQgdGhlIHBhcmVudCB0byBiZSBvdXIgcGFyZW50XG4gICAgZXh0ZW5zaW9uLnBhcmVudCA9IHRoaXMucGFyZW50XG5cbiAgICByZXR1cm4gZXh0ZW5zaW9uXG4gIH1cblxuICBleHRlbmQ8RXh0ZW5kZWRPcHRpb25zID0gT3B0aW9ucywgRXh0ZW5kZWRTdG9yYWdlID0gU3RvcmFnZT4oXG4gICAgZXh0ZW5kZWRDb25maWc6IFBhcnRpYWw8Tm9kZUNvbmZpZzxFeHRlbmRlZE9wdGlvbnMsIEV4dGVuZGVkU3RvcmFnZT4+ID0ge30sXG4gICkge1xuICAgIGNvbnN0IGV4dGVuc2lvbiA9IG5ldyBOb2RlPEV4dGVuZGVkT3B0aW9ucywgRXh0ZW5kZWRTdG9yYWdlPihleHRlbmRlZENvbmZpZylcblxuICAgIGV4dGVuc2lvbi5wYXJlbnQgPSB0aGlzXG5cbiAgICB0aGlzLmNoaWxkID0gZXh0ZW5zaW9uXG5cbiAgICBleHRlbnNpb24ubmFtZSA9IGV4dGVuZGVkQ29uZmlnLm5hbWUgPyBleHRlbmRlZENvbmZpZy5uYW1lIDogZXh0ZW5zaW9uLnBhcmVudC5uYW1lXG5cbiAgICBpZiAoZXh0ZW5kZWRDb25maWcuZGVmYXVsdE9wdGlvbnMgJiYgT2JqZWN0LmtleXMoZXh0ZW5kZWRDb25maWcuZGVmYXVsdE9wdGlvbnMpLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgYFt0aXB0YXAgd2Fybl06IEJSRUFLSU5HIENIQU5HRTogXCJkZWZhdWx0T3B0aW9uc1wiIGlzIGRlcHJlY2F0ZWQuIFBsZWFzZSB1c2UgXCJhZGRPcHRpb25zXCIgaW5zdGVhZC4gRm91bmQgaW4gZXh0ZW5zaW9uOiBcIiR7ZXh0ZW5zaW9uLm5hbWV9XCIuYCxcbiAgICAgIClcbiAgICB9XG5cbiAgICBleHRlbnNpb24ub3B0aW9ucyA9IGNhbGxPclJldHVybihcbiAgICAgIGdldEV4dGVuc2lvbkZpZWxkPEFueUNvbmZpZ1snYWRkT3B0aW9ucyddPihleHRlbnNpb24sICdhZGRPcHRpb25zJywge1xuICAgICAgICBuYW1lOiBleHRlbnNpb24ubmFtZSxcbiAgICAgIH0pLFxuICAgIClcblxuICAgIGV4dGVuc2lvbi5zdG9yYWdlID0gY2FsbE9yUmV0dXJuKFxuICAgICAgZ2V0RXh0ZW5zaW9uRmllbGQ8QW55Q29uZmlnWydhZGRTdG9yYWdlJ10+KGV4dGVuc2lvbiwgJ2FkZFN0b3JhZ2UnLCB7XG4gICAgICAgIG5hbWU6IGV4dGVuc2lvbi5uYW1lLFxuICAgICAgICBvcHRpb25zOiBleHRlbnNpb24ub3B0aW9ucyxcbiAgICAgIH0pLFxuICAgIClcblxuICAgIHJldHVybiBleHRlbnNpb25cbiAgfVxufVxuIiwgImltcG9ydCB7IE5vZGVTZWxlY3Rpb24gfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuaW1wb3J0IHsgTm9kZVZpZXcgYXMgUHJvc2VNaXJyb3JOb2RlVmlldywgVmlld011dGF0aW9uUmVjb3JkIH0gZnJvbSAnQHRpcHRhcC9wbS92aWV3J1xuXG5pbXBvcnQgeyBFZGl0b3IgYXMgQ29yZUVkaXRvciB9IGZyb20gJy4vRWRpdG9yLmpzJ1xuaW1wb3J0IHsgRGVjb3JhdGlvbldpdGhUeXBlLCBOb2RlVmlld1JlbmRlcmVyT3B0aW9ucywgTm9kZVZpZXdSZW5kZXJlclByb3BzIH0gZnJvbSAnLi90eXBlcy5qcydcbmltcG9ydCB7IGlzQW5kcm9pZCB9IGZyb20gJy4vdXRpbGl0aWVzL2lzQW5kcm9pZC5qcydcbmltcG9ydCB7IGlzaU9TIH0gZnJvbSAnLi91dGlsaXRpZXMvaXNpT1MuanMnXG5cbi8qKlxuICogTm9kZSB2aWV3cyBhcmUgdXNlZCB0byBjdXN0b21pemUgdGhlIHJlbmRlcmVkIERPTSBzdHJ1Y3R1cmUgb2YgYSBub2RlLlxuICogQHNlZSBodHRwczovL3RpcHRhcC5kZXYvZ3VpZGUvbm9kZS12aWV3c1xuICovXG5leHBvcnQgY2xhc3MgTm9kZVZpZXc8XG4gIENvbXBvbmVudCxcbiAgTm9kZUVkaXRvciBleHRlbmRzIENvcmVFZGl0b3IgPSBDb3JlRWRpdG9yLFxuICBPcHRpb25zIGV4dGVuZHMgTm9kZVZpZXdSZW5kZXJlck9wdGlvbnMgPSBOb2RlVmlld1JlbmRlcmVyT3B0aW9ucyxcbj4gaW1wbGVtZW50cyBQcm9zZU1pcnJvck5vZGVWaWV3IHtcbiAgY29tcG9uZW50OiBDb21wb25lbnRcblxuICBlZGl0b3I6IE5vZGVFZGl0b3JcblxuICBvcHRpb25zOiBPcHRpb25zXG5cbiAgZXh0ZW5zaW9uOiBOb2RlVmlld1JlbmRlcmVyUHJvcHNbJ2V4dGVuc2lvbiddXG5cbiAgbm9kZTogTm9kZVZpZXdSZW5kZXJlclByb3BzWydub2RlJ11cblxuICBkZWNvcmF0aW9uczogTm9kZVZpZXdSZW5kZXJlclByb3BzWydkZWNvcmF0aW9ucyddXG5cbiAgaW5uZXJEZWNvcmF0aW9uczogTm9kZVZpZXdSZW5kZXJlclByb3BzWydpbm5lckRlY29yYXRpb25zJ11cblxuICB2aWV3OiBOb2RlVmlld1JlbmRlcmVyUHJvcHNbJ3ZpZXcnXVxuXG4gIGdldFBvczogTm9kZVZpZXdSZW5kZXJlclByb3BzWydnZXRQb3MnXVxuXG4gIEhUTUxBdHRyaWJ1dGVzOiBOb2RlVmlld1JlbmRlcmVyUHJvcHNbJ0hUTUxBdHRyaWJ1dGVzJ11cblxuICBpc0RyYWdnaW5nID0gZmFsc2VcblxuICBjb25zdHJ1Y3Rvcihjb21wb25lbnQ6IENvbXBvbmVudCwgcHJvcHM6IE5vZGVWaWV3UmVuZGVyZXJQcm9wcywgb3B0aW9ucz86IFBhcnRpYWw8T3B0aW9ucz4pIHtcbiAgICB0aGlzLmNvbXBvbmVudCA9IGNvbXBvbmVudFxuICAgIHRoaXMuZWRpdG9yID0gcHJvcHMuZWRpdG9yIGFzIE5vZGVFZGl0b3JcbiAgICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgICBzdG9wRXZlbnQ6IG51bGwsXG4gICAgICBpZ25vcmVNdXRhdGlvbjogbnVsbCxcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgfSBhcyBPcHRpb25zXG4gICAgdGhpcy5leHRlbnNpb24gPSBwcm9wcy5leHRlbnNpb25cbiAgICB0aGlzLm5vZGUgPSBwcm9wcy5ub2RlXG4gICAgdGhpcy5kZWNvcmF0aW9ucyA9IHByb3BzLmRlY29yYXRpb25zIGFzIERlY29yYXRpb25XaXRoVHlwZVtdXG4gICAgdGhpcy5pbm5lckRlY29yYXRpb25zID0gcHJvcHMuaW5uZXJEZWNvcmF0aW9uc1xuICAgIHRoaXMudmlldyA9IHByb3BzLnZpZXdcbiAgICB0aGlzLkhUTUxBdHRyaWJ1dGVzID0gcHJvcHMuSFRNTEF0dHJpYnV0ZXNcbiAgICB0aGlzLmdldFBvcyA9IHByb3BzLmdldFBvc1xuICAgIHRoaXMubW91bnQoKVxuICB9XG5cbiAgbW91bnQoKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXG4gICAgcmV0dXJuXG4gIH1cblxuICBnZXQgZG9tKCk6IEhUTUxFbGVtZW50IHtcbiAgICByZXR1cm4gdGhpcy5lZGl0b3Iudmlldy5kb20gYXMgSFRNTEVsZW1lbnRcbiAgfVxuXG4gIGdldCBjb250ZW50RE9NKCk6IEhUTUxFbGVtZW50IHwgbnVsbCB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIG9uRHJhZ1N0YXJ0KGV2ZW50OiBEcmFnRXZlbnQpIHtcbiAgICBjb25zdCB7IHZpZXcgfSA9IHRoaXMuZWRpdG9yXG4gICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50XG5cbiAgICAvLyBnZXQgdGhlIGRyYWcgaGFuZGxlIGVsZW1lbnRcbiAgICAvLyBgY2xvc2VzdGAgaXMgbm90IGF2YWlsYWJsZSBmb3IgdGV4dCBub2RlcyBzbyB3ZSBtYXkgaGF2ZSB0byB1c2UgaXRzIHBhcmVudFxuICAgIGNvbnN0IGRyYWdIYW5kbGUgPSB0YXJnZXQubm9kZVR5cGUgPT09IDNcbiAgICAgID8gdGFyZ2V0LnBhcmVudEVsZW1lbnQ/LmNsb3Nlc3QoJ1tkYXRhLWRyYWctaGFuZGxlXScpXG4gICAgICA6IHRhcmdldC5jbG9zZXN0KCdbZGF0YS1kcmFnLWhhbmRsZV0nKVxuXG4gICAgaWYgKCF0aGlzLmRvbSB8fCB0aGlzLmNvbnRlbnRET00/LmNvbnRhaW5zKHRhcmdldCkgfHwgIWRyYWdIYW5kbGUpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGxldCB4ID0gMFxuICAgIGxldCB5ID0gMFxuXG4gICAgLy8gY2FsY3VsYXRlIG9mZnNldCBmb3IgZHJhZyBlbGVtZW50IGlmIHdlIHVzZSBhIGRpZmZlcmVudCBkcmFnIGhhbmRsZSBlbGVtZW50XG4gICAgaWYgKHRoaXMuZG9tICE9PSBkcmFnSGFuZGxlKSB7XG4gICAgICBjb25zdCBkb21Cb3ggPSB0aGlzLmRvbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgICAgY29uc3QgaGFuZGxlQm94ID0gZHJhZ0hhbmRsZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuXG4gICAgICAvLyBJbiBSZWFjdCwgd2UgaGF2ZSB0byBnbyB0aHJvdWdoIG5hdGl2ZUV2ZW50IHRvIHJlYWNoIG9mZnNldFgvb2Zmc2V0WS5cbiAgICAgIGNvbnN0IG9mZnNldFggPSBldmVudC5vZmZzZXRYID8/IChldmVudCBhcyBhbnkpLm5hdGl2ZUV2ZW50Py5vZmZzZXRYXG4gICAgICBjb25zdCBvZmZzZXRZID0gZXZlbnQub2Zmc2V0WSA/PyAoZXZlbnQgYXMgYW55KS5uYXRpdmVFdmVudD8ub2Zmc2V0WVxuXG4gICAgICB4ID0gaGFuZGxlQm94LnggLSBkb21Cb3gueCArIG9mZnNldFhcbiAgICAgIHkgPSBoYW5kbGVCb3gueSAtIGRvbUJveC55ICsgb2Zmc2V0WVxuICAgIH1cblxuICAgIGNvbnN0IGNsb25lZE5vZGUgPSB0aGlzLmRvbS5jbG9uZU5vZGUodHJ1ZSkgYXMgSFRNTEVsZW1lbnRcblxuICAgIGV2ZW50LmRhdGFUcmFuc2Zlcj8uc2V0RHJhZ0ltYWdlKGNsb25lZE5vZGUsIHgsIHkpXG5cbiAgICBjb25zdCBwb3MgPSB0aGlzLmdldFBvcygpXG5cbiAgICBpZiAodHlwZW9mIHBvcyAhPT0gJ251bWJlcicpIHtcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICAvLyB3ZSBuZWVkIHRvIHRlbGwgUHJvc2VNaXJyb3IgdGhhdCB3ZSB3YW50IHRvIG1vdmUgdGhlIHdob2xlIG5vZGVcbiAgICAvLyBzbyB3ZSBjcmVhdGUgYSBOb2RlU2VsZWN0aW9uXG4gICAgY29uc3Qgc2VsZWN0aW9uID0gTm9kZVNlbGVjdGlvbi5jcmVhdGUodmlldy5zdGF0ZS5kb2MsIHBvcylcbiAgICBjb25zdCB0cmFuc2FjdGlvbiA9IHZpZXcuc3RhdGUudHIuc2V0U2VsZWN0aW9uKHNlbGVjdGlvbilcblxuICAgIHZpZXcuZGlzcGF0Y2godHJhbnNhY3Rpb24pXG4gIH1cblxuICBzdG9wRXZlbnQoZXZlbnQ6IEV2ZW50KSB7XG4gICAgaWYgKCF0aGlzLmRvbSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiB0aGlzLm9wdGlvbnMuc3RvcEV2ZW50ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gdGhpcy5vcHRpb25zLnN0b3BFdmVudCh7IGV2ZW50IH0pXG4gICAgfVxuXG4gICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50XG4gICAgY29uc3QgaXNJbkVsZW1lbnQgPSB0aGlzLmRvbS5jb250YWlucyh0YXJnZXQpICYmICF0aGlzLmNvbnRlbnRET00/LmNvbnRhaW5zKHRhcmdldClcblxuICAgIC8vIGFueSBldmVudCBmcm9tIGNoaWxkIG5vZGVzIHNob3VsZCBiZSBoYW5kbGVkIGJ5IFByb3NlTWlycm9yXG4gICAgaWYgKCFpc0luRWxlbWVudCkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgY29uc3QgaXNEcmFnRXZlbnQgPSBldmVudC50eXBlLnN0YXJ0c1dpdGgoJ2RyYWcnKVxuICAgIGNvbnN0IGlzRHJvcEV2ZW50ID0gZXZlbnQudHlwZSA9PT0gJ2Ryb3AnXG4gICAgY29uc3QgaXNJbnB1dCA9IFsnSU5QVVQnLCAnQlVUVE9OJywgJ1NFTEVDVCcsICdURVhUQVJFQSddLmluY2x1ZGVzKHRhcmdldC50YWdOYW1lKSB8fCB0YXJnZXQuaXNDb250ZW50RWRpdGFibGVcblxuICAgIC8vIGFueSBpbnB1dCBldmVudCB3aXRoaW4gbm9kZSB2aWV3cyBzaG91bGQgYmUgaWdub3JlZCBieSBQcm9zZU1pcnJvclxuICAgIGlmIChpc0lucHV0ICYmICFpc0Ryb3BFdmVudCAmJiAhaXNEcmFnRXZlbnQpIHtcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgY29uc3QgeyBpc0VkaXRhYmxlIH0gPSB0aGlzLmVkaXRvclxuICAgIGNvbnN0IHsgaXNEcmFnZ2luZyB9ID0gdGhpc1xuICAgIGNvbnN0IGlzRHJhZ2dhYmxlID0gISF0aGlzLm5vZGUudHlwZS5zcGVjLmRyYWdnYWJsZVxuICAgIGNvbnN0IGlzU2VsZWN0YWJsZSA9IE5vZGVTZWxlY3Rpb24uaXNTZWxlY3RhYmxlKHRoaXMubm9kZSlcbiAgICBjb25zdCBpc0NvcHlFdmVudCA9IGV2ZW50LnR5cGUgPT09ICdjb3B5J1xuICAgIGNvbnN0IGlzUGFzdGVFdmVudCA9IGV2ZW50LnR5cGUgPT09ICdwYXN0ZSdcbiAgICBjb25zdCBpc0N1dEV2ZW50ID0gZXZlbnQudHlwZSA9PT0gJ2N1dCdcbiAgICBjb25zdCBpc0NsaWNrRXZlbnQgPSBldmVudC50eXBlID09PSAnbW91c2Vkb3duJ1xuXG4gICAgLy8gUHJvc2VNaXJyb3IgdHJpZXMgdG8gZHJhZyBzZWxlY3RhYmxlIG5vZGVzXG4gICAgLy8gZXZlbiBpZiBgZHJhZ2dhYmxlYCBpcyBzZXQgdG8gYGZhbHNlYFxuICAgIC8vIHRoaXMgZml4IHByZXZlbnRzIHRoYXRcbiAgICBpZiAoIWlzRHJhZ2dhYmxlICYmIGlzU2VsZWN0YWJsZSAmJiBpc0RyYWdFdmVudCAmJiBldmVudC50YXJnZXQgPT09IHRoaXMuZG9tKSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpXG4gICAgfVxuXG4gICAgaWYgKGlzRHJhZ2dhYmxlICYmIGlzRHJhZ0V2ZW50ICYmICFpc0RyYWdnaW5nICYmIGV2ZW50LnRhcmdldCA9PT0gdGhpcy5kb20pIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KClcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIC8vIHdlIGhhdmUgdG8gc3RvcmUgdGhhdCBkcmFnZ2luZyBzdGFydGVkXG4gICAgaWYgKGlzRHJhZ2dhYmxlICYmIGlzRWRpdGFibGUgJiYgIWlzRHJhZ2dpbmcgJiYgaXNDbGlja0V2ZW50KSB7XG4gICAgICBjb25zdCBkcmFnSGFuZGxlID0gdGFyZ2V0LmNsb3Nlc3QoJ1tkYXRhLWRyYWctaGFuZGxlXScpXG4gICAgICBjb25zdCBpc1ZhbGlkRHJhZ0hhbmRsZSA9IGRyYWdIYW5kbGUgJiYgKHRoaXMuZG9tID09PSBkcmFnSGFuZGxlIHx8IHRoaXMuZG9tLmNvbnRhaW5zKGRyYWdIYW5kbGUpKVxuXG4gICAgICBpZiAoaXNWYWxpZERyYWdIYW5kbGUpIHtcbiAgICAgICAgdGhpcy5pc0RyYWdnaW5nID0gdHJ1ZVxuXG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgJ2RyYWdlbmQnLFxuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IGZhbHNlXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7IG9uY2U6IHRydWUgfSxcbiAgICAgICAgKVxuXG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgJ2Ryb3AnLFxuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IGZhbHNlXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7IG9uY2U6IHRydWUgfSxcbiAgICAgICAgKVxuXG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXG4gICAgICAgICAgJ21vdXNldXAnLFxuICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IGZhbHNlXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7IG9uY2U6IHRydWUgfSxcbiAgICAgICAgKVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHRoZXNlIGV2ZW50cyBhcmUgaGFuZGxlZCBieSBwcm9zZW1pcnJvclxuICAgIGlmIChcbiAgICAgIGlzRHJhZ2dpbmdcbiAgICAgIHx8IGlzRHJvcEV2ZW50XG4gICAgICB8fCBpc0NvcHlFdmVudFxuICAgICAgfHwgaXNQYXN0ZUV2ZW50XG4gICAgICB8fCBpc0N1dEV2ZW50XG4gICAgICB8fCAoaXNDbGlja0V2ZW50ICYmIGlzU2VsZWN0YWJsZSlcbiAgICApIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICAvKipcbiAgICogQ2FsbGVkIHdoZW4gYSBET00gW211dGF0aW9uXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvTXV0YXRpb25PYnNlcnZlcikgb3IgYSBzZWxlY3Rpb24gY2hhbmdlIGhhcHBlbnMgd2l0aGluIHRoZSB2aWV3LlxuICAgKiBAcmV0dXJuIGBmYWxzZWAgaWYgdGhlIGVkaXRvciBzaG91bGQgcmUtcmVhZCB0aGUgc2VsZWN0aW9uIG9yIHJlLXBhcnNlIHRoZSByYW5nZSBhcm91bmQgdGhlIG11dGF0aW9uXG4gICAqIEByZXR1cm4gYHRydWVgIGlmIGl0IGNhbiBzYWZlbHkgYmUgaWdub3JlZC5cbiAgICovXG4gIGlnbm9yZU11dGF0aW9uKG11dGF0aW9uOiBWaWV3TXV0YXRpb25SZWNvcmQpIHtcbiAgICBpZiAoIXRoaXMuZG9tIHx8ICF0aGlzLmNvbnRlbnRET00pIHtcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiB0aGlzLm9wdGlvbnMuaWdub3JlTXV0YXRpb24gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMuaWdub3JlTXV0YXRpb24oeyBtdXRhdGlvbiB9KVxuICAgIH1cblxuICAgIC8vIGEgbGVhZi9hdG9tIG5vZGUgaXMgbGlrZSBhIGJsYWNrIGJveCBmb3IgUHJvc2VNaXJyb3JcbiAgICAvLyBhbmQgc2hvdWxkIGJlIGZ1bGx5IGhhbmRsZWQgYnkgdGhlIG5vZGUgdmlld1xuICAgIGlmICh0aGlzLm5vZGUuaXNMZWFmIHx8IHRoaXMubm9kZS5pc0F0b20pIHtcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgLy8gUHJvc2VNaXJyb3Igc2hvdWxkIGhhbmRsZSBhbnkgc2VsZWN0aW9uc1xuICAgIGlmIChtdXRhdGlvbi50eXBlID09PSAnc2VsZWN0aW9uJykge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgLy8gdHJ5IHRvIHByZXZlbnQgYSBidWcgb24gaU9TIGFuZCBBbmRyb2lkIHRoYXQgd2lsbCBicmVhayBub2RlIHZpZXdzIG9uIGVudGVyXG4gICAgLy8gdGhpcyBpcyBiZWNhdXNlIFByb3NlTWlycm9yIGNhbuKAmXQgcHJldmVudERpc3BhdGNoIG9uIGVudGVyXG4gICAgLy8gdGhpcyB3aWxsIGxlYWQgdG8gYSByZS1yZW5kZXIgb2YgdGhlIG5vZGUgdmlldyBvbiBlbnRlclxuICAgIC8vIHNlZTogaHR0cHM6Ly9naXRodWIuY29tL3VlYmVyZG9zaXMvdGlwdGFwL2lzc3Vlcy8xMjE0XG4gICAgLy8gc2VlOiBodHRwczovL2dpdGh1Yi5jb20vdWViZXJkb3Npcy90aXB0YXAvaXNzdWVzLzI1MzRcbiAgICBpZiAoXG4gICAgICB0aGlzLmRvbS5jb250YWlucyhtdXRhdGlvbi50YXJnZXQpXG4gICAgICAmJiBtdXRhdGlvbi50eXBlID09PSAnY2hpbGRMaXN0J1xuICAgICAgJiYgKGlzaU9TKCkgfHwgaXNBbmRyb2lkKCkpXG4gICAgICAmJiB0aGlzLmVkaXRvci5pc0ZvY3VzZWRcbiAgICApIHtcbiAgICAgIGNvbnN0IGNoYW5nZWROb2RlcyA9IFtcbiAgICAgICAgLi4uQXJyYXkuZnJvbShtdXRhdGlvbi5hZGRlZE5vZGVzKSxcbiAgICAgICAgLi4uQXJyYXkuZnJvbShtdXRhdGlvbi5yZW1vdmVkTm9kZXMpLFxuICAgICAgXSBhcyBIVE1MRWxlbWVudFtdXG5cbiAgICAgIC8vIHdl4oCZbGwgY2hlY2sgaWYgZXZlcnkgY2hhbmdlZCBub2RlIGlzIGNvbnRlbnRFZGl0YWJsZVxuICAgICAgLy8gdG8gbWFrZSBzdXJlIGl04oCZcyBwcm9iYWJseSBtdXRhdGVkIGJ5IFByb3NlTWlycm9yXG4gICAgICBpZiAoY2hhbmdlZE5vZGVzLmV2ZXJ5KG5vZGUgPT4gbm9kZS5pc0NvbnRlbnRFZGl0YWJsZSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gd2Ugd2lsbCBhbGxvdyBtdXRhdGlvbiBjb250ZW50RE9NIHdpdGggYXR0cmlidXRlc1xuICAgIC8vIHNvIHdlIGNhbiBmb3IgZXhhbXBsZSBhZGRpbmcgY2xhc3NlcyB3aXRoaW4gb3VyIG5vZGUgdmlld1xuICAgIGlmICh0aGlzLmNvbnRlbnRET00gPT09IG11dGF0aW9uLnRhcmdldCAmJiBtdXRhdGlvbi50eXBlID09PSAnYXR0cmlidXRlcycpIHtcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgLy8gUHJvc2VNaXJyb3Igc2hvdWxkIGhhbmRsZSBhbnkgY2hhbmdlcyB3aXRoaW4gY29udGVudERPTVxuICAgIGlmICh0aGlzLmNvbnRlbnRET00uY29udGFpbnMobXV0YXRpb24udGFyZ2V0KSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgdGhlIGF0dHJpYnV0ZXMgb2YgdGhlIHByb3NlbWlycm9yIG5vZGUuXG4gICAqL1xuICB1cGRhdGVBdHRyaWJ1dGVzKGF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIGFueT4pOiB2b2lkIHtcbiAgICB0aGlzLmVkaXRvci5jb21tYW5kcy5jb21tYW5kKCh7IHRyIH0pID0+IHtcbiAgICAgIGNvbnN0IHBvcyA9IHRoaXMuZ2V0UG9zKClcblxuICAgICAgaWYgKHR5cGVvZiBwb3MgIT09ICdudW1iZXInKSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfVxuXG4gICAgICB0ci5zZXROb2RlTWFya3VwKHBvcywgdW5kZWZpbmVkLCB7XG4gICAgICAgIC4uLnRoaXMubm9kZS5hdHRycyxcbiAgICAgICAgLi4uYXR0cmlidXRlcyxcbiAgICAgIH0pXG5cbiAgICAgIHJldHVybiB0cnVlXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGUgdGhlIG5vZGUuXG4gICAqL1xuICBkZWxldGVOb2RlKCk6IHZvaWQge1xuICAgIGNvbnN0IGZyb20gPSB0aGlzLmdldFBvcygpXG5cbiAgICBpZiAodHlwZW9mIGZyb20gIT09ICdudW1iZXInKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgY29uc3QgdG8gPSBmcm9tICsgdGhpcy5ub2RlLm5vZGVTaXplXG5cbiAgICB0aGlzLmVkaXRvci5jb21tYW5kcy5kZWxldGVSYW5nZSh7IGZyb20sIHRvIH0pXG4gIH1cbn1cbiIsICJpbXBvcnQgeyBNYXJrVHlwZSB9IGZyb20gJ0B0aXB0YXAvcG0vbW9kZWwnXG5cbmltcG9ydCB7IGdldE1hcmtzQmV0d2VlbiB9IGZyb20gJy4uL2hlbHBlcnMvZ2V0TWFya3NCZXR3ZWVuLmpzJ1xuaW1wb3J0IHsgUGFzdGVSdWxlLCBQYXN0ZVJ1bGVGaW5kZXIgfSBmcm9tICcuLi9QYXN0ZVJ1bGUuanMnXG5pbXBvcnQgeyBFeHRlbmRlZFJlZ0V4cE1hdGNoQXJyYXkgfSBmcm9tICcuLi90eXBlcy5qcydcbmltcG9ydCB7IGNhbGxPclJldHVybiB9IGZyb20gJy4uL3V0aWxpdGllcy9jYWxsT3JSZXR1cm4uanMnXG5cbi8qKlxuICogQnVpbGQgYW4gcGFzdGUgcnVsZSB0aGF0IGFkZHMgYSBtYXJrIHdoZW4gdGhlXG4gKiBtYXRjaGVkIHRleHQgaXMgcGFzdGVkIGludG8gaXQuXG4gKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9kb2NzL2VkaXRvci9leHRlbnNpb25zL2N1c3RvbS1leHRlbnNpb25zL2V4dGVuZC1leGlzdGluZyNwYXN0ZS1ydWxlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gbWFya1Bhc3RlUnVsZShjb25maWc6IHtcbiAgZmluZDogUGFzdGVSdWxlRmluZGVyXG4gIHR5cGU6IE1hcmtUeXBlXG4gIGdldEF0dHJpYnV0ZXM/OlxuICAgIHwgUmVjb3JkPHN0cmluZywgYW55PlxuICAgIHwgKChtYXRjaDogRXh0ZW5kZWRSZWdFeHBNYXRjaEFycmF5LCBldmVudDogQ2xpcGJvYXJkRXZlbnQpID0+IFJlY29yZDxzdHJpbmcsIGFueT4pXG4gICAgfCBmYWxzZVxuICAgIHwgbnVsbFxufSkge1xuICByZXR1cm4gbmV3IFBhc3RlUnVsZSh7XG4gICAgZmluZDogY29uZmlnLmZpbmQsXG4gICAgaGFuZGxlcjogKHtcbiAgICAgIHN0YXRlLCByYW5nZSwgbWF0Y2gsIHBhc3RlRXZlbnQsXG4gICAgfSkgPT4ge1xuICAgICAgY29uc3QgYXR0cmlidXRlcyA9IGNhbGxPclJldHVybihjb25maWcuZ2V0QXR0cmlidXRlcywgdW5kZWZpbmVkLCBtYXRjaCwgcGFzdGVFdmVudClcblxuICAgICAgaWYgKGF0dHJpYnV0ZXMgPT09IGZhbHNlIHx8IGF0dHJpYnV0ZXMgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgIH1cblxuICAgICAgY29uc3QgeyB0ciB9ID0gc3RhdGVcbiAgICAgIGNvbnN0IGNhcHR1cmVHcm91cCA9IG1hdGNoW21hdGNoLmxlbmd0aCAtIDFdXG4gICAgICBjb25zdCBmdWxsTWF0Y2ggPSBtYXRjaFswXVxuICAgICAgbGV0IG1hcmtFbmQgPSByYW5nZS50b1xuXG4gICAgICBpZiAoY2FwdHVyZUdyb3VwKSB7XG4gICAgICAgIGNvbnN0IHN0YXJ0U3BhY2VzID0gZnVsbE1hdGNoLnNlYXJjaCgvXFxTLylcbiAgICAgICAgY29uc3QgdGV4dFN0YXJ0ID0gcmFuZ2UuZnJvbSArIGZ1bGxNYXRjaC5pbmRleE9mKGNhcHR1cmVHcm91cClcbiAgICAgICAgY29uc3QgdGV4dEVuZCA9IHRleHRTdGFydCArIGNhcHR1cmVHcm91cC5sZW5ndGhcblxuICAgICAgICBjb25zdCBleGNsdWRlZE1hcmtzID0gZ2V0TWFya3NCZXR3ZWVuKHJhbmdlLmZyb20sIHJhbmdlLnRvLCBzdGF0ZS5kb2MpXG4gICAgICAgICAgLmZpbHRlcihpdGVtID0+IHtcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgICAgIGNvbnN0IGV4Y2x1ZGVkID0gaXRlbS5tYXJrLnR5cGUuZXhjbHVkZWQgYXMgTWFya1R5cGVbXVxuXG4gICAgICAgICAgICByZXR1cm4gZXhjbHVkZWQuZmluZCh0eXBlID0+IHR5cGUgPT09IGNvbmZpZy50eXBlICYmIHR5cGUgIT09IGl0ZW0ubWFyay50eXBlKVxuICAgICAgICAgIH0pXG4gICAgICAgICAgLmZpbHRlcihpdGVtID0+IGl0ZW0udG8gPiB0ZXh0U3RhcnQpXG5cbiAgICAgICAgaWYgKGV4Y2x1ZGVkTWFya3MubGVuZ3RoKSB7XG4gICAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0ZXh0RW5kIDwgcmFuZ2UudG8pIHtcbiAgICAgICAgICB0ci5kZWxldGUodGV4dEVuZCwgcmFuZ2UudG8pXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGV4dFN0YXJ0ID4gcmFuZ2UuZnJvbSkge1xuICAgICAgICAgIHRyLmRlbGV0ZShyYW5nZS5mcm9tICsgc3RhcnRTcGFjZXMsIHRleHRTdGFydClcbiAgICAgICAgfVxuXG4gICAgICAgIG1hcmtFbmQgPSByYW5nZS5mcm9tICsgc3RhcnRTcGFjZXMgKyBjYXB0dXJlR3JvdXAubGVuZ3RoXG5cbiAgICAgICAgdHIuYWRkTWFyayhyYW5nZS5mcm9tICsgc3RhcnRTcGFjZXMsIG1hcmtFbmQsIGNvbmZpZy50eXBlLmNyZWF0ZShhdHRyaWJ1dGVzIHx8IHt9KSlcblxuICAgICAgICB0ci5yZW1vdmVTdG9yZWRNYXJrKGNvbmZpZy50eXBlKVxuICAgICAgfVxuICAgIH0sXG4gIH0pXG59XG4iLCAiLy8gc291cmNlOiBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvNjk2OTQ4NlxuZXhwb3J0IGZ1bmN0aW9uIGVzY2FwZUZvclJlZ0V4KHN0cmluZzogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHN0cmluZy5yZXBsYWNlKC9bLS9cXFxcXiQqKz8uKCl8W1xcXXt9XS9nLCAnXFxcXCQmJylcbn1cbiIsICJleHBvcnQgZnVuY3Rpb24gaXNTdHJpbmcodmFsdWU6IGFueSk6IHZhbHVlIGlzIHN0cmluZyB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnXG59XG4iLCAiaW1wb3J0IHsgTm9kZVR5cGUgfSBmcm9tICdAdGlwdGFwL3BtL21vZGVsJ1xuXG5pbXBvcnQgeyBQYXN0ZVJ1bGUsIFBhc3RlUnVsZUZpbmRlciB9IGZyb20gJy4uL1Bhc3RlUnVsZS5qcydcbmltcG9ydCB7IEV4dGVuZGVkUmVnRXhwTWF0Y2hBcnJheSwgSlNPTkNvbnRlbnQgfSBmcm9tICcuLi90eXBlcy5qcydcbmltcG9ydCB7IGNhbGxPclJldHVybiB9IGZyb20gJy4uL3V0aWxpdGllcy9pbmRleC5qcydcblxuLyoqXG4gKiBCdWlsZCBhbiBwYXN0ZSBydWxlIHRoYXQgYWRkcyBhIG5vZGUgd2hlbiB0aGVcbiAqIG1hdGNoZWQgdGV4dCBpcyBwYXN0ZWQgaW50byBpdC5cbiAqIEBzZWUgaHR0cHM6Ly90aXB0YXAuZGV2L2RvY3MvZWRpdG9yL2V4dGVuc2lvbnMvY3VzdG9tLWV4dGVuc2lvbnMvZXh0ZW5kLWV4aXN0aW5nI3Bhc3RlLXJ1bGVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub2RlUGFzdGVSdWxlKGNvbmZpZzoge1xuICBmaW5kOiBQYXN0ZVJ1bGVGaW5kZXJcbiAgdHlwZTogTm9kZVR5cGVcbiAgZ2V0QXR0cmlidXRlcz86XG4gICAgfCBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gICAgfCAoKG1hdGNoOiBFeHRlbmRlZFJlZ0V4cE1hdGNoQXJyYXksIGV2ZW50OiBDbGlwYm9hcmRFdmVudCkgPT4gUmVjb3JkPHN0cmluZywgYW55PilcbiAgICB8IGZhbHNlXG4gICAgfCBudWxsXG4gIGdldENvbnRlbnQ/OlxuICAgIHwgSlNPTkNvbnRlbnRbXVxuICAgIHwgKChhdHRyczogUmVjb3JkPHN0cmluZywgYW55PikgPT4gSlNPTkNvbnRlbnRbXSlcbiAgICB8IGZhbHNlXG4gICAgfCBudWxsXG59KSB7XG4gIHJldHVybiBuZXcgUGFzdGVSdWxlKHtcbiAgICBmaW5kOiBjb25maWcuZmluZCxcbiAgICBoYW5kbGVyKHtcbiAgICAgIG1hdGNoLCBjaGFpbiwgcmFuZ2UsIHBhc3RlRXZlbnQsXG4gICAgfSkge1xuICAgICAgY29uc3QgYXR0cmlidXRlcyA9IGNhbGxPclJldHVybihjb25maWcuZ2V0QXR0cmlidXRlcywgdW5kZWZpbmVkLCBtYXRjaCwgcGFzdGVFdmVudClcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSBjYWxsT3JSZXR1cm4oY29uZmlnLmdldENvbnRlbnQsIHVuZGVmaW5lZCwgYXR0cmlidXRlcylcblxuICAgICAgaWYgKGF0dHJpYnV0ZXMgPT09IGZhbHNlIHx8IGF0dHJpYnV0ZXMgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgIH1cblxuICAgICAgY29uc3Qgbm9kZSA9IHsgdHlwZTogY29uZmlnLnR5cGUubmFtZSwgYXR0cnM6IGF0dHJpYnV0ZXMgfSBhcyBKU09OQ29udGVudFxuXG4gICAgICBpZiAoY29udGVudCkge1xuICAgICAgICBub2RlLmNvbnRlbnQgPSBjb250ZW50XG4gICAgICB9XG5cbiAgICAgIGlmIChtYXRjaC5pbnB1dCkge1xuICAgICAgICBjaGFpbigpLmRlbGV0ZVJhbmdlKHJhbmdlKS5pbnNlcnRDb250ZW50QXQocmFuZ2UuZnJvbSwgbm9kZSlcbiAgICAgIH1cbiAgICB9LFxuICB9KVxufVxuIiwgImltcG9ydCB7IFBhc3RlUnVsZSwgUGFzdGVSdWxlRmluZGVyIH0gZnJvbSAnLi4vUGFzdGVSdWxlLmpzJ1xuXG4vKipcbiAqIEJ1aWxkIGFuIHBhc3RlIHJ1bGUgdGhhdCByZXBsYWNlcyB0ZXh0IHdoZW4gdGhlXG4gKiBtYXRjaGVkIHRleHQgaXMgcGFzdGVkIGludG8gaXQuXG4gKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9kb2NzL2VkaXRvci9leHRlbnNpb25zL2N1c3RvbS1leHRlbnNpb25zL2V4dGVuZC1leGlzdGluZyNwYXN0ZS1ydWxlc1xuICovXG5leHBvcnQgZnVuY3Rpb24gdGV4dFBhc3RlUnVsZShjb25maWc6IHtcbiAgZmluZDogUGFzdGVSdWxlRmluZGVyLFxuICByZXBsYWNlOiBzdHJpbmcsXG59KSB7XG4gIHJldHVybiBuZXcgUGFzdGVSdWxlKHtcbiAgICBmaW5kOiBjb25maWcuZmluZCxcbiAgICBoYW5kbGVyOiAoeyBzdGF0ZSwgcmFuZ2UsIG1hdGNoIH0pID0+IHtcbiAgICAgIGxldCBpbnNlcnQgPSBjb25maWcucmVwbGFjZVxuICAgICAgbGV0IHN0YXJ0ID0gcmFuZ2UuZnJvbVxuICAgICAgY29uc3QgZW5kID0gcmFuZ2UudG9cblxuICAgICAgaWYgKG1hdGNoWzFdKSB7XG4gICAgICAgIGNvbnN0IG9mZnNldCA9IG1hdGNoWzBdLmxhc3RJbmRleE9mKG1hdGNoWzFdKVxuXG4gICAgICAgIGluc2VydCArPSBtYXRjaFswXS5zbGljZShvZmZzZXQgKyBtYXRjaFsxXS5sZW5ndGgpXG4gICAgICAgIHN0YXJ0ICs9IG9mZnNldFxuXG4gICAgICAgIGNvbnN0IGN1dE9mZiA9IHN0YXJ0IC0gZW5kXG5cbiAgICAgICAgaWYgKGN1dE9mZiA+IDApIHtcbiAgICAgICAgICBpbnNlcnQgPSBtYXRjaFswXS5zbGljZShvZmZzZXQgLSBjdXRPZmYsIG9mZnNldCkgKyBpbnNlcnRcbiAgICAgICAgICBzdGFydCA9IGVuZFxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHN0YXRlLnRyLmluc2VydFRleHQoaW5zZXJ0LCBzdGFydCwgZW5kKVxuICAgIH0sXG4gIH0pXG59XG4iLCAiaW1wb3J0IHsgVHJhbnNhY3Rpb24gfSBmcm9tICdAdGlwdGFwL3BtL3N0YXRlJ1xuXG5leHBvcnQgaW50ZXJmYWNlIFRyYWNrZXJSZXN1bHQge1xuICBwb3NpdGlvbjogbnVtYmVyXG4gIGRlbGV0ZWQ6IGJvb2xlYW5cbn1cblxuZXhwb3J0IGNsYXNzIFRyYWNrZXIge1xuICB0cmFuc2FjdGlvbjogVHJhbnNhY3Rpb25cblxuICBjdXJyZW50U3RlcDogbnVtYmVyXG5cbiAgY29uc3RydWN0b3IodHJhbnNhY3Rpb246IFRyYW5zYWN0aW9uKSB7XG4gICAgdGhpcy50cmFuc2FjdGlvbiA9IHRyYW5zYWN0aW9uXG4gICAgdGhpcy5jdXJyZW50U3RlcCA9IHRoaXMudHJhbnNhY3Rpb24uc3RlcHMubGVuZ3RoXG4gIH1cblxuICBtYXAocG9zaXRpb246IG51bWJlcik6IFRyYWNrZXJSZXN1bHQge1xuICAgIGxldCBkZWxldGVkID0gZmFsc2VcblxuICAgIGNvbnN0IG1hcHBlZFBvc2l0aW9uID0gdGhpcy50cmFuc2FjdGlvbi5zdGVwc1xuICAgICAgLnNsaWNlKHRoaXMuY3VycmVudFN0ZXApXG4gICAgICAucmVkdWNlKChuZXdQb3NpdGlvbiwgc3RlcCkgPT4ge1xuICAgICAgICBjb25zdCBtYXBSZXN1bHQgPSBzdGVwLmdldE1hcCgpLm1hcFJlc3VsdChuZXdQb3NpdGlvbilcblxuICAgICAgICBpZiAobWFwUmVzdWx0LmRlbGV0ZWQpIHtcbiAgICAgICAgICBkZWxldGVkID0gdHJ1ZVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG1hcFJlc3VsdC5wb3NcbiAgICAgIH0sIHBvc2l0aW9uKVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHBvc2l0aW9uOiBtYXBwZWRQb3NpdGlvbixcbiAgICAgIGRlbGV0ZWQsXG4gICAgfVxuICB9XG59XG4iLCAiaW1wb3J0IHsgTm9kZSB9IGZyb20gJ0B0aXB0YXAvY29yZSdcblxuLyoqXG4gKiBUaGUgZGVmYXVsdCBkb2N1bWVudCBub2RlIHdoaWNoIHJlcHJlc2VudHMgdGhlIHRvcCBsZXZlbCBub2RlIG9mIHRoZSBlZGl0b3IuXG4gKiBAc2VlIGh0dHBzOi8vdGlwdGFwLmRldi9hcGkvbm9kZXMvZG9jdW1lbnRcbiAqL1xuZXhwb3J0IGNvbnN0IERvY3VtZW50ID0gTm9kZS5jcmVhdGUoe1xuICBuYW1lOiAnZG9jJyxcbiAgdG9wTm9kZTogdHJ1ZSxcbiAgY29udGVudDogJ2Jsb2NrKycsXG59KVxuIiwgImltcG9ydCB7IG1lcmdlQXR0cmlidXRlcywgTm9kZSB9IGZyb20gJ0B0aXB0YXAvY29yZSdcblxuZXhwb3J0IGludGVyZmFjZSBQYXJhZ3JhcGhPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBIVE1MIGF0dHJpYnV0ZXMgZm9yIGEgcGFyYWdyYXBoIG5vZGUuXG4gICAqIEBkZWZhdWx0IHt9XG4gICAqIEBleGFtcGxlIHsgY2xhc3M6ICdmb28nIH1cbiAgICovXG4gIEhUTUxBdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxufVxuXG5kZWNsYXJlIG1vZHVsZSAnQHRpcHRhcC9jb3JlJyB7XG4gIGludGVyZmFjZSBDb21tYW5kczxSZXR1cm5UeXBlPiB7XG4gICAgcGFyYWdyYXBoOiB7XG4gICAgICAvKipcbiAgICAgICAqIFRvZ2dsZSBhIHBhcmFncmFwaFxuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnRvZ2dsZVBhcmFncmFwaCgpXG4gICAgICAgKi9cbiAgICAgIHNldFBhcmFncmFwaDogKCkgPT4gUmV0dXJuVHlwZSxcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBUaGlzIGV4dGVuc2lvbiBhbGxvd3MgeW91IHRvIGNyZWF0ZSBwYXJhZ3JhcGhzLlxuICogQHNlZSBodHRwczovL3d3dy50aXB0YXAuZGV2L2FwaS9ub2Rlcy9wYXJhZ3JhcGhcbiAqL1xuZXhwb3J0IGNvbnN0IFBhcmFncmFwaCA9IE5vZGUuY3JlYXRlPFBhcmFncmFwaE9wdGlvbnM+KHtcbiAgbmFtZTogJ3BhcmFncmFwaCcsXG5cbiAgcHJpb3JpdHk6IDEwMDAsXG5cbiAgYWRkT3B0aW9ucygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgSFRNTEF0dHJpYnV0ZXM6IHt9LFxuICAgIH1cbiAgfSxcblxuICBncm91cDogJ2Jsb2NrJyxcblxuICBjb250ZW50OiAnaW5saW5lKicsXG5cbiAgcGFyc2VIVE1MKCkge1xuICAgIHJldHVybiBbXG4gICAgICB7IHRhZzogJ3AnIH0sXG4gICAgXVxuICB9LFxuXG4gIHJlbmRlckhUTUwoeyBIVE1MQXR0cmlidXRlcyB9KSB7XG4gICAgcmV0dXJuIFsncCcsIG1lcmdlQXR0cmlidXRlcyh0aGlzLm9wdGlvbnMuSFRNTEF0dHJpYnV0ZXMsIEhUTUxBdHRyaWJ1dGVzKSwgMF1cbiAgfSxcblxuICBhZGRDb21tYW5kcygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc2V0UGFyYWdyYXBoOiAoKSA9PiAoeyBjb21tYW5kcyB9KSA9PiB7XG4gICAgICAgIHJldHVybiBjb21tYW5kcy5zZXROb2RlKHRoaXMubmFtZSlcbiAgICAgIH0sXG4gICAgfVxuICB9LFxuXG4gIGFkZEtleWJvYXJkU2hvcnRjdXRzKCkge1xuICAgIHJldHVybiB7XG4gICAgICAnTW9kLUFsdC0wJzogKCkgPT4gdGhpcy5lZGl0b3IuY29tbWFuZHMuc2V0UGFyYWdyYXBoKCksXG4gICAgfVxuICB9LFxufSlcbiIsICJpbXBvcnQgeyBOb2RlIH0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuXG4vKipcbiAqIFRoaXMgZXh0ZW5zaW9uIGFsbG93cyB5b3UgdG8gY3JlYXRlIHRleHQgbm9kZXMuXG4gKiBAc2VlIGh0dHBzOi8vd3d3LnRpcHRhcC5kZXYvYXBpL25vZGVzL3RleHRcbiAqL1xuZXhwb3J0IGNvbnN0IFRleHQgPSBOb2RlLmNyZWF0ZSh7XG4gIG5hbWU6ICd0ZXh0JyxcbiAgZ3JvdXA6ICdpbmxpbmUnLFxufSlcbiIsICJpbXBvcnQgeyBtZXJnZUF0dHJpYnV0ZXMsIE5vZGUgfSBmcm9tICdAdGlwdGFwL2NvcmUnXG5cbmV4cG9ydCBpbnRlcmZhY2UgSGFyZEJyZWFrT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBDb250cm9scyBpZiBtYXJrcyBzaG91bGQgYmUga2VwdCBhZnRlciBiZWluZyBzcGxpdCBieSBhIGhhcmQgYnJlYWsuXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICogQGV4YW1wbGUgZmFsc2VcbiAgICovXG4gIGtlZXBNYXJrczogYm9vbGVhbixcblxuICAvKipcbiAgICogSFRNTCBhdHRyaWJ1dGVzIHRvIGFkZCB0byB0aGUgaGFyZCBicmVhayBlbGVtZW50LlxuICAgKiBAZGVmYXVsdCB7fVxuICAgKiBAZXhhbXBsZSB7IGNsYXNzOiAnZm9vJyB9XG4gICAqL1xuICBIVE1MQXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgYW55Pixcbn1cblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIGhhcmRCcmVhazoge1xuICAgICAgLyoqXG4gICAgICAgKiBBZGQgYSBoYXJkIGJyZWFrXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuc2V0SGFyZEJyZWFrKClcbiAgICAgICAqL1xuICAgICAgc2V0SGFyZEJyZWFrOiAoKSA9PiBSZXR1cm5UeXBlLFxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFRoaXMgZXh0ZW5zaW9uIGFsbG93cyB5b3UgdG8gaW5zZXJ0IGhhcmQgYnJlYWtzLlxuICogQHNlZSBodHRwczovL3d3dy50aXB0YXAuZGV2L2FwaS9ub2Rlcy9oYXJkLWJyZWFrXG4gKi9cbmV4cG9ydCBjb25zdCBIYXJkQnJlYWsgPSBOb2RlLmNyZWF0ZTxIYXJkQnJlYWtPcHRpb25zPih7XG4gIG5hbWU6ICdoYXJkQnJlYWsnLFxuXG4gIGFkZE9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGtlZXBNYXJrczogdHJ1ZSxcbiAgICAgIEhUTUxBdHRyaWJ1dGVzOiB7fSxcbiAgICB9XG4gIH0sXG5cbiAgaW5saW5lOiB0cnVlLFxuXG4gIGdyb3VwOiAnaW5saW5lJyxcblxuICBzZWxlY3RhYmxlOiBmYWxzZSxcblxuICBsaW5lYnJlYWtSZXBsYWNlbWVudDogdHJ1ZSxcblxuICBwYXJzZUhUTUwoKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIHsgdGFnOiAnYnInIH0sXG4gICAgXVxuICB9LFxuXG4gIHJlbmRlckhUTUwoeyBIVE1MQXR0cmlidXRlcyB9KSB7XG4gICAgcmV0dXJuIFsnYnInLCBtZXJnZUF0dHJpYnV0ZXModGhpcy5vcHRpb25zLkhUTUxBdHRyaWJ1dGVzLCBIVE1MQXR0cmlidXRlcyldXG4gIH0sXG5cbiAgcmVuZGVyVGV4dCgpIHtcbiAgICByZXR1cm4gJ1xcbidcbiAgfSxcblxuICBhZGRDb21tYW5kcygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc2V0SGFyZEJyZWFrOiAoKSA9PiAoe1xuICAgICAgICBjb21tYW5kcyxcbiAgICAgICAgY2hhaW4sXG4gICAgICAgIHN0YXRlLFxuICAgICAgICBlZGl0b3IsXG4gICAgICB9KSA9PiB7XG4gICAgICAgIHJldHVybiBjb21tYW5kcy5maXJzdChbXG4gICAgICAgICAgKCkgPT4gY29tbWFuZHMuZXhpdENvZGUoKSxcbiAgICAgICAgICAoKSA9PiBjb21tYW5kcy5jb21tYW5kKCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgc2VsZWN0aW9uLCBzdG9yZWRNYXJrcyB9ID0gc3RhdGVcblxuICAgICAgICAgICAgaWYgKHNlbGVjdGlvbi4kZnJvbS5wYXJlbnQudHlwZS5zcGVjLmlzb2xhdGluZykge1xuICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgeyBrZWVwTWFya3MgfSA9IHRoaXMub3B0aW9uc1xuICAgICAgICAgICAgY29uc3QgeyBzcGxpdHRhYmxlTWFya3MgfSA9IGVkaXRvci5leHRlbnNpb25NYW5hZ2VyXG4gICAgICAgICAgICBjb25zdCBtYXJrcyA9IHN0b3JlZE1hcmtzXG4gICAgICAgICAgICAgIHx8IChzZWxlY3Rpb24uJHRvLnBhcmVudE9mZnNldCAmJiBzZWxlY3Rpb24uJGZyb20ubWFya3MoKSlcblxuICAgICAgICAgICAgcmV0dXJuIGNoYWluKClcbiAgICAgICAgICAgICAgLmluc2VydENvbnRlbnQoeyB0eXBlOiB0aGlzLm5hbWUgfSlcbiAgICAgICAgICAgICAgLmNvbW1hbmQoKHsgdHIsIGRpc3BhdGNoIH0pID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZGlzcGF0Y2ggJiYgbWFya3MgJiYga2VlcE1hcmtzKSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBmaWx0ZXJlZE1hcmtzID0gbWFya3NcbiAgICAgICAgICAgICAgICAgICAgLmZpbHRlcihtYXJrID0+IHNwbGl0dGFibGVNYXJrcy5pbmNsdWRlcyhtYXJrLnR5cGUubmFtZSkpXG5cbiAgICAgICAgICAgICAgICAgIHRyLmVuc3VyZU1hcmtzKGZpbHRlcmVkTWFya3MpXG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgLnJ1bigpXG4gICAgICAgICAgfSksXG4gICAgICAgIF0pXG4gICAgICB9LFxuICAgIH1cbiAgfSxcblxuICBhZGRLZXlib2FyZFNob3J0Y3V0cygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgJ01vZC1FbnRlcic6ICgpID0+IHRoaXMuZWRpdG9yLmNvbW1hbmRzLnNldEhhcmRCcmVhaygpLFxuICAgICAgJ1NoaWZ0LUVudGVyJzogKCkgPT4gdGhpcy5lZGl0b3IuY29tbWFuZHMuc2V0SGFyZEJyZWFrKCksXG4gICAgfVxuICB9LFxufSlcbiIsICIvKipcbkBsaWNlbnNlXG5Db3B5cmlnaHQgKGMpIDIwMjUgdHJhZGluZ19wZXRlclxuVGhpcyBwcm9ncmFtIGlzIGF2YWlsYWJsZSB1bmRlciBBcGFjaGUgTGljZW5zZSBWZXJzaW9uIDIuMFxuKi9cblxuaW1wb3J0IHsgTGl0RWxlbWVudCwgaHRtbCwgY3NzIH0gZnJvbSAnbGl0JztcbmltcG9ydCB7IEVkaXRvciB9IGZyb20gJ0B0aXB0YXAvY29yZSc7XG5pbXBvcnQgRG9jdW1lbnQgZnJvbSAnQHRpcHRhcC9leHRlbnNpb24tZG9jdW1lbnQnO1xuaW1wb3J0IFBhcmFncmFwaCBmcm9tICdAdGlwdGFwL2V4dGVuc2lvbi1wYXJhZ3JhcGgnO1xuaW1wb3J0IFRleHQgZnJvbSAnQHRpcHRhcC9leHRlbnNpb24tdGV4dCc7XG5pbXBvcnQgSGFyZEJyZWFrIGZyb20gJ0B0aXB0YXAvZXh0ZW5zaW9uLWhhcmQtYnJlYWsnO1xuXG5jbGFzcyBUcFJpY2hUZXh0Qm94IGV4dGVuZHMgTGl0RWxlbWVudCB7XG4gIHN0YXRpYyBnZXQgc3R5bGVzKCkge1xuICAgIHJldHVybiBbXG4gICAgICBjc3NgXG4gICAgICAgIDpob3N0IHtcbiAgICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICAgICAgYm9yZGVyOiAxcHggc29saWQgI2NjYztcbiAgICAgICAgICBtaW4taGVpZ2h0OiAxMDBweDtcbiAgICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgIH1cblxuICAgICAgICAjZWRpdG9yIHtcbiAgICAgICAgICBwYWRkaW5nOiA4cHg7XG4gICAgICAgICAgZmxleC1ncm93OiAxO1xuICAgICAgICB9XG5cbiAgICAgICAgLmN1c3RvbS1mbG9hdGluZy1tZW51IHtcbiAgICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgICAgIHBhZGRpbmc6IDRweDtcbiAgICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmO1xuICAgICAgICAgIGJvcmRlcjogMXB4IHNvbGlkICNjY2M7XG4gICAgICAgICAgYm9yZGVyLXJhZGl1czogNHB4O1xuICAgICAgICAgIGJveC1zaGFkb3c6IDAgMnB4IDRweCByZ2JhKDAsIDAsIDAsIDAuMSk7XG4gICAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgICAgIHRvcDogMDtcbiAgICAgICAgICBsZWZ0OiAwO1xuICAgICAgICAgIHotaW5kZXg6IDEwMDtcbiAgICAgICAgfVxuXG4gICAgICAgIC5jdXN0b20tZmxvYXRpbmctbWVudVtoaWRkZW5dIHtcbiAgICAgICAgICBkaXNwbGF5OiBub25lO1xuICAgICAgICB9XG4gICAgICBgXG4gICAgXTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5leHRlbnNpb25zID0gW107XG4gICAgdGhpcy5fc2xvdE9ic2VydmVyID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIodGhpcy5fcHJvY2Vzc1Nsb3RDaGFuZ2VzLmJpbmQodGhpcykpO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIHJldHVybiBodG1sYFxuICAgICAgPGRpdiBjbGFzcz1cImN1c3RvbS1mbG9hdGluZy1tZW51XCIgaGlkZGVuPlxuICAgICAgICA8c2xvdCBAc2xvdGNoYW5nZT0ke3RoaXMuX2hhbmRsZVNsb3RDaGFuZ2V9Pjwvc2xvdD5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBpZD1cImVkaXRvclwiPjwvZGl2PlxuICAgIGA7XG4gIH1cblxuICBzdGF0aWMgZ2V0IHByb3BlcnRpZXMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGVkaXRvcjogeyB0eXBlOiBPYmplY3QgfSxcbiAgICAgIGV4dGVuc2lvbnM6IHsgdHlwZTogQXJyYXkgfVxuICAgIH07XG4gIH1cblxuICBmaXJzdFVwZGF0ZWQoKSB7XG4gICAgLy8gR2V0IGluaXRpYWwgZXh0ZW5zaW9ucyBmcm9tIHNsb3RcbiAgICB0aGlzLl9wcm9jZXNzQ2hpbGRFeHRlbnNpb25zKCk7XG4gICAgXG4gICAgLy8gSW5pdGlhbGl6ZSB0aGUgZWRpdG9yIHdpdGggY29sbGVjdGVkIGV4dGVuc2lvbnNcbiAgICB0aGlzLl9pbml0RWRpdG9yKCk7XG5cbiAgICAvLyBPYnNlcnZlIGZ1dHVyZSBzbG90IGNoYW5nZXNcbiAgICB0aGlzLl9zbG90T2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLCB7IFxuICAgICAgY2hpbGRMaXN0OiB0cnVlLFxuICAgICAgc3VidHJlZTogZmFsc2UgXG4gICAgfSk7XG4gIH1cblxuICBfaW5pdEVkaXRvcigpIHtcbiAgICBpZiAodGhpcy5lZGl0b3IpIHtcbiAgICAgIHRoaXMuZWRpdG9yLmRlc3Ryb3koKTtcbiAgICB9XG5cbiAgICB0aGlzLmVkaXRvciA9IG5ldyBFZGl0b3Ioe1xuICAgICAgZWxlbWVudDogdGhpcy5zaGFkb3dSb290LnF1ZXJ5U2VsZWN0b3IoJyNlZGl0b3InKSxcbiAgICAgIGV4dGVuc2lvbnM6IHRoaXMuZXh0ZW5zaW9ucyxcbiAgICAgIGNvbnRlbnQ6ICc8cD5IZWxsbyBXb3JsZCE8L3A+JyxcbiAgICB9KTtcblxuICAgIC8vIE5vdGlmeSBjaGlsZCBleHRlbnNpb25zIHRoYXQgdGhlIGVkaXRvciBpcyByZWFkeVxuICAgIGNvbnN0IGNoaWxkcmVuID0gQXJyYXkuZnJvbSh0aGlzLmNoaWxkcmVuKTtcbiAgICBjaGlsZHJlbi5mb3JFYWNoKGNoaWxkID0+IHtcbiAgICAgIGlmIChjaGlsZC5fZWRpdG9yUmVhZHkgJiYgdHlwZW9mIGNoaWxkLl9lZGl0b3JSZWFkeSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBjaGlsZC5fZWRpdG9yUmVhZHkodGhpcy5lZGl0b3IpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGhpcy5lZGl0b3Iub24oJ3NlbGVjdGlvblVwZGF0ZScsIHRoaXMuX2hhbmRsZVNlbGVjdGlvblVwZGF0ZS5iaW5kKHRoaXMpKTtcbiAgICB0aGlzLmVkaXRvci5vbignYmx1cicsIHRoaXMuX2hhbmRsZVNlbGVjdGlvblVwZGF0ZS5iaW5kKHRoaXMpKTtcbiAgfVxuXG4gIF9oYW5kbGVTZWxlY3Rpb25VcGRhdGUoKSB7XG4gICAgY29uc3QgeyBlZGl0b3IgfSA9IHRoaXM7XG4gICAgY29uc3QgbWVudSA9IHRoaXMuc2hhZG93Um9vdC5xdWVyeVNlbGVjdG9yKCcuY3VzdG9tLWZsb2F0aW5nLW1lbnUnKTtcblxuICAgIGlmICghZWRpdG9yIHx8ICFtZW51KSB7XG4gICAgICBjb25zb2xlLmxvZygnRWRpdG9yIG9yIG1lbnUgZWxlbWVudCBub3QgZm91bmQuJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgeyBlbXB0eSwgZnJvbSwgdG8gfSA9IGVkaXRvci5zdGF0ZS5zZWxlY3Rpb247XG5cbiAgICBpZiAoZW1wdHkgfHwgZnJvbSA9PT0gdG8pIHtcbiAgICAgIG1lbnUuaGlkZGVuID0gdHJ1ZTtcbiAgICAgIGNvbnNvbGUubG9nKCdTZWxlY3Rpb24gaXMgZW1wdHkgb3IgYSBjYXJldC4gSGlkaW5nIG1lbnUuJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbWVudS5oaWRkZW4gPSBmYWxzZTtcbiAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgdGhpcy5fcG9zaXRpb25NZW51KG1lbnUsIGVkaXRvcik7XG4gICAgICBjb25zb2xlLmxvZygnVGV4dCBzZWxlY3RlZC4gU2hvd2luZyBtZW51LicpO1xuICAgIH0pO1xuICB9XG5cbiAgX3Bvc2l0aW9uTWVudShtZW51RWxlbWVudCwgZWRpdG9ySW5zdGFuY2UpIHtcbiAgICBjb25zdCB7IHZpZXcgfSA9IGVkaXRvckluc3RhbmNlO1xuICAgIGNvbnN0IHsgc2VsZWN0aW9uIH0gPSBlZGl0b3JJbnN0YW5jZS5zdGF0ZTtcbiAgICBjb25zdCB7IGZyb20sIHRvIH0gPSBzZWxlY3Rpb247XG5cbiAgICAvLyBHZXQgdGhlIGNvb3JkaW5hdGVzIG9mIHRoZSBzZWxlY3Rpb25cbiAgICBjb25zdCBzdGFydCA9IHZpZXcuY29vcmRzQXRQb3MoZnJvbSk7XG4gICAgY29uc3QgZW5kID0gdmlldy5jb29yZHNBdFBvcyh0byk7XG5cbiAgICAvLyBDYWxjdWxhdGUgdGhlIGNlbnRlciBvZiB0aGUgc2VsZWN0aW9uXG4gICAgbGV0IGxlZnQgPSAoc3RhcnQubGVmdCArIGVuZC5sZWZ0KSAvIDI7XG4gICAgY29uc29sZS5sb2coJ01lbnUgb2Zmc2V0SGVpZ2h0OicsIG1lbnVFbGVtZW50Lm9mZnNldEhlaWdodCk7XG4gICAgbGV0IHRvcCA9IHN0YXJ0LnRvcCAtIG1lbnVFbGVtZW50Lm9mZnNldEhlaWdodCAtIDEwOyAvLyAxMHB4IGFib3ZlIHNlbGVjdGlvblxuXG4gICAgLy8gSWYgdGhlIGNhbGN1bGF0ZWQgdG9wIGlzIG5lZ2F0aXZlLCBwb3NpdGlvbiB0aGUgbWVudSBiZWxvdyB0aGUgc2VsZWN0aW9uXG4gICAgaWYgKHRvcCA8IDApIHtcbiAgICAgIHRvcCA9IGVuZC5ib3R0b20gKyAxMDsgLy8gMTBweCBiZWxvdyBzZWxlY3Rpb25cbiAgICB9XG5cbiAgICAvLyBBZGp1c3QgbGVmdCBwb3NpdGlvbiBpZiBpdCBnb2VzIG91dCBvZiB2aWV3cG9ydCBvbiB0aGUgcmlnaHRcbiAgICBjb25zdCB2aWV3cG9ydFdpZHRoID0gd2luZG93LmlubmVyV2lkdGg7XG4gICAgY29uc3QgbWVudVdpZHRoID0gbWVudUVsZW1lbnQub2Zmc2V0V2lkdGg7XG4gICAgaWYgKGxlZnQgKyBtZW51V2lkdGggPiB2aWV3cG9ydFdpZHRoKSB7XG4gICAgICBsZWZ0ID0gdmlld3BvcnRXaWR0aCAtIG1lbnVXaWR0aCAtIDEwOyAvLyAxMHB4IHBhZGRpbmcgZnJvbSByaWdodCBlZGdlXG4gICAgfVxuXG4gICAgLy8gRW5zdXJlIGxlZnQgaXMgbm90IG5lZ2F0aXZlXG4gICAgaWYgKGxlZnQgPCAwKSB7XG4gICAgICBsZWZ0ID0gMTA7IC8vIDEwcHggcGFkZGluZyBmcm9tIGxlZnQgZWRnZVxuICAgIH1cblxuICAgIC8vIFBvc2l0aW9uIHRoZSBtZW51XG4gICAgbWVudUVsZW1lbnQuc3R5bGUubGVmdCA9IGAke2xlZnR9cHhgO1xuICAgIG1lbnVFbGVtZW50LnN0eWxlLnRvcCA9IGAke3RvcH1weGA7XG4gICAgY29uc29sZS5sb2coYE1lbnUgcG9zaXRpb25lZCBhdDogbGVmdD0ke2xlZnR9cHgsIHRvcD0ke3RvcH1weGApO1xuICB9XG5cbiAgX2hhbmRsZVNsb3RDaGFuZ2UoZSkge1xuICAgIHRoaXMuX3Byb2Nlc3NDaGlsZEV4dGVuc2lvbnMoKTtcbiAgfVxuXG4gIF9wcm9jZXNzU2xvdENoYW5nZXMobXV0YXRpb25zKSB7XG4gICAgbGV0IG5lZWRzVXBkYXRlID0gZmFsc2U7XG4gICAgXG4gICAgbXV0YXRpb25zLmZvckVhY2gobXV0YXRpb24gPT4ge1xuICAgICAgaWYgKG11dGF0aW9uLnR5cGUgPT09ICdjaGlsZExpc3QnKSB7XG4gICAgICAgIG5lZWRzVXBkYXRlID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBcbiAgICBpZiAobmVlZHNVcGRhdGUpIHtcbiAgICAgIHRoaXMuX3Byb2Nlc3NDaGlsZEV4dGVuc2lvbnMoKTtcbiAgICB9XG4gIH1cblxuICBfcHJvY2Vzc0NoaWxkRXh0ZW5zaW9ucygpIHtcbiAgICB0aGlzLmV4dGVuc2lvbnMgPSBbXG4gICAgICBEb2N1bWVudCxcbiAgICAgIFBhcmFncmFwaCxcbiAgICAgIFRleHQsXG4gICAgICBIYXJkQnJlYWtcbiAgICBdO1xuICAgIFxuICAgIC8vIEdldCBhbGwgZXh0ZW5zaW9uIGNvbXBvbmVudHNcbiAgICBjb25zdCBjaGlsZHJlbiA9IEFycmF5LmZyb20odGhpcy5jaGlsZHJlbik7XG4gICAgXG4gICAgY2hpbGRyZW4uZm9yRWFjaChjaGlsZCA9PiB7XG4gICAgICAvLyBJZiB0aGUgY2hpbGQgaGFzIGEgZ2V0RXh0ZW5zaW9uIG1ldGhvZCwgaXQncyBhbiBleHRlbnNpb24gY29tcG9uZW50XG4gICAgICBpZiAoY2hpbGQuZ2V0RXh0ZW5zaW9uICYmIHR5cGVvZiBjaGlsZC5nZXRFeHRlbnNpb24gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgY29uc3QgZXh0ZW5zaW9uID0gY2hpbGQuZ2V0RXh0ZW5zaW9uKCk7XG4gICAgICAgIGlmIChleHRlbnNpb24pIHtcbiAgICAgICAgICB0aGlzLmV4dGVuc2lvbnMucHVzaChleHRlbnNpb24pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gICAgXG4gICAgLy8gUmUtaW5pdGlhbGl6ZSB0aGUgZWRpdG9yIHdpdGggbmV3IGV4dGVuc2lvbnMgaWYgaXQgYWxyZWFkeSBleGlzdHNcbiAgICBpZiAodGhpcy5lZGl0b3IpIHtcbiAgICAgIHRoaXMuX2luaXRFZGl0b3IoKTtcbiAgICB9XG4gIH1cblxuICBkaXNjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICBzdXBlci5kaXNjb25uZWN0ZWRDYWxsYmFjaygpO1xuICAgIGlmICh0aGlzLl9zbG90T2JzZXJ2ZXIpIHtcbiAgICAgIHRoaXMuX3Nsb3RPYnNlcnZlci5kaXNjb25uZWN0KCk7XG4gICAgfVxuICAgIGlmICh0aGlzLmVkaXRvcikge1xuICAgICAgdGhpcy5lZGl0b3IuZGVzdHJveSgpO1xuICAgIH1cbiAgfVxufVxuXG53aW5kb3cuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCd0cC1yaWNoLXRleHQtYm94JywgVHBSaWNoVGV4dEJveCk7XG4iLCAiaW1wb3J0IHsgTGl0RWxlbWVudCwgaHRtbCwgY3NzIH0gZnJvbSAnbGl0JztcblxuZXhwb3J0IGNsYXNzIFRwUnRiQmFzZUV4dGVuc2lvbiBleHRlbmRzIExpdEVsZW1lbnQge1xuICBzdGF0aWMgZ2V0IHN0eWxlcygpIHtcbiAgICByZXR1cm4gY3NzYFxuICAgICAgOmhvc3Qge1xuICAgICAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gICAgICB9XG4gICAgICBcbiAgICAgIGJ1dHRvbiB7XG4gICAgICAgIG1hcmdpbjogMCAycHg7XG4gICAgICAgIHBhZGRpbmc6IDRweCA4cHg7XG4gICAgICAgIGJhY2tncm91bmQ6IG5vbmU7XG4gICAgICAgIGJvcmRlcjogMXB4IHNvbGlkICNjY2M7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDNweDtcbiAgICAgICAgY3Vyc29yOiBwb2ludGVyO1xuICAgICAgfVxuICAgICAgXG4gICAgICBidXR0b246aG92ZXIge1xuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjZjBmMGYwO1xuICAgICAgfVxuICAgICAgXG4gICAgICBidXR0b24uYWN0aXZlIHtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogI2UwZTBlMDtcbiAgICAgIH1cbiAgICBgO1xuICB9XG5cbiAgc3RhdGljIGdldCBwcm9wZXJ0aWVzKCkge1xuICAgIHJldHVybiB7XG4gICAgICBsYWJlbDogeyB0eXBlOiBTdHJpbmcgfSxcbiAgICAgIGFjdGl2ZTogeyB0eXBlOiBCb29sZWFuLCByZWZsZWN0OiB0cnVlIH1cbiAgICB9O1xuICB9XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLmxhYmVsID0gJyc7XG4gICAgdGhpcy5hY3RpdmUgPSBmYWxzZTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICByZXR1cm4gaHRtbGBcbiAgICAgIDxidXR0b24gY2xhc3M9XCIke3RoaXMuYWN0aXZlID8gJ2FjdGl2ZScgOiAnJ31cIiBAY2xpY2s9JHt0aGlzLl9oYW5kbGVDbGlja30+XG4gICAgICAgICR7dGhpcy5sYWJlbH1cbiAgICAgIDwvYnV0dG9uPlxuICAgIGA7XG4gIH1cblxuICBjb25uZWN0ZWRDYWxsYmFjaygpIHtcbiAgICBzdXBlci5jb25uZWN0ZWRDYWxsYmFjaygpO1xuICAgIHRoaXMuX2ZpbmRQYXJlbnRFZGl0b3IoKTtcbiAgfVxuXG4gIF9maW5kUGFyZW50RWRpdG9yKCkge1xuICAgIHRoaXMucGFyZW50RWRpdG9yID0gdGhpcy5jbG9zZXN0KCd0cC1yaWNoLXRleHQtYm94Jyk7XG4gIH1cblxuICBfZWRpdG9yUmVhZHkoZWRpdG9ySW5zdGFuY2UpIHtcbiAgICB0aGlzLnBhcmVudEVkaXRvci5lZGl0b3IgPSBlZGl0b3JJbnN0YW5jZTtcbiAgICB0aGlzLl9zZXR1cEVkaXRvckxpc3RlbmVycygpO1xuICB9XG5cbiAgX3NldHVwRWRpdG9yTGlzdGVuZXJzKCkge1xuICAgIC8vIFRvIGJlIGltcGxlbWVudGVkIGJ5IGNoaWxkIGNsYXNzZXNcbiAgfVxuXG4gIF9oYW5kbGVDbGljaygpIHtcbiAgICAvLyBUbyBiZSBpbXBsZW1lbnRlZCBieSBjaGlsZCBjbGFzc2VzXG4gIH1cblxuICBnZXRFeHRlbnNpb24oKSB7XG4gICAgLy8gVG8gYmUgaW1wbGVtZW50ZWQgYnkgY2hpbGQgY2xhc3Nlc1xuICAgIHJldHVybiBudWxsO1xuICB9XG59IiwgImltcG9ydCB7XG4gIE1hcmssXG4gIG1hcmtJbnB1dFJ1bGUsXG4gIG1hcmtQYXN0ZVJ1bGUsXG4gIG1lcmdlQXR0cmlidXRlcyxcbn0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuXG5leHBvcnQgaW50ZXJmYWNlIEJvbGRPcHRpb25zIHtcbiAgLyoqXG4gICAqIEhUTUwgYXR0cmlidXRlcyB0byBhZGQgdG8gdGhlIGJvbGQgZWxlbWVudC5cbiAgICogQGRlZmF1bHQge31cbiAgICogQGV4YW1wbGUgeyBjbGFzczogJ2ZvbycgfVxuICAgKi9cbiAgSFRNTEF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIGFueT4sXG59XG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBib2xkOiB7XG4gICAgICAvKipcbiAgICAgICAqIFNldCBhIGJvbGQgbWFya1xuICAgICAgICovXG4gICAgICBzZXRCb2xkOiAoKSA9PiBSZXR1cm5UeXBlLFxuICAgICAgLyoqXG4gICAgICAgKiBUb2dnbGUgYSBib2xkIG1hcmtcbiAgICAgICAqL1xuICAgICAgdG9nZ2xlQm9sZDogKCkgPT4gUmV0dXJuVHlwZSxcbiAgICAgIC8qKlxuICAgICAgICogVW5zZXQgYSBib2xkIG1hcmtcbiAgICAgICAqL1xuICAgICAgdW5zZXRCb2xkOiAoKSA9PiBSZXR1cm5UeXBlLFxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIE1hdGNoZXMgYm9sZCB0ZXh0IHZpYSBgKipgIGFzIGlucHV0LlxuICovXG5leHBvcnQgY29uc3Qgc3RhcklucHV0UmVnZXggPSAvKD86XnxcXHMpKFxcKlxcKig/IVxccytcXCpcXCopKCg/OlteKl0rKSlcXCpcXCooPyFcXHMrXFwqXFwqKSkkL1xuXG4vKipcbiAqIE1hdGNoZXMgYm9sZCB0ZXh0IHZpYSBgKipgIHdoaWxlIHBhc3RpbmcuXG4gKi9cbmV4cG9ydCBjb25zdCBzdGFyUGFzdGVSZWdleCA9IC8oPzpefFxccykoXFwqXFwqKD8hXFxzK1xcKlxcKikoKD86W14qXSspKVxcKlxcKig/IVxccytcXCpcXCopKS9nXG5cbi8qKlxuICogTWF0Y2hlcyBib2xkIHRleHQgdmlhIGBfX2AgYXMgaW5wdXQuXG4gKi9cbmV4cG9ydCBjb25zdCB1bmRlcnNjb3JlSW5wdXRSZWdleCA9IC8oPzpefFxccykoX18oPyFcXHMrX18pKCg/OlteX10rKSlfXyg/IVxccytfXykpJC9cblxuLyoqXG4gKiBNYXRjaGVzIGJvbGQgdGV4dCB2aWEgYF9fYCB3aGlsZSBwYXN0aW5nLlxuICovXG5leHBvcnQgY29uc3QgdW5kZXJzY29yZVBhc3RlUmVnZXggPSAvKD86XnxcXHMpKF9fKD8hXFxzK19fKSgoPzpbXl9dKykpX18oPyFcXHMrX18pKS9nXG5cbi8qKlxuICogVGhpcyBleHRlbnNpb24gYWxsb3dzIHlvdSB0byBtYXJrIHRleHQgYXMgYm9sZC5cbiAqIEBzZWUgaHR0cHM6Ly90aXB0YXAuZGV2L2FwaS9tYXJrcy9ib2xkXG4gKi9cbmV4cG9ydCBjb25zdCBCb2xkID0gTWFyay5jcmVhdGU8Qm9sZE9wdGlvbnM+KHtcbiAgbmFtZTogJ2JvbGQnLFxuXG4gIGFkZE9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIEhUTUxBdHRyaWJ1dGVzOiB7fSxcbiAgICB9XG4gIH0sXG5cbiAgcGFyc2VIVE1MKCkge1xuICAgIHJldHVybiBbXG4gICAgICB7XG4gICAgICAgIHRhZzogJ3N0cm9uZycsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB0YWc6ICdiJyxcbiAgICAgICAgZ2V0QXR0cnM6IG5vZGUgPT4gKG5vZGUgYXMgSFRNTEVsZW1lbnQpLnN0eWxlLmZvbnRXZWlnaHQgIT09ICdub3JtYWwnICYmIG51bGwsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBzdHlsZTogJ2ZvbnQtd2VpZ2h0PTQwMCcsXG4gICAgICAgIGNsZWFyTWFyazogbWFyayA9PiBtYXJrLnR5cGUubmFtZSA9PT0gdGhpcy5uYW1lLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgc3R5bGU6ICdmb250LXdlaWdodCcsXG4gICAgICAgIGdldEF0dHJzOiB2YWx1ZSA9PiAvXihib2xkKGVyKT98WzUtOV1cXGR7Mix9KSQvLnRlc3QodmFsdWUgYXMgc3RyaW5nKSAmJiBudWxsLFxuICAgICAgfSxcbiAgICBdXG4gIH0sXG5cbiAgcmVuZGVySFRNTCh7IEhUTUxBdHRyaWJ1dGVzIH0pIHtcbiAgICByZXR1cm4gWydzdHJvbmcnLCBtZXJnZUF0dHJpYnV0ZXModGhpcy5vcHRpb25zLkhUTUxBdHRyaWJ1dGVzLCBIVE1MQXR0cmlidXRlcyksIDBdXG4gIH0sXG5cbiAgYWRkQ29tbWFuZHMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNldEJvbGQ6ICgpID0+ICh7IGNvbW1hbmRzIH0pID0+IHtcbiAgICAgICAgcmV0dXJuIGNvbW1hbmRzLnNldE1hcmsodGhpcy5uYW1lKVxuICAgICAgfSxcbiAgICAgIHRvZ2dsZUJvbGQ6ICgpID0+ICh7IGNvbW1hbmRzIH0pID0+IHtcbiAgICAgICAgcmV0dXJuIGNvbW1hbmRzLnRvZ2dsZU1hcmsodGhpcy5uYW1lKVxuICAgICAgfSxcbiAgICAgIHVuc2V0Qm9sZDogKCkgPT4gKHsgY29tbWFuZHMgfSkgPT4ge1xuICAgICAgICByZXR1cm4gY29tbWFuZHMudW5zZXRNYXJrKHRoaXMubmFtZSlcbiAgICAgIH0sXG4gICAgfVxuICB9LFxuXG4gIGFkZEtleWJvYXJkU2hvcnRjdXRzKCkge1xuICAgIHJldHVybiB7XG4gICAgICAnTW9kLWInOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy50b2dnbGVCb2xkKCksXG4gICAgICAnTW9kLUInOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy50b2dnbGVCb2xkKCksXG4gICAgfVxuICB9LFxuXG4gIGFkZElucHV0UnVsZXMoKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIG1hcmtJbnB1dFJ1bGUoe1xuICAgICAgICBmaW5kOiBzdGFySW5wdXRSZWdleCxcbiAgICAgICAgdHlwZTogdGhpcy50eXBlLFxuICAgICAgfSksXG4gICAgICBtYXJrSW5wdXRSdWxlKHtcbiAgICAgICAgZmluZDogdW5kZXJzY29yZUlucHV0UmVnZXgsXG4gICAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICAgIH0pLFxuICAgIF1cbiAgfSxcblxuICBhZGRQYXN0ZVJ1bGVzKCkge1xuICAgIHJldHVybiBbXG4gICAgICBtYXJrUGFzdGVSdWxlKHtcbiAgICAgICAgZmluZDogc3RhclBhc3RlUmVnZXgsXG4gICAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICAgIH0pLFxuICAgICAgbWFya1Bhc3RlUnVsZSh7XG4gICAgICAgIGZpbmQ6IHVuZGVyc2NvcmVQYXN0ZVJlZ2V4LFxuICAgICAgICB0eXBlOiB0aGlzLnR5cGUsXG4gICAgICB9KSxcbiAgICBdXG4gIH0sXG59KVxuIiwgImltcG9ydCB7IFRwUnRiQmFzZUV4dGVuc2lvbiB9IGZyb20gJy4vdHAtcnRiLWJhc2UtZXh0ZW5zaW9uLmpzJztcbmltcG9ydCBCb2xkIGZyb20gJ0B0aXB0YXAvZXh0ZW5zaW9uLWJvbGQnO1xuXG5jbGFzcyBUcFJ0YkJvbGQgZXh0ZW5kcyBUcFJ0YkJhc2VFeHRlbnNpb24ge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMubGFiZWwgPSAnQm9sZCc7XG4gIH1cblxuICBnZXRFeHRlbnNpb24oKSB7XG4gICAgcmV0dXJuIEJvbGQ7XG4gIH1cblxuICBfaGFuZGxlQ2xpY2soKSB7XG4gICAgaWYgKHRoaXMucGFyZW50RWRpdG9yICYmIHRoaXMucGFyZW50RWRpdG9yLmVkaXRvcikge1xuICAgICAgdGhpcy5wYXJlbnRFZGl0b3IuZWRpdG9yLmNoYWluKCkuZm9jdXMoKS50b2dnbGVCb2xkKCkucnVuKCk7XG4gICAgfVxuICB9XG5cbiAgX3NldHVwRWRpdG9yTGlzdGVuZXJzKCkge1xuICAgIGNvbnN0IHsgZWRpdG9yIH0gPSB0aGlzLnBhcmVudEVkaXRvcjtcbiAgICBcbiAgICAvLyBVcGRhdGUgYnV0dG9uIHN0YXRlIHdoZW4gc2VsZWN0aW9uIGNoYW5nZXNcbiAgICBlZGl0b3Iub24oJ3NlbGVjdGlvblVwZGF0ZScsICgpID0+IHtcbiAgICAgIHRoaXMuYWN0aXZlID0gZWRpdG9yLmlzQWN0aXZlKCdib2xkJyk7XG4gICAgfSk7XG4gICAgXG4gICAgZWRpdG9yLm9uKCdmb2N1cycsICgpID0+IHtcbiAgICAgIHRoaXMuYWN0aXZlID0gZWRpdG9yLmlzQWN0aXZlKCdib2xkJyk7XG4gICAgfSk7XG4gIH1cbn1cblxuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCd0cC1ydGItYm9sZCcsIFRwUnRiQm9sZCk7IiwgImltcG9ydCB7XG4gIE1hcmssXG4gIG1hcmtJbnB1dFJ1bGUsXG4gIG1hcmtQYXN0ZVJ1bGUsXG4gIG1lcmdlQXR0cmlidXRlcyxcbn0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuXG5leHBvcnQgaW50ZXJmYWNlIEl0YWxpY09wdGlvbnMge1xuICAvKipcbiAgICogSFRNTCBhdHRyaWJ1dGVzIHRvIGFkZCB0byB0aGUgaXRhbGljIGVsZW1lbnQuXG4gICAqIEBkZWZhdWx0IHt9XG4gICAqIEBleGFtcGxlIHsgY2xhc3M6ICdmb28nIH1cbiAgKi9cbiAgSFRNTEF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIGFueT4sXG59XG5cbmRlY2xhcmUgbW9kdWxlICdAdGlwdGFwL2NvcmUnIHtcbiAgaW50ZXJmYWNlIENvbW1hbmRzPFJldHVyblR5cGU+IHtcbiAgICBpdGFsaWM6IHtcbiAgICAgIC8qKlxuICAgICAgICogU2V0IGFuIGl0YWxpYyBtYXJrXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMuc2V0SXRhbGljKClcbiAgICAgICAqL1xuICAgICAgc2V0SXRhbGljOiAoKSA9PiBSZXR1cm5UeXBlLFxuICAgICAgLyoqXG4gICAgICAgKiBUb2dnbGUgYW4gaXRhbGljIG1hcmtcbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy50b2dnbGVJdGFsaWMoKVxuICAgICAgICovXG4gICAgICB0b2dnbGVJdGFsaWM6ICgpID0+IFJldHVyblR5cGUsXG4gICAgICAvKipcbiAgICAgICAqIFVuc2V0IGFuIGl0YWxpYyBtYXJrXG4gICAgICAgKiBAZXhhbXBsZSBlZGl0b3IuY29tbWFuZHMudW5zZXRJdGFsaWMoKVxuICAgICAgICovXG4gICAgICB1bnNldEl0YWxpYzogKCkgPT4gUmV0dXJuVHlwZSxcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBNYXRjaGVzIGFuIGl0YWxpYyB0byBhICppdGFsaWMqIG9uIGlucHV0LlxuICovXG5leHBvcnQgY29uc3Qgc3RhcklucHV0UmVnZXggPSAvKD86XnxcXHMpKFxcKig/IVxccytcXCopKCg/OlteKl0rKSlcXCooPyFcXHMrXFwqKSkkL1xuXG4vKipcbiAqIE1hdGNoZXMgYW4gaXRhbGljIHRvIGEgKml0YWxpYyogb24gcGFzdGUuXG4gKi9cbmV4cG9ydCBjb25zdCBzdGFyUGFzdGVSZWdleCA9IC8oPzpefFxccykoXFwqKD8hXFxzK1xcKikoKD86W14qXSspKVxcKig/IVxccytcXCopKS9nXG5cbi8qKlxuICogTWF0Y2hlcyBhbiBpdGFsaWMgdG8gYSBfaXRhbGljXyBvbiBpbnB1dC5cbiAqL1xuZXhwb3J0IGNvbnN0IHVuZGVyc2NvcmVJbnB1dFJlZ2V4ID0gLyg/Ol58XFxzKShfKD8hXFxzK18pKCg/OlteX10rKSlfKD8hXFxzK18pKSQvXG5cbi8qKlxuICogTWF0Y2hlcyBhbiBpdGFsaWMgdG8gYSBfaXRhbGljXyBvbiBwYXN0ZS5cbiAqL1xuZXhwb3J0IGNvbnN0IHVuZGVyc2NvcmVQYXN0ZVJlZ2V4ID0gLyg/Ol58XFxzKShfKD8hXFxzK18pKCg/OlteX10rKSlfKD8hXFxzK18pKS9nXG5cbi8qKlxuICogVGhpcyBleHRlbnNpb24gYWxsb3dzIHlvdSB0byBjcmVhdGUgaXRhbGljIHRleHQuXG4gKiBAc2VlIGh0dHBzOi8vd3d3LnRpcHRhcC5kZXYvYXBpL21hcmtzL2l0YWxpY1xuICovXG5leHBvcnQgY29uc3QgSXRhbGljID0gTWFyay5jcmVhdGU8SXRhbGljT3B0aW9ucz4oe1xuICBuYW1lOiAnaXRhbGljJyxcblxuICBhZGRPcHRpb25zKCkge1xuICAgIHJldHVybiB7XG4gICAgICBIVE1MQXR0cmlidXRlczoge30sXG4gICAgfVxuICB9LFxuXG4gIHBhcnNlSFRNTCgpIHtcbiAgICByZXR1cm4gW1xuICAgICAge1xuICAgICAgICB0YWc6ICdlbScsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB0YWc6ICdpJyxcbiAgICAgICAgZ2V0QXR0cnM6IG5vZGUgPT4gKG5vZGUgYXMgSFRNTEVsZW1lbnQpLnN0eWxlLmZvbnRTdHlsZSAhPT0gJ25vcm1hbCcgJiYgbnVsbCxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIHN0eWxlOiAnZm9udC1zdHlsZT1ub3JtYWwnLFxuICAgICAgICBjbGVhck1hcms6IG1hcmsgPT4gbWFyay50eXBlLm5hbWUgPT09IHRoaXMubmFtZSxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIHN0eWxlOiAnZm9udC1zdHlsZT1pdGFsaWMnLFxuICAgICAgfSxcbiAgICBdXG4gIH0sXG5cbiAgcmVuZGVySFRNTCh7IEhUTUxBdHRyaWJ1dGVzIH0pIHtcbiAgICByZXR1cm4gWydlbScsIG1lcmdlQXR0cmlidXRlcyh0aGlzLm9wdGlvbnMuSFRNTEF0dHJpYnV0ZXMsIEhUTUxBdHRyaWJ1dGVzKSwgMF1cbiAgfSxcblxuICBhZGRDb21tYW5kcygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc2V0SXRhbGljOiAoKSA9PiAoeyBjb21tYW5kcyB9KSA9PiB7XG4gICAgICAgIHJldHVybiBjb21tYW5kcy5zZXRNYXJrKHRoaXMubmFtZSlcbiAgICAgIH0sXG4gICAgICB0b2dnbGVJdGFsaWM6ICgpID0+ICh7IGNvbW1hbmRzIH0pID0+IHtcbiAgICAgICAgcmV0dXJuIGNvbW1hbmRzLnRvZ2dsZU1hcmsodGhpcy5uYW1lKVxuICAgICAgfSxcbiAgICAgIHVuc2V0SXRhbGljOiAoKSA9PiAoeyBjb21tYW5kcyB9KSA9PiB7XG4gICAgICAgIHJldHVybiBjb21tYW5kcy51bnNldE1hcmsodGhpcy5uYW1lKVxuICAgICAgfSxcbiAgICB9XG4gIH0sXG5cbiAgYWRkS2V5Ym9hcmRTaG9ydGN1dHMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICdNb2QtaSc6ICgpID0+IHRoaXMuZWRpdG9yLmNvbW1hbmRzLnRvZ2dsZUl0YWxpYygpLFxuICAgICAgJ01vZC1JJzogKCkgPT4gdGhpcy5lZGl0b3IuY29tbWFuZHMudG9nZ2xlSXRhbGljKCksXG4gICAgfVxuICB9LFxuXG4gIGFkZElucHV0UnVsZXMoKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIG1hcmtJbnB1dFJ1bGUoe1xuICAgICAgICBmaW5kOiBzdGFySW5wdXRSZWdleCxcbiAgICAgICAgdHlwZTogdGhpcy50eXBlLFxuICAgICAgfSksXG4gICAgICBtYXJrSW5wdXRSdWxlKHtcbiAgICAgICAgZmluZDogdW5kZXJzY29yZUlucHV0UmVnZXgsXG4gICAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICAgIH0pLFxuICAgIF1cbiAgfSxcblxuICBhZGRQYXN0ZVJ1bGVzKCkge1xuICAgIHJldHVybiBbXG4gICAgICBtYXJrUGFzdGVSdWxlKHtcbiAgICAgICAgZmluZDogc3RhclBhc3RlUmVnZXgsXG4gICAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICAgIH0pLFxuICAgICAgbWFya1Bhc3RlUnVsZSh7XG4gICAgICAgIGZpbmQ6IHVuZGVyc2NvcmVQYXN0ZVJlZ2V4LFxuICAgICAgICB0eXBlOiB0aGlzLnR5cGUsXG4gICAgICB9KSxcbiAgICBdXG4gIH0sXG59KVxuIiwgImltcG9ydCB7IFRwUnRiQmFzZUV4dGVuc2lvbiB9IGZyb20gJy4vdHAtcnRiLWJhc2UtZXh0ZW5zaW9uLmpzJztcbmltcG9ydCBJdGFsaWMgZnJvbSAnQHRpcHRhcC9leHRlbnNpb24taXRhbGljJztcblxuY2xhc3MgVHBSdGJJdGFsaWMgZXh0ZW5kcyBUcFJ0YkJhc2VFeHRlbnNpb24ge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMubGFiZWwgPSAnSXRhbGljJztcbiAgfVxuXG4gIGdldEV4dGVuc2lvbigpIHtcbiAgICByZXR1cm4gSXRhbGljO1xuICB9XG5cbiAgX2hhbmRsZUNsaWNrKCkge1xuICAgIGlmICh0aGlzLnBhcmVudEVkaXRvciAmJiB0aGlzLnBhcmVudEVkaXRvci5lZGl0b3IpIHtcbiAgICAgIHRoaXMucGFyZW50RWRpdG9yLmVkaXRvci5jaGFpbigpLmZvY3VzKCkudG9nZ2xlSXRhbGljKCkucnVuKCk7XG4gICAgfVxuICB9XG5cbiAgX3NldHVwRWRpdG9yTGlzdGVuZXJzKCkge1xuICAgIGNvbnN0IHsgZWRpdG9yIH0gPSB0aGlzLnBhcmVudEVkaXRvcjtcbiAgICBcbiAgICAvLyBVcGRhdGUgYnV0dG9uIHN0YXRlIHdoZW4gc2VsZWN0aW9uIGNoYW5nZXNcbiAgICBlZGl0b3Iub24oJ3NlbGVjdGlvblVwZGF0ZScsICgpID0+IHtcbiAgICAgIHRoaXMuYWN0aXZlID0gZWRpdG9yLmlzQWN0aXZlKCdpdGFsaWMnKTtcbiAgICB9KTtcbiAgICBcbiAgICBlZGl0b3Iub24oJ2ZvY3VzJywgKCkgPT4ge1xuICAgICAgdGhpcy5hY3RpdmUgPSBlZGl0b3IuaXNBY3RpdmUoJ2l0YWxpYycpO1xuICAgIH0pO1xuICB9XG59XG5cbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgndHAtcnRiLWl0YWxpYycsIFRwUnRiSXRhbGljKTtcbiIsICJpbXBvcnQge1xuICBNYXJrLFxuICBtYXJrSW5wdXRSdWxlLFxuICBtYXJrUGFzdGVSdWxlLFxuICBtZXJnZUF0dHJpYnV0ZXMsXG59IGZyb20gJ0B0aXB0YXAvY29yZSdcblxuZXhwb3J0IGludGVyZmFjZSBTdHJpa2VPcHRpb25zIHtcbiAgLyoqXG4gICAqIEhUTUwgYXR0cmlidXRlcyB0byBhZGQgdG8gdGhlIHN0cmlrZSBlbGVtZW50LlxuICAgKiBAZGVmYXVsdCB7fVxuICAgKiBAZXhhbXBsZSB7IGNsYXNzOiAnZm9vJyB9XG4gICAqL1xuICBIVE1MQXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgYW55Pixcbn1cblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIHN0cmlrZToge1xuICAgICAgLyoqXG4gICAgICAgKiBTZXQgYSBzdHJpa2UgbWFya1xuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnNldFN0cmlrZSgpXG4gICAgICAgKi9cbiAgICAgIHNldFN0cmlrZTogKCkgPT4gUmV0dXJuVHlwZSxcbiAgICAgIC8qKlxuICAgICAgICogVG9nZ2xlIGEgc3RyaWtlIG1hcmtcbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy50b2dnbGVTdHJpa2UoKVxuICAgICAgICovXG4gICAgICB0b2dnbGVTdHJpa2U6ICgpID0+IFJldHVyblR5cGUsXG4gICAgICAvKipcbiAgICAgICAqIFVuc2V0IGEgc3RyaWtlIG1hcmtcbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy51bnNldFN0cmlrZSgpXG4gICAgICAgKi9cbiAgICAgIHVuc2V0U3RyaWtlOiAoKSA9PiBSZXR1cm5UeXBlLFxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIE1hdGNoZXMgYSBzdHJpa2UgdG8gYSB+fnN0cmlrZX5+IG9uIGlucHV0LlxuICovXG5leHBvcnQgY29uc3QgaW5wdXRSZWdleCA9IC8oPzpefFxccykofn4oPyFcXHMrfn4pKCg/Oltefl0rKSl+fig/IVxccyt+fikpJC9cblxuLyoqXG4gKiBNYXRjaGVzIGEgc3RyaWtlIHRvIGEgfn5zdHJpa2V+fiBvbiBwYXN0ZS5cbiAqL1xuZXhwb3J0IGNvbnN0IHBhc3RlUmVnZXggPSAvKD86XnxcXHMpKH5+KD8hXFxzK35+KSgoPzpbXn5dKykpfn4oPyFcXHMrfn4pKS9nXG5cbi8qKlxuICogVGhpcyBleHRlbnNpb24gYWxsb3dzIHlvdSB0byBjcmVhdGUgc3RyaWtlIHRleHQuXG4gKiBAc2VlIGh0dHBzOi8vd3d3LnRpcHRhcC5kZXYvYXBpL21hcmtzL3N0cmlrZVxuICovXG5leHBvcnQgY29uc3QgU3RyaWtlID0gTWFyay5jcmVhdGU8U3RyaWtlT3B0aW9ucz4oe1xuICBuYW1lOiAnc3RyaWtlJyxcblxuICBhZGRPcHRpb25zKCkge1xuICAgIHJldHVybiB7XG4gICAgICBIVE1MQXR0cmlidXRlczoge30sXG4gICAgfVxuICB9LFxuXG4gIHBhcnNlSFRNTCgpIHtcbiAgICByZXR1cm4gW1xuICAgICAge1xuICAgICAgICB0YWc6ICdzJyxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIHRhZzogJ2RlbCcsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB0YWc6ICdzdHJpa2UnLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgc3R5bGU6ICd0ZXh0LWRlY29yYXRpb24nLFxuICAgICAgICBjb25zdW1pbmc6IGZhbHNlLFxuICAgICAgICBnZXRBdHRyczogc3R5bGUgPT4gKChzdHlsZSBhcyBzdHJpbmcpLmluY2x1ZGVzKCdsaW5lLXRocm91Z2gnKSA/IHt9IDogZmFsc2UpLFxuICAgICAgfSxcbiAgICBdXG4gIH0sXG5cbiAgcmVuZGVySFRNTCh7IEhUTUxBdHRyaWJ1dGVzIH0pIHtcbiAgICByZXR1cm4gWydzJywgbWVyZ2VBdHRyaWJ1dGVzKHRoaXMub3B0aW9ucy5IVE1MQXR0cmlidXRlcywgSFRNTEF0dHJpYnV0ZXMpLCAwXVxuICB9LFxuXG4gIGFkZENvbW1hbmRzKCkge1xuICAgIHJldHVybiB7XG4gICAgICBzZXRTdHJpa2U6ICgpID0+ICh7IGNvbW1hbmRzIH0pID0+IHtcbiAgICAgICAgcmV0dXJuIGNvbW1hbmRzLnNldE1hcmsodGhpcy5uYW1lKVxuICAgICAgfSxcbiAgICAgIHRvZ2dsZVN0cmlrZTogKCkgPT4gKHsgY29tbWFuZHMgfSkgPT4ge1xuICAgICAgICByZXR1cm4gY29tbWFuZHMudG9nZ2xlTWFyayh0aGlzLm5hbWUpXG4gICAgICB9LFxuICAgICAgdW5zZXRTdHJpa2U6ICgpID0+ICh7IGNvbW1hbmRzIH0pID0+IHtcbiAgICAgICAgcmV0dXJuIGNvbW1hbmRzLnVuc2V0TWFyayh0aGlzLm5hbWUpXG4gICAgICB9LFxuICAgIH1cbiAgfSxcblxuICBhZGRLZXlib2FyZFNob3J0Y3V0cygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgJ01vZC1TaGlmdC1zJzogKCkgPT4gdGhpcy5lZGl0b3IuY29tbWFuZHMudG9nZ2xlU3RyaWtlKCksXG4gICAgfVxuICB9LFxuXG4gIGFkZElucHV0UnVsZXMoKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIG1hcmtJbnB1dFJ1bGUoe1xuICAgICAgICBmaW5kOiBpbnB1dFJlZ2V4LFxuICAgICAgICB0eXBlOiB0aGlzLnR5cGUsXG4gICAgICB9KSxcbiAgICBdXG4gIH0sXG5cbiAgYWRkUGFzdGVSdWxlcygpIHtcbiAgICByZXR1cm4gW1xuICAgICAgbWFya1Bhc3RlUnVsZSh7XG4gICAgICAgIGZpbmQ6IHBhc3RlUmVnZXgsXG4gICAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICAgIH0pLFxuICAgIF1cbiAgfSxcbn0pXG4iLCAiaW1wb3J0IHsgVHBSdGJCYXNlRXh0ZW5zaW9uIH0gZnJvbSAnLi90cC1ydGItYmFzZS1leHRlbnNpb24uanMnO1xuaW1wb3J0IFN0cmlrZSBmcm9tICdAdGlwdGFwL2V4dGVuc2lvbi1zdHJpa2UnO1xuXG5jbGFzcyBUcFJ0YlN0cmlrZSBleHRlbmRzIFRwUnRiQmFzZUV4dGVuc2lvbiB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5sYWJlbCA9ICdTdHJpa2UnO1xuICB9XG5cbiAgZ2V0RXh0ZW5zaW9uKCkge1xuICAgIHJldHVybiBTdHJpa2U7XG4gIH1cblxuICBfaGFuZGxlQ2xpY2soKSB7XG4gICAgaWYgKHRoaXMucGFyZW50RWRpdG9yICYmIHRoaXMucGFyZW50RWRpdG9yLmVkaXRvcikge1xuICAgICAgdGhpcy5wYXJlbnRFZGl0b3IuZWRpdG9yLmNoYWluKCkuZm9jdXMoKS50b2dnbGVTdHJpa2UoKS5ydW4oKTtcbiAgICB9XG4gIH1cblxuICBfc2V0dXBFZGl0b3JMaXN0ZW5lcnMoKSB7XG4gICAgY29uc3QgeyBlZGl0b3IgfSA9IHRoaXMucGFyZW50RWRpdG9yO1xuICAgIFxuICAgIC8vIFVwZGF0ZSBidXR0b24gc3RhdGUgd2hlbiBzZWxlY3Rpb24gY2hhbmdlc1xuICAgIGVkaXRvci5vbignc2VsZWN0aW9uVXBkYXRlJywgKCkgPT4ge1xuICAgICAgdGhpcy5hY3RpdmUgPSBlZGl0b3IuaXNBY3RpdmUoJ3N0cmlrZScpO1xuICAgIH0pO1xuICAgIFxuICAgIGVkaXRvci5vbignZm9jdXMnLCAoKSA9PiB7XG4gICAgICB0aGlzLmFjdGl2ZSA9IGVkaXRvci5pc0FjdGl2ZSgnc3RyaWtlJyk7XG4gICAgfSk7XG4gIH1cbn1cblxuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCd0cC1ydGItc3RyaWtlJywgVHBSdGJTdHJpa2UpO1xuIiwgImltcG9ydCB7IE1hcmssIG1lcmdlQXR0cmlidXRlcyB9IGZyb20gJ0B0aXB0YXAvY29yZSdcblxuZXhwb3J0IGludGVyZmFjZSBVbmRlcmxpbmVPcHRpb25zIHtcbiAgLyoqXG4gICAqIEhUTUwgYXR0cmlidXRlcyB0byBhZGQgdG8gdGhlIHVuZGVybGluZSBlbGVtZW50LlxuICAgKiBAZGVmYXVsdCB7fVxuICAgKiBAZXhhbXBsZSB7IGNsYXNzOiAnZm9vJyB9XG4gICAqL1xuICBIVE1MQXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgYW55Pixcbn1cblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIHVuZGVybGluZToge1xuICAgICAgLyoqXG4gICAgICAgKiBTZXQgYW4gdW5kZXJsaW5lIG1hcmtcbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy5zZXRVbmRlcmxpbmUoKVxuICAgICAgICovXG4gICAgICBzZXRVbmRlcmxpbmU6ICgpID0+IFJldHVyblR5cGUsXG4gICAgICAvKipcbiAgICAgICAqIFRvZ2dsZSBhbiB1bmRlcmxpbmUgbWFya1xuICAgICAgICogQGV4YW1wbGUgZWRpdG9yLmNvbW1hbmRzLnRvZ2dsZVVuZGVybGluZSgpXG4gICAgICAgKi9cbiAgICAgIHRvZ2dsZVVuZGVybGluZTogKCkgPT4gUmV0dXJuVHlwZSxcbiAgICAgIC8qKlxuICAgICAgICogVW5zZXQgYW4gdW5kZXJsaW5lIG1hcmtcbiAgICAgICAqIEBleGFtcGxlIGVkaXRvci5jb21tYW5kcy51bnNldFVuZGVybGluZSgpXG4gICAgICAgKi9cbiAgICAgIHVuc2V0VW5kZXJsaW5lOiAoKSA9PiBSZXR1cm5UeXBlLFxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFRoaXMgZXh0ZW5zaW9uIGFsbG93cyB5b3UgdG8gY3JlYXRlIHVuZGVybGluZSB0ZXh0LlxuICogQHNlZSBodHRwczovL3d3dy50aXB0YXAuZGV2L2FwaS9tYXJrcy91bmRlcmxpbmVcbiAqL1xuZXhwb3J0IGNvbnN0IFVuZGVybGluZSA9IE1hcmsuY3JlYXRlPFVuZGVybGluZU9wdGlvbnM+KHtcbiAgbmFtZTogJ3VuZGVybGluZScsXG5cbiAgYWRkT3B0aW9ucygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgSFRNTEF0dHJpYnV0ZXM6IHt9LFxuICAgIH1cbiAgfSxcblxuICBwYXJzZUhUTUwoKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIHtcbiAgICAgICAgdGFnOiAndScsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBzdHlsZTogJ3RleHQtZGVjb3JhdGlvbicsXG4gICAgICAgIGNvbnN1bWluZzogZmFsc2UsXG4gICAgICAgIGdldEF0dHJzOiBzdHlsZSA9PiAoKHN0eWxlIGFzIHN0cmluZykuaW5jbHVkZXMoJ3VuZGVybGluZScpID8ge30gOiBmYWxzZSksXG4gICAgICB9LFxuICAgIF1cbiAgfSxcblxuICByZW5kZXJIVE1MKHsgSFRNTEF0dHJpYnV0ZXMgfSkge1xuICAgIHJldHVybiBbJ3UnLCBtZXJnZUF0dHJpYnV0ZXModGhpcy5vcHRpb25zLkhUTUxBdHRyaWJ1dGVzLCBIVE1MQXR0cmlidXRlcyksIDBdXG4gIH0sXG5cbiAgYWRkQ29tbWFuZHMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNldFVuZGVybGluZTogKCkgPT4gKHsgY29tbWFuZHMgfSkgPT4ge1xuICAgICAgICByZXR1cm4gY29tbWFuZHMuc2V0TWFyayh0aGlzLm5hbWUpXG4gICAgICB9LFxuICAgICAgdG9nZ2xlVW5kZXJsaW5lOiAoKSA9PiAoeyBjb21tYW5kcyB9KSA9PiB7XG4gICAgICAgIHJldHVybiBjb21tYW5kcy50b2dnbGVNYXJrKHRoaXMubmFtZSlcbiAgICAgIH0sXG4gICAgICB1bnNldFVuZGVybGluZTogKCkgPT4gKHsgY29tbWFuZHMgfSkgPT4ge1xuICAgICAgICByZXR1cm4gY29tbWFuZHMudW5zZXRNYXJrKHRoaXMubmFtZSlcbiAgICAgIH0sXG4gICAgfVxuICB9LFxuXG4gIGFkZEtleWJvYXJkU2hvcnRjdXRzKCkge1xuICAgIHJldHVybiB7XG4gICAgICAnTW9kLXUnOiAoKSA9PiB0aGlzLmVkaXRvci5jb21tYW5kcy50b2dnbGVVbmRlcmxpbmUoKSxcbiAgICAgICdNb2QtVSc6ICgpID0+IHRoaXMuZWRpdG9yLmNvbW1hbmRzLnRvZ2dsZVVuZGVybGluZSgpLFxuICAgIH1cbiAgfSxcbn0pXG4iLCAiaW1wb3J0IHsgVHBSdGJCYXNlRXh0ZW5zaW9uIH0gZnJvbSAnLi90cC1ydGItYmFzZS1leHRlbnNpb24uanMnO1xuaW1wb3J0IFVuZGVybGluZSBmcm9tICdAdGlwdGFwL2V4dGVuc2lvbi11bmRlcmxpbmUnO1xuXG5jbGFzcyBUcFJ0YlVuZGVybGluZSBleHRlbmRzIFRwUnRiQmFzZUV4dGVuc2lvbiB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5sYWJlbCA9ICdVbmRlcmxpbmUnO1xuICB9XG5cbiAgZ2V0RXh0ZW5zaW9uKCkge1xuICAgIHJldHVybiBVbmRlcmxpbmU7XG4gIH1cblxuICBfaGFuZGxlQ2xpY2soKSB7XG4gICAgaWYgKHRoaXMucGFyZW50RWRpdG9yICYmIHRoaXMucGFyZW50RWRpdG9yLmVkaXRvcikge1xuICAgICAgdGhpcy5wYXJlbnRFZGl0b3IuZWRpdG9yLmNoYWluKCkuZm9jdXMoKS50b2dnbGVVbmRlcmxpbmUoKS5ydW4oKTtcbiAgICB9XG4gIH1cblxuICBfc2V0dXBFZGl0b3JMaXN0ZW5lcnMoKSB7XG4gICAgY29uc3QgeyBlZGl0b3IgfSA9IHRoaXMucGFyZW50RWRpdG9yO1xuICAgIFxuICAgIC8vIFVwZGF0ZSBidXR0b24gc3RhdGUgd2hlbiBzZWxlY3Rpb24gY2hhbmdlc1xuICAgIGVkaXRvci5vbignc2VsZWN0aW9uVXBkYXRlJywgKCkgPT4ge1xuICAgICAgdGhpcy5hY3RpdmUgPSBlZGl0b3IuaXNBY3RpdmUoJ3VuZGVybGluZScpO1xuICAgIH0pO1xuICAgIFxuICAgIGVkaXRvci5vbignZm9jdXMnLCAoKSA9PiB7XG4gICAgICB0aGlzLmFjdGl2ZSA9IGVkaXRvci5pc0FjdGl2ZSgndW5kZXJsaW5lJyk7XG4gICAgfSk7XG4gIH1cbn1cblxuY3VzdG9tRWxlbWVudHMuZGVmaW5lKCd0cC1ydGItdW5kZXJsaW5lJywgVHBSdGJVbmRlcmxpbmUpO1xuIiwgImltcG9ydCB7XG4gIE1hcmssXG4gIG1hcmtJbnB1dFJ1bGUsXG4gIG1hcmtQYXN0ZVJ1bGUsXG4gIG1lcmdlQXR0cmlidXRlcyxcbn0gZnJvbSAnQHRpcHRhcC9jb3JlJ1xuXG5leHBvcnQgaW50ZXJmYWNlIENvZGVPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBIVE1MIGF0dHJpYnV0ZXMgYXBwbGllZCB0byB0aGUgY29kZSBlbGVtZW50LlxuICAgKiBAZGVmYXVsdCB7fVxuICAgKiBAZXhhbXBsZSB7IGNsYXNzOiAnZm9vJyB9XG4gICAqL1xuICBIVE1MQXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgYW55Pixcbn1cblxuZGVjbGFyZSBtb2R1bGUgJ0B0aXB0YXAvY29yZScge1xuICBpbnRlcmZhY2UgQ29tbWFuZHM8UmV0dXJuVHlwZT4ge1xuICAgIGNvZGU6IHtcbiAgICAgIC8qKlxuICAgICAgICogU2V0IGEgY29kZSBtYXJrXG4gICAgICAgKi9cbiAgICAgIHNldENvZGU6ICgpID0+IFJldHVyblR5cGUsXG4gICAgICAvKipcbiAgICAgICAqIFRvZ2dsZSBpbmxpbmUgY29kZVxuICAgICAgICovXG4gICAgICB0b2dnbGVDb2RlOiAoKSA9PiBSZXR1cm5UeXBlLFxuICAgICAgLyoqXG4gICAgICAgKiBVbnNldCBhIGNvZGUgbWFya1xuICAgICAgICovXG4gICAgICB1bnNldENvZGU6ICgpID0+IFJldHVyblR5cGUsXG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogUmVndWxhciBleHByZXNzaW9ucyB0byBtYXRjaCBpbmxpbmUgY29kZSBibG9ja3MgZW5jbG9zZWQgaW4gYmFja3RpY2tzLlxuICogIEl0IG1hdGNoZXM6XG4gKiAgICAgLSBBbiBvcGVuaW5nIGJhY2t0aWNrLCBmb2xsb3dlZCBieVxuICogICAgIC0gQW55IHRleHQgdGhhdCBkb2Vzbid0IGluY2x1ZGUgYSBiYWNrdGljayAoY2FwdHVyZWQgZm9yIG1hcmtpbmcpLCBmb2xsb3dlZCBieVxuICogICAgIC0gQSBjbG9zaW5nIGJhY2t0aWNrLlxuICogIFRoaXMgZW5zdXJlcyB0aGF0IGFueSB0ZXh0IGJldHdlZW4gYmFja3RpY2tzIGlzIGZvcm1hdHRlZCBhcyBjb2RlLFxuICogIHJlZ2FyZGxlc3Mgb2YgdGhlIHN1cnJvdW5kaW5nIGNoYXJhY3RlcnMgKGV4Y2VwdGlvbiBiZWluZyBhbm90aGVyIGJhY2t0aWNrKS5cbiAqL1xuZXhwb3J0IGNvbnN0IGlucHV0UmVnZXggPSAvKF58W15gXSlgKFteYF0rKWAoPyFgKS9cblxuLyoqXG4gKiBNYXRjaGVzIGlubGluZSBjb2RlIHdoaWxlIHBhc3RpbmcuXG4gKi9cbmV4cG9ydCBjb25zdCBwYXN0ZVJlZ2V4ID0gLyhefFteYF0pYChbXmBdKylgKD8hYCkvZ1xuXG4vKipcbiAqIFRoaXMgZXh0ZW5zaW9uIGFsbG93cyB5b3UgdG8gbWFyayB0ZXh0IGFzIGlubGluZSBjb2RlLlxuICogQHNlZSBodHRwczovL3RpcHRhcC5kZXYvYXBpL21hcmtzL2NvZGVcbiAqL1xuZXhwb3J0IGNvbnN0IENvZGUgPSBNYXJrLmNyZWF0ZTxDb2RlT3B0aW9ucz4oe1xuICBuYW1lOiAnY29kZScsXG5cbiAgYWRkT3B0aW9ucygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgSFRNTEF0dHJpYnV0ZXM6IHt9LFxuICAgIH1cbiAgfSxcblxuICBleGNsdWRlczogJ18nLFxuXG4gIGNvZGU6IHRydWUsXG5cbiAgZXhpdGFibGU6IHRydWUsXG5cbiAgcGFyc2VIVE1MKCkge1xuICAgIHJldHVybiBbXG4gICAgICB7IHRhZzogJ2NvZGUnIH0sXG4gICAgXVxuICB9LFxuXG4gIHJlbmRlckhUTUwoeyBIVE1MQXR0cmlidXRlcyB9KSB7XG4gICAgcmV0dXJuIFsnY29kZScsIG1lcmdlQXR0cmlidXRlcyh0aGlzLm9wdGlvbnMuSFRNTEF0dHJpYnV0ZXMsIEhUTUxBdHRyaWJ1dGVzKSwgMF1cbiAgfSxcblxuICBhZGRDb21tYW5kcygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc2V0Q29kZTogKCkgPT4gKHsgY29tbWFuZHMgfSkgPT4ge1xuICAgICAgICByZXR1cm4gY29tbWFuZHMuc2V0TWFyayh0aGlzLm5hbWUpXG4gICAgICB9LFxuICAgICAgdG9nZ2xlQ29kZTogKCkgPT4gKHsgY29tbWFuZHMgfSkgPT4ge1xuICAgICAgICByZXR1cm4gY29tbWFuZHMudG9nZ2xlTWFyayh0aGlzLm5hbWUpXG4gICAgICB9LFxuICAgICAgdW5zZXRDb2RlOiAoKSA9PiAoeyBjb21tYW5kcyB9KSA9PiB7XG4gICAgICAgIHJldHVybiBjb21tYW5kcy51bnNldE1hcmsodGhpcy5uYW1lKVxuICAgICAgfSxcbiAgICB9XG4gIH0sXG5cbiAgYWRkS2V5Ym9hcmRTaG9ydGN1dHMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICdNb2QtZSc6ICgpID0+IHRoaXMuZWRpdG9yLmNvbW1hbmRzLnRvZ2dsZUNvZGUoKSxcbiAgICB9XG4gIH0sXG5cbiAgYWRkSW5wdXRSdWxlcygpIHtcbiAgICByZXR1cm4gW1xuICAgICAgbWFya0lucHV0UnVsZSh7XG4gICAgICAgIGZpbmQ6IGlucHV0UmVnZXgsXG4gICAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICAgIH0pLFxuICAgIF1cbiAgfSxcblxuICBhZGRQYXN0ZVJ1bGVzKCkge1xuICAgIHJldHVybiBbXG4gICAgICBtYXJrUGFzdGVSdWxlKHtcbiAgICAgICAgZmluZDogcGFzdGVSZWdleCxcbiAgICAgICAgdHlwZTogdGhpcy50eXBlLFxuICAgICAgfSksXG4gICAgXVxuICB9LFxufSlcbiIsICJpbXBvcnQgeyBUcFJ0YkJhc2VFeHRlbnNpb24gfSBmcm9tICcuL3RwLXJ0Yi1iYXNlLWV4dGVuc2lvbi5qcyc7XG5pbXBvcnQgQ29kZSBmcm9tICdAdGlwdGFwL2V4dGVuc2lvbi1jb2RlJztcblxuY2xhc3MgVHBSdGJDb2RlIGV4dGVuZHMgVHBSdGJCYXNlRXh0ZW5zaW9uIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLmxhYmVsID0gJ0NvZGUnO1xuICB9XG5cbiAgZ2V0RXh0ZW5zaW9uKCkge1xuICAgIHJldHVybiBDb2RlO1xuICB9XG5cbiAgX2hhbmRsZUNsaWNrKCkge1xuICAgIGlmICh0aGlzLnBhcmVudEVkaXRvciAmJiB0aGlzLnBhcmVudEVkaXRvci5lZGl0b3IpIHtcbiAgICAgIHRoaXMucGFyZW50RWRpdG9yLmVkaXRvci5jaGFpbigpLmZvY3VzKCkudG9nZ2xlQ29kZSgpLnJ1bigpO1xuICAgIH1cbiAgfVxuXG4gIF9zZXR1cEVkaXRvckxpc3RlbmVycygpIHtcbiAgICBjb25zdCB7IGVkaXRvciB9ID0gdGhpcy5wYXJlbnRFZGl0b3I7XG4gICAgXG4gICAgLy8gVXBkYXRlIGJ1dHRvbiBzdGF0ZSB3aGVuIHNlbGVjdGlvbiBjaGFuZ2VzXG4gICAgZWRpdG9yLm9uKCdzZWxlY3Rpb25VcGRhdGUnLCAoKSA9PiB7XG4gICAgICB0aGlzLmFjdGl2ZSA9IGVkaXRvci5pc0FjdGl2ZSgnY29kZScpO1xuICAgIH0pO1xuICAgIFxuICAgIGVkaXRvci5vbignZm9jdXMnLCAoKSA9PiB7XG4gICAgICB0aGlzLmFjdGl2ZSA9IGVkaXRvci5pc0FjdGl2ZSgnY29kZScpO1xuICAgIH0pO1xuICB9XG59XG5cbmN1c3RvbUVsZW1lbnRzLmRlZmluZSgndHAtcnRiLWNvZGUnLCBUcFJ0YkNvZGUpO1xuIiwgImltcG9ydCB7IFRwUnRiQmFzZUV4dGVuc2lvbiB9IGZyb20gJy4vdHAtcnRiLWJhc2UtZXh0ZW5zaW9uLmpzJztcblxuY2xhc3MgVHBSdGJDbGVhckZvcm1hdCBleHRlbmRzIFRwUnRiQmFzZUV4dGVuc2lvbiB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5sYWJlbCA9ICdDbGVhciBGb3JtYXQnO1xuICB9XG5cbiAgX2hhbmRsZUNsaWNrKCkge1xuICAgIGlmICh0aGlzLnBhcmVudEVkaXRvciAmJiB0aGlzLnBhcmVudEVkaXRvci5lZGl0b3IpIHtcbiAgICAgIHRoaXMucGFyZW50RWRpdG9yLmVkaXRvci5jaGFpbigpLmZvY3VzKCkudW5zZXRBbGxNYXJrcygpLnJ1bigpO1xuICAgIH1cbiAgfVxufVxuXG5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ3RwLXJ0Yi1jbGVhci1mb3JtYXQnLCBUcFJ0YkNsZWFyRm9ybWF0KTtcbiIsICIvKipcbkBsaWNlbnNlXG5Db3B5cmlnaHQgKGMpIDIwMjUgdHJhZGluZ19wZXRlclxuVGhpcyBwcm9ncmFtIGlzIGF2YWlsYWJsZSB1bmRlciBBcGFjaGUgTGljZW5zZSBWZXJzaW9uIDIuMFxuKi9cblxuaW1wb3J0ICcuLi8uLi90cC1yaWNoLXRleHQtYm94LmpzJztcbmltcG9ydCAnLi4vLi4vdHAtcnRiLWJvbGQuanMnO1xuaW1wb3J0ICcuLi8uLi90cC1ydGItaXRhbGljLmpzJztcbmltcG9ydCAnLi4vLi4vdHAtcnRiLXN0cmlrZS5qcyc7XG5pbXBvcnQgJy4uLy4uL3RwLXJ0Yi11bmRlcmxpbmUuanMnO1xuaW1wb3J0ICcuLi8uLi90cC1ydGItY29kZS5qcyc7XG5pbXBvcnQgJy4uLy4uL3RwLXJ0Yi1jbGVhci1mb3JtYXQuanMnO1xuaW1wb3J0IHsgTGl0RWxlbWVudCwgaHRtbCwgY3NzIH0gZnJvbSAnbGl0JztcblxuY2xhc3MgVGhlQXBwIGV4dGVuZHMgTGl0RWxlbWVudCB7XG4gIHN0YXRpYyBnZXQgc3R5bGVzKCkge1xuICAgIHJldHVybiBbXG4gICAgICBjc3NgXG4gICAgICAgIDpob3N0IHtcbiAgICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgICAgICAgIGluc2V0OiAwO1xuICAgICAgICAgIGZvbnQtZmFtaWx5OiBzYW5zLXNlcmlmO1xuICAgICAgICB9XG4gICAgICBgXG4gICAgXTtcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICByZXR1cm4gaHRtbGBcbiAgICAgIDx0cC1yaWNoLXRleHQtYm94PlxuICAgICAgICA8dHAtcnRiLWJvbGQ+PC90cC1ydGItYm9sZD5cbiAgICAgICAgPHRwLXJ0Yi1pdGFsaWM+PC90cC1ydGItaXRhbGljPlxuICAgICAgICA8dHAtcnRiLXN0cmlrZT48L3RwLXJ0Yi1zdHJpa2U+XG4gICAgICAgIDx0cC1ydGItdW5kZXJsaW5lPjwvdHAtcnRiLXVuZGVybGluZT5cbiAgICAgICAgPHRwLXJ0Yi1jb2RlPjwvdHAtcnRiLWNvZGU+XG4gICAgICAgIDx0cC1ydGItY2xlYXItZm9ybWF0PjwvdHAtcnRiLWNsZWFyLWZvcm1hdD5cbiAgICAgIDwvdHAtcmljaC10ZXh0LWJveD5cbiAgICBgO1xuICB9XG5cbiAgc3RhdGljIGdldCBwcm9wZXJ0aWVzKCkge1xuICAgIHJldHVybiB7XG4gICAgfTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG4gIH1cbn1cblxud2luZG93LmN1c3RvbUVsZW1lbnRzLmRlZmluZSgndGhlLWFwcCcsIFRoZUFwcCk7Il0sCiAgIm1hcHBpbmdzIjogIjtBQU1BLElBR01BLElBQVNDO0FBSGYsSUFRYUMsSUFDWEYsRUFBT0csZUFBQUEsV0FDTkgsRUFBT0ksWUFBMEJKLEVBQU9JLFNBQVNDLGlCQUNsRCx3QkFBd0JDLFNBQVNDLGFBQ2pDLGFBQWFDLGNBQWNEO0FBWjdCLElBOEJNRSxJQUFvQkMsT0FB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QUNKLElBQUk7QUFBQSxFQUNKLElBQUk7QUFBQSxFQUNKLElBQUk7QUFBQSxFQUNKLElBQUk7QUFBQSxFQUNKLElBQUk7QUFBQSxFQUNKLElBQUk7QUFBQSxFQUNKLElBQUk7QUFBQSxFQUNKLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFDUDtBQUVPLElBQUksUUFBUTtBQUFBLEVBQ2pCLElBQUk7QUFBQSxFQUNKLElBQUk7QUFBQSxFQUNKLElBQUk7QUFBQSxFQUNKLElBQUk7QUFBQSxFQUNKLElBQUk7QUFBQSxFQUNKLElBQUk7QUFBQSxFQUNKLElBQUk7QUFBQSxFQUNKLElBQUk7QUFBQSxFQUNKLElBQUk7QUFBQSxFQUNKLElBQUk7QUFBQSxFQUNKLElBQUk7QUFBQSxFQUNKLElBQUk7QUFBQSxFQUNKLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFBQSxFQUNMLEtBQUs7QUFDUDtBQUVBLElBQUlFLE9BQU0sT0FBTyxhQUFh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IFsiZ2xvYmFsIiwgImdsb2JhbFRoaXMiLCAic3VwcG9ydHNBZG9wdGluZ1N0eWxlU2hlZXRzIiwgIlNoYWRvd1Jvb3QiLCAiU2hhZHlDU1MiLCAibmF0aXZlU2hhZG93IiwgIkRvY3VtZW50IiwgInByb3RvdHlwZSIsICJDU1NTdHlsZVNoZWV0IiwgImNvbnN0cnVjdGlvblRva2VuIiwgIlN5bWJvbCIsICJjc3NUYWdDYWNoZSIsICJXZWFrTWFwIiwgIkNTU1Jlc3VsdCIsICJjc3NUZXh0IiwgInN0cmluZ3MiLCAic2FmZVRva2VuIiwgInRoaXMiLCAiRXJyb3IiLCAiX3N0cmluZ3MiLCAic3R5bGVTaGVldCIsICJfc3R5bGVTaGVldCIsICJjYWNoZWFibGUiLCAibGVuZ3RoIiwgImdldCIsICJyZXBsYWNlU3luYyIsICJzZXQiLCAidG9TdHJpbmciLCAidW5zYWZlQ1NTIiwgInZhbHVlIiwgIlN0cmluZyIsICJjc3MiLCAidmFsdWVzIiwgInJlZHVjZSIsICJhY2MiLCAidiIsICJpZHgiLCAiYWRvcHRTdHlsZXMiLCAicmVuZGVyUm9vdCIsICJzdHlsZXMiLCAiYWRvcHRlZFN0eWxlU2hlZXRzIiwgIm1hcCIsICJzIiwgInN0eWxlIiwgImRvY3VtZW50IiwgImNyZWF0ZUVsZW1lbnQiLCAibm9uY2UiLCAic2V0QXR0cmlidXRlIiwgInRleHRDb250ZW50IiwgImFwcGVuZENoaWxkIiwgImdldENvbXBhdGlibGVTdHlsZSIsICJzaGVldCIsICJydWxlIiwgImNzc1J1bGVzIiwgImlzIiwgImRlZmluZVByb3BlcnR5IiwgImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsICJnZXRPd25Qcm9wZXJ0eU5hbWVzIiwgImdldE93blByb3BlcnR5U3ltYm9scyIsICJnZXRQcm90b3R5cGVPZiIsICJPYmplY3QiLCAiZ2xvYmFsIiwgImdsb2JhbFRoaXMiLCAidHJ1c3RlZFR5cGVzIiwgImVtcHR5U3RyaW5nRm9yQm9vbGVhbkF0dHJpYnV0ZSIsICJlbXB0eVNjcmlwdCIsICJwb2x5ZmlsbFN1cHBvcnQiLCAicmVhY3RpdmVFbGVtZW50UG9seWZpbGxTdXBwb3J0IiwgIkpTQ29tcGlsZXJfcmVuYW1lUHJvcGVydHkiLCAicHJvcCIsICJfb2JqIiwgImRlZmF1bHRDb252ZXJ0ZXIiLCAidmFsdWUiLCAidHlwZSIsICJCb29sZWFuIiwgIkFycmF5IiwgIkpTT04iLCAic3RyaW5naWZ5IiwgImZyb21WYWx1ZSIsICJOdW1iZXIiLCAicGFyc2UiLCAiZSIsICJub3RFcXVhbCIsICJvbGQiLCAiZGVmYXVsdFByb3BlcnR5RGVjbGFyYXRpb24iLCAiYXR0cmlidXRlIiwgIlN0cmluZyIsICJjb252ZXJ0ZXIiLCAicmVmbGVjdCIsICJ1c2VEZWZhdWx0IiwgImhhc0NoYW5nZWQiLCAiU3ltYm9sIiwgIm1ldGFkYXRhIiwgImxpdFByb3BlcnR5TWV0YWRhdGEiLCAiV2Vha01hcCIsICJSZWFjdGl2ZUVsZW1lbnQiLCAiSFRNTEVsZW1lbnQiLCAiaW5pdGlhbGl6ZXIiLCAidGhpcyIsICJfX3ByZXBhcmUiLCAiX2luaXRpYWxpemVycyIsICJwdXNoIiwgIm9ic2VydmVkQXR0cmlidXRlcyIsICJmaW5hbGl6ZSIsICJfX2F0dHJpYnV0ZVRvUHJvcGVydHlNYXAiLCAia2V5cyIsICJuYW1lIiwgIm9wdGlvbnMiLCAic3RhdGUiLCAicHJvdG90eXBlIiwgImhhc093blByb3BlcnR5IiwgImNyZWF0ZSIsICJ3cmFwcGVkIiwgImVsZW1lbnRQcm9wZXJ0aWVzIiwgInNldCIsICJub0FjY2Vzc29yIiwgImtleSIsICJkZXNjcmlwdG9yIiwgImdldFByb3BlcnR5RGVzY3JpcHRvciIsICJnZXQiLCAidiIsICJvbGRWYWx1ZSIsICJjYWxsIiwgInJlcXVlc3RVcGRhdGUiLCAiY29uZmlndXJhYmxlIiwgImVudW1lcmFibGUiLCAic3VwZXJDdG9yIiwgIk1hcCIsICJmaW5hbGl6ZWQiLCAicHJvcHMiLCAicHJvcGVydGllcyIsICJwcm9wS2V5cyIsICJwIiwgImNyZWF0ZVByb3BlcnR5IiwgImF0dHIiLCAiX19hdHRyaWJ1dGVOYW1lRm9yUHJvcGVydHkiLCAiZWxlbWVudFN0eWxlcyIsICJmaW5hbGl6ZVN0eWxlcyIsICJzdHlsZXMiLCAiaXNBcnJheSIsICJTZXQiLCAiZmxhdCIsICJJbmZpbml0eSIsICJyZXZlcnNlIiwgInMiLCAidW5zaGlmdCIsICJnZXRDb21wYXRpYmxlU3R5bGUiLCAidG9Mb3dlckNhc2UiLCAiY29uc3RydWN0b3IiLCAic3VwZXIiLCAiX19pbnN0YW5jZVByb3BlcnRpZXMiLCAiaXNVcGRhdGVQZW5kaW5nIiwgImhhc1VwZGF0ZWQiLCAiX19yZWZsZWN0aW5nUHJvcGVydHkiLCAiX19pbml0aWFsaXplIiwgIl9fdXBkYXRlUHJvbWlzZSIsICJQcm9taXNlIiwgInJlcyIsICJlbmFibGVVcGRhdGluZyIsICJfJGNoYW5nZWRQcm9wZXJ0aWVzIiwgIl9fc2F2ZUluc3RhbmNlUHJvcGVydGllcyIsICJmb3JFYWNoIiwgImkiLCAiY29udHJvbGxlciIsICJfX2NvbnRyb2xsZXJzIiwgImFkZCIsICJyZW5kZXJSb290IiwgImlzQ29ubmVjdGVkIiwgImhvc3RDb25uZWN0ZWQiLCAiZGVsZXRlIiwgImluc3RhbmNlUHJvcGVydGllcyIsICJzaXplIiwgImNyZWF0ZVJlbmRlclJvb3QiLCAic2hhZG93Um9vdCIsICJhdHRhY2hTaGFkb3ciLCAic2hhZG93Um9vdE9wdGlvbnMiLCAiYWRvcHRTdHlsZXMiLCAiY29ubmVjdGVkQ2FsbGJhY2siLCAiYyIsICJfcmVxdWVzdGVkVXBkYXRlIiwgImRpc2Nvbm5lY3RlZENhbGxiYWNrIiwgImhvc3REaXNjb25uZWN0ZWQiLCAiX29sZCIsICJfJGF0dHJpYnV0ZVRvUHJvcGVydHkiLCAiYXR0clZhbHVlIiwgInRvQXR0cmlidXRlIiwgInJlbW92ZUF0dHJpYnV0ZSIsICJzZXRBdHRyaWJ1dGUiLCAiY3RvciIsICJwcm9wTmFtZSIsICJnZXRQcm9wZXJ0eU9wdGlvbnMiLCAiZnJvbUF0dHJpYnV0ZSIsICJfX2RlZmF1bHRWYWx1ZXMiLCAibmV3VmFsdWUiLCAiaGFzQXR0cmlidXRlIiwgIl8kY2hhbmdlUHJvcGVydHkiLCAiX19lbnF1ZXVlVXBkYXRlIiwgImluaXRpYWxpemVWYWx1ZSIsICJoYXMiLCAiX19yZWZsZWN0aW5nUHJvcGVydGllcyIsICJyZWplY3QiLCAicmVzdWx0IiwgInNjaGVkdWxlVXBkYXRlIiwgInBlcmZvcm1VcGRhdGUiLCAic2hvdWxkVXBkYXRlIiwgImNoYW5nZWRQcm9wZXJ0aWVzIiwgIndpbGxVcGRhdGUiLCAiaG9zdFVwZGF0ZSIsICJ1cGRhdGUiLCAiX19tYXJrVXBkYXRlZCIsICJfJGRpZFVwZGF0ZSIsICJfY2hhbmdlZFByb3BlcnRpZXMiLCAiaG9zdFVwZGF0ZWQiLCAiZmlyc3RVcGRhdGVkIiwgInVwZGF0ZWQiLCAidXBkYXRlQ29tcGxldGUiLCAiZ2V0VXBkYXRlQ29tcGxldGUiLCAiX19wcm9wZXJ0eVRvQXR0cmlidXRlIiwgIm1vZGUiLCAicmVhY3RpdmVFbGVtZW50VmVyc2lvbnMiLCAiZ2xvYmFsIiwgImdsb2JhbFRoaXMiLCAidHJ1c3RlZFR5cGVzIiwgInBvbGljeSIsICJjcmVhdGVQb2xpY3kiLCAiY3JlYXRlSFRNTCIsICJzIiwgImJvdW5kQXR0cmlidXRlU3VmZml4IiwgIm1hcmtlciIsICJNYXRoIiwgInJhbmRvbSIsICJ0b0ZpeGVkIiwgInNsaWNlIiwgIm1hcmtlck1hdGNoIiwgIm5vZGVNYXJrZXIiLCAiZCIsICJkb2N1bWVudCIsICJjcmVhdGVNYXJrZXIiLCAiY3JlYXRlQ29tbWVudCIsICJpc1ByaW1pdGl2ZSIsICJ2YWx1ZSIsICJpc0FycmF5IiwgIkFycmF5IiwgImlzSXRlcmFibGUiLCAiU3ltYm9sIiwgIml0ZXJhdG9yIiwgIlNQQUNFX0NIQVIiLCAidGV4dEVuZFJlZ2V4IiwgImNvbW1lbnRFbmRSZWdleCIsICJjb21tZW50MkVuZFJlZ2V4IiwgInRhZ0VuZFJlZ2V4IiwgIlJlZ0V4cCIsICJzaW5nbGVRdW90ZUF0dHJFbmRSZWdleCIsICJkb3VibGVRdW90ZUF0dHJFbmRSZWdleCIsICJyYXdUZXh0RWxlbWVudCIsICJ0YWciLCAidHlwZSIsICJzdHJpbmdzIiwgInZhbHVlcyIsICJfJGxpdFR5cGUkIiwgImh0bWwiLCAic3ZnIiwgIm1hdGhtbCIsICJub0NoYW5nZSIsICJmb3IiLCAibm90aGluZyIsICJ0ZW1wbGF0ZUNhY2hlIiwgIldlYWtNYXAiLCAid2Fsa2VyIiwgImNyZWF0ZVRyZWVXYWxrZXIiLCAidHJ1c3RGcm9tVGVtcGxhdGVTdHJpbmciLCAidHNhIiwgInN0cmluZ0Zyb21UU0EiLCAiaGFzT3duUHJvcGVydHkiLCAiRXJyb3IiLCAiZ2V0VGVtcGxhdGVIdG1sIiwgImwiLCAibGVuZ3RoIiwgImF0dHJOYW1lcyIsICJyYXdUZXh0RW5kUmVnZXgiLCAicmVnZXgiLCAiaSIsICJhdHRyTmFtZSIsICJtYXRjaCIsICJhdHRyTmFtZUVuZEluZGV4IiwgImxhc3RJbmRleCIsICJleGVjIiwgInRlc3QiLCAiZW5kIiwgInN0YXJ0c1dpdGgiLCAicHVzaCIsICJUZW1wbGF0ZSIsICJjb25zdHJ1Y3RvciIsICJvcHRpb25zIiwgIm5vZGUiLCAidGhpcyIsICJwYXJ0cyIsICJub2RlSW5kZXgiLCAiYXR0ck5hbWVJbmRleCIsICJwYXJ0Q291bnQiLCAiZWwiLCAiY3JlYXRlRWxlbWVudCIsICJjdXJyZW50Tm9kZSIsICJjb250ZW50IiwgIndyYXBwZXIiLCAiZmlyc3RDaGlsZCIsICJyZXBsYWNlV2l0aCIsICJjaGlsZE5vZGVzIiwgIm5leHROb2RlIiwgIm5vZGVUeXBlIiwgImhhc0F0dHJpYnV0ZXMiLCAibmFtZSIsICJnZXRBdHRyaWJ1dGVOYW1lcyIsICJlbmRzV2l0aCIsICJyZWFsTmFtZSIsICJzdGF0aWNzIiwgImdldEF0dHJpYnV0ZSIsICJzcGxpdCIsICJtIiwgImluZGV4IiwgImN0b3IiLCAiUHJvcGVydHlQYXJ0IiwgIkJvb2xlYW5BdHRyaWJ1dGVQYXJ0IiwgIkV2ZW50UGFydCIsICJBdHRyaWJ1dGVQYXJ0IiwgInJlbW92ZUF0dHJpYnV0ZSIsICJ0YWdOYW1lIiwgInRleHRDb250ZW50IiwgImVtcHR5U2NyaXB0IiwgImFwcGVuZCIsICJkYXRhIiwgImluZGV4T2YiLCAiX29wdGlvbnMiLCAiaW5uZXJIVE1MIiwgInJlc29sdmVEaXJlY3RpdmUiLCAicGFydCIsICJwYXJlbnQiLCAiYXR0cmlidXRlSW5kZXgiLCAiY3VycmVudERpcmVjdGl2ZSIsICJfX2RpcmVjdGl2ZXMiLCAiX19kaXJlY3RpdmUiLCAibmV4dERpcmVjdGl2ZUNvbnN0cnVjdG9yIiwgIl8kaW5pdGlhbGl6ZSIsICJfJHJlc29sdmUiLCAiVGVtcGxhdGVJbnN0YW5jZSIsICJ0ZW1wbGF0ZSIsICJfJHBhcnRzIiwgIl8kZGlzY29ubmVjdGFibGVDaGlsZHJlbiIsICJfJHRlbXBsYXRlIiwgIl8kcGFyZW50IiwgInBhcmVudE5vZGUiLCAiXyRpc0Nvbm5lY3RlZCIsICJmcmFnbWVudCIsICJjcmVhdGlvblNjb3BlIiwgImltcG9ydE5vZGUiLCAicGFydEluZGV4IiwgInRlbXBsYXRlUGFydCIsICJDaGlsZFBhcnQiLCAibmV4dFNpYmxpbmciLCAiRWxlbWVudFBhcnQiLCAiXyRzZXRWYWx1ZSIsICJfX2lzQ29ubmVjdGVkIiwgInN0YXJ0Tm9kZSIsICJlbmROb2RlIiwgIl8kY29tbWl0dGVkVmFsdWUiLCAiXyRzdGFydE5vZGUiLCAiXyRlbmROb2RlIiwgImlzQ29ubmVjdGVkIiwgImRpcmVjdGl2ZVBhcmVudCIsICJfJGNsZWFyIiwgIl9jb21taXRUZXh0IiwgIl9jb21taXRUZW1wbGF0ZVJlc3VsdCIsICJfY29tbWl0Tm9kZSIsICJfY29tbWl0SXRlcmFibGUiLCAiaW5zZXJ0QmVmb3JlIiwgIl9pbnNlcnQiLCAiY3JlYXRlVGV4dE5vZGUiLCAicmVzdWx0IiwgIl8kZ2V0VGVtcGxhdGUiLCAiaCIsICJfdXBkYXRlIiwgImluc3RhbmNlIiwgIl9jbG9uZSIsICJnZXQiLCAic2V0IiwgIml0ZW1QYXJ0cyIsICJpdGVtUGFydCIsICJpdGVtIiwgInN0YXJ0IiwgImZyb20iLCAiXyRub3RpZnlDb25uZWN0aW9uQ2hhbmdlZCIsICJuIiwgInJlbW92ZSIsICJlbGVtZW50IiwgImZpbGwiLCAiU3RyaW5nIiwgInZhbHVlSW5kZXgiLCAibm9Db21taXQiLCAiY2hhbmdlIiwgInYiLCAiX2NvbW1pdFZhbHVlIiwgInNldEF0dHJpYnV0ZSIsICJ0b2dnbGVBdHRyaWJ1dGUiLCAic3VwZXIiLCAibmV3TGlzdGVuZXIiLCAib2xkTGlzdGVuZXIiLCAic2hvdWxkUmVtb3ZlTGlzdGVuZXIiLCAiY2FwdHVyZSIsICJvbmNlIiwgInBhc3NpdmUiLCAic2hvdWxkQWRkTGlzdGVuZXIiLCAicmVtb3ZlRXZlbnRMaXN0ZW5lciIsICJhZGRFdmVudExpc3RlbmVyIiwgImV2ZW50IiwgImNhbGwiLCAiaG9zdCIsICJoYW5kbGVFdmVudCIsICJwb2x5ZmlsbFN1cHBvcnQiLCAiZ2xvYmFsIiwgImxpdEh0bWxQb2x5ZmlsbFN1cHBvcnQiLCAiVGVtcGxhdGUiLCAiQ2hpbGRQYXJ0IiwgImxpdEh0bWxWZXJzaW9ucyIsICJwdXNoIiwgInJlbmRlciIsICJ2YWx1ZSIsICJjb250YWluZXIiLCAib3B0aW9ucyIsICJwYXJ0T3duZXJOb2RlIiwgInJlbmRlckJlZm9yZSIsICJwYXJ0IiwgImVuZE5vZGUiLCAiaW5zZXJ0QmVmb3JlIiwgImNyZWF0ZU1hcmtlciIsICJfJHNldFZhbHVlIiwgImdsb2JhbCIsICJnbG9iYWxUaGlzIiwgIkxpdEVsZW1lbnQiLCAiUmVhY3RpdmVFbGVtZW50IiwgImNvbnN0cnVjdG9yIiwgInRoaXMiLCAicmVuZGVyT3B0aW9ucyIsICJob3N0IiwgIl9fY2hpbGRQYXJ0IiwgImNyZWF0ZVJlbmRlclJvb3QiLCAicmVuZGVyUm9vdCIsICJzdXBlciIsICJyZW5kZXJCZWZvcmUiLCAiZmlyc3RDaGlsZCIsICJjaGFuZ2VkUHJvcGVydGllcyIsICJ2YWx1ZSIsICJyZW5kZXIiLCAiaGFzVXBkYXRlZCIsICJpc0Nvbm5lY3RlZCIsICJ1cGRhdGUiLCAiY29ubmVjdGVkQ2FsbGJhY2siLCAic2V0Q29ubmVjdGVkIiwgImRpc2Nvbm5lY3RlZENhbGxiYWNrIiwgIm5vQ2hhbmdlIiwgImxpdEVsZW1lbnRIeWRyYXRlU3VwcG9ydCIsICJwb2x5ZmlsbFN1cHBvcnQiLCAibGl0RWxlbWVudFBvbHlmaWxsU3VwcG9ydCIsICJnbG9iYWwiLCAibGl0RWxlbWVudFZlcnNpb25zIiwgInB1c2giLCAiaSIsICJmb3VuZCIsICJmIiwgImEiLCAiYiIsICJpIiwgImoiLCAiZiIsICJmaXJzdCIsICJjb3B5IiwgImZvdW5kIiwgInAiLCAibiIsICJfIiwgImQiLCAiZG9jIiwgIm0iLCAiYmFzZSIsICJ0eXBlIiwgIm5mYSIsICJlZGdlIiwgImV4cHIiLCAibm9kZSIsICJzdGF0ZXMiLCAibmFtZSIsICJtYXJrIiwgInIiLCAic3R5bGUiLCAid3JhcCIsICJzcGFjZSIsICJpIiwgImRlbCIsICJmIiwgIm4iLCAibSIsICJkb2MiLCAiZSIsICJwYXJlbnQiLCAicyIsICJmb3VuZCIsICJzdHlsZSIsICJqIiwgImQiLCAiYmFzZSIsICJpbmRleCIsICJqb2luYWJsZSIsICJhIiwgImIiLCAiZmlyc3QiLCAid3JhcCIsICJtYXRjaGVzIiwgIm1hdGNoIiwgInR5cGUiLCAiY2xvc2UiLCAiVHJhbnNmb3JtRXJyb3IiLCAiaSIsICJmb3VuZCIsICJkb2MiLCAiXyIsICJmIiwgIm4iLCAiaiIsICJtIiwgImRvYyIsICJ4IiwgInkiLCAiXyIsICJpIiwgImoiLCAicCIsICJmaXJzdCIsICJmIiwgImVudGVyIiwgImJhc2UiLCAid3JhcCIsICJjb3B5IiwgInNwZWMiLCAibiIsICJtIiwgImEiLCAiYiIsICJmb3VuZCIsICJlIiwgInByZU1hdGNoIiwgIm1hdGNoZXMiLCAiZCIsICJlbXB0eSIsICJkb20iLCAicyIsICJldmVudCIsICJoYW5kbGVycyIsICJzZWwiLCAiY3V0IiwgIk5vZGVUeXBlIiwgInIiLCAib2xkT2Zmc2V0IiwgImFuY2hvciIsICJ0ciIsICJmIiwgImkiLCAiZm91bmQiLCAicHJvcCIsICJhIiwgImIiLCAiXyIsICJtYWMiLCAiaWUiLCAiaSIsICJtYWMiLCAid2luZG93cyIsICJzaGlmdCIsICJpIiwgImNvcHkiLCAiZW1wdHkiLCAiaSIsICJsaWZ0IiwgImQiLCAiZmlyc3QiLCAid3JhcCIsICJpIiwgInNldEJsb2NrVHlwZSIsICJjb21tYW5kcyIsICJpIiwgIm1hYyIsICJkb2MiLCAid3JhcCIsICJpIiwgImZvdW5kIiwgImUiLCAiZmlyc3QiLCAiaSIsICJlIiwgImRvYyIsICJjb21tYW5kIiwgInJ1biIsICJzdHlsZSIsICJlIiwgIl9hIiwgImNvbW1hbmRzIiwgIk1hcmsiLCAibSIsICJyZW1vdmVNYXJrIiwgIm1hdGNoZXMiLCAiaGFuZGxlcnMiLCAiZnJvbSIsICJ0byIsICJhIiwgImIiLCAicmFuZ2UiLCAiY3JlYXRlUGFyYWdyYXBoTmVhciIsICJvcmlnaW5hbENyZWF0ZVBhcmFncmFwaE5lYXIiLCAiZGVsZXRlUmFuZ2UiLCAiZGVsZXRlU2VsZWN0aW9uIiwgIm9yaWdpbmFsRGVsZXRlU2VsZWN0aW9uIiwgImV4aXRDb2RlIiwgIm9yaWdpbmFsRXhpdENvZGUiLCAia2V5cyIsICJrIiwgIm1hcmsiLCAiaSIsICJQcm9zZU1pcnJvck5vZGUiLCAic2VsZWN0aW9uVG9JbnNlcnRpb25FbmQiLCAidiIsICJqb2luVXAiLCAib3JpZ2luYWxKb2luVXAiLCAiam9pbkRvd24iLCAib3JpZ2luYWxKb2luRG93biIsICJqb2luQmFja3dhcmQiLCAib3JpZ2luYWxKb2luQmFja3dhcmQiLCAiam9pbkZvcndhcmQiLCAib3JpZ2luYWxKb2luRm9yd2FyZCIsICJqb2luVGV4dGJsb2NrQmFja3dhcmQiLCAib3JpZ2luYWxDb21tYW5kIiwgImpvaW5UZXh0YmxvY2tGb3J3YXJkIiwgIm5vcm1hbGl6ZUtleU5hbWUiLCAic2hpZnQiLCAiZiIsICJlbXB0eSIsICJsaWZ0IiwgImlzQWN0aXZlIiwgIm9yaWdpbmFsTGlmdCIsICJsaWZ0RW1wdHlCbG9jayIsICJvcmlnaW5hbExpZnRFbXB0eUJsb2NrIiwgImxpZnRMaXN0SXRlbSIsICJvcmlnaW5hbExpZnRMaXN0SXRlbSIsICJuZXdsaW5lSW5Db2RlIiwgIm9yaWdpbmFsTmV3bGluZUluQ29kZSIsICJzZWxlY3RBbGwiLCAic2VsZWN0Tm9kZUJhY2t3YXJkIiwgIm9yaWdpbmFsU2VsZWN0Tm9kZUJhY2t3YXJkIiwgInNlbGVjdE5vZGVGb3J3YXJkIiwgIm9yaWdpbmFsU2VsZWN0Tm9kZUZvcndhcmQiLCAic2VsZWN0UGFyZW50Tm9kZSIsICJvcmlnaW5hbFNlbGVjdFBhcmVudE5vZGUiLCAic2VsZWN0VGV4dGJsb2NrRW5kIiwgIm9yaWdpbmFsU2VsZWN0VGV4dGJsb2NrRW5kIiwgInNlbGVjdFRleHRibG9ja1N0YXJ0IiwgIm9yaWdpbmFsU2VsZWN0VGV4dGJsb2NrU3RhcnQiLCAiZG9jdW1lbnQiLCAiZGVmYXVsdEJsb2NrQXQiLCAiaSIsICJpIiwgImdldFRleHQiLCAibm9kZSIsICJkb2MiLCAiZW1wdHkiLCAicmFuZ2UiLCAiZW1wdHkiLCAiY29tbWFuZHMiLCAic2V0QmxvY2tUeXBlIiwgImRvYyIsICJzaW5rTGlzdEl0ZW0iLCAib3JpZ2luYWxTaW5rTGlzdEl0ZW0iLCAic3BsaXRCbG9jayIsICJkZWZhdWx0QmxvY2tBdCIsICJmaXJzdCIsICJ3cmFwIiwgImQiLCAibmV3TmV4dFR5cGVBdHRyaWJ1dGVzIiwgIm5leHRUeXBlIiwgIm4iLCAiaXNBY3RpdmUiLCAiaSIsICJqIiwgIndyYXBJbiIsICJvcmlnaW5hbFdyYXBJbiIsICJ3cmFwSW5MaXN0IiwgIm9yaWdpbmFsV3JhcEluTGlzdCIsICJfIiwgImUiLCAidHIiLCAic3R5bGUiLCAiZG9jIiwgImUiLCAiZm9jdXMiLCAiYmx1ciIsICJnZXRUZXh0IiwgIk5vZGUiLCAiRG9jdW1lbnQiLCAiTm9kZSIsICJOb2RlIiwgImNvbW1hbmRzIiwgIk5vZGUiLCAiTm9kZSIsICJjb21tYW5kcyIsICJpIiwgImVtcHR5IiwgImUiLCAiRG9jdW1lbnQiLCAiaSIsICJNYXJrIiwgImNvbW1hbmRzIiwgInN0YXJJbnB1dFJlZ2V4IiwgInN0YXJQYXN0ZVJlZ2V4IiwgInVuZGVyc2NvcmVJbnB1dFJlZ2V4IiwgInVuZGVyc2NvcmVQYXN0ZVJlZ2V4IiwgIk1hcmsiLCAiY29tbWFuZHMiLCAiTWFyayIsICJzdHlsZSIsICJjb21tYW5kcyIsICJNYXJrIiwgInN0eWxlIiwgImNvbW1hbmRzIiwgImlucHV0UmVnZXgiLCAicGFzdGVSZWdleCIsICJNYXJrIiwgImNvbW1hbmRzIiwgImkiXQp9Cg== diff --git a/demo/index.html b/demo/index.html new file mode 100644 index 0000000..d04d8b7 --- /dev/null +++ b/demo/index.html @@ -0,0 +1,18 @@ + + + + tp-rich-text-box demo + + + + + + + + + \ No newline at end of file diff --git a/demo/src/the-app.js b/demo/src/the-app.js new file mode 100644 index 0000000..ab06ff7 --- /dev/null +++ b/demo/src/the-app.js @@ -0,0 +1,54 @@ +/** +@license +Copyright (c) 2025 trading_peter +This program is available under Apache License Version 2.0 +*/ + +import '../../tp-rich-text-box.js'; +import '../../tp-rtb-bold.js'; +import '../../tp-rtb-italic.js'; +import '../../tp-rtb-strike.js'; +import '../../tp-rtb-underline.js'; +import '../../tp-rtb-code.js'; +import '../../tp-rtb-clear-format.js'; +import { LitElement, html, css } from 'lit'; + +class TheApp extends LitElement { + static get styles() { + return [ + css` + :host { + display: flex; + flex-direction: column; + position: absolute; + inset: 0; + font-family: sans-serif; + } + ` + ]; + } + + render() { + return html` + + + + + + + + + `; + } + + static get properties() { + return { + }; + } + + constructor() { + super(); + } +} + +window.customElements.define('the-app', TheApp); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..c07f9d3 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,597 @@ +{ + "name": "@tp/tp-rich-text-box", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@tp/tp-rich-text-box", + "version": "0.0.1", + "license": "Apache-2.0", + "dependencies": { + "@tiptap/core": "^2.12.0", + "@tiptap/extension-bold": "^2.12.0", + "@tiptap/extension-code": "^2.24.2", + "@tiptap/extension-document": "^2.24.2", + "@tiptap/extension-hard-break": "^2.24.2", + "@tiptap/extension-italic": "^2.0.0-beta.220", + "@tiptap/extension-paragraph": "^2.0.0-beta.220", + "@tiptap/extension-strike": "^2.0.0-beta.220", + "@tiptap/extension-text": "^2.0.0-beta.220", + "@tiptap/extension-underline": "^2.0.0-beta.220", + "lit": "^3.0.0" + } + }, + "node_modules/@lit-labs/ssr-dom-shim": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.3.0.tgz", + "integrity": "sha512-nQIWonJ6eFAvUUrSlwyHDm/aE8PBDu5kRpL0vHMg6K8fK3Diq1xdPjTnsJSwxABhaZ+5eBi1btQB5ShUTKo4nQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@lit/reactive-element": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.1.0.tgz", + "integrity": "sha512-L2qyoZSQClcBmq0qajBVbhYEcG6iK0XfLn66ifLe/RfC0/ihpc+pl0Wdn8bJ8o+hj38cG0fGXRgSS20MuXn7qA==", + "license": "BSD-3-Clause", + "dependencies": { + "@lit-labs/ssr-dom-shim": "^1.2.0" + } + }, + "node_modules/@remirror/core-constants": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@remirror/core-constants/-/core-constants-3.0.0.tgz", + "integrity": "sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==", + "license": "MIT", + "peer": true + }, + "node_modules/@tiptap/core": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.12.0.tgz", + "integrity": "sha512-3qX8oGVKFFZzQ0vit+ZolR6AJIATBzmEmjAA0llFhWk4vf3v64p1YcXcJsOBsr5scizJu5L6RYWEFatFwqckRg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-bold": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.12.0.tgz", + "integrity": "sha512-lAUtoLDLRc5ofD2I9MFY6MQ7d1qBLLqS1rvpwaPjOaoQb/GPVnaHj9qXYG0SY9K3erMtto48bMFpAcscjZHzZQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-code": { + "version": "2.24.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.24.2.tgz", + "integrity": "sha512-dK1jOm0Xe0h8SUXVUJPj3AxWb1N4zeBkdPZFoz+iUHacpymMinH1CuukN9UpwmSi0YPfrIMKkCaw5WOEzjV8RA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-document": { + "version": "2.24.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.24.2.tgz", + "integrity": "sha512-w3q1JaWZlwK8aHmF4lrFqalLssNkZoS3rjL/iS0v69q/fTI9t0WmCx5Jx427eUlNITZ5XoCL8zguKmnSPbFovg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-hard-break": { + "version": "2.24.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.24.2.tgz", + "integrity": "sha512-6TB9GBUTp3DIOptQubEVvL6BVKhxfLzAJwWYXjw0EkZHrK8TQPB3QIjLV/uZy29Ruji2k97ytxuxfrGoQXoXtA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-italic": { + "version": "2.24.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.24.2.tgz", + "integrity": "sha512-gW9c0zJh4f9D2uZl13rhV8FFt7UgISLiRp4e+DynpKUkhjftDHmruii5Qw6fz9W5cf/vQcyMwCN3lO7Efqnyng==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-paragraph": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.12.0.tgz", + "integrity": "sha512-QNK5cgewCunWFxpLlbvvoO1rrLgEtNKxiY79fctP9toV+e59R+1i1Q9lXC1O5mOfDgVxCb6uFDMsqmKhFjpPog==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-strike": { + "version": "2.24.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.24.2.tgz", + "integrity": "sha512-7JJ+IOTOoXlAqXDiUY9A+oRx01vRClvKuQzIDQoDtvd4Ut9rkZ+9L+Iv7AE/HzGkOOAVvfvLzYcyHiHDOpArDA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-text": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.12.0.tgz", + "integrity": "sha512-0ytN9V1tZYTXdiYDQg4FB2SQ56JAJC9r/65snefb9ztl+gZzDrIvih7CflHs1ic9PgyjexfMLeH+VzuMccNyZw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-underline": { + "version": "2.24.2", + "resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-2.24.2.tgz", + "integrity": "sha512-vzsGRGsHkoV43tnJKjb4aLzVYtJ531Puxjf3qToGP5kRqyuSl2FyCARTZUHgVhMmD7Yu6oXsrXvTR3pNaDuIrA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/pm": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.12.0.tgz", + "integrity": "sha512-TNzVwpeNzFfHAcYTOKqX9iU4fRxliyoZrCnERR+RRzeg7gWrXrCLubQt1WEx0sojMAfznshSL3M5HGsYjEbYwA==", + "license": "MIT", + "peer": true, + "dependencies": { + "prosemirror-changeset": "^2.3.0", + "prosemirror-collab": "^1.3.1", + "prosemirror-commands": "^1.6.2", + "prosemirror-dropcursor": "^1.8.1", + "prosemirror-gapcursor": "^1.3.2", + "prosemirror-history": "^1.4.1", + "prosemirror-inputrules": "^1.4.0", + "prosemirror-keymap": "^1.2.2", + "prosemirror-markdown": "^1.13.1", + "prosemirror-menu": "^1.2.4", + "prosemirror-model": "^1.23.0", + "prosemirror-schema-basic": "^1.2.3", + "prosemirror-schema-list": "^1.4.1", + "prosemirror-state": "^1.4.3", + "prosemirror-tables": "^1.6.4", + "prosemirror-trailing-node": "^3.0.0", + "prosemirror-transform": "^1.10.2", + "prosemirror-view": "^1.37.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + } + }, + "node_modules/@types/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", + "license": "MIT", + "peer": true + }, + "node_modules/@types/markdown-it": { + "version": "14.1.2", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", + "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/linkify-it": "^5", + "@types/mdurl": "^2" + } + }, + "node_modules/@types/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", + "license": "MIT", + "peer": true + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0", + "peer": true + }, + "node_modules/crelt": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", + "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==", + "license": "MIT", + "peer": true + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "uc.micro": "^2.0.0" + } + }, + "node_modules/lit": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lit/-/lit-3.3.0.tgz", + "integrity": "sha512-DGVsqsOIHBww2DqnuZzW7QsuCdahp50ojuDaBPC7jUDRpYoH0z7kHBBYZewRzer75FwtrkmkKk7iOAwSaWdBmw==", + "license": "BSD-3-Clause", + "dependencies": { + "@lit/reactive-element": "^2.1.0", + "lit-element": "^4.2.0", + "lit-html": "^3.3.0" + } + }, + "node_modules/lit-element": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.2.0.tgz", + "integrity": "sha512-MGrXJVAI5x+Bfth/pU9Kst1iWID6GHDLEzFEnyULB/sFiRLgkd8NPK/PeeXxktA3T6EIIaq8U3KcbTU5XFcP2Q==", + "license": "BSD-3-Clause", + "dependencies": { + "@lit-labs/ssr-dom-shim": "^1.2.0", + "@lit/reactive-element": "^2.1.0", + "lit-html": "^3.3.0" + } + }, + "node_modules/lit-html": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.3.0.tgz", + "integrity": "sha512-RHoswrFAxY2d8Cf2mm4OZ1DgzCoBKUKSPvA1fhtSELxUERq2aQQ2h05pO9j81gS1o7RIRJ+CePLogfyahwmynw==", + "license": "BSD-3-Clause", + "dependencies": { + "@types/trusted-types": "^2.0.2" + } + }, + "node_modules/markdown-it": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "license": "MIT", + "peer": true, + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "license": "MIT", + "peer": true + }, + "node_modules/orderedmap": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz", + "integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==", + "license": "MIT", + "peer": true + }, + "node_modules/prosemirror-changeset": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.3.0.tgz", + "integrity": "sha512-8wRKhlEwEJ4I13Ju54q2NZR1pVKGTgJ/8XsQ8L5A5uUsQ/YQScQJuEAuh8Bn8i6IwAMjjLRABd9lVli+DlIiVw==", + "license": "MIT", + "peer": true, + "dependencies": { + "prosemirror-transform": "^1.0.0" + } + }, + "node_modules/prosemirror-collab": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/prosemirror-collab/-/prosemirror-collab-1.3.1.tgz", + "integrity": "sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "prosemirror-state": "^1.0.0" + } + }, + "node_modules/prosemirror-commands": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.7.1.tgz", + "integrity": "sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==", + "license": "MIT", + "peer": true, + "dependencies": { + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.10.2" + } + }, + "node_modules/prosemirror-dropcursor": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.2.tgz", + "integrity": "sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==", + "license": "MIT", + "peer": true, + "dependencies": { + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.1.0", + "prosemirror-view": "^1.1.0" + } + }, + "node_modules/prosemirror-gapcursor": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.3.2.tgz", + "integrity": "sha512-wtjswVBd2vaQRrnYZaBCbyDqr232Ed4p2QPtRIUK5FuqHYKGWkEwl08oQM4Tw7DOR0FsasARV5uJFvMZWxdNxQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "prosemirror-keymap": "^1.0.0", + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-view": "^1.0.0" + } + }, + "node_modules/prosemirror-history": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.4.1.tgz", + "integrity": "sha512-2JZD8z2JviJrboD9cPuX/Sv/1ChFng+xh2tChQ2X4bB2HeK+rra/bmJ3xGntCcjhOqIzSDG6Id7e8RJ9QPXLEQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "prosemirror-state": "^1.2.2", + "prosemirror-transform": "^1.0.0", + "prosemirror-view": "^1.31.0", + "rope-sequence": "^1.3.0" + } + }, + "node_modules/prosemirror-inputrules": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.5.0.tgz", + "integrity": "sha512-K0xJRCmt+uSw7xesnHmcn72yBGTbY45vm8gXI4LZXbx2Z0jwh5aF9xrGQgrVPu0WbyFVFF3E/o9VhJYz6SQWnA==", + "license": "MIT", + "peer": true, + "dependencies": { + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.0.0" + } + }, + "node_modules/prosemirror-keymap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.3.tgz", + "integrity": "sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==", + "license": "MIT", + "peer": true, + "dependencies": { + "prosemirror-state": "^1.0.0", + "w3c-keyname": "^2.2.0" + } + }, + "node_modules/prosemirror-markdown": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.13.2.tgz", + "integrity": "sha512-FPD9rHPdA9fqzNmIIDhhnYQ6WgNoSWX9StUZ8LEKapaXU9i6XgykaHKhp6XMyXlOWetmaFgGDS/nu/w9/vUc5g==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/markdown-it": "^14.0.0", + "markdown-it": "^14.0.0", + "prosemirror-model": "^1.25.0" + } + }, + "node_modules/prosemirror-menu": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.2.5.tgz", + "integrity": "sha512-qwXzynnpBIeg1D7BAtjOusR+81xCp53j7iWu/IargiRZqRjGIlQuu1f3jFi+ehrHhWMLoyOQTSRx/IWZJqOYtQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "crelt": "^1.0.0", + "prosemirror-commands": "^1.0.0", + "prosemirror-history": "^1.0.0", + "prosemirror-state": "^1.0.0" + } + }, + "node_modules/prosemirror-model": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.1.tgz", + "integrity": "sha512-AUvbm7qqmpZa5d9fPKMvH1Q5bqYQvAZWOGRvxsB6iFLyycvC9MwNemNVjHVrWgjaoxAfY8XVg7DbvQ/qxvI9Eg==", + "license": "MIT", + "peer": true, + "dependencies": { + "orderedmap": "^2.0.0" + } + }, + "node_modules/prosemirror-schema-basic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.4.tgz", + "integrity": "sha512-ELxP4TlX3yr2v5rM7Sb70SqStq5NvI15c0j9j/gjsrO5vaw+fnnpovCLEGIcpeGfifkuqJwl4fon6b+KdrODYQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "prosemirror-model": "^1.25.0" + } + }, + "node_modules/prosemirror-schema-list": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.5.1.tgz", + "integrity": "sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.7.3" + } + }, + "node_modules/prosemirror-state": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.3.tgz", + "integrity": "sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "prosemirror-model": "^1.0.0", + "prosemirror-transform": "^1.0.0", + "prosemirror-view": "^1.27.0" + } + }, + "node_modules/prosemirror-tables": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.7.1.tgz", + "integrity": "sha512-eRQ97Bf+i9Eby99QbyAiyov43iOKgWa7QCGly+lrDt7efZ1v8NWolhXiB43hSDGIXT1UXgbs4KJN3a06FGpr1Q==", + "license": "MIT", + "peer": true, + "dependencies": { + "prosemirror-keymap": "^1.2.2", + "prosemirror-model": "^1.25.0", + "prosemirror-state": "^1.4.3", + "prosemirror-transform": "^1.10.3", + "prosemirror-view": "^1.39.1" + } + }, + "node_modules/prosemirror-trailing-node": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/prosemirror-trailing-node/-/prosemirror-trailing-node-3.0.0.tgz", + "integrity": "sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@remirror/core-constants": "3.0.0", + "escape-string-regexp": "^4.0.0" + }, + "peerDependencies": { + "prosemirror-model": "^1.22.1", + "prosemirror-state": "^1.4.2", + "prosemirror-view": "^1.33.8" + } + }, + "node_modules/prosemirror-transform": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.10.4.tgz", + "integrity": "sha512-pwDy22nAnGqNR1feOQKHxoFkkUtepoFAd3r2hbEDsnf4wp57kKA36hXsB3njA9FtONBEwSDnDeCiJe+ItD+ykw==", + "license": "MIT", + "peer": true, + "dependencies": { + "prosemirror-model": "^1.21.0" + } + }, + "node_modules/prosemirror-view": { + "version": "1.39.3", + "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.39.3.tgz", + "integrity": "sha512-bY/7kg0LzRE7ytR0zRdSMWX3sknEjw68l836ffLPMh0OG3OYnNuBDUSF3v0vjvnzgYjgY9ZH/RypbARURlcMFA==", + "license": "MIT", + "peer": true, + "dependencies": { + "prosemirror-model": "^1.20.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.1.0" + } + }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/rope-sequence": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz", + "integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==", + "license": "MIT", + "peer": true + }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "license": "MIT", + "peer": true + }, + "node_modules/w3c-keyname": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", + "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", + "license": "MIT", + "peer": true + } + } +} diff --git a/package.json b/package.json index 24f0225..2cd1ec8 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,28 @@ { - "name": "@tp/tp-element", + "name": "@tp/tp-rich-text-box", "version": "0.0.1", "description": "", - "main": "tp-element.js", + "main": "tp-rich-text-box.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "repository": { "type": "git", - "url": "https://gitea.codeblob.work/tp-elements/tp-element.git" + "url": "https://gitea.codeblob.work/tp-elements/tp-rich-text-box.git" }, "author": "trading_peter", "license": "Apache-2.0", "dependencies": { + "@tiptap/core": "^2.12.0", + "@tiptap/extension-bold": "^2.12.0", + "@tiptap/extension-code": "^2.24.2", + "@tiptap/extension-document": "^2.24.2", + "@tiptap/extension-hard-break": "^2.24.2", + "@tiptap/extension-italic": "^2.0.0-beta.220", + "@tiptap/extension-paragraph": "^2.0.0-beta.220", + "@tiptap/extension-strike": "^2.0.0-beta.220", + "@tiptap/extension-text": "^2.0.0-beta.220", + "@tiptap/extension-underline": "^2.0.0-beta.220", "lit": "^3.0.0" } } diff --git a/tp-element.js b/tp-element.js deleted file mode 100644 index 6195006..0000000 --- a/tp-element.js +++ /dev/null @@ -1,35 +0,0 @@ -/** -@license -Copyright (c) 2024 trading_peter -This program is available under Apache License Version 2.0 -*/ - -import { LitElement, html, css } from 'lit'; - -class TpElement extends LitElement { - static get styles() { - return [ - css` - :host { - display: block; - } - ` - ]; - } - - render() { - const { } = this; - - return html` - - `; - } - - static get properties() { - return { }; - } - - -} - -window.customElements.define('tp-element', TpElement); diff --git a/tp-rich-text-box.js b/tp-rich-text-box.js new file mode 100644 index 0000000..ec9b03a --- /dev/null +++ b/tp-rich-text-box.js @@ -0,0 +1,227 @@ +/** +@license +Copyright (c) 2025 trading_peter +This program is available under Apache License Version 2.0 +*/ + +import { LitElement, html, css } from 'lit'; +import { Editor } from '@tiptap/core'; +import Document from '@tiptap/extension-document'; +import Paragraph from '@tiptap/extension-paragraph'; +import Text from '@tiptap/extension-text'; +import HardBreak from '@tiptap/extension-hard-break'; + +class TpRichTextBox extends LitElement { + static get styles() { + return [ + css` + :host { + display: flex; + flex-direction: column; + border: 1px solid #ccc; + min-height: 100px; + position: relative; + } + + #editor { + padding: 8px; + flex-grow: 1; + } + + .custom-floating-menu { + display: flex; + padding: 4px; + background-color: #fff; + border: 1px solid #ccc; + border-radius: 4px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + position: absolute; + top: 0; + left: 0; + z-index: 100; + } + + .custom-floating-menu[hidden] { + display: none; + } + ` + ]; + } + + constructor() { + super(); + this.extensions = []; + this._slotObserver = new MutationObserver(this._processSlotChanges.bind(this)); + } + + render() { + return html` + +
+ `; + } + + static get properties() { + return { + editor: { type: Object }, + extensions: { type: Array } + }; + } + + firstUpdated() { + // Get initial extensions from slot + this._processChildExtensions(); + + // Initialize the editor with collected extensions + this._initEditor(); + + // Observe future slot changes + this._slotObserver.observe(this, { + childList: true, + subtree: false + }); + } + + _initEditor() { + if (this.editor) { + this.editor.destroy(); + } + + this.editor = new Editor({ + element: this.shadowRoot.querySelector('#editor'), + extensions: this.extensions, + content: '

Hello World!

', + }); + + // Notify child extensions that the editor is ready + const children = Array.from(this.children); + children.forEach(child => { + if (child._editorReady && typeof child._editorReady === 'function') { + child._editorReady(this.editor); + } + }); + + this.editor.on('selectionUpdate', this._handleSelectionUpdate.bind(this)); + this.editor.on('blur', this._handleSelectionUpdate.bind(this)); + } + + _handleSelectionUpdate() { + const { editor } = this; + const menu = this.shadowRoot.querySelector('.custom-floating-menu'); + + if (!editor || !menu) { + console.log('Editor or menu element not found.'); + return; + } + + const { empty, from, to } = editor.state.selection; + + if (empty || from === to) { + menu.hidden = true; + console.log('Selection is empty or a caret. Hiding menu.'); + return; + } + + menu.hidden = false; + requestAnimationFrame(() => { + this._positionMenu(menu, editor); + console.log('Text selected. Showing menu.'); + }); + } + + _positionMenu(menuElement, editorInstance) { + const { view } = editorInstance; + const { selection } = editorInstance.state; + const { from, to } = selection; + + // Get the coordinates of the selection + const start = view.coordsAtPos(from); + const end = view.coordsAtPos(to); + + // Calculate the center of the selection + let left = (start.left + end.left) / 2; + console.log('Menu offsetHeight:', menuElement.offsetHeight); + let top = start.top - menuElement.offsetHeight - 10; // 10px above selection + + // If the calculated top is negative, position the menu below the selection + if (top < 0) { + top = end.bottom + 10; // 10px below selection + } + + // Adjust left position if it goes out of viewport on the right + const viewportWidth = window.innerWidth; + const menuWidth = menuElement.offsetWidth; + if (left + menuWidth > viewportWidth) { + left = viewportWidth - menuWidth - 10; // 10px padding from right edge + } + + // Ensure left is not negative + if (left < 0) { + left = 10; // 10px padding from left edge + } + + // Position the menu + menuElement.style.left = `${left}px`; + menuElement.style.top = `${top}px`; + console.log(`Menu positioned at: left=${left}px, top=${top}px`); + } + + _handleSlotChange(e) { + this._processChildExtensions(); + } + + _processSlotChanges(mutations) { + let needsUpdate = false; + + mutations.forEach(mutation => { + if (mutation.type === 'childList') { + needsUpdate = true; + } + }); + + if (needsUpdate) { + this._processChildExtensions(); + } + } + + _processChildExtensions() { + this.extensions = [ + Document, + Paragraph, + Text, + HardBreak + ]; + + // Get all extension components + const children = Array.from(this.children); + + children.forEach(child => { + // If the child has a getExtension method, it's an extension component + if (child.getExtension && typeof child.getExtension === 'function') { + const extension = child.getExtension(); + if (extension) { + this.extensions.push(extension); + } + } + }); + + // Re-initialize the editor with new extensions if it already exists + if (this.editor) { + this._initEditor(); + } + } + + disconnectedCallback() { + super.disconnectedCallback(); + if (this._slotObserver) { + this._slotObserver.disconnect(); + } + if (this.editor) { + this.editor.destroy(); + } + } +} + +window.customElements.define('tp-rich-text-box', TpRichTextBox); diff --git a/tp-rtb-base-extension.js b/tp-rtb-base-extension.js new file mode 100644 index 0000000..5ff9dd1 --- /dev/null +++ b/tp-rtb-base-extension.js @@ -0,0 +1,76 @@ +import { LitElement, html, css } from 'lit'; + +export class TpRtbBaseExtension extends LitElement { + static get styles() { + return css` + :host { + display: inline-block; + } + + button { + margin: 0 2px; + padding: 4px 8px; + background: none; + border: 1px solid #ccc; + border-radius: 3px; + cursor: pointer; + } + + button:hover { + background-color: #f0f0f0; + } + + button.active { + background-color: #e0e0e0; + } + `; + } + + static get properties() { + return { + label: { type: String }, + active: { type: Boolean, reflect: true } + }; + } + + constructor() { + super(); + this.label = ''; + this.active = false; + } + + render() { + return html` + + `; + } + + connectedCallback() { + super.connectedCallback(); + this._findParentEditor(); + } + + _findParentEditor() { + this.parentEditor = this.closest('tp-rich-text-box'); + } + + _editorReady(editorInstance) { + this.parentEditor.editor = editorInstance; + this._setupEditorListeners(); + } + + _setupEditorListeners() { + // To be implemented by child classes + } + + _handleClick() { + // To be implemented by child classes + } + + getExtension() { + // To be implemented by child classes + return null; + } +} \ No newline at end of file diff --git a/tp-rtb-bold.js b/tp-rtb-bold.js new file mode 100644 index 0000000..f995e25 --- /dev/null +++ b/tp-rtb-bold.js @@ -0,0 +1,34 @@ +import { TpRtbBaseExtension } from './tp-rtb-base-extension.js'; +import Bold from '@tiptap/extension-bold'; + +class TpRtbBold extends TpRtbBaseExtension { + constructor() { + super(); + this.label = 'Bold'; + } + + getExtension() { + return Bold; + } + + _handleClick() { + if (this.parentEditor && this.parentEditor.editor) { + this.parentEditor.editor.chain().focus().toggleBold().run(); + } + } + + _setupEditorListeners() { + const { editor } = this.parentEditor; + + // Update button state when selection changes + editor.on('selectionUpdate', () => { + this.active = editor.isActive('bold'); + }); + + editor.on('focus', () => { + this.active = editor.isActive('bold'); + }); + } +} + +customElements.define('tp-rtb-bold', TpRtbBold); \ No newline at end of file diff --git a/tp-rtb-clear-format.js b/tp-rtb-clear-format.js new file mode 100644 index 0000000..85f2073 --- /dev/null +++ b/tp-rtb-clear-format.js @@ -0,0 +1,16 @@ +import { TpRtbBaseExtension } from './tp-rtb-base-extension.js'; + +class TpRtbClearFormat extends TpRtbBaseExtension { + constructor() { + super(); + this.label = 'Clear Format'; + } + + _handleClick() { + if (this.parentEditor && this.parentEditor.editor) { + this.parentEditor.editor.chain().focus().unsetAllMarks().run(); + } + } +} + +customElements.define('tp-rtb-clear-format', TpRtbClearFormat); diff --git a/tp-rtb-code.js b/tp-rtb-code.js new file mode 100644 index 0000000..c61ddd8 --- /dev/null +++ b/tp-rtb-code.js @@ -0,0 +1,34 @@ +import { TpRtbBaseExtension } from './tp-rtb-base-extension.js'; +import Code from '@tiptap/extension-code'; + +class TpRtbCode extends TpRtbBaseExtension { + constructor() { + super(); + this.label = 'Code'; + } + + getExtension() { + return Code; + } + + _handleClick() { + if (this.parentEditor && this.parentEditor.editor) { + this.parentEditor.editor.chain().focus().toggleCode().run(); + } + } + + _setupEditorListeners() { + const { editor } = this.parentEditor; + + // Update button state when selection changes + editor.on('selectionUpdate', () => { + this.active = editor.isActive('code'); + }); + + editor.on('focus', () => { + this.active = editor.isActive('code'); + }); + } +} + +customElements.define('tp-rtb-code', TpRtbCode); diff --git a/tp-rtb-italic.js b/tp-rtb-italic.js new file mode 100644 index 0000000..e6646f4 --- /dev/null +++ b/tp-rtb-italic.js @@ -0,0 +1,34 @@ +import { TpRtbBaseExtension } from './tp-rtb-base-extension.js'; +import Italic from '@tiptap/extension-italic'; + +class TpRtbItalic extends TpRtbBaseExtension { + constructor() { + super(); + this.label = 'Italic'; + } + + getExtension() { + return Italic; + } + + _handleClick() { + if (this.parentEditor && this.parentEditor.editor) { + this.parentEditor.editor.chain().focus().toggleItalic().run(); + } + } + + _setupEditorListeners() { + const { editor } = this.parentEditor; + + // Update button state when selection changes + editor.on('selectionUpdate', () => { + this.active = editor.isActive('italic'); + }); + + editor.on('focus', () => { + this.active = editor.isActive('italic'); + }); + } +} + +customElements.define('tp-rtb-italic', TpRtbItalic); diff --git a/tp-rtb-strike.js b/tp-rtb-strike.js new file mode 100644 index 0000000..8e79b76 --- /dev/null +++ b/tp-rtb-strike.js @@ -0,0 +1,34 @@ +import { TpRtbBaseExtension } from './tp-rtb-base-extension.js'; +import Strike from '@tiptap/extension-strike'; + +class TpRtbStrike extends TpRtbBaseExtension { + constructor() { + super(); + this.label = 'Strike'; + } + + getExtension() { + return Strike; + } + + _handleClick() { + if (this.parentEditor && this.parentEditor.editor) { + this.parentEditor.editor.chain().focus().toggleStrike().run(); + } + } + + _setupEditorListeners() { + const { editor } = this.parentEditor; + + // Update button state when selection changes + editor.on('selectionUpdate', () => { + this.active = editor.isActive('strike'); + }); + + editor.on('focus', () => { + this.active = editor.isActive('strike'); + }); + } +} + +customElements.define('tp-rtb-strike', TpRtbStrike); diff --git a/tp-rtb-underline.js b/tp-rtb-underline.js new file mode 100644 index 0000000..003999a --- /dev/null +++ b/tp-rtb-underline.js @@ -0,0 +1,34 @@ +import { TpRtbBaseExtension } from './tp-rtb-base-extension.js'; +import Underline from '@tiptap/extension-underline'; + +class TpRtbUnderline extends TpRtbBaseExtension { + constructor() { + super(); + this.label = 'Underline'; + } + + getExtension() { + return Underline; + } + + _handleClick() { + if (this.parentEditor && this.parentEditor.editor) { + this.parentEditor.editor.chain().focus().toggleUnderline().run(); + } + } + + _setupEditorListeners() { + const { editor } = this.parentEditor; + + // Update button state when selection changes + editor.on('selectionUpdate', () => { + this.active = editor.isActive('underline'); + }); + + editor.on('focus', () => { + this.active = editor.isActive('underline'); + }); + } +} + +customElements.define('tp-rtb-underline', TpRtbUnderline);