raise-common-lib-new 0.0.62 → 0.0.64

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 (223) hide show
  1. package/esm2022/lib/actions/toolbar/index.component.mjs +4 -3
  2. package/esm2022/lib/actions/toolbar-item/index.component.mjs +2 -2
  3. package/esm2022/lib/common-grid/grid-action/grid-action-item/grid-action-item.component.mjs +1 -1
  4. package/esm2022/lib/common-grid/grid-action/grid-action.component.mjs +3 -2
  5. package/esm2022/lib/common-grid/index.component.mjs +6 -3
  6. package/esm2022/lib/dashboard/api.mjs +33 -0
  7. package/esm2022/lib/dashboard/bar-charts/bar-charts.component.mjs +430 -0
  8. package/esm2022/lib/dashboard/bar-charts/utils.mjs +18 -0
  9. package/esm2022/lib/dashboard/dashboard-properties/data-mart-new/data-mart-new.component.mjs +442 -0
  10. package/esm2022/lib/dashboard/dashboard.service.mjs +295 -0
  11. package/esm2022/lib/dashboard/dashboardPorlets.service.mjs +2169 -0
  12. package/esm2022/lib/dashboard/dialog-group/download/index.component.mjs +212 -0
  13. package/esm2022/lib/dashboard/dialog-group/empty-icon-prompt/empty-icon-prompt.component.mjs +36 -0
  14. package/esm2022/lib/dashboard/gadget-group/gadget-pivot/gadget-pivot.component.mjs +3211 -0
  15. package/esm2022/lib/dashboard/gadget-group/gadget-pivot-chart/gadget-pivot.component.mjs +3117 -0
  16. package/esm2022/lib/dashboard/gadget-group/gadget-table/gadget-table.component.mjs +1099 -0
  17. package/esm2022/lib/dashboard/gadget-group/gadget-transpose/gadget-transpose.component.mjs +583 -0
  18. package/esm2022/lib/dashboard/pane-group-new.component.mjs +2031 -0
  19. package/esm2022/lib/dashboard/sidebar-iconlist/field-filter/field-filter.component.mjs +637 -0
  20. package/esm2022/lib/dashboard/sidebar-iconlist/field-format/field-format.component.mjs +753 -0
  21. package/esm2022/lib/dashboard/sidebar-iconlist/portlet-type-new/portlet-type-new.component.mjs +216 -0
  22. package/esm2022/lib/dashboard/sidebar-iconlist/sidebar-iconlist-new.component.mjs +1239 -0
  23. package/esm2022/lib/dialog/common-delete-dialog/index.component.mjs +1 -1
  24. package/esm2022/lib/dialog/common-dialog/index.component.mjs +16 -5
  25. package/esm2022/lib/float-box/index.component.mjs +18 -4
  26. package/esm2022/lib/form/checkbox-group/index.component.mjs +35 -5
  27. package/esm2022/lib/form/drawer-form/drawer-form.component.mjs +177 -76
  28. package/esm2022/lib/form/richtexteditor/index.component.mjs +7 -9
  29. package/esm2022/lib/layout/drawer/index.component.mjs +2 -2
  30. package/esm2022/lib/layout/page-list/index.component.mjs +9 -3
  31. package/esm2022/lib/layout/page-tab/index.component.mjs +5 -3
  32. package/esm2022/lib/layout/rs-stepper/constants.mjs +2 -0
  33. package/esm2022/lib/layout/rs-stepper/index.component.mjs +148 -0
  34. package/esm2022/lib/raise-common-lib.module.mjs +114 -7
  35. package/esm2022/lib/service/InjectionToken.mjs +5 -0
  36. package/esm2022/lib/service/keep-alive.service.mjs +2 -2
  37. package/esm2022/lib/smart-popup/index.component.mjs +1084 -0
  38. package/esm2022/public-api.mjs +19 -1
  39. package/fesm2022/raise-common-lib-new.mjs +18042 -227
  40. package/fesm2022/raise-common-lib-new.mjs.map +1 -1
  41. package/lib/common-grid/index.component.d.ts +2 -1
  42. package/lib/dashboard/api.d.ts +24 -0
  43. package/lib/dashboard/bar-charts/bar-charts.component.d.ts +63 -0
  44. package/lib/dashboard/bar-charts/utils.d.ts +1 -0
  45. package/lib/dashboard/dashboard-properties/data-mart-new/data-mart-new.component.d.ts +52 -0
  46. package/lib/dashboard/dashboard.service.d.ts +152 -0
  47. package/lib/dashboard/dashboardPorlets.service.d.ts +214 -0
  48. package/lib/dashboard/dialog-group/download/index.component.d.ts +36 -0
  49. package/lib/dashboard/dialog-group/empty-icon-prompt/empty-icon-prompt.component.d.ts +15 -0
  50. package/lib/dashboard/gadget-group/gadget-pivot/gadget-pivot.component.d.ts +128 -0
  51. package/lib/dashboard/gadget-group/gadget-pivot-chart/gadget-pivot.component.d.ts +131 -0
  52. package/lib/dashboard/gadget-group/gadget-table/gadget-table.component.d.ts +77 -0
  53. package/lib/dashboard/gadget-group/gadget-transpose/gadget-transpose.component.d.ts +47 -0
  54. package/lib/dashboard/pane-group-new.component.d.ts +169 -0
  55. package/lib/dashboard/sidebar-iconlist/field-filter/field-filter.component.d.ts +56 -0
  56. package/lib/dashboard/sidebar-iconlist/field-format/field-format.component.d.ts +62 -0
  57. package/lib/dashboard/sidebar-iconlist/portlet-type-new/portlet-type-new.component.d.ts +30 -0
  58. package/lib/dashboard/sidebar-iconlist/sidebar-iconlist-new.component.d.ts +150 -0
  59. package/lib/dialog/common-dialog/index.component.d.ts +3 -1
  60. package/lib/float-box/index.component.d.ts +4 -3
  61. package/lib/form/checkbox-group/index.component.d.ts +5 -0
  62. package/lib/form/drawer-form/drawer-form.component.d.ts +21 -8
  63. package/lib/form/richtexteditor/index.component.d.ts +1 -3
  64. package/lib/layout/page-list/index.component.d.ts +3 -1
  65. package/lib/layout/page-tab/index.component.d.ts +1 -0
  66. package/lib/layout/rs-stepper/constants.d.ts +5 -0
  67. package/lib/layout/rs-stepper/index.component.d.ts +31 -0
  68. package/lib/raise-common-lib.module.d.ts +61 -40
  69. package/lib/service/InjectionToken.d.ts +4 -0
  70. package/lib/smart-popup/index.component.d.ts +60 -0
  71. package/package.json +1 -1
  72. package/public-api.d.ts +18 -0
  73. package/src/assets/img/dashboard_icon/AddPerson.svg +4 -0
  74. package/src/assets/img/dashboard_icon/Angle-double-left.svg +12 -0
  75. package/src/assets/img/dashboard_icon/Angle-double-right.svg +12 -0
  76. package/src/assets/img/dashboard_icon/Arrow_collapse.svg +3 -0
  77. package/src/assets/img/dashboard_icon/Arrow_expand.svg +3 -0
  78. package/src/assets/img/dashboard_icon/Close.svg +4 -0
  79. package/src/assets/img/dashboard_icon/Edit_label.svg +3 -0
  80. package/src/assets/img/dashboard_icon/RemoveMini.svg +3 -0
  81. package/src/assets/img/dashboard_icon/ShareTo.svg +3 -0
  82. package/src/assets/img/dashboard_icon/add-dashboard.svg +4 -0
  83. package/src/assets/img/dashboard_icon/add-tab.svg +4 -0
  84. package/src/assets/img/dashboard_icon/angle-left.svg +12 -0
  85. package/src/assets/img/dashboard_icon/angle-right.svg +12 -0
  86. package/src/assets/img/dashboard_icon/area-white.svg +3 -0
  87. package/src/assets/img/dashboard_icon/area.svg +3 -0
  88. package/src/assets/img/dashboard_icon/bar-white.svg +14 -0
  89. package/src/assets/img/dashboard_icon/bar.svg +14 -0
  90. package/src/assets/img/dashboard_icon/basic-icon-filter.svg +14 -0
  91. package/src/assets/img/dashboard_icon/chart-combined-active.svg +7 -0
  92. package/src/assets/img/dashboard_icon/chart-combined.svg +7 -0
  93. package/src/assets/img/dashboard_icon/column-white.svg +14 -0
  94. package/src/assets/img/dashboard_icon/column.svg +26 -0
  95. package/src/assets/img/dashboard_icon/customize.png +0 -0
  96. package/src/assets/img/dashboard_icon/dashboard-description.svg +18 -0
  97. package/src/assets/img/dashboard_icon/dashboard-download.svg +18 -0
  98. package/src/assets/img/dashboard_icon/dashboard-drag.svg +28 -0
  99. package/src/assets/img/dashboard_icon/dashboard-duplicate.svg +24 -0
  100. package/src/assets/img/dashboard_icon/dashboard-icon.svg +12 -0
  101. package/src/assets/img/dashboard_icon/dashboard-properties.svg +18 -0
  102. package/src/assets/img/dashboard_icon/dashboard-rename.svg +18 -0
  103. package/src/assets/img/dashboard_icon/dashboard-share.svg +20 -0
  104. package/src/assets/img/dashboard_icon/dashboard-tab-delete.svg +4 -0
  105. package/src/assets/img/dashboard_icon/dashboard_Share.svg +3 -0
  106. package/src/assets/img/dashboard_icon/dashboard_ToolsHide.svg +4 -0
  107. package/src/assets/img/dashboard_icon/datamart_.svg +5 -0
  108. package/src/assets/img/dashboard_icon/datamart_Admin.svg +3 -0
  109. package/src/assets/img/dashboard_icon/datamart_Asset Portfolio.svg +4 -0
  110. package/src/assets/img/dashboard_icon/datamart_Bank.svg +3 -0
  111. package/src/assets/img/dashboard_icon/datamart_CRM.svg +6 -0
  112. package/src/assets/img/dashboard_icon/datamart_Company.svg +6 -0
  113. package/src/assets/img/dashboard_icon/datamart_Compliance.svg +3 -0
  114. package/src/assets/img/dashboard_icon/datamart_Contact.svg +3 -0
  115. package/src/assets/img/dashboard_icon/datamart_DASHBOARD.svg +4 -0
  116. package/src/assets/img/dashboard_icon/datamart_DOCX.svg +4 -0
  117. package/src/assets/img/dashboard_icon/datamart_ESG.svg +4 -0
  118. package/src/assets/img/dashboard_icon/datamart_Financials - Company.svg +3 -0
  119. package/src/assets/img/dashboard_icon/datamart_Fund.svg +4 -0
  120. package/src/assets/img/dashboard_icon/datamart_FundFinancial.svg +4 -0
  121. package/src/assets/img/dashboard_icon/datamart_HTML.svg +4 -0
  122. package/src/assets/img/dashboard_icon/datamart_Logs.svg +8 -0
  123. package/src/assets/img/dashboard_icon/datamart_PDF.svg +5 -0
  124. package/src/assets/img/dashboard_icon/datamart_Project.svg +3 -0
  125. package/src/assets/img/dashboard_icon/datamart_Templates.svg +7 -0
  126. package/src/assets/img/dashboard_icon/datamart_Track Change.svg +3 -0
  127. package/src/assets/img/dashboard_icon/datamart_VirtualGroup.svg +5 -0
  128. package/src/assets/img/dashboard_icon/datamart_XLS.svg +4 -0
  129. package/src/assets/img/dashboard_icon/desktop_selected.svg +10 -0
  130. package/src/assets/img/dashboard_icon/desktop_unselected.svg +10 -0
  131. package/src/assets/img/dashboard_icon/favourite-grey.svg +3 -0
  132. package/src/assets/img/dashboard_icon/favourite-yellow.svg +3 -0
  133. package/src/assets/img/dashboard_icon/forms-checkbox-square-tick.svg +3 -0
  134. package/src/assets/img/dashboard_icon/ftable-white.svg +24 -0
  135. package/src/assets/img/dashboard_icon/ftable.svg +24 -0
  136. package/src/assets/img/dashboard_icon/gadget-basic-arrow-down.svg +14 -0
  137. package/src/assets/img/dashboard_icon/gadget-basic-format.svg +21 -0
  138. package/src/assets/img/dashboard_icon/gadget-basic-sub-total.svg +18 -0
  139. package/src/assets/img/dashboard_icon/gadget-basic-total-1.svg +9 -0
  140. package/src/assets/img/dashboard_icon/gadget-basic-total.svg +16 -0
  141. package/src/assets/img/dashboard_icon/gadget-columns.svg +12 -0
  142. package/src/assets/img/dashboard_icon/gadget-delete.svg +18 -0
  143. package/src/assets/img/dashboard_icon/gadget-download.svg +18 -0
  144. package/src/assets/img/dashboard_icon/gadget-duplicate.svg +24 -0
  145. package/src/assets/img/dashboard_icon/gadget-edit.svg +18 -0
  146. package/src/assets/img/dashboard_icon/gadget-filters-light.svg +9 -0
  147. package/src/assets/img/dashboard_icon/gadget-filters.svg +9 -0
  148. package/src/assets/img/dashboard_icon/gadget-format-0.svg +8 -0
  149. package/src/assets/img/dashboard_icon/gadget-format-1.svg +8 -0
  150. package/src/assets/img/dashboard_icon/gadget-format.svg +19 -0
  151. package/src/assets/img/dashboard_icon/gadget-fullscreen.svg +30 -0
  152. package/src/assets/img/dashboard_icon/gadget-settings.svg +18 -0
  153. package/src/assets/img/dashboard_icon/gadget-sub-total-0.svg +18 -0
  154. package/src/assets/img/dashboard_icon/gadget-sub-total-1.svg +18 -0
  155. package/src/assets/img/dashboard_icon/gadget-thumbnail.svg +12 -0
  156. package/src/assets/img/dashboard_icon/gadget-type-light.svg +15 -0
  157. package/src/assets/img/dashboard_icon/gadget-type.svg +16 -0
  158. package/src/assets/img/dashboard_icon/geo-white.svg +14 -0
  159. package/src/assets/img/dashboard_icon/geo.svg +14 -0
  160. package/src/assets/img/dashboard_icon/historic-IRR-white.svg +9 -0
  161. package/src/assets/img/dashboard_icon/historic-IRR.svg +5 -0
  162. package/src/assets/img/dashboard_icon/information-1.png +0 -0
  163. package/src/assets/img/dashboard_icon/information-grey.svg +4 -0
  164. package/src/assets/img/dashboard_icon/menu-change-group.svg +3 -0
  165. package/src/assets/img/dashboard_icon/menu-close.svg +20 -0
  166. package/src/assets/img/dashboard_icon/menu-delete.svg +18 -0
  167. package/src/assets/img/dashboard_icon/menu-description.svg +19 -0
  168. package/src/assets/img/dashboard_icon/menu-download.svg +24 -0
  169. package/src/assets/img/dashboard_icon/menu-drag.svg +28 -0
  170. package/src/assets/img/dashboard_icon/menu-duplicate.svg +26 -0
  171. package/src/assets/img/dashboard_icon/menu-properties.svg +18 -0
  172. package/src/assets/img/dashboard_icon/menu-rename.svg +23 -0
  173. package/src/assets/img/dashboard_icon/menu-share.svg +20 -0
  174. package/src/assets/img/dashboard_icon/menu-toolbar.svg +10 -0
  175. package/src/assets/img/dashboard_icon/mobile_selected.svg +10 -0
  176. package/src/assets/img/dashboard_icon/mobile_unselected.svg +10 -0
  177. package/src/assets/img/dashboard_icon/more_Save.svg +3 -0
  178. package/src/assets/img/dashboard_icon/more_View.svg +3 -0
  179. package/src/assets/img/dashboard_icon/multi-series-white.svg +20 -0
  180. package/src/assets/img/dashboard_icon/multi-series.svg +6 -0
  181. package/src/assets/img/dashboard_icon/paint-bucket.svg +6 -0
  182. package/src/assets/img/dashboard_icon/pie-white.svg +16 -0
  183. package/src/assets/img/dashboard_icon/pie.svg +16 -0
  184. package/src/assets/img/dashboard_icon/pivot-chart-active.svg +8 -0
  185. package/src/assets/img/dashboard_icon/pivot-chart.svg +8 -0
  186. package/src/assets/img/dashboard_icon/pivot-white.svg +8 -0
  187. package/src/assets/img/dashboard_icon/pivot.svg +8 -0
  188. package/src/assets/img/dashboard_icon/pivot_column.svg +9 -0
  189. package/src/assets/img/dashboard_icon/pivot_column_active.svg +9 -0
  190. package/src/assets/img/dashboard_icon/pivot_line.svg +12 -0
  191. package/src/assets/img/dashboard_icon/pivot_line_active.svg +12 -0
  192. package/src/assets/img/dashboard_icon/print-A2.svg +3 -0
  193. package/src/assets/img/dashboard_icon/radar-white.svg +19 -0
  194. package/src/assets/img/dashboard_icon/radar.svg +19 -0
  195. package/src/assets/img/dashboard_icon/saveAs.svg +3 -0
  196. package/src/assets/img/dashboard_icon/search_input.svg +4 -0
  197. package/src/assets/img/dashboard_icon/table-3-white.svg +16 -0
  198. package/src/assets/img/dashboard_icon/table-3.svg +16 -0
  199. package/src/assets/img/dashboard_icon/table-filter-off.svg +5 -0
  200. package/src/assets/img/dashboard_icon/table-filter-on.svg +5 -0
  201. package/src/assets/img/dashboard_icon/tag_dashboard_selected.svg +3 -0
  202. package/src/assets/img/dashboard_icon/tag_dashboard_unselected.svg +3 -0
  203. package/src/assets/img/dashboard_icon/tag_share_selected.svg +3 -0
  204. package/src/assets/img/dashboard_icon/tag_share_unselected.svg +3 -0
  205. package/src/assets/img/dashboard_icon/tick.svg +26 -0
  206. package/src/assets/img/dashboard_icon/toolbar_AddDashboard.svg +5 -0
  207. package/src/assets/img/dashboard_icon/toolbar_AddGroup.svg +3 -0
  208. package/src/assets/img/dashboard_icon/toolbar_AddReport.svg +3 -0
  209. package/src/assets/img/dashboard_icon/toolbar_CollapseAll.svg +3 -0
  210. package/src/assets/img/dashboard_icon/toolbar_Customize.svg +3 -0
  211. package/src/assets/img/dashboard_icon/toolbar_DeleteDark.svg +3 -0
  212. package/src/assets/img/dashboard_icon/toolbar_Duplicate.svg +3 -0
  213. package/src/assets/img/dashboard_icon/toolbar_Edit.svg +3 -0
  214. package/src/assets/img/dashboard_icon/toolbar_ExpandAll.svg +3 -0
  215. package/src/assets/img/dashboard_icon/toolbar_Search.svg +3 -0
  216. package/src/assets/img/dashboard_icon/topbar-menu.svg +33 -0
  217. package/src/assets/img/dashboard_icon/topbar-refresh.svg +17 -0
  218. package/src/assets/img/dashboard_icon/topbar-tool-off.svg +12 -0
  219. package/src/assets/img/dashboard_icon/topbar-tool-on.svg +12 -0
  220. package/src/assets/img/dashboard_icon/trade-up-white.svg +14 -0
  221. package/src/assets/img/dashboard_icon/trade-up.svg +14 -0
  222. package/src/assets/img/dashboard_icon/transpose-white.svg +16 -0
  223. package/src/assets/img/dashboard_icon/transpose.svg +16 -0
@@ -0,0 +1,1084 @@
1
+ import { Component, EventEmitter, Input, Output, ViewChild, HostListener, } from "@angular/core";
2
+ import * as i0 from "@angular/core";
3
+ import * as i1 from "@angular/common";
4
+ export class SmartPopupComponent {
5
+ ref;
6
+ _placement = "BottomLeft";
7
+ _offset = 8;
8
+ _autoAdjust = "yes";
9
+ triggerElementRef = null;
10
+ loading = false;
11
+ _open = false;
12
+ _width = null;
13
+ _height = null;
14
+ // 解析placement格式
15
+ get placementInfo() {
16
+ const placementMap = {
17
+ TopLeft: { placement: "top", position: "start" },
18
+ TopCenter: { placement: "top", position: "center" },
19
+ TopRight: { placement: "top", position: "end" },
20
+ BottomLeft: { placement: "bottom", position: "start" },
21
+ BottomCenter: { placement: "bottom", position: "center" },
22
+ BottomRight: { placement: "bottom", position: "end" },
23
+ LeftTop: { placement: "left", position: "start" },
24
+ LeftCenter: { placement: "left", position: "center" },
25
+ LeftBottom: { placement: "left", position: "end" },
26
+ RightTop: { placement: "right", position: "start" },
27
+ RightCenter: { placement: "right", position: "center" },
28
+ RightBottom: { placement: "right", position: "end" },
29
+ };
30
+ return (placementMap[this._placement] || {
31
+ placement: "bottom",
32
+ position: "start",
33
+ });
34
+ }
35
+ get offset() {
36
+ return this._offset || 8;
37
+ }
38
+ get autoAdjust() {
39
+ return this._autoAdjust === "yes";
40
+ }
41
+ openChange = new EventEmitter();
42
+ contentLoad = new EventEmitter();
43
+ internalTriggerElement;
44
+ popupElement;
45
+ currentTriggerElement = null;
46
+ constructor(ref) {
47
+ this.ref = ref;
48
+ }
49
+ ngAfterViewInit() {
50
+ this.fixedContainerEl = this.getFixedContainer();
51
+ this.fixedContainerEl.append(this.popupElement.nativeElement);
52
+ this.updateTriggerElement();
53
+ // 如果提供了固定尺寸,立即应用
54
+ if (this._width !== null &&
55
+ this._height !== null &&
56
+ this.popupElement &&
57
+ this.popupElement.nativeElement) {
58
+ const popupEl = this.popupElement.nativeElement;
59
+ popupEl.style.width = this._width + "px";
60
+ popupEl.style.height = this._height + "px";
61
+ popupEl.style.minWidth = this._width + "px";
62
+ popupEl.style.maxWidth = this._width + "px";
63
+ popupEl.style.minHeight = this._height + "px";
64
+ popupEl.style.maxHeight = this._height + "px";
65
+ }
66
+ // 如果外部传入 open 属性为 true,自动打开
67
+ if (this._open) {
68
+ setTimeout(() => this.open(), 0);
69
+ }
70
+ }
71
+ ngOnChanges(changes) {
72
+ // 处理固定尺寸变化
73
+ if ((changes._width || changes._height) &&
74
+ this.popupElement &&
75
+ this.popupElement.nativeElement) {
76
+ const popupEl = this.popupElement.nativeElement;
77
+ if (this._width !== null) {
78
+ popupEl.style.width = this._width + "px";
79
+ popupEl.style.minWidth = this._width + "px";
80
+ popupEl.style.maxWidth = this._width + "px";
81
+ }
82
+ if (this._height !== null) {
83
+ popupEl.style.height = this._height + "px";
84
+ popupEl.style.minHeight = this._height + "px";
85
+ popupEl.style.maxHeight = this._height + "px";
86
+ }
87
+ }
88
+ // 先处理触发元素变化(确保在打开前更新触发元素)
89
+ if (changes.triggerElementRef) {
90
+ const previousTrigger = this.currentTriggerElement;
91
+ this.updateTriggerElement();
92
+ // 如果弹窗已经打开,且触发元素发生了变化,立即更新位置
93
+ if (this.opened === "yes" &&
94
+ previousTrigger !== this.currentTriggerElement &&
95
+ this.currentTriggerElement) {
96
+ // 如果提供了固定尺寸,直接重新计算位置(避免位置跳动)
97
+ if (this._width !== null && this._height !== null) {
98
+ // 先隐藏弹窗(positioning = yes)
99
+ this.positioning = "yes";
100
+ this.ref.markForCheck();
101
+ this.ref.detectChanges(); // 立即应用隐藏状态
102
+ requestAnimationFrame(() => {
103
+ if (this.currentTriggerElement) {
104
+ const triggerRect = this.currentTriggerElement.getBoundingClientRect();
105
+ const popupSize = {
106
+ width: this._width,
107
+ height: this._height,
108
+ };
109
+ const targetInfo = this.placementInfo;
110
+ let finalPlacement = targetInfo.placement;
111
+ const finalPosition = targetInfo.position;
112
+ if (this.autoAdjust) {
113
+ const popupRect = {
114
+ width: popupSize.width,
115
+ height: popupSize.height,
116
+ top: 0,
117
+ left: 0,
118
+ right: popupSize.width,
119
+ bottom: popupSize.height,
120
+ x: 0,
121
+ y: 0,
122
+ toJSON: () => ({}),
123
+ };
124
+ const optimal = this.calculateOptimalPlacement(triggerRect, popupRect, window.innerWidth, window.innerHeight);
125
+ finalPlacement = optimal.placement;
126
+ }
127
+ this.actualPlacement = finalPlacement;
128
+ this.actualPosition = finalPosition;
129
+ const position = this.calculatePositionCoordinates(triggerRect, finalPlacement, finalPosition, popupSize);
130
+ if (this.popupElement && this.popupElement.nativeElement) {
131
+ const popupEl = this.popupElement.nativeElement;
132
+ popupEl.style.top = position.top;
133
+ popupEl.style.left = position.left;
134
+ popupEl.style.transform = `translate(${position.translateX}, ${position.translateY})`;
135
+ popupEl.offsetHeight; // 强制同步应用样式
136
+ // 位置设置完成后,再显示弹窗
137
+ requestAnimationFrame(() => {
138
+ this.positioning = "no";
139
+ this.ref.markForCheck();
140
+ });
141
+ }
142
+ }
143
+ });
144
+ }
145
+ else {
146
+ // 使用新的打开方式更新位置
147
+ this.positioning = "yes";
148
+ this.ref.markForCheck();
149
+ requestAnimationFrame(() => {
150
+ requestAnimationFrame(() => {
151
+ this.updatePopupPosition();
152
+ this.positioning = "no";
153
+ this.ref.markForCheck();
154
+ });
155
+ });
156
+ }
157
+ }
158
+ }
159
+ // 处理 open 变化(确保在触发元素更新后处理)
160
+ if (changes._open) {
161
+ if (this._open && this.opened === "no") {
162
+ // 确保触发元素已更新
163
+ this.updateTriggerElement();
164
+ // 使用 setTimeout 确保所有变更都已处理
165
+ setTimeout(() => {
166
+ // 再次确保触发元素已更新
167
+ this.updateTriggerElement();
168
+ this.open();
169
+ }, 0);
170
+ }
171
+ else if (!this._open && this.opened === "yes") {
172
+ this.close();
173
+ }
174
+ }
175
+ // 当加载完成时,更新位置(如果提供了固定尺寸,不需要更新位置)
176
+ if (changes.loading &&
177
+ !changes.loading.currentValue &&
178
+ changes.loading.previousValue) {
179
+ if (this.opened === "yes") {
180
+ // 如果提供了固定尺寸,位置已经计算好了,不需要更新
181
+ if (this._width !== null && this._height !== null) {
182
+ this.contentLoad.emit();
183
+ }
184
+ else {
185
+ // 如果正在定位,不需要更新位置
186
+ if (this.positioning === "no") {
187
+ requestAnimationFrame(() => {
188
+ this.updatePopupPosition();
189
+ this.contentLoad.emit();
190
+ });
191
+ }
192
+ else {
193
+ // 如果正在定位,等待定位完成后再触发事件
194
+ const checkPositioning = () => {
195
+ if (this.positioning === "no") {
196
+ this.contentLoad.emit();
197
+ }
198
+ else {
199
+ setTimeout(checkPositioning, 10);
200
+ }
201
+ };
202
+ checkPositioning();
203
+ }
204
+ }
205
+ }
206
+ }
207
+ }
208
+ ngOnDestroy() {
209
+ if (this.popupElement && this.popupElement.nativeElement) {
210
+ this.popupElement.nativeElement.remove();
211
+ }
212
+ window.removeEventListener("click", this.onClickOutside);
213
+ window.removeEventListener("scroll", this.onWindowScroll, true);
214
+ }
215
+ updateTriggerElement() {
216
+ if (this.triggerElementRef) {
217
+ this.currentTriggerElement = this.triggerElementRef;
218
+ }
219
+ else if (this.internalTriggerElement &&
220
+ this.internalTriggerElement.nativeElement) {
221
+ this.currentTriggerElement = this.internalTriggerElement.nativeElement;
222
+ }
223
+ else {
224
+ this.currentTriggerElement = null;
225
+ }
226
+ }
227
+ FIXED_CONTAINER_ID = "rs-smart-popup-fixed-container";
228
+ fixedContainerEl;
229
+ getFixedContainer() {
230
+ let containerElement = document.getElementById(this.FIXED_CONTAINER_ID);
231
+ if (!containerElement) {
232
+ containerElement = document.createElement("div");
233
+ containerElement.setAttribute("id", this.FIXED_CONTAINER_ID);
234
+ document.body.append(containerElement);
235
+ }
236
+ return containerElement;
237
+ }
238
+ opened = "no";
239
+ positioning = "no";
240
+ actualPlacement = "bottom";
241
+ actualPosition = "start";
242
+ open(triggerElement) {
243
+ // 如果传入了触发元素,使用它
244
+ if (triggerElement) {
245
+ this.currentTriggerElement = triggerElement;
246
+ }
247
+ else {
248
+ this.updateTriggerElement();
249
+ }
250
+ if (!this.currentTriggerElement) {
251
+ console.warn("SmartPopupComponent: No trigger element found");
252
+ return;
253
+ }
254
+ // 如果已经打开,且提供了固定尺寸,直接重新计算位置(避免关闭再打开导致的跳动)
255
+ if (this.opened === "yes") {
256
+ if (this._width !== null && this._height !== null) {
257
+ // 有固定尺寸,直接重新计算位置,不关闭弹窗
258
+ // 先隐藏弹窗(positioning = yes)
259
+ this.positioning = "yes";
260
+ this.ref.markForCheck();
261
+ this.ref.detectChanges(); // 立即应用隐藏状态
262
+ requestAnimationFrame(() => {
263
+ // 再次确保触发元素已更新
264
+ this.updateTriggerElement();
265
+ if (this.currentTriggerElement) {
266
+ const triggerRect = this.currentTriggerElement.getBoundingClientRect();
267
+ const popupSize = {
268
+ width: this._width,
269
+ height: this._height,
270
+ };
271
+ const targetInfo = this.placementInfo;
272
+ let finalPlacement = targetInfo.placement;
273
+ const finalPosition = targetInfo.position;
274
+ if (this.autoAdjust) {
275
+ const popupRect = {
276
+ width: popupSize.width,
277
+ height: popupSize.height,
278
+ top: 0,
279
+ left: 0,
280
+ right: popupSize.width,
281
+ bottom: popupSize.height,
282
+ x: 0,
283
+ y: 0,
284
+ toJSON: () => ({}),
285
+ };
286
+ const optimal = this.calculateOptimalPlacement(triggerRect, popupRect, window.innerWidth, window.innerHeight);
287
+ finalPlacement = optimal.placement;
288
+ }
289
+ this.actualPlacement = finalPlacement;
290
+ this.actualPosition = finalPosition;
291
+ const position = this.calculatePositionCoordinates(triggerRect, finalPlacement, finalPosition, popupSize);
292
+ if (this.popupElement && this.popupElement.nativeElement) {
293
+ const popupEl = this.popupElement.nativeElement;
294
+ popupEl.style.top = position.top;
295
+ popupEl.style.left = position.left;
296
+ popupEl.style.transform = `translate(${position.translateX}, ${position.translateY})`;
297
+ popupEl.offsetHeight; // 强制同步应用样式
298
+ // 位置设置完成后,再显示弹窗
299
+ requestAnimationFrame(() => {
300
+ this.positioning = "no";
301
+ this.ref.markForCheck();
302
+ });
303
+ }
304
+ }
305
+ });
306
+ return;
307
+ }
308
+ else {
309
+ // 没有固定尺寸,先关闭再打开
310
+ this.opened = "no";
311
+ this.positioning = "no";
312
+ this.ref.markForCheck();
313
+ requestAnimationFrame(() => {
314
+ this.updateTriggerElement();
315
+ this.openPopup();
316
+ });
317
+ return;
318
+ }
319
+ }
320
+ // 确保触发元素已更新
321
+ this.updateTriggerElement();
322
+ this.openPopup();
323
+ }
324
+ openPopup() {
325
+ // 再次确保触发元素已更新
326
+ this.updateTriggerElement();
327
+ if (!this.currentTriggerElement) {
328
+ console.warn("SmartPopupComponent: No trigger element found when opening popup");
329
+ return;
330
+ }
331
+ // 如果提供了固定尺寸,可以在打开前就计算好位置
332
+ if (this._width !== null && this._height !== null) {
333
+ // 先计算位置(不依赖DOM渲染,直接根据triggerElement计算)
334
+ const triggerRect = this.currentTriggerElement.getBoundingClientRect();
335
+ const viewportWidth = window.innerWidth;
336
+ const viewportHeight = window.innerHeight;
337
+ const popupSize = {
338
+ width: this._width,
339
+ height: this._height,
340
+ };
341
+ const popupRect = {
342
+ width: popupSize.width,
343
+ height: popupSize.height,
344
+ top: 0,
345
+ left: 0,
346
+ right: popupSize.width,
347
+ bottom: popupSize.height,
348
+ x: 0,
349
+ y: 0,
350
+ toJSON: () => ({}),
351
+ };
352
+ const targetInfo = this.placementInfo;
353
+ let finalPlacement = targetInfo.placement;
354
+ // 始终使用用户指定的 position,autoAdjust 只调整 placement(方向),不改变对齐方式
355
+ const finalPosition = targetInfo.position;
356
+ if (this.autoAdjust) {
357
+ const optimal = this.calculateOptimalPlacement(triggerRect, popupRect, viewportWidth, viewportHeight);
358
+ // autoAdjust 只调整 placement(上下左右),保持用户指定的 position(对齐方式)
359
+ finalPlacement = optimal.placement;
360
+ // finalPosition 保持用户指定的值,不改变
361
+ }
362
+ this.actualPlacement = finalPlacement;
363
+ this.actualPosition = finalPosition;
364
+ // 计算位置坐标(不依赖DOM,直接计算)
365
+ const position = this.calculatePositionCoordinates(triggerRect, finalPlacement, finalPosition, popupSize);
366
+ // 先设置打开状态,但保持隐藏(positioning = yes)
367
+ // 注意:先设置 positioning = yes,再设置 opened = yes,确保弹窗在位置计算完成前始终隐藏
368
+ this.positioning = "yes";
369
+ this.opened = "yes";
370
+ this.openChange.emit(true);
371
+ this.ref.markForCheck();
372
+ // 强制更新视图,确保DOM已更新,但弹窗仍然隐藏(因为 positioning = yes)
373
+ this.ref.detectChanges();
374
+ // 设置位置的函数
375
+ const setPosition = () => {
376
+ if (this.popupElement && this.popupElement.nativeElement) {
377
+ const popupEl = this.popupElement.nativeElement;
378
+ // 立即设置尺寸和位置
379
+ popupEl.style.width = this._width + "px";
380
+ popupEl.style.height = this._height + "px";
381
+ popupEl.style.minWidth = this._width + "px";
382
+ popupEl.style.maxWidth = this._width + "px";
383
+ popupEl.style.minHeight = this._height + "px";
384
+ popupEl.style.maxHeight = this._height + "px";
385
+ popupEl.style.top = position.top;
386
+ popupEl.style.left = position.left;
387
+ popupEl.style.transform = `translate(${position.translateX}, ${position.translateY})`;
388
+ // 强制同步应用样式,确保位置已设置
389
+ popupEl.offsetHeight;
390
+ // 位置设置完成后,再显示弹窗(设置 positioning = no)
391
+ // 使用 requestAnimationFrame 确保样式已应用
392
+ requestAnimationFrame(() => {
393
+ this.positioning = "no";
394
+ this.ref.markForCheck();
395
+ });
396
+ }
397
+ };
398
+ // 如果元素已经存在,立即设置位置
399
+ if (this.popupElement && this.popupElement.nativeElement) {
400
+ setPosition();
401
+ }
402
+ else {
403
+ // 如果元素还不存在,等待渲染后再设置位置
404
+ requestAnimationFrame(() => {
405
+ if (this.popupElement && this.popupElement.nativeElement) {
406
+ setPosition();
407
+ }
408
+ });
409
+ }
410
+ }
411
+ else {
412
+ // 没有固定尺寸,需要等待DOM渲染
413
+ this.positioning = "yes";
414
+ this.ref.markForCheck();
415
+ // 立即强制更新视图,确保DOM已更新
416
+ this.ref.detectChanges();
417
+ // 使用 requestAnimationFrame 确保在浏览器渲染之前更新位置
418
+ requestAnimationFrame(() => {
419
+ // 确保元素已渲染并获取尺寸
420
+ if (this.popupElement && this.popupElement.nativeElement) {
421
+ // 强制重新计算布局,确保元素尺寸已计算
422
+ this.popupElement.nativeElement.offsetHeight;
423
+ // 计算并设置位置
424
+ this.updatePopupPosition();
425
+ // 位置设置完成后,移除定位状态,显示弹窗
426
+ this.positioning = "no";
427
+ this.ref.markForCheck();
428
+ }
429
+ });
430
+ }
431
+ window.addEventListener("click", this.onClickOutside);
432
+ window.addEventListener("scroll", this.onWindowScroll, true);
433
+ }
434
+ close() {
435
+ if (this.opened === "no") {
436
+ return;
437
+ }
438
+ this.opened = "no";
439
+ this.positioning = "no";
440
+ this.openChange.emit(false);
441
+ window.removeEventListener("click", this.onClickOutside);
442
+ window.removeEventListener("scroll", this.onWindowScroll, true);
443
+ this.ref.markForCheck();
444
+ }
445
+ toggle() {
446
+ if (this.opened === "yes") {
447
+ this.close();
448
+ }
449
+ else {
450
+ this.open();
451
+ }
452
+ }
453
+ onClickTrigger(event) {
454
+ event.stopPropagation();
455
+ this.toggle();
456
+ }
457
+ onClickOutside = (event) => {
458
+ const target = event.target;
459
+ const isClickOnTrigger = this.currentTriggerElement && this.currentTriggerElement.contains(target);
460
+ const isClickOnPopup = this.popupElement &&
461
+ this.popupElement.nativeElement &&
462
+ this.popupElement.nativeElement.contains(target);
463
+ if (!isClickOnTrigger && !isClickOnPopup) {
464
+ this.close();
465
+ }
466
+ };
467
+ onWindowScroll = (event) => {
468
+ if (this.opened === "yes") {
469
+ // 检查滚动是否发生在弹窗内部
470
+ const target = event.target;
471
+ const isScrollOnPopup = this.popupElement &&
472
+ this.popupElement.nativeElement &&
473
+ this.popupElement.nativeElement.contains(target);
474
+ // 如果滚动发生在弹窗内部,不更新位置(避免不必要的计算)
475
+ // 如果滚动发生在外部,更新位置(因为触发元素位置可能改变)
476
+ if (!isScrollOnPopup) {
477
+ this.updatePopupPosition();
478
+ }
479
+ }
480
+ };
481
+ // 处理弹窗内部的滚轮事件
482
+ onPopupWheel(event) {
483
+ // 阻止滚轮事件冒泡,避免触发外部滚动处理
484
+ event.stopPropagation();
485
+ }
486
+ // 处理弹窗内部的滚动事件
487
+ onPopupScroll(event) {
488
+ // 阻止滚动事件冒泡,避免触发外部滚动处理
489
+ event.stopPropagation();
490
+ }
491
+ // 计算并设置位置(支持固定尺寸,可在打开前调用)
492
+ calculateAndSetPosition() {
493
+ if (!this.currentTriggerElement) {
494
+ return;
495
+ }
496
+ const triggerRect = this.currentTriggerElement.getBoundingClientRect();
497
+ const viewportWidth = window.innerWidth;
498
+ const viewportHeight = window.innerHeight;
499
+ // 获取弹窗尺寸(优先使用固定尺寸)
500
+ const popupSize = {
501
+ width: this._width !== null
502
+ ? this._width
503
+ : this.popupElement && this.popupElement.nativeElement
504
+ ? this.popupElement.nativeElement.offsetWidth
505
+ : 300,
506
+ height: this._height !== null
507
+ ? this._height
508
+ : this.popupElement && this.popupElement.nativeElement
509
+ ? this.popupElement.nativeElement.offsetHeight
510
+ : 200,
511
+ };
512
+ // 创建虚拟的 popupRect(用于计算)
513
+ const popupRect = {
514
+ width: popupSize.width,
515
+ height: popupSize.height,
516
+ top: 0,
517
+ left: 0,
518
+ right: popupSize.width,
519
+ bottom: popupSize.height,
520
+ x: 0,
521
+ y: 0,
522
+ toJSON: () => ({}),
523
+ };
524
+ // 获取目标位置信息
525
+ const targetInfo = this.placementInfo;
526
+ let finalPlacement = targetInfo.placement;
527
+ // 始终使用用户指定的 position,autoAdjust 只调整 placement(方向),不改变对齐方式
528
+ const finalPosition = targetInfo.position;
529
+ if (this.autoAdjust) {
530
+ const optimal = this.calculateOptimalPlacement(triggerRect, popupRect, viewportWidth, viewportHeight);
531
+ // autoAdjust 只调整 placement(上下左右),保持用户指定的 position(对齐方式)
532
+ finalPlacement = optimal.placement;
533
+ // finalPosition 保持用户指定的值,不改变
534
+ }
535
+ this.actualPlacement = finalPlacement;
536
+ this.actualPosition = finalPosition;
537
+ // 立即设置位置(即使元素还没完全渲染,也要先设置位置)
538
+ if (this.popupElement && this.popupElement.nativeElement) {
539
+ this.setPopupPosition(triggerRect, popupRect, finalPlacement, finalPosition, popupSize);
540
+ // 强制应用样式,确保位置立即生效
541
+ this.ref.detectChanges();
542
+ }
543
+ else {
544
+ // 如果元素还不存在,延迟设置位置
545
+ setTimeout(() => {
546
+ if (this.popupElement && this.popupElement.nativeElement) {
547
+ this.setPopupPosition(triggerRect, popupRect, finalPlacement, finalPosition, popupSize);
548
+ this.ref.detectChanges();
549
+ }
550
+ }, 0);
551
+ }
552
+ this.ref.markForCheck();
553
+ }
554
+ updatePopupPosition() {
555
+ if (!this.currentTriggerElement ||
556
+ !this.popupElement ||
557
+ !this.popupElement.nativeElement) {
558
+ return;
559
+ }
560
+ // 如果提供了固定尺寸,使用固定尺寸计算
561
+ if (this._width !== null && this._height !== null) {
562
+ this.calculateAndSetPosition();
563
+ return;
564
+ }
565
+ const triggerRect = this.currentTriggerElement.getBoundingClientRect();
566
+ const popupRect = this.popupElement.nativeElement.getBoundingClientRect();
567
+ const viewportWidth = window.innerWidth;
568
+ const viewportHeight = window.innerHeight;
569
+ // 获取目标位置信息
570
+ const targetInfo = this.placementInfo;
571
+ let finalPlacement = targetInfo.placement;
572
+ // 始终使用用户指定的 position,autoAdjust 只调整 placement(方向),不改变对齐方式
573
+ const finalPosition = targetInfo.position;
574
+ if (this.autoAdjust) {
575
+ const optimal = this.calculateOptimalPlacement(triggerRect, popupRect, viewportWidth, viewportHeight);
576
+ // autoAdjust 只调整 placement(上下左右),保持用户指定的 position(对齐方式)
577
+ finalPlacement = optimal.placement;
578
+ // finalPosition 保持用户指定的值,不改变
579
+ }
580
+ this.actualPlacement = finalPlacement;
581
+ this.actualPosition = finalPosition;
582
+ this.setPopupPosition(triggerRect, popupRect, finalPlacement, finalPosition);
583
+ this.ref.markForCheck();
584
+ }
585
+ calculateOptimalPlacement(triggerRect, popupRect, viewportWidth, viewportHeight) {
586
+ const targetInfo = this.placementInfo;
587
+ const preferred = targetInfo.placement;
588
+ const preferredPosition = targetInfo.position;
589
+ const space = {
590
+ top: triggerRect.top,
591
+ bottom: viewportHeight - triggerRect.bottom,
592
+ left: triggerRect.left,
593
+ right: viewportWidth - triggerRect.right,
594
+ };
595
+ const popupSize = {
596
+ width: popupRect.width || 300,
597
+ height: popupRect.height || 200, // 默认高度
598
+ };
599
+ // 检查首选位置是否有足够空间
600
+ const hasEnoughSpace = (placement) => {
601
+ switch (placement) {
602
+ case "top":
603
+ return space.top >= popupSize.height + this.offset;
604
+ case "bottom":
605
+ return space.bottom >= popupSize.height + this.offset;
606
+ case "left":
607
+ return space.left >= popupSize.width + this.offset;
608
+ case "right":
609
+ return space.right >= popupSize.width + this.offset;
610
+ }
611
+ };
612
+ // 检查指定位置是否有足够空间
613
+ const checkPositionSpace = (placement, position) => {
614
+ if (placement === "top" || placement === "bottom") {
615
+ // 对于上下位置,检查水平对齐空间
616
+ const popupWidth = popupSize.width;
617
+ const spaceLeft = triggerRect.left;
618
+ const spaceRight = viewportWidth - triggerRect.right;
619
+ if (position === "center") {
620
+ return spaceLeft >= popupWidth / 2 && spaceRight >= popupWidth / 2;
621
+ }
622
+ else if (position === "start") {
623
+ return spaceLeft >= popupWidth;
624
+ }
625
+ else {
626
+ // end
627
+ return spaceRight >= popupWidth;
628
+ }
629
+ }
630
+ else {
631
+ // 对于左右位置,检查垂直对齐空间
632
+ const popupHeight = popupSize.height;
633
+ const spaceTop = triggerRect.top;
634
+ const spaceBottom = viewportHeight - triggerRect.bottom;
635
+ if (position === "center") {
636
+ return spaceTop >= popupHeight / 2 && spaceBottom >= popupHeight / 2;
637
+ }
638
+ else if (position === "start") {
639
+ return spaceTop >= popupHeight;
640
+ }
641
+ else {
642
+ // end
643
+ return spaceBottom >= popupHeight;
644
+ }
645
+ }
646
+ };
647
+ // 计算位置是否合适(考虑水平/垂直对齐)
648
+ const calculatePosition = (placement) => {
649
+ if (placement === "top" || placement === "bottom") {
650
+ // 对于上下位置,检查水平对齐
651
+ const popupWidth = popupSize.width;
652
+ const spaceLeft = triggerRect.left;
653
+ const spaceRight = viewportWidth - triggerRect.right;
654
+ // 优先尝试使用用户指定的position
655
+ if (checkPositionSpace(placement, preferredPosition)) {
656
+ return preferredPosition;
657
+ }
658
+ // 如果中心对齐有足够空间,优先使用中心
659
+ if (spaceLeft >= popupWidth / 2 && spaceRight >= popupWidth / 2) {
660
+ return "center";
661
+ }
662
+ // 如果左侧空间不足,使用右对齐
663
+ if (spaceLeft < popupWidth / 2) {
664
+ return "end";
665
+ }
666
+ // 如果右侧空间不足,使用左对齐
667
+ if (spaceRight < popupWidth / 2) {
668
+ return "start";
669
+ }
670
+ return preferredPosition;
671
+ }
672
+ else {
673
+ // 对于左右位置,检查垂直对齐
674
+ const popupHeight = popupSize.height;
675
+ const spaceTop = triggerRect.top;
676
+ const spaceBottom = viewportHeight - triggerRect.bottom;
677
+ // 优先尝试使用用户指定的position
678
+ if (checkPositionSpace(placement, preferredPosition)) {
679
+ return preferredPosition;
680
+ }
681
+ // 如果中心对齐有足够空间,优先使用中心
682
+ if (spaceTop >= popupHeight / 2 && spaceBottom >= popupHeight / 2) {
683
+ return "center";
684
+ }
685
+ // 如果上方空间不足,使用下对齐
686
+ if (spaceTop < popupHeight / 2) {
687
+ return "end";
688
+ }
689
+ // 如果下方空间不足,使用上对齐
690
+ if (spaceBottom < popupHeight / 2) {
691
+ return "start";
692
+ }
693
+ return preferredPosition;
694
+ }
695
+ };
696
+ // 如果首选位置有足够空间,优先使用用户指定的position
697
+ if (hasEnoughSpace(preferred)) {
698
+ // 即使指定的position空间不足,也尽量保持用户指定的position
699
+ // 边界约束逻辑会在 calculatePositionCoordinates 中处理位置调整
700
+ // 这样可以保持用户期望的对齐方式
701
+ return {
702
+ placement: preferred,
703
+ position: preferredPosition,
704
+ };
705
+ }
706
+ // 根据首选位置选择备选位置
707
+ const alternatives = {
708
+ bottom: ["top", "right", "left"],
709
+ top: ["bottom", "right", "left"],
710
+ right: ["left", "bottom", "top"],
711
+ left: ["right", "bottom", "top"],
712
+ };
713
+ const altList = alternatives[preferred] || [];
714
+ // 尝试找到第一个有足够空间的备选位置
715
+ for (const alt of altList) {
716
+ if (hasEnoughSpace(alt)) {
717
+ return {
718
+ placement: alt,
719
+ position: calculatePosition(alt),
720
+ };
721
+ }
722
+ }
723
+ // 如果都没有足够空间,选择空间最大的位置
724
+ const maxSpace = Math.max(space.top, space.bottom, space.left, space.right);
725
+ let bestPlacement;
726
+ if (maxSpace === space.top)
727
+ bestPlacement = "top";
728
+ else if (maxSpace === space.bottom)
729
+ bestPlacement = "bottom";
730
+ else if (maxSpace === space.left)
731
+ bestPlacement = "left";
732
+ else
733
+ bestPlacement = "right";
734
+ return {
735
+ placement: bestPlacement,
736
+ position: calculatePosition(bestPlacement),
737
+ };
738
+ }
739
+ // 计算位置坐标(纯计算,不依赖DOM,包含边界约束)
740
+ // 注意:弹窗使用 position: fixed,所以坐标应该是相对于视口的,不需要加上滚动偏移
741
+ calculatePositionCoordinates(triggerRect, placement, position, popupSize) {
742
+ const triggerWidth = triggerRect.width;
743
+ const triggerHeight = triggerRect.height;
744
+ const viewportWidth = window.innerWidth;
745
+ const viewportHeight = window.innerHeight;
746
+ let top = 0;
747
+ let left = 0;
748
+ let translateX = "0";
749
+ let translateY = "0";
750
+ switch (placement) {
751
+ case "top":
752
+ // 弹窗在触发元素上方
753
+ top = triggerRect.top - this.offset;
754
+ translateY = "-100%";
755
+ if (position === "start") {
756
+ // 左对齐
757
+ left = triggerRect.left;
758
+ translateX = "0";
759
+ }
760
+ else if (position === "center") {
761
+ // 居中对齐
762
+ left = triggerRect.left + triggerWidth / 2;
763
+ translateX = "-50%";
764
+ }
765
+ else {
766
+ // 右对齐(end)
767
+ left = triggerRect.right;
768
+ translateX = "-100%";
769
+ }
770
+ // 边界约束:确保弹窗不超出视口
771
+ const popupTop = top - popupSize.height;
772
+ if (popupTop < 0) {
773
+ top = popupSize.height + 8; // 距离顶部至少8px
774
+ translateY = "0"; // 取消向上偏移
775
+ }
776
+ // 水平边界约束:尽量保持原始对齐方式
777
+ if (position === "start") {
778
+ // 左对齐:如果超出右边界,调整到右边界;如果超出左边界,调整到左边界
779
+ if (left + popupSize.width > viewportWidth) {
780
+ left = viewportWidth - popupSize.width - 8;
781
+ }
782
+ if (left < 8) {
783
+ left = 8;
784
+ }
785
+ }
786
+ else if (position === "center") {
787
+ // 居中对齐:计算实际左边界
788
+ const actualLeft = left - popupSize.width / 2;
789
+ if (actualLeft < 8) {
790
+ // 左边界不足,尽量保持居中,但调整到不超出左边界
791
+ left = 8 + popupSize.width / 2;
792
+ translateX = "-50%";
793
+ }
794
+ else if (actualLeft + popupSize.width > viewportWidth - 8) {
795
+ // 右边界不足,尽量保持居中,但调整到不超出右边界
796
+ left = viewportWidth - 8 - popupSize.width / 2;
797
+ translateX = "-50%";
798
+ }
799
+ }
800
+ else {
801
+ // 右对齐(end):弹窗右边缘与触发元素右边缘对齐
802
+ // left 是弹窗的右边缘位置(因为 translateX = "-100%")
803
+ // 弹窗的左边缘在 left - popupSize.width
804
+ const popupLeftEdge = left - popupSize.width;
805
+ // 如果弹窗左边缘超出左边界,调整位置但保持右对齐
806
+ if (popupLeftEdge < 8) {
807
+ left = 8 + popupSize.width;
808
+ translateX = "-100%";
809
+ }
810
+ // 如果弹窗右边缘超出右边界,调整位置但保持右对齐
811
+ if (left > viewportWidth - 8) {
812
+ left = viewportWidth - 8;
813
+ translateX = "-100%";
814
+ }
815
+ }
816
+ break;
817
+ case "bottom":
818
+ // 弹窗在触发元素下方
819
+ top = triggerRect.bottom + this.offset;
820
+ if (position === "start") {
821
+ // 左对齐
822
+ left = triggerRect.left;
823
+ translateX = "0";
824
+ }
825
+ else if (position === "center") {
826
+ // 居中对齐
827
+ left = triggerRect.left + triggerWidth / 2;
828
+ translateX = "-50%";
829
+ }
830
+ else {
831
+ // 右对齐(end)
832
+ left = triggerRect.right;
833
+ translateX = "-100%";
834
+ }
835
+ // 边界约束:确保弹窗不超出视口
836
+ if (top + popupSize.height > viewportHeight) {
837
+ top = viewportHeight - popupSize.height - 8; // 距离底部至少8px
838
+ }
839
+ // 水平边界约束:尽量保持原始对齐方式
840
+ if (position === "start") {
841
+ // 左对齐:如果超出右边界,调整到右边界;如果超出左边界,调整到左边界
842
+ if (left + popupSize.width > viewportWidth) {
843
+ left = viewportWidth - popupSize.width - 8;
844
+ }
845
+ if (left < 8) {
846
+ left = 8;
847
+ }
848
+ }
849
+ else if (position === "center") {
850
+ // 居中对齐:计算实际左边界
851
+ const actualLeft = left - popupSize.width / 2;
852
+ if (actualLeft < 8) {
853
+ // 左边界不足,尽量保持居中,但调整到不超出左边界
854
+ left = 8 + popupSize.width / 2;
855
+ translateX = "-50%";
856
+ }
857
+ else if (actualLeft + popupSize.width > viewportWidth - 8) {
858
+ // 右边界不足,尽量保持居中,但调整到不超出右边界
859
+ left = viewportWidth - 8 - popupSize.width / 2;
860
+ translateX = "-50%";
861
+ }
862
+ }
863
+ else {
864
+ // 右对齐(end):弹窗右边缘与触发元素右边缘对齐
865
+ // left 是弹窗的右边缘位置(因为 translateX = "-100%")
866
+ // 弹窗的左边缘在 left - popupSize.width
867
+ const popupLeftEdge = left - popupSize.width;
868
+ // 优先保持与触发元素右对齐,只在必要时调整
869
+ // 如果弹窗右边缘超出右边界,调整位置但保持右对齐
870
+ if (left > viewportWidth - 8) {
871
+ left = viewportWidth - 8;
872
+ translateX = "-100%";
873
+ }
874
+ // 如果弹窗左边缘超出左边界,且弹窗可以完全显示在视口内,才调整位置
875
+ // 这样可以确保在可能的情况下,弹窗始终与触发元素右对齐
876
+ if (popupLeftEdge < 8 && popupSize.width < viewportWidth - 16) {
877
+ // 只有当弹窗可以完全显示在视口内时,才调整位置
878
+ // 否则保持与触发元素右对齐,即使部分超出左边界
879
+ left = 8 + popupSize.width;
880
+ translateX = "-100%";
881
+ }
882
+ }
883
+ break;
884
+ case "left":
885
+ // 弹窗在触发元素左侧
886
+ left = triggerRect.left - this.offset;
887
+ translateX = "-100%";
888
+ if (position === "start") {
889
+ // 上对齐
890
+ top = triggerRect.top;
891
+ translateY = "0";
892
+ }
893
+ else if (position === "center") {
894
+ // 居中对齐
895
+ top = triggerRect.top + triggerHeight / 2;
896
+ translateY = "-50%";
897
+ }
898
+ else {
899
+ // 下对齐(end)
900
+ top = triggerRect.bottom;
901
+ translateY = "-100%";
902
+ }
903
+ // 边界约束:确保弹窗不超出视口
904
+ const popupLeftSide = left - popupSize.width;
905
+ if (popupLeftSide < 0) {
906
+ left = 8; // 距离左侧至少8px
907
+ translateX = "0"; // 取消向左偏移
908
+ }
909
+ // 垂直边界约束:尽量保持原始对齐方式
910
+ if (position === "start") {
911
+ // 上对齐:如果超出下边界,调整到下边界;如果超出上边界,调整到上边界
912
+ if (top + popupSize.height > viewportHeight) {
913
+ top = viewportHeight - popupSize.height - 8;
914
+ }
915
+ if (top < 8) {
916
+ top = 8;
917
+ }
918
+ }
919
+ else if (position === "center") {
920
+ // 居中对齐:计算实际上边界
921
+ const actualTop = top - popupSize.height / 2;
922
+ if (actualTop < 8) {
923
+ // 上边界不足,尽量保持居中,但调整到不超出上边界
924
+ top = 8 + popupSize.height / 2;
925
+ translateY = "-50%";
926
+ }
927
+ else if (actualTop + popupSize.height > viewportHeight - 8) {
928
+ // 下边界不足,尽量保持居中,但调整到不超出下边界
929
+ top = viewportHeight - 8 - popupSize.height / 2;
930
+ translateY = "-50%";
931
+ }
932
+ }
933
+ else {
934
+ // 下对齐(end):如果超出上边界,调整到上边界;如果超出下边界,调整到下边界
935
+ const actualTop = top - popupSize.height;
936
+ if (actualTop < 8) {
937
+ top = 8 + popupSize.height;
938
+ translateY = "-100%";
939
+ }
940
+ if (top > viewportHeight - 8) {
941
+ top = viewportHeight - 8;
942
+ translateY = "-100%";
943
+ }
944
+ }
945
+ break;
946
+ case "right":
947
+ // 弹窗在触发元素右侧
948
+ left = triggerRect.right + this.offset;
949
+ translateX = "0";
950
+ if (position === "start") {
951
+ // 上对齐
952
+ top = triggerRect.top;
953
+ translateY = "0";
954
+ }
955
+ else if (position === "center") {
956
+ // 居中对齐
957
+ top = triggerRect.top + triggerHeight / 2;
958
+ translateY = "-50%";
959
+ }
960
+ else {
961
+ // 下对齐(end)
962
+ top = triggerRect.bottom;
963
+ translateY = "-100%";
964
+ }
965
+ // 边界约束:确保弹窗不超出视口
966
+ if (left + popupSize.width > viewportWidth) {
967
+ left = viewportWidth - popupSize.width - 8; // 距离右侧至少8px
968
+ }
969
+ // 垂直边界约束:尽量保持原始对齐方式
970
+ if (position === "start") {
971
+ // 上对齐:如果超出下边界,调整到下边界;如果超出上边界,调整到上边界
972
+ if (top + popupSize.height > viewportHeight) {
973
+ top = viewportHeight - popupSize.height - 8;
974
+ }
975
+ if (top < 8) {
976
+ top = 8;
977
+ }
978
+ }
979
+ else if (position === "center") {
980
+ // 居中对齐:计算实际上边界
981
+ const actualTop = top - popupSize.height / 2;
982
+ if (actualTop < 8) {
983
+ // 上边界不足,尽量保持居中,但调整到不超出上边界
984
+ top = 8 + popupSize.height / 2;
985
+ translateY = "-50%";
986
+ }
987
+ else if (actualTop + popupSize.height > viewportHeight - 8) {
988
+ // 下边界不足,尽量保持居中,但调整到不超出下边界
989
+ top = viewportHeight - 8 - popupSize.height / 2;
990
+ translateY = "-50%";
991
+ }
992
+ }
993
+ else {
994
+ // 下对齐(end):如果超出上边界,调整到上边界;如果超出下边界,调整到下边界
995
+ const actualTop = top - popupSize.height;
996
+ if (actualTop < 8) {
997
+ top = 8 + popupSize.height;
998
+ translateY = "-100%";
999
+ }
1000
+ if (top > viewportHeight - 8) {
1001
+ top = viewportHeight - 8;
1002
+ translateY = "-100%";
1003
+ }
1004
+ }
1005
+ break;
1006
+ }
1007
+ return {
1008
+ top: top + "px",
1009
+ left: left + "px",
1010
+ translateX,
1011
+ translateY,
1012
+ };
1013
+ }
1014
+ setPopupPosition(triggerRect, popupRect, placement, position, popupSize) {
1015
+ const popupEl = this.popupElement && this.popupElement.nativeElement
1016
+ ? this.popupElement.nativeElement
1017
+ : null;
1018
+ if (!popupEl) {
1019
+ return; // 如果元素还不存在,无法设置位置
1020
+ }
1021
+ // 优先使用传入的固定尺寸,否则从DOM获取
1022
+ const popupWidth = popupSize && popupSize.width !== null && popupSize.width !== undefined
1023
+ ? popupSize.width
1024
+ : popupRect.width || popupEl.offsetWidth || 300;
1025
+ const popupHeight = popupSize && popupSize.height !== null && popupSize.height !== undefined
1026
+ ? popupSize.height
1027
+ : popupRect.height || popupEl.offsetHeight || 200;
1028
+ const coordinates = this.calculatePositionCoordinates(triggerRect, placement, position, { width: popupWidth, height: popupHeight });
1029
+ popupEl.style.top = coordinates.top;
1030
+ popupEl.style.left = coordinates.left;
1031
+ popupEl.style.transform = `translate(${coordinates.translateX}, ${coordinates.translateY})`;
1032
+ }
1033
+ onWindowResize() {
1034
+ if (this.opened === "yes") {
1035
+ this.updatePopupPosition();
1036
+ }
1037
+ }
1038
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SmartPopupComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1039
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: SmartPopupComponent, selector: "rs-smart-popup", inputs: { _placement: ["placement", "_placement"], _offset: ["offset", "_offset"], _autoAdjust: ["autoAdjust", "_autoAdjust"], triggerElementRef: ["triggerElement", "triggerElementRef"], loading: "loading", _open: ["open", "_open"], _width: ["width", "_width"], _height: ["height", "_height"] }, outputs: { openChange: "openChange", contentLoad: "contentLoad" }, host: { listeners: { "window:resize": "onWindowResize()" } }, viewQueries: [{ propertyName: "internalTriggerElement", first: true, predicate: ["trigger"], descendants: true }, { propertyName: "popupElement", first: true, predicate: ["popup"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<!-- \u89E6\u53D1\u5143\u7D20\u63D2\u69FD -->\r\n<ng-container #trigger>\r\n <ng-content select=\"[trigger]\"></ng-content>\r\n</ng-container>\r\n\r\n<!-- \u5F39\u7A97\u5185\u5BB9 -->\r\n<div\r\n #popup\r\n class=\"rs-smart-popup-content\"\r\n [attr.data-opened]=\"opened\"\r\n [attr.data-positioning]=\"positioning\"\r\n (wheel)=\"onPopupWheel($event)\"\r\n (scroll)=\"onPopupScroll($event)\"\r\n>\r\n <div *ngIf=\"loading\" class=\"rs-smart-popup-loading\">\r\n <div class=\"loading-spinner\"></div>\r\n </div>\r\n <div *ngIf=\"!loading\" class=\"rs-smart-popup-body\">\r\n <ng-content></ng-content>\r\n </div>\r\n</div>\r\n\r\n", styles: [".rs-smart-popup-trigger{display:inline-block;cursor:pointer}::ng-deep #rs-smart-popup-fixed-container{width:0;height:0;z-index:100000;pointer-events:none}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content{pointer-events:auto;position:fixed;z-index:100001;padding:8px;border-radius:8px;background:#fff;box-shadow:0 0 8px #00000040;min-width:200px;max-width:400px;max-height:500px;overflow:auto}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content[data-opened=no]{display:none}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content[data-opened=yes]{display:block}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content[data-opened=yes][data-positioning=yes]{display:none!important}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content[data-opened=yes][data-positioning=no]{display:block;visibility:visible;opacity:1;pointer-events:auto}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content .rs-smart-popup-loading{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:20px;min-height:100px}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content .rs-smart-popup-loading .loading-spinner{width:24px;height:24px;border:3px solid #f3f3f3;border-top:3px solid #3498db;border-radius:50%;animation:spin 1s linear infinite;margin-bottom:12px}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content .rs-smart-popup-loading .loading-text{color:#666;font-size:14px}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content .rs-smart-popup-body{width:100%}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
1040
+ }
1041
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SmartPopupComponent, decorators: [{
1042
+ type: Component,
1043
+ args: [{ selector: "rs-smart-popup", template: "<!-- \u89E6\u53D1\u5143\u7D20\u63D2\u69FD -->\r\n<ng-container #trigger>\r\n <ng-content select=\"[trigger]\"></ng-content>\r\n</ng-container>\r\n\r\n<!-- \u5F39\u7A97\u5185\u5BB9 -->\r\n<div\r\n #popup\r\n class=\"rs-smart-popup-content\"\r\n [attr.data-opened]=\"opened\"\r\n [attr.data-positioning]=\"positioning\"\r\n (wheel)=\"onPopupWheel($event)\"\r\n (scroll)=\"onPopupScroll($event)\"\r\n>\r\n <div *ngIf=\"loading\" class=\"rs-smart-popup-loading\">\r\n <div class=\"loading-spinner\"></div>\r\n </div>\r\n <div *ngIf=\"!loading\" class=\"rs-smart-popup-body\">\r\n <ng-content></ng-content>\r\n </div>\r\n</div>\r\n\r\n", styles: [".rs-smart-popup-trigger{display:inline-block;cursor:pointer}::ng-deep #rs-smart-popup-fixed-container{width:0;height:0;z-index:100000;pointer-events:none}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content{pointer-events:auto;position:fixed;z-index:100001;padding:8px;border-radius:8px;background:#fff;box-shadow:0 0 8px #00000040;min-width:200px;max-width:400px;max-height:500px;overflow:auto}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content[data-opened=no]{display:none}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content[data-opened=yes]{display:block}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content[data-opened=yes][data-positioning=yes]{display:none!important}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content[data-opened=yes][data-positioning=no]{display:block;visibility:visible;opacity:1;pointer-events:auto}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content .rs-smart-popup-loading{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:20px;min-height:100px}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content .rs-smart-popup-loading .loading-spinner{width:24px;height:24px;border:3px solid #f3f3f3;border-top:3px solid #3498db;border-radius:50%;animation:spin 1s linear infinite;margin-bottom:12px}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content .rs-smart-popup-loading .loading-text{color:#666;font-size:14px}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}::ng-deep #rs-smart-popup-fixed-container .rs-smart-popup-content .rs-smart-popup-body{width:100%}\n"] }]
1044
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { _placement: [{
1045
+ type: Input,
1046
+ args: ["placement"]
1047
+ }], _offset: [{
1048
+ type: Input,
1049
+ args: ["offset"]
1050
+ }], _autoAdjust: [{
1051
+ type: Input,
1052
+ args: ["autoAdjust"]
1053
+ }], triggerElementRef: [{
1054
+ type: Input,
1055
+ args: ["triggerElement"]
1056
+ }], loading: [{
1057
+ type: Input,
1058
+ args: ["loading"]
1059
+ }], _open: [{
1060
+ type: Input,
1061
+ args: ["open"]
1062
+ }], _width: [{
1063
+ type: Input,
1064
+ args: ["width"]
1065
+ }], _height: [{
1066
+ type: Input,
1067
+ args: ["height"]
1068
+ }], openChange: [{
1069
+ type: Output,
1070
+ args: ["openChange"]
1071
+ }], contentLoad: [{
1072
+ type: Output,
1073
+ args: ["contentLoad"]
1074
+ }], internalTriggerElement: [{
1075
+ type: ViewChild,
1076
+ args: ["trigger", { static: false }]
1077
+ }], popupElement: [{
1078
+ type: ViewChild,
1079
+ args: ["popup", { static: false }]
1080
+ }], onWindowResize: [{
1081
+ type: HostListener,
1082
+ args: ["window:resize"]
1083
+ }] } });
1084
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvcmFpc2UtY29tbW9uLWxpYi9zcmMvbGliL3NtYXJ0LXBvcHVwL2luZGV4LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3JhaXNlLWNvbW1vbi1saWIvc3JjL2xpYi9zbWFydC1wb3B1cC9pbmRleC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBR0wsU0FBUyxFQUVULFlBQVksRUFDWixLQUFLLEVBSUwsTUFBTSxFQUNOLFNBQVMsRUFDVCxZQUFZLEdBQ2IsTUFBTSxlQUFlLENBQUM7OztBQXFCdkIsTUFBTSxPQUFPLG1CQUFtQjtJQThEVjtJQTNEQSxVQUFVLEdBQWtCLFlBQVksQ0FBQztJQUM1QyxPQUFPLEdBQVcsQ0FBQyxDQUFDO0lBQ2hCLFdBQVcsR0FBaUIsS0FBSyxDQUFDO0lBQzlCLGlCQUFpQixHQUF1QixJQUFJLENBQUM7SUFDcEQsT0FBTyxHQUFZLEtBQUssQ0FBQztJQUM1QixLQUFLLEdBQVksS0FBSyxDQUFDO0lBQ3RCLE1BQU0sR0FBa0IsSUFBSSxDQUFDO0lBQzVCLE9BQU8sR0FBa0IsSUFBSSxDQUFDO0lBRS9DLGdCQUFnQjtJQUNoQixJQUFJLGFBQWE7UUFJZixNQUFNLFlBQVksR0FLZDtZQUNGLE9BQU8sRUFBRSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRTtZQUNoRCxTQUFTLEVBQUUsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUU7WUFDbkQsUUFBUSxFQUFFLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFO1lBQy9DLFVBQVUsRUFBRSxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRTtZQUN0RCxZQUFZLEVB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QkFBbUI7a0JBTC9CLFNBQVM7K0JBQ0UsZ0JBQWdCO3dHQU9OLFVBQVU7c0JBQTdCLEtBQUs7dUJBQUMsV0FBVztnQkFDRCxPQUFPO3NCQUF2QixLQUFLO3VCQUFDLFFBQVE7Z0JBQ00sV0FBVztzQkFBL0IsS0FBSzt1QkFBQyxZQUFZO2dCQUNNLGlCQUFpQjtzQkFBekMsS0FBSzt1QkFBQyxnQkFBZ0I7Z0JBQ0wsT0FBTztzQkFBeEIsS0FBSzt1QkFBQyxTQUFTO2dCQUNELEtBQUs7c0JBQW5CLEtBQUs7dUJBQUMsTUFBTTtnQkFDRyxNQUFNO3NCQUFyQixLQUFLO3VCQUFDLE9BQU87Z0JBQ0csT0FBTztzQkFBdkIsS0FBSzt1QkFBQyxRQUFRO2dCQTBDTyxVQUFVO3NCQUEvQixNQUFNO3VCQUFDLFlBQVk7Z0JBQ0csV0FBVztzQkFBakMsTUFBTTt1QkFBQyxhQUFhO2dCQUdyQixzQkFBc0I7c0JBRHJCLFNBQVM7dUJBQUMsU0FBUyxFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRTtnQkFHdkMsWUFBWTtzQkFEWCxTQUFTO3VCQUFDLE9BQU8sRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUU7Z0JBNG9DckMsY0FBYztzQkFEYixZQUFZO3VCQUFDLGVBQWUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIEFmdGVyVmlld0luaXQsXHJcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgQ29tcG9uZW50LFxyXG4gIEVsZW1lbnRSZWYsXHJcbiAgRXZlbnRFbWl0dGVyLFxyXG4gIElucHV0LFxyXG4gIE9uRGVzdHJveSxcclxuICBPbkNoYW5nZXMsXHJcbiAgU2ltcGxlQ2hhbmdlcyxcclxuICBPdXRwdXQsXHJcbiAgVmlld0NoaWxkLFxyXG4gIEhvc3RMaXN0ZW5lcixcclxufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xyXG5cclxuZXhwb3J0IHR5cGUgUGxhY2VtZW50VHlwZSA9XHJcbiAgfCBcIlRvcExlZnRcIlxyXG4gIHwgXCJUb3BDZW50ZXJcIlxyXG4gIHwgXCJUb3BSaWdodFwiXHJcbiAgfCBcIkJvdHRvbUxlZnRcIlxyXG4gIHwgXCJCb3R0b21DZW50ZXJcIlxyXG4gIHwgXCJCb3R0b21SaWdodFwiXHJcbiAgfCBcIkxlZnRUb3BcIlxyXG4gIHwgXCJMZWZ0Q2VudGVyXCJcclxuICB8IFwiTGVmdEJvdHRvbVwiXHJcbiAgfCBcIlJpZ2h0VG9wXCJcclxuICB8IFwiUmlnaHRDZW50ZXJcIlxyXG4gIHwgXCJSaWdodEJvdHRvbVwiO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6IFwicnMtc21hcnQtcG9wdXBcIixcclxuICB0ZW1wbGF0ZVVybDogXCIuL2luZGV4LmNvbXBvbmVudC5odG1sXCIsXHJcbiAgc3R5bGVVcmxzOiBbXCIuL2luZGV4LmNvbXBvbmVudC5zY3NzXCJdLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgU21hcnRQb3B1cENvbXBvbmVudFxyXG4gIGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95LCBPbkNoYW5nZXNcclxue1xyXG4gIEBJbnB1dChcInBsYWNlbWVudFwiKSBfcGxhY2VtZW50OiBQbGFjZW1lbnRUeXBlID0gXCJCb3R0b21MZWZ0XCI7XHJcbiAgQElucHV0KFwib2Zmc2V0XCIpIF9vZmZzZXQ6IG51bWJlciA9IDg7XHJcbiAgQElucHV0KFwiYXV0b0FkanVzdFwiKSBfYXV0b0FkanVzdDogXCJ5ZXNcIiB8IFwibm9cIiA9IFwieWVzXCI7XHJcbiAgQElucHV0KFwidHJpZ2dlckVsZW1lbnRcIikgdHJpZ2dlckVsZW1lbnRSZWY6IEhUTUxFbGVtZW50IHwgbnVsbCA9IG51bGw7XHJcbiAgQElucHV0KFwibG9hZGluZ1wiKSBsb2FkaW5nOiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KFwib3BlblwiKSBfb3BlbjogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dChcIndpZHRoXCIpIF93aWR0aDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XHJcbiAgQElucHV0KFwiaGVpZ2h0XCIpIF9oZWlnaHQ6IG51bWJlciB8IG51bGwgPSBudWxsO1xyXG5cclxuICAvLyDop6PmnpBwbGFjZW1lbnTmoLzlvI9cclxuICBnZXQgcGxhY2VtZW50SW5mbygpOiB7XHJcbiAgICBwbGFjZW1lbnQ6IFwidG9wXCIgfCBcImxlZnRcIiB8IFwicmlnaHRcIiB8IFwiYm90dG9tXCI7XHJcbiAgICBwb3NpdGlvbjogXCJzdGFydFwiIHwgXCJjZW50ZXJcIiB8IFwiZW5kXCI7XHJcbiAgfSB7XHJcbiAgICBjb25zdCBwbGFjZW1lbnRNYXA6IHtcclxuICAgICAgW2tleTogc3RyaW5nXToge1xyXG4gICAgICAgIHBsYWNlbWVudDogXCJ0b3BcIiB8IFwibGVmdFwiIHwgXCJyaWdodFwiIHwgXCJib3R0b21cIjtcclxuICAgICAgICBwb3NpdGlvbjogXCJzdGFydFwiIHwgXCJjZW50ZXJcIiB8IFwiZW5kXCI7XHJcbiAgICAgIH07XHJcbiAgICB9ID0ge1xyXG4gICAgICBUb3BMZWZ0OiB7IHBsYWNlbWVudDogXCJ0b3BcIiwgcG9zaXRpb246IFwic3RhcnRcIiB9LFxyXG4gICAgICBUb3BDZW50ZXI6IHsgcGxhY2VtZW50OiBcInRvcFwiLCBwb3NpdGlvbjogXCJjZW50ZXJcIiB9LFxyXG4gICAgICBUb3BSaWdodDogeyBwbGFjZW1lbnQ6IFwidG9wXCIsIHBvc2l0aW9uOiBcImVuZFwiIH0sXHJcbiAgICAgIEJvdHRvbUxlZnQ6IHsgcGxhY2VtZW50OiBcImJvdHRvbVwiLCBwb3NpdGlvbjogXCJzdGFydFwiIH0sXHJcbiAgICAgIEJvdHRvbUNlbnRlcjogeyBwbGFjZW1lbnQ6IFwiYm90dG9tXCIsIHBvc2l0aW9uOiBcImNlbnRlclwiIH0sXHJcbiAgICAgIEJvdHRvbVJpZ2h0OiB7IHBsYWNlbWVudDogXCJib3R0b21cIiwgcG9zaXRpb246IFwiZW5kXCIgfSxcclxuICAgICAgTGVmdFRvcDogeyBwbGFjZW1lbnQ6IFwibGVmdFwiLCBwb3NpdGlvbjogXCJzdGFydFwiIH0sXHJcbiAgICAgIExlZnRDZW50ZXI6IHsgcGxhY2VtZW50OiBcImxlZnRcIiwgcG9zaXRpb246IFwiY2VudGVyXCIgfSxcclxuICAgICAgTGVmdEJvdHRvbTogeyBwbGFjZW1lbnQ6IFwibGVmdFwiLCBwb3NpdGlvbjogXCJlbmRcIiB9LFxyXG4gICAgICBSaWdodFRvcDogeyBwbGFjZW1lbnQ6IFwicmlnaHRcIiwgcG9zaXRpb246IFwic3RhcnRcIiB9LFxyXG4gICAgICBSaWdodENlbnRlcjogeyBwbGFjZW1lbnQ6IFwicmlnaHRcIiwgcG9zaXRpb246IFwiY2VudGVyXCIgfSxcclxuICAgICAgUmlnaHRCb3R0b206IHsgcGxhY2VtZW50OiBcInJpZ2h0XCIsIHBvc2l0aW9uOiBcImVuZFwiIH0sXHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIChcclxuICAgICAgcGxhY2VtZW50TWFwW3RoaXMuX3BsYWNlbWVudF0gfHwge1xyXG4gICAgICAgIHBsYWNlbWVudDogXCJib3R0b21cIixcclxuICAgICAgICBwb3NpdGlvbjogXCJzdGFydFwiLFxyXG4gICAgICB9XHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgZ2V0IG9mZnNldCgpIHtcclxuICAgIHJldHVybiB0aGlzLl9vZmZzZXQgfHwgODtcclxuICB9XHJcblxyXG4gIGdldCBhdXRvQWRqdXN0KCkge1xyXG4gICAgcmV0dXJuIHRoaXMuX2F1dG9BZGp1c3QgPT09IFwieWVzXCI7XHJcbiAgfVxyXG5cclxuICBAT3V0cHV0KFwib3BlbkNoYW5nZVwiKSBvcGVuQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPigpO1xyXG4gIEBPdXRwdXQoXCJjb250ZW50TG9hZFwiKSBjb250ZW50TG9hZCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcclxuXHJcbiAgQFZpZXdDaGlsZChcInRyaWdnZXJcIiwgeyBzdGF0aWM6IGZhbHNlIH0pXHJcbiAgaW50ZXJuYWxUcmlnZ2VyRWxlbWVudDogRWxlbWVudFJlZjxIVE1MRWxlbWVudD47XHJcbiAgQFZpZXdDaGlsZChcInBvcHVwXCIsIHsgc3RhdGljOiBmYWxzZSB9KVxyXG4gIHBvcHVwRWxlbWVudDogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD47XHJcblxyXG4gIGN1cnJlbnRUcmlnZ2VyRWxlbWVudDogSFRNTEVsZW1lbnQgfCBudWxsID0gbnVsbDtcclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWY6IENoYW5nZURldGVjdG9yUmVmKSB7fVxyXG5cclxuICBuZ0FmdGVyVmlld0luaXQoKSB7XHJcbiAgICB0aGlzLmZpeGVkQ29udGFpbmVyRWwgPSB0aGlzLmdldEZpeGVkQ29udGFpbmVyKCk7XHJcbiAgICB0aGlzLmZpeGVkQ29udGFpbmVyRWwuYXBwZW5kKHRoaXMucG9wdXBFbGVtZW50Lm5hdGl2ZUVsZW1lbnQpO1xyXG4gICAgdGhpcy51cGRhdGVUcmlnZ2VyRWxlbWVudCgpO1xyXG5cclxuICAgIC8vIOWmguaenOaPkOS+m+S6huWbuuWumuWwuuWvuO+8jOeri+WNs+W6lOeUqFxyXG4gICAgaWYgKFxyXG4gICAgICB0aGlzLl93aWR0aCAhPT0gbnVsbCAmJlxyXG4gICAgICB0aGlzLl9oZWlnaHQgIT09IG51bGwgJiZcclxuICAgICAgdGhpcy5wb3B1cEVsZW1lbnQgJiZcclxuICAgICAgdGhpcy5wb3B1cEVsZW1lbnQubmF0aXZlRWxlbWVudFxyXG4gICAgKSB7XHJcbiAgICAgIGNvbnN0IHBvcHVwRWwgPSB0aGlzLnBvcHVwRWxlbWVudC5uYXRpdmVFbGVtZW50O1xyXG4gICAgICBwb3B1cEVsLnN0eWxlLndpZHRoID0gdGhpcy5fd2lkdGggKyBcInB4XCI7XHJcbiAgICAgIHBvcHVwRWwuc3R5bGUuaGVpZ2h0ID0gdGhpcy5faGVpZ2h0ICsgXCJweFwiO1xyXG4gICAgICBwb3B1cEVsLnN0eWxlLm1pbldpZHRoID0gdGhpcy5fd2lkdGggKyBcInB4XCI7XHJcbiAgICAgIHBvcHVwRWwuc3R5bGUubWF4V2lkdGggPSB0aGlzLl93aWR0aCArIFwicHhcIjtcclxuICAgICAgcG9wdXBFbC5zdHlsZS5taW5IZWlnaHQgPSB0aGlzLl9oZWlnaHQgKyBcInB4XCI7XHJcbiAgICAgIHBvcHVwRWwuc3R5bGUubWF4SGVpZ2h0ID0gdGhpcy5faGVpZ2h0ICsgXCJweFwiO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIOWmguaenOWklumDqOS8oOWFpSBvcGVuIOWxnuaAp+S4uiB0cnVl77yM6Ieq5Yqo5omT5byAXHJcbiAgICBpZiAodGhpcy5fb3Blbikge1xyXG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMub3BlbigpLCAwKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcclxuICAgIC8vIOWkhOeQhuWbuuWumuWwuuWvuOWPmOWMllxyXG4gICAgaWYgKFxyXG4gICAgICAoY2hhbmdlcy5fd2lkdGggfHwgY2hhbmdlcy5faGVpZ2h0KSAmJlxyXG4gICAgICB0aGlzLnBvcHVwRWxlbWVudCAmJlxyXG4gICAgICB0aGlzLnBvcHVwRWxlbWVudC5uYXRpdmVFbGVtZW50XHJcbiAgICApIHtcclxuICAgICAgY29uc3QgcG9wdXBFbCA9IHRoaXMucG9wdXBFbGVtZW50Lm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICAgIGlmICh0aGlzLl93aWR0aCAhPT0gbnVsbCkge1xyXG4gICAgICAgIHBvcHVwRWwuc3R5bGUud2lkdGggPSB0aGlzLl93aWR0aCArIFwicHhcIjtcclxuICAgICAgICBwb3B1cEVsLnN0eWxlLm1pbldpZHRoID0gdGhpcy5fd2lkdGggKyBcInB4XCI7XHJcbiAgICAgICAgcG9wdXBFbC5zdHlsZS5tYXhXaWR0aCA9IHRoaXMuX3dpZHRoICsgXCJweFwiO1xyXG4gICAgICB9XHJcbiAgICAgIGlmICh0aGlzLl9oZWlnaHQgIT09IG51bGwpIHtcclxuICAgICAgICBwb3B1cEVsLnN0eWxlLmhlaWdodCA9IHRoaXMuX2hlaWdodCArIFwicHhcIjtcclxuICAgICAgICBwb3B1cEVsLnN0eWxlLm1pbkhlaWdodCA9IHRoaXMuX2hlaWdodCArIFwicHhcIjtcclxuICAgICAgICBwb3B1cEVsLnN0eWxlLm1heEhlaWdodCA9IHRoaXMuX2hlaWdodCArIFwicHhcIjtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIOWFiOWkhOeQhuinpuWPkeWFg+e0oOWPmOWMlu+8iOehruS/neWcqOaJk+W8gOWJjeabtOaWsOinpuWPkeWFg+e0oO+8iVxyXG4gICAgaWYgKGNoYW5nZXMudHJpZ2dlckVsZW1lbnRSZWYpIHtcclxuICAgICAgY29uc3QgcHJldmlvdXNUcmlnZ2VyID0gdGhpcy5jdXJyZW50VHJpZ2dlckVsZW1lbnQ7XHJcbiAgICAgIHRoaXMudXBkYXRlVHJpZ2dlckVsZW1lbnQoKTtcclxuXHJcbiAgICAgIC8vIOWmguaenOW8ueeql+W3sue7j+aJk+W8gO+8jOS4lOinpuWPkeWFg+e0oOWPkeeUn+S6huWPmOWMlu+8jOeri+WNs+abtOaWsOS9jee9rlxyXG4gICAgICBpZiAoXHJcbiAgICAgICAgdGhpcy5vcGVuZWQgPT09IFwieWVzXCIgJiZcclxuICAgICAgICBwcmV2aW91c1RyaWdnZXIgIT09IHRoaXMuY3VycmVudFRyaWdnZXJFbGVtZW50ICYmXHJcbiAgICAgICAgdGhpcy5jdXJyZW50VHJpZ2dlckVsZW1lbnRcclxuICAgICAgKSB7XHJcbiAgICAgICAgLy8g5aaC5p6c5o+Q5L6b5LqG5Zu65a6a5bC65a+477yM55u05o6l6YeN5paw6K6h566X5L2N572u77yI6YG/5YWN5L2N572u6Lez5Yqo77yJXHJcbiAgICAgICAgaWYgKHRoaXMuX3dpZHRoICE9PSBudWxsICYmIHRoaXMuX2hlaWdodCAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgLy8g5YWI6ZqQ6JeP5by556qX77yIcG9zaXRpb25pbmcgPSB5ZXPvvIlcclxuICAgICAgICAgIHRoaXMucG9zaXRpb25pbmcgPSBcInllc1wiO1xyXG4gICAgICAgICAgdGhpcy5yZWYubWFya0ZvckNoZWNrKCk7XHJcbiAgICAgICAgICB0aGlzLnJlZi5kZXRlY3RDaGFuZ2VzKCk7IC8vIOeri+WNs+W6lOeUqOmakOiXj+eKtuaAgVxyXG4gICAgICAgICAgXHJcbiAgICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5jdXJyZW50VHJpZ2dlckVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICBjb25zdCB0cmlnZ2VyUmVjdCA9IHRoaXMuY3VycmVudFRyaWdnZXJFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgICAgICAgICAgIGNvbnN0IHBvcHVwU2l6ZSA9IHtcclxuICAgICAgICAgICAgICAgIHdpZHRoOiB0aGlzLl93aWR0aCEsXHJcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IHRoaXMuX2hlaWdodCEsXHJcbiAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICBjb25zdCB0YXJnZXRJbmZvID0gdGhpcy5wbGFjZW1lbnRJbmZvO1xyXG4gICAgICAgICAgICAgIGxldCBmaW5hbFBsYWNlbWVudCA9IHRhcmdldEluZm8ucGxhY2VtZW50O1xyXG4gICAgICAgICAgICAgIGNvbnN0IGZpbmFsUG9zaXRpb24gPSB0YXJnZXRJbmZvLnBvc2l0aW9uO1xyXG5cclxuICAgICAgICAgICAgICBpZiAodGhpcy5hdXRvQWRqdXN0KSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBwb3B1cFJlY3Q6IERPTVJlY3QgPSB7XHJcbiAgICAgICAgICAgICAgICAgIHdpZHRoOiBwb3B1cFNpemUud2lkdGgsXHJcbiAgICAgICAgICAgICAgICAgIGhlaWdodDogcG9wdXBTaXplLmhlaWdodCxcclxuICAgICAgICAgICAgICAgICAgdG9wOiAwLFxyXG4gICAgICAgICAgICAgICAgICBsZWZ0OiAwLFxyXG4gICAgICAgICAgICAgICAgICByaWdodDogcG9wdXBTaXplLndpZHRoLFxyXG4gICAgICAgICAgICAgICAgICBib3R0b206IHBvcHVwU2l6ZS5oZWlnaHQsXHJcbiAgICAgICAgICAgICAgICAgIHg6IDAsXHJcbiAgICAgICAgICAgICAgICAgIHk6IDAsXHJcbiAgICAgICAgICAgICAgICAgIHRvSlNPTjogKCkgPT4gKHt9KSxcclxuICAgICAgICAgICAgICAgIH0gYXMgRE9NUmVjdDtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG9wdGltYWwgPSB0aGlzLmNhbGN1bGF0ZU9wdGltYWxQbGFjZW1lbnQoXHJcbiAgICAgICAgICAgICAgICAgIHRyaWdnZXJSZWN0LFxyXG4gICAgICAgICAgICAgICAgICBwb3B1cFJlY3QsXHJcbiAgICAgICAgICAgICAgICAgIHdpbmRvdy5pbm5lcldpZHRoLFxyXG4gICAgICAgICAgICAgICAgICB3aW5kb3cuaW5uZXJIZWlnaHRcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICBmaW5hbFBsYWNlbWVudCA9IG9wdGltYWwucGxhY2VtZW50O1xyXG4gICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgdGhpcy5hY3R1YWxQbGFjZW1lbnQgPSBmaW5hbFBsYWNlbWVudDtcclxuICAgICAgICAgICAgICB0aGlzLmFjdHVhbFBvc2l0aW9uID0gZmluYWxQb3NpdGlvbjtcclxuXHJcbiAgICAgICAgICAgICAgY29uc3QgcG9zaXRpb24gPSB0aGlzLmNhbGN1bGF0ZVBvc2l0aW9uQ29vcmRpbmF0ZXMoXHJcbiAgICAgICAgICAgICAgICB0cmlnZ2VyUmVjdCxcclxuICAgICAgICAgICAgICAgIGZpbmFsUGxhY2VtZW50LFxyXG4gICAgICAgICAgICAgICAgZmluYWxQb3NpdGlvbixcclxuICAgICAgICAgICAgICAgIHBvcHVwU2l6ZVxyXG4gICAgICAgICAgICAgICk7XHJcblxyXG4gICAgICAgICAgICAgIGlmICh0aGlzLnBvcHVwRWxlbWVudCAmJiB0aGlzLnBvcHVwRWxlbWVudC5uYXRpdmVFbGVtZW50KSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBwb3B1cEVsID0gdGhpcy5wb3B1cEVsZW1lbnQubmF0aXZlRWxlbWVudDtcclxuICAgICAgICAgICAgICAgIHBvcHVwRWwuc3R5bGUudG9wID0gcG9zaXRpb24udG9wO1xyXG4gICAgICAgICAgICAgICAgcG9wdXBFbC5zdHlsZS5sZWZ0ID0gcG9zaXRpb24ubGVmdDtcclxuICAgICAgICAgICAgICAgIHBvcHVwRWwuc3R5bGUudHJhbnNmb3JtID0gYHRyYW5zbGF0ZSgke3Bvc2l0aW9uLnRyYW5zbGF0ZVh9LCAke3Bvc2l0aW9uLnRyYW5zbGF0ZVl9KWA7XHJcbiAgICAgICAgICAgICAgICBwb3B1cEVsLm9mZnNldEhlaWdodDsgLy8g5by65Yi25ZCM5q2l5bqU55So5qC35byPXHJcbiAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIC8vIOS9jee9ruiuvue9ruWujOaIkOWQju+8jOWGjeaYvuekuuW8ueeql1xyXG4gICAgICAgICAgICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgdGhpcy5wb3NpdGlvbmluZyA9IFwibm9cIjtcclxuICAgICAgICAgICAgICAgICAgdGhpcy5yZWYubWFya0ZvckNoZWNrKCk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAvLyDkvb/nlKjmlrDnmoTmiZPlvIDmlrnlvI/mm7TmlrDkvY3nva5cclxuICAgICAgICAgIHRoaXMucG9zaXRpb25pbmcgPSBcInllc1wiO1xyXG4gICAgICAgICAgdGhpcy5yZWYubWFya0ZvckNoZWNrKCk7XHJcbiAgICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xyXG4gICAgICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xyXG4gICAgICAgICAgICAgIHRoaXMudXBkYXRlUG9wdXBQb3NpdGlvbigpO1xyXG4gICAgICAgICAgICAgIHRoaXMucG9zaXRpb25pbmcgPSBcIm5vXCI7XHJcbiAgICAgICAgICAgICAgdGhpcy5yZWYubWFya0ZvckNoZWNrKCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8g5aSE55CGIG9wZW4g5Y+Y5YyW77yI56Gu5L+d5Zyo6Kem5Y+R5YWD57Sg5pu05paw5ZCO5aSE55CG77yJXHJcbiAgICBpZiAoY2hhbmdlcy5fb3Blbikge1xyXG4gICAgICBpZiAodGhpcy5fb3BlbiAmJiB0aGlzLm9wZW5lZCA9PT0gXCJub1wiKSB7XHJcbiAgICAgICAgLy8g56Gu5L+d6Kem5Y+R5YWD57Sg5bey5pu05pawXHJcbiAgICAgICAgdGhpcy51cGRhdGVUcmlnZ2VyRWxlbWVudCgpO1xyXG4gICAgICAgIC8vIOS9v+eUqCBzZXRUaW1lb3V0IOehruS/neaJgOacieWPmOabtOmDveW3suWkhOeQhlxyXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgLy8g5YaN5qyh56Gu5L+d6Kem5Y+R5YWD57Sg5bey5pu05pawXHJcbiAgICAgICAgICB0aGlzLnVwZGF0ZVRyaWdnZXJFbGVtZW50KCk7XHJcbiAgICAgICAgICB0aGlzLm9wZW4oKTtcclxuICAgICAgICB9LCAwKTtcclxuICAgICAgfSBlbHNlIGlmICghdGhpcy5fb3BlbiAmJiB0aGlzLm9wZW5lZCA9PT0gXCJ5ZXNcIikge1xyXG4gICAgICAgIHRoaXMuY2xvc2UoKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIOW9k+WKoOi9veWujOaIkOaXtu+8jOabtOaWsOS9jee9ru+8iOWmguaenOaPkOS+m+S6huWbuuWumuWwuuWvuO+8jOS4jemcgOimgeabtOaWsOS9jee9ru+8iVxyXG4gICAgaWYgKFxyXG4gICAgICBjaGFuZ2VzLmxvYWRpbmcgJiZcclxuICAgICAgIWNoYW5nZXMubG9hZGluZy5jdXJyZW50VmFsdWUgJiZcclxuICAgICAgY2hhbmdlcy5sb2FkaW5nLnByZXZpb3VzVmFsdWVcclxuICAgICkge1xyXG4gICAgICBpZiAodGhpcy5vcGVuZWQgPT09IFwieWVzXCIpIHtcclxuICAgICAgICAvLyDlpoLmnpzmj5Dkvpvkuoblm7rlrprlsLrlr7jvvIzkvY3nva7lt7Lnu4/orqHnrpflpb3kuobvvIzkuI3pnIDopoHmm7TmlrBcclxuICAgICAgICBpZiAodGhpcy5fd2lkdGggIT09IG51bGwgJiYgdGhpcy5faGVpZ2h0ICE9PSBudWxsKSB7XHJcbiAgICAgICAgICB0aGlzLmNvbnRlbnRMb2FkLmVtaXQoKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgLy8g5aaC5p6c5q2j5Zyo5a6a5L2N77yM5LiN6ZyA6KaB5pu05paw5L2N572uXHJcbiAgICAgICAgICBpZiAodGhpcy5wb3NpdGlvbmluZyA9PT0gXCJub1wiKSB7XHJcbiAgICAgICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgdGhpcy51cGRhdGVQb3B1cFBvc2l0aW9uKCk7XHJcbiAgICAgICAgICAgICAgdGhpcy5jb250ZW50TG9hZC5lbWl0KCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgLy8g5aaC5p6c5q2j5Zyo5a6a5L2N77yM562J5b6F5a6a5L2N5a6M5oiQ5ZCO5YaN6Kem5Y+R5LqL5Lu2XHJcbiAgICAgICAgICAgIGNvbnN0IGNoZWNrUG9zaXRpb25pbmcgPSAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgaWYgKHRoaXMucG9zaXRpb25pbmcgPT09IFwibm9cIikge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZW50TG9hZC5lbWl0KCk7XHJcbiAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoY2hlY2tQb3NpdGlvbmluZywgMTApO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgY2hlY2tQb3NpdGlvbmluZygpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICBpZiAodGhpcy5wb3B1cEVsZW1lbnQgJiYgdGhpcy5wb3B1cEVsZW1lbnQubmF0aXZlRWxlbWVudCkge1xyXG4gICAgICB0aGlzLnBvcHVwRWxlbWVudC5uYXRpdmVFbGVtZW50LnJlbW92ZSgpO1xyXG4gICAgfVxyXG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCB0aGlzLm9uQ2xpY2tPdXRzaWRlKTtcclxuICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFwic2Nyb2xsXCIsIHRoaXMub25XaW5kb3dTY3JvbGwsIHRydWUpO1xyXG4gIH1cclxuXHJcbiAgdXBkYXRlVHJpZ2dlckVsZW1lbnQoKSB7XHJcbiAgICBpZiAodGhpcy50cmlnZ2VyRWxlbWVudFJlZikge1xyXG4gICAgICB0aGlzLmN1cnJlbnRUcmlnZ2VyRWxlbWVudCA9IHRoaXMudHJpZ2dlckVsZW1lbnRSZWY7XHJcbiAgICB9IGVsc2UgaWYgKFxyXG4gICAgICB0aGlzLmludGVybmFsVHJpZ2dlckVsZW1lbnQgJiZcclxuICAgICAgdGhpcy5pbnRlcm5hbFRyaWdnZXJFbGVtZW50Lm5hdGl2ZUVsZW1lbnRcclxuICAgICkge1xyXG4gICAgICB0aGlzLmN1cnJlbnRUcmlnZ2VyRWxlbWVudCA9IHRoaXMuaW50ZXJuYWxUcmlnZ2VyRWxlbWVudC5uYXRpdmVFbGVtZW50O1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5jdXJyZW50VHJpZ2dlckVsZW1lbnQgPSBudWxsO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgRklYRURfQ09OVEFJTkVSX0lEID0gXCJycy1zbWFydC1wb3B1cC1maXhlZC1jb250YWluZXJcIjtcclxuICBmaXhlZENvbnRhaW5lckVsOiBIVE1MRWxlbWVudDtcclxuICBnZXRGaXhlZENvbnRhaW5lcigpIHtcclxuICAgIGxldCBjb250YWluZXJFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5GSVhFRF9DT05UQUlORVJfSUQpO1xyXG4gICAgaWYgKCFjb250YWluZXJFbGVtZW50KSB7XHJcbiAgICAgIGNvbnRhaW5lckVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xyXG4gICAgICBjb250YWluZXJFbGVtZW50LnNldEF0dHJpYnV0ZShcImlkXCIsIHRoaXMuRklYRURfQ09OVEFJTkVSX0lEKTtcclxuICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmQoY29udGFpbmVyRWxlbWVudCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gY29udGFpbmVyRWxlbWVudDtcclxuICB9XHJcblxyXG4gIG9wZW5lZDogXCJ5ZXNcIiB8IFwibm9cIiA9IFwibm9cIjtcclxuICBwb3NpdGlvbmluZzogXCJ5ZXNcIiB8IFwibm9cIiA9IFwibm9cIjtcclxuICBhY3R1YWxQbGFjZW1lbnQ6IFwidG9wXCIgfCBcImxlZnRcIiB8IFwicmlnaHRcIiB8IFwiYm90dG9tXCIgPSBcImJvdHRvbVwiO1xyXG4gIGFjdHVhbFBvc2l0aW9uOiBcInN0YXJ0XCIgfCBcImNlbnRlclwiIHwgXCJlbmRcIiA9IFwic3RhcnRcIjtcclxuXHJcbiAgb3Blbih0cmlnZ2VyRWxlbWVudD86IEhUTUxFbGVtZW50KSB7XHJcbiAgICAvLyDlpoLmnpzkvKDlhaXkuobop6blj5HlhYPntKDvvIzkvb/nlKjlroNcclxuICAgIGlmICh0cmlnZ2VyRWxlbWVudCkge1xyXG4gICAgICB0aGlzLmN1cnJlbnRUcmlnZ2VyRWxlbWVudCA9IHRyaWdnZXJFbGVtZW50O1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy51cGRhdGVUcmlnZ2VyRWxlbWVudCgpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghdGhpcy5jdXJyZW50VHJpZ2dlckVsZW1lbnQpIHtcclxuICAgICAgY29uc29sZS53YXJuKFwiU21hcnRQb3B1cENvbXBvbmVudDogTm8gdHJpZ2dlciBlbGVtZW50IGZvdW5kXCIpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgLy8g5aaC5p6c5bey57uP5omT5byA77yM5LiU5o+Q5L6b5LqG5Zu65a6a5bC65a+477yM55u05o6l6YeN5paw6K6h566X5L2N572u77yI6YG/5YWN5YWz6Zet5YaN5omT5byA5a+86Ie055qE6Lez5Yqo77yJXHJcbiAgICBpZiAodGhpcy5vcGVuZWQgPT09IFwieWVzXCIpIHtcclxuICAgICAgaWYgKHRoaXMuX3dpZHRoICE9PSBudWxsICYmIHRoaXMuX2hlaWdodCAhPT0gbnVsbCkge1xyXG4gICAgICAgIC8vIOacieWbuuWumuWwuuWvuO+8jOebtOaOpemHjeaWsOiuoeeul+S9jee9ru+8jOS4jeWFs+mXreW8ueeql1xyXG4gICAgICAgIC8vIOWFiOmakOiXj+W8ueeql++8iHBvc2l0aW9uaW5nID0geWVz77yJXHJcbiAgICAgICAgdGhpcy5wb3NpdGlvbmluZyA9IFwieWVzXCI7XHJcbiAgICAgICAgdGhpcy5yZWYubWFya0ZvckNoZWNrKCk7XHJcbiAgICAgICAgdGhpcy5yZWYuZGV0ZWN0Q2hhbmdlcygpOyAvLyDnq4vljbPlupTnlKjpmpDol4/nirbmgIFcclxuICAgICAgICBcclxuICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xyXG4gICAgICAgICAgLy8g5YaN5qyh56Gu5L+d6Kem5Y+R5YWD57Sg5bey5pu05pawXHJcbiAgICAgICAgICB0aGlzLnVwZGF0ZVRyaWdnZXJFbGVtZW50KCk7XHJcbiAgICAgICAgICBpZiAodGhpcy5jdXJyZW50VHJpZ2dlckVsZW1lbnQpIHtcclxuICAgICAgICAgICAgY29uc3QgdHJpZ2dlclJlY3QgPSB0aGlzLmN1cnJlbnRUcmlnZ2VyRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgICAgICAgICAgY29uc3QgcG9wdXBTaXplID0ge1xyXG4gICAgICAgICAgICAgIHdpZHRoOiB0aGlzLl93aWR0aCEsXHJcbiAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLl9oZWlnaHQhLFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBjb25zdCB0YXJnZXRJbmZvID0gdGhpcy5wbGFjZW1lbnRJbmZvO1xyXG4gICAgICAgICAgICBsZXQgZmluYWxQbGFjZW1lbnQgPSB0YXJnZXRJbmZvLnBsYWNlbWVudDtcclxuICAgICAgICAgICAgY29uc3QgZmluYWxQb3NpdGlvbiA9IHRhcmdldEluZm8ucG9zaXRpb247XHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5hdXRvQWRqdXN0KSB7XHJcbiAgICAgICAgICAgICAgY29uc3QgcG9wdXBSZWN0OiBET01SZWN0ID0ge1xyXG4gICAgICAgICAgICAgICAgd2lkdGg6IHBvcHVwU2l6ZS53aWR0aCxcclxuICAgICAgICAgICAgICAgIGhlaWdodDogcG9wdXBTaXplLmhlaWdodCxcclxuICAgICAgICAgICAgICAgIHRvcDogMCxcclxuICAgICAgICAgICAgICAgIGxlZnQ6IDAsXHJcbiAgICAgICAgICAgICAgICByaWdodDogcG9wdXBTaXplLndpZHRoLFxyXG4gICAgICAgICAgICAgICAgYm90dG9tOiBwb3B1cFNpemUuaGVpZ2h0LFxyXG4gICAgICAgICAgICAgICAgeDogMCxcclxuICAgICAgICAgICAgICAgIHk6IDAsXHJcbiAgICAgICAgICAgICAgICB0b0pTT046ICgpID0+ICh7fSksXHJcbiAgICAgICAgICAgICAgfSBhcyBET01SZWN0O1xyXG4gICAgICAgICAgICAgIGNvbnN0IG9wdGltYWwgPSB0aGlzLmNhbGN1bGF0ZU9wdGltYWxQbGFjZW1lbnQoXHJcbiAgICAgICAgICAgICAgICB0cmlnZ2VyUmVjdCxcclxuICAgICAgICAgICAgICAgIHBvcHVwUmVjdCxcclxuICAgICAgICAgICAgICAgIHdpbmRvdy5pbm5lcldpZHRoLFxyXG4gICAgICAgICAgICAgICAgd2luZG93LmlubmVySGVpZ2h0XHJcbiAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICBmaW5hbFBsYWNlbWVudCA9IG9wdGltYWwucGxhY2VtZW50O1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLmFjdHVhbFBsYWNlbWVudCA9IGZpbmFsUGxhY2VtZW50O1xyXG4gICAgICAgICAgICB0aGlzLmFjdHVhbFBvc2l0aW9uID0gZmluYWxQb3NpdGlvbjtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uID0gdGhpcy5jYWxjdWxhdGVQb3NpdGlvbkNvb3JkaW5hdGVzKFxyXG4gICAgICAgICAgICAgIHRyaWdnZXJSZWN0LFxyXG4gICAgICAgICAgICAgIGZpbmFsUGxhY2VtZW50LFxyXG4gICAgICAgICAgICAgIGZpbmFsUG9zaXRpb24sXHJcbiAgICAgICAgICAgICAgcG9wdXBTaXplXHJcbiAgICAgICAgICAgICk7XHJcblxyXG4gICAgICAgICAgICBpZiAodGhpcy5wb3B1cEVsZW1lbnQgJiYgdGhpcy5wb3B1cEVsZW1lbnQubmF0aXZlRWxlbWVudCkge1xyXG4gICAgICAgICAgICAgIGNvbnN0IHBvcHVwRWwgPSB0aGlzLnBvcHVwRWxlbWVudC5uYXRpdmVFbGVtZW50O1xyXG4gICAgICAgICAgICAgIHBvcHVwRWwuc3R5bGUudG9wID0gcG9zaXRpb24udG9wO1xyXG4gICAgICAgICAgICAgIHBvcHVwRWwuc3R5bGUubGVmdCA9IHBvc2l0aW9uLmxlZnQ7XHJcbiAgICAgICAgICAgICAgcG9wdXBFbC5zdHlsZS50cmFuc2Zvcm0gPSBgdHJhbnNsYXRlKCR7cG9zaXRpb24udHJhbnNsYXRlWH0sICR7cG9zaXRpb24udHJhbnNsYXRlWX0pYDtcclxuICAgICAgICAgICAgICBwb3B1cEVsLm9mZnNldEhlaWdodDsgLy8g5by65Yi25ZCM5q2l5bqU55So5qC35byPXHJcbiAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgLy8g5L2N572u6K6+572u5a6M5oiQ5ZCO77yM5YaN5pi+56S65by556qXXHJcbiAgICAgICAgICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMucG9zaXRpb25pbmcgPSBcIm5vXCI7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnJlZi5tYXJrRm9yQ2hlY2soKTtcclxuICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICAvLyDmsqHmnInlm7rlrprlsLrlr7jvvIzlhYjlhbPpl63lho3miZPlvIBcclxuICAgICAgICB0aGlzLm9wZW5lZCA9IFwibm9cIjtcclxuICAgICAgICB0aGlzLnBvc2l0aW9uaW5nID0gXCJub1wiO1xyXG4gICAgICAgIHRoaXMucmVmLm1hcmtGb3JDaGVjaygpO1xyXG4gICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLnVwZGF0ZVRyaWdnZXJFbGVtZW50KCk7XHJcbiAgICAgICAgICB0aGlzLm9wZW5Qb3B1cCgpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIOehruS/neinpuWPkeWFg+e0oOW3suabtOaWsFxyXG4gICAgdGhpcy51cGRhdGVUcmlnZ2VyRWxlbWVudCgpO1xyXG4gICAgdGhpcy5vcGVuUG9wdXAoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgb3BlblBvcHVwKCkge1xyXG4gICAgLy8g5YaN5qyh56Gu5L+d6Kem5Y+R5YWD57Sg5bey5pu05pawXHJcbiAgICB0aGlzLnVwZGF0ZVRyaWdnZXJFbGVtZW50KCk7XHJcblxyXG4gICAgaWYgKCF0aGlzLmN1cnJlbnRUcmlnZ2VyRWxlbWVudCkge1xyXG4gICAgICBjb25zb2xlLndhcm4oXHJcbiAgICAgICAgXCJTbWFydFBvcHVwQ29tcG9uZW50OiBObyB0cmlnZ2VyIGVsZW1lbnQgZm91bmQgd2hlbiBvcGVuaW5nIHBvcHVwXCJcclxuICAgICAgKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIOWmguaenOaPkOS+m+S6huWbuuWumuWwuuWvuO+8jOWPr+S7peWcqOaJk+W8gOWJjeWwseiuoeeul+WlveS9jee9rlxyXG4gICAgaWYgKHRoaXMuX3dpZHRoICE9PSBudWxsICYmIHRoaXMuX2hlaWdodCAhPT0gbnVsbCkge1xyXG4gICAgICAvLyDlhYjorqHnrpfkvY3nva7vvIjkuI3kvp3otZZET03muLLmn5PvvIznm7TmjqXmoLnmja50cmlnZ2VyRWxlbWVudOiuoeeul++8iVxyXG4gICAgICBjb25zdCB0cmlnZ2VyUmVjdCA9IHRoaXMuY3VycmVudFRyaWdnZXJFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgICBjb25zdCB2aWV3cG9ydFdpZHRoID0gd2luZG93LmlubmVyV2lkdGg7XHJcbiAgICAgIGNvbnN0IHZpZXdwb3J0SGVpZ2h0ID0gd2luZG93LmlubmVySGVpZ2h0O1xyXG5cclxuICAgICAgY29uc3QgcG9wdXBTaXplID0ge1xyXG4gICAgICAgIHdpZHRoOiB0aGlzLl93aWR0aCxcclxuICAgICAgICBoZWlnaHQ6IHRoaXMuX2hlaWdodCxcclxuICAgICAgfTtcclxuXHJcbiAgICAgIGNvbnN0IHBvcHVwUmVjdDogRE9NUmVjdCA9IHtcclxuICAgICAgICB3aWR0aDogcG9wdXBTaXplLndpZHRoLFxyXG4gICAgICAgIGhlaWdodDogcG9wdXBTaXplLmhlaWdodCxcclxuICAgICAgICB0b3A6IDAsXHJcbiAgICAgICAgbGVmdDogMCxcclxuICAgICAgICByaWdodDogcG9wdXBTaXplLndpZHRoLFxyXG4gICAgICAgIGJvdHRvbTogcG9wdXBTaXplLmhlaWdodCxcclxuICAgICAgICB4OiAwLFxyXG4gICAgICAgIHk6IDAsXHJcbiAgICAgICAgdG9KU09OOiAoKSA9PiAoe30pLFxyXG4gICAgICB9IGFzIERPTVJlY3Q7XHJcblxyXG4gICAgICBjb25zdCB0YXJnZXRJbmZvID0gdGhpcy5wbGFjZW1lbnRJbmZvO1xyXG4gICAgICBsZXQgZmluYWxQbGFjZW1lbnQgPSB0YXJnZXRJbmZvLnBsYWNlbWVudDtcclxuICAgICAgLy8g5aeL57uI5L2/55So55So5oi35oyH5a6a55qEIHBvc2l0aW9u77yMYXV0b0FkanVzdCDlj6rosIPmlbQgcGxhY2VtZW5077yI5pa55ZCR77yJ77yM5LiN5pS55Y+Y5a+56b2Q5pa55byPXHJcbiAgICAgIGNvbnN0IGZpbmFsUG9zaXRpb24gPSB0YXJnZXRJbmZvLnBvc2l0aW9uO1xyXG5cclxuICAgICAgaWYgKHRoaXMuYXV0b0FkanVzdCkge1xyXG4gICAgICAgIGNvbnN0IG9wdGltYWwgPSB0aGlzLmNhbGN1bGF0ZU9wdGltYWxQbGFjZW1lbnQoXHJcbiAgICAgICAgICB0cmlnZ2VyUmVjdCxcclxuICAgICAgICAgIHBvcHVwUmVjdCxcclxuICAgICAgICAgIHZpZXdwb3J0V2lkdGgsXHJcbiAgICAgICAgICB2aWV3cG9ydEhlaWdodFxyXG4gICAgICAgICk7XHJcbiAgICAgICAgLy8gYXV0b0FkanVzdCDlj6rosIPmlbQgcGxhY2VtZW5077yI5LiK5LiL5bem5Y+z77yJ77yM5L+d5oyB55So5oi35oyH5a6a55qEIHBvc2l0aW9u77yI5a+56b2Q5pa55byP77yJXHJcbiAgICAgICAgZmluYWxQbGFjZW1lbnQgPSBvcHRpbWFsLnBsYWNlbWVudDtcclxuICAgICAgICAvLyBmaW5hbFBvc2l0aW9uIOS/neaMgeeUqOaIt+aMh+WumueahOWAvO+8jOS4jeaUueWPmFxyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLmFjdHVhbFBsYWNlbWVudCA9IGZpbmFsUGxhY2VtZW50O1xyXG4gICAgICB0aGlzLmFjdHVhbFBvc2l0aW9uID0gZmluYWxQb3NpdGlvbjtcclxuXHJcbiAgICAgIC8vIOiuoeeul+S9jee9ruWdkOagh++8iOS4jeS+nei1lkRPTe+8jOebtOaOpeiuoeeul++8iVxyXG4gICAgICBjb25zdCBwb3NpdGlvbiA9IHRoaXMuY2FsY3VsYXRlUG9zaXRpb25Db29yZGluYXRlcyhcclxuICAgICAgICB0cmlnZ2VyUmVjdCxcclxuICAgICAgICBmaW5hbFBsYWNlbWVudCxcclxuICAgICAgICBmaW5hbFBvc2l0aW9uLFxyXG4gICAgICAgIHBvcHVwU2l6ZVxyXG4gICAgICApO1xyXG5cclxuICAgICAgLy8g5YWI6K6+572u5omT5byA54q25oCB77yM5L2G5L+d5oyB6ZqQ6JeP77yIcG9zaXRpb25pbmcgPSB5ZXPvvIlcclxuICAgICAgLy8g5rOo5oSP77ya5YWI6K6+572uIHBvc2l0aW9uaW5nID0geWVz77yM5YaN6K6+572uIG9wZW5lZCA9IHllc++8jOehruS/neW8ueeql+WcqOS9jee9ruiuoeeul+WujOaIkOWJjeWni+e7iOmakOiXj1xyXG4gICAgICB0aGlzLnBvc2l0aW9uaW5nID0gXCJ5ZXNcIjtcclxuICAgICAgdGhpcy5vcGVuZWQgPSBcInllc1wiO1xyXG4gICAgICB0aGlzLm9wZW5DaGFuZ2UuZW1pdCh0cnVlKTtcclxuICAgICAgdGhpcy5yZWYubWFya0ZvckNoZWNrKCk7XHJcblxyXG4gICAgICAvLyDlvLrliLbmm7TmlrDop4blm77vvIznoa7kv51ET03lt7Lmm7TmlrDvvIzkvYblvLnnqpfku43nhLbpmpDol4/vvIjlm6DkuLogcG9zaXRpb25pbmcgPSB5ZXPvvIlcclxuICAgICAgdGhpcy5yZWYuZGV0ZWN0Q2hhbmdlcygpO1xyXG5cclxuICAgICAgLy8g6K6+572u5L2N572u55qE5Ye95pWwXHJcbiAgICAgIGNvbnN0IHNldFBvc2l0aW9uID0gKCkgPT4ge1xyXG4gICAgICAgIGlmICh0aGlzLnBvcHVwRWxlbWVudCAmJiB0aGlzLnBvcHVwRWxlbWVudC5uYXRpdmVFbGVtZW50KSB7XHJcbiAgICAgICAgICBjb25zdCBwb3B1cEVsID0gdGhpcy5wb3B1cEVsZW1lbnQubmF0aXZlRWxlbWVudDtcclxuXHJcbiAgICAgICAgICAvLyDnq4vljbPorr7nva7lsLrlr7jlkozkvY3nva5cclxuICAgICAgICAgIHBvcHVwRWwuc3R5bGUud2lkdGggPSB0aGlzLl93aWR0aCArIFwicHhcIjtcclxuICAgICAgICAgIHBvcHVwRWwuc3R5bGUuaGVpZ2h0ID0gdGhpcy5faGVpZ2h0ICsgXCJweFwiO1xyXG4gICAgICAgICAgcG9wdXBFbC5zdHlsZS5taW5XaWR0aCA9IHRoaXMuX3dpZHRoICsgXCJweFwiO1xyXG4gICAgICAgICAgcG9wdXBFbC5zdHlsZS5tYXhXaWR0aCA9IHRoaXMuX3dpZHRoICsgXCJweFwiO1xyXG4gICAgICAgICAgcG9wdXBFbC5zdHlsZS5taW5IZWlnaHQgPSB0aGlzLl9oZWlnaHQgKyBcInB4XCI7XHJcbiAgICAgICAgICBwb3B1cEVsLnN0eWxlLm1heEhlaWdodCA9IHRoaXMuX2hlaWdodCArIFwicHhcIjtcclxuICAgICAgICAgIHBvcHVwRWwuc3R5bGUudG9wID0gcG9zaXRpb24udG9wO1xyXG4gICAgICAgICAgcG9wdXBFbC5zdHlsZS5sZWZ0ID0gcG9zaXRpb24ubGVmdDtcclxuICAgICAgICAgIHBvcHVwRWwuc3R5bGUudHJhbnNmb3JtID0gYHRyYW5zbGF0ZSgke3Bvc2l0aW9uLnRyYW5zbGF0ZVh9LCAke3Bvc2l0aW9uLnRyYW5zbGF0ZVl9KWA7XHJcblxyXG4gICAgICAgICAgLy8g5by65Yi25ZCM5q2l5bqU55So5qC35byP77yM56Gu5L+d5L2N572u5bey6K6+572uXHJcbiAgICAgICAgICBwb3B1cEVsLm9mZnNldEhlaWdodDtcclxuXHJcbiAgICAgICAgICAvLyDkvY3nva7orr7nva7lrozmiJDlkI7vvIzlho3mmL7npLrlvLnnqpfvvIjorr7nva4gcG9zaXRpb25pbmcgPSBub++8iVxyXG4gICAgICAgICAgLy8g5L2/55SoIHJlcXVlc3RBbmltYXRpb25GcmFtZSDnoa7kv53moLflvI/lt7LlupTnlKhcclxuICAgICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMucG9zaXRpb25pbmcgPSBcIm5vXCI7XHJcbiAgICAgICAgICAgIHRoaXMucmVmLm1hcmtGb3JDaGVjaygpO1xyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9O1xyXG5cclxuICAgICAgLy8g5aaC5p6c5YWD57Sg5bey57uP5a2Y5Zyo77yM56uL5Y2z6K6+572u5L2N572uXHJcbiAgICAgIGlmICh0aGlzLnBvcHVwRWxlbWVudCAmJiB0aGlzLnBvcHVwRWxlbWVudC5uYXRpdmVFbGVtZW50KSB7XHJcbiAgICAgICAgc2V0UG9zaXRpb24oKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICAvLyDlpoLmnpzlhYPntKDov5jkuI3lrZjlnKjvvIznrYnlvoXmuLLmn5PlkI7lho3orr7nva7kvY3nva5cclxuICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xyXG4gICAgICAgICAgaWYgKHRoaXMucG9wdXBFbGVtZW50ICYmIHRoaXMucG9wdXBFbGVtZW50Lm5hdGl2ZUVsZW1lbnQpIHtcclxuICAgICAgICAgICAgc2V0UG9zaXRpb24oKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgLy8g5rKh5pyJ5Zu65a6a5bC65a+477yM6ZyA6KaB562J5b6FRE9N5riy5p+TXHJcbiAgICAgIHRoaXMucG9zaXRpb25pbmcgPSBcInllc1wiO1xyXG4gICAgICB0aGlzLnJlZi5tYXJrRm9yQ2hlY2soKTtcclxuXHJcbiAgICAgIC8vIOeri+WNs+W8uuWItuabtOaWsOinhuWbvu+8jOehruS/nURPTeW3suabtOaWsFxyXG4gICAgICB0aGlzLnJlZi5kZXRlY3RDaGFuZ2VzKCk7XHJcblxyXG4gICAgICAvLyDkvb/nlKggcmVxdWVzdEFuaW1hdGlvbkZyYW1lIOehruS/neWcqOa1j+iniOWZqOa4suafk+S5i+WJjeabtOaWsOS9jee9rlxyXG4gICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xyXG4gICAgICAgIC8vIOehruS/neWFg+e0oOW3sua4suafk+W5tuiOt+WPluWwuuWvuFxyXG4gICAgICAgIGlmICh0aGlzLnBvcHVwRWxlbWVudCAmJiB0aGlzLnBvcHVwRWxlbWVudC5uYXRpdmVFbGVtZW50KSB7XHJcbiAgICAgICAgICAvLyDlvLrliLbph43mlrDorqHnrpfluIPlsYDvvIznoa7kv53lhYPntKDlsLrlr7jlt7LorqHnrpdcclxuICAgICAgICAgIHRoaXMucG9wdXBFbGVtZW50Lm5hdGl2ZUVsZW1lbnQub2Zmc2V0SGVpZ2h0O1xyXG5cclxuICAgICAgICAgIC8vIOiuoeeul+W5tuiuvue9ruS9jee9rlxyXG4gICAgICAgICAgdGhpcy51cGRhdGVQb3B1cFBvc2l0aW9uKCk7XHJcblxyXG4gICAgICAgICAgLy8g5L2N572u6K6+572u5a6M5oiQ5ZCO77yM56e76Zmk5a6a5L2N54q25oCB77yM5pi+56S65by556qXXHJcbiAgICAgICAgICB0aGlzLnBvc2l0aW9uaW5nID0gXCJub1wiO1xyXG4gICAgICAgICAgdGhpcy5yZWYubWFya0ZvckNoZWNrKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIHRoaXMub25DbGlja091dHNpZGUpO1xyXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIiwgdGhpcy5vbldpbmRvd1Njcm9sbCwgdHJ1ZSk7XHJcbiAgfVxyXG5cclxuICBjbG9zZSgpIHtcclxuICAgIGlmICh0aGlzLm9wZW5lZCA9PT0gXCJub1wiKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLm9wZW5lZCA9IFwibm9cIjtcclxuICAgIHRoaXMucG9zaXRpb25pbmcgPSBcIm5vXCI7XHJcbiAgICB0aGlzLm9wZW5DaGFuZ2UuZW1pdChmYWxzZSk7XHJcbiAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsIHRoaXMub25DbGlja091dHNpZGUpO1xyXG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIiwgdGhpcy5vbldpbmRvd1Njcm9sbCwgdHJ1ZSk7XHJcbiAgICB0aGlzLnJlZi5tYXJrRm9yQ2hlY2soKTtcclxuICB9XHJcblxyXG4gIHRvZ2dsZSgpIHtcclxuICAgIGlmICh0aGlzLm9wZW5lZCA9PT0gXCJ5ZXNcIikge1xyXG4gICAgICB0aGlzLmNsb3NlKCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLm9wZW4oKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIG9uQ2xpY2tUcmlnZ2VyKGV2ZW50OiBNb3VzZUV2ZW50KSB7XHJcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgIHRoaXMudG9nZ2xlKCk7XHJcbiAgfVxyXG5cclxuICBvbkNsaWNrT3V0c2lkZSA9IChldmVudDogTW91c2VFdmVudCkgPT4ge1xyXG4gICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IGFzIEVsZW1lbnQ7XHJcbiAgICBjb25zdCBpc0NsaWNrT25UcmlnZ2VyID1cclxuICAgICAgdGhpcy5jdXJyZW50VHJpZ2dlckVsZW1lbnQgJiYgdGhpcy5jdXJyZW50VHJpZ2dlckVsZW1lbnQuY29udGFpbnModGFyZ2V0KTtcclxuICAgIGNvbnN0IGlzQ2xpY2tPblBvcHVwID1cclxuICAgICAgdGhpcy5wb3B1cEVsZW1lbnQgJiZcclxuICAgICAgdGhpcy5wb3B1cEVsZW1lbnQubmF0aXZlRWxlbWVudCAmJlxyXG4gICAgICB0aGlzLnBvcHVwRWxlbWVudC5uYXRpdmVFbGVtZW50LmNvbnRhaW5zKHRhcmdldCk7XHJcblxyXG4gICAgaWYgKCFpc0NsaWNrT25UcmlnZ2VyICYmICFpc0NsaWNrT25Qb3B1cCkge1xyXG4gICAgICB0aGlzLmNsb3NlKCk7XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgb25XaW5kb3dTY3JvbGwgPSAoZXZlbnQ6IEV2ZW50KSA9PiB7XHJcbiAgICBpZiAodGhpcy5vcGVuZWQgPT09IFwieWVzXCIpIHtcclxuICAgICAgLy8g5qOA5p+l5rua5Yqo5piv5ZCm5Y+R55Sf5Zyo5by556qX5YaF6YOoXHJcbiAgICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBFbGVtZW50O1xyXG4gICAgICBjb25zdCBpc1Njcm9sbE9uUG9wdXAgPVxyXG4gICAgICAgIHRoaXMucG9wdXBFbGVtZW50ICYmXHJcbiAgICAgICAgdGhpcy5wb3B1cEVsZW1lbnQubmF0aXZlRWxlbWVudCAmJlxyXG4gICAgICAgIHRoaXMucG9wdXBFbGVtZW50Lm5hdGl2ZUVsZW1lbnQuY29udGFpbnModGFyZ2V0KTtcclxuXHJcbiAgICAgIC8vIOWmguaenOa7muWKqOWPkeeUn+WcqOW8ueeql+WGhemDqO+8jOS4jeabtOaWsOS9jee9ru+8iOmBv+WFjeS4jeW/heimgeeahOiuoeeul++8iVxyXG4gICAgICAvLyDlpoLmnpzmu5rliqjlj5HnlJ/lnKjlpJbpg6jvvIzmm7TmlrDkvY3nva7vvIjlm6DkuLrop6blj5HlhYPntKDkvY3nva7lj6/og73mlLnlj5jvvIlcclxuICAgICAgaWYgKCFpc1Njcm9sbE9uUG9wdXApIHtcclxuICAgICAgICB0aGlzLnVwZGF0ZVBvcHVwUG9zaXRpb24oKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH07XHJcblxyXG4gIC8vIOWkhOeQhuW8ueeql+WGhemDqOeahOa7mui9ruS6i+S7tlxyXG4gIG9uUG9wdXBXaGVlbChldmVudDogV2hlZWxFdmVudCkge1xyXG4gICAgLy8g6Zi75q2i5rua6L2u5LqL5Lu25YaS5rOh77yM6YG/5YWN6Kem5Y+R5aSW6YOo5rua5Yqo5aSE55CGXHJcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuICB9XHJcblxyXG4gIC8vIOWkhOeQhuW8ueeql+WGhemDqOeahOa7muWKqOS6i+S7tlxyXG4gIG9uUG9wdXBTY3JvbGwoZXZlbnQ6IEV2ZW50KSB7XHJcbiAgICAvLyDpmLvmraLmu5rliqjkuovku7blhpLms6HvvIzpgb/lhY3op6blj5HlpJbpg6jmu5rliqjlpITnkIZcclxuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gIH1cclxuXHJcbiAgLy8g6K6h566X5bm26K6+572u5L2N572u77yI5pSv5oyB5Zu65a6a5bC65a+477yM5Y+v5Zyo5omT5byA5YmN6LCD55So77yJXHJcbiAgcHJpdmF0ZSBjYWxjdWxhdGVBbmRTZXRQb3NpdGlvbigpIHtcclxuICAgIGlmICghdGhpcy5jdXJyZW50VHJpZ2dlckVsZW1lbnQpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHRyaWdnZXJSZWN0ID0gdGhpcy5jdXJyZW50VHJpZ2dlckVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgICBjb25zdCB2aWV3cG9ydFdpZHRoID0gd2luZG93LmlubmVyV2lkdGg7XHJcbiAgICBjb25zdCB2aWV3cG9ydEhlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodDtcclxuXHJcbiAgICAvLyDojrflj5blvLnnqpflsLrlr7jvvIjkvJjlhYjkvb/nlKjlm7rlrprlsLrlr7jvvIlcclxuICAgIGNvbnN0IHBvcHVwU2l6ZSA9IHtcclxuICAgICAgd2lkdGg6XHJcbiAgICAgICAgdGhpcy5fd2lkdGggIT09IG51bGxcclxuICAgICAgICAgID8gdGhpcy5fd2lkdGhcclxuICAgICAgICAgIDogdGhpcy5wb3B1cEVsZW1lbnQgJiYgdGhpcy5wb3B1cEVsZW1lbnQubmF0aXZlRWxlbWVudFxyXG4gICAgICAgICAgPyB0aGlzLnBvcHVwRWxlbWVudC5uYXRpdmVFbGVtZW50Lm9mZnNldFdpZHRoXHJcbiAgICAgICAgICA6IDMwMCxcclxuICAgICAgaGVpZ2h0OlxyXG4gICAgICAgIHRoaXMuX2hlaWdodCAhPT0gbnVsbFxyXG4gICAgICAgICAgPyB0aGlzLl9oZWlnaHRcclxuICAgICAgICAgIDogdGhpcy5wb3B1cEVsZW1lbnQgJiYgdGhpcy5wb3B1cEVsZW1lbnQubmF0aXZlRWxlbWVudFxyXG4gICAgICAgICAgPyB0aGlzLnBvcHVwRWxlbWVudC5uYXRpdmVFbGVtZW50Lm9mZnNldEhlaWdodFxyXG4gICAgICAgICAgOiAyMDAsXHJcbiAgICB9O1xyXG5cclxuICAgIC8vIOWIm+W7uuiZmuaLn+eahCBwb3B1cFJlY3TvvIjnlKjkuo7orqHnrpfvvIlcclxuICAgIGNvbnN0IHBvcHVwUmVjdDogRE9NUmVjdCA9IHtcclxuICAgICAgd2lkdGg6IHBvcHVwU2l6ZS53aWR0aCxcclxuICAgICAgaGVpZ2h0OiBwb3B1cFNpemUuaGVpZ2h0LFxyXG4gICAgICB0b3A6IDAsXHJcbiAgICAgIGxlZnQ6IDAsXHJcbiAgICAgIHJpZ2h0OiBwb3B1cFNpemUud2lkdGgsXHJcbiAgICAgIGJvdHRvbTogcG9wdXBTaXplLmhlaWdodCxcclxuICAgICAgeDogMCxcclxuICAgICAgeTogMCxcclxuICAgICAgdG9KU09OOiAoKSA9PiAoe30pLFxyXG4gICAgfSBhcyBET01SZWN0O1xyXG5cclxuICAgIC8vIOiOt+WPluebruagh+S9jee9ruS/oeaBr1xyXG4gICAgY29uc3QgdGFyZ2V0SW5mbyA9IHRoaXMucGxhY2VtZW50SW5mbztcclxuICAgIGxldCBmaW5hbFBsYWNlbWVudCA9IHRhcmdldEluZm8ucGxhY2VtZW50O1xyXG4gICAgLy8g5aeL57uI5L2/55So55So5oi35oyH5a6a55qEIHBvc2l0aW9u77yMYXV0b0FkanVzdCDlj6rosIPmlbQgcGxhY2VtZW5077yI5pa55ZCR77yJ77yM5LiN5pS55Y+Y5a+56b2Q5pa55byPXHJcbiAgICBjb25zdCBmaW5hbFBvc2l0aW9uID0gdGFyZ2V0SW5mby5wb3NpdGlvbjtcclxuXHJcbiAgICBpZiAodGhpcy5hdXRvQWRqdXN0KSB7XHJcbiAgICAgIGNvbnN0IG9wdGltYWwgPSB0aGlzLmNhbGN1bGF0ZU9wdGltYWxQbGFjZW1lbnQoXHJcbiAgICAgICAgdHJpZ2dlclJlY3QsXHJcbiAgICAgICAgcG9wdXBSZWN0LFxyXG4gICAgICAgIHZpZXdwb3J0V2lkdGgsXHJcbiAgICAgICAgdmlld3BvcnRIZWlnaHRcclxuICAgICAgKTtcclxuICAgICAgLy8gYXV0b0FkanVzdCDlj6rosIPmlbQgcGxhY2VtZW5077yI5LiK5LiL5bem5Y+z77yJ77yM5L+d5oyB55So5oi35oyH5a6a55qEIHBvc2l0aW9u77yI5a+56b2Q5pa55byP77yJXHJcbiAgICAgIGZpbmFsUGxhY2VtZW50ID0gb3B0aW1hbC5wbGFjZW1lbnQ7XHJcbiAgICAgIC8vIGZpbmFsUG9zaXRpb24g5L+d5oyB55So5oi35oyH5a6a55qE5YC877yM5LiN5pS55Y+YXHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5hY3R1YWxQbGFjZW1lbnQgPSBmaW5hbFBsYWNlbWVudDtcclxuICAgIHRoaXMuYWN0dWFsUG9zaXRpb24gPSBmaW5hbFBvc2l0aW9uO1xyXG5cclxuICAgIC8vIOeri+WNs+iuvue9ruS9jee9ru+8iOWNs+S9v+WFg+e0oOi/mOayoeWujOWFqOa4suafk++8jOS5n+imgeWFiOiuvue9ruS9jee9ru+8iVxyXG4gICAgaWYgKHRoaXMucG9wdXBFbGVtZW50ICYmIHRoaXMucG9wdXBFbGVtZW50Lm5hdGl2ZUVsZW1lbnQpIHtcclxuICAgICAgdGhpcy5zZXRQb3B1cFBvc2l0aW9uKFxyXG4gICAgICAgIHRyaWdnZXJSZWN0LFxyXG4gICAgICAgIHBvcHVwUmVjdCxcclxuICAgICAgICBmaW5hbFBsYWNlbWVudCxcclxuICAgICAgICBmaW5hbFBvc2l0aW9uLFxyXG4gICAgICAgIHBvcHVwU2l6ZVxyXG4gICAgICApO1xyXG4gICAgICAvLyDlvLrliLblupTnlKjmoLflvI/vvIznoa7kv53kvY3nva7nq4vljbPnlJ/mlYhcclxuICAgICAgdGhpcy5yZWYuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgLy8g5aaC5p6c5YWD57Sg6L+Y5LiN5a2Y5Zyo77yM5bu26L+f6K6+572u5L2N572uXHJcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgIGlmICh0aGlzLnBvcHVwRWxlbWVudCAmJiB0aGlzLnBvcHVwRWxlbWVudC5uYXRpdmVFbGVtZW50KSB7XHJcbiAgICAgICAgICB0aGlzLnNldFBvcHVwUG9zaXRpb24oXHJcbiAgICAgICAgICAgIHRyaWdnZXJSZWN0LFxyXG4gICAgICAgICAgICBwb3B1cFJlY3QsXHJcbiAgICAgICAgICAgIGZpbmFsUGxhY2VtZW50LFxyXG4gICAgICAgICAgICBmaW5hbFBvc2l0aW9uLFxyXG4gICAgICAgICAgICBwb3B1cFNpemVcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICB0aGlzLnJlZi5kZXRlY3RDaGFuZ2VzKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9LCAwKTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnJlZi5tYXJrRm9yQ2hlY2soKTtcclxuICB9XHJcblxyXG4gIHVwZGF0ZVBvcHVwUG9zaXRpb24oKSB7XHJcbiAgICBpZiAoXHJcbiAgICAgICF0aGlzLmN1cnJlbnRUcmlnZ2VyRWxlbWVudCB8fFxyXG4gICAgICAhdGhpcy5wb3B1cEVsZW1lbnQgfHxcclxuICAgICAgIXRoaXMucG9wdXBFbGVtZW50Lm5hdGl2ZUVsZW1lbnRcclxuICAgICkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgLy8g5aaC5p6c5o+Q5L6b5LqG5Zu65a6a5bC65a+477yM5L2/55So5Zu65a6a5bC65a+46K6h566XXHJcbiAgICBpZiAodGhpcy5fd2lkdGggIT09IG51bGwgJiYgdGhpcy5faGVpZ2h0ICE9PSBudWxsKSB7XHJcbiAgICAgIHRoaXMuY2FsY3VsYXRlQW5kU2V0UG9zaXRpb24oKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHRyaWdnZXJSZWN0ID0gdGhpcy5jdXJyZW50VHJpZ2dlckVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgICBjb25zdCBwb3B1cFJlY3QgPSB0aGlzLnBvcHVwRWxlbWVudC5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgY29uc3Qgdmlld3BvcnRXaWR0aCA9IHdpbmRvdy5pbm5lcldpZHRoO1xyXG4gICAgY29uc3Qgdmlld3BvcnRIZWlnaHQgPSB3aW5kb3cuaW5uZXJIZWlnaHQ7XHJcblxyXG4gICAgLy8g6I635Y+W55uu5qCH5L2N572u5L+h5oGvXHJcbiAgICBjb25zdCB0YXJnZXRJbmZvID0gdGhpcy5wbGFjZW1lbnRJbmZvO1xyXG4gICAgbGV0IGZpbmFsUGxhY2VtZW50ID0gdGFyZ2V0SW5mby5wbGFjZW1lbnQ7XHJcbiAgICAvLyDlp4vnu4jkvb/nlKjnlKjmiLfmjIflrprnmoQgcG9zaXRpb27vvIxhdXRvQWRqdXN0IOWPquiwg+aVtCBwbGFjZW1lbnTvvIjmlrnlkJHvvInvvIzkuI3mlLnlj5jlr7npvZDmlrnlvI9cclxuICAgIGNvbnN0IGZpbmFsUG9zaXRpb24gPSB0YXJnZXRJbmZvLnBvc2l0aW9uO1xyXG5cclxuICAgIGlmICh0aGlzLmF1dG9BZGp1c3QpIHtcclxuICAgICAgY29uc3Qgb3B0aW1hbCA9IHRoaXMuY2FsY3VsYXRlT3B0aW1hbFBsYWNlbWVudChcclxuICAgICAgICB0cmlnZ2VyUmVjdCxcclxuICAgICAgICBwb3B1cFJlY3QsXHJcbiAgICAgICAgdmlld3BvcnRXaWR0aCxcclxuICAgICAgICB2aWV3cG9ydEhlaWdodFxyXG4gICAgICApO1xyXG4gICAgICAvLyBhdXRvQWRqdXN0IOWPquiwg+aVtCBwbGFjZW1lbnTvvIjkuIrkuIvlt6blj7PvvInvvIzkv53mjIHnlKjmiLfmjIflrprnmoQgcG9zaXRpb27vvIjlr7npvZDmlrnlvI/vvIlcclxuICAgICAgZmluYWxQbGFjZW1lbnQgPSBvcHRpbWFsLnBsYWNlbWVudDtcclxuICAgICAgLy8gZmluYWxQb3NpdGlvbiDkv53mjIHnlKjmiLfmjIflrprnmoTlgLzvvIzkuI3mlLnlj5hcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmFjdHVhbFBsYWNlbWVudCA9IGZpbmFsUGxhY2VtZW50O1xyXG4gICAgdGhpcy5hY3R1YWxQb3NpdGlvbiA9IGZpbmFsUG9zaXRpb247XHJcbiAgICB0aGlzLnNldFBvcHVwUG9zaXRpb24oXHJcbiAgICAgIHRyaWdnZXJSZWN0LFxyXG4gICAgICBwb3B1cFJlY3QsXHJcbiAgICAgIGZpbmFsUGxhY2VtZW50LFxyXG4gICAgICBmaW5hbFBvc2l0aW9uXHJcbiAgICApO1xyXG4gICAgdGhpcy5yZWYubWFya0ZvckNoZWNrKCk7XHJcbiAgfVxyXG5cclxuICBjYWxjdWxhdGVPcHRpbWFsUGxhY2VtZW50KFxyXG4gICAgdHJpZ2dlclJlY3Q6IERPTVJlY3QgfCBDbGllbnRSZWN0LFxyXG4gICAgcG9wdXBSZWN0OiBET01SZWN0IHwgQ2xpZW50UmVjdCxcclxuICAgIHZpZXdwb3J0V2lkdGg6IG51bWJlcixcclxuICAgIHZpZXdwb3J0SGVpZ2h0OiBudW1iZXJcclxuICApOiB7XHJcbiAgICBwbGFjZW1lbnQ6IFwidG9wXCIgfCBcImxlZnRcIiB8IFwicmlnaHRcIiB8IFwiYm90dG9tXCI7XHJcbiAgICBwb3NpdGlvbjogXCJzdGFydFwiIHwgXCJjZW50ZXJcIiB8IFwiZW5kXCI7XHJcbiAgfSB7XHJcbiAgICBjb25zdCB0YXJnZXRJbmZvID0gdGhpcy5wbGFjZW1lbnRJbmZvO1xyXG4gICAgY29uc3QgcHJlZmVycmVkID0gdGFyZ2V0SW5mby5wbGFjZW1lbnQ7XHJcbiAgICBjb25zdCBwcmVmZXJyZWRQb3NpdGlvbiA9IHRhcmdldEluZm8ucG9zaXRpb247XHJcblxyXG4gICAgY29uc3Qgc3BhY2UgPSB7XHJcbiAgICAgIHRvcDogdHJpZ2dlclJlY3QudG9wLFxyXG4gICAgICBib3R0b206IHZpZXdwb3J0SGVpZ2h0IC0gdHJpZ2dlclJlY3QuYm90dG9tLFxyXG4gICAgICBsZWZ0OiB0cmlnZ2VyUmVjdC5sZWZ0LFxyXG4gICAgICByaWdodDogdmlld3BvcnRXaWR0aCAtIHRyaWdnZXJSZWN0LnJpZ2h0LFxyXG4gICAgfTtcclxuXHJcbiAgICBjb25zdCBwb3B1cFNpemUgPSB7XHJcbiAgICAgIHdpZHRoOiBwb3B1cFJlY3Qud2lkdGggfHwgMzAwLCAvLyDpu5jorqTlrr3luqbvvIzlpoLmnpzov5jmsqHmnInmuLLmn5NcclxuICAgICAgaGVpZ2h0OiBwb3B1cFJlY3QuaGVpZ2h0IHx8IDIwMCwgLy8g6buY6K6k6auY5bqmXHJcbiAgICB9O1xyXG5cclxuICAgIC8vIOajgOafpemmlumAieS9jee9ruaYr+WQpuaciei2s+Wkn+epuumXtFxyXG4gICAgY29uc3QgaGFzRW5vdWdoU3BhY2UgPSAocGxhY2VtZW50OiBcInRvcFwiIHwgXCJsZWZ0XCIgfCBcInJpZ2h0XCIgfCBcImJvdHRvbVwiKSA9PiB7XHJcbiAgICAgIHN3aXRjaCAocGxhY2VtZW50KSB7XHJcbiAgICAgICAgY2FzZSBcInRvcFwiOlxyXG4gICAgICAgICAgcmV0dXJuIHNwYWNlLnRvcCA+PSBwb3B1cFNpemUuaGVpZ2h0ICsgdGhpcy5vZmZzZXQ7XHJcbiAgICAgICAgY2FzZSBcImJvdHRvbVwiOlxyXG4gICAgICAgICAgcmV0dXJuIHNwYWNlLmJvdHRvbSA+PSBwb3B1cFNpemUuaGVpZ2h0ICsgdGhpcy5vZmZzZXQ7XHJcbiAgICAgICAgY2FzZSBcImxlZnRcIjpcclxuICAgICAgICAgIHJldHVybiBzcGFjZS5sZWZ0ID49IHBvcHVwU2l6ZS53aWR0aCArIHRoaXMub2Zmc2V0O1xyXG4gICAgICAgIGNhc2UgXCJyaWdodFwiOlxyXG4gICAgICAgICAgcmV0dXJuIHNwYWNlLnJpZ2h0ID49IHBvcHVwU2l6ZS53aWR0aCArIHRoaXMub2Zmc2V0O1xyXG4gICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIC8vIOajgOafpeaMh+WumuS9jee9ruaYr+WQpuaciei2s+Wkn+epuumXtFxyXG4gICAgY29uc3QgY2hlY2tQb3NpdGlvblNwYWNlID0gKFxyXG4gICAgICBwbGFjZW1lbnQ6IFwidG9wXCIgfCBcImxlZnRcIiB8IFwicmlnaHRcIiB8IFwiYm90dG9tXCIsXHJcbiAgICAgIHBvc2l0aW9uOiBcInN0YXJ0XCIgfCBcImNlbnRlclwiIHwgXCJlbmRcIlxyXG4gICAgKTogYm9vbGVhbiA9PiB7XHJcbiAgICAgIGlmIChwbGFjZW1lbnQgPT09IFwidG9wXCIgfHwgcGxhY2VtZW50ID09PSBcImJvdHRvbVwiKSB7XHJcbiAgICAgICAgLy8g5a+55LqO5LiK5LiL5L2N572u77yM5qOA5p+l5rC05bmz5a+56b2Q56m66Ze0XHJcbiAgICAgICAgY29uc3QgcG9wdXBXaWR0aCA9IHBvcHVwU2l6ZS53aWR0aDtcclxuICAgICAgICBjb25zdCBzcGFjZUxlZnQgPSB0cmlnZ2VyUmVjdC5sZWZ0O1xyXG4gICAgICAgIGNvbnN0IHNwYWNlUmlnaHQgPSB2aWV3cG9ydFdpZHRoIC0gdHJpZ2dlclJlY3QucmlnaHQ7XHJcblxyXG4gICAgICAgIGlmIChwb3NpdGlvbiA9PT0gXCJjZW50ZXJcIikge1xyXG4gICAgICAgICAgcmV0dXJuIHNwYWNlTGVmdCA+PSBwb3B1cFdpZHRoIC8gMiAmJiBzcGFjZVJpZ2h0ID49IHBvcHVwV2lkdGggLyAyO1xyXG4gICAgICAgIH0gZWxzZSBpZiAocG9zaXRpb24gPT09IFwic3RhcnRcIikge1xyXG4gICAgICAgICAgcmV0dXJuIHNwYWNlTGVmdCA+PSBwb3B1cFdpZHRoO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAvLyBlbmRcclxuICAgICAgICAgIHJldHVybiBzcGFjZVJpZ2h0ID49IHBvcHVwV2lkdGg7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIC8vIOWvueS6juW3puWPs+S9jee9ru+8jOajgOafpeWeguebtOWvuem9kOepuumXtFxyXG4gICAgICAgIGNvbnN0IHBvcHVwSGVpZ2h0ID0gcG9wdXBTaXplLmhlaWdodDtcclxuICAgICAgICBjb25zdCBzcGFjZVRvcCA9IHRyaWdnZXJSZWN0LnRvcDtcclxuICAgICAgICBjb25zdCBzcGFjZUJvdHRvbSA9IHZpZXdwb3J0SGVpZ2h0IC0gdHJpZ2dlclJlY3QuYm90dG9tO1xyXG5cclxuICAgICAgICBpZiAocG9zaXRpb24gPT09IFwiY2VudGVyXCIpIHtcclxuICAgICAgICAgIHJldHVybiBzcGFjZVRvcCA+PSBwb3B1cEhlaWdodCAvIDIgJiYgc3BhY2VCb3R0b20gPj0gcG9wdXBIZWlnaHQgLyAyO1xyXG4gICAgICAgIH0gZWxzZSBpZiAocG9zaXRpb24gPT09IFwic3RhcnRcIikge1xyXG4gICAgICAgICAgcmV0dXJuIHNwYWNlVG9wID49IHBvcHVwSGVpZ2h0O1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAvLyBlbmRcclxuICAgICAgICAgIHJldHVybiBzcGFjZUJvdHRvbSA+PSBwb3B1cEhlaWdodDtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgLy8g6K6h566X5L2N572u5piv5ZCm5ZCI6YCC77yI6ICD6JmR5rC05bmzL+WeguebtOWvuem9kO+8iVxyXG4gICAgY29uc3QgY2FsY3VsYXRlUG9zaXRpb24gPSAoXHJcbiAgICAgIHBsYWNlbWVudDogXCJ0b3BcIiB8IFwibGVmdFwiIHwgXCJyaWdodFwiIHwgXCJib3R0b21cIlxyXG4gICAgKTogXCJzdGFydFwiIHwgXCJjZW50ZXJcIiB8IFwiZW5kXCIgPT4ge1xyXG4gICAgICBpZiAocGxhY2VtZW50ID09PSBcInRvcFwiIHx8IHBsYWNlbWVudCA9PT0gXCJib3R0b21cIikge1xyXG4gICAgICAgIC8vIOWvueS6juS4iuS4i+S9jee9ru+8jOajgOafpeawtOW5s+Wvuem9kFxyXG4gICAgICAgIGNvbnN0IHBvcHVwV2lkdGggPSBwb3B1cFNpemUud2lkdGg7XHJcbiAgICAgICAgY29uc3Qgc3BhY2VMZWZ0ID0gdHJpZ2dlclJlY3QubGVmdDtcclxuICAgICAgICBjb25zdCBzcGFjZVJpZ2h0ID0gdmlld3BvcnRXaWR0aCAtIHRyaWdnZXJSZWN0LnJpZ2h0O1xyXG5cclxuICAgICAgICAvLyDkvJjlhYjlsJ3or5Xkvb/nlKjnlKjmiLfmjIflrprnmoRwb3NpdGlvblxyXG4gICAgICAgIGlmIChjaGVja1Bvc2l0aW9uU3BhY2UocGxhY2VtZW50LCBwcmVmZXJyZWRQb3NpdGlvbikpIHtcclxuICAgICAgICAgIHJldHVybiBwcmVmZXJyZWRQb3NpdGlvbjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIOWmguaenOS4reW/g+Wvuem9kOaciei2s+Wkn+epuumXtO+8jOS8mOWFiOS9v+eUqOS4reW/g1xyXG4gICAgICAgIGlmIChzcGFjZUxlZnQgPj0gcG9wdXBXaWR0aCAvIDIgJiYgc3BhY2VSaWdodCA+PSBwb3B1cFdpZHRoIC8gMikge1xyXG4gICAgICAgICAgcmV0dXJuIFwiY2VudGVyXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIOWmguaenOW3puS+p+epuumXtOS4jei2s++8jOS9v+eUqOWPs+Wvuem9kFxyXG4gICAgICAgIGlmIChzcGFjZUxlZnQgPCBwb3B1cFdpZHRoIC8gMikge1xyXG4gICAgICAgICAgcmV0dXJuIFwiZW5kXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIOWmguaenOWPs+S+p+epuumXtOS4jei2s++8jOS9v+eUqOW3puWvuem9kFxyXG4gICAgICAgIGlmIChzcGFjZVJpZ2h0IDwgcG9wdXBXaWR0aCAvIDIpIHtcclxuICAgICAgICAgIHJldHVybiBcInN0YXJ0XCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBwcmVmZXJyZWRQb3NpdGlvbjtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICAvLyDlr7nkuo7lt6blj7PkvY3nva7vvIzmo4Dmn6XlnoLnm7Tlr7npvZBcclxuICAgICAgICBjb25zdCBwb3B1cEhlaWdodCA9IHBvcHVwU2l6ZS5oZWlnaHQ7XHJcbiAgICAgICAgY29uc3Qgc3BhY2VUb3AgPSB0cmlnZ2VyUmVjdC50b3A7XHJcbiAgICAgICAgY29uc3Qgc3BhY2VCb3R0b20gPSB2aWV3cG9ydEhlaWdodCAtIHRyaWdnZXJSZWN0LmJvdHRvbTtcclxuXHJcbiAgICAgICAgLy8g5LyY5YWI5bCd6K+V5L2/55So55So5oi35oyH5a6a55qEcG9zaXRpb25cclxuICAgICAgICBpZiAoY2hlY2tQb3NpdGlvblNwYWNlKHBsYWNlbWVudCwgcHJlZmVycmVkUG9zaXRpb24pKSB7XHJcbiAgICAgICAgICByZXR1cm4gcHJlZmVycmVkUG9zaXRpb247XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyDlpoLmnpzkuK3lv4Plr7npvZDmnInotrPlpJ/nqbrpl7TvvIzkvJjlhYjkvb/nlKjkuK3lv4NcclxuICAgICAgICBpZiAoc3BhY2VUb3AgPj0gcG9wdXBIZWlnaHQgLyAyICYmIHNwYWNlQm90dG9tID49IHBvcHVwSGVpZ2h0IC8gMikge1xyXG4gICAgICAgICAgcmV0dXJuIFwiY2VudGVyXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIOWmguaenOS4iuaWueepuumXtOS4jei2s++8jOS9v+eUqOS4i+Wvuem9kFxyXG4gICAgICAgIGlmIChzcGFjZVRvcCA8IHBvcHVwSGVpZ2h0IC8gMikge1xyXG4gICAgICAgICAgcmV0dXJuIFwiZW5kXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIOWmguaenOS4i+aWueepuumXtOS4jei2s++8jOS9v+eUqOS4iuWvuem9kFxyXG4gICAgICAgIGlmIChzcGFjZUJvdHRvbSA8IHBvcHVwSGVpZ2h0IC8gMikge1xyXG4gICAgICAgICAgcmV0dXJuIFwic3RhcnRcIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHByZWZlcnJlZFBvc2l0aW9uO1xyXG4gICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIC8vIOWmguaenOmmlumAieS9jee9ruaciei2s+Wkn+epuumXtO+8jOS8mOWFiOS9v+eUqOeUqOaIt+aMh+WumueahHBvc2l0aW9uXHJcbiAgICBpZiAoaGFzRW5vdWdoU3BhY2UocHJlZmVycmVkKSkge1xyXG4gICAgICAvLyDljbPkvb/mjIflrprnmoRwb3NpdGlvbuepuumXtOS4jei2s++8jOS5n+WwvemHj+S/neaMgeeUqOaIt+aMh+WumueahHBvc2l0aW9uXHJcbiAgICAgIC8vIOi+ueeVjOe6puadn+mAu+i+keS8muWcqCBjYWxjdWxhdGVQb3NpdGlvbkNvb3JkaW5hdGVzIOS4reWkhOeQhuS9jee9ruiwg+aVtFxyXG4gICAgICAvLyDov5nmoLflj6/ku6Xkv53mjIHnlKjmiLfmnJ/mnJvnmoTlr7npvZDmlrnlvI9cclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBwbGFjZW1lbnQ6IHByZWZlcnJlZCxcclxuICAgICAgICBwb3NpdGlvbjogcHJlZmVycmVkUG9zaXRpb24sXHJcbiAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgLy8g5qC55o2u6aaW6YCJ5L2N572u6YCJ5oup5aSH6YCJ5L2N572uXHJcbiAgICBjb25zdCBhbHRlcm5hdGl2ZXM6IHtcclxuICAgICAgW2tleTogc3RyaW5nXTogKFwidG9wXCIgfCBcImxlZnRcIiB8IFwicmlnaHRcIiB8IFwiYm90dG9tXCIpW107XHJcbiAgICB9ID0ge1xyXG4gICAgICBib3R0b206IFtcInRvcFwiLCBcInJpZ2h0XCIsIFwibGVmdFwiXSxcclxuICAgICAgdG9wOiBbXCJib3R0b21cIiwgXCJyaWdodFwiLCBcImxlZnRcIl0sXHJcbiAgICAgIHJpZ2h0OiBbXCJsZWZ0XCIsIFwiYm90dG9tXCIsIFwidG9wXCJdLFxyXG4gICAgICBsZWZ0OiBbXCJyaWdodFwiLCBcImJvdHRvbVwiLCBcInRvcFwiXSxcclxuICAgIH07XHJcblxyXG4gICAgY29uc3QgYWx0TGlzdCA9IGFsdGVybmF0aXZlc1twcmVmZXJyZWRdIHx8IFtdO1xyXG5cclxuICAgIC8vIOWwneivleaJvuWIsOesrOS4gOS4quaciei2s+Wkn+epuumXtOeahOWkh+mAieS9jee9rlxyXG4gICAgZm9yIChjb25zdCBhbHQgb2YgYWx0TGlzdCkge1xyXG4gICAgICBpZiAoaGFzRW5vdWdoU3BhY2UoYWx0KSkge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICBwbGFjZW1lbnQ6IGFsdCxcclxuICAgICAgICAgIHBvc2l0aW9uOiBjYWxjdWxhdGVQb3NpdGlvbihhbHQpLFxyXG4gICAgICAgIH07XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyDlpoLmnpzpg73msqHmnInotrPlpJ/nqbrpl7TvvIzpgInmi6nnqbrpl7TmnIDlpKfnmoTkvY3nva5cclxuICAgIGNvbnN0IG1heFNwYWNlID0gTWF0aC5tYXgoc3BhY2UudG9wLCBzcGFjZS5ib3R0b20sIHNwYWNlLmxlZnQsIHNwYWNlLnJpZ2h0KTtcclxuICAgIGxldCBiZXN0UGxhY2VtZW50OiBcInRvcFwiIHwgXCJsZWZ0XCIgfCBcInJpZ2h0XCIgfCBcImJvdHRvbVwiO1xyXG4gICAgaWYgKG1heFNwYWNlID09PSBzcGFjZS50b3ApIGJlc3RQbGFjZW1lbnQgPSBcInRvcFwiO1xyXG4gICAgZWxzZSBpZiAobWF4U3BhY2UgPT09IHNwYWNlLmJvdHRvbSkgYmVzdFBsYWNlbWVudCA9IFwiYm90dG9tXCI7XHJcbiAgICBlbHNlIGlmIChtYXhTcGFjZSA9PT0gc3BhY2UubGVmdCkgYmVzdFBsYWNlbWVudCA9IFwibGVmdFwiO1xyXG4gICAgZWxzZSBiZXN0UGxhY2VtZW50ID0gXCJyaWdodFwiO1xyXG5cclxuICAgIHJldHVybiB7XHJcbiAgICAgIHBsYWNlbWVudDogYmVzdFBsYWNlbWVudCxcclxuICAgICAgcG9zaXRpb246IGNhbGN1bGF0ZVBvc2l0aW9uKGJlc3RQbGFjZW1lbnQpLFxyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIC8vIOiuoeeul+S9jee9ruWdkOagh++8iOe6r+iuoeeul++8jOS4jeS+nei1lkRPTe+8jOWMheWQq+i+ueeVjOe6puadn++8iVxyXG4gIC8vIOazqOaEj++8muW8ueeql+S9v+eUqCBwb3NpdGlvbjogZml4ZWTvvIzmiYDku6XlnZDmoIflupTor6XmmK/nm7jlr7nkuo7op4blj6PnmoTvvIzkuI3pnIDopoHliqDkuIrmu5rliqjlgY/np7tcclxuICBwcml2YXRlIGNhbGN1bGF0ZVBvc2l0aW9uQ29vcmRpbmF0ZXMoXHJcbiAgICB0cmlnZ2VyUmVjdDogRE9NUmVjdCB8IENsaWVudFJlY3QsXHJcbiAgICBwbGFjZW1lbnQ6IFwidG9wXCIgfCBcImxlZnRcIiB8IFwicmlnaHRcIiB8IFwiYm90dG9tXCIsXHJcbiAgICBwb3NpdGlvbjogXCJzdGFydFwiIHwgXCJjZW50ZXJcIiB8IFwiZW5kXCIsXHJcbiAgICBwb3B1cFNpemU6IHsgd2lkdGg6IG51bWJlcjsgaGVpZ2h0OiBudW1iZXIgfVxyXG4gICk6IHsgdG9wOiBzdHJpbmc7IGxlZnQ6IHN0cmluZzsgdHJhbnNsYXRlWDogc3RyaW5nOyB0cmFuc2xhdGVZOiBzdHJpbmcgfSB7XHJcbiAgICBjb25zdCB0cmlnZ2VyV2lkdGggPSB0cmlnZ2VyUmVjdC53aWR0aDtcclxuICAgIGNvbnN0IHRyaWdnZXJIZWlnaHQgPSB0cmlnZ2VyUmVjdC5oZWlnaHQ7XHJcbiAgICBjb25zdCB2aWV3cG9ydFdpZHRoID0gd2luZG93LmlubmVyV2lkdGg7XHJcbiAgICBjb25zdCB2aWV3cG9ydEhlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodDtcclxuXHJcbiAgICBsZXQgdG9wID0gMDtcclxuICAgIGxldCBsZWZ0ID0gMDtcclxuICAgIGxldCB0cmFuc2xhdGVYID0gXCIwXCI7XHJcbiAgICBsZXQgdHJhbnNsYXRlWSA9IFwiMFwiO1xyXG5cclxuICAgIHN3aXRjaCAocGxhY2VtZW50KSB7XHJcbiAgICAgIGNhc2UgXCJ0b3BcIjpcclxuICAgICAgICAvLyDlvLnnqpflnKjop6blj5HlhYPntKDkuIrmlrlcclxuICAgICAgICB0b3AgPSB0cmlnZ2VyUmVjdC50b3AgLSB0aGlzLm9mZnNldDtcclxuICAgICAgICB0cmFuc2xhdGVZID0gXCItMTAwJVwiO1xyXG4gICAgICAgIGlmIChwb3NpdGlvbiA9PT0gXCJzdGFydFwiKSB7XHJcbiAgICAgICAgICAvLyDlt6blr7npvZBcclxuICAgICAgICAgIGxlZnQgPSB0cmlnZ2VyUmVjdC5sZWZ0O1xyXG4gICAgICAgICAgdHJhbnNsYXRlWCA9IFwiMFwiO1xyXG4gICAgICAgIH0gZWxzZSBpZiAocG9zaXRpb24gPT09IFwiY2VudGVyXCIpIHtcclxuICAgICAgICAgIC8vIOWxheS4reWvuem9kFxyXG4gICAgICAgICAgbGVmdCA9IHRyaWdnZXJSZWN0LmxlZnQgKyB0cmlnZ2VyV2lkdGggLyAyO1xyXG4gICAgICAgICAgdHJhbnNsYXRlWCA9IFwiLTUwJVwiO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAvLyDlj7Plr7npvZDvvIhlbmTvvIlcclxuICAgICAgICAgIGxlZnQgPSB0cmlnZ2VyUmVjdC5yaWdodDtcclxuICAgICAgICAgIHRyYW5zbGF0ZVggPSBcIi0xMDAlXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIOi+ueeVjOe6puadn++8muehruS/neW8ueeql+S4jei2heWHuuinhuWPo1xyXG4gICAgICAgIGNvbnN0IHBvcHVwVG9wID0gdG9wIC0gcG9wdXBTaXplLmhlaWdodDtcclxuICAgICAgICBpZiAocG9wdXBUb3AgPCAwKSB7XHJcbiAgICAgICAgICB0b3AgPSBwb3B1cFNpemUuaGVpZ2h0ICsgODsgLy8g6Led56a76aG26YOo6Iez5bCROHB4XHJcbiAgICAgICAgICB0cmFuc2xhdGVZID0gXCIwXCI7IC8vIOWPlua2iOWQkeS4iuWBj+enu1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyDmsLTlubPovrnnlYznuqbmnZ/vvJrlsL3ph4/kv53mjIHljp/lp4vlr7npvZDmlrnlvI9cclxuICAgICAgICBpZiAocG9zaXRpb24gPT09IFwic3RhcnRcIikge1xyXG4gICAgICAgICAgLy8g5bem5a+56b2Q77ya5aaC5p6c6LaF5Ye65Y+z6L6555WM77yM6LCD5pW05Yiw5Y+z6L6555WM77yb5aaC5p6c6LaF5Ye65bem6L6555WM77yM6LCD5pW05Yiw5bem6L6555WMXHJcbiAgICAgICAgICBpZiAobGVmdCArIHBvcHVwU2l6ZS53aWR0aCA+IHZpZXdwb3J0V2lkdGgpIHtcclxuICAgICAgICAgICAgbGVmdCA9IHZpZXdwb3J0V2lkdGggLSBwb3B1cFNpemUud2lkdGggLSA4O1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgaWYgKGxlZnQgPCA4KSB7XHJcbiAgICAgICAgICAgIGxlZnQgPSA4O1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSBpZiAocG9zaXRpb24gPT09IFwiY2VudGVyXCIpIHtcclxuICAgICAgICAgIC8vIOWxheS4reWvuem9kO+8muiuoeeul+WunumZheW3pui+ueeVjFxyXG4gICAgICAgICAgY29uc3QgYWN0dWFsTGVmdCA9IGxlZnQgLSBwb3B1cFNpemUud2lkdGggLyAyO1xyXG4gICAgICAgICAgaWYgKGFjdHVhbExlZnQgPCA4KSB7XHJcbiAgICAgICAgICAgIC8vIOW3pui+ueeVjOS4jei2s++8jOWwvemHj+S/neaMgeWxheS4re+8jOS9huiwg+aVtOWIsOS4jei2heWHuuW3pui+ueeVjFxyXG4gICAgICAgICAgICBsZWZ0ID0gOCArIHBvcHVwU2l6ZS53aWR0aCAvIDI7XHJcbiAgICAgICAgICAgIHRyYW5zbGF0ZVggPSBcIi01MCVcIjtcclxuICAgICAgICAgIH0gZWxzZSBpZiAoYWN0dWFsTGVmdCArIHBvcHVwU2l6ZS53aWR0aCA+IHZpZXdwb3J0V2lkdGggLSA4KSB7XHJcbiAgICAgICAgICAgIC8vIOWPs+i+ueeVjOS4jei2s++8jOWwvemHj+S/neaMgeWxheS4re+8jOS9huiwg+aVtOWIsOS4jei2heWHuuWPs+i+ueeVjFxyXG4gICAgICAgICAgICBsZWZ0ID0gdmlld3BvcnRXaWR0aCAtIDggLSBwb3B1cFNpemUud2lkdGggLyAyO1xyXG4gICAgICAgICAgICB0cmFuc2xhdGVYID0gXCItNTAlXCI7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIC8vIOWPs+Wvuem9kO+8iGVuZO+8ie+8muW8ueeql+WPs+i+uee8mOS4juinpuWPkeWFg+e0oOWPs+i+uee8mOWvuem9kFxyXG4gICAgICAgICAgLy8gbGVmdCDmmK/lvLnnqpfnmoTlj7PovrnnvJjkvY3nva7vvIjlm6DkuLogdHJhbnNsYXRlWCA9IFwiLTEwMCVcIu+8iVxyXG4gICAgICAgICAgLy8g5by556qX55qE5bem6L6557yY5ZyoIGxlZnQgLSBwb3B1cFNpemUud2lkdGhcclxuICAgICAgICAgIGNvbnN0IHBvcHVwTGVmdEVkZ2UgPSBsZWZ0IC0gcG9wdXBTaXplLndpZHRoO1xyXG4gICAgICAgICAgXHJcbiAgICAgICAgICAvLyDlpoLmnpzlvLnnqpflt6bovrnnvJjotoXlh7rlt6bovrnnlYzvvIzosIPmlbTkvY3nva7kvYbkv53mjIHlj7Plr7npvZBcclxuICAgICAgICAgIGlmIChwb3B1cExlZnRFZGdlIDwgOCkge1xyXG4gICAgICAgICAgICBsZWZ0ID0gOCArIHBvcHVwU2l6ZS53aWR0aDtcclxuICAgICAgICAgICAgdHJhbnNsYXRlWCA9IFwiLTEwMCVcIjtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIC8vIOWmguaenOW8ueeql+WPs+i+uee8mOi2heWHuuWPs+i+ueeVjO+8jOiwg+aVtOS9jee9ruS9huS/neaMgeWPs+Wvuem9kFxyXG4gICAgICAgICAgaWYgKGxlZnQgPiB2aWV3cG9ydFdpZHRoIC0gOCkge1xyXG4gICAgICAgICAgICBsZWZ0ID0gdmlld3BvcnRXaWR0aCAtIDg7XHJcbiAgICAgICAgICAgIHRyYW5zbGF0ZVggPSBcIi0xMDAlXCI7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgY2FzZSBcImJvdHRvbVwiOlxyXG4gICAgICAgIC8vIOW8ueeql+WcqOinpuWPkeWFg+e0oOS4i+aWuVxyXG4gICAgICAgIHRvcCA9IHRyaWdnZXJSZWN0LmJvdHRvbSArIHRoaXMub2Zmc2V0O1xyXG4gICAgICAgIGlmIChwb3NpdGlvbiA9PT0gXCJzdGFydFwiKSB7XHJcbiAgICAgICAgICAvLyDlt6blr7npvZBcclxuICAgICAgICAgIGxlZnQgPSB0cmlnZ2VyUmVjdC5sZWZ0O1xyXG4gICAgICAgICAgdHJhbnNsYXRlWCA9IFwiMFwiO1xyXG4gICAgICAgIH0gZWxzZSBpZiAocG9zaXRpb24gPT09IFwiY2VudGVyXCIpIHtcclxuICAgICAgICAgIC8vIOWxheS4reWvuem9kFxyXG4gICAgICAgICAgbGVmdCA9IHRyaWdnZXJSZWN0LmxlZnQgKyB0cmlnZ2VyV2lkdGggLyAyO1xyXG4gICAgICAgICAgdHJhbnNsYXRlWCA9IFwiLTUwJVwiO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAvLyDlj7Plr7npvZDvvIhlbmTvvIlcclxuICAgICAgICAgIGxlZnQgPSB0cmlnZ2VyUmVjdC5yaWdodDtcclxuICAgICAgICAgIHRyYW5zbGF0ZVggPSBcIi0xMDAlXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIOi+ueeVjOe6puadn++8muehruS/neW8ueeql+S4jei2heWHuuinhuWPo1xyXG4gICAgICAgIGlmICh0b3AgKyBwb3B1cFNpemUuaGVpZ2h0ID4gdmlld3BvcnRIZWlnaHQpIHtcclxuICAgICAgICAgIHRvcCA9IHZpZXdwb3J0SGVpZ2h0IC0gcG9wdXBTaXplLmhlaWdodCAtIDg7IC8vIOi3neemu+W6lemDqOiHs+WwkThweFxyXG4gICAgICAgIH1cclxuICAgICAgICAvLyDmsLTlubPovrnnlYznuqbmnZ/vvJrlsL3ph4/kv53mjIHljp/lp4vlr7npvZDmlrnlvI9cclxuICAgICAgICBpZiAocG9zaXRpb24gPT09IFwic3RhcnRcIikge1xyXG4gICAgICAgICAgLy8g5bem5a+56b2Q77ya5aaC5p6c6LaF5Ye65Y+z6L6555WM77yM6LCD5pW05Yiw5Y+z6L6555WM77yb5aaC5p6c6LaF5Ye65bem6L6555WM77yM6LCD5pW05Yiw5bem6L6555WMXHJcbiAgICAgICAgICBpZiAobGVmdCArIHBvcHVwU2l6ZS53aWR0aCA+IHZpZXdwb3J0V2lkdGgpIHtcclxuICAgICAgICAgICAgbGVmdCA9IHZpZXdwb3J0V2lkdGggLSBwb3B1cFNpemUud2lkdGggLSA4O1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgaWYgKGxlZnQgPCA4KSB7XHJcbiAgICAgICAgICAgIGxlZnQgPSA4O1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSBpZiAocG9zaXRpb24gPT09IFwiY2VudGVyXCIpIHtcclxuICAgICAgICAgIC8vIOWxheS4reWvuem9kO+8muiuoeeul+WunumZheW3pui+ueeVjFxyXG4gICAgICAgICAgY29uc3QgYWN0dWFsTGVmdCA9IGxlZnQgLSBwb3B1cFNpemUud2lkdGggLyAyO1xyXG4gICAgICAgICAgaWYgKGFjdHVhbExlZnQgPCA4KSB7XHJcbiAgICAgICAgICAgIC8vIOW3pui+ueeVjOS4jei2s++8jOWwvemHj+S/neaMgeWxheS4re+8jOS9huiwg+aVtOWIsOS4jei2heWHuuW3pui+ueeVjFxyXG4gICAgICAgICAgICBsZWZ0ID0gOCArIHBvcHVwU2l6ZS53aWR0aCAvIDI7XHJcbiAgICAgICAgICAgIHRyYW5zbGF0ZVggPSBcIi01MCVcIjtcclxuICAgICAgICAgIH0gZWxzZSBpZiAoYWN0dWFsTGVmdCArIHBvcHVwU2l6ZS53aWR0aCA+IHZpZXdwb3J0V2lkdGggLSA4KSB7XHJcbiAgICAgICAgICAgIC8vIOWPs+i+ueeVjOS4jei2s++8jOWwvemHj+S/neaMgeWxheS4re+8jOS9huiwg+aVtOWIsOS4jei2heWHuuWPs+i+ueeVjFxyXG4gICAgICAgICAgICBsZWZ0ID0gdmlld3BvcnRXaWR0aCAtIDggLSBwb3B1cFNpemUud2lkdGggLyAyO1xyXG4gICAgICAgICAgICB0cmFuc2xhdGVYID0gXCItNTAlXCI7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIC8vIOWPs+Wvuem9kO+8iGVuZO+8ie+8muW8ueeql+WPs+i+uee8mOS4juinpuWPkeWFg+e0oOWPs+i+uee8mOWvuem9kFxyXG4gICAgICAgICAgLy8gbGVmdCDmmK/lvLnnqpfnmoTlj7PovrnnvJjkvY3nva7vvIjlm6DkuLogdHJhbnNsYXRlWCA9IFwiLTEwMCVcIu+8iVxyXG4gICAgICAgICAgLy8g5by556qX55qE5bem6L6557yY5ZyoIGxlZnQgLSBwb3B1cFNpemUud2lkdGhcclxuICAgICAgICAgIGNvbnN0IHBvcHVwTGVmdEVkZ2UgPSBsZWZ0IC0gcG9wdXBTaXplLndpZHRoO1xyXG4gICAgICAgICAgXHJcbiAgICAgICAgICAvLyDkvJjlhYjkv53mjIHkuI7op6blj5HlhYPntKDlj7Plr7npvZDvvIzlj6rlnKjlv4XopoHml7bosIPmlbRcclxuICAgICAgICAgIC8vIOWmguaenOW8ueeql+WPs+i+uee8mOi2heWHuuWPs+i+ueeVjO+8jOiwg+aVtOS9jee9ruS9huS/neaMgeWPs+Wvuem9kFxyXG4gICAgICAgICAgaWYgKGxlZnQgPiB2aWV3cG9ydFdpZHRoIC0gOCkge1xyXG4gICAgICAgICAgICBsZWZ0ID0gdmlld3BvcnRXaWR0aCAtIDg7XHJcbiAgICAgICAgICAgIHRyYW5zbGF0ZVggPSBcIi0xMDAlXCI7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICAvLyDlpoLmnpzlvLnnqpflt6bovrnnvJjotoXlh7rlt6bovrnnlYzvvIzkuJTlvLnnqpflj6/ku6XlrozlhajmmL7npLrlnKjop4blj6PlhoXvvIzmiY3osIPmlbTkvY3nva5cclxuICAgICAgICAgIC8vIOi/meagt+WPr+S7peehruS/neWcqOWPr+iDveeahOaDheWGteS4i++8jOW8ueeql+Wni+e7iOS4juinpuWPkeWFg+e0oOWPs+Wvuem9kFxyXG4gICAgICAgICAgaWYgKHBvcHVwTGVmdEVkZ2UgPCA4ICYmIHBvcHVwU2l6ZS53aWR0aCA8IHZpZXdwb3J0V2lkdGggLSAxNikge1xyXG4gICAgICAgICAgICAvLyDlj6rmnInlvZPlvLnnqpflj6/ku6XlrozlhajmmL7npLrlnKjop4blj6PlhoXml7bvvIzmiY3osIPmlbTkvY3nva5cclxuICAgICAgICAgICAgLy8g5ZCm5YiZ5L+d5oyB5LiO6Kem5Y+R5YWD57Sg5Y+z5a+56b2Q77yM5Y2z5L2/6YOo5YiG6LaF5Ye65bem6L6555WMXHJcbiAgICAgICAgICAgIGxlZnQgPSA4ICsgcG9wdXBTaXplLndpZHRoO1xyXG4gICAgICAgICAgICB0cmFuc2xhdGVYID0gXCItMTAwJVwiO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBicmVhaztcclxuXHJcbiAgICAgIGNhc2UgXCJsZWZ0XCI6XHJcbiAgICAgICAgLy8g5by556qX5Zyo6Kem5Y+R5YWD57Sg5bem5L6nXHJcbiAgICAgICAgbGVmdCA9IHRyaWdnZXJSZWN0LmxlZnQgLSB0aGlzLm9mZnNldDtcclxuICAgICAgICB0cmFuc2xhdGVYID0gXCItMTAwJVwiO1xyXG4gICAgICAgIGlmIChwb3NpdGlvbiA9PT0gXCJzdGFydFwiKSB7XHJcbiAgICAgICAgICAvLyDkuIrlr7npvZBcclxuICAgICAgICAgIHRvcCA9IHRyaWdnZXJSZWN0LnRvcDtcclxuICAgICAgICAgIHRyYW5zbGF0ZVkgPSBcIjBcIjtcclxuICAgICAgICB9IGVsc2UgaWYgKHBvc2l0aW9uID09PSBcImNlbnRlclwiKSB7XHJcbiAgICAgICAgICAvLyDlsYXkuK3lr7npvZBcclxuICAgICAgICAgIHRvcCA9IHRyaWdnZXJSZWN0LnRvcCArIHRyaWdnZXJIZWlnaHQgLyAyO1xyXG4gICAgICAgICAgdHJhbnNsYXRlWSA9IFwiLTUwJVwiO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAvLyDkuIvlr7npvZDvvIhlbmTvvIlcclxuICAgICAgICAgIHRvcCA9IHRyaWdnZXJSZWN0LmJvdHRvbTtcclxuICAgICAgICAgIHRyYW5zbGF0ZVkgPSBcIi0xMDAlXCI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIOi+ueeVjOe6puadn++8muehruS/neW8ueeql+S4jei2heWHuuinhuWPo1xyXG4gICAgICAgIGNvbnN0IHBvcHVwTGVmdFNpZGUgPSBsZWZ0IC0gcG9wdXBTaXplLndpZHRoO1xyXG4gICAgICAgIGlmIChwb3B1cExlZnRTaWRlIDwgMCkge1xyXG4gICAgICAgICAgbGVmdCA9IDg7IC8vIOi3neemu+W3puS+p+iHs+WwkThweFxyXG4gICAgICAgICAgdHJhbnNsYXRlWCA9IFwiMFwiOyAvLyDlj5bmtojlkJHlt6blgY/np7tcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8g5Z6C55u06L6555WM57qm5p2f77ya5bC96YeP5L+d5oyB5Y6f5aeL5a+56b2Q5pa55byPXHJcbiAgICAgICAgaWYgKHBvc2l0aW9uID09PSBcInN0YXJ0XCIpIHtcclxuICAgICAgICAgIC8vIOS4iuWvuem9kO+8muWmguaenOi2heWHuuS4i+i+ueeVjO+8jOiwg+aVtOWIsOS4i+i+ueeVjO+8m+WmguaenOi2heWHuuS4iui+ueeVjO+8jOiwg+aVtOWIsOS4iui+ueeVjFxyXG4gICAgICAgICAgaWYgKHRvcCArIHBvcHVwU2l6ZS5oZWlnaHQgPiB2aWV3cG9ydEhlaWdodCkge1xyXG4gICAgICAgICAgICB0b3AgPSB2aWV3cG9ydEhlaWdodCAtIHBvcHVwU2l6ZS5oZWlnaHQgLSA4O1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgaWYgKHRvcCA8IDgpIHtcclxuICAgICAgICAgICAgdG9wID0gODtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2UgaWYgKHBvc2l0aW9uID09PSBcImNlbnRlclwiKSB7XHJcbiAgICAgICAgICAvLyDlsYXkuK3lr7npvZDvvJrorqHnrpflrp7pmYXkuIrovrnnlYxcclxuICAgICAgICAgIGNvbnN0IGFjdHVhbFRvcCA9IHRvcCAtIHBvcHVwU2l6ZS5oZWlnaHQgLyAyO1xyXG4gICAgICAgICAgaWYgKGFjdHVhbFRvcCA8IDgpIHtcclxuICAgICAgICAgICAgLy8g5LiK6L6555WM5LiN6Laz77yM5bC96YeP5L+d5oyB5bGF5Lit77yM5L2G6LCD5pW05Yiw5LiN6LaF5Ye65LiK6L6555WMXHJcbiAgICAgICAgICAgIHRvcCA9IDggKyBwb3B1cFNpemUuaGVpZ2h0IC8gMjtcclxuICAgICAgICAgICAgdHJhbnNsYXRlWSA9IFwiLTUwJVwiO1xyXG4gICAgICAgICAgfSBlbHNlIGlmIChhY3R1YWxUb3AgKyBwb3B1cFNpemUuaGVpZ2h0ID4gdmlld3BvcnRIZWlnaHQgLSA4KSB7XHJcbiAgICAgICAgICAgIC8vIOS4i+i+ueeVjOS4jei2s++8jOWwvemHj+S/neaMgeWxheS4re+8jOS9huiwg+aVtOWIsOS4jei2heWHuuS4i+i+ueeVjFxyXG4gICAgICAgICAgICB0b3AgPSB2aWV3cG9ydEhlaWdodCAtIDggLSBwb3B1cFNpemUuaGVpZ2h0IC8gMjtcclxuICAgICAgICAgICAgdHJhbnNsYXRlWSA9IFwiLTUwJVwiO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAvLyDkuIvlr7npvZDvvIhlbmTvvInvvJrlpoLmnpzotoXlh7rkuIrovrnnlYzvvIzosIPmlbTliLDkuIrovrnnlYzvvJvlpoLmnpzotoXlh7rkuIvovrnnlYzvvIzosIPmlbTliLDkuIvovrnnlYxcclxuICAgICAgICAgIGNvbnN0IGFjdHVhbFRvcCA9IHRvcCAtIHBvcHVwU2l6ZS5oZWlnaHQ7XHJcbiAgICAgICAgICBpZiAoYWN0dWFsVG9wIDwgOCkge1xyXG4gICAgICAgICAgICB0b3AgPSA4ICsgcG9wdXBTaXplLmhlaWdodDtcclxuICAgICAgICAgICAgdHJhbnNsYXRlWSA9IFwiLTEwMCVcIjtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGlmICh0b3AgPiB2aWV3cG9ydEhlaWdodCAtIDgpIHtcclxuICAgICAgICAgICAgdG9wID0gdmlld3BvcnRIZWlnaHQgLSA4O1xyXG4gICAgICAgICAgICB0cmFuc2xhdGVZID0gXCItMTAwJVwiO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBicmVhaztcclxuXHJcbiAgICAgIGNhc2UgXCJyaWdodFwiOlxyXG4gICAgICAgIC8vIOW8ueeql+WcqOinpuWPkeWFg+e0oOWPs+S+p1xyXG4gICAgICAgIGxlZnQgPSB0cmlnZ2VyUmVjdC5yaWdodCArIHRoaXMub2Zmc2V0O1xyXG4gICAgICAgIHRyYW5zbGF0ZVggPSBcIjBcIjtcclxuICAgICAgICBpZiAocG9zaXRpb24gPT09IFwic3RhcnRcIikge1xyXG4gICAgICAgICAgLy8g5LiK5a+56b2QXHJcbiAgICAgICAgICB0b3AgPSB0cmlnZ2VyUmVjdC50b3A7XHJcbiAgICAgICAgICB0cmFuc2xhdGVZID0gXCIwXCI7XHJcbiAgICAgICAgfSBlbHNlIGlmIChwb3NpdGlvbiA9PT0gXCJjZW50ZXJcIikge1xyXG4gICAgICAgICAgLy8g5bGF5Lit5a+56b2QXHJcbiAgICAgICAgICB0b3AgPSB0cmlnZ2VyUmVjdC50b3AgKyB0cmlnZ2VySGVpZ2h0IC8gMjtcclxuICAgICAgICAgIHRyYW5zbGF0ZVkgPSBcIi01MCVcIjtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgLy8g5LiL5a+56b2Q77yIZW5k77yJXHJcbiAgICAgICAgICB0b3AgPSB0cmlnZ2VyUmVjdC5ib3R0b207XHJcbiAgICAgICAgICB0cmFuc2xhdGVZID0gXCItMTAwJVwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyDovrnnlYznuqbmnZ/vvJrnoa7kv53lvLnnqpfkuI3otoXlh7rop4blj6NcclxuICAgICAgICBpZiAobGVmdCArIHBvcHVwU2l6ZS53aWR0aCA+IHZpZXdwb3J0V2lkdGgpIHtcclxuICAgICAgICAgIGxlZnQgPSB2aWV3cG9ydFdpZHRoIC0gcG9wdXBTaXplLndpZHRoIC0gODsgLy8g6Led56a75Y+z5L6n6Iez5bCROHB4XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIOWeguebtOi+ueeVjOe6puadn++8muWwvemHj+S/neaMgeWOn+Wni+Wvuem9kOaWueW8j1xyXG4gICAgICAgIGlmIChwb3NpdGlvbiA9PT0gXCJzdGFydFwiKSB7XHJcbiAgICAgICAgICAvLyDkuIrlr7npvZDvvJrlpoLmnpzotoXlh7rkuIvovrnnlYzvvIzosIPmlbTliLDkuIvovrnnlYzvvJvlpoLmnpzotoXlh7rkuIrovrnnlYzvvIzosIPmlbTliLDkuIrovrnnlYxcclxuICAgICAgICAgIGlmICh0b3AgKyBwb3B1cFNpemUuaGVpZ2h0ID4gdmlld3BvcnRIZWlnaHQpIHtcclxuICAgICAgICAgICAgdG9wID0gdmlld3BvcnRIZWlnaHQgLSBwb3B1cFNpemUuaGVpZ2h0IC0gODtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGlmICh0b3AgPCA4KSB7XHJcbiAgICAgICAgICAgIHRvcCA9IDg7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIGlmIChwb3NpdGlvbiA9PT0gXCJjZW50ZXJcIikge1xyXG4gICAgICAgICAgLy8g5bGF5Lit5a+56b2Q77ya6K6h566X5a6e6ZmF5LiK6L6555WMXHJcbiAgICAgICAgICBjb25zdCBhY3R1YWxUb3AgPSB0b3AgLSBwb3B1cFNpemUuaGVpZ2h0IC8gMjtcclxuICAgICAgICAgIGlmIChhY3R1YWxUb3AgPCA4KSB7XHJcbiAgICAgICAgICAgIC8vIOS4iui+ueeVjOS4jei2s++8jOWwvemHj+S/neaMgeWxheS4re+8jOS9huiwg+aVtOWIsOS4jei2heWHuuS4iui+ueeVjFxyXG4gICAgICAgICAgICB0b3AgPSA4ICsgcG9wdXBTaXplLmhlaWdodCAvIDI7XHJcbiAgICAgICAgICAgIHRyYW5zbGF0ZVkgPSBcIi01MCVcIjtcclxuICAgICAgICAgIH0gZWxzZSBpZiAoYWN0dWFsVG9wICsgcG9wdXBTaXplLmhlaWdodCA+IHZpZXdwb3J0SGVpZ2h0IC0gOCkge1xyXG4gICAgICAgICAgICAvLyDkuIvovrnnlYzkuI3otrPvvIzlsL3ph4/kv53mjIHlsYXkuK3vvIzkvYbosIPmlbTliLDkuI3otoXlh7rkuIvovrnnlYxcclxuICAgICAgICAgICAgdG9wID0gdmlld3BvcnRIZWlnaHQgLSA4IC0gcG9wdXBTaXplLmhlaWdodCAvIDI7XHJcbiAgICAgICAgICAgIHRyYW5zbGF0ZVkgPSBcIi01MCVcIjtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgLy8g5LiL5a+56b2Q77yIZW5k77yJ77ya5aaC5p6c6LaF5Ye65LiK6L6555WM77yM6LCD5pW05Yiw5LiK6L6555WM77yb5aaC5p6c6LaF5Ye65LiL6L6555WM77yM6LCD5pW05Yiw5LiL6L6555WMXHJcbiAgICAgICAgICBjb25zdCBhY3R1YWxUb3AgPSB0b3AgLSBwb3B1cFNpemUuaGVpZ2h0O1xyXG4gICAgICAgICAgaWYgKGFjdHVhbFRvcCA8IDgpIHtcclxuICAgICAgICAgICAgdG9wID0gOCArIHBvcHVwU2l6ZS5oZWlnaHQ7XHJcbiAgICAgICAgICAgIHRyYW5zbGF0ZVkgPSBcIi0xMDAlXCI7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBpZiAodG9wID4gdmlld3BvcnRIZWlnaHQgLSA4KSB7XHJcbiAgICAgICAgICAgIHRvcCA9IHZpZXdwb3J0SGVpZ2h0IC0gODtcclxuICAgICAgICAgICAgdHJhbnNsYXRlWSA9IFwiLTEwMCVcIjtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgdG9wOiB0b3AgKyBcInB4XCIsXHJcbiAgICAgIGxlZnQ6IGxlZnQgKyBcInB4XCIsXHJcbiAgICAgIHRyYW5zbGF0ZVgsXHJcbiAgICAgIHRyYW5zbGF0ZVksXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgc2V0UG9wdXBQb3NpdGlvbihcclxuICAgIHRyaWdnZXJSZWN0OiBET01SZWN0IHwgQ2xpZW50UmVjdCxcclxuICAgIHBvcHVwUmVjdDogRE9NUmVjdCB8IENsaWVudFJlY3QsXHJcbiAgICBwbGFjZW1lbnQ6IFwidG9wXCIgfCBcImxlZnRcIiB8IFwicmlnaHRcIiB8IFwiYm90dG9tXCIsXHJcbiAgICBwb3NpdGlvbjogXCJzdGFydFwiIHwgXCJjZW50ZXJcIiB8IFwiZW5kXCIsXHJcbiAgICBwb3B1cFNpemU/OiB7IHdpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyIH1cclxuICApIHtcclxuICAgIGNvbnN0IHBvcHVwRWwgPVxyXG4gICAgICB0aGlzLnBvcHVwRWxlbWVudCAmJiB0aGlzLnBvcHVwRWxlbWVudC5uYXRpdmVFbGVtZW50XHJcbiAgICAgICAgPyB0aGlzLnBvcHVwRWxlbWVudC5uYXRpdmVFbGVtZW50XHJcbiAgICAgICAgOiBudWxsO1xyXG4gICAgaWYgKCFwb3B1cEVsKSB7XHJcbiAgICAgIHJldHVybjsgLy8g5aaC5p6c5YWD57Sg6L+Y5LiN5a2Y5Zyo77yM5peg5rOV6K6+572u5L2N572uXHJcbiAgICB9XHJcblxyXG4gICAgLy8g5LyY5YWI5L2/55So5Lyg5YWl55qE5Zu65a6a5bC65a+477yM5ZCm5YiZ5LuORE9N6I635Y+WXHJcbiAgICBjb25zdCBwb3B1cFdpZHRoID1cclxuICAgICAgcG9wdXBTaXplICYmIHBvcHVwU2l6ZS53aWR0aCAhPT0gbnVsbCAmJiBwb3B1cFNpemUud2lkdGggIT09IHVuZGVmaW5lZFxyXG4gICAgICAgID8gcG9wdXBTaXplLndpZHRoXHJcbiAgICAgICAgOiBwb3B1cFJlY3Qud2lkdGggfHwgcG9wdXBFbC5vZmZzZXRXaWR0aCB8fCAzMDA7XHJcbiAgICBjb25zdCBwb3B1cEhlaWdodCA9XHJcbiAgICAgIHBvcHVwU2l6ZSAmJiBwb3B1cFNpemUuaGVpZ2h0ICE9PSBudWxsICYmIHBvcHVwU2l6ZS5oZWlnaHQgIT09IHVuZGVmaW5lZFxyXG4gICAgICAgID8gcG9wdXBTaXplLmhlaWdodFxyXG4gICAgICAgIDogcG9wdXBSZWN0LmhlaWdodCB8fCBwb3B1cEVsLm9mZnNldEhlaWdodCB8fCAyMDA7XHJcblxyXG4gICAgY29uc3QgY29vcmRpbmF0ZXMgPSB0aGlzLmNhbGN1bGF0ZVBvc2l0aW9uQ29vcmRpbmF0ZXMoXHJcbiAgICAgIHRyaWdnZXJSZWN0LFxyXG4gICAgICBwbGFjZW1lbnQsXHJcbiAgICAgIHBvc2l0aW9uLFxyXG4gICAgICB7IHdpZHRoOiBwb3B1cFdpZHRoLCBoZWlnaHQ6IHBvcHVwSGVpZ2h0IH1cclxuICAgICk7XHJcblxyXG4gICAgcG9wdXBFbC5zdHlsZS50b3AgPSBjb29yZGluYXRlcy50b3A7XHJcbiAgICBwb3B1cEVsLnN0eWxlLmxlZnQgPSBjb29yZGluYXRlcy5sZWZ0O1xyXG4gICAgcG9wdXBFbC5zdHlsZS50cmFuc2Zvcm0gPSBgdHJhbnNsYXRlKCR7Y29vcmRpbmF0ZXMudHJhbnNsYXRlWH0sICR7Y29vcmRpbmF0ZXMudHJhbnNsYXRlWX0pYDtcclxuICB9XHJcblxyXG4gIEBIb3N0TGlzdGVuZXIoXCJ3aW5kb3c6cmVzaXplXCIpXHJcbiAgb25XaW5kb3dSZXNpemUoKSB7XHJcbiAgICBpZiAodGhpcy5vcGVuZWQgPT09IFwieWVzXCIpIHtcclxuICAgICAgdGhpcy51cGRhdGVQb3B1cFBvc2l0aW9uKCk7XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcbiIsIjwhLS0g6Kem5Y+R5YWD57Sg5o+S5qe9IC0tPlxyXG48bmctY29udGFpbmVyICN0cmlnZ2VyPlxyXG4gIDxuZy1jb250ZW50IHNlbGVjdD1cIlt0cmlnZ2VyXVwiPjwvbmctY29udGVudD5cclxuPC9uZy1jb250YWluZXI+XHJcblxyXG48IS0tIOW8ueeql+WGheWuuSAtLT5cclxuPGRpdlxyXG4gICNwb3B1cFxyXG4gIGNsYXNzPVwicnMtc21hcnQtcG9wdXAtY29udGVudFwiXHJcbiAgW2F0dHIuZGF0YS1vcGVuZWRdPVwib3BlbmVkXCJcclxuICBbYXR0ci5kYXRhLXBvc2l0aW9uaW5nXT1cInBvc2l0aW9uaW5nXCJcclxuICAod2hlZWwpPVwib25Qb3B1cFdoZWVsKCRldmVudClcIlxyXG4gIChzY3JvbGwpPVwib25Qb3B1cFNjcm9sbCgkZXZlbnQpXCJcclxuPlxyXG4gIDxkaXYgKm5nSWY9XCJsb2FkaW5nXCIgY2xhc3M9XCJycy1zbWFydC1wb3B1cC1sb2FkaW5nXCI+XHJcbiAgICA8ZGl2IGNsYXNzPVwibG9hZGluZy1zcGlubmVyXCI+PC9kaXY+XHJcbiAgPC9kaXY+XHJcbiAgPGRpdiAqbmdJZj1cIiFsb2FkaW5nXCIgY2xhc3M9XCJycy1zbWFydC1wb3B1cC1ib2R5XCI+XHJcbiAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XHJcbiAgPC9kaXY+XHJcbjwvZGl2PlxyXG5cclxuIl19