@sbb-esta/lyne-elements-experimental-dev 5.0.0-next.3-dev.1779265358 → 5.0.0-next.3-dev.1779268564
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/styles/{theme.scss → _theme.scss} +1 -1
- package/core/styles/{core.scss → features/core.scss} +1 -1
- package/development/autocomplete-grid-option.component-D9pTXPlu.js +1 -1
- package/development/autocomplete-grid-row.component-CBHh50jC.js +1 -1
- package/development/journey-summary.component-De1ioDRq.js +1 -1
- package/development/pearl-chain-time.component-BxVQ1z-Z.js +1 -1
- package/development/pearl-chain-vertical-item.component-DJioJtxP.js +1 -1
- package/development/pearl-chain.component-EEAZ7Kol.js +1 -1
- package/development/seat-reservation/seat-reservation/seat-reservation.component.d.ts.map +1 -1
- package/development/seat-reservation/seat-reservation/seat-reservation.component.js +1 -1
- package/development/seat-reservation/seat-reservation-navigation-coach/seat-reservation-navigation-coach.component.d.ts.map +1 -1
- package/development/seat-reservation/seat-reservation-navigation-coach/seat-reservation-navigation-coach.component.js +1 -1
- package/development/seat-reservation-graphic.component-C2r57590.js +1 -1
- package/development/seat-reservation-navigation-coach.component-CMm-2Vuc.js +438 -0
- package/development/seat-reservation-place-control.component-Dfxv9B6C.js +1 -1
- package/development/seat-reservation.component-CR5QYNWZ.js +473 -0
- package/development/seat-reservation.js +2 -2
- package/development/seat-reservation.pure.js +2 -2
- package/development/timetable-duration.component-fBla8Kue.js +1 -1
- package/development/timetable-row/timetable-row.component.d.ts.map +1 -1
- package/development/timetable-row/timetable-row.component.js +1 -1
- package/development/timetable-row.component-CTShHdLn.js +736 -0
- package/development/timetable-row.js +1 -1
- package/development/timetable-row.pure.js +1 -1
- package/package.json +2 -6
- package/seat-reservation/seat-reservation/seat-reservation.component.js +1 -1
- package/seat-reservation/seat-reservation-navigation-coach/seat-reservation-navigation-coach.component.js +1 -1
- package/seat-reservation-navigation-coach.component-Cwxd9vLy.js +338 -0
- package/{seat-reservation.component-VhMc8Rqt.js → seat-reservation.component-TLuTP9Nm.js} +77 -76
- package/seat-reservation.js +2 -2
- package/seat-reservation.pure.js +2 -2
- package/timetable-row/timetable-row.component.js +1 -1
- package/{timetable-row.component-Din-TQ9u.js → timetable-row.component-DawXp2ut.js} +112 -108
- package/timetable-row.js +1 -1
- package/timetable-row.pure.js +1 -1
- package/core.css +0 -13
- package/development/seat-reservation-navigation-coach.component-9ySnZIKH.js +0 -434
- package/development/seat-reservation.component-BGvVv6rJ.js +0 -472
- package/development/timetable-row.component-DSTGtQAC.js +0 -732
- package/seat-reservation-navigation-coach.component-BkqPWUtu.js +0 -334
|
@@ -1,472 +0,0 @@
|
|
|
1
|
-
import { SeatReservationBaseElement } from "./seat-reservation/seat-reservation/seat-reservation-base-element.js";
|
|
2
|
-
import { SbbSecondaryButtonElement } from "@sbb-esta/lyne-elements/button.pure.js";
|
|
3
|
-
import { SbbLanguageController, screenReaderOnlyStyles, scrollbarStyles } from "@sbb-esta/lyne-elements/core.js";
|
|
4
|
-
import { html, isServer, nothing, unsafeCSS } from "lit";
|
|
5
|
-
import { styleMap } from "lit/directives/style-map.js";
|
|
6
|
-
import { classMap } from "lit/directives/class-map.js";
|
|
7
|
-
import { getI18nSeatReservation } from "./seat-reservation/common/translations.js";
|
|
8
|
-
import { SbbSeatReservationGraphicElement } from "./seat-reservation/seat-reservation-graphic/seat-reservation-graphic.component.js";
|
|
9
|
-
import { SbbPopoverElement } from "@sbb-esta/lyne-elements/popover.pure.js";
|
|
10
|
-
import { repeat } from "lit/directives/repeat.js";
|
|
11
|
-
import { SbbSeatReservationAreaElement } from "./seat-reservation/seat-reservation-area/seat-reservation-area.component.js";
|
|
12
|
-
import { SbbSeatReservationNavigationCoachElement } from "./seat-reservation/seat-reservation-navigation-coach/seat-reservation-navigation-coach.component.js";
|
|
13
|
-
import { SbbSeatReservationPlaceControlElement } from "./seat-reservation/seat-reservation-place-control/seat-reservation-place-control.component.js";
|
|
14
|
-
import { SbbSeatReservationScopedElement } from "./seat-reservation/seat-reservation-scoped/seat-reservation-scoped.component.js";
|
|
15
|
-
//#region src/elements-experimental/seat-reservation/seat-reservation/seat-reservation.scss?inline
|
|
16
|
-
var seat_reservation_default = ":host {\n --sbb-seat-reservation-grid-size: 16px;\n --sbb-seat-reservation-height: 0;\n --sbb-seat-reservation-decks: 1;\n display: block;\n height: inherit;\n}\n:host ::part(coach-floor) {\n fill: var(--sbb-background-color-2);\n}\n@media (forced-colors: active) {\n :host ::part(coach-floor) {\n fill: transparent;\n }\n}\n\n:host(:dir(rtl)) :not(.sbb-sr-place-ctrl--type-bicycle,\n.sbb-sr-place-ctrl--orientation-90,\n.sbb-sr-place-ctrl--orientation-270,\n.sbb-sr-place-ctrl--state-selected) ::part(coach-floor) {\n rotate: calc(180 * 1deg);\n}\n\n[popover]:where(sbb-popover) {\n margin: 0;\n padding: 0;\n border: none;\n width: auto;\n height: auto;\n background-color: transparent;\n color: inherit;\n pointer-events: none;\n}\n[popover]:where(sbb-popover) .sbb-sr-popover {\n margin-block: calc(4 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));\n}\n\n:host([align-vertical]) .sbb-sr__component {\n flex-direction: row-reverse;\n justify-content: flex-end;\n gap: calc(22 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));\n height: inherit;\n}\n@media (min-width: calc(37.5rem)) {\n :host([align-vertical]) .sbb-sr__component {\n gap: calc(54 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));\n }\n}\n:host([align-vertical]) .sbb-sr__component nav.sbb-sr-navigation,\n:host([align-vertical]) .sbb-sr__component ul.sbb-sr-navigation__list-coaches {\n flex-direction: column;\n}\n:host([align-vertical]) .sbb-sr__component nav.sbb-sr-navigation {\n padding: calc(16 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem)) 0;\n}\n:host([align-vertical]) .sbb-sr__component nav.sbb-sr-navigation .sbb-sr__navigation-control-button {\n left: calc(1 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));\n top: 0;\n rotate: 90deg;\n}\n@media (min-width: calc(64rem)) {\n :host([align-vertical]) .sbb-sr__component nav.sbb-sr-navigation .sbb-sr__navigation-control-button {\n left: calc(-1 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));\n }\n}\n:host([align-vertical]) .sbb-sr__component nav.sbb-sr-navigation ul.sbb-sr-navigation__list-coaches {\n max-width: initial;\n padding: calc(5 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));\n overflow: hidden scroll;\n}\n:host([align-vertical]) .sbb-sr__component nav.sbb-sr-navigation ul.sbb-sr-navigation__list-coaches li {\n display: flex;\n}\n:host([align-vertical]) .sbb-sr__wrapper-coach-decks {\n flex-direction: column;\n}\n:host([align-vertical]) .sbb-sr__wrapper-coach-decks .sbb-sr__wrapper-deck-labels {\n flex-direction: column-reverse;\n width: calc((var(--sbb-seat-reservation-height) + 24) * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));\n height: initial;\n}\n:host([align-vertical]) .sbb-sr__wrapper-coach-decks .sbb-sr__wrapper-deck-labels b {\n inline-size: calc(50% - 16 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));\n block-size: calc(20 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));\n margin-bottom: calc(16 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));\n rotate: initial;\n writing-mode: initial;\n}\n:host([align-vertical]) .sbb-sr__wrapper-scrollarea {\n width: calc((var(--sbb-seat-reservation-height) + 24) * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));\n height: 100%;\n overflow: hidden scroll;\n}\n:host([align-vertical]) .sbb-sr__wrapper-scrollarea .sbb-sr__parent {\n rotate: 90deg;\n}\n:host([align-vertical]) .sbb-sr-travel-direction-wrapper {\n width: calc(var(--sbb-seat-reservation-height) * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));\n margin-block-start: calc(4 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));\n}\n\n.sbb-sr-navigation {\n gap: calc(3 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));\n}\n\n.sbb-sr-navigation .sbb-sr__navigation-control-button {\n position: relative;\n top: calc(2 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));\n}\n@media (min-width: calc(64rem)) {\n .sbb-sr-navigation .sbb-sr__navigation-control-button {\n top: 0;\n }\n}\n\n.sbb-sr__component {\n display: flex;\n flex-direction: column;\n gap: calc(64 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem) - 16px);\n}\n\n.sbb-sr-travel-direction-wrapper {\n display: flex;\n justify-content: center;\n align-items: center;\n column-gap: calc(4 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));\n margin-block: calc(8 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem)) calc(4 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));\n font-size: var(--sbb-text-font-size-s);\n}\n.sbb-sr-travel-direction-wrapper .sbb-sr__travel-direction--arrow {\n display: flex;\n align-items: center;\n}\n\n.sbb-sr-navigation-wrapper {\n display: flex;\n}\n\n.sbb-sr-navigation {\n display: flex;\n justify-content: center;\n width: 100%;\n padding-inline: 16px;\n}\n\n.sbb-sr-navigation__list-coaches {\n list-style: none;\n margin: 0;\n padding: 0;\n font-size: inherit;\n display: flex;\n flex-wrap: nowrap;\n gap: calc(4 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));\n padding: calc(6 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem)) calc(5 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem)) 0;\n max-width: 856px;\n --sbb-scrollbar-color: transparent;\n overflow: scroll hidden;\n position: relative;\n}\n\n.sbb-sr__wrapper-coach-decks {\n display: flex;\n overflow: hidden;\n height: inherit;\n}\n.sbb-sr__wrapper-coach-decks .sbb-sr__wrapper-deck-labels {\n display: flex;\n justify-content: space-between;\n height: calc(var(--sbb-seat-reservation-height) * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));\n writing-mode: vertical-lr;\n}\n.sbb-sr__wrapper-coach-decks .sbb-sr__wrapper-deck-labels b {\n height: calc(50% - 16 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));\n width: calc(20 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));\n margin-block-end: 16px;\n rotate: 180deg;\n text-align: center;\n line-height: calc(20 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));\n}\n\n.sbb-sr__wrapper-scrollarea {\n overflow: scroll hidden;\n padding-block: calc(8 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem)) calc(16 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));\n}\n.sbb-sr__wrapper-scrollarea .sbb-sr__parent {\n display: flex;\n flex-direction: column;\n position: relative;\n}\n\n.sbb-sr__list-decks {\n list-style: none;\n margin: 0;\n padding: 0;\n font-size: inherit;\n display: flex;\n flex-direction: column;\n}\n\n.sbb-sr__list-decks--gap {\n gap: calc(48 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));\n}\n\n.sbb-sr__list-item-deck {\n position: relative;\n}\n\n.sbb-sr__list-coaches {\n list-style: none;\n margin: 0;\n padding: 0;\n font-size: inherit;\n display: flex;\n gap: calc(4 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));\n}\n\n.sbb-sr__list-decks:has(.sbb-sr-coach-has-overhanging-elements) .sbb-sr__list-coaches {\n gap: calc(8 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));\n}\n\n.sbb-sr__item-coach {\n position: relative;\n}\n\n.sbb-sr-coach-wrapper__table {\n outline: 0;\n}";
|
|
17
|
-
//#endregion
|
|
18
|
-
//#region src/elements-experimental/seat-reservation/seat-reservation/seat-reservation.component.ts
|
|
19
|
-
/**
|
|
20
|
-
* Main component for the seat reservation.
|
|
21
|
-
*
|
|
22
|
-
*/
|
|
23
|
-
var SbbSeatReservationElement = class extends SeatReservationBaseElement {
|
|
24
|
-
constructor() {
|
|
25
|
-
super(...arguments);
|
|
26
|
-
this._language = new SbbLanguageController(this);
|
|
27
|
-
}
|
|
28
|
-
static {
|
|
29
|
-
this.elementName = "sbb-seat-reservation";
|
|
30
|
-
}
|
|
31
|
-
static {
|
|
32
|
-
this.elementDependencies = [
|
|
33
|
-
SbbSecondaryButtonElement,
|
|
34
|
-
SbbPopoverElement,
|
|
35
|
-
SbbSeatReservationAreaElement,
|
|
36
|
-
SbbSeatReservationGraphicElement,
|
|
37
|
-
SbbSeatReservationPlaceControlElement,
|
|
38
|
-
SbbSeatReservationNavigationCoachElement,
|
|
39
|
-
SbbSeatReservationScopedElement
|
|
40
|
-
];
|
|
41
|
-
}
|
|
42
|
-
static {
|
|
43
|
-
this.styles = [
|
|
44
|
-
scrollbarStyles,
|
|
45
|
-
screenReaderOnlyStyles,
|
|
46
|
-
unsafeCSS(seat_reservation_default)
|
|
47
|
-
];
|
|
48
|
-
}
|
|
49
|
-
willUpdate(changedProperties) {
|
|
50
|
-
super.willUpdate(changedProperties);
|
|
51
|
-
if (changedProperties.has("hasNavigation")) if (this.hasNavigation) this.shadowRoot?.querySelectorAll("table").forEach((table) => table.removeAttribute("tabindex"));
|
|
52
|
-
else this.shadowRoot?.querySelectorAll("table").forEach((table) => table.setAttribute("tabindex", "0"));
|
|
53
|
-
}
|
|
54
|
-
firstUpdated(changedProperties) {
|
|
55
|
-
super.firstUpdated(changedProperties);
|
|
56
|
-
this.updateComplete.then(() => {
|
|
57
|
-
this.initNavigationSelectionByScrollEvent();
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
render() {
|
|
61
|
-
this._initVehicleSeatReservationConstruction();
|
|
62
|
-
return this._coachesHtmlTemplate || null;
|
|
63
|
-
}
|
|
64
|
-
_initVehicleSeatReservationConstruction() {
|
|
65
|
-
this._coachesHtmlTemplate = html`
|
|
66
|
-
${this._renderTravelDirection()}
|
|
67
|
-
<div class="sbb-sr__component">
|
|
68
|
-
${this._renderNavigation()}
|
|
69
|
-
<div
|
|
70
|
-
class="sbb-sr__wrapper-coach-decks"
|
|
71
|
-
@keydown=${(evt) => this.keyboardSeatmapEventHandling(evt)}
|
|
72
|
-
>
|
|
73
|
-
<div class="sbb-sr__wrapper-deck-labels">${this._renderDeckLabels()}</div>
|
|
74
|
-
<div
|
|
75
|
-
@scroll=${() => this.coachAreaScrollend()}
|
|
76
|
-
id="sbb-sr__wrapper-scrollarea"
|
|
77
|
-
class="sbb-sr__wrapper-scrollarea sbb-scrollbar"
|
|
78
|
-
tabindex="-1"
|
|
79
|
-
>
|
|
80
|
-
<div id="sbb-sr__parent-area" class="sbb-sr__parent">
|
|
81
|
-
<ul
|
|
82
|
-
class="${classMap({
|
|
83
|
-
"sbb-sr__list-decks": true,
|
|
84
|
-
"sbb-sr__list-decks--gap": this.hasMultipleDecks
|
|
85
|
-
})}"
|
|
86
|
-
>
|
|
87
|
-
${this.seatReservations?.map((seatReservation, coachDeckIndex) => {
|
|
88
|
-
return html`<li class="sbb-sr__list-item-deck">
|
|
89
|
-
<ul class="sbb-sr__list-coaches" role="presentation">
|
|
90
|
-
${this._renderCoaches(seatReservation, coachDeckIndex)}
|
|
91
|
-
</ul>
|
|
92
|
-
</li>`;
|
|
93
|
-
})}
|
|
94
|
-
</ul>
|
|
95
|
-
</div>
|
|
96
|
-
</div>
|
|
97
|
-
</div>
|
|
98
|
-
</div>
|
|
99
|
-
`;
|
|
100
|
-
}
|
|
101
|
-
_renderDeckLabels() {
|
|
102
|
-
if (!this.hasMultipleDecks) return null;
|
|
103
|
-
return this.seatReservations.map((seatReservation) => {
|
|
104
|
-
return html`<b aria-hidden="true">${getI18nSeatReservation(seatReservation.deckCoachLevel, this._language.current)}</b>`;
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
_renderNavigationControlButton(btnDirection) {
|
|
108
|
-
if (!this.hasNavigation || !this.seatReservations) return null;
|
|
109
|
-
const btnNavigationDirectionId = btnDirection == "DIRECTION_RIGHT" ? "sbb-sr-navigation__wrapper-button-direction--right" : "sbb-sr-navigation__wrapper-button-direction--left";
|
|
110
|
-
const btnIcon = btnDirection == "DIRECTION_RIGHT" ? "chevron-small-right-small" : "chevron-small-left-small";
|
|
111
|
-
const btnAriaDescription = btnDirection == "DIRECTION_RIGHT" ? getI18nSeatReservation("SEAT_RESERVATION_END", this._language.current) : getI18nSeatReservation("SEAT_RESERVATION_BEGIN", this._language.current);
|
|
112
|
-
let btnDisabled = true;
|
|
113
|
-
if (btnDirection == "DIRECTION_LEFT" && this.selectedCoachIndex > 0) btnDisabled = false;
|
|
114
|
-
else if (btnDirection == "DIRECTION_RIGHT" && this.selectedCoachIndex < this.coachItemDetailsElements.length - 1) btnDisabled = false;
|
|
115
|
-
return html`<div class="sbb-sr-navigation__wrapper-button-direction">
|
|
116
|
-
<sbb-secondary-button
|
|
117
|
-
@click="${() => this.navigateByDirectionBtn(btnDirection)}"
|
|
118
|
-
@focus="${() => this.onFocusNavDirectionButton()}"
|
|
119
|
-
id="${btnNavigationDirectionId}"
|
|
120
|
-
class="sbb-sr__navigation-control-button"
|
|
121
|
-
size="m"
|
|
122
|
-
icon-name="${btnIcon}"
|
|
123
|
-
type="button"
|
|
124
|
-
aria-label="${btnAriaDescription}"
|
|
125
|
-
role="button"
|
|
126
|
-
.disabledInteractive="${btnDisabled || nothing}"
|
|
127
|
-
.disabled="${btnDisabled || nothing}"
|
|
128
|
-
></sbb-secondary-button>
|
|
129
|
-
</div>`;
|
|
130
|
-
}
|
|
131
|
-
_renderTravelDirection() {
|
|
132
|
-
if (!this.travelDirection || this.travelDirection === "NONE") return null;
|
|
133
|
-
const labelText = getI18nSeatReservation("SEAT_RESERVATION_TRAVEL_DIRECTION", this._language.current);
|
|
134
|
-
return html`<div class="sbb-sr-travel-direction-wrapper">
|
|
135
|
-
<div class="sbb-sr__travel-direction--arrow">
|
|
136
|
-
<sbb-icon slot="icon" name="${`arrow-${this.alignVertical ? this.travelDirection === "RIGHT" ? "down" : "up" : this.travelDirection === "RIGHT" ? "right" : "left"}-small`}"></sbb-icon>
|
|
137
|
-
</div>
|
|
138
|
-
<div class="sbb-sr__travel-direction--label">${labelText}</div>
|
|
139
|
-
</div>`;
|
|
140
|
-
}
|
|
141
|
-
_renderNavigation() {
|
|
142
|
-
if (isServer || !this.hasNavigation || !this.seatReservations) return null;
|
|
143
|
-
return html`<div class="sbb-sr-navigation-wrapper">
|
|
144
|
-
<nav id="sbb-sr-navigation" class="sbb-sr-navigation">
|
|
145
|
-
${this._renderNavigationControlButton("DIRECTION_LEFT")}
|
|
146
|
-
<ul
|
|
147
|
-
id="sbb-sr__navigation-list-coaches"
|
|
148
|
-
class="sbb-sr-navigation__list-coaches sbb-scrollbar"
|
|
149
|
-
aria-label="${getI18nSeatReservation("SEAT_RESERVATION_NAVIGATION", this._language.current)}"
|
|
150
|
-
>
|
|
151
|
-
${this.coachItemDetailsElements.map((coachItemDetails, index) => {
|
|
152
|
-
return html`<li>
|
|
153
|
-
<sbb-seat-reservation-navigation-coach
|
|
154
|
-
@selectcoach=${(event) => this._onSelectNavCoach(event)}
|
|
155
|
-
@focuscoach=${() => this._onFocusNavCoach()}
|
|
156
|
-
@keyup=${(evt) => this.onKeyNavigationNavCoachButton(evt, index)}
|
|
157
|
-
index="${index}"
|
|
158
|
-
.selected=${this.selectedCoachIndex === index}
|
|
159
|
-
.focused=${this.focusedCoachIndex === index}
|
|
160
|
-
.hovered=${this.hoveredCoachIndex === index}
|
|
161
|
-
.nativeFocusActive=${this.hasSeatReservationNativeFocus}
|
|
162
|
-
.coachItemDetails="${coachItemDetails}"
|
|
163
|
-
?vertical="${this.alignVertical}"
|
|
164
|
-
?showTitleInfo="${this.showTitleInfo}"
|
|
165
|
-
>
|
|
166
|
-
</sbb-seat-reservation-navigation-coach>
|
|
167
|
-
</li>`;
|
|
168
|
-
})}
|
|
169
|
-
</ul>
|
|
170
|
-
${this._renderNavigationControlButton("DIRECTION_RIGHT")}
|
|
171
|
-
</nav>
|
|
172
|
-
</div>`;
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
*
|
|
176
|
-
* @returns
|
|
177
|
-
* @param seatReservation
|
|
178
|
-
* @param coachDeckIndex
|
|
179
|
-
*/
|
|
180
|
-
_renderCoaches(seatReservation, coachDeckIndex) {
|
|
181
|
-
const coaches = JSON.parse(JSON.stringify(seatReservation?.coachItems));
|
|
182
|
-
if (!coaches || isServer) return null;
|
|
183
|
-
return coaches.map((coachItem, coachIndex) => {
|
|
184
|
-
return html`
|
|
185
|
-
<li class="sbb-sr__item-coach">
|
|
186
|
-
${this._renderCoachElement(coachItem, coachIndex, coachDeckIndex, seatReservation.deckCoachIndex)}
|
|
187
|
-
</li>
|
|
188
|
-
`;
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
_renderCoachElement(coachItem, coachIndex, coachDeckIndex, placeCoachDeckIndex) {
|
|
192
|
-
const currCoachStructure = this.seatReservationStructure.decks[coachDeckIndex].deckCoaches[coachIndex];
|
|
193
|
-
const descriptionTableCoachWithServices = this._getDescriptionTableCoach(coachItem);
|
|
194
|
-
return html`<sbb-seat-reservation-scoped
|
|
195
|
-
style=${styleMap({
|
|
196
|
-
"--sbb-seat-reservation-scoped-width": currCoachStructure.width,
|
|
197
|
-
"--sbb-seat-reservation-scoped-height": currCoachStructure.height
|
|
198
|
-
})}
|
|
199
|
-
>
|
|
200
|
-
${this._getRenderedCoachBorders(coachItem, coachDeckIndex, coachIndex)}
|
|
201
|
-
${this._getRenderedCoachElements(coachDeckIndex, coachIndex)}
|
|
202
|
-
${this._getRenderedAreaElements(coachDeckIndex, coachIndex)}
|
|
203
|
-
${this._getRenderedServiceElements(coachDeckIndex, coachIndex)}
|
|
204
|
-
|
|
205
|
-
<table
|
|
206
|
-
@focus=${() => this.onFocusTableCoachAndPreselectPlace(coachIndex)}
|
|
207
|
-
id="sbb-sr-coach-${coachIndex}"
|
|
208
|
-
class="sbb-sr-coach-wrapper__table"
|
|
209
|
-
aria-describedby="sbb-sr-coach-caption-${coachIndex}"
|
|
210
|
-
tabindex="-1"
|
|
211
|
-
>
|
|
212
|
-
<caption id="sbb-sr-coach-caption-${coachIndex}" tabindex="-1">
|
|
213
|
-
<span class="sbb-screen-reader-only">${descriptionTableCoachWithServices}</span>
|
|
214
|
-
</caption>
|
|
215
|
-
${this._getRenderedRowPlaces(coachItem, coachIndex, coachDeckIndex, placeCoachDeckIndex)}
|
|
216
|
-
</table>
|
|
217
|
-
</sbb-seat-reservation-scoped>`;
|
|
218
|
-
}
|
|
219
|
-
/**
|
|
220
|
-
* @returns Returns the border graphic (COACH_BORDER_MIDDLE) of a coach with calculated border gap and coach width,
|
|
221
|
-
* depending on whether the coach is with a driver area or without.
|
|
222
|
-
*/
|
|
223
|
-
_getRenderedCoachBorders(coachItem, deckCoachIndex, coachIndex) {
|
|
224
|
-
if (!coachItem.graphicElements) return null;
|
|
225
|
-
const currCoachStructure = this.seatReservationStructure.decks[deckCoachIndex].deckCoaches[coachIndex];
|
|
226
|
-
const coachBorderElement = currCoachStructure.borderMiddleElement;
|
|
227
|
-
const hasOverhangingElements = currCoachStructure.hasOverhangingElements;
|
|
228
|
-
return html`
|
|
229
|
-
<sbb-seat-reservation-graphic
|
|
230
|
-
class="${classMap({ "sbb-sr-coach-has-overhanging-elements": hasOverhangingElements || false })}"
|
|
231
|
-
style=${styleMap({
|
|
232
|
-
"--sbb-seat-reservation-graphic-width": coachBorderElement.dimension.w,
|
|
233
|
-
"--sbb-seat-reservation-graphic-height": coachBorderElement.dimension.h,
|
|
234
|
-
"--sbb-seat-reservation-graphic-top": coachBorderElement.position.y,
|
|
235
|
-
"--sbb-seat-reservation-graphic-left": coachBorderElement.position.x,
|
|
236
|
-
"--sbb-seat-reservation-graphic-position": "absolute"
|
|
237
|
-
})}
|
|
238
|
-
name="COACH_BORDER_MIDDLE"
|
|
239
|
-
?stretch=${true}
|
|
240
|
-
role="presentation"
|
|
241
|
-
></sbb-seat-reservation-graphic>
|
|
242
|
-
`;
|
|
243
|
-
}
|
|
244
|
-
_getRenderedRowPlaces(coach, coachIndex, coachDeckIndex, placeCoachDeckIndex) {
|
|
245
|
-
if (!coach.places) return null;
|
|
246
|
-
const tableRowPlaces = {};
|
|
247
|
-
for (const place of coach.places) if (!tableRowPlaces[place.position.y]) tableRowPlaces[place.position.y] = [place];
|
|
248
|
-
else tableRowPlaces[place.position.y].push(place);
|
|
249
|
-
return Object.values(tableRowPlaces).map((rowPlaces, index) => {
|
|
250
|
-
return html`
|
|
251
|
-
<tr id="row-${coachIndex}-${rowPlaces[0].position.y}" data-row-index=${index}>
|
|
252
|
-
${this._getRenderedColumnPlaces(rowPlaces, coachIndex, coachDeckIndex, placeCoachDeckIndex)}
|
|
253
|
-
</tr>
|
|
254
|
-
`;
|
|
255
|
-
}).flatMap((rowTemplate) => rowTemplate);
|
|
256
|
-
}
|
|
257
|
-
_getRenderedColumnPlaces(places, coachIndex, deckIndex, placeCoachDeckIndex) {
|
|
258
|
-
places.sort((placeA, placeB) => Number(placeA.position.x) - Number(placeB.position.x));
|
|
259
|
-
const trackPlaceId = coachIndex + "-" + placeCoachDeckIndex;
|
|
260
|
-
return html`${repeat(places, (place) => trackPlaceId + "-" + place.number, (place, index) => {
|
|
261
|
-
const calculatedDimension = this.getCalculatedDimension(place.dimension);
|
|
262
|
-
const calculatedPosition = this.getCalculatedPosition(place.position);
|
|
263
|
-
const rotation = place.rotation || 0;
|
|
264
|
-
const textRotation = this.alignVertical ? -90 : 0;
|
|
265
|
-
const placeId = this.getPlaceElementId(deckIndex, coachIndex, place.number);
|
|
266
|
-
return html`
|
|
267
|
-
<td
|
|
268
|
-
id="cell-${deckIndex}-${coachIndex}-${place.position.y}-${index}"
|
|
269
|
-
class="graphical-element"
|
|
270
|
-
>
|
|
271
|
-
<sbb-seat-reservation-place-control
|
|
272
|
-
style=${styleMap({
|
|
273
|
-
"--sbb-seat-reservation-place-control-text-scale-value": Math.min(calculatedDimension.w, calculatedDimension.h),
|
|
274
|
-
"--sbb-seat-reservation-place-control-width": calculatedDimension.w,
|
|
275
|
-
"--sbb-seat-reservation-place-control-height": calculatedDimension.h,
|
|
276
|
-
"--sbb-seat-reservation-place-control-top": calculatedPosition.y,
|
|
277
|
-
"--sbb-seat-reservation-place-control-left": calculatedPosition.x,
|
|
278
|
-
"--sbb-seat-reservation-place-control-rotation": rotation,
|
|
279
|
-
"--sbb-seat-reservation-place-control-text-rotation": textRotation
|
|
280
|
-
})}
|
|
281
|
-
@selectplace=${(selectPlaceEvent) => this._onSelectPlace(selectPlaceEvent)}
|
|
282
|
-
exportparts="sbb-sr-place-part"
|
|
283
|
-
id=${placeId}
|
|
284
|
-
class="seat-reservation-place-control"
|
|
285
|
-
text=${place.number}
|
|
286
|
-
type=${place.type}
|
|
287
|
-
state=${place.state}
|
|
288
|
-
travel-direction=${this.travelDirection}
|
|
289
|
-
coach-index=${coachIndex}
|
|
290
|
-
deck-index=${placeCoachDeckIndex}
|
|
291
|
-
data-deck-index=${deckIndex}
|
|
292
|
-
.propertyIds=${place.propertyIds}
|
|
293
|
-
.preventClick=${this.preventPlaceClick}
|
|
294
|
-
?showTitleInfo="${this.showTitleInfo}"
|
|
295
|
-
></sbb-seat-reservation-place-control>
|
|
296
|
-
</td>
|
|
297
|
-
`;
|
|
298
|
-
})}`;
|
|
299
|
-
}
|
|
300
|
-
_getRenderedCoachElements(coachDeckIndex, coachIndex) {
|
|
301
|
-
return this.seatReservationStructure.decks[coachDeckIndex].deckCoaches[coachIndex].otherElements.map((graphicElement) => {
|
|
302
|
-
return html` <sbb-seat-reservation-graphic
|
|
303
|
-
style=${styleMap({
|
|
304
|
-
"--sbb-seat-reservation-graphic-width": graphicElement.dimension.w,
|
|
305
|
-
"--sbb-seat-reservation-graphic-height": graphicElement.dimension.h,
|
|
306
|
-
"--sbb-seat-reservation-graphic-top": graphicElement.position.y,
|
|
307
|
-
"--sbb-seat-reservation-graphic-left": graphicElement.position.x,
|
|
308
|
-
"--sbb-seat-reservation-graphic-position": "absolute",
|
|
309
|
-
"--sbb-seat-reservation-graphic-rotation": graphicElement.rotation
|
|
310
|
-
})}
|
|
311
|
-
name=${graphicElement.icon ?? nothing}
|
|
312
|
-
aria-hidden="true"
|
|
313
|
-
?stretch=${true}
|
|
314
|
-
></sbb-seat-reservation-graphic>`;
|
|
315
|
-
});
|
|
316
|
-
}
|
|
317
|
-
_getRenderedAreaElements(coachDeckIndex, coachIndex) {
|
|
318
|
-
return this.seatReservationStructure.decks[coachDeckIndex].deckCoaches[coachIndex].areaElements.map((graphicElement) => {
|
|
319
|
-
const triggerId = `popover-trigger-${coachDeckIndex}-${coachIndex}-${graphicElement.position.x}-${graphicElement.position.y}`;
|
|
320
|
-
const isNotTableGraphic = graphicElement.icon?.indexOf("TABLE") === -1;
|
|
321
|
-
const areaProperty = graphicElement.icon && isNotTableGraphic ? graphicElement.icon : null;
|
|
322
|
-
const ariaLabelForArea = graphicElement.icon ? getI18nSeatReservation(graphicElement.icon, this._language.current) : nothing;
|
|
323
|
-
return html`
|
|
324
|
-
<sbb-seat-reservation-area
|
|
325
|
-
id="${triggerId}"
|
|
326
|
-
class="${classMap({ "sbb-seat-reservation-area--cursor-pointer": areaProperty !== null })}"
|
|
327
|
-
style=${styleMap({
|
|
328
|
-
"--sbb-seat-reservation-area-width": graphicElement.dimension.w,
|
|
329
|
-
"--sbb-seat-reservation-area-height": graphicElement.dimension.h,
|
|
330
|
-
"--sbb-seat-reservation-area-top": graphicElement.position.y,
|
|
331
|
-
"--sbb-seat-reservation-area-left": graphicElement.position.x,
|
|
332
|
-
"--sbb-seat-reservation-area-z-index": graphicElement.position.z
|
|
333
|
-
})}
|
|
334
|
-
mounting=${graphicElement.mounting ?? nothing}
|
|
335
|
-
background="dark"
|
|
336
|
-
aria-hidden="true"
|
|
337
|
-
>
|
|
338
|
-
${areaProperty ? html`
|
|
339
|
-
<sbb-seat-reservation-graphic
|
|
340
|
-
style=${styleMap({
|
|
341
|
-
"--sbb-seat-reservation-graphic-max-width": this.globalAreaIconDim.w,
|
|
342
|
-
"--sbb-seat-reservation-graphic-max-height": this.globalAreaIconDim.h,
|
|
343
|
-
"--sbb-seat-reservation-graphic-width": graphicElement.dimension.w,
|
|
344
|
-
"--sbb-seat-reservation-graphic-height": graphicElement.dimension.h,
|
|
345
|
-
"--sbb-seat-reservation-graphic-rotation": graphicElement.rotation,
|
|
346
|
-
"--sbb-seat-reservation-graphic-padding-percent": areaProperty !== "ENTRY_EXIT" ? this.globalAreaIconPadding : 1
|
|
347
|
-
})}
|
|
348
|
-
name=${areaProperty}
|
|
349
|
-
role="img"
|
|
350
|
-
aria-hidden="true"
|
|
351
|
-
class="sbb-sr-graphic__dimension--square-dim"
|
|
352
|
-
></sbb-seat-reservation-graphic>
|
|
353
|
-
` : nothing}
|
|
354
|
-
</sbb-seat-reservation-area>
|
|
355
|
-
${areaProperty ? this._popover(triggerId, ariaLabelForArea) : nothing}
|
|
356
|
-
`;
|
|
357
|
-
});
|
|
358
|
-
}
|
|
359
|
-
_getRenderedServiceElements(coachDeckIndex, coachIndex) {
|
|
360
|
-
return this.seatReservationStructure.decks[coachDeckIndex].deckCoaches[coachIndex].serviceElements.map((serviceElement) => {
|
|
361
|
-
const triggerId = `popover-trigger-${coachDeckIndex}-${coachIndex}-${serviceElement.position.x}-${serviceElement.position.y}`;
|
|
362
|
-
const titleDescription = serviceElement.icon ? getI18nSeatReservation(serviceElement.icon, this._language.current) : null;
|
|
363
|
-
return html`
|
|
364
|
-
<sbb-seat-reservation-graphic
|
|
365
|
-
id="${triggerId}"
|
|
366
|
-
style=${styleMap({
|
|
367
|
-
"--sbb-seat-reservation-graphic-width": serviceElement.dimension.w,
|
|
368
|
-
"--sbb-seat-reservation-graphic-height": serviceElement.dimension.h,
|
|
369
|
-
"--sbb-seat-reservation-graphic-top": serviceElement.position.y,
|
|
370
|
-
"--sbb-seat-reservation-graphic-left": serviceElement.position.x,
|
|
371
|
-
"--sbb-seat-reservation-graphic-position": "absolute",
|
|
372
|
-
"--sbb-seat-reservation-graphic-rotation": serviceElement.rotation
|
|
373
|
-
})}
|
|
374
|
-
class="sbb-seat-reservation-graphic--cursor-pointer"
|
|
375
|
-
name=${serviceElement.icon ?? nothing}
|
|
376
|
-
role="img"
|
|
377
|
-
aria-hidden="true"
|
|
378
|
-
></sbb-seat-reservation-graphic>
|
|
379
|
-
${this._popover(triggerId, titleDescription)}
|
|
380
|
-
`;
|
|
381
|
-
});
|
|
382
|
-
}
|
|
383
|
-
/**
|
|
384
|
-
* Manages the selected place event triggered from the place
|
|
385
|
-
* Each selection emits an array of all selected places
|
|
386
|
-
* @param selectPlaceEvent
|
|
387
|
-
*/
|
|
388
|
-
_onSelectPlace(selectPlaceEvent) {
|
|
389
|
-
const selectedPlace = selectPlaceEvent.detail;
|
|
390
|
-
this.preventCoachScrollByPlaceClick = true;
|
|
391
|
-
this.isCoachGridFocusable = false;
|
|
392
|
-
this.focusedCoachIndex = -1;
|
|
393
|
-
if (!this.hasSeatReservationNativeFocus) this.hasSeatReservationNativeFocus = true;
|
|
394
|
-
if (!this.preventPlaceClick) {
|
|
395
|
-
this.updateSelectedSeatReservationPlaces(selectedPlace);
|
|
396
|
-
this.updateCurrentSelectedPlaceInCoach(selectedPlace);
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
_onSelectNavCoach(event) {
|
|
400
|
-
const selectedNavCoachIndex = event.coachIndex;
|
|
401
|
-
this.isKeyboardNavigation = false;
|
|
402
|
-
this.preventCoachScrollByPlaceClick = false;
|
|
403
|
-
this.hasSeatReservationNativeFocus = true;
|
|
404
|
-
if (selectedNavCoachIndex !== null && selectedNavCoachIndex !== this.currSelectedCoachIndex) {
|
|
405
|
-
this.unfocusPlaceElement();
|
|
406
|
-
this.scrollToSelectedNavCoach(selectedNavCoachIndex);
|
|
407
|
-
} else if (selectedNavCoachIndex === this.currSelectedCoachIndex) {
|
|
408
|
-
this.updateCurrentSelectedCoach();
|
|
409
|
-
this.preselectPlaceInCoach();
|
|
410
|
-
}
|
|
411
|
-
this._closePopover();
|
|
412
|
-
}
|
|
413
|
-
_onFocusNavCoach() {
|
|
414
|
-
if (!this.preventCoachScrollByPlaceClick) this.preselectPlaceInCoach();
|
|
415
|
-
else this.focusPlaceElement(this.currSelectedPlace);
|
|
416
|
-
this.isAutoScrolling = false;
|
|
417
|
-
}
|
|
418
|
-
/**
|
|
419
|
-
* Creates a popover for extra service information
|
|
420
|
-
* @param triggerId
|
|
421
|
-
* @param popoverContent
|
|
422
|
-
* @private
|
|
423
|
-
*/
|
|
424
|
-
_popover(triggerId, popoverContent) {
|
|
425
|
-
return html`
|
|
426
|
-
<sbb-popover trigger="${triggerId}" hover-trigger="">
|
|
427
|
-
<p class="sbb-text-s sbb-sr-popover">${popoverContent}</p>
|
|
428
|
-
</sbb-popover>
|
|
429
|
-
`;
|
|
430
|
-
}
|
|
431
|
-
/**
|
|
432
|
-
* trigger to close all opened popovers (normally only one is opened at a time)
|
|
433
|
-
* @private
|
|
434
|
-
*/
|
|
435
|
-
_closePopover() {
|
|
436
|
-
this.shadowRoot?.querySelectorAll("sbb-popover:is(:state(state-opened),[state--state-opened])").forEach((popover) => popover.close());
|
|
437
|
-
}
|
|
438
|
-
_getDescriptionTableCoach(coachItem) {
|
|
439
|
-
if (coachItem.type === "LOCOMOTIVE_COACH") return getI18nSeatReservation("COACH_LOCOMOTIVE", this._language.current);
|
|
440
|
-
if (!coachItem.places?.length) return getI18nSeatReservation("COACH_BLOCKED_TABLE_CAPTION", this._language.current, [coachItem.id]);
|
|
441
|
-
let tableCoachDescription;
|
|
442
|
-
const areaDescriptions = this._getTitleDescriptionListString(coachItem.graphicElements);
|
|
443
|
-
const serviceDescriptions = this._getTitleDescriptionListString(coachItem.serviceElements);
|
|
444
|
-
tableCoachDescription = getI18nSeatReservation("COACH_TABLE_CAPTION", this._language.current, [coachItem.id]);
|
|
445
|
-
if (!this.hasNavigation) {
|
|
446
|
-
const freePlaces = this.getAvailableFreePlacesNumFromCoach(coachItem.places);
|
|
447
|
-
const freePlacesTxt = getI18nSeatReservation("COACH_AVAILABLE_NUMBER_OF_PLACES", this._language.current, [freePlaces.seats, freePlaces.bicycles]);
|
|
448
|
-
tableCoachDescription = tableCoachDescription.concat(". ").concat(freePlacesTxt).concat(". ");
|
|
449
|
-
}
|
|
450
|
-
if (!!areaDescriptions || !!serviceDescriptions) {
|
|
451
|
-
tableCoachDescription += ". " + getI18nSeatReservation("COACH_AVAILABLE_SERVICES", this._language.current) + ": ";
|
|
452
|
-
tableCoachDescription += serviceDescriptions + ", " + areaDescriptions + ".";
|
|
453
|
-
}
|
|
454
|
-
return tableCoachDescription;
|
|
455
|
-
}
|
|
456
|
-
_getTitleDescriptionListString(descriptionsElements) {
|
|
457
|
-
const uniqueDescriptions = [];
|
|
458
|
-
return descriptionsElements?.map((descriptionElement) => {
|
|
459
|
-
const icon = descriptionElement.icon;
|
|
460
|
-
if (!icon) return null;
|
|
461
|
-
const descriptionAlreadyExist = uniqueDescriptions.indexOf(icon) > -1;
|
|
462
|
-
const translation = getI18nSeatReservation(descriptionElement.icon, this._language.current);
|
|
463
|
-
const isValidDescription = this.notFixedRotatableAreaIcons.indexOf(icon) === -1 && this.notAreaElements.indexOf(icon) === -1;
|
|
464
|
-
if (!descriptionAlreadyExist) uniqueDescriptions.push(descriptionElement.icon);
|
|
465
|
-
return !!translation && !descriptionAlreadyExist && isValidDescription ? translation : null;
|
|
466
|
-
}).filter((description) => !!description).join(", ");
|
|
467
|
-
}
|
|
468
|
-
};
|
|
469
|
-
//#endregion
|
|
470
|
-
export { SbbSeatReservationElement as t };
|
|
471
|
-
|
|
472
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VhdC1yZXNlcnZhdGlvbi5jb21wb25lbnQtQkd2VnY2ckouanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2VsZW1lbnRzLWV4cGVyaW1lbnRhbC9zZWF0LXJlc2VydmF0aW9uL3NlYXQtcmVzZXJ2YXRpb24vc2VhdC1yZXNlcnZhdGlvbi5zY3NzP2lubGluZSIsIi4uLy4uLy4uL3NyYy9lbGVtZW50cy1leHBlcmltZW50YWwvc2VhdC1yZXNlcnZhdGlvbi9zZWF0LXJlc2VydmF0aW9uL3NlYXQtcmVzZXJ2YXRpb24uY29tcG9uZW50LnRzIl0sInNvdXJjZXNDb250ZW50IjpbIkB1c2UgJ0BzYmItZXN0YS9seW5lLWVsZW1lbnRzL2NvcmUvc3R5bGVzJyBhcyBzYmI7XG5AdXNlICcuLi9jb21tb24vc3R5bGVzL3NlYXQtcmVzZXJ2YXRpb24tbWl4aW5zJyBhcyBzYmItc3ItbWl4aW5zO1xuQHVzZSAnLi4vY29tbW9uL3N0eWxlcy9zZWF0LXJlc2VydmF0aW9uLWZ1bmN0aW9ucycgYXMgc2JiLXNyLWZ1bmN0aW9ucztcblxuLy8gTWF4aW11bSByZXNwb25zaXZlIG5hdmlnYXRpb24gd2lkdGgsIGNvbnNpc3RzIG9mIHRoZSBtYXhpbXVtIG5hdmlnYXRpb24gZXh0ZW50IG1pbnVzIDJ4IG5hdiBkaXJlY3Rpb24gYnV0dG9ucyA5NnB4IGFuZCA4cHggcGFkZGluZy5cbiRtYXgtY29hY2gtbmF2aWdhdGlvbi13aWR0aDogY2FsYyg5NjBweCAtIDk2cHggLSA4cHgpO1xuJHNjcm9sbGJhci1oZWlnaHQ6IDE2cHg7XG5cbjpob3N0IHtcbiAgLy8gTm90ZTogVGhlIHVzZSBvZiBweCBpcyBpbnRlbnRpb25hbCBoZXJlLCBiZWNhdXNlIG1hbnkgd2lkdGhzL2hlaWdodHMsIHJvdGF0aW9ucywgc2NhbGVzLCBldGMuIGRlcGVuZHMgb24gdGhpcy5cbiAgLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmlkLXNpemU6IDE2cHg7XG4gIC0tc2JiLXNlYXQtcmVzZXJ2YXRpb24taGVpZ2h0OiAwO1xuICAtLXNiYi1zZWF0LXJlc2VydmF0aW9uLWRlY2tzOiAxO1xuXG4gIGRpc3BsYXk6IGJsb2NrO1xuICBoZWlnaHQ6IGluaGVyaXQ7XG5cbiAgOjpwYXJ0KGNvYWNoLWZsb29yKSB7XG4gICAgZmlsbDogdmFyKC0tc2JiLWJhY2tncm91bmQtY29sb3ItMik7XG5cbiAgICAvLyBJbiBIaWdoIENvbnRyYXN0IE1vZGUgd2Ugc2V0IGZsb29yIGNvbG9yIHRvIHRyYW5zcGFyZW50XG4gICAgQGluY2x1ZGUgc2JiLmlmLWZvcmNlZC1jb2xvcnMge1xuICAgICAgZmlsbDogdHJhbnNwYXJlbnQ7XG4gICAgfVxuICB9XG59XG5cbi8vIHJvdGF0ZXMgdGhlIERPTS1wYXJ0IFwiY29hY2gtZmxvb3JcIiBieSAxODAgZGVncmVlcyBpZiB0aGUgaG9zdCBpcyBpbiBSVEwgbW9kZS5cbkBpbmNsdWRlIHNiYi1zci1taXhpbnMucm90YXRlLWRvbS1wYXJ0KGNvYWNoLWZsb29yKTtcblxuW3BvcG92ZXJdOndoZXJlKHNiYi1wb3BvdmVyKSB7XG4gIEBpbmNsdWRlIHNiYi5wb3BvdmVyLXJlc2V0O1xuXG4gIC5zYmItc3ItcG9wb3ZlciB7XG4gICAgbWFyZ2luLWJsb2NrOiBzYmItc3ItZnVuY3Rpb25zLnNyLXB4LXRvLXJlbSg0KTtcbiAgfVxufVxuXG4vLyBTVEFSVCAtIFZlcnRpY2FsIG1vZGVcbjpob3N0KFthbGlnbi12ZXJ0aWNhbF0pIHtcbiAgJGNvYWNoLW5hdmlnYXRpb24tcGFkZGluZzogNTtcbiAgJGNvYWNoLXNjcm9sbGJhci13aWR0aDogMjQ7XG4gICRjb2FjaC1ncmlkLXdpZHRoOiBjYWxjKHZhcigtLXNiYi1zZWF0LXJlc2VydmF0aW9uLWhlaWdodCkgKyAkY29hY2gtc2Nyb2xsYmFyLXdpZHRoKTtcblxuICAuc2JiLXNyX19jb21wb25lbnQge1xuICAgIGZsZXgtZGlyZWN0aW9uOiByb3ctcmV2ZXJzZTtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IGZsZXgtZW5kO1xuICAgIGdhcDogc2JiLXNyLWZ1bmN0aW9ucy5zci1weC10by1yZW0oMjIpO1xuICAgIGhlaWdodDogaW5oZXJpdDtcblxuICAgIEBpbmNsdWRlIHNiYi5tcSgkZnJvbTogc21hbGwpIHtcbiAgICAgIGdhcDogc2JiLXNyLWZ1bmN0aW9ucy5zci1weC10by1yZW0oNTQpO1xuICAgIH1cblxuICAgIG5hdi5zYmItc3ItbmF2aWdhdGlvbixcbiAgICB1bC5zYmItc3ItbmF2aWdhdGlvbl9fbGlzdC1jb2FjaGVzIHtcbiAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgfVxuXG4gICAgbmF2LnNiYi1zci1uYXZpZ2F0aW9uIHtcbiAgICAgIHBhZGRpbmc6IHNiYi1zci1mdW5jdGlvbnMuc3ItcHgtdG8tcmVtKDE2KSAwO1xuXG4gICAgICAuc2JiLXNyX19uYXZpZ2F0aW9uLWNvbnRyb2wtYnV0dG9uIHtcbiAgICAgICAgbGVmdDogc2JiLXNyLWZ1bmN0aW9ucy5zci1weC10by1yZW0oMSk7XG4gICAgICAgIHRvcDogMDtcbiAgICAgICAgcm90YXRlOiA5MGRlZztcblxuICAgICAgICBAaW5jbHVkZSBzYmIubXEoJGZyb206IGxhcmdlKSB7XG4gICAgICAgICAgbGVmdDogc2JiLXNyLWZ1bmN0aW9ucy5zci1weC10by1yZW0oLTEpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHVsLnNiYi1zci1uYXZpZ2F0aW9uX19saXN0LWNvYWNoZXMge1xuICAgICAgICBtYXgtd2lkdGg6IGluaXRpYWw7XG5cbiAgICAgICAgLy8gUGFkZGluZyBuZWVkcyB0byB2aXN1YWwgZm9jdXMtdmlzaWJsZSBzdHlsZSBmb3IgbmF2IGJ1dHRvbiBpbnNpZGUgb3ZlcmZsb3cgY29udGVudCxcbiAgICAgICAgLy8gb3RoZXJ3aXNlIGZvY3VzLXZpc2libGUgc3R5bGUgaXMgY3V0dGVkLlxuICAgICAgICBwYWRkaW5nOiBzYmItc3ItZnVuY3Rpb25zLnNyLXB4LXRvLXJlbSgkY29hY2gtbmF2aWdhdGlvbi1wYWRkaW5nKTtcbiAgICAgICAgb3ZlcmZsb3c6IGhpZGRlbiBzY3JvbGw7XG5cbiAgICAgICAgLy8gaW4gdmVydGljYWwgbW9kZSwgdGhlIGxpIG11c3QgYmUgZmxleGVkOyBvdGhlcndpc2UgaXQgd291bGQgY2FsY3VsYXRlIHRoZSB3cm9uZyBoZWlnaHRcbiAgICAgICAgLy8gZHVlIHRvIHVzZXJhZ2VudCBzdHlsZSBzZXQgdG8gXCJsaXN0LWl0ZW1cIiBmb3IgZGlzcGxheVxuICAgICAgICBsaSB7XG4gICAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIFZFUlRJQ0FMIE1PREUgLSBMQUJFTE1VTFRJUExFIERFQ0tTIC0gTEFCRUxTXG4gIC5zYmItc3JfX3dyYXBwZXItY29hY2gtZGVja3Mge1xuICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG5cbiAgICAuc2JiLXNyX193cmFwcGVyLWRlY2stbGFiZWxzIHtcbiAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW4tcmV2ZXJzZTtcbiAgICAgIHdpZHRoOiBzYmItc3ItZnVuY3Rpb25zLnNyLXB4LXRvLXJlbSgkY29hY2gtZ3JpZC13aWR0aCk7XG4gICAgICBoZWlnaHQ6IGluaXRpYWw7XG5cbiAgICAgIGIge1xuICAgICAgICBpbmxpbmUtc2l6ZTogY2FsYyg1MCUgLSBzYmItc3ItZnVuY3Rpb25zLnNyLXB4LXRvLXJlbSgxNikpO1xuICAgICAgICBibG9jay1zaXplOiBzYmItc3ItZnVuY3Rpb25zLnNyLXB4LXRvLXJlbSgyMCk7XG4gICAgICAgIG1hcmdpbi1ib3R0b206IHNiYi1zci1mdW5jdGlvbnMuc3ItcHgtdG8tcmVtKDE2KTtcbiAgICAgICAgcm90YXRlOiBpbml0aWFsO1xuICAgICAgICB3cml0aW5nLW1vZGU6IGluaXRpYWw7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gVkVSVElDQUwgTU9ERSAtIFNFQVRNQVAgU0NST0xMIEFSRUFcbiAgLnNiYi1zcl9fd3JhcHBlci1zY3JvbGxhcmVhIHtcbiAgICB3aWR0aDogc2JiLXNyLWZ1bmN0aW9ucy5zci1weC10by1yZW0oJGNvYWNoLWdyaWQtd2lkdGgpO1xuICAgIGhlaWdodDogMTAwJTtcbiAgICBvdmVyZmxvdzogaGlkZGVuIHNjcm9sbDtcblxuICAgIC5zYmItc3JfX3BhcmVudCB7XG4gICAgICByb3RhdGU6IDkwZGVnO1xuICAgIH1cbiAgfVxuXG4gIC8vIFZFUlRJQ0FMIE1PREUgLSBUUkFWRUwtRElSRUNUSU9OXG4gIC5zYmItc3ItdHJhdmVsLWRpcmVjdGlvbi13cmFwcGVyIHtcbiAgICB3aWR0aDogc2JiLXNyLWZ1bmN0aW9ucy5zci1weC10by1yZW0odmFyKC0tc2JiLXNlYXQtcmVzZXJ2YXRpb24taGVpZ2h0KSk7XG4gICAgbWFyZ2luLWJsb2NrLXN0YXJ0OiBzYmItc3ItZnVuY3Rpb25zLnNyLXB4LXRvLXJlbSg0KTtcbiAgfVxufVxuXG4vLyBFTkQgLSBWZXJ0aWNhbCBtb2RlXG5cbi5zYmItc3ItbmF2aWdhdGlvbiB7XG4gIGdhcDogc2JiLXNyLWZ1bmN0aW9ucy5zci1weC10by1yZW0oMyk7XG59XG5cbi5zYmItc3ItbmF2aWdhdGlvbiAuc2JiLXNyX19uYXZpZ2F0aW9uLWNvbnRyb2wtYnV0dG9uIHtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xuICB0b3A6IHNiYi1zci1mdW5jdGlvbnMuc3ItcHgtdG8tcmVtKDIpO1xuXG4gIEBpbmNsdWRlIHNiYi5tcSgkZnJvbTogbGFyZ2UpIHtcbiAgICB0b3A6IDA7XG4gIH1cbn1cblxuLnNiYi1zcl9fY29tcG9uZW50IHtcbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgZ2FwOiBjYWxjKHNiYi1zci1mdW5jdGlvbnMuc3ItcHgtdG8tcmVtKDY0KSAtICRzY3JvbGxiYXItaGVpZ2h0KTtcbn1cblxuLy8gVFJBVkVMIERJUkVDVElPTlxuLnNiYi1zci10cmF2ZWwtZGlyZWN0aW9uLXdyYXBwZXIge1xuICBkaXNwbGF5OiBmbGV4O1xuICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgY29sdW1uLWdhcDogc2JiLXNyLWZ1bmN0aW9ucy5zci1weC10by1yZW0oNCk7XG4gIG1hcmdpbi1ibG9jazogc2JiLXNyLWZ1bmN0aW9ucy5zci1weC10by1yZW0oOCkgc2JiLXNyLWZ1bmN0aW9ucy5zci1weC10by1yZW0oNCk7XG4gIGZvbnQtc2l6ZTogdmFyKC0tc2JiLXRleHQtZm9udC1zaXplLXMpO1xuXG4gIC5zYmItc3JfX3RyYXZlbC1kaXJlY3Rpb24tLWFycm93IHtcbiAgICBkaXNwbGF5OiBmbGV4O1xuICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIH1cbn1cblxuLy8gTkFWSUdBVElPTiBORVdcbi5zYmItc3ItbmF2aWdhdGlvbi13cmFwcGVyIHtcbiAgZGlzcGxheTogZmxleDtcbn1cblxuLnNiYi1zci1uYXZpZ2F0aW9uIHtcbiAgZGlzcGxheTogZmxleDtcbiAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gIHdpZHRoOiAxMDAlO1xuICBwYWRkaW5nLWlubGluZTogMTZweDtcbn1cblxuLnNiYi1zci1uYXZpZ2F0aW9uX19saXN0LWNvYWNoZXMge1xuICBAaW5jbHVkZSBzYmIubGlzdC1yZXNldDtcblxuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LXdyYXA6IG5vd3JhcDtcbiAgZ2FwOiBzYmItc3ItZnVuY3Rpb25zLnNyLXB4LXRvLXJlbSg0KTtcbiAgcGFkZGluZzogc2JiLXNyLWZ1bmN0aW9ucy5zci1weC10by1yZW0oNikgc2JiLXNyLWZ1bmN0aW9ucy5zci1weC10by1yZW0oNSkgMDtcbiAgbWF4LXdpZHRoOiAkbWF4LWNvYWNoLW5hdmlnYXRpb24td2lkdGg7XG5cbiAgLy8gU2V0IHNiYiBzY3JvbGxiYXIgdHJhbnNwYXJlbnQgYnkgZGVmYXVsdFxuICAtLXNiYi1zY3JvbGxiYXItY29sb3I6IHRyYW5zcGFyZW50O1xuXG4gIG92ZXJmbG93OiBzY3JvbGwgaGlkZGVuO1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG59XG5cbi8vIC0tLS0tLS0tLS0tLS0tLSBTZWF0IFJlc2VydmF0aW9uIE1haW4gTmF2aWdhdGlvbiAtIEVORCAtLS0tLS0tLS0tLS0tLS0tXG5cbi8vIC0tLS0tLS0tLS0tLS0gU2VhdCBSZXNlcnZhdGlvbiBDb2FjaGVzIC0gU1RBUlQgLS0tLS0tLS0tLS0tLS0tLS1cbi5zYmItc3JfX3dyYXBwZXItY29hY2gtZGVja3Mge1xuICBkaXNwbGF5OiBmbGV4O1xuICBvdmVyZmxvdzogaGlkZGVuO1xuICBoZWlnaHQ6IGluaGVyaXQ7XG5cbiAgLnNiYi1zcl9fd3JhcHBlci1kZWNrLWxhYmVscyB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47XG4gICAgaGVpZ2h0OiBzYmItc3ItZnVuY3Rpb25zLnNyLXB4LXRvLXJlbSh2YXIoLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1oZWlnaHQpKTtcbiAgICB3cml0aW5nLW1vZGU6IHZlcnRpY2FsLWxyO1xuXG4gICAgYiB7XG4gICAgICBoZWlnaHQ6IGNhbGMoNTAlIC0gc2JiLXNyLWZ1bmN0aW9ucy5zci1weC10by1yZW0oMTYpKTtcbiAgICAgIHdpZHRoOiBzYmItc3ItZnVuY3Rpb25zLnNyLXB4LXRvLXJlbSgyMCk7XG4gICAgICBtYXJnaW4tYmxvY2stZW5kOiAxNnB4O1xuICAgICAgcm90YXRlOiAxODBkZWc7XG4gICAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgICBsaW5lLWhlaWdodDogc2JiLXNyLWZ1bmN0aW9ucy5zci1weC10by1yZW0oMjApO1xuICAgIH1cbiAgfVxufVxuXG4uc2JiLXNyX193cmFwcGVyLXNjcm9sbGFyZWEge1xuICBvdmVyZmxvdzogc2Nyb2xsIGhpZGRlbjtcbiAgcGFkZGluZy1ibG9jazogc2JiLXNyLWZ1bmN0aW9ucy5zci1weC10by1yZW0oOCkgc2JiLXNyLWZ1bmN0aW9ucy5zci1weC10by1yZW0oMTYpO1xuXG4gIC5zYmItc3JfX3BhcmVudCB7XG4gICAgZGlzcGxheTogZmxleDtcbiAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgfVxufVxuXG4uc2JiLXNyX19saXN0LWRlY2tzIHtcbiAgQGluY2x1ZGUgc2JiLmxpc3QtcmVzZXQ7XG5cbiAgZGlzcGxheTogZmxleDtcbiAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbn1cblxuLnNiYi1zcl9fbGlzdC1kZWNrcy0tZ2FwIHtcbiAgZ2FwOiBzYmItc3ItZnVuY3Rpb25zLnNyLXB4LXRvLXJlbSg0OCk7XG59XG5cbi5zYmItc3JfX2xpc3QtaXRlbS1kZWNrIHtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xufVxuXG4uc2JiLXNyX19saXN0LWNvYWNoZXMge1xuICBAaW5jbHVkZSBzYmIubGlzdC1yZXNldDtcblxuICBkaXNwbGF5OiBmbGV4O1xuICBnYXA6IHNiYi1zci1mdW5jdGlvbnMuc3ItcHgtdG8tcmVtKDQpO1xufVxuXG4vLyBJZiB0aGVyZSBhcmUgb3ZlcmhhbmdpbmcgZWxlbWVudHMgd2UgbmVlZCB0byBpbmNyZWFzZSB0aGUgZ2FwIGJldHdlZW4gY29hY2hlc1xuLnNiYi1zcl9fbGlzdC1kZWNrczpoYXMoLnNiYi1zci1jb2FjaC1oYXMtb3ZlcmhhbmdpbmctZWxlbWVudHMpIC5zYmItc3JfX2xpc3QtY29hY2hlcyB7XG4gIGdhcDogc2JiLXNyLWZ1bmN0aW9ucy5zci1weC10by1yZW0oOCk7XG59XG5cbi5zYmItc3JfX2l0ZW0tY29hY2gge1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG59XG5cbi5zYmItc3ItY29hY2gtd3JhcHBlcl9fdGFibGUge1xuICBvdXRsaW5lOiAwO1xufVxuIiwiaW1wb3J0IHsgU2JiU2Vjb25kYXJ5QnV0dG9uRWxlbWVudCB9IGZyb20gJ0BzYmItZXN0YS9seW5lLWVsZW1lbnRzL2J1dHRvbi5wdXJlLmpzJztcbmltcG9ydCB7XG4gIHR5cGUgU2JiRWxlbWVudFR5cGUsXG4gIFNiYkxhbmd1YWdlQ29udHJvbGxlcixcbiAgc2NyZWVuUmVhZGVyT25seVN0eWxlcyxcbiAgc2Nyb2xsYmFyU3R5bGVzLFxufSBmcm9tICdAc2JiLWVzdGEvbHluZS1lbGVtZW50cy9jb3JlLmpzJztcbmltcG9ydCB7IFNiYlBvcG92ZXJFbGVtZW50IH0gZnJvbSAnQHNiYi1lc3RhL2x5bmUtZWxlbWVudHMvcG9wb3Zlci5wdXJlLmpzJztcbmltcG9ydCB0eXBlIHsgQ1NTUmVzdWx0R3JvdXAsIFByb3BlcnR5VmFsdWVzLCBUZW1wbGF0ZVJlc3VsdCB9IGZyb20gJ2xpdCc7XG5pbXBvcnQgeyBodG1sLCBpc1NlcnZlciwgbm90aGluZywgdW5zYWZlQ1NTIH0gZnJvbSAnbGl0JztcbmltcG9ydCB7IGNsYXNzTWFwIH0gZnJvbSAnbGl0L2RpcmVjdGl2ZXMvY2xhc3MtbWFwLmpzJztcbmltcG9ydCB7IHJlcGVhdCB9IGZyb20gJ2xpdC9kaXJlY3RpdmVzL3JlcGVhdC5qcyc7XG5pbXBvcnQgeyBzdHlsZU1hcCB9IGZyb20gJ2xpdC9kaXJlY3RpdmVzL3N0eWxlLW1hcC5qcyc7XG5cbmltcG9ydCB7IGdldEkxOG5TZWF0UmVzZXJ2YXRpb24gfSBmcm9tICcuLi9jb21tb24vdHJhbnNsYXRpb25zLnRzJztcbmltcG9ydCB0eXBlIHtcbiAgQmFzZUVsZW1lbnQsXG4gIENvYWNoSXRlbSxcbiAgQ29hY2hJdGVtRGV0YWlscyxcbiAgUGxhY2UsXG4gIFNlYXRSZXNlcnZhdGlvbixcbn0gZnJvbSAnLi4vY29tbW9uL3R5cGVzLnRzJztcbmltcG9ydCB7IFNiYlNlYXRSZXNlcnZhdGlvbkFyZWFFbGVtZW50IH0gZnJvbSAnLi4vc2VhdC1yZXNlcnZhdGlvbi1hcmVhL3NlYXQtcmVzZXJ2YXRpb24tYXJlYS5jb21wb25lbnQudHMnO1xuaW1wb3J0IHsgU2JiU2VhdFJlc2VydmF0aW9uR3JhcGhpY0VsZW1lbnQgfSBmcm9tICcuLi9zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWMvc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljLmNvbXBvbmVudC50cyc7XG5pbXBvcnQge1xuICBTYmJTZWF0UmVzZXJ2YXRpb25OYXZpZ2F0aW9uQ29hY2hFbGVtZW50LFxuICB0eXBlIFNiYlNlbGVjdENvYWNoRXZlbnQsXG59IGZyb20gJy4uL3NlYXQtcmVzZXJ2YXRpb24tbmF2aWdhdGlvbi1jb2FjaC9zZWF0LXJlc2VydmF0aW9uLW5hdmlnYXRpb24tY29hY2guY29tcG9uZW50LnRzJztcbmltcG9ydCB7XG4gIHR5cGUgU2JiUGxhY2VTZWxlY3Rpb25FdmVudCxcbiAgU2JiU2VhdFJlc2VydmF0aW9uUGxhY2VDb250cm9sRWxlbWVudCxcbn0gZnJvbSAnLi4vc2VhdC1yZXNlcnZhdGlvbi1wbGFjZS1jb250cm9sL3NlYXQtcmVzZXJ2YXRpb24tcGxhY2UtY29udHJvbC5jb21wb25lbnQudHMnO1xuaW1wb3J0IHsgU2JiU2VhdFJlc2VydmF0aW9uU2NvcGVkRWxlbWVudCB9IGZyb20gJy4uL3NlYXQtcmVzZXJ2YXRpb24tc2NvcGVkL3NlYXQtcmVzZXJ2YXRpb24tc2NvcGVkLmNvbXBvbmVudC50cyc7XG5cbmltcG9ydCB7IFNlYXRSZXNlcnZhdGlvbkJhc2VFbGVtZW50IH0gZnJvbSAnLi9zZWF0LXJlc2VydmF0aW9uLWJhc2UtZWxlbWVudC50cyc7XG5pbXBvcnQgc3R5bGUgZnJvbSAnLi9zZWF0LXJlc2VydmF0aW9uLnNjc3M/aW5saW5lJztcblxuLyoqXG4gKiBNYWluIGNvbXBvbmVudCBmb3IgdGhlIHNlYXQgcmVzZXJ2YXRpb24uXG4gKlxuICovXG5leHBvcnQgY2xhc3MgU2JiU2VhdFJlc2VydmF0aW9uRWxlbWVudCBleHRlbmRzIFNlYXRSZXNlcnZhdGlvbkJhc2VFbGVtZW50IHtcbiAgcHVibGljIHN0YXRpYyBvdmVycmlkZSByZWFkb25seSBlbGVtZW50TmFtZTogc3RyaW5nID0gJ3NiYi1zZWF0LXJlc2VydmF0aW9uJztcbiAgcHVibGljIHN0YXRpYyBvdmVycmlkZSBlbGVtZW50RGVwZW5kZW5jaWVzOiBTYmJFbGVtZW50VHlwZVtdID0gW1xuICAgIFNiYlNlY29uZGFyeUJ1dHRvbkVsZW1lbnQsXG4gICAgU2JiUG9wb3ZlckVsZW1lbnQsXG4gICAgU2JiU2VhdFJlc2VydmF0aW9uQXJlYUVsZW1lbnQsXG4gICAgU2JiU2VhdFJlc2VydmF0aW9uR3JhcGhpY0VsZW1lbnQsXG4gICAgU2JiU2VhdFJlc2VydmF0aW9uUGxhY2VDb250cm9sRWxlbWVudCxcbiAgICBTYmJTZWF0UmVzZXJ2YXRpb25OYXZpZ2F0aW9uQ29hY2hFbGVtZW50LFxuICAgIFNiYlNlYXRSZXNlcnZhdGlvblNjb3BlZEVsZW1lbnQsXG4gIF07XG4gIHB1YmxpYyBzdGF0aWMgb3ZlcnJpZGUgc3R5bGVzOiBDU1NSZXN1bHRHcm91cCA9IFtcbiAgICBzY3JvbGxiYXJTdHlsZXMsXG4gICAgc2NyZWVuUmVhZGVyT25seVN0eWxlcyxcbiAgICB1bnNhZmVDU1Moc3R5bGUpLFxuICBdO1xuXG4gIHByaXZhdGUgX2xhbmd1YWdlID0gbmV3IFNiYkxhbmd1YWdlQ29udHJvbGxlcih0aGlzKTtcbiAgcHJpdmF0ZSBfY29hY2hlc0h0bWxUZW1wbGF0ZT86IFRlbXBsYXRlUmVzdWx0O1xuXG4gIHByb3RlY3RlZCBvdmVycmlkZSB3aWxsVXBkYXRlKGNoYW5nZWRQcm9wZXJ0aWVzOiBQcm9wZXJ0eVZhbHVlczx0aGlzPik6IHZvaWQge1xuICAgIHN1cGVyLndpbGxVcGRhdGUoY2hhbmdlZFByb3BlcnRpZXMpO1xuXG4gICAgaWYgKGNoYW5nZWRQcm9wZXJ0aWVzLmhhcygnaGFzTmF2aWdhdGlvbicpKSB7XG4gICAgICBpZiAodGhpcy5oYXNOYXZpZ2F0aW9uKSB7XG4gICAgICAgIHRoaXMuc2hhZG93Um9vdFxuICAgICAgICAgID8ucXVlcnlTZWxlY3RvckFsbCgndGFibGUnKVxuICAgICAgICAgIC5mb3JFYWNoKCh0YWJsZSkgPT4gdGFibGUucmVtb3ZlQXR0cmlidXRlKCd0YWJpbmRleCcpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2hhZG93Um9vdFxuICAgICAgICAgID8ucXVlcnlTZWxlY3RvckFsbCgndGFibGUnKVxuICAgICAgICAgIC5mb3JFYWNoKCh0YWJsZSkgPT4gdGFibGUuc2V0QXR0cmlidXRlKCd0YWJpbmRleCcsICcwJykpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBvdmVycmlkZSBmaXJzdFVwZGF0ZWQoY2hhbmdlZFByb3BlcnRpZXM6IFByb3BlcnR5VmFsdWVzPHRoaXM+KTogdm9pZCB7XG4gICAgc3VwZXIuZmlyc3RVcGRhdGVkKGNoYW5nZWRQcm9wZXJ0aWVzKTtcblxuICAgIC8vIFdlIG5lZWQgdG8gd2FpdCB1bnRpbCB0aGUgZmlyc3QgdXBkYXRlIGlzIGNvbXBsZXRlIHRvIGluaXQgZGlmZmVyZW50IEhUTUwgZWxlbWVudCBkaW1lbnNpb25zXG4gICAgdGhpcy51cGRhdGVDb21wbGV0ZS50aGVuKCgpID0+IHtcbiAgICAgIHRoaXMuaW5pdE5hdmlnYXRpb25TZWxlY3Rpb25CeVNjcm9sbEV2ZW50KCk7XG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgcmVuZGVyKCk6IFRlbXBsYXRlUmVzdWx0IHwgbnVsbCB7XG4gICAgdGhpcy5faW5pdFZlaGljbGVTZWF0UmVzZXJ2YXRpb25Db25zdHJ1Y3Rpb24oKTtcbiAgICByZXR1cm4gdGhpcy5fY29hY2hlc0h0bWxUZW1wbGF0ZSB8fCBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBfaW5pdFZlaGljbGVTZWF0UmVzZXJ2YXRpb25Db25zdHJ1Y3Rpb24oKTogdm9pZCB7XG4gICAgdGhpcy5fY29hY2hlc0h0bWxUZW1wbGF0ZSA9IGh0bWxgXG4gICAgICAke3RoaXMuX3JlbmRlclRyYXZlbERpcmVjdGlvbigpfVxuICAgICAgPGRpdiBjbGFzcz1cInNiYi1zcl9fY29tcG9uZW50XCI+XG4gICAgICAgICR7dGhpcy5fcmVuZGVyTmF2aWdhdGlvbigpfVxuICAgICAgICA8ZGl2XG4gICAgICAgICAgY2xhc3M9XCJzYmItc3JfX3dyYXBwZXItY29hY2gtZGVja3NcIlxuICAgICAgICAgIEBrZXlkb3duPSR7KGV2dDogS2V5Ym9hcmRFdmVudCkgPT4gdGhpcy5rZXlib2FyZFNlYXRtYXBFdmVudEhhbmRsaW5nKGV2dCl9XG4gICAgICAgID5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JiLXNyX193cmFwcGVyLWRlY2stbGFiZWxzXCI+JHt0aGlzLl9yZW5kZXJEZWNrTGFiZWxzKCl9PC9kaXY+XG4gICAgICAgICAgPGRpdlxuICAgICAgICAgICAgQHNjcm9sbD0keygpID0+IHRoaXMuY29hY2hBcmVhU2Nyb2xsZW5kKCl9XG4gICAgICAgICAgICBpZD1cInNiYi1zcl9fd3JhcHBlci1zY3JvbGxhcmVhXCJcbiAgICAgICAgICAgIGNsYXNzPVwic2JiLXNyX193cmFwcGVyLXNjcm9sbGFyZWEgc2JiLXNjcm9sbGJhclwiXG4gICAgICAgICAgICB0YWJpbmRleD1cIi0xXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8ZGl2IGlkPVwic2JiLXNyX19wYXJlbnQtYXJlYVwiIGNsYXNzPVwic2JiLXNyX19wYXJlbnRcIj5cbiAgICAgICAgICAgICAgPHVsXG4gICAgICAgICAgICAgICAgY2xhc3M9XCIke2NsYXNzTWFwKHtcbiAgICAgICAgICAgICAgICAgICdzYmItc3JfX2xpc3QtZGVja3MnOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgJ3NiYi1zcl9fbGlzdC1kZWNrcy0tZ2FwJzogdGhpcy5oYXNNdWx0aXBsZURlY2tzLFxuICAgICAgICAgICAgICAgIH0pfVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAke3RoaXMuc2VhdFJlc2VydmF0aW9ucz8ubWFwKFxuICAgICAgICAgICAgICAgICAgKHNlYXRSZXNlcnZhdGlvbjogU2VhdFJlc2VydmF0aW9uLCBjb2FjaERlY2tJbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBodG1sYDxsaSBjbGFzcz1cInNiYi1zcl9fbGlzdC1pdGVtLWRlY2tcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8dWwgY2xhc3M9XCJzYmItc3JfX2xpc3QtY29hY2hlc1wiIHJvbGU9XCJwcmVzZW50YXRpb25cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICR7dGhpcy5fcmVuZGVyQ29hY2hlcyhzZWF0UmVzZXJ2YXRpb24sIGNvYWNoRGVja0luZGV4KX1cbiAgICAgICAgICAgICAgICAgICAgICA8L3VsPlxuICAgICAgICAgICAgICAgICAgICA8L2xpPmA7XG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICl9XG4gICAgICAgICAgICAgIDwvdWw+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICBgO1xuICB9XG5cbiAgcHJpdmF0ZSBfcmVuZGVyRGVja0xhYmVscygpOiBUZW1wbGF0ZVJlc3VsdFtdIHwgbnVsbCB7XG4gICAgaWYgKCF0aGlzLmhhc011bHRpcGxlRGVja3MpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnNlYXRSZXNlcnZhdGlvbnMubWFwKChzZWF0UmVzZXJ2YXRpb24pID0+IHtcbiAgICAgIGNvbnN0IGRlY2tEZXNjcmlwdGlvbiA9IGdldEkxOG5TZWF0UmVzZXJ2YXRpb24oXG4gICAgICAgIHNlYXRSZXNlcnZhdGlvbi5kZWNrQ29hY2hMZXZlbCxcbiAgICAgICAgdGhpcy5fbGFuZ3VhZ2UuY3VycmVudCxcbiAgICAgICk7XG4gICAgICByZXR1cm4gaHRtbGA8YiBhcmlhLWhpZGRlbj1cInRydWVcIj4ke2RlY2tEZXNjcmlwdGlvbn08L2I+YDtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX3JlbmRlck5hdmlnYXRpb25Db250cm9sQnV0dG9uKGJ0bkRpcmVjdGlvbjogc3RyaW5nKTogVGVtcGxhdGVSZXN1bHQgfCBudWxsIHtcbiAgICBpZiAoIXRoaXMuaGFzTmF2aWdhdGlvbiB8fCAhdGhpcy5zZWF0UmVzZXJ2YXRpb25zKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgYnRuTmF2aWdhdGlvbkRpcmVjdGlvbklkID1cbiAgICAgIGJ0bkRpcmVjdGlvbiA9PSAnRElSRUNUSU9OX1JJR0hUJ1xuICAgICAgICA/ICdzYmItc3ItbmF2aWdhdGlvbl9fd3JhcHBlci1idXR0b24tZGlyZWN0aW9uLS1yaWdodCdcbiAgICAgICAgOiAnc2JiLXNyLW5hdmlnYXRpb25fX3dyYXBwZXItYnV0dG9uLWRpcmVjdGlvbi0tbGVmdCc7XG4gICAgY29uc3QgYnRuSWNvbiA9XG4gICAgICBidG5EaXJlY3Rpb24gPT0gJ0RJUkVDVElPTl9SSUdIVCcgPyAnY2hldnJvbi1zbWFsbC1yaWdodC1zbWFsbCcgOiAnY2hldnJvbi1zbWFsbC1sZWZ0LXNtYWxsJztcbiAgICBjb25zdCBidG5BcmlhRGVzY3JpcHRpb24gPVxuICAgICAgYnRuRGlyZWN0aW9uID09ICdESVJFQ1RJT05fUklHSFQnXG4gICAgICAgID8gZ2V0STE4blNlYXRSZXNlcnZhdGlvbignU0VBVF9SRVNFUlZBVElPTl9FTkQnLCB0aGlzLl9sYW5ndWFnZS5jdXJyZW50KVxuICAgICAgICA6IGdldEkxOG5TZWF0UmVzZXJ2YXRpb24oJ1NFQVRfUkVTRVJWQVRJT05fQkVHSU4nLCB0aGlzLl9sYW5ndWFnZS5jdXJyZW50KTtcbiAgICBsZXQgYnRuRGlzYWJsZWQgPSB0cnVlO1xuXG4gICAgaWYgKGJ0bkRpcmVjdGlvbiA9PSAnRElSRUNUSU9OX0xFRlQnICYmIHRoaXMuc2VsZWN0ZWRDb2FjaEluZGV4ID4gMCkge1xuICAgICAgYnRuRGlzYWJsZWQgPSBmYWxzZTtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgYnRuRGlyZWN0aW9uID09ICdESVJFQ1RJT05fUklHSFQnICYmXG4gICAgICB0aGlzLnNlbGVjdGVkQ29hY2hJbmRleCA8IHRoaXMuY29hY2hJdGVtRGV0YWlsc0VsZW1lbnRzLmxlbmd0aCAtIDFcbiAgICApIHtcbiAgICAgIGJ0bkRpc2FibGVkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIGh0bWxgPGRpdiBjbGFzcz1cInNiYi1zci1uYXZpZ2F0aW9uX193cmFwcGVyLWJ1dHRvbi1kaXJlY3Rpb25cIj5cbiAgICAgIDxzYmItc2Vjb25kYXJ5LWJ1dHRvblxuICAgICAgICBAY2xpY2s9XCIkeygpID0+IHRoaXMubmF2aWdhdGVCeURpcmVjdGlvbkJ0bihidG5EaXJlY3Rpb24pfVwiXG4gICAgICAgIEBmb2N1cz1cIiR7KCkgPT4gdGhpcy5vbkZvY3VzTmF2RGlyZWN0aW9uQnV0dG9uKCl9XCJcbiAgICAgICAgaWQ9XCIke2J0bk5hdmlnYXRpb25EaXJlY3Rpb25JZH1cIlxuICAgICAgICBjbGFzcz1cInNiYi1zcl9fbmF2aWdhdGlvbi1jb250cm9sLWJ1dHRvblwiXG4gICAgICAgIHNpemU9XCJtXCJcbiAgICAgICAgaWNvbi1uYW1lPVwiJHtidG5JY29ufVwiXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBhcmlhLWxhYmVsPVwiJHtidG5BcmlhRGVzY3JpcHRpb259XCJcbiAgICAgICAgcm9sZT1cImJ1dHRvblwiXG4gICAgICAgIC5kaXNhYmxlZEludGVyYWN0aXZlPVwiJHtidG5EaXNhYmxlZCB8fCBub3RoaW5nfVwiXG4gICAgICAgIC5kaXNhYmxlZD1cIiR7YnRuRGlzYWJsZWQgfHwgbm90aGluZ31cIlxuICAgICAgPjwvc2JiLXNlY29uZGFyeS1idXR0b24+XG4gICAgPC9kaXY+YDtcbiAgfVxuXG4gIHByaXZhdGUgX3JlbmRlclRyYXZlbERpcmVjdGlvbigpOiBUZW1wbGF0ZVJlc3VsdCB8IG51bGwge1xuICAgIGlmICghdGhpcy50cmF2ZWxEaXJlY3Rpb24gfHwgdGhpcy50cmF2ZWxEaXJlY3Rpb24gPT09ICdOT05FJykge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29uc3QgbGFiZWxUZXh0ID0gZ2V0STE4blNlYXRSZXNlcnZhdGlvbihcbiAgICAgICdTRUFUX1JFU0VSVkFUSU9OX1RSQVZFTF9ESVJFQ1RJT04nLFxuICAgICAgdGhpcy5fbGFuZ3VhZ2UuY3VycmVudCxcbiAgICApO1xuXG4gICAgY29uc3QgYXJyb3dEaXJlY3Rpb24gPSB0aGlzLmFsaWduVmVydGljYWxcbiAgICAgID8gdGhpcy50cmF2ZWxEaXJlY3Rpb24gPT09ICdSSUdIVCdcbiAgICAgICAgPyAnZG93bidcbiAgICAgICAgOiAndXAnXG4gICAgICA6IHRoaXMudHJhdmVsRGlyZWN0aW9uID09PSAnUklHSFQnXG4gICAgICAgID8gJ3JpZ2h0J1xuICAgICAgICA6ICdsZWZ0JztcblxuICAgIGNvbnN0IGljb25OYW1lID0gYGFycm93LSR7YXJyb3dEaXJlY3Rpb259LXNtYWxsYDtcblxuICAgIHJldHVybiBodG1sYDxkaXYgY2xhc3M9XCJzYmItc3ItdHJhdmVsLWRpcmVjdGlvbi13cmFwcGVyXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwic2JiLXNyX190cmF2ZWwtZGlyZWN0aW9uLS1hcnJvd1wiPlxuICAgICAgICA8c2JiLWljb24gc2xvdD1cImljb25cIiBuYW1lPVwiJHtpY29uTmFtZX1cIj48L3NiYi1pY29uPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwic2JiLXNyX190cmF2ZWwtZGlyZWN0aW9uLS1sYWJlbFwiPiR7bGFiZWxUZXh0fTwvZGl2PlxuICAgIDwvZGl2PmA7XG4gIH1cblxuICBwcml2YXRlIF9yZW5kZXJOYXZpZ2F0aW9uKCk6IFRlbXBsYXRlUmVzdWx0IHwgbnVsbCB7XG4gICAgaWYgKGlzU2VydmVyIHx8ICF0aGlzLmhhc05hdmlnYXRpb24gfHwgIXRoaXMuc2VhdFJlc2VydmF0aW9ucykge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHJldHVybiBodG1sYDxkaXYgY2xhc3M9XCJzYmItc3ItbmF2aWdhdGlvbi13cmFwcGVyXCI+XG4gICAgICA8bmF2IGlkPVwic2JiLXNyLW5hdmlnYXRpb25cIiBjbGFzcz1cInNiYi1zci1uYXZpZ2F0aW9uXCI+XG4gICAgICAgICR7dGhpcy5fcmVuZGVyTmF2aWdhdGlvbkNvbnRyb2xCdXR0b24oJ0RJUkVDVElPTl9MRUZUJyl9XG4gICAgICAgIDx1bFxuICAgICAgICAgIGlkPVwic2JiLXNyX19uYXZpZ2F0aW9uLWxpc3QtY29hY2hlc1wiXG4gICAgICAgICAgY2xhc3M9XCJzYmItc3ItbmF2aWdhdGlvbl9fbGlzdC1jb2FjaGVzIHNiYi1zY3JvbGxiYXJcIlxuICAgICAgICAgIGFyaWEtbGFiZWw9XCIke2dldEkxOG5TZWF0UmVzZXJ2YXRpb24oXG4gICAgICAgICAgICAnU0VBVF9SRVNFUlZBVElPTl9OQVZJR0FUSU9OJyxcbiAgICAgICAgICAgIHRoaXMuX2xhbmd1YWdlLmN1cnJlbnQsXG4gICAgICAgICAgKX1cIlxuICAgICAgICA+XG4gICAgICAgICAgJHt0aGlzLmNvYWNoSXRlbURldGFpbHNFbGVtZW50cy5tYXAoXG4gICAgICAgICAgICAoY29hY2hJdGVtRGV0YWlsczogQ29hY2hJdGVtRGV0YWlscywgaW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gaHRtbGA8bGk+XG4gICAgICAgICAgICAgICAgPHNiYi1zZWF0LXJlc2VydmF0aW9uLW5hdmlnYXRpb24tY29hY2hcbiAgICAgICAgICAgICAgICAgIEBzZWxlY3Rjb2FjaD0keyhldmVudDogU2JiU2VsZWN0Q29hY2hFdmVudCkgPT4gdGhpcy5fb25TZWxlY3ROYXZDb2FjaChldmVudCl9XG4gICAgICAgICAgICAgICAgICBAZm9jdXNjb2FjaD0keygpID0+IHRoaXMuX29uRm9jdXNOYXZDb2FjaCgpfVxuICAgICAgICAgICAgICAgICAgQGtleXVwPSR7KGV2dDogS2V5Ym9hcmRFdmVudCkgPT4gdGhpcy5vbktleU5hdmlnYXRpb25OYXZDb2FjaEJ1dHRvbihldnQsIGluZGV4KX1cbiAgICAgICAgICAgICAgICAgIGluZGV4PVwiJHtpbmRleH1cIlxuICAgICAgICAgICAgICAgICAgLnNlbGVjdGVkPSR7dGhpcy5zZWxlY3RlZENvYWNoSW5kZXggPT09IGluZGV4fVxuICAgICAgICAgICAgICAgICAgLmZvY3VzZWQ9JHt0aGlzLmZvY3VzZWRDb2FjaEluZGV4ID09PSBpbmRleH1cbiAgICAgICAgICAgICAgICAgIC5ob3ZlcmVkPSR7dGhpcy5ob3ZlcmVkQ29hY2hJbmRleCA9PT0gaW5kZXh9XG4gICAgICAgICAgICAgICAgICAubmF0aXZlRm9jdXNBY3RpdmU9JHt0aGlzLmhhc1NlYXRSZXNlcnZhdGlvbk5hdGl2ZUZvY3VzfVxuICAgICAgICAgICAgICAgICAgLmNvYWNoSXRlbURldGFpbHM9XCIke2NvYWNoSXRlbURldGFpbHN9XCJcbiAgICAgICAgICAgICAgICAgID92ZXJ0aWNhbD1cIiR7dGhpcy5hbGlnblZlcnRpY2FsfVwiXG4gICAgICAgICAgICAgICAgICA/c2hvd1RpdGxlSW5mbz1cIiR7dGhpcy5zaG93VGl0bGVJbmZvfVwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDwvc2JiLXNlYXQtcmVzZXJ2YXRpb24tbmF2aWdhdGlvbi1jb2FjaD5cbiAgICAgICAgICAgICAgPC9saT5gO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICApfVxuICAgICAgICA8L3VsPlxuICAgICAgICAke3RoaXMuX3JlbmRlck5hdmlnYXRpb25Db250cm9sQnV0dG9uKCdESVJFQ1RJT05fUklHSFQnKX1cbiAgICAgIDwvbmF2PlxuICAgIDwvZGl2PmA7XG4gIH1cbiAgLyoqXG4gICAqXG4gICAqIEByZXR1cm5zXG4gICAqIEBwYXJhbSBzZWF0UmVzZXJ2YXRpb25cbiAgICogQHBhcmFtIGNvYWNoRGVja0luZGV4XG4gICAqL1xuICBwcml2YXRlIF9yZW5kZXJDb2FjaGVzKFxuICAgIHNlYXRSZXNlcnZhdGlvbjogU2VhdFJlc2VydmF0aW9uLFxuICAgIGNvYWNoRGVja0luZGV4OiBudW1iZXIsXG4gICk6IFRlbXBsYXRlUmVzdWx0W10gfCBudWxsIHtcbiAgICBjb25zdCBjb2FjaGVzOiBDb2FjaEl0ZW1bXSA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoc2VhdFJlc2VydmF0aW9uPy5jb2FjaEl0ZW1zKSk7XG5cbiAgICBpZiAoIWNvYWNoZXMgfHwgaXNTZXJ2ZXIpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gY29hY2hlcy5tYXAoKGNvYWNoSXRlbTogQ29hY2hJdGVtLCBjb2FjaEluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgIHJldHVybiBodG1sYFxuICAgICAgICA8bGkgY2xhc3M9XCJzYmItc3JfX2l0ZW0tY29hY2hcIj5cbiAgICAgICAgICAke3RoaXMuX3JlbmRlckNvYWNoRWxlbWVudChcbiAgICAgICAgICAgIGNvYWNoSXRlbSxcbiAgICAgICAgICAgIGNvYWNoSW5kZXgsXG4gICAgICAgICAgICBjb2FjaERlY2tJbmRleCxcbiAgICAgICAgICAgIHNlYXRSZXNlcnZhdGlvbi5kZWNrQ29hY2hJbmRleCxcbiAgICAgICAgICApfVxuICAgICAgICA8L2xpPlxuICAgICAgYDtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX3JlbmRlckNvYWNoRWxlbWVudChcbiAgICBjb2FjaEl0ZW06IENvYWNoSXRlbSxcbiAgICBjb2FjaEluZGV4OiBudW1iZXIsXG4gICAgY29hY2hEZWNrSW5kZXg6IG51bWJlcixcbiAgICBwbGFjZUNvYWNoRGVja0luZGV4OiBudW1iZXIsXG4gICk6IFRlbXBsYXRlUmVzdWx0IHtcbiAgICBjb25zdCBjdXJyQ29hY2hTdHJ1Y3R1cmUgPVxuICAgICAgdGhpcy5zZWF0UmVzZXJ2YXRpb25TdHJ1Y3R1cmUuZGVja3NbY29hY2hEZWNrSW5kZXhdLmRlY2tDb2FjaGVzW2NvYWNoSW5kZXhdO1xuICAgIGNvbnN0IGRlc2NyaXB0aW9uVGFibGVDb2FjaFdpdGhTZXJ2aWNlcyA9IHRoaXMuX2dldERlc2NyaXB0aW9uVGFibGVDb2FjaChjb2FjaEl0ZW0pO1xuXG4gICAgcmV0dXJuIGh0bWxgPHNiYi1zZWF0LXJlc2VydmF0aW9uLXNjb3BlZFxuICAgICAgc3R5bGU9JHtzdHlsZU1hcCh7XG4gICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLXNjb3BlZC13aWR0aCc6IGN1cnJDb2FjaFN0cnVjdHVyZS53aWR0aCxcbiAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tc2NvcGVkLWhlaWdodCc6IGN1cnJDb2FjaFN0cnVjdHVyZS5oZWlnaHQsXG4gICAgICB9KX1cbiAgICA+XG4gICAgICAke3RoaXMuX2dldFJlbmRlcmVkQ29hY2hCb3JkZXJzKGNvYWNoSXRlbSwgY29hY2hEZWNrSW5kZXgsIGNvYWNoSW5kZXgpfVxuICAgICAgJHt0aGlzLl9nZXRSZW5kZXJlZENvYWNoRWxlbWVudHMoY29hY2hEZWNrSW5kZXgsIGNvYWNoSW5kZXgpfVxuICAgICAgJHt0aGlzLl9nZXRSZW5kZXJlZEFyZWFFbGVtZW50cyhjb2FjaERlY2tJbmRleCwgY29hY2hJbmRleCl9XG4gICAgICAke3RoaXMuX2dldFJlbmRlcmVkU2VydmljZUVsZW1lbnRzKGNvYWNoRGVja0luZGV4LCBjb2FjaEluZGV4KX1cblxuICAgICAgPHRhYmxlXG4gICAgICAgIEBmb2N1cz0keygpID0+IHRoaXMub25Gb2N1c1RhYmxlQ29hY2hBbmRQcmVzZWxlY3RQbGFjZShjb2FjaEluZGV4KX1cbiAgICAgICAgaWQ9XCJzYmItc3ItY29hY2gtJHtjb2FjaEluZGV4fVwiXG4gICAgICAgIGNsYXNzPVwic2JiLXNyLWNvYWNoLXdyYXBwZXJfX3RhYmxlXCJcbiAgICAgICAgYXJpYS1kZXNjcmliZWRieT1cInNiYi1zci1jb2FjaC1jYXB0aW9uLSR7Y29hY2hJbmRleH1cIlxuICAgICAgICB0YWJpbmRleD1cIi0xXCJcbiAgICAgID5cbiAgICAgICAgPGNhcHRpb24gaWQ9XCJzYmItc3ItY29hY2gtY2FwdGlvbi0ke2NvYWNoSW5kZXh9XCIgdGFiaW5kZXg9XCItMVwiPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2JiLXNjcmVlbi1yZWFkZXItb25seVwiPiR7ZGVzY3JpcHRpb25UYWJsZUNvYWNoV2l0aFNlcnZpY2VzfTwvc3Bhbj5cbiAgICAgICAgPC9jYXB0aW9uPlxuICAgICAgICAke3RoaXMuX2dldFJlbmRlcmVkUm93UGxhY2VzKGNvYWNoSXRlbSwgY29hY2hJbmRleCwgY29hY2hEZWNrSW5kZXgsIHBsYWNlQ29hY2hEZWNrSW5kZXgpfVxuICAgICAgPC90YWJsZT5cbiAgICA8L3NiYi1zZWF0LXJlc2VydmF0aW9uLXNjb3BlZD5gO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIFJldHVybnMgdGhlIGJvcmRlciBncmFwaGljIChDT0FDSF9CT1JERVJfTUlERExFKSBvZiBhIGNvYWNoIHdpdGggY2FsY3VsYXRlZCBib3JkZXIgZ2FwIGFuZCBjb2FjaCB3aWR0aCxcbiAgICogZGVwZW5kaW5nIG9uIHdoZXRoZXIgdGhlIGNvYWNoIGlzIHdpdGggYSBkcml2ZXIgYXJlYSBvciB3aXRob3V0LlxuICAgKi9cbiAgcHJpdmF0ZSBfZ2V0UmVuZGVyZWRDb2FjaEJvcmRlcnMoXG4gICAgY29hY2hJdGVtOiBDb2FjaEl0ZW0sXG4gICAgZGVja0NvYWNoSW5kZXg6IG51bWJlcixcbiAgICBjb2FjaEluZGV4OiBudW1iZXIsXG4gICk6IFRlbXBsYXRlUmVzdWx0IHwgbnVsbCB7XG4gICAgaWYgKCFjb2FjaEl0ZW0uZ3JhcGhpY0VsZW1lbnRzKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBjdXJyQ29hY2hTdHJ1Y3R1cmUgPVxuICAgICAgdGhpcy5zZWF0UmVzZXJ2YXRpb25TdHJ1Y3R1cmUuZGVja3NbZGVja0NvYWNoSW5kZXhdLmRlY2tDb2FjaGVzW2NvYWNoSW5kZXhdO1xuICAgIGNvbnN0IGNvYWNoQm9yZGVyRWxlbWVudCA9IGN1cnJDb2FjaFN0cnVjdHVyZS5ib3JkZXJNaWRkbGVFbGVtZW50O1xuICAgIGNvbnN0IGhhc092ZXJoYW5naW5nRWxlbWVudHMgPSBjdXJyQ29hY2hTdHJ1Y3R1cmUuaGFzT3ZlcmhhbmdpbmdFbGVtZW50cztcblxuICAgIHJldHVybiBodG1sYFxuICAgICAgPHNiYi1zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWNcbiAgICAgICAgY2xhc3M9XCIke2NsYXNzTWFwKHtcbiAgICAgICAgICAnc2JiLXNyLWNvYWNoLWhhcy1vdmVyaGFuZ2luZy1lbGVtZW50cyc6IGhhc092ZXJoYW5naW5nRWxlbWVudHMgfHwgZmFsc2UsXG4gICAgICAgIH0pfVwiXG4gICAgICAgIHN0eWxlPSR7c3R5bGVNYXAoe1xuICAgICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWMtd2lkdGgnOiBjb2FjaEJvcmRlckVsZW1lbnQuZGltZW5zaW9uLncsXG4gICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JhcGhpYy1oZWlnaHQnOiBjb2FjaEJvcmRlckVsZW1lbnQuZGltZW5zaW9uLmgsXG4gICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JhcGhpYy10b3AnOiBjb2FjaEJvcmRlckVsZW1lbnQucG9zaXRpb24ueSxcbiAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljLWxlZnQnOiBjb2FjaEJvcmRlckVsZW1lbnQucG9zaXRpb24ueCxcbiAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljLXBvc2l0aW9uJzogJ2Fic29sdXRlJyxcbiAgICAgICAgfSl9XG4gICAgICAgIG5hbWU9XCJDT0FDSF9CT1JERVJfTUlERExFXCJcbiAgICAgICAgP3N0cmV0Y2g9JHt0cnVlfVxuICAgICAgICByb2xlPVwicHJlc2VudGF0aW9uXCJcbiAgICAgID48L3NiYi1zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWM+XG4gICAgYDtcbiAgfVxuXG4gIHByaXZhdGUgX2dldFJlbmRlcmVkUm93UGxhY2VzKFxuICAgIGNvYWNoOiBDb2FjaEl0ZW0sXG4gICAgY29hY2hJbmRleDogbnVtYmVyLFxuICAgIGNvYWNoRGVja0luZGV4OiBudW1iZXIsXG4gICAgcGxhY2VDb2FjaERlY2tJbmRleDogbnVtYmVyLFxuICApOiBUZW1wbGF0ZVJlc3VsdFtdIHwgbnVsbCB7XG4gICAgaWYgKCFjb2FjaC5wbGFjZXMpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICAvLyBQcmVwYXJlIHJvd3Mgd2l0aCB0aGUgcGxhY2VzIHRvIHJlbmRlciBhIHRhYmxlXG4gICAgY29uc3QgdGFibGVSb3dQbGFjZXM6IFJlY29yZDxudW1iZXIsIFBsYWNlW10+ID0ge307XG4gICAgZm9yIChjb25zdCBwbGFjZSBvZiBjb2FjaC5wbGFjZXMpIHtcbiAgICAgIGlmICghdGFibGVSb3dQbGFjZXNbcGxhY2UucG9zaXRpb24ueV0pIHtcbiAgICAgICAgdGFibGVSb3dQbGFjZXNbcGxhY2UucG9zaXRpb24ueV0gPSBbcGxhY2VdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGFibGVSb3dQbGFjZXNbcGxhY2UucG9zaXRpb24ueV0ucHVzaChwbGFjZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIE9iamVjdC52YWx1ZXModGFibGVSb3dQbGFjZXMpXG4gICAgICAubWFwKChyb3dQbGFjZXM6IFBsYWNlW10sIGluZGV4KSA9PiB7XG4gICAgICAgIHJldHVybiBodG1sYFxuICAgICAgICAgIDx0ciBpZD1cInJvdy0ke2NvYWNoSW5kZXh9LSR7cm93UGxhY2VzWzBdLnBvc2l0aW9uLnl9XCIgZGF0YS1yb3ctaW5kZXg9JHtpbmRleH0+XG4gICAgICAgICAgICAke3RoaXMuX2dldFJlbmRlcmVkQ29sdW1uUGxhY2VzKFxuICAgICAgICAgICAgICByb3dQbGFjZXMsXG4gICAgICAgICAgICAgIGNvYWNoSW5kZXgsXG4gICAgICAgICAgICAgIGNvYWNoRGVja0luZGV4LFxuICAgICAgICAgICAgICBwbGFjZUNvYWNoRGVja0luZGV4LFxuICAgICAgICAgICAgKX1cbiAgICAgICAgICA8L3RyPlxuICAgICAgICBgO1xuICAgICAgfSlcbiAgICAgIC5mbGF0TWFwKChyb3dUZW1wbGF0ZSkgPT4gcm93VGVtcGxhdGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0UmVuZGVyZWRDb2x1bW5QbGFjZXMoXG4gICAgcGxhY2VzOiBQbGFjZVtdLFxuICAgIGNvYWNoSW5kZXg6IG51bWJlcixcbiAgICBkZWNrSW5kZXg6IG51bWJlcixcbiAgICBwbGFjZUNvYWNoRGVja0luZGV4OiBudW1iZXIsXG4gICk6IFRlbXBsYXRlUmVzdWx0IHwgbnVsbCB7XG4gICAgLy9Tb3J0cyBlYWNoIHBsYWNlIGJ5IGl0cyBhc2NlbmRpbmcgeCBjb29yZGluYXRlXG4gICAgcGxhY2VzLnNvcnQoXG4gICAgICAocGxhY2VBOiBQbGFjZSwgcGxhY2VCOiBQbGFjZSkgPT4gTnVtYmVyKHBsYWNlQS5wb3NpdGlvbi54KSAtIE51bWJlcihwbGFjZUIucG9zaXRpb24ueCksXG4gICAgKTtcblxuICAgIC8vIEZvciByZW5kZXJpbmcgdGhlIHBsYWNlcyB3aXRoaW4gYSB0ZCBlbGVtZW50LCBoZXJlIHdlIHVzZSByZXBlYXQgZGlyZWN0aXZlIGZvciBiZXR0ZXIgcGVyZm9ybWFuY2UgZm9yIHJldXNpbmcgZWxlbWVudHMgKHRyYWNrIGJ5IGlkKS5cbiAgICBjb25zdCB0cmFja1BsYWNlSWQgPSBjb2FjaEluZGV4ICsgJy0nICsgcGxhY2VDb2FjaERlY2tJbmRleDtcbiAgICByZXR1cm4gaHRtbGAke3JlcGVhdChcbiAgICAgIHBsYWNlcyxcbiAgICAgIChwbGFjZSkgPT4gdHJhY2tQbGFjZUlkICsgJy0nICsgcGxhY2UubnVtYmVyLFxuICAgICAgKHBsYWNlLCBpbmRleCkgPT4ge1xuICAgICAgICBjb25zdCBjYWxjdWxhdGVkRGltZW5zaW9uID0gdGhpcy5nZXRDYWxjdWxhdGVkRGltZW5zaW9uKHBsYWNlLmRpbWVuc2lvbik7XG4gICAgICAgIGNvbnN0IGNhbGN1bGF0ZWRQb3NpdGlvbiA9IHRoaXMuZ2V0Q2FsY3VsYXRlZFBvc2l0aW9uKHBsYWNlLnBvc2l0aW9uKTtcbiAgICAgICAgY29uc3Qgcm90YXRpb24gPSBwbGFjZS5yb3RhdGlvbiB8fCAwO1xuICAgICAgICBjb25zdCB0ZXh0Um90YXRpb24gPSB0aGlzLmFsaWduVmVydGljYWwgPyAtOTAgOiAwO1xuICAgICAgICBjb25zdCBwbGFjZUlkID0gdGhpcy5nZXRQbGFjZUVsZW1lbnRJZChkZWNrSW5kZXgsIGNvYWNoSW5kZXgsIHBsYWNlLm51bWJlcik7XG4gICAgICAgIHJldHVybiBodG1sYFxuICAgICAgICAgIDx0ZFxuICAgICAgICAgICAgaWQ9XCJjZWxsLSR7ZGVja0luZGV4fS0ke2NvYWNoSW5kZXh9LSR7cGxhY2UucG9zaXRpb24ueX0tJHtpbmRleH1cIlxuICAgICAgICAgICAgY2xhc3M9XCJncmFwaGljYWwtZWxlbWVudFwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHNiYi1zZWF0LXJlc2VydmF0aW9uLXBsYWNlLWNvbnRyb2xcbiAgICAgICAgICAgICAgc3R5bGU9JHtzdHlsZU1hcCh7XG4gICAgICAgICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tcGxhY2UtY29udHJvbC10ZXh0LXNjYWxlLXZhbHVlJzogTWF0aC5taW4oXG4gICAgICAgICAgICAgICAgICBjYWxjdWxhdGVkRGltZW5zaW9uLncsXG4gICAgICAgICAgICAgICAgICBjYWxjdWxhdGVkRGltZW5zaW9uLmgsXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1wbGFjZS1jb250cm9sLXdpZHRoJzogY2FsY3VsYXRlZERpbWVuc2lvbi53LFxuICAgICAgICAgICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLXBsYWNlLWNvbnRyb2wtaGVpZ2h0JzogY2FsY3VsYXRlZERpbWVuc2lvbi5oLFxuICAgICAgICAgICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLXBsYWNlLWNvbnRyb2wtdG9wJzogY2FsY3VsYXRlZFBvc2l0aW9uLnksXG4gICAgICAgICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tcGxhY2UtY29udHJvbC1sZWZ0JzogY2FsY3VsYXRlZFBvc2l0aW9uLngsXG4gICAgICAgICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tcGxhY2UtY29udHJvbC1yb3RhdGlvbic6IHJvdGF0aW9uLFxuICAgICAgICAgICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLXBsYWNlLWNvbnRyb2wtdGV4dC1yb3RhdGlvbic6IHRleHRSb3RhdGlvbixcbiAgICAgICAgICAgICAgfSl9XG4gICAgICAgICAgICAgIEBzZWxlY3RwbGFjZT0keyhzZWxlY3RQbGFjZUV2ZW50OiBTYmJQbGFjZVNlbGVjdGlvbkV2ZW50KSA9PlxuICAgICAgICAgICAgICAgIHRoaXMuX29uU2VsZWN0UGxhY2Uoc2VsZWN0UGxhY2VFdmVudCl9XG4gICAgICAgICAgICAgIGV4cG9ydHBhcnRzPVwic2JiLXNyLXBsYWNlLXBhcnRcIlxuICAgICAgICAgICAgICBpZD0ke3BsYWNlSWR9XG4gICAgICAgICAgICAgIGNsYXNzPVwic2VhdC1yZXNlcnZhdGlvbi1wbGFjZS1jb250cm9sXCJcbiAgICAgICAgICAgICAgdGV4dD0ke3BsYWNlLm51bWJlcn1cbiAgICAgICAgICAgICAgdHlwZT0ke3BsYWNlLnR5cGV9XG4gICAgICAgICAgICAgIHN0YXRlPSR7cGxhY2Uuc3RhdGV9XG4gICAgICAgICAgICAgIHRyYXZlbC1kaXJlY3Rpb249JHt0aGlzLnRyYXZlbERpcmVjdGlvbn1cbiAgICAgICAgICAgICAgY29hY2gtaW5kZXg9JHtjb2FjaEluZGV4fVxuICAgICAgICAgICAgICBkZWNrLWluZGV4PSR7cGxhY2VDb2FjaERlY2tJbmRleH1cbiAgICAgICAgICAgICAgZGF0YS1kZWNrLWluZGV4PSR7ZGVja0luZGV4fVxuICAgICAgICAgICAgICAucHJvcGVydHlJZHM9JHtwbGFjZS5wcm9wZXJ0eUlkc31cbiAgICAgICAgICAgICAgLnByZXZlbnRDbGljaz0ke3RoaXMucHJldmVudFBsYWNlQ2xpY2t9XG4gICAgICAgICAgICAgID9zaG93VGl0bGVJbmZvPVwiJHt0aGlzLnNob3dUaXRsZUluZm99XCJcbiAgICAgICAgICAgID48L3NiYi1zZWF0LXJlc2VydmF0aW9uLXBsYWNlLWNvbnRyb2w+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgYDtcbiAgICAgIH0sXG4gICAgKX1gO1xuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0UmVuZGVyZWRDb2FjaEVsZW1lbnRzKFxuICAgIGNvYWNoRGVja0luZGV4OiBudW1iZXIsXG4gICAgY29hY2hJbmRleDogbnVtYmVyLFxuICApOiBUZW1wbGF0ZVJlc3VsdFtdIHwgbnVsbCB7XG4gICAgY29uc3QgY3VyckNvYWNoU3RydWN0dXJlID1cbiAgICAgIHRoaXMuc2VhdFJlc2VydmF0aW9uU3RydWN0dXJlLmRlY2tzW2NvYWNoRGVja0luZGV4XS5kZWNrQ29hY2hlc1tjb2FjaEluZGV4XTtcblxuICAgIHJldHVybiBjdXJyQ29hY2hTdHJ1Y3R1cmUub3RoZXJFbGVtZW50cy5tYXAoKGdyYXBoaWNFbGVtZW50KSA9PiB7XG4gICAgICByZXR1cm4gaHRtbGAgPHNiYi1zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWNcbiAgICAgICAgc3R5bGU9JHtzdHlsZU1hcCh7XG4gICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JhcGhpYy13aWR0aCc6IGdyYXBoaWNFbGVtZW50LmRpbWVuc2lvbi53LFxuICAgICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWMtaGVpZ2h0JzogZ3JhcGhpY0VsZW1lbnQuZGltZW5zaW9uLmgsXG4gICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JhcGhpYy10b3AnOiBncmFwaGljRWxlbWVudC5wb3NpdGlvbi55LFxuICAgICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWMtbGVmdCc6IGdyYXBoaWNFbGVtZW50LnBvc2l0aW9uLngsXG4gICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JhcGhpYy1wb3NpdGlvbic6ICdhYnNvbHV0ZScsXG4gICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JhcGhpYy1yb3RhdGlvbic6IGdyYXBoaWNFbGVtZW50LnJvdGF0aW9uLFxuICAgICAgICB9KX1cbiAgICAgICAgbmFtZT0ke2dyYXBoaWNFbGVtZW50Lmljb24gPz8gbm90aGluZ31cbiAgICAgICAgYXJpYS1oaWRkZW49XCJ0cnVlXCJcbiAgICAgICAgP3N0cmV0Y2g9JHt0cnVlfVxuICAgICAgPjwvc2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JhcGhpYz5gO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0UmVuZGVyZWRBcmVhRWxlbWVudHMoXG4gICAgY29hY2hEZWNrSW5kZXg6IG51bWJlcixcbiAgICBjb2FjaEluZGV4OiBudW1iZXIsXG4gICk6IFRlbXBsYXRlUmVzdWx0W10gfCBudWxsIHtcbiAgICBjb25zdCBjdXJyQ29hY2hTdHJ1Y3R1cmUgPVxuICAgICAgdGhpcy5zZWF0UmVzZXJ2YXRpb25TdHJ1Y3R1cmUuZGVja3NbY29hY2hEZWNrSW5kZXhdLmRlY2tDb2FjaGVzW2NvYWNoSW5kZXhdO1xuXG4gICAgcmV0dXJuIGN1cnJDb2FjaFN0cnVjdHVyZS5hcmVhRWxlbWVudHMubWFwKChncmFwaGljRWxlbWVudCkgPT4ge1xuICAgICAgY29uc3QgdHJpZ2dlcklkID0gYHBvcG92ZXItdHJpZ2dlci0ke2NvYWNoRGVja0luZGV4fS0ke2NvYWNoSW5kZXh9LSR7Z3JhcGhpY0VsZW1lbnQucG9zaXRpb24ueH0tJHtncmFwaGljRWxlbWVudC5wb3NpdGlvbi55fWA7XG4gICAgICBjb25zdCBpc05vdFRhYmxlR3JhcGhpYyA9IGdyYXBoaWNFbGVtZW50Lmljb24/LmluZGV4T2YoJ1RBQkxFJykgPT09IC0xO1xuICAgICAgY29uc3QgYXJlYVByb3BlcnR5ID0gZ3JhcGhpY0VsZW1lbnQuaWNvbiAmJiBpc05vdFRhYmxlR3JhcGhpYyA/IGdyYXBoaWNFbGVtZW50Lmljb24gOiBudWxsO1xuICAgICAgY29uc3QgYXJpYUxhYmVsRm9yQXJlYSA9IGdyYXBoaWNFbGVtZW50Lmljb25cbiAgICAgICAgPyBnZXRJMThuU2VhdFJlc2VydmF0aW9uKGdyYXBoaWNFbGVtZW50Lmljb24sIHRoaXMuX2xhbmd1YWdlLmN1cnJlbnQpXG4gICAgICAgIDogbm90aGluZztcblxuICAgICAgcmV0dXJuIGh0bWxgXG4gICAgICAgIDxzYmItc2VhdC1yZXNlcnZhdGlvbi1hcmVhXG4gICAgICAgICAgaWQ9XCIke3RyaWdnZXJJZH1cIlxuICAgICAgICAgIGNsYXNzPVwiJHtjbGFzc01hcCh7XG4gICAgICAgICAgICAnc2JiLXNlYXQtcmVzZXJ2YXRpb24tYXJlYS0tY3Vyc29yLXBvaW50ZXInOiBhcmVhUHJvcGVydHkgIT09IG51bGwsXG4gICAgICAgICAgfSl9XCJcbiAgICAgICAgICBzdHlsZT0ke3N0eWxlTWFwKHtcbiAgICAgICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLWFyZWEtd2lkdGgnOiBncmFwaGljRWxlbWVudC5kaW1lbnNpb24udyxcbiAgICAgICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLWFyZWEtaGVpZ2h0JzogZ3JhcGhpY0VsZW1lbnQuZGltZW5zaW9uLmgsXG4gICAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1hcmVhLXRvcCc6IGdyYXBoaWNFbGVtZW50LnBvc2l0aW9uLnksXG4gICAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1hcmVhLWxlZnQnOiBncmFwaGljRWxlbWVudC5wb3NpdGlvbi54LFxuICAgICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tYXJlYS16LWluZGV4JzogZ3JhcGhpY0VsZW1lbnQucG9zaXRpb24ueixcbiAgICAgICAgICB9KX1cbiAgICAgICAgICBtb3VudGluZz0ke2dyYXBoaWNFbGVtZW50Lm1vdW50aW5nID8/IG5vdGhpbmd9XG4gICAgICAgICAgYmFja2dyb3VuZD1cImRhcmtcIlxuICAgICAgICAgIGFyaWEtaGlkZGVuPVwidHJ1ZVwiXG4gICAgICAgID5cbiAgICAgICAgICAke2FyZWFQcm9wZXJ0eVxuICAgICAgICAgICAgPyBodG1sYFxuICAgICAgICAgICAgICAgIDxzYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljXG4gICAgICAgICAgICAgICAgICBzdHlsZT0ke3N0eWxlTWFwKHtcbiAgICAgICAgICAgICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JhcGhpYy1tYXgtd2lkdGgnOiB0aGlzLmdsb2JhbEFyZWFJY29uRGltLncsXG4gICAgICAgICAgICAgICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWMtbWF4LWhlaWdodCc6IHRoaXMuZ2xvYmFsQXJlYUljb25EaW0uaCxcbiAgICAgICAgICAgICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JhcGhpYy13aWR0aCc6IGdyYXBoaWNFbGVtZW50LmRpbWVuc2lvbi53LFxuICAgICAgICAgICAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljLWhlaWdodCc6IGdyYXBoaWNFbGVtZW50LmRpbWVuc2lvbi5oLFxuICAgICAgICAgICAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljLXJvdGF0aW9uJzogZ3JhcGhpY0VsZW1lbnQucm90YXRpb24sXG4gICAgICAgICAgICAgICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWMtcGFkZGluZy1wZXJjZW50JzpcbiAgICAgICAgICAgICAgICAgICAgICBhcmVhUHJvcGVydHkgIT09ICdFTlRSWV9FWElUJyA/IHRoaXMuZ2xvYmFsQXJlYUljb25QYWRkaW5nIDogMSxcbiAgICAgICAgICAgICAgICAgIH0pfVxuICAgICAgICAgICAgICAgICAgbmFtZT0ke2FyZWFQcm9wZXJ0eX1cbiAgICAgICAgICAgICAgICAgIHJvbGU9XCJpbWdcIlxuICAgICAgICAgICAgICAgICAgYXJpYS1oaWRkZW49XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgIGNsYXNzPVwic2JiLXNyLWdyYXBoaWNfX2RpbWVuc2lvbi0tc3F1YXJlLWRpbVwiXG4gICAgICAgICAgICAgICAgPjwvc2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JhcGhpYz5cbiAgICAgICAgICAgICAgYFxuICAgICAgICAgICAgOiBub3RoaW5nfVxuICAgICAgICA8L3NiYi1zZWF0LXJlc2VydmF0aW9uLWFyZWE+XG4gICAgICAgICR7YXJlYVByb3BlcnR5ID8gdGhpcy5fcG9wb3Zlcih0cmlnZ2VySWQsIGFyaWFMYWJlbEZvckFyZWEpIDogbm90aGluZ31cbiAgICAgIGA7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9nZXRSZW5kZXJlZFNlcnZpY2VFbGVtZW50cyhcbiAgICBjb2FjaERlY2tJbmRleDogbnVtYmVyLFxuICAgIGNvYWNoSW5kZXg6IG51bWJlcixcbiAgKTogVGVtcGxhdGVSZXN1bHRbXSB8IG51bGwge1xuICAgIGNvbnN0IGN1cnJDb2FjaFN0cnVjdHVyZSA9XG4gICAgICB0aGlzLnNlYXRSZXNlcnZhdGlvblN0cnVjdHVyZS5kZWNrc1tjb2FjaERlY2tJbmRleF0uZGVja0NvYWNoZXNbY29hY2hJbmRleF07XG5cbiAgICByZXR1cm4gY3VyckNvYWNoU3RydWN0dXJlLnNlcnZpY2VFbGVtZW50cy5tYXAoKHNlcnZpY2VFbGVtZW50OiBCYXNlRWxlbWVudCkgPT4ge1xuICAgICAgLy9nZW5lcmF0ZSB1bmlxdWUgaW5kZXggbnVtYmVyIGZvciB0aGUgdHJpZ2dlciBlbGVtZW50XG4gICAgICBjb25zdCB0cmlnZ2VySWQgPSBgcG9wb3Zlci10cmlnZ2VyLSR7Y29hY2hEZWNrSW5kZXh9LSR7Y29hY2hJbmRleH0tJHtzZXJ2aWNlRWxlbWVudC5wb3NpdGlvbi54fS0ke3NlcnZpY2VFbGVtZW50LnBvc2l0aW9uLnl9YDtcbiAgICAgIGNvbnN0IHRpdGxlRGVzY3JpcHRpb24gPSBzZXJ2aWNlRWxlbWVudC5pY29uXG4gICAgICAgID8gZ2V0STE4blNlYXRSZXNlcnZhdGlvbihzZXJ2aWNlRWxlbWVudC5pY29uLCB0aGlzLl9sYW5ndWFnZS5jdXJyZW50KVxuICAgICAgICA6IG51bGw7XG5cbiAgICAgIHJldHVybiBodG1sYFxuICAgICAgICA8c2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JhcGhpY1xuICAgICAgICAgIGlkPVwiJHt0cmlnZ2VySWR9XCJcbiAgICAgICAgICBzdHlsZT0ke3N0eWxlTWFwKHtcbiAgICAgICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWMtd2lkdGgnOiBzZXJ2aWNlRWxlbWVudC5kaW1lbnNpb24udyxcbiAgICAgICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWMtaGVpZ2h0Jzogc2VydmljZUVsZW1lbnQuZGltZW5zaW9uLmgsXG4gICAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljLXRvcCc6IHNlcnZpY2VFbGVtZW50LnBvc2l0aW9uLnksXG4gICAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljLWxlZnQnOiBzZXJ2aWNlRWxlbWVudC5wb3NpdGlvbi54LFxuICAgICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JhcGhpYy1wb3NpdGlvbic6ICdhYnNvbHV0ZScsXG4gICAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljLXJvdGF0aW9uJzogc2VydmljZUVsZW1lbnQucm90YXRpb24sXG4gICAgICAgICAgfSl9XG4gICAgICAgICAgY2xhc3M9XCJzYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljLS1jdXJzb3ItcG9pbnRlclwiXG4gICAgICAgICAgbmFtZT0ke3NlcnZpY2VFbGVtZW50Lmljb24gPz8gbm90aGluZ31cbiAgICAgICAgICByb2xlPVwiaW1nXCJcbiAgICAgICAgICBhcmlhLWhpZGRlbj1cInRydWVcIlxuICAgICAgICA+PC9zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljPlxuICAgICAgICAke3RoaXMuX3BvcG92ZXIodHJpZ2dlcklkLCB0aXRsZURlc2NyaXB0aW9uKX1cbiAgICAgIGA7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogTWFuYWdlcyB0aGUgc2VsZWN0ZWQgcGxhY2UgZXZlbnQgdHJpZ2dlcmVkIGZyb20gdGhlIHBsYWNlXG4gICAqIEVhY2ggc2VsZWN0aW9uIGVtaXRzIGFuIGFycmF5IG9mIGFsbCBzZWxlY3RlZCBwbGFjZXNcbiAgICogQHBhcmFtIHNlbGVjdFBsYWNlRXZlbnRcbiAgICovXG4gIHByaXZhdGUgX29uU2VsZWN0UGxhY2Uoc2VsZWN0UGxhY2VFdmVudDogU2JiUGxhY2VTZWxlY3Rpb25FdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IHNlbGVjdGVkUGxhY2UgPSBzZWxlY3RQbGFjZUV2ZW50LmRldGFpbDtcbiAgICAvLyBXZSBoYXZlIHRvIHNldCBwcmV2ZW50Q29hY2hTY3JvbGxCeVBsYWNlQ2xpY2sgdG8gdHJ1ZSwgdG8gcHJldmVudCBhdXRvbWF0aWMgc2Nyb2xsaW5nIHRvIHRoZSBuZXcgZm9jdXNlZCBwbGFjZVxuICAgIHRoaXMucHJldmVudENvYWNoU2Nyb2xsQnlQbGFjZUNsaWNrID0gdHJ1ZTtcbiAgICB0aGlzLmlzQ29hY2hHcmlkRm9jdXNhYmxlID0gZmFsc2U7XG4gICAgdGhpcy5mb2N1c2VkQ29hY2hJbmRleCA9IC0xO1xuICAgIC8vIENoZWNrIGFueSBrZXlib2FyZCBldmVudCB3YXMgdHJpZ2dlcmVkIGluc2lkZSB0aGUgc2VhdCByZXNlcnZhdGlvbiBjb21wb25lbnQsXG4gICAgLy8gc28gd2UgY2FuIHNheSB0aGUgbmF0aXZlIGJyb3dzZXIgZm9jdXMgbGllcyBvbiB0aGUgY29tcG9uZW50XG4gICAgaWYgKCF0aGlzLmhhc1NlYXRSZXNlcnZhdGlvbk5hdGl2ZUZvY3VzKSB7XG4gICAgICB0aGlzLmhhc1NlYXRSZXNlcnZhdGlvbk5hdGl2ZUZvY3VzID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMucHJldmVudFBsYWNlQ2xpY2spIHtcbiAgICAgIC8vIEFkZCBwbGFjZSB0byBwbGFjZSBjb2xsZWN0aW9uXG4gICAgICB0aGlzLnVwZGF0ZVNlbGVjdGVkU2VhdFJlc2VydmF0aW9uUGxhY2VzKHNlbGVjdGVkUGxhY2UpO1xuICAgICAgdGhpcy51cGRhdGVDdXJyZW50U2VsZWN0ZWRQbGFjZUluQ29hY2goc2VsZWN0ZWRQbGFjZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfb25TZWxlY3ROYXZDb2FjaChldmVudDogU2JiU2VsZWN0Q29hY2hFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IHNlbGVjdGVkTmF2Q29hY2hJbmRleCA9IGV2ZW50LmNvYWNoSW5kZXg7XG5cbiAgICB0aGlzLmlzS2V5Ym9hcmROYXZpZ2F0aW9uID0gZmFsc2U7XG4gICAgdGhpcy5wcmV2ZW50Q29hY2hTY3JvbGxCeVBsYWNlQ2xpY2sgPSBmYWxzZTtcbiAgICB0aGlzLmhhc1NlYXRSZXNlcnZhdGlvbk5hdGl2ZUZvY3VzID0gdHJ1ZTtcblxuICAgIGlmIChzZWxlY3RlZE5hdkNvYWNoSW5kZXggIT09IG51bGwgJiYgc2VsZWN0ZWROYXZDb2FjaEluZGV4ICE9PSB0aGlzLmN1cnJTZWxlY3RlZENvYWNoSW5kZXgpIHtcbiAgICAgIHRoaXMudW5mb2N1c1BsYWNlRWxlbWVudCgpO1xuICAgICAgdGhpcy5zY3JvbGxUb1NlbGVjdGVkTmF2Q29hY2goc2VsZWN0ZWROYXZDb2FjaEluZGV4KTtcbiAgICB9IGVsc2UgaWYgKHNlbGVjdGVkTmF2Q29hY2hJbmRleCA9PT0gdGhpcy5jdXJyU2VsZWN0ZWRDb2FjaEluZGV4KSB7XG4gICAgICB0aGlzLnVwZGF0ZUN1cnJlbnRTZWxlY3RlZENvYWNoKCk7XG4gICAgICB0aGlzLnByZXNlbGVjdFBsYWNlSW5Db2FjaCgpO1xuICAgIH1cblxuICAgIC8vY2xvc2UgYWxsIG9wZW5lZCBwb3BvdmVyc1xuICAgIHRoaXMuX2Nsb3NlUG9wb3ZlcigpO1xuICB9XG5cbiAgcHJpdmF0ZSBfb25Gb2N1c05hdkNvYWNoKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5wcmV2ZW50Q29hY2hTY3JvbGxCeVBsYWNlQ2xpY2spIHtcbiAgICAgIHRoaXMucHJlc2VsZWN0UGxhY2VJbkNvYWNoKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZm9jdXNQbGFjZUVsZW1lbnQodGhpcy5jdXJyU2VsZWN0ZWRQbGFjZSk7XG4gICAgfVxuXG4gICAgdGhpcy5pc0F1dG9TY3JvbGxpbmcgPSBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgcG9wb3ZlciBmb3IgZXh0cmEgc2VydmljZSBpbmZvcm1hdGlvblxuICAgKiBAcGFyYW0gdHJpZ2dlcklkXG4gICAqIEBwYXJhbSBwb3BvdmVyQ29udGVudFxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBfcG9wb3ZlcihcbiAgICB0cmlnZ2VySWQ6IHN0cmluZyxcbiAgICBwb3BvdmVyQ29udGVudDogc3RyaW5nIHwgbnVsbCB8IHR5cGVvZiBub3RoaW5nLFxuICApOiBUZW1wbGF0ZVJlc3VsdCB7XG4gICAgcmV0dXJuIGh0bWxgXG4gICAgICA8c2JiLXBvcG92ZXIgdHJpZ2dlcj1cIiR7dHJpZ2dlcklkfVwiIGhvdmVyLXRyaWdnZXI9XCJcIj5cbiAgICAgICAgPHAgY2xhc3M9XCJzYmItdGV4dC1zIHNiYi1zci1wb3BvdmVyXCI+JHtwb3BvdmVyQ29udGVudH08L3A+XG4gICAgICA8L3NiYi1wb3BvdmVyPlxuICAgIGA7XG4gIH1cblxuICAvKipcbiAgICogdHJpZ2dlciB0byBjbG9zZSBhbGwgb3BlbmVkIHBvcG92ZXJzIChub3JtYWxseSBvbmx5IG9uZSBpcyBvcGVuZWQgYXQgYSB0aW1lKVxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBfY2xvc2VQb3BvdmVyKCk6IHZvaWQge1xuICAgIHRoaXMuc2hhZG93Um9vdFxuICAgICAgPy5xdWVyeVNlbGVjdG9yQWxsPFNiYlBvcG92ZXJFbGVtZW50Pignc2JiLXBvcG92ZXI6c3RhdGUoc3RhdGUtb3BlbmVkKScpXG4gICAgICAuZm9yRWFjaCgocG9wb3ZlcikgPT4gcG9wb3Zlci5jbG9zZSgpKTtcbiAgfVxuXG4gIHByaXZhdGUgX2dldERlc2NyaXB0aW9uVGFibGVDb2FjaChjb2FjaEl0ZW06IENvYWNoSXRlbSk6IHN0cmluZyB7XG4gICAgLy9zaG93IGRpZmZlcmVudCB0YWJsZSBjYXB0aW9uIGZvciBzY3JlZW5yZWFkZXIgaWYgaXQgaXMgYSBsb2NvbW90aXZlXG4gICAgaWYgKGNvYWNoSXRlbS50eXBlID09PSAnTE9DT01PVElWRV9DT0FDSCcpIHtcbiAgICAgIHJldHVybiBnZXRJMThuU2VhdFJlc2VydmF0aW9uKCdDT0FDSF9MT0NPTU9USVZFJywgdGhpcy5fbGFuZ3VhZ2UuY3VycmVudCk7XG4gICAgfVxuXG4gICAgaWYgKCFjb2FjaEl0ZW0ucGxhY2VzPy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBnZXRJMThuU2VhdFJlc2VydmF0aW9uKCdDT0FDSF9CTE9DS0VEX1RBQkxFX0NBUFRJT04nLCB0aGlzLl9sYW5ndWFnZS5jdXJyZW50LCBbXG4gICAgICAgIGNvYWNoSXRlbS5pZCxcbiAgICAgIF0pO1xuICAgIH1cblxuICAgIGxldCB0YWJsZUNvYWNoRGVzY3JpcHRpb246IHN0cmluZztcbiAgICBjb25zdCBhcmVhRGVzY3JpcHRpb25zID0gdGhpcy5fZ2V0VGl0bGVEZXNjcmlwdGlvbkxpc3RTdHJpbmcoY29hY2hJdGVtLmdyYXBoaWNFbGVtZW50cyEpO1xuICAgIGNvbnN0IHNlcnZpY2VEZXNjcmlwdGlvbnMgPSB0aGlzLl9nZXRUaXRsZURlc2NyaXB0aW9uTGlzdFN0cmluZyhjb2FjaEl0ZW0uc2VydmljZUVsZW1lbnRzISk7XG5cbiAgICB0YWJsZUNvYWNoRGVzY3JpcHRpb24gPSBnZXRJMThuU2VhdFJlc2VydmF0aW9uKCdDT0FDSF9UQUJMRV9DQVBUSU9OJywgdGhpcy5fbGFuZ3VhZ2UuY3VycmVudCwgW1xuICAgICAgY29hY2hJdGVtLmlkLFxuICAgIF0pO1xuXG4gICAgaWYgKCF0aGlzLmhhc05hdmlnYXRpb24pIHtcbiAgICAgIC8vIEV4cGFuZHMgdGhlIG51bWJlciBvZiBhdmFpbGFibGUgc2VhdHMgYW5kIGJpY3ljbGUgc3BhY2VzIGFzIGluZm9cbiAgICAgIGNvbnN0IGZyZWVQbGFjZXMgPSB0aGlzLmdldEF2YWlsYWJsZUZyZWVQbGFjZXNOdW1Gcm9tQ29hY2goY29hY2hJdGVtLnBsYWNlcyk7XG4gICAgICBjb25zdCBmcmVlUGxhY2VzVHh0ID0gZ2V0STE4blNlYXRSZXNlcnZhdGlvbihcbiAgICAgICAgJ0NPQUNIX0FWQUlMQUJMRV9OVU1CRVJfT0ZfUExBQ0VTJyxcbiAgICAgICAgdGhpcy5fbGFuZ3VhZ2UuY3VycmVudCxcbiAgICAgICAgW2ZyZWVQbGFjZXMuc2VhdHMsIGZyZWVQbGFjZXMuYmljeWNsZXNdLFxuICAgICAgKTtcbiAgICAgIHRhYmxlQ29hY2hEZXNjcmlwdGlvbiA9IHRhYmxlQ29hY2hEZXNjcmlwdGlvbi5jb25jYXQoJy4gJykuY29uY2F0KGZyZWVQbGFjZXNUeHQpLmNvbmNhdCgnLiAnKTtcbiAgICB9XG5cbiAgICBpZiAoISFhcmVhRGVzY3JpcHRpb25zIHx8ICEhc2VydmljZURlc2NyaXB0aW9ucykge1xuICAgICAgdGFibGVDb2FjaERlc2NyaXB0aW9uICs9XG4gICAgICAgICcuICcgKyBnZXRJMThuU2VhdFJlc2VydmF0aW9uKCdDT0FDSF9BVkFJTEFCTEVfU0VSVklDRVMnLCB0aGlzLl9sYW5ndWFnZS5jdXJyZW50KSArICc6ICc7XG4gICAgICB0YWJsZUNvYWNoRGVzY3JpcHRpb24gKz0gc2VydmljZURlc2NyaXB0aW9ucyArICcsICcgKyBhcmVhRGVzY3JpcHRpb25zICsgJy4nO1xuICAgIH1cbiAgICByZXR1cm4gdGFibGVDb2FjaERlc2NyaXB0aW9uO1xuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0VGl0bGVEZXNjcmlwdGlvbkxpc3RTdHJpbmcoZGVzY3JpcHRpb25zRWxlbWVudHM6IEJhc2VFbGVtZW50W10pOiBzdHJpbmcge1xuICAgIGNvbnN0IHVuaXF1ZURlc2NyaXB0aW9uczogc3RyaW5nW10gPSBbXTtcblxuICAgIHJldHVybiBkZXNjcmlwdGlvbnNFbGVtZW50c1xuICAgICAgPy5tYXAoKGRlc2NyaXB0aW9uRWxlbWVudCkgPT4ge1xuICAgICAgICBjb25zdCBpY29uID0gZGVzY3JpcHRpb25FbGVtZW50Lmljb247XG4gICAgICAgIGlmICghaWNvbikge1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZGVzY3JpcHRpb25BbHJlYWR5RXhpc3QgPSB1bmlxdWVEZXNjcmlwdGlvbnMuaW5kZXhPZihpY29uKSA+IC0xO1xuICAgICAgICBjb25zdCB0cmFuc2xhdGlvbiA9IGdldEkxOG5TZWF0UmVzZXJ2YXRpb24oXG4gICAgICAgICAgZGVzY3JpcHRpb25FbGVtZW50Lmljb24hLFxuICAgICAgICAgIHRoaXMuX2xhbmd1YWdlLmN1cnJlbnQsXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IGlzVmFsaWREZXNjcmlwdGlvbiA9XG4gICAgICAgICAgdGhpcy5ub3RGaXhlZFJvdGF0YWJsZUFyZWFJY29ucy5pbmRleE9mKGljb24pID09PSAtMSAmJlxuICAgICAgICAgIHRoaXMubm90QXJlYUVsZW1lbnRzLmluZGV4T2YoaWNvbikgPT09IC0xO1xuXG4gICAgICAgIGlmICghZGVzY3JpcHRpb25BbHJlYWR5RXhpc3QpIHtcbiAgICAgICAgICB1bmlxdWVEZXNjcmlwdGlvbnMucHVzaChkZXNjcmlwdGlvbkVsZW1lbnQuaWNvbiEpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAhIXRyYW5zbGF0aW9uICYmICFkZXNjcmlwdGlvbkFscmVhZHlFeGlzdCAmJiBpc1ZhbGlkRGVzY3JpcHRpb24gPyB0cmFuc2xhdGlvbiA6IG51bGw7XG4gICAgICB9KVxuICAgICAgLmZpbHRlcigoZGVzY3JpcHRpb24pID0+ICEhZGVzY3JpcHRpb24pXG4gICAgICAuam9pbignLCAnKTtcbiAgfVxufVxuXG5kZWNsYXJlIGdsb2JhbCB7XG4gIGludGVyZmFjZSBIVE1MRWxlbWVudFRhZ05hbWVNYXAge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cbiAgICAnc2JiLXNlYXQtcmVzZXJ2YXRpb24nOiBTYmJTZWF0UmVzZXJ2YXRpb25FbGVtZW50O1xuICB9XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUN5Q0EsSUFBYSw0QkFBYixjQUErQywyQkFBMEI7Q0FBekUsY0FBQTs7RUFpQlUsS0FBQSxZQUFZLElBQUksc0JBQXNCLElBQUk7Q0FrcEJwRDs7RUFscUJrQyxLQUFBLGNBQXNCO0NBQXVCOztFQUN0RCxLQUFBLHNCQUF3QztHQUM3RDtHQUNBO0dBQ0E7R0FDQTtHQUNBO0dBQ0E7R0FDQTs7Q0FDQTs7RUFDcUIsS0FBQSxTQUF5QjtHQUM5QztHQUNBO0dBQ0EsVUFBVSx3QkFBSzs7Q0FDZjtDQUtpQixXQUFXLG1CQUF1QztFQUNuRSxNQUFNLFdBQVcsaUJBQWlCO0VBRWxDLElBQUksa0JBQWtCLElBQUksZUFBZSxHQUN2QyxJQUFJLEtBQUssZUFDUCxLQUFLLFlBQ0QsaUJBQWlCLE9BQU8sRUFDekIsU0FBUyxVQUFVLE1BQU0sZ0JBQWdCLFVBQVUsQ0FBQztPQUV2RCxLQUFLLFlBQ0QsaUJBQWlCLE9BQU8sRUFDekIsU0FBUyxVQUFVLE1BQU0sYUFBYSxZQUFZLEdBQUcsQ0FBQztDQUcvRDtDQUVtQixhQUFhLG1CQUF1QztFQUNyRSxNQUFNLGFBQWEsaUJBQWlCO0VBR3BDLEtBQUssZUFBZSxXQUFVO0dBQzVCLEtBQUsscUNBQW9DO0VBQzNDLENBQUM7Q0FDSDtDQUVtQixTQUFNO0VBQ3ZCLEtBQUssd0NBQXVDO0VBQzVDLE9BQU8sS0FBSyx3QkFBd0I7Q0FDdEM7Q0FFUSwwQ0FBdUM7RUFDN0MsS0FBSyx1QkFBdUIsSUFBSTtRQUM1QixLQUFLLHVC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
|