ag-studio-angular 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,183 @@
1
+ # Angular Embedded Analytics
2
+
3
+ <div align="center">
4
+ <picture>
5
+ <source media="(prefers-color-scheme: dark)" srcset="https://ag-grid.com/studio/images/ag-studio-logo-dark.svg"/>
6
+ <source media="(prefers-color-scheme: light)" srcset="https://ag-grid.com/studio/images/ag-studio-logo.svg"/>
7
+ <img width="100%" alt="AG Studio Logo" src="https://ag-grid.com/studio/images/ag-studio-logo.svg"/>
8
+ </picture>
9
+ <div align="center">
10
+ <h4><a href="https://ag-grid.com/studio/">Website</a> · <a href="https://ag-grid.com/studio/angular/overview/">Documentation</a> · <a href="https://ag-grid.com/studio/example/">Live Demo</a></h4>
11
+ </div>
12
+ <br>
13
+ <a href="https://www.npmjs.com/package/ag-studio-angular">
14
+ <img src="https://img.shields.io/npm/v/ag-studio-angular?style=for-the-badge" alt="NPM Version">
15
+ </a>
16
+ <a href="https://www.npmjs.com/package/ag-studio-angular">
17
+ <img src="https://img.shields.io/npm/dm/ag-studio-angular?style=for-the-badge" alt="NPM Downloads">
18
+ </a>
19
+ <br><br>
20
+ <!-- START MAIN DESCRIPTION -->
21
+ <p><strong><a href="https://ag-grid.com/studio/angular/overview/"><img src="https://ag-grid.com/images/fw-logos/angular.svg" height="16" width="16" alt="Angular Logo"> AG Studio</a></strong> is an <strong>Angular</strong> Embedded Analytics component for creating dashboards, built on top of <a href="https://ag-grid.com">AG Grid</a> and <a href="https://ag-grid.com/charts">AG Charts</a>.</p>
22
+ <!-- END MAIN DESCRIPTION -->
23
+ <br>
24
+ </div>
25
+
26
+ <picture>
27
+ <source srcset="https://ag-grid.com/studio/images/studio-footer.png" media="(prefers-color-scheme: light)">
28
+ <source srcset="https://ag-grid.com/studio/images/studio-footer-dark.png" media="(prefers-color-scheme: dark)">
29
+ <img src="https://ag-grid.com/studio/images/studio-footer.png" alt="AG Studio Preview">
30
+ </picture>
31
+ <div align="right">
32
+ <a href="https://ag-grid.com/studio/example/"><br><img alt="Live Demo" src="https://img.shields.io/badge/ag--grid.com%2Fstudio-Live%20Demo-blue?style=for-the-badge"></a>
33
+ </div>
34
+
35
+ ## Overview
36
+
37
+ AG Studio is an embedded analytics component that lets analysts build interactive dashboards on top of your data. Add a single component to your application, configure your data source and get drag-and-drop report building with advanced cross-filtering, powered by a built-in data engine.
38
+
39
+ ### How it Works
40
+
41
+ Your application owns the surrounding shell: routing, authentication, data fetching, persistence, whilst AG Studio handles everything inside the component boundary: the canvas, widgets, drag-and-drop, and filtering, all powered by a built-in data engine that runs entirely in the browser.
42
+
43
+ Once configured, analysts can use the drag-and-drop UI to create self-serve reports, and end users can then interact with those reports to interrogate their data with cross-filters and page-level filters.
44
+
45
+ You can ship pre-built reports in code so users see a finished dashboard on first load, or let analysts create reports from scratch using the drag-and-drop editor. The entire dashboard state is a single JSON object, so you can save and restore it later.
46
+
47
+ ### Features
48
+
49
+ | Feature | Description |
50
+ | ------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
51
+ | [Drag & Drop Report Builder](https://ag-grid.com/studio/angular/modes-layout/) | Bar charts, line charts, pie charts, grids, KPI tiles, text, and images on a drag-and-drop canvas. Design in **edit mode**, then switch to **view mode** to lock the layout while keeping the dashboard fully interactive. |
52
+ | [Data Engine](https://ag-grid.com/studio/angular/data/) | Provide one or more data sources and the data engine automatically manages joins across tables via relationships, aggregation, filtering, and calculated fields through an expression language. No query layer required. |
53
+ | [Advanced Filtering](https://ag-grid.com/studio/angular/filters/) | Page-level filters, widget-level filters, and cross-filtering between widgets are all built in. Users can filter from the filters panel, from on-canvas filter widgets (list, button, and date), or by clicking data points in charts to cross-filter the rest of the page. |
54
+ | [Theming](https://ag-grid.com/studio/angular/theming/) | Full customisation via the Theming API. Override colours, fonts, spacing, and borders across the Studio UI, grid widgets, and chart widgets independently. Light and dark modes are supported out of the box. |
55
+ | [State Management](https://ag-grid.com/studio/angular/state/) | The entire dashboard state (pages, widgets, layout, and filters) is captured in a single serialisable JSON object. Save and restore state to persist reports, and let users switch between saved reports. |
56
+
57
+ ## Quick Start
58
+
59
+ <!-- START QUICK START DESCRIPTION -->
60
+
61
+ To configure AG Studio, simply provide your data and render the component.
62
+
63
+ <!-- END QUICK START DESCRIPTION -->
64
+
65
+ ### Installation
66
+
67
+ ```sh
68
+ npm install ag-studio-angular
69
+ ```
70
+
71
+ ### Setup
72
+
73
+ **1. Define Your Data**
74
+
75
+ Studio works with arrays of plain objects, where each array becomes a data source:
76
+
77
+ ```ts
78
+ const data = {
79
+ sources: [
80
+ {
81
+ id: 'products',
82
+ data: [
83
+ {
84
+ product_name: 'Printer',
85
+ category: 'Printing & Imaging',
86
+ brand: 'CleanSlate Office',
87
+ list_price: 109.09,
88
+ unit_cost: 92.26,
89
+ },
90
+ {
91
+ product_name: 'Notebook',
92
+ category: 'Paper & Notebooks',
93
+ brand: 'PaperLine',
94
+ list_price: 24.7,
95
+ unit_cost: 14.19,
96
+ },
97
+ {
98
+ product_name: 'Highlighters',
99
+ category: 'Writing Instruments',
100
+ brand: 'PaperLine',
101
+ list_price: 10.34,
102
+ unit_cost: 5.03,
103
+ },
104
+ // ... more rows
105
+ ],
106
+ },
107
+ ],
108
+ };
109
+ ```
110
+
111
+ **2. Add the Component**
112
+
113
+ Import `AgStudio` from `ag-studio-angular` and add it to your component. AG Studio fills the size of its parent, so ensure it has a height and width:
114
+
115
+ ```ts
116
+ import { Component } from '@angular/core';
117
+ import { AgStudio } from 'ag-studio-angular';
118
+
119
+ @Component({
120
+ selector: 'app-dashboard',
121
+ standalone: true,
122
+ imports: [AgStudio],
123
+ template: `
124
+ <div style="height: 100%; width: 100%">
125
+ <ag-studio [data]="data" mode="edit" />
126
+ </div>
127
+ `,
128
+ })
129
+ export class DashboardComponent {
130
+ data = data;
131
+ }
132
+ ```
133
+
134
+ That's it — users can now build reports using the drag-and-drop editor.
135
+
136
+ > **Note:** For more information on building dashboards with AG Studio, refer to our [Quick Start](https://ag-grid.com/studio/angular/quick-start/) guide or step through the full [Tutorial](https://ag-grid.com/studio/angular/tutorial/).
137
+
138
+ ## User Guides
139
+
140
+ Our [User Guides](https://ag-grid.com/studio/angular/user-interface/) contain comprehensive guides to help users understand how to use AG Studio.
141
+
142
+ ## Support
143
+
144
+ AG Studio customers have access to dedicated support via [ZenDesk](https://ag-grid.zendesk.com/hc/en-us), which is monitored by our engineering teams.
145
+
146
+ ## License
147
+
148
+ `ag-studio` has a **Commercial** license. See the [LICENSE file](./LICENSE.html) for more info.
149
+
150
+ [Request a free 45-day enterprise trial](https://ag-grid.com/studio/license-pricing/?tab=trial) to explore the full enterprise capabilities of AG Studio with no restrictions or watermarks.
151
+
152
+ <div><h2><img vertical-align="middle" width="32" height="32" src="https://ag-grid.com/images/ag-logos/svg-logos/AG-BrandMark_Light-Theme.svg" alt="AG Grid Logo">&nbsp;AG Grid</h2></div>
153
+
154
+ AG Studio is built on top of [AG Grid](https://www.ag-grid.com/) — the best JavaScript Data Grid in the world. If you need a standalone data grid with sorting, filtering, grouping, pivoting, and more, check out [AG Grid Repo](https://github.com/ag-grid/ag-grid).
155
+
156
+ <picture>
157
+ <source srcset="https://github.com/ag-grid/ag-grid/blob/latest/readme-assets/kitchen-sink-demo-light.gif?raw=true" media="(prefers-color-scheme: light)">
158
+ <source srcset="https://github.com/ag-grid/ag-grid/blob/latest/readme-assets/kitchen-sink-demo-dark.gif?raw=true" media="(prefers-color-scheme: dark)">
159
+ <img src="https://github.com/ag-grid/ag-grid/blob/latest/readme-assets/kitchen-sink-demo-light.gif?raw=true" alt="High Performance Demo">
160
+ </picture>
161
+
162
+ <div><h2><img vertical-align="middle" width="32" height="32" src="https://ag-grid.com/images/ag-logos/svg-logos/AG-BrandMark_Light-Theme.svg" alt="AG Charts Logo">&nbsp;AG Charts</h2></div>
163
+
164
+ AG Studio is built on top of [AG Charts](https://www.ag-grid.com/charts/) — the best JavaScript Charting library in the world. If you need standalone charts with bar, line, pie, scatter, treemap, and more, check out [AG Charts](https://github.com/ag-grid/ag-charts).
165
+
166
+ <picture>
167
+ <source media="(prefers-color-scheme: dark)" srcset="https://github.com/ag-grid/ag-charts/blob/latest/packages/ag-charts-website/public/images/readme-assets/gallery-dark.gif?raw=true"/>
168
+ <source media="(prefers-color-scheme: light)" srcset="https://github.com/ag-grid/ag-charts/blob/latest/packages/ag-charts-website/public/images/readme-assets/gallery.gif?raw=true"/>
169
+ <img width="100%" alt="Preview of AG Charts JavaScript Charting Examples" src="https://github.com/ag-grid/ag-charts/blob/latest/packages/ag-charts-website/public/images/readme-assets/gallery.gif?raw=true"/>
170
+ </picture>
171
+
172
+ <div align="center">
173
+
174
+ <hr/>
175
+
176
+ <strong>Follow us to keep up to date with all the latest news from AG Studio:</strong>
177
+
178
+ <a href="https://x.com/ag_grid"><img src="https://img.shields.io/badge/-X%20(Twitter)-black?style=for-the-badge&logo=x" alt="Twitter" height="36"></a>
179
+ <a href="https://www.linkedin.com/company/ag-grid/"><img src="https://img.shields.io/badge/-LinkedIn-blue?style=for-the-badge&logo=linkedin" alt="LinkedIn" height="36"></a>
180
+ <a href="https://www.youtube.com/c/ag-grid"><img src="https://img.shields.io/badge/-YouTube-red?style=for-the-badge&logo=youtube" alt="YouTube" height="36"></a>
181
+ <a href="https://blog.ag-grid.com"><img src="https://img.shields.io/badge/-Blog-grey?style=for-the-badge&logo=rss" alt="Blog" height="36"></a>
182
+
183
+ </div>
@@ -4,12 +4,16 @@
4
4
  import { Component, EventEmitter, Input, Output, ViewEncapsulation, booleanAttribute, } from '@angular/core';
5
5
  import { _BOOLEAN_MIXED_STUDIO_PROPERTIES, _combineAttributesAndStudioProperties, _createStudio, _processPropertyChanges, } from 'ag-studio';
6
6
  // @END_IMPORTS@
7
+ import { AngularFrameworkComponentWrapper } from './angularFrameworkComponentWrapper';
7
8
  import { AngularFrameworkOverrides } from './angularFrameworkOverrides';
8
9
  import * as i0 from "@angular/core";
9
10
  import * as i1 from "./angularFrameworkOverrides";
11
+ import * as i2 from "./angularFrameworkComponentWrapper";
10
12
  export class AgStudio {
11
- constructor(elementDef, _angularFrameworkOverrides) {
13
+ constructor(elementDef, _viewContainerRef, _angularFrameworkOverrides, _frameworkCompWrapper) {
14
+ this._viewContainerRef = _viewContainerRef;
12
15
  this._angularFrameworkOverrides = _angularFrameworkOverrides;
16
+ this._frameworkCompWrapper = _frameworkCompWrapper;
13
17
  this._initialised = false;
14
18
  this._destroyed = false;
15
19
  // in order to ensure firing of apiReady is deterministic
@@ -114,15 +118,33 @@ export class AgStudio {
114
118
  */
115
119
  this.layout = undefined;
116
120
  /** AI Assistant configuration.
121
+ *
122
+ * NOTE: The **AI Assistant** is an experimental feature. Behaviour will be
123
+ * slightly different depending on the LLM being used, and results can vary across queries.
124
+ *
117
125
  * @initial
118
126
  */
119
127
  this.ai = undefined;
120
- /** Overrides for the layout and widget configs.
128
+ /** Data-layer configuration. Controls behaviours such as export row limits.
129
+ */
130
+ this.dataOptions = undefined;
131
+ /** @deprecated v1.1 Use `widgets` to customise the widget configurations and available widgets,
132
+ * and `page` to customise the page setup form.
133
+ *
134
+ * Overrides for the layout and widget configs.
121
135
  */
122
136
  this.overrides = undefined;
123
137
  /** Configure which panels are displayed and on which side.
124
138
  */
125
139
  this.panels = undefined;
140
+ /** Configure page (e.g. page setup form in page tab of edit panel).
141
+ */
142
+ this.page = undefined;
143
+ this.widgets = undefined;
144
+ /** Custom components (e.g. custom widget components) keyed by ID.
145
+ * Used to share components which can then be referenced directly by key in the definitions.
146
+ */
147
+ this.components = undefined;
126
148
  /** State has been updated.
127
149
  */
128
150
  this.stateUpdated = new EventEmitter();
@@ -146,6 +168,7 @@ export class AgStudio {
146
168
  ngAfterViewInit() {
147
169
  // Run the setup outside of angular so all the event handlers that are created do not trigger change detection
148
170
  this._angularFrameworkOverrides.runOutsideAngular(() => {
171
+ this._frameworkCompWrapper.setViewContainerRef(this._viewContainerRef, this._angularFrameworkOverrides);
149
172
  // Get all the inputs that are valid AgStudioProperties
150
173
  const studioPropertiesKeys = Object.keys(this).filter((key) => !(key.startsWith('_') ||
151
174
  key == 'studioProperties' ||
@@ -162,6 +185,9 @@ export class AgStudio {
162
185
  frameworkOverrides: this._angularFrameworkOverrides,
163
186
  setThemeOnRootDiv: true,
164
187
  modules: this.modules,
188
+ providedBeanInstances: {
189
+ frameworkCompWrapper: this._frameworkCompWrapper,
190
+ },
165
191
  };
166
192
  const api = _createStudio(this._nativeElement, mergedStudioProperties, studioParams);
167
193
  if (api) {
@@ -228,8 +254,8 @@ export class AgStudio {
228
254
  }
229
255
  }
230
256
  }
231
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AgStudio, deps: [{ token: i0.ElementRef }, { token: i1.AngularFrameworkOverrides }], target: i0.ɵɵFactoryTarget.Component }); }
232
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "18.2.14", type: AgStudio, isStandalone: true, selector: "ag-studio", inputs: { studioProperties: "studioProperties", modules: "modules", tabIndex: "tabIndex", enableRtl: ["enableRtl", "enableRtl", booleanAttribute], popupParent: "popupParent", theme: "theme", loadThemeGoogleFonts: ["loadThemeGoogleFonts", "loadThemeGoogleFonts", booleanAttribute], themeCssLayer: "themeCssLayer", styleNonce: "styleNonce", themeStyleContainer: "themeStyleContainer", getDocument: "getDocument", suppressTouch: ["suppressTouch", "suppressTouch", booleanAttribute], localeText: "localeText", getLocaleText: "getLocaleText", studioId: "studioId", context: "context", initialState: "initialState", data: "data", mode: "mode", layout: "layout", ai: "ai", overrides: "overrides", panels: "panels" }, outputs: { stateUpdated: "stateUpdated", apiReady: "apiReady", studioReady: "studioReady", errorRaised: "errorRaised" }, providers: [AngularFrameworkOverrides], usesOnChanges: true, ngImport: i0, template: '', isInline: true, encapsulation: i0.ViewEncapsulation.None }); }
257
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AgStudio, deps: [{ token: i0.ElementRef }, { token: i0.ViewContainerRef }, { token: i1.AngularFrameworkOverrides }, { token: i2.AngularFrameworkComponentWrapper }], target: i0.ɵɵFactoryTarget.Component }); }
258
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "18.2.14", type: AgStudio, isStandalone: true, selector: "ag-studio", inputs: { studioProperties: "studioProperties", modules: "modules", tabIndex: "tabIndex", enableRtl: ["enableRtl", "enableRtl", booleanAttribute], popupParent: "popupParent", theme: "theme", loadThemeGoogleFonts: ["loadThemeGoogleFonts", "loadThemeGoogleFonts", booleanAttribute], themeCssLayer: "themeCssLayer", styleNonce: "styleNonce", themeStyleContainer: "themeStyleContainer", getDocument: "getDocument", suppressTouch: ["suppressTouch", "suppressTouch", booleanAttribute], localeText: "localeText", getLocaleText: "getLocaleText", studioId: "studioId", context: "context", initialState: "initialState", data: "data", mode: "mode", layout: "layout", ai: "ai", dataOptions: "dataOptions", overrides: "overrides", panels: "panels", page: "page", widgets: "widgets", components: "components" }, outputs: { stateUpdated: "stateUpdated", apiReady: "apiReady", studioReady: "studioReady", errorRaised: "errorRaised" }, providers: [AngularFrameworkOverrides, AngularFrameworkComponentWrapper], usesOnChanges: true, ngImport: i0, template: '', isInline: true, encapsulation: i0.ViewEncapsulation.None }); }
233
259
  }
234
260
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AgStudio, decorators: [{
235
261
  type: Component,
@@ -237,11 +263,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
237
263
  selector: 'ag-studio',
238
264
  standalone: true,
239
265
  template: '',
240
- providers: [AngularFrameworkOverrides],
266
+ providers: [AngularFrameworkOverrides, AngularFrameworkComponentWrapper],
241
267
  // tell angular we don't want view encapsulation, we don't want a shadow root
242
268
  encapsulation: ViewEncapsulation.None,
243
269
  }]
244
- }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.AngularFrameworkOverrides }], propDecorators: { studioProperties: [{
270
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ViewContainerRef }, { type: i1.AngularFrameworkOverrides }, { type: i2.AngularFrameworkComponentWrapper }], propDecorators: { studioProperties: [{
245
271
  type: Input
246
272
  }], modules: [{
247
273
  type: Input
@@ -286,10 +312,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
286
312
  type: Input
287
313
  }], ai: [{
288
314
  type: Input
315
+ }], dataOptions: [{
316
+ type: Input
289
317
  }], overrides: [{
290
318
  type: Input
291
319
  }], panels: [{
292
320
  type: Input
321
+ }], page: [{
322
+ type: Input
323
+ }], widgets: [{
324
+ type: Input
325
+ }], components: [{
326
+ type: Input
293
327
  }], stateUpdated: [{
294
328
  type: Output
295
329
  }], apiReady: [{
@@ -309,9 +343,8 @@ function getValueOrCoercedValue(key, valueToUse) {
309
343
  if (booleanMixedStudioProperties.has(key)) {
310
344
  // Handle plain HTML boolean attributes and convert them to boolean values
311
345
  // Also handle the false string case to match Angular boolean attributes
312
- // eslint-disable-next-line sonarjs/no-nested-conditional
313
346
  return valueToUse === '' ? true : valueToUse === 'false' ? false : valueToUse;
314
347
  }
315
348
  return valueToUse;
316
349
  }
317
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWctc3R1ZGlvLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2FnLXN0dWRpby1hbmd1bGFyL3NyYy9saWIvYWctc3R1ZGlvLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx5Q0FBeUM7QUFDekMscUVBQXFFO0FBQ3JFLHNFQUFzRTtBQUN0RSxPQUFPLEVBRUgsU0FBUyxFQUVULFlBQVksRUFDWixLQUFLLEVBR0wsTUFBTSxFQUNOLGlCQUFpQixFQUNqQixnQkFBZ0IsR0FDbkIsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUNILGdDQUFnQyxFQUNoQyxxQ0FBcUMsRUFDckMsYUFBYSxFQUNiLHVCQUF1QixHQUMxQixNQUFNLFdBQVcsQ0FBQztBQW9CbkIsZ0JBQWdCO0FBRWhCLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDOzs7QUFVeEUsTUFBTSxPQUFPLFFBQVE7SUFpQmpCLFlBQ0ksVUFBc0IsRUFDTCwwQkFBcUQ7UUFBckQsK0JBQTBCLEdBQTFCLDBCQUEwQixDQUEyQjtRQWZsRSxpQkFBWSxHQUFHLEtBQUssQ0FBQztRQUNyQixlQUFVLEdBQUcsS0FBSyxDQUFDO1FBRTNCLHlEQUF5RDtRQUNqRCxnQkFBVyxHQUFHLElBQUksQ0FBQztRQUVWLGdCQUFXLEdBQWtCLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7WUFDbEUsSUFBSSxDQUFDLGtCQUFrQixHQUFHLE9BQU8sQ0FBQztRQUN0QyxDQUFDLENBQUMsQ0FBQztRQXFJSCxVQUFVO1FBQ1Y7OztXQUdHO1FBQ2EsYUFBUSxHQUF1QixTQUFTLENBQUM7UUFDekQ7OztXQUdHO1FBQzRDLGNBQVMsR0FBd0IsU0FBUyxDQUFDO1FBQzFGO1dBQ0c7UUFDYSxnQkFBVyxHQUFtQyxTQUFTLENBQUM7UUFDeEU7OztXQUdHO1FBQ2EsVUFBSyxHQUE4QixTQUFTLENBQUM7UUFD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dEIsVUFBVTtzQkFBekIsS0FBSztnQkFJVSxhQUFhO3NCQUE1QixLQUFLO2dCQUlVLFFBQVE7c0JBQXZCLEtBQUs7Z0JBSVUsT0FBTztzQkFBdEIsS0FBSztnQkFJVSxZQUFZO3NCQUEzQixLQUFLO2dCQU1VLElBQUk7c0JBQW5CLEtBQUs7Z0JBSVUsSUFBSTtzQkFBbkIsS0FBSztnQkFHVSxNQUFNO3NCQUFyQixLQUFLO2dCQUlVLEVBQUU7c0JBQWpCLEtBQUs7Z0JBR1UsU0FBUztzQkFBeEIsS0FBSztnQkFHVSxNQUFNO3NCQUFyQixLQUFLO2dCQUlXLFlBQVk7c0JBQTVCLE1BQU07Z0JBSVUsUUFBUTtzQkFBeEIsTUFBTTtnQkFHVSxXQUFXO3NCQUEzQixNQUFNO2dCQUdVLFdBQVc7c0JBQTNCLE1BQU07O0FBS1gsTUFBTSw0QkFBNEIsR0FBRyxJQUFJLEdBQUcsQ0FBUyxnQ0FBZ0MsQ0FBQyxDQUFDO0FBQ3ZGOzs7O0dBSUc7QUFDSCxTQUFTLHNCQUFzQixDQUFDLEdBQVcsRUFBRSxVQUFlO0lBQ3hELElBQUksNEJBQTRCLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDeEMsMEVBQTBFO1FBQzFFLHdFQUF3RTtRQUN4RSx5REFBeUQ7UUFDekQsT0FBTyxVQUFVLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFVBQVUsS0FBSyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDO0lBQ2xGLENBQUM7SUFDRCxPQUFPLFVBQVUsQ0FBQztBQUN0QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgbm8tZHVwbGljYXRlLWltcG9ydHMgKi9cbi8vIEZhbHNlIHBvc2l0aXZlIGxpbnQgZXJyb3IsIEVsZW1lbnRSZWYgYW5kIGNvIGNhbid0IGJlIHR5cGUgaW1wb3J0c1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9jb25zaXN0ZW50LXR5cGUtaW1wb3J0c1xuaW1wb3J0IHtcbiAgICBBZnRlclZpZXdJbml0LFxuICAgIENvbXBvbmVudCxcbiAgICBFbGVtZW50UmVmLFxuICAgIEV2ZW50RW1pdHRlcixcbiAgICBJbnB1dCxcbiAgICBPbkNoYW5nZXMsXG4gICAgT25EZXN0cm95LFxuICAgIE91dHB1dCxcbiAgICBWaWV3RW5jYXBzdWxhdGlvbixcbiAgICBib29sZWFuQXR0cmlidXRlLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB0eXBlIHsgQWdTdHVkaW9BcGksIEFnU3R1ZGlvTW9kdWxlLCBBZ1N0dWRpb1Byb3BlcnRpZXMsIF9TdHVkaW9QYXJhbXMgfSBmcm9tICdhZy1zdHVkaW8nO1xuaW1wb3J0IHtcbiAgICBfQk9PTEVBTl9NSVhFRF9TVFVESU9fUFJPUEVSVElFUyxcbiAgICBfY29tYmluZUF0dHJpYnV0ZXNBbmRTdHVkaW9Qcm9wZXJ0aWVzLFxuICAgIF9jcmVhdGVTdHVkaW8sXG4gICAgX3Byb2Nlc3NQcm9wZXJ0eUNoYW5nZXMsXG59IGZyb20gJ2FnLXN0dWRpbyc7XG4vLyBAU1RBUlRfSU1QT1JUU0BcbmltcG9ydCB0eXBlIHtcbiAgICBBZ0FpQXNzaXN0YW50LFxuICAgIEFnRGF0YUVuZ2luZSxcbiAgICBBZ0RhdGFTb3VyY2VzRGVmaW5pdGlvbixcbiAgICBBZ1BhZ2VMYXlvdXRTdGF0ZSxcbiAgICBBZ1BhbmVsQ29uZmlnLFxuICAgIEFnUmVwb3J0U3RhdGUsXG4gICAgQWdTdHVkaW9BcGlSZWFkeUV2ZW50LFxuICAgIEFnU3R1ZGlvRXJyb3JSYWlzZWRFdmVudCxcbiAgICBBZ1N0dWRpb0dldExvY2FsZVRleHRQYXJhbXMsXG4gICAgQWdTdHVkaW9Mb2NhbGVUZXh0LFxuICAgIEFnU3R1ZGlvTW9kZSxcbiAgICBBZ1N0dWRpb092ZXJyaWRlcyxcbiAgICBBZ1N0dWRpb1JlYWR5RXZlbnQsXG4gICAgQWdTdHVkaW9TdGF0ZVVwZGF0ZWRFdmVudCxcbiAgICBBZ1N0dWRpb1RoZW1lLFxufSBmcm9tICdhZy1zdHVkaW8nO1xuXG4vLyBARU5EX0lNUE9SVFNAXG5cbmltcG9ydCB7IEFuZ3VsYXJGcmFtZXdvcmtPdmVycmlkZXMgfSBmcm9tICcuL2FuZ3VsYXJGcmFtZXdvcmtPdmVycmlkZXMnO1xuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ2FnLXN0dWRpbycsXG4gICAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgICB0ZW1wbGF0ZTogJycsXG4gICAgcHJvdmlkZXJzOiBbQW5ndWxhckZyYW1ld29ya092ZXJyaWRlc10sXG4gICAgLy8gdGVsbCBhbmd1bGFyIHdlIGRvbid0IHdhbnQgdmlldyBlbmNhcHN1bGF0aW9uLCB3ZSBkb24ndCB3YW50IGEgc2hhZG93IHJvb3RcbiAgICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxufSlcbmV4cG9ydCBjbGFzcyBBZ1N0dWRpbyBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uQ2hhbmdlcywgT25EZXN0cm95IHtcbiAgICAvLyBub3QgaW50ZW5kZWQgZm9yIHVzZXIgdG8gaW50ZXJhY3Qgd2l0aC4gc28gcHV0dGluZyBfIGluIHNvIGlmIHVzZXIgZ2V0cyByZWZlcmVuY2VcbiAgICAvLyB0byB0aGlzIG9iamVjdCwgdGhleSBraW5kJ2Ega25vdyBpdCdzIG5vdCBwYXJ0IG9mIHRoZSBhZ3JlZWQgaW50ZXJmYWNlXG4gICAgcHJpdmF0ZSByZWFkb25seSBfbmF0aXZlRWxlbWVudDogYW55O1xuICAgIHByaXZhdGUgX2luaXRpYWxpc2VkID0gZmFsc2U7XG4gICAgcHJpdmF0ZSBfZGVzdHJveWVkID0gZmFsc2U7XG5cbiAgICAvLyBpbiBvcmRlciB0byBlbnN1cmUgZmlyaW5nIG9mIGFwaVJlYWR5IGlzIGRldGVybWluaXN0aWNcbiAgICBwcml2YXRlIF9ob2xkRXZlbnRzID0gdHJ1ZTtcbiAgICBwcml2YXRlIF9yZXNvbHZlRnVsbHlSZWFkeTogKCkgPT4gdm9pZDtcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9mdWxseVJlYWR5OiBQcm9taXNlPHZvaWQ+ID0gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgdGhpcy5fcmVzb2x2ZUZ1bGx5UmVhZHkgPSByZXNvbHZlO1xuICAgIH0pO1xuXG4gICAgLyoqIERhc2ggQXBpIGF2YWlsYWJsZSBhZnRlciBvbkFwaVJlYWR5IGV2ZW50IGhhcyBmaXJlZC4gKi9cbiAgICBwdWJsaWMgYXBpOiBBZ1N0dWRpb0FwaTtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBlbGVtZW50RGVmOiBFbGVtZW50UmVmLFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IF9hbmd1bGFyRnJhbWV3b3JrT3ZlcnJpZGVzOiBBbmd1bGFyRnJhbWV3b3JrT3ZlcnJpZGVzXG4gICAgKSB7XG4gICAgICAgIHRoaXMuX25hdGl2ZUVsZW1lbnQgPSBlbGVtZW50RGVmLm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgIC8vIE5PU09OQVJcbiAgICAgICAgdGhpcy5fZnVsbHlSZWFkeS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIC8vIFJlZ2lzdGVyIHRoZSBzdGF0dXMgZmxhZyByZXNldCBiZWZvcmUgYW55IGV2ZW50cyBhcmUgZmlyZWRcbiAgICAgICAgICAgIC8vIHNvIHRoYXQgd2UgY2FuIHN3YXAgdG8gc3luY2hyb25vdXMgZXZlbnQgZmlyaW5nIGFzIHNvb24gYXMgdGhlIHN0dWRpbyBpcyByZWFkeVxuICAgICAgICAgICAgdGhpcy5faG9sZEV2ZW50cyA9IGZhbHNlO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgICAgIC8vIFJ1biB0aGUgc2V0dXAgb3V0c2lkZSBvZiBhbmd1bGFyIHNvIGFsbCB0aGUgZXZlbnQgaGFuZGxlcnMgdGhhdCBhcmUgY3JlYXRlZCBkbyBub3QgdHJpZ2dlciBjaGFuZ2UgZGV0ZWN0aW9uXG4gICAgICAgIHRoaXMuX2FuZ3VsYXJGcmFtZXdvcmtPdmVycmlkZXMucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgICAgICAgLy8gR2V0IGFsbCB0aGUgaW5wdXRzIHRoYXQgYXJlIHZhbGlkIEFnU3R1ZGlvUHJvcGVydGllc1xuICAgICAgICAgICAgY29uc3Qgc3R1ZGlvUHJvcGVydGllc0tleXMgPSBPYmplY3Qua2V5cyh0aGlzKS5maWx0ZXIoXG4gICAgICAgICAgICAgICAgKGtleSkgPT5cbiAgICAgICAgICAgICAgICAgICAgIShcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleS5zdGFydHNXaXRoKCdfJykgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9PSAnc3R1ZGlvUHJvcGVydGllcycgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9PSAnbW9kdWxlcycgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNba2V5IGFzIGtleW9mIEFnU3R1ZGlvXSBpbnN0YW5jZW9mIEV2ZW50RW1pdHRlclxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBjb25zdCBjb2VyY2VkU3R1ZGlvUHJvcGVydGllcyA9IHt9IGFzIEFnU3R1ZGlvUHJvcGVydGllcztcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IG9mIHN0dWRpb1Byb3BlcnRpZXNLZXlzKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWVUb1VzZSA9IGdldFZhbHVlT3JDb2VyY2VkVmFsdWUoa2V5LCB0aGlzW2tleSBhcyBrZXlvZiBBZ1N0dWRpb10pO1xuICAgICAgICAgICAgICAgIGNvZXJjZWRTdHVkaW9Qcm9wZXJ0aWVzW2tleSBhcyBrZXlvZiBBZ1N0dWRpb1Byb3BlcnRpZXNdID0gdmFsdWVUb1VzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgbWVyZ2VkU3R1ZGlvUHJvcGVydGllcyA9IF9jb21iaW5lQXR0cmlidXRlc0FuZFN0dWRpb1Byb3BlcnRpZXMoXG4gICAgICAgICAgICAgICAgdGhpcy5zdHVkaW9Qcm9wZXJ0aWVzLFxuICAgICAgICAgICAgICAgIGNvZXJjZWRTdHVkaW9Qcm9wZXJ0aWVzLFxuICAgICAgICAgICAgICAgIHN0dWRpb1Byb3BlcnRpZXNLZXlzXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBjb25zdCBzdHVkaW9QYXJhbXM6IF9TdHVkaW9QYXJhbXMgPSB7XG4gICAgICAgICAgICAgICAgZ2xvYmFsTGlzdGVuZXI6IHRoaXMuZ2xvYmFsTGlzdGVuZXIuYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBmcmFtZXdvcmtPdmVycmlkZXM6IHRoaXMuX2FuZ3VsYXJGcmFtZXdvcmtPdmVycmlkZXMsXG4gICAgICAgICAgICAgICAgc2V0VGhlbWVPblJvb3REaXY6IHRydWUsXG4gICAgICAgICAgICAgICAgbW9kdWxlczogdGhpcy5tb2R1bGVzLFxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29uc3QgYXBpID0gX2NyZWF0ZVN0dWRpbyh0aGlzLl9uYXRpdmVFbGVtZW50LCBtZXJnZWRTdHVkaW9Qcm9wZXJ0aWVzLCBzdHVkaW9QYXJhbXMpO1xuICAgICAgICAgICAgaWYgKGFwaSkge1xuICAgICAgICAgICAgICAgIHRoaXMuYXBpID0gYXBpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLl9pbml0aWFsaXNlZCA9IHRydWU7XG5cbiAgICAgICAgICAgIC8vIHNvbWV0aW1lcywgZXNwZWNpYWxseSBpbiBsYXJnZSBjbGllbnQgYXBwcyBhcGlSZWFkeSBjYW4gZmlyZSBiZWZvcmUgbmdBZnRlclZpZXdJbml0XG4gICAgICAgICAgICAvLyB0aGlzIHRpZXMgdGhlc2UgdG9nZXRoZXIgc28gdGhhdCBhcGlSZWFkeSB3aWxsIGFsd2F5cyBmaXJlIGFmdGVyIGFnU3R1ZGlvJ3MgbmdBZnRlclZpZXdJbml0XG4gICAgICAgICAgICAvLyB0aGUgYWN0dWFsIGNvbnRhaW5pbmcgY29tcG9uZW50J3MgbmdBZnRlclZpZXdJbml0IHdpbGwgZmlyZSBqdXN0IGFmdGVyIGFnU3R1ZGlvJ3NcbiAgICAgICAgICAgIHRoaXMuX3Jlc29sdmVGdWxseVJlYWR5KCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBhbnkpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuX2luaXRpYWxpc2VkKSB7XG4gICAgICAgICAgICAvLyBSdW4gdGhlIGNoYW5nZXMgb3V0c2lkZSBvZiBhbmd1bGFyIHNvIGFueSBldmVudCBoYW5kbGVycyB0aGF0IGFyZSBjcmVhdGVkIGRvIG5vdCB0cmlnZ2VyIGNoYW5nZSBkZXRlY3Rpb25cbiAgICAgICAgICAgIHRoaXMuX2FuZ3VsYXJGcmFtZXdvcmtPdmVycmlkZXMucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0dWRpb1Byb3BlcnRpZXM6IEFnU3R1ZGlvUHJvcGVydGllcyA9IHt9O1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGNoYW5nZXMpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gY2hhbmdlc1trZXldO1xuICAgICAgICAgICAgICAgICAgICBzdHVkaW9Qcm9wZXJ0aWVzW2tleSBhcyBrZXlvZiBBZ1N0dWRpb1Byb3BlcnRpZXNdID0gdmFsdWUuY3VycmVudFZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBfcHJvY2Vzc1Byb3BlcnR5Q2hhbmdlcyhzdHVkaW9Qcm9wZXJ0aWVzLCB0aGlzLmFwaSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuX2luaXRpYWxpc2VkKSB7XG4gICAgICAgICAgICAvLyBuZWVkIHRvIGRvIHRoaXMgYmVmb3JlIHRoZSBkZXN0cm95LCBzbyB3ZSBrbm93IG5vdCB0byBlbWl0IGFueSBldmVudHNcbiAgICAgICAgICAgIC8vIHdoaWxlIHRlYXJpbmcgZG93biB0aGUgc3R1ZGlvLlxuICAgICAgICAgICAgdGhpcy5fZGVzdHJveWVkID0gdHJ1ZTtcbiAgICAgICAgICAgIC8vIGNvdWxkIGJlIG51bGwgaWYgc3R1ZGlvIGZhaWxlZCB0byBpbml0aWFsaXNlXG4gICAgICAgICAgICB0aGlzLmFwaT8uZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gd2UnbGwgZW1pdCB0aGUgZW1pdCBpZiBhIHVzZXIgaXMgbGlzdGVuaW5nIGZvciBhIGdpdmVuIGV2ZW50IGVpdGhlciBvbiB0aGUgY29tcG9uZW50IHZpYSBub3JtYWwgYW5ndWxhciBiaW5kaW5nXG4gICAgLy8gb3IgdmlhIHN0dWRpb1Byb3BlcnRpZXNcbiAgICBwcm90ZWN0ZWQgaXNFbWl0dGVyVXNlZChldmVudFR5cGU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCBlbWl0dGVyID0gPEV2ZW50RW1pdHRlcjxhbnk+Pig8YW55PnRoaXMpW2V2ZW50VHlwZV07XG4gICAgICAgIC8vIEZvciBSeEpzIGNvbXBhdGliaWxpdHkgd2UgbmVlZCB0byBjaGVjayBmb3Igb2JzZXJ2ZWQgdjcrIG9yIG9ic2VydmVycyB2NlxuICAgICAgICBjb25zdCBlbWl0dGVyQW55ID0gZW1pdHRlciBhcyBhbnk7XG4gICAgICAgIGNvbnN0IGhhc0VtaXR0ZXIgPSBlbWl0dGVyQW55Py5vYnNlcnZlZCA/PyBlbWl0dGVyQW55Py5vYnNlcnZlcnM/Lmxlbmd0aCA+IDA7XG5cbiAgICAgICAgLy8gYXBpUmVhZHkgPT4gb25BcGlSZWFkeVxuICAgICAgICBjb25zdCBhc0V2ZW50TmFtZSA9IGBvbiR7ZXZlbnRUeXBlLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpfSR7ZXZlbnRUeXBlLnN1YnN0cmluZygxKX1gO1xuICAgICAgICBjb25zdCBoYXNTdHVkaW9Qcm9wZXJ0eUxpc3RlbmVyID0gISF0aGlzLnN0dWRpb1Byb3BlcnRpZXMgJiYgISEodGhpcy5zdHVkaW9Qcm9wZXJ0aWVzIGFzIGFueSlbYXNFdmVudE5hbWVdO1xuXG4gICAgICAgIHJldHVybiBoYXNFbWl0dGVyIHx8IGhhc1N0dWRpb1Byb3BlcnR5TGlzdGVuZXI7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnbG9iYWxMaXN0ZW5lcihldmVudFR5cGU6IHN0cmluZywgZXZlbnQ6IGFueSk6IHZvaWQge1xuICAgICAgICAvLyBpZiB3ZSBhcmUgdGVhcmluZyBkb3duLCBkb24ndCBlbWl0IGFuZ3VsYXIgZXZlbnRzLCBhcyB0aGlzIGNhdXNlc1xuICAgICAgICAvLyBwcm9ibGVtcyB3aXRoIHRoZSBhbmd1bGFyIHJvdXRlclxuICAgICAgICBpZiAodGhpcy5fZGVzdHJveWVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBnZW5lcmljYWxseSBsb29rIHVwIHRoZSBldmVudFR5cGVcbiAgICAgICAgY29uc3QgZW1pdHRlciA9IDxFdmVudEVtaXR0ZXI8YW55Pj4oPGFueT50aGlzKVtldmVudFR5cGVdO1xuICAgICAgICBpZiAoZW1pdHRlciAmJiB0aGlzLmlzRW1pdHRlclVzZWQoZXZlbnRUeXBlKSkge1xuICAgICAgICAgICAgLy8gTWFrZSBzdXJlIHdlIGVtaXQgd2l0aGluIHRoZSBhbmd1bGFyIHpvbmUsIHNvIGNoYW5nZSBkZXRlY3Rpb24gd29ya3MgcHJvcGVybHlcbiAgICAgICAgICAgIGNvbnN0IGZpcmVFbWl0dGVyID0gKCkgPT4gdGhpcy5fYW5ndWxhckZyYW1ld29ya092ZXJyaWRlcy5ydW5JbnNpZGVBbmd1bGFyKCgpID0+IGVtaXR0ZXIuZW1pdChldmVudCkpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5faG9sZEV2ZW50cykge1xuICAgICAgICAgICAgICAgIC8vIGlmIHRoZSB1c2VyIGlzIGxpc3RlbmluZyB0byBldmVudHMsIHdhaXQgZm9yIG5nQWZ0ZXJWaWV3SW5pdCB0byBmaXJlIGZpcnN0LCB0aGVuIGVtaXQgdGhlIHN0dWRpbyBldmVudHNcbiAgICAgICAgICAgICAgICB0aGlzLl9mdWxseVJlYWR5LnRoZW4oKCkgPT4gZmlyZUVtaXR0ZXIoKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGZpcmVFbWl0dGVyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogUHJvdmlkZWQgYW4gaW5pdGlhbCBzdHVkaW9Qcm9wZXJ0aWVzIGNvbmZpZ3VyYXRpb24gdG8gdGhlIGNvbXBvbmVudC4gSWYgYSBwcm9wZXJ0eSBpcyBzcGVjaWZpZWQgaW4gYm90aCBzdHVkaW9Qcm9wZXJ0aWVzIGFuZCB2aWEgY29tcG9uZW50IGJpbmRpbmcgdGhlIGNvbXBvbmVudCBiaW5kaW5nIHRha2VzIHByZWNlZGVuY2UuICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBzdHVkaW9Qcm9wZXJ0aWVzOiBBZ1N0dWRpb1Byb3BlcnRpZXMgfCB1bmRlZmluZWQ7XG4gICAgLyoqXG4gICAgICogVXNlZCB0byByZWdpc3RlciBBRyBTdHVkaW8gTW9kdWxlcyBkaXJlY3RseSB3aXRoIHRoaXMgaW5zdGFuY2Ugb2YgU3R1ZGlvLlxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBtb2R1bGVzOiBBZ1N0dWRpb01vZHVsZVtdIHwgdW5kZWZpbmVkO1xuXG4gICAgLy8gQFNUQVJUQFxuICAgIC8qKiBDaGFuZ2UgdGhpcyB2YWx1ZSB0byBzZXQgdGhlIHRhYkluZGV4IG9yZGVyIG9mIFN0dWRpbyB3aXRoaW4geW91ciBhcHBsaWNhdGlvbi5cbiAgICAgKiBAZGVmYXVsdCAwXG4gICAgICogQGluaXRpYWxcbiAgICAgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgdGFiSW5kZXg6IG51bWJlciB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICAvKiogU2V0IHRvIGB0cnVlYCB0byBvcGVyYXRlIFN0dWRpbyBpbiBSVEwgKFJpZ2h0IHRvIExlZnQpIG1vZGUuXG4gICAgICogQGRlZmF1bHQgZmFsc2VcbiAgICAgKiBAaW5pdGlhbFxuICAgICAqL1xuICAgIEBJbnB1dCh7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KSBwdWJsaWMgZW5hYmxlUnRsOiBib29sZWFuIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBET00gZWxlbWVudCB0byB1c2UgYXMgdGhlIHBvcHVwIHBhcmVudCBmb3IgU3R1ZGlvIHBvcHVwcyAoY29udGV4dCBtZW51cywgZXRjLikuXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIHBvcHVwUGFyZW50OiBIVE1MRWxlbWVudCB8IG51bGwgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgLyoqIFRoZW1lIHRvIGFwcGx5IHRvIFN0dWRpby5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0IHN0dWRpb1RoZW1lXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIHRoZW1lOiBBZ1N0dWRpb1RoZW1lIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBJZiB5b3VyIHRoZW1lIHVzZXMgYSBmb250IHRoYXQgaXMgYXZhaWxhYmxlIG9uIEdvb2dsZSBGb250cywgcGFzcyB0cnVlIHRvIGxvYWQgaXQgZnJvbSBHb29nbGUncyBDRE4uXG4gICAgICovXG4gICAgQElucHV0KHsgdHJhbnNmb3JtOiBib29sZWFuQXR0cmlidXRlIH0pIHB1YmxpYyBsb2FkVGhlbWVHb29nbGVGb250czogYm9vbGVhbiB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICAvKiogVGhlIENTUyBsYXllciB0aGF0IHRoaXMgdGhlbWUgc2hvdWxkIGJlIHJlbmRlcmVkIG9udG8uIFdoZW4gc3BlY2lmaWVkLFxuICAgICAqIFN0dWRpbyBDU1Mgd2lsbCBiZSB3cmFwcGVkIGluIGEgYEBsYXllciAke3RoZW1lQ3NzTGF5ZXJ9IHsgLi4uIH1gIGJsb2NrLlxuICAgICAqXG4gICAgICogTk9URTogd2hlbiBzcGVjaWZ5aW5nIGB0aGVtZUNzc0xheWVyYCB3ZSByZWNvbW1lbmQgc2V0dGluZ1xuICAgICAqIGB0aGVtZVN0eWxlQ29udGFpbmVyYCB0byBgZG9jdW1lbnQuYm9keWAgdG8gZW5zdXJlIHRoYXQgU3R1ZGlvIENTU1xuICAgICAqIGNvbWVzIGFmdGVyIHlvdXIgYXBwbGljYXRpb24gQ1NTLCBhbGxvd2luZyB5b3VyIGFwcGxpY2F0aW9uIHRvIHNldCB0aGVcbiAgICAgKiBvcmRlciBvZiBsYXllcnMuXG4gICAgICpcbiAgICAgKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0NTUy9AbGF5ZXJcbiAgICAgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgdGhlbWVDc3NMYXllcjogc3RyaW5nIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBUaGUgbm9uY2UgYXR0cmlidXRlIHRvIHNldCBvbiBzdHlsZSBlbGVtZW50cyBhZGRlZCB0byB0aGUgZG9jdW1lbnQgYnlcbiAgICAgKiB0aGVtZXMuIElmIFwiZm9vXCIgaXMgcGFzc2VkIHRvIHRoaXMgcHJvcGVydHksIFN0dWRpbyBjYW4gdXNlIHRoZSBDb250ZW50XG4gICAgICogU2VjdXJpdHkgUG9saWN5IGBzdHlsZS1zcmMgJ25vbmNlLWZvbydgLCBpbnN0ZWFkIG9mIHRoZSBsZXNzIHNlY3VyZVxuICAgICAqIGBzdHlsZS1zcmMgJ3Vuc2FmZS1pbmxpbmUnYC5cbiAgICAgKlxuICAgICAqIE5vdGU6IENTUCBub25jZXMgYXJlIGdsb2JhbCB0byBhIHBhZ2UsIHdoZXJlIGEgcGFnZSBoYXMgbXVsdGlwbGUgU3R1ZGlvIGNvbXBvbmVudHMsXG4gICAgICogZXZlcnkgb25lIG11c3QgaGF2ZSB0aGUgc2FtZSBzdHlsZU5vbmNlIHNldC5cbiAgICAgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgc3R5bGVOb25jZTogc3RyaW5nIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBBbiBlbGVtZW50IHRvIGluc2VydCBzdHlsZSBlbGVtZW50cyBpbnRvIHdoZW4gaW5qZWN0aW5nIHN0eWxlcyBpbnRvIHRoZVxuICAgICAqIFN0dWRpby4gU3R5bGVzIGFyZSBpbnNlcnRlZCBhdCB0aGUgc3RhcnQgb2YgdGhlIGVsZW1lbnQuXG4gICAgICpcbiAgICAgKiBJZiB1bmRlZmluZWQsIHN0eWxlcyB3aWxsIGJlIGFkZGVkIHRvIHRoZSBkb2N1bWVudCBoZWFkIGZvciBTdHVkaW8gY29tcG9uZW50c1xuICAgICAqIHJlbmRlcmVkIGluIHRoZSBtYWluIGRvY3VtZW50IGZyYWdtZW50LCBvciB0byBTdHVkaW8gd3JhcHBlciBlbGVtZW50XG4gICAgICogZm9yIG90aGVyIFN0dWRpbyBjb21wb25lbnRzIChlLmcuIHRob3NlIHJlbmRlcmVkIGluIGEgc2hhZG93IERPTSBvciBkZXRhY2hlZCBmcm9tIHRoZVxuICAgICAqIGRvY3VtZW50KS5cbiAgICAgKlxuICAgICAqIEBpbml0aWFsXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIHRoZW1lU3R5bGVDb250YWluZXI6IChIVE1MRWxlbWVudCB8ICgoKSA9PiBIVE1MRWxlbWVudCB8IHZvaWQpKSB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICAvKiogQWxsb3dzIG92ZXJyaWRpbmcgd2hhdCBgZG9jdW1lbnRgIGlzIHVzZWQuXG4gICAgICogVXNlIHRoaXMgd2hlbiB5b3Ugd2FudCBTdHVkaW8gdG8gdXNlIGEgZGlmZmVyZW50IGBkb2N1bWVudGAgdGhhbiB0aGUgb25lIGF2YWlsYWJsZSBvbiB0aGUgZ2xvYmFsIHNjb3BlLlxuICAgICAqIFRoaXMgY2FuIGhhcHBlbiBpZiBkb2NraW5nIG91dCBjb21wb25lbnRzIChzb21ldGhpbmcgd2hpY2ggRWxlY3Ryb24gc3VwcG9ydHMpLlxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBnZXREb2N1bWVudDogKCgpID0+IERvY3VtZW50KSB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICAvKiogRGlzYWJsZXMgdG91Y2ggc3VwcG9ydCAoYnV0IGRvZXMgbm90IHJlbW92ZSB0aGUgYnJvd3NlcidzIGVmZm9ydHMgdG8gc2ltdWxhdGUgbW91c2UgZXZlbnRzIG9uIHRvdWNoKS5cbiAgICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgICAqIEBpbml0aWFsXG4gICAgICovXG4gICAgQElucHV0KHsgdHJhbnNmb3JtOiBib29sZWFuQXR0cmlidXRlIH0pIHB1YmxpYyBzdXBwcmVzc1RvdWNoOiBib29sZWFuIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBBIG1hcCBvZiBrZXktPnZhbHVlIHBhaXJzIGZvciBsb2NhbGlzaW5nIHRleHQgd2l0aGluIFN0dWRpby5cbiAgICAgKiBAaW5pdGlhbFxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBsb2NhbGVUZXh0OiBBZ1N0dWRpb0xvY2FsZVRleHQgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgLyoqIEEgY2FsbGJhY2sgZm9yIGxvY2FsaXNpbmcgdGV4dCB3aXRoaW4gU3R1ZGlvLlxuICAgICAqIEBpbml0aWFsXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIGdldExvY2FsZVRleHQ6ICgocGFyYW1zOiBBZ1N0dWRpb0dldExvY2FsZVRleHRQYXJhbXMpID0+IHN0cmluZykgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgLyoqIFByb3ZpZGUgYSBjdXN0b20gYHN0dWRpb0lkYCBmb3IgdGhpcyBpbnN0YW5jZSBvZiBTdHVkaW8uIFZhbHVlIHdpbGwgYmUgc2V0IG9uIHRoZSByb290IERPTSBub2RlIHVzaW5nIHRoZSBhdHRyaWJ1dGUgYHN0dWRpby1pZGAgYXMgd2VsbCBhcyBiZWluZyBhY2Nlc3NpYmxlIHZpYSB0aGUgYGFwaS5nZXRTdHVkaW9JZCgpYCBtZXRob2QuXG4gICAgICogQGluaXRpYWxcbiAgICAgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgc3R1ZGlvSWQ6IHN0cmluZyB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICAvKiogUHJvdmlkZXMgYSBjb250ZXh0IG9iamVjdCB0aGF0IGlzIHByb3ZpZGVkIHRvIGRpZmZlcmVudCBjYWxsYmFja3MgU3R1ZGlvIHVzZXMuIFVzZWQgZm9yIHBhc3NpbmcgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0byB0aGUgY2FsbGJhY2tzIHVzZWQgYnkgeW91ciBhcHBsaWNhdGlvbi5cbiAgICAgKiBAaW5pdGlhbFxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBjb250ZXh0OiBhbnkgPSB1bmRlZmluZWQ7XG4gICAgLyoqIEluaXRpYWwgc3RhdGUgZm9yIFN0dWRpby4gT25seSByZWFkIG9uY2Ugb24gaW5pdGlhbGl6YXRpb24uIENhbiBiZSB1c2VkIGluIGNvbmp1bmN0aW9uIHdpdGggYGFwaS5nZXRTdGF0ZSgpYCB0byBzYXZlIGFuZCByZXN0b3JlIFN0dWRpbyBzdGF0ZS5cbiAgICAgKiBAaW5pdGlhbFxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBpbml0aWFsU3RhdGU6IEFnUmVwb3J0U3RhdGUgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgLyoqIERlZmluZXMgdGhlIGRhdGEgc291cmNlcyB1c2VkIGJ5IFN0dWRpby5cbiAgICAgKlxuICAgICAqIElmIHVwZGF0ZWQgYWZ0ZXIgaW5pdGlhbGx5IGJlaW5nIHNldCwgb25seSBjaGFuZ2VzIHRvIHN5bmNocm9ub3VzIGRhdGEgd2lsbCBiZSBwcm9jZXNzZWQuXG4gICAgICogQW55IG90aGVyIGNoYW5nZXMgd2lsbCBiZSBpZ25vcmVkIChlLmcuIGFkZGluZy9yZW1vdmluZyBkYXRhIHNvdXJjZXMsIHVwZGF0aW5nIGZpZWxkcywgZXRjLilcbiAgICAgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgZGF0YTogQWdEYXRhU291cmNlc0RlZmluaXRpb24gfCBBZ0RhdGFFbmdpbmUgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgLyoqIFdoaWNoIG1vZGUgU3R1ZGlvIGlzIGluLlxuICAgICAqIEBkZWZhdWx0ICd2aWV3J1xuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBtb2RlOiBBZ1N0dWRpb01vZGUgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgLyoqIERlZmF1bHQgbGF5b3V0IHN0eWxpbmcuXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIGxheW91dDogUGFydGlhbDxBZ1BhZ2VMYXlvdXRTdGF0ZT4gfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgLyoqIEFJIEFzc2lzdGFudCBjb25maWd1cmF0aW9uLlxuICAgICAqIEBpbml0aWFsXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIGFpOiBBZ0FpQXNzaXN0YW50IHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBPdmVycmlkZXMgZm9yIHRoZSBsYXlvdXQgYW5kIHdpZGdldCBjb25maWdzLlxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBvdmVycmlkZXM6IEFnU3R1ZGlvT3ZlcnJpZGVzIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBDb25maWd1cmUgd2hpY2ggcGFuZWxzIGFyZSBkaXNwbGF5ZWQgYW5kIG9uIHdoaWNoIHNpZGUuXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIHBhbmVsczogQWdQYW5lbENvbmZpZyB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcblxuICAgIC8qKiBTdGF0ZSBoYXMgYmVlbiB1cGRhdGVkLlxuICAgICAqL1xuICAgIEBPdXRwdXQoKSBwdWJsaWMgc3RhdGVVcGRhdGVkOiBFdmVudEVtaXR0ZXI8QWdTdHVkaW9TdGF0ZVVwZGF0ZWRFdmVudD4gPVxuICAgICAgICBuZXcgRXZlbnRFbWl0dGVyPEFnU3R1ZGlvU3RhdGVVcGRhdGVkRXZlbnQ+KCk7XG4gICAgLyoqIFRoZSBBUEkgaGFzIGJlZW4gaW5pdGlhbGlzZWQgYW5kIGlzIHJlYWR5IGZvciBtb3N0IGNhbGxzLiBUaGUgZGF0YSBlbmdpbmUgaGFzIG5vdCBiZWVuIGluaXRpYWxpc2VkIHlldCwgYW5kIHRoZSBVSSBpcyBub3QgcmVhZHkuXG4gICAgICovXG4gICAgQE91dHB1dCgpIHB1YmxpYyBhcGlSZWFkeTogRXZlbnRFbWl0dGVyPEFnU3R1ZGlvQXBpUmVhZHlFdmVudD4gPSBuZXcgRXZlbnRFbWl0dGVyPEFnU3R1ZGlvQXBpUmVhZHlFdmVudD4oKTtcbiAgICAvKiogVGhlIGRhdGEgZW5naW5lIGhhcyBiZWVuIGluaXRpYWxpc2VkLCBhbmQgdGhlIFVJIGhhcyBiZWVuIGNyZWF0ZWQsIGJ1dCBtYXkgbm90IGJlIGZ1bGx5IHJlbmRlcmVkIHlldC5cbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgcHVibGljIHN0dWRpb1JlYWR5OiBFdmVudEVtaXR0ZXI8QWdTdHVkaW9SZWFkeUV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXI8QWdTdHVkaW9SZWFkeUV2ZW50PigpO1xuICAgIC8qKiBBbiBlcnJvciBoYXMgb2NjdXJyZWQgd2l0aGluIFN0dWRpby5cbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgcHVibGljIGVycm9yUmFpc2VkOiBFdmVudEVtaXR0ZXI8QWdTdHVkaW9FcnJvclJhaXNlZEV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXI8QWdTdHVkaW9FcnJvclJhaXNlZEV2ZW50PigpO1xuXG4gICAgLy8gQEVOREBcbn1cblxuY29uc3QgYm9vbGVhbk1peGVkU3R1ZGlvUHJvcGVydGllcyA9IG5ldyBTZXQ8c3RyaW5nPihfQk9PTEVBTl9NSVhFRF9TVFVESU9fUFJPUEVSVElFUyk7XG4vKipcbiAqIFVzZWQgdG8gc3VwcG9ydCB0aGUgdXNlciBzZXR0aW5nIGNvbWJpbmVkIGJvb2xlYW4gYW5kIHN0cmluZyAvIG9iamVjdCBwcm9wZXJ0aWVzXG4gKiBhcyBwbGFpbiBIVE1MIGF0dHJpYnV0ZXMgYW5kIHVzIGNvcnJlY3RseSBtYXBwaW5nIHRoYXQgdG8gdHJ1ZS5cbiAqIEZvciBleGFtcGxlIGNlbGxTZWN0aW9uIGNhbiBiZSBib29sZWFuIG9yIGFuIG9iamVjdFxuICovXG5mdW5jdGlvbiBnZXRWYWx1ZU9yQ29lcmNlZFZhbHVlKGtleTogc3RyaW5nLCB2YWx1ZVRvVXNlOiBhbnkpOiBhbnkge1xuICAgIGlmIChib29sZWFuTWl4ZWRTdHVkaW9Qcm9wZXJ0aWVzLmhhcyhrZXkpKSB7XG4gICAgICAgIC8vIEhhbmRsZSBwbGFpbiBIVE1MIGJvb2xlYW4gYXR0cmlidXRlcyBhbmQgY29udmVydCB0aGVtIHRvIGJvb2xlYW4gdmFsdWVzXG4gICAgICAgIC8vIEFsc28gaGFuZGxlIHRoZSBmYWxzZSBzdHJpbmcgY2FzZSB0byBtYXRjaCBBbmd1bGFyIGJvb2xlYW4gYXR0cmlidXRlc1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgc29uYXJqcy9uby1uZXN0ZWQtY29uZGl0aW9uYWxcbiAgICAgICAgcmV0dXJuIHZhbHVlVG9Vc2UgPT09ICcnID8gdHJ1ZSA6IHZhbHVlVG9Vc2UgPT09ICdmYWxzZScgPyBmYWxzZSA6IHZhbHVlVG9Vc2U7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZVRvVXNlO1xufVxuIl19
350
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWctc3R1ZGlvLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2FnLXN0dWRpby1hbmd1bGFyL3NyYy9saWIvYWctc3R1ZGlvLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx5Q0FBeUM7QUFDekMscUVBQXFFO0FBQ3JFLHNFQUFzRTtBQUN0RSxPQUFPLEVBRUgsU0FBUyxFQUVULFlBQVksRUFDWixLQUFLLEVBR0wsTUFBTSxFQUVOLGlCQUFpQixFQUNqQixnQkFBZ0IsR0FDbkIsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUNILGdDQUFnQyxFQUNoQyxxQ0FBcUMsRUFDckMsYUFBYSxFQUNiLHVCQUF1QixHQUMxQixNQUFNLFdBQVcsQ0FBQztBQXVCbkIsZ0JBQWdCO0FBRWhCLE9BQU8sRUFBRSxnQ0FBZ0MsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3RGLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLDZCQUE2QixDQUFDOzs7O0FBV3hFLE1BQU0sT0FBTyxRQUFRO0lBaUJqQixZQUNJLFVBQXNCLEVBQ0wsaUJBQW1DLEVBQ25DLDBCQUFxRCxFQUNyRCxxQkFBdUQ7UUFGdkQsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFrQjtRQUNuQywrQkFBMEIsR0FBMUIsMEJBQTBCLENBQTJCO1FBQ3JELDBCQUFxQixHQUFyQixxQkFBcUIsQ0FBa0M7UUFqQnBFLGlCQUFZLEdBQUcsS0FBSyxDQUFDO1FBQ3JCLGVBQVUsR0FBRyxLQUFLLENBQUM7UUFFM0IseURBQXlEO1FBQ2pELGdCQUFXLEdBQUcsSUFBSSxDQUFDO1FBRVYsZ0JBQVcsR0FBa0IsSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUNsRSxJQUFJLENBQUMsa0JBQWtCLEdBQUcsT0FBTyxDQUFDO1FBQ3RDLENBQUMsQ0FBQyxDQUFDO1FBNElILFVBQVU7UUFDVjs7O1dBR0c7UUFDYSxhQUFR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TSw0QkFBNEIsR0FBRyxJQUFJLEdBQUcsQ0FBUyxnQ0FBZ0MsQ0FBQyxDQUFDO0FBQ3ZGOzs7O0dBSUc7QUFDSCxTQUFTLHNCQUFzQixDQUFDLEdBQVcsRUFBRSxVQUFlO0lBQ3hELElBQUksNEJBQTRCLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDeEMsMEVBQTBFO1FBQzFFLHdFQUF3RTtRQUN4RSxPQUFPLFVBQVUsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsVUFBVSxLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUM7SUFDbEYsQ0FBQztJQUNELE9BQU8sVUFBVSxDQUFDO0FBQ3RCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBuby1kdXBsaWNhdGUtaW1wb3J0cyAqL1xuLy8gRmFsc2UgcG9zaXRpdmUgbGludCBlcnJvciwgRWxlbWVudFJlZiBhbmQgY28gY2FuJ3QgYmUgdHlwZSBpbXBvcnRzXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L2NvbnNpc3RlbnQtdHlwZS1pbXBvcnRzXG5pbXBvcnQge1xuICAgIEFmdGVyVmlld0luaXQsXG4gICAgQ29tcG9uZW50LFxuICAgIEVsZW1lbnRSZWYsXG4gICAgRXZlbnRFbWl0dGVyLFxuICAgIElucHV0LFxuICAgIE9uQ2hhbmdlcyxcbiAgICBPbkRlc3Ryb3ksXG4gICAgT3V0cHV0LFxuICAgIFZpZXdDb250YWluZXJSZWYsXG4gICAgVmlld0VuY2Fwc3VsYXRpb24sXG4gICAgYm9vbGVhbkF0dHJpYnV0ZSxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgdHlwZSB7IEFnRGVmYXVsdFJlZ2lzdHJ5LCBBZ1N0dWRpb0FwaSwgQWdTdHVkaW9Nb2R1bGUsIEFnU3R1ZGlvUHJvcGVydGllcywgX1N0dWRpb1BhcmFtcyB9IGZyb20gJ2FnLXN0dWRpbyc7XG5pbXBvcnQge1xuICAgIF9CT09MRUFOX01JWEVEX1NUVURJT19QUk9QRVJUSUVTLFxuICAgIF9jb21iaW5lQXR0cmlidXRlc0FuZFN0dWRpb1Byb3BlcnRpZXMsXG4gICAgX2NyZWF0ZVN0dWRpbyxcbiAgICBfcHJvY2Vzc1Byb3BlcnR5Q2hhbmdlcyxcbn0gZnJvbSAnYWctc3R1ZGlvJztcbi8vIEBTVEFSVF9JTVBPUlRTQFxuaW1wb3J0IHR5cGUge1xuICAgIEFnQWlBc3Npc3RhbnQsXG4gICAgQWdEYXRhRW5naW5lLFxuICAgIEFnRGF0YU9wdGlvbnMsXG4gICAgQWdEYXRhU291cmNlc0RlZmluaXRpb24sXG4gICAgQWdQYWdlQ29uZmlnLFxuICAgIEFnUGFnZUxheW91dFN0YXRlLFxuICAgIEFnUGFuZWxDb25maWcsXG4gICAgQWdSZXBvcnRTdGF0ZSxcbiAgICBBZ1N0dWRpb0FwaVJlYWR5RXZlbnQsXG4gICAgQWdTdHVkaW9FcnJvclJhaXNlZEV2ZW50LFxuICAgIEFnU3R1ZGlvR2V0TG9jYWxlVGV4dFBhcmFtcyxcbiAgICBBZ1N0dWRpb0xvY2FsZVRleHQsXG4gICAgQWdTdHVkaW9Nb2RlLFxuICAgIEFnU3R1ZGlvT3ZlcnJpZGVzLFxuICAgIEFnU3R1ZGlvUmVhZHlFdmVudCxcbiAgICBBZ1N0dWRpb1N0YXRlVXBkYXRlZEV2ZW50LFxuICAgIEFnU3R1ZGlvVGhlbWUsXG4gICAgQWdXaWRnZXRzQ29uZmlnLFxufSBmcm9tICdhZy1zdHVkaW8nO1xuXG4vLyBARU5EX0lNUE9SVFNAXG5cbmltcG9ydCB7IEFuZ3VsYXJGcmFtZXdvcmtDb21wb25lbnRXcmFwcGVyIH0gZnJvbSAnLi9hbmd1bGFyRnJhbWV3b3JrQ29tcG9uZW50V3JhcHBlcic7XG5pbXBvcnQgeyBBbmd1bGFyRnJhbWV3b3JrT3ZlcnJpZGVzIH0gZnJvbSAnLi9hbmd1bGFyRnJhbWV3b3JrT3ZlcnJpZGVzJztcbmltcG9ydCB0eXBlIHsgQWdSZWdpc3RyeSB9IGZyb20gJy4vaW50ZXJmYWNlcyc7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnYWctc3R1ZGlvJyxcbiAgICBzdGFuZGFsb25lOiB0cnVlLFxuICAgIHRlbXBsYXRlOiAnJyxcbiAgICBwcm92aWRlcnM6IFtBbmd1bGFyRnJhbWV3b3JrT3ZlcnJpZGVzLCBBbmd1bGFyRnJhbWV3b3JrQ29tcG9uZW50V3JhcHBlcl0sXG4gICAgLy8gdGVsbCBhbmd1bGFyIHdlIGRvbid0IHdhbnQgdmlldyBlbmNhcHN1bGF0aW9uLCB3ZSBkb24ndCB3YW50IGEgc2hhZG93IHJvb3RcbiAgICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxufSlcbmV4cG9ydCBjbGFzcyBBZ1N0dWRpbzxUUmVnaXN0cnkgZXh0ZW5kcyBBZ1JlZ2lzdHJ5ID0gQWdEZWZhdWx0UmVnaXN0cnk+IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xuICAgIC8vIG5vdCBpbnRlbmRlZCBmb3IgdXNlciB0byBpbnRlcmFjdCB3aXRoLiBzbyBwdXR0aW5nIF8gaW4gc28gaWYgdXNlciBnZXRzIHJlZmVyZW5jZVxuICAgIC8vIHRvIHRoaXMgb2JqZWN0LCB0aGV5IGtpbmQnYSBrbm93IGl0J3Mgbm90IHBhcnQgb2YgdGhlIGFncmVlZCBpbnRlcmZhY2VcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9uYXRpdmVFbGVtZW50OiBhbnk7XG4gICAgcHJpdmF0ZSBfaW5pdGlhbGlzZWQgPSBmYWxzZTtcbiAgICBwcml2YXRlIF9kZXN0cm95ZWQgPSBmYWxzZTtcblxuICAgIC8vIGluIG9yZGVyIHRvIGVuc3VyZSBmaXJpbmcgb2YgYXBpUmVhZHkgaXMgZGV0ZXJtaW5pc3RpY1xuICAgIHByaXZhdGUgX2hvbGRFdmVudHMgPSB0cnVlO1xuICAgIHByaXZhdGUgX3Jlc29sdmVGdWxseVJlYWR5OiAoKSA9PiB2b2lkO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgX2Z1bGx5UmVhZHk6IFByb21pc2U8dm9pZD4gPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICB0aGlzLl9yZXNvbHZlRnVsbHlSZWFkeSA9IHJlc29sdmU7XG4gICAgfSk7XG5cbiAgICAvKiogU3R1ZGlvIEFwaSBhdmFpbGFibGUgYWZ0ZXIgb25BcGlSZWFkeSBldmVudCBoYXMgZmlyZWQuICovXG4gICAgYXBpOiBBZ1N0dWRpb0FwaTxUUmVnaXN0cnk+O1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIGVsZW1lbnREZWY6IEVsZW1lbnRSZWYsXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgX3ZpZXdDb250YWluZXJSZWY6IFZpZXdDb250YWluZXJSZWYsXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgX2FuZ3VsYXJGcmFtZXdvcmtPdmVycmlkZXM6IEFuZ3VsYXJGcmFtZXdvcmtPdmVycmlkZXMsXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgX2ZyYW1ld29ya0NvbXBXcmFwcGVyOiBBbmd1bGFyRnJhbWV3b3JrQ29tcG9uZW50V3JhcHBlclxuICAgICkge1xuICAgICAgICB0aGlzLl9uYXRpdmVFbGVtZW50ID0gZWxlbWVudERlZi5uYXRpdmVFbGVtZW50O1xuICAgICAgICAvLyBOT1NPTkFSXG4gICAgICAgIHRoaXMuX2Z1bGx5UmVhZHkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAvLyBSZWdpc3RlciB0aGUgc3RhdHVzIGZsYWcgcmVzZXQgYmVmb3JlIGFueSBldmVudHMgYXJlIGZpcmVkXG4gICAgICAgICAgICAvLyBzbyB0aGF0IHdlIGNhbiBzd2FwIHRvIHN5bmNocm9ub3VzIGV2ZW50IGZpcmluZyBhcyBzb29uIGFzIHRoZSBzdHVkaW8gaXMgcmVhZHlcbiAgICAgICAgICAgIHRoaXMuX2hvbGRFdmVudHMgPSBmYWxzZTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgICAgICAvLyBSdW4gdGhlIHNldHVwIG91dHNpZGUgb2YgYW5ndWxhciBzbyBhbGwgdGhlIGV2ZW50IGhhbmRsZXJzIHRoYXQgYXJlIGNyZWF0ZWQgZG8gbm90IHRyaWdnZXIgY2hhbmdlIGRldGVjdGlvblxuICAgICAgICB0aGlzLl9hbmd1bGFyRnJhbWV3b3JrT3ZlcnJpZGVzLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuX2ZyYW1ld29ya0NvbXBXcmFwcGVyLnNldFZpZXdDb250YWluZXJSZWYodGhpcy5fdmlld0NvbnRhaW5lclJlZiwgdGhpcy5fYW5ndWxhckZyYW1ld29ya092ZXJyaWRlcyk7XG5cbiAgICAgICAgICAgIC8vIEdldCBhbGwgdGhlIGlucHV0cyB0aGF0IGFyZSB2YWxpZCBBZ1N0dWRpb1Byb3BlcnRpZXNcbiAgICAgICAgICAgIGNvbnN0IHN0dWRpb1Byb3BlcnRpZXNLZXlzID0gT2JqZWN0LmtleXModGhpcykuZmlsdGVyKFxuICAgICAgICAgICAgICAgIChrZXkpID0+XG4gICAgICAgICAgICAgICAgICAgICEoXG4gICAgICAgICAgICAgICAgICAgICAgICBrZXkuc3RhcnRzV2l0aCgnXycpIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICBrZXkgPT0gJ3N0dWRpb1Byb3BlcnRpZXMnIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICBrZXkgPT0gJ21vZHVsZXMnIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzW2tleSBhcyBrZXlvZiBBZ1N0dWRpb10gaW5zdGFuY2VvZiBFdmVudEVtaXR0ZXJcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgY29uc3QgY29lcmNlZFN0dWRpb1Byb3BlcnRpZXMgPSB7fSBhcyBBZ1N0dWRpb1Byb3BlcnRpZXM8VFJlZ2lzdHJ5PjtcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IG9mIHN0dWRpb1Byb3BlcnRpZXNLZXlzKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWVUb1VzZSA9IGdldFZhbHVlT3JDb2VyY2VkVmFsdWUoa2V5LCB0aGlzW2tleSBhcyBrZXlvZiBBZ1N0dWRpb10pO1xuICAgICAgICAgICAgICAgIGNvZXJjZWRTdHVkaW9Qcm9wZXJ0aWVzW2tleSBhcyBrZXlvZiBBZ1N0dWRpb1Byb3BlcnRpZXNdID0gdmFsdWVUb1VzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgbWVyZ2VkU3R1ZGlvUHJvcGVydGllcyA9IF9jb21iaW5lQXR0cmlidXRlc0FuZFN0dWRpb1Byb3BlcnRpZXMoXG4gICAgICAgICAgICAgICAgdGhpcy5zdHVkaW9Qcm9wZXJ0aWVzLFxuICAgICAgICAgICAgICAgIGNvZXJjZWRTdHVkaW9Qcm9wZXJ0aWVzLFxuICAgICAgICAgICAgICAgIHN0dWRpb1Byb3BlcnRpZXNLZXlzXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBjb25zdCBzdHVkaW9QYXJhbXM6IF9TdHVkaW9QYXJhbXMgPSB7XG4gICAgICAgICAgICAgICAgZ2xvYmFsTGlzdGVuZXI6IHRoaXMuZ2xvYmFsTGlzdGVuZXIuYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBmcmFtZXdvcmtPdmVycmlkZXM6IHRoaXMuX2FuZ3VsYXJGcmFtZXdvcmtPdmVycmlkZXMsXG4gICAgICAgICAgICAgICAgc2V0VGhlbWVPblJvb3REaXY6IHRydWUsXG4gICAgICAgICAgICAgICAgbW9kdWxlczogdGhpcy5tb2R1bGVzLFxuICAgICAgICAgICAgICAgIHByb3ZpZGVkQmVhbkluc3RhbmNlczoge1xuICAgICAgICAgICAgICAgICAgICBmcmFtZXdvcmtDb21wV3JhcHBlcjogdGhpcy5fZnJhbWV3b3JrQ29tcFdyYXBwZXIsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIGNvbnN0IGFwaSA9IF9jcmVhdGVTdHVkaW8odGhpcy5fbmF0aXZlRWxlbWVudCwgbWVyZ2VkU3R1ZGlvUHJvcGVydGllcywgc3R1ZGlvUGFyYW1zKTtcbiAgICAgICAgICAgIGlmIChhcGkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFwaSA9IGFwaTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5faW5pdGlhbGlzZWQgPSB0cnVlO1xuXG4gICAgICAgICAgICAvLyBzb21ldGltZXMsIGVzcGVjaWFsbHkgaW4gbGFyZ2UgY2xpZW50IGFwcHMgYXBpUmVhZHkgY2FuIGZpcmUgYmVmb3JlIG5nQWZ0ZXJWaWV3SW5pdFxuICAgICAgICAgICAgLy8gdGhpcyB0aWVzIHRoZXNlIHRvZ2V0aGVyIHNvIHRoYXQgYXBpUmVhZHkgd2lsbCBhbHdheXMgZmlyZSBhZnRlciBhZ1N0dWRpbydzIG5nQWZ0ZXJWaWV3SW5pdFxuICAgICAgICAgICAgLy8gdGhlIGFjdHVhbCBjb250YWluaW5nIGNvbXBvbmVudCdzIG5nQWZ0ZXJWaWV3SW5pdCB3aWxsIGZpcmUganVzdCBhZnRlciBhZ1N0dWRpbydzXG4gICAgICAgICAgICB0aGlzLl9yZXNvbHZlRnVsbHlSZWFkeSgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgbmdPbkNoYW5nZXMoY2hhbmdlczogYW55KTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLl9pbml0aWFsaXNlZCkge1xuICAgICAgICAgICAgLy8gUnVuIHRoZSBjaGFuZ2VzIG91dHNpZGUgb2YgYW5ndWxhciBzbyBhbnkgZXZlbnQgaGFuZGxlcnMgdGhhdCBhcmUgY3JlYXRlZCBkbyBub3QgdHJpZ2dlciBjaGFuZ2UgZGV0ZWN0aW9uXG4gICAgICAgICAgICB0aGlzLl9hbmd1bGFyRnJhbWV3b3JrT3ZlcnJpZGVzLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdHVkaW9Qcm9wZXJ0aWVzOiBBZ1N0dWRpb1Byb3BlcnRpZXM8VFJlZ2lzdHJ5PiA9IHt9O1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGNoYW5nZXMpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gY2hhbmdlc1trZXldO1xuICAgICAgICAgICAgICAgICAgICBzdHVkaW9Qcm9wZXJ0aWVzW2tleSBhcyBrZXlvZiBBZ1N0dWRpb1Byb3BlcnRpZXNdID0gdmFsdWUuY3VycmVudFZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBfcHJvY2Vzc1Byb3BlcnR5Q2hhbmdlcyhzdHVkaW9Qcm9wZXJ0aWVzLCB0aGlzLmFwaSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuX2luaXRpYWxpc2VkKSB7XG4gICAgICAgICAgICAvLyBuZWVkIHRvIGRvIHRoaXMgYmVmb3JlIHRoZSBkZXN0cm95LCBzbyB3ZSBrbm93IG5vdCB0byBlbWl0IGFueSBldmVudHNcbiAgICAgICAgICAgIC8vIHdoaWxlIHRlYXJpbmcgZG93biB0aGUgc3R1ZGlvLlxuICAgICAgICAgICAgdGhpcy5fZGVzdHJveWVkID0gdHJ1ZTtcbiAgICAgICAgICAgIC8vIGNvdWxkIGJlIG51bGwgaWYgc3R1ZGlvIGZhaWxlZCB0byBpbml0aWFsaXNlXG4gICAgICAgICAgICB0aGlzLmFwaT8uZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gd2UnbGwgZW1pdCB0aGUgZW1pdCBpZiBhIHVzZXIgaXMgbGlzdGVuaW5nIGZvciBhIGdpdmVuIGV2ZW50IGVpdGhlciBvbiB0aGUgY29tcG9uZW50IHZpYSBub3JtYWwgYW5ndWxhciBiaW5kaW5nXG4gICAgLy8gb3IgdmlhIHN0dWRpb1Byb3BlcnRpZXNcbiAgICBwcm90ZWN0ZWQgaXNFbWl0dGVyVXNlZChldmVudFR5cGU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCBlbWl0dGVyID0gPEV2ZW50RW1pdHRlcjxhbnk+Pig8YW55PnRoaXMpW2V2ZW50VHlwZV07XG4gICAgICAgIC8vIEZvciBSeEpzIGNvbXBhdGliaWxpdHkgd2UgbmVlZCB0byBjaGVjayBmb3Igb2JzZXJ2ZWQgdjcrIG9yIG9ic2VydmVycyB2NlxuICAgICAgICBjb25zdCBlbWl0dGVyQW55ID0gZW1pdHRlciBhcyBhbnk7XG4gICAgICAgIGNvbnN0IGhhc0VtaXR0ZXIgPSBlbWl0dGVyQW55Py5vYnNlcnZlZCA/PyBlbWl0dGVyQW55Py5vYnNlcnZlcnM/Lmxlbmd0aCA+IDA7XG5cbiAgICAgICAgLy8gYXBpUmVhZHkgPT4gb25BcGlSZWFkeVxuICAgICAgICBjb25zdCBhc0V2ZW50TmFtZSA9IGBvbiR7ZXZlbnRUeXBlLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpfSR7ZXZlbnRUeXBlLnN1YnN0cmluZygxKX1gO1xuICAgICAgICBjb25zdCBoYXNTdHVkaW9Qcm9wZXJ0eUxpc3RlbmVyID0gISF0aGlzLnN0dWRpb1Byb3BlcnRpZXMgJiYgISEodGhpcy5zdHVkaW9Qcm9wZXJ0aWVzIGFzIGFueSlbYXNFdmVudE5hbWVdO1xuXG4gICAgICAgIHJldHVybiBoYXNFbWl0dGVyIHx8IGhhc1N0dWRpb1Byb3BlcnR5TGlzdGVuZXI7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnbG9iYWxMaXN0ZW5lcihldmVudFR5cGU6IHN0cmluZywgZXZlbnQ6IGFueSk6IHZvaWQge1xuICAgICAgICAvLyBpZiB3ZSBhcmUgdGVhcmluZyBkb3duLCBkb24ndCBlbWl0IGFuZ3VsYXIgZXZlbnRzLCBhcyB0aGlzIGNhdXNlc1xuICAgICAgICAvLyBwcm9ibGVtcyB3aXRoIHRoZSBhbmd1bGFyIHJvdXRlclxuICAgICAgICBpZiAodGhpcy5fZGVzdHJveWVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBnZW5lcmljYWxseSBsb29rIHVwIHRoZSBldmVudFR5cGVcbiAgICAgICAgY29uc3QgZW1pdHRlciA9IDxFdmVudEVtaXR0ZXI8YW55Pj4oPGFueT50aGlzKVtldmVudFR5cGVdO1xuICAgICAgICBpZiAoZW1pdHRlciAmJiB0aGlzLmlzRW1pdHRlclVzZWQoZXZlbnRUeXBlKSkge1xuICAgICAgICAgICAgLy8gTWFrZSBzdXJlIHdlIGVtaXQgd2l0aGluIHRoZSBhbmd1bGFyIHpvbmUsIHNvIGNoYW5nZSBkZXRlY3Rpb24gd29ya3MgcHJvcGVybHlcbiAgICAgICAgICAgIGNvbnN0IGZpcmVFbWl0dGVyID0gKCkgPT4gdGhpcy5fYW5ndWxhckZyYW1ld29ya092ZXJyaWRlcy5ydW5JbnNpZGVBbmd1bGFyKCgpID0+IGVtaXR0ZXIuZW1pdChldmVudCkpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5faG9sZEV2ZW50cykge1xuICAgICAgICAgICAgICAgIC8vIGlmIHRoZSB1c2VyIGlzIGxpc3RlbmluZyB0byBldmVudHMsIHdhaXQgZm9yIG5nQWZ0ZXJWaWV3SW5pdCB0byBmaXJlIGZpcnN0LCB0aGVuIGVtaXQgdGhlIHN0dWRpbyBldmVudHNcbiAgICAgICAgICAgICAgICB0aGlzLl9mdWxseVJlYWR5LnRoZW4oKCkgPT4gZmlyZUVtaXR0ZXIoKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGZpcmVFbWl0dGVyKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogUHJvdmlkZWQgYW4gaW5pdGlhbCBzdHVkaW9Qcm9wZXJ0aWVzIGNvbmZpZ3VyYXRpb24gdG8gdGhlIGNvbXBvbmVudC4gSWYgYSBwcm9wZXJ0eSBpcyBzcGVjaWZpZWQgaW4gYm90aCBzdHVkaW9Qcm9wZXJ0aWVzIGFuZCB2aWEgY29tcG9uZW50IGJpbmRpbmcgdGhlIGNvbXBvbmVudCBiaW5kaW5nIHRha2VzIHByZWNlZGVuY2UuICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBzdHVkaW9Qcm9wZXJ0aWVzOiBBZ1N0dWRpb1Byb3BlcnRpZXM8VFJlZ2lzdHJ5PiB8IHVuZGVmaW5lZDtcbiAgICAvKipcbiAgICAgKiBVc2VkIHRvIHJlZ2lzdGVyIEFHIFN0dWRpbyBNb2R1bGVzIGRpcmVjdGx5IHdpdGggdGhpcyBpbnN0YW5jZSBvZiBTdHVkaW8uXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIG1vZHVsZXM6IEFnU3R1ZGlvTW9kdWxlW10gfCB1bmRlZmluZWQ7XG5cbiAgICAvLyBAU1RBUlRAXG4gICAgLyoqIENoYW5nZSB0aGlzIHZhbHVlIHRvIHNldCB0aGUgdGFiSW5kZXggb3JkZXIgb2YgU3R1ZGlvIHdpdGhpbiB5b3VyIGFwcGxpY2F0aW9uLlxuICAgICAqIEBkZWZhdWx0IDBcbiAgICAgKiBAaW5pdGlhbFxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyB0YWJJbmRleDogbnVtYmVyIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBTZXQgdG8gYHRydWVgIHRvIG9wZXJhdGUgU3R1ZGlvIGluIFJUTCAoUmlnaHQgdG8gTGVmdCkgbW9kZS5cbiAgICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgICAqIEBpbml0aWFsXG4gICAgICovXG4gICAgQElucHV0KHsgdHJhbnNmb3JtOiBib29sZWFuQXR0cmlidXRlIH0pIHB1YmxpYyBlbmFibGVSdGw6IGJvb2xlYW4gfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgLyoqIERPTSBlbGVtZW50IHRvIHVzZSBhcyB0aGUgcG9wdXAgcGFyZW50IGZvciBTdHVkaW8gcG9wdXBzIChjb250ZXh0IG1lbnVzLCBldGMuKS5cbiAgICAgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgcG9wdXBQYXJlbnQ6IEhUTUxFbGVtZW50IHwgbnVsbCB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICAvKiogVGhlbWUgdG8gYXBwbHkgdG8gU3R1ZGlvLlxuICAgICAqXG4gICAgICogQGRlZmF1bHQgc3R1ZGlvVGhlbWVcbiAgICAgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgdGhlbWU6IEFnU3R1ZGlvVGhlbWUgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgLyoqIElmIHlvdXIgdGhlbWUgdXNlcyBhIGZvbnQgdGhhdCBpcyBhdmFpbGFibGUgb24gR29vZ2xlIEZvbnRzLCBwYXNzIHRydWUgdG8gbG9hZCBpdCBmcm9tIEdvb2dsZSdzIENETi5cbiAgICAgKi9cbiAgICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUgfSkgcHVibGljIGxvYWRUaGVtZUdvb2dsZUZvbnRzOiBib29sZWFuIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBUaGUgQ1NTIGxheWVyIHRoYXQgdGhpcyB0aGVtZSBzaG91bGQgYmUgcmVuZGVyZWQgb250by4gV2hlbiBzcGVjaWZpZWQsXG4gICAgICogU3R1ZGlvIENTUyB3aWxsIGJlIHdyYXBwZWQgaW4gYSBgQGxheWVyICR7dGhlbWVDc3NMYXllcn0geyAuLi4gfWAgYmxvY2suXG4gICAgICpcbiAgICAgKiBOT1RFOiB3aGVuIHNwZWNpZnlpbmcgYHRoZW1lQ3NzTGF5ZXJgIHdlIHJlY29tbWVuZCBzZXR0aW5nXG4gICAgICogYHRoZW1lU3R5bGVDb250YWluZXJgIHRvIGBkb2N1bWVudC5ib2R5YCB0byBlbnN1cmUgdGhhdCBTdHVkaW8gQ1NTXG4gICAgICogY29tZXMgYWZ0ZXIgeW91ciBhcHBsaWNhdGlvbiBDU1MsIGFsbG93aW5nIHlvdXIgYXBwbGljYXRpb24gdG8gc2V0IHRoZVxuICAgICAqIG9yZGVyIG9mIGxheWVycy5cbiAgICAgKlxuICAgICAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQ1NTL0BsYXllclxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyB0aGVtZUNzc0xheWVyOiBzdHJpbmcgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgLyoqIFRoZSBub25jZSBhdHRyaWJ1dGUgdG8gc2V0IG9uIHN0eWxlIGVsZW1lbnRzIGFkZGVkIHRvIHRoZSBkb2N1bWVudCBieVxuICAgICAqIHRoZW1lcy4gSWYgXCJmb29cIiBpcyBwYXNzZWQgdG8gdGhpcyBwcm9wZXJ0eSwgU3R1ZGlvIGNhbiB1c2UgdGhlIENvbnRlbnRcbiAgICAgKiBTZWN1cml0eSBQb2xpY3kgYHN0eWxlLXNyYyAnbm9uY2UtZm9vJ2AsIGluc3RlYWQgb2YgdGhlIGxlc3Mgc2VjdXJlXG4gICAgICogYHN0eWxlLXNyYyAndW5zYWZlLWlubGluZSdgLlxuICAgICAqXG4gICAgICogTm90ZTogQ1NQIG5vbmNlcyBhcmUgZ2xvYmFsIHRvIGEgcGFnZSwgd2hlcmUgYSBwYWdlIGhhcyBtdWx0aXBsZSBTdHVkaW8gY29tcG9uZW50cyxcbiAgICAgKiBldmVyeSBvbmUgbXVzdCBoYXZlIHRoZSBzYW1lIHN0eWxlTm9uY2Ugc2V0LlxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBzdHlsZU5vbmNlOiBzdHJpbmcgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgLyoqIEFuIGVsZW1lbnQgdG8gaW5zZXJ0IHN0eWxlIGVsZW1lbnRzIGludG8gd2hlbiBpbmplY3Rpbmcgc3R5bGVzIGludG8gdGhlXG4gICAgICogU3R1ZGlvLiBTdHlsZXMgYXJlIGluc2VydGVkIGF0IHRoZSBzdGFydCBvZiB0aGUgZWxlbWVudC5cbiAgICAgKlxuICAgICAqIElmIHVuZGVmaW5lZCwgc3R5bGVzIHdpbGwgYmUgYWRkZWQgdG8gdGhlIGRvY3VtZW50IGhlYWQgZm9yIFN0dWRpbyBjb21wb25lbnRzXG4gICAgICogcmVuZGVyZWQgaW4gdGhlIG1haW4gZG9jdW1lbnQgZnJhZ21lbnQsIG9yIHRvIFN0dWRpbyB3cmFwcGVyIGVsZW1lbnRcbiAgICAgKiBmb3Igb3RoZXIgU3R1ZGlvIGNvbXBvbmVudHMgKGUuZy4gdGhvc2UgcmVuZGVyZWQgaW4gYSBzaGFkb3cgRE9NIG9yIGRldGFjaGVkIGZyb20gdGhlXG4gICAgICogZG9jdW1lbnQpLlxuICAgICAqXG4gICAgICogQGluaXRpYWxcbiAgICAgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgdGhlbWVTdHlsZUNvbnRhaW5lcjogKEhUTUxFbGVtZW50IHwgKCgpID0+IEhUTUxFbGVtZW50IHwgdm9pZCkpIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBBbGxvd3Mgb3ZlcnJpZGluZyB3aGF0IGBkb2N1bWVudGAgaXMgdXNlZC5cbiAgICAgKiBVc2UgdGhpcyB3aGVuIHlvdSB3YW50IFN0dWRpbyB0byB1c2UgYSBkaWZmZXJlbnQgYGRvY3VtZW50YCB0aGFuIHRoZSBvbmUgYXZhaWxhYmxlIG9uIHRoZSBnbG9iYWwgc2NvcGUuXG4gICAgICogVGhpcyBjYW4gaGFwcGVuIGlmIGRvY2tpbmcgb3V0IGNvbXBvbmVudHMgKHNvbWV0aGluZyB3aGljaCBFbGVjdHJvbiBzdXBwb3J0cykuXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIGdldERvY3VtZW50OiAoKCkgPT4gRG9jdW1lbnQpIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBEaXNhYmxlcyB0b3VjaCBzdXBwb3J0IChidXQgZG9lcyBub3QgcmVtb3ZlIHRoZSBicm93c2VyJ3MgZWZmb3J0cyB0byBzaW11bGF0ZSBtb3VzZSBldmVudHMgb24gdG91Y2gpLlxuICAgICAqIEBkZWZhdWx0IGZhbHNlXG4gICAgICogQGluaXRpYWxcbiAgICAgKi9cbiAgICBASW5wdXQoeyB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUgfSkgcHVibGljIHN1cHByZXNzVG91Y2g6IGJvb2xlYW4gfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgLyoqIEEgbWFwIG9mIGtleS0+dmFsdWUgcGFpcnMgZm9yIGxvY2FsaXNpbmcgdGV4dCB3aXRoaW4gU3R1ZGlvLlxuICAgICAqIEBpbml0aWFsXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIGxvY2FsZVRleHQ6IEFnU3R1ZGlvTG9jYWxlVGV4dCB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICAvKiogQSBjYWxsYmFjayBmb3IgbG9jYWxpc2luZyB0ZXh0IHdpdGhpbiBTdHVkaW8uXG4gICAgICogQGluaXRpYWxcbiAgICAgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgZ2V0TG9jYWxlVGV4dDogKChwYXJhbXM6IEFnU3R1ZGlvR2V0TG9jYWxlVGV4dFBhcmFtcykgPT4gc3RyaW5nKSB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICAvKiogUHJvdmlkZSBhIGN1c3RvbSBgc3R1ZGlvSWRgIGZvciB0aGlzIGluc3RhbmNlIG9mIFN0dWRpby4gVmFsdWUgd2lsbCBiZSBzZXQgb24gdGhlIHJvb3QgRE9NIG5vZGUgdXNpbmcgdGhlIGF0dHJpYnV0ZSBgc3R1ZGlvLWlkYCBhcyB3ZWxsIGFzIGJlaW5nIGFjY2Vzc2libGUgdmlhIHRoZSBgYXBpLmdldFN0dWRpb0lkKClgIG1ldGhvZC5cbiAgICAgKiBAaW5pdGlhbFxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBzdHVkaW9JZDogc3RyaW5nIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBQcm92aWRlcyBhIGNvbnRleHQgb2JqZWN0IHRoYXQgaXMgcHJvdmlkZWQgdG8gZGlmZmVyZW50IGNhbGxiYWNrcyBTdHVkaW8gdXNlcy4gVXNlZCBmb3IgcGFzc2luZyBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHRvIHRoZSBjYWxsYmFja3MgdXNlZCBieSB5b3VyIGFwcGxpY2F0aW9uLlxuICAgICAqIEBpbml0aWFsXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIGNvbnRleHQ6IGFueSA9IHVuZGVmaW5lZDtcbiAgICAvKiogSW5pdGlhbCBzdGF0ZSBmb3IgU3R1ZGlvLiBPbmx5IHJlYWQgb25jZSBvbiBpbml0aWFsaXphdGlvbi4gQ2FuIGJlIHVzZWQgaW4gY29uanVuY3Rpb24gd2l0aCBgYXBpLmdldFN0YXRlKClgIHRvIHNhdmUgYW5kIHJlc3RvcmUgU3R1ZGlvIHN0YXRlLlxuICAgICAqIEBpbml0aWFsXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIGluaXRpYWxTdGF0ZTogQWdSZXBvcnRTdGF0ZTxUUmVnaXN0cnk+IHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBEZWZpbmVzIHRoZSBkYXRhIHNvdXJjZXMgdXNlZCBieSBTdHVkaW8uXG4gICAgICpcbiAgICAgKiBJZiB1cGRhdGVkIGFmdGVyIGluaXRpYWxseSBiZWluZyBzZXQsIG9ubHkgY2hhbmdlcyB0byBzeW5jaHJvbm91cyBkYXRhIHdpbGwgYmUgcHJvY2Vzc2VkLlxuICAgICAqIEFueSBvdGhlciBjaGFuZ2VzIHdpbGwgYmUgaWdub3JlZCAoZS5nLiBhZGRpbmcvcmVtb3ZpbmcgZGF0YSBzb3VyY2VzLCB1cGRhdGluZyBmaWVsZHMsIGV0Yy4pXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIGRhdGE6IEFnRGF0YVNvdXJjZXNEZWZpbml0aW9uIHwgQWdEYXRhRW5naW5lIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBXaGljaCBtb2RlIFN0dWRpbyBpcyBpbi5cbiAgICAgKiBAZGVmYXVsdCAndmlldydcbiAgICAgKi9cbiAgICBASW5wdXQoKSBwdWJsaWMgbW9kZTogQWdTdHVkaW9Nb2RlIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBEZWZhdWx0IGxheW91dCBzdHlsaW5nLlxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBsYXlvdXQ6IFBhcnRpYWw8QWdQYWdlTGF5b3V0U3RhdGU+IHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBBSSBBc3Npc3RhbnQgY29uZmlndXJhdGlvbi5cbiAgICAgKlxuICAgICAqIE5PVEU6IFRoZSAgICAgKipBSSBBc3Npc3RhbnQqKiBpcyBhbiBleHBlcmltZW50YWwgZmVhdHVyZS4gQmVoYXZpb3VyIHdpbGwgYmVcbiAgICAgKiBzbGlnaHRseSBkaWZmZXJlbnQgZGVwZW5kaW5nIG9uIHRoZSBMTE0gYmVpbmcgdXNlZCwgYW5kIHJlc3VsdHMgY2FuIHZhcnkgYWNyb3NzIHF1ZXJpZXMuXG4gICAgICpcbiAgICAgKiBAaW5pdGlhbFxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBhaTogQWdBaUFzc2lzdGFudCB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICAvKiogRGF0YS1sYXllciBjb25maWd1cmF0aW9uLiBDb250cm9scyBiZWhhdmlvdXJzIHN1Y2ggYXMgZXhwb3J0IHJvdyBsaW1pdHMuXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIGRhdGFPcHRpb25zOiBBZ0RhdGFPcHRpb25zIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBAZGVwcmVjYXRlZCB2MS4xIFVzZSBgd2lkZ2V0c2AgdG8gY3VzdG9taXNlIHRoZSB3aWRnZXQgY29uZmlndXJhdGlvbnMgYW5kIGF2YWlsYWJsZSB3aWRnZXRzLFxuICAgICAqIGFuZCBgcGFnZWAgdG8gY3VzdG9taXNlIHRoZSBwYWdlIHNldHVwIGZvcm0uXG4gICAgICpcbiAgICAgKiBPdmVycmlkZXMgZm9yIHRoZSBsYXlvdXQgYW5kIHdpZGdldCBjb25maWdzLlxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBvdmVycmlkZXM6IEFnU3R1ZGlvT3ZlcnJpZGVzIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIC8qKiBDb25maWd1cmUgd2hpY2ggcGFuZWxzIGFyZSBkaXNwbGF5ZWQgYW5kIG9uIHdoaWNoIHNpZGUuXG4gICAgICovXG4gICAgQElucHV0KCkgcHVibGljIHBhbmVsczogQWdQYW5lbENvbmZpZyB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICAvKiogQ29uZmlndXJlIHBhZ2UgKGUuZy4gcGFnZSBzZXR1cCBmb3JtIGluIHBhZ2UgdGFiIG9mIGVkaXQgcGFuZWwpLlxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBwYWdlOiAoQWdQYWdlQ29uZmlnIHwgKChjb25maWc6IEFnUGFnZUNvbmZpZykgPT4gQWdQYWdlQ29uZmlnKSkgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgQElucHV0KCkgcHVibGljIHdpZGdldHM6XG4gICAgICAgIHwgKEFnV2lkZ2V0c0NvbmZpZzxUUmVnaXN0cnk+IHwgKCh3aWRnZXRzOiBBZ1dpZGdldHNDb25maWc8VFJlZ2lzdHJ5PikgPT4gQWdXaWRnZXRzQ29uZmlnPFRSZWdpc3RyeT4pKVxuICAgICAgICB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICAvKiogQ3VzdG9tIGNvbXBvbmVudHMgKGUuZy4gY3VzdG9tIHdpZGdldCBjb21wb25lbnRzKSBrZXllZCBieSBJRC5cbiAgICAgKiBVc2VkIHRvIHNoYXJlIGNvbXBvbmVudHMgd2hpY2ggY2FuIHRoZW4gYmUgcmVmZXJlbmNlZCBkaXJlY3RseSBieSBrZXkgaW4gdGhlIGRlZmluaXRpb25zLlxuICAgICAqL1xuICAgIEBJbnB1dCgpIHB1YmxpYyBjb21wb25lbnRzOiBUUmVnaXN0cnlbJ2NvbXBvbmVudHMnXSB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcblxuICAgIC8qKiBTdGF0ZSBoYXMgYmVlbiB1cGRhdGVkLlxuICAgICAqL1xuICAgIEBPdXRwdXQoKSBwdWJsaWMgc3RhdGVVcGRhdGVkOiBFdmVudEVtaXR0ZXI8QWdTdHVkaW9TdGF0ZVVwZGF0ZWRFdmVudD4gPVxuICAgICAgICBuZXcgRXZlbnRFbWl0dGVyPEFnU3R1ZGlvU3RhdGVVcGRhdGVkRXZlbnQ+KCk7XG4gICAgLyoqIFRoZSBBUEkgaGFzIGJlZW4gaW5pdGlhbGlzZWQgYW5kIGlzIHJlYWR5IGZvciBtb3N0IGNhbGxzLiBUaGUgZGF0YSBlbmdpbmUgaGFzIG5vdCBiZWVuIGluaXRpYWxpc2VkIHlldCwgYW5kIHRoZSBVSSBpcyBub3QgcmVhZHkuXG4gICAgICovXG4gICAgQE91dHB1dCgpIHB1YmxpYyBhcGlSZWFkeTogRXZlbnRFbWl0dGVyPEFnU3R1ZGlvQXBpUmVhZHlFdmVudD4gPSBuZXcgRXZlbnRFbWl0dGVyPEFnU3R1ZGlvQXBpUmVhZHlFdmVudD4oKTtcbiAgICAvKiogVGhlIGRhdGEgZW5naW5lIGhhcyBiZWVuIGluaXRpYWxpc2VkLCBhbmQgdGhlIFVJIGhhcyBiZWVuIGNyZWF0ZWQsIGJ1dCBtYXkgbm90IGJlIGZ1bGx5IHJlbmRlcmVkIHlldC5cbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgcHVibGljIHN0dWRpb1JlYWR5OiBFdmVudEVtaXR0ZXI8QWdTdHVkaW9SZWFkeUV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXI8QWdTdHVkaW9SZWFkeUV2ZW50PigpO1xuICAgIC8qKiBBbiBlcnJvciBoYXMgb2NjdXJyZWQgd2l0aGluIFN0dWRpby5cbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgcHVibGljIGVycm9yUmFpc2VkOiBFdmVudEVtaXR0ZXI8QWdTdHVkaW9FcnJvclJhaXNlZEV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXI8QWdTdHVkaW9FcnJvclJhaXNlZEV2ZW50PigpO1xuXG4gICAgLy8gQEVOREBcbn1cblxuY29uc3QgYm9vbGVhbk1peGVkU3R1ZGlvUHJvcGVydGllcyA9IG5ldyBTZXQ8c3RyaW5nPihfQk9PTEVBTl9NSVhFRF9TVFVESU9fUFJPUEVSVElFUyk7XG4vKipcbiAqIFVzZWQgdG8gc3VwcG9ydCB0aGUgdXNlciBzZXR0aW5nIGNvbWJpbmVkIGJvb2xlYW4gYW5kIHN0cmluZyAvIG9iamVjdCBwcm9wZXJ0aWVzXG4gKiBhcyBwbGFpbiBIVE1MIGF0dHJpYnV0ZXMgYW5kIHVzIGNvcnJlY3RseSBtYXBwaW5nIHRoYXQgdG8gdHJ1ZS5cbiAqIEZvciBleGFtcGxlIGNlbGxTZWN0aW9uIGNhbiBiZSBib29sZWFuIG9yIGFuIG9iamVjdFxuICovXG5mdW5jdGlvbiBnZXRWYWx1ZU9yQ29lcmNlZFZhbHVlKGtleTogc3RyaW5nLCB2YWx1ZVRvVXNlOiBhbnkpOiBhbnkge1xuICAgIGlmIChib29sZWFuTWl4ZWRTdHVkaW9Qcm9wZXJ0aWVzLmhhcyhrZXkpKSB7XG4gICAgICAgIC8vIEhhbmRsZSBwbGFpbiBIVE1MIGJvb2xlYW4gYXR0cmlidXRlcyBhbmQgY29udmVydCB0aGVtIHRvIGJvb2xlYW4gdmFsdWVzXG4gICAgICAgIC8vIEFsc28gaGFuZGxlIHRoZSBmYWxzZSBzdHJpbmcgY2FzZSB0byBtYXRjaCBBbmd1bGFyIGJvb2xlYW4gYXR0cmlidXRlc1xuICAgICAgICByZXR1cm4gdmFsdWVUb1VzZSA9PT0gJycgPyB0cnVlIDogdmFsdWVUb1VzZSA9PT0gJ2ZhbHNlJyA/IGZhbHNlIDogdmFsdWVUb1VzZTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlVG9Vc2U7XG59XG4iXX0=
@@ -0,0 +1,107 @@
1
+ import { Component, Injectable, ViewContainerRef, inject } from '@angular/core';
2
+ import { _BaseComponentWrapper } from 'ag-studio';
3
+ import { _removeFromParent } from 'ag-grid-enterprise';
4
+ import * as i0 from "@angular/core";
5
+ // To speed up the removal of custom components we create a number of shards to contain them.
6
+ // Removing a single component calls a function within Angular called removeFromArray.
7
+ // This is a lot faster if the array is smaller.
8
+ export class AgComponentContainer {
9
+ constructor() {
10
+ this.vcr = inject(ViewContainerRef);
11
+ }
12
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AgComponentContainer, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
13
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: AgComponentContainer, selector: "ag-component-container", ngImport: i0, template: '', isInline: true }); }
14
+ }
15
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AgComponentContainer, decorators: [{
16
+ type: Component,
17
+ args: [{
18
+ selector: 'ag-component-container',
19
+ template: '',
20
+ }]
21
+ }] });
22
+ const NUM_SHARDS = 16;
23
+ let shardIdx = 0;
24
+ function createComponentContainers(vcr) {
25
+ const containerMap = new Map();
26
+ for (let i = 0; i < NUM_SHARDS; i++) {
27
+ const container = vcr.createComponent(AgComponentContainer);
28
+ containerMap.set(i, container);
29
+ _removeFromParent(container.location.nativeElement);
30
+ }
31
+ return containerMap;
32
+ }
33
+ export class AngularFrameworkComponentWrapper extends _BaseComponentWrapper {
34
+ setViewContainerRef(viewContainerRef, angularFrameworkOverrides) {
35
+ this.viewContainerRef = viewContainerRef;
36
+ this.frameworkOverrides = angularFrameworkOverrides;
37
+ }
38
+ createWrapper(OriginalConstructor) {
39
+ this.compShards ??= createComponentContainers(this.viewContainerRef);
40
+ return new DynamicAgNg2Component(this.frameworkOverrides, this, OriginalConstructor);
41
+ }
42
+ createComponent(componentType) {
43
+ shardIdx = (shardIdx + 1) % NUM_SHARDS;
44
+ const container = this.compShards.get(shardIdx);
45
+ return container.instance.vcr.createComponent(componentType);
46
+ }
47
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AngularFrameworkComponentWrapper, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
48
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AngularFrameworkComponentWrapper }); }
49
+ }
50
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AngularFrameworkComponentWrapper, decorators: [{
51
+ type: Injectable
52
+ }] });
53
+ class DynamicAgNg2Component {
54
+ constructor(frameworkOverrides, frameworkCompWrapper, OriginalConstructor) {
55
+ this.frameworkOverrides = frameworkOverrides;
56
+ this.frameworkCompWrapper = frameworkCompWrapper;
57
+ this.OriginalConstructor = OriginalConstructor;
58
+ }
59
+ init(params) {
60
+ return new Promise((resolve) => {
61
+ this.frameworkOverrides.runInsideAngular(() => {
62
+ this._init(params).then((result) => {
63
+ this._componentRef.changeDetectorRef.detectChanges();
64
+ resolve(result);
65
+ });
66
+ });
67
+ });
68
+ }
69
+ async _init(params) {
70
+ this._componentRef = this.frameworkCompWrapper.createComponent(this.OriginalConstructor);
71
+ const instance = this._componentRef.instance;
72
+ this._frameworkComponentInstance = instance;
73
+ this._eGui = this._componentRef.location.nativeElement;
74
+ // Angular appends the component to the DOM, so remove it
75
+ _removeFromParent(this._eGui);
76
+ return instance.agInit?.(params);
77
+ }
78
+ async refresh(params) {
79
+ return this.frameworkOverrides.runInsideAngular(() => this._frameworkComponentInstance.refresh?.(params));
80
+ }
81
+ getGui() {
82
+ return this._eGui;
83
+ }
84
+ /** `getGui()` returns the `ng-component` element. This returns the actual root element. */
85
+ getRootElement() {
86
+ return this._eGui.firstChild;
87
+ }
88
+ destroy() {
89
+ if (typeof this._frameworkComponentInstance?.destroy === 'function') {
90
+ this._frameworkComponentInstance.destroy();
91
+ }
92
+ this._componentRef?.destroy();
93
+ }
94
+ getFrameworkComponentInstance() {
95
+ return this._frameworkComponentInstance;
96
+ }
97
+ hasMethod(name) {
98
+ return this._frameworkComponentInstance[name] != null;
99
+ }
100
+ callMethod(name, args) {
101
+ return this.frameworkOverrides.runInsideAngular(() => this._frameworkComponentInstance[name](...args));
102
+ }
103
+ addMethod(name, callback) {
104
+ this[name] = callback;
105
+ }
106
+ }
107
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5ndWxhckZyYW1ld29ya0NvbXBvbmVudFdyYXBwZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9hZy1zdHVkaW8tYW5ndWxhci9zcmMvbGliL2FuZ3VsYXJGcmFtZXdvcmtDb21wb25lbnRXcmFwcGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLGdCQUFnQixFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVoRixPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFbEQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7O0FBS3ZELDZGQUE2RjtBQUM3RixzRkFBc0Y7QUFDdEYsZ0RBQWdEO0FBS2hELE1BQU0sT0FBTyxvQkFBb0I7SUFKakM7UUFLVyxRQUFHLEdBQUcsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUM7S0FDekM7K0dBRlksb0JBQW9CO21HQUFwQixvQkFBb0IsOERBRm5CLEVBQUU7OzRGQUVILG9CQUFvQjtrQkFKaEMsU0FBUzttQkFBQztvQkFDUCxRQUFRLEVBQUUsd0JBQXdCO29CQUNsQyxRQUFRLEVBQUUsRUFBRTtpQkFDZjs7QUFJRCxNQUFNLFVBQVUsR0FBRyxFQUFFLENBQUM7QUFDdEIsSUFBSSxRQUFRLEdBQUcsQ0FBQyxDQUFDO0FBRWpCLFNBQVMseUJBQXlCLENBQUMsR0FBcUI7SUFDcEQsTUFBTSxZQUFZLEdBQUcsSUFBSSxHQUFHLEVBQThDLENBQUM7SUFDM0UsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFVBQVUsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ2xDLE1BQU0sU0FBUyxHQUFHLEdBQUcsQ0FBQyxlQUFlLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUM1RCxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxTQUFT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QUksQ0FBQyxLQUFLLENBQUM7SUFDdEIsQ0FBQztJQUVELDJGQUEyRjtJQUMzRixjQUFjO1FBQ1YsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQXlCLENBQUM7SUFDaEQsQ0FBQztJQUVELE9BQU87UUFDSCxJQUFJLE9BQU8sSUFBSSxDQUFDLDJCQUEyQixFQUFFLE9BQU8sS0FBSyxVQUFVLEVBQUUsQ0FBQztZQUNsRSxJQUFJLENBQUMsMkJBQTJCLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDL0MsQ0FBQztRQUNELElBQUksQ0FBQyxhQUFhLEVBQUUsT0FBTyxFQUFFLENBQUM7SUFDbEMsQ0FBQztJQUVELDZCQUE2QjtRQUN6QixPQUFPLElBQUksQ0FBQywyQkFBMkIsQ0FBQztJQUM1QyxDQUFDO0lBRUQsU0FBUyxDQUFDLElBQVk7UUFDbEIsT0FBTyxJQUFJLENBQUMsMkJBQTJCLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDO0lBQzFELENBQUM7SUFFRCxVQUFVLENBQUMsSUFBWSxFQUFFLElBQWdCO1FBQ3JDLE9BQU8sSUFBSSxDQUFDLGtCQUFrQixDQUFDLGdCQUFnQixDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQywyQkFBMkIsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDM0csQ0FBQztJQUVELFNBQVMsQ0FBQyxJQUFZLEVBQUUsUUFBaUM7UUFDcEQsSUFBWSxDQUFDLElBQUksQ0FBQyxHQUFHLFFBQVEsQ0FBQztJQUNuQyxDQUFDO0NBQ0oiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IENvbXBvbmVudFJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tcG9uZW50LCBJbmplY3RhYmxlLCBWaWV3Q29udGFpbmVyUmVmLCBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB0eXBlIHsgX0ZyYW1ld29ya0NvbXBvbmVudFdyYXBwZXIsIF9XcmFwcGFibGVJbnRlcmZhY2UgfSBmcm9tICdhZy1zdHVkaW8nO1xuaW1wb3J0IHsgX0Jhc2VDb21wb25lbnRXcmFwcGVyIH0gZnJvbSAnYWctc3R1ZGlvJztcblxuaW1wb3J0IHsgX3JlbW92ZUZyb21QYXJlbnQgfSBmcm9tICdhZy1ncmlkLWVudGVycHJpc2UnO1xuXG5pbXBvcnQgdHlwZSB7IEFuZ3VsYXJGcmFtZXdvcmtPdmVycmlkZXMgfSBmcm9tICcuL2FuZ3VsYXJGcmFtZXdvcmtPdmVycmlkZXMnO1xuaW1wb3J0IHR5cGUgeyBBZ0N1c3RvbUNvbXBvbmVudCB9IGZyb20gJy4vaW50ZXJmYWNlcyc7XG5cbi8vIFRvIHNwZWVkIHVwIHRoZSByZW1vdmFsIG9mIGN1c3RvbSBjb21wb25lbnRzIHdlIGNyZWF0ZSBhIG51bWJlciBvZiBzaGFyZHMgdG8gY29udGFpbiB0aGVtLlxuLy8gUmVtb3ZpbmcgYSBzaW5nbGUgY29tcG9uZW50IGNhbGxzIGEgZnVuY3Rpb24gd2l0aGluIEFuZ3VsYXIgY2FsbGVkIHJlbW92ZUZyb21BcnJheS5cbi8vIFRoaXMgaXMgYSBsb3QgZmFzdGVyIGlmIHRoZSBhcnJheSBpcyBzbWFsbGVyLlxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdhZy1jb21wb25lbnQtY29udGFpbmVyJyxcbiAgICB0ZW1wbGF0ZTogJycsXG59KVxuZXhwb3J0IGNsYXNzIEFnQ29tcG9uZW50Q29udGFpbmVyIHtcbiAgICBwdWJsaWMgdmNyID0gaW5qZWN0KFZpZXdDb250YWluZXJSZWYpO1xufVxuY29uc3QgTlVNX1NIQVJEUyA9IDE2O1xubGV0IHNoYXJkSWR4ID0gMDtcblxuZnVuY3Rpb24gY3JlYXRlQ29tcG9uZW50Q29udGFpbmVycyh2Y3I6IFZpZXdDb250YWluZXJSZWYpOiBNYXA8bnVtYmVyLCBDb21wb25lbnRSZWY8QWdDb21wb25lbnRDb250YWluZXI+PiB7XG4gICAgY29uc3QgY29udGFpbmVyTWFwID0gbmV3IE1hcDxudW1iZXIsIENvbXBvbmVudFJlZjxBZ0NvbXBvbmVudENvbnRhaW5lcj4+KCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBOVU1fU0hBUkRTOyBpKyspIHtcbiAgICAgICAgY29uc3QgY29udGFpbmVyID0gdmNyLmNyZWF0ZUNvbXBvbmVudChBZ0NvbXBvbmVudENvbnRhaW5lcik7XG4gICAgICAgIGNvbnRhaW5lck1hcC5zZXQoaSwgY29udGFpbmVyKTtcbiAgICAgICAgX3JlbW92ZUZyb21QYXJlbnQoY29udGFpbmVyLmxvY2F0aW9uLm5hdGl2ZUVsZW1lbnQpO1xuICAgIH1cbiAgICByZXR1cm4gY29udGFpbmVyTWFwO1xufVxuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgQW5ndWxhckZyYW1ld29ya0NvbXBvbmVudFdyYXBwZXJcbiAgICBleHRlbmRzIF9CYXNlQ29tcG9uZW50V3JhcHBlcjxfV3JhcHBhYmxlSW50ZXJmYWNlPlxuICAgIGltcGxlbWVudHMgX0ZyYW1ld29ya0NvbXBvbmVudFdyYXBwZXJcbntcbiAgICBwcml2YXRlIHZpZXdDb250YWluZXJSZWY6IFZpZXdDb250YWluZXJSZWY7XG4gICAgcHJpdmF0ZSBmcmFtZXdvcmtPdmVycmlkZXM6IEFuZ3VsYXJGcmFtZXdvcmtPdmVycmlkZXM7XG4gICAgcHJpdmF0ZSBjb21wU2hhcmRzOiBNYXA8bnVtYmVyLCBDb21wb25lbnRSZWY8QWdDb21wb25lbnRDb250YWluZXI+PjtcblxuICAgIHNldFZpZXdDb250YWluZXJSZWYodmlld0NvbnRhaW5lclJlZjogVmlld0NvbnRhaW5lclJlZiwgYW5ndWxhckZyYW1ld29ya092ZXJyaWRlczogQW5ndWxhckZyYW1ld29ya092ZXJyaWRlcykge1xuICAgICAgICB0aGlzLnZpZXdDb250YWluZXJSZWYgPSB2aWV3Q29udGFpbmVyUmVmO1xuICAgICAgICB0aGlzLmZyYW1ld29ya092ZXJyaWRlcyA9IGFuZ3VsYXJGcmFtZXdvcmtPdmVycmlkZXM7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGNyZWF0ZVdyYXBwZXIoT3JpZ2luYWxDb25zdHJ1Y3RvcjogeyBuZXcgKCk6IGFueSB9KTogX1dyYXBwYWJsZUludGVyZmFjZSB7XG4gICAgICAgIHRoaXMuY29tcFNoYXJkcyA/Pz0gY3JlYXRlQ29tcG9uZW50Q29udGFpbmVycyh0aGlzLnZpZXdDb250YWluZXJSZWYpO1xuICAgICAgICByZXR1cm4gbmV3IER5bmFtaWNBZ05nMkNvbXBvbmVudCh0aGlzLmZyYW1ld29ya092ZXJyaWRlcywgdGhpcywgT3JpZ2luYWxDb25zdHJ1Y3Rvcik7XG4gICAgfVxuXG4gICAgY3JlYXRlQ29tcG9uZW50PFQ+KGNvbXBvbmVudFR5cGU6IHsgbmV3ICguLi5hcmdzOiBhbnlbXSk6IFQgfSk6IENvbXBvbmVudFJlZjxUPiB7XG4gICAgICAgIHNoYXJkSWR4ID0gKHNoYXJkSWR4ICsgMSkgJSBOVU1fU0hBUkRTO1xuICAgICAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLmNvbXBTaGFyZHMuZ2V0KHNoYXJkSWR4KSE7XG4gICAgICAgIHJldHVybiBjb250YWluZXIuaW5zdGFuY2UudmNyLmNyZWF0ZUNvbXBvbmVudChjb21wb25lbnRUeXBlKTtcbiAgICB9XG59XG5cbmNsYXNzIER5bmFtaWNBZ05nMkNvbXBvbmVudDxQPiBpbXBsZW1lbnRzIF9XcmFwcGFibGVJbnRlcmZhY2Uge1xuICAgIHByaXZhdGUgX2VHdWk6IEhUTUxFbGVtZW50O1xuICAgIHByaXZhdGUgX2NvbXBvbmVudFJlZjogQ29tcG9uZW50UmVmPEFnQ3VzdG9tQ29tcG9uZW50PFA+PjtcbiAgICBwcml2YXRlIF9mcmFtZXdvcmtDb21wb25lbnRJbnN0YW5jZTogYW55OyAvLyB0aGUgdXNlcidzIGNvbXBvbmVudCAtIGZvciBhY2Nlc3NpbmcgbWV0aG9kcyB0aGV5IGNyZWF0ZVxuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByaXZhdGUgZnJhbWV3b3JrT3ZlcnJpZGVzOiBBbmd1bGFyRnJhbWV3b3JrT3ZlcnJpZGVzLFxuICAgICAgICBwcml2YXRlIGZyYW1ld29ya0NvbXBXcmFwcGVyOiBBbmd1bGFyRnJhbWV3b3JrQ29tcG9uZW50V3JhcHBlcixcbiAgICAgICAgcHJpdmF0ZSBPcmlnaW5hbENvbnN0cnVjdG9yOiB7IG5ldyAoKTogYW55IH1cbiAgICApIHt9XG5cbiAgICBpbml0KHBhcmFtczogUCk6IFByb21pc2U8YW55PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5mcmFtZXdvcmtPdmVycmlkZXMucnVuSW5zaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5faW5pdChwYXJhbXMpLnRoZW4oKHJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9jb21wb25lbnRSZWYuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBfaW5pdChwYXJhbXM6IFApOiBQcm9taXNlPGFueT4ge1xuICAgICAgICB0aGlzLl9jb21wb25lbnRSZWYgPSB0aGlzLmZyYW1ld29ya0NvbXBXcmFwcGVyLmNyZWF0ZUNvbXBvbmVudCh0aGlzLk9yaWdpbmFsQ29uc3RydWN0b3IpO1xuICAgICAgICBjb25zdCBpbnN0YW5jZSA9IHRoaXMuX2NvbXBvbmVudFJlZi5pbnN0YW5jZTtcbiAgICAgICAgdGhpcy5fZnJhbWV3b3JrQ29tcG9uZW50SW5zdGFuY2UgPSBpbnN0YW5jZTtcbiAgICAgICAgdGhpcy5fZUd1aSA9IHRoaXMuX2NvbXBvbmVudFJlZi5sb2NhdGlvbi5uYXRpdmVFbGVtZW50O1xuICAgICAgICAvLyBBbmd1bGFyIGFwcGVuZHMgdGhlIGNvbXBvbmVudCB0byB0aGUgRE9NLCBzbyByZW1vdmUgaXRcbiAgICAgICAgX3JlbW92ZUZyb21QYXJlbnQodGhpcy5fZUd1aSk7XG5cbiAgICAgICAgcmV0dXJuIGluc3RhbmNlLmFnSW5pdD8uKHBhcmFtcyk7XG4gICAgfVxuXG4gICAgYXN5bmMgcmVmcmVzaChwYXJhbXM6IFApOiBQcm9taXNlPGFueT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5mcmFtZXdvcmtPdmVycmlkZXMucnVuSW5zaWRlQW5ndWxhcigoKSA9PiB0aGlzLl9mcmFtZXdvcmtDb21wb25lbnRJbnN0YW5jZS5yZWZyZXNoPy4ocGFyYW1zKSk7XG4gICAgfVxuXG4gICAgZ2V0R3VpKCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VHdWk7XG4gICAgfVxuXG4gICAgLyoqIGBnZXRHdWkoKWAgcmV0dXJucyB0aGUgYG5nLWNvbXBvbmVudGAgZWxlbWVudC4gVGhpcyByZXR1cm5zIHRoZSBhY3R1YWwgcm9vdCBlbGVtZW50LiAqL1xuICAgIGdldFJvb3RFbGVtZW50KCk6IEhUTUxFbGVtZW50IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VHdWkuZmlyc3RDaGlsZCBhcyBIVE1MRWxlbWVudDtcbiAgICB9XG5cbiAgICBkZXN0cm95KCk6IHZvaWQge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuX2ZyYW1ld29ya0NvbXBvbmVudEluc3RhbmNlPy5kZXN0cm95ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLl9mcmFtZXdvcmtDb21wb25lbnRJbnN0YW5jZS5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fY29tcG9uZW50UmVmPy5kZXN0cm95KCk7XG4gICAgfVxuXG4gICAgZ2V0RnJhbWV3b3JrQ29tcG9uZW50SW5zdGFuY2UoKTogYW55IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZyYW1ld29ya0NvbXBvbmVudEluc3RhbmNlO1xuICAgIH1cblxuICAgIGhhc01ldGhvZChuYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2ZyYW1ld29ya0NvbXBvbmVudEluc3RhbmNlW25hbWVdICE9IG51bGw7XG4gICAgfVxuXG4gICAgY2FsbE1ldGhvZChuYW1lOiBzdHJpbmcsIGFyZ3M6IElBcmd1bWVudHMpOiBhbnkge1xuICAgICAgICByZXR1cm4gdGhpcy5mcmFtZXdvcmtPdmVycmlkZXMucnVuSW5zaWRlQW5ndWxhcigoKSA9PiB0aGlzLl9mcmFtZXdvcmtDb21wb25lbnRJbnN0YW5jZVtuYW1lXSguLi5hcmdzKSk7XG4gICAgfVxuXG4gICAgYWRkTWV0aG9kKG5hbWU6IHN0cmluZywgY2FsbGJhY2s6ICguLi5hcmdzOiBhbnlbXSkgPT4gYW55KTogdm9pZCB7XG4gICAgICAgICh0aGlzIGFzIGFueSlbbmFtZV0gPSBjYWxsYmFjaztcbiAgICB9XG59XG4iXX0=