@smarterplan/ngx-smarterplan-core 1.4.20 → 1.4.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/README.md +24 -24
  2. package/esm2022/lib/components/csv-export/csv-export.component.mjs +3 -3
  3. package/esm2022/lib/components/loader/loader.component.mjs +3 -3
  4. package/esm2022/lib/components/menu-bar/avatar/avatar.component.mjs +1 -1
  5. package/esm2022/lib/components/menu-bar/menu-bar.component.mjs +3 -3
  6. package/esm2022/lib/components/menu-bar/navigation-bar/navigation-bar.component.mjs +3 -3
  7. package/esm2022/lib/components/modal-switch-visit/modal-switch-visit.component.mjs +3 -3
  8. package/esm2022/lib/components/search-bar/search-bar.component.mjs +3 -3
  9. package/esm2022/lib/components/support-modal/support-modal.component.mjs +3 -3
  10. package/esm2022/lib/config.mjs +1 -1
  11. package/esm2022/lib/helpers.service.mjs +1 -1
  12. package/esm2022/lib/matterport-extensions/nest-thermostat/CanvasImage.mjs +1 -1
  13. package/esm2022/lib/matterport-extensions/nest-thermostat/CanvasRenderer.mjs +1 -1
  14. package/esm2022/lib/matterport-extensions/nest-thermostat/NestThermostat.mjs +1 -1
  15. package/esm2022/lib/matterport-extensions/nest-thermostat/PlaneRenderer.mjs +1 -1
  16. package/esm2022/lib/matterport-extensions/scene-component/SceneComponent.mjs +1 -1
  17. package/esm2022/lib/matterport-extensions/security-camera/SecurityCamera.mjs +49 -28
  18. package/esm2022/lib/matterport-extensions/tv-player/TvPlayer.mjs +1 -1
  19. package/esm2022/lib/matterport-extensions/view-frustum-mesh/ViewFrustumMesh.mjs +22 -22
  20. package/esm2022/lib/mattertagData.mjs +1 -1
  21. package/esm2022/lib/ngx-smarterplan-core.module.mjs +1 -1
  22. package/esm2022/lib/ngx-smarterplan-core.service.mjs +1 -1
  23. package/esm2022/lib/pipes/duration-to-string.pipe.mjs +1 -1
  24. package/esm2022/lib/pipes/format-date-number-to-digits.pipe.mjs +1 -1
  25. package/esm2022/lib/pipes/hashtag-from-id.pipe.mjs +1 -1
  26. package/esm2022/lib/pipes/safe-url.pipe.mjs +1 -1
  27. package/esm2022/lib/pipes/time-date-to-local-string.pipe.mjs +1 -1
  28. package/esm2022/lib/pipes/username-from-id.pipe.mjs +1 -1
  29. package/esm2022/lib/services/amplify-cache.service.mjs +1 -1
  30. package/esm2022/lib/services/base-tab.service.mjs +1 -1
  31. package/esm2022/lib/services/baseVisibility.service.mjs +1 -1
  32. package/esm2022/lib/services/content.service.mjs +1 -1
  33. package/esm2022/lib/services/filter.service.mjs +1 -1
  34. package/esm2022/lib/services/intervention.service.mjs +1 -1
  35. package/esm2022/lib/services/locale.service.mjs +1 -1
  36. package/esm2022/lib/services/matterport-import.service.mjs +1 -1
  37. package/esm2022/lib/services/matterport-measurement.service.mjs +1 -1
  38. package/esm2022/lib/services/matterport-navigation.service.mjs +1 -1
  39. package/esm2022/lib/services/matterport-object3d.service.mjs +657 -133
  40. package/esm2022/lib/services/matterport-pointer.service.mjs +6 -6
  41. package/esm2022/lib/services/matterport-tag-copy.service.mjs +1 -1
  42. package/esm2022/lib/services/matterport-tag.service.mjs +1 -1
  43. package/esm2022/lib/services/matterport.service.mjs +346 -25
  44. package/esm2022/lib/services/models/affectation.service.mjs +1 -1
  45. package/esm2022/lib/services/models/base-object.service.mjs +1 -1
  46. package/esm2022/lib/services/models/capture.service.mjs +1 -1
  47. package/esm2022/lib/services/models/comment.service.mjs +1 -1
  48. package/esm2022/lib/services/models/domain.service.mjs +1 -1
  49. package/esm2022/lib/services/models/equipment.service.mjs +1 -1
  50. package/esm2022/lib/services/models/event.service.mjs +1 -1
  51. package/esm2022/lib/services/models/feature.service.mjs +1 -1
  52. package/esm2022/lib/services/models/hashtag.service.mjs +1 -1
  53. package/esm2022/lib/services/models/layer.service.mjs +1 -1
  54. package/esm2022/lib/services/models/measurement.service.mjs +1 -1
  55. package/esm2022/lib/services/models/mission.service.mjs +1 -1
  56. package/esm2022/lib/services/models/navigation.service.mjs +1 -1
  57. package/esm2022/lib/services/models/node.service.mjs +1 -1
  58. package/esm2022/lib/services/models/object3D.service.mjs +1 -1
  59. package/esm2022/lib/services/models/operation.service.mjs +1 -1
  60. package/esm2022/lib/services/models/organisation.service.mjs +1 -1
  61. package/esm2022/lib/services/models/plan.service.mjs +1 -1
  62. package/esm2022/lib/services/models/poi.service.mjs +27 -27
  63. package/esm2022/lib/services/models/profile.service.mjs +1 -1
  64. package/esm2022/lib/services/models/property.service.mjs +1 -1
  65. package/esm2022/lib/services/models/space.service.mjs +1 -1
  66. package/esm2022/lib/services/models/template.service.mjs +1 -1
  67. package/esm2022/lib/services/models/ticket.service.mjs +1 -1
  68. package/esm2022/lib/services/models/visit.service.mjs +1 -1
  69. package/esm2022/lib/services/models/zone.service.mjs +1 -1
  70. package/esm2022/lib/services/navigator.service.mjs +1 -1
  71. package/esm2022/lib/services/s3.service.mjs +1 -1
  72. package/esm2022/lib/services/search.service.mjs +1 -1
  73. package/esm2022/lib/services/support.service.mjs +1 -1
  74. package/esm2022/lib/services/sweep-locator.service.mjs +1 -1
  75. package/esm2022/lib/services/tag.service.mjs +16 -16
  76. package/esm2022/lib/services/threejs-import.service.mjs +1 -1
  77. package/esm2022/lib/services/threejs.service.mjs +1 -1
  78. package/esm2022/lib/services/user.service.mjs +1 -1
  79. package/esm2022/lib/services/utils/matterport-framing.util.mjs +63 -0
  80. package/esm2022/lib/services/utils/matterport-transform.util.mjs +1 -1
  81. package/esm2022/lib/services/validators.service.mjs +1 -1
  82. package/esm2022/lib/services/viewer.service.mjs +1 -1
  83. package/esm2022/lib/services/zone-drawer.service.mjs +1 -1
  84. package/esm2022/lib/services/zoneChange.service.mjs +1 -1
  85. package/esm2022/lib/tokens/matterport-sdk-key.token.mjs +1 -1
  86. package/esm2022/lib/types.service.mjs +3 -1
  87. package/esm2022/lib/validators/email.directive.mjs +1 -1
  88. package/esm2022/lib/validators/no-empty.directive.mjs +1 -1
  89. package/esm2022/lib/validators/number.directive.mjs +1 -1
  90. package/esm2022/lib/validators/text.directive.mjs +1 -1
  91. package/esm2022/public-api.mjs +1 -1
  92. package/fesm2022/smarterplan-ngx-smarterplan-core.mjs +1192 -263
  93. package/fesm2022/smarterplan-ngx-smarterplan-core.mjs.map +1 -1
  94. package/lib/services/matterport-object3d.service.d.ts +125 -5
  95. package/lib/services/matterport.service.d.ts +106 -7
  96. package/lib/services/utils/matterport-framing.util.d.ts +40 -0
  97. package/lib/types.service.d.ts +42 -1
  98. package/package.json +1 -1
  99. package/src/assets/vs-app.json +67 -67
@@ -1,6 +1,7 @@
1
1
  import { Injectable } from '@angular/core';
2
- import { PoiType } from '../types.service';
3
- import { Object3D } from 'three';
2
+ import { Subject } from 'rxjs';
3
+ import { PoiType, } from '../types.service';
4
+ import { Box3, MathUtils, Object3D, Vector3 } from 'three';
4
5
  import { NestThermostat } from '../matterport-extensions/nest-thermostat/NestThermostat';
5
6
  import { PlaneRenderer } from '../matterport-extensions/nest-thermostat/PlaneRenderer';
6
7
  import { CanvasRenderer } from "../matterport-extensions/nest-thermostat/CanvasRenderer";
@@ -15,6 +16,28 @@ export class MatterportObject3DService {
15
16
  azimuthalCrown;
16
17
  threeJSScene;
17
18
  noLightForObjects = true;
19
+ /** Max time (ms) to wait for a model to be loaded by the SDK */
20
+ loadTimeoutMs = 15000;
21
+ /** Max distance (m) an object can travel from where a translate drag started */
22
+ maxDragDistance = 2;
23
+ /** Max vertical travel (m, up and down) during a translate drag, so an object cannot jump to another floor */
24
+ maxDragHeight = 1.5;
25
+ /** Emits on every gizmo change and on setObject3DTransform */
26
+ object3DTransformChanged$ = new Subject();
27
+ /** Security camera animators by object uuid (`securityCameraAnimator` stays the last loaded one) */
28
+ securityCameraAnimators = new Map();
29
+ viewFrustumVisible = new Map();
30
+ lastSecurityCameraUuid = null;
31
+ /** Loader component of each model (outputs.objectRoot is set once loaded) */
32
+ loaderComponents = new Map();
33
+ gizmos = new Map();
34
+ activeGizmoUuid = null;
35
+ gizmoSnap = null;
36
+ /** Sweeps disabled by setNavigationLocked(true), re-enabled on unlock */
37
+ sweepsDisabledByLock = [];
38
+ /** Sweeps re-enabled by the last unlock (the SDK may still report them disabled for a moment) */
39
+ sweepsEnabledByUnlock = [];
40
+ tmpBox = new Box3();
18
41
  constructor() { }
19
42
  async init3DObjectViewer(sdk) {
20
43
  const [sceneObject] = await sdk.Scene.createObjects(1);
@@ -25,112 +48,184 @@ export class MatterportObject3DService {
25
48
  this.objectControl = nodeControl.addComponent('mp.transformControls');
26
49
  nodeControl.start();
27
50
  }
28
- async add3DObject(sdk, obj, mode) {
29
- return new Promise(async (resolve) => {
30
- const [sceneObject] = await sdk.Scene.createObjects(1);
31
- let isAnimatedSecurityCamera = (obj.object === "security_camera");
32
- let isNestThermostat = (obj.object === "nest_thermostat");
33
- let isSmarterplanPromotionalVideo = (obj.object === 'video');
34
- let isAzimuthalCrown = (obj.object === 'azimuth');
35
- const modelNode = sceneObject.addNode();
36
- let component = null;
37
- const initial = {
38
- url: `/assets/3Dobjects/objects/${obj.object}${obj.format.indexOf('.') === -1 ? '.' + obj.format : obj.format}`,
39
- localRotation: { "x": 0, "y": 0, "z": 0 },
40
- localPosition: { "x": 0, "y": 0, "z": 0 },
41
- visible: true,
42
- colliderEnabled: true
43
- };
44
- switch (obj.format) {
45
- case '.obj':
46
- case 'obj':
47
- component = modelNode.addComponent('mp.objLoader', initial);
48
- break;
49
- case '.fbx':
50
- case 'fbx':
51
- component = modelNode.addComponent('mp.fbxLoader', initial);
52
- break;
53
- case '.gltf':
54
- case 'gltf':
55
- case '.glb':
56
- case 'glb':
57
- component = modelNode.addComponent('mp.gltfLoader', initial);
58
- break;
59
- case '.dae':
60
- case 'dae':
61
- component = modelNode.addComponent('mp.daeLoader', initial);
62
- break;
63
- default:
64
- console.log('Format not supported');
65
- break;
66
- }
67
- if (this.noLightForObjects) {
68
- const lightsNode = sceneObject.addNode();
69
- lightsNode.addComponent('mp.ambientLight', {
70
- intensity: 1,
71
- color: { r: 1.0, g: 1.0, b: 1.0 },
72
- });
73
- this.noLightForObjects = false;
74
- }
75
- modelNode.obj3D.position.set(obj.position.x, obj.position.y, obj.position.z);
76
- modelNode.obj3D.rotation.set(obj.rotation.x, obj.rotation.y, obj.rotation.z);
77
- modelNode.obj3D.scale.set(obj.scale.x, obj.scale.y, obj.scale.z);
78
- if (isAzimuthalCrown) {
79
- this.azimuthalCrown = modelNode;
80
- }
81
- if (mode && !isNestThermostat) {
82
- this.attachGizmoControlTo3DObject(sdk, modelNode, sceneObject, mode, true, true).catch((e) => console.log(e));
83
- }
84
- if (this.lastObject3D && typeof this.lastObject3D.id === 'string') {
85
- modelNode.obj3D.uuid = this.lastObject3D.id;
86
- }
87
- else if (obj.id) {
88
- modelNode.obj3D.uuid = obj.id;
51
+ /** SDK loader component name for a model format, null when the format is not supported */
52
+ getLoaderComponentName(format) {
53
+ switch ((format || '').toLowerCase()) {
54
+ case '.obj':
55
+ case 'obj': return 'mp.objLoader';
56
+ case '.fbx':
57
+ case 'fbx': return 'mp.fbxLoader';
58
+ case '.gltf':
59
+ case 'gltf':
60
+ case '.glb':
61
+ case 'glb': return 'mp.gltfLoader';
62
+ case '.dae':
63
+ case 'dae': return 'mp.daeLoader';
64
+ default: return null;
65
+ }
66
+ }
67
+ /** Resolves once the loader component has produced its objectRoot, rejects after `timeoutMs` */
68
+ waitForModelLoaded(component, timeoutMs) {
69
+ return new Promise((resolve, reject) => {
70
+ const isLoaded = () => !!component?.outputs?.objectRoot;
71
+ if (isLoaded()) {
72
+ resolve();
73
+ return;
89
74
  }
90
- this.lastObject3D = modelNode.obj3D;
91
- this.dictionnaryObjects3D.set(modelNode.obj3D.uuid, modelNode);
92
- this.dictionnarySceneObjects3D.set(modelNode.obj3D.uuid, sceneObject);
93
- if (isAnimatedSecurityCamera) {
94
- const animator = modelNode.addComponent('mp.securityCamera', {
95
- "nearPlane": 0.1, "farPlane": 10, "horizontalFOV": 52, "aspect": 1.7777777777777777,
96
- "localPosition": { "x": 0.3, "y": 0.18, "z": 0 },
97
- "localRotation": { "x": -15, "y": -90, "z": 0 },
98
- "color": 65280, "panPeriod": 5, "panAngle": -45
99
- });
100
- this.securityCameraAnimator = animator;
101
- if (!obj.viewFrustum) {
102
- setTimeout(() => { animator.toggleViewFrustum(); }, 1000);
75
+ const poll = setInterval(() => {
76
+ if (isLoaded()) {
77
+ clearInterval(poll);
78
+ clearTimeout(timer);
79
+ resolve();
103
80
  }
104
- }
105
- if (isNestThermostat) {
106
- const cv = new CanvasRenderer();
107
- cv.onInit();
108
- const plane = new PlaneRenderer();
109
- plane.outputs = { objectRoot: new Object3D(), collider: new Object3D() };
110
- const inputTexture = cv.outputs.texture;
111
- plane.setRootScene(this.threeJSScene);
112
- plane.onInit(modelNode, inputTexture);
113
- const sc = new NestThermostat();
114
- sc.setComponent(component, plane, cv);
115
- sc.setRootScene(this.threeJSScene);
116
- sc.onInit(modelNode, plane, inputTexture);
117
- cv.setCanvasNestThermostatPainter(sc);
118
- setTimeout(() => { sc.inputs.loadingState = "Loaded"; sc.onInputsUpdated(); }, 5000);
119
- }
120
- if (isSmarterplanPromotionalVideo) {
121
- const sc = new TvPlayer();
122
- sc.setComponent(component);
123
- sc.onInit(modelNode);
124
- setTimeout(() => { sc.inputs.loadingState = "Loaded"; sc.onInputsUpdated(); }, 5000);
125
- }
126
- sceneObject.start();
127
- resolve(this.lastObject3D);
81
+ }, 50);
82
+ const timer = setTimeout(() => {
83
+ clearInterval(poll);
84
+ reject(new Error(`3D model not loaded after ${timeoutMs} ms`));
85
+ }, timeoutMs);
128
86
  });
129
87
  }
88
+ /**
89
+ * Adds a 3D model to the scene.
90
+ * The promise resolves with the three.js object once the model is actually loaded, and rejects
91
+ * (after cleaning the scene) when the format is unknown or the load times out.
92
+ * The position / rotation / scale of `obj` are applied to the model origin, as stored in DB.
93
+ */
94
+ async add3DObject(sdk, obj, mode) {
95
+ const loaderName = this.getLoaderComponentName(obj.format);
96
+ if (!loaderName) {
97
+ throw new Error(`3D object format not supported: ${obj.format}`);
98
+ }
99
+ const [sceneObject] = await sdk.Scene.createObjects(1);
100
+ const isAnimatedSecurityCamera = (!obj.url && obj.object === 'security_camera');
101
+ const isNestThermostat = (!obj.url && obj.object === 'nest_thermostat');
102
+ const isSmarterplanPromotionalVideo = (!obj.url && obj.object === 'video');
103
+ const isAzimuthalCrown = (!obj.url && obj.object === 'azimuth');
104
+ const modelNode = sceneObject.addNode();
105
+ const initial = {
106
+ url: obj.url || `/assets/3Dobjects/objects/${obj.object}${obj.format.indexOf('.') === -1 ? '.' + obj.format : obj.format}`,
107
+ localRotation: { 'x': 0, 'y': 0, 'z': 0 },
108
+ localPosition: { 'x': 0, 'y': 0, 'z': 0 },
109
+ visible: true,
110
+ colliderEnabled: true
111
+ };
112
+ const component = modelNode.addComponent(loaderName, initial);
113
+ if (this.noLightForObjects) {
114
+ const lightsNode = sceneObject.addNode();
115
+ lightsNode.addComponent('mp.ambientLight', {
116
+ intensity: 1,
117
+ color: { r: 1.0, g: 1.0, b: 1.0 },
118
+ });
119
+ this.noLightForObjects = false;
120
+ }
121
+ modelNode.obj3D.position.set(obj.position.x, obj.position.y, obj.position.z);
122
+ modelNode.obj3D.rotation.set(obj.rotation.x, obj.rotation.y, obj.rotation.z);
123
+ modelNode.obj3D.scale.set(obj.scale.x, obj.scale.y, obj.scale.z);
124
+ // The DB id replaces the three.js uuid. The id pre-set through setLastObject3D is only a fallback
125
+ // for callers without id: taking it first gave the same id to every object loaded meanwhile
126
+ // (several cameras or cubes loading while an add is starting), which then overwrote each other.
127
+ if (obj.id) {
128
+ modelNode.obj3D.uuid = obj.id;
129
+ }
130
+ else if (this.lastObject3D && typeof this.lastObject3D.id === 'string') {
131
+ modelNode.obj3D.uuid = this.lastObject3D.id;
132
+ }
133
+ const uuid = modelNode.obj3D.uuid;
134
+ this.lastObject3D = modelNode.obj3D;
135
+ this.dictionnaryObjects3D.set(uuid, modelNode);
136
+ this.dictionnarySceneObjects3D.set(uuid, sceneObject);
137
+ this.loaderComponents.set(uuid, component);
138
+ if (isAzimuthalCrown) {
139
+ this.azimuthalCrown = modelNode;
140
+ }
141
+ if (mode && !isNestThermostat) {
142
+ this.attachGizmo(uuid, mode).catch(() => { });
143
+ }
144
+ let animator = null;
145
+ if (isAnimatedSecurityCamera) {
146
+ animator = modelNode.addComponent('mp.securityCamera', {
147
+ 'nearPlane': 0.1, 'farPlane': 10, 'horizontalFOV': 52, 'aspect': 1.7777777777777777,
148
+ 'localPosition': { 'x': 0.3, 'y': 0.18, 'z': 0 },
149
+ 'localRotation': { 'x': -15, 'y': -90, 'z': 0 },
150
+ 'color': 65280, 'panPeriod': 5, 'panAngle': -45
151
+ });
152
+ this.securityCameraAnimator = animator;
153
+ this.securityCameraAnimators.set(uuid, animator);
154
+ this.viewFrustumVisible.set(uuid, true); // the component shows its frustum by default
155
+ this.lastSecurityCameraUuid = uuid;
156
+ }
157
+ if (isNestThermostat) {
158
+ const cv = new CanvasRenderer();
159
+ cv.onInit();
160
+ const plane = new PlaneRenderer();
161
+ plane.outputs = { objectRoot: new Object3D(), collider: new Object3D() };
162
+ const inputTexture = cv.outputs.texture;
163
+ plane.setRootScene(this.threeJSScene);
164
+ plane.onInit(modelNode, inputTexture);
165
+ const sc = new NestThermostat();
166
+ sc.setComponent(component, plane, cv);
167
+ sc.setRootScene(this.threeJSScene);
168
+ sc.onInit(modelNode, plane, inputTexture);
169
+ cv.setCanvasNestThermostatPainter(sc);
170
+ setTimeout(() => { sc.inputs.loadingState = 'Loaded'; sc.onInputsUpdated(); }, 5000);
171
+ }
172
+ if (isSmarterplanPromotionalVideo) {
173
+ const sc = new TvPlayer();
174
+ sc.setComponent(component);
175
+ sc.onInit(modelNode);
176
+ setTimeout(() => { sc.inputs.loadingState = 'Loaded'; sc.onInputsUpdated(); }, 5000);
177
+ }
178
+ sceneObject.start();
179
+ try {
180
+ await this.waitForModelLoaded(component, this.loadTimeoutMs);
181
+ }
182
+ catch (e) {
183
+ await this.deleteObject3D(uuid);
184
+ throw e;
185
+ }
186
+ if (animator && !obj.viewFrustum) {
187
+ // The camera component starts with the model node, so it is ready now that the model is loaded
188
+ this.applyViewFrustum(uuid, false);
189
+ }
190
+ return modelNode.obj3D;
191
+ }
192
+ /**
193
+ * Removes a 3D object for good: detaches its gizmo, stops its scene object and forgets it.
194
+ */
130
195
  async deleteObject3D(uuid) {
131
- const obj = this.dictionnaryObjects3D.get(uuid);
132
- if (obj)
133
- obj.obj3D.visible = false;
196
+ this.detachGizmo(uuid);
197
+ const node = this.dictionnaryObjects3D.get(uuid);
198
+ const sceneObject = this.dictionnarySceneObjects3D.get(uuid);
199
+ if (node) {
200
+ try {
201
+ node.obj3D.visible = false;
202
+ }
203
+ catch { /* already destroyed */ }
204
+ }
205
+ if (sceneObject && typeof sceneObject.stop === 'function') {
206
+ try {
207
+ sceneObject.stop();
208
+ }
209
+ catch { /* already stopped */ }
210
+ }
211
+ this.dictionnaryObjects3D.delete(uuid);
212
+ this.dictionnarySceneObjects3D.delete(uuid);
213
+ this.loaderComponents.delete(uuid);
214
+ if (this.lastObject3D && (this.lastObject3D.uuid === uuid || this.lastObject3D.id === uuid)) {
215
+ this.lastObject3D = null;
216
+ }
217
+ if (node && this.azimuthalCrown === node) {
218
+ this.azimuthalCrown = null;
219
+ }
220
+ const animator = this.securityCameraAnimators.get(uuid);
221
+ if (animator && this.securityCameraAnimator === animator) {
222
+ this.securityCameraAnimator = null;
223
+ }
224
+ this.securityCameraAnimators.delete(uuid);
225
+ this.viewFrustumVisible.delete(uuid);
226
+ if (this.lastSecurityCameraUuid === uuid) {
227
+ this.lastSecurityCameraUuid = null;
228
+ }
134
229
  }
135
230
  getObject3DModelNodeFromDictionnary(uuid) {
136
231
  let obj = this.dictionnaryObjects3D.get(uuid);
@@ -150,10 +245,32 @@ export class MatterportObject3DService {
150
245
  let obj = this.dictionnaryObjects3D.get(objectId);
151
246
  return obj ? obj.obj3D.visible : false;
152
247
  }
248
+ /** Shows / hides a model (used by the placement preview) */
249
+ setObject3DVisible(uuid, visible) {
250
+ const node = this.dictionnaryObjects3D.get(uuid);
251
+ if (node)
252
+ node.obj3D.visible = visible;
253
+ }
254
+ /** Enables / disables the pointer collider of a model (disabled while it follows the cursor) */
255
+ setObject3DColliderEnabled(uuid, enabled) {
256
+ const component = this.loaderComponents.get(uuid);
257
+ if (component?.inputs) {
258
+ component.inputs.colliderEnabled = enabled;
259
+ }
260
+ }
261
+ /**
262
+ * Moves the camera next to a 3D object by creating a temporary tag on the object centre.
263
+ * @returns false when the object is unknown or no tag could be reached
264
+ */
153
265
  async pointCameraTo3DObject(sdk, objectId, createTagCallback, goToTagCallback, deleteLastTagCallback, getTagFromElementId) {
154
- let obj = this.dictionnaryObjects3D.get(objectId);
266
+ const obj = this.dictionnaryObjects3D.get(objectId);
267
+ if (!obj)
268
+ return false;
269
+ // Tag on the bounding box centre (the model origin is a corner for most models)
270
+ const box = this.getObject3DBoundingBox(objectId);
271
+ const anchor = box ? box.center : this.toPoint(obj.obj3D.position);
155
272
  const poiObject = {
156
- coordinate: JSON.stringify(obj.obj3D.position),
273
+ coordinate: JSON.stringify(anchor),
157
274
  type: PoiType.OBJECT3D,
158
275
  elementID: objectId,
159
276
  };
@@ -162,9 +279,16 @@ export class MatterportObject3DService {
162
279
  await createTagCallback(PoiType.OBJECT3D, objectDb, poiObject);
163
280
  }
164
281
  catch (err) { }
165
- let result = getTagFromElementId(objectId);
166
- await goToTagCallback(result.tag);
167
- deleteLastTagCallback();
282
+ try {
283
+ const result = getTagFromElementId(objectId);
284
+ if (!result?.tag)
285
+ return false;
286
+ await goToTagCallback(result.tag);
287
+ return true;
288
+ }
289
+ finally {
290
+ deleteLastTagCallback();
291
+ }
168
292
  }
169
293
  getSceneNodeFromObject3DId(uuid) {
170
294
  return this.dictionnarySceneObjects3D.get(uuid);
@@ -174,49 +298,449 @@ export class MatterportObject3DService {
174
298
  this.azimuthalCrown.obj3D.position.set(poseCamera.position.x, poseCamera.position.y, poseCamera.position.z);
175
299
  }
176
300
  }
301
+ //
302
+ // ---------- Geometry helpers ----------
303
+ //
304
+ toPoint(v) {
305
+ return { x: v.x, y: v.y, z: v.z };
306
+ }
307
+ /**
308
+ * Geometry of the model itself (the loader output): the node also holds the helpers added by other
309
+ * components, like the view frustum of a security camera, which must not count in its size.
310
+ */
311
+ modelRoot(uuid, node) {
312
+ return this.loaderComponents.get(uuid)?.outputs?.objectRoot ?? node.obj3D;
313
+ }
314
+ /** World-space bounding box of the model, null when unknown or when nothing is loaded yet */
315
+ getObject3DBoundingBox(uuid) {
316
+ const node = this.dictionnaryObjects3D.get(uuid);
317
+ if (!node)
318
+ return null;
319
+ node.obj3D.updateWorldMatrix(true, true);
320
+ const box = this.tmpBox.setFromObject(this.modelRoot(uuid, node));
321
+ if (box.isEmpty())
322
+ return null;
323
+ const size = box.getSize(new Vector3());
324
+ const center = box.getCenter(new Vector3());
325
+ return {
326
+ min: this.toPoint(box.min),
327
+ max: this.toPoint(box.max),
328
+ size: this.toPoint(size),
329
+ center: this.toPoint(center),
330
+ };
331
+ }
332
+ /**
333
+ * Real dimensions of the model in meters (width x, height y, depth z), scale included but not
334
+ * its rotation: the world bounding box of a rotated object is larger than the object itself.
335
+ */
336
+ getObject3DDimensions(uuid) {
337
+ const node = this.dictionnaryObjects3D.get(uuid);
338
+ if (!node)
339
+ return null;
340
+ const rotation = node.obj3D.rotation.clone();
341
+ node.obj3D.rotation.set(0, 0, 0);
342
+ try {
343
+ node.obj3D.updateWorldMatrix(true, true);
344
+ const box = this.tmpBox.setFromObject(this.modelRoot(uuid, node));
345
+ return box.isEmpty() ? null : this.toPoint(box.getSize(new Vector3()));
346
+ }
347
+ finally {
348
+ node.obj3D.rotation.copy(rotation);
349
+ node.obj3D.updateWorldMatrix(true, true);
350
+ }
351
+ }
352
+ /**
353
+ * Uniform scale so that the largest bounding box dimension equals `targetSizeMeters`.
354
+ * The node position is untouched, so call placeObject3DOnSurface afterwards.
355
+ * @returns the new scale, null when the object is unknown / not loaded / `targetSizeMeters` invalid
356
+ */
357
+ normalizeObject3DSize(uuid, targetSizeMeters) {
358
+ const node = this.dictionnaryObjects3D.get(uuid);
359
+ const box = this.getObject3DBoundingBox(uuid);
360
+ if (!node || !box || !(targetSizeMeters > 0))
361
+ return null;
362
+ const largest = Math.max(box.size.x, box.size.y, box.size.z);
363
+ if (!(largest > 0))
364
+ return null;
365
+ const factor = targetSizeMeters / largest;
366
+ node.obj3D.scale.multiplyScalar(factor);
367
+ this.emitTransformChanged(uuid);
368
+ return this.toPoint(node.obj3D.scale);
369
+ }
370
+ /**
371
+ * Places the model on a surface point without touching its pivot: the node position is
372
+ * adjusted so that the bounding box bottom-center lies on `point`.
373
+ * - floor (normal pointing up, or no normal): bottom-center on the point
374
+ * - wall (mostly horizontal normal): model turned around Y so its +Z faces away from the wall,
375
+ * and pushed along the normal by half its depth so it does not cut the wall
376
+ * - ceiling (normal pointing down): the model hangs, top-center on the point
377
+ * @returns the new transform, null when the object is unknown or not loaded
378
+ */
379
+ /**
380
+ * @param frontYawOffset rotation (radians, around Y) that turns the front of the model toward its +Z
381
+ * axis, for models whose front is another axis (e.g. -PI/2 when it is +X)
382
+ */
383
+ placeObject3DOnSurface(uuid, point, normal, frontYawOffset = 0) {
384
+ const node = this.dictionnaryObjects3D.get(uuid);
385
+ if (!node || !this.getObject3DBoundingBox(uuid))
386
+ return null;
387
+ const obj = node.obj3D;
388
+ const n = normal ? new Vector3(normal.x, normal.y, normal.z) : new Vector3(0, 1, 0);
389
+ if (n.lengthSq() === 0)
390
+ n.set(0, 1, 0);
391
+ n.normalize();
392
+ const isWall = Math.abs(n.y) < 0.5;
393
+ const isCeiling = !isWall && n.y < 0;
394
+ const target = new Vector3(point.x, point.y, point.z);
395
+ if (isWall) {
396
+ // Face away from the wall; the box has to be measured after the rotation
397
+ obj.rotation.y = Math.atan2(n.x, n.z) + frontYawOffset;
398
+ }
399
+ const box = this.getObject3DBoundingBox(uuid);
400
+ if (isWall) {
401
+ const horizontal = new Vector3(n.x, 0, n.z).normalize();
402
+ const halfDepth = 0.5 * (Math.abs(horizontal.x) * box.size.x + Math.abs(horizontal.z) * box.size.z);
403
+ target.addScaledVector(horizontal, halfDepth);
404
+ }
405
+ const anchorY = isCeiling ? box.max.y : box.min.y;
406
+ obj.position.x += target.x - box.center.x;
407
+ obj.position.y += target.y - anchorY;
408
+ obj.position.z += target.z - box.center.z;
409
+ this.emitTransformChanged(uuid);
410
+ return this.getObject3DTransform(uuid);
411
+ }
412
+ getObject3DTransform(uuid) {
413
+ const node = this.dictionnaryObjects3D.get(uuid);
414
+ if (!node)
415
+ return null;
416
+ const o = node.obj3D;
417
+ return {
418
+ position: this.toPoint(o.position),
419
+ rotation: { x: o.rotation.x, y: o.rotation.y, z: o.rotation.z },
420
+ scale: this.toPoint(o.scale),
421
+ };
422
+ }
423
+ /** Applies a (partial) transform. Rotation is in radians. */
424
+ setObject3DTransform(uuid, transform) {
425
+ const node = this.dictionnaryObjects3D.get(uuid);
426
+ if (!node)
427
+ return false;
428
+ const o = node.obj3D;
429
+ if (transform.position)
430
+ o.position.set(transform.position.x, transform.position.y, transform.position.z);
431
+ if (transform.rotation)
432
+ o.rotation.set(transform.rotation.x, transform.rotation.y, transform.rotation.z);
433
+ if (transform.scale)
434
+ o.scale.set(transform.scale.x, transform.scale.y, transform.scale.z);
435
+ this.emitTransformChanged(uuid);
436
+ return true;
437
+ }
438
+ emitTransformChanged(uuid) {
439
+ const transform = this.getObject3DTransform(uuid);
440
+ if (transform) {
441
+ this.object3DTransformChanged$.next({ uuid, ...transform });
442
+ }
443
+ }
444
+ //
445
+ // ---------- Gizmo ----------
446
+ //
447
+ /** Creates the mp.transformControls node of a model and wires it (events, snap) */
448
+ createGizmo(uuid, modelNode, sceneObject, mode, visible, node) {
449
+ const gizmoNode = node ?? sceneObject.addNode();
450
+ const component = gizmoNode.addComponent('mp.transformControls');
451
+ gizmoNode.start();
452
+ const tc = component.transformControls;
453
+ tc.visible = visible;
454
+ component.inputs.selection = modelNode;
455
+ component.inputs.mode = mode;
456
+ modelNode.obj3D.controls = component;
457
+ const entry = {
458
+ uuid,
459
+ node: gizmoNode,
460
+ component,
461
+ mode,
462
+ dragStart: null,
463
+ lastPosition: modelNode.obj3D.position.clone(),
464
+ onDraggingChanged: (event) => {
465
+ entry.dragStart = event?.value ? modelNode.obj3D.position.clone() : null;
466
+ entry.lastPosition = modelNode.obj3D.position.clone();
467
+ },
468
+ onObjectChange: () => this.onGizmoObjectChange(entry, modelNode),
469
+ };
470
+ if (typeof tc.addEventListener === 'function') {
471
+ tc.addEventListener('dragging-changed', entry.onDraggingChanged);
472
+ tc.addEventListener('objectChange', entry.onObjectChange);
473
+ }
474
+ this.applySnap(tc);
475
+ this.gizmos.set(uuid, entry);
476
+ this.activeGizmoUuid = uuid;
477
+ return entry;
478
+ }
479
+ /** Keeps a translate drag within maxDragDistance / maxDragHeight of where it started, then notifies */
480
+ onGizmoObjectChange(entry, modelNode) {
481
+ const pos = modelNode.obj3D.position;
482
+ if (entry.mode === 'translate') {
483
+ const start = entry.dragStart ?? entry.lastPosition;
484
+ const delta = pos.clone().sub(start);
485
+ delta.y = MathUtils.clamp(delta.y, -this.maxDragHeight, this.maxDragHeight);
486
+ const length = delta.length();
487
+ if (length > this.maxDragDistance) {
488
+ delta.multiplyScalar(this.maxDragDistance / length);
489
+ }
490
+ pos.copy(start).add(delta);
491
+ }
492
+ entry.lastPosition = pos.clone();
493
+ this.emitTransformChanged(entry.uuid);
494
+ }
495
+ applySnap(tc) {
496
+ if (!tc)
497
+ return;
498
+ const snap = this.gizmoSnap;
499
+ const translation = snap?.translation ?? null;
500
+ const rotation = snap?.rotationDeg != null ? MathUtils.degToRad(snap.rotationDeg) : null;
501
+ const scale = snap?.scale ?? null;
502
+ if (typeof tc.setTranslationSnap === 'function')
503
+ tc.setTranslationSnap(translation);
504
+ else
505
+ tc.translationSnap = translation;
506
+ if (typeof tc.setRotationSnap === 'function')
507
+ tc.setRotationSnap(rotation);
508
+ else
509
+ tc.rotationSnap = rotation;
510
+ if (typeof tc.setScaleSnap === 'function')
511
+ tc.setScaleSnap(scale);
512
+ else
513
+ tc.scaleSnap = scale;
514
+ }
515
+ /**
516
+ * Shows the transform gizmo on an object (any previous gizmo is detached first).
517
+ * Re-attaching to the object that already has the gizmo only changes its mode.
518
+ */
519
+ async attachGizmo(uuid, mode, sdk) {
520
+ const modelNode = this.dictionnaryObjects3D.get(uuid);
521
+ const sceneObject = this.dictionnarySceneObjects3D.get(uuid);
522
+ if (!modelNode || !sceneObject)
523
+ return false;
524
+ const existing = this.gizmos.get(uuid);
525
+ if (existing && this.activeGizmoUuid === uuid) {
526
+ this.setGizmoMode(mode);
527
+ return true;
528
+ }
529
+ // A started scene object refuses new nodes (addNode returns null): use a dedicated one
530
+ let node = sceneObject.addNode();
531
+ let gizmoSceneObject = null;
532
+ if (!node) {
533
+ if (!sdk?.Scene)
534
+ return false;
535
+ [gizmoSceneObject] = await sdk.Scene.createObjects(1);
536
+ node = gizmoSceneObject.addNode();
537
+ }
538
+ this.detachGizmo();
539
+ const entry = this.createGizmo(uuid, modelNode, sceneObject, mode, true, node);
540
+ entry.sceneObject = gizmoSceneObject;
541
+ this.lastObject3D = modelNode.obj3D;
542
+ return true;
543
+ }
544
+ /** Switches the active gizmo between translate / rotate / scale without re-attaching it */
545
+ setGizmoMode(mode) {
546
+ const entry = this.activeGizmoUuid ? this.gizmos.get(this.activeGizmoUuid) : null;
547
+ if (!entry)
548
+ return;
549
+ entry.mode = mode;
550
+ entry.dragStart = null;
551
+ entry.component.inputs.mode = mode;
552
+ const tc = entry.component.transformControls;
553
+ if (tc && typeof tc.setMode === 'function')
554
+ tc.setMode(mode);
555
+ }
556
+ /** Really removes the gizmo from the scene (default: the active one) */
557
+ detachGizmo(uuid) {
558
+ const id = uuid ?? this.activeGizmoUuid;
559
+ if (!id)
560
+ return;
561
+ const entry = this.gizmos.get(id);
562
+ if (!entry)
563
+ return;
564
+ const tc = entry.component?.transformControls;
565
+ if (tc) {
566
+ if (typeof tc.removeEventListener === 'function') {
567
+ tc.removeEventListener('dragging-changed', entry.onDraggingChanged);
568
+ tc.removeEventListener('objectChange', entry.onObjectChange);
569
+ }
570
+ tc.visible = false;
571
+ if (typeof tc.detach === 'function')
572
+ tc.detach();
573
+ if (typeof tc.dispose === 'function')
574
+ tc.dispose();
575
+ if (tc.parent && typeof tc.parent.remove === 'function')
576
+ tc.parent.remove(tc);
577
+ }
578
+ try {
579
+ entry.node.stop();
580
+ }
581
+ catch { /* already stopped */ }
582
+ try {
583
+ entry.sceneObject?.stop();
584
+ }
585
+ catch { /* already stopped */ }
586
+ const modelNode = this.dictionnaryObjects3D.get(id);
587
+ if (modelNode?.obj3D)
588
+ modelNode.obj3D.controls = null;
589
+ this.gizmos.delete(id);
590
+ if (this.activeGizmoUuid === id)
591
+ this.activeGizmoUuid = null;
592
+ }
593
+ isGizmoAttached(uuid) {
594
+ return uuid ? this.gizmos.has(uuid) : this.activeGizmoUuid !== null;
595
+ }
596
+ /** Snap steps for all gizmos (null / missing value = no snap) */
597
+ setGizmoSnap(snap) {
598
+ this.gizmoSnap = snap ? { ...snap } : null;
599
+ this.gizmos.forEach((entry) => this.applySnap(entry.component?.transformControls));
600
+ }
601
+ setGizmoMaxDragDistance(maxDistance, maxHeight) {
602
+ if (maxDistance > 0)
603
+ this.maxDragDistance = maxDistance;
604
+ if (maxHeight !== undefined && maxHeight > 0)
605
+ this.maxDragHeight = maxHeight;
606
+ }
607
+ /**
608
+ * Prevents camera navigation to other sweeps while a gizmo is edited.
609
+ * The SDK has no "freeze camera" switch, so every enabled sweep except the current one is
610
+ * disabled (Sweep.disable); exactly those sweeps are re-enabled on unlock. Sweeps already
611
+ * disabled (forbidden sweeps, edit mode) are never touched, and `keepDisabled` lists sweeps
612
+ * that must stay disabled on unlock.
613
+ * @returns false when the lock could not be applied (SDK without Sweep.disable, unknown current sweep)
614
+ */
615
+ async setNavigationLocked(sdk, locked, sweepCollection, currentSweepId, keepDisabled = []) {
616
+ if (!sdk?.Sweep || typeof sdk.Sweep.disable !== 'function' || typeof sdk.Sweep.enable !== 'function') {
617
+ return false;
618
+ }
619
+ if (locked) {
620
+ if (this.sweepsDisabledByLock.length > 0)
621
+ return true;
622
+ if (!sweepCollection || !currentSweepId)
623
+ return false;
624
+ // a sweep this lock re-enabled just before may still be reported disabled by the SDK
625
+ const ids = Object.keys(sweepCollection).filter((sid) => sid !== currentSweepId &&
626
+ (sweepCollection[sid]?.enabled !== false || this.sweepsEnabledByUnlock.includes(sid)));
627
+ if (ids.length === 0)
628
+ return true;
629
+ try {
630
+ await sdk.Sweep.disable(...ids);
631
+ this.sweepsDisabledByLock = ids;
632
+ }
633
+ catch {
634
+ // fall back to one call per sweep to know exactly which ones were disabled
635
+ const results = await Promise.allSettled(ids.map((sid) => sdk.Sweep.disable(sid)));
636
+ this.sweepsDisabledByLock = ids.filter((_, i) => results[i].status === 'fulfilled');
637
+ }
638
+ return true;
639
+ }
640
+ const toEnable = this.sweepsDisabledByLock.filter((sid) => !keepDisabled.includes(sid));
641
+ this.sweepsDisabledByLock = [];
642
+ this.sweepsEnabledByUnlock = toEnable;
643
+ if (toEnable.length > 0) {
644
+ try {
645
+ await sdk.Sweep.enable(...toEnable);
646
+ }
647
+ catch {
648
+ await Promise.allSettled(toEnable.map((sid) => sdk.Sweep.enable(sid)));
649
+ }
650
+ }
651
+ return true;
652
+ }
653
+ isNavigationLocked() {
654
+ return this.sweepsDisabledByLock.length > 0;
655
+ }
656
+ /** Sweeps currently disabled by the navigation lock */
657
+ getSweepsDisabledByLock() {
658
+ return [...this.sweepsDisabledByLock];
659
+ }
660
+ /**
661
+ * Legacy API: attaches a gizmo to a model node. Prefer attachGizmo(uuid, mode).
662
+ */
177
663
  async attachGizmoControlTo3DObject(sdk, modelNode, sceneObject, mode, visible, isNewObject) {
178
664
  let node = sceneObject.addNode();
179
665
  if (!node) {
180
666
  const [newSceneObject] = await sdk.Scene.createObjects(1);
181
667
  node = newSceneObject.addNode();
182
668
  }
183
- const myControl = node.addComponent('mp.transformControls');
184
- node.start();
185
- myControl.transformControls.visible = visible;
186
- myControl.inputs.selection = modelNode;
187
- myControl.inputs.mode = mode;
188
- modelNode.obj3D.controls = myControl;
189
- if (isNewObject) {
190
- if (!this.lastObject3D || !this.lastObject3D.controls) {
191
- try {
192
- modelNode.obj3D.uuid = this.lastObject3D.uuid || this.lastObject3D.id;
193
- }
194
- catch (e) {
195
- console.log(`id obj in Scene was not assigned to id from DB`);
196
- }
197
- this.lastObject3D = modelNode.obj3D;
669
+ if (isNewObject && (!this.lastObject3D || !this.lastObject3D.controls)) {
670
+ try {
671
+ modelNode.obj3D.uuid = this.lastObject3D.uuid || this.lastObject3D.id;
672
+ }
673
+ catch (e) {
674
+ // lastObject3D is not set: the model keeps its own uuid
198
675
  }
199
676
  }
200
- else {
201
- this.lastObject3D = modelNode.obj3D;
202
- }
677
+ this.detachGizmo();
678
+ this.createGizmo(modelNode.obj3D.uuid, modelNode, sceneObject, mode, visible, node);
679
+ this.lastObject3D = modelNode.obj3D;
203
680
  return modelNode;
204
681
  }
682
+ /** Removes the gizmo of the last added / edited object */
205
683
  removeGizmoFromLastObject() {
206
- if (this.lastObject3D && this.lastObject3D.controls) {
207
- this.lastObject3D.controls.transformControls.visible = false;
208
- this.lastObject3D.controls.transformControls.dispose();
209
- this.lastObject3D.controls = null;
684
+ const last = this.lastObject3D;
685
+ if (!last)
686
+ return;
687
+ const uuid = last.uuid ?? last.id;
688
+ if (uuid && this.gizmos.has(uuid)) {
689
+ this.detachGizmo(uuid);
690
+ }
691
+ else if (last.controls) {
692
+ // gizmo not created by this service: best effort
693
+ last.controls.transformControls.visible = false;
694
+ last.controls.transformControls.dispose();
695
+ last.controls = null;
210
696
  }
211
697
  }
212
- toggleViewFrustum() {
213
- if (this.securityCameraAnimator) {
698
+ //
699
+ // ---------- Security camera ----------
700
+ //
701
+ applyViewFrustum(uuid, visible) {
702
+ const animator = this.securityCameraAnimators.get(uuid);
703
+ if (!animator)
704
+ return false;
705
+ const current = this.viewFrustumVisible.get(uuid) ?? true;
706
+ if (current === visible)
707
+ return true;
708
+ try {
709
+ animator.toggleViewFrustum();
710
+ }
711
+ catch {
712
+ return false;
713
+ }
714
+ this.viewFrustumVisible.set(uuid, visible);
715
+ return true;
716
+ }
717
+ /** Shows / hides the view frustum of the security camera `uuid` */
718
+ setViewFrustum(uuid, visible) {
719
+ return this.applyViewFrustum(uuid, visible);
720
+ }
721
+ isViewFrustumVisible(uuid) {
722
+ return this.viewFrustumVisible.get(uuid) ?? false;
723
+ }
724
+ /** Toggles the frustum of `uuid`, or of the last loaded security camera when omitted */
725
+ toggleViewFrustum(uuid) {
726
+ const id = uuid ?? this.lastSecurityCameraUuid;
727
+ if (id && this.securityCameraAnimators.has(id)) {
728
+ this.applyViewFrustum(id, !(this.viewFrustumVisible.get(id) ?? true));
729
+ }
730
+ else if (!uuid && this.securityCameraAnimator) {
731
+ // animator set by hand (legacy)
214
732
  this.securityCameraAnimator.toggleViewFrustum();
215
733
  }
216
734
  }
217
735
  clear() {
736
+ Array.from(this.gizmos.keys()).forEach((id) => this.detachGizmo(id));
218
737
  this.dictionnaryObjects3D.clear();
219
738
  this.dictionnarySceneObjects3D.clear();
739
+ this.loaderComponents.clear();
740
+ this.securityCameraAnimators.clear();
741
+ this.viewFrustumVisible.clear();
742
+ this.lastSecurityCameraUuid = null;
743
+ this.sweepsDisabledByLock = [];
220
744
  this.lastObject3D = null;
221
745
  this.azimuthalCrown = null;
222
746
  this.securityCameraAnimator = null;
@@ -231,4 +755,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
231
755
  providedIn: 'root',
232
756
  }]
233
757
  }], ctorParameters: () => [] });
234
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0dGVycG9ydC1vYmplY3QzZC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXNtYXJ0ZXJwbGFuLWNvcmUvc3JjL2xpYi9zZXJ2aWNlcy9tYXR0ZXJwb3J0LW9iamVjdDNkLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQWEsT0FBTyxFQUFxQixNQUFNLGtCQUFrQixDQUFDO0FBQ3pFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxPQUFPLENBQUM7QUFDakMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHlEQUF5RCxDQUFDO0FBQ3pGLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx3REFBd0QsQ0FBQztBQUN2RixPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0seURBQXlELENBQUM7QUFDekYsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLDZDQUE2QyxDQUFDOztBQUt2RSxNQUFNLE9BQU8seUJBQXlCO0lBQzdCLG9CQUFvQixHQUFxQixJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQ25ELHlCQUF5QixHQUFxQixJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQ3hELFlBQVksQ0FBTSxDQUFDLGtCQUFrQjtJQUNyQyxhQUFhLENBQU07SUFDbkIsc0JBQXNCLENBQU07SUFDNUIsY0FBYyxDQUFNO0lBQ3BCLFlBQVksQ0FBTTtJQUNsQixpQkFBaUIsR0FBRyxJQUFJLENBQUM7SUFFaEMsZ0JBQWdCLENBQUM7SUFFakIsS0FBSyxDQUFDLGtCQUFrQixDQUFDLEdBQVE7UUFDL0IsTUFBTSxDQUFDLFdBQVcsQ0FBQyxHQUFHLE1BQU0sR0FBRyxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkQsTUFBTSxJQUFJLEdBQUcsV0FBVyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FB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QUcsSUFBSSxDQUFDO1FBQ3BDLENBQUM7SUFDSCxDQUFDO0lBRUQsaUJBQWlCO1FBQ2YsSUFBSSxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztZQUNoQyxJQUFJLENBQUMsc0JBQXNCLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUNsRCxDQUFDO0lBQ0gsQ0FBQztJQUVELEtBQUs7UUFDSCxJQUFJLENBQUMsb0JBQW9CLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDbEMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDO1FBQzNCLElBQUksQ0FBQyxzQkFBc0IsR0FBRyxJQUFJLENBQUM7UUFDbkMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQztJQUNoQyxDQUFDO3dHQXJPVSx5QkFBeUI7NEdBQXpCLHlCQUF5QixjQUZ4QixNQUFNOzs0RkFFUCx5QkFBeUI7a0JBSHJDLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSU9iamVjdDNELCBQb2lUeXBlLCBQT0ksIERiT2JqZWN0VHlwZSB9IGZyb20gJy4uL3R5cGVzLnNlcnZpY2UnO1xuaW1wb3J0IHsgT2JqZWN0M0QgfSBmcm9tICd0aHJlZSc7XG5pbXBvcnQgeyBOZXN0VGhlcm1vc3RhdCB9IGZyb20gJy4uL21hdHRlcnBvcnQtZXh0ZW5zaW9ucy9uZXN0LXRoZXJtb3N0YXQvTmVzdFRoZXJtb3N0YXQnO1xuaW1wb3J0IHsgUGxhbmVSZW5kZXJlciB9IGZyb20gJy4uL21hdHRlcnBvcnQtZXh0ZW5zaW9ucy9uZXN0LXRoZXJtb3N0YXQvUGxhbmVSZW5kZXJlcic7XG5pbXBvcnQgeyBDYW52YXNSZW5kZXJlciB9IGZyb20gXCIuLi9tYXR0ZXJwb3J0LWV4dGVuc2lvbnMvbmVzdC10aGVybW9zdGF0L0NhbnZhc1JlbmRlcmVyXCI7XG5pbXBvcnQgeyBUdlBsYXllciB9IGZyb20gXCIuLi9tYXR0ZXJwb3J0LWV4dGVuc2lvbnMvdHYtcGxheWVyL1R2UGxheWVyXCI7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBNYXR0ZXJwb3J0T2JqZWN0M0RTZXJ2aWNlIHtcbiAgcHVibGljIGRpY3Rpb25uYXJ5T2JqZWN0czNEOiBNYXA8c3RyaW5nLCBhbnk+ID0gbmV3IE1hcCgpO1xuICBwdWJsaWMgZGljdGlvbm5hcnlTY2VuZU9iamVjdHMzRDogTWFwPHN0cmluZywgYW55PiA9IG5ldyBNYXAoKTtcbiAgcHVibGljIGxhc3RPYmplY3QzRDogYW55OyAvLyBUaHJlZSBKUyBvYmplY3RcbiAgcHVibGljIG9iamVjdENvbnRyb2w6IGFueTtcbiAgcHVibGljIHNlY3VyaXR5Q2FtZXJhQW5pbWF0b3I6IGFueTtcbiAgcHVibGljIGF6aW11dGhhbENyb3duOiBhbnk7XG4gIHB1YmxpYyB0aHJlZUpTU2NlbmU6IGFueTtcbiAgcHVibGljIG5vTGlnaHRGb3JPYmplY3RzID0gdHJ1ZTtcblxuICBjb25zdHJ1Y3RvcigpIHsgfVxuXG4gIGFzeW5jIGluaXQzRE9iamVjdFZpZXdlcihzZGs6IGFueSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IFtzY2VuZU9iamVjdF0gPSBhd2FpdCBzZGsuU2NlbmUuY3JlYXRlT2JqZWN0cygxKTtcbiAgICBjb25zdCBub2RlID0gc2NlbmVPYmplY3QuYWRkTm9kZSgpO1xuICAgIG5vZGUuc3RhcnQoKTtcbiAgICB0aGlzLnRocmVlSlNTY2VuZSA9IG5vZGUub2JqM0QucGFyZW50O1xuXG4gICAgY29uc3Qgbm9kZUNvbnRyb2wgPSBzY2VuZU9iamVjdC5hZGROb2RlKCk7XG4gICAgdGhpcy5vYmplY3RDb250cm9sID0gbm9kZUNvbnRyb2wuYWRkQ29tcG9uZW50KCdtcC50cmFuc2Zvcm1Db250cm9scycpO1xuICAgIG5vZGVDb250cm9sLnN0YXJ0KCk7XG4gIH1cblxuICBhc3luYyBhZGQzRE9iamVjdChcbiAgICBzZGs6IGFueSxcbiAgICBvYmo6IElPYmplY3QzRCxcbiAgICBtb2RlPzogJ3RyYW5zbGF0ZScgfCAncm90YXRlJ1xuICApOiBQcm9taXNlPGFueT4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSkgPT4ge1xuICAgICAgY29uc3QgW3NjZW5lT2JqZWN0XSA9IGF3YWl0IHNkay5TY2VuZS5jcmVhdGVPYmplY3RzKDEpO1xuXG4gICAgICBsZXQgaXNBbmltYXRlZFNlY3VyaXR5Q2FtZXJhID0gKG9iai5vYmplY3QgPT09IFwic2VjdXJpdHlfY2FtZXJhXCIpO1xuICAgICAgbGV0IGlzTmVzdFRoZXJtb3N0YXQgPSAob2JqLm9iamVjdCA9PT0gXCJuZXN0X3RoZXJtb3N0YXRcIik7XG4gICAgICBsZXQgaXNTbWFydGVycGxhblByb21vdGlvbmFsVmlkZW8gPSAob2JqLm9iamVjdCA9PT0gJ3ZpZGVvJyk7XG4gICAgICBsZXQgaXNBemltdXRoYWxDcm93biA9IChvYmoub2JqZWN0ID09PSAnYXppbXV0aCcpO1xuXG4gICAgICBjb25zdCBtb2RlbE5vZGUgPSBzY2VuZU9iamVjdC5hZGROb2RlKCk7XG4gICAgICBsZXQgY29tcG9uZW50ID0gbnVsbDtcbiAgICAgIGNvbnN0IGluaXRpYWwgPSB7XG4gICAgICAgIHVybDogYC9hc3NldHMvM0RvYmplY3RzL29iamVjdHMvJHtvYmoub2JqZWN0fSR7b2JqLmZvcm1hdC5pbmRleE9mKCcuJykgPT09IC0xID8gJy4nICsgb2JqLmZvcm1hdCA6IG9iai5mb3JtYXR9YCxcbiAgICAgICAgbG9jYWxSb3RhdGlvbjogeyBcInhcIjogMCwgXCJ5XCI6IDAsIFwielwiOiAwIH0sXG4gICAgICAgIGxvY2FsUG9zaXRpb246IHsgXCJ4XCI6IDAsIFwieVwiOiAwLCBcInpcIjogMCB9LFxuICAgICAgICB2aXNpYmxlOiB0cnVlLFxuICAgICAgICBjb2xsaWRlckVuYWJsZWQ6IHRydWVcbiAgICAgIH07XG5cbiAgICAgIHN3aXRjaCAob2JqLmZvcm1hdCkge1xuICAgICAgICBjYXNlICcub2JqJzogY2FzZSAnb2JqJzogY29tcG9uZW50ID0gbW9kZWxOb2RlLmFkZENvbXBvbmVudCgnbXAub2JqTG9hZGVyJywgaW5pdGlhbCk7IGJyZWFrO1xuICAgICAgICBjYXNlICcuZmJ4JzogY2FzZSAnZmJ4JzogY29tcG9uZW50ID0gbW9kZWxOb2RlLmFkZENvbXBvbmVudCgnbXAuZmJ4TG9hZGVyJywgaW5pdGlhbCk7IGJyZWFrO1xuICAgICAgICBjYXNlICcuZ2x0Zic6IGNhc2UgJ2dsdGYnOiBjYXNlICcuZ2xiJzogY2FzZSAnZ2xiJzogY29tcG9uZW50ID0gbW9kZWxOb2RlLmFkZENvbXBvbmVudCgnbXAuZ2x0ZkxvYWRlcicsIGluaXRpYWwpOyBicmVhaztcbiAgICAgICAgY2FzZSAnLmRhZSc6IGNhc2UgJ2RhZSc6IGNvbXBvbmVudCA9IG1vZGVsTm9kZS5hZGRDb21wb25lbnQoJ21wLmRhZUxvYWRlcicsIGluaXRpYWwpOyBicmVhaztcbiAgICAgICAgZGVmYXVsdDogY29uc29sZS5sb2coJ0Zvcm1hdCBub3Qgc3VwcG9ydGVkJyk7IGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5ub0xpZ2h0Rm9yT2JqZWN0cykge1xuICAgICAgICBjb25zdCBsaWdodHNOb2RlID0gc2NlbmVPYmplY3QuYWRkTm9kZSgpO1xuICAgICAgICBsaWdodHNOb2RlLmFkZENvbXBvbmVudCgnbXAuYW1iaWVudExpZ2h0Jywge1xuICAgICAgICAgIGludGVuc2l0eTogMSxcbiAgICAgICAgICBjb2xvcjogeyByOiAxLjAsIGc6IDEuMCwgYjogMS4wIH0sXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm5vTGlnaHRGb3JPYmplY3RzID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIG1vZGVsTm9kZS5vYmozRC5wb3NpdGlvbi5zZXQob2JqLnBvc2l0aW9uLngsIG9iai5wb3NpdGlvbi55LCBvYmoucG9zaXRpb24ueik7XG4gICAgICBtb2RlbE5vZGUub2JqM0Qucm90YXRpb24uc2V0KG9iai5yb3RhdGlvbi54LCBvYmoucm90YXRpb24ueSwgb2JqLnJvdGF0aW9uLnopO1xuICAgICAgbW9kZWxOb2RlLm9iajNELnNjYWxlLnNldChvYmouc2NhbGUueCwgb2JqLnNjYWxlLnksIG9iai5zY2FsZS56KTtcblxuICAgICAgaWYgKGlzQXppbXV0aGFsQ3Jvd24pIHtcbiAgICAgICAgdGhpcy5hemltdXRoYWxDcm93biA9IG1vZGVsTm9kZTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1vZGUgJiYgIWlzTmVzdFRoZXJtb3N0YXQpIHtcbiAgICAgICAgdGhpcy5hdHRhY2hHaXptb0NvbnRyb2xUbzNET2JqZWN0KHNkaywgbW9kZWxOb2RlLCBzY2VuZU9iamVjdCwgbW9kZSwgdHJ1ZSwgdHJ1ZSkuY2F0Y2goKGUpID0+IGNvbnNvbGUubG9nKGUpKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMubGFzdE9iamVjdDNEICYmIHR5cGVvZiB0aGlzLmxhc3RPYmplY3QzRC5pZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgbW9kZWxOb2RlLm9iajNELnV1aWQgPSB0aGlzLmxhc3RPYmplY3QzRC5pZDtcbiAgICAgIH0gZWxzZSBpZiAob2JqLmlkKSB7XG4gICAgICAgIG1vZGVsTm9kZS5vYmozRC51dWlkID0gb2JqLmlkO1xuICAgICAgfVxuICAgICAgdGhpcy5sYXN0T2JqZWN0M0QgPSBtb2RlbE5vZGUub2JqM0Q7XG5cbiAgICAgIHRoaXMuZGljdGlvbm5hcnlPYmplY3RzM0Quc2V0KG1vZGVsTm9kZS5vYmozRC51dWlkLCBtb2RlbE5vZGUpO1xuICAgICAgdGhpcy5kaWN0aW9ubmFyeVNjZW5lT2JqZWN0czNELnNldChtb2RlbE5vZGUub2JqM0QudXVpZCwgc2NlbmVPYmplY3QpO1xuXG4gICAgICBpZiAoaXNBbmltYXRlZFNlY3VyaXR5Q2FtZXJhKSB7XG4gICAgICAgIGNvbnN0IGFuaW1hdG9yID0gbW9kZWxOb2RlLmFkZENvbXBvbmVudCgnbXAuc2VjdXJpdHlDYW1lcmEnLCB7XG4gICAgICAgICAgXCJuZWFyUGxhbmVcIjogMC4xLCBcImZhclBsYW5lXCI6IDEwLCBcImhvcml6b250YWxGT1ZcIjogNTIsIFwiYXNwZWN0XCI6IDEuNzc3Nzc3Nzc3Nzc3Nzc3NyxcbiAgICAgICAgICBcImxvY2FsUG9zaXRpb25cIjogeyBcInhcIjogMC4zLCBcInlcIjogMC4xOCwgXCJ6XCI6IDAgfSxcbiAgICAgICAgICBcImxvY2FsUm90YXRpb25cIjogeyBcInhcIjogLTE1LCBcInlcIjogLTkwLCBcInpcIjogMCB9LFxuICAgICAgICAgIFwiY29sb3JcIjogNjUyODAsIFwicGFuUGVyaW9kXCI6IDUsIFwicGFuQW5nbGVcIjogLTQ1XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnNlY3VyaXR5Q2FtZXJhQW5pbWF0b3IgPSBhbmltYXRvcjtcbiAgICAgICAgaWYgKCFvYmoudmlld0ZydXN0dW0pIHtcbiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHsgYW5pbWF0b3IudG9nZ2xlVmlld0ZydXN0dW0oKTsgfSwgMTAwMCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGlzTmVzdFRoZXJtb3N0YXQpIHtcbiAgICAgICAgY29uc3QgY3YgPSBuZXcgQ2FudmFzUmVuZGVyZXIoKTsgY3Yub25Jbml0KCk7XG4gICAgICAgIGNvbnN0IHBsYW5lID0gbmV3IFBsYW5lUmVuZGVyZXIoKTtcbiAgICAgICAgcGxhbmUub3V0cHV0cyA9IHsgb2JqZWN0Um9vdDogbmV3IE9iamVjdDNEKCksIGNvbGxpZGVyOiBuZXcgT2JqZWN0M0QoKSB9O1xuICAgICAgICBjb25zdCBpbnB1dFRleHR1cmUgPSBjdi5vdXRwdXRzLnRleHR1cmU7XG4gICAgICAgIHBsYW5lLnNldFJvb3RTY2VuZSh0aGlzLnRocmVlSlNTY2VuZSk7XG4gICAgICAgIHBsYW5lLm9uSW5pdChtb2RlbE5vZGUsIGlucHV0VGV4dHVyZSk7XG4gICAgICAgIGNvbnN0IHNjID0gbmV3IE5lc3RUaGVybW9zdGF0KCk7XG4gICAgICAgIHNjLnNldENvbXBvbmVudChjb21wb25lbnQsIHBsYW5lLCBjdik7XG4gICAgICAgIHNjLnNldFJvb3RTY2VuZSh0aGlzLnRocmVlSlNTY2VuZSk7XG4gICAgICAgIHNjLm9uSW5pdChtb2RlbE5vZGUsIHBsYW5lLCBpbnB1dFRleHR1cmUpO1xuICAgICAgICBjdi5zZXRDYW52YXNOZXN0VGhlcm1vc3RhdFBhaW50ZXIoc2MpO1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHsgc2MuaW5wdXRzLmxvYWRpbmdTdGF0ZSA9IFwiTG9hZGVkXCI7IHNjLm9uSW5wdXRzVXBkYXRlZCgpOyB9LCA1MDAwKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzU21hcnRlcnBsYW5Qcm9tb3Rpb25hbFZpZGVvKSB7XG4gICAgICAgIGNvbnN0IHNjID0gbmV3IFR2UGxheWVyKCk7IHNjLnNldENvbXBvbmVudChjb21wb25lbnQpOyBzYy5vbkluaXQobW9kZWxOb2RlKTtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7IHNjLmlucHV0cy5sb2FkaW5nU3RhdGUgPSBcIkxvYWRlZFwiOyBzYy5vbklucHV0c1VwZGF0ZWQoKTsgfSwgNTAwMCk7XG4gICAgICB9XG5cbiAgICAgIHNjZW5lT2JqZWN0LnN0YXJ0KCk7XG4gICAgICByZXNvbHZlKHRoaXMubGFzdE9iamVjdDNEKTtcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGRlbGV0ZU9iamVjdDNEKHV1aWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IG9iaiA9IHRoaXMuZGljdGlvbm5hcnlPYmplY3RzM0QuZ2V0KHV1aWQpO1xuICAgIGlmIChvYmopIG9iai5vYmozRC52aXNpYmxlID0gZmFsc2U7XG4gIH1cblxuICBnZXRPYmplY3QzRE1vZGVsTm9kZUZyb21EaWN0aW9ubmFyeSh1dWlkOiBzdHJpbmcpOiBhbnkge1xuICAgIGxldCBvYmogPSB0aGlzLmRpY3Rpb25uYXJ5T2JqZWN0czNELmdldCh1dWlkKTtcbiAgICBpZiAoIW9iaikgcmV0dXJuIG51bGw7XG4gICAgaWYgKG9iai5vYmozRC51dWlkICE9IHV1aWQpIHtcbiAgICAgIG9iai5vYmozRC51dWlkID0gdXVpZDtcbiAgICB9XG4gICAgcmV0dXJuIG9iajtcbiAgfVxuXG4gIHRvZ2dsZU9iamVjdFZpc2liaWxpdHkob2JqZWN0SWQ6IGFueSkge1xuICAgIGxldCBvYmogPSB0aGlzLmRpY3Rpb25uYXJ5T2JqZWN0czNELmdldChvYmplY3RJZCk7XG4gICAgaWYgKG9iaikgb2JqLm9iajNELnZpc2libGUgPSAhb2JqLm9iajNELnZpc2libGU7XG4gIH1cblxuICBpc09iamVjdFZpc2libGUob2JqZWN0SWQ6IGFueSk6IGJvb2xlYW4ge1xuICAgIGxldCBvYmogPSB0aGlzLmRpY3Rpb25uYXJ5T2JqZWN0czNELmdldChvYmplY3RJZCk7XG4gICAgcmV0dXJuIG9iaiA/IG9iai5vYmozRC52aXNpYmxlIDogZmFsc2U7XG4gIH1cblxuICBhc3luYyBwb2ludENhbWVyYVRvM0RPYmplY3Qoc2RrOiBhbnksIG9iamVjdElkOiBhbnksIGNyZWF0ZVRhZ0NhbGxiYWNrOiAodGFnVHlwZTogUG9pVHlwZSwgb2JqZWN0OiBEYk9iamVjdFR5cGUsIHBvaTogUE9JKSA9PiBQcm9taXNlPGFueT4sIGdvVG9UYWdDYWxsYmFjazogKHNpZDogc3RyaW5nKSA9PiBQcm9taXNlPGFueT4sIGRlbGV0ZUxhc3RUYWdDYWxsYmFjazogKCkgPT4gdm9pZCwgZ2V0VGFnRnJvbUVsZW1lbnRJZDogKGlkOiBzdHJpbmcpID0+IHsgdGFnOiBzdHJpbmcsIHN3ZWVwOiBzdHJpbmcgfSkge1xuICAgIGxldCBvYmogPSB0aGlzLmRpY3Rpb25uYXJ5T2JqZWN0czNELmdldChvYmplY3RJZCk7XG4gICAgY29uc3QgcG9pT2JqZWN0ID0ge1xuICAgICAgY29vcmRpbmF0ZTogSlNPTi5zdHJpbmdpZnkob2JqLm9iajNELnBvc2l0aW9uKSxcbiAgICAgIHR5cGU6IFBvaVR5cGUuT0JKRUNUM0QsXG4gICAgICBlbGVtZW50SUQ6IG9iamVjdElkLFxuICAgIH0gYXMgUE9JO1xuICAgIGNvbnN0IG9iamVjdERiID0geyBpZDogb2JqZWN0SWQgfSBhcyBEYk9iamVjdFR5cGU7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGNyZWF0ZVRhZ0NhbGxiYWNrKFBvaVR5cGUuT0JKRUNUM0QsIG9iamVjdERiLCBwb2lPYmplY3QpO1xuICAgIH0gY2F0Y2ggKGVycjogYW55KSB7IH1cblxuICAgIGxldCByZXN1bHQgPSBnZXRUYWdGcm9tRWxlbWVudElkKG9iamVjdElkKTtcbiAgICBhd2FpdCBnb1RvVGFnQ2FsbGJhY2socmVzdWx0LnRhZyk7XG4gICAgZGVsZXRlTGFzdFRhZ0NhbGxiYWNrKCk7XG4gIH1cblxuICBnZXRTY2VuZU5vZGVGcm9tT2JqZWN0M0RJZCh1dWlkOiBzdHJpbmcpOiBhbnkge1xuICAgIHJldHVybiB0aGlzLmRpY3Rpb25uYXJ5U2NlbmVPYmplY3RzM0QuZ2V0KHV1aWQpO1xuICB9XG5cbiAgYXN5bmMgZGlzcGxheUF6aW11dGFsQ3Jvd24ocG9zZUNhbWVyYTogYW55KSB7XG4gICAgaWYgKHRoaXMuYXppbXV0aGFsQ3Jvd24gJiYgcG9zZUNhbWVyYSkge1xuICAgICAgdGhpcy5hemltdXRoYWxDcm93bi5vYmozRC5wb3NpdGlvbi5zZXQocG9zZUNhbWVyYS5wb3NpdGlvbi54LCBwb3NlQ2FtZXJhLnBvc2l0aW9uLnksIHBvc2VDYW1lcmEucG9zaXRpb24ueilcbiAgICB9XG4gIH1cblxuICBhc3luYyBhdHRhY2hHaXptb0NvbnRyb2xUbzNET2JqZWN0KFxuICAgIHNkazogYW55LFxuICAgIG1vZGVsTm9kZTogYW55LFxuICAgIHNjZW5lT2JqZWN0OiBhbnksXG4gICAgbW9kZTogJ3RyYW5zbGF0ZScgfCAncm90YXRlJyB8ICdzY2FsZScsXG4gICAgdmlzaWJsZTogYm9vbGVhbixcbiAgICBpc05ld09iamVjdDogYm9vbGVhblxuICApOiBQcm9taXNlPGFueT4ge1xuICAgIGxldCBub2RlID0gc2NlbmVPYmplY3QuYWRkTm9kZSgpO1xuICAgIGlmICghbm9kZSkge1xuICAgICAgY29uc3QgW25ld1NjZW5lT2JqZWN0XSA9IGF3YWl0IHNkay5TY2VuZS5jcmVhdGVPYmplY3RzKDEpO1xuICAgICAgbm9kZSA9IG5ld1NjZW5lT2JqZWN0LmFkZE5vZGUoKTtcbiAgICB9XG4gICAgY29uc3QgbXlDb250cm9sID0gbm9kZS5hZGRDb21wb25lbnQoJ21wLnRyYW5zZm9ybUNvbnRyb2xzJyk7XG4gICAgbm9kZS5zdGFydCgpO1xuICAgIG15Q29udHJvbC50cmFuc2Zvcm1Db250cm9scy52aXNpYmxlID0gdmlzaWJsZTtcbiAgICBteUNvbnRyb2wuaW5wdXRzLnNlbGVjdGlvbiA9IG1vZGVsTm9kZTtcbiAgICBteUNvbnRyb2wuaW5wdXRzLm1vZGUgPSBtb2RlO1xuICAgIG1vZGVsTm9kZS5vYmozRC5jb250cm9scyA9IG15Q29udHJvbDtcbiAgICBpZiAoaXNOZXdPYmplY3QpIHtcbiAgICAgIGlmICghdGhpcy5sYXN0T2JqZWN0M0QgfHwgIXRoaXMubGFzdE9iamVjdDNELmNvbnRyb2xzKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgbW9kZWxOb2RlLm9iajNELnV1aWQgPSB0aGlzLmxhc3RPYmplY3QzRC51dWlkIHx8IHRoaXMubGFzdE9iamVjdDNELmlkO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coYGlkIG9iaiBpbiBTY2VuZSB3YXMgbm90IGFzc2lnbmVkIHRvIGlkIGZyb20gREJgKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmxhc3RPYmplY3QzRCA9IG1vZGVsTm9kZS5vYmozRDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5sYXN0T2JqZWN0M0QgPSBtb2RlbE5vZGUub2JqM0Q7XG4gICAgfVxuICAgIHJldHVybiBtb2RlbE5vZGU7XG4gIH1cblxuICByZW1vdmVHaXptb0Zyb21MYXN0T2JqZWN0KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmxhc3RPYmplY3QzRCAmJiB0aGlzLmxhc3RPYmplY3QzRC5jb250cm9scykge1xuICAgICAgdGhpcy5sYXN0T2JqZWN0M0QuY29udHJvbHMudHJhbnNmb3JtQ29udHJvbHMudmlzaWJsZSA9IGZhbHNlO1xuICAgICAgdGhpcy5sYXN0T2JqZWN0M0QuY29udHJvbHMudHJhbnNmb3JtQ29udHJvbHMuZGlzcG9zZSgpO1xuICAgICAgdGhpcy5sYXN0T2JqZWN0M0QuY29udHJvbHMgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHRvZ2dsZVZpZXdGcnVzdHVtKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnNlY3VyaXR5Q2FtZXJhQW5pbWF0b3IpIHtcbiAgICAgIHRoaXMuc2VjdXJpdHlDYW1lcmFBbmltYXRvci50b2dnbGVWaWV3RnJ1c3R1bSgpO1xuICAgIH1cbiAgfVxuXG4gIGNsZWFyKCkge1xuICAgIHRoaXMuZGljdGlvbm5hcnlPYmplY3RzM0QuY2xlYXIoKTtcbiAgICB0aGlzLmRpY3Rpb25uYXJ5U2NlbmVPYmplY3RzM0QuY2xlYXIoKTtcbiAgICB0aGlzLmxhc3RPYmplY3QzRCA9IG51bGw7XG4gICAgdGhpcy5hemltdXRoYWxDcm93biA9IG51bGw7XG4gICAgdGhpcy5zZWN1cml0eUNhbWVyYUFuaW1hdG9yID0gbnVsbDtcbiAgICB0aGlzLm5vTGlnaHRGb3JPYmplY3RzID0gdHJ1ZTtcbiAgfVxufVxuIl19
758
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0dGVycG9ydC1vYmplY3QzZC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXNtYXJ0ZXJwbGFuLWNvcmUvc3JjL2xpYi9zZXJ2aWNlcy9tYXR0ZXJwb3J0LW9iamVjdDNkLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9CLE9BQU8sRUFFTCxPQUFPLEdBU1IsTUFBTSxrQkFBa0IsQ0FBQztBQUMxQixPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLE1BQU0sT0FBTyxDQUFDO0FBQzNELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx5REFBeUQsQ0FBQztBQUN6RixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sd0RBQXdELENBQUM7QUFDdkYsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHlEQUF5RCxDQUFDO0FBQ3pGLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSw2Q0FBNkMsQ0FBQzs7QUFxQnZFLE1BQU0sT0FBTyx5QkFBeUI7SUFDN0Isb0JBQW9CLEdBQXFCLElBQUksR0FBRyxFQUFFLENBQUM7SUFDbkQseUJBQXlCLEdBQXFCLElBQUksR0FBRyxFQUFFLENBQUM7SUFDeEQsWUFBWSxDQUFNLENBQUMsa0JBQWtCO0lBQ3JDLGFBQWEsQ0FBTTtJQUNuQixzQkFBc0IsQ0FBTTtJQUM1QixjQUFjLENBQU07SUFDcEIsWUFBWSxDQUFNO0lBQ2xCLGlCQUFpQixHQUFHLElBQUksQ0FBQztJQUVoQyxnRUFBZ0U7SUFDekQsYUFBYSxHQUFHLEtBQUssQ0FBQztJQUM3QixnRkFBZ0Y7SUFDekUsZUFBZSxHQUFHLENBQUMsQ0FBQztJQUMzQiw4R0FBOEc7SUFDdkcsYUFBYSxHQUFHLEdB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RUFBRSxDQUFDO1FBQ3JDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNoQyxJQUFJLENBQUMsc0JBQXNCLEdBQUcsSUFBSSxDQUFDO1FBQ25DLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxFQUFFLENBQUM7UUFDL0IsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7UUFDekIsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7UUFDM0IsSUFBSSxDQUFDLHNCQUFzQixHQUFHLElBQUksQ0FBQztRQUNuQyxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDO0lBQ2hDLENBQUM7d0dBcnZCVSx5QkFBeUI7NEdBQXpCLHlCQUF5QixjQUZ4QixNQUFNOzs0RkFFUCx5QkFBeUI7a0JBSHJDLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtcbiAgSU9iamVjdDNELFxuICBQb2lUeXBlLFxuICBQT0ksXG4gIERiT2JqZWN0VHlwZSxcbiAgR2l6bW9Nb2RlLFxuICBHaXptb1NuYXAsXG4gIE9iamVjdDNEQm91bmRpbmdCb3gsXG4gIE9iamVjdDNEVHJhbnNmb3JtLFxuICBPYmplY3QzRFRyYW5zZm9ybUNoYW5nZSxcbiAgUG9pbnQzRCxcbn0gZnJvbSAnLi4vdHlwZXMuc2VydmljZSc7XG5pbXBvcnQgeyBCb3gzLCBNYXRoVXRpbHMsIE9iamVjdDNELCBWZWN0b3IzIH0gZnJvbSAndGhyZWUnO1xuaW1wb3J0IHsgTmVzdFRoZXJtb3N0YXQgfSBmcm9tICcuLi9tYXR0ZXJwb3J0LWV4dGVuc2lvbnMvbmVzdC10aGVybW9zdGF0L05lc3RUaGVybW9zdGF0JztcbmltcG9ydCB7IFBsYW5lUmVuZGVyZXIgfSBmcm9tICcuLi9tYXR0ZXJwb3J0LWV4dGVuc2lvbnMvbmVzdC10aGVybW9zdGF0L1BsYW5lUmVuZGVyZXInO1xuaW1wb3J0IHsgQ2FudmFzUmVuZGVyZXIgfSBmcm9tIFwiLi4vbWF0dGVycG9ydC1leHRlbnNpb25zL25lc3QtdGhlcm1vc3RhdC9DYW52YXNSZW5kZXJlclwiO1xuaW1wb3J0IHsgVHZQbGF5ZXIgfSBmcm9tIFwiLi4vbWF0dGVycG9ydC1leHRlbnNpb25zL3R2LXBsYXllci9UdlBsYXllclwiO1xuXG4vKiogR2l6bW8gKG1wLnRyYW5zZm9ybUNvbnRyb2xzKSBib29ra2VlcGluZyBmb3Igb25lIG9iamVjdCAqL1xuaW50ZXJmYWNlIEdpem1vRW50cnkge1xuICB1dWlkOiBzdHJpbmc7XG4gIG5vZGU6IGFueTtcbiAgLyoqIGRlZGljYXRlZCBzY2VuZSBvYmplY3Qgd2hlbiB0aGUgb2JqZWN0J3Mgb3duIG9uZSB3YXMgYWxyZWFkeSBzdGFydGVkICovXG4gIHNjZW5lT2JqZWN0PzogYW55O1xuICBjb21wb25lbnQ6IGFueTtcbiAgbW9kZTogR2l6bW9Nb2RlO1xuICAvKiogcG9zaXRpb24gb2YgdGhlIG9iamVjdCB3aGVuIHRoZSBjdXJyZW50IGRyYWcgc3RhcnRlZCAqL1xuICBkcmFnU3RhcnQ6IFZlY3RvcjMgfCBudWxsO1xuICAvKiogcG9zaXRpb24gb2YgdGhlIG9iamVjdCBhdCB0aGUgbGFzdCBjaGFuZ2UgKGZhbGxiYWNrIHdoZW4gZHJhZyBzdGFydCB3YXMgbWlzc2VkKSAqL1xuICBsYXN0UG9zaXRpb246IFZlY3RvcjM7XG4gIG9uRHJhZ2dpbmdDaGFuZ2VkOiAoZXZlbnQ6IGFueSkgPT4gdm9pZDtcbiAgb25PYmplY3RDaGFuZ2U6ICgpID0+IHZvaWQ7XG59XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBNYXR0ZXJwb3J0T2JqZWN0M0RTZXJ2aWNlIHtcbiAgcHVibGljIGRpY3Rpb25uYXJ5T2JqZWN0czNEOiBNYXA8c3RyaW5nLCBhbnk+ID0gbmV3IE1hcCgpO1xuICBwdWJsaWMgZGljdGlvbm5hcnlTY2VuZU9iamVjdHMzRDogTWFwPHN0cmluZywgYW55PiA9IG5ldyBNYXAoKTtcbiAgcHVibGljIGxhc3RPYmplY3QzRDogYW55OyAvLyBUaHJlZSBKUyBvYmplY3RcbiAgcHVibGljIG9iamVjdENvbnRyb2w6IGFueTtcbiAgcHVibGljIHNlY3VyaXR5Q2FtZXJhQW5pbWF0b3I6IGFueTtcbiAgcHVibGljIGF6aW11dGhhbENyb3duOiBhbnk7XG4gIHB1YmxpYyB0aHJlZUpTU2NlbmU6IGFueTtcbiAgcHVibGljIG5vTGlnaHRGb3JPYmplY3RzID0gdHJ1ZTtcblxuICAvKiogTWF4IHRpbWUgKG1zKSB0byB3YWl0IGZvciBhIG1vZGVsIHRvIGJlIGxvYWRlZCBieSB0aGUgU0RLICovXG4gIHB1YmxpYyBsb2FkVGltZW91dE1zID0gMTUwMDA7XG4gIC8qKiBNYXggZGlzdGFuY2UgKG0pIGFuIG9iamVjdCBjYW4gdHJhdmVsIGZyb20gd2hlcmUgYSB0cmFuc2xhdGUgZHJhZyBzdGFydGVkICovXG4gIHB1YmxpYyBtYXhEcmFnRGlzdGFuY2UgPSAyO1xuICAvKiogTWF4IHZlcnRpY2FsIHRyYXZlbCAobSwgdXAgYW5kIGRvd24pIGR1cmluZyBhIHRyYW5zbGF0ZSBkcmFnLCBzbyBhbiBvYmplY3QgY2Fubm90IGp1bXAgdG8gYW5vdGhlciBmbG9vciAqL1xuICBwdWJsaWMgbWF4RHJhZ0hlaWdodCA9IDEuNTtcblxuICAvKiogRW1pdHMgb24gZXZlcnkgZ2l6bW8gY2hhbmdlIGFuZCBvbiBzZXRPYmplY3QzRFRyYW5zZm9ybSAqL1xuICBwdWJsaWMgcmVhZG9ubHkgb2JqZWN0M0RUcmFuc2Zvcm1DaGFuZ2VkJCA9IG5ldyBTdWJqZWN0PE9iamVjdDNEVHJhbnNmb3JtQ2hhbmdlPigpO1xuXG4gIC8qKiBTZWN1cml0eSBjYW1lcmEgYW5pbWF0b3JzIGJ5IG9iamVjdCB1dWlkIChgc2VjdXJpdHlDYW1lcmFBbmltYXRvcmAgc3RheXMgdGhlIGxhc3QgbG9hZGVkIG9uZSkgKi9cbiAgcHVibGljIHNlY3VyaXR5Q2FtZXJhQW5pbWF0b3JzOiBNYXA8c3RyaW5nLCBhbnk+ID0gbmV3IE1hcCgpO1xuICBwcml2YXRlIHZpZXdGcnVzdHVtVmlzaWJsZTogTWFwPHN0cmluZywgYm9vbGVhbj4gPSBuZXcgTWFwKCk7XG4gIHByaXZhdGUgbGFzdFNlY3VyaXR5Q2FtZXJhVXVpZDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqIExvYWRlciBjb21wb25lbnQgb2YgZWFjaCBtb2RlbCAob3V0cHV0cy5vYmplY3RSb290IGlzIHNldCBvbmNlIGxvYWRlZCkgKi9cbiAgcHJpdmF0ZSBsb2FkZXJDb21wb25lbnRzOiBNYXA8c3RyaW5nLCBhbnk+ID0gbmV3IE1hcCgpO1xuXG4gIHByaXZhdGUgZ2l6bW9zOiBNYXA8c3RyaW5nLCBHaXptb0VudHJ5PiA9IG5ldyBNYXAoKTtcbiAgcHJpdmF0ZSBhY3RpdmVHaXptb1V1aWQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGdpem1vU25hcDogR2l6bW9TbmFwIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqIFN3ZWVwcyBkaXNhYmxlZCBieSBzZXROYXZpZ2F0aW9uTG9ja2VkKHRydWUpLCByZS1lbmFibGVkIG9uIHVubG9jayAqL1xuICBwcml2YXRlIHN3ZWVwc0Rpc2FibGVkQnlMb2NrOiBzdHJpbmdbXSA9IFtdO1xuICAvKiogU3dlZXBzIHJlLWVuYWJsZWQgYnkgdGhlIGxhc3QgdW5sb2NrICh0aGUgU0RLIG1heSBzdGlsbCByZXBvcnQgdGhlbSBkaXNhYmxlZCBmb3IgYSBtb21lbnQpICovXG4gIHByaXZhdGUgc3dlZXBzRW5hYmxlZEJ5VW5sb2NrOiBzdHJpbmdbXSA9IFtdO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgdG1wQm94ID0gbmV3IEJveDMoKTtcblxuICBjb25zdHJ1Y3RvcigpIHsgfVxuXG4gIGFzeW5jIGluaXQzRE9iamVjdFZpZXdlcihzZGs6IGFueSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IFtzY2VuZU9iamVjdF0gPSBhd2FpdCBzZGsuU2NlbmUuY3JlYXRlT2JqZWN0cygxKTtcbiAgICBjb25zdCBub2RlID0gc2NlbmVPYmplY3QuYWRkTm9kZSgpO1xuICAgIG5vZGUuc3RhcnQoKTtcbiAgICB0aGlzLnRocmVlSlNTY2VuZSA9IG5vZGUub2JqM0QucGFyZW50O1xuXG4gICAgY29uc3Qgbm9kZUNvbnRyb2wgPSBzY2VuZU9iamVjdC5hZGROb2RlKCk7XG4gICAgdGhpcy5vYmplY3RDb250cm9sID0gbm9kZUNvbnRyb2wuYWRkQ29tcG9uZW50KCdtcC50cmFuc2Zvcm1Db250cm9scycpO1xuICAgIG5vZGVDb250cm9sLnN0YXJ0KCk7XG4gIH1cblxuICAvKiogU0RLIGxvYWRlciBjb21wb25lbnQgbmFtZSBmb3IgYSBtb2RlbCBmb3JtYXQsIG51bGwgd2hlbiB0aGUgZm9ybWF0IGlzIG5vdCBzdXBwb3J0ZWQgKi9cbiAgcHJpdmF0ZSBnZXRMb2FkZXJDb21wb25lbnROYW1lKGZvcm1hdDogc3RyaW5nKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgc3dpdGNoICgoZm9ybWF0IHx8ICcnKS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICBjYXNlICcub2JqJzogY2FzZSAnb2JqJzogcmV0dXJuICdtcC5vYmpMb2FkZXInO1xuICAgICAgY2FzZSAnLmZieCc6IGNhc2UgJ2ZieCc6IHJldHVybiAnbXAuZmJ4TG9hZGVyJztcbiAgICAgIGNhc2UgJy5nbHRmJzogY2FzZSAnZ2x0Zic6IGNhc2UgJy5nbGInOiBjYXNlICdnbGInOiByZXR1cm4gJ21wLmdsdGZMb2FkZXInO1xuICAgICAgY2FzZSAnLmRhZSc6IGNhc2UgJ2RhZSc6IHJldHVybiAnbXAuZGFlTG9hZGVyJztcbiAgICAgIGRlZmF1bHQ6IHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBSZXNvbHZlcyBvbmNlIHRoZSBsb2FkZXIgY29tcG9uZW50IGhhcyBwcm9kdWNlZCBpdHMgb2JqZWN0Um9vdCwgcmVqZWN0cyBhZnRlciBgdGltZW91dE1zYCAqL1xuICBwcml2YXRlIHdhaXRGb3JNb2RlbExvYWRlZChjb21wb25lbnQ6IGFueSwgdGltZW91dE1zOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgY29uc3QgaXNMb2FkZWQgPSAoKSA9PiAhIWNvbXBvbmVudD8ub3V0cHV0cz8ub2JqZWN0Um9vdDtcbiAgICAgIGlmIChpc0xvYWRlZCgpKSB7XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgcG9sbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgaWYgKGlzTG9hZGVkKCkpIHtcbiAgICAgICAgICBjbGVhckludGVydmFsKHBvbGwpO1xuICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgICB9LCA1MCk7XG4gICAgICBjb25zdCB0aW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBjbGVhckludGVydmFsKHBvbGwpO1xuICAgICAgICByZWplY3QobmV3IEVycm9yKGAzRCBtb2RlbCBub3QgbG9hZGVkIGFmdGVyICR7dGltZW91dE1zfSBtc2ApKTtcbiAgICAgIH0sIHRpbWVvdXRNcyk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIDNEIG1vZGVsIHRvIHRoZSBzY2VuZS5cbiAgICogVGhlIHByb21pc2UgcmVzb2x2ZXMgd2l0aCB0aGUgdGhyZWUuanMgb2JqZWN0IG9uY2UgdGhlIG1vZGVsIGlzIGFjdHVhbGx5IGxvYWRlZCwgYW5kIHJlamVjdHNcbiAgICogKGFmdGVyIGNsZWFuaW5nIHRoZSBzY2VuZSkgd2hlbiB0aGUgZm9ybWF0IGlzIHVua25vd24gb3IgdGhlIGxvYWQgdGltZXMgb3V0LlxuICAgKiBUaGUgcG9zaXRpb24gLyByb3RhdGlvbiAvIHNjYWxlIG9mIGBvYmpgIGFyZSBhcHBsaWVkIHRvIHRoZSBtb2RlbCBvcmlnaW4sIGFzIHN0b3JlZCBpbiBEQi5cbiAgICovXG4gIGFzeW5jIGFkZDNET2JqZWN0KFxuICAgIHNkazogYW55LFxuICAgIG9iajogSU9iamVjdDNELFxuICAgIG1vZGU/OiBHaXptb01vZGVcbiAgKTogUHJvbWlzZTxhbnk+IHtcbiAgICBjb25zdCBsb2FkZXJOYW1lID0gdGhpcy5nZXRMb2FkZXJDb21wb25lbnROYW1lKG9iai5mb3JtYXQpO1xuICAgIGlmICghbG9hZGVyTmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAzRCBvYmplY3QgZm9ybWF0IG5vdCBzdXBwb3J0ZWQ6ICR7b2JqLmZvcm1hdH1gKTtcbiAgICB9XG5cbiAgICBjb25zdCBbc2NlbmVPYmplY3RdID0gYXdhaXQgc2RrLlNjZW5lLmNyZWF0ZU9iamVjdHMoMSk7XG5cbiAgICBjb25zdCBpc0FuaW1hdGVkU2VjdXJpdHlDYW1lcmEgPSAoIW9iai51cmwgJiYgb2JqLm9iamVjdCA9PT0gJ3NlY3VyaXR5X2NhbWVyYScpO1xuICAgIGNvbnN0IGlzTmVzdFRoZXJtb3N0YXQgPSAoIW9iai51cmwgJiYgb2JqLm9iamVjdCA9PT0gJ25lc3RfdGhlcm1vc3RhdCcpO1xuICAgIGNvbnN0IGlzU21hcnRlcnBsYW5Qcm9tb3Rpb25hbFZpZGVvID0gKCFvYmoudXJsICYmIG9iai5vYmplY3QgPT09ICd2aWRlbycpO1xuICAgIGNvbnN0IGlzQXppbXV0aGFsQ3Jvd24gPSAoIW9iai51cmwgJiYgb2JqLm9iamVjdCA9PT0gJ2F6aW11dGgnKTtcblxuICAgIGNvbnN0IG1vZGVsTm9kZSA9IHNjZW5lT2JqZWN0LmFkZE5vZGUoKTtcbiAgICBjb25zdCBpbml0aWFsID0ge1xuICAgICAgdXJsOiBvYmoudXJsIHx8IGAvYXNzZXRzLzNEb2JqZWN0cy9vYmplY3RzLyR7b2JqLm9iamVjdH0ke29iai5mb3JtYXQuaW5kZXhPZignLicpID09PSAtMSA/ICcuJyArIG9iai5mb3JtYXQgOiBvYmouZm9ybWF0fWAsXG4gICAgICBsb2NhbFJvdGF0aW9uOiB7ICd4JzogMCwgJ3knOiAwLCAneic6IDAgfSxcbiAgICAgIGxvY2FsUG9zaXRpb246IHsgJ3gnOiAwLCAneSc6IDAsICd6JzogMCB9LFxuICAgICAgdmlzaWJsZTogdHJ1ZSxcbiAgICAgIGNvbGxpZGVyRW5hYmxlZDogdHJ1ZVxuICAgIH07XG4gICAgY29uc3QgY29tcG9uZW50ID0gbW9kZWxOb2RlLmFkZENvbXBvbmVudChsb2FkZXJOYW1lLCBpbml0aWFsKTtcblxuICAgIGlmICh0aGlzLm5vTGlnaHRGb3JPYmplY3RzKSB7XG4gICAgICBjb25zdCBsaWdodHNOb2RlID0gc2NlbmVPYmplY3QuYWRkTm9kZSgpO1xuICAgICAgbGlnaHRzTm9kZS5hZGRDb21wb25lbnQoJ21wLmFtYmllbnRMaWdodCcsIHtcbiAgICAgICAgaW50ZW5zaXR5OiAxLFxuICAgICAgICBjb2xvcjogeyByOiAxLjAsIGc6IDEuMCwgYjogMS4wIH0sXG4gICAgICB9KTtcbiAgICAgIHRoaXMubm9MaWdodEZvck9iamVjdHMgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBtb2RlbE5vZGUub2JqM0QucG9zaXRpb24uc2V0KG9iai5wb3NpdGlvbi54LCBvYmoucG9zaXRpb24ueSwgb2JqLnBvc2l0aW9uLnopO1xuICAgIG1vZGVsTm9kZS5vYmozRC5yb3RhdGlvbi5zZXQob2JqLnJvdGF0aW9uLngsIG9iai5yb3RhdGlvbi55LCBvYmoucm90YXRpb24ueik7XG4gICAgbW9kZWxOb2RlLm9iajNELnNjYWxlLnNldChvYmouc2NhbGUueCwgb2JqLnNjYWxlLnksIG9iai5zY2FsZS56KTtcblxuICAgIC8vIFRoZSBEQiBpZCByZXBsYWNlcyB0aGUgdGhyZWUuanMgdXVpZC4gVGhlIGlkIHByZS1zZXQgdGhyb3VnaCBzZXRMYXN0T2JqZWN0M0QgaXMgb25seSBhIGZhbGxiYWNrXG4gICAgLy8gZm9yIGNhbGxlcnMgd2l0aG91dCBpZDogdGFraW5nIGl0IGZpcnN0IGdhdmUgdGhlIHNhbWUgaWQgdG8gZXZlcnkgb2JqZWN0IGxvYWRlZCBtZWFud2hpbGVcbiAgICAvLyAoc2V2ZXJhbCBjYW1lcmFzIG9yIGN1YmVzIGxvYWRpbmcgd2hpbGUgYW4gYWRkIGlzIHN0YXJ0aW5nKSwgd2hpY2ggdGhlbiBvdmVyd3JvdGUgZWFjaCBvdGhlci5cbiAgICBpZiAob2JqLmlkKSB7XG4gICAgICBtb2RlbE5vZGUub2JqM0QudXVpZCA9IG9iai5pZDtcbiAgICB9IGVsc2UgaWYgKHRoaXMubGFzdE9iamVjdDNEICYmIHR5cGVvZiB0aGlzLmxhc3RPYmplY3QzRC5pZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIG1vZGVsTm9kZS5vYmozRC51dWlkID0gdGhpcy5sYXN0T2JqZWN0M0QuaWQ7XG4gICAgfVxuICAgIGNvbnN0IHV1aWQ6IHN0cmluZyA9IG1vZGVsTm9kZS5vYmozRC51dWlkO1xuICAgIHRoaXMubGFzdE9iamVjdDNEID0gbW9kZWxOb2RlLm9iajNEO1xuXG4gICAgdGhpcy5kaWN0aW9ubmFyeU9iamVjdHMzRC5zZXQodXVpZCwgbW9kZWxOb2RlKTtcbiAgICB0aGlzLmRpY3Rpb25uYXJ5U2NlbmVPYmplY3RzM0Quc2V0KHV1aWQsIHNjZW5lT2JqZWN0KTtcbiAgICB0aGlzLmxvYWRlckNvbXBvbmVudHMuc2V0KHV1aWQsIGNvbXBvbmVudCk7XG5cbiAgICBpZiAoaXNBemltdXRoYWxDcm93bikge1xuICAgICAgdGhpcy5hemltdXRoYWxDcm93biA9IG1vZGVsTm9kZTtcbiAgICB9XG5cbiAgICBpZiAobW9kZSAmJiAhaXNOZXN0VGhlcm1vc3RhdCkge1xuICAgICAgdGhpcy5hdHRhY2hHaXptbyh1dWlkLCBtb2RlKS5jYXRjaCgoKSA9PiB7IC8qIG5vIGdpem1vLCB0aGUgb2JqZWN0IGlzIHN0aWxsIGxvYWRlZCAqLyB9KTtcbiAgICB9XG5cbiAgICBsZXQgYW5pbWF0b3I6IGFueSA9IG51bGw7XG4gICAgaWYgKGlzQW5pbWF0ZWRTZWN1cml0eUNhbWVyYSkge1xuICAgICAgYW5pbWF0b3IgPSBtb2RlbE5vZGUuYWRkQ29tcG9uZW50KCdtcC5zZWN1cml0eUNhbWVyYScsIHtcbiAgICAgICAgJ25lYXJQbGFuZSc6IDAuMSwgJ2ZhclBsYW5lJzogMTAsICdob3Jpem9udGFsRk9WJzogNTIsICdhc3BlY3QnOiAxLjc3Nzc3Nzc3Nzc3Nzc3NzcsXG4gICAgICAgICdsb2NhbFBvc2l0aW9uJzogeyAneCc6IDAuMywgJ3knOiAwLjE4LCAneic6IDAgfSxcbiAgICAgICAgJ2xvY2FsUm90YXRpb24nOiB7ICd4JzogLTE1LCAneSc6IC05MCwgJ3onOiAwIH0sXG4gICAgICAgICdjb2xvcic6IDY1MjgwLCAncGFuUGVyaW9kJzogNSwgJ3BhbkFuZ2xlJzogLTQ1XG4gICAgICB9KTtcbiAgICAgIHRoaXMuc2VjdXJpdHlDYW1lcmFBbmltYXRvciA9IGFuaW1hdG9yO1xuICAgICAgdGhpcy5zZWN1cml0eUNhbWVyYUFuaW1hdG9ycy5zZXQodXVpZCwgYW5pbWF0b3IpO1xuICAgICAgdGhpcy52aWV3RnJ1c3R1bVZpc2libGUuc2V0KHV1aWQsIHRydWUpOyAvLyB0aGUgY29tcG9uZW50IHNob3dzIGl0cyBmcnVzdHVtIGJ5IGRlZmF1bHRcbiAgICAgIHRoaXMubGFzdFNlY3VyaXR5Q2FtZXJhVXVpZCA9IHV1aWQ7XG4gICAgfVxuXG4gICAgaWYgKGlzTmVzdFRoZXJtb3N0YXQpIHtcbiAgICAgIGNvbnN0IGN2ID0gbmV3IENhbnZhc1JlbmRlcmVyKCk7IGN2Lm9uSW5pdCgpO1xuICAgICAgY29uc3QgcGxhbmUgPSBuZXcgUGxhbmVSZW5kZXJlcigpO1xuICAgICAgcGxhbmUub3V0cHV0cyA9IHsgb2JqZWN0Um9vdDogbmV3IE9iamVjdDNEKCksIGNvbGxpZGVyOiBuZXcgT2JqZWN0M0QoKSB9O1xuICAgICAgY29uc3QgaW5wdXRUZXh0dXJlID0gY3Yub3V0cHV0cy50ZXh0dXJlO1xuICAgICAgcGxhbmUuc2V0Um9vdFNjZW5lKHRoaXMudGhyZWVKU1NjZW5lKTtcbiAgICAgIHBsYW5lLm9uSW5pdChtb2RlbE5vZGUsIGlucHV0VGV4dHVyZSk7XG4gICAgICBjb25zdCBzYyA9IG5ldyBOZXN0VGhlcm1vc3RhdCgpO1xuICAgICAgc2Muc2V0Q29tcG9uZW50KGNvbXBvbmVudCwgcGxhbmUsIGN2KTtcbiAgICAgIHNjLnNldFJvb3RTY2VuZSh0aGlzLnRocmVlSlNTY2VuZSk7XG4gICAgICBzYy5vbkluaXQobW9kZWxOb2RlLCBwbGFuZSwgaW5wdXRUZXh0dXJlKTtcbiAgICAgIGN2LnNldENhbnZhc05lc3RUaGVybW9zdGF0UGFpbnRlcihzYyk7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHsgc2MuaW5wdXRzLmxvYWRpbmdTdGF0ZSA9ICdMb2FkZWQnOyBzYy5vbklucHV0c1VwZGF0ZWQoKTsgfSwgNTAwMCk7XG4gICAgfVxuXG4gICAgaWYgKGlzU21hcnRlcnBsYW5Qcm9tb3Rpb25hbFZpZGVvKSB7XG4gICAgICBjb25zdCBzYyA9IG5ldyBUdlBsYXllcigpOyBzYy5zZXRDb21wb25lbnQoY29tcG9uZW50KTsgc2Mub25Jbml0KG1vZGVsTm9kZSk7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHsgc2MuaW5wdXRzLmxvYWRpbmdTdGF0ZSA9ICdMb2FkZWQnOyBzYy5vbklucHV0c1VwZGF0ZWQoKTsgfSwgNTAwMCk7XG4gICAgfVxuXG4gICAgc2NlbmVPYmplY3Quc3RhcnQoKTtcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLndhaXRGb3JNb2RlbExvYWRlZChjb21wb25lbnQsIHRoaXMubG9hZFRpbWVvdXRNcyk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgYXdhaXQgdGhpcy5kZWxldGVPYmplY3QzRCh1dWlkKTtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuXG4gICAgaWYgKGFuaW1hdG9yICYmICFvYmoudmlld0ZydXN0dW0pIHtcbiAgICAgIC8vIFRoZSBjYW1lcmEgY29tcG9uZW50IHN0YXJ0cyB3aXRoIHRoZSBtb2RlbCBub2RlLCBzbyBpdCBpcyByZWFkeSBub3cgdGhhdCB0aGUgbW9kZWwgaXMgbG9hZGVkXG4gICAgICB0aGlzLmFwcGx5Vmlld0ZydXN0dW0odXVpZCwgZmFsc2UpO1xuICAgIH1cblxuICAgIHJldHVybiBtb2RlbE5vZGUub2JqM0Q7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBhIDNEIG9iamVjdCBmb3IgZ29vZDogZGV0YWNoZXMgaXRzIGdpem1vLCBzdG9wcyBpdHMgc2NlbmUgb2JqZWN0IGFuZCBmb3JnZXRzIGl0LlxuICAgKi9cbiAgYXN5bmMgZGVsZXRlT2JqZWN0M0QodXVpZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5kZXRhY2hHaXptbyh1dWlkKTtcblxuICAgIGNvbnN0IG5vZGUgPSB0aGlzLmRpY3Rpb25uYXJ5T2JqZWN0czNELmdldCh1dWlkKTtcbiAgICBjb25zdCBzY2VuZU9iamVjdCA9IHRoaXMuZGljdGlvbm5hcnlTY2VuZU9iamVjdHMzRC5nZXQodXVpZCk7XG4gICAgaWYgKG5vZGUpIHtcbiAgICAgIHRyeSB7IG5vZGUub2JqM0QudmlzaWJsZSA9IGZhbHNlOyB9IGNhdGNoIHsgLyogYWxyZWFkeSBkZXN0cm95ZWQgKi8gfVxuICAgIH1cbiAgICBpZiAoc2NlbmVPYmplY3QgJiYgdHlwZW9mIHNjZW5lT2JqZWN0LnN0b3AgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRyeSB7IHNjZW5lT2JqZWN0LnN0b3AoKTsgfSBjYXRjaCB7IC8qIGFscmVhZHkgc3RvcHBlZCAqLyB9XG4gICAgfVxuXG4gICAgdGhpcy5kaWN0aW9ubmFyeU9iamVjdHMzRC5kZWxldGUodXVpZCk7XG4gICAgdGhpcy5kaWN0aW9ubmFyeVNjZW5lT2JqZWN0czNELmRlbGV0ZSh1dWlkKTtcbiAgICB0aGlzLmxvYWRlckNvbXBvbmVudHMuZGVsZXRlKHV1aWQpO1xuXG4gICAgaWYgKHRoaXMubGFzdE9iamVjdDNEICYmICh0aGlzLmxhc3RPYmplY3QzRC51dWlkID09PSB1dWlkIHx8IHRoaXMubGFzdE9iamVjdDNELmlkID09PSB1dWlkKSkge1xuICAgICAgdGhpcy5sYXN0T2JqZWN0M0QgPSBudWxsO1xuICAgIH1cbiAgICBpZiAobm9kZSAmJiB0aGlzLmF6aW11dGhhbENyb3duID09PSBub2RlKSB7XG4gICAgICB0aGlzLmF6aW11dGhhbENyb3duID0gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgYW5pbWF0b3IgPSB0aGlzLnNlY3VyaXR5Q2FtZXJhQW5pbWF0b3JzLmdldCh1dWlkKTtcbiAgICBpZiAoYW5pbWF0b3IgJiYgdGhpcy5zZWN1cml0eUNhbWVyYUFuaW1hdG9yID09PSBhbmltYXRvcikge1xuICAgICAgdGhpcy5zZWN1cml0eUNhbWVyYUFuaW1hdG9yID0gbnVsbDtcbiAgICB9XG4gICAgdGhpcy5zZWN1cml0eUNhbWVyYUFuaW1hdG9ycy5kZWxldGUodXVpZCk7XG4gICAgdGhpcy52aWV3RnJ1c3R1bVZpc2libGUuZGVsZXRlKHV1aWQpO1xuICAgIGlmICh0aGlzLmxhc3RTZWN1cml0eUNhbWVyYVV1aWQgPT09IHV1aWQpIHtcbiAgICAgIHRoaXMubGFzdFNlY3VyaXR5Q2FtZXJhVXVpZCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgZ2V0T2JqZWN0M0RNb2RlbE5vZGVGcm9tRGljdGlvbm5hcnkodXVpZDogc3RyaW5nKTogYW55IHtcbiAgICBsZXQgb2JqID0gdGhpcy5kaWN0aW9ubmFyeU9iamVjdHMzRC5nZXQodXVpZCk7XG4gICAgaWYgKCFvYmopIHJldHVybiBudWxsO1xuICAgIGlmIChvYmoub2JqM0QudXVpZCAhPSB1dWlkKSB7XG4gICAgICBvYmoub2JqM0QudXVpZCA9IHV1aWQ7XG4gICAgfVxuICAgIHJldHVybiBvYmo7XG4gIH1cblxuICB0b2dnbGVPYmplY3RWaXNpYmlsaXR5KG9iamVjdElkOiBhbnkpIHtcbiAgICBsZXQgb2JqID0gdGhpcy5kaWN0aW9ubmFyeU9iamVjdHMzRC5nZXQob2JqZWN0SWQpO1xuICAgIGlmIChvYmopIG9iai5vYmozRC52aXNpYmxlID0gIW9iai5vYmozRC52aXNpYmxlO1xuICB9XG5cbiAgaXNPYmplY3RWaXNpYmxlKG9iamVjdElkOiBhbnkpOiBib29sZWFuIHtcbiAgICBsZXQgb2JqID0gdGhpcy5kaWN0aW9ubmFyeU9iamVjdHMzRC5nZXQob2JqZWN0SWQpO1xuICAgIHJldHVybiBvYmogPyBvYmoub2JqM0QudmlzaWJsZSA6IGZhbHNlO1xuICB9XG5cbiAgLyoqIFNob3dzIC8gaGlkZXMgYSBtb2RlbCAodXNlZCBieSB0aGUgcGxhY2VtZW50IHByZXZpZXcpICovXG4gIHNldE9iamVjdDNEVmlzaWJsZSh1dWlkOiBzdHJpbmcsIHZpc2libGU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBjb25zdCBub2RlID0gdGhpcy5kaWN0aW9ubmFyeU9iamVjdHMzRC5nZXQodXVpZCk7XG4gICAgaWYgKG5vZGUpIG5vZGUub2JqM0QudmlzaWJsZSA9IHZpc2libGU7XG4gIH1cblxuICAvKiogRW5hYmxlcyAvIGRpc2FibGVzIHRoZSBwb2ludGVyIGNvbGxpZGVyIG9mIGEgbW9kZWwgKGRpc2FibGVkIHdoaWxlIGl0IGZvbGxvd3MgdGhlIGN1cnNvcikgKi9cbiAgc2V0T2JqZWN0M0RDb2xsaWRlckVuYWJsZWQodXVpZDogc3RyaW5nLCBlbmFibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgY29uc3QgY29tcG9uZW50ID0gdGhpcy5sb2FkZXJDb21wb25lbnRzLmdldCh1dWlkKTtcbiAgICBpZiAoY29tcG9uZW50Py5pbnB1dHMpIHtcbiAgICAgIGNvbXBvbmVudC5pbnB1dHMuY29sbGlkZXJFbmFibGVkID0gZW5hYmxlZDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTW92ZXMgdGhlIGNhbWVyYSBuZXh0IHRvIGEgM0Qgb2JqZWN0IGJ5IGNyZWF0aW5nIGEgdGVtcG9yYXJ5IHRhZyBvbiB0aGUgb2JqZWN0IGNlbnRyZS5cbiAgICogQHJldHVybnMgZmFsc2Ugd2hlbiB0aGUgb2JqZWN0IGlzIHVua25vd24gb3Igbm8gdGFnIGNvdWxkIGJlIHJlYWNoZWRcbiAgICovXG4gIGFzeW5jIHBvaW50Q2FtZXJhVG8zRE9iamVjdChzZGs6IGFueSwgb2JqZWN0SWQ6IGFueSwgY3JlYXRlVGFnQ2FsbGJhY2s6ICh0YWdUeXBlOiBQb2lUeXBlLCBvYmplY3Q6IERiT2JqZWN0VHlwZSwgcG9pOiBQT0kpID0+IFByb21pc2U8YW55PiwgZ29Ub1RhZ0NhbGxiYWNrOiAoc2lkOiBzdHJpbmcpID0+IFByb21pc2U8YW55PiwgZGVsZXRlTGFzdFRhZ0NhbGxiYWNrOiAoKSA9PiB2b2lkLCBnZXRUYWdGcm9tRWxlbWVudElkOiAoaWQ6IHN0cmluZykgPT4geyB0YWc6IHN0cmluZywgc3dlZXA6IHN0cmluZyB9KTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3Qgb2JqID0gdGhpcy5kaWN0aW9ubmFyeU9iamVjdHMzRC5nZXQob2JqZWN0SWQpO1xuICAgIGlmICghb2JqKSByZXR1cm4gZmFsc2U7XG5cbiAgICAvLyBUYWcgb24gdGhlIGJvdW5kaW5nIGJveCBjZW50cmUgKHRoZSBtb2RlbCBvcmlnaW4gaXMgYSBjb3JuZXIgZm9yIG1vc3QgbW9kZWxzKVxuICAgIGNvbnN0IGJveCA9IHRoaXMuZ2V0T2JqZWN0M0RCb3VuZGluZ0JveChvYmplY3RJZCk7XG4gICAgY29uc3QgYW5jaG9yID0gYm94ID8gYm94LmNlbnRlciA6IHRoaXMudG9Qb2ludChvYmoub2JqM0QucG9zaXRpb24pO1xuICAgIGNvbnN0IHBvaU9iamVjdCA9IHtcbiAgICAgIGNvb3JkaW5hdGU6IEpTT04uc3RyaW5naWZ5KGFuY2hvciksXG4gICAgICB0eXBlOiBQb2lUeXBlLk9CSkVDVDNELFxuICAgICAgZWxlbWVudElEOiBvYmplY3RJZCxcbiAgICB9IGFzIFBPSTtcbiAgICBjb25zdCBvYmplY3REYiA9IHsgaWQ6IG9iamVjdElkIH0gYXMgRGJPYmplY3RUeXBlO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBjcmVhdGVUYWdDYWxsYmFjayhQb2lUeXBlLk9CSkVDVDNELCBvYmplY3REYiwgcG9pT2JqZWN0KTtcbiAgICB9IGNhdGNoIChlcnI6IGFueSkgeyB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gZ2V0VGFnRnJvbUVsZW1lbnRJZChvYmplY3RJZCk7XG4gICAgICBpZiAoIXJlc3VsdD8udGFnKSByZXR1cm4gZmFsc2U7XG4gICAgICBhd2FpdCBnb1RvVGFnQ2FsbGJhY2socmVzdWx0LnRhZyk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgZGVsZXRlTGFzdFRhZ0NhbGxiYWNrKCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0U2NlbmVOb2RlRnJvbU9iamVjdDNESWQodXVpZDogc3RyaW5nKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy5kaWN0aW9ubmFyeVNjZW5lT2JqZWN0czNELmdldCh1dWlkKTtcbiAgfVxuXG4gIGFzeW5jIGRpc3BsYXlBemltdXRhbENyb3duKHBvc2VDYW1lcmE6IGFueSkge1xuICAgIGlmICh0aGlzLmF6aW11dGhhbENyb3duICYmIHBvc2VDYW1lcmEpIHtcbiAgICAgIHRoaXMuYXppbXV0aGFsQ3Jvd24ub2JqM0QucG9zaXRpb24uc2V0KHBvc2VDYW1lcmEucG9zaXRpb24ueCwgcG9zZUNhbWVyYS5wb3NpdGlvbi55LCBwb3NlQ2FtZXJhLnBvc2l0aW9uLnopXG4gICAgfVxuICB9XG5cbiAgLy9cbiAgLy8gLS0tLS0tLS0tLSBHZW9tZXRyeSBoZWxwZXJzIC0tLS0tLS0tLS1cbiAgLy9cbiAgcHJpdmF0ZSB0b1BvaW50KHY6IHsgeDogbnVtYmVyLCB5OiBudW1iZXIsIHo6IG51bWJlciB9KTogUG9pbnQzRCB7XG4gICAgcmV0dXJuIHsgeDogdi54LCB5OiB2LnksIHo6IHYueiB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEdlb21ldHJ5IG9mIHRoZSBtb2RlbCBpdHNlbGYgKHRoZSBsb2FkZXIgb3V0cHV0KTogdGhlIG5vZGUgYWxzbyBob2xkcyB0aGUgaGVscGVycyBhZGRlZCBieSBvdGhlclxuICAgKiBjb21wb25lbnRzLCBsaWtlIHRoZSB2aWV3IGZydXN0dW0gb2YgYSBzZWN1cml0eSBjYW1lcmEsIHdoaWNoIG11c3Qgbm90IGNvdW50IGluIGl0cyBzaXplLlxuICAgKi9cbiAgcHJpdmF0ZSBtb2RlbFJvb3QodXVpZDogc3RyaW5nLCBub2RlOiBhbnkpOiBhbnkge1xuICAgIHJldHVybiB0aGlzLmxvYWRlckNvbXBvbmVudHMuZ2V0KHV1aWQpPy5vdXRwdXRzPy5vYmplY3RSb290ID8/IG5vZGUub2JqM0Q7XG4gIH1cblxuICAvKiogV29ybGQtc3BhY2UgYm91bmRpbmcgYm94IG9mIHRoZSBtb2RlbCwgbnVsbCB3aGVuIHVua25vd24gb3Igd2hlbiBub3RoaW5nIGlzIGxvYWRlZCB5ZXQgKi9cbiAgZ2V0T2JqZWN0M0RCb3VuZGluZ0JveCh1dWlkOiBzdHJpbmcpOiBPYmplY3QzREJvdW5kaW5nQm94IHwgbnVsbCB7XG4gICAgY29uc3Qgbm9kZSA9IHRoaXMuZGljdGlvbm5hcnlPYmplY3RzM0QuZ2V0KHV1aWQpO1xuICAgIGlmICghbm9kZSkgcmV0dXJuIG51bGw7XG4gICAgbm9kZS5vYmozRC51cGRhdGVXb3JsZE1hdHJpeCh0cnVlLCB0cnVlKTtcbiAgICBjb25zdCBib3ggPSB0aGlzLnRtcEJveC5zZXRGcm9tT2JqZWN0KHRoaXMubW9kZWxSb290KHV1aWQsIG5vZGUpKTtcbiAgICBpZiAoYm94LmlzRW1wdHkoKSkgcmV0dXJuIG51bGw7XG4gICAgY29uc3Qgc2l6ZSA9IGJveC5nZXRTaXplKG5ldyBWZWN0b3IzKCkpO1xuICAgIGNvbnN0IGNlbnRlciA9IGJveC5nZXRDZW50ZXIobmV3IFZlY3RvcjMoKSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIG1pbjogdGhpcy50b1BvaW50KGJveC5taW4pLFxuICAgICAgbWF4OiB0aGlzLnRvUG9pbnQoYm94Lm1heCksXG4gICAgICBzaXplOiB0aGlzLnRvUG9pbnQoc2l6ZSksXG4gICAgICBjZW50ZXI6IHRoaXMudG9Qb2ludChjZW50ZXIpLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogUmVhbCBkaW1lbnNpb25zIG9mIHRoZSBtb2RlbCBpbiBtZXRlcnMgKHdpZHRoIHgsIGhlaWdodCB5LCBkZXB0aCB6KSwgc2NhbGUgaW5jbHVkZWQgYnV0IG5vdFxuICAgKiBpdHMgcm90YXRpb246IHRoZSB3b3JsZCBib3VuZGluZyBib3ggb2YgYSByb3RhdGVkIG9iamVjdCBpcyBsYXJnZXIgdGhhbiB0aGUgb2JqZWN0IGl0c2VsZi5cbiAgICovXG4gIGdldE9iamVjdDNERGltZW5zaW9ucyh1dWlkOiBzdHJpbmcpOiBQb2ludDNEIHwgbnVsbCB7XG4gICAgY29uc3Qgbm9kZSA9IHRoaXMuZGljdGlvbm5hcnlPYmplY3RzM0QuZ2V0KHV1aWQpO1xuICAgIGlmICghbm9kZSkgcmV0dXJuIG51bGw7XG4gICAgY29uc3Qgcm90YXRpb24gPSBub2RlLm9iajNELnJvdGF0aW9uLmNsb25lKCk7XG4gICAgbm9kZS5vYmozRC5yb3RhdGlvbi5zZXQoMCwgMCwgMCk7XG4gICAgdHJ5IHtcbiAgICAgIG5vZGUub2JqM0QudXBkYXRlV29ybGRNYXRyaXgodHJ1ZSwgdHJ1ZSk7XG4gICAgICBjb25zdCBib3ggPSB0aGlzLnRtcEJveC5zZXRGcm9tT2JqZWN0KHRoaXMubW9kZWxSb290KHV1aWQsIG5vZGUpKTtcbiAgICAgIHJldHVybiBib3guaXNFbXB0eSgpID8gbnVsbCA6IHRoaXMudG9Qb2ludChib3guZ2V0U2l6ZShuZXcgVmVjdG9yMygpKSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIG5vZGUub2JqM0Qucm90YXRpb24uY29weShyb3RhdGlvbik7XG4gICAgICBub2RlLm9iajNELnVwZGF0ZVdvcmxkTWF0cml4KHRydWUsIHRydWUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBVbmlmb3JtIHNjYWxlIHNvIHRoYXQgdGhlIGxhcmdlc3QgYm91bmRpbmcgYm94IGRpbWVuc2lvbiBlcXVhbHMgYHRhcmdldFNpemVNZXRlcnNgLlxuICAgKiBUaGUgbm9kZSBwb3NpdGlvbiBpcyB1bnRvdWNoZWQsIHNvIGNhbGwgcGxhY2VPYmplY3QzRE9uU3VyZmFjZSBhZnRlcndhcmRzLlxuICAgKiBAcmV0dXJucyB0aGUgbmV3IHNjYWxlLCBudWxsIHdoZW4gdGhlIG9iamVjdCBpcyB1bmtub3duIC8gbm90IGxvYWRlZCAvIGB0YXJnZXRTaXplTWV0ZXJzYCBpbnZhbGlkXG4gICAqL1xuICBub3JtYWxpemVPYmplY3QzRFNpemUodXVpZDogc3RyaW5nLCB0YXJnZXRTaXplTWV0ZXJzOiBudW1iZXIpOiBQb2ludDNEIHwgbnVsbCB7XG4gICAgY29uc3Qgbm9kZSA9IHRoaXMuZGljdGlvbm5hcnlPYmplY3RzM0QuZ2V0KHV1aWQpO1xuICAgIGNvbnN0IGJveCA9IHRoaXMuZ2V0T2JqZWN0M0RCb3VuZGluZ0JveCh1dWlkKTtcbiAgICBpZiAoIW5vZGUgfHwgIWJveCB8fCAhKHRhcmdldFNpemVNZXRlcnMgPiAwKSkgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgbGFyZ2VzdCA9IE1hdGgubWF4KGJveC5zaXplLngsIGJveC5zaXplLnksIGJveC5zaXplLnopO1xuICAgIGlmICghKGxhcmdlc3QgPiAwKSkgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgZmFjdG9yID0gdGFyZ2V0U2l6ZU1ldGVycyAvIGxhcmdlc3Q7XG4gICAgbm9kZS5vYmozRC5zY2FsZS5tdWx0aXBseVNjYWxhcihmYWN0b3IpO1xuICAgIHRoaXMuZW1pdFRyYW5zZm9ybUNoYW5nZWQodXVpZCk7XG4gICAgcmV0dXJuIHRoaXMudG9Qb2ludChub2RlLm9iajNELnNjYWxlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQbGFjZXMgdGhlIG1vZGVsIG9uIGEgc3VyZmFjZSBwb2ludCB3aXRob3V0IHRvdWNoaW5nIGl0cyBwaXZvdDogdGhlIG5vZGUgcG9zaXRpb24gaXNcbiAgICogYWRqdXN0ZWQgc28gdGhhdCB0aGUgYm91bmRpbmcgYm94IGJvdHRvbS1jZW50ZXIgbGllcyBvbiBgcG9pbnRgLlxuICAgKiAtIGZsb29yIChub3JtYWwgcG9pbnRpbmcgdXAsIG9yIG5vIG5vcm1hbCk6IGJvdHRvbS1jZW50ZXIgb24gdGhlIHBvaW50XG4gICAqIC0gd2FsbCAobW9zdGx5IGhvcml6b250YWwgbm9ybWFsKTogbW9kZWwgdHVybmVkIGFyb3VuZCBZIHNvIGl0cyArWiBmYWNlcyBhd2F5IGZyb20gdGhlIHdhbGwsXG4gICAqICAgYW5kIHB1c2hlZCBhbG9uZyB0aGUgbm9ybWFsIGJ5IGhhbGYgaXRzIGRlcHRoIHNvIGl0IGRvZXMgbm90IGN1dCB0aGUgd2FsbFxuICAgKiAtIGNlaWxpbmcgKG5vcm1hbCBwb2ludGluZyBkb3duKTogdGhlIG1vZGVsIGhhbmdzLCB0b3AtY2VudGVyIG9uIHRoZSBwb2ludFxuICAgKiBAcmV0dXJucyB0aGUgbmV3IHRyYW5zZm9ybSwgbnVsbCB3aGVuIHRoZSBvYmplY3QgaXMgdW5rbm93biBvciBub3QgbG9hZGVkXG4gICAqL1xuICAvKipcbiAgICogQHBhcmFtIGZyb250WWF3T2Zmc2V0IHJvdGF0aW9uIChyYWRpYW5zLCBhcm91bmQgWSkgdGhhdCB0dXJucyB0aGUgZnJvbnQgb2YgdGhlIG1vZGVsIHRvd2FyZCBpdHMgK1pcbiAgICogICAgICAgICAgICAgICAgICAgICAgIGF4aXMsIGZvciBtb2RlbHMgd2hvc2UgZnJvbnQgaXMgYW5vdGhlciBheGlzIChlLmcuIC1QSS8yIHdoZW4gaXQgaXMgK1gpXG4gICAqL1xuICBwbGFjZU9iamVjdDNET25TdXJmYWNlKHV1aWQ6IHN0cmluZywgcG9pbnQ6IFBvaW50M0QsIG5vcm1hbD86IFBvaW50M0QsIGZyb250WWF3T2Zmc2V0ID0gMCk6IE9iamVjdDNEVHJhbnNmb3JtIHwgbnVsbCB7XG4gICAgY29uc3Qgbm9kZSA9IHRoaXMuZGljdGlvbm5hcnlPYmplY3RzM0QuZ2V0KHV1aWQpO1xuICAgIGlmICghbm9kZSB8fCAhdGhpcy5nZXRPYmplY3QzREJvdW5kaW5nQm94KHV1aWQpKSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCBvYmogPSBub2RlLm9iajNEO1xuXG4gICAgY29uc3QgbiA9IG5vcm1hbCA/IG5ldyBWZWN0b3IzKG5vcm1hbC54LCBub3JtYWwueSwgbm9ybWFsLnopIDogbmV3IFZlY3RvcjMoMCwgMSwgMCk7XG4gICAgaWYgKG4ubGVuZ3RoU3EoKSA9PT0gMCkgbi5zZXQoMCwgMSwgMCk7XG4gICAgbi5ub3JtYWxpemUoKTtcblxuICAgIGNvbnN0IGlzV2FsbCA9IE1hdGguYWJzKG4ueSkgPCAwLjU7XG4gICAgY29uc3QgaXNDZWlsaW5nID0gIWlzV2FsbCAmJiBuLnkgPCAwO1xuICAgIGNvbnN0IHRhcmdldCA9IG5ldyBWZWN0b3IzKHBvaW50LngsIHBvaW50LnksIHBvaW50LnopO1xuXG4gICAgaWYgKGlzV2FsbCkge1xuICAgICAgLy8gRmFjZSBhd2F5IGZyb20gdGhlIHdhbGw7IHRoZSBib3ggaGFzIHRvIGJlIG1lYXN1cmVkIGFmdGVyIHRoZSByb3RhdGlvblxuICAgICAgb2JqLnJvdGF0aW9uLnkgPSBNYXRoLmF0YW4yKG4ueCwgbi56KSArIGZyb250WWF3T2Zmc2V0O1xuICAgIH1cbiAgICBjb25zdCBib3ggPSB0aGlzLmdldE9iamVjdDNEQm91bmRpbmdCb3godXVpZCkhO1xuXG4gICAgaWYgKGlzV2FsbCkge1xuICAgICAgY29uc3QgaG9yaXpvbnRhbCA9IG5ldyBWZWN0b3IzKG4ueCwgMCwgbi56KS5ub3JtYWxpemUoKTtcbiAgICAgIGNvbnN0IGhhbGZEZXB0aCA9IDAuNSAqIChNYXRoLmFicyhob3Jpem9udGFsLngpICogYm94LnNpemUueCArIE1hdGguYWJzKGhvcml6b250YWwueikgKiBib3guc2l6ZS56KTtcbiAgICAgIHRhcmdldC5hZGRTY2FsZWRWZWN0b3IoaG9yaXpvbnRhbCwgaGFsZkRlcHRoKTtcbiAgICB9XG5cbiAgICBjb25zdCBhbmNob3JZID0gaXNDZWlsaW5nID8gYm94Lm1heC55IDogYm94Lm1pbi55O1xuICAgIG9iai5wb3NpdGlvbi54ICs9IHRhcmdldC54IC0gYm94LmNlbnRlci54O1xuICAgIG9iai5wb3NpdGlvbi55ICs9IHRhcmdldC55IC0gYW5jaG9yWTtcbiAgICBvYmoucG9zaXRpb24ueiArPSB0YXJnZXQueiAtIGJveC5jZW50ZXIuejtcblxuICAgIHRoaXMuZW1pdFRyYW5zZm9ybUNoYW5nZWQodXVpZCk7XG4gICAgcmV0dXJuIHRoaXMuZ2V0T2JqZWN0M0RUcmFuc2Zvcm0odXVpZCk7XG4gIH1cblxuICBnZXRPYmplY3QzRFRyYW5zZm9ybSh1dWlkOiBzdHJpbmcpOiBPYmplY3QzRFRyYW5zZm9ybSB8IG51bGwge1xuICAgIGNvbnN0IG5vZGUgPSB0aGlzLmRpY3Rpb25uYXJ5T2JqZWN0czNELmdldCh1dWlkKTtcbiAgICBpZiAoIW5vZGUpIHJldHVybiBudWxsO1xuICAgIGNvbnN0IG8gPSBub2RlLm9iajNEO1xuICAgIHJldHVybiB7XG4gICAgICBwb3NpdGlvbjogdGhpcy50b1BvaW50KG8ucG9zaXRpb24pLFxuICAgICAgcm90YXRpb246IHsgeDogby5yb3RhdGlvbi54LCB5OiBvLnJvdGF0aW9uLnksIHo6IG8ucm90YXRpb24ueiB9LFxuICAgICAgc2NhbGU6IHRoaXMudG9Qb2ludChvLnNjYWxlKSxcbiAgICB9O1xuICB9XG5cbiAgLyoqIEFwcGxpZXMgYSAocGFydGlhbCkgdHJhbnNmb3JtLiBSb3RhdGlvbiBpcyBpbiByYWRpYW5zLiAqL1xuICBzZXRPYmplY3QzRFRyYW5zZm9ybSh1dWlkOiBzdHJpbmcsIHRyYW5zZm9ybTogUGFydGlhbDxPYmplY3QzRFRyYW5zZm9ybT4pOiBib29sZWFuIHtcbiAgICBjb25zdCBub2RlID0gdGhpcy5kaWN0aW9ubmFyeU9iamVjdHMzRC5nZXQodXVpZCk7XG4gICAgaWYgKCFub2RlKSByZXR1cm4gZmFsc2U7XG4gICAgY29uc3QgbyA9IG5vZGUub2JqM0Q7XG4gICAgaWYgKHRyYW5zZm9ybS5wb3NpdGlvbikgby5wb3NpdGlvbi5zZXQodHJhbnNmb3JtLnBvc2l0aW9uLngsIHRyYW5zZm9ybS5wb3NpdGlvbi55LCB0cmFuc2Zvcm0ucG9zaXRpb24ueik7XG4gICAgaWYgKHRyYW5zZm9ybS5yb3RhdGlvbikgby5yb3RhdGlvbi5zZXQodHJhbnNmb3JtLnJvdGF0aW9uLngsIHRyYW5zZm9ybS5yb3RhdGlvbi55LCB0cmFuc2Zvcm0ucm90YXRpb24ueik7XG4gICAgaWYgKHRyYW5zZm9ybS5zY2FsZSkgby5zY2FsZS5zZXQodHJhbnNmb3JtLnNjYWxlLngsIHRyYW5zZm9ybS5zY2FsZS55LCB0cmFuc2Zvcm0uc2NhbGUueik7XG4gICAgdGhpcy5lbWl0VHJhbnNmb3JtQ2hhbmdlZCh1dWlkKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHByaXZhdGUgZW1pdFRyYW5zZm9ybUNoYW5nZWQodXVpZDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgdHJhbnNmb3JtID0gdGhpcy5nZXRPYmplY3QzRFRyYW5zZm9ybSh1dWlkKTtcbiAgICBpZiAodHJhbnNmb3JtKSB7XG4gICAgICB0aGlzLm9iamVjdDNEVHJhbnNmb3JtQ2hhbmdlZCQubmV4dCh7IHV1aWQsIC4uLnRyYW5zZm9ybSB9KTtcbiAgICB9XG4gIH1cblxuICAvL1xuICAvLyAtLS0tLS0tLS0tIEdpem1vIC0tLS0tLS0tLS1cbiAgLy9cbiAgLyoqIENyZWF0ZXMgdGhlIG1wLnRyYW5zZm9ybUNvbnRyb2xzIG5vZGUgb2YgYSBtb2RlbCBhbmQgd2lyZXMgaXQgKGV2ZW50cywgc25hcCkgKi9cbiAgcHJpdmF0ZSBjcmVhdGVHaXptbyh1dWlkOiBzdHJpbmcsIG1vZGVsTm9kZTogYW55LCBzY2VuZU9iamVjdDogYW55LCBtb2RlOiBHaXptb01vZGUsIHZpc2libGU6IGJvb2xlYW4sIG5vZGU/OiBhbnkpOiBHaXptb0VudHJ5IHtcbiAgICBjb25zdCBnaXptb05vZGUgPSBub2RlID8/IHNjZW5lT2JqZWN0LmFkZE5vZGUoKTtcbiAgICBjb25zdCBjb21wb25lbnQgPSBnaXptb05vZGUuYWRkQ29tcG9uZW50KCdtcC50cmFuc2Zvcm1Db250cm9scycpO1xuICAgIGdpem1vTm9kZS5zdGFydCgpO1xuICAgIGNvbnN0IHRjID0gY29tcG9uZW50LnRyYW5zZm9ybUNvbnRyb2xzO1xuICAgIHRjLnZpc2libGUgPSB2aXNpYmxlO1xuICAgIGNvbXBvbmVudC5pbnB1dHMuc2VsZWN0aW9uID0gbW9kZWxOb2RlO1xuICAgIGNvbXBvbmVudC5pbnB1dHMubW9kZSA9IG1vZGU7XG4gICAgbW9kZWxOb2RlLm9iajNELmNvbnRyb2xzID0gY29tcG9uZW50O1xuXG4gICAgY29uc3QgZW50cnk6IEdpem1vRW50cnkgPSB7XG4gICAgICB1dWlkLFxuICAgICAgbm9kZTogZ2l6bW9Ob2RlLFxuICAgICAgY29tcG9uZW50LFxuICAgICAgbW9kZSxcbiAgICAgIGRyYWdTdGFydDogbnVsbCxcbiAgICAgIGxhc3RQb3NpdGlvbjogbW9kZWxOb2RlLm9iajNELnBvc2l0aW9uLmNsb25lKCksXG4gICAgICBvbkRyYWdnaW5nQ2hhbmdlZDogKGV2ZW50OiBhbnkpID0+IHtcbiAgICAgICAgZW50cnkuZHJhZ1N0YXJ0ID0gZXZlbnQ/LnZhbHVlID8gbW9kZWxOb2RlLm9iajNELnBvc2l0aW9uLmNsb25lKCkgOiBudWxsO1xuICAgICAgICBlbnRyeS5sYXN0UG9zaXRpb24gPSBtb2RlbE5vZGUub2JqM0QucG9zaXRpb24uY2xvbmUoKTtcbiAgICAgIH0sXG4gICAgICBvbk9iamVjdENoYW5nZTogKCkgPT4gdGhpcy5vbkdpem1vT2JqZWN0Q2hhbmdlKGVudHJ5LCBtb2RlbE5vZGUpLFxuICAgIH07XG4gICAgaWYgKHR5cGVvZiB0Yy5hZGRFdmVudExpc3RlbmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0Yy5hZGRFdmVudExpc3RlbmVyKCdkcmFnZ2luZy1jaGFuZ2VkJywgZW50cnkub25EcmFnZ2luZ0NoYW5nZWQpO1xuICAgICAgdGMuYWRkRXZlbnRMaXN0ZW5lcignb2JqZWN0Q2hhbmdlJywgZW50cnkub25PYmplY3RDaGFuZ2UpO1xuICAgIH1cbiAgICB0aGlzLmFwcGx5U25hcCh0Yyk7XG4gICAgdGhpcy5naXptb3Muc2V0KHV1aWQsIGVudHJ5KTtcbiAgICB0aGlzLmFjdGl2ZUdpem1vVXVpZCA9IHV1aWQ7XG4gICAgcmV0dXJuIGVudHJ5O1xuICB9XG5cbiAgLyoqIEtlZXBzIGEgdHJhbnNsYXRlIGRyYWcgd2l0aGluIG1heERyYWdEaXN0YW5jZSAvIG1heERyYWdIZWlnaHQgb2Ygd2hlcmUgaXQgc3RhcnRlZCwgdGhlbiBub3RpZmllcyAqL1xuICBwcml2YXRlIG9uR2l6bW9PYmplY3RDaGFuZ2UoZW50cnk6IEdpem1vRW50cnksIG1vZGVsTm9kZTogYW55KTogdm9pZCB7XG4gICAgY29uc3QgcG9zOiBWZWN0b3IzID0gbW9kZWxOb2RlLm9iajNELnBvc2l0aW9uO1xuICAgIGlmIChlbnRyeS5tb2RlID09PSAndHJhbnNsYXRlJykge1xuICAgICAgY29uc3Qgc3RhcnQgPSBlbnRyeS5kcmFnU3RhcnQgPz8gZW50cnkubGFzdFBvc2l0aW9uO1xuICAgICAgY29uc3QgZGVsdGEgPSBwb3MuY2xvbmUoKS5zdWIoc3RhcnQpO1xuICAgICAgZGVsdGEueSA9IE1hdGhVdGlscy5jbGFtcChkZWx0YS55LCAtdGhpcy5tYXhEcmFnSGVpZ2h0LCB0aGlzLm1heERyYWdIZWlnaHQpO1xuICAgICAgY29uc3QgbGVuZ3RoID0gZGVsdGEubGVuZ3RoKCk7XG4gICAgICBpZiAobGVuZ3RoID4gdGhpcy5tYXhEcmFnRGlzdGFuY2UpIHtcbiAgICAgICAgZGVsdGEubXVsdGlwbHlTY2FsYXIodGhpcy5tYXhEcmFnRGlzdGFuY2UgLyBsZW5ndGgpO1xuICAgICAgfVxuICAgICAgcG9zLmNvcHkoc3RhcnQpLmFkZChkZWx0YSk7XG4gICAgfVxuICAgIGVudHJ5Lmxhc3RQb3NpdGlvbiA9IHBvcy5jbG9uZSgpO1xuICAgIHRoaXMuZW1pdFRyYW5zZm9ybUNoYW5nZWQoZW50cnkudXVpZCk7XG4gIH1cblxuICBwcml2YXRlIGFwcGx5U25hcCh0YzogYW55KTogdm9pZCB7XG4gICAgaWYgKCF0YykgcmV0dXJuO1xuICAgIGNvbnN0IHNuYXAgPSB0aGlzLmdpem1vU25hcDtcbiAgICBjb25zdCB0cmFuc2xhdGlvbiA9IHNuYXA/LnRyYW5zbGF0aW9uID8/IG51bGw7XG4gICAgY29uc3Qgcm90YXRpb24gPSBzbmFwPy5yb3RhdGlvbkRlZyAhPSBudWxsID8gTWF0aFV0aWxzLmRlZ1RvUmFkKHNuYXAucm90YXRpb25EZWcpIDogbnVsbDtcbiAgICBjb25zdCBzY2FsZSA9IHNuYXA/LnNjYWxlID8/IG51bGw7XG4gICAgaWYgKHR5cGVvZiB0Yy5zZXRUcmFuc2xhdGlvblNuYXAgPT09ICdmdW5jdGlvbicpIHRjLnNldFRyYW5zbGF0aW9uU25hcCh0cmFuc2xhdGlvbik7IGVsc2UgdGMudHJhbnNsYXRpb25TbmFwID0gdHJhbnNsYXRpb247XG4gICAgaWYgKHR5cGVvZiB0Yy5zZXRSb3RhdGlvblNuYXAgPT09ICdmdW5jdGlvbicpIHRjLnNldFJvdGF0aW9uU25hcChyb3RhdGlvbik7IGVsc2UgdGMucm90YXRpb25TbmFwID0gcm90YXRpb247XG4gICAgaWYgKHR5cGVvZiB0Yy5zZXRTY2FsZVNuYXAgPT09ICdmdW5jdGlvbicpIHRjLnNldFNjYWxlU25hcChzY2FsZSk7IGVsc2UgdGMuc2NhbGVTbmFwID0gc2NhbGU7XG4gIH1cblxuICAvKipcbiAgICogU2hvd3MgdGhlIHRyYW5zZm9ybSBnaXptbyBvbiBhbiBvYmplY3QgKGFueSBwcmV2aW91cyBnaXptbyBpcyBkZXRhY2hlZCBmaXJzdCkuXG4gICAqIFJlLWF0dGFjaGluZyB0byB0aGUgb2JqZWN0IHRoYXQgYWxyZWFkeSBoYXMgdGhlIGdpem1vIG9ubHkgY2hhbmdlcyBpdHMgbW9kZS5cbiAgICovXG4gIGFzeW5jIGF0dGFjaEdpem1vKHV1aWQ6IHN0cmluZywgbW9kZTogR2l6bW9Nb2RlLCBzZGs/OiBhbnkpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBtb2RlbE5vZGUgPSB0aGlzLmRpY3Rpb25uYXJ5T2JqZWN0czNELmdldCh1dWlkKTtcbiAgICBjb25zdCBzY2VuZU9iamVjdCA9IHRoaXMuZGljdGlvbm5hcnlTY2VuZU9iamVjdHMzRC5nZXQodXVpZCk7XG4gICAgaWYgKCFtb2RlbE5vZGUgfHwgIXNjZW5lT2JqZWN0KSByZXR1cm4gZmFsc2U7XG5cbiAgICBjb25zdCBleGlzdGluZyA9IHRoaXMuZ2l6bW9zLmdldCh1dWlkKTtcbiAgICBpZiAoZXhpc3RpbmcgJiYgdGhpcy5hY3RpdmVHaXptb1V1aWQgPT09IHV1aWQpIHtcbiAgICAgIHRoaXMuc2V0R2l6bW9Nb2RlKG1vZGUpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIC8vIEEgc3RhcnRlZCBzY2VuZSBvYmplY3QgcmVmdXNlcyBuZXcgbm9kZXMgKGFkZE5vZGUgcmV0dXJucyBudWxsKTogdXNlIGEgZGVkaWNhdGVkIG9uZVxuICAgIGxldCBub2RlID0gc2NlbmVPYmplY3QuYWRkTm9kZSgpO1xuICAgIGxldCBnaXptb1NjZW5lT2JqZWN0ID0gbnVsbDtcbiAgICBpZiAoIW5vZGUpIHtcbiAgICAgIGlmICghc2RrPy5TY2VuZSkgcmV0dXJuIGZhbHNlO1xuICAgICAgW2dpem1vU2NlbmVPYmplY3RdID0gYXdhaXQgc2RrLlNjZW5lLmNyZWF0ZU9iamVjdHMoMSk7XG4gICAgICBub2RlID0gZ2l6bW9TY2VuZU9iamVjdC5hZGROb2RlKCk7XG4gICAgfVxuICAgIHRoaXMuZGV0YWNoR2l6bW8oKTtcbiAgICBjb25zdCBlbnRyeSA9IHRoaXMuY3JlYXRlR2l6bW8odXVpZCwgbW9kZWxOb2RlLCBzY2VuZU9iamVjdCwgbW9kZSwgdHJ1ZSwgbm9kZSk7XG4gICAgZW50cnkuc2NlbmVPYmplY3QgPSBnaXptb1NjZW5lT2JqZWN0O1xuICAgIHRoaXMubGFzdE9iamVjdDNEID0gbW9kZWxOb2RlLm9iajNEO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgLyoqIFN3aXRjaGVzIHRoZSBhY3RpdmUgZ2l6bW8gYmV0d2VlbiB0cmFuc2xhdGUgLyByb3RhdGUgLyBzY2FsZSB3aXRob3V0IHJlLWF0dGFjaGluZyBpdCAqL1xuICBzZXRHaXptb01vZGUobW9kZTogR2l6bW9Nb2RlKTogdm9pZCB7XG4gICAgY29uc3QgZW50cnkgPSB0aGlzLmFjdGl2ZUdpem1vVXVpZCA/IHRoaXMuZ2l6bW9zLmdldCh0aGlzLmFjdGl2ZUdpem1vVXVpZCkgOiBudWxsO1xuICAgIGlmICghZW50cnkpIHJldHVybjtcbiAgICBlbnRyeS5tb2RlID0gbW9kZTtcbiAgICBlbnRyeS5kcmFnU3RhcnQgPSBudWxsO1xuICAgIGVudHJ5LmNvbXBvbmVudC5pbnB1dHMubW9kZSA9IG1vZGU7XG4gICAgY29uc3QgdGMgPSBlbnRyeS5jb21wb25lbnQudHJhbnNmb3JtQ29udHJvbHM7XG4gICAgaWYgKHRjICYmIHR5cGVvZiB0Yy5zZXRNb2RlID09PSAnZnVuY3Rpb24nKSB0Yy5zZXRNb2RlKG1vZGUpO1xuICB9XG5cbiAgLyoqIFJlYWxseSByZW1vdmVzIHRoZSBnaXptbyBmcm9tIHRoZSBzY2VuZSAoZGVmYXVsdDogdGhlIGFjdGl2ZSBvbmUpICovXG4gIGRldGFjaEdpem1vKHV1aWQ/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBpZCA9IHV1aWQgPz8gdGhpcy5hY3RpdmVHaXptb1V1aWQ7XG4gICAgaWYgKCFpZCkgcmV0dXJuO1xuICAgIGNvbnN0IGVudHJ5ID0gdGhpcy5naXptb3MuZ2V0KGlkKTtcbiAgICBpZiAoIWVudHJ5KSByZXR1cm47XG4gICAgY29uc3QgdGMgPSBlbnRyeS5jb21wb25lbnQ/LnRyYW5zZm9ybUNvbnRyb2xzO1xuICAgIGlmICh0Yykge1xuICAgICAgaWYgKHR5cGVvZiB0Yy5yZW1vdmVFdmVudExpc3RlbmVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRjLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2RyYWdnaW5nLWNoYW5nZWQnLCBlbnRyeS5vbkRyYWdnaW5nQ2hhbmdlZCk7XG4gICAgICAgIHRjLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ29iamVjdENoYW5nZScsIGVudHJ5Lm9uT2JqZWN0Q2hhbmdlKTtcbiAgICAgIH1cbiAgICAgIHRjLnZpc2libGUgPSBmYWxzZTtcbiAgICAgIGlmICh0eXBlb2YgdGMuZGV0YWNoID09PSAnZnVuY3Rpb24nKSB0Yy5kZXRhY2goKTtcbiAgICAgIGlmICh0eXBlb2YgdGMuZGlzcG9zZSA9PT0gJ2Z1bmN0aW9uJykgdGMuZGlzcG9zZSgpO1xuICAgICAgaWYgKHRjLnBhcmVudCAmJiB0eXBlb2YgdGMucGFyZW50LnJlbW92ZSA9PT0gJ2Z1bmN0aW9uJykgdGMucGFyZW50LnJlbW92ZSh0Yyk7XG4gICAgfVxuICAgIHRyeSB7IGVudHJ5Lm5vZGUuc3RvcCgpOyB9IGNhdGNoIHsgLyogYWxyZWFkeSBzdG9wcGVkICovIH1cbiAgICB0cnkgeyBlbnRyeS5zY2VuZU9iamVjdD8uc3RvcCgpOyB9IGNhdGNoIHsgLyogYWxyZWFkeSBzdG9wcGVkICovIH1cbiAgICBjb25zdCBtb2RlbE5vZGUgPSB0aGlzLmRpY3Rpb25uYXJ5T2JqZWN0czNELmdldChpZCk7XG4gICAgaWYgKG1vZGVsTm9kZT8ub2JqM0QpIG1vZGVsTm9kZS5vYmozRC5jb250cm9scyA9IG51bGw7XG4gICAgdGhpcy5naXptb3MuZGVsZXRlKGlkKTtcbiAgICBpZiAodGhpcy5hY3RpdmVHaXptb1V1aWQgPT09IGlkKSB0aGlzLmFjdGl2ZUdpem1vVXVpZCA9IG51bGw7XG4gIH1cblxuICBpc0dpem1vQXR0YWNoZWQodXVpZD86IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB1dWlkID8gdGhpcy5naXptb3MuaGFzKHV1aWQpIDogdGhpcy5hY3RpdmVHaXptb1V1aWQgIT09IG51bGw7XG4gIH1cblxuICAvKiogU25hcCBzdGVwcyBmb3IgYWxsIGdpem1vcyAobnVsbCAvIG1pc3NpbmcgdmFsdWUgPSBubyBzbmFwKSAqL1xuICBzZXRHaXptb1NuYXAoc25hcDogR2l6bW9TbmFwIHwgbnVsbCk6IHZvaWQge1xuICAgIHRoaXMuZ2l6bW9TbmFwID0gc25hcCA/IHsgLi4uc25hcCB9IDogbnVsbDtcbiAgICB0aGlzLmdpem1vcy5mb3JFYWNoKChlbnRyeSkgPT4gdGhpcy5hcHBseVNuYXAoZW50cnkuY29tcG9uZW50Py50cmFuc2Zvcm1Db250cm9scykpO1xuICB9XG5cbiAgc2V0R2l6bW9NYXhEcmFnRGlzdGFuY2UobWF4RGlzdGFuY2U6IG51bWJlciwgbWF4SGVpZ2h0PzogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKG1heERpc3RhbmNlID4gMCkgdGhpcy5tYXhEcmFnRGlzdGFuY2UgPSBtYXhEaXN0YW5jZTtcbiAgICBpZiAobWF4SGVpZ2h0ICE9PSB1bmRlZmluZWQgJiYgbWF4SGVpZ2h0ID4gMCkgdGhpcy5tYXhEcmFnSGVpZ2h0ID0gbWF4SGVpZ2h0O1xuICB9XG5cbiAgLyoqXG4gICAqIFByZXZlbnRzIGNhbWVyYSBuYXZpZ2F0aW9uIHRvIG90aGVyIHN3ZWVwcyB3aGlsZSBhIGdpem1vIGlzIGVkaXRlZC5cbiAgICogVGhlIFNESyBoYXMgbm8gXCJmcmVlemUgY2FtZXJhXCIgc3dpdGNoLCBzbyBldmVyeSBlbmFibGVkIHN3ZWVwIGV4Y2VwdCB0aGUgY3VycmVudCBvbmUgaXNcbiAgICogZGlzYWJsZWQgKFN3ZWVwLmRpc2FibGUpOyBleGFjdGx5IHRob3NlIHN3ZWVwcyBhcmUgcmUtZW5hYmxlZCBvbiB1bmxvY2suIFN3ZWVwcyBhbHJlYWR5XG4gICAqIGRpc2FibGVkIChmb3JiaWRkZW4gc3dlZXBzLCBlZGl0IG1vZGUpIGFyZSBuZXZlciB0b3VjaGVkLCBhbmQgYGtlZXBEaXNhYmxlZGAgbGlzdHMgc3dlZXBzXG4gICAqIHRoYXQgbXVzdCBzdGF5IGRpc2FibGVkIG9uIHVubG9jay5cbiAgICogQHJldHVybnMgZmFsc2Ugd2hlbiB0aGUgbG9jayBjb3VsZCBub3QgYmUgYXBwbGllZCAoU0RLIHdpdGhvdXQgU3dlZXAuZGlzYWJsZSwgdW5rbm93biBjdXJyZW50IHN3ZWVwKVxuICAgKi9cbiAgYXN5bmMgc2V0TmF2aWdhdGlvbkxvY2tlZChcbiAgICBzZGs6IGFueSxcbiAgICBsb2NrZWQ6IGJvb2xlYW4sXG4gICAgc3dlZXBDb2xsZWN0aW9uPzogUmVjb3JkPHN0cmluZywgYW55PiB8IG51bGwsXG4gICAgY3VycmVudFN3ZWVwSWQ/OiBzdHJpbmcgfCBudWxsLFxuICAgIGtlZXBEaXNhYmxlZDogc3RyaW5nW10gPSBbXVxuICApOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBpZiAoIXNkaz8uU3dlZXAgfHwgdHlwZW9mIHNkay5Td2VlcC5kaXNhYmxlICE9PSAnZnVuY3Rpb24nIHx8IHR5cGVvZiBzZGsuU3dlZXAuZW5hYmxlICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmIChsb2NrZWQpIHtcbiAgICAgIGlmICh0aGlzLnN3ZWVwc0Rpc2FibGVkQnlMb2NrLmxlbmd0aCA+IDApIHJldHVybiB0cnVlO1xuICAgICAgaWYgKCFzd2VlcENvbGxlY3Rpb24gfHwgIWN1cnJlbnRTd2VlcElkKSByZXR1cm4gZmFsc2U7XG4gICAgICAvLyBhIHN3ZWVwIHRoaXMgbG9jayByZS1lbmFibGVkIGp1c3QgYmVmb3JlIG1heSBzdGlsbCBiZSByZXBvcnRlZCBkaXNhYmxlZCBieSB0aGUgU0RLXG4gICAgICBjb25zdCBpZHMgPSBPYmplY3Qua2V5cyhzd2VlcENvbGxlY3Rpb24pLmZpbHRlcigoc2lkKSA9PlxuICAgICAgICBzaWQgIT09IGN1cnJlbnRTd2VlcElkICYmXG4gICAgICAgIChzd2VlcENvbGxlY3Rpb25bc2lkXT8uZW5hYmxlZCAhPT0gZmFsc2UgfHwgdGhpcy5zd2VlcHNFbmFibGVkQnlVbmxvY2suaW5jbHVkZXMoc2lkKSkpO1xuICAgICAgaWYgKGlkcy5sZW5ndGggPT09IDApIHJldHVybiB0cnVlO1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgc2RrLlN3ZWVwLmRpc2FibGUoLi4uaWRzKTtcbiAgICAgICAgdGhpcy5zd2VlcHNEaXNhYmxlZEJ5TG9jayA9IGlkcztcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBmYWxsIGJhY2sgdG8gb25lIGNhbGwgcGVyIHN3ZWVwIHRvIGtub3cgZXhhY3RseSB3aGljaCBvbmVzIHdlcmUgZGlzYWJsZWRcbiAgICAgICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChpZHMubWFwKChzaWQpID0+IHNkay5Td2VlcC5kaXNhYmxlKHNpZCkpKTtcbiAgICAgICAgdGhpcy5zd2VlcHNEaXNhYmxlZEJ5TG9jayA9IGlkcy5maWx0ZXIoKF8sIGkpID0+IHJlc3VsdHNbaV0uc3RhdHVzID09PSAnZnVsZmlsbGVkJyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgdG9FbmFibGUgPSB0aGlzLnN3ZWVwc0Rpc2FibGVkQnlMb2NrLmZpbHRlcigoc2lkKSA9PiAha2VlcERpc2FibGVkLmluY2x1ZGVzKHNpZCkpO1xuICAgIHRoaXMuc3dlZXBzRGlzYWJsZWRCeUxvY2sgPSBbXTtcbiAgICB0aGlzLnN3ZWVwc0VuYWJsZWRCeVVubG9jayA9IHRvRW5hYmxlO1xuICAgIGlmICh0b0VuYWJsZS5sZW5ndGggPiAwKSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBzZGsuU3dlZXAuZW5hYmxlKC4uLnRvRW5hYmxlKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQodG9FbmFibGUubWFwKChzaWQpID0+IHNkay5Td2VlcC5lbmFibGUoc2lkKSkpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGlzTmF2aWdhdGlvbkxvY2tlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zd2VlcHNEaXNhYmxlZEJ5TG9jay5sZW5ndGggPiAwO1xuICB9XG5cbiAgLyoqIFN3ZWVwcyBjdXJyZW50bHkgZGlzYWJsZWQgYnkgdGhlIG5hdmlnYXRpb24gbG9jayAqL1xuICBnZXRTd2VlcHNEaXNhYmxlZEJ5TG9jaygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIFsuLi50aGlzLnN3ZWVwc0Rpc2FibGVkQnlMb2NrXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMZWdhY3kgQVBJOiBhdHRhY2hlcyBhIGdpem1vIHRvIGEgbW9kZWwgbm9kZS4gUHJlZmVyIGF0dGFjaEdpem1vKHV1aWQsIG1vZGUpLlxuICAgKi9cbiAgYXN5bmMgYXR0YWNoR2l6bW9Db250cm9sVG8zRE9iamVjdChcbiAgICBzZGs6IGFueSxcbiAgICBtb2RlbE5vZGU6IGFueSxcbiAgICBzY2VuZU9iamVjdDogYW55LFxuICAgIG1vZGU6IEdpem1vTW9kZSxcbiAgICB2aXNpYmxlOiBib29sZWFuLFxuICAgIGlzTmV3T2JqZWN0OiBib29sZWFuXG4gICk6IFByb21pc2U8YW55PiB7XG4gICAgbGV0IG5vZGUgPSBzY2VuZU9iamVjdC5hZGROb2RlKCk7XG4gICAgaWYgKCFub2RlKSB7XG4gICAgICBjb25zdCBbbmV3U2NlbmVPYmplY3RdID0gYXdhaXQgc2RrLlNjZW5lLmNyZWF0ZU9iamVjdHMoMSk7XG4gICAgICBub2RlID0gbmV3U2NlbmVPYmplY3QuYWRkTm9kZSgpO1xuICAgIH1cbiAgICBpZiAoaXNOZXdPYmplY3QgJiYgKCF0aGlzLmxhc3RPYmplY3QzRCB8fCAhdGhpcy5sYXN0T2JqZWN0M0QuY29udHJvbHMpKSB7XG4gICAgICB0cnkge1xuICAgICAgICBtb2RlbE5vZGUub2JqM0QudXVpZCA9IHRoaXMubGFzdE9iamVjdDNELnV1aWQgfHwgdGhpcy5sYXN0T2JqZWN0M0QuaWQ7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIC8vIGxhc3RPYmplY3QzRCBpcyBub3Qgc2V0OiB0aGUgbW9kZWwga2VlcHMgaXRzIG93biB1dWlkXG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuZGV0YWNoR2l6bW8oKTtcbiAgICB0aGlzLmNyZWF0ZUdpem1vKG1vZGVsTm9kZS5vYmozRC51dWlkLCBtb2RlbE5vZGUsIHNjZW5lT2JqZWN0LCBtb2RlLCB2aXNpYmxlLCBub2RlKTtcbiAgICB0aGlzLmxhc3RPYmplY3QzRCA9IG1vZGVsTm9kZS5vYmozRDtcbiAgICByZXR1cm4gbW9kZWxOb2RlO1xuICB9XG5cbiAgLyoqIFJlbW92ZXMgdGhlIGdpem1vIG9mIHRoZSBsYXN0IGFkZGVkIC8gZWRpdGVkIG9iamVjdCAqL1xuICByZW1vdmVHaXptb0Zyb21MYXN0T2JqZWN0KCk6IHZvaWQge1xuICAgIGNvbnN0IGxhc3QgPSB0aGlzLmxhc3RPYmplY3QzRDtcbiAgICBpZiAoIWxhc3QpIHJldHVybjtcbiAgICBjb25zdCB1dWlkID0gbGFzdC51dWlkID8/IGxhc3QuaWQ7XG4gICAgaWYgKHV1aWQgJiYgdGhpcy5naXptb3MuaGFzKHV1aWQpKSB7XG4gICAgICB0aGlzLmRldGFjaEdpem1vKHV1aWQpO1xuICAgIH0gZWxzZSBpZiAobGFzdC5jb250cm9scykge1xuICAgICAgLy8gZ2l6bW8gbm90IGNyZWF0ZWQgYnkgdGhpcyBzZXJ2aWNlOiBiZXN0IGVmZm9ydFxuICAgICAgbGFzdC5jb250cm9scy50cmFuc2Zvcm1Db250cm9scy52aXNpYmxlID0gZmFsc2U7XG4gICAgICBsYXN0LmNvbnRyb2xzLnRyYW5zZm9ybUNvbnRyb2xzLmRpc3Bvc2UoKTtcbiAgICAgIGxhc3QuY29udHJvbHMgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8vXG4gIC8vIC0tLS0tLS0tLS0gU2VjdXJpdHkgY2FtZXJhIC0tLS0tLS0tLS1cbiAgLy9cbiAgcHJpdmF0ZSBhcHBseVZpZXdGcnVzdHVtKHV1aWQ6IHN0cmluZywgdmlzaWJsZTogYm9vbGVhbik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGFuaW1hdG9yID0gdGhpcy5zZWN1cml0eUNhbWVyYUFuaW1hdG9ycy5nZXQodXVpZCk7XG4gICAgaWYgKCFhbmltYXRvcikgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLnZpZXdGcnVzdHVtVmlzaWJsZS5nZXQodXVpZCkgPz8gdHJ1ZTtcbiAgICBpZiAoY3VycmVudCA9PT0gdmlzaWJsZSkgcmV0dXJuIHRydWU7XG4gICAgdHJ5IHtcbiAgICAgIGFuaW1hdG9yLnRvZ2dsZVZpZXdGcnVzdHVtKCk7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRoaXMudmlld0ZydXN0dW1WaXNpYmxlLnNldCh1dWlkLCB2aXNpYmxlKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKiBTaG93cyAvIGhpZGVzIHRoZSB2aWV3IGZydXN0dW0gb2YgdGhlIHNlY3VyaXR5IGNhbWVyYSBgdXVpZGAgKi9cbiAgc2V0Vmlld0ZydXN0dW0odXVpZDogc3RyaW5nLCB2aXNpYmxlOiBib29sZWFuKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuYXBwbHlWaWV3RnJ1c3R1bSh1dWlkLCB2aXNpYmxlKTtcbiAgfVxuXG4gIGlzVmlld0ZydXN0dW1WaXNpYmxlKHV1aWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnZpZXdGcnVzdHVtVmlzaWJsZS5nZXQodXVpZCkgPz8gZmFsc2U7XG4gIH1cblxuICAvKiogVG9nZ2xlcyB0aGUgZnJ1c3R1bSBvZiBgdXVpZGAsIG9yIG9mIHRoZSBsYXN0IGxvYWRlZCBzZWN1cml0eSBjYW1lcmEgd2hlbiBvbWl0dGVkICovXG4gIHRvZ2dsZVZpZXdGcnVzdHVtKHV1aWQ/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBpZCA9IHV1aWQgPz8gdGhpcy5sYXN0U2VjdXJpdHlDYW1lcmFVdWlkO1xuICAgIGlmIChpZCAmJiB0aGlzLnNlY3VyaXR5Q2FtZXJhQW5pbWF0b3JzLmhhcyhpZCkpIHtcbiAgICAgIHRoaXMuYXBwbHlWaWV3RnJ1c3R1bShpZCwgISh0aGlzLnZpZXdGcnVzdHVtVmlzaWJsZS5nZXQoaWQpID8/IHRydWUpKTtcbiAgICB9IGVsc2UgaWYgKCF1dWlkICYmIHRoaXMuc2VjdXJpdHlDYW1lcmFBbmltYXRvcikge1xuICAgICAgLy8gYW5pbWF0b3Igc2V0IGJ5IGhhbmQgKGxlZ2FjeSlcbiAgICAgIHRoaXMuc2VjdXJpdHlDYW1lcmFBbmltYXRvci50b2dnbGVWaWV3RnJ1c3R1bSgpO1xuICAgIH1cbiAgfVxuXG4gIGNsZWFyKCkge1xuICAgIEFycmF5LmZyb20odGhpcy5naXptb3Mua2V5cygpKS5mb3JFYWNoKChpZCkgPT4gdGhpcy5kZXRhY2hHaXptbyhpZCkpO1xuICAgIHRoaXMuZGljdGlvbm5hcnlPYmplY3RzM0QuY2xlYXIoKTtcbiAgICB0aGlzLmRpY3Rpb25uYXJ5U2NlbmVPYmplY3RzM0QuY2xlYXIoKTtcbiAgICB0aGlzLmxvYWRlckNvbXBvbmVudHMuY2xlYXIoKTtcbiAgICB0aGlzLnNlY3VyaXR5Q2FtZXJhQW5pbWF0b3JzLmNsZWFyKCk7XG4gICAgdGhpcy52aWV3RnJ1c3R1bVZpc2libGUuY2xlYXIoKTtcbiAgICB0aGlzLmxhc3RTZWN1cml0eUNhbWVyYVV1aWQgPSBudWxsO1xuICAgIHRoaXMuc3dlZXBzRGlzYWJsZWRCeUxvY2sgPSBbXTtcbiAgICB0aGlzLmxhc3RPYmplY3QzRCA9IG51bGw7XG4gICAgdGhpcy5hemltdXRoYWxDcm93biA9IG51bGw7XG4gICAgdGhpcy5zZWN1cml0eUNhbWVyYUFuaW1hdG9yID0gbnVsbDtcbiAgICB0aGlzLm5vTGlnaHRGb3JPYmplY3RzID0gdHJ1ZTtcbiAgfVxufVxuIl19