@sbb-esta/lyne-elements-experimental-dev 4.7.0-dev.1773388997 → 4.7.0-dev.1773393170

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.
Files changed (200) hide show
  1. package/autocomplete-grid/autocomplete-grid/autocomplete-grid.component.js +76 -65
  2. package/autocomplete-grid/autocomplete-grid-button/autocomplete-grid-button.component.js +52 -72
  3. package/autocomplete-grid/autocomplete-grid-button.js +6 -3
  4. package/autocomplete-grid/autocomplete-grid-cell/autocomplete-grid-cell.component.js +17 -2
  5. package/autocomplete-grid/autocomplete-grid-cell.js +7 -4
  6. package/autocomplete-grid/autocomplete-grid-optgroup/autocomplete-grid-optgroup.component.js +21 -20
  7. package/autocomplete-grid/autocomplete-grid-optgroup.js +6 -3
  8. package/autocomplete-grid/autocomplete-grid-option/autocomplete-grid-option.component.js +33 -2
  9. package/autocomplete-grid/autocomplete-grid-option.js +9 -4
  10. package/autocomplete-grid/autocomplete-grid-row/autocomplete-grid-row.component.js +22 -2
  11. package/autocomplete-grid/autocomplete-grid-row.js +7 -4
  12. package/autocomplete-grid/autocomplete-grid.js +6 -3
  13. package/autocomplete-grid.js +21 -9
  14. package/autocomplete-grid.pure.js +15 -7
  15. package/core/datetime/date-helper.js +191 -2
  16. package/core/datetime.js +5 -2
  17. package/core/timetable/access-leg-helper.js +71 -76
  18. package/core/timetable/timetable-helper.js +11 -9
  19. package/core/timetable/timetable-properties.js +1 -0
  20. package/core/timetable.js +7 -3
  21. package/custom-elements.json +84 -84
  22. package/development/autocomplete-grid/autocomplete-grid/autocomplete-grid.component.js +122 -114
  23. package/development/autocomplete-grid/autocomplete-grid-button/autocomplete-grid-button.component.js +70 -92
  24. package/development/autocomplete-grid/autocomplete-grid-button.js +4 -6
  25. package/development/autocomplete-grid/autocomplete-grid-cell/autocomplete-grid-cell.component.js +29 -2
  26. package/development/autocomplete-grid/autocomplete-grid-cell.js +5 -7
  27. package/development/autocomplete-grid/autocomplete-grid-optgroup/autocomplete-grid-optgroup.component.js +22 -27
  28. package/development/autocomplete-grid/autocomplete-grid-optgroup.js +4 -6
  29. package/development/autocomplete-grid/autocomplete-grid-option/autocomplete-grid-option.component.js +109 -2
  30. package/development/autocomplete-grid/autocomplete-grid-option.js +7 -7
  31. package/development/autocomplete-grid/autocomplete-grid-row/autocomplete-grid-row.component.js +91 -2
  32. package/development/autocomplete-grid/autocomplete-grid-row.js +5 -7
  33. package/development/autocomplete-grid/autocomplete-grid.js +4 -6
  34. package/development/autocomplete-grid.js +14 -10
  35. package/development/autocomplete-grid.pure.js +13 -4
  36. package/development/core/datetime/date-helper.js +285 -2
  37. package/development/core/datetime.js +6 -2
  38. package/development/core/timetable/access-leg-helper.js +82 -104
  39. package/development/core/timetable/timetable-helper.js +17 -16
  40. package/development/core/timetable/timetable-properties.js +2 -0
  41. package/development/core/timetable.js +8 -3
  42. package/development/differenceInMinutes-B0dawX-5.js +26 -0
  43. package/development/format-BMkeaqaF.js +1433 -0
  44. package/development/isValid-BYRch7pV.js +53 -0
  45. package/development/journey-summary/journey-summary.component.js +288 -2
  46. package/development/journey-summary.js +5 -8
  47. package/development/journey-summary.pure.js +5 -2
  48. package/development/pearl-chain/pearl-chain.component.js +634 -2
  49. package/development/pearl-chain-time/pearl-chain-time.component.js +306 -2
  50. package/development/pearl-chain-time.js +5 -8
  51. package/development/pearl-chain-time.pure.js +5 -2
  52. package/development/pearl-chain-vertical/pearl-chain-vertical.component.js +28 -2
  53. package/development/pearl-chain-vertical-item/pearl-chain-vertical-item.component.js +393 -2
  54. package/development/pearl-chain-vertical-item.js +5 -8
  55. package/development/pearl-chain-vertical-item.pure.js +5 -2
  56. package/development/pearl-chain-vertical.js +5 -8
  57. package/development/pearl-chain-vertical.pure.js +5 -2
  58. package/development/pearl-chain.js +5 -8
  59. package/development/pearl-chain.pure.js +5 -2
  60. package/development/seat-reservation/common/mapper/icon-mapper.js +71 -168
  61. package/development/seat-reservation/common/mapper/mapper.js +122 -153
  62. package/development/seat-reservation/common/mapper/sample-data/seat-reservation-sample-data-bus.js +559 -570
  63. package/development/seat-reservation/common/mapper/sample-data/seat-reservation-sample-data-decks.js +972 -992
  64. package/development/seat-reservation/common/mapper/sample-data/seat-reservation-sample-data-giruno.js +20367 -20334
  65. package/development/seat-reservation/common/mapper/sample-data/seat-reservation-sample-data-others.js +1738 -1731
  66. package/development/seat-reservation/common/mapper/sample-data/seat-reservation-sample-data-train.js +9782 -9741
  67. package/development/seat-reservation/common/mapper.js +8 -1
  68. package/development/seat-reservation/common/svgs.js +46 -2
  69. package/development/seat-reservation/common/translations/i18n.js +900 -1118
  70. package/development/seat-reservation/common/translations.js +4 -1
  71. package/development/seat-reservation/common/types.js +2 -0
  72. package/development/seat-reservation/common.js +11 -7
  73. package/development/seat-reservation/seat-reservation/seat-reservation-base-element.js +1230 -1305
  74. package/development/seat-reservation/seat-reservation/seat-reservation.component.js +859 -2
  75. package/development/seat-reservation/seat-reservation-area/seat-reservation-area.component.js +106 -2
  76. package/development/seat-reservation/seat-reservation-area.js +5 -7
  77. package/development/seat-reservation/seat-reservation-graphic/seat-reservation-assets.js +34 -35
  78. package/development/seat-reservation/seat-reservation-graphic/seat-reservation-graphic.component.js +162 -2
  79. package/development/seat-reservation/seat-reservation-graphic.js +5 -7
  80. package/development/seat-reservation/seat-reservation-navigation-coach/seat-reservation-navigation-coach.component.js +713 -2
  81. package/development/seat-reservation/seat-reservation-navigation-coach.js +5 -7
  82. package/development/seat-reservation/seat-reservation-navigation-services/seat-reservation-navigation-services.component.js +131 -2
  83. package/development/seat-reservation/seat-reservation-navigation-services.js +5 -7
  84. package/development/seat-reservation/seat-reservation-place-control/seat-reservation-place-control.component.js +601 -2
  85. package/development/seat-reservation/seat-reservation-place-control.js +5 -7
  86. package/development/seat-reservation/seat-reservation-scoped/seat-reservation-scoped.component.js +22 -2
  87. package/development/seat-reservation/seat-reservation-scoped.js +5 -7
  88. package/development/seat-reservation/seat-reservation.js +6 -7
  89. package/development/seat-reservation.js +28 -15
  90. package/development/seat-reservation.pure.js +28 -10
  91. package/development/timetable-duration/timetable-duration.component.js +108 -2
  92. package/development/timetable-duration.js +5 -8
  93. package/development/timetable-duration.pure.js +5 -2
  94. package/development/timetable-row/timetable-row.component.js +781 -2
  95. package/development/timetable-row.js +13 -8
  96. package/development/timetable-row.pure.js +12 -2
  97. package/development/toDate-BWb6Z1JD.js +24 -0
  98. package/differenceInMinutes-COvvdYsJ.js +23 -0
  99. package/format-CmKROkbc.js +1186 -0
  100. package/isValid-m3_OsPaB.js +45 -0
  101. package/journey-summary/journey-summary.component.js +194 -2
  102. package/journey-summary.js +4 -5
  103. package/journey-summary.pure.js +4 -2
  104. package/package.json +2 -2
  105. package/pearl-chain/pearl-chain.component.js +165 -2
  106. package/pearl-chain-time/pearl-chain-time.component.js +157 -2
  107. package/pearl-chain-time.js +4 -5
  108. package/pearl-chain-time.pure.js +4 -2
  109. package/pearl-chain-vertical/pearl-chain-vertical.component.js +17 -2
  110. package/pearl-chain-vertical-item/pearl-chain-vertical-item.component.js +77 -2
  111. package/pearl-chain-vertical-item.js +4 -5
  112. package/pearl-chain-vertical-item.pure.js +4 -2
  113. package/pearl-chain-vertical.js +4 -5
  114. package/pearl-chain-vertical.pure.js +4 -2
  115. package/pearl-chain.js +4 -5
  116. package/pearl-chain.pure.js +4 -2
  117. package/seat-reservation/common/mapper/icon-mapper.js +71 -71
  118. package/seat-reservation/common/mapper/mapper.js +89 -95
  119. package/seat-reservation/common/mapper/sample-data/seat-reservation-sample-data-bus.js +558 -568
  120. package/seat-reservation/common/mapper/sample-data/seat-reservation-sample-data-decks.js +970 -989
  121. package/seat-reservation/common/mapper/sample-data/seat-reservation-sample-data-giruno.js +20366 -20332
  122. package/seat-reservation/common/mapper/sample-data/seat-reservation-sample-data-others.js +1737 -1729
  123. package/seat-reservation/common/mapper/sample-data/seat-reservation-sample-data-train.js +9781 -9739
  124. package/seat-reservation/common/mapper.js +9 -3
  125. package/seat-reservation/common/svgs.js +243 -2
  126. package/seat-reservation/common/translations/i18n.js +891 -1084
  127. package/seat-reservation/common/translations.js +4 -2
  128. package/seat-reservation/common/types.js +1 -0
  129. package/seat-reservation/common.js +15 -9
  130. package/seat-reservation/seat-reservation/seat-reservation-base-element.js +810 -832
  131. package/seat-reservation/seat-reservation/seat-reservation.component.js +420 -2
  132. package/seat-reservation/seat-reservation-area/seat-reservation-area.component.js +51 -2
  133. package/seat-reservation/seat-reservation-area.js +7 -4
  134. package/seat-reservation/seat-reservation-graphic/seat-reservation-assets.js +71 -68
  135. package/seat-reservation/seat-reservation-graphic/seat-reservation-graphic.component.js +75 -2
  136. package/seat-reservation/seat-reservation-graphic.js +7 -4
  137. package/seat-reservation/seat-reservation-navigation-coach/seat-reservation-navigation-coach.component.js +234 -2
  138. package/seat-reservation/seat-reservation-navigation-coach.js +7 -4
  139. package/seat-reservation/seat-reservation-navigation-services/seat-reservation-navigation-services.component.js +85 -2
  140. package/seat-reservation/seat-reservation-navigation-services.js +7 -4
  141. package/seat-reservation/seat-reservation-place-control/seat-reservation-place-control.component.js +203 -2
  142. package/seat-reservation/seat-reservation-place-control.js +7 -4
  143. package/seat-reservation/seat-reservation-scoped/seat-reservation-scoped.component.js +13 -2
  144. package/seat-reservation/seat-reservation-scoped.js +7 -4
  145. package/seat-reservation/seat-reservation.js +9 -5
  146. package/seat-reservation.js +39 -17
  147. package/seat-reservation.pure.js +32 -15
  148. package/timetable-duration/timetable-duration.component.js +57 -2
  149. package/timetable-duration.js +4 -5
  150. package/timetable-duration.pure.js +4 -2
  151. package/timetable-row/timetable-row.component.js +427 -2
  152. package/timetable-row.js +13 -6
  153. package/timetable-row.pure.js +11 -2
  154. package/toDate-Bw2KTWeq.js +15 -0
  155. package/autocomplete-grid-cell.component-Dak9wlBr.js +0 -24
  156. package/autocomplete-grid-option.component-DNRFHOwc.js +0 -37
  157. package/autocomplete-grid-row.component-DBHZQ0GQ.js +0 -27
  158. package/date-helper-CGproP5d.js +0 -185
  159. package/development/autocomplete-grid-cell.component-BBvM4o2H.js +0 -42
  160. package/development/autocomplete-grid-option.component-QzfM5eIE.js +0 -123
  161. package/development/autocomplete-grid-row.component-H8sCTCkT.js +0 -104
  162. package/development/date-helper-8_Y-PuHh.js +0 -520
  163. package/development/differenceInMinutes-DN_1Rk3O.js +0 -110
  164. package/development/format-Bbrn2bgo.js +0 -1848
  165. package/development/isValid-C-HzKv4v.js +0 -178
  166. package/development/journey-summary.component-uGhZvA4p.js +0 -385
  167. package/development/pearl-chain-time.component-B8mayTWD.js +0 -415
  168. package/development/pearl-chain-vertical-item.component-BDzbcIaf.js +0 -435
  169. package/development/pearl-chain-vertical.component-CswE7b3M.js +0 -39
  170. package/development/pearl-chain.component-wpsTvoSe.js +0 -704
  171. package/development/seat-reservation-area.component-BK92ZtFo.js +0 -138
  172. package/development/seat-reservation-graphic.component-cUnsHh5x.js +0 -193
  173. package/development/seat-reservation-navigation-coach.component-D6Bglus8.js +0 -828
  174. package/development/seat-reservation-navigation-services.component-DYJ6Ddkg.js +0 -179
  175. package/development/seat-reservation-place-control.component-Bg9evKBW.js +0 -726
  176. package/development/seat-reservation-scoped.component-DRQ_I702.js +0 -31
  177. package/development/seat-reservation.component-Cq_aJKR0.js +0 -818
  178. package/development/svgs-C3JMWR26.js +0 -28
  179. package/development/timetable-duration.component-DI0lET17.js +0 -125
  180. package/development/timetable-row.component-CAED6Zwc.js +0 -932
  181. package/development/toDate-Biiv3kyf.js +0 -150
  182. package/differenceInMinutes-Dr9gRqtu.js +0 -27
  183. package/format-CM5exOsN.js +0 -1103
  184. package/isValid-B9oVW3lA.js +0 -36
  185. package/journey-summary.component-Cq_4kaOp.js +0 -264
  186. package/pearl-chain-time.component-DGDW5S1c.js +0 -239
  187. package/pearl-chain-vertical-item.component-G22bWhLU.js +0 -108
  188. package/pearl-chain-vertical.component-CXIDT5RD.js +0 -21
  189. package/pearl-chain.component-DmjkVIva.js +0 -194
  190. package/seat-reservation-area.component-n-9rGn_y.js +0 -75
  191. package/seat-reservation-graphic.component-YTXRmKt0.js +0 -102
  192. package/seat-reservation-navigation-coach.component-YJ0vaYmO.js +0 -333
  193. package/seat-reservation-navigation-services.component-C3xnLJg2.js +0 -127
  194. package/seat-reservation-place-control.component-DmBAfM6K.js +0 -322
  195. package/seat-reservation-scoped.component-DPkz6u17.js +0 -17
  196. package/seat-reservation.component-C_anMkgw.js +0 -364
  197. package/svgs-D9arBcqr.js +0 -26
  198. package/timetable-duration.component-DCu8Phts.js +0 -65
  199. package/timetable-row.component-BVRCB3xK.js +0 -559
  200. package/toDate-p-Tpkb7t.js +0 -16
@@ -1,2 +1,859 @@
1
- import { t as SbbSeatReservationElement } from "../../seat-reservation.component-Cq_aJKR0.js";
2
- export { SbbSeatReservationElement };
1
+ import { SbbLanguageController } from "@sbb-esta/lyne-elements/core/controllers.js";
2
+ import { boxSizingStyles } from "@sbb-esta/lyne-elements/core/styles.js";
3
+ import { css, html, nothing } from "lit";
4
+ import { classMap } from "lit/directives/class-map.js";
5
+ import { repeat } from "lit/directives/repeat.js";
6
+ import { styleMap } from "lit/directives/style-map.js";
7
+ import { getI18nSeatReservation } from "../common/translations.js";
8
+ import { SbbSeatReservationAreaElement } from "../seat-reservation-area/seat-reservation-area.component.js";
9
+ import { SbbSeatReservationGraphicElement } from "../seat-reservation-graphic/seat-reservation-graphic.component.js";
10
+ import { SbbSeatReservationNavigationCoachElement } from "../seat-reservation-navigation-coach/seat-reservation-navigation-coach.component.js";
11
+ import { SbbSeatReservationPlaceControlElement } from "../seat-reservation-place-control/seat-reservation-place-control.component.js";
12
+ import { SbbSeatReservationScopedElement } from "../seat-reservation-scoped/seat-reservation-scoped.component.js";
13
+ import { SeatReservationBaseElement } from "./seat-reservation-base-element.js";
14
+ import "@sbb-esta/lyne-elements/button.js";
15
+ import "@sbb-esta/lyne-elements/screen-reader-only.js";
16
+ import "@sbb-esta/lyne-elements/popover.js";
17
+ const style = css`:host {
18
+ --sbb-seat-reservation-grid-size: 16px;
19
+ --sbb-seat-reservation-height: 0;
20
+ --sbb-seat-reservation-decks: 1;
21
+ display: block;
22
+ height: inherit;
23
+ }
24
+ :host ::part(coach-floor) {
25
+ fill: var(--sbb-background-color-2);
26
+ }
27
+ @media (forced-colors: active) {
28
+ :host ::part(coach-floor) {
29
+ fill: transparent;
30
+ }
31
+ }
32
+
33
+ :host(:dir(rtl)) :not(.sbb-sr-place-ctrl--type-bicycle,
34
+ .sbb-sr-place-ctrl--orientation-90,
35
+ .sbb-sr-place-ctrl--orientation-270,
36
+ .sbb-sr-place-ctrl--state-selected) ::part(coach-floor) {
37
+ rotate: calc(180 * 1deg);
38
+ }
39
+
40
+ [popover]:where(sbb-popover) {
41
+ margin: 0;
42
+ padding: 0;
43
+ border: none;
44
+ width: auto;
45
+ height: auto;
46
+ background-color: transparent;
47
+ color: inherit;
48
+ pointer-events: none;
49
+ }
50
+ [popover]:where(sbb-popover) .sbb-sr-popover {
51
+ margin-block: calc(4 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
52
+ }
53
+
54
+ :host([align-vertical]) .sbb-sr__component {
55
+ flex-direction: row-reverse;
56
+ justify-content: flex-end;
57
+ gap: calc(22 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
58
+ height: inherit;
59
+ }
60
+ @media (min-width: calc(37.5rem)) {
61
+ :host([align-vertical]) .sbb-sr__component {
62
+ gap: calc(54 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
63
+ }
64
+ }
65
+ :host([align-vertical]) .sbb-sr__component nav.sbb-sr-navigation,
66
+ :host([align-vertical]) .sbb-sr__component ul.sbb-sr-navigation__list-coaches {
67
+ flex-direction: column;
68
+ }
69
+ :host([align-vertical]) .sbb-sr__component nav.sbb-sr-navigation {
70
+ padding: calc(16 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem)) 0;
71
+ }
72
+ :host([align-vertical]) .sbb-sr__component nav.sbb-sr-navigation .sbb-sr__navigation-control-button {
73
+ left: calc(1 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
74
+ top: 0;
75
+ rotate: 90deg;
76
+ }
77
+ @media (min-width: calc(64rem)) {
78
+ :host([align-vertical]) .sbb-sr__component nav.sbb-sr-navigation .sbb-sr__navigation-control-button {
79
+ left: calc(-1 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
80
+ }
81
+ }
82
+ :host([align-vertical]) .sbb-sr__component nav.sbb-sr-navigation ul.sbb-sr-navigation__list-coaches {
83
+ max-width: initial;
84
+ padding: calc(5 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
85
+ overflow: hidden scroll;
86
+ }
87
+ :host([align-vertical]) .sbb-sr__wrapper-coach-decks {
88
+ flex-direction: column;
89
+ }
90
+ :host([align-vertical]) .sbb-sr__wrapper-coach-decks .sbb-sr__wrapper-deck-labels {
91
+ flex-direction: column-reverse;
92
+ width: calc((var(--sbb-seat-reservation-height) + 24) * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
93
+ height: initial;
94
+ }
95
+ :host([align-vertical]) .sbb-sr__wrapper-coach-decks .sbb-sr__wrapper-deck-labels b {
96
+ inline-size: calc(50% - 16 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
97
+ block-size: calc(20 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
98
+ margin-bottom: calc(16 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
99
+ rotate: initial;
100
+ writing-mode: initial;
101
+ }
102
+ :host([align-vertical]) .sbb-sr__wrapper-scrollarea {
103
+ width: calc((var(--sbb-seat-reservation-height) + 24) * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
104
+ height: 100%;
105
+ overflow: hidden scroll;
106
+ }
107
+ :host([align-vertical]) .sbb-sr__wrapper-scrollarea .sbb-sr__parent {
108
+ rotate: 90deg;
109
+ }
110
+ :host([align-vertical]) .sbb-sr-travel-direction-wrapper {
111
+ width: calc(var(--sbb-seat-reservation-height) * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
112
+ margin-block-start: calc(4 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
113
+ }
114
+
115
+ .sbb-sr-navigation {
116
+ gap: calc(3 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
117
+ }
118
+
119
+ .sbb-sr-navigation .sbb-sr__navigation-control-button {
120
+ position: relative;
121
+ top: calc(2 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
122
+ }
123
+ @media (min-width: calc(64rem)) {
124
+ .sbb-sr-navigation .sbb-sr__navigation-control-button {
125
+ top: 0;
126
+ }
127
+ }
128
+
129
+ .sbb-sr__component {
130
+ display: flex;
131
+ flex-direction: column;
132
+ gap: calc(64 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem) - 16px);
133
+ }
134
+
135
+ .sbb-sr-travel-direction-wrapper {
136
+ display: flex;
137
+ justify-content: center;
138
+ align-items: center;
139
+ column-gap: calc(4 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
140
+ margin-block: calc(8 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem)) calc(4 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
141
+ font-size: var(--sbb-text-font-size-s);
142
+ }
143
+ .sbb-sr-travel-direction-wrapper .sbb-sr__travel-direction--arrow {
144
+ display: flex;
145
+ align-items: center;
146
+ }
147
+
148
+ .sbb-sr-navigation-wrapper {
149
+ display: flex;
150
+ }
151
+
152
+ .sbb-sr-navigation {
153
+ display: flex;
154
+ justify-content: center;
155
+ width: 100%;
156
+ padding-inline: 16px;
157
+ }
158
+
159
+ .sbb-sr-navigation__list-coaches {
160
+ list-style: none;
161
+ margin: 0;
162
+ padding: 0;
163
+ font-size: inherit;
164
+ --sbb-scrollbar-thumb-width: 0.125rem;
165
+ --sbb-scrollbar-thumb-width-hover: 0.25rem;
166
+ --sbb-scrollbar-width-firefox: thin;
167
+ --sbb-scrollbar-color: color-mix(in srgb, var(--sbb-color-black) 30%, transparent);
168
+ --sbb-scrollbar-color: light-dark(
169
+ color-mix(in srgb, var(--sbb-color-black) 30%, transparent),
170
+ color-mix(in srgb, var(--sbb-color-white) 30%, transparent)
171
+ );
172
+ --sbb-scrollbar-color-hover: color-mix(in srgb, var(--sbb-color-black) 60%, transparent);
173
+ --sbb-scrollbar-color-hover: light-dark(
174
+ color-mix(in srgb, var(--sbb-color-black) 60%, transparent),
175
+ color-mix(in srgb, var(--sbb-color-white) 60%, transparent)
176
+ );
177
+ --sbb-scrollbar-track-color: transparent;
178
+ --sbb-scrollbar-width: var(--sbb-spacing-fixed-3x);
179
+ }
180
+ .sbb-sr-navigation__list-coaches::-webkit-scrollbar {
181
+ width: var(--sbb-scrollbar-width);
182
+ height: var(--sbb-scrollbar-width);
183
+ background-color: var(--sbb-scrollbar-track-color, transparent);
184
+ }
185
+ .sbb-sr-navigation__list-coaches::-webkit-scrollbar-corner {
186
+ background-color: var(--sbb-scrollbar-track-color, transparent);
187
+ }
188
+ .sbb-sr-navigation__list-coaches::-webkit-scrollbar-thumb {
189
+ background-color: var(--sbb-scrollbar-color, currentcolor);
190
+ border: calc(0.5 * (var(--sbb-scrollbar-width) - var(--sbb-scrollbar-thumb-width))) solid transparent;
191
+ border-radius: var(--sbb-border-radius-4x);
192
+ background-clip: padding-box;
193
+ }
194
+ .sbb-sr-navigation__list-coaches::-webkit-scrollbar-thumb:hover {
195
+ background-color: var(--sbb-scrollbar-color-hover, currentcolor);
196
+ border-width: calc(0.5 * (var(--sbb-scrollbar-width) - var(--sbb-scrollbar-thumb-width-hover)));
197
+ }
198
+ .sbb-sr-navigation__list-coaches::-webkit-scrollbar-button, .sbb-sr-navigation__list-coaches::-webkit-scrollbar-corner {
199
+ display: none;
200
+ }
201
+ @supports not selector(::-webkit-scrollbar) {
202
+ .sbb-sr-navigation__list-coaches {
203
+ scrollbar-width: var(--sbb-scrollbar-width-firefox);
204
+ scrollbar-color: var(--sbb-scrollbar-color, currentcolor) var(--sbb-scrollbar-track-color, transparent);
205
+ }
206
+ }
207
+ .sbb-sr-navigation__list-coaches {
208
+ display: flex;
209
+ flex-wrap: nowrap;
210
+ gap: calc(4 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
211
+ padding: calc(6 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem)) calc(5 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem)) 0;
212
+ max-width: 856px;
213
+ --sbb-scrollbar-color: transparent;
214
+ overflow: scroll hidden;
215
+ position: relative;
216
+ }
217
+
218
+ .sbb-sr__wrapper-coach-decks {
219
+ display: flex;
220
+ overflow: hidden;
221
+ height: inherit;
222
+ }
223
+ .sbb-sr__wrapper-coach-decks .sbb-sr__wrapper-deck-labels {
224
+ display: flex;
225
+ justify-content: space-between;
226
+ height: calc(var(--sbb-seat-reservation-height) * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
227
+ writing-mode: vertical-lr;
228
+ }
229
+ .sbb-sr__wrapper-coach-decks .sbb-sr__wrapper-deck-labels b {
230
+ height: calc(50% - 16 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
231
+ width: calc(20 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
232
+ margin-block-end: 16px;
233
+ rotate: 180deg;
234
+ text-align: center;
235
+ line-height: calc(20 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
236
+ }
237
+
238
+ .sbb-sr__wrapper-scrollarea {
239
+ --sbb-scrollbar-thumb-width: 0.125rem;
240
+ --sbb-scrollbar-thumb-width-hover: 0.25rem;
241
+ --sbb-scrollbar-width-firefox: thin;
242
+ --sbb-scrollbar-color: color-mix(in srgb, var(--sbb-color-black) 30%, transparent);
243
+ --sbb-scrollbar-color: light-dark(
244
+ color-mix(in srgb, var(--sbb-color-black) 30%, transparent),
245
+ color-mix(in srgb, var(--sbb-color-white) 30%, transparent)
246
+ );
247
+ --sbb-scrollbar-color-hover: color-mix(in srgb, var(--sbb-color-black) 60%, transparent);
248
+ --sbb-scrollbar-color-hover: light-dark(
249
+ color-mix(in srgb, var(--sbb-color-black) 60%, transparent),
250
+ color-mix(in srgb, var(--sbb-color-white) 60%, transparent)
251
+ );
252
+ --sbb-scrollbar-track-color: transparent;
253
+ --sbb-scrollbar-width: var(--sbb-spacing-fixed-3x);
254
+ }
255
+ .sbb-sr__wrapper-scrollarea::-webkit-scrollbar {
256
+ width: var(--sbb-scrollbar-width);
257
+ height: var(--sbb-scrollbar-width);
258
+ background-color: var(--sbb-scrollbar-track-color, transparent);
259
+ }
260
+ .sbb-sr__wrapper-scrollarea::-webkit-scrollbar-corner {
261
+ background-color: var(--sbb-scrollbar-track-color, transparent);
262
+ }
263
+ .sbb-sr__wrapper-scrollarea::-webkit-scrollbar-thumb {
264
+ background-color: var(--sbb-scrollbar-color, currentcolor);
265
+ border: calc(0.5 * (var(--sbb-scrollbar-width) - var(--sbb-scrollbar-thumb-width))) solid transparent;
266
+ border-radius: var(--sbb-border-radius-4x);
267
+ background-clip: padding-box;
268
+ }
269
+ .sbb-sr__wrapper-scrollarea::-webkit-scrollbar-thumb:hover {
270
+ background-color: var(--sbb-scrollbar-color-hover, currentcolor);
271
+ border-width: calc(0.5 * (var(--sbb-scrollbar-width) - var(--sbb-scrollbar-thumb-width-hover)));
272
+ }
273
+ .sbb-sr__wrapper-scrollarea::-webkit-scrollbar-button, .sbb-sr__wrapper-scrollarea::-webkit-scrollbar-corner {
274
+ display: none;
275
+ }
276
+ @supports not selector(::-webkit-scrollbar) {
277
+ .sbb-sr__wrapper-scrollarea {
278
+ scrollbar-width: var(--sbb-scrollbar-width-firefox);
279
+ scrollbar-color: var(--sbb-scrollbar-color, currentcolor) var(--sbb-scrollbar-track-color, transparent);
280
+ }
281
+ }
282
+ .sbb-sr__wrapper-scrollarea {
283
+ overflow: scroll hidden;
284
+ padding-block: calc(8 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem)) calc(16 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
285
+ }
286
+ .sbb-sr__wrapper-scrollarea .sbb-sr__parent {
287
+ display: flex;
288
+ flex-direction: column;
289
+ position: relative;
290
+ }
291
+
292
+ .sbb-sr__list-decks {
293
+ list-style: none;
294
+ margin: 0;
295
+ padding: 0;
296
+ font-size: inherit;
297
+ display: flex;
298
+ flex-direction: column;
299
+ }
300
+
301
+ .sbb-sr__list-decks--gap {
302
+ gap: calc(48 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
303
+ }
304
+
305
+ .sbb-sr__list-item-deck {
306
+ position: relative;
307
+ }
308
+
309
+ .sbb-sr__list-coaches {
310
+ list-style: none;
311
+ margin: 0;
312
+ padding: 0;
313
+ font-size: inherit;
314
+ display: flex;
315
+ gap: calc(4 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
316
+ }
317
+
318
+ .sbb-sr__list-decks:has(.sbb-sr-coach-has-overhanging-elements) .sbb-sr__list-coaches {
319
+ gap: calc(8 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
320
+ }
321
+
322
+ .sbb-sr__item-coach {
323
+ position: relative;
324
+ }
325
+
326
+ .sbb-sr-coach-wrapper__table {
327
+ outline: 0;
328
+ }`;
329
+ SbbSeatReservationAreaElement.define();
330
+ SbbSeatReservationGraphicElement.define();
331
+ SbbSeatReservationPlaceControlElement.define();
332
+ SbbSeatReservationNavigationCoachElement.define();
333
+ SbbSeatReservationScopedElement.define();
334
+ const _SbbSeatReservationElement = class _SbbSeatReservationElement extends SeatReservationBaseElement {
335
+ constructor() {
336
+ super(...arguments);
337
+ this._language = new SbbLanguageController(this);
338
+ this._notFixedRotatableAreaIcons = ["ENTRY_EXIT"];
339
+ }
340
+ willUpdate(changedProperties) {
341
+ super.willUpdate(changedProperties);
342
+ if (changedProperties.has("hasNavigation")) {
343
+ if (this.hasNavigation) {
344
+ this.shadowRoot?.querySelectorAll("table").forEach((table) => table.removeAttribute("tabindex"));
345
+ } else {
346
+ this.shadowRoot?.querySelectorAll("table").forEach((table) => table.setAttribute("tabindex", "0"));
347
+ }
348
+ }
349
+ }
350
+ firstUpdated(changedProperties) {
351
+ super.firstUpdated(changedProperties);
352
+ this.updateComplete.then(() => {
353
+ this.initNavigationSelectionByScrollEvent();
354
+ });
355
+ }
356
+ render() {
357
+ this._initVehicleSeatReservationConstruction();
358
+ return this._coachesHtmlTemplate || null;
359
+ }
360
+ _initVehicleSeatReservationConstruction() {
361
+ this._coachesHtmlTemplate = html`
362
+ ${this._renderTravelDirection()}
363
+ <div class="sbb-sr__component">
364
+ ${this._renderNavigation()}
365
+ <div
366
+ class="sbb-sr__wrapper-coach-decks"
367
+ @keydown=${(evt) => this.keyboardSeatmapEventHandling(evt)}
368
+ >
369
+ <div class="sbb-sr__wrapper-deck-labels">${this._renderDeckLabels()}</div>
370
+ <div
371
+ @scroll=${() => this.coachAreaScrollend()}
372
+ id="sbb-sr__wrapper-scrollarea"
373
+ class="sbb-sr__wrapper-scrollarea"
374
+ tabindex="-1"
375
+ >
376
+ <div id="sbb-sr__parent-area" class="sbb-sr__parent">
377
+ <ul
378
+ class="${classMap({
379
+ "sbb-sr__list-decks": true,
380
+ "sbb-sr__list-decks--gap": this.hasMultipleDecks
381
+ })}"
382
+ >
383
+ ${this.seatReservations?.map((seatReservation, coachDeckIndex) => {
384
+ return html`<li class="sbb-sr__list-item-deck">
385
+ <ul class="sbb-sr__list-coaches" role="presentation">
386
+ ${this._renderCoaches(seatReservation, coachDeckIndex)}
387
+ </ul>
388
+ </li>`;
389
+ })}
390
+ </ul>
391
+ </div>
392
+ </div>
393
+ </div>
394
+ </div>
395
+ `;
396
+ }
397
+ _renderDeckLabels() {
398
+ if (!this.hasMultipleDecks)
399
+ return null;
400
+ return this.seatReservations.map((seatReservation) => {
401
+ const deckDescription = getI18nSeatReservation(seatReservation.deckCoachLevel, this._language.current);
402
+ return html`<b aria-hidden="true">${deckDescription}</b>`;
403
+ });
404
+ }
405
+ _renderNavigationControlButton(btnDirection) {
406
+ if (!this.hasNavigation || !this.seatReservations)
407
+ return null;
408
+ const btnNavigationDirectionId = btnDirection == "DIRECTION_RIGHT" ? "sbb-sr-navigation__wrapper-button-direction--right" : "sbb-sr-navigation__wrapper-button-direction--left";
409
+ const btnIcon = btnDirection == "DIRECTION_RIGHT" ? "chevron-small-right-small" : "chevron-small-left-small";
410
+ const btnAriaDescription = btnDirection == "DIRECTION_RIGHT" ? getI18nSeatReservation("SEAT_RESERVATION_END", this._language.current) : getI18nSeatReservation("SEAT_RESERVATION_BEGIN", this._language.current);
411
+ let btnDisabled = true;
412
+ if (btnDirection == "DIRECTION_LEFT" && this.selectedCoachIndex > 0) {
413
+ btnDisabled = false;
414
+ } else if (btnDirection == "DIRECTION_RIGHT" && this.selectedCoachIndex < this.coachItemDetailsElements.length - 1) {
415
+ btnDisabled = false;
416
+ }
417
+ return html`<div class="sbb-sr-navigation__wrapper-button-direction">
418
+ <sbb-secondary-button
419
+ @click="${() => this.navigateByDirectionBtn(btnDirection)}"
420
+ @focus="${() => this.onFocusNavDirectionButton()}"
421
+ id="${btnNavigationDirectionId}"
422
+ class="sbb-sr__navigation-control-button"
423
+ size="m"
424
+ icon-name="${btnIcon}"
425
+ type="button"
426
+ aria-label="${btnAriaDescription}"
427
+ role="button"
428
+ .disabledInteractive="${btnDisabled || nothing}"
429
+ .disabled="${btnDisabled || nothing}"
430
+ ></sbb-secondary-button>
431
+ </div>`;
432
+ }
433
+ _renderTravelDirection() {
434
+ if (!this.travelDirection || this.travelDirection === "NONE")
435
+ return null;
436
+ const labelText = getI18nSeatReservation("SEAT_RESERVATION_TRAVEL_DIRECTION", this._language.current);
437
+ const arrowDirection = this.alignVertical ? this.travelDirection === "RIGHT" ? "down" : "up" : this.travelDirection === "RIGHT" ? "right" : "left";
438
+ const iconName = `arrow-${arrowDirection}-small`;
439
+ return html`<div class="sbb-sr-travel-direction-wrapper">
440
+ <div class="sbb-sr__travel-direction--arrow">
441
+ <sbb-icon slot="icon" name="${iconName}"></sbb-icon>
442
+ </div>
443
+ <div class="sbb-sr__travel-direction--label">${labelText}</div>
444
+ </div>`;
445
+ }
446
+ _renderNavigation() {
447
+ if (!this.hasNavigation || !this.seatReservations)
448
+ return null;
449
+ return html`<div class="sbb-sr-navigation-wrapper">
450
+ <nav id="sbb-sr-navigation" class="sbb-sr-navigation">
451
+ ${this._renderNavigationControlButton("DIRECTION_LEFT")}
452
+ <ul
453
+ id="sbb-sr__navigation-list-coaches"
454
+ class="sbb-sr-navigation__list-coaches"
455
+ aria-label="${getI18nSeatReservation("SEAT_RESERVATION_NAVIGATION", this._language.current)}"
456
+ >
457
+ ${this.coachItemDetailsElements.map((coachItemDetails, index) => {
458
+ return html`<li>
459
+ <sbb-seat-reservation-navigation-coach
460
+ @selectcoach=${(event) => this._onSelectNavCoach(event)}
461
+ @focuscoach=${() => this._onFocusNavCoach()}
462
+ @keyup=${(evt) => this.onKeyNavigationNavCoachButton(evt, index)}
463
+ index="${index}"
464
+ .selected=${this.selectedCoachIndex === index}
465
+ .focused=${this.focusedCoachIndex === index}
466
+ .hovered=${this.hoveredCoachIndex === index}
467
+ .nativeFocusActive=${this.hasSeatReservationNativeFocus}
468
+ .coachItemDetails="${coachItemDetails}"
469
+ ?vertical="${this.alignVertical}"
470
+ ?showTitleInfo="${this.showTitleInfo}"
471
+ >
472
+ </sbb-seat-reservation-navigation-coach>
473
+ </li>`;
474
+ })}
475
+ </ul>
476
+ ${this._renderNavigationControlButton("DIRECTION_RIGHT")}
477
+ </nav>
478
+ </div>`;
479
+ }
480
+ /**
481
+ *
482
+ * @returns
483
+ * @param seatReservation
484
+ * @param coachDeckIndex
485
+ */
486
+ _renderCoaches(seatReservation, coachDeckIndex) {
487
+ const coaches = JSON.parse(JSON.stringify(seatReservation?.coachItems));
488
+ if (!coaches) {
489
+ return null;
490
+ }
491
+ return coaches.map((coachItem, coachIndex) => {
492
+ return html`
493
+ <li class="sbb-sr__item-coach">
494
+ ${this._renderCoachElement(coachItem, coachIndex, coachDeckIndex, seatReservation.deckCoachIndex)}
495
+ </li>
496
+ `;
497
+ });
498
+ }
499
+ _renderCoachElement(coachItem, coachIndex, coachDeckIndex, placeCoachDeckIndex) {
500
+ const calculatedCoachDimension = this.getCalculatedDimension(coachItem.dimension);
501
+ const descriptionTableCoachWithServices = this._getDescriptionTableCoach(coachItem);
502
+ return html`<sbb-seat-reservation-scoped
503
+ style=${styleMap({
504
+ "--sbb-seat-reservation-scoped-width": calculatedCoachDimension.w,
505
+ "--sbb-seat-reservation-scoped-height": calculatedCoachDimension.h
506
+ })}
507
+ >
508
+ ${this._getRenderedCoachBorders(coachItem, coachIndex)}
509
+ ${this._getRenderedGraphicalElements(coachItem.graphicElements || [], coachItem.dimension, coachIndex, coachDeckIndex)}
510
+ ${this._getRenderedServiceElements(coachIndex, coachDeckIndex, coachItem.serviceElements)}
511
+
512
+ <table
513
+ @focus=${() => this.onFocusTableCoachAndPreselectPlace(coachIndex)}
514
+ id="sbb-sr-coach-${coachIndex}"
515
+ class="sbb-sr-coach-wrapper__table"
516
+ aria-describedby="sbb-sr-coach-caption-${coachIndex}"
517
+ tabindex="-1"
518
+ >
519
+ <caption id="sbb-sr-coach-caption-${coachIndex}" tabindex="-1">
520
+ <sbb-screen-reader-only>${descriptionTableCoachWithServices}</sbb-screen-reader-only>
521
+ </caption>
522
+ ${this._getRenderedRowPlaces(coachItem, coachIndex, coachDeckIndex, placeCoachDeckIndex)}
523
+ </table>
524
+ </sbb-seat-reservation-scoped>`;
525
+ }
526
+ /**
527
+ * @returns Returns the border graphic (COACH_BORDER_MIDDLE) of a coach with calculated border gap and coach width,
528
+ * depending on whether the coach is with a driver area or without.
529
+ */
530
+ _getRenderedCoachBorders(coachItem, coachIndex) {
531
+ if (!coachItem.graphicElements)
532
+ return null;
533
+ const COACH_PASSAGE_WIDTH = 1;
534
+ const driverArea = this.coachItemDetailsElements[coachIndex]?.driverAreaElements?.driverArea;
535
+ const driverAreaNoVerticalWall = this.coachItemDetailsElements[coachIndex]?.driverAreaElements?.driverAreaNoVerticalWall;
536
+ let borderWidth = driverArea ? coachItem.dimension.w - driverArea.dimension.w - COACH_PASSAGE_WIDTH : coachItem.dimension.w - COACH_PASSAGE_WIDTH * 2;
537
+ borderWidth *= this.baseGridSize;
538
+ const borderHeight = (coachItem.dimension.h + this.coachBorderOffset * 2) * this.baseGridSize;
539
+ let borderOffsetX = driverArea && driverArea.position.x === 0 ? driverArea?.dimension.w * this.baseGridSize : this.baseGridSize;
540
+ if (driverAreaNoVerticalWall) {
541
+ const coachWidth = this.getCalculatedDimension(coachItem.dimension).w;
542
+ borderWidth = coachWidth - 2 * (driverAreaNoVerticalWall.dimension.w * this.baseGridSize);
543
+ borderOffsetX = driverAreaNoVerticalWall.dimension.w * this.baseGridSize;
544
+ }
545
+ const currentCoachOverlappingInfo = this.overHangingElementInformation.find((el) => el.coachId == coachItem.id);
546
+ if (currentCoachOverlappingInfo?.overhangingPlaces || currentCoachOverlappingInfo?.overhangingGraphicAreas) {
547
+ borderWidth += 2 * this.baseGridSize;
548
+ borderOffsetX = 0;
549
+ }
550
+ return html`
551
+ <sbb-seat-reservation-graphic
552
+ class="${classMap({
553
+ "sbb-sr-coach-has-overhanging-elements": currentCoachOverlappingInfo?.overhangingPlaces || currentCoachOverlappingInfo?.overhangingGraphicAreas || false
554
+ })}"
555
+ style=${styleMap({
556
+ "--sbb-seat-reservation-graphic-width": borderWidth,
557
+ "--sbb-seat-reservation-graphic-height": borderHeight,
558
+ "--sbb-seat-reservation-graphic-top": this.coachBorderPadding * -1,
559
+ "--sbb-seat-reservation-graphic-left": borderOffsetX,
560
+ "--sbb-seat-reservation-graphic-position": "absolute"
561
+ })}
562
+ name="COACH_BORDER_MIDDLE"
563
+ ?stretch=${true}
564
+ role="presentation"
565
+ ></sbb-seat-reservation-graphic>
566
+ `;
567
+ }
568
+ _getRenderedRowPlaces(coach, coachIndex, coachDeckIndex, placeCoachDeckIndex) {
569
+ if (!coach.places) {
570
+ return null;
571
+ }
572
+ const tableRowPlaces = {};
573
+ for (const place of coach.places) {
574
+ if (!tableRowPlaces[place.position.y]) {
575
+ tableRowPlaces[place.position.y] = [place];
576
+ } else {
577
+ tableRowPlaces[place.position.y].push(place);
578
+ }
579
+ }
580
+ return Object.values(tableRowPlaces).map((rowPlaces, index) => {
581
+ return html`
582
+ <tr id="row-${coachIndex}-${rowPlaces[0].position.y}" data-row-index=${index}>
583
+ ${this._getRenderedColumnPlaces(rowPlaces, coachIndex, coachDeckIndex, placeCoachDeckIndex)}
584
+ </tr>
585
+ `;
586
+ }).flatMap((rowTemplate) => rowTemplate);
587
+ }
588
+ _getRenderedColumnPlaces(places, coachIndex, deckIndex, placeCoachDeckIndex) {
589
+ places.sort((placeA, placeB) => Number(placeA.position.x) - Number(placeB.position.x));
590
+ const trackPlaceId = coachIndex + "-" + placeCoachDeckIndex;
591
+ return html`${repeat(places, (place) => trackPlaceId + "-" + place.number, (place, index) => {
592
+ const calculatedDimension = this.getCalculatedDimension(place.dimension);
593
+ const calculatedPosition = this.getCalculatedPosition(place.position);
594
+ const rotation = place.rotation || 0;
595
+ const textRotation = this.alignVertical ? -90 : 0;
596
+ const placeId = this.getPlaceElementId(deckIndex, coachIndex, place.number);
597
+ return html`
598
+ <td
599
+ id="cell-${deckIndex}-${coachIndex}-${place.position.y}-${index}"
600
+ class="graphical-element"
601
+ >
602
+ <sbb-seat-reservation-place-control
603
+ style=${styleMap({
604
+ "--sbb-seat-reservation-place-control-text-scale-value": Math.min(calculatedDimension.w, calculatedDimension.h),
605
+ "--sbb-seat-reservation-place-control-width": calculatedDimension.w,
606
+ "--sbb-seat-reservation-place-control-height": calculatedDimension.h,
607
+ "--sbb-seat-reservation-place-control-top": calculatedPosition.y,
608
+ "--sbb-seat-reservation-place-control-left": calculatedPosition.x,
609
+ "--sbb-seat-reservation-place-control-rotation": rotation,
610
+ "--sbb-seat-reservation-place-control-text-rotation": textRotation
611
+ })}
612
+ @selectplace=${(selectPlaceEvent) => this._onSelectPlace(selectPlaceEvent)}
613
+ exportparts="sbb-sr-place-part"
614
+ id=${placeId}
615
+ class="seat-reservation-place-control"
616
+ text=${place.number}
617
+ type=${place.type}
618
+ state=${place.state}
619
+ travel-direction=${this.travelDirection}
620
+ coach-index=${coachIndex}
621
+ deck-index=${placeCoachDeckIndex}
622
+ data-deck-index=${deckIndex}
623
+ .propertyIds=${place.propertyIds}
624
+ .preventClick=${this.preventPlaceClick}
625
+ ?showTitleInfo="${this.showTitleInfo}"
626
+ ></sbb-seat-reservation-place-control>
627
+ </td>
628
+ `;
629
+ })}`;
630
+ }
631
+ _getRenderedGraphicalElements(graphicalElements, coachDimension, coachIndex, coachDeckIndex) {
632
+ if (!graphicalElements)
633
+ return null;
634
+ return graphicalElements?.map((graphicalElement) => {
635
+ const icon = graphicalElement.icon ?? "";
636
+ const elementRotation = graphicalElement.rotation || 0;
637
+ const isNotFixedRotationGraphicalElement = this._notFixedRotatableAreaIcons.indexOf(graphicalElement.icon) === -1;
638
+ const elementFixedRotation = this.alignVertical && isNotFixedRotationGraphicalElement ? elementRotation - 90 : elementRotation;
639
+ if (this.notAreaElements.findIndex((notAreaElement) => notAreaElement === icon) > -1) {
640
+ return this._getRenderElementWithoutArea(graphicalElement, elementRotation, coachDimension);
641
+ }
642
+ return this._getRenderElementWithArea(graphicalElement, elementFixedRotation, coachDimension, coachIndex, coachDeckIndex);
643
+ });
644
+ }
645
+ /**
646
+ * creates a rendered element with an area component
647
+ * @param graphicalElement
648
+ * @param rotation
649
+ * @param coachDimension
650
+ * @param coachIndex used to generate a unique id for the popover trigger
651
+ * @param coachDeckIndex used to generate a unique id
652
+ * @private
653
+ */
654
+ _getRenderElementWithArea(graphicalElement, rotation, coachDimension, coachIndex, coachDeckIndex) {
655
+ const isNotTableGraphic = graphicalElement.icon?.indexOf("TABLE") === -1;
656
+ const areaProperty = graphicalElement.icon && isNotTableGraphic ? graphicalElement.icon : null;
657
+ const stretchHeight = this.isElementDirectlyOnBorder(graphicalElement, coachDimension) && areaProperty !== "ENTRY_EXIT";
658
+ const ariaLabelForArea = graphicalElement.icon ? getI18nSeatReservation(graphicalElement.icon, this._language.current) : nothing;
659
+ const calculatedDimension = this.getCalculatedDimension(graphicalElement.dimension, coachDimension, true, stretchHeight);
660
+ const calculatedPosition = this.getCalculatedPosition(graphicalElement.position, graphicalElement.dimension, coachDimension, true);
661
+ const triggerId = `popover-trigger-${coachDeckIndex}-${coachIndex}-${calculatedPosition.x}-${calculatedPosition.y}`;
662
+ let elementMounting = "free";
663
+ if (graphicalElement.position.y === this.coachBorderOffset * -1) {
664
+ elementMounting = "upper-border";
665
+ } else if (graphicalElement.position.y + graphicalElement.dimension.h === coachDimension.h + this.coachBorderOffset) {
666
+ elementMounting = "lower-border";
667
+ }
668
+ if (elementMounting !== "free") {
669
+ calculatedPosition.y += elementMounting === "upper-border" ? 2 : 1;
670
+ calculatedDimension.h -= 3;
671
+ }
672
+ return html`
673
+ <sbb-seat-reservation-area
674
+ id="${triggerId}"
675
+ class="${classMap({ "sbb-seat-reservation-area--cursor-pointer": areaProperty !== null })}"
676
+ style=${styleMap({
677
+ "--sbb-seat-reservation-area-width": calculatedDimension.w,
678
+ "--sbb-seat-reservation-area-height": calculatedDimension.h,
679
+ "--sbb-seat-reservation-area-top": calculatedPosition.y,
680
+ "--sbb-seat-reservation-area-left": calculatedPosition.x
681
+ })}
682
+ mounting=${elementMounting}
683
+ background="dark"
684
+ aria-hidden="true"
685
+ >
686
+ ${areaProperty ? html`
687
+ <sbb-seat-reservation-graphic
688
+ style=${styleMap({
689
+ "--sbb-seat-reservation-graphic-max-width": calculatedDimension.w,
690
+ "--sbb-seat-reservation-graphic-height": this.baseGridSize,
691
+ "--sbb-seat-reservation-graphic-rotation": rotation
692
+ })}
693
+ name=${areaProperty}
694
+ role="img"
695
+ aria-hidden="true"
696
+ class="auto-width"
697
+ ></sbb-seat-reservation-graphic>
698
+ ` : nothing}
699
+ </sbb-seat-reservation-area>
700
+ ${areaProperty ? this._popover(triggerId, ariaLabelForArea) : nothing}
701
+ `;
702
+ }
703
+ _getRenderElementWithoutArea(graphicalElement, rotation, coachDimension) {
704
+ const calculatedDimension = this.getCalculatedDimension(graphicalElement.dimension, coachDimension);
705
+ const calculatedPosition = this.getCalculatedPosition(graphicalElement.position, graphicalElement.dimension, coachDimension);
706
+ const icon = graphicalElement.icon && graphicalElement.icon.endsWith("DRIVER_AREA") ? graphicalElement.icon?.concat("_", this.seatReservations[this.currSelectedDeckIndex].vehicleType) : graphicalElement.icon;
707
+ return html` <sbb-seat-reservation-graphic
708
+ style=${styleMap({
709
+ "--sbb-seat-reservation-graphic-width": calculatedDimension.w,
710
+ "--sbb-seat-reservation-graphic-height": calculatedDimension.h,
711
+ "--sbb-seat-reservation-graphic-top": calculatedPosition.y,
712
+ "--sbb-seat-reservation-graphic-left": calculatedPosition.x,
713
+ "--sbb-seat-reservation-graphic-position": "absolute",
714
+ "--sbb-seat-reservation-graphic-rotation": rotation
715
+ })}
716
+ name=${icon ?? nothing}
717
+ aria-hidden="true"
718
+ ?stretch=${true}
719
+ ></sbb-seat-reservation-graphic>`;
720
+ }
721
+ _getRenderedServiceElements(coachIndex, coachDeckIndex, serviceElements) {
722
+ if (!serviceElements)
723
+ return null;
724
+ return serviceElements?.map((serviceElement) => {
725
+ const titleDescription = serviceElement.icon ? getI18nSeatReservation(serviceElement.icon, this._language.current) : null;
726
+ const calculatedDimension = this.getCalculatedDimension(serviceElement.dimension);
727
+ const calculatedPosition = this.getCalculatedPosition(serviceElement.position);
728
+ const elementRotation = serviceElement.rotation || 0;
729
+ const elementFixedRotation = this.alignVertical ? elementRotation - 90 : elementRotation;
730
+ const triggerId = `popover-trigger-${coachDeckIndex}-${coachIndex}-${calculatedPosition.x}-${calculatedPosition.y}`;
731
+ return html`
732
+ <sbb-seat-reservation-graphic
733
+ id="${triggerId}"
734
+ style=${styleMap({
735
+ "--sbb-seat-reservation-graphic-width": calculatedDimension.w,
736
+ "--sbb-seat-reservation-graphic-height": calculatedDimension.h,
737
+ "--sbb-seat-reservation-graphic-top": calculatedPosition.y,
738
+ "--sbb-seat-reservation-graphic-left": calculatedPosition.x,
739
+ "--sbb-seat-reservation-graphic-position": "absolute",
740
+ "--sbb-seat-reservation-graphic-rotation": elementFixedRotation
741
+ })}
742
+ class="sbb-seat-reservation-graphic--cursor-pointer"
743
+ name=${serviceElement.icon ?? nothing}
744
+ role="img"
745
+ aria-hidden="true"
746
+ ></sbb-seat-reservation-graphic>
747
+ ${this._popover(triggerId, titleDescription)}
748
+ `;
749
+ });
750
+ }
751
+ /**
752
+ * Manages the selected place event triggered from the place
753
+ * Each selection emits an array of all selected places
754
+ * @param selectPlaceEvent
755
+ */
756
+ _onSelectPlace(selectPlaceEvent) {
757
+ const selectedPlace = selectPlaceEvent.detail;
758
+ this.preventCoachScrollByPlaceClick = true;
759
+ this.isCoachGridFocusable = false;
760
+ this.focusedCoachIndex = -1;
761
+ if (!this.hasSeatReservationNativeFocus) {
762
+ this.hasSeatReservationNativeFocus = true;
763
+ }
764
+ if (!this.preventPlaceClick) {
765
+ this.updateSelectedSeatReservationPlaces(selectedPlace);
766
+ this.updateCurrentSelectedPlaceInCoach(selectedPlace);
767
+ }
768
+ }
769
+ _onSelectNavCoach(event) {
770
+ const selectedNavCoachIndex = event.detail;
771
+ this.isKeyboardNavigation = false;
772
+ this.preventCoachScrollByPlaceClick = false;
773
+ this.hasSeatReservationNativeFocus = true;
774
+ if (selectedNavCoachIndex !== null && selectedNavCoachIndex !== this.currSelectedCoachIndex) {
775
+ this.unfocusPlaceElement();
776
+ this.scrollToSelectedNavCoach(selectedNavCoachIndex);
777
+ } else if (selectedNavCoachIndex === this.currSelectedCoachIndex) {
778
+ this.updateCurrentSelectedCoach();
779
+ this.preselectPlaceInCoach();
780
+ }
781
+ this._closePopover();
782
+ }
783
+ _onFocusNavCoach() {
784
+ if (!this.preventCoachScrollByPlaceClick) {
785
+ this.preselectPlaceInCoach();
786
+ } else {
787
+ this.focusPlaceElement(this.currSelectedPlace);
788
+ }
789
+ this.isAutoScrolling = false;
790
+ }
791
+ /**
792
+ * Creates a popover for extra service information
793
+ * @param triggerId
794
+ * @param popoverContent
795
+ * @private
796
+ */
797
+ _popover(triggerId, popoverContent) {
798
+ return html`
799
+ <sbb-popover trigger="${triggerId}" hover-trigger="">
800
+ <p class="sbb-text-s sbb-sr-popover">${popoverContent}</p>
801
+ </sbb-popover>
802
+ `;
803
+ }
804
+ /**
805
+ * trigger to close all opened popovers (normally only one is opened at a time)
806
+ * @private
807
+ */
808
+ _closePopover() {
809
+ this.shadowRoot?.querySelectorAll("sbb-popover:is(:state(state-opened),[state--state-opened])").forEach((popover) => popover.close());
810
+ }
811
+ _getDescriptionTableCoach(coachItem) {
812
+ if (coachItem.type === "LOCOMOTIVE_COACH") {
813
+ return getI18nSeatReservation("COACH_LOCOMOTIVE", this._language.current);
814
+ }
815
+ if (!coachItem.places?.length) {
816
+ return getI18nSeatReservation("COACH_BLOCKED_TABLE_CAPTION", this._language.current, [
817
+ coachItem.id
818
+ ]);
819
+ }
820
+ let tableCoachDescription;
821
+ const areaDescriptions = this._getTitleDescriptionListString(coachItem.graphicElements);
822
+ const serviceDescriptions = this._getTitleDescriptionListString(coachItem.serviceElements);
823
+ tableCoachDescription = getI18nSeatReservation("COACH_TABLE_CAPTION", this._language.current, [
824
+ coachItem.id
825
+ ]);
826
+ if (!this.hasNavigation) {
827
+ const freePlaces = this.getAvailableFreePlacesNumFromCoach(coachItem.places);
828
+ const freePlacesTxt = getI18nSeatReservation("COACH_AVAILABLE_NUMBER_OF_PLACES", this._language.current, [freePlaces.seats, freePlaces.bicycles]);
829
+ tableCoachDescription = tableCoachDescription.concat(". ").concat(freePlacesTxt).concat(". ");
830
+ }
831
+ if (!!areaDescriptions || !!serviceDescriptions) {
832
+ tableCoachDescription += ". " + getI18nSeatReservation("COACH_AVAILABLE_SERVICES", this._language.current) + ": ";
833
+ tableCoachDescription += serviceDescriptions + ", " + areaDescriptions + ".";
834
+ }
835
+ return tableCoachDescription;
836
+ }
837
+ _getTitleDescriptionListString(descriptionsElements) {
838
+ const uniqueDescriptions = [];
839
+ return descriptionsElements?.map((descriptionElement) => {
840
+ const icon = descriptionElement.icon;
841
+ if (!icon)
842
+ return null;
843
+ const descriptionAlreadyExist = uniqueDescriptions.indexOf(icon) > -1;
844
+ const translation = getI18nSeatReservation(descriptionElement.icon, this._language.current);
845
+ const isValidDescription = this._notFixedRotatableAreaIcons.indexOf(icon) === -1 && this.notAreaElements.indexOf(icon) === -1;
846
+ if (!descriptionAlreadyExist) {
847
+ uniqueDescriptions.push(descriptionElement.icon);
848
+ }
849
+ return !!translation && !descriptionAlreadyExist && isValidDescription ? translation : null;
850
+ }).filter((description) => !!description).join(", ");
851
+ }
852
+ };
853
+ _SbbSeatReservationElement.elementName = "sbb-seat-reservation";
854
+ _SbbSeatReservationElement.styles = [boxSizingStyles, style];
855
+ let SbbSeatReservationElement = _SbbSeatReservationElement;
856
+ export {
857
+ SbbSeatReservationElement
858
+ };
859
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VhdC1yZXNlcnZhdGlvbi5jb21wb25lbnQuanMiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9lbGVtZW50cy1leHBlcmltZW50YWwvc2VhdC1yZXNlcnZhdGlvbi9zZWF0LXJlc2VydmF0aW9uL3NlYXQtcmVzZXJ2YXRpb24uY29tcG9uZW50LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFNiYkxhbmd1YWdlQ29udHJvbGxlciB9IGZyb20gJ0BzYmItZXN0YS9seW5lLWVsZW1lbnRzL2NvcmUvY29udHJvbGxlcnMuanMnO1xuaW1wb3J0IHsgYm94U2l6aW5nU3R5bGVzIH0gZnJvbSAnQHNiYi1lc3RhL2x5bmUtZWxlbWVudHMvY29yZS9zdHlsZXMuanMnO1xuaW1wb3J0IHR5cGUgeyBTYmJQb3BvdmVyRWxlbWVudCB9IGZyb20gJ0BzYmItZXN0YS9seW5lLWVsZW1lbnRzL3BvcG92ZXIuanMnO1xuaW1wb3J0IHsgaHRtbCwgbm90aGluZyB9IGZyb20gJ2xpdCc7XG5pbXBvcnQgdHlwZSB7IENTU1Jlc3VsdEdyb3VwLCBQcm9wZXJ0eVZhbHVlcywgVGVtcGxhdGVSZXN1bHQgfSBmcm9tICdsaXQnO1xuaW1wb3J0IHsgY2xhc3NNYXAgfSBmcm9tICdsaXQvZGlyZWN0aXZlcy9jbGFzcy1tYXAuanMnO1xuaW1wb3J0IHsgcmVwZWF0IH0gZnJvbSAnbGl0L2RpcmVjdGl2ZXMvcmVwZWF0LmpzJztcbmltcG9ydCB7IHN0eWxlTWFwIH0gZnJvbSAnbGl0L2RpcmVjdGl2ZXMvc3R5bGUtbWFwLmpzJztcblxuaW1wb3J0IHsgZ2V0STE4blNlYXRSZXNlcnZhdGlvbiB9IGZyb20gJy4uL2NvbW1vbi90cmFuc2xhdGlvbnMudHMnO1xuaW1wb3J0IHR5cGUge1xuICBDb2FjaEl0ZW0sXG4gIENvYWNoSXRlbURldGFpbHMsXG4gIFBsYWNlLFxuICBFbGVtZW50RGltZW5zaW9uLFxuICBCYXNlRWxlbWVudCxcbiAgUGxhY2VTZWxlY3Rpb24sXG4gIFNlYXRSZXNlcnZhdGlvbixcbn0gZnJvbSAnLi4vY29tbW9uL3R5cGVzLnRzJztcbmltcG9ydCB7IFNiYlNlYXRSZXNlcnZhdGlvbkFyZWFFbGVtZW50IH0gZnJvbSAnLi4vc2VhdC1yZXNlcnZhdGlvbi1hcmVhL3NlYXQtcmVzZXJ2YXRpb24tYXJlYS5jb21wb25lbnQudHMnO1xuaW1wb3J0IHsgU2JiU2VhdFJlc2VydmF0aW9uR3JhcGhpY0VsZW1lbnQgfSBmcm9tICcuLi9zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWMvc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljLmNvbXBvbmVudC50cyc7XG5pbXBvcnQgeyBTYmJTZWF0UmVzZXJ2YXRpb25OYXZpZ2F0aW9uQ29hY2hFbGVtZW50IH0gZnJvbSAnLi4vc2VhdC1yZXNlcnZhdGlvbi1uYXZpZ2F0aW9uLWNvYWNoL3NlYXQtcmVzZXJ2YXRpb24tbmF2aWdhdGlvbi1jb2FjaC5jb21wb25lbnQudHMnO1xuaW1wb3J0IHsgU2JiU2VhdFJlc2VydmF0aW9uUGxhY2VDb250cm9sRWxlbWVudCB9IGZyb20gJy4uL3NlYXQtcmVzZXJ2YXRpb24tcGxhY2UtY29udHJvbC9zZWF0LXJlc2VydmF0aW9uLXBsYWNlLWNvbnRyb2wuY29tcG9uZW50LnRzJztcbmltcG9ydCB7IFNiYlNlYXRSZXNlcnZhdGlvblNjb3BlZEVsZW1lbnQgfSBmcm9tICcuLi9zZWF0LXJlc2VydmF0aW9uLXNjb3BlZC9zZWF0LXJlc2VydmF0aW9uLXNjb3BlZC5jb21wb25lbnQudHMnO1xuXG5pbXBvcnQgeyBTZWF0UmVzZXJ2YXRpb25CYXNlRWxlbWVudCB9IGZyb20gJy4vc2VhdC1yZXNlcnZhdGlvbi1iYXNlLWVsZW1lbnQudHMnO1xuaW1wb3J0IHN0eWxlIGZyb20gJy4vc2VhdC1yZXNlcnZhdGlvbi5zY3NzP2xpdCZpbmxpbmUnO1xuXG5pbXBvcnQgJ0BzYmItZXN0YS9seW5lLWVsZW1lbnRzL2J1dHRvbi5qcyc7XG5pbXBvcnQgJ0BzYmItZXN0YS9seW5lLWVsZW1lbnRzL3NjcmVlbi1yZWFkZXItb25seS5qcyc7XG5pbXBvcnQgJ0BzYmItZXN0YS9seW5lLWVsZW1lbnRzL3BvcG92ZXIuanMnO1xuXG5TYmJTZWF0UmVzZXJ2YXRpb25BcmVhRWxlbWVudC5kZWZpbmUoKTtcblNiYlNlYXRSZXNlcnZhdGlvbkdyYXBoaWNFbGVtZW50LmRlZmluZSgpO1xuU2JiU2VhdFJlc2VydmF0aW9uUGxhY2VDb250cm9sRWxlbWVudC5kZWZpbmUoKTtcblNiYlNlYXRSZXNlcnZhdGlvbk5hdmlnYXRpb25Db2FjaEVsZW1lbnQuZGVmaW5lKCk7XG5TYmJTZWF0UmVzZXJ2YXRpb25TY29wZWRFbGVtZW50LmRlZmluZSgpO1xuXG4vKipcbiAqIE1haW4gY29tcG9uZW50IGZvciB0aGUgc2VhdCByZXNlcnZhdGlvbi5cbiAqXG4gKi9cbmV4cG9ydCBjbGFzcyBTYmJTZWF0UmVzZXJ2YXRpb25FbGVtZW50IGV4dGVuZHMgU2VhdFJlc2VydmF0aW9uQmFzZUVsZW1lbnQge1xuICBwdWJsaWMgc3RhdGljIG92ZXJyaWRlIHJlYWRvbmx5IGVsZW1lbnROYW1lOiBzdHJpbmcgPSAnc2JiLXNlYXQtcmVzZXJ2YXRpb24nO1xuICBwdWJsaWMgc3RhdGljIG92ZXJyaWRlIHN0eWxlczogQ1NTUmVzdWx0R3JvdXAgPSBbYm94U2l6aW5nU3R5bGVzLCBzdHlsZV07XG5cbiAgcHJpdmF0ZSBfbGFuZ3VhZ2UgPSBuZXcgU2JiTGFuZ3VhZ2VDb250cm9sbGVyKHRoaXMpO1xuICBwcml2YXRlIF9jb2FjaGVzSHRtbFRlbXBsYXRlPzogVGVtcGxhdGVSZXN1bHQ7XG5cbiAgLy8gQXJlYSBpY29ucyB0aGF0IHNob3VsZCBub3QgYmUgZml4ZWQgZHVyaW5nIHJvdGF0aW9uIHdoZW4gdmVydGljYWwgbW9kZSBpcyBzZWxlY3RlZFxuICBwcml2YXRlIF9ub3RGaXhlZFJvdGF0YWJsZUFyZWFJY29ucyA9IFsnRU5UUllfRVhJVCddO1xuXG4gIHByb3RlY3RlZCBvdmVycmlkZSB3aWxsVXBkYXRlKGNoYW5nZWRQcm9wZXJ0aWVzOiBQcm9wZXJ0eVZhbHVlczx0aGlzPik6IHZvaWQge1xuICAgIHN1cGVyLndpbGxVcGRhdGUoY2hhbmdlZFByb3BlcnRpZXMpO1xuXG4gICAgaWYgKGNoYW5nZWRQcm9wZXJ0aWVzLmhhcygnaGFzTmF2aWdhdGlvbicpKSB7XG4gICAgICBpZiAodGhpcy5oYXNOYXZpZ2F0aW9uKSB7XG4gICAgICAgIHRoaXMuc2hhZG93Um9vdFxuICAgICAgICAgID8ucXVlcnlTZWxlY3RvckFsbCgndGFibGUnKVxuICAgICAgICAgIC5mb3JFYWNoKCh0YWJsZSkgPT4gdGFibGUucmVtb3ZlQXR0cmlidXRlKCd0YWJpbmRleCcpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2hhZG93Um9vdFxuICAgICAgICAgID8ucXVlcnlTZWxlY3RvckFsbCgndGFibGUnKVxuICAgICAgICAgIC5mb3JFYWNoKCh0YWJsZSkgPT4gdGFibGUuc2V0QXR0cmlidXRlKCd0YWJpbmRleCcsICcwJykpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBvdmVycmlkZSBmaXJzdFVwZGF0ZWQoY2hhbmdlZFByb3BlcnRpZXM6IFByb3BlcnR5VmFsdWVzPHRoaXM+KTogdm9pZCB7XG4gICAgc3VwZXIuZmlyc3RVcGRhdGVkKGNoYW5nZWRQcm9wZXJ0aWVzKTtcblxuICAgIC8vIFdlIG5lZWQgdG8gd2FpdCB1bnRpbCB0aGUgZmlyc3QgdXBkYXRlIGlzIGNvbXBsZXRlIHRvIGluaXQgZGlmZmVyZW50IEhUTUwgZWxlbWVudCBkaW1lbnNpb25zXG4gICAgdGhpcy51cGRhdGVDb21wbGV0ZS50aGVuKCgpID0+IHtcbiAgICAgIHRoaXMuaW5pdE5hdmlnYXRpb25TZWxlY3Rpb25CeVNjcm9sbEV2ZW50KCk7XG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgcmVuZGVyKCk6IFRlbXBsYXRlUmVzdWx0IHwgbnVsbCB7XG4gICAgdGhpcy5faW5pdFZlaGljbGVTZWF0UmVzZXJ2YXRpb25Db25zdHJ1Y3Rpb24oKTtcbiAgICByZXR1cm4gdGhpcy5fY29hY2hlc0h0bWxUZW1wbGF0ZSB8fCBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBfaW5pdFZlaGljbGVTZWF0UmVzZXJ2YXRpb25Db25zdHJ1Y3Rpb24oKTogdm9pZCB7XG4gICAgdGhpcy5fY29hY2hlc0h0bWxUZW1wbGF0ZSA9IGh0bWxgXG4gICAgICAke3RoaXMuX3JlbmRlclRyYXZlbERpcmVjdGlvbigpfVxuICAgICAgPGRpdiBjbGFzcz1cInNiYi1zcl9fY29tcG9uZW50XCI+XG4gICAgICAgICR7dGhpcy5fcmVuZGVyTmF2aWdhdGlvbigpfVxuICAgICAgICA8ZGl2XG4gICAgICAgICAgY2xhc3M9XCJzYmItc3JfX3dyYXBwZXItY29hY2gtZGVja3NcIlxuICAgICAgICAgIEBrZXlkb3duPSR7KGV2dDogS2V5Ym9hcmRFdmVudCkgPT4gdGhpcy5rZXlib2FyZFNlYXRtYXBFdmVudEhhbmRsaW5nKGV2dCl9XG4gICAgICAgID5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic2JiLXNyX193cmFwcGVyLWRlY2stbGFiZWxzXCI+JHt0aGlzLl9yZW5kZXJEZWNrTGFiZWxzKCl9PC9kaXY+XG4gICAgICAgICAgPGRpdlxuICAgICAgICAgICAgQHNjcm9sbD0keygpID0+IHRoaXMuY29hY2hBcmVhU2Nyb2xsZW5kKCl9XG4gICAgICAgICAgICBpZD1cInNiYi1zcl9fd3JhcHBlci1zY3JvbGxhcmVhXCJcbiAgICAgICAgICAgIGNsYXNzPVwic2JiLXNyX193cmFwcGVyLXNjcm9sbGFyZWFcIlxuICAgICAgICAgICAgdGFiaW5kZXg9XCItMVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPGRpdiBpZD1cInNiYi1zcl9fcGFyZW50LWFyZWFcIiBjbGFzcz1cInNiYi1zcl9fcGFyZW50XCI+XG4gICAgICAgICAgICAgIDx1bFxuICAgICAgICAgICAgICAgIGNsYXNzPVwiJHtjbGFzc01hcCh7XG4gICAgICAgICAgICAgICAgICAnc2JiLXNyX19saXN0LWRlY2tzJzogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICdzYmItc3JfX2xpc3QtZGVja3MtLWdhcCc6IHRoaXMuaGFzTXVsdGlwbGVEZWNrcyxcbiAgICAgICAgICAgICAgICB9KX1cIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgJHt0aGlzLnNlYXRSZXNlcnZhdGlvbnM/Lm1hcChcbiAgICAgICAgICAgICAgICAgIChzZWF0UmVzZXJ2YXRpb246IFNlYXRSZXNlcnZhdGlvbiwgY29hY2hEZWNrSW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaHRtbGA8bGkgY2xhc3M9XCJzYmItc3JfX2xpc3QtaXRlbS1kZWNrXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPHVsIGNsYXNzPVwic2JiLXNyX19saXN0LWNvYWNoZXNcIiByb2xlPVwicHJlc2VudGF0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAke3RoaXMuX3JlbmRlckNvYWNoZXMoc2VhdFJlc2VydmF0aW9uLCBjb2FjaERlY2tJbmRleCl9XG4gICAgICAgICAgICAgICAgICAgICAgPC91bD5cbiAgICAgICAgICAgICAgICAgICAgPC9saT5gO1xuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgICA8L3VsPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgYDtcbiAgfVxuXG4gIHByaXZhdGUgX3JlbmRlckRlY2tMYWJlbHMoKTogVGVtcGxhdGVSZXN1bHRbXSB8IG51bGwge1xuICAgIGlmICghdGhpcy5oYXNNdWx0aXBsZURlY2tzKSByZXR1cm4gbnVsbDtcblxuICAgIHJldHVybiB0aGlzLnNlYXRSZXNlcnZhdGlvbnMubWFwKChzZWF0UmVzZXJ2YXRpb24pID0+IHtcbiAgICAgIGNvbnN0IGRlY2tEZXNjcmlwdGlvbiA9IGdldEkxOG5TZWF0UmVzZXJ2YXRpb24oXG4gICAgICAgIHNlYXRSZXNlcnZhdGlvbi5kZWNrQ29hY2hMZXZlbCxcbiAgICAgICAgdGhpcy5fbGFuZ3VhZ2UuY3VycmVudCxcbiAgICAgICk7XG4gICAgICByZXR1cm4gaHRtbGA8YiBhcmlhLWhpZGRlbj1cInRydWVcIj4ke2RlY2tEZXNjcmlwdGlvbn08L2I+YDtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX3JlbmRlck5hdmlnYXRpb25Db250cm9sQnV0dG9uKGJ0bkRpcmVjdGlvbjogc3RyaW5nKTogVGVtcGxhdGVSZXN1bHQgfCBudWxsIHtcbiAgICBpZiAoIXRoaXMuaGFzTmF2aWdhdGlvbiB8fCAhdGhpcy5zZWF0UmVzZXJ2YXRpb25zKSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCBidG5OYXZpZ2F0aW9uRGlyZWN0aW9uSWQgPVxuICAgICAgYnRuRGlyZWN0aW9uID09ICdESVJFQ1RJT05fUklHSFQnXG4gICAgICAgID8gJ3NiYi1zci1uYXZpZ2F0aW9uX193cmFwcGVyLWJ1dHRvbi1kaXJlY3Rpb24tLXJpZ2h0J1xuICAgICAgICA6ICdzYmItc3ItbmF2aWdhdGlvbl9fd3JhcHBlci1idXR0b24tZGlyZWN0aW9uLS1sZWZ0JztcbiAgICBjb25zdCBidG5JY29uID1cbiAgICAgIGJ0bkRpcmVjdGlvbiA9PSAnRElSRUNUSU9OX1JJR0hUJyA/ICdjaGV2cm9uLXNtYWxsLXJpZ2h0LXNtYWxsJyA6ICdjaGV2cm9uLXNtYWxsLWxlZnQtc21hbGwnO1xuICAgIGNvbnN0IGJ0bkFyaWFEZXNjcmlwdGlvbiA9XG4gICAgICBidG5EaXJlY3Rpb24gPT0gJ0RJUkVDVElPTl9SSUdIVCdcbiAgICAgICAgPyBnZXRJMThuU2VhdFJlc2VydmF0aW9uKCdTRUFUX1JFU0VSVkFUSU9OX0VORCcsIHRoaXMuX2xhbmd1YWdlLmN1cnJlbnQpXG4gICAgICAgIDogZ2V0STE4blNlYXRSZXNlcnZhdGlvbignU0VBVF9SRVNFUlZBVElPTl9CRUdJTicsIHRoaXMuX2xhbmd1YWdlLmN1cnJlbnQpO1xuICAgIGxldCBidG5EaXNhYmxlZCA9IHRydWU7XG5cbiAgICBpZiAoYnRuRGlyZWN0aW9uID09ICdESVJFQ1RJT05fTEVGVCcgJiYgdGhpcy5zZWxlY3RlZENvYWNoSW5kZXggPiAwKSB7XG4gICAgICBidG5EaXNhYmxlZCA9IGZhbHNlO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICBidG5EaXJlY3Rpb24gPT0gJ0RJUkVDVElPTl9SSUdIVCcgJiZcbiAgICAgIHRoaXMuc2VsZWN0ZWRDb2FjaEluZGV4IDwgdGhpcy5jb2FjaEl0ZW1EZXRhaWxzRWxlbWVudHMubGVuZ3RoIC0gMVxuICAgICkge1xuICAgICAgYnRuRGlzYWJsZWQgPSBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gaHRtbGA8ZGl2IGNsYXNzPVwic2JiLXNyLW5hdmlnYXRpb25fX3dyYXBwZXItYnV0dG9uLWRpcmVjdGlvblwiPlxuICAgICAgPHNiYi1zZWNvbmRhcnktYnV0dG9uXG4gICAgICAgIEBjbGljaz1cIiR7KCkgPT4gdGhpcy5uYXZpZ2F0ZUJ5RGlyZWN0aW9uQnRuKGJ0bkRpcmVjdGlvbil9XCJcbiAgICAgICAgQGZvY3VzPVwiJHsoKSA9PiB0aGlzLm9uRm9jdXNOYXZEaXJlY3Rpb25CdXR0b24oKX1cIlxuICAgICAgICBpZD1cIiR7YnRuTmF2aWdhdGlvbkRpcmVjdGlvbklkfVwiXG4gICAgICAgIGNsYXNzPVwic2JiLXNyX19uYXZpZ2F0aW9uLWNvbnRyb2wtYnV0dG9uXCJcbiAgICAgICAgc2l6ZT1cIm1cIlxuICAgICAgICBpY29uLW5hbWU9XCIke2J0bkljb259XCJcbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIGFyaWEtbGFiZWw9XCIke2J0bkFyaWFEZXNjcmlwdGlvbn1cIlxuICAgICAgICByb2xlPVwiYnV0dG9uXCJcbiAgICAgICAgLmRpc2FibGVkSW50ZXJhY3RpdmU9XCIke2J0bkRpc2FibGVkIHx8IG5vdGhpbmd9XCJcbiAgICAgICAgLmRpc2FibGVkPVwiJHtidG5EaXNhYmxlZCB8fCBub3RoaW5nfVwiXG4gICAgICA+PC9zYmItc2Vjb25kYXJ5LWJ1dHRvbj5cbiAgICA8L2Rpdj5gO1xuICB9XG5cbiAgcHJpdmF0ZSBfcmVuZGVyVHJhdmVsRGlyZWN0aW9uKCk6IFRlbXBsYXRlUmVzdWx0IHwgbnVsbCB7XG4gICAgaWYgKCF0aGlzLnRyYXZlbERpcmVjdGlvbiB8fCB0aGlzLnRyYXZlbERpcmVjdGlvbiA9PT0gJ05PTkUnKSByZXR1cm4gbnVsbDtcblxuICAgIGNvbnN0IGxhYmVsVGV4dCA9IGdldEkxOG5TZWF0UmVzZXJ2YXRpb24oXG4gICAgICAnU0VBVF9SRVNFUlZBVElPTl9UUkFWRUxfRElSRUNUSU9OJyxcbiAgICAgIHRoaXMuX2xhbmd1YWdlLmN1cnJlbnQsXG4gICAgKTtcblxuICAgIGNvbnN0IGFycm93RGlyZWN0aW9uID0gdGhpcy5hbGlnblZlcnRpY2FsXG4gICAgICA/IHRoaXMudHJhdmVsRGlyZWN0aW9uID09PSAnUklHSFQnXG4gICAgICAgID8gJ2Rvd24nXG4gICAgICAgIDogJ3VwJ1xuICAgICAgOiB0aGlzLnRyYXZlbERpcmVjdGlvbiA9PT0gJ1JJR0hUJ1xuICAgICAgICA/ICdyaWdodCdcbiAgICAgICAgOiAnbGVmdCc7XG5cbiAgICBjb25zdCBpY29uTmFtZSA9IGBhcnJvdy0ke2Fycm93RGlyZWN0aW9ufS1zbWFsbGA7XG5cbiAgICByZXR1cm4gaHRtbGA8ZGl2IGNsYXNzPVwic2JiLXNyLXRyYXZlbC1kaXJlY3Rpb24td3JhcHBlclwiPlxuICAgICAgPGRpdiBjbGFzcz1cInNiYi1zcl9fdHJhdmVsLWRpcmVjdGlvbi0tYXJyb3dcIj5cbiAgICAgICAgPHNiYi1pY29uIHNsb3Q9XCJpY29uXCIgbmFtZT1cIiR7aWNvbk5hbWV9XCI+PC9zYmItaWNvbj5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cInNiYi1zcl9fdHJhdmVsLWRpcmVjdGlvbi0tbGFiZWxcIj4ke2xhYmVsVGV4dH08L2Rpdj5cbiAgICA8L2Rpdj5gO1xuICB9XG5cbiAgcHJpdmF0ZSBfcmVuZGVyTmF2aWdhdGlvbigpOiBUZW1wbGF0ZVJlc3VsdCB8IG51bGwge1xuICAgIGlmICghdGhpcy5oYXNOYXZpZ2F0aW9uIHx8ICF0aGlzLnNlYXRSZXNlcnZhdGlvbnMpIHJldHVybiBudWxsO1xuICAgIHJldHVybiBodG1sYDxkaXYgY2xhc3M9XCJzYmItc3ItbmF2aWdhdGlvbi13cmFwcGVyXCI+XG4gICAgICA8bmF2IGlkPVwic2JiLXNyLW5hdmlnYXRpb25cIiBjbGFzcz1cInNiYi1zci1uYXZpZ2F0aW9uXCI+XG4gICAgICAgICR7dGhpcy5fcmVuZGVyTmF2aWdhdGlvbkNvbnRyb2xCdXR0b24oJ0RJUkVDVElPTl9MRUZUJyl9XG4gICAgICAgIDx1bFxuICAgICAgICAgIGlkPVwic2JiLXNyX19uYXZpZ2F0aW9uLWxpc3QtY29hY2hlc1wiXG4gICAgICAgICAgY2xhc3M9XCJzYmItc3ItbmF2aWdhdGlvbl9fbGlzdC1jb2FjaGVzXCJcbiAgICAgICAgICBhcmlhLWxhYmVsPVwiJHtnZXRJMThuU2VhdFJlc2VydmF0aW9uKFxuICAgICAgICAgICAgJ1NFQVRfUkVTRVJWQVRJT05fTkFWSUdBVElPTicsXG4gICAgICAgICAgICB0aGlzLl9sYW5ndWFnZS5jdXJyZW50LFxuICAgICAgICAgICl9XCJcbiAgICAgICAgPlxuICAgICAgICAgICR7dGhpcy5jb2FjaEl0ZW1EZXRhaWxzRWxlbWVudHMubWFwKFxuICAgICAgICAgICAgKGNvYWNoSXRlbURldGFpbHM6IENvYWNoSXRlbURldGFpbHMsIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgICAgICAgcmV0dXJuIGh0bWxgPGxpPlxuICAgICAgICAgICAgICAgIDxzYmItc2VhdC1yZXNlcnZhdGlvbi1uYXZpZ2F0aW9uLWNvYWNoXG4gICAgICAgICAgICAgICAgICBAc2VsZWN0Y29hY2g9JHsoZXZlbnQ6IEN1c3RvbUV2ZW50PG51bWJlcj4pID0+IHRoaXMuX29uU2VsZWN0TmF2Q29hY2goZXZlbnQpfVxuICAgICAgICAgICAgICAgICAgQGZvY3VzY29hY2g9JHsoKSA9PiB0aGlzLl9vbkZvY3VzTmF2Q29hY2goKX1cbiAgICAgICAgICAgICAgICAgIEBrZXl1cD0keyhldnQ6IEtleWJvYXJkRXZlbnQpID0+IHRoaXMub25LZXlOYXZpZ2F0aW9uTmF2Q29hY2hCdXR0b24oZXZ0LCBpbmRleCl9XG4gICAgICAgICAgICAgICAgICBpbmRleD1cIiR7aW5kZXh9XCJcbiAgICAgICAgICAgICAgICAgIC5zZWxlY3RlZD0ke3RoaXMuc2VsZWN0ZWRDb2FjaEluZGV4ID09PSBpbmRleH1cbiAgICAgICAgICAgICAgICAgIC5mb2N1c2VkPSR7dGhpcy5mb2N1c2VkQ29hY2hJbmRleCA9PT0gaW5kZXh9XG4gICAgICAgICAgICAgICAgICAuaG92ZXJlZD0ke3RoaXMuaG92ZXJlZENvYWNoSW5kZXggPT09IGluZGV4fVxuICAgICAgICAgICAgICAgICAgLm5hdGl2ZUZvY3VzQWN0aXZlPSR7dGhpcy5oYXNTZWF0UmVzZXJ2YXRpb25OYXRpdmVGb2N1c31cbiAgICAgICAgICAgICAgICAgIC5jb2FjaEl0ZW1EZXRhaWxzPVwiJHtjb2FjaEl0ZW1EZXRhaWxzfVwiXG4gICAgICAgICAgICAgICAgICA/dmVydGljYWw9XCIke3RoaXMuYWxpZ25WZXJ0aWNhbH1cIlxuICAgICAgICAgICAgICAgICAgP3Nob3dUaXRsZUluZm89XCIke3RoaXMuc2hvd1RpdGxlSW5mb31cIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8L3NiYi1zZWF0LXJlc2VydmF0aW9uLW5hdmlnYXRpb24tY29hY2g+XG4gICAgICAgICAgICAgIDwvbGk+YDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgKX1cbiAgICAgICAgPC91bD5cbiAgICAgICAgJHt0aGlzLl9yZW5kZXJOYXZpZ2F0aW9uQ29udHJvbEJ1dHRvbignRElSRUNUSU9OX1JJR0hUJyl9XG4gICAgICA8L25hdj5cbiAgICA8L2Rpdj5gO1xuICB9XG4gIC8qKlxuICAgKlxuICAgKiBAcmV0dXJuc1xuICAgKiBAcGFyYW0gc2VhdFJlc2VydmF0aW9uXG4gICAqIEBwYXJhbSBjb2FjaERlY2tJbmRleFxuICAgKi9cbiAgcHJpdmF0ZSBfcmVuZGVyQ29hY2hlcyhcbiAgICBzZWF0UmVzZXJ2YXRpb246IFNlYXRSZXNlcnZhdGlvbixcbiAgICBjb2FjaERlY2tJbmRleDogbnVtYmVyLFxuICApOiBUZW1wbGF0ZVJlc3VsdFtdIHwgbnVsbCB7XG4gICAgY29uc3QgY29hY2hlczogQ29hY2hJdGVtW10gPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHNlYXRSZXNlcnZhdGlvbj8uY29hY2hJdGVtcykpO1xuXG4gICAgaWYgKCFjb2FjaGVzKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIGNvYWNoZXMubWFwKChjb2FjaEl0ZW06IENvYWNoSXRlbSwgY29hY2hJbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICByZXR1cm4gaHRtbGBcbiAgICAgICAgPGxpIGNsYXNzPVwic2JiLXNyX19pdGVtLWNvYWNoXCI+XG4gICAgICAgICAgJHt0aGlzLl9yZW5kZXJDb2FjaEVsZW1lbnQoXG4gICAgICAgICAgICBjb2FjaEl0ZW0sXG4gICAgICAgICAgICBjb2FjaEluZGV4LFxuICAgICAgICAgICAgY29hY2hEZWNrSW5kZXgsXG4gICAgICAgICAgICBzZWF0UmVzZXJ2YXRpb24uZGVja0NvYWNoSW5kZXgsXG4gICAgICAgICAgKX1cbiAgICAgICAgPC9saT5cbiAgICAgIGA7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9yZW5kZXJDb2FjaEVsZW1lbnQoXG4gICAgY29hY2hJdGVtOiBDb2FjaEl0ZW0sXG4gICAgY29hY2hJbmRleDogbnVtYmVyLFxuICAgIGNvYWNoRGVja0luZGV4OiBudW1iZXIsXG4gICAgcGxhY2VDb2FjaERlY2tJbmRleDogbnVtYmVyLFxuICApOiBUZW1wbGF0ZVJlc3VsdCB7XG4gICAgY29uc3QgY2FsY3VsYXRlZENvYWNoRGltZW5zaW9uID0gdGhpcy5nZXRDYWxjdWxhdGVkRGltZW5zaW9uKGNvYWNoSXRlbS5kaW1lbnNpb24pO1xuICAgIGNvbnN0IGRlc2NyaXB0aW9uVGFibGVDb2FjaFdpdGhTZXJ2aWNlcyA9IHRoaXMuX2dldERlc2NyaXB0aW9uVGFibGVDb2FjaChjb2FjaEl0ZW0pO1xuXG4gICAgcmV0dXJuIGh0bWxgPHNiYi1zZWF0LXJlc2VydmF0aW9uLXNjb3BlZFxuICAgICAgc3R5bGU9JHtzdHlsZU1hcCh7XG4gICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLXNjb3BlZC13aWR0aCc6IGNhbGN1bGF0ZWRDb2FjaERpbWVuc2lvbi53LFxuICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1zY29wZWQtaGVpZ2h0JzogY2FsY3VsYXRlZENvYWNoRGltZW5zaW9uLmgsXG4gICAgICB9KX1cbiAgICA+XG4gICAgICAke3RoaXMuX2dldFJlbmRlcmVkQ29hY2hCb3JkZXJzKGNvYWNoSXRlbSwgY29hY2hJbmRleCl9XG4gICAgICAke3RoaXMuX2dldFJlbmRlcmVkR3JhcGhpY2FsRWxlbWVudHMoXG4gICAgICAgIGNvYWNoSXRlbS5ncmFwaGljRWxlbWVudHMgfHwgW10sXG4gICAgICAgIGNvYWNoSXRlbS5kaW1lbnNpb24sXG4gICAgICAgIGNvYWNoSW5kZXgsXG4gICAgICAgIGNvYWNoRGVja0luZGV4LFxuICAgICAgKX1cbiAgICAgICR7dGhpcy5fZ2V0UmVuZGVyZWRTZXJ2aWNlRWxlbWVudHMoY29hY2hJbmRleCwgY29hY2hEZWNrSW5kZXgsIGNvYWNoSXRlbS5zZXJ2aWNlRWxlbWVudHMpfVxuXG4gICAgICA8dGFibGVcbiAgICAgICAgQGZvY3VzPSR7KCkgPT4gdGhpcy5vbkZvY3VzVGFibGVDb2FjaEFuZFByZXNlbGVjdFBsYWNlKGNvYWNoSW5kZXgpfVxuICAgICAgICBpZD1cInNiYi1zci1jb2FjaC0ke2NvYWNoSW5kZXh9XCJcbiAgICAgICAgY2xhc3M9XCJzYmItc3ItY29hY2gtd3JhcHBlcl9fdGFibGVcIlxuICAgICAgICBhcmlhLWRlc2NyaWJlZGJ5PVwic2JiLXNyLWNvYWNoLWNhcHRpb24tJHtjb2FjaEluZGV4fVwiXG4gICAgICAgIHRhYmluZGV4PVwiLTFcIlxuICAgICAgPlxuICAgICAgICA8Y2FwdGlvbiBpZD1cInNiYi1zci1jb2FjaC1jYXB0aW9uLSR7Y29hY2hJbmRleH1cIiB0YWJpbmRleD1cIi0xXCI+XG4gICAgICAgICAgPHNiYi1zY3JlZW4tcmVhZGVyLW9ubHk+JHtkZXNjcmlwdGlvblRhYmxlQ29hY2hXaXRoU2VydmljZXN9PC9zYmItc2NyZWVuLXJlYWRlci1vbmx5PlxuICAgICAgICA8L2NhcHRpb24+XG4gICAgICAgICR7dGhpcy5fZ2V0UmVuZGVyZWRSb3dQbGFjZXMoY29hY2hJdGVtLCBjb2FjaEluZGV4LCBjb2FjaERlY2tJbmRleCwgcGxhY2VDb2FjaERlY2tJbmRleCl9XG4gICAgICA8L3RhYmxlPlxuICAgIDwvc2JiLXNlYXQtcmVzZXJ2YXRpb24tc2NvcGVkPmA7XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMgUmV0dXJucyB0aGUgYm9yZGVyIGdyYXBoaWMgKENPQUNIX0JPUkRFUl9NSURETEUpIG9mIGEgY29hY2ggd2l0aCBjYWxjdWxhdGVkIGJvcmRlciBnYXAgYW5kIGNvYWNoIHdpZHRoLFxuICAgKiBkZXBlbmRpbmcgb24gd2hldGhlciB0aGUgY29hY2ggaXMgd2l0aCBhIGRyaXZlciBhcmVhIG9yIHdpdGhvdXQuXG4gICAqL1xuICBwcml2YXRlIF9nZXRSZW5kZXJlZENvYWNoQm9yZGVycyhcbiAgICBjb2FjaEl0ZW06IENvYWNoSXRlbSxcbiAgICBjb2FjaEluZGV4OiBudW1iZXIsXG4gICk6IFRlbXBsYXRlUmVzdWx0IHwgbnVsbCB7XG4gICAgaWYgKCFjb2FjaEl0ZW0uZ3JhcGhpY0VsZW1lbnRzKSByZXR1cm4gbnVsbDtcblxuICAgIGNvbnN0IENPQUNIX1BBU1NBR0VfV0lEVEggPSAxO1xuICAgIGNvbnN0IGRyaXZlckFyZWEgPSB0aGlzLmNvYWNoSXRlbURldGFpbHNFbGVtZW50c1tjb2FjaEluZGV4XT8uZHJpdmVyQXJlYUVsZW1lbnRzPy5kcml2ZXJBcmVhO1xuICAgIGNvbnN0IGRyaXZlckFyZWFOb1ZlcnRpY2FsV2FsbCA9XG4gICAgICB0aGlzLmNvYWNoSXRlbURldGFpbHNFbGVtZW50c1tjb2FjaEluZGV4XT8uZHJpdmVyQXJlYUVsZW1lbnRzPy5kcml2ZXJBcmVhTm9WZXJ0aWNhbFdhbGw7XG5cbiAgICBsZXQgYm9yZGVyV2lkdGggPSBkcml2ZXJBcmVhXG4gICAgICA/IGNvYWNoSXRlbS5kaW1lbnNpb24udyAtIGRyaXZlckFyZWEuZGltZW5zaW9uLncgLSBDT0FDSF9QQVNTQUdFX1dJRFRIXG4gICAgICA6IGNvYWNoSXRlbS5kaW1lbnNpb24udyAtIENPQUNIX1BBU1NBR0VfV0lEVEggKiAyO1xuXG4gICAgLy9tdWx0aXBseSB3aXRoIGJhc2UgZ3JpZCBzaXplIGFsd2F5cyBmb3IgYWxsIGtpbmQgb2YgYm9yZGVyV2lkdGhcbiAgICBib3JkZXJXaWR0aCAqPSB0aGlzLmJhc2VHcmlkU2l6ZTtcblxuICAgIGNvbnN0IGJvcmRlckhlaWdodCA9IChjb2FjaEl0ZW0uZGltZW5zaW9uLmggKyB0aGlzLmNvYWNoQm9yZGVyT2Zmc2V0ICogMikgKiB0aGlzLmJhc2VHcmlkU2l6ZTtcbiAgICBsZXQgYm9yZGVyT2Zmc2V0WCA9XG4gICAgICBkcml2ZXJBcmVhICYmIGRyaXZlckFyZWEucG9zaXRpb24ueCA9PT0gMFxuICAgICAgICA/IGRyaXZlckFyZWE/LmRpbWVuc2lvbi53ICogdGhpcy5iYXNlR3JpZFNpemVcbiAgICAgICAgOiB0aGlzLmJhc2VHcmlkU2l6ZTtcblxuICAgIC8vcmVjYWxjdWxhdGUgdGhlIGJvcmRlciB3aWR0aCBhbmQgb2Zmc2V0IGlmIHRoZXJlIGlzIGEgZHJpdmVyIGFyZWEgd2l0aG91dCB2ZXJ0aWNhbCB3YWxsIG9uIGJvdGggc2lkZXNcbiAgICBpZiAoZHJpdmVyQXJlYU5vVmVydGljYWxXYWxsKSB7XG4gICAgICBjb25zdCBjb2FjaFdpZHRoID0gdGhpcy5nZXRDYWxjdWxhdGVkRGltZW5zaW9uKGNvYWNoSXRlbS5kaW1lbnNpb24pLnc7XG5cbiAgICAgIC8vcmVjYWxjdWxhdGVkIGJvcmRlcldpZHRoID0gY29hY2hXaWR0aCAtIDIgKiBkcml2ZXIgYXJlYSB3aWR0aCwgc2luY2UgdGhlIGRyaXZlciBhcmVhIGlzIG9uIGJvdGggc2lkZXNcbiAgICAgIGJvcmRlcldpZHRoID0gY29hY2hXaWR0aCAtIDIgKiAoZHJpdmVyQXJlYU5vVmVydGljYWxXYWxsLmRpbWVuc2lvbi53ICogdGhpcy5iYXNlR3JpZFNpemUpO1xuXG4gICAgICAvL3JlY2FsY3VsYXRlZCBib3JkZXJPZmZzZXRYID0gZHJpdmVyIGFyZWEgd2lkdGgsIHNpbmNlIHRoZSBib3JkZXIgc3RhcnRzIGFmdGVyIHRoZSBkcml2ZXIgYXJlYSBvbiB0aGUgbGVmdCBzaWRlXG4gICAgICBib3JkZXJPZmZzZXRYID0gZHJpdmVyQXJlYU5vVmVydGljYWxXYWxsLmRpbWVuc2lvbi53ICogdGhpcy5iYXNlR3JpZFNpemU7XG4gICAgfVxuXG4gICAgY29uc3QgY3VycmVudENvYWNoT3ZlcmxhcHBpbmdJbmZvID0gdGhpcy5vdmVySGFuZ2luZ0VsZW1lbnRJbmZvcm1hdGlvbi5maW5kKFxuICAgICAgKGVsKSA9PiBlbC5jb2FjaElkID09IGNvYWNoSXRlbS5pZCxcbiAgICApO1xuXG4gICAgLy8gY2hlY2sgaWYgdGhlcmUgYXJlIG92ZXJoYW5naW5nIHBsYWNlcyBvciBncmFwaGljYWwgZWxlbWVudHMgdG8gYWRqdXN0IHRoZSBib3JkZXIgd2lkdGggYW5kIG9mZnNldCArIGdhcFxuICAgIC8vIFdlIGRvIG5vdCBkaWZmZXJlbnRpYXRlIHdoZXRoZXIgdGhlcmUgaXMgc29tZXRoaW5nIHRvIGJlIGRvbmUgb24gYm90aCBzaWRlcyBhcyB0aGlzIHdvdWxkIGxlYWQgdG8gdW5uZWNlc3NhcnlcbiAgICAvLyBjb21wbGV4aXR5LiBTbyBpZiB0aGVyZSBpcyBzb21ldGhpbmcgb24gb25lIHNpZGUsIHdlIGp1c3QgaW5jcmVhc2UgdGhlIGNvYWNoLWJvcmRlciBvbiBib3RoIHNpZGVzLlxuICAgIGlmIChcbiAgICAgIGN1cnJlbnRDb2FjaE92ZXJsYXBwaW5nSW5mbz8ub3ZlcmhhbmdpbmdQbGFjZXMgfHxcbiAgICAgIGN1cnJlbnRDb2FjaE92ZXJsYXBwaW5nSW5mbz8ub3ZlcmhhbmdpbmdHcmFwaGljQXJlYXNcbiAgICApIHtcbiAgICAgIGJvcmRlcldpZHRoICs9IDIgKiB0aGlzLmJhc2VHcmlkU2l6ZTsgLy8gd2UgaW5jcmVhc2UgdGhlIHdpZHRoIGJ5IDIgZ3JpZCBzaXplcyB0byBoYXZlIGVub3VnaCBzcGFjZSBmb3IgcHJvdHJ1ZGVkIHBsYWNlcyBvbiBib3RoIHNpZGVzXG4gICAgICBib3JkZXJPZmZzZXRYID0gMDsgLy8gd2Ugc3RhcnQgYXQgMCB0byBoYXZlIGVub3VnaCBzcGFjZSBvbiB0aGUgbGVmdCBzaWRlIGFzIHdlbGxcbiAgICB9XG5cbiAgICByZXR1cm4gaHRtbGBcbiAgICAgIDxzYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljXG4gICAgICAgIGNsYXNzPVwiJHtjbGFzc01hcCh7XG4gICAgICAgICAgJ3NiYi1zci1jb2FjaC1oYXMtb3ZlcmhhbmdpbmctZWxlbWVudHMnOlxuICAgICAgICAgICAgY3VycmVudENvYWNoT3ZlcmxhcHBpbmdJbmZvPy5vdmVyaGFuZ2luZ1BsYWNlcyB8fFxuICAgICAgICAgICAgY3VycmVudENvYWNoT3ZlcmxhcHBpbmdJbmZvPy5vdmVyaGFuZ2luZ0dyYXBoaWNBcmVhcyB8fFxuICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgIH0pfVwiXG4gICAgICAgIHN0eWxlPSR7c3R5bGVNYXAoe1xuICAgICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWMtd2lkdGgnOiBib3JkZXJXaWR0aCxcbiAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljLWhlaWdodCc6IGJvcmRlckhlaWdodCxcbiAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljLXRvcCc6IHRoaXMuY29hY2hCb3JkZXJQYWRkaW5nICogLTEsXG4gICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JhcGhpYy1sZWZ0JzogYm9yZGVyT2Zmc2V0WCxcbiAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljLXBvc2l0aW9uJzogJ2Fic29sdXRlJyxcbiAgICAgICAgfSl9XG4gICAgICAgIG5hbWU9XCJDT0FDSF9CT1JERVJfTUlERExFXCJcbiAgICAgICAgP3N0cmV0Y2g9JHt0cnVlfVxuICAgICAgICByb2xlPVwicHJlc2VudGF0aW9uXCJcbiAgICAgID48L3NiYi1zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWM+XG4gICAgYDtcbiAgfVxuXG4gIHByaXZhdGUgX2dldFJlbmRlcmVkUm93UGxhY2VzKFxuICAgIGNvYWNoOiBDb2FjaEl0ZW0sXG4gICAgY29hY2hJbmRleDogbnVtYmVyLFxuICAgIGNvYWNoRGVja0luZGV4OiBudW1iZXIsXG4gICAgcGxhY2VDb2FjaERlY2tJbmRleDogbnVtYmVyLFxuICApOiBUZW1wbGF0ZVJlc3VsdFtdIHwgbnVsbCB7XG4gICAgaWYgKCFjb2FjaC5wbGFjZXMpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8vIFByZXBhcmUgcm93cyB3aXRoIHRoZSBwbGFjZXMgdG8gcmVuZGVyIGEgdGFibGVcbiAgICBjb25zdCB0YWJsZVJvd1BsYWNlczogUmVjb3JkPG51bWJlciwgUGxhY2VbXT4gPSB7fTtcbiAgICBmb3IgKGNvbnN0IHBsYWNlIG9mIGNvYWNoLnBsYWNlcykge1xuICAgICAgaWYgKCF0YWJsZVJvd1BsYWNlc1twbGFjZS5wb3NpdGlvbi55XSkge1xuICAgICAgICB0YWJsZVJvd1BsYWNlc1twbGFjZS5wb3NpdGlvbi55XSA9IFtwbGFjZV07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0YWJsZVJvd1BsYWNlc1twbGFjZS5wb3NpdGlvbi55XS5wdXNoKHBsYWNlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gT2JqZWN0LnZhbHVlcyh0YWJsZVJvd1BsYWNlcylcbiAgICAgIC5tYXAoKHJvd1BsYWNlczogUGxhY2VbXSwgaW5kZXgpID0+IHtcbiAgICAgICAgcmV0dXJuIGh0bWxgXG4gICAgICAgICAgPHRyIGlkPVwicm93LSR7Y29hY2hJbmRleH0tJHtyb3dQbGFjZXNbMF0ucG9zaXRpb24ueX1cIiBkYXRhLXJvdy1pbmRleD0ke2luZGV4fT5cbiAgICAgICAgICAgICR7dGhpcy5fZ2V0UmVuZGVyZWRDb2x1bW5QbGFjZXMoXG4gICAgICAgICAgICAgIHJvd1BsYWNlcyxcbiAgICAgICAgICAgICAgY29hY2hJbmRleCxcbiAgICAgICAgICAgICAgY29hY2hEZWNrSW5kZXgsXG4gICAgICAgICAgICAgIHBsYWNlQ29hY2hEZWNrSW5kZXgsXG4gICAgICAgICAgICApfVxuICAgICAgICAgIDwvdHI+XG4gICAgICAgIGA7XG4gICAgICB9KVxuICAgICAgLmZsYXRNYXAoKHJvd1RlbXBsYXRlKSA9PiByb3dUZW1wbGF0ZSk7XG4gIH1cblxuICBwcml2YXRlIF9nZXRSZW5kZXJlZENvbHVtblBsYWNlcyhcbiAgICBwbGFjZXM6IFBsYWNlW10sXG4gICAgY29hY2hJbmRleDogbnVtYmVyLFxuICAgIGRlY2tJbmRleDogbnVtYmVyLFxuICAgIHBsYWNlQ29hY2hEZWNrSW5kZXg6IG51bWJlcixcbiAgKTogVGVtcGxhdGVSZXN1bHQgfCBudWxsIHtcbiAgICAvL1NvcnRzIGVhY2ggcGxhY2UgYnkgaXRzIGFzY2VuZGluZyB4IGNvb3JkaW5hdGVcbiAgICBwbGFjZXMuc29ydChcbiAgICAgIChwbGFjZUE6IFBsYWNlLCBwbGFjZUI6IFBsYWNlKSA9PiBOdW1iZXIocGxhY2VBLnBvc2l0aW9uLngpIC0gTnVtYmVyKHBsYWNlQi5wb3NpdGlvbi54KSxcbiAgICApO1xuXG4gICAgLy8gRm9yIHJlbmRlcmluZyB0aGUgcGxhY2VzIHdpdGhpbiBhIHRkIGVsZW1lbnQsIGhlcmUgd2UgdXNlIHJlcGVhdCBkaXJlY3RpdmUgZm9yIGJldHRlciBwZXJmb3JtYW5jZSBmb3IgcmV1c2luZyBlbGVtZW50cyAodHJhY2sgYnkgaWQpLlxuICAgIGNvbnN0IHRyYWNrUGxhY2VJZCA9IGNvYWNoSW5kZXggKyAnLScgKyBwbGFjZUNvYWNoRGVja0luZGV4O1xuICAgIHJldHVybiBodG1sYCR7cmVwZWF0KFxuICAgICAgcGxhY2VzLFxuICAgICAgKHBsYWNlKSA9PiB0cmFja1BsYWNlSWQgKyAnLScgKyBwbGFjZS5udW1iZXIsXG4gICAgICAocGxhY2UsIGluZGV4KSA9PiB7XG4gICAgICAgIGNvbnN0IGNhbGN1bGF0ZWREaW1lbnNpb24gPSB0aGlzLmdldENhbGN1bGF0ZWREaW1lbnNpb24ocGxhY2UuZGltZW5zaW9uKTtcbiAgICAgICAgY29uc3QgY2FsY3VsYXRlZFBvc2l0aW9uID0gdGhpcy5nZXRDYWxjdWxhdGVkUG9zaXRpb24ocGxhY2UucG9zaXRpb24pO1xuICAgICAgICBjb25zdCByb3RhdGlvbiA9IHBsYWNlLnJvdGF0aW9uIHx8IDA7XG4gICAgICAgIGNvbnN0IHRleHRSb3RhdGlvbiA9IHRoaXMuYWxpZ25WZXJ0aWNhbCA/IC05MCA6IDA7XG4gICAgICAgIGNvbnN0IHBsYWNlSWQgPSB0aGlzLmdldFBsYWNlRWxlbWVudElkKGRlY2tJbmRleCwgY29hY2hJbmRleCwgcGxhY2UubnVtYmVyKTtcbiAgICAgICAgcmV0dXJuIGh0bWxgXG4gICAgICAgICAgPHRkXG4gICAgICAgICAgICBpZD1cImNlbGwtJHtkZWNrSW5kZXh9LSR7Y29hY2hJbmRleH0tJHtwbGFjZS5wb3NpdGlvbi55fS0ke2luZGV4fVwiXG4gICAgICAgICAgICBjbGFzcz1cImdyYXBoaWNhbC1lbGVtZW50XCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8c2JiLXNlYXQtcmVzZXJ2YXRpb24tcGxhY2UtY29udHJvbFxuICAgICAgICAgICAgICBzdHlsZT0ke3N0eWxlTWFwKHtcbiAgICAgICAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1wbGFjZS1jb250cm9sLXRleHQtc2NhbGUtdmFsdWUnOiBNYXRoLm1pbihcbiAgICAgICAgICAgICAgICAgIGNhbGN1bGF0ZWREaW1lbnNpb24udyxcbiAgICAgICAgICAgICAgICAgIGNhbGN1bGF0ZWREaW1lbnNpb24uaCxcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLXBsYWNlLWNvbnRyb2wtd2lkdGgnOiBjYWxjdWxhdGVkRGltZW5zaW9uLncsXG4gICAgICAgICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tcGxhY2UtY29udHJvbC1oZWlnaHQnOiBjYWxjdWxhdGVkRGltZW5zaW9uLmgsXG4gICAgICAgICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tcGxhY2UtY29udHJvbC10b3AnOiBjYWxjdWxhdGVkUG9zaXRpb24ueSxcbiAgICAgICAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1wbGFjZS1jb250cm9sLWxlZnQnOiBjYWxjdWxhdGVkUG9zaXRpb24ueCxcbiAgICAgICAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1wbGFjZS1jb250cm9sLXJvdGF0aW9uJzogcm90YXRpb24sXG4gICAgICAgICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tcGxhY2UtY29udHJvbC10ZXh0LXJvdGF0aW9uJzogdGV4dFJvdGF0aW9uLFxuICAgICAgICAgICAgICB9KX1cbiAgICAgICAgICAgICAgQHNlbGVjdHBsYWNlPSR7KHNlbGVjdFBsYWNlRXZlbnQ6IEN1c3RvbUV2ZW50PFBsYWNlU2VsZWN0aW9uPikgPT5cbiAgICAgICAgICAgICAgICB0aGlzLl9vblNlbGVjdFBsYWNlKHNlbGVjdFBsYWNlRXZlbnQpfVxuICAgICAgICAgICAgICBleHBvcnRwYXJ0cz1cInNiYi1zci1wbGFjZS1wYXJ0XCJcbiAgICAgICAgICAgICAgaWQ9JHtwbGFjZUlkfVxuICAgICAgICAgICAgICBjbGFzcz1cInNlYXQtcmVzZXJ2YXRpb24tcGxhY2UtY29udHJvbFwiXG4gICAgICAgICAgICAgIHRleHQ9JHtwbGFjZS5udW1iZXJ9XG4gICAgICAgICAgICAgIHR5cGU9JHtwbGFjZS50eXBlfVxuICAgICAgICAgICAgICBzdGF0ZT0ke3BsYWNlLnN0YXRlfVxuICAgICAgICAgICAgICB0cmF2ZWwtZGlyZWN0aW9uPSR7dGhpcy50cmF2ZWxEaXJlY3Rpb259XG4gICAgICAgICAgICAgIGNvYWNoLWluZGV4PSR7Y29hY2hJbmRleH1cbiAgICAgICAgICAgICAgZGVjay1pbmRleD0ke3BsYWNlQ29hY2hEZWNrSW5kZXh9XG4gICAgICAgICAgICAgIGRhdGEtZGVjay1pbmRleD0ke2RlY2tJbmRleH1cbiAgICAgICAgICAgICAgLnByb3BlcnR5SWRzPSR7cGxhY2UucHJvcGVydHlJZHN9XG4gICAgICAgICAgICAgIC5wcmV2ZW50Q2xpY2s9JHt0aGlzLnByZXZlbnRQbGFjZUNsaWNrfVxuICAgICAgICAgICAgICA/c2hvd1RpdGxlSW5mbz1cIiR7dGhpcy5zaG93VGl0bGVJbmZvfVwiXG4gICAgICAgICAgICA+PC9zYmItc2VhdC1yZXNlcnZhdGlvbi1wbGFjZS1jb250cm9sPlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIGA7XG4gICAgICB9LFxuICAgICl9YDtcbiAgfVxuXG4gIHByaXZhdGUgX2dldFJlbmRlcmVkR3JhcGhpY2FsRWxlbWVudHMoXG4gICAgZ3JhcGhpY2FsRWxlbWVudHM6IEJhc2VFbGVtZW50W10sXG4gICAgY29hY2hEaW1lbnNpb246IEVsZW1lbnREaW1lbnNpb24sXG4gICAgY29hY2hJbmRleDogbnVtYmVyLFxuICAgIGNvYWNoRGVja0luZGV4OiBudW1iZXIsXG4gICk6IFRlbXBsYXRlUmVzdWx0W10gfCBudWxsIHtcbiAgICBpZiAoIWdyYXBoaWNhbEVsZW1lbnRzKSByZXR1cm4gbnVsbDtcblxuICAgIHJldHVybiBncmFwaGljYWxFbGVtZW50cz8ubWFwKChncmFwaGljYWxFbGVtZW50OiBCYXNlRWxlbWVudCkgPT4ge1xuICAgICAgY29uc3QgaWNvbiA9IGdyYXBoaWNhbEVsZW1lbnQuaWNvbiA/PyAnJztcbiAgICAgIGNvbnN0IGVsZW1lbnRSb3RhdGlvbiA9IGdyYXBoaWNhbEVsZW1lbnQucm90YXRpb24gfHwgMDtcbiAgICAgIGNvbnN0IGlzTm90Rml4ZWRSb3RhdGlvbkdyYXBoaWNhbEVsZW1lbnQgPVxuICAgICAgICB0aGlzLl9ub3RGaXhlZFJvdGF0YWJsZUFyZWFJY29ucy5pbmRleE9mKGdyYXBoaWNhbEVsZW1lbnQuaWNvbiEpID09PSAtMTtcbiAgICAgIGNvbnN0IGVsZW1lbnRGaXhlZFJvdGF0aW9uID1cbiAgICAgICAgdGhpcy5hbGlnblZlcnRpY2FsICYmIGlzTm90Rml4ZWRSb3RhdGlvbkdyYXBoaWNhbEVsZW1lbnRcbiAgICAgICAgICA/IGVsZW1lbnRSb3RhdGlvbiAtIDkwXG4gICAgICAgICAgOiBlbGVtZW50Um90YXRpb247XG5cbiAgICAgIC8vY2hlY2sgaWYgdGhlIGN1cnJlbnQgZWxlbWVudCBpcyBub3QgYW4gYXJlYSBlbGVtZW50LCBzaW5jZSB0aGlzIGVsZW1lbnQgaXMgZHJhd24gd2l0aG91dCBhbiBhcmVhIGNvbXBvbmVudFxuICAgICAgaWYgKHRoaXMubm90QXJlYUVsZW1lbnRzLmZpbmRJbmRleCgobm90QXJlYUVsZW1lbnQpID0+IG5vdEFyZWFFbGVtZW50ID09PSBpY29uKSA+IC0xKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9nZXRSZW5kZXJFbGVtZW50V2l0aG91dEFyZWEoZ3JhcGhpY2FsRWxlbWVudCwgZWxlbWVudFJvdGF0aW9uLCBjb2FjaERpbWVuc2lvbik7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5fZ2V0UmVuZGVyRWxlbWVudFdpdGhBcmVhKFxuICAgICAgICBncmFwaGljYWxFbGVtZW50LFxuICAgICAgICBlbGVtZW50Rml4ZWRSb3RhdGlvbixcbiAgICAgICAgY29hY2hEaW1lbnNpb24sXG4gICAgICAgIGNvYWNoSW5kZXgsXG4gICAgICAgIGNvYWNoRGVja0luZGV4LFxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBjcmVhdGVzIGEgcmVuZGVyZWQgZWxlbWVudCB3aXRoIGFuIGFyZWEgY29tcG9uZW50XG4gICAqIEBwYXJhbSBncmFwaGljYWxFbGVtZW50XG4gICAqIEBwYXJhbSByb3RhdGlvblxuICAgKiBAcGFyYW0gY29hY2hEaW1lbnNpb25cbiAgICogQHBhcmFtIGNvYWNoSW5kZXggdXNlZCB0byBnZW5lcmF0ZSBhIHVuaXF1ZSBpZCBmb3IgdGhlIHBvcG92ZXIgdHJpZ2dlclxuICAgKiBAcGFyYW0gY29hY2hEZWNrSW5kZXggdXNlZCB0byBnZW5lcmF0ZSBhIHVuaXF1ZSBpZFxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBfZ2V0UmVuZGVyRWxlbWVudFdpdGhBcmVhKFxuICAgIGdyYXBoaWNhbEVsZW1lbnQ6IEJhc2VFbGVtZW50LFxuICAgIHJvdGF0aW9uOiBudW1iZXIsXG4gICAgY29hY2hEaW1lbnNpb246IEVsZW1lbnREaW1lbnNpb24sXG4gICAgY29hY2hJbmRleDogbnVtYmVyLFxuICAgIGNvYWNoRGVja0luZGV4OiBudW1iZXIsXG4gICk6IFRlbXBsYXRlUmVzdWx0IHtcbiAgICAvLyBmb3IgVEFCTEUsIHdlIHVzZSB0aGUgYXJlYSBjb21wb25lbnQgaXRzZWxmIHRvIGRpc3BsYXkgdGhlIHRhYmxlIGluc3RlYWQgb2YgdGhlIFNWRyBncmFwaGljLlxuICAgIC8vIER1ZSB0byBkaWZmZXJlbnQgaGVpZ2h0cyBhbmQgd2lkdGhzLCBpdCB3b3VsZG4ndCBzaG93IGNvcnJlY3RseS4gVG8gY29ycmVjdCB0aGlzLCB3ZSB3b3VsZFxuICAgIC8vIG5lZWQgZGlmZmljdWx0IGNhbGN1bGF0aW9ucyBmb3IgcG9zaXRpb24sIHJvdGF0aW9uIGFuZCBkaW1lbnNpb24uXG4gICAgY29uc3QgaXNOb3RUYWJsZUdyYXBoaWMgPSBncmFwaGljYWxFbGVtZW50Lmljb24/LmluZGV4T2YoJ1RBQkxFJykgPT09IC0xO1xuICAgIGNvbnN0IGFyZWFQcm9wZXJ0eSA9IGdyYXBoaWNhbEVsZW1lbnQuaWNvbiAmJiBpc05vdFRhYmxlR3JhcGhpYyA/IGdyYXBoaWNhbEVsZW1lbnQuaWNvbiA6IG51bGw7XG4gICAgY29uc3Qgc3RyZXRjaEhlaWdodCA9XG4gICAgICB0aGlzLmlzRWxlbWVudERpcmVjdGx5T25Cb3JkZXIoZ3JhcGhpY2FsRWxlbWVudCwgY29hY2hEaW1lbnNpb24pICYmXG4gICAgICBhcmVhUHJvcGVydHkgIT09ICdFTlRSWV9FWElUJztcbiAgICBjb25zdCBhcmlhTGFiZWxGb3JBcmVhID0gZ3JhcGhpY2FsRWxlbWVudC5pY29uXG4gICAgICA/IGdldEkxOG5TZWF0UmVzZXJ2YXRpb24oZ3JhcGhpY2FsRWxlbWVudC5pY29uLCB0aGlzLl9sYW5ndWFnZS5jdXJyZW50KVxuICAgICAgOiBub3RoaW5nO1xuXG4gICAgY29uc3QgY2FsY3VsYXRlZERpbWVuc2lvbiA9IHRoaXMuZ2V0Q2FsY3VsYXRlZERpbWVuc2lvbihcbiAgICAgIGdyYXBoaWNhbEVsZW1lbnQuZGltZW5zaW9uLFxuICAgICAgY29hY2hEaW1lbnNpb24sXG4gICAgICB0cnVlLFxuICAgICAgc3RyZXRjaEhlaWdodCxcbiAgICApO1xuXG4gICAgY29uc3QgY2FsY3VsYXRlZFBvc2l0aW9uID0gdGhpcy5nZXRDYWxjdWxhdGVkUG9zaXRpb24oXG4gICAgICBncmFwaGljYWxFbGVtZW50LnBvc2l0aW9uLFxuICAgICAgZ3JhcGhpY2FsRWxlbWVudC5kaW1lbnNpb24sXG4gICAgICBjb2FjaERpbWVuc2lvbixcbiAgICAgIHRydWUsXG4gICAgKTtcblxuICAgIC8vZ2VuZXJhdGUgdW5pcXVlIGluZGV4IG51bWJlciBmb3IgdGhlIHRyaWdnZXIgZWxlbWVudFxuICAgIGNvbnN0IHRyaWdnZXJJZCA9IGBwb3BvdmVyLXRyaWdnZXItJHtjb2FjaERlY2tJbmRleH0tJHtjb2FjaEluZGV4fS0ke2NhbGN1bGF0ZWRQb3NpdGlvbi54fS0ke2NhbGN1bGF0ZWRQb3NpdGlvbi55fWA7XG4gICAgbGV0IGVsZW1lbnRNb3VudGluZyA9ICdmcmVlJztcblxuICAgIGlmIChncmFwaGljYWxFbGVtZW50LnBvc2l0aW9uLnkgPT09IHRoaXMuY29hY2hCb3JkZXJPZmZzZXQgKiAtMSkge1xuICAgICAgZWxlbWVudE1vdW50aW5nID0gJ3VwcGVyLWJvcmRlcic7XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIGdyYXBoaWNhbEVsZW1lbnQucG9zaXRpb24ueSArIGdyYXBoaWNhbEVsZW1lbnQuZGltZW5zaW9uLmggPT09XG4gICAgICBjb2FjaERpbWVuc2lvbi5oICsgdGhpcy5jb2FjaEJvcmRlck9mZnNldFxuICAgICkge1xuICAgICAgZWxlbWVudE1vdW50aW5nID0gJ2xvd2VyLWJvcmRlcic7XG4gICAgfVxuXG4gICAgLy8gVElNTy00NTgzMFxuICAgIC8vIElmIGFyZWEgZWxlbWVudHMgYXJlIGxvY2F0ZWQgYXQgdGhlIGJvcmRlciBvZiBjb2FjaCxcbiAgICAvLyB3ZSBoYXZlIHRvIG1hbnVhbGx5IG1vZGlmeSB0aGUgcG9zaXRpb24gYW5kIGhlaWdodCBvZiB0aGUgYXJlYSBlbGVtZW50LFxuICAgIC8vIHNvIHRoYXQgd2UgZ2V0IGEgZ2FwIGZyb20gdGhlIHZpc3VlbCBjb2FjaCBib3JkZXJcbiAgICBpZiAoZWxlbWVudE1vdW50aW5nICE9PSAnZnJlZScpIHtcbiAgICAgIGNhbGN1bGF0ZWRQb3NpdGlvbi55ICs9IGVsZW1lbnRNb3VudGluZyA9PT0gJ3VwcGVyLWJvcmRlcicgPyAyIDogMTtcbiAgICAgIGNhbGN1bGF0ZWREaW1lbnNpb24uaCAtPSAzO1xuICAgIH1cbiAgICByZXR1cm4gaHRtbGBcbiAgICAgIDxzYmItc2VhdC1yZXNlcnZhdGlvbi1hcmVhXG4gICAgICAgIGlkPVwiJHt0cmlnZ2VySWR9XCJcbiAgICAgICAgY2xhc3M9XCIke2NsYXNzTWFwKHsgJ3NiYi1zZWF0LXJlc2VydmF0aW9uLWFyZWEtLWN1cnNvci1wb2ludGVyJzogYXJlYVByb3BlcnR5ICE9PSBudWxsIH0pfVwiXG4gICAgICAgIHN0eWxlPSR7c3R5bGVNYXAoe1xuICAgICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLWFyZWEtd2lkdGgnOiBjYWxjdWxhdGVkRGltZW5zaW9uLncsXG4gICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tYXJlYS1oZWlnaHQnOiBjYWxjdWxhdGVkRGltZW5zaW9uLmgsXG4gICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tYXJlYS10b3AnOiBjYWxjdWxhdGVkUG9zaXRpb24ueSxcbiAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1hcmVhLWxlZnQnOiBjYWxjdWxhdGVkUG9zaXRpb24ueCxcbiAgICAgICAgfSl9XG4gICAgICAgIG1vdW50aW5nPSR7ZWxlbWVudE1vdW50aW5nfVxuICAgICAgICBiYWNrZ3JvdW5kPVwiZGFya1wiXG4gICAgICAgIGFyaWEtaGlkZGVuPVwidHJ1ZVwiXG4gICAgICA+XG4gICAgICAgICR7YXJlYVByb3BlcnR5XG4gICAgICAgICAgPyBodG1sYFxuICAgICAgICAgICAgICA8c2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JhcGhpY1xuICAgICAgICAgICAgICAgIHN0eWxlPSR7c3R5bGVNYXAoe1xuICAgICAgICAgICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JhcGhpYy1tYXgtd2lkdGgnOiBjYWxjdWxhdGVkRGltZW5zaW9uLncsXG4gICAgICAgICAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljLWhlaWdodCc6IHRoaXMuYmFzZUdyaWRTaXplLFxuICAgICAgICAgICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JhcGhpYy1yb3RhdGlvbic6IHJvdGF0aW9uLFxuICAgICAgICAgICAgICAgIH0pfVxuICAgICAgICAgICAgICAgIG5hbWU9JHthcmVhUHJvcGVydHl9XG4gICAgICAgICAgICAgICAgcm9sZT1cImltZ1wiXG4gICAgICAgICAgICAgICAgYXJpYS1oaWRkZW49XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cImF1dG8td2lkdGhcIlxuICAgICAgICAgICAgICA+PC9zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljPlxuICAgICAgICAgICAgYFxuICAgICAgICAgIDogbm90aGluZ31cbiAgICAgIDwvc2JiLXNlYXQtcmVzZXJ2YXRpb24tYXJlYT5cbiAgICAgICR7YXJlYVByb3BlcnR5ID8gdGhpcy5fcG9wb3Zlcih0cmlnZ2VySWQsIGFyaWFMYWJlbEZvckFyZWEpIDogbm90aGluZ31cbiAgICBgO1xuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0UmVuZGVyRWxlbWVudFdpdGhvdXRBcmVhKFxuICAgIGdyYXBoaWNhbEVsZW1lbnQ6IEJhc2VFbGVtZW50LFxuICAgIHJvdGF0aW9uOiBudW1iZXIsXG4gICAgY29hY2hEaW1lbnNpb246IEVsZW1lbnREaW1lbnNpb24sXG4gICk6IFRlbXBsYXRlUmVzdWx0IHtcbiAgICBjb25zdCBjYWxjdWxhdGVkRGltZW5zaW9uID0gdGhpcy5nZXRDYWxjdWxhdGVkRGltZW5zaW9uKFxuICAgICAgZ3JhcGhpY2FsRWxlbWVudC5kaW1lbnNpb24sXG4gICAgICBjb2FjaERpbWVuc2lvbixcbiAgICApO1xuICAgIGNvbnN0IGNhbGN1bGF0ZWRQb3NpdGlvbiA9IHRoaXMuZ2V0Q2FsY3VsYXRlZFBvc2l0aW9uKFxuICAgICAgZ3JhcGhpY2FsRWxlbWVudC5wb3NpdGlvbixcbiAgICAgIGdyYXBoaWNhbEVsZW1lbnQuZGltZW5zaW9uLFxuICAgICAgY29hY2hEaW1lbnNpb24sXG4gICAgKTtcblxuICAgIC8vIElmIHRoZSBpY29uIGlzIHRoZSBkcml2ZXIgYXJlYSwgdGhlbiBoZXJlIGNvbmNhdCB0aGUgdmVoaWNsZSB0eXBlIHRvIGdldCB0aGUgcmlnaHQgdmVoaWNsZSBjaGFzc2lzIGljb25cbiAgICBjb25zdCBpY29uID1cbiAgICAgIGdyYXBoaWNhbEVsZW1lbnQuaWNvbiAmJiBncmFwaGljYWxFbGVtZW50Lmljb24uZW5kc1dpdGgoJ0RSSVZFUl9BUkVBJylcbiAgICAgICAgPyBncmFwaGljYWxFbGVtZW50Lmljb24/LmNvbmNhdChcbiAgICAgICAgICAgICdfJyxcbiAgICAgICAgICAgIHRoaXMuc2VhdFJlc2VydmF0aW9uc1t0aGlzLmN1cnJTZWxlY3RlZERlY2tJbmRleF0udmVoaWNsZVR5cGUsXG4gICAgICAgICAgKVxuICAgICAgICA6IGdyYXBoaWNhbEVsZW1lbnQuaWNvbjtcblxuICAgIHJldHVybiBodG1sYCA8c2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JhcGhpY1xuICAgICAgc3R5bGU9JHtzdHlsZU1hcCh7XG4gICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWMtd2lkdGgnOiBjYWxjdWxhdGVkRGltZW5zaW9uLncsXG4gICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWMtaGVpZ2h0JzogY2FsY3VsYXRlZERpbWVuc2lvbi5oLFxuICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljLXRvcCc6IGNhbGN1bGF0ZWRQb3NpdGlvbi55LFxuICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljLWxlZnQnOiBjYWxjdWxhdGVkUG9zaXRpb24ueCxcbiAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JhcGhpYy1wb3NpdGlvbic6ICdhYnNvbHV0ZScsXG4gICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWMtcm90YXRpb24nOiByb3RhdGlvbixcbiAgICAgIH0pfVxuICAgICAgbmFtZT0ke2ljb24gPz8gbm90aGluZ31cbiAgICAgIGFyaWEtaGlkZGVuPVwidHJ1ZVwiXG4gICAgICA/c3RyZXRjaD0ke3RydWV9XG4gICAgPjwvc2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JhcGhpYz5gO1xuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0UmVuZGVyZWRTZXJ2aWNlRWxlbWVudHMoXG4gICAgY29hY2hJbmRleDogbnVtYmVyLFxuICAgIGNvYWNoRGVja0luZGV4OiBudW1iZXIsXG4gICAgc2VydmljZUVsZW1lbnRzPzogQmFzZUVsZW1lbnRbXSxcbiAgKTogVGVtcGxhdGVSZXN1bHRbXSB8IG51bGwge1xuICAgIGlmICghc2VydmljZUVsZW1lbnRzKSByZXR1cm4gbnVsbDtcblxuICAgIHJldHVybiBzZXJ2aWNlRWxlbWVudHM/Lm1hcCgoc2VydmljZUVsZW1lbnQ6IEJhc2VFbGVtZW50KSA9PiB7XG4gICAgICBjb25zdCB0aXRsZURlc2NyaXB0aW9uID0gc2VydmljZUVsZW1lbnQuaWNvblxuICAgICAgICA/IGdldEkxOG5TZWF0UmVzZXJ2YXRpb24oc2VydmljZUVsZW1lbnQuaWNvbiwgdGhpcy5fbGFuZ3VhZ2UuY3VycmVudClcbiAgICAgICAgOiBudWxsO1xuICAgICAgY29uc3QgY2FsY3VsYXRlZERpbWVuc2lvbiA9IHRoaXMuZ2V0Q2FsY3VsYXRlZERpbWVuc2lvbihzZXJ2aWNlRWxlbWVudC5kaW1lbnNpb24pO1xuICAgICAgY29uc3QgY2FsY3VsYXRlZFBvc2l0aW9uID0gdGhpcy5nZXRDYWxjdWxhdGVkUG9zaXRpb24oc2VydmljZUVsZW1lbnQucG9zaXRpb24pO1xuICAgICAgY29uc3QgZWxlbWVudFJvdGF0aW9uID0gc2VydmljZUVsZW1lbnQucm90YXRpb24gfHwgMDtcbiAgICAgIGNvbnN0IGVsZW1lbnRGaXhlZFJvdGF0aW9uID0gdGhpcy5hbGlnblZlcnRpY2FsID8gZWxlbWVudFJvdGF0aW9uIC0gOTAgOiBlbGVtZW50Um90YXRpb247XG5cbiAgICAgIC8vZ2VuZXJhdGUgdW5pcXVlIGluZGV4IG51bWJlciBmb3IgdGhlIHRyaWdnZXIgZWxlbWVudFxuICAgICAgY29uc3QgdHJpZ2dlcklkID0gYHBvcG92ZXItdHJpZ2dlci0ke2NvYWNoRGVja0luZGV4fS0ke2NvYWNoSW5kZXh9LSR7Y2FsY3VsYXRlZFBvc2l0aW9uLnh9LSR7Y2FsY3VsYXRlZFBvc2l0aW9uLnl9YDtcblxuICAgICAgcmV0dXJuIGh0bWxgXG4gICAgICAgIDxzYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljXG4gICAgICAgICAgaWQ9XCIke3RyaWdnZXJJZH1cIlxuICAgICAgICAgIHN0eWxlPSR7c3R5bGVNYXAoe1xuICAgICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JhcGhpYy13aWR0aCc6IGNhbGN1bGF0ZWREaW1lbnNpb24udyxcbiAgICAgICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWMtaGVpZ2h0JzogY2FsY3VsYXRlZERpbWVuc2lvbi5oLFxuICAgICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JhcGhpYy10b3AnOiBjYWxjdWxhdGVkUG9zaXRpb24ueSxcbiAgICAgICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWMtbGVmdCc6IGNhbGN1bGF0ZWRQb3NpdGlvbi54LFxuICAgICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JhcGhpYy1wb3NpdGlvbic6ICdhYnNvbHV0ZScsXG4gICAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljLXJvdGF0aW9uJzogZWxlbWVudEZpeGVkUm90YXRpb24sXG4gICAgICAgICAgfSl9XG4gICAgICAgICAgY2xhc3M9XCJzYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljLS1jdXJzb3ItcG9pbnRlclwiXG4gICAgICAgICAgbmFtZT0ke3NlcnZpY2VFbGVtZW50Lmljb24gPz8gbm90aGluZ31cbiAgICAgICAgICByb2xlPVwiaW1nXCJcbiAgICAgICAgICBhcmlhLWhpZGRlbj1cInRydWVcIlxuICAgICAgICA+PC9zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljPlxuICAgICAgICAke3RoaXMuX3BvcG92ZXIodHJpZ2dlcklkLCB0aXRsZURlc2NyaXB0aW9uKX1cbiAgICAgIGA7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogTWFuYWdlcyB0aGUgc2VsZWN0ZWQgcGxhY2UgZXZlbnQgdHJpZ2dlcmVkIGZyb20gdGhlIHBsYWNlXG4gICAqIEVhY2ggc2VsZWN0aW9uIGVtaXRzIGFuIGFycmF5IG9mIGFsbCBzZWxlY3RlZCBwbGFjZXNcbiAgICogQHBhcmFtIHNlbGVjdFBsYWNlRXZlbnRcbiAgICovXG4gIHByaXZhdGUgX29uU2VsZWN0UGxhY2Uoc2VsZWN0UGxhY2VFdmVudDogQ3VzdG9tRXZlbnQ8UGxhY2VTZWxlY3Rpb24+KTogdm9pZCB7XG4gICAgY29uc3Qgc2VsZWN0ZWRQbGFjZSA9IHNlbGVjdFBsYWNlRXZlbnQuZGV0YWlsO1xuICAgIC8vIFdlIGhhdmUgdG8gc2V0IHByZXZlbnRDb2FjaFNjcm9sbEJ5UGxhY2VDbGljayB0byB0cnVlLCB0byBwcmV2ZW50IGF1dG9tYXRpYyBzY3JvbGxpbmcgdG8gdGhlIG5ldyBmb2N1c2VkIHBsYWNlXG4gICAgdGhpcy5wcmV2ZW50Q29hY2hTY3JvbGxCeVBsYWNlQ2xpY2sgPSB0cnVlO1xuICAgIHRoaXMuaXNDb2FjaEdyaWRGb2N1c2FibGUgPSBmYWxzZTtcbiAgICB0aGlzLmZvY3VzZWRDb2FjaEluZGV4ID0gLTE7XG4gICAgLy8gQ2hlY2sgYW55IGtleWJvYXJkIGV2ZW50IHdhcyB0cmlnZ2VyZWQgaW5zaWRlIHRoZSBzZWF0IHJlc2VydmF0aW9uIGNvbXBvbmVudCxcbiAgICAvLyBzbyB3ZSBjYW4gc2F5IHRoZSBuYXRpdmUgYnJvd3NlciBmb2N1cyBsaWVzIG9uIHRoZSBjb21wb25lbnRcbiAgICBpZiAoIXRoaXMuaGFzU2VhdFJlc2VydmF0aW9uTmF0aXZlRm9jdXMpIHtcbiAgICAgIHRoaXMuaGFzU2VhdFJlc2VydmF0aW9uTmF0aXZlRm9jdXMgPSB0cnVlO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5wcmV2ZW50UGxhY2VDbGljaykge1xuICAgICAgLy8gQWRkIHBsYWNlIHRvIHBsYWNlIGNvbGxlY3Rpb25cbiAgICAgIHRoaXMudXBkYXRlU2VsZWN0ZWRTZWF0UmVzZXJ2YXRpb25QbGFjZXMoc2VsZWN0ZWRQbGFjZSk7XG4gICAgICB0aGlzLnVwZGF0ZUN1cnJlbnRTZWxlY3RlZFBsYWNlSW5Db2FjaChzZWxlY3RlZFBsYWNlKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9vblNlbGVjdE5hdkNvYWNoKGV2ZW50OiBDdXN0b21FdmVudDxudW1iZXI+KTogdm9pZCB7XG4gICAgY29uc3Qgc2VsZWN0ZWROYXZDb2FjaEluZGV4ID0gZXZlbnQuZGV0YWlsO1xuXG4gICAgdGhpcy5pc0tleWJvYXJkTmF2aWdhdGlvbiA9IGZhbHNlO1xuICAgIHRoaXMucHJldmVudENvYWNoU2Nyb2xsQnlQbGFjZUNsaWNrID0gZmFsc2U7XG4gICAgdGhpcy5oYXNTZWF0UmVzZXJ2YXRpb25OYXRpdmVGb2N1cyA9IHRydWU7XG5cbiAgICBpZiAoc2VsZWN0ZWROYXZDb2FjaEluZGV4ICE9PSBudWxsICYmIHNlbGVjdGVkTmF2Q29hY2hJbmRleCAhPT0gdGhpcy5jdXJyU2VsZWN0ZWRDb2FjaEluZGV4KSB7XG4gICAgICB0aGlzLnVuZm9jdXNQbGFjZUVsZW1lbnQoKTtcbiAgICAgIHRoaXMuc2Nyb2xsVG9TZWxlY3RlZE5hdkNvYWNoKHNlbGVjdGVkTmF2Q29hY2hJbmRleCk7XG4gICAgfSBlbHNlIGlmIChzZWxlY3RlZE5hdkNvYWNoSW5kZXggPT09IHRoaXMuY3VyclNlbGVjdGVkQ29hY2hJbmRleCkge1xuICAgICAgdGhpcy51cGRhdGVDdXJyZW50U2VsZWN0ZWRDb2FjaCgpO1xuICAgICAgdGhpcy5wcmVzZWxlY3RQbGFjZUluQ29hY2goKTtcbiAgICB9XG5cbiAgICAvL2Nsb3NlIGFsbCBvcGVuZWQgcG9wb3ZlcnNcbiAgICB0aGlzLl9jbG9zZVBvcG92ZXIoKTtcbiAgfVxuXG4gIHByaXZhdGUgX29uRm9jdXNOYXZDb2FjaCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMucHJldmVudENvYWNoU2Nyb2xsQnlQbGFjZUNsaWNrKSB7XG4gICAgICB0aGlzLnByZXNlbGVjdFBsYWNlSW5Db2FjaCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmZvY3VzUGxhY2VFbGVtZW50KHRoaXMuY3VyclNlbGVjdGVkUGxhY2UpO1xuICAgIH1cblxuICAgIHRoaXMuaXNBdXRvU2Nyb2xsaW5nID0gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIHBvcG92ZXIgZm9yIGV4dHJhIHNlcnZpY2UgaW5mb3JtYXRpb25cbiAgICogQHBhcmFtIHRyaWdnZXJJZFxuICAgKiBAcGFyYW0gcG9wb3ZlckNvbnRlbnRcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgX3BvcG92ZXIoXG4gICAgdHJpZ2dlcklkOiBzdHJpbmcsXG4gICAgcG9wb3ZlckNvbnRlbnQ6IHN0cmluZyB8IG51bGwgfCB0eXBlb2Ygbm90aGluZyxcbiAgKTogVGVtcGxhdGVSZXN1bHQge1xuICAgIHJldHVybiBodG1sYFxuICAgICAgPHNiYi1wb3BvdmVyIHRyaWdnZXI9XCIke3RyaWdnZXJJZH1cIiBob3Zlci10cmlnZ2VyPVwiXCI+XG4gICAgICAgIDxwIGNsYXNzPVwic2JiLXRleHQtcyBzYmItc3ItcG9wb3ZlclwiPiR7cG9wb3ZlckNvbnRlbnR9PC9wPlxuICAgICAgPC9zYmItcG9wb3Zlcj5cbiAgICBgO1xuICB9XG5cbiAgLyoqXG4gICAqIHRyaWdnZXIgdG8gY2xvc2UgYWxsIG9wZW5lZCBwb3BvdmVycyAobm9ybWFsbHkgb25seSBvbmUgaXMgb3BlbmVkIGF0IGEgdGltZSlcbiAgICogQHByaXZhdGVcbiAgICovXG4gIHByaXZhdGUgX2Nsb3NlUG9wb3ZlcigpOiB2b2lkIHtcbiAgICB0aGlzLnNoYWRvd1Jvb3RcbiAgICAgID8ucXVlcnlTZWxlY3RvckFsbDxTYmJQb3BvdmVyRWxlbWVudD4oJ3NiYi1wb3BvdmVyOnN0YXRlKHN0YXRlLW9wZW5lZCknKVxuICAgICAgLmZvckVhY2goKHBvcG92ZXIpID0+IHBvcG92ZXIuY2xvc2UoKSk7XG4gIH1cblxuICBwcml2YXRlIF9nZXREZXNjcmlwdGlvblRhYmxlQ29hY2goY29hY2hJdGVtOiBDb2FjaEl0ZW0pOiBzdHJpbmcge1xuICAgIC8vc2hvdyBkaWZmZXJlbnQgdGFibGUgY2FwdGlvbiBmb3Igc2NyZWVucmVhZGVyIGlmIGl0IGlzIGEgbG9jb21vdGl2ZVxuICAgIGlmIChjb2FjaEl0ZW0udHlwZSA9PT0gJ0xPQ09NT1RJVkVfQ09BQ0gnKSB7XG4gICAgICByZXR1cm4gZ2V0STE4blNlYXRSZXNlcnZhdGlvbignQ09BQ0hfTE9DT01PVElWRScsIHRoaXMuX2xhbmd1YWdlLmN1cnJlbnQpO1xuICAgIH1cblxuICAgIGlmICghY29hY2hJdGVtLnBsYWNlcz8ubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZ2V0STE4blNlYXRSZXNlcnZhdGlvbignQ09BQ0hfQkxPQ0tFRF9UQUJMRV9DQVBUSU9OJywgdGhpcy5fbGFuZ3VhZ2UuY3VycmVudCwgW1xuICAgICAgICBjb2FjaEl0ZW0uaWQsXG4gICAgICBdKTtcbiAgICB9XG5cbiAgICBsZXQgdGFibGVDb2FjaERlc2NyaXB0aW9uOiBzdHJpbmc7XG4gICAgY29uc3QgYXJlYURlc2NyaXB0aW9ucyA9IHRoaXMuX2dldFRpdGxlRGVzY3JpcHRpb25MaXN0U3RyaW5nKGNvYWNoSXRlbS5ncmFwaGljRWxlbWVudHMhKTtcbiAgICBjb25zdCBzZXJ2aWNlRGVzY3JpcHRpb25zID0gdGhpcy5fZ2V0VGl0bGVEZXNjcmlwdGlvbkxpc3RTdHJpbmcoY29hY2hJdGVtLnNlcnZpY2VFbGVtZW50cyEpO1xuXG4gICAgdGFibGVDb2FjaERlc2NyaXB0aW9uID0gZ2V0STE4blNlYXRSZXNlcnZhdGlvbignQ09BQ0hfVEFCTEVfQ0FQVElPTicsIHRoaXMuX2xhbmd1YWdlLmN1cnJlbnQsIFtcbiAgICAgIGNvYWNoSXRlbS5pZCxcbiAgICBdKTtcblxuICAgIGlmICghdGhpcy5oYXNOYXZpZ2F0aW9uKSB7XG4gICAgICAvLyBFeHBhbmRzIHRoZSBudW1iZXIgb2YgYXZhaWxhYmxlIHNlYXRzIGFuZCBiaWN5Y2xlIHNwYWNlcyBhcyBpbmZvXG4gICAgICBjb25zdCBmcmVlUGxhY2VzID0gdGhpcy5nZXRBdmFpbGFibGVGcmVlUGxhY2VzTnVtRnJvbUNvYWNoKGNvYWNoSXRlbS5wbGFjZXMpO1xuICAgICAgY29uc3QgZnJlZVBsYWNlc1R4dCA9IGdldEkxOG5TZWF0UmVzZXJ2YXRpb24oXG4gICAgICAgICdDT0FDSF9BVkFJTEFCTEVfTlVNQkVSX09GX1BMQUNFUycsXG4gICAgICAgIHRoaXMuX2xhbmd1YWdlLmN1cnJlbnQsXG4gICAgICAgIFtmcmVlUGxhY2VzLnNlYXRzLCBmcmVlUGxhY2VzLmJpY3ljbGVzXSxcbiAgICAgICk7XG4gICAgICB0YWJsZUNvYWNoRGVzY3JpcHRpb24gPSB0YWJsZUNvYWNoRGVzY3JpcHRpb24uY29uY2F0KCcuICcpLmNvbmNhdChmcmVlUGxhY2VzVHh0KS5jb25jYXQoJy4gJyk7XG4gICAgfVxuXG4gICAgaWYgKCEhYXJlYURlc2NyaXB0aW9ucyB8fCAhIXNlcnZpY2VEZXNjcmlwdGlvbnMpIHtcbiAgICAgIHRhYmxlQ29hY2hEZXNjcmlwdGlvbiArPVxuICAgICAgICAnLiAnICsgZ2V0STE4blNlYXRSZXNlcnZhdGlvbignQ09BQ0hfQVZBSUxBQkxFX1NFUlZJQ0VTJywgdGhpcy5fbGFuZ3VhZ2UuY3VycmVudCkgKyAnOiAnO1xuICAgICAgdGFibGVDb2FjaERlc2NyaXB0aW9uICs9IHNlcnZpY2VEZXNjcmlwdGlvbnMgKyAnLCAnICsgYXJlYURlc2NyaXB0aW9ucyArICcuJztcbiAgICB9XG4gICAgcmV0dXJuIHRhYmxlQ29hY2hEZXNjcmlwdGlvbjtcbiAgfVxuXG4gIHByaXZhdGUgX2dldFRpdGxlRGVzY3JpcHRpb25MaXN0U3RyaW5nKGRlc2NyaXB0aW9uc0VsZW1lbnRzOiBCYXNlRWxlbWVudFtdKTogc3RyaW5nIHtcbiAgICBjb25zdCB1bmlxdWVEZXNjcmlwdGlvbnM6IHN0cmluZ1tdID0gW107XG5cbiAgICByZXR1cm4gZGVzY3JpcHRpb25zRWxlbWVudHNcbiAgICAgID8ubWFwKChkZXNjcmlwdGlvbkVsZW1lbnQpID0+IHtcbiAgICAgICAgY29uc3QgaWNvbiA9IGRlc2NyaXB0aW9uRWxlbWVudC5pY29uO1xuICAgICAgICBpZiAoIWljb24pIHJldHVybiBudWxsO1xuXG4gICAgICAgIGNvbnN0IGRlc2NyaXB0aW9uQWxyZWFkeUV4aXN0ID0gdW5pcXVlRGVzY3JpcHRpb25zLmluZGV4T2YoaWNvbikgPiAtMTtcbiAgICAgICAgY29uc3QgdHJhbnNsYXRpb24gPSBnZXRJMThuU2VhdFJlc2VydmF0aW9uKFxuICAgICAgICAgIGRlc2NyaXB0aW9uRWxlbWVudC5pY29uISxcbiAgICAgICAgICB0aGlzLl9sYW5ndWFnZS5jdXJyZW50LFxuICAgICAgICApO1xuICAgICAgICBjb25zdCBpc1ZhbGlkRGVzY3JpcHRpb24gPVxuICAgICAgICAgIHRoaXMuX25vdEZpeGVkUm90YXRhYmxlQXJlYUljb25zLmluZGV4T2YoaWNvbikgPT09IC0xICYmXG4gICAgICAgICAgdGhpcy5ub3RBcmVhRWxlbWVudHMuaW5kZXhPZihpY29uKSA9PT0gLTE7XG5cbiAgICAgICAgaWYgKCFkZXNjcmlwdGlvbkFscmVhZHlFeGlzdCkge1xuICAgICAgICAgIHVuaXF1ZURlc2NyaXB0aW9ucy5wdXNoKGRlc2NyaXB0aW9uRWxlbWVudC5pY29uISk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuICEhdHJhbnNsYXRpb24gJiYgIWRlc2NyaXB0aW9uQWxyZWFkeUV4aXN0ICYmIGlzVmFsaWREZXNjcmlwdGlvbiA/IHRyYW5zbGF0aW9uIDogbnVsbDtcbiAgICAgIH0pXG4gICAgICAuZmlsdGVyKChkZXNjcmlwdGlvbikgPT4gISFkZXNjcmlwdGlvbilcbiAgICAgIC5qb2luKCcsICcpO1xuICB9XG59XG5cbmRlY2xhcmUgZ2xvYmFsIHtcbiAgaW50ZXJmYWNlIEhUTUxFbGVtZW50VGFnTmFtZU1hcCB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxuICAgICdzYmItc2VhdC1yZXNlcnZhdGlvbic6IFNiYlNlYXRSZXNlcnZhdGlvbkVsZW1lbnQ7XG4gIH1cbn1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBZ0NBLDhCQUE4QixPQUFBO0FBQzlCLGlDQUFpQyxPQUFBO0FBQ2pDLHNDQUFzQyxPQUFBO0FBQ3RDLHlDQUF5QyxPQUFBO0FBQ3pDLGdDQUFnQyxPQUFBO0FBTTFCLE1BQU8sNkJBQVAsTUFBTyxtQ0FBa0MsMkJBQTBCO0FBQUEsRUFBekUsY0FBQTs7QUFJVSxTQUFBLFlBQVksSUFBSSxzQkFBc0IsSUFBSTtBQUkxQyxTQUFBLDhCQUE4QixDQUFDLFlBQVk7QUFBQSxFQTh3QnJEO0FBQUEsRUE1d0JxQixXQUFXLG1CQUF1QztBQUNuRSxVQUFNLFdBQVcsaUJBQWlCO0FBRWxDLFFBQUksa0JBQWtCLElBQUksZUFBZSxHQUFHO0FBQzFDLFVBQUksS0FBSyxlQUFlO0FBQ3RCLGFBQUssWUFDRCxpQkFBaUIsT0FBTyxFQUN6QixRQUFRLENBQUMsVUFBVSxNQUFNLGdCQUFnQixVQUFVLENB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