@smarterplan/ngx-smarterplan-core 1.4.14 → 1.4.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -24
- package/esm2022/lib/components/csv-export/csv-export.component.mjs +3 -3
- package/esm2022/lib/components/loader/loader.component.mjs +3 -3
- package/esm2022/lib/components/menu-bar/avatar/avatar.component.mjs +1 -1
- package/esm2022/lib/components/menu-bar/menu-bar.component.mjs +3 -3
- package/esm2022/lib/components/menu-bar/navigation-bar/navigation-bar.component.mjs +3 -3
- package/esm2022/lib/components/modal-switch-visit/modal-switch-visit.component.mjs +3 -3
- package/esm2022/lib/components/search-bar/search-bar.component.mjs +3 -3
- package/esm2022/lib/components/support-modal/support-modal.component.mjs +3 -3
- package/esm2022/lib/config.mjs +1 -1
- package/esm2022/lib/helpers.service.mjs +46 -1
- package/esm2022/lib/matterport-extensions/nest-thermostat/CanvasImage.mjs +1 -1
- package/esm2022/lib/matterport-extensions/nest-thermostat/CanvasRenderer.mjs +1 -1
- package/esm2022/lib/matterport-extensions/nest-thermostat/NestThermostat.mjs +1 -1
- package/esm2022/lib/matterport-extensions/nest-thermostat/PlaneRenderer.mjs +1 -1
- package/esm2022/lib/matterport-extensions/scene-component/SceneComponent.mjs +1 -1
- package/esm2022/lib/matterport-extensions/security-camera/SecurityCamera.mjs +22 -22
- package/esm2022/lib/matterport-extensions/tv-player/TvPlayer.mjs +1 -1
- package/esm2022/lib/matterport-extensions/view-frustum-mesh/ViewFrustumMesh.mjs +22 -22
- package/esm2022/lib/mattertagData.mjs +1 -1
- package/esm2022/lib/ngx-smarterplan-core.module.mjs +1 -1
- package/esm2022/lib/ngx-smarterplan-core.service.mjs +1 -1
- package/esm2022/lib/pipes/duration-to-string.pipe.mjs +1 -1
- package/esm2022/lib/pipes/format-date-number-to-digits.pipe.mjs +1 -1
- package/esm2022/lib/pipes/safe-url.pipe.mjs +1 -1
- package/esm2022/lib/pipes/time-date-to-local-string.pipe.mjs +1 -1
- package/esm2022/lib/pipes/username-from-id.pipe.mjs +1 -1
- package/esm2022/lib/services/amplify-cache.service.mjs +1 -1
- package/esm2022/lib/services/base-tab.service.mjs +1 -1
- package/esm2022/lib/services/baseVisibility.service.mjs +1 -1
- package/esm2022/lib/services/content.service.mjs +1 -1
- package/esm2022/lib/services/filter.service.mjs +1 -1
- package/esm2022/lib/services/intervention.service.mjs +1 -1
- package/esm2022/lib/services/locale.service.mjs +1 -1
- package/esm2022/lib/services/matterport-import.service.mjs +1 -1
- package/esm2022/lib/services/matterport-measurement.service.mjs +1 -1
- package/esm2022/lib/services/matterport-navigation.service.mjs +1 -1
- package/esm2022/lib/services/matterport-object3d.service.mjs +1 -1
- package/esm2022/lib/services/matterport-pointer.service.mjs +6 -6
- package/esm2022/lib/services/matterport-tag-copy.service.mjs +448 -62
- package/esm2022/lib/services/matterport-tag.service.mjs +1 -1
- package/esm2022/lib/services/matterport.service.mjs +17 -17
- package/esm2022/lib/services/models/affectation.service.mjs +1 -1
- package/esm2022/lib/services/models/base-object.service.mjs +1 -1
- package/esm2022/lib/services/models/capture.service.mjs +1 -1
- package/esm2022/lib/services/models/comment.service.mjs +1 -1
- package/esm2022/lib/services/models/domain.service.mjs +20 -1
- package/esm2022/lib/services/models/equipment.service.mjs +4 -2
- package/esm2022/lib/services/models/event.service.mjs +1 -1
- package/esm2022/lib/services/models/feature.service.mjs +1 -7
- package/esm2022/lib/services/models/hashtag.service.mjs +1 -1
- package/esm2022/lib/services/models/layer.service.mjs +1 -1
- package/esm2022/lib/services/models/measurement.service.mjs +1 -1
- package/esm2022/lib/services/models/mission.service.mjs +17 -1
- package/esm2022/lib/services/models/navigation.service.mjs +1 -1
- package/esm2022/lib/services/models/node.service.mjs +1 -1
- package/esm2022/lib/services/models/object3D.service.mjs +1 -1
- package/esm2022/lib/services/models/operation.service.mjs +1 -1
- package/esm2022/lib/services/models/organisation.service.mjs +1 -1
- package/esm2022/lib/services/models/plan.service.mjs +1 -1
- package/esm2022/lib/services/models/poi.service.mjs +27 -27
- package/esm2022/lib/services/models/profile.service.mjs +1 -1
- package/esm2022/lib/services/models/property.service.mjs +1 -1
- package/esm2022/lib/services/models/space.service.mjs +25 -6
- package/esm2022/lib/services/models/template.service.mjs +1 -1
- package/esm2022/lib/services/models/ticket.service.mjs +1 -1
- package/esm2022/lib/services/models/visit.service.mjs +17 -5
- package/esm2022/lib/services/models/zone.service.mjs +1 -1
- package/esm2022/lib/services/navigator.service.mjs +1 -1
- package/esm2022/lib/services/s3.service.mjs +18 -1
- package/esm2022/lib/services/search.service.mjs +1 -1
- package/esm2022/lib/services/support.service.mjs +1 -1
- package/esm2022/lib/services/tag.service.mjs +16 -16
- package/esm2022/lib/services/threejs-import.service.mjs +151 -0
- package/esm2022/lib/services/threejs.service.mjs +1306 -0
- package/esm2022/lib/services/user.service.mjs +1 -1
- package/esm2022/lib/services/utils/matterport-transform.util.mjs +1 -1
- package/esm2022/lib/services/validators.service.mjs +1 -1
- package/esm2022/lib/services/viewer.service.mjs +263 -5
- package/esm2022/lib/services/zone-drawer.service.mjs +1 -1
- package/esm2022/lib/services/zoneChange.service.mjs +1 -1
- package/esm2022/lib/tokens/matterport-sdk-key.token.mjs +1 -1
- package/esm2022/lib/types.service.mjs +2 -1
- package/esm2022/lib/validators/email.directive.mjs +1 -1
- package/esm2022/lib/validators/no-empty.directive.mjs +1 -1
- package/esm2022/lib/validators/number.directive.mjs +1 -1
- package/esm2022/lib/validators/text.directive.mjs +1 -1
- package/esm2022/public-api.mjs +3 -1
- package/fesm2022/smarterplan-ngx-smarterplan-core.mjs +2759 -551
- package/fesm2022/smarterplan-ngx-smarterplan-core.mjs.map +1 -1
- package/lib/helpers.service.d.ts +43 -0
- package/lib/services/matterport-tag-copy.service.d.ts +137 -17
- package/lib/services/models/domain.service.d.ts +8 -0
- package/lib/services/models/feature.service.d.ts +0 -6
- package/lib/services/models/mission.service.d.ts +5 -0
- package/lib/services/models/space.service.d.ts +15 -1
- package/lib/services/models/visit.service.d.ts +9 -1
- package/lib/services/s3.service.d.ts +8 -0
- package/lib/services/threejs-import.service.d.ts +31 -0
- package/lib/services/threejs.service.d.ts +423 -0
- package/lib/services/viewer.service.d.ts +114 -1
- package/lib/types.service.d.ts +7 -1
- package/package.json +1 -1
- package/public-api.d.ts +2 -0
- package/src/assets/vs-app.json +67 -67
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { removeNullKeysFromObject, parseThreeJsPlacement } from '../helpers.service';
|
|
3
|
+
import { LevelStatus, } from '../types.service';
|
|
4
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
import * as i1 from "./models/navigation.service";
|
|
7
|
+
import * as i2 from "./models/zone.service";
|
|
8
|
+
import * as i3 from "./models/layer.service";
|
|
9
|
+
import * as i4 from "./user.service";
|
|
10
|
+
import * as i5 from "./models/plan.service";
|
|
11
|
+
/** File extensions the Three.js viewer can load as a base model. */
|
|
12
|
+
const SUPPORTED_MODEL_EXTENSIONS = ['.glb', '.gltf'];
|
|
13
|
+
export class ThreeJsImportService {
|
|
14
|
+
navigationService;
|
|
15
|
+
zoneService;
|
|
16
|
+
layerService;
|
|
17
|
+
userService;
|
|
18
|
+
planService;
|
|
19
|
+
_spaceID;
|
|
20
|
+
get spaceID() {
|
|
21
|
+
return this._spaceID;
|
|
22
|
+
}
|
|
23
|
+
set spaceID(value) {
|
|
24
|
+
this._spaceID = value;
|
|
25
|
+
}
|
|
26
|
+
constructor(navigationService, zoneService, layerService, userService, planService) {
|
|
27
|
+
this.navigationService = navigationService;
|
|
28
|
+
this.zoneService = zoneService;
|
|
29
|
+
this.layerService = layerService;
|
|
30
|
+
this.userService = userService;
|
|
31
|
+
this.planService = planService;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Checks that an S3 key points at something the viewer can actually load.
|
|
35
|
+
*
|
|
36
|
+
* Returns the reason it can't, or null when it's fine. This runs before anything is written, so a
|
|
37
|
+
* mistyped key fails on the form rather than creating zones and navigation for a model that will
|
|
38
|
+
* 404 the first time someone opens the visit.
|
|
39
|
+
*/
|
|
40
|
+
validateModelKey(key) {
|
|
41
|
+
if (!key || !key.trim()) {
|
|
42
|
+
return 'A 3D model file (.glb) is required for a Three.js visit.';
|
|
43
|
+
}
|
|
44
|
+
const trimmed = key.trim();
|
|
45
|
+
if (!SUPPORTED_MODEL_EXTENSIONS.some((extension) => trimmed.toLowerCase().endsWith(extension))) {
|
|
46
|
+
return `The 3D model must be a ${SUPPORTED_MODEL_EXTENSIONS.join(' or ')} file.`;
|
|
47
|
+
}
|
|
48
|
+
// A full https:// URL is a signed link that expires; the stored value has to be the key itself
|
|
49
|
+
// so a fresh URL can be signed on every visit.
|
|
50
|
+
if (/^https?:\/\//i.test(trimmed)) {
|
|
51
|
+
return 'Enter the S3 key of the file (e.g. visits/my-model.glb), not a full URL.';
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
async importData(spaceID, surface, reloading = false, node = null, overrideExisting = true, placementMetadata = null) {
|
|
56
|
+
if (reloading) {
|
|
57
|
+
// Reloading is not fully applicable to static 3D models the same way as Matterport
|
|
58
|
+
return Promise.resolve(true);
|
|
59
|
+
}
|
|
60
|
+
const keyError = this.validateModelKey(node?.model3D);
|
|
61
|
+
if (keyError) {
|
|
62
|
+
return Promise.reject(new Error(keyError));
|
|
63
|
+
}
|
|
64
|
+
this.spaceID = spaceID;
|
|
65
|
+
const zones = await this.zoneService.getZonesBySpace(spaceID);
|
|
66
|
+
const mainZone = zones.find((z) => !z.parentID);
|
|
67
|
+
if (!mainZone) {
|
|
68
|
+
return Promise.reject(new Error('Missing data (no main Building Zone)'));
|
|
69
|
+
}
|
|
70
|
+
console.log('[ThreeJsImportService] Importing data for Three.js model');
|
|
71
|
+
// 1. Check/create layer of building type
|
|
72
|
+
const layerBuilding = await this.getLayerByName('BUILDING');
|
|
73
|
+
// We generate a dummy ID to act as our single "sweep" equivalent
|
|
74
|
+
const dummySweepID = uuidv4();
|
|
75
|
+
// 2. Create the default Zone
|
|
76
|
+
const createdDefaultZone = await this.createZone(node.metadata || 'Three.js 3D Model', layerBuilding.id, surface, mainZone.id, [dummySweepID], node);
|
|
77
|
+
if (!createdDefaultZone) {
|
|
78
|
+
return Promise.resolve(false);
|
|
79
|
+
}
|
|
80
|
+
// 3. Create a blank Plan for the model (to ensure consistency in the app structure)
|
|
81
|
+
const plan = {
|
|
82
|
+
name: `plan_threejs_${node.id}`,
|
|
83
|
+
annexe: '', // No floorplan image generated automatically yet
|
|
84
|
+
zoneID: createdDefaultZone.id,
|
|
85
|
+
spaceID: this.spaceID,
|
|
86
|
+
isCurrentForZone: true,
|
|
87
|
+
isModified: false,
|
|
88
|
+
isImportedMatterport: false, // Explicitly not matterport
|
|
89
|
+
};
|
|
90
|
+
await this.planService.createPlan(plan);
|
|
91
|
+
// 4. Create the single Navigation entry this model is viewed from.
|
|
92
|
+
// Matterport derives these from its sweeps; a static model has no sweeps, so the placement
|
|
93
|
+
// comes from the metadata entered on the form, falling back to the origin.
|
|
94
|
+
const placement = parseThreeJsPlacement(placementMetadata);
|
|
95
|
+
const origin = { x: 0, y: 0, z: 0 };
|
|
96
|
+
const navigationInput = {
|
|
97
|
+
matterportSweepID: dummySweepID,
|
|
98
|
+
position: JSON.stringify(placement?.cameraPosition ?? origin),
|
|
99
|
+
rotation: JSON.stringify(placement?.rotation ?? origin),
|
|
100
|
+
level: LevelStatus.LOW,
|
|
101
|
+
nodeID: node.id,
|
|
102
|
+
spaceID,
|
|
103
|
+
};
|
|
104
|
+
const nav = await this.navigationService.createNavigation(navigationInput);
|
|
105
|
+
if (!nav) {
|
|
106
|
+
console.log('Could not create navigation for', navigationInput);
|
|
107
|
+
}
|
|
108
|
+
console.log('[ThreeJsImportService] Import done.');
|
|
109
|
+
return Promise.resolve(true);
|
|
110
|
+
}
|
|
111
|
+
async createZone(name, layerID, surface = null, parentID = null, sweeps = [], node = null, metadata = null) {
|
|
112
|
+
const zoneInput = {
|
|
113
|
+
name,
|
|
114
|
+
spaceID: this.spaceID,
|
|
115
|
+
layerID,
|
|
116
|
+
sweepIDs: sweeps,
|
|
117
|
+
nodeIDs: node ? [node.id] : null,
|
|
118
|
+
};
|
|
119
|
+
removeNullKeysFromObject(zoneInput);
|
|
120
|
+
if (surface) {
|
|
121
|
+
zoneInput.surface = surface;
|
|
122
|
+
}
|
|
123
|
+
if (parentID) {
|
|
124
|
+
zoneInput.parentID = parentID;
|
|
125
|
+
}
|
|
126
|
+
if (metadata) {
|
|
127
|
+
zoneInput.metadata = metadata;
|
|
128
|
+
}
|
|
129
|
+
const newLocal = await this.zoneService.create(zoneInput);
|
|
130
|
+
return newLocal;
|
|
131
|
+
}
|
|
132
|
+
async getLayerByName(name) {
|
|
133
|
+
const mission = this.userService.currentMission(this.spaceID);
|
|
134
|
+
const currentOrgId = mission.organisationID;
|
|
135
|
+
const layers = await this.layerService.getLayerByNameForOrganisation(name, currentOrgId);
|
|
136
|
+
if (layers.length > 0) {
|
|
137
|
+
return layers[0];
|
|
138
|
+
}
|
|
139
|
+
// Create it if it doesn't exist
|
|
140
|
+
return this.layerService.createLayerForOrganisation(name, currentOrgId);
|
|
141
|
+
}
|
|
142
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ThreeJsImportService, deps: [{ token: i1.NavigationService }, { token: i2.ZoneService }, { token: i3.LayerService }, { token: i4.BaseUserService }, { token: i5.PlanService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
143
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ThreeJsImportService, providedIn: 'root' });
|
|
144
|
+
}
|
|
145
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ThreeJsImportService, decorators: [{
|
|
146
|
+
type: Injectable,
|
|
147
|
+
args: [{
|
|
148
|
+
providedIn: 'root',
|
|
149
|
+
}]
|
|
150
|
+
}], ctorParameters: () => [{ type: i1.NavigationService }, { type: i2.ZoneService }, { type: i3.LayerService }, { type: i4.BaseUserService }, { type: i5.PlanService }] });
|
|
151
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGhyZWVqcy1pbXBvcnQuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1zbWFydGVycGxhbi1jb3JlL3NyYy9saWIvc2VydmljZXMvdGhyZWVqcy1pbXBvcnQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxxQkFBcUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3JGLE9BQU8sRUFDTCxXQUFXLEdBTVosTUFBTSxrQkFBa0IsQ0FBQztBQU0xQixPQUFPLEVBQUUsRUFBRSxJQUFJLE1BQU0sRUFBRSxNQUFNLE1BQU0sQ0FBQzs7Ozs7OztBQUVwQyxvRUFBb0U7QUFDcEUsTUFBTSwwQkFBMEIsR0FBRyxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQztBQUtyRCxNQUFNLE9BQU8sb0JBQW9CO0lBWXJCO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFmRixRQUFRLENBQVM7SUFFekIsSUFBVyxPQUFPO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUN2QixDQUFDO0lBRUQsSUFBVyxPQUFPLENBQUMsS0FBYTtRQUM5QixJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQztJQUN4QixDQUFDO0lBRUQsWUFDVSxpQkFBb0MsRUFDcEMsV0FBd0IsRUFDeEIsWUFBMEIsRUFDMUIsV0FBNEIsRUFDNUIsV0FBd0I7UUFKeEIsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFtQjtRQUNwQyxnQkFBVyxHQUFYLFdBQVcsQ0FBYTtRQUN4QixpQkFBWSxHQUFaLFlBQVksQ0FBYztRQUMxQixnQkFBVyxHQUFYLFdBQVcsQ0FBaUI7UUFDNUIsZ0JBQVcsR0FBWCxXQUFXLENBQWE7SUFDL0IsQ0FBQztJQUVKOzs7Ozs7T0FNRztJQUNILGdCQUFnQixDQUFDLEdBQVc7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QUNELGdDQUFnQztRQUNoQyxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsMEJBQTBCLENBQUMsSUFBSSxFQUFFLFlBQVksQ0FBQyxDQUFDO0lBQzFFLENBQUM7d0dBeEtVLG9CQUFvQjs0R0FBcEIsb0JBQW9CLGNBRm5CLE1BQU07OzRGQUVQLG9CQUFvQjtrQkFIaEMsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyByZW1vdmVOdWxsS2V5c0Zyb21PYmplY3QsIHBhcnNlVGhyZWVKc1BsYWNlbWVudCB9IGZyb20gJy4uL2hlbHBlcnMuc2VydmljZSc7XG5pbXBvcnQge1xuICBMZXZlbFN0YXR1cyxcbiAgTGF5ZXIsXG4gIE5vZGUsXG4gIFpvbmUsXG4gIE5hdmlnYXRpb24sXG4gIFBsYW4sXG59IGZyb20gJy4uL3R5cGVzLnNlcnZpY2UnO1xuaW1wb3J0IHsgTGF5ZXJTZXJ2aWNlIH0gZnJvbSAnLi9tb2RlbHMvbGF5ZXIuc2VydmljZSc7XG5pbXBvcnQgeyBOYXZpZ2F0aW9uU2VydmljZSB9IGZyb20gJy4vbW9kZWxzL25hdmlnYXRpb24uc2VydmljZSc7XG5pbXBvcnQgeyBQbGFuU2VydmljZSB9IGZyb20gJy4vbW9kZWxzL3BsYW4uc2VydmljZSc7XG5pbXBvcnQgeyBab25lU2VydmljZSB9IGZyb20gJy4vbW9kZWxzL3pvbmUuc2VydmljZSc7XG5pbXBvcnQgeyBCYXNlVXNlclNlcnZpY2UgfSBmcm9tICcuL3VzZXIuc2VydmljZSc7XG5pbXBvcnQgeyB2NCBhcyB1dWlkdjQgfSBmcm9tICd1dWlkJztcblxuLyoqIEZpbGUgZXh0ZW5zaW9ucyB0aGUgVGhyZWUuanMgdmlld2VyIGNhbiBsb2FkIGFzIGEgYmFzZSBtb2RlbC4gKi9cbmNvbnN0IFNVUFBPUlRFRF9NT0RFTF9FWFRFTlNJT05TID0gWycuZ2xiJywgJy5nbHRmJ107XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBUaHJlZUpzSW1wb3J0U2VydmljZSB7XG4gIHByaXZhdGUgX3NwYWNlSUQ6IHN0cmluZztcblxuICBwdWJsaWMgZ2V0IHNwYWNlSUQoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5fc3BhY2VJRDtcbiAgfVxuXG4gIHB1YmxpYyBzZXQgc3BhY2VJRCh2YWx1ZTogc3RyaW5nKSB7XG4gICAgdGhpcy5fc3BhY2VJRCA9IHZhbHVlO1xuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBuYXZpZ2F0aW9uU2VydmljZTogTmF2aWdhdGlvblNlcnZpY2UsXG4gICAgcHJpdmF0ZSB6b25lU2VydmljZTogWm9uZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBsYXllclNlcnZpY2U6IExheWVyU2VydmljZSxcbiAgICBwcml2YXRlIHVzZXJTZXJ2aWNlOiBCYXNlVXNlclNlcnZpY2UsXG4gICAgcHJpdmF0ZSBwbGFuU2VydmljZTogUGxhblNlcnZpY2VcbiAgKSB7fVxuXG4gIC8qKlxuICAgKiBDaGVja3MgdGhhdCBhbiBTMyBrZXkgcG9pbnRzIGF0IHNvbWV0aGluZyB0aGUgdmlld2VyIGNhbiBhY3R1YWxseSBsb2FkLlxuICAgKlxuICAgKiBSZXR1cm5zIHRoZSByZWFzb24gaXQgY2FuJ3QsIG9yIG51bGwgd2hlbiBpdCdzIGZpbmUuIFRoaXMgcnVucyBiZWZvcmUgYW55dGhpbmcgaXMgd3JpdHRlbiwgc28gYVxuICAgKiBtaXN0eXBlZCBrZXkgZmFpbHMgb24gdGhlIGZvcm0gcmF0aGVyIHRoYW4gY3JlYXRpbmcgem9uZXMgYW5kIG5hdmlnYXRpb24gZm9yIGEgbW9kZWwgdGhhdCB3aWxsXG4gICAqIDQwNCB0aGUgZmlyc3QgdGltZSBzb21lb25lIG9wZW5zIHRoZSB2aXNpdC5cbiAgICovXG4gIHZhbGlkYXRlTW9kZWxLZXkoa2V5OiBzdHJpbmcpOiBzdHJpbmcgfCBudWxsIHtcbiAgICBpZiAoIWtleSB8fCAha2V5LnRyaW0oKSkge1xuICAgICAgcmV0dXJuICdBIDNEIG1vZGVsIGZpbGUgKC5nbGIpIGlzIHJlcXVpcmVkIGZvciBhIFRocmVlLmpzIHZpc2l0Lic7XG4gICAgfVxuICAgIGNvbnN0IHRyaW1tZWQgPSBrZXkudHJpbSgpO1xuICAgIGlmICghU1VQUE9SVEVEX01PREVMX0VYVEVOU0lPTlMuc29tZSgoZXh0ZW5zaW9uKSA9PiB0cmltbWVkLnRvTG93ZXJDYXNlKCkuZW5kc1dpdGgoZXh0ZW5zaW9uKSkpIHtcbiAgICAgIHJldHVybiBgVGhlIDNEIG1vZGVsIG11c3QgYmUgYSAke1NVUFBPUlRFRF9NT0RFTF9FWFRFTlNJT05TLmpvaW4oJyBvciAnKX0gZmlsZS5gO1xuICAgIH1cbiAgICAvLyBBIGZ1bGwgaHR0cHM6Ly8gVVJMIGlzIGEgc2lnbmVkIGxpbmsgdGhhdCBleHBpcmVzOyB0aGUgc3RvcmVkIHZhbHVlIGhhcyB0byBiZSB0aGUga2V5IGl0c2VsZlxuICAgIC8vIHNvIGEgZnJlc2ggVVJMIGNhbiBiZSBzaWduZWQgb24gZXZlcnkgdmlzaXQuXG4gICAgaWYgKC9eaHR0cHM/OlxcL1xcLy9pLnRlc3QodHJpbW1lZCkpIHtcbiAgICAgIHJldHVybiAnRW50ZXIgdGhlIFMzIGtleSBvZiB0aGUgZmlsZSAoZS5nLiB2aXNpdHMvbXktbW9kZWwuZ2xiKSwgbm90IGEgZnVsbCBVUkwuJztcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBhc3luYyBpbXBvcnREYXRhKFxuICAgIHNwYWNlSUQ6IHN0cmluZyxcbiAgICBzdXJmYWNlOiBudW1iZXIsXG4gICAgcmVsb2FkaW5nOiBib29sZWFuID0gZmFsc2UsXG4gICAgbm9kZTogTm9kZSA9IG51bGwsXG4gICAgb3ZlcnJpZGVFeGlzdGluZyA9IHRydWUsXG4gICAgcGxhY2VtZW50TWV0YWRhdGE6IHN0cmluZyA9IG51bGxcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgaWYgKHJlbG9hZGluZykge1xuICAgICAgLy8gUmVsb2FkaW5nIGlzIG5vdCBmdWxseSBhcHBsaWNhYmxlIHRvIHN0YXRpYyAzRCBtb2RlbHMgdGhlIHNhbWUgd2F5IGFzIE1hdHRlcnBvcnRcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodHJ1ZSk7XG4gICAgfVxuXG4gICAgY29uc3Qga2V5RXJyb3IgPSB0aGlzLnZhbGlkYXRlTW9kZWxLZXkobm9kZT8ubW9kZWwzRCk7XG4gICAgaWYgKGtleUVycm9yKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKGtleUVycm9yKSk7XG4gICAgfVxuXG4gICAgdGhpcy5zcGFjZUlEID0gc3BhY2VJRDtcbiAgICBjb25zdCB6b25lcyA9IGF3YWl0IHRoaXMuem9uZVNlcnZpY2UuZ2V0Wm9uZXNCeVNwYWNlKHNwYWNlSUQpO1xuICAgIGNvbnN0IG1haW5ab25lID0gem9uZXMuZmluZCgoeikgPT4gIXoucGFyZW50SUQpO1xuICAgIGlmICghbWFpblpvbmUpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoJ01pc3NpbmcgZGF0YSAobm8gbWFpbiBCdWlsZGluZyBab25lKScpKTtcbiAgICB9XG5cbiAgICBjb25zb2xlLmxvZygnW1RocmVlSnNJbXBvcnRTZXJ2aWNlXSBJbXBvcnRpbmcgZGF0YSBmb3IgVGhyZWUuanMgbW9kZWwnKTtcblxuICAgIC8vIDEuIENoZWNrL2NyZWF0ZSBsYXllciBvZiBidWlsZGluZyB0eXBlXG4gICAgY29uc3QgbGF5ZXJCdWlsZGluZyA9IGF3YWl0IHRoaXMuZ2V0TGF5ZXJCeU5hbWUoJ0JVSUxESU5HJyk7XG4gICAgXG4gICAgLy8gV2UgZ2VuZXJhdGUgYSBkdW1teSBJRCB0byBhY3QgYXMgb3VyIHNpbmdsZSBcInN3ZWVwXCIgZXF1aXZhbGVudFxuICAgIGNvbnN0IGR1bW15U3dlZXBJRCA9IHV1aWR2NCgpO1xuXG4gICAgLy8gMi4gQ3JlYXRlIHRoZSBkZWZhdWx0IFpvbmVcbiAgICBjb25zdCBjcmVhdGVkRGVmYXVsdFpvbmUgPSBhd2FpdCB0aGlzLmNyZWF0ZVpvbmUoXG4gICAgICBub2RlLm1ldGFkYXRhIHx8ICdUaHJlZS5qcyAzRCBNb2RlbCcsXG4gICAgICBsYXllckJ1aWxkaW5nLmlkLFxuICAgICAgc3VyZmFjZSxcbiAgICAgIG1haW5ab25lLmlkLFxuICAgICAgW2R1bW15U3dlZXBJRF0sXG4gICAgICBub2RlXG4gICAgKTtcblxuICAgIGlmICghY3JlYXRlZERlZmF1bHRab25lKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcbiAgICB9XG5cbiAgICAvLyAzLiBDcmVhdGUgYSBibGFuayBQbGFuIGZvciB0aGUgbW9kZWwgKHRvIGVuc3VyZSBjb25zaXN0ZW5jeSBpbiB0aGUgYXBwIHN0cnVjdHVyZSlcbiAgICBjb25zdCBwbGFuID0ge1xuICAgICAgbmFtZTogYHBsYW5fdGhyZWVqc18ke25vZGUuaWR9YCxcbiAgICAgIGFubmV4ZTogJycsIC8vIE5vIGZsb29ycGxhbiBpbWFnZSBnZW5lcmF0ZWQgYXV0b21hdGljYWxseSB5ZXRcbiAgICAgIHpvbmVJRDogY3JlYXRlZERlZmF1bHRab25lLmlkLFxuICAgICAgc3BhY2VJRDogdGhpcy5zcGFjZUlELFxuICAgICAgaXNDdXJyZW50Rm9yWm9uZTogdHJ1ZSxcbiAgICAgIGlzTW9kaWZpZWQ6IGZhbHNlLFxuICAgICAgaXNJbXBvcnRlZE1hdHRlcnBvcnQ6IGZhbHNlLCAvLyBFeHBsaWNpdGx5IG5vdCBtYXR0ZXJwb3J0XG4gICAgfSBhcyBQbGFuO1xuICAgIGF3YWl0IHRoaXMucGxhblNlcnZpY2UuY3JlYXRlUGxhbihwbGFuKTtcblxuICAgIC8vIDQuIENyZWF0ZSB0aGUgc2luZ2xlIE5hdmlnYXRpb24gZW50cnkgdGhpcyBtb2RlbCBpcyB2aWV3ZWQgZnJvbS5cbiAgICAvLyBNYXR0ZXJwb3J0IGRlcml2ZXMgdGhlc2UgZnJvbSBpdHMgc3dlZXBzOyBhIHN0YXRpYyBtb2RlbCBoYXMgbm8gc3dlZXBzLCBzbyB0aGUgcGxhY2VtZW50XG4gICAgLy8gY29tZXMgZnJvbSB0aGUgbWV0YWRhdGEgZW50ZXJlZCBvbiB0aGUgZm9ybSwgZmFsbGluZyBiYWNrIHRvIHRoZSBvcmlnaW4uXG4gICAgY29uc3QgcGxhY2VtZW50ID0gcGFyc2VUaHJlZUpzUGxhY2VtZW50KHBsYWNlbWVudE1ldGFkYXRhKTtcbiAgICBjb25zdCBvcmlnaW4gPSB7IHg6IDAsIHk6IDAsIHo6IDAgfTtcbiAgICBjb25zdCBuYXZpZ2F0aW9uSW5wdXQgPSB7XG4gICAgICBtYXR0ZXJwb3J0U3dlZXBJRDogZHVtbXlTd2VlcElELFxuICAgICAgcG9zaXRpb246IEpTT04uc3RyaW5naWZ5KHBsYWNlbWVudD8uY2FtZXJhUG9zaXRpb24gPz8gb3JpZ2luKSxcbiAgICAgIHJvdGF0aW9uOiBKU09OLnN0cmluZ2lmeShwbGFjZW1lbnQ/LnJvdGF0aW9uID8/IG9yaWdpbiksXG4gICAgICBsZXZlbDogTGV2ZWxTdGF0dXMuTE9XLFxuICAgICAgbm9kZUlEOiBub2RlLmlkLFxuICAgICAgc3BhY2VJRCxcbiAgICB9IGFzIE5hdmlnYXRpb247XG4gICAgXG4gICAgY29uc3QgbmF2ID0gYXdhaXQgdGhpcy5uYXZpZ2F0aW9uU2VydmljZS5jcmVhdGVOYXZpZ2F0aW9uKG5hdmlnYXRpb25JbnB1dCk7XG4gICAgaWYgKCFuYXYpIHtcbiAgICAgIGNvbnNvbGUubG9nKCdDb3VsZCBub3QgY3JlYXRlIG5hdmlnYXRpb24gZm9yJywgbmF2aWdhdGlvbklucHV0KTtcbiAgICB9XG5cbiAgICBjb25zb2xlLmxvZygnW1RocmVlSnNJbXBvcnRTZXJ2aWNlXSBJbXBvcnQgZG9uZS4nKTtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRydWUpO1xuICB9XG5cbiAgYXN5bmMgY3JlYXRlWm9uZShcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgbGF5ZXJJRDogc3RyaW5nLFxuICAgIHN1cmZhY2U6IG51bWJlciA9IG51bGwsXG4gICAgcGFyZW50SUQ6IHN0cmluZyA9IG51bGwsXG4gICAgc3dlZXBzOiBzdHJpbmdbXSA9IFtdLFxuICAgIG5vZGU6IE5vZGUgPSBudWxsLFxuICAgIG1ldGFkYXRhOiBzdHJpbmcgPSBudWxsXG4gICk6IFByb21pc2U8Wm9uZT4ge1xuICAgIGNvbnN0IHpvbmVJbnB1dCA9IHtcbiAgICAgIG5hbWUsXG4gICAgICBzcGFjZUlEOiB0aGlzLnNwYWNlSUQsXG4gICAgICBsYXllcklELFxuICAgICAgc3dlZXBJRHM6IHN3ZWVwcyxcbiAgICAgIG5vZGVJRHM6IG5vZGUgPyBbbm9kZS5pZF0gOiBudWxsLFxuICAgIH0gYXMgWm9uZTtcbiAgICBcbiAgICByZW1vdmVOdWxsS2V5c0Zyb21PYmplY3Qoem9uZUlucHV0KTtcbiAgICBpZiAoc3VyZmFjZSkge1xuICAgICAgem9uZUlucHV0LnN1cmZhY2UgPSBzdXJmYWNlO1xuICAgIH1cbiAgICBpZiAocGFyZW50SUQpIHtcbiAgICAgIHpvbmVJbnB1dC5wYXJlbnRJRCA9IHBhcmVudElEO1xuICAgIH1cbiAgICBpZiAobWV0YWRhdGEpIHtcbiAgICAgIHpvbmVJbnB1dC5tZXRhZGF0YSA9IG1ldGFkYXRhO1xuICAgIH1cbiAgICBcbiAgICBjb25zdCBuZXdMb2NhbCA9IGF3YWl0IHRoaXMuem9uZVNlcnZpY2UuY3JlYXRlKHpvbmVJbnB1dCk7XG4gICAgcmV0dXJuIG5ld0xvY2FsO1xuICB9XG5cbiAgYXN5bmMgZ2V0TGF5ZXJCeU5hbWUobmFtZTogc3RyaW5nKTogUHJvbWlzZTxMYXllcj4ge1xuICAgIGNvbnN0IG1pc3Npb24gPSB0aGlzLnVzZXJTZXJ2aWNlLmN1cnJlbnRNaXNzaW9uKHRoaXMuc3BhY2VJRCk7XG4gICAgY29uc3QgY3VycmVudE9yZ0lkID0gbWlzc2lvbi5vcmdhbmlzYXRpb25JRDtcbiAgICBjb25zdCBsYXllcnMgPSBhd2FpdCB0aGlzLmxheWVyU2VydmljZS5nZXRMYXllckJ5TmFtZUZvck9yZ2FuaXNhdGlvbihcbiAgICAgIG5hbWUsXG4gICAgICBjdXJyZW50T3JnSWRcbiAgICApO1xuICAgIGlmIChsYXllcnMubGVuZ3RoID4gMCkge1xuICAgICAgcmV0dXJuIGxheWVyc1swXTtcbiAgICB9XG4gICAgLy8gQ3JlYXRlIGl0IGlmIGl0IGRvZXNuJ3QgZXhpc3RcbiAgICByZXR1cm4gdGhpcy5sYXllclNlcnZpY2UuY3JlYXRlTGF5ZXJGb3JPcmdhbmlzYXRpb24obmFtZSwgY3VycmVudE9yZ0lkKTtcbiAgfVxufVxuIl19
|