@smarterplan/ngx-smarterplan-locations 0.4.20 → 0.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.
@@ -122,7 +122,10 @@ export class VisitsComponent {
122
122
  .getVisitsForSpaceForUser(this.spaceId)
123
123
  .then((visits) => {
124
124
  if (visits) {
125
- this.visits = visits;
125
+ // 3D models share this storage but have their own screen, so listing them here
126
+ // too showed every model twice. They can still be created from this form; they
127
+ // just belong to the other tab once they exist.
128
+ this.visits = visits.filter((visit) => visit.viewer !== CaptureViewer.THREEJS);
126
129
  }
127
130
  });
128
131
  }
@@ -320,4 +323,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
320
323
  type: ViewChild,
321
324
  args: ['content', { static: false }]
322
325
  }] } });
323
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlzaXRzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1zbWFydGVycGxhbi1sb2NhdGlvbnMvc3JjL2xpYi9jb21wb25lbnRzL3Zpc2l0cy92aXNpdHMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXNtYXJ0ZXJwbGFuLWxvY2F0aW9ucy9zcmMvbGliL2NvbXBvbmVudHMvdmlzaXRzL3Zpc2l0cy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFVLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM3RCxPQUFPLEVBR0gsVUFBVSxHQUViLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEIsT0FBTyxFQUFZLG1CQUFtQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDM0UsT0FBTyxFQVVILGFBQWEsR0FJaEIsTUFBTSxtQ0FBbUMsQ0FBQztBQUUzQyxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQzs7Ozs7Ozs7OztBQU8xQyxNQUFNLE9BQU8sZUFBZTtJQXdDWjtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDRDtJQUNDO0lBQ0E7SUFDQTtJQW5EWixPQUFPLENBQVM7SUFFaEIsaUJBQWlCLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFFdkIsU0FBUyxDQUFtQjtJQUU1QixTQUFTLEdBQVksS0FBSyxDQUFDO0lBRTNCLGNBQWMsR0FBWSxLQUFLLENBQUM7SUFFaEMsV0FBVyxDQUFTO0lBRXBCLFlBQVksR0FBRyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQVMsQ0FBQztJQUVwQyxNQUFNLEdBQVksRUFBRSxDQUFDO0lBRXJCLFdBQVcsQ0FBUztJQUU2QixPQUFPLENBQUM7SUFFekQsY0FBYyxDQUFNO0lBRXBCLGVBQWUsR0FBRyxLQUFL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LENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsS0FBSyxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQ3ZILENBQUM7SUFFRCxXQUFXLENBQUMsT0FBTztRQUNmLE9BQU8sT0FBTyxJQUFJLE9BQU8sQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQztJQUN4RCxDQUFDO3dHQXZXUSxlQUFlOzRGQUFmLGVBQWUsc0pDaEM1Qix3elVBaUtNOzs0RkRqSU8sZUFBZTtrQkFMM0IsU0FBUzsrQkFDSSxZQUFZO29iQXVCMkIsT0FBTztzQkFBdkQsU0FBUzt1QkFBQyxTQUFTLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgICBVbnR5cGVkRm9ybUdyb3VwLFxuICAgIFVudHlwZWRGb3JtQnVpbGRlcixcbiAgICBWYWxpZGF0b3JzLFxuICAgIEFic3RyYWN0Q29udHJvbCxcbn0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGUsIFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBOZ2JNb2RhbCwgTW9kYWxEaXNtaXNzUmVhc29ucyB9IGZyb20gJ0BuZy1ib290c3RyYXAvbmctYm9vdHN0cmFwJztcbmltcG9ydCB7XG4gICAgTm9kZSxcbiAgICBWaXNpdCxcbiAgICBNZW51SXRlbSxcbiAgICBNYXR0ZXJwb3J0SW1wb3J0U2VydmljZSxcbiAgICBUaHJlZUpzSW1wb3J0U2VydmljZSxcbiAgICBDYXB0dXJlU2VydmljZSxcbiAgICBOb2RlU2VydmljZSxcbiAgICBTcGFjZVNlcnZpY2UsXG4gICAgVmlzaXRTZXJ2aWNlLFxuICAgIENhcHR1cmVWaWV3ZXIsXG4gICAgQ2FwdHVyZSxcbiAgICBWYWxpZGF0b3JzU2VydmljZSxcbiAgICBOYXZpZ2F0b3JTZXJ2aWNlLFxufSBmcm9tICdAc21hcnRlcnBsYW4vbmd4LXNtYXJ0ZXJwbGFuLWNvcmUnO1xuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHsgU3ViamVjdCwgdGFrZVVudGlsIH0gZnJvbSAncnhqcyc7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnbGliLXZpc2l0cycsXG4gICAgdGVtcGxhdGVVcmw6ICcuL3Zpc2l0cy5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vdmlzaXRzLmNvbXBvbmVudC5zY3NzJ10sXG59KVxuZXhwb3J0IGNsYXNzIFZpc2l0c0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gICAgc3BhY2VJZDogc3RyaW5nO1xuXG4gICAgdmlzaXRJbmRleERldGFpbHMgPSAtMTtcblxuICAgIHZpc2l0Rm9ybTogVW50eXBlZEZvcm1Hcm91cDtcblxuICAgIGlzRWRpdGluZzogYm9vbGVhbiA9IGZhbHNlO1xuXG4gICAgdmlzaXRTdWJtaXR0ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIGNhcHR1cmVEYXRlOiBudW1iZXI7XG5cbiAgICBjdXJyZW50U3BhY2UgPSB7IHpvbmVzOiBbXSB9IGFzIGFueTtcblxuICAgIHZpc2l0czogVmlzaXRbXSA9IFtdO1xuXG4gICAgY2xvc2VSZXN1bHQ6IHN0cmluZztcblxuICAgIEBWaWV3Q2hpbGQoJ2NvbnRlbnQnLCB7IHN0YXRpYzogZmFsc2UgfSkgcHJpdmF0ZSBjb250ZW50O1xuXG4gICAgbW9kYWxSZWZlcmVuY2U6IGFueTtcblxuICAgIGNhbkNhbmNlbEltcG9ydCA9IGZhbHNlO1xuXG4gICAgaW1hZ2VzUHJvY2Vzc2VkOiBudW1iZXIgPSAwO1xuXG4gICAgdG90YWxJbWFnZXM6IG51bWJlciA9IDA7XG5cbiAgICBpbWFnZXNVcGxvYWRlZDogbnVtYmVyID0gMDtcblxuICAgIG1lbnVJdGVtczogTWVudUl0ZW1bXSA9IFtdO1xuXG4gICAgZXJyb3JGb3JtOiBib29sZWFuID0gZmFsc2U7XG5cbiAgICBpc1Byb2Nlc3NpbmcgPSBmYWxzZTtcblxuICAgIGRlc3Ryb3kkID0gbmV3IFN1YmplY3QoKTtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcml2YXRlIGZiOiBVbnR5cGVkRm9ybUJ1aWxkZXIsXG4gICAgICAgIHByaXZhdGUgbWF0dGVycG9ydEltcG9ydFNlcnZpY2U6IE1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHRocmVlanNJbXBvcnRTZXJ2aWNlOiBUaHJlZUpzSW1wb3J0U2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBjYXB0dXJlU2VydmljZTogQ2FwdHVyZVNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgbm9kZVNlcnZpY2U6IE5vZGVTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHNwYWNlU2VydmljZTogU3BhY2VTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHJvdXRlOiBBY3RpdmF0ZWRSb3V0ZSxcbiAgICAgICAgcHJpdmF0ZSBtb2RhbFNlcnZpY2U6IE5nYk1vZGFsLFxuICAgICAgICBwcml2YXRlIHZpc2l0U2VydmljZTogVmlzaXRTZXJ2aWNlLFxuICAgICAgICBwdWJsaWMgdmFsaWRhdG9yc1NlcnZpY2U6IFZhbGlkYXRvcnNTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHRyYW5zbGF0ZTogVHJhbnNsYXRlU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBuYXZpZ2F0b3JTZXJ2aWNlOiBOYXZpZ2F0b3JTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHJvdXRlcjogUm91dGVyLFxuICAgICkge1xuICAgICAgICB0aGlzLm1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLmltcG9ydGluZ0ltYWdlcy5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2FuQ2FuY2VsSW1wb3J0ID0gdHJ1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubWF0dGVycG9ydEltcG9ydFNlcnZpY2Uuc3dlZXBQcm9jZXNzZWRDb3VudC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKChjb3VudCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5pbWFnZXNQcm9jZXNzZWQgPSBjb3VudCArIDE7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLnRvdGFsU3dlZXBzQ291bnQucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSgoY291bnQpID0+IHtcbiAgICAgICAgICAgIHRoaXMudG90YWxJbWFnZXMgPSBjb3VudDtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5uYXZpZ2F0b3JTZXJ2aWNlLmxvY2F0aW9uSURDaGFuZ2VcbiAgICAgICAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSlcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoKHNwYWNlSUQpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbXCJkYXNoYm9hcmQvbG9jYWxpc2F0aW9uXCIsIHNwYWNlSUQsIFwidmlzaXRzXCJdKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMucm91dGUucGFyYW1zLnN1YnNjcmliZSgocGFyYW1zKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnNwYWNlSWQgPSBwYXJhbXMuaWQ7XG4gICAgICAgICAgICB0aGlzLnJlc2V0VmlzaXRzKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGFzeW5jIG5nT25Jbml0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLnNwYWNlSWQgPSB0aGlzLnJvdXRlLnNuYXBzaG90LnBhcmFtTWFwLmdldCgnaWQnKTtcbiAgICAgICAgYXdhaXQgdGhpcy5yZXNldFZpc2l0cygpO1xuICAgIH1cblxuICAgIG5nT25EZXN0cm95KCkge1xuICAgICAgICB0aGlzLmRlc3Ryb3kkLm5leHQodHJ1ZSk7XG4gICAgICAgIHRoaXMuZGVzdHJveSQuY29tcGxldGUoKTtcbiAgICB9XG5cbiAgICAvKlxuICAgIFZpc2l0ID0ge1xuICAgICAgY2FwdHVyZUlEOiBzdHJpbmcsXG4gICAgICBtb2RlbDNkOiBzdHJpbmcsXG4gICAgICB0YWtlbkF0OiBudW1iZXIsXG4gICAgICBzcGFjZUlEOiBzdHJpbmcsXG4gICAgICB2aWV3ZXI6IENhcHR1cmVWaWV3ZXIsXG4gICAgICBzdXJmYWNlOiBudW1iZXIsXG4gICAgICBub2RlOiBOb2RlLFxuICAgICAgbmFtZT86IHN0cmluZyB8IG51bGxcbiAgICB9XG4gICAgKi9cbiAgICBzZXR1cE1lbnVJdGVtcygpIHtcbiAgICAgICAgdGhpcy5tZW51SXRlbXMgPSBbXG4gICAgICAgICAgICB7IGxhYmVsOiAnTG9jYXRpb25zJywgdXJsOiAnL2xvY2FsaXNhdGlvbicgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBsYWJlbDogdGhpcy5jdXJyZW50U3BhY2UubmFtZSxcbiAgICAgICAgICAgICAgICB1cmw6IGAvbG9jYWxpc2F0aW9uLyR7dGhpcy5jdXJyZW50U3BhY2UuaWR9YCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbGFiZWw6ICdWaXJ0dWFsIHZpc2l0cycsXG4gICAgICAgICAgICAgICAgdXJsOiBgL2xvY2FsaXNhdGlvbi8ke3RoaXMuY3VycmVudFNwYWNlLmlkfS92aXNpdHNgLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgXTtcbiAgICB9XG5cbiAgICBvbkdvQmFjaygpIHtcbiAgICAgICAgdGhpcy5vbkNhbmNlbCgpO1xuICAgIH1cblxuICAgIGFzeW5jIHJlc2V0VmlzaXRzKCkge1xuICAgICAgICB0aGlzLnZpc2l0cyA9IFtdO1xuICAgICAgICB0aGlzLmN1cnJlbnRTcGFjZSA9IGF3YWl0IHRoaXMuc3BhY2VTZXJ2aWNlLmdldFNwYWNlKHRoaXMuc3BhY2VJZCk7XG4gICAgICAgIHRoaXMuc2V0dXBNZW51SXRlbXMoKTtcbiAgICAgICAgYXdhaXQgdGhpcy52aXNpdFNlcnZpY2VcbiAgICAgICAgICAgIC5nZXRWaXNpdHNGb3JTcGFjZUZvclVzZXIodGhpcy5zcGFjZUlkKVxuICAgICAgICAgICAgLnRoZW4oKHZpc2l0cykgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh2aXNpdHMpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy52aXNpdHMgPSB2aXNpdHM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgaW5pdFZpc2l0Rm9ybShpbnB1dDogVmlzaXQgPSBudWxsKSB7XG4gICAgICAgIGlmIChpbnB1dCkge1xuICAgICAgICAgICAgdGhpcy52aXNpdEZvcm0gPSB0aGlzLmZiLmdyb3VwKHtcbiAgICAgICAgICAgICAgICBjYXB0dXJlSUQ6IGlucHV0LmNhcHR1cmVJRCxcbiAgICAgICAgICAgICAgICBub2RlSUQ6IGlucHV0Lm5vZGUuaWQsXG4gICAgICAgICAgICAgICAgbmFtZTogW2lucHV0Lm5hbWUsIFtWYWxpZGF0b3JzLnJlcXVpcmVkXV0sXG4gICAgICAgICAgICAgICAgbW9kZWwzRDogW2lucHV0Lm1vZGVsM2QsIFtWYWxpZGF0b3JzLnJlcXVpcmVkXV0sXG4gICAgICAgICAgICAgICAgdmlld2VyOiBpbnB1dC52aWV3ZXIgPyBpbnB1dC52aWV3ZXIgOiBDYXB0dXJlVmlld2VyLk1BVFRFUlBPUlQsXG4gICAgICAgICAgICAgICAgc3VyZmFjZTogaW5wdXQuc3VyZmFjZSA/IGlucHV0LnN1cmZhY2UgOiBudWxsLFxuICAgICAgICAgICAgICAgIHRocmVlSnNQbGFjZW1lbnQ6IGlucHV0LmNhcHR1cmVNZXRhZGF0YSA/PyBudWxsLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLmNhcHR1cmVEYXRlID0gaW5wdXQudGFrZW5BdDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMudmlzaXRGb3JtID0gdGhpcy5mYi5ncm91cCh7XG4gICAgICAgICAgICAgICAgbW9kZWwzRDogW251bGwsIFtWYWxpZGF0b3JzLnJlcXVpcmVkXV0sXG4gICAgICAgICAgICAgICAgdmlld2VyOiBDYXB0dXJlVmlld2VyLk1BVFRFUlBPUlQsXG4gICAgICAgICAgICAgICAgc3VyZmFjZTogbnVsbCxcbiAgICAgICAgICAgICAgICBuYW1lOiBbbnVsbCwgW1ZhbGlkYXRvcnMucmVxdWlyZWRdXSxcbiAgICAgICAgICAgICAgICB0aHJlZUpzUGxhY2VtZW50OiBudWxsLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogVHJ1ZSB3aGlsZSB0aGUgZm9ybSBpcyBzZXQgdG8gY3JlYXRlIGEgVGhyZWUuanMgdmlzaXQsIHdoaWNoIGFza3MgZm9yIGRpZmZlcmVudCBmaWVsZHMuICovXG4gICAgZ2V0IGlzVGhyZWVKc1Zpc2l0KCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy52aXNpdEZvcm0/LnZhbHVlLnZpZXdlciA9PT0gQ2FwdHVyZVZpZXdlci5USFJFRUpTO1xuICAgIH1cblxuICAgIC8qKiBWYWxpZGF0aW9uIGVycm9yIGZvciB0aGUgM0QgbW9kZWwgZmllbGQsIG9yIG51bGwuIE9ubHkgbWVhbmluZ2Z1bCBmb3IgVGhyZWUuanMgdmlzaXRzLiAqL1xuICAgIGdldCBtb2RlbEtleUVycm9yKCk6IHN0cmluZyB8IG51bGwge1xuICAgICAgICBpZiAoIXRoaXMuaXNUaHJlZUpzVmlzaXQpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnRocmVlanNJbXBvcnRTZXJ2aWNlLnZhbGlkYXRlTW9kZWxLZXkodGhpcy52aXNpdEZvcm0udmFsdWUubW9kZWwzRCk7XG4gICAgfVxuXG4gICAgYXN5bmMgb25Ub2dnbGVEZXRhaWwoaW5kZXgpIHtcbiAgICAgICAgdGhpcy52aXNpdEluZGV4RGV0YWlscyA9IGluZGV4ID09PSB0aGlzLnZpc2l0SW5kZXhEZXRhaWxzID8gLTEgOiBpbmRleDtcbiAgICAgICAgdGhpcy5pbWFnZXNVcGxvYWRlZCA9IGF3YWl0IHRoaXMubWF0dGVycG9ydEltcG9ydFNlcnZpY2UuZ2V0VXBsb2FkZWRJbWFnZUNvdW50KHRoaXMudmlzaXRzW2luZGV4XS5tb2RlbDNkKTtcbiAgICB9XG5cbiAgICBvbkFkZFZpc2l0KCkge1xuICAgICAgICB0aGlzLmluaXRWaXNpdEZvcm0oKTtcbiAgICAgICAgdGhpcy5tZW51SXRlbXMucHVzaCh7IGxhYmVsOiAnTmV3JyB9KTtcbiAgICB9XG5cbiAgICBvbkVkaXQodmlzaXQpIHtcbiAgICAgICAgdGhpcy5pbml0VmlzaXRGb3JtKHZpc2l0KTtcbiAgICAgICAgdGhpcy5pc0VkaXRpbmcgPSB0cnVlO1xuICAgICAgICB0aGlzLm1lbnVJdGVtcy5wdXNoKHsgbGFiZWw6IHZpc2l0Lm5hbWUgfSk7XG4gICAgfVxuXG4gICAgYXN5bmMgb25TdWJtaXRWaXNpdCgpIHtcbiAgICAgICAgdGhpcy52aXNpdFN1Ym1pdHRlZCA9IHRydWU7XG4gICAgICAgIGlmICghdGhpcy52aXNpdEZvcm0udmFsaWQpIHtcbiAgICAgICAgICAgIHRoaXMuZXJyb3JGb3JtID0gdHJ1ZTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBBIFRocmVlLmpzIHZpc2l0IHBvaW50cyBhdCBhIGZpbGUgcmF0aGVyIHRoYW4gYSBNYXR0ZXJwb3J0IG1vZGVsLCBzbyB0aGUgcmVmZXJlbmNlIGlzXG4gICAgICAgIC8vIGNoZWNrZWQgYmVmb3JlIGFueXRoaW5nIGlzIHdyaXR0ZW4gLSBvdGhlcndpc2UgYSB0eXBvIGNyZWF0ZXMgem9uZXMgYW5kIG5hdmlnYXRpb24gZm9yIGFcbiAgICAgICAgLy8gbW9kZWwgdGhhdCA0MDRzIHRoZSBmaXJzdCB0aW1lIHNvbWVvbmUgb3BlbnMgdGhlIHZpc2l0LlxuICAgICAgICBpZiAodGhpcy5tb2RlbEtleUVycm9yKSB7XG4gICAgICAgICAgICB0aGlzLmVycm9yRm9ybSA9IHRydWU7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5lcnJvckZvcm0gPSBmYWxzZTtcbiAgICAgICAgY29uc3QgZm9ybVZhbHVlID0gdGhpcy52aXNpdEZvcm0udmFsdWU7XG4gICAgICAgIGNvbnN0IGNhcHR1cmUgPSB7XG4gICAgICAgICAgICB2aWV3ZXI6IGZvcm1WYWx1ZS52aWV3ZXIsXG4gICAgICAgICAgICB0YWtlbkF0OiB0aGlzLmNhcHR1cmVEYXRlLFxuICAgICAgICAgICAgc3VyZmFjZTogZm9ybVZhbHVlLnN1cmZhY2UsXG4gICAgICAgICAgICBzcGFjZUlEOiB0aGlzLmN1cnJlbnRTcGFjZS5pZCxcbiAgICAgICAgICAgIG1ldGFkYXRhOiB0aGlzLmlzVGhyZWVKc1Zpc2l0ID8gZm9ybVZhbHVlLnRocmVlSnNQbGFjZW1lbnQgOiBudWxsLFxuICAgICAgICB9IGFzIENhcHR1cmU7XG5cbiAgICAgICAgaWYgKHRoaXMuaXNFZGl0aW5nKSB7XG4gICAgICAgICAgICBjYXB0dXJlLmlkID0gZm9ybVZhbHVlLmNhcHR1cmVJRDtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuY2FwdHVyZVNlcnZpY2UudXBkYXRlQ2FwdHVyZShjYXB0dXJlKTtcbiAgICAgICAgICAgIGNvbnN0IG5vZGUgPSB7XG4gICAgICAgICAgICAgICAgaWQ6IGZvcm1WYWx1ZS5ub2RlSUQsXG4gICAgICAgICAgICAgICAgbW9kZWwzRDogZm9ybVZhbHVlLm1vZGVsM0QsXG4gICAgICAgICAgICAgICAgbWV0YWRhdGE6IGZvcm1WYWx1ZS5uYW1lLFxuICAgICAgICAgICAgfSBhcyBOb2RlO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5ub2RlU2VydmljZS51cGRhdGVOb2RlKG5vZGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGV0IGNyZWF0ZWROb2RlO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5jYXB0dXJlU2VydmljZS5jcmVhdGVDYXB0dXJlKGNhcHR1cmUpLnRoZW4oYXN5bmMgKHJlcykgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChyZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgbm9kZSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vZGVsM0Q6IGZvcm1WYWx1ZS5tb2RlbDNELFxuICAgICAgICAgICAgICAgICAgICAgICAgY2FwdHVyZUlEOiByZXMuaWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXRhZGF0YTogZm9ybVZhbHVlLm5hbWUsXG4gICAgICAgICAgICAgICAgICAgIH0gYXMgTm9kZTtcbiAgICAgICAgICAgICAgICAgICAgY3JlYXRlZE5vZGUgPSBhd2FpdCB0aGlzLm5vZGVTZXJ2aWNlLmNyZWF0ZU5vZGUobm9kZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLmxhdW5jaEltcG9ydChcbiAgICAgICAgICAgICAgICBmb3JtVmFsdWUubW9kZWwzRCxcbiAgICAgICAgICAgICAgICBmb3JtVmFsdWUuc3VyZmFjZSxcbiAgICAgICAgICAgICAgICBjcmVhdGVkTm9kZSxcbiAgICAgICAgICAgICAgICBmb3JtVmFsdWUudmlld2VyLFxuICAgICAgICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgICAgICAgIGZvcm1WYWx1ZS50aHJlZUpzUGxhY2VtZW50XG4gICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgLnRoZW4oKHN1Y2Nlc3MpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tb2RhbFJlZmVyZW5jZS5jbG9zZSgnaW1wb3J0IGVuZGVkIHdpdGggc3VjY2VzcycpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKChlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubW9kYWxSZWZlcmVuY2UuY2xvc2UoYEVycm9yIHdoaWxlIGltcG9ydDogJHtlfWApO1xuICAgICAgICAgICAgICAgICAgICBhbGVydChgRXJyb3Igd2hpbGUgaW1wb3J0OiAke2V9ICR7SlNPTi5zdHJpbmdpZnkoZSl9YCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25EZWxldGUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgbm9kZTogY3JlYXRlZE5vZGUsXG4gICAgICAgICAgICAgICAgICAgICAgICBjYXB0dXJlSUQ6IGNyZWF0ZWROb2RlLmNhcHR1cmVJRCxcbiAgICAgICAgICAgICAgICAgICAgfSBhcyBWaXNpdCwgZmFsc2UpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHRoaXMucmVzZXRWaXNpdHMoKTtcbiAgICAgICAgdGhpcy5vbkNhbmNlbCgpO1xuICAgIH1cblxuICAgIGdldCBtb2RlbDNEKCk6IEFic3RyYWN0Q29udHJvbCB7XG4gICAgICAgIHJldHVybiB0aGlzLnZpc2l0Rm9ybS5nZXQoJ21vZGVsM0QnKTtcbiAgICB9XG5cbiAgICBnZXQgbmFtZSgpOiBBYnN0cmFjdENvbnRyb2wge1xuICAgICAgICByZXR1cm4gdGhpcy52aXNpdEZvcm0uZ2V0KCduYW1lJyk7XG4gICAgfVxuXG4gICAgb25DYW5jZWwoKSB7XG4gICAgICAgIHRoaXMudmlzaXRTdWJtaXR0ZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy52aXNpdEZvcm0gPSBudWxsO1xuICAgICAgICB0aGlzLmlzRWRpdGluZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLmNhbkNhbmNlbEltcG9ydCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnRvdGFsSW1hZ2VzID0gMDtcbiAgICAgICAgdGhpcy5pbWFnZXNQcm9jZXNzZWQgPSAwO1xuICAgICAgICB0aGlzLmVycm9yRm9ybSA9IGZhbHNlO1xuICAgICAgICB0aGlzLnNldHVwTWVudUl0ZW1zKCk7XG4gICAgfVxuXG4gICAgYXN5bmMgb25EZWxldGUodmlzaXQ6IFZpc2l0LCBuZWVkUGVybWlzc2lvbiA9IHRydWUpIHtcbiAgICAgICAgY29uc3QgbWVzc2FnZSA9IHRoaXMudHJhbnNsYXRlLmluc3RhbnQoJ2NvbmZpcm0uZGVsZXRlVmlzaXQnKTtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWFsZXJ0XG4gICAgICAgIGlmICh3aW5kb3cuY29uZmlybShtZXNzYWdlKSB8fCAhbmVlZFBlcm1pc3Npb24pIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKHRoaXMudmlzaXRJbmRleERldGFpbHMpO1xuICAgICAgICAgICAgdGhpcy5pc1Byb2Nlc3NpbmcgPSB0cnVlO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy52aXNpdFNlcnZpY2UuZGVsZXRlVmlzaXQodmlzaXQsIHRoaXMuc3BhY2VJZCk7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnJlc2V0VmlzaXRzKCk7XG4gICAgICAgICAgICB0aGlzLmlzUHJvY2Vzc2luZyA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXREaXNtaXNzUmVhc29uKHJlYXNvbjogYW55KTogc3RyaW5nIHtcbiAgICAgICAgaWYgKHJlYXNvbiA9PT0gTW9kYWxEaXNtaXNzUmVhc29ucy5FU0MpIHtcbiAgICAgICAgICAgIHJldHVybiAnYnkgcHJlc3NpbmcgRVNDJztcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVhc29uID09PSBNb2RhbERpc21pc3NSZWFzb25zLkJBQ0tEUk9QX0NMSUNLKSB7XG4gICAgICAgICAgICByZXR1cm4gJ2J5IGNsaWNraW5nIG9uIGEgYmFja2Ryb3AnO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBgd2l0aDogJHtyZWFzb259YDtcbiAgICB9XG5cbiAgICBhc3luYyBsYXVuY2hJbXBvcnQoXG4gICAgICAgIG1vZGVsM0QsXG4gICAgICAgIHN1cmZhY2UsXG4gICAgICAgIG5vZGUsXG4gICAgICAgIHZpZXdlclR5cGU6IENhcHR1cmVWaWV3ZXIsXG4gICAgICAgIGltYWdlc09ubHkgPSBmYWxzZSxcbiAgICAgICAgb3ZlcnJpZGVFeGlzdGluZyA9IGZhbHNlLFxuICAgICAgICBwbGFjZW1lbnRNZXRhZGF0YTogc3RyaW5nID0gbnVsbCxcbiAgICApIHtcbiAgICAgICAgdGhpcy5tb2RhbFJlZmVyZW5jZSA9IHRoaXMubW9kYWxTZXJ2aWNlLm9wZW4odGhpcy5jb250ZW50LCB7XG4gICAgICAgICAgICBhcmlhTGFiZWxsZWRCeTogXCJtb2RhbC1iYXNpYy10aXRsZVwiLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5tb2RhbFJlZmVyZW5jZS5yZXN1bHQudGhlbihcbiAgICAgICAgICAgIChyZXN1bHQpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsb3NlUmVzdWx0ID0gYENsb3NlZCB3aXRoOiAke3Jlc3VsdH1gO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHRoaXMuY2xvc2VSZXN1bHQpO1xuICAgICAgICAgICAgICAgIHRoaXMuY2FuY2VsSW1wb3J0KCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5jbG9zZVJlc3VsdCA9IGBEaXNtaXNzZWQgJHt0aGlzLmdldERpc21pc3NSZWFzb24oZXJyb3IpfWA7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2codGhpcy5jbG9zZVJlc3VsdCk7XG4gICAgICAgICAgICAgICAgdGhpcy5jYW5jZWxJbXBvcnQoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAodmlld2VyVHlwZSA9PT0gQ2FwdHVyZVZpZXdlci5USFJFRUpTKSB7XG4gICAgICAgICAgICAgICAgLy8gUm91dGUgdGhlIGltcG9ydCB0byB0aGUgbmV3IFRocmVlLmpzIEltcG9ydCBTZXJ2aWNlXG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy50aHJlZWpzSW1wb3J0U2VydmljZS5pbXBvcnREYXRhKFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNwYWNlSWQsXG4gICAgICAgICAgICAgICAgICAgIHN1cmZhY2UsXG4gICAgICAgICAgICAgICAgICAgIGltYWdlc09ubHksXG4gICAgICAgICAgICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgICAgICAgICAgIG92ZXJyaWRlRXhpc3RpbmcsXG4gICAgICAgICAgICAgICAgICAgIHBsYWNlbWVudE1ldGFkYXRhXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gUm91dGUgdGhlIGltcG9ydCB0byB0aGUgZXhpc3RpbmcgTWF0dGVycG9ydCBJbXBvcnQgU2VydmljZVxuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMubWF0dGVycG9ydEltcG9ydFNlcnZpY2UuaW5pdFNka0Zvck1vZGVsKG1vZGVsM0QpO1xuXG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5tYXR0ZXJwb3J0SW1wb3J0U2VydmljZS5pbXBvcnREYXRhKFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNwYWNlSWQsXG4gICAgICAgICAgICAgICAgICAgIHN1cmZhY2UsXG4gICAgICAgICAgICAgICAgICAgIGltYWdlc09ubHksXG4gICAgICAgICAgICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgICAgICAgICAgIG92ZXJyaWRlRXhpc3RpbmdcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm1vZGFsUmVmZXJlbmNlLmNsb3NlKCk7XG5cbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGVycm9yKTtcbiAgICAgICAgICAgIFByb21pc2UucmVqZWN0KGVycm9yKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgY2FuY2VsSW1wb3J0KCkge1xuICAgICAgICB0aGlzLm1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLmFiYW5kb24oKTtcbiAgICAgICAgdGhpcy5vbkNhbmNlbCgpO1xuICAgICAgICB0aGlzLnJlc2V0VmlzaXRzKCk7XG4gICAgfVxuXG4gICAgb25JbXBvcnRJbWFnZXModmlzaXQ6IFZpc2l0LCBvdmVycmlkZUV4aXN0aW5nKSB7XG4gICAgICAgIHRoaXMubGF1bmNoSW1wb3J0KHZpc2l0Lm1vZGVsM2QsIG51bGwsIHZpc2l0Lm5vZGUuaWQsIHZpc2l0LnZpZXdlciwgdHJ1ZSwgb3ZlcnJpZGVFeGlzdGluZywgdmlzaXQuY2FwdHVyZU1ldGFkYXRhKTtcbiAgICB9XG5cbiAgICBpc0Zvcm1FcnJvcihjb250cm9sKSB7XG4gICAgICAgIHJldHVybiBjb250cm9sICYmIGNvbnRyb2wuaW52YWxpZCAmJiB0aGlzLmVycm9yRm9ybTtcbiAgICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwiY29udGFpbmVyLWZsdWlkXCIgY2xhc3M9XCJkYXNoYm9hcmQtdGFiXCI+XG4gICAgPGRpdiBjbGFzcz1cIm0tM1wiPlxuICAgICAgICA8bGliLXRhYi1uYXZpZ2F0aW9uIFttZW51SXRlbXNdPSdtZW51SXRlbXMnIChvbkdvQmFjayk9XCJvbkdvQmFjaygpXCI+PC9saWItdGFiLW5hdmlnYXRpb24+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwicm93IG1haW4tZm9ybS1jb250YWluZXJcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC02IGZvcm0tY29udGFpbmVyXCI+XG4gICAgICAgICAgICA8dWwgY2xhc3M9XCJsaXN0LWdyb3VwIGxpc3QtZ3JvdXAtZmx1c2hcIiAqbmdJZj1cIiF2aXNpdEZvcm1cIj5cbiAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJsaXN0LWdyb3VwLWl0ZW0gbGlzdC1ncm91cC1pdGVtLWFjdGlvblwiICpuZ0Zvcj1cImxldCB2aXNpdCBvZiB2aXNpdHM7IGluZGV4IGFzIGluZGV4XCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gYWxpZ24taXRlbXMtY2VudGVyXCIgKGNsaWNrKT1cIm9uVG9nZ2xlRGV0YWlsKGluZGV4KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge3t2aXNpdC5uYW1lID8gdmlzaXQubmFtZSA6IHZpc2l0Lm1vZGVsM2QgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsaWItY2hldnJvbiBbY29uZGl0aW9uU2hvd2luZ109XCJpbmRleD09dmlzaXRJbmRleERldGFpbHNcIj48L2xpYi1jaGV2cm9uPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImluZGV4PT12aXNpdEluZGV4RGV0YWlsc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHVsIGNsYXNzPVwibGlzdC1ncm91cCBsaXN0LWdyb3VwLWZsdXNoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtIGJnLXRyYW5zcGFyZW50XCI+e3snTmFtZScgfCB0cmFuc2xhdGV9fSA6IHt7IHZpc2l0Lm5hbWUgP1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aXNpdC5uYW1lIDogXCJOb3QgcHJvdmlkZWRcIiB8IHRyYW5zbGF0ZX19PC9saT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJsaXN0LWdyb3VwLWl0ZW0gYmctdHJhbnNwYXJlbnRcIj57eyczRCBNb2RlbCcgfCB0cmFuc2xhdGV9fSA6IHt7IHZpc2l0Lm1vZGVsM2QgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cImxpc3QtZ3JvdXAtaXRlbSBiZy10cmFuc3BhcmVudFwiPnt7J1N1cmZhY2UnIHwgdHJhbnNsYXRlfX0sIG08c3VwPjI8L3N1cD46IHt7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpc2l0LnN1cmZhY2UgP1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aXNpdC5zdXJmYWNlIDogJ05vdCBwcm92aWRlZCcgfCB0cmFuc2xhdGV9fTwvbGk+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtIGJnLXRyYW5zcGFyZW50XCI+e3snVmlld2VyJyB8IHRyYW5zbGF0ZX19IDoge3sgdmlzaXQudmlld2VyIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJsaXN0LWdyb3VwLWl0ZW0gYmctdHJhbnNwYXJlbnRcIj57eydEYXRlIG9mIGNhcHR1cmUnIHwgdHJhbnNsYXRlfX0gOiB7e1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aXNpdC50YWtlbkF0IHwgdGltZURhdGVTdHJpbmcgfCBhc3luY319XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cImxpc3QtZ3JvdXAtaXRlbSBiZy10cmFuc3BhcmVudFwiPnt7J0ltYWdlcyBhcmUgaW1wb3J0ZWQnIHwgdHJhbnNsYXRlfX0gOiB7e1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1hZ2VzVXBsb2FkZWQgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdWw+XG4gICAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgIDxsaWItbG9hZGVyICpuZ0lmPVwiaXNQcm9jZXNzaW5nXCI+PC9saWItbG9hZGVyPlxuXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWN0aW9uLWJ1dHRvbi1jb250YWluZXIgbXQtM1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtcHJpbWFyeSByb3VuZGVkLXBpbGwgbWUtMlwiIChjbGljayk9XCJvbkltcG9ydEltYWdlcyh2aXNpdCwgdHJ1ZSlcIiBbZGlzYWJsZWRdPVwiaXNQcm9jZXNzaW5nXCI+e3snSW1wb3J0IGFsbCBpbWFnZXMnIHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGV9fTwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiICpuZ0lmPVwiaW1hZ2VzVXBsb2FkZWQgPiAwXCIgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtcHJpbWFyeSByb3VuZGVkLXBpbGwgbWUtMlwiIChjbGljayk9XCJvbkltcG9ydEltYWdlcyh2aXNpdCwgZmFsc2UpXCIgW2Rpc2FibGVkXT1cImlzUHJvY2Vzc2luZ1wiPnt7J0ltcG9ydCBmcm9tIGltYWdlJyB8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZX19IHt7aW1hZ2VzVXBsb2FkZWR9fTwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtcHJpbWFyeSByb3VuZGVkLXBpbGwgbWUtMlwiIFtkaXNhYmxlZF09XCJpc1Byb2Nlc3NpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJvbkVkaXQodmlzaXQpXCI+e3snRWRpdCcgfCB0cmFuc2xhdGV9fTwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtcHJpbWFyeSByb3VuZGVkLXBpbGxcIiBbZGlzYWJsZWRdPVwiaXNQcm9jZXNzaW5nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwib25EZWxldGUodmlzaXQpXCI+e3snRGVsZXRlJyB8IHRyYW5zbGF0ZX19PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgPC91bD5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJ2aXNpdEZvcm1cIj5cbiAgICAgICAgICAgICAgICA8Zm9ybSAobmdTdWJtaXQpPVwib25TdWJtaXRWaXNpdCgpXCIgW2Zvcm1Hcm91cF09XCJ2aXNpdEZvcm1cIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTMgcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjb2wtc20tMiBjb2wtZm9ybS1sYWJlbFwiPnt7J05hbWUnIHwgdHJhbnNsYXRlfX08L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1zbS0xMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgZm9ybUNvbnRyb2xOYW1lPVwibmFtZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItMyByb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNvbC1zbS0yIGNvbC1mb3JtLWxhYmVsXCI+e3snUmVmZXJlbmNlIDNEIG1vZGVsJyB8IHRyYW5zbGF0ZX19ICo8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1zbS0xMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgW3JlYWRvbmx5XT1cImlzRWRpdGluZ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1pbnZhbGlkXT1cIm1vZGVsM0QuaW52YWxpZCAmJiB2aXNpdFN1Ym1pdHRlZFwiIHJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cIm1vZGVsM0RcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1mZWVkYmFja1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmdiLWFsZXJ0IGRhdGEtdGVzdGlkPVwibmV3LWxvY2F0aW9uLW5hbWUtaW52YWxpZFwiIFtkaXNtaXNzaWJsZV09XCJmYWxzZVwiIHR5cGU9XCJkYW5nZXJcIiBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJ2YWxpZGF0b3JzU2VydmljZS5pc0NvbnRyb2xFcnJvcih2aXNpdEZvcm0uY29udHJvbHNbJ25hbWUnXSkgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCAgaXNGb3JtRXJyb3IodmlzaXRGb3JtLmNvbnRyb2xzWyduYW1lJ10pXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7dmFsaWRhdG9yc1NlcnZpY2UuZ2V0RXJyb3IodmlzaXRGb3JtLmNvbnRyb2xzWyduYW1lJ10pIHwgdHJhbnNsYXRlfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZ2ItYWxlcnQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImlzRWRpdGluZ1wiIGNsYXNzPVwidGV4dC1kYW5nZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3snQ2Fubm90IGNoYW5nZSAzRCBtb2RlbCByZWZlcmVuY2UuIFBsZWFzZSBhZGQgbmV3IG1vZGVsLicgfCB0cmFuc2xhdGV9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gQSBUaHJlZS5qcyB2aXNpdCBzdG9yZXMgYW4gUzMga2V5IGhlcmUgaW5zdGVhZCBvZiBhIE1hdHRlcnBvcnQgbW9kZWwgSUQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbyB0aGUgZmllbGQgbWVhbnMgc29tZXRoaW5nIGRpZmZlcmVudCBkZXBlbmRpbmcgb24gdGhlIHZpZXdlciBhYm92ZS4gLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImlzVGhyZWVKc1Zpc2l0XCIgY2xhc3M9XCJmb3JtLXRleHRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3snUzMga2V5IG9mIHRoZSAuZ2xiIGZpbGUsIGZvciBleGFtcGxlIHZpc2l0cy9teS1tb2RlbC5nbGInIHwgdHJhbnNsYXRlfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwibW9kZWxLZXlFcnJvciAmJiB2aXNpdFN1Ym1pdHRlZFwiIGNsYXNzPVwidGV4dC1kYW5nZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ttb2RlbEtleUVycm9yIHwgdHJhbnNsYXRlfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItMyByb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNvbC1zbS0yIGNvbC1mb3JtLWxhYmVsXCI+e3snVmlld2VyJyB8IHRyYW5zbGF0ZX19PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtc20tMTBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IGNsYXNzPVwiZm9ybS1zZWxlY3RcIiBmb3JtQ29udHJvbE5hbWU9XCJ2aWV3ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIk1BVFRFUlBPUlRcIj5NYXR0ZXJwb3J0PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJUSFJFRUpTXCI+TW9kw6hsZSAzRCAoVGhyZWUuanMpPC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJDVVBJWFwiPkN1cGl4PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTMgcm93XCIgKm5nSWY9XCJpc1RocmVlSnNWaXNpdFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY29sLXNtLTIgY29sLWZvcm0tbGFiZWxcIj57eydJbml0aWFsIHBsYWNlbWVudCcgfCB0cmFuc2xhdGV9fTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLXNtLTEwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRleHRhcmVhIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgcm93cz1cIjNcIiBmb3JtQ29udHJvbE5hbWU9XCJ0aHJlZUpzUGxhY2VtZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9J3tcImNhbWVyYVBvc2l0aW9uXCI6IHtcInhcIjogMCwgXCJ5XCI6IDUsIFwielwiOiAxNX0sIFwicm90YXRpb25cIjoge1wieFwiOiAwLCBcInlcIjogMCwgXCJ6XCI6IDB9fSc+PC90ZXh0YXJlYT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS10ZXh0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7J09wdGlvbmFsLiBMZWF2ZSBlbXB0eSB0byBmcmFtZSB0aGUgbW9kZWwgYXV0b21hdGljYWxseS4nIHwgdHJhbnNsYXRlfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItMyByb3dcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNvbC1zbS0yIGNvbC1mb3JtLWxhYmVsXCI+e3snU3VyZmFjZScgfCB0cmFuc2xhdGV9fTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLXNtLTEwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBmb3JtQ29udHJvbE5hbWU9XCJzdXJmYWNlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTMgcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjb2wtc20tMiBjb2wtZm9ybS1sYWJlbFwiPnt7J0NhcHR1cmUgRGF0ZScgfCB0cmFuc2xhdGV9fTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtZ3JvdXBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBwbGFjZWhvbGRlcj1cImRkL21tL3l5eXlcIiBbKG5nTW9kZWwpXT1cImNhcHR1cmVEYXRlXCIgbmdiRGF0ZXBpY2tlclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjZDE9XCJuZ2JEYXRlcGlja2VyXCIgW25nTW9kZWxPcHRpb25zXT1cIntzdGFuZGFsb25lOiB0cnVlfVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1ncm91cC1hcHBlbmRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tb3V0bGluZS1zZWNvbmRhcnkgY2FsZW5kYXJcIiAoY2xpY2spPVwiZDEudG9nZ2xlKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiPjwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJzdWJtaXRcIiBjbGFzcz1cImJ0biBidG4tb3V0bGluZS1wcmltYXJ5IHJvdW5kZWQtcGlsbCBtZS0yXCI+e3snU2F2ZScgfFxuICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlfX08L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cIm9uQ2FuY2VsKClcIiBjbGFzcz1cImJ0biBidG4tb3V0bGluZS1wcmltYXJ5IHJvdW5kZWQtcGlsbFwiPnt7J0NhbmNlbCcgfFxuICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlfX08L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2tcIiAqbmdJZj1cImVycm9yRm9ybVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxuZ2ItYWxlcnQgZGF0YS10ZXN0aWQ9XCJuZXctbG9jYXRpb24tZm9ybS1pbnZhbGlkXCIgW2Rpc21pc3NpYmxlXT1cImZhbHNlXCIgdHlwZT1cImRhbmdlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3snZXJyb3JGb3JtLmluZm9CdG4nIHx0cmFuc2xhdGV9fVxuICAgICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmdiLWFsZXJ0PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Zvcm0+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCIhdmlzaXRGb3JtXCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tb3V0bGluZS1wcmltYXJ5IHJvdW5kZWQtcGlsbFwiIChjbGljayk9XCJvbkFkZFZpc2l0KClcIj57eydBZGQgM0QgdmlzaXQnIHxcbiAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlfX08L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBpZD1cInZpZXdlci1mcmFtZVwiIHN0eWxlPVwid2lkdGg6IDEwMCU7IGFzcGVjdC1yYXRpbzogMi8xO1wiPjwvZGl2PlxuICAgIDwvZGl2PlxuICAgIDxuZy10ZW1wbGF0ZSAjY29udGVudCBsZXQtbW9kYWw+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1oZWFkZXJcIj5cbiAgICAgICAgICAgIDxoNCBjbGFzcz1cIm1vZGFsLXRpdGxlXCIgaWQ9XCJtb2RhbC1iYXNpYy10aXRsZVwiPnt7J0ltcG9ydGluZyBEYXRhJyB8IHRyYW5zbGF0ZX19PC9oND5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiY2xvc2VcIiBhcmlhLWxhYmVsPVwiQ2xvc2VcIiAoY2xpY2spPVwibW9kYWwuZGlzbWlzcygnQ3Jvc3MgY2xpY2snKVwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPsOXPC9zcGFuPlxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtYm9keVwiPlxuICAgICAgICAgICAge3snUGxlYXNlIGRvIG5vdCBsZWF2ZSBvciByZWZyZXNoIHRoaXMgcGFnZS4uLicgfCB0cmFuc2xhdGV9fVxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cInRvdGFsSW1hZ2VzICE9IDBcIj5JbXBvcnRlZCB7e2ltYWdlc1Byb2Nlc3NlZH19IG91dCBvZiB7e3RvdGFsSW1hZ2VzfX0gaW1hZ2VzLjwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNwaW5uZXItYm9yZGVyXCIgcm9sZT1cInN0YXR1c1wiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInZpc3VhbGx5LWhpZGRlblwiPnt7J0xvYWRpbmcnIHwgdHJhbnNsYXRlfX0uLi48L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1mb290ZXJcIj5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLWRhcmtcIiBbZGlzYWJsZWRdPVwiIWNhbkNhbmNlbEltcG9ydFwiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cIm1vZGFsLmNsb3NlKCdDYW5jZWwgY2xpY2snKVwiPnt7J0NhbmNlbCBpbXBvcnQgb2YgaW1hZ2VzJyB8IHRyYW5zbGF0ZX19PC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvbmctdGVtcGxhdGU+XG48L2Rpdj4iXX0=
326
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlzaXRzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1zbWFydGVycGxhbi1sb2NhdGlvbnMvc3JjL2xpYi9jb21wb25lbnRzL3Zpc2l0cy92aXNpdHMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXNtYXJ0ZXJwbGFuLWxvY2F0aW9ucy9zcmMvbGliL2NvbXBvbmVudHMvdmlzaXRzL3Zpc2l0cy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFVLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM3RCxPQUFPLEVBR0gsVUFBVSxHQUViLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEIsT0FBTyxFQUFZLG1CQUFtQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDM0UsT0FBTyxFQVVILGFBQWEsR0FJaEIsTUFBTSxtQ0FBbUMsQ0FBQztBQUUzQyxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQzs7Ozs7Ozs7OztBQU8xQyxNQUFNLE9BQU8sZUFBZTtJQXdDWjtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDRDtJQUNDO0lBQ0E7SUFDQTtJQW5EWixPQUFPLENBQVM7SUFFaEIsaUJBQWlCLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFFdkIsU0FBUyxDQUFtQjtJQUU1QixTQUFTLEdBQVksS0FBSyxDQUFDO0lBRTNCLGNBQWMsR0FBWSxLQUFLLENBQUM7SUFFaEMsV0FBVyxDQUFTO0lBRXBCLFlBQVksR0FBRyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQVMsQ0FBQztJQUVwQyxNQUFNLEdBQVksRUFBRSxDQUFDO0lBRXJCLFdBQVcsQ0FBUztJQUU2QixPQUFPLENBQUM7SUFFekQsY0FBYyxDQUFNO0lBRXBCLGVBQWUsR0FBRyxLQUFL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Q3ZDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNoQixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDdkIsQ0FBQztJQUVELGNBQWMsQ0FBQyxLQUFZLEVBQUUsZ0JBQWdCO1FBQ3pDLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsS0FBSyxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQ3ZILENBQUM7SUFFRCxXQUFXLENBQUMsT0FBTztRQUNmLE9BQU8sT0FBTyxJQUFJLE9BQU8sQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQztJQUN4RCxDQUFDO3dHQTVXUSxlQUFlOzRGQUFmLGVBQWUsc0pDaEM1Qix3elVBaUtNOzs0RkRqSU8sZUFBZTtrQkFMM0IsU0FBUzsrQkFDSSxZQUFZO29iQXVCMkIsT0FBTztzQkFBdkQsU0FBUzt1QkFBQyxTQUFTLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgICBVbnR5cGVkRm9ybUdyb3VwLFxuICAgIFVudHlwZWRGb3JtQnVpbGRlcixcbiAgICBWYWxpZGF0b3JzLFxuICAgIEFic3RyYWN0Q29udHJvbCxcbn0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGUsIFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBOZ2JNb2RhbCwgTW9kYWxEaXNtaXNzUmVhc29ucyB9IGZyb20gJ0BuZy1ib290c3RyYXAvbmctYm9vdHN0cmFwJztcbmltcG9ydCB7XG4gICAgTm9kZSxcbiAgICBWaXNpdCxcbiAgICBNZW51SXRlbSxcbiAgICBNYXR0ZXJwb3J0SW1wb3J0U2VydmljZSxcbiAgICBUaHJlZUpzSW1wb3J0U2VydmljZSxcbiAgICBDYXB0dXJlU2VydmljZSxcbiAgICBOb2RlU2VydmljZSxcbiAgICBTcGFjZVNlcnZpY2UsXG4gICAgVmlzaXRTZXJ2aWNlLFxuICAgIENhcHR1cmVWaWV3ZXIsXG4gICAgQ2FwdHVyZSxcbiAgICBWYWxpZGF0b3JzU2VydmljZSxcbiAgICBOYXZpZ2F0b3JTZXJ2aWNlLFxufSBmcm9tICdAc21hcnRlcnBsYW4vbmd4LXNtYXJ0ZXJwbGFuLWNvcmUnO1xuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHsgU3ViamVjdCwgdGFrZVVudGlsIH0gZnJvbSAncnhqcyc7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnbGliLXZpc2l0cycsXG4gICAgdGVtcGxhdGVVcmw6ICcuL3Zpc2l0cy5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vdmlzaXRzLmNvbXBvbmVudC5zY3NzJ10sXG59KVxuZXhwb3J0IGNsYXNzIFZpc2l0c0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gICAgc3BhY2VJZDogc3RyaW5nO1xuXG4gICAgdmlzaXRJbmRleERldGFpbHMgPSAtMTtcblxuICAgIHZpc2l0Rm9ybTogVW50eXBlZEZvcm1Hcm91cDtcblxuICAgIGlzRWRpdGluZzogYm9vbGVhbiA9IGZhbHNlO1xuXG4gICAgdmlzaXRTdWJtaXR0ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIGNhcHR1cmVEYXRlOiBudW1iZXI7XG5cbiAgICBjdXJyZW50U3BhY2UgPSB7IHpvbmVzOiBbXSB9IGFzIGFueTtcblxuICAgIHZpc2l0czogVmlzaXRbXSA9IFtdO1xuXG4gICAgY2xvc2VSZXN1bHQ6IHN0cmluZztcblxuICAgIEBWaWV3Q2hpbGQoJ2NvbnRlbnQnLCB7IHN0YXRpYzogZmFsc2UgfSkgcHJpdmF0ZSBjb250ZW50O1xuXG4gICAgbW9kYWxSZWZlcmVuY2U6IGFueTtcblxuICAgIGNhbkNhbmNlbEltcG9ydCA9IGZhbHNlO1xuXG4gICAgaW1hZ2VzUHJvY2Vzc2VkOiBudW1iZXIgPSAwO1xuXG4gICAgdG90YWxJbWFnZXM6IG51bWJlciA9IDA7XG5cbiAgICBpbWFnZXNVcGxvYWRlZDogbnVtYmVyID0gMDtcblxuICAgIG1lbnVJdGVtczogTWVudUl0ZW1bXSA9IFtdO1xuXG4gICAgZXJyb3JGb3JtOiBib29sZWFuID0gZmFsc2U7XG5cbiAgICBpc1Byb2Nlc3NpbmcgPSBmYWxzZTtcblxuICAgIGRlc3Ryb3kkID0gbmV3IFN1YmplY3QoKTtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcml2YXRlIGZiOiBVbnR5cGVkRm9ybUJ1aWxkZXIsXG4gICAgICAgIHByaXZhdGUgbWF0dGVycG9ydEltcG9ydFNlcnZpY2U6IE1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHRocmVlanNJbXBvcnRTZXJ2aWNlOiBUaHJlZUpzSW1wb3J0U2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBjYXB0dXJlU2VydmljZTogQ2FwdHVyZVNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgbm9kZVNlcnZpY2U6IE5vZGVTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHNwYWNlU2VydmljZTogU3BhY2VTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHJvdXRlOiBBY3RpdmF0ZWRSb3V0ZSxcbiAgICAgICAgcHJpdmF0ZSBtb2RhbFNlcnZpY2U6IE5nYk1vZGFsLFxuICAgICAgICBwcml2YXRlIHZpc2l0U2VydmljZTogVmlzaXRTZXJ2aWNlLFxuICAgICAgICBwdWJsaWMgdmFsaWRhdG9yc1NlcnZpY2U6IFZhbGlkYXRvcnNTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHRyYW5zbGF0ZTogVHJhbnNsYXRlU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBuYXZpZ2F0b3JTZXJ2aWNlOiBOYXZpZ2F0b3JTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIHJvdXRlcjogUm91dGVyLFxuICAgICkge1xuICAgICAgICB0aGlzLm1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLmltcG9ydGluZ0ltYWdlcy5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2FuQ2FuY2VsSW1wb3J0ID0gdHJ1ZTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubWF0dGVycG9ydEltcG9ydFNlcnZpY2Uuc3dlZXBQcm9jZXNzZWRDb3VudC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKChjb3VudCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5pbWFnZXNQcm9jZXNzZWQgPSBjb3VudCArIDE7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLnRvdGFsU3dlZXBzQ291bnQucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSgoY291bnQpID0+IHtcbiAgICAgICAgICAgIHRoaXMudG90YWxJbWFnZXMgPSBjb3VudDtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5uYXZpZ2F0b3JTZXJ2aWNlLmxvY2F0aW9uSURDaGFuZ2VcbiAgICAgICAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSlcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoKHNwYWNlSUQpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbXCJkYXNoYm9hcmQvbG9jYWxpc2F0aW9uXCIsIHNwYWNlSUQsIFwidmlzaXRzXCJdKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMucm91dGUucGFyYW1zLnN1YnNjcmliZSgocGFyYW1zKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnNwYWNlSWQgPSBwYXJhbXMuaWQ7XG4gICAgICAgICAgICB0aGlzLnJlc2V0VmlzaXRzKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGFzeW5jIG5nT25Jbml0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLnNwYWNlSWQgPSB0aGlzLnJvdXRlLnNuYXBzaG90LnBhcmFtTWFwLmdldCgnaWQnKTtcbiAgICAgICAgYXdhaXQgdGhpcy5yZXNldFZpc2l0cygpO1xuICAgIH1cblxuICAgIG5nT25EZXN0cm95KCkge1xuICAgICAgICB0aGlzLmRlc3Ryb3kkLm5leHQodHJ1ZSk7XG4gICAgICAgIHRoaXMuZGVzdHJveSQuY29tcGxldGUoKTtcbiAgICB9XG5cbiAgICAvKlxuICAgIFZpc2l0ID0ge1xuICAgICAgY2FwdHVyZUlEOiBzdHJpbmcsXG4gICAgICBtb2RlbDNkOiBzdHJpbmcsXG4gICAgICB0YWtlbkF0OiBudW1iZXIsXG4gICAgICBzcGFjZUlEOiBzdHJpbmcsXG4gICAgICB2aWV3ZXI6IENhcHR1cmVWaWV3ZXIsXG4gICAgICBzdXJmYWNlOiBudW1iZXIsXG4gICAgICBub2RlOiBOb2RlLFxuICAgICAgbmFtZT86IHN0cmluZyB8IG51bGxcbiAgICB9XG4gICAgKi9cbiAgICBzZXR1cE1lbnVJdGVtcygpIHtcbiAgICAgICAgdGhpcy5tZW51SXRlbXMgPSBbXG4gICAgICAgICAgICB7IGxhYmVsOiAnTG9jYXRpb25zJywgdXJsOiAnL2xvY2FsaXNhdGlvbicgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBsYWJlbDogdGhpcy5jdXJyZW50U3BhY2UubmFtZSxcbiAgICAgICAgICAgICAgICB1cmw6IGAvbG9jYWxpc2F0aW9uLyR7dGhpcy5jdXJyZW50U3BhY2UuaWR9YCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbGFiZWw6ICdWaXJ0dWFsIHZpc2l0cycsXG4gICAgICAgICAgICAgICAgdXJsOiBgL2xvY2FsaXNhdGlvbi8ke3RoaXMuY3VycmVudFNwYWNlLmlkfS92aXNpdHNgLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgXTtcbiAgICB9XG5cbiAgICBvbkdvQmFjaygpIHtcbiAgICAgICAgdGhpcy5vbkNhbmNlbCgpO1xuICAgIH1cblxuICAgIGFzeW5jIHJlc2V0VmlzaXRzKCkge1xuICAgICAgICB0aGlzLnZpc2l0cyA9IFtdO1xuICAgICAgICB0aGlzLmN1cnJlbnRTcGFjZSA9IGF3YWl0IHRoaXMuc3BhY2VTZXJ2aWNlLmdldFNwYWNlKHRoaXMuc3BhY2VJZCk7XG4gICAgICAgIHRoaXMuc2V0dXBNZW51SXRlbXMoKTtcbiAgICAgICAgYXdhaXQgdGhpcy52aXNpdFNlcnZpY2VcbiAgICAgICAgICAgIC5nZXRWaXNpdHNGb3JTcGFjZUZvclVzZXIodGhpcy5zcGFjZUlkKVxuICAgICAgICAgICAgLnRoZW4oKHZpc2l0cykgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh2aXNpdHMpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gM0QgbW9kZWxzIHNoYXJlIHRoaXMgc3RvcmFnZSBidXQgaGF2ZSB0aGVpciBvd24gc2NyZWVuLCBzbyBsaXN0aW5nIHRoZW0gaGVyZVxuICAgICAgICAgICAgICAgICAgICAvLyB0b28gc2hvd2VkIGV2ZXJ5IG1vZGVsIHR3aWNlLiBUaGV5IGNhbiBzdGlsbCBiZSBjcmVhdGVkIGZyb20gdGhpcyBmb3JtOyB0aGV5XG4gICAgICAgICAgICAgICAgICAgIC8vIGp1c3QgYmVsb25nIHRvIHRoZSBvdGhlciB0YWIgb25jZSB0aGV5IGV4aXN0LlxuICAgICAgICAgICAgICAgICAgICB0aGlzLnZpc2l0cyA9IHZpc2l0cy5maWx0ZXIoXG4gICAgICAgICAgICAgICAgICAgICAgICAodmlzaXQpID0+IHZpc2l0LnZpZXdlciAhPT0gQ2FwdHVyZVZpZXdlci5USFJFRUpTLFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIGluaXRWaXNpdEZvcm0oaW5wdXQ6IFZpc2l0ID0gbnVsbCkge1xuICAgICAgICBpZiAoaW5wdXQpIHtcbiAgICAgICAgICAgIHRoaXMudmlzaXRGb3JtID0gdGhpcy5mYi5ncm91cCh7XG4gICAgICAgICAgICAgICAgY2FwdHVyZUlEOiBpbnB1dC5jYXB0dXJlSUQsXG4gICAgICAgICAgICAgICAgbm9kZUlEOiBpbnB1dC5ub2RlLmlkLFxuICAgICAgICAgICAgICAgIG5hbWU6IFtpbnB1dC5uYW1lLCBbVmFsaWRhdG9ycy5yZXF1aXJlZF1dLFxuICAgICAgICAgICAgICAgIG1vZGVsM0Q6IFtpbnB1dC5tb2RlbDNkLCBbVmFsaWRhdG9ycy5yZXF1aXJlZF1dLFxuICAgICAgICAgICAgICAgIHZpZXdlcjogaW5wdXQudmlld2VyID8gaW5wdXQudmlld2VyIDogQ2FwdHVyZVZpZXdlci5NQVRURVJQT1JULFxuICAgICAgICAgICAgICAgIHN1cmZhY2U6IGlucHV0LnN1cmZhY2UgPyBpbnB1dC5zdXJmYWNlIDogbnVsbCxcbiAgICAgICAgICAgICAgICB0aHJlZUpzUGxhY2VtZW50OiBpbnB1dC5jYXB0dXJlTWV0YWRhdGEgPz8gbnVsbCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5jYXB0dXJlRGF0ZSA9IGlucHV0LnRha2VuQXQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZpc2l0Rm9ybSA9IHRoaXMuZmIuZ3JvdXAoe1xuICAgICAgICAgICAgICAgIG1vZGVsM0Q6IFtudWxsLCBbVmFsaWRhdG9ycy5yZXF1aXJlZF1dLFxuICAgICAgICAgICAgICAgIHZpZXdlcjogQ2FwdHVyZVZpZXdlci5NQVRURVJQT1JULFxuICAgICAgICAgICAgICAgIHN1cmZhY2U6IG51bGwsXG4gICAgICAgICAgICAgICAgbmFtZTogW251bGwsIFtWYWxpZGF0b3JzLnJlcXVpcmVkXV0sXG4gICAgICAgICAgICAgICAgdGhyZWVKc1BsYWNlbWVudDogbnVsbCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIFRydWUgd2hpbGUgdGhlIGZvcm0gaXMgc2V0IHRvIGNyZWF0ZSBhIFRocmVlLmpzIHZpc2l0LCB3aGljaCBhc2tzIGZvciBkaWZmZXJlbnQgZmllbGRzLiAqL1xuICAgIGdldCBpc1RocmVlSnNWaXNpdCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmlzaXRGb3JtPy52YWx1ZS52aWV3ZXIgPT09IENhcHR1cmVWaWV3ZXIuVEhSRUVKUztcbiAgICB9XG5cbiAgICAvKiogVmFsaWRhdGlvbiBlcnJvciBmb3IgdGhlIDNEIG1vZGVsIGZpZWxkLCBvciBudWxsLiBPbmx5IG1lYW5pbmdmdWwgZm9yIFRocmVlLmpzIHZpc2l0cy4gKi9cbiAgICBnZXQgbW9kZWxLZXlFcnJvcigpOiBzdHJpbmcgfCBudWxsIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzVGhyZWVKc1Zpc2l0KSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy50aHJlZWpzSW1wb3J0U2VydmljZS52YWxpZGF0ZU1vZGVsS2V5KHRoaXMudmlzaXRGb3JtLnZhbHVlLm1vZGVsM0QpO1xuICAgIH1cblxuICAgIGFzeW5jIG9uVG9nZ2xlRGV0YWlsKGluZGV4KSB7XG4gICAgICAgIHRoaXMudmlzaXRJbmRleERldGFpbHMgPSBpbmRleCA9PT0gdGhpcy52aXNpdEluZGV4RGV0YWlscyA/IC0xIDogaW5kZXg7XG4gICAgICAgIHRoaXMuaW1hZ2VzVXBsb2FkZWQgPSBhd2FpdCB0aGlzLm1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLmdldFVwbG9hZGVkSW1hZ2VDb3VudCh0aGlzLnZpc2l0c1tpbmRleF0ubW9kZWwzZCk7XG4gICAgfVxuXG4gICAgb25BZGRWaXNpdCgpIHtcbiAgICAgICAgdGhpcy5pbml0VmlzaXRGb3JtKCk7XG4gICAgICAgIHRoaXMubWVudUl0ZW1zLnB1c2goeyBsYWJlbDogJ05ldycgfSk7XG4gICAgfVxuXG4gICAgb25FZGl0KHZpc2l0KSB7XG4gICAgICAgIHRoaXMuaW5pdFZpc2l0Rm9ybSh2aXNpdCk7XG4gICAgICAgIHRoaXMuaXNFZGl0aW5nID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5tZW51SXRlbXMucHVzaCh7IGxhYmVsOiB2aXNpdC5uYW1lIH0pO1xuICAgIH1cblxuICAgIGFzeW5jIG9uU3VibWl0VmlzaXQoKSB7XG4gICAgICAgIHRoaXMudmlzaXRTdWJtaXR0ZWQgPSB0cnVlO1xuICAgICAgICBpZiAoIXRoaXMudmlzaXRGb3JtLnZhbGlkKSB7XG4gICAgICAgICAgICB0aGlzLmVycm9yRm9ybSA9IHRydWU7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gQSBUaHJlZS5qcyB2aXNpdCBwb2ludHMgYXQgYSBmaWxlIHJhdGhlciB0aGFuIGEgTWF0dGVycG9ydCBtb2RlbCwgc28gdGhlIHJlZmVyZW5jZSBpc1xuICAgICAgICAvLyBjaGVja2VkIGJlZm9yZSBhbnl0aGluZyBpcyB3cml0dGVuIC0gb3RoZXJ3aXNlIGEgdHlwbyBjcmVhdGVzIHpvbmVzIGFuZCBuYXZpZ2F0aW9uIGZvciBhXG4gICAgICAgIC8vIG1vZGVsIHRoYXQgNDA0cyB0aGUgZmlyc3QgdGltZSBzb21lb25lIG9wZW5zIHRoZSB2aXNpdC5cbiAgICAgICAgaWYgKHRoaXMubW9kZWxLZXlFcnJvcikge1xuICAgICAgICAgICAgdGhpcy5lcnJvckZvcm0gPSB0cnVlO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZXJyb3JGb3JtID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IGZvcm1WYWx1ZSA9IHRoaXMudmlzaXRGb3JtLnZhbHVlO1xuICAgICAgICBjb25zdCBjYXB0dXJlID0ge1xuICAgICAgICAgICAgdmlld2VyOiBmb3JtVmFsdWUudmlld2VyLFxuICAgICAgICAgICAgdGFrZW5BdDogdGhpcy5jYXB0dXJlRGF0ZSxcbiAgICAgICAgICAgIHN1cmZhY2U6IGZvcm1WYWx1ZS5zdXJmYWNlLFxuICAgICAgICAgICAgc3BhY2VJRDogdGhpcy5jdXJyZW50U3BhY2UuaWQsXG4gICAgICAgICAgICBtZXRhZGF0YTogdGhpcy5pc1RocmVlSnNWaXNpdCA/IGZvcm1WYWx1ZS50aHJlZUpzUGxhY2VtZW50IDogbnVsbCxcbiAgICAgICAgfSBhcyBDYXB0dXJlO1xuXG4gICAgICAgIGlmICh0aGlzLmlzRWRpdGluZykge1xuICAgICAgICAgICAgY2FwdHVyZS5pZCA9IGZvcm1WYWx1ZS5jYXB0dXJlSUQ7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmNhcHR1cmVTZXJ2aWNlLnVwZGF0ZUNhcHR1cmUoY2FwdHVyZSk7XG4gICAgICAgICAgICBjb25zdCBub2RlID0ge1xuICAgICAgICAgICAgICAgIGlkOiBmb3JtVmFsdWUubm9kZUlELFxuICAgICAgICAgICAgICAgIG1vZGVsM0Q6IGZvcm1WYWx1ZS5tb2RlbDNELFxuICAgICAgICAgICAgICAgIG1ldGFkYXRhOiBmb3JtVmFsdWUubmFtZSxcbiAgICAgICAgICAgIH0gYXMgTm9kZTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMubm9kZVNlcnZpY2UudXBkYXRlTm9kZShub2RlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxldCBjcmVhdGVkTm9kZTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuY2FwdHVyZVNlcnZpY2UuY3JlYXRlQ2FwdHVyZShjYXB0dXJlKS50aGVuKGFzeW5jIChyZXMpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAocmVzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG5vZGUgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtb2RlbDNEOiBmb3JtVmFsdWUubW9kZWwzRCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhcHR1cmVJRDogcmVzLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWV0YWRhdGE6IGZvcm1WYWx1ZS5uYW1lLFxuICAgICAgICAgICAgICAgICAgICB9IGFzIE5vZGU7XG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZWROb2RlID0gYXdhaXQgdGhpcy5ub2RlU2VydmljZS5jcmVhdGVOb2RlKG5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5sYXVuY2hJbXBvcnQoXG4gICAgICAgICAgICAgICAgZm9ybVZhbHVlLm1vZGVsM0QsXG4gICAgICAgICAgICAgICAgZm9ybVZhbHVlLnN1cmZhY2UsXG4gICAgICAgICAgICAgICAgY3JlYXRlZE5vZGUsXG4gICAgICAgICAgICAgICAgZm9ybVZhbHVlLnZpZXdlcixcbiAgICAgICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgICAgICBmb3JtVmFsdWUudGhyZWVKc1BsYWNlbWVudFxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIC50aGVuKChzdWNjZXNzKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubW9kYWxSZWZlcmVuY2UuY2xvc2UoJ2ltcG9ydCBlbmRlZCB3aXRoIHN1Y2Nlc3MnKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaCgoZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1vZGFsUmVmZXJlbmNlLmNsb3NlKGBFcnJvciB3aGlsZSBpbXBvcnQ6ICR7ZX1gKTtcbiAgICAgICAgICAgICAgICAgICAgYWxlcnQoYEVycm9yIHdoaWxlIGltcG9ydDogJHtlfSAke0pTT04uc3RyaW5naWZ5KGUpfWApO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uRGVsZXRlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5vZGU6IGNyZWF0ZWROb2RlLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2FwdHVyZUlEOiBjcmVhdGVkTm9kZS5jYXB0dXJlSUQsXG4gICAgICAgICAgICAgICAgICAgIH0gYXMgVmlzaXQsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBhd2FpdCB0aGlzLnJlc2V0VmlzaXRzKCk7XG4gICAgICAgIHRoaXMub25DYW5jZWwoKTtcbiAgICB9XG5cbiAgICBnZXQgbW9kZWwzRCgpOiBBYnN0cmFjdENvbnRyb2wge1xuICAgICAgICByZXR1cm4gdGhpcy52aXNpdEZvcm0uZ2V0KCdtb2RlbDNEJyk7XG4gICAgfVxuXG4gICAgZ2V0IG5hbWUoKTogQWJzdHJhY3RDb250cm9sIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmlzaXRGb3JtLmdldCgnbmFtZScpO1xuICAgIH1cblxuICAgIG9uQ2FuY2VsKCkge1xuICAgICAgICB0aGlzLnZpc2l0U3VibWl0dGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMudmlzaXRGb3JtID0gbnVsbDtcbiAgICAgICAgdGhpcy5pc0VkaXRpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5jYW5DYW5jZWxJbXBvcnQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy50b3RhbEltYWdlcyA9IDA7XG4gICAgICAgIHRoaXMuaW1hZ2VzUHJvY2Vzc2VkID0gMDtcbiAgICAgICAgdGhpcy5lcnJvckZvcm0gPSBmYWxzZTtcbiAgICAgICAgdGhpcy5zZXR1cE1lbnVJdGVtcygpO1xuICAgIH1cblxuICAgIGFzeW5jIG9uRGVsZXRlKHZpc2l0OiBWaXNpdCwgbmVlZFBlcm1pc3Npb24gPSB0cnVlKSB7XG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSB0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdjb25maXJtLmRlbGV0ZVZpc2l0Jyk7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hbGVydFxuICAgICAgICBpZiAod2luZG93LmNvbmZpcm0obWVzc2FnZSkgfHwgIW5lZWRQZXJtaXNzaW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyh0aGlzLnZpc2l0SW5kZXhEZXRhaWxzKTtcbiAgICAgICAgICAgIHRoaXMuaXNQcm9jZXNzaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMudmlzaXRTZXJ2aWNlLmRlbGV0ZVZpc2l0KHZpc2l0LCB0aGlzLnNwYWNlSWQpO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5yZXNldFZpc2l0cygpO1xuICAgICAgICAgICAgdGhpcy5pc1Byb2Nlc3NpbmcgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0RGlzbWlzc1JlYXNvbihyZWFzb246IGFueSk6IHN0cmluZyB7XG4gICAgICAgIGlmIChyZWFzb24gPT09IE1vZGFsRGlzbWlzc1JlYXNvbnMuRVNDKSB7XG4gICAgICAgICAgICByZXR1cm4gJ2J5IHByZXNzaW5nIEVTQyc7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlYXNvbiA9PT0gTW9kYWxEaXNtaXNzUmVhc29ucy5CQUNLRFJPUF9DTElDSykge1xuICAgICAgICAgICAgcmV0dXJuICdieSBjbGlja2luZyBvbiBhIGJhY2tkcm9wJztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYHdpdGg6ICR7cmVhc29ufWA7XG4gICAgfVxuXG4gICAgYXN5bmMgbGF1bmNoSW1wb3J0KFxuICAgICAgICBtb2RlbDNELFxuICAgICAgICBzdXJmYWNlLFxuICAgICAgICBub2RlLFxuICAgICAgICB2aWV3ZXJUeXBlOiBDYXB0dXJlVmlld2VyLFxuICAgICAgICBpbWFnZXNPbmx5ID0gZmFsc2UsXG4gICAgICAgIG92ZXJyaWRlRXhpc3RpbmcgPSBmYWxzZSxcbiAgICAgICAgcGxhY2VtZW50TWV0YWRhdGE6IHN0cmluZyA9IG51bGwsXG4gICAgKSB7XG4gICAgICAgIHRoaXMubW9kYWxSZWZlcmVuY2UgPSB0aGlzLm1vZGFsU2VydmljZS5vcGVuKHRoaXMuY29udGVudCwge1xuICAgICAgICAgICAgYXJpYUxhYmVsbGVkQnk6IFwibW9kYWwtYmFzaWMtdGl0bGVcIixcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMubW9kYWxSZWZlcmVuY2UucmVzdWx0LnRoZW4oXG4gICAgICAgICAgICAocmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5jbG9zZVJlc3VsdCA9IGBDbG9zZWQgd2l0aDogJHtyZXN1bHR9YDtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyh0aGlzLmNsb3NlUmVzdWx0KTtcbiAgICAgICAgICAgICAgICB0aGlzLmNhbmNlbEltcG9ydCgpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuY2xvc2VSZXN1bHQgPSBgRGlzbWlzc2VkICR7dGhpcy5nZXREaXNtaXNzUmVhc29uKGVycm9yKX1gO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHRoaXMuY2xvc2VSZXN1bHQpO1xuICAgICAgICAgICAgICAgIHRoaXMuY2FuY2VsSW1wb3J0KCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICApO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKHZpZXdlclR5cGUgPT09IENhcHR1cmVWaWV3ZXIuVEhSRUVKUykge1xuICAgICAgICAgICAgICAgIC8vIFJvdXRlIHRoZSBpbXBvcnQgdG8gdGhlIG5ldyBUaHJlZS5qcyBJbXBvcnQgU2VydmljZVxuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMudGhyZWVqc0ltcG9ydFNlcnZpY2UuaW1wb3J0RGF0YShcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zcGFjZUlkLFxuICAgICAgICAgICAgICAgICAgICBzdXJmYWNlLFxuICAgICAgICAgICAgICAgICAgICBpbWFnZXNPbmx5LFxuICAgICAgICAgICAgICAgICAgICBub2RlLFxuICAgICAgICAgICAgICAgICAgICBvdmVycmlkZUV4aXN0aW5nLFxuICAgICAgICAgICAgICAgICAgICBwbGFjZW1lbnRNZXRhZGF0YVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFJvdXRlIHRoZSBpbXBvcnQgdG8gdGhlIGV4aXN0aW5nIE1hdHRlcnBvcnQgSW1wb3J0IFNlcnZpY2VcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLm1hdHRlcnBvcnRJbXBvcnRTZXJ2aWNlLmluaXRTZGtGb3JNb2RlbChtb2RlbDNEKTtcblxuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMubWF0dGVycG9ydEltcG9ydFNlcnZpY2UuaW1wb3J0RGF0YShcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zcGFjZUlkLFxuICAgICAgICAgICAgICAgICAgICBzdXJmYWNlLFxuICAgICAgICAgICAgICAgICAgICBpbWFnZXNPbmx5LFxuICAgICAgICAgICAgICAgICAgICBub2RlLFxuICAgICAgICAgICAgICAgICAgICBvdmVycmlkZUV4aXN0aW5nXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5tb2RhbFJlZmVyZW5jZS5jbG9zZSgpO1xuXG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhlcnJvcik7XG4gICAgICAgICAgICBQcm9taXNlLnJlamVjdChlcnJvcik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGNhbmNlbEltcG9ydCgpIHtcbiAgICAgICAgdGhpcy5tYXR0ZXJwb3J0SW1wb3J0U2VydmljZS5hYmFuZG9uKCk7XG4gICAgICAgIHRoaXMub25DYW5jZWwoKTtcbiAgICAgICAgdGhpcy5yZXNldFZpc2l0cygpO1xuICAgIH1cblxuICAgIG9uSW1wb3J0SW1hZ2VzKHZpc2l0OiBWaXNpdCwgb3ZlcnJpZGVFeGlzdGluZykge1xuICAgICAgICB0aGlzLmxhdW5jaEltcG9ydCh2aXNpdC5tb2RlbDNkLCBudWxsLCB2aXNpdC5ub2RlLmlkLCB2aXNpdC52aWV3ZXIsIHRydWUsIG92ZXJyaWRlRXhpc3RpbmcsIHZpc2l0LmNhcHR1cmVNZXRhZGF0YSk7XG4gICAgfVxuXG4gICAgaXNGb3JtRXJyb3IoY29udHJvbCkge1xuICAgICAgICByZXR1cm4gY29udHJvbCAmJiBjb250cm9sLmludmFsaWQgJiYgdGhpcy5lcnJvckZvcm07XG4gICAgfVxufVxuIiwiPGRpdiBjbGFzcz1cImNvbnRhaW5lci1mbHVpZFwiIGNsYXNzPVwiZGFzaGJvYXJkLXRhYlwiPlxuICAgIDxkaXYgY2xhc3M9XCJtLTNcIj5cbiAgICAgICAgPGxpYi10YWItbmF2aWdhdGlvbiBbbWVudUl0ZW1zXT0nbWVudUl0ZW1zJyAob25Hb0JhY2spPVwib25Hb0JhY2soKVwiPjwvbGliLXRhYi1uYXZpZ2F0aW9uPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiBjbGFzcz1cInJvdyBtYWluLWZvcm0tY29udGFpbmVyXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNiBmb3JtLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgPHVsIGNsYXNzPVwibGlzdC1ncm91cCBsaXN0LWdyb3VwLWZsdXNoXCIgKm5nSWY9XCIhdmlzaXRGb3JtXCI+XG4gICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtIGxpc3QtZ3JvdXAtaXRlbS1hY3Rpb25cIiAqbmdGb3I9XCJsZXQgdmlzaXQgb2YgdmlzaXRzOyBpbmRleCBhcyBpbmRleFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiIChjbGljayk9XCJvblRvZ2dsZURldGFpbChpbmRleClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7dmlzaXQubmFtZSA/IHZpc2l0Lm5hbWUgOiB2aXNpdC5tb2RlbDNkIH19XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGliLWNoZXZyb24gW2NvbmRpdGlvblNob3dpbmddPVwiaW5kZXg9PXZpc2l0SW5kZXhEZXRhaWxzXCI+PC9saWItY2hldnJvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJpbmRleD09dmlzaXRJbmRleERldGFpbHNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx1bCBjbGFzcz1cImxpc3QtZ3JvdXAgbGlzdC1ncm91cC1mbHVzaFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cImxpc3QtZ3JvdXAtaXRlbSBiZy10cmFuc3BhcmVudFwiPnt7J05hbWUnIHwgdHJhbnNsYXRlfX0gOiB7eyB2aXNpdC5uYW1lID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlzaXQubmFtZSA6IFwiTm90IHByb3ZpZGVkXCIgfCB0cmFuc2xhdGV9fTwvbGk+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtIGJnLXRyYW5zcGFyZW50XCI+e3snM0QgTW9kZWwnIHwgdHJhbnNsYXRlfX0gOiB7eyB2aXNpdC5tb2RlbDNkIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJsaXN0LWdyb3VwLWl0ZW0gYmctdHJhbnNwYXJlbnRcIj57eydTdXJmYWNlJyB8IHRyYW5zbGF0ZX19LCBtPHN1cD4yPC9zdXA+OiB7e1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aXNpdC5zdXJmYWNlID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlzaXQuc3VyZmFjZSA6ICdOb3QgcHJvdmlkZWQnIHwgdHJhbnNsYXRlfX08L2xpPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cImxpc3QtZ3JvdXAtaXRlbSBiZy10cmFuc3BhcmVudFwiPnt7J1ZpZXdlcicgfCB0cmFuc2xhdGV9fSA6IHt7IHZpc2l0LnZpZXdlciB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwibGlzdC1ncm91cC1pdGVtIGJnLXRyYW5zcGFyZW50XCI+e3snRGF0ZSBvZiBjYXB0dXJlJyB8IHRyYW5zbGF0ZX19IDoge3tcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlzaXQudGFrZW5BdCB8IHRpbWVEYXRlU3RyaW5nIHwgYXN5bmN9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJsaXN0LWdyb3VwLWl0ZW0gYmctdHJhbnNwYXJlbnRcIj57eydJbWFnZXMgYXJlIGltcG9ydGVkJyB8IHRyYW5zbGF0ZX19IDoge3tcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlc1VwbG9hZGVkIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3VsPlxuICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgICAgICA8bGliLWxvYWRlciAqbmdJZj1cImlzUHJvY2Vzc2luZ1wiPjwvbGliLWxvYWRlcj5cblxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFjdGlvbi1idXR0b24tY29udGFpbmVyIG10LTNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXByaW1hcnkgcm91bmRlZC1waWxsIG1lLTJcIiAoY2xpY2spPVwib25JbXBvcnRJbWFnZXModmlzaXQsIHRydWUpXCIgW2Rpc2FibGVkXT1cImlzUHJvY2Vzc2luZ1wiPnt7J0ltcG9ydCBhbGwgaW1hZ2VzJyB8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRlfX08L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAqbmdJZj1cImltYWdlc1VwbG9hZGVkID4gMFwiIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXByaW1hcnkgcm91bmRlZC1waWxsIG1lLTJcIiAoY2xpY2spPVwib25JbXBvcnRJbWFnZXModmlzaXQsIGZhbHNlKVwiIFtkaXNhYmxlZF09XCJpc1Byb2Nlc3NpbmdcIj57eydJbXBvcnQgZnJvbSBpbWFnZScgfFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2xhdGV9fSB7e2ltYWdlc1VwbG9hZGVkfX08L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXByaW1hcnkgcm91bmRlZC1waWxsIG1lLTJcIiBbZGlzYWJsZWRdPVwiaXNQcm9jZXNzaW5nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwib25FZGl0KHZpc2l0KVwiPnt7J0VkaXQnIHwgdHJhbnNsYXRlfX08L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXByaW1hcnkgcm91bmRlZC1waWxsXCIgW2Rpc2FibGVkXT1cImlzUHJvY2Vzc2luZ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uRGVsZXRlKHZpc2l0KVwiPnt7J0RlbGV0ZScgfCB0cmFuc2xhdGV9fTwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgIDwvdWw+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwidmlzaXRGb3JtXCI+XG4gICAgICAgICAgICAgICAgPGZvcm0gKG5nU3VibWl0KT1cIm9uU3VibWl0VmlzaXQoKVwiIFtmb3JtR3JvdXBdPVwidmlzaXRGb3JtXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0zIHJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY29sLXNtLTIgY29sLWZvcm0tbGFiZWxcIj57eydOYW1lJyB8IHRyYW5zbGF0ZX19PC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtc20tMTBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIGZvcm1Db250cm9sTmFtZT1cIm5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTMgcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjb2wtc20tMiBjb2wtZm9ybS1sYWJlbFwiPnt7J1JlZmVyZW5jZSAzRCBtb2RlbCcgfCB0cmFuc2xhdGV9fSAqPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtc20tMTBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIFtyZWFkb25seV09XCJpc0VkaXRpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbY2xhc3MuaXMtaW52YWxpZF09XCJtb2RlbDNELmludmFsaWQgJiYgdmlzaXRTdWJtaXR0ZWRcIiByZXF1aXJlZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJtb2RlbDNEXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2tcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG5nYi1hbGVydCBkYXRhLXRlc3RpZD1cIm5ldy1sb2NhdGlvbi1uYW1lLWludmFsaWRcIiBbZGlzbWlzc2libGVdPVwiZmFsc2VcIiB0eXBlPVwiZGFuZ2VyXCIgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwidmFsaWRhdG9yc1NlcnZpY2UuaXNDb250cm9sRXJyb3IodmlzaXRGb3JtLmNvbnRyb2xzWyduYW1lJ10pIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgIGlzRm9ybUVycm9yKHZpc2l0Rm9ybS5jb250cm9sc1snbmFtZSddKVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e3ZhbGlkYXRvcnNTZXJ2aWNlLmdldEVycm9yKHZpc2l0Rm9ybS5jb250cm9sc1snbmFtZSddKSB8IHRyYW5zbGF0ZX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbmdiLWFsZXJ0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJpc0VkaXRpbmdcIiBjbGFzcz1cInRleHQtZGFuZ2VyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7J0Nhbm5vdCBjaGFuZ2UgM0QgbW9kZWwgcmVmZXJlbmNlLiBQbGVhc2UgYWRkIG5ldyBtb2RlbC4nIHwgdHJhbnNsYXRlfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIEEgVGhyZWUuanMgdmlzaXQgc3RvcmVzIGFuIFMzIGtleSBoZXJlIGluc3RlYWQgb2YgYSBNYXR0ZXJwb3J0IG1vZGVsIElELFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc28gdGhlIGZpZWxkIG1lYW5zIHNvbWV0aGluZyBkaWZmZXJlbnQgZGVwZW5kaW5nIG9uIHRoZSB2aWV3ZXIgYWJvdmUuIC0tPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJpc1RocmVlSnNWaXNpdFwiIGNsYXNzPVwiZm9ybS10ZXh0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7J1MzIGtleSBvZiB0aGUgLmdsYiBmaWxlLCBmb3IgZXhhbXBsZSB2aXNpdHMvbXktbW9kZWwuZ2xiJyB8IHRyYW5zbGF0ZX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cIm1vZGVsS2V5RXJyb3IgJiYgdmlzaXRTdWJtaXR0ZWRcIiBjbGFzcz1cInRleHQtZGFuZ2VyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7bW9kZWxLZXlFcnJvciB8IHRyYW5zbGF0ZX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTMgcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjb2wtc20tMiBjb2wtZm9ybS1sYWJlbFwiPnt7J1ZpZXdlcicgfCB0cmFuc2xhdGV9fTwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLXNtLTEwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBjbGFzcz1cImZvcm0tc2VsZWN0XCIgZm9ybUNvbnRyb2xOYW1lPVwidmlld2VyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJNQVRURVJQT1JUXCI+TWF0dGVycG9ydDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiVEhSRUVKU1wiPk1vZMOobGUgM0QgKFRocmVlLmpzKTwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiQ1VQSVhcIj5DdXBpeDwvb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0zIHJvd1wiICpuZ0lmPVwiaXNUaHJlZUpzVmlzaXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImNvbC1zbS0yIGNvbC1mb3JtLWxhYmVsXCI+e3snSW5pdGlhbCBwbGFjZW1lbnQnIHwgdHJhbnNsYXRlfX08L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1zbS0xMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZXh0YXJlYSBjbGFzcz1cImZvcm0tY29udHJvbFwiIHJvd3M9XCIzXCIgZm9ybUNvbnRyb2xOYW1lPVwidGhyZWVKc1BsYWNlbWVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPSd7XCJjYW1lcmFQb3NpdGlvblwiOiB7XCJ4XCI6IDAsIFwieVwiOiA1LCBcInpcIjogMTV9LCBcInJvdGF0aW9uXCI6IHtcInhcIjogMCwgXCJ5XCI6IDAsIFwielwiOiAwfX0nPjwvdGV4dGFyZWE+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tdGV4dFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eydPcHRpb25hbC4gTGVhdmUgZW1wdHkgdG8gZnJhbWUgdGhlIG1vZGVsIGF1dG9tYXRpY2FsbHkuJyB8IHRyYW5zbGF0ZX19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTMgcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjb2wtc20tMiBjb2wtZm9ybS1sYWJlbFwiPnt7J1N1cmZhY2UnIHwgdHJhbnNsYXRlfX08L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1zbS0xMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgZm9ybUNvbnRyb2xOYW1lPVwic3VyZmFjZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtYi0zIHJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY29sLXNtLTIgY29sLWZvcm0tbGFiZWxcIj57eydDYXB0dXJlIERhdGUnIHwgdHJhbnNsYXRlfX08L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LWdyb3VwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiZm9ybS1jb250cm9sXCIgcGxhY2Vob2xkZXI9XCJkZC9tbS95eXl5XCIgWyhuZ01vZGVsKV09XCJjYXB0dXJlRGF0ZVwiIG5nYkRhdGVwaWNrZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI2QxPVwibmdiRGF0ZXBpY2tlclwiIFtuZ01vZGVsT3B0aW9uc109XCJ7c3RhbmRhbG9uZTogdHJ1ZX1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtZ3JvdXAtYXBwZW5kXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtc2Vjb25kYXJ5IGNhbGVuZGFyXCIgKGNsaWNrKT1cImQxLnRvZ2dsZSgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIj48L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwic3VibWl0XCIgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtcHJpbWFyeSByb3VuZGVkLXBpbGwgbWUtMlwiPnt7J1NhdmUnIHxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZX19PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJvbkNhbmNlbCgpXCIgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtcHJpbWFyeSByb3VuZGVkLXBpbGxcIj57eydDYW5jZWwnIHxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZX19PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLWZlZWRiYWNrXCIgKm5nSWY9XCJlcnJvckZvcm1cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bmdiLWFsZXJ0IGRhdGEtdGVzdGlkPVwibmV3LWxvY2F0aW9uLWZvcm0taW52YWxpZFwiIFtkaXNtaXNzaWJsZV09XCJmYWxzZVwiIHR5cGU9XCJkYW5nZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7J2Vycm9yRm9ybS5pbmZvQnRuJyB8dHJhbnNsYXRlfX1cbiAgICAgICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nYi1hbGVydD5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9mb3JtPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiIXZpc2l0Rm9ybVwiPlxuICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtcHJpbWFyeSByb3VuZGVkLXBpbGxcIiAoY2xpY2spPVwib25BZGRWaXNpdCgpXCI+e3snQWRkIDNEIHZpc2l0JyB8XG4gICAgICAgICAgICAgICAgICAgIHRyYW5zbGF0ZX19PC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgaWQ9XCJ2aWV3ZXItZnJhbWVcIiBzdHlsZT1cIndpZHRoOiAxMDAlOyBhc3BlY3QtcmF0aW86IDIvMTtcIj48L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8bmctdGVtcGxhdGUgI2NvbnRlbnQgbGV0LW1vZGFsPlxuICAgICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtaGVhZGVyXCI+XG4gICAgICAgICAgICA8aDQgY2xhc3M9XCJtb2RhbC10aXRsZVwiIGlkPVwibW9kYWwtYmFzaWMtdGl0bGVcIj57eydJbXBvcnRpbmcgRGF0YScgfCB0cmFuc2xhdGV9fTwvaDQ+XG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImNsb3NlXCIgYXJpYS1sYWJlbD1cIkNsb3NlXCIgKGNsaWNrKT1cIm1vZGFsLmRpc21pc3MoJ0Nyb3NzIGNsaWNrJylcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBhcmlhLWhpZGRlbj1cInRydWVcIj7Dlzwvc3Bhbj5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWJvZHlcIj5cbiAgICAgICAgICAgIHt7J1BsZWFzZSBkbyBub3QgbGVhdmUgb3IgcmVmcmVzaCB0aGlzIHBhZ2UuLi4nIHwgdHJhbnNsYXRlfX1cbiAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJ0b3RhbEltYWdlcyAhPSAwXCI+SW1wb3J0ZWQge3tpbWFnZXNQcm9jZXNzZWR9fSBvdXQgb2Yge3t0b3RhbEltYWdlc319IGltYWdlcy48L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWNlbnRlclwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzcGlubmVyLWJvcmRlclwiIHJvbGU9XCJzdGF0dXNcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2aXN1YWxseS1oaWRkZW5cIj57eydMb2FkaW5nJyB8IHRyYW5zbGF0ZX19Li4uPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtZm9vdGVyXCI+XG4gICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tb3V0bGluZS1kYXJrXCIgW2Rpc2FibGVkXT1cIiFjYW5DYW5jZWxJbXBvcnRcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJtb2RhbC5jbG9zZSgnQ2FuY2VsIGNsaWNrJylcIj57eydDYW5jZWwgaW1wb3J0IG9mIGltYWdlcycgfCB0cmFuc2xhdGV9fTwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICA8L25nLXRlbXBsYXRlPlxuPC9kaXY+Il19
@@ -875,6 +875,10 @@ class DetailLocationComponent {
875
875
  // Visits available for the selected source space, and for the current (target) space
876
876
  sourceVisits = [];
877
877
  visits = [];
878
+ /** The capture a visitor opens by default, of any viewer type. Null means none chosen. */
879
+ defaultCaptureID = null;
880
+ savingDefaultCapture = false;
881
+ defaultCaptureError = null;
878
882
  // 3D landmark points picked directly in each viewer (source and target)
879
883
  landmarkSourceA = null;
880
884
  landmarkTargetA = null;
@@ -937,6 +941,7 @@ class DetailLocationComponent {
937
941
  }
938
942
  // Visits (3D models) belonging to the CURRENT space, used as copy targets
939
943
  this.visits = await this.visitService.getVisitsForSpaceForUser(this.id);
944
+ this.defaultCaptureID = this.space?.defaultCaptureID ?? null;
940
945
  }
941
946
  setupMenuItems() {
942
947
  this.menuItems = [
@@ -1056,6 +1061,37 @@ class DetailLocationComponent {
1056
1061
  }, 1500);
1057
1062
  }
1058
1063
  //
1064
+ /**
1065
+ * Stores which capture a visitor opens by default.
1066
+ *
1067
+ * One field on the space, not a flag per capture, so the two admin screens cannot disagree:
1068
+ * setting it from either one writes the same place, and there is nothing to clear elsewhere.
1069
+ */
1070
+ async onDefaultCaptureChange() {
1071
+ this.savingDefaultCapture = true;
1072
+ this.defaultCaptureError = null;
1073
+ try {
1074
+ await this.spaceService.setDefaultCapture(this.id, this.defaultCaptureID || null);
1075
+ this.space.defaultCaptureID = this.defaultCaptureID || null;
1076
+ }
1077
+ catch (error) {
1078
+ // Until the schema change is deployed, AppSync rejects the field outright. Say so
1079
+ // rather than leaving the picker looking as though it saved.
1080
+ const graphQl = error?.errors;
1081
+ this.defaultCaptureError = Array.isArray(graphQl) && graphQl.length > 0
1082
+ ? graphQl.map((e) => e?.message ?? JSON.stringify(e)).join(' | ')
1083
+ : (error?.message ?? String(error));
1084
+ this.defaultCaptureID = this.space?.defaultCaptureID ?? null;
1085
+ }
1086
+ finally {
1087
+ this.savingDefaultCapture = false;
1088
+ }
1089
+ }
1090
+ /** Label for a visit in the default picker, naming the viewer it opens in. */
1091
+ visitLabel(visit) {
1092
+ const name = visit?.name || visit?.model3d || '';
1093
+ return visit?.viewer === CaptureViewer.THREEJS ? `${name} (3D)` : `${name} (Matterport)`;
1094
+ }
1059
1095
  // ---------- Copy POIs between visits ----------
1060
1096
  //
1061
1097
  /** Toggles visibility of the admin "copy POIs from another location" form. */
@@ -1200,11 +1236,11 @@ class DetailLocationComponent {
1200
1236
  }
1201
1237
  }
1202
1238
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DetailLocationComponent, deps: [{ token: MATTERPORT_SDK_KEY }, { token: i1.ActivatedRoute }, { token: i2.SpaceService }, { token: i2.VisitService }, { token: i1.Router }, { token: i2.BaseUserService }, { token: i3.TranslateService }, { token: i2.NavigatorService }, { token: i2.MatterportTagCopyService }], target: i0.ɵɵFactoryTarget.Component });
1203
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: DetailLocationComponent, selector: "lib-detail-location", ngImport: i0, template: "<div class=\"container-fluid\">\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"reset()\"></lib-tab-navigation>\n </div>\n <button class=\"btn btn-outline-primary rounded-pill me-3\" (click)=\"onReturn()\">{{'Back to locations' |\n translate}}</button>\n <div class=\"row\" *ngIf=\"!isEditing && space\">\n <div class=\"col-md-5\">\n <ul class=\"list-group list-group-flush\">\n <li class=\"list-group-item bg-transparent\">{{'Name' | translate}}: {{space.name}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Address' | translate}}: {{space.addresses}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Construction year' | translate}}:\n {{space.constructionYear ?\n space.constructionYear : \"No data\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Latitude' | translate}}:\n {{space.latitude ?\n space.latitude : \"No data\" | translate}}</li>\n <li class=\"list-group-item bg-transparent\">{{'Longitude' | translate}}: {{space.longitude ?\n space.longitude : \"No data\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Access level' | translate}}: {{space.level | translate\n }} </li>\n <li class=\"list-group-item bg-transparent\">{{'Energy Class' | translate}}:\n {{space.classEnergyConsumption ?\n space.classEnergyConsumption : \"No data\" | translate}}\n <button *ngIf=\"space.status !== 'DPE_TO_VALIDATE'\"\n class=\"btn btn-outline-primary rounded-pill no-lowercase ms-5\" (click)=\"onGetDpeData()\">\n {{'Get data from API DPE' | translate}}</button>\n <a class=\"bg-transparent ms-5\" *ngIf=\"space.status === 'DPE_TO_VALIDATE'\" (click)=\"onDpeValidate()\"\n style=\"cursor: pointer;\">\n <span class=\"iconify\" data-icon=\"mdi:alert-circle-check\" style=\"color: #f19c80;\" data-width=\"25\"\n data-height=\"25\"></span>\n {{'DPE data found. Click to validate' | translate}}\n </a>\n </li>\n <li class=\"list-group-item bg-transparent\">{{'Greenhouse gas emission Class' | translate}}:\n {{space.classGes ? space.classGes : \"No data\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Shareable Guest Link' | translate}}:\n <div style=\"display: inline;\" *ngIf=\"guestLink\">\n <a id=\"linkHref\" target=\"_blank\">{{'Try the link' | translate }}</a>\n <div [cdkCopyToClipboard]=\"guestLink\" [style.cursor]=\"'pointer'\"\n style=\"margin-left: 5px; max-width: 20px; display: inline;\" ngbTooltip=\"Copied!\"\n triggers=\"click:blur\">\n <span class=\"iconify\" data-icon=\"mdi:content-copy\" data-inline=\"false\" data-width=\"20\"\n data-height=\"20\"></span>\n </div>\n </div>\n <p *ngIf=\"!guestLink\" style=\"display: inline;\">{{'No link' | translate }}</p>\n <p *ngIf=\"!guestLink\"><small>({{'Generate link from a VISITOR mission'|translate}})</small>\n </p>\n </li>\n\n </ul>\n <div class=\"d-flex justify-content-center\" *ngIf=\"gettingData\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n </div>\n <hr>\n <div class=\"d-flex\">\n <button class=\"btn btn-outline-primary rounded-pill me-3\" (click)=\"onEdit()\"\n data-testid=\"location-edit-btn\">{{'Edit' |\n translate}}</button>\n <div class=\"tooltip-wrapper\"\n ngbTooltip=\"{{!canArchive ? ('Contact SmarterPlan' | translate) : ('Archive location and related data' | translate)}}\">\n <button class=\"btn btn-outline-primary rounded-pill\" (click)=\"onArchive()\" [disabled]=\"!canArchive\">\n {{'Archive' | translate}}</button>\n </div>\n </div>\n\n\n </div>\n <div class=\"col-md-7\" *ngIf=\"isValidatingDpe\">\n <h6>{{'Most relevant results for' | translate}} :\n <b>diagnostics de performance \u00E9nerg\u00E9tique (DPE) des b\u00E2timents tertiaires</b>\n </h6>\n <table class=\"table table-striped\">\n <thead>\n <tr>\n <th scope=\"col\">#</th>\n <th scope=\"col\">{{'Apply to location' | translate}}</th>\n <th scope=\"col\">{{'Address' | translate}}</th>\n <th scope=\"col\">{{'Activity sector' | translate}}</th>\n <th scope=\"col\">{{'Construction year' | translate}}</th>\n <th scope=\"col\">{{'Energy Class' | translate}}</th>\n <th scope=\"col\">{{'Greenhouse gas emission Class' | translate}}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let result of parsedMetadata; index as i\">\n <th scope=\"row\">{{ i + 1 }}</th>\n <td><input class=\"checkbox-apply\" type=\"checkbox\" [(ngModel)]=\"result.selected\"\n (change)=\"onSelectChange(result)\"></td>\n <td>{{result.geo_adresse}}</td>\n <td>{{result.secteur_activite}}</td>\n <td>{{ result.annee_construction }}</td>\n <td>{{ result.classe_consommation_energie }}</td>\n <td>{{ result.classe_estimation_ges }}</td>\n </tr>\n </tbody>\n </table>\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onSaveResult()\"\n [disabled]=\"!selectedDpeResult\">{{'Save selected' |\n translate}}</button>\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onErase()\">\n {{'No match (erase data)' | translate}}</button>\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onCancel()\">\n {{'Cancel' | translate}}</button>\n </div>\n </div>\n\n <!-- Toggle button for the admin \"Copy POIs\" form -->\n <div *ngIf=\"isAdmin && spaces && spaces.length > 0\" class=\"mt-4\">\n <button class=\"btn btn-outline-secondary rounded-pill\" (click)=\"toggleCopyPoisForm()\">\n {{ (showCopyPoisForm ? 'matterportCopy.hideForm' : 'matterportCopy.showForm') | translate }}\n </button>\n </div>\n\n <!-- Admin Form to Copy POIs -->\n <div *ngIf=\"isAdmin && spaces && spaces.length > 0 && showCopyPoisForm\" class=\"mt-3 p-4 border rounded bg-light\">\n <h6>{{ 'matterportCopy.formTitle' | translate }}</h6>\n\n <div class=\"mb-3 col-md-5\">\n <label class=\"form-label\">{{ 'matterportCopy.sourceSpace' | translate }}</label>\n <select class=\"form-select\" [(ngModel)]=\"selectedSourceSpaceId\" (ngModelChange)=\"onSourceSpaceChange()\">\n <option [ngValue]=\"null\">{{ 'matterportCopy.selectSpace' | translate }}</option>\n <option *ngFor=\"let space of spaces\" [ngValue]=\"space.id\">{{space.name}}</option>\n </select>\n </div>\n\n <div class=\"mb-3 col-md-5\" *ngIf=\"sourceVisits\">\n <label class=\"form-label\">{{ 'matterportCopy.sourceVisit' | translate }}</label>\n <select class=\"form-select\" [(ngModel)]=\"selectedSource3dModel\" (ngModelChange)=\"onModelSelectionChange()\">\n <option [ngValue]=\"null\">{{ 'matterportCopy.selectVisit' | translate }}</option>\n <option *ngFor=\"let visit of sourceVisits\" [ngValue]=\"visit.model3d\">{{visit.name}}</option>\n </select>\n </div>\n\n <div class=\"mb-3 col-md-5\">\n <label class=\"form-label\">{{ 'matterportCopy.targetVisit' | translate }}</label>\n <select class=\"form-select\" [(ngModel)]=\"selectedTarget3dModel\" (ngModelChange)=\"onModelSelectionChange()\">\n <option [ngValue]=\"null\">{{ 'matterportCopy.selectVisit' | translate }}</option>\n <option *ngFor=\"let visit of visits\" [ngValue]=\"visit.model3d\">{{visit.name}}</option>\n </select>\n </div>\n\n <div *ngIf=\"selectedSourceSpaceId && selectedSource3dModel && selectedTarget3dModel\"\n class=\"border rounded p-3 mb-3 bg-white\">\n <p class=\"small text-muted mb-2\">\n {{ 'matterportCopy.landmarkInstructions' | translate }}\n </p>\n\n <p class=\"fw-bold small mb-2\">{{ 'matterportCopy.landmarkA' | translate }}</p>\n <div class=\"row mb-4\">\n <div class=\"col-6\">\n <lib-landmark-picker [visit3dModel]=\"selectedSource3dModel\" [sdkKey]=\"sdkKey\"\n [value]=\"landmarkSourceA\" title=\"{{ 'matterportCopy.sourceVisitLabel' | translate }}\"\n (pointPicked)=\"onSourceLandmarkPicked('A', $event)\">\n </lib-landmark-picker>\n </div>\n <div class=\"col-6\">\n <lib-landmark-picker [visit3dModel]=\"selectedTarget3dModel\" [sdkKey]=\"sdkKey\"\n [value]=\"landmarkTargetA\" title=\"{{ 'matterportCopy.targetVisitLabel' | translate }}\"\n (pointPicked)=\"onTargetLandmarkPicked('A', $event)\">\n </lib-landmark-picker>\n </div>\n </div>\n\n <p class=\"fw-bold small mb-2\">{{ 'matterportCopy.landmarkB' | translate }}</p>\n <div class=\"row\">\n <div class=\"col-6\">\n <lib-landmark-picker [visit3dModel]=\"selectedSource3dModel\" [sdkKey]=\"sdkKey\"\n [value]=\"landmarkSourceB\" title=\"{{ 'matterportCopy.sourceVisitLabel' | translate }}\"\n (pointPicked)=\"onSourceLandmarkPicked('B', $event)\">\n </lib-landmark-picker>\n </div>\n <div class=\"col-6\">\n <lib-landmark-picker [visit3dModel]=\"selectedTarget3dModel\" [sdkKey]=\"sdkKey\"\n [value]=\"landmarkTargetB\" title=\"{{ 'matterportCopy.targetVisitLabel' | translate }}\"\n (pointPicked)=\"onTargetLandmarkPicked('B', $event)\">\n </lib-landmark-picker>\n </div>\n </div>\n </div>\n\n <div class=\"d-flex align-items-center pt-2\">\n <button class=\"btn btn-primary rounded-pill me-3\" [disabled]=\"!canCopyPois || isCopyingPois\"\n (click)=\"onCopyPois()\">\n {{ 'matterportCopy.copyButton' | translate }}\n </button>\n <div class=\"d-flex align-items-center gap-2 mb-3\">\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary\" (click)=\"exportLandmarkConfig()\">\n {{ 'matterportCopy.exportLandmarks' | translate }}\n </button>\n\n <label class=\"btn btn-sm btn-outline-secondary mb-0\">\n {{ 'matterportCopy.importLandmarks' | translate }}\n <input type=\"file\" accept=\"application/json\" hidden\n (change)=\"onImportLandmarkConfigSelected($event)\">\n </label>\n </div>\n <div *ngIf=\"isCopyingPois\" class=\"spinner-border spinner-border-sm text-primary\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n </div>\n\n <div *ngIf=\"copyPoisResultMsg\" class=\"mt-2 text-success fw-bold\">\n {{ copyPoisResultMsg }}\n </div>\n <div *ngIf=\"copyProgress\" class=\"mt-3\">\n <div class=\"d-flex justify-content-between small mb-1\">\n <span>\n <ng-container [ngSwitch]=\"copyProgress.phase\">\n <span *ngSwitchCase=\"'collecting'\">{{ 'Collecting information from both visits...' | translate\n }}</span>\n <span *ngSwitchCase=\"'tickets'\">{{ 'Copying tickets' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'equipments'\">{{ 'Copying equipments' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'pois'\">{{ 'Copying standalone POIs' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'objects3d'\">{{ 'Copying 3D objects' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'features'\">{{ 'Copying features' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'measurements'\">{{ 'Copying measurements' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'done'\">{{ 'Done!' | translate }}</span>\n </ng-container>\n </span>\n <span>{{ copyProgress.percent }}%</span>\n </div>\n <div class=\"progress\" style=\"height: 6px;\">\n <div class=\"progress-bar\" [class.progress-bar-striped]=\"copyProgress.phase === 'collecting'\"\n [class.progress-bar-animated]=\"copyProgress.phase === 'collecting'\"\n [class.bg-warning]=\"copyProgress.errorCount > 0\" role=\"progressbar\"\n [style.width.%]=\"copyProgress.phase === 'collecting' ? 100 : copyProgress.percent\">\n </div>\n </div>\n\n <!-- Detailed step-by-step log -->\n <div *ngIf=\"copyLog.length > 0\" class=\"mt-2 p-2 bg-white border rounded small\"\n style=\"max-height: 200px; overflow-y: auto; font-family: monospace;\">\n <div *ngFor=\"let entry of copyLog\" [class.text-danger]=\"entry.type === 'error'\"\n [class.text-warning]=\"entry.type === 'healed'\">\n {{ entry.text }}\n </div>\n </div>\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary mt-2\" *ngIf=\"copyLog.length > 0\"\n (click)=\"downloadCopyLog()\">\n {{ 'matterportCopy.downloadLog' | translate }}\n </button>\n </div>\n </div>\n\n <lib-form-location *ngIf=\"isEditing\" [location]=\"space\" (onChange)=\"onFormChange($event)\"></lib-form-location>\n</div>", styles: [""], dependencies: [{ kind: "directive", type: i4$1.CdkCopyToClipboard, selector: "[cdkCopyToClipboard]", inputs: ["cdkCopyToClipboard", "cdkCopyToClipboardAttempts"], outputs: ["cdkCopyToClipboardCopied"] }, { kind: "directive", type: i3$1.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "popperOptions", "triggers", "positionTarget", "container", "disableTooltip", "tooltipClass", "tooltipContext", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i4.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i1$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: LandmarkPickerComponent, selector: "lib-landmark-picker", inputs: ["visit3dModel", "sdkKey", "title", "value"], outputs: ["pointPicked"] }, { kind: "component", type: TabNavigationComponent, selector: "lib-tab-navigation", inputs: ["menuItems"], outputs: ["onGoBack"] }, { kind: "component", type: FormLocationComponent, selector: "lib-form-location", inputs: ["location"], outputs: ["onChange"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
1239
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: DetailLocationComponent, selector: "lib-detail-location", ngImport: i0, template: "<div class=\"container-fluid\">\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"reset()\"></lib-tab-navigation>\n </div>\n <button class=\"btn btn-outline-primary rounded-pill me-3\" (click)=\"onReturn()\">{{'Back to locations' |\n translate}}</button>\n <div class=\"row\" *ngIf=\"!isEditing && space\">\n <div class=\"col-md-5\">\n <ul class=\"list-group list-group-flush\">\n <li class=\"list-group-item bg-transparent\">{{'Name' | translate}}: {{space.name}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Address' | translate}}: {{space.addresses}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Construction year' | translate}}:\n {{space.constructionYear ?\n space.constructionYear : \"No data\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Latitude' | translate}}:\n {{space.latitude ?\n space.latitude : \"No data\" | translate}}</li>\n <li class=\"list-group-item bg-transparent\">{{'Longitude' | translate}}: {{space.longitude ?\n space.longitude : \"No data\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Access level' | translate}}: {{space.level | translate\n }} </li>\n <li class=\"list-group-item bg-transparent\">{{'Energy Class' | translate}}:\n {{space.classEnergyConsumption ?\n space.classEnergyConsumption : \"No data\" | translate}}\n <button *ngIf=\"space.status !== 'DPE_TO_VALIDATE'\"\n class=\"btn btn-outline-primary rounded-pill no-lowercase ms-5\" (click)=\"onGetDpeData()\">\n {{'Get data from API DPE' | translate}}</button>\n <a class=\"bg-transparent ms-5\" *ngIf=\"space.status === 'DPE_TO_VALIDATE'\" (click)=\"onDpeValidate()\"\n style=\"cursor: pointer;\">\n <span class=\"iconify\" data-icon=\"mdi:alert-circle-check\" style=\"color: #f19c80;\" data-width=\"25\"\n data-height=\"25\"></span>\n {{'DPE data found. Click to validate' | translate}}\n </a>\n </li>\n <!-- One picker for both viewers: the default lives on the space, so Matterport\n captures and 3D models compete for the same single slot. -->\n <li class=\"list-group-item bg-transparent\" *ngIf=\"visits.length > 1\">\n {{'Default visit' | translate}}:\n <select class=\"form-select d-inline-block ms-2\" style=\"width: auto;\"\n [(ngModel)]=\"defaultCaptureID\" (ngModelChange)=\"onDefaultCaptureChange()\"\n [disabled]=\"savingDefaultCapture\">\n <option [ngValue]=\"null\">{{'First available' | translate}}</option>\n <option *ngFor=\"let visit of visits\" [ngValue]=\"visit.captureID\">\n {{ visitLabel(visit) }}\n </option>\n </select>\n <span class=\"form-text d-block\">\n {{'What a visitor opens when they enter this location.' | translate}}\n </span>\n <span class=\"text-danger d-block\" *ngIf=\"defaultCaptureError\">\n {{ defaultCaptureError }}\n </span>\n </li>\n <li class=\"list-group-item bg-transparent\">{{'Greenhouse gas emission Class' | translate}}:\n {{space.classGes ? space.classGes : \"No data\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Shareable Guest Link' | translate}}:\n <div style=\"display: inline;\" *ngIf=\"guestLink\">\n <a id=\"linkHref\" target=\"_blank\">{{'Try the link' | translate }}</a>\n <div [cdkCopyToClipboard]=\"guestLink\" [style.cursor]=\"'pointer'\"\n style=\"margin-left: 5px; max-width: 20px; display: inline;\" ngbTooltip=\"Copied!\"\n triggers=\"click:blur\">\n <span class=\"iconify\" data-icon=\"mdi:content-copy\" data-inline=\"false\" data-width=\"20\"\n data-height=\"20\"></span>\n </div>\n </div>\n <p *ngIf=\"!guestLink\" style=\"display: inline;\">{{'No link' | translate }}</p>\n <p *ngIf=\"!guestLink\"><small>({{'Generate link from a VISITOR mission'|translate}})</small>\n </p>\n </li>\n\n </ul>\n <div class=\"d-flex justify-content-center\" *ngIf=\"gettingData\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n </div>\n <hr>\n <div class=\"d-flex\">\n <button class=\"btn btn-outline-primary rounded-pill me-3\" (click)=\"onEdit()\"\n data-testid=\"location-edit-btn\">{{'Edit' |\n translate}}</button>\n <div class=\"tooltip-wrapper\"\n ngbTooltip=\"{{!canArchive ? ('Contact SmarterPlan' | translate) : ('Archive location and related data' | translate)}}\">\n <button class=\"btn btn-outline-primary rounded-pill\" (click)=\"onArchive()\" [disabled]=\"!canArchive\">\n {{'Archive' | translate}}</button>\n </div>\n </div>\n\n\n </div>\n <div class=\"col-md-7\" *ngIf=\"isValidatingDpe\">\n <h6>{{'Most relevant results for' | translate}} :\n <b>diagnostics de performance \u00E9nerg\u00E9tique (DPE) des b\u00E2timents tertiaires</b>\n </h6>\n <table class=\"table table-striped\">\n <thead>\n <tr>\n <th scope=\"col\">#</th>\n <th scope=\"col\">{{'Apply to location' | translate}}</th>\n <th scope=\"col\">{{'Address' | translate}}</th>\n <th scope=\"col\">{{'Activity sector' | translate}}</th>\n <th scope=\"col\">{{'Construction year' | translate}}</th>\n <th scope=\"col\">{{'Energy Class' | translate}}</th>\n <th scope=\"col\">{{'Greenhouse gas emission Class' | translate}}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let result of parsedMetadata; index as i\">\n <th scope=\"row\">{{ i + 1 }}</th>\n <td><input class=\"checkbox-apply\" type=\"checkbox\" [(ngModel)]=\"result.selected\"\n (change)=\"onSelectChange(result)\"></td>\n <td>{{result.geo_adresse}}</td>\n <td>{{result.secteur_activite}}</td>\n <td>{{ result.annee_construction }}</td>\n <td>{{ result.classe_consommation_energie }}</td>\n <td>{{ result.classe_estimation_ges }}</td>\n </tr>\n </tbody>\n </table>\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onSaveResult()\"\n [disabled]=\"!selectedDpeResult\">{{'Save selected' |\n translate}}</button>\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onErase()\">\n {{'No match (erase data)' | translate}}</button>\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onCancel()\">\n {{'Cancel' | translate}}</button>\n </div>\n </div>\n\n <!-- Toggle button for the admin \"Copy POIs\" form -->\n <div *ngIf=\"isAdmin && spaces && spaces.length > 0\" class=\"mt-4\">\n <button class=\"btn btn-outline-secondary rounded-pill\" (click)=\"toggleCopyPoisForm()\">\n {{ (showCopyPoisForm ? 'matterportCopy.hideForm' : 'matterportCopy.showForm') | translate }}\n </button>\n </div>\n\n <!-- Admin Form to Copy POIs -->\n <div *ngIf=\"isAdmin && spaces && spaces.length > 0 && showCopyPoisForm\" class=\"mt-3 p-4 border rounded bg-light\">\n <h6>{{ 'matterportCopy.formTitle' | translate }}</h6>\n\n <div class=\"mb-3 col-md-5\">\n <label class=\"form-label\">{{ 'matterportCopy.sourceSpace' | translate }}</label>\n <select class=\"form-select\" [(ngModel)]=\"selectedSourceSpaceId\" (ngModelChange)=\"onSourceSpaceChange()\">\n <option [ngValue]=\"null\">{{ 'matterportCopy.selectSpace' | translate }}</option>\n <option *ngFor=\"let space of spaces\" [ngValue]=\"space.id\">{{space.name}}</option>\n </select>\n </div>\n\n <div class=\"mb-3 col-md-5\" *ngIf=\"sourceVisits\">\n <label class=\"form-label\">{{ 'matterportCopy.sourceVisit' | translate }}</label>\n <select class=\"form-select\" [(ngModel)]=\"selectedSource3dModel\" (ngModelChange)=\"onModelSelectionChange()\">\n <option [ngValue]=\"null\">{{ 'matterportCopy.selectVisit' | translate }}</option>\n <option *ngFor=\"let visit of sourceVisits\" [ngValue]=\"visit.model3d\">{{visit.name}}</option>\n </select>\n </div>\n\n <div class=\"mb-3 col-md-5\">\n <label class=\"form-label\">{{ 'matterportCopy.targetVisit' | translate }}</label>\n <select class=\"form-select\" [(ngModel)]=\"selectedTarget3dModel\" (ngModelChange)=\"onModelSelectionChange()\">\n <option [ngValue]=\"null\">{{ 'matterportCopy.selectVisit' | translate }}</option>\n <option *ngFor=\"let visit of visits\" [ngValue]=\"visit.model3d\">{{visit.name}}</option>\n </select>\n </div>\n\n <div *ngIf=\"selectedSourceSpaceId && selectedSource3dModel && selectedTarget3dModel\"\n class=\"border rounded p-3 mb-3 bg-white\">\n <p class=\"small text-muted mb-2\">\n {{ 'matterportCopy.landmarkInstructions' | translate }}\n </p>\n\n <p class=\"fw-bold small mb-2\">{{ 'matterportCopy.landmarkA' | translate }}</p>\n <div class=\"row mb-4\">\n <div class=\"col-6\">\n <lib-landmark-picker [visit3dModel]=\"selectedSource3dModel\" [sdkKey]=\"sdkKey\"\n [value]=\"landmarkSourceA\" title=\"{{ 'matterportCopy.sourceVisitLabel' | translate }}\"\n (pointPicked)=\"onSourceLandmarkPicked('A', $event)\">\n </lib-landmark-picker>\n </div>\n <div class=\"col-6\">\n <lib-landmark-picker [visit3dModel]=\"selectedTarget3dModel\" [sdkKey]=\"sdkKey\"\n [value]=\"landmarkTargetA\" title=\"{{ 'matterportCopy.targetVisitLabel' | translate }}\"\n (pointPicked)=\"onTargetLandmarkPicked('A', $event)\">\n </lib-landmark-picker>\n </div>\n </div>\n\n <p class=\"fw-bold small mb-2\">{{ 'matterportCopy.landmarkB' | translate }}</p>\n <div class=\"row\">\n <div class=\"col-6\">\n <lib-landmark-picker [visit3dModel]=\"selectedSource3dModel\" [sdkKey]=\"sdkKey\"\n [value]=\"landmarkSourceB\" title=\"{{ 'matterportCopy.sourceVisitLabel' | translate }}\"\n (pointPicked)=\"onSourceLandmarkPicked('B', $event)\">\n </lib-landmark-picker>\n </div>\n <div class=\"col-6\">\n <lib-landmark-picker [visit3dModel]=\"selectedTarget3dModel\" [sdkKey]=\"sdkKey\"\n [value]=\"landmarkTargetB\" title=\"{{ 'matterportCopy.targetVisitLabel' | translate }}\"\n (pointPicked)=\"onTargetLandmarkPicked('B', $event)\">\n </lib-landmark-picker>\n </div>\n </div>\n </div>\n\n <div class=\"d-flex align-items-center pt-2\">\n <button class=\"btn btn-primary rounded-pill me-3\" [disabled]=\"!canCopyPois || isCopyingPois\"\n (click)=\"onCopyPois()\">\n {{ 'matterportCopy.copyButton' | translate }}\n </button>\n <div class=\"d-flex align-items-center gap-2 mb-3\">\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary\" (click)=\"exportLandmarkConfig()\">\n {{ 'matterportCopy.exportLandmarks' | translate }}\n </button>\n\n <label class=\"btn btn-sm btn-outline-secondary mb-0\">\n {{ 'matterportCopy.importLandmarks' | translate }}\n <input type=\"file\" accept=\"application/json\" hidden\n (change)=\"onImportLandmarkConfigSelected($event)\">\n </label>\n </div>\n <div *ngIf=\"isCopyingPois\" class=\"spinner-border spinner-border-sm text-primary\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n </div>\n\n <div *ngIf=\"copyPoisResultMsg\" class=\"mt-2 text-success fw-bold\">\n {{ copyPoisResultMsg }}\n </div>\n <div *ngIf=\"copyProgress\" class=\"mt-3\">\n <div class=\"d-flex justify-content-between small mb-1\">\n <span>\n <ng-container [ngSwitch]=\"copyProgress.phase\">\n <span *ngSwitchCase=\"'collecting'\">{{ 'Collecting information from both visits...' | translate\n }}</span>\n <span *ngSwitchCase=\"'tickets'\">{{ 'Copying tickets' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'equipments'\">{{ 'Copying equipments' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'pois'\">{{ 'Copying standalone POIs' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'objects3d'\">{{ 'Copying 3D objects' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'features'\">{{ 'Copying features' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'measurements'\">{{ 'Copying measurements' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'done'\">{{ 'Done!' | translate }}</span>\n </ng-container>\n </span>\n <span>{{ copyProgress.percent }}%</span>\n </div>\n <div class=\"progress\" style=\"height: 6px;\">\n <div class=\"progress-bar\" [class.progress-bar-striped]=\"copyProgress.phase === 'collecting'\"\n [class.progress-bar-animated]=\"copyProgress.phase === 'collecting'\"\n [class.bg-warning]=\"copyProgress.errorCount > 0\" role=\"progressbar\"\n [style.width.%]=\"copyProgress.phase === 'collecting' ? 100 : copyProgress.percent\">\n </div>\n </div>\n\n <!-- Detailed step-by-step log -->\n <div *ngIf=\"copyLog.length > 0\" class=\"mt-2 p-2 bg-white border rounded small\"\n style=\"max-height: 200px; overflow-y: auto; font-family: monospace;\">\n <div *ngFor=\"let entry of copyLog\" [class.text-danger]=\"entry.type === 'error'\"\n [class.text-warning]=\"entry.type === 'healed'\">\n {{ entry.text }}\n </div>\n </div>\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary mt-2\" *ngIf=\"copyLog.length > 0\"\n (click)=\"downloadCopyLog()\">\n {{ 'matterportCopy.downloadLog' | translate }}\n </button>\n </div>\n </div>\n\n <lib-form-location *ngIf=\"isEditing\" [location]=\"space\" (onChange)=\"onFormChange($event)\"></lib-form-location>\n</div>", styles: [""], dependencies: [{ kind: "directive", type: i4$1.CdkCopyToClipboard, selector: "[cdkCopyToClipboard]", inputs: ["cdkCopyToClipboard", "cdkCopyToClipboardAttempts"], outputs: ["cdkCopyToClipboardCopied"] }, { kind: "directive", type: i3$1.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "popperOptions", "triggers", "positionTarget", "container", "disableTooltip", "tooltipClass", "tooltipContext", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i4.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: i1$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: LandmarkPickerComponent, selector: "lib-landmark-picker", inputs: ["visit3dModel", "sdkKey", "title", "value"], outputs: ["pointPicked"] }, { kind: "component", type: TabNavigationComponent, selector: "lib-tab-navigation", inputs: ["menuItems"], outputs: ["onGoBack"] }, { kind: "component", type: FormLocationComponent, selector: "lib-form-location", inputs: ["location"], outputs: ["onChange"] }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }] });
1204
1240
  }
1205
1241
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DetailLocationComponent, decorators: [{
1206
1242
  type: Component,
1207
- args: [{ selector: 'lib-detail-location', template: "<div class=\"container-fluid\">\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"reset()\"></lib-tab-navigation>\n </div>\n <button class=\"btn btn-outline-primary rounded-pill me-3\" (click)=\"onReturn()\">{{'Back to locations' |\n translate}}</button>\n <div class=\"row\" *ngIf=\"!isEditing && space\">\n <div class=\"col-md-5\">\n <ul class=\"list-group list-group-flush\">\n <li class=\"list-group-item bg-transparent\">{{'Name' | translate}}: {{space.name}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Address' | translate}}: {{space.addresses}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Construction year' | translate}}:\n {{space.constructionYear ?\n space.constructionYear : \"No data\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Latitude' | translate}}:\n {{space.latitude ?\n space.latitude : \"No data\" | translate}}</li>\n <li class=\"list-group-item bg-transparent\">{{'Longitude' | translate}}: {{space.longitude ?\n space.longitude : \"No data\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Access level' | translate}}: {{space.level | translate\n }} </li>\n <li class=\"list-group-item bg-transparent\">{{'Energy Class' | translate}}:\n {{space.classEnergyConsumption ?\n space.classEnergyConsumption : \"No data\" | translate}}\n <button *ngIf=\"space.status !== 'DPE_TO_VALIDATE'\"\n class=\"btn btn-outline-primary rounded-pill no-lowercase ms-5\" (click)=\"onGetDpeData()\">\n {{'Get data from API DPE' | translate}}</button>\n <a class=\"bg-transparent ms-5\" *ngIf=\"space.status === 'DPE_TO_VALIDATE'\" (click)=\"onDpeValidate()\"\n style=\"cursor: pointer;\">\n <span class=\"iconify\" data-icon=\"mdi:alert-circle-check\" style=\"color: #f19c80;\" data-width=\"25\"\n data-height=\"25\"></span>\n {{'DPE data found. Click to validate' | translate}}\n </a>\n </li>\n <li class=\"list-group-item bg-transparent\">{{'Greenhouse gas emission Class' | translate}}:\n {{space.classGes ? space.classGes : \"No data\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Shareable Guest Link' | translate}}:\n <div style=\"display: inline;\" *ngIf=\"guestLink\">\n <a id=\"linkHref\" target=\"_blank\">{{'Try the link' | translate }}</a>\n <div [cdkCopyToClipboard]=\"guestLink\" [style.cursor]=\"'pointer'\"\n style=\"margin-left: 5px; max-width: 20px; display: inline;\" ngbTooltip=\"Copied!\"\n triggers=\"click:blur\">\n <span class=\"iconify\" data-icon=\"mdi:content-copy\" data-inline=\"false\" data-width=\"20\"\n data-height=\"20\"></span>\n </div>\n </div>\n <p *ngIf=\"!guestLink\" style=\"display: inline;\">{{'No link' | translate }}</p>\n <p *ngIf=\"!guestLink\"><small>({{'Generate link from a VISITOR mission'|translate}})</small>\n </p>\n </li>\n\n </ul>\n <div class=\"d-flex justify-content-center\" *ngIf=\"gettingData\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n </div>\n <hr>\n <div class=\"d-flex\">\n <button class=\"btn btn-outline-primary rounded-pill me-3\" (click)=\"onEdit()\"\n data-testid=\"location-edit-btn\">{{'Edit' |\n translate}}</button>\n <div class=\"tooltip-wrapper\"\n ngbTooltip=\"{{!canArchive ? ('Contact SmarterPlan' | translate) : ('Archive location and related data' | translate)}}\">\n <button class=\"btn btn-outline-primary rounded-pill\" (click)=\"onArchive()\" [disabled]=\"!canArchive\">\n {{'Archive' | translate}}</button>\n </div>\n </div>\n\n\n </div>\n <div class=\"col-md-7\" *ngIf=\"isValidatingDpe\">\n <h6>{{'Most relevant results for' | translate}} :\n <b>diagnostics de performance \u00E9nerg\u00E9tique (DPE) des b\u00E2timents tertiaires</b>\n </h6>\n <table class=\"table table-striped\">\n <thead>\n <tr>\n <th scope=\"col\">#</th>\n <th scope=\"col\">{{'Apply to location' | translate}}</th>\n <th scope=\"col\">{{'Address' | translate}}</th>\n <th scope=\"col\">{{'Activity sector' | translate}}</th>\n <th scope=\"col\">{{'Construction year' | translate}}</th>\n <th scope=\"col\">{{'Energy Class' | translate}}</th>\n <th scope=\"col\">{{'Greenhouse gas emission Class' | translate}}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let result of parsedMetadata; index as i\">\n <th scope=\"row\">{{ i + 1 }}</th>\n <td><input class=\"checkbox-apply\" type=\"checkbox\" [(ngModel)]=\"result.selected\"\n (change)=\"onSelectChange(result)\"></td>\n <td>{{result.geo_adresse}}</td>\n <td>{{result.secteur_activite}}</td>\n <td>{{ result.annee_construction }}</td>\n <td>{{ result.classe_consommation_energie }}</td>\n <td>{{ result.classe_estimation_ges }}</td>\n </tr>\n </tbody>\n </table>\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onSaveResult()\"\n [disabled]=\"!selectedDpeResult\">{{'Save selected' |\n translate}}</button>\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onErase()\">\n {{'No match (erase data)' | translate}}</button>\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onCancel()\">\n {{'Cancel' | translate}}</button>\n </div>\n </div>\n\n <!-- Toggle button for the admin \"Copy POIs\" form -->\n <div *ngIf=\"isAdmin && spaces && spaces.length > 0\" class=\"mt-4\">\n <button class=\"btn btn-outline-secondary rounded-pill\" (click)=\"toggleCopyPoisForm()\">\n {{ (showCopyPoisForm ? 'matterportCopy.hideForm' : 'matterportCopy.showForm') | translate }}\n </button>\n </div>\n\n <!-- Admin Form to Copy POIs -->\n <div *ngIf=\"isAdmin && spaces && spaces.length > 0 && showCopyPoisForm\" class=\"mt-3 p-4 border rounded bg-light\">\n <h6>{{ 'matterportCopy.formTitle' | translate }}</h6>\n\n <div class=\"mb-3 col-md-5\">\n <label class=\"form-label\">{{ 'matterportCopy.sourceSpace' | translate }}</label>\n <select class=\"form-select\" [(ngModel)]=\"selectedSourceSpaceId\" (ngModelChange)=\"onSourceSpaceChange()\">\n <option [ngValue]=\"null\">{{ 'matterportCopy.selectSpace' | translate }}</option>\n <option *ngFor=\"let space of spaces\" [ngValue]=\"space.id\">{{space.name}}</option>\n </select>\n </div>\n\n <div class=\"mb-3 col-md-5\" *ngIf=\"sourceVisits\">\n <label class=\"form-label\">{{ 'matterportCopy.sourceVisit' | translate }}</label>\n <select class=\"form-select\" [(ngModel)]=\"selectedSource3dModel\" (ngModelChange)=\"onModelSelectionChange()\">\n <option [ngValue]=\"null\">{{ 'matterportCopy.selectVisit' | translate }}</option>\n <option *ngFor=\"let visit of sourceVisits\" [ngValue]=\"visit.model3d\">{{visit.name}}</option>\n </select>\n </div>\n\n <div class=\"mb-3 col-md-5\">\n <label class=\"form-label\">{{ 'matterportCopy.targetVisit' | translate }}</label>\n <select class=\"form-select\" [(ngModel)]=\"selectedTarget3dModel\" (ngModelChange)=\"onModelSelectionChange()\">\n <option [ngValue]=\"null\">{{ 'matterportCopy.selectVisit' | translate }}</option>\n <option *ngFor=\"let visit of visits\" [ngValue]=\"visit.model3d\">{{visit.name}}</option>\n </select>\n </div>\n\n <div *ngIf=\"selectedSourceSpaceId && selectedSource3dModel && selectedTarget3dModel\"\n class=\"border rounded p-3 mb-3 bg-white\">\n <p class=\"small text-muted mb-2\">\n {{ 'matterportCopy.landmarkInstructions' | translate }}\n </p>\n\n <p class=\"fw-bold small mb-2\">{{ 'matterportCopy.landmarkA' | translate }}</p>\n <div class=\"row mb-4\">\n <div class=\"col-6\">\n <lib-landmark-picker [visit3dModel]=\"selectedSource3dModel\" [sdkKey]=\"sdkKey\"\n [value]=\"landmarkSourceA\" title=\"{{ 'matterportCopy.sourceVisitLabel' | translate }}\"\n (pointPicked)=\"onSourceLandmarkPicked('A', $event)\">\n </lib-landmark-picker>\n </div>\n <div class=\"col-6\">\n <lib-landmark-picker [visit3dModel]=\"selectedTarget3dModel\" [sdkKey]=\"sdkKey\"\n [value]=\"landmarkTargetA\" title=\"{{ 'matterportCopy.targetVisitLabel' | translate }}\"\n (pointPicked)=\"onTargetLandmarkPicked('A', $event)\">\n </lib-landmark-picker>\n </div>\n </div>\n\n <p class=\"fw-bold small mb-2\">{{ 'matterportCopy.landmarkB' | translate }}</p>\n <div class=\"row\">\n <div class=\"col-6\">\n <lib-landmark-picker [visit3dModel]=\"selectedSource3dModel\" [sdkKey]=\"sdkKey\"\n [value]=\"landmarkSourceB\" title=\"{{ 'matterportCopy.sourceVisitLabel' | translate }}\"\n (pointPicked)=\"onSourceLandmarkPicked('B', $event)\">\n </lib-landmark-picker>\n </div>\n <div class=\"col-6\">\n <lib-landmark-picker [visit3dModel]=\"selectedTarget3dModel\" [sdkKey]=\"sdkKey\"\n [value]=\"landmarkTargetB\" title=\"{{ 'matterportCopy.targetVisitLabel' | translate }}\"\n (pointPicked)=\"onTargetLandmarkPicked('B', $event)\">\n </lib-landmark-picker>\n </div>\n </div>\n </div>\n\n <div class=\"d-flex align-items-center pt-2\">\n <button class=\"btn btn-primary rounded-pill me-3\" [disabled]=\"!canCopyPois || isCopyingPois\"\n (click)=\"onCopyPois()\">\n {{ 'matterportCopy.copyButton' | translate }}\n </button>\n <div class=\"d-flex align-items-center gap-2 mb-3\">\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary\" (click)=\"exportLandmarkConfig()\">\n {{ 'matterportCopy.exportLandmarks' | translate }}\n </button>\n\n <label class=\"btn btn-sm btn-outline-secondary mb-0\">\n {{ 'matterportCopy.importLandmarks' | translate }}\n <input type=\"file\" accept=\"application/json\" hidden\n (change)=\"onImportLandmarkConfigSelected($event)\">\n </label>\n </div>\n <div *ngIf=\"isCopyingPois\" class=\"spinner-border spinner-border-sm text-primary\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n </div>\n\n <div *ngIf=\"copyPoisResultMsg\" class=\"mt-2 text-success fw-bold\">\n {{ copyPoisResultMsg }}\n </div>\n <div *ngIf=\"copyProgress\" class=\"mt-3\">\n <div class=\"d-flex justify-content-between small mb-1\">\n <span>\n <ng-container [ngSwitch]=\"copyProgress.phase\">\n <span *ngSwitchCase=\"'collecting'\">{{ 'Collecting information from both visits...' | translate\n }}</span>\n <span *ngSwitchCase=\"'tickets'\">{{ 'Copying tickets' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'equipments'\">{{ 'Copying equipments' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'pois'\">{{ 'Copying standalone POIs' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'objects3d'\">{{ 'Copying 3D objects' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'features'\">{{ 'Copying features' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'measurements'\">{{ 'Copying measurements' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'done'\">{{ 'Done!' | translate }}</span>\n </ng-container>\n </span>\n <span>{{ copyProgress.percent }}%</span>\n </div>\n <div class=\"progress\" style=\"height: 6px;\">\n <div class=\"progress-bar\" [class.progress-bar-striped]=\"copyProgress.phase === 'collecting'\"\n [class.progress-bar-animated]=\"copyProgress.phase === 'collecting'\"\n [class.bg-warning]=\"copyProgress.errorCount > 0\" role=\"progressbar\"\n [style.width.%]=\"copyProgress.phase === 'collecting' ? 100 : copyProgress.percent\">\n </div>\n </div>\n\n <!-- Detailed step-by-step log -->\n <div *ngIf=\"copyLog.length > 0\" class=\"mt-2 p-2 bg-white border rounded small\"\n style=\"max-height: 200px; overflow-y: auto; font-family: monospace;\">\n <div *ngFor=\"let entry of copyLog\" [class.text-danger]=\"entry.type === 'error'\"\n [class.text-warning]=\"entry.type === 'healed'\">\n {{ entry.text }}\n </div>\n </div>\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary mt-2\" *ngIf=\"copyLog.length > 0\"\n (click)=\"downloadCopyLog()\">\n {{ 'matterportCopy.downloadLog' | translate }}\n </button>\n </div>\n </div>\n\n <lib-form-location *ngIf=\"isEditing\" [location]=\"space\" (onChange)=\"onFormChange($event)\"></lib-form-location>\n</div>" }]
1243
+ args: [{ selector: 'lib-detail-location', template: "<div class=\"container-fluid\">\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"reset()\"></lib-tab-navigation>\n </div>\n <button class=\"btn btn-outline-primary rounded-pill me-3\" (click)=\"onReturn()\">{{'Back to locations' |\n translate}}</button>\n <div class=\"row\" *ngIf=\"!isEditing && space\">\n <div class=\"col-md-5\">\n <ul class=\"list-group list-group-flush\">\n <li class=\"list-group-item bg-transparent\">{{'Name' | translate}}: {{space.name}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Address' | translate}}: {{space.addresses}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Construction year' | translate}}:\n {{space.constructionYear ?\n space.constructionYear : \"No data\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Latitude' | translate}}:\n {{space.latitude ?\n space.latitude : \"No data\" | translate}}</li>\n <li class=\"list-group-item bg-transparent\">{{'Longitude' | translate}}: {{space.longitude ?\n space.longitude : \"No data\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Access level' | translate}}: {{space.level | translate\n }} </li>\n <li class=\"list-group-item bg-transparent\">{{'Energy Class' | translate}}:\n {{space.classEnergyConsumption ?\n space.classEnergyConsumption : \"No data\" | translate}}\n <button *ngIf=\"space.status !== 'DPE_TO_VALIDATE'\"\n class=\"btn btn-outline-primary rounded-pill no-lowercase ms-5\" (click)=\"onGetDpeData()\">\n {{'Get data from API DPE' | translate}}</button>\n <a class=\"bg-transparent ms-5\" *ngIf=\"space.status === 'DPE_TO_VALIDATE'\" (click)=\"onDpeValidate()\"\n style=\"cursor: pointer;\">\n <span class=\"iconify\" data-icon=\"mdi:alert-circle-check\" style=\"color: #f19c80;\" data-width=\"25\"\n data-height=\"25\"></span>\n {{'DPE data found. Click to validate' | translate}}\n </a>\n </li>\n <!-- One picker for both viewers: the default lives on the space, so Matterport\n captures and 3D models compete for the same single slot. -->\n <li class=\"list-group-item bg-transparent\" *ngIf=\"visits.length > 1\">\n {{'Default visit' | translate}}:\n <select class=\"form-select d-inline-block ms-2\" style=\"width: auto;\"\n [(ngModel)]=\"defaultCaptureID\" (ngModelChange)=\"onDefaultCaptureChange()\"\n [disabled]=\"savingDefaultCapture\">\n <option [ngValue]=\"null\">{{'First available' | translate}}</option>\n <option *ngFor=\"let visit of visits\" [ngValue]=\"visit.captureID\">\n {{ visitLabel(visit) }}\n </option>\n </select>\n <span class=\"form-text d-block\">\n {{'What a visitor opens when they enter this location.' | translate}}\n </span>\n <span class=\"text-danger d-block\" *ngIf=\"defaultCaptureError\">\n {{ defaultCaptureError }}\n </span>\n </li>\n <li class=\"list-group-item bg-transparent\">{{'Greenhouse gas emission Class' | translate}}:\n {{space.classGes ? space.classGes : \"No data\" | translate}} </li>\n <li class=\"list-group-item bg-transparent\">{{'Shareable Guest Link' | translate}}:\n <div style=\"display: inline;\" *ngIf=\"guestLink\">\n <a id=\"linkHref\" target=\"_blank\">{{'Try the link' | translate }}</a>\n <div [cdkCopyToClipboard]=\"guestLink\" [style.cursor]=\"'pointer'\"\n style=\"margin-left: 5px; max-width: 20px; display: inline;\" ngbTooltip=\"Copied!\"\n triggers=\"click:blur\">\n <span class=\"iconify\" data-icon=\"mdi:content-copy\" data-inline=\"false\" data-width=\"20\"\n data-height=\"20\"></span>\n </div>\n </div>\n <p *ngIf=\"!guestLink\" style=\"display: inline;\">{{'No link' | translate }}</p>\n <p *ngIf=\"!guestLink\"><small>({{'Generate link from a VISITOR mission'|translate}})</small>\n </p>\n </li>\n\n </ul>\n <div class=\"d-flex justify-content-center\" *ngIf=\"gettingData\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n </div>\n <hr>\n <div class=\"d-flex\">\n <button class=\"btn btn-outline-primary rounded-pill me-3\" (click)=\"onEdit()\"\n data-testid=\"location-edit-btn\">{{'Edit' |\n translate}}</button>\n <div class=\"tooltip-wrapper\"\n ngbTooltip=\"{{!canArchive ? ('Contact SmarterPlan' | translate) : ('Archive location and related data' | translate)}}\">\n <button class=\"btn btn-outline-primary rounded-pill\" (click)=\"onArchive()\" [disabled]=\"!canArchive\">\n {{'Archive' | translate}}</button>\n </div>\n </div>\n\n\n </div>\n <div class=\"col-md-7\" *ngIf=\"isValidatingDpe\">\n <h6>{{'Most relevant results for' | translate}} :\n <b>diagnostics de performance \u00E9nerg\u00E9tique (DPE) des b\u00E2timents tertiaires</b>\n </h6>\n <table class=\"table table-striped\">\n <thead>\n <tr>\n <th scope=\"col\">#</th>\n <th scope=\"col\">{{'Apply to location' | translate}}</th>\n <th scope=\"col\">{{'Address' | translate}}</th>\n <th scope=\"col\">{{'Activity sector' | translate}}</th>\n <th scope=\"col\">{{'Construction year' | translate}}</th>\n <th scope=\"col\">{{'Energy Class' | translate}}</th>\n <th scope=\"col\">{{'Greenhouse gas emission Class' | translate}}</th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let result of parsedMetadata; index as i\">\n <th scope=\"row\">{{ i + 1 }}</th>\n <td><input class=\"checkbox-apply\" type=\"checkbox\" [(ngModel)]=\"result.selected\"\n (change)=\"onSelectChange(result)\"></td>\n <td>{{result.geo_adresse}}</td>\n <td>{{result.secteur_activite}}</td>\n <td>{{ result.annee_construction }}</td>\n <td>{{ result.classe_consommation_energie }}</td>\n <td>{{ result.classe_estimation_ges }}</td>\n </tr>\n </tbody>\n </table>\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onSaveResult()\"\n [disabled]=\"!selectedDpeResult\">{{'Save selected' |\n translate}}</button>\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onErase()\">\n {{'No match (erase data)' | translate}}</button>\n <button class=\"btn btn-outline-primary rounded-pill me-2\" (click)=\"onCancel()\">\n {{'Cancel' | translate}}</button>\n </div>\n </div>\n\n <!-- Toggle button for the admin \"Copy POIs\" form -->\n <div *ngIf=\"isAdmin && spaces && spaces.length > 0\" class=\"mt-4\">\n <button class=\"btn btn-outline-secondary rounded-pill\" (click)=\"toggleCopyPoisForm()\">\n {{ (showCopyPoisForm ? 'matterportCopy.hideForm' : 'matterportCopy.showForm') | translate }}\n </button>\n </div>\n\n <!-- Admin Form to Copy POIs -->\n <div *ngIf=\"isAdmin && spaces && spaces.length > 0 && showCopyPoisForm\" class=\"mt-3 p-4 border rounded bg-light\">\n <h6>{{ 'matterportCopy.formTitle' | translate }}</h6>\n\n <div class=\"mb-3 col-md-5\">\n <label class=\"form-label\">{{ 'matterportCopy.sourceSpace' | translate }}</label>\n <select class=\"form-select\" [(ngModel)]=\"selectedSourceSpaceId\" (ngModelChange)=\"onSourceSpaceChange()\">\n <option [ngValue]=\"null\">{{ 'matterportCopy.selectSpace' | translate }}</option>\n <option *ngFor=\"let space of spaces\" [ngValue]=\"space.id\">{{space.name}}</option>\n </select>\n </div>\n\n <div class=\"mb-3 col-md-5\" *ngIf=\"sourceVisits\">\n <label class=\"form-label\">{{ 'matterportCopy.sourceVisit' | translate }}</label>\n <select class=\"form-select\" [(ngModel)]=\"selectedSource3dModel\" (ngModelChange)=\"onModelSelectionChange()\">\n <option [ngValue]=\"null\">{{ 'matterportCopy.selectVisit' | translate }}</option>\n <option *ngFor=\"let visit of sourceVisits\" [ngValue]=\"visit.model3d\">{{visit.name}}</option>\n </select>\n </div>\n\n <div class=\"mb-3 col-md-5\">\n <label class=\"form-label\">{{ 'matterportCopy.targetVisit' | translate }}</label>\n <select class=\"form-select\" [(ngModel)]=\"selectedTarget3dModel\" (ngModelChange)=\"onModelSelectionChange()\">\n <option [ngValue]=\"null\">{{ 'matterportCopy.selectVisit' | translate }}</option>\n <option *ngFor=\"let visit of visits\" [ngValue]=\"visit.model3d\">{{visit.name}}</option>\n </select>\n </div>\n\n <div *ngIf=\"selectedSourceSpaceId && selectedSource3dModel && selectedTarget3dModel\"\n class=\"border rounded p-3 mb-3 bg-white\">\n <p class=\"small text-muted mb-2\">\n {{ 'matterportCopy.landmarkInstructions' | translate }}\n </p>\n\n <p class=\"fw-bold small mb-2\">{{ 'matterportCopy.landmarkA' | translate }}</p>\n <div class=\"row mb-4\">\n <div class=\"col-6\">\n <lib-landmark-picker [visit3dModel]=\"selectedSource3dModel\" [sdkKey]=\"sdkKey\"\n [value]=\"landmarkSourceA\" title=\"{{ 'matterportCopy.sourceVisitLabel' | translate }}\"\n (pointPicked)=\"onSourceLandmarkPicked('A', $event)\">\n </lib-landmark-picker>\n </div>\n <div class=\"col-6\">\n <lib-landmark-picker [visit3dModel]=\"selectedTarget3dModel\" [sdkKey]=\"sdkKey\"\n [value]=\"landmarkTargetA\" title=\"{{ 'matterportCopy.targetVisitLabel' | translate }}\"\n (pointPicked)=\"onTargetLandmarkPicked('A', $event)\">\n </lib-landmark-picker>\n </div>\n </div>\n\n <p class=\"fw-bold small mb-2\">{{ 'matterportCopy.landmarkB' | translate }}</p>\n <div class=\"row\">\n <div class=\"col-6\">\n <lib-landmark-picker [visit3dModel]=\"selectedSource3dModel\" [sdkKey]=\"sdkKey\"\n [value]=\"landmarkSourceB\" title=\"{{ 'matterportCopy.sourceVisitLabel' | translate }}\"\n (pointPicked)=\"onSourceLandmarkPicked('B', $event)\">\n </lib-landmark-picker>\n </div>\n <div class=\"col-6\">\n <lib-landmark-picker [visit3dModel]=\"selectedTarget3dModel\" [sdkKey]=\"sdkKey\"\n [value]=\"landmarkTargetB\" title=\"{{ 'matterportCopy.targetVisitLabel' | translate }}\"\n (pointPicked)=\"onTargetLandmarkPicked('B', $event)\">\n </lib-landmark-picker>\n </div>\n </div>\n </div>\n\n <div class=\"d-flex align-items-center pt-2\">\n <button class=\"btn btn-primary rounded-pill me-3\" [disabled]=\"!canCopyPois || isCopyingPois\"\n (click)=\"onCopyPois()\">\n {{ 'matterportCopy.copyButton' | translate }}\n </button>\n <div class=\"d-flex align-items-center gap-2 mb-3\">\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary\" (click)=\"exportLandmarkConfig()\">\n {{ 'matterportCopy.exportLandmarks' | translate }}\n </button>\n\n <label class=\"btn btn-sm btn-outline-secondary mb-0\">\n {{ 'matterportCopy.importLandmarks' | translate }}\n <input type=\"file\" accept=\"application/json\" hidden\n (change)=\"onImportLandmarkConfigSelected($event)\">\n </label>\n </div>\n <div *ngIf=\"isCopyingPois\" class=\"spinner-border spinner-border-sm text-primary\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n </div>\n\n <div *ngIf=\"copyPoisResultMsg\" class=\"mt-2 text-success fw-bold\">\n {{ copyPoisResultMsg }}\n </div>\n <div *ngIf=\"copyProgress\" class=\"mt-3\">\n <div class=\"d-flex justify-content-between small mb-1\">\n <span>\n <ng-container [ngSwitch]=\"copyProgress.phase\">\n <span *ngSwitchCase=\"'collecting'\">{{ 'Collecting information from both visits...' | translate\n }}</span>\n <span *ngSwitchCase=\"'tickets'\">{{ 'Copying tickets' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'equipments'\">{{ 'Copying equipments' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'pois'\">{{ 'Copying standalone POIs' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'objects3d'\">{{ 'Copying 3D objects' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'features'\">{{ 'Copying features' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'measurements'\">{{ 'Copying measurements' | translate }} ({{\n copyProgress.processedInPhase }}/{{ copyProgress.totalInPhase }})</span>\n <span *ngSwitchCase=\"'done'\">{{ 'Done!' | translate }}</span>\n </ng-container>\n </span>\n <span>{{ copyProgress.percent }}%</span>\n </div>\n <div class=\"progress\" style=\"height: 6px;\">\n <div class=\"progress-bar\" [class.progress-bar-striped]=\"copyProgress.phase === 'collecting'\"\n [class.progress-bar-animated]=\"copyProgress.phase === 'collecting'\"\n [class.bg-warning]=\"copyProgress.errorCount > 0\" role=\"progressbar\"\n [style.width.%]=\"copyProgress.phase === 'collecting' ? 100 : copyProgress.percent\">\n </div>\n </div>\n\n <!-- Detailed step-by-step log -->\n <div *ngIf=\"copyLog.length > 0\" class=\"mt-2 p-2 bg-white border rounded small\"\n style=\"max-height: 200px; overflow-y: auto; font-family: monospace;\">\n <div *ngFor=\"let entry of copyLog\" [class.text-danger]=\"entry.type === 'error'\"\n [class.text-warning]=\"entry.type === 'healed'\">\n {{ entry.text }}\n </div>\n </div>\n <button type=\"button\" class=\"btn btn-sm btn-outline-secondary mt-2\" *ngIf=\"copyLog.length > 0\"\n (click)=\"downloadCopyLog()\">\n {{ 'matterportCopy.downloadLog' | translate }}\n </button>\n </div>\n </div>\n\n <lib-form-location *ngIf=\"isEditing\" [location]=\"space\" (onChange)=\"onFormChange($event)\"></lib-form-location>\n</div>" }]
1208
1244
  }], ctorParameters: () => [{ type: undefined, decorators: [{
1209
1245
  type: Inject,
1210
1246
  args: [MATTERPORT_SDK_KEY]
@@ -2043,7 +2079,10 @@ class VisitsComponent {
2043
2079
  .getVisitsForSpaceForUser(this.spaceId)
2044
2080
  .then((visits) => {
2045
2081
  if (visits) {
2046
- this.visits = visits;
2082
+ // 3D models share this storage but have their own screen, so listing them here
2083
+ // too showed every model twice. They can still be created from this form; they
2084
+ // just belong to the other tab once they exist.
2085
+ this.visits = visits.filter((visit) => visit.viewer !== CaptureViewer.THREEJS);
2047
2086
  }
2048
2087
  });
2049
2088
  }