@lumiscaphe/ng-viewer 14.0.0 → 14.2.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 CHANGED
@@ -7,203 +7,221 @@ Official Angular component for Lumiscaphe 3D Viewer
7
7
  ```
8
8
  $ npm i @lumiscaphe/ng-viewer
9
9
  ```
10
+
10
11
  or
12
+
11
13
  ```
12
14
  $ yarn add @lumiscaphe/ng-viewer
13
15
  ```
14
16
 
15
- ## The basics
17
+ ## Usage
16
18
 
17
- Import Lumiscaphe Viewer module in your module:
19
+ ### Import
18
20
 
19
21
  ```javascript
20
22
  import { NgViewerModule } from '@lumiscaphe/ng-viewer';
23
+ ```
24
+
25
+ ### Basic
21
26
 
22
- @NgModule({
23
- ...,
24
- imports: [
25
- ...,
26
- NgViewerModule
27
- ],
28
- ...
29
- })
27
+ ```html
28
+ <NgViewer [server]="server" [scene]="scene" [view]="view"></NgViewer>
30
29
  ```
31
30
 
32
- Prepare Lumiscaphe Viewer data in your component:
33
31
  ```javascript
34
32
  server = 'https://wr.lumiscaphe.com';
35
33
 
36
- scene = [{
37
- database: 'ee294840-5689-49b0-9edb-527598602df0',
38
- configuration: 'Bin.Blue/Cabin.Yellow/Style.Design1/Wheels.Red',
39
- animations: ['LeftDoor'],
40
- }];
34
+ scene = [
35
+ {
36
+ database: 'ee294840-5689-49b0-9edb-527598602df0',
37
+ configuration: 'Bin.Blue/Cabin.Yellow/Style.Design1/Wheels.Red'
38
+ }
39
+ ];
41
40
 
42
41
  view = {
43
42
  mode: 'image',
44
- camera: 'EXTER/1',
45
- background: 'product',
43
+ camera: 'EXTER/1'
46
44
  };
45
+ ```
47
46
 
48
- // Optional
49
- transition = {
50
- fromPosition: 0,
51
- toPosition: 2,
52
- animation: {
53
- name: 'Porte Gauche',
54
- camera: '/Camera_Ext',
55
- duration: 1,
56
- reverse: false,
57
- },
58
- };
47
+ ### Hotspot
59
48
 
60
- // Optional - default values
61
- encoder = {
62
- format: 'jpeg',
63
- quality: 80,
64
- };
49
+ Hotspots are interactive elements that can be selected to engage in additional content or media.\
50
+ Hotspots are overlaid on top of the viewer to provide additional media for informational purposes.
65
51
 
66
- // Optional - default values
67
- parameters = {
68
- antialiasing: false,
69
- superSampling: 2,
70
- };
52
+ ```html
53
+ <NgViewer ... [hotspots]="hotspots">
54
+ <ng-template #hotspotTemplate let-hotspot let-index="index">
55
+ <ng-container *ngIf="hotspot.visibility === 'Visible'">
56
+ <button>{{ index + 1 }}</button>
57
+ </ng-container>
58
+ </ng-template>
59
+ </NgViewer>
60
+ ```
61
+
62
+ ```typescript
63
+ hotspots = [{ x: 0, y: 0, z: 0 }];
64
+ ```
65
+
66
+ ### Pick
71
67
 
72
- // Optional - default values
73
- onLoadStart() {
74
- }
68
+ Pick allow to retrieve information of a 3D point from a 2D point.
75
69
 
76
- onLoadProgress() {
77
- }
70
+ ```html
71
+ <NgViewer ...></NgViewer>
78
72
 
79
- onLoadEnd() {
80
- }
73
+ <button type="button" (click)="pick()">Pick</button>
74
+ ```
81
75
 
82
- onLoadError() {
83
- }
76
+ ```typescript
77
+ import { NgViewerComponent } from '@lumiscaphe/ng-viewer';
84
78
 
85
- onVrcubeInteraction() {
86
- }
79
+ ...
87
80
 
88
- onVrobjectInteraction() {
89
- }
81
+ @ViewChild(NgViewerComponent) viewer: NgViewerComponent;
82
+ @ViewChild(ngViewerComponent, { read: ElementRef }) viewerElement: ElementRef<HTMLDivElement>;
90
83
 
91
- ```
84
+ ...
92
85
 
93
- Add Lumiscaphe Viewer component in your HTML:
94
- ```html
95
- <NgViewer [server]="server" [scene]="scene" [view]="view" [parameters]="parameters" [encoder]="encoder" (onLoadStart)="onLoadStart()" (onLoadProgress)="onLoadProgress()" (onLoadEnd)="onLoadEnd()" (onLoadError)="onLoadError()"></NgViewer>
86
+ pick(): void {
87
+ this.viewerElement.nativeElement.addEventListener('click', e => {
88
+ const position = { x: e.clientX, y: e.clientY };
89
+ this.viewer.pick(position).then(pickResult => console.log(pickResult))
90
+ }, { once: true });
91
+ };
96
92
  ```
97
93
 
98
- ## Scene
94
+ ## API
99
95
 
100
- A scene is an array of products defined with:
101
- * `database` : product 3D model guid string
102
- * `configuration` : product configuration as a string of concatenated values separated by a slash
103
- * `animations` : product animations as an array of string
96
+ ### Properties
104
97
 
105
- Basic scenes should contain only one product.
98
+ | Name | Type | Default | Description |
99
+ | -------------- | ------------ | ------------------------------------------- | -------------------------------- |
100
+ | **server** | `string` | `undefined` | WebRender URL to use. |
101
+ | **scene** | `Scene` | `undefined` | Scene to render. |
102
+ | **view** | `View` | `undefined` | View to render. |
103
+ | **api** | `'v1'\|'v2'` | `'v1'` | API version to use. |
104
+ | **encoder** | `Encoder` | `{ format: 'jpeg', quality: 80 }` | Image encoder to use. |
105
+ | **parameters** | `Parameters` | `{ antialiasing: false, superSampling: 2 }` | Rendering parameters to use. |
106
+ | **hotspots** | `Vector3D[]` | `undefined` | Hotspot array to display. |
107
+ | **vrcube** | `VRCube` | `undefined` | VRCube point of view to display. |
108
+ | **vrobject** | `VRObject` | `undefined` | VRObject position to display. |
106
109
 
107
- ## Decor
110
+ ### Emitters
108
111
 
109
- Two ways to drive scene decor.
112
+ | Name | Parameters | Description |
113
+ | ------------------------- | -------------------- | ------------------------------------------------------ |
114
+ | **onLoadStart** | `progress: number` | Callback to invoke when load starts. |
115
+ | **onLoadProgress** | `progress: number` | Callback to invoke when load makes progress. |
116
+ | **onLoadEnd** | `progress: number` | Callback to invoke when load ends. |
117
+ | **onLoadError** | `Error` | Callback to invoke when load failed. |
118
+ | **onInteraction** | `VRCube \| VRObject` | Callback to invoke when interaction happened. |
119
+ | **onVrcubeInteraction** | `VRCube` | Callback to invoke when VRCube interaction happened. |
120
+ | **onVrobjectInteraction** | `VRObject` | Callback to invoke when VRObject interaction happened. |
110
121
 
111
- **Integrated**
122
+ ### Methods
112
123
 
113
- When a 3D model contains integrated decors, it can be change through product configuration. For example: add `ENV.STUDIO` or `ENV.ALPES` to product configuration string.
124
+ | Name | Parameters | Description | Returns |
125
+ | ------------ | --------------------------------- | ------------------------------------ | -------------------- |
126
+ | **pick** | `position: Position` | Get the 3D point from a 2D position. | `PickResult` |
127
+ | **snapshot** | `type: string`, `quality: number` | Get a snapshot of the viewer. | `string` - Image URL |
114
128
 
115
- ```javascript
116
- const scene = [{
117
- database: 'ee294840-5689-49b0-9edb-527598602df0',
118
- configuration: 'Bin.Blue/Cabin.Yellow/Style.Design1/Wheels.Red/ENV.ALPES',
119
- animations: ['LeftDoor'],
120
- }];
121
- ```
129
+ ### Templates
122
130
 
123
- **External**
131
+ | Name | Parameters | Description |
132
+ | ------------------- | ------------------------------------------------ | ------------------------ |
133
+ | **hotspotTemplate** | `context: { $implicit: Hotspot, index: number }` | Custom hotspot template. |
124
134
 
125
- When a 3D model does not contain integrated decors, it can be added with an external 3D model. For example:
135
+ ### Interfaces
126
136
 
127
- ```javascript
128
- const decorProduct = {
129
- database: '82c1f7e8-9ae4-4f00-b45c-c857e21a954f',
130
- translation: { x: 0, y: -0.12, z: 0 },
131
- };
137
+ #### Scene
132
138
 
133
- const product = {
134
- database: 'ee294840-5689-49b0-9edb-527598602df0',
135
- configuration: 'Bin.Blue/Cabin.Yellow/Style.Design1/Wheels.Red',
136
- animations: ['LeftDoor'],
137
- };
139
+ | Name | Type | Description |
140
+ | ----------------- | ---------- | -------------------------------------- |
141
+ | **database** | `string` | Database id of the 3D model. |
142
+ | **configuration** | `string` | Product configuration of the 3D model. |
143
+ | **animations** | `string[]` | Animations of the 3D model |
138
144
 
139
- const scene = [decorProduct, product];
140
- ```
145
+ #### View
146
+
147
+ | Name | Type | Description |
148
+ | ---------- | ------------------------------- | ---------------------------------------- |
149
+ | **mode** | `'image'\|'vrcube'\|'vrobject'` | Mode of the view. |
150
+ | **camera** | `string` | Camera or camera group name of the view. |
151
+
152
+ #### Encoder
153
+
154
+ | Name | Type | Description |
155
+ | ----------- | -------- | --------------------------------- |
156
+ | **format** | `'jpeg'` | Format of the encoder. |
157
+ | **quality** | `number` | Quality of the encoder (0 - 100). |
141
158
 
142
- Decor product is defined with:
143
- * `database` : decor product 3D model guid string
144
- * `translation` : decor product 3D position (e.g. decorDeltaAltitude)
159
+ #### Parameters
145
160
 
146
- Note: decor product should always be the first product in the scene.
161
+ | Name | Type | Description |
162
+ | ----------------- | ------ | ---------------------------------------------- |
163
+ | **superSampling** | number | Super sampling to use for antialiasing (1 -2). |
147
164
 
148
- ## View
165
+ #### Hotspot
149
166
 
150
- A view can be defined in the following modes:
167
+ | Name | Type | Description |
168
+ | ------------ | ----------- | --------------------------------------------------------------- |
169
+ | `id` | `string` | Id of the hotspot (when hotspot is provided by the 3D model). |
170
+ | `name` | `string` | Name of the hotspot (when hotspot is provided by the 3D model). |
171
+ | `position2D` | `Vector2D` | 2D position of the hotspot in the viewer. |
172
+ | `position3D` | `Vector3D` | 3D position of the hotspot. |
173
+ | `visibility` | `Visiblity` | Visiblity of the hotspot. |
151
174
 
152
- **Image**
153
- * `mode` : `image`
154
- * `camera` : camera path
155
- * `background` : view background mode (`product`, `transparent`, `gradient`)
175
+ #### VRCube
156
176
 
157
- **VRCube**
158
- * `mode` : `vrcube`
159
- * `camera` : camera path
160
- * `background` : view background mode (`product`, `transparent`, `gradient`)
177
+ | Name | Type | Description |
178
+ | ---- | ------------- | ---------------------------------------------- |
179
+ | pov | `PointOfView` | Point of view of the VRCube widget. |
180
+ | fov | `number` | Field of view in degrees of the VRCube widget. |
161
181
 
162
- **VRObject - animation**
163
- * `mode` : `vrobject`
164
- * `animation` : animation name
165
- * `camera` : camera path
166
- * `frames` : number of frames
167
- * `loop` : whether animation loops or not
168
- * `background` : view background mode (`product`, `transparent`, `gradient`)
182
+ #### VRObject
169
183
 
170
- **VRObject - bookmark set**
171
- * `mode` : `vrobject`
172
- * `camera` : camera group path
173
- * `background` : view background mode (`product`, `transparent`, `gradient`)
184
+ | Name | Type | Description |
185
+ | ---------- | -------- | ---------------------------------- |
186
+ | `position` | `number` | Image inde of the VRObject widget. |
174
187
 
175
- ## Transition
188
+ #### PickResult
176
189
 
177
- A transition can be set when loading a scene or setting a view with:
178
- * `fromPosition` : go to specific vrobject image at the beginning - optional
179
- * `toPosition` : go to specific vrobject image at the end - optional
180
- * `animation` :
181
- * `name`: animation name
182
- * `camera`: camera path to use for animation
183
- * `duration`: animation duration in seconds
184
- * `reverse`: whether to reverse animation direction
190
+ | Name | Type | Description |
191
+ | ----------- | ---------- | --------------------------------------- |
192
+ | **product** | `string` | Product id of the picked point. |
193
+ | **surface** | `Surface` | Surface of the picked point. |
194
+ | **normal** | `Vector3D` | Normal coordinates of the picked point. |
195
+ | **point** | `Vector3D` | Point coordinates of the picked point. |
196
+ | **uvw** | `UVW` | UV coordinates of the picked point. |
185
197
 
186
- ## Encoder
198
+ #### Surface
199
+
200
+ | Name | Type | Description |
201
+ | -------- | ---------- | ------------------------ |
202
+ | **id** | `string` | Id of the surface. |
203
+ | **name** | `string` | Name of the surface. |
204
+ | **tags** | `string[]` | Tag list of the surface. |
187
205
 
188
- An encoder is defined with:
189
- * `format` : encoder format (`jpeg`, `png`, `webp`)
190
- * `quality` : encoder quality (0-100 for `jpeg` and `webp` and 0-9 for `png`)
206
+ #### UVW
191
207
 
192
- ## Parameters
208
+ | Name | Type | Description |
209
+ | ----- | -------- | ------------- |
210
+ | **u** | `number` | U coordinate. |
211
+ | **v** | `number` | V coordinate. |
212
+ | **w** | `number` | W coordinate. |
193
213
 
194
- Render parameters are defined with:
195
- * `antialiasing` : whether software antialiasing is enabled or not
196
- * `superSampling` : super sampling coefficient 1-4
214
+ #### Vector2D
197
215
 
198
- WebRender is always optimized for the following default values (false, 2). Change this with precaution !
216
+ | Name | Type | Description |
217
+ | ----- | -------- | ------------- |
218
+ | **x** | `number` | X coordinate. |
219
+ | **y** | `number` | Y coordinate. |
199
220
 
200
- ## Events
221
+ #### Vector3D
201
222
 
202
- Events are defined with:
203
- * `onLoadStart` : event sent on load start
204
- * `onLoadProgress` : event sent on load progress
205
- * `onLoadEnd` : event sent on load end
206
- * `onLoadError` : event sent on load error
207
- * `onInteraction` : event sent on vrcube or vrobject interaction
208
- * `onVrcubeInteraction` : event sent on vrcube interaction
209
- * `onVrobjectInteraction` : event sent on vrobject interaction
223
+ | Name | Type | Description |
224
+ | ----- | -------- | ------------- |
225
+ | **x** | `number` | X coordinate. |
226
+ | **y** | `number` | Y coordinate. |
227
+ | **z** | `number` | Z coordinate. |
@@ -1,12 +1,10 @@
1
- import { Component, EventEmitter, Input, ViewChild, Output, HostListener } from '@angular/core';
1
+ import { Component, ContentChild, EventEmitter, Input, Output, ViewChild } from '@angular/core';
2
2
  import { Viewer } from '@lumiscaphe/viewer';
3
- import Viewport from './viewport';
4
3
  import * as i0 from "@angular/core";
5
4
  import * as i1 from "@angular/common";
6
5
  export class NgViewerComponent {
7
6
  constructor() {
8
- this.hotspots = [];
9
- this.hotspotTemplateRef = null;
7
+ this.hotspots2D = [];
10
8
  this.onLoadStart = new EventEmitter();
11
9
  this.onLoadProgress = new EventEmitter();
12
10
  this.onLoadEnd = new EventEmitter();
@@ -14,9 +12,7 @@ export class NgViewerComponent {
14
12
  this.onInteraction = new EventEmitter();
15
13
  this.onVrcubeInteraction = new EventEmitter();
16
14
  this.onVrobjectInteraction = new EventEmitter();
17
- this.fitPosition = { width: 1, height: 1, top: 1, left: 1 };
18
- this.scaleX = 1;
19
- this.scaleY = 1;
15
+ this.hotspotTemplateRef = null;
20
16
  }
21
17
  ngAfterViewInit() {
22
18
  this.viewer = new Viewer(this.container.nativeElement, {
@@ -24,22 +20,39 @@ export class NgViewerComponent {
24
20
  api: this.api || 'v1',
25
21
  fit: this.fit || 'cover',
26
22
  events: {
27
- onLoadStart: (...args) => { this.onLoadStart.emit(...args); },
28
- onLoadProgress: (...args) => { this.onLoadProgress.emit(...args); },
29
- onLoadEnd: (...args) => { this.onLoadEnd.emit(...args); },
30
- onLoadError: (...args) => { this.onLoadError.emit(...args); },
31
- onInteraction: (...args) => { this.onInteraction.emit(...args); },
32
- onVrcubeInteraction: (...args) => { this.onVrcubeInteraction.emit(...args); },
33
- onVrobjectInteraction: (...args) => { this.onVrobjectInteraction.emit(...args); },
34
- onHotspotsChange: this.onHotspotsChange.bind(this)
35
- },
23
+ onLoadStart: (...args) => {
24
+ this.onLoadStart.emit(...args);
25
+ },
26
+ onLoadProgress: (...args) => {
27
+ this.onLoadProgress.emit(...args);
28
+ },
29
+ onLoadEnd: (...args) => {
30
+ this.onLoadEnd.emit(...args);
31
+ },
32
+ onLoadError: (...args) => {
33
+ this.onLoadError.emit(...args);
34
+ },
35
+ onHotspotsChange: this.onHotspotsChange.bind(this),
36
+ onInteraction: (...args) => {
37
+ this.onInteraction.emit(...args);
38
+ },
39
+ onVrcubeInteraction: (...args) => {
40
+ this.onVrcubeInteraction.emit(...args);
41
+ },
42
+ onVrobjectInteraction: (...args) => {
43
+ this.onVrobjectInteraction.emit(...args);
44
+ }
45
+ }
36
46
  });
37
- if (this['scene']) {
47
+ if (this.scene) {
38
48
  this.viewer.load(this.scene).catch(() => { });
39
49
  }
40
- if (this['encoder']) {
50
+ if (this.encoder) {
41
51
  this.viewer.setEncoder(this.encoder).catch(() => { });
42
52
  }
53
+ if (this.hotspots) {
54
+ this.viewer.setHotspots(this.hotspots);
55
+ }
43
56
  if (this.parameters) {
44
57
  this.viewer.setParameters(this.parameters).catch(() => { });
45
58
  }
@@ -52,10 +65,6 @@ export class NgViewerComponent {
52
65
  if (this.vrobject) {
53
66
  this.viewer.setVrobject(this.vrobject);
54
67
  }
55
- if (this.tags) {
56
- this.viewer.setTags(this.tags);
57
- }
58
- this.onResize();
59
68
  }
60
69
  ngOnDestroy() {
61
70
  this.viewer?.destroy();
@@ -70,12 +79,12 @@ export class NgViewerComponent {
70
79
  if (changes['encoder'] && changes['encoder'].currentValue) {
71
80
  this.viewer.setEncoder(changes['encoder'].currentValue).catch(() => { });
72
81
  }
82
+ if (changes['hotspots'] && changes['hotspots'].currentValue) {
83
+ this.viewer.setHotspots(changes['hotspots'].currentValue);
84
+ }
73
85
  if (changes['parameters'] && changes['parameters'].currentValue) {
74
86
  this.viewer.setParameters(changes['parameters'].currentValue).catch(() => { });
75
87
  }
76
- if (changes['tags'] && changes['tags'].currentValue) {
77
- this.viewer.setTags(changes['tags'].currentValue);
78
- }
79
88
  if (changes['view'] && changes['view'].currentValue) {
80
89
  this.viewer.setView(changes['view'].currentValue).catch(() => { });
81
90
  }
@@ -86,43 +95,24 @@ export class NgViewerComponent {
86
95
  this.viewer.setVrobject(changes['vrobject'].currentValue);
87
96
  }
88
97
  }
89
- onHotspotsChange(hotspots) {
90
- this.hotspots = hotspots;
91
- if (this.hotspotsFilter !== undefined) {
92
- this.hotspots = this.hotspotsFilter(this.hotspots);
93
- }
98
+ async pick(position) {
99
+ return this.viewer?.pick(position);
94
100
  }
95
101
  snapshot(type, quality) {
96
102
  return this.viewer?.snapshot(type, quality);
97
103
  }
98
- onResize() {
99
- this.resolution = Viewport.getStandardResolution(window.innerWidth, window.innerHeight);
100
- this.fitPosition = Viewport.fit(this.resolution, window.innerWidth, window.innerHeight, 'cover');
101
- this.scaleX = this.fitPosition.width / this.resolution.width;
102
- this.scaleY = this.fitPosition.height / this.resolution.height;
103
- }
104
- hotspotStyle(hotspot) {
105
- if (this.view?.mode === 'vrcube') {
106
- return {
107
- position: 'absolute',
108
- top: hotspot.position2D.y + 'px',
109
- left: hotspot.position2D.x + 'px'
110
- };
111
- }
112
- else {
113
- return {
114
- position: 'absolute',
115
- top: (hotspot.position2D.y * this.scaleY + this.fitPosition.top) + 'px',
116
- left: (hotspot.position2D.x * this.scaleX + this.fitPosition.left) + 'px'
117
- };
104
+ onHotspotsChange(hotspots) {
105
+ this.hotspots2D = hotspots;
106
+ if (this.hotspotsFilter !== undefined) {
107
+ this.hotspots2D = this.hotspotsFilter(this.hotspots2D);
118
108
  }
119
109
  }
120
110
  }
121
- NgViewerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.0", ngImport: i0, type: NgViewerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
122
- NgViewerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.0", type: NgViewerComponent, selector: "NgViewer", inputs: { server: "server", api: "api", fit: "fit", scene: "scene", encoder: "encoder", parameters: "parameters", view: "view", vrcube: "vrcube", vrobject: "vrobject", tags: "tags", hotspotTemplateRef: "hotspotTemplateRef", hotspotsFilter: "hotspotsFilter" }, outputs: { onLoadStart: "onLoadStart", onLoadProgress: "onLoadProgress", onLoadEnd: "onLoadEnd", onLoadError: "onLoadError", onInteraction: "onInteraction", onVrcubeInteraction: "onVrcubeInteraction", onVrobjectInteraction: "onVrobjectInteraction" }, host: { listeners: { "window:resize": "onResize($event)" } }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div #container></div>\n\n<div class=\"position-absolute w-100 h-100\" style=\"pointer-events: none;\" *ngIf=\"hotspots.length\">\n <div [ngStyle]=\"hotspotStyle(hotspot)\" *ngFor=\"let hotspot of hotspots\">\n <ng-container *ngTemplateOutlet=\"hotspotTemplateRef; context:{hotspot: hotspot}\"></ng-container>\n </div>\n</div>", styles: [":host{display:flex;flex:1 0 auto}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
123
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.0", ngImport: i0, type: NgViewerComponent, decorators: [{
111
+ NgViewerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: NgViewerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
112
+ NgViewerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: NgViewerComponent, selector: "NgViewer", inputs: { server: "server", api: "api", fit: "fit", scene: "scene", encoder: "encoder", parameters: "parameters", view: "view", vrcube: "vrcube", vrobject: "vrobject", hotspots: "hotspots", hotspotsFilter: "hotspotsFilter" }, outputs: { onLoadStart: "onLoadStart", onLoadProgress: "onLoadProgress", onLoadEnd: "onLoadEnd", onLoadError: "onLoadError", onInteraction: "onInteraction", onVrcubeInteraction: "onVrcubeInteraction", onVrobjectInteraction: "onVrobjectInteraction" }, queries: [{ propertyName: "hotspotTemplateRef", first: true, predicate: ["hotspotTemplate"], descendants: true }], viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div #container></div>\n\n<div class=\"position-absolute w-100 h-100\" style=\"pointer-events: none\" *ngIf=\"hotspots2D.length\">\n <ng-container *ngFor=\"let hotspot of hotspots2D; index as i\">\n <div [ngStyle]=\"{ position: 'absolute', top: hotspot.position2D.y + 'px', left: hotspot.position2D.x + 'px' }\">\n <ng-container *ngTemplateOutlet=\"hotspotTemplateRef; context: { $implicit: hotspot, index: i }\"></ng-container>\n </div>\n </ng-container>\n</div>\n", styles: [":host{display:flex;flex:1 0 auto}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
113
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: NgViewerComponent, decorators: [{
124
114
  type: Component,
125
- args: [{ selector: 'NgViewer', template: "<div #container></div>\n\n<div class=\"position-absolute w-100 h-100\" style=\"pointer-events: none;\" *ngIf=\"hotspots.length\">\n <div [ngStyle]=\"hotspotStyle(hotspot)\" *ngFor=\"let hotspot of hotspots\">\n <ng-container *ngTemplateOutlet=\"hotspotTemplateRef; context:{hotspot: hotspot}\"></ng-container>\n </div>\n</div>", styles: [":host{display:flex;flex:1 0 auto}\n"] }]
115
+ args: [{ selector: 'NgViewer', template: "<div #container></div>\n\n<div class=\"position-absolute w-100 h-100\" style=\"pointer-events: none\" *ngIf=\"hotspots2D.length\">\n <ng-container *ngFor=\"let hotspot of hotspots2D; index as i\">\n <div [ngStyle]=\"{ position: 'absolute', top: hotspot.position2D.y + 'px', left: hotspot.position2D.x + 'px' }\">\n <ng-container *ngTemplateOutlet=\"hotspotTemplateRef; context: { $implicit: hotspot, index: i }\"></ng-container>\n </div>\n </ng-container>\n</div>\n", styles: [":host{display:flex;flex:1 0 auto}\n"] }]
126
116
  }], propDecorators: { server: [{
127
117
  type: Input
128
118
  }], api: [{
@@ -141,9 +131,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.0", ngImpor
141
131
  type: Input
142
132
  }], vrobject: [{
143
133
  type: Input
144
- }], tags: [{
145
- type: Input
146
- }], hotspotTemplateRef: [{
134
+ }], hotspots: [{
147
135
  type: Input
148
136
  }], hotspotsFilter: [{
149
137
  type: Input
@@ -161,11 +149,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.0", ngImpor
161
149
  type: Output
162
150
  }], onVrobjectInteraction: [{
163
151
  type: Output
152
+ }], hotspotTemplateRef: [{
153
+ type: ContentChild,
154
+ args: ['hotspotTemplate']
164
155
  }], container: [{
165
156
  type: ViewChild,
166
157
  args: ['container']
167
- }], onResize: [{
168
- type: HostListener,
169
- args: ['window:resize', ['$event']]
170
158
  }] } });
171
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctdmlld2VyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25nLXZpZXdlci9zcmMvbGliL25nLXZpZXdlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy12aWV3ZXIvc3JjL2xpYi9uZy12aWV3ZXIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFpQixTQUFTLEVBQWMsWUFBWSxFQUFFLEtBQUssRUFBdUMsU0FBUyxFQUFFLE1BQU0sRUFBZSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFN0ssT0FBTyxFQUE2QyxNQUFNLEVBQWdDLE1BQU0sb0JBQW9CLENBQUM7QUFDckgsT0FBTyxRQUFRLE1BQU0sWUFBWSxDQUFDOzs7QUFRbEMsTUFBTSxPQUFPLGlCQUFpQjtJQU45QjtRQVVTLGFBQVEsR0FBYyxFQUFFLENBQUM7UUFZdkIsdUJBQWtCLEdBQTRCLElBQUksQ0FBQztRQUdsRCxnQkFBVyxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFDakMsbUJBQWMsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ3BDLGNBQVMsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQy9CLGdCQUFXLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUNqQyxrQkFBYSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFDbkMsd0JBQW1CLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUN6QywwQkFBcUIsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBc0c5QyxnQkFBVyxHQUFpRSxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQztRQUVySCxXQUFNLEdBQVcsQ0FBQyxDQUFDO1FBQ25CLFdBQU0sR0FBVyxDQUFDLENBQUM7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Q0FBQztTQUNIO0lBQ0gsQ0FBQzs7OEdBMUpVLGlCQUFpQjtrR0FBakIsaUJBQWlCLDB1QkNYOUIsNlVBTU07MkZES08saUJBQWlCO2tCQU43QixTQUFTOytCQUNFLFVBQVU7OEJBV1gsTUFBTTtzQkFBZCxLQUFLO2dCQUNHLEdBQUc7c0JBQVgsS0FBSztnQkFDRyxHQUFHO3NCQUFYLEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLElBQUk7c0JBQVosS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxJQUFJO3NCQUFaLEtBQUs7Z0JBQ0csa0JBQWtCO3NCQUExQixLQUFLO2dCQUNHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBRUksV0FBVztzQkFBcEIsTUFBTTtnQkFDRyxjQUFjO3NCQUF2QixNQUFNO2dCQUNHLFNBQVM7c0JBQWxCLE1BQU07Z0JBQ0csV0FBVztzQkFBcEIsTUFBTTtnQkFDRyxhQUFhO3NCQUF0QixNQUFNO2dCQUNHLG1CQUFtQjtzQkFBNUIsTUFBTTtnQkFDRyxxQkFBcUI7c0JBQTlCLE1BQU07Z0JBRWlCLFNBQVM7c0JBQWhDLFNBQVM7dUJBQUMsV0FBVztnQkEwR2YsUUFBUTtzQkFEZCxZQUFZO3VCQUFDLGVBQWUsRUFBRSxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFmdGVyVmlld0luaXQsIENvbXBvbmVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3ksIFNpbXBsZUNoYW5nZXMsIFZpZXdDaGlsZCwgT3V0cHV0LCBUZW1wbGF0ZVJlZiwgSG9zdExpc3RlbmVyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IEVuY29kZXIsIEhvdHNwb3QsIFBhcmFtZXRlcnMsIFNjZW5lLCBWaWV3LCBWaWV3ZXIsIFdpZGdldFZSQ3ViZSwgV2lkZ2V0VlJPYmplY3QgfSBmcm9tICdAbHVtaXNjYXBoZS92aWV3ZXInO1xuaW1wb3J0IFZpZXdwb3J0IGZyb20gJy4vdmlld3BvcnQnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdOZ1ZpZXdlcicsXG4gIHRlbXBsYXRlVXJsOiAnLi9uZy12aWV3ZXIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9uZy12aWV3ZXIuY29tcG9uZW50LnNjc3MnXVxufSlcblxuZXhwb3J0IGNsYXNzIE5nVmlld2VyQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xuXG4gIHB1YmxpYyB2aWV3ZXI6IFZpZXdlciB8IHVuZGVmaW5lZDtcblxuICBwdWJsaWMgaG90c3BvdHM6IEhvdHNwb3RbXSA9IFtdO1xuXG4gIEBJbnB1dCgpIHNlcnZlcjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBASW5wdXQoKSBhcGk6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgQElucHV0KCkgZml0OiAnY29udGFpbicgfCAnY292ZXInIHwgJ2ZpbGwnIHwgdW5kZWZpbmVkO1xuICBASW5wdXQoKSBzY2VuZTogU2NlbmUgfCB1bmRlZmluZWQ7XG4gIEBJbnB1dCgpIGVuY29kZXI6IEVuY29kZXIgfCB1bmRlZmluZWQ7XG4gIEBJbnB1dCgpIHBhcmFtZXRlcnM6IFBhcmFtZXRlcnMgfCB1bmRlZmluZWQ7XG4gIEBJbnB1dCgpIHZpZXc6IFZpZXcgfCB1bmRlZmluZWQ7XG4gIEBJbnB1dCgpIHZyY3ViZTogUGFydGlhbDxXaWRnZXRWUkN1YmU+IHwgdW5kZWZpbmVkO1xuICBASW5wdXQoKSB2cm9iamVjdDogUGFydGlhbDxXaWRnZXRWUk9iamVjdD4gfCB1bmRlZmluZWQ7XG4gIEBJbnB1dCgpIHRhZ3M6IHN0cmluZ1tdIHwgdW5kZWZpbmVkO1xuICBASW5wdXQoKSBob3RzcG90VGVtcGxhdGVSZWY6IFRlbXBsYXRlUmVmPGFueT4gfCBudWxsID0gbnVsbDtcbiAgQElucHV0KCkgaG90c3BvdHNGaWx0ZXI6ICgoaG90c3BvdHM6IEhvdHNwb3RbXSkgPT4gSG90c3BvdFtdKSB8IHVuZGVmaW5lZDtcblxuICBAT3V0cHV0KCkgb25Mb2FkU3RhcnQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBvbkxvYWRQcm9ncmVzcyA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIG9uTG9hZEVuZCA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIG9uTG9hZEVycm9yID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgb25JbnRlcmFjdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIG9uVnJjdWJlSW50ZXJhY3Rpb24gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBvblZyb2JqZWN0SW50ZXJhY3Rpb24gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgQFZpZXdDaGlsZCgnY29udGFpbmVyJykgY29udGFpbmVyITogRWxlbWVudFJlZjtcblxuICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgdGhpcy52aWV3ZXIgPSBuZXcgVmlld2VyKHRoaXMuY29udGFpbmVyLm5hdGl2ZUVsZW1lbnQsIHtcbiAgICAgIHNlcnZlcjogdGhpcy5zZXJ2ZXIsXG4gICAgICBhcGk6IHRoaXMuYXBpIHx8ICd2MScsXG4gICAgICBmaXQ6IHRoaXMuZml0IHx8ICdjb3ZlcicsXG4gICAgICBldmVudHM6IHtcbiAgICAgICAgb25Mb2FkU3RhcnQ6ICguLi5hcmdzOiBhbnlbXSkgPT4geyB0aGlzLm9uTG9hZFN0YXJ0LmVtaXQoLi4uYXJncyk7IH0sXG4gICAgICAgIG9uTG9hZFByb2dyZXNzOiAoLi4uYXJnczogYW55W10pID0+IHsgdGhpcy5vbkxvYWRQcm9ncmVzcy5lbWl0KC4uLmFyZ3MpOyB9LFxuICAgICAgICBvbkxvYWRFbmQ6ICguLi5hcmdzOiBhbnlbXSkgPT4geyB0aGlzLm9uTG9hZEVuZC5lbWl0KC4uLmFyZ3MpOyB9LFxuICAgICAgICBvbkxvYWRFcnJvcjogKC4uLmFyZ3M6IGFueVtdKSA9PiB7IHRoaXMub25Mb2FkRXJyb3IuZW1pdCguLi5hcmdzKTsgfSxcbiAgICAgICAgb25JbnRlcmFjdGlvbjogKC4uLmFyZ3M6IGFueVtdKSA9PiB7IHRoaXMub25JbnRlcmFjdGlvbi5lbWl0KC4uLmFyZ3MpOyB9LFxuICAgICAgICBvblZyY3ViZUludGVyYWN0aW9uOiAoLi4uYXJnczogYW55W10pID0+IHsgdGhpcy5vblZyY3ViZUludGVyYWN0aW9uLmVtaXQoLi4uYXJncyk7IH0sXG4gICAgICAgIG9uVnJvYmplY3RJbnRlcmFjdGlvbjogKC4uLmFyZ3M6IGFueVtdKSA9PiB7IHRoaXMub25Wcm9iamVjdEludGVyYWN0aW9uLmVtaXQoLi4uYXJncyk7IH0sXG4gICAgICAgIG9uSG90c3BvdHNDaGFuZ2U6IHRoaXMub25Ib3RzcG90c0NoYW5nZS5iaW5kKHRoaXMpXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgaWYgKHRoaXNbJ3NjZW5lJ10pIHtcbiAgICAgIHRoaXMudmlld2VyLmxvYWQodGhpcy5zY2VuZSkuY2F0Y2goKCkgPT4geyB9KTtcbiAgICB9XG5cbiAgICBpZiAodGhpc1snZW5jb2RlciddKSB7XG4gICAgICB0aGlzLnZpZXdlci5zZXRFbmNvZGVyKHRoaXMuZW5jb2RlcikuY2F0Y2goKCkgPT4geyB9KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5wYXJhbWV0ZXJzKSB7XG4gICAgICB0aGlzLnZpZXdlci5zZXRQYXJhbWV0ZXJzKHRoaXMucGFyYW1ldGVycykuY2F0Y2goKCkgPT4geyB9KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy52aWV3KSB7XG4gICAgICB0aGlzLnZpZXdlci5zZXRWaWV3KHRoaXMudmlldykuY2F0Y2goKCkgPT4geyB9KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy52cmN1YmUpIHtcbiAgICAgIHRoaXMudmlld2VyLnNldFZyY3ViZSh0aGlzLnZyY3ViZSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMudnJvYmplY3QpIHtcbiAgICAgIHRoaXMudmlld2VyLnNldFZyb2JqZWN0KHRoaXMudnJvYmplY3QpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnRhZ3MpIHtcbiAgICAgIHRoaXMudmlld2VyLnNldFRhZ3ModGhpcy50YWdzKTtcbiAgICB9XG5cbiAgICB0aGlzLm9uUmVzaXplKCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLnZpZXdlcj8uZGVzdHJveSgpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuICAgIGlmICghdGhpcy52aWV3ZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoY2hhbmdlc1snc2NlbmUnXSAmJiBjaGFuZ2VzWydzY2VuZSddLmN1cnJlbnRWYWx1ZSkge1xuICAgICAgdGhpcy52aWV3ZXIubG9hZChjaGFuZ2VzWydzY2VuZSddLmN1cnJlbnRWYWx1ZSkuY2F0Y2goKCkgPT4geyB9KTtcbiAgICB9XG5cbiAgICBpZiAoY2hhbmdlc1snZW5jb2RlciddICYmIGNoYW5nZXNbJ2VuY29kZXInXS5jdXJyZW50VmFsdWUpIHtcbiAgICAgIHRoaXMudmlld2VyLnNldEVuY29kZXIoY2hhbmdlc1snZW5jb2RlciddLmN1cnJlbnRWYWx1ZSkuY2F0Y2goKCkgPT4geyB9KTtcbiAgICB9XG5cbiAgICBpZiAoY2hhbmdlc1sncGFyYW1ldGVycyddICYmIGNoYW5nZXNbJ3BhcmFtZXRlcnMnXS5jdXJyZW50VmFsdWUpIHtcbiAgICAgIHRoaXMudmlld2VyLnNldFBhcmFtZXRlcnMoY2hhbmdlc1sncGFyYW1ldGVycyddLmN1cnJlbnRWYWx1ZSkuY2F0Y2goKCkgPT4geyB9KTtcbiAgICB9XG5cbiAgICBpZiAoY2hhbmdlc1sndGFncyddICYmIGNoYW5nZXNbJ3RhZ3MnXS5jdXJyZW50VmFsdWUpIHtcbiAgICAgIHRoaXMudmlld2VyLnNldFRhZ3MoY2hhbmdlc1sndGFncyddLmN1cnJlbnRWYWx1ZSk7XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZXNbJ3ZpZXcnXSAmJiBjaGFuZ2VzWyd2aWV3J10uY3VycmVudFZhbHVlKSB7XG4gICAgICB0aGlzLnZpZXdlci5zZXRWaWV3KGNoYW5nZXNbJ3ZpZXcnXS5jdXJyZW50VmFsdWUpLmNhdGNoKCgpID0+IHsgfSk7XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZXNbJ3ZyY3ViZSddICYmIGNoYW5nZXNbJ3ZyY3ViZSddLmN1cnJlbnRWYWx1ZSkge1xuICAgICAgdGhpcy52aWV3ZXIuc2V0VnJjdWJlKGNoYW5nZXNbJ3ZyY3ViZSddLmN1cnJlbnRWYWx1ZSk7XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZXNbJ3Zyb2JqZWN0J10gJiYgY2hhbmdlc1sndnJvYmplY3QnXS5jdXJyZW50VmFsdWUpIHtcbiAgICAgIHRoaXMudmlld2VyLnNldFZyb2JqZWN0KGNoYW5nZXNbJ3Zyb2JqZWN0J10uY3VycmVudFZhbHVlKTtcbiAgICB9XG4gIH1cblxuICBvbkhvdHNwb3RzQ2hhbmdlKGhvdHNwb3RzOiBIb3RzcG90W10pOiB2b2lkIHtcbiAgICB0aGlzLmhvdHNwb3RzID0gaG90c3BvdHM7XG5cbiAgICBpZiAodGhpcy5ob3RzcG90c0ZpbHRlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmhvdHNwb3RzID0gdGhpcy5ob3RzcG90c0ZpbHRlcih0aGlzLmhvdHNwb3RzKTtcbiAgICB9XG4gIH1cblxuICBzbmFwc2hvdCh0eXBlOiBzdHJpbmcsIHF1YWxpdHk6IG51bWJlcik6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMudmlld2VyPy5zbmFwc2hvdCh0eXBlLCBxdWFsaXR5KTtcbiAgfVxuXG4gIHB1YmxpYyBmaXRQb3NpdGlvbjogeyB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlciwgdG9wOiBudW1iZXIsIGxlZnQ6IG51bWJlciB9ID0geyB3aWR0aDogMSwgaGVpZ2h0OiAxLCB0b3A6IDEsIGxlZnQ6IDEgfTtcbiAgcHVibGljIHJlc29sdXRpb246IHsgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIgfSB8IHVuZGVmaW5lZDtcbiAgcHVibGljIHNjYWxlWDogbnVtYmVyID0gMTtcbiAgcHVibGljIHNjYWxlWTogbnVtYmVyID0gMTtcblxuICBASG9zdExpc3RlbmVyKCd3aW5kb3c6cmVzaXplJywgWyckZXZlbnQnXSlcbiAgcHVibGljIG9uUmVzaXplKCk6IHZvaWQge1xuICAgIHRoaXMucmVzb2x1dGlvbiA9IFZpZXdwb3J0LmdldFN0YW5kYXJkUmVzb2x1dGlvbih3aW5kb3cuaW5uZXJXaWR0aCwgd2luZG93LmlubmVySGVpZ2h0KTtcbiAgICB0aGlzLmZpdFBvc2l0aW9uID0gVmlld3BvcnQuZml0KHRoaXMucmVzb2x1dGlvbiwgd2luZG93LmlubmVyV2lkdGgsIHdpbmRvdy5pbm5lckhlaWdodCwgJ2NvdmVyJyk7XG4gICAgdGhpcy5zY2FsZVggPSB0aGlzLmZpdFBvc2l0aW9uLndpZHRoIC8gdGhpcy5yZXNvbHV0aW9uLndpZHRoO1xuICAgIHRoaXMuc2NhbGVZID0gdGhpcy5maXRQb3NpdGlvbi5oZWlnaHQgLyB0aGlzLnJlc29sdXRpb24uaGVpZ2h0O1xuICB9XG5cbiAgcHVibGljIGhvdHNwb3RTdHlsZShob3RzcG90OiBIb3RzcG90KTogeyBsZWZ0OiBzdHJpbmcsIHRvcDogc3RyaW5nLCBwb3NpdGlvbjogc3RyaW5nIH0ge1xuICAgIGlmICh0aGlzLnZpZXc/Lm1vZGUgPT09ICd2cmN1YmUnKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgICAgdG9wOiBob3RzcG90LnBvc2l0aW9uMkQueSArICdweCcsXG4gICAgICAgIGxlZnQ6IGhvdHNwb3QucG9zaXRpb24yRC54ICsgJ3B4J1xuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICAgIHRvcDogKGhvdHNwb3QucG9zaXRpb24yRC55ICogdGhpcy5zY2FsZVkgKyB0aGlzLmZpdFBvc2l0aW9uLnRvcCkgKyAncHgnLFxuICAgICAgICBsZWZ0OiAoaG90c3BvdC5wb3NpdGlvbjJELnggKiB0aGlzLnNjYWxlWCArIHRoaXMuZml0UG9zaXRpb24ubGVmdCkgKyAncHgnXG4gICAgICB9O1xuICAgIH1cbiAgfVxufVxuIiwiPGRpdiAjY29udGFpbmVyPjwvZGl2PlxuXG48ZGl2IGNsYXNzPVwicG9zaXRpb24tYWJzb2x1dGUgdy0xMDAgaC0xMDBcIiBzdHlsZT1cInBvaW50ZXItZXZlbnRzOiBub25lO1wiICpuZ0lmPVwiaG90c3BvdHMubGVuZ3RoXCI+XG4gIDxkaXYgW25nU3R5bGVdPVwiaG90c3BvdFN0eWxlKGhvdHNwb3QpXCIgKm5nRm9yPVwibGV0IGhvdHNwb3Qgb2YgaG90c3BvdHNcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiaG90c3BvdFRlbXBsYXRlUmVmOyBjb250ZXh0Ontob3RzcG90OiBob3RzcG90fVwiPjwvbmctY29udGFpbmVyPlxuICA8L2Rpdj5cbjwvZGl2PiJdfQ==
159
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmctdmlld2VyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25nLXZpZXdlci9zcmMvbGliL25nLXZpZXdlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy12aWV3ZXIvc3JjL2xpYi9uZy12aWV3ZXIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFpQixTQUFTLEVBQUUsWUFBWSxFQUFjLFlBQVksRUFBRSxLQUFLLEVBQXdCLE1BQU0sRUFBOEIsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzdLLE9BQU8sRUFBNkMsTUFBTSxFQUF5QyxNQUFNLG9CQUFvQixDQUFDOzs7QUFPOUgsTUFBTSxPQUFPLGlCQUFpQjtJQUw5QjtRQVFTLGVBQVUsR0FBYyxFQUFFLENBQUM7UUFjeEIsZ0JBQVcsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ2pDLG1CQUFjLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUNwQyxjQUFTLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUMvQixnQkFBVyxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFDakMsa0JBQWEsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ25DLHdCQUFtQixHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFDekMsMEJBQXFCLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUVwQix1QkFBa0IsR0FBNEIsSUFBSSxDQUFDO0tBcUhyRjtJQWpIQyxlQUFlO1FBQ2IsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsRUFBRTtZQUNyRCxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU07WUFDbkIsR0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHLElBQUksSUFBSTtZQUNyQixHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcs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QUc7c0JBQVgsS0FBSztnQkFDRyxHQUFHO3NCQUFYLEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLElBQUk7c0JBQVosS0FBSztnQkFDRyxNQUFNO3NCQUFkLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBRUksV0FBVztzQkFBcEIsTUFBTTtnQkFDRyxjQUFjO3NCQUF2QixNQUFNO2dCQUNHLFNBQVM7c0JBQWxCLE1BQU07Z0JBQ0csV0FBVztzQkFBcEIsTUFBTTtnQkFDRyxhQUFhO3NCQUF0QixNQUFNO2dCQUNHLG1CQUFtQjtzQkFBNUIsTUFBTTtnQkFDRyxxQkFBcUI7c0JBQTlCLE1BQU07Z0JBRTBCLGtCQUFrQjtzQkFBbEQsWUFBWTt1QkFBQyxpQkFBaUI7Z0JBRVAsU0FBUztzQkFBaEMsU0FBUzt1QkFBQyxXQUFXIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWZ0ZXJWaWV3SW5pdCwgQ29tcG9uZW50LCBDb250ZW50Q2hpbGQsIEVsZW1lbnRSZWYsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE9uQ2hhbmdlcywgT25EZXN0cm95LCBPdXRwdXQsIFNpbXBsZUNoYW5nZXMsIFRlbXBsYXRlUmVmLCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEVuY29kZXIsIEhvdHNwb3QsIFBhcmFtZXRlcnMsIFNjZW5lLCBWaWV3LCBWaWV3ZXIsIFdSQVBJdjIsIFdpZGdldFZSQ3ViZSwgV2lkZ2V0VlJPYmplY3QgfSBmcm9tICdAbHVtaXNjYXBoZS92aWV3ZXInO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdOZ1ZpZXdlcicsXG4gIHRlbXBsYXRlVXJsOiAnLi9uZy12aWV3ZXIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9uZy12aWV3ZXIuY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBOZ1ZpZXdlckNvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uQ2hhbmdlcywgT25EZXN0cm95IHtcbiAgcHVibGljIHZpZXdlcjogVmlld2VyIHwgdW5kZWZpbmVkO1xuXG4gIHB1YmxpYyBob3RzcG90czJEOiBIb3RzcG90W10gPSBbXTtcblxuICBASW5wdXQoKSBzZXJ2ZXI6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgQElucHV0KCkgYXBpOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIEBJbnB1dCgpIGZpdDogJ2NvbnRhaW4nIHwgJ2NvdmVyJyB8ICdmaWxsJyB8IHVuZGVmaW5lZDtcbiAgQElucHV0KCkgc2NlbmU6IFNjZW5lIHwgdW5kZWZpbmVkO1xuICBASW5wdXQoKSBlbmNvZGVyOiBFbmNvZGVyIHwgdW5kZWZpbmVkO1xuICBASW5wdXQoKSBwYXJhbWV0ZXJzOiBQYXJhbWV0ZXJzIHwgdW5kZWZpbmVkO1xuICBASW5wdXQoKSB2aWV3OiBWaWV3IHwgdW5kZWZpbmVkO1xuICBASW5wdXQoKSB2cmN1YmU6IFBhcnRpYWw8V2lkZ2V0VlJDdWJlPiB8IHVuZGVmaW5lZDtcbiAgQElucHV0KCkgdnJvYmplY3Q6IFBhcnRpYWw8V2lkZ2V0VlJPYmplY3Q+IHwgdW5kZWZpbmVkO1xuICBASW5wdXQoKSBob3RzcG90czogQXJyYXk8c3RyaW5nIHwgV1JBUEl2Mi5WZWN0b3IzRD4gfCB1bmRlZmluZWQ7XG4gIEBJbnB1dCgpIGhvdHNwb3RzRmlsdGVyOiAoKGhvdHNwb3RzOiBIb3RzcG90W10pID0+IEhvdHNwb3RbXSkgfCB1bmRlZmluZWQ7XG5cbiAgQE91dHB1dCgpIG9uTG9hZFN0YXJ0ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgb25Mb2FkUHJvZ3Jlc3MgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBvbkxvYWRFbmQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBvbkxvYWRFcnJvciA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIG9uSW50ZXJhY3Rpb24gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBvblZyY3ViZUludGVyYWN0aW9uID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgb25Wcm9iamVjdEludGVyYWN0aW9uID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIEBDb250ZW50Q2hpbGQoJ2hvdHNwb3RUZW1wbGF0ZScpIGhvdHNwb3RUZW1wbGF0ZVJlZjogVGVtcGxhdGVSZWY8YW55PiB8IG51bGwgPSBudWxsO1xuXG4gIEBWaWV3Q2hpbGQoJ2NvbnRhaW5lcicpIGNvbnRhaW5lciE6IEVsZW1lbnRSZWY7XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIHRoaXMudmlld2VyID0gbmV3IFZpZXdlcih0aGlzLmNvbnRhaW5lci5uYXRpdmVFbGVtZW50LCB7XG4gICAgICBzZXJ2ZXI6IHRoaXMuc2VydmVyLFxuICAgICAgYXBpOiB0aGlzLmFwaSB8fCAndjEnLFxuICAgICAgZml0OiB0aGlzLmZpdCB8fCAnY292ZXInLFxuICAgICAgZXZlbnRzOiB7XG4gICAgICAgIG9uTG9hZFN0YXJ0OiAoLi4uYXJnczogYW55W10pID0+IHtcbiAgICAgICAgICB0aGlzLm9uTG9hZFN0YXJ0LmVtaXQoLi4uYXJncyk7XG4gICAgICAgIH0sXG4gICAgICAgIG9uTG9hZFByb2dyZXNzOiAoLi4uYXJnczogYW55W10pID0+IHtcbiAgICAgICAgICB0aGlzLm9uTG9hZFByb2dyZXNzLmVtaXQoLi4uYXJncyk7XG4gICAgICAgIH0sXG4gICAgICAgIG9uTG9hZEVuZDogKC4uLmFyZ3M6IGFueVtdKSA9PiB7XG4gICAgICAgICAgdGhpcy5vbkxvYWRFbmQuZW1pdCguLi5hcmdzKTtcbiAgICAgICAgfSxcbiAgICAgICAgb25Mb2FkRXJyb3I6ICguLi5hcmdzOiBhbnlbXSkgPT4ge1xuICAgICAgICAgIHRoaXMub25Mb2FkRXJyb3IuZW1pdCguLi5hcmdzKTtcbiAgICAgICAgfSxcbiAgICAgICAgb25Ib3RzcG90c0NoYW5nZTogdGhpcy5vbkhvdHNwb3RzQ2hhbmdlLmJpbmQodGhpcyksXG4gICAgICAgIG9uSW50ZXJhY3Rpb246ICguLi5hcmdzOiBhbnlbXSkgPT4ge1xuICAgICAgICAgIHRoaXMub25JbnRlcmFjdGlvbi5lbWl0KC4uLmFyZ3MpO1xuICAgICAgICB9LFxuICAgICAgICBvblZyY3ViZUludGVyYWN0aW9uOiAoLi4uYXJnczogYW55W10pID0+IHtcbiAgICAgICAgICB0aGlzLm9uVnJjdWJlSW50ZXJhY3Rpb24uZW1pdCguLi5hcmdzKTtcbiAgICAgICAgfSxcbiAgICAgICAgb25Wcm9iamVjdEludGVyYWN0aW9uOiAoLi4uYXJnczogYW55W10pID0+IHtcbiAgICAgICAgICB0aGlzLm9uVnJvYmplY3RJbnRlcmFjdGlvbi5lbWl0KC4uLmFyZ3MpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpZiAodGhpcy5zY2VuZSkge1xuICAgICAgdGhpcy52aWV3ZXIubG9hZCh0aGlzLnNjZW5lKS5jYXRjaCgoKSA9PiB7fSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuZW5jb2Rlcikge1xuICAgICAgdGhpcy52aWV3ZXIuc2V0RW5jb2Rlcih0aGlzLmVuY29kZXIpLmNhdGNoKCgpID0+IHt9KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5ob3RzcG90cykge1xuICAgICAgdGhpcy52aWV3ZXIuc2V0SG90c3BvdHModGhpcy5ob3RzcG90cyk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucGFyYW1ldGVycykge1xuICAgICAgdGhpcy52aWV3ZXIuc2V0UGFyYW1ldGVycyh0aGlzLnBhcmFtZXRlcnMpLmNhdGNoKCgpID0+IHt9KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy52aWV3KSB7XG4gICAgICB0aGlzLnZpZXdlci5zZXRWaWV3KHRoaXMudmlldykuY2F0Y2goKCkgPT4ge30pO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnZyY3ViZSkge1xuICAgICAgdGhpcy52aWV3ZXIuc2V0VnJjdWJlKHRoaXMudnJjdWJlKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy52cm9iamVjdCkge1xuICAgICAgdGhpcy52aWV3ZXIuc2V0VnJvYmplY3QodGhpcy52cm9iamVjdCk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy52aWV3ZXI/LmRlc3Ryb3koKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcbiAgICBpZiAoIXRoaXMudmlld2VyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZXNbJ3NjZW5lJ10gJiYgY2hhbmdlc1snc2NlbmUnXS5jdXJyZW50VmFsdWUpIHtcbiAgICAgIHRoaXMudmlld2VyLmxvYWQoY2hhbmdlc1snc2NlbmUnXS5jdXJyZW50VmFsdWUpLmNhdGNoKCgpID0+IHt9KTtcbiAgICB9XG5cbiAgICBpZiAoY2hhbmdlc1snZW5jb2RlciddICYmIGNoYW5nZXNbJ2VuY29kZXInXS5jdXJyZW50VmFsdWUpIHtcbiAgICAgIHRoaXMudmlld2VyLnNldEVuY29kZXIoY2hhbmdlc1snZW5jb2RlciddLmN1cnJlbnRWYWx1ZSkuY2F0Y2goKCkgPT4ge30pO1xuICAgIH1cblxuICAgIGlmIChjaGFuZ2VzWydob3RzcG90cyddICYmIGNoYW5nZXNbJ2hvdHNwb3RzJ10uY3VycmVudFZhbHVlKSB7XG4gICAgICB0aGlzLnZpZXdlci5zZXRIb3RzcG90cyhjaGFuZ2VzWydob3RzcG90cyddLmN1cnJlbnRWYWx1ZSk7XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZXNbJ3BhcmFtZXRlcnMnXSAmJiBjaGFuZ2VzWydwYXJhbWV0ZXJzJ10uY3VycmVudFZhbHVlKSB7XG4gICAgICB0aGlzLnZpZXdlci5zZXRQYXJhbWV0ZXJzKGNoYW5nZXNbJ3BhcmFtZXRlcnMnXS5jdXJyZW50VmFsdWUpLmNhdGNoKCgpID0+IHt9KTtcbiAgICB9XG5cbiAgICBpZiAoY2hhbmdlc1sndmlldyddICYmIGNoYW5nZXNbJ3ZpZXcnXS5jdXJyZW50VmFsdWUpIHtcbiAgICAgIHRoaXMudmlld2VyLnNldFZpZXcoY2hhbmdlc1sndmlldyddLmN1cnJlbnRWYWx1ZSkuY2F0Y2goKCkgPT4ge30pO1xuICAgIH1cblxuICAgIGlmIChjaGFuZ2VzWyd2cmN1YmUnXSAmJiBjaGFuZ2VzWyd2cmN1YmUnXS5jdXJyZW50VmFsdWUpIHtcbiAgICAgIHRoaXMudmlld2VyLnNldFZyY3ViZShjaGFuZ2VzWyd2cmN1YmUnXS5jdXJyZW50VmFsdWUpO1xuICAgIH1cblxuICAgIGlmIChjaGFuZ2VzWyd2cm9iamVjdCddICYmIGNoYW5nZXNbJ3Zyb2JqZWN0J10uY3VycmVudFZhbHVlKSB7XG4gICAgICB0aGlzLnZpZXdlci5zZXRWcm9iamVjdChjaGFuZ2VzWyd2cm9iamVjdCddLmN1cnJlbnRWYWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgcGljayhwb3NpdGlvbjogV1JBUEl2Mi5WZWN0b3IyRCk6IFByb21pc2U8V1JBUEl2Mi5QaWNrUmVzdWx0IHwgdW5kZWZpbmVkPiB7XG4gICAgcmV0dXJuIHRoaXMudmlld2VyPy5waWNrKHBvc2l0aW9uKTtcbiAgfVxuXG4gIHNuYXBzaG90KHR5cGU6IHN0cmluZywgcXVhbGl0eTogbnVtYmVyKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy52aWV3ZXI/LnNuYXBzaG90KHR5cGUsIHF1YWxpdHkpO1xuICB9XG5cbiAgb25Ib3RzcG90c0NoYW5nZShob3RzcG90czogSG90c3BvdFtdKTogdm9pZCB7XG4gICAgdGhpcy5ob3RzcG90czJEID0gaG90c3BvdHM7XG5cbiAgICBpZiAodGhpcy5ob3RzcG90c0ZpbHRlciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmhvdHNwb3RzMkQgPSB0aGlzLmhvdHNwb3RzRmlsdGVyKHRoaXMuaG90c3BvdHMyRCk7XG4gICAgfVxuICB9XG59XG4iLCI8ZGl2ICNjb250YWluZXI+PC9kaXY+XG5cbjxkaXYgY2xhc3M9XCJwb3NpdGlvbi1hYnNvbHV0ZSB3LTEwMCBoLTEwMFwiIHN0eWxlPVwicG9pbnRlci1ldmVudHM6IG5vbmVcIiAqbmdJZj1cImhvdHNwb3RzMkQubGVuZ3RoXCI+XG4gIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGhvdHNwb3Qgb2YgaG90c3BvdHMyRDsgaW5kZXggYXMgaVwiPlxuICAgIDxkaXYgW25nU3R5bGVdPVwieyBwb3NpdGlvbjogJ2Fic29sdXRlJywgdG9wOiBob3RzcG90LnBvc2l0aW9uMkQueSArICdweCcsIGxlZnQ6IGhvdHNwb3QucG9zaXRpb24yRC54ICsgJ3B4JyB9XCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwiaG90c3BvdFRlbXBsYXRlUmVmOyBjb250ZXh0OiB7ICRpbXBsaWNpdDogaG90c3BvdCwgaW5kZXg6IGkgfVwiPjwvbmctY29udGFpbmVyPlxuICAgIDwvZGl2PlxuICA8L25nLWNvbnRhaW5lcj5cbjwvZGl2PlxuIl19