@wolsok/thanos 3.0.0 → 16.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,199 +0,0 @@
1
- export class SimplexNoise {
2
- constructor(options) {
3
- this.memScale3D = {};
4
- const { min, max, random, amplitude, frequency, octaves, persistence } = createOptionsWithDefaults(options);
5
- this.random = random;
6
- this.amplitude = amplitude;
7
- this.frequency = frequency;
8
- this.octaves = octaves;
9
- this.persistence = persistence;
10
- this.scale =
11
- min === -1 && max === 1
12
- ? (value) => value
13
- : (value) => min + ((value + 1) / 2) * (max - min);
14
- const p = new Uint8Array(256);
15
- for (let i = 0; i < 256; i++) {
16
- p[i] = i;
17
- }
18
- let n;
19
- let q;
20
- for (let i = 255; i > 0; i--) {
21
- n = Math.floor((i + 1) * this.random());
22
- q = p[i];
23
- p[i] = p[n];
24
- p[n] = q;
25
- }
26
- this.perm = new Uint8Array(512);
27
- this.permMod12 = new Uint8Array(512);
28
- for (let i = 0; i < 512; i++) {
29
- this.perm[i] = p[i & 255];
30
- this.permMod12[i] = this.perm[i] % 12;
31
- }
32
- }
33
- dot(gs, coords) {
34
- return gs
35
- .slice(0, Math.min(gs.length, coords.length))
36
- .reduce((total, g, i) => total + g * coords[i], 0);
37
- }
38
- raw3D(x, y, z) {
39
- // Skew the input space to determine which simplex cell we're in
40
- const s = (x + y + z) / 3.0; // Very nice and simple skew factor for 3D
41
- const i = Math.floor(x + s);
42
- const j = Math.floor(y + s);
43
- const k = Math.floor(z + s);
44
- const t = (i + j + k) * SimplexNoise.G3;
45
- const X0 = i - t; // Unskew the cell origin back to (x,y,z) space
46
- const Y0 = j - t;
47
- const Z0 = k - t;
48
- const x0 = x - X0; // The x,y,z distances from the cell origin
49
- const y0 = y - Y0;
50
- const z0 = z - Z0;
51
- // Determine which simplex we are in
52
- let i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords
53
- let i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords
54
- if (x0 >= y0) {
55
- if (y0 >= z0) {
56
- i1 = i2 = j2 = 1;
57
- j1 = k1 = k2 = 0;
58
- }
59
- else if (x0 >= z0) {
60
- i1 = i2 = k2 = 1;
61
- j1 = k1 = j2 = 0;
62
- }
63
- else {
64
- k1 = i2 = k2 = 1;
65
- i1 = j1 = j2 = 0;
66
- }
67
- }
68
- else {
69
- if (y0 < z0) {
70
- k1 = j2 = k2 = 1;
71
- i1 = j1 = i2 = 0;
72
- }
73
- else if (x0 < z0) {
74
- j1 = j2 = k2 = 1;
75
- i1 = k1 = i2 = 0;
76
- }
77
- else {
78
- j1 = i2 = j2 = 1;
79
- i1 = k1 = k2 = 0;
80
- }
81
- }
82
- const x1 = x0 - i1 + SimplexNoise.G3; // Offsets for second corner in (x,y,z) coords
83
- const y1 = y0 - j1 + SimplexNoise.G3;
84
- const z1 = z0 - k1 + SimplexNoise.G3;
85
- const x2 = x0 - i2 + 2.0 * SimplexNoise.G3; // Offsets for third corner in (x,y,z) coords
86
- const y2 = y0 - j2 + 2.0 * SimplexNoise.G3;
87
- const z2 = z0 - k2 + 2.0 * SimplexNoise.G3;
88
- const x3 = x0 - 1.0 + 3.0 * SimplexNoise.G3; // Offsets for last corner in (x,y,z) coords
89
- const y3 = y0 - 1.0 + 3.0 * SimplexNoise.G3;
90
- const z3 = z0 - 1.0 + 3.0 * SimplexNoise.G3;
91
- // Work out the hashed gradient indices of the four simplex corners
92
- const ii = i & 255;
93
- const jj = j & 255;
94
- const kk = k & 255;
95
- const gi0 = this.permMod12[ii + this.perm[jj + this.perm[kk]]];
96
- const gi1 = this.permMod12[ii + i1 + this.perm[jj + j1 + this.perm[kk + k1]]];
97
- const gi2 = this.permMod12[ii + i2 + this.perm[jj + j2 + this.perm[kk + k2]]];
98
- const gi3 = this.permMod12[ii + 1 + this.perm[jj + 1 + this.perm[kk + 1]]];
99
- // Calculate the contribution from the four corners
100
- const t0 = 0.5 - x0 * x0 - y0 * y0 - z0 * z0;
101
- const n0 = t0 < 0
102
- ? 0.0
103
- : Math.pow(t0, 4) * this.dot(SimplexNoise.GRAD3D[gi0], [x0, y0, z0]);
104
- const t1 = 0.5 - x1 * x1 - y1 * y1 - z1 * z1;
105
- const n1 = t1 < 0
106
- ? 0.0
107
- : Math.pow(t1, 4) * this.dot(SimplexNoise.GRAD3D[gi1], [x1, y1, z1]);
108
- const t2 = 0.5 - x2 * x2 - y2 * y2 - z2 * z2;
109
- const n2 = t2 < 0
110
- ? 0.0
111
- : Math.pow(t2, 4) * this.dot(SimplexNoise.GRAD3D[gi2], [x2, y2, z2]);
112
- const t3 = 0.5 - x3 * x3 - y3 * y3 - z3 * z3;
113
- const n3 = t3 < 0
114
- ? 0.0
115
- : Math.pow(t3, 4) * this.dot(SimplexNoise.GRAD3D[gi3], [x3, y3, z3]);
116
- // Add contributions from each corner to get the final noise value.
117
- // The result is scaled to stay just inside [-1,1]
118
- return 94.68493150681972 * (n0 + n1 + n2 + n3);
119
- }
120
- scaled3D(x, y, z, resolution) {
121
- const memIndex = `${Math.round(x * resolution)}${Math.round(y * resolution)}${Math.round(z * resolution)}`;
122
- const memElem = this.memScale3D[memIndex];
123
- if (memElem != null) {
124
- return memElem;
125
- }
126
- let amplitude = this.amplitude;
127
- let frequency = this.frequency;
128
- let maxAmplitude = 0;
129
- let noise = 0;
130
- for (let i = 0; i < this.octaves; i++) {
131
- noise +=
132
- this.raw3D(x * frequency, y * frequency, z * frequency) * amplitude;
133
- maxAmplitude += amplitude;
134
- amplitude *= this.persistence;
135
- frequency *= 2;
136
- }
137
- const result = this.scale(noise / maxAmplitude);
138
- this.memScale3D[memIndex] = result;
139
- return result;
140
- }
141
- }
142
- SimplexNoise.G3 = 1.0 / 6.0;
143
- SimplexNoise.GRAD3D = [
144
- [1, 1, 0],
145
- [-1, 1, 0],
146
- [1, -1, 0],
147
- [-1, -1, 0],
148
- [1, 0, 1],
149
- [-1, 0, 1],
150
- [1, 0, -1],
151
- [-1, 0, -1],
152
- [0, 1, 1],
153
- [0, -1, -1],
154
- [0, 1, -1],
155
- [0, -1, -1],
156
- ];
157
- function createOptionsWithDefaults(options) {
158
- if (options != null) {
159
- if (options['amplitude'] && typeof options.amplitude !== 'number') {
160
- throw new Error('options.amplitude must be a number');
161
- }
162
- if (options['frequency'] && typeof options.frequency !== 'number') {
163
- throw new Error('options.frequency must be a number');
164
- }
165
- if (options['octaves'] &&
166
- (typeof options.octaves !== 'number' ||
167
- !isFinite(options.octaves) ||
168
- Math.floor(options.octaves) !== options.octaves)) {
169
- throw new Error('options.octaves must be an integer');
170
- }
171
- if (options['persistence'] && typeof options.persistence !== 'number') {
172
- throw new Error('options.persistence must be a number');
173
- }
174
- if (options['random'] && typeof options.random !== 'function') {
175
- throw new Error('options.random must be a function');
176
- }
177
- if (options['min'] && typeof options.min !== 'number') {
178
- throw new Error('options.min must be a number');
179
- }
180
- if (options['max'] && typeof options.max !== 'number') {
181
- throw new Error('options.max must be a number');
182
- }
183
- }
184
- const optionsResult = {
185
- amplitude: 1.0,
186
- frequency: 1.0,
187
- max: 1.0,
188
- min: -1.0,
189
- octaves: 1,
190
- persistence: 0.5,
191
- random: Math.random,
192
- ...options,
193
- };
194
- if (optionsResult.min > optionsResult.max) {
195
- throw new Error('min must be smaller max');
196
- }
197
- return optionsResult;
198
- }
199
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2ltcGxleC1ub2lzZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvcHVibGljL3dzLXRoYW5vcy9zcmMvbGliL3NpbXBsZXgtbm9pc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsTUFBTSxPQUFPLFlBQVk7SUFDdkIsWUFBWSxPQUFzQztRQThEMUMsZUFBVSxHQUE4QixFQUFFLENBQUM7UUE3RGpELE1BQU0sRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxXQUFXLEVBQUUsR0FDcEUseUJBQXlCLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFckMsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsSUFBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7UUFDM0IsSUFBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7UUFDM0IsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7UUFDdkIsSUFBSSxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUM7UUFFL0IsSUFBSSxDQUFDLEtBQUs7WUFDUixHQUFHLEtBQUssQ0FBQyxDQUFDLElBQUksR0FBRyxLQUFLLENBQUM7Z0JBQ3JCLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSztnQkFDbEIsQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQztRQUV2RCxNQUFNLENBQUMsR0FBRyxJQUFJLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUM5QixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQzVCLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7U0FDVjtRQUVELElBQUksQ0FBUyxDQUFDO1FBQ2QsSUFBSSxDQUFTLENBQUM7UUFDZCxLQUFLLElBQUksQ0FBQyxHQUFHLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQzVCLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1lBQ3hDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDVCxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ1osQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztTQUNWO1FBRUQsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNoQyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3JDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDNUIsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDO1lBQzFCLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7U0FDdkM7SUFDSCxDQUFDO0lBNkJELEdBQUcsQ0FBQyxFQUFZLEVBQUUsTUFBZ0I7UUFDaEMsT0FBTyxFQUFFO2FBQ04sS0FBSyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2FBQzVDLE1BQU0sQ0FBQyxDQUFD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LEVBQUU7UUFDekMsTUFBTSxJQUFJLEtBQUssQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO0tBQzVDO0lBQ0QsT0FBTyxhQUFhLENBQUM7QUFDdkIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgU2ltcGxleE5vaXNlT3B0aW9ucyB9IGZyb20gJy4vc2ltcGxleC1ub2lzZS1vcHRpb25zJztcblxuZXhwb3J0IGNsYXNzIFNpbXBsZXhOb2lzZSB7XG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM/OiBQYXJ0aWFsPFNpbXBsZXhOb2lzZU9wdGlvbnM+KSB7XG4gICAgY29uc3QgeyBtaW4sIG1heCwgcmFuZG9tLCBhbXBsaXR1ZGUsIGZyZXF1ZW5jeSwgb2N0YXZlcywgcGVyc2lzdGVuY2UgfSA9XG4gICAgICBjcmVhdGVPcHRpb25zV2l0aERlZmF1bHRzKG9wdGlvbnMpO1xuXG4gICAgdGhpcy5yYW5kb20gPSByYW5kb207XG4gICAgdGhpcy5hbXBsaXR1ZGUgPSBhbXBsaXR1ZGU7XG4gICAgdGhpcy5mcmVxdWVuY3kgPSBmcmVxdWVuY3k7XG4gICAgdGhpcy5vY3RhdmVzID0gb2N0YXZlcztcbiAgICB0aGlzLnBlcnNpc3RlbmNlID0gcGVyc2lzdGVuY2U7XG5cbiAgICB0aGlzLnNjYWxlID1cbiAgICAgIG1pbiA9PT0gLTEgJiYgbWF4ID09PSAxXG4gICAgICAgID8gKHZhbHVlKSA9PiB2YWx1ZVxuICAgICAgICA6ICh2YWx1ZSkgPT4gbWluICsgKCh2YWx1ZSArIDEpIC8gMikgKiAobWF4IC0gbWluKTtcblxuICAgIGNvbnN0IHAgPSBuZXcgVWludDhBcnJheSgyNTYpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgMjU2OyBpKyspIHtcbiAgICAgIHBbaV0gPSBpO1xuICAgIH1cblxuICAgIGxldCBuOiBudW1iZXI7XG4gICAgbGV0IHE6IG51bWJlcjtcbiAgICBmb3IgKGxldCBpID0gMjU1OyBpID4gMDsgaS0tKSB7XG4gICAgICBuID0gTWF0aC5mbG9vcigoaSArIDEpICogdGhpcy5yYW5kb20oKSk7XG4gICAgICBxID0gcFtpXTtcbiAgICAgIHBbaV0gPSBwW25dO1xuICAgICAgcFtuXSA9IHE7XG4gICAgfVxuXG4gICAgdGhpcy5wZXJtID0gbmV3IFVpbnQ4QXJyYXkoNTEyKTtcbiAgICB0aGlzLnBlcm1Nb2QxMiA9IG5ldyBVaW50OEFycmF5KDUxMik7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCA1MTI7IGkrKykge1xuICAgICAgdGhpcy5wZXJtW2ldID0gcFtpICYgMjU1XTtcbiAgICAgIHRoaXMucGVybU1vZDEyW2ldID0gdGhpcy5wZXJtW2ldICUgMTI7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIEczID0gMS4wIC8gNi4wO1xuXG4gIHN0YXRpYyBHUkFEM0QgPSBbXG4gICAgWzEsIDEsIDBdLFxuICAgIFstMSwgMSwgMF0sXG4gICAgWzEsIC0xLCAwXSxcbiAgICBbLTEsIC0xLCAwXSxcbiAgICBbMSwgMCwgMV0sXG4gICAgWy0xLCAwLCAxXSxcbiAgICBbMSwgMCwgLTFdLFxuICAgIFstMSwgMCwgLTFdLFxuICAgIFswLCAxLCAxXSxcbiAgICBbMCwgLTEsIC0xXSxcbiAgICBbMCwgMSwgLTFdLFxuICAgIFswLCAtMSwgLTFdLFxuICBdO1xuXG4gIHJlYWRvbmx5IGFtcGxpdHVkZTogbnVtYmVyO1xuICByZWFkb25seSBmcmVxdWVuY3k6IG51bWJlcjtcbiAgcmVhZG9ubHkgb2N0YXZlczogbnVtYmVyO1xuICByZWFkb25seSBwZXJtOiBVaW50OEFycmF5O1xuICByZWFkb25seSBwZXJtTW9kMTI6IFVpbnQ4QXJyYXk7XG4gIHJlYWRvbmx5IHBlcnNpc3RlbmNlOiBudW1iZXI7XG4gIHJlYWRvbmx5IHJhbmRvbTogKCkgPT4gbnVtYmVyO1xuICByZWFkb25seSBzY2FsZTogKHZhbHVlOiBudW1iZXIpID0+IG51bWJlcjtcbiAgcHJpdmF0ZSBtZW1TY2FsZTNEOiB7IFtrZXk6IHN0cmluZ106IG51bWJlciB9ID0ge307XG5cbiAgZG90KGdzOiBudW1iZXJbXSwgY29vcmRzOiBudW1iZXJbXSk6IG51bWJlciB7XG4gICAgcmV0dXJuIGdzXG4gICAgICAuc2xpY2UoMCwgTWF0aC5taW4oZ3MubGVuZ3RoLCBjb29yZHMubGVuZ3RoKSlcbiAgICAgIC5yZWR1Y2UoKHRvdGFsLCBnLCBpKSA9PiB0b3RhbCArIGcgKiBjb29yZHNbaV0sIDApO1xuICB9XG5cbiAgcmF3M0QoeDogbnVtYmVyLCB5OiBudW1iZXIsIHo6IG51bWJlcik6IG51bWJlciB7XG4gICAgLy8gU2tldyB0aGUgaW5wdXQgc3BhY2UgdG8gZGV0ZXJtaW5lIHdoaWNoIHNpbXBsZXggY2VsbCB3ZSdyZSBpblxuICAgIGNvbnN0IHMgPSAoeCArIHkgKyB6KSAvIDMuMDsgLy8gVmVyeSBuaWNlIGFuZCBzaW1wbGUgc2tldyBmYWN0b3IgZm9yIDNEXG4gICAgY29uc3QgaSA9IE1hdGguZmxvb3IoeCArIHMpO1xuICAgIGNvbnN0IGogPSBNYXRoLmZsb29yKHkgKyBzKTtcbiAgICBjb25zdCBrID0gTWF0aC5mbG9vcih6ICsgcyk7XG4gICAgY29uc3QgdCA9IChpICsgaiArIGspICogU2ltcGxleE5vaXNlLkczO1xuICAgIGNvbnN0IFgwID0gaSAtIHQ7IC8vIFVuc2tldyB0aGUgY2VsbCBvcmlnaW4gYmFjayB0byAoeCx5LHopIHNwYWNlXG4gICAgY29uc3QgWTAgPSBqIC0gdDtcbiAgICBjb25zdCBaMCA9IGsgLSB0O1xuICAgIGNvbnN0IHgwID0geCAtIFgwOyAvLyBUaGUgeCx5LHogZGlzdGFuY2VzIGZyb20gdGhlIGNlbGwgb3JpZ2luXG4gICAgY29uc3QgeTAgPSB5IC0gWTA7XG4gICAgY29uc3QgejAgPSB6IC0gWjA7XG5cbiAgICAvLyBEZXRlcm1pbmUgd2hpY2ggc2ltcGxleCB3ZSBhcmUgaW5cbiAgICBsZXQgaTE6IG51bWJlciwgajE6IG51bWJlciwgazE6IG51bWJlcjsgLy8gT2Zmc2V0cyBmb3Igc2Vjb25kIGNvcm5lciBvZiBzaW1wbGV4IGluIChpLGosaykgY29vcmRzXG4gICAgbGV0IGkyOiBudW1iZXIsIGoyOiBudW1iZXIsIGsyOiBudW1iZXI7IC8vIE9mZnNldHMgZm9yIHRoaXJkIGNvcm5lciBvZiBzaW1wbGV4IGluIChpLGosaykgY29vcmRzXG4gICAgaWYgKHgwID49IHkwKSB7XG4gICAgICBpZiAoeTAgPj0gejApIHtcbiAgICAgICAgaTEgPSBpMiA9IGoyID0gMTtcbiAgICAgICAgajEgPSBrMSA9IGsyID0gMDtcbiAgICAgIH0gZWxzZSBpZiAoeDAgPj0gejApIHtcbiAgICAgICAgaTEgPSBpMiA9IGsyID0gMTtcbiAgICAgICAgajEgPSBrMSA9IGoyID0gMDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGsxID0gaTIgPSBrMiA9IDE7XG4gICAgICAgIGkxID0gajEgPSBqMiA9IDA7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh5MCA8IHowKSB7XG4gICAgICAgIGsxID0gajIgPSBrMiA9IDE7XG4gICAgICAgIGkxID0gajEgPSBpMiA9IDA7XG4gICAgICB9IGVsc2UgaWYgKHgwIDwgejApIHtcbiAgICAgICAgajEgPSBqMiA9IGsyID0gMTtcbiAgICAgICAgaTEgPSBrMSA9IGkyID0gMDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGoxID0gaTIgPSBqMiA9IDE7XG4gICAgICAgIGkxID0gazEgPSBrMiA9IDA7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgeDEgPSB4MCAtIGkxICsgU2ltcGxleE5vaXNlLkczOyAvLyBPZmZzZXRzIGZvciBzZWNvbmQgY29ybmVyIGluICh4LHkseikgY29vcmRzXG4gICAgY29uc3QgeTEgPSB5MCAtIGoxICsgU2ltcGxleE5vaXNlLkczO1xuICAgIGNvbnN0IHoxID0gejAgLSBrMSArIFNpbXBsZXhOb2lzZS5HMztcbiAgICBjb25zdCB4MiA9IHgwIC0gaTIgKyAyLjAgKiBTaW1wbGV4Tm9pc2UuRzM7IC8vIE9mZnNldHMgZm9yIHRoaXJkIGNvcm5lciBpbiAoeCx5LHopIGNvb3Jkc1xuICAgIGNvbnN0IHkyID0geTAgLSBqMiArIDIuMCAqIFNpbXBsZXhOb2lzZS5HMztcbiAgICBjb25zdCB6MiA9IHowIC0gazIgKyAyLjAgKiBTaW1wbGV4Tm9pc2UuRzM7XG4gICAgY29uc3QgeDMgPSB4MCAtIDEuMCArIDMuMCAqIFNpbXBsZXhOb2lzZS5HMzsgLy8gT2Zmc2V0cyBmb3IgbGFzdCBjb3JuZXIgaW4gKHgseSx6KSBjb29yZHNcbiAgICBjb25zdCB5MyA9IHkwIC0gMS4wICsgMy4wICogU2ltcGxleE5vaXNlLkczO1xuICAgIGNvbnN0IHozID0gejAgLSAxLjAgKyAzLjAgKiBTaW1wbGV4Tm9pc2UuRzM7XG5cbiAgICAvLyBXb3JrIG91dCB0aGUgaGFzaGVkIGdyYWRpZW50IGluZGljZXMgb2YgdGhlIGZvdXIgc2ltcGxleCBjb3JuZXJzXG4gICAgY29uc3QgaWkgPSBpICYgMjU1O1xuICAgIGNvbnN0IGpqID0gaiAmIDI1NTtcbiAgICBjb25zdCBrayA9IGsgJiAyNTU7XG4gICAgY29uc3QgZ2kwID0gdGhpcy5wZXJtTW9kMTJbaWkgKyB0aGlzLnBlcm1bamogKyB0aGlzLnBlcm1ba2tdXV07XG4gICAgY29uc3QgZ2kxID1cbiAgICAgIHRoaXMucGVybU1vZDEyW2lpICsgaTEgKyB0aGlzLnBlcm1bamogKyBqMSArIHRoaXMucGVybVtrayArIGsxXV1dO1xuICAgIGNvbnN0IGdpMiA9XG4gICAgICB0aGlzLnBlcm1Nb2QxMltpaSArIGkyICsgdGhpcy5wZXJtW2pqICsgajIgKyB0aGlzLnBlcm1ba2sgKyBrMl1dXTtcbiAgICBjb25zdCBnaTMgPSB0aGlzLnBlcm1Nb2QxMltpaSArIDEgKyB0aGlzLnBlcm1bamogKyAxICsgdGhpcy5wZXJtW2trICsgMV1dXTtcblxuICAgIC8vIENhbGN1bGF0ZSB0aGUgY29udHJpYnV0aW9uIGZyb20gdGhlIGZvdXIgY29ybmVyc1xuICAgIGNvbnN0IHQwID0gMC41IC0geDAgKiB4MCAtIHkwICogeTAgLSB6MCAqIHowO1xuICAgIGNvbnN0IG4wID1cbiAgICAgIHQwIDwgMFxuICAgICAgICA/IDAuMFxuICAgICAgICA6IE1hdGgucG93KHQwLCA0KSAqIHRoaXMuZG90KFNpbXBsZXhOb2lzZS5HUkFEM0RbZ2kwXSwgW3gwLCB5MCwgejBdKTtcbiAgICBjb25zdCB0MSA9IDAuNSAtIHgxICogeDEgLSB5MSAqIHkxIC0gejEgKiB6MTtcbiAgICBjb25zdCBuMSA9XG4gICAgICB0MSA8IDBcbiAgICAgICAgPyAwLjBcbiAgICAgICAgOiBNYXRoLnBvdyh0MSwgNCkgKiB0aGlzLmRvdChTaW1wbGV4Tm9pc2UuR1JBRDNEW2dpMV0sIFt4MSwgeTEsIHoxXSk7XG4gICAgY29uc3QgdDIgPSAwLjUgLSB4MiAqIHgyIC0geTIgKiB5MiAtIHoyICogejI7XG4gICAgY29uc3QgbjIgPVxuICAgICAgdDIgPCAwXG4gICAgICAgID8gMC4wXG4gICAgICAgIDogTWF0aC5wb3codDIsIDQpICogdGhpcy5kb3QoU2ltcGxleE5vaXNlLkdSQUQzRFtnaTJdLCBbeDIsIHkyLCB6Ml0pO1xuICAgIGNvbnN0IHQzID0gMC41IC0geDMgKiB4MyAtIHkzICogeTMgLSB6MyAqIHozO1xuICAgIGNvbnN0IG4zID1cbiAgICAgIHQzIDwgMFxuICAgICAgICA/IDAuMFxuICAgICAgICA6IE1hdGgucG93KHQzLCA0KSAqIHRoaXMuZG90KFNpbXBsZXhOb2lzZS5HUkFEM0RbZ2kzXSwgW3gzLCB5MywgejNdKTtcblxuICAgIC8vIEFkZCBjb250cmlidXRpb25zIGZyb20gZWFjaCBjb3JuZXIgdG8gZ2V0IHRoZSBmaW5hbCBub2lzZSB2YWx1ZS5cbiAgICAvLyBUaGUgcmVzdWx0IGlzIHNjYWxlZCB0byBzdGF5IGp1c3QgaW5zaWRlIFstMSwxXVxuICAgIHJldHVybiA5NC42ODQ5MzE1MDY4MTk3MiAqIChuMCArIG4xICsgbjIgKyBuMyk7XG4gIH1cblxuICBzY2FsZWQzRCh4OiBudW1iZXIsIHk6IG51bWJlciwgejogbnVtYmVyLCByZXNvbHV0aW9uOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGNvbnN0IG1lbUluZGV4ID0gYCR7TWF0aC5yb3VuZCh4ICogcmVzb2x1dGlvbil9JHtNYXRoLnJvdW5kKFxuICAgICAgeSAqIHJlc29sdXRpb25cbiAgICApfSR7TWF0aC5yb3VuZCh6ICogcmVzb2x1dGlvbil9YDtcbiAgICBjb25zdCBtZW1FbGVtID0gdGhpcy5tZW1TY2FsZTNEW21lbUluZGV4XTtcbiAgICBpZiAobWVtRWxlbSAhPSBudWxsKSB7XG4gICAgICByZXR1cm4gbWVtRWxlbTtcbiAgICB9XG5cbiAgICBsZXQgYW1wbGl0dWRlID0gdGhpcy5hbXBsaXR1ZGU7XG4gICAgbGV0IGZyZXF1ZW5jeSA9IHRoaXMuZnJlcXVlbmN5O1xuICAgIGxldCBtYXhBbXBsaXR1ZGUgPSAwO1xuICAgIGxldCBub2lzZSA9IDA7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMub2N0YXZlczsgaSsrKSB7XG4gICAgICBub2lzZSArPVxuICAgICAgICB0aGlzLnJhdzNEKHggKiBmcmVxdWVuY3ksIHkgKiBmcmVxdWVuY3ksIHogKiBmcmVxdWVuY3kpICogYW1wbGl0dWRlO1xuICAgICAgbWF4QW1wbGl0dWRlICs9IGFtcGxpdHVkZTtcbiAgICAgIGFtcGxpdHVkZSAqPSB0aGlzLnBlcnNpc3RlbmNlO1xuICAgICAgZnJlcXVlbmN5ICo9IDI7XG4gICAgfVxuICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuc2NhbGUobm9pc2UgLyBtYXhBbXBsaXR1ZGUpO1xuICAgIHRoaXMubWVtU2NhbGUzRFttZW1JbmRleF0gPSByZXN1bHQ7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxufVxuXG5mdW5jdGlvbiBjcmVhdGVPcHRpb25zV2l0aERlZmF1bHRzKG9wdGlvbnM/OiBQYXJ0aWFsPFNpbXBsZXhOb2lzZU9wdGlvbnM+KSB7XG4gIGlmIChvcHRpb25zICE9IG51bGwpIHtcbiAgICBpZiAob3B0aW9uc1snYW1wbGl0dWRlJ10gJiYgdHlwZW9mIG9wdGlvbnMuYW1wbGl0dWRlICE9PSAnbnVtYmVyJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdvcHRpb25zLmFtcGxpdHVkZSBtdXN0IGJlIGEgbnVtYmVyJyk7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnNbJ2ZyZXF1ZW5jeSddICYmIHR5cGVvZiBvcHRpb25zLmZyZXF1ZW5jeSAhPT0gJ251bWJlcicpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignb3B0aW9ucy5mcmVxdWVuY3kgbXVzdCBiZSBhIG51bWJlcicpO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIG9wdGlvbnNbJ29jdGF2ZXMnXSAmJlxuICAgICAgKHR5cGVvZiBvcHRpb25zLm9jdGF2ZXMgIT09ICdudW1iZXInIHx8XG4gICAgICAgICFpc0Zpbml0ZShvcHRpb25zLm9jdGF2ZXMpIHx8XG4gICAgICAgIE1hdGguZmxvb3Iob3B0aW9ucy5vY3RhdmVzKSAhPT0gb3B0aW9ucy5vY3RhdmVzKVxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdvcHRpb25zLm9jdGF2ZXMgbXVzdCBiZSBhbiBpbnRlZ2VyJyk7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnNbJ3BlcnNpc3RlbmNlJ10gJiYgdHlwZW9mIG9wdGlvbnMucGVyc2lzdGVuY2UgIT09ICdudW1iZXInKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ29wdGlvbnMucGVyc2lzdGVuY2UgbXVzdCBiZSBhIG51bWJlcicpO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zWydyYW5kb20nXSAmJiB0eXBlb2Ygb3B0aW9ucy5yYW5kb20gIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignb3B0aW9ucy5yYW5kb20gbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnNbJ21pbiddICYmIHR5cGVvZiBvcHRpb25zLm1pbiAhPT0gJ251bWJlcicpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignb3B0aW9ucy5taW4gbXVzdCBiZSBhIG51bWJlcicpO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zWydtYXgnXSAmJiB0eXBlb2Ygb3B0aW9ucy5tYXggIT09ICdudW1iZXInKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ29wdGlvbnMubWF4IG11c3QgYmUgYSBudW1iZXInKTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBvcHRpb25zUmVzdWx0ID0ge1xuICAgIGFtcGxpdHVkZTogMS4wLFxuICAgIGZyZXF1ZW5jeTogMS4wLFxuICAgIG1heDogMS4wLFxuICAgIG1pbjogLTEuMCxcbiAgICBvY3RhdmVzOiAxLFxuICAgIHBlcnNpc3RlbmNlOiAwLjUsXG4gICAgcmFuZG9tOiBNYXRoLnJhbmRvbSxcbiAgICAuLi5vcHRpb25zLFxuICB9O1xuICBpZiAob3B0aW9uc1Jlc3VsdC5taW4gPiBvcHRpb25zUmVzdWx0Lm1heCkge1xuICAgIHRocm93IG5ldyBFcnJvcignbWluIG11c3QgYmUgc21hbGxlciBtYXgnKTtcbiAgfVxuICByZXR1cm4gb3B0aW9uc1Jlc3VsdDtcbn1cbiJdfQ==
@@ -1,56 +0,0 @@
1
- import { Directive, ElementRef, EventEmitter, Inject, NgZone, Output, } from '@angular/core';
2
- import { WS_THANOS_OPTIONS_TOKEN } from './ws-thanos-options.token';
3
- import { WsThanosService } from './ws-thanos.service';
4
- import * as i0 from "@angular/core";
5
- import * as i1 from "./ws-thanos.service";
6
- export class WsThanosDirective {
7
- constructor(vaporizeDomElem, thanosService, thanosOptions, ngZone) {
8
- this.vaporizeDomElem = vaporizeDomElem;
9
- this.thanosService = thanosService;
10
- this.thanosOptions = thanosOptions;
11
- this.ngZone = ngZone;
12
- this.wsThanosComplete = new EventEmitter();
13
- }
14
- vaporize(removeElem = true) {
15
- const elem = this.vaporizeDomElem.nativeElement;
16
- this.subscription = this.thanosService.vaporize(elem).subscribe({
17
- complete: () => {
18
- this.ngZone.run(() => {
19
- if (removeElem) {
20
- elem.remove();
21
- }
22
- else {
23
- // make visible again
24
- elem.style.transition = 'opacity 700ms';
25
- elem.style.opacity = '1';
26
- }
27
- this.wsThanosComplete.emit();
28
- });
29
- },
30
- error: (error) => {
31
- console.error('error emitted by vaporize', error);
32
- this.wsThanosComplete.emit();
33
- },
34
- });
35
- return this.wsThanosComplete.asObservable();
36
- }
37
- ngOnDestroy() {
38
- this.subscription?.unsubscribe();
39
- }
40
- }
41
- WsThanosDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: WsThanosDirective, deps: [{ token: i0.ElementRef }, { token: i1.WsThanosService }, { token: WS_THANOS_OPTIONS_TOKEN }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive });
42
- WsThanosDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.9", type: WsThanosDirective, isStandalone: true, selector: "[wsThanos], ws-thanos", outputs: { wsThanosComplete: "wsThanosComplete" }, exportAs: ["thanos"], ngImport: i0 });
43
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: WsThanosDirective, decorators: [{
44
- type: Directive,
45
- args: [{
46
- standalone: true,
47
- selector: '[wsThanos], ws-thanos',
48
- exportAs: 'thanos',
49
- }]
50
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1.WsThanosService }, { type: undefined, decorators: [{
51
- type: Inject,
52
- args: [WS_THANOS_OPTIONS_TOKEN]
53
- }] }, { type: i0.NgZone }]; }, propDecorators: { wsThanosComplete: [{
54
- type: Output
55
- }] } });
56
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid3MtdGhhbm9zLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvcHVibGljL3dzLXRoYW5vcy9zcmMvbGliL3dzLXRoYW5vcy5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLE1BQU0sRUFDTixNQUFNLEVBRU4sTUFBTSxHQUNQLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRXBFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQzs7O0FBT3RELE1BQU0sT0FBTyxpQkFBaUI7SUFNNUIsWUFDbUIsZUFBd0MsRUFDeEMsYUFBOEIsRUFFOUIsYUFBOEIsRUFDOUIsTUFBYztRQUpkLG9CQUFlLEdBQWYsZUFBZSxDQUF5QjtRQUN4QyxrQkFBYSxHQUFiLGFBQWEsQ0FBaUI7UUFFOUIsa0JBQWEsR0FBYixhQUFhLENBQWlCO1FBQzlCLFdBQU0sR0FBTixNQUFNLENBQVE7UUFQekIscUJBQWdCLEdBQXVCLElBQUksWUFBWSxFQUFRLENBQUM7SUFRckUsQ0FBQztJQUVHLFFBQVEsQ0FBQyxVQUFVLEdBQUcsSUFBSTtRQUMvQixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLGFBQWEsQ0FBQztRQUNoRCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsQ0FBQztZQUM5RCxRQUFRLEVBQUUsR0FBRyxFQUFFO2dCQUNiLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRTtvQkFDbkIsSUFBSSxVQUFVLEVBQUU7d0JBQ2QsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO3FCQUNmO3lCQUFNO3dCQUNMLHFCQUFxQjt3QkFDckIsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLEdBQUcsZUFBZSxDQUFDO3dCQUN4QyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxHQUFHLENBQUM7cUJBQzFCO29CQUNELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDL0IsQ0FBQyxDQUFDLENBQUM7WUFDTCxDQUFDO1lBQ0QsS0FBSyxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUU7Z0JBQ2YsT0FBTyxDQUFDLEtBQUssQ0FBQywyQkFBMkIsRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDbEQsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksRUFBRSxDQUFDO1lBQy9CLENBQUM7U0FDRixDQUFDLENBQUM7UUFFSCxPQUFPLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUM5QyxDQUFDO0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxZQUFZLEVBQUUsV0FBVyxFQUFFLENBQUM7SUFDbkMsQ0FBQzs7OEdBeENVLGlCQUFpQiwyRUFTbEIsdUJBQXVCO2tHQVR0QixpQkFBaUI7MkZBQWpCLGlCQUFpQjtrQkFMN0IsU0FBUzttQkFBQztvQkFDVCxVQUFVLEVBQUUsSUFBSTtvQkFDaEIsUUFBUSxFQUFFLHVCQUF1QjtvQkFDakMsUUFBUSxFQUFFLFFBQVE7aUJBQ25COzswQkFVSSxNQUFNOzJCQUFDLHVCQUF1QjtpRUFMekIsZ0JBQWdCO3NCQUR2QixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgRGlyZWN0aXZlLFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEluamVjdCxcbiAgTmdab25lLFxuICBPbkRlc3Ryb3ksXG4gIE91dHB1dCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IFdTX1RIQU5PU19PUFRJT05TX1RPS0VOIH0gZnJvbSAnLi93cy10aGFub3Mtb3B0aW9ucy50b2tlbic7XG5pbXBvcnQgdHlwZSB7IFdzVGhhbm9zT3B0aW9ucyB9IGZyb20gJy4vd3MtdGhhbm9zLm9wdGlvbnMnO1xuaW1wb3J0IHsgV3NUaGFub3NTZXJ2aWNlIH0gZnJvbSAnLi93cy10aGFub3Muc2VydmljZSc7XG5cbkBEaXJlY3RpdmUoe1xuICBzdGFuZGFsb25lOiB0cnVlLFxuICBzZWxlY3RvcjogJ1t3c1RoYW5vc10sIHdzLXRoYW5vcycsXG4gIGV4cG9ydEFzOiAndGhhbm9zJyxcbn0pXG5leHBvcnQgY2xhc3MgV3NUaGFub3NEaXJlY3RpdmUgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICBwcml2YXRlIHN1YnNjcmlwdGlvbj86IFN1YnNjcmlwdGlvbjtcblxuICBAT3V0cHV0KClcbiAgcHJpdmF0ZSB3c1RoYW5vc0NvbXBsZXRlOiBFdmVudEVtaXR0ZXI8dm9pZD4gPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSB2YXBvcml6ZURvbUVsZW06IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgdGhhbm9zU2VydmljZTogV3NUaGFub3NTZXJ2aWNlLFxuICAgIEBJbmplY3QoV1NfVEhBTk9TX09QVElPTlNfVE9LRU4pXG4gICAgcHJpdmF0ZSByZWFkb25seSB0aGFub3NPcHRpb25zOiBXc1RoYW5vc09wdGlvbnMsXG4gICAgcHJpdmF0ZSByZWFkb25seSBuZ1pvbmU6IE5nWm9uZVxuICApIHt9XG5cbiAgcHVibGljIHZhcG9yaXplKHJlbW92ZUVsZW0gPSB0cnVlKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgY29uc3QgZWxlbSA9IHRoaXMudmFwb3JpemVEb21FbGVtLm5hdGl2ZUVsZW1lbnQ7XG4gICAgdGhpcy5zdWJzY3JpcHRpb24gPSB0aGlzLnRoYW5vc1NlcnZpY2UudmFwb3JpemUoZWxlbSkuc3Vic2NyaWJlKHtcbiAgICAgIGNvbXBsZXRlOiAoKSA9PiB7XG4gICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgaWYgKHJlbW92ZUVsZW0pIHtcbiAgICAgICAgICAgIGVsZW0ucmVtb3ZlKCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIG1ha2UgdmlzaWJsZSBhZ2FpblxuICAgICAgICAgICAgZWxlbS5zdHlsZS50cmFuc2l0aW9uID0gJ29wYWNpdHkgNzAwbXMnO1xuICAgICAgICAgICAgZWxlbS5zdHlsZS5vcGFjaXR5ID0gJzEnO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLndzVGhhbm9zQ29tcGxldGUuZW1pdCgpO1xuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICBlcnJvcjogKGVycm9yKSA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ2Vycm9yIGVtaXR0ZWQgYnkgdmFwb3JpemUnLCBlcnJvcik7XG4gICAgICAgIHRoaXMud3NUaGFub3NDb21wbGV0ZS5lbWl0KCk7XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXMud3NUaGFub3NDb21wbGV0ZS5hc09ic2VydmFibGUoKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICB9XG59XG4iXX0=
@@ -1,260 +0,0 @@
1
- import { Inject, Injectable, NgZone } from '@angular/core';
2
- import { default as html2canvas } from 'html2canvas';
3
- import { animationFrameScheduler, from, interval, map, switchMap, takeWhile, tap, timeInterval, } from 'rxjs';
4
- import { SimplexNoise } from './simplex-noise';
5
- import { WS_THANOS_OPTIONS_TOKEN } from './ws-thanos-options.token';
6
- import * as i0 from "@angular/core";
7
- const PARTICLE_BYTE_LENGTH = 10;
8
- const MIN_PARTICLE_ALPHA = ~~(255 * 0.01);
9
- const HEIGHT_SCALE = 5;
10
- const WIDTH_SCALE = 2;
11
- const FLOW_FIELD_RES = 0.05;
12
- export class WsThanosService {
13
- constructor(thanosOptions, ngZone) {
14
- this.thanosOptions = thanosOptions;
15
- this.ngZone = ngZone;
16
- }
17
- static getParticleIndicesForBase(base) {
18
- return {
19
- x: base,
20
- y: base + 1,
21
- dx: base + 2,
22
- dy: base + 3,
23
- ax: base + 4,
24
- ay: base + 5,
25
- r: base + 6,
26
- g: base + 7,
27
- b: base + 8,
28
- a: base + 9,
29
- };
30
- }
31
- static getColorIndicesForCoord(x, y, width) {
32
- const red = y * (width * 4) + x * 4;
33
- return { r: red, g: red + 1, b: red + 2, a: red + 3 };
34
- }
35
- static updateParticles({ seed, noise, particlesData, thanosOptions, animationState, }) {
36
- const { deltaTSec, animationT, maxWidth, maxHeight } = animationState;
37
- const { particleAcceleration } = thanosOptions;
38
- const { particles, maxParticleX, minParticleY } = particlesData;
39
- // the time is used to calculate the vaporization front.
40
- const time = Math.sin(animationT * (Math.PI / 2)) * 1.1;
41
- const startAccelerateX = maxParticleX - time * maxParticleX;
42
- const startAccelerateY = time * (maxHeight - minParticleY) + minParticleY;
43
- const lengthY = maxHeight - startAccelerateY;
44
- const accelerateRadiusPow = startAccelerateX * startAccelerateX + lengthY * lengthY;
45
- for (let i = 0; i < particles.length; i += PARTICLE_BYTE_LENGTH) {
46
- const { x, y, dx, dy, ax, ay, a } = WsThanosService.getParticleIndicesForBase(i);
47
- const particleX = particles[x];
48
- const particleY = particles[y];
49
- // only update particles that are inside view and visible
50
- if (particleX > maxWidth ||
51
- particleX < 0 ||
52
- particleY > maxHeight ||
53
- particleY < 0 ||
54
- particles[a] < MIN_PARTICLE_ALPHA) {
55
- continue;
56
- }
57
- if (!(Math.abs(particles[ax]) > 0 || Math.abs(particles[ay]) > 0)) {
58
- let pYLength = maxHeight - particleY;
59
- let pXLength = particleX;
60
- // we calculate some random looking numbers and functions to have nice looking vaporizing front of particles
61
- // todo consider to use noise;
62
- pXLength += Math.tan((pXLength / 20.12) * time + seed) * 0.5;
63
- pXLength += (particleX % deltaTSec) * 0.5;
64
- pXLength +=
65
- Math.sin((pXLength / 30 + 723.394) * time + seed * 12.5) * 11;
66
- pYLength += Math.tan((pYLength / 0.45) * time + seed * 1.5) * 0.5;
67
- pYLength +=
68
- Math.cos((pYLength / 100 + 2323.234) * time + seed * 456.1) * 23;
69
- const pLength = pXLength * pXLength + pYLength * pYLength;
70
- if (pLength > accelerateRadiusPow) {
71
- particles[ax] = Math.random();
72
- particles[ay] = Math.random() * -1;
73
- }
74
- }
75
- else {
76
- // use noise to flow along velocity field
77
- const flowFieldAcc = WsThanosService.getXYFromFlowField(noise, seed, particleX, particleY);
78
- const accelerationX = flowFieldAcc[0];
79
- const accelerationY = flowFieldAcc[1];
80
- particles[ax] += accelerationX;
81
- particles[ay] += accelerationY;
82
- }
83
- // * Math.pow(1 + animationT, 4)
84
- particles[dx] += particles[ax] * particleAcceleration * deltaTSec;
85
- particles[dy] += particles[ay] * particleAcceleration * deltaTSec;
86
- particles[x] += particles[dx] * deltaTSec;
87
- particles[y] += particles[dy] * deltaTSec;
88
- // fade particle out ( very late);
89
- particles[a] *= 1 - Math.pow(animationT, 15); // 255 - Math.sqrt(particles[dx] * particles[dx] + particles[dy] * particles[dy]) / 1.2;
90
- }
91
- }
92
- static drawParticles(drawCtx, particles) {
93
- const { width, height } = drawCtx.canvas;
94
- drawCtx.clearRect(0, 0, width, height);
95
- const image = drawCtx.getImageData(0, 0, width, height);
96
- const imageData = image.data;
97
- for (let i = 0; i < particles.length; i += PARTICLE_BYTE_LENGTH) {
98
- const particleX = particles[i];
99
- const particleY = particles[i + 1];
100
- const pI = WsThanosService.getParticleIndicesForBase(i);
101
- if (particleX > width ||
102
- particleX < 0 ||
103
- particleY > height ||
104
- particleY < 0 ||
105
- particles[pI.a] < MIN_PARTICLE_ALPHA) {
106
- continue;
107
- }
108
- const { r, g, b, a } = WsThanosService.getColorIndicesForCoord(~~particles[pI.x], ~~particles[pI.y], width);
109
- imageData[r] = ~~particles[pI.r];
110
- imageData[g] = ~~particles[pI.g];
111
- imageData[b] = ~~particles[pI.b];
112
- imageData[a] = ~~particles[pI.a];
113
- }
114
- drawCtx.putImageData(image, 0, 0);
115
- }
116
- static prepareCanvasForVaporize(divCanvas, maxParticleCount) {
117
- const { width, height } = divCanvas;
118
- // scale result canvas to have more room to draw particles while vaporizing;
119
- const resultHeight = height * HEIGHT_SCALE;
120
- const resultWidth = width * WIDTH_SCALE;
121
- const resultCanvas = document.createElement('canvas');
122
- resultCanvas.height = resultHeight;
123
- resultCanvas.width = resultWidth;
124
- const imageData = divCanvas
125
- .getContext('2d')
126
- ?.getImageData(0, 0, width, height);
127
- if (imageData == null) {
128
- throw new Error('Could not get image data from canvas');
129
- }
130
- const particlesData = WsThanosService.createParticlesForImageData(imageData, maxParticleCount, resultHeight);
131
- return { resultCanvas, particlesData };
132
- }
133
- static createParticlesForImageData(imageData, maxParticleCount, resultHeight) {
134
- const { width, height } = imageData;
135
- let particleCandidates = 0;
136
- let particleCount = 0;
137
- const particleCandiatesList = [];
138
- for (let y = 0; y < height; y++) {
139
- for (let x = 0; x < width; x++) {
140
- const { a } = WsThanosService.getColorIndicesForCoord(x, y, width);
141
- if (imageData.data[a] >= MIN_PARTICLE_ALPHA) {
142
- particleCandidates++;
143
- particleCandiatesList.push({ x, y });
144
- }
145
- }
146
- }
147
- const maxNumParticles = Math.min(particleCandidates, maxParticleCount);
148
- const particles = new Float32Array(Float32Array.BYTES_PER_ELEMENT * maxNumParticles * PARTICLE_BYTE_LENGTH);
149
- let maxParticleX = 0;
150
- let minParticleY = resultHeight;
151
- while (particleCount < maxNumParticles) {
152
- // select random index from candiates
153
- const index = ~~(Math.random() * particleCandiatesList.length);
154
- const { x, y } = particleCandiatesList[index];
155
- // overwrite index with last element to prevent double selection of particles
156
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
157
- particleCandiatesList[index] = particleCandiatesList.pop();
158
- maxParticleX = Math.max(maxParticleX, x);
159
- minParticleY = Math.min(minParticleY, y);
160
- const { dx, dy, ax, ay, r, g, b, a, ...xy } = WsThanosService.getParticleIndicesForBase(particleCount * PARTICLE_BYTE_LENGTH);
161
- particles[xy.x] = x;
162
- particles[xy.y] = y + resultHeight - height;
163
- particles[dx] = 0;
164
- particles[dy] = 0;
165
- particles[ax] = 0;
166
- particles[ay] = 0;
167
- const indicesImage = WsThanosService.getColorIndicesForCoord(x, y, width);
168
- particles[r] = imageData.data[indicesImage.r];
169
- particles[g] = imageData.data[indicesImage.g];
170
- particles[b] = imageData.data[indicesImage.b];
171
- particles[a] = imageData.data[indicesImage.a];
172
- particleCount++;
173
- }
174
- return { particles, maxParticleX, minParticleY };
175
- }
176
- static getXYFromFlowField(noise, seed, x, y) {
177
- const sampleX = noise.scaled3D(x, y, seed + 33.23, FLOW_FIELD_RES);
178
- const sampleY = noise.scaled3D(x, seed / 13.23, y, FLOW_FIELD_RES) * -1;
179
- return [sampleX, sampleY];
180
- }
181
- /**
182
- * start the vaporize-effect.
183
- *
184
- * It's running outside the ngZone.
185
- */
186
- vaporize(elem) {
187
- return this.ngZone.runOutsideAngular(() => this.vaporizeIntern(elem));
188
- }
189
- vaporizeIntern(elem) {
190
- elem.style.opacity = elem.style.opacity || '1';
191
- elem.style.transition = `opacity ${Math.floor(this.thanosOptions.animationLength * 0.8)}ms ease-out`;
192
- const noise = new SimplexNoise({ frequency: 0.01, min: 0 });
193
- const seed = new Date().getDate() * Math.random();
194
- const html2CanvasPromise = html2canvas(elem, {
195
- backgroundColor: null,
196
- scale: 1,
197
- allowTaint: true,
198
- windowHeight: window.innerHeight,
199
- windowWidth: window.innerWidth,
200
- scrollY: -window.scrollY,
201
- });
202
- return from(html2CanvasPromise).pipe(map((canvasFromHtmlElem) => {
203
- const canvasAndParticles = WsThanosService.prepareCanvasForVaporize(canvasFromHtmlElem, this.thanosOptions.maxParticleCount);
204
- const { resultCanvas } = canvasAndParticles;
205
- if (elem.parentElement) {
206
- elem.parentElement.style.position =
207
- elem.parentElement.style.position || 'relative';
208
- }
209
- resultCanvas.style.position = 'absolute';
210
- resultCanvas.style.left = 0 + 'px';
211
- resultCanvas.style.top =
212
- '-' + elem.getBoundingClientRect().height * (HEIGHT_SCALE - 1) + 'px';
213
- resultCanvas.style.zIndex = '2000';
214
- resultCanvas.style.pointerEvents = 'none';
215
- elem.insertAdjacentElement('beforebegin', resultCanvas);
216
- // this should start the transition above defined
217
- elem.style.opacity = '0';
218
- return canvasAndParticles;
219
- }), switchMap(({ resultCanvas, particlesData }) => {
220
- let time = 0;
221
- const { animationLength, maxParticleCount, particleAcceleration } = this.thanosOptions;
222
- return interval(1000 / 60, animationFrameScheduler).pipe(timeInterval(), tap((deltaT) => (time += deltaT.interval)), map((deltaT) => ({
223
- deltaTSec: deltaT.interval / 1000,
224
- animationT: time / animationLength,
225
- maxWidth: resultCanvas.width,
226
- maxHeight: resultCanvas.height,
227
- })), tap((animationState) => {
228
- WsThanosService.updateParticles({
229
- particlesData,
230
- animationState,
231
- thanosOptions: {
232
- animationLength,
233
- maxParticleCount,
234
- particleAcceleration,
235
- },
236
- noise,
237
- seed,
238
- });
239
- const context = resultCanvas.getContext('2d');
240
- if (context) {
241
- WsThanosService.drawParticles(context, particlesData.particles);
242
- }
243
- }), takeWhile((animationState) => animationState.animationT <= 1), tap({
244
- complete: () => {
245
- return resultCanvas.remove();
246
- },
247
- }));
248
- }));
249
- }
250
- }
251
- WsThanosService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: WsThanosService, deps: [{ token: WS_THANOS_OPTIONS_TOKEN }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
252
- WsThanosService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: WsThanosService, providedIn: 'root' });
253
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.9", ngImport: i0, type: WsThanosService, decorators: [{
254
- type: Injectable,
255
- args: [{ providedIn: 'root' }]
256
- }], ctorParameters: function () { return [{ type: undefined, decorators: [{
257
- type: Inject,
258
- args: [WS_THANOS_OPTIONS_TOKEN]
259
- }] }, { type: i0.NgZone }]; } });
260
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid3MtdGhhbm9zLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9saWJzL3B1YmxpYy93cy10aGFub3Mvc3JjL2xpYi93cy10aGFub3Muc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFM0QsT0FBTyxFQUFFLE9BQU8sSUFBSSxXQUFXLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDckQsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixJQUFJLEVBQ0osUUFBUSxFQUNSLEdBQUcsRUFFSCxTQUFTLEVBQ1QsU0FBUyxFQUNULEdBQUcsRUFDSCxZQUFZLEdBQ2IsTUFBTSxNQUFNLENBQUM7QUFDZCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sMkJBQTJCLENBQUM7O0FBR3BFLE1BQU0sb0JBQW9CLEdBQUcsRUFBRSxDQUFDO0FBQ2hDLE1BQU0sa0JBQWtCLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxDQUFDO0FBQzFDLE1BQU0sWUFBWSxHQUFHLENBQUMsQ0FBQztBQUN2QixNQUFNLFdBQVcsR0FBRyxDQUFDLENBQUM7QUFDdEIsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDO0FBcUM1QixNQUFNLE9BQU8sZUFBZTtJQUMxQixZQUVVLGFBQThCLEVBQzlCLE1BQWM7UUFEZCxrQkFBYSxHQUFiLGFBQWEsQ0FBaUI7UUFDOUIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtJQUNyQixDQUFDO0lBRUksTUFBTSxDQUFDLHlCQUF5QixDQUFDLElBQVk7UUFDbkQsT0FBTztZQUNMLENBQUMsRUFBRSxJQUFJO1lBQ1AsQ0FBQyxFQUFFLElBQUksR0FBRyxDQUFDO1lBQ1gsRUFBRSxFQUFFLElBQUksR0FBRyxD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YUFBYSxFQUFFO3dCQUNiLGVBQWU7d0JBQ2YsZ0JBQWdCO3dCQUNoQixvQkFBb0I7cUJBQ3JCO29CQUNELEtBQUs7b0JBQ0wsSUFBSTtpQkFDTCxDQUFDLENBQUM7Z0JBQ0gsTUFBTSxPQUFPLEdBQUcsWUFBWSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDOUMsSUFBSSxPQUFPLEVBQUU7b0JBQ1gsZUFBZSxDQUFDLGFBQWEsQ0FBQyxPQUFPLEVBQUUsYUFBYSxDQUFDLFNBQVMsQ0FBQyxDQUFDO2lCQUNqRTtZQUNILENBQUMsQ0FBQyxFQUNGLFNBQVMsQ0FBQyxDQUFDLGNBQWMsRUFBRSxFQUFFLENBQUMsY0FBYyxDQUFDLFVBQVUsSUFBSSxDQUFDLENBQUMsRUFDN0QsR0FBRyxDQUFDO2dCQUNGLFFBQVEsRUFBRSxHQUFHLEVBQUU7b0JBQ2IsT0FBTyxZQUFZLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQy9CLENBQUM7YUFDRixDQUFDLENBQ0gsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUNILENBQUM7SUFDSixDQUFDOzs0R0FqVlUsZUFBZSxrQkFFaEIsdUJBQXVCO2dIQUZ0QixlQUFlLGNBREYsTUFBTTsyRkFDbkIsZUFBZTtrQkFEM0IsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUU7OzBCQUc3QixNQUFNOzJCQUFDLHVCQUF1QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdCwgSW5qZWN0YWJsZSwgTmdab25lIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IGRlZmF1bHQgYXMgaHRtbDJjYW52YXMgfSBmcm9tICdodG1sMmNhbnZhcyc7XG5pbXBvcnQge1xuICBhbmltYXRpb25GcmFtZVNjaGVkdWxlcixcbiAgZnJvbSxcbiAgaW50ZXJ2YWwsXG4gIG1hcCxcbiAgT2JzZXJ2YWJsZSxcbiAgc3dpdGNoTWFwLFxuICB0YWtlV2hpbGUsXG4gIHRhcCxcbiAgdGltZUludGVydmFsLFxufSBmcm9tICdyeGpzJztcbmltcG9ydCB7IFNpbXBsZXhOb2lzZSB9IGZyb20gJy4vc2ltcGxleC1ub2lzZSc7XG5pbXBvcnQgeyBXU19USEFOT1NfT1BUSU9OU19UT0tFTiB9IGZyb20gJy4vd3MtdGhhbm9zLW9wdGlvbnMudG9rZW4nO1xuaW1wb3J0IHR5cGUgeyBXc1RoYW5vc09wdGlvbnMgfSBmcm9tICcuL3dzLXRoYW5vcy5vcHRpb25zJztcblxuY29uc3QgUEFSVElDTEVfQllURV9MRU5HVEggPSAxMDtcbmNvbnN0IE1JTl9QQVJUSUNMRV9BTFBIQSA9IH5+KDI1NSAqIDAuMDEpO1xuY29uc3QgSEVJR0hUX1NDQUxFID0gNTtcbmNvbnN0IFdJRFRIX1NDQUxFID0gMjtcbmNvbnN0IEZMT1dfRklFTERfUkVTID0gMC4wNTtcblxuaW50ZXJmYWNlIFBhcnRpY2xlc0RhdGEge1xuICBwYXJ0aWNsZXM6IEZsb2F0MzJBcnJheTtcbiAgbWF4UGFydGljbGVYOiBudW1iZXI7XG4gIG1pblBhcnRpY2xlWTogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgQW5pbWF0aW9uU3RhdGUge1xuICBkZWx0YVRTZWM6IG51bWJlcjtcbiAgYW5pbWF0aW9uVDogbnVtYmVyO1xuICBtYXhXaWR0aDogbnVtYmVyO1xuICBtYXhIZWlnaHQ6IG51bWJlcjtcbn1cblxuaW50ZXJmYWNlIFVwZGF0ZVBhcnRpY2xlUGFyYW1zIHtcbiAgcGFydGljbGVzRGF0YTogUGFydGljbGVzRGF0YTtcbiAgYW5pbWF0aW9uU3RhdGU6IEFuaW1hdGlvblN0YXRlO1xuICB0aGFub3NPcHRpb25zOiBXc1RoYW5vc09wdGlvbnM7XG4gIG5vaXNlOiBTaW1wbGV4Tm9pc2U7XG4gIHNlZWQ6IG51bWJlcjtcbn1cblxuaW50ZXJmYWNlIFBhcnRpY2xlSW5kaWNlcyB7XG4gIHg6IG51bWJlcjtcbiAgeTogbnVtYmVyO1xuICBkeDogbnVtYmVyO1xuICBkeTogbnVtYmVyO1xuICBheDogbnVtYmVyO1xuICBheTogbnVtYmVyO1xuICByOiBudW1iZXI7XG4gIGc6IG51bWJlcjtcbiAgYjogbnVtYmVyO1xuICBhOiBudW1iZXI7XG59XG5cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgV3NUaGFub3NTZXJ2aWNlIHtcbiAgY29uc3RydWN0b3IoXG4gICAgQEluamVjdChXU19USEFOT1NfT1BUSU9OU19UT0tFTilcbiAgICBwcml2YXRlIHRoYW5vc09wdGlvbnM6IFdzVGhhbm9zT3B0aW9ucyxcbiAgICBwcml2YXRlIG5nWm9uZTogTmdab25lXG4gICkge31cblxuICBwcml2YXRlIHN0YXRpYyBnZXRQYXJ0aWNsZUluZGljZXNGb3JCYXNlKGJhc2U6IG51bWJlcik6IFBhcnRpY2xlSW5kaWNlcyB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IGJhc2UsXG4gICAgICB5OiBiYXNlICsgMSxcbiAgICAgIGR4OiBiYXNlICsgMixcbiAgICAgIGR5OiBiYXNlICsgMyxcbiAgICAgIGF4OiBiYXNlICsgNCxcbiAgICAgIGF5OiBiYXNlICsgNSxcbiAgICAgIHI6IGJhc2UgKyA2LFxuICAgICAgZzogYmFzZSArIDcsXG4gICAgICBiOiBiYXNlICsgOCxcbiAgICAgIGE6IGJhc2UgKyA5LFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBnZXRDb2xvckluZGljZXNGb3JDb29yZChcbiAgICB4OiBudW1iZXIsXG4gICAgeTogbnVtYmVyLFxuICAgIHdpZHRoOiBudW1iZXJcbiAgKTogeyBhOiBudW1iZXI7IHI6IG51bWJlcjsgYjogbnVtYmVyOyBnOiBudW1iZXIgfSB7XG4gICAgY29uc3QgcmVkID0geSAqICh3aWR0aCAqIDQpICsgeCAqIDQ7XG4gICAgcmV0dXJuIHsgcjogcmVkLCBnOiByZWQgKyAxLCBiOiByZWQgKyAyLCBhOiByZWQgKyAzIH07XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyB1cGRhdGVQYXJ0aWNsZXMoe1xuICAgIHNlZWQsXG4gICAgbm9pc2UsXG4gICAgcGFydGljbGVzRGF0YSxcbiAgICB0aGFub3NPcHRpb25zLFxuICAgIGFuaW1hdGlvblN0YXRlLFxuICB9OiBVcGRhdGVQYXJ0aWNsZVBhcmFtcyk6IHZvaWQge1xuICAgIGNvbnN0IHsgZGVsdGFUU2VjLCBhbmltYXRpb25ULCBtYXhXaWR0aCwgbWF4SGVpZ2h0IH0gPSBhbmltYXRpb25TdGF0ZTtcbiAgICBjb25zdCB7IHBhcnRpY2xlQWNjZWxlcmF0aW9uIH0gPSB0aGFub3NPcHRpb25zO1xuICAgIGNvbnN0IHsgcGFydGljbGVzLCBtYXhQYXJ0aWNsZVgsIG1pblBhcnRpY2xlWSB9ID0gcGFydGljbGVzRGF0YTtcblxuICAgIC8vIHRoZSB0aW1lIGlzIHVzZWQgdG8gY2FsY3VsYXRlIHRoZSB2YXBvcml6YXRpb24gZnJvbnQuXG4gICAgY29uc3QgdGltZSA9IE1hdGguc2luKGFuaW1hdGlvblQgKiAoTWF0aC5QSSAvIDIpKSAqIDEuMTtcblxuICAgIGNvbnN0IHN0YXJ0QWNjZWxlcmF0ZVggPSBtYXhQYXJ0aWNsZVggLSB0aW1lICogbWF4UGFydGljbGVYO1xuICAgIGNvbnN0IHN0YXJ0QWNjZWxlcmF0ZVkgPSB0aW1lICogKG1heEhlaWdodCAtIG1pblBhcnRpY2xlWSkgKyBtaW5QYXJ0aWNsZVk7XG5cbiAgICBjb25zdCBsZW5ndGhZID0gbWF4SGVpZ2h0IC0gc3RhcnRBY2NlbGVyYXRlWTtcbiAgICBjb25zdCBhY2NlbGVyYXRlUmFkaXVzUG93ID1cbiAgICAgIHN0YXJ0QWNjZWxlcmF0ZVggKiBzdGFydEFjY2VsZXJhdGVYICsgbGVuZ3RoWSAqIGxlbmd0aFk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcnRpY2xlcy5sZW5ndGg7IGkgKz0gUEFSVElDTEVfQllURV9MRU5HVEgpIHtcbiAgICAgIGNvbnN0IHsgeCwgeSwgZHgsIGR5LCBheCwgYXksIGEgfSA9XG4gICAgICAgIFdzVGhhbm9zU2VydmljZS5nZXRQYXJ0aWNsZUluZGljZXNGb3JCYXNlKGkpO1xuICAgICAgY29uc3QgcGFydGljbGVYID0gcGFydGljbGVzW3hdO1xuICAgICAgY29uc3QgcGFydGljbGVZID0gcGFydGljbGVzW3ldO1xuXG4gICAgICAvLyBvbmx5IHVwZGF0ZSBwYXJ0aWNsZXMgdGhhdCBhcmUgaW5zaWRlIHZpZXcgYW5kIHZpc2libGVcbiAgICAgIGlmIChcbiAgICAgICAgcGFydGljbGVYID4gbWF4V2lkdGggfHxcbiAgICAgICAgcGFydGljbGVYIDwgMCB8fFxuICAgICAgICBwYXJ0aWNsZVkgPiBtYXhIZWlnaHQgfHxcbiAgICAgICAgcGFydGljbGVZIDwgMCB8fFxuICAgICAgICBwYXJ0aWNsZXNbYV0gPCBNSU5fUEFSVElDTEVfQUxQSEFcbiAgICAgICkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKCEoTWF0aC5hYnMocGFydGljbGVzW2F4XSkgPiAwIHx8IE1hdGguYWJzKHBhcnRpY2xlc1theV0pID4gMCkpIHtcbiAgICAgICAgbGV0IHBZTGVuZ3RoID0gbWF4SGVpZ2h0IC0gcGFydGljbGVZO1xuICAgICAgICBsZXQgcFhMZW5ndGggPSBwYXJ0aWNsZVg7XG5cbiAgICAgICAgLy8gd2UgY2FsY3VsYXRlIHNvbWUgcmFuZG9tIGxvb2tpbmcgbnVtYmVycyBhbmQgZnVuY3Rpb25zIHRvIGhhdmUgbmljZSBsb29raW5nIHZhcG9yaXppbmcgZnJvbnQgb2YgcGFydGljbGVzXG4gICAgICAgIC8vIHRvZG8gY29uc2lkZXIgdG8gdXNlIG5vaXNlO1xuICAgICAgICBwWExlbmd0aCArPSBNYXRoLnRhbigocFhMZW5ndGggLyAyMC4xMikgKiB0aW1lICsgc2VlZCkgKiAwLjU7XG4gICAgICAgIHBYTGVuZ3RoICs9IChwYXJ0aWNsZVggJSBkZWx0YVRTZWMpICogMC41O1xuICAgICAgICBwWExlbmd0aCArPVxuICAgICAgICAgIE1hdGguc2luKChwWExlbmd0aCAvIDMwICsgNzIzLjM5NCkgKiB0aW1lICsgc2VlZCAqIDEyLjUpICogMTE7XG4gICAgICAgIHBZTGVuZ3RoICs9IE1hdGgudGFuKChwWUxlbmd0aCAvIDAuNDUpICogdGltZSArIHNlZWQgKiAxLjUpICogMC41O1xuICAgICAgICBwWUxlbmd0aCArPVxuICAgICAgICAgIE1hdGguY29zKChwWUxlbmd0aCAvIDEwMCArIDIzMjMuMjM0KSAqIHRpbWUgKyBzZWVkICogNDU2LjEpICogMjM7XG5cbiAgICAgICAgY29uc3QgcExlbmd0aCA9IHBYTGVuZ3RoICogcFhMZW5ndGggKyBwWUxlbmd0aCAqIHBZTGVuZ3RoO1xuICAgICAgICBpZiAocExlbmd0aCA+IGFjY2VsZXJhdGVSYWRpdXNQb3cpIHtcbiAgICAgICAgICBwYXJ0aWNsZXNbYXhdID0gTWF0aC5yYW5kb20oKTtcbiAgICAgICAgICBwYXJ0aWNsZXNbYXldID0gTWF0aC5yYW5kb20oKSAqIC0xO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyB1c2Ugbm9pc2UgdG8gZmxvdyBhbG9uZyB2ZWxvY2l0eSBmaWVsZFxuICAgICAgICBjb25zdCBmbG93RmllbGRBY2MgPSBXc1RoYW5vc1NlcnZpY2UuZ2V0WFlGcm9tRmxvd0ZpZWxkKFxuICAgICAgICAgIG5vaXNlLFxuICAgICAgICAgIHNlZWQsXG4gICAgICAgICAgcGFydGljbGVYLFxuICAgICAgICAgIHBhcnRpY2xlWVxuICAgICAgICApO1xuICAgICAgICBjb25zdCBhY2NlbGVyYXRpb25YID0gZmxvd0ZpZWxkQWNjWzBdO1xuICAgICAgICBjb25zdCBhY2NlbGVyYXRpb25ZID0gZmxvd0ZpZWxkQWNjWzFdO1xuICAgICAgICBwYXJ0aWNsZXNbYXhdICs9IGFjY2VsZXJhdGlvblg7XG4gICAgICAgIHBhcnRpY2xlc1theV0gKz0gYWNjZWxlcmF0aW9uWTtcbiAgICAgIH1cblxuICAgICAgLy8gKiBNYXRoLnBvdygxICsgYW5pbWF0aW9uVCwgNClcbiAgICAgIHBhcnRpY2xlc1tkeF0gKz0gcGFydGljbGVzW2F4XSAqIHBhcnRpY2xlQWNjZWxlcmF0aW9uICogZGVsdGFUU2VjO1xuICAgICAgcGFydGljbGVzW2R5XSArPSBwYXJ0aWNsZXNbYXldICogcGFydGljbGVBY2NlbGVyYXRpb24gKiBkZWx0YVRTZWM7XG4gICAgICBwYXJ0aWNsZXNbeF0gKz0gcGFydGljbGVzW2R4XSAqIGRlbHRhVFNlYztcbiAgICAgIHBhcnRpY2xlc1t5XSArPSBwYXJ0aWNsZXNbZHldICogZGVsdGFUU2VjO1xuICAgICAgLy8gZmFkZSBwYXJ0aWNsZSBvdXQgKCB2ZXJ5IGxhdGUpO1xuICAgICAgcGFydGljbGVzW2FdICo9IDEgLSBNYXRoLnBvdyhhbmltYXRpb25ULCAxNSk7IC8vIDI1NSAtIE1hdGguc3FydChwYXJ0aWNsZXNbZHhdICogcGFydGljbGVzW2R4XSArIHBhcnRpY2xlc1tkeV0gKiBwYXJ0aWNsZXNbZHldKSAvIDEuMjtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBkcmF3UGFydGljbGVzKFxuICAgIGRyYXdDdHg6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCxcbiAgICBwYXJ0aWNsZXM6IEZsb2F0MzJBcnJheVxuICApOiB2b2lkIHtcbiAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IGRyYXdDdHguY2FudmFzO1xuICAgIGRyYXdDdHguY2xlYXJSZWN0KDAsIDAsIHdpZHRoLCBoZWlnaHQpO1xuICAgIGNvbnN0IGltYWdlID0gZHJhd0N0eC5nZXRJbWFnZURhdGEoMCwgMCwgd2lkdGgsIGhlaWdodCk7XG4gICAgY29uc3QgaW1hZ2VEYXRhID0gaW1hZ2UuZGF0YTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcnRpY2xlcy5sZW5ndGg7IGkgKz0gUEFSVElDTEVfQllURV9MRU5HVEgpIHtcbiAgICAgIGNvbnN0IHBhcnRpY2xlWCA9IHBhcnRpY2xlc1tpXTtcbiAgICAgIGNvbnN0IHBhcnRpY2xlWSA9IHBhcnRpY2xlc1tpICsgMV07XG4gICAgICBjb25zdCBwSSA9IFdzVGhhbm9zU2VydmljZS5nZXRQYXJ0aWNsZUluZGljZXNGb3JCYXNlKGkpO1xuICAgICAgaWYgKFxuICAgICAgICBwYXJ0aWNsZVggPiB3aWR0aCB8fFxuICAgICAgICBwYXJ0aWNsZVggPCAwIHx8XG4gICAgICAgIHBhcnRpY2xlWSA+IGhlaWdodCB8fFxuICAgICAgICBwYXJ0aWNsZVkgPCAwIHx8XG4gICAgICAgIHBhcnRpY2xlc1twSS5hXSA8IE1JTl9QQVJUSUNMRV9BTFBIQVxuICAgICAgKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgeyByLCBnLCBiLCBhIH0gPSBXc1RoYW5vc1NlcnZpY2UuZ2V0Q29sb3JJbmRpY2VzRm9yQ29vcmQoXG4gICAgICAgIH5+cGFydGljbGVzW3BJLnhdLFxuICAgICAgICB+fnBhcnRpY2xlc1twSS55XSxcbiAgICAgICAgd2lkdGhcbiAgICAgICk7XG4gICAgICBpbWFnZURhdGFbcl0gPSB+fnBhcnRpY2xlc1twSS5yXTtcbiAgICAgIGltYWdlRGF0YVtnXSA9IH5+cGFydGljbGVzW3BJLmddO1xuICAgICAgaW1hZ2VEYXRhW2JdID0gfn5wYXJ0aWNsZXNbcEkuYl07XG4gICAgICBpbWFnZURhdGFbYV0gPSB+fnBhcnRpY2xlc1twSS5hXTtcbiAgICB9XG4gICAgZHJhd0N0eC5wdXRJbWFnZURhdGEoaW1hZ2UsIDAsIDApO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgcHJlcGFyZUNhbnZhc0ZvclZhcG9yaXplKFxuICAgIGRpdkNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQsXG4gICAgbWF4UGFydGljbGVDb3VudDogbnVtYmVyXG4gICk6IHtcbiAgICBwYXJ0aWNsZXNEYXRhOiBQYXJ0aWNsZXNEYXRhO1xuICAgIHJlc3VsdENhbnZhczogSFRNTENhbnZhc0VsZW1lbnQ7XG4gIH0ge1xuICAgIGNvbnN0IHsgd2lkdGgsIGhlaWdodCB9ID0gZGl2Q2FudmFzO1xuXG4gICAgLy8gc2NhbGUgcmVzdWx0IGNhbnZhcyB0byBoYXZlIG1vcmUgcm9vbSB0byBkcmF3IHBhcnRpY2xlcyB3aGlsZSB2YXBvcml6aW5nO1xuICAgIGNvbnN0IHJlc3VsdEhlaWdodCA9IGhlaWdodCAqIEhFSUdIVF9TQ0FMRTtcbiAgICBjb25zdCByZXN1bHRXaWR0aCA9IHdpZHRoICogV0lEVEhfU0NBTEU7XG4gICAgY29uc3QgcmVzdWx0Q2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgIHJlc3VsdENhbnZhcy5oZWlnaHQgPSByZXN1bHRIZWlnaHQ7XG4gICAgcmVzdWx0Q2FudmFzLndpZHRoID0gcmVzdWx0V2lkdGg7XG5cbiAgICBjb25zdCBpbWFnZURhdGEgPSBkaXZDYW52YXNcbiAgICAgIC5nZXRDb250ZXh0KCcyZCcpXG4gICAgICA/LmdldEltYWdlRGF0YSgwLCAwLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICBpZiAoaW1hZ2VEYXRhID09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ291bGQgbm90IGdldCBpbWFnZSBkYXRhIGZyb20gY2FudmFzJyk7XG4gICAgfVxuICAgIGNvbnN0IHBhcnRpY2xlc0RhdGEgPSBXc1RoYW5vc1NlcnZpY2UuY3JlYXRlUGFydGljbGVzRm9ySW1hZ2VEYXRhKFxuICAgICAgaW1hZ2VEYXRhLFxuICAgICAgbWF4UGFydGljbGVDb3VudCxcbiAgICAgIHJlc3VsdEhlaWdodFxuICAgICk7XG4gICAgcmV0dXJuIHsgcmVzdWx0Q2FudmFzLCBwYXJ0aWNsZXNEYXRhIH07XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBjcmVhdGVQYXJ0aWNsZXNGb3JJbWFnZURhdGEoXG4gICAgaW1hZ2VEYXRhOiBJbWFnZURhdGEsXG4gICAgbWF4UGFydGljbGVDb3VudDogbnVtYmVyLFxuICAgIHJlc3VsdEhlaWdodDogbnVtYmVyXG4gICk6IHsgbWluUGFydGljbGVZOiBudW1iZXI7IG1heFBhcnRpY2xlWDogbnVtYmVyOyBwYXJ0aWNsZXM6IEZsb2F0MzJBcnJheSB9IHtcbiAgICBjb25zdCB7IHdpZHRoLCBoZWlnaHQgfSA9IGltYWdlRGF0YTtcbiAgICBsZXQgcGFydGljbGVDYW5kaWRhdGVzID0gMDtcbiAgICBsZXQgcGFydGljbGVDb3VudCA9IDA7XG5cbiAgICBjb25zdCBwYXJ0aWNsZUNhbmRpYXRlc0xpc3Q6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfVtdID0gW107XG4gICAgZm9yIChsZXQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykge1xuICAgICAgZm9yIChsZXQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7XG4gICAgICAgIGNvbnN0IHsgYSB9ID0gV3NUaGFub3NTZXJ2aWNlLmdldENvbG9ySW5kaWNlc0ZvckNvb3JkKHgsIHksIHdpZHRoKTtcbiAgICAgICAgaWYgKGltYWdlRGF0YS5kYXRhW2FdID49IE1JTl9QQVJUSUNMRV9BTFBIQSkge1xuICAgICAgICAgIHBhcnRpY2xlQ2FuZGlkYXRlcysrO1xuICAgICAgICAgIHBhcnRpY2xlQ2FuZGlhdGVzTGlzdC5wdXNoKHsgeCwgeSB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IG1heE51bVBhcnRpY2xlcyA9IE1hdGgubWluKHBhcnRpY2xlQ2FuZGlkYXRlcywgbWF4UGFydGljbGVDb3VudCk7XG4gICAgY29uc3QgcGFydGljbGVzID0gbmV3IEZsb2F0MzJBcnJheShcbiAgICAgIEZsb2F0MzJBcnJheS5CWVRFU19QRVJfRUxFTUVOVCAqIG1heE51bVBhcnRpY2xlcyAqIFBBUlRJQ0xFX0JZVEVfTEVOR1RIXG4gICAgKTtcblxuICAgIGxldCBtYXhQYXJ0aWNsZVggPSAwO1xuICAgIGxldCBtaW5QYXJ0aWNsZVkgPSByZXN1bHRIZWlnaHQ7XG4gICAgd2hpbGUgKHBhcnRpY2xlQ291bnQgPCBtYXhOdW1QYXJ0aWNsZXMpIHtcbiAgICAgIC8vIHNlbGVjdCByYW5kb20gaW5kZXggZnJvbSBjYW5kaWF0ZXNcbiAgICAgIGNvbnN0IGluZGV4ID0gfn4oTWF0aC5yYW5kb20oKSAqIHBhcnRpY2xlQ2FuZGlhdGVzTGlzdC5sZW5ndGgpO1xuICAgICAgY29uc3QgeyB4LCB5IH0gPSBwYXJ0aWNsZUNhbmRpYXRlc0xpc3RbaW5kZXhdO1xuXG4gICAgICAvLyBvdmVyd3JpdGUgaW5kZXggd2l0aCBsYXN0IGVsZW1lbnQgdG8gcHJldmVudCBkb3VibGUgc2VsZWN0aW9uIG9mIHBhcnRpY2xlc1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgIHBhcnRpY2xlQ2FuZGlhdGVzTGlzdFtpbmRleF0gPSBwYXJ0aWNsZUNhbmRpYXRlc0xpc3QucG9wKCkhO1xuXG4gICAgICBtYXhQYXJ0aWNsZVggPSBNYXRoLm1heChtYXhQYXJ0aWNsZVgsIHgpO1xuICAgICAgbWluUGFydGljbGVZID0gTWF0aC5taW4obWluUGFydGljbGVZLCB5KTtcbiAgICAgIGNvbnN0IHsgZHgsIGR5LCBheCwgYXksIHIsIGcsIGIsIGEsIC4uLnh5IH0gPVxuICAgICAgICBXc1RoYW5vc1NlcnZpY2UuZ2V0UGFydGljbGVJbmRpY2VzRm9yQmFzZShcbiAgICAgICAgICBwYXJ0aWNsZUNvdW50ICogUEFSVElDTEVfQllURV9MRU5HVEhcbiAgICAgICAgKTtcbiAgICAgIHBhcnRpY2xlc1t4eS54XSA9IHg7XG4gICAgICBwYXJ0aWNsZXNbeHkueV0gPSB5ICsgcmVzdWx0SGVpZ2h0IC0gaGVpZ2h0O1xuICAgICAgcGFydGljbGVzW2R4XSA9IDA7XG4gICAgICBwYXJ0aWNsZXNbZHldID0gMDtcbiAgICAgIHBhcnRpY2xlc1theF0gPSAwO1xuICAgICAgcGFydGljbGVzW2F5XSA9IDA7XG5cbiAgICAgIGNvbnN0IGluZGljZXNJbWFnZSA9IFdzVGhhbm9zU2VydmljZS5nZXRDb2xvckluZGljZXNGb3JDb29yZCh4LCB5LCB3aWR0aCk7XG5cbiAgICAgIHBhcnRpY2xlc1tyXSA9IGltYWdlRGF0YS5kYXRhW2luZGljZXNJbWFnZS5yXTtcbiAgICAgIHBhcnRpY2xlc1tnXSA9IGltYWdlRGF0YS5kYXRhW2luZGljZXNJbWFnZS5nXTtcbiAgICAgIHBhcnRpY2xlc1tiXSA9IGltYWdlRGF0YS5kYXRhW2luZGljZXNJbWFnZS5iXTtcbiAgICAgIHBhcnRpY2xlc1thXSA9IGltYWdlRGF0YS5kYXRhW2luZGljZXNJbWFnZS5hXTtcbiAgICAgIHBhcnRpY2xlQ291bnQrKztcbiAgICB9XG4gICAgcmV0dXJuIHsgcGFydGljbGVzLCBtYXhQYXJ0aWNsZVgsIG1pblBhcnRpY2xlWSB9O1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0WFlGcm9tRmxvd0ZpZWxkKFxuICAgIG5vaXNlOiBTaW1wbGV4Tm9pc2UsXG4gICAgc2VlZDogbnVtYmVyLFxuICAgIHg6IG51bWJlcixcbiAgICB5OiBudW1iZXJcbiAgKSB7XG4gICAgY29uc3Qgc2FtcGxlWCA9IG5vaXNlLnNjYWxlZDNEKHgsIHksIHNlZWQgKyAzMy4yMywgRkxPV19GSUVMRF9SRVMpO1xuICAgIGNvbnN0IHNhbXBsZVkgPSBub2lzZS5zY2FsZWQzRCh4LCBzZWVkIC8gMTMuMjMsIHksIEZMT1dfRklFTERfUkVTKSAqIC0xO1xuICAgIHJldHVybiBbc2FtcGxlWCwgc2FtcGxlWV07XG4gIH1cblxuICAvKipcbiAgICogc3RhcnQgdGhlIHZhcG9yaXplLWVmZmVjdC5cbiAgICpcbiAgICogSXQncyBydW5uaW5nIG91dHNpZGUgdGhlIG5nWm9uZS5cbiAgICovXG4gIHZhcG9yaXplKGVsZW06IEhUTUxFbGVtZW50KTogT2JzZXJ2YWJsZTxBbmltYXRpb25TdGF0ZT4ge1xuICAgIHJldHVybiB0aGlzLm5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB0aGlzLnZhcG9yaXplSW50ZXJuKGVsZW0pKTtcbiAgfVxuXG4gIHByaXZhdGUgdmFwb3JpemVJbnRlcm4oZWxlbTogSFRNTEVsZW1lbnQpOiBPYnNlcnZhYmxlPEFuaW1hdGlvblN0YXRlPiB7XG4gICAgZWxlbS5zdHlsZS5vcGFjaXR5ID0gZWxlbS5zdHlsZS5vcGFjaXR5IHx8ICcxJztcbiAgICBlbGVtLnN0eWxlLnRyYW5zaXRpb24gPSBgb3BhY2l0eSAke01hdGguZmxvb3IoXG4gICAgICB0aGlzLnRoYW5vc09wdGlvbnMuYW5pbWF0aW9uTGVuZ3RoICogMC44XG4gICAgKX1tcyBlYXNlLW91dGA7XG4gICAgY29uc3Qgbm9pc2UgPSBuZXcgU2ltcGxleE5vaXNlKHsgZnJlcXVlbmN5OiAwLjAxLCBtaW46IDAgfSk7XG4gICAgY29uc3Qgc2VlZCA9IG5ldyBEYXRlKCkuZ2V0RGF0ZSgpICogTWF0aC5yYW5kb20oKTtcbiAgICBjb25zdCBodG1sMkNhbnZhc1Byb21pc2U6IFByb21pc2U8SFRNTENhbnZhc0VsZW1lbnQ+ID0gaHRtbDJjYW52YXMoZWxlbSwge1xuICAgICAgYmFja2dyb3VuZENvbG9yOiBudWxsLFxuICAgICAgc2NhbGU6IDEsXG4gICAgICBhbGxvd1RhaW50OiB0cnVlLFxuICAgICAgd2luZG93SGVpZ2h0OiB3aW5kb3cuaW5uZXJIZWlnaHQsXG4gICAgICB3aW5kb3dXaWR0aDogd2luZG93LmlubmVyV2lkdGgsXG4gICAgICBzY3JvbGxZOiAtd2luZG93LnNjcm9sbFksXG4gICAgfSk7XG5cbiAgICByZXR1cm4gZnJvbShodG1sMkNhbnZhc1Byb21pc2UpLnBpcGUoXG4gICAgICBtYXAoKGNhbnZhc0Zyb21IdG1sRWxlbSkgPT4ge1xuICAgICAgICBjb25zdCBjYW52YXNBbmRQYXJ0aWNsZXMgPSBXc1RoYW5vc1NlcnZpY2UucHJlcGFyZUNhbnZhc0ZvclZhcG9yaXplKFxuICAgICAgICAgIGNhbnZhc0Zyb21IdG1sRWxlbSxcbiAgICAgICAgICB0aGlzLnRoYW5vc09wdGlvbnMubWF4UGFydGljbGVDb3VudFxuICAgICAgICApO1xuICAgICAgICBjb25zdCB7IHJlc3VsdENhbnZhcyB9ID0gY2FudmFzQW5kUGFydGljbGVzO1xuICAgICAgICBpZiAoZWxlbS5wYXJlbnRFbGVtZW50KSB7XG4gICAgICAgICAgZWxlbS5wYXJlbnRFbGVtZW50LnN0eWxlLnBvc2l0aW9uID1cbiAgICAgICAgICAgIGVsZW0ucGFyZW50RWxlbWVudC5zdHlsZS5wb3NpdGlvbiB8fCAncmVsYXRpdmUnO1xuICAgICAgICB9XG4gICAgICAgIHJlc3VsdENhbnZhcy5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgICAgIHJlc3VsdENhbnZhcy5zdHlsZS5sZWZ0ID0gMCArICdweCc7XG4gICAgICAgIHJlc3VsdENhbnZhcy5zdHlsZS50b3AgPVxuICAgICAgICAgICctJyArIGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkuaGVpZ2h0ICogKEhFSUdIVF9TQ0FMRSAtIDEpICsgJ3B4JztcbiAgICAgICAgcmVzdWx0Q2FudmFzLnN0eWxlLnpJbmRleCA9ICcyMDAwJztcbiAgICAgICAgcmVzdWx0Q2FudmFzLnN0eWxlLnBvaW50ZXJFdmVudHMgPSAnbm9uZSc7XG5cbiAgICAgICAgZWxlbS5pbnNlcnRBZGphY2VudEVsZW1lbnQoJ2JlZm9yZWJlZ2luJywgcmVzdWx0Q2FudmFzKTtcbiAgICAgICAgLy8gdGhpcyBzaG91bGQgc3RhcnQgdGhlIHRyYW5zaXRpb24gYWJvdmUgZGVmaW5lZFxuICAgICAgICBlbGVtLnN0eWxlLm9wYWNpdHkgPSAnMCc7XG4gICAgICAgIHJldHVybiBjYW52YXNBbmRQYXJ0aWNsZXM7XG4gICAgICB9KSxcbiAgICAgIHN3aXRjaE1hcCgoeyByZXN1bHRDYW52YXMsIHBhcnRpY2xlc0RhdGEgfSkgPT4ge1xuICAgICAgICBsZXQgdGltZSA9IDA7XG4gICAgICAgIGNvbnN0IHsgYW5pbWF0aW9uTGVuZ3RoLCBtYXhQYXJ0aWNsZUNvdW50LCBwYXJ0aWNsZUFjY2VsZXJhdGlvbiB9ID1cbiAgICAgICAgICB0aGlzLnRoYW5vc09wdGlvbnM7XG4gICAgICAgIHJldHVybiBpbnRlcnZhbCgxMDAwIC8gNjAsIGFuaW1hdGlvbkZyYW1lU2NoZWR1bGVyKS5waXBlKFxuICAgICAgICAgIHRpbWVJbnRlcnZhbCgpLFxuICAgICAgICAgIHRhcCgoZGVsdGFUKSA9PiAodGltZSArPSBkZWx0YVQuaW50ZXJ2YWwpKSxcbiAgICAgICAgICBtYXAoXG4gICAgICAgICAgICAoZGVsdGFUKSA9PlxuICAgICAgICAgICAgICAoe1xuICAgICAgICAgICAgICAgIGRlbHRhVFNlYzogZGVsdGFULmludGVydmFsIC8gMTAwMCxcbiAgICAgICAgICAgICAgICBhbmltYXRpb25UOiB0aW1lIC8gYW5pbWF0aW9uTGVuZ3RoLFxuICAgICAgICAgICAgICAgIG1heFdpZHRoOiByZXN1bHRDYW52YXMud2lkdGgsXG4gICAgICAgICAgICAgICAgbWF4SGVpZ2h0OiByZXN1bHRDYW52YXMuaGVpZ2h0LFxuICAgICAgICAgICAgICB9IGFzIEFuaW1hdGlvblN0YXRlKVxuICAgICAgICAgICksXG4gICAgICAgICAgdGFwKChhbmltYXRpb25TdGF0ZSkgPT4ge1xuICAgICAgICAgICAgV3NUaGFub3NTZXJ2aWNlLnVwZGF0ZVBhcnRpY2xlcyh7XG4gICAgICAgICAgICAgIHBhcnRpY2xlc0RhdGEsXG4gICAgICAgICAgICAgIGFuaW1hdGlvblN0YXRlLFxuICAgICAgICAgICAgICB0aGFub3NPcHRpb25zOiB7XG4gICAgICAgICAgICAgICAgYW5pbWF0aW9uTGVuZ3RoLFxuICAgICAgICAgICAgICAgIG1heFBhcnRpY2xlQ291bnQsXG4gICAgICAgICAgICAgICAgcGFydGljbGVBY2NlbGVyYXRpb24sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIG5vaXNlLFxuICAgICAgICAgICAgICBzZWVkLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjb25zdCBjb250ZXh0ID0gcmVzdWx0Q2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgICAgICAgICBpZiAoY29udGV4dCkge1xuICAgICAgICAgICAgICBXc1RoYW5vc1NlcnZpY2UuZHJhd1BhcnRpY2xlcyhjb250ZXh0LCBwYXJ0aWNsZXNEYXRhLnBhcnRpY2xlcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSksXG4gICAgICAgICAgdGFrZVdoaWxlKChhbmltYXRpb25TdGF0ZSkgPT4gYW5pbWF0aW9uU3RhdGUuYW5pbWF0aW9uVCA8PSAxKSxcbiAgICAgICAgICB0YXAoe1xuICAgICAgICAgICAgY29tcGxldGU6ICgpID0+IHtcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdENhbnZhcy5yZW1vdmUoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxufVxuIl19