@rocketshow/designer 1.39.0 → 1.42.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.
- package/fesm2022/rocketshow-designer.mjs +1084 -1061
- package/fesm2022/rocketshow-designer.mjs.map +1 -1
- package/index.d.ts +1658 -5
- package/package.json +2 -4
- package/rocketshow-designer-1.42.0.tgz +0 -0
- package/esm2022/lib/array-sort-pipe.mjs +0 -30
- package/esm2022/lib/designer.component.mjs +0 -672
- package/esm2022/lib/designer.module.mjs +0 -186
- package/esm2022/lib/designer.service.mjs +0 -14
- package/esm2022/lib/dropzone/dropzone.component.mjs +0 -93
- package/esm2022/lib/effect/effect-curve/effect-curve.component.mjs +0 -577
- package/esm2022/lib/effect/effect-pan-tilt/effect-pan-tilt.component.mjs +0 -36
- package/esm2022/lib/effect/effect.component.mjs +0 -174
- package/esm2022/lib/error-dialog/error-dialog.component.mjs +0 -75
- package/esm2022/lib/fixture/fixture-capability/fixture-capability-channel/fixture-capability-channel.component.mjs +0 -370
- package/esm2022/lib/fixture/fixture-capability/fixture-capability-color/fixture-capability-color.component.mjs +0 -147
- package/esm2022/lib/fixture/fixture-capability/fixture-capability-color-wheel/fixture-capability-color-wheel.component.mjs +0 -213
- package/esm2022/lib/fixture/fixture-capability/fixture-capability-dimmer/fixture-capability-dimmer.component.mjs +0 -78
- package/esm2022/lib/fixture/fixture-capability/fixture-capability-pan-tilt/fixture-capability-pan-tilt.component.mjs +0 -119
- package/esm2022/lib/fixture/fixture-capability/fixture-capability.component.mjs +0 -191
- package/esm2022/lib/fixture/fixture-channel/fixture-channel.component.mjs +0 -162
- package/esm2022/lib/fixture/fixture-settings/fixture-settings-position/fixture-settings-position.component.mjs +0 -365
- package/esm2022/lib/fixture/fixture-settings/fixture-settings-stage/fixture-settings-stage.component.mjs +0 -151
- package/esm2022/lib/fixture/fixture-settings/fixture-settings.component.mjs +0 -46
- package/esm2022/lib/fixture/fixture.component.mjs +0 -148
- package/esm2022/lib/fixture-pool/fixture-pool-create-from-file/fixture-pool-create-from-file.component.mjs +0 -145
- package/esm2022/lib/fixture-pool/fixture-pool.component.mjs +0 -641
- package/esm2022/lib/intro/intro.component.mjs +0 -95
- package/esm2022/lib/master-dimmer/master-dimmer.component.mjs +0 -66
- package/esm2022/lib/models/cached-fixture-capability.mjs +0 -9
- package/esm2022/lib/models/cached-fixture-channel.mjs +0 -7
- package/esm2022/lib/models/cached-fixture.mjs +0 -6
- package/esm2022/lib/models/color.mjs +0 -8
- package/esm2022/lib/models/composition.mjs +0 -46
- package/esm2022/lib/models/effect-curve-profile-channel.mjs +0 -15
- package/esm2022/lib/models/effect-curve.mjs +0 -69
- package/esm2022/lib/models/effect-pan-tilt.mjs +0 -19
- package/esm2022/lib/models/effect.mjs +0 -12
- package/esm2022/lib/models/fixture-capability-value.mjs +0 -15
- package/esm2022/lib/models/fixture-capability.mjs +0 -127
- package/esm2022/lib/models/fixture-channel-value.mjs +0 -11
- package/esm2022/lib/models/fixture-channel.mjs +0 -24
- package/esm2022/lib/models/fixture-matrix-pixel-group-constraints.mjs +0 -27
- package/esm2022/lib/models/fixture-matrix-pixel-group.mjs +0 -12
- package/esm2022/lib/models/fixture-matrix.mjs +0 -25
- package/esm2022/lib/models/fixture-mode-channel.mjs +0 -26
- package/esm2022/lib/models/fixture-mode.mjs +0 -17
- package/esm2022/lib/models/fixture-physical.mjs +0 -14
- package/esm2022/lib/models/fixture-profile.mjs +0 -85
- package/esm2022/lib/models/fixture-wheel-slot.mjs +0 -26
- package/esm2022/lib/models/fixture-wheel.mjs +0 -15
- package/esm2022/lib/models/fixture.mjs +0 -40
- package/esm2022/lib/models/preset-fixture.mjs +0 -10
- package/esm2022/lib/models/preset-region-scene.mjs +0 -8
- package/esm2022/lib/models/preset.mjs +0 -65
- package/esm2022/lib/models/project.mjs +0 -78
- package/esm2022/lib/models/scene-playback-region.mjs +0 -11
- package/esm2022/lib/models/scene.mjs +0 -27
- package/esm2022/lib/preset/preset-settings/preset-settings.component.mjs +0 -194
- package/esm2022/lib/preset/preset.component.mjs +0 -131
- package/esm2022/lib/preview/models/color-changer-3d.mjs +0 -52
- package/esm2022/lib/preview/models/fixture-3d.mjs +0 -260
- package/esm2022/lib/preview/models/moving-head-3d.mjs +0 -115
- package/esm2022/lib/preview/preview.component.mjs +0 -217
- package/esm2022/lib/project/project-browser/project-browser.component.mjs +0 -143
- package/esm2022/lib/project/project-import/project-import.component.mjs +0 -107
- package/esm2022/lib/project/project-save/project-save.component.mjs +0 -178
- package/esm2022/lib/project/project-share/project-share.component.mjs +0 -71
- package/esm2022/lib/scene/scene-settings/scene-settings.component.mjs +0 -146
- package/esm2022/lib/scene/scene.component.mjs +0 -110
- package/esm2022/lib/services/animation.service.mjs +0 -16
- package/esm2022/lib/services/config.service.mjs +0 -28
- package/esm2022/lib/services/effect.service.mjs +0 -14
- package/esm2022/lib/services/error-dialog.service.mjs +0 -39
- package/esm2022/lib/services/fixture-pool.service.mjs +0 -30
- package/esm2022/lib/services/fixture.service.mjs +0 -693
- package/esm2022/lib/services/hotkey-target-exclude.service.mjs +0 -24
- package/esm2022/lib/services/intro.service.mjs +0 -140
- package/esm2022/lib/services/preset.service.mjs +0 -450
- package/esm2022/lib/services/preview-mesh.service.mjs +0 -57
- package/esm2022/lib/services/preview.service.mjs +0 -481
- package/esm2022/lib/services/project-load.service.mjs +0 -206
- package/esm2022/lib/services/project.service.mjs +0 -93
- package/esm2022/lib/services/scene.service.mjs +0 -164
- package/esm2022/lib/services/timeline.service.mjs +0 -726
- package/esm2022/lib/services/user-ensure-login.service.mjs +0 -38
- package/esm2022/lib/services/user.service.mjs +0 -89
- package/esm2022/lib/services/uuid.service.mjs +0 -23
- package/esm2022/lib/services/warning-dialog.service.mjs +0 -38
- package/esm2022/lib/timeline/composition-settings/composition-settings.component.mjs +0 -304
- package/esm2022/lib/timeline/timeline-grid/timeline-grid.component.mjs +0 -216
- package/esm2022/lib/timeline/timeline.component.mjs +0 -418
- package/esm2022/lib/user/user-login/user-login.component.mjs +0 -144
- package/esm2022/lib/user/user-register/user-register.component.mjs +0 -220
- package/esm2022/lib/wait-dialog/wait-dialog.component.mjs +0 -26
- package/esm2022/lib/warning-dialog/warning-dialog.component.mjs +0 -68
- package/esm2022/public_api.mjs +0 -7
- package/esm2022/rocketshow-designer.mjs +0 -5
- package/lib/array-sort-pipe.d.ts +0 -7
- package/lib/designer.component.d.ts +0 -73
- package/lib/designer.module.d.ts +0 -57
- package/lib/designer.service.d.ts +0 -6
- package/lib/dropzone/dropzone.component.d.ts +0 -24
- package/lib/effect/effect-curve/effect-curve.component.d.ts +0 -59
- package/lib/effect/effect-pan-tilt/effect-pan-tilt.component.d.ts +0 -15
- package/lib/effect/effect.component.d.ts +0 -22
- package/lib/error-dialog/error-dialog.component.d.ts +0 -17
- package/lib/fixture/fixture-capability/fixture-capability-channel/fixture-capability-channel.component.d.ts +0 -41
- package/lib/fixture/fixture-capability/fixture-capability-color/fixture-capability-color.component.d.ts +0 -26
- package/lib/fixture/fixture-capability/fixture-capability-color-wheel/fixture-capability-color-wheel.component.d.ts +0 -34
- package/lib/fixture/fixture-capability/fixture-capability-dimmer/fixture-capability-dimmer.component.d.ts +0 -15
- package/lib/fixture/fixture-capability/fixture-capability-pan-tilt/fixture-capability-pan-tilt.component.d.ts +0 -18
- package/lib/fixture/fixture-capability/fixture-capability.component.d.ts +0 -31
- package/lib/fixture/fixture-channel/fixture-channel.component.d.ts +0 -25
- package/lib/fixture/fixture-settings/fixture-settings-position/fixture-settings-position.component.d.ts +0 -32
- package/lib/fixture/fixture-settings/fixture-settings-stage/fixture-settings-stage.component.d.ts +0 -14
- package/lib/fixture/fixture-settings/fixture-settings.component.d.ts +0 -14
- package/lib/fixture/fixture.component.d.ts +0 -25
- package/lib/fixture-pool/fixture-pool-create-from-file/fixture-pool-create-from-file.component.d.ts +0 -28
- package/lib/fixture-pool/fixture-pool.component.d.ts +0 -62
- package/lib/intro/intro.component.d.ts +0 -11
- package/lib/master-dimmer/master-dimmer.component.d.ts +0 -15
- package/lib/models/cached-fixture-capability.d.ts +0 -11
- package/lib/models/cached-fixture-channel.d.ts +0 -11
- package/lib/models/cached-fixture.d.ts +0 -11
- package/lib/models/color.d.ts +0 -6
- package/lib/models/composition.d.ts +0 -19
- package/lib/models/effect-curve-profile-channel.d.ts +0 -5
- package/lib/models/effect-curve.d.ts +0 -15
- package/lib/models/effect-pan-tilt.d.ts +0 -6
- package/lib/models/effect.d.ts +0 -6
- package/lib/models/fixture-capability-value.d.ts +0 -10
- package/lib/models/fixture-capability.d.ts +0 -117
- package/lib/models/fixture-channel-value.d.ts +0 -6
- package/lib/models/fixture-channel.d.ts +0 -9
- package/lib/models/fixture-matrix-pixel-group-constraints.d.ts +0 -8
- package/lib/models/fixture-matrix-pixel-group.d.ts +0 -6
- package/lib/models/fixture-matrix.d.ts +0 -6
- package/lib/models/fixture-mode-channel.d.ts +0 -8
- package/lib/models/fixture-mode.d.ts +0 -8
- package/lib/models/fixture-physical.d.ts +0 -4
- package/lib/models/fixture-profile.d.ts +0 -39
- package/lib/models/fixture-wheel-slot.d.ts +0 -17
- package/lib/models/fixture-wheel.d.ts +0 -5
- package/lib/models/fixture.d.ts +0 -23
- package/lib/models/preset-fixture.d.ts +0 -5
- package/lib/models/preset-region-scene.d.ts +0 -9
- package/lib/models/preset.d.ts +0 -20
- package/lib/models/project.d.ts +0 -31
- package/lib/models/scene-playback-region.d.ts +0 -6
- package/lib/models/scene.d.ts +0 -11
- package/lib/preset/preset-settings/preset-settings.component.d.ts +0 -22
- package/lib/preset/preset.component.d.ts +0 -25
- package/lib/preview/models/color-changer-3d.d.ts +0 -16
- package/lib/preview/models/fixture-3d.d.ts +0 -38
- package/lib/preview/models/moving-head-3d.d.ts +0 -23
- package/lib/preview/preview.component.d.ts +0 -38
- package/lib/project/project-browser/project-browser.component.d.ts +0 -27
- package/lib/project/project-import/project-import.component.d.ts +0 -23
- package/lib/project/project-save/project-save.component.d.ts +0 -28
- package/lib/project/project-share/project-share.component.d.ts +0 -16
- package/lib/scene/scene-settings/scene-settings.component.d.ts +0 -20
- package/lib/scene/scene.component.d.ts +0 -22
- package/lib/services/animation.service.d.ts +0 -7
- package/lib/services/config.service.d.ts +0 -20
- package/lib/services/effect.service.d.ts +0 -8
- package/lib/services/error-dialog.service.d.ts +0 -12
- package/lib/services/fixture-pool.service.d.ts +0 -10
- package/lib/services/fixture.service.d.ts +0 -70
- package/lib/services/hotkey-target-exclude.service.d.ts +0 -7
- package/lib/services/intro.service.d.ts +0 -21
- package/lib/services/preset.service.d.ts +0 -64
- package/lib/services/preview-mesh.service.d.ts +0 -14
- package/lib/services/preview.service.d.ts +0 -42
- package/lib/services/project-load.service.d.ts +0 -36
- package/lib/services/project.service.d.ts +0 -26
- package/lib/services/scene.service.d.ts +0 -30
- package/lib/services/timeline.service.d.ts +0 -70
- package/lib/services/user-ensure-login.service.d.ts +0 -14
- package/lib/services/user.service.d.ts +0 -22
- package/lib/services/uuid.service.d.ts +0 -7
- package/lib/services/warning-dialog.service.d.ts +0 -12
- package/lib/timeline/composition-settings/composition-settings.component.d.ts +0 -48
- package/lib/timeline/timeline-grid/timeline-grid.component.d.ts +0 -22
- package/lib/timeline/timeline.component.d.ts +0 -50
- package/lib/user/user-login/user-login.component.d.ts +0 -21
- package/lib/user/user-register/user-register.component.d.ts +0 -26
- package/lib/wait-dialog/wait-dialog.component.d.ts +0 -8
- package/lib/warning-dialog/warning-dialog.component.d.ts +0 -16
- package/public_api.d.ts +0 -3
- package/rocketshow-designer-1.39.0.tgz +0 -0
|
@@ -1,693 +0,0 @@
|
|
|
1
|
-
import { HttpClient } from '@angular/common/http';
|
|
2
|
-
import { Injectable } from '@angular/core';
|
|
3
|
-
import { TranslateService } from '@ngx-translate/core';
|
|
4
|
-
import { ToastrService } from 'ngx-toastr';
|
|
5
|
-
import { forkJoin, of } from 'rxjs';
|
|
6
|
-
import { map } from 'rxjs/operators';
|
|
7
|
-
import { CachedFixture } from '../models/cached-fixture';
|
|
8
|
-
import { CachedFixtureCapability } from '../models/cached-fixture-capability';
|
|
9
|
-
import { CachedFixtureChannel } from '../models/cached-fixture-channel';
|
|
10
|
-
import { Color } from '../models/color';
|
|
11
|
-
import { Fixture } from '../models/fixture';
|
|
12
|
-
import { FixtureProfile } from '../models/fixture-profile';
|
|
13
|
-
import { FixtureWheelSlotType } from '../models/fixture-wheel-slot';
|
|
14
|
-
import { ProjectService } from './project.service';
|
|
15
|
-
import { UuidService } from './uuid.service';
|
|
16
|
-
import * as i0 from "@angular/core";
|
|
17
|
-
import * as i1 from "@angular/common/http";
|
|
18
|
-
import * as i2 from "./project.service";
|
|
19
|
-
import * as i3 from "@ngx-translate/core";
|
|
20
|
-
import * as i4 from "ngx-toastr";
|
|
21
|
-
import * as i5 from "./uuid.service";
|
|
22
|
-
export class FixtureService {
|
|
23
|
-
constructor(http, projectService, translateService, toastrService, uuidService) {
|
|
24
|
-
this.http = http;
|
|
25
|
-
this.projectService = projectService;
|
|
26
|
-
this.translateService = translateService;
|
|
27
|
-
this.toastrService = toastrService;
|
|
28
|
-
this.uuidService = uuidService;
|
|
29
|
-
this.cachedFixtures = [];
|
|
30
|
-
// is the side-tab settings currently selected?
|
|
31
|
-
this.settingsSelection = false;
|
|
32
|
-
this.selectedSettingsFixtures = [];
|
|
33
|
-
}
|
|
34
|
-
getFixtureByUuid(uuid) {
|
|
35
|
-
for (const fixture of this.projectService.project.fixtures) {
|
|
36
|
-
if (fixture.uuid === uuid) {
|
|
37
|
-
return fixture;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
fixtureUuidAndPixelKeyEquals(fixtureUuid1, fixtureUuid2, pixelKey1, pixelKey2) {
|
|
42
|
-
return fixtureUuid1 === fixtureUuid2 && ((pixelKey1 == null && pixelKey2 == null) || pixelKey1 === pixelKey2);
|
|
43
|
-
}
|
|
44
|
-
getCachedFixtureByUuid(uuid, pixelKey) {
|
|
45
|
-
for (const fixture of this.cachedFixtures) {
|
|
46
|
-
if (this.fixtureUuidAndPixelKeyEquals(fixture.fixture.uuid, uuid, fixture.pixelKey, pixelKey)) {
|
|
47
|
-
return fixture;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
// not yet found -> try searching the fixture without pixelKey for the general channels
|
|
51
|
-
if (pixelKey) {
|
|
52
|
-
return undefined;
|
|
53
|
-
}
|
|
54
|
-
for (const fixture of this.cachedFixtures) {
|
|
55
|
-
if (!fixture.pixelKey && fixture.fixture.uuid === uuid) {
|
|
56
|
-
return fixture;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
// Get all profiles to search for (only metadata)
|
|
61
|
-
getSearchProfiles() {
|
|
62
|
-
return this.http.get('fixtures').pipe(map((response) => {
|
|
63
|
-
const searchProfiles = [];
|
|
64
|
-
for (const profile of response) {
|
|
65
|
-
searchProfiles.push(new FixtureProfile(profile));
|
|
66
|
-
}
|
|
67
|
-
return searchProfiles;
|
|
68
|
-
}));
|
|
69
|
-
}
|
|
70
|
-
getProfileByUuid(uuid) {
|
|
71
|
-
for (const fixtureProfile of this.projectService.project.fixtureProfiles) {
|
|
72
|
-
if (fixtureProfile.uuid === uuid) {
|
|
73
|
-
return fixtureProfile;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
loadProfileByUuid(uuid) {
|
|
78
|
-
const loadedProfile = this.getProfileByUuid(uuid);
|
|
79
|
-
if (loadedProfile) {
|
|
80
|
-
// This profile is already loaded
|
|
81
|
-
return of(undefined);
|
|
82
|
-
}
|
|
83
|
-
// Load the metadata and the profile
|
|
84
|
-
return forkJoin([this.http.get('fixtures?uuid=' + encodeURI(uuid)), this.http.get('fixture?uuid=' + encodeURI(uuid))]).pipe(map((result) => {
|
|
85
|
-
const mergedData = { ...result[0][0], ...result[1] };
|
|
86
|
-
const fixtureProfile = new FixtureProfile(mergedData);
|
|
87
|
-
this.projectService.project.fixtureProfiles.push(fixtureProfile);
|
|
88
|
-
}));
|
|
89
|
-
}
|
|
90
|
-
getRotationAngleDeg(value) {
|
|
91
|
-
// convert a rotation angle value into degrees
|
|
92
|
-
if (value.endsWith('deg')) {
|
|
93
|
-
return Number.parseInt(value.replace('deg', ''), 10);
|
|
94
|
-
}
|
|
95
|
-
else if (value.endsWith('%')) {
|
|
96
|
-
const perc = Number.parseInt(value.replace('%', ''), 10);
|
|
97
|
-
return (perc / 100) * 360;
|
|
98
|
-
}
|
|
99
|
-
return undefined;
|
|
100
|
-
}
|
|
101
|
-
getWheelSlotColors(wheel, slotNumber) {
|
|
102
|
-
let colors = [];
|
|
103
|
-
const wheelSlots = this.getWheelSlots(wheel, slotNumber);
|
|
104
|
-
for (const slot of wheelSlots) {
|
|
105
|
-
if (slot.colors && slot.colors.length > 0) {
|
|
106
|
-
colors = colors.concat(slot.colors);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
return colors;
|
|
110
|
-
}
|
|
111
|
-
getMixedWheelSlotColor(wheel, slotNumber) {
|
|
112
|
-
const colors = this.getWheelSlotColors(wheel, slotNumber);
|
|
113
|
-
const colorsRgb = [];
|
|
114
|
-
if (colors.length === 0) {
|
|
115
|
-
return undefined;
|
|
116
|
-
}
|
|
117
|
-
for (const color of colors) {
|
|
118
|
-
colorsRgb.push(this.hexToRgb(color));
|
|
119
|
-
}
|
|
120
|
-
return this.mixColors(colorsRgb);
|
|
121
|
-
}
|
|
122
|
-
componentToHex(c) {
|
|
123
|
-
const hex = c.toString(16);
|
|
124
|
-
return hex.length === 1 ? '0' + hex : hex;
|
|
125
|
-
}
|
|
126
|
-
rgbToHex(r, g, b) {
|
|
127
|
-
return '#' + this.componentToHex(r) + this.componentToHex(g) + this.componentToHex(b);
|
|
128
|
-
}
|
|
129
|
-
hexToRgb(hex) {
|
|
130
|
-
// expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
|
|
131
|
-
const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
|
|
132
|
-
hex = hex.replace(shorthandRegex, (m, r, g, b) => {
|
|
133
|
-
return r + r + g + g + b + b;
|
|
134
|
-
});
|
|
135
|
-
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
136
|
-
return result ? new Color(parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)) : null;
|
|
137
|
-
}
|
|
138
|
-
mixColors(colors) {
|
|
139
|
-
// mix an array of rgb-colors containing r, g, b values to a new color
|
|
140
|
-
let r = 0;
|
|
141
|
-
let g = 0;
|
|
142
|
-
let b = 0;
|
|
143
|
-
for (const color of colors) {
|
|
144
|
-
r += color.red;
|
|
145
|
-
g += color.green;
|
|
146
|
-
b += color.blue;
|
|
147
|
-
}
|
|
148
|
-
r /= colors.length;
|
|
149
|
-
g /= colors.length;
|
|
150
|
-
b /= colors.length;
|
|
151
|
-
return new Color(r, g, b);
|
|
152
|
-
}
|
|
153
|
-
wheelHasSlotType(wheel, slotType) {
|
|
154
|
-
for (const slot of wheel.slots) {
|
|
155
|
-
if (slot.type === slotType) {
|
|
156
|
-
return true;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
return false;
|
|
160
|
-
}
|
|
161
|
-
getWheelByName(profile, wheelName) {
|
|
162
|
-
for (const property in profile.wheels) {
|
|
163
|
-
if (property === wheelName) {
|
|
164
|
-
return profile.wheels[property];
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
// wheel not found
|
|
168
|
-
return undefined;
|
|
169
|
-
}
|
|
170
|
-
getWheelSlots(wheel, slotNumber) {
|
|
171
|
-
// return one slot or two slots, if they are mixed (e.g. slor number 2.5 returns the slots 2 and 3)
|
|
172
|
-
const slots = [];
|
|
173
|
-
if (!wheel) {
|
|
174
|
-
return slots;
|
|
175
|
-
}
|
|
176
|
-
if (slotNumber - Math.floor(slotNumber) > 0) {
|
|
177
|
-
// two slots are set
|
|
178
|
-
const number = Math.floor(slotNumber);
|
|
179
|
-
slots.push(wheel.slots[number - 1]);
|
|
180
|
-
if (number >= 0 && number < wheel.slots.length) {
|
|
181
|
-
slots.push(wheel.slots[number]);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
else {
|
|
185
|
-
// only one slot is set
|
|
186
|
-
slots.push(wheel.slots[slotNumber - 1]);
|
|
187
|
-
}
|
|
188
|
-
return slots;
|
|
189
|
-
}
|
|
190
|
-
getModeByFixture(profile, fixture) {
|
|
191
|
-
for (const mode of profile.modes) {
|
|
192
|
-
if (mode.shortName) {
|
|
193
|
-
if (mode.shortName === fixture.modeShortName) {
|
|
194
|
-
return mode;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
else {
|
|
198
|
-
if (mode.name === fixture.modeShortName) {
|
|
199
|
-
return mode;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
getFixtureCapability(capability, channelName, profile) {
|
|
205
|
-
const cachedFixtureCapability = new CachedFixtureCapability();
|
|
206
|
-
cachedFixtureCapability.capability = capability;
|
|
207
|
-
if (capability.slotNumber) {
|
|
208
|
-
// there is a wheel connected to this capability
|
|
209
|
-
if (typeof capability.wheel === 'string') {
|
|
210
|
-
cachedFixtureCapability.wheelName = capability.wheel;
|
|
211
|
-
}
|
|
212
|
-
else if (Array.isArray(capability.wheel)) {
|
|
213
|
-
cachedFixtureCapability.wheelName = capability.wheel[0];
|
|
214
|
-
}
|
|
215
|
-
else {
|
|
216
|
-
cachedFixtureCapability.wheelName = channelName;
|
|
217
|
-
}
|
|
218
|
-
cachedFixtureCapability.wheel = this.getWheelByName(profile, cachedFixtureCapability.wheelName);
|
|
219
|
-
cachedFixtureCapability.wheelSlots = this.getWheelSlots(cachedFixtureCapability.wheel, capability.slotNumber);
|
|
220
|
-
cachedFixtureCapability.wheelIsColor = this.wheelHasSlotType(cachedFixtureCapability.wheel, FixtureWheelSlotType.Color);
|
|
221
|
-
}
|
|
222
|
-
if (cachedFixtureCapability.capability.dmxRange && cachedFixtureCapability.capability.dmxRange.length === 2) {
|
|
223
|
-
cachedFixtureCapability.centerValue = Math.floor((cachedFixtureCapability.capability.dmxRange[0] + cachedFixtureCapability.capability.dmxRange[1]) / 2);
|
|
224
|
-
}
|
|
225
|
-
return cachedFixtureCapability;
|
|
226
|
-
}
|
|
227
|
-
getCapabilitiesByChannel(fixtureChannel, channelName, profile) {
|
|
228
|
-
const capabilites = [];
|
|
229
|
-
if (fixtureChannel.capability) {
|
|
230
|
-
capabilites.push(this.getFixtureCapability(fixtureChannel.capability, channelName, profile));
|
|
231
|
-
}
|
|
232
|
-
else if (fixtureChannel.capabilities) {
|
|
233
|
-
for (const capability of fixtureChannel.capabilities) {
|
|
234
|
-
capabilites.push(this.getFixtureCapability(capability, channelName, profile));
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
return capabilites;
|
|
238
|
-
}
|
|
239
|
-
getMaxValueByChannel(fixtureChannel) {
|
|
240
|
-
return Math.pow(256, 1 + fixtureChannel.fineChannelAliases.length) - 1;
|
|
241
|
-
}
|
|
242
|
-
getDefaultValueByChannel(fixtureChannel) {
|
|
243
|
-
if (!fixtureChannel.defaultValue) {
|
|
244
|
-
return undefined;
|
|
245
|
-
}
|
|
246
|
-
if (isNaN(fixtureChannel.defaultValue) && fixtureChannel.defaultValue.endsWith('%')) {
|
|
247
|
-
// percentage value
|
|
248
|
-
const percentage = Number.parseInt(fixtureChannel.defaultValue.replace('%', ''), 10);
|
|
249
|
-
const maxValue = this.getMaxValueByChannel(fixtureChannel);
|
|
250
|
-
return (maxValue / 100) * percentage;
|
|
251
|
-
}
|
|
252
|
-
else {
|
|
253
|
-
// DMX value
|
|
254
|
-
return Number.parseInt(fixtureChannel.defaultValue, 10);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
getColorWheelByChannel(channel, profile) {
|
|
258
|
-
for (const channelCapability of channel.capabilities) {
|
|
259
|
-
if (channelCapability.wheelIsColor) {
|
|
260
|
-
return channelCapability.wheel;
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
return undefined;
|
|
264
|
-
}
|
|
265
|
-
getChannelByName(fixture, channelName) {
|
|
266
|
-
for (const channel of fixture.channels) {
|
|
267
|
-
if ((channel.name && channel.name === channelName) ||
|
|
268
|
-
(channel.channel && channel.channel.fineChannelAliases.indexOf(channelName) > -1)) {
|
|
269
|
-
return channel;
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
return undefined;
|
|
273
|
-
}
|
|
274
|
-
getChannelNameWithPixelKey(templateChannelName, pixelKey) {
|
|
275
|
-
return templateChannelName.replace('$pixelKey', pixelKey);
|
|
276
|
-
}
|
|
277
|
-
addCachedChannel(channels, channel, templateChannelName, pixelKey, profile) {
|
|
278
|
-
const cachedFixtureChannel = new CachedFixtureChannel();
|
|
279
|
-
const channelName = this.getChannelNameWithPixelKey(templateChannelName, pixelKey);
|
|
280
|
-
cachedFixtureChannel.channel = channel;
|
|
281
|
-
cachedFixtureChannel.name = channelName;
|
|
282
|
-
cachedFixtureChannel.capabilities = this.getCapabilitiesByChannel(cachedFixtureChannel.channel, channelName, profile);
|
|
283
|
-
const defaultValue = this.getDefaultValueByChannel(cachedFixtureChannel.channel);
|
|
284
|
-
if (defaultValue) {
|
|
285
|
-
cachedFixtureChannel.defaultValue = defaultValue;
|
|
286
|
-
}
|
|
287
|
-
cachedFixtureChannel.maxValue = this.getMaxValueByChannel(cachedFixtureChannel.channel);
|
|
288
|
-
cachedFixtureChannel.colorWheel = this.getColorWheelByChannel(cachedFixtureChannel, profile);
|
|
289
|
-
channels.push(cachedFixtureChannel);
|
|
290
|
-
}
|
|
291
|
-
alphanumericSort(a, b) {
|
|
292
|
-
return a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' });
|
|
293
|
-
}
|
|
294
|
-
getAllPixelKeys(profile) {
|
|
295
|
-
let result = [];
|
|
296
|
-
for (let pixelKeyX of profile.matrix.pixelKeys) {
|
|
297
|
-
for (let pixelKeyY of pixelKeyX) {
|
|
298
|
-
for (let pixelKeyZ of pixelKeyY) {
|
|
299
|
-
if (pixelKeyZ) {
|
|
300
|
-
result.push(pixelKeyZ);
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
return result;
|
|
306
|
-
}
|
|
307
|
-
getAllPixelGroups(profile) {
|
|
308
|
-
let result = [];
|
|
309
|
-
for (const property of Object.keys(profile.matrix.pixelGroups)) {
|
|
310
|
-
result.push(property);
|
|
311
|
-
}
|
|
312
|
-
return result;
|
|
313
|
-
}
|
|
314
|
-
getPixelKeysInOrder(profile, repeatFor) {
|
|
315
|
-
let result = [];
|
|
316
|
-
// could contain just a single string (e.g. 'eachPixelABC') or
|
|
317
|
-
if (repeatFor.length > 1) {
|
|
318
|
-
// an array of pixel (groups)
|
|
319
|
-
result = repeatFor;
|
|
320
|
-
}
|
|
321
|
-
else if (repeatFor.length === 0) {
|
|
322
|
-
return result;
|
|
323
|
-
}
|
|
324
|
-
else if (repeatFor[0] === 'eachPixelABC') {
|
|
325
|
-
// Gets computed into an alphanumerically sorted list of all pixelKeys
|
|
326
|
-
if (profile.matrix.pixelCount.length === 3) {
|
|
327
|
-
for (let x = 0; x < profile.matrix.pixelCount[0]; x++) {
|
|
328
|
-
for (let y = 0; y < profile.matrix.pixelCount[1]; y++) {
|
|
329
|
-
for (let z = 0; z < profile.matrix.pixelCount[2]; z++) {
|
|
330
|
-
result.push('Pixel ' + (x + 1) + '-' + (y + 1) + '-' + (z + 1));
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
else {
|
|
336
|
-
result = result.concat(this.getAllPixelKeys(profile));
|
|
337
|
-
}
|
|
338
|
-
result.sort(this.alphanumericSort);
|
|
339
|
-
}
|
|
340
|
-
else if (repeatFor[0] === 'eachPixelGroup') {
|
|
341
|
-
// Gets computed into an array of all pixel group keys, ordered by appearance in the JSON file
|
|
342
|
-
result = result.concat(this.getAllPixelGroups(profile));
|
|
343
|
-
}
|
|
344
|
-
else if (repeatFor[0] === 'eachPixelXYZ') {
|
|
345
|
-
for (let x = 0; x < profile.matrix.pixelKeys.length; x++) {
|
|
346
|
-
for (let y = 0; y < profile.matrix.pixelKeys[x].length; y++) {
|
|
347
|
-
for (let z = 0; z < profile.matrix.pixelKeys[x][y].length; z++) {
|
|
348
|
-
const pixel = profile.matrix.pixelKeys[x][y][z];
|
|
349
|
-
if (pixel) {
|
|
350
|
-
result.push(pixel);
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
else if (repeatFor[0] === 'eachPixelXZY') {
|
|
357
|
-
for (let x = 0; x < profile.matrix.pixelKeys.length; x++) {
|
|
358
|
-
for (let z = 0; z < profile.matrix.pixelKeys[x][0].length; z++) {
|
|
359
|
-
for (let y = 0; y < profile.matrix.pixelKeys[x].length; y++) {
|
|
360
|
-
const pixel = profile.matrix.pixelKeys[x][y][z];
|
|
361
|
-
if (pixel) {
|
|
362
|
-
result.push(pixel);
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
else if (repeatFor[0] === 'eachPixelYXZ') {
|
|
369
|
-
for (let y = 0; y < profile.matrix.pixelKeys[0].length; y++) {
|
|
370
|
-
for (let x = 0; x < profile.matrix.pixelKeys.length; x++) {
|
|
371
|
-
for (let z = 0; z < profile.matrix.pixelKeys[x][y].length; z++) {
|
|
372
|
-
const pixel = profile.matrix.pixelKeys[x][y][z];
|
|
373
|
-
if (pixel) {
|
|
374
|
-
result.push(pixel);
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
else if (repeatFor[0] === 'eachPixelYZX') {
|
|
381
|
-
for (let y = 0; y < profile.matrix.pixelKeys[0].length; y++) {
|
|
382
|
-
for (let z = 0; z < profile.matrix.pixelKeys[0][y].length; z++) {
|
|
383
|
-
for (let x = 0; x < profile.matrix.pixelKeys.length; x++) {
|
|
384
|
-
const pixel = profile.matrix.pixelKeys[x][y][z];
|
|
385
|
-
if (pixel) {
|
|
386
|
-
result.push(pixel);
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
else if (repeatFor[0] === 'eachPixelZXY') {
|
|
393
|
-
for (let z = 0; z < profile.matrix.pixelKeys[0][0].length; z++) {
|
|
394
|
-
for (let x = 0; x < profile.matrix.pixelKeys.length; x++) {
|
|
395
|
-
for (let y = 0; y < profile.matrix.pixelKeys[x].length; y++) {
|
|
396
|
-
const pixel = profile.matrix.pixelKeys[x][y][z];
|
|
397
|
-
if (pixel) {
|
|
398
|
-
result.push(pixel);
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
else if (repeatFor[0] === 'eachPixelZYX') {
|
|
405
|
-
for (let z = 0; z < profile.matrix.pixelKeys[0][0].length; z++) {
|
|
406
|
-
for (let y = 0; y < profile.matrix.pixelKeys[0].length; y++) {
|
|
407
|
-
for (let x = 0; x < profile.matrix.pixelKeys.length; x++) {
|
|
408
|
-
const pixel = profile.matrix.pixelKeys[x][y][z];
|
|
409
|
-
if (pixel) {
|
|
410
|
-
result.push(pixel);
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
return result;
|
|
417
|
-
}
|
|
418
|
-
getModeChannelCount(profile, mode) {
|
|
419
|
-
let count = 0;
|
|
420
|
-
// already calculated?
|
|
421
|
-
if (mode.channelCount) {
|
|
422
|
-
return mode.channelCount;
|
|
423
|
-
}
|
|
424
|
-
for (let channel of mode.channels) {
|
|
425
|
-
if (channel.insert === 'matrixChannels') {
|
|
426
|
-
if (channel.repeatFor.length > 1) {
|
|
427
|
-
count += channel.repeatFor.length * channel.templateChannels.length;
|
|
428
|
-
}
|
|
429
|
-
else if (channel.repeatFor[0] === 'eachPixelGroup') {
|
|
430
|
-
count += profile.matrix.pixelGroups.length * channel.templateChannels.length;
|
|
431
|
-
}
|
|
432
|
-
else if (channel.repeatFor[0].startsWith('eachPixel')) {
|
|
433
|
-
if (profile.matrix.pixelCount.length === 3) {
|
|
434
|
-
count +=
|
|
435
|
-
profile.matrix.pixelCount[0] * profile.matrix.pixelCount[1] * profile.matrix.pixelCount[2] * channel.templateChannels.length;
|
|
436
|
-
}
|
|
437
|
-
else {
|
|
438
|
-
for (let x = 0; x < profile.matrix.pixelKeys.length; x++) {
|
|
439
|
-
for (let y = 0; y < profile.matrix.pixelKeys[x].length; y++) {
|
|
440
|
-
for (let z = 0; z < profile.matrix.pixelKeys[x][y].length; z++) {
|
|
441
|
-
const pixel = profile.matrix.pixelKeys[x][y][z];
|
|
442
|
-
if (pixel) {
|
|
443
|
-
count += channel.templateChannels.length;
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
else {
|
|
452
|
-
count++;
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
mode.channelCount = count;
|
|
456
|
-
return mode.channelCount;
|
|
457
|
-
}
|
|
458
|
-
getCachedChannels(profile, mode, pixelKey) {
|
|
459
|
-
const channels = [];
|
|
460
|
-
if (!mode) {
|
|
461
|
-
return channels;
|
|
462
|
-
}
|
|
463
|
-
for (const channel of mode.channels) {
|
|
464
|
-
if (channel.name && !pixelKey) {
|
|
465
|
-
// direct reference to a channel
|
|
466
|
-
// don't check the fine channels. only add the coarse channel.
|
|
467
|
-
let channelFound = false;
|
|
468
|
-
for (const availableChannelName of Object.keys(profile.availableChannels)) {
|
|
469
|
-
if (channel.name === availableChannelName) {
|
|
470
|
-
const availableChannel = profile.availableChannels[availableChannelName];
|
|
471
|
-
this.addCachedChannel(channels, availableChannel, availableChannelName, null, profile);
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
// check the template channels, if not found in the available channels
|
|
475
|
-
if (!channelFound) {
|
|
476
|
-
for (const templateChannelName of Object.keys(profile.templateChannels)) {
|
|
477
|
-
let existingPixelKeys = this.getAllPixelKeys(profile).concat(this.getAllPixelGroups(profile));
|
|
478
|
-
for (const existingPixelKey of existingPixelKeys) {
|
|
479
|
-
const channelName = this.getChannelNameWithPixelKey(templateChannelName, existingPixelKey);
|
|
480
|
-
if (channel.name === channelName) {
|
|
481
|
-
const templateChannel = profile.templateChannels[templateChannelName];
|
|
482
|
-
this.addCachedChannel(channels, templateChannel, channelName, existingPixelKey, profile);
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
else {
|
|
489
|
-
// reference a channel through a pixel matrix
|
|
490
|
-
const availablePixelKeys = this.getPixelKeysInOrder(profile, channel.repeatFor);
|
|
491
|
-
if (channel.channelOrder === 'perPixel') {
|
|
492
|
-
// each channel for each pixel
|
|
493
|
-
for (const availablePixelKey of availablePixelKeys) {
|
|
494
|
-
if (availablePixelKey === pixelKey) {
|
|
495
|
-
for (const modeTemplateChannelName of channel.templateChannels) {
|
|
496
|
-
for (const templateChannelName of Object.keys(profile.templateChannels)) {
|
|
497
|
-
// don't check the fine channels. only add the coarse channel.
|
|
498
|
-
if (modeTemplateChannelName === templateChannelName) {
|
|
499
|
-
const templateChannel = profile.templateChannels[templateChannelName];
|
|
500
|
-
this.addCachedChannel(channels, templateChannel, templateChannelName, availablePixelKey, profile);
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
else if (channel.channelOrder === 'perChannel') {
|
|
508
|
-
// each pixel for each channel
|
|
509
|
-
for (const modeTemplateChannelName of channel.templateChannels) {
|
|
510
|
-
for (const availablePixelKey of availablePixelKeys) {
|
|
511
|
-
if (availablePixelKey === pixelKey) {
|
|
512
|
-
for (const templateChannelName of Object.keys(profile.templateChannels)) {
|
|
513
|
-
// don't check the fine channels. only add the coarse channel.
|
|
514
|
-
if (modeTemplateChannelName === templateChannelName) {
|
|
515
|
-
const templateChannel = profile.templateChannels[templateChannelName];
|
|
516
|
-
this.addCachedChannel(channels, templateChannel, templateChannelName, availablePixelKey, profile);
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
return channels;
|
|
526
|
-
}
|
|
527
|
-
fixtureGetUniquePixelKeys(fixture) {
|
|
528
|
-
let pixelKeys = new Set();
|
|
529
|
-
let profile = this.getProfileByUuid(fixture.profileUuid);
|
|
530
|
-
let mode = this.getModeByFixture(profile, fixture);
|
|
531
|
-
// add the unique pixel keys
|
|
532
|
-
for (let channel of mode.channels) {
|
|
533
|
-
this.getPixelKeysInOrder(profile, channel.repeatFor).forEach((str) => {
|
|
534
|
-
pixelKeys.add(str);
|
|
535
|
-
});
|
|
536
|
-
}
|
|
537
|
-
return Array.from(pixelKeys);
|
|
538
|
-
}
|
|
539
|
-
// does the fixture have a general channel without reference to specific pixel keys in the current mode?
|
|
540
|
-
fixtureHasGeneralChannel(fixture) {
|
|
541
|
-
let profile = this.getProfileByUuid(fixture.profileUuid);
|
|
542
|
-
let mode = this.getModeByFixture(profile, fixture);
|
|
543
|
-
// add the unique pixel keys
|
|
544
|
-
for (let channel of mode.channels) {
|
|
545
|
-
if (this.getPixelKeysInOrder(profile, channel.repeatFor).length === 0) {
|
|
546
|
-
return true;
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
return false;
|
|
550
|
-
}
|
|
551
|
-
updateCachedFixtures() {
|
|
552
|
-
// calculate some frequently used values as a cache to save cpu time
|
|
553
|
-
// afterwards
|
|
554
|
-
this.cachedFixtures = [];
|
|
555
|
-
for (const fixture of this.projectService.project.fixtures) {
|
|
556
|
-
if (this.fixtureHasGeneralChannel(fixture)) {
|
|
557
|
-
const cachedFixture = new CachedFixture();
|
|
558
|
-
cachedFixture.fixture = fixture;
|
|
559
|
-
cachedFixture.profile = this.getProfileByUuid(fixture.profileUuid);
|
|
560
|
-
cachedFixture.mode = this.getModeByFixture(cachedFixture.profile, fixture);
|
|
561
|
-
cachedFixture.channels = this.getCachedChannels(cachedFixture.profile, cachedFixture.mode, null);
|
|
562
|
-
this.cachedFixtures.push(cachedFixture);
|
|
563
|
-
}
|
|
564
|
-
const pixelKeys = this.fixtureGetUniquePixelKeys(fixture);
|
|
565
|
-
for (let pixelKey of pixelKeys) {
|
|
566
|
-
const cachedFixture = new CachedFixture();
|
|
567
|
-
cachedFixture.fixture = fixture;
|
|
568
|
-
cachedFixture.pixelKey = pixelKey;
|
|
569
|
-
cachedFixture.profile = this.getProfileByUuid(fixture.profileUuid);
|
|
570
|
-
cachedFixture.mode = this.getModeByFixture(cachedFixture.profile, fixture);
|
|
571
|
-
cachedFixture.channels = this.getCachedChannels(cachedFixture.profile, cachedFixture.mode, pixelKey);
|
|
572
|
-
this.cachedFixtures.push(cachedFixture);
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
capabilitiesMatch(type1, type2, color1, color2, wheel1, wheel2, profileUuid1, profileUuid2) {
|
|
577
|
-
// checks, whether two provided capapabilities match
|
|
578
|
-
return (type1 === type2 &&
|
|
579
|
-
(!color1 || color1 === color2) &&
|
|
580
|
-
(!wheel1 || wheel1 === wheel2) &&
|
|
581
|
-
(!profileUuid1 || profileUuid1 === profileUuid2));
|
|
582
|
-
}
|
|
583
|
-
settingsFixtureIsSelected(fixture) {
|
|
584
|
-
for (const selectedFixture of this.selectedSettingsFixtures) {
|
|
585
|
-
if (selectedFixture === fixture) {
|
|
586
|
-
return true;
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
|
-
return false;
|
|
590
|
-
}
|
|
591
|
-
switchSettingsFixtureSelection(fixture) {
|
|
592
|
-
if (this.settingsFixtureIsSelected(fixture)) {
|
|
593
|
-
this.selectedSettingsFixtures.splice(this.selectedSettingsFixtures.indexOf(fixture), 1);
|
|
594
|
-
}
|
|
595
|
-
else {
|
|
596
|
-
this.selectedSettingsFixtures.push(fixture);
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
getFixtureIconClass(profile) {
|
|
600
|
-
if (!profile) {
|
|
601
|
-
return '';
|
|
602
|
-
}
|
|
603
|
-
if (profile.categories.length === 0) {
|
|
604
|
-
return '';
|
|
605
|
-
}
|
|
606
|
-
if (!profile.categories[0]) {
|
|
607
|
-
return '';
|
|
608
|
-
}
|
|
609
|
-
return profile.categories[0].replace(' ', '-').toLocaleLowerCase();
|
|
610
|
-
}
|
|
611
|
-
updateProfiles() {
|
|
612
|
-
return this.http.post('update-profiles', null);
|
|
613
|
-
}
|
|
614
|
-
getNextFreeDmxChannel(fixturePool, neededChannels) {
|
|
615
|
-
// get the next free space for this fixture
|
|
616
|
-
let freeChannels = 0;
|
|
617
|
-
for (let i = 0; i < 512; i++) {
|
|
618
|
-
let occupiedChannels = 0;
|
|
619
|
-
for (const fixture of fixturePool) {
|
|
620
|
-
const profile = this.getProfileByUuid(fixture.profileUuid);
|
|
621
|
-
const mode = this.getModeByFixture(this.getProfileByUuid(fixture.profileUuid), fixture);
|
|
622
|
-
const channelCount = this.getModeChannelCount(profile, mode);
|
|
623
|
-
if (i >= fixture.dmxFirstChannel && i < fixture.dmxFirstChannel + channelCount) {
|
|
624
|
-
// this channel is already occupied by a fixture -> move forward to the end of the fixture
|
|
625
|
-
if (channelCount > occupiedChannels) {
|
|
626
|
-
occupiedChannels = channelCount - (i - fixture.dmxFirstChannel);
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
}
|
|
630
|
-
if (occupiedChannels > 0) {
|
|
631
|
-
i += occupiedChannels - 1;
|
|
632
|
-
freeChannels = 0;
|
|
633
|
-
}
|
|
634
|
-
else {
|
|
635
|
-
freeChannels++;
|
|
636
|
-
}
|
|
637
|
-
if (freeChannels === neededChannels) {
|
|
638
|
-
return i - freeChannels + 1;
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
// no free space left for the needed channels
|
|
642
|
-
return -1;
|
|
643
|
-
}
|
|
644
|
-
addFixture(profile, fixturePool) {
|
|
645
|
-
const fixture = new Fixture();
|
|
646
|
-
fixture.uuid = this.uuidService.getUuid();
|
|
647
|
-
fixture.profileUuid = profile.uuid;
|
|
648
|
-
fixture.name = profile.name;
|
|
649
|
-
if (profile.modes && profile.modes.length > 0) {
|
|
650
|
-
fixture.modeShortName = profile.modes[0].shortName;
|
|
651
|
-
}
|
|
652
|
-
// add the same mode as an existing fixture, if available
|
|
653
|
-
let existingModeShortName;
|
|
654
|
-
for (const existingFixture of fixturePool) {
|
|
655
|
-
const existingProfile = this.getProfileByUuid(existingFixture.profileUuid);
|
|
656
|
-
if (existingProfile === profile) {
|
|
657
|
-
existingModeShortName = existingFixture.modeShortName;
|
|
658
|
-
break;
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
if (existingModeShortName) {
|
|
662
|
-
fixture.modeShortName = existingModeShortName;
|
|
663
|
-
}
|
|
664
|
-
else {
|
|
665
|
-
fixture.modeShortName = profile.modes[0].shortName || profile.modes[0].name;
|
|
666
|
-
}
|
|
667
|
-
const mode = this.getModeByFixture(profile, fixture);
|
|
668
|
-
const channelCount = this.getModeChannelCount(profile, mode);
|
|
669
|
-
const firstChannel = this.getNextFreeDmxChannel(fixturePool, channelCount);
|
|
670
|
-
if (firstChannel >= 0) {
|
|
671
|
-
fixture.dmxFirstChannel = firstChannel;
|
|
672
|
-
fixturePool.push(fixture);
|
|
673
|
-
return fixture;
|
|
674
|
-
}
|
|
675
|
-
else {
|
|
676
|
-
// no free space anymore
|
|
677
|
-
const msg = 'designer.fixture-pool.no-free-space';
|
|
678
|
-
const title = 'designer.fixture-pool.no-free-space-title';
|
|
679
|
-
this.translateService.get([msg, title]).subscribe((result) => {
|
|
680
|
-
this.toastrService.error(result[msg], result[title]);
|
|
681
|
-
});
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
static { this.ɵfac = function FixtureService_Factory(t) { return new (t || FixtureService)(i0.ɵɵinject(i1.HttpClient), i0.ɵɵinject(i2.ProjectService), i0.ɵɵinject(i3.TranslateService), i0.ɵɵinject(i4.ToastrService), i0.ɵɵinject(i5.UuidService)); }; }
|
|
685
|
-
static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: FixtureService, factory: FixtureService.ɵfac, providedIn: 'root' }); }
|
|
686
|
-
}
|
|
687
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(FixtureService, [{
|
|
688
|
-
type: Injectable,
|
|
689
|
-
args: [{
|
|
690
|
-
providedIn: 'root',
|
|
691
|
-
}]
|
|
692
|
-
}], () => [{ type: i1.HttpClient }, { type: i2.ProjectService }, { type: i3.TranslateService }, { type: i4.ToastrService }, { type: i5.UuidService }], null); })();
|
|
693
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZml4dHVyZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZGVzaWduZXIvc3JjL2xpYi9zZXJ2aWNlcy9maXh0dXJlLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdkQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUMzQyxPQUFPLEVBQUUsUUFBUSxFQUFjLEVBQUUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNoRCxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDckMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3pELE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQzlFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQ3hFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN4QyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFJNUMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRTNELE9BQU8sRUFBb0Isb0JBQW9CLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUN0RixPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDbkQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7Ozs7O0FBSzdDLE1BQU0sT0FBTyxjQUFjO0lBUXpCLFlBQ1UsSUFBZ0IsRUFDaEIsY0FBOEIsRUFDOUIsZ0JBQWtDLEVBQ2xDLGFBQTRC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QUM7WUFDMUIsT0FBTyxPQUFPLENBQUM7UUFDakIsQ0FBQzthQUFNLENBQUM7WUFDTix3QkFBd0I7WUFDeEIsTUFBTSxHQUFHLEdBQUcscUNBQXFDLENBQUM7WUFDbEQsTUFBTSxLQUFLLEdBQUcsMkNBQTJDLENBQUM7WUFFMUQsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFO2dCQUMzRCxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDdkQsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDO0lBQ0gsQ0FBQzsrRUF6d0JVLGNBQWM7dUVBQWQsY0FBYyxXQUFkLGNBQWMsbUJBRmIsTUFBTTs7aUZBRVAsY0FBYztjQUgxQixVQUFVO2VBQUM7Z0JBQ1YsVUFBVSxFQUFFLE1BQU07YUFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHsgVG9hc3RyU2VydmljZSB9IGZyb20gJ25neC10b2FzdHInO1xuaW1wb3J0IHsgZm9ya0pvaW4sIE9ic2VydmFibGUsIG9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBtYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBDYWNoZWRGaXh0dXJlIH0gZnJvbSAnLi4vbW9kZWxzL2NhY2hlZC1maXh0dXJlJztcbmltcG9ydCB7IENhY2hlZEZpeHR1cmVDYXBhYmlsaXR5IH0gZnJvbSAnLi4vbW9kZWxzL2NhY2hlZC1maXh0dXJlLWNhcGFiaWxpdHknO1xuaW1wb3J0IHsgQ2FjaGVkRml4dHVyZUNoYW5uZWwgfSBmcm9tICcuLi9tb2RlbHMvY2FjaGVkLWZpeHR1cmUtY2hhbm5lbCc7XG5pbXBvcnQgeyBDb2xvciB9IGZyb20gJy4uL21vZGVscy9jb2xvcic7XG5pbXBvcnQgeyBGaXh0dXJlIH0gZnJvbSAnLi4vbW9kZWxzL2ZpeHR1cmUnO1xuaW1wb3J0IHsgRml4dHVyZUNhcGFiaWxpdHksIEZpeHR1cmVDYXBhYmlsaXR5Q29sb3IsIEZpeHR1cmVDYXBhYmlsaXR5VHlwZSB9IGZyb20gJy4uL21vZGVscy9maXh0dXJlLWNhcGFiaWxpdHknO1xuaW1wb3J0IHsgRml4dHVyZUNoYW5uZWwgfSBmcm9tICcuLi9tb2RlbHMvZml4dHVyZS1jaGFubmVsJztcbmltcG9ydCB7IEZpeHR1cmVNb2RlIH0gZnJvbSAnLi4vbW9kZWxzL2ZpeHR1cmUtbW9kZSc7XG5pbXBvcnQgeyBGaXh0dXJlUHJvZmlsZSB9IGZyb20gJy4uL21vZGVscy9maXh0dXJlLXByb2ZpbGUnO1xuaW1wb3J0IHsgRml4dHVyZVdoZWVsIH0gZnJvbSAnLi4vbW9kZWxzL2ZpeHR1cmUtd2hlZWwnO1xuaW1wb3J0IHsgRml4dHVyZVdoZWVsU2xvdCwgRml4dHVyZVdoZWVsU2xvdFR5cGUgfSBmcm9tICcuLi9tb2RlbHMvZml4dHVyZS13aGVlbC1zbG90JztcbmltcG9ydCB7IFByb2plY3RTZXJ2aWNlIH0gZnJvbSAnLi9wcm9qZWN0LnNlcnZpY2UnO1xuaW1wb3J0IHsgVXVpZFNlcnZpY2UgfSBmcm9tICcuL3V1aWQuc2VydmljZSc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBGaXh0dXJlU2VydmljZSB7XG4gIGNhY2hlZEZpeHR1cmVzOiBDYWNoZWRGaXh0dXJlW10gPSBbXTtcblxuICAvLyBpcyB0aGUgc2lkZS10YWIgc2V0dGluZ3MgY3VycmVudGx5IHNlbGVjdGVkP1xuICBzZXR0aW5nc1NlbGVjdGlvbiA9IGZhbHNlO1xuXG4gIHNlbGVjdGVkU2V0dGluZ3NGaXh0dXJlczogRml4dHVyZVtdID0gW107XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBodHRwOiBIdHRwQ2xpZW50LFxuICAgIHByaXZhdGUgcHJvamVjdFNlcnZpY2U6IFByb2plY3RTZXJ2aWNlLFxuICAgIHByaXZhdGUgdHJhbnNsYXRlU2VydmljZTogVHJhbnNsYXRlU2VydmljZSxcbiAgICBwcml2YXRlIHRvYXN0clNlcnZpY2U6IFRvYXN0clNlcnZpY2UsXG4gICAgcHJpdmF0ZSB1dWlkU2VydmljZTogVXVpZFNlcnZpY2VcbiAgKSB7fVxuXG4gIGdldEZpeHR1cmVCeVV1aWQodXVpZDogc3RyaW5nKTogRml4dHVyZSB7XG4gICAgZm9yIChjb25zdCBmaXh0dXJlIG9mIHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5maXh0dXJlcykge1xuICAgICAgaWYgKGZpeHR1cmUudXVpZCA9PT0gdXVpZCkge1xuICAgICAgICByZXR1cm4gZml4dHVyZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGZpeHR1cmVVdWlkQW5kUGl4ZWxLZXlFcXVhbHMoZml4dHVyZVV1aWQxOiBzdHJpbmcsIGZpeHR1cmVVdWlkMjogc3RyaW5nLCBwaXhlbEtleTE6IHN0cmluZywgcGl4ZWxLZXkyOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gZml4dHVyZVV1aWQxID09PSBmaXh0dXJlVXVpZDIgJiYgKChwaXhlbEtleTEgPT0gbnVsbCAmJiBwaXhlbEtleTIgPT0gbnVsbCkgfHwgcGl4ZWxLZXkxID09PSBwaXhlbEtleTIpO1xuICB9XG5cbiAgZ2V0Q2FjaGVkRml4dHVyZUJ5VXVpZCh1dWlkOiBzdHJpbmcsIHBpeGVsS2V5OiBzdHJpbmcpOiBDYWNoZWRGaXh0dXJlIHtcbiAgICBmb3IgKGNvbnN0IGZpeHR1cmUgb2YgdGhpcy5jYWNoZWRGaXh0dXJlcykge1xuICAgICAgaWYgKHRoaXMuZml4dHVyZVV1aWRBbmRQaXhlbEtleUVxdWFscyhmaXh0dXJlLmZpeHR1cmUudXVpZCwgdXVpZCwgZml4dHVyZS5waXhlbEtleSwgcGl4ZWxLZXkpKSB7XG4gICAgICAgIHJldHVybiBmaXh0dXJlO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIG5vdCB5ZXQgZm91bmQgLT4gdHJ5IHNlYXJjaGluZyB0aGUgZml4dHVyZSB3aXRob3V0IHBpeGVsS2V5IGZvciB0aGUgZ2VuZXJhbCBjaGFubmVsc1xuICAgIGlmIChwaXhlbEtleSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGZpeHR1cmUgb2YgdGhpcy5jYWNoZWRGaXh0dXJlcykge1xuICAgICAgaWYgKCFmaXh0dXJlLnBpeGVsS2V5ICYmIGZpeHR1cmUuZml4dHVyZS51dWlkID09PSB1dWlkKSB7XG4gICAgICAgIHJldHVybiBmaXh0dXJlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIEdldCBhbGwgcHJvZmlsZXMgdG8gc2VhcmNoIGZvciAob25seSBtZXRhZGF0YSlcbiAgZ2V0U2VhcmNoUHJvZmlsZXMoKTogT2JzZXJ2YWJsZTxGaXh0dXJlUHJvZmlsZVtdPiB7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQoJ2ZpeHR1cmVzJykucGlwZShcbiAgICAgIG1hcCgocmVzcG9uc2U6IG9iamVjdFtdKSA9PiB7XG4gICAgICAgIGNvbnN0IHNlYXJjaFByb2ZpbGVzOiBGaXh0dXJlUHJvZmlsZVtdID0gW107XG5cbiAgICAgICAgZm9yIChjb25zdCBwcm9maWxlIG9mIHJlc3BvbnNlKSB7XG4gICAgICAgICAgc2VhcmNoUHJvZmlsZXMucHVzaChuZXcgRml4dHVyZVByb2ZpbGUocHJvZmlsZSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHNlYXJjaFByb2ZpbGVzO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgZ2V0UHJvZmlsZUJ5VXVpZCh1dWlkOiBzdHJpbmcpOiBGaXh0dXJlUHJvZmlsZSB7XG4gICAgZm9yIChjb25zdCBmaXh0dXJlUHJvZmlsZSBvZiB0aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3QuZml4dHVyZVByb2ZpbGVzKSB7XG4gICAgICBpZiAoZml4dHVyZVByb2ZpbGUudXVpZCA9PT0gdXVpZCkge1xuICAgICAgICByZXR1cm4gZml4dHVyZVByb2ZpbGU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgbG9hZFByb2ZpbGVCeVV1aWQodXVpZDogc3RyaW5nKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgY29uc3QgbG9hZGVkUHJvZmlsZSA9IHRoaXMuZ2V0UHJvZmlsZUJ5VXVpZCh1dWlkKTtcblxuICAgIGlmIChsb2FkZWRQcm9maWxlKSB7XG4gICAgICAvLyBUaGlzIHByb2ZpbGUgaXMgYWxyZWFkeSBsb2FkZWRcbiAgICAgIHJldHVybiBvZih1bmRlZmluZWQpO1xuICAgIH1cblxuICAgIC8vIExvYWQgdGhlIG1ldGFkYXRhIGFuZCB0aGUgcHJvZmlsZVxuICAgIHJldHVybiBmb3JrSm9pbihbdGhpcy5odHRwLmdldCgnZml4dHVyZXM/dXVpZD0nICsgZW5jb2RlVVJJKHV1aWQpKSwgdGhpcy5odHRwLmdldCgnZml4dHVyZT91dWlkPScgKyBlbmNvZGVVUkkodXVpZCkpXSkucGlwZShcbiAgICAgIG1hcCgocmVzdWx0KSA9PiB7XG4gICAgICAgIGNvbnN0IG1lcmdlZERhdGEgPSB7IC4uLnJlc3VsdFswXVswXSwgLi4ucmVzdWx0WzFdIH07XG4gICAgICAgIGNvbnN0IGZpeHR1cmVQcm9maWxlID0gbmV3IEZpeHR1cmVQcm9maWxlKG1lcmdlZERhdGEpO1xuICAgICAgICB0aGlzLnByb2plY3RTZXJ2aWNlLnByb2plY3QuZml4dHVyZVByb2ZpbGVzLnB1c2goZml4dHVyZVByb2ZpbGUpO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgZ2V0Um90YXRpb25BbmdsZURlZyh2YWx1ZTogc3RyaW5nKTogbnVtYmVyIHtcbiAgICAvLyBjb252ZXJ0IGEgcm90YXRpb24gYW5nbGUgdmFsdWUgaW50byBkZWdyZWVzXG4gICAgaWYgKHZhbHVlLmVuZHNXaXRoKCdkZWcnKSkge1xuICAgICAgcmV0dXJuIE51bWJlci5wYXJzZUludCh2YWx1ZS5yZXBsYWNlKCdkZWcnLCAnJyksIDEwKTtcbiAgICB9IGVsc2UgaWYgKHZhbHVlLmVuZHNXaXRoKCclJykpIHtcbiAgICAgIGNvbnN0IHBlcmMgPSBOdW1iZXIucGFyc2VJbnQodmFsdWUucmVwbGFjZSgnJScsICcnKSwgMTApO1xuICAgICAgcmV0dXJuIChwZXJjIC8gMTAwKSAqIDM2MDtcbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgZ2V0V2hlZWxTbG90Q29sb3JzKHdoZWVsOiBGaXh0dXJlV2hlZWwsIHNsb3ROdW1iZXI6IG51bWJlcik6IHN0cmluZ1tdIHtcbiAgICBsZXQgY29sb3JzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGNvbnN0IHdoZWVsU2xvdHMgPSB0aGlzLmdldFdoZWVsU2xvdHMod2hlZWwsIHNsb3ROdW1iZXIpO1xuXG4gICAgZm9yIChjb25zdCBzbG90IG9mIHdoZWVsU2xvdHMpIHtcbiAgICAgIGlmIChzbG90LmNvbG9ycyAmJiBzbG90LmNvbG9ycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbG9ycyA9IGNvbG9ycy5jb25jYXQoc2xvdC5jb2xvcnMpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBjb2xvcnM7XG4gIH1cblxuICBnZXRNaXhlZFdoZWVsU2xvdENvbG9yKHdoZWVsOiBGaXh0dXJlV2hlZWwsIHNsb3ROdW1iZXI6IG51bWJlcik6IENvbG9yIHtcbiAgICBjb25zdCBjb2xvcnMgPSB0aGlzLmdldFdoZWVsU2xvdENvbG9ycyh3aGVlbCwgc2xvdE51bWJlcik7XG4gICAgY29uc3QgY29sb3JzUmdiOiBDb2xvcltdID0gW107XG5cbiAgICBpZiAoY29sb3JzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGNvbG9yIG9mIGNvbG9ycykge1xuICAgICAgY29sb3JzUmdiLnB1c2godGhpcy5oZXhUb1JnYihjb2xvcikpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLm1peENvbG9ycyhjb2xvcnNSZ2IpO1xuICB9XG5cbiAgcHJpdmF0ZSBjb21wb25lbnRUb0hleChjOiBudW1iZXIpOiBhbnkge1xuICAgIGNvbnN0IGhleCA9IGMudG9TdHJpbmcoMTYpO1xuICAgIHJldHVybiBoZXgubGVuZ3RoID09PSAxID8gJzAnICsgaGV4IDogaGV4O1xuICB9XG5cbiAgcmdiVG9IZXgocjogbnVtYmVyLCBnOiBudW1iZXIsIGI6IG51bWJlcik6IHN0cmluZyB7XG4gICAgcmV0dXJuICcjJyArIHRoaXMuY29tcG9uZW50VG9IZXgocikgKyB0aGlzLmNvbXBvbmVudFRvSGV4KGcpICsgdGhpcy5jb21wb25lbnRUb0hleChiKTtcbiAgfVxuXG4gIGhleFRvUmdiKGhleDogc3RyaW5nKTogQ29sb3Ige1xuICAgIC8vIGV4cGFuZCBzaG9ydGhhbmQgZm9ybSAoZS5nLiBcIjAzRlwiKSB0byBmdWxsIGZvcm0gKGUuZy4gXCIwMDMzRkZcIilcbiAgICBjb25zdCBzaG9ydGhhbmRSZWdleCA9IC9eIz8oW2EtZlxcZF0pKFthLWZcXGRdKShbYS1mXFxkXSkkL2k7XG4gICAgaGV4ID0gaGV4LnJlcGxhY2Uoc2hvcnRoYW5kUmVnZXgsIChtLCByLCBnLCBiKSA9PiB7XG4gICAgICByZXR1cm4gciArIHIgKyBnICsgZyArIGIgKyBiO1xuICAgIH0pO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gL14jPyhbYS1mXFxkXXsyfSkoW2EtZlxcZF17Mn0pKFthLWZcXGRdezJ9KSQvaS5leGVjKGhleCk7XG4gICAgcmV0dXJuIHJlc3VsdCA/IG5ldyBDb2xvcihwYXJzZUludChyZXN1bHRbMV0sIDE2KSwgcGFyc2VJbnQocmVzdWx0WzJdLCAxNiksIHBhcnNlSW50KHJlc3VsdFszXSwgMTYpKSA6IG51bGw7XG4gIH1cblxuICBtaXhDb2xvcnMoY29sb3JzOiBDb2xvcltdKTogQ29sb3Ige1xuICAgIC8vIG1peCBhbiBhcnJheSBvZiByZ2ItY29sb3JzIGNvbnRhaW5pbmcgciwgZywgYiB2YWx1ZXMgdG8gYSBuZXcgY29sb3JcbiAgICBsZXQgciA9IDA7XG4gICAgbGV0IGcgPSAwO1xuICAgIGxldCBiID0gMDtcblxuICAgIGZvciAoY29uc3QgY29sb3Igb2YgY29sb3JzKSB7XG4gICAgICByICs9IGNvbG9yLnJlZDtcbiAgICAgIGcgKz0gY29sb3IuZ3JlZW47XG4gICAgICBiICs9IGNvbG9yLmJsdWU7XG4gICAgfVxuXG4gICAgciAvPSBjb2xvcnMubGVuZ3RoO1xuICAgIGcgLz0gY29sb3JzLmxlbmd0aDtcbiAgICBiIC89IGNvbG9ycy5sZW5ndGg7XG5cbiAgICByZXR1cm4gbmV3IENvbG9yKHIsIGcsIGIpO1xuICB9XG5cbiAgd2hlZWxIYXNTbG90VHlwZSh3aGVlbDogRml4dHVyZVdoZWVsLCBzbG90VHlwZTogRml4dHVyZVdoZWVsU2xvdFR5cGUpOiBib29sZWFuIHtcbiAgICBmb3IgKGNvbnN0IHNsb3Qgb2Ygd2hlZWwuc2xvdHMpIHtcbiAgICAgIGlmIChzbG90LnR5cGUgPT09IHNsb3RUeXBlKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGdldFdoZWVsQnlOYW1lKHByb2ZpbGU6IEZpeHR1cmVQcm9maWxlLCB3aGVlbE5hbWU6IHN0cmluZyk6IEZpeHR1cmVXaGVlbCB7XG4gICAgZm9yIChjb25zdCBwcm9wZXJ0eSBpbiBwcm9maWxlLndoZWVscykge1xuICAgICAgaWYgKHByb3BlcnR5ID09PSB3aGVlbE5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHByb2ZpbGUud2hlZWxzW3Byb3BlcnR5XTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyB3aGVlbCBub3QgZm91bmRcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRXaGVlbFNsb3RzKHdoZWVsOiBGaXh0dXJlV2hlZWwsIHNsb3ROdW1iZXI6IG51bWJlcik6IEZpeHR1cmVXaGVlbFNsb3RbXSB7XG4gICAgLy8gcmV0dXJuIG9uZSBzbG90IG9yIHR3byBzbG90cywgaWYgdGhleSBhcmUgbWl4ZWQgKGUuZy4gc2xvciBudW1iZXIgMi41IHJldHVybnMgdGhlIHNsb3RzIDIgYW5kIDMpXG4gICAgY29uc3Qgc2xvdHM6IEZpeHR1cmVXaGVlbFNsb3RbXSA9IFtdO1xuXG4gICAgaWYgKCF3aGVlbCkge1xuICAgICAgcmV0dXJuIHNsb3RzO1xuICAgIH1cblxuICAgIGlmIChzbG90TnVtYmVyIC0gTWF0aC5mbG9vcihzbG90TnVtYmVyKSA+IDApIHtcbiAgICAgIC8vIHR3byBzbG90cyBhcmUgc2V0XG4gICAgICBjb25zdCBudW1iZXIgPSBNYXRoLmZsb29yKHNsb3ROdW1iZXIpO1xuICAgICAgc2xvdHMucHVzaCh3aGVlbC5zbG90c1tudW1iZXIgLSAxXSk7XG4gICAgICBpZiAobnVtYmVyID49IDAgJiYgbnVtYmVyIDwgd2hlZWwuc2xvdHMubGVuZ3RoKSB7XG4gICAgICAgIHNsb3RzLnB1c2god2hlZWwuc2xvdHNbbnVtYmVyXSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIG9ubHkgb25lIHNsb3QgaXMgc2V0XG4gICAgICBzbG90cy5wdXNoKHdoZWVsLnNsb3RzW3Nsb3ROdW1iZXIgLSAxXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNsb3RzO1xuICB9XG5cbiAgZ2V0TW9kZUJ5Rml4dHVyZShwcm9maWxlOiBGaXh0dXJlUHJvZmlsZSwgZml4dHVyZTogRml4dHVyZSk6IEZpeHR1cmVNb2RlIHtcbiAgICBmb3IgKGNvbnN0IG1vZGUgb2YgcHJvZmlsZS5tb2Rlcykge1xuICAgICAgaWYgKG1vZGUuc2hvcnROYW1lKSB7XG4gICAgICAgIGlmIChtb2RlLnNob3J0TmFtZSA9PT0gZml4dHVyZS5tb2RlU2hvcnROYW1lKSB7XG4gICAgICAgICAgcmV0dXJuIG1vZGU7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChtb2RlLm5hbWUgPT09IGZpeHR1cmUubW9kZVNob3J0TmFtZSkge1xuICAgICAgICAgIHJldHVybiBtb2RlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRGaXh0dXJlQ2FwYWJpbGl0eShjYXBhYmlsaXR5OiBGaXh0dXJlQ2FwYWJpbGl0eSwgY2hhbm5lbE5hbWU6IHN0cmluZywgcHJvZmlsZTogRml4dHVyZVByb2ZpbGUpOiBDYWNoZWRGaXh0dXJlQ2FwYWJpbGl0eSB7XG4gICAgY29uc3QgY2FjaGVkRml4dHVyZUNhcGFiaWxpdHkgPSBuZXcgQ2FjaGVkRml4dHVyZUNhcGFiaWxpdHkoKTtcbiAgICBjYWNoZWRGaXh0dXJlQ2FwYWJpbGl0eS5jYXBhYmlsaXR5ID0gY2FwYWJpbGl0eTtcbiAgICBpZiAoY2FwYWJpbGl0eS5zbG90TnVtYmVyKSB7XG4gICAgICAvLyB0aGVyZSBpcyBhIHdoZWVsIGNvbm5lY3RlZCB0byB0aGlzIGNhcGFiaWxpdHlcbiAgICAgIGlmICh0eXBlb2YgY2FwYWJpbGl0eS53aGVlbCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgY2FjaGVkRml4dHVyZUNhcGFiaWxpdHkud2hlZWxOYW1lID0gY2FwYWJpbGl0eS53aGVlbCBhcyBzdHJpbmc7XG4gICAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoY2FwYWJpbGl0eS53aGVlbCkpIHtcbiAgICAgICAgY2FjaGVkRml4dHVyZUNhcGFiaWxpdHkud2hlZWxOYW1lID0gY2FwYWJpbGl0eS53aGVlbFswXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNhY2hlZEZpeHR1cmVDYXBhYmlsaXR5LndoZWVsTmFtZSA9IGNoYW5uZWxOYW1lO1xuICAgICAgfVxuICAgICAgY2FjaGVkRml4dHVyZUNhcGFiaWxpdHkud2hlZWwgPSB0aGlzLmdldFdoZWVsQnlOYW1lKHByb2ZpbGUsIGNhY2hlZEZpeHR1cmVDYXBhYmlsaXR5LndoZWVsTmFtZSk7XG4gICAgICBjYWNoZWRGaXh0dXJlQ2FwYWJpbGl0eS53aGVlbFNsb3RzID0gdGhpcy5nZXRXaGVlbFNsb3RzKGNhY2hlZEZpeHR1cmVDYXBhYmlsaXR5LndoZWVsLCBjYXBhYmlsaXR5LnNsb3ROdW1iZXIpO1xuICAgICAgY2FjaGVkRml4dHVyZUNhcGFiaWxpdHkud2hlZWxJc0NvbG9yID0gdGhpcy53aGVlbEhhc1Nsb3RUeXBlKGNhY2hlZEZpeHR1cmVDYXBhYmlsaXR5LndoZWVsLCBGaXh0dXJlV2hlZWxTbG90VHlwZS5Db2xvcik7XG4gICAgfVxuICAgIGlmIChjYWNoZWRGaXh0dXJlQ2FwYWJpbGl0eS5jYXBhYmlsaXR5LmRteFJhbmdlICYmIGNhY2hlZEZpeHR1cmVDYXBhYmlsaXR5LmNhcGFiaWxpdHkuZG14UmFuZ2UubGVuZ3RoID09PSAyKSB7XG4gICAgICBjYWNoZWRGaXh0dXJlQ2FwYWJpbGl0eS5jZW50ZXJWYWx1ZSA9IE1hdGguZmxvb3IoXG4gICAgICAgIChjYWNoZWRGaXh0dXJlQ2FwYWJpbGl0eS5jYXBhYmlsaXR5LmRteFJhbmdlWzBdICsgY2FjaGVkRml4dHVyZUNhcGFiaWxpdHkuY2FwYWJpbGl0eS5kbXhSYW5nZVsxXSkgLyAyXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gY2FjaGVkRml4dHVyZUNhcGFiaWxpdHk7XG4gIH1cblxuICBwcml2YXRlIGdldENhcGFiaWxpdGllc0J5Q2hhbm5lbChcbiAgICBmaXh0dXJlQ2hhbm5lbDogRml4dHVyZUNoYW5uZWwsXG4gICAgY2hhbm5lbE5hbWU6IHN0cmluZyxcbiAgICBwcm9maWxlOiBGaXh0dXJlUHJvZmlsZVxuICApOiBDYWNoZWRGaXh0dXJlQ2FwYWJpbGl0eVtdIHtcbiAgICBjb25zdCBjYXBhYmlsaXRlczogQ2FjaGVkRml4dHVyZUNhcGFiaWxpdHlbXSA9IFtdO1xuXG4gICAgaWYgKGZpeHR1cmVDaGFubmVsLmNhcGFiaWxpdHkpIHtcbiAgICAgIGNhcGFiaWxpdGVzLnB1c2godGhpcy5nZXRGaXh0dXJlQ2FwYWJpbGl0eShmaXh0dXJlQ2hhbm5lbC5jYXBhYmlsaXR5LCBjaGFubmVsTmFtZSwgcHJvZmlsZSkpO1xuICAgIH0gZWxzZSBpZiAoZml4dHVyZUNoYW5uZWwuY2FwYWJpbGl0aWVzKSB7XG4gICAgICBmb3IgKGNvbnN0IGNhcGFiaWxpdHkgb2YgZml4dHVyZUNoYW5uZWwuY2FwYWJpbGl0aWVzKSB7XG4gICAgICAgIGNhcGFiaWxpdGVzLnB1c2godGhpcy5nZXRGaXh0dXJlQ2FwYWJpbGl0eShjYXBhYmlsaXR5LCBjaGFubmVsTmFtZSwgcHJvZmlsZSkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBjYXBhYmlsaXRlcztcbiAgfVxuXG4gIHByaXZhdGUgZ2V0TWF4VmFsdWVCeUNoYW5uZWwoZml4dHVyZUNoYW5uZWw6IEZpeHR1cmVDaGFubmVsKTogbnVtYmVyIHtcbiAgICByZXR1cm4gTWF0aC5wb3coMjU2LCAxICsgZml4dHVyZUNoYW5uZWwuZmluZUNoYW5uZWxBbGlhc2VzLmxlbmd0aCkgLSAxO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXREZWZhdWx0VmFsdWVCeUNoYW5uZWwoZml4dHVyZUNoYW5uZWw6IEZpeHR1cmVDaGFubmVsKTogbnVtYmVyIHtcbiAgICBpZiAoIWZpeHR1cmVDaGFubmVsLmRlZmF1bHRWYWx1ZSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBpZiAoaXNOYU4oZml4dHVyZUNoYW5uZWwuZGVmYXVsdFZhbHVlIGFzIGFueSkgJiYgKGZpeHR1cmVDaGFubmVsLmRlZmF1bHRWYWx1ZSBhcyBzdHJpbmcpLmVuZHNXaXRoKCclJykpIHtcbiAgICAgIC8vIHBlcmNlbnRhZ2UgdmFsdWVcbiAgICAgIGNvbnN0IHBlcmNlbnRhZ2UgPSBOdW1iZXIucGFyc2VJbnQoKGZpeHR1cmVDaGFubmVsLmRlZmF1bHRWYWx1ZSBhcyBzdHJpbmcpLnJlcGxhY2UoJyUnLCAnJyksIDEwKTtcbiAgICAgIGNvbnN0IG1heFZhbHVlID0gdGhpcy5nZXRNYXhWYWx1ZUJ5Q2hhbm5lbChmaXh0dXJlQ2hhbm5lbCk7XG4gICAgICByZXR1cm4gKG1heFZhbHVlIC8gMTAwKSAqIHBlcmNlbnRhZ2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIERNWCB2YWx1ZVxuICAgICAgcmV0dXJuIE51bWJlci5wYXJzZUludChmaXh0dXJlQ2hhbm5lbC5kZWZhdWx0VmFsdWUgYXMgYW55LCAxMCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRDb2xvcldoZWVsQnlDaGFubmVsKGNoYW5uZWw6IENhY2hlZEZpeHR1cmVDaGFubmVsLCBwcm9maWxlOiBGaXh0dXJlUHJvZmlsZSk6IEZpeHR1cmVXaGVlbCB7XG4gICAgZm9yIChjb25zdCBjaGFubmVsQ2FwYWJpbGl0eSBvZiBjaGFubmVsLmNhcGFiaWxpdGllcykge1xuICAgICAgaWYgKGNoYW5uZWxDYXBhYmlsaXR5LndoZWVsSXNDb2xvcikge1xuICAgICAgICByZXR1cm4gY2hhbm5lbENhcGFiaWxpdHkud2hlZWw7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGdldENoYW5uZWxCeU5hbWUoZml4dHVyZTogQ2FjaGVkRml4dHVyZSwgY2hhbm5lbE5hbWU6IHN0cmluZyk6IENhY2hlZEZpeHR1cmVDaGFubmVsIHtcbiAgICBmb3IgKGNvbnN0IGNoYW5uZWwgb2YgZml4dHVyZS5jaGFubmVscykge1xuICAgICAgaWYgKFxuICAgICAgICAoY2hhbm5lbC5uYW1lICYmIGNoYW5uZWwubmFtZSA9PT0gY2hhbm5lbE5hbWUpIHx8XG4gICAgICAgIChjaGFubmVsLmNoYW5uZWwgJiYgY2hhbm5lbC5jaGFubmVsLmZpbmVDaGFubmVsQWxpYXNlcy5pbmRleE9mKGNoYW5uZWxOYW1lKSA+IC0xKVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBjaGFubmVsO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBwcml2YXRlIGdldENoYW5uZWxOYW1lV2l0aFBpeGVsS2V5KHRlbXBsYXRlQ2hhbm5lbE5hbWU6IHN0cmluZywgcGl4ZWxLZXk6IHN0cmluZykge1xuICAgIHJldHVybiB0ZW1wbGF0ZUNoYW5uZWxOYW1lLnJlcGxhY2UoJyRwaXhlbEtleScsIHBpeGVsS2V5KTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkQ2FjaGVkQ2hhbm5lbChcbiAgICBjaGFubmVsczogQ2FjaGVkRml4dHVyZUNoYW5uZWxbXSxcbiAgICBjaGFubmVsOiBGaXh0dXJlQ2hhbm5lbCxcbiAgICB0ZW1wbGF0ZUNoYW5uZWxOYW1lOiBzdHJpbmcsXG4gICAgcGl4ZWxLZXk6IHN0cmluZyxcbiAgICBwcm9maWxlOiBGaXh0dXJlUHJvZmlsZVxuICApIHtcbiAgICBjb25zdCBjYWNoZWRGaXh0dXJlQ2hhbm5lbCA9IG5ldyBDYWNoZWRGaXh0dXJlQ2hhbm5lbCgpO1xuICAgIGNvbnN0IGNoYW5uZWxOYW1lID0gdGhpcy5nZXRDaGFubmVsTmFtZVdpdGhQaXhlbEtleSh0ZW1wbGF0ZUNoYW5uZWxOYW1lLCBwaXhlbEtleSk7XG5cbiAgICBjYWNoZWRGaXh0dXJlQ2hhbm5lbC5jaGFubmVsID0gY2hhbm5lbDtcbiAgICBjYWNoZWRGaXh0dXJlQ2hhbm5lbC5uYW1lID0gY2hhbm5lbE5hbWU7XG4gICAgY2FjaGVkRml4dHVyZUNoYW5uZWwuY2FwYWJpbGl0aWVzID0gdGhpcy5nZXRDYXBhYmlsaXRpZXNCeUNoYW5uZWwoY2FjaGVkRml4dHVyZUNoYW5uZWwuY2hhbm5lbCwgY2hhbm5lbE5hbWUsIHByb2ZpbGUpO1xuICAgIGNvbnN0IGRlZmF1bHRWYWx1ZSA9IHRoaXMuZ2V0RGVmYXVsdFZhbHVlQnlDaGFubmVsKGNhY2hlZEZpeHR1cmVDaGFubmVsLmNoYW5uZWwpO1xuICAgIGlmIChkZWZhdWx0VmFsdWUpIHtcbiAgICAgIGNhY2hlZEZpeHR1cmVDaGFubmVsLmRlZmF1bHRWYWx1ZSA9IGRlZmF1bHRWYWx1ZTtcbiAgICB9XG4gICAgY2FjaGVkRml4dHVyZUNoYW5uZWwubWF4VmFsdWUgPSB0aGlzLmdldE1heFZhbHVlQnlDaGFubmVsKGNhY2hlZEZpeHR1cmVDaGFubmVsLmNoYW5uZWwpO1xuICAgIGNhY2hlZEZpeHR1cmVDaGFubmVsLmNvbG9yV2hlZWwgPSB0aGlzLmdldENvbG9yV2hlZWxCeUNoYW5uZWwoY2FjaGVkRml4dHVyZUNoYW5uZWwsIHByb2ZpbGUpO1xuICAgIGNoYW5uZWxzLnB1c2goY2FjaGVkRml4dHVyZUNoYW5uZWwpO1xuICB9XG5cbiAgcHJpdmF0ZSBhbHBoYW51bWVyaWNTb3J0KGE6IHN0cmluZywgYjogc3RyaW5nKTogbnVtYmVyIHtcbiAgICByZXR1cm4gYS5sb2NhbGVDb21wYXJlKGIsIHVuZGVmaW5lZCwgeyBudW1lcmljOiB0cnVlLCBzZW5zaXRpdml0eTogJ2Jhc2UnIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRBbGxQaXhlbEtleXMocHJvZmlsZTogRml4dHVyZVByb2ZpbGUpIHtcbiAgICBsZXQgcmVzdWx0OiBzdHJpbmdbXSA9IFtdO1xuICAgIGZvciAobGV0IHBpeGVsS2V5WCBvZiBwcm9maWxlLm1hdHJpeC5waXhlbEtleXMpIHtcbiAgICAgIGZvciAobGV0IHBpeGVsS2V5WSBvZiBwaXhlbEtleVgpIHtcbiAgICAgICAgZm9yIChsZXQgcGl4ZWxLZXlaIG9mIHBpeGVsS2V5WSkge1xuICAgICAgICAgIGlmIChwaXhlbEtleVopIHtcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKHBpeGVsS2V5Wik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcml2YXRlIGdldEFsbFBpeGVsR3JvdXBzKHByb2ZpbGU6IEZpeHR1cmVQcm9maWxlKSB7XG4gICAgbGV0IHJlc3VsdDogc3RyaW5nW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IHByb3BlcnR5IG9mIE9iamVjdC5rZXlzKHByb2ZpbGUubWF0cml4LnBpeGVsR3JvdXBzKSkge1xuICAgICAgcmVzdWx0LnB1c2gocHJvcGVydHkpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRQaXhlbEtleXNJbk9yZGVyKHByb2ZpbGU6IEZpeHR1cmVQcm9maWxlLCByZXBlYXRGb3I6IHN0cmluZ1tdKTogc3RyaW5nW10ge1xuICAgIGxldCByZXN1bHQ6IHN0cmluZ1tdID0gW107XG5cbiAgICAvLyBjb3VsZCBjb250YWluIGp1c3QgYSBzaW5nbGUgc3RyaW5nIChlLmcuICdlYWNoUGl4ZWxBQkMnKSBvclxuICAgIGlmIChyZXBlYXRGb3IubGVuZ3RoID4gMSkge1xuICAgICAgLy8gYW4gYXJyYXkgb2YgcGl4ZWwgKGdyb3VwcylcbiAgICAgIHJlc3VsdCA9IHJlcGVhdEZvcjtcbiAgICB9IGVsc2UgaWYgKHJlcGVhdEZvci5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSBlbHNlIGlmIChyZXBlYXRGb3JbMF0gPT09ICdlYWNoUGl4ZWxBQkMnKSB7XG4gICAgICAvLyBHZXRzIGNvbXB1dGVkIGludG8gYW4gYWxwaGFudW1lcmljYWxseSBzb3J0ZWQgbGlzdCBvZiBhbGwgcGl4ZWxLZXlzXG4gICAgICBpZiAocHJvZmlsZS5tYXRyaXgucGl4ZWxDb3VudC5sZW5ndGggPT09IDMpIHtcbiAgICAgICAgZm9yIChsZXQgeCA9IDA7IHggPCBwcm9maWxlLm1hdHJpeC5waXhlbENvdW50WzBdOyB4KyspIHtcbiAgICAgICAgICBmb3IgKGxldCB5ID0gMDsgeSA8IHByb2ZpbGUubWF0cml4LnBpeGVsQ291bnRbMV07IHkrKykge1xuICAgICAgICAgICAgZm9yIChsZXQgeiA9IDA7IHogPCBwcm9maWxlLm1hdHJpeC5waXhlbENvdW50WzJdOyB6KyspIHtcbiAgICAgICAgICAgICAgcmVzdWx0LnB1c2goJ1BpeGVsICcgKyAoeCArIDEpICsgJy0nICsgKHkgKyAxKSArICctJyArICh6ICsgMSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0ID0gcmVzdWx0LmNvbmNhdCh0aGlzLmdldEFsbFBpeGVsS2V5cyhwcm9maWxlKSk7XG4gICAgICB9XG4gICAgICByZXN1bHQuc29ydCh0aGlzLmFscGhhbnVtZXJpY1NvcnQpO1xuICAgIH0gZWxzZSBpZiAocmVwZWF0Rm9yWzBdID09PSAnZWFjaFBpeGVsR3JvdXAnKSB7XG4gICAgICAvLyBHZXRzIGNvbXB1dGVkIGludG8gYW4gYXJyYXkgb2YgYWxsIHBpeGVsIGdyb3VwIGtleXMsIG9yZGVyZWQgYnkgYXBwZWFyYW5jZSBpbiB0aGUgSlNPTiBmaWxlXG4gICAgICByZXN1bHQgPSByZXN1bHQuY29uY2F0KHRoaXMuZ2V0QWxsUGl4ZWxHcm91cHMocHJvZmlsZSkpO1xuICAgIH0gZWxzZSBpZiAocmVwZWF0Rm9yWzBdID09PSAnZWFjaFBpeGVsWFlaJykge1xuICAgICAgZm9yIChsZXQgeCA9IDA7IHggPCBwcm9maWxlLm1hdHJpeC5waXhlbEtleXMubGVuZ3RoOyB4KyspIHtcbiAgICAgICAgZm9yIChsZXQgeSA9IDA7IHkgPCBwcm9maWxlLm1hdHJpeC5waXhlbEtleXNbeF0ubGVuZ3RoOyB5KyspIHtcbiAgICAgICAgICBmb3IgKGxldCB6ID0gMDsgeiA8IHByb2ZpbGUubWF0cml4LnBpeGVsS2V5c1t4XVt5XS5sZW5ndGg7IHorKykge1xuICAgICAgICAgICAgY29uc3QgcGl4ZWwgPSBwcm9maWxlLm1hdHJpeC5waXhlbEtleXNbeF1beV1bel07XG4gICAgICAgICAgICBpZiAocGl4ZWwpIHtcbiAgICAgICAgICAgICAgcmVzdWx0LnB1c2gocGl4ZWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocmVwZWF0Rm9yWzBdID09PSAnZWFjaFBpeGVsWFpZJykge1xuICAgICAgZm9yIChsZXQgeCA9IDA7IHggPCBwcm9maWxlLm1hdHJpeC5waXhlbEtleXMubGVuZ3RoOyB4KyspIHtcbiAgICAgICAgZm9yIChsZXQgeiA9IDA7IHogPCBwcm9maWxlLm1hdHJpeC5waXhlbEtleXNbeF1bMF0ubGVuZ3RoOyB6KyspIHtcbiAgICAgICAgICBmb3IgKGxldCB5ID0gMDsgeSA8IHByb2ZpbGUubWF0cml4LnBpeGVsS2V5c1t4XS5sZW5ndGg7IHkrKykge1xuICAgICAgICAgICAgY29uc3QgcGl4ZWwgPSBwcm9maWxlLm1hdHJpeC5waXhlbEtleXNbeF1beV1bel07XG4gICAgICAgICAgICBpZiAocGl4ZWwpIHtcbiAgICAgICAgICAgICAgcmVzdWx0LnB1c2gocGl4ZWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocmVwZWF0Rm9yWzBdID09PSAnZWFjaFBpeGVsWVhaJykge1xuICAgICAgZm9yIChsZXQgeSA9IDA7IHkgPCBwcm9maWxlLm1hdHJpeC5waXhlbEtleXNbMF0ubGVuZ3RoOyB5KyspIHtcbiAgICAgICAgZm9yIChsZXQgeCA9IDA7IHggPCBwcm9maWxlLm1hdHJpeC5waXhlbEtleXMubGVuZ3RoOyB4KyspIHtcbiAgICAgICAgICBmb3IgKGxldCB6ID0gMDsgeiA8IHByb2ZpbGUubWF0cml4LnBpeGVsS2V5c1t4XVt5XS5sZW5ndGg7IHorKykge1xuICAgICAgICAgICAgY29uc3QgcGl4ZWwgPSBwcm9maWxlLm1hdHJpeC5waXhlbEtleXNbeF1beV1bel07XG4gICAgICAgICAgICBpZiAocGl4ZWwpIHtcbiAgICAgICAgICAgICAgcmVzdWx0LnB1c2gocGl4ZWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocmVwZWF0Rm9yWzBdID09PSAnZWFjaFBpeGVsWVpYJykge1xuICAgICAgZm9yIChsZXQgeSA9IDA7IHkgPCBwcm9maWxlLm1hdHJpeC5waXhlbEtleXNbMF0ubGVuZ3RoOyB5KyspIHtcbiAgICAgICAgZm9yIChsZXQgeiA9IDA7IHogPCBwcm9maWxlLm1hdHJpeC5waXhlbEtleXNbMF1beV0ubGVuZ3RoOyB6KyspIHtcbiAgICAgICAgICBmb3IgKGxldCB4ID0gMDsgeCA8IHByb2ZpbGUubWF0cml4LnBpeGVsS2V5cy5sZW5ndGg7IHgrKykge1xuICAgICAgICAgICAgY29uc3QgcGl4ZWwgPSBwcm9maWxlLm1hdHJpeC5waXhlbEtleXNbeF1beV1bel07XG4gICAgICAgICAgICBpZiAocGl4ZWwpIHtcbiAgICAgICAgICAgICAgcmVzdWx0LnB1c2gocGl4ZWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocmVwZWF0Rm9yWzBdID09PSAnZWFjaFBpeGVsWlhZJykge1xuICAgICAgZm9yIChsZXQgeiA9IDA7IHogPCBwcm9maWxlLm1hdHJpeC5waXhlbEtleXNbMF1bMF0ubGVuZ3RoOyB6KyspIHtcbiAgICAgICAgZm9yIChsZXQgeCA9IDA7IHggPCBwcm9maWxlLm1hdHJpeC5waXhlbEtleXMubGVuZ3RoOyB4KyspIHtcbiAgICAgICAgICBmb3IgKGxldCB5ID0gMDsgeSA8IHByb2ZpbGUubWF0cml4LnBpeGVsS2V5c1t4XS5sZW5ndGg7IHkrKykge1xuICAgICAgICAgICAgY29uc3QgcGl4ZWwgPSBwcm9maWxlLm1hdHJpeC5waXhlbEtleXNbeF1beV1bel07XG4gICAgICAgICAgICBpZiAocGl4ZWwpIHtcbiAgICAgICAgICAgICAgcmVzdWx0LnB1c2gocGl4ZWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocmVwZWF0Rm9yWzBdID09PSAnZWFjaFBpeGVsWllYJykge1xuICAgICAgZm9yIChsZXQgeiA9IDA7IHogPCBwcm9maWxlLm1hdHJpeC5waXhlbEtleXNbMF1bMF0ubGVuZ3RoOyB6KyspIHtcbiAgICAgICAgZm9yIChsZXQgeSA9IDA7IHkgPCBwcm9maWxlLm1hdHJpeC5waXhlbEtleXNbMF0ubGVuZ3RoOyB5KyspIHtcbiAgICAgICAgICBmb3IgKGxldCB4ID0gMDsgeCA8IHByb2ZpbGUubWF0cml4LnBpeGVsS2V5cy5sZW5ndGg7IHgrKykge1xuICAgICAgICAgICAgY29uc3QgcGl4ZWwgPSBwcm9maWxlLm1hdHJpeC5waXhlbEtleXNbeF1beV1bel07XG4gICAgICAgICAgICBpZiAocGl4ZWwpIHtcbiAgICAgICAgICAgICAgcmVzdWx0LnB1c2gocGl4ZWwpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBnZXRNb2RlQ2hhbm5lbENvdW50KHByb2ZpbGU6IEZpeHR1cmVQcm9maWxlLCBtb2RlOiBGaXh0dXJlTW9kZSk6IG51bWJlciB7XG4gICAgbGV0IGNvdW50OiBudW1iZXIgPSAwO1xuXG4gICAgLy8gYWxyZWFkeSBjYWxjdWxhdGVkP1xuICAgIGlmIChtb2RlLmNoYW5uZWxDb3VudCkge1xuICAgICAgcmV0dXJuIG1vZGUuY2hhbm5lbENvdW50O1xuICAgIH1cblxuICAgIGZvciAobGV0IGNoYW5uZWwgb2YgbW9kZS5jaGFubmVscykge1xuICAgICAgaWYgKGNoYW5uZWwuaW5zZXJ0ID09PSAnbWF0cml4Q2hhbm5lbHMnKSB7XG4gICAgICAgIGlmIChjaGFubmVsLnJlcGVhdEZvci5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgY291bnQgKz0gY2hhbm5lbC5yZXBlYXRGb3IubGVuZ3RoICogY2hhbm5lbC50ZW1wbGF0ZUNoYW5uZWxzLmxlbmd0aDtcbiAgICAgICAgfSBlbHNlIGlmIChjaGFubmVsLnJlcGVhdEZvclswXSA9PT0gJ2VhY2hQaXhlbEdyb3VwJykge1xuICAgICAgICAgIGNvdW50ICs9IHByb2ZpbGUubWF0cml4LnBpeGVsR3JvdXBzLmxlbmd0aCAqIGNoYW5uZWwudGVtcGxhdGVDaGFubmVscy5sZW5ndGg7XG4gICAgICAgIH0gZWxzZSBpZiAoY2hhbm5lbC5yZXBlYXRGb3JbMF0uc3RhcnRzV2l0aCgnZWFjaFBpeGVsJykpIHtcbiAgICAgICAgICBpZiAocHJvZmlsZS5tYXRyaXgucGl4ZWxDb3VudC5sZW5ndGggPT09IDMpIHtcbiAgICAgICAgICAgIGNvdW50ICs9XG4gICAgICAgICAgICAgIHByb2ZpbGUubWF0cml4LnBpeGVsQ291bnRbMF0gKiBwcm9maWxlLm1hdHJpeC5waXhlbENvdW50WzFdICogcHJvZmlsZS5tYXRyaXgucGl4ZWxDb3VudFsyXSAqIGNoYW5uZWwudGVtcGxhdGVDaGFubmVscy5sZW5ndGg7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGZvciAobGV0IHggPSAwOyB4IDwgcHJvZmlsZS5tYXRyaXgucGl4ZWxLZXlzLmxlbmd0aDsgeCsrKSB7XG4gICAgICAgICAgICAgIGZvciAobGV0IHkgPSAwOyB5IDwgcHJvZmlsZS5tYXRyaXgucGl4ZWxLZXlzW3hdLmxlbmd0aDsgeSsrKSB7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgeiA9IDA7IHogPCBwcm9maWxlLm1hdHJpeC5waXhlbEtleXNbeF1beV0ubGVuZ3RoOyB6KyspIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHBpeGVsID0gcHJvZmlsZS5tYXRyaXgucGl4ZWxLZXlzW3hdW3ldW3pdO1xuICAgICAgICAgICAgICAgICAgaWYgKHBpeGVsKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IGNoYW5uZWwudGVtcGxhdGVDaGFubmVscy5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb3VudCsrO1xuICAgICAgfVxuICAgIH1cblxuICAgIG1vZGUuY2hhbm5lbENvdW50ID0gY291bnQ7XG5cbiAgICByZXR1cm4gbW9kZS5jaGFubmVsQ291bnQ7XG4gIH1cblxuICBnZXRDYWNoZWRDaGFubmVscyhwcm9maWxlOiBGaXh0dXJlUHJvZmlsZSwgbW9kZTogRml4dHVyZU1vZGUsIHBpeGVsS2V5OiBzdHJpbmcpOiBDYWNoZWRGaXh0dXJlQ2hhbm5lbFtdIHtcbiAgICBjb25zdCBjaGFubmVsczogQ2FjaGVkRml4dHVyZUNoYW5uZWxbXSA9IFtdO1xuXG4gICAgaWYgKCFtb2RlKSB7XG4gICAgICByZXR1cm4gY2hhbm5lbHM7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBjaGFubmVsIG9mIG1vZGUuY2hhbm5lbHMpIHtcbiAgICAgIGlmIChjaGFubmVsLm5hbWUgJiYgIXBpeGVsS2V5KSB7XG4gICAgICAgIC8vIGRpcmVjdCByZWZlcmVuY2UgdG8gYSBjaGFubmVsXG4gICAgICAgIC8vIGRvbid0IGNoZWNrIHRoZSBmaW5lIGNoYW5uZWxzLiBvbmx5IGFkZCB0aGUgY29hcnNlIGNoYW5uZWwuXG4gICAgICAgIGxldCBjaGFubmVsRm91bmQgPSBmYWxzZTtcblxuICAgICAgICBmb3IgKGNvbnN0IGF2YWlsYWJsZUNoYW5uZWxOYW1lIG9mIE9iamVjdC5rZXlzKHByb2ZpbGUuYXZhaWxhYmxlQ2hhbm5lbHMpKSB7XG4gICAgICAgICAgaWYgKGNoYW5uZWwubmFtZSA9PT0gYXZhaWxhYmxlQ2hhbm5lbE5hbWUpIHtcbiAgICAgICAgICAgIGNvbnN0IGF2YWlsYWJsZUNoYW5uZWw6IEZpeHR1cmVDaGFubmVsID0gcHJvZmlsZS5hdmFpbGFibGVDaGFubmVsc1thdmFpbGFibGVDaGFubmVsTmFtZV07XG5cbiAgICAgICAgICAgIHRoaXMuYWRkQ2FjaGVkQ2hhbm5lbChjaGFubmVscywgYXZhaWxhYmxlQ2hhbm5lbCwgYXZhaWxhYmxlQ2hhbm5lbE5hbWUsIG51bGwsIHByb2ZpbGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGNoZWNrIHRoZSB0ZW1wbGF0ZSBjaGFubmVscywgaWYgbm90IGZvdW5kIGluIHRoZSBhdmFpbGFibGUgY2hhbm5lbHNcbiAgICAgICAgaWYgKCFjaGFubmVsRm91bmQpIHtcbiAgICAgICAgICBmb3IgKGNvbnN0IHRlbXBsYXRlQ2hhbm5lbE5hbWUgb2YgT2JqZWN0LmtleXMocHJvZmlsZS50ZW1wbGF0ZUNoYW5uZWxzKSkge1xuICAgICAgICAgICAgbGV0IGV4aXN0aW5nUGl4ZWxLZXlzID0gdGhpcy5nZXRBbGxQaXhlbEtleXMocHJvZmlsZSkuY29uY2F0KHRoaXMuZ2V0QWxsUGl4ZWxHcm91cHMocHJvZmlsZSkpO1xuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGV4aXN0aW5nUGl4ZWxLZXkgb2YgZXhpc3RpbmdQaXhlbEtleXMpIHtcbiAgICAgICAgICAgICAgY29uc3QgY2hhbm5lbE5hbWUgPSB0aGlzLmdldENoYW5uZWxOYW1lV2l0aFBpeGVsS2V5KHRlbXBsYXRlQ2hhbm5lbE5hbWUsIGV4aXN0aW5nUGl4ZWxLZXkpO1xuXG4gICAgICAgICAgICAgIGlmIChjaGFubmVsLm5hbWUgPT09IGNoYW5uZWxOYW1lKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdGVtcGxhdGVDaGFubmVsOiBGaXh0dXJlQ2hhbm5lbCA9IHByb2ZpbGUudGVtcGxhdGVDaGFubmVsc1t0ZW1wbGF0ZUNoYW5uZWxOYW1lXTtcblxuICAgICAgICAgICAgICAgIHRoaXMuYWRkQ2FjaGVkQ2hhbm5lbChjaGFubmVscywgdGVtcGxhdGVDaGFubmVsLCBjaGFubmVsTmFtZSwgZXhpc3RpbmdQaXhlbEtleSwgcHJvZmlsZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIHJlZmVyZW5jZSBhIGNoYW5uZWwgdGhyb3VnaCBhIHBpeGVsIG1hdHJpeFxuICAgICAgICBjb25zdCBhdmFpbGFibGVQaXhlbEtleXMgPSB0aGlzLmdldFBpeGVsS2V5c0luT3JkZXIocHJvZmlsZSwgY2hhbm5lbC5yZXBlYXRGb3IpO1xuXG4gICAgICAgIGlmIChjaGFubmVsLmNoYW5uZWxPcmRlciA9PT0gJ3BlclBpeGVsJykge1xuICAgICAgICAgIC8vIGVhY2ggY2hhbm5lbCBmb3IgZWFjaCBwaXhlbFxuXG4gICAgICAgICAgZm9yIChjb25zdCBhdmFpbGFibGVQaXhlbEtleSBvZiBhdmFpbGFibGVQaXhlbEtleXMpIHtcbiAgICAgICAgICAgIGlmIChhdmFpbGFibGVQaXhlbEtleSA9PT0gcGl4ZWxLZXkpIHtcbiAgICAgICAgICAgICAgZm9yIChjb25zdCBtb2RlVGVtcGxhdGVDaGFubmVsTmFtZSBvZiBjaGFubmVsLnRlbXBsYXRlQ2hhbm5lbHMpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHRlbXBsYXRlQ2hhbm5lbE5hbWUgb2YgT2JqZWN0LmtleXMocHJvZmlsZS50ZW1wbGF0ZUNoYW5uZWxzKSkge1xuICAgICAgICAgICAgICAgICAgLy8gZG9uJ3QgY2hlY2sgdGhlIGZpbmUgY2hhbm5lbHMuIG9ubHkgYWRkIHRoZSBjb2Fyc2UgY2hhbm5lbC5cbiAgICAgICAgICAgICAgICAgIGlmIChtb2RlVGVtcGxhdGVDaGFubmVsTmFtZSA9PT0gdGVtcGxhdGVDaGFubmVsTmFtZSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB0ZW1wbGF0ZUNoYW5uZWw6IEZpeHR1cmVDaGFubmVsID0gcHJvZmlsZS50ZW1wbGF0ZUNoYW5uZWxzW3RlbXBsYXRlQ2hhbm5lbE5hbWVdO1xuXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWRkQ2FjaGVkQ2hhbm5lbChjaGFubmVscywgdGVtcGxhdGVDaGFubmVsLCB0ZW1wbGF0ZUNoYW5uZWxOYW1lLCBhdmFpbGFibGVQaXhlbEtleSwgcHJvZmlsZSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGNoYW5uZWwuY2hhbm5lbE9yZGVyID09PSAncGVyQ2hhbm5lbCcpIHtcbiAgICAgICAgICAvLyBlYWNoIHBpeGVsIGZvciBlYWNoIGNoYW5uZWxcblxuICAgICAgICAgIGZvciAoY29uc3QgbW9kZVRlbXBsYXRlQ2hhbm5lbE5hbWUgb2YgY2hhbm5lbC50ZW1wbGF0ZUNoYW5uZWxzKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGF2YWlsYWJsZVBpeGVsS2V5IG9mIGF2YWlsYWJsZVBpeGVsS2V5cykge1xuICAgICAgICAgICAgICBpZiAoYXZhaWxhYmxlUGl4ZWxLZXkgPT09IHBpeGVsS2V5KSB7XG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCB0ZW1wbGF0ZUNoYW5uZWxOYW1lIG9mIE9iamVjdC5rZXlzKHByb2ZpbGUudGVtcGxhdGVDaGFubmVscykpIHtcbiAgICAgICAgICAgICAgICAgIC8vIGRvbid0IGNoZWNrIHRoZSBmaW5lIGNoYW5uZWxzLiBvbmx5IGFkZCB0aGUgY29hcnNlIGNoYW5uZWwuXG4gICAgICAgICAgICAgICAgICBpZiAobW9kZVRlbXBsYXRlQ2hhbm5lbE5hbWUgPT09IHRlbXBsYXRlQ2hhbm5lbE5hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGVtcGxhdGVDaGFubmVsOiBGaXh0dXJlQ2hhbm5lbCA9IHByb2ZpbGUudGVtcGxhdGVDaGFubmVsc1t0ZW1wbGF0ZUNoYW5uZWxOYW1lXTtcblxuICAgICAgICAgICAgICAgICAgICB0aGlzLmFkZENhY2hlZENoYW5uZWwoY2hhbm5lbHMsIHRlbXBsYXRlQ2hhbm5lbCwgdGVtcGxhdGVDaGFubmVsTmFtZSwgYXZhaWxhYmxlUGl4ZWxLZXksIHByb2ZpbGUpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBjaGFubmVscztcbiAgfVxuXG4gIGZpeHR1cmVHZXRVbmlxdWVQaXhlbEtleXMoZml4dHVyZTogRml4dHVyZSk6IHN0cmluZ1tdIHtcbiAgICBsZXQgcGl4ZWxLZXlzOiBTZXQ8c3RyaW5nPiA9IG5ldyBTZXQoKTtcblxuICAgIGxldCBwcm9maWxlID0gdGhpcy5nZXRQcm9maWxlQnlVdWlkKGZpeHR1cmUucHJvZmlsZVV1aWQpO1xuICAgIGxldCBtb2RlID0gdGhpcy5nZXRNb2RlQnlGaXh0dXJlKHByb2ZpbGUsIGZpeHR1cmUpO1xuXG4gICAgLy8gYWRkIHRoZSB1bmlxdWUgcGl4ZWwga2V5c1xuICAgIGZvciAobGV0IGNoYW5uZWwgb2YgbW9kZS5jaGFubmVscykge1xuICAgICAgdGhpcy5nZXRQaXhlbEtleXNJbk9yZGVyKHByb2ZpbGUsIGNoYW5uZWwucmVwZWF0Rm9yKS5mb3JFYWNoKChzdHIpID0+IHtcbiAgICAgICAgcGl4ZWxLZXlzLmFkZChzdHIpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIEFycmF5LmZyb20ocGl4ZWxLZXlzKTtcbiAgfVxuXG4gIC8vIGRvZXMgdGhlIGZpeHR1cmUgaGF2ZSBhIGdlbmVyYWwgY2hhbm5lbCB3aXRob3V0IHJlZmVyZW5jZSB0byBzcGVjaWZpYyBwaXhlbCBrZXlzIGluIHRoZSBjdXJyZW50IG1vZGU/XG4gIGZpeHR1cmVIYXNHZW5lcmFsQ2hhbm5lbChmaXh0dXJlOiBGaXh0dXJlKTogYm9vbGVhbiB7XG4gICAgbGV0IHByb2ZpbGUgPSB0aGlzLmdldFByb2ZpbGVCeVV1aWQoZml4dHVyZS5wcm9maWxlVXVpZCk7XG4gICAgbGV0IG1vZGUgPSB0aGlzLmdldE1vZGVCeUZpeHR1cmUocHJvZmlsZSwgZml4dHVyZSk7XG5cbiAgICAvLyBhZGQgdGhlIHVuaXF1ZSBwaXhlbCBrZXlzXG4gICAgZm9yIChsZXQgY2hhbm5lbCBvZiBtb2RlLmNoYW5uZWxzKSB7XG4gICAgICBpZiAodGhpcy5nZXRQaXhlbEtleXNJbk9yZGVyKHByb2ZpbGUsIGNoYW5uZWwucmVwZWF0Rm9yKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdXBkYXRlQ2FjaGVkRml4dHVyZXMoKSB7XG4gICAgLy8gY2FsY3VsYXRlIHNvbWUgZnJlcXVlbnRseSB1c2VkIHZhbHVlcyBhcyBhIGNhY2hlIHRvIHNhdmUgY3B1IHRpbWVcbiAgICAvLyBhZnRlcndhcmRzXG4gICAgdGhpcy5jYWNoZWRGaXh0dXJlcyA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBmaXh0dXJlIG9mIHRoaXMucHJvamVjdFNlcnZpY2UucHJvamVjdC5maXh0dXJlcykge1xuICAgICAgaWYgKHRoaXMuZml4dHVyZUhhc0dlbmVyYWxDaGFubmVsKGZpeHR1cmUpKSB7XG4gICAgICAgIGNvbnN0IGNhY2hlZEZpeHR1cmUgPSBuZXcgQ2FjaGVkRml4dHVyZSgpO1xuICAgICAgICBjYWNoZWRGaXh0dXJlLmZpeHR1cmUgPSBmaXh0dXJlO1xuICAgICAgICBjYWNoZWRGaXh0dXJlLnByb2ZpbGUgPSB0aGlzLmdldFByb2ZpbGVCeVV1aWQoZml4dHVyZS5wcm9maWxlVXVpZCk7XG4gICAgICAgIGNhY2hlZEZpeHR1cmUubW9kZSA9IHRoaXMuZ2V0TW9kZUJ5Rml4dHVyZShjYWNoZWRGaXh0dXJlLnByb2ZpbGUsIGZpeHR1cmUpO1xuICAgICAgICBjYWNoZWRGaXh0dXJlLmNoYW5uZWxzID0gdGhpcy5nZXRDYWNoZWRDaGFubmVscyhjYWNoZWRGaXh0dXJlLnByb2ZpbGUsIGNhY2hlZEZpeHR1cmUubW9kZSwgbnVsbCk7XG4gICAgICAgIHRoaXMuY2FjaGVkRml4dHVyZXMucHVzaChjYWNoZWRGaXh0dXJlKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcGl4ZWxLZXlzID0gdGhpcy5maXh0dXJlR2V0VW5pcXVlUGl4ZWxLZXlzKGZpeHR1cmUpO1xuXG4gICAgICBmb3IgKGxldCBwaXhlbEtleSBvZiBwaXhlbEtleXMpIHtcbiAgICAgICAgY29uc3QgY2FjaGVkRml4dHVyZSA9IG5ldyBDYWNoZWRGaXh0dXJlKCk7XG4gICAgICAgIGNhY2hlZEZpeHR1cmUuZml4dHVyZSA9IGZpeHR1cmU7XG4gICAgICAgIGNhY2hlZEZpeHR1cmUucGl4ZWxLZXkgPSBwaXhlbEtleTtcbiAgICAgICAgY2FjaGVkRml4dHVyZS5wcm9maWxlID0gdGhpcy5nZXRQcm9maWxlQnlVdWlkKGZpeHR1cmUucHJvZmlsZVV1aWQpO1xuICAgICAgICBjYWNoZWRGaXh0dXJlLm1vZGUgPSB0aGlzLmdldE1vZGVCeUZpeHR1cmUoY2FjaGVkRml4dHVyZS5wcm9maWxlLCBmaXh0dXJlKTtcbiAgICAgICAgY2FjaGVkRml4dHVyZS5jaGFubmVscyA9IHRoaXMuZ2V0Q2FjaGVkQ2hhbm5lbHMoY2FjaGVkRml4dHVyZS5wcm9maWxlLCBjYWNoZWRGaXh0dXJlLm1vZGUsIHBpeGVsS2V5KTtcbiAgICAgICAgdGhpcy5jYWNoZWRGaXh0dXJlcy5wdXNoKGNhY2hlZEZpeHR1cmUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNhcGFiaWxpdGllc01hdGNoKFxuICAgIHR5cGUxOiBGaXh0dXJlQ2FwYWJpbGl0eVR5cGUsXG4gICAgdHlwZTI6IEZpeHR1cmVDYXBhYmlsaXR5VHlwZSxcbiAgICBjb2xvcjE6IEZpeHR1cmVDYXBhYmlsaXR5Q29sb3IsXG4gICAgY29sb3IyOiBGaXh0dXJlQ2FwYWJpbGl0eUNvbG9yLFxuICAgIHdoZWVsMTogc3RyaW5nLFxuICAgIHdoZWVsMjogc3RyaW5nLFxuICAgIHByb2ZpbGVVdWlkMTogc3RyaW5nLFxuICAgIHByb2ZpbGVVdWlkMjogc3RyaW5nXG4gICk6IGJvb2xlYW4ge1xuICAgIC8vIGNoZWNrcywgd2hldGhlciB0d28gcHJvdmlkZWQgY2FwYXBhYmlsaXRpZXMgbWF0Y2hcbiAgICByZXR1cm4gKFxuICAgICAgdHlwZTEgPT09IHR5cGUyICYmXG4gICAgICAoIWNvbG9yMSB8fCBjb2xvcjEgPT09IGNvbG9yMikgJiZcbiAgICAgICghd2hlZWwxIHx8IHdoZWVsMSA9PT0gd2hlZWwyKSAmJlxuICAgICAgKCFwcm9maWxlVXVpZDEgfHwgcHJvZmlsZVV1aWQxID09PSBwcm9maWxlVXVpZDIpXG4gICAgKTtcbiAgfVxuXG4gIHNldHRpbmdzRml4dHVyZUlzU2VsZWN0ZWQoZml4dHVyZTogRml4dHVyZSk6IGJvb2xlYW4ge1xuICAgIGZvciAoY29uc3Qgc2VsZWN0ZWRGaXh0dXJlIG9mIHRoaXMuc2VsZWN0ZWRTZXR0aW5nc0ZpeHR1cmVzKSB7XG4gICAgICBpZiAoc2VsZWN0ZWRGaXh0dXJlID09PSBmaXh0dXJlKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHN3aXRjaFNldHRpbmdzRml4dHVyZVNlbGVjdGlvbihmaXh0dXJlOiBGaXh0dXJlKSB7XG4gICAgaWYgKHRoaXMuc2V0dGluZ3NGaXh0dXJlSXNTZWxlY3RlZChmaXh0dXJlKSkge1xuICAgICAgdGhpcy5zZWxlY3RlZFNldHRpbmdzRml4dHVyZXMuc3BsaWNlKHRoaXMuc2VsZWN0ZWRTZXR0aW5nc0ZpeHR1cmVzLmluZGV4T2YoZml4dHVyZSksIDEpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNlbGVjdGVkU2V0dGluZ3NGaXh0dXJlcy5wdXNoKGZpeHR1cmUpO1xuICAgIH1cbiAgfVxuXG4gIGdldEZpeHR1cmVJY29uQ2xhc3MocHJvZmlsZTogRml4dHVyZVByb2ZpbGUpOiBzdHJpbmcge1xuICAgIGlmICghcHJvZmlsZSkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgICBpZiAocHJvZmlsZS5jYXRlZ29yaWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgICBpZiAoIXByb2ZpbGUuY2F0ZWdvcmllc1swXSkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgICByZXR1cm4gcHJvZmlsZS5jYXRlZ29yaWVzWzBdLnJlcGxhY2UoJyAnLCAnLScpLnRvTG9jYWxlTG93ZXJDYXNlKCk7XG4gIH1cblxuICB1cGRhdGVQcm9maWxlcygpIHtcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3QoJ3VwZGF0ZS1wcm9maWxlcycsIG51bGwpO1xuICB9XG5cbiAgZ2V0TmV4dEZyZWVEbXhDaGFubmVsKGZpeHR1cmVQb29sOiBGaXh0dXJlW10sIG5lZWRlZENoYW5uZWxzOiBudW1iZXIpOiBudW1iZXIge1xuICAgIC8vIGdldCB0aGUgbmV4dCBmcmVlIHNwYWNlIGZvciB0aGlzIGZpeHR1cmVcbiAgICBsZXQgZnJlZUNoYW5uZWxzID0gMDtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgNTEyOyBpKyspIHtcbiAgICAgIGxldCBvY2N1cGllZENoYW5uZWxzID0gMDtcblxuICAgICAgZm9yIChjb25zdCBmaXh0dXJlIG9mIGZpeHR1cmVQb29sKSB7XG4gICAgICAgIGNvbnN0IHByb2ZpbGUgPSB0aGlzLmdldFByb2ZpbGVCeVV1aWQoZml4dHVyZS5wcm9maWxlVXVpZCk7XG4gICAgICAgIGNvbnN0IG1vZGUgPSB0aGlzLmdldE1vZGVCeUZpeHR1cmUodGhpcy5nZXRQcm9maWxlQnlVdWlkKGZpeHR1cmUucHJvZmlsZVV1aWQpLCBmaXh0dXJlKTtcbiAgICAgICAgY29uc3QgY2hhbm5lbENvdW50ID0gdGhpcy5nZXRNb2RlQ2hhbm5lbENvdW50KHByb2ZpbGUsIG1vZGUpO1xuXG4gICAgICAgIGlmIChpID49IGZpeHR1cmUuZG14Rmlyc3RDaGFubmVsICYmIGkgPCBmaXh0dXJlLmRteEZpcnN0Q2hhbm5lbCArIGNoYW5uZWxDb3VudCkge1xuICAgICAgICAgIC8vIHRoaXMgY2hhbm5lbCBpcyBhbHJlYWR5IG9jY3VwaWVkIGJ5IGEgZml4dHVyZSAtPiBtb3ZlIGZvcndhcmQgdG8gdGhlIGVuZCBvZiB0aGUgZml4dHVyZVxuICAgICAgICAgIGlmIChjaGFubmVsQ291bnQgPiBvY2N1cGllZENoYW5uZWxzKSB7XG4gICAgICAgICAgICBvY2N1cGllZENoYW5uZWxzID0gY2hhbm5lbENvdW50IC0gKGkgLSBmaXh0dXJlLmRteEZpcnN0Q2hhbm5lbCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChvY2N1cGllZENoYW5uZWxzID4gMCkge1xuICAgICAgICBpICs9IG9jY3VwaWVkQ2hhbm5lbHMgLSAxO1xuICAgICAgICBmcmVlQ2hhbm5lbHMgPSAwO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZnJlZUNoYW5uZWxzKys7XG4gICAgICB9XG5cbiAgICAgIGlmIChmcmVlQ2hhbm5lbHMgPT09IG5lZWRlZENoYW5uZWxzKSB7XG4gICAgICAgIHJldHVybiBpIC0gZnJlZUNoYW5uZWxzICsgMTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBubyBmcmVlIHNwYWNlIGxlZnQgZm9yIHRoZSBuZWVkZWQgY2hhbm5lbHNcbiAgICByZXR1cm4gLTE7XG4gIH1cblxuICBhZGRGaXh0dXJlKHByb2ZpbGU6IEZpeHR1cmVQcm9maWxlLCBmaXh0dXJlUG9vbDogRml4dHVyZVtdKTogRml4dHVyZSB7XG4gICAgY29uc3QgZml4dHVyZSA9IG5ldyBGaXh0dXJlKCk7XG5cbiAgICBmaXh0dXJlLnV1aWQgPSB0aGlzLnV1aWRTZXJ2aWNlLmdldFV1aWQoKTtcbiAgICBmaXh0dXJlLnByb2ZpbGVVdWlkID0gcHJvZmlsZS51dWlkO1xuICAgIGZpeHR1cmUubmFtZSA9IHByb2ZpbGUubmFtZTtcblxuICAgIGlmIChwcm9maWxlLm1vZGVzICYmIHByb2ZpbGUubW9kZXMubGVuZ3RoID4gMCkge1xuICAgICAgZml4dHVyZS5tb2RlU2hvcnROYW1lID0gcHJvZmlsZS5tb2Rlc1swXS5zaG9ydE5hbWU7XG4gICAgfVxuXG4gICAgLy8gYWRkIHRoZSBzYW1lIG1vZGUgYXMgYW4gZXhpc3RpbmcgZml4dHVyZSwgaWYgYXZhaWxhYmxlXG4gICAgbGV0IGV4aXN0aW5nTW9kZVNob3J0TmFtZTogc3RyaW5nO1xuICAgIGZvciAoY29uc3QgZXhpc3RpbmdGaXh0dXJlIG9mIGZpeHR1cmVQb29sKSB7XG4gICAgICBjb25zdCBleGlzdGluZ1Byb2ZpbGUgPSB0aGlzLmdldFByb2ZpbGVCeVV1aWQoZXhpc3RpbmdGaXh0dXJlLnByb2ZpbGVVdWlkKTtcblxuICAgICAgaWYgKGV4aXN0aW5nUHJvZmlsZSA9PT0gcHJvZmlsZSkge1xuICAgICAgICBleGlzdGluZ01vZGVTaG9ydE5hbWUgPSBleGlzdGluZ0ZpeHR1cmUubW9kZVNob3J0TmFtZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGV4aXN0aW5nTW9kZVNob3J0TmFtZSkge1xuICAgICAgZml4dHVyZS5tb2RlU2hvcnROYW1lID0gZXhpc3RpbmdNb2RlU2hvcnROYW1lO1xuICAgIH0gZWxzZSB7XG4gICAgICBmaXh0dXJlLm1vZGVTaG9ydE5hbWUgPSBwcm9maWxlLm1vZGVzWzBdLnNob3J0TmFtZSB8fCBwcm9maWxlLm1vZGVzWzBdLm5hbWU7XG4gICAgfVxuXG4gICAgY29uc3QgbW9kZSA9IHRoaXMuZ2V0TW9kZUJ5Rml4dHVyZShwcm9maWxlLCBmaXh0dXJlKTtcbiAgICBjb25zdCBjaGFubmVsQ291bnQgPSB0aGlzLmdldE1vZGVDaGFubmVsQ291bnQocHJvZmlsZSwgbW9kZSk7XG4gICAgY29uc3QgZmlyc3RDaGFubmVsID0gdGhpcy5nZXROZXh0RnJlZURteENoYW5uZWwoZml4dHVyZVBvb2wsIGNoYW5uZWxDb3VudCk7XG5cbiAgICBpZiAoZmlyc3RDaGFubmVsID49IDApIHtcbiAgICAgIGZpeHR1cmUuZG14Rmlyc3RDaGFubmVsID0gZmlyc3RDaGFubmVsO1xuICAgICAgZml4dHVyZVBvb2wucHVzaChmaXh0dXJlKTtcbiAgICAgIHJldHVybiBmaXh0dXJlO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBubyBmcmVlIHNwYWNlIGFueW1vcmVcbiAgICAgIGNvbnN0IG1zZyA9ICdkZXNpZ25lci5maXh0dXJlLXBvb2wubm8tZnJlZS1zcGFjZSc7XG4gICAgICBjb25zdCB0aXRsZSA9ICdkZXNpZ25lci5maXh0dXJlLXBvb2wubm8tZnJlZS1zcGFjZS10aXRsZSc7XG5cbiAgICAgIHRoaXMudHJhbnNsYXRlU2VydmljZS5nZXQoW21zZywgdGl0bGVdKS5zdWJzY3JpYmUoKHJlc3VsdCkgPT4ge1xuICAgICAgICB0aGlzLnRvYXN0clNlcnZpY2UuZXJyb3IocmVzdWx0W21zZ10sIHJlc3VsdFt0aXRsZV0pO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG59XG4iXX0=
|