@firestitch/report 18.9.0 → 18.10.1

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 (186) hide show
  1. package/app/reports/anchor-at-point.d.ts +14 -0
  2. package/app/reports/canvas-landing-page.d.ts +2 -0
  3. package/app/reports/components/component-chart/component-chart.component.d.ts +18 -2
  4. package/app/reports/components/component-kpi/component-kpi.component.d.ts +4 -1
  5. package/app/reports/components/report-canvas/report-canvas.component.d.ts +3 -0
  6. package/app/reports/components/report-component/report-component.component.d.ts +35 -1
  7. package/app/reports/components/report-view-picker/report-view-picker.component.d.ts +21 -0
  8. package/app/reports/data/report.data.d.ts +20 -7
  9. package/app/reports/dialogs/component-settings/component-settings.component.d.ts +18 -3
  10. package/app/reports/dialogs/report-settings/report-settings.component.d.ts +45 -8
  11. package/app/reports/dialogs/report-view/report-view-dialog.component.d.ts +13 -0
  12. package/app/reports/drill-crumbs.d.ts +12 -0
  13. package/app/reports/export/report-export-collector.service.d.ts +13 -4
  14. package/app/reports/export/report-filter-lines.d.ts +18 -0
  15. package/app/reports/filter-settings-rules.d.ts +37 -0
  16. package/app/reports/format.d.ts +0 -1
  17. package/app/reports/interfaces/canvas-landing-input.interface.d.ts +8 -0
  18. package/app/reports/interfaces/component-data-applied.interface.d.ts +13 -0
  19. package/app/reports/interfaces/component-data-drill.interface.d.ts +22 -0
  20. package/app/reports/interfaces/filter-bar-placement.type.d.ts +1 -0
  21. package/app/reports/interfaces/filter-component-toggle-state.interface.d.ts +4 -0
  22. package/app/reports/interfaces/filter-settings-option.interface.d.ts +4 -0
  23. package/app/reports/interfaces/filter-type-select-state.interface.d.ts +5 -0
  24. package/app/reports/interfaces/report-chart-hit.interface.d.ts +5 -0
  25. package/app/reports/interfaces/report-chat-viewer-cross-filter-field.interface.d.ts +4 -0
  26. package/app/reports/interfaces/report-chat-viewer-cross-filter.interface.d.ts +7 -0
  27. package/app/reports/interfaces/report-chat-viewer-detail.interface.d.ts +4 -0
  28. package/app/reports/interfaces/report-chat-viewer-drill-step.interface.d.ts +5 -0
  29. package/app/reports/interfaces/report-chat-viewer-drill.interface.d.ts +5 -0
  30. package/app/reports/interfaces/report-chat-viewer-filter.interface.d.ts +3 -0
  31. package/app/reports/interfaces/report-chat-viewer-selection.interface.d.ts +5 -0
  32. package/app/reports/interfaces/report-chat-viewer-state.interface.d.ts +12 -0
  33. package/app/reports/interfaces/report-drill-crumb.interface.d.ts +6 -0
  34. package/app/reports/interfaces/report-drill-refusal.type.d.ts +1 -0
  35. package/app/reports/interfaces/report-drill-step.interface.d.ts +5 -0
  36. package/app/reports/interfaces/report-export-line-kind.type.d.ts +1 -0
  37. package/app/reports/interfaces/report-export-line.interface.d.ts +8 -0
  38. package/app/reports/interfaces/report-export-lines-input.interface.d.ts +9 -0
  39. package/app/reports/interfaces/report-export-snapshot.interface.d.ts +15 -0
  40. package/app/reports/interfaces/report-filter-group-changes.interface.d.ts +7 -0
  41. package/app/reports/interfaces/report-filter-line-context.interface.d.ts +8 -0
  42. package/app/reports/interfaces/report-filter-line-form.type.d.ts +1 -0
  43. package/app/reports/interfaces/report-filter-match.type.d.ts +1 -0
  44. package/app/reports/interfaces/report-filter-option-pair.interface.d.ts +4 -0
  45. package/app/reports/interfaces/report-filter-options-ask.interface.d.ts +6 -0
  46. package/app/reports/interfaces/report-filter-options-list.interface.d.ts +7 -0
  47. package/app/reports/interfaces/report-filter-options-request.interface.d.ts +6 -0
  48. package/app/reports/interfaces/report-filter-options-stream.interface.d.ts +11 -0
  49. package/app/reports/interfaces/report-filter-options.interface.d.ts +7 -0
  50. package/app/reports/interfaces/report-filter-skip.type.d.ts +1 -0
  51. package/app/reports/interfaces/report-mark-action.type.d.ts +1 -0
  52. package/app/reports/interfaces/report-mark-click.interface.d.ts +13 -0
  53. package/app/reports/interfaces/report-mark-context.interface.d.ts +6 -0
  54. package/app/reports/interfaces/report-mark-decision.interface.d.ts +6 -0
  55. package/app/reports/interfaces/report-mark-event.interface.d.ts +11 -0
  56. package/app/reports/interfaces/report-mark-point.interface.d.ts +8 -0
  57. package/app/reports/interfaces/report-temporary-state.interface.d.ts +4 -0
  58. package/app/reports/interfaces/report-tile-state.interface.d.ts +8 -0
  59. package/app/reports/interfaces/report-view-config.interface.d.ts +11 -0
  60. package/app/reports/interfaces/report-view-create.interface.d.ts +7 -0
  61. package/app/reports/interfaces/report-view-deleted.interface.d.ts +4 -0
  62. package/app/reports/interfaces/report-view-dialog-data.interface.d.ts +7 -0
  63. package/app/reports/interfaces/report-view-dropped.interface.d.ts +5 -0
  64. package/app/reports/interfaces/report-view-menu-item.interface.d.ts +10 -0
  65. package/app/reports/interfaces/report-view-summary.interface.d.ts +11 -0
  66. package/app/reports/interfaces/report-view.interface.d.ts +7 -0
  67. package/app/reports/interfaces/report-viewer-feature.type.d.ts +1 -0
  68. package/app/reports/interfaces/report-views.interface.d.ts +7 -0
  69. package/app/reports/interfaces/report.interface.d.ts +27 -16
  70. package/app/reports/interfaces/tile-load-result.interface.d.ts +4 -0
  71. package/app/reports/mark-click.d.ts +20 -0
  72. package/app/reports/option-builder.d.ts +12 -1
  73. package/app/reports/report-chat-viewer-state.d.ts +8 -0
  74. package/app/reports/report-date-presets.d.ts +2 -0
  75. package/app/reports/report-filter-items.d.ts +20 -21
  76. package/app/reports/report-tile.d.ts +2 -0
  77. package/app/reports/report-view-config.d.ts +34 -0
  78. package/app/reports/report-view-menu.d.ts +15 -0
  79. package/app/reports/report-viewer-features.d.ts +5 -0
  80. package/app/reports/services/report-filter-options.service.d.ts +26 -0
  81. package/app/reports/services/report-filter-state.service.d.ts +65 -11
  82. package/app/reports/services/report-view.service.d.ts +39 -0
  83. package/app/reports/tile-data-state.d.ts +7 -0
  84. package/app/reports/tile-loads.d.ts +4 -0
  85. package/app/reports/views/report/fs-ai-report.component.d.ts +10 -8
  86. package/app/reports/views/report/report.component.d.ts +6 -0
  87. package/esm2022/app/reports/anchor-at-point.mjs +49 -0
  88. package/esm2022/app/reports/canvas-landing-page.mjs +26 -0
  89. package/esm2022/app/reports/components/component-chart/component-chart.component.mjs +97 -5
  90. package/esm2022/app/reports/components/component-kpi/component-kpi.component.mjs +11 -4
  91. package/esm2022/app/reports/components/component-list/component-list.component.mjs +11 -5
  92. package/esm2022/app/reports/components/report-canvas/report-canvas.component.mjs +56 -40
  93. package/esm2022/app/reports/components/report-component/report-component.component.mjs +261 -65
  94. package/esm2022/app/reports/components/report-view-picker/report-view-picker.component.mjs +115 -0
  95. package/esm2022/app/reports/data/report.data.mjs +94 -14
  96. package/esm2022/app/reports/dialogs/component-settings/component-settings.component.mjs +106 -51
  97. package/esm2022/app/reports/dialogs/report-settings/report-settings.component.mjs +248 -104
  98. package/esm2022/app/reports/dialogs/report-view/report-view-dialog.component.mjs +52 -0
  99. package/esm2022/app/reports/drill-crumbs.mjs +73 -0
  100. package/esm2022/app/reports/export/report-export-collector.service.mjs +187 -117
  101. package/esm2022/app/reports/export/report-filter-lines.mjs +235 -0
  102. package/esm2022/app/reports/export/report-pdf.service.mjs +12 -7
  103. package/esm2022/app/reports/export/report-pptx.service.mjs +18 -14
  104. package/esm2022/app/reports/filter-settings-rules.mjs +290 -0
  105. package/esm2022/app/reports/format.mjs +2 -22
  106. package/esm2022/app/reports/interfaces/canvas-landing-input.interface.mjs +2 -0
  107. package/esm2022/app/reports/interfaces/component-data-applied.interface.mjs +2 -0
  108. package/esm2022/app/reports/interfaces/component-data-drill.interface.mjs +2 -0
  109. package/esm2022/app/reports/interfaces/filter-bar-placement.type.mjs +2 -0
  110. package/esm2022/app/reports/interfaces/filter-component-toggle-state.interface.mjs +2 -0
  111. package/esm2022/app/reports/interfaces/filter-settings-option.interface.mjs +2 -0
  112. package/esm2022/app/reports/interfaces/filter-type-select-state.interface.mjs +2 -0
  113. package/esm2022/app/reports/interfaces/report-chart-hit.interface.mjs +2 -0
  114. package/esm2022/app/reports/interfaces/report-chat-viewer-cross-filter-field.interface.mjs +2 -0
  115. package/esm2022/app/reports/interfaces/report-chat-viewer-cross-filter.interface.mjs +2 -0
  116. package/esm2022/app/reports/interfaces/report-chat-viewer-detail.interface.mjs +2 -0
  117. package/esm2022/app/reports/interfaces/report-chat-viewer-drill-step.interface.mjs +2 -0
  118. package/esm2022/app/reports/interfaces/report-chat-viewer-drill.interface.mjs +2 -0
  119. package/esm2022/app/reports/interfaces/report-chat-viewer-filter.interface.mjs +1 -1
  120. package/esm2022/app/reports/interfaces/report-chat-viewer-selection.interface.mjs +2 -0
  121. package/esm2022/app/reports/interfaces/report-chat-viewer-state.interface.mjs +1 -1
  122. package/esm2022/app/reports/interfaces/report-drill-crumb.interface.mjs +2 -0
  123. package/esm2022/app/reports/interfaces/report-drill-refusal.type.mjs +2 -0
  124. package/esm2022/app/reports/interfaces/report-drill-step.interface.mjs +2 -0
  125. package/esm2022/app/reports/interfaces/report-export-line-kind.type.mjs +2 -0
  126. package/esm2022/app/reports/interfaces/report-export-line.interface.mjs +2 -0
  127. package/esm2022/app/reports/interfaces/report-export-lines-input.interface.mjs +2 -0
  128. package/esm2022/app/reports/interfaces/report-export-snapshot.interface.mjs +2 -0
  129. package/esm2022/app/reports/interfaces/report-filter-group-changes.interface.mjs +2 -0
  130. package/esm2022/app/reports/interfaces/report-filter-line-context.interface.mjs +2 -0
  131. package/esm2022/app/reports/interfaces/report-filter-line-form.type.mjs +2 -0
  132. package/esm2022/app/reports/interfaces/report-filter-match.type.mjs +2 -0
  133. package/esm2022/app/reports/interfaces/report-filter-option-pair.interface.mjs +2 -0
  134. package/esm2022/app/reports/interfaces/report-filter-options-ask.interface.mjs +2 -0
  135. package/esm2022/app/reports/interfaces/report-filter-options-list.interface.mjs +2 -0
  136. package/esm2022/app/reports/interfaces/report-filter-options-request.interface.mjs +2 -0
  137. package/esm2022/app/reports/interfaces/report-filter-options-stream.interface.mjs +2 -0
  138. package/esm2022/app/reports/interfaces/report-filter-options.interface.mjs +2 -0
  139. package/esm2022/app/reports/interfaces/report-filter-skip.type.mjs +2 -0
  140. package/esm2022/app/reports/interfaces/report-mark-action.type.mjs +2 -0
  141. package/esm2022/app/reports/interfaces/report-mark-click.interface.mjs +2 -0
  142. package/esm2022/app/reports/interfaces/report-mark-context.interface.mjs +2 -0
  143. package/esm2022/app/reports/interfaces/report-mark-decision.interface.mjs +2 -0
  144. package/esm2022/app/reports/interfaces/report-mark-event.interface.mjs +2 -0
  145. package/esm2022/app/reports/interfaces/report-mark-point.interface.mjs +2 -0
  146. package/esm2022/app/reports/interfaces/report-temporary-state.interface.mjs +2 -0
  147. package/esm2022/app/reports/interfaces/report-tile-state.interface.mjs +2 -0
  148. package/esm2022/app/reports/interfaces/report-view-config.interface.mjs +2 -0
  149. package/esm2022/app/reports/interfaces/report-view-create.interface.mjs +2 -0
  150. package/esm2022/app/reports/interfaces/report-view-deleted.interface.mjs +2 -0
  151. package/esm2022/app/reports/interfaces/report-view-dialog-data.interface.mjs +2 -0
  152. package/esm2022/app/reports/interfaces/report-view-dropped.interface.mjs +2 -0
  153. package/esm2022/app/reports/interfaces/report-view-menu-item.interface.mjs +2 -0
  154. package/esm2022/app/reports/interfaces/report-view-summary.interface.mjs +2 -0
  155. package/esm2022/app/reports/interfaces/report-view.interface.mjs +2 -0
  156. package/esm2022/app/reports/interfaces/report-viewer-feature.type.mjs +2 -0
  157. package/esm2022/app/reports/interfaces/report-views.interface.mjs +2 -0
  158. package/esm2022/app/reports/interfaces/report.interface.mjs +1 -1
  159. package/esm2022/app/reports/interfaces/tile-load-result.interface.mjs +2 -0
  160. package/esm2022/app/reports/mark-click.mjs +193 -0
  161. package/esm2022/app/reports/option-builder.mjs +159 -15
  162. package/esm2022/app/reports/report-chat-viewer-state.mjs +34 -0
  163. package/esm2022/app/reports/report-date-presets.mjs +18 -0
  164. package/esm2022/app/reports/report-filter-items.mjs +263 -72
  165. package/esm2022/app/reports/report-tile.mjs +12 -0
  166. package/esm2022/app/reports/report-view-config.mjs +587 -0
  167. package/esm2022/app/reports/report-view-menu.mjs +119 -0
  168. package/esm2022/app/reports/report-viewer-features.mjs +42 -0
  169. package/esm2022/app/reports/services/report-filter-options.service.mjs +238 -0
  170. package/esm2022/app/reports/services/report-filter-state.service.mjs +668 -210
  171. package/esm2022/app/reports/services/report-view.service.mjs +218 -0
  172. package/esm2022/app/reports/tile-data-state.mjs +127 -0
  173. package/esm2022/app/reports/tile-loads.mjs +38 -0
  174. package/esm2022/app/reports/views/report/fs-ai-report.component.mjs +194 -127
  175. package/esm2022/app/reports/views/report/report.component.mjs +112 -29
  176. package/esm2022/public_api.mjs +23 -1
  177. package/fesm2022/{firestitch-report-echarts-DBMOHmBF.mjs → firestitch-report-echarts-DHEH_K_q.mjs} +2 -2
  178. package/fesm2022/{firestitch-report-echarts-DBMOHmBF.mjs.map → firestitch-report-echarts-DHEH_K_q.mjs.map} +1 -1
  179. package/fesm2022/{firestitch-report-firestitch-report-CqbXT1gh.mjs → firestitch-report-firestitch-report-ZcHTnNKq.mjs} +8222 -4447
  180. package/fesm2022/firestitch-report-firestitch-report-ZcHTnNKq.mjs.map +1 -0
  181. package/fesm2022/firestitch-report.mjs +1 -1
  182. package/package.json +1 -1
  183. package/public_api.d.ts +22 -0
  184. package/app/reports/report-url-state.d.ts +0 -19
  185. package/esm2022/app/reports/report-url-state.mjs +0 -189
  186. package/fesm2022/firestitch-report-firestitch-report-CqbXT1gh.mjs.map +0 -1
@@ -1,34 +1,23 @@
1
1
  import { Injectable, signal } from '@angular/core';
2
+ import { computed } from '@angular/core';
3
+ import { toSignal } from '@angular/core/rxjs-interop';
2
4
  import { Subject } from 'rxjs';
3
5
  import { map, filter as rxFilter } from 'rxjs/operators';
6
+ import { scan } from 'rxjs/operators';
4
7
  import { endOfWeek, startOfMonth, startOfQuarter, startOfWeek, startOfYear, subDays, subMonths, subWeeks, } from 'date-fns';
5
8
  import { REPORT_WEEK_STARTS_ON } from '../consts/report-week.const';
6
9
  import { DEFAULT_FORMAT_CONTEXT, getZonedNow, resolveFormatContext, resolveReportTimezone, } from '../format';
7
- import { GRANULARITY_OPTIONS, } from '../interfaces/report.interface';
8
10
  import { listHiddenColumns, listSortTerms } from '../list-config';
9
11
  import { dateBoundString, LIST_SEARCH_MAX_LENGTH } from '../report-filter-items';
10
- import { decodeColumnList, decodeFilterValue, decodeSort } from '../report-url-state';
12
+ import { groupValueSignature } from '../report-filter-items';
13
+ import { isTile } from '../report-tile';
14
+ import { isRelativeRange } from '../report-view-config';
15
+ import { REPORT_VIEW_CONFIG_VERSION, cleanDrillPath, groupValueFromStored, isChartGranularity, sameDrillPath, toLiveGroupValue, toStoredGroupValue, viewDiffers, } from '../report-view-config';
16
+ import { finiteNumber } from '../report-view-config';
17
+ import { sameStoredGroupValue } from '../report-view-config';
18
+ import { tileDataState } from '../tile-data-state';
11
19
  import { reportComponents } from '../values';
12
20
  import * as i0 from "@angular/core";
13
- // Every relative range name the server knows. A record rather than a list, so
14
- // the build fails when ReportRelativeRange gains a name this misses.
15
- const RELATIVE_RANGES = {
16
- thisWeek: true,
17
- lastWeek: true,
18
- last7Days: true,
19
- last30Days: true,
20
- last3Months: true,
21
- last6Months: true,
22
- last12Months: true,
23
- thisMonth: true,
24
- thisQuarter: true,
25
- thisYear: true,
26
- yearToDate: true,
27
- };
28
- // Whether a stored preset name is one the server resolves (ReportRelativeRange).
29
- function isRelativeRange(name) {
30
- return Object.prototype.hasOwnProperty.call(RELATIVE_RANGES, name);
31
- }
32
21
  // Whether two stored filter-group defaults are the same. Compared on the fields a
33
22
  // default can actually carry, so key order in the payload can't read as a change.
34
23
  export function sameDefault(a, b) {
@@ -39,8 +28,15 @@ export function sameDefault(a, b) {
39
28
  && a.end === b.end
40
29
  && a.value === b.value
41
30
  && a.relative === b.relative
42
- && (a.values ?? []).length === (b.values ?? []).length
43
- && (a.values ?? []).every((value, index) => value === (b.values ?? [])[index]);
31
+ && sameList(a.values, b.values)
32
+ && sameList(a.excludeValues, b.excludeValues)
33
+ && a.min === b.min
34
+ && a.max === b.max;
35
+ }
36
+ // Whether two stored lists hold the same values in the same order.
37
+ function sameList(a, b) {
38
+ return (a ?? []).length === (b ?? []).length
39
+ && (a ?? []).every((value, index) => value === (b ?? [])[index]);
44
40
  }
45
41
  // Whether two list sorts order the rows the same way. No direction reads as
46
42
  // ascending, the way the list applies it.
@@ -50,18 +46,12 @@ function sameSort(a, b) {
50
46
  && (a.direction ?? 'asc') === (b.direction ?? 'asc');
51
47
  }
52
48
  // Whether a value read off a filter bar is the value already stored for its
53
- // group: the same calendar days, the same select values in the same order and
54
- // the same trimmed text. A bar re-reads every group it shows on any change, so
55
- // this is what tells the group that changed from the ones that did not.
49
+ // group: the same calendar days, the same select values kept or left out in
50
+ // the same order, the same trimmed text and the same number range ends. A
51
+ // bar re-reads every group it shows on any change, so this is what tells the
52
+ // group that changed from the ones that did not.
56
53
  export function sameFilterValue(a, b) {
57
- if (!a || !b) {
58
- return !a && !b;
59
- }
60
- const values = (value) => (value.values ?? []).map(String);
61
- return sameDays(a, b)
62
- && values(a).join('\u0000') === values(b).join('\u0000')
63
- && values(a).length === values(b).length
64
- && (a.value ?? '').trim() === (b.value ?? '').trim();
54
+ return groupValueSignature(a) === groupValueSignature(b);
65
55
  }
66
56
  // The groups a bar re-read that it now shows with a value other than the one
67
57
  // it last reported, recording each new value in `lastReported`. A bar is
@@ -112,19 +102,34 @@ export function defaultSignature(group) {
112
102
  groupDefault.value ?? '',
113
103
  groupDefault.relative ?? '',
114
104
  (groupDefault.values ?? []).join(','),
105
+ (groupDefault.excludeValues ?? []).join(','),
106
+ groupDefault.min ?? '',
107
+ groupDefault.max ?? '',
115
108
  ].join('~');
116
109
  }
110
+ // The temporary layer with nothing picked.
111
+ function emptyTemporaryState() {
112
+ return { crossFilters: [], detail: null };
113
+ }
117
114
  // Viewer filter state for the open report. Filter VALUES are never saved to
118
115
  // the report — this service holds them per filter GROUP (the propagation unit),
119
116
  // resolves them into per-component member-filter values for each data request,
120
117
  // and notifies the components whose groups changed so only they refetch.
121
118
  //
122
- // It is also the one source of the viewer state the report URL carries (group
123
- // values, the group-by grain, list sorts, searches and hidden columns):
124
- // urlSnapshot() says what differs from the authored defaults, init() restores
125
- // it, and urlChanges() tells the host's single URL writer when to write.
119
+ // It is the one place the viewer's state lives while the report is open: the
120
+ // group values, the group-by grain, the match, list sorts, searches and hidden
121
+ // columns, the page and each chart's drill path. None of it is ever written to
122
+ // the browser URL. It outlives a page switch (the canvas changes the page, not
123
+ // this service) and goes with the report view: a reload starts a new service,
124
+ // which opens on the report's defaults or the viewer's default view.
125
+ // changes() fires on every change of it.
126
126
  //
127
- // Session-only, never in the URL: per-filter enable/disable toggles from a
127
+ // The durable part is one view document: snapshot() writes it, apply() opens
128
+ // a view, and base and viewChanged say whether the screen still shows that
129
+ // view. The temporary layer (a cross-filter, an open rows panel) is its own
130
+ // section, so no view ever carries it.
131
+ //
132
+ // Session-only, never in a view: per-filter enable/disable toggles from a
128
133
  // component's filter menu (the `enabled` column is the authored default; a
129
134
  // viewer's toggle shouldn't write to the report).
130
135
  export class ReportFilterStateService {
@@ -148,6 +153,46 @@ export class ReportFilterStateService {
148
153
  listHidden = signal(new Map(), {
149
154
  equal: sameHidden,
150
155
  });
156
+ // Moves each time apply() or resetToBase() replaces the whole durable
157
+ // state. Bars and tiles key on it, so an applied view repaints all of them.
158
+ stateVersion = computed(() => this._stateVersion());
159
+ // Moves each time apply() opens a view (or the report's defaults). The
160
+ // canvas keys its tiles on it, so an opened view draws each one again.
161
+ // resetToBase() leaves it: a reset refetches the tiles in place, so their
162
+ // data stays on screen while they reload.
163
+ appliedVersion = computed(() => this._appliedVersion());
164
+ // By list component id, how many resets moved that list's sort. FsList
165
+ // reads its sort only when it is created, so a list whose sort a reset
166
+ // moved is drawn again (keyed on its count); every other tile reloads in
167
+ // place.
168
+ listSortResets = computed(() => this._listSortResets());
169
+ // The open page, or null before the host reports one (setPage).
170
+ page = computed(() => this._pageId());
171
+ // How the groups combine: 'all' keeps the rows every group keeps, 'any'
172
+ // the rows at least one eligible group keeps (setMatch).
173
+ match = computed(() => this._match());
174
+ // The viewer features the open report's server serves (Report.viewerFeatures):
175
+ // a filter bar offers a control only when its feature is listed. Empty
176
+ // before a report is open and from an older server.
177
+ viewerFeatures = computed(() => this._report()?.viewerFeatures ?? []);
178
+ // The report init() last read, or null before one is open. A tile header
179
+ // lists its select options from it (ReportFilterOptionsService).
180
+ report = computed(() => this._report());
181
+ // The state the screen is compared with: the base apply() was given (the
182
+ // open view as it applied), or the report's authored defaults
183
+ // (authoredConfig()) when no view is open. It holds only the groups the
184
+ // view held; every other group follows its authored default.
185
+ base = computed(() => {
186
+ this._revision();
187
+ return this._baseConfig() ?? this.authoredConfig();
188
+ });
189
+ // Whether the screen differs from base (viewDiffers): what a view picker
190
+ // marks '(edited)'. A switch of page does not count, and the temporary
191
+ // state never does.
192
+ viewChanged = computed(() => {
193
+ this._revision();
194
+ return viewDiffers(this.base(), this.snapshot(), this.authoredConfig());
195
+ });
151
196
  _values = new Map();
152
197
  _groups = new Map();
153
198
  _sessionDisabled = new Set();
@@ -157,7 +202,7 @@ export class ReportFilterStateService {
157
202
  _cleared = new Set();
158
203
  // The report's group-by control: a single report-wide bucket override for all
159
204
  // time-series charts. Unset = each chart uses its authored granularity. Never
160
- // saved to the report (the URL carries it), and carried in the data request's
205
+ // saved to the report (a saved view keeps it), and carried in the data request's
161
206
  // `state`, so it propagates through to the PDF/PowerPoint exports too. Named
162
207
  // for the `frequency` wire key it travels under, not for the control's label.
163
208
  _frequency = null;
@@ -182,8 +227,42 @@ export class ReportFilterStateService {
182
227
  // Emits the group id that changed; components listen filtered to their own
183
228
  // group ids. null = everything changed (re-init).
184
229
  _changed$ = new Subject();
185
- // Fires whenever anything the URL carries may have changed.
186
- _urlChanged$ = new Subject();
230
+ // Fires whenever anything in the viewer state may have changed.
231
+ _stateChanged$ = new Subject();
232
+ // Counts the changes changes() reports. The group values, the grain and
233
+ // the list state that base and viewChanged compare are the plain fields
234
+ // above, which every setter reports through changes() (they are shared
235
+ // with the inline values build, so they stay as they are); this counter is
236
+ // how the two computeds hear of them. The view state below is signals and
237
+ // is read directly. The subject is this service's own and is never
238
+ // completed, so the signal listens to it exactly as long as the service
239
+ // lives.
240
+ _revision = toSignal(this._stateChanged$.pipe(scan((count) => count + 1, 0)), {
241
+ initialValue: 0,
242
+ manualCleanup: true,
243
+ });
244
+ _stateVersion = signal(0);
245
+ _appliedVersion = signal(0);
246
+ _listSortResets = signal(new Map());
247
+ // The report init() last read: the tiles and pages a view's state is
248
+ // checked against.
249
+ _report = signal(null);
250
+ // The open page, set by the host as the viewer moves between pages. A view
251
+ // stores it, but moving to another page never edits a view.
252
+ _pageId = signal(null);
253
+ // How the groups combine: 'all' (the default) or 'any'.
254
+ _match = signal('all');
255
+ // Each chart's drill path, top first, by component id. A chart at its top
256
+ // has no entry, and only a chart has one.
257
+ _drills = signal(new Map());
258
+ // Emits the id of the chart whose drill path changed.
259
+ _drillChanged$ = new Subject();
260
+ // The base as apply() applied it, or null when the base is the authored
261
+ // defaults (see base).
262
+ _baseConfig = signal(null);
263
+ // The temporary layer: kept apart from everything above, so snapshot()
264
+ // and viewChanged never read it.
265
+ _temporary = signal(emptyTemporaryState());
187
266
  // Seed groups + their defaults when a report loads. Existing session values
188
267
  // for still-existing groups survive a structure re-fetch (a chat edit
189
268
  // shouldn't reset the viewer's filters), and so does a group the viewer
@@ -196,17 +275,12 @@ export class ReportFilterStateService {
196
275
  // A change of the report's zone moves "today", so a value still carrying its
197
276
  // group default's preset name is resolved again in the new zone. A value the
198
277
  // viewer picked, or one carrying another preset name, is kept as it is.
199
- //
200
- // `restore` is the viewer state read from the URL. The host passes it only on
201
- // the first load of a report; a reload after a chat or dialog edit passes
202
- // null, so the in-memory state wins. Params that name a group, list or column
203
- // the report no longer has, or that do not decode, are ignored.
204
- init(report, restore = null) {
278
+ init(report) {
205
279
  const previousTimezone = this.timezone();
206
280
  // Set first: the defaults seeded below resolve their relative presets in it.
207
281
  this.timezone.set(resolveReportTimezone(report));
208
282
  this.formatContext.set(resolveFormatContext(report));
209
- // Before any search restore: listSearchable reads it.
283
+ // Before the pruning: listSearchable reads it.
210
284
  this._serverSearches = report.effectiveLocale !== undefined;
211
285
  const timezoneChanged = previousTimezone !== this.timezone();
212
286
  const previousGroups = this._groups;
@@ -216,12 +290,10 @@ export class ReportFilterStateService {
216
290
  this._seed(group, previousGroups.get(group.id) ?? null, timezoneChanged);
217
291
  }
218
292
  this._lists = new Map(this._listComponents(report).map((component) => [component.id, component]));
219
- if (restore) {
220
- this._restore(report, restore);
221
- }
222
293
  this._prune(report);
294
+ this._pruneViewState(report, previousGroups);
223
295
  this._changed$.next(null);
224
- this._urlChanged$.next();
296
+ this._stateChanged$.next();
225
297
  }
226
298
  value(groupId) {
227
299
  return this._values.get(groupId);
@@ -230,7 +302,7 @@ export class ReportFilterStateService {
230
302
  // while its days are still the stored days: the bars re-set every group they
231
303
  // show whenever any one of them changes, and an untouched rolling range must
232
304
  // keep its name rather than turn into two fixed dates. Any other range, a
233
- // picker shortcut included, is stored as the fixed dates it shows.
305
+ // date picker preset included, is stored as the fixed dates it shows.
234
306
  setValue(groupId, value) {
235
307
  if (value === null) {
236
308
  this._values.delete(groupId);
@@ -243,10 +315,10 @@ export class ReportFilterStateService {
243
315
  this._cleared.delete(groupId);
244
316
  }
245
317
  this._changed$.next(groupId);
246
- this._urlChanged$.next();
318
+ this._stateChanged$.next();
247
319
  }
248
320
  // A relative preset name as today's range in the report's zone, or null for
249
- // a name it does not know. The URL codec decodes preset names through this.
321
+ // a name it does not know. A view's rolling range is opened through this.
250
322
  resolveRelative(name) {
251
323
  return this._relativeRange(name);
252
324
  }
@@ -257,7 +329,7 @@ export class ReportFilterStateService {
257
329
  setFrequency(frequency) {
258
330
  this._frequency = frequency;
259
331
  this._frequencyChanged$.next();
260
- this._urlChanged$.next();
332
+ this._stateChanged$.next();
261
333
  }
262
334
  // Fires whenever the group-by grain changes — every time-series chart listens
263
335
  // so it refetches and re-buckets (the override isn't scoped to any filter
@@ -272,12 +344,12 @@ export class ReportFilterStateService {
272
344
  }
273
345
  // Records a list's sort when it is the viewer's own: a sort that is the
274
346
  // list's authored first term is the list's default, not a choice, so it
275
- // clears the entry instead (the rule the URL snapshot applies). Otherwise a
347
+ // clears the entry instead (the rule snapshot() applies). Otherwise a
276
348
  // list's first fetch would record its seeded authored term, and a list the
277
349
  // agent re-sorts later in the session would keep sending the old term
278
350
  // first. Deliberately emits no change: the list sets this from the fetch
279
351
  // that already ran with that sort, so a notification would only make it
280
- // refetch the same rows. Only the URL hears about it.
352
+ // refetch the same rows. Only changes() hears about it.
281
353
  setListSort(component, sort) {
282
354
  if (sort && !sameSort(sort, listSortTerms(component.config)[0] ?? null)) {
283
355
  this._listSorts.set(component.id, sort);
@@ -285,7 +357,7 @@ export class ReportFilterStateService {
285
357
  else {
286
358
  this._listSorts.delete(component.id);
287
359
  }
288
- this._urlChanged$.next();
360
+ this._stateChanged$.next();
289
361
  }
290
362
  // The text a list is searched by, or null when its search box is empty.
291
363
  listSearch(componentId) {
@@ -294,8 +366,8 @@ export class ReportFilterStateService {
294
366
  // Whether a list shows the search box over its text columns: it does when the
295
367
  // server answers a list search (see _serverSearches), unless one of its live
296
368
  // filters belongs to a keyword group its header shows. A bar shows one search
297
- // box (its last keyword item), and that one is the author's. The header, the
298
- // URL restore, the pruning, the data request state and the exports all read
369
+ // box (its last keyword item), and that one is the author's. The header, an
370
+ // opened view, the pruning, the data request state and the exports all read
299
371
  // this one rule, so no search narrows a list whose screen has no box showing
300
372
  // it, and no export titles a search the server did not apply.
301
373
  listSearchable(component) {
@@ -311,7 +383,7 @@ export class ReportFilterStateService {
311
383
  }
312
384
  // Records a list's search box text (listSearchText); an empty box clears
313
385
  // it. The header calls this on every change of any of its items, so the
314
- // list and the URL hear about it only when the stored text actually changed.
386
+ // list and changes() hear about it only when the stored text actually changed.
315
387
  setListSearch(componentId, text) {
316
388
  const search = listSearchText(text);
317
389
  if (search === (this._listSearches.get(componentId) ?? '')) {
@@ -324,7 +396,7 @@ export class ReportFilterStateService {
324
396
  this._listSearches.delete(componentId);
325
397
  }
326
398
  this._listSearchChanged$.next(componentId);
327
- this._urlChanged$.next();
399
+ this._stateChanged$.next();
328
400
  }
329
401
  // The config column names a viewer hid on a list; none when it shows them all.
330
402
  hiddenColumns(componentId) {
@@ -332,7 +404,7 @@ export class ReportFilterStateService {
332
404
  }
333
405
  // Records the columns a viewer hid on a list, kept to listHiddenColumns:
334
406
  // names the list cannot hide are dropped, and none (or every column) clears
335
- // the entry. Only the URL hears about it, and only on a real change.
407
+ // the entry. Only changes() hears about it, and only on a real change.
336
408
  setHiddenColumns(componentId, names) {
337
409
  const hidden = listHiddenColumns(this._lists.get(componentId)?.config, names);
338
410
  if (sameNames(hidden, this.hiddenColumns(componentId))) {
@@ -346,54 +418,18 @@ export class ReportFilterStateService {
346
418
  next.delete(componentId);
347
419
  }
348
420
  this.listHidden.set(next);
349
- this._urlChanged$.next();
421
+ this._stateChanged$.next();
350
422
  }
351
423
  // Fires whenever one list's search text changes, so that list refetches.
352
424
  listSearchChanges(componentId) {
353
425
  return this._listSearchChanged$.asObservable()
354
426
  .pipe(rxFilter((id) => id === componentId), map(() => undefined));
355
427
  }
356
- // Fires whenever the viewer state the URL carries may have changed: a group
357
- // value, the grain, a list sort, search or hidden columns, or a (re)load of
358
- // the report.
359
- urlChanges() {
360
- return this._urlChanged$.asObservable();
361
- }
362
- // The viewer state the URL should carry for `report`: only what differs from
363
- // the authored defaults, so an untouched report has a bare URL and keeps
364
- // following its defaults when they change. A group the viewer cleared is
365
- // null. A date range is compared on its days against its default resolved
366
- // today, so a value that is the default under another preset name (thisYear
367
- // against a yearToDate default) is still the default.
368
- urlSnapshot(report) {
369
- const groups = new Map();
370
- for (const group of this._groups.values()) {
371
- const value = this._values.get(group.id);
372
- if (this._cleared.has(group.id)) {
373
- groups.set(group.id, null);
374
- }
375
- else if (value && !this._isDefault(group, value)) {
376
- groups.set(group.id, value);
377
- }
378
- }
379
- const listSorts = new Map();
380
- const listSearches = new Map();
381
- const listHidden = new Map();
382
- for (const component of this._listComponents(report)) {
383
- const sort = this._listSorts.get(component.id);
384
- const search = this._listSearches.get(component.id);
385
- const hidden = this.hiddenColumns(component.id);
386
- if (sort && !sameSort(sort, listSortTerms(component.config)[0] ?? null)) {
387
- listSorts.set(component.id, sort);
388
- }
389
- if (search) {
390
- listSearches.set(component.id, search);
391
- }
392
- if (hidden.length) {
393
- listHidden.set(component.id, [...hidden]);
394
- }
395
- }
396
- return { groups, listSorts, listSearches, listHidden, frequency: this._frequency };
428
+ // Fires whenever the viewer state may have changed: a group value, the
429
+ // grain, the match, the page, a list sort, search or hidden columns, a
430
+ // drill path, an applied view or a (re)load of the report.
431
+ changes() {
432
+ return this._stateChanged$.asObservable();
397
433
  }
398
434
  isFilterDisabled(filterId) {
399
435
  return this._sessionDisabled.has(filterId);
@@ -409,7 +445,7 @@ export class ReportFilterStateService {
409
445
  // the search with it. The list refetches on the group change below.
410
446
  this._dropUnsearchable();
411
447
  this._changed$.next(groupId);
412
- this._urlChanged$.next();
448
+ this._stateChanged$.next();
413
449
  }
414
450
  // Notifications relevant to ONE component: any change to a group one of its
415
451
  // filters belongs to (or a full re-init).
@@ -463,21 +499,203 @@ export class ReportFilterStateService {
463
499
  })
464
500
  .filter((entry) => entry !== null);
465
501
  }
466
- // Every component's resolved values in one array — what a report-level export
502
+ // Every tile's resolved values in one array — what a report-level export
467
503
  // carries so each file in the archive is filtered exactly as the screen is.
468
504
  // Filter ids are unique per component, so the backend picks each component's
469
- // own out of the pile. A page id narrows it to that page.
505
+ // own out of the pile. Only a tile becomes a file (isTile), so no other
506
+ // component's entries ride along. A page id narrows it to that page.
470
507
  resolveForReport(report, pageId = null) {
471
508
  const pages = (report.pages ?? [])
472
509
  .filter((page) => !pageId || page.id === pageId);
473
510
  return pages
474
511
  .flatMap((page) => (page.components ?? [])
512
+ .filter((component) => isTile(component))
475
513
  .flatMap((component) => this.resolveForComponent(component)));
476
514
  }
515
+ setPage(pageId) {
516
+ if (pageId === this._pageId()) {
517
+ return;
518
+ }
519
+ this._pageId.set(pageId);
520
+ this._stateChanged$.next();
521
+ }
522
+ // A change of match can change every tile a group with a value narrows, so
523
+ // every tile hears about it.
524
+ setMatch(match) {
525
+ const next = match === 'any' ? 'any' : 'all';
526
+ if (next === this._match()) {
527
+ return;
528
+ }
529
+ this._match.set(next);
530
+ this._changed$.next(null);
531
+ this._stateChanged$.next();
532
+ }
533
+ // A chart's drill path, top first; empty while the chart is at its top.
534
+ // It reads a signal, so a template that shows it repaints when it moves.
535
+ drill(componentId) {
536
+ return this._drills().get(componentId) ?? [];
537
+ }
538
+ // Records a chart's drill path, kept to cleanDrillPath; an empty path is
539
+ // the chart's top. Only a chart of the open report drills: a path for any
540
+ // other component is ignored. Only that chart and changes() hear about it,
541
+ // and only on a real change.
542
+ setDrill(componentId, path) {
543
+ const kept = cleanDrillPath(path);
544
+ if (!this._isChart(componentId) || sameDrillPath(kept, this.drill(componentId))) {
545
+ return;
546
+ }
547
+ this._setDrillPath(componentId, kept);
548
+ this._drillChanged$.next(componentId);
549
+ this._stateChanged$.next();
550
+ }
551
+ // Fires whenever one chart's drill path changes, so that chart refetches.
552
+ drillChanges(componentId) {
553
+ return this._drillChanged$.asObservable()
554
+ .pipe(rxFilter((id) => id === componentId), map(() => undefined));
555
+ }
556
+ // Takes the drill path a chart's answer applied as the chart's own: the
557
+ // server keeps the longest part of a sent path it can apply, so a later
558
+ // save holds that part only. The chart has just read that path, so only
559
+ // changes() hears about it. True when the path changed.
560
+ adoptDrill(componentId, path) {
561
+ const kept = cleanDrillPath(path);
562
+ if (!this._isChart(componentId) || sameDrillPath(kept, this.drill(componentId))) {
563
+ return false;
564
+ }
565
+ this._setDrillPath(componentId, kept);
566
+ this._stateChanged$.next();
567
+ return true;
568
+ }
569
+ // The durable state on screen as one view document: the page, every group
570
+ // the report has (null when it holds nothing, a cleared default included),
571
+ // the match, the grain, and each tile's sort, search, hidden columns and
572
+ // drill path where they differ from the authored tile. A date range that
573
+ // still carries its relative preset is written as that preset, whatever
574
+ // today is (toStoredGroupValue). The temporary layer is never part of it.
575
+ snapshot() {
576
+ const config = { v: REPORT_VIEW_CONFIG_VERSION };
577
+ if (this._pageId()) {
578
+ config.pageId = this._pageId();
579
+ }
580
+ if (this._frequency) {
581
+ config.groupBy = this._frequency;
582
+ }
583
+ if (this._match() === 'any') {
584
+ config.match = 'any';
585
+ }
586
+ config.groups = this._snapshotGroups();
587
+ const tiles = this._snapshotTiles();
588
+ if (Object.keys(tiles).length) {
589
+ config.tiles = tiles;
590
+ }
591
+ return config;
592
+ }
593
+ // The report's authored defaults as a view document: every group at its
594
+ // authored default (null when it has none), no match, grain or tile state.
595
+ authoredConfig() {
596
+ const groups = {};
597
+ this._groups.forEach((group) => {
598
+ groups[group.id] = toStoredGroupValue(group.type, this._defaultValue(group));
599
+ });
600
+ return { v: REPORT_VIEW_CONFIG_VERSION, groups };
601
+ }
602
+ // Replaces the durable state with a view's (`config`; null = the report's
603
+ // authored defaults), which becomes the base: what the screen is compared
604
+ // with for '(edited)' and what resetToBase() returns to. A group the view
605
+ // does not hold opens at its authored default; one the report does not
606
+ // have, or whose value does not fit the group's type, is skipped. The
607
+ // view's page opens, unless `pageId` names a page of the report (a ?page=
608
+ // the report opened with beats its default view's page). The temporary
609
+ // layer is kept. Every change is announced once, at the end.
610
+ apply(config, pageId = null) {
611
+ const frequency = this._frequency;
612
+ this._setBase(config);
613
+ this._applyPage(config?.pageId);
614
+ this._applyPage(pageId);
615
+ this._appliedVersion.update((version) => version + 1);
616
+ this._notifyApplied(frequency);
617
+ }
618
+ // Puts the screen back on its base (the open view, else the authored
619
+ // defaults) on the page it is on, and clears the temporary layer. The
620
+ // tiles stay and reload in place (appliedVersion does not move), except a
621
+ // list whose sort this moved (listSortResets).
622
+ resetToBase() {
623
+ const frequency = this._frequency;
624
+ const sorts = new Map(this._listSorts);
625
+ this._temporary.set(emptyTemporaryState());
626
+ this._applyLayer(this._baseConfig());
627
+ this._countSortResets(sorts);
628
+ this._notifyApplied(frequency);
629
+ }
630
+ // The screen as it is becomes the base, with nothing applied: what a view
631
+ // just saved from the screen holds. The page on screen is the base's.
632
+ setBaseToScreen() {
633
+ this._baseConfig.set(this.snapshot());
634
+ this._stateChanged$.next();
635
+ }
636
+ // The report's authored defaults become the base again (the open view was
637
+ // deleted); the screen stays as it is.
638
+ clearBase() {
639
+ this._baseConfig.set(null);
640
+ this._stateChanged$.next();
641
+ }
642
+ // Puts only `groupIds` back on the base: the open view's value for a group
643
+ // it holds, else the group's authored default. A tile header's 'Clear
644
+ // filters' owns only its own groups; the report bar's calls resetToBase().
645
+ // Each group is announced as a viewer's change to it is, so the tiles in
646
+ // it refetch and a bar showing it with another value is built again.
647
+ resetGroupsToBase(groupIds) {
648
+ const held = this._baseConfig()?.groups ?? {};
649
+ groupIds.forEach((groupId) => {
650
+ const group = this._groups.get(groupId);
651
+ if (!group) {
652
+ return;
653
+ }
654
+ if (!Object.prototype.hasOwnProperty.call(held, groupId) || !this._applyGroup(group, held[groupId])) {
655
+ this._seedAuthored(group);
656
+ }
657
+ this._changed$.next(groupId);
658
+ });
659
+ this._stateChanged$.next();
660
+ }
661
+ // Whether one of `groupIds` shows a value other than its base: the open
662
+ // view's value for a group it holds, else the group's authored default,
663
+ // the value resetGroupsToBase() puts back and viewChanged compares. A tile
664
+ // header's Clear chip shows exactly while one of its own groups does. It
665
+ // reads the revision viewChanged reads, so a caller on each check of an
666
+ // OnPush view stays current.
667
+ groupsDifferFromBase(groupIds) {
668
+ this._revision();
669
+ const held = this._baseConfig()?.groups ?? {};
670
+ return groupIds.some((groupId) => {
671
+ const group = this._groups.get(groupId);
672
+ if (!group) {
673
+ return false;
674
+ }
675
+ const base = Object.prototype.hasOwnProperty.call(held, groupId)
676
+ ? held[groupId]
677
+ : toStoredGroupValue(group.type, this._defaultValue(group));
678
+ const screen = this._cleared.has(groupId) ? null : toStoredGroupValue(group.type, this._values.get(groupId));
679
+ return !sameStoredGroupValue(base, screen);
680
+ });
681
+ }
682
+ // The interaction state a tile's data request carries now: tileDataState
683
+ // over the open report and the screen's snapshot().
684
+ tileState(component) {
685
+ return tileDataState(this._report(), component, this.snapshot());
686
+ }
687
+ // The relative range a group's value still is, as a data request names it
688
+ // (its preset while its days are that range resolved today), or null. The
689
+ // export wording names a live preset by it.
690
+ livePreset(groupId) {
691
+ const value = this._values.get(groupId);
692
+ return value ? this._livePreset(value) : null;
693
+ }
477
694
  // A group value as the fields a request carries: date bounds as calendar
478
- // days, select values when any are picked, keyword text trimmed. Null when
479
- // all of them are empty. A date range also names the relative range it
480
- // still is (_livePreset), so the server knows which period the days cover;
695
+ // days, select values when any are picked (else the values left out),
696
+ // keyword text trimmed, a number range's ends. Null when all of them are
697
+ // empty. A date range also names the relative range it still is
698
+ // (_livePreset), so the server knows which period the days cover;
481
699
  // the days stay the window either way. Component data, the report and page
482
700
  // exports and the chat's viewer filters all read their fields here, so all
483
701
  // three carry it.
@@ -499,7 +717,9 @@ export class ReportFilterStateService {
499
717
  if (value.value?.trim()) {
500
718
  fields.value = value.value.trim();
501
719
  }
720
+ this._resolveExcludeAndRange(value, fields);
502
721
  return fields.start || fields.end || fields.values || fields.value
722
+ || fields.excludeValues || fields.min !== undefined || fields.max !== undefined
503
723
  ? fields
504
724
  : null;
505
725
  }
@@ -540,74 +760,6 @@ export class ReportFilterStateService {
540
760
  this._values.delete(group.id);
541
761
  }
542
762
  }
543
- // Applies the viewer state read from the URL on top of the seeded defaults.
544
- _restore(report, restore) {
545
- this._restoreGroups(restore);
546
- this._restoreListSorts(report, restore);
547
- this._restoreListSearches(report, restore);
548
- this._restoreListHidden(restore);
549
- // The URL is the whole truth on a first load: no grain in it means the
550
- // authored ones. The host still drops a grain the report does not offer.
551
- this._frequency = GRANULARITY_OPTIONS
552
- .find((option) => option.value === restore.groupBy)?.value ?? null;
553
- }
554
- // The URL's group values. An empty one is an explicit clear of the group.
555
- _restoreGroups(restore) {
556
- restore.groups.forEach((raw, groupId) => {
557
- const group = this._groups.get(groupId);
558
- const value = group
559
- ? decodeFilterValue(group.type, raw, (name) => this.resolveRelative(name))
560
- : undefined;
561
- if (value === null) {
562
- this._values.delete(groupId);
563
- if (group?.config?.default) {
564
- this._cleared.add(groupId);
565
- }
566
- }
567
- else if (value) {
568
- this._values.set(groupId, value);
569
- this._cleared.delete(groupId);
570
- }
571
- });
572
- }
573
- // The URL's list sorts, each kept only for a list the report has and a
574
- // column that list can be sorted by.
575
- _restoreListSorts(report, restore) {
576
- const lists = new Map(this._listComponents(report).map((component) => [component.id, component]));
577
- restore.listSorts.forEach((raw, componentId) => {
578
- const component = lists.get(componentId);
579
- const sort = decodeSort(raw);
580
- if (component && sort && this._sortableColumns(component).includes(sort.column)) {
581
- this._listSorts.set(componentId, sort);
582
- }
583
- });
584
- }
585
- // The URL's list searches, each kept only for a list the report has that
586
- // shows a search box (listSearchable). The text is read as listSearchText,
587
- // and an empty one is no search.
588
- _restoreListSearches(report, restore) {
589
- const lists = new Map(this._listComponents(report).map((component) => [component.id, component]));
590
- restore.listSearches.forEach((raw, componentId) => {
591
- const component = lists.get(componentId);
592
- const search = listSearchText(raw);
593
- if (component && this.listSearchable(component) && search) {
594
- this._listSearches.set(componentId, search);
595
- }
596
- });
597
- }
598
- // The URL's hidden columns, each list's kept to listHiddenColumns: only the
599
- // configured columns of a plain list the report has, and none when they
600
- // would hide every column.
601
- _restoreListHidden(restore) {
602
- const next = new Map(this.listHidden());
603
- restore.listHidden.forEach((raw, componentId) => {
604
- const hidden = listHiddenColumns(this._lists.get(componentId)?.config, decodeColumnList(raw));
605
- if (hidden.length) {
606
- next.set(componentId, hidden);
607
- }
608
- });
609
- this.listHidden.set(next);
610
- }
611
763
  // Drops the search of every list that no longer shows a search box: one
612
764
  // the report no longer has, or one whose header now has a keyword group.
613
765
  _dropUnsearchable() {
@@ -667,33 +819,6 @@ export class ReportFilterStateService {
667
819
  ? { ...fixed, preset: stored.preset }
668
820
  : fixed;
669
821
  }
670
- // Whether a value is the group's authored default, by type: a date range on
671
- // its days (the default resolved today), a select on its values in any
672
- // order, a keyword on its text.
673
- _isDefault(group, value) {
674
- const defaultValue = this._defaultValue(group);
675
- if (!defaultValue) {
676
- return false;
677
- }
678
- switch (group.type) {
679
- case 'dateRange':
680
- // An untouched rolling default still carries its preset name. Its days
681
- // were resolved when it was seeded, and after midnight they no longer
682
- // match today's, but it is still the default and stays out of the URL.
683
- if (value.preset && value.preset === group.config?.default?.relative) {
684
- return true;
685
- }
686
- return sameDays(value, defaultValue);
687
- case 'select': {
688
- const values = (value.values ?? []).map(String).sort();
689
- const defaults = (defaultValue.values ?? []).map(String).sort();
690
- return values.length === defaults.length
691
- && values.every((item, index) => item === defaults[index]);
692
- }
693
- default:
694
- return (value.value ?? '').trim() === (defaultValue.value ?? '').trim();
695
- }
696
- }
697
822
  _listComponents(report) {
698
823
  return reportComponents(report)
699
824
  .filter((component) => component.type === 'list');
@@ -732,7 +857,7 @@ export class ReportFilterStateService {
732
857
  if (groupDefault.value) {
733
858
  return { value: groupDefault.value };
734
859
  }
735
- return null;
860
+ return this._excludeOrRangeDefault(groupDefault);
736
861
  }
737
862
  // A relative preset as a calendar-day range. "Today" is the day in the
738
863
  // report's effective zone, not the browser's, so every viewer seeds the same
@@ -779,10 +904,343 @@ export class ReportFilterStateService {
779
904
  return null;
780
905
  }
781
906
  }
907
+ // Every group in its stored shape: null when it holds nothing, a default
908
+ // the viewer cleared included.
909
+ _snapshotGroups() {
910
+ const groups = {};
911
+ this._groups.forEach((group) => {
912
+ groups[group.id] = this._cleared.has(group.id)
913
+ ? null
914
+ : toStoredGroupValue(group.type, this._values.get(group.id));
915
+ });
916
+ return groups;
917
+ }
918
+ // Each tile's state where it differs from the authored tile. A list sort
919
+ // that is the list's authored first term is its default, not a choice.
920
+ _snapshotTiles() {
921
+ const tiles = {};
922
+ for (const component of this._tiles()) {
923
+ const tile = {};
924
+ const sort = this._listSorts.get(component.id);
925
+ const search = this._listSearches.get(component.id);
926
+ const hidden = this.hiddenColumns(component.id);
927
+ const drill = this.drill(component.id);
928
+ if (sort && !sameSort(sort, listSortTerms(component.config)[0] ?? null)) {
929
+ tile.sort = { ...sort };
930
+ }
931
+ if (search) {
932
+ tile.search = search;
933
+ }
934
+ if (hidden.length) {
935
+ tile.hidden = [...hidden];
936
+ }
937
+ if (drill.length) {
938
+ tile.drill = drill.map((step) => ({ ...step }));
939
+ }
940
+ if (Object.keys(tile).length) {
941
+ tiles[component.id] = tile;
942
+ }
943
+ }
944
+ return tiles;
945
+ }
946
+ // The view apply() was given, applied as the screen's state and kept as
947
+ // the base. What is kept is the snapshot of it, with only the groups it
948
+ // held: a group it did not hold, or held in a shape that does not fit,
949
+ // follows its authored default (viewDiffers compares it with
950
+ // authoredConfig()).
951
+ _setBase(base) {
952
+ const held = this._applyLayer(base);
953
+ if (!base) {
954
+ this._baseConfig.set(null);
955
+ return;
956
+ }
957
+ // The page is the base's own, not the one on screen.
958
+ const applied = this.snapshot();
959
+ delete applied.pageId;
960
+ applied.groups = Object.fromEntries(Object.entries(applied.groups ?? {})
961
+ .filter(([groupId]) => held.has(Number(groupId))));
962
+ if (base.pageId && (this._report()?.pages ?? []).some((page) => page.id === base.pageId)) {
963
+ applied.pageId = base.pageId;
964
+ }
965
+ this._baseConfig.set(applied);
966
+ }
967
+ // Applies a view's state in place of the whole durable state, and gives the
968
+ // ids of the groups it set: what `config` does not hold goes back to the
969
+ // authored report. Nothing is announced here: the caller announces once
970
+ // (_notifyApplied).
971
+ _applyLayer(config) {
972
+ const held = this._applyGroups(config?.groups ?? {});
973
+ this._match.set(config?.match === 'any' ? 'any' : 'all');
974
+ const groupBy = config?.groupBy;
975
+ this._frequency = isChartGranularity(groupBy) ? groupBy : null;
976
+ this._clearTiles();
977
+ Object.entries(config?.tiles ?? {})
978
+ .forEach(([componentId, tile]) => this._applyTile(Number(componentId), tile ?? {}));
979
+ return held;
980
+ }
981
+ // Each group's value from a view; a group it does not set goes back to its
982
+ // authored default.
983
+ _applyGroups(groups) {
984
+ const held = new Set();
985
+ this._groups.forEach((group) => {
986
+ if (Object.prototype.hasOwnProperty.call(groups, group.id) && this._applyGroup(group, groups[group.id])) {
987
+ held.add(group.id);
988
+ }
989
+ else {
990
+ this._seedAuthored(group);
991
+ }
992
+ });
993
+ return held;
994
+ }
995
+ // One group's stored value, or false when the group's type cannot hold it
996
+ // (it is then dropped whole, and the caller seeds the group's authored
997
+ // default). null, or a value that holds nothing, clears the group.
998
+ _applyGroup(group, stored) {
999
+ const kept = stored === null ? {} : groupValueFromStored(stored, group.type);
1000
+ if (kept === null) {
1001
+ return false;
1002
+ }
1003
+ const value = toLiveGroupValue(group.type, kept, (name) => this.resolveRelative(name));
1004
+ if (value) {
1005
+ this._values.set(group.id, value);
1006
+ this._cleared.delete(group.id);
1007
+ }
1008
+ else {
1009
+ this._values.delete(group.id);
1010
+ this._cleared.delete(group.id);
1011
+ if (group.config?.default) {
1012
+ this._cleared.add(group.id);
1013
+ }
1014
+ }
1015
+ return true;
1016
+ }
1017
+ // A group back at its authored default.
1018
+ _seedAuthored(group) {
1019
+ const value = this._defaultValue(group);
1020
+ this._cleared.delete(group.id);
1021
+ if (value) {
1022
+ this._values.set(group.id, value);
1023
+ }
1024
+ else {
1025
+ this._values.delete(group.id);
1026
+ }
1027
+ }
1028
+ // Every tile back at its authored state.
1029
+ _clearTiles() {
1030
+ this._listSorts.clear();
1031
+ this._listSearches.clear();
1032
+ this.listHidden.set(new Map());
1033
+ this._drills.set(new Map());
1034
+ }
1035
+ // One tile's stored state, each key checked: a sort on a column the list
1036
+ // can sort by, a search on a list that shows the box, hidden columns the
1037
+ // list can hide, a drill path on a chart.
1038
+ _applyTile(componentId, tile) {
1039
+ const list = this._lists.get(componentId);
1040
+ if (list) {
1041
+ this._applyListTile(list, tile);
1042
+ }
1043
+ if (Array.isArray(tile.drill) && this._isChart(componentId)) {
1044
+ this._setDrillPath(componentId, cleanDrillPath(tile.drill));
1045
+ }
1046
+ }
1047
+ // A list's sort, search and hidden columns from a tile state, kept by the
1048
+ // rules setListSort, setListSearch and setHiddenColumns apply, but set
1049
+ // straight on the maps: those setters each announce a change, and an apply
1050
+ // announces once, at its end. A sort that is the list's authored first
1051
+ // term is its default, so it clears the entry.
1052
+ _applyListTile(list, tile) {
1053
+ const sort = tile.sort;
1054
+ if (sort?.column && this._sortableColumns(list).includes(sort.column)) {
1055
+ if (sameSort(sort, listSortTerms(list.config)[0] ?? null)) {
1056
+ this._listSorts.delete(list.id);
1057
+ }
1058
+ else {
1059
+ this._listSorts.set(list.id, { ...sort });
1060
+ }
1061
+ }
1062
+ if (typeof tile.search === 'string') {
1063
+ const search = listSearchText(tile.search);
1064
+ if (search && this.listSearchable(list)) {
1065
+ this._listSearches.set(list.id, search);
1066
+ }
1067
+ else {
1068
+ this._listSearches.delete(list.id);
1069
+ }
1070
+ }
1071
+ if (Array.isArray(tile.hidden)) {
1072
+ const hidden = listHiddenColumns(list.config, tile.hidden);
1073
+ const next = new Map(this.listHidden());
1074
+ if (hidden.length) {
1075
+ next.set(list.id, hidden);
1076
+ }
1077
+ else {
1078
+ next.delete(list.id);
1079
+ }
1080
+ this.listHidden.set(next);
1081
+ }
1082
+ }
1083
+ // One chart's drill path; an empty path is the chart's top.
1084
+ _setDrillPath(componentId, path) {
1085
+ const next = new Map(this._drills());
1086
+ if (path.length) {
1087
+ next.set(componentId, path);
1088
+ }
1089
+ else {
1090
+ next.delete(componentId);
1091
+ }
1092
+ this._drills.set(next);
1093
+ }
1094
+ // The page a layer names, when the report has it.
1095
+ _applyPage(pageId) {
1096
+ if (pageId && (this._report()?.pages ?? []).some((page) => page.id === pageId)) {
1097
+ this._pageId.set(pageId);
1098
+ }
1099
+ }
1100
+ // After apply() or resetToBase(): every bar and tile repaints, and the
1101
+ // time-series charts refetch when the grain moved.
1102
+ _notifyApplied(frequency) {
1103
+ this._stateVersion.update((version) => version + 1);
1104
+ this._changed$.next(null);
1105
+ if (frequency !== this._frequency) {
1106
+ this._frequencyChanged$.next();
1107
+ }
1108
+ this._stateChanged$.next();
1109
+ }
1110
+ // The tiles of the report init() last read.
1111
+ _tiles() {
1112
+ const report = this._report();
1113
+ return report
1114
+ ? reportComponents(report).filter(isTile)
1115
+ : [];
1116
+ }
1117
+ _isChart(componentId) {
1118
+ return this._tiles()
1119
+ .some((component) => component.id === componentId && component.type === 'chart');
1120
+ }
1121
+ // Keeps the view state to what the report (re)loaded by init() still has:
1122
+ // drill paths on charts it still has, the page while it has it, and the
1123
+ // base to what the screen can still show (_pruneBase). On another report it
1124
+ // starts again: no open view, match 'all', no drill and nothing temporary.
1125
+ _pruneViewState(report, previousGroups) {
1126
+ if (this._report()?.id !== report.id) {
1127
+ this._baseConfig.set(null);
1128
+ this._match.set('all');
1129
+ this._pageId.set(null);
1130
+ this._drills.set(new Map());
1131
+ this._temporary.set(emptyTemporaryState());
1132
+ }
1133
+ this._report.set(report);
1134
+ this._drills.set(new Map([...this._drills()]
1135
+ .filter(([componentId]) => this._isChart(componentId))));
1136
+ if (this._pageId() && !(report.pages ?? []).some((page) => page.id === this._pageId())) {
1137
+ this._pageId.set(null);
1138
+ }
1139
+ this._pruneBase(previousGroups);
1140
+ }
1141
+ // Keeps the base to what the screen can still show, by the rules the live
1142
+ // state is pruned by (_prune, _seed and the drill pruning above), so an
1143
+ // edit of the report alone never reads as '(edited)'. A group whose
1144
+ // authored default changed leaves the base and follows the new default,
1145
+ // as the live value does (_seed re-seeds it); so does a group the report
1146
+ // no longer has. Each tile keeps only the state its component can still
1147
+ // take (_baseTile).
1148
+ _pruneBase(previousGroups) {
1149
+ const base = this._baseConfig();
1150
+ if (!base) {
1151
+ return;
1152
+ }
1153
+ const groups = Object.fromEntries(Object.entries(base.groups ?? {})
1154
+ .filter(([groupId]) => {
1155
+ const group = this._groups.get(Number(groupId));
1156
+ return !!group
1157
+ && sameDefault(previousGroups.get(group.id)?.config?.default ?? null, group.config?.default ?? null);
1158
+ }));
1159
+ const tiles = Object.fromEntries(Object.entries(base.tiles ?? {})
1160
+ .map(([componentId, tile]) => [componentId, this._baseTile(Number(componentId), tile)])
1161
+ .filter(([, tile]) => Object.keys(tile).length));
1162
+ const pruned = { ...base, groups };
1163
+ delete pruned.tiles;
1164
+ if (Object.keys(tiles).length) {
1165
+ pruned.tiles = tiles;
1166
+ }
1167
+ this._baseConfig.set(pruned);
1168
+ }
1169
+ // A base tile's state, kept to what its component can still take: a sort
1170
+ // on a column the list can still sort by that is not now its authored
1171
+ // first term, a search while the list shows the box, the hidden columns
1172
+ // the list still has, a drill path while the component is a chart.
1173
+ _baseTile(componentId, tile) {
1174
+ const kept = {};
1175
+ const list = this._lists.get(componentId);
1176
+ const hidden = list && tile.hidden ? listHiddenColumns(list.config, tile.hidden) : [];
1177
+ if (list && tile.sort && this._sortableColumns(list).includes(tile.sort.column)
1178
+ && !sameSort(tile.sort, listSortTerms(list.config)[0] ?? null)) {
1179
+ kept.sort = tile.sort;
1180
+ }
1181
+ if (list && tile.search && this.listSearchable(list)) {
1182
+ kept.search = tile.search;
1183
+ }
1184
+ if (hidden.length) {
1185
+ kept.hidden = hidden;
1186
+ }
1187
+ if (tile.drill?.length && this._isChart(componentId)) {
1188
+ kept.drill = tile.drill;
1189
+ }
1190
+ return kept;
1191
+ }
1192
+ // A select's values to leave out (only when it keeps none) and a number
1193
+ // range's ends, an open end left out and 0 kept, written onto `fields`.
1194
+ _resolveExcludeAndRange(value, fields) {
1195
+ if (value.excludeValues?.length && !fields.values) {
1196
+ fields.excludeValues = value.excludeValues;
1197
+ }
1198
+ const min = finiteNumber(value.min);
1199
+ const max = finiteNumber(value.max);
1200
+ if (min !== undefined) {
1201
+ fields.min = min;
1202
+ }
1203
+ if (max !== undefined) {
1204
+ fields.max = max;
1205
+ }
1206
+ }
1207
+ // An authored default that leaves select values out, or a number range's
1208
+ // ends (0 kept), as a session value; null when it holds neither.
1209
+ _excludeOrRangeDefault(groupDefault) {
1210
+ if (groupDefault.excludeValues?.length) {
1211
+ return { excludeValues: groupDefault.excludeValues };
1212
+ }
1213
+ const min = finiteNumber(groupDefault.min);
1214
+ const max = finiteNumber(groupDefault.max);
1215
+ if (min === undefined && max === undefined) {
1216
+ return null;
1217
+ }
1218
+ return {
1219
+ ...(min !== undefined ? { min } : {}),
1220
+ ...(max !== undefined ? { max } : {}),
1221
+ };
1222
+ }
1223
+ // Counts a reset for each list whose sort is not the one it had (`before`,
1224
+ // the sorts by list before the reset). A sort a list lost and one it
1225
+ // gained both count; the authored sort is no entry either side.
1226
+ _countSortResets(before) {
1227
+ const moved = [...new Set([...before.keys(), ...this._listSorts.keys()])]
1228
+ .filter((componentId) => {
1229
+ const was = before.get(componentId);
1230
+ const now = this._listSorts.get(componentId) ?? null;
1231
+ return was ? !sameSort(was, now) : now !== null;
1232
+ });
1233
+ if (!moved.length) {
1234
+ return;
1235
+ }
1236
+ const counts = new Map(this._listSortResets());
1237
+ moved.forEach((componentId) => counts.set(componentId, (counts.get(componentId) ?? 0) + 1));
1238
+ this._listSortResets.set(counts);
1239
+ }
782
1240
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportFilterStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
783
1241
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportFilterStateService });
784
1242
  }
785
1243
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportFilterStateService, decorators: [{
786
1244
  type: Injectable
787
1245
  }] });
788
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LWZpbHRlci1zdGF0ZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL3NlcnZpY2VzL3JlcG9ydC1maWx0ZXItc3RhdGUuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVuRCxPQUFPLEVBQWMsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxJQUFJLFFBQVEsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXpELE9BQU8sRUFDTCxTQUFTLEVBQUUsWUFBWSxFQUFFLGNBQWMsRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUNqRSxPQUFPLEVBQUUsU0FBUyxFQUFFLFFBQVEsR0FDN0IsTUFBTSxVQUFVLENBQUM7QUFFbEIsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDcEUsT0FBTyxFQUNMLHNCQUFzQixFQUFFLFdBQVcsRUFBRSxvQkFBb0IsRUFBRSxxQkFBcUIsR0FDakYsTUFBTSxXQUFXLENBQUM7QUFFbkIsT0FBTyxFQUlMLG1CQUFtQixHQVVwQixNQUFNLGdDQUFnQyxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxhQUFhLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNsRSxPQUFPLEVBQUUsZUFBZSxFQUFFLHNCQUFzQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDakYsT0FBTyxFQUFFLGdCQUFnQixFQUFFLGlCQUFpQixFQUFFLFVBQVUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3RGLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLFdBQVcsQ0FBQzs7QUFHN0MsOEVBQThFO0FBQzlFLHFFQUFxRTtBQUNyRSxNQUFNLGVBQWUsR0FBc0M7SUFDekQsUUFBUSxFQUFFLElB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LFNBQVMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO1lBQ2pELEtBQUssV0FBVztnQkFDZCxPQUFPLEVBQUUsS0FBSyxFQUFFLFlBQVksQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7WUFDaEQsS0FBSyxhQUFhO2dCQUNoQixPQUFPLEVBQUUsS0FBSyxFQUFFLGNBQWMsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7WUFDbEQsS0FBSyxVQUFVLENBQUM7WUFDaEIsS0FBSyxZQUFZO2dCQUNmLE9BQU8sRUFBRSxLQUFLLEVBQUUsV0FBVyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztZQUMvQztnQkFDRSxPQUFPLElBQUksQ0FBQztRQUNoQixDQUFDO0lBQ0gsQ0FBQzt3R0FweEJVLHdCQUF3Qjs0R0FBeEIsd0JBQXdCOzs0RkFBeEIsd0JBQXdCO2tCQURwQyxVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgc2lnbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IE9ic2VydmFibGUsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1hcCwgZmlsdGVyIGFzIHJ4RmlsdGVyIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQge1xuICBlbmRPZldlZWssIHN0YXJ0T2ZNb250aCwgc3RhcnRPZlF1YXJ0ZXIsIHN0YXJ0T2ZXZWVrLCBzdGFydE9mWWVhcixcbiAgc3ViRGF5cywgc3ViTW9udGhzLCBzdWJXZWVrcyxcbn0gZnJvbSAnZGF0ZS1mbnMnO1xuXG5pbXBvcnQgeyBSRVBPUlRfV0VFS19TVEFSVFNfT04gfSBmcm9tICcuLi9jb25zdHMvcmVwb3J0LXdlZWsuY29uc3QnO1xuaW1wb3J0IHtcbiAgREVGQVVMVF9GT1JNQVRfQ09OVEVYVCwgZ2V0Wm9uZWROb3csIHJlc29sdmVGb3JtYXRDb250ZXh0LCByZXNvbHZlUmVwb3J0VGltZXpvbmUsXG59IGZyb20gJy4uL2Zvcm1hdCc7XG5pbXBvcnQgeyBSZXBvcnRDaGF0Vmlld2VyRmlsdGVyIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZXBvcnQtY2hhdC12aWV3ZXItZmlsdGVyLmludGVyZmFjZSc7XG5pbXBvcnQge1xuICBDaGFydEdyYW51bGFyaXR5LFxuICBGaWx0ZXJHcm91cERlZmF1bHQsXG4gIEZpbHRlckdyb3VwVmFsdWUsXG4gIEdSQU5VTEFSSVRZX09QVElPTlMsXG4gIFJlcG9ydCxcbiAgUmVwb3J0Q29tcG9uZW50LFxuICBSZXBvcnRGaWx0ZXJHcm91cCxcbiAgUmVwb3J0Rm9ybWF0Q29udGV4dCxcbiAgUmVwb3J0UmVsYXRpdmVSYW5nZSxcbiAgUmVwb3J0U29ydCxcbiAgUmVwb3J0VXJsUGFyYW1zLFxuICBSZXBvcnRVcmxTbmFwc2hvdCxcbiAgUmVzb2x2ZWRGaWx0ZXJWYWx1ZSxcbn0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZXBvcnQuaW50ZXJmYWNlJztcbmltcG9ydCB7IGxpc3RIaWRkZW5Db2x1bW5zLCBsaXN0U29ydFRlcm1zIH0gZnJvbSAnLi4vbGlzdC1jb25maWcnO1xuaW1wb3J0IHsgZGF0ZUJvdW5kU3RyaW5nLCBMSVNUX1NFQVJDSF9NQVhfTEVOR1RIIH0gZnJvbSAnLi4vcmVwb3J0LWZpbHRlci1pdGVtcyc7XG5pbXBvcnQgeyBkZWNvZGVDb2x1bW5MaXN0LCBkZWNvZGVGaWx0ZXJWYWx1ZSwgZGVjb2RlU29ydCB9IGZyb20gJy4uL3JlcG9ydC11cmwtc3RhdGUnO1xuaW1wb3J0IHsgcmVwb3J0Q29tcG9uZW50cyB9IGZyb20gJy4uL3ZhbHVlcyc7XG5cblxuLy8gRXZlcnkgcmVsYXRpdmUgcmFuZ2UgbmFtZSB0aGUgc2VydmVyIGtub3dzLiBBIHJlY29yZCByYXRoZXIgdGhhbiBhIGxpc3QsIHNvXG4vLyB0aGUgYnVpbGQgZmFpbHMgd2hlbiBSZXBvcnRSZWxhdGl2ZVJhbmdlIGdhaW5zIGEgbmFtZSB0aGlzIG1pc3Nlcy5cbmNvbnN0IFJFTEFUSVZFX1JBTkdFUzogUmVjb3JkPFJlcG9ydFJlbGF0aXZlUmFuZ2UsIHRydWU+ID0ge1xuICB0aGlzV2VlazogdHJ1ZSxcbiAgbGFzdFdlZWs6IHRydWUsXG4gIGxhc3Q3RGF5czogdHJ1ZSxcbiAgbGFzdDMwRGF5czogdHJ1ZSxcbiAgbGFzdDNNb250aHM6IHRydWUsXG4gIGxhc3Q2TW9udGhzOiB0cnVlLFxuICBsYXN0MTJNb250aHM6IHRydWUsXG4gIHRoaXNNb250aDogdHJ1ZSxcbiAgdGhpc1F1YXJ0ZXI6IHRydWUsXG4gIHRoaXNZZWFyOiB0cnVlLFxuICB5ZWFyVG9EYXRlOiB0cnVlLFxufTtcblxuXG4vLyBXaGV0aGVyIGEgc3RvcmVkIHByZXNldCBuYW1lIGlzIG9uZSB0aGUgc2VydmVyIHJlc29sdmVzIChSZXBvcnRSZWxhdGl2ZVJhbmdlKS5cbmZ1bmN0aW9uIGlzUmVsYXRpdmVSYW5nZShuYW1lOiBzdHJpbmcpOiBuYW1lIGlzIFJlcG9ydFJlbGF0aXZlUmFuZ2Uge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKFJFTEFUSVZFX1JBTkdFUywgbmFtZSk7XG59XG5cblxuLy8gV2hldGhlciB0d28gc3RvcmVkIGZpbHRlci1ncm91cCBkZWZhdWx0cyBhcmUgdGhlIHNhbWUuIENvbXBhcmVkIG9uIHRoZSBmaWVsZHMgYVxuLy8gZGVmYXVsdCBjYW4gYWN0dWFsbHkgY2FycnksIHNvIGtleSBvcmRlciBpbiB0aGUgcGF5bG9hZCBjYW4ndCByZWFkIGFzIGEgY2hhbmdlLlxuZXhwb3J0IGZ1bmN0aW9uIHNhbWVEZWZhdWx0KFxuICBhOiBGaWx0ZXJHcm91cERlZmF1bHQgfCBudWxsLFxuICBiOiBGaWx0ZXJHcm91cERlZmF1bHQgfCBudWxsLFxuKTogYm9vbGVhbiB7XG4gIGlmICghYSB8fCAhYikge1xuICAgIHJldHVybiAhYSAmJiAhYjtcbiAgfVxuXG4gIHJldHVybiBhLnN0YXJ0ID09PSBiLnN0YXJ0XG4gICAgJiYgYS5lbmQgPT09IGIuZW5kXG4gICAgJiYgYS52YWx1ZSA9PT0gYi52YWx1ZVxuICAgICYmIGEucmVsYXRpdmUgPT09IGIucmVsYXRpdmVcbiAgICAmJiAoYS52YWx1ZXMgPz8gW10pLmxlbmd0aCA9PT0gKGIudmFsdWVzID8/IFtdKS5sZW5ndGhcbiAgICAmJiAoYS52YWx1ZXMgPz8gW10pLmV2ZXJ5KCh2YWx1ZSwgaW5kZXgpID0+IHZhbHVlID09PSAoYi52YWx1ZXMgPz8gW10pW2luZGV4XSk7XG59XG5cblxuLy8gV2hldGhlciB0d28gbGlzdCBzb3J0cyBvcmRlciB0aGUgcm93cyB0aGUgc2FtZSB3YXkuIE5vIGRpcmVjdGlvbiByZWFkcyBhc1xuLy8gYXNjZW5kaW5nLCB0aGUgd2F5IHRoZSBsaXN0IGFwcGxpZXMgaXQuXG5mdW5jdGlvbiBzYW1lU29ydChhOiBSZXBvcnRTb3J0LCBiOiBSZXBvcnRTb3J0IHwgbnVsbCk6IGJvb2xlYW4ge1xuICByZXR1cm4gISFiXG4gICAgJiYgYS5jb2x1bW4gPT09IGIuY29sdW1uXG4gICAgJiYgKGEuZGlyZWN0aW9uID8/ICdhc2MnKSA9PT0gKGIuZGlyZWN0aW9uID8/ICdhc2MnKTtcbn1cblxuXG4vLyBXaGV0aGVyIGEgdmFsdWUgcmVhZCBvZmYgYSBmaWx0ZXIgYmFyIGlzIHRoZSB2YWx1ZSBhbHJlYWR5IHN0b3JlZCBmb3IgaXRzXG4vLyBncm91cDogdGhlIHNhbWUgY2FsZW5kYXIgZGF5cywgdGhlIHNhbWUgc2VsZWN0IHZhbHVlcyBpbiB0aGUgc2FtZSBvcmRlciBhbmRcbi8vIHRoZSBzYW1lIHRyaW1tZWQgdGV4dC4gQSBiYXIgcmUtcmVhZHMgZXZlcnkgZ3JvdXAgaXQgc2hvd3Mgb24gYW55IGNoYW5nZSwgc29cbi8vIHRoaXMgaXMgd2hhdCB0ZWxscyB0aGUgZ3JvdXAgdGhhdCBjaGFuZ2VkIGZyb20gdGhlIG9uZXMgdGhhdCBkaWQgbm90LlxuZXhwb3J0IGZ1bmN0aW9uIHNhbWVGaWx0ZXJWYWx1ZShcbiAgYTogRmlsdGVyR3JvdXBWYWx1ZSB8IG51bGwgfCB1bmRlZmluZWQsXG4gIGI6IEZpbHRlckdyb3VwVmFsdWUgfCBudWxsIHwgdW5kZWZpbmVkLFxuKTogYm9vbGVhbiB7XG4gIGlmICghYSB8fCAhYikge1xuICAgIHJldHVybiAhYSAmJiAhYjtcbiAgfVxuXG4gIGNvbnN0IHZhbHVlcyA9ICh2YWx1ZTogRmlsdGVyR3JvdXBWYWx1ZSkgPT4gKHZhbHVlLnZhbHVlcyA/PyBbXSkubWFwKFN0cmluZyk7XG5cbiAgcmV0dXJuIHNhbWVEYXlzKGEsIGIpXG4gICAgJiYgdmFsdWVzKGEpLmpvaW4oJ1xcdTAwMDAnKSA9PT0gdmFsdWVzKGIpLmpvaW4oJ1xcdTAwMDAnKVxuICAgICYmIHZhbHVlcyhhKS5sZW5ndGggPT09IHZhbHVlcyhiKS5sZW5ndGhcbiAgICAmJiAoYS52YWx1ZSA/PyAnJykudHJpbSgpID09PSAoYi52YWx1ZSA/PyAnJykudHJpbSgpO1xufVxuXG5cbi8vIFRoZSBncm91cHMgYSBiYXIgcmUtcmVhZCB0aGF0IGl0IG5vdyBzaG93cyB3aXRoIGEgdmFsdWUgb3RoZXIgdGhhbiB0aGUgb25lXG4vLyBpdCBsYXN0IHJlcG9ydGVkLCByZWNvcmRpbmcgZWFjaCBuZXcgdmFsdWUgaW4gYGxhc3RSZXBvcnRlZGAuIEEgYmFyIGlzXG4vLyBjb21wYXJlZCB3aXRoIGl0c2VsZiwgbmV2ZXIgd2l0aCB0aGUgc3RvcmVkIHZhbHVlOiBhIGdyb3VwIHNob3duIGluIHR3byBiYXJzXG4vLyAobGV2ZWwgJ2JvdGgnKSBjYW4gYmUgY2hhbmdlZCBpbiB0aGUgb3RoZXIgb25lLCBhbmQgdGhpcyBiYXIgaXMgbm90XG4vLyByZXBhaW50ZWQsIHNvIGl0cyBzdGFsZSB2YWx1ZSBtdXN0IG5vdCBiZSBzZXQgYmFjayB3aGVuIHRoZSB2aWV3ZXIgY2hhbmdlc1xuLy8gYW5vdGhlciBvZiBpdHMgaXRlbXMgKHRoZSBsaXN0IHNlYXJjaCBib3gsIHNheSkuXG5leHBvcnQgZnVuY3Rpb24gbW92ZWRHcm91cFZhbHVlcyhcbiAgbGFzdFJlcG9ydGVkOiBNYXA8bnVtYmVyLCBGaWx0ZXJHcm91cFZhbHVlIHwgbnVsbD4sXG4gIHJlcG9ydGVkOiB7IGdyb3VwSWQ6IG51bWJlcjsgdmFsdWU6IEZpbHRlckdyb3VwVmFsdWUgfCBudWxsIH1bXSxcbik6IHsgZ3JvdXBJZDogbnVtYmVyOyB2YWx1ZTogRmlsdGVyR3JvdXBWYWx1ZSB8IG51bGwgfVtdIHtcbiAgcmV0dXJuIHJlcG9ydGVkLmZpbHRlcigoeyBncm91cElkLCB2YWx1ZSB9KSA9PiB7XG4gICAgaWYgKHNhbWVGaWx0ZXJWYWx1ZShsYXN0UmVwb3J0ZWQuZ2V0KGdyb3VwSWQpLCB2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBsYXN0UmVwb3J0ZWQuc2V0KGdyb3VwSWQsIHZhbHVlKTtcblxuICAgIHJldHVybiB0cnVlO1xuICB9KTtcbn1cblxuXG4vLyBBIGxpc3QncyBzZWFyY2ggdGV4dCBhcyB0aGUgc2VydmVyIGFwcGxpZXMgaXQ6IHRyaW1tZWQsIHRoZW4gY3V0IHRvXG4vLyBMSVNUX1NFQVJDSF9NQVhfTEVOR1RIIGNoYXJhY3RlcnMgKGNvZGUgcG9pbnRzLCBhcyB0aGUgc2VydmVyIGNvdW50cyB0aGVtKS5cbmV4cG9ydCBmdW5jdGlvbiBsaXN0U2VhcmNoVGV4dCh0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gWy4uLnRleHQudHJpbSgpXS5zbGljZSgwLCBMSVNUX1NFQVJDSF9NQVhfTEVOR1RIKS5qb2luKCcnKTtcbn1cblxuXG4vLyBXaGV0aGVyIHR3byBsaXN0cyBvZiBjb2x1bW4gbmFtZXMgYXJlIHRoZSBzYW1lIG5hbWVzIGluIHRoZSBzYW1lIG9yZGVyLlxuZnVuY3Rpb24gc2FtZU5hbWVzKGE6IHJlYWRvbmx5IHN0cmluZ1tdLCBiOiByZWFkb25seSBzdHJpbmdbXSk6IGJvb2xlYW4ge1xuICByZXR1cm4gYS5sZW5ndGggPT09IGIubGVuZ3RoICYmIGEuZXZlcnkoKG5hbWUsIGluZGV4KSA9PiBuYW1lID09PSBiW2luZGV4XSk7XG59XG5cblxuLy8gV2hldGhlciB0d28gaGlkZGVuLWNvbHVtbiBtYXBzIGhpZGUgdGhlIHNhbWUgY29sdW1ucyBvbiB0aGUgc2FtZSBsaXN0cy5cbmZ1bmN0aW9uIHNhbWVIaWRkZW4oXG4gIGE6IFJlYWRvbmx5TWFwPG51bWJlciwgcmVhZG9ubHkgc3RyaW5nW10+LFxuICBiOiBSZWFkb25seU1hcDxudW1iZXIsIHJlYWRvbmx5IHN0cmluZ1tdPixcbik6IGJvb2xlYW4ge1xuICByZXR1cm4gYS5zaXplID09PSBiLnNpemVcbiAgICAmJiBbLi4uYV0uZXZlcnkoKFtjb21wb25lbnRJZCwgbmFtZXNdKSA9PiBzYW1lTmFtZXMobmFtZXMsIGIuZ2V0KGNvbXBvbmVudElkKSA/PyBbXSkpO1xufVxuXG5cbi8vIFdoZXRoZXIgdHdvIGRhdGUtcmFuZ2UgdmFsdWVzIGNvdmVyIHRoZSBzYW1lIGNhbGVuZGFyIGRheXMuXG5mdW5jdGlvbiBzYW1lRGF5cyhhOiBGaWx0ZXJHcm91cFZhbHVlLCBiOiBGaWx0ZXJHcm91cFZhbHVlKTogYm9vbGVhbiB7XG4gIHJldHVybiBkYXRlQm91bmRTdHJpbmcoYS5zdGFydCkgPT09IGRhdGVCb3VuZFN0cmluZyhiLnN0YXJ0KVxuICAgICYmIGRhdGVCb3VuZFN0cmluZyhhLmVuZCkgPT09IGRhdGVCb3VuZFN0cmluZyhiLmVuZCk7XG59XG5cblxuLy8gQSBzdGFibGUgc2lnbmF0dXJlIGZvciBhIGdyb3VwJ3Mgc3RvcmVkIGRlZmF1bHQuIFRoZSByZXBvcnQgdG9vbGJhciBrZXlzIGl0c1xuLy8gZnMtZmlsdGVyIG9uIHRoaXMsIGJlY2F1c2UgZnMtZmlsdGVyIHJlYWRzIGl0cyBjb25maWcgb25jZSBhdCBpbml0IOKAlCB3aXRob3V0IGFcbi8vIGtleSBjaGFuZ2UgaXQga2VlcHMgcmVuZGVyaW5nIHRoZSB2YWx1ZXMgaXQgd2FzIGNyZWF0ZWQgd2l0aCBldmVuIGFmdGVyIHRoZVxuLy8gY29uZmlnIGJlaGluZCBpdCBoYXMgYmVlbiByZWJ1aWx0LlxuZXhwb3J0IGZ1bmN0aW9uIGRlZmF1bHRTaWduYXR1cmUoZ3JvdXA6IFJlcG9ydEZpbHRlckdyb3VwKTogc3RyaW5nIHtcbiAgY29uc3QgZ3JvdXBEZWZhdWx0ID0gZ3JvdXAuY29uZmlnPy5kZWZhdWx0O1xuXG4gIGlmICghZ3JvdXBEZWZhdWx0KSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgcmV0dXJuIFtcbiAgICBncm91cERlZmF1bHQuc3RhcnQgPz8gJycsXG4gICAgZ3JvdXBEZWZhdWx0LmVuZCA/PyAnJyxcbiAgICBncm91cERlZmF1bHQudmFsdWUgPz8gJycsXG4gICAgZ3JvdXBEZWZhdWx0LnJlbGF0aXZlID8/ICcnLFxuICAgIChncm91cERlZmF1bHQudmFsdWVzID8/IFtdKS5qb2luKCcsJyksXG4gIF0uam9pbignficpO1xufVxuXG5cbi8vIFZpZXdlciBmaWx0ZXIgc3RhdGUgZm9yIHRoZSBvcGVuIHJlcG9ydC4gRmlsdGVyIFZBTFVFUyBhcmUgbmV2ZXIgc2F2ZWQgdG9cbi8vIHRoZSByZXBvcnQg4oCUIHRoaXMgc2VydmljZSBob2xkcyB0aGVtIHBlciBmaWx0ZXIgR1JPVVAgKHRoZSBwcm9wYWdhdGlvbiB1bml0KSxcbi8vIHJlc29sdmVzIHRoZW0gaW50byBwZXItY29tcG9uZW50IG1lbWJlci1maWx0ZXIgdmFsdWVzIGZvciBlYWNoIGRhdGEgcmVxdWVzdCxcbi8vIGFuZCBub3RpZmllcyB0aGUgY29tcG9uZW50cyB3aG9zZSBncm91cHMgY2hhbmdlZCBzbyBvbmx5IHRoZXkgcmVmZXRjaC5cbi8vXG4vLyBJdCBpcyBhbHNvIHRoZSBvbmUgc291cmNlIG9mIHRoZSB2aWV3ZXIgc3RhdGUgdGhlIHJlcG9ydCBVUkwgY2FycmllcyAoZ3JvdXBcbi8vIHZhbHVlcywgdGhlIGdyb3VwLWJ5IGdyYWluLCBsaXN0IHNvcnRzLCBzZWFyY2hlcyBhbmQgaGlkZGVuIGNvbHVtbnMpOlxuLy8gdXJsU25hcHNob3QoKSBzYXlzIHdoYXQgZGlmZmVycyBmcm9tIHRoZSBhdXRob3JlZCBkZWZhdWx0cywgaW5pdCgpIHJlc3RvcmVzXG4vLyBpdCwgYW5kIHVybENoYW5nZXMoKSB0ZWxscyB0aGUgaG9zdCdzIHNpbmdsZSBVUkwgd3JpdGVyIHdoZW4gdG8gd3JpdGUuXG4vL1xuLy8gU2Vzc2lvbi1vbmx5LCBuZXZlciBpbiB0aGUgVVJMOiBwZXItZmlsdGVyIGVuYWJsZS9kaXNhYmxlIHRvZ2dsZXMgZnJvbSBhXG4vLyBjb21wb25lbnQncyBmaWx0ZXIgbWVudSAodGhlIGBlbmFibGVkYCBjb2x1bW4gaXMgdGhlIGF1dGhvcmVkIGRlZmF1bHQ7IGFcbi8vIHZpZXdlcidzIHRvZ2dsZSBzaG91bGRuJ3Qgd3JpdGUgdG8gdGhlIHJlcG9ydCkuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgUmVwb3J0RmlsdGVyU3RhdGVTZXJ2aWNlIHtcblxuICAvLyBUaGUgb3BlbiByZXBvcnQncyBlZmZlY3RpdmUgem9uZSAocmVzb2x2ZVJlcG9ydFRpbWV6b25lKS4gUmVsYXRpdmUgcHJlc2V0c1xuICAvLyByZXNvbHZlIGFnYWluc3QgdG9kYXkgaW4gaXQsIGFuZCBkYXRlIGNlbGxzIHJlbmRlciBpbiBpdC5cbiAgcHVibGljIHJlYWRvbmx5IHRpbWV6b25lID0gc2lnbmFsPHN0cmluZz4oJ1VUQycpO1xuXG4gIC8vIEhvdyB0aGUgb3BlbiByZXBvcnQgd3JpdGVzIGl0cyBudW1iZXJzIGFuZCBkYXRlcyAocmVzb2x2ZUZvcm1hdENvbnRleHQpOlxuICAvLyBpdHMgbG9jYWxlLCBpdHMgY3VycmVuY3kgYW5kIHdoZXRoZXIgcGVyY2VudHMgYXJyaXZlIGFzIHJhdGlvcy4gRXZlcnkgS1BJLFxuICAvLyBjaGFydCwgZGF0ZSBjZWxsIGFuZCBleHBvcnQgcmVhZHMgaXQgaGVyZS4gQ29tcGFyZWQgYnkgdmFsdWUsIHNvIGEgcmVsb2FkXG4gIC8vIG9mIGFuIHVuY2hhbmdlZCByZXBvcnQgcmUtcmVuZGVycyBub3RoaW5nLlxuICBwdWJsaWMgcmVhZG9ubHkgZm9ybWF0Q29udGV4dCA9IHNpZ25hbDxSZXBvcnRGb3JtYXRDb250ZXh0PihERUZBVUxUX0ZPUk1BVF9DT05URVhULCB7XG4gICAgZXF1YWw6IChhLCBiKSA9PiBhLmxvY2FsZSA9PT0gYi5sb2NhbGVcbiAgICAgICYmIGEuY3VycmVuY3kgPT09IGIuY3VycmVuY3lcbiAgICAgICYmIGEucmF0aW9QZXJjZW50ID09PSBiLnJhdGlvUGVyY2VudCxcbiAgfSk7XG5cbiAgLy8gVGhlIGNvbmZpZyBjb2x1bW5zIGEgdmlld2VyIGhpZCBvbiBlYWNoIHBsYWluIGxpc3QgKGxpc3RIaWRkZW5Db2x1bW5zKSxcbiAgLy8gYnkgY29tcG9uZW50IGlkOyBhIGxpc3Qgc2hvd2luZyBldmVyeSBjb2x1bW4gaGFzIG5vIGVudHJ5LiBBIHNpZ25hbCwgc28gYVxuICAvLyBsaXN0IGhpZGVzIGFuZCBzaG93cyBpdHMgY29sdW1ucyBpbiBwbGFjZTogdGhlIHJvd3MgZG8gbm90IGNoYW5nZSwgc29cbiAgLy8gbm90aGluZyByZWZldGNoZXMuIENvbXBhcmVkIGJ5IHZhbHVlLCBzbyBhIHJlbG9hZCB0aGF0IGtlZXBzIGV2ZXJ5IGNvbHVtblxuICAvLyByZXBhaW50cyBub3RoaW5nLlxuICBwdWJsaWMgcmVhZG9ubHkgbGlzdEhpZGRlbiA9IHNpZ25hbDxSZWFkb25seU1hcDxudW1iZXIsIHJlYWRvbmx5IHN0cmluZ1tdPj4obmV3IE1hcCgpLCB7XG4gICAgZXF1YWw6IHNhbWVIaWRkZW4sXG4gIH0pO1xuXG4gIHByaXZhdGUgX3ZhbHVlcyA9IG5ldyBNYXA8bnVtYmVyLCBGaWx0ZXJHcm91cFZhbHVlPigpO1xuICBwcml2YXRlIF9ncm91cHMgPSBuZXcgTWFwPG51bWJlciwgUmVwb3J0RmlsdGVyR3JvdXA+KCk7XG4gIHByaXZhdGUgX3Nlc3Npb25EaXNhYmxlZCA9IG5ldyBTZXQ8bnVtYmVyPigpO1xuXG4gIC8vIEdyb3VwcyB0aGF0IGhhdmUgYSBkZWZhdWx0IHRoZSB2aWV3ZXIgY2xlYXJlZC4gV2l0aG91dCB0aGlzIGEgcmVsb2FkIG9mIHRoZVxuICAvLyByZXBvcnQgKGEgY2hhdCBlZGl0LCBhIGRpYWxvZykgd291bGQgZmluZCBubyB2YWx1ZSBmb3IgdGhlIGdyb3VwIGFuZCBzZWVkXG4gIC8vIGl0cyBkZWZhdWx0IHN0cmFpZ2h0IGJhY2suIEEgY2hhbmdlIHRvIHRoZSBzdG9yZWQgZGVmYXVsdCByZWxlYXNlcyBpdC5cbiAgcHJpdmF0ZSBfY2xlYXJlZCA9IG5ldyBTZXQ8bnVtYmVyPigpO1xuXG4gIC8vIFRoZSByZXBvcnQncyBncm91cC1ieSBjb250cm9sOiBhIHNpbmdsZSByZXBvcnQtd2lkZSBidWNrZXQgb3ZlcnJpZGUgZm9yIGFsbFxuICAvLyB0aW1lLXNlcmllcyBjaGFydHMuIFVuc2V0ID0gZWFjaCBjaGFydCB1c2VzIGl0cyBhdXRob3JlZCBncmFudWxhcml0eS4gTmV2ZXJcbiAgLy8gc2F2ZWQgdG8gdGhlIHJlcG9ydCAodGhlIFVSTCBjYXJyaWVzIGl0KSwgYW5kIGNhcnJpZWQgaW4gdGhlIGRhdGEgcmVxdWVzdCdzXG4gIC8vIGBzdGF0ZWAsIHNvIGl0IHByb3BhZ2F0ZXMgdGhyb3VnaCB0byB0aGUgUERGL1Bvd2VyUG9pbnQgZXhwb3J0cyB0b28uIE5hbWVkXG4gIC8vIGZvciB0aGUgYGZyZXF1ZW5jeWAgd2lyZSBrZXkgaXQgdHJhdmVscyB1bmRlciwgbm90IGZvciB0aGUgY29udHJvbCdzIGxhYmVsLlxuICBwcml2YXRlIF9mcmVxdWVuY3k6IENoYXJ0R3JhbnVsYXJpdHkgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBfZnJlcXVlbmN5Q2hhbmdlZCQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIC8vIEVhY2ggbGlzdCdzIHZpZXdlci1jaG9zZW4gc29ydCwgYnkgY29tcG9uZW50IGlkLiBIZWxkIGhlcmUgcmF0aGVyIHRoYW4gb25seVxuICAvLyBpbiB0aGUgbGlzdCdzIEZzTGlzdCBzbyBpdCBzdXJ2aXZlcyB0aGUgbGlzdCBiZWluZyByZWNyZWF0ZWQgKGEgcGFnZSBzd2l0Y2gsXG4gIC8vIGEgcmVsb2FkIGFmdGVyIGFuIGVkaXQpIGFuZCBzbyBldmVyeSBjb25zdW1lciBvZiB2aWV3ZXIgc3RhdGUgcmVhZHMgb25lIHBsYWNlLlxuICBwcml2YXRlIF9saXN0U29ydHMgPSBuZXcgTWFwPG51bWJlciwgUmVwb3J0U29ydD4oKTtcblxuICAvLyBFYWNoIGxpc3QncyBzZWFyY2ggYm94IHRleHQgKGxpc3RTZWFyY2hUZXh0KSwgYnkgY29tcG9uZW50IGlkLiBBIGxpc3Qgd2l0aFxuICAvLyBhbiBlbXB0eSBib3ggaGFzIG5vIGVudHJ5LiBIZWxkIGhlcmUgZm9yIHRoZSBzYW1lIHJlYXNvbnMgYXMgdGhlIHNvcnRzLCBhbmRcbiAgLy8gYmVjYXVzZSB0aGUgYm94IGxpdmVzIGluIHRoZSBjb21wb25lbnQgaGVhZGVyLCBub3QgaW4gdGhlIGxpc3QuXG4gIHByaXZhdGUgX2xpc3RTZWFyY2hlcyA9IG5ldyBNYXA8bnVtYmVyLCBzdHJpbmc+KCk7XG5cbiAgLy8gVGhlIG9wZW4gcmVwb3J0J3MgbGlzdHMsIGJ5IGNvbXBvbmVudCBpZCwgc28gYSBmaWx0ZXIgdG9nZ2xlIGNhbiB0ZWxsXG4gIC8vIHdoaWNoIG9mIHRoZW0gbG9zZSB0aGVpciBzZWFyY2ggYm94IChsaXN0U2VhcmNoYWJsZSkuXG4gIHByaXZhdGUgX2xpc3RzID0gbmV3IE1hcDxudW1iZXIsIFJlcG9ydENvbXBvbmVudD4oKTtcblxuICAvLyBXaGV0aGVyIHRoZSBzZXJ2ZXIgYW5zd2VycyBhIGxpc3Qgc2VhcmNoLiBMaXN0IHNlYXJjaCBhbmQgZWZmZWN0aXZlTG9jYWxlXG4gIC8vIHNoaXAgaW4gdGhlIHNhbWUgZnJhbWV3b3JrIGNoYW5nZSBzZXQsIHNvIGEgc2VydmVyIHRoYXQgc2VuZHMgbm9cbiAgLy8gZWZmZWN0aXZlTG9jYWxlIGhhcyBuZWl0aGVyLCBhbmQgaXRzIGxpc3RzIHNob3cgbm8gc2VhcmNoIGJveC5cbiAgcHJpdmF0ZSBfc2VydmVyU2VhcmNoZXMgPSBmYWxzZTtcblxuICAvLyBFbWl0cyB0aGUgaWQgb2YgdGhlIGxpc3Qgd2hvc2Ugc2VhcmNoIHRleHQgY2hhbmdlZC5cbiAgcHJpdmF0ZSBfbGlzdFNlYXJjaENoYW5nZWQkID0gbmV3IFN1YmplY3Q8bnVtYmVyPigpO1xuXG4gIC8vIEVtaXRzIHRoZSBncm91cCBpZCB0aGF0IGNoYW5nZWQ7IGNvbXBvbmVudHMgbGlzdGVuIGZpbHRlcmVkIHRvIHRoZWlyIG93blxuICAvLyBncm91cCBpZHMuIG51bGwgPSBldmVyeXRoaW5nIGNoYW5nZWQgKHJlLWluaXQpLlxuICBwcml2YXRlIF9jaGFuZ2VkJCA9IG5ldyBTdWJqZWN0PG51bWJlciB8IG51bGw+KCk7XG5cbiAgLy8gRmlyZXMgd2hlbmV2ZXIgYW55dGhpbmcgdGhlIFVSTCBjYXJyaWVzIG1heSBoYXZlIGNoYW5nZWQuXG4gIHByaXZhdGUgX3VybENoYW5nZWQkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICAvLyBTZWVkIGdyb3VwcyArIHRoZWlyIGRlZmF1bHRzIHdoZW4gYSByZXBvcnQgbG9hZHMuIEV4aXN0aW5nIHNlc3Npb24gdmFsdWVzXG4gIC8vIGZvciBzdGlsbC1leGlzdGluZyBncm91cHMgc3Vydml2ZSBhIHN0cnVjdHVyZSByZS1mZXRjaCAoYSBjaGF0IGVkaXRcbiAgLy8gc2hvdWxkbid0IHJlc2V0IHRoZSB2aWV3ZXIncyBmaWx0ZXJzKSwgYW5kIHNvIGRvZXMgYSBncm91cCB0aGUgdmlld2VyXG4gIC8vIGNsZWFyZWQg4oCUIFVOTEVTUyB0aGUgZ3JvdXAncyBzdG9yZWQgZGVmYXVsdCBpdHNlbGYgY2hhbmdlZCwgd2hpY2ggb25seVxuICAvLyBoYXBwZW5zIHdoZW4gYW4gb3BlcmF0b3Igc2F2ZWQgYSBuZXcgZGVmYXVsdCBpbiByZXBvcnQgc2V0dGluZ3Mgb3IgdGhlXG4gIC8vIGFnZW50IHNldCBvbmUuIFRoYXQgaXMgYW4gZXhwbGljaXQgaW5zdHJ1Y3Rpb24gdG8gcmUtc2VlZCwgc28gaXQgd2lucyBvdmVyXG4gIC8vIHRoZSBzdXJ2aXZpbmcgc2Vzc2lvbiB2YWx1ZTsgd2l0aG91dCBpdCB0aGUgYmFyIGtlZXBzIHNob3dpbmcgd2hhdGV2ZXIgaXRcbiAgLy8gd2FzIGZpcnN0IHNlZWRlZCB3aXRoIHVudGlsIGEgZnVsbCBwYWdlIHJlbG9hZC5cbiAgLy9cbiAgLy8gQSBjaGFuZ2Ugb2YgdGhlIHJlcG9ydCdzIHpvbmUgbW92ZXMgXCJ0b2RheVwiLCBzbyBhIHZhbHVlIHN0aWxsIGNhcnJ5aW5nIGl0c1xuICAvLyBncm91cCBkZWZhdWx0J3MgcHJlc2V0IG5hbWUgaXMgcmVzb2x2ZWQgYWdhaW4gaW4gdGhlIG5ldyB6b25lLiBBIHZhbHVlIHRoZVxuICAvLyB2aWV3ZXIgcGlja2VkLCBvciBvbmUgY2FycnlpbmcgYW5vdGhlciBwcmVzZXQgbmFtZSwgaXMga2VwdCBhcyBpdCBpcy5cbiAgLy9cbiAgLy8gYHJlc3RvcmVgIGlzIHRoZSB2aWV3ZXIgc3RhdGUgcmVhZCBmcm9tIHRoZSBVUkwuIFRoZSBob3N0IHBhc3NlcyBpdCBvbmx5IG9uXG4gIC8vIHRoZSBmaXJzdCBsb2FkIG9mIGEgcmVwb3J0OyBhIHJlbG9hZCBhZnRlciBhIGNoYXQgb3IgZGlhbG9nIGVkaXQgcGFzc2VzXG4gIC8vIG51bGwsIHNvIHRoZSBpbi1tZW1vcnkgc3RhdGUgd2lucy4gUGFyYW1zIHRoYXQgbmFtZSBhIGdyb3VwLCBsaXN0IG9yIGNvbHVtblxuICAvLyB0aGUgcmVwb3J0IG5vIGxvbmdlciBoYXMsIG9yIHRoYXQgZG8gbm90IGRlY29kZSwgYXJlIGlnbm9yZWQuXG4gIHB1YmxpYyBpbml0KHJlcG9ydDogUmVwb3J0LCByZXN0b3JlOiBSZXBvcnRVcmxQYXJhbXMgfCBudWxsID0gbnVsbCk6IHZvaWQge1xuICAgIGNvbnN0IHByZXZpb3VzVGltZXpvbmUgPSB0aGlzLnRpbWV6b25lKCk7XG5cbiAgICAvLyBTZXQgZmlyc3Q6IHRoZSBkZWZhdWx0cyBzZWVkZWQgYmVsb3cgcmVzb2x2ZSB0aGVpciByZWxhdGl2ZSBwcmVzZXRzIGluIGl0LlxuICAgIHRoaXMudGltZXpvbmUuc2V0KHJlc29sdmVSZXBvcnRUaW1lem9uZShyZXBvcnQpKTtcbiAgICB0aGlzLmZvcm1hdENvbnRleHQuc2V0KHJlc29sdmVGb3JtYXRDb250ZXh0KHJlcG9ydCkpO1xuICAgIC8vIEJlZm9yZSBhbnkgc2VhcmNoIHJlc3RvcmU6IGxpc3RTZWFyY2hhYmxlIHJlYWRzIGl0LlxuICAgIHRoaXMuX3NlcnZlclNlYXJjaGVzID0gcmVwb3J0LmVmZmVjdGl2ZUxvY2FsZSAhPT0gdW5kZWZpbmVkO1xuXG4gICAgY29uc3QgdGltZXpvbmVDaGFuZ2VkID0gcHJldmlvdXNUaW1lem9uZSAhPT0gdGhpcy50aW1lem9uZSgpO1xuICAgIGNvbnN0IHByZXZpb3VzR3JvdXBzID0gdGhpcy5fZ3JvdXBzO1xuICAgIHRoaXMuX2dyb3VwcyA9IG5ldyBNYXA8bnVtYmVyLCBSZXBvcnRGaWx0ZXJHcm91cD4oKTtcblxuICAgIGZvciAoY29uc3QgZ3JvdXAgb2YgcmVwb3J0LmZpbHRlckdyb3VwcyA/PyBbXSkge1xuICAgICAgdGhpcy5fZ3JvdXBzLnNldChncm91cC5pZCwgZ3JvdXApO1xuICAgICAgdGhpcy5fc2VlZChncm91cCwgcHJldmlvdXNHcm91cHMuZ2V0KGdyb3VwLmlkKSA/PyBudWxsLCB0aW1lem9uZUNoYW5nZWQpO1xuICAgIH1cblxuICAgIHRoaXMuX2xpc3RzID0gbmV3IE1hcCh0aGlzLl9saXN0Q29tcG9uZW50cyhyZXBvcnQpLm1hcCgoY29tcG9uZW50KSA9PiBbY29tcG9uZW50LmlkLCBjb21wb25lbnRdKSk7XG5cbiAgICBpZiAocmVzdG9yZSkge1xuICAgICAgdGhpcy5fcmVzdG9yZShyZXBvcnQsIHJlc3RvcmUpO1xuICAgIH1cblxuICAgIHRoaXMuX3BydW5lKHJlcG9ydCk7XG5cbiAgICB0aGlzLl9jaGFuZ2VkJC5uZXh0KG51bGwpO1xuICAgIHRoaXMuX3VybENoYW5nZWQkLm5leHQoKTtcbiAgfVxuXG4gIHB1YmxpYyB2YWx1ZShncm91cElkOiBudW1iZXIpOiBGaWx0ZXJHcm91cFZhbHVlIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWVzLmdldChncm91cElkKTtcbiAgfVxuXG4gIC8vIEEgYmFyJ3MgdmFsdWUgZm9yIGEgZ3JvdXAuIEEgZGF0ZSByYW5nZSBrZWVwcyB0aGUgc3RvcmVkIHByZXNldCBuYW1lIG9ubHlcbiAgLy8gd2hpbGUgaXRzIGRheXMgYXJlIHN0aWxsIHRoZSBzdG9yZWQgZGF5czogdGhlIGJhcnMgcmUtc2V0IGV2ZXJ5IGdyb3VwIHRoZXlcbiAgLy8gc2hvdyB3aGVuZXZlciBhbnkgb25lIG9mIHRoZW0gY2hhbmdlcywgYW5kIGFuIHVudG91Y2hlZCByb2xsaW5nIHJhbmdlIG11c3RcbiAgLy8ga2VlcCBpdHMgbmFtZSByYXRoZXIgdGhhbiB0dXJuIGludG8gdHdvIGZpeGVkIGRhdGVzLiBBbnkgb3RoZXIgcmFuZ2UsIGFcbiAgLy8gcGlja2VyIHNob3J0Y3V0IGluY2x1ZGVkLCBpcyBzdG9yZWQgYXMgdGhlIGZpeGVkIGRhdGVzIGl0IHNob3dzLlxuICBwdWJsaWMgc2V0VmFsdWUoZ3JvdXBJZDogbnVtYmVyLCB2YWx1ZTogRmlsdGVyR3JvdXBWYWx1ZSB8IG51bGwpOiB2b2lkIHtcbiAgICBpZiAodmFsdWUgPT09IG51bGwpIHtcbiAgICAgIHRoaXMuX3ZhbHVlcy5kZWxldGUoZ3JvdXBJZCk7XG5cbiAgICAgIGlmICh0aGlzLl9ncm91cHMuZ2V0KGdyb3VwSWQpPy5jb25maWc/LmRlZmF1bHQpIHtcbiAgICAgICAgdGhpcy5fY2xlYXJlZC5hZGQoZ3JvdXBJZCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3ZhbHVlcy5zZXQoZ3JvdXBJZCwgdGhpcy5fd2l0aFByZXNldCh0aGlzLl92YWx1ZXMuZ2V0KGdyb3VwSWQpLCB2YWx1ZSkpO1xuICAgICAgdGhpcy5fY2xlYXJlZC5kZWxldGUoZ3JvdXBJZCk7XG4gICAgfVxuXG4gICAgdGhpcy5fY2hhbmdlZCQubmV4dChncm91cElkKTtcbiAgICB0aGlzLl91cmxDaGFuZ2VkJC5uZXh0KCk7XG4gIH1cblxuICAvLyBBIHJlbGF0aXZlIHByZXNldCBuYW1lIGFzIHRvZGF5J3MgcmFuZ2UgaW4gdGhlIHJlcG9ydCdzIHpvbmUsIG9yIG51bGwgZm9yXG4gIC8vIGEgbmFtZSBpdCBkb2VzIG5vdCBrbm93LiBUaGUgVVJMIGNvZGVjIGRlY29kZXMgcHJlc2V0IG5hbWVzIHRocm91Z2ggdGhpcy5cbiAgcHVibGljIHJlc29sdmVSZWxhdGl2ZShuYW1lOiBzdHJpbmcpOiB7IHN0YXJ0OiBEYXRlOyBlbmQ6IERhdGUgfSB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLl9yZWxhdGl2ZVJhbmdlKG5hbWUpO1xuICB9XG5cbiAgLy8gVGhlIGFjdGl2ZSBncm91cC1ieSBncmFpbiwgb3IgbnVsbCB3aGVuIHRoZSB2aWV3ZXIgaGFzbid0IGNob3NlbiBvbmUuXG4gIHB1YmxpYyBmcmVxdWVuY3koKTogQ2hhcnRHcmFudWxhcml0eSB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLl9mcmVxdWVuY3k7XG4gIH1cblxuICBwdWJsaWMgc2V0RnJlcXVlbmN5KGZyZXF1ZW5jeTogQ2hhcnRHcmFudWxhcml0eSB8IG51bGwpOiB2b2lkIHtcbiAgICB0aGlzLl9mcmVxdWVuY3kgPSBmcmVxdWVuY3k7XG4gICAgdGhpcy5fZnJlcXVlbmN5Q2hhbmdlZCQubmV4dCgpO1xuICAgIHRoaXMuX3VybENoYW5nZWQkLm5leHQoKTtcbiAgfVxuXG4gIC8vIEZpcmVzIHdoZW5ldmVyIHRoZSBncm91cC1ieSBncmFpbiBjaGFuZ2VzIOKAlCBldmVyeSB0aW1lLXNlcmllcyBjaGFydCBsaXN0ZW5zXG4gIC8vIHNvIGl0IHJlZmV0Y2hlcyBhbmQgcmUtYnVja2V0cyAodGhlIG92ZXJyaWRlIGlzbid0IHNjb3BlZCB0byBhbnkgZmlsdGVyXG4gIC8vIGdyb3VwLCBzbyBjaGFuZ2VzRm9yKCkgY2FuJ3QgY2FycnkgaXQpLlxuICBwdWJsaWMgZnJlcXVlbmN5Q2hhbmdlcygpOiBPYnNlcnZhYmxlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5fZnJlcXVlbmN5Q2hhbmdlZCQuYXNPYnNlcnZhYmxlKCk7XG4gIH1cblxuICAvLyBUaGUgc29ydCB0aGUgdmlld2VyIGxhc3QgZmV0Y2hlZCBhIGxpc3Qgd2l0aCwgb3IgbnVsbCB3aGVuIGl0IGhhc24ndCBzb3J0ZWRcbiAgLy8gKHRoZSBsaXN0IHRoZW4gZmFsbHMgYmFjayB0byBpdHMgYXV0aG9yZWQgc29ydCkuXG4gIHB1YmxpYyBsaXN0U29ydChjb21wb25lbnRJZDogbnVtYmVyKTogUmVwb3J0U29ydCB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLl9saXN0U29ydHMuZ2V0KGNvbXBvbmVudElkKSA/PyBudWxsO1xuICB9XG5cbiAgLy8gUmVjb3JkcyBhIGxpc3QncyBzb3J0IHdoZW4gaXQgaXMgdGhlIHZpZXdlcidzIG93bjogYSBzb3J0IHRoYXQgaXMgdGhlXG4gIC8vIGxpc3QncyBhdXRob3JlZCBmaXJzdCB0ZXJtIGlzIHRoZSBsaXN0J3MgZGVmYXVsdCwgbm90IGEgY2hvaWNlLCBzbyBpdFxuICAvLyBjbGVhcnMgdGhlIGVudHJ5IGluc3RlYWQgKHRoZSBydWxlIHRoZSBVUkwgc25hcHNob3QgYXBwbGllcykuIE90aGVyd2lzZSBhXG4gIC8vIGxpc3QncyBmaXJzdCBmZXRjaCB3b3VsZCByZWNvcmQgaXRzIHNlZWRlZCBhdXRob3JlZCB0ZXJtLCBhbmQgYSBsaXN0IHRoZVxuICAvLyBhZ2VudCByZS1zb3J0cyBsYXRlciBpbiB0aGUgc2Vzc2lvbiB3b3VsZCBrZWVwIHNlbmRpbmcgdGhlIG9sZCB0ZXJtXG4gIC8vIGZpcnN0LiBEZWxpYmVyYXRlbHkgZW1pdHMgbm8gY2hhbmdlOiB0aGUgbGlzdCBzZXRzIHRoaXMgZnJvbSB0aGUgZmV0Y2hcbiAgLy8gdGhhdCBhbHJlYWR5IHJhbiB3aXRoIHRoYXQgc29ydCwgc28gYSBub3RpZmljYXRpb24gd291bGQgb25seSBtYWtlIGl0XG4gIC8vIHJlZmV0Y2ggdGhlIHNhbWUgcm93cy4gT25seSB0aGUgVVJMIGhlYXJzIGFib3V0IGl0LlxuICBwdWJsaWMgc2V0TGlzdFNvcnQoY29tcG9uZW50OiBSZXBvcnRDb21wb25lbnQsIHNvcnQ6IFJlcG9ydFNvcnQgfCBudWxsKTogdm9pZCB7XG4gICAgaWYgKHNvcnQgJiYgIXNhbWVTb3J0KHNvcnQsIGxpc3RTb3J0VGVybXMoY29tcG9uZW50LmNvbmZpZylbMF0gPz8gbnVsbCkpIHtcbiAgICAgIHRoaXMuX2xpc3RTb3J0cy5zZXQoY29tcG9uZW50LmlkLCBzb3J0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fbGlzdFNvcnRzLmRlbGV0ZShjb21wb25lbnQuaWQpO1xuICAgIH1cblxuICAgIHRoaXMuX3VybENoYW5nZWQkLm5leHQoKTtcbiAgfVxuXG4gIC8vIFRoZSB0ZXh0IGEgbGlzdCBpcyBzZWFyY2hlZCBieSwgb3IgbnVsbCB3aGVuIGl0cyBzZWFyY2ggYm94IGlzIGVtcHR5LlxuICBwdWJsaWMgbGlzdFNlYXJjaChjb21wb25lbnRJZDogbnVtYmVyKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuX2xpc3RTZWFyY2hlcy5nZXQoY29tcG9uZW50SWQpID8/IG51bGw7XG4gIH1cblxuICAvLyBXaGV0aGVyIGEgbGlzdCBzaG93cyB0aGUgc2VhcmNoIGJveCBvdmVyIGl0cyB0ZXh0IGNvbHVtbnM6IGl0IGRvZXMgd2hlbiB0aGVcbiAgLy8gc2VydmVyIGFuc3dlcnMgYSBsaXN0IHNlYXJjaCAoc2VlIF9zZXJ2ZXJTZWFyY2hlcyksIHVubGVzcyBvbmUgb2YgaXRzIGxpdmVcbiAgLy8gZmlsdGVycyBiZWxvbmdzIHRvIGEga2V5d29yZCBncm91cCBpdHMgaGVhZGVyIHNob3dzLiBBIGJhciBzaG93cyBvbmUgc2VhcmNoXG4gIC8vIGJveCAoaXRzIGxhc3Qga2V5d29yZCBpdGVtKSwgYW5kIHRoYXQgb25lIGlzIHRoZSBhdXRob3Incy4gVGhlIGhlYWRlciwgdGhlXG4gIC8vIFVSTCByZXN0b3JlLCB0aGUgcHJ1bmluZywgdGhlIGRhdGEgcmVxdWVzdCBzdGF0ZSBhbmQgdGhlIGV4cG9ydHMgYWxsIHJlYWRcbiAgLy8gdGhpcyBvbmUgcnVsZSwgc28gbm8gc2VhcmNoIG5hcnJvd3MgYSBsaXN0IHdob3NlIHNjcmVlbiBoYXMgbm8gYm94IHNob3dpbmdcbiAgLy8gaXQsIGFuZCBubyBleHBvcnQgdGl0bGVzIGEgc2VhcmNoIHRoZSBzZXJ2ZXIgZGlkIG5vdCBhcHBseS5cbiAgcHVibGljIGxpc3RTZWFyY2hhYmxlKGNvbXBvbmVudDogUmVwb3J0Q29tcG9uZW50KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX3NlcnZlclNlYXJjaGVzXG4gICAgICAmJiBjb21wb25lbnQudHlwZSA9PT0gJ2xpc3QnXG4gICAgICAmJiAhKGNvbXBvbmVudC5maWx0ZXJzID8/IFtdKS5zb21lKChmaWx0ZXIpID0+IHtcbiAgICAgICAgY29uc3QgZ3JvdXAgPSB0aGlzLl9ncm91cHMuZ2V0KGZpbHRlci5maWx0ZXJHcm91cElkKTtcblxuICAgICAgICByZXR1cm4gZmlsdGVyLmVuYWJsZWRcbiAgICAgICAgICAmJiAhdGhpcy5fc2Vzc2lvbkRpc2FibGVkLmhhcyhmaWx0ZXIuaWQpXG4gICAgICAgICAgJiYgZ3JvdXA/LnR5cGUgPT09ICdrZXl3b3JkJ1xuICAgICAgICAgICYmIChncm91cC5sZXZlbCA9PT0gJ2NvbXBvbmVudCcgfHwgZ3JvdXAubGV2ZWwgPT09ICdib3RoJyk7XG4gICAgICB9KTtcbiAgfVxuXG4gIC8vIFJlY29yZHMgYSBsaXN0J3Mgc2VhcmNoIGJveCB0ZXh0IChsaXN0U2VhcmNoVGV4dCk7IGFuIGVtcHR5IGJveCBjbGVhcnNcbiAgLy8gaXQuIFRoZSBoZWFkZXIgY2FsbHMgdGhpcyBvbiBldmVyeSBjaGFuZ2Ugb2YgYW55IG9mIGl0cyBpdGVtcywgc28gdGhlXG4gIC8vIGxpc3QgYW5kIHRoZSBVUkwgaGVhciBhYm91dCBpdCBvbmx5IHdoZW4gdGhlIHN0b3JlZCB0ZXh0IGFjdHVhbGx5IGNoYW5nZWQuXG4gIHB1YmxpYyBzZXRMaXN0U2VhcmNoKGNvbXBvbmVudElkOiBudW1iZXIsIHRleHQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IHNlYXJjaCA9IGxpc3RTZWFyY2hUZXh0KHRleHQpO1xuXG4gICAgaWYgKHNlYXJjaCA9PT0gKHRoaXMuX2xpc3RTZWFyY2hlcy5nZXQoY29tcG9uZW50SWQpID8/ICcnKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChzZWFyY2gpIHtcbiAgICAgIHRoaXMuX2xpc3RTZWFyY2hlcy5zZXQoY29tcG9uZW50SWQsIHNlYXJjaCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2xpc3RTZWFyY2hlcy5kZWxldGUoY29tcG9uZW50SWQpO1xuICAgIH1cblxuICAgIHRoaXMuX2xpc3RTZWFyY2hDaGFuZ2VkJC5uZXh0KGNvbXBvbmVudElkKTtcbiAgICB0aGlzLl91cmxDaGFuZ2VkJC5uZXh0KCk7XG4gIH1cblxuICAvLyBUaGUgY29uZmlnIGNvbHVtbiBuYW1lcyBhIHZpZXdlciBoaWQgb24gYSBsaXN0OyBub25lIHdoZW4gaXQgc2hvd3MgdGhlbSBhbGwuXG4gIHB1YmxpYyBoaWRkZW5Db2x1bW5zKGNvbXBvbmVudElkOiBudW1iZXIpOiByZWFkb25seSBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMubGlzdEhpZGRlbigpLmdldChjb21wb25lbnRJZCkgPz8gW107XG4gIH1cblxuICAvLyBSZWNvcmRzIHRoZSBjb2x1bW5zIGEgdmlld2VyIGhpZCBvbiBhIGxpc3QsIGtlcHQgdG8gbGlzdEhpZGRlbkNvbHVtbnM6XG4gIC8vIG5hbWVzIHRoZSBsaXN0IGNhbm5vdCBoaWRlIGFyZSBkcm9wcGVkLCBhbmQgbm9uZSAob3IgZXZlcnkgY29sdW1uKSBjbGVhcnNcbiAgLy8gdGhlIGVudHJ5LiBPbmx5IHRoZSBVUkwgaGVhcnMgYWJvdXQgaXQsIGFuZCBvbmx5IG9uIGEgcmVhbCBjaGFuZ2UuXG4gIHB1YmxpYyBzZXRIaWRkZW5Db2x1bW5zKGNvbXBvbmVudElkOiBudW1iZXIsIG5hbWVzOiByZWFkb25seSBzdHJpbmdbXSk6IHZvaWQge1xuICAgIGNvbnN0IGhpZGRlbiA9IGxpc3RIaWRkZW5Db2x1bW5zKHRoaXMuX2xpc3RzLmdldChjb21wb25lbnRJZCk/LmNvbmZpZywgbmFtZXMpO1xuXG4gICAgaWYgKHNhbWVOYW1lcyhoaWRkZW4sIHRoaXMuaGlkZGVuQ29sdW1ucyhjb21wb25lbnRJZCkpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgbmV4dCA9IG5ldyBNYXAodGhpcy5saXN0SGlkZGVuKCkpO1xuXG4gICAgaWYgKGhpZGRlbi5sZW5ndGgpIHtcbiAgICAgIG5leHQuc2V0KGNvbXBvbmVudElkLCBoaWRkZW4pO1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXh0LmRlbGV0ZShjb21wb25lbnRJZCk7XG4gICAgfVxuXG4gICAgdGhpcy5saXN0SGlkZGVuLnNldChuZXh0KTtcbiAgICB0aGlzLl91cmxDaGFuZ2VkJC5uZXh0KCk7XG4gIH1cblxuICAvLyBGaXJlcyB3aGVuZXZlciBvbmUgbGlzdCdzIHNlYXJjaCB0ZXh0IGNoYW5nZXMsIHNvIHRoYXQgbGlzdCByZWZldGNoZXMuXG4gIHB1YmxpYyBsaXN0U2VhcmNoQ2hhbmdlcyhjb21wb25lbnRJZDogbnVtYmVyKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuX2xpc3RTZWFyY2hDaGFuZ2VkJC5hc09ic2VydmFibGUoKVxuICAgICAgLnBpcGUoXG4gICAgICAgIHJ4RmlsdGVyKChpZCkgPT4gaWQgPT09IGNvbXBvbmVudElkKSxcbiAgICAgICAgbWFwKCgpID0+IHVuZGVmaW5lZCksXG4gICAgICApO1xuICB9XG5cbiAgLy8gRmlyZXMgd2hlbmV2ZXIgdGhlIHZpZXdlciBzdGF0ZSB0aGUgVVJMIGNhcnJpZXMgbWF5IGhhdmUgY2hhbmdlZDogYSBncm91cFxuICAvLyB2YWx1ZSwgdGhlIGdyYWluLCBhIGxpc3Qgc29ydCwgc2VhcmNoIG9yIGhpZGRlbiBjb2x1bW5zLCBvciBhIChyZSlsb2FkIG9mXG4gIC8vIHRoZSByZXBvcnQuXG4gIHB1YmxpYyB1cmxDaGFuZ2VzKCk6IE9ic2VydmFibGU8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLl91cmxDaGFuZ2VkJC5hc09ic2VydmFibGUoKTtcbiAgfVxuXG4gIC8vIFRoZSB2aWV3ZXIgc3RhdGUgdGhlIFVSTCBzaG91bGQgY2FycnkgZm9yIGByZXBvcnRgOiBvbmx5IHdoYXQgZGlmZmVycyBmcm9tXG4gIC8vIHRoZSBhdXRob3JlZCBkZWZhdWx0cywgc28gYW4gdW50b3VjaGVkIHJlcG9ydCBoYXMgYSBiYXJlIFVSTCBhbmQga2VlcHNcbiAgLy8gZm9sbG93aW5nIGl0cyBkZWZhdWx0cyB3aGVuIHRoZXkgY2hhbmdlLiBBIGdyb3VwIHRoZSB2aWV3ZXIgY2xlYXJlZCBpc1xuICAvLyBudWxsLiBBIGRhdGUgcmFuZ2UgaXMgY29tcGFyZWQgb24gaXRzIGRheXMgYWdhaW5zdCBpdHMgZGVmYXVsdCByZXNvbHZlZFxuICAvLyB0b2RheSwgc28gYSB2YWx1ZSB0aGF0IGlzIHRoZSBkZWZhdWx0IHVuZGVyIGFub3RoZXIgcHJlc2V0IG5hbWUgKHRoaXNZZWFyXG4gIC8vIGFnYWluc3QgYSB5ZWFyVG9EYXRlIGRlZmF1bHQpIGlzIHN0aWxsIHRoZSBkZWZhdWx0LlxuICBwdWJsaWMgdXJsU25hcHNob3QocmVwb3J0OiBSZXBvcnQpOiBSZXBvcnRVcmxTbmFwc2hvdCB7XG4gICAgY29uc3QgZ3JvdXBzID0gbmV3IE1hcDxudW1iZXIsIEZpbHRlckdyb3VwVmFsdWUgfCBudWxsPigpO1xuXG4gICAgZm9yIChjb25zdCBncm91cCBvZiB0aGlzLl9ncm91cHMudmFsdWVzKCkpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5fdmFsdWVzLmdldChncm91cC5pZCk7XG5cbiAgICAgIGlmICh0aGlzLl9jbGVhcmVkLmhhcyhncm91cC5pZCkpIHtcbiAgICAgICAgZ3JvdXBzLnNldChncm91cC5pZCwgbnVsbCk7XG4gICAgICB9IGVsc2UgaWYgKHZhbHVlICYmICF0aGlzLl9pc0RlZmF1bHQoZ3JvdXAsIHZhbHVlKSkge1xuICAgICAgICBncm91cHMuc2V0KGdyb3VwLmlkLCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgbGlzdFNvcnRzID0gbmV3IE1hcDxudW1iZXIsIFJlcG9ydFNvcnQ+KCk7XG4gICAgY29uc3QgbGlzdFNlYXJjaGVzID0gbmV3IE1hcDxudW1iZXIsIHN0cmluZz4oKTtcbiAgICBjb25zdCBsaXN0SGlkZGVuID0gbmV3IE1hcDxudW1iZXIsIHN0cmluZ1tdPigpO1xuXG4gICAgZm9yIChjb25zdCBjb21wb25lbnQgb2YgdGhpcy5fbGlzdENvbXBvbmVudHMocmVwb3J0KSkge1xuICAgICAgY29uc3Qgc29ydCA9IHRoaXMuX2xpc3RTb3J0cy5nZXQoY29tcG9uZW50LmlkKTtcbiAgICAgIGNvbnN0IHNlYXJjaCA9IHRoaXMuX2xpc3RTZWFyY2hlcy5nZXQoY29tcG9uZW50LmlkKTtcbiAgICAgIGNvbnN0IGhpZGRlbiA9IHRoaXMuaGlkZGVuQ29sdW1ucyhjb21wb25lbnQuaWQpO1xuXG4gICAgICBpZiAoc29ydCAmJiAhc2FtZVNvcnQoc29ydCwgbGlzdFNvcnRUZXJtcyhjb21wb25lbnQuY29uZmlnKVswXSA/PyBudWxsKSkge1xuICAgICAgICBsaXN0U29ydHMuc2V0KGNvbXBvbmVudC5pZCwgc29ydCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzZWFyY2gpIHtcbiAgICAgICAgbGlzdFNlYXJjaGVzLnNldChjb21wb25lbnQuaWQsIHNlYXJjaCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChoaWRkZW4ubGVuZ3RoKSB7XG4gICAgICAgIGxpc3RIaWRkZW4uc2V0KGNvbXBvbmVudC5pZCwgWy4uLmhpZGRlbl0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7IGdyb3VwcywgbGlzdFNvcnRzLCBsaXN0U2VhcmNoZXMsIGxpc3RIaWRkZW4sIGZyZXF1ZW5jeTogdGhpcy5fZnJlcXVlbmN5IH07XG4gIH1cblxuICBwdWJsaWMgaXNGaWx0ZXJEaXNhYmxlZChmaWx0ZXJJZDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX3Nlc3Npb25EaXNhYmxlZC5oYXMoZmlsdGVySWQpO1xuICB9XG5cbiAgcHVibGljIHRvZ2dsZUZpbHRlcihmaWx0ZXJJZDogbnVtYmVyLCBncm91cElkOiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fc2Vzc2lvbkRpc2FibGVkLmhhcyhmaWx0ZXJJZCkpIHtcbiAgICAgIHRoaXMuX3Nlc3Npb25EaXNhYmxlZC5kZWxldGUoZmlsdGVySWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9zZXNzaW9uRGlzYWJsZWQuYWRkKGZpbHRlcklkKTtcbiAgICB9XG5cbiAgICAvLyBUdXJuaW5nIGEga2V5d29yZCBmaWx0ZXIgYmFjayBvbiB0YWtlcyBpdHMgbGlzdCdzIHNlYXJjaCBib3ggYXdheSwgYW5kXG4gICAgLy8gdGhlIHNlYXJjaCB3aXRoIGl0LiBUaGUgbGlzdCByZWZldGNoZXMgb24gdGhlIGdyb3VwIGNoYW5nZSBiZWxvdy5cbiAgICB0aGlzLl9kcm9wVW5zZWFyY2hhYmxlKCk7XG5cbiAgICB0aGlzLl9jaGFuZ2VkJC5uZXh0KGdyb3VwSWQpO1xuICAgIHRoaXMuX3VybENoYW5nZWQkLm5leHQoKTtcbiAgfVxuXG4gIC8vIE5vdGlmaWNhdGlvbnMgcmVsZXZhbnQgdG8gT05FIGNvbXBvbmVudDogYW55IGNoYW5nZSB0byBhIGdyb3VwIG9uZSBvZiBpdHNcbiAgLy8gZmlsdGVycyBiZWxvbmdzIHRvIChvciBhIGZ1bGwgcmUtaW5pdCkuXG4gIHB1YmxpYyBjaGFuZ2VzRm9yKGNvbXBvbmVudDogUmVwb3J0Q29tcG9uZW50KTogT2JzZXJ2YWJsZTxudW1iZXIgfCBudWxsPiB7XG4gICAgY29uc3QgZ3JvdXBJZHMgPSBuZXcgU2V0KChjb21wb25lbnQuZmlsdGVycyA/PyBbXSkubWFwKChmaWx0ZXIpID0+IGZpbHRlci5maWx0ZXJHcm91cElkKSk7XG5cbiAgICByZXR1cm4gdGhpcy5fY2hhbmdlZCQuYXNPYnNlcnZhYmxlKClcbiAgICAgIC5waXBlKFxuICAgICAgICByeEZpbHRlcigoZ3JvdXBJZCkgPT4gZ3JvdXBJZCA9PT0gbnVsbCB8fCBncm91cElkcy5oYXMoZ3JvdXBJZCkpLFxuICAgICAgKTtcbiAgfVxuXG4gIC8vIE5vdGlmaWNhdGlvbnMgcmVsZXZhbnQgdG8gQU5ZIG9mIGEgc2V0IG9mIGNvbXBvbmVudHMgdGhhdCBjb21lcyBhbmQgZ29lc1xuICAvLyAoYSBwYWdlJ3MgdmFsdWVzKTogYSBjaGFuZ2UgdG8gYSBncm91cCBvbmUgb2YgdGhlaXIgZmlsdGVycyBiZWxvbmdzIHRvLlxuICAvLyBVbmxpa2UgY2hhbmdlc0ZvciwgdGhlIHNldCBpcyByZWFkIG9uIGVhY2ggZXZlbnQgcmF0aGVyIHRoYW4gY2FwdHVyZWQgYXRcbiAgLy8gc3Vic2NyaWJlLCBzbyBvbmUgc3Vic2NyaXB0aW9uIGZvbGxvd3MgdGhlIHNldCBhcyB0aGUgcmVwb3J0IHJlbG9hZHMuIEFcbiAgLy8gZnVsbCByZS1pbml0IChudWxsKSBpcyBub3QgcGFzc2VkIG9uOiBpbml0KCkgcnVucyBvbiBhIHJlcG9ydFxuICAvLyAocmUpbG9hZCwgYW5kIGEgY2FsbGVyIG9mIHRoaXMgY2hlY2tzIG9uIHRoYXQgcmVsb2FkIGl0c2VsZiB3aGV0aGVyIHRoZVxuICAvLyBmaWx0ZXIgdmFsdWVzIGl0cyBjb21wb25lbnRzIGFyZSByZWFkIHdpdGggbW92ZWQuXG4gIHB1YmxpYyBjaGFuZ2VzRm9yQW55KGNvbXBvbmVudHM6ICgpID0+IFJlcG9ydENvbXBvbmVudFtdKTogT2JzZXJ2YWJsZTxudW1iZXI+IHtcbiAgICByZXR1cm4gdGhpcy5fY2hhbmdlZCQuYXNPYnNlcnZhYmxlKClcbiAgICAgIC5waXBlKFxuICAgICAgICByeEZpbHRlcigoZ3JvdXBJZCk6IGdyb3VwSWQgaXMgbnVtYmVyID0+IGdyb3VwSWQgIT09IG51bGxcbiAgICAgICAgICAmJiBjb21wb25lbnRzKCkuc29tZSgoY29tcG9uZW50KSA9PiAoY29tcG9uZW50LmZpbHRlcnMgPz8gW10pXG4gICAgICAgICAgICAuc29tZSgoZmlsdGVyKSA9PiBmaWx0ZXIuZmlsdGVyR3JvdXBJZCA9PT0gZ3JvdXBJZCkpKSxcbiAgICAgICk7XG4gIH1cblxuICAvLyBUaGUgZ3JvdXAgdmFsdWVzIHJlc29sdmVkIGludG8gdGhpcyBjb21wb25lbnQncyBtZW1iZXItZmlsdGVyIHZhbHVlcyDigJRcbiAgLy8gd2hhdCB0aGUgZGF0YSByZXF1ZXN0IGNhcnJpZXMuIERpc2FibGVkIGZpbHRlcnMgKGF1dGhvcmVkIG9yIHNlc3Npb24pIGFyZVxuICAvLyBza2lwcGVkIGVudGlyZWx5LlxuICBwdWJsaWMgcmVzb2x2ZUZvckNvbXBvbmVudChjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudCk6IFJlc29sdmVkRmlsdGVyVmFsdWVbXSB7XG4gICAgY29uc3QgcmVzb2x2ZWQ6IFJlc29sdmVkRmlsdGVyVmFsdWVbXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBmaWx0ZXIgb2YgY29tcG9uZW50LmZpbHRlcnMgPz8gW10pIHtcbiAgICAgIGlmICghZmlsdGVyLmVuYWJsZWQgfHwgdGhpcy5fc2Vzc2lvbkRpc2FibGVkLmhhcyhmaWx0ZXIuaWQpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuX3ZhbHVlcy5nZXQoZmlsdGVyLmZpbHRlckdyb3VwSWQpO1xuICAgICAgY29uc3QgZmllbGRzID0gdmFsdWUgPyB0aGlzLl9yZXNvbHZlZEZpZWxkcyh2YWx1ZSkgOiBudWxsO1xuXG4gICAgICBpZiAoZmllbGRzKSB7XG4gICAgICAgIHJlc29sdmVkLnB1c2goeyBmaWx0ZXJJZDogZmlsdGVyLmlkLCAuLi5maWVsZHMgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc29sdmVkO1xuICB9XG5cbiAgLy8gV2hhdCB0aGUgdmlld2VyIGhhcyBzZXQsIG9uZSBlbnRyeSBwZXIgZmlsdGVyIGdyb3VwLCBmb3IgdGhlIHJlcG9ydCBjaGF0OlxuICAvLyB0aGUgYWdlbnQgcmVhZHMgaXQgdG8ga25vdyB3aGF0IGlzIG9uIHNjcmVlbi4gR3JvdXAgb3JkZXIsIG5vdCB0aGUgb3JkZXJcbiAgLy8gdGhlIHZhbHVlcyB3ZXJlIHNldCBpbiwgc28gdGhlIHNhbWUgc3RhdGUgYWx3YXlzIHJlYWRzIHRoZSBzYW1lLiBBIGdyb3VwXG4gIC8vIHdpdGggbm90aGluZyBpbiBpdCBpcyBsZWZ0IG91dCwgYW5kIGEgc2F2ZWQgZGVmYXVsdCBjb3VudHMgdW50aWwgdGhlXG4gIC8vIHZpZXdlciBjaGFuZ2VzIGl0LiBQZXItZmlsdGVyIHRvZ2dsZXMgYXJlIGEgY29tcG9uZW50J3Mgb3duIGJ1c2luZXNzLCBzb1xuICAvLyB0aGV5IGFyZSBub3QgcGFydCBvZiBpdC5cbiAgcHVibGljIHZpZXdlckZpbHRlcnMoKTogUmVwb3J0Q2hhdFZpZXdlckZpbHRlcltdIHtcbiAgICByZXR1cm4gWy4uLnRoaXMuX3ZhbHVlcy5lbnRyaWVzKCldXG4gICAgICAuc29ydCgoW2FdLCBbYl0pID0+IGEgLSBiKVxuICAgICAgLm1hcCgoW2dyb3VwSWQsIHZhbHVlXSkgPT4ge1xuICAgICAgICBjb25zdCBmaWVsZHMgPSB0aGlzLl9yZXNvbHZlZEZpZWxkcyh2YWx1ZSk7XG5cbiAgICAgICAgcmV0dXJuIGZpZWxkcyA/IHsgZ3JvdXBJZCwgLi4uZmllbGRzIH0gOiBudWxsO1xuICAgICAgfSlcbiAgICAgIC5maWx0ZXIoKGVudHJ5KTogZW50cnkgaXMgUmVwb3J0Q2hhdFZpZXdlckZpbHRlciA9PiBlbnRyeSAhPT0gbnVsbCk7XG4gIH1cblxuICAvLyBFdmVyeSBjb21wb25lbnQncyByZXNvbHZlZCB2YWx1ZXMgaW4gb25lIGFycmF5IOKAlCB3aGF0IGEgcmVwb3J0LWxldmVsIGV4cG9ydFxuICAvLyBjYXJyaWVzIHNvIGVhY2ggZmlsZSBpbiB0aGUgYXJjaGl2ZSBpcyBmaWx0ZXJlZCBleGFjdGx5IGFzIHRoZSBzY3JlZW4gaXMuXG4gIC8vIEZpbHRlciBpZHMgYXJlIHVuaXF1ZSBwZXIgY29tcG9uZW50LCBzbyB0aGUgYmFja2VuZCBwaWNrcyBlYWNoIGNvbXBvbmVudCdzXG4gIC8vIG93biBvdXQgb2YgdGhlIHBpbGUuIEEgcGFnZSBpZCBuYXJyb3dzIGl0IHRvIHRoYXQgcGFnZS5cbiAgcHVibGljIHJlc29sdmVGb3JSZXBvcnQocmVwb3J0OiBSZXBvcnQsIHBhZ2VJZDogbnVtYmVyIHwgbnVsbCA9IG51bGwpOiBSZXNvbHZlZEZpbHRlclZhbHVlW10ge1xuICAgIGNvbnN0IHBhZ2VzID0gKHJlcG9ydC5wYWdlcyA/PyBbXSlcbiAgICAgIC5maWx0ZXIoKHBhZ2UpID0+ICFwYWdlSWQgfHwgcGFnZS5pZCA9PT0gcGFnZUlkKTtcblxuICAgIHJldHVybiBwYWdlc1xuICAgICAgLmZsYXRNYXAoKHBhZ2UpID0+IChwYWdlLmNvbXBvbmVudHMgPz8gW10pXG4gICAgICAgIC5mbGF0TWFwKChjb21wb25lbnQpID0+IHRoaXMucmVzb2x2ZUZvckNvbXBvbmVudChjb21wb25lbnQpKSk7XG4gIH1cblxuICAvLyBBIGdyb3VwIHZhbHVlIGFzIHRoZSBmaWVsZHMgYSByZXF1ZXN0IGNhcnJpZXM6IGRhdGUgYm91bmRzIGFzIGNhbGVuZGFyXG4gIC8vIGRheXMsIHNlbGVjdCB2YWx1ZXMgd2hlbiBhbnkgYXJlIHBpY2tlZCwga2V5d29yZCB0ZXh0IHRyaW1tZWQuIE51bGwgd2hlblxuICAvLyBhbGwgb2YgdGhlbSBhcmUgZW1wdHkuIEEgZGF0ZSByYW5nZSBhbHNvIG5hbWVzIHRoZSByZWxhdGl2ZSByYW5nZSBpdFxuICAvLyBzdGlsbCBpcyAoX2xpdmVQcmVzZXQpLCBzbyB0aGUgc2VydmVyIGtub3dzIHdoaWNoIHBlcmlvZCB0aGUgZGF5cyBjb3ZlcjtcbiAgLy8gdGhlIGRheXMgc3RheSB0aGUgd2luZG93IGVpdGhlciB3YXkuIENvbXBvbmVudCBkYXRhLCB0aGUgcmVwb3J0IGFuZCBwYWdlXG4gIC8vIGV4cG9ydHMgYW5kIHRoZSBjaGF0J3Mgdmlld2VyIGZpbHRlcnMgYWxsIHJlYWQgdGhlaXIgZmllbGRzIGhlcmUsIHNvIGFsbFxuICAvLyB0aHJlZSBjYXJyeSBpdC5cbiAgcHJpdmF0ZSBfcmVzb2x2ZWRGaWVsZHModmFsdWU6IEZpbHRlckdyb3VwVmFsdWUpOiBPbWl0PFJlc29sdmVkRmlsdGVyVmFsdWUsICdmaWx0ZXJJZCc+IHwgbnVsbCB7XG4gICAgY29uc3QgZmllbGRzOiBPbWl0PFJlc29sdmVkRmlsdGVyVmFsdWUsICdmaWx0ZXJJZCc+ID0ge307XG4gICAgY29uc3QgcHJlc2V0ID0gdGhpcy5fbGl2ZVByZXNldCh2YWx1ZSk7XG5cbiAgICBpZiAodmFsdWUuc3RhcnQpIHtcbiAgICAgIGZpZWxkcy5zdGFydCA9IGRhdGVCb3VuZFN0cmluZyh2YWx1ZS5zdGFydCk7XG4gICAgfVxuICAgIGlmICh2YWx1ZS5lbmQpIHtcbiAgICAgIGZpZWxkcy5lbmQgPSBkYXRlQm91bmRTdHJpbmcodmFsdWUuZW5kKTtcbiAgICB9XG4gICAgaWYgKHByZXNldCkge1xuICAgICAgZmllbGRzLnByZXNldCA9IHByZXNldDtcbiAgICB9XG4gICAgaWYgKHZhbHVlLnZhbHVlcz8ubGVuZ3RoKSB7XG4gICAgICBmaWVsZHMudmFsdWVzID0gdmFsdWUudmFsdWVzO1xuICAgIH1cbiAgICBpZiAodmFsdWUudmFsdWU/LnRyaW0oKSkge1xuICAgICAgZmllbGRzLnZhbHVlID0gdmFsdWUudmFsdWUudHJpbSgpO1xuICAgIH1cblxuICAgIHJldHVybiBmaWVsZHMuc3RhcnQgfHwgZmllbGRzLmVuZCB8fCBmaWVsZHMudmFsdWVzIHx8IGZpZWxkcy52YWx1ZVxuICAgICAgPyBmaWVsZHNcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIC8vIFRoZSByZWxhdGl2ZSByYW5nZSBhIGRhdGUgdmFsdWUgc3RpbGwgaXM6IHRoZSBwcmVzZXQgbmFtZSBpdCBjYXJyaWVzLFxuICAvLyB3aGlsZSBpdHMgZGF5cyBhcmUgdGhhdCByYW5nZSByZXNvbHZlZCB0b2RheSBpbiB0aGUgcmVwb3J0J3Mgem9uZS4gQVxuICAvLyB2YWx1ZSB3aG9zZSBkYXlzIHRoZSB2aWV3ZXIgY2hhbmdlZCwgb3Igb25lIHNlZWRlZCBiZWZvcmUgbWlkbmlnaHQgdGhhdFxuICAvLyBpcyBub3cgYSBkYXkgYmVoaW5kLCBuYW1lcyBub25lLCBhbmQgdGhlIHNlcnZlciByZWFkcyBpdHMgZGF5cyBhbG9uZS5cbiAgcHJpdmF0ZSBfbGl2ZVByZXNldCh2YWx1ZTogRmlsdGVyR3JvdXBWYWx1ZSk6IFJlcG9ydFJlbGF0aXZlUmFuZ2UgfCBudWxsIHtcbiAgICBpZiAoIXZhbHVlLnByZXNldCB8fCAhaXNSZWxhdGl2ZVJhbmdlKHZhbHVlLnByZXNldCkpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IHJhbmdlID0gdGhpcy5fcmVsYXRpdmVSYW5nZSh2YWx1ZS5wcmVzZXQpO1xuXG4gICAgcmV0dXJuIHJhbmdlICYmIHNhbWVEYXlzKHZhbHVlLCByYW5nZSkgPyB2YWx1ZS5wcmVzZXQgOiBudWxsO1xuICB9XG5cbiAgLy8gU2VlZHMgb25lIGdyb3VwIG9uIChyZSlsb2FkOyBzZWUgaW5pdCgpLiBgcHJldmlvdXNgIGlzIHRoZSBncm91cCBhcyB0aGVcbiAgLy8gbGFzdCBsb2FkIGhhZCBpdCwgb3IgbnVsbCB3aGVuIGl0IGlzIG5ldy5cbiAgcHJpdmF0ZSBfc2VlZChcbiAgICBncm91cDogUmVwb3J0RmlsdGVyR3JvdXAsXG4gICAgcHJldmlvdXM6IFJlcG9ydEZpbHRlckdyb3VwIHwgbnVsbCxcbiAgICB0aW1lem9uZUNoYW5nZWQ6IGJvb2xlYW4sXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IGRlZmF1bHRDaGFuZ2VkID0gIXNhbWVEZWZhdWx0KHByZXZpb3VzPy5jb25maWc/LmRlZmF1bHQgPz8gbnVsbCwgZ3JvdXAuY29uZmlnPy5kZWZhdWx0ID8/IG51bGwpO1xuXG4gICAgaWYgKGRlZmF1bHRDaGFuZ2VkKSB7XG4gICAgICB0aGlzLl9jbGVhcmVkLmRlbGV0ZShncm91cC5pZCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2NsZWFyZWQuaGFzKGdyb3VwLmlkKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHZhbHVlID0gdGhpcy5fdmFsdWVzLmdldChncm91cC5pZCk7XG4gICAgY29uc3QgcHJlc2V0VG9SZXNvbHZlID0gdGltZXpvbmVDaGFuZ2VkXG4gICAgICAmJiAhIXZhbHVlPy5wcmVzZXRcbiAgICAgICYmIHZhbHVlLnByZXNldCA9PT0gZ3JvdXAuY29uZmlnPy5kZWZhdWx0Py5yZWxhdGl2ZTtcblxuICAgIGlmICh2YWx1ZSAmJiAhZGVmYXVsdENoYW5nZWQgJiYgIXByZXNldFRvUmVzb2x2ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGRlZmF1bHRWYWx1ZSA9IHRoaXMuX2RlZmF1bHRWYWx1ZShncm91cCk7XG5cbiAgICBpZiAoZGVmYXVsdFZhbHVlKSB7XG4gICAgICB0aGlzLl92YWx1ZXMuc2V0KGdyb3VwLmlkLCBkZWZhdWx0VmFsdWUpO1xuICAgIH0gZWxzZSBpZiAoZGVmYXVsdENoYW5nZWQpIHtcbiAgICAgIC8vIFRoZSBkZWZhdWx0IHdhcyBjbGVhcmVkLCBzbyB0aGUgdmFsdWUgaXQgc2VlZGVkIGdvZXMgd2l0aCBpdC5cbiAgICAgIHRoaXMuX3ZhbHVlcy5kZWxldGUoZ3JvdXAuaWQpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEFwcGxpZXMgdGhlIHZpZXdlciBzdGF0ZSByZWFkIGZyb20gdGhlIFVSTCBvbiB0b3Agb2YgdGhlIHNlZWRlZCBkZWZhdWx0cy5cbiAgcHJpdmF0ZSBfcmVzdG9yZShyZXBvcnQ6IFJlcG9ydCwgcmVzdG9yZTogUmVwb3J0VXJsUGFyYW1zKTogdm9pZCB7XG4gICAgdGhpcy5fcmVzdG9yZUdyb3VwcyhyZXN0b3JlKTtcbiAgICB0aGlzLl9yZXN0b3JlTGlzdFNvcnRzKHJlcG9ydCwgcmVzdG9yZSk7XG4gICAgdGhpcy5fcmVzdG9yZUxpc3RTZWFyY2hlcyhyZXBvcnQsIHJlc3RvcmUpO1xuICAgIHRoaXMuX3Jlc3RvcmVMaXN0SGlkZGVuKHJlc3RvcmUpO1xuXG4gICAgLy8gVGhlIFVSTCBpcyB0aGUgd2hvbGUgdHJ1dGggb24gYSBmaXJzdCBsb2FkOiBubyBncmFpbiBpbiBpdCBtZWFucyB0aGVcbiAgICAvLyBhdXRob3JlZCBvbmVzLiBUaGUgaG9zdCBzdGlsbCBkcm9wcyBhIGdyYWluIHRoZSByZXBvcnQgZG9lcyBub3Qgb2ZmZXIuXG4gICAgdGhpcy5fZnJlcXVlbmN5ID0gR1JBTlVMQVJJVFlfT1BUSU9OU1xuICAgICAgLmZpbmQoKG9wdGlvbikgPT4gb3B0aW9uLnZhbHVlID09PSByZXN0b3JlLmdyb3VwQnkpPy52YWx1ZSA/PyBudWxsO1xuICB9XG5cbiAgLy8gVGhlIFVSTCdzIGdyb3VwIHZhbHVlcy4gQW4gZW1wdHkgb25lIGlzIGFuIGV4cGxpY2l0IGNsZWFyIG9mIHRoZSBncm91cC5cbiAgcHJpdmF0ZSBfcmVzdG9yZUdyb3VwcyhyZXN0b3JlOiBSZXBvcnRVcmxQYXJhbXMpOiB2b2lkIHtcbiAgICByZXN0b3JlLmdyb3Vwcy5mb3JFYWNoKChyYXcsIGdyb3VwSWQpID0+IHtcbiAgICAgIGNvbnN0IGdyb3VwID0gdGhpcy5fZ3JvdXBzLmdldChncm91cElkKTtcbiAgICAgIGNvbnN0IHZhbHVlID0gZ3JvdXBcbiAgICAgICAgPyBkZWNvZGVGaWx0ZXJWYWx1ZShncm91cC50eXBlLCByYXcsIChuYW1lKSA9PiB0aGlzLnJlc29sdmVSZWxhdGl2ZShuYW1lKSlcbiAgICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICB0aGlzLl92YWx1ZXMuZGVsZXRlKGdyb3VwSWQpO1xuXG4gICAgICAgIGlmIChncm91cD8uY29uZmlnPy5kZWZhdWx0KSB7XG4gICAgICAgICAgdGhpcy5fY2xlYXJlZC5hZGQoZ3JvdXBJZCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodmFsdWUpIHtcbiAgICAgICAgdGhpcy5fdmFsdWVzLnNldChncm91cElkLCB2YWx1ZSk7XG4gICAgICAgIHRoaXMuX2NsZWFyZWQuZGVsZXRlKGdyb3VwSWQpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gVGhlIFVSTCdzIGxpc3Qgc29ydHMsIGVhY2gga2VwdCBvbmx5IGZvciBhIGxpc3QgdGhlIHJlcG9ydCBoYXMgYW5kIGFcbiAgLy8gY29sdW1uIHRoYXQgbGlzdCBjYW4gYmUgc29ydGVkIGJ5LlxuICBwcml2YXRlIF9yZXN0b3JlTGlzdFNvcnRzKHJlcG9ydDogUmVwb3J0LCByZXN0b3JlOiBSZXBvcnRVcmxQYXJhbXMpOiB2b2lkIHtcbiAgICBjb25zdCBsaXN0cyA9IG5ldyBNYXAodGhpcy5fbGlzdENvbXBvbmVudHMocmVwb3J0KS5tYXAoKGNvbXBvbmVudCkgPT4gW2NvbXBvbmVudC5pZCwgY29tcG9uZW50XSkpO1xuXG4gICAgcmVzdG9yZS5saXN0U29ydHMuZm9yRWFjaCgocmF3LCBjb21wb25lbnRJZCkgPT4ge1xuICAgICAgY29uc3QgY29tcG9uZW50ID0gbGlzdHMuZ2V0KGNvbXBvbmVudElkKTtcbiAgICAgIGNvbnN0IHNvcnQgPSBkZWNvZGVTb3J0KHJhdyk7XG5cbiAgICAgIGlmIChjb21wb25lbnQgJiYgc29ydCAmJiB0aGlzLl9zb3J0YWJsZUNvbHVtbnMoY29tcG9uZW50KS5pbmNsdWRlcyhzb3J0LmNvbHVtbikpIHtcbiAgICAgICAgdGhpcy5fbGlzdFNvcnRzLnNldChjb21wb25lbnRJZCwgc29ydCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBUaGUgVVJMJ3MgbGlzdCBzZWFyY2hlcywgZWFjaCBrZXB0IG9ubHkgZm9yIGEgbGlzdCB0aGUgcmVwb3J0IGhhcyB0aGF0XG4gIC8vIHNob3dzIGEgc2VhcmNoIGJveCAobGlzdFNlYXJjaGFibGUpLiBUaGUgdGV4dCBpcyByZWFkIGFzIGxpc3RTZWFyY2hUZXh0LFxuICAvLyBhbmQgYW4gZW1wdHkgb25lIGlzIG5vIHNlYXJjaC5cbiAgcHJpdmF0ZSBfcmVzdG9yZUxpc3RTZWFyY2hlcyhyZXBvcnQ6IFJlcG9ydCwgcmVzdG9yZTogUmVwb3J0VXJsUGFyYW1zKTogdm9pZCB7XG4gICAgY29uc3QgbGlzdHMgPSBuZXcgTWFwKHRoaXMuX2xpc3RDb21wb25lbnRzKHJlcG9ydCkubWFwKChjb21wb25lbnQpID0+IFtjb21wb25lbnQuaWQsIGNvbXBvbmVudF0pKTtcblxuICAgIHJlc3RvcmUubGlzdFNlYXJjaGVzLmZvckVhY2goKHJhdywgY29tcG9uZW50SWQpID0+IHtcbiAgICAgIGNvbnN0IGNvbXBvbmVudCA9IGxpc3RzLmdldChjb21wb25lbnRJZCk7XG4gICAgICBjb25zdCBzZWFyY2ggPSBsaXN0U2VhcmNoVGV4dChyYXcpO1xuXG4gICAgICBpZiAoY29tcG9uZW50ICYmIHRoaXMubGlzdFNlYXJjaGFibGUoY29tcG9uZW50KSAmJiBzZWFyY2gpIHtcbiAgICAgICAgdGhpcy5fbGlzdFNlYXJjaGVzLnNldChjb21wb25lbnRJZCwgc2VhcmNoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vIFRoZSBVUkwncyBoaWRkZW4gY29sdW1ucywgZWFjaCBsaXN0J3Mga2VwdCB0byBsaXN0SGlkZGVuQ29sdW1uczogb25seSB0aGVcbiAgLy8gY29uZmlndXJlZCBjb2x1bW5zIG9mIGEgcGxhaW4gbGlzdCB0aGUgcmVwb3J0IGhhcywgYW5kIG5vbmUgd2hlbiB0aGV5XG4gIC8vIHdvdWxkIGhpZGUgZXZlcnkgY29sdW1uLlxuICBwcml2YXRlIF9yZXN0b3JlTGlzdEhpZGRlbihyZXN0b3JlOiBSZXBvcnRVcmxQYXJhbXMpOiB2b2lkIHtcbiAgICBjb25zdCBuZXh0ID0gbmV3IE1hcCh0aGlzLmxpc3RIaWRkZW4oKSk7XG5cbiAgICByZXN0b3JlLmxpc3RIaWRkZW4uZm9yRWFjaCgocmF3LCBjb21wb25lbnRJZCkgPT4ge1xuICAgICAgY29uc3QgaGlkZGVuID0gbGlzdEhpZGRlbkNvbHVtbnModGhpcy5fbGlzdHMuZ2V0KGNvbXBvbmVudElkKT8uY29uZmlnLCBkZWNvZGVDb2x1bW5MaXN0KHJhdykpO1xuXG4gICAgICBpZiAoaGlkZGVuLmxlbmd0aCkge1xuICAgICAgICBuZXh0LnNldChjb21wb25lbnRJZCwgaGlkZGVuKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMubGlzdEhpZGRlbi5zZXQobmV4dCk7XG4gIH1cblxuICAvLyBEcm9wcyB0aGUgc2VhcmNoIG9mIGV2ZXJ5IGxpc3QgdGhhdCBubyBsb25nZXIgc2hvd3MgYSBzZWFyY2ggYm94OiBvbmVcbiAgLy8gdGhlIHJlcG9ydCBubyBsb25nZXIgaGFzLCBvciBvbmUgd2hvc2UgaGVhZGVyIG5vdyBoYXMgYSBrZXl3b3JkIGdyb3VwLlxuICBwcml2YXRlIF9kcm9wVW5zZWFyY2hhYmxlKCk6IHZvaWQge1xuICAgIHRoaXMuX2xpc3RTZWFyY2hlcy5mb3JFYWNoKChzZWFyY2gsIGNvbXBvbmVudElkKSA9PiB7XG4gICAgICBjb25zdCBjb21wb25lbnQgPSB0aGlzLl9saXN0cy5nZXQoY29tcG9uZW50SWQpO1xuXG4gICAgICBpZiAoIWNvbXBvbmVudCB8fCAhdGhpcy5saXN0U2VhcmNoYWJsZShjb21wb25lbnQpKSB7XG4gICAgICAgIHRoaXMuX2xpc3RTZWFyY2hlcy5kZWxldGUoY29tcG9uZW50SWQpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gRHJvcHMgc3RhdGUga2VwdCBmb3IgZ3JvdXBzLCBsaXN0cyBhbmQgZmlsdGVycyB0aGUgcmVwb3J0IG5vIGxvbmdlciBoYXMuXG4gIC8vIEEgbGlzdCBzb3J0IGFsc28gZ29lcyB3aGVuIGl0cyBjb2x1bW4gZG9lczogdGhlIGFnZW50IGNhbiByZW1vdmUgb3IgcmVuYW1lXG4gIC8vIGl0LCBhbmQgdGhlIHJlY3JlYXRlZCBsaXN0IHdvdWxkIHNlbmQgYSBjb2x1bW4gdGhlIHF1ZXJ5IGRvZXMgbm90IGtub3cuXG4gIC8vIEEgbGlzdCBzZWFyY2ggZ29lcyB3aXRoIGl0cyBsaXN0IChvciB3aGVuIHRoZSBjb21wb25lbnQgaXMgbm8gbG9uZ2VyIGFcbiAgLy8gbGlzdCksIGFuZCB3aGVuIHRoZSBsaXN0IGdhaW5zIGEga2V5d29yZCBncm91cCBhbmQgc28gbG9zZXMgaXRzIGJveC5cbiAgLy8gSGlkZGVuIGNvbHVtbnMga2VlcCBvbmx5IHRoZSBuYW1lcyB0aGVpciBsaXN0IHN0aWxsIGhhcyBhcyBjb2x1bW5zICh0aGVcbiAgLy8gYWdlbnQgY2FuIHJlbW92ZSBvciByZW5hbWUgb25lLCBvciB0dXJuIHRoZSBsaXN0IGludG8gYSBjcm9zcy10YWIpLCBhbmQgZ29cbiAgLy8gd2hlbiB3aGF0IGlzIGxlZnQgd291bGQgaGlkZSBldmVyeSBjb2x1bW4uXG4gIHByaXZhdGUgX3BydW5lKHJlcG9ydDogUmVwb3J0KTogdm9pZCB7XG4gICAgZm9yIChjb25zdCBncm91cElkIG9mIFsuLi50aGlzLl92YWx1ZXMua2V5cygpLCAuLi50aGlzLl9jbGVhcmVkXSkge1xuICAgICAgaWYgKCF0aGlzLl9ncm91cHMuaGFzKGdyb3VwSWQpKSB7XG4gICAgICAgIHRoaXMuX3ZhbHVlcy5kZWxldGUoZ3JvdXBJZCk7XG4gICAgICAgIHRoaXMuX2NsZWFyZWQuZGVsZXRlKGdyb3VwSWQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuX2xpc3RTb3J0cy5mb3JFYWNoKChzb3J0LCBjb21wb25lbnRJZCkgPT4ge1xuICAgICAgY29uc3QgY29tcG9uZW50ID0gdGhpcy5fbGlzdHMuZ2V0KGNvbXBvbmVudElkKTtcblxuICAgICAgaWYgKCFjb21wb25lbnQgfHwgIXRoaXMuX3NvcnRhYmxlQ29sdW1ucyhjb21wb25lbnQpLmluY2x1ZGVzKHNvcnQuY29sdW1uKSkge1xuICAgICAgICB0aGlzLl9saXN0U29ydHMuZGVsZXRlKGNvbXBvbmVudElkKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIFZhbHVlcyBpbmNsdWRlZDogb25lIGlzIG5ldmVyIGRyYXduLCBidXQgaXRzIGZpbHRlcnMgYXJlIHRoZSByZXBvcnQnc1xuICAgIC8vIGxpa2UgYW55IG90aGVyIGNvbXBvbmVudCdzLCBhbmQgc28gYXJlIHRoZWlyIHNlc3Npb24gdG9nZ2xlcy5cbiAgICBjb25zdCBmaWx0ZXJJZHMgPSBuZXcgU2V0KHJlcG9ydENvbXBvbmVudHMocmVwb3J0KVxuICAgICAgLmZsYXRNYXAoKGNvbXBvbmVudCkgPT4gKGNvbXBvbmVudC5maWx0ZXJzID8/IFtdKS5tYXAoKGZpbHRlcikgPT4gZmlsdGVyLmlkKSkpO1xuXG4gICAgdGhpcy5fc2Vzc2lvbkRpc2FibGVkLmZvckVhY2goKGZpbHRlcklkKSA9PiB7XG4gICAgICBpZiAoIWZpbHRlcklkcy5oYXMoZmlsdGVySWQpKSB7XG4gICAgICAgIHRoaXMuX3Nlc3Npb25EaXNhYmxlZC5kZWxldGUoZmlsdGVySWQpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGhpcy5fZHJvcFVuc2VhcmNoYWJsZSgpO1xuXG4gICAgY29uc3QgaGlkZGVuID0gbmV3IE1hcDxudW1iZXIsIHJlYWRvbmx5IHN0cmluZ1tdPigpO1xuXG4gICAgdGhpcy5saXN0SGlkZGVuKCkuZm9yRWFjaCgobmFtZXMsIGNvbXBvbmVudElkKSA9PiB7XG4gICAgICBjb25zdCBrZXB0ID0gbGlzdEhpZGRlbkNvbHVtbnModGhpcy5fbGlzdHMuZ2V0KGNvbXBvbmVudElkKT8uY29uZmlnLCBuYW1lcyk7XG5cbiAgICAgIGlmIChrZXB0Lmxlbmd0aCkge1xuICAgICAgICBoaWRkZW4uc2V0KGNvbXBvbmVudElkLCBrZXB0KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMubGlzdEhpZGRlbi5zZXQoaGlkZGVuKTtcbiAgfVxuXG4gIC8vIFRoZSB2YWx1ZSBhIGJhciBzZXRzLCBrZWVwaW5nIHRoZSBzdG9yZWQgcHJlc2V0IG5hbWUgd2hpbGUgdGhlIGRheXMgYXJlXG4gIC8vIHN0aWxsIHRoZSBzdG9yZWQgZGF5cyAoc2VlIHNldFZhbHVlKS5cbiAgcHJpdmF0ZSBfd2l0aFByZXNldChzdG9yZWQ6IEZpbHRlckdyb3VwVmFsdWUgfCB1bmRlZmluZWQsIHZhbHVlOiBGaWx0ZXJHcm91cFZhbHVlKTogRmlsdGVyR3JvdXBWYWx1ZSB7XG4gICAgY29uc3QgZml4ZWQ6IEZpbHRlckdyb3VwVmFsdWUgPSB7IC4uLnZhbHVlIH07XG4gICAgZGVsZXRlIGZpeGVkLnByZXNldDtcblxuICAgIHJldHVybiBzdG9yZWQ/LnByZXNldCAmJiBzYW1lRGF5cyhzdG9yZWQsIGZpeGVkKVxuICAgICAgPyB7IC4uLmZpeGVkLCBwcmVzZXQ6IHN0b3JlZC5wcmVzZXQgfVxuICAgICAgOiBmaXhlZDtcbiAgfVxuXG4gIC8vIFdoZXRoZXIgYSB2YWx1ZSBpcyB0aGUgZ3JvdXAncyBhdXRob3JlZCBkZWZhdWx0LCBieSB0eXBlOiBhIGRhdGUgcmFuZ2Ugb25cbiAgLy8gaXRzIGRheXMgKHRoZSBkZWZhdWx0IHJlc29sdmVkIHRvZGF5KSwgYSBzZWxlY3Qgb24gaXRzIHZhbHVlcyBpbiBhbnlcbiAgLy8gb3JkZXIsIGEga2V5d29yZCBvbiBpdHMgdGV4dC5cbiAgcHJpdmF0ZSBfaXNEZWZhdWx0KGdyb3VwOiBSZXBvcnRGaWx0ZXJHcm91cCwgdmFsdWU6IEZpbHRlckdyb3VwVmFsdWUpOiBib29sZWFuIHtcbiAgICBjb25zdCBkZWZhdWx0VmFsdWUgPSB0aGlzLl9kZWZhdWx0VmFsdWUoZ3JvdXApO1xuICAgIGlmICghZGVmYXVsdFZhbHVlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgc3dpdGNoIChncm91cC50eXBlKSB7XG4gICAgICBjYXNlICdkYXRlUmFuZ2UnOlxuICAgICAgICAvLyBBbiB1bnRvdWNoZWQgcm9sbGluZyBkZWZhdWx0IHN0aWxsIGNhcnJpZXMgaXRzIHByZXNldCBuYW1lLiBJdHMgZGF5c1xuICAgICAgICAvLyB3ZXJlIHJlc29sdmVkIHdoZW4gaXQgd2FzIHNlZWRlZCwgYW5kIGFmdGVyIG1pZG5pZ2h0IHRoZXkgbm8gbG9uZ2VyXG4gICAgICAgIC8vIG1hdGNoIHRvZGF5J3MsIGJ1dCBpdCBpcyBzdGlsbCB0aGUgZGVmYXVsdCBhbmQgc3RheXMgb3V0IG9mIHRoZSBVUkwuXG4gICAgICAgIGlmICh2YWx1ZS5wcmVzZXQgJiYgdmFsdWUucHJlc2V0ID09PSBncm91cC5jb25maWc/LmRlZmF1bHQ/LnJlbGF0aXZlKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gc2FtZURheXModmFsdWUsIGRlZmF1bHRWYWx1ZSk7XG5cbiAgICAgIGNhc2UgJ3NlbGVjdCc6IHtcbiAgICAgICAgY29uc3QgdmFsdWVzID0gKHZhbHVlLnZhbHVlcyA/PyBbXSkubWFwKFN0cmluZykuc29ydCgpO1xuICAgICAgICBjb25zdCBkZWZhdWx0cyA9IChkZWZhdWx0VmFsdWUudmFsdWVzID8/IFtdKS5tYXAoU3RyaW5nKS5zb3J0KCk7XG5cbiAgICAgICAgcmV0dXJuIHZhbHVlcy5sZW5ndGggPT09IGRlZmF1bHRzLmxlbmd0aFxuICAgICAgICAgICYmIHZhbHVlcy5ldmVyeSgoaXRlbSwgaW5kZXgpID0+IGl0ZW0gPT09IGRlZmF1bHRzW2luZGV4XSk7XG4gICAgICB9XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiAodmFsdWUudmFsdWUgPz8gJycpLnRyaW0oKSA9PT0gKGRlZmF1bHRWYWx1ZS52YWx1ZSA/PyAnJykudHJpbSgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2xpc3RDb21wb25lbnRzKHJlcG9ydDogUmVwb3J0KTogUmVwb3J0Q29tcG9uZW50W10ge1xuICAgIHJldHVybiByZXBvcnRDb21wb25lbnRzKHJlcG9ydClcbiAgICAgIC5maWx0ZXIoKGNvbXBvbmVudCkgPT4gY29tcG9uZW50LnR5cGUgPT09ICdsaXN0Jyk7XG4gIH1cblxuICAvLyBUaGUgY29sdW1ucyBhIGxpc3QgY2FuIGJlIHNvcnRlZCBieTogZXZlcnkgYXV0aG9yZWQgY29sdW1uLCBvciBhXG4gIC8vIGNyb3NzLXRhYidzIHJvdyBjb2x1bW4gb25seSAoaXRzIHBpdm90IGNvbHVtbnMgY29tZSBhbmQgZ28gd2l0aCB0aGUgZGF0YSkuXG4gIHByaXZhdGUgX3NvcnRhYmxlQ29sdW1ucyhjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudCk6IHN0cmluZ1tdIHtcbiAgICBjb25zdCBjb25maWcgPSBjb21wb25lbnQuY29uZmlnO1xuXG4gICAgaWYgKGNvbmZpZz8ucGl2b3RCeT8uY29sdW1uKSB7XG4gICAgICByZXR1cm4gY29uZmlnLnJvd0J5Py5jb2x1bW4gPyBbY29uZmlnLnJvd0J5LmNvbHVtbl0gOiBbXTtcbiAgICB9XG5cbiAgICByZXR1cm4gKGNvbmZpZz8uY29sdW1ucyA/PyBbXSkubWFwKChjb2x1bW4pID0+IGNvbHVtbi5jb2x1bW4pO1xuICB9XG5cbiAgLy8gQSBncm91cCdzIGF1dGhvcmVkIGRlZmF1bHQsIG1hcHBlZCB0byBhIHNlc3Npb24gdmFsdWUgYnkgdHlwZS4gUmVsYXRpdmVcbiAgLy8gZGF0ZSBwcmVzZXRzIHJlc29sdmUgYWdhaW5zdCBcIm5vd1wiIGVhY2ggdGltZSB0aGUgcmVwb3J0IG9wZW5zLCBzbyBhIHNhdmVkXG4gIC8vIFwibGFzdCAxMiBtb250aHNcIiBzdGF5cyByZWxhdGl2ZSBhbmQgY2FycmllcyBpdHMgcHJlc2V0IG5hbWU7IGEgZml4ZWRcbiAgLy8gcmFuZ2UsIHNlbGVjdCB2YWx1ZXMgYW5kIGtleXdvcmQgdGV4dCBzZWVkIHZlcmJhdGltLlxuICBwcml2YXRlIF9kZWZhdWx0VmFsdWUoZ3JvdXA6IFJlcG9ydEZpbHRlckdyb3VwKTogRmlsdGVyR3JvdXBWYWx1ZSB8IG51bGwge1xuICAgIGNvbnN0IGdyb3VwRGVmYXVsdCA9IGdyb3VwLmNvbmZpZz8uZGVmYXVsdDtcbiAgICBpZiAoIWdyb3VwRGVmYXVsdCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgaWYgKGdyb3VwRGVmYXVsdC5yZWxhdGl2ZSkge1xuICAgICAgY29uc3QgcmFuZ2UgPSB0aGlzLl9yZWxhdGl2ZVJhbmdlKGdyb3VwRGVmYXVsdC5yZWxhdGl2ZSk7XG5cbiAgICAgIHJldHVybiByYW5nZSA/IHsgc3RhcnQ6IHJhbmdlLnN0YXJ0LCBlbmQ6IHJhbmdlLmVuZCwgcHJlc2V0OiBncm91cERlZmF1bHQucmVsYXRpdmUgfSA6IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKGdyb3VwRGVmYXVsdC5zdGFydCB8fCBncm91cERlZmF1bHQuZW5kKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdGFydDogZ3JvdXBEZWZhdWx0LnN0YXJ0ID8/IG51bGwsXG4gICAgICAgIGVuZDogZ3JvdXBEZWZhdWx0LmVuZCA/PyBudWxsLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoZ3JvdXBEZWZhdWx0LnZhbHVlcz8ubGVuZ3RoKSB7XG4gICAgICByZXR1cm4geyB2YWx1ZXM6IGdyb3VwRGVmYXVsdC52YWx1ZXMgfTtcbiAgICB9XG5cbiAgICBpZiAoZ3JvdXBEZWZhdWx0LnZhbHVlKSB7XG4gICAgICByZXR1cm4geyB2YWx1ZTogZ3JvdXBEZWZhdWx0LnZhbHVlIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvLyBBIHJlbGF0aXZlIHByZXNldCBhcyBhIGNhbGVuZGFyLWRheSByYW5nZS4gXCJUb2RheVwiIGlzIHRoZSBkYXkgaW4gdGhlXG4gIC8vIHJlcG9ydCdzIGVmZmVjdGl2ZSB6b25lLCBub3QgdGhlIGJyb3dzZXIncywgc28gZXZlcnkgdmlld2VyIHNlZWRzIHRoZSBzYW1lXG4gIC8vIHJhbmdlLiBUaGUgc2VydmVyIHR3aW4gaXMgUmVwb3J0UmVsYXRpdmVSYW5nZUVudW0gKGZyYW1ld29yay9SZXBvcnQvRW51bSksXG4gIC8vIGFuZCBSZXBvcnRSZWxhdGl2ZVJhbmdlRW51bVRlc3QgcGlucyB0aGUgdGFibGUgYm90aCBzaWRlcyBtdXN0IHByb2R1Y2UuXG4gIHByaXZhdGUgX3JlbGF0aXZlUmFuZ2UocmVsYXRpdmU6IHN0cmluZyk6IHsgc3RhcnQ6IERhdGU7IGVuZDogRGF0ZSB9IHwgbnVsbCB7XG4gICAgY29uc3Qgbm93ID0gZ2V0Wm9uZWROb3codGhpcy50aW1lem9uZSgpKTtcblxuICAgIHN3aXRjaCAocmVsYXRpdmUpIHtcbiAgICAgIC8vIEEgY2FsZW5kYXIgd2VlaywgTW9uZGF5IHRvIFN1bmRheSAoUkVQT1JUX1dFRUtfU1RBUlRTX09OLCB0aGUgc2FtZSB3ZWVrXG4gICAgICAvLyB0aGUgc2VydmVyJ3Mgd2Vla2x5IGJ1Y2tldHMgdXNlKSwgaW4gd2hvbGUgZGF5cyDigJQgbm90IHRoZSByb2xsaW5nXG4gICAgICAvLyBzZXZlbiBkYXlzIGBsYXN0N0RheXNgIGdpdmVzLCB3aGljaCBuZXZlciBsaW5lcyB1cCB3aXRoIHRoZSB3ZWVrIGFcbiAgICAgIC8vIHBhcnRuZXIgaGFzIGFscmVhZHkgYmVlbiBzZW50LiBgbGFzdFdlZWtgIGlzIHRoZSBvbmUgYSB3ZWVrbHkgcmVwb3J0XG4gICAgICAvLyB3YW50czogaXQgZW5kcyBvbiB0aGUgcHJldmlvdXMgd2VlaydzIFN1bmRheSByYXRoZXIgdGhhbiBhdCBgbm93YCxcbiAgICAgIC8vIGJlY2F1c2UgdGhlIHdlZWsgaXQgbmFtZXMgaGFzIGNsb3NlZC4gYHRoaXNXZWVrYCBmb2xsb3dzIGV2ZXJ5IG90aGVyXG4gICAgICAvLyBwcmVzZXQgaGVyZSBhbmQgcnVucyB1cCB0byBub3csIHNvIGl0IGlzIGRlbGliZXJhdGVseSBhIHBhcnQtZmluaXNoZWRcbiAgICAgIC8vIHdlZWsgKG9uIGEgU3VuZGF5IGl0IGlzIHRoZSB3aG9sZSBNb25kYXktdG8tU3VuZGF5IHdlZWspLlxuICAgICAgY2FzZSAndGhpc1dlZWsnOlxuICAgICAgICByZXR1cm4geyBzdGFydDogc3RhcnRPZldlZWsobm93LCB7IHdlZWtTdGFydHNPbjogUkVQT1JUX1dFRUtfU1RBUlRTX09OIH0pLCBlbmQ6IG5vdyB9O1xuICAgICAgY2FzZSAnbGFzdFdlZWsnOiB7XG4gICAgICAgIGNvbnN0IHByZXZpb3VzID0gc3ViV2Vla3Mobm93LCAxKTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHN0YXJ0OiBzdGFydE9mV2VlayhwcmV2aW91cywgeyB3ZWVrU3RhcnRzT246IFJFUE9SVF9XRUVLX1NUQVJUU19PTiB9KSxcbiAgICAgICAgICBlbmQ6IGVuZE9mV2VlayhwcmV2aW91cywgeyB3ZWVrU3RhcnRzT246IFJFUE9SVF9XRUVLX1NUQVJUU19PTiB9KSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIGNhc2UgJ2xhc3Q3RGF5cyc6XG4gICAgICAgIHJldHVybiB7IHN0YXJ0OiBzdWJEYXlzKG5vdywgNyksIGVuZDogbm93IH07XG4gICAgICBjYXNlICdsYXN0MzBEYXlzJzpcbiAgICAgICAgcmV0dXJuIHsgc3RhcnQ6IHN1YkRheXMobm93LCAzMCksIGVuZDogbm93IH07XG4gICAgICBjYXNlICdsYXN0M01vbnRocyc6XG4gICAgICAgIHJldHVybiB7IHN0YXJ0OiBzdWJNb250aHMobm93LCAzKSwgZW5kOiBub3cgfTtcbiAgICAgIGNhc2UgJ2xhc3Q2TW9udGhzJzpcbiAgICAgICAgcmV0dXJuIHsgc3RhcnQ6IHN1Yk1vbnRocyhub3csIDYpLCBlbmQ6IG5vdyB9O1xuICAgICAgY2FzZSAnbGFzdDEyTW9udGhzJzpcbiAgICAgICAgcmV0dXJuIHsgc3RhcnQ6IHN1Yk1vbnRocyhub3csIDEyKSwgZW5kOiBub3cgfTtcbiAgICAgIGNhc2UgJ3RoaXNNb250aCc6XG4gICAgICAgIHJldHVybiB7IHN0YXJ0OiBzdGFydE9mTW9udGgobm93KSwgZW5kOiBub3cgfTtcbiAgICAgIGNhc2UgJ3RoaXNRdWFydGVyJzpcbiAgICAgICAgcmV0dXJuIHsgc3RhcnQ6IHN0YXJ0T2ZRdWFydGVyKG5vdyksIGVuZDogbm93IH07XG4gICAgICBjYXNlICd0aGlzWWVhcic6XG4gICAgICBjYXNlICd5ZWFyVG9EYXRlJzpcbiAgICAgICAgcmV0dXJuIHsgc3RhcnQ6IHN0YXJ0T2ZZZWFyKG5vdyksIGVuZDogbm93IH07XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
1246
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LWZpbHRlci1zdGF0ZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL3NlcnZpY2VzL3JlcG9ydC1maWx0ZXItc3RhdGUuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUV0RCxPQUFPLEVBQWMsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxJQUFJLFFBQVEsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUV0QyxPQUFPLEVBQ0wsU0FBUyxFQUFFLFlBQVksRUFBRSxjQUFjLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFDakUsT0FBTyxFQUFFLFNBQVMsRUFBRSxRQUFRLEdBQzdCLE1BQU0sVUFBVSxDQUFDO0FBRWxCLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ3BFLE9BQU8sRUFDTCxzQkFBc0IsRUFBRSxXQUFXLEVBQUUsb0JBQW9CLEVBQUUscUJBQXFCLEdBQ2pGLE1BQU0sV0FBVyxDQUFDO0FBbUJuQixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsYUFBYSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDbEUsT0FBTyxFQUFFLGVBQWUsRUFBRSxzQkFBc0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ2pGLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzdELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QyxP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QUUsRUFBRSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO2FBQ3RFLE1BQU0sQ0FBQyxDQUFDLFdBQVcsRUFBRSxFQUFFO1lBQ3RCLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDcEMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLElBQUksSUFBSSxDQUFDO1lBRXJELE9BQU8sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxJQUFJLENBQUM7UUFDbEQsQ0FBQyxDQUFDLENBQUM7UUFFTCxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2xCLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDLENBQUM7UUFDL0MsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDNUYsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDbkMsQ0FBQzt3R0FyMENVLHdCQUF3Qjs0R0FBeEIsd0JBQXdCOzs0RkFBeEIsd0JBQXdCO2tCQURwQyxVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgc2lnbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBjb21wdXRlZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdG9TaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5cbmltcG9ydCB7IE9ic2VydmFibGUsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1hcCwgZmlsdGVyIGFzIHJ4RmlsdGVyIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgc2NhbiB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHtcbiAgZW5kT2ZXZWVrLCBzdGFydE9mTW9udGgsIHN0YXJ0T2ZRdWFydGVyLCBzdGFydE9mV2Vlaywgc3RhcnRPZlllYXIsXG4gIHN1YkRheXMsIHN1Yk1vbnRocywgc3ViV2Vla3MsXG59IGZyb20gJ2RhdGUtZm5zJztcblxuaW1wb3J0IHsgUkVQT1JUX1dFRUtfU1RBUlRTX09OIH0gZnJvbSAnLi4vY29uc3RzL3JlcG9ydC13ZWVrLmNvbnN0JztcbmltcG9ydCB7XG4gIERFRkFVTFRfRk9STUFUX0NPTlRFWFQsIGdldFpvbmVkTm93LCByZXNvbHZlRm9ybWF0Q29udGV4dCwgcmVzb2x2ZVJlcG9ydFRpbWV6b25lLFxufSBmcm9tICcuLi9mb3JtYXQnO1xuaW1wb3J0IHsgUmVwb3J0Q2hhdFZpZXdlckZpbHRlciB9IGZyb20gJy4uL2ludGVyZmFjZXMvcmVwb3J0LWNoYXQtdmlld2VyLWZpbHRlci5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgUmVwb3J0RHJpbGxTdGVwIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZXBvcnQtZHJpbGwtc3RlcC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgUmVwb3J0RmlsdGVyTWF0Y2ggfSBmcm9tICcuLi9pbnRlcmZhY2VzL3JlcG9ydC1maWx0ZXItbWF0Y2gudHlwZSc7XG5pbXBvcnQgeyBSZXBvcnRUZW1wb3JhcnlTdGF0ZSB9IGZyb20gJy4uL2ludGVyZmFjZXMvcmVwb3J0LXRlbXBvcmFyeS1zdGF0ZS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgUmVwb3J0VGlsZVN0YXRlIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZXBvcnQtdGlsZS1zdGF0ZS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgUmVwb3J0Vmlld0NvbmZpZyB9IGZyb20gJy4uL2ludGVyZmFjZXMvcmVwb3J0LXZpZXctY29uZmlnLmludGVyZmFjZSc7XG5pbXBvcnQge1xuICBDaGFydEdyYW51bGFyaXR5LFxuICBGaWx0ZXJHcm91cERlZmF1bHQsXG4gIEZpbHRlckdyb3VwVmFsdWUsXG4gIFJlcG9ydCxcbiAgUmVwb3J0Q29tcG9uZW50LFxuICBSZXBvcnRGaWx0ZXJHcm91cCxcbiAgUmVwb3J0Rm9ybWF0Q29udGV4dCxcbiAgUmVwb3J0UmVsYXRpdmVSYW5nZSxcbiAgUmVwb3J0U29ydCxcbiAgUmVzb2x2ZWRGaWx0ZXJWYWx1ZSxcbn0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZXBvcnQuaW50ZXJmYWNlJztcbmltcG9ydCB7IGxpc3RIaWRkZW5Db2x1bW5zLCBsaXN0U29ydFRlcm1zIH0gZnJvbSAnLi4vbGlzdC1jb25maWcnO1xuaW1wb3J0IHsgZGF0ZUJvdW5kU3RyaW5nLCBMSVNUX1NFQVJDSF9NQVhfTEVOR1RIIH0gZnJvbSAnLi4vcmVwb3J0LWZpbHRlci1pdGVtcyc7XG5pbXBvcnQgeyBncm91cFZhbHVlU2lnbmF0dXJlIH0gZnJvbSAnLi4vcmVwb3J0LWZpbHRlci1pdGVtcyc7XG5pbXBvcnQgeyBpc1RpbGUgfSBmcm9tICcuLi9yZXBvcnQtdGlsZSc7XG5pbXBvcnQgeyBpc1JlbGF0aXZlUmFuZ2UgfSBmcm9tICcuLi9yZXBvcnQtdmlldy1jb25maWcnO1xuaW1wb3J0IHtcbiAgUkVQT1JUX1ZJRVdfQ09ORklHX1ZFUlNJT04sIGNsZWFuRHJpbGxQYXRoLCBncm91cFZhbHVlRnJvbVN0b3JlZCwgaXNDaGFydEdyYW51bGFyaXR5LFxuICBzYW1lRHJpbGxQYXRoLCB0b0xpdmVHcm91cFZhbHVlLCB0b1N0b3JlZEdyb3VwVmFsdWUsIHZpZXdEaWZmZXJzLFxufSBmcm9tICcuLi9yZXBvcnQtdmlldy1jb25maWcnO1xuaW1wb3J0IHsgZmluaXRlTnVtYmVyIH0gZnJvbSAnLi4vcmVwb3J0LXZpZXctY29uZmlnJztcbmltcG9ydCB7IHNhbWVTdG9yZWRHcm91cFZhbHVlIH0gZnJvbSAnLi4vcmVwb3J0LXZpZXctY29uZmlnJztcbmltcG9ydCB7IENvbXBvbmVudERhdGFTdGF0ZSB9IGZyb20gJy4uL2ludGVyZmFjZXMvcmVwb3J0LmludGVyZmFjZSc7XG5pbXBvcnQgeyB0aWxlRGF0YVN0YXRlIH0gZnJvbSAnLi4vdGlsZS1kYXRhLXN0YXRlJztcbmltcG9ydCB7IHJlcG9ydENvbXBvbmVudHMgfSBmcm9tICcuLi92YWx1ZXMnO1xuXG5cbi8vIFdoZXRoZXIgdHdvIHN0b3JlZCBmaWx0ZXItZ3JvdXAgZGVmYXVsdHMgYXJlIHRoZSBzYW1lLiBDb21wYXJlZCBvbiB0aGUgZmllbGRzIGFcbi8vIGRlZmF1bHQgY2FuIGFjdHVhbGx5IGNhcnJ5LCBzbyBrZXkgb3JkZXIgaW4gdGhlIHBheWxvYWQgY2FuJ3QgcmVhZCBhcyBhIGNoYW5nZS5cbmV4cG9ydCBmdW5jdGlvbiBzYW1lRGVmYXVsdChcbiAgYTogRmlsdGVyR3JvdXBEZWZhdWx0IHwgbnVsbCxcbiAgYjogRmlsdGVyR3JvdXBEZWZhdWx0IHwgbnVsbCxcbik6IGJvb2xlYW4ge1xuICBpZiAoIWEgfHwgIWIpIHtcbiAgICByZXR1cm4gIWEgJiYgIWI7XG4gIH1cblxuICByZXR1cm4gYS5zdGFydCA9PT0gYi5zdGFydFxuICAgICYmIGEuZW5kID09PSBiLmVuZFxuICAgICYmIGEudmFsdWUgPT09IGIudmFsdWVcbiAgICAmJiBhLnJlbGF0aXZlID09PSBiLnJlbGF0aXZlXG4gICAgJiYgc2FtZUxpc3QoYS52YWx1ZXMsIGIudmFsdWVzKVxuICAgICYmIHNhbWVMaXN0KGEuZXhjbHVkZVZhbHVlcywgYi5leGNsdWRlVmFsdWVzKVxuICAgICYmIGEubWluID09PSBiLm1pblxuICAgICYmIGEubWF4ID09PSBiLm1heDtcbn1cblxuXG4vLyBXaGV0aGVyIHR3byBzdG9yZWQgbGlzdHMgaG9sZCB0aGUgc2FtZSB2YWx1ZXMgaW4gdGhlIHNhbWUgb3JkZXIuXG5mdW5jdGlvbiBzYW1lTGlzdChhOiB1bmtub3duW10gfCB1bmRlZmluZWQsIGI6IHVua25vd25bXSB8IHVuZGVmaW5lZCk6IGJvb2xlYW4ge1xuICByZXR1cm4gKGEgPz8gW10pLmxlbmd0aCA9PT0gKGIgPz8gW10pLmxlbmd0aFxuICAgICYmIChhID8/IFtdKS5ldmVyeSgodmFsdWUsIGluZGV4KSA9PiB2YWx1ZSA9PT0gKGIgPz8gW10pW2luZGV4XSk7XG59XG5cblxuLy8gV2hldGhlciB0d28gbGlzdCBzb3J0cyBvcmRlciB0aGUgcm93cyB0aGUgc2FtZSB3YXkuIE5vIGRpcmVjdGlvbiByZWFkcyBhc1xuLy8gYXNjZW5kaW5nLCB0aGUgd2F5IHRoZSBsaXN0IGFwcGxpZXMgaXQuXG5mdW5jdGlvbiBzYW1lU29ydChhOiBSZXBvcnRTb3J0LCBiOiBSZXBvcnRTb3J0IHwgbnVsbCk6IGJvb2xlYW4ge1xuICByZXR1cm4gISFiXG4gICAgJiYgYS5jb2x1bW4gPT09IGIuY29sdW1uXG4gICAgJiYgKGEuZGlyZWN0aW9uID8/ICdhc2MnKSA9PT0gKGIuZGlyZWN0aW9uID8/ICdhc2MnKTtcbn1cblxuXG4vLyBXaGV0aGVyIGEgdmFsdWUgcmVhZCBvZmYgYSBmaWx0ZXIgYmFyIGlzIHRoZSB2YWx1ZSBhbHJlYWR5IHN0b3JlZCBmb3IgaXRzXG4vLyBncm91cDogdGhlIHNhbWUgY2FsZW5kYXIgZGF5cywgdGhlIHNhbWUgc2VsZWN0IHZhbHVlcyBrZXB0IG9yIGxlZnQgb3V0IGluXG4vLyB0aGUgc2FtZSBvcmRlciwgdGhlIHNhbWUgdHJpbW1lZCB0ZXh0IGFuZCB0aGUgc2FtZSBudW1iZXIgcmFuZ2UgZW5kcy4gQVxuLy8gYmFyIHJlLXJlYWRzIGV2ZXJ5IGdyb3VwIGl0IHNob3dzIG9uIGFueSBjaGFuZ2UsIHNvIHRoaXMgaXMgd2hhdCB0ZWxscyB0aGVcbi8vIGdyb3VwIHRoYXQgY2hhbmdlZCBmcm9tIHRoZSBvbmVzIHRoYXQgZGlkIG5vdC5cbmV4cG9ydCBmdW5jdGlvbiBzYW1lRmlsdGVyVmFsdWUoXG4gIGE6IEZpbHRlckdyb3VwVmFsdWUgfCBudWxsIHwgdW5kZWZpbmVkLFxuICBiOiBGaWx0ZXJHcm91cFZhbHVlIHwgbnVsbCB8IHVuZGVmaW5lZCxcbik6IGJvb2xlYW4ge1xuICByZXR1cm4gZ3JvdXBWYWx1ZVNpZ25hdHVyZShhKSA9PT0gZ3JvdXBWYWx1ZVNpZ25hdHVyZShiKTtcbn1cblxuXG4vLyBUaGUgZ3JvdXBzIGEgYmFyIHJlLXJlYWQgdGhhdCBpdCBub3cgc2hvd3Mgd2l0aCBhIHZhbHVlIG90aGVyIHRoYW4gdGhlIG9uZVxuLy8gaXQgbGFzdCByZXBvcnRlZCwgcmVjb3JkaW5nIGVhY2ggbmV3IHZhbHVlIGluIGBsYXN0UmVwb3J0ZWRgLiBBIGJhciBpc1xuLy8gY29tcGFyZWQgd2l0aCBpdHNlbGYsIG5ldmVyIHdpdGggdGhlIHN0b3JlZCB2YWx1ZTogYSBncm91cCBzaG93biBpbiB0d28gYmFyc1xuLy8gKGxldmVsICdib3RoJykgY2FuIGJlIGNoYW5nZWQgaW4gdGhlIG90aGVyIG9uZSwgYW5kIHRoaXMgYmFyIGlzIG5vdFxuLy8gcmVwYWludGVkLCBzbyBpdHMgc3RhbGUgdmFsdWUgbXVzdCBub3QgYmUgc2V0IGJhY2sgd2hlbiB0aGUgdmlld2VyIGNoYW5nZXNcbi8vIGFub3RoZXIgb2YgaXRzIGl0ZW1zICh0aGUgbGlzdCBzZWFyY2ggYm94LCBzYXkpLlxuZXhwb3J0IGZ1bmN0aW9uIG1vdmVkR3JvdXBWYWx1ZXMoXG4gIGxhc3RSZXBvcnRlZDogTWFwPG51bWJlciwgRmlsdGVyR3JvdXBWYWx1ZSB8IG51bGw+LFxuICByZXBvcnRlZDogeyBncm91cElkOiBudW1iZXI7IHZhbHVlOiBGaWx0ZXJHcm91cFZhbHVlIHwgbnVsbCB9W10sXG4pOiB7IGdyb3VwSWQ6IG51bWJlcjsgdmFsdWU6IEZpbHRlckdyb3VwVmFsdWUgfCBudWxsIH1bXSB7XG4gIHJldHVybiByZXBvcnRlZC5maWx0ZXIoKHsgZ3JvdXBJZCwgdmFsdWUgfSkgPT4ge1xuICAgIGlmIChzYW1lRmlsdGVyVmFsdWUobGFzdFJlcG9ydGVkLmdldChncm91cElkKSwgdmFsdWUpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgbGFzdFJlcG9ydGVkLnNldChncm91cElkLCB2YWx1ZSk7XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSk7XG59XG5cblxuLy8gQSBsaXN0J3Mgc2VhcmNoIHRleHQgYXMgdGhlIHNlcnZlciBhcHBsaWVzIGl0OiB0cmltbWVkLCB0aGVuIGN1dCB0b1xuLy8gTElTVF9TRUFSQ0hfTUFYX0xFTkdUSCBjaGFyYWN0ZXJzIChjb2RlIHBvaW50cywgYXMgdGhlIHNlcnZlciBjb3VudHMgdGhlbSkuXG5leHBvcnQgZnVuY3Rpb24gbGlzdFNlYXJjaFRleHQodGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIFsuLi50ZXh0LnRyaW0oKV0uc2xpY2UoMCwgTElTVF9TRUFSQ0hfTUFYX0xFTkdUSCkuam9pbignJyk7XG59XG5cblxuLy8gV2hldGhlciB0d28gbGlzdHMgb2YgY29sdW1uIG5hbWVzIGFyZSB0aGUgc2FtZSBuYW1lcyBpbiB0aGUgc2FtZSBvcmRlci5cbmZ1bmN0aW9uIHNhbWVOYW1lcyhhOiByZWFkb25seSBzdHJpbmdbXSwgYjogcmVhZG9ubHkgc3RyaW5nW10pOiBib29sZWFuIHtcbiAgcmV0dXJuIGEubGVuZ3RoID09PSBiLmxlbmd0aCAmJiBhLmV2ZXJ5KChuYW1lLCBpbmRleCkgPT4gbmFtZSA9PT0gYltpbmRleF0pO1xufVxuXG5cbi8vIFdoZXRoZXIgdHdvIGhpZGRlbi1jb2x1bW4gbWFwcyBoaWRlIHRoZSBzYW1lIGNvbHVtbnMgb24gdGhlIHNhbWUgbGlzdHMuXG5mdW5jdGlvbiBzYW1lSGlkZGVuKFxuICBhOiBSZWFkb25seU1hcDxudW1iZXIsIHJlYWRvbmx5IHN0cmluZ1tdPixcbiAgYjogUmVhZG9ubHlNYXA8bnVtYmVyLCByZWFkb25seSBzdHJpbmdbXT4sXG4pOiBib29sZWFuIHtcbiAgcmV0dXJuIGEuc2l6ZSA9PT0gYi5zaXplXG4gICAgJiYgWy4uLmFdLmV2ZXJ5KChbY29tcG9uZW50SWQsIG5hbWVzXSkgPT4gc2FtZU5hbWVzKG5hbWVzLCBiLmdldChjb21wb25lbnRJZCkgPz8gW10pKTtcbn1cblxuXG4vLyBXaGV0aGVyIHR3byBkYXRlLXJhbmdlIHZhbHVlcyBjb3ZlciB0aGUgc2FtZSBjYWxlbmRhciBkYXlzLlxuZnVuY3Rpb24gc2FtZURheXMoYTogRmlsdGVyR3JvdXBWYWx1ZSwgYjogRmlsdGVyR3JvdXBWYWx1ZSk6IGJvb2xlYW4ge1xuICByZXR1cm4gZGF0ZUJvdW5kU3RyaW5nKGEuc3RhcnQpID09PSBkYXRlQm91bmRTdHJpbmcoYi5zdGFydClcbiAgICAmJiBkYXRlQm91bmRTdHJpbmcoYS5lbmQpID09PSBkYXRlQm91bmRTdHJpbmcoYi5lbmQpO1xufVxuXG5cbi8vIEEgc3RhYmxlIHNpZ25hdHVyZSBmb3IgYSBncm91cCdzIHN0b3JlZCBkZWZhdWx0LiBUaGUgcmVwb3J0IHRvb2xiYXIga2V5cyBpdHNcbi8vIGZzLWZpbHRlciBvbiB0aGlzLCBiZWNhdXNlIGZzLWZpbHRlciByZWFkcyBpdHMgY29uZmlnIG9uY2UgYXQgaW5pdCDigJQgd2l0aG91dCBhXG4vLyBrZXkgY2hhbmdlIGl0IGtlZXBzIHJlbmRlcmluZyB0aGUgdmFsdWVzIGl0IHdhcyBjcmVhdGVkIHdpdGggZXZlbiBhZnRlciB0aGVcbi8vIGNvbmZpZyBiZWhpbmQgaXQgaGFzIGJlZW4gcmVidWlsdC5cbmV4cG9ydCBmdW5jdGlvbiBkZWZhdWx0U2lnbmF0dXJlKGdyb3VwOiBSZXBvcnRGaWx0ZXJHcm91cCk6IHN0cmluZyB7XG4gIGNvbnN0IGdyb3VwRGVmYXVsdCA9IGdyb3VwLmNvbmZpZz8uZGVmYXVsdDtcblxuICBpZiAoIWdyb3VwRGVmYXVsdCkge1xuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIHJldHVybiBbXG4gICAgZ3JvdXBEZWZhdWx0LnN0YXJ0ID8/ICcnLFxuICAgIGdyb3VwRGVmYXVsdC5lbmQgPz8gJycsXG4gICAgZ3JvdXBEZWZhdWx0LnZhbHVlID8/ICcnLFxuICAgIGdyb3VwRGVmYXVsdC5yZWxhdGl2ZSA/PyAnJyxcbiAgICAoZ3JvdXBEZWZhdWx0LnZhbHVlcyA/PyBbXSkuam9pbignLCcpLFxuICAgIChncm91cERlZmF1bHQuZXhjbHVkZVZhbHVlcyA/PyBbXSkuam9pbignLCcpLFxuICAgIGdyb3VwRGVmYXVsdC5taW4gPz8gJycsXG4gICAgZ3JvdXBEZWZhdWx0Lm1heCA/PyAnJyxcbiAgXS5qb2luKCd+Jyk7XG59XG5cblxuLy8gVGhlIHRlbXBvcmFyeSBsYXllciB3aXRoIG5vdGhpbmcgcGlja2VkLlxuZnVuY3Rpb24gZW1wdHlUZW1wb3JhcnlTdGF0ZSgpOiBSZXBvcnRUZW1wb3JhcnlTdGF0ZSB7XG4gIHJldHVybiB7IGNyb3NzRmlsdGVyczogW10sIGRldGFpbDogbnVsbCB9O1xufVxuXG5cbi8vIFZpZXdlciBmaWx0ZXIgc3RhdGUgZm9yIHRoZSBvcGVuIHJlcG9ydC4gRmlsdGVyIFZBTFVFUyBhcmUgbmV2ZXIgc2F2ZWQgdG9cbi8vIHRoZSByZXBvcnQg4oCUIHRoaXMgc2VydmljZSBob2xkcyB0aGVtIHBlciBmaWx0ZXIgR1JPVVAgKHRoZSBwcm9wYWdhdGlvbiB1bml0KSxcbi8vIHJlc29sdmVzIHRoZW0gaW50byBwZXItY29tcG9uZW50IG1lbWJlci1maWx0ZXIgdmFsdWVzIGZvciBlYWNoIGRhdGEgcmVxdWVzdCxcbi8vIGFuZCBub3RpZmllcyB0aGUgY29tcG9uZW50cyB3aG9zZSBncm91cHMgY2hhbmdlZCBzbyBvbmx5IHRoZXkgcmVmZXRjaC5cbi8vXG4vLyBJdCBpcyB0aGUgb25lIHBsYWNlIHRoZSB2aWV3ZXIncyBzdGF0ZSBsaXZlcyB3aGlsZSB0aGUgcmVwb3J0IGlzIG9wZW46IHRoZVxuLy8gZ3JvdXAgdmFsdWVzLCB0aGUgZ3JvdXAtYnkgZ3JhaW4sIHRoZSBtYXRjaCwgbGlzdCBzb3J0cywgc2VhcmNoZXMgYW5kIGhpZGRlblxuLy8gY29sdW1ucywgdGhlIHBhZ2UgYW5kIGVhY2ggY2hhcnQncyBkcmlsbCBwYXRoLiBOb25lIG9mIGl0IGlzIGV2ZXIgd3JpdHRlbiB0b1xuLy8gdGhlIGJyb3dzZXIgVVJMLiBJdCBvdXRsaXZlcyBhIHBhZ2Ugc3dpdGNoICh0aGUgY2FudmFzIGNoYW5nZXMgdGhlIHBhZ2UsIG5vdFxuLy8gdGhpcyBzZXJ2aWNlKSBhbmQgZ29lcyB3aXRoIHRoZSByZXBvcnQgdmlldzogYSByZWxvYWQgc3RhcnRzIGEgbmV3IHNlcnZpY2UsXG4vLyB3aGljaCBvcGVucyBvbiB0aGUgcmVwb3J0J3MgZGVmYXVsdHMgb3IgdGhlIHZpZXdlcidzIGRlZmF1bHQgdmlldy5cbi8vIGNoYW5nZXMoKSBmaXJlcyBvbiBldmVyeSBjaGFuZ2Ugb2YgaXQuXG4vL1xuLy8gVGhlIGR1cmFibGUgcGFydCBpcyBvbmUgdmlldyBkb2N1bWVudDogc25hcHNob3QoKSB3cml0ZXMgaXQsIGFwcGx5KCkgb3BlbnNcbi8vIGEgdmlldywgYW5kIGJhc2UgYW5kIHZpZXdDaGFuZ2VkIHNheSB3aGV0aGVyIHRoZSBzY3JlZW4gc3RpbGwgc2hvd3MgdGhhdFxuLy8gdmlldy4gVGhlIHRlbXBvcmFyeSBsYXllciAoYSBjcm9zcy1maWx0ZXIsIGFuIG9wZW4gcm93cyBwYW5lbCkgaXMgaXRzIG93blxuLy8gc2VjdGlvbiwgc28gbm8gdmlldyBldmVyIGNhcnJpZXMgaXQuXG4vL1xuLy8gU2Vzc2lvbi1vbmx5LCBuZXZlciBpbiBhIHZpZXc6IHBlci1maWx0ZXIgZW5hYmxlL2Rpc2FibGUgdG9nZ2xlcyBmcm9tIGFcbi8vIGNvbXBvbmVudCdzIGZpbHRlciBtZW51ICh0aGUgYGVuYWJsZWRgIGNvbHVtbiBpcyB0aGUgYXV0aG9yZWQgZGVmYXVsdDsgYVxuLy8gdmlld2VyJ3MgdG9nZ2xlIHNob3VsZG4ndCB3cml0ZSB0byB0aGUgcmVwb3J0KS5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBSZXBvcnRGaWx0ZXJTdGF0ZVNlcnZpY2Uge1xuXG4gIC8vIFRoZSBvcGVuIHJlcG9ydCdzIGVmZmVjdGl2ZSB6b25lIChyZXNvbHZlUmVwb3J0VGltZXpvbmUpLiBSZWxhdGl2ZSBwcmVzZXRzXG4gIC8vIHJlc29sdmUgYWdhaW5zdCB0b2RheSBpbiBpdCwgYW5kIGRhdGUgY2VsbHMgcmVuZGVyIGluIGl0LlxuICBwdWJsaWMgcmVhZG9ubHkgdGltZXpvbmUgPSBzaWduYWw8c3RyaW5nPignVVRDJyk7XG5cbiAgLy8gSG93IHRoZSBvcGVuIHJlcG9ydCB3cml0ZXMgaXRzIG51bWJlcnMgYW5kIGRhdGVzIChyZXNvbHZlRm9ybWF0Q29udGV4dCk6XG4gIC8vIGl0cyBsb2NhbGUsIGl0cyBjdXJyZW5jeSBhbmQgd2hldGhlciBwZXJjZW50cyBhcnJpdmUgYXMgcmF0aW9zLiBFdmVyeSBLUEksXG4gIC8vIGNoYXJ0LCBkYXRlIGNlbGwgYW5kIGV4cG9ydCByZWFkcyBpdCBoZXJlLiBDb21wYXJlZCBieSB2YWx1ZSwgc28gYSByZWxvYWRcbiAgLy8gb2YgYW4gdW5jaGFuZ2VkIHJlcG9ydCByZS1yZW5kZXJzIG5vdGhpbmcuXG4gIHB1YmxpYyByZWFkb25seSBmb3JtYXRDb250ZXh0ID0gc2lnbmFsPFJlcG9ydEZvcm1hdENvbnRleHQ+KERFRkFVTFRfRk9STUFUX0NPTlRFWFQsIHtcbiAgICBlcXVhbDogKGEsIGIpID0+IGEubG9jYWxlID09PSBiLmxvY2FsZVxuICAgICAgJiYgYS5jdXJyZW5jeSA9PT0gYi5jdXJyZW5jeVxuICAgICAgJiYgYS5yYXRpb1BlcmNlbnQgPT09IGIucmF0aW9QZXJjZW50LFxuICB9KTtcblxuICAvLyBUaGUgY29uZmlnIGNvbHVtbnMgYSB2aWV3ZXIgaGlkIG9uIGVhY2ggcGxhaW4gbGlzdCAobGlzdEhpZGRlbkNvbHVtbnMpLFxuICAvLyBieSBjb21wb25lbnQgaWQ7IGEgbGlzdCBzaG93aW5nIGV2ZXJ5IGNvbHVtbiBoYXMgbm8gZW50cnkuIEEgc2lnbmFsLCBzbyBhXG4gIC8vIGxpc3QgaGlkZXMgYW5kIHNob3dzIGl0cyBjb2x1bW5zIGluIHBsYWNlOiB0aGUgcm93cyBkbyBub3QgY2hhbmdlLCBzb1xuICAvLyBub3RoaW5nIHJlZmV0Y2hlcy4gQ29tcGFyZWQgYnkgdmFsdWUsIHNvIGEgcmVsb2FkIHRoYXQga2VlcHMgZXZlcnkgY29sdW1uXG4gIC8vIHJlcGFpbnRzIG5vdGhpbmcuXG4gIHB1YmxpYyByZWFkb25seSBsaXN0SGlkZGVuID0gc2lnbmFsPFJlYWRvbmx5TWFwPG51bWJlciwgcmVhZG9ubHkgc3RyaW5nW10+PihuZXcgTWFwKCksIHtcbiAgICBlcXVhbDogc2FtZUhpZGRlbixcbiAgfSk7XG5cbiAgLy8gTW92ZXMgZWFjaCB0aW1lIGFwcGx5KCkgb3IgcmVzZXRUb0Jhc2UoKSByZXBsYWNlcyB0aGUgd2hvbGUgZHVyYWJsZVxuICAvLyBzdGF0ZS4gQmFycyBhbmQgdGlsZXMga2V5IG9uIGl0LCBzbyBhbiBhcHBsaWVkIHZpZXcgcmVwYWludHMgYWxsIG9mIHRoZW0uXG4gIHB1YmxpYyByZWFkb25seSBzdGF0ZVZlcnNpb24gPSBjb21wdXRlZCgoKSA9PiB0aGlzLl9zdGF0ZVZlcnNpb24oKSk7XG5cbiAgLy8gTW92ZXMgZWFjaCB0aW1lIGFwcGx5KCkgb3BlbnMgYSB2aWV3IChvciB0aGUgcmVwb3J0J3MgZGVmYXVsdHMpLiBUaGVcbiAgLy8gY2FudmFzIGtleXMgaXRzIHRpbGVzIG9uIGl0LCBzbyBhbiBvcGVuZWQgdmlldyBkcmF3cyBlYWNoIG9uZSBhZ2Fpbi5cbiAgLy8gcmVzZXRUb0Jhc2UoKSBsZWF2ZXMgaXQ6IGEgcmVzZXQgcmVmZXRjaGVzIHRoZSB0aWxlcyBpbiBwbGFjZSwgc28gdGhlaXJcbiAgLy8gZGF0YSBzdGF5cyBvbiBzY3JlZW4gd2hpbGUgdGhleSByZWxvYWQuXG4gIHB1YmxpYyByZWFkb25seSBhcHBsaWVkVmVyc2lvbiA9IGNvbXB1dGVkKCgpID0+IHRoaXMuX2FwcGxpZWRWZXJzaW9uKCkpO1xuXG4gIC8vIEJ5IGxpc3QgY29tcG9uZW50IGlkLCBob3cgbWFueSByZXNldHMgbW92ZWQgdGhhdCBsaXN0J3Mgc29ydC4gRnNMaXN0XG4gIC8vIHJlYWRzIGl0cyBzb3J0IG9ubHkgd2hlbiBpdCBpcyBjcmVhdGVkLCBzbyBhIGxpc3Qgd2hvc2Ugc29ydCBhIHJlc2V0XG4gIC8vIG1vdmVkIGlzIGRyYXduIGFnYWluIChrZXllZCBvbiBpdHMgY291bnQpOyBldmVyeSBvdGhlciB0aWxlIHJlbG9hZHMgaW5cbiAgLy8gcGxhY2UuXG4gIHB1YmxpYyByZWFkb25seSBsaXN0U29ydFJlc2V0cyA9IGNvbXB1dGVkKCgpID0+IHRoaXMuX2xpc3RTb3J0UmVzZXRzKCkpO1xuXG4gIC8vIFRoZSBvcGVuIHBhZ2UsIG9yIG51bGwgYmVmb3JlIHRoZSBob3N0IHJlcG9ydHMgb25lIChzZXRQYWdlKS5cbiAgcHVibGljIHJlYWRvbmx5IHBhZ2UgPSBjb21wdXRlZCgoKSA9PiB0aGlzLl9wYWdlSWQoKSk7XG5cbiAgLy8gSG93IHRoZSBncm91cHMgY29tYmluZTogJ2FsbCcga2VlcHMgdGhlIHJvd3MgZXZlcnkgZ3JvdXAga2VlcHMsICdhbnknXG4gIC8vIHRoZSByb3dzIGF0IGxlYXN0IG9uZSBlbGlnaWJsZSBncm91cCBrZWVwcyAoc2V0TWF0Y2gpLlxuICBwdWJsaWMgcmVhZG9ubHkgbWF0Y2ggPSBjb21wdXRlZCgoKSA9PiB0aGlzLl9tYXRjaCgpKTtcblxuICAvLyBUaGUgdmlld2VyIGZlYXR1cmVzIHRoZSBvcGVuIHJlcG9ydCdzIHNlcnZlciBzZXJ2ZXMgKFJlcG9ydC52aWV3ZXJGZWF0dXJlcyk6XG4gIC8vIGEgZmlsdGVyIGJhciBvZmZlcnMgYSBjb250cm9sIG9ubHkgd2hlbiBpdHMgZmVhdHVyZSBpcyBsaXN0ZWQuIEVtcHR5XG4gIC8vIGJlZm9yZSBhIHJlcG9ydCBpcyBvcGVuIGFuZCBmcm9tIGFuIG9sZGVyIHNlcnZlci5cbiAgcHVibGljIHJlYWRvbmx5IHZpZXdlckZlYXR1cmVzID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5fcmVwb3J0KCk/LnZpZXdlckZlYXR1cmVzID8/IFtdKTtcblxuICAvLyBUaGUgcmVwb3J0IGluaXQoKSBsYXN0IHJlYWQsIG9yIG51bGwgYmVmb3JlIG9uZSBpcyBvcGVuLiBBIHRpbGUgaGVhZGVyXG4gIC8vIGxpc3RzIGl0cyBzZWxlY3Qgb3B0aW9ucyBmcm9tIGl0IChSZXBvcnRGaWx0ZXJPcHRpb25zU2VydmljZSkuXG4gIHB1YmxpYyByZWFkb25seSByZXBvcnQgPSBjb21wdXRlZCgoKSA9PiB0aGlzLl9yZXBvcnQoKSk7XG5cbiAgLy8gVGhlIHN0YXRlIHRoZSBzY3JlZW4gaXMgY29tcGFyZWQgd2l0aDogdGhlIGJhc2UgYXBwbHkoKSB3YXMgZ2l2ZW4gKHRoZVxuICAvLyBvcGVuIHZpZXcgYXMgaXQgYXBwbGllZCksIG9yIHRoZSByZXBvcnQncyBhdXRob3JlZCBkZWZhdWx0c1xuICAvLyAoYXV0aG9yZWRDb25maWcoKSkgd2hlbiBubyB2aWV3IGlzIG9wZW4uIEl0IGhvbGRzIG9ubHkgdGhlIGdyb3VwcyB0aGVcbiAgLy8gdmlldyBoZWxkOyBldmVyeSBvdGhlciBncm91cCBmb2xsb3dzIGl0cyBhdXRob3JlZCBkZWZhdWx0LlxuICBwdWJsaWMgcmVhZG9ubHkgYmFzZSA9IGNvbXB1dGVkPFJlcG9ydFZpZXdDb25maWc+KCgpID0+IHtcbiAgICB0aGlzLl9yZXZpc2lvbigpO1xuXG4gICAgcmV0dXJuIHRoaXMuX2Jhc2VDb25maWcoKSA/PyB0aGlzLmF1dGhvcmVkQ29uZmlnKCk7XG4gIH0pO1xuXG4gIC8vIFdoZXRoZXIgdGhlIHNjcmVlbiBkaWZmZXJzIGZyb20gYmFzZSAodmlld0RpZmZlcnMpOiB3aGF0IGEgdmlldyBwaWNrZXJcbiAgLy8gbWFya3MgJyhlZGl0ZWQpJy4gQSBzd2l0Y2ggb2YgcGFnZSBkb2VzIG5vdCBjb3VudCwgYW5kIHRoZSB0ZW1wb3JhcnlcbiAgLy8gc3RhdGUgbmV2ZXIgZG9lcy5cbiAgcHVibGljIHJlYWRvbmx5IHZpZXdDaGFuZ2VkID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIHRoaXMuX3JldmlzaW9uKCk7XG5cbiAgICByZXR1cm4gdmlld0RpZmZlcnModGhpcy5iYXNlKCksIHRoaXMuc25hcHNob3QoKSwgdGhpcy5hdXRob3JlZENvbmZpZygpKTtcbiAgfSk7XG5cbiAgcHJpdmF0ZSBfdmFsdWVzID0gbmV3IE1hcDxudW1iZXIsIEZpbHRlckdyb3VwVmFsdWU+KCk7XG4gIHByaXZhdGUgX2dyb3VwcyA9IG5ldyBNYXA8bnVtYmVyLCBSZXBvcnRGaWx0ZXJHcm91cD4oKTtcbiAgcHJpdmF0ZSBfc2Vzc2lvbkRpc2FibGVkID0gbmV3IFNldDxudW1iZXI+KCk7XG5cbiAgLy8gR3JvdXBzIHRoYXQgaGF2ZSBhIGRlZmF1bHQgdGhlIHZpZXdlciBjbGVhcmVkLiBXaXRob3V0IHRoaXMgYSByZWxvYWQgb2YgdGhlXG4gIC8vIHJlcG9ydCAoYSBjaGF0IGVkaXQsIGEgZGlhbG9nKSB3b3VsZCBmaW5kIG5vIHZhbHVlIGZvciB0aGUgZ3JvdXAgYW5kIHNlZWRcbiAgLy8gaXRzIGRlZmF1bHQgc3RyYWlnaHQgYmFjay4gQSBjaGFuZ2UgdG8gdGhlIHN0b3JlZCBkZWZhdWx0IHJlbGVhc2VzIGl0LlxuICBwcml2YXRlIF9jbGVhcmVkID0gbmV3IFNldDxudW1iZXI+KCk7XG5cbiAgLy8gVGhlIHJlcG9ydCdzIGdyb3VwLWJ5IGNvbnRyb2w6IGEgc2luZ2xlIHJlcG9ydC13aWRlIGJ1Y2tldCBvdmVycmlkZSBmb3IgYWxsXG4gIC8vIHRpbWUtc2VyaWVzIGNoYXJ0cy4gVW5zZXQgPSBlYWNoIGNoYXJ0IHVzZXMgaXRzIGF1dGhvcmVkIGdyYW51bGFyaXR5LiBOZXZlclxuICAvLyBzYXZlZCB0byB0aGUgcmVwb3J0IChhIHNhdmVkIHZpZXcga2VlcHMgaXQpLCBhbmQgY2FycmllZCBpbiB0aGUgZGF0YSByZXF1ZXN0J3NcbiAgLy8gYHN0YXRlYCwgc28gaXQgcHJvcGFnYXRlcyB0aHJvdWdoIHRvIHRoZSBQREYvUG93ZXJQb2ludCBleHBvcnRzIHRvby4gTmFtZWRcbiAgLy8gZm9yIHRoZSBgZnJlcXVlbmN5YCB3aXJlIGtleSBpdCB0cmF2ZWxzIHVuZGVyLCBub3QgZm9yIHRoZSBjb250cm9sJ3MgbGFiZWwuXG4gIHByaXZhdGUgX2ZyZXF1ZW5jeTogQ2hhcnRHcmFudWxhcml0eSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIF9mcmVxdWVuY3lDaGFuZ2VkJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgLy8gRWFjaCBsaXN0J3Mgdmlld2VyLWNob3NlbiBzb3J0LCBieSBjb21wb25lbnQgaWQuIEhlbGQgaGVyZSByYXRoZXIgdGhhbiBvbmx5XG4gIC8vIGluIHRoZSBsaXN0J3MgRnNMaXN0IHNvIGl0IHN1cnZpdmVzIHRoZSBsaXN0IGJlaW5nIHJlY3JlYXRlZCAoYSBwYWdlIHN3aXRjaCxcbiAgLy8gYSByZWxvYWQgYWZ0ZXIgYW4gZWRpdCkgYW5kIHNvIGV2ZXJ5IGNvbnN1bWVyIG9mIHZpZXdlciBzdGF0ZSByZWFkcyBvbmUgcGxhY2UuXG4gIHByaXZhdGUgX2xpc3RTb3J0cyA9IG5ldyBNYXA8bnVtYmVyLCBSZXBvcnRTb3J0PigpO1xuXG4gIC8vIEVhY2ggbGlzdCdzIHNlYXJjaCBib3ggdGV4dCAobGlzdFNlYXJjaFRleHQpLCBieSBjb21wb25lbnQgaWQuIEEgbGlzdCB3aXRoXG4gIC8vIGFuIGVtcHR5IGJveCBoYXMgbm8gZW50cnkuIEhlbGQgaGVyZSBmb3IgdGhlIHNhbWUgcmVhc29ucyBhcyB0aGUgc29ydHMsIGFuZFxuICAvLyBiZWNhdXNlIHRoZSBib3ggbGl2ZXMgaW4gdGhlIGNvbXBvbmVudCBoZWFkZXIsIG5vdCBpbiB0aGUgbGlzdC5cbiAgcHJpdmF0ZSBfbGlzdFNlYXJjaGVzID0gbmV3IE1hcDxudW1iZXIsIHN0cmluZz4oKTtcblxuICAvLyBUaGUgb3BlbiByZXBvcnQncyBsaXN0cywgYnkgY29tcG9uZW50IGlkLCBzbyBhIGZpbHRlciB0b2dnbGUgY2FuIHRlbGxcbiAgLy8gd2hpY2ggb2YgdGhlbSBsb3NlIHRoZWlyIHNlYXJjaCBib3ggKGxpc3RTZWFyY2hhYmxlKS5cbiAgcHJpdmF0ZSBfbGlzdHMgPSBuZXcgTWFwPG51bWJlciwgUmVwb3J0Q29tcG9uZW50PigpO1xuXG4gIC8vIFdoZXRoZXIgdGhlIHNlcnZlciBhbnN3ZXJzIGEgbGlzdCBzZWFyY2guIExpc3Qgc2VhcmNoIGFuZCBlZmZlY3RpdmVMb2NhbGVcbiAgLy8gc2hpcCBpbiB0aGUgc2FtZSBmcmFtZXdvcmsgY2hhbmdlIHNldCwgc28gYSBzZXJ2ZXIgdGhhdCBzZW5kcyBub1xuICAvLyBlZmZlY3RpdmVMb2NhbGUgaGFzIG5laXRoZXIsIGFuZCBpdHMgbGlzdHMgc2hvdyBubyBzZWFyY2ggYm94LlxuICBwcml2YXRlIF9zZXJ2ZXJTZWFyY2hlcyA9IGZhbHNlO1xuXG4gIC8vIEVtaXRzIHRoZSBpZCBvZiB0aGUgbGlzdCB3aG9zZSBzZWFyY2ggdGV4dCBjaGFuZ2VkLlxuICBwcml2YXRlIF9saXN0U2VhcmNoQ2hhbmdlZCQgPSBuZXcgU3ViamVjdDxudW1iZXI+KCk7XG5cbiAgLy8gRW1pdHMgdGhlIGdyb3VwIGlkIHRoYXQgY2hhbmdlZDsgY29tcG9uZW50cyBsaXN0ZW4gZmlsdGVyZWQgdG8gdGhlaXIgb3duXG4gIC8vIGdyb3VwIGlkcy4gbnVsbCA9IGV2ZXJ5dGhpbmcgY2hhbmdlZCAocmUtaW5pdCkuXG4gIHByaXZhdGUgX2NoYW5nZWQkID0gbmV3IFN1YmplY3Q8bnVtYmVyIHwgbnVsbD4oKTtcblxuICAvLyBGaXJlcyB3aGVuZXZlciBhbnl0aGluZyBpbiB0aGUgdmlld2VyIHN0YXRlIG1heSBoYXZlIGNoYW5nZWQuXG4gIHByaXZhdGUgX3N0YXRlQ2hhbmdlZCQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIC8vIENvdW50cyB0aGUgY2hhbmdlcyBjaGFuZ2VzKCkgcmVwb3J0cy4gVGhlIGdyb3VwIHZhbHVlcywgdGhlIGdyYWluIGFuZFxuICAvLyB0aGUgbGlzdCBzdGF0ZSB0aGF0IGJhc2UgYW5kIHZpZXdDaGFuZ2VkIGNvbXBhcmUgYXJlIHRoZSBwbGFpbiBmaWVsZHNcbiAgLy8gYWJvdmUsIHdoaWNoIGV2ZXJ5IHNldHRlciByZXBvcnRzIHRocm91Z2ggY2hhbmdlcygpICh0aGV5IGFyZSBzaGFyZWRcbiAgLy8gd2l0aCB0aGUgaW5saW5lIHZhbHVlcyBidWlsZCwgc28gdGhleSBzdGF5IGFzIHRoZXkgYXJlKTsgdGhpcyBjb3VudGVyIGlzXG4gIC8vIGhvdyB0aGUgdHdvIGNvbXB1dGVkcyBoZWFyIG9mIHRoZW0uIFRoZSB2aWV3IHN0YXRlIGJlbG93IGlzIHNpZ25hbHMgYW5kXG4gIC8vIGlzIHJlYWQgZGlyZWN0bHkuIFRoZSBzdWJqZWN0IGlzIHRoaXMgc2VydmljZSdzIG93biBhbmQgaXMgbmV2ZXJcbiAgLy8gY29tcGxldGVkLCBzbyB0aGUgc2lnbmFsIGxpc3RlbnMgdG8gaXQgZXhhY3RseSBhcyBsb25nIGFzIHRoZSBzZXJ2aWNlXG4gIC8vIGxpdmVzLlxuICBwcml2YXRlIF9yZXZpc2lvbiA9IHRvU2lnbmFsKHRoaXMuX3N0YXRlQ2hhbmdlZCQucGlwZShzY2FuKChjb3VudCkgPT4gY291bnQgKyAxLCAwKSksIHtcbiAgICBpbml0aWFsVmFsdWU6IDAsXG4gICAgbWFudWFsQ2xlYW51cDogdHJ1ZSxcbiAgfSk7XG5cbiAgcHJpdmF0ZSBfc3RhdGVWZXJzaW9uID0gc2lnbmFsKDApO1xuXG4gIHByaXZhdGUgX2FwcGxpZWRWZXJzaW9uID0gc2lnbmFsKDApO1xuXG4gIHByaXZhdGUgX2xpc3RTb3J0UmVzZXRzID0gc2lnbmFsPFJlYWRvbmx5TWFwPG51bWJlciwgbnVtYmVyPj4obmV3IE1hcCgpKTtcblxuICAvLyBUaGUgcmVwb3J0IGluaXQoKSBsYXN0IHJlYWQ6IHRoZSB0aWxlcyBhbmQgcGFnZXMgYSB2aWV3J3Mgc3RhdGUgaXNcbiAgLy8gY2hlY2tlZCBhZ2FpbnN0LlxuICBwcml2YXRlIF9yZXBvcnQgPSBzaWduYWw8UmVwb3J0IHwgbnVsbD4obnVsbCk7XG5cbiAgLy8gVGhlIG9wZW4gcGFnZSwgc2V0IGJ5IHRoZSBob3N0IGFzIHRoZSB2aWV3ZXIgbW92ZXMgYmV0d2VlbiBwYWdlcy4gQSB2aWV3XG4gIC8vIHN0b3JlcyBpdCwgYnV0IG1vdmluZyB0byBhbm90aGVyIHBhZ2UgbmV2ZXIgZWRpdHMgYSB2aWV3LlxuICBwcml2YXRlIF9wYWdlSWQgPSBzaWduYWw8bnVtYmVyIHwgbnVsbD4obnVsbCk7XG5cbiAgLy8gSG93IHRoZSBncm91cHMgY29tYmluZTogJ2FsbCcgKHRoZSBkZWZhdWx0KSBvciAnYW55Jy5cbiAgcHJpdmF0ZSBfbWF0Y2ggPSBzaWduYWw8UmVwb3J0RmlsdGVyTWF0Y2g+KCdhbGwnKTtcblxuICAvLyBFYWNoIGNoYXJ0J3MgZHJpbGwgcGF0aCwgdG9wIGZpcnN0LCBieSBjb21wb25lbnQgaWQuIEEgY2hhcnQgYXQgaXRzIHRvcFxuICAvLyBoYXMgbm8gZW50cnksIGFuZCBvbmx5IGEgY2hhcnQgaGFzIG9uZS5cbiAgcHJpdmF0ZSBfZHJpbGxzID0gc2lnbmFsPFJlYWRvbmx5TWFwPG51bWJlciwgcmVhZG9ubHkgUmVwb3J0RHJpbGxTdGVwW10+PihuZXcgTWFwKCkpO1xuXG4gIC8vIEVtaXRzIHRoZSBpZCBvZiB0aGUgY2hhcnQgd2hvc2UgZHJpbGwgcGF0aCBjaGFuZ2VkLlxuICBwcml2YXRlIF9kcmlsbENoYW5nZWQkID0gbmV3IFN1YmplY3Q8bnVtYmVyPigpO1xuXG4gIC8vIFRoZSBiYXNlIGFzIGFwcGx5KCkgYXBwbGllZCBpdCwgb3IgbnVsbCB3aGVuIHRoZSBiYXNlIGlzIHRoZSBhdXRob3JlZFxuICAvLyBkZWZhdWx0cyAoc2VlIGJhc2UpLlxuICBwcml2YXRlIF9iYXNlQ29uZmlnID0gc2lnbmFsPFJlcG9ydFZpZXdDb25maWcgfCBudWxsPihudWxsKTtcblxuICAvLyBUaGUgdGVtcG9yYXJ5IGxheWVyOiBrZXB0IGFwYXJ0IGZyb20gZXZlcnl0aGluZyBhYm92ZSwgc28gc25hcHNob3QoKVxuICAvLyBhbmQgdmlld0NoYW5nZWQgbmV2ZXIgcmVhZCBpdC5cbiAgcHJpdmF0ZSBfdGVtcG9yYXJ5ID0gc2lnbmFsPFJlcG9ydFRlbXBvcmFyeVN0YXRlPihlbXB0eVRlbXBvcmFyeVN0YXRlKCkpO1xuXG4gIC8vIFNlZWQgZ3JvdXBzICsgdGhlaXIgZGVmYXVsdHMgd2hlbiBhIHJlcG9ydCBsb2Fkcy4gRXhpc3Rpbmcgc2Vzc2lvbiB2YWx1ZXNcbiAgLy8gZm9yIHN0aWxsLWV4aXN0aW5nIGdyb3VwcyBzdXJ2aXZlIGEgc3RydWN0dXJlIHJlLWZldGNoIChhIGNoYXQgZWRpdFxuICAvLyBzaG91bGRuJ3QgcmVzZXQgdGhlIHZpZXdlcidzIGZpbHRlcnMpLCBhbmQgc28gZG9lcyBhIGdyb3VwIHRoZSB2aWV3ZXJcbiAgLy8gY2xlYXJlZCDigJQgVU5MRVNTIHRoZSBncm91cCdzIHN0b3JlZCBkZWZhdWx0IGl0c2VsZiBjaGFuZ2VkLCB3aGljaCBvbmx5XG4gIC8vIGhhcHBlbnMgd2hlbiBhbiBvcGVyYXRvciBzYXZlZCBhIG5ldyBkZWZhdWx0IGluIHJlcG9ydCBzZXR0aW5ncyBvciB0aGVcbiAgLy8gYWdlbnQgc2V0IG9uZS4gVGhhdCBpcyBhbiBleHBsaWNpdCBpbnN0cnVjdGlvbiB0byByZS1zZWVkLCBzbyBpdCB3aW5zIG92ZXJcbiAgLy8gdGhlIHN1cnZpdmluZyBzZXNzaW9uIHZhbHVlOyB3aXRob3V0IGl0IHRoZSBiYXIga2VlcHMgc2hvd2luZyB3aGF0ZXZlciBpdFxuICAvLyB3YXMgZmlyc3Qgc2VlZGVkIHdpdGggdW50aWwgYSBmdWxsIHBhZ2UgcmVsb2FkLlxuICAvL1xuICAvLyBBIGNoYW5nZSBvZiB0aGUgcmVwb3J0J3Mgem9uZSBtb3ZlcyBcInRvZGF5XCIsIHNvIGEgdmFsdWUgc3RpbGwgY2FycnlpbmcgaXRzXG4gIC8vIGdyb3VwIGRlZmF1bHQncyBwcmVzZXQgbmFtZSBpcyByZXNvbHZlZCBhZ2FpbiBpbiB0aGUgbmV3IHpvbmUuIEEgdmFsdWUgdGhlXG4gIC8vIHZpZXdlciBwaWNrZWQsIG9yIG9uZSBjYXJyeWluZyBhbm90aGVyIHByZXNldCBuYW1lLCBpcyBrZXB0IGFzIGl0IGlzLlxuICBwdWJsaWMgaW5pdChyZXBvcnQ6IFJlcG9ydCk6IHZvaWQge1xuICAgIGNvbnN0IHByZXZpb3VzVGltZXpvbmUgPSB0aGlzLnRpbWV6b25lKCk7XG5cbiAgICAvLyBTZXQgZmlyc3Q6IHRoZSBkZWZhdWx0cyBzZWVkZWQgYmVsb3cgcmVzb2x2ZSB0aGVpciByZWxhdGl2ZSBwcmVzZXRzIGluIGl0LlxuICAgIHRoaXMudGltZXpvbmUuc2V0KHJlc29sdmVSZXBvcnRUaW1lem9uZShyZXBvcnQpKTtcbiAgICB0aGlzLmZvcm1hdENvbnRleHQuc2V0KHJlc29sdmVGb3JtYXRDb250ZXh0KHJlcG9ydCkpO1xuICAgIC8vIEJlZm9yZSB0aGUgcHJ1bmluZzogbGlzdFNlYXJjaGFibGUgcmVhZHMgaXQuXG4gICAgdGhpcy5fc2VydmVyU2VhcmNoZXMgPSByZXBvcnQuZWZmZWN0aXZlTG9jYWxlICE9PSB1bmRlZmluZWQ7XG5cbiAgICBjb25zdCB0aW1lem9uZUNoYW5nZWQgPSBwcmV2aW91c1RpbWV6b25lICE9PSB0aGlzLnRpbWV6b25lKCk7XG4gICAgY29uc3QgcHJldmlvdXNHcm91cHMgPSB0aGlzLl9ncm91cHM7XG4gICAgdGhpcy5fZ3JvdXBzID0gbmV3IE1hcDxudW1iZXIsIFJlcG9ydEZpbHRlckdyb3VwPigpO1xuXG4gICAgZm9yIChjb25zdCBncm91cCBvZiByZXBvcnQuZmlsdGVyR3JvdXBzID8/IFtdKSB7XG4gICAgICB0aGlzLl9ncm91cHMuc2V0KGdyb3VwLmlkLCBncm91cCk7XG4gICAgICB0aGlzLl9zZWVkKGdyb3VwLCBwcmV2aW91c0dyb3Vwcy5nZXQoZ3JvdXAuaWQpID8/IG51bGwsIHRpbWV6b25lQ2hhbmdlZCk7XG4gICAgfVxuXG4gICAgdGhpcy5fbGlzdHMgPSBuZXcgTWFwKHRoaXMuX2xpc3RDb21wb25lbnRzKHJlcG9ydCkubWFwKChjb21wb25lbnQpID0+IFtjb21wb25lbnQuaWQsIGNvbXBvbmVudF0pKTtcblxuICAgIHRoaXMuX3BydW5lKHJlcG9ydCk7XG4gICAgdGhpcy5fcHJ1bmVWaWV3U3RhdGUocmVwb3J0LCBwcmV2aW91c0dyb3Vwcyk7XG5cbiAgICB0aGlzLl9jaGFuZ2VkJC5uZXh0KG51bGwpO1xuICAgIHRoaXMuX3N0YXRlQ2hhbmdlZCQubmV4dCgpO1xuICB9XG5cbiAgcHVibGljIHZhbHVlKGdyb3VwSWQ6IG51bWJlcik6IEZpbHRlckdyb3VwVmFsdWUgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZXMuZ2V0KGdyb3VwSWQpO1xuICB9XG5cbiAgLy8gQSBiYXIncyB2YWx1ZSBmb3IgYSBncm91cC4gQSBkYXRlIHJhbmdlIGtlZXBzIHRoZSBzdG9yZWQgcHJlc2V0IG5hbWUgb25seVxuICAvLyB3aGlsZSBpdHMgZGF5cyBhcmUgc3RpbGwgdGhlIHN0b3JlZCBkYXlzOiB0aGUgYmFycyByZS1zZXQgZXZlcnkgZ3JvdXAgdGhleVxuICAvLyBzaG93IHdoZW5ldmVyIGFueSBvbmUgb2YgdGhlbSBjaGFuZ2VzLCBhbmQgYW4gdW50b3VjaGVkIHJvbGxpbmcgcmFuZ2UgbXVzdFxuICAvLyBrZWVwIGl0cyBuYW1lIHJhdGhlciB0aGFuIHR1cm4gaW50byB0d28gZml4ZWQgZGF0ZXMuIEFueSBvdGhlciByYW5nZSwgYVxuICAvLyBkYXRlIHBpY2tlciBwcmVzZXQgaW5jbHVkZWQsIGlzIHN0b3JlZCBhcyB0aGUgZml4ZWQgZGF0ZXMgaXQgc2hvd3MuXG4gIHB1YmxpYyBzZXRWYWx1ZShncm91cElkOiBudW1iZXIsIHZhbHVlOiBGaWx0ZXJHcm91cFZhbHVlIHwgbnVsbCk6IHZvaWQge1xuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgdGhpcy5fdmFsdWVzLmRlbGV0ZShncm91cElkKTtcblxuICAgICAgaWYgKHRoaXMuX2dyb3Vwcy5nZXQoZ3JvdXBJZCk/LmNvbmZpZz8uZGVmYXVsdCkge1xuICAgICAgICB0aGlzLl9jbGVhcmVkLmFkZChncm91cElkKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fdmFsdWVzLnNldChncm91cElkLCB0aGlzLl93aXRoUHJlc2V0KHRoaXMuX3ZhbHVlcy5nZXQoZ3JvdXBJZCksIHZhbHVlKSk7XG4gICAgICB0aGlzLl9jbGVhcmVkLmRlbGV0ZShncm91cElkKTtcbiAgICB9XG5cbiAgICB0aGlzLl9jaGFuZ2VkJC5uZXh0KGdyb3VwSWQpO1xuICAgIHRoaXMuX3N0YXRlQ2hhbmdlZCQubmV4dCgpO1xuICB9XG5cbiAgLy8gQSByZWxhdGl2ZSBwcmVzZXQgbmFtZSBhcyB0b2RheSdzIHJhbmdlIGluIHRoZSByZXBvcnQncyB6b25lLCBvciBudWxsIGZvclxuICAvLyBhIG5hbWUgaXQgZG9lcyBub3Qga25vdy4gQSB2aWV3J3Mgcm9sbGluZyByYW5nZSBpcyBvcGVuZWQgdGhyb3VnaCB0aGlzLlxuICBwdWJsaWMgcmVzb2x2ZVJlbGF0aXZlKG5hbWU6IHN0cmluZyk6IHsgc3RhcnQ6IERhdGU7IGVuZDogRGF0ZSB9IHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuX3JlbGF0aXZlUmFuZ2UobmFtZSk7XG4gIH1cblxuICAvLyBUaGUgYWN0aXZlIGdyb3VwLWJ5IGdyYWluLCBvciBudWxsIHdoZW4gdGhlIHZpZXdlciBoYXNuJ3QgY2hvc2VuIG9uZS5cbiAgcHVibGljIGZyZXF1ZW5jeSgpOiBDaGFydEdyYW51bGFyaXR5IHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuX2ZyZXF1ZW5jeTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRGcmVxdWVuY3koZnJlcXVlbmN5OiBDaGFydEdyYW51bGFyaXR5IHwgbnVsbCk6IHZvaWQge1xuICAgIHRoaXMuX2ZyZXF1ZW5jeSA9IGZyZXF1ZW5jeTtcbiAgICB0aGlzLl9mcmVxdWVuY3lDaGFuZ2VkJC5uZXh0KCk7XG4gICAgdGhpcy5fc3RhdGVDaGFuZ2VkJC5uZXh0KCk7XG4gIH1cblxuICAvLyBGaXJlcyB3aGVuZXZlciB0aGUgZ3JvdXAtYnkgZ3JhaW4gY2hhbmdlcyDigJQgZXZlcnkgdGltZS1zZXJpZXMgY2hhcnQgbGlzdGVuc1xuICAvLyBzbyBpdCByZWZldGNoZXMgYW5kIHJlLWJ1Y2tldHMgKHRoZSBvdmVycmlkZSBpc24ndCBzY29wZWQgdG8gYW55IGZpbHRlclxuICAvLyBncm91cCwgc28gY2hhbmdlc0ZvcigpIGNhbid0IGNhcnJ5IGl0KS5cbiAgcHVibGljIGZyZXF1ZW5jeUNoYW5nZXMoKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuX2ZyZXF1ZW5jeUNoYW5nZWQkLmFzT2JzZXJ2YWJsZSgpO1xuICB9XG5cbiAgLy8gVGhlIHNvcnQgdGhlIHZpZXdlciBsYXN0IGZldGNoZWQgYSBsaXN0IHdpdGgsIG9yIG51bGwgd2hlbiBpdCBoYXNuJ3Qgc29ydGVkXG4gIC8vICh0aGUgbGlzdCB0aGVuIGZhbGxzIGJhY2sgdG8gaXRzIGF1dGhvcmVkIHNvcnQpLlxuICBwdWJsaWMgbGlzdFNvcnQoY29tcG9uZW50SWQ6IG51bWJlcik6IFJlcG9ydFNvcnQgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5fbGlzdFNvcnRzLmdldChjb21wb25lbnRJZCkgPz8gbnVsbDtcbiAgfVxuXG4gIC8vIFJlY29yZHMgYSBsaXN0J3Mgc29ydCB3aGVuIGl0IGlzIHRoZSB2aWV3ZXIncyBvd246IGEgc29ydCB0aGF0IGlzIHRoZVxuICAvLyBsaXN0J3MgYXV0aG9yZWQgZmlyc3QgdGVybSBpcyB0aGUgbGlzdCdzIGRlZmF1bHQsIG5vdCBhIGNob2ljZSwgc28gaXRcbiAgLy8gY2xlYXJzIHRoZSBlbnRyeSBpbnN0ZWFkICh0aGUgcnVsZSBzbmFwc2hvdCgpIGFwcGxpZXMpLiBPdGhlcndpc2UgYVxuICAvLyBsaXN0J3MgZmlyc3QgZmV0Y2ggd291bGQgcmVjb3JkIGl0cyBzZWVkZWQgYXV0aG9yZWQgdGVybSwgYW5kIGEgbGlzdCB0aGVcbiAgLy8gYWdlbnQgcmUtc29ydHMgbGF0ZXIgaW4gdGhlIHNlc3Npb24gd291bGQga2VlcCBzZW5kaW5nIHRoZSBvbGQgdGVybVxuICAvLyBmaXJzdC4gRGVsaWJlcmF0ZWx5IGVtaXRzIG5vIGNoYW5nZTogdGhlIGxpc3Qgc2V0cyB0aGlzIGZyb20gdGhlIGZldGNoXG4gIC8vIHRoYXQgYWxyZWFkeSByYW4gd2l0aCB0aGF0IHNvcnQsIHNvIGEgbm90aWZpY2F0aW9uIHdvdWxkIG9ubHkgbWFrZSBpdFxuICAvLyByZWZldGNoIHRoZSBzYW1lIHJvd3MuIE9ubHkgY2hhbmdlcygpIGhlYXJzIGFib3V0IGl0LlxuICBwdWJsaWMgc2V0TGlzdFNvcnQoY29tcG9uZW50OiBSZXBvcnRDb21wb25lbnQsIHNvcnQ6IFJlcG9ydFNvcnQgfCBudWxsKTogdm9pZCB7XG4gICAgaWYgKHNvcnQgJiYgIXNhbWVTb3J0KHNvcnQsIGxpc3RTb3J0VGVybXMoY29tcG9uZW50LmNvbmZpZylbMF0gPz8gbnVsbCkpIHtcbiAgICAgIHRoaXMuX2xpc3RTb3J0cy5zZXQoY29tcG9uZW50LmlkLCBzb3J0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fbGlzdFNvcnRzLmRlbGV0ZShjb21wb25lbnQuaWQpO1xuICAgIH1cblxuICAgIHRoaXMuX3N0YXRlQ2hhbmdlZCQubmV4dCgpO1xuICB9XG5cbiAgLy8gVGhlIHRleHQgYSBsaXN0IGlzIHNlYXJjaGVkIGJ5LCBvciBudWxsIHdoZW4gaXRzIHNlYXJjaCBib3ggaXMgZW1wdHkuXG4gIHB1YmxpYyBsaXN0U2VhcmNoKGNvbXBvbmVudElkOiBudW1iZXIpOiBzdHJpbmcgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5fbGlzdFNlYXJjaGVzLmdldChjb21wb25lbnRJZCkgPz8gbnVsbDtcbiAgfVxuXG4gIC8vIFdoZXRoZXIgYSBsaXN0IHNob3dzIHRoZSBzZWFyY2ggYm94IG92ZXIgaXRzIHRleHQgY29sdW1uczogaXQgZG9lcyB3aGVuIHRoZVxuICAvLyBzZXJ2ZXIgYW5zd2VycyBhIGxpc3Qgc2VhcmNoIChzZWUgX3NlcnZlclNlYXJjaGVzKSwgdW5sZXNzIG9uZSBvZiBpdHMgbGl2ZVxuICAvLyBmaWx0ZXJzIGJlbG9uZ3MgdG8gYSBrZXl3b3JkIGdyb3VwIGl0cyBoZWFkZXIgc2hvd3MuIEEgYmFyIHNob3dzIG9uZSBzZWFyY2hcbiAgLy8gYm94IChpdHMgbGFzdCBrZXl3b3JkIGl0ZW0pLCBhbmQgdGhhdCBvbmUgaXMgdGhlIGF1dGhvcidzLiBUaGUgaGVhZGVyLCBhblxuICAvLyBvcGVuZWQgdmlldywgdGhlIHBydW5pbmcsIHRoZSBkYXRhIHJlcXVlc3Qgc3RhdGUgYW5kIHRoZSBleHBvcnRzIGFsbCByZWFkXG4gIC8vIHRoaXMgb25lIHJ1bGUsIHNvIG5vIHNlYXJjaCBuYXJyb3dzIGEgbGlzdCB3aG9zZSBzY3JlZW4gaGFzIG5vIGJveCBzaG93aW5nXG4gIC8vIGl0LCBhbmQgbm8gZXhwb3J0IHRpdGxlcyBhIHNlYXJjaCB0aGUgc2VydmVyIGRpZCBub3QgYXBwbHkuXG4gIHB1YmxpYyBsaXN0U2VhcmNoYWJsZShjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9zZXJ2ZXJTZWFyY2hlc1xuICAgICAgJiYgY29tcG9uZW50LnR5cGUgPT09ICdsaXN0J1xuICAgICAgJiYgIShjb21wb25lbnQuZmlsdGVycyA/PyBbXSkuc29tZSgoZmlsdGVyKSA9PiB7XG4gICAgICAgIGNvbnN0IGdyb3VwID0gdGhpcy5fZ3JvdXBzLmdldChmaWx0ZXIuZmlsdGVyR3JvdXBJZCk7XG5cbiAgICAgICAgcmV0dXJuIGZpbHRlci5lbmFibGVkXG4gICAgICAgICAgJiYgIXRoaXMuX3Nlc3Npb25EaXNhYmxlZC5oYXMoZmlsdGVyLmlkKVxuICAgICAgICAgICYmIGdyb3VwPy50eXBlID09PSAna2V5d29yZCdcbiAgICAgICAgICAmJiAoZ3JvdXAubGV2ZWwgPT09ICdjb21wb25lbnQnIHx8IGdyb3VwLmxldmVsID09PSAnYm90aCcpO1xuICAgICAgfSk7XG4gIH1cblxuICAvLyBSZWNvcmRzIGEgbGlzdCdzIHNlYXJjaCBib3ggdGV4dCAobGlzdFNlYXJjaFRleHQpOyBhbiBlbXB0eSBib3ggY2xlYXJzXG4gIC8vIGl0LiBUaGUgaGVhZGVyIGNhbGxzIHRoaXMgb24gZXZlcnkgY2hhbmdlIG9mIGFueSBvZiBpdHMgaXRlbXMsIHNvIHRoZVxuICAvLyBsaXN0IGFuZCBjaGFuZ2VzKCkgaGVhciBhYm91dCBpdCBvbmx5IHdoZW4gdGhlIHN0b3JlZCB0ZXh0IGFjdHVhbGx5IGNoYW5nZWQuXG4gIHB1YmxpYyBzZXRMaXN0U2VhcmNoKGNvbXBvbmVudElkOiBudW1iZXIsIHRleHQ6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IHNlYXJjaCA9IGxpc3RTZWFyY2hUZXh0KHRleHQpO1xuXG4gICAgaWYgKHNlYXJjaCA9PT0gKHRoaXMuX2xpc3RTZWFyY2hlcy5nZXQoY29tcG9uZW50SWQpID8/ICcnKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChzZWFyY2gpIHtcbiAgICAgIHRoaXMuX2xpc3RTZWFyY2hlcy5zZXQoY29tcG9uZW50SWQsIHNlYXJjaCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2xpc3RTZWFyY2hlcy5kZWxldGUoY29tcG9uZW50SWQpO1xuICAgIH1cblxuICAgIHRoaXMuX2xpc3RTZWFyY2hDaGFuZ2VkJC5uZXh0KGNvbXBvbmVudElkKTtcbiAgICB0aGlzLl9zdGF0ZUNoYW5nZWQkLm5leHQoKTtcbiAgfVxuXG4gIC8vIFRoZSBjb25maWcgY29sdW1uIG5hbWVzIGEgdmlld2VyIGhpZCBvbiBhIGxpc3Q7IG5vbmUgd2hlbiBpdCBzaG93cyB0aGVtIGFsbC5cbiAgcHVibGljIGhpZGRlbkNvbHVtbnMoY29tcG9uZW50SWQ6IG51bWJlcik6IHJlYWRvbmx5IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5saXN0SGlkZGVuKCkuZ2V0KGNvbXBvbmVudElkKSA/PyBbXTtcbiAgfVxuXG4gIC8vIFJlY29yZHMgdGhlIGNvbHVtbnMgYSB2aWV3ZXIgaGlkIG9uIGEgbGlzdCwga2VwdCB0byBsaXN0SGlkZGVuQ29sdW1uczpcbiAgLy8gbmFtZXMgdGhlIGxpc3QgY2Fubm90IGhpZGUgYXJlIGRyb3BwZWQsIGFuZCBub25lIChvciBldmVyeSBjb2x1bW4pIGNsZWFyc1xuICAvLyB0aGUgZW50cnkuIE9ubHkgY2hhbmdlcygpIGhlYXJzIGFib3V0IGl0LCBhbmQgb25seSBvbiBhIHJlYWwgY2hhbmdlLlxuICBwdWJsaWMgc2V0SGlkZGVuQ29sdW1ucyhjb21wb25lbnRJZDogbnVtYmVyLCBuYW1lczogcmVhZG9ubHkgc3RyaW5nW10pOiB2b2lkIHtcbiAgICBjb25zdCBoaWRkZW4gPSBsaXN0SGlkZGVuQ29sdW1ucyh0aGlzLl9saXN0cy5nZXQoY29tcG9uZW50SWQpPy5jb25maWcsIG5hbWVzKTtcblxuICAgIGlmIChzYW1lTmFtZXMoaGlkZGVuLCB0aGlzLmhpZGRlbkNvbHVtbnMoY29tcG9uZW50SWQpKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IG5leHQgPSBuZXcgTWFwKHRoaXMubGlzdEhpZGRlbigpKTtcblxuICAgIGlmIChoaWRkZW4ubGVuZ3RoKSB7XG4gICAgICBuZXh0LnNldChjb21wb25lbnRJZCwgaGlkZGVuKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmV4dC5kZWxldGUoY29tcG9uZW50SWQpO1xuICAgIH1cblxuICAgIHRoaXMubGlzdEhpZGRlbi5zZXQobmV4dCk7XG4gICAgdGhpcy5fc3RhdGVDaGFuZ2VkJC5uZXh0KCk7XG4gIH1cblxuICAvLyBGaXJlcyB3aGVuZXZlciBvbmUgbGlzdCdzIHNlYXJjaCB0ZXh0IGNoYW5nZXMsIHNvIHRoYXQgbGlzdCByZWZldGNoZXMuXG4gIHB1YmxpYyBsaXN0U2VhcmNoQ2hhbmdlcyhjb21wb25lbnRJZDogbnVtYmVyKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuX2xpc3RTZWFyY2hDaGFuZ2VkJC5hc09ic2VydmFibGUoKVxuICAgICAgLnBpcGUoXG4gICAgICAgIHJ4RmlsdGVyKChpZCkgPT4gaWQgPT09IGNvbXBvbmVudElkKSxcbiAgICAgICAgbWFwKCgpID0+IHVuZGVmaW5lZCksXG4gICAgICApO1xuICB9XG5cbiAgLy8gRmlyZXMgd2hlbmV2ZXIgdGhlIHZpZXdlciBzdGF0ZSBtYXkgaGF2ZSBjaGFuZ2VkOiBhIGdyb3VwIHZhbHVlLCB0aGVcbiAgLy8gZ3JhaW4sIHRoZSBtYXRjaCwgdGhlIHBhZ2UsIGEgbGlzdCBzb3J0LCBzZWFyY2ggb3IgaGlkZGVuIGNvbHVtbnMsIGFcbiAgLy8gZHJpbGwgcGF0aCwgYW4gYXBwbGllZCB2aWV3IG9yIGEgKHJlKWxvYWQgb2YgdGhlIHJlcG9ydC5cbiAgcHVibGljIGNoYW5nZXMoKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRlQ2hhbmdlZCQuYXNPYnNlcnZhYmxlKCk7XG4gIH1cblxuICBwdWJsaWMgaXNGaWx0ZXJEaXNhYmxlZChmaWx0ZXJJZDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX3Nlc3Npb25EaXNhYmxlZC5oYXMoZmlsdGVySWQpO1xuICB9XG5cbiAgcHVibGljIHRvZ2dsZUZpbHRlcihmaWx0ZXJJZDogbnVtYmVyLCBncm91cElkOiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fc2Vzc2lvbkRpc2FibGVkLmhhcyhmaWx0ZXJJZCkpIHtcbiAgICAgIHRoaXMuX3Nlc3Npb25EaXNhYmxlZC5kZWxldGUoZmlsdGVySWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9zZXNzaW9uRGlzYWJsZWQuYWRkKGZpbHRlcklkKTtcbiAgICB9XG5cbiAgICAvLyBUdXJuaW5nIGEga2V5d29yZCBmaWx0ZXIgYmFjayBvbiB0YWtlcyBpdHMgbGlzdCdzIHNlYXJjaCBib3ggYXdheSwgYW5kXG4gICAgLy8gdGhlIHNlYXJjaCB3aXRoIGl0LiBUaGUgbGlzdCByZWZldGNoZXMgb24gdGhlIGdyb3VwIGNoYW5nZSBiZWxvdy5cbiAgICB0aGlzLl9kcm9wVW5zZWFyY2hhYmxlKCk7XG5cbiAgICB0aGlzLl9jaGFuZ2VkJC5uZXh0KGdyb3VwSWQpO1xuICAgIHRoaXMuX3N0YXRlQ2hhbmdlZCQubmV4dCgpO1xuICB9XG5cbiAgLy8gTm90aWZpY2F0aW9ucyByZWxldmFudCB0byBPTkUgY29tcG9uZW50OiBhbnkgY2hhbmdlIHRvIGEgZ3JvdXAgb25lIG9mIGl0c1xuICAvLyBmaWx0ZXJzIGJlbG9uZ3MgdG8gKG9yIGEgZnVsbCByZS1pbml0KS5cbiAgcHVibGljIGNoYW5nZXNGb3IoY29tcG9uZW50OiBSZXBvcnRDb21wb25lbnQpOiBPYnNlcnZhYmxlPG51bWJlciB8IG51bGw+IHtcbiAgICBjb25zdCBncm91cElkcyA9IG5ldyBTZXQoKGNvbXBvbmVudC5maWx0ZXJzID8/IFtdKS5tYXAoKGZpbHRlcikgPT4gZmlsdGVyLmZpbHRlckdyb3VwSWQpKTtcblxuICAgIHJldHVybiB0aGlzLl9jaGFuZ2VkJC5hc09ic2VydmFibGUoKVxuICAgICAgLnBpcGUoXG4gICAgICAgIHJ4RmlsdGVyKChncm91cElkKSA9PiBncm91cElkID09PSBudWxsIHx8IGdyb3VwSWRzLmhhcyhncm91cElkKSksXG4gICAgICApO1xuICB9XG5cbiAgLy8gTm90aWZpY2F0aW9ucyByZWxldmFudCB0byBBTlkgb2YgYSBzZXQgb2YgY29tcG9uZW50cyB0aGF0IGNvbWVzIGFuZCBnb2VzXG4gIC8vIChhIHBhZ2UncyB2YWx1ZXMpOiBhIGNoYW5nZSB0byBhIGdyb3VwIG9uZSBvZiB0aGVpciBmaWx0ZXJzIGJlbG9uZ3MgdG8uXG4gIC8vIFVubGlrZSBjaGFuZ2VzRm9yLCB0aGUgc2V0IGlzIHJlYWQgb24gZWFjaCBldmVudCByYXRoZXIgdGhhbiBjYXB0dXJlZCBhdFxuICAvLyBzdWJzY3JpYmUsIHNvIG9uZSBzdWJzY3JpcHRpb24gZm9sbG93cyB0aGUgc2V0IGFzIHRoZSByZXBvcnQgcmVsb2Fkcy4gQVxuICAvLyBmdWxsIHJlLWluaXQgKG51bGwpIGlzIG5vdCBwYXNzZWQgb246IGluaXQoKSBydW5zIG9uIGEgcmVwb3J0XG4gIC8vIChyZSlsb2FkLCBhbmQgYSBjYWxsZXIgb2YgdGhpcyBjaGVja3Mgb24gdGhhdCByZWxvYWQgaXRzZWxmIHdoZXRoZXIgdGhlXG4gIC8vIGZpbHRlciB2YWx1ZXMgaXRzIGNvbXBvbmVudHMgYXJlIHJlYWQgd2l0aCBtb3ZlZC5cbiAgcHVibGljIGNoYW5nZXNGb3JBbnkoY29tcG9uZW50czogKCkgPT4gUmVwb3J0Q29tcG9uZW50W10pOiBPYnNlcnZhYmxlPG51bWJlcj4ge1xuICAgIHJldHVybiB0aGlzLl9jaGFuZ2VkJC5hc09ic2VydmFibGUoKVxuICAgICAgLnBpcGUoXG4gICAgICAgIHJ4RmlsdGVyKChncm91cElkKTogZ3JvdXBJZCBpcyBudW1iZXIgPT4gZ3JvdXBJZCAhPT0gbnVsbFxuICAgICAgICAgICYmIGNvbXBvbmVudHMoKS5zb21lKChjb21wb25lbnQpID0+IChjb21wb25lbnQuZmlsdGVycyA/PyBbXSlcbiAgICAgICAgICAgIC5zb21lKChmaWx0ZXIpID0+IGZpbHRlci5maWx0ZXJHcm91cElkID09PSBncm91cElkKSkpLFxuICAgICAgKTtcbiAgfVxuXG4gIC8vIFRoZSBncm91cCB2YWx1ZXMgcmVzb2x2ZWQgaW50byB0aGlzIGNvbXBvbmVudCdzIG1lbWJlci1maWx0ZXIgdmFsdWVzIOKAlFxuICAvLyB3aGF0IHRoZSBkYXRhIHJlcXVlc3QgY2Fycmllcy4gRGlzYWJsZWQgZmlsdGVycyAoYXV0aG9yZWQgb3Igc2Vzc2lvbikgYXJlXG4gIC8vIHNraXBwZWQgZW50aXJlbHkuXG4gIHB1YmxpYyByZXNvbHZlRm9yQ29tcG9uZW50KGNvbXBvbmVudDogUmVwb3J0Q29tcG9uZW50KTogUmVzb2x2ZWRGaWx0ZXJWYWx1ZVtdIHtcbiAgICBjb25zdCByZXNvbHZlZDogUmVzb2x2ZWRGaWx0ZXJWYWx1ZVtdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IGZpbHRlciBvZiBjb21wb25lbnQuZmlsdGVycyA/PyBbXSkge1xuICAgICAgaWYgKCFmaWx0ZXIuZW5hYmxlZCB8fCB0aGlzLl9zZXNzaW9uRGlzYWJsZWQuaGFzKGZpbHRlci5pZCkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5fdmFsdWVzLmdldChmaWx0ZXIuZmlsdGVyR3JvdXBJZCk7XG4gICAgICBjb25zdCBmaWVsZHMgPSB2YWx1ZSA/IHRoaXMuX3Jlc29sdmVkRmllbGRzKHZhbHVlKSA6IG51bGw7XG5cbiAgICAgIGlmIChmaWVsZHMpIHtcbiAgICAgICAgcmVzb2x2ZWQucHVzaCh7IGZpbHRlcklkOiBmaWx0ZXIuaWQsIC4uLmZpZWxkcyB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzb2x2ZWQ7XG4gIH1cblxuICAvLyBXaGF0IHRoZSB2aWV3ZXIgaGFzIHNldCwgb25lIGVudHJ5IHBlciBmaWx0ZXIgZ3JvdXAsIGZvciB0aGUgcmVwb3J0IGNoYXQ6XG4gIC8vIHRoZSBhZ2VudCByZWFkcyBpdCB0byBrbm93IHdoYXQgaXMgb24gc2NyZWVuLiBHcm91cCBvcmRlciwgbm90IHRoZSBvcmRlclxuICAvLyB0aGUgdmFsdWVzIHdlcmUgc2V0IGluLCBzbyB0aGUgc2FtZSBzdGF0ZSBhbHdheXMgcmVhZHMgdGhlIHNhbWUuIEEgZ3JvdXBcbiAgLy8gd2l0aCBub3RoaW5nIGluIGl0IGlzIGxlZnQgb3V0LCBhbmQgYSBzYXZlZCBkZWZhdWx0IGNvdW50cyB1bnRpbCB0aGVcbiAgLy8gdmlld2VyIGNoYW5nZXMgaXQuIFBlci1maWx0ZXIgdG9nZ2xlcyBhcmUgYSBjb21wb25lbnQncyBvd24gYnVzaW5lc3MsIHNvXG4gIC8vIHRoZXkgYXJlIG5vdCBwYXJ0IG9mIGl0LlxuICBwdWJsaWMgdmlld2VyRmlsdGVycygpOiBSZXBvcnRDaGF0Vmlld2VyRmlsdGVyW10ge1xuICAgIHJldHVybiBbLi4udGhpcy5fdmFsdWVzLmVudHJpZXMoKV1cbiAgICAgIC5zb3J0KChbYV0sIFtiXSkgPT4gYSAtIGIpXG4gICAgICAubWFwKChbZ3JvdXBJZCwgdmFsdWVdKSA9PiB7XG4gICAgICAgIGNvbnN0IGZpZWxkcyA9IHRoaXMuX3Jlc29sdmVkRmllbGRzKHZhbHVlKTtcblxuICAgICAgICByZXR1cm4gZmllbGRzID8geyBncm91cElkLCAuLi5maWVsZHMgfSA6IG51bGw7XG4gICAgICB9KVxuICAgICAgLmZpbHRlcigoZW50cnkpOiBlbnRyeSBpcyBSZXBvcnRDaGF0Vmlld2VyRmlsdGVyID0+IGVudHJ5ICE9PSBudWxsKTtcbiAgfVxuXG4gIC8vIEV2ZXJ5IHRpbGUncyByZXNvbHZlZCB2YWx1ZXMgaW4gb25lIGFycmF5IOKAlCB3aGF0IGEgcmVwb3J0LWxldmVsIGV4cG9ydFxuICAvLyBjYXJyaWVzIHNvIGVhY2ggZmlsZSBpbiB0aGUgYXJjaGl2ZSBpcyBmaWx0ZXJlZCBleGFjdGx5IGFzIHRoZSBzY3JlZW4gaXMuXG4gIC8vIEZpbHRlciBpZHMgYXJlIHVuaXF1ZSBwZXIgY29tcG9uZW50LCBzbyB0aGUgYmFja2VuZCBwaWNrcyBlYWNoIGNvbXBvbmVudCdzXG4gIC8vIG93biBvdXQgb2YgdGhlIHBpbGUuIE9ubHkgYSB0aWxlIGJlY29tZXMgYSBmaWxlIChpc1RpbGUpLCBzbyBubyBvdGhlclxuICAvLyBjb21wb25lbnQncyBlbnRyaWVzIHJpZGUgYWxvbmcuIEEgcGFnZSBpZCBuYXJyb3dzIGl0IHRvIHRoYXQgcGFnZS5cbiAgcHVibGljIHJlc29sdmVGb3JSZXBvcnQocmVwb3J0OiBSZXBvcnQsIHBhZ2VJZDogbnVtYmVyIHwgbnVsbCA9IG51bGwpOiBSZXNvbHZlZEZpbHRlclZhbHVlW10ge1xuICAgIGNvbnN0IHBhZ2VzID0gKHJlcG9ydC5wYWdlcyA/PyBbXSlcbiAgICAgIC5maWx0ZXIoKHBhZ2UpID0+ICFwYWdlSWQgfHwgcGFnZS5pZCA9PT0gcGFnZUlkKTtcblxuICAgIHJldHVybiBwYWdlc1xuICAgICAgLmZsYXRNYXAoKHBhZ2UpID0+IChwYWdlLmNvbXBvbmVudHMgPz8gW10pXG4gICAgICAgIC5maWx0ZXIoKGNvbXBvbmVudCkgPT4gaXNUaWxlKGNvbXBvbmVudCkpXG4gICAgICAgIC5mbGF0TWFwKChjb21wb25lbnQpID0+IHRoaXMucmVzb2x2ZUZvckNvbXBvbmVudChjb21wb25lbnQpKSk7XG4gIH1cblxuICBwdWJsaWMgc2V0UGFnZShwYWdlSWQ6IG51bWJlciB8IG51bGwpOiB2b2lkIHtcbiAgICBpZiAocGFnZUlkID09PSB0aGlzLl9wYWdlSWQoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX3BhZ2VJZC5zZXQocGFnZUlkKTtcbiAgICB0aGlzLl9zdGF0ZUNoYW5nZWQkLm5leHQoKTtcbiAgfVxuXG4gIC8vIEEgY2hhbmdlIG9mIG1hdGNoIGNhbiBjaGFuZ2UgZXZlcnkgdGlsZSBhIGdyb3VwIHdpdGggYSB2YWx1ZSBuYXJyb3dzLCBzb1xuICAvLyBldmVyeSB0aWxlIGhlYXJzIGFib3V0IGl0LlxuICBwdWJsaWMgc2V0TWF0Y2gobWF0Y2g6IFJlcG9ydEZpbHRlck1hdGNoKTogdm9pZCB7XG4gICAgY29uc3QgbmV4dDogUmVwb3J0RmlsdGVyTWF0Y2ggPSBtYXRjaCA9PT0gJ2FueScgPyAnYW55JyA6ICdhbGwnO1xuICAgIGlmIChuZXh0ID09PSB0aGlzLl9tYXRjaCgpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fbWF0Y2guc2V0KG5leHQpO1xuICAgIHRoaXMuX2NoYW5nZWQkLm5leHQobnVsbCk7XG4gICAgdGhpcy5fc3RhdGVDaGFuZ2VkJC5uZXh0KCk7XG4gIH1cblxuICAvLyBBIGNoYXJ0J3MgZHJpbGwgcGF0aCwgdG9wIGZpcnN0OyBlbXB0eSB3aGlsZSB0aGUgY2hhcnQgaXMgYXQgaXRzIHRvcC5cbiAgLy8gSXQgcmVhZHMgYSBzaWduYWwsIHNvIGEgdGVtcGxhdGUgdGhhdCBzaG93cyBpdCByZXBhaW50cyB3aGVuIGl0IG1vdmVzLlxuICBwdWJsaWMgZHJpbGwoY29tcG9uZW50SWQ6IG51bWJlcik6IHJlYWRvbmx5IFJlcG9ydERyaWxsU3RlcFtdIHtcbiAgICByZXR1cm4gdGhpcy5fZHJpbGxzKCkuZ2V0KGNvbXBvbmVudElkKSA/PyBbXTtcbiAgfVxuXG4gIC8vIFJlY29yZHMgYSBjaGFydCdzIGRyaWxsIHBhdGgsIGtlcHQgdG8gY2xlYW5EcmlsbFBhdGg7IGFuIGVtcHR5IHBhdGggaXNcbiAgLy8gdGhlIGNoYXJ0J3MgdG9wLiBPbmx5IGEgY2hhcnQgb2YgdGhlIG9wZW4gcmVwb3J0IGRyaWxsczogYSBwYXRoIGZvciBhbnlcbiAgLy8gb3RoZXIgY29tcG9uZW50IGlzIGlnbm9yZWQuIE9ubHkgdGhhdCBjaGFydCBhbmQgY2hhbmdlcygpIGhlYXIgYWJvdXQgaXQsXG4gIC8vIGFuZCBvbmx5IG9uIGEgcmVhbCBjaGFuZ2UuXG4gIHB1YmxpYyBzZXREcmlsbChjb21wb25lbnRJZDogbnVtYmVyLCBwYXRoOiByZWFkb25seSBSZXBvcnREcmlsbFN0ZXBbXSk6IHZvaWQge1xuICAgIGNvbnN0IGtlcHQgPSBjbGVhbkRyaWxsUGF0aChwYXRoKTtcbiAgICBpZiAoIXRoaXMuX2lzQ2hhcnQoY29tcG9uZW50SWQpIHx8IHNhbWVEcmlsbFBhdGgoa2VwdCwgdGhpcy5kcmlsbChjb21wb25lbnRJZCkpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fc2V0RHJpbGxQYXRoKGNvbXBvbmVudElkLCBrZXB0KTtcbiAgICB0aGlzLl9kcmlsbENoYW5nZWQkLm5leHQoY29tcG9uZW50SWQpO1xuICAgIHRoaXMuX3N0YXRlQ2hhbmdlZCQubmV4dCgpO1xuICB9XG5cbiAgLy8gRmlyZXMgd2hlbmV2ZXIgb25lIGNoYXJ0J3MgZHJpbGwgcGF0aCBjaGFuZ2VzLCBzbyB0aGF0IGNoYXJ0IHJlZmV0Y2hlcy5cbiAgcHVibGljIGRyaWxsQ2hhbmdlcyhjb21wb25lbnRJZDogbnVtYmVyKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuX2RyaWxsQ2hhbmdlZCQuYXNPYnNlcnZhYmxlKClcbiAgICAgIC5waXBlKFxuICAgICAgICByeEZpbHRlcigoaWQpID0+IGlkID09PSBjb21wb25lbnRJZCksXG4gICAgICAgIG1hcCgoKSA9PiB1bmRlZmluZWQpLFxuICAgICAgKTtcbiAgfVxuXG4gIC8vIFRha2VzIHRoZSBkcmlsbCBwYXRoIGEgY2hhcnQncyBhbnN3ZXIgYXBwbGllZCBhcyB0aGUgY2hhcnQncyBvd246IHRoZVxuICAvLyBzZXJ2ZXIga2VlcHMgdGhlIGxvbmdlc3QgcGFydCBvZiBhIHNlbnQgcGF0aCBpdCBjYW4gYXBwbHksIHNvIGEgbGF0ZXJcbiAgLy8gc2F2ZSBob2xkcyB0aGF0IHBhcnQgb25seS4gVGhlIGNoYXJ0IGhhcyBqdXN0IHJlYWQgdGhhdCBwYXRoLCBzbyBvbmx5XG4gIC8vIGNoYW5nZXMoKSBoZWFycyBhYm91dCBpdC4gVHJ1ZSB3aGVuIHRoZSBwYXRoIGNoYW5nZWQuXG4gIHB1YmxpYyBhZG9wdERyaWxsKGNvbXBvbmVudElkOiBudW1iZXIsIHBhdGg6IHJlYWRvbmx5IFJlcG9ydERyaWxsU3RlcFtdKTogYm9vbGVhbiB7XG4gICAgY29uc3Qga2VwdCA9IGNsZWFuRHJpbGxQYXRoKHBhdGgpO1xuICAgIGlmICghdGhpcy5faXNDaGFydChjb21wb25lbnRJZCkgfHwgc2FtZURyaWxsUGF0aChrZXB0LCB0aGlzLmRyaWxsKGNvbXBvbmVudElkKSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICB0aGlzLl9zZXREcmlsbFBhdGgoY29tcG9uZW50SWQsIGtlcHQpO1xuICAgIHRoaXMuX3N0YXRlQ2hhbmdlZCQubmV4dCgpO1xuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvLyBUaGUgZHVyYWJsZSBzdGF0ZSBvbiBzY3JlZW4gYXMgb25lIHZpZXcgZG9jdW1lbnQ6IHRoZSBwYWdlLCBldmVyeSBncm91cFxuICAvLyB0aGUgcmVwb3J0IGhhcyAobnVsbCB3aGVuIGl0IGhvbGRzIG5vdGhpbmcsIGEgY2xlYXJlZCBkZWZhdWx0IGluY2x1ZGVkKSxcbiAgLy8gdGhlIG1hdGNoLCB0aGUgZ3JhaW4sIGFuZCBlYWNoIHRpbGUncyBzb3J0LCBzZWFyY2gsIGhpZGRlbiBjb2x1bW5zIGFuZFxuICAvLyBkcmlsbCBwYXRoIHdoZXJlIHRoZXkgZGlmZmVyIGZyb20gdGhlIGF1dGhvcmVkIHRpbGUuIEEgZGF0ZSByYW5nZSB0aGF0XG4gIC8vIHN0aWxsIGNhcnJpZXMgaXRzIHJlbGF0aXZlIHByZXNldCBpcyB3cml0dGVuIGFzIHRoYXQgcHJlc2V0LCB3aGF0ZXZlclxuICAvLyB0b2RheSBpcyAodG9TdG9yZWRHcm91cFZhbHVlKS4gVGhlIHRlbXBvcmFyeSBsYXllciBpcyBuZXZlciBwYXJ0IG9mIGl0LlxuICBwdWJsaWMgc25hcHNob3QoKTogUmVwb3J0Vmlld0NvbmZpZyB7XG4gICAgY29uc3QgY29uZmlnOiBSZXBvcnRWaWV3Q29uZmlnID0geyB2OiBSRVBPUlRfVklFV19DT05GSUdfVkVSU0lPTiB9O1xuXG4gICAgaWYgKHRoaXMuX3BhZ2VJZCgpKSB7XG4gICAgICBjb25maWcucGFnZUlkID0gdGhpcy5fcGFnZUlkKCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2ZyZXF1ZW5jeSkge1xuICAgICAgY29uZmlnLmdyb3VwQnkgPSB0aGlzLl9mcmVxdWVuY3k7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX21hdGNoKCkgPT09ICdhbnknKSB7XG4gICAgICBjb25maWcubWF0Y2ggPSAnYW55JztcbiAgICB9XG5cbiAgICBjb25maWcuZ3JvdXBzID0gdGhpcy5fc25hcHNob3RHcm91cHMoKTtcblxuICAgIGNvbnN0IHRpbGVzID0gdGhpcy5fc25hcHNob3RUaWxlcygpO1xuICAgIGlmIChPYmplY3Qua2V5cyh0aWxlcykubGVuZ3RoKSB7XG4gICAgICBjb25maWcudGlsZXMgPSB0aWxlcztcbiAgICB9XG5cbiAgICByZXR1cm4gY29uZmlnO1xuICB9XG5cbiAgLy8gVGhlIHJlcG9ydCdzIGF1dGhvcmVkIGRlZmF1bHRzIGFzIGEgdmlldyBkb2N1bWVudDogZXZlcnkgZ3JvdXAgYXQgaXRzXG4gIC8vIGF1dGhvcmVkIGRlZmF1bHQgKG51bGwgd2hlbiBpdCBoYXMgbm9uZSksIG5vIG1hdGNoLCBncmFpbiBvciB0aWxlIHN0YXRlLlxuICBwdWJsaWMgYXV0aG9yZWRDb25maWcoKTogUmVwb3J0Vmlld0NvbmZpZyB7XG4gICAgY29uc3QgZ3JvdXBzOiBSZWNvcmQ8bnVtYmVyLCBGaWx0ZXJHcm91cERlZmF1bHQgfCBudWxsPiA9IHt9O1xuXG4gICAgdGhpcy5fZ3JvdXBzLmZvckVhY2goKGdyb3VwKSA9PiB7XG4gICAgICBncm91cHNbZ3JvdXAuaWRdID0gdG9TdG9yZWRHcm91cFZhbHVlKGdyb3VwLnR5cGUsIHRoaXMuX2RlZmF1bHRWYWx1ZShncm91cCkpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHsgdjogUkVQT1JUX1ZJRVdfQ09ORklHX1ZFUlNJT04sIGdyb3VwcyB9O1xuICB9XG5cbiAgLy8gUmVwbGFjZXMgdGhlIGR1cmFibGUgc3RhdGUgd2l0aCBhIHZpZXcncyAoYGNvbmZpZ2A7IG51bGwgPSB0aGUgcmVwb3J0J3NcbiAgLy8gYXV0aG9yZWQgZGVmYXVsdHMpLCB3aGljaCBiZWNvbWVzIHRoZSBiYXNlOiB3aGF0IHRoZSBzY3JlZW4gaXMgY29tcGFyZWRcbiAgLy8gd2l0aCBmb3IgJyhlZGl0ZWQpJyBhbmQgd2hhdCByZXNldFRvQmFzZSgpIHJldHVybnMgdG8uIEEgZ3JvdXAgdGhlIHZpZXdcbiAgLy8gZG9lcyBub3QgaG9sZCBvcGVucyBhdCBpdHMgYXV0aG9yZWQgZGVmYXVsdDsgb25lIHRoZSByZXBvcnQgZG9lcyBub3RcbiAgLy8gaGF2ZSwgb3Igd2hvc2UgdmFsdWUgZG9lcyBub3QgZml0IHRoZSBncm91cCdzIHR5cGUsIGlzIHNraXBwZWQuIFRoZVxuICAvLyB2aWV3J3MgcGFnZSBvcGVucywgdW5sZXNzIGBwYWdlSWRgIG5hbWVzIGEgcGFnZSBvZiB0aGUgcmVwb3J0IChhID9wYWdlPVxuICAvLyB0aGUgcmVwb3J0IG9wZW5lZCB3aXRoIGJlYXRzIGl0cyBkZWZhdWx0IHZpZXcncyBwYWdlKS4gVGhlIHRlbXBvcmFyeVxuICAvLyBsYXllciBpcyBrZXB0LiBFdmVyeSBjaGFuZ2UgaXMgYW5ub3VuY2VkIG9uY2UsIGF0IHRoZSBlbmQuXG4gIHB1YmxpYyBhcHBseShjb25maWc6IFJlcG9ydFZpZXdDb25maWcgfCBudWxsLCBwYWdlSWQ6IG51bWJlciB8IG51bGwgPSBudWxsKTogdm9pZCB7XG4gICAgY29uc3QgZnJlcXVlbmN5ID0gdGhpcy5fZnJlcXVlbmN5O1xuXG4gICAgdGhpcy5fc2V0QmFzZShjb25maWcpO1xuICAgIHRoaXMuX2FwcGx5UGFnZShjb25maWc/LnBhZ2VJZCk7XG4gICAgdGhpcy5fYXBwbHlQYWdlKHBhZ2VJZCk7XG5cbiAgICB0aGlzLl9hcHBsaWVkVmVyc2lvbi51cGRhdGUoKHZlcnNpb24pID0+IHZlcnNpb24gKyAxKTtcbiAgICB0aGlzLl9ub3RpZnlBcHBsaWVkKGZyZXF1ZW5jeSk7XG4gIH1cblxuICAvLyBQdXRzIHRoZSBzY3JlZW4gYmFjayBvbiBpdHMgYmFzZSAodGhlIG9wZW4gdmlldywgZWxzZSB0aGUgYXV0aG9yZWRcbiAgLy8gZGVmYXVsdHMpIG9uIHRoZSBwYWdlIGl0IGlzIG9uLCBhbmQgY2xlYXJzIHRoZSB0ZW1wb3JhcnkgbGF5ZXIuIFRoZVxuICAvLyB0aWxlcyBzdGF5IGFuZCByZWxvYWQgaW4gcGxhY2UgKGFwcGxpZWRWZXJzaW9uIGRvZXMgbm90IG1vdmUpLCBleGNlcHQgYVxuICAvLyBsaXN0IHdob3NlIHNvcnQgdGhpcyBtb3ZlZCAobGlzdFNvcnRSZXNldHMpLlxuICBwdWJsaWMgcmVzZXRUb0Jhc2UoKTogdm9pZCB7XG4gICAgY29uc3QgZnJlcXVlbmN5ID0gdGhpcy5fZnJlcXVlbmN5O1xuICAgIGNvbnN0IHNvcnRzID0gbmV3IE1hcCh0aGlzLl9saXN0U29ydHMpO1xuXG4gICAgdGhpcy5fdGVtcG9yYXJ5LnNldChlbXB0eVRlbXBvcmFyeVN0YXRlKCkpO1xuICAgIHRoaXMuX2FwcGx5TGF5ZXIodGhpcy5fYmFzZUNvbmZpZygpKTtcbiAgICB0aGlzLl9jb3VudFNvcnRSZXNldHMoc29ydHMpO1xuICAgIHRoaXMuX25vdGlmeUFwcGxpZWQoZnJlcXVlbmN5KTtcbiAgfVxuXG4gIC8vIFRoZSBzY3JlZW4gYXMgaXQgaXMgYmVjb21lcyB0aGUgYmFzZSwgd2l0aCBub3RoaW5nIGFwcGxpZWQ6IHdoYXQgYSB2aWV3XG4gIC8vIGp1c3Qgc2F2ZWQgZnJvbSB0aGUgc2NyZWVuIGhvbGRzLiBUaGUgcGFnZSBvbiBzY3JlZW4gaXMgdGhlIGJhc2Uncy5cbiAgcHVibGljIHNldEJhc2VUb1NjcmVlbigpOiB2b2lkIHtcbiAgICB0aGlzLl9iYXNlQ29uZmlnLnNldCh0aGlzLnNuYXBzaG90KCkpO1xuICAgIHRoaXMuX3N0YXRlQ2hhbmdlZCQubmV4dCgpO1xuICB9XG5cbiAgLy8gVGhlIHJlcG9ydCdzIGF1dGhvcmVkIGRlZmF1bHRzIGJlY29tZSB0aGUgYmFzZSBhZ2FpbiAodGhlIG9wZW4gdmlldyB3YXNcbiAgLy8gZGVsZXRlZCk7IHRoZSBzY3JlZW4gc3RheXMgYXMgaXQgaXMuXG4gIHB1YmxpYyBjbGVhckJhc2UoKTogdm9pZCB7XG4gICAgdGhpcy5fYmFzZUNvbmZpZy5zZXQobnVsbCk7XG4gICAgdGhpcy5fc3RhdGVDaGFuZ2VkJC5uZXh0KCk7XG4gIH1cblxuICAvLyBQdXRzIG9ubHkgYGdyb3VwSWRzYCBiYWNrIG9uIHRoZSBiYXNlOiB0aGUgb3BlbiB2aWV3J3MgdmFsdWUgZm9yIGEgZ3JvdXBcbiAgLy8gaXQgaG9sZHMsIGVsc2UgdGhlIGdyb3VwJ3MgYXV0aG9yZWQgZGVmYXVsdC4gQSB0aWxlIGhlYWRlcidzICdDbGVhclxuICAvLyBmaWx0ZXJzJyBvd25zIG9ubHkgaXRzIG93biBncm91cHM7IHRoZSByZXBvcnQgYmFyJ3MgY2FsbHMgcmVzZXRUb0Jhc2UoKS5cbiAgLy8gRWFjaCBncm91cCBpcyBhbm5vdW5jZWQgYXMgYSB2aWV3ZXIncyBjaGFuZ2UgdG8gaXQgaXMsIHNvIHRoZSB0aWxlcyBpblxuICAvLyBpdCByZWZldGNoIGFuZCBhIGJhciBzaG93aW5nIGl0IHdpdGggYW5vdGhlciB2YWx1ZSBpcyBidWlsdCBhZ2Fpbi5cbiAgcHVibGljIHJlc2V0R3JvdXBzVG9CYXNlKGdyb3VwSWRzOiByZWFkb25seSBudW1iZXJbXSk6IHZvaWQge1xuICAgIGNvbnN0IGhlbGQgPSB0aGlzLl9iYXNlQ29uZmlnKCk/Lmdyb3VwcyA/PyB7fTtcblxuICAgIGdyb3VwSWRzLmZvckVhY2goKGdyb3VwSWQpID0+IHtcbiAgICAgIGNvbnN0IGdyb3VwID0gdGhpcy5fZ3JvdXBzLmdldChncm91cElkKTtcbiAgICAgIGlmICghZ3JvdXApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChoZWxkLCBncm91cElkKSB8fCAhdGhpcy5fYXBwbHlHcm91cChncm91cCwgaGVsZFtncm91cElkXSkpIHtcbiAgICAgICAgdGhpcy5fc2VlZEF1dGhvcmVkKGdyb3VwKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fY2hhbmdlZCQubmV4dChncm91cElkKTtcbiAgICB9KTtcblxuICAgIHRoaXMuX3N0YXRlQ2hhbmdlZCQubmV4dCgpO1xuICB9XG5cbiAgLy8gV2hldGhlciBvbmUgb2YgYGdyb3VwSWRzYCBzaG93cyBhIHZhbHVlIG90aGVyIHRoYW4gaXRzIGJhc2U6IHRoZSBvcGVuXG4gIC8vIHZpZXcncyB2YWx1ZSBmb3IgYSBncm91cCBpdCBob2xkcywgZWxzZSB0aGUgZ3JvdXAncyBhdXRob3JlZCBkZWZhdWx0LFxuICAvLyB0aGUgdmFsdWUgcmVzZXRHcm91cHNUb0Jhc2UoKSBwdXRzIGJhY2sgYW5kIHZpZXdDaGFuZ2VkIGNvbXBhcmVzLiBBIHRpbGVcbiAgLy8gaGVhZGVyJ3MgQ2xlYXIgY2hpcCBzaG93cyBleGFjdGx5IHdoaWxlIG9uZSBvZiBpdHMgb3duIGdyb3VwcyBkb2VzLiBJdFxuICAvLyByZWFkcyB0aGUgcmV2aXNpb24gdmlld0NoYW5nZWQgcmVhZHMsIHNvIGEgY2FsbGVyIG9uIGVhY2ggY2hlY2sgb2YgYW5cbiAgLy8gT25QdXNoIHZpZXcgc3RheXMgY3VycmVudC5cbiAgcHVibGljIGdyb3Vwc0RpZmZlckZyb21CYXNlKGdyb3VwSWRzOiByZWFkb25seSBudW1iZXJbXSk6IGJvb2xlYW4ge1xuICAgIHRoaXMuX3JldmlzaW9uKCk7XG4gICAgY29uc3QgaGVsZCA9IHRoaXMuX2Jhc2VDb25maWcoKT8uZ3JvdXBzID8/IHt9O1xuXG4gICAgcmV0dXJuIGdyb3VwSWRzLnNvbWUoKGdyb3VwSWQpID0+IHtcbiAgICAgIGNvbnN0IGdyb3VwID0gdGhpcy5fZ3JvdXBzLmdldChncm91cElkKTtcbiAgICAgIGlmICghZ3JvdXApIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBiYXNlID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGhlbGQsIGdyb3VwSWQpXG4gICAgICAgID8gaGVsZFtncm91cElkXVxuICAgICAgICA6IHRvU3RvcmVkR3JvdXBWYWx1ZShncm91cC50eXBlLCB0aGlzLl9kZWZhdWx0VmFsdWUoZ3JvdXApKTtcbiAgICAgIGNvbnN0IHNjcmVlbiA9IHRoaXMuX2NsZWFyZWQuaGFzKGdyb3VwSWQpID8gbnVsbCA6IHRvU3RvcmVkR3JvdXBWYWx1ZShncm91cC50eXBlLCB0aGlzLl92YWx1ZXMuZ2V0KGdyb3VwSWQpKTtcblxuICAgICAgcmV0dXJuICFzYW1lU3RvcmVkR3JvdXBWYWx1ZShiYXNlLCBzY3JlZW4pO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gVGhlIGludGVyYWN0aW9uIHN0YXRlIGEgdGlsZSdzIGRhdGEgcmVxdWVzdCBjYXJyaWVzIG5vdzogdGlsZURhdGFTdGF0ZVxuICAvLyBvdmVyIHRoZSBvcGVuIHJlcG9ydCBhbmQgdGhlIHNjcmVlbidzIHNuYXBzaG90KCkuXG4gIHB1YmxpYyB0aWxlU3RhdGUoY29tcG9uZW50OiBSZXBvcnRDb21wb25lbnQpOiBDb21wb25lbnREYXRhU3RhdGUge1xuICAgIHJldHVybiB0aWxlRGF0YVN0YXRlKHRoaXMuX3JlcG9ydCgpLCBjb21wb25lbnQsIHRoaXMuc25hcHNob3QoKSk7XG4gIH1cblxuICAvLyBUaGUgcmVsYXRpdmUgcmFuZ2UgYSBncm91cCdzIHZhbHVlIHN0aWxsIGlzLCBhcyBhIGRhdGEgcmVxdWVzdCBuYW1lcyBpdFxuICAvLyAoaXRzIHByZXNldCB3aGlsZSBpdHMgZGF5cyBhcmUgdGhhdCByYW5nZSByZXNvbHZlZCB0b2RheSksIG9yIG51bGwuIFRoZVxuICAvLyBleHBvcnQgd29yZGluZyBuYW1lcyBhIGxpdmUgcHJlc2V0IGJ5IGl0LlxuICBwdWJsaWMgbGl2ZVByZXNldChncm91cElkOiBudW1iZXIpOiBSZXBvcnRSZWxhdGl2ZVJhbmdlIHwgbnVsbCB7XG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLl92YWx1ZXMuZ2V0KGdyb3VwSWQpO1xuXG4gICAgcmV0dXJuIHZhbHVlID8gdGhpcy5fbGl2ZVByZXNldCh2YWx1ZSkgOiBudWxsO1xuICB9XG5cbiAgLy8gQSBncm91cCB2YWx1ZSBhcyB0aGUgZmllbGRzIGEgcmVxdWVzdCBjYXJyaWVzOiBkYXRlIGJvdW5kcyBhcyBjYWxlbmRhclxuICAvLyBkYXlzLCBzZWxlY3QgdmFsdWVzIHdoZW4gYW55IGFyZSBwaWNrZWQgKGVsc2UgdGhlIHZhbHVlcyBsZWZ0IG91dCksXG4gIC8vIGtleXdvcmQgdGV4dCB0cmltbWVkLCBhIG51bWJlciByYW5nZSdzIGVuZHMuIE51bGwgd2hlbiBhbGwgb2YgdGhlbSBhcmVcbiAgLy8gZW1wdHkuIEEgZGF0ZSByYW5nZSBhbHNvIG5hbWVzIHRoZSByZWxhdGl2ZSByYW5nZSBpdCBzdGlsbCBpc1xuICAvLyAoX2xpdmVQcmVzZXQpLCBzbyB0aGUgc2VydmVyIGtub3dzIHdoaWNoIHBlcmlvZCB0aGUgZGF5cyBjb3ZlcjtcbiAgLy8gdGhlIGRheXMgc3RheSB0aGUgd2luZG93IGVpdGhlciB3YXkuIENvbXBvbmVudCBkYXRhLCB0aGUgcmVwb3J0IGFuZCBwYWdlXG4gIC8vIGV4cG9ydHMgYW5kIHRoZSBjaGF0J3Mgdmlld2VyIGZpbHRlcnMgYWxsIHJlYWQgdGhlaXIgZmllbGRzIGhlcmUsIHNvIGFsbFxuICAvLyB0aHJlZSBjYXJyeSBpdC5cbiAgcHJpdmF0ZSBfcmVzb2x2ZWRGaWVsZHModmFsdWU6IEZpbHRlckdyb3VwVmFsdWUpOiBPbWl0PFJlc29sdmVkRmlsdGVyVmFsdWUsICdmaWx0ZXJJZCc+IHwgbnVsbCB7XG4gICAgY29uc3QgZmllbGRzOiBPbWl0PFJlc29sdmVkRmlsdGVyVmFsdWUsICdmaWx0ZXJJZCc+ID0ge307XG4gICAgY29uc3QgcHJlc2V0ID0gdGhpcy5fbGl2ZVByZXNldCh2YWx1ZSk7XG5cbiAgICBpZiAodmFsdWUuc3RhcnQpIHtcbiAgICAgIGZpZWxkcy5zdGFydCA9IGRhdGVCb3VuZFN0cmluZyh2YWx1ZS5zdGFydCk7XG4gICAgfVxuICAgIGlmICh2YWx1ZS5lbmQpIHtcbiAgICAgIGZpZWxkcy5lbmQgPSBkYXRlQm91bmRTdHJpbmcodmFsdWUuZW5kKTtcbiAgICB9XG4gICAgaWYgKHByZXNldCkge1xuICAgICAgZmllbGRzLnByZXNldCA9IHByZXNldDtcbiAgICB9XG4gICAgaWYgKHZhbHVlLnZhbHVlcz8ubGVuZ3RoKSB7XG4gICAgICBmaWVsZHMudmFsdWVzID0gdmFsdWUudmFsdWVzO1xuICAgIH1cbiAgICBpZiAodmFsdWUudmFsdWU/LnRyaW0oKSkge1xuICAgICAgZmllbGRzLnZhbHVlID0gdmFsdWUudmFsdWUudHJpbSgpO1xuICAgIH1cblxuICAgIHRoaXMuX3Jlc29sdmVFeGNsdWRlQW5kUmFuZ2UodmFsdWUsIGZpZWxkcyk7XG5cbiAgICByZXR1cm4gZmllbGRzLnN0YXJ0IHx8IGZpZWxkcy5lbmQgfHwgZmllbGRzLnZhbHVlcyB8fCBmaWVsZHMudmFsdWVcbiAgICAgIHx8IGZpZWxkcy5leGNsdWRlVmFsdWVzIHx8IGZpZWxkcy5taW4gIT09IHVuZGVmaW5lZCB8fCBmaWVsZHMubWF4ICE9PSB1bmRlZmluZWRcbiAgICAgID8gZmllbGRzXG4gICAgICA6IG51bGw7XG4gIH1cblxuICAvLyBUaGUgcmVsYXRpdmUgcmFuZ2UgYSBkYXRlIHZhbHVlIHN0aWxsIGlzOiB0aGUgcHJlc2V0IG5hbWUgaXQgY2FycmllcyxcbiAgLy8gd2hpbGUgaXRzIGRheXMgYXJlIHRoYXQgcmFuZ2UgcmVzb2x2ZWQgdG9kYXkgaW4gdGhlIHJlcG9ydCdzIHpvbmUuIEFcbiAgLy8gdmFsdWUgd2hvc2UgZGF5cyB0aGUgdmlld2VyIGNoYW5nZWQsIG9yIG9uZSBzZWVkZWQgYmVmb3JlIG1pZG5pZ2h0IHRoYXRcbiAgLy8gaXMgbm93IGEgZGF5IGJlaGluZCwgbmFtZXMgbm9uZSwgYW5kIHRoZSBzZXJ2ZXIgcmVhZHMgaXRzIGRheXMgYWxvbmUuXG4gIHByaXZhdGUgX2xpdmVQcmVzZXQodmFsdWU6IEZpbHRlckdyb3VwVmFsdWUpOiBSZXBvcnRSZWxhdGl2ZVJhbmdlIHwgbnVsbCB7XG4gICAgaWYgKCF2YWx1ZS5wcmVzZXQgfHwgIWlzUmVsYXRpdmVSYW5nZSh2YWx1ZS5wcmVzZXQpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCByYW5nZSA9IHRoaXMuX3JlbGF0aXZlUmFuZ2UodmFsdWUucHJlc2V0KTtcblxuICAgIHJldHVybiByYW5nZSAmJiBzYW1lRGF5cyh2YWx1ZSwgcmFuZ2UpID8gdmFsdWUucHJlc2V0IDogbnVsbDtcbiAgfVxuXG4gIC8vIFNlZWRzIG9uZSBncm91cCBvbiAocmUpbG9hZDsgc2VlIGluaXQoKS4gYHByZXZpb3VzYCBpcyB0aGUgZ3JvdXAgYXMgdGhlXG4gIC8vIGxhc3QgbG9hZCBoYWQgaXQsIG9yIG51bGwgd2hlbiBpdCBpcyBuZXcuXG4gIHByaXZhdGUgX3NlZWQoXG4gICAgZ3JvdXA6IFJlcG9ydEZpbHRlckdyb3VwLFxuICAgIHByZXZpb3VzOiBSZXBvcnRGaWx0ZXJHcm91cCB8IG51bGwsXG4gICAgdGltZXpvbmVDaGFuZ2VkOiBib29sZWFuLFxuICApOiB2b2lkIHtcbiAgICBjb25zdCBkZWZhdWx0Q2hhbmdlZCA9ICFzYW1lRGVmYXVsdChwcmV2aW91cz8uY29uZmlnPy5kZWZhdWx0ID8/IG51bGwsIGdyb3VwLmNvbmZpZz8uZGVmYXVsdCA/PyBudWxsKTtcblxuICAgIGlmIChkZWZhdWx0Q2hhbmdlZCkge1xuICAgICAgdGhpcy5fY2xlYXJlZC5kZWxldGUoZ3JvdXAuaWQpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9jbGVhcmVkLmhhcyhncm91cC5pZCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuX3ZhbHVlcy5nZXQoZ3JvdXAuaWQpO1xuICAgIGNvbnN0IHByZXNldFRvUmVzb2x2ZSA9IHRpbWV6b25lQ2hhbmdlZFxuICAgICAgJiYgISF2YWx1ZT8ucHJlc2V0XG4gICAgICAmJiB2YWx1ZS5wcmVzZXQgPT09IGdyb3VwLmNvbmZpZz8uZGVmYXVsdD8ucmVsYXRpdmU7XG5cbiAgICBpZiAodmFsdWUgJiYgIWRlZmF1bHRDaGFuZ2VkICYmICFwcmVzZXRUb1Jlc29sdmUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBkZWZhdWx0VmFsdWUgPSB0aGlzLl9kZWZhdWx0VmFsdWUoZ3JvdXApO1xuXG4gICAgaWYgKGRlZmF1bHRWYWx1ZSkge1xuICAgICAgdGhpcy5fdmFsdWVzLnNldChncm91cC5pZCwgZGVmYXVsdFZhbHVlKTtcbiAgICB9IGVsc2UgaWYgKGRlZmF1bHRDaGFuZ2VkKSB7XG4gICAgICAvLyBUaGUgZGVmYXVsdCB3YXMgY2xlYXJlZCwgc28gdGhlIHZhbHVlIGl0IHNlZWRlZCBnb2VzIHdpdGggaXQuXG4gICAgICB0aGlzLl92YWx1ZXMuZGVsZXRlKGdyb3VwLmlkKTtcbiAgICB9XG4gIH1cblxuICAvLyBEcm9wcyB0aGUgc2VhcmNoIG9mIGV2ZXJ5IGxpc3QgdGhhdCBubyBsb25nZXIgc2hvd3MgYSBzZWFyY2ggYm94OiBvbmVcbiAgLy8gdGhlIHJlcG9ydCBubyBsb25nZXIgaGFzLCBvciBvbmUgd2hvc2UgaGVhZGVyIG5vdyBoYXMgYSBrZXl3b3JkIGdyb3VwLlxuICBwcml2YXRlIF9kcm9wVW5zZWFyY2hhYmxlKCk6IHZvaWQge1xuICAgIHRoaXMuX2xpc3RTZWFyY2hlcy5mb3JFYWNoKChzZWFyY2gsIGNvbXBvbmVudElkKSA9PiB7XG4gICAgICBjb25zdCBjb21wb25lbnQgPSB0aGlzLl9saXN0cy5nZXQoY29tcG9uZW50SWQpO1xuXG4gICAgICBpZiAoIWNvbXBvbmVudCB8fCAhdGhpcy5saXN0U2VhcmNoYWJsZShjb21wb25lbnQpKSB7XG4gICAgICAgIHRoaXMuX2xpc3RTZWFyY2hlcy5kZWxldGUoY29tcG9uZW50SWQpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gRHJvcHMgc3RhdGUga2VwdCBmb3IgZ3JvdXBzLCBsaXN0cyBhbmQgZmlsdGVycyB0aGUgcmVwb3J0IG5vIGxvbmdlciBoYXMuXG4gIC8vIEEgbGlzdCBzb3J0IGFsc28gZ29lcyB3aGVuIGl0cyBjb2x1bW4gZG9lczogdGhlIGFnZW50IGNhbiByZW1vdmUgb3IgcmVuYW1lXG4gIC8vIGl0LCBhbmQgdGhlIHJlY3JlYXRlZCBsaXN0IHdvdWxkIHNlbmQgYSBjb2x1bW4gdGhlIHF1ZXJ5IGRvZXMgbm90IGtub3cuXG4gIC8vIEEgbGlzdCBzZWFyY2ggZ29lcyB3aXRoIGl0cyBsaXN0IChvciB3aGVuIHRoZSBjb21wb25lbnQgaXMgbm8gbG9uZ2VyIGFcbiAgLy8gbGlzdCksIGFuZCB3aGVuIHRoZSBsaXN0IGdhaW5zIGEga2V5d29yZCBncm91cCBhbmQgc28gbG9zZXMgaXRzIGJveC5cbiAgLy8gSGlkZGVuIGNvbHVtbnMga2VlcCBvbmx5IHRoZSBuYW1lcyB0aGVpciBsaXN0IHN0aWxsIGhhcyBhcyBjb2x1bW5zICh0aGVcbiAgLy8gYWdlbnQgY2FuIHJlbW92ZSBvciByZW5hbWUgb25lLCBvciB0dXJuIHRoZSBsaXN0IGludG8gYSBjcm9zcy10YWIpLCBhbmQgZ29cbiAgLy8gd2hlbiB3aGF0IGlzIGxlZnQgd291bGQgaGlkZSBldmVyeSBjb2x1bW4uXG4gIHByaXZhdGUgX3BydW5lKHJlcG9ydDogUmVwb3J0KTogdm9pZCB7XG4gICAgZm9yIChjb25zdCBncm91cElkIG9mIFsuLi50aGlzLl92YWx1ZXMua2V5cygpLCAuLi50aGlzLl9jbGVhcmVkXSkge1xuICAgICAgaWYgKCF0aGlzLl9ncm91cHMuaGFzKGdyb3VwSWQpKSB7XG4gICAgICAgIHRoaXMuX3ZhbHVlcy5kZWxldGUoZ3JvdXBJZCk7XG4gICAgICAgIHRoaXMuX2NsZWFyZWQuZGVsZXRlKGdyb3VwSWQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuX2xpc3RTb3J0cy5mb3JFYWNoKChzb3J0LCBjb21wb25lbnRJZCkgPT4ge1xuICAgICAgY29uc3QgY29tcG9uZW50ID0gdGhpcy5fbGlzdHMuZ2V0KGNvbXBvbmVudElkKTtcblxuICAgICAgaWYgKCFjb21wb25lbnQgfHwgIXRoaXMuX3NvcnRhYmxlQ29sdW1ucyhjb21wb25lbnQpLmluY2x1ZGVzKHNvcnQuY29sdW1uKSkge1xuICAgICAgICB0aGlzLl9saXN0U29ydHMuZGVsZXRlKGNvbXBvbmVudElkKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIFZhbHVlcyBpbmNsdWRlZDogb25lIGlzIG5ldmVyIGRyYXduLCBidXQgaXRzIGZpbHRlcnMgYXJlIHRoZSByZXBvcnQnc1xuICAgIC8vIGxpa2UgYW55IG90aGVyIGNvbXBvbmVudCdzLCBhbmQgc28gYXJlIHRoZWlyIHNlc3Npb24gdG9nZ2xlcy5cbiAgICBjb25zdCBmaWx0ZXJJZHMgPSBuZXcgU2V0KHJlcG9ydENvbXBvbmVudHMocmVwb3J0KVxuICAgICAgLmZsYXRNYXAoKGNvbXBvbmVudCkgPT4gKGNvbXBvbmVudC5maWx0ZXJzID8/IFtdKS5tYXAoKGZpbHRlcikgPT4gZmlsdGVyLmlkKSkpO1xuXG4gICAgdGhpcy5fc2Vzc2lvbkRpc2FibGVkLmZvckVhY2goKGZpbHRlcklkKSA9PiB7XG4gICAgICBpZiAoIWZpbHRlcklkcy5oYXMoZmlsdGVySWQpKSB7XG4gICAgICAgIHRoaXMuX3Nlc3Npb25EaXNhYmxlZC5kZWxldGUoZmlsdGVySWQpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGhpcy5fZHJvcFVuc2VhcmNoYWJsZSgpO1xuXG4gICAgY29uc3QgaGlkZGVuID0gbmV3IE1hcDxudW1iZXIsIHJlYWRvbmx5IHN0cmluZ1tdPigpO1xuXG4gICAgdGhpcy5saXN0SGlkZGVuKCkuZm9yRWFjaCgobmFtZXMsIGNvbXBvbmVudElkKSA9PiB7XG4gICAgICBjb25zdCBrZXB0ID0gbGlzdEhpZGRlbkNvbHVtbnModGhpcy5fbGlzdHMuZ2V0KGNvbXBvbmVudElkKT8uY29uZmlnLCBuYW1lcyk7XG5cbiAgICAgIGlmIChrZXB0Lmxlbmd0aCkge1xuICAgICAgICBoaWRkZW4uc2V0KGNvbXBvbmVudElkLCBrZXB0KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMubGlzdEhpZGRlbi5zZXQoaGlkZGVuKTtcbiAgfVxuXG4gIC8vIFRoZSB2YWx1ZSBhIGJhciBzZXRzLCBrZWVwaW5nIHRoZSBzdG9yZWQgcHJlc2V0IG5hbWUgd2hpbGUgdGhlIGRheXMgYXJlXG4gIC8vIHN0aWxsIHRoZSBzdG9yZWQgZGF5cyAoc2VlIHNldFZhbHVlKS5cbiAgcHJpdmF0ZSBfd2l0aFByZXNldChzdG9yZWQ6IEZpbHRlckdyb3VwVmFsdWUgfCB1bmRlZmluZWQsIHZhbHVlOiBGaWx0ZXJHcm91cFZhbHVlKTogRmlsdGVyR3JvdXBWYWx1ZSB7XG4gICAgY29uc3QgZml4ZWQ6IEZpbHRlckdyb3VwVmFsdWUgPSB7IC4uLnZhbHVlIH07XG4gICAgZGVsZXRlIGZpeGVkLnByZXNldDtcblxuICAgIHJldHVybiBzdG9yZWQ/LnByZXNldCAmJiBzYW1lRGF5cyhzdG9yZWQsIGZpeGVkKVxuICAgICAgPyB7IC4uLmZpeGVkLCBwcmVzZXQ6IHN0b3JlZC5wcmVzZXQgfVxuICAgICAgOiBmaXhlZDtcbiAgfVxuXG4gIHByaXZhdGUgX2xpc3RDb21wb25lbnRzKHJlcG9ydDogUmVwb3J0KTogUmVwb3J0Q29tcG9uZW50W10ge1xuICAgIHJldHVybiByZXBvcnRDb21wb25lbnRzKHJlcG9ydClcbiAgICAgIC5maWx0ZXIoKGNvbXBvbmVudCkgPT4gY29tcG9uZW50LnR5cGUgPT09ICdsaXN0Jyk7XG4gIH1cblxuICAvLyBUaGUgY29sdW1ucyBhIGxpc3QgY2FuIGJlIHNvcnRlZCBieTogZXZlcnkgYXV0aG9yZWQgY29sdW1uLCBvciBhXG4gIC8vIGNyb3NzLXRhYidzIHJvdyBjb2x1bW4gb25seSAoaXRzIHBpdm90IGNvbHVtbnMgY29tZSBhbmQgZ28gd2l0aCB0aGUgZGF0YSkuXG4gIHByaXZhdGUgX3NvcnRhYmxlQ29sdW1ucyhjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudCk6IHN0cmluZ1tdIHtcbiAgICBjb25zdCBjb25maWcgPSBjb21wb25lbnQuY29uZmlnO1xuXG4gICAgaWYgKGNvbmZpZz8ucGl2b3RCeT8uY29sdW1uKSB7XG4gICAgICByZXR1cm4gY29uZmlnLnJvd0J5Py5jb2x1bW4gPyBbY29uZmlnLnJvd0J5LmNvbHVtbl0gOiBbXTtcbiAgICB9XG5cbiAgICByZXR1cm4gKGNvbmZpZz8uY29sdW1ucyA/PyBbXSkubWFwKChjb2x1bW4pID0+IGNvbHVtbi5jb2x1bW4pO1xuICB9XG5cbiAgLy8gQSBncm91cCdzIGF1dGhvcmVkIGRlZmF1bHQsIG1hcHBlZCB0byBhIHNlc3Npb24gdmFsdWUgYnkgdHlwZS4gUmVsYXRpdmVcbiAgLy8gZGF0ZSBwcmVzZXRzIHJlc29sdmUgYWdhaW5zdCBcIm5vd1wiIGVhY2ggdGltZSB0aGUgcmVwb3J0IG9wZW5zLCBzbyBhIHNhdmVkXG4gIC8vIFwibGFzdCAxMiBtb250aHNcIiBzdGF5cyByZWxhdGl2ZSBhbmQgY2FycmllcyBpdHMgcHJlc2V0IG5hbWU7IGEgZml4ZWRcbiAgLy8gcmFuZ2UsIHNlbGVjdCB2YWx1ZXMgYW5kIGtleXdvcmQgdGV4dCBzZWVkIHZlcmJhdGltLlxuICBwcml2YXRlIF9kZWZhdWx0VmFsdWUoZ3JvdXA6IFJlcG9ydEZpbHRlckdyb3VwKTogRmlsdGVyR3JvdXBWYWx1ZSB8IG51bGwge1xuICAgIGNvbnN0IGdyb3VwRGVmYXVsdCA9IGdyb3VwLmNvbmZpZz8uZGVmYXVsdDtcbiAgICBpZiAoIWdyb3VwRGVmYXVsdCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgaWYgKGdyb3VwRGVmYXVsdC5yZWxhdGl2ZSkge1xuICAgICAgY29uc3QgcmFuZ2UgPSB0aGlzLl9yZWxhdGl2ZVJhbmdlKGdyb3VwRGVmYXVsdC5yZWxhdGl2ZSk7XG5cbiAgICAgIHJldHVybiByYW5nZSA/IHsgc3RhcnQ6IHJhbmdlLnN0YXJ0LCBlbmQ6IHJhbmdlLmVuZCwgcHJlc2V0OiBncm91cERlZmF1bHQucmVsYXRpdmUgfSA6IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKGdyb3VwRGVmYXVsdC5zdGFydCB8fCBncm91cERlZmF1bHQuZW5kKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdGFydDogZ3JvdXBEZWZhdWx0LnN0YXJ0ID8/IG51bGwsXG4gICAgICAgIGVuZDogZ3JvdXBEZWZhdWx0LmVuZCA/PyBudWxsLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoZ3JvdXBEZWZhdWx0LnZhbHVlcz8ubGVuZ3RoKSB7XG4gICAgICByZXR1cm4geyB2YWx1ZXM6IGdyb3VwRGVmYXVsdC52YWx1ZXMgfTtcbiAgICB9XG5cbiAgICBpZiAoZ3JvdXBEZWZhdWx0LnZhbHVlKSB7XG4gICAgICByZXR1cm4geyB2YWx1ZTogZ3JvdXBEZWZhdWx0LnZhbHVlIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX2V4Y2x1ZGVPclJhbmdlRGVmYXVsdChncm91cERlZmF1bHQpO1xuICB9XG5cbiAgLy8gQSByZWxhdGl2ZSBwcmVzZXQgYXMgYSBjYWxlbmRhci1kYXkgcmFuZ2UuIFwiVG9kYXlcIiBpcyB0aGUgZGF5IGluIHRoZVxuICAvLyByZXBvcnQncyBlZmZlY3RpdmUgem9uZSwgbm90IHRoZSBicm93c2VyJ3MsIHNvIGV2ZXJ5IHZpZXdlciBzZWVkcyB0aGUgc2FtZVxuICAvLyByYW5nZS4gVGhlIHNlcnZlciB0d2luIGlzIFJlcG9ydFJlbGF0aXZlUmFuZ2VFbnVtIChmcmFtZXdvcmsvUmVwb3J0L0VudW0pLFxuICAvLyBhbmQgUmVwb3J0UmVsYXRpdmVSYW5nZUVudW1UZXN0IHBpbnMgdGhlIHRhYmxlIGJvdGggc2lkZXMgbXVzdCBwcm9kdWNlLlxuICBwcml2YXRlIF9yZWxhdGl2ZVJhbmdlKHJlbGF0aXZlOiBzdHJpbmcpOiB7IHN0YXJ0OiBEYXRlOyBlbmQ6IERhdGUgfSB8IG51bGwge1xuICAgIGNvbnN0IG5vdyA9IGdldFpvbmVkTm93KHRoaXMudGltZXpvbmUoKSk7XG5cbiAgICBzd2l0Y2ggKHJlbGF0aXZlKSB7XG4gICAgICAvLyBBIGNhbGVuZGFyIHdlZWssIE1vbmRheSB0byBTdW5kYXkgKFJFUE9SVF9XRUVLX1NUQVJUU19PTiwgdGhlIHNhbWUgd2Vla1xuICAgICAgLy8gdGhlIHNlcnZlcidzIHdlZWtseSBidWNrZXRzIHVzZSksIGluIHdob2xlIGRheXMg4oCUIG5vdCB0aGUgcm9sbGluZ1xuICAgICAgLy8gc2V2ZW4gZGF5cyBgbGFzdDdEYXlzYCBnaXZlcywgd2hpY2ggbmV2ZXIgbGluZXMgdXAgd2l0aCB0aGUgd2VlayBhXG4gICAgICAvLyBwYXJ0bmVyIGhhcyBhbHJlYWR5IGJlZW4gc2VudC4gYGxhc3RXZWVrYCBpcyB0aGUgb25lIGEgd2Vla2x5IHJlcG9ydFxuICAgICAgLy8gd2FudHM6IGl0IGVuZHMgb24gdGhlIHByZXZpb3VzIHdlZWsncyBTdW5kYXkgcmF0aGVyIHRoYW4gYXQgYG5vd2AsXG4gICAgICAvLyBiZWNhdXNlIHRoZSB3ZWVrIGl0IG5hbWVzIGhhcyBjbG9zZWQuIGB0aGlzV2Vla2AgZm9sbG93cyBldmVyeSBvdGhlclxuICAgICAgLy8gcHJlc2V0IGhlcmUgYW5kIHJ1bnMgdXAgdG8gbm93LCBzbyBpdCBpcyBkZWxpYmVyYXRlbHkgYSBwYXJ0LWZpbmlzaGVkXG4gICAgICAvLyB3ZWVrIChvbiBhIFN1bmRheSBpdCBpcyB0aGUgd2hvbGUgTW9uZGF5LXRvLVN1bmRheSB3ZWVrKS5cbiAgICAgIGNhc2UgJ3RoaXNXZWVrJzpcbiAgICAgICAgcmV0dXJuIHsgc3RhcnQ6IHN0YXJ0T2ZXZWVrKG5vdywgeyB3ZWVrU3RhcnRzT246IFJFUE9SVF9XRUVLX1NUQVJUU19PTiB9KSwgZW5kOiBub3cgfTtcbiAgICAgIGNhc2UgJ2xhc3RXZWVrJzoge1xuICAgICAgICBjb25zdCBwcmV2aW91cyA9IHN1YldlZWtzKG5vdywgMSk7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzdGFydDogc3RhcnRPZldlZWsocHJldmlvdXMsIHsgd2Vla1N0YXJ0c09uOiBSRVBPUlRfV0VFS19TVEFSVFNfT04gfSksXG4gICAgICAgICAgZW5kOiBlbmRPZldlZWsocHJldmlvdXMsIHsgd2Vla1N0YXJ0c09uOiBSRVBPUlRfV0VFS19TVEFSVFNfT04gfSksXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBjYXNlICdsYXN0N0RheXMnOlxuICAgICAgICByZXR1cm4geyBzdGFydDogc3ViRGF5cyhub3csIDcpLCBlbmQ6IG5vdyB9O1xuICAgICAgY2FzZSAnbGFzdDMwRGF5cyc6XG4gICAgICAgIHJldHVybiB7IHN0YXJ0OiBzdWJEYXlzKG5vdywgMzApLCBlbmQ6IG5vdyB9O1xuICAgICAgY2FzZSAnbGFzdDNNb250aHMnOlxuICAgICAgICByZXR1cm4geyBzdGFydDogc3ViTW9udGhzKG5vdywgMyksIGVuZDogbm93IH07XG4gICAgICBjYXNlICdsYXN0Nk1vbnRocyc6XG4gICAgICAgIHJldHVybiB7IHN0YXJ0OiBzdWJNb250aHMobm93LCA2KSwgZW5kOiBub3cgfTtcbiAgICAgIGNhc2UgJ2xhc3QxMk1vbnRocyc6XG4gICAgICAgIHJldHVybiB7IHN0YXJ0OiBzdWJNb250aHMobm93LCAxMiksIGVuZDogbm93IH07XG4gICAgICBjYXNlICd0aGlzTW9udGgnOlxuICAgICAgICByZXR1cm4geyBzdGFydDogc3RhcnRPZk1vbnRoKG5vdyksIGVuZDogbm93IH07XG4gICAgICBjYXNlICd0aGlzUXVhcnRlcic6XG4gICAgICAgIHJldHVybiB7IHN0YXJ0OiBzdGFydE9mUXVhcnRlcihub3cpLCBlbmQ6IG5vdyB9O1xuICAgICAgY2FzZSAndGhpc1llYXInOlxuICAgICAgY2FzZSAneWVhclRvRGF0ZSc6XG4gICAgICAgIHJldHVybiB7IHN0YXJ0OiBzdGFydE9mWWVhcihub3cpLCBlbmQ6IG5vdyB9O1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgLy8gRXZlcnkgZ3JvdXAgaW4gaXRzIHN0b3JlZCBzaGFwZTogbnVsbCB3aGVuIGl0IGhvbGRzIG5vdGhpbmcsIGEgZGVmYXVsdFxuICAvLyB0aGUgdmlld2VyIGNsZWFyZWQgaW5jbHVkZWQuXG4gIHByaXZhdGUgX3NuYXBzaG90R3JvdXBzKCk6IFJlY29yZDxudW1iZXIsIEZpbHRlckdyb3VwRGVmYXVsdCB8IG51bGw+IHtcbiAgICBjb25zdCBncm91cHM6IFJlY29yZDxudW1iZXIsIEZpbHRlckdyb3VwRGVmYXVsdCB8IG51bGw+ID0ge307XG5cbiAgICB0aGlzLl9ncm91cHMuZm9yRWFjaCgoZ3JvdXApID0+IHtcbiAgICAgIGdyb3Vwc1tncm91cC5pZF0gPSB0aGlzLl9jbGVhcmVkLmhhcyhncm91cC5pZClcbiAgICAgICAgPyBudWxsXG4gICAgICAgIDogdG9TdG9yZWRHcm91cFZhbHVlKGdyb3VwLnR5cGUsIHRoaXMuX3ZhbHVlcy5nZXQoZ3JvdXAuaWQpKTtcbiAgICB9KTtcblxuICAgIHJldHVybiBncm91cHM7XG4gIH1cblxuICAvLyBFYWNoIHRpbGUncyBzdGF0ZSB3aGVyZSBpdCBkaWZmZXJzIGZyb20gdGhlIGF1dGhvcmVkIHRpbGUuIEEgbGlzdCBzb3J0XG4gIC8vIHRoYXQgaXMgdGhlIGxpc3QncyBhdXRob3JlZCBmaXJzdCB0ZXJtIGlzIGl0cyBkZWZhdWx0LCBub3QgYSBjaG9pY2UuXG4gIHByaXZhdGUgX3NuYXBzaG90VGlsZXMoKTogUmVjb3JkPG51bWJlciwgUmVwb3J0VGlsZVN0YXRlPiB7XG4gICAgY29uc3QgdGlsZXM6IFJlY29yZDxudW1iZXIsIFJlcG9ydFRpbGVTdGF0ZT4gPSB7fTtcblxuICAgIGZvciAoY29uc3QgY29tcG9uZW50IG9mIHRoaXMuX3RpbGVzKCkpIHtcbiAgICAgIGNvbnN0IHRpbGU6IFJlcG9ydFRpbGVTdGF0ZSA9IHt9O1xuICAgICAgY29uc3Qgc29ydCA9IHRoaXMuX2xpc3RTb3J0cy5nZXQoY29tcG9uZW50LmlkKTtcbiAgICAgIGNvbnN0IHNlYXJjaCA9IHRoaXMuX2xpc3RTZWFyY2hlcy5nZXQoY29tcG9uZW50LmlkKTtcbiAgICAgIGNvbnN0IGhpZGRlbiA9IHRoaXMuaGlkZGVuQ29sdW1ucyhjb21wb25lbnQuaWQpO1xuICAgICAgY29uc3QgZHJpbGwgPSB0aGlzLmRyaWxsKGNvbXBvbmVudC5pZCk7XG5cbiAgICAgIGlmIChzb3J0ICYmICFzYW1lU29ydChzb3J0LCBsaXN0U29ydFRlcm1zKGNvbXBvbmVudC5jb25maWcpWzBdID8/IG51bGwpKSB7XG4gICAgICAgIHRpbGUuc29ydCA9IHsgLi4uc29ydCB9O1xuICAgICAgfVxuICAgICAgaWYgKHNlYXJjaCkge1xuICAgICAgICB0aWxlLnNlYXJjaCA9IHNlYXJjaDtcbiAgICAgIH1cbiAgICAgIGlmIChoaWRkZW4ubGVuZ3RoKSB7XG4gICAgICAgIHRpbGUuaGlkZGVuID0gWy4uLmhpZGRlbl07XG4gICAgICB9XG4gICAgICBpZiAoZHJpbGwubGVuZ3RoKSB7XG4gICAgICAgIHRpbGUuZHJpbGwgPSBkcmlsbC5tYXAoKHN0ZXApID0+ICh7IC4uLnN0ZXAgfSkpO1xuICAgICAgfVxuXG4gICAgICBpZiAoT2JqZWN0LmtleXModGlsZSkubGVuZ3RoKSB7XG4gICAgICAgIHRpbGVzW2NvbXBvbmVudC5pZF0gPSB0aWxlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aWxlcztcbiAgfVxuXG4gIC8vIFRoZSB2aWV3IGFwcGx5KCkgd2FzIGdpdmVuLCBhcHBsaWVkIGFzIHRoZSBzY3JlZW4ncyBzdGF0ZSBhbmQga2VwdCBhc1xuICAvLyB0aGUgYmFzZS4gV2hhdCBpcyBrZXB0IGlzIHRoZSBzbmFwc2hvdCBvZiBpdCwgd2l0aCBvbmx5IHRoZSBncm91cHMgaXRcbiAgLy8gaGVsZDogYSBncm91cCBpdCBkaWQgbm90IGhvbGQsIG9yIGhlbGQgaW4gYSBzaGFwZSB0aGF0IGRvZXMgbm90IGZpdCxcbiAgLy8gZm9sbG93cyBpdHMgYXV0aG9yZWQgZGVmYXVsdCAodmlld0RpZmZlcnMgY29tcGFyZXMgaXQgd2l0aFxuICAvLyBhdXRob3JlZENvbmZpZygpKS5cbiAgcHJpdmF0ZSBfc2V0QmFzZShiYXNlOiBSZXBvcnRWaWV3Q29uZmlnIHwgbnVsbCk6IHZvaWQge1xuICAgIGNvbnN0IGhlbGQgPSB0aGlzLl9hcHBseUxheWVyKGJhc2UpO1xuXG4gICAgaWYgKCFiYXNlKSB7XG4gICAgICB0aGlzLl9iYXNlQ29uZmlnLnNldChudWxsKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFRoZSBwYWdlIGlzIHRoZSBiYXNlJ3Mgb3duLCBub3QgdGhlIG9uZSBvbiBzY3JlZW4uXG4gICAgY29uc3QgYXBwbGllZCA9IHRoaXMuc25hcHNob3QoKTtcbiAgICBkZWxldGUgYXBwbGllZC5wYWdlSWQ7XG4gICAgYXBwbGllZC5ncm91cHMgPSBPYmplY3QuZnJvbUVudHJpZXMoT2JqZWN0LmVudHJpZXMoYXBwbGllZC5ncm91cHMgPz8ge30pXG4gICAgICAuZmlsdGVyKChbZ3JvdXBJZF0pID0+IGhlbGQuaGFzKE51bWJlcihncm91cElkKSkpKTtcblxuICAgIGlmIChiYXNlLnBhZ2VJZCAmJiAodGhpcy5fcmVwb3J0KCk/LnBhZ2VzID8/IFtdKS5zb21lKChwYWdlKSA9PiBwYWdlLmlkID09PSBiYXNlLnBhZ2VJZCkpIHtcbiAgICAgIGFwcGxpZWQucGFnZUlkID0gYmFzZS5wYWdlSWQ7XG4gICAgfVxuXG4gICAgdGhpcy5fYmFzZUNvbmZpZy5zZXQoYXBwbGllZCk7XG4gIH1cblxuICAvLyBBcHBsaWVzIGEgdmlldydzIHN0YXRlIGluIHBsYWNlIG9mIHRoZSB3aG9sZSBkdXJhYmxlIHN0YXRlLCBhbmQgZ2l2ZXMgdGhlXG4gIC8vIGlkcyBvZiB0aGUgZ3JvdXBzIGl0IHNldDogd2hhdCBgY29uZmlnYCBkb2VzIG5vdCBob2xkIGdvZXMgYmFjayB0byB0aGVcbiAgLy8gYXV0aG9yZWQgcmVwb3J0LiBOb3RoaW5nIGlzIGFubm91bmNlZCBoZXJlOiB0aGUgY2FsbGVyIGFubm91bmNlcyBvbmNlXG4gIC8vIChfbm90aWZ5QXBwbGllZCkuXG4gIHByaXZhdGUgX2FwcGx5TGF5ZXIoY29uZmlnOiBSZXBvcnRWaWV3Q29uZmlnIHwgbnVsbCk6IFNldDxudW1iZXI+IHtcbiAgICBjb25zdCBoZWxkID0gdGhpcy5fYXBwbHlHcm91cHMoY29uZmlnPy5ncm91cHMgPz8ge30pO1xuXG4gICAgdGhpcy5fbWF0Y2guc2V0KGNvbmZpZz8ubWF0Y2ggPT09ICdhbnknID8gJ2FueScgOiAnYWxsJyk7XG5cbiAgICBjb25zdCBncm91cEJ5ID0gY29uZmlnPy5ncm91cEJ5O1xuICAgIHRoaXMuX2ZyZXF1ZW5jeSA9IGlzQ2hhcnRHcmFudWxhcml0eShncm91cEJ5KSA/IGdyb3VwQnkgOiBudWxsO1xuXG4gICAgdGhpcy5fY2xlYXJUaWxlcygpO1xuXG4gICAgT2JqZWN0LmVudHJpZXMoY29uZmlnPy50aWxlcyA/PyB7fSlcbiAgICAgIC5mb3JFYWNoKChbY29tcG9uZW50SWQsIHRpbGVdKSA9PiB0aGlzLl9hcHBseVRpbGUoTnVtYmVyKGNvbXBvbmVudElkKSwgdGlsZSA/PyB7fSkpO1xuXG4gICAgcmV0dXJuIGhlbGQ7XG4gIH1cblxuICAvLyBFYWNoIGdyb3VwJ3MgdmFsdWUgZnJvbSBhIHZpZXc7IGEgZ3JvdXAgaXQgZG9lcyBub3Qgc2V0IGdvZXMgYmFjayB0byBpdHNcbiAgLy8gYXV0aG9yZWQgZGVmYXVsdC5cbiAgcHJpdmF0ZSBfYXBwbHlHcm91cHMoZ3JvdXBzOiBSZWNvcmQ8bnVtYmVyLCBGaWx0ZXJHcm91cERlZmF1bHQgfCBudWxsPik6IFNldDxudW1iZXI+IHtcbiAgICBjb25zdCBoZWxkID0gbmV3IFNldDxudW1iZXI+KCk7XG5cbiAgICB0aGlzLl9ncm91cHMuZm9yRWFjaCgoZ3JvdXApID0+IHtcbiAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZ3JvdXBzLCBncm91cC5pZCkgJiYgdGhpcy5fYXBwbHlHcm91cChncm91cCwgZ3JvdXBzW2dyb3VwLmlkXSkpIHtcbiAgICAgICAgaGVsZC5hZGQoZ3JvdXAuaWQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fc2VlZEF1dGhvcmVkKGdyb3VwKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiBoZWxkO1xuICB9XG5cbiAgLy8gT25lIGdyb3VwJ3Mgc3RvcmVkIHZhbHVlLCBvciBmYWxzZSB3aGVuIHRoZSBncm91cCdzIHR5cGUgY2Fubm90IGhvbGQgaXRcbiAgLy8gKGl0IGlzIHRoZW4gZHJvcHBlZCB3aG9sZSwgYW5kIHRoZSBjYWxsZXIgc2VlZHMgdGhlIGdyb3VwJ3MgYXV0aG9yZWRcbiAgLy8gZGVmYXVsdCkuIG51bGwsIG9yIGEgdmFsdWUgdGhhdCBob2xkcyBub3RoaW5nLCBjbGVhcnMgdGhlIGdyb3VwLlxuICBwcml2YXRlIF9hcHBseUdyb3VwKGdyb3VwOiBSZXBvcnRGaWx0ZXJHcm91cCwgc3RvcmVkOiBGaWx0ZXJHcm91cERlZmF1bHQgfCBudWxsKTogYm9vbGVhbiB7XG4gICAgY29uc3Qga2VwdCA9IHN0b3JlZCA9PT0gbnVsbCA/IHt9IDogZ3JvdXBWYWx1ZUZyb21TdG9yZWQoc3RvcmVkLCBncm91cC50eXBlKTtcblxuICAgIGlmIChrZXB0ID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3QgdmFsdWUgPSB0b0xpdmVHcm91cFZhbHVlKGdyb3VwLnR5cGUsIGtlcHQsIChuYW1lKSA9PiB0aGlzLnJlc29sdmVSZWxhdGl2ZShuYW1lKSk7XG5cbiAgICBpZiAodmFsdWUpIHtcbiAgICAgIHRoaXMuX3ZhbHVlcy5zZXQoZ3JvdXAuaWQsIHZhbHVlKTtcbiAgICAgIHRoaXMuX2NsZWFyZWQuZGVsZXRlKGdyb3VwLmlkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fdmFsdWVzLmRlbGV0ZShncm91cC5pZCk7XG4gICAgICB0aGlzLl9jbGVhcmVkLmRlbGV0ZShncm91cC5pZCk7XG5cbiAgICAgIGlmIChncm91cC5jb25maWc/LmRlZmF1bHQpIHtcbiAgICAgICAgdGhpcy5fY2xlYXJlZC5hZGQoZ3JvdXAuaWQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLy8gQSBncm91cCBiYWNrIGF0IGl0cyBhdXRob3JlZCBkZWZhdWx0LlxuICBwcml2YXRlIF9zZWVkQXV0aG9yZWQoZ3JvdXA6IFJlcG9ydEZpbHRlckdyb3VwKTogdm9pZCB7XG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLl9kZWZhdWx0VmFsdWUoZ3JvdXApO1xuXG4gICAgdGhpcy5fY2xlYXJlZC5kZWxldGUoZ3JvdXAuaWQpO1xuXG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICB0aGlzLl92YWx1ZXMuc2V0KGdyb3VwLmlkLCB2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3ZhbHVlcy5kZWxldGUoZ3JvdXAuaWQpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEV2ZXJ5IHRpbGUgYmFjayBhdCBpdHMgYXV0aG9yZWQgc3RhdGUuXG4gIHByaXZhdGUgX2NsZWFyVGlsZXMoKTogdm9pZCB7XG4gICAgdGhpcy5fbGlzdFNvcnRzLmNsZWFyKCk7XG4gICAgdGhpcy5fbGlzdFNlYXJjaGVzLmNsZWFyKCk7XG4gICAgdGhpcy5saXN0SGlkZGVuLnNldChuZXcgTWFwKCkpO1xuICAgIHRoaXMuX2RyaWxscy5zZXQobmV3IE1hcCgpKTtcbiAgfVxuXG4gIC8vIE9uZSB0aWxlJ3Mgc3RvcmVkIHN0YXRlLCBlYWNoIGtleSBjaGVja2VkOiBhIHNvcnQgb24gYSBjb2x1bW4gdGhlIGxpc3RcbiAgLy8gY2FuIHNvcnQgYnksIGEgc2VhcmNoIG9uIGEgbGlzdCB0aGF0IHNob3dzIHRoZSBib3gsIGhpZGRlbiBjb2x1bW5zIHRoZVxuICAvLyBsaXN0IGNhbiBoaWRlLCBhIGRyaWxsIHBhdGggb24gYSBjaGFydC5cbiAgcHJpdmF0ZSBfYXBwbHlUaWxlKGNvbXBvbmVudElkOiBudW1iZXIsIHRpbGU6IFJlcG9ydFRpbGVTdGF0ZSk6IHZvaWQge1xuICAgIGNvbnN0IGxpc3QgPSB0aGlzLl9saXN0cy5nZXQoY29tcG9uZW50SWQpO1xuXG4gICAgaWYgKGxpc3QpIHtcbiAgICAgIHRoaXMuX2FwcGx5TGlzdFRpbGUobGlzdCwgdGlsZSk7XG4gICAgfVxuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkodGlsZS5kcmlsbCkgJiYgdGhpcy5faXNDaGFydChjb21wb25lbnRJZCkpIHtcbiAgICAgIHRoaXMuX3NldERyaWxsUGF0aChjb21wb25lbnRJZCwgY2xlYW5EcmlsbFBhdGgodGlsZS5kcmlsbCkpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEEgbGlzdCdzIHNvcnQsIHNlYXJjaCBhbmQgaGlkZGVuIGNvbHVtbnMgZnJvbSBhIHRpbGUgc3RhdGUsIGtlcHQgYnkgdGhlXG4gIC8vIHJ1bGVzIHNldExpc3RTb3J0LCBzZXRMaXN0U2VhcmNoIGFuZCBzZXRIaWRkZW5Db2x1bW5zIGFwcGx5LCBidXQgc2V0XG4gIC8vIHN0cmFpZ2h0IG9uIHRoZSBtYXBzOiB0aG9zZSBzZXR0ZXJzIGVhY2ggYW5ub3VuY2UgYSBjaGFuZ2UsIGFuZCBhbiBhcHBseVxuICAvLyBhbm5vdW5jZXMgb25jZSwgYXQgaXRzIGVuZC4gQSBzb3J0IHRoYXQgaXMgdGhlIGxpc3QncyBhdXRob3JlZCBmaXJzdFxuICAvLyB0ZXJtIGlzIGl0cyBkZWZhdWx0LCBzbyBpdCBjbGVhcnMgdGhlIGVudHJ5LlxuICBwcml2YXRlIF9hcHBseUxpc3RUaWxlKGxpc3Q6IFJlcG9ydENvbXBvbmVudCwgdGlsZTogUmVwb3J0VGlsZVN0YXRlKTogdm9pZCB7XG4gICAgY29uc3Qgc29ydCA9IHRpbGUuc29ydDtcblxuICAgIGlmIChzb3J0Py5jb2x1bW4gJiYgdGhpcy5fc29ydGFibGVDb2x1bW5zKGxpc3QpLmluY2x1ZGVzKHNvcnQuY29sdW1uKSkge1xuICAgICAgaWYgKHNhbWVTb3J0KHNvcnQsIGxpc3RTb3J0VGVybXMobGlzdC5jb25maWcpWzBdID8/IG51bGwpKSB7XG4gICAgICAgIHRoaXMuX2xpc3RTb3J0cy5kZWxldGUobGlzdC5pZCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLl9saXN0U29ydHMuc2V0KGxpc3QuaWQsIHsgLi4uc29ydCB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHRpbGUuc2VhcmNoID09PSAnc3RyaW5nJykge1xuICAgICAgY29uc3Qgc2VhcmNoID0gbGlzdFNlYXJjaFRleHQodGlsZS5zZWFyY2gpO1xuXG4gICAgICBpZiAoc2VhcmNoICYmIHRoaXMubGlzdFNlYXJjaGFibGUobGlzdCkpIHtcbiAgICAgICAgdGhpcy5fbGlzdFNlYXJjaGVzLnNldChsaXN0LmlkLCBzZWFyY2gpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fbGlzdFNlYXJjaGVzLmRlbGV0ZShsaXN0LmlkKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheSh0aWxlLmhpZGRlbikpIHtcbiAgICAgIGNvbnN0IGhpZGRlbiA9IGxpc3RIaWRkZW5Db2x1bW5zKGxpc3QuY29uZmlnLCB0aWxlLmhpZGRlbik7XG4gICAgICBjb25zdCBuZXh0ID0gbmV3IE1hcCh0aGlzLmxpc3RIaWRkZW4oKSk7XG5cbiAgICAgIGlmIChoaWRkZW4ubGVuZ3RoKSB7XG4gICAgICAgIG5leHQuc2V0KGxpc3QuaWQsIGhpZGRlbik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuZXh0LmRlbGV0ZShsaXN0LmlkKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5saXN0SGlkZGVuLnNldChuZXh0KTtcbiAgICB9XG4gIH1cblxuICAvLyBPbmUgY2hhcnQncyBkcmlsbCBwYXRoOyBhbiBlbXB0eSBwYXRoIGlzIHRoZSBjaGFydCdzIHRvcC5cbiAgcHJpdmF0ZSBfc2V0RHJpbGxQYXRoKGNvbXBvbmVudElkOiBudW1iZXIsIHBhdGg6IHJlYWRvbmx5IFJlcG9ydERyaWxsU3RlcFtdKTogdm9pZCB7XG4gICAgY29uc3QgbmV4dCA9IG5ldyBNYXAodGhpcy5fZHJpbGxzKCkpO1xuXG4gICAgaWYgKHBhdGgubGVuZ3RoKSB7XG4gICAgICBuZXh0LnNldChjb21wb25lbnRJZCwgcGF0aCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5leHQuZGVsZXRlKGNvbXBvbmVudElkKTtcbiAgICB9XG5cbiAgICB0aGlzLl9kcmlsbHMuc2V0KG5leHQpO1xuICB9XG5cbiAgLy8gVGhlIHBhZ2UgYSBsYXllciBuYW1lcywgd2hlbiB0aGUgcmVwb3J0IGhhcyBpdC5cbiAgcHJpdmF0ZSBfYXBwbHlQYWdlKHBhZ2VJZDogbnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZCk6IHZvaWQge1xuICAgIGlmIChwYWdlSWQgJiYgKHRoaXMuX3JlcG9ydCgpPy5wYWdlcyA/PyBbXSkuc29tZSgocGFnZSkgPT4gcGFnZS5pZCA9PT0gcGFnZUlkKSkge1xuICAgICAgdGhpcy5fcGFnZUlkLnNldChwYWdlSWQpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEFmdGVyIGFwcGx5KCkgb3IgcmVzZXRUb0Jhc2UoKTogZXZlcnkgYmFyIGFuZCB0aWxlIHJlcGFpbnRzLCBhbmQgdGhlXG4gIC8vIHRpbWUtc2VyaWVzIGNoYXJ0cyByZWZldGNoIHdoZW4gdGhlIGdyYWluIG1vdmVkLlxuICBwcml2YXRlIF9ub3RpZnlBcHBsaWVkKGZyZXF1ZW5jeTogQ2hhcnRHcmFudWxhcml0eSB8IG51bGwpOiB2b2lkIHtcbiAgICB0aGlzLl9zdGF0ZVZlcnNpb24udXBkYXRlKCh2ZXJzaW9uKSA9PiB2ZXJzaW9uICsgMSk7XG4gICAgdGhpcy5fY2hhbmdlZCQubmV4dChudWxsKTtcblxuICAgIGlmIChmcmVxdWVuY3kgIT09IHRoaXMuX2ZyZXF1ZW5jeSkge1xuICAgICAgdGhpcy5fZnJlcXVlbmN5Q2hhbmdlZCQubmV4dCgpO1xuICAgIH1cblxuICAgIHRoaXMuX3N0YXRlQ2hhbmdlZCQubmV4dCgpO1xuICB9XG5cbiAgLy8gVGhlIHRpbGVzIG9mIHRoZSByZXBvcnQgaW5pdCgpIGxhc3QgcmVhZC5cbiAgcHJpdmF0ZSBfdGlsZXMoKTogUmVwb3J0Q29tcG9uZW50W10ge1xuICAgIGNvbnN0IHJlcG9ydCA9IHRoaXMuX3JlcG9ydCgpO1xuXG4gICAgcmV0dXJuIHJlcG9ydFxuICAgICAgPyByZXBvcnRDb21wb25lbnRzKHJlcG9ydCkuZmlsdGVyKGlzVGlsZSlcbiAgICAgIDogW107XG4gIH1cblxuICBwcml2YXRlIF9pc0NoYXJ0KGNvbXBvbmVudElkOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fdGlsZXMoKVxuICAgICAgLnNvbWUoKGNvbXBvbmVudCkgPT4gY29tcG9uZW50LmlkID09PSBjb21wb25lbnRJZCAmJiBjb21wb25lbnQudHlwZSA9PT0gJ2NoYXJ0Jyk7XG4gIH1cblxuICAvLyBLZWVwcyB0aGUgdmlldyBzdGF0ZSB0byB3aGF0IHRoZSByZXBvcnQgKHJlKWxvYWRlZCBieSBpbml0KCkgc3RpbGwgaGFzOlxuICAvLyBkcmlsbCBwYXRocyBvbiBjaGFydHMgaXQgc3RpbGwgaGFzLCB0aGUgcGFnZSB3aGlsZSBpdCBoYXMgaXQsIGFuZCB0aGVcbiAgLy8gYmFzZSB0byB3aGF0IHRoZSBzY3JlZW4gY2FuIHN0aWxsIHNob3cgKF9wcnVuZUJhc2UpLiBPbiBhbm90aGVyIHJlcG9ydCBpdFxuICAvLyBzdGFydHMgYWdhaW46IG5vIG9wZW4gdmlldywgbWF0Y2ggJ2FsbCcsIG5vIGRyaWxsIGFuZCBub3RoaW5nIHRlbXBvcmFyeS5cbiAgcHJpdmF0ZSBfcHJ1bmVWaWV3U3RhdGUocmVwb3J0OiBSZXBvcnQsIHByZXZpb3VzR3JvdXBzOiBSZWFkb25seU1hcDxudW1iZXIsIFJlcG9ydEZpbHRlckdyb3VwPik6IHZvaWQge1xuICAgIGlmICh0aGlzLl9yZXBvcnQoKT8uaWQgIT09IHJlcG9ydC5pZCkge1xuICAgICAgdGhpcy5fYmFzZUNvbmZpZy5zZXQobnVsbCk7XG4gICAgICB0aGlzLl9tYXRjaC5zZXQoJ2FsbCcpO1xuICAgICAgdGhpcy5fcGFnZUlkLnNldChudWxsKTtcbiAgICAgIHRoaXMuX2RyaWxscy5zZXQobmV3IE1hcCgpKTtcbiAgICAgIHRoaXMuX3RlbXBvcmFyeS5zZXQoZW1wdHlUZW1wb3JhcnlTdGF0ZSgpKTtcbiAgICB9XG5cbiAgICB0aGlzLl9yZXBvcnQuc2V0KHJlcG9ydCk7XG4gICAgdGhpcy5fZHJpbGxzLnNldChuZXcgTWFwKFsuLi50aGlzLl9kcmlsbHMoKV1cbiAgICAgIC5maWx0ZXIoKFtjb21wb25lbnRJZF0pID0+IHRoaXMuX2lzQ2hhcnQoY29tcG9uZW50SWQpKSkpO1xuXG4gICAgaWYgKHRoaXMuX3BhZ2VJZCgpICYmICEocmVwb3J0LnBhZ2VzID8/IFtdKS5zb21lKChwYWdlKSA9PiBwYWdlLmlkID09PSB0aGlzLl9wYWdlSWQoKSkpIHtcbiAgICAgIHRoaXMuX3BhZ2VJZC5zZXQobnVsbCk7XG4gICAgfVxuXG4gICAgdGhpcy5fcHJ1bmVCYXNlKHByZXZpb3VzR3JvdXBzKTtcbiAgfVxuXG4gIC8vIEtlZXBzIHRoZSBiYXNlIHRvIHdoYXQgdGhlIHNjcmVlbiBjYW4gc3RpbGwgc2hvdywgYnkgdGhlIHJ1bGVzIHRoZSBsaXZlXG4gIC8vIHN0YXRlIGlzIHBydW5lZCBieSAoX3BydW5lLCBfc2VlZCBhbmQgdGhlIGRyaWxsIHBydW5pbmcgYWJvdmUpLCBzbyBhblxuICAvLyBlZGl0IG9mIHRoZSByZXBvcnQgYWxvbmUgbmV2ZXIgcmVhZHMgYXMgJyhlZGl0ZWQpJy4gQSBncm91cCB3aG9zZVxuICAvLyBhdXRob3JlZCBkZWZhdWx0IGNoYW5nZWQgbGVhdmVzIHRoZSBiYXNlIGFuZCBmb2xsb3dzIHRoZSBuZXcgZGVmYXVsdCxcbiAgLy8gYXMgdGhlIGxpdmUgdmFsdWUgZG9lcyAoX3NlZWQgcmUtc2VlZHMgaXQpOyBzbyBkb2VzIGEgZ3JvdXAgdGhlIHJlcG9ydFxuICAvLyBubyBsb25nZXIgaGFzLiBFYWNoIHRpbGUga2VlcHMgb25seSB0aGUgc3RhdGUgaXRzIGNvbXBvbmVudCBjYW4gc3RpbGxcbiAgLy8gdGFrZSAoX2Jhc2VUaWxlKS5cbiAgcHJpdmF0ZSBfcHJ1bmVCYXNlKHByZXZpb3VzR3JvdXBzOiBSZWFkb25seU1hcDxudW1iZXIsIFJlcG9ydEZpbHRlckdyb3VwPik6IHZvaWQge1xuICAgIGNvbnN0IGJhc2UgPSB0aGlzLl9iYXNlQ29uZmlnKCk7XG4gICAgaWYgKCFiYXNlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZ3JvdXBzID0gT2JqZWN0LmZyb21FbnRyaWVzKE9iamVjdC5lbnRyaWVzKGJhc2UuZ3JvdXBzID8/IHt9KVxuICAgICAgLmZpbHRlcigoW2dyb3VwSWRdKSA9PiB7XG4gICAgICAgIGNvbnN0IGdyb3VwID0gdGhpcy5fZ3JvdXBzLmdldChOdW1iZXIoZ3JvdXBJZCkpO1xuXG4gICAgICAgIHJldHVybiAhIWdyb3VwXG4gICAgICAgICAgJiYgc2FtZURlZmF1bHQocHJldmlvdXNHcm91cHMuZ2V0KGdyb3VwLmlkKT8uY29uZmlnPy5kZWZhdWx0ID8/IG51bGwsIGdyb3VwLmNvbmZpZz8uZGVmYXVsdCA/PyBudWxsKTtcbiAgICAgIH0pKTtcblxuICAgIGNvbnN0IHRpbGVzID0gT2JqZWN0LmZyb21FbnRyaWVzKE9iamVjdC5lbnRyaWVzKGJhc2UudGlsZXMgPz8ge30pXG4gICAgICAubWFwKChbY29tcG9uZW50SWQsIHRpbGVdKSA9PiBbY29tcG9uZW50SWQsIHRoaXMuX2Jhc2VUaWxlKE51bWJlcihjb21wb25lbnRJZCksIHRpbGUpXSBhcyBjb25zdClcbiAgICAgIC5maWx0ZXIoKFssIHRpbGVdKSA9PiBPYmplY3Qua2V5cyh0aWxlKS5sZW5ndGgpKTtcblxuICAgIGNvbnN0IHBydW5lZDogUmVwb3J0Vmlld0NvbmZpZyA9IHsgLi4uYmFzZSwgZ3JvdXBzIH07XG4gICAgZGVsZXRlIHBydW5lZC50aWxlcztcblxuICAgIGlmIChPYmplY3Qua2V5cyh0aWxlcykubGVuZ3RoKSB7XG4gICAgICBwcnVuZWQudGlsZXMgPSB0aWxlcztcbiAgICB9XG5cbiAgICB0aGlzLl9iYXNlQ29uZmlnLnNldChwcnVuZWQpO1xuICB9XG5cbiAgLy8gQSBiYXNlIHRpbGUncyBzdGF0ZSwga2VwdCB0byB3aGF0IGl0cyBjb21wb25lbnQgY2FuIHN0aWxsIHRha2U6IGEgc29ydFxuICAvLyBvbiBhIGNvbHVtbiB0aGUgbGlzdCBjYW4gc3RpbGwgc29ydCBieSB0aGF0IGlzIG5vdCBub3cgaXRzIGF1dGhvcmVkXG4gIC8vIGZpcnN0IHRlcm0sIGEgc2VhcmNoIHdoaWxlIHRoZSBsaXN0IHNob3dzIHRoZSBib3gsIHRoZSBoaWRkZW4gY29sdW1uc1xuICAvLyB0aGUgbGlzdCBzdGlsbCBoYXMsIGEgZHJpbGwgcGF0aCB3aGlsZSB0aGUgY29tcG9uZW50IGlzIGEgY2hhcnQuXG4gIHByaXZhdGUgX2Jhc2VUaWxlKGNvbXBvbmVudElkOiBudW1iZXIsIHRpbGU6IFJlcG9ydFRpbGVTdGF0ZSk6IFJlcG9ydFRpbGVTdGF0ZSB7XG4gICAgY29uc3Qga2VwdDogUmVwb3J0VGlsZVN0YXRlID0ge307XG4gICAgY29uc3QgbGlzdCA9IHRoaXMuX2xpc3RzLmdldChjb21wb25lbnRJZCk7XG4gICAgY29uc3QgaGlkZGVuID0gbGlzdCAmJiB0aWxlLmhpZGRlbiA/IGxpc3RIaWRkZW5Db2x1bW5zKGxpc3QuY29uZmlnLCB0aWxlLmhpZGRlbikgOiBbXTtcblxuICAgIGlmIChsaXN0ICYmIHRpbGUuc29ydCAmJiB0aGlzLl9zb3J0YWJsZUNvbHVtbnMobGlzdCkuaW5jbHVkZXModGlsZS5zb3J0LmNvbHVtbilcbiAgICAgICYmICFzYW1lU29ydCh0aWxlLnNvcnQsIGxpc3RTb3J0VGVybXMobGlzdC5jb25maWcpWzBdID8/IG51bGwpKSB7XG4gICAgICBrZXB0LnNvcnQgPSB0aWxlLnNvcnQ7XG4gICAgfVxuICAgIGlmIChsaXN0ICYmIHRpbGUuc2VhcmNoICYmIHRoaXMubGlzdFNlYXJjaGFibGUobGlzdCkpIHtcbiAgICAgIGtlcHQuc2VhcmNoID0gdGlsZS5zZWFyY2g7XG4gICAgfVxuICAgIGlmIChoaWRkZW4ubGVuZ3RoKSB7XG4gICAgICBrZXB0LmhpZGRlbiA9IGhpZGRlbjtcbiAgICB9XG4gICAgaWYgKHRpbGUuZHJpbGw/Lmxlbmd0aCAmJiB0aGlzLl9pc0NoYXJ0KGNvbXBvbmVudElkKSkge1xuICAgICAga2VwdC5kcmlsbCA9IHRpbGUuZHJpbGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIGtlcHQ7XG4gIH1cblxuICAvLyBBIHNlbGVjdCdzIHZhbHVlcyB0byBsZWF2ZSBvdXQgKG9ubHkgd2hlbiBpdCBrZWVwcyBub25lKSBhbmQgYSBudW1iZXJcbiAgLy8gcmFuZ2UncyBlbmRzLCBhbiBvcGVuIGVuZCBsZWZ0IG91dCBhbmQgMCBrZXB0LCB3cml0dGVuIG9udG8gYGZpZWxkc2AuXG4gIHByaXZhdGUgX3Jlc29sdmVFeGNsdWRlQW5kUmFuZ2UodmFsdWU6IEZpbHRlckdyb3VwVmFsdWUsIGZpZWxkczogT21pdDxSZXNvbHZlZEZpbHRlclZhbHVlLCAnZmlsdGVySWQnPik6IHZvaWQge1xuICAgIGlmICh2YWx1ZS5leGNsdWRlVmFsdWVzPy5sZW5ndGggJiYgIWZpZWxkcy52YWx1ZXMpIHtcbiAgICAgIGZpZWxkcy5leGNsdWRlVmFsdWVzID0gdmFsdWUuZXhjbHVkZVZhbHVlcztcbiAgICB9XG5cbiAgICBjb25zdCBtaW4gPSBmaW5pdGVOdW1iZXIodmFsdWUubWluKTtcbiAgICBjb25zdCBtYXggPSBmaW5pdGVOdW1iZXIodmFsdWUubWF4KTtcblxuICAgIGlmIChtaW4gIT09IHVuZGVmaW5lZCkge1xuICAgICAgZmllbGRzLm1pbiA9IG1pbjtcbiAgICB9XG4gICAgaWYgKG1heCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBmaWVsZHMubWF4ID0gbWF4O1xuICAgIH1cbiAgfVxuXG4gIC8vIEFuIGF1dGhvcmVkIGRlZmF1bHQgdGhhdCBsZWF2ZXMgc2VsZWN0IHZhbHVlcyBvdXQsIG9yIGEgbnVtYmVyIHJhbmdlJ3NcbiAgLy8gZW5kcyAoMCBrZXB0KSwgYXMgYSBzZXNzaW9uIHZhbHVlOyBudWxsIHdoZW4gaXQgaG9sZHMgbmVpdGhlci5cbiAgcHJpdmF0ZSBfZXhjbHVkZU9yUmFuZ2VEZWZhdWx0KGdyb3VwRGVmYXVsdDogRmlsdGVyR3JvdXBEZWZhdWx0KTogRmlsdGVyR3JvdXBWYWx1ZSB8IG51bGwge1xuICAgIGlmIChncm91cERlZmF1bHQuZXhjbHVkZVZhbHVlcz8ubGVuZ3RoKSB7XG4gICAgICByZXR1cm4geyBleGNsdWRlVmFsdWVzOiBncm91cERlZmF1bHQuZXhjbHVkZVZhbHVlcyB9O1xuICAgIH1cblxuICAgIGNvbnN0IG1pbiA9IGZpbml0ZU51bWJlcihncm91cERlZmF1bHQubWluKTtcbiAgICBjb25zdCBtYXggPSBmaW5pdGVOdW1iZXIoZ3JvdXBEZWZhdWx0Lm1heCk7XG5cbiAgICBpZiAobWluID09PSB1bmRlZmluZWQgJiYgbWF4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAuLi4obWluICE9PSB1bmRlZmluZWQgPyB7IG1pbiB9IDoge30pLFxuICAgICAgLi4uKG1heCAhPT0gdW5kZWZpbmVkID8geyBtYXggfSA6IHt9KSxcbiAgICB9O1xuICB9XG5cbiAgLy8gQ291bnRzIGEgcmVzZXQgZm9yIGVhY2ggbGlzdCB3aG9zZSBzb3J0IGlzIG5vdCB0aGUgb25lIGl0IGhhZCAoYGJlZm9yZWAsXG4gIC8vIHRoZSBzb3J0cyBieSBsaXN0IGJlZm9yZSB0aGUgcmVzZXQpLiBBIHNvcnQgYSBsaXN0IGxvc3QgYW5kIG9uZSBpdFxuICAvLyBnYWluZWQgYm90aCBjb3VudDsgdGhlIGF1dGhvcmVkIHNvcnQgaXMgbm8gZW50cnkgZWl0aGVyIHNpZGUuXG4gIHByaXZhdGUgX2NvdW50U29ydFJlc2V0cyhiZWZvcmU6IFJlYWRvbmx5TWFwPG51bWJlciwgUmVwb3J0U29ydD4pOiB2b2lkIHtcbiAgICBjb25zdCBtb3ZlZCA9IFsuLi5uZXcgU2V0KFsuLi5iZWZvcmUua2V5cygpLCAuLi50aGlzLl9saXN0U29ydHMua2V5cygpXSldXG4gICAgICAuZmlsdGVyKChjb21wb25lbnRJZCkgPT4ge1xuICAgICAgICBjb25zdCB3YXMgPSBiZWZvcmUuZ2V0KGNvbXBvbmVudElkKTtcbiAgICAgICAgY29uc3Qgbm93ID0gdGhpcy5fbGlzdFNvcnRzLmdldChjb21wb25lbnRJZCkgPz8gbnVsbDtcblxuICAgICAgICByZXR1cm4gd2FzID8gIXNhbWVTb3J0KHdhcywgbm93KSA6IG5vdyAhPT0gbnVsbDtcbiAgICAgIH0pO1xuXG4gICAgaWYgKCFtb3ZlZC5sZW5ndGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBjb3VudHMgPSBuZXcgTWFwKHRoaXMuX2xpc3RTb3J0UmVzZXRzKCkpO1xuICAgIG1vdmVkLmZvckVhY2goKGNvbXBvbmVudElkKSA9PiBjb3VudHMuc2V0KGNvbXBvbmVudElkLCAoY291bnRzLmdldChjb21wb25lbnRJZCkgPz8gMCkgKyAxKSk7XG4gICAgdGhpcy5fbGlzdFNvcnRSZXNldHMuc2V0KGNvdW50cyk7XG4gIH1cbn1cbiJdfQ==