fx-form-builder-wrapper 2.0.58 → 2.0.61
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/lib/components/three-viewer/three-viewer.component.mjs +161 -0
- package/esm2022/lib/components/uploader/uploader.component.mjs +101 -11
- package/fesm2022/fx-form-builder-wrapper.mjs +273 -27
- package/fesm2022/fx-form-builder-wrapper.mjs.map +1 -1
- package/lib/components/three-viewer/three-viewer.component.d.ts +30 -0
- package/lib/components/uploader/uploader.component.d.ts +17 -2
- package/package.json +1 -1
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { Component, ViewChild, Input } from '@angular/core';
|
|
2
|
+
import * as THREE from 'three';
|
|
3
|
+
import { STLLoader } from 'three/examples/jsm/loaders/STLLoader.js';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
import * as i1 from "@angular/common/http";
|
|
6
|
+
export class ThreeViewerComponent {
|
|
7
|
+
http;
|
|
8
|
+
viewerContainer;
|
|
9
|
+
file;
|
|
10
|
+
manualFileUpload = null;
|
|
11
|
+
scene;
|
|
12
|
+
camera;
|
|
13
|
+
renderer;
|
|
14
|
+
loader = new STLLoader();
|
|
15
|
+
model;
|
|
16
|
+
isDragging = false;
|
|
17
|
+
previousMousePosition = { x: 0, y: 0 };
|
|
18
|
+
zoomSpeed = 1.1;
|
|
19
|
+
constructor(http) {
|
|
20
|
+
this.http = http;
|
|
21
|
+
}
|
|
22
|
+
ngAfterViewInit() {
|
|
23
|
+
this.initThree();
|
|
24
|
+
}
|
|
25
|
+
ngOnChanges(changes) {
|
|
26
|
+
if (changes['manualFileUpload']?.currentValue && this.manualFileUpload) {
|
|
27
|
+
this.loadModelFromBlob(this.manualFileUpload);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
ngOnDestroy() {
|
|
31
|
+
this.cleanupThreeJS();
|
|
32
|
+
}
|
|
33
|
+
initThree() {
|
|
34
|
+
const container = this.viewerContainer.nativeElement;
|
|
35
|
+
this.scene = new THREE.Scene();
|
|
36
|
+
this.scene.background = new THREE.Color(0xf0f0f0);
|
|
37
|
+
this.camera = new THREE.PerspectiveCamera(60, container.clientWidth / container.clientHeight, 0.1, 1000);
|
|
38
|
+
this.camera.position.set(0, 0, 100);
|
|
39
|
+
this.renderer = new THREE.WebGLRenderer({ antialias: true });
|
|
40
|
+
this.renderer.setSize(container.clientWidth, container.clientHeight);
|
|
41
|
+
container.appendChild(this.renderer.domElement);
|
|
42
|
+
const ambientLight = new THREE.AmbientLight(0x404040, 2);
|
|
43
|
+
this.scene.add(ambientLight);
|
|
44
|
+
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
|
|
45
|
+
directionalLight.position.set(1, 1, 1).normalize();
|
|
46
|
+
this.scene.add(directionalLight);
|
|
47
|
+
this.initControls();
|
|
48
|
+
this.animate();
|
|
49
|
+
}
|
|
50
|
+
initControls() {
|
|
51
|
+
const canvas = this.renderer.domElement;
|
|
52
|
+
// Mouse Drag for Rotation
|
|
53
|
+
canvas.addEventListener('mousedown', (event) => {
|
|
54
|
+
this.isDragging = true;
|
|
55
|
+
this.previousMousePosition.x = event.clientX;
|
|
56
|
+
this.previousMousePosition.y = event.clientY;
|
|
57
|
+
});
|
|
58
|
+
canvas.addEventListener('mouseup', () => {
|
|
59
|
+
this.isDragging = false;
|
|
60
|
+
});
|
|
61
|
+
canvas.addEventListener('mousemove', (event) => {
|
|
62
|
+
if (!this.isDragging)
|
|
63
|
+
return;
|
|
64
|
+
const deltaX = event.clientX - this.previousMousePosition.x;
|
|
65
|
+
const deltaY = event.clientY - this.previousMousePosition.y;
|
|
66
|
+
const rotationSpeed = 0.005;
|
|
67
|
+
this.model?.rotateY(deltaX * rotationSpeed);
|
|
68
|
+
this.model?.rotateX(deltaY * rotationSpeed);
|
|
69
|
+
this.previousMousePosition.x = event.clientX;
|
|
70
|
+
this.previousMousePosition.y = event.clientY;
|
|
71
|
+
});
|
|
72
|
+
// Scroll for Zoom
|
|
73
|
+
canvas.addEventListener('wheel', (event) => {
|
|
74
|
+
// event.preventDefault();
|
|
75
|
+
if (event.deltaY < 0) {
|
|
76
|
+
this.camera.position.multiplyScalar(1 / this.zoomSpeed); // Zoom In
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
this.camera.position.multiplyScalar(this.zoomSpeed); // Zoom Out
|
|
80
|
+
}
|
|
81
|
+
this.camera.updateProjectionMatrix();
|
|
82
|
+
});
|
|
83
|
+
// Resize Handling
|
|
84
|
+
window.addEventListener('resize', () => this.onWindowResize());
|
|
85
|
+
}
|
|
86
|
+
loadModelFromBlob(blob) {
|
|
87
|
+
const reader = new FileReader();
|
|
88
|
+
reader.onload = () => {
|
|
89
|
+
const arrayBuffer = reader.result;
|
|
90
|
+
const geometry = this.loader.parse(arrayBuffer);
|
|
91
|
+
geometry.computeVertexNormals();
|
|
92
|
+
if (this.model) {
|
|
93
|
+
this.scene.remove(this.model);
|
|
94
|
+
this.model.geometry.dispose();
|
|
95
|
+
}
|
|
96
|
+
const material = new THREE.MeshPhysicalMaterial({
|
|
97
|
+
color: 0xF8F0E3,
|
|
98
|
+
metalness: 0.1,
|
|
99
|
+
roughness: 0.5,
|
|
100
|
+
transmission: 0.5, // Creates slight translucency
|
|
101
|
+
clearcoat: 1.0, // Adds enamel-like reflection
|
|
102
|
+
clearcoatRoughness: 0.3
|
|
103
|
+
});
|
|
104
|
+
this.model = new THREE.Mesh(geometry, material);
|
|
105
|
+
this.scene.add(this.model);
|
|
106
|
+
this.centerModel();
|
|
107
|
+
};
|
|
108
|
+
reader.readAsArrayBuffer(blob);
|
|
109
|
+
}
|
|
110
|
+
centerModel() {
|
|
111
|
+
if (!this.model)
|
|
112
|
+
return;
|
|
113
|
+
const box = new THREE.Box3().setFromObject(this.model);
|
|
114
|
+
const center = new THREE.Vector3();
|
|
115
|
+
box.getCenter(center);
|
|
116
|
+
this.model.position.sub(center);
|
|
117
|
+
const size = box.getSize(new THREE.Vector3()).length();
|
|
118
|
+
this.camera.position.set(0, 0, size * 2);
|
|
119
|
+
this.camera.updateProjectionMatrix();
|
|
120
|
+
this.onWindowResize();
|
|
121
|
+
}
|
|
122
|
+
animate = () => {
|
|
123
|
+
requestAnimationFrame(this.animate);
|
|
124
|
+
this.renderer.render(this.scene, this.camera);
|
|
125
|
+
};
|
|
126
|
+
onWindowResize() {
|
|
127
|
+
const container = this.viewerContainer.nativeElement;
|
|
128
|
+
this.camera.aspect = container.clientWidth / container.clientHeight;
|
|
129
|
+
this.camera.updateProjectionMatrix();
|
|
130
|
+
this.renderer.setSize(container.clientWidth, container.clientHeight);
|
|
131
|
+
}
|
|
132
|
+
cleanupThreeJS() {
|
|
133
|
+
// Remove event listeners
|
|
134
|
+
const canvas = this.renderer.domElement;
|
|
135
|
+
canvas.removeEventListener('mousedown', () => { });
|
|
136
|
+
canvas.removeEventListener('mouseup', () => { });
|
|
137
|
+
canvas.removeEventListener('mousemove', () => { });
|
|
138
|
+
canvas.removeEventListener('wheel', () => { });
|
|
139
|
+
window.removeEventListener('resize', () => this.onWindowResize());
|
|
140
|
+
// Dispose of Three.js resources
|
|
141
|
+
if (this.model) {
|
|
142
|
+
this.scene.remove(this.model);
|
|
143
|
+
this.model.geometry.dispose();
|
|
144
|
+
}
|
|
145
|
+
this.renderer.dispose();
|
|
146
|
+
}
|
|
147
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ThreeViewerComponent, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Component });
|
|
148
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ThreeViewerComponent, isStandalone: true, selector: "app-three-viewer", inputs: { file: "file", manualFileUpload: "manualFileUpload" }, viewQueries: [{ propertyName: "viewerContainer", first: true, predicate: ["viewerContainer"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div #viewerContainer class=\"viewer-container\"></div>\r\n ", styles: [".viewer-container{position:relative;width:100%;max-height:500px;overflow:hidden}button{position:absolute;top:10px;background:#000000b3;color:#fff;border:none;padding:5px 10px;cursor:pointer;margin:5px}button:hover{background:#000000e6}::ng-deep canvas{display:block;width:100%!important;height:100%!important;min-height:450px!important;min-width:986px!important}@media (min-width: 1600px){.viewer-container{width:100%;max-height:650px}canvas{min-width:1326px!important}}\n"] });
|
|
149
|
+
}
|
|
150
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ThreeViewerComponent, decorators: [{
|
|
151
|
+
type: Component,
|
|
152
|
+
args: [{ selector: 'app-three-viewer', standalone: true, template: "<div #viewerContainer class=\"viewer-container\"></div>\r\n ", styles: [".viewer-container{position:relative;width:100%;max-height:500px;overflow:hidden}button{position:absolute;top:10px;background:#000000b3;color:#fff;border:none;padding:5px 10px;cursor:pointer;margin:5px}button:hover{background:#000000e6}::ng-deep canvas{display:block;width:100%!important;height:100%!important;min-height:450px!important;min-width:986px!important}@media (min-width: 1600px){.viewer-container{width:100%;max-height:650px}canvas{min-width:1326px!important}}\n"] }]
|
|
153
|
+
}], ctorParameters: () => [{ type: i1.HttpClient }], propDecorators: { viewerContainer: [{
|
|
154
|
+
type: ViewChild,
|
|
155
|
+
args: ['viewerContainer', { static: true }]
|
|
156
|
+
}], file: [{
|
|
157
|
+
type: Input
|
|
158
|
+
}], manualFileUpload: [{
|
|
159
|
+
type: Input
|
|
160
|
+
}] } });
|
|
161
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGhyZWUtdmlld2VyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Z4LWJ1aWxkZXItd3JhcHBlci9zcmMvbGliL2NvbXBvbmVudHMvdGhyZWUtdmlld2VyL3RocmVlLXZpZXdlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9meC1idWlsZGVyLXdyYXBwZXIvc3JjL2xpYi9jb21wb25lbnRzL3RocmVlLXZpZXdlci90aHJlZS12aWV3ZXIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFBNkIsU0FBUyxFQUFFLEtBQUssRUFDdkQsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxLQUFLLEtBQUssTUFBTSxPQUFPLENBQUM7QUFDL0IsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHlDQUF5QyxDQUFDOzs7QUFRcEUsTUFBTSxPQUFPLG9CQUFvQjtJQWVYO0lBZDRCLGVBQWUsQ0FBYztJQUNwRSxJQUFJLENBQU87SUFDWCxnQkFBZ0IsR0FBZ0IsSUFBSSxDQUFDO0lBRXRDLEtBQUssQ0FBZTtJQUNwQixNQUFNLENBQTJCO0lBQ2pDLFFBQVEsQ0FBdUI7SUFDL0IsTUFBTSxHQUFHLElBQUksU0FBUyxFQUFFLENBQUM7SUFDekIsS0FBSyxDQUFxQjtJQUUxQixVQUFVLEdBQUcsS0FBSyxDQUFDO0lBQ25CLHFCQUFxQixHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFDdkMsU0FBUyxHQUFHLEdBQUcsQ0FBQztJQUV4QixZQUFvQixJQUFnQjtRQUFoQixTQUFJLEdBQUosSUFBSSxDQUFZO0lBQUcsQ0FBQztJQUV4QyxlQUFlO1FBQ2IsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQ25CLENBQUM7SUFFRCxXQUFXLENBQUMsT0FBc0I7UUFDaEMs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dGVudCI6WyJpbXBvcnQgeyBcclxuICBDb21wb25lbnQsIEVsZW1lbnRSZWYsIEFmdGVyVmlld0luaXQsIFZpZXdDaGlsZCwgSW5wdXQsIE9uQ2hhbmdlcywgU2ltcGxlQ2hhbmdlcywgT25EZXN0cm95IFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xyXG5pbXBvcnQgKiBhcyBUSFJFRSBmcm9tICd0aHJlZSc7XHJcbmltcG9ydCB7IFNUTExvYWRlciB9IGZyb20gJ3RocmVlL2V4YW1wbGVzL2pzbS9sb2FkZXJzL1NUTExvYWRlci5qcyc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2FwcC10aHJlZS12aWV3ZXInLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi90aHJlZS12aWV3ZXIuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL3RocmVlLXZpZXdlci5jb21wb25lbnQuc2NzcyddLFxyXG4gIHN0YW5kYWxvbmU6IHRydWVcclxufSlcclxuZXhwb3J0IGNsYXNzIFRocmVlVmlld2VyQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xyXG4gIEBWaWV3Q2hpbGQoJ3ZpZXdlckNvbnRhaW5lcicsIHsgc3RhdGljOiB0cnVlIH0pIHZpZXdlckNvbnRhaW5lciE6IEVsZW1lbnRSZWY7XHJcbiAgQElucHV0KCkgZmlsZSE6IGFueTtcclxuICBASW5wdXQoKSBtYW51YWxGaWxlVXBsb2FkOiBCbG9iIHwgbnVsbCA9IG51bGw7XHJcblxyXG4gIHByaXZhdGUgc2NlbmUhOiBUSFJFRS5TY2VuZTtcclxuICBwcml2YXRlIGNhbWVyYSE6IFRIUkVFLlBlcnNwZWN0aXZlQ2FtZXJhO1xyXG4gIHByaXZhdGUgcmVuZGVyZXIhOiBUSFJFRS5XZWJHTFJlbmRlcmVyO1xyXG4gIHByaXZhdGUgbG9hZGVyID0gbmV3IFNUTExvYWRlcigpO1xyXG4gIHByaXZhdGUgbW9kZWwhOiBUSFJFRS5NZXNoIHwgbnVsbDtcclxuXHJcbiAgcHJpdmF0ZSBpc0RyYWdnaW5nID0gZmFsc2U7XHJcbiAgcHJpdmF0ZSBwcmV2aW91c01vdXNlUG9zaXRpb24gPSB7IHg6IDAsIHk6IDAgfTtcclxuICBwcml2YXRlIHpvb21TcGVlZCA9IDEuMTtcclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBodHRwOiBIdHRwQ2xpZW50KSB7fVxyXG5cclxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XHJcbiAgICB0aGlzLmluaXRUaHJlZSgpO1xyXG4gIH1cclxuXHJcbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xyXG4gICAgaWYgKGNoYW5nZXNbJ21hbnVhbEZpbGVVcGxvYWQnXT8uY3VycmVudFZhbHVlICYmIHRoaXMubWFudWFsRmlsZVVwbG9hZCkge1xyXG4gICAgICB0aGlzLmxvYWRNb2RlbEZyb21CbG9iKHRoaXMubWFudWFsRmlsZVVwbG9hZCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcclxuICAgIHRoaXMuY2xlYW51cFRocmVlSlMoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgaW5pdFRocmVlKCk6IHZvaWQge1xyXG4gICAgY29uc3QgY29udGFpbmVyID0gdGhpcy52aWV3ZXJDb250YWluZXIubmF0aXZlRWxlbWVudDtcclxuICAgIHRoaXMuc2NlbmUgPSBuZXcgVEhSRUUuU2NlbmUoKTtcclxuICAgIHRoaXMuc2NlbmUuYmFja2dyb3VuZCA9IG5ldyBUSFJFRS5Db2xvcigweGYwZjBmMCk7XHJcblxyXG4gICAgdGhpcy5jYW1lcmEgPSBuZXcgVEhSRUUuUGVyc3BlY3RpdmVDYW1lcmEoNjAsIGNvbnRhaW5lci5jbGllbnRXaWR0aCAvIGNvbnRhaW5lci5jbGllbnRIZWlnaHQsIDAuMSwgMTAwMCk7XHJcbiAgICB0aGlzLmNhbWVyYS5wb3NpdGlvbi5zZXQoMCwgMCwgMTAwKTtcclxuXHJcbiAgICB0aGlzLnJlbmRlcmVyID0gbmV3IFRIUkVFLldlYkdMUmVuZGVyZXIoeyBhbnRpYWxpYXM6IHRydWUgfSk7XHJcbiAgICB0aGlzLnJlbmRlcmVyLnNldFNpemUoY29udGFpbmVyLmNsaWVudFdpZHRoLCBjb250YWluZXIuY2xpZW50SGVpZ2h0KTtcclxuICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZCh0aGlzLnJlbmRlcmVyLmRvbUVsZW1lbnQpO1xyXG5cclxuICAgIGNvbnN0IGFtYmllbnRMaWdodCA9IG5ldyBUSFJFRS5BbWJpZW50TGlnaHQoMHg0MDQwNDAsIDIpO1xyXG4gICAgdGhpcy5zY2VuZS5hZGQoYW1iaWVudExpZ2h0KTtcclxuXHJcbiAgICBjb25zdCBkaXJlY3Rpb25hbExpZ2h0ID0gbmV3IFRIUkVFLkRpcmVjdGlvbmFsTGlnaHQoMHhmZmZmZmYsIDEpO1xyXG4gICAgZGlyZWN0aW9uYWxMaWdodC5wb3NpdGlvbi5zZXQoMSwgMSwgMSkubm9ybWFsaXplKCk7XHJcbiAgICB0aGlzLnNjZW5lLmFkZChkaXJlY3Rpb25hbExpZ2h0KTtcclxuXHJcbiAgICB0aGlzLmluaXRDb250cm9scygpO1xyXG4gICAgdGhpcy5hbmltYXRlKCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGluaXRDb250cm9scygpOiB2b2lkIHtcclxuICAgIGNvbnN0IGNhbnZhcyA9IHRoaXMucmVuZGVyZXIuZG9tRWxlbWVudDtcclxuXHJcbiAgICAvLyBNb3VzZSBEcmFnIGZvciBSb3RhdGlvblxyXG4gICAgY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIChldmVudCkgPT4ge1xyXG4gICAgICB0aGlzLmlzRHJhZ2dpbmcgPSB0cnVlO1xyXG4gICAgICB0aGlzLnByZXZpb3VzTW91c2VQb3NpdGlvbi54ID0gZXZlbnQuY2xpZW50WDtcclxuICAgICAgdGhpcy5wcmV2aW91c01vdXNlUG9zaXRpb24ueSA9IGV2ZW50LmNsaWVudFk7XHJcbiAgICB9KTtcclxuXHJcbiAgICBjYW52YXMuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsICgpID0+IHtcclxuICAgICAgdGhpcy5pc0RyYWdnaW5nID0gZmFsc2U7XHJcbiAgICB9KTtcclxuXHJcbiAgICBjYW52YXMuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgKGV2ZW50KSA9PiB7XHJcbiAgICAgIGlmICghdGhpcy5pc0RyYWdnaW5nKSByZXR1cm47XHJcblxyXG4gICAgICBjb25zdCBkZWx0YVggPSBldmVudC5jbGllbnRYIC0gdGhpcy5wcmV2aW91c01vdXNlUG9zaXRpb24ueDtcclxuICAgICAgY29uc3QgZGVsdGFZID0gZXZlbnQuY2xpZW50WSAtIHRoaXMucHJldmlvdXNNb3VzZVBvc2l0aW9uLnk7XHJcblxyXG4gICAgICBjb25zdCByb3RhdGlvblNwZWVkID0gMC4wMDU7XHJcbiAgICAgIHRoaXMubW9kZWw/LnJvdGF0ZVkoZGVsdGFYICogcm90YXRpb25TcGVlZCk7XHJcbiAgICAgIHRoaXMubW9kZWw/LnJvdGF0ZVgoZGVsdGFZICogcm90YXRpb25TcGVlZCk7XHJcblxyXG4gICAgICB0aGlzLnByZXZpb3VzTW91c2VQb3NpdGlvbi54ID0gZXZlbnQuY2xpZW50WDtcclxuICAgICAgdGhpcy5wcmV2aW91c01vdXNlUG9zaXRpb24ueSA9IGV2ZW50LmNsaWVudFk7XHJcbiAgICB9KTtcclxuXHJcbiAgICAvLyBTY3JvbGwgZm9yIFpvb21cclxuICAgIGNhbnZhcy5hZGRFdmVudExpc3RlbmVyKCd3aGVlbCcsIChldmVudCkgPT4ge1xyXG4gICAgICAvLyBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICBpZiAoZXZlbnQuZGVsdGFZIDwgMCkge1xyXG4gICAgICAgIHRoaXMuY2FtZXJhLnBvc2l0aW9uLm11bHRpcGx5U2NhbGFyKDEgLyB0aGlzLnpvb21TcGVlZCk7IC8vIFpvb20gSW5cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLmNhbWVyYS5wb3NpdGlvbi5tdWx0aXBseVNjYWxhcih0aGlzLnpvb21TcGVlZCk7IC8vIFpvb20gT3V0XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5jYW1lcmEudXBkYXRlUHJvamVjdGlvbk1hdHJpeCgpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgLy8gUmVzaXplIEhhbmRsaW5nXHJcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgKCkgPT4gdGhpcy5vbldpbmRvd1Jlc2l6ZSgpKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgbG9hZE1vZGVsRnJvbUJsb2IoYmxvYjogQmxvYik6IHZvaWQge1xyXG4gICAgY29uc3QgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcclxuICAgIHJlYWRlci5vbmxvYWQgPSAoKSA9PiB7XHJcbiAgICAgIGNvbnN0IGFycmF5QnVmZmVyID0gcmVhZGVyLnJlc3VsdCBhcyBBcnJheUJ1ZmZlcjtcclxuICAgICAgY29uc3QgZ2VvbWV0cnkgPSB0aGlzLmxvYWRlci5wYXJzZShhcnJheUJ1ZmZlcik7XHJcbiAgICAgIGdlb21ldHJ5LmNvbXB1dGVWZXJ0ZXhOb3JtYWxzKCk7XHJcblxyXG4gICAgICBpZiAodGhpcy5tb2RlbCkge1xyXG4gICAgICAgIHRoaXMuc2NlbmUucmVtb3ZlKHRoaXMubW9kZWwpO1xyXG4gICAgICAgIHRoaXMubW9kZWwuZ2VvbWV0cnkuZGlzcG9zZSgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBjb25zdCBtYXRlcmlhbCA9IG5ldyBUSFJFRS5NZXNoUGh5c2ljYWxNYXRlcmlhbCh7XHJcbiAgICAgICAgY29sb3I6IDB4RjhGMEUzLFxyXG4gICAgICAgIG1ldGFsbmVzczogMC4xLFxyXG4gICAgICAgIHJvdWdobmVzczogMC41LFxyXG4gICAgICAgIHRyYW5zbWlzc2lvbjogMC41LCAvLyBDcmVhdGVzIHNsaWdodCB0cmFuc2x1Y2VuY3lcclxuICAgICAgICBjbGVhcmNvYXQ6IDEuMCwgICAgLy8gQWRkcyBlbmFtZWwtbGlrZSByZWZsZWN0aW9uXHJcbiAgICAgICAgY2xlYXJjb2F0Um91Z2huZXNzOiAwLjNcclxuICAgICAgfSk7XHJcbiAgICAgIFxyXG4gICAgICB0aGlzLm1vZGVsID0gbmV3IFRIUkVFLk1lc2goZ2VvbWV0cnksIG1hdGVyaWFsKTtcclxuICAgICAgdGhpcy5zY2VuZS5hZGQodGhpcy5tb2RlbCk7XHJcblxyXG4gICAgICB0aGlzLmNlbnRlck1vZGVsKCk7XHJcbiAgICB9O1xyXG4gICAgcmVhZGVyLnJlYWRBc0FycmF5QnVmZmVyKGJsb2IpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjZW50ZXJNb2RlbCgpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy5tb2RlbCkgcmV0dXJuO1xyXG4gICAgY29uc3QgYm94ID0gbmV3IFRIUkVFLkJveDMoKS5zZXRGcm9tT2JqZWN0KHRoaXMubW9kZWwpO1xyXG4gICAgY29uc3QgY2VudGVyID0gbmV3IFRIUkVFLlZlY3RvcjMoKTtcclxuICAgIGJveC5nZXRDZW50ZXIoY2VudGVyKTtcclxuICAgIHRoaXMubW9kZWwucG9zaXRpb24uc3ViKGNlbnRlcik7XHJcblxyXG4gICAgY29uc3Qgc2l6ZSA9IGJveC5nZXRTaXplKG5ldyBUSFJFRS5WZWN0b3IzKCkpLmxlbmd0aCgpO1xyXG4gICAgdGhpcy5jYW1lcmEucG9zaXRpb24uc2V0KDAsIDAsIHNpemUgKiAyKTtcclxuICAgIHRoaXMuY2FtZXJhLnVwZGF0ZVByb2plY3Rpb25NYXRyaXgoKTtcclxuICAgIHRoaXMub25XaW5kb3dSZXNpemUoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYW5pbWF0ZSA9ICgpOiB2b2lkID0+IHtcclxuICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLmFuaW1hdGUpO1xyXG4gICAgdGhpcy5yZW5kZXJlci5yZW5kZXIodGhpcy5zY2VuZSwgdGhpcy5jYW1lcmEpO1xyXG4gIH07XHJcblxyXG4gIG9uV2luZG93UmVzaXplKCk6IHZvaWQge1xyXG4gICAgY29uc3QgY29udGFpbmVyID0gdGhpcy52aWV3ZXJDb250YWluZXIubmF0aXZlRWxlbWVudDtcclxuICAgIHRoaXMuY2FtZXJhLmFzcGVjdCA9IGNvbnRhaW5lci5jbGllbnRXaWR0aCAvIGNvbnRhaW5lci5jbGllbnRIZWlnaHQ7XHJcbiAgICB0aGlzLmNhbWVyYS51cGRhdGVQcm9qZWN0aW9uTWF0cml4KCk7XHJcbiAgICB0aGlzLnJlbmRlcmVyLnNldFNpemUoY29udGFpbmVyLmNsaWVudFdpZHRoLCBjb250YWluZXIuY2xpZW50SGVpZ2h0KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgY2xlYW51cFRocmVlSlMoKTogdm9pZCB7XHJcbiAgICAvLyBSZW1vdmUgZXZlbnQgbGlzdGVuZXJzXHJcbiAgICBjb25zdCBjYW52YXMgPSB0aGlzLnJlbmRlcmVyLmRvbUVsZW1lbnQ7XHJcbiAgICBjYW52YXMucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgKCkgPT4ge30pO1xyXG4gICAgY2FudmFzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCAoKSA9PiB7fSk7XHJcbiAgICBjYW52YXMucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgKCkgPT4ge30pO1xyXG4gICAgY2FudmFzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3doZWVsJywgKCkgPT4ge30pO1xyXG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsICgpID0+IHRoaXMub25XaW5kb3dSZXNpemUoKSk7XHJcblxyXG4gICAgLy8gRGlzcG9zZSBvZiBUaHJlZS5qcyByZXNvdXJjZXNcclxuICAgIGlmICh0aGlzLm1vZGVsKSB7XHJcbiAgICAgIHRoaXMuc2NlbmUucmVtb3ZlKHRoaXMubW9kZWwpO1xyXG4gICAgICB0aGlzLm1vZGVsLmdlb21ldHJ5LmRpc3Bvc2UoKTtcclxuICAgIH1cclxuICAgIHRoaXMucmVuZGVyZXIuZGlzcG9zZSgpO1xyXG4gIH1cclxufVxyXG4iLCI8ZGl2ICN2aWV3ZXJDb250YWluZXIgY2xhc3M9XCJ2aWV3ZXItY29udGFpbmVyXCI+PC9kaXY+XHJcbiAgIl19
|