@angular-generic-table/core 5.0.0-alpha.2 → 5.0.0-rc.11

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 (260) hide show
  1. package/README.md +13 -134
  2. package/angular-generic-table-core.d.ts +2 -19
  3. package/esm2020/angular-generic-table-core.mjs +5 -0
  4. package/esm2020/lib/core.component.mjs +143 -0
  5. package/esm2020/lib/core.module.mjs +23 -0
  6. package/esm2020/lib/core.service.mjs +14 -0
  7. package/esm2020/lib/enums/order.enum.mjs +6 -0
  8. package/esm2020/lib/models/table-column.interface.mjs +2 -0
  9. package/esm2020/lib/models/table-config.interface.mjs +2 -0
  10. package/esm2020/lib/models/table-info.interface.mjs +2 -0
  11. package/esm2020/lib/models/table-meta.interface.mjs +2 -0
  12. package/esm2020/lib/models/table-row.interface.mjs +2 -0
  13. package/esm2020/lib/models/table-sort.interface.mjs +2 -0
  14. package/esm2020/lib/pagination/pagination.component.mjs +63 -0
  15. package/esm2020/lib/pagination/pagination.module.mjs +18 -0
  16. package/esm2020/lib/pipes/capital-case.pipe.mjs +17 -0
  17. package/esm2020/lib/pipes/dash-case.pipe.mjs +17 -0
  18. package/esm2020/lib/pipes/dynamic.pipe.mjs +25 -0
  19. package/esm2020/lib/pipes/highlight.pipe.mjs +48 -0
  20. package/esm2020/lib/pipes/sort-class.pipe.mjs +22 -0
  21. package/esm2020/lib/utilities/utilities.mjs +39 -0
  22. package/esm2020/public-api.mjs +15 -0
  23. package/fesm2015/angular-generic-table-core.mjs +412 -0
  24. package/fesm2015/angular-generic-table-core.mjs.map +1 -0
  25. package/fesm2020/angular-generic-table-core.mjs +408 -0
  26. package/fesm2020/angular-generic-table-core.mjs.map +1 -0
  27. package/lib/core.component.d.ts +34 -0
  28. package/lib/core.module.d.ts +12 -1
  29. package/lib/core.service.d.ts +6 -0
  30. package/lib/enums/order.enum.d.ts +4 -0
  31. package/lib/models/table-column.interface.d.ts +19 -0
  32. package/lib/models/table-config.interface.d.ts +15 -0
  33. package/lib/models/table-info.interface.d.ts +4 -0
  34. package/lib/models/table-meta.interface.d.ts +8 -0
  35. package/lib/models/table-row.interface.d.ts +4 -0
  36. package/lib/models/table-sort.interface.d.ts +5 -0
  37. package/lib/pagination/pagination.component.d.ts +14 -0
  38. package/lib/pagination/pagination.module.d.ts +8 -0
  39. package/lib/pipes/capital-case.pipe.d.ts +7 -0
  40. package/lib/pipes/dash-case.pipe.d.ts +4 -1
  41. package/lib/pipes/dynamic.pipe.d.ts +9 -0
  42. package/lib/pipes/highlight.pipe.d.ts +7 -0
  43. package/lib/pipes/sort-class.pipe.d.ts +11 -0
  44. package/lib/utilities/utilities.d.ts +6 -0
  45. package/package.json +26 -24
  46. package/public-api.d.ts +11 -0
  47. package/scss/index.scss +102 -0
  48. package/CHANGELOG.md +0 -461
  49. package/LICENSE.md +0 -201
  50. package/angular-generic-table-core.metadata.json +0 -1
  51. package/bundles/angular-generic-table-core.umd.js +0 -3679
  52. package/bundles/angular-generic-table-core.umd.js.map +0 -1
  53. package/bundles/angular-generic-table-core.umd.min.js +0 -2
  54. package/bundles/angular-generic-table-core.umd.min.js.map +0 -1
  55. package/css/generic-table.css +0 -168
  56. package/css/generic-table.css.map +0 -9
  57. package/css/generic-table.min.css +0 -2
  58. package/css/generic-table.min.css.map +0 -1
  59. package/esm2015/angular-generic-table-core.js +0 -28
  60. package/esm2015/angular-generic-table-core.metadata.json +0 -1
  61. package/esm2015/lib/components/generic-table/generic-table.component.js +0 -1738
  62. package/esm2015/lib/components/generic-table/generic-table.component.metadata.json +0 -1
  63. package/esm2015/lib/components/gt-checkbox/gt-checkbox.component.js +0 -88
  64. package/esm2015/lib/components/gt-checkbox/gt-checkbox.component.metadata.json +0 -1
  65. package/esm2015/lib/components/gt-custom-component-factory/gt-custom-component-factory.component.js +0 -112
  66. package/esm2015/lib/components/gt-custom-component-factory/gt-custom-component-factory.component.metadata.json +0 -1
  67. package/esm2015/lib/components/gt-drilldown/gt-drilldown.component.js +0 -53
  68. package/esm2015/lib/components/gt-drilldown/gt-drilldown.component.metadata.json +0 -1
  69. package/esm2015/lib/components/gt-dropdown/gt-dropdown.component.js +0 -176
  70. package/esm2015/lib/components/gt-dropdown/gt-dropdown.component.metadata.json +0 -1
  71. package/esm2015/lib/components/gt-expanding-row/gt-expanding-row.component.js +0 -147
  72. package/esm2015/lib/components/gt-expanding-row/gt-expanding-row.component.metadata.json +0 -1
  73. package/esm2015/lib/components/gt-pagination/gt-pagination.component.js +0 -141
  74. package/esm2015/lib/components/gt-pagination/gt-pagination.component.metadata.json +0 -1
  75. package/esm2015/lib/components/gt-table-info/gt-table-info.component.js +0 -103
  76. package/esm2015/lib/components/gt-table-info/gt-table-info.component.metadata.json +0 -1
  77. package/esm2015/lib/core.module.js +0 -100
  78. package/esm2015/lib/core.module.metadata.json +0 -1
  79. package/esm2015/lib/directives/component-anchor.directive.js +0 -65
  80. package/esm2015/lib/directives/component-anchor.directive.metadata.json +0 -1
  81. package/esm2015/lib/directives/gt-column-width.directive.js +0 -73
  82. package/esm2015/lib/directives/gt-column-width.directive.metadata.json +0 -1
  83. package/esm2015/lib/interfaces/gt-config-field.js +0 -96
  84. package/esm2015/lib/interfaces/gt-config-field.metadata.json +0 -1
  85. package/esm2015/lib/interfaces/gt-config-setting.js +0 -41
  86. package/esm2015/lib/interfaces/gt-config-setting.metadata.json +0 -1
  87. package/esm2015/lib/interfaces/gt-config-total.js +0 -20
  88. package/esm2015/lib/interfaces/gt-config-total.metadata.json +0 -1
  89. package/esm2015/lib/interfaces/gt-config.js +0 -24
  90. package/esm2015/lib/interfaces/gt-config.metadata.json +0 -1
  91. package/esm2015/lib/interfaces/gt-event.js +0 -16
  92. package/esm2015/lib/interfaces/gt-event.metadata.json +0 -1
  93. package/esm2015/lib/interfaces/gt-information.js +0 -38
  94. package/esm2015/lib/interfaces/gt-information.metadata.json +0 -1
  95. package/esm2015/lib/interfaces/gt-options.js +0 -55
  96. package/esm2015/lib/interfaces/gt-options.metadata.json +0 -1
  97. package/esm2015/lib/interfaces/gt-render-field.js +0 -29
  98. package/esm2015/lib/interfaces/gt-render-field.metadata.json +0 -1
  99. package/esm2015/lib/interfaces/gt-row-meta.js +0 -18
  100. package/esm2015/lib/interfaces/gt-row-meta.metadata.json +0 -1
  101. package/esm2015/lib/interfaces/gt-row.js +0 -20
  102. package/esm2015/lib/interfaces/gt-row.metadata.json +0 -1
  103. package/esm2015/lib/interfaces/gt-texts.js +0 -36
  104. package/esm2015/lib/interfaces/gt-texts.metadata.json +0 -1
  105. package/esm2015/lib/pipes/dash-case.pipe.js +0 -30
  106. package/esm2015/lib/pipes/dash-case.pipe.metadata.json +0 -1
  107. package/esm2015/lib/pipes/gt-chunk.pipe.js +0 -52
  108. package/esm2015/lib/pipes/gt-chunk.pipe.metadata.json +0 -1
  109. package/esm2015/lib/pipes/gt-column-class.pipe.js +0 -51
  110. package/esm2015/lib/pipes/gt-column-class.pipe.metadata.json +0 -1
  111. package/esm2015/lib/pipes/gt-filter.pipe.js +0 -60
  112. package/esm2015/lib/pipes/gt-filter.pipe.metadata.json +0 -1
  113. package/esm2015/lib/pipes/gt-highlight.pipe.js +0 -72
  114. package/esm2015/lib/pipes/gt-highlight.pipe.metadata.json +0 -1
  115. package/esm2015/lib/pipes/gt-is-editable.pipe.js +0 -37
  116. package/esm2015/lib/pipes/gt-is-editable.pipe.metadata.json +0 -1
  117. package/esm2015/lib/pipes/gt-is-observable.pipe.js +0 -31
  118. package/esm2015/lib/pipes/gt-is-observable.pipe.metadata.json +0 -1
  119. package/esm2015/lib/pipes/gt-meta.pipe.js +0 -54
  120. package/esm2015/lib/pipes/gt-meta.pipe.metadata.json +0 -1
  121. package/esm2015/lib/pipes/gt-order-by.pipe.js +0 -202
  122. package/esm2015/lib/pipes/gt-order-by.pipe.metadata.json +0 -1
  123. package/esm2015/lib/pipes/gt-property.pipe.js +0 -52
  124. package/esm2015/lib/pipes/gt-property.pipe.metadata.json +0 -1
  125. package/esm2015/lib/pipes/gt-render.pipe.js +0 -173
  126. package/esm2015/lib/pipes/gt-render.pipe.metadata.json +0 -1
  127. package/esm2015/lib/pipes/gt-row-class.pipe.js +0 -66
  128. package/esm2015/lib/pipes/gt-row-class.pipe.metadata.json +0 -1
  129. package/esm2015/lib/pipes/gt-search.pipe.js +0 -114
  130. package/esm2015/lib/pipes/gt-search.pipe.metadata.json +0 -1
  131. package/esm2015/lib/pipes/gt-totals-position.pipe.js +0 -35
  132. package/esm2015/lib/pipes/gt-totals-position.pipe.metadata.json +0 -1
  133. package/esm2015/lib/pipes/gt-totals.pipe.js +0 -46
  134. package/esm2015/lib/pipes/gt-totals.pipe.metadata.json +0 -1
  135. package/esm2015/lib/pipes/gt-visible.pipe.js +0 -71
  136. package/esm2015/lib/pipes/gt-visible.pipe.metadata.json +0 -1
  137. package/esm2015/public_api.js +0 -18
  138. package/esm2015/public_api.metadata.json +0 -1
  139. package/esm5/angular-generic-table-core.js +0 -28
  140. package/esm5/angular-generic-table-core.metadata.json +0 -1
  141. package/esm5/lib/components/generic-table/generic-table.component.js +0 -1813
  142. package/esm5/lib/components/generic-table/generic-table.component.metadata.json +0 -1
  143. package/esm5/lib/components/gt-checkbox/gt-checkbox.component.js +0 -100
  144. package/esm5/lib/components/gt-checkbox/gt-checkbox.component.metadata.json +0 -1
  145. package/esm5/lib/components/gt-custom-component-factory/gt-custom-component-factory.component.js +0 -136
  146. package/esm5/lib/components/gt-custom-component-factory/gt-custom-component-factory.component.metadata.json +0 -1
  147. package/esm5/lib/components/gt-drilldown/gt-drilldown.component.js +0 -41
  148. package/esm5/lib/components/gt-drilldown/gt-drilldown.component.metadata.json +0 -1
  149. package/esm5/lib/components/gt-dropdown/gt-dropdown.component.js +0 -179
  150. package/esm5/lib/components/gt-dropdown/gt-dropdown.component.metadata.json +0 -1
  151. package/esm5/lib/components/gt-expanding-row/gt-expanding-row.component.js +0 -173
  152. package/esm5/lib/components/gt-expanding-row/gt-expanding-row.component.metadata.json +0 -1
  153. package/esm5/lib/components/gt-pagination/gt-pagination.component.js +0 -149
  154. package/esm5/lib/components/gt-pagination/gt-pagination.component.metadata.json +0 -1
  155. package/esm5/lib/components/gt-table-info/gt-table-info.component.js +0 -111
  156. package/esm5/lib/components/gt-table-info/gt-table-info.component.metadata.json +0 -1
  157. package/esm5/lib/core.module.js +0 -104
  158. package/esm5/lib/core.module.metadata.json +0 -1
  159. package/esm5/lib/directives/component-anchor.directive.js +0 -66
  160. package/esm5/lib/directives/component-anchor.directive.metadata.json +0 -1
  161. package/esm5/lib/directives/gt-column-width.directive.js +0 -81
  162. package/esm5/lib/directives/gt-column-width.directive.metadata.json +0 -1
  163. package/esm5/lib/interfaces/gt-config-field.js +0 -96
  164. package/esm5/lib/interfaces/gt-config-field.metadata.json +0 -1
  165. package/esm5/lib/interfaces/gt-config-setting.js +0 -41
  166. package/esm5/lib/interfaces/gt-config-setting.metadata.json +0 -1
  167. package/esm5/lib/interfaces/gt-config-total.js +0 -20
  168. package/esm5/lib/interfaces/gt-config-total.metadata.json +0 -1
  169. package/esm5/lib/interfaces/gt-config.js +0 -24
  170. package/esm5/lib/interfaces/gt-config.metadata.json +0 -1
  171. package/esm5/lib/interfaces/gt-event.js +0 -16
  172. package/esm5/lib/interfaces/gt-event.metadata.json +0 -1
  173. package/esm5/lib/interfaces/gt-information.js +0 -38
  174. package/esm5/lib/interfaces/gt-information.metadata.json +0 -1
  175. package/esm5/lib/interfaces/gt-options.js +0 -55
  176. package/esm5/lib/interfaces/gt-options.metadata.json +0 -1
  177. package/esm5/lib/interfaces/gt-render-field.js +0 -29
  178. package/esm5/lib/interfaces/gt-render-field.metadata.json +0 -1
  179. package/esm5/lib/interfaces/gt-row-meta.js +0 -18
  180. package/esm5/lib/interfaces/gt-row-meta.metadata.json +0 -1
  181. package/esm5/lib/interfaces/gt-row.js +0 -20
  182. package/esm5/lib/interfaces/gt-row.metadata.json +0 -1
  183. package/esm5/lib/interfaces/gt-texts.js +0 -36
  184. package/esm5/lib/interfaces/gt-texts.metadata.json +0 -1
  185. package/esm5/lib/pipes/dash-case.pipe.js +0 -38
  186. package/esm5/lib/pipes/dash-case.pipe.metadata.json +0 -1
  187. package/esm5/lib/pipes/gt-chunk.pipe.js +0 -70
  188. package/esm5/lib/pipes/gt-chunk.pipe.metadata.json +0 -1
  189. package/esm5/lib/pipes/gt-column-class.pipe.js +0 -61
  190. package/esm5/lib/pipes/gt-column-class.pipe.metadata.json +0 -1
  191. package/esm5/lib/pipes/gt-filter.pipe.js +0 -73
  192. package/esm5/lib/pipes/gt-filter.pipe.metadata.json +0 -1
  193. package/esm5/lib/pipes/gt-highlight.pipe.js +0 -77
  194. package/esm5/lib/pipes/gt-highlight.pipe.metadata.json +0 -1
  195. package/esm5/lib/pipes/gt-is-editable.pipe.js +0 -47
  196. package/esm5/lib/pipes/gt-is-editable.pipe.metadata.json +0 -1
  197. package/esm5/lib/pipes/gt-is-observable.pipe.js +0 -39
  198. package/esm5/lib/pipes/gt-is-observable.pipe.metadata.json +0 -1
  199. package/esm5/lib/pipes/gt-meta.pipe.js +0 -65
  200. package/esm5/lib/pipes/gt-meta.pipe.metadata.json +0 -1
  201. package/esm5/lib/pipes/gt-order-by.pipe.js +0 -223
  202. package/esm5/lib/pipes/gt-order-by.pipe.metadata.json +0 -1
  203. package/esm5/lib/pipes/gt-property.pipe.js +0 -63
  204. package/esm5/lib/pipes/gt-property.pipe.metadata.json +0 -1
  205. package/esm5/lib/pipes/gt-render.pipe.js +0 -182
  206. package/esm5/lib/pipes/gt-render.pipe.metadata.json +0 -1
  207. package/esm5/lib/pipes/gt-row-class.pipe.js +0 -75
  208. package/esm5/lib/pipes/gt-row-class.pipe.metadata.json +0 -1
  209. package/esm5/lib/pipes/gt-search.pipe.js +0 -125
  210. package/esm5/lib/pipes/gt-search.pipe.metadata.json +0 -1
  211. package/esm5/lib/pipes/gt-totals-position.pipe.js +0 -45
  212. package/esm5/lib/pipes/gt-totals-position.pipe.metadata.json +0 -1
  213. package/esm5/lib/pipes/gt-totals.pipe.js +0 -57
  214. package/esm5/lib/pipes/gt-totals.pipe.metadata.json +0 -1
  215. package/esm5/lib/pipes/gt-visible.pipe.js +0 -79
  216. package/esm5/lib/pipes/gt-visible.pipe.metadata.json +0 -1
  217. package/esm5/public_api.js +0 -18
  218. package/esm5/public_api.metadata.json +0 -1
  219. package/fesm2015/angular-generic-table-core.js +0 -3289
  220. package/fesm2015/angular-generic-table-core.js.map +0 -1
  221. package/fesm5/angular-generic-table-core.js +0 -3578
  222. package/fesm5/angular-generic-table-core.js.map +0 -1
  223. package/lib/components/generic-table/generic-table.component.d.ts +0 -282
  224. package/lib/components/gt-checkbox/gt-checkbox.component.d.ts +0 -12
  225. package/lib/components/gt-custom-component-factory/gt-custom-component-factory.component.d.ts +0 -27
  226. package/lib/components/gt-drilldown/gt-drilldown.component.d.ts +0 -6
  227. package/lib/components/gt-dropdown/gt-dropdown.component.d.ts +0 -21
  228. package/lib/components/gt-expanding-row/gt-expanding-row.component.d.ts +0 -34
  229. package/lib/components/gt-pagination/gt-pagination.component.d.ts +0 -11
  230. package/lib/components/gt-table-info/gt-table-info.component.d.ts +0 -15
  231. package/lib/directives/component-anchor.directive.d.ts +0 -10
  232. package/lib/directives/gt-column-width.directive.d.ts +0 -11
  233. package/lib/interfaces/gt-config-field.d.ts +0 -87
  234. package/lib/interfaces/gt-config-setting.d.ts +0 -21
  235. package/lib/interfaces/gt-config-total.d.ts +0 -8
  236. package/lib/interfaces/gt-config.d.ts +0 -12
  237. package/lib/interfaces/gt-event.d.ts +0 -4
  238. package/lib/interfaces/gt-information.d.ts +0 -15
  239. package/lib/interfaces/gt-options.d.ts +0 -27
  240. package/lib/interfaces/gt-render-field.d.ts +0 -19
  241. package/lib/interfaces/gt-row-meta.d.ts +0 -5
  242. package/lib/interfaces/gt-row.d.ts +0 -6
  243. package/lib/interfaces/gt-texts.d.ts +0 -14
  244. package/lib/pipes/gt-chunk.pipe.d.ts +0 -8
  245. package/lib/pipes/gt-column-class.pipe.d.ts +0 -6
  246. package/lib/pipes/gt-filter.pipe.d.ts +0 -5
  247. package/lib/pipes/gt-highlight.pipe.d.ts +0 -7
  248. package/lib/pipes/gt-is-editable.pipe.d.ts +0 -4
  249. package/lib/pipes/gt-is-observable.pipe.d.ts +0 -4
  250. package/lib/pipes/gt-meta.pipe.d.ts +0 -5
  251. package/lib/pipes/gt-order-by.pipe.d.ts +0 -11
  252. package/lib/pipes/gt-property.pipe.d.ts +0 -7
  253. package/lib/pipes/gt-render.pipe.d.ts +0 -19
  254. package/lib/pipes/gt-row-class.pipe.d.ts +0 -5
  255. package/lib/pipes/gt-search.pipe.d.ts +0 -10
  256. package/lib/pipes/gt-totals-position.pipe.d.ts +0 -5
  257. package/lib/pipes/gt-totals.pipe.d.ts +0 -4
  258. package/lib/pipes/gt-visible.pipe.d.ts +0 -9
  259. package/public_api.d.ts +0 -18
  260. package/scss/generic-table.scss +0 -246
@@ -1,3679 +0,0 @@
1
- (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('rxjs'), require('tether'), require('@angular/platform-browser'), require('@angular/common'), require('@angular/forms')) :
3
- typeof define === 'function' && define.amd ? define('@angular-generic-table/core', ['exports', '@angular/core', 'rxjs', 'tether', '@angular/platform-browser', '@angular/common', '@angular/forms'], factory) :
4
- (factory((global['angular-generic-table'] = global['angular-generic-table'] || {}, global['angular-generic-table'].core = {}),global.ng.core,global.rxjs,null,global.ng.platformBrowser,global.ng.common,global.ng.forms));
5
- }(this, (function (exports,core,rxjs,Tether,platformBrowser,common,forms) { 'use strict';
6
-
7
- /**
8
- * @fileoverview added by tsickle
9
- * @suppress {checkTypes} checked by tsc
10
- */
11
- var GtTableInfoComponent = /** @class */ (function () {
12
- function GtTableInfoComponent(_changeDetectionRef) {
13
- this._changeDetectionRef = _changeDetectionRef;
14
- }
15
- /**
16
- * @return {?}
17
- */
18
- GtTableInfoComponent.prototype.ngAfterViewChecked = /**
19
- * @return {?}
20
- */
21
- function () {
22
- this._changeDetectionRef.detectChanges();
23
- };
24
- GtTableInfoComponent.decorators = [
25
- { type: core.Component, args: [{
26
- selector: 'gt-table-info',
27
- template: "\n\t\t<span *ngIf=\"genericTable.gtInfo\">{{(customText? customText:genericTable.gtTexts) | gtTableInfo:\n\t\t\tgenericTable.gtInfo:\n\t\t\tgenericTable.gtInfo.recordsAfterSearch:\n\t\t\tgenericTable.gtInfo.recordFrom:\n\t\t\tgenericTable.gtInfo.recordTo:\n\t\t\tgenericTable.gtInfo.recordsAll:\n\t\t\tgenericTable.gtTexts.loading:\n\t\t\tgenericTable.gtTexts.tableInfoAfterSearch}}</span>\n "
28
- }] }
29
- ];
30
- /** @nocollapse */
31
- GtTableInfoComponent.ctorParameters = function () {
32
- return [
33
- { type: core.ChangeDetectorRef, },
34
- ];
35
- };
36
- GtTableInfoComponent.propDecorators = {
37
- "genericTable": [{ type: core.Input },],
38
- "customText": [{ type: core.Input },],
39
- };
40
- return GtTableInfoComponent;
41
- }());
42
- var TableInfoPipe = /** @class */ (function () {
43
- function TableInfoPipe() {
44
- }
45
- /**
46
- * @param {?} texts
47
- * @param {?} keys
48
- * @param {?} recordsAfterSearch
49
- * @param {?} recordFrom
50
- * @param {?} recordTo
51
- * @param {?} recordsAll
52
- * @param {?} loading
53
- * @param {?} tableInfoAfterSearch
54
- * @return {?}
55
- */
56
- TableInfoPipe.prototype.transform = /**
57
- * @param {?} texts
58
- * @param {?} keys
59
- * @param {?} recordsAfterSearch
60
- * @param {?} recordFrom
61
- * @param {?} recordTo
62
- * @param {?} recordsAll
63
- * @param {?} loading
64
- * @param {?} tableInfoAfterSearch
65
- * @return {?}
66
- */
67
- function (texts, keys, recordsAfterSearch, recordFrom, recordTo, recordsAll, loading, tableInfoAfterSearch) {
68
- var /** @type {?} */ text = typeof texts === 'object' ? texts.tableInfo : '';
69
- if (keys.recordsAfterSearch !== keys.recordsAll) {
70
- text = typeof texts === 'object' ? texts.tableInfoAfterSearch : '';
71
- }
72
- for (var /** @type {?} */ key in keys) {
73
- if (keys.hasOwnProperty(key)) {
74
- var /** @type {?} */ searchString = new RegExp('#' + key, 'g');
75
- text = text.replace(searchString, keys[key]);
76
- }
77
- }
78
- return text;
79
- };
80
- TableInfoPipe.decorators = [
81
- { type: core.Pipe, args: [{
82
- name: 'gtTableInfo'
83
- },] }
84
- ];
85
- return TableInfoPipe;
86
- }());
87
-
88
- /**
89
- * @fileoverview added by tsickle
90
- * @suppress {checkTypes} checked by tsc
91
- */
92
- var GtPaginationComponent = /** @class */ (function () {
93
- function GtPaginationComponent() {
94
- this.ready = false;
95
- }
96
- Object.defineProperty(GtPaginationComponent.prototype, "genericTable", {
97
- get: /**
98
- * @return {?}
99
- */ function () {
100
- return this._genericTable;
101
- },
102
- set: /**
103
- * @param {?} value
104
- * @return {?}
105
- */ function (value) {
106
- var _this = this;
107
- if (value) {
108
- value.gtEvent.subscribe(function (res) {
109
- if (res.name === 'gt-info' && res.value.pageTotal > 0) {
110
- _this.ready = true;
111
- }
112
- });
113
- }
114
- this._genericTable = value;
115
- },
116
- enumerable: true,
117
- configurable: true
118
- });
119
- GtPaginationComponent.decorators = [
120
- { type: core.Component, args: [{
121
- selector: 'gt-pagination',
122
- template: "\n\t\t<nav class=\"gt-pagination\" aria-label=\"Table navigation\" *ngIf=\"genericTable && genericTable.gtInfo && ready && genericTable.gtData?.length > 0\" [ngClass]=\"{'no-data':genericTable.gtInfo.pageTotal === 0}\">\n\t\t\t<ul class=\"pagination\" [ngClass]=\"gtClasses\">\n\t\t\t\t<li class=\"page-item\" [ngClass]=\"{'disabled' : genericTable.gtInfo.pageCurrent === 1 || genericTable.loading }\"><a class=\"page-link\" href=\"javascript:void(0);\" (click)=\"genericTable.gtInfo.pageCurrent > 1 && genericTable.previousPage()\" [attr.aria-label]=\"genericTable.gtTexts.paginatePrevious\"><span aria-hidden=\"true\">&laquo;</span><span class=\"sr-only\">{{genericTable.gtTexts.paginatePrevious}}</span></a></li>\n\t\t\t\t<li class=\"page-item\" [ngClass]=\"{'disabled' : genericTable.loading && genericTable.gtInfo.pageCurrent !== page, 'active' : genericTable.gtInfo.pageCurrent === page }\" *ngFor=\"let page of genericTable.gtInfo.pageTotal | gtPaginationPipe:genericTable.gtInfo.pageCurrent\"><a class=\"page-link\" [tabindex]=\"page === true ? -1:0\" href=\"javascript:void(0);\" (click)=\"page === true ? '':genericTable.goToPage(page)\">{{page === true ? '&hellip;':page}}</a></li>\n\t\t\t\t<li class=\"page-item\" [ngClass]=\"{'disabled' : genericTable.gtInfo.pageCurrent === genericTable.gtInfo.pageTotal || genericTable.loading }\"><a class=\"page-link gt-link\" href=\"javascript:void(0);\" (click)=\"genericTable.gtInfo.pageCurrent !== genericTable.gtInfo.pageTotal && genericTable.nextPage()\" [attr.aria-label]=\"genericTable.gtTexts.paginateNext\"><span aria-hidden=\"true\">&raquo;</span><span class=\"sr-only\">{{genericTable.gtTexts.paginateNext}}</span></a></li>\n\t\t\t</ul>\n\t\t</nav>\n ",
123
- styles: [".gt-link {cursor: pointer;}"]
124
- }] }
125
- ];
126
- /** @nocollapse */
127
- GtPaginationComponent.propDecorators = {
128
- "genericTable": [{ type: core.Input },],
129
- "gtClasses": [{ type: core.Input },],
130
- };
131
- return GtPaginationComponent;
132
- }());
133
- var PaginationPipe = /** @class */ (function () {
134
- function PaginationPipe() {
135
- }
136
- /**
137
- * @param {?} totalPages
138
- * @param {?} currentPage
139
- * @return {?}
140
- */
141
- PaginationPipe.prototype.transform = /**
142
- * @param {?} totalPages
143
- * @param {?} currentPage
144
- * @return {?}
145
- */
146
- function (totalPages, currentPage) {
147
- if (totalPages === 0) {
148
- return [1];
149
- }
150
- var /** @type {?} */ pagination = []; // create new empty array for pagination
151
- var /** @type {?} */ siblings = 2; // sibling elements ie. number of elements on each side of current page
152
- var /** @type {?} */ paginationLength = totalPages < siblings * 2 + 1 ? totalPages : siblings * 2 + 1; // number of elements in pagination array
153
- var /** @type {?} */ start = currentPage <= siblings ? 1 : currentPage - siblings; // starting position for array
154
- var /** @type {?} */ modifier = totalPages - (currentPage + siblings) <= 0
155
- ? totalPages - (currentPage + siblings)
156
- : 0; // modifier for pagination values
157
- var /** @type {?} */ modifiedPosition = start + modifier <= 0 ? 1 : start + modifier;
158
- // push pages to pagination array
159
- for (var /** @type {?} */ i = 0; i < paginationLength; i++) {
160
- pagination.push(modifiedPosition + i);
161
- }
162
- // if first page is not included in pagination...
163
- if (pagination.indexOf(1) === -1) {
164
- // ...check if second page is in pagination...
165
- if (pagination.indexOf(2) === -1) {
166
- // ...if not check if total number of pages equals seven and number of siblings are two...
167
- if (totalPages === 7 && siblings === 2) {
168
- // ...add second page and don't convert page number to ellipsis
169
- pagination.unshift(2);
170
- }
171
- else {
172
- // ...if not, use this placeholder for ellipsis instead of actual page number
173
- pagination[0] = true;
174
- }
175
- }
176
- // ...add first page as first array item
177
- pagination.unshift(1);
178
- }
179
- else if (totalPages > paginationLength) {
180
- // if first page is included add extra page to keep number of items consistent
181
- pagination.splice(paginationLength, 0, paginationLength + 1);
182
- }
183
- // check if last page is included in pagination...
184
- if (pagination.indexOf(totalPages) === -1) {
185
- // ...if not, page next to last should either show ellipsis or actual page number for the page
186
- pagination[pagination.length - 1] =
187
- pagination[pagination.length - 1] === totalPages - 1
188
- ? totalPages - 1
189
- : true;
190
- // ...add last page to pagination
191
- pagination.push(totalPages);
192
- }
193
- return pagination;
194
- };
195
- PaginationPipe.decorators = [
196
- { type: core.Pipe, args: [{
197
- name: 'gtPaginationPipe'
198
- },] }
199
- ];
200
- return PaginationPipe;
201
- }());
202
-
203
- /**
204
- * @fileoverview added by tsickle
205
- * @suppress {checkTypes} checked by tsc
206
- */
207
- // unsupported: template constraints.
208
- /**
209
- * @template R
210
- */
211
- var
212
- // unsupported: template constraints.
213
- /**
214
- * @template R
215
- */
216
- GtExpandedRow = /** @class */ (function () {
217
- function GtExpandedRow() {
218
- this.redrawEvent = new core.EventEmitter();
219
- this.toggleRowEvent = new core.EventEmitter();
220
- }
221
- /**
222
- * @return {?}
223
- */
224
- GtExpandedRow.prototype.$hide = /**
225
- * @return {?}
226
- */
227
- function () {
228
- this.toggleRowEvent.emit(this.row);
229
- };
230
- /**
231
- * @param {?=} $event
232
- * @return {?}
233
- */
234
- GtExpandedRow.prototype.$redraw = /**
235
- * @param {?=} $event
236
- * @return {?}
237
- */
238
- function ($event) {
239
- this.redrawEvent.emit(this.row);
240
- };
241
- /**
242
- * @param {?} row
243
- * @param {?} $event
244
- * @return {?}
245
- */
246
- GtExpandedRow.prototype.$rowClick = /**
247
- * @param {?} row
248
- * @param {?} $event
249
- * @return {?}
250
- */
251
- function (row, $event) {
252
- this.gtEvent.emit({
253
- name: 'gt-row-clicked',
254
- value: { row: row, event: $event }
255
- });
256
- };
257
- return GtExpandedRow;
258
- }());
259
- // unsupported: template constraints.
260
- // unsupported: template constraints.
261
- /**
262
- * @template R, C
263
- */
264
- var GtExpandingRowComponent = /** @class */ (function () {
265
- function GtExpandingRowComponent() {
266
- this.redrawEvent = new core.EventEmitter();
267
- this.toggleRowEvent = new core.EventEmitter();
268
- }
269
- /**
270
- * @param {?} instance
271
- * @return {?}
272
- */
273
- GtExpandingRowComponent.prototype.newInstance = /**
274
- * @param {?} instance
275
- * @return {?}
276
- */
277
- function (instance) {
278
- instance.row = this.row;
279
- instance.columnWidth = this.columnWidth;
280
- instance.gtSettings = this.gtSettings;
281
- instance.gtFields = this.gtFields;
282
- instance.gtOptions = this.gtOptions;
283
- instance.gtInfo = this.gtInfo;
284
- instance.data =
285
- typeof this.data === 'function' ? this.data(this.row) : this.data;
286
- instance.redrawEvent.subscribe(this.redrawEvent);
287
- instance.toggleRowEvent.subscribe(this.toggleRowEvent);
288
- instance.gtEvent = this.gtEvent;
289
- };
290
- GtExpandingRowComponent.decorators = [
291
- { type: core.Component, args: [{
292
- selector: 'gt-expanding-row',
293
- template: "\n\t\t<div gtComponentAnchor\n\t\t\t [ctor]=\"type\" (instance)=\"newInstance($event)\"></div>\n "
294
- }] }
295
- ];
296
- /** @nocollapse */
297
- GtExpandingRowComponent.propDecorators = {
298
- "type": [{ type: core.Input },],
299
- "row": [{ type: core.Input },],
300
- "columnWidth": [{ type: core.Input },],
301
- "gtSettings": [{ type: core.Input },],
302
- "gtFields": [{ type: core.Input },],
303
- "gtOptions": [{ type: core.Input },],
304
- "gtInfo": [{ type: core.Input },],
305
- "data": [{ type: core.Input },],
306
- "redrawEvent": [{ type: core.Output },],
307
- "toggleRowEvent": [{ type: core.Output },],
308
- "gtEvent": [{ type: core.Input },],
309
- };
310
- return GtExpandingRowComponent;
311
- }());
312
-
313
- /**
314
- * @fileoverview added by tsickle
315
- * @suppress {checkTypes} checked by tsc
316
- */
317
- var GtDropdownComponent = /** @class */ (function () {
318
- function GtDropdownComponent(renderer) {
319
- this.renderer = renderer;
320
- this.selectedChange = new core.EventEmitter();
321
- this.active = false; // is dropdown active or not
322
- this.state = new rxjs.Subject(); // current state of dropdown
323
- }
324
- Object.defineProperty(GtDropdownComponent.prototype, "selected", {
325
- get: /**
326
- * @return {?}
327
- */ function () {
328
- return this._selected;
329
- },
330
- set: /**
331
- * @param {?} selection
332
- * @return {?}
333
- */ function (selection) {
334
- this._selected = selection;
335
- },
336
- enumerable: true,
337
- configurable: true
338
- });
339
- /**
340
- * @param {?} option
341
- * @return {?}
342
- */
343
- GtDropdownComponent.prototype.select = /**
344
- * @param {?} option
345
- * @return {?}
346
- */
347
- function (option) {
348
- this.active = false;
349
- this.state.next(this.active);
350
- if (this._selected !== option) {
351
- this.selectedChange.emit(option);
352
- }
353
- };
354
- /**
355
- * @return {?}
356
- */
357
- GtDropdownComponent.prototype.toggleDropdown = /**
358
- * @return {?}
359
- */
360
- function () {
361
- var _this = this;
362
- this.active = !this.active;
363
- setTimeout(function () {
364
- _this.state.next(_this.active);
365
- }, 0);
366
- };
367
- /**
368
- * @return {?}
369
- */
370
- GtDropdownComponent.prototype.ngOnInit = /**
371
- * @return {?}
372
- */
373
- function () {
374
- var _this = this;
375
- this.state.subscribe(function (state) {
376
- if (state) {
377
- _this.tether = new Tether({
378
- element: '#' + _this.id + '_menu',
379
- target: '#' + _this.id,
380
- attachment: 'top left',
381
- targetAttachment: 'bottom left',
382
- constraints: [
383
- {
384
- to: 'window',
385
- attachment: 'together'
386
- }
387
- ]
388
- });
389
- _this.tether.position();
390
- // set up click listener and listen for click outside dropdown
391
- _this.clickListener = _this.renderer.listen('document', 'click', function (event) {
392
- _this.active = false;
393
- _this.state.next(_this.active);
394
- });
395
- // set up keyboard listener and listen for escape key up
396
- _this.keyupListener = _this.renderer.listen('document', 'keyup', function (event) {
397
- switch (event.key) {
398
- case 'Escape':
399
- _this.active = false;
400
- _this.state.next(_this.active);
401
- break;
402
- }
403
- });
404
- }
405
- else {
406
- _this.tether.destroy();
407
- _this.removeListeners();
408
- }
409
- });
410
- };
411
- /**
412
- * @return {?}
413
- */
414
- GtDropdownComponent.prototype.ngOnDestroy = /**
415
- * @return {?}
416
- */
417
- function () {
418
- this.removeListeners();
419
- };
420
- /**
421
- * @return {?}
422
- */
423
- GtDropdownComponent.prototype.removeListeners = /**
424
- * @return {?}
425
- */
426
- function () {
427
- if (this.clickListener) {
428
- this.clickListener();
429
- }
430
- if (this.keyupListener) {
431
- this.keyupListener();
432
- }
433
- };
434
- GtDropdownComponent.decorators = [
435
- { type: core.Component, args: [{
436
- selector: 'gt-dropdown',
437
- template: "\n\t\t<div class=\"dropdown gt-dropdown\" [ngClass]=\"{'show':active}\" [attr.id]=\"id\">\n\t\t\t<div class=\"dropdown-toggle\" (click)=\"toggleDropdown()\" [attr.aria-expanded]=\"active\">{{selected}}</div>\n\t\t\t<div class=\"gt-dropdown-menu dropdown-menu\" *ngIf=\"active\" [ngClass]=\"{'show':active}\" [attr.id]=\"id+'_menu'\">\n\t\t\t\t<button *ngFor=\"let option of options;\" class=\"dropdown-item\" (click)=\"select(option)\" [ngClass]=\"{'active':option === selected}\">{{option}}</button>\n\t\t\t</div>\n\t\t</div>\n ",
438
- styles: ["\n\t\t.gt-dropdown .dropdown-toggle {\n\t\t\tcursor: pointer;\n\t\t}\n\t\t.gt-dropdown .dropdown-toggle::after {\n\t\t\ttransition: opacity 0.4s ease-in-out;\n\t\t\topacity: 0;\n\t\t}\n\t\t.gt-dropdown .dropdown-toggle:hover::after {\n\t\t\topacity: 1;\n\t\t}\n\t"]
439
- }] }
440
- ];
441
- /** @nocollapse */
442
- GtDropdownComponent.ctorParameters = function () {
443
- return [
444
- { type: core.Renderer2, },
445
- ];
446
- };
447
- GtDropdownComponent.propDecorators = {
448
- "selected": [{ type: core.Input },],
449
- "options": [{ type: core.Input },],
450
- "id": [{ type: core.Input },],
451
- "selectedChange": [{ type: core.Output },],
452
- };
453
- return GtDropdownComponent;
454
- }());
455
-
456
- /*! *****************************************************************************
457
- Copyright (c) Microsoft Corporation. All rights reserved.
458
- Licensed under the Apache License, Version 2.0 (the "License"); you may not use
459
- this file except in compliance with the License. You may obtain a copy of the
460
- License at http://www.apache.org/licenses/LICENSE-2.0
461
-
462
- THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
463
- KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
464
- WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
465
- MERCHANTABLITY OR NON-INFRINGEMENT.
466
-
467
- See the Apache Version 2.0 License for specific language governing permissions
468
- and limitations under the License.
469
- ***************************************************************************** */
470
- /* global Reflect, Promise */
471
- var extendStatics = function (d, b) {
472
- extendStatics = Object.setPrototypeOf ||
473
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
474
- function (d, b) { for (var p in b)
475
- if (b.hasOwnProperty(p))
476
- d[p] = b[p]; };
477
- return extendStatics(d, b);
478
- };
479
- function __extends(d, b) {
480
- extendStatics(d, b);
481
- function __() { this.constructor = d; }
482
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
483
- }
484
- var __assign = function () {
485
- __assign = Object.assign || function __assign(t) {
486
- for (var s, i = 1, n = arguments.length; i < n; i++) {
487
- s = arguments[i];
488
- for (var p in s)
489
- if (Object.prototype.hasOwnProperty.call(s, p))
490
- t[p] = s[p];
491
- }
492
- return t;
493
- };
494
- return __assign.apply(this, arguments);
495
- };
496
- function __read(o, n) {
497
- var m = typeof Symbol === "function" && o[Symbol.iterator];
498
- if (!m)
499
- return o;
500
- var i = m.call(o), r, ar = [], e;
501
- try {
502
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done)
503
- ar.push(r.value);
504
- }
505
- catch (error) {
506
- e = { error: error };
507
- }
508
- finally {
509
- try {
510
- if (r && !r.done && (m = i["return"]))
511
- m.call(i);
512
- }
513
- finally {
514
- if (e)
515
- throw e.error;
516
- }
517
- }
518
- return ar;
519
- }
520
- function __spread() {
521
- for (var ar = [], i = 0; i < arguments.length; i++)
522
- ar = ar.concat(__read(arguments[i]));
523
- return ar;
524
- }
525
-
526
- /**
527
- * @fileoverview added by tsickle
528
- * @suppress {checkTypes} checked by tsc
529
- */
530
- var GtDrilldownComponent = /** @class */ (function (_super) {
531
- __extends(GtDrilldownComponent, _super);
532
- function GtDrilldownComponent() {
533
- return _super.call(this) || this;
534
- }
535
- /**
536
- * @return {?}
537
- */
538
- GtDrilldownComponent.prototype.ngOnInit = /**
539
- * @return {?}
540
- */
541
- function () { };
542
- GtDrilldownComponent.decorators = [
543
- { type: core.Component, args: [{
544
- selector: 'gt-drilldown',
545
- template: "\n\t\t<table class=\"table\">\n\t\t\t<tr *ngFor=\"let row of data\" (click)=\"$rowClick(row, $event)\">\n\t\t\t\t<td *ngFor=\"let column of row | gtRender:gtSettings:gtFields:null:null:gtOptions.highlightSearch:gtInfo.searchTerms;\"\n\t\t\t\t\tngClass=\"{{column.objectKey +'-column' | dashCase}} {{gtFields | gtProperty:column.objectKey:'classNames'}} {{(gtFields | gtProperty:column.objectKey:'inlineEdit') ? 'gt-inline-edit':''}} {{column.edited ? 'gt-edited':''}} {{ gtFields | gtColumnClass:row:column }}\" [style.width]=\"columnWidth[column.objectKey]\" [style.max-width]=\"columnWidth[column.objectKey]\">\n <span class=\"gt-row-label\"\n\t\t\t\t\t\t\t *ngIf=\"gtOptions.stack\">{{(gtFields | gtProperty:column.objectKey:'stackedHeading') ? (gtFields | gtProperty:column.objectKey:'stackedHeading') : (gtFields | gtProperty:column.objectKey:'name')}}</span>\n\t\t\t\t\t<gt-custom-component-factory *ngIf=\"column.columnComponent\" class=\"gt-row-content\"\n\t\t\t\t\t\t\t\t\t\t\t\t [type]=\"column.columnComponent.type\"\n\t\t\t\t\t\t\t\t\t\t\t\t [injector]=\"column.columnComponent.injector\" [row]=\"row\"\n\t\t\t\t\t\t\t\t\t\t\t\t [column]=\"column\" (redrawEvent)=\"$redraw($event)\"\n\t\t\t\t\t\t\t\t\t\t\t\t (click)=\"column.click ? column.click(row,column,$event):'';\"></gt-custom-component-factory>\n\t\t\t\t\t<span *ngIf=\"!column.columnComponent\"\n\t\t\t\t\t\t class=\"gt-row-content\" [innerHTML]=\"column.renderValue\"\n\t\t\t\t\t\t (click)=\"column.click ? column.click(row,column,$event):''\"></span>\n\t\t\t\t</td>\n\n\t\t\t</tr>\n\t\t</table>\n "
546
- }] }
547
- ];
548
- /** @nocollapse */
549
- GtDrilldownComponent.ctorParameters = function () { return []; };
550
- return GtDrilldownComponent;
551
- }(GtExpandedRow));
552
-
553
- /**
554
- * @fileoverview added by tsickle
555
- * @suppress {checkTypes} checked by tsc
556
- */
557
- /**
558
- * @abstract
559
- * @template R
560
- */
561
- var /**
562
- * @abstract
563
- * @template R
564
- */ GtCustomComponent = /** @class */ (function () {
565
- function GtCustomComponent() {
566
- this.redrawEvent = new core.EventEmitter();
567
- this.$searchTerms = new rxjs.ReplaySubject(1);
568
- }
569
- /**
570
- * @param {?=} $event
571
- * @return {?}
572
- */
573
- GtCustomComponent.prototype.$redraw = /**
574
- * @param {?=} $event
575
- * @return {?}
576
- */
577
- function ($event) {
578
- this.redrawEvent.emit({ row: this.row, column: this.column });
579
- };
580
- /**
581
- * @return {?}
582
- */
583
- GtCustomComponent.prototype.ngOnInit = /**
584
- * @return {?}
585
- */
586
- function () {
587
- var _this = this;
588
- this.$searchTerms.subscribe(function (terms) { return (_this.searchTerms = terms); });
589
- };
590
- return GtCustomComponent;
591
- }());
592
- // unsupported: template constraints.
593
- /**
594
- * @template R, C
595
- */
596
- var GtCustomComponentFactory = /** @class */ (function () {
597
- function GtCustomComponentFactory() {
598
- this.$searchTerms = new rxjs.ReplaySubject(1);
599
- this.redrawEvent = new core.EventEmitter();
600
- }
601
- Object.defineProperty(GtCustomComponentFactory.prototype, "searchTerms", {
602
- set: /**
603
- * @param {?} value
604
- * @return {?}
605
- */ function (value) {
606
- this.$searchTerms.next(value);
607
- },
608
- enumerable: true,
609
- configurable: true
610
- });
611
- /**
612
- * @param {?} instance
613
- * @return {?}
614
- */
615
- GtCustomComponentFactory.prototype.instance = /**
616
- * @param {?} instance
617
- * @return {?}
618
- */
619
- function (instance) {
620
- instance.row = this.row;
621
- instance.column = this.column;
622
- instance.$searchTerms = this.$searchTerms;
623
- instance.redrawEvent.subscribe(this.redrawEvent);
624
- };
625
- GtCustomComponentFactory.decorators = [
626
- { type: core.Component, args: [{
627
- selector: 'gt-custom-component-factory',
628
- template: "\n\t\t<div gtComponentAnchor [ctor]=\"type\"\n\t\t\t [injector]=\"injector\"\n\t\t\t (instance)=\"instance($event)\"></div>\n\t"
629
- }] }
630
- ];
631
- /** @nocollapse */
632
- GtCustomComponentFactory.propDecorators = {
633
- "searchTerms": [{ type: core.Input },],
634
- "type": [{ type: core.Input },],
635
- "injector": [{ type: core.Input },],
636
- "row": [{ type: core.Input },],
637
- "column": [{ type: core.Input },],
638
- "redrawEvent": [{ type: core.Output },],
639
- };
640
- return GtCustomComponentFactory;
641
- }());
642
-
643
- /**
644
- * @fileoverview added by tsickle
645
- * @suppress {checkTypes} checked by tsc
646
- */
647
- var GtCheckboxComponent = /** @class */ (function () {
648
- function GtCheckboxComponent() {
649
- this.class = 'd-flex justify-content-end';
650
- this.changed = new core.EventEmitter();
651
- }
652
- Object.defineProperty(GtCheckboxComponent.prototype, "initialValue", {
653
- get: /**
654
- * @return {?}
655
- */ function () {
656
- return this._initialValue;
657
- },
658
- set: /**
659
- * @param {?} value
660
- * @return {?}
661
- */ function (value) {
662
- this._initialValue = value;
663
- },
664
- enumerable: true,
665
- configurable: true
666
- });
667
- Object.defineProperty(GtCheckboxComponent.prototype, "checked", {
668
- get: /**
669
- * @return {?}
670
- */ function () {
671
- return this._checked;
672
- },
673
- set: /**
674
- * @param {?} value
675
- * @return {?}
676
- */ function (value) {
677
- this._checked = value;
678
- },
679
- enumerable: true,
680
- configurable: true
681
- });
682
- /**
683
- * @return {?}
684
- */
685
- GtCheckboxComponent.prototype.ngOnInit = /**
686
- * @return {?}
687
- */
688
- function () { };
689
- /**
690
- * @param {?} checked
691
- * @return {?}
692
- */
693
- GtCheckboxComponent.prototype.toggle = /**
694
- * @param {?} checked
695
- * @return {?}
696
- */
697
- function (checked) {
698
- this.changed.emit(this.checked);
699
- };
700
- GtCheckboxComponent.decorators = [
701
- { type: core.Component, args: [{
702
- selector: 'gt-checkbox',
703
- template: "\n\t\t<label class=\"custom-control custom-checkbox p-0\" (click)=\"$event.stopPropagation()\">\n\t\t\t<input #checkbox type=\"checkbox\" class=\"custom-control-input\" [(checked)]=\"checked\" (change)=\"toggle($event);\">\n\t\t\t<span class=\"custom-control-label\"></span>\n\t\t</label>\n "
704
- }] }
705
- ];
706
- /** @nocollapse */
707
- GtCheckboxComponent.ctorParameters = function () { return []; };
708
- GtCheckboxComponent.propDecorators = {
709
- "class": [{ type: core.HostBinding, args: ['class',] },],
710
- "initialValue": [{ type: core.Input },],
711
- "checked": [{ type: core.Input },],
712
- "changed": [{ type: core.Output },],
713
- };
714
- return GtCheckboxComponent;
715
- }());
716
-
717
- /**
718
- * @fileoverview added by tsickle
719
- * @suppress {checkTypes} checked by tsc
720
- */
721
- var GtMetaPipe = /** @class */ (function () {
722
- function GtMetaPipe() {
723
- }
724
- /**
725
- * @param {?} allRows
726
- * @param {?=} rowIndex
727
- * @param {?=} page
728
- * @param {?=} recordLength
729
- * @return {?}
730
- */
731
- GtMetaPipe.prototype.transform = /**
732
- * @param {?} allRows
733
- * @param {?=} rowIndex
734
- * @param {?=} page
735
- * @param {?=} recordLength
736
- * @return {?}
737
- */
738
- function (allRows, rowIndex, page, recordLength) {
739
- for (var /** @type {?} */ i = 0; i < allRows.length; i++) {
740
- if (!allRows[i].$$gtRowId) {
741
- allRows[i].$$gtRowId = rowIndex
742
- ? allRows[i][rowIndex]
743
- : page
744
- ? page * recordLength +
745
- i +
746
- '_' +
747
- Math.random()
748
- .toString(36)
749
- .substr(2, 16)
750
- : i +
751
- '_' +
752
- Math.random()
753
- .toString(36)
754
- .substr(2, 16);
755
- }
756
- if (!allRows[i].$$gtInitialRowIndex) {
757
- allRows[i].$$gtInitialRowIndex = i;
758
- }
759
- }
760
- return allRows;
761
- };
762
- GtMetaPipe.decorators = [
763
- { type: core.Pipe, args: [{
764
- name: 'gtMeta'
765
- },] }
766
- ];
767
- return GtMetaPipe;
768
- }());
769
-
770
- /**
771
- * @fileoverview added by tsickle
772
- * @suppress {checkTypes} checked by tsc
773
- */
774
- // unsupported: template constraints.
775
- // unsupported: template constraints.
776
- /**
777
- * @template R, C
778
- */
779
- var GenericTableComponent = /** @class */ (function () {
780
- function GenericTableComponent(renderer, gtMetaPipe) {
781
- var _this = this;
782
- this.renderer = renderer;
783
- this.gtMetaPipe = gtMetaPipe;
784
- this.columnWidth = {};
785
- this.sortOrder = [];
786
- this.metaInfo = {};
787
- this.selectedRows = [];
788
- this.openRows = [];
789
- this._gtSettings = [];
790
- this._gtFields = [];
791
- this.gtDefaultTexts = {
792
- loading: 'Loading...',
793
- noData: 'No data',
794
- noMatchingData: 'No data matching results found',
795
- noVisibleColumnsHeading: 'No visible columns',
796
- noVisibleColumns: 'Please select at least one column to be visible.',
797
- tableInfo: 'Showing #recordFrom to #recordTo of #recordsAfterSearch entries.',
798
- tableInfoAfterSearch: 'Showing #recordFrom to #recordTo of #recordsAfterSearch entries (filtered from a total of #recordsAll entries).',
799
- csvDownload: 'download',
800
- sortLabel: 'Sort:',
801
- paginateNext: 'Next page',
802
- paginatePrevious: 'Previous page',
803
- inlineEditEdited: 'Press enter to save'
804
- };
805
- this.gtTexts = this.gtDefaultTexts;
806
- this.gtEvent = new core.EventEmitter();
807
- this.gtDefaultOptions = {
808
- csvDelimiter: ';',
809
- stack: false,
810
- lazyLoad: false,
811
- cache: false,
812
- debounceTime: 200,
813
- highlightSearch: false,
814
- rowSelection: false,
815
- rowSelectionAllowMultiple: true,
816
- rowExpandAllowMultiple: true,
817
- numberOfRows: 10,
818
- reportColumnWidth: false,
819
- allowUnsorted: true,
820
- mutateData: true
821
- };
822
- this._gtOptions = this.gtDefaultOptions;
823
- this.store = [];
824
- this.loading = true;
825
- this.debounceTimer = null;
826
- this.lazyAllSelected = false;
827
- this.gtInfo = {
828
- pageCurrent: 1,
829
- pageTotal: 0,
830
- recordFrom: 0,
831
- recordTo: 0,
832
- recordLength: this.gtOptions.numberOfRows,
833
- recordsAll: 0,
834
- recordsAfterFilter: 0,
835
- recordsAfterSearch: 0
836
- };
837
- this.refreshPipe = false;
838
- this.refreshTotals = false;
839
- this.refreshSorting = false;
840
- this.refreshFilter = false;
841
- this.refreshPageArray = false;
842
- this.editedRows = {};
843
- this.data = { exportData: [] };
844
- /**
845
- * Sort table by object key.
846
- * @param objectKey - name of key to sort on.
847
- * @param event - such as key press during sorting.
848
- */
849
- this.gtSort = function (objectKey, event) {
850
- this.inlineEditCancel(); // cancel inline editing
851
- // loop through current settings
852
- for (var /** @type {?} */ i = 0; i < this._gtSettings.length; i++) {
853
- if (this._gtSettings[i].objectKey === objectKey) {
854
- // check if sorting is disabled...
855
- if (this._gtSettings[i].sort &&
856
- this._gtSettings[i].sort.indexOf('disable') !== -1) {
857
- // ...if so, exit function without applying any sorting
858
- return;
859
- }
860
- else if ( /* check if sorting is undefined... */typeof this._gtSettings[i]
861
- .sort === 'undefined') {
862
- // ...is so, set sorting property to enable
863
- this._gtSettings[i].sort = 'enable';
864
- }
865
- }
866
- }
867
- // check length
868
- var /** @type {?} */ ctrlKey = event.metaKey || event.ctrlKey;
869
- var /** @type {?} */ sort = this.sortOrder.slice(0);
870
- var /** @type {?} */ match = -1;
871
- var /** @type {?} */ matchDesc = -1;
872
- var /** @type {?} */ pos = -1;
873
- // check if property already exits
874
- for (var /** @type {?} */ i = 0; i < sort.length; i++) {
875
- var /** @type {?} */ hit = sort[i].indexOf(objectKey);
876
- if (hit !== -1) {
877
- match = this.sortOrder.indexOf(objectKey);
878
- matchDesc =
879
- match === -1 ? this.sortOrder.indexOf('-' + objectKey) : match;
880
- pos = Math.max(match, matchDesc);
881
- }
882
- }
883
- // if ctrl key or meta key is press together with sort...
884
- if (ctrlKey) {
885
- if (this.sortOrder[this.sortOrder.length - 1] === '$$gtInitialRowIndex') {
886
- this.sortOrder.pop();
887
- }
888
- switch (pos) {
889
- // ...and property is not sorted before...
890
- case -1:
891
- // ...add property to sorting
892
- this.sortOrder.push(objectKey);
893
- break;
894
- default:
895
- // ...and property is sorted before...
896
- if (match !== -1) {
897
- // ...change from asc to desc if sorted asc
898
- this.sortOrder[pos] = '-' + objectKey;
899
- }
900
- else if (this.sortOrder.length > 1) {
901
- // ...remove sorting if sorted desc
902
- if (ctrlKey) {
903
- this.sortOrder[pos] = objectKey;
904
- }
905
- else {
906
- this.sortOrder.splice(pos, 1);
907
- }
908
- }
909
- else if (this.sortOrder.length === 1) {
910
- // ...set sorting to asc if only sorted property
911
- this.sortOrder[pos] = objectKey;
912
- }
913
- break;
914
- }
915
- }
916
- else {
917
- /* if ctrl key or meta key is not press together with sort... */
918
- switch (pos) {
919
- // ...and property is not sorted before...
920
- case -1:
921
- // ...sort by property
922
- this.sortOrder = [objectKey];
923
- break;
924
- default:
925
- // ...change from desc to asc and vise versa
926
- this.sortOrder =
927
- match !== -1
928
- ? ['-' + objectKey]
929
- : ctrlKey || !this.gtOptions.allowUnsorted
930
- ? [objectKey]
931
- : [];
932
- break;
933
- }
934
- }
935
- // update settings object with new sorting information
936
- for (var /** @type {?} */ i = 0; i < this._gtSettings.length; i++) {
937
- if (this._gtSettings[i].objectKey === objectKey) {
938
- switch (this._gtSettings[i].sort) {
939
- // if sorted asc...
940
- case 'asc':
941
- // ...change to desc
942
- this._gtSettings[i].sort = 'desc';
943
- break;
944
- // if sorted desc...
945
- case 'desc':
946
- // ...change to asc if it's the only sorted property otherwise remove sorting
947
- this._gtSettings[i].sort =
948
- (this.sortOrder.length === 1 && sort.length < 2) ||
949
- ctrlKey ||
950
- !this.gtOptions.allowUnsorted
951
- ? 'asc'
952
- : 'enable';
953
- break;
954
- // if sorting enabled...
955
- case 'enable':
956
- // ...change to asc
957
- this._gtSettings[i].sort = 'asc';
958
- break;
959
- }
960
- this._gtSettings[i].sortOrder =
961
- this._gtSettings[i].sort === 'enable'
962
- ? this._gtSettings.length - 1
963
- : this.sortOrder.indexOf(objectKey) === -1
964
- ? this.sortOrder.indexOf('-' + objectKey)
965
- : this.sortOrder.indexOf(objectKey);
966
- }
967
- else if (this._gtSettings[i].sort &&
968
- this._gtSettings[i].sort.indexOf('disable') === -1 &&
969
- this.sortOrder.indexOf(this._gtSettings[i].objectKey) === -1 &&
970
- this.sortOrder.indexOf('-' + this._gtSettings[i].objectKey) === -1) {
971
- this._gtSettings[i].sort = 'enable';
972
- this._gtSettings[i].sortOrder = this._gtSettings.length - 1;
973
- }
974
- }
975
- // refresh sorting pipe
976
- this.refreshSorting = !this.refreshSorting;
977
- this.refreshPageArray = !this.refreshPageArray;
978
- // sort by initial sort order as last resort
979
- this.sortOrder.push('$$gtInitialRowIndex');
980
- // emit sort event
981
- this.gtEvent.emit({
982
- name: 'gt-sorting-applied',
983
- value: this.sortOrder
984
- });
985
- };
986
- /**
987
- * Change number of rows to be displayed.
988
- * @param rowLength - total number of rows.
989
- * @param reset - should page be reset to first page.
990
- */
991
- this.changeRowLength = function (rowLength, reset) {
992
- var /** @type {?} */ lengthValue = isNaN(parseInt(rowLength, 10))
993
- ? 0
994
- : parseInt(rowLength, 10);
995
- var /** @type {?} */ newPosition = 1;
996
- if (!lengthValue && this.gtData) {
997
- lengthValue = this.gtData.length;
998
- }
999
- // if reset is not true and we're not lazy loading data...
1000
- if (reset !== true && this._gtOptions.lazyLoad !== true) {
1001
- // ...get current position in record set
1002
- var /** @type {?} */ currentRecord = this.gtInfo.recordLength * (this.gtInfo.pageCurrent - 1);
1003
- var /** @type {?} */ currentPosition = this._gtData.indexOf(this._gtData[currentRecord]) + 1;
1004
- // ...get new position
1005
- newPosition = Math.ceil(currentPosition / lengthValue);
1006
- }
1007
- // change row length
1008
- this.gtInfo.recordLength = lengthValue;
1009
- // go to new position
1010
- this.gtInfo.pageCurrent = newPosition;
1011
- // if lazy loading data...
1012
- if (this._gtOptions.lazyLoad) {
1013
- // ...replace data with place holders for new data
1014
- this._gtData[0] = this.loadingContent(lengthValue);
1015
- // ...empty current store
1016
- this.store = [];
1017
- }
1018
- // this.updateRecordRange();
1019
- this.gtEvent.emit({
1020
- name: 'gt-row-length-changed',
1021
- value: lengthValue
1022
- });
1023
- };
1024
- /**
1025
- * Force a redraw of table rows.
1026
- * As the table uses pure pipes, we need to force a redraw if an object in the array is changed to see the changes.
1027
- */
1028
- this.redraw = function ($event) {
1029
- this.refreshSorting = !this.refreshSorting;
1030
- this.refreshPageArray = !this.refreshPageArray;
1031
- this.refreshPipe = !this.refreshPipe;
1032
- };
1033
- /**
1034
- * Go to next page.
1035
- */
1036
- this.nextPage = function () {
1037
- var /** @type {?} */ page = this.gtInfo.pageCurrent === this.gtInfo.pageTotal
1038
- ? this.gtInfo.pageTotal
1039
- : this.gtInfo.pageCurrent + 1;
1040
- this.goToPage(page);
1041
- };
1042
- /**
1043
- * Go to previous page.
1044
- */
1045
- this.previousPage = function () {
1046
- var /** @type {?} */ page = this.gtInfo.pageCurrent === 1 ? 1 : this.gtInfo.pageCurrent - 1;
1047
- this.goToPage(page);
1048
- };
1049
- /**
1050
- * Request more data (used when lazy loading)
1051
- */
1052
- this.getData = function () {
1053
- // ...emit event requesting for more data
1054
- this.gtEvent.emit({
1055
- name: 'gt-page-changed-lazy',
1056
- value: {
1057
- pageCurrent: this.gtInfo.pageCurrent,
1058
- recordLength: this.gtInfo.recordLength
1059
- }
1060
- });
1061
- };
1062
- /**
1063
- * Go to specific page.
1064
- * @param page - page number.
1065
- */
1066
- this.goToPage = function (page) {
1067
- var _this = this;
1068
- var /** @type {?} */ previousPage = this.gtInfo.pageCurrent;
1069
- this.gtInfo.pageCurrent = page;
1070
- this.inlineEditCancel(); // cancel inline edit
1071
- // if lazy loading and if page contains no records...
1072
- if (this._gtOptions.lazyLoad) {
1073
- // ...if data for current page contains no entries...
1074
- if (this._gtOptions.cache === false ||
1075
- this._gtData[this.gtInfo.pageCurrent - 1].length === 0) {
1076
- // ...create temporary content while waiting for data
1077
- this._gtData[this.gtInfo.pageCurrent - 1] = this.loadingContent(this.gtInfo.recordLength);
1078
- this.loading = true; // loading true
1079
- }
1080
- // ...if first entry in current page equals our loading placeholder...
1081
- if (this._gtData[this.gtInfo.pageCurrent - 1][0][this.loadingProperty] ===
1082
- this.gtTexts.loading) {
1083
- // ...get data
1084
- clearTimeout(this.debounceTimer);
1085
- this.debounceTimer = setTimeout(function () {
1086
- _this.getData();
1087
- }, this._gtOptions.debounceTime);
1088
- }
1089
- }
1090
- // this.updateRecordRange();
1091
- // ...emit page change event
1092
- if (previousPage !== page) {
1093
- this.gtEvent.emit({
1094
- name: 'gt-page-changed',
1095
- value: {
1096
- pageCurrent: this.gtInfo.pageCurrent,
1097
- pagePrevious: previousPage,
1098
- recordLength: this.gtInfo.recordLength
1099
- }
1100
- });
1101
- }
1102
- };
1103
- /**
1104
- * Sort by sort order
1105
- */
1106
- this.getSortOrder = function (a, b) {
1107
- if (a.sortOrder < b.sortOrder) {
1108
- return -1;
1109
- }
1110
- if (a.sortOrder > b.sortOrder || typeof a.sortOrder === 'undefined') {
1111
- return 1;
1112
- }
1113
- return 0;
1114
- };
1115
- /**
1116
- * Sort by column order
1117
- */
1118
- this.getColumnOrder = function (a, b) {
1119
- if (a.columnOrder === undefined) {
1120
- return -1;
1121
- }
1122
- if (a.columnOrder < b.columnOrder) {
1123
- return -1;
1124
- }
1125
- if (a.columnOrder > b.columnOrder) {
1126
- return 1;
1127
- }
1128
- return 0;
1129
- };
1130
- /**
1131
- * Create a deep copy of data
1132
- */
1133
- this.cloneDeep = function (o) {
1134
- return JSON.parse(JSON.stringify(o));
1135
- };
1136
- /**
1137
- * Return property
1138
- */
1139
- this.getProperty = function (array, key) {
1140
- for (var /** @type {?} */ i = 0; i < array.length; i++) {
1141
- if (array[i].objectKey === key) {
1142
- return array[i];
1143
- }
1144
- }
1145
- };
1146
- this.restructureSorting = function () {
1147
- /**
1148
- * Check and store sort order upon initialization.
1149
- * This is done by checking sort properties in the settings array of the table, if no sorting is defined
1150
- * we'll sort the data by the first visible and enabled column in the table(ascending). Please note that actually
1151
- * sorting have to be done server side when lazy loading data for obvious reasons.
1152
- */
1153
- var /** @type {?} */ sorting = [];
1154
- if (this._gtSettings) {
1155
- // ...sort settings by sort order
1156
- this._gtSettings.sort(this.getSortOrder);
1157
- // ...loop through settings
1158
- for (var /** @type {?} */ i = 0; i < this._gtSettings.length; i++) {
1159
- var /** @type {?} */ setting = this._gtSettings[i];
1160
- // ...if sorted ascending...
1161
- if (setting.sort === 'asc') {
1162
- // ... add to sorting
1163
- sorting.push(setting.objectKey);
1164
- }
1165
- else if (setting.sort === 'desc') {
1166
- /* ...else if sorted descending... */
1167
- // ... add to sorting
1168
- sorting.push('-' + setting.objectKey);
1169
- }
1170
- }
1171
- // ...if no sorting applied...
1172
- if (sorting.length === 0) {
1173
- sorting.push('$$gtRowId');
1174
- /*// ...sort settings by column order
1175
- this._gtSettings.sort(this.getColumnOrder);
1176
-
1177
- // ...loop through settings
1178
- for (let i = 0; i < this._gtSettings.length; i++) {
1179
- const setting = this._gtSettings[i];
1180
-
1181
- // ...if column is enabled and visible...
1182
- if (setting.enabled !== false && setting.visible !== false) {
1183
- // ...add first match and exit function
1184
- this.sortOrder = [this._gtSettings[i].objectKey];
1185
- return;
1186
- }
1187
- }*/
1188
- }
1189
- }
1190
- if (this.sortOrder.length === 0) {
1191
- this.sortOrder = sorting;
1192
- }
1193
- };
1194
- /**
1195
- * Extend object function.
1196
- */
1197
- this.extend = function (a, b) {
1198
- for (var /** @type {?} */ key in b) {
1199
- if (b.hasOwnProperty(key)) {
1200
- a[key] = b[key];
1201
- }
1202
- }
1203
- return a;
1204
- };
1205
- this.gtEvent.subscribe(function ($event) {
1206
- if ($event.name === 'gt-info') {
1207
- _this.updateRecordRange();
1208
- }
1209
- if ($event.name === 'gt-row-updated') {
1210
- _this.updateTotals();
1211
- }
1212
- });
1213
- }
1214
- Object.defineProperty(GenericTableComponent.prototype, "gtRowComponent", {
1215
- get: /**
1216
- * @return {?}
1217
- */ function () {
1218
- return this._gtRowComponent;
1219
- },
1220
- set: /**
1221
- * @param {?} value
1222
- * @return {?}
1223
- */ function (value) {
1224
- console.warn('GtRowComponent has been deprecated and support will be removed in a future release, see https://github.com/hjalmers/angular-generic-table/issues/34');
1225
- this._gtRowComponent = value;
1226
- },
1227
- enumerable: true,
1228
- configurable: true
1229
- });
1230
- Object.defineProperty(GenericTableComponent.prototype, "hasEdits", {
1231
- get: /**
1232
- * @return {?}
1233
- */ function () {
1234
- return Object.keys(this.editedRows).length > 0;
1235
- },
1236
- enumerable: true,
1237
- configurable: true
1238
- });
1239
- Object.defineProperty(GenericTableComponent.prototype, "gtOptions", {
1240
- get: /**
1241
- * @return {?}
1242
- */ function () {
1243
- return this._gtOptions;
1244
- },
1245
- set: /**
1246
- * @param {?} value
1247
- * @return {?}
1248
- */ function (value) {
1249
- this._gtOptions = value;
1250
- // if number of rows is passed and if number of rows differs from current record length...
1251
- if (this.gtOptions.numberOfRows &&
1252
- this.gtInfo.recordLength !== this.gtOptions.numberOfRows) {
1253
- // ...update record length and redraw table
1254
- this.gtInfo.recordLength = this.gtOptions.numberOfRows;
1255
- this.redraw();
1256
- }
1257
- // ...extend gtOptions default values with values passed into component
1258
- this._gtOptions = /** @type {?} */ (this.extend(this.gtDefaultOptions, this._gtOptions));
1259
- },
1260
- enumerable: true,
1261
- configurable: true
1262
- });
1263
- Object.defineProperty(GenericTableComponent.prototype, "gtTotals", {
1264
- get: /**
1265
- * @return {?}
1266
- */ function () {
1267
- return this._gtTotals;
1268
- },
1269
- set: /**
1270
- * @param {?} value
1271
- * @return {?}
1272
- */ function (value) {
1273
- this._gtTotals = value;
1274
- },
1275
- enumerable: true,
1276
- configurable: true
1277
- });
1278
- Object.defineProperty(GenericTableComponent.prototype, "gtFields", {
1279
- get: /**
1280
- * @return {?}
1281
- */ function () {
1282
- return this._gtFields;
1283
- },
1284
- set: /**
1285
- * @param {?} value
1286
- * @return {?}
1287
- */ function (value) {
1288
- this._gtFields = value;
1289
- var /** @type {?} */ COLUMNS_WITH_CLASS_NAMES = this._gtFields
1290
- .map(function (column) { return column; })
1291
- .filter(function (column) { return column.classNames; });
1292
- // TODO: remove deprecated warning when setting has been removed
1293
- if (COLUMNS_WITH_CLASS_NAMES.length > 0) {
1294
- console.warn('Field setting "classNames" have been deprecated in favor for "columnClass" and will be removed in the future, please update field settings for column with object key: ' +
1295
- COLUMNS_WITH_CLASS_NAMES[0].objectKey);
1296
- }
1297
- },
1298
- enumerable: true,
1299
- configurable: true
1300
- });
1301
- Object.defineProperty(GenericTableComponent.prototype, "gtSettings", {
1302
- get: /**
1303
- * @return {?}
1304
- */ function () {
1305
- return this._gtSettings;
1306
- },
1307
- set: /**
1308
- * @param {?} value
1309
- * @return {?}
1310
- */ function (value) {
1311
- this._gtSettings = value;
1312
- // loop through current settings
1313
- for (var /** @type {?} */ i = 0; i < this._gtSettings.length; i++) {
1314
- // set sort enabled/disabled setting
1315
- this._gtSettings[i].sortEnabled =
1316
- this._gtSettings[i].sortEnabled !== false
1317
- ? (this._gtSettings[i].sortEnabled = !(this._gtSettings[i].sort &&
1318
- this._gtSettings[i].sort.indexOf('disable') !== -1))
1319
- : false;
1320
- // check if sorting is undefined...
1321
- if (typeof this._gtSettings[i].sort === 'undefined') {
1322
- // ...is so, set sorting property to enable
1323
- this._gtSettings[i].sort = 'enable';
1324
- }
1325
- // check if column order is undefined...
1326
- if (typeof this._gtSettings[i].columnOrder === 'undefined' &&
1327
- this._gtSettings[i].enabled !== false) {
1328
- // ...is so, set sorting property to enable
1329
- this._gtSettings[i].columnOrder = this._gtSettings[i - 1]
1330
- ? this._gtSettings[i - 1].columnOrder + 1
1331
- : 0;
1332
- }
1333
- // check if column lock settings are undefined...
1334
- if (typeof this._gtSettings[i].lockSettings === 'undefined') {
1335
- // ...if so, set lock settings to false unless field is disabled (enable === false)
1336
- this._gtSettings[i].lockSettings =
1337
- this._gtSettings[i].enabled === false || false;
1338
- }
1339
- }
1340
- this.restructureSorting();
1341
- },
1342
- enumerable: true,
1343
- configurable: true
1344
- });
1345
- Object.defineProperty(GenericTableComponent.prototype, "gtData", {
1346
- get: /**
1347
- * @return {?}
1348
- */ function () {
1349
- return this._gtData;
1350
- },
1351
- set: /**
1352
- * @param {?} initialData
1353
- * @return {?}
1354
- */ function (initialData) {
1355
- var _this = this;
1356
- var /** @type {?} */ data = this._gtOptions.mutateData
1357
- ? __spread(initialData) : this.cloneDeep(initialData);
1358
- if (this.gtOptions.lazyLoad && this.gtInfo) {
1359
- this.gtMetaPipe.transform(data, this.gtOptions.rowIndex, this.gtInfo.pageCurrent - 1, this.gtInfo.recordLength);
1360
- if (this.lazyAllSelected) {
1361
- var /** @type {?} */ UNIQUE_ROWS_1 = this.selectedRows.map(function (row) { return row.$$gtRowId; });
1362
- data.map(function (row) {
1363
- if (UNIQUE_ROWS_1.indexOf(row.$$gtRowId) === -1) {
1364
- _this.selectedRows.push(row);
1365
- }
1366
- });
1367
- this._updateMetaInfo(this.selectedRows, 'isSelected', true);
1368
- }
1369
- }
1370
- else {
1371
- this.gtMetaPipe.transform(data, this.gtOptions.rowIndex);
1372
- }
1373
- if (this.gtOptions.rowSelectionInitialState) {
1374
- data.map(function (row) {
1375
- var /** @type {?} */ selected = typeof _this.gtOptions.rowSelectionInitialState === 'function'
1376
- ? _this.gtOptions.rowSelectionInitialState(row)
1377
- : _this.gtOptions.rowSelectionInitialState;
1378
- if (selected) {
1379
- if (typeof _this.metaInfo[row.$$gtRowId] === 'undefined') {
1380
- _this.metaInfo[row.$$gtRowId] = { isSelected: true };
1381
- }
1382
- else {
1383
- _this.metaInfo[row.$$gtRowId].isSelected = true;
1384
- }
1385
- _this.selectedRows.push(row);
1386
- }
1387
- });
1388
- }
1389
- if (this.gtOptions.rowExpandInitialState &&
1390
- this.gtOptions.rowExpandInitialComponent) {
1391
- data.map(function (row) {
1392
- var /** @type {?} */ expanded = typeof _this.gtOptions.rowExpandInitialState === 'function'
1393
- ? _this.gtOptions.rowExpandInitialState(row)
1394
- : _this.gtOptions.rowExpandInitialState;
1395
- _this.expandedRow = _this.gtOptions.rowExpandInitialComponent;
1396
- if (expanded) {
1397
- if (typeof _this.metaInfo[row.$$gtRowId] === 'undefined') {
1398
- _this.metaInfo[row.$$gtRowId] = { isOpen: true };
1399
- }
1400
- else {
1401
- _this.metaInfo[row.$$gtRowId].isOpen = true;
1402
- }
1403
- }
1404
- });
1405
- }
1406
- this._gtData = data;
1407
- },
1408
- enumerable: true,
1409
- configurable: true
1410
- });
1411
- /**
1412
- * Update record range.
1413
- * @return {?}
1414
- */
1415
- GenericTableComponent.prototype.updateRecordRange = /**
1416
- * Update record range.
1417
- * @return {?}
1418
- */
1419
- function () {
1420
- this.gtInfo.recordFrom =
1421
- this.gtInfo.recordsAfterSearch === 0
1422
- ? 0
1423
- : (this.gtInfo.pageCurrent - 1) * this.gtInfo.recordLength + 1;
1424
- this.gtInfo.recordTo =
1425
- this.gtInfo.recordsAfterSearch <
1426
- this.gtInfo.pageCurrent * this.gtInfo.recordLength
1427
- ? this.gtInfo.recordsAfterSearch
1428
- : this.gtInfo.pageCurrent * this.gtInfo.recordLength;
1429
- };
1430
- /**
1431
- * Update totals.
1432
- * @return {?}
1433
- */
1434
- GenericTableComponent.prototype.updateTotals = /**
1435
- * Update totals.
1436
- * @return {?}
1437
- */
1438
- function () {
1439
- this.refreshTotals = !this.refreshTotals;
1440
- };
1441
- /**
1442
- * Get meta data for row.
1443
- * @param {?} row
1444
- * @return {?}
1445
- */
1446
- GenericTableComponent.prototype.getRowState = /**
1447
- * Get meta data for row.
1448
- * @param {?} row
1449
- * @return {?}
1450
- */
1451
- function (row) {
1452
- return typeof this.metaInfo[row.$$gtRowId] === 'undefined'
1453
- ? null
1454
- : this.metaInfo[row.$$gtRowId];
1455
- };
1456
- /**
1457
- * Expand all rows.
1458
- * @param {?} expandedRow - component to render when rows are expanded.
1459
- * @return {?}
1460
- */
1461
- GenericTableComponent.prototype.expandAllRows = /**
1462
- * Expand all rows.
1463
- * @param {?} expandedRow - component to render when rows are expanded.
1464
- * @return {?}
1465
- */
1466
- function (expandedRow) {
1467
- this.expandedRow = expandedRow;
1468
- this._toggleAllRowProperty('isOpen', true);
1469
- };
1470
- /**
1471
- * Collapse all rows.
1472
- * @return {?}
1473
- */
1474
- GenericTableComponent.prototype.collapseAllRows = /**
1475
- * Collapse all rows.
1476
- * @return {?}
1477
- */
1478
- function () {
1479
- this._toggleAllRowProperty('isOpen', false);
1480
- };
1481
- /**
1482
- * Select all rows.
1483
- * @return {?}
1484
- */
1485
- GenericTableComponent.prototype.selectAllRows = /**
1486
- * Select all rows.
1487
- * @return {?}
1488
- */
1489
- function () {
1490
- this._toggleAllRowProperty('isSelected', true);
1491
- };
1492
- /**
1493
- * Deselect all rows.
1494
- * @return {?}
1495
- */
1496
- GenericTableComponent.prototype.deselectAllRows = /**
1497
- * Deselect all rows.
1498
- * @return {?}
1499
- */
1500
- function () {
1501
- this._toggleAllRowProperty('isSelected', false);
1502
- };
1503
- /**
1504
- * Toggle all rows.
1505
- * @return {?}
1506
- */
1507
- GenericTableComponent.prototype.toggleAllRows = /**
1508
- * Toggle all rows.
1509
- * @return {?}
1510
- */
1511
- function () {
1512
- if (this._gtOptions.lazyLoad) {
1513
- if (!this.lazyAllSelected || this.selectedRows.length === 0) {
1514
- this.selectAllRows();
1515
- this.lazyAllSelected = true;
1516
- }
1517
- else {
1518
- this.deselectAllRows();
1519
- this.lazyAllSelected = false;
1520
- }
1521
- }
1522
- else {
1523
- if (this.selectedRows.length !== this.gtData.length) {
1524
- this.selectAllRows();
1525
- }
1526
- else {
1527
- this.deselectAllRows();
1528
- }
1529
- }
1530
- };
1531
- /**
1532
- * Toggle row collapsed state ie. expanded/open or collapsed/closed.
1533
- * @param {?} row - row object that should be expanded/collapsed.
1534
- * @param {?=} expandedRow - component to render when row is expanded.
1535
- * @return {?}
1536
- */
1537
- GenericTableComponent.prototype.toggleCollapse = /**
1538
- * Toggle row collapsed state ie. expanded/open or collapsed/closed.
1539
- * @param {?} row - row object that should be expanded/collapsed.
1540
- * @param {?=} expandedRow - component to render when row is expanded.
1541
- * @return {?}
1542
- */
1543
- function (row, expandedRow) {
1544
- if (expandedRow) {
1545
- this.expandedRow = expandedRow;
1546
- }
1547
- this._toggleRowProperty(row, 'isOpen');
1548
- };
1549
- /**
1550
- * Toggle row selected state ie. selected or not.
1551
- * @param {?} row - row object that should be selected/deselected.
1552
- * @return {?}
1553
- */
1554
- GenericTableComponent.prototype.toggleSelect = /**
1555
- * Toggle row selected state ie. selected or not.
1556
- * @param {?} row - row object that should be selected/deselected.
1557
- * @return {?}
1558
- */
1559
- function (row) {
1560
- this._toggleRowProperty(row, 'isSelected');
1561
- };
1562
- /**
1563
- * @param {?} row
1564
- * @param {?} $event
1565
- * @return {?}
1566
- */
1567
- GenericTableComponent.prototype.rowClick = /**
1568
- * @param {?} row
1569
- * @param {?} $event
1570
- * @return {?}
1571
- */
1572
- function (row, $event) {
1573
- this.gtEvent.emit({
1574
- name: 'gt-row-clicked',
1575
- value: { row: row, event: $event }
1576
- });
1577
- };
1578
- /**
1579
- * Update row data.
1580
- * @param {?} row - row object that has been edited.
1581
- * @param {?} oldValue - row object before edit.
1582
- * @return {?}
1583
- */
1584
- GenericTableComponent.prototype.updateRow = /**
1585
- * Update row data.
1586
- * @param {?} row - row object that has been edited.
1587
- * @param {?} oldValue - row object before edit.
1588
- * @return {?}
1589
- */
1590
- function (row, oldValue) {
1591
- this._toggleRowProperty(row, 'isUpdated', oldValue);
1592
- };
1593
- /**
1594
- * removes a row from the table
1595
- * @param {?} row - the row object to remove
1596
- * @return {?}
1597
- */
1598
- GenericTableComponent.prototype.removeRow = /**
1599
- * removes a row from the table
1600
- * @param {?} row - the row object to remove
1601
- * @return {?}
1602
- */
1603
- function (row) {
1604
- if (this.isRowSelected(row)) {
1605
- this.toggleSelect(row);
1606
- }
1607
- var /** @type {?} */ index = this._gtData.indexOf(row);
1608
- this._gtData.splice(index, 1);
1609
- };
1610
- /**
1611
- * check if a row is selected
1612
- * @param {?} row - row object
1613
- * @return {?}
1614
- */
1615
- GenericTableComponent.prototype.isRowSelected = /**
1616
- * check if a row is selected
1617
- * @param {?} row - row object
1618
- * @return {?}
1619
- */
1620
- function (row) {
1621
- return (this.metaInfo[row.$$gtRowId] && this.metaInfo[row.$$gtRowId].isSelected);
1622
- };
1623
- /**
1624
- * Update meta info for all rows, ie. isSelected, isOpen.
1625
- * @param {?} array - array that holds rows that need to be updated.
1626
- * @param {?} property - name of property that should be changed/toggled.
1627
- * @param {?} active - should rows be expanded/open, selected.
1628
- * @param {?=} exception - update all rows except this one.
1629
- * @return {?}
1630
- */
1631
- GenericTableComponent.prototype._updateMetaInfo = /**
1632
- * Update meta info for all rows, ie. isSelected, isOpen.
1633
- * @param {?} array - array that holds rows that need to be updated.
1634
- * @param {?} property - name of property that should be changed/toggled.
1635
- * @param {?} active - should rows be expanded/open, selected.
1636
- * @param {?=} exception - update all rows except this one.
1637
- * @return {?}
1638
- */
1639
- function (array, property, active, exception) {
1640
- for (var /** @type {?} */ i = 0; i < array.length; i++) {
1641
- if (!this.metaInfo[array[i].$$gtRowId]) {
1642
- this.metaInfo[array[i].$$gtRowId] = {};
1643
- }
1644
- if (exception && array[i].$$gtRowId === exception.$$gtRowId) ;
1645
- else {
1646
- this.metaInfo[array[i].$$gtRowId][property] = active;
1647
- }
1648
- }
1649
- };
1650
- /**
1651
- * Push selected/expanded lazy loaded rows to array with meta data.
1652
- * @param {?} target - array to which rows should be added.
1653
- * @param {?} source - array that holds rows that should be added.
1654
- * @return {?} array with added rows.
1655
- */
1656
- GenericTableComponent.prototype._pushLazyRows = /**
1657
- * Push selected/expanded lazy loaded rows to array with meta data.
1658
- * @param {?} target - array to which rows should be added.
1659
- * @param {?} source - array that holds rows that should be added.
1660
- * @return {?} array with added rows.
1661
- */
1662
- function (target, source) {
1663
- var /** @type {?} */ UNIQUE_ROWS = target.map(function (row) { return row.$$gtRowId; });
1664
- for (var /** @type {?} */ i = 0; i < source.length; i++) {
1665
- // only add if not already in list
1666
- if (UNIQUE_ROWS.indexOf(source[i].$$gtRowId) === -1) {
1667
- target.push(source[i]);
1668
- }
1669
- }
1670
- return target;
1671
- };
1672
- /**
1673
- * Toggle meta info for all rows, ie. isSelected, isOpen.
1674
- * @param {?} property - name of property that should be changed/toggled.
1675
- * @param {?} active - should rows be expanded/open, selected.
1676
- * @return {?}
1677
- */
1678
- GenericTableComponent.prototype._toggleAllRowProperty = /**
1679
- * Toggle meta info for all rows, ie. isSelected, isOpen.
1680
- * @param {?} property - name of property that should be changed/toggled.
1681
- * @param {?} active - should rows be expanded/open, selected.
1682
- * @return {?}
1683
- */
1684
- function (property, active) {
1685
- var /** @type {?} */ eventName;
1686
- var /** @type {?} */ eventValue;
1687
- switch (property) {
1688
- case 'isOpen':
1689
- // check if multiple expanded rows are allowed...
1690
- if (this._gtOptions.rowExpandAllowMultiple === false) {
1691
- // ...if not, exit function
1692
- console.log('feature disabled: enable by setting "rowExpandAllowMultiple = true"');
1693
- return;
1694
- }
1695
- if (active) {
1696
- eventName = 'expand-all';
1697
- this.openRows = this._gtOptions.lazyLoad
1698
- ? this._pushLazyRows(this.openRows, this._gtData[this.gtInfo.pageCurrent - 1].slice())
1699
- : this._gtData.slice();
1700
- this._updateMetaInfo(this.openRows, property, active);
1701
- }
1702
- else {
1703
- eventName = 'collapse-all';
1704
- this._updateMetaInfo(this.openRows, property, active);
1705
- this.openRows = [];
1706
- }
1707
- eventValue = {
1708
- expandedRows: this.openRows,
1709
- changedRow: 'all'
1710
- };
1711
- break;
1712
- case 'isSelected':
1713
- // check if multi row selection is allowed...
1714
- if (this._gtOptions.rowSelectionAllowMultiple === false) {
1715
- // ...if not, exit function
1716
- console.log('feature disabled: enable by setting "rowSelectionAllowMultiple = true"');
1717
- return;
1718
- }
1719
- if (active) {
1720
- eventName = 'select-all';
1721
- this.selectedRows = this._gtOptions.lazyLoad
1722
- ? this._pushLazyRows(this.selectedRows, this._gtData[this.gtInfo.pageCurrent - 1].slice())
1723
- : this._gtData.slice();
1724
- this._updateMetaInfo(this.selectedRows, property, active);
1725
- }
1726
- else {
1727
- eventName = 'deselect-all';
1728
- this._updateMetaInfo(this.selectedRows, property, active);
1729
- this.selectedRows = [];
1730
- }
1731
- eventValue = {
1732
- selectedRows: this.selectedRows,
1733
- changedRow: 'all'
1734
- };
1735
- break;
1736
- }
1737
- this.gtEvent.emit({
1738
- name: 'gt-row-' + eventName,
1739
- value: eventValue
1740
- });
1741
- };
1742
- /**
1743
- * Toggle meta info for row, ie. isSelected, isOpen.
1744
- * @param {?} row - row object.
1745
- * @param {?} property - name of property that should be changed/toggled.
1746
- * @param {?=} propertyValues - optional property values that can be passed.
1747
- * @return {?}
1748
- */
1749
- GenericTableComponent.prototype._toggleRowProperty = /**
1750
- * Toggle meta info for row, ie. isSelected, isOpen.
1751
- * @param {?} row - row object.
1752
- * @param {?} property - name of property that should be changed/toggled.
1753
- * @param {?=} propertyValues - optional property values that can be passed.
1754
- * @return {?}
1755
- */
1756
- function (row, property, propertyValues) {
1757
- var /** @type {?} */ eventName;
1758
- var /** @type {?} */ eventValue;
1759
- // make sure gtRowId exists on row object
1760
- if (typeof row.$$gtRowId !== 'undefined') {
1761
- // check if meta info exists for row
1762
- if (!this.metaInfo[row.$$gtRowId]) {
1763
- // if not, add object to store meta info
1764
- this.metaInfo[row.$$gtRowId] = {};
1765
- }
1766
- switch (property) {
1767
- case 'isOpen':
1768
- var /** @type {?} */ opened = this.metaInfo[row.$$gtRowId][property];
1769
- // check if multiple expanded rows are allowed...
1770
- if (this._gtOptions.rowExpandAllowMultiple === false) {
1771
- // ...if not, collapse all rows except current row
1772
- this._updateMetaInfo(this.openRows, property, false, row);
1773
- this.openRows = [];
1774
- }
1775
- // check if row is expanded
1776
- if (!opened) {
1777
- eventName = 'expand';
1778
- // add row to expanded rows
1779
- this.openRows.push(row);
1780
- }
1781
- else {
1782
- eventName = 'collapse';
1783
- // loop through expanded rows...
1784
- for (var /** @type {?} */ i = 0; i < this.openRows.length; i++) {
1785
- // if expanded row equals passed row...
1786
- if (this.openRows[i].$$gtRowId === row.$$gtRowId) {
1787
- // ...remove row from expanded rows...
1788
- this.openRows.splice(i, 1);
1789
- // ...and exit loop
1790
- break;
1791
- }
1792
- }
1793
- }
1794
- eventValue = {
1795
- expandedRows: this.openRows,
1796
- changedRow: row
1797
- };
1798
- break;
1799
- case 'isSelected':
1800
- var /** @type {?} */ selected = this.metaInfo[row.$$gtRowId][property];
1801
- // check if multi row selection is allowed...
1802
- if (this._gtOptions.rowSelectionAllowMultiple === false) {
1803
- // ...if not, deselect all rows except current row
1804
- this._updateMetaInfo(this.selectedRows, property, false, row);
1805
- this.selectedRows = [];
1806
- }
1807
- // check if row is selected
1808
- if (!selected) {
1809
- eventName = 'select';
1810
- // add row to selected rows
1811
- this.selectedRows.push(row);
1812
- }
1813
- else {
1814
- if (this.gtOptions.lazyLoad && this.lazyAllSelected) {
1815
- this.lazyAllSelected = false;
1816
- }
1817
- eventName = 'deselect';
1818
- // loop through selected rows...
1819
- for (var /** @type {?} */ i = 0; i < this.selectedRows.length; i++) {
1820
- // if selected row equals passed row...
1821
- if (this.selectedRows[i].$$gtRowId === row.$$gtRowId) {
1822
- // ...remove row from selected rows...
1823
- this.selectedRows.splice(i, 1);
1824
- // ...and exit loop
1825
- break;
1826
- }
1827
- }
1828
- }
1829
- eventValue = {
1830
- selectedRows: this.selectedRows,
1831
- changedRow: row
1832
- };
1833
- break;
1834
- case 'isUpdated':
1835
- eventName = 'updated';
1836
- var /** @type {?} */ oldValue = propertyValues;
1837
- // check if edit object exists for row
1838
- if (typeof this.metaInfo[row.$$gtRowId][property] === 'undefined') {
1839
- this.metaInfo[row.$$gtRowId][property] = {
1840
- originalValue: oldValue,
1841
- oldValue: oldValue,
1842
- newValue: row
1843
- };
1844
- }
1845
- else {
1846
- this.metaInfo[row.$$gtRowId][property].oldValue = oldValue;
1847
- this.metaInfo[row.$$gtRowId][property].newValue = row;
1848
- }
1849
- eventValue = this.metaInfo[row.$$gtRowId][property];
1850
- this.redraw();
1851
- this.inlineEditCancel(row);
1852
- // this.gtData = [...this.gtData.map((r) => { return{...r}; })];
1853
- break;
1854
- }
1855
- this.gtEvent.emit({
1856
- name: 'gt-row-' + eventName,
1857
- value: eventValue
1858
- });
1859
- if (property !== 'isUpdated') {
1860
- this.metaInfo[row.$$gtRowId][property] = !this.metaInfo[row.$$gtRowId][property];
1861
- }
1862
- }
1863
- };
1864
- /**
1865
- * Update column.
1866
- * @param {?} $event - key up event.
1867
- * @param {?} row - row object.
1868
- * @param {?} column - column object.
1869
- * @return {?}
1870
- */
1871
- GenericTableComponent.prototype.gtUpdateColumn = /**
1872
- * Update column.
1873
- * @param {?} $event - key up event.
1874
- * @param {?} row - row object.
1875
- * @param {?} column - column object.
1876
- * @return {?}
1877
- */
1878
- function ($event, row, column) {
1879
- this._editRow(row, column);
1880
- };
1881
- /**
1882
- * Dropdown select.
1883
- * @param {?} row - row object.
1884
- * @param {?} column - column object.
1885
- * @return {?}
1886
- */
1887
- GenericTableComponent.prototype.gtDropdownSelect = /**
1888
- * Dropdown select.
1889
- * @param {?} row - row object.
1890
- * @param {?} column - column object.
1891
- * @return {?}
1892
- */
1893
- function (row, column) {
1894
- var /** @type {?} */ oldValue = __assign({}, row);
1895
- row[column.objectKey] = column.renderValue;
1896
- this.updateRow(row, oldValue);
1897
- };
1898
- /**
1899
- * @param {?} row
1900
- * @param {?} column
1901
- * @return {?}
1902
- */
1903
- GenericTableComponent.prototype._editRow = /**
1904
- * @param {?} row
1905
- * @param {?} column
1906
- * @return {?}
1907
- */
1908
- function (row, column) {
1909
- var /** @type {?} */ OBJECT_KEY = column.objectKey; // declare object key which contains changes
1910
- // check if cell has changed value
1911
- column.edited = row[column.objectKey] !== column.renderValue;
1912
- // check if row contains changes...
1913
- if (!this.editedRows[row.$$gtRowId]) {
1914
- // if not, create an object for the changed row
1915
- this.editedRows[row.$$gtRowId] = {
1916
- changes: {},
1917
- // create placeholder for changes
1918
- row: row // store reference to the row that should be updated
1919
- };
1920
- }
1921
- // store changed column under changes if it has been edited
1922
- if (column.edited) {
1923
- this.editedRows[row.$$gtRowId].changes[OBJECT_KEY] = column;
1924
- }
1925
- else {
1926
- // delete change object if column is unchanged
1927
- delete this.editedRows[row.$$gtRowId].changes[OBJECT_KEY];
1928
- // check how many columns have been changed
1929
- var /** @type {?} */ CHANGED_COLUMNS = Object.keys(this.editedRows[row.$$gtRowId].changes).length;
1930
- if (CHANGED_COLUMNS === 0) {
1931
- // delete row from edited rows if no columns have been edited
1932
- delete this.editedRows[row.$$gtRowId];
1933
- }
1934
- }
1935
- // if no listener is present...
1936
- if (!this.globalInlineEditListener) {
1937
- // ...listen for update event
1938
- this._listenForKeydownEvent();
1939
- }
1940
- };
1941
- /**
1942
- * Listen for key down event - listen for key down event during inline edit.
1943
- * @return {?}
1944
- */
1945
- GenericTableComponent.prototype._listenForKeydownEvent = /**
1946
- * Listen for key down event - listen for key down event during inline edit.
1947
- * @return {?}
1948
- */
1949
- function () {
1950
- var _this = this;
1951
- // add global listener for key down events
1952
- this.globalInlineEditListener = this.renderer.listen('document', 'keydown', function ($event) {
1953
- switch ($event.key) {
1954
- case 'Enter': // update data object
1955
- // update data object
1956
- _this.inlineEditUpdate();
1957
- break;
1958
- case 'Escape': // cancel
1959
- // cancel
1960
- _this.inlineEditCancel();
1961
- break;
1962
- }
1963
- });
1964
- };
1965
- /**
1966
- * Inline edit update - accept changes and update row values.
1967
- * @return {?}
1968
- */
1969
- GenericTableComponent.prototype.inlineEditUpdate = /**
1970
- * Inline edit update - accept changes and update row values.
1971
- * @return {?}
1972
- */
1973
- function () {
1974
- var _this = this;
1975
- // loop through rows that have been edited
1976
- Object.keys(this.editedRows).map(function (key) {
1977
- var /** @type {?} */ ROW = _this.editedRows[key].row; // row to update
1978
- var /** @type {?} */ CHANGES = _this.editedRows[key].changes; // changes to the row
1979
- // loop through changes in row
1980
- Object.keys(CHANGES).map(function (objectKey) {
1981
- var /** @type {?} */ oldValue = __assign({}, ROW);
1982
- ROW[objectKey] = CHANGES[objectKey].renderValue; // update data value
1983
- _this.updateRow(ROW, oldValue); // update meta info for row and send event
1984
- CHANGES[objectKey].edited = false; // disable edit mode
1985
- });
1986
- });
1987
- // clear rows marked as edited as the rows have been updated
1988
- this.editedRows = {};
1989
- // remove listener
1990
- this._stopListeningForKeydownEvent();
1991
- };
1992
- /**
1993
- * Inline edit cancel - cancel and reset inline edits.
1994
- * @param {?=} row
1995
- * @return {?}
1996
- */
1997
- GenericTableComponent.prototype.inlineEditCancel = /**
1998
- * Inline edit cancel - cancel and reset inline edits.
1999
- * @param {?=} row
2000
- * @return {?}
2001
- */
2002
- function (row) {
2003
- var _this = this;
2004
- if (row) {
2005
- delete this.editedRows[row.$$gtRowId];
2006
- // remove listener
2007
- this._stopListeningForKeydownEvent();
2008
- return;
2009
- }
2010
- // loop through rows that have been edited
2011
- Object.keys(this.editedRows).map(function (key) {
2012
- var /** @type {?} */ ROW = _this.editedRows[key].row; // row to update
2013
- var /** @type {?} */ CHANGES = _this.editedRows[key].changes; // changes to the row
2014
- // loop through changes in row
2015
- Object.keys(CHANGES).map(function (objectKey) {
2016
- CHANGES[objectKey].renderValue = ROW[objectKey]; // reset rendered value
2017
- CHANGES[objectKey].edited = false; // disable edit mode
2018
- });
2019
- });
2020
- // clear rows marked as edited as the rows have been updated
2021
- this.editedRows = {};
2022
- // remove listener
2023
- this._stopListeningForKeydownEvent();
2024
- };
2025
- /**
2026
- * Stop listening for key down event - stop listening for key down events passed during inline edit.
2027
- * @return {?}
2028
- */
2029
- GenericTableComponent.prototype._stopListeningForKeydownEvent = /**
2030
- * Stop listening for key down event - stop listening for key down events passed during inline edit.
2031
- * @return {?}
2032
- */
2033
- function () {
2034
- if (this.globalInlineEditListener) {
2035
- this.globalInlineEditListener();
2036
- this.globalInlineEditListener = null;
2037
- }
2038
- };
2039
- /**
2040
- * Apply filter(s).
2041
- * @param {?} filter - object containing key value pairs, where value should be array of values.
2042
- * @return {?}
2043
- */
2044
- GenericTableComponent.prototype.gtApplyFilter = /**
2045
- * Apply filter(s).
2046
- * @param {?} filter - object containing key value pairs, where value should be array of values.
2047
- * @return {?}
2048
- */
2049
- function (filter) {
2050
- this.gtInfo.filter = filter;
2051
- // go to first page
2052
- this.goToPage(1);
2053
- this.updateTotals();
2054
- };
2055
- /**
2056
- * Clear/remove applied filter(s).
2057
- * @return {?}
2058
- */
2059
- GenericTableComponent.prototype.gtClearFilter = /**
2060
- * Clear/remove applied filter(s).
2061
- * @return {?}
2062
- */
2063
- function () {
2064
- this.gtInfo.filter = false;
2065
- this.updateTotals();
2066
- // this.updateRecordRange();
2067
- };
2068
- /**
2069
- * Search
2070
- * @param {?} value - string containing one or more words
2071
- * @return {?}
2072
- */
2073
- GenericTableComponent.prototype.gtSearch = /**
2074
- * Search
2075
- * @param {?} value - string containing one or more words
2076
- * @return {?}
2077
- */
2078
- function (value) {
2079
- this.gtInfo.searchTerms = value;
2080
- // always go to first page when searching
2081
- this.goToPage(1);
2082
- this.updateTotals();
2083
- };
2084
- /**
2085
- * Add rows
2086
- * @param {?} rows - rows to add
2087
- * @return {?} new data array.
2088
- */
2089
- GenericTableComponent.prototype.gtAdd = /**
2090
- * Add rows
2091
- * @param {?} rows - rows to add
2092
- * @return {?} new data array.
2093
- */
2094
- function (rows) {
2095
- this.gtData = __spread(this.gtData, rows);
2096
- return __spread(this.gtData);
2097
- };
2098
- /**
2099
- * Delete row
2100
- * @param {?} objectKey - object key you want to find match with
2101
- * @param {?} value - the value that should be deleted
2102
- * @param {?=} match - all: delete all matches, first: delete first match (default)
2103
- * @return {?} new data array.
2104
- */
2105
- GenericTableComponent.prototype.gtDelete = /**
2106
- * Delete row
2107
- * @param {?} objectKey - object key you want to find match with
2108
- * @param {?} value - the value that should be deleted
2109
- * @param {?=} match - all: delete all matches, first: delete first match (default)
2110
- * @return {?} new data array.
2111
- */
2112
- function (objectKey, value, match) {
2113
- if (match === void 0) {
2114
- match = 'first';
2115
- }
2116
- if (match === 'first') {
2117
- for (var /** @type {?} */ i = 0; i < this.gtData.length; i++) {
2118
- if (this.gtData[i][objectKey] === value) {
2119
- if (this.isRowSelected(this.gtData[i])) {
2120
- this.toggleSelect(this.gtData[i]);
2121
- }
2122
- this.gtData.splice(i, 1);
2123
- this.gtData = __spread(this.gtData);
2124
- if (match === 'first') {
2125
- break;
2126
- }
2127
- }
2128
- }
2129
- }
2130
- else {
2131
- for (var /** @type {?} */ i = this.gtData.length; i > 0; i--) {
2132
- if (this.gtData[i - 1][objectKey] === value) {
2133
- if (this.isRowSelected(this.gtData[i - 1])) {
2134
- this.toggleSelect(this.gtData[i - 1]);
2135
- }
2136
- this.gtData.splice(i - 1, 1);
2137
- this.gtData = __spread(this.gtData);
2138
- }
2139
- }
2140
- }
2141
- return __spread(this.gtData);
2142
- };
2143
- /**
2144
- * Create store to hold previously loaded records.
2145
- * @param {?} records - total number of records in store.
2146
- * @param {?} perPage - how many records to show per page.
2147
- * @return {?} a nested array to hold records per page.
2148
- */
2149
- GenericTableComponent.prototype.createStore = /**
2150
- * Create store to hold previously loaded records.
2151
- * @param {?} records - total number of records in store.
2152
- * @param {?} perPage - how many records to show per page.
2153
- * @return {?} a nested array to hold records per page.
2154
- */
2155
- function (records, perPage) {
2156
- var /** @type {?} */ stores = Math.ceil(records / perPage);
2157
- var /** @type {?} */ store = [];
2158
- for (var /** @type {?} */ i = 0; i < stores; i++) {
2159
- store[i] = [];
2160
- }
2161
- return store;
2162
- };
2163
- /**
2164
- * Create placeholders for rows while loading data from back-end.
2165
- * @param {?} perPage - how many records to show per page.
2166
- * @return {?} an array containing empty records to be presented while fetching real data.
2167
- */
2168
- GenericTableComponent.prototype.loadingContent = /**
2169
- * Create placeholders for rows while loading data from back-end.
2170
- * @param {?} perPage - how many records to show per page.
2171
- * @return {?} an array containing empty records to be presented while fetching real data.
2172
- */
2173
- function (perPage) {
2174
- // create row object
2175
- var /** @type {?} */ rowObject = {
2176
- $$loading: true
2177
- };
2178
- var /** @type {?} */ order = 0;
2179
- // sort settings by column order
2180
- this._gtSettings.sort(this.getColumnOrder);
2181
- // loop through all settings objects...
2182
- for (var /** @type {?} */ i = 0; i < this._gtSettings.length; i++) {
2183
- var /** @type {?} */ setting = this._gtSettings[i];
2184
- // ...if column is visible and enabled...
2185
- if (setting.visible !== false && setting.enabled !== false) {
2186
- // ...if first column, set value to loading text otherwise leave it empty
2187
- if (order === 0) {
2188
- rowObject[setting.objectKey] = this.gtTexts.loading;
2189
- this.loadingProperty = setting.objectKey;
2190
- }
2191
- else {
2192
- rowObject[setting.objectKey] = '';
2193
- }
2194
- order++;
2195
- }
2196
- else {
2197
- rowObject[setting.objectKey] = '';
2198
- }
2199
- }
2200
- // create content placeholder
2201
- var /** @type {?} */ contentPlaceholder = [];
2202
- // create equal number of rows as rows per page
2203
- for (var /** @type {?} */ i = 0; i < perPage; i++) {
2204
- // ...add temporary row object
2205
- contentPlaceholder.push(rowObject);
2206
- }
2207
- return contentPlaceholder;
2208
- };
2209
- /**
2210
- * Export data as CSV
2211
- * @param {?=} fileName - optional file name (overrides default file name).
2212
- * @param {?=} useBOM - use BOM (byte order marker).
2213
- * @return {?}
2214
- */
2215
- GenericTableComponent.prototype.exportCSV = /**
2216
- * Export data as CSV
2217
- * @param {?=} fileName - optional file name (overrides default file name).
2218
- * @param {?=} useBOM - use BOM (byte order marker).
2219
- * @return {?}
2220
- */
2221
- function (fileName, useBOM) {
2222
- var _this = this;
2223
- if (useBOM === void 0) {
2224
- useBOM = false;
2225
- }
2226
- var /** @type {?} */ data = this.data.exportData;
2227
- var /** @type {?} */ csv = '';
2228
- var /** @type {?} */ BOM = '\uFEFF';
2229
- // csv export headers
2230
- for (var /** @type {?} */ i = 0; i < this._gtSettings.length; i++) {
2231
- if (this._gtSettings[i].export !== false) {
2232
- csv += this.getProperty(this._gtFields, this._gtSettings[i].objectKey)
2233
- .name;
2234
- if (i < this._gtSettings.length - 1) {
2235
- csv += this._gtOptions.csvDelimiter;
2236
- }
2237
- }
2238
- }
2239
- // csv export body
2240
- data.forEach(function (row) {
2241
- csv += '\n';
2242
- for (var /** @type {?} */ i = 0; i < _this._gtSettings.length; i++) {
2243
- if (_this._gtSettings[i].export !== false) {
2244
- // get field settings
2245
- var /** @type {?} */ fieldSetting = _this.getProperty(_this._gtFields, _this._gtSettings[i].objectKey);
2246
- // get export value, if export function is defined use it otherwise check for value function and as a last resort export raw data
2247
- var /** @type {?} */ exportValue = fieldSetting.export && typeof fieldSetting.export === 'function'
2248
- ? fieldSetting.export(row)
2249
- : fieldSetting.value && typeof fieldSetting.value === 'function'
2250
- ? fieldSetting.value(row)
2251
- : row[_this._gtSettings[i].objectKey];
2252
- // escape export value using double quotes (") if export value contains delimiter
2253
- exportValue =
2254
- typeof exportValue === 'string' &&
2255
- exportValue.indexOf(_this._gtOptions.csvDelimiter) !== -1
2256
- ? '"' + exportValue + '"'
2257
- : exportValue;
2258
- csv += exportValue;
2259
- if (i < _this._gtSettings.length - 1) {
2260
- csv += _this._gtOptions.csvDelimiter;
2261
- }
2262
- }
2263
- }
2264
- });
2265
- var /** @type {?} */ blob = new Blob([(useBOM ? BOM : '') + csv], {
2266
- type: 'text/csv;charset=utf-8'
2267
- });
2268
- if (window.navigator.msSaveOrOpenBlob) {
2269
- navigator.msSaveOrOpenBlob(blob, fileName ? fileName + '.csv' : this.gtTexts.csvDownload + '.csv');
2270
- }
2271
- else {
2272
- var /** @type {?} */ link = document.createElement('a');
2273
- link.style.display = 'none';
2274
- document.body.appendChild(link);
2275
- if (link.download !== undefined) {
2276
- link.setAttribute('href', 'data:text/csv;charset=utf-8,' +
2277
- encodeURIComponent((useBOM ? BOM : '') + csv)); // URL.createObjectURL(blob));
2278
- link.setAttribute('download', fileName ? fileName + '.csv' : this.gtTexts.csvDownload + '.csv');
2279
- document.body.appendChild(link);
2280
- link.click();
2281
- }
2282
- else {
2283
- csv = 'data:text/csv;charset=utf-8,' + (useBOM ? BOM : '') + csv;
2284
- window.open(encodeURIComponent(csv));
2285
- }
2286
- document.body.removeChild(link);
2287
- }
2288
- // emit export event
2289
- this.gtEvent.emit({
2290
- name: 'gt-exported-csv',
2291
- value: fileName ? fileName : this.gtTexts.csvDownload + '.csv'
2292
- });
2293
- };
2294
- /**
2295
- * @return {?}
2296
- */
2297
- GenericTableComponent.prototype.ngOnInit = /**
2298
- * @return {?}
2299
- */
2300
- function () {
2301
- // if number of row to display from start is set to null or 0...
2302
- if (!this.gtOptions.numberOfRows) {
2303
- // ...change row length
2304
- this.changeRowLength(this.gtOptions.numberOfRows);
2305
- }
2306
- this.restructureSorting();
2307
- };
2308
- /**
2309
- * @param {?} changes
2310
- * @return {?}
2311
- */
2312
- GenericTableComponent.prototype.ngOnChanges = /**
2313
- * @param {?} changes
2314
- * @return {?}
2315
- */
2316
- function (changes) {
2317
- // if gt texts have changed...
2318
- if (changes['gtTexts']) {
2319
- // ...extend gtOptions default values with values passed into component
2320
- this.gtTexts = /** @type {?} */ (this.extend(this.gtDefaultTexts, this.gtTexts));
2321
- }
2322
- // if lazy loading data and paging information is available...
2323
- if (this.gtOptions.lazyLoad && this.gtInfo) {
2324
- // ...calculate total number of pages
2325
- this.gtInfo.pageTotal = Math.ceil(this.gtInfo.recordsAfterSearch / this.gtInfo.recordLength);
2326
- // ...declare store position
2327
- var /** @type {?} */ storePosition = this.gtInfo.pageCurrent - 1;
2328
- // ...and if store is empty or page length has changed...
2329
- if (this.store.length === 0 ||
2330
- this.store[0].length !== this.gtInfo.recordLength) {
2331
- // ...create store
2332
- this.store = this.createStore(this.gtInfo.recordsAfterSearch, this.gtInfo.recordLength);
2333
- }
2334
- // ...store retrieved data in store at store position
2335
- this.store[storePosition] = this.gtData;
2336
- this.gtInfo.visibleRecords = __spread(this.gtData); // add visible rows
2337
- // replace data with store
2338
- this._gtData = this.store;
2339
- this.loading = false;
2340
- this.updateRecordRange();
2341
- this.gtEvent.emit({
2342
- name: 'gt-info',
2343
- value: this.gtInfo
2344
- });
2345
- }
2346
- else if (this._gtData &&
2347
- this._gtData.length >= 0 &&
2348
- changes['gtData'] &&
2349
- changes['gtData'].previousValue) {
2350
- this.loading = false;
2351
- }
2352
- else if (changes['gtData'] &&
2353
- changes['gtData'].firstChange &&
2354
- this._gtData &&
2355
- this._gtData.length > 0) {
2356
- this.loading = false;
2357
- }
2358
- };
2359
- /**
2360
- * @param {?} index
2361
- * @param {?} item
2362
- * @return {?}
2363
- */
2364
- GenericTableComponent.prototype.trackByFn = /**
2365
- * @param {?} index
2366
- * @param {?} item
2367
- * @return {?}
2368
- */
2369
- function (index, item) {
2370
- return item.$$gtRowId;
2371
- };
2372
- /**
2373
- * @param {?} index
2374
- * @param {?} item
2375
- * @return {?}
2376
- */
2377
- GenericTableComponent.prototype.trackByColumnFn = /**
2378
- * @param {?} index
2379
- * @param {?} item
2380
- * @return {?}
2381
- */
2382
- function (index, item) {
2383
- return item.objectKey;
2384
- };
2385
- /**
2386
- * @return {?}
2387
- */
2388
- GenericTableComponent.prototype.ngOnDestroy = /**
2389
- * @return {?}
2390
- */
2391
- function () {
2392
- // remove listener
2393
- this._stopListeningForKeydownEvent();
2394
- };
2395
- GenericTableComponent.decorators = [
2396
- { type: core.Component, args: [{
2397
- selector: 'generic-table',
2398
- template: "<table class=\"table\" ngClass=\"{{gtClasses}} {{gtOptions.stack ? 'table-stacked':''}}\"\n *ngIf=\"gtFields && gtSettings && (gtFields | gtVisible:gtSettings:refreshPipe).length > 0\">\n <thead>\n <tr>\n <th class=\"gt-sort-label\" *ngIf=\"gtOptions.stack\">{{gtTexts.sortLabel}}</th>\n <th *ngFor=\"let column of gtSettings | gtVisible:gtSettings:refreshPipe\"\n ngClass=\"{{column.objectKey +'-column' | dashCase}} {{gtFields | gtProperty:column.objectKey:'classNames'}} {{column.sortEnabled ? 'sort-'+column.sort:''}} {{column.sortEnabled && column.sortOrder >= 0 ? 'sort-order-'+column.sortOrder:''}} {{ gtFields | gtColumnClass:column }}\"\n (click)=\"column.sortEnabled ? gtSort(column.objectKey,$event):'';\">\n <span *ngIf=\"!(gtFields | gtProperty:column.objectKey:'header')\">{{gtFields | gtProperty:column.objectKey:'name'}}</span>\n <gt-custom-component-factory *ngIf=\"(gtFields | gtProperty:column.objectKey:'header')\"\n [type]=\"(gtFields | gtProperty:column.objectKey:'header')?.type\"\n [injector]=\"(gtFields | gtProperty:column.objectKey:'header')?.injector\"\n [column]=\"gtFields | gtProperty:column.objectKey:'name'\"></gt-custom-component-factory>\n <gt-checkbox *ngIf=\"(gtFields | gtProperty:column.objectKey:'columnComponent')?.type === 'checkbox'\" [checked]=\"(gtOptions.lazyLoad ? lazyAllSelected:selectedRows.length === gtData.length)\" (changed)=\"toggleAllRows()\"></gt-checkbox>\n </th>\n </tr>\n </thead>\n <ng-template\n [ngIf]=\"gtTotals && (gtOptions.lazyLoad === false ? (gtData | gtFilter:gtInfo.filter:gtInfo:refreshFilter:gtData.length | gtSearch:gtInfo.searchTerms:gtInfo:gtSettings:gtFields:gtData.length).length > 0 : gtData.length > 0)\">\n <thead class=\"gt-totals\">\n <tr *ngFor=\"let total of gtTotals | gtTotalsPosition\">\n <td *ngFor=\"let column of gtSettings | gtVisible:gtSettings:refreshPipe;let i = index;\"\n ngClass=\"{{column.objectKey +'-totals-column' | dashCase}} {{gtFields | gtProperty:column.objectKey:'classNames'}} {{ gtFields | gtColumnClass:column }}\">\n <span *ngIf=\"i === 0\" class=\"float-left\">{{total.name}}</span><span\n [innerHTML]=\"total.fields[column.objectKey] | gtTotals:(total.update === false || gtOptions.lazyLoad === true) ? gtData:(gtData | gtFilter:gtInfo.filter:gtInfo:refreshFilter:gtData.length | gtSearch:gtInfo.searchTerms:gtInfo:gtSettings:gtFields:gtData.length):column.objectKey:refreshTotals\"></span>\n </td>\n </tr>\n </thead>\n <tfoot class=\"gt-totals\">\n <tr *ngFor=\"let total of gtTotals | gtTotalsPosition:'footer'\">\n <td *ngFor=\"let column of gtSettings | gtVisible:gtSettings:refreshPipe;let i = index;\"\n ngClass=\"{{column.objectKey +'-totals-column' | dashCase}} {{gtFields | gtProperty:column.objectKey:'classNames'}} {{ gtFields | gtColumnClass:column }}\">\n <span *ngIf=\"i === 0\" class=\"float-left\">{{total.name}}</span><span\n [innerHTML]=\"total.fields[column.objectKey] | gtTotals:(total.update === false || gtOptions.lazyLoad === true) ? gtData:(gtData | gtFilter:gtInfo.filter:gtInfo:refreshFilter:gtData.length | gtSearch:gtInfo.searchTerms:gtInfo:gtSettings:gtFields:gtData.length):column.objectKey:refreshTotals\"></span>\n </td>\n </tr>\n </tfoot>\n </ng-template>\n <tbody *ngIf=\"gtData && gtInfo\">\n <ng-template class=\"table-rows\" ngFor let-row let-last=\"last\" [ngForTrackBy]=\"trackByFn\"\n [ngForOf]=\"gtOptions.lazyLoad && gtInfo ? (gtData[gtInfo.pageCurrent-1]) : (gtData | gtFilter:gtInfo.filter:gtInfo:refreshFilter:gtData.length | gtSearch:gtInfo.searchTerms:gtInfo:gtSettings:gtFields:gtData.length | gtOrderBy:sortOrder:gtFields:refreshSorting:gtData.length | gtChunk:gtInfo:gtInfo.recordLength:gtInfo.pageCurrent:refreshPageArray:gtData.length:gtEvent:data | gtRowClass:gtFields)\">\n <tr [ngClass]=\"{'row-selected':metaInfo[row.$$gtRowId]?.isSelected, 'row-open':metaInfo[row.$$gtRowId]?.isOpen, 'row-loading':loading, 'row-expandable':gtRowComponent}\"\n class=\"{{row.$$gtRowClass}}\"\n (click)=\"gtOptions.rowSelection ? toggleSelect(row):rowClick(row, $event)\">\n <td *ngFor=\"let column of row | gtRender:gtSettings:gtFields:refreshPipe:loading:gtOptions.highlightSearch:gtInfo.searchTerms;trackBy:trackByColumnFn\"\n ngClass=\"{{column.objectKey +'-column' | dashCase}} {{gtFields | gtProperty:column.objectKey:'classNames'}} {{(gtFields | gtProperty:column.objectKey:'inlineEdit') ? 'gt-inline-edit':''}} {{column.edited ? 'gt-edited':''}} {{ gtFields | gtColumnClass:column:row }}\">\n <span class=\"gt-row-label\"\n *ngIf=\"gtOptions.stack\">{{(gtFields | gtProperty:column.objectKey:'stackedHeading') ? (gtFields | gtProperty:column.objectKey:'stackedHeading') : (gtFields | gtProperty:column.objectKey:'name')}}</span>\n <gt-custom-component-factory *ngIf=\"column.columnComponent && column.columnComponent.type !== 'checkbox'\" class=\"gt-row-content\"\n [type]=\"column.columnComponent.type\"\n [injector]=\"column.columnComponent.injector\" [row]=\"row\"\n [column]=\"column\" (redrawEvent)=\"redraw($event)\"\n [searchTerms]=\"gtInfo.searchTerms\" (searchEvent)=\"redraw($event)\"\n (click)=\"column.click ? column.click(row,column,$event):'';column.expand ? toggleCollapse(row, column.expand):''\"></gt-custom-component-factory>\n <span *ngIf=\"!column.columnComponent && (!(gtFields | gtProperty:column.objectKey:'inlineEdit') || ((gtFields | gtProperty:column.objectKey:'inlineEdit')?.active | gtIsObservable) && !((gtFields | gtProperty:column.objectKey:'inlineEdit')?.active | async) || (!((gtFields | gtProperty:column.objectKey:'inlineEdit')?.active | gtIsObservable) && !((gtFields | gtProperty:column.objectKey:'inlineEdit')?.active | gtIsEditable:row:refreshPipe)))\"\n class=\"gt-row-content\" [innerHTML]=\"column.renderValue\"\n (click)=\"column.click ? column.click(row,column,$event):'';column.expand ? toggleCollapse(row, column.expand):''\"></span>\n <ng-template\n [ngIf]=\"!column.columnComponent && (((gtFields | gtProperty:column.objectKey:'inlineEdit')?.active | gtIsObservable) && ((gtFields | gtProperty:column.objectKey:'inlineEdit')?.active | async) || ((gtFields | gtProperty:column.objectKey:'inlineEdit')?.active | gtIsEditable:row:refreshPipe))\">\n <ng-template [ngIf]=\"([true,'email','number','password', 'text'].indexOf((gtFields | gtProperty:column.objectKey:'inlineEdit').type) !== -1) || !(gtFields | gtProperty:column.objectKey:'inlineEdit').type\">\n <input class=\"inline-edit\" [attr.type]=\"!(gtFields | gtProperty:column.objectKey:'inlineEdit').type ? 'text' : !((gtFields | gtProperty:column.objectKey:'inlineEdit').type | gtIsObservable) ? (gtFields | gtProperty:column.objectKey:'inlineEdit').type:(gtFields | gtProperty:column.objectKey:'inlineEdit').type | async\" [(ngModel)]=\"column.renderValue\"\n (input)=\"gtUpdateColumn($event,row, column)\">\n <span class=\"gt-inline-edit-notice\">{{gtTexts.inlineEditEdited}}</span>\n </ng-template>\n <gt-dropdown\n *ngIf=\"(((gtFields | gtProperty:column.objectKey:'inlineEdit').type) && ((gtFields | gtProperty:column.objectKey:'inlineEdit').type).length > 0) || ((gtFields | gtProperty:column.objectKey:'inlineEdit').type | gtIsObservable)\"\n [options]=\"!((gtFields | gtProperty:column.objectKey:'inlineEdit').type | gtIsObservable) ? (gtFields | gtProperty:column.objectKey:'inlineEdit').type : (gtFields | gtProperty:column.objectKey:'inlineEdit').type | async\"\n [id]=\"'_' + row.$$gtRowId + '_' + column.objectKey\"\n [(selected)]=\"column.renderValue\" (selectedChange)=\"gtDropdownSelect(row, column)\">Add\n inline editing module\n </gt-dropdown>\n </ng-template>\n <ng-template [ngIf]=\"!column.columnComponent && !((gtFields | gtProperty:column.objectKey:'inlineEdit')?.active) \">\n <ng-template\n [ngIf]=\"[true,'email','number','password'].indexOf(gtFields | gtProperty:column.objectKey:'inlineEdit') !== -1\">\n <input class=\"inline-edit\" [attr.type]=\"(gtFields | gtProperty:column.objectKey:'inlineEdit') === true ? 'text':(gtFields | gtProperty:column.objectKey:'inlineEdit')\" [(ngModel)]=\"column.renderValue\"\n (input)=\"gtUpdateColumn($event,row, column)\">\n <span class=\"gt-inline-edit-notice\">{{gtTexts.inlineEditEdited}}</span>\n </ng-template>\n <gt-dropdown\n *ngIf=\"(gtFields | gtProperty:column.objectKey:'inlineEdit') && [true,'email','number','password'].indexOf(gtFields | gtProperty:column.objectKey:'inlineEdit') === -1\"\n [options]=\"gtFields | gtProperty:column.objectKey:'inlineEdit'\"\n [id]=\"'_' + row.$$gtRowId + '_' + column.objectKey\"\n [(selected)]=\"column.renderValue\" (selectedChange)=\"gtDropdownSelect(row, column)\">Add\n inline editing module\n </gt-dropdown>\n </ng-template>\n <gt-checkbox *ngIf=\"column.columnComponent && column.columnComponent.type === 'checkbox'\" [checked]=\"metaInfo[row.$$gtRowId]?.isSelected\" (changed)=\"toggleSelect(row)\"></gt-checkbox>\n </td>\n </tr>\n <tr class=\"row-expanded\" *ngIf=\"metaInfo[row.$$gtRowId]?.isOpen\">\n <td [attr.colspan]=\"(gtFields | gtVisible:gtSettings:refreshPipe).length\">\n <gt-expanding-row [row]=\"row\"\n [type]=\"expandedRow.component ? expandedRow.component:gtRowComponent\"\n [columnWidth]=\"columnWidth\"\n [gtFields]=\"gtFields\"\n [gtOptions]=\"gtOptions\"\n [gtEvent]=\"gtEvent\"\n [gtInfo]=\"gtInfo\"\n [gtSettings]=\"gtSettings\"\n [data]=\"expandedRow.data ? expandedRow.data:row\"\n (redrawEvent)=\"redraw($event)\"\n (toggleRowEvent)=\"toggleCollapse($event)\"></gt-expanding-row>\n </td>\n </tr>\n <tr *ngIf=\"gtOptions.reportColumnWidth && last\">\n <td style=\"padding: 0; border:none;\"\n *ngFor=\"let column of gtSettings | gtVisible:gtSettings:refreshPipe\" gtColumnWidth\n [objectKey]=\"column.objectKey\" [widths]=\"columnWidth\"></td>\n </tr>\n </ng-template>\n <tr *ngIf=\"gtInfo.pageTotal === 0 && (gtInfo.searchTerms || gtInfo.filter) && !loading\">\n <td class=\"gt-no-matching-results\" [attr.colspan]=\"(gtFields | gtVisible:gtSettings).length\">\n {{gtTexts.noMatchingData}}\n </td>\n </tr>\n <tr *ngIf=\"gtInfo.pageTotal === 0 && !(gtInfo.searchTerms || gtInfo.filter) && !loading\">\n <td class=\"gt-no-results\" [attr.colspan]=\"(gtFields | gtVisible:gtSettings).length\">{{gtTexts.noData}}\n </td>\n </tr>\n <tr *ngIf=\"gtInfo.pageTotal === 0 && loading\">\n <td class=\"gt-loading-data\" [attr.colspan]=\"(gtFields | gtVisible:gtSettings).length\">{{gtTexts.loading}}</td>\n </tr>\n </tbody>\n</table>\n<table class=\"table\" ngClass=\"{{gtClasses}} {{gtOptions.stack ? 'table-stacked':''}}\"\n *ngIf=\"gtFields && gtSettings && (gtFields | gtVisible:gtSettings:refreshPipe).length === 0\">\n <thead>\n <tr>\n <th class=\"gt-no-visible-columns\">{{gtTexts.noVisibleColumnsHeading}}</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td class=\"gt-no-visible-columns\">{{gtTexts.noVisibleColumns}}</td>\n </tr>\n </tbody>\n</table>\n<table class=\"table\" ngClass=\"{{gtClasses}} {{gtOptions.stack ? 'table-stacked':''}}\"\n *ngIf=\"!gtFields || !gtSettings\">\n <thead>\n <tr>\n <th class=\"gt-loading-config\">&nbsp;</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td class=\"gt-loading-config\">&nbsp;</td>\n </tr>\n </tbody>\n</table>\n"
2399
- }] }
2400
- ];
2401
- /** @nocollapse */
2402
- GenericTableComponent.ctorParameters = function () {
2403
- return [
2404
- { type: core.Renderer2, },
2405
- { type: GtMetaPipe, },
2406
- ];
2407
- };
2408
- GenericTableComponent.propDecorators = {
2409
- "gtOptions": [{ type: core.Input },],
2410
- "gtTotals": [{ type: core.Input },],
2411
- "gtFields": [{ type: core.Input },],
2412
- "gtSettings": [{ type: core.Input },],
2413
- "gtData": [{ type: core.Input },],
2414
- "gtRowComponent": [{ type: core.Input },],
2415
- "gtTexts": [{ type: core.Input },],
2416
- "gtClasses": [{ type: core.Input },],
2417
- "gtEvent": [{ type: core.Output },],
2418
- "gtInfo": [{ type: core.Input },],
2419
- };
2420
- return GenericTableComponent;
2421
- }());
2422
-
2423
- /**
2424
- * @fileoverview added by tsickle
2425
- * @suppress {checkTypes} checked by tsc
2426
- */
2427
- // unsupported: template constraints.
2428
- /**
2429
- * @template R
2430
- */
2431
- var GtVisiblePipe = /** @class */ (function () {
2432
- function GtVisiblePipe() {
2433
- /**
2434
- * Sort by column order
2435
- */
2436
- this.getColumnOrder = function (a, b) {
2437
- if (a.columnOrder < b.columnOrder) {
2438
- return -1;
2439
- }
2440
- if (a.columnOrder > b.columnOrder || typeof a.columnOrder === 'undefined') {
2441
- return 1;
2442
- }
2443
- return 0;
2444
- };
2445
- }
2446
- /**
2447
- * @param {?} array
2448
- * @param {?} settings
2449
- * @param {?=} refreshPipe
2450
- * @return {?}
2451
- */
2452
- GtVisiblePipe.prototype.transform = /**
2453
- * @param {?} array
2454
- * @param {?} settings
2455
- * @param {?=} refreshPipe
2456
- * @return {?}
2457
- */
2458
- function (array, settings, refreshPipe) {
2459
- var /** @type {?} */ visibleColumns = settings
2460
- .sort(this.getColumnOrder)
2461
- .map(function (setting) {
2462
- if (setting.visible !== false && setting.enabled !== false) {
2463
- return setting.objectKey;
2464
- }
2465
- });
2466
- return array
2467
- .filter(function (column) {
2468
- return visibleColumns.indexOf(column.objectKey) !== -1;
2469
- })
2470
- .sort(function (a, b) {
2471
- return visibleColumns.indexOf(a.objectKey) <
2472
- visibleColumns.indexOf(b.objectKey)
2473
- ? -1
2474
- : 1;
2475
- });
2476
- };
2477
- GtVisiblePipe.decorators = [
2478
- { type: core.Pipe, args: [{
2479
- name: 'gtVisible'
2480
- },] }
2481
- ];
2482
- return GtVisiblePipe;
2483
- }());
2484
-
2485
- /**
2486
- * @fileoverview added by tsickle
2487
- * @suppress {checkTypes} checked by tsc
2488
- */
2489
- // unsupported: template constraints.
2490
- /**
2491
- * @template R
2492
- */
2493
- var GtSearchPipe = /** @class */ (function () {
2494
- function GtSearchPipe() {
2495
- /**
2496
- * Return property
2497
- */
2498
- this.getProperty = function (array, key) {
2499
- for (var /** @type {?} */ i = 0; i < array.length; i++) {
2500
- if (array[i].objectKey === key) {
2501
- return array[i];
2502
- }
2503
- }
2504
- };
2505
- }
2506
- /**
2507
- * @param {?} allRows
2508
- * @param {?} searchTerms
2509
- * @param {?} gtInfo
2510
- * @param {?} settings
2511
- * @param {?} fields
2512
- * @param {?} refreshData
2513
- * @return {?}
2514
- */
2515
- GtSearchPipe.prototype.transform = /**
2516
- * @param {?} allRows
2517
- * @param {?} searchTerms
2518
- * @param {?} gtInfo
2519
- * @param {?} settings
2520
- * @param {?} fields
2521
- * @param {?} refreshData
2522
- * @return {?}
2523
- */
2524
- function (allRows, searchTerms, gtInfo, settings, fields, refreshData) {
2525
- // if no search terms are defined...
2526
- if (!searchTerms || searchTerms.replace(/"/g, '').length === 0) {
2527
- // ...return all rows
2528
- var /** @type {?} */ length_1 = allRows === null ? 0 : allRows.length;
2529
- gtInfo.recordsAfterSearch = length_1;
2530
- return allRows;
2531
- }
2532
- var /** @type {?} */ searchFunction = {};
2533
- var /** @type {?} */ fieldsTemp = [];
2534
- for (var /** @type {?} */ k = 0; k < fields.length; k++) {
2535
- var /** @type {?} */ field = fields[k];
2536
- // check if field should be included in global search
2537
- var /** @type {?} */ include = this.getProperty(settings, field.objectKey).search === false
2538
- ? false
2539
- : true;
2540
- // if include...
2541
- if (include) {
2542
- // ...and if search function is defined...
2543
- if (typeof field.search === 'function') {
2544
- // ...add it as search function for field
2545
- searchFunction[field.objectKey] = field.search;
2546
- }
2547
- // ...if no search function is defined but value function is defined...
2548
- else if (typeof field.value === 'function') {
2549
- // ...add it as search function for field
2550
- searchFunction[field.objectKey] = field.value;
2551
- }
2552
- // ...push it to our fields array
2553
- fieldsTemp.push(field);
2554
- }
2555
- }
2556
- var /** @type {?} */ filteredRows = [];
2557
- searchTerms = typeof searchTerms === 'undefined' ? '' : searchTerms;
2558
- var /** @type {?} */ searchTermsArray = searchTerms.toLowerCase().match(/(".*"|[^\s]+)/g);
2559
- for (var /** @type {?} */ i = 0; i < allRows.length; i++) {
2560
- var /** @type {?} */ row = allRows[i];
2561
- var /** @type {?} */ string = '';
2562
- for (var /** @type {?} */ j = 0; j < fieldsTemp.length; j++) {
2563
- var /** @type {?} */ separator = j === 0 ? '' : ' & ';
2564
- string += searchFunction[fieldsTemp[j].objectKey]
2565
- ? separator + searchFunction[fieldsTemp[j].objectKey](row, j)
2566
- : separator + row[fieldsTemp[j].objectKey];
2567
- }
2568
- string = string.toLowerCase();
2569
- var /** @type {?} */ match = true;
2570
- for (var /** @type {?} */ k = 0; k < searchTermsArray.length; k++) {
2571
- var /** @type {?} */ term = searchTermsArray[k].replace(/"/g, '');
2572
- match = string.indexOf(term) !== -1;
2573
- if (!match) {
2574
- break;
2575
- }
2576
- }
2577
- if (match) {
2578
- filteredRows.push(row);
2579
- }
2580
- }
2581
- gtInfo.recordsAfterSearch = filteredRows.length;
2582
- // gtInfo.refresh(filteredRows.length,gt);
2583
- return filteredRows;
2584
- };
2585
- GtSearchPipe.decorators = [
2586
- { type: core.Pipe, args: [{
2587
- name: 'gtSearch'
2588
- },] }
2589
- ];
2590
- return GtSearchPipe;
2591
- }());
2592
-
2593
- /**
2594
- * @fileoverview added by tsickle
2595
- * @suppress {checkTypes} checked by tsc
2596
- */
2597
- var GtIsEditablePipe = /** @class */ (function () {
2598
- function GtIsEditablePipe() {
2599
- }
2600
- /**
2601
- * @param {?} property
2602
- * @param {?} row
2603
- * @param {?} refreshPipe
2604
- * @return {?}
2605
- */
2606
- GtIsEditablePipe.prototype.transform = /**
2607
- * @param {?} property
2608
- * @param {?} row
2609
- * @param {?} refreshPipe
2610
- * @return {?}
2611
- */
2612
- function (property, row, refreshPipe) {
2613
- if (typeof property === 'function') {
2614
- return property(row);
2615
- }
2616
- else {
2617
- return false;
2618
- }
2619
- };
2620
- GtIsEditablePipe.decorators = [
2621
- { type: core.Pipe, args: [{
2622
- name: 'gtIsEditable'
2623
- },] }
2624
- ];
2625
- return GtIsEditablePipe;
2626
- }());
2627
-
2628
- /**
2629
- * @fileoverview added by tsickle
2630
- * @suppress {checkTypes} checked by tsc
2631
- */
2632
- var GtIsObservablePipe = /** @class */ (function () {
2633
- function GtIsObservablePipe() {
2634
- }
2635
- /**
2636
- * @param {?} input
2637
- * @return {?}
2638
- */
2639
- GtIsObservablePipe.prototype.transform = /**
2640
- * @param {?} input
2641
- * @return {?}
2642
- */
2643
- function (input) {
2644
- return input instanceof rxjs.Observable;
2645
- };
2646
- GtIsObservablePipe.decorators = [
2647
- { type: core.Pipe, args: [{
2648
- name: 'gtIsObservable'
2649
- },] }
2650
- ];
2651
- return GtIsObservablePipe;
2652
- }());
2653
-
2654
- /**
2655
- * @fileoverview added by tsickle
2656
- * @suppress {checkTypes} checked by tsc
2657
- */
2658
- var GtHighlightPipe = /** @class */ (function () {
2659
- function GtHighlightPipe(sanitizer) {
2660
- this.sanitizer = sanitizer;
2661
- }
2662
- /**
2663
- * @param {?} text
2664
- * @param {?} searchTerm
2665
- * @return {?}
2666
- */
2667
- GtHighlightPipe.prototype.transform = /**
2668
- * @param {?} text
2669
- * @param {?} searchTerm
2670
- * @return {?}
2671
- */
2672
- function (text, searchTerm) {
2673
- var /** @type {?} */ haystackAlwaysString = text + '';
2674
- var /** @type {?} */ highlightedText = haystackAlwaysString; // fallback
2675
- var /** @type {?} */ searchPattern;
2676
- try {
2677
- searchPattern = new RegExp('(' +
2678
- searchTerm
2679
- .toLowerCase()
2680
- .match(/".*?"|[^ ]+/g) // extract words
2681
- .map(function (needle) { return needle.replace(/"(.*?)"/, '$1'); } // strip away '"'
2682
- // strip away '"'
2683
- )
2684
- .join('|') + // combine words
2685
- ')', 'ig');
2686
- }
2687
- catch ( /** @type {?} */error) {
2688
- return this.sanitizer.bypassSecurityTrustHtml(highlightedText);
2689
- }
2690
- var /** @type {?} */ containsTagPattern = /(<.*?>)(.*)(<\/.*?>)/gi;
2691
- var /** @type {?} */ containsTagMatches = containsTagPattern.exec(haystackAlwaysString);
2692
- if (containsTagMatches) {
2693
- // tag exists in haystack
2694
- highlightedText =
2695
- containsTagMatches[1] +
2696
- containsTagMatches[2].replace(searchPattern, '<span class="gt-highlight-search">$1</span>') +
2697
- containsTagMatches[3];
2698
- }
2699
- else {
2700
- highlightedText = haystackAlwaysString.replace(searchPattern, '<span class="gt-highlight-search">$1</span>');
2701
- }
2702
- return this.sanitizer.bypassSecurityTrustHtml(highlightedText);
2703
- };
2704
- GtHighlightPipe.decorators = [
2705
- { type: core.Pipe, args: [{
2706
- name: 'gtHighlight'
2707
- },] }
2708
- ];
2709
- /** @nocollapse */
2710
- GtHighlightPipe.ctorParameters = function () {
2711
- return [
2712
- { type: platformBrowser.DomSanitizer, },
2713
- ];
2714
- };
2715
- return GtHighlightPipe;
2716
- }());
2717
-
2718
- /**
2719
- * @fileoverview added by tsickle
2720
- * @suppress {checkTypes} checked by tsc
2721
- */
2722
- var GtColumnClassPipe = /** @class */ (function () {
2723
- function GtColumnClassPipe() {
2724
- }
2725
- /**
2726
- * @param {?} gtFields
2727
- * @param {?} column
2728
- * @param {?=} row
2729
- * @return {?}
2730
- */
2731
- GtColumnClassPipe.prototype.transform = /**
2732
- * @param {?} gtFields
2733
- * @param {?} column
2734
- * @param {?=} row
2735
- * @return {?}
2736
- */
2737
- function (gtFields, column, row) {
2738
- // find columns with columnClass property defined
2739
- var /** @type {?} */ COLUMN_WITH_CLASS = gtFields
2740
- .map(function (field) { return field; })
2741
- .filter(function (field) { return field.columnClass && field.objectKey === column.objectKey; })[0];
2742
- if (!COLUMN_WITH_CLASS) {
2743
- return;
2744
- }
2745
- else if (typeof COLUMN_WITH_CLASS.columnClass === 'function') {
2746
- // if column class is a function, try using the function...
2747
- try {
2748
- return COLUMN_WITH_CLASS.columnClass(row, column);
2749
- }
2750
- catch ( /** @type {?} */error) {
2751
- console.log('Error when trying to get column class name using formula.', error);
2752
- }
2753
- }
2754
- else {
2755
- // if not a function, return plain string value
2756
- return COLUMN_WITH_CLASS.columnClass;
2757
- }
2758
- };
2759
- GtColumnClassPipe.decorators = [
2760
- { type: core.Pipe, args: [{
2761
- name: 'gtColumnClass'
2762
- },] }
2763
- ];
2764
- return GtColumnClassPipe;
2765
- }());
2766
-
2767
- /**
2768
- * @fileoverview added by tsickle
2769
- * @suppress {checkTypes} checked by tsc
2770
- */
2771
- var GtRowClassPipe = /** @class */ (function () {
2772
- function GtRowClassPipe() {
2773
- }
2774
- /**
2775
- * @param {?} array
2776
- * @param {?} gtFields
2777
- * @return {?}
2778
- */
2779
- GtRowClassPipe.prototype.transform = /**
2780
- * @param {?} array
2781
- * @param {?} gtFields
2782
- * @return {?}
2783
- */
2784
- function (array, gtFields) {
2785
- if (array) {
2786
- // find columns with rowClass property defined
2787
- var /** @type {?} */ COLUMNS_WITH_CLASS = gtFields
2788
- .map(function (column) { return column; })
2789
- .filter(function (column) { return column.rowClass; });
2790
- COLUMNS_WITH_CLASS.map(function (column) {
2791
- // for each column with rowClass property defined...
2792
- array.map(function (row) {
2793
- // loop through rows and set row class
2794
- if (typeof column.rowClass === 'function') {
2795
- // if row class is a function, try using the function...
2796
- try {
2797
- if (row.$$gtRowClass) {
2798
- row.$$gtRowClass = row.$$gtRowClass.concat(' ' + column.rowClass(row, column));
2799
- }
2800
- else {
2801
- row.$$gtRowClass = column.rowClass(row, column);
2802
- }
2803
- }
2804
- catch ( /** @type {?} */error) {
2805
- console.log('Error when trying to get row class name using formula.', error);
2806
- }
2807
- }
2808
- else {
2809
- // if not a function, return plain string value
2810
- if (row.$$gtRowClass) {
2811
- row.$$gtRowClass = row.$$gtRowClass.concat(' ' + column.rowClass);
2812
- }
2813
- else {
2814
- row.$$gtRowClass = column.rowClass;
2815
- }
2816
- }
2817
- });
2818
- });
2819
- }
2820
- return array;
2821
- };
2822
- GtRowClassPipe.decorators = [
2823
- { type: core.Pipe, args: [{
2824
- name: 'gtRowClass'
2825
- },] }
2826
- ];
2827
- return GtRowClassPipe;
2828
- }());
2829
-
2830
- /**
2831
- * @fileoverview added by tsickle
2832
- * @suppress {checkTypes} checked by tsc
2833
- */
2834
- var GtTotalsPositionPipe = /** @class */ (function () {
2835
- function GtTotalsPositionPipe() {
2836
- }
2837
- /**
2838
- * @param {?} array
2839
- * @param {?=} position
2840
- * @return {?}
2841
- */
2842
- GtTotalsPositionPipe.prototype.transform = /**
2843
- * @param {?} array
2844
- * @param {?=} position
2845
- * @return {?}
2846
- */
2847
- function (array, position) {
2848
- if (position === void 0) {
2849
- position = 'header';
2850
- }
2851
- return array.filter(function (total) {
2852
- // if no position is defined assume position to be header
2853
- var /** @type {?} */ totalPosition = total.position ? total.position : 'header';
2854
- return totalPosition === position;
2855
- });
2856
- };
2857
- GtTotalsPositionPipe.decorators = [
2858
- { type: core.Pipe, args: [{
2859
- name: 'gtTotalsPosition'
2860
- },] }
2861
- ];
2862
- return GtTotalsPositionPipe;
2863
- }());
2864
-
2865
- /**
2866
- * @fileoverview added by tsickle
2867
- * @suppress {checkTypes} checked by tsc
2868
- */
2869
- var GtTotalsPipe = /** @class */ (function () {
2870
- function GtTotalsPipe() {
2871
- }
2872
- /**
2873
- * @param {?} value
2874
- * @param {?} data
2875
- * @param {?} objectKey
2876
- * @param {?} refresh
2877
- * @return {?}
2878
- */
2879
- GtTotalsPipe.prototype.transform = /**
2880
- * @param {?} value
2881
- * @param {?} data
2882
- * @param {?} objectKey
2883
- * @param {?} refresh
2884
- * @return {?}
2885
- */
2886
- function (value, data, objectKey, refresh) {
2887
- var /** @type {?} */ output;
2888
- if (data.length === 0) {
2889
- return;
2890
- }
2891
- if (typeof value === 'function') {
2892
- output = value(data, objectKey);
2893
- }
2894
- else if (value) {
2895
- output = value;
2896
- }
2897
- else {
2898
- output = '';
2899
- }
2900
- return output;
2901
- };
2902
- GtTotalsPipe.decorators = [
2903
- { type: core.Pipe, args: [{
2904
- name: 'gtTotals'
2905
- },] }
2906
- ];
2907
- return GtTotalsPipe;
2908
- }());
2909
-
2910
- /**
2911
- * @fileoverview added by tsickle
2912
- * @suppress {checkTypes} checked by tsc
2913
- */
2914
- // unsupported: template constraints.
2915
- /**
2916
- * @template R
2917
- */
2918
- var GtOrderByPipe = /** @class */ (function () {
2919
- function GtOrderByPipe() {
2920
- /**
2921
- * Return property
2922
- */
2923
- this.getProperty = function (array, key) {
2924
- for (var /** @type {?} */ i = 0; i < array.length; i++) {
2925
- if (array[i].objectKey === key) {
2926
- return array[i];
2927
- }
2928
- }
2929
- };
2930
- }
2931
- /**
2932
- * @param {?} a
2933
- * @param {?} b
2934
- * @return {?}
2935
- */
2936
- GtOrderByPipe._orderByComparator = /**
2937
- * @param {?} a
2938
- * @param {?} b
2939
- * @return {?}
2940
- */
2941
- function (a, b) {
2942
- // sort boolean values as strings
2943
- if (typeof a === 'boolean') {
2944
- a = a.toString();
2945
- }
2946
- if (typeof b === 'boolean') {
2947
- b = b.toString();
2948
- }
2949
- if (isNaN(parseFloat(a)) ||
2950
- !isFinite(a) ||
2951
- (isNaN(parseFloat(b)) || !isFinite(b))) {
2952
- if (b === null ||
2953
- (typeof b === 'undefined' && (a !== null && typeof a !== 'undefined'))) {
2954
- return 1;
2955
- }
2956
- if (a === null ||
2957
- (typeof a === 'undefined' && (b !== null && typeof b !== 'undefined'))) {
2958
- return -1;
2959
- }
2960
- // isn't a number so lowercase the string to properly compare
2961
- try {
2962
- if (a.toLowerCase() < b.toLowerCase()) {
2963
- return -1;
2964
- }
2965
- if (a.toLowerCase() > b.toLowerCase()) {
2966
- return 1;
2967
- }
2968
- }
2969
- catch ( /** @type {?} */error) {
2970
- return 0;
2971
- }
2972
- }
2973
- else {
2974
- // parse strings as numbers to compare properly
2975
- if (parseFloat(a) < parseFloat(b)) {
2976
- return -1;
2977
- }
2978
- if (parseFloat(a) > parseFloat(b)) {
2979
- return 1;
2980
- }
2981
- }
2982
- return 0; // equal each other
2983
- };
2984
- /**
2985
- * Return sort function
2986
- * @param {?} field
2987
- * @return {?}
2988
- */
2989
- GtOrderByPipe.prototype.getSortFunction = /**
2990
- * Return sort function
2991
- * @param {?} field
2992
- * @return {?}
2993
- */
2994
- function (field) {
2995
- if (!field) {
2996
- // console.log('error trying to sort undefined field');
2997
- return false;
2998
- }
2999
- if (typeof field.sort === 'function') {
3000
- return field.sort;
3001
- }
3002
- else if (typeof field.value === 'function') {
3003
- return field.value;
3004
- }
3005
- else {
3006
- return false;
3007
- }
3008
- };
3009
- /**
3010
- * @param {?} input
3011
- * @param {?} sortByProperties
3012
- * @param {?} fields
3013
- * @param {?} refreshSorting
3014
- * @param {?} refreshData
3015
- * @return {?}
3016
- */
3017
- GtOrderByPipe.prototype.transform = /**
3018
- * @param {?} input
3019
- * @param {?} sortByProperties
3020
- * @param {?} fields
3021
- * @param {?} refreshSorting
3022
- * @param {?} refreshData
3023
- * @return {?}
3024
- */
3025
- function (input, sortByProperties, fields, refreshSorting, refreshData) {
3026
- var _this = this;
3027
- if (!Array.isArray(input) || input === null) {
3028
- return input;
3029
- }
3030
- if (!Array.isArray(sortByProperties) ||
3031
- (Array.isArray(sortByProperties) && sortByProperties.length === 1)) {
3032
- var /** @type {?} */ propertyToCheck = sortByProperties[0];
3033
- var /** @type {?} */ desc_1 = propertyToCheck.substr(0, 1) === '-';
3034
- // basic array
3035
- if (!propertyToCheck ||
3036
- propertyToCheck === '-' ||
3037
- propertyToCheck === '+') {
3038
- return !desc_1 ? input.sort() : input.sort().reverse();
3039
- }
3040
- else {
3041
- var /** @type {?} */ property_1 = propertyToCheck.substr(0, 1) === '+' ||
3042
- propertyToCheck.substr(0, 1) === '-'
3043
- ? propertyToCheck.substr(1)
3044
- : propertyToCheck;
3045
- // check if custom sort function is defined
3046
- var /** @type {?} */ sortFunction_1 = this.getSortFunction(this.getProperty(fields, property_1));
3047
- // console.log(property);
3048
- return input.sort(function (a, b) {
3049
- // use custom sort function if one is defined
3050
- var /** @type {?} */ propertyA = sortFunction_1 === false
3051
- ? property_1 === '$$gtRowId'
3052
- ? +a.$$gtRowId.split('_')[0]
3053
- : a[property_1]
3054
- : sortFunction_1(a);
3055
- var /** @type {?} */ propertyB = sortFunction_1 === false
3056
- ? property_1 === '$$gtRowId'
3057
- ? +b.$$gtRowId.split('_')[0]
3058
- : b[property_1]
3059
- : sortFunction_1(b);
3060
- // if both values are undefined...
3061
- if (typeof propertyA === 'undefined' &&
3062
- typeof propertyB === 'undefined') {
3063
- // ...skip comparison
3064
- return;
3065
- }
3066
- return !desc_1
3067
- ? GtOrderByPipe._orderByComparator(propertyA, propertyB)
3068
- : -GtOrderByPipe._orderByComparator(propertyA, propertyB);
3069
- });
3070
- }
3071
- }
3072
- else {
3073
- // loop over property of the array in order and sort
3074
- return input.sort(function (a, b) {
3075
- // console.log('multiple');
3076
- for (var /** @type {?} */ i = 0; i < sortByProperties.length; i++) {
3077
- var /** @type {?} */ desc = sortByProperties[i].substr(0, 1) === '-';
3078
- var /** @type {?} */ property = sortByProperties[i].substr(0, 1) === '+' ||
3079
- sortByProperties[i].substr(0, 1) === '-'
3080
- ? sortByProperties[i].substr(1)
3081
- : sortByProperties[i];
3082
- // console.log(property);
3083
- // check if custom sort function is defined
3084
- var /** @type {?} */ sortFunction = _this.getSortFunction(_this.getProperty(fields, property));
3085
- // use custom sort function if one is defined
3086
- var /** @type {?} */ propertyA = sortFunction === false
3087
- ? property === '$$gtRowId'
3088
- ? +a.$$gtRowId.split('_')[0]
3089
- : a[property]
3090
- : sortFunction(a);
3091
- var /** @type {?} */ propertyB = sortFunction === false
3092
- ? property === '$$gtRowId'
3093
- ? +b.$$gtRowId.split('_')[0]
3094
- : b[property]
3095
- : sortFunction(b);
3096
- var /** @type {?} */ comparison = !desc
3097
- ? GtOrderByPipe._orderByComparator(propertyA, propertyB)
3098
- : -GtOrderByPipe._orderByComparator(propertyA, propertyB);
3099
- // don't return 0 yet in case of needing to sort by next property
3100
- if (comparison !== 0) {
3101
- return comparison;
3102
- }
3103
- }
3104
- return 0; // equal each other
3105
- });
3106
- }
3107
- };
3108
- GtOrderByPipe.decorators = [
3109
- { type: core.Pipe, args: [{
3110
- name: 'gtOrderBy'
3111
- },] }
3112
- ];
3113
- return GtOrderByPipe;
3114
- }());
3115
-
3116
- /**
3117
- * @fileoverview added by tsickle
3118
- * @suppress {checkTypes} checked by tsc
3119
- */
3120
- var GtFilterPipe = /** @class */ (function () {
3121
- function GtFilterPipe() {
3122
- }
3123
- // @Output() filterInfo = new EventEmitter();
3124
- /**
3125
- * @param {?} allRows
3126
- * @param {?} filterBy
3127
- * @param {?} gtInfo
3128
- * @param {?} refreshFilter
3129
- * @param {?} refreshData
3130
- * @return {?}
3131
- */
3132
- GtFilterPipe.prototype.transform = /**
3133
- * @param {?} allRows
3134
- * @param {?} filterBy
3135
- * @param {?} gtInfo
3136
- * @param {?} refreshFilter
3137
- * @param {?} refreshData
3138
- * @return {?}
3139
- */
3140
- function (allRows, filterBy, gtInfo, refreshFilter, refreshData) {
3141
- // console.log(allRows,filterBy);
3142
- gtInfo.recordsAll = allRows.length;
3143
- if (!Array.isArray(allRows) || !filterBy) {
3144
- // gtInfo.filtered = false;
3145
- var /** @type {?} */ length_1 = allRows === null ? 0 : allRows.length;
3146
- gtInfo.recordsAfterFilter = length_1;
3147
- return allRows;
3148
- }
3149
- var /** @type {?} */ output = [];
3150
- for (var /** @type {?} */ i = 0; i < allRows.length; i++) {
3151
- var /** @type {?} */ rowObject = allRows[i];
3152
- var /** @type {?} */ match = true;
3153
- for (var /** @type {?} */ property in filterBy) {
3154
- if (filterBy.hasOwnProperty(property)) {
3155
- // console.log(property);
3156
- // console.log(filter[property].indexOf(obj[property]));
3157
- if (filterBy[property].indexOf(rowObject[property]) === -1) {
3158
- match = false;
3159
- }
3160
- }
3161
- }
3162
- if (match) {
3163
- output.push(rowObject);
3164
- }
3165
- }
3166
- gtInfo.recordsAfterFilter = output.length; // .emit(output.length);
3167
- return output;
3168
- };
3169
- GtFilterPipe.decorators = [
3170
- { type: core.Pipe, args: [{
3171
- name: 'gtFilter'
3172
- },] }
3173
- ];
3174
- return GtFilterPipe;
3175
- }());
3176
-
3177
- /**
3178
- * @fileoverview added by tsickle
3179
- * @suppress {checkTypes} checked by tsc
3180
- */
3181
- var GtChunkPipe = /** @class */ (function () {
3182
- function GtChunkPipe() {
3183
- }
3184
- /**
3185
- * @param {?} array
3186
- * @param {?} gtInfo
3187
- * @param {?} chunkSize
3188
- * @param {?} page
3189
- * @param {?} refreshPageArray
3190
- * @param {?} refreshData
3191
- * @param {?} gtEvent
3192
- * @param {?} data
3193
- * @return {?}
3194
- */
3195
- GtChunkPipe.prototype.transform = /**
3196
- * @param {?} array
3197
- * @param {?} gtInfo
3198
- * @param {?} chunkSize
3199
- * @param {?} page
3200
- * @param {?} refreshPageArray
3201
- * @param {?} refreshData
3202
- * @param {?} gtEvent
3203
- * @param {?} data
3204
- * @return {?}
3205
- */
3206
- function (array, gtInfo, chunkSize, page, refreshPageArray, refreshData, gtEvent, data) {
3207
- if (!Array.isArray(array)) {
3208
- return array;
3209
- }
3210
- data.exportData = array; // store data for export
3211
- var /** @type {?} */ PAGES = [];
3212
- var /** @type {?} */ ENTRIES = array.length;
3213
- for (var /** @type {?} */ i = 0; i < ENTRIES; i += chunkSize) {
3214
- PAGES.push(array.slice(i, i + chunkSize));
3215
- }
3216
- gtInfo.visibleRecords = !PAGES[page - 1] ? [] : __spread(PAGES[page - 1]); // add visible rows
3217
- gtInfo.pageTotal = PAGES.length; // add number of pages
3218
- setTimeout(function () {
3219
- return gtEvent.emit({
3220
- name: 'gt-info',
3221
- value: gtInfo
3222
- });
3223
- }, 0);
3224
- return PAGES[page - 1];
3225
- };
3226
- GtChunkPipe.decorators = [
3227
- { type: core.Pipe, args: [{
3228
- name: 'gtChunk'
3229
- },] }
3230
- ];
3231
- return GtChunkPipe;
3232
- }());
3233
-
3234
- /**
3235
- * @fileoverview added by tsickle
3236
- * @suppress {checkTypes} checked by tsc
3237
- */
3238
- // unsupported: template constraints.
3239
- /**
3240
- * @template R
3241
- */
3242
- var GtPropertyPipe = /** @class */ (function () {
3243
- function GtPropertyPipe() {
3244
- }
3245
- /**
3246
- * @param {?} config
3247
- * @param {?} objectKey
3248
- * @param {?} property
3249
- * @param {?=} refresh
3250
- * @return {?}
3251
- */
3252
- GtPropertyPipe.prototype.transform = /**
3253
- * @param {?} config
3254
- * @param {?} objectKey
3255
- * @param {?} property
3256
- * @param {?=} refresh
3257
- * @return {?}
3258
- */
3259
- function (config, objectKey, property, refresh) {
3260
- var /** @type {?} */ output = null;
3261
- try {
3262
- for (var /** @type {?} */ i = 0; i < config.length; i++) {
3263
- if (config[i].objectKey === objectKey) {
3264
- output = config[i][property];
3265
- }
3266
- }
3267
- }
3268
- catch ( /** @type {?} */error) {
3269
- console.log('cannot read property: "' +
3270
- property +
3271
- '" on missing key: "' +
3272
- objectKey +
3273
- '" in config.', error);
3274
- }
3275
- return output;
3276
- };
3277
- GtPropertyPipe.decorators = [
3278
- { type: core.Pipe, args: [{
3279
- name: 'gtProperty'
3280
- },] }
3281
- ];
3282
- return GtPropertyPipe;
3283
- }());
3284
-
3285
- /**
3286
- * @fileoverview added by tsickle
3287
- * @suppress {checkTypes} checked by tsc
3288
- */
3289
- var DashCasePipe = /** @class */ (function () {
3290
- function DashCasePipe() {
3291
- }
3292
- /**
3293
- * @param {?} string
3294
- * @return {?}
3295
- */
3296
- DashCasePipe.prototype.transform = /**
3297
- * @param {?} string
3298
- * @return {?}
3299
- */
3300
- function (string) {
3301
- return string.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
3302
- };
3303
- DashCasePipe.decorators = [
3304
- { type: core.Pipe, args: [{
3305
- name: 'dashCase'
3306
- },] }
3307
- ];
3308
- return DashCasePipe;
3309
- }());
3310
-
3311
- /**
3312
- * @fileoverview added by tsickle
3313
- * @suppress {checkTypes} checked by tsc
3314
- */
3315
- // unsupported: template constraints.
3316
- /**
3317
- * @template R
3318
- */
3319
- var GtRenderPipe = /** @class */ (function () {
3320
- function GtRenderPipe(sanitizer, gtHighlightPipe) {
3321
- this.sanitizer = sanitizer;
3322
- this.gtHighlightPipe = gtHighlightPipe;
3323
- /**
3324
- * Sort by column order
3325
- */
3326
- this.getColumnOrder = function (a, b) {
3327
- if (a.columnOrder < b.columnOrder) {
3328
- return -1;
3329
- }
3330
- if (a.columnOrder > b.columnOrder || typeof a.columnOrder === 'undefined') {
3331
- return 1;
3332
- }
3333
- return 0;
3334
- };
3335
- /**
3336
- * Sort by length
3337
- */
3338
- this.getOrderByLength = function (a, b) {
3339
- return b.length - a.length;
3340
- };
3341
- /**
3342
- * Return property
3343
- */
3344
- this.getProperty = function (array, key) {
3345
- for (var /** @type {?} */ i = 0; i < array.length; i++) {
3346
- if (array[i].objectKey === key) {
3347
- return array[i];
3348
- }
3349
- }
3350
- };
3351
- }
3352
- /**
3353
- * @param {?} row
3354
- * @param {?} settings
3355
- * @param {?} fields
3356
- * @param {?} updated
3357
- * @param {?} loading
3358
- * @param {?=} highlight
3359
- * @param {?=} searchString
3360
- * @return {?}
3361
- */
3362
- GtRenderPipe.prototype.transform = /**
3363
- * @param {?} row
3364
- * @param {?} settings
3365
- * @param {?} fields
3366
- * @param {?} updated
3367
- * @param {?} loading
3368
- * @param {?=} highlight
3369
- * @param {?=} searchString
3370
- * @return {?}
3371
- */
3372
- function (row, settings, fields, updated, loading, highlight, searchString) {
3373
- if (highlight === void 0) {
3374
- highlight = false;
3375
- }
3376
- // let arr = [{"temp":123,"name":"happy"},{"temp":456,"name":"dfgdfg"},{"temp":789,"name":"asdasd"}];
3377
- // console.log(arr,arr.map(function(item){return item.temp}));
3378
- // console.log(settings.map('objectKey'));
3379
- // console.log('render');
3380
- var /** @type {?} */ columns = [];
3381
- for (var /** @type {?} */ i = 0; i < settings.length; i++) {
3382
- if (settings[i].visible !== false && settings[i].enabled !== false) {
3383
- columns.push(settings[i].objectKey);
3384
- }
3385
- }
3386
- for (var /** @type {?} */ i = 0; i < fields.length; i++) {
3387
- // console.log(!row[fields[i].objectKey]);
3388
- if (fields[i].value &&
3389
- typeof fields[i].value === 'function' &&
3390
- !row.hasOwnProperty(fields[i].objectKey)) {
3391
- row[fields[i].objectKey] = loading ? '' : fields[i].value(row);
3392
- }
3393
- }
3394
- // console.log(row);
3395
- var /** @type {?} */ keys = [];
3396
- for (var /** @type {?} */ key in row) {
3397
- // console.log(key);
3398
- if (columns.indexOf(key) !== -1) {
3399
- var /** @type {?} */ fieldSetting = void 0;
3400
- for (var /** @type {?} */ i = 0; i < fields.length; i++) {
3401
- if (fields[i].objectKey === key) {
3402
- fieldSetting = fields[i];
3403
- // console.log(fieldSetting);
3404
- }
3405
- }
3406
- var /** @type {?} */ columnObject = {
3407
- objectKey: key,
3408
- sortValue: row[key]
3409
- };
3410
- // add component if defined
3411
- if (fieldSetting.columnComponent) {
3412
- columnObject.columnComponent = fieldSetting.columnComponent;
3413
- }
3414
- if (loading) {
3415
- columnObject.renderValue = row[key] !== null ? row[key] : '';
3416
- }
3417
- else if (highlight &&
3418
- searchString &&
3419
- this.getProperty(settings, key).search !== false) {
3420
- columnObject.renderValue =
3421
- fieldSetting.render && typeof fieldSetting.render === 'function'
3422
- ? this.gtHighlightPipe.transform(fieldSetting.render(row), searchString)
3423
- : this.gtHighlightPipe.transform(row[key] !== null ? row[key] : '', searchString);
3424
- }
3425
- else {
3426
- columnObject.renderValue =
3427
- fieldSetting.render && typeof fieldSetting.render === 'function'
3428
- ? this.sanitizer.bypassSecurityTrustHtml(fieldSetting.render(row))
3429
- : row[key] !== null
3430
- ? row[key]
3431
- : '';
3432
- }
3433
- if (fieldSetting.click && typeof fieldSetting.click === 'function') {
3434
- columnObject.click = fieldSetting.click;
3435
- }
3436
- if (fieldSetting.expand) {
3437
- columnObject.expand = fieldSetting.expand;
3438
- }
3439
- keys.push(columnObject);
3440
- }
3441
- }
3442
- keys.sort(function (a, b) {
3443
- return columns.indexOf(a.objectKey) < columns.indexOf(b.objectKey)
3444
- ? -1
3445
- : 1;
3446
- });
3447
- return keys;
3448
- };
3449
- GtRenderPipe.decorators = [
3450
- { type: core.Pipe, args: [{
3451
- name: 'gtRender'
3452
- },] }
3453
- ];
3454
- /** @nocollapse */
3455
- GtRenderPipe.ctorParameters = function () {
3456
- return [
3457
- { type: platformBrowser.DomSanitizer, },
3458
- { type: GtHighlightPipe, },
3459
- ];
3460
- };
3461
- return GtRenderPipe;
3462
- }());
3463
-
3464
- /**
3465
- * @fileoverview added by tsickle
3466
- * @suppress {checkTypes} checked by tsc
3467
- */
3468
- /**
3469
- * @template C
3470
- */
3471
- var ComponentAnchorDirective = /** @class */ (function () {
3472
- function ComponentAnchorDirective(componentFactoryResolver, viewContainer) {
3473
- this.componentFactoryResolver = componentFactoryResolver;
3474
- this.viewContainer = viewContainer;
3475
- this.instance = new core.EventEmitter();
3476
- }
3477
- /**
3478
- * @return {?}
3479
- */
3480
- ComponentAnchorDirective.prototype.ngOnInit = /**
3481
- * @return {?}
3482
- */
3483
- function () {
3484
- var /** @type {?} */ factory = this.componentFactoryResolver.resolveComponentFactory(this.ctor);
3485
- var /** @type {?} */ component = this.viewContainer.createComponent(factory, 0, this.injector);
3486
- this.instance.emit(component.instance);
3487
- };
3488
- ComponentAnchorDirective.decorators = [
3489
- { type: core.Directive, args: [{
3490
- selector: '[gtComponentAnchor]'
3491
- },] }
3492
- ];
3493
- /** @nocollapse */
3494
- ComponentAnchorDirective.ctorParameters = function () {
3495
- return [
3496
- { type: core.ComponentFactoryResolver, },
3497
- { type: core.ViewContainerRef, },
3498
- ];
3499
- };
3500
- ComponentAnchorDirective.propDecorators = {
3501
- "ctor": [{ type: core.Input },],
3502
- "injector": [{ type: core.Input },],
3503
- "instance": [{ type: core.Output },],
3504
- };
3505
- return ComponentAnchorDirective;
3506
- }());
3507
-
3508
- /**
3509
- * @fileoverview added by tsickle
3510
- * @suppress {checkTypes} checked by tsc
3511
- */
3512
- var GtColumnWidthDirective = /** @class */ (function () {
3513
- function GtColumnWidthDirective(hostElement, cdRef) {
3514
- this.hostElement = hostElement;
3515
- this.cdRef = cdRef;
3516
- }
3517
- /**
3518
- * @param {?} $event
3519
- * @return {?}
3520
- */
3521
- GtColumnWidthDirective.prototype.onResize = /**
3522
- * @param {?} $event
3523
- * @return {?}
3524
- */
3525
- function ($event) {
3526
- this.checkSize();
3527
- };
3528
- /**
3529
- * @return {?}
3530
- */
3531
- GtColumnWidthDirective.prototype.ngOnInit = /**
3532
- * @return {?}
3533
- */
3534
- function () {
3535
- this.checkSize();
3536
- };
3537
- /**
3538
- * @return {?}
3539
- */
3540
- GtColumnWidthDirective.prototype.checkSize = /**
3541
- * @return {?}
3542
- */
3543
- function () {
3544
- this.widths[this.objectKey] = window
3545
- .getComputedStyle(this.hostElement.nativeElement, null)
3546
- .getPropertyValue('width');
3547
- this.cdRef.detectChanges();
3548
- };
3549
- GtColumnWidthDirective.decorators = [
3550
- { type: core.Directive, args: [{
3551
- selector: '[gtColumnWidth]'
3552
- },] }
3553
- ];
3554
- /** @nocollapse */
3555
- GtColumnWidthDirective.ctorParameters = function () {
3556
- return [
3557
- { type: core.ElementRef, },
3558
- { type: core.ChangeDetectorRef, },
3559
- ];
3560
- };
3561
- GtColumnWidthDirective.propDecorators = {
3562
- "objectKey": [{ type: core.Input },],
3563
- "widths": [{ type: core.Input },],
3564
- "onResize": [{ type: core.HostListener, args: ['window:resize', ['$event'],] },],
3565
- };
3566
- return GtColumnWidthDirective;
3567
- }());
3568
-
3569
- /**
3570
- * @fileoverview added by tsickle
3571
- * @suppress {checkTypes} checked by tsc
3572
- */
3573
- var GenericTableModule = /** @class */ (function () {
3574
- function GenericTableModule() {
3575
- }
3576
- GenericTableModule.decorators = [
3577
- { type: core.NgModule, args: [{
3578
- declarations: [
3579
- ComponentAnchorDirective,
3580
- GenericTableComponent,
3581
- GtPaginationComponent,
3582
- GtVisiblePipe,
3583
- GtRenderPipe,
3584
- DashCasePipe,
3585
- GtPropertyPipe,
3586
- GtChunkPipe,
3587
- GtFilterPipe,
3588
- GtOrderByPipe,
3589
- GtExpandingRowComponent,
3590
- GtCustomComponentFactory,
3591
- GtSearchPipe,
3592
- PaginationPipe,
3593
- GtTableInfoComponent,
3594
- TableInfoPipe,
3595
- GtMetaPipe,
3596
- GtTotalsPipe,
3597
- GtTotalsPositionPipe,
3598
- GtRowClassPipe,
3599
- GtColumnClassPipe,
3600
- GtHighlightPipe,
3601
- GtIsObservablePipe,
3602
- GtIsEditablePipe,
3603
- GtDropdownComponent,
3604
- GtColumnWidthDirective,
3605
- GtDrilldownComponent,
3606
- GtCheckboxComponent
3607
- ],
3608
- imports: [common.CommonModule, forms.FormsModule],
3609
- exports: [
3610
- GenericTableComponent,
3611
- GtPaginationComponent,
3612
- GtTableInfoComponent,
3613
- GtRenderPipe,
3614
- DashCasePipe,
3615
- GtColumnClassPipe,
3616
- GtRowClassPipe,
3617
- GtPropertyPipe,
3618
- GtCustomComponentFactory,
3619
- ComponentAnchorDirective,
3620
- GtHighlightPipe,
3621
- GtExpandingRowComponent,
3622
- GtDropdownComponent,
3623
- GtDrilldownComponent,
3624
- GtCheckboxComponent
3625
- ],
3626
- entryComponents: [GtDrilldownComponent, GtCheckboxComponent],
3627
- providers: [GtMetaPipe, GtHighlightPipe]
3628
- },] }
3629
- ];
3630
- return GenericTableModule;
3631
- }());
3632
-
3633
- /**
3634
- * @fileoverview added by tsickle
3635
- * @suppress {checkTypes} checked by tsc
3636
- */
3637
-
3638
- /**
3639
- * @fileoverview added by tsickle
3640
- * @suppress {checkTypes} checked by tsc
3641
- */
3642
-
3643
- exports.GtTableInfoComponent = GtTableInfoComponent;
3644
- exports.TableInfoPipe = TableInfoPipe;
3645
- exports.GtPaginationComponent = GtPaginationComponent;
3646
- exports.PaginationPipe = PaginationPipe;
3647
- exports.GtExpandedRow = GtExpandedRow;
3648
- exports.GtExpandingRowComponent = GtExpandingRowComponent;
3649
- exports.GtDropdownComponent = GtDropdownComponent;
3650
- exports.GtDrilldownComponent = GtDrilldownComponent;
3651
- exports.GtCustomComponent = GtCustomComponent;
3652
- exports.GtCustomComponentFactory = GtCustomComponentFactory;
3653
- exports.GtCheckboxComponent = GtCheckboxComponent;
3654
- exports.GenericTableComponent = GenericTableComponent;
3655
- exports.GenericTableModule = GenericTableModule;
3656
- exports.ɵb = ComponentAnchorDirective;
3657
- exports.ɵr = GtColumnWidthDirective;
3658
- exports.ɵf = DashCasePipe;
3659
- exports.ɵh = GtChunkPipe;
3660
- exports.ɵo = GtColumnClassPipe;
3661
- exports.ɵi = GtFilterPipe;
3662
- exports.ɵe = GtHighlightPipe;
3663
- exports.ɵq = GtIsEditablePipe;
3664
- exports.ɵp = GtIsObservablePipe;
3665
- exports.ɵa = GtMetaPipe;
3666
- exports.ɵj = GtOrderByPipe;
3667
- exports.ɵg = GtPropertyPipe;
3668
- exports.ɵd = GtRenderPipe;
3669
- exports.ɵn = GtRowClassPipe;
3670
- exports.ɵk = GtSearchPipe;
3671
- exports.ɵm = GtTotalsPositionPipe;
3672
- exports.ɵl = GtTotalsPipe;
3673
- exports.ɵc = GtVisiblePipe;
3674
-
3675
- Object.defineProperty(exports, '__esModule', { value: true });
3676
-
3677
- })));
3678
-
3679
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5ndWxhci1nZW5lcmljLXRhYmxlLWNvcmUudW1kLmpzLm1hcCIsInNvdXJjZXMiOlsibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL2NvbXBvbmVudHMvZ3QtdGFibGUtaW5mby9ndC10YWJsZS1pbmZvLmNvbXBvbmVudC50cyIsIm5nOi8vQGFuZ3VsYXItZ2VuZXJpYy10YWJsZS9jb3JlL2xpYi9jb21wb25lbnRzL2d0LXBhZ2luYXRpb24vZ3QtcGFnaW5hdGlvbi5jb21wb25lbnQudHMiLCJuZzovL0Bhbmd1bGFyLWdlbmVyaWMtdGFibGUvY29yZS9saWIvY29tcG9uZW50cy9ndC1leHBhbmRpbmctcm93L2d0LWV4cGFuZGluZy1yb3cuY29tcG9uZW50LnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL2NvbXBvbmVudHMvZ3QtZHJvcGRvd24vZ3QtZHJvcGRvd24uY29tcG9uZW50LnRzIixudWxsLCJuZzovL0Bhbmd1bGFyLWdlbmVyaWMtdGFibGUvY29yZS9saWIvY29tcG9uZW50cy9ndC1kcmlsbGRvd24vZ3QtZHJpbGxkb3duLmNvbXBvbmVudC50cyIsIm5nOi8vQGFuZ3VsYXItZ2VuZXJpYy10YWJsZS9jb3JlL2xpYi9jb21wb25lbnRzL2d0LWN1c3RvbS1jb21wb25lbnQtZmFjdG9yeS9ndC1jdXN0b20tY29tcG9uZW50LWZhY3RvcnkuY29tcG9uZW50LnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL2NvbXBvbmVudHMvZ3QtY2hlY2tib3gvZ3QtY2hlY2tib3guY29tcG9uZW50LnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL3BpcGVzL2d0LW1ldGEucGlwZS50cyIsIm5nOi8vQGFuZ3VsYXItZ2VuZXJpYy10YWJsZS9jb3JlL2xpYi9jb21wb25lbnRzL2dlbmVyaWMtdGFibGUvZ2VuZXJpYy10YWJsZS5jb21wb25lbnQudHMiLCJuZzovL0Bhbmd1bGFyLWdlbmVyaWMtdGFibGUvY29yZS9saWIvcGlwZXMvZ3QtdmlzaWJsZS5waXBlLnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL3BpcGVzL2d0LXNlYXJjaC5waXBlLnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL3BpcGVzL2d0LWlzLWVkaXRhYmxlLnBpcGUudHMiLCJuZzovL0Bhbmd1bGFyLWdlbmVyaWMtdGFibGUvY29yZS9saWIvcGlwZXMvZ3QtaXMtb2JzZXJ2YWJsZS5waXBlLnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL3BpcGVzL2d0LWhpZ2hsaWdodC5waXBlLnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL3BpcGVzL2d0LWNvbHVtbi1jbGFzcy5waXBlLnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL3BpcGVzL2d0LXJvdy1jbGFzcy5waXBlLnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL3BpcGVzL2d0LXRvdGFscy1wb3NpdGlvbi5waXBlLnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL3BpcGVzL2d0LXRvdGFscy5waXBlLnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL3BpcGVzL2d0LW9yZGVyLWJ5LnBpcGUudHMiLCJuZzovL0Bhbmd1bGFyLWdlbmVyaWMtdGFibGUvY29yZS9saWIvcGlwZXMvZ3QtZmlsdGVyLnBpcGUudHMiLCJuZzovL0Bhbmd1bGFyLWdlbmVyaWMtdGFibGUvY29yZS9saWIvcGlwZXMvZ3QtY2h1bmsucGlwZS50cyIsIm5nOi8vQGFuZ3VsYXItZ2VuZXJpYy10YWJsZS9jb3JlL2xpYi9waXBlcy9ndC1wcm9wZXJ0eS5waXBlLnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL3BpcGVzL2Rhc2gtY2FzZS5waXBlLnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL3BpcGVzL2d0LXJlbmRlci5waXBlLnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL2RpcmVjdGl2ZXMvY29tcG9uZW50LWFuY2hvci5kaXJlY3RpdmUudHMiLCJuZzovL0Bhbmd1bGFyLWdlbmVyaWMtdGFibGUvY29yZS9saWIvZGlyZWN0aXZlcy9ndC1jb2x1bW4td2lkdGguZGlyZWN0aXZlLnRzIiwibmc6Ly9AYW5ndWxhci1nZW5lcmljLXRhYmxlL2NvcmUvbGliL2NvcmUubW9kdWxlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG5cdEFmdGVyVmlld0NoZWNrZWQsXG5cdENoYW5nZURldGVjdG9yUmVmLFxuXHRDb21wb25lbnQsXG5cdElucHV0XG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5AQ29tcG9uZW50KHtcblx0c2VsZWN0b3I6ICdndC10YWJsZS1pbmZvJyxcblx0dGVtcGxhdGU6IGBcblx0XHQ8c3BhbiAqbmdJZj1cImdlbmVyaWNUYWJsZS5ndEluZm9cIj57eyhjdXN0b21UZXh0PyBjdXN0b21UZXh0OmdlbmVyaWNUYWJsZS5ndFRleHRzKSB8IGd0VGFibGVJbmZvOlxuXHRcdFx0Z2VuZXJpY1RhYmxlLmd0SW5mbzpcblx0XHRcdGdlbmVyaWNUYWJsZS5ndEluZm8ucmVjb3Jkc0FmdGVyU2VhcmNoOlxuXHRcdFx0Z2VuZXJpY1RhYmxlLmd0SW5mby5yZWNvcmRGcm9tOlxuXHRcdFx0Z2VuZXJpY1RhYmxlLmd0SW5mby5yZWNvcmRUbzpcblx0XHRcdGdlbmVyaWNUYWJsZS5ndEluZm8ucmVjb3Jkc0FsbDpcblx0XHRcdGdlbmVyaWNUYWJsZS5ndFRleHRzLmxvYWRpbmc6XG5cdFx0XHRnZW5lcmljVGFibGUuZ3RUZXh0cy50YWJsZUluZm9BZnRlclNlYXJjaH19PC9zcGFuPlxuICBgLFxuXHRzdHlsZXM6IFtdXG59KVxuZXhwb3J0IGNsYXNzIEd0VGFibGVJbmZvQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3Q2hlY2tlZCB7XG5cdEBJbnB1dCgpIGdlbmVyaWNUYWJsZTogR2VuZXJpY1RhYmxlQ29tcG9uZW50PGFueSwgYW55Pjtcblx0QElucHV0KCkgY3VzdG9tVGV4dDogc3RyaW5nO1xuXG5cdGNvbnN0cnVjdG9yKHByaXZhdGUgX2NoYW5nZURldGVjdGlvblJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYpIHt9XG5cblx0bmdBZnRlclZpZXdDaGVja2VkKCkge1xuXHRcdHRoaXMuX2NoYW5nZURldGVjdGlvblJlZi5kZXRlY3RDaGFuZ2VzKCk7XG5cdH1cbn1cbmltcG9ydCB7IFBpcGUsIFBpcGVUcmFuc2Zvcm0gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEdlbmVyaWNUYWJsZUNvbXBvbmVudCB9IGZyb20gJy4uL2dlbmVyaWMtdGFibGUvZ2VuZXJpYy10YWJsZS5jb21wb25lbnQnO1xuaW1wb3J0IHsgR3RUZXh0cyB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvZ3QtdGV4dHMnO1xuaW1wb3J0IHsgR3RJbmZvcm1hdGlvbiB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvZ3QtaW5mb3JtYXRpb24nO1xuXG5AUGlwZSh7XG5cdG5hbWU6ICdndFRhYmxlSW5mbydcbn0pXG5leHBvcnQgY2xhc3MgVGFibGVJbmZvUGlwZSBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xuXHR0cmFuc2Zvcm0oXG5cdFx0dGV4dHM6IEd0VGV4dHMgfCBzdHJpbmcsXG5cdFx0a2V5czogR3RJbmZvcm1hdGlvbixcblx0XHRyZWNvcmRzQWZ0ZXJTZWFyY2g6IG51bWJlcixcblx0XHRyZWNvcmRGcm9tOiBudW1iZXIsXG5cdFx0cmVjb3JkVG86IG51bWJlcixcblx0XHRyZWNvcmRzQWxsOiBudW1iZXIsXG5cdFx0bG9hZGluZzogc3RyaW5nLFxuXHRcdHRhYmxlSW5mb0FmdGVyU2VhcmNoOiBzdHJpbmdcblx0KTogc3RyaW5nIHtcblx0XHRsZXQgdGV4dCA9IHR5cGVvZiB0ZXh0cyA9PT0gJ29iamVjdCcgPyB0ZXh0cy50YWJsZUluZm8gOiAnJztcblx0XHRpZiAoa2V5cy5yZWNvcmRzQWZ0ZXJTZWFyY2ggIT09IGtleXMucmVjb3Jkc0FsbCkge1xuXHRcdFx0dGV4dCA9IHR5cGVvZiB0ZXh0cyA9PT0gJ29iamVjdCcgPyB0ZXh0cy50YWJsZUluZm9BZnRlclNlYXJjaCA6ICcnO1xuXHRcdH1cblx0XHRmb3IgKGNvbnN0IGtleSBpbiBrZXlzKSB7XG5cdFx0XHRpZiAoa2V5cy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG5cdFx0XHRcdGNvbnN0IHNlYXJjaFN0cmluZyA9IG5ldyBSZWdFeHAoJyMnICsga2V5LCAnZycpO1xuXHRcdFx0XHR0ZXh0ID0gdGV4dC5yZXBsYWNlKHNlYXJjaFN0cmluZywga2V5c1trZXldKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHRleHQ7XG5cdH1cbn1cbiIsImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuQENvbXBvbmVudCh7XG5cdHNlbGVjdG9yOiAnZ3QtcGFnaW5hdGlvbicsXG5cdHRlbXBsYXRlOiBgXG5cdFx0PG5hdiBjbGFzcz1cImd0LXBhZ2luYXRpb25cIiBhcmlhLWxhYmVsPVwiVGFibGUgbmF2aWdhdGlvblwiICpuZ0lmPVwiZ2VuZXJpY1RhYmxlICYmIGdlbmVyaWNUYWJsZS5ndEluZm8gJiYgcmVhZHkgJiYgZ2VuZXJpY1RhYmxlLmd0RGF0YT8ubGVuZ3RoID4gMFwiIFtuZ0NsYXNzXT1cInsnbm8tZGF0YSc6Z2VuZXJpY1RhYmxlLmd0SW5mby5wYWdlVG90YWwgPT09IDB9XCI+XG5cdFx0XHQ8dWwgY2xhc3M9XCJwYWdpbmF0aW9uXCIgW25nQ2xhc3NdPVwiZ3RDbGFzc2VzXCI+XG5cdFx0XHRcdDxsaSBjbGFzcz1cInBhZ2UtaXRlbVwiIFtuZ0NsYXNzXT1cInsnZGlzYWJsZWQnIDogZ2VuZXJpY1RhYmxlLmd0SW5mby5wYWdlQ3VycmVudCA9PT0gMSB8fCBnZW5lcmljVGFibGUubG9hZGluZyB9XCI+PGEgY2xhc3M9XCJwYWdlLWxpbmtcIiBocmVmPVwiamF2YXNjcmlwdDp2b2lkKDApO1wiIChjbGljayk9XCJnZW5lcmljVGFibGUuZ3RJbmZvLnBhZ2VDdXJyZW50ID4gMSAmJiBnZW5lcmljVGFibGUucHJldmlvdXNQYWdlKClcIiBbYXR0ci5hcmlhLWxhYmVsXT1cImdlbmVyaWNUYWJsZS5ndFRleHRzLnBhZ2luYXRlUHJldmlvdXNcIj48c3BhbiBhcmlhLWhpZGRlbj1cInRydWVcIj4mbGFxdW87PC9zcGFuPjxzcGFuIGNsYXNzPVwic3Itb25seVwiPnt7Z2VuZXJpY1RhYmxlLmd0VGV4dHMucGFnaW5hdGVQcmV2aW91c319PC9zcGFuPjwvYT48L2xpPlxuXHRcdFx0XHQ8bGkgY2xhc3M9XCJwYWdlLWl0ZW1cIiBbbmdDbGFzc109XCJ7J2Rpc2FibGVkJyA6IGdlbmVyaWNUYWJsZS5sb2FkaW5nICYmIGdlbmVyaWNUYWJsZS5ndEluZm8ucGFnZUN1cnJlbnQgIT09IHBhZ2UsICdhY3RpdmUnIDogZ2VuZXJpY1RhYmxlLmd0SW5mby5wYWdlQ3VycmVudCA9PT0gcGFnZSB9XCIgKm5nRm9yPVwibGV0IHBhZ2Ugb2YgZ2VuZXJpY1RhYmxlLmd0SW5mby5wYWdlVG90YWwgfCBndFBhZ2luYXRpb25QaXBlOmdlbmVyaWNUYWJsZS5ndEluZm8ucGFnZUN1cnJlbnRcIj48YSBjbGFzcz1cInBhZ2UtbGlua1wiIFt0YWJpbmRleF09XCJwYWdlID09PSB0cnVlID8gLTE6MFwiIGhyZWY9XCJqYXZhc2NyaXB0OnZvaWQoMCk7XCIgKGNsaWNrKT1cInBhZ2UgPT09IHRydWUgPyAnJzpnZW5lcmljVGFibGUuZ29Ub1BhZ2UocGFnZSlcIj57e3BhZ2UgPT09IHRydWUgPyAnJmhlbGxpcDsnOnBhZ2V9fTwvYT48L2xpPlxuXHRcdFx0XHQ8bGkgY2xhc3M9XCJwYWdlLWl0ZW1cIiBbbmdDbGFzc109XCJ7J2Rpc2FibGVkJyA6IGdlbmVyaWNUYWJsZS5ndEluZm8ucGFnZUN1cnJlbnQgPT09IGdlbmVyaWNUYWJsZS5ndEluZm8ucGFnZVRvdGFsIHx8IGdlbmVyaWNUYWJsZS5sb2FkaW5nIH1cIj48YSBjbGFzcz1cInBhZ2UtbGluayBndC1saW5rXCIgaHJlZj1cImphdmFzY3JpcHQ6dm9pZCgwKTtcIiAoY2xpY2spPVwiZ2VuZXJpY1RhYmxlLmd0SW5mby5wYWdlQ3VycmVudCAhPT0gZ2VuZXJpY1RhYmxlLmd0SW5mby5wYWdlVG90YWwgJiYgZ2VuZXJpY1RhYmxlLm5leHRQYWdlKClcIiBbYXR0ci5hcmlhLWxhYmVsXT1cImdlbmVyaWNUYWJsZS5ndFRleHRzLnBhZ2luYXRlTmV4dFwiPjxzcGFuIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPiZyYXF1bzs8L3NwYW4+PHNwYW4gY2xhc3M9XCJzci1vbmx5XCI+e3tnZW5lcmljVGFibGUuZ3RUZXh0cy5wYWdpbmF0ZU5leHR9fTwvc3Bhbj48L2E+PC9saT5cblx0XHRcdDwvdWw+XG5cdFx0PC9uYXY+XG4gIGAsXG5cdHN0eWxlczogW2AuZ3QtbGluayB7Y3Vyc29yOiBwb2ludGVyO31gXVxufSlcbmV4cG9ydCBjbGFzcyBHdFBhZ2luYXRpb25Db21wb25lbnQge1xuXHRnZXQgZ2VuZXJpY1RhYmxlKCk6IEdlbmVyaWNUYWJsZUNvbXBvbmVudDxhbnksIGFueT4ge1xuXHRcdHJldHVybiB0aGlzLl9nZW5lcmljVGFibGU7XG5cdH1cblxuXHRASW5wdXQoKVxuXHRzZXQgZ2VuZXJpY1RhYmxlKHZhbHVlOiBHZW5lcmljVGFibGVDb21wb25lbnQ8YW55LCBhbnk+KSB7XG5cdFx0aWYgKHZhbHVlKSB7XG5cdFx0XHR2YWx1ZS5ndEV2ZW50LnN1YnNjcmliZSgocmVzOiBhbnkpID0+IHtcblx0XHRcdFx0aWYgKHJlcy5uYW1lID09PSAnZ3QtaW5mbycgJiYgcmVzLnZhbHVlLnBhZ2VUb3RhbCA+IDApIHtcblx0XHRcdFx0XHR0aGlzLnJlYWR5ID0gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fVxuXHRcdHRoaXMuX2dlbmVyaWNUYWJsZSA9IHZhbHVlO1xuXHR9XG5cblx0cHJpdmF0ZSBfZ2VuZXJpY1RhYmxlOiBHZW5lcmljVGFibGVDb21wb25lbnQ8YW55LCBhbnk+O1xuXHRASW5wdXQoKSBndENsYXNzZXM6IHN0cmluZztcblx0cHVibGljIHJlYWR5ID0gZmFsc2U7XG59XG5pbXBvcnQgeyBQaXBlLCBQaXBlVHJhbnNmb3JtIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBHZW5lcmljVGFibGVDb21wb25lbnQgfSBmcm9tICcuLi9nZW5lcmljLXRhYmxlL2dlbmVyaWMtdGFibGUuY29tcG9uZW50JztcblxuQFBpcGUoe1xuXHRuYW1lOiAnZ3RQYWdpbmF0aW9uUGlwZSdcbn0pXG5leHBvcnQgY2xhc3MgUGFnaW5hdGlvblBpcGUgaW1wbGVtZW50cyBQaXBlVHJhbnNmb3JtIHtcblx0dHJhbnNmb3JtKHRvdGFsUGFnZXM6IG51bWJlciwgY3VycmVudFBhZ2U6IG51bWJlcik6IEFycmF5PGFueT4ge1xuXHRcdGlmICh0b3RhbFBhZ2VzID09PSAwKSB7XG5cdFx0XHRyZXR1cm4gWzFdO1xuXHRcdH1cblx0XHRjb25zdCBwYWdpbmF0aW9uOiBBcnJheTxhbnk+ID0gW107IC8vIGNyZWF0ZSBuZXcgZW1wdHkgYXJyYXkgZm9yIHBhZ2luYXRpb25cblx0XHRjb25zdCBzaWJsaW5ncyA9IDI7IC8vIHNpYmxpbmcgZWxlbWVudHMgaWUuIG51bWJlciBvZiBlbGVtZW50cyBvbiBlYWNoIHNpZGUgb2YgY3VycmVudCBwYWdlXG5cdFx0Y29uc3QgcGFnaW5hdGlvbkxlbmd0aCA9XG5cdFx0XHR0b3RhbFBhZ2VzIDwgc2libGluZ3MgKiAyICsgMSA/IHRvdGFsUGFnZXMgOiBzaWJsaW5ncyAqIDIgKyAxOyAvLyBudW1iZXIgb2YgZWxlbWVudHMgaW4gcGFnaW5hdGlvbiBhcnJheVxuXHRcdGNvbnN0IHN0YXJ0ID0gY3VycmVudFBhZ2UgPD0gc2libGluZ3MgPyAxIDogY3VycmVudFBhZ2UgLSBzaWJsaW5nczsgLy8gc3RhcnRpbmcgcG9zaXRpb24gZm9yIGFycmF5XG5cdFx0Y29uc3QgbW9kaWZpZXIgPVxuXHRcdFx0dG90YWxQYWdlcyAtIChjdXJyZW50UGFnZSArIHNpYmxpbmdzKSA8PSAwXG5cdFx0XHRcdD8gdG90YWxQYWdlcyAtIChjdXJyZW50UGFnZSArIHNpYmxpbmdzKVxuXHRcdFx0XHQ6IDA7IC8vIG1vZGlmaWVyIGZvciBwYWdpbmF0aW9uIHZhbHVlc1xuXHRcdGNvbnN0IG1vZGlmaWVkUG9zaXRpb24gPSBzdGFydCArIG1vZGlmaWVyIDw9IDAgPyAxIDogc3RhcnQgKyBtb2RpZmllcjtcblxuXHRcdC8vIHB1c2ggcGFnZXMgdG8gcGFnaW5hdGlvbiBhcnJheVxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgcGFnaW5hdGlvbkxlbmd0aDsgaSsrKSB7XG5cdFx0XHRwYWdpbmF0aW9uLnB1c2gobW9kaWZpZWRQb3NpdGlvbiArIGkpO1xuXHRcdH1cblxuXHRcdC8vIGlmIGZpcnN0IHBhZ2UgaXMgbm90IGluY2x1ZGVkIGluIHBhZ2luYXRpb24uLi5cblx0XHRpZiAocGFnaW5hdGlvbi5pbmRleE9mKDEpID09PSAtMSkge1xuXHRcdFx0Ly8gLi4uY2hlY2sgaWYgc2Vjb25kIHBhZ2UgaXMgaW4gcGFnaW5hdGlvbi4uLlxuXHRcdFx0aWYgKHBhZ2luYXRpb24uaW5kZXhPZigyKSA9PT0gLTEpIHtcblx0XHRcdFx0Ly8gLi4uaWYgbm90IGNoZWNrIGlmIHRvdGFsIG51bWJlciBvZiBwYWdlcyBlcXVhbHMgc2V2ZW4gYW5kIG51bWJlciBvZiBzaWJsaW5ncyBhcmUgdHdvLi4uXG5cdFx0XHRcdGlmICh0b3RhbFBhZ2VzID09PSA3ICYmIHNpYmxpbmdzID09PSAyKSB7XG5cdFx0XHRcdFx0Ly8gLi4uYWRkIHNlY29uZCBwYWdlIGFuZCBkb24ndCBjb252ZXJ0IHBhZ2UgbnVtYmVyIHRvIGVsbGlwc2lzXG5cdFx0XHRcdFx0cGFnaW5hdGlvbi51bnNoaWZ0KDIpO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdC8vIC4uLmlmIG5vdCwgdXNlIHRoaXMgcGxhY2Vob2xkZXIgZm9yIGVsbGlwc2lzIGluc3RlYWQgb2YgYWN0dWFsIHBhZ2UgbnVtYmVyXG5cdFx0XHRcdFx0cGFnaW5hdGlvblswXSA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdC8vIC4uLmFkZCBmaXJzdCBwYWdlIGFzIGZpcnN0IGFycmF5IGl0ZW1cblx0XHRcdHBhZ2luYXRpb24udW5zaGlmdCgxKTtcblx0XHR9IGVsc2UgaWYgKHRvdGFsUGFnZXMgPiBwYWdpbmF0aW9uTGVuZ3RoKSB7XG5cdFx0XHQvLyBpZiBmaXJzdCBwYWdlIGlzIGluY2x1ZGVkIGFkZCBleHRyYSBwYWdlIHRvIGtlZXAgbnVtYmVyIG9mIGl0ZW1zIGNvbnNpc3RlbnRcblx0XHRcdHBhZ2luYXRpb24uc3BsaWNlKHBhZ2luYXRpb25MZW5ndGgsIDAsIHBhZ2luYXRpb25MZW5ndGggKyAxKTtcblx0XHR9XG5cdFx0Ly8gY2hlY2sgaWYgbGFzdCBwYWdlIGlzIGluY2x1ZGVkIGluIHBhZ2luYXRpb24uLi5cblx0XHRpZiAocGFnaW5hdGlvbi5pbmRleE9mKHRvdGFsUGFnZXMpID09PSAtMSkge1xuXHRcdFx0Ly8gLi4uaWYgbm90LCBwYWdlIG5leHQgdG8gbGFzdCBzaG91bGQgZWl0aGVyIHNob3cgZWxsaXBzaXMgb3IgYWN0dWFsIHBhZ2UgbnVtYmVyIGZvciB0aGUgcGFnZVxuXHRcdFx0cGFnaW5hdGlvbltwYWdpbmF0aW9uLmxlbmd0aCAtIDFdID1cblx0XHRcdFx0cGFnaW5hdGlvbltwYWdpbmF0aW9uLmxlbmd0aCAtIDFdID09PSB0b3RhbFBhZ2VzIC0gMVxuXHRcdFx0XHRcdD8gdG90YWxQYWdlcyAtIDFcblx0XHRcdFx0XHQ6IHRydWU7XG5cblx0XHRcdC8vIC4uLmFkZCBsYXN0IHBhZ2UgdG8gcGFnaW5hdGlvblxuXHRcdFx0cGFnaW5hdGlvbi5wdXNoKHRvdGFsUGFnZXMpO1xuXHRcdH1cblxuXHRcdHJldHVybiBwYWdpbmF0aW9uO1xuXHR9XG59XG4iLCJpbXBvcnQgeyBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE91dHB1dCwgVHlwZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgR3RSb3cgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL2d0LXJvdyc7XG5pbXBvcnQgeyBHdENvbmZpZ1NldHRpbmcgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL2d0LWNvbmZpZy1zZXR0aW5nJztcbmltcG9ydCB7IEd0Q29uZmlnRmllbGQgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL2d0LWNvbmZpZy1maWVsZCc7XG5pbXBvcnQgeyBHdEV2ZW50IH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9ndC1ldmVudCc7XG5cbmV4cG9ydCBjbGFzcyBHdEV4cGFuZGVkUm93PFIgZXh0ZW5kcyBHdFJvdz4ge1xuXHRyb3c6IFI7XG5cdGNvbHVtbldpZHRoOiBPYmplY3Q7XG5cdGd0U2V0dGluZ3M6IEFycmF5PEd0Q29uZmlnU2V0dGluZz47XG5cdGd0RmllbGRzOiBBcnJheTxHdENvbmZpZ0ZpZWxkPFIsIGFueT4+O1xuXHRndE9wdGlvbnM6IGFueTtcblx0Z3RJbmZvOiBhbnk7XG5cdGRhdGE6IGFueTtcblx0cmVkcmF3RXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyPFI+KCk7XG5cdGd0RXZlbnQ6IEV2ZW50RW1pdHRlcjxHdEV2ZW50Pjtcblx0dG9nZ2xlUm93RXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyPFI+KCk7XG5cblx0cHVibGljICRoaWRlKCk6IHZvaWQge1xuXHRcdHRoaXMudG9nZ2xlUm93RXZlbnQuZW1pdCh0aGlzLnJvdyk7XG5cdH1cblxuXHRwdWJsaWMgJHJlZHJhdygkZXZlbnQ/OiBhbnkpOiB2b2lkIHtcblx0XHR0aGlzLnJlZHJhd0V2ZW50LmVtaXQodGhpcy5yb3cpO1xuXHR9XG5cdHB1YmxpYyAkcm93Q2xpY2socm93OiBHdFJvdywgJGV2ZW50OiBNb3VzZUV2ZW50KSB7XG5cdFx0dGhpcy5ndEV2ZW50LmVtaXQoe1xuXHRcdFx0bmFtZTogJ2d0LXJvdy1jbGlja2VkJyxcblx0XHRcdHZhbHVlOiB7IHJvdzogcm93LCBldmVudDogJGV2ZW50IH1cblx0XHR9KTtcblx0fVxufVxuXG5AQ29tcG9uZW50KHtcblx0c2VsZWN0b3I6ICdndC1leHBhbmRpbmctcm93Jyxcblx0dGVtcGxhdGU6IGBcblx0XHQ8ZGl2IGd0Q29tcG9uZW50QW5jaG9yXG5cdFx0XHQgW2N0b3JdPVwidHlwZVwiIChpbnN0YW5jZSk9XCJuZXdJbnN0YW5jZSgkZXZlbnQpXCI+PC9kaXY+XG4gIGAsXG5cdHN0eWxlczogW11cbn0pXG5leHBvcnQgY2xhc3MgR3RFeHBhbmRpbmdSb3dDb21wb25lbnQ8XG5cdFIgZXh0ZW5kcyBHdFJvdyxcblx0QyBleHRlbmRzIEd0RXhwYW5kZWRSb3c8Uj5cbj4ge1xuXHRASW5wdXQoKSB0eXBlOiBUeXBlPEM+O1xuXHRASW5wdXQoKSByb3c6IFI7XG5cdEBJbnB1dCgpIGNvbHVtbldpZHRoOiBPYmplY3Q7XG5cdEBJbnB1dCgpIGd0U2V0dGluZ3M6IEFycmF5PEd0Q29uZmlnU2V0dGluZz47XG5cdEBJbnB1dCgpIGd0RmllbGRzOiBBcnJheTxHdENvbmZpZ0ZpZWxkPFIsIGFueT4+O1xuXHRASW5wdXQoKSBndE9wdGlvbnM6IGFueTtcblx0QElucHV0KCkgZ3RJbmZvOiBhbnk7XG5cdEBJbnB1dCgpIGRhdGE6IGFueTtcblxuXHRAT3V0cHV0KCkgcmVkcmF3RXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyPFI+KCk7XG5cdEBPdXRwdXQoKSB0b2dnbGVSb3dFdmVudCA9IG5ldyBFdmVudEVtaXR0ZXI8Uj4oKTtcblx0QElucHV0KCkgZ3RFdmVudDogYW55O1xuXG5cdG5ld0luc3RhbmNlKGluc3RhbmNlOiBDKTogdm9pZCB7XG5cdFx0aW5zdGFuY2Uucm93ID0gdGhpcy5yb3c7XG5cdFx0aW5zdGFuY2UuY29sdW1uV2lkdGggPSB0aGlzLmNvbHVtbldpZHRoO1xuXHRcdGluc3RhbmNlLmd0U2V0dGluZ3MgPSB0aGlzLmd0U2V0dGluZ3M7XG5cdFx0aW5zdGFuY2UuZ3RGaWVsZHMgPSB0aGlzLmd0RmllbGRzO1xuXHRcdGluc3RhbmNlLmd0T3B0aW9ucyA9IHRoaXMuZ3RPcHRpb25zO1xuXHRcdGluc3RhbmNlLmd0SW5mbyA9IHRoaXMuZ3RJbmZvO1xuXHRcdGluc3RhbmNlLmRhdGEgPVxuXHRcdFx0dHlwZW9mIHRoaXMuZGF0YSA9PT0gJ2Z1bmN0aW9uJyA/IHRoaXMuZGF0YSh0aGlzLnJvdykgOiB0aGlzLmRhdGE7XG5cdFx0aW5zdGFuY2UucmVkcmF3RXZlbnQuc3Vic2NyaWJlKHRoaXMucmVkcmF3RXZlbnQpO1xuXHRcdGluc3RhbmNlLnRvZ2dsZVJvd0V2ZW50LnN1YnNjcmliZSh0aGlzLnRvZ2dsZVJvd0V2ZW50KTtcblx0XHRpbnN0YW5jZS5ndEV2ZW50ID0gdGhpcy5ndEV2ZW50O1xuXHR9XG59XG4iLCJpbXBvcnQge1xuXHRDb21wb25lbnQsXG5cdEV2ZW50RW1pdHRlcixcblx0SW5wdXQsXG5cdE9uRGVzdHJveSxcblx0T25Jbml0LFxuXHRPdXRwdXQsXG5cdFJlbmRlcmVyMlxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCAqIGFzIFRldGhlciBmcm9tICd0ZXRoZXInO1xuXG5AQ29tcG9uZW50KHtcblx0c2VsZWN0b3I6ICdndC1kcm9wZG93bicsXG5cdHRlbXBsYXRlOiBgXG5cdFx0PGRpdiBjbGFzcz1cImRyb3Bkb3duIGd0LWRyb3Bkb3duXCIgW25nQ2xhc3NdPVwieydzaG93JzphY3RpdmV9XCIgW2F0dHIuaWRdPVwiaWRcIj5cblx0XHRcdDxkaXYgY2xhc3M9XCJkcm9wZG93bi10b2dnbGVcIiAoY2xpY2spPVwidG9nZ2xlRHJvcGRvd24oKVwiIFthdHRyLmFyaWEtZXhwYW5kZWRdPVwiYWN0aXZlXCI+e3tzZWxlY3RlZH19PC9kaXY+XG5cdFx0XHQ8ZGl2IGNsYXNzPVwiZ3QtZHJvcGRvd24tbWVudSBkcm9wZG93bi1tZW51XCIgKm5nSWY9XCJhY3RpdmVcIiBbbmdDbGFzc109XCJ7J3Nob3cnOmFjdGl2ZX1cIiBbYXR0ci5pZF09XCJpZCsnX21lbnUnXCI+XG5cdFx0XHRcdDxidXR0b24gKm5nRm9yPVwibGV0IG9wdGlvbiBvZiBvcHRpb25zO1wiIGNsYXNzPVwiZHJvcGRvd24taXRlbVwiIChjbGljayk9XCJzZWxlY3Qob3B0aW9uKVwiIFtuZ0NsYXNzXT1cInsnYWN0aXZlJzpvcHRpb24gPT09IHNlbGVjdGVkfVwiPnt7b3B0aW9ufX08L2J1dHRvbj5cblx0XHRcdDwvZGl2PlxuXHRcdDwvZGl2PlxuICBgLFxuXHRzdHlsZXM6IFtcblx0XHRgXG5cdFx0Lmd0LWRyb3Bkb3duIC5kcm9wZG93bi10b2dnbGUge1xuXHRcdFx0Y3Vyc29yOiBwb2ludGVyO1xuXHRcdH1cblx0XHQuZ3QtZHJvcGRvd24gLmRyb3Bkb3duLXRvZ2dsZTo6YWZ0ZXIge1xuXHRcdFx0dHJhbnNpdGlvbjogb3BhY2l0eSAwLjRzIGVhc2UtaW4tb3V0O1xuXHRcdFx0b3BhY2l0eTogMDtcblx0XHR9XG5cdFx0Lmd0LWRyb3Bkb3duIC5kcm9wZG93bi10b2dnbGU6aG92ZXI6OmFmdGVyIHtcblx0XHRcdG9wYWNpdHk6IDE7XG5cdFx0fVxuXHRgXG5cdF1cbn0pXG5leHBvcnQgY2xhc3MgR3REcm9wZG93bkNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcblx0Z2V0IHNlbGVjdGVkKCkge1xuXHRcdHJldHVybiB0aGlzLl9zZWxlY3RlZDtcblx0fVxuXG5cdF9zZWxlY3RlZDogYW55O1xuXHRASW5wdXQoKVxuXHRzZXQgc2VsZWN0ZWQoc2VsZWN0aW9uKSB7XG5cdFx0dGhpcy5fc2VsZWN0ZWQgPSBzZWxlY3Rpb247XG5cdH1cblx0QElucHV0KCkgb3B0aW9uczogQXJyYXk8YW55Pjtcblx0QElucHV0KCkgaWQ6IHN0cmluZztcblx0QE91dHB1dCgpIHNlbGVjdGVkQ2hhbmdlOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuXHRhY3RpdmUgPSBmYWxzZTsgLy8gaXMgZHJvcGRvd24gYWN0aXZlIG9yIG5vdFxuXHRzdGF0ZTogU3ViamVjdDxib29sZWFuPiA9IG5ldyBTdWJqZWN0KCk7IC8vIGN1cnJlbnQgc3RhdGUgb2YgZHJvcGRvd25cblx0dGV0aGVyOiBhbnk7XG5cdGNsaWNrTGlzdGVuZXI6IEZ1bmN0aW9uO1xuXHRrZXl1cExpc3RlbmVyOiBGdW5jdGlvbjtcblxuXHRjb25zdHJ1Y3Rvcihwcml2YXRlIHJlbmRlcmVyOiBSZW5kZXJlcjIpIHt9XG5cblx0c2VsZWN0KG9wdGlvbjogYW55KSB7XG5cdFx0dGhpcy5hY3RpdmUgPSBmYWxzZTtcblx0XHR0aGlzLnN0YXRlLm5leHQodGhpcy5hY3RpdmUpO1xuXHRcdGlmICh0aGlzLl9zZWxlY3RlZCAhPT0gb3B0aW9uKSB7XG5cdFx0XHR0aGlzLnNlbGVjdGVkQ2hhbmdlLmVtaXQob3B0aW9uKTtcblx0XHR9XG5cdH1cblxuXHR0b2dnbGVEcm9wZG93bigpIHtcblx0XHR0aGlzLmFjdGl2ZSA9ICF0aGlzLmFjdGl2ZTtcblx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdHRoaXMuc3RhdGUubmV4dCh0aGlzLmFjdGl2ZSk7XG5cdFx0fSwgMCk7XG5cdH1cblxuXHRuZ09uSW5pdCgpIHtcblx0XHR0aGlzLnN0YXRlLnN1YnNjcmliZShzdGF0ZSA9PiB7XG5cdFx0XHRpZiAoc3RhdGUpIHtcblx0XHRcdFx0dGhpcy50ZXRoZXIgPSBuZXcgVGV0aGVyKHtcblx0XHRcdFx0XHRlbGVtZW50OiAnIycgKyB0aGlzLmlkICsgJ19tZW51Jyxcblx0XHRcdFx0XHR0YXJnZXQ6ICcjJyArIHRoaXMuaWQsXG5cdFx0XHRcdFx0YXR0YWNobWVudDogJ3RvcCBsZWZ0Jyxcblx0XHRcdFx0XHR0YXJnZXRBdHRhY2htZW50OiAnYm90dG9tIGxlZnQnLFxuXHRcdFx0XHRcdGNvbnN0cmFpbnRzOiBbXG5cdFx0XHRcdFx0XHR7XG5cdFx0XHRcdFx0XHRcdHRvOiAnd2luZG93Jyxcblx0XHRcdFx0XHRcdFx0YXR0YWNobWVudDogJ3RvZ2V0aGVyJ1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdF1cblx0XHRcdFx0fSk7XG5cblx0XHRcdFx0dGhpcy50ZXRoZXIucG9zaXRpb24oKTtcblxuXHRcdFx0XHQvLyBzZXQgdXAgY2xpY2sgbGlzdGVuZXIgYW5kIGxpc3RlbiBmb3IgY2xpY2sgb3V0c2lkZSBkcm9wZG93blxuXHRcdFx0XHR0aGlzLmNsaWNrTGlzdGVuZXIgPSB0aGlzLnJlbmRlcmVyLmxpc3Rlbihcblx0XHRcdFx0XHQnZG9jdW1lbnQnLFxuXHRcdFx0XHRcdCdjbGljaycsXG5cdFx0XHRcdFx0KGV2ZW50OiBNb3VzZUV2ZW50KSA9PiB7XG5cdFx0XHRcdFx0XHR0aGlzLmFjdGl2ZSA9IGZhbHNlO1xuXHRcdFx0XHRcdFx0dGhpcy5zdGF0ZS5uZXh0KHRoaXMuYWN0aXZlKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdCk7XG5cblx0XHRcdFx0Ly8gc2V0IHVwIGtleWJvYXJkIGxpc3RlbmVyIGFuZCBsaXN0ZW4gZm9yIGVzY2FwZSBrZXkgdXBcblx0XHRcdFx0dGhpcy5rZXl1cExpc3RlbmVyID0gdGhpcy5yZW5kZXJlci5saXN0ZW4oXG5cdFx0XHRcdFx0J2RvY3VtZW50Jyxcblx0XHRcdFx0XHQna2V5dXAnLFxuXHRcdFx0XHRcdChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4ge1xuXHRcdFx0XHRcdFx0c3dpdGNoIChldmVudC5rZXkpIHtcblx0XHRcdFx0XHRcdFx0Y2FzZSAnRXNjYXBlJzpcblx0XHRcdFx0XHRcdFx0XHR0aGlzLmFjdGl2ZSA9IGZhbHNlO1xuXHRcdFx0XHRcdFx0XHRcdHRoaXMuc3RhdGUubmV4dCh0aGlzLmFjdGl2ZSk7XG5cdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHQpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dGhpcy50ZXRoZXIuZGVzdHJveSgpO1xuXHRcdFx0XHR0aGlzLnJlbW92ZUxpc3RlbmVycygpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG5cblx0bmdPbkRlc3Ryb3koKSB7XG5cdFx0dGhpcy5yZW1vdmVMaXN0ZW5lcnMoKTtcblx0fVxuXG5cdHJlbW92ZUxpc3RlbmVycygpIHtcblx0XHRpZiAodGhpcy5jbGlja0xpc3RlbmVyKSB7XG5cdFx0XHR0aGlzLmNsaWNrTGlzdGVuZXIoKTtcblx0XHR9XG5cdFx0aWYgKHRoaXMua2V5dXBMaXN0ZW5lcikge1xuXHRcdFx0dGhpcy5rZXl1cExpc3RlbmVyKCk7XG5cdFx0fVxuXHR9XG59XG4iLCIvKiEgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuXHJcbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7IHlvdSBtYXkgbm90IHVzZVxyXG50aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZVxyXG5MaWNlbnNlIGF0IGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxyXG5cclxuVEhJUyBDT0RFIElTIFBST1ZJREVEIE9OIEFOICpBUyBJUyogQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWVxyXG5LSU5ELCBFSVRIRVIgRVhQUkVTUyBPUiBJTVBMSUVELCBJTkNMVURJTkcgV0lUSE9VVCBMSU1JVEFUSU9OIEFOWSBJTVBMSUVEXHJcbldBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBUSVRMRSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UsXHJcbk1FUkNIQU5UQUJMSVRZIE9SIE5PTi1JTkZSSU5HRU1FTlQuXHJcblxyXG5TZWUgdGhlIEFwYWNoZSBWZXJzaW9uIDIuMCBMaWNlbnNlIGZvciBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnNcclxuYW5kIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxyXG4qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqL1xyXG4vKiBnbG9iYWwgUmVmbGVjdCwgUHJvbWlzZSAqL1xyXG5cclxudmFyIGV4dGVuZFN0YXRpY3MgPSBmdW5jdGlvbihkLCBiKSB7XHJcbiAgICBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHtcclxuICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2Fzc2lnbiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgX19hc3NpZ24gPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uIF9fYXNzaWduKHQpIHtcclxuICAgICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcclxuICAgICAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKSB0W3BdID0gc1twXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gX19hc3NpZ24uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVzdChzLCBlKSB7XHJcbiAgICB2YXIgdCA9IHt9O1xyXG4gICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApICYmIGUuaW5kZXhPZihwKSA8IDApXHJcbiAgICAgICAgdFtwXSA9IHNbcF07XHJcbiAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSBcImZ1bmN0aW9uXCIpXHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIHAgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHMpOyBpIDwgcC5sZW5ndGg7IGkrKykgaWYgKGUuaW5kZXhPZihwW2ldKSA8IDApXHJcbiAgICAgICAgICAgIHRbcFtpXV0gPSBzW3BbaV1dO1xyXG4gICAgcmV0dXJuIHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2RlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKSB7XHJcbiAgICB2YXIgYyA9IGFyZ3VtZW50cy5sZW5ndGgsIHIgPSBjIDwgMyA/IHRhcmdldCA6IGRlc2MgPT09IG51bGwgPyBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGtleSkgOiBkZXNjLCBkO1xyXG4gICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0LmRlY29yYXRlID09PSBcImZ1bmN0aW9uXCIpIHIgPSBSZWZsZWN0LmRlY29yYXRlKGRlY29yYXRvcnMsIHRhcmdldCwga2V5LCBkZXNjKTtcclxuICAgIGVsc2UgZm9yICh2YXIgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIGlmIChkID0gZGVjb3JhdG9yc1tpXSkgciA9IChjIDwgMyA/IGQocikgOiBjID4gMyA/IGQodGFyZ2V0LCBrZXksIHIpIDogZCh0YXJnZXQsIGtleSkpIHx8IHI7XHJcbiAgICByZXR1cm4gYyA+IDMgJiYgciAmJiBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBrZXksIHIpLCByO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19wYXJhbShwYXJhbUluZGV4LCBkZWNvcmF0b3IpIHtcclxuICAgIHJldHVybiBmdW5jdGlvbiAodGFyZ2V0LCBrZXkpIHsgZGVjb3JhdG9yKHRhcmdldCwga2V5LCBwYXJhbUluZGV4KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSkge1xyXG4gICAgaWYgKHR5cGVvZiBSZWZsZWN0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0Lm1ldGFkYXRhID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiBSZWZsZWN0Lm1ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXRlcih0aGlzQXJnLCBfYXJndW1lbnRzLCBQLCBnZW5lcmF0b3IpIHtcclxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvcltcInRocm93XCJdKHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUocmVzdWx0LnZhbHVlKTsgfSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxyXG4gICAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcclxuICAgIH0pO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19nZW5lcmF0b3IodGhpc0FyZywgYm9keSkge1xyXG4gICAgdmFyIF8gPSB7IGxhYmVsOiAwLCBzZW50OiBmdW5jdGlvbigpIHsgaWYgKHRbMF0gJiAxKSB0aHJvdyB0WzFdOyByZXR1cm4gdFsxXTsgfSwgdHJ5czogW10sIG9wczogW10gfSwgZiwgeSwgdCwgZztcclxuICAgIHJldHVybiBnID0geyBuZXh0OiB2ZXJiKDApLCBcInRocm93XCI6IHZlcmIoMSksIFwicmV0dXJuXCI6IHZlcmIoMikgfSwgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIChnW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXM7IH0pLCBnO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IHJldHVybiBmdW5jdGlvbiAodikgeyByZXR1cm4gc3RlcChbbiwgdl0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKG9wKSB7XHJcbiAgICAgICAgaWYgKGYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJHZW5lcmF0b3IgaXMgYWxyZWFkeSBleGVjdXRpbmcuXCIpO1xyXG4gICAgICAgIHdoaWxlIChfKSB0cnkge1xyXG4gICAgICAgICAgICBpZiAoZiA9IDEsIHkgJiYgKHQgPSBvcFswXSAmIDIgPyB5W1wicmV0dXJuXCJdIDogb3BbMF0gPyB5W1widGhyb3dcIl0gfHwgKCh0ID0geVtcInJldHVyblwiXSkgJiYgdC5jYWxsKHkpLCAwKSA6IHkubmV4dCkgJiYgISh0ID0gdC5jYWxsKHksIG9wWzFdKSkuZG9uZSkgcmV0dXJuIHQ7XHJcbiAgICAgICAgICAgIGlmICh5ID0gMCwgdCkgb3AgPSBbb3BbMF0gJiAyLCB0LnZhbHVlXTtcclxuICAgICAgICAgICAgc3dpdGNoIChvcFswXSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAwOiBjYXNlIDE6IHQgPSBvcDsgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDQ6IF8ubGFiZWwrKzsgcmV0dXJuIHsgdmFsdWU6IG9wWzFdLCBkb25lOiBmYWxzZSB9O1xyXG4gICAgICAgICAgICAgICAgY2FzZSA1OiBfLmxhYmVsKys7IHkgPSBvcFsxXTsgb3AgPSBbMF07IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA3OiBvcCA9IF8ub3BzLnBvcCgpOyBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoISh0ID0gXy50cnlzLCB0ID0gdC5sZW5ndGggPiAwICYmIHRbdC5sZW5ndGggLSAxXSkgJiYgKG9wWzBdID09PSA2IHx8IG9wWzBdID09PSAyKSkgeyBfID0gMDsgY29udGludWU7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDMgJiYgKCF0IHx8IChvcFsxXSA+IHRbMF0gJiYgb3BbMV0gPCB0WzNdKSkpIHsgXy5sYWJlbCA9IG9wWzFdOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gNiAmJiBfLmxhYmVsIDwgdFsxXSkgeyBfLmxhYmVsID0gdFsxXTsgdCA9IG9wOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ICYmIF8ubGFiZWwgPCB0WzJdKSB7IF8ubGFiZWwgPSB0WzJdOyBfLm9wcy5wdXNoKG9wKTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodFsyXSkgXy5vcHMucG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBvcCA9IGJvZHkuY2FsbCh0aGlzQXJnLCBfKTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7IG9wID0gWzYsIGVdOyB5ID0gMDsgfSBmaW5hbGx5IHsgZiA9IHQgPSAwOyB9XHJcbiAgICAgICAgaWYgKG9wWzBdICYgNSkgdGhyb3cgb3BbMV07IHJldHVybiB7IHZhbHVlOiBvcFswXSA/IG9wWzFdIDogdm9pZCAwLCBkb25lOiB0cnVlIH07XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2V4cG9ydFN0YXIobSwgZXhwb3J0cykge1xyXG4gICAgZm9yICh2YXIgcCBpbiBtKSBpZiAoIWV4cG9ydHMuaGFzT3duUHJvcGVydHkocCkpIGV4cG9ydHNbcF0gPSBtW3BdO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX192YWx1ZXMobykge1xyXG4gICAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgb1tTeW1ib2wuaXRlcmF0b3JdLCBpID0gMDtcclxuICAgIGlmIChtKSByZXR1cm4gbS5jYWxsKG8pO1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBuZXh0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChvICYmIGkgPj0gby5sZW5ndGgpIG8gPSB2b2lkIDA7XHJcbiAgICAgICAgICAgIHJldHVybiB7IHZhbHVlOiBvICYmIG9baSsrXSwgZG9uZTogIW8gfTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZWFkKG8sIG4pIHtcclxuICAgIHZhciBtID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9bU3ltYm9sLml0ZXJhdG9yXTtcclxuICAgIGlmICghbSkgcmV0dXJuIG87XHJcbiAgICB2YXIgaSA9IG0uY2FsbChvKSwgciwgYXIgPSBbXSwgZTtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgd2hpbGUgKChuID09PSB2b2lkIDAgfHwgbi0tID4gMCkgJiYgIShyID0gaS5uZXh0KCkpLmRvbmUpIGFyLnB1c2goci52YWx1ZSk7XHJcbiAgICB9XHJcbiAgICBjYXRjaCAoZXJyb3IpIHsgZSA9IHsgZXJyb3I6IGVycm9yIH07IH1cclxuICAgIGZpbmFsbHkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChyICYmICFyLmRvbmUgJiYgKG0gPSBpW1wicmV0dXJuXCJdKSkgbS5jYWxsKGkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmaW5hbGx5IHsgaWYgKGUpIHRocm93IGUuZXJyb3I7IH1cclxuICAgIH1cclxuICAgIHJldHVybiBhcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkKCkge1xyXG4gICAgZm9yICh2YXIgYXIgPSBbXSwgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspXHJcbiAgICAgICAgYXIgPSBhci5jb25jYXQoX19yZWFkKGFyZ3VtZW50c1tpXSkpO1xyXG4gICAgcmV0dXJuIGFyO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdCh2KSB7XHJcbiAgICByZXR1cm4gdGhpcyBpbnN0YW5jZW9mIF9fYXdhaXQgPyAodGhpcy52ID0gdiwgdGhpcykgOiBuZXcgX19hd2FpdCh2KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNHZW5lcmF0b3IodGhpc0FyZywgX2FyZ3VtZW50cywgZ2VuZXJhdG9yKSB7XHJcbiAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgdmFyIGcgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSksIGksIHEgPSBbXTtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpZiAoZ1tuXSkgaVtuXSA9IGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAoYSwgYikgeyBxLnB1c2goW24sIHYsIGEsIGJdKSA+IDEgfHwgcmVzdW1lKG4sIHYpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gcmVzdW1lKG4sIHYpIHsgdHJ5IHsgc3RlcChnW25dKHYpKTsgfSBjYXRjaCAoZSkgeyBzZXR0bGUocVswXVszXSwgZSk7IH0gfVxyXG4gICAgZnVuY3Rpb24gc3RlcChyKSB7IHIudmFsdWUgaW5zdGFuY2VvZiBfX2F3YWl0ID8gUHJvbWlzZS5yZXNvbHZlKHIudmFsdWUudikudGhlbihmdWxmaWxsLCByZWplY3QpIDogc2V0dGxlKHFbMF1bMl0sIHIpOyB9XHJcbiAgICBmdW5jdGlvbiBmdWxmaWxsKHZhbHVlKSB7IHJlc3VtZShcIm5leHRcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiByZWplY3QodmFsdWUpIHsgcmVzdW1lKFwidGhyb3dcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUoZiwgdikgeyBpZiAoZih2KSwgcS5zaGlmdCgpLCBxLmxlbmd0aCkgcmVzdW1lKHFbMF1bMF0sIHFbMF1bMV0pOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jRGVsZWdhdG9yKG8pIHtcclxuICAgIHZhciBpLCBwO1xyXG4gICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiLCBmdW5jdGlvbiAoZSkgeyB0aHJvdyBlOyB9KSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpW25dID0gb1tuXSA/IGZ1bmN0aW9uICh2KSB7IHJldHVybiAocCA9ICFwKSA/IHsgdmFsdWU6IF9fYXdhaXQob1tuXSh2KSksIGRvbmU6IG4gPT09IFwicmV0dXJuXCIgfSA6IGYgPyBmKHYpIDogdjsgfSA6IGY7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNWYWx1ZXMobykge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBtID0gb1tTeW1ib2wuYXN5bmNJdGVyYXRvcl0sIGk7XHJcbiAgICByZXR1cm4gbSA/IG0uY2FsbChvKSA6IChvID0gdHlwZW9mIF9fdmFsdWVzID09PSBcImZ1bmN0aW9uXCIgPyBfX3ZhbHVlcyhvKSA6IG9bU3ltYm9sLml0ZXJhdG9yXSgpLCBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLmFzeW5jSXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaSk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaVtuXSA9IG9bbl0gJiYgZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHsgdiA9IG9bbl0odiksIHNldHRsZShyZXNvbHZlLCByZWplY3QsIHYuZG9uZSwgdi52YWx1ZSk7IH0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCBkLCB2KSB7IFByb21pc2UucmVzb2x2ZSh2KS50aGVuKGZ1bmN0aW9uKHYpIHsgcmVzb2x2ZSh7IHZhbHVlOiB2LCBkb25lOiBkIH0pOyB9LCByZWplY3QpOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ha2VUZW1wbGF0ZU9iamVjdChjb29rZWQsIHJhdykge1xyXG4gICAgaWYgKE9iamVjdC5kZWZpbmVQcm9wZXJ0eSkgeyBPYmplY3QuZGVmaW5lUHJvcGVydHkoY29va2VkLCBcInJhd1wiLCB7IHZhbHVlOiByYXcgfSk7IH0gZWxzZSB7IGNvb2tlZC5yYXcgPSByYXc7IH1cclxuICAgIHJldHVybiBjb29rZWQ7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19pbXBvcnRTdGFyKG1vZCkge1xyXG4gICAgaWYgKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgcmV0dXJuIG1vZDtcclxuICAgIHZhciByZXN1bHQgPSB7fTtcclxuICAgIGlmIChtb2QgIT0gbnVsbCkgZm9yICh2YXIgayBpbiBtb2QpIGlmIChPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChtb2QsIGspKSByZXN1bHRba10gPSBtb2Rba107XHJcbiAgICByZXN1bHQuZGVmYXVsdCA9IG1vZDtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydERlZmF1bHQobW9kKSB7XHJcbiAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IGRlZmF1bHQ6IG1vZCB9O1xyXG59XHJcbiIsImltcG9ydCB7IENvbXBvbmVudCwgT25Jbml0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBHdEV4cGFuZGVkUm93IH0gZnJvbSAnLi4vZ3QtZXhwYW5kaW5nLXJvdy9ndC1leHBhbmRpbmctcm93LmNvbXBvbmVudCc7XG5cbkBDb21wb25lbnQoe1xuXHRzZWxlY3RvcjogJ2d0LWRyaWxsZG93bicsXG5cdHRlbXBsYXRlOiBgXG5cdFx0PHRhYmxlIGNsYXNzPVwidGFibGVcIj5cblx0XHRcdDx0ciAqbmdGb3I9XCJsZXQgcm93IG9mIGRhdGFcIiAoY2xpY2spPVwiJHJvd0NsaWNrKHJvdywgJGV2ZW50KVwiPlxuXHRcdFx0XHQ8dGQgKm5nRm9yPVwibGV0IGNvbHVtbiBvZiByb3cgfCBndFJlbmRlcjpndFNldHRpbmdzOmd0RmllbGRzOm51bGw6bnVsbDpndE9wdGlvbnMuaGlnaGxpZ2h0U2VhcmNoOmd0SW5mby5zZWFyY2hUZXJtcztcIlxuXHRcdFx0XHRcdG5nQ2xhc3M9XCJ7e2NvbHVtbi5vYmplY3RLZXkgKyctY29sdW1uJyB8IGRhc2hDYXNlfX0ge3tndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonY2xhc3NOYW1lcyd9fSB7eyhndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpID8gJ2d0LWlubGluZS1lZGl0JzonJ319IHt7Y29sdW1uLmVkaXRlZCA/ICdndC1lZGl0ZWQnOicnfX0ge3sgZ3RGaWVsZHMgfCBndENvbHVtbkNsYXNzOnJvdzpjb2x1bW4gfX1cIiBbc3R5bGUud2lkdGhdPVwiY29sdW1uV2lkdGhbY29sdW1uLm9iamVjdEtleV1cIiBbc3R5bGUubWF4LXdpZHRoXT1cImNvbHVtbldpZHRoW2NvbHVtbi5vYmplY3RLZXldXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImd0LXJvdy1sYWJlbFwiXG5cdFx0XHRcdFx0XHRcdCAgKm5nSWY9XCJndE9wdGlvbnMuc3RhY2tcIj57eyhndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonc3RhY2tlZEhlYWRpbmcnKSA/IChndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonc3RhY2tlZEhlYWRpbmcnKSA6IChndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonbmFtZScpfX08L3NwYW4+XG5cdFx0XHRcdFx0PGd0LWN1c3RvbS1jb21wb25lbnQtZmFjdG9yeSAqbmdJZj1cImNvbHVtbi5jb2x1bW5Db21wb25lbnRcIiBjbGFzcz1cImd0LXJvdy1jb250ZW50XCJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCBbdHlwZV09XCJjb2x1bW4uY29sdW1uQ29tcG9uZW50LnR5cGVcIlxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0IFtpbmplY3Rvcl09XCJjb2x1bW4uY29sdW1uQ29tcG9uZW50LmluamVjdG9yXCIgW3Jvd109XCJyb3dcIlxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0IFtjb2x1bW5dPVwiY29sdW1uXCIgKHJlZHJhd0V2ZW50KT1cIiRyZWRyYXcoJGV2ZW50KVwiXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQgKGNsaWNrKT1cImNvbHVtbi5jbGljayA/IGNvbHVtbi5jbGljayhyb3csY29sdW1uLCRldmVudCk6Jyc7XCI+PC9ndC1jdXN0b20tY29tcG9uZW50LWZhY3Rvcnk+XG5cdFx0XHRcdFx0PHNwYW4gKm5nSWY9XCIhY29sdW1uLmNvbHVtbkNvbXBvbmVudFwiXG5cdFx0XHRcdFx0XHQgIGNsYXNzPVwiZ3Qtcm93LWNvbnRlbnRcIiBbaW5uZXJIVE1MXT1cImNvbHVtbi5yZW5kZXJWYWx1ZVwiXG5cdFx0XHRcdFx0XHQgIChjbGljayk9XCJjb2x1bW4uY2xpY2sgPyBjb2x1bW4uY2xpY2socm93LGNvbHVtbiwkZXZlbnQpOicnXCI+PC9zcGFuPlxuXHRcdFx0XHQ8L3RkPlxuXG5cdFx0XHQ8L3RyPlxuXHRcdDwvdGFibGU+XG4gIGAsXG5cdHN0eWxlczogW11cbn0pXG5leHBvcnQgY2xhc3MgR3REcmlsbGRvd25Db21wb25lbnQgZXh0ZW5kcyBHdEV4cGFuZGVkUm93PGFueT4gaW1wbGVtZW50cyBPbkluaXQge1xuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHRzdXBlcigpO1xuXHR9XG5cblx0bmdPbkluaXQoKSB7fVxufVxuIiwiaW1wb3J0IHtcblx0Q29tcG9uZW50LFxuXHRFdmVudEVtaXR0ZXIsXG5cdEluamVjdG9yLFxuXHRJbnB1dCxcblx0T25Jbml0LFxuXHRPdXRwdXQsXG5cdFR5cGVcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBSZXBsYXlTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBHdEN1c3RvbUNvbXBvbmVudDxSPiBpbXBsZW1lbnRzIE9uSW5pdCB7XG5cdHJvdzogUjtcblx0Y29sdW1uOiBhbnk7XG5cdHJlZHJhd0V2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcjx7IHJvdzogUjsgY29sdW1uOiBhbnkgfT4oKTtcblx0c2VhcmNoVGVybXM6IHN0cmluZztcblx0JHNlYXJjaFRlcm1zOiBSZXBsYXlTdWJqZWN0PHN0cmluZz4gPSBuZXcgUmVwbGF5U3ViamVjdCgxKTtcblxuXHRwcm90ZWN0ZWQgJHJlZHJhdygkZXZlbnQ/OiBhbnkpIHtcblx0XHR0aGlzLnJlZHJhd0V2ZW50LmVtaXQoeyByb3c6IHRoaXMucm93LCBjb2x1bW46IHRoaXMuY29sdW1uIH0pO1xuXHR9XG5cdG5nT25Jbml0KCkge1xuXHRcdHRoaXMuJHNlYXJjaFRlcm1zLnN1YnNjcmliZSh0ZXJtcyA9PiAodGhpcy5zZWFyY2hUZXJtcyA9IHRlcm1zKSk7XG5cdH1cbn1cblxuQENvbXBvbmVudCh7XG5cdHNlbGVjdG9yOiAnZ3QtY3VzdG9tLWNvbXBvbmVudC1mYWN0b3J5Jyxcblx0dGVtcGxhdGU6IGBcblx0XHQ8ZGl2IGd0Q29tcG9uZW50QW5jaG9yIFtjdG9yXT1cInR5cGVcIlxuXHRcdFx0IFtpbmplY3Rvcl09XCJpbmplY3RvclwiXG5cdFx0XHQgKGluc3RhbmNlKT1cImluc3RhbmNlKCRldmVudClcIj48L2Rpdj5cblx0YFxufSlcbmV4cG9ydCBjbGFzcyBHdEN1c3RvbUNvbXBvbmVudEZhY3Rvcnk8UiwgQyBleHRlbmRzIEd0Q3VzdG9tQ29tcG9uZW50PFI+PiB7XG5cdEBJbnB1dCgpXG5cdHNldCBzZWFyY2hUZXJtcyh2YWx1ZTogc3RyaW5nKSB7XG5cdFx0dGhpcy4kc2VhcmNoVGVybXMubmV4dCh2YWx1ZSk7XG5cdH1cblx0QElucHV0KCkgdHlwZTogVHlwZTxDPjtcblx0QElucHV0KCkgaW5qZWN0b3I6IEluamVjdG9yO1xuXHRASW5wdXQoKSByb3c6IFI7XG5cdEBJbnB1dCgpIGNvbHVtbjogYW55O1xuXHQkc2VhcmNoVGVybXM6IFJlcGxheVN1YmplY3Q8c3RyaW5nPiA9IG5ldyBSZXBsYXlTdWJqZWN0KDEpO1xuXHRAT3V0cHV0KCkgcmVkcmF3RXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyPHsgcm93OiBSOyBjb2x1bW46IGFueSB9PigpO1xuXG5cdGluc3RhbmNlKGluc3RhbmNlOiBDKSB7XG5cdFx0aW5zdGFuY2Uucm93ID0gdGhpcy5yb3c7XG5cdFx0aW5zdGFuY2UuY29sdW1uID0gdGhpcy5jb2x1bW47XG5cdFx0aW5zdGFuY2UuJHNlYXJjaFRlcm1zID0gdGhpcy4kc2VhcmNoVGVybXM7XG5cdFx0aW5zdGFuY2UucmVkcmF3RXZlbnQuc3Vic2NyaWJlKHRoaXMucmVkcmF3RXZlbnQpO1xuXHR9XG59XG4iLCJpbXBvcnQge1xuXHRDb21wb25lbnQsXG5cdEV2ZW50RW1pdHRlcixcblx0SG9zdEJpbmRpbmcsXG5cdElucHV0LFxuXHRPbkluaXQsXG5cdE91dHB1dFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuQENvbXBvbmVudCh7XG5cdHNlbGVjdG9yOiAnZ3QtY2hlY2tib3gnLFxuXHR0ZW1wbGF0ZTogYFxuXHRcdDxsYWJlbCBjbGFzcz1cImN1c3RvbS1jb250cm9sIGN1c3RvbS1jaGVja2JveCBwLTBcIiAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG5cdFx0XHQ8aW5wdXQgI2NoZWNrYm94IHR5cGU9XCJjaGVja2JveFwiIGNsYXNzPVwiY3VzdG9tLWNvbnRyb2wtaW5wdXRcIiBbKGNoZWNrZWQpXT1cImNoZWNrZWRcIiAoY2hhbmdlKT1cInRvZ2dsZSgkZXZlbnQpO1wiPlxuXHRcdFx0PHNwYW4gY2xhc3M9XCJjdXN0b20tY29udHJvbC1sYWJlbFwiPjwvc3Bhbj5cblx0XHQ8L2xhYmVsPlxuICBgLFxuXHRzdHlsZXM6IFtdXG59KVxuZXhwb3J0IGNsYXNzIEd0Q2hlY2tib3hDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuXHRnZXQgaW5pdGlhbFZhbHVlKCk6IGJvb2xlYW4ge1xuXHRcdHJldHVybiB0aGlzLl9pbml0aWFsVmFsdWU7XG5cdH1cblxuXHRASG9zdEJpbmRpbmcoJ2NsYXNzJykgY2xhc3MgPSAnZC1mbGV4IGp1c3RpZnktY29udGVudC1lbmQnO1xuXG5cdEBJbnB1dCgpXG5cdHNldCBpbml0aWFsVmFsdWUodmFsdWU6IGJvb2xlYW4pIHtcblx0XHR0aGlzLl9pbml0aWFsVmFsdWUgPSB2YWx1ZTtcblx0fVxuXHRnZXQgY2hlY2tlZCgpOiBib29sZWFuIHtcblx0XHRyZXR1cm4gdGhpcy5fY2hlY2tlZDtcblx0fVxuXG5cdEBJbnB1dCgpXG5cdHNldCBjaGVja2VkKHZhbHVlOiBib29sZWFuKSB7XG5cdFx0dGhpcy5fY2hlY2tlZCA9IHZhbHVlO1xuXHR9XG5cblx0cHJpdmF0ZSBfY2hlY2tlZDogYm9vbGVhbjtcblx0cHJpdmF0ZSBfaW5pdGlhbFZhbHVlOiBib29sZWFuO1xuXHRAT3V0cHV0KCkgY2hhbmdlZDogRXZlbnRFbWl0dGVyPGJvb2xlYW4+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG5cdGNvbnN0cnVjdG9yKCkge31cblxuXHRuZ09uSW5pdCgpIHt9XG5cblx0dG9nZ2xlKGNoZWNrZWQ6IGJvb2xlYW4pIHtcblx0XHR0aGlzLmNoYW5nZWQuZW1pdCh0aGlzLmNoZWNrZWQpO1xuXHR9XG59XG4iLCJpbXBvcnQgeyBQaXBlLCBQaXBlVHJhbnNmb3JtIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBHdFJvdyB9IGZyb20gJy4uL2ludGVyZmFjZXMvZ3Qtcm93JztcblxuQFBpcGUoe1xuXHRuYW1lOiAnZ3RNZXRhJ1xufSlcbmV4cG9ydCBjbGFzcyBHdE1ldGFQaXBlIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XG5cdHRyYW5zZm9ybShcblx0XHRhbGxSb3dzOiBBcnJheTxHdFJvdz4sXG5cdFx0cm93SW5kZXg/OiBzdHJpbmcsXG5cdFx0cGFnZT86IG51bWJlcixcblx0XHRyZWNvcmRMZW5ndGg/OiBudW1iZXJcblx0KTogQXJyYXk8R3RSb3c+IHtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGFsbFJvd3MubGVuZ3RoOyBpKyspIHtcblx0XHRcdGlmICghYWxsUm93c1tpXS4kJGd0Um93SWQpIHtcblx0XHRcdFx0YWxsUm93c1tpXS4kJGd0Um93SWQgPSByb3dJbmRleFxuXHRcdFx0XHRcdD8gYWxsUm93c1tpXVtyb3dJbmRleF1cblx0XHRcdFx0XHQ6IHBhZ2Vcblx0XHRcdFx0XHRcdD8gcGFnZSAqIHJlY29yZExlbmd0aCArXG5cdFx0XHRcdFx0XHQgIGkgK1xuXHRcdFx0XHRcdFx0ICAnXycgK1xuXHRcdFx0XHRcdFx0ICBNYXRoLnJhbmRvbSgpXG5cdFx0XHRcdFx0XHRcdFx0LnRvU3RyaW5nKDM2KVxuXHRcdFx0XHRcdFx0XHRcdC5zdWJzdHIoMiwgMTYpXG5cdFx0XHRcdFx0XHQ6IGkgK1xuXHRcdFx0XHRcdFx0ICAnXycgK1xuXHRcdFx0XHRcdFx0ICBNYXRoLnJhbmRvbSgpXG5cdFx0XHRcdFx0XHRcdFx0LnRvU3RyaW5nKDM2KVxuXHRcdFx0XHRcdFx0XHRcdC5zdWJzdHIoMiwgMTYpO1xuXHRcdFx0fVxuXHRcdFx0aWYgKCFhbGxSb3dzW2ldLiQkZ3RJbml0aWFsUm93SW5kZXgpIHtcblx0XHRcdFx0YWxsUm93c1tpXS4kJGd0SW5pdGlhbFJvd0luZGV4ID0gaTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGFsbFJvd3M7XG5cdH1cbn1cbiIsImltcG9ydCB7XG5cdENvbXBvbmVudCxcblx0RXZlbnRFbWl0dGVyLFxuXHRJbnB1dCxcblx0T25DaGFuZ2VzLFxuXHRPbkRlc3Ryb3ksXG5cdE9uSW5pdCxcblx0T3V0cHV0LFxuXHRSZW5kZXJlcjIsXG5cdFNpbXBsZUNoYW5nZXMsXG5cdFR5cGVcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBHdFJvdyB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvZ3Qtcm93JztcbmltcG9ydCB7IEd0RXhwYW5kZWRSb3cgfSBmcm9tICcuLi9ndC1leHBhbmRpbmctcm93L2d0LWV4cGFuZGluZy1yb3cuY29tcG9uZW50JztcbmltcG9ydCB7IEd0T3B0aW9ucyB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvZ3Qtb3B0aW9ucyc7XG5pbXBvcnQgeyBHdENvbmZpZ0ZpZWxkIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9ndC1jb25maWctZmllbGQnO1xuaW1wb3J0IHsgR3RDb25maWdTZXR0aW5nIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9ndC1jb25maWctc2V0dGluZyc7XG5pbXBvcnQgeyBHdFJvd01ldGEgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL2d0LXJvdy1tZXRhJztcbmltcG9ydCB7IEd0VGV4dHMgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL2d0LXRleHRzJztcbmltcG9ydCB7IEd0Q29uZmlnIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9ndC1jb25maWcnO1xuaW1wb3J0IHsgR3RFdmVudCB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvZ3QtZXZlbnQnO1xuaW1wb3J0IHsgR3RJbmZvcm1hdGlvbiB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvZ3QtaW5mb3JtYXRpb24nO1xuaW1wb3J0IHsgR3RSZW5kZXJGaWVsZCB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvZ3QtcmVuZGVyLWZpZWxkJztcbmltcG9ydCB7IEd0TWV0YVBpcGUgfSBmcm9tICcuLi8uLi9waXBlcy9ndC1tZXRhLnBpcGUnO1xuXG5AQ29tcG9uZW50KHtcblx0c2VsZWN0b3I6ICdnZW5lcmljLXRhYmxlJyxcblx0dGVtcGxhdGU6IGA8dGFibGUgY2xhc3M9XCJ0YWJsZVwiIG5nQ2xhc3M9XCJ7e2d0Q2xhc3Nlc319IHt7Z3RPcHRpb25zLnN0YWNrID8gJ3RhYmxlLXN0YWNrZWQnOicnfX1cIlxuICAgICAgICpuZ0lmPVwiZ3RGaWVsZHMgJiYgZ3RTZXR0aW5ncyAmJiAoZ3RGaWVsZHMgfCBndFZpc2libGU6Z3RTZXR0aW5nczpyZWZyZXNoUGlwZSkubGVuZ3RoID4gMFwiPlxuICA8dGhlYWQ+XG4gIDx0cj5cbiAgICA8dGggY2xhc3M9XCJndC1zb3J0LWxhYmVsXCIgKm5nSWY9XCJndE9wdGlvbnMuc3RhY2tcIj57e2d0VGV4dHMuc29ydExhYmVsfX08L3RoPlxuICAgIDx0aCAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIGd0U2V0dGluZ3MgfCBndFZpc2libGU6Z3RTZXR0aW5nczpyZWZyZXNoUGlwZVwiXG4gICAgICAgIG5nQ2xhc3M9XCJ7e2NvbHVtbi5vYmplY3RLZXkgKyctY29sdW1uJyB8IGRhc2hDYXNlfX0ge3tndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonY2xhc3NOYW1lcyd9fSB7e2NvbHVtbi5zb3J0RW5hYmxlZCA/ICdzb3J0LScrY29sdW1uLnNvcnQ6Jyd9fSB7e2NvbHVtbi5zb3J0RW5hYmxlZCAmJiBjb2x1bW4uc29ydE9yZGVyID49IDAgID8gJ3NvcnQtb3JkZXItJytjb2x1bW4uc29ydE9yZGVyOicnfX0ge3sgZ3RGaWVsZHMgfCBndENvbHVtbkNsYXNzOmNvbHVtbiB9fVwiXG4gICAgICAgIChjbGljayk9XCJjb2x1bW4uc29ydEVuYWJsZWQgPyBndFNvcnQoY29sdW1uLm9iamVjdEtleSwkZXZlbnQpOicnO1wiPlxuICAgICAgPHNwYW4gKm5nSWY9XCIhKGd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidoZWFkZXInKVwiPnt7Z3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J25hbWUnfX08L3NwYW4+XG4gICAgICA8Z3QtY3VzdG9tLWNvbXBvbmVudC1mYWN0b3J5ICpuZ0lmPVwiKGd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidoZWFkZXInKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0eXBlXT1cIihndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaGVhZGVyJyk/LnR5cGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaW5qZWN0b3JdPVwiKGd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidoZWFkZXInKT8uaW5qZWN0b3JcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY29sdW1uXT1cImd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OiduYW1lJ1wiPjwvZ3QtY3VzdG9tLWNvbXBvbmVudC1mYWN0b3J5PlxuICAgICAgPGd0LWNoZWNrYm94ICpuZ0lmPVwiKGd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5Oidjb2x1bW5Db21wb25lbnQnKT8udHlwZSA9PT0gJ2NoZWNrYm94J1wiIFtjaGVja2VkXT1cIihndE9wdGlvbnMubGF6eUxvYWQgPyBsYXp5QWxsU2VsZWN0ZWQ6c2VsZWN0ZWRSb3dzLmxlbmd0aCA9PT0gZ3REYXRhLmxlbmd0aClcIiAoY2hhbmdlZCk9XCJ0b2dnbGVBbGxSb3dzKClcIj48L2d0LWNoZWNrYm94PlxuICAgIDwvdGg+XG4gIDwvdHI+XG4gIDwvdGhlYWQ+XG4gIDxuZy10ZW1wbGF0ZVxuICAgIFtuZ0lmXT1cImd0VG90YWxzICYmIChndE9wdGlvbnMubGF6eUxvYWQgPT09IGZhbHNlID8gKGd0RGF0YSB8IGd0RmlsdGVyOmd0SW5mby5maWx0ZXI6Z3RJbmZvOnJlZnJlc2hGaWx0ZXI6Z3REYXRhLmxlbmd0aCB8IGd0U2VhcmNoOmd0SW5mby5zZWFyY2hUZXJtczpndEluZm86Z3RTZXR0aW5nczpndEZpZWxkczpndERhdGEubGVuZ3RoKS5sZW5ndGggPiAwIDogZ3REYXRhLmxlbmd0aCA+IDApXCI+XG4gICAgPHRoZWFkIGNsYXNzPVwiZ3QtdG90YWxzXCI+XG4gICAgPHRyICpuZ0Zvcj1cImxldCB0b3RhbCBvZiBndFRvdGFscyB8IGd0VG90YWxzUG9zaXRpb25cIj5cbiAgICAgIDx0ZCAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIGd0U2V0dGluZ3MgfCBndFZpc2libGU6Z3RTZXR0aW5nczpyZWZyZXNoUGlwZTtsZXQgaSA9IGluZGV4O1wiXG4gICAgICAgICAgbmdDbGFzcz1cInt7Y29sdW1uLm9iamVjdEtleSArJy10b3RhbHMtY29sdW1uJyB8IGRhc2hDYXNlfX0ge3tndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonY2xhc3NOYW1lcyd9fSB7eyBndEZpZWxkcyB8IGd0Q29sdW1uQ2xhc3M6Y29sdW1uIH19XCI+XG4gICAgICAgIDxzcGFuICpuZ0lmPVwiaSA9PT0gMFwiIGNsYXNzPVwiZmxvYXQtbGVmdFwiPnt7dG90YWwubmFtZX19PC9zcGFuPjxzcGFuXG4gICAgICAgIFtpbm5lckhUTUxdPVwidG90YWwuZmllbGRzW2NvbHVtbi5vYmplY3RLZXldIHwgZ3RUb3RhbHM6KHRvdGFsLnVwZGF0ZSA9PT0gZmFsc2UgfHwgZ3RPcHRpb25zLmxhenlMb2FkID09PSB0cnVlKSA/IGd0RGF0YTooZ3REYXRhIHwgZ3RGaWx0ZXI6Z3RJbmZvLmZpbHRlcjpndEluZm86cmVmcmVzaEZpbHRlcjpndERhdGEubGVuZ3RoIHwgZ3RTZWFyY2g6Z3RJbmZvLnNlYXJjaFRlcm1zOmd0SW5mbzpndFNldHRpbmdzOmd0RmllbGRzOmd0RGF0YS5sZW5ndGgpOmNvbHVtbi5vYmplY3RLZXk6cmVmcmVzaFRvdGFsc1wiPjwvc3Bhbj5cbiAgICAgIDwvdGQ+XG4gICAgPC90cj5cbiAgICA8L3RoZWFkPlxuICAgIDx0Zm9vdCBjbGFzcz1cImd0LXRvdGFsc1wiPlxuICAgIDx0ciAqbmdGb3I9XCJsZXQgdG90YWwgb2YgZ3RUb3RhbHMgfCBndFRvdGFsc1Bvc2l0aW9uOidmb290ZXInXCI+XG4gICAgICA8dGQgKm5nRm9yPVwibGV0IGNvbHVtbiBvZiBndFNldHRpbmdzIHwgZ3RWaXNpYmxlOmd0U2V0dGluZ3M6cmVmcmVzaFBpcGU7bGV0IGkgPSBpbmRleDtcIlxuICAgICAgICAgIG5nQ2xhc3M9XCJ7e2NvbHVtbi5vYmplY3RLZXkgKyctdG90YWxzLWNvbHVtbicgfCBkYXNoQ2FzZX19IHt7Z3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2NsYXNzTmFtZXMnfX0ge3sgZ3RGaWVsZHMgfCBndENvbHVtbkNsYXNzOmNvbHVtbiB9fVwiPlxuICAgICAgICA8c3BhbiAqbmdJZj1cImkgPT09IDBcIiBjbGFzcz1cImZsb2F0LWxlZnRcIj57e3RvdGFsLm5hbWV9fTwvc3Bhbj48c3BhblxuICAgICAgICBbaW5uZXJIVE1MXT1cInRvdGFsLmZpZWxkc1tjb2x1bW4ub2JqZWN0S2V5XSB8IGd0VG90YWxzOih0b3RhbC51cGRhdGUgPT09IGZhbHNlIHx8IGd0T3B0aW9ucy5sYXp5TG9hZCA9PT0gdHJ1ZSkgPyBndERhdGE6KGd0RGF0YSB8IGd0RmlsdGVyOmd0SW5mby5maWx0ZXI6Z3RJbmZvOnJlZnJlc2hGaWx0ZXI6Z3REYXRhLmxlbmd0aCB8IGd0U2VhcmNoOmd0SW5mby5zZWFyY2hUZXJtczpndEluZm86Z3RTZXR0aW5nczpndEZpZWxkczpndERhdGEubGVuZ3RoKTpjb2x1bW4ub2JqZWN0S2V5OnJlZnJlc2hUb3RhbHNcIj48L3NwYW4+XG4gICAgICA8L3RkPlxuICAgIDwvdHI+XG4gICAgPC90Zm9vdD5cbiAgPC9uZy10ZW1wbGF0ZT5cbiAgPHRib2R5ICpuZ0lmPVwiZ3REYXRhICYmIGd0SW5mb1wiPlxuICA8bmctdGVtcGxhdGUgY2xhc3M9XCJ0YWJsZS1yb3dzXCIgbmdGb3IgbGV0LXJvdyBsZXQtbGFzdD1cImxhc3RcIiBbbmdGb3JUcmFja0J5XT1cInRyYWNrQnlGblwiXG4gICAgICAgICAgICAgICBbbmdGb3JPZl09XCJndE9wdGlvbnMubGF6eUxvYWQgJiYgZ3RJbmZvID8gKGd0RGF0YVtndEluZm8ucGFnZUN1cnJlbnQtMV0pIDogKGd0RGF0YSB8IGd0RmlsdGVyOmd0SW5mby5maWx0ZXI6Z3RJbmZvOnJlZnJlc2hGaWx0ZXI6Z3REYXRhLmxlbmd0aCB8IGd0U2VhcmNoOmd0SW5mby5zZWFyY2hUZXJtczpndEluZm86Z3RTZXR0aW5nczpndEZpZWxkczpndERhdGEubGVuZ3RoIHwgZ3RPcmRlckJ5OnNvcnRPcmRlcjpndEZpZWxkczpyZWZyZXNoU29ydGluZzpndERhdGEubGVuZ3RoIHwgZ3RDaHVuazpndEluZm86Z3RJbmZvLnJlY29yZExlbmd0aDpndEluZm8ucGFnZUN1cnJlbnQ6cmVmcmVzaFBhZ2VBcnJheTpndERhdGEubGVuZ3RoOmd0RXZlbnQ6ZGF0YSB8IGd0Um93Q2xhc3M6Z3RGaWVsZHMpXCI+XG4gICAgPHRyIFtuZ0NsYXNzXT1cInsncm93LXNlbGVjdGVkJzptZXRhSW5mb1tyb3cuJCRndFJvd0lkXT8uaXNTZWxlY3RlZCwgJ3Jvdy1vcGVuJzptZXRhSW5mb1tyb3cuJCRndFJvd0lkXT8uaXNPcGVuLCAncm93LWxvYWRpbmcnOmxvYWRpbmcsICdyb3ctZXhwYW5kYWJsZSc6Z3RSb3dDb21wb25lbnR9XCJcbiAgICAgICAgY2xhc3M9XCJ7e3Jvdy4kJGd0Um93Q2xhc3N9fVwiXG4gICAgICAgIChjbGljayk9XCJndE9wdGlvbnMucm93U2VsZWN0aW9uID8gdG9nZ2xlU2VsZWN0KHJvdyk6cm93Q2xpY2socm93LCAkZXZlbnQpXCI+XG4gICAgICA8dGQgKm5nRm9yPVwibGV0IGNvbHVtbiBvZiByb3cgfCBndFJlbmRlcjpndFNldHRpbmdzOmd0RmllbGRzOnJlZnJlc2hQaXBlOmxvYWRpbmc6Z3RPcHRpb25zLmhpZ2hsaWdodFNlYXJjaDpndEluZm8uc2VhcmNoVGVybXM7dHJhY2tCeTp0cmFja0J5Q29sdW1uRm5cIlxuICAgICAgICAgIG5nQ2xhc3M9XCJ7e2NvbHVtbi5vYmplY3RLZXkgKyctY29sdW1uJyB8IGRhc2hDYXNlfX0ge3tndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonY2xhc3NOYW1lcyd9fSB7eyhndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpID8gJ2d0LWlubGluZS1lZGl0JzonJ319IHt7Y29sdW1uLmVkaXRlZCA/ICdndC1lZGl0ZWQnOicnfX0ge3sgZ3RGaWVsZHMgfCBndENvbHVtbkNsYXNzOmNvbHVtbjpyb3cgfX1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZ3Qtcm93LWxhYmVsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiZ3RPcHRpb25zLnN0YWNrXCI+e3soZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J3N0YWNrZWRIZWFkaW5nJykgPyAoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J3N0YWNrZWRIZWFkaW5nJykgOiAoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J25hbWUnKX19PC9zcGFuPlxuICAgICAgICA8Z3QtY3VzdG9tLWNvbXBvbmVudC1mYWN0b3J5ICpuZ0lmPVwiY29sdW1uLmNvbHVtbkNvbXBvbmVudCAmJiBjb2x1bW4uY29sdW1uQ29tcG9uZW50LnR5cGUgIT09ICdjaGVja2JveCdcIiBjbGFzcz1cImd0LXJvdy1jb250ZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdHlwZV09XCJjb2x1bW4uY29sdW1uQ29tcG9uZW50LnR5cGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpbmplY3Rvcl09XCJjb2x1bW4uY29sdW1uQ29tcG9uZW50LmluamVjdG9yXCIgW3Jvd109XCJyb3dcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjb2x1bW5dPVwiY29sdW1uXCIgKHJlZHJhd0V2ZW50KT1cInJlZHJhdygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2VhcmNoVGVybXNdPVwiZ3RJbmZvLnNlYXJjaFRlcm1zXCIgIChzZWFyY2hFdmVudCk9XCJyZWRyYXcoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNvbHVtbi5jbGljayA/IGNvbHVtbi5jbGljayhyb3csY29sdW1uLCRldmVudCk6Jyc7Y29sdW1uLmV4cGFuZCA/IHRvZ2dsZUNvbGxhcHNlKHJvdywgY29sdW1uLmV4cGFuZCk6JydcIj48L2d0LWN1c3RvbS1jb21wb25lbnQtZmFjdG9yeT5cbiAgICAgICAgPHNwYW4gKm5nSWY9XCIhY29sdW1uLmNvbHVtbkNvbXBvbmVudCAmJiAoIShndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpIHx8ICgoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKT8uYWN0aXZlIHwgZ3RJc09ic2VydmFibGUpICYmICEoKGd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidpbmxpbmVFZGl0Jyk/LmFjdGl2ZSB8IGFzeW5jKSB8fCAoISgoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKT8uYWN0aXZlIHwgZ3RJc09ic2VydmFibGUpICYmICEoKGd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidpbmxpbmVFZGl0Jyk/LmFjdGl2ZSB8IGd0SXNFZGl0YWJsZTpyb3c6cmVmcmVzaFBpcGUpKSlcIlxuICAgICAgICAgICAgICBjbGFzcz1cImd0LXJvdy1jb250ZW50XCIgW2lubmVySFRNTF09XCJjb2x1bW4ucmVuZGVyVmFsdWVcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwiY29sdW1uLmNsaWNrID8gY29sdW1uLmNsaWNrKHJvdyxjb2x1bW4sJGV2ZW50KTonJztjb2x1bW4uZXhwYW5kID8gdG9nZ2xlQ29sbGFwc2Uocm93LCBjb2x1bW4uZXhwYW5kKTonJ1wiPjwvc3Bhbj5cbiAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgW25nSWZdPVwiIWNvbHVtbi5jb2x1bW5Db21wb25lbnQgJiYgKCgoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKT8uYWN0aXZlIHwgZ3RJc09ic2VydmFibGUpICYmICgoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKT8uYWN0aXZlIHwgYXN5bmMpIHx8ICgoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKT8uYWN0aXZlIHwgZ3RJc0VkaXRhYmxlOnJvdzpyZWZyZXNoUGlwZSkpXCI+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cIihbdHJ1ZSwnZW1haWwnLCdudW1iZXInLCdwYXNzd29yZCcsICd0ZXh0J10uaW5kZXhPZigoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKS50eXBlKSAhPT0gLTEpIHx8ICEoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKS50eXBlXCI+XG4gICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJpbmxpbmUtZWRpdFwiIFthdHRyLnR5cGVdPVwiIShndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpLnR5cGUgPyAndGV4dCcgOiAhKChndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpLnR5cGUgfCBndElzT2JzZXJ2YWJsZSkgPyAoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKS50eXBlOihndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpLnR5cGUgfCBhc3luY1wiIFsobmdNb2RlbCldPVwiY29sdW1uLnJlbmRlclZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAoaW5wdXQpPVwiZ3RVcGRhdGVDb2x1bW4oJGV2ZW50LHJvdywgY29sdW1uKVwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJndC1pbmxpbmUtZWRpdC1ub3RpY2VcIj57e2d0VGV4dHMuaW5saW5lRWRpdEVkaXRlZH19PC9zcGFuPlxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgPGd0LWRyb3Bkb3duXG4gICAgICAgICAgICAqbmdJZj1cIigoKGd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidpbmxpbmVFZGl0JykudHlwZSkgJiYgKChndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpLnR5cGUpLmxlbmd0aCA+IDApIHx8ICgoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKS50eXBlIHwgZ3RJc09ic2VydmFibGUpXCJcbiAgICAgICAgICAgIFtvcHRpb25zXT1cIiEoKGd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidpbmxpbmVFZGl0JykudHlwZSB8IGd0SXNPYnNlcnZhYmxlKSA/IChndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpLnR5cGUgOiAoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKS50eXBlIHwgYXN5bmNcIlxuICAgICAgICAgICAgW2lkXT1cIidfJyArIHJvdy4kJGd0Um93SWQgKyAnXycgKyBjb2x1bW4ub2JqZWN0S2V5XCJcbiAgICAgICAgICAgIFsoc2VsZWN0ZWQpXT1cImNvbHVtbi5yZW5kZXJWYWx1ZVwiIChzZWxlY3RlZENoYW5nZSk9XCJndERyb3Bkb3duU2VsZWN0KHJvdywgY29sdW1uKVwiPkFkZFxuICAgICAgICAgICAgaW5saW5lIGVkaXRpbmcgbW9kdWxlXG4gICAgICAgICAgPC9ndC1kcm9wZG93bj5cbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPG5nLXRlbXBsYXRlIFtuZ0lmXT1cIiFjb2x1bW4uY29sdW1uQ29tcG9uZW50ICYmICEoKGd0RmllbGRzIHwgZ3RQcm9wZXJ0eTpjb2x1bW4ub2JqZWN0S2V5OidpbmxpbmVFZGl0Jyk/LmFjdGl2ZSkgXCI+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICBbbmdJZl09XCJbdHJ1ZSwnZW1haWwnLCdudW1iZXInLCdwYXNzd29yZCddLmluZGV4T2YoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKSAhPT0gLTFcIj5cbiAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImlubGluZS1lZGl0XCIgW2F0dHIudHlwZV09XCIoZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKSA9PT0gdHJ1ZSA/ICd0ZXh0JzooZ3RGaWVsZHMgfCBndFByb3BlcnR5OmNvbHVtbi5vYmplY3RLZXk6J2lubGluZUVkaXQnKVwiIFsobmdNb2RlbCldPVwiY29sdW1uLnJlbmRlclZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAoaW5wdXQpPVwiZ3RVcGRhdGVDb2x1bW4oJGV2ZW50LHJvdywgY29sdW1uKVwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJndC1pbmxpbmUtZWRpdC1ub3RpY2VcIj57e2d0VGV4dHMuaW5saW5lRWRpdEVkaXRlZH19PC9zcGFuPlxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgPGd0LWRyb3Bkb3duXG4gICAgICAgICAgICAqbmdJZj1cIihndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpICYmIFt0cnVlLCdlbWFpbCcsJ251bWJlcicsJ3Bhc3N3b3JkJ10uaW5kZXhPZihndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCcpID09PSAtMVwiXG4gICAgICAgICAgICBbb3B0aW9uc109XCJndEZpZWxkcyB8IGd0UHJvcGVydHk6Y29sdW1uLm9iamVjdEtleTonaW5saW5lRWRpdCdcIlxuICAgICAgICAgICAgW2lkXT1cIidfJyArIHJvdy4kJGd0Um93SWQgKyAnXycgKyBjb2x1bW4ub2JqZWN0S2V5XCJcbiAgICAgICAgICAgIFsoc2VsZWN0ZWQpXT1cImNvbHVtbi5yZW5kZXJWYWx1ZVwiIChzZWxlY3RlZENoYW5nZSk9XCJndERyb3Bkb3duU2VsZWN0KHJvdywgY29sdW1uKVwiPkFkZFxuICAgICAgICAgICAgaW5saW5lIGVkaXRpbmcgbW9kdWxlXG4gICAgICAgICAgPC9ndC1kcm9wZG93bj5cbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPGd0LWNoZWNrYm94ICpuZ0lmPVwiY29sdW1uLmNvbHVtbkNvbXBvbmVudCAmJiBjb2x1bW4uY29sdW1uQ29tcG9uZW50LnR5cGUgPT09ICdjaGVja2JveCdcIiBbY2hlY2tlZF09XCJtZXRhSW5mb1tyb3cuJCRndFJvd0lkXT8uaXNTZWxlY3RlZFwiIChjaGFuZ2VkKT1cInRvZ2dsZVNlbGVjdChyb3cpXCI+PC9ndC1jaGVja2JveD5cbiAgICAgIDwvdGQ+XG4gICAgPC90cj5cbiAgICA8dHIgY2xhc3M9XCJyb3ctZXhwYW5kZWRcIiAqbmdJZj1cIm1ldGFJbmZvW3Jvdy4kJGd0Um93SWRdPy5pc09wZW5cIj5cbiAgICAgIDx0ZCBbYXR0ci5jb2xzcGFuXT1cIihndEZpZWxkcyB8IGd0VmlzaWJsZTpndFNldHRpbmdzOnJlZnJlc2hQaXBlKS5sZW5ndGhcIj5cbiAgICAgICAgPGd0LWV4cGFuZGluZy1yb3cgW3Jvd109XCJyb3dcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbdHlwZV09XCJleHBhbmRlZFJvdy5jb21wb25lbnQgPyBleHBhbmRlZFJvdy5jb21wb25lbnQ6Z3RSb3dDb21wb25lbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbY29sdW1uV2lkdGhdPVwiY29sdW1uV2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbZ3RGaWVsZHNdPVwiZ3RGaWVsZHNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbZ3RPcHRpb25zXT1cImd0T3B0aW9uc1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtndEV2ZW50XT1cImd0RXZlbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbZ3RJbmZvXT1cImd0SW5mb1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtndFNldHRpbmdzXT1cImd0U2V0dGluZ3NcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbZGF0YV09XCJleHBhbmRlZFJvdy5kYXRhID8gZXhwYW5kZWRSb3cuZGF0YTpyb3dcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAocmVkcmF3RXZlbnQpPVwicmVkcmF3KCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAodG9nZ2xlUm93RXZlbnQpPVwidG9nZ2xlQ29sbGFwc2UoJGV2ZW50KVwiPjwvZ3QtZXhwYW5kaW5nLXJvdz5cbiAgICAgIDwvdGQ+XG4gICAgPC90cj5cbiAgICA8dHIgKm5nSWY9XCJndE9wdGlvbnMucmVwb3J0Q29sdW1uV2lkdGggJiYgbGFzdFwiPlxuICAgICAgPHRkIHN0eWxlPVwicGFkZGluZzogMDsgYm9yZGVyOm5vbmU7XCJcbiAgICAgICAgICAqbmdGb3I9XCJsZXQgY29sdW1uIG9mIGd0U2V0dGluZ3MgfCBndFZpc2libGU6Z3RTZXR0aW5nczpyZWZyZXNoUGlwZVwiIGd0Q29sdW1uV2lkdGhcbiAgICAgICAgICBbb2JqZWN0S2V5XT1cImNvbHVtbi5vYmplY3RLZXlcIiBbd2lkdGhzXT1cImNvbHVtbldpZHRoXCI+PC90ZD5cbiAgICA8L3RyPlxuICA8L25nLXRlbXBsYXRlPlxuICA8dHIgKm5nSWY9XCJndEluZm8ucGFnZVRvdGFsID09PSAwICYmIChndEluZm8uc2VhcmNoVGVybXMgfHwgZ3RJbmZvLmZpbHRlcikgJiYgIWxvYWRpbmdcIj5cbiAgICA8dGQgY2xhc3M9XCJndC1uby1tYXRjaGluZy1yZXN1bHRzXCIgW2F0dHIuY29sc3Bhbl09XCIoZ3RGaWVsZHMgfCBndFZpc2libGU6Z3RTZXR0aW5ncykubGVuZ3RoXCI+XG4gICAgICB7e2d0VGV4dHMubm9NYXRjaGluZ0RhdGF9fVxuICAgIDwvdGQ+XG4gIDwvdHI+XG4gIDx0ciAqbmdJZj1cImd0SW5mby5wYWdlVG90YWwgPT09IDAgJiYgIShndEluZm8uc2VhcmNoVGVybXMgfHwgZ3RJbmZvLmZpbHRlcikgJiYgIWxvYWRpbmdcIj5cbiAgICA8dGQgY2xhc3M9XCJndC1uby1yZXN1bHRzXCIgW2F0dHIuY29sc3Bhbl09XCIoZ3RGaWVsZHMgfCBndFZpc2libGU6Z3RTZXR0aW5ncykubGVuZ3RoXCI+e3tndFRleHRzLm5vRGF0YX19XG4gICAgPC90ZD5cbiAgPC90cj5cbiAgPHRyICpuZ0lmPVwiZ3RJbmZvLnBhZ2VUb3RhbCA9PT0gMCAmJiBsb2FkaW5nXCI+XG4gICAgPHRkIGNsYXNzPVwiZ3QtbG9hZGluZy1kYXRhXCIgW2F0dHIuY29sc3Bhbl09XCIoZ3RGaWVsZHMgfCBndFZpc2libGU6Z3RTZXR0aW5ncykubGVuZ3RoXCI+e3tndFRleHRzLmxvYWRpbmd9fTwvdGQ+XG4gIDwvdHI+XG4gIDwvdGJvZHk+XG48L3RhYmxlPlxuPHRhYmxlIGNsYXNzPVwidGFibGVcIiBuZ0NsYXNzPVwie3tndENsYXNzZXN9fSB7e2d0T3B0aW9ucy5zdGFjayA/ICd0YWJsZS1zdGFja2VkJzonJ319XCJcbiAgICAgICAqbmdJZj1cImd0RmllbGRzICYmIGd0U2V0dGluZ3MgJiYgKGd0RmllbGRzIHwgZ3RWaXNpYmxlOmd0U2V0dGluZ3M6cmVmcmVzaFBpcGUpLmxlbmd0aCA9PT0gMFwiPlxuICA8dGhlYWQ+XG4gIDx0cj5cbiAgICA8dGggY2xhc3M9XCJndC1uby12aXNpYmxlLWNvbHVtbnNcIj57e2d0VGV4dHMubm9WaXNpYmxlQ29sdW1uc0hlYWRpbmd9fTwvdGg+XG4gIDwvdHI+XG4gIDwvdGhlYWQ+XG4gIDx0Ym9keT5cbiAgPHRyPlxuICAgIDx0ZCBjbGFzcz1cImd0LW5vLXZpc2libGUtY29sdW1uc1wiPnt7Z3RUZXh0cy5ub1Zpc2libGVDb2x1bW5zfX08L3RkPlxuICA8L3RyPlxuICA8L3Rib2R5PlxuPC90YWJsZT5cbjx0YWJsZSBjbGFzcz1cInRhYmxlXCIgbmdDbGFzcz1cInt7Z3RDbGFzc2VzfX0ge3tndE9wdGlvbnMuc3RhY2sgPyAndGFibGUtc3RhY2tlZCc6Jyd9fVwiXG4gICAgICAgKm5nSWY9XCIhZ3RGaWVsZHMgfHwgIWd0U2V0dGluZ3NcIj5cbiAgPHRoZWFkPlxuICA8dHI+XG4gICAgPHRoIGNsYXNzPVwiZ3QtbG9hZGluZy1jb25maWdcIj4mbmJzcDs8L3RoPlxuICA8L3RyPlxuICA8L3RoZWFkPlxuICA8dGJvZHk+XG4gIDx0cj5cbiAgICA8dGQgY2xhc3M9XCJndC1sb2FkaW5nLWNvbmZpZ1wiPiZuYnNwOzwvdGQ+XG4gIDwvdHI+XG4gIDwvdGJvZHk+XG48L3RhYmxlPlxuYFxufSlcbmV4cG9ydCBjbGFzcyBHZW5lcmljVGFibGVDb21wb25lbnQ8UiBleHRlbmRzIEd0Um93LCBDIGV4dGVuZHMgR3RFeHBhbmRlZFJvdzxSPj5cblx0aW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcywgT25EZXN0cm95IHtcblx0Z2V0IGd0Um93Q29tcG9uZW50KCk6IFR5cGU8Qz4ge1xuXHRcdHJldHVybiB0aGlzLl9ndFJvd0NvbXBvbmVudDtcblx0fVxuXG5cdGdldCBoYXNFZGl0cygpOiBib29sZWFuIHtcblx0XHRyZXR1cm4gT2JqZWN0LmtleXModGhpcy5lZGl0ZWRSb3dzKS5sZW5ndGggPiAwO1xuXHR9XG5cblx0Z2V0IGd0T3B0aW9ucygpOiBHdE9wdGlvbnMge1xuXHRcdHJldHVybiB0aGlzLl9ndE9wdGlvbnM7XG5cdH1cblxuXHRnZXQgZ3RUb3RhbHMoKTogYW55IHtcblx0XHRyZXR1cm4gdGhpcy5fZ3RUb3RhbHM7XG5cdH1cblxuXHRnZXQgZ3RGaWVsZHMoKTogR3RDb25maWdGaWVsZDxSLCBhbnk+W10ge1xuXHRcdHJldHVybiB0aGlzLl9ndEZpZWxkcztcblx0fVxuXG5cdGdldCBndFNldHRpbmdzKCk6IEd0Q29uZmlnU2V0dGluZ1tdIHtcblx0XHRyZXR1cm4gdGhpcy5fZ3RTZXR0aW5ncztcblx0fVxuXG5cdGdldCBndERhdGEoKTogQXJyYXk8YW55PiB7XG5cdFx0cmV0dXJuIHRoaXMuX2d0RGF0YTtcblx0fVxuXG5cdEBJbnB1dCgpXG5cdHNldCBndE9wdGlvbnModmFsdWU6IEd0T3B0aW9ucykge1xuXHRcdHRoaXMuX2d0T3B0aW9ucyA9IHZhbHVlO1xuXG5cdFx0Ly8gaWYgbnVtYmVyIG9mIHJvd3MgaXMgcGFzc2VkIGFuZCBpZiBudW1iZXIgb2Ygcm93cyBkaWZmZXJzIGZyb20gY3VycmVudCByZWNvcmQgbGVuZ3RoLi4uXG5cdFx0aWYgKFxuXHRcdFx0dGhpcy5ndE9wdGlvbnMubnVtYmVyT2ZSb3dzICYmXG5cdFx0XHR0aGlzLmd0SW5mby5yZWNvcmRMZW5ndGggIT09IHRoaXMuZ3RPcHRpb25zLm51bWJlck9mUm93c1xuXHRcdCkge1xuXHRcdFx0Ly8gLi4udXBkYXRlIHJlY29yZCBsZW5ndGggYW5kIHJlZHJhdyB0YWJsZVxuXHRcdFx0dGhpcy5ndEluZm8ucmVjb3JkTGVuZ3RoID0gdGhpcy5ndE9wdGlvbnMubnVtYmVyT2ZSb3dzO1xuXHRcdFx0dGhpcy5yZWRyYXcoKTtcblx0XHR9XG5cblx0XHQvLyAuLi5leHRlbmQgZ3RPcHRpb25zIGRlZmF1bHQgdmFsdWVzIHdpdGggdmFsdWVzIHBhc3NlZCBpbnRvIGNvbXBvbmVudFxuXHRcdHRoaXMuX2d0T3B0aW9ucyA9IDxHdE9wdGlvbnM+dGhpcy5leHRlbmQoXG5cdFx0XHR0aGlzLmd0RGVmYXVsdE9wdGlvbnMsXG5cdFx0XHR0aGlzLl9ndE9wdGlvbnNcblx0XHQpO1xuXHR9XG5cblx0QElucHV0KClcblx0c2V0IGd0VG90YWxzKHZhbHVlOiBhbnkpIHtcblx0XHR0aGlzLl9ndFRvdGFscyA9IHZhbHVlO1xuXHR9XG5cdEBJbnB1dCgpXG5cdHNldCBndEZpZWxkcyh2YWx1ZTogR3RDb25maWdGaWVsZDxSLCBhbnk+W10pIHtcblx0XHR0aGlzLl9ndEZpZWxkcyA9IHZhbHVlO1xuXHRcdGNvbnN0IENPTFVNTlNfV0lUSF9DTEFTU19OQU1FUyA9IHRoaXMuX2d0RmllbGRzXG5cdFx0XHQubWFwKGNvbHVtbiA9PiBjb2x1bW4pXG5cdFx0XHQuZmlsdGVyKGNvbHVtbiA9PiBjb2x1bW4uY2xhc3NOYW1lcyk7XG5cdFx0Ly8gVE9ETzogcmVtb3ZlIGRlcHJlY2F0ZWQgd2FybmluZyB3aGVuIHNldHRpbmcgaGFzIGJlZW4gcmVtb3ZlZFxuXHRcdGlmIChDT0xVTU5TX1dJVEhfQ0xBU1NfTkFNRVMubGVuZ3RoID4gMCkge1xuXHRcdFx0Y29uc29sZS53YXJuKFxuXHRcdFx0XHQnRmllbGQgc2V0dGluZyBcImNsYXNzTmFtZXNcIiBoYXZlIGJlZW4gZGVwcmVjYXRlZCBpbiBmYXZvciBmb3IgXCJjb2x1bW5DbGFzc1wiIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gdGhlIGZ1dHVyZSwgcGxlYXNlIHVwZGF0ZSBmaWVsZCBzZXR0aW5ncyBmb3IgY29sdW1uIHdpdGggb2JqZWN0IGtleTogJyArXG5cdFx0XHRcdFx0Q09MVU1OU19XSVRIX0NMQVNTX05BTUVTWzBdLm9iamVjdEtleVxuXHRcdFx0KTtcblx0XHR9XG5cdH1cblx0QElucHV0KClcblx0c2V0IGd0U2V0dGluZ3ModmFsdWU6IEd0Q29uZmlnU2V0dGluZ1tdKSB7XG5cdFx0dGhpcy5fZ3RTZXR0aW5ncyA9IHZhbHVlO1xuXG5cdFx0Ly8gbG9vcCB0aHJvdWdoIGN1cnJlbnQgc2V0dGluZ3Ncblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2d0U2V0dGluZ3MubGVuZ3RoOyBpKyspIHtcblx0XHRcdC8vIHNldCBzb3J0IGVuYWJsZWQvZGlzYWJsZWQgc2V0dGluZ1xuXHRcdFx0dGhpcy5fZ3RTZXR0aW5nc1tpXS5zb3J0RW5hYmxlZCA9XG5cdFx0XHRcdHRoaXMuX2d0U2V0dGluZ3NbaV0uc29ydEVuYWJsZWQgIT09IGZhbHNlXG5cdFx0XHRcdFx0PyAodGhpcy5fZ3RTZXR0aW5nc1tpXS5zb3J0RW5hYmxlZCA9ICEoXG5cdFx0XHRcdFx0XHRcdHRoaXMuX2d0U2V0dGluZ3NbaV0uc29ydCAmJlxuXHRcdFx0XHRcdFx0XHR0aGlzLl9ndFNldHRpbmdzW2ldLnNvcnQuaW5kZXhPZignZGlzYWJsZScpICE9PSAtMVxuXHRcdFx0XHRcdCAgKSlcblx0XHRcdFx0XHQ6IGZhbHNlO1xuXG5cdFx0XHQvLyBjaGVjayBpZiBzb3J0aW5nIGlzIHVuZGVmaW5lZC4uLlxuXHRcdFx0aWYgKHR5cGVvZiB0aGlzLl9ndFNldHRpbmdzW2ldLnNvcnQgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRcdC8vIC4uLmlzIHNvLCBzZXQgc29ydGluZyBwcm9wZXJ0eSB0byBlbmFibGVcblx0XHRcdFx0dGhpcy5fZ3RTZXR0aW5nc1tpXS5zb3J0ID0gJ2VuYWJsZSc7XG5cdFx0XHR9XG5cblx0XHRcdC8vIGNoZWNrIGlmIGNvbHVtbiBvcmRlciBpcyB1bmRlZmluZWQuLi5cblx0XHRcdGlmIChcblx0XHRcdFx0dHlwZW9mIHRoaXMuX2d0U2V0dGluZ3NbaV0uY29sdW1uT3JkZXIgPT09ICd1bmRlZmluZWQnICYmXG5cdFx0XHRcdHRoaXMuX2d0U2V0dGluZ3NbaV0uZW5hYmxlZCAhPT0gZmFsc2Vcblx0XHRcdCkge1xuXHRcdFx0XHQvLyAuLi5pcyBzbywgc2V0IHNvcnRpbmcgcHJvcGVydHkgdG8gZW5hYmxlXG5cdFx0XHRcdHRoaXMuX2d0U2V0dGluZ3NbaV0uY29sdW1uT3JkZXIgPSB0aGlzLl9ndFNldHRpbmdzW2kgLSAxXVxuXHRcdFx0XHRcdD8gdGhpcy5fZ3RTZXR0aW5nc1tpIC0gMV0uY29sdW1uT3JkZXIgKyAxXG5cdFx0XHRcdFx0OiAwO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBjaGVjayBpZiBjb2x1bW4gbG9jayBzZXR0aW5ncyBhcmUgdW5kZWZpbmVkLi4uXG5cdFx0XHRpZiAodHlwZW9mIHRoaXMuX2d0U2V0dGluZ3NbaV0ubG9ja1NldHRpbmdzID09PSAndW5kZWZpbmVkJykge1xuXHRcdFx0XHQvLyAuLi5pZiBzbywgc2V0IGxvY2sgc2V0dGluZ3MgdG8gZmFsc2UgdW5sZXNzIGZpZWxkIGlzIGRpc2FibGVkIChlbmFibGUgPT09IGZhbHNlKVxuXHRcdFx0XHR0aGlzLl9ndFNldHRpbmdzW2ldLmxvY2tTZXR0aW5ncyA9XG5cdFx0XHRcdFx0dGhpcy5fZ3RTZXR0aW5nc1tpXS5lbmFibGVkID09PSBmYWxzZSB8fCBmYWxzZTtcblx0XHRcdH1cblx0XHR9XG5cdFx0dGhpcy5yZXN0cnVjdHVyZVNvcnRpbmcoKTtcblx0fVxuXHRASW5wdXQoKVxuXHRzZXQgZ3REYXRhKGluaXRpYWxEYXRhOiBBcnJheTxhbnk+KSB7XG5cdFx0Y29uc3QgZGF0YSA9IHRoaXMuX2d0T3B0aW9ucy5tdXRhdGVEYXRhXG5cdFx0XHQ/IFsuLi5pbml0aWFsRGF0YV1cblx0XHRcdDogdGhpcy5jbG9uZURlZXAoaW5pdGlhbERhdGEpO1xuXHRcdGlmICh0aGlzLmd0T3B0aW9ucy5sYXp5TG9hZCAmJiB0aGlzLmd0SW5mbykge1xuXHRcdFx0dGhpcy5ndE1ldGFQaXBlLnRyYW5zZm9ybShcblx0XHRcdFx0ZGF0YSxcblx0XHRcdFx0dGhpcy5ndE9wdGlvbnMucm93SW5kZXgsXG5cdFx0XHRcdHRoaXMuZ3RJbmZvLnBhZ2VDdXJyZW50IC0gMSxcblx0XHRcdFx0dGhpcy5ndEluZm8ucmVjb3JkTGVuZ3RoXG5cdFx0XHQpO1xuXHRcdFx0aWYgKHRoaXMubGF6eUFsbFNlbGVjdGVkKSB7XG5cdFx0XHRcdGNvbnN0IFVOSVFVRV9ST1dTID0gdGhpcy5zZWxlY3RlZFJvd3MubWFwKHJvdyA9PiByb3cuJCRndFJvd0lkKTtcblx0XHRcdFx0ZGF0YS5tYXAocm93ID0+IHtcblx0XHRcdFx0XHRpZiAoVU5JUVVFX1JPV1MuaW5kZXhPZihyb3cuJCRndFJvd0lkKSA9PT0gLTEpIHtcblx0XHRcdFx0XHRcdHRoaXMuc2VsZWN0ZWRSb3dzLnB1c2gocm93KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pO1xuXHRcdFx0XHR0aGlzLl91cGRhdGVNZXRhSW5mbyh0aGlzLnNlbGVjdGVkUm93cywgJ2lzU2VsZWN0ZWQnLCB0cnVlKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5ndE1ldGFQaXBlLnRyYW5zZm9ybShkYXRhLCB0aGlzLmd0T3B0aW9ucy5yb3dJbmRleCk7XG5cdFx0fVxuXHRcdGlmICh0aGlzLmd0T3B0aW9ucy5yb3dTZWxlY3Rpb25Jbml0aWFsU3RhdGUpIHtcblx0XHRcdGRhdGEubWFwKHJvdyA9PiB7XG5cdFx0XHRcdGNvbnN0IHNlbGVjdGVkID1cblx0XHRcdFx0XHR0eXBlb2YgdGhpcy5ndE9wdGlvbnMucm93U2VsZWN0aW9uSW5pdGlhbFN0YXRlID09PSAnZnVuY3Rpb24nXG5cdFx0XHRcdFx0XHQ/IHRoaXMuZ3RPcHRpb25zLnJvd1NlbGVjdGlvbkluaXRpYWxTdGF0ZShyb3cpXG5cdFx0XHRcdFx0XHQ6IHRoaXMuZ3RPcHRpb25zLnJvd1NlbGVjdGlvbkluaXRpYWxTdGF0ZTtcblx0XHRcdFx0aWYgKHNlbGVjdGVkKSB7XG5cdFx0XHRcdFx0aWYgKHR5cGVvZiB0aGlzLm1ldGFJbmZvW3Jvdy4kJGd0Um93SWRdID09PSAndW5kZWZpbmVkJykge1xuXHRcdFx0XHRcdFx0dGhpcy5tZXRhSW5mb1tyb3cuJCRndFJvd0lkXSA9IHsgaXNTZWxlY3RlZDogdHJ1ZSB9O1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHR0aGlzLm1ldGFJbmZvW3Jvdy4kJGd0Um93SWRdLmlzU2VsZWN0ZWQgPSB0cnVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHR0aGlzLnNlbGVjdGVkUm93cy5wdXNoKHJvdyk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH1cblx0XHRpZiAoXG5cdFx0XHR0aGlzLmd0T3B0aW9ucy5yb3dFeHBhbmRJbml0aWFsU3RhdGUgJiZcblx0XHRcdHRoaXMuZ3RPcHRpb25zLnJvd0V4cGFuZEluaXRpYWxDb21wb25lbnRcblx0XHQpIHtcblx0XHRcdGRhdGEubWFwKHJvdyA9PiB7XG5cdFx0XHRcdGNvbnN0IGV4cGFuZGVkID1cblx0XHRcdFx0XHR0eXBlb2YgdGhpcy5ndE9wdGlvbnMucm93RXhwYW5kSW5pdGlhbFN0YXRlID09PSAnZnVuY3Rpb24nXG5cdFx0XHRcdFx0XHQ/IHRoaXMuZ3RPcHRpb25zLnJvd0V4cGFuZEluaXRpYWxTdGF0ZShyb3cpXG5cdFx0XHRcdFx0XHQ6IHRoaXMuZ3RPcHRpb25zLnJvd0V4cGFuZEluaXRpYWxTdGF0ZTtcblx0XHRcdFx0dGhpcy5leHBhbmRlZFJvdyA9IHRoaXMuZ3RPcHRpb25zLnJvd0V4cGFuZEluaXRpYWxDb21wb25lbnQ7XG5cblx0XHRcdFx0aWYgKGV4cGFuZGVkKSB7XG5cdFx0XHRcdFx0aWYgKHR5cGVvZiB0aGlzLm1ldGFJbmZvW3Jvdy4kJGd0Um93SWRdID09PSAndW5kZWZpbmVkJykge1xuXHRcdFx0XHRcdFx0dGhpcy5tZXRhSW5mb1tyb3cuJCRndFJvd0lkXSA9IHsgaXNPcGVuOiB0cnVlIH07XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHRoaXMubWV0YUluZm9bcm93LiQkZ3RSb3dJZF0uaXNPcGVuID0gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH1cblx0XHR0aGlzLl9ndERhdGEgPSBkYXRhO1xuXHR9XG5cblx0QElucHV0KClcblx0c2V0IGd0Um93Q29tcG9uZW50KHZhbHVlOiBUeXBlPEM+KSB7XG5cdFx0Y29uc29sZS53YXJuKFxuXHRcdFx0J0d0Um93Q29tcG9uZW50IGhhcyBiZWVuIGRlcHJlY2F0ZWQgYW5kIHN1cHBvcnQgd2lsbCBiZSByZW1vdmVkIGluIGEgZnV0dXJlIHJlbGVhc2UsIHNlZSBodHRwczovL2dpdGh1Yi5jb20vaGphbG1lcnMvYW5ndWxhci1nZW5lcmljLXRhYmxlL2lzc3Vlcy8zNCdcblx0XHQpO1xuXHRcdHRoaXMuX2d0Um93Q29tcG9uZW50ID0gdmFsdWU7XG5cdH1cblxuXHRwdWJsaWMgY29sdW1uV2lkdGg6IE9iamVjdCA9IHt9O1xuXHRwdWJsaWMgY29uZmlnT2JqZWN0OiBHdENvbmZpZzxSPjtcblx0cHVibGljIHNvcnRPcmRlcjogQXJyYXk8YW55PiA9IFtdO1xuXHRwdWJsaWMgbWV0YUluZm86IHsgW2d0Um93SWQ6IHN0cmluZ106IEd0Um93TWV0YSB9ID0ge307XG5cdHB1YmxpYyBzZWxlY3RlZFJvd3M6IEFycmF5PEd0Um93PiA9IFtdO1xuXHRwdWJsaWMgb3BlblJvd3M6IEFycmF5PEd0Um93PiA9IFtdO1xuXHRwcml2YXRlIF9ndFNldHRpbmdzOiBHdENvbmZpZ1NldHRpbmdbXSA9IFtdO1xuXHRwcml2YXRlIF9ndEZpZWxkczogR3RDb25maWdGaWVsZDxSLCBhbnk+W10gPSBbXTtcblx0cHJpdmF0ZSBfZ3REYXRhOiBBcnJheTxhbnk+O1xuXHRwcml2YXRlIF9ndFRvdGFsczogYW55O1xuXHRwcml2YXRlIF9ndFJvd0NvbXBvbmVudDogVHlwZTxDPjtcblx0cHVibGljIGV4cGFuZGVkUm93OiB7XG5cdFx0Y29tcG9uZW50OiBUeXBlPEM+O1xuXHRcdGRhdGE/OiBBcnJheTxhbnk+O1xuXHR9O1xuXHRwdWJsaWMgZ3REZWZhdWx0VGV4dHM6IEd0VGV4dHMgPSB7XG5cdFx0bG9hZGluZzogJ0xvYWRpbmcuLi4nLFxuXHRcdG5vRGF0YTogJ05vIGRhdGEnLFxuXHRcdG5vTWF0Y2hpbmdEYXRhOiAnTm8gZGF0YSBtYXRjaGluZyByZXN1bHRzIGZvdW5kJyxcblx0XHRub1Zpc2libGVDb2x1bW5zSGVhZGluZzogJ05vIHZpc2libGUgY29sdW1ucycsXG5cdFx0bm9WaXNpYmxlQ29sdW1uczogJ1BsZWFzZSBzZWxlY3QgYXQgbGVhc3Qgb25lIGNvbHVtbiB0byBiZSB2aXNpYmxlLicsXG5cdFx0dGFibGVJbmZvOlxuXHRcdFx0J1Nob3dpbmcgI3JlY29yZEZyb20gdG8gI3JlY29yZFRvIG9mICNyZWNvcmRzQWZ0ZXJTZWFyY2ggZW50cmllcy4nLFxuXHRcdHRhYmxlSW5mb0FmdGVyU2VhcmNoOlxuXHRcdFx0J1Nob3dpbmcgICNyZWNvcmRGcm9tIHRvICNyZWNvcmRUbyBvZiAjcmVjb3Jkc0FmdGVyU2VhcmNoIGVudHJpZXMgKGZpbHRlcmVkIGZyb20gYSB0b3RhbCBvZiAjcmVjb3Jkc0FsbCBlbnRyaWVzKS4nLFxuXHRcdGNzdkRvd25sb2FkOiAnZG93bmxvYWQnLFxuXHRcdHNvcnRMYWJlbDogJ1NvcnQ6Jyxcblx0XHRwYWdpbmF0ZU5leHQ6ICdOZXh0IHBhZ2UnLFxuXHRcdHBhZ2luYXRlUHJldmlvdXM6ICdQcmV2aW91cyBwYWdlJyxcblx0XHRpbmxpbmVFZGl0RWRpdGVkOiAnUHJlc3MgZW50ZXIgdG8gc2F2ZSdcblx0fTtcblx0QElucHV0KCkgZ3RUZXh0czogR3RUZXh0cyA9IHRoaXMuZ3REZWZhdWx0VGV4dHM7XG5cdEBJbnB1dCgpIGd0Q2xhc3Nlczogc3RyaW5nO1xuXHRAT3V0cHV0KCkgZ3RFdmVudDogRXZlbnRFbWl0dGVyPEd0RXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXHRwdWJsaWMgZ3REZWZhdWx0T3B0aW9uczogR3RPcHRpb25zID0ge1xuXHRcdGNzdkRlbGltaXRlcjogJzsnLFxuXHRcdHN0YWNrOiBmYWxzZSxcblx0XHRsYXp5TG9hZDogZmFsc2UsXG5cdFx0Y2FjaGU6IGZhbHNlLFxuXHRcdGRlYm91bmNlVGltZTogMjAwLFxuXHRcdGhpZ2hsaWdodFNlYXJjaDogZmFsc2UsXG5cdFx0cm93U2VsZWN0aW9uOiBmYWxzZSxcblx0XHRyb3dTZWxlY3Rpb25BbGxvd011bHRpcGxlOiB0cnVlLFxuXHRcdHJvd0V4cGFuZEFsbG93TXVsdGlwbGU6IHRydWUsXG5cdFx0bnVtYmVyT2ZSb3dzOiAxMCxcblx0XHRyZXBvcnRDb2x1bW5XaWR0aDogZmFsc2UsXG5cdFx0YWxsb3dVbnNvcnRlZDogdHJ1ZSxcblx0XHRtdXRhdGVEYXRhOiB0cnVlXG5cdH07XG5cdHByaXZhdGUgX2d0T3B0aW9uczogR3RPcHRpb25zID0gdGhpcy5ndERlZmF1bHRPcHRpb25zO1xuXHRwdWJsaWMgc3RvcmU6IEFycmF5PGFueT4gPSBbXTtcblx0cHVibGljIGxvYWRpbmcgPSB0cnVlO1xuXHRwcml2YXRlIGRlYm91bmNlVGltZXI6IHZvaWQgPSBudWxsO1xuXHRwdWJsaWMgbG9hZGluZ1Byb3BlcnR5OiBzdHJpbmc7XG5cdHB1YmxpYyBsYXp5QWxsU2VsZWN0ZWQgPSBmYWxzZTtcblxuXHRASW5wdXQoKVxuXHRndEluZm86IEd0SW5mb3JtYXRpb24gPSB7XG5cdFx0cGFnZUN1cnJlbnQ6IDEsXG5cdFx0cGFnZVRvdGFsOiAwLFxuXHRcdHJlY29yZEZyb206IDAsXG5cdFx0cmVjb3JkVG86IDAsXG5cdFx0cmVjb3JkTGVuZ3RoOiB0aGlzLmd0T3B0aW9ucy5udW1iZXJPZlJvd3MsXG5cdFx0cmVjb3Jkc0FsbDogMCxcblx0XHRyZWNvcmRzQWZ0ZXJGaWx0ZXI6IDAsXG5cdFx0cmVjb3Jkc0FmdGVyU2VhcmNoOiAwXG5cdH07XG5cblx0cHVibGljIHJlZnJlc2hQaXBlID0gZmFsc2U7XG5cdHB1YmxpYyByZWZyZXNoVG90YWxzID0gZmFsc2U7XG5cdHB1YmxpYyByZWZyZXNoU29ydGluZyA9IGZhbHNlO1xuXHRwdWJsaWMgcmVmcmVzaEZpbHRlciA9IGZhbHNlO1xuXHRwdWJsaWMgcmVmcmVzaFBhZ2VBcnJheSA9IGZhbHNlO1xuXHRwcml2YXRlIGdsb2JhbElubGluZUVkaXRMaXN0ZW5lcjogRnVuY3Rpb247XG5cdHB1YmxpYyBlZGl0ZWRSb3dzOiB7XG5cdFx0W2tleTogc3RyaW5nXToge1xuXHRcdFx0Y2hhbmdlczogeyBba2V5OiBzdHJpbmddOiBHdFJlbmRlckZpZWxkPEd0Um93LCBhbnk+IH07XG5cdFx0XHRyb3c6IEd0Um93O1xuXHRcdH07XG5cdH0gPSB7fTtcblxuXHRwdWJsaWMgZGF0YTogeyBleHBvcnREYXRhOiBBcnJheTxhbnk+IH0gPSB7IGV4cG9ydERhdGE6IFtdIH07IC8vIFN0b3JlIGZpbHRlcmVkIGRhdGEgZm9yIGV4cG9ydFxuXG5cdGNvbnN0cnVjdG9yKHByaXZhdGUgcmVuZGVyZXI6IFJlbmRlcmVyMiwgcHJpdmF0ZSBndE1ldGFQaXBlOiBHdE1ldGFQaXBlKSB7XG5cdFx0dGhpcy5ndEV2ZW50LnN1YnNjcmliZSgoJGV2ZW50OiBHdEV2ZW50KSA9PiB7XG5cdFx0XHRpZiAoJGV2ZW50Lm5hbWUgPT09ICdndC1pbmZvJykge1xuXHRcdFx0XHR0aGlzLnVwZGF0ZVJlY29yZFJhbmdlKCk7XG5cdFx0XHR9XG5cdFx0XHRpZiAoJGV2ZW50Lm5hbWUgPT09ICdndC1yb3ctdXBkYXRlZCcpIHtcblx0XHRcdFx0dGhpcy51cGRhdGVUb3RhbHMoKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTb3J0IHRhYmxlIGJ5IG9iamVjdCBrZXkuXG5cdCAqIEBwYXJhbSBvYmplY3RLZXkgLSBuYW1lIG9mIGtleSB0byBzb3J0IG9uLlxuXHQgKiBAcGFyYW0gZXZlbnQgLSBzdWNoIGFzIGtleSBwcmVzcyBkdXJpbmcgc29ydGluZy5cblx0ICovXG5cdHB1YmxpYyBndFNvcnQgPSBmdW5jdGlvbihvYmplY3RLZXk6IHN0cmluZywgZXZlbnQ6IGFueSkge1xuXHRcdHRoaXMuaW5saW5lRWRpdENhbmNlbCgpOyAvLyBjYW5jZWwgaW5saW5lIGVkaXRpbmdcblxuXHRcdC8vIGxvb3AgdGhyb3VnaCBjdXJyZW50IHNldHRpbmdzXG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9ndFNldHRpbmdzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRpZiAodGhpcy5fZ3RTZXR0aW5nc1tpXS5vYmplY3RLZXkgPT09IG9iamVjdEtleSkge1xuXHRcdFx0XHQvLyBjaGVjayBpZiBzb3J0aW5nIGlzIGRpc2FibGVkLi4uXG5cdFx0XHRcdGlmIChcblx0XHRcdFx0XHR0aGlzLl9ndFNldHRpbmdzW2ldLnNvcnQgJiZcblx0XHRcdFx0XHR0aGlzLl9ndFNldHRpbmdzW2ldLnNvcnQuaW5kZXhPZignZGlzYWJsZScpICE9PSAtMVxuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHQvLyAuLi5pZiBzbywgZXhpdCBmdW5jdGlvbiB3aXRob3V0IGFwcGx5aW5nIGFueSBzb3J0aW5nXG5cdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHR9IGVsc2UgaWYgKFxuXHRcdFx0XHRcdC8qIGNoZWNrIGlmIHNvcnRpbmcgaXMgdW5kZWZpbmVkLi4uICovIHR5cGVvZiB0aGlzLl9ndFNldHRpbmdzW2ldXG5cdFx0XHRcdFx0XHQuc29ydCA9PT0gJ3VuZGVmaW5lZCdcblx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0Ly8gLi4uaXMgc28sIHNldCBzb3J0aW5nIHByb3BlcnR5IHRvIGVuYWJsZVxuXHRcdFx0XHRcdHRoaXMuX2d0U2V0dGluZ3NbaV0uc29ydCA9ICdlbmFibGUnO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gY2hlY2sgbGVuZ3RoXG5cdFx0Y29uc3QgY3RybEtleSA9IGV2ZW50Lm1ldGFLZXkgfHwgZXZlbnQuY3RybEtleTtcblx0XHRjb25zdCBzb3J0ID0gdGhpcy5zb3J0T3JkZXIuc2xpY2UoMCk7XG5cblx0XHRsZXQgbWF0Y2ggPSAtMTtcblx0XHRsZXQgbWF0Y2hEZXNjID0gLTE7XG5cdFx0bGV0IHBvcyA9IC0xO1xuXG5cdFx0Ly8gY2hlY2sgaWYgcHJvcGVydHkgYWxyZWFkeSBleGl0c1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgc29ydC5sZW5ndGg7IGkrKykge1xuXHRcdFx0Y29uc3QgaGl0ID0gc29ydFtpXS5pbmRleE9mKG9iamVjdEtleSk7XG5cdFx0XHRpZiAoaGl0ICE9PSAtMSkge1xuXHRcdFx0XHRtYXRjaCA9IHRoaXMuc29ydE9yZGVyLmluZGV4T2Yob2JqZWN0S2V5KTtcblx0XHRcdFx0bWF0Y2hEZXNjID1cblx0XHRcdFx0XHRtYXRjaCA9PT0gLTEgPyB0aGlzLnNvcnRPcmRlci5pbmRleE9mKCctJyArIG9iamVjdEtleSkgOiBtYXRjaDtcblx0XHRcdFx0cG9zID0gTWF0aC5tYXgobWF0Y2gsIG1hdGNoRGVzYyk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gaWYgY3RybCBrZXkgb3IgbWV0YSBrZXkgaXMgcHJlc3MgdG9nZXRoZXIgd2l0aCBzb3J0Li4uXG5cdFx0aWYgKGN0cmxLZXkpIHtcblx0XHRcdGlmICh0aGlzLnNvcnRPcmRlclt0aGlzLnNvcnRPcmRlci5sZW5ndGggLSAxXSA9PT0gJyQkZ3RJbml0aWFsUm93SW5kZXgnKSB7XG5cdFx0XHRcdHRoaXMuc29ydE9yZGVyLnBvcCgpO1xuXHRcdFx0fVxuXHRcdFx0c3dpdGNoIChwb3MpIHtcblx0XHRcdFx0Ly8gLi4uYW5kIHByb3BlcnR5IGlzIG5vdCBzb3J0ZWQgYmVmb3JlLi4uXG5cdFx0XHRcdGNhc2UgLTE6XG5cdFx0XHRcdFx0Ly8gLi4uYWRkIHByb3BlcnR5IHRvIHNvcnRpbmdcblx0XHRcdFx0XHR0aGlzLnNvcnRPcmRlci5wdXNoKG9iamVjdEtleSk7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0Ly8gLi4uYW5kIHByb3BlcnR5IGlzIHNvcnRlZCBiZWZvcmUuLi5cblx0XHRcdFx0XHRpZiAobWF0Y2ggIT09IC0xKSB7XG5cdFx0XHRcdFx0XHQvLyAuLi5jaGFuZ2UgZnJvbSBhc2MgdG8gZGVzYyBpZiBzb3J0ZWQgYXNjXG5cdFx0XHRcdFx0XHR0aGlzLnNvcnRPcmRlcltwb3NdID0gJy0nICsgb2JqZWN0S2V5O1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAodGhpcy5zb3J0T3JkZXIubGVuZ3RoID4gMSkge1xuXHRcdFx0XHRcdFx0Ly8gLi4ucmVtb3ZlIHNvcnRpbmcgaWYgc29ydGVkIGRlc2Ncblx0XHRcdFx0XHRcdGlmIChjdHJsS2V5KSB7XG5cdFx0XHRcdFx0XHRcdHRoaXMuc29ydE9yZGVyW3Bvc10gPSBvYmplY3RLZXk7XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHR0aGlzLnNvcnRPcmRlci5zcGxpY2UocG9zLCAxKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9IGVsc2UgaWYgKHRoaXMuc29ydE9yZGVyLmxlbmd0aCA9PT0gMSkge1xuXHRcdFx0XHRcdFx0Ly8gLi4uc2V0IHNvcnRpbmcgdG8gYXNjIGlmIG9ubHkgc29ydGVkIHByb3BlcnR5XG5cdFx0XHRcdFx0XHR0aGlzLnNvcnRPcmRlcltwb3NdID0gb2JqZWN0S2V5O1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0LyogaWYgY3RybCBrZXkgb3IgbWV0YSBrZXkgaXMgbm90IHByZXNzIHRvZ2V0aGVyIHdpdGggc29ydC4uLiAqL1xuXHRcdFx0c3dpdGNoIChwb3MpIHtcblx0XHRcdFx0Ly8gLi4uYW5kIHByb3BlcnR5IGlzIG5vdCBzb3J0ZWQgYmVmb3JlLi4uXG5cdFx0XHRcdGNhc2UgLTE6XG5cdFx0XHRcdFx0Ly8gLi4uc29ydCBieSBwcm9wZXJ0eVxuXHRcdFx0XHRcdHRoaXMuc29ydE9yZGVyID0gW29iamVjdEtleV07XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGRlZmF1bHQ6XG5cdFx0XHRcdFx0Ly8gLi4uY2hhbmdlIGZyb20gZGVzYyB0byBhc2MgYW5kIHZpc2UgdmVyc2Fcblx0XHRcdFx0XHR0aGlzLnNvcnRPcmRlciA9XG5cdFx0XHRcdFx0XHRtYXRjaCAhPT0gLTFcblx0XHRcdFx0XHRcdFx0PyBbJy0nICsgb2JqZWN0S2V5XVxuXHRcdFx0XHRcdFx0XHQ6IGN0cmxLZXkgfHwgIXRoaXMuZ3RPcHRpb25zLmFsbG93VW5zb3J0ZWRcblx0XHRcdFx0XHRcdFx0XHQ/IFtvYmplY3RLZXldXG5cdFx0XHRcdFx0XHRcdFx0OiBbXTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyB1cGRhdGUgc2V0dGluZ3Mgb2JqZWN0IHdpdGggbmV3IHNvcnRpbmcgaW5mb3JtYXRpb25cblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2d0U2V0dGluZ3MubGVuZ3RoOyBpKyspIHtcblx0XHRcdGlmICh0aGlzLl9ndFNldHRpbmdzW2ldLm9iamVjdEtleSA9PT0gb2JqZWN0S2V5KSB7XG5cdFx0XHRcdHN3aXRjaCAodGhpcy5fZ3RTZXR0aW5nc1tpXS5zb3J0KSB7XG5cdFx0XHRcdFx0Ly8gaWYgc29ydGVkIGFzYy4uLlxuXHRcdFx0XHRcdGNhc2UgJ2FzYyc6XG5cdFx0XHRcdFx0XHQvLyAuLi5jaGFuZ2UgdG8gZGVzY1xuXHRcdFx0XHRcdFx0dGhpcy5fZ3RTZXR0aW5nc1tpXS5zb3J0ID0gJ2Rlc2MnO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Ly8gaWYgc29ydGVkIGRlc2MuLi5cblx0XHRcdFx0XHRjYXNlICdkZXNjJzpcblx0XHRcdFx0XHRcdC8vIC4uLmNoYW5nZSB0byBhc2MgaWYgaXQncyB0aGUgb25seSBzb3J0ZWQgcHJvcGVydHkgb3RoZXJ3aXNlIHJlbW92ZSBzb3J0aW5nXG5cdFx0XHRcdFx0XHR0aGlzLl9ndFNldHRpbmdzW2ldLnNvcnQgPVxuXHRcdFx0XHRcdFx0XHQodGhpcy5zb3J0T3JkZXIubGVuZ3RoID09PSAxICYmIHNvcnQubGVuZ3RoIDwgMikgfHxcblx0XHRcdFx0XHRcdFx0Y3RybEtleSB8fFxuXHRcdFx0XHRcdFx0XHQhdGhpcy5ndE9wdGlvbnMuYWxsb3dVbnNvcnRlZFxuXHRcdFx0XHRcdFx0XHRcdD8gJ2FzYydcblx0XHRcdFx0XHRcdFx0XHQ6ICdlbmFibGUnO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Ly8gaWYgc29ydGluZyBlbmFibGVkLi4uXG5cdFx0XHRcdFx0Y2FzZSAnZW5hYmxlJzpcblx0XHRcdFx0XHRcdC8vIC4uLmNoYW5nZSB0byBhc2Ncblx0XHRcdFx0XHRcdHRoaXMuX2d0U2V0dGluZ3NbaV0uc29ydCA9ICdhc2MnO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdFx0dGhpcy5fZ3RTZXR0aW5nc1tpXS5zb3J0T3JkZXIgPVxuXHRcdFx0XHRcdHRoaXMuX2d0U2V0dGluZ3NbaV0uc29ydCA9PT0gJ2VuYWJsZSdcblx0XHRcdFx0XHRcdD8gdGhpcy5fZ3RTZXR0aW5ncy5sZW5ndGggLSAxXG5cdFx0XHRcdFx0XHQ6IHRoaXMuc29ydE9yZGVyLmluZGV4T2Yob2JqZWN0S2V5KSA9PT0gLTFcblx0XHRcdFx0XHRcdFx0PyB0aGlzLnNvcnRPcmRlci5pbmRleE9mKCctJyArIG9iamVjdEtleSlcblx0XHRcdFx0XHRcdFx0OiB0aGlzLnNvcnRPcmRlci5pbmRleE9mKG9iamVjdEtleSk7XG5cdFx0XHR9IGVsc2UgaWYgKFxuXHRcdFx0XHR0aGlzLl9ndFNldHRpbmdzW2ldLnNvcnQgJiZcblx0XHRcdFx0dGhpcy5fZ3RTZXR0aW5nc1tpXS5zb3J0LmluZGV4T2YoJ2Rpc2FibGUnKSA9PT0gLTEgJiZcblx0XHRcdFx0dGhpcy5zb3J0T3JkZXIuaW5kZXhPZih0aGlzLl9ndFNldHRpbmdzW2ldLm9iamVjdEtleSkgPT09IC0xICYmXG5cdFx0XHRcdHRoaXMuc29ydE9yZGVyLmluZGV4T2YoJy0nICsgdGhpcy5fZ3RTZXR0aW5nc1tpXS5vYmplY3RLZXkpID09PSAtMVxuXHRcdFx0KSB7XG5cdFx0XHRcdHRoaXMuX2d0U2V0dGluZ3NbaV0uc29ydCA9ICdlbmFibGUnO1xuXHRcdFx0XHR0aGlzLl9ndFNldHRpbmdzW2ldLnNvcnRPcmRlciA9IHRoaXMuX2d0U2V0dGluZ3MubGVuZ3RoIC0gMTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyByZWZyZXNoIHNvcnRpbmcgcGlwZVxuXHRcdHRoaXMucmVmcmVzaFNvcnRpbmcgPSAhdGhpcy5yZWZyZXNoU29ydGluZztcblx0XHR0aGlzLnJlZnJlc2hQYWdlQXJyYXkgPSAhdGhpcy5yZWZyZXNoUGFnZUFycmF5O1xuXG5cdFx0Ly8gc29ydCBieSBpbml0aWFsIHNvcnQgb3JkZXIgYXMgbGFzdCByZXNvcnRcblx0XHR0aGlzLnNvcnRPcmRlci5wdXNoKCckJGd0SW5pdGlhbFJvd0luZGV4Jyk7XG5cblx0XHQvLyBlbWl0IHNvcnQgZXZlbnRcblx0XHR0aGlzLmd0RXZlbnQuZW1pdCh7XG5cdFx0XHRuYW1lOiAnZ3Qtc29ydGluZy1hcHBsaWVkJyxcblx0XHRcdHZhbHVlOiB0aGlzLnNvcnRPcmRlclxuXHRcdH0pO1xuXHR9O1xuXG5cdC8qKlxuXHQgKiBDaGFuZ2UgbnVtYmVyIG9mIHJvd3MgdG8gYmUgZGlzcGxheWVkLlxuXHQgKiBAcGFyYW0gcm93TGVuZ3RoIC0gdG90YWwgbnVtYmVyIG9mIHJvd3MuXG5cdCAqIEBwYXJhbSByZXNldCAtIHNob3VsZCBwYWdlIGJlIHJlc2V0IHRvIGZpcnN0IHBhZ2UuXG5cdCAqL1xuXHRwdWJsaWMgY2hhbmdlUm93TGVuZ3RoID0gZnVuY3Rpb24ocm93TGVuZ3RoOiBhbnksIHJlc2V0PzogYm9vbGVhbikge1xuXHRcdGxldCBsZW5ndGhWYWx1ZSA9IGlzTmFOKHBhcnNlSW50KHJvd0xlbmd0aCwgMTApKVxuXHRcdFx0PyAwXG5cdFx0XHQ6IHBhcnNlSW50KHJvd0xlbmd0aCwgMTApO1xuXHRcdGxldCBuZXdQb3NpdGlvbiA9IDE7XG5cblx0XHRpZiAoIWxlbmd0aFZhbHVlICYmIHRoaXMuZ3REYXRhKSB7XG5cdFx0XHRsZW5ndGhWYWx1ZSA9IHRoaXMuZ3REYXRhLmxlbmd0aDtcblx0XHR9XG5cblx0XHQvLyBpZiByZXNldCBpcyBub3QgdHJ1ZSBhbmQgd2UncmUgbm90IGxhenkgbG9hZGluZyBkYXRhLi4uXG5cdFx0aWYgKHJlc2V0ICE9PSB0cnVlICYmIHRoaXMuX2d0T3B0aW9ucy5sYXp5TG9hZCAhPT0gdHJ1ZSkge1xuXHRcdFx0Ly8gLi4uZ2V0IGN1cnJlbnQgcG9zaXRpb24gaW4gcmVjb3JkIHNldFxuXHRcdFx0Y29uc3QgY3VycmVudFJlY29yZCA9XG5cdFx0XHRcdHRoaXMuZ3RJbmZvLnJlY29yZExlbmd0aCAqICh0aGlzLmd0SW5mby5wYWdlQ3VycmVudCAtIDEpO1xuXHRcdFx0Y29uc3QgY3VycmVudFBvc2l0aW9uID1cblx0XHRcdFx0dGhpcy5fZ3REYXRhLmluZGV4T2YodGhpcy5fZ3REYXRhW2N1cnJlbnRSZWNvcmRdKSArIDE7XG5cblx0XHRcdC8vIC4uLmdldCBuZXcgcG9zaXRpb25cblx0XHRcdG5ld1Bvc2l0aW9uID0gTWF0aC5jZWlsKGN1cnJlbnRQb3NpdGlvbiAvIGxlbmd0aFZhbHVlKTtcblx0XHR9XG5cblx0XHQvLyBjaGFuZ2Ugcm93IGxlbmd0aFxuXHRcdHRoaXMuZ3RJbmZvLnJlY29yZExlbmd0aCA9IGxlbmd0aFZhbHVlO1xuXG5cdFx0Ly8gZ28gdG8gbmV3IHBvc2l0aW9uXG5cdFx0dGhpcy5ndEluZm8ucGFnZUN1cnJlbnQgPSBuZXdQb3NpdGlvbjtcblxuXHRcdC8vIGlmIGxhenkgbG9hZGluZyBkYXRhLi4uXG5cdFx0aWYgKHRoaXMuX2d0T3B0aW9ucy5sYXp5TG9hZCkge1xuXHRcdFx0Ly8gLi4ucmVwbGFjZSBkYXRhIHdpdGggcGxhY2UgaG9sZGVycyBmb3IgbmV3IGRhdGFcblx0XHRcdHRoaXMuX2d0RGF0YVswXSA9IHRoaXMubG9hZGluZ0NvbnRlbnQobGVuZ3RoVmFsdWUpO1xuXG5cdFx0XHQvLyAuLi5lbXB0eSBjdXJyZW50IHN0b3JlXG5cdFx0XHR0aGlzLnN0b3JlID0gW107XG5cdFx0fVxuXG5cdFx0Ly8gdGhpcy51cGRhdGVSZWNvcmRSYW5nZSgpO1xuXG5cdFx0dGhpcy5ndEV2ZW50LmVtaXQoe1xuXHRcdFx0bmFtZTogJ2d0LXJvdy1sZW5ndGgtY2hhbmdlZCcsXG5cdFx0XHR2YWx1ZTogbGVuZ3RoVmFsdWVcblx0XHR9KTtcblx0fTtcblxuXHQvKipcblx0ICogRm9yY2UgYSByZWRyYXcgb2YgdGFibGUgcm93cy5cblx0ICogQXMgdGhlIHRhYmxlIHVzZXMgcHVyZSBwaXBlcywgd2UgbmVlZCB0byBmb3JjZSBhIHJlZHJhdyBpZiBhbiBvYmplY3QgaW4gdGhlIGFycmF5IGlzIGNoYW5nZWQgdG8gc2VlIHRoZSBjaGFuZ2VzLlxuXHQgKi9cblx0cHVibGljIHJlZHJhdyA9IGZ1bmN0aW9uKCRldmVudD86IGFueSkge1xuXHRcdHRoaXMucmVmcmVzaFNvcnRpbmcgPSAhdGhpcy5yZWZyZXNoU29ydGluZztcblx0XHR0aGlzLnJlZnJlc2hQYWdlQXJyYXkgPSAhdGhpcy5yZWZyZXNoUGFnZUFycmF5O1xuXHRcdHRoaXMucmVmcmVzaFBpcGUgPSAhdGhpcy5yZWZyZXNoUGlwZTtcblx0fTtcblxuXHQvKiogVXBkYXRlIHJlY29yZCByYW5nZS4gKi9cblx0cHJpdmF0ZSB1cGRhdGVSZWNvcmRSYW5nZSgpIHtcblx0XHR0aGlzLmd0SW5mby5yZWNvcmRGcm9tID1cblx0XHRcdHRoaXMuZ3RJbmZvLnJlY29yZHNBZnRlclNlYXJjaCA9PT0gMFxuXHRcdFx0XHQ/IDBcblx0XHRcdFx0OiAodGhpcy5ndEluZm8ucGFnZUN1cnJlbnQgLSAxKSAqIHRoaXMuZ3RJbmZvLnJlY29yZExlbmd0aCArIDE7XG5cdFx0dGhpcy5ndEluZm8ucmVjb3JkVG8gPVxuXHRcdFx0dGhpcy5ndEluZm8ucmVjb3Jkc0FmdGVyU2VhcmNoIDxcblx0XHRcdHRoaXMuZ3RJbmZvLnBhZ2VDdXJyZW50ICogdGhpcy5ndEluZm8ucmVjb3JkTGVuZ3RoXG5cdFx0XHRcdD8gdGhpcy5ndEluZm8ucmVjb3Jkc0FmdGVyU2VhcmNoXG5cdFx0XHRcdDogdGhpcy5ndEluZm8ucGFnZUN1cnJlbnQgKiB0aGlzLmd0SW5mby5yZWNvcmRMZW5ndGg7XG5cdH1cblxuXHQvKiogVXBkYXRlIHRvdGFscy4gKi9cblx0cHJpdmF0ZSB1cGRhdGVUb3RhbHMoKSB7XG5cdFx0dGhpcy5yZWZyZXNoVG90YWxzID0gIXRoaXMucmVmcmVzaFRvdGFscztcblx0fVxuXG5cdC8qKiBHbyB0byBuZXh0IHBhZ2UuICovXG5cdHB1YmxpYyBuZXh0UGFnZSA9IGZ1bmN0aW9uKCkge1xuXHRcdGNvbnN0IHBhZ2UgPVxuXHRcdFx0dGhpcy5ndEluZm8ucGFnZUN1cnJlbnQgPT09IHRoaXMuZ3RJbmZvLnBhZ2VUb3RhbFxuXHRcdFx0XHQ/IHRoaXMuZ3RJbmZvLnBhZ2VUb3RhbFxuXHRcdFx0XHQ6IHRoaXMuZ3RJbmZvLnBhZ2VDdXJyZW50ICsgMTtcblx0XHR0aGlzLmdvVG9QYWdlKHBhZ2UpO1xuXHR9O1xuXG5cdC8qKiBHbyB0byBwcmV2aW91cyBwYWdlLiAqL1xuXHRwdWJsaWMgcHJldmlvdXNQYWdlID0gZnVuY3Rpb24oKSB7XG5cdFx0Y29uc3QgcGFnZSA9XG5cdFx0XHR0aGlzLmd0SW5mby5wYWdlQ3VycmVudCA9PT0gMSA/IDEgOiB0aGlzLmd0SW5mby5wYWdlQ3VycmVudCAtIDE7XG5cdFx0dGhpcy5nb1RvUGFnZShwYWdlKTtcblx0fTtcblxuXHQvKiogUmVxdWVzdCBtb3JlIGRhdGEgKHVzZWQgd2hlbiBsYXp5IGxvYWRpbmcpICovXG5cdHByaXZhdGUgZ2V0RGF0YSA9IGZ1bmN0aW9uKCkge1xuXHRcdC8vIC4uLmVtaXQgZXZlbnQgcmVxdWVzdGluZyBmb3IgbW9yZSBkYXRhXG5cdFx0dGhpcy5ndEV2ZW50LmVtaXQoe1xuXHRcdFx0bmFtZTogJ2d0LXBhZ2UtY2hhbmdlZC1sYXp5Jyxcblx0XHRcdHZhbHVlOiB7XG5cdFx0XHRcdHBhZ2VDdXJyZW50OiB0aGlzLmd0SW5mby5wYWdlQ3VycmVudCxcblx0XHRcdFx0cmVjb3JkTGVuZ3RoOiB0aGlzLmd0SW5mby5yZWNvcmRMZW5ndGhcblx0XHRcdH1cblx0XHR9KTtcblx0fTtcblxuXHQvKipcblx0ICogR28gdG8gc3BlY2lmaWMgcGFnZS5cblx0ICogQHBhcmFtIHBhZ2UgLSBwYWdlIG51bWJlci5cblx0ICovXG5cdHB1YmxpYyBnb1RvUGFnZSA9IGZ1bmN0aW9uKHBhZ2U6IG51bWJlcikge1xuXHRcdGNvbnN0IHByZXZpb3VzUGFnZSA9IHRoaXMuZ3RJbmZvLnBhZ2VDdXJyZW50O1xuXHRcdHRoaXMuZ3RJbmZvLnBhZ2VDdXJyZW50ID0gcGFnZTtcblx0XHR0aGlzLmlubGluZUVkaXRDYW5jZWwoKTsgLy8gY2FuY2VsIGlubGluZSBlZGl0XG5cblx0XHQvLyBpZiBsYXp5IGxvYWRpbmcgYW5kIGlmIHBhZ2UgY29udGFpbnMgbm8gcmVjb3Jkcy4uLlxuXHRcdGlmICh0aGlzLl9ndE9wdGlvbnMubGF6eUxvYWQpIHtcblx0XHRcdC8vIC4uLmlmIGRhdGEgZm9yIGN1cnJlbnQgcGFnZSBjb250YWlucyBubyBlbnRyaWVzLi4uXG5cdFx0XHRpZiAoXG5cdFx0XHRcdHRoaXMuX2d0T3B0aW9ucy5jYWNoZSA9PT0gZmFsc2UgfHxcblx0XHRcdFx0dGhpcy5fZ3REYXRhW3RoaXMuZ3RJbmZvLnBhZ2VDdXJyZW50IC0gMV0ubGVuZ3RoID09PSAwXG5cdFx0XHQpIHtcblx0XHRcdFx0Ly8gLi4uY3JlYXRlIHRlbXBvcmFyeSBjb250ZW50IHdoaWxlIHdhaXRpbmcgZm9yIGRhdGFcblx0XHRcdFx0dGhpcy5fZ3REYXRhW3RoaXMuZ3RJbmZvLnBhZ2VDdXJyZW50IC0gMV0gPSB0aGlzLmxvYWRpbmdDb250ZW50KFxuXHRcdFx0XHRcdHRoaXMuZ3RJbmZvLnJlY29yZExlbmd0aFxuXHRcdFx0XHQpO1xuXHRcdFx0XHR0aGlzLmxvYWRpbmcgPSB0cnVlOyAvLyBsb2FkaW5nIHRydWVcblx0XHRcdH1cblx0XHRcdC8vIC4uLmlmIGZpcnN0IGVudHJ5IGluIGN1cnJlbnQgcGFnZSBlcXVhbHMgb3VyIGxvYWRpbmcgcGxhY2Vob2xkZXIuLi5cblx0XHRcdGlmIChcblx0XHRcdFx0dGhpcy5fZ3REYXRhW3RoaXMuZ3RJbmZvLnBhZ2VDdXJyZW50IC0gMV1bMF1bdGhpcy5sb2FkaW5nUHJvcGVydHldID09PVxuXHRcdFx0XHR0aGlzLmd0VGV4dHMubG9hZGluZ1xuXHRcdFx0KSB7XG5cdFx0XHRcdC8vIC4uLmdldCBkYXRhXG5cdFx0XHRcdGNsZWFyVGltZW91dCh0aGlzLmRlYm91bmNlVGltZXIpO1xuXHRcdFx0XHR0aGlzLmRlYm91bmNlVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdFx0XHR0aGlzLmdldERhdGEoKTtcblx0XHRcdFx0fSwgdGhpcy5fZ3RPcHRpb25zLmRlYm91bmNlVGltZSk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gdGhpcy51cGRhdGVSZWNvcmRSYW5nZSgpO1xuXG5cdFx0Ly8gLi4uZW1pdCBwYWdlIGNoYW5nZSBldmVudFxuXHRcdGlmIChwcmV2aW91c1BhZ2UgIT09IHBhZ2UpIHtcblx0XHRcdHRoaXMuZ3RFdmVudC5lbWl0KHtcblx0XHRcdFx0bmFtZTogJ2d0LXBhZ2UtY2hhbmdlZCcsXG5cdFx0XHRcdHZhbHVlOiB7XG5cdFx0XHRcdFx0cGFnZUN1cnJlbnQ6IHRoaXMuZ3RJbmZvLnBhZ2VDdXJyZW50LFxuXHRcdFx0XHRcdHBhZ2VQcmV2aW91czogcHJldmlvdXNQYWdlLFxuXHRcdFx0XHRcdHJlY29yZExlbmd0aDogdGhpcy5ndEluZm8ucmVjb3JkTGVuZ3RoXG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH1cblx0fTtcblxuXHQvKipcblx0ICogR2V0IG1ldGEgZGF0YSBmb3Igcm93LlxuXHQgKi9cblx0cHVibGljIGdldFJvd1N0YXRlKHJvdzogUik6IEd0Um93TWV0YSB7XG5cdFx0cmV0dXJuIHR5cGVvZiB0aGlzLm1ldGFJbmZvW3Jvdy4kJGd0Um93SWRdID09PSAndW5kZWZpbmVkJ1xuXHRcdFx0PyBudWxsXG5cdFx0XHQ6IHRoaXMubWV0YUluZm9bcm93LiQkZ3RSb3dJZF07XG5cdH1cblxuXHQvKipcblx0ICogRXhwYW5kIGFsbCByb3dzLlxuXHQgKiBAcGFyYW0gZXhwYW5kZWRSb3cgLSBjb21wb25lbnQgdG8gcmVuZGVyIHdoZW4gcm93cyBhcmUgZXhwYW5kZWQuXG5cdCAqL1xuXHRwdWJsaWMgZXhwYW5kQWxsUm93cyhleHBhbmRlZFJvdzogeyBjb21wb25lbnQ6IFR5cGU8Qz47IGRhdGE/OiBhbnkgfSk6IHZvaWQge1xuXHRcdHRoaXMuZXhwYW5kZWRSb3cgPSBleHBhbmRlZFJvdztcblx0XHR0aGlzLl90b2dnbGVBbGxSb3dQcm9wZXJ0eSgnaXNPcGVuJywgdHJ1ZSk7XG5cdH1cblxuXHQvKipcblx0ICogQ29sbGFwc2UgYWxsIHJvd3MuXG5cdCAqL1xuXHRwdWJsaWMgY29sbGFwc2VBbGxSb3dzKCk6IHZvaWQge1xuXHRcdHRoaXMuX3RvZ2dsZUFsbFJvd1Byb3BlcnR5KCdpc09wZW4nLCBmYWxzZSk7XG5cdH1cblxuXHQvKipcblx0ICogU2VsZWN0IGFsbCByb3dzLlxuXHQgKi9cblx0cHVibGljIHNlbGVjdEFsbFJvd3MoKTogdm9pZCB7XG5cdFx0dGhpcy5fdG9nZ2xlQWxsUm93UHJvcGVydHkoJ2lzU2VsZWN0ZWQnLCB0cnVlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBEZXNlbGVjdCBhbGwgcm93cy5cblx0ICovXG5cdHB1YmxpYyBkZXNlbGVjdEFsbFJvd3MoKTogdm9pZCB7XG5cdFx0dGhpcy5fdG9nZ2xlQWxsUm93UHJvcGVydHkoJ2lzU2VsZWN0ZWQnLCBmYWxzZSk7XG5cdH1cblx0LyoqXG5cdCAqIFRvZ2dsZSBhbGwgcm93cy5cblx0ICovXG5cdHB1YmxpYyB0b2dnbGVBbGxSb3dzKCk6IHZvaWQge1xuXHRcdGlmICh0aGlzLl9ndE9wdGlvbnMubGF6eUxvYWQpIHtcblx0XHRcdGlmICghdGhpcy5sYXp5QWxsU2VsZWN0ZWQgfHwgdGhpcy5zZWxlY3RlZFJvd3MubGVuZ3RoID09PSAwKSB7XG5cdFx0XHRcdHRoaXMuc2VsZWN0QWxsUm93cygpO1xuXHRcdFx0XHR0aGlzLmxhenlBbGxTZWxlY3RlZCA9IHRydWU7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLmRlc2VsZWN0QWxsUm93cygpO1xuXHRcdFx0XHR0aGlzLmxhenlBbGxTZWxlY3RlZCA9IGZhbHNlO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZiAodGhpcy5zZWxlY3RlZFJvd3MubGVuZ3RoICE9PSB0aGlzLmd0RGF0YS5sZW5ndGgpIHtcblx0XHRcdFx0dGhpcy5zZWxlY3RBbGxSb3dzKCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLmRlc2VsZWN0QWxsUm93cygpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBUb2dnbGUgcm93IGNvbGxhcHNlZCBzdGF0ZSBpZS4gZXhwYW5kZWQvb3BlbiBvciBjb2xsYXBzZWQvY2xvc2VkLlxuXHQgKiBAcGFyYW0gcm93IC0gcm93IG9iamVjdCB0aGF0IHNob3VsZCBiZSBleHBhbmRlZC9jb2xsYXBzZWQuXG5cdCAqIEBwYXJhbSBleHBhbmRlZFJvdyAtIGNvbXBvbmVudCB0byByZW5kZXIgd2hlbiByb3cgaXMgZXhwYW5kZWQuXG5cdCAqL1xuXHRwdWJsaWMgdG9nZ2xlQ29sbGFwc2UoXG5cdFx0cm93OiBHdFJvdyxcblx0XHRleHBhbmRlZFJvdz86IHsgY29tcG9uZW50OiBUeXBlPEM+OyBkYXRhPzogYW55IH1cblx0KSB7XG5cdFx0aWYgKGV4cGFuZGVkUm93KSB7XG5cdFx0XHR0aGlzLmV4cGFuZGVkUm93ID0gZXhwYW5kZWRSb3c7XG5cdFx0fVxuXHRcdHRoaXMuX3RvZ2dsZVJvd1Byb3BlcnR5KHJvdywgJ2lzT3BlbicpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFRvZ2dsZSByb3cgc2VsZWN0ZWQgc3RhdGUgaWUuIHNlbGVjdGVkIG9yIG5vdC5cblx0ICogQHBhcmFtIHJvdyAtIHJvdyBvYmplY3QgdGhhdCBzaG91bGQgYmUgc2VsZWN0ZWQvZGVzZWxlY3RlZC5cblx0ICovXG5cdHB1YmxpYyB0b2dnbGVTZWxlY3Qocm93OiBHdFJvdykge1xuXHRcdHRoaXMuX3RvZ2dsZVJvd1Byb3BlcnR5KHJvdywgJ2lzU2VsZWN0ZWQnKTtcblx0fVxuXG5cdHB1YmxpYyByb3dDbGljayhyb3c6IEd0Um93LCAkZXZlbnQ6IE1vdXNlRXZlbnQpIHtcblx0XHR0aGlzLmd0RXZlbnQuZW1pdCh7XG5cdFx0XHRuYW1lOiAnZ3Qtcm93LWNsaWNrZWQnLFxuXHRcdFx0dmFsdWU6IHsgcm93OiByb3csIGV2ZW50OiAkZXZlbnQgfVxuXHRcdH0pO1xuXHR9XG5cblx0LyoqXG5cdCAqIFVwZGF0ZSByb3cgZGF0YS5cblx0ICogQHBhcmFtIHJvdyAtIHJvdyBvYmplY3QgdGhhdCBoYXMgYmVlbiBlZGl0ZWQuXG5cdCAqIEBwYXJhbSBvbGRWYWx1ZSAtIHJvdyBvYmplY3QgYmVmb3JlIGVkaXQuXG5cdCAqL1xuXHRwdWJsaWMgdXBkYXRlUm93KHJvdzogR3RSb3csIG9sZFZhbHVlOiBHdFJvdykge1xuXHRcdHRoaXMuX3RvZ2dsZVJvd1Byb3BlcnR5KHJvdywgJ2lzVXBkYXRlZCcsIG9sZFZhbHVlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiByZW1vdmVzIGEgcm93IGZyb20gdGhlIHRhYmxlXG5cdCAqIEBwYXJhbSByb3cgLSB0aGUgcm93IG9iamVjdCB0byByZW1vdmVcblx0ICovXG5cdHB1YmxpYyByZW1vdmVSb3cocm93OiBHdFJvdykge1xuXHRcdGlmICh0aGlzLmlzUm93U2VsZWN0ZWQocm93KSkge1xuXHRcdFx0dGhpcy50b2dnbGVTZWxlY3Qocm93KTtcblx0XHR9XG5cdFx0Y29uc3QgaW5kZXggPSB0aGlzLl9ndERhdGEuaW5kZXhPZihyb3cpO1xuXHRcdHRoaXMuX2d0RGF0YS5zcGxpY2UoaW5kZXgsIDEpO1xuXHR9XG5cblx0LyoqXG5cdCAqIGNoZWNrIGlmIGEgcm93IGlzIHNlbGVjdGVkXG5cdCAqIEBwYXJhbSByb3cgLSByb3cgb2JqZWN0XG5cdCAqL1xuXHRwdWJsaWMgaXNSb3dTZWxlY3RlZChyb3c6IEd0Um93KTogYm9vbGVhbiB7XG5cdFx0cmV0dXJuIChcblx0XHRcdHRoaXMubWV0YUluZm9bcm93LiQkZ3RSb3dJZF0gJiYgdGhpcy5tZXRhSW5mb1tyb3cuJCRndFJvd0lkXS5pc1NlbGVjdGVkXG5cdFx0KTtcblx0fVxuXG5cdC8qKlxuXHQgKiBVcGRhdGUgbWV0YSBpbmZvIGZvciBhbGwgcm93cywgaWUuIGlzU2VsZWN0ZWQsIGlzT3Blbi5cblx0ICogQHBhcmFtIGFycmF5IC0gYXJyYXkgdGhhdCBob2xkcyByb3dzIHRoYXQgbmVlZCB0byBiZSB1cGRhdGVkLlxuXHQgKiBAcGFyYW0gcHJvcGVydHkgLSBuYW1lIG9mIHByb3BlcnR5IHRoYXQgc2hvdWxkIGJlIGNoYW5nZWQvdG9nZ2xlZC5cblx0ICogQHBhcmFtIGFjdGl2ZSAtIHNob3VsZCByb3dzIGJlIGV4cGFuZGVkL29wZW4sIHNlbGVjdGVkLlxuXHQgKiBAcGFyYW0gZXhjZXB0aW9uIC0gdXBkYXRlIGFsbCByb3dzIGV4Y2VwdCB0aGlzIG9uZS5cblx0ICovXG5cdHByaXZhdGUgX3VwZGF0ZU1ldGFJbmZvKFxuXHRcdGFycmF5OiBBcnJheTxHdFJvdz4sXG5cdFx0cHJvcGVydHk6IHN0cmluZyxcblx0XHRhY3RpdmU6IGJvb2xlYW4sXG5cdFx0ZXhjZXB0aW9uPzogR3RSb3dcblx0KSB7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKCF0aGlzLm1ldGFJbmZvW2FycmF5W2ldLiQkZ3RSb3dJZF0pIHtcblx0XHRcdFx0dGhpcy5tZXRhSW5mb1thcnJheVtpXS4kJGd0Um93SWRdID0ge307XG5cdFx0XHR9XG5cdFx0XHRpZiAoZXhjZXB0aW9uICYmIGFycmF5W2ldLiQkZ3RSb3dJZCA9PT0gZXhjZXB0aW9uLiQkZ3RSb3dJZCkge1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dGhpcy5tZXRhSW5mb1thcnJheVtpXS4kJGd0Um93SWRdW3Byb3BlcnR5XSA9IGFjdGl2ZTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogUHVzaCBzZWxlY3RlZC9leHBhbmRlZCBsYXp5IGxvYWRlZCByb3dzIHRvIGFycmF5IHdpdGggbWV0YSBkYXRhLlxuXHQgKiBAcGFyYW0gdGFyZ2V0IC0gYXJyYXkgdG8gd2hpY2ggcm93cyBzaG91bGQgYmUgYWRkZWQuXG5cdCAqIEBwYXJhbSBzb3VyY2UgLSBhcnJheSB0aGF0IGhvbGRzIHJvd3MgdGhhdCBzaG91bGQgYmUgYWRkZWQuXG5cdCAqIEByZXR1cm5zIGFycmF5IHdpdGggYWRkZWQgcm93cy5cblx0ICovXG5cdHByaXZhdGUgX3B1c2hMYXp5Um93cyhcblx0XHR0YXJnZXQ6IEFycmF5PEd0Um93Pixcblx0XHRzb3VyY2U6IEFycmF5PEd0Um93PlxuXHQpOiBBcnJheTxHdFJvdz4ge1xuXHRcdGNvbnN0IFVOSVFVRV9ST1dTID0gdGFyZ2V0Lm1hcChyb3cgPT4gcm93LiQkZ3RSb3dJZCk7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBzb3VyY2UubGVuZ3RoOyBpKyspIHtcblx0XHRcdC8vIG9ubHkgYWRkIGlmIG5vdCBhbHJlYWR5IGluIGxpc3Rcblx0XHRcdGlmIChVTklRVUVfUk9XUy5pbmRleE9mKHNvdXJjZVtpXS4kJGd0Um93SWQpID09PSAtMSkge1xuXHRcdFx0XHR0YXJnZXQucHVzaChzb3VyY2VbaV0pO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gdGFyZ2V0O1xuXHR9XG5cblx0LyoqXG5cdCAqIFRvZ2dsZSBtZXRhIGluZm8gZm9yIGFsbCByb3dzLCBpZS4gaXNTZWxlY3RlZCwgaXNPcGVuLlxuXHQgKiBAcGFyYW0gcHJvcGVydHkgLSBuYW1lIG9mIHByb3BlcnR5IHRoYXQgc2hvdWxkIGJlIGNoYW5nZWQvdG9nZ2xlZC5cblx0ICogQHBhcmFtIGFjdGl2ZSAtIHNob3VsZCByb3dzIGJlIGV4cGFuZGVkL29wZW4sIHNlbGVjdGVkLlxuXHQgKi9cblx0cHJpdmF0ZSBfdG9nZ2xlQWxsUm93UHJvcGVydHkocHJvcGVydHk6IHN0cmluZywgYWN0aXZlOiBib29sZWFuKSB7XG5cdFx0bGV0IGV2ZW50TmFtZTogc3RyaW5nO1xuXHRcdGxldCBldmVudFZhbHVlOiBhbnk7XG5cdFx0c3dpdGNoIChwcm9wZXJ0eSkge1xuXHRcdFx0Y2FzZSAnaXNPcGVuJzpcblx0XHRcdFx0Ly8gY2hlY2sgaWYgbXVsdGlwbGUgZXhwYW5kZWQgcm93cyBhcmUgYWxsb3dlZC4uLlxuXHRcdFx0XHRpZiAodGhpcy5fZ3RPcHRpb25zLnJvd0V4cGFuZEFsbG93TXVsdGlwbGUgPT09IGZhbHNlKSB7XG5cdFx0XHRcdFx0Ly8gLi4uaWYgbm90LCBleGl0IGZ1bmN0aW9uXG5cdFx0XHRcdFx0Y29uc29sZS5sb2coXG5cdFx0XHRcdFx0XHQnZmVhdHVyZSBkaXNhYmxlZDogZW5hYmxlIGJ5IHNldHRpbmcgXCJyb3dFeHBhbmRBbGxvd011bHRpcGxlID0gdHJ1ZVwiJ1xuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmIChhY3RpdmUpIHtcblx0XHRcdFx0XHRldmVudE5hbWUgPSAnZXhwYW5kLWFsbCc7XG5cdFx0XHRcdFx0dGhpcy5vcGVuUm93cyA9IHRoaXMuX2d0T3B0aW9ucy5sYXp5TG9hZFxuXHRcdFx0XHRcdFx0PyB0aGlzLl9wdXNoTGF6eVJvd3MoXG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5vcGVuUm93cyxcblx0XHRcdFx0XHRcdFx0XHR0aGlzLl9ndERhdGFbdGhpcy5ndEluZm8ucGFnZUN1cnJlbnQgLSAxXS5zbGljZSgpXG5cdFx0XHRcdFx0XHQgIClcblx0XHRcdFx0XHRcdDogdGhpcy5fZ3REYXRhLnNsaWNlKCk7XG5cdFx0XHRcdFx0dGhpcy5fdXBkYXRlTWV0YUluZm8odGhpcy5vcGVuUm93cywgcHJvcGVydHksIGFjdGl2ZSk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0ZXZlbnROYW1lID0gJ2NvbGxhcHNlLWFsbCc7XG5cdFx0XHRcdFx0dGhpcy5fdXBkYXRlTWV0YUluZm8odGhpcy5vcGVuUm93cywgcHJvcGVydHksIGFjdGl2ZSk7XG5cdFx0XHRcdFx0dGhpcy5vcGVuUm93cyA9IFtdO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGV2ZW50VmFsdWUgPSB7XG5cdFx0XHRcdFx0ZXhwYW5kZWRSb3dzOiB0aGlzLm9wZW5Sb3dzLFxuXHRcdFx0XHRcdGNoYW5nZWRSb3c6ICdhbGwnXG5cdFx0XHRcdH07XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnaXNTZWxlY3RlZCc6XG5cdFx0XHRcdC8vIGNoZWNrIGlmIG11bHRpIHJvdyBzZWxlY3Rpb24gaXMgYWxsb3dlZC4uLlxuXHRcdFx0XHRpZiAodGhpcy5fZ3RPcHRpb25zLnJvd1NlbGVjdGlvbkFsbG93TXVsdGlwbGUgPT09IGZhbHNlKSB7XG5cdFx0XHRcdFx0Ly8gLi4uaWYgbm90LCBleGl0IGZ1bmN0aW9uXG5cdFx0XHRcdFx0Y29uc29sZS5sb2coXG5cdFx0XHRcdFx0XHQnZmVhdHVyZSBkaXNhYmxlZDogZW5hYmxlIGJ5IHNldHRpbmcgXCJyb3dTZWxlY3Rpb25BbGxvd011bHRpcGxlID0gdHJ1ZVwiJ1xuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmIChhY3RpdmUpIHtcblx0XHRcdFx0XHRldmVudE5hbWUgPSAnc2VsZWN0LWFsbCc7XG5cdFx0XHRcdFx0dGhpcy5zZWxlY3RlZFJvd3MgPSB0aGlzLl9ndE9wdGlvbnMubGF6eUxvYWRcblx0XHRcdFx0XHRcdD8gdGhpcy5fcHVzaExhenlSb3dzKFxuXHRcdFx0XHRcdFx0XHRcdHRoaXMuc2VsZWN0ZWRSb3dzLFxuXHRcdFx0XHRcdFx0XHRcdHRoaXMuX2d0RGF0YVt0aGlzLmd0SW5mby5wYWdlQ3VycmVudCAtIDFdLnNsaWNlKClcblx0XHRcdFx0XHRcdCAgKVxuXHRcdFx0XHRcdFx0OiB0aGlzLl9ndERhdGEuc2xpY2UoKTtcblx0XHRcdFx0XHR0aGlzLl91cGRhdGVNZXRhSW5mbyh0aGlzLnNlbGVjdGVkUm93cywgcHJvcGVydHksIGFjdGl2ZSk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0ZXZlbnROYW1lID0gJ2Rlc2VsZWN0LWFsbCc7XG5cdFx0XHRcdFx0dGhpcy5fdXBkYXRlTWV0YUluZm8odGhpcy5zZWxlY3RlZFJvd3MsIHByb3BlcnR5LCBhY3RpdmUpO1xuXHRcdFx0XHRcdHRoaXMuc2VsZWN0ZWRSb3dzID0gW107XG5cdFx0XHRcdH1cblx0XHRcdFx0ZXZlbnRWYWx1ZSA9IHtcblx0XHRcdFx0XHRzZWxlY3RlZFJvd3M6IHRoaXMuc2VsZWN0ZWRSb3dzLFxuXHRcdFx0XHRcdGNoYW5nZWRSb3c6ICdhbGwnXG5cdFx0XHRcdH07XG5cblx0XHRcdFx0YnJlYWs7XG5cdFx0fVxuXHRcdHRoaXMuZ3RFdmVudC5lbWl0KHtcblx0XHRcdG5hbWU6ICdndC1yb3ctJyArIGV2ZW50TmFtZSxcblx0XHRcdHZhbHVlOiBldmVudFZhbHVlXG5cdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogVG9nZ2xlIG1ldGEgaW5mbyBmb3Igcm93LCBpZS4gaXNTZWxlY3RlZCwgaXNPcGVuLlxuXHQgKiBAcGFyYW0gcm93IC0gcm93IG9iamVjdC5cblx0ICogQHBhcmFtIHByb3BlcnR5IC0gbmFtZSBvZiBwcm9wZXJ0eSB0aGF0IHNob3VsZCBiZSBjaGFuZ2VkL3RvZ2dsZWQuXG5cdCAqIEBwYXJhbSBwcm9wZXJ0eVZhbHVlcyAtIG9wdGlvbmFsIHByb3BlcnR5IHZhbHVlcyB0aGF0IGNhbiBiZSBwYXNzZWQuXG5cdCAqL1xuXHRwcml2YXRlIF90b2dnbGVSb3dQcm9wZXJ0eShcblx0XHRyb3c6IEd0Um93LFxuXHRcdHByb3BlcnR5OiBzdHJpbmcsXG5cdFx0cHJvcGVydHlWYWx1ZXM/OiBhbnlcblx0KSB7XG5cdFx0bGV0IGV2ZW50TmFtZTogc3RyaW5nO1xuXHRcdGxldCBldmVudFZhbHVlOiBhbnk7XG5cdFx0Ly8gbWFrZSBzdXJlIGd0Um93SWQgZXhpc3RzIG9uIHJvdyBvYmplY3Rcblx0XHRpZiAodHlwZW9mIHJvdy4kJGd0Um93SWQgIT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHQvLyBjaGVjayBpZiBtZXRhIGluZm8gZXhpc3RzIGZvciByb3dcblx0XHRcdGlmICghdGhpcy5tZXRhSW5mb1tyb3cuJCRndFJvd0lkXSkge1xuXHRcdFx0XHQvLyBpZiBub3QsIGFkZCBvYmplY3QgdG8gc3RvcmUgbWV0YSBpbmZvXG5cdFx0XHRcdHRoaXMubWV0YUluZm9bcm93LiQkZ3RSb3dJZF0gPSB7fTtcblx0XHRcdH1cblxuXHRcdFx0c3dpdGNoIChwcm9wZXJ0eSkge1xuXHRcdFx0XHRjYXNlICdpc09wZW4nOlxuXHRcdFx0XHRcdGNvbnN0IG9wZW5lZCA9IHRoaXMubWV0YUluZm9bcm93LiQkZ3RSb3dJZF1bcHJvcGVydHldO1xuXG5cdFx0XHRcdFx0Ly8gY2hlY2sgaWYgbXVsdGlwbGUgZXhwYW5kZWQgcm93cyBhcmUgYWxsb3dlZC4uLlxuXHRcdFx0XHRcdGlmICh0aGlzLl9ndE9wdGlvbnMucm93RXhwYW5kQWxsb3dNdWx0aXBsZSA9PT0gZmFsc2UpIHtcblx0XHRcdFx0XHRcdC8vIC4uLmlmIG5vdCwgY29sbGFwc2UgYWxsIHJvd3MgZXhjZXB0IGN1cnJlbnQgcm93XG5cdFx0XHRcdFx0XHR0aGlzLl91cGRhdGVNZXRhSW5mbyh0aGlzLm9wZW5Sb3dzLCBwcm9wZXJ0eSwgZmFsc2UsIHJvdyk7XG5cdFx0XHRcdFx0XHR0aGlzLm9wZW5Sb3dzID0gW107XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gY2hlY2sgaWYgcm93IGlzIGV4cGFuZGVkXG5cdFx0XHRcdFx0aWYgKCFvcGVuZWQpIHtcblx0XHRcdFx0XHRcdGV2ZW50TmFtZSA9ICdleHBhbmQnO1xuXHRcdFx0XHRcdFx0Ly8gYWRkIHJvdyB0byBleHBhbmRlZCByb3dzXG5cdFx0XHRcdFx0XHR0aGlzLm9wZW5Sb3dzLnB1c2gocm93KTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0ZXZlbnROYW1lID0gJ2NvbGxhcHNlJztcblx0XHRcdFx0XHRcdC8vIGxvb3AgdGhyb3VnaCBleHBhbmRlZCByb3dzLi4uXG5cdFx0XHRcdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMub3BlblJvd3MubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0XHRcdFx0Ly8gaWYgZXhwYW5kZWQgcm93IGVxdWFscyBwYXNzZWQgcm93Li4uXG5cdFx0XHRcdFx0XHRcdGlmICh0aGlzLm9wZW5Sb3dzW2ldLiQkZ3RSb3dJZCA9PT0gcm93LiQkZ3RSb3dJZCkge1xuXHRcdFx0XHRcdFx0XHRcdC8vIC4uLnJlbW92ZSByb3cgZnJvbSBleHBhbmRlZCByb3dzLi4uXG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5vcGVuUm93cy5zcGxpY2UoaSwgMSk7XG5cblx0XHRcdFx0XHRcdFx0XHQvLyAuLi5hbmQgZXhpdCBsb29wXG5cdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0ZXZlbnRWYWx1ZSA9IHtcblx0XHRcdFx0XHRcdGV4cGFuZGVkUm93czogdGhpcy5vcGVuUm93cyxcblx0XHRcdFx0XHRcdGNoYW5nZWRSb3c6IHJvd1xuXHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdGNhc2UgJ2lzU2VsZWN0ZWQnOlxuXHRcdFx0XHRcdGNvbnN0IHNlbGVjdGVkID0gdGhpcy5tZXRhSW5mb1tyb3cuJCRndFJvd0lkXVtwcm9wZXJ0eV07XG5cblx0XHRcdFx0XHQvLyBjaGVjayBpZiBtdWx0aSByb3cgc2VsZWN0aW9uIGlzIGFsbG93ZWQuLi5cblx0XHRcdFx0XHRpZiAodGhpcy5fZ3RPcHRpb25zLnJvd1NlbGVjdGlvbkFsbG93TXVsdGlwbGUgPT09IGZhbHNlKSB7XG5cdFx0XHRcdFx0XHQvLyAuLi5pZiBub3QsIGRlc2VsZWN0IGFsbCByb3dzIGV4Y2VwdCBjdXJyZW50IHJvd1xuXHRcdFx0XHRcdFx0dGhpcy5fdXBkYXRlTWV0YUluZm8odGhpcy5zZWxlY3RlZFJvd3MsIHByb3BlcnR5LCBmYWxzZSwgcm93KTtcblx0XHRcdFx0XHRcdHRoaXMuc2VsZWN0ZWRSb3dzID0gW107XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gY2hlY2sgaWYgcm93IGlzIHNlbGVjdGVkXG5cdFx0XHRcdFx0aWYgKCFzZWxlY3RlZCkge1xuXHRcdFx0XHRcdFx0ZXZlbnROYW1lID0gJ3NlbGVjdCc7XG5cdFx0XHRcdFx0XHQvLyBhZGQgcm93IHRvIHNlbGVjdGVkIHJvd3Ncblx0XHRcdFx0XHRcdHRoaXMuc2VsZWN0ZWRSb3dzLnB1c2gocm93KTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0aWYgKHRoaXMuZ3RPcHRpb25zLmxhenlMb2FkICYmIHRoaXMubGF6eUFsbFNlbGVjdGVkKSB7XG5cdFx0XHRcdFx0XHRcdHRoaXMubGF6eUFsbFNlbGVjdGVkID0gZmFsc2U7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRldmVudE5hbWUgPSAnZGVzZWxlY3QnO1xuXHRcdFx0XHRcdFx0Ly8gbG9vcCB0aHJvdWdoIHNlbGVjdGVkIHJvd3MuLi5cblx0XHRcdFx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5zZWxlY3RlZFJvd3MubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0XHRcdFx0Ly8gaWYgc2VsZWN0ZWQgcm93IGVxdWFscyBwYXNzZWQgcm93Li4uXG5cdFx0XHRcdFx0XHRcdGlmICh0aGlzLnNlbGVjdGVkUm93c1tpXS4kJGd0Um93SWQgPT09IHJvdy4kJGd0Um93SWQpIHtcblx0XHRcdFx0XHRcdFx0XHQvLyAuLi5yZW1vdmUgcm93IGZyb20gc2VsZWN0ZWQgcm93cy4uLlxuXHRcdFx0XHRcdFx0XHRcdHRoaXMuc2VsZWN0ZWRSb3dzLnNwbGljZShpLCAxKTtcblxuXHRcdFx0XHRcdFx0XHRcdC8vIC4uLmFuZCBleGl0IGxvb3Bcblx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRldmVudFZhbHVlID0ge1xuXHRcdFx0XHRcdFx0c2VsZWN0ZWRSb3dzOiB0aGlzLnNlbGVjdGVkUm93cyxcblx0XHRcdFx0XHRcdGNoYW5nZWRSb3c6IHJvd1xuXHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0YnJlYWs7XG5cblx0XHRcdFx0Y2FzZSAnaXNVcGRhdGVkJzpcblx0XHRcdFx0XHRldmVudE5hbWUgPSAndXBkYXRlZCc7XG5cdFx0XHRcdFx0Y29uc3Qgb2xkVmFsdWUgPSBwcm9wZXJ0eVZhbHVlcztcblx0XHRcdFx0XHQvLyBjaGVjayBpZiBlZGl0IG9iamVjdCBleGlzdHMgZm9yIHJvd1xuXHRcdFx0XHRcdGlmICh0eXBlb2YgdGhpcy5tZXRhSW5mb1tyb3cuJCRndFJvd0lkXVtwcm9wZXJ0eV0gPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRcdFx0XHR0aGlzLm1ldGFJbmZvW3Jvdy4kJGd0Um93SWRdW3Byb3BlcnR5XSA9IHtcblx0XHRcdFx0XHRcdFx0b3JpZ2luYWxWYWx1ZTogb2xkVmFsdWUsXG5cdFx0XHRcdFx0XHRcdG9sZFZhbHVlOiBvbGRWYWx1ZSxcblx0XHRcdFx0XHRcdFx0bmV3VmFsdWU6IHJvd1xuXHRcdFx0XHRcdFx0fTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0dGhpcy5tZXRhSW5mb1tyb3cuJCRndFJvd0lkXVtwcm9wZXJ0eV0ub2xkVmFsdWUgPSBvbGRWYWx1ZTtcblx0XHRcdFx0XHRcdHRoaXMubWV0YUluZm9bcm93LiQkZ3RSb3dJZF1bcHJvcGVydHldLm5ld1ZhbHVlID0gcm93O1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRldmVudFZhbHVlID0gdGhpcy5tZXRhSW5mb1tyb3cuJCRndFJvd0lkXVtwcm9wZXJ0eV07XG5cdFx0XHRcdFx0dGhpcy5yZWRyYXcoKTtcblx0XHRcdFx0XHR0aGlzLmlubGluZUVkaXRDYW5jZWwocm93KTtcblx0XHRcdFx0XHQvLyB0aGlzLmd0RGF0YSA9IFsuLi50aGlzLmd0RGF0YS5tYXAoKHIpID0+IHsgcmV0dXJuey4uLnJ9OyB9KV07XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLmd0RXZlbnQuZW1pdCh7XG5cdFx0XHRcdG5hbWU6ICdndC1yb3ctJyArIGV2ZW50TmFtZSxcblx0XHRcdFx0dmFsdWU6IGV2ZW50VmFsdWVcblx0XHRcdH0pO1xuXHRcdFx0aWYgKHByb3BlcnR5ICE9PSAnaXNVcGRhdGVkJykge1xuXHRcdFx0XHR0aGlzLm1ldGFJbmZvW3Jvdy4kJGd0Um93SWRdW3Byb3BlcnR5XSA9ICF0aGlzLm1ldGFJbmZvW3Jvdy4kJGd0Um93SWRdW1xuXHRcdFx0XHRcdHByb3BlcnR5XG5cdFx0XHRcdF07XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFVwZGF0ZSBjb2x1bW4uXG5cdCAqIEBwYXJhbSAkZXZlbnQgLSBrZXkgdXAgZXZlbnQuXG5cdCAqIEBwYXJhbSByb3cgLSByb3cgb2JqZWN0LlxuXHQgKiBAcGFyYW0gY29sdW1uIC0gY29sdW1uIG9iamVjdC5cblx0ICovXG5cdHB1YmxpYyBndFVwZGF0ZUNvbHVtbihcblx0XHQkZXZlbnQ6IEtleWJvYXJkRXZlbnQsXG5cdFx0cm93OiBHdFJvdyxcblx0XHRjb2x1bW46IEd0UmVuZGVyRmllbGQ8YW55LCBhbnk+XG5cdCkge1xuXHRcdHRoaXMuX2VkaXRSb3cocm93LCBjb2x1bW4pO1xuXHR9XG5cblx0LyoqXG5cdCAqIERyb3Bkb3duIHNlbGVjdC5cblx0ICogQHBhcmFtIHJvdyAtIHJvdyBvYmplY3QuXG5cdCAqIEBwYXJhbSBjb2x1bW4gLSBjb2x1bW4gb2JqZWN0LlxuXHQgKi9cblx0cHVibGljIGd0RHJvcGRvd25TZWxlY3Qocm93OiBHdFJvdywgY29sdW1uOiBHdFJlbmRlckZpZWxkPGFueSwgYW55Pikge1xuXHRcdGNvbnN0IG9sZFZhbHVlID0geyAuLi5yb3cgfTtcblx0XHRyb3dbY29sdW1uLm9iamVjdEtleV0gPSBjb2x1bW4ucmVuZGVyVmFsdWU7XG5cdFx0dGhpcy51cGRhdGVSb3cocm93LCBvbGRWYWx1ZSk7XG5cdH1cblxuXHRwcml2YXRlIF9lZGl0Um93KHJvdzogR3RSb3csIGNvbHVtbjogR3RSZW5kZXJGaWVsZDxhbnksIGFueT4pIHtcblx0XHRjb25zdCBPQkpFQ1RfS0VZID0gY29sdW1uLm9iamVjdEtleTsgLy8gZGVjbGFyZSBvYmplY3Qga2V5IHdoaWNoIGNvbnRhaW5zIGNoYW5nZXNcblxuXHRcdC8vIGNoZWNrIGlmIGNlbGwgaGFzIGNoYW5nZWQgdmFsdWVcblx0XHRjb2x1bW4uZWRpdGVkID0gcm93W2NvbHVtbi5vYmplY3RLZXldICE9PSBjb2x1bW4ucmVuZGVyVmFsdWU7XG5cdFx0Ly8gY2hlY2sgaWYgcm93IGNvbnRhaW5zIGNoYW5nZXMuLi5cblx0XHRpZiAoIXRoaXMuZWRpdGVkUm93c1tyb3cuJCRndFJvd0lkXSkge1xuXHRcdFx0Ly8gaWYgbm90LCBjcmVhdGUgYW4gb2JqZWN0IGZvciB0aGUgY2hhbmdlZCByb3dcblx0XHRcdHRoaXMuZWRpdGVkUm93c1tyb3cuJCRndFJvd0lkXSA9IHtcblx0XHRcdFx0Y2hhbmdlczoge30sIC8vIGNyZWF0ZSBwbGFjZWhvbGRlciBmb3IgY2hhbmdlc1xuXHRcdFx0XHRyb3c6IHJvdyAvLyBzdG9yZSByZWZlcmVuY2UgdG8gdGhlIHJvdyB0aGF0IHNob3VsZCBiZSB1cGRhdGVkXG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdC8vIHN0b3JlIGNoYW5nZWQgY29sdW1uIHVuZGVyIGNoYW5nZXMgaWYgaXQgaGFzIGJlZW4gZWRpdGVkXG5cdFx0aWYgKGNvbHVtbi5lZGl0ZWQpIHtcblx0XHRcdHRoaXMuZWRpdGVkUm93c1tyb3cuJCRndFJvd0lkXS5jaGFuZ2VzW09CSkVDVF9LRVldID0gY29sdW1uO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBkZWxldGUgY2hhbmdlIG9iamVjdCBpZiBjb2x1bW4gaXMgdW5jaGFuZ2VkXG5cdFx0XHRkZWxldGUgdGhpcy5lZGl0ZWRSb3dzW3Jvdy4kJGd0Um93SWRdLmNoYW5nZXNbT0JKRUNUX0tFWV07XG5cdFx0XHQvLyBjaGVjayBob3cgbWFueSBjb2x1bW5zIGhhdmUgYmVlbiBjaGFuZ2VkXG5cdFx0XHRjb25zdCBDSEFOR0VEX0NPTFVNTlMgPSBPYmplY3Qua2V5cyhcblx0XHRcdFx0dGhpcy5lZGl0ZWRSb3dzW3Jvdy4kJGd0Um93SWRdLmNoYW5nZXNcblx0XHRcdCkubGVuZ3RoO1xuXHRcdFx0aWYgKENIQU5HRURfQ09MVU1OUyA9PT0gMCkge1xuXHRcdFx0XHQvLyBkZWxldGUgcm93IGZyb20gZWRpdGVkIHJvd3MgaWYgbm8gY29sdW1ucyBoYXZlIGJlZW4gZWRpdGVkXG5cdFx0XHRcdGRlbGV0ZSB0aGlzLmVkaXRlZFJvd3Nbcm93LiQkZ3RSb3dJZF07XG5cdFx0XHR9XG5cdFx0fVxuXHRcdC8vIGlmIG5vIGxpc3RlbmVyIGlzIHByZXNlbnQuLi5cblx0XHRpZiAoIXRoaXMuZ2xvYmFsSW5saW5lRWRpdExpc3RlbmVyKSB7XG5cdFx0XHQvLyAuLi5saXN0ZW4gZm9yIHVwZGF0ZSBldmVudFxuXHRcdFx0dGhpcy5fbGlzdGVuRm9yS2V5ZG93bkV2ZW50KCk7XG5cdFx0fVxuXHR9XG5cdC8qKlxuXHQgKiBMaXN0ZW4gZm9yIGtleSBkb3duIGV2ZW50IC0gbGlzdGVuIGZvciBrZXkgZG93biBldmVudCBkdXJpbmcgaW5saW5lIGVkaXQuXG5cdCAqL1xuXHRwcml2YXRlIF9saXN0ZW5Gb3JLZXlkb3duRXZlbnQoKSB7XG5cdFx0Ly8gYWRkIGdsb2JhbCBsaXN0ZW5lciBmb3Iga2V5IGRvd24gZXZlbnRzXG5cdFx0dGhpcy5nbG9iYWxJbmxpbmVFZGl0TGlzdGVuZXIgPSB0aGlzLnJlbmRlcmVyLmxpc3Rlbihcblx0XHRcdCdkb2N1bWVudCcsXG5cdFx0XHQna2V5ZG93bicsXG5cdFx0XHQkZXZlbnQgPT4ge1xuXHRcdFx0XHRzd2l0Y2ggKCRldmVudC5rZXkpIHtcblx0XHRcdFx0XHRjYXNlICdFbnRlcic6IC8vIHVwZGF0ZSBkYXRhIG9iamVjdFxuXHRcdFx0XHRcdFx0dGhpcy5pbmxpbmVFZGl0VXBkYXRlKCk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICdFc2NhcGUnOiAvLyBjYW5jZWxcblx0XHRcdFx0XHRcdHRoaXMuaW5saW5lRWRpdENhbmNlbCgpO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHQpO1xuXHR9XG5cdC8qKlxuXHQgKiBJbmxpbmUgZWRpdCB1cGRhdGUgLSBhY2NlcHQgY2hhbmdlcyBhbmQgdXBkYXRlIHJvdyB2YWx1ZXMuXG5cdCAqL1xuXHRwdWJsaWMgaW5saW5lRWRpdFVwZGF0ZSgpIHtcblx0XHQvLyBsb29wIHRocm91Z2ggcm93cyB0aGF0IGhhdmUgYmVlbiBlZGl0ZWRcblx0XHRPYmplY3Qua2V5cyh0aGlzLmVkaXRlZFJvd3MpLm1hcChrZXkgPT4ge1xuXHRcdFx0Y29uc3QgUk9XID0gdGhpcy5lZGl0ZWRSb3dzW2tleV0ucm93OyAvLyByb3cgdG8gdXBkYXRlXG5cdFx0XHRjb25zdCBDSEFOR0VTID0gdGhpcy5lZGl0ZWRSb3dzW2tleV0uY2hhbmdlczsgLy8gY2hhbmdlcyB0byB0aGUgcm93XG5cblx0XHRcdC8vIGxvb3AgdGhyb3VnaCBjaGFuZ2VzIGluIHJvd1xuXHRcdFx0T2JqZWN0LmtleXMoQ0hBTkdFUykubWFwKG9iamVjdEtleSA9PiB7XG5cdFx0XHRcdGNvbnN0IG9sZFZhbHVlID0geyAuLi5ST1cgfTtcblx0XHRcdFx0Uk9XW29iamVjdEtleV0gPSBDSEFOR0VTW29iamVjdEtleV0ucmVuZGVyVmFsdWU7IC8vIHVwZGF0ZSBkYXRhIHZhbHVlXG5cdFx0XHRcdHRoaXMudXBkYXRlUm93KFJPVywgb2xkVmFsdWUpOyAvLyB1cGRhdGUgbWV0YSBpbmZvIGZvciByb3cgYW5kIHNlbmQgZXZlbnRcblx0XHRcdFx0Q0hBTkdFU1tvYmplY3RLZXldLmVkaXRlZCA9IGZhbHNlOyAvLyBkaXNhYmxlIGVkaXQgbW9kZVxuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdFx0Ly8gY2xlYXIgcm93cyBtYXJrZWQgYXMgZWRpdGVkIGFzIHRoZSByb3dzIGhhdmUgYmVlbiB1cGRhdGVkXG5cdFx0dGhpcy5lZGl0ZWRSb3dzID0ge307XG5cdFx0Ly8gcmVtb3ZlIGxpc3RlbmVyXG5cdFx0dGhpcy5fc3RvcExpc3RlbmluZ0ZvcktleWRvd25FdmVudCgpO1xuXHR9XG5cdC8qKlxuXHQgKiBJbmxpbmUgZWRpdCBjYW5jZWwgLSBjYW5jZWwgYW5kIHJlc2V0IGlubGluZSBlZGl0cy5cblx0ICovXG5cdHB1YmxpYyBpbmxpbmVFZGl0Q2FuY2VsKHJvdz86IEd0Um93KSB7XG5cdFx0aWYgKHJvdykge1xuXHRcdFx0ZGVsZXRlIHRoaXMuZWRpdGVkUm93c1tyb3cuJCRndFJvd0lkXTtcblx0XHRcdC8vIHJlbW92ZSBsaXN0ZW5lclxuXHRcdFx0dGhpcy5fc3RvcExpc3RlbmluZ0ZvcktleWRvd25FdmVudCgpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIGxvb3AgdGhyb3VnaCByb3dzIHRoYXQgaGF2ZSBiZWVuIGVkaXRlZFxuXHRcdE9iamVjdC5rZXlzKHRoaXMuZWRpdGVkUm93cykubWFwKGtleSA9PiB7XG5cdFx0XHRjb25zdCBST1cgPSB0aGlzLmVkaXRlZFJvd3Nba2V5XS5yb3c7IC8vIHJvdyB0byB1cGRhdGVcblx0XHRcdGNvbnN0IENIQU5HRVMgPSB0aGlzLmVkaXRlZFJvd3Nba2V5XS5jaGFuZ2VzOyAvLyBjaGFuZ2VzIHRvIHRoZSByb3dcblxuXHRcdFx0Ly8gbG9vcCB0aHJvdWdoIGNoYW5nZXMgaW4gcm93XG5cdFx0XHRPYmplY3Qua2V5cyhDSEFOR0VTKS5tYXAob2JqZWN0S2V5ID0+IHtcblx0XHRcdFx0Q0hBTkdFU1tvYmplY3RLZXldLnJlbmRlclZhbHVlID0gUk9XW29iamVjdEtleV07IC8vIHJlc2V0IHJlbmRlcmVkIHZhbHVlXG5cdFx0XHRcdENIQU5HRVNbb2JqZWN0S2V5XS5lZGl0ZWQgPSBmYWxzZTsgLy8gZGlzYWJsZSBlZGl0IG1vZGVcblx0XHRcdH0pO1xuXHRcdH0pO1xuXHRcdC8vIGNsZWFyIHJvd3MgbWFya2VkIGFzIGVkaXRlZCBhcyB0aGUgcm93cyBoYXZlIGJlZW4gdXBkYXRlZFxuXHRcdHRoaXMuZWRpdGVkUm93cyA9IHt9O1xuXHRcdC8vIHJlbW92ZSBsaXN0ZW5lclxuXHRcdHRoaXMuX3N0b3BMaXN0ZW5pbmdGb3JLZXlkb3duRXZlbnQoKTtcblx0fVxuXHQvKipcblx0ICogU3RvcCBsaXN0ZW5pbmcgZm9yIGtleSBkb3duIGV2ZW50IC0gc3RvcCBsaXN0ZW5pbmcgZm9yIGtleSBkb3duIGV2ZW50cyBwYXNzZWQgZHVyaW5nIGlubGluZSBlZGl0LlxuXHQgKi9cblx0cHJpdmF0ZSBfc3RvcExpc3RlbmluZ0ZvcktleWRvd25FdmVudCgpIHtcblx0XHRpZiAodGhpcy5nbG9iYWxJbmxpbmVFZGl0TGlzdGVuZXIpIHtcblx0XHRcdHRoaXMuZ2xvYmFsSW5saW5lRWRpdExpc3RlbmVyKCk7XG5cdFx0XHR0aGlzLmdsb2JhbElubGluZUVkaXRMaXN0ZW5lciA9IG51bGw7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEFwcGx5IGZpbHRlcihzKS5cblx0ICogQHBhcmFtIGZpbHRlciAtIG9iamVjdCBjb250YWluaW5nIGtleSB2YWx1ZSBwYWlycywgd2hlcmUgdmFsdWUgc2hvdWxkIGJlIGFycmF5IG9mIHZhbHVlcy5cblx0ICovXG5cdHB1YmxpYyBndEFwcGx5RmlsdGVyKGZpbHRlcjogT2JqZWN0KSB7XG5cdFx0dGhpcy5ndEluZm8uZmlsdGVyID0gZmlsdGVyO1xuXHRcdC8vIGdvIHRvIGZpcnN0IHBhZ2Vcblx0XHR0aGlzLmdvVG9QYWdlKDEpO1xuXHRcdHRoaXMudXBkYXRlVG90YWxzKCk7XG5cdH1cblxuXHQvKiogQ2xlYXIvcmVtb3ZlIGFwcGxpZWQgZmlsdGVyKHMpLiAqL1xuXHRwdWJsaWMgZ3RDbGVhckZpbHRlcigpIHtcblx0XHR0aGlzLmd0SW5mby5maWx0ZXIgPSBmYWxzZTtcblx0XHR0aGlzLnVwZGF0ZVRvdGFscygpO1xuXHRcdC8vIHRoaXMudXBkYXRlUmVjb3JkUmFuZ2UoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBTZWFyY2hcblx0ICogQHBhcmFtIHZhbHVlIC0gc3RyaW5nIGNvbnRhaW5pbmcgb25lIG9yIG1vcmUgd29yZHNcblx0ICovXG5cdHB1YmxpYyBndFNlYXJjaCh2YWx1ZTogc3RyaW5nKSB7XG5cdFx0dGhpcy5ndEluZm8uc2VhcmNoVGVybXMgPSB2YWx1ZTtcblx0XHQvLyBhbHdheXMgZ28gdG8gZmlyc3QgcGFnZSB3aGVuIHNlYXJjaGluZ1xuXHRcdHRoaXMuZ29Ub1BhZ2UoMSk7XG5cdFx0dGhpcy51cGRhdGVUb3RhbHMoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBBZGQgcm93c1xuXHQgKiBAcGFyYW0gcm93cyAtIHJvd3MgdG8gYWRkXG5cdCAqIEByZXR1cm5zIG5ldyBkYXRhIGFycmF5LlxuXHQgKi9cblx0cHVibGljIGd0QWRkKHJvd3M6IEFycmF5PFI+KTogUmVhZG9ubHlBcnJheTxSPiB7XG5cdFx0dGhpcy5ndERhdGEgPSBbLi4udGhpcy5ndERhdGEsIC4uLnJvd3NdO1xuXHRcdHJldHVybiBbLi4udGhpcy5ndERhdGFdO1xuXHR9XG5cblx0LyoqXG5cdCAqIERlbGV0ZSByb3dcblx0ICogQHBhcmFtIG9iamVjdEtleSAtIG9iamVjdCBrZXkgeW91IHdhbnQgdG8gZmluZCBtYXRjaCB3aXRoXG5cdCAqIEBwYXJhbSB2YWx1ZSAtIHRoZSB2YWx1ZSB0aGF0IHNob3VsZCBiZSBkZWxldGVkXG5cdCAqIEBwYXJhbSBtYXRjaCAtIGFsbDogZGVsZXRlIGFsbCBtYXRjaGVzLCBmaXJzdDogZGVsZXRlIGZpcnN0IG1hdGNoIChkZWZhdWx0KVxuXHQgKiBAcmV0dXJucyBuZXcgZGF0YSBhcnJheS5cblx0ICovXG5cdHB1YmxpYyBndERlbGV0ZShcblx0XHRvYmplY3RLZXk6IHN0cmluZyxcblx0XHR2YWx1ZTogc3RyaW5nIHwgbnVtYmVyLFxuXHRcdG1hdGNoOiAnZmlyc3QnIHwgJ2FsbCcgPSAnZmlyc3QnXG5cdCk6IFJlYWRvbmx5QXJyYXk8Uj4ge1xuXHRcdGlmIChtYXRjaCA9PT0gJ2ZpcnN0Jykge1xuXHRcdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmd0RGF0YS5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRpZiAodGhpcy5ndERhdGFbaV1bb2JqZWN0S2V5XSA9PT0gdmFsdWUpIHtcblx0XHRcdFx0XHRpZiAodGhpcy5pc1Jvd1NlbGVjdGVkKHRoaXMuZ3REYXRhW2ldKSkge1xuXHRcdFx0XHRcdFx0dGhpcy50b2dnbGVTZWxlY3QodGhpcy5ndERhdGFbaV0pO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHR0aGlzLmd0RGF0YS5zcGxpY2UoaSwgMSk7XG5cdFx0XHRcdFx0dGhpcy5ndERhdGEgPSBbLi4udGhpcy5ndERhdGFdO1xuXHRcdFx0XHRcdGlmIChtYXRjaCA9PT0gJ2ZpcnN0Jykge1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdGZvciAobGV0IGkgPSB0aGlzLmd0RGF0YS5sZW5ndGg7IGkgPiAwOyBpLS0pIHtcblx0XHRcdFx0aWYgKHRoaXMuZ3REYXRhW2kgLSAxXVtvYmplY3RLZXldID09PSB2YWx1ZSkge1xuXHRcdFx0XHRcdGlmICh0aGlzLmlzUm93U2VsZWN0ZWQodGhpcy5ndERhdGFbaSAtIDFdKSkge1xuXHRcdFx0XHRcdFx0dGhpcy50b2dnbGVTZWxlY3QodGhpcy5ndERhdGFbaSAtIDFdKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0dGhpcy5ndERhdGEuc3BsaWNlKGkgLSAxLCAxKTtcblx0XHRcdFx0XHR0aGlzLmd0RGF0YSA9IFsuLi50aGlzLmd0RGF0YV07XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIFsuLi50aGlzLmd0RGF0YV07XG5cdH1cblxuXHQvKipcblx0ICogQ3JlYXRlIHN0b3JlIHRvIGhvbGQgcHJldmlvdXNseSBsb2FkZWQgcmVjb3Jkcy5cblx0ICogQHBhcmFtIHJlY29yZHMgLSB0b3RhbCBudW1iZXIgb2YgcmVjb3JkcyBpbiBzdG9yZS5cblx0ICogQHBhcmFtIHBlclBhZ2UgLSBob3cgbWFueSByZWNvcmRzIHRvIHNob3cgcGVyIHBhZ2UuXG5cdCAqIEByZXR1cm5zIGEgbmVzdGVkIGFycmF5IHRvIGhvbGQgcmVjb3JkcyBwZXIgcGFnZS5cblx0ICovXG5cdHByaXZhdGUgY3JlYXRlU3RvcmUocmVjb3JkczogbnVtYmVyLCBwZXJQYWdlOiBudW1iZXIpOiBBcnJheTxBcnJheTxhbnk+PiB7XG5cdFx0Y29uc3Qgc3RvcmVzID0gTWF0aC5jZWlsKHJlY29yZHMgLyBwZXJQYWdlKTtcblx0XHRjb25zdCBzdG9yZTogQXJyYXk8QXJyYXk8YW55Pj4gPSBbXTtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHN0b3JlczsgaSsrKSB7XG5cdFx0XHRzdG9yZVtpXSA9IFtdO1xuXHRcdH1cblx0XHRyZXR1cm4gc3RvcmU7XG5cdH1cblxuXHQvKipcblx0ICogQ3JlYXRlIHBsYWNlaG9sZGVycyBmb3Igcm93cyB3aGlsZSBsb2FkaW5nIGRhdGEgZnJvbSBiYWNrLWVuZC5cblx0ICogQHBhcmFtIHBlclBhZ2UgLSBob3cgbWFueSByZWNvcmRzIHRvIHNob3cgcGVyIHBhZ2UuXG5cdCAqIEByZXR1cm5zIGFuIGFycmF5IGNvbnRhaW5pbmcgZW1wdHkgcmVjb3JkcyB0byBiZSBwcmVzZW50ZWQgd2hpbGUgZmV0Y2hpbmcgcmVhbCBkYXRhLlxuXHQgKi9cblx0cHJpdmF0ZSBsb2FkaW5nQ29udGVudChwZXJQYWdlOiBudW1iZXIpIHtcblx0XHQvLyBjcmVhdGUgcm93IG9iamVjdFxuXHRcdGNvbnN0IHJvd09iamVjdDogT2JqZWN0ID0ge1xuXHRcdFx0JCRsb2FkaW5nOiB0cnVlXG5cdFx0fTtcblx0XHRsZXQgb3JkZXIgPSAwO1xuXG5cdFx0Ly8gc29ydCBzZXR0aW5ncyBieSBjb2x1bW4gb3JkZXJcblx0XHR0aGlzLl9ndFNldHRpbmdzLnNvcnQodGhpcy5nZXRDb2x1bW5PcmRlcik7XG5cblx0XHQvLyBsb29wIHRocm91Z2ggYWxsIHNldHRpbmdzIG9iamVjdHMuLi5cblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2d0U2V0dGluZ3MubGVuZ3RoOyBpKyspIHtcblx0XHRcdGNvbnN0IHNldHRpbmcgPSB0aGlzLl9ndFNldHRpbmdzW2ldO1xuXG5cdFx0XHQvLyAuLi5pZiBjb2x1bW4gaXMgdmlzaWJsZSBhbmQgZW5hYmxlZC4uLlxuXHRcdFx0aWYgKHNldHRpbmcudmlzaWJsZSAhPT0gZmFsc2UgJiYgc2V0dGluZy5lbmFibGVkICE9PSBmYWxzZSkge1xuXHRcdFx0XHQvLyAuLi5pZiBmaXJzdCBjb2x1bW4sIHNldCB2YWx1ZSB0byBsb2FkaW5nIHRleHQgb3RoZXJ3aXNlIGxlYXZlIGl0IGVtcHR5XG5cdFx0XHRcdGlmIChvcmRlciA9PT0gMCkge1xuXHRcdFx0XHRcdHJvd09iamVjdFtzZXR0aW5nLm9iamVjdEtleV0gPSB0aGlzLmd0VGV4dHMubG9hZGluZztcblx0XHRcdFx0XHR0aGlzLmxvYWRpbmdQcm9wZXJ0eSA9IHNldHRpbmcub2JqZWN0S2V5O1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJvd09iamVjdFtzZXR0aW5nLm9iamVjdEtleV0gPSAnJztcblx0XHRcdFx0fVxuXHRcdFx0XHRvcmRlcisrO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cm93T2JqZWN0W3NldHRpbmcub2JqZWN0S2V5XSA9ICcnO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIGNyZWF0ZSBjb250ZW50IHBsYWNlaG9sZGVyXG5cdFx0Y29uc3QgY29udGVudFBsYWNlaG9sZGVyOiBBcnJheTxhbnk+ID0gW107XG5cblx0XHQvLyBjcmVhdGUgZXF1YWwgbnVtYmVyIG9mIHJvd3MgYXMgcm93cyBwZXIgcGFnZVxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgcGVyUGFnZTsgaSsrKSB7XG5cdFx0XHQvLyAuLi5hZGQgdGVtcG9yYXJ5IHJvdyBvYmplY3Rcblx0XHRcdGNvbnRlbnRQbGFjZWhvbGRlci5wdXNoKHJvd09iamVjdCk7XG5cdFx0fVxuXHRcdHJldHVybiBjb250ZW50UGxhY2Vob2xkZXI7XG5cdH1cblxuXHQvLyBUT0RPOiBtb3ZlIHRvIGhlbHBlciBmdW5jdGlvbnNcblx0LyoqIFNvcnQgYnkgc29ydCBvcmRlciAqL1xuXHRwcml2YXRlIGdldFNvcnRPcmRlciA9IGZ1bmN0aW9uKGE6IEd0Q29uZmlnU2V0dGluZywgYjogR3RDb25maWdTZXR0aW5nKSB7XG5cdFx0aWYgKGEuc29ydE9yZGVyIDwgYi5zb3J0T3JkZXIpIHtcblx0XHRcdHJldHVybiAtMTtcblx0XHR9XG5cdFx0aWYgKGEuc29ydE9yZGVyID4gYi5zb3J0T3JkZXIgfHwgdHlwZW9mIGEuc29ydE9yZGVyID09PSAndW5kZWZpbmVkJykge1xuXHRcdFx0cmV0dXJuIDE7XG5cdFx0fVxuXHRcdHJldHVybiAwO1xuXHR9O1xuXG5cdC8vIFRPRE86IG1vdmUgdG8gaGVscGVyIGZ1bmN0aW9uc1xuXHQvKiogU29ydCBieSBjb2x1bW4gb3JkZXIgKi9cblx0cHJpdmF0ZSBnZXRDb2x1bW5PcmRlciA9IGZ1bmN0aW9uKGE6IEd0Q29uZmlnU2V0dGluZywgYjogR3RDb25maWdTZXR0aW5nKSB7XG5cdFx0aWYgKGEuY29sdW1uT3JkZXIgPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0cmV0dXJuIC0xO1xuXHRcdH1cblx0XHRpZiAoYS5jb2x1bW5PcmRlciA8IGIuY29sdW1uT3JkZXIpIHtcblx0XHRcdHJldHVybiAtMTtcblx0XHR9XG5cdFx0aWYgKGEuY29sdW1uT3JkZXIgPiBiLmNvbHVtbk9yZGVyKSB7XG5cdFx0XHRyZXR1cm4gMTtcblx0XHR9XG5cdFx0cmV0dXJuIDA7XG5cdH07XG5cblx0Ly8gVE9ETzogbW92ZSB0byBoZWxwZXIgZnVuY3Rpb25zXG5cdC8qKiBDcmVhdGUgYSBkZWVwIGNvcHkgb2YgZGF0YSAqL1xuXHRwcml2YXRlIGNsb25lRGVlcCA9IGZ1bmN0aW9uKG86IGFueSkge1xuXHRcdHJldHVybiBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KG8pKTtcblx0fTtcblxuXHQvKiogRXhwb3J0IGRhdGEgYXMgQ1NWXG5cdCAqIEBwYXJhbSBmaWxlTmFtZSAtIG9wdGlvbmFsIGZpbGUgbmFtZSAob3ZlcnJpZGVzIGRlZmF1bHQgZmlsZSBuYW1lKS5cblx0ICogQHBhcmFtIHVzZUJPTSAtIHVzZSBCT00gKGJ5dGUgb3JkZXIgbWFya2VyKS5cblx0ICovXG5cdHB1YmxpYyBleHBvcnRDU1YoZmlsZU5hbWU/OiBzdHJpbmcsIHVzZUJPTTogYm9vbGVhbiA9IGZhbHNlKSB7XG5cdFx0Y29uc3QgZGF0YSA9IHRoaXMuZGF0YS5leHBvcnREYXRhO1xuXHRcdGxldCBjc3YgPSAnJztcblx0XHRjb25zdCBCT00gPSAnXFx1RkVGRic7XG5cblx0XHQvLyBjc3YgZXhwb3J0IGhlYWRlcnNcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2d0U2V0dGluZ3MubGVuZ3RoOyBpKyspIHtcblx0XHRcdGlmICh0aGlzLl9ndFNldHRpbmdzW2ldLmV4cG9ydCAhPT0gZmFsc2UpIHtcblx0XHRcdFx0Y3N2ICs9IHRoaXMuZ2V0UHJvcGVydHkodGhpcy5fZ3RGaWVsZHMsIHRoaXMuX2d0U2V0dGluZ3NbaV0ub2JqZWN0S2V5KVxuXHRcdFx0XHRcdC5uYW1lO1xuXG5cdFx0XHRcdGlmIChpIDwgdGhpcy5fZ3RTZXR0aW5ncy5sZW5ndGggLSAxKSB7XG5cdFx0XHRcdFx0Y3N2ICs9IHRoaXMuX2d0T3B0aW9ucy5jc3ZEZWxpbWl0ZXI7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBjc3YgZXhwb3J0IGJvZHlcblx0XHRkYXRhLmZvckVhY2gocm93ID0+IHtcblx0XHRcdGNzdiArPSAnXFxuJztcblx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fZ3RTZXR0aW5ncy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRpZiAodGhpcy5fZ3RTZXR0aW5nc1tpXS5leHBvcnQgIT09IGZhbHNlKSB7XG5cdFx0XHRcdFx0Ly8gZ2V0IGZpZWxkIHNldHRpbmdzXG5cdFx0XHRcdFx0Y29uc3QgZmllbGRTZXR0aW5nID0gdGhpcy5nZXRQcm9wZXJ0eShcblx0XHRcdFx0XHRcdHRoaXMuX2d0RmllbGRzLFxuXHRcdFx0XHRcdFx0dGhpcy5fZ3RTZXR0aW5nc1tpXS5vYmplY3RLZXlcblx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0Ly8gZ2V0IGV4cG9ydCB2YWx1ZSwgaWYgZXhwb3J0IGZ1bmN0aW9uIGlzIGRlZmluZWQgdXNlIGl0IG90aGVyd2lzZSBjaGVjayBmb3IgdmFsdWUgZnVuY3Rpb24gYW5kIGFzIGEgbGFzdCByZXNvcnQgZXhwb3J0IHJhdyBkYXRhXG5cdFx0XHRcdFx0bGV0IGV4cG9ydFZhbHVlOiBzdHJpbmcgPVxuXHRcdFx0XHRcdFx0ZmllbGRTZXR0aW5nLmV4cG9ydCAmJiB0eXBlb2YgZmllbGRTZXR0aW5nLmV4cG9ydCA9PT0gJ2Z1bmN0aW9uJ1xuXHRcdFx0XHRcdFx0XHQ/IGZpZWxkU2V0dGluZy5leHBvcnQocm93KVxuXHRcdFx0XHRcdFx0XHQ6IGZpZWxkU2V0dGluZy52YWx1ZSAmJiB0eXBlb2YgZmllbGRTZXR0aW5nLnZhbHVlID09PSAnZnVuY3Rpb24nXG5cdFx0XHRcdFx0XHRcdFx0PyBmaWVsZFNldHRpbmcudmFsdWUocm93KVxuXHRcdFx0XHRcdFx0XHRcdDogcm93W3RoaXMuX2d0U2V0dGluZ3NbaV0ub2JqZWN0S2V5XTtcblxuXHRcdFx0XHRcdC8vIGVzY2FwZSBleHBvcnQgdmFsdWUgdXNpbmcgZG91YmxlIHF1b3RlcyAoXCIpIGlmIGV4cG9ydCB2YWx1ZSBjb250YWlucyBkZWxpbWl0ZXJcblx0XHRcdFx0XHRleHBvcnRWYWx1ZSA9XG5cdFx0XHRcdFx0XHR0eXBlb2YgZXhwb3J0VmFsdWUgPT09ICdzdHJpbmcnICYmXG5cdFx0XHRcdFx0XHRleHBvcnRWYWx1ZS5pbmRleE9mKHRoaXMuX2d0T3B0aW9ucy5jc3ZEZWxpbWl0ZXIpICE9PSAtMVxuXHRcdFx0XHRcdFx0XHQ/ICdcIicgKyBleHBvcnRWYWx1ZSArICdcIidcblx0XHRcdFx0XHRcdFx0OiBleHBvcnRWYWx1ZTtcblxuXHRcdFx0XHRcdGNzdiArPSBleHBvcnRWYWx1ZTtcblx0XHRcdFx0XHRpZiAoaSA8IHRoaXMuX2d0U2V0dGluZ3MubGVuZ3RoIC0gMSkge1xuXHRcdFx0XHRcdFx0Y3N2ICs9IHRoaXMuX2d0T3B0aW9ucy5jc3ZEZWxpbWl0ZXI7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHRjb25zdCBibG9iID0gbmV3IEJsb2IoWyh1c2VCT00gPyBCT00gOiAnJykgKyBjc3ZdLCB7XG5cdFx0XHR0eXBlOiAndGV4dC9jc3Y7Y2hhcnNldD11dGYtOCdcblx0XHR9KTtcblxuXHRcdGlmICh3aW5kb3cubmF2aWdhdG9yLm1zU2F2ZU9yT3BlbkJsb2IpIHtcblx0XHRcdG5hdmlnYXRvci5tc1NhdmVPck9wZW5CbG9iKFxuXHRcdFx0XHRibG9iLFxuXHRcdFx0XHRmaWxlTmFtZSA/IGZpbGVOYW1lICsgJy5jc3YnIDogdGhpcy5ndFRleHRzLmNzdkRvd25sb2FkICsgJy5jc3YnXG5cdFx0XHQpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRjb25zdCBsaW5rID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpO1xuXHRcdFx0bGluay5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuXHRcdFx0ZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChsaW5rKTtcblx0XHRcdGlmIChsaW5rLmRvd25sb2FkICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0bGluay5zZXRBdHRyaWJ1dGUoXG5cdFx0XHRcdFx0J2hyZWYnLFxuXHRcdFx0XHRcdCdkYXRhOnRleHQvY3N2O2NoYXJzZXQ9dXRmLTgsJyArXG5cdFx0XHRcdFx0XHRlbmNvZGVVUklDb21wb25lbnQoKHVzZUJPTSA/IEJPTSA6ICcnKSArIGNzdilcblx0XHRcdFx0KTsgLy8gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKSk7XG5cdFx0XHRcdGxpbmsuc2V0QXR0cmlidXRlKFxuXHRcdFx0XHRcdCdkb3dubG9hZCcsXG5cdFx0XHRcdFx0ZmlsZU5hbWUgPyBmaWxlTmFtZSArICcuY3N2JyA6IHRoaXMuZ3RUZXh0cy5jc3ZEb3dubG9hZCArICcuY3N2J1xuXHRcdFx0XHQpO1xuXHRcdFx0XHRkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGxpbmspO1xuXHRcdFx0XHRsaW5rLmNsaWNrKCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRjc3YgPSAnZGF0YTp0ZXh0L2NzdjtjaGFyc2V0PXV0Zi04LCcgKyAodXNlQk9NID8gQk9NIDogJycpICsgY3N2O1xuXHRcdFx0XHR3aW5kb3cub3BlbihlbmNvZGVVUklDb21wb25lbnQoY3N2KSk7XG5cdFx0XHR9XG5cdFx0XHRkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGxpbmspO1xuXHRcdH1cblxuXHRcdC8vIGVtaXQgZXhwb3J0IGV2ZW50XG5cdFx0dGhpcy5ndEV2ZW50LmVtaXQoe1xuXHRcdFx0bmFtZTogJ2d0LWV4cG9ydGVkLWNzdicsXG5cdFx0XHR2YWx1ZTogZmlsZU5hbWUgPyBmaWxlTmFtZSA6IHRoaXMuZ3RUZXh0cy5jc3ZEb3dubG9hZCArICcuY3N2J1xuXHRcdH0pO1xuXHR9XG5cblx0LyoqIFJldHVybiBwcm9wZXJ0eSAqL1xuXHRwcml2YXRlIGdldFByb3BlcnR5ID0gZnVuY3Rpb24oYXJyYXk6IEFycmF5PGFueT4sIGtleTogc3RyaW5nKSB7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKGFycmF5W2ldLm9iamVjdEtleSA9PT0ga2V5KSB7XG5cdFx0XHRcdHJldHVybiBhcnJheVtpXTtcblx0XHRcdH1cblx0XHR9XG5cdH07XG5cblx0cHJpdmF0ZSByZXN0cnVjdHVyZVNvcnRpbmcgPSBmdW5jdGlvbigpIHtcblx0XHQvKiogQ2hlY2sgYW5kIHN0b3JlIHNvcnQgb3JkZXIgdXBvbiBpbml0aWFsaXphdGlvbi5cblx0XHQgKiAgVGhpcyBpcyBkb25lIGJ5IGNoZWNraW5nIHNvcnQgcHJvcGVydGllcyBpbiB0aGUgc2V0dGluZ3MgYXJyYXkgb2YgdGhlIHRhYmxlLCBpZiBubyBzb3J0aW5nIGlzIGRlZmluZWRcblx0XHQgKiAgd2UnbGwgc29ydCB0aGUgZGF0YSBieSB0aGUgZmlyc3QgdmlzaWJsZSBhbmQgZW5hYmxlZCBjb2x1bW4gaW4gdGhlIHRhYmxlKGFzY2VuZGluZykuIFBsZWFzZSBub3RlIHRoYXQgYWN0dWFsbHlcblx0XHQgKiAgc29ydGluZyBoYXZlIHRvIGJlIGRvbmUgc2VydmVyIHNpZGUgd2hlbiBsYXp5IGxvYWRpbmcgZGF0YSBmb3Igb2J2aW91cyByZWFzb25zLiAgKi9cblx0XHQvLyBjcmVhdGUgc29ydGluZyBhcnJheVxuXHRcdGNvbnN0IHNvcnRpbmcgPSBbXTtcblx0XHRpZiAodGhpcy5fZ3RTZXR0aW5ncykge1xuXHRcdFx0Ly8gLi4uc29ydCBzZXR0aW5ncyBieSBzb3J0IG9yZGVyXG5cdFx0XHR0aGlzLl9ndFNldHRpbmdzLnNvcnQodGhpcy5nZXRTb3J0T3JkZXIpO1xuXG5cdFx0XHQvLyAuLi5sb29wIHRocm91Z2ggc2V0dGluZ3Ncblx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fZ3RTZXR0aW5ncy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRjb25zdCBzZXR0aW5nID0gdGhpcy5fZ3RTZXR0aW5nc1tpXTtcblxuXHRcdFx0XHQvLyAuLi5pZiBzb3J0ZWQgYXNjZW5kaW5nLi4uXG5cdFx0XHRcdGlmIChzZXR0aW5nLnNvcnQgPT09ICdhc2MnKSB7XG5cdFx0XHRcdFx0Ly8gLi4uIGFkZCB0byBzb3J0aW5nXG5cdFx0XHRcdFx0c29ydGluZy5wdXNoKHNldHRpbmcub2JqZWN0S2V5KTtcblx0XHRcdFx0fSBlbHNlIGlmIChzZXR0aW5nLnNvcnQgPT09ICdkZXNjJykge1xuXHRcdFx0XHRcdC8qIC4uLmVsc2UgaWYgc29ydGVkIGRlc2NlbmRpbmcuLi4gKi8gLy8gLi4uIGFkZCB0byBzb3J0aW5nXG5cdFx0XHRcdFx0c29ydGluZy5wdXNoKCctJyArIHNldHRpbmcub2JqZWN0S2V5KTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0Ly8gLi4uaWYgbm8gc29ydGluZyBhcHBsaWVkLi4uXG5cdFx0XHRpZiAoc29ydGluZy5sZW5ndGggPT09IDApIHtcblx0XHRcdFx0c29ydGluZy5wdXNoKCckJGd0Um93SWQnKTtcblx0XHRcdFx0LyovLyAuLi5zb3J0IHNldHRpbmdzIGJ5IGNvbHVtbiBvcmRlclxuXHRcdFx0XHR0aGlzLl9ndFNldHRpbmdzLnNvcnQodGhpcy5nZXRDb2x1bW5PcmRlcik7XG5cblx0XHRcdFx0Ly8gLi4ubG9vcCB0aHJvdWdoIHNldHRpbmdzXG5cdFx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fZ3RTZXR0aW5ncy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRcdGNvbnN0IHNldHRpbmcgPSB0aGlzLl9ndFNldHRpbmdzW2ldO1xuXG5cdFx0XHRcdFx0Ly8gLi4uaWYgY29sdW1uIGlzIGVuYWJsZWQgYW5kIHZpc2libGUuLi5cblx0XHRcdFx0XHRpZiAoc2V0dGluZy5lbmFibGVkICE9PSBmYWxzZSAmJiBzZXR0aW5nLnZpc2libGUgIT09IGZhbHNlKSB7XG5cdFx0XHRcdFx0XHQvLyAuLi5hZGQgZmlyc3QgbWF0Y2ggYW5kIGV4aXQgZnVuY3Rpb25cblx0XHRcdFx0XHRcdHRoaXMuc29ydE9yZGVyID0gW3RoaXMuX2d0U2V0dGluZ3NbaV0ub2JqZWN0S2V5XTtcblx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0qL1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmICh0aGlzLnNvcnRPcmRlci5sZW5ndGggPT09IDApIHtcblx0XHRcdHRoaXMuc29ydE9yZGVyID0gc29ydGluZztcblx0XHR9XG5cdH07XG5cblx0bmdPbkluaXQoKSB7XG5cdFx0Ly8gaWYgbnVtYmVyIG9mIHJvdyB0byBkaXNwbGF5IGZyb20gc3RhcnQgaXMgc2V0IHRvIG51bGwgb3IgMC4uLlxuXHRcdGlmICghdGhpcy5ndE9wdGlvbnMubnVtYmVyT2ZSb3dzKSB7XG5cdFx0XHQvLyAuLi5jaGFuZ2Ugcm93IGxlbmd0aFxuXHRcdFx0dGhpcy5jaGFuZ2VSb3dMZW5ndGgodGhpcy5ndE9wdGlvbnMubnVtYmVyT2ZSb3dzKTtcblx0XHR9XG5cdFx0dGhpcy5yZXN0cnVjdHVyZVNvcnRpbmcoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiAgRXh0ZW5kIG9iamVjdCBmdW5jdGlvbi5cblx0ICovXG5cdHByaXZhdGUgZXh0ZW5kID0gZnVuY3Rpb24oYTogT2JqZWN0LCBiOiBPYmplY3QpIHtcblx0XHRmb3IgKGNvbnN0IGtleSBpbiBiKSB7XG5cdFx0XHRpZiAoYi5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG5cdFx0XHRcdGFba2V5XSA9IGJba2V5XTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGE7XG5cdH07XG5cblx0bmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuXHRcdC8vIGlmIGd0IHRleHRzIGhhdmUgY2hhbmdlZC4uLlxuXHRcdGlmIChjaGFuZ2VzWydndFRleHRzJ10pIHtcblx0XHRcdC8vIC4uLmV4dGVuZCBndE9wdGlvbnMgZGVmYXVsdCB2YWx1ZXMgd2l0aCB2YWx1ZXMgcGFzc2VkIGludG8gY29tcG9uZW50XG5cdFx0XHR0aGlzLmd0VGV4dHMgPSA8R3RUZXh0cz50aGlzLmV4dGVuZCh0aGlzLmd0RGVmYXVsdFRleHRzLCB0aGlzLmd0VGV4dHMpO1xuXHRcdH1cblxuXHRcdC8vIGlmIGxhenkgbG9hZGluZyBkYXRhIGFuZCBwYWdpbmcgaW5mb3JtYXRpb24gaXMgYXZhaWxhYmxlLi4uXG5cdFx0aWYgKHRoaXMuZ3RPcHRpb25zLmxhenlMb2FkICYmIHRoaXMuZ3RJbmZvKSB7XG5cdFx0XHQvLyAuLi5jYWxjdWxhdGUgdG90YWwgbnVtYmVyIG9mIHBhZ2VzXG5cdFx0XHR0aGlzLmd0SW5mby5wYWdlVG90YWwgPSBNYXRoLmNlaWwoXG5cdFx0XHRcdHRoaXMuZ3RJbmZvLnJlY29yZHNBZnRlclNlYXJjaCAvIHRoaXMuZ3RJbmZvLnJlY29yZExlbmd0aFxuXHRcdFx0KTtcblxuXHRcdFx0Ly8gLi4uZGVjbGFyZSBzdG9yZSBwb3NpdGlvblxuXHRcdFx0Y29uc3Qgc3RvcmVQb3NpdGlvbiA9IHRoaXMuZ3RJbmZvLnBhZ2VDdXJyZW50IC0gMTtcblxuXHRcdFx0Ly8gLi4uYW5kIGlmIHN0b3JlIGlzIGVtcHR5IG9yIHBhZ2UgbGVuZ3RoIGhhcyBjaGFuZ2VkLi4uXG5cdFx0XHRpZiAoXG5cdFx0XHRcdHRoaXMuc3RvcmUubGVuZ3RoID09PSAwIHx8XG5cdFx0XHRcdHRoaXMuc3RvcmVbMF0ubGVuZ3RoICE9PSB0aGlzLmd0SW5mby5yZWNvcmRMZW5ndGhcblx0XHRcdCkge1xuXHRcdFx0XHQvLyAuLi5jcmVhdGUgc3RvcmVcblx0XHRcdFx0dGhpcy5zdG9yZSA9IHRoaXMuY3JlYXRlU3RvcmUoXG5cdFx0XHRcdFx0dGhpcy5ndEluZm8ucmVjb3Jkc0FmdGVyU2VhcmNoLFxuXHRcdFx0XHRcdHRoaXMuZ3RJbmZvLnJlY29yZExlbmd0aFxuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyAuLi5zdG9yZSByZXRyaWV2ZWQgZGF0YSBpbiBzdG9yZSBhdCBzdG9yZSBwb3NpdGlvblxuXHRcdFx0dGhpcy5zdG9yZVtzdG9yZVBvc2l0aW9uXSA9IHRoaXMuZ3REYXRhO1xuXHRcdFx0dGhpcy5ndEluZm8udmlzaWJsZVJlY29yZHMgPSBbLi4udGhpcy5ndERhdGFdOyAvLyBhZGQgdmlzaWJsZSByb3dzXG5cblx0XHRcdC8vIHJlcGxhY2UgZGF0YSB3aXRoIHN0b3JlXG5cdFx0XHR0aGlzLl9ndERhdGEgPSB0aGlzLnN0b3JlO1xuXHRcdFx0dGhpcy5sb2FkaW5nID0gZmFsc2U7XG5cdFx0XHR0aGlzLnVwZGF0ZVJlY29yZFJhbmdlKCk7XG5cdFx0XHR0aGlzLmd0RXZlbnQuZW1pdCh7XG5cdFx0XHRcdG5hbWU6ICdndC1pbmZvJyxcblx0XHRcdFx0dmFsdWU6IHRoaXMuZ3RJbmZvXG5cdFx0XHR9KTtcblx0XHR9IGVsc2UgaWYgKFxuXHRcdFx0dGhpcy5fZ3REYXRhICYmXG5cdFx0XHR0aGlzLl9ndERhdGEubGVuZ3RoID49IDAgJiZcblx0XHRcdGNoYW5nZXNbJ2d0RGF0YSddICYmXG5cdFx0XHRjaGFuZ2VzWydndERhdGEnXS5wcmV2aW91c1ZhbHVlXG5cdFx0KSB7XG5cdFx0XHR0aGlzLmxvYWRpbmcgPSBmYWxzZTtcblx0XHR9IGVsc2UgaWYgKFxuXHRcdFx0Y2hhbmdlc1snZ3REYXRhJ10gJiZcblx0XHRcdGNoYW5nZXNbJ2d0RGF0YSddLmZpcnN0Q2hhbmdlICYmXG5cdFx0XHR0aGlzLl9ndERhdGEgJiZcblx0XHRcdHRoaXMuX2d0RGF0YS5sZW5ndGggPiAwXG5cdFx0KSB7XG5cdFx0XHR0aGlzLmxvYWRpbmcgPSBmYWxzZTtcblx0XHR9XG5cdH1cblxuXHR0cmFja0J5Rm4oaW5kZXg6IG51bWJlciwgaXRlbTogR3RSb3cpIHtcblx0XHRyZXR1cm4gaXRlbS4kJGd0Um93SWQ7XG5cdH1cblxuXHR0cmFja0J5Q29sdW1uRm4oaW5kZXg6IG51bWJlciwgaXRlbTogR3RDb25maWdGaWVsZDxhbnksIGFueT4pIHtcblx0XHRyZXR1cm4gaXRlbS5vYmplY3RLZXk7XG5cdH1cblxuXHRuZ09uRGVzdHJveSgpIHtcblx0XHQvLyByZW1vdmUgbGlzdGVuZXJcblx0XHR0aGlzLl9zdG9wTGlzdGVuaW5nRm9yS2V5ZG93bkV2ZW50KCk7XG5cdH1cbn1cbiIsImltcG9ydCB7IFBpcGUsIFBpcGVUcmFuc2Zvcm0gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEd0Q29uZmlnRmllbGQgfSBmcm9tICcuLi9pbnRlcmZhY2VzL2d0LWNvbmZpZy1maWVsZCc7XG5pbXBvcnQgeyBHdENvbmZpZ1NldHRpbmcgfSBmcm9tICcuLi9pbnRlcmZhY2VzL2d0LWNvbmZpZy1zZXR0aW5nJztcbmltcG9ydCB7IEd0Um93IH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9ndC1yb3cnO1xuXG5AUGlwZSh7XG5cdG5hbWU6ICdndFZpc2libGUnXG59KVxuZXhwb3J0IGNsYXNzIEd0VmlzaWJsZVBpcGU8UiBleHRlbmRzIEd0Um93PiBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xuXHQvLyBUT0RPOiBtb3ZlIHRvIGhlbHBlciBmdW5jdGlvbnNcblx0LyoqIFNvcnQgYnkgY29sdW1uIG9yZGVyICovXG5cdHByaXZhdGUgZ2V0Q29sdW1uT3JkZXIgPSBmdW5jdGlvbihhOiBhbnksIGI6IGFueSkge1xuXHRcdGlmIChhLmNvbHVtbk9yZGVyIDwgYi5jb2x1bW5PcmRlcikge1xuXHRcdFx0cmV0dXJuIC0xO1xuXHRcdH1cblx0XHRpZiAoYS5jb2x1bW5PcmRlciA+IGIuY29sdW1uT3JkZXIgfHwgdHlwZW9mIGEuY29sdW1uT3JkZXIgPT09ICd1bmRlZmluZWQnKSB7XG5cdFx0XHRyZXR1cm4gMTtcblx0XHR9XG5cdFx0cmV0dXJuIDA7XG5cdH07XG5cblx0dHJhbnNmb3JtKFxuXHRcdGFycmF5OiBBcnJheTxhbnk+LFxuXHRcdHNldHRpbmdzOiBBcnJheTxHdENvbmZpZ1NldHRpbmc+LFxuXHRcdHJlZnJlc2hQaXBlPzogYm9vbGVhblxuXHQpOiBBcnJheTxHdENvbmZpZ0ZpZWxkPFIsIGFueT4+IHwgQXJyYXk8R3RDb25maWdTZXR0aW5nPiB7XG5cdFx0Y29uc3QgdmlzaWJsZUNvbHVtbnMgPSBzZXR0aW5nc1xuXHRcdFx0LnNvcnQodGhpcy5nZXRDb2x1bW5PcmRlcilcblx0XHRcdC5tYXAoKHNldHRpbmc6IEd0Q29uZmlnU2V0dGluZykgPT4ge1xuXHRcdFx0XHRpZiAoc2V0dGluZy52aXNpYmxlICE9PSBmYWxzZSAmJiBzZXR0aW5nLmVuYWJsZWQgIT09IGZhbHNlKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHNldHRpbmcub2JqZWN0S2V5O1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblxuXHRcdHJldHVybiBhcnJheVxuXHRcdFx0LmZpbHRlcigoY29sdW1uOiBhbnkpID0+IHtcblx0XHRcdFx0cmV0dXJuIHZpc2libGVDb2x1bW5zLmluZGV4T2YoY29sdW1uLm9iamVjdEtleSkgIT09IC0xO1xuXHRcdFx0fSlcblx0XHRcdC5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcblx0XHRcdFx0cmV0dXJuIHZpc2libGVDb2x1bW5zLmluZGV4T2YoYS5vYmplY3RLZXkpIDxcblx0XHRcdFx0XHR2aXNpYmxlQ29sdW1ucy5pbmRleE9mKGIub2JqZWN0S2V5KVxuXHRcdFx0XHRcdD8gLTFcblx0XHRcdFx0XHQ6IDE7XG5cdFx0XHR9KTtcblx0fVxufVxuIiwiaW1wb3J0IHsgUGlwZSwgUGlwZVRyYW5zZm9ybSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgR3RDb25maWdGaWVsZCB9IGZyb20gJy4uL2ludGVyZmFjZXMvZ3QtY29uZmlnLWZpZWxkJztcbmltcG9ydCB7IEd0Um93IH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9ndC1yb3cnO1xuaW1wb3J0IHsgR3RDb25maWdTZXR0aW5nIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9ndC1jb25maWctc2V0dGluZyc7XG5pbXBvcnQgeyBHdEluZm9ybWF0aW9uIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9ndC1pbmZvcm1hdGlvbic7XG5cbkBQaXBlKHtcblx0bmFtZTogJ2d0U2VhcmNoJ1xufSlcbmV4cG9ydCBjbGFzcyBHdFNlYXJjaFBpcGU8UiBleHRlbmRzIEd0Um93PiBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xuXHQvKiogUmV0dXJuIHByb3BlcnR5ICovXG5cdHByaXZhdGUgZ2V0UHJvcGVydHkgPSBmdW5jdGlvbihhcnJheTogQXJyYXk8YW55Piwga2V5OiBzdHJpbmcpIHtcblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRpZiAoYXJyYXlbaV0ub2JqZWN0S2V5ID09PSBrZXkpIHtcblx0XHRcdFx0cmV0dXJuIGFycmF5W2ldO1xuXHRcdFx0fVxuXHRcdH1cblx0fTtcblxuXHR0cmFuc2Zvcm0oXG5cdFx0YWxsUm93czogYW55LFxuXHRcdHNlYXJjaFRlcm1zOiBzdHJpbmcsXG5cdFx0Z3RJbmZvOiBHdEluZm9ybWF0aW9uLFxuXHRcdHNldHRpbmdzOiBBcnJheTxHdENvbmZpZ1NldHRpbmc+LFxuXHRcdGZpZWxkczogQXJyYXk8R3RDb25maWdGaWVsZDxSLCBhbnk+Pixcblx0XHRyZWZyZXNoRGF0YTogbnVtYmVyXG5cdCk6IGFueSB7XG5cdFx0Ly8gIGlmIG5vIHNlYXJjaCB0ZXJtcyBhcmUgZGVmaW5lZC4uLlxuXHRcdGlmICghc2VhcmNoVGVybXMgfHwgc2VhcmNoVGVybXMucmVwbGFjZSgvXCIvZywgJycpLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0Ly8gLi4ucmV0dXJuIGFsbCByb3dzXG5cdFx0XHRjb25zdCBsZW5ndGggPSBhbGxSb3dzID09PSBudWxsID8gMCA6IGFsbFJvd3MubGVuZ3RoO1xuXHRcdFx0Z3RJbmZvLnJlY29yZHNBZnRlclNlYXJjaCA9IGxlbmd0aDtcblx0XHRcdHJldHVybiBhbGxSb3dzO1xuXHRcdH1cblxuXHRcdGNvbnN0IHNlYXJjaEZ1bmN0aW9uOiBhbnkgPSB7fTtcblx0XHRjb25zdCBmaWVsZHNUZW1wOiBBcnJheTxhbnk+ID0gW107XG5cblx0XHRmb3IgKGxldCBrID0gMDsgayA8IGZpZWxkcy5sZW5ndGg7IGsrKykge1xuXHRcdFx0Y29uc3QgZmllbGQgPSBmaWVsZHNba107XG5cblx0XHRcdC8vIGNoZWNrIGlmIGZpZWxkIHNob3VsZCBiZSBpbmNsdWRlZCBpbiBnbG9iYWwgc2VhcmNoXG5cdFx0XHRjb25zdCBpbmNsdWRlID1cblx0XHRcdFx0dGhpcy5nZXRQcm9wZXJ0eShzZXR0aW5ncywgZmllbGQub2JqZWN0S2V5KS5zZWFyY2ggPT09IGZhbHNlXG5cdFx0XHRcdFx0PyBmYWxzZVxuXHRcdFx0XHRcdDogdHJ1ZTtcblxuXHRcdFx0Ly8gaWYgaW5jbHVkZS4uLlxuXHRcdFx0aWYgKGluY2x1ZGUpIHtcblx0XHRcdFx0Ly8gLi4uYW5kIGlmIHNlYXJjaCBmdW5jdGlvbiBpcyBkZWZpbmVkLi4uXG5cdFx0XHRcdGlmICh0eXBlb2YgZmllbGQuc2VhcmNoID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0XHRcdFx0Ly8gLi4uYWRkIGl0IGFzIHNlYXJjaCBmdW5jdGlvbiBmb3IgZmllbGRcblx0XHRcdFx0XHRzZWFyY2hGdW5jdGlvbltmaWVsZC5vYmplY3RLZXldID0gZmllbGQuc2VhcmNoO1xuXHRcdFx0XHR9XG5cdFx0XHRcdC8vIC4uLmlmIG5vIHNlYXJjaCBmdW5jdGlvbiBpcyBkZWZpbmVkIGJ1dCB2YWx1ZSBmdW5jdGlvbiBpcyBkZWZpbmVkLi4uXG5cdFx0XHRcdGVsc2UgaWYgKHR5cGVvZiBmaWVsZC52YWx1ZSA9PT0gJ2Z1bmN0aW9uJykge1xuXHRcdFx0XHRcdC8vIC4uLmFkZCBpdCBhcyBzZWFyY2ggZnVuY3Rpb24gZm9yIGZpZWxkXG5cdFx0XHRcdFx0c2VhcmNoRnVuY3Rpb25bZmllbGQub2JqZWN0S2V5XSA9IGZpZWxkLnZhbHVlO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gLi4ucHVzaCBpdCB0byBvdXIgZmllbGRzIGFycmF5XG5cdFx0XHRcdGZpZWxkc1RlbXAucHVzaChmaWVsZCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Y29uc3QgZmlsdGVyZWRSb3dzOiBBcnJheTxhbnk+ID0gW107XG5cdFx0c2VhcmNoVGVybXMgPSB0eXBlb2Ygc2VhcmNoVGVybXMgPT09ICd1bmRlZmluZWQnID8gJycgOiBzZWFyY2hUZXJtcztcblx0XHRjb25zdCBzZWFyY2hUZXJtc0FycmF5ID0gc2VhcmNoVGVybXMudG9Mb3dlckNhc2UoKS5tYXRjaCgvKFwiLipcInxbXlxcc10rKS9nKTtcblxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgYWxsUm93cy5sZW5ndGg7IGkrKykge1xuXHRcdFx0Y29uc3Qgcm93ID0gYWxsUm93c1tpXTtcblx0XHRcdGxldCBzdHJpbmcgPSAnJztcblxuXHRcdFx0Zm9yIChsZXQgaiA9IDA7IGogPCBmaWVsZHNUZW1wLmxlbmd0aDsgaisrKSB7XG5cdFx0XHRcdGNvbnN0IHNlcGFyYXRvciA9IGogPT09IDAgPyAnJyA6ICcgJiAnO1xuXHRcdFx0XHRzdHJpbmcgKz0gc2VhcmNoRnVuY3Rpb25bZmllbGRzVGVtcFtqXS5vYmplY3RLZXldXG5cdFx0XHRcdFx0PyBzZXBhcmF0b3IgKyBzZWFyY2hGdW5jdGlvbltmaWVsZHNUZW1wW2pdLm9iamVjdEtleV0ocm93LCBqKVxuXHRcdFx0XHRcdDogc2VwYXJhdG9yICsgcm93W2ZpZWxkc1RlbXBbal0ub2JqZWN0S2V5XTtcblx0XHRcdH1cblx0XHRcdHN0cmluZyA9IHN0cmluZy50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0bGV0IG1hdGNoOiBCb29sZWFuID0gdHJ1ZTtcblxuXHRcdFx0Zm9yIChsZXQgayA9IDA7IGsgPCBzZWFyY2hUZXJtc0FycmF5Lmxlbmd0aDsgaysrKSB7XG5cdFx0XHRcdGNvbnN0IHRlcm0gPSBzZWFyY2hUZXJtc0FycmF5W2tdLnJlcGxhY2UoL1wiL2csICcnKTtcblx0XHRcdFx0bWF0Y2ggPSBzdHJpbmcuaW5kZXhPZih0ZXJtKSAhPT0gLTE7XG5cblx0XHRcdFx0aWYgKCFtYXRjaCkge1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRpZiAobWF0Y2gpIHtcblx0XHRcdFx0ZmlsdGVyZWRSb3dzLnB1c2gocm93KTtcblx0XHRcdH1cblx0XHR9XG5cdFx0Z3RJbmZvLnJlY29yZHNBZnRlclNlYXJjaCA9IGZpbHRlcmVkUm93cy5sZW5ndGg7XG5cdFx0Ly8gZ3RJbmZvLnJlZnJlc2goZmlsdGVyZWRSb3dzLmxlbmd0aCxndCk7XG5cdFx0cmV0dXJuIGZpbHRlcmVkUm93cztcblx0fVxufVxuIiwiaW1wb3J0IHsgUGlwZSwgUGlwZVRyYW5zZm9ybSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5AUGlwZSh7XG5cdG5hbWU6ICdndElzRWRpdGFibGUnXG59KVxuZXhwb3J0IGNsYXNzIEd0SXNFZGl0YWJsZVBpcGUgaW1wbGVtZW50cyBQaXBlVHJhbnNmb3JtIHtcblx0dHJhbnNmb3JtKHByb3BlcnR5OiBhbnksIHJvdzogYW55LCByZWZyZXNoUGlwZTogYm9vbGVhbik6IGJvb2xlYW4ge1xuXHRcdGlmICh0eXBlb2YgcHJvcGVydHkgPT09ICdmdW5jdGlvbicpIHtcblx0XHRcdHJldHVybiBwcm9wZXJ0eShyb3cpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHR9XG59XG4iLCJpbXBvcnQgeyBQaXBlLCBQaXBlVHJhbnNmb3JtIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5cbkBQaXBlKHtcblx0bmFtZTogJ2d0SXNPYnNlcnZhYmxlJ1xufSlcbmV4cG9ydCBjbGFzcyBHdElzT2JzZXJ2YWJsZVBpcGUgaW1wbGVtZW50cyBQaXBlVHJhbnNmb3JtIHtcblx0dHJhbnNmb3JtKGlucHV0OiBhbnkpOiBib29sZWFuIHtcblx0XHRyZXR1cm4gaW5wdXQgaW5zdGFuY2VvZiBPYnNlcnZhYmxlO1xuXHR9XG59XG4iLCJpbXBvcnQgeyBQaXBlLCBQaXBlVHJhbnNmb3JtIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBEb21TYW5pdGl6ZXIsIFNhZmVIdG1sIH0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlcic7XG5cbkBQaXBlKHtcblx0bmFtZTogJ2d0SGlnaGxpZ2h0J1xufSlcbmV4cG9ydCBjbGFzcyBHdEhpZ2hsaWdodFBpcGUgaW1wbGVtZW50cyBQaXBlVHJhbnNmb3JtIHtcblx0Y29uc3RydWN0b3IocHJpdmF0ZSBzYW5pdGl6ZXI6IERvbVNhbml0aXplcikge31cblxuXHR0cmFuc2Zvcm0odGV4dDogc3RyaW5nLCBzZWFyY2hUZXJtOiBzdHJpbmcpOiBTYWZlSHRtbCB7XG5cdFx0Y29uc3QgaGF5c3RhY2tBbHdheXNTdHJpbmcgPSB0ZXh0ICsgJyc7XG5cdFx0bGV0IGhpZ2hsaWdodGVkVGV4dCA9IGhheXN0YWNrQWx3YXlzU3RyaW5nOyAvLyBmYWxsYmFja1xuXG5cdFx0bGV0IHNlYXJjaFBhdHRlcm47XG5cdFx0dHJ5IHtcblx0XHRcdHNlYXJjaFBhdHRlcm4gPSBuZXcgUmVnRXhwKFxuXHRcdFx0XHQnKCcgK1xuXHRcdFx0XHRzZWFyY2hUZXJtXG5cdFx0XHRcdFx0LnRvTG93ZXJDYXNlKClcblx0XHRcdFx0XHQubWF0Y2goL1wiLio/XCJ8W14gXSsvZykgLy8gZXh0cmFjdCB3b3Jkc1xuXHRcdFx0XHRcdC5tYXAoXG5cdFx0XHRcdFx0XHRuZWVkbGUgPT4gbmVlZGxlLnJlcGxhY2UoL1wiKC4qPylcIi8sICckMScpIC8vIHN0cmlwIGF3YXkgJ1wiJ1xuXHRcdFx0XHRcdClcblx0XHRcdFx0XHQuam9pbignfCcpICsgLy8gY29tYmluZSB3b3Jkc1xuXHRcdFx0XHRcdCcpJyxcblx0XHRcdFx0J2lnJ1xuXHRcdFx0KTtcblx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0cmV0dXJuIHRoaXMuc2FuaXRpemVyLmJ5cGFzc1NlY3VyaXR5VHJ1c3RIdG1sKGhpZ2hsaWdodGVkVGV4dCk7XG5cdFx0fVxuXG5cdFx0Y29uc3QgY29udGFpbnNUYWdQYXR0ZXJuID0gLyg8Lio/PikoLiopKDxcXC8uKj8+KS9naTtcblx0XHRjb25zdCBjb250YWluc1RhZ01hdGNoZXMgPSBjb250YWluc1RhZ1BhdHRlcm4uZXhlYyhoYXlzdGFja0Fsd2F5c1N0cmluZyk7XG5cblx0XHRpZiAoY29udGFpbnNUYWdNYXRjaGVzKSB7XG5cdFx0XHQvLyB0YWcgZXhpc3RzIGluIGhheXN0YWNrXG5cdFx0XHRoaWdobGlnaHRlZFRleHQgPVxuXHRcdFx0XHRjb250YWluc1RhZ01hdGNoZXNbMV0gK1xuXHRcdFx0XHRjb250YWluc1RhZ01hdGNoZXNbMl0ucmVwbGFjZShcblx0XHRcdFx0XHRzZWFyY2hQYXR0ZXJuLFxuXHRcdFx0XHRcdCc8c3BhbiBjbGFzcz1cImd0LWhpZ2hsaWdodC1zZWFyY2hcIj4kMTwvc3Bhbj4nXG5cdFx0XHRcdCkgK1xuXHRcdFx0XHRjb250YWluc1RhZ01hdGNoZXNbM107XG5cdFx0fSBlbHNlIHtcblx0XHRcdGhpZ2hsaWdodGVkVGV4dCA9IGhheXN0YWNrQWx3YXlzU3RyaW5nLnJlcGxhY2UoXG5cdFx0XHRcdHNlYXJjaFBhdHRlcm4sXG5cdFx0XHRcdCc8c3BhbiBjbGFzcz1cImd0LWhpZ2hsaWdodC1zZWFyY2hcIj4kMTwvc3Bhbj4nXG5cdFx0XHQpO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLnNhbml0aXplci5ieXBhc3NTZWN1cml0eVRydXN0SHRtbChoaWdobGlnaHRlZFRleHQpO1xuXHR9XG59XG4iLCJpbXBvcnQgeyBQaXBlLCBQaXBlVHJhbnNmb3JtIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBHdENvbmZpZ0ZpZWxkIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9ndC1jb25maWctZmllbGQnO1xuaW1wb3J0IHsgR3RSb3cgfSBmcm9tICcuLi9pbnRlcmZhY2VzL2d0LXJvdyc7XG5cbkBQaXBlKHtcblx0bmFtZTogJ2d0Q29sdW1uQ2xhc3MnXG59KVxuZXhwb3J0IGNsYXNzIEd0Q29sdW1uQ2xhc3NQaXBlIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XG5cdHRyYW5zZm9ybShcblx0XHRndEZpZWxkczogQXJyYXk8R3RDb25maWdGaWVsZDxhbnksIGFueT4+LFxuXHRcdGNvbHVtbjogR3RDb25maWdGaWVsZDxHdFJvdywgYW55Pixcblx0XHRyb3c/OiBHdFJvd1xuXHQpOiBhbnkge1xuXHRcdC8vIGZpbmQgY29sdW1ucyB3aXRoIGNvbHVtbkNsYXNzIHByb3BlcnR5IGRlZmluZWRcblx0XHRjb25zdCBDT0xVTU5fV0lUSF9DTEFTUyA9IGd0RmllbGRzXG5cdFx0XHQubWFwKGZpZWxkID0+IGZpZWxkKVxuXHRcdFx0LmZpbHRlcihcblx0XHRcdFx0ZmllbGQgPT4gZmllbGQuY29sdW1uQ2xhc3MgJiYgZmllbGQub2JqZWN0S2V5ID09PSBjb2x1bW4ub2JqZWN0S2V5XG5cdFx0XHQpWzBdO1xuXHRcdGlmICghQ09MVU1OX1dJVEhfQ0xBU1MpIHtcblx0XHRcdHJldHVybjtcblx0XHR9IGVsc2UgaWYgKHR5cGVvZiBDT0xVTU5fV0lUSF9DTEFTUy5jb2x1bW5DbGFzcyA9PT0gJ2Z1bmN0aW9uJykge1xuXHRcdFx0Ly8gaWYgY29sdW1uIGNsYXNzIGlzIGEgZnVuY3Rpb24sIHRyeSB1c2luZyB0aGUgZnVuY3Rpb24uLi5cblx0XHRcdHRyeSB7XG5cdFx0XHRcdHJldHVybiBDT0xVTU5fV0lUSF9DTEFTUy5jb2x1bW5DbGFzcyhyb3csIGNvbHVtbik7XG5cdFx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0XHRjb25zb2xlLmxvZyhcblx0XHRcdFx0XHQnRXJyb3Igd2hlbiB0cnlpbmcgdG8gZ2V0IGNvbHVtbiBjbGFzcyBuYW1lIHVzaW5nIGZvcm11bGEuJyxcblx0XHRcdFx0XHRlcnJvclxuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBpZiBub3QgYSBmdW5jdGlvbiwgcmV0dXJuIHBsYWluIHN0cmluZyB2YWx1ZVxuXHRcdFx0cmV0dXJuIENPTFVNTl9XSVRIX0NMQVNTLmNvbHVtbkNsYXNzO1xuXHRcdH1cblx0fVxufVxuIiwiaW1wb3J0IHsgUGlwZSwgUGlwZVRyYW5zZm9ybSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgR3RDb25maWdGaWVsZCB9IGZyb20gJy4uL2ludGVyZmFjZXMvZ3QtY29uZmlnLWZpZWxkJztcblxuQFBpcGUoe1xuXHRuYW1lOiAnZ3RSb3dDbGFzcydcbn0pXG5leHBvcnQgY2xhc3MgR3RSb3dDbGFzc1BpcGUgaW1wbGVtZW50cyBQaXBlVHJhbnNmb3JtIHtcblx0dHJhbnNmb3JtKGFycmF5OiBBcnJheTxhbnk+LCBndEZpZWxkczogQXJyYXk8R3RDb25maWdGaWVsZDxhbnksIGFueT4+KTogYW55IHtcblx0XHRpZiAoYXJyYXkpIHtcblx0XHRcdC8vIGZpbmQgY29sdW1ucyB3aXRoIHJvd0NsYXNzIHByb3BlcnR5IGRlZmluZWRcblx0XHRcdGNvbnN0IENPTFVNTlNfV0lUSF9DTEFTUyA9IGd0RmllbGRzXG5cdFx0XHRcdC5tYXAoY29sdW1uID0+IGNvbHVtbilcblx0XHRcdFx0LmZpbHRlcihjb2x1bW4gPT4gY29sdW1uLnJvd0NsYXNzKTtcblx0XHRcdENPTFVNTlNfV0lUSF9DTEFTUy5tYXAoY29sdW1uID0+IHtcblx0XHRcdFx0Ly8gZm9yIGVhY2ggY29sdW1uIHdpdGggcm93Q2xhc3MgcHJvcGVydHkgZGVmaW5lZC4uLlxuXHRcdFx0XHRhcnJheS5tYXAocm93ID0+IHtcblx0XHRcdFx0XHQvLyBsb29wIHRocm91Z2ggcm93cyBhbmQgc2V0IHJvdyBjbGFzc1xuXHRcdFx0XHRcdGlmICh0eXBlb2YgY29sdW1uLnJvd0NsYXNzID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0XHRcdFx0XHQvLyBpZiByb3cgY2xhc3MgaXMgYSBmdW5jdGlvbiwgdHJ5IHVzaW5nIHRoZSBmdW5jdGlvbi4uLlxuXHRcdFx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRcdFx0aWYgKHJvdy4kJGd0Um93Q2xhc3MpIHtcblx0XHRcdFx0XHRcdFx0XHRyb3cuJCRndFJvd0NsYXNzID0gcm93LiQkZ3RSb3dDbGFzcy5jb25jYXQoXG5cdFx0XHRcdFx0XHRcdFx0XHQnICcgKyBjb2x1bW4ucm93Q2xhc3Mocm93LCBjb2x1bW4pXG5cdFx0XHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRyb3cuJCRndFJvd0NsYXNzID0gY29sdW1uLnJvd0NsYXNzKHJvdywgY29sdW1uKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRcdFx0XHRcdFx0Y29uc29sZS5sb2coXG5cdFx0XHRcdFx0XHRcdFx0J0Vycm9yIHdoZW4gdHJ5aW5nIHRvIGdldCByb3cgY2xhc3MgbmFtZSB1c2luZyBmb3JtdWxhLicsXG5cdFx0XHRcdFx0XHRcdFx0ZXJyb3Jcblx0XHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0Ly8gaWYgbm90IGEgZnVuY3Rpb24sIHJldHVybiBwbGFpbiBzdHJpbmcgdmFsdWVcblx0XHRcdFx0XHRcdGlmIChyb3cuJCRndFJvd0NsYXNzKSB7XG5cdFx0XHRcdFx0XHRcdHJvdy4kJGd0Um93Q2xhc3MgPSByb3cuJCRndFJvd0NsYXNzLmNvbmNhdCgnICcgKyBjb2x1bW4ucm93Q2xhc3MpO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0cm93LiQkZ3RSb3dDbGFzcyA9IGNvbHVtbi5yb3dDbGFzcztcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHRcdHJldHVybiBhcnJheTtcblx0fVxufVxuIiwiaW1wb3J0IHsgUGlwZSwgUGlwZVRyYW5zZm9ybSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgR3RDb25maWdUb3RhbCB9IGZyb20gJy4uL2ludGVyZmFjZXMvZ3QtY29uZmlnLXRvdGFsJztcblxuQFBpcGUoe1xuXHRuYW1lOiAnZ3RUb3RhbHNQb3NpdGlvbidcbn0pXG5leHBvcnQgY2xhc3MgR3RUb3RhbHNQb3NpdGlvblBpcGUgaW1wbGVtZW50cyBQaXBlVHJhbnNmb3JtIHtcblx0dHJhbnNmb3JtKFxuXHRcdGFycmF5OiBBcnJheTxHdENvbmZpZ1RvdGFsPixcblx0XHRwb3NpdGlvbjogJ2hlYWRlcicgfCAnZm9vdGVyJyA9ICdoZWFkZXInXG5cdCk6IEFycmF5PGFueT4ge1xuXHRcdHJldHVybiBhcnJheS5maWx0ZXIodG90YWwgPT4ge1xuXHRcdFx0Ly8gaWYgbm8gcG9zaXRpb24gaXMgZGVmaW5lZCBhc3N1bWUgcG9zaXRpb24gdG8gYmUgaGVhZGVyXG5cdFx0XHRjb25zdCB0b3RhbFBvc2l0aW9uID0gdG90YWwucG9zaXRpb24gPyB0b3RhbC5wb3NpdGlvbiA6ICdoZWFkZXInO1xuXHRcdFx0cmV0dXJuIHRvdGFsUG9zaXRpb24gPT09IHBvc2l0aW9uO1xuXHRcdH0pO1xuXHR9XG59XG4iLCJpbXBvcnQgeyBQaXBlLCBQaXBlVHJhbnNmb3JtIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbkBQaXBlKHtcblx0bmFtZTogJ2d0VG90YWxzJ1xufSlcbmV4cG9ydCBjbGFzcyBHdFRvdGFsc1BpcGUgaW1wbGVtZW50cyBQaXBlVHJhbnNmb3JtIHtcblx0dHJhbnNmb3JtKFxuXHRcdHZhbHVlOiBzdHJpbmcgfCBudW1iZXIgfCBGdW5jdGlvbixcblx0XHRkYXRhOiBBcnJheTxhbnk+LFxuXHRcdG9iamVjdEtleTogc3RyaW5nLFxuXHRcdHJlZnJlc2g6IGJvb2xlYW5cblx0KTogYW55IHtcblx0XHRsZXQgb3V0cHV0O1xuXG5cdFx0aWYgKGRhdGEubGVuZ3RoID09PSAwKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJykge1xuXHRcdFx0b3V0cHV0ID0gdmFsdWUoZGF0YSwgb2JqZWN0S2V5KTtcblx0XHR9IGVsc2UgaWYgKHZhbHVlKSB7XG5cdFx0XHRvdXRwdXQgPSB2YWx1ZTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0b3V0cHV0ID0gJyc7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG91dHB1dDtcblx0fVxufVxuIiwiaW1wb3J0IHsgUGlwZSwgUGlwZVRyYW5zZm9ybSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgR3RDb25maWdGaWVsZCB9IGZyb20gJy4uL2ludGVyZmFjZXMvZ3QtY29uZmlnLWZpZWxkJztcbmltcG9ydCB7IEd0Um93IH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9ndC1yb3cnO1xuXG5AUGlwZSh7XG5cdG5hbWU6ICdndE9yZGVyQnknXG59KVxuZXhwb3J0IGNsYXNzIEd0T3JkZXJCeVBpcGU8UiBleHRlbmRzIEd0Um93PiBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xuXHRzdGF0aWMgX29yZGVyQnlDb21wYXJhdG9yKGE6IGFueSwgYjogYW55KTogbnVtYmVyIHtcblx0XHQvLyBzb3J0IGJvb2xlYW4gdmFsdWVzIGFzIHN0cmluZ3Ncblx0XHRpZiAodHlwZW9mIGEgPT09ICdib29sZWFuJykge1xuXHRcdFx0YSA9IGEudG9TdHJpbmcoKTtcblx0XHR9XG5cdFx0aWYgKHR5cGVvZiBiID09PSAnYm9vbGVhbicpIHtcblx0XHRcdGIgPSBiLnRvU3RyaW5nKCk7XG5cdFx0fVxuXG5cdFx0aWYgKFxuXHRcdFx0aXNOYU4ocGFyc2VGbG9hdChhKSkgfHxcblx0XHRcdCFpc0Zpbml0ZShhKSB8fFxuXHRcdFx0KGlzTmFOKHBhcnNlRmxvYXQoYikpIHx8ICFpc0Zpbml0ZShiKSlcblx0XHQpIHtcblx0XHRcdGlmIChcblx0XHRcdFx0YiA9PT0gbnVsbCB8fFxuXHRcdFx0XHQodHlwZW9mIGIgPT09ICd1bmRlZmluZWQnICYmIChhICE9PSBudWxsICYmIHR5cGVvZiBhICE9PSAndW5kZWZpbmVkJykpXG5cdFx0XHQpIHtcblx0XHRcdFx0cmV0dXJuIDE7XG5cdFx0XHR9XG5cdFx0XHRpZiAoXG5cdFx0XHRcdGEgPT09IG51bGwgfHxcblx0XHRcdFx0KHR5cGVvZiBhID09PSAndW5kZWZpbmVkJyAmJiAoYiAhPT0gbnVsbCAmJiB0eXBlb2YgYiAhPT0gJ3VuZGVmaW5lZCcpKVxuXHRcdFx0KSB7XG5cdFx0XHRcdHJldHVybiAtMTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gaXNuJ3QgYSBudW1iZXIgc28gbG93ZXJjYXNlIHRoZSBzdHJpbmcgdG8gcHJvcGVybHkgY29tcGFyZVxuXHRcdFx0dHJ5IHtcblx0XHRcdFx0aWYgKGEudG9Mb3dlckNhc2UoKSA8IGIudG9Mb3dlckNhc2UoKSkge1xuXHRcdFx0XHRcdHJldHVybiAtMTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoYS50b0xvd2VyQ2FzZSgpID4gYi50b0xvd2VyQ2FzZSgpKSB7XG5cdFx0XHRcdFx0cmV0dXJuIDE7XG5cdFx0XHRcdH1cblx0XHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHRcdHJldHVybiAwO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBwYXJzZSBzdHJpbmdzIGFzIG51bWJlcnMgdG8gY29tcGFyZSBwcm9wZXJseVxuXHRcdFx0aWYgKHBhcnNlRmxvYXQoYSkgPCBwYXJzZUZsb2F0KGIpKSB7XG5cdFx0XHRcdHJldHVybiAtMTtcblx0XHRcdH1cblx0XHRcdGlmIChwYXJzZUZsb2F0KGEpID4gcGFyc2VGbG9hdChiKSkge1xuXHRcdFx0XHRyZXR1cm4gMTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gMDsgLy8gZXF1YWwgZWFjaCBvdGhlclxuXHR9XG5cblx0LyoqIFJldHVybiBwcm9wZXJ0eSAqL1xuXHRwcml2YXRlIGdldFByb3BlcnR5ID0gZnVuY3Rpb24oYXJyYXk6IEFycmF5PGFueT4sIGtleTogc3RyaW5nKSB7XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykge1xuXHRcdFx0aWYgKGFycmF5W2ldLm9iamVjdEtleSA9PT0ga2V5KSB7XG5cdFx0XHRcdHJldHVybiBhcnJheVtpXTtcblx0XHRcdH1cblx0XHR9XG5cdH07XG5cblx0LyoqIFJldHVybiBzb3J0IGZ1bmN0aW9uICovXG5cdHByaXZhdGUgZ2V0U29ydEZ1bmN0aW9uKGZpZWxkOiBhbnkpIHtcblx0XHRpZiAoIWZpZWxkKSB7XG5cdFx0XHQvLyBjb25zb2xlLmxvZygnZXJyb3IgdHJ5aW5nIHRvIHNvcnQgdW5kZWZpbmVkIGZpZWxkJyk7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHRcdGlmICh0eXBlb2YgZmllbGQuc29ydCA9PT0gJ2Z1bmN0aW9uJykge1xuXHRcdFx0cmV0dXJuIGZpZWxkLnNvcnQ7XG5cdFx0fSBlbHNlIGlmICh0eXBlb2YgZmllbGQudmFsdWUgPT09ICdmdW5jdGlvbicpIHtcblx0XHRcdHJldHVybiBmaWVsZC52YWx1ZTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fVxuXG5cdHRyYW5zZm9ybShcblx0XHRpbnB1dDogYW55LFxuXHRcdHNvcnRCeVByb3BlcnRpZXM6IEFycmF5PHN0cmluZz4sXG5cdFx0ZmllbGRzOiBHdENvbmZpZ0ZpZWxkPFIsIGFueT5bXSxcblx0XHRyZWZyZXNoU29ydGluZzogYm9vbGVhbixcblx0XHRyZWZyZXNoRGF0YTogbnVtYmVyXG5cdCk6IGFueSB7XG5cdFx0aWYgKCFBcnJheS5pc0FycmF5KGlucHV0KSB8fCBpbnB1dCA9PT0gbnVsbCkge1xuXHRcdFx0cmV0dXJuIGlucHV0O1xuXHRcdH1cblx0XHRpZiAoXG5cdFx0XHQhQXJyYXkuaXNBcnJheShzb3J0QnlQcm9wZXJ0aWVzKSB8fFxuXHRcdFx0KEFycmF5LmlzQXJyYXkoc29ydEJ5UHJvcGVydGllcykgJiYgc29ydEJ5UHJvcGVydGllcy5sZW5ndGggPT09IDEpXG5cdFx0KSB7XG5cdFx0XHRjb25zdCBwcm9wZXJ0eVRvQ2hlY2s6IHN0cmluZyA9IHNvcnRCeVByb3BlcnRpZXNbMF07XG5cdFx0XHRjb25zdCBkZXNjID0gcHJvcGVydHlUb0NoZWNrLnN1YnN0cigwLCAxKSA9PT0gJy0nO1xuXG5cdFx0XHQvLyBiYXNpYyBhcnJheVxuXHRcdFx0aWYgKFxuXHRcdFx0XHQhcHJvcGVydHlUb0NoZWNrIHx8XG5cdFx0XHRcdHByb3BlcnR5VG9DaGVjayA9PT0gJy0nIHx8XG5cdFx0XHRcdHByb3BlcnR5VG9DaGVjayA9PT0gJysnXG5cdFx0XHQpIHtcblx0XHRcdFx0cmV0dXJuICFkZXNjID8gaW5wdXQuc29ydCgpIDogaW5wdXQuc29ydCgpLnJldmVyc2UoKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGNvbnN0IHByb3BlcnR5OiBzdHJpbmcgPVxuXHRcdFx0XHRcdHByb3BlcnR5VG9DaGVjay5zdWJzdHIoMCwgMSkgPT09ICcrJyB8fFxuXHRcdFx0XHRcdHByb3BlcnR5VG9DaGVjay5zdWJzdHIoMCwgMSkgPT09ICctJ1xuXHRcdFx0XHRcdFx0PyBwcm9wZXJ0eVRvQ2hlY2suc3Vic3RyKDEpXG5cdFx0XHRcdFx0XHQ6IHByb3BlcnR5VG9DaGVjaztcblxuXHRcdFx0XHQvLyBjaGVjayBpZiBjdXN0b20gc29ydCBmdW5jdGlvbiBpcyBkZWZpbmVkXG5cdFx0XHRcdGNvbnN0IHNvcnRGdW5jdGlvbjogYW55ID0gdGhpcy5nZXRTb3J0RnVuY3Rpb24oXG5cdFx0XHRcdFx0dGhpcy5nZXRQcm9wZXJ0eShmaWVsZHMsIHByb3BlcnR5KVxuXHRcdFx0XHQpO1xuXG5cdFx0XHRcdC8vIGNvbnNvbGUubG9nKHByb3BlcnR5KTtcblx0XHRcdFx0cmV0dXJuIGlucHV0LnNvcnQoZnVuY3Rpb24oYTogYW55LCBiOiBhbnkpIHtcblx0XHRcdFx0XHQvLyB1c2UgY3VzdG9tIHNvcnQgZnVuY3Rpb24gaWYgb25lIGlzIGRlZmluZWRcblx0XHRcdFx0XHRjb25zdCBwcm9wZXJ0eUEgPVxuXHRcdFx0XHRcdFx0c29ydEZ1bmN0aW9uID09PSBmYWxzZVxuXHRcdFx0XHRcdFx0XHQ/IHByb3BlcnR5ID09PSAnJCRndFJvd0lkJ1xuXHRcdFx0XHRcdFx0XHRcdD8gK2EuJCRndFJvd0lkLnNwbGl0KCdfJylbMF1cblx0XHRcdFx0XHRcdFx0XHQ6IGFbcHJvcGVydHldXG5cdFx0XHRcdFx0XHRcdDogc29ydEZ1bmN0aW9uKGEpO1xuXHRcdFx0XHRcdGNvbnN0IHByb3BlcnR5QiA9XG5cdFx0XHRcdFx0XHRzb3J0RnVuY3Rpb24gPT09IGZhbHNlXG5cdFx0XHRcdFx0XHRcdD8gcHJvcGVydHkgPT09ICckJGd0Um93SWQnXG5cdFx0XHRcdFx0XHRcdFx0PyArYi4kJGd0Um93SWQuc3BsaXQoJ18nKVswXVxuXHRcdFx0XHRcdFx0XHRcdDogYltwcm9wZXJ0eV1cblx0XHRcdFx0XHRcdFx0OiBzb3J0RnVuY3Rpb24oYik7XG5cblx0XHRcdFx0XHQvLyBpZiBib3RoIHZhbHVlcyBhcmUgdW5kZWZpbmVkLi4uXG5cdFx0XHRcdFx0aWYgKFxuXHRcdFx0XHRcdFx0dHlwZW9mIHByb3BlcnR5QSA9PT0gJ3VuZGVmaW5lZCcgJiZcblx0XHRcdFx0XHRcdHR5cGVvZiBwcm9wZXJ0eUIgPT09ICd1bmRlZmluZWQnXG5cdFx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0XHQvLyAuLi5za2lwIGNvbXBhcmlzb25cblx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuICFkZXNjXG5cdFx0XHRcdFx0XHQ/IEd0T3JkZXJCeVBpcGUuX29yZGVyQnlDb21wYXJhdG9yKHByb3BlcnR5QSwgcHJvcGVydHlCKVxuXHRcdFx0XHRcdFx0OiAtR3RPcmRlckJ5UGlwZS5fb3JkZXJCeUNvbXBhcmF0b3IocHJvcGVydHlBLCBwcm9wZXJ0eUIpO1xuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gbG9vcCBvdmVyIHByb3BlcnR5IG9mIHRoZSBhcnJheSBpbiBvcmRlciBhbmQgc29ydFxuXHRcdFx0cmV0dXJuIGlucHV0LnNvcnQoKGE6IGFueSwgYjogYW55KSA9PiB7XG5cdFx0XHRcdC8vIGNvbnNvbGUubG9nKCdtdWx0aXBsZScpO1xuXHRcdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IHNvcnRCeVByb3BlcnRpZXMubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0XHRjb25zdCBkZXNjID0gc29ydEJ5UHJvcGVydGllc1tpXS5zdWJzdHIoMCwgMSkgPT09ICctJztcblx0XHRcdFx0XHRjb25zdCBwcm9wZXJ0eSA9XG5cdFx0XHRcdFx0XHRzb3J0QnlQcm9wZXJ0aWVzW2ldLnN1YnN0cigwLCAxKSA9PT0gJysnIHx8XG5cdFx0XHRcdFx0XHRzb3J0QnlQcm9wZXJ0aWVzW2ldLnN1YnN0cigwLCAxKSA9PT0gJy0nXG5cdFx0XHRcdFx0XHRcdD8gc29ydEJ5UHJvcGVydGllc1tpXS5zdWJzdHIoMSlcblx0XHRcdFx0XHRcdFx0OiBzb3J0QnlQcm9wZXJ0aWVzW2ldO1xuXG5cdFx0XHRcdFx0Ly8gY29uc29sZS5sb2cocHJvcGVydHkpO1xuXHRcdFx0XHRcdC8vIGNoZWNrIGlmIGN1c3RvbSBzb3J0IGZ1bmN0aW9uIGlzIGRlZmluZWRcblx0XHRcdFx0XHRjb25zdCBzb3J0RnVuY3Rpb246IGFueSA9IHRoaXMuZ2V0U29ydEZ1bmN0aW9uKFxuXHRcdFx0XHRcdFx0dGhpcy5nZXRQcm9wZXJ0eShmaWVsZHMsIHByb3BlcnR5KVxuXHRcdFx0XHRcdCk7XG5cblx0XHRcdFx0XHQvLyB1c2UgY3VzdG9tIHNvcnQgZnVuY3Rpb24gaWYgb25lIGlzIGRlZmluZWRcblx0XHRcdFx0XHRjb25zdCBwcm9wZXJ0eUEgPVxuXHRcdFx0XHRcdFx0c29ydEZ1bmN0aW9uID09PSBmYWxzZVxuXHRcdFx0XHRcdFx0XHQ/IHByb3BlcnR5ID09PSAnJCRndFJvd0lkJ1xuXHRcdFx0XHRcdFx0XHRcdD8gK2EuJCRndFJvd0lkLnNwbGl0KCdfJylbMF1cblx0XHRcdFx0XHRcdFx0XHQ6IGFbcHJvcGVydHldXG5cdFx0XHRcdFx0XHRcdDogc29ydEZ1bmN0aW9uKGEpO1xuXHRcdFx0XHRcdGNvbnN0IHByb3BlcnR5QiA9XG5cdFx0XHRcdFx0XHRzb3J0RnVuY3Rpb24gPT09IGZhbHNlXG5cdFx0XHRcdFx0XHRcdD8gcHJvcGVydHkgPT09ICckJGd0Um93SWQnXG5cdFx0XHRcdFx0XHRcdFx0PyArYi4kJGd0Um93SWQuc3BsaXQoJ18nKVswXVxuXHRcdFx0XHRcdFx0XHRcdDogYltwcm9wZXJ0eV1cblx0XHRcdFx0XHRcdFx0OiBzb3J0RnVuY3Rpb24oYik7XG5cblx0XHRcdFx0XHRjb25zdCBjb21wYXJpc29uID0gIWRlc2Ncblx0XHRcdFx0XHRcdD8gR3RPcmRlckJ5UGlwZS5fb3JkZXJCeUNvbXBhcmF0b3IocHJvcGVydHlBLCBwcm9wZXJ0eUIpXG5cdFx0XHRcdFx0XHQ6IC1HdE9yZGVyQnlQaXBlLl9vcmRlckJ5Q29tcGFyYXRvcihwcm9wZXJ0eUEsIHByb3BlcnR5Qik7XG5cblx0XHRcdFx0XHQvLyBkb24ndCByZXR1cm4gMCB5ZXQgaW4gY2FzZSBvZiBuZWVkaW5nIHRvIHNvcnQgYnkgbmV4dCBwcm9wZXJ0eVxuXHRcdFx0XHRcdGlmIChjb21wYXJpc29uICE9PSAwKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gY29tcGFyaXNvbjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gMDsgLy8gZXF1YWwgZWFjaCBvdGhlclxuXHRcdFx0fSk7XG5cdFx0fVxuXHR9XG59XG4iLCJpbXBvcnQgeyBQaXBlLCBQaXBlVHJhbnNmb3JtLCBFdmVudEVtaXR0ZXIsIE91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgR3RJbmZvcm1hdGlvbiB9IGZyb20gJy4uL2ludGVyZmFjZXMvZ3QtaW5mb3JtYXRpb24nO1xuXG5AUGlwZSh7XG5cdG5hbWU6ICdndEZpbHRlcidcbn0pXG5leHBvcnQgY2xhc3MgR3RGaWx0ZXJQaXBlIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XG5cdC8vIEBPdXRwdXQoKSBmaWx0ZXJJbmZvID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG5cdHRyYW5zZm9ybShcblx0XHRhbGxSb3dzOiBhbnlbXSxcblx0XHRmaWx0ZXJCeTogT2JqZWN0LFxuXHRcdGd0SW5mbzogR3RJbmZvcm1hdGlvbixcblx0XHRyZWZyZXNoRmlsdGVyOiBib29sZWFuLFxuXHRcdHJlZnJlc2hEYXRhOiBudW1iZXJcblx0KTogYW55W10ge1xuXHRcdC8vIGNvbnNvbGUubG9nKGFsbFJvd3MsZmlsdGVyQnkpO1xuXHRcdGd0SW5mby5yZWNvcmRzQWxsID0gYWxsUm93cy5sZW5ndGg7XG5cdFx0aWYgKCFBcnJheS5pc0FycmF5KGFsbFJvd3MpIHx8ICFmaWx0ZXJCeSkge1xuXHRcdFx0Ly8gZ3RJbmZvLmZpbHRlcmVkID0gZmFsc2U7XG5cblx0XHRcdGNvbnN0IGxlbmd0aCA9IGFsbFJvd3MgPT09IG51bGwgPyAwIDogYWxsUm93cy5sZW5ndGg7XG5cdFx0XHRndEluZm8ucmVjb3Jkc0FmdGVyRmlsdGVyID0gbGVuZ3RoO1xuXHRcdFx0cmV0dXJuIGFsbFJvd3M7XG5cdFx0fVxuXG5cdFx0Y29uc3Qgb3V0cHV0ID0gW107XG5cdFx0Zm9yIChsZXQgaSA9IDA7IGkgPCBhbGxSb3dzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRjb25zdCByb3dPYmplY3QgPSBhbGxSb3dzW2ldO1xuXHRcdFx0bGV0IG1hdGNoID0gdHJ1ZTtcblxuXHRcdFx0Zm9yIChjb25zdCBwcm9wZXJ0eSBpbiBmaWx0ZXJCeSkge1xuXHRcdFx0XHRpZiAoZmlsdGVyQnkuaGFzT3duUHJvcGVydHkocHJvcGVydHkpKSB7XG5cdFx0XHRcdFx0Ly8gY29uc29sZS5sb2cocHJvcGVydHkpO1xuXHRcdFx0XHRcdC8vIGNvbnNvbGUubG9nKGZpbHRlcltwcm9wZXJ0eV0uaW5kZXhPZihvYmpbcHJvcGVydHldKSk7XG5cdFx0XHRcdFx0aWYgKGZpbHRlckJ5W3Byb3BlcnR5XS5pbmRleE9mKHJvd09iamVjdFtwcm9wZXJ0eV0pID09PSAtMSkge1xuXHRcdFx0XHRcdFx0bWF0Y2ggPSBmYWxzZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGlmIChtYXRjaCkge1xuXHRcdFx0XHRvdXRwdXQucHVzaChyb3dPYmplY3QpO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRndEluZm8ucmVjb3Jkc0FmdGVyRmlsdGVyID0gb3V0cHV0Lmxlbmd0aDsgLy8gLmVtaXQob3V0cHV0Lmxlbmd0aCk7XG5cdFx0cmV0dXJuIG91dHB1dDtcblx0fVxufVxuIiwiaW1wb3J0IHsgUGlwZSwgUGlwZVRyYW5zZm9ybSwgRXZlbnRFbWl0dGVyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBHdEluZm9ybWF0aW9uIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9ndC1pbmZvcm1hdGlvbic7XG5pbXBvcnQgeyBHdEV2ZW50IH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9ndC1ldmVudCc7XG5cbkBQaXBlKHtcblx0bmFtZTogJ2d0Q2h1bmsnXG59KVxuZXhwb3J0IGNsYXNzIEd0Q2h1bmtQaXBlIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XG5cdHRyYW5zZm9ybShcblx0XHRhcnJheTogYW55W10sXG5cdFx0Z3RJbmZvOiBHdEluZm9ybWF0aW9uLFxuXHRcdGNodW5rU2l6ZTogbnVtYmVyLFxuXHRcdHBhZ2U6IG51bWJlcixcblx0XHRyZWZyZXNoUGFnZUFycmF5OiBib29sZWFuLFxuXHRcdHJlZnJlc2hEYXRhOiBudW1iZXIsXG5cdFx0Z3RFdmVudDogRXZlbnRFbWl0dGVyPEd0RXZlbnQ+LFxuXHRcdGRhdGE6IHsgZXhwb3J0RGF0YTogQXJyYXk8YW55PiB9XG5cdCk6IGFueVtdIHtcblx0XHRpZiAoIUFycmF5LmlzQXJyYXkoYXJyYXkpKSB7XG5cdFx0XHRyZXR1cm4gYXJyYXk7XG5cdFx0fVxuXHRcdGRhdGEuZXhwb3J0RGF0YSA9IGFycmF5OyAvLyBzdG9yZSBkYXRhIGZvciBleHBvcnRcblxuXHRcdGNvbnN0IFBBR0VTID0gW107XG5cdFx0Y29uc3QgRU5UUklFUyA9IGFycmF5Lmxlbmd0aDtcblxuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgRU5UUklFUzsgaSArPSBjaHVua1NpemUpIHtcblx0XHRcdFBBR0VTLnB1c2goYXJyYXkuc2xpY2UoaSwgaSArIGNodW5rU2l6ZSkpO1xuXHRcdH1cblx0XHRndEluZm8udmlzaWJsZVJlY29yZHMgPSAhUEFHRVNbcGFnZSAtIDFdID8gW10gOiBbLi4uUEFHRVNbcGFnZSAtIDFdXTsgLy8gYWRkIHZpc2libGUgcm93c1xuXHRcdGd0SW5mby5wYWdlVG90YWwgPSBQQUdFUy5sZW5ndGg7IC8vIGFkZCBudW1iZXIgb2YgcGFnZXNcblxuXHRcdHNldFRpbWVvdXQoXG5cdFx0XHQoKSA9PlxuXHRcdFx0XHRndEV2ZW50LmVtaXQoe1xuXHRcdFx0XHRcdG5hbWU6ICdndC1pbmZvJyxcblx0XHRcdFx0XHR2YWx1ZTogZ3RJbmZvXG5cdFx0XHRcdH0pLFxuXHRcdFx0MFxuXHRcdCk7XG5cdFx0cmV0dXJuIFBBR0VTW3BhZ2UgLSAxXTtcblx0fVxufVxuIiwiaW1wb3J0IHsgUGlwZSwgUGlwZVRyYW5zZm9ybSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgR3RDb25maWdGaWVsZCB9IGZyb20gJy4uL2ludGVyZmFjZXMvZ3QtY29uZmlnLWZpZWxkJztcbmltcG9ydCB7IEd0Q29uZmlnU2V0dGluZyB9IGZyb20gJy4uL2ludGVyZmFjZXMvZ3QtY29uZmlnLXNldHRpbmcnO1xuaW1wb3J0IHsgR3RSb3cgfSBmcm9tICcuLi9pbnRlcmZhY2VzL2d0LXJvdyc7XG5cbkBQaXBlKHtcblx0bmFtZTogJ2d0UHJvcGVydHknXG59KVxuZXhwb3J0IGNsYXNzIEd0UHJvcGVydHlQaXBlPFIgZXh0ZW5kcyBHdFJvdz4gaW1wbGVtZW50cyBQaXBlVHJhbnNmb3JtIHtcblx0dHJhbnNmb3JtKFxuXHRcdGNvbmZpZzogR3RDb25maWdGaWVsZDxSLCBhbnk+W10gfCBHdENvbmZpZ1NldHRpbmdbXSxcblx0XHRvYmplY3RLZXk6IHN0cmluZyxcblx0XHRwcm9wZXJ0eTogc3RyaW5nLFxuXHRcdHJlZnJlc2g/OiBib29sZWFuXG5cdCk6IGFueSB7XG5cdFx0bGV0IG91dHB1dCA9IG51bGw7XG5cdFx0dHJ5IHtcblx0XHRcdGZvciAobGV0IGkgPSAwOyBpIDwgY29uZmlnLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdGlmIChjb25maWdbaV0ub2JqZWN0S2V5ID09PSBvYmplY3RLZXkpIHtcblx0XHRcdFx0XHRvdXRwdXQgPSBjb25maWdbaV1bcHJvcGVydHldO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRcdGNvbnNvbGUubG9nKFxuXHRcdFx0XHQnY2Fubm90IHJlYWQgcHJvcGVydHk6IFwiJyArXG5cdFx0XHRcdFx0cHJvcGVydHkgK1xuXHRcdFx0XHRcdCdcIiBvbiBtaXNzaW5nIGtleTogXCInICtcblx0XHRcdFx0XHRvYmplY3RLZXkgK1xuXHRcdFx0XHRcdCdcIiBpbiBjb25maWcuJyxcblx0XHRcdFx0ZXJyb3Jcblx0XHRcdCk7XG5cdFx0fVxuXHRcdHJldHVybiBvdXRwdXQ7XG5cdH1cbn1cbiIsImltcG9ydCB7IFBpcGUsIFBpcGVUcmFuc2Zvcm0gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuQFBpcGUoe1xuXHRuYW1lOiAnZGFzaENhc2UnXG59KVxuZXhwb3J0IGNsYXNzIERhc2hDYXNlUGlwZSBpbXBsZW1lbnRzIFBpcGVUcmFuc2Zvcm0ge1xuXHR0cmFuc2Zvcm0oc3RyaW5nOiBzdHJpbmcpOiBzdHJpbmcge1xuXHRcdHJldHVybiBzdHJpbmcucmVwbGFjZSgvKFthLXpdKShbQS1aXSkvZywgJyQxLSQyJykudG9Mb3dlckNhc2UoKTtcblx0fVxufVxuIiwiaW1wb3J0IHsgUGlwZSwgUGlwZVRyYW5zZm9ybSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgR3RDb25maWdTZXR0aW5nIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9ndC1jb25maWctc2V0dGluZyc7XG5pbXBvcnQgeyBHdENvbmZpZ0ZpZWxkIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9ndC1jb25maWctZmllbGQnO1xuaW1wb3J0IHsgRG9tU2FuaXRpemVyIH0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlcic7XG5pbXBvcnQgeyBHdFJvdyB9IGZyb20gJy4uL2ludGVyZmFjZXMvZ3Qtcm93JztcbmltcG9ydCB7IEd0UmVuZGVyRmllbGQgfSBmcm9tICcuLi9pbnRlcmZhY2VzL2d0LXJlbmRlci1maWVsZCc7XG5pbXBvcnQgeyBHdEhpZ2hsaWdodFBpcGUgfSBmcm9tICcuL2d0LWhpZ2hsaWdodC5waXBlJztcblxuQFBpcGUoe1xuXHRuYW1lOiAnZ3RSZW5kZXInXG59KVxuZXhwb3J0IGNsYXNzIEd0UmVuZGVyUGlwZTxSIGV4dGVuZHMgR3RSb3c+IGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XG5cdGNvbnN0cnVjdG9yKFxuXHRcdHByaXZhdGUgc2FuaXRpemVyOiBEb21TYW5pdGl6ZXIsXG5cdFx0cHJpdmF0ZSBndEhpZ2hsaWdodFBpcGU6IEd0SGlnaGxpZ2h0UGlwZVxuXHQpIHt9XG5cblx0Ly8gVE9ETzogbW92ZSB0byBoZWxwZXIgZnVuY3Rpb25zXG5cdC8qKiBTb3J0IGJ5IGNvbHVtbiBvcmRlciAqL1xuXHRwcml2YXRlIGdldENvbHVtbk9yZGVyID0gZnVuY3Rpb24oYTogR3RDb25maWdTZXR0aW5nLCBiOiBHdENvbmZpZ1NldHRpbmcpIHtcblx0XHRpZiAoYS5jb2x1bW5PcmRlciA8IGIuY29sdW1uT3JkZXIpIHtcblx0XHRcdHJldHVybiAtMTtcblx0XHR9XG5cdFx0aWYgKGEuY29sdW1uT3JkZXIgPiBiLmNvbHVtbk9yZGVyIHx8IHR5cGVvZiBhLmNvbHVtbk9yZGVyID09PSAndW5kZWZpbmVkJykge1xuXHRcdFx0cmV0dXJuIDE7XG5cdFx0fVxuXHRcdHJldHVybiAwO1xuXHR9O1xuXG5cdC8qKiBTb3J0IGJ5IGxlbmd0aCAqL1xuXHRwcml2YXRlIGdldE9yZGVyQnlMZW5ndGggPSBmdW5jdGlvbihhOiBhbnksIGI6IGFueSkge1xuXHRcdHJldHVybiBiLmxlbmd0aCAtIGEubGVuZ3RoO1xuXHR9O1xuXG5cdC8qKiBSZXR1cm4gcHJvcGVydHkgKi9cblx0cHJpdmF0ZSBnZXRQcm9wZXJ0eSA9IGZ1bmN0aW9uKGFycmF5OiBBcnJheTxhbnk+LCBrZXk6IHN0cmluZykge1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHtcblx0XHRcdGlmIChhcnJheVtpXS5vYmplY3RLZXkgPT09IGtleSkge1xuXHRcdFx0XHRyZXR1cm4gYXJyYXlbaV07XG5cdFx0XHR9XG5cdFx0fVxuXHR9O1xuXG5cdHRyYW5zZm9ybShcblx0XHRyb3c6IGFueSxcblx0XHRzZXR0aW5nczogQXJyYXk8R3RDb25maWdTZXR0aW5nPixcblx0XHRmaWVsZHM6IEFycmF5PEd0Q29uZmlnRmllbGQ8UiwgYW55Pj4sXG5cdFx0dXBkYXRlZDogYm9vbGVhbixcblx0XHRsb2FkaW5nOiBib29sZWFuLFxuXHRcdGhpZ2hsaWdodDogYm9vbGVhbiA9IGZhbHNlLFxuXHRcdHNlYXJjaFN0cmluZz86IHN0cmluZ1xuXHQpOiBBcnJheTxHdFJlbmRlckZpZWxkPFIsIGFueT4+IHtcblx0XHQvLyBsZXQgYXJyID0gW3tcInRlbXBcIjoxMjMsXCJuYW1lXCI6XCJoYXBweVwifSx7XCJ0ZW1wXCI6NDU2LFwibmFtZVwiOlwiZGZnZGZnXCJ9LHtcInRlbXBcIjo3ODksXCJuYW1lXCI6XCJhc2Rhc2RcIn1dO1xuXHRcdC8vIGNvbnNvbGUubG9nKGFycixhcnIubWFwKGZ1bmN0aW9uKGl0ZW0pe3JldHVybiBpdGVtLnRlbXB9KSk7XG5cdFx0Ly8gY29uc29sZS5sb2coc2V0dGluZ3MubWFwKCdvYmplY3RLZXknKSk7XG5cblx0XHQvLyBjb25zb2xlLmxvZygncmVuZGVyJyk7XG5cdFx0Y29uc3QgY29sdW1uczogQXJyYXk8c3RyaW5nPiA9IFtdO1xuXHRcdGZvciAobGV0IGkgPSAwOyBpIDwgc2V0dGluZ3MubGVuZ3RoOyBpKyspIHtcblx0XHRcdGlmIChzZXR0aW5nc1tpXS52aXNpYmxlICE9PSBmYWxzZSAmJiBzZXR0aW5nc1tpXS5lbmFibGVkICE9PSBmYWxzZSkge1xuXHRcdFx0XHRjb2x1bW5zLnB1c2goc2V0dGluZ3NbaV0ub2JqZWN0S2V5KTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGZpZWxkcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0Ly8gY29uc29sZS5sb2coIXJvd1tmaWVsZHNbaV0ub2JqZWN0S2V5XSk7XG5cdFx0XHRpZiAoXG5cdFx0XHRcdGZpZWxkc1tpXS52YWx1ZSAmJlxuXHRcdFx0XHR0eXBlb2YgZmllbGRzW2ldLnZhbHVlID09PSAnZnVuY3Rpb24nICYmXG5cdFx0XHRcdCFyb3cuaGFzT3duUHJvcGVydHkoZmllbGRzW2ldLm9iamVjdEtleSlcblx0XHRcdCkge1xuXHRcdFx0XHRyb3dbZmllbGRzW2ldLm9iamVjdEtleV0gPSBsb2FkaW5nID8gJycgOiBmaWVsZHNbaV0udmFsdWUocm93KTtcblx0XHRcdH1cblx0XHR9XG5cdFx0Ly8gY29uc29sZS5sb2cocm93KTtcblx0XHRjb25zdCBrZXlzOiBBcnJheTxhbnk+ID0gW107XG5cdFx0Zm9yIChjb25zdCBrZXkgaW4gcm93KSB7XG5cdFx0XHQvLyBjb25zb2xlLmxvZyhrZXkpO1xuXHRcdFx0aWYgKGNvbHVtbnMuaW5kZXhPZihrZXkpICE9PSAtMSkge1xuXHRcdFx0XHRsZXQgZmllbGRTZXR0aW5nO1xuXHRcdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGZpZWxkcy5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHRcdGlmIChmaWVsZHNbaV0ub2JqZWN0S2V5ID09PSBrZXkpIHtcblx0XHRcdFx0XHRcdGZpZWxkU2V0dGluZyA9IGZpZWxkc1tpXTtcblx0XHRcdFx0XHRcdC8vIGNvbnNvbGUubG9nKGZpZWxkU2V0dGluZyk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Y29uc3QgY29sdW1uT2JqZWN0OiBHdFJlbmRlckZpZWxkPFIsIGFueT4gPSB7XG5cdFx0XHRcdFx0b2JqZWN0S2V5OiBrZXksXG5cdFx0XHRcdFx0c29ydFZhbHVlOiByb3dba2V5XVxuXHRcdFx0XHR9O1xuXG5cdFx0XHRcdC8vIGFkZCBjb21wb25lbnQgaWYgZGVmaW5lZFxuXHRcdFx0XHRpZiAoZmllbGRTZXR0aW5nLmNvbHVtbkNvbXBvbmVudCkge1xuXHRcdFx0XHRcdGNvbHVtbk9iamVjdC5jb2x1bW5Db21wb25lbnQgPSBmaWVsZFNldHRpbmcuY29sdW1uQ29tcG9uZW50O1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKGxvYWRpbmcpIHtcblx0XHRcdFx0XHRjb2x1bW5PYmplY3QucmVuZGVyVmFsdWUgPSByb3dba2V5XSAhPT0gbnVsbCA/IHJvd1trZXldIDogJyc7XG5cdFx0XHRcdH0gZWxzZSBpZiAoXG5cdFx0XHRcdFx0aGlnaGxpZ2h0ICYmXG5cdFx0XHRcdFx0c2VhcmNoU3RyaW5nICYmXG5cdFx0XHRcdFx0dGhpcy5nZXRQcm9wZXJ0eShzZXR0aW5ncywga2V5KS5zZWFyY2ggIT09IGZhbHNlXG5cdFx0XHRcdCkge1xuXHRcdFx0XHRcdGNvbHVtbk9iamVjdC5yZW5kZXJWYWx1ZSA9XG5cdFx0XHRcdFx0XHRmaWVsZFNldHRpbmcucmVuZGVyICYmIHR5cGVvZiBmaWVsZFNldHRpbmcucmVuZGVyID09PSAnZnVuY3Rpb24nXG5cdFx0XHRcdFx0XHRcdD8gdGhpcy5ndEhpZ2hsaWdodFBpcGUudHJhbnNmb3JtKFxuXHRcdFx0XHRcdFx0XHRcdFx0ZmllbGRTZXR0aW5nLnJlbmRlcihyb3cpLFxuXHRcdFx0XHRcdFx0XHRcdFx0c2VhcmNoU3RyaW5nXG5cdFx0XHRcdFx0XHRcdCAgKVxuXHRcdFx0XHRcdFx0XHQ6IHRoaXMuZ3RIaWdobGlnaHRQaXBlLnRyYW5zZm9ybShcblx0XHRcdFx0XHRcdFx0XHRcdHJvd1trZXldICE9PSBudWxsID8gcm93W2tleV0gOiAnJyxcblx0XHRcdFx0XHRcdFx0XHRcdHNlYXJjaFN0cmluZ1xuXHRcdFx0XHRcdFx0XHQgICk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Y29sdW1uT2JqZWN0LnJlbmRlclZhbHVlID1cblx0XHRcdFx0XHRcdGZpZWxkU2V0dGluZy5yZW5kZXIgJiYgdHlwZW9mIGZpZWxkU2V0dGluZy5yZW5kZXIgPT09ICdmdW5jdGlvbidcblx0XHRcdFx0XHRcdFx0PyB0aGlzLnNhbml0aXplci5ieXBhc3NTZWN1cml0eVRydXN0SHRtbChmaWVsZFNldHRpbmcucmVuZGVyKHJvdykpXG5cdFx0XHRcdFx0XHRcdDogcm93W2tleV0gIT09IG51bGxcblx0XHRcdFx0XHRcdFx0XHQ/IHJvd1trZXldXG5cdFx0XHRcdFx0XHRcdFx0OiAnJztcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmIChmaWVsZFNldHRpbmcuY2xpY2sgJiYgdHlwZW9mIGZpZWxkU2V0dGluZy5jbGljayA9PT0gJ2Z1bmN0aW9uJykge1xuXHRcdFx0XHRcdGNvbHVtbk9iamVjdC5jbGljayA9IGZpZWxkU2V0dGluZy5jbGljaztcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoZmllbGRTZXR0aW5nLmV4cGFuZCkge1xuXHRcdFx0XHRcdGNvbHVtbk9iamVjdC5leHBhbmQgPSBmaWVsZFNldHRpbmcuZXhwYW5kO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0a2V5cy5wdXNoKGNvbHVtbk9iamVjdCk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0a2V5cy5zb3J0KGZ1bmN0aW9uKGE6IGFueSwgYjogYW55KSB7XG5cdFx0XHRyZXR1cm4gY29sdW1ucy5pbmRleE9mKGEub2JqZWN0S2V5KSA8IGNvbHVtbnMuaW5kZXhPZihiLm9iamVjdEtleSlcblx0XHRcdFx0PyAtMVxuXHRcdFx0XHQ6IDE7XG5cdFx0fSk7XG5cdFx0cmV0dXJuIGtleXM7XG5cdH1cbn1cbiIsImltcG9ydCB7XG5cdENvbXBvbmVudEZhY3RvcnksXG5cdENvbXBvbmVudEZhY3RvcnlSZXNvbHZlcixcblx0Q29tcG9uZW50UmVmLFxuXHREaXJlY3RpdmUsXG5cdEV2ZW50RW1pdHRlcixcblx0SW5qZWN0b3IsXG5cdElucHV0LFxuXHRPbkluaXQsXG5cdE91dHB1dCxcblx0VHlwZSxcblx0Vmlld0NvbnRhaW5lclJlZlxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuQERpcmVjdGl2ZSh7XG5cdHNlbGVjdG9yOiAnW2d0Q29tcG9uZW50QW5jaG9yXSdcbn0pXG5leHBvcnQgY2xhc3MgQ29tcG9uZW50QW5jaG9yRGlyZWN0aXZlPEM+IGltcGxlbWVudHMgT25Jbml0IHtcblx0QElucHV0KCkgY3RvcjogVHlwZTxDPjtcblx0QElucHV0KCkgaW5qZWN0b3I6IEluamVjdG9yO1xuXHRAT3V0cHV0KCkgaW5zdGFuY2U6IEV2ZW50RW1pdHRlcjxDPiA9IG5ldyBFdmVudEVtaXR0ZXI8Qz4oKTtcblxuXHRjb25zdHJ1Y3Rvcihcblx0XHRwcml2YXRlIGNvbXBvbmVudEZhY3RvcnlSZXNvbHZlcjogQ29tcG9uZW50RmFjdG9yeVJlc29sdmVyLFxuXHRcdHByaXZhdGUgdmlld0NvbnRhaW5lcjogVmlld0NvbnRhaW5lclJlZlxuXHQpIHt9XG5cblx0bmdPbkluaXQoKTogdm9pZCB7XG5cdFx0Y29uc3QgZmFjdG9yeTogQ29tcG9uZW50RmFjdG9yeTxcblx0XHRcdENcblx0XHQ+ID0gdGhpcy5jb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIucmVzb2x2ZUNvbXBvbmVudEZhY3RvcnkodGhpcy5jdG9yKTtcblx0XHRjb25zdCBjb21wb25lbnQ6IENvbXBvbmVudFJlZjxDPiA9IHRoaXMudmlld0NvbnRhaW5lci5jcmVhdGVDb21wb25lbnQoXG5cdFx0XHRmYWN0b3J5LFxuXHRcdFx0MCxcblx0XHRcdHRoaXMuaW5qZWN0b3Jcblx0XHQpO1xuXHRcdHRoaXMuaW5zdGFuY2UuZW1pdChjb21wb25lbnQuaW5zdGFuY2UpO1xuXHR9XG59XG4iLCJpbXBvcnQge1xuXHRDaGFuZ2VEZXRlY3RvclJlZixcblx0RGlyZWN0aXZlLFxuXHRFbGVtZW50UmVmLFxuXHRIb3N0TGlzdGVuZXIsXG5cdElucHV0XG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5ARGlyZWN0aXZlKHtcblx0c2VsZWN0b3I6ICdbZ3RDb2x1bW5XaWR0aF0nXG59KVxuZXhwb3J0IGNsYXNzIEd0Q29sdW1uV2lkdGhEaXJlY3RpdmUge1xuXHRASW5wdXQoKSBvYmplY3RLZXk6IHN0cmluZztcblx0QElucHV0KCkgd2lkdGhzOiBPYmplY3Q7XG5cdEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzpyZXNpemUnLCBbJyRldmVudCddKVxuXHRwdWJsaWMgb25SZXNpemUoJGV2ZW50OiBhbnkpIHtcblx0XHR0aGlzLmNoZWNrU2l6ZSgpO1xuXHR9XG5cdGNvbnN0cnVjdG9yKFxuXHRcdHByaXZhdGUgaG9zdEVsZW1lbnQ6IEVsZW1lbnRSZWYsXG5cdFx0cHJpdmF0ZSBjZFJlZjogQ2hhbmdlRGV0ZWN0b3JSZWZcblx0KSB7fVxuXHRuZ09uSW5pdCgpIHtcblx0XHR0aGlzLmNoZWNrU2l6ZSgpO1xuXHR9XG5cblx0Y2hlY2tTaXplKCkge1xuXHRcdHRoaXMud2lkdGhzW3RoaXMub2JqZWN0S2V5XSA9IHdpbmRvd1xuXHRcdFx0LmdldENvbXB1dGVkU3R5bGUodGhpcy5ob3N0RWxlbWVudC5uYXRpdmVFbGVtZW50LCBudWxsKVxuXHRcdFx0LmdldFByb3BlcnR5VmFsdWUoJ3dpZHRoJyk7XG5cdFx0dGhpcy5jZFJlZi5kZXRlY3RDaGFuZ2VzKCk7XG5cdH1cbn1cbiIsImltcG9ydCB7IE5nTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBHdENoZWNrYm94Q29tcG9uZW50IH0gZnJvbSAnLi9jb21wb25lbnRzL2d0LWNoZWNrYm94L2d0LWNoZWNrYm94LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBHdERyaWxsZG93bkNvbXBvbmVudCB9IGZyb20gJy4vY29tcG9uZW50cy9ndC1kcmlsbGRvd24vZ3QtZHJpbGxkb3duLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBHdERyb3Bkb3duQ29tcG9uZW50IH0gZnJvbSAnLi9jb21wb25lbnRzL2d0LWRyb3Bkb3duL2d0LWRyb3Bkb3duLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBHdEV4cGFuZGluZ1Jvd0NvbXBvbmVudCB9IGZyb20gJy4vY29tcG9uZW50cy9ndC1leHBhbmRpbmctcm93L2d0LWV4cGFuZGluZy1yb3cuY29tcG9uZW50JztcbmltcG9ydCB7XG5cdEd0UGFnaW5hdGlvbkNvbXBvbmVudCxcblx0UGFnaW5hdGlvblBpcGVcbn0gZnJvbSAnLi9jb21wb25lbnRzL2d0LXBhZ2luYXRpb24vZ3QtcGFnaW5hdGlvbi5jb21wb25lbnQnO1xuaW1wb3J0IHtcblx0R3RUYWJsZUluZm9Db21wb25lbnQsXG5cdFRhYmxlSW5mb1BpcGVcbn0gZnJvbSAnLi9jb21wb25lbnRzL2d0LXRhYmxlLWluZm8vZ3QtdGFibGUtaW5mby5jb21wb25lbnQnO1xuaW1wb3J0IHsgR2VuZXJpY1RhYmxlQ29tcG9uZW50IH0gZnJvbSAnLi9jb21wb25lbnRzL2dlbmVyaWMtdGFibGUvZ2VuZXJpYy10YWJsZS5jb21wb25lbnQnO1xuaW1wb3J0IHsgR3RWaXNpYmxlUGlwZSB9IGZyb20gJy4vcGlwZXMvZ3QtdmlzaWJsZS5waXBlJztcbmltcG9ydCB7IEd0U2VhcmNoUGlwZSB9IGZyb20gJy4vcGlwZXMvZ3Qtc2VhcmNoLnBpcGUnO1xuaW1wb3J0IHsgR3RJc0VkaXRhYmxlUGlwZSB9IGZyb20gJy4vcGlwZXMvZ3QtaXMtZWRpdGFibGUucGlwZSc7XG5pbXBvcnQgeyBHdElzT2JzZXJ2YWJsZVBpcGUgfSBmcm9tICcuL3BpcGVzL2d0LWlzLW9ic2VydmFibGUucGlwZSc7XG5pbXBvcnQgeyBHdEhpZ2hsaWdodFBpcGUgfSBmcm9tICcuL3BpcGVzL2d0LWhpZ2hsaWdodC5waXBlJztcbmltcG9ydCB7IEd0Q29sdW1uQ2xhc3NQaXBlIH0gZnJvbSAnLi9waXBlcy9ndC1jb2x1bW4tY2xhc3MucGlwZSc7XG5pbXBvcnQgeyBHdFJvd0NsYXNzUGlwZSB9IGZyb20gJy4vcGlwZXMvZ3Qtcm93LWNsYXNzLnBpcGUnO1xuaW1wb3J0IHsgR3RUb3RhbHNQb3NpdGlvblBpcGUgfSBmcm9tICcuL3BpcGVzL2d0LXRvdGFscy1wb3NpdGlvbi5waXBlJztcbmltcG9ydCB7IEd0VG90YWxzUGlwZSB9IGZyb20gJy4vcGlwZXMvZ3QtdG90YWxzLnBpcGUnO1xuaW1wb3J0IHsgR3RNZXRhUGlwZSB9IGZyb20gJy4vcGlwZXMvZ3QtbWV0YS5waXBlJztcbmltcG9ydCB7IEd0T3JkZXJCeVBpcGUgfSBmcm9tICcuL3BpcGVzL2d0LW9yZGVyLWJ5LnBpcGUnO1xuaW1wb3J0IHsgR3RGaWx0ZXJQaXBlIH0gZnJvbSAnLi9waXBlcy9ndC1maWx0ZXIucGlwZSc7XG5pbXBvcnQgeyBHdENodW5rUGlwZSB9IGZyb20gJy4vcGlwZXMvZ3QtY2h1bmsucGlwZSc7XG5pbXBvcnQgeyBHdFByb3BlcnR5UGlwZSB9IGZyb20gJy4vcGlwZXMvZ3QtcHJvcGVydHkucGlwZSc7XG5pbXBvcnQgeyBEYXNoQ2FzZVBpcGUgfSBmcm9tICcuL3BpcGVzL2Rhc2gtY2FzZS5waXBlJztcbmltcG9ydCB7IEd0UmVuZGVyUGlwZSB9IGZyb20gJy4vcGlwZXMvZ3QtcmVuZGVyLnBpcGUnO1xuaW1wb3J0IHsgR3RDdXN0b21Db21wb25lbnRGYWN0b3J5IH0gZnJvbSAnLi9jb21wb25lbnRzL2d0LWN1c3RvbS1jb21wb25lbnQtZmFjdG9yeS9ndC1jdXN0b20tY29tcG9uZW50LWZhY3RvcnkuY29tcG9uZW50JztcbmltcG9ydCB7IENvbXBvbmVudEFuY2hvckRpcmVjdGl2ZSB9IGZyb20gJy4vZGlyZWN0aXZlcy9jb21wb25lbnQtYW5jaG9yLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBHdENvbHVtbldpZHRoRGlyZWN0aXZlIH0gZnJvbSAnLi9kaXJlY3RpdmVzL2d0LWNvbHVtbi13aWR0aC5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5ATmdNb2R1bGUoe1xuXHRkZWNsYXJhdGlvbnM6IFtcblx0XHRDb21wb25lbnRBbmNob3JEaXJlY3RpdmUsXG5cdFx0R2VuZXJpY1RhYmxlQ29tcG9uZW50LFxuXHRcdEd0UGFnaW5hdGlvbkNvbXBvbmVudCxcblx0XHRHdFZpc2libGVQaXBlLFxuXHRcdEd0UmVuZGVyUGlwZSxcblx0XHREYXNoQ2FzZVBpcGUsXG5cdFx0R3RQcm9wZXJ0eVBpcGUsXG5cdFx0R3RDaHVua1BpcGUsXG5cdFx0R3RGaWx0ZXJQaXBlLFxuXHRcdEd0T3JkZXJCeVBpcGUsXG5cdFx0R3RFeHBhbmRpbmdSb3dDb21wb25lbnQsXG5cdFx0R3RDdXN0b21Db21wb25lbnRGYWN0b3J5LFxuXHRcdEd0U2VhcmNoUGlwZSxcblx0XHRQYWdpbmF0aW9uUGlwZSxcblx0XHRHdFRhYmxlSW5mb0NvbXBvbmVudCxcblx0XHRUYWJsZUluZm9QaXBlLFxuXHRcdEd0TWV0YVBpcGUsXG5cdFx0R3RUb3RhbHNQaXBlLFxuXHRcdEd0VG90YWxzUG9zaXRpb25QaXBlLFxuXHRcdEd0Um93Q2xhc3NQaXBlLFxuXHRcdEd0Q29sdW1uQ2xhc3NQaXBlLFxuXHRcdEd0SGlnaGxpZ2h0UGlwZSxcblx0XHRHdElzT2JzZXJ2YWJsZVBpcGUsXG5cdFx0R3RJc0VkaXRhYmxlUGlwZSxcblx0XHRHdERyb3Bkb3duQ29tcG9uZW50LFxuXHRcdEd0Q29sdW1uV2lkdGhEaXJlY3RpdmUsXG5cdFx0R3REcmlsbGRvd25Db21wb25lbnQsXG5cdFx0R3RDaGVja2JveENvbXBvbmVudFxuXHRdLFxuXHRpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBGb3Jtc01vZHVsZV0sXG5cdGV4cG9ydHM6IFtcblx0XHRHZW5lcmljVGFibGVDb21wb25lbnQsXG5cdFx0R3RQYWdpbmF0aW9uQ29tcG9uZW50LFxuXHRcdEd0VGFibGVJbmZvQ29tcG9uZW50LFxuXHRcdEd0UmVuZGVyUGlwZSxcblx0XHREYXNoQ2FzZVBpcGUsXG5cdFx0R3RDb2x1bW5DbGFzc1BpcGUsXG5cdFx0R3RSb3dDbGFzc1BpcGUsXG5cdFx0R3RQcm9wZXJ0eVBpcGUsXG5cdFx0R3RDdXN0b21Db21wb25lbnRGYWN0b3J5LFxuXHRcdENvbXBvbmVudEFuY2hvckRpcmVjdGl2ZSxcblx0XHRHdEhpZ2hsaWdodFBpcGUsXG5cdFx0R3RFeHBhbmRpbmdSb3dDb21wb25lbnQsXG5cdFx0R3REcm9wZG93bkNvbXBvbmVudCxcblx0XHRHdERyaWxsZG93bkNvbXBvbmVudCxcblx0XHRHdENoZWNrYm94Q29tcG9uZW50XG5cdF0sXG5cdGVudHJ5Q29tcG9uZW50czogW0d0RHJpbGxkb3duQ29tcG9uZW50LCBHdENoZWNrYm94Q29tcG9uZW50XSxcblx0cHJvdmlkZXJzOiBbR3RNZXRhUGlwZSwgR3RIaWdobGlnaHRQaXBlXVxufSlcbmV4cG9ydCBjbGFzcyBHZW5lcmljVGFibGVNb2R1bGUge31cbiJdLCJuYW1lcyI6WyJDb21wb25lbnQiLCJDaGFuZ2VEZXRlY3RvclJlZiIsIklucHV0IiwiUGlwZSIsIkV2ZW50RW1pdHRlciIsIk91dHB1dCIsIlN1YmplY3QiLCJSZW5kZXJlcjIiLCJ0c2xpYl8xLl9fZXh0ZW5kcyIsIlJlcGxheVN1YmplY3QiLCJIb3N0QmluZGluZyIsIk9ic2VydmFibGUiLCJEb21TYW5pdGl6ZXIiLCJEaXJlY3RpdmUiLCJDb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIiLCJWaWV3Q29udGFpbmVyUmVmIiwiRWxlbWVudFJlZiIsIkhvc3RMaXN0ZW5lciIsIk5nTW9kdWxlIiwiQ29tbW9uTW9kdWxlIiwiRm9ybXNNb2R1bGUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQTtRQXlCQyw4QkFBb0IsbUJBQXNDO1lBQXRDLHdCQUFtQixHQUFuQixtQkFBbUIsQ0FBbUI7U0FBSTs7OztRQUU5RCxpREFBa0I7OztZQUFsQjtnQkFDQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsYUFBYSxFQUFFLENBQUM7YUFDekM7O29CQXRCREEsY0FBUyxTQUFDO3dCQUNWLFFBQVEsRUFBRSxlQUFlO3dCQUN6QixRQUFRLEVBQUUsMllBU1I7cUJBRUY7Ozs7O3dCQWxCQUMsc0JBQWlCOzs7O3FDQW9CaEJDLFVBQUs7bUNBQ0xBLFVBQUs7O21DQXZCUDs7Ozs7Ozs7Ozs7Ozs7OztRQXdDQyxpQ0FBUzs7Ozs7Ozs7Ozs7WUFBVCxVQUNDLEtBQXVCLEVBQ3ZCLElBQW1CLEVBQ25CLGtCQUEwQixFQUMxQixVQUFrQixFQUNsQixRQUFnQixFQUNoQixVQUFrQixFQUNsQixPQUFlLEVBQ2Ysb0JBQTRCO2dCQUU1QixxQkFBSSxJQUFJLEdBQUcsT0FBTyxLQUFLLEtBQUssUUFBUSxHQUFHLEtBQUssQ0FBQyxTQUFTLEdBQUcsRUFBRSxDQUFDO2dCQUM1RCxJQUFJLElBQUksQ0FBQyxrQkFBa0IsS0FBSyxJQUFJLENBQUMsVUFBVSxFQUFFO29CQUNoRCxJQUFJLEdBQUcsT0FBTyxLQUFLLEtBQUssUUFBUSxHQUFHLEtBQUssQ0FBQyxvQkFBb0IsR0FBRyxFQUFFLENBQUM7aUJBQ25FO2dCQUNELEtBQUsscUJBQU0sR0FBRyxJQUFJLElBQUksRUFBRTtvQkFDdkIsSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxFQUFFO3dCQUM3QixxQkFBTSxZQUFZLEdBQUcs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