@aws-cdk/aws-mediaconnect-alpha 2.263.0-alpha.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/lib/flow.js ADDED
@@ -0,0 +1,1065 @@
1
+ "use strict";
2
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
3
+ var useValue = arguments.length > 2;
4
+ for (var i = 0; i < initializers.length; i++) {
5
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
6
+ }
7
+ return useValue ? value : void 0;
8
+ };
9
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
10
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
11
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
12
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
13
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
14
+ var _, done = false;
15
+ for (var i = decorators.length - 1; i >= 0; i--) {
16
+ var context = {};
17
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
18
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
19
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
20
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
21
+ if (kind === "accessor") {
22
+ if (result === void 0) continue;
23
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
24
+ if (_ = accept(result.get)) descriptor.get = _;
25
+ if (_ = accept(result.set)) descriptor.set = _;
26
+ if (_ = accept(result.init)) initializers.unshift(_);
27
+ }
28
+ else if (_ = accept(result)) {
29
+ if (kind === "field") initializers.unshift(_);
30
+ else descriptor[key] = _;
31
+ }
32
+ }
33
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
34
+ done = true;
35
+ };
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.Flow = exports.MediaStream = exports.MediaVideoFormat = exports.AudioStreamOrderOptions = exports.Tcs = exports.ScanMode = exports.VideoRange = exports.Colorimetry = exports.EncodingProfile = exports.FailoverConfig = exports.FlowSize = void 0;
38
+ const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
39
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
40
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
41
+ const aws_cloudwatch_1 = require("aws-cdk-lib/aws-cloudwatch");
42
+ const aws_mediaconnect_1 = require("aws-cdk-lib/aws-mediaconnect");
43
+ const helpers_internal_1 = require("aws-cdk-lib/core/lib/helpers-internal");
44
+ const metadata_resource_1 = require("aws-cdk-lib/core/lib/metadata-resource");
45
+ const prop_injectable_1 = require("aws-cdk-lib/core/lib/prop-injectable");
46
+ const flow_output_1 = require("./flow-output");
47
+ const flow_source_configuration_1 = require("./flow-source-configuration");
48
+ const mediaconnect_grants_generated_1 = require("./mediaconnect-grants.generated");
49
+ const shared_1 = require("./shared");
50
+ /**
51
+ * Options for Flow Size
52
+ */
53
+ class FlowSize {
54
+ value;
55
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-mediaconnect-alpha.FlowSize", version: "2.263.0-alpha.0" };
56
+ /**
57
+ * Medium flow size. The default — standard transport stream distribution; does not
58
+ * support NDI, CDI, or JPEG XS.
59
+ *
60
+ * @see https://docs.aws.amazon.com/mediaconnect/latest/ug/flow-sizes-capabilities.html
61
+ */
62
+ static MEDIUM = new FlowSize('MEDIUM');
63
+ /**
64
+ * Large flow size. Required when the flow uses NDI sources or outputs. Supports
65
+ * transport stream distribution plus NDI; does not support CDI or JPEG XS.
66
+ *
67
+ * @see https://docs.aws.amazon.com/mediaconnect/latest/ug/flow-sizes-capabilities.html
68
+ */
69
+ static LARGE = new FlowSize('LARGE');
70
+ /**
71
+ * Option for large 4x flow size. Required for JPEG XS and CDI protocols. Does not support transport streams or NDI.
72
+ */
73
+ static LARGE_4X = new FlowSize('LARGE_4X');
74
+ /**
75
+ * Use a custom flow size value
76
+ * @param value The flow size string value
77
+ */
78
+ static of(value) {
79
+ return new FlowSize(value);
80
+ }
81
+ /** @param value The flow size string value */
82
+ constructor(value) {
83
+ this.value = value;
84
+ }
85
+ /** Returns the string value */
86
+ toString() {
87
+ return this.value;
88
+ }
89
+ }
90
+ exports.FlowSize = FlowSize;
91
+ /**
92
+ * Source failover configuration for a flow.
93
+ *
94
+ * MediaConnect supports two failover modes:
95
+ * - {@link FailoverConfig.merge} combines two binary-identical sources into a single
96
+ * stream, recovering lost packets from the other source (SMPTE 2022-7).
97
+ * - {@link FailoverConfig.failover} switches between a primary and backup source when
98
+ * the active source stops receiving data.
99
+ */
100
+ class FailoverConfig {
101
+ _failoverMode;
102
+ _state;
103
+ _recoveryWindow;
104
+ _primarySource;
105
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-mediaconnect-alpha.FailoverConfig", version: "2.263.0-alpha.0" };
106
+ /**
107
+ * Configure merge-mode failover. Requires two binary-identical sources.
108
+ */
109
+ static merge(options = {}) {
110
+ try {
111
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_MergeFailoverOptions(options);
112
+ }
113
+ catch (error) {
114
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
115
+ Error.captureStackTrace(error, this.merge);
116
+ }
117
+ throw error;
118
+ }
119
+ if (options.recoveryWindow) {
120
+ const ms = options.recoveryWindow.toMilliseconds();
121
+ if (ms < 100 || ms > 15000) {
122
+ throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `RecoveryWindowRange`, `Recovery window must be between 100 and 15000 ms, got ${ms}`);
123
+ }
124
+ }
125
+ return new FailoverConfig(shared_1.FailoverMode.MERGE, options.state ?? shared_1.State.ENABLED, options.recoveryWindow, undefined);
126
+ }
127
+ /**
128
+ * Configure switchover-mode failover. The flow swaps to the backup source when the
129
+ * primary source stops receiving data.
130
+ */
131
+ static failover(options = {}) {
132
+ try {
133
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_FailoverFailoverOptions(options);
134
+ }
135
+ catch (error) {
136
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
137
+ Error.captureStackTrace(error, this.failover);
138
+ }
139
+ throw error;
140
+ }
141
+ return new FailoverConfig(shared_1.FailoverMode.FAILOVER, options.state ?? shared_1.State.ENABLED, undefined, options.primarySource);
142
+ }
143
+ constructor(_failoverMode, _state, _recoveryWindow, _primarySource) {
144
+ this._failoverMode = _failoverMode;
145
+ this._state = _state;
146
+ this._recoveryWindow = _recoveryWindow;
147
+ this._primarySource = _primarySource;
148
+ }
149
+ /**
150
+ * Whether this configuration has failover enabled.
151
+ * @internal
152
+ */
153
+ get _isEnabled() {
154
+ return this._state === shared_1.State.ENABLED;
155
+ }
156
+ /**
157
+ * Called when the configuration is bound to a Flow.
158
+ * @internal
159
+ */
160
+ _bind() {
161
+ return {
162
+ failoverMode: this._failoverMode.value,
163
+ recoveryWindow: this._recoveryWindow?.toMilliseconds(),
164
+ sourcePriority: this._primarySource ? { primarySource: this._primarySource } : undefined,
165
+ state: this._state,
166
+ };
167
+ }
168
+ }
169
+ exports.FailoverConfig = FailoverConfig;
170
+ /**
171
+ * Encoding profiles supported when transcoding an NDI source to a transport stream.
172
+ */
173
+ var EncodingProfile;
174
+ (function (EncodingProfile) {
175
+ /**
176
+ * H.264 profile tuned for contribution workflows — higher quality, higher bitrate.
177
+ */
178
+ EncodingProfile["CONTRIBUTION_H264_DEFAULT"] = "CONTRIBUTION_H264_DEFAULT";
179
+ /**
180
+ * H.264 profile tuned for distribution workflows — lower bitrate, wider compatibility.
181
+ */
182
+ EncodingProfile["DISTRIBUTION_H264_DEFAULT"] = "DISTRIBUTION_H264_DEFAULT";
183
+ })(EncodingProfile || (exports.EncodingProfile = EncodingProfile = {}));
184
+ /**
185
+ * Option for Colorimetry
186
+ */
187
+ class Colorimetry {
188
+ value;
189
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-mediaconnect-alpha.Colorimetry", version: "2.263.0-alpha.0" };
190
+ /** Option for BT601 */
191
+ static BT601 = new Colorimetry('BT601');
192
+ /** Option for BT709 */
193
+ static BT709 = new Colorimetry('BT709');
194
+ /** Option for BT2020 */
195
+ static BT2020 = new Colorimetry('BT2020');
196
+ /** Option for BT2100 */
197
+ static BT2100 = new Colorimetry('BT2100');
198
+ /** Option for ST2065-1 */
199
+ static ST2065_1 = new Colorimetry('ST2065-1');
200
+ /** Option for ST2065-3 */
201
+ static ST2065_3 = new Colorimetry('ST2065-3');
202
+ /** Option for XYZ */
203
+ static XYZ = new Colorimetry('XYZ');
204
+ /** Use a custom colorimetry value */
205
+ static of(value) { return new Colorimetry(value); }
206
+ /** @param value The colorimetry string value */
207
+ constructor(value) {
208
+ this.value = value;
209
+ }
210
+ /** Returns the string value */
211
+ toString() { return this.value; }
212
+ }
213
+ exports.Colorimetry = Colorimetry;
214
+ /**
215
+ * Options for Video Range
216
+ */
217
+ class VideoRange {
218
+ value;
219
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-mediaconnect-alpha.VideoRange", version: "2.263.0-alpha.0" };
220
+ /** Option for Narrow */
221
+ static NARROW = new VideoRange('NARROW');
222
+ /** Option for Full */
223
+ static FULL = new VideoRange('FULL');
224
+ /** Option for Full Protect */
225
+ static FULLPROTECT = new VideoRange('FULLPROTECT');
226
+ /** Use a custom video range value */
227
+ static of(value) { return new VideoRange(value); }
228
+ /** @param value The video range string value */
229
+ constructor(value) {
230
+ this.value = value;
231
+ }
232
+ /** Returns the string value */
233
+ toString() { return this.value; }
234
+ }
235
+ exports.VideoRange = VideoRange;
236
+ /**
237
+ * Options for Scan Mode
238
+ */
239
+ class ScanMode {
240
+ value;
241
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-mediaconnect-alpha.ScanMode", version: "2.263.0-alpha.0" };
242
+ /** Option for Progressive */
243
+ static PROGRESSIVE = new ScanMode('progressive');
244
+ /** Option for Interlace */
245
+ static INTERLACE = new ScanMode('interlace');
246
+ /** Option for Progressive Segmented Frame */
247
+ static PROGRESSIVE_SEGMENTED_FRAME = new ScanMode('progressive-segmented-frame');
248
+ /** Use a custom scan mode value */
249
+ static of(value) { return new ScanMode(value); }
250
+ /** @param value The scan mode string value */
251
+ constructor(value) {
252
+ this.value = value;
253
+ }
254
+ /** Returns the string value */
255
+ toString() { return this.value; }
256
+ }
257
+ exports.ScanMode = ScanMode;
258
+ /**
259
+ * Options for Tcs
260
+ */
261
+ class Tcs {
262
+ value;
263
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-mediaconnect-alpha.Tcs", version: "2.263.0-alpha.0" };
264
+ /** Option for SDR */
265
+ static SDR = new Tcs('SDR');
266
+ /** Option for PQ */
267
+ static PQ = new Tcs('PQ');
268
+ /** Option for HLG */
269
+ static HLG = new Tcs('HLG');
270
+ /** Option for Linear */
271
+ static LINEAR = new Tcs('LINEAR');
272
+ /** Option for BT2100LINPQ */
273
+ static BT2100LINPQ = new Tcs('BT2100LINPQ');
274
+ /** Option for BT2100LINHLG */
275
+ static BT2100LINHLG = new Tcs('BT2100LINHLG');
276
+ /** Option for ST2065-1 */
277
+ static ST2065_1 = new Tcs('ST2065-1');
278
+ /** Option for ST428-1 */
279
+ static ST428_1 = new Tcs('ST428-1');
280
+ /** Option for Density */
281
+ static DENSITY = new Tcs('DENSITY');
282
+ /** Use a custom TCS value */
283
+ static of(value) { return new Tcs(value); }
284
+ /** @param value The TCS string value */
285
+ constructor(value) {
286
+ this.value = value;
287
+ }
288
+ /** Returns the string value */
289
+ toString() { return this.value; }
290
+ }
291
+ exports.Tcs = Tcs;
292
+ /**
293
+ * Audio Stream Order Options
294
+ */
295
+ class AudioStreamOrderOptions {
296
+ value;
297
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-mediaconnect-alpha.AudioStreamOrderOptions", version: "2.263.0-alpha.0" };
298
+ /** Mono */
299
+ static MONO = new AudioStreamOrderOptions('SMPTE2110.(M)');
300
+ /** Dual Mono */
301
+ static DUAL_MONO = new AudioStreamOrderOptions('SMPTE2110.(DM)');
302
+ /** Standard Stereo */
303
+ static STANDARD_STEREO = new AudioStreamOrderOptions('SMPTE2110.(ST)');
304
+ /** Left Right Matrix Stereo */
305
+ static LTRT_MATRIX_STEREO = new AudioStreamOrderOptions('SMPTE2110.(LtRt)');
306
+ /** 5.1 Surround */
307
+ static SURROUND_5_1 = new AudioStreamOrderOptions('SMPTE2110.(51)');
308
+ /** 7.1 Surround */
309
+ static SURROUND_7_1 = new AudioStreamOrderOptions('SMPTE2110.(71)');
310
+ /** 22.2 Surround */
311
+ static SURROUND_22_2 = new AudioStreamOrderOptions('SMPTE2110.(222)');
312
+ /** One SDI Audio Group */
313
+ static ONE_SDI_AUDIO_GROUP = new AudioStreamOrderOptions('SMPTE2110.(SGRP)');
314
+ /** Use a custom audio stream order value */
315
+ static of(value) { return new AudioStreamOrderOptions(value); }
316
+ /** @param value The audio stream order string value */
317
+ constructor(value) {
318
+ this.value = value;
319
+ }
320
+ /** Returns the string value */
321
+ toString() { return this.value; }
322
+ }
323
+ exports.AudioStreamOrderOptions = AudioStreamOrderOptions;
324
+ /**
325
+ * Options for Media Stream Type
326
+ *
327
+ * @internal
328
+ */
329
+ var MediaStreamType;
330
+ (function (MediaStreamType) {
331
+ /**
332
+ * Option for Video
333
+ */
334
+ MediaStreamType["VIDEO"] = "video";
335
+ /**
336
+ * Option for Audio
337
+ */
338
+ MediaStreamType["AUDIO"] = "audio";
339
+ /**
340
+ * Option for ancillary data
341
+ */
342
+ MediaStreamType["ANCILLARY_DATA"] = "ancillary-data";
343
+ })(MediaStreamType || (MediaStreamType = {}));
344
+ /**
345
+ * Options for Media Video format
346
+ */
347
+ class MediaVideoFormat {
348
+ value;
349
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-mediaconnect-alpha.MediaVideoFormat", version: "2.263.0-alpha.0" };
350
+ /** Option for 2160p */
351
+ static UHD_2160P = new MediaVideoFormat('2160p');
352
+ /** Option for 1080p */
353
+ static HD_1080P = new MediaVideoFormat('1080p');
354
+ /** Option for 1080i */
355
+ static HD_1080I = new MediaVideoFormat('1080i');
356
+ /** Option for 720p */
357
+ static HD_720P = new MediaVideoFormat('720p');
358
+ /** Option for 480p */
359
+ static SD_480P = new MediaVideoFormat('480p');
360
+ /** Use a custom video format value */
361
+ static of(value) { return new MediaVideoFormat(value); }
362
+ /** @param value The video format string value */
363
+ constructor(value) {
364
+ this.value = value;
365
+ }
366
+ /** Returns the string value */
367
+ toString() { return this.value; }
368
+ }
369
+ exports.MediaVideoFormat = MediaVideoFormat;
370
+ /**
371
+ * Simplified configuration for Media Streams
372
+ */
373
+ class MediaStream {
374
+ _config;
375
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-mediaconnect-alpha.MediaStream", version: "2.263.0-alpha.0" };
376
+ /**
377
+ * Configuration for MediaStream Video
378
+ */
379
+ static video(config) {
380
+ try {
381
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_MediaStreamVideo(config);
382
+ }
383
+ catch (error) {
384
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
385
+ Error.captureStackTrace(error, this.video);
386
+ }
387
+ throw error;
388
+ }
389
+ return new MediaStream({
390
+ mediaStreamId: config.mediaStreamId,
391
+ mediaStreamName: config.mediaStreamName,
392
+ videoFormat: config.videoFormat.value,
393
+ clockRate: config.clockRate,
394
+ fmt: config.fmt,
395
+ description: config.description,
396
+ attributes: {
397
+ fmtp: {
398
+ exactFramerate: config.fmtp.exactFramerate?.toString(),
399
+ par: config.fmtp.par?.toString(),
400
+ colorimetry: config.fmtp.colorimetry?.value,
401
+ range: config.fmtp.videoRange?.value,
402
+ scanMode: config.fmtp.scanMode?.value,
403
+ tcs: config.fmtp.tcs?.value,
404
+ },
405
+ },
406
+ mediaStreamType: MediaStreamType.VIDEO,
407
+ });
408
+ }
409
+ /**
410
+ * Configuration for MediaStream audio
411
+ */
412
+ static audio(config) {
413
+ try {
414
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_MediaStreamAudio(config);
415
+ }
416
+ catch (error) {
417
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
418
+ Error.captureStackTrace(error, this.audio);
419
+ }
420
+ throw error;
421
+ }
422
+ return new MediaStream({
423
+ mediaStreamId: config.mediaStreamId,
424
+ mediaStreamName: config.mediaStreamName,
425
+ clockRate: config.clockRate,
426
+ fmt: config.fmt,
427
+ description: config.description,
428
+ attributes: {
429
+ fmtp: {
430
+ channelOrder: config.channelOrder?.value,
431
+ },
432
+ lang: config.lang,
433
+ },
434
+ mediaStreamType: MediaStreamType.AUDIO,
435
+ });
436
+ }
437
+ /**
438
+ * Configuration for MediaStream ancillary data
439
+ */
440
+ static ancillaryData(config) {
441
+ try {
442
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_MediaStreamAncillaryData(config);
443
+ }
444
+ catch (error) {
445
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
446
+ Error.captureStackTrace(error, this.ancillaryData);
447
+ }
448
+ throw error;
449
+ }
450
+ return new MediaStream({
451
+ mediaStreamId: config.mediaStreamId,
452
+ mediaStreamName: config.mediaStreamName,
453
+ description: config.description,
454
+ mediaStreamType: MediaStreamType.ANCILLARY_DATA,
455
+ });
456
+ }
457
+ constructor(_config) {
458
+ this._config = _config;
459
+ }
460
+ /**
461
+ * @internal
462
+ */
463
+ _bind() {
464
+ return this._config;
465
+ }
466
+ }
467
+ exports.MediaStream = MediaStream;
468
+ class FlowBase extends aws_cdk_lib_1.Resource {
469
+ /**
470
+ * Creates a Flow construct that represents an external (imported) Flow.
471
+ */
472
+ static fromFlowAttributes(scope, id, attrs) {
473
+ class Import extends FlowBase {
474
+ flowArn = attrs.flowArn;
475
+ flowAvailabilityZone = attrs.flowAvailabilityZone;
476
+ // Imported flows default to `false`. Pass `isFailoverEnabled: true` in the
477
+ // attributes when the real service-side flow has failover enabled and you
478
+ // need to add a FlowSource.
479
+ isFailoverEnabled = attrs.isFailoverEnabled ?? false;
480
+ get sourceArn() {
481
+ if (attrs.sourceArn)
482
+ return attrs.sourceArn;
483
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `SourceArnNotProvided`, `'sourceArn' was not provided when importing Flow ${this.node.path}; provide 'sourceArn' in fromFlowAttributes()`, this);
484
+ }
485
+ get egressIp() {
486
+ if (attrs.egressIp)
487
+ return attrs.egressIp;
488
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `EgressIpNotProvided`, `'egressIp' was not provided when importing Flow ${this.node.path}; provide it in fromFlowAttributes()`, this);
489
+ }
490
+ get sourceIngestIp() {
491
+ if (attrs.sourceIngestIp)
492
+ return attrs.sourceIngestIp;
493
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `SourceIngestIpNotProvided`, `'sourceIngestIp' was not provided when importing Flow ${this.node.path}; provide it in fromFlowAttributes()`, this);
494
+ }
495
+ get sourceIngestPort() {
496
+ if (attrs.sourceIngestPort)
497
+ return attrs.sourceIngestPort;
498
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `SourceIngestPortNotProvided`, `'sourceIngestPort' was not provided when importing Flow ${this.node.path}; provide it in fromFlowAttributes()`, this);
499
+ }
500
+ get sourceIngestUrl() {
501
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `SourceIngestUrlNotAvailableImported`, `'sourceIngestUrl' is not available on imported Flow ${this.node.path}; only Flows constructed in this app for listener-style source protocols (RTP, RTP-FEC, RIST, SRT listener, Zixi push) expose a source ingest URL`, this);
502
+ }
503
+ }
504
+ return new Import(scope, id);
505
+ }
506
+ /**
507
+ * Import an existing Flow from its ARN.
508
+ *
509
+ * Use `fromFlowAttributes()` instead if you need access to `sourceArn` or any other
510
+ * attribute not encoded in the flow ARN.
511
+ */
512
+ static fromFlowArn(scope, id, flowArn) {
513
+ return Flow.fromFlowAttributes(scope, id, { flowArn });
514
+ }
515
+ /**
516
+ * The NDI state for this flow. `undefined` for imported flows (state is unknown).
517
+ * @internal
518
+ */
519
+ _ndiState;
520
+ /**
521
+ * The source protocol value for this flow. `undefined` for imported flows.
522
+ * @internal
523
+ */
524
+ _sourceProtocol;
525
+ /**
526
+ * Tracks the number of NDI outputs added to this flow. Used to enforce the
527
+ * documented "max 1 NDI output per flow" limit.
528
+ * @internal
529
+ */
530
+ _ndiOutputCount = 0;
531
+ /**
532
+ * Collection of grant methods for this flow.
533
+ */
534
+ grants = mediaconnect_grants_generated_1.FlowGrants.fromFlow(this);
535
+ /**
536
+ * A reference to this Flow resource.
537
+ * Required by the auto-generated IFlowRef interface.
538
+ */
539
+ get flowRef() {
540
+ return {
541
+ flowArn: this.flowArn,
542
+ };
543
+ }
544
+ /**
545
+ * Add an output to this flow
546
+ */
547
+ addOutput(id, outputConfig) {
548
+ const protocol = outputConfig._bind().protocol;
549
+ if (protocol === 'ndi-speed-hq') {
550
+ if (this._ndiState !== undefined && this._ndiState !== shared_1.State.ENABLED) {
551
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `NdiOutputRequiresNdiConfig`, 'NDI outputs require ndiConfig with ndiState set to State.ENABLED on the flow', this);
552
+ }
553
+ // NDI passthrough is not supported — a flow cannot have both an NDI source
554
+ // and an NDI output. The service rejects this at deploy; fail fast here.
555
+ if (this._sourceProtocol === flow_source_configuration_1.SourceProtocol.NDI_SPEED_HQ.value) {
556
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `NdiPassthroughNotSupported`, 'NDI passthrough is not supported. A flow cannot have both an NDI source and an NDI output', this);
557
+ }
558
+ // A flow supports a maximum of 1 NDI output (Large flow size, transport
559
+ // stream protocols + 1 NDI output).
560
+ // @see https://docs.aws.amazon.com/mediaconnect/latest/ug/flow-sizes-capabilities.html
561
+ if (this._ndiOutputCount >= 1) {
562
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `NdiOutputLimit`, 'A flow supports a maximum of 1 NDI output', this);
563
+ }
564
+ this._ndiOutputCount++;
565
+ }
566
+ return new flow_output_1.FlowOutput(this, id, {
567
+ flow: this,
568
+ output: outputConfig,
569
+ });
570
+ }
571
+ /**
572
+ * Create a CloudWatch metric for this flow.
573
+ */
574
+ metric(metricName, props) {
575
+ return new aws_cloudwatch_1.Metric({
576
+ metricName,
577
+ namespace: 'AWS/MediaConnect',
578
+ dimensionsMap: {
579
+ FlowARN: this.flowArn,
580
+ },
581
+ ...props,
582
+ }).attachTo(this);
583
+ }
584
+ /**
585
+ * Metric for the bitrate of content ingested into the flow.
586
+ *
587
+ * Emits the `SourceBitRate` metric with dimension `FlowARN`, which aggregates across
588
+ * all sources on the flow. To narrow to a specific source on a multi-source flow, call
589
+ * {@link metric} with an additional `SourceARN` dimension.
590
+ *
591
+ * @default - average over 60 seconds
592
+ */
593
+ metricSourceBitrate(props) {
594
+ return this.metric('SourceBitRate', {
595
+ statistic: 'avg',
596
+ period: aws_cdk_lib_1.Duration.seconds(60),
597
+ unit: aws_cloudwatch_1.Unit.BITS_PER_SECOND,
598
+ ...props,
599
+ });
600
+ }
601
+ /**
602
+ * Metric for packets that were lost in transit and not recovered by error correction.
603
+ *
604
+ * Emits the `SourceNotRecoveredPackets` metric with dimension `FlowARN`, which aggregates
605
+ * across all sources on the flow.
606
+ *
607
+ * @default - sum over 60 seconds
608
+ */
609
+ metricSourceNotRecoveredPackets(props) {
610
+ return this.metric('SourceNotRecoveredPackets', {
611
+ statistic: 'sum',
612
+ period: aws_cdk_lib_1.Duration.seconds(60),
613
+ unit: aws_cloudwatch_1.Unit.COUNT,
614
+ ...props,
615
+ });
616
+ }
617
+ /**
618
+ * Metric for the total number of packets received by the flow sources.
619
+ *
620
+ * Emits the `SourceTotalPackets` metric with dimension `FlowARN`, which aggregates across
621
+ * all sources on the flow.
622
+ *
623
+ * @default - sum over 60 seconds
624
+ */
625
+ metricSourceTotalPackets(props) {
626
+ return this.metric('SourceTotalPackets', {
627
+ statistic: 'sum',
628
+ period: aws_cdk_lib_1.Duration.seconds(60),
629
+ unit: aws_cloudwatch_1.Unit.COUNT,
630
+ ...props,
631
+ });
632
+ }
633
+ /**
634
+ * Metric indicating which source is selected for ingest when using `Failover` failover mode.
635
+ * A value of 1 indicates the source is being used as the input; 0 indicates it is standby.
636
+ *
637
+ * Emits the `SourceSelected` metric with dimension `FlowARN`. To narrow to a specific source,
638
+ * call {@link metric} with an additional `SourceARN` dimension.
639
+ *
640
+ * @default - maximum over 60 seconds
641
+ */
642
+ metricSourceSelected(props) {
643
+ return this.metric('SourceSelected', {
644
+ statistic: 'max',
645
+ period: aws_cdk_lib_1.Duration.seconds(60),
646
+ unit: aws_cloudwatch_1.Unit.NONE,
647
+ ...props,
648
+ });
649
+ }
650
+ /**
651
+ * Metric indicating the connection state of the source. 1 for connected, 0 for disconnected.
652
+ * Applies only to Zixi, SRT, and RIST sources.
653
+ *
654
+ * Emits the `SourceConnected` metric with dimension `FlowARN`.
655
+ *
656
+ * @default - minimum over 60 seconds
657
+ */
658
+ metricSourceConnected(props) {
659
+ return this.metric('SourceConnected', {
660
+ statistic: 'min',
661
+ period: aws_cdk_lib_1.Duration.seconds(60),
662
+ unit: aws_cloudwatch_1.Unit.NONE,
663
+ ...props,
664
+ });
665
+ }
666
+ /**
667
+ * Metric for the number of times the source transitioned from connected to disconnected.
668
+ *
669
+ * Emits the `SourceDisconnections` metric with dimension `FlowARN`.
670
+ *
671
+ * @default - sum over 60 seconds
672
+ */
673
+ metricSourceDisconnections(props) {
674
+ return this.metric('SourceDisconnections', {
675
+ statistic: 'sum',
676
+ period: aws_cdk_lib_1.Duration.seconds(60),
677
+ unit: aws_cloudwatch_1.Unit.COUNT,
678
+ ...props,
679
+ });
680
+ }
681
+ /**
682
+ * Metric for the number of packets lost during transit, measured before any error
683
+ * correction takes place.
684
+ *
685
+ * Emits the `SourceDroppedPackets` metric with dimension `FlowARN`.
686
+ *
687
+ * @default - sum over 60 seconds
688
+ */
689
+ metricSourceDroppedPackets(props) {
690
+ return this.metric('SourceDroppedPackets', {
691
+ statistic: 'sum',
692
+ period: aws_cdk_lib_1.Duration.seconds(60),
693
+ unit: aws_cloudwatch_1.Unit.COUNT,
694
+ ...props,
695
+ });
696
+ }
697
+ /**
698
+ * Metric for the percentage of packets lost during transit, even if they were recovered.
699
+ *
700
+ * Emits the `SourcePacketLossPercent` metric with dimension `FlowARN`.
701
+ *
702
+ * @default - average over 60 seconds
703
+ */
704
+ metricSourcePacketLossPercent(props) {
705
+ return this.metric('SourcePacketLossPercent', {
706
+ statistic: 'avg',
707
+ period: aws_cdk_lib_1.Duration.seconds(60),
708
+ unit: aws_cloudwatch_1.Unit.PERCENT,
709
+ ...props,
710
+ });
711
+ }
712
+ /**
713
+ * Metric for the round-trip time between the source and MediaConnect. Applies only to
714
+ * RIST, Zixi, and SRT sources.
715
+ *
716
+ * Emits the `SourceRoundTripTime` metric with dimension `FlowARN`.
717
+ *
718
+ * @default - average over 60 seconds
719
+ */
720
+ metricSourceRoundTripTime(props) {
721
+ return this.metric('SourceRoundTripTime', {
722
+ statistic: 'avg',
723
+ period: aws_cdk_lib_1.Duration.seconds(60),
724
+ unit: aws_cloudwatch_1.Unit.MILLISECONDS,
725
+ ...props,
726
+ });
727
+ }
728
+ /**
729
+ * Metric for the current network jitter of the source, measured in milliseconds.
730
+ *
731
+ * Emits the `SourceJitter` metric with dimension `FlowARN`.
732
+ *
733
+ * @default - average over 60 seconds
734
+ */
735
+ metricSourceJitter(props) {
736
+ return this.metric('SourceJitter', {
737
+ statistic: 'avg',
738
+ period: aws_cdk_lib_1.Duration.seconds(60),
739
+ unit: aws_cloudwatch_1.Unit.MILLISECONDS,
740
+ ...props,
741
+ });
742
+ }
743
+ }
744
+ /**
745
+ * Defines an AWS Elemental MediaConnect Flow.
746
+ */
747
+ let Flow = (() => {
748
+ let _classDecorators = [prop_injectable_1.propertyInjectable];
749
+ let _classDescriptor;
750
+ let _classExtraInitializers = [];
751
+ let _classThis;
752
+ let _classSuper = FlowBase;
753
+ let _instanceExtraInitializers = [];
754
+ let _addVpcInterface_decorators;
755
+ var Flow = class extends _classSuper {
756
+ static { _classThis = this; }
757
+ static {
758
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
759
+ _addVpcInterface_decorators = [(0, metadata_resource_1.MethodMetadata)()];
760
+ __esDecorate(this, null, _addVpcInterface_decorators, { kind: "method", name: "addVpcInterface", static: false, private: false, access: { has: obj => "addVpcInterface" in obj, get: obj => obj.addVpcInterface }, metadata: _metadata }, null, _instanceExtraInitializers);
761
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
762
+ Flow = _classThis = _classDescriptor.value;
763
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
764
+ }
765
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-mediaconnect-alpha.Flow", version: "2.263.0-alpha.0" };
766
+ /** Uniquely identifies this class. */
767
+ static PROPERTY_INJECTION_ID = '@aws-cdk.aws-mediaconnect-alpha.Flow';
768
+ /**
769
+ * The set of source protocols where the flow opens an IP:port and listens for
770
+ * upstream content. Determines availability of `sourceIngestIp`, `sourceIngestPort`,
771
+ * and `sourceIngestUrl`. Maps each protocol to the URL scheme used to construct
772
+ * the ingest URL.
773
+ */
774
+ static LISTENER_PROTOCOL_SCHEMES = new Map([
775
+ ['rtp', 'rtp'],
776
+ ['rtp-fec', 'rtp'],
777
+ ['rist', 'rist'],
778
+ ['srt-listener', 'srt'],
779
+ ['zixi-push', 'zixi'],
780
+ ]);
781
+ static isListenerStyleProtocol(protocol) {
782
+ return protocol !== undefined && Flow.LISTENER_PROTOCOL_SCHEMES.has(protocol);
783
+ }
784
+ flowArn = __runInitializers(this, _instanceExtraInitializers);
785
+ sourceArn;
786
+ egressIp;
787
+ _sourceIngestIp;
788
+ _sourceIngestPort;
789
+ _hasListenerSource;
790
+ flowAvailabilityZone;
791
+ isFailoverEnabled = false;
792
+ vpcInterfaces = [];
793
+ get sourceIngestIp() {
794
+ if (!this._hasListenerSource) {
795
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `SourceIngestIpNotAvailableSourceProtocol`, `'sourceIngestIp' is not available on this Flow ${this.node.path}; only listener-style source protocols (RTP, RTP-FEC, RIST, SRT listener, Zixi push) expose a source ingest IP — CDI, JPEG XS, entitlement, gateway bridge, router, and SRT caller sources do not`, this);
796
+ }
797
+ return this._sourceIngestIp;
798
+ }
799
+ get sourceIngestPort() {
800
+ if (!this._hasListenerSource) {
801
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `SourceIngestPortNotAvailableSourceProtocol`, `'sourceIngestPort' is not available on this Flow ${this.node.path}; only listener-style source protocols (RTP, RTP-FEC, RIST, SRT listener, Zixi push) expose a source ingest port — CDI, JPEG XS, entitlement, gateway bridge, router, and SRT caller sources do not`, this);
802
+ }
803
+ return this._sourceIngestPort;
804
+ }
805
+ get sourceIngestUrl() {
806
+ if (!this._hasListenerSource) {
807
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `SourceIngestUrlNotAvailableSourceProtocol`, `'sourceIngestUrl' is not available on this Flow ${this.node.path}; only listener-style source protocols (RTP, RTP-FEC, RIST, SRT listener, Zixi push) expose a source ingest URL — CDI, JPEG XS, entitlement, gateway bridge, router, and SRT caller sources do not`, this);
808
+ }
809
+ return this.computeIngestUrl(this._sourceProtocol, this._sourceIngestIp, this._sourceIngestPort);
810
+ }
811
+ constructor(scope, id, props) {
812
+ super(scope, id, {
813
+ physicalName: props?.flowName ?? aws_cdk_lib_1.Lazy.string({ produce: () => aws_cdk_lib_1.Names.uniqueResourceName(this, { maxLength: 64 }) }),
814
+ });
815
+ try {
816
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_FlowProps(props);
817
+ }
818
+ catch (error) {
819
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
820
+ Error.captureStackTrace(error, Flow);
821
+ }
822
+ throw error;
823
+ }
824
+ // Validate flow name if provided
825
+ this.validateName(props);
826
+ // Enhanced CDK Analytics Telemetry
827
+ (0, metadata_resource_1.addConstructMetadata)(this, props);
828
+ // Validate maintenance start hour format
829
+ if (props.maintenance) {
830
+ (0, shared_1.validateMaintenanceTime)(props.maintenance.maintenanceStartHour);
831
+ }
832
+ // Validate source monitoring thresholds and content-quality requirements
833
+ this.validateMonitoring(props);
834
+ // Validate encoding config video max bitrate range (10-50 Mbps)
835
+ this.validateEncoding(props);
836
+ // Only iterate a known-concrete vpcInterfaces list; skip tokenized lists to avoid
837
+ // pushing the token marker into our internal collection.
838
+ if (props.vpcInterfaces !== undefined && !aws_cdk_lib_1.Token.isUnresolved(props.vpcInterfaces)) {
839
+ props.vpcInterfaces.forEach(vpc => this.addVpcInterface(vpc));
840
+ }
841
+ this.isFailoverEnabled = props.sourceFailoverConfig?._isEnabled ?? false;
842
+ const sourceConfig = props.source._bind(this, aws_cdk_lib_1.Stack.of(this).formatArn({
843
+ service: 'mediaconnect',
844
+ resource: 'flow',
845
+ resourceName: `*:${this.physicalName}`,
846
+ arnFormat: aws_cdk_lib_1.ArnFormat.COLON_RESOURCE_NAME,
847
+ }));
848
+ if ((sourceConfig.protocol === flow_source_configuration_1.SourceProtocol.JPEGXS.value || sourceConfig.protocol === flow_source_configuration_1.SourceProtocol.CDI.value)
849
+ && props.flowSize?.value !== FlowSize.LARGE_4X.value) {
850
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `FlowSizeRequired`, 'Flows using JPEG XS and CDI protocols require LARGE_4X flow size; set flowSize to FlowSize.LARGE_4X', this);
851
+ }
852
+ // NDI constraints (discovery server limit, protocol conflicts, flow size, source requirements)
853
+ this.validateNdi(props, sourceConfig);
854
+ // LARGE_4X only supports CDI and JPEG XS protocols
855
+ if (props.flowSize?.value === FlowSize.LARGE_4X.value
856
+ && sourceConfig.protocol !== flow_source_configuration_1.SourceProtocol.JPEGXS.value
857
+ && sourceConfig.protocol !== flow_source_configuration_1.SourceProtocol.CDI.value) {
858
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `FlowSizeLarge4xProtocol`, 'LARGE_4X flow size only supports CDI and JPEG XS protocols', this);
859
+ }
860
+ // VPC interface EFA-count limit
861
+ this.validateVpcEfaCount(props);
862
+ const flow = new aws_mediaconnect_1.CfnFlow(this, 'Resource', {
863
+ name: this.physicalName,
864
+ source: sourceConfig,
865
+ availabilityZone: props?.availabilityZone,
866
+ flowSize: props?.flowSize?.value,
867
+ maintenance: props?.maintenance ? {
868
+ maintenanceDay: (0, shared_1.toTitleCase)(props.maintenance.maintenanceDay),
869
+ maintenanceStartHour: props.maintenance.maintenanceStartHour,
870
+ } : undefined,
871
+ mediaStreams: props.mediaStreams ? props.mediaStreams.map(stream => stream._bind()) : undefined,
872
+ ndiConfig: props.ndiConfig ? {
873
+ machineName: props.ndiConfig.machineName,
874
+ ndiState: props.ndiConfig.ndiState,
875
+ ndiDiscoveryServers: props.ndiConfig.ndiDiscoveryServers?.map(server => ({
876
+ discoveryServerAddress: server.discoveryServerAddress,
877
+ discoveryServerPort: server.discoveryServerPort,
878
+ vpcInterfaceAdapter: server.vpcInterface.name,
879
+ })),
880
+ } : undefined,
881
+ encodingConfig: props.encodingConfig ? {
882
+ encodingProfile: props.encodingConfig.encodingProfile,
883
+ videoMaxBitrate: props.encodingConfig.videoMaxBitrate?.toBps(),
884
+ } : undefined,
885
+ sourceFailoverConfig: props.sourceFailoverConfig?._bind(),
886
+ sourceMonitoringConfig: props.sourceMonitoringConfig ? {
887
+ contentQualityAnalysisState: props.sourceMonitoringConfig.contentQualityAnalysisState,
888
+ thumbnailState: props.sourceMonitoringConfig.thumbnailState,
889
+ audioMonitoringSettings: props.sourceMonitoringConfig.silentAudio ? [{
890
+ silentAudio: {
891
+ state: props.sourceMonitoringConfig.silentAudio.state,
892
+ thresholdSeconds: props.sourceMonitoringConfig.silentAudio.threshold.toSeconds(),
893
+ },
894
+ }] : undefined,
895
+ videoMonitoringSettings: props.sourceMonitoringConfig.blackFrames || props.sourceMonitoringConfig.frozenFrames ? [{
896
+ blackFrames: props.sourceMonitoringConfig.blackFrames ? {
897
+ state: props.sourceMonitoringConfig.blackFrames.state,
898
+ thresholdSeconds: props.sourceMonitoringConfig.blackFrames.threshold.toSeconds(),
899
+ } : undefined,
900
+ frozenFrames: props.sourceMonitoringConfig.frozenFrames ? {
901
+ state: props.sourceMonitoringConfig.frozenFrames.state,
902
+ thresholdSeconds: props.sourceMonitoringConfig.frozenFrames.threshold.toSeconds(),
903
+ } : undefined,
904
+ }] : undefined,
905
+ } : undefined,
906
+ vpcInterfaces: aws_cdk_lib_1.Lazy.any({ produce: () => this.vpcInterfaces }, { omitEmptyArray: true }),
907
+ });
908
+ this.flowArn = flow.attrFlowArn;
909
+ this.sourceArn = flow.attrSourceSourceArn;
910
+ this.egressIp = flow.attrEgressIp;
911
+ this._sourceIngestIp = flow.attrSourceIngestIp;
912
+ this._sourceIngestPort = flow.attrSourceSourceIngestPort;
913
+ this.flowAvailabilityZone = flow.attrFlowAvailabilityZone;
914
+ this._ndiState = props.ndiConfig?.ndiState ?? shared_1.State.DISABLED;
915
+ this._sourceProtocol = sourceConfig.protocol;
916
+ this._hasListenerSource = Flow.isListenerStyleProtocol(sourceConfig.protocol);
917
+ this.node.addValidation({
918
+ validate: () => {
919
+ const names = this.vpcInterfaces.map(v => v.name).filter(n => !aws_cdk_lib_1.Token.isUnresolved(n));
920
+ const duplicates = [...new Set(names.filter((n, i) => names.indexOf(n) !== i))];
921
+ return duplicates.length > 0
922
+ ? [`VPC interface names must be unique within a flow. Duplicate name(s): ${duplicates.join(', ')}`]
923
+ : [];
924
+ },
925
+ });
926
+ }
927
+ /** Validate the flow name length and character set, when a concrete value is provided. */
928
+ validateName(props) {
929
+ if (props.flowName != null && props.flowName !== '' && !aws_cdk_lib_1.Token.isUnresolved(props.flowName)) {
930
+ if (props.flowName.length > 64) {
931
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `FlowNameLength`, `Flow name must be between 1 and 64 characters, got ${props.flowName.length}`, this);
932
+ }
933
+ if (!/^[a-zA-Z0-9_-]+$/.test(props.flowName)) {
934
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `FlowNameFormat`, `Flow name must contain only alphanumeric characters, hyphens, and underscores, got '${props.flowName}'`, this);
935
+ }
936
+ }
937
+ }
938
+ /**
939
+ * Validate source-monitoring thresholds (10-60 seconds) and that the per-metric checks are only
940
+ * used when content-quality analysis is enabled.
941
+ */
942
+ validateMonitoring(props) {
943
+ const monitoring = props.sourceMonitoringConfig;
944
+ if (monitoring && (monitoring.silentAudio || monitoring.blackFrames || monitoring.frozenFrames)
945
+ && monitoring.contentQualityAnalysisState !== shared_1.State.ENABLED) {
946
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `MonitoringMetricsRequireContentQualityAnalysis`, 'silentAudio, blackFrames, and frozenFrames require contentQualityAnalysisState to be State.ENABLED', this);
947
+ }
948
+ if (monitoring?.silentAudio) {
949
+ const secs = monitoring.silentAudio.threshold.toSeconds();
950
+ if (secs < 10 || secs > 60) {
951
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `SilentAudioThresholdRange`, `Silent audio threshold must be between 10 and 60 seconds, got ${secs}`, this);
952
+ }
953
+ }
954
+ if (monitoring?.blackFrames) {
955
+ const secs = monitoring.blackFrames.threshold.toSeconds();
956
+ if (secs < 10 || secs > 60) {
957
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `BlackFramesThresholdRange`, `Black frames threshold must be between 10 and 60 seconds, got ${secs}`, this);
958
+ }
959
+ }
960
+ if (monitoring?.frozenFrames) {
961
+ const secs = monitoring.frozenFrames.threshold.toSeconds();
962
+ if (secs < 10 || secs > 60) {
963
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `FrozenFramesThresholdRange`, `Frozen frames threshold must be between 10 and 60 seconds, got ${secs}`, this);
964
+ }
965
+ }
966
+ }
967
+ /** Validate the encoding config's video max bitrate range (10-50 Mbps). */
968
+ validateEncoding(props) {
969
+ if (props.encodingConfig?.videoMaxBitrate) {
970
+ const mbps = props.encodingConfig.videoMaxBitrate.toMbps();
971
+ if (mbps < 10 || mbps > 50) {
972
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `EncodingVideoMaxBitrateRange`, `Encoding config videoMaxBitrate must be between 10 and 50 Mbps, got ${mbps}`, this);
973
+ }
974
+ }
975
+ }
976
+ /**
977
+ * Validate NDI constraints: discovery-server limit, mutual exclusivity with CDI/JPEG XS, the
978
+ * required LARGE flow size, and the requirements an NDI source places on the flow.
979
+ */
980
+ validateNdi(props, sourceConfig) {
981
+ // NDI discovery servers limit (service rejects >3 at deploy time)
982
+ const discoveryServers = props.ndiConfig?.ndiDiscoveryServers;
983
+ if (discoveryServers !== undefined && !aws_cdk_lib_1.Token.isUnresolved(discoveryServers) && discoveryServers.length > 3) {
984
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `NdiMaxDiscoveryServers`, `NDI config supports a maximum of 3 discovery servers, got ${discoveryServers.length}`, this);
985
+ }
986
+ // NDI cannot coexist with CDI or JPEG XS — they require different flow sizes
987
+ if (props.ndiConfig?.ndiState === shared_1.State.ENABLED
988
+ && (sourceConfig.protocol === flow_source_configuration_1.SourceProtocol.CDI.value || sourceConfig.protocol === flow_source_configuration_1.SourceProtocol.JPEGXS.value)) {
989
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `NdiCdiConflict`, 'NDI cannot be used with CDI or JPEG XS protocols; NDI requires LARGE flow size while CDI and JPEG XS require LARGE_4X', this);
990
+ }
991
+ // NDI requires LARGE flow size (not MEDIUM, not LARGE_4X)
992
+ if (props.ndiConfig?.ndiState === shared_1.State.ENABLED
993
+ && props.flowSize?.value !== FlowSize.LARGE.value) {
994
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `NdiFlowSizeRequired`, 'NDI requires LARGE flow size; set flowSize to FlowSize.LARGE', this);
995
+ }
996
+ // NDI sources require NDI to be enabled on the flow
997
+ if (sourceConfig.protocol === flow_source_configuration_1.SourceProtocol.NDI_SPEED_HQ.value
998
+ && props.ndiConfig?.ndiState !== shared_1.State.ENABLED) {
999
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `NdiSourceRequiresNdiConfig`, 'NDI sources require ndiConfig with ndiState set to State.ENABLED', this);
1000
+ }
1001
+ // NDI sources require LARGE flow size
1002
+ if (sourceConfig.protocol === flow_source_configuration_1.SourceProtocol.NDI_SPEED_HQ.value
1003
+ && props.flowSize?.value !== FlowSize.LARGE.value) {
1004
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `NdiSourceFlowSizeRequired`, 'NDI sources require LARGE flow size; set flowSize to FlowSize.LARGE', this);
1005
+ }
1006
+ // NDI sources require encodingConfig to transcode into a transport stream
1007
+ if (sourceConfig.protocol === flow_source_configuration_1.SourceProtocol.NDI_SPEED_HQ.value
1008
+ && !props.encodingConfig) {
1009
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `NdiSourceRequiresEncodingConfig`, 'NDI sources require encodingConfig to transcode the NDI source into a transport stream', this);
1010
+ }
1011
+ }
1012
+ /** Validate the EFA VPC-interface count (at most one), when the list is concrete. */
1013
+ validateVpcEfaCount(props) {
1014
+ // Skip EFA-count validation when the user passed a tokenized vpcInterfaces list;
1015
+ // we can't inspect individual entries in that case.
1016
+ const efaCount = props.vpcInterfaces !== undefined && !aws_cdk_lib_1.Token.isUnresolved(props.vpcInterfaces)
1017
+ ? props.vpcInterfaces.filter(vpc => vpc.networkInterfaceType?.value === shared_1.NetworkInterface.EFA.value).length
1018
+ : 0;
1019
+ if (efaCount > 1) {
1020
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `FlowMaxEfaInterfaces`, `A flow can have a maximum of 1 EFA VPC interface, got ${efaCount}`, this);
1021
+ }
1022
+ }
1023
+ /**
1024
+ * Build the URL for a listener-style source protocol. The caller must have already
1025
+ * checked `_hasListenerSource`; this method assumes the protocol is in
1026
+ * `LISTENER_PROTOCOL_SCHEMES` and throws an unscoped error otherwise.
1027
+ */
1028
+ computeIngestUrl(protocol, ip, port) {
1029
+ const scheme = protocol === undefined ? undefined : Flow.LISTENER_PROTOCOL_SCHEMES.get(protocol);
1030
+ if (scheme === undefined) {
1031
+ throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `SourceIngestUrlComputeNotListener`, `internal: computeIngestUrl called for non-listener protocol '${protocol}'`);
1032
+ }
1033
+ return aws_cdk_lib_1.Fn.join('', [`${scheme}://`, ip, ':', port]);
1034
+ }
1035
+ /**
1036
+ * Add a VPC interface to this flow.
1037
+ */
1038
+ addVpcInterface(vpc) {
1039
+ try {
1040
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_VpcInterfaceConfig(vpc);
1041
+ }
1042
+ catch (error) {
1043
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
1044
+ Error.captureStackTrace(error, this.addVpcInterface);
1045
+ }
1046
+ throw error;
1047
+ }
1048
+ this.vpcInterfaces.push({
1049
+ name: vpc.name,
1050
+ networkInterfaceIds: vpc.networkInterfaceIds,
1051
+ networkInterfaceType: vpc.networkInterfaceType?.value,
1052
+ securityGroupIds: vpc.securityGroups.map(sg => sg.securityGroupId),
1053
+ subnetId: vpc.subnet.subnetId,
1054
+ roleArn: vpc.role.roleArn,
1055
+ });
1056
+ return vpc;
1057
+ }
1058
+ static {
1059
+ __runInitializers(_classThis, _classExtraInitializers);
1060
+ }
1061
+ };
1062
+ return Flow = _classThis;
1063
+ })();
1064
+ exports.Flow = Flow;
1065
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmxvdy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImZsb3cudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQ0EsNkNBQXFJO0FBRXJJLCtEQUEwRDtBQUMxRCxtRUFBdUQ7QUFFdkQsNEVBQTREO0FBQzVELDhFQUE4RjtBQUM5RiwwRUFBMEU7QUFHMUUsK0NBQTJDO0FBRTNDLDJFQUE2RDtBQUM3RCxtRkFBNkQ7QUFFN0QscUNBQXVHO0FBd0p2Rzs7R0FFRztBQUNILE1BQWEsUUFBUTtJQTZCaUI7O0lBNUJwQzs7Ozs7T0FLRztJQUNJLE1BQU0sQ0FBVSxNQUFNLEdBQUcsSUFBSSxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDdkQ7Ozs7O09BS0c7SUFDSSxNQUFNLENBQVUsS0FBSyxHQUFHLElBQUksUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3JEOztPQUVHO0lBQ0ksTUFBTSxDQUFVLFFBQVEsR0FBRyxJQUFJLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUUzRDs7O09BR0c7SUFDSSxNQUFNLENBQUMsRUFBRSxDQUFDLEtBQWE7UUFDNUIsT0FBTyxJQUFJLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztLQUM1QjtJQUVELDhDQUE4QztJQUM5QyxZQUFvQyxLQUFhO1FBQWIsVUFBSyxHQUFMLEtBQUssQ0FBUTtLQUFJO0lBRXJELCtCQUErQjtJQUN4QixRQUFRO1FBQ2IsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDO0tBQ25COztBQWxDSCw0QkFtQ0M7QUE0REQ7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFhLGNBQWM7SUF1Qk47SUFDQTtJQUNBO0lBQ0E7O0lBekJuQjs7T0FFRztJQUNJLE1BQU0sQ0FBQyxLQUFLLENBQUMsVUFBZ0MsRUFBRTs7Ozs7Ozs7OztRQUNwRCxJQUFJLE9BQU8sQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUMzQixNQUFNLEVBQUUsR0FBRyxPQUFP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S0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDekIsTUFBTSxJQUFJLHFDQUF1QixDQUMvQixJQUFBLHNCQUFHLEVBQUEsbUNBQW1DLEVBQ3RDLGdFQUFnRSxRQUFRLEdBQUcsQ0FDNUUsQ0FBQztZQUNKLENBQUM7WUFDRCxPQUFPLGdCQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsTUFBTSxLQUFLLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO1NBQ3JEO1FBRUQ7O1dBRUc7UUFFSSxlQUFlLENBQUMsR0FBdUI7Ozs7Ozs7Ozs7WUFDNUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUM7Z0JBQ3RCLElBQUksRUFBRSxHQUFHLENBQUMsSUFBSTtnQkFDZCxtQkFBbUIsRUFBRSxHQUFHLENBQUMsbUJBQW1CO2dCQUM1QyxvQkFBb0IsRUFBRSxHQUFHLENBQUMsb0JBQW9CLEVBQUUsS0FBSztnQkFDckQsZ0JBQWdCLEVBQUUsR0FBRyxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsZUFBZSxDQUFDO2dCQUNsRSxRQUFRLEVBQUUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRO2dCQUM3QixPQUFPLEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPO2FBQzFCLENBQUMsQ0FBQztZQUNILE9BQU8sR0FBRyxDQUFDO1NBQ1o7O1lBaFhVLHVEQUFJOzs7OztBQUFKLG9CQUFJIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBCaXRyYXRlLCBJUmVzb3VyY2UgfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBBcm5Gb3JtYXQsIFJlc291cmNlLCBMYXp5LCBOYW1lcywgRHVyYXRpb24sIFN0YWNrLCBUb2tlbiwgRm4sIFVuc2NvcGVkVmFsaWRhdGlvbkVycm9yLCBWYWxpZGF0aW9uRXJyb3IgfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgdHlwZSB7IE1ldHJpY09wdGlvbnMgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtY2xvdWR3YXRjaCc7XG5pbXBvcnQgeyBNZXRyaWMsIFVuaXQgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtY2xvdWR3YXRjaCc7XG5pbXBvcnQgeyBDZm5GbG93IH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLW1lZGlhY29ubmVjdCc7XG5pbXBvcnQgdHlwZSB7IElGbG93UmVmLCBGbG93UmVmZXJlbmNlIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLW1lZGlhY29ubmVjdCc7XG5pbXBvcnQgeyBsaXQgfSBmcm9tICdhd3MtY2RrLWxpYi9jb3JlL2xpYi9oZWxwZXJzLWludGVybmFsJztcbmltcG9ydCB7IGFkZENvbnN0cnVjdE1ldGFkYXRhLCBNZXRob2RNZXRhZGF0YSB9IGZyb20gJ2F3cy1jZGstbGliL2NvcmUvbGliL21ldGFkYXRhLXJlc291cmNlJztcbmltcG9ydCB7IHByb3BlcnR5SW5qZWN0YWJsZSB9IGZyb20gJ2F3cy1jZGstbGliL2NvcmUvbGliL3Byb3AtaW5qZWN0YWJsZSc7XG5pbXBvcnQgdHlwZSB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHR5cGUgeyBJRmxvd091dHB1dCwgT3V0cHV0Q29uZmlndXJhdGlvbiB9IGZyb20gJy4vZmxvdy1vdXRwdXQnO1xuaW1wb3J0IHsgRmxvd091dHB1dCB9IGZyb20gJy4vZmxvdy1vdXRwdXQnO1xuaW1wb3J0IHR5cGUgeyBTb3VyY2VDb25maWd1cmF0aW9uIH0gZnJvbSAnLi9mbG93LXNvdXJjZS1jb25maWd1cmF0aW9uJztcbmltcG9ydCB7IFNvdXJjZVByb3RvY29sIH0gZnJvbSAnLi9mbG93LXNvdXJjZS1jb25maWd1cmF0aW9uJztcbmltcG9ydCB7IEZsb3dHcmFudHMgfSBmcm9tICcuL21lZGlhY29ubmVjdC1ncmFudHMuZ2VuZXJhdGVkJztcbmltcG9ydCB0eXBlIHsgVnBjSW50ZXJmYWNlQ29uZmlnLCBNYWludGVuYW5jZURheSwgRnJhbWVyYXRlLCBQaXhlbEFzcGVjdFJhdGlvIH0gZnJvbSAnLi9zaGFyZWQnO1xuaW1wb3J0IHsgRmFpbG92ZXJNb2RlLCBOZXR3b3JrSW50ZXJmYWNlLCBTdGF0ZSwgdG9UaXRsZUNhc2UsIHZhbGlkYXRlTWFpbnRlbmFuY2VUaW1lIH0gZnJvbSAnLi9zaGFyZWQnO1xuXG4vKipcbiAqIEludGVyZmFjZSBmb3IgRmxvd1xuICovXG5leHBvcnQgaW50ZXJmYWNlIElGbG93IGV4dGVuZHMgSVJlc291cmNlLCBJRmxvd1JlZiB7XG5cbiAgLyoqXG4gICAqIFRoZSBBbWF6b24gUmVzb3VyY2UgTmFtZSAoQVJOKSBvZiB0aGUgZmxvdy5cbiAgICpcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcmVhZG9ubHkgZmxvd0Fybjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgQW1hem9uIFJlc291cmNlIE5hbWUgKEFSTikgb2YgdGhlIHNvdXJjZSBkZWZpbmVkIG9uIHRoZSBmbG93LlxuICAgKlxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICByZWFkb25seSBzb3VyY2VBcm46IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIElQIGFkZHJlc3MgdGhhdCB0aGUgZmxvdyB1c2VzIHRvIHNlbmQgb3V0Ym91bmQgY29udGVudC5cbiAgICpcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcmVhZG9ubHkgZWdyZXNzSXA6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIElQIGFkZHJlc3MgdGhhdCB0aGUgZmxvdyBsaXN0ZW5zIG9uIGZvciBpbmNvbWluZyBjb250ZW50LlxuICAgKlxuICAgKiBBdmFpbGFibGUgZm9yIGxpc3RlbmVyLXN0eWxlIHNvdXJjZSBwcm90b2NvbHMgKFJUUCwgUlRQLUZFQywgUklTVCwgU1JUIGxpc3RlbmVyLFxuICAgKiBaaXhpIHB1c2gpLiBBY2Nlc3NpbmcgdGhpcyBvbiBTUlQgY2FsbGVyLCBlbnRpdGxlbWVudCwgZ2F0ZXdheSBicmlkZ2UsIHJvdXRlcixcbiAgICogQ0RJLCBKUEVHIFhTLCBvciBpbXBvcnRlZCBmbG93cyB0aHJvd3Mg4oCUIHRob3NlIHNvdXJjZXMgZG9uJ3QgZXhwb3NlIGEgbGlzdGVuaW5nXG4gICAqIElQIGFkZHJlc3MuXG4gICAqXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHJlYWRvbmx5IHNvdXJjZUluZ2VzdElwOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBwb3J0IHRoYXQgdGhlIGZsb3cgbGlzdGVucyBvbiBmb3IgaW5jb21pbmcgY29udGVudC5cbiAgICpcbiAgICogQXZhaWxhYmxlIGZvciB0aGUgc2FtZSBsaXN0ZW5lci1zdHlsZSBzb3VyY2UgcHJvdG9jb2xzIGFzIGBzb3VyY2VJbmdlc3RJcGAuXG4gICAqIEFjY2Vzc2luZyB0aGlzIG9uIFNSVCBjYWxsZXIsIGVudGl0bGVtZW50LCBnYXRld2F5IGJyaWRnZSwgcm91dGVyLCBDREksIEpQRUcgWFMsXG4gICAqIG9yIGltcG9ydGVkIGZsb3dzIHRocm93cy5cbiAgICpcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcmVhZG9ubHkgc291cmNlSW5nZXN0UG9ydDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgZnVsbCBpbmdlc3QgVVJMIGZvciB0aGUgZmxvdyBzb3VyY2UsIGNvbWJpbmluZyBwcm90b2NvbCwgSVAsIGFuZCBwb3J0LlxuICAgKiBGb3IgZXhhbXBsZTogYHNydDovLzIwMy4wLjExMy4xMDo1MDAwYFxuICAgKlxuICAgKiBBdmFpbGFibGUgZm9yIGxpc3RlbmVyLXN0eWxlIHNvdXJjZSBwcm90b2NvbHMgKFJUUCwgUlRQLUZFQywgUklTVCwgU1JUIGxpc3RlbmVyLFxuICAgKiBaaXhpIHB1c2gpIHdoZXJlIHRoZSBmbG93IGxpc3RlbnMgZm9yIGFuIHVwc3RyZWFtIHNlbmRlci4gQWNjZXNzaW5nIHRoaXMgb25cbiAgICogU1JUIGNhbGxlciwgZW50aXRsZW1lbnQsIGdhdGV3YXkgYnJpZGdlLCByb3V0ZXIsIENESSwgSlBFRyBYUywgb3IgaW1wb3J0ZWRcbiAgICogZmxvd3MgdGhyb3dzIOKAlCB0aG9zZSBzb3VyY2VzIGRvbid0IGV4cG9zZSBhIHNpbmdsZSBob3N0OnBvcnQgaW5nZXN0IFVSTC5cbiAgICovXG4gIHJlYWRvbmx5IHNvdXJjZUluZ2VzdFVybDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgQXZhaWxhYmlsaXR5IFpvbmUgdGhhdCB0aGUgZmxvdyB3YXMgY3JlYXRlZCBpbi5cbiAgICpcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcmVhZG9ubHkgZmxvd0F2YWlsYWJpbGl0eVpvbmU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEZhaWxvdmVyIENvbmZpZ3VyYXRpb24gZm9yIGZsb3dcbiAgICovXG4gIHJlYWRvbmx5IGlzRmFpbG92ZXJFbmFibGVkPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQ29sbGVjdGlvbiBvZiBncmFudCBtZXRob2RzIGZvciB0aGlzIGZsb3cuXG4gICAqL1xuICByZWFkb25seSBncmFudHM6IEZsb3dHcmFudHM7XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIENsb3VkV2F0Y2ggbWV0cmljIGZvciB0aGlzIGZsb3cuXG4gICAqL1xuICBtZXRyaWMobWV0cmljTmFtZTogc3RyaW5nLCBwcm9wcz86IE1ldHJpY09wdGlvbnMpOiBNZXRyaWM7XG5cbiAgLyoqXG4gICAqIE1ldHJpYyBmb3IgdGhlIGJpdHJhdGUgb2YgY29udGVudCBpbmdlc3RlZCBpbnRvIHRoZSBmbG93LlxuICAgKiBAZGVmYXVsdCAtIGF2ZXJhZ2Ugb3ZlciA2MCBzZWNvbmRzXG4gICAqL1xuICBtZXRyaWNTb3VyY2VCaXRyYXRlKHByb3BzPzogTWV0cmljT3B0aW9ucyk6IE1ldHJpYztcblxuICAvKipcbiAgICogTWV0cmljIGZvciBwYWNrZXRzIHRoYXQgd2VyZSBub3QgcmVjb3ZlcmVkIGJ5IHRoZSBmbG93IHNvdXJjZS5cbiAgICogQGRlZmF1bHQgLSBzdW0gb3ZlciA2MCBzZWNvbmRzXG4gICAqL1xuICBtZXRyaWNTb3VyY2VOb3RSZWNvdmVyZWRQYWNrZXRzKHByb3BzPzogTWV0cmljT3B0aW9ucyk6IE1ldHJpYztcblxuICAvKipcbiAgICogTWV0cmljIGZvciB0aGUgdG90YWwgbnVtYmVyIG9mIHBhY2tldHMgcmVjZWl2ZWQgYnkgdGhlIGZsb3cgc291cmNlLlxuICAgKiBAZGVmYXVsdCAtIHN1bSBvdmVyIDYwIHNlY29uZHNcbiAgICovXG4gIG1ldHJpY1NvdXJjZVRvdGFsUGFja2V0cyhwcm9wcz86IE1ldHJpY09wdGlvbnMpOiBNZXRyaWM7XG5cbiAgLyoqXG4gICAqIE1ldHJpYyBpbmRpY2F0aW5nIHdoaWNoIHNvdXJjZSBpcyBzZWxlY3RlZCBmb3IgaW5nZXN0IHdoZW4gdXNpbmcgYEZhaWxvdmVyYCBmYWlsb3ZlciBtb2RlLlxuICAgKiBAZGVmYXVsdCAtIG1heGltdW0gb3ZlciA2MCBzZWNvbmRzXG4gICAqL1xuICBtZXRyaWNTb3VyY2VTZWxlY3RlZChwcm9wcz86IE1ldHJpY09wdGlvbnMpOiBNZXRyaWM7XG5cbiAgLyoqXG4gICAqIE1ldHJpYyBpbmRpY2F0aW5nIHRoZSBjb25uZWN0aW9uIHN0YXRlIG9mIHRoZSBzb3VyY2UgKDEgY29ubmVjdGVkLCAwIGRpc2Nvbm5lY3RlZCkuXG4gICAqIEFwcGxpZXMgb25seSB0byBaaXhpLCBTUlQsIGFuZCBSSVNUIHNvdXJjZXMuXG4gICAqIEBkZWZhdWx0IC0gbWluaW11bSBvdmVyIDYwIHNlY29uZHNcbiAgICovXG4gIG1ldHJpY1NvdXJjZUNvbm5lY3RlZChwcm9wcz86IE1ldHJpY09wdGlvbnMpOiBNZXRyaWM7XG5cbiAgLyoqXG4gICAqIE1ldHJpYyBmb3IgdGhlIG51bWJlciBvZiB0aW1lcyB0aGUgc291cmNlIHRyYW5zaXRpb25lZCBmcm9tIGNvbm5lY3RlZCB0byBkaXNjb25uZWN0ZWQuXG4gICAqIEBkZWZhdWx0IC0gc3VtIG92ZXIgNjAgc2Vjb25kc1xuICAgKi9cbiAgbWV0cmljU291cmNlRGlzY29ubmVjdGlvbnMocHJvcHM/OiBNZXRyaWNPcHRpb25zKTogTWV0cmljO1xuXG4gIC8qKlxuICAgKiBNZXRyaWMgZm9yIHRoZSBudW1iZXIgb2YgcGFja2V0cyBsb3N0IGR1cmluZyB0cmFuc2l0LCBtZWFzdXJlZCBiZWZvcmUgYW55IGVycm9yIGNvcnJlY3Rpb24uXG4gICAqIEBkZWZhdWx0IC0gc3VtIG92ZXIgNjAgc2Vjb25kc1xuICAgKi9cbiAgbWV0cmljU291cmNlRHJvcHBlZFBhY2tldHMocHJvcHM/OiBNZXRyaWNPcHRpb25zKTogTWV0cmljO1xuXG4gIC8qKlxuICAgKiBNZXRyaWMgZm9yIHRoZSBwZXJjZW50YWdlIG9mIHBhY2tldHMgbG9zdCBkdXJpbmcgdHJhbnNpdCwgZXZlbiBpZiB0aGV5IHdlcmUgcmVjb3ZlcmVkLlxuICAgKiBAZGVmYXVsdCAtIGF2ZXJhZ2Ugb3ZlciA2MCBzZWNvbmRzXG4gICAqL1xuICBtZXRyaWNTb3VyY2VQYWNrZXRMb3NzUGVyY2VudChwcm9wcz86IE1ldHJpY09wdGlvbnMpOiBNZXRyaWM7XG5cbiAgLyoqXG4gICAqIE1ldHJpYyBmb3IgdGhlIHJvdW5kLXRyaXAgdGltZSBiZXR3ZWVuIHRoZSBzb3VyY2UgYW5kIE1lZGlhQ29ubmVjdC5cbiAgICogQXBwbGllcyBvbmx5IHRvIFJJU1QsIFppeGksIGFuZCBTUlQgc291cmNlcy5cbiAgICogQGRlZmF1bHQgLSBhdmVyYWdlIG92ZXIgNjAgc2Vjb25kc1xuICAgKi9cbiAgbWV0cmljU291cmNlUm91bmRUcmlwVGltZShwcm9wcz86IE1ldHJpY09wdGlvbnMpOiBNZXRyaWM7XG5cbiAgLyoqXG4gICAqIE1ldHJpYyBmb3IgdGhlIGN1cnJlbnQgbmV0d29yayBqaXR0ZXIgb2YgdGhlIHNvdXJjZSwgbWVhc3VyZWQgaW4gbWlsbGlzZWNvbmRzLlxuICAgKiBAZGVmYXVsdCAtIGF2ZXJhZ2Ugb3ZlciA2MCBzZWNvbmRzXG4gICAqL1xuICBtZXRyaWNTb3VyY2VKaXR0ZXIocHJvcHM/OiBNZXRyaWNPcHRpb25zKTogTWV0cmljO1xuXG4gIC8qKlxuICAgKiBBZGQgYW4gb3V0cHV0IHRvIHRoaXMgZmxvd1xuICAgKi9cbiAgYWRkT3V0cHV0KGlkOiBzdHJpbmcsIG91dHB1dENvbmZpZzogT3V0cHV0Q29uZmlndXJhdGlvbik6IElGbG93T3V0cHV0O1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIEZsb3cgU2l6ZVxuICovXG5leHBvcnQgY2xhc3MgRmxvd1NpemUge1xuICAvKipcbiAgICogTWVkaXVtIGZsb3cgc2l6ZS4gVGhlIGRlZmF1bHQg4oCUIHN0YW5kYXJkIHRyYW5zcG9ydCBzdHJlYW0gZGlzdHJpYnV0aW9uOyBkb2VzIG5vdFxuICAgKiBzdXBwb3J0IE5ESSwgQ0RJLCBvciBKUEVHIFhTLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9tZWRpYWNvbm5lY3QvbGF0ZXN0L3VnL2Zsb3ctc2l6ZXMtY2FwYWJpbGl0aWVzLmh0bWxcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgTUVESVVNID0gbmV3IEZsb3dTaXplKCdNRURJVU0nKTtcbiAgLyoqXG4gICAqIExhcmdlIGZsb3cgc2l6ZS4gUmVxdWlyZWQgd2hlbiB0aGUgZmxvdyB1c2VzIE5ESSBzb3VyY2VzIG9yIG91dHB1dHMuIFN1cHBvcnRzXG4gICAqIHRyYW5zcG9ydCBzdHJlYW0gZGlzdHJpYnV0aW9uIHBsdXMgTkRJOyBkb2VzIG5vdCBzdXBwb3J0IENESSBvciBKUEVHIFhTLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9tZWRpYWNvbm5lY3QvbGF0ZXN0L3VnL2Zsb3ctc2l6ZXMtY2FwYWJpbGl0aWVzLmh0bWxcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgTEFSR0UgPSBuZXcgRmxvd1NpemUoJ0xBUkdFJyk7XG4gIC8qKlxuICAgKiBPcHRpb24gZm9yIGxhcmdlIDR4IGZsb3cgc2l6ZS4gUmVxdWlyZWQgZm9yIEpQRUcgWFMgYW5kIENESSBwcm90b2NvbHMuIERvZXMgbm90IHN1cHBvcnQgdHJhbnNwb3J0IHN0cmVhbXMgb3IgTkRJLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBMQVJHRV80WCA9IG5ldyBGbG93U2l6ZSgnTEFSR0VfNFgnKTtcblxuICAvKipcbiAgICogVXNlIGEgY3VzdG9tIGZsb3cgc2l6ZSB2YWx1ZVxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIGZsb3cgc2l6ZSBzdHJpbmcgdmFsdWVcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgb2YodmFsdWU6IHN0cmluZyk6IEZsb3dTaXplIHtcbiAgICByZXR1cm4gbmV3IEZsb3dTaXplKHZhbHVlKTtcbiAgfVxuXG4gIC8qKiBAcGFyYW0gdmFsdWUgVGhlIGZsb3cgc2l6ZSBzdHJpbmcgdmFsdWUgKi9cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgdmFsdWU6IHN0cmluZykge31cblxuICAvKiogUmV0dXJucyB0aGUgc3RyaW5nIHZhbHVlICovXG4gIHB1YmxpYyB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnZhbHVlO1xuICB9XG59XG5cbi8qKlxuICogTWFpbnRlbmFuY2UgV2luZG93IGNvbmZpZ3VyYXRpb24gZm9yIE1lZGlhQ29ubmVjdCBGbG93LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE1haW50ZW5hbmNlV2luZG93IHtcbiAgLyoqXG4gICAqIEEgZGF5IG9mIGEgd2VlayB3aGVuIHRoZSBtYWludGVuYW5jZSB3aWxsIGhhcHBlbi5cbiAgICovXG4gIHJlYWRvbmx5IG1haW50ZW5hbmNlRGF5OiBNYWludGVuYW5jZURheTtcbiAgLyoqXG4gICAqIFVUQyB0aW1lIHdoZW4gdGhlIG1haW50ZW5hbmNlIHdpbGwgaGFwcGVuLiBVc2UgMjQtaG91ciBISDpNTSBmb3JtYXQuIE1pbnV0ZXMgbXVzdCBiZSAwMC4gRXhhbXBsZTogMTM6MDAuXG4gICAqL1xuICByZWFkb25seSBtYWludGVuYW5jZVN0YXJ0SG91cjogc3RyaW5nO1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIG1lcmdlLW1vZGUgc291cmNlIGZhaWxvdmVyLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE1lcmdlRmFpbG92ZXJPcHRpb25zIHtcbiAgLyoqXG4gICAqIFdoZXRoZXIgZmFpbG92ZXIgaXMgZW5hYmxlZC4gU2V0IHRvIGBTdGF0ZS5ESVNBQkxFRGAgdG8ga2VlcCB0aGUgY29uZmlndXJhdGlvblxuICAgKiBvbiB0aGUgZmxvdyB3aXRob3V0IHN3aXRjaGluZyBmYWlsb3ZlciBvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgU3RhdGUuRU5BQkxFRFxuICAgKi9cbiAgcmVhZG9ubHkgc3RhdGU/OiBTdGF0ZTtcbiAgLyoqXG4gICAqIFNlYXJjaCB3aW5kb3cgdGltZSB0byBsb29rIGZvciBTTVBURSAyMDIyLTcgcGFja2V0cy4gQSBsYXJnZXIgcmVjb3Zlcnkgd2luZG93XG4gICAqIG1lYW5zIGEgbG9uZ2VyIGRlbGF5IGluIHRyYW5zbWl0dGluZyB0aGUgc3RyZWFtLCBidXQgbW9yZSByb29tIGZvciBlcnJvclxuICAgKiBjb3JyZWN0aW9uLiBBIHNtYWxsZXIgd2luZG93IG1lYW5zIGEgc2hvcnRlciBkZWxheSBidXQgbGVzcyByb29tIGZvciBjb3JyZWN0aW9uLlxuICAgKlxuICAgKiBWYWxpZCByYW5nZTogMTAw4oCTMTUwMDAgbXMuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gMjAwIG1zXG4gICAqL1xuICByZWFkb25seSByZWNvdmVyeVdpbmRvdz86IER1cmF0aW9uO1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHN3aXRjaG92ZXItbW9kZSBzb3VyY2UgZmFpbG92ZXIuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRmFpbG92ZXJGYWlsb3Zlck9wdGlvbnMge1xuICAvKipcbiAgICogV2hldGhlciBmYWlsb3ZlciBpcyBlbmFibGVkLiBTZXQgdG8gYFN0YXRlLkRJU0FCTEVEYCB0byBrZWVwIHRoZSBjb25maWd1cmF0aW9uXG4gICAqIG9uIHRoZSBmbG93IHdpdGhvdXQgc3dpdGNoaW5nIGZhaWxvdmVyIG9uLlxuICAgKlxuICAgKiBAZGVmYXVsdCBTdGF0ZS5FTkFCTEVEXG4gICAqL1xuICByZWFkb25seSBzdGF0ZT86IFN0YXRlO1xuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIHNvdXJjZSB5b3Ugd2FudCB0byB0cmVhdCBhcyBwcmltYXJ5LiBJZiBzZXQsIE1lZGlhQ29ubmVjdCBhbHdheXNcbiAgICogdXNlcyB0aGlzIHNvdXJjZSB3aGVuIGl0IGlzIGF2YWlsYWJsZS4gV2hlbiB1bnNldCwgYm90aCBzb3VyY2VzIGFyZSB0cmVhdGVkIHdpdGhcbiAgICogZXF1YWwgcHJpb3JpdHkuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gYm90aCBzb3VyY2VzIGFyZSBlcXVhbCBwcmlvcml0eVxuICAgKi9cbiAgcmVhZG9ubHkgcHJpbWFyeVNvdXJjZT86IHN0cmluZztcbn1cblxuLyoqXG4gKiBTb3VyY2UgZmFpbG92ZXIgY29uZmlndXJhdGlvbiBmb3IgYSBmbG93LlxuICpcbiAqIE1lZGlhQ29ubmVjdCBzdXBwb3J0cyB0d28gZmFpbG92ZXIgbW9kZXM6XG4gKiAtIHtAbGluayBGYWlsb3ZlckNvbmZpZy5tZXJnZX0gY29tYmluZXMgdHdvIGJpbmFyeS1pZGVudGljYWwgc291cmNlcyBpbnRvIGEgc2luZ2xlXG4gKiAgIHN0cmVhbSwgcmVjb3ZlcmluZyBsb3N0IHBhY2tldHMgZnJvbSB0aGUgb3RoZXIgc291cmNlIChTTVBURSAyMDIyLTcpLlxuICogLSB7QGxpbmsgRmFpbG92ZXJDb25maWcuZmFpbG92ZXJ9IHN3aXRjaGVzIGJldHdlZW4gYSBwcmltYXJ5IGFuZCBiYWNrdXAgc291cmNlIHdoZW5cbiAqICAgdGhlIGFjdGl2ZSBzb3VyY2Ugc3RvcHMgcmVjZWl2aW5nIGRhdGEuXG4gKi9cbmV4cG9ydCBjbGFzcyBGYWlsb3ZlckNvbmZpZyB7XG4gIC8qKlxuICAgKiBDb25maWd1cmUgbWVyZ2UtbW9kZSBmYWlsb3Zlci4gUmVxdWlyZXMgdHdvIGJpbmFyeS1pZGVudGljYWwgc291cmNlcy5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgbWVyZ2Uob3B0aW9uczogTWVyZ2VGYWlsb3Zlck9wdGlvbnMgPSB7fSk6IEZhaWxvdmVyQ29uZmlnIHtcbiAgICBpZiAob3B0aW9ucy5yZWNvdmVyeVdpbmRvdykge1xuICAgICAgY29uc3QgbXMgPSBvcHRpb25zLnJlY292ZXJ5V2luZG93LnRvTWlsbGlzZWNvbmRzKCk7XG4gICAgICBpZiAobXMgPCAxMDAgfHwgbXMgPiAxNTAwMCkge1xuICAgICAgICB0aHJvdyBuZXcgVW5zY29wZWRWYWxpZGF0aW9uRXJyb3IobGl0YFJlY292ZXJ5V2luZG93UmFuZ2VgLCBgUmVjb3Zlcnkgd2luZG93IG11c3QgYmUgYmV0d2VlbiAxMDAgYW5kIDE1MDAwIG1zLCBnb3QgJHttc31gKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG5ldyBGYWlsb3ZlckNvbmZpZyhGYWlsb3Zlck1vZGUuTUVSR0UsIG9wdGlvbnMuc3RhdGUgPz8gU3RhdGUuRU5BQkxFRCwgb3B0aW9ucy5yZWNvdmVyeVdpbmRvdywgdW5kZWZpbmVkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25maWd1cmUgc3dpdGNob3Zlci1tb2RlIGZhaWxvdmVyLiBUaGUgZmxvdyBzd2FwcyB0byB0aGUgYmFja3VwIHNvdXJjZSB3aGVuIHRoZVxuICAgKiBwcmltYXJ5IHNvdXJjZSBzdG9wcyByZWNlaXZpbmcgZGF0YS5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZmFpbG92ZXIob3B0aW9uczogRmFpbG92ZXJGYWlsb3Zlck9wdGlvbnMgPSB7fSk6IEZhaWxvdmVyQ29uZmlnIHtcbiAgICByZXR1cm4gbmV3IEZhaWxvdmVyQ29uZmlnKEZhaWxvdmVyTW9kZS5GQUlMT1ZFUiwgb3B0aW9ucy5zdGF0ZSA/PyBTdGF0ZS5FTkFCTEVELCB1bmRlZmluZWQsIG9wdGlvbnMucHJpbWFyeVNvdXJjZSk7XG4gIH1cblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX2ZhaWxvdmVyTW9kZTogRmFpbG92ZXJNb2RlLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgX3N0YXRlOiBTdGF0ZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IF9yZWNvdmVyeVdpbmRvdzogRHVyYXRpb24gfCB1bmRlZmluZWQsXG4gICAgcHJpdmF0ZSByZWFkb25seSBfcHJpbWFyeVNvdXJjZTogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICApIHt9XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhpcyBjb25maWd1cmF0aW9uIGhhcyBmYWlsb3ZlciBlbmFibGVkLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHB1YmxpYyBnZXQgX2lzRW5hYmxlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fc3RhdGUgPT09IFN0YXRlLkVOQUJMRUQ7XG4gIH1cblxuICAvKipcbiAgICogQ2FsbGVkIHdoZW4gdGhlIGNvbmZpZ3VyYXRpb24gaXMgYm91bmQgdG8gYSBGbG93LlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHB1YmxpYyBfYmluZCgpOiBDZm5GbG93LkZhaWxvdmVyQ29uZmlnUHJvcGVydHkge1xuICAgIHJldHVybiB7XG4gICAgICBmYWlsb3Zlck1vZGU6IHRoaXMuX2ZhaWxvdmVyTW9kZS52YWx1ZSxcbiAgICAgIHJlY292ZXJ5V2luZG93OiB0aGlzLl9yZWNvdmVyeVdpbmRvdz8udG9NaWxsaXNlY29uZHMoKSxcbiAgICAgIHNvdXJjZVByaW9yaXR5OiB0aGlzLl9wcmltYXJ5U291cmNlID8geyBwcmltYXJ5U291cmNlOiB0aGlzLl9wcmltYXJ5U291cmNlIH0gOiB1bmRlZmluZWQsXG4gICAgICBzdGF0ZTogdGhpcy5fc3RhdGUsXG4gICAgfTtcbiAgfVxufVxuXG4vKipcbiAqIENvbmZpZ3VyZXMgYSBzb3VyY2UgbW9uaXRvcmluZyBtZXRyaWMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTW9uaXRvcmluZ01ldHJpYyB7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBtZXRyaWMgaXMgZW5hYmxlZCBvciBkaXNhYmxlZC4gVGhlIHRocmVzaG9sZCBpcyBwZXJzaXN0ZWQgYnkgdGhlXG4gICAqIHNlcnZpY2UgZWl0aGVyIHdheSwgc28geW91IGNhbiB0b2dnbGUgdGhlIG1ldHJpYyBvbiBhbmQgb2ZmIHdpdGhvdXQgbG9zaW5nXG4gICAqIHRoZSB0aHJlc2hvbGQgdmFsdWUuXG4gICAqL1xuICByZWFkb25seSBzdGF0ZTogU3RhdGU7XG4gIC8qKlxuICAgKiBUaHJlc2hvbGQgaW4gc2Vjb25kcyB0aGF0IHRyaWdnZXJzIHRoZSBtZXRyaWMncyBhbGVydC4gVmFsaWQgcmFuZ2U6IDEw4oCTNjAgc2Vjb25kcy5cbiAgICovXG4gIHJlYWRvbmx5IHRocmVzaG9sZDogRHVyYXRpb247XG59XG5cbi8qKlxuICogU291cmNlIG1vbml0b3Jpbmcgc2V0dGluZ3MuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU291cmNlTW9uaXRvcmluZ0NvbmZpZyB7XG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgd2hldGhlciBjb250ZW50IHF1YWxpdHkgYW5hbHlzaXMgaXMgZW5hYmxlZCBvciBkaXNhYmxlZC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBjb250ZW50IHF1YWxpdHkgYW5hbHlzaXMgaXMgZGlzYWJsZWRcbiAgICovXG4gIHJlYWRvbmx5IGNvbnRlbnRRdWFsaXR5QW5hbHlzaXNTdGF0ZT86IFN0YXRlO1xuICAvKipcbiAgICogVGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIHRodW1ibmFpbCBtb25pdG9yaW5nLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIHRodW1ibmFpbCBtb25pdG9yaW5nIGlzIGRpc2FibGVkXG4gICAqL1xuICByZWFkb25seSB0aHVtYm5haWxTdGF0ZT86IFN0YXRlO1xuICAvKipcbiAgICogU2lsZW50LWF1ZGlvIGRldGVjdGlvbiBvbiB0aGUgc291cmNlLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIHNpbGVudCBhdWRpbyBtb25pdG9yaW5nIGlzIG5vdCBjb25maWd1cmVkXG4gICAqL1xuICByZWFkb25seSBzaWxlbnRBdWRpbz86IE1vbml0b3JpbmdNZXRyaWM7XG4gIC8qKlxuICAgKiBCbGFjay1mcmFtZXMgZGV0ZWN0aW9uIG9uIHRoZSBzb3VyY2UuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gYmxhY2sgZnJhbWVzIG1vbml0b3JpbmcgaXMgbm90IGNvbmZpZ3VyZWRcbiAgICovXG4gIHJlYWRvbmx5IGJsYWNrRnJhbWVzPzogTW9uaXRvcmluZ01ldHJpYztcbiAgLyoqXG4gICAqIEZyb3plbi1mcmFtZXMgZGV0ZWN0aW9uIG9uIHRoZSBzb3VyY2UuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gZnJvemVuIGZyYW1lcyBtb25pdG9yaW5nIGlzIG5vdCBjb25maWd1cmVkXG4gICAqL1xuICByZWFkb25seSBmcm96ZW5GcmFtZXM/OiBNb25pdG9yaW5nTWV0cmljO1xufVxuXG4vKipcbiAqIE5ESSBDb25maWd1cmF0aW9uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTmRpRGlzY292ZXJ5U2VydmVyQ29uZmlnIHtcbiAgLyoqXG4gICAqIFRoZSB1bmlxdWUgbmV0d29yayBhZGRyZXNzIG9mIHRoZSBOREkgZGlzY292ZXJ5IHNlcnZlci5cbiAgICovXG4gIHJlYWRvbmx5IGRpc2NvdmVyeVNlcnZlckFkZHJlc3M6IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBwb3J0IGZvciB0aGUgTkRJIGRpc2NvdmVyeSBzZXJ2ZXIuIERlZmF1bHRzIHRvIDU5NTkgaWYgYSBjdXN0b20gcG9ydCBpc24ndCBzcGVjaWZpZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdW5kZWZpbmVkOyB3aGVuIG9taXR0ZWQsIE1lZGlhQ29ubmVjdCBhcHBsaWVzIDU5NTkgYXQgZGVwbG95IHRpbWVcbiAgICovXG4gIHJlYWRvbmx5IGRpc2NvdmVyeVNlcnZlclBvcnQ/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgVlBDIGludGVyZmFjZSB0aGF0IHRoZSBOREkgZGlzY292ZXJ5IHNlcnZlciB1c2VzIHRvIHJlYWNoIHRoZSBmbG93LlxuICAgKi9cbiAgcmVhZG9ubHkgdnBjSW50ZXJmYWNlOiBWcGNJbnRlcmZhY2VDb25maWc7XG59XG5cbi8qKlxuICogQ29uZmlndXJhdGlvbiBmb3IgTkRJIENvbmZpZ1xuICovXG5leHBvcnQgaW50ZXJmYWNlIE5kaUNvbmZpZyB7XG4gIC8qKlxuICAgKiBBIHByZWZpeCBmb3IgdGhlIG5hbWVzIG9mIHRoZSBOREkgc291cmNlcyB0aGF0IHRoZSBmbG93IGNyZWF0ZXMuXG4gICAqIElmIGEgY3VzdG9tIG5hbWUgaXNuJ3Qgc3BlY2lmaWVkLCBNZWRpYUNvbm5lY3QgZ2VuZXJhdGVzIGEgdW5pcXVlIDEyLWNoYXJhY3RlciBJRCBhcyB0aGUgcHJlZml4LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE1lZGlhQ29ubmVjdCBnZW5lcmF0ZXMgYSB1bmlxdWUgMTItY2hhcmFjdGVyIElEXG4gICAqL1xuICByZWFkb25seSBtYWNoaW5lTmFtZT86IHN0cmluZztcbiAgLyoqXG4gICAqIFNwZWNpZmllcyB0aGUgY29uZmlndXJhdGlvbiBzZXR0aW5ncyBmb3IgaW5kaXZpZHVhbCBOREkgZGlzY292ZXJ5IHNlcnZlcnMuXG4gICAqIEEgbWF4aW11bSBvZiAzIHNlcnZlcnMgaXMgYWxsb3dlZC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyBOREkgZGlzY292ZXJ5IHNlcnZlcnNcbiAgICovXG4gIHJlYWRvbmx5IG5kaURpc2NvdmVyeVNlcnZlcnM/OiBOZGlEaXNjb3ZlcnlTZXJ2ZXJDb25maWdbXTtcbiAgLyoqXG4gICAqIEEgc2V0dGluZyB0aGF0IGNvbnRyb2xzIHdoZXRoZXIgTkRJIHNvdXJjZXMgb3Igb3V0cHV0cyBjYW4gYmUgdXNlZCBpbiB0aGUgZmxvdy5cbiAgICogTXVzdCBiZSBFTkFCTEVEIGZvciB0aGUgZmxvdyB0byBzdXBwb3J0IE5ESSBzb3VyY2VzIG9yIG91dHB1dHMuXG4gICAqXG4gICAqIEBkZWZhdWx0IFN0YXRlLkRJU0FCTEVEXG4gICAqL1xuICByZWFkb25seSBuZGlTdGF0ZT86IFN0YXRlO1xufVxuXG4vKipcbiAqIEVuY29kaW5nIHByb2ZpbGVzIHN1cHBvcnRlZCB3aGVuIHRyYW5zY29kaW5nIGFuIE5ESSBzb3VyY2UgdG8gYSB0cmFuc3BvcnQgc3RyZWFtLlxuICovXG5leHBvcnQgZW51bSBFbmNvZGluZ1Byb2ZpbGUge1xuICAvKipcbiAgICogSC4yNjQgcHJvZmlsZSB0dW5lZCBmb3IgY29udHJpYnV0aW9uIHdvcmtmbG93cyDigJQgaGlnaGVyIHF1YWxpdHksIGhpZ2hlciBiaXRyYXRlLlxuICAgKi9cbiAgQ09OVFJJQlVUSU9OX0gyNjRfREVGQVVMVCA9ICdDT05UUklCVVRJT05fSDI2NF9ERUZBVUxUJyxcbiAgLyoqXG4gICAqIEguMjY0IHByb2ZpbGUgdHVuZWQgZm9yIGRpc3RyaWJ1dGlvbiB3b3JrZmxvd3Mg4oCUIGxvd2VyIGJpdHJhdGUsIHdpZGVyIGNvbXBhdGliaWxpdHkuXG4gICAqL1xuICBESVNUUklCVVRJT05fSDI2NF9ERUZBVUxUID0gJ0RJU1RSSUJVVElPTl9IMjY0X0RFRkFVTFQnLFxufVxuXG4vKipcbiAqIEVuY29kaW5nIGNvbmZpZ3VyYXRpb24gYXBwbGllZCB0byBhbiBOREkgc291cmNlIHdoZW4gdHJhbnNjb2RpbmcgaXQgdG8gYSB0cmFuc3BvcnRcbiAqIHN0cmVhbSBmb3IgZG93bnN0cmVhbSBkaXN0cmlidXRpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRW5jb2RpbmdDb25maWcge1xuICAvKipcbiAgICogVGhlIGVuY29kaW5nIHByb2ZpbGUgdG8gdXNlIHdoZW4gdHJhbnNjb2RpbmcgdGhlIE5ESSBzb3VyY2UgY29udGVudCB0byBhIHRyYW5zcG9ydFxuICAgKiBzdHJlYW0uIFlvdSBjYW4gY2hhbmdlIHRoaXMgdmFsdWUgd2hpbGUgdGhlIGZsb3cgaXMgcnVubmluZy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSB0aGUgTWVkaWFDb25uZWN0IHNlcnZpY2UgZGVmYXVsdFxuICAgKi9cbiAgcmVhZG9ubHkgZW5jb2RpbmdQcm9maWxlPzogRW5jb2RpbmdQcm9maWxlO1xuXG4gIC8qKlxuICAgKiBUaGUgbWF4aW11bSB2aWRlbyBiaXRyYXRlIHRvIHVzZSB3aGVuIHRyYW5zY29kaW5nIHRoZSBOREkgc291cmNlIHRvIGEgdHJhbnNwb3J0IHN0cmVhbS5cbiAgICpcbiAgICogVGhlIHN1cHBvcnRlZCByYW5nZSBpcyAxMCBNYnBzIOKAkyA1MCBNYnBzLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIHVuZGVmaW5lZDsgd2hlbiBvbWl0dGVkLCBNZWRpYUNvbm5lY3QgYXBwbGllcyAyMCBNYnBzIGF0IGRlcGxveSB0aW1lXG4gICAqL1xuICByZWFkb25seSB2aWRlb01heEJpdHJhdGU/OiBCaXRyYXRlO1xufVxuXG4vKipcbiAqIE9wdGlvbiBmb3IgQ29sb3JpbWV0cnlcbiAqL1xuZXhwb3J0IGNsYXNzIENvbG9yaW1ldHJ5IHtcbiAgLyoqIE9wdGlvbiBmb3IgQlQ2MDEgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBCVDYwMSA9IG5ldyBDb2xvcmltZXRyeSgnQlQ2MDEnKTtcbiAgLyoqIE9wdGlvbiBmb3IgQlQ3MDkgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBCVDcwOSA9IG5ldyBDb2xvcmltZXRyeSgnQlQ3MDknKTtcbiAgLyoqIE9wdGlvbiBmb3IgQlQyMDIwICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgQlQyMDIwID0gbmV3IENvbG9yaW1ldHJ5KCdCVDIwMjAnKTtcbiAgLyoqIE9wdGlvbiBmb3IgQlQyMTAwICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgQlQyMTAwID0gbmV3IENvbG9yaW1ldHJ5KCdCVDIxMDAnKTtcbiAgLyoqIE9wdGlvbiBmb3IgU1QyMDY1LTEgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBTVDIwNjVfMSA9IG5ldyBDb2xvcmltZXRyeSgnU1QyMDY1LTEnKTtcbiAgLyoqIE9wdGlvbiBmb3IgU1QyMDY1LTMgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBTVDIwNjVfMyA9IG5ldyBDb2xvcmltZXRyeSgnU1QyMDY1LTMnKTtcbiAgLyoqIE9wdGlvbiBmb3IgWFlaICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgWFlaID0gbmV3IENvbG9yaW1ldHJ5KCdYWVonKTtcblxuICAvKiogVXNlIGEgY3VzdG9tIGNvbG9yaW1ldHJ5IHZhbHVlICovXG4gIHB1YmxpYyBzdGF0aWMgb2YodmFsdWU6IHN0cmluZyk6IENvbG9yaW1ldHJ5IHsgcmV0dXJuIG5ldyBDb2xvcmltZXRyeSh2YWx1ZSk7IH1cbiAgLyoqIEBwYXJhbSB2YWx1ZSBUaGUgY29sb3JpbWV0cnkgc3RyaW5nIHZhbHVlICovXG4gIHByaXZhdGUgY29uc3RydWN0b3IocHVibGljIHJlYWRvbmx5IHZhbHVlOiBzdHJpbmcpIHt9XG4gIC8qKiBSZXR1cm5zIHRoZSBzdHJpbmcgdmFsdWUgKi9cbiAgcHVibGljIHRvU3RyaW5nKCk6IHN0cmluZyB7IHJldHVybiB0aGlzLnZhbHVlOyB9XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgVmlkZW8gUmFuZ2VcbiAqL1xuZXhwb3J0IGNsYXNzIFZpZGVvUmFuZ2Uge1xuICAvKiogT3B0aW9uIGZvciBOYXJyb3cgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBOQVJST1cgPSBuZXcgVmlkZW9SYW5nZSgnTkFSUk9XJyk7XG4gIC8qKiBPcHRpb24gZm9yIEZ1bGwgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBGVUxMID0gbmV3IFZpZGVvUmFuZ2UoJ0ZVTEwnKTtcbiAgLyoqIE9wdGlvbiBmb3IgRnVsbCBQcm90ZWN0ICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgRlVMTFBST1RFQ1QgPSBuZXcgVmlkZW9SYW5nZSgnRlVMTFBST1RFQ1QnKTtcblxuICAvKiogVXNlIGEgY3VzdG9tIHZpZGVvIHJhbmdlIHZhbHVlICovXG4gIHB1YmxpYyBzdGF0aWMgb2YodmFsdWU6IHN0cmluZyk6IFZpZGVvUmFuZ2UgeyByZXR1cm4gbmV3IFZpZGVvUmFuZ2UodmFsdWUpOyB9XG4gIC8qKiBAcGFyYW0gdmFsdWUgVGhlIHZpZGVvIHJhbmdlIHN0cmluZyB2YWx1ZSAqL1xuICBwcml2YXRlIGNvbnN0cnVjdG9yKHB1YmxpYyByZWFkb25seSB2YWx1ZTogc3RyaW5nKSB7fVxuICAvKiogUmV0dXJucyB0aGUgc3RyaW5nIHZhbHVlICovXG4gIHB1YmxpYyB0b1N0cmluZygpOiBzdHJpbmcgeyByZXR1cm4gdGhpcy52YWx1ZTsgfVxufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIFNjYW4gTW9kZVxuICovXG5leHBvcnQgY2xhc3MgU2Nhbk1vZGUge1xuICAvKiogT3B0aW9uIGZvciBQcm9ncmVzc2l2ZSAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IFBST0dSRVNTSVZFID0gbmV3IFNjYW5Nb2RlKCdwcm9ncmVzc2l2ZScpO1xuICAvKiogT3B0aW9uIGZvciBJbnRlcmxhY2UgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBJTlRFUkxBQ0UgPSBuZXcgU2Nhbk1vZGUoJ2ludGVybGFjZScpO1xuICAvKiogT3B0aW9uIGZvciBQcm9ncmVzc2l2ZSBTZWdtZW50ZWQgRnJhbWUgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBQUk9HUkVTU0lWRV9TRUdNRU5URURfRlJBTUUgPSBuZXcgU2Nhbk1vZGUoJ3Byb2dyZXNzaXZlLXNlZ21lbnRlZC1mcmFtZScpO1xuXG4gIC8qKiBVc2UgYSBjdXN0b20gc2NhbiBtb2RlIHZhbHVlICovXG4gIHB1YmxpYyBzdGF0aWMgb2YodmFsdWU6IHN0cmluZyk6IFNjYW5Nb2RlIHsgcmV0dXJuIG5ldyBTY2FuTW9kZSh2YWx1ZSk7IH1cbiAgLyoqIEBwYXJhbSB2YWx1ZSBUaGUgc2NhbiBtb2RlIHN0cmluZyB2YWx1ZSAqL1xuICBwcml2YXRlIGNvbnN0cnVjdG9yKHB1YmxpYyByZWFkb25seSB2YWx1ZTogc3RyaW5nKSB7fVxuICAvKiogUmV0dXJucyB0aGUgc3RyaW5nIHZhbHVlICovXG4gIHB1YmxpYyB0b1N0cmluZygpOiBzdHJpbmcgeyByZXR1cm4gdGhpcy52YWx1ZTsgfVxufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIFRjc1xuICovXG5leHBvcnQgY2xhc3MgVGNzIHtcbiAgLyoqIE9wdGlvbiBmb3IgU0RSICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgU0RSID0gbmV3IFRjcygnU0RSJyk7XG4gIC8qKiBPcHRpb24gZm9yIFBRICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgUFEgPSBuZXcgVGNzKCdQUScpO1xuICAvKiogT3B0aW9uIGZvciBITEcgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBITEcgPSBuZXcgVGNzKCdITEcnKTtcbiAgLyoqIE9wdGlvbiBmb3IgTGluZWFyICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgTElORUFSID0gbmV3IFRjcygnTElORUFSJyk7XG4gIC8qKiBPcHRpb24gZm9yIEJUMjEwMExJTlBRICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgQlQyMTAwTElOUFEgPSBuZXcgVGNzKCdCVDIxMDBMSU5QUScpO1xuICAvKiogT3B0aW9uIGZvciBCVDIxMDBMSU5ITEcgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBCVDIxMDBMSU5ITEcgPSBuZXcgVGNzKCdCVDIxMDBMSU5ITEcnKTtcbiAgLyoqIE9wdGlvbiBmb3IgU1QyMDY1LTEgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBTVDIwNjVfMSA9IG5ldyBUY3MoJ1NUMjA2NS0xJyk7XG4gIC8qKiBPcHRpb24gZm9yIFNUNDI4LTEgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBTVDQyOF8xID0gbmV3IFRjcygnU1Q0MjgtMScpO1xuICAvKiogT3B0aW9uIGZvciBEZW5zaXR5ICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgREVOU0lUWSA9IG5ldyBUY3MoJ0RFTlNJVFknKTtcblxuICAvKiogVXNlIGEgY3VzdG9tIFRDUyB2YWx1ZSAqL1xuICBwdWJsaWMgc3RhdGljIG9mKHZhbHVlOiBzdHJpbmcpOiBUY3MgeyByZXR1cm4gbmV3IFRjcyh2YWx1ZSk7IH1cbiAgLyoqIEBwYXJhbSB2YWx1ZSBUaGUgVENTIHN0cmluZyB2YWx1ZSAqL1xuICBwcml2YXRlIGNvbnN0cnVjdG9yKHB1YmxpYyByZWFkb25seSB2YWx1ZTogc3RyaW5nKSB7fVxuICAvKiogUmV0dXJucyB0aGUgc3RyaW5nIHZhbHVlICovXG4gIHB1YmxpYyB0b1N0cmluZygpOiBzdHJpbmcgeyByZXR1cm4gdGhpcy52YWx1ZTsgfVxufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIEZNVFAgVmlkZW9cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBGbXRwVmlkZW8ge1xuICAvKipcbiAgICogVGhlIGZvcm1hdCB1c2VkIGZvciB0aGUgcmVwcmVzZW50YXRpb24gb2YgY29sb3IuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gY29sb3JpbWV0cnkgc3BlY2lmaWVkXG4gICAqL1xuICByZWFkb25seSBjb2xvcmltZXRyeT86IENvbG9yaW1ldHJ5O1xuICAvKipcbiAgICogVGhlIGZyYW1lIHJhdGUgZm9yIHRoZSB2aWRlbyBzdHJlYW0uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gZnJhbWUgcmF0ZSBzcGVjaWZpZWRcbiAgICovXG4gIHJlYWRvbmx5IGV4YWN0RnJhbWVyYXRlPzogRnJhbWVyYXRlO1xuICAvKipcbiAgICogVGhlIHBpeGVsIGFzcGVjdCByYXRpbyAoUEFSKSBvZiB0aGUgdmlkZW8g4oCUIHRoZSBzaGFwZSBvZiBhIHNpbmdsZSBwaXhlbCwgbm90IHRoZVxuICAgKiBkaXNwbGF5IGFzcGVjdCByYXRpby4gVXNlIGBQaXhlbEFzcGVjdFJhdGlvLlNRVUFSRWAgZm9yIG1vc3QgbW9kZXJuIGNvbnRlbnQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gcGl4ZWwgYXNwZWN0IHJhdGlvIHNwZWNpZmllZFxuICAgKi9cbiAgcmVhZG9ubHkgcGFyPzogUGl4ZWxBc3BlY3RSYXRpbztcbiAgLyoqXG4gICAqIFRoZSBlbmNvZGluZyByYW5nZSBvZiB0aGUgdmlkZW8uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gdmlkZW8gcmFuZ2Ugc3BlY2lmaWVkXG4gICAqL1xuICByZWFkb25seSB2aWRlb1JhbmdlPzogVmlkZW9SYW5nZTtcbiAgLyoqXG4gICAqIFRoZSB0eXBlIG9mIGNvbXByZXNzaW9uIHRoYXQgd2FzIHVzZWQgdG8gc21vb3RoIHRoZSB2aWRlbydzIGFwcGVhcmFuY2UuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gc2NhbiBtb2RlIHNwZWNpZmllZFxuICAgKi9cbiAgcmVhZG9ubHkgc2Nhbk1vZGU/OiBTY2FuTW9kZTtcbiAgLyoqXG4gICAqIFRoZSB0cmFuc2ZlciBjaGFyYWN0ZXJpc3RpYyBzeXN0ZW0gKFRDUykgdGhhdCBpcyB1c2VkIGluIHRoZSB2aWRlby5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyBUQ1Mgc3BlY2lmaWVkXG4gICAqL1xuICByZWFkb25seSB0Y3M/OiBUY3M7XG59XG5cbi8qKlxuICogQXVkaW8gU3RyZWFtIE9yZGVyIE9wdGlvbnNcbiAqL1xuZXhwb3J0IGNsYXNzIEF1ZGlvU3RyZWFtT3JkZXJPcHRpb25zIHtcbiAgLyoqIE1vbm8gKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBNT05PID0gbmV3IEF1ZGlvU3RyZWFtT3JkZXJPcHRpb25zKCdTTVBURTIxMTAuKE0pJyk7XG4gIC8qKiBEdWFsIE1vbm8gKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBEVUFMX01PTk8gPSBuZXcgQXVkaW9TdHJlYW1PcmRlck9wdGlvbnMoJ1NNUFRFMjExMC4oRE0pJyk7XG4gIC8qKiBTdGFuZGFyZCBTdGVyZW8gKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBTVEFOREFSRF9TVEVSRU8gPSBuZXcgQXVkaW9TdHJlYW1PcmRlck9wdGlvbnMoJ1NNUFRFMjExMC4oU1QpJyk7XG4gIC8qKiBMZWZ0IFJpZ2h0IE1hdHJpeCBTdGVyZW8gKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBMVFJUX01BVFJJWF9TVEVSRU8gPSBuZXcgQXVkaW9TdHJlYW1PcmRlck9wdGlvbnMoJ1NNUFRFMjExMC4oTHRSdCknKTtcbiAgLyoqIDUuMSBTdXJyb3VuZCAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IFNVUlJPVU5EXzVfMSA9IG5ldyBBdWRpb1N0cmVhbU9yZGVyT3B0aW9ucygnU01QVEUyMTEwLig1MSknKTtcbiAgLyoqIDcuMSBTdXJyb3VuZCAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IFNVUlJPVU5EXzdfMSA9IG5ldyBBdWRpb1N0cmVhbU9yZGVyT3B0aW9ucygnU01QVEUyMTEwLig3MSknKTtcbiAgLyoqIDIyLjIgU3Vycm91bmQgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBTVVJST1VORF8yMl8yID0gbmV3IEF1ZGlvU3RyZWFtT3JkZXJPcHRpb25zKCdTTVBURTIxMTAuKDIyMiknKTtcbiAgLyoqIE9uZSBTREkgQXVkaW8gR3JvdXAgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBPTkVfU0RJX0FVRElPX0dST1VQID0gbmV3IEF1ZGlvU3RyZWFtT3JkZXJPcHRpb25zKCdTTVBURTIxMTAuKFNHUlApJyk7XG5cbiAgLyoqIFVzZSBhIGN1c3RvbSBhdWRpbyBzdHJlYW0gb3JkZXIgdmFsdWUgKi9cbiAgcHVibGljIHN0YXRpYyBvZih2YWx1ZTogc3RyaW5nKTogQXVkaW9TdHJlYW1PcmRlck9wdGlvbnMgeyByZXR1cm4gbmV3IEF1ZGlvU3RyZWFtT3JkZXJPcHRpb25zKHZhbHVlKTsgfVxuICAvKiogQHBhcmFtIHZhbHVlIFRoZSBhdWRpbyBzdHJlYW0gb3JkZXIgc3RyaW5nIHZhbHVlICovXG4gIHByaXZhdGUgY29uc3RydWN0b3IocHVibGljIHJlYWRvbmx5IHZhbHVlOiBzdHJpbmcpIHt9XG4gIC8qKiBSZXR1cm5zIHRoZSBzdHJpbmcgdmFsdWUgKi9cbiAgcHVibGljIHRvU3RyaW5nKCk6IHN0cmluZyB7IHJldHVybiB0aGlzLnZhbHVlOyB9XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgTWVkaWEgU3RyZWFtIFR5cGVcbiAqXG4gKiBAaW50ZXJuYWxcbiAqL1xuZW51bSBNZWRpYVN0cmVhbVR5cGUge1xuICAvKipcbiAgICogT3B0aW9uIGZvciBWaWRlb1xuICAgKi9cbiAgVklERU89J3ZpZGVvJyxcbiAgLyoqXG4gICAqIE9wdGlvbiBmb3IgQXVkaW9cbiAgICovXG4gIEFVRElPPSdhdWRpbycsXG4gIC8qKlxuICAgKiBPcHRpb24gZm9yIGFuY2lsbGFyeSBkYXRhXG4gICAqL1xuICBBTkNJTExBUllfREFUQT0nYW5jaWxsYXJ5LWRhdGEnLFxufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIE1lZGlhIFZpZGVvIGZvcm1hdFxuICovXG5leHBvcnQgY2xhc3MgTWVkaWFWaWRlb0Zvcm1hdCB7XG4gIC8qKiBPcHRpb24gZm9yIDIxNjBwICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgVUhEXzIxNjBQID0gbmV3IE1lZGlhVmlkZW9Gb3JtYXQoJzIxNjBwJyk7XG4gIC8qKiBPcHRpb24gZm9yIDEwODBwICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgSERfMTA4MFAgPSBuZXcgTWVkaWFWaWRlb0Zvcm1hdCgnMTA4MHAnKTtcbiAgLyoqIE9wdGlvbiBmb3IgMTA4MGkgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBIRF8xMDgwSSA9IG5ldyBNZWRpYVZpZGVvRm9ybWF0KCcxMDgwaScpO1xuICAvKiogT3B0aW9uIGZvciA3MjBwICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgSERfNzIwUCA9IG5ldyBNZWRpYVZpZGVvRm9ybWF0KCc3MjBwJyk7XG4gIC8qKiBPcHRpb24gZm9yIDQ4MHAgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBTRF80ODBQID0gbmV3IE1lZGlhVmlkZW9Gb3JtYXQoJzQ4MHAnKTtcblxuICAvKiogVXNlIGEgY3VzdG9tIHZpZGVvIGZvcm1hdCB2YWx1ZSAqL1xuICBwdWJsaWMgc3RhdGljIG9mKHZhbHVlOiBzdHJpbmcpOiBNZWRpYVZpZGVvRm9ybWF0IHsgcmV0dXJuIG5ldyBNZWRpYVZpZGVvRm9ybWF0KHZhbHVlKTsgfVxuICAvKiogQHBhcmFtIHZhbHVlIFRoZSB2aWRlbyBmb3JtYXQgc3RyaW5nIHZhbHVlICovXG4gIHByaXZhdGUgY29uc3RydWN0b3IocHVibGljIHJlYWRvbmx5IHZhbHVlOiBzdHJpbmcpIHt9XG4gIC8qKiBSZXR1cm5zIHRoZSBzdHJpbmcgdmFsdWUgKi9cbiAgcHVibGljIHRvU3RyaW5nKCk6IHN0cmluZyB7IHJldHVybiB0aGlzLnZhbHVlOyB9XG59XG5cbi8qKlxuICogQmFzZSBjb25maWd1cmF0aW9uIGZvciBNZWRpYSBTdHJlYW0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWVkaWFTdHJlYW1CYXNlIHtcbiAgLyoqXG4gICAqIEEgdW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoZSBtZWRpYSBzdHJlYW0uXG4gICAqL1xuICByZWFkb25seSBtZWRpYVN0cmVhbUlkOiBudW1iZXI7XG4gIC8qKlxuICAgKiBBIG5hbWUgdGhhdCBoZWxwcyB5b3UgZGlzdGluZ3Vpc2ggb25lIG1lZGlhIHN0cmVhbSBmcm9tIGFub3RoZXIuXG4gICAqL1xuICByZWFkb25seSBtZWRpYVN0cmVhbU5hbWU6IHN0cmluZztcbiAgLyoqXG4gICAqIEEgZGVzY3JpcHRpb24gdGhhdCBjYW4gaGVscCB5b3UgcXVpY2tseSBpZGVudGlmeSB3aGF0IHlvdXIgbWVkaWEgc3RyZWFtIGlzIHVzZWQgZm9yLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIGRlc2NyaXB0aW9uXG4gICAqL1xuICByZWFkb25seSBkZXNjcmlwdGlvbj86IHN0cmluZztcbn1cblxuLyoqXG4gKiBBIG1lZGlhIHN0cmVhbSByZXByZXNlbnRzIG9uZSBjb21wb25lbnQgb2YgeW91ciBjb250ZW50LCBzdWNoIGFzIHZpZGVvLCBhdWRpbywgb3IgYW5jaWxsYXJ5IGRhdGEuXG4gKiBBZnRlciB5b3UgYWRkIGEgbWVkaWEgc3RyZWFtIHRvIHlvdXIgZmxvdywgeW91IGNhbiBhc3NvY2lhdGUgaXQgd2l0aCBzb3VyY2VzIGFuZCBvdXRwdXRzIHRoYXQgdXNlXG4gKiB0aGUgU1QgMjExMCBKUEVHIFhTIG9yIENESSBwcm90b2NvbC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBNZWRpYVN0cmVhbVZpZGVvIGV4dGVuZHMgTWVkaWFTdHJlYW1CYXNlIHtcbiAgLyoqXG4gICAqIEF0dHJpYnV0ZXMgdGhhdCBhcmUgcmVsYXRlZCB0byB0aGUgbWVkaWEgc3RyZWFtLlxuICAgKi9cbiAgcmVhZG9ubHkgZm10cDogRm10cFZpZGVvO1xuICAvKipcbiAgICogVGhlIHNhbXBsZSByYXRlIGZvciB0aGUgc3RyZWFtLiBUaGlzIHZhbHVlIGlzIG1lYXN1cmVkIGluIEh6LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGRlZmF1bHQgY2xvY2sgcmF0ZSBmb3IgdGhlIG1lZGlhIHN0cmVhbSB0eXBlXG4gICAqL1xuICByZWFkb25seSBjbG9ja1JhdGU/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgZm9ybWF0IHR5cGUgbnVtYmVyIChzb21ldGltZXMgcmVmZXJyZWQgdG8gYXMgUlRQIHBheWxvYWQgdHlwZSkgb2YgdGhlIG1lZGlhIHN0cmVhbS5cbiAgICogTWVkaWFDb25uZWN0IGFzc2lnbnMgdGhpcyB2YWx1ZSB0byB0aGUgbWVkaWEgc3RyZWFtLiBGb3IgU1QgMjExMCBKUEVHIFhTIG91dHB1dHMsIHlvdSBuZWVkIHRvIHByb3ZpZGUgdGhpcyB2YWx1ZSB0byB0aGUgcmVjZWl2ZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gYXNzaWduZWQgYnkgTWVkaWFDb25uZWN0XG4gICAqL1xuICByZWFkb25seSBmbXQ/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgcmVzb2x1dGlvbiBvZiB0aGUgdmlkZW8uXG4gICAqL1xuICByZWFkb25seSB2aWRlb0Zvcm1hdDogTWVkaWFWaWRlb0Zvcm1hdDtcbn1cblxuLyoqXG4gKiBBIG1lZGlhIHN0cmVhbSByZXByZXNlbnRzIG9uZSBjb21wb25lbnQgb2YgeW91ciBjb250ZW50LCBzdWNoIGFzIHZpZGVvLCBhdWRpbywgb3IgYW5jaWxsYXJ5IGRhdGEuXG4gKiBBZnRlciB5b3UgYWRkIGEgbWVkaWEgc3RyZWFtIHRvIHlvdXIgZmxvdywgeW91IGNhbiBhc3NvY2lhdGUgaXQgd2l0aCBzb3VyY2VzIGFuZCBvdXRwdXRzIHRoYXQgdXNlXG4gKiB0aGUgU1QgMjExMCBKUEVHIFhTIG9yIENESSBwcm90b2NvbC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBNZWRpYVN0cmVhbUF1ZGlvIGV4dGVuZHMgTWVkaWFTdHJlYW1CYXNlIHtcbiAgLyoqXG4gICAqIFRoZSBmb3JtYXQgb2YgdGhlIGF1ZGlvIGNoYW5uZWwuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdGhlIE1lZGlhQ29ubmVjdCBzZXJ2aWNlIGRlZmF1bHRcbiAgICovXG4gIHJlYWRvbmx5IGNoYW5uZWxPcmRlcj86IEF1ZGlvU3RyZWFtT3JkZXJPcHRpb25zO1xuICAvKipcbiAgICogVGhlIHNhbXBsZSByYXRlIGZvciB0aGUgc3RyZWFtLiBUaGlzIHZhbHVlIGlzIG1lYXN1cmVkIGluIEh6LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGRlZmF1bHQgY2xvY2sgcmF0ZSBmb3IgdGhlIG1lZGlhIHN0cmVhbSB0eXBlXG4gICAqL1xuICByZWFkb25seSBjbG9ja1JhdGU/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgZm9ybWF0IHR5cGUgbnVtYmVyIChzb21ldGltZXMgcmVmZXJyZWQgdG8gYXMgUlRQIHBheWxvYWQgdHlwZSkgb2YgdGhlIG1lZGlhIHN0cmVhbS5cbiAgICogTWVkaWFDb25uZWN0IGFzc2lnbnMgdGhpcyB2YWx1ZSB0byB0aGUgbWVkaWEgc3RyZWFtLiBGb3IgU1QgMjExMCBKUEVHIFhTIG91dHB1dHMsIHlvdSBuZWVkIHRvIHByb3ZpZGUgdGhpcyB2YWx1ZSB0byB0aGUgcmVjZWl2ZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gYXNzaWduZWQgYnkgTWVkaWFDb25uZWN0XG4gICAqL1xuICByZWFkb25seSBmbXQ/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUaGUgYXVkaW8gbGFuZ3VhZ2UsIGluIGEgZm9ybWF0IHRoYXQgaXMgcmVjb2duaXplZCBieSB0aGUgcmVjZWl2ZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gbGFuZ3VhZ2Ugc3BlY2lmaWVkXG4gICAqL1xuICByZWFkb25seSBsYW5nPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEEgbWVkaWEgc3RyZWFtIHJlcHJlc2VudHMgb25lIGNvbXBvbmVudCBvZiB5b3VyIGNvbnRlbnQsIHN1Y2ggYXMgdmlkZW8sIGF1ZGlvLCBvciBhbmNpbGxhcnkgZGF0YS5cbiAqIEFmdGVyIHlvdSBhZGQgYSBtZWRpYSBzdHJlYW0gdG8geW91ciBmbG93LCB5b3UgY2FuIGFzc29jaWF0ZSBpdCB3aXRoIHNvdXJjZXMgYW5kIG91dHB1dHMgdGhhdCB1c2VcbiAqIHRoZSBTVCAyMTEwIEpQRUcgWFMgb3IgQ0RJIHByb3RvY29sLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE1lZGlhU3RyZWFtQW5jaWxsYXJ5RGF0YSBleHRlbmRzIE1lZGlhU3RyZWFtQmFzZSB7IH1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciB0aGUgRmxvd1xuICovXG5leHBvcnQgaW50ZXJmYWNlIEZsb3dQcm9wcyB7XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgZmxvdy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBhdXRvZ2VuZXJhdGVkXG4gICAqL1xuICByZWFkb25seSBmbG93TmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIEF2YWlsYWJpbGl0eSBab25lIHRoYXQgeW91IHdhbnQgdG8gY3JlYXRlIHRoZSBmbG93IGluLiBUaGVzZSBvcHRpb25zIGFyZSBsaW1pdGVkIHRvIHRoZSBBdmFpbGFiaWxpdHkgWm9uZXMgd2l0aGluIHRoZSBjdXJyZW50IEFXUyBSZWdpb24uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gY2hvc2VuIGJ5IE1lZGlhQ29ubmVjdFxuICAgKi9cbiAgcmVhZG9ubHkgYXZhaWxhYmlsaXR5Wm9uZT86IHN0cmluZztcblxuICAvKipcbiAgICogRGV0ZXJtaW5lcyB0aGUgcHJvY2Vzc2luZyBjYXBhY2l0eSBhbmQgZmVhdHVyZSBzZXQgb2YgdGhlIGZsb3cuIFNldCB0aGlzIG9wdGlvbmFsIHBhcmFtZXRlciB0byBMQVJHRSBpZiB5b3Ugd2FudCB0byBlbmFibGUgTkRJIG91dHB1dHMgb24gdGhlIGZsb3cuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gdW5kZWZpbmVkOyB3aGVuIG9taXR0ZWQsIE1lZGlhQ29ubmVjdCBhcHBsaWVzIEZsb3dTaXplLk1FRElVTSBhdCBkZXBsb3kgdGltZVxuICAgKi9cbiAgcmVhZG9ubHkgZmxvd1NpemU/OiBGbG93U2l6ZTtcblxuICAvKipcbiAgICogVGhlIG1haW50ZW5hbmNlIHdpbmRvdyBmb3IgdGhlIGZsb3cuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gY2hvc2VuIGJ5IE1lZGlhQ29ubmVjdFxuICAgKi9cbiAgcmVhZG9ubHkgbWFpbnRlbmFuY2U/OiBNYWludGVuYW5jZVdpbmRvdztcblxuICAvKipcbiAgICogVGhlIG1lZGlhIHN0cmVhbXMgdGhhdCBhcmUgYXNzb2NpYXRlZCB3aXRoIHRoZSBmbG93LiBBZnRlciB5b3UgYXNzb2NpYXRlIGEgbWVkaWEgc3RyZWFtIHdpdGggYSBzb3VyY2UsIHlvdSBjYW4gYWxzbyBhc3NvY2lhdGUgaXQgd2l0aCBvdXRwdXRzIG9uIHRoZSBmbG93LlxuICAgKlxuICAgKiBAZGVmYXVsdCBObyBNZWRpYSBTdHJlYW1zXG4gICAqL1xuICByZWFkb25seSBtZWRpYVN0cmVhbXM/OiBNZWRpYVN0cmVhbVtdO1xuXG4gIC8qKlxuICAgKiBTcGVjaWZpZXMgdGhlIGNvbmZpZ3VyYXRpb24gc2V0dGluZ3MgZm9yIGEgZmxvdydzIE5ESSBzb3VyY2Ugb3Igb3V0cHV0LiBSZXF1aXJlZCB3aGVuIHRoZSBmbG93IGluY2x1ZGVzIGFuIE5ESSBzb3VyY2Ugb3Igb3V0cHV0LlxuICAgKlxuICAgKiBAZGVmYXVsdCBObyBOREkgQ29uZmlndXJhdGlvbiBhcHBsaWVkXG4gICAqL1xuICByZWFkb25seSBuZGlDb25maWc/OiBOZGlDb25maWc7XG5cbiAgLyoqXG4gICAqIEVuY29kaW5nIGNvbmZpZ3VyYXRpb24gYXBwbGllZCB0byB0aGUgTkRJIHNvdXJjZSB3aGVuIHRyYW5zY29kaW5nIGl0IHRvIGEgdHJhbnNwb3J0XG4gICAqIHN0cmVhbSBmb3IgZG93bnN0cmVhbSBkaXN0cmlidXRpb24uXG4gICAqXG4gICAqIFJlcXVpcmVkIHdoZW4gdGhlIGZsb3cgc291cmNlIHVzZXMgdGhlIE5ESSBTcGVlZEhRIHByb3RvY29sXG4gICAqIChzZWUge0BsaW5rIFNvdXJjZUNvbmZpZ3VyYXRpb24ubmRpfSkuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gZW5jb2RpbmcgY29uZmlnOyByZXF1aXJlZCBmb3IgTkRJIHNvdXJjZXNcbiAgICovXG4gIHJlYWRvbmx5IGVuY29kaW5nQ29uZmlnPzogRW5jb2RpbmdDb25maWc7XG5cbiAgLyoqXG4gICAqIFRoZSBzZXR0aW5ncyBmb3IgdGhlIHNvdXJjZSB0aGF0IHlvdSB3YW50IHRvIHVzZSBmb3IgdGhlIG5ldyBmbG93LlxuICAgKi9cbiAgcmVhZG9ubHkgc291cmNlOiBTb3VyY2VDb25maWd1cmF0aW9uO1xuXG4gIC8qKlxuICAgKiBUaGUgc2V0dGluZ3MgZm9yIHNvdXJjZSBmYWlsb3Zlci5cbiAgICpcbiAgICogQGRlZmF1bHQgTm8gc291cmNlIGZhaWxvdmVyIGNvbmZpZ3VyYXRpb24gYXBwbGllZFxuICAgKi9cbiAgcmVhZG9ubHkgc291cmNlRmFpbG92ZXJDb25maWc/OiBGYWlsb3ZlckNvbmZpZztcblxuICAvKipcbiAgICogVGhlIHNldHRpbmdzIGZvciBzb3VyY2UgbW9uaXRvcmluZy5cbiAgICpcbiAgICogQGRlZmF1bHQgTm8gc291cmNlIG1vbml0b3JpbmcgY29uZmlndXJhdGlvbiBhcHBsaWVkXG4gICAqL1xuICByZWFkb25seSBzb3VyY2VNb25pdG9yaW5nQ29uZmlnPzogU291cmNlTW9uaXRvcmluZ0NvbmZpZztcblxuICAvKipcbiAgICogVGhlIFZQQyBJbnRlcmZhY2VzIGZvciB0aGlzIGZsb3cuXG4gICAqXG4gICAqIFVzZSB0aGlzIGluc3RlYWQgb2YgdGhlIEZsb3dWcGNJbnRlcmZhY2UgY29uc3RydWN0LlxuICAgKlxuICAgKiBAZGVmYXVsdCBObyBWUEMgSW50ZXJmYWNlIGNvbmZpZ3VyYXRpb24gYXBwbGllZFxuICAgKi9cbiAgcmVhZG9ubHkgdnBjSW50ZXJmYWNlcz86IFZwY0ludGVyZmFjZUNvbmZpZ1tdO1xuXG59XG5cbi8qKlxuICogU2ltcGxpZmllZCBjb25maWd1cmF0aW9uIGZvciBNZWRpYSBTdHJlYW1zXG4gKi9cbmV4cG9ydCBjbGFzcyBNZWRpYVN0cmVhbSB7XG4gIC8qKlxuICAgKiBDb25maWd1cmF0aW9uIGZvciBNZWRpYVN0cmVhbSBWaWRlb1xuICAgKi9cbiAgcHVibGljIHN0YXRpYyB2aWRlbyhjb25maWc6IE1lZGlhU3RyZWFtVmlkZW8pOiBNZWRpYVN0cmVhbSB7XG4gICAgcmV0dXJuIG5ldyBNZWRpYVN0cmVhbSh7XG4gICAgICBtZWRpYVN0cmVhbUlkOiBjb25maWcubWVkaWFTdHJlYW1JZCxcbiAgICAgIG1lZGlhU3RyZWFtTmFtZTogY29uZmlnLm1lZGlhU3RyZWFtTmFtZSxcbiAgICAgIHZpZGVvRm9ybWF0OiBjb25maWcudmlkZW9Gb3JtYXQudmFsdWUsXG4gICAgICBjbG9ja1JhdGU6IGNvbmZpZy5jbG9ja1JhdGUsXG4gICAgICBmbXQ6IGNvbmZpZy5mbXQsXG4gICAgICBkZXNjcmlwdGlvbjogY29uZmlnLmRlc2NyaXB0aW9uLFxuICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICBmbXRwOiB7XG4gICAgICAgICAgZXhhY3RGcmFtZXJhdGU6IGNvbmZpZy5mbXRwLmV4YWN0RnJhbWVyYXRlPy50b1N0cmluZygpLFxuICAgICAgICAgIHBhcjogY29uZmlnLmZtdHAucGFyPy50b1N0cmluZygpLFxuICAgICAgICAgIGNvbG9yaW1ldHJ5OiBjb25maWcuZm10cC5jb2xvcmltZXRyeT8udmFsdWUsXG4gICAgICAgICAgcmFuZ2U6IGNvbmZpZy5mbXRwLnZpZGVvUmFuZ2U/LnZhbHVlLFxuICAgICAgICAgIHNjYW5Nb2RlOiBjb25maWcuZm10cC5zY2FuTW9kZT8udmFsdWUsXG4gICAgICAgICAgdGNzOiBjb25maWcuZm10cC50Y3M/LnZhbHVlLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIG1lZGlhU3RyZWFtVHlwZTogTWVkaWFTdHJlYW1UeXBlLlZJREVPLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbmZpZ3VyYXRpb24gZm9yIE1lZGlhU3RyZWFtIGF1ZGlvXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGF1ZGlvKGNvbmZpZzogTWVkaWFTdHJlYW1BdWRpbyk6IE1lZGlhU3RyZWFtIHtcbiAgICByZXR1cm4gbmV3IE1lZGlhU3RyZWFtKHtcbiAgICAgIG1lZGlhU3RyZWFtSWQ6IGNvbmZpZy5tZWRpYVN0cmVhbUlkLFxuICAgICAgbWVkaWFTdHJlYW1OYW1lOiBjb25maWcubWVkaWFTdHJlYW1OYW1lLFxuICAgICAgY2xvY2tSYXRlOiBjb25maWcuY2xvY2tSYXRlLFxuICAgICAgZm10OiBjb25maWcuZm10LFxuICAgICAgZGVzY3JpcHRpb246IGNvbmZpZy5kZXNjcmlwdGlvbixcbiAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgZm10cDoge1xuICAgICAgICAgIGNoYW5uZWxPcmRlcjogY29uZmlnLmNoYW5uZWxPcmRlcj8udmFsdWUsXG4gICAgICAgIH0sXG4gICAgICAgIGxhbmc6IGNvbmZpZy5sYW5nLFxuICAgICAgfSxcbiAgICAgIG1lZGlhU3RyZWFtVHlwZTogTWVkaWFTdHJlYW1UeXBlLkFVRElPLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbmZpZ3VyYXRpb24gZm9yIE1lZGlhU3RyZWFtIGFuY2lsbGFyeSBkYXRhXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGFuY2lsbGFyeURhdGEoY29uZmlnOiBNZWRpYVN0cmVhbUFuY2lsbGFyeURhdGEpOiBNZWRpYVN0cmVhbSB7XG4gICAgcmV0dXJuIG5ldyBNZWRpYVN0cmVhbSh7XG4gICAgICBtZWRpYVN0cmVhbUlkOiBjb25maWcubWVkaWFTdHJlYW1JZCxcbiAgICAgIG1lZGlhU3RyZWFtTmFtZTogY29uZmlnLm1lZGlhU3RyZWFtTmFtZSxcbiAgICAgIGRlc2NyaXB0aW9uOiBjb25maWcuZGVzY3JpcHRpb24sXG4gICAgICBtZWRpYVN0cmVhbVR5cGU6IE1lZGlhU3RyZWFtVHlwZS5BTkNJTExBUllfREFUQSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBfY29uZmlnOiBDZm5GbG93Lk1lZGlhU3RyZWFtUHJvcGVydHkpIHt9XG5cbiAgLyoqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcHVibGljIF9iaW5kKCk6IENmbkZsb3cuTWVkaWFTdHJlYW1Qcm9wZXJ0eSB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbmZpZztcbiAgfVxufVxuXG4vKipcbiAqIEF0dHJpYnV0ZXMgZm9yIGltcG9ydGluZyBhbiBleGlzdGluZyBGbG93LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEZsb3dBdHRyaWJ1dGVzIHtcbiAgLyoqXG4gICAqIFRoZSBBUk4gb2YgdGhlIGZsb3cuXG4gICAqL1xuICByZWFkb25seSBmbG93QXJuOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyB3aGV0aGVyIGZhaWxvdmVyIGNvbmZpZ3VyZWRcbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IGlzRmFpbG92ZXJFbmFibGVkPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQVJOIG9mIHRoZSBzb3VyY2UgZGVmaW5lZCBvbiB0aGUgZmxvdy5cbiAgICpcbiAgICogTm90IGVuY29kZWQgaW4gdGhlIGZsb3cgQVJOLCBzbyBtdXN0IGJlIHByb3ZpZGVkIGV4cGxpY2l0bHkgd2hlbiB5b3UgbmVlZFxuICAgKiBhY2Nlc3MgdG8gYHNvdXJjZUFybmAgb24gdGhlIGltcG9ydGVkIGNvbnN0cnVjdC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBzb3VyY2VBcm4gaXMgbm90IGF2YWlsYWJsZSBvbiB0aGUgaW1wb3J0ZWQgY29uc3RydWN0XG4gICAqL1xuICByZWFkb25seSBzb3VyY2VBcm4/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBJUCBhZGRyZXNzIHRoYXQgdGhlIGZsb3cgdXNlcyB0byBzZW5kIG91dGJvdW5kIGNvbnRlbnQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gYWNjZXNzaW5nIGBlZ3Jlc3NJcGAgb24gdGhlIGltcG9ydGVkIGZsb3cgdGhyb3dzOyBvbmx5IHByb3ZpZGUgd2hlbiBhdmFpbGFibGUuXG4gICAqL1xuICByZWFkb25seSBlZ3Jlc3NJcD86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIElQIGFkZHJlc3MgdGhhdCB0aGUgZmxvdyBsaXN0ZW5zIG9uIGZvciBpbmNvbWluZyBjb250ZW50LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGFjY2Vzc2luZyBgc291cmNlSW5nZXN0SXBgIG9uIHRoZSBpbXBvcnRlZCBmbG93IHRocm93czsgb25seSBwcm92aWRlIHdoZW4gYXZhaWxhYmxlLlxuICAgKi9cbiAgcmVhZG9ubHkgc291cmNlSW5nZXN0SXA/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBwb3J0IHRoYXQgdGhlIGZsb3cgbGlzdGVucyBvbiBmb3IgaW5jb21pbmcgY29udGVudC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBhY2Nlc3NpbmcgYHNvdXJjZUluZ2VzdFBvcnRgIG9uIHRoZSBpbXBvcnRlZCBmbG93IHRocm93czsgb25seSBwcm92aWRlIHdoZW4gYXZhaWxhYmxlLlxuICAgKi9cbiAgcmVhZG9ubHkgc291cmNlSW5nZXN0UG9ydD86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIEF2YWlsYWJpbGl0eSBab25lIHRoYXQgdGhlIGZsb3cgd2FzIGNyZWF0ZWQgaW4uXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gYGZsb3dBdmFpbGFiaWxpdHlab25lYCBpcyB1bmRlZmluZWQgb24gdGhlIGltcG9ydGVkIGZsb3cuXG4gICAqL1xuICByZWFkb25seSBmbG93QXZhaWxhYmlsaXR5Wm9uZT86IHN0cmluZztcbn1cblxuYWJzdHJhY3QgY2xhc3MgRmxvd0Jhc2UgZXh0ZW5kcyBSZXNvdXJjZSBpbXBsZW1lbnRzIElGbG93IHtcbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBGbG93IGNvbnN0cnVjdCB0aGF0IHJlcHJlc2VudHMgYW4gZXh0ZXJuYWwgKGltcG9ydGVkKSBGbG93LlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBmcm9tRmxvd0F0dHJpYnV0ZXMoc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgYXR0cnM6IEZsb3dBdHRyaWJ1dGVzKTogSUZsb3cge1xuICAgIGNsYXNzIEltcG9ydCBleHRlbmRzIEZsb3dCYXNlIGltcGxlbWVudHMgSUZsb3cge1xuICAgICAgcHVibGljIHJlYWRvbmx5IGZsb3dBcm4gPSBhdHRycy5mbG93QXJuO1xuICAgICAgcHVibGljIHJlYWRvbmx5IGZsb3dBdmFpbGFiaWxpdHlab25lID0gYXR0cnMuZmxvd0F2YWlsYWJpbGl0eVpvbmU7XG5cbiAgICAgIC8vIEltcG9ydGVkIGZsb3dzIGRlZmF1bHQgdG8gYGZhbHNlYC4gUGFzcyBgaXNGYWlsb3ZlckVuYWJsZWQ6IHRydWVgIGluIHRoZVxuICAgICAgLy8gYXR0cmlidXRlcyB3aGVuIHRoZSByZWFsIHNlcnZpY2Utc2lkZSBmbG93IGhhcyBmYWlsb3ZlciBlbmFibGVkIGFuZCB5b3VcbiAgICAgIC8vIG5lZWQgdG8gYWRkIGEgRmxvd1NvdXJjZS5cbiAgICAgIHB1YmxpYyBpc0ZhaWxvdmVyRW5hYmxlZD86IGJvb2xlYW4gPSBhdHRycy5pc0ZhaWxvdmVyRW5hYmxlZCA/PyBmYWxzZTtcblxuICAgICAgcHVibGljIGdldCBzb3VyY2VBcm4oKTogc3RyaW5nIHtcbiAgICAgICAgaWYgKGF0dHJzLnNvdXJjZUFybikgcmV0dXJuIGF0dHJzLnNvdXJjZUFybjtcbiAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihcbiAgICAgICAgICBsaXRgU291cmNlQXJuTm90UHJvdmlkZWRgLFxuICAgICAgICAgIGAnc291cmNlQXJuJyB3YXMgbm90IHByb3ZpZGVkIHdoZW4gaW1wb3J0aW5nIEZsb3cgJHt0aGlzLm5vZGUucGF0aH07IHByb3ZpZGUgJ3NvdXJjZUFybicgaW4gZnJvbUZsb3dBdHRyaWJ1dGVzKClgLFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIHB1YmxpYyBnZXQgZWdyZXNzSXAoKTogc3RyaW5nIHtcbiAgICAgICAgaWYgKGF0dHJzLmVncmVzc0lwKSByZXR1cm4gYXR0cnMuZWdyZXNzSXA7XG4gICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoXG4gICAgICAgICAgbGl0YEVncmVzc0lwTm90UHJvdmlkZWRgLFxuICAgICAgICAgIGAnZWdyZXNzSXAnIHdhcyBub3QgcHJvdmlkZWQgd2hlbiBpbXBvcnRpbmcgRmxvdyAke3RoaXMubm9kZS5wYXRofTsgcHJvdmlkZSBpdCBpbiBmcm9tRmxvd0F0dHJpYnV0ZXMoKWAsXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgcHVibGljIGdldCBzb3VyY2VJbmdlc3RJcCgpOiBzdHJpbmcge1xuICAgICAgICBpZiAoYXR0cnMuc291cmNlSW5nZXN0SXApIHJldHVybiBhdHRycy5zb3VyY2VJbmdlc3RJcDtcbiAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihcbiAgICAgICAgICBsaXRgU291cmNlSW5nZXN0SXBOb3RQcm92aWRlZGAsXG4gICAgICAgICAgYCdzb3VyY2VJbmdlc3RJcCcgd2FzIG5vdCBwcm92aWRlZCB3aGVuIGltcG9ydGluZyBGbG93ICR7dGhpcy5ub2RlLnBhdGh9OyBwcm92aWRlIGl0IGluIGZyb21GbG93QXR0cmlidXRlcygpYCxcbiAgICAgICAgICB0aGlzLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBwdWJsaWMgZ2V0IHNvdXJjZUluZ2VzdFBvcnQoKTogc3RyaW5nIHtcbiAgICAgICAgaWYgKGF0dHJzLnNvdXJjZUluZ2VzdFBvcnQpIHJldHVybiBhdHRycy5zb3VyY2VJbmdlc3RQb3J0O1xuICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKFxuICAgICAgICAgIGxpdGBTb3VyY2VJbmdlc3RQb3J0Tm90UHJvdmlkZWRgLFxuICAgICAgICAgIGAnc291cmNlSW5nZXN0UG9ydCcgd2FzIG5vdCBwcm92aWRlZCB3aGVuIGltcG9ydGluZyBGbG93ICR7dGhpcy5ub2RlLnBhdGh9OyBwcm92aWRlIGl0IGluIGZyb21GbG93QXR0cmlidXRlcygpYCxcbiAgICAgICAgICB0aGlzLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBwdWJsaWMgZ2V0IHNvdXJjZUluZ2VzdFVybCgpOiBzdHJpbmcge1xuICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKFxuICAgICAgICAgIGxpdGBTb3VyY2VJbmdlc3RVcmxOb3RBdmFpbGFibGVJbXBvcnRlZGAsXG4gICAgICAgICAgYCdzb3VyY2VJbmdlc3RVcmwnIGlzIG5vdCBhdmFpbGFibGUgb24gaW1wb3J0ZWQgRmxvdyAke3RoaXMubm9kZS5wYXRofTsgb25seSBGbG93cyBjb25zdHJ1Y3RlZCBpbiB0aGlzIGFwcCBmb3IgbGlzdGVuZXItc3R5bGUgc291cmNlIHByb3RvY29scyAoUlRQLCBSVFAtRkVDLCBSSVNULCBTUlQgbGlzdGVuZXIsIFppeGkgcHVzaCkgZXhwb3NlIGEgc291cmNlIGluZ2VzdCBVUkxgLFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBJbXBvcnQoc2NvcGUsIGlkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbXBvcnQgYW4gZXhpc3RpbmcgRmxvdyBmcm9tIGl0cyBBUk4uXG4gICAqXG4gICAqIFVzZSBgZnJvbUZsb3dBdHRyaWJ1dGVzKClgIGluc3RlYWQgaWYgeW91IG5lZWQgYWNjZXNzIHRvIGBzb3VyY2VBcm5gIG9yIGFueSBvdGhlclxuICAgKiBhdHRyaWJ1dGUgbm90IGVuY29kZWQgaW4gdGhlIGZsb3cgQVJOLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBmcm9tRmxvd0FybihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBmbG93QXJuOiBzdHJpbmcpOiBJRmxvdyB7XG4gICAgcmV0dXJuIEZsb3cuZnJvbUZsb3dBdHRyaWJ1dGVzKHNjb3BlLCBpZCwgeyBmbG93QXJuIH0pO1xuICB9XG5cbiAgcHVibGljIGFic3RyYWN0IHJlYWRvbmx5IHNvdXJjZUFybjogc3RyaW5nO1xuICBwdWJsaWMgYWJzdHJhY3QgcmVhZG9ubHkgZmxvd0Fybjogc3RyaW5nO1xuICBwdWJsaWMgYWJzdHJhY3QgcmVhZG9ubHkgZWdyZXNzSXA6IHN0cmluZztcbiAgcHVibGljIGFic3RyYWN0IHJlYWRvbmx5IHNvdXJjZUluZ2VzdElwOiBzdHJpbmc7XG4gIHB1YmxpYyBhYnN0cmFjdCByZWFkb25seSBzb3VyY2VJbmdlc3RQb3J0OiBzdHJpbmc7XG4gIHB1YmxpYyBhYnN0cmFjdCByZWFkb25seSBzb3VyY2VJbmdlc3RVcmw6IHN0cmluZztcbiAgcHVibGljIGFic3RyYWN0IHJlYWRvbmx5IGZsb3dBdmFpbGFiaWxpdHlab25lPzogc3RyaW5nO1xuICBwdWJsaWMgYWJzdHJhY3QgcmVhZG9ubHkgaXNGYWlsb3ZlckVuYWJsZWQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaGUgTkRJIHN0YXRlIGZvciB0aGlzIGZsb3cuIGB1bmRlZmluZWRgIGZvciBpbXBvcnRlZCBmbG93cyAoc3RhdGUgaXMgdW5rbm93bikuXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcHJvdGVjdGVkIF9uZGlTdGF0ZT86IFN0YXRlO1xuXG4gIC8qKlxuICAgKiBUaGUgc291cmNlIHByb3RvY29sIHZhbHVlIGZvciB0aGlzIGZsb3cuIGB1bmRlZmluZWRgIGZvciBpbXBvcnRlZCBmbG93cy5cbiAgICogQGludGVybmFsXG4gICAqL1xuICBwcm90ZWN0ZWQgX3NvdXJjZVByb3RvY29sPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUcmFja3MgdGhlIG51bWJlciBvZiBOREkgb3V0cHV0cyBhZGRlZCB0byB0aGlzIGZsb3cuIFVzZWQgdG8gZW5mb3JjZSB0aGVcbiAgICogZG9jdW1lbnRlZCBcIm1heCAxIE5ESSBvdXRwdXQgcGVyIGZsb3dcIiBsaW1pdC5cbiAgICogQGludGVybmFsXG4gICAqL1xuICBwcm90ZWN0ZWQgX25kaU91dHB1dENvdW50ID0gMDtcblxuICAvKipcbiAgICogQ29sbGVjdGlvbiBvZiBncmFudCBtZXRob2RzIGZvciB0aGlzIGZsb3cuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgZ3JhbnRzID0gRmxvd0dyYW50cy5mcm9tRmxvdyh0aGlzKTtcblxuICAvKipcbiAgICogQSByZWZlcmVuY2UgdG8gdGhpcyBGbG93IHJlc291cmNlLlxuICAgKiBSZXF1aXJlZCBieSB0aGUgYXV0by1nZW5lcmF0ZWQgSUZsb3dSZWYgaW50ZXJmYWNlLlxuICAgKi9cbiAgcHVibGljIGdldCBmbG93UmVmKCk6IEZsb3dSZWZlcmVuY2Uge1xuICAgIHJldHVybiB7XG4gICAgICBmbG93QXJuOiB0aGlzLmZsb3dBcm4sXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgYW4gb3V0cHV0IHRvIHRoaXMgZmxvd1xuICAgKi9cbiAgcHVibGljIGFkZE91dHB1dChpZDogc3RyaW5nLCBvdXRwdXRDb25maWc6IE91dHB1dENvbmZpZ3VyYXRpb24pOiBJRmxvd091dHB1dCB7XG4gICAgY29uc3QgcHJvdG9jb2wgPSBvdXRwdXRDb25maWcuX2JpbmQoKS5wcm90b2NvbDtcblxuICAgIGlmIChwcm90b2NvbCA9PT0gJ25kaS1zcGVlZC1ocScpIHtcbiAgICAgIGlmICh0aGlzLl9uZGlTdGF0ZSAhPT0gdW5kZWZpbmVkICYmIHRoaXMuX25kaVN0YXRlICE9PSBTdGF0ZS5FTkFCTEVEKSB7XG4gICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoXG4gICAgICAgICAgbGl0YE5kaU91dHB1dFJlcXVpcmVzTmRpQ29uZmlnYCxcbiAgICAgICAgICAnTkRJIG91dHB1dHMgcmVxdWlyZSBuZGlDb25maWcgd2l0aCBuZGlTdGF0ZSBzZXQgdG8gU3RhdGUuRU5BQkxFRCBvbiB0aGUgZmxvdycsXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gTkRJIHBhc3N0aHJvdWdoIGlzIG5vdCBzdXBwb3J0ZWQg4oCUIGEgZmxvdyBjYW5ub3QgaGF2ZSBib3RoIGFuIE5ESSBzb3VyY2VcbiAgICAgIC8vIGFuZCBhbiBOREkgb3V0cHV0LiBUaGUgc2VydmljZSByZWplY3RzIHRoaXMgYXQgZGVwbG95OyBmYWlsIGZhc3QgaGVyZS5cbiAgICAgIGlmICh0aGlzLl9zb3VyY2VQcm90b2NvbCA9PT0gU291cmNlUHJvdG9jb2wuTkRJX1NQRUVEX0hRLnZhbHVlKSB7XG4gICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoXG4gICAgICAgICAgbGl0YE5kaVBhc3N0aHJvdWdoTm90U3VwcG9ydGVkYCxcbiAgICAgICAgICAnTkRJIHBhc3N0aHJvdWdoIGlzIG5vdCBzdXBwb3J0ZWQuIEEgZmxvdyBjYW5ub3QgaGF2ZSBib3RoIGFuIE5ESSBzb3VyY2UgYW5kIGFuIE5ESSBvdXRwdXQnLFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIEEgZmxvdyBzdXBwb3J0cyBhIG1heGltdW0gb2YgMSBOREkgb3V0cHV0IChMYXJnZSBmbG93IHNpemUsIHRyYW5zcG9ydFxuICAgICAgLy8gc3RyZWFtIHByb3RvY29scyArIDEgTkRJIG91dHB1dCkuXG4gICAgICAvLyBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9tZWRpYWNvbm5lY3QvbGF0ZXN0L3VnL2Zsb3ctc2l6ZXMtY2FwYWJpbGl0aWVzLmh0bWxcbiAgICAgIGlmICh0aGlzLl9uZGlPdXRwdXRDb3VudCA+PSAxKSB7XG4gICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoXG4gICAgICAgICAgbGl0YE5kaU91dHB1dExpbWl0YCxcbiAgICAgICAgICAnQSBmbG93IHN1cHBvcnRzIGEgbWF4aW11bSBvZiAxIE5ESSBvdXRwdXQnLFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICB0aGlzLl9uZGlPdXRwdXRDb3VudCsrO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgRmxvd091dHB1dCh0aGlzLCBpZCwge1xuICAgICAgZmxvdzogdGhpcyxcbiAgICAgIG91dHB1dDogb3V0cHV0Q29uZmlnLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIENsb3VkV2F0Y2ggbWV0cmljIGZvciB0aGlzIGZsb3cuXG4gICAqL1xuICBwdWJsaWMgbWV0cmljKG1ldHJpY05hbWU6IHN0cmluZywgcHJvcHM/OiBNZXRyaWNPcHRpb25zKTogTWV0cmljIHtcbiAgICByZXR1cm4gbmV3IE1ldHJpYyh7XG4gICAgICBtZXRyaWNOYW1lLFxuICAgICAgbmFtZXNwYWNlOiAnQVdTL01lZGlhQ29ubmVjdCcsXG4gICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgIEZsb3dBUk46IHRoaXMuZmxvd0FybixcbiAgICAgIH0sXG4gICAgICAuLi5wcm9wcyxcbiAgICB9KS5hdHRhY2hUbyh0aGlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRyaWMgZm9yIHRoZSBiaXRyYXRlIG9mIGNvbnRlbnQgaW5nZXN0ZWQgaW50byB0aGUgZmxvdy5cbiAgICpcbiAgICogRW1pdHMgdGhlIGBTb3VyY2VCaXRSYXRlYCBtZXRyaWMgd2l0aCBkaW1lbnNpb24gYEZsb3dBUk5gLCB3aGljaCBhZ2dyZWdhdGVzIGFjcm9zc1xuICAgKiBhbGwgc291cmNlcyBvbiB0aGUgZmxvdy4gVG8gbmFycm93IHRvIGEgc3BlY2lmaWMgc291cmNlIG9uIGEgbXVsdGktc291cmNlIGZsb3csIGNhbGxcbiAgICoge0BsaW5rIG1ldHJpY30gd2l0aCBhbiBhZGRpdGlvbmFsIGBTb3VyY2VBUk5gIGRpbWVuc2lvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBhdmVyYWdlIG92ZXIgNjAgc2Vjb25kc1xuICAgKi9cbiAgcHVibGljIG1ldHJpY1NvdXJjZUJpdHJhdGUocHJvcHM/OiBNZXRyaWNPcHRpb25zKTogTWV0cmljIHtcbiAgICByZXR1cm4gdGhpcy5tZXRyaWMoJ1NvdXJjZUJpdFJhdGUnLCB7XG4gICAgICBzdGF0aXN0aWM6ICdhdmcnLFxuICAgICAgcGVyaW9kOiBEdXJhdGlvbi5zZWNvbmRzKDYwKSxcbiAgICAgIHVuaXQ6IFVuaXQuQklUU19QRVJfU0VDT05ELFxuICAgICAgLi4ucHJvcHMsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogTWV0cmljIGZvciBwYWNrZXRzIHRoYXQgd2VyZSBsb3N0IGluIHRyYW5zaXQgYW5kIG5vdCByZWNvdmVyZWQgYnkgZXJyb3IgY29ycmVjdGlvbi5cbiAgICpcbiAgICogRW1pdHMgdGhlIGBTb3VyY2VOb3RSZWNvdmVyZWRQYWNrZXRzYCBtZXRyaWMgd2l0aCBkaW1lbnNpb24gYEZsb3dBUk5gLCB3aGljaCBhZ2dyZWdhdGVzXG4gICAqIGFjcm9zcyBhbGwgc291cmNlcyBvbiB0aGUgZmxvdy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBzdW0gb3ZlciA2MCBzZWNvbmRzXG4gICAqL1xuICBwdWJsaWMgbWV0cmljU291cmNlTm90UmVjb3ZlcmVkUGFja2V0cyhwcm9wcz86IE1ldHJpY09wdGlvbnMpOiBNZXRyaWMge1xuICAgIHJldHVybiB0aGlzLm1ldHJpYygnU291cmNlTm90UmVjb3ZlcmVkUGFja2V0cycsIHtcbiAgICAgIHN0YXRpc3RpYzogJ3N1bScsXG4gICAgICBwZXJpb2Q6IER1cmF0aW9uLnNlY29uZHMoNjApLFxuICAgICAgdW5pdDogVW5pdC5DT1VOVCxcbiAgICAgIC4uLnByb3BzLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldHJpYyBmb3IgdGhlIHRvdGFsIG51bWJlciBvZiBwYWNrZXRzIHJlY2VpdmVkIGJ5IHRoZSBmbG93IHNvdXJjZXMuXG4gICAqXG4gICAqIEVtaXRzIHRoZSBgU291cmNlVG90YWxQYWNrZXRzYCBtZXRyaWMgd2l0aCBkaW1lbnNpb24gYEZsb3dBUk5gLCB3aGljaCBhZ2dyZWdhdGVzIGFjcm9zc1xuICAgKiBhbGwgc291cmNlcyBvbiB0aGUgZmxvdy5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBzdW0gb3ZlciA2MCBzZWNvbmRzXG4gICAqL1xuICBwdWJsaWMgbWV0cmljU291cmNlVG90YWxQYWNrZXRzKHByb3BzPzogTWV0cmljT3B0aW9ucyk6IE1ldHJpYyB7XG4gICAgcmV0dXJuIHRoaXMubWV0cmljKCdTb3VyY2VUb3RhbFBhY2tldHMnLCB7XG4gICAgICBzdGF0aXN0aWM6ICdzdW0nLFxuICAgICAgcGVyaW9kOiBEdXJhdGlvbi5zZWNvbmRzKDYwKSxcbiAgICAgIHVuaXQ6IFVuaXQuQ09VTlQsXG4gICAgICAuLi5wcm9wcyxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRyaWMgaW5kaWNhdGluZyB3aGljaCBzb3VyY2UgaXMgc2VsZWN0ZWQgZm9yIGluZ2VzdCB3aGVuIHVzaW5nIGBGYWlsb3ZlcmAgZmFpbG92ZXIgbW9kZS5cbiAgICogQSB2YWx1ZSBvZiAxIGluZGljYXRlcyB0aGUgc291cmNlIGlzIGJlaW5nIHVzZWQgYXMgdGhlIGlucHV0OyAwIGluZGljYXRlcyBpdCBpcyBzdGFuZGJ5LlxuICAgKlxuICAgKiBFbWl0cyB0aGUgYFNvdXJjZVNlbGVjdGVkYCBtZXRyaWMgd2l0aCBkaW1lbnNpb24gYEZsb3dBUk5gLiBUbyBuYXJyb3cgdG8gYSBzcGVjaWZpYyBzb3VyY2UsXG4gICAqIGNhbGwge0BsaW5rIG1ldHJpY30gd2l0aCBhbiBhZGRpdGlvbmFsIGBTb3VyY2VBUk5gIGRpbWVuc2lvbi5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBtYXhpbXVtIG92ZXIgNjAgc2Vjb25kc1xuICAgKi9cbiAgcHVibGljIG1ldHJpY1NvdXJjZVNlbGVjdGVkKHByb3BzPzogTWV0cmljT3B0aW9ucyk6IE1ldHJpYyB7XG4gICAgcmV0dXJuIHRoaXMubWV0cmljKCdTb3VyY2VTZWxlY3RlZCcsIHtcbiAgICAgIHN0YXRpc3RpYzogJ21heCcsXG4gICAgICBwZXJpb2Q6IER1cmF0aW9uLnNlY29uZHMoNjApLFxuICAgICAgdW5pdDogVW5pdC5OT05FLFxuICAgICAgLi4ucHJvcHMsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogTWV0cmljIGluZGljYXRpbmcgdGhlIGNvbm5lY3Rpb24gc3RhdGUgb2YgdGhlIHNvdXJjZS4gMSBmb3IgY29ubmVjdGVkLCAwIGZvciBkaXNjb25uZWN0ZWQuXG4gICAqIEFwcGxpZXMgb25seSB0byBaaXhpLCBTUlQsIGFuZCBSSVNUIHNvdXJjZXMuXG4gICAqXG4gICAqIEVtaXRzIHRoZSBgU291cmNlQ29ubmVjdGVkYCBtZXRyaWMgd2l0aCBkaW1lbnNpb24gYEZsb3dBUk5gLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG1pbmltdW0gb3ZlciA2MCBzZWNvbmRzXG4gICAqL1xuICBwdWJsaWMgbWV0cmljU291cmNlQ29ubmVjdGVkKHByb3BzPzogTWV0cmljT3B0aW9ucyk6IE1ldHJpYyB7XG4gICAgcmV0dXJuIHRoaXMubWV0cmljKCdTb3VyY2VDb25uZWN0ZWQnLCB7XG4gICAgICBzdGF0aXN0aWM6ICdtaW4nLFxuICAgICAgcGVyaW9kOiBEdXJhdGlvbi5zZWNvbmRzKDYwKSxcbiAgICAgIHVuaXQ6IFVuaXQuTk9ORSxcbiAgICAgIC4uLnByb3BzLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldHJpYyBmb3IgdGhlIG51bWJlciBvZiB0aW1lcyB0aGUgc291cmNlIHRyYW5zaXRpb25lZCBmcm9tIGNvbm5lY3RlZCB0byBkaXNjb25uZWN0ZWQuXG4gICAqXG4gICAqIEVtaXRzIHRoZSBgU291cmNlRGlzY29ubmVjdGlvbnNgIG1ldHJpYyB3aXRoIGRpbWVuc2lvbiBgRmxvd0FSTmAuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gc3VtIG92ZXIgNjAgc2Vjb25kc1xuICAgKi9cbiAgcHVibGljIG1ldHJpY1NvdXJjZURpc2Nvbm5lY3Rpb25zKHByb3BzPzogTWV0cmljT3B0aW9ucyk6IE1ldHJpYyB7XG4gICAgcmV0dXJuIHRoaXMubWV0cmljKCdTb3VyY2VEaXNjb25uZWN0aW9ucycsIHtcbiAgICAgIHN0YXRpc3RpYzogJ3N1bScsXG4gICAgICBwZXJpb2Q6IER1cmF0aW9uLnNlY29uZHMoNjApLFxuICAgICAgdW5pdDogVW5pdC5DT1VOVCxcbiAgICAgIC4uLnByb3BzLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldHJpYyBmb3IgdGhlIG51bWJlciBvZiBwYWNrZXRzIGxvc3QgZHVyaW5nIHRyYW5zaXQsIG1lYXN1cmVkIGJlZm9yZSBhbnkgZXJyb3JcbiAgICogY29ycmVjdGlvbiB0YWtlcyBwbGFjZS5cbiAgICpcbiAgICogRW1pdHMgdGhlIGBTb3VyY2VEcm9wcGVkUGFja2V0c2AgbWV0cmljIHdpdGggZGltZW5zaW9uIGBGbG93QVJOYC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBzdW0gb3ZlciA2MCBzZWNvbmRzXG4gICAqL1xuICBwdWJsaWMgbWV0cmljU291cmNlRHJvcHBlZFBhY2tldHMocHJvcHM/OiBNZXRyaWNPcHRpb25zKTogTWV0cmljIHtcbiAgICByZXR1cm4gdGhpcy5tZXRyaWMoJ1NvdXJjZURyb3BwZWRQYWNrZXRzJywge1xuICAgICAgc3RhdGlzdGljOiAnc3VtJyxcbiAgICAgIHBlcmlvZDogRHVyYXRpb24uc2Vjb25kcyg2MCksXG4gICAgICB1bml0OiBVbml0LkNPVU5ULFxuICAgICAgLi4ucHJvcHMsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogTWV0cmljIGZvciB0aGUgcGVyY2VudGFnZSBvZiBwYWNrZXRzIGxvc3QgZHVyaW5nIHRyYW5zaXQsIGV2ZW4gaWYgdGhleSB3ZXJlIHJlY292ZXJlZC5cbiAgICpcbiAgICogRW1pdHMgdGhlIGBTb3VyY2VQYWNrZXRMb3NzUGVyY2VudGAgbWV0cmljIHdpdGggZGltZW5zaW9uIGBGbG93QVJOYC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBhdmVyYWdlIG92ZXIgNjAgc2Vjb25kc1xuICAgKi9cbiAgcHVibGljIG1ldHJpY1NvdXJjZVBhY2tldExvc3NQZXJjZW50KHByb3BzPzogTWV0cmljT3B0aW9ucyk6IE1ldHJpYyB7XG4gICAgcmV0dXJuIHRoaXMubWV0cmljKCdTb3VyY2VQYWNrZXRMb3NzUGVyY2VudCcsIHtcbiAgICAgIHN0YXRpc3RpYzogJ2F2ZycsXG4gICAgICBwZXJpb2Q6IER1cmF0aW9uLnNlY29uZHMoNjApLFxuICAgICAgdW5pdDogVW5pdC5QRVJDRU5ULFxuICAgICAgLi4ucHJvcHMsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogTWV0cmljIGZvciB0aGUgcm91bmQtdHJpcCB0aW1lIGJldHdlZW4gdGhlIHNvdXJjZSBhbmQgTWVkaWFDb25uZWN0LiBBcHBsaWVzIG9ubHkgdG9cbiAgICogUklTVCwgWml4aSwgYW5kIFNSVCBzb3VyY2VzLlxuICAgKlxuICAgKiBFbWl0cyB0aGUgYFNvdXJjZVJvdW5kVHJpcFRpbWVgIG1ldHJpYyB3aXRoIGRpbWVuc2lvbiBgRmxvd0FSTmAuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gYXZlcmFnZSBvdmVyIDYwIHNlY29uZHNcbiAgICovXG4gIHB1YmxpYyBtZXRyaWNTb3VyY2VSb3VuZFRyaXBUaW1lKHByb3BzPzogTWV0cmljT3B0aW9ucyk6IE1ldHJpYyB7XG4gICAgcmV0dXJuIHRoaXMubWV0cmljKCdTb3VyY2VSb3VuZFRyaXBUaW1lJywge1xuICAgICAgc3RhdGlzdGljOiAnYXZnJyxcbiAgICAgIHBlcmlvZDogRHVyYXRpb24uc2Vjb25kcyg2MCksXG4gICAgICB1bml0OiBVbml0Lk1JTExJU0VDT05EUyxcbiAgICAgIC4uLnByb3BzLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldHJpYyBmb3IgdGhlIGN1cnJlbnQgbmV0d29yayBqaXR0ZXIgb2YgdGhlIHNvdXJjZSwgbWVhc3VyZWQgaW4gbWlsbGlzZWNvbmRzLlxuICAgKlxuICAgKiBFbWl0cyB0aGUgYFNvdXJjZUppdHRlcmAgbWV0cmljIHdpdGggZGltZW5zaW9uIGBGbG93QVJOYC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBhdmVyYWdlIG92ZXIgNjAgc2Vjb25kc1xuICAgKi9cbiAgcHVibGljIG1ldHJpY1NvdXJjZUppdHRlcihwcm9wcz86IE1ldHJpY09wdGlvbnMpOiBNZXRyaWMge1xuICAgIHJldHVybiB0aGlzLm1ldHJpYygnU291cmNlSml0dGVyJywge1xuICAgICAgc3RhdGlzdGljOiAnYXZnJyxcbiAgICAgIHBlcmlvZDogRHVyYXRpb24uc2Vjb25kcyg2MCksXG4gICAgICB1bml0OiBVbml0Lk1JTExJU0VDT05EUyxcbiAgICAgIC4uLnByb3BzLFxuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogRGVmaW5lcyBhbiBBV1MgRWxlbWVudGFsIE1lZGlhQ29ubmVjdCBGbG93LlxuICovXG5AcHJvcGVydHlJbmplY3RhYmxlXG5leHBvcnQgY2xhc3MgRmxvdyBleHRlbmRzIEZsb3dCYXNlIGltcGxlbWVudHMgSUZsb3cge1xuICAvKiogVW5pcXVlbHkgaWRlbnRpZmllcyB0aGlzIGNsYXNzLiAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IFBST1BFUlRZX0lOSkVDVElPTl9JRDogc3RyaW5nID0gJ0Bhd3MtY2RrLmF3cy1tZWRpYWNvbm5lY3QtYWxwaGEuRmxvdyc7XG5cbiAgLyoqXG4gICAqIFRoZSBzZXQgb2Ygc291cmNlIHByb3RvY29scyB3aGVyZSB0aGUgZmxvdyBvcGVucyBhbiBJUDpwb3J0IGFuZCBsaXN0ZW5zIGZvclxuICAgKiB1cHN0cmVhbSBjb250ZW50LiBEZXRlcm1pbmVzIGF2YWlsYWJpbGl0eSBvZiBgc291cmNlSW5nZXN0SXBgLCBgc291cmNlSW5nZXN0UG9ydGAsXG4gICAqIGFuZCBgc291cmNlSW5nZXN0VXJsYC4gTWFwcyBlYWNoIHByb3RvY29sIHRvIHRoZSBVUkwgc2NoZW1lIHVzZWQgdG8gY29uc3RydWN0XG4gICAqIHRoZSBpbmdlc3QgVVJMLlxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgTElTVEVORVJfUFJPVE9DT0xfU0NIRU1FUzogUmVhZG9ubHlNYXA8c3RyaW5nLCBzdHJpbmc+ID0gbmV3IE1hcChbXG4gICAgWydydHAnLCAncnRwJ10sXG4gICAgWydydHAtZmVjJywgJ3J0cCddLFxuICAgIFsncmlzdCcsICdyaXN0J10sXG4gICAgWydzcnQtbGlzdGVuZXInLCAnc3J0J10sXG4gICAgWyd6aXhpLXB1c2gnLCAneml4aSddLFxuICBdKTtcblxuICBwcml2YXRlIHN0YXRpYyBpc0xpc3RlbmVyU3R5bGVQcm90b2NvbChwcm90b2NvbDogc3RyaW5nIHwgdW5kZWZpbmVkKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHByb3RvY29sICE9PSB1bmRlZmluZWQgJiYgRmxvdy5MSVNURU5FUl9QUk9UT0NPTF9TQ0hFTUVTLmhhcyhwcm90b2NvbCk7XG4gIH1cblxuICBwdWJsaWMgcmVhZG9ubHkgZmxvd0Fybjogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgc291cmNlQXJuOiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBlZ3Jlc3NJcDogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IF9zb3VyY2VJbmdlc3RJcDogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IF9zb3VyY2VJbmdlc3RQb3J0OiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2hhc0xpc3RlbmVyU291cmNlOiBib29sZWFuO1xuICBwdWJsaWMgcmVhZG9ubHkgZmxvd0F2YWlsYWJpbGl0eVpvbmU/OiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBpc0ZhaWxvdmVyRW5hYmxlZD86IGJvb2xlYW4gPSBmYWxzZTtcbiAgcHJpdmF0ZSB2cGNJbnRlcmZhY2VzOiBDZm5GbG93LlZwY0ludGVyZmFjZVByb3BlcnR5W10gPSBbXTtcblxuICBwdWJsaWMgZ2V0IHNvdXJjZUluZ2VzdElwKCk6IHN0cmluZyB7XG4gICAgaWYgKCF0aGlzLl9oYXNMaXN0ZW5lclNvdXJjZSkge1xuICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihcbiAgICAgICAgbGl0YFNvdXJjZUluZ2VzdElwTm90QXZhaWxhYmxlU291cmNlUHJvdG9jb2xgLFxuICAgICAgICBgJ3NvdXJjZUluZ2VzdElwJyBpcyBub3QgYXZhaWxhYmxlIG9uIHRoaXMgRmxvdyAke3RoaXMubm9kZS5wYXRofTsgb25seSBsaXN0ZW5lci1zdHlsZSBzb3VyY2UgcHJvdG9jb2xzIChSVFAsIFJUUC1GRUMsIFJJU1QsIFNSVCBsaXN0ZW5lciwgWml4aSBwdXNoKSBleHBvc2UgYSBzb3VyY2UgaW5nZXN0IElQIOKAlCBDREksIEpQRUcgWFMsIGVudGl0bGVtZW50LCBnYXRld2F5IGJyaWRnZSwgcm91dGVyLCBhbmQgU1JUIGNhbGxlciBzb3VyY2VzIGRvIG5vdGAsXG4gICAgICAgIHRoaXMsXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fc291cmNlSW5nZXN0SXA7XG4gIH1cblxuICBwdWJsaWMgZ2V0IHNvdXJjZUluZ2VzdFBvcnQoKTogc3RyaW5nIHtcbiAgICBpZiAoIXRoaXMuX2hhc0xpc3RlbmVyU291cmNlKSB7XG4gICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKFxuICAgICAgICBsaXRgU291cmNlSW5nZXN0UG9ydE5vdEF2YWlsYWJsZVNvdXJjZVByb3RvY29sYCxcbiAgICAgICAgYCdzb3VyY2VJbmdlc3RQb3J0JyBpcyBub3QgYXZhaWxhYmxlIG9uIHRoaXMgRmxvdyAke3RoaXMubm9kZS5wYXRofTsgb25seSBsaXN0ZW5lci1zdHlsZSBzb3VyY2UgcHJvdG9jb2xzIChSVFAsIFJUUC1GRUMsIFJJU1QsIFNSVCBsaXN0ZW5lciwgWml4aSBwdXNoKSBleHBvc2UgYSBzb3VyY2UgaW5nZXN0IHBvcnQg4oCUIENESSwgSlBFRyBYUywgZW50aXRsZW1lbnQsIGdhdGV3YXkgYnJpZGdlLCByb3V0ZXIsIGFuZCBTUlQgY2FsbGVyIHNvdXJjZXMgZG8gbm90YCxcbiAgICAgICAgdGhpcyxcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9zb3VyY2VJbmdlc3RQb3J0O1xuICB9XG5cbiAgcHVibGljIGdldCBzb3VyY2VJbmdlc3RVcmwoKTogc3RyaW5nIHtcbiAgICBpZiAoIXRoaXMuX2hhc0xpc3RlbmVyU291cmNlKSB7XG4gICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKFxuICAgICAgICBsaXRgU291cmNlSW5nZXN0VXJsTm90QXZhaWxhYmxlU291cmNlUHJvdG9jb2xgLFxuICAgICAgICBgJ3NvdXJjZUluZ2VzdFVybCcgaXMgbm90IGF2YWlsYWJsZSBvbiB0aGlzIEZsb3cgJHt0aGlzLm5vZGUucGF0aH07IG9ubHkgbGlzdGVuZXItc3R5bGUgc291cmNlIHByb3RvY29scyAoUlRQLCBSVFAtRkVDLCBSSVNULCBTUlQgbGlzdGVuZXIsIFppeGkgcHVzaCkgZXhwb3NlIGEgc291cmNlIGluZ2VzdCBVUkwg4oCUIENESSwgSlBFRyBYUywgZW50aXRsZW1lbnQsIGdhdGV3YXkgYnJpZGdlLCByb3V0ZXIsIGFuZCBTUlQgY2FsbGVyIHNvdXJjZXMgZG8gbm90YCxcbiAgICAgICAgdGhpcyxcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNvbXB1dGVJbmdlc3RVcmwodGhpcy5fc291cmNlUHJvdG9jb2wsIHRoaXMuX3NvdXJjZUluZ2VzdElwLCB0aGlzLl9zb3VyY2VJbmdlc3RQb3J0KTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBGbG93UHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQsIHtcbiAgICAgIHBoeXNpY2FsTmFtZTogcHJvcHM/LmZsb3dOYW1lID8/IExhenkuc3RyaW5nKHsgcHJvZHVjZTogKCkgPT4gTmFtZXMudW5pcXVlUmVzb3VyY2VOYW1lKHRoaXMsIHsgbWF4TGVuZ3RoOiA2NCB9KSB9KSxcbiAgICB9KTtcblxuICAgIC8vIFZhbGlkYXRlIGZsb3cgbmFtZSBpZiBwcm92aWRlZFxuICAgIHRoaXMudmFsaWRhdGVOYW1lKHByb3BzKTtcblxuICAgIC8vIEVuaGFuY2VkIENESyBBbmFseXRpY3MgVGVsZW1ldHJ5XG4gICAgYWRkQ29uc3RydWN0TWV0YWRhdGEodGhpcywgcHJvcHMpO1xuXG4gICAgLy8gVmFsaWRhdGUgbWFpbnRlbmFuY2Ugc3RhcnQgaG91ciBmb3JtYXRcbiAgICBpZiAocHJvcHMubWFpbnRlbmFuY2UpIHtcbiAgICAgIHZhbGlkYXRlTWFpbnRlbmFuY2VUaW1lKHByb3BzLm1haW50ZW5hbmNlLm1haW50ZW5hbmNlU3RhcnRIb3VyKTtcbiAgICB9XG5cbiAgICAvLyBWYWxpZGF0ZSBzb3VyY2UgbW9uaXRvcmluZyB0aHJlc2hvbGRzIGFuZCBjb250ZW50LXF1YWxpdHkgcmVxdWlyZW1lbnRzXG4gICAgdGhpcy52YWxpZGF0ZU1vbml0b3JpbmcocHJvcHMpO1xuXG4gICAgLy8gVmFsaWRhdGUgZW5jb2RpbmcgY29uZmlnIHZpZGVvIG1heCBiaXRyYXRlIHJhbmdlICgxMC01MCBNYnBzKVxuICAgIHRoaXMudmFsaWRhdGVFbmNvZGluZyhwcm9wcyk7XG5cbiAgICAvLyBPbmx5IGl0ZXJhdGUgYSBrbm93bi1jb25jcmV0ZSB2cGNJbnRlcmZhY2VzIGxpc3Q7IHNraXAgdG9rZW5pemVkIGxpc3RzIHRvIGF2b2lkXG4gICAgLy8gcHVzaGluZyB0aGUgdG9rZW4gbWFya2VyIGludG8gb3VyIGludGVybmFsIGNvbGxlY3Rpb24uXG4gICAgaWYgKHByb3BzLnZwY0ludGVyZmFjZXMgIT09IHVuZGVmaW5lZCAmJiAhVG9rZW4uaXNVbnJlc29sdmVkKHByb3BzLnZwY0ludGVyZmFjZXMpKSB7XG4gICAgICBwcm9wcy52cGNJbnRlcmZhY2VzLmZvckVhY2godnBjID0+IHRoaXMuYWRkVnBjSW50ZXJmYWNlKHZwYykpO1xuICAgIH1cbiAgICB0aGlzLmlzRmFpbG92ZXJFbmFibGVkID0gcHJvcHMuc291cmNlRmFpbG92ZXJDb25maWc/Ll9pc0VuYWJsZWQgPz8gZmFsc2U7XG5cbiAgICBjb25zdCBzb3VyY2VDb25maWcgPSBwcm9wcy5zb3VyY2UuX2JpbmQodGhpcywgU3RhY2sub2YodGhpcykuZm9ybWF0QXJuKHtcbiAgICAgIHNlcnZpY2U6ICdtZWRpYWNvbm5lY3QnLFxuICAgICAgcmVzb3VyY2U6ICdmbG93JyxcbiAgICAgIHJlc291cmNlTmFtZTogYCo6JHt0aGlzLnBoeXNpY2FsTmFtZX1gLFxuICAgICAgYXJuRm9ybWF0OiBBcm5Gb3JtYXQuQ09MT05fUkVTT1VSQ0VfTkFNRSxcbiAgICB9KSk7XG5cbiAgICBpZiAoKHNvdXJjZUNvbmZpZy5wcm90b2NvbCA9PT0gU291cmNlUHJvdG9jb2wuSlBFR1hTLnZhbHVlIHx8IHNvdXJjZUNvbmZpZy5wcm90b2NvbCA9PT0gU291cmNlUHJvdG9jb2wuQ0RJLnZhbHVlKVxuICAgICAgJiYgcHJvcHMuZmxvd1NpemU/LnZhbHVlICE9PSBGbG93U2l6ZS5MQVJHRV80WC52YWx1ZSkge1xuICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihcbiAgICAgICAgbGl0YEZsb3dTaXplUmVxdWlyZWRgLFxuICAgICAgICAnRmxvd3MgdXNpbmcgSlBFRyBYUyBhbmQgQ0RJIHByb3RvY29scyByZXF1aXJlIExBUkdFXzRYIGZsb3cgc2l6ZTsgc2V0IGZsb3dTaXplIHRvIEZsb3dTaXplLkxBUkdFXzRYJyxcbiAgICAgICAgdGhpcyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gTkRJIGNvbnN0cmFpbnRzIChkaXNjb3Zlcnkgc2VydmVyIGxpbWl0LCBwcm90b2NvbCBjb25mbGljdHMsIGZsb3cgc2l6ZSwgc291cmNlIHJlcXVpcmVtZW50cylcbiAgICB0aGlzLnZhbGlkYXRlTmRpKHByb3BzLCBzb3VyY2VDb25maWcpO1xuXG4gICAgLy8gTEFSR0VfNFggb25seSBzdXBwb3J0cyBDREkgYW5kIEpQRUcgWFMgcHJvdG9jb2xzXG4gICAgaWYgKHByb3BzLmZsb3dTaXplPy52YWx1ZSA9PT0gRmxvd1NpemUuTEFSR0VfNFgudmFsdWVcbiAgICAgICYmIHNvdXJjZUNvbmZpZy5wcm90b2NvbCAhPT0gU291cmNlUHJvdG9jb2wuSlBFR1hTLnZhbHVlXG4gICAgICAmJiBzb3VyY2VDb25maWcucHJvdG9jb2wgIT09IFNvdXJjZVByb3RvY29sLkNESS52YWx1ZSkge1xuICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihcbiAgICAgICAgbGl0YEZsb3dTaXplTGFyZ2U0eFByb3RvY29sYCxcbiAgICAgICAgJ0xBUkdFXzRYIGZsb3cgc2l6ZSBvbmx5IHN1cHBvcnRzIENESSBhbmQgSlBFRyBYUyBwcm90b2NvbHMnLFxuICAgICAgICB0aGlzLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBWUEMgaW50ZXJmYWNlIEVGQS1jb3VudCBsaW1pdFxuICAgIHRoaXMudmFsaWRhdGVWcGNFZmFDb3VudChwcm9wcyk7XG5cbiAgICBjb25zdCBmbG93ID0gbmV3IENmbkZsb3codGhpcywgJ1Jlc291cmNlJywge1xuICAgICAgbmFtZTogdGhpcy5waHlzaWNhbE5hbWUsXG4gICAgICBzb3VyY2U6IHNvdXJjZUNvbmZpZyxcbiAgICAgIGF2YWlsYWJpbGl0eVpvbmU6IHByb3BzPy5hdmFpbGFiaWxpdHlab25lLFxuICAgICAgZmxvd1NpemU6IHByb3BzPy5mbG93U2l6ZT8udmFsdWUsXG4gICAgICBtYWludGVuYW5jZTogcHJvcHM/Lm1haW50ZW5hbmNlID8ge1xuICAgICAgICBtYWludGVuYW5jZURheTogdG9UaXRsZUNhc2UocHJvcHMubWFpbnRlbmFuY2UubWFpbnRlbmFuY2VEYXkpLFxuICAgICAgICBtYWludGVuYW5jZVN0YXJ0SG91cjogcHJvcHMubWFpbnRlbmFuY2UubWFpbnRlbmFuY2VTdGFydEhvdXIsXG4gICAgICB9IDogdW5kZWZpbmVkLFxuICAgICAgbWVkaWFTdHJlYW1zOiBwcm9wcy5tZWRpYVN0cmVhbXMgPyBwcm9wcy5tZWRpYVN0cmVhbXMubWFwKHN0cmVhbSA9PiBzdHJlYW0uX2JpbmQoKSkgOiB1bmRlZmluZWQsXG4gICAgICBuZGlDb25maWc6IHByb3BzLm5kaUNvbmZpZyA/IHtcbiAgICAgICAgbWFjaGluZU5hbWU6IHByb3BzLm5kaUNvbmZpZy5tYWNoaW5lTmFtZSxcbiAgICAgICAgbmRpU3RhdGU6IHByb3BzLm5kaUNvbmZpZy5uZGlTdGF0ZSxcbiAgICAgICAgbmRpRGlzY292ZXJ5U2VydmVyczogcHJvcHMubmRpQ29uZmlnLm5kaURpc2NvdmVyeVNlcnZlcnM/Lm1hcChzZXJ2ZXIgPT4gKHtcbiAgICAgICAgICBkaXNjb3ZlcnlTZXJ2ZXJBZGRyZXNzOiBzZXJ2ZXIuZGlzY292ZXJ5U2VydmVyQWRkcmVzcyxcbiAgICAgICAgICBkaXNjb3ZlcnlTZXJ2ZXJQb3J0OiBzZXJ2ZXIuZGlzY292ZXJ5U2VydmVyUG9ydCxcbiAgICAgICAgICB2cGNJbnRlcmZhY2VBZGFwdGVyOiBzZXJ2ZXIudnBjSW50ZXJmYWNlLm5hbWUsXG4gICAgICAgIH0pKSxcbiAgICAgIH0gOiB1bmRlZmluZWQsXG4gICAgICBlbmNvZGluZ0NvbmZpZzogcHJvcHMuZW5jb2RpbmdDb25maWcgPyB7XG4gICAgICAgIGVuY29kaW5nUHJvZmlsZTogcHJvcHMuZW5jb2RpbmdDb25maWcuZW5jb2RpbmdQcm9maWxlLFxuICAgICAgICB2aWRlb01heEJpdHJhdGU6IHByb3BzLmVuY29kaW5nQ29uZmlnLnZpZGVvTWF4Qml0cmF0ZT8udG9CcHMoKSxcbiAgICAgIH0gOiB1bmRlZmluZWQsXG4gICAgICBzb3VyY2VGYWlsb3ZlckNvbmZpZzogcHJvcHMuc291cmNlRmFpbG92ZXJDb25maWc/Ll9iaW5kKCksXG4gICAgICBzb3VyY2VNb25pdG9yaW5nQ29uZmlnOiBwcm9wcy5zb3VyY2VNb25pdG9yaW5nQ29uZmlnID8ge1xuICAgICAgICBjb250ZW50UXVhbGl0eUFuYWx5c2lzU3RhdGU6IHByb3BzLnNvdXJjZU1vbml0b3JpbmdDb25maWcuY29udGVudFF1YWxpdHlBbmFseXNpc1N0YXRlLFxuICAgICAgICB0aHVtYm5haWxTdGF0ZTogcHJvcHMuc291cmNlTW9uaXRvcmluZ0NvbmZpZy50aHVtYm5haWxTdGF0ZSxcbiAgICAgICAgYXVkaW9Nb25pdG9yaW5nU2V0dGluZ3M6IHByb3BzLnNvdXJjZU1vbml0b3JpbmdDb25maWcuc2lsZW50QXVkaW8gPyBbe1xuICAgICAgICAgIHNpbGVudEF1ZGlvOiB7XG4gICAgICAgICAgICBzdGF0ZTogcHJvcHMuc291cmNlTW9uaXRvcmluZ0NvbmZpZy5zaWxlbnRBdWRpby5zdGF0ZSxcbiAgICAgICAgICAgIHRocmVzaG9sZFNlY29uZHM6IHByb3BzLnNvdXJjZU1vbml0b3JpbmdDb25maWcuc2lsZW50QXVkaW8udGhyZXNob2xkLnRvU2Vjb25kcygpLFxuICAgICAgICAgIH0sXG4gICAgICAgIH1dIDogdW5kZWZpbmVkLFxuICAgICAgICB2aWRlb01vbml0b3JpbmdTZXR0aW5nczogcHJvcHMuc291cmNlTW9uaXRvcmluZ0NvbmZpZy5ibGFja0ZyYW1lcyB8fCBwcm9wcy5zb3VyY2VNb25pdG9yaW5nQ29uZmlnLmZyb3plbkZyYW1lcyA/IFt7XG4gICAgICAgICAgYmxhY2tGcmFtZXM6IHByb3BzLnNvdXJjZU1vbml0b3JpbmdDb25maWcuYmxhY2tGcmFtZXMgPyB7XG4gICAgICAgICAgICBzdGF0ZTogcHJvcHMuc291cmNlTW9uaXRvcmluZ0NvbmZpZy5ibGFja0ZyYW1lcy5zdGF0ZSxcbiAgICAgICAgICAgIHRocmVzaG9sZFNlY29uZHM6IHByb3BzLnNvdXJjZU1vbml0b3JpbmdDb25maWcuYmxhY2tGcmFtZXMudGhyZXNob2xkLnRvU2Vjb25kcygpLFxuICAgICAgICAgIH0gOiB1bmRlZmluZWQsXG4gICAgICAgICAgZnJvemVuRnJhbWVzOiBwcm9wcy5zb3VyY2VNb25pdG9yaW5nQ29uZmlnLmZyb3plbkZyYW1lcyA/IHtcbiAgICAgICAgICAgIHN0YXRlOiBwcm9wcy5zb3VyY2VNb25pdG9yaW5nQ29uZmlnLmZyb3plbkZyYW1lcy5zdGF0ZSxcbiAgICAgICAgICAgIHRocmVzaG9sZFNlY29uZHM6IHByb3BzLnNvdXJjZU1vbml0b3JpbmdDb25maWcuZnJvemVuRnJhbWVzLnRocmVzaG9sZC50b1NlY29uZHMoKSxcbiAgICAgICAgICB9IDogdW5kZWZpbmVkLFxuICAgICAgICB9XSA6IHVuZGVmaW5lZCxcbiAgICAgIH0gOiB1bmRlZmluZWQsXG4gICAgICB2cGNJbnRlcmZhY2VzOiBMYXp5LmFueSh7IHByb2R1Y2U6ICgpID0+IHRoaXMudnBjSW50ZXJmYWNlcyB9LCB7IG9taXRFbXB0eUFycmF5OiB0cnVlIH0pLFxuICAgIH0pO1xuXG4gICAgdGhpcy5mbG93QXJuID0gZmxvdy5hdHRyRmxvd0FybjtcbiAgICB0aGlzLnNvdXJjZUFybiA9IGZsb3cuYXR0clNvdXJjZVNvdXJjZUFybjtcbiAgICB0aGlzLmVncmVzc0lwID0gZmxvdy5hdHRyRWdyZXNzSXA7XG4gICAgdGhpcy5fc291cmNlSW5nZXN0SXAgPSBmbG93LmF0dHJTb3VyY2VJbmdlc3RJcDtcbiAgICB0aGlzLl9zb3VyY2VJbmdlc3RQb3J0ID0gZmxvdy5hdHRyU291cmNlU291cmNlSW5nZXN0UG9ydDtcbiAgICB0aGlzLmZsb3dBdmFpbGFiaWxpdHlab25lID0gZmxvdy5hdHRyRmxvd0F2YWlsYWJpbGl0eVpvbmU7XG4gICAgdGhpcy5fbmRpU3RhdGUgPSBwcm9wcy5uZGlDb25maWc/Lm5kaVN0YXRlID8/IFN0YXRlLkRJU0FCTEVEO1xuICAgIHRoaXMuX3NvdXJjZVByb3RvY29sID0gc291cmNlQ29uZmlnLnByb3RvY29sO1xuICAgIHRoaXMuX2hhc0xpc3RlbmVyU291cmNlID0gRmxvdy5pc0xpc3RlbmVyU3R5bGVQcm90b2NvbChzb3VyY2VDb25maWcucHJvdG9jb2wpO1xuXG4gICAgdGhpcy5ub2RlLmFkZFZhbGlkYXRpb24oe1xuICAgICAgdmFsaWRhdGU6ICgpID0+IHtcbiAgICAgICAgY29uc3QgbmFtZXMgPSB0aGlzLnZwY0ludGVyZmFjZXMubWFwKHYgPT4gdi5uYW1lKS5maWx0ZXIobiA9PiAhVG9rZW4uaXNVbnJlc29sdmVkKG4pKTtcbiAgICAgICAgY29uc3QgZHVwbGljYXRlcyA9IFsuLi5uZXcgU2V0KG5hbWVzLmZpbHRlcigobiwgaSkgPT4gbmFtZXMuaW5kZXhPZihuKSAhPT0gaSkpXTtcbiAgICAgICAgcmV0dXJuIGR1cGxpY2F0ZXMubGVuZ3RoID4gMFxuICAgICAgICAgID8gW2BWUEMgaW50ZXJmYWNlIG5hbWVzIG11c3QgYmUgdW5pcXVlIHdpdGhpbiBhIGZsb3cuIER1cGxpY2F0ZSBuYW1lKHMpOiAke2R1cGxpY2F0ZXMuam9pbignLCAnKX1gXVxuICAgICAgICAgIDogW107XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqIFZhbGlkYXRlIHRoZSBmbG93IG5hbWUgbGVuZ3RoIGFuZCBjaGFyYWN0ZXIgc2V0LCB3aGVuIGEgY29uY3JldGUgdmFsdWUgaXMgcHJvdmlkZWQuICovXG4gIHByaXZhdGUgdmFsaWRhdGVOYW1lKHByb3BzOiBGbG93UHJvcHMpOiB2b2lkIHtcbiAgICBpZiAocHJvcHMuZmxvd05hbWUgIT0gbnVsbCAmJiBwcm9wcy5mbG93TmFtZSAhPT0gJycgJiYgIVRva2VuLmlzVW5yZXNvbHZlZChwcm9wcy5mbG93TmFtZSkpIHtcbiAgICAgIGlmIChwcm9wcy5mbG93TmFtZS5sZW5ndGggPiA2NCkge1xuICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKGxpdGBGbG93TmFtZUxlbmd0aGAsIGBGbG93IG5hbWUgbXVzdCBiZSBiZXR3ZWVuIDEgYW5kIDY0IGNoYXJhY3RlcnMsIGdvdCAke3Byb3BzLmZsb3dOYW1lLmxlbmd0aH1gLCB0aGlzKTtcbiAgICAgIH1cbiAgICAgIGlmICghL15bYS16QS1aMC05Xy1dKyQvLnRlc3QocHJvcHMuZmxvd05hbWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IobGl0YEZsb3dOYW1lRm9ybWF0YCwgYEZsb3cgbmFtZSBtdXN0IGNvbnRhaW4gb25seSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycywgaHlwaGVucywgYW5kIHVuZGVyc2NvcmVzLCBnb3QgJyR7cHJvcHMuZmxvd05hbWV9J2AsIHRoaXMpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBzb3VyY2UtbW9uaXRvcmluZyB0aHJlc2hvbGRzICgxMC02MCBzZWNvbmRzKSBhbmQgdGhhdCB0aGUgcGVyLW1ldHJpYyBjaGVja3MgYXJlIG9ubHlcbiAgICogdXNlZCB3aGVuIGNvbnRlbnQtcXVhbGl0eSBhbmFseXNpcyBpcyBlbmFibGVkLlxuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZU1vbml0b3JpbmcocHJvcHM6IEZsb3dQcm9wcyk6IHZvaWQge1xuICAgIGNvbnN0IG1vbml0b3JpbmcgPSBwcm9wcy5zb3VyY2VNb25pdG9yaW5nQ29uZmlnO1xuICAgIGlmIChtb25pdG9yaW5nICYmIChtb25pdG9yaW5nLnNpbGVudEF1ZGlvIHx8IG1vbml0b3JpbmcuYmxhY2tGcmFtZXMgfHwgbW9uaXRvcmluZy5mcm96ZW5GcmFtZXMpXG4gICAgICAmJiBtb25pdG9yaW5nLmNvbnRlbnRRdWFsaXR5QW5hbHlzaXNTdGF0ZSAhPT0gU3RhdGUuRU5BQkxFRCkge1xuICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihcbiAgICAgICAgbGl0YE1vbml0b3JpbmdNZXRyaWNzUmVxdWlyZUNvbnRlbnRRdWFsaXR5QW5hbHlzaXNgLFxuICAgICAgICAnc2lsZW50QXVkaW8sIGJsYWNrRnJhbWVzLCBhbmQgZnJvemVuRnJhbWVzIHJlcXVpcmUgY29udGVudFF1YWxpdHlBbmFseXNpc1N0YXRlIHRvIGJlIFN0YXRlLkVOQUJMRUQnLFxuICAgICAgICB0aGlzLFxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKG1vbml0b3Jpbmc/LnNpbGVudEF1ZGlvKSB7XG4gICAgICBjb25zdCBzZWNzID0gbW9uaXRvcmluZy5zaWxlbnRBdWRpby50aHJlc2hvbGQudG9TZWNvbmRzKCk7XG4gICAgICBpZiAoc2VjcyA8IDEwIHx8IHNlY3MgPiA2MCkge1xuICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKGxpdGBTaWxlbnRBdWRpb1RocmVzaG9sZFJhbmdlYCwgYFNpbGVudCBhdWRpbyB0aHJlc2hvbGQgbXVzdCBiZSBiZXR3ZWVuIDEwIGFuZCA2MCBzZWNvbmRzLCBnb3QgJHtzZWNzfWAsIHRoaXMpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAobW9uaXRvcmluZz8uYmxhY2tGcmFtZXMpIHtcbiAgICAgIGNvbnN0IHNlY3MgPSBtb25pdG9yaW5nLmJsYWNrRnJhbWVzLnRocmVzaG9sZC50b1NlY29uZHMoKTtcbiAgICAgIGlmIChzZWNzIDwgMTAgfHwgc2VjcyA+IDYwKSB7XG4gICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IobGl0YEJsYWNrRnJhbWVzVGhyZXNob2xkUmFuZ2VgLCBgQmxhY2sgZnJhbWVzIHRocmVzaG9sZCBtdXN0IGJlIGJldHdlZW4gMTAgYW5kIDYwIHNlY29uZHMsIGdvdCAke3NlY3N9YCwgdGhpcyk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChtb25pdG9yaW5nPy5mcm96ZW5GcmFtZXMpIHtcbiAgICAgIGNvbnN0IHNlY3MgPSBtb25pdG9yaW5nLmZyb3plbkZyYW1lcy50aHJlc2hvbGQudG9TZWNvbmRzKCk7XG4gICAgICBpZiAoc2VjcyA8IDEwIHx8IHNlY3MgPiA2MCkge1xuICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKGxpdGBGcm96ZW5GcmFtZXNUaHJlc2hvbGRSYW5nZWAsIGBGcm96ZW4gZnJhbWVzIHRocmVzaG9sZCBtdXN0IGJlIGJldHdlZW4gMTAgYW5kIDYwIHNlY29uZHMsIGdvdCAke3NlY3N9YCwgdGhpcyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqIFZhbGlkYXRlIHRoZSBlbmNvZGluZyBjb25maWcncyB2aWRlbyBtYXggYml0cmF0ZSByYW5nZSAoMTAtNTAgTWJwcykuICovXG4gIHByaXZhdGUgdmFsaWRhdGVFbmNvZGluZyhwcm9wczogRmxvd1Byb3BzKTogdm9pZCB7XG4gICAgaWYgKHByb3BzLmVuY29kaW5nQ29uZmlnPy52aWRlb01heEJpdHJhdGUpIHtcbiAgICAgIGNvbnN0IG1icHMgPSBwcm9wcy5lbmNvZGluZ0NvbmZpZy52aWRlb01heEJpdHJhdGUudG9NYnBzKCk7XG4gICAgICBpZiAobWJwcyA8IDEwIHx8IG1icHMgPiA1MCkge1xuICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKFxuICAgICAgICAgIGxpdGBFbmNvZGluZ1ZpZGVvTWF4Qml0cmF0ZVJhbmdlYCxcbiAgICAgICAgICBgRW5jb2RpbmcgY29uZmlnIHZpZGVvTWF4Qml0cmF0ZSBtdXN0IGJlIGJldHdlZW4gMTAgYW5kIDUwIE1icHMsIGdvdCAke21icHN9YCxcbiAgICAgICAgICB0aGlzLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBOREkgY29uc3RyYWludHM6IGRpc2NvdmVyeS1zZXJ2ZXIgbGltaXQsIG11dHVhbCBleGNsdXNpdml0eSB3aXRoIENESS9KUEVHIFhTLCB0aGVcbiAgICogcmVxdWlyZWQgTEFSR0UgZmxvdyBzaXplLCBhbmQgdGhlIHJlcXVpcmVtZW50cyBhbiBOREkgc291cmNlIHBsYWNlcyBvbiB0aGUgZmxvdy5cbiAgICovXG4gIHByaXZhdGUgdmFsaWRhdGVOZGkocHJvcHM6IEZsb3dQcm9wcywgc291cmNlQ29uZmlnOiBDZm5GbG93LlNvdXJjZVByb3BlcnR5KTogdm9pZCB7XG4gICAgLy8gTkRJIGRpc2NvdmVyeSBzZXJ2ZXJzIGxpbWl0IChzZXJ2aWNlIHJlamVjdHMgPjMgYXQgZGVwbG95IHRpbWUpXG4gICAgY29uc3QgZGlzY292ZXJ5U2VydmVycyA9IHByb3BzLm5kaUNvbmZpZz8ubmRpRGlzY292ZXJ5U2VydmVycztcbiAgICBpZiAoZGlzY292ZXJ5U2VydmVycyAhPT0gdW5kZWZpbmVkICYmICFUb2tlbi5pc1VucmVzb2x2ZWQoZGlzY292ZXJ5U2VydmVycykgJiYgZGlzY292ZXJ5U2VydmVycy5sZW5ndGggPiAzKSB7XG4gICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKFxuICAgICAgICBsaXRgTmRpTWF4RGlzY292ZXJ5U2VydmVyc2AsXG4gICAgICAgIGBOREkgY29uZmlnIHN1cHBvcnRzIGEgbWF4aW11bSBvZiAzIGRpc2NvdmVyeSBzZXJ2ZXJzLCBnb3QgJHtkaXNjb3ZlcnlTZXJ2ZXJzLmxlbmd0aH1gLFxuICAgICAgICB0aGlzLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBOREkgY2Fubm90IGNvZXhpc3Qgd2l0aCBDREkgb3IgSlBFRyBYUyDigJQgdGhleSByZXF1aXJlIGRpZmZlcmVudCBmbG93IHNpemVzXG4gICAgaWYgKHByb3BzLm5kaUNvbmZpZz8ubmRpU3RhdGUgPT09IFN0YXRlLkVOQUJMRURcbiAgICAgICYmIChzb3VyY2VDb25maWcucHJvdG9jb2wgPT09IFNvdXJjZVByb3RvY29sLkNESS52YWx1ZSB8fCBzb3VyY2VDb25maWcucHJvdG9jb2wgPT09IFNvdXJjZVByb3RvY29sLkpQRUdYUy52YWx1ZSkpIHtcbiAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoXG4gICAgICAgIGxpdGBOZGlDZGlDb25mbGljdGAsXG4gICAgICAgICdOREkgY2Fubm90IGJlIHVzZWQgd2l0aCBDREkgb3IgSlBFRyBYUyBwcm90b2NvbHM7IE5ESSByZXF1aXJlcyBMQVJHRSBmbG93IHNpemUgd2hpbGUgQ0RJIGFuZCBKUEVHIFhTIHJlcXVpcmUgTEFSR0VfNFgnLFxuICAgICAgICB0aGlzLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBOREkgcmVxdWlyZXMgTEFSR0UgZmxvdyBzaXplIChub3QgTUVESVVNLCBub3QgTEFSR0VfNFgpXG4gICAgaWYgKHByb3BzLm5kaUNvbmZpZz8ubmRpU3RhdGUgPT09IFN0YXRlLkVOQUJMRURcbiAgICAgICYmIHByb3BzLmZsb3dTaXplPy52YWx1ZSAhPT0gRmxvd1NpemUuTEFSR0UudmFsdWUpIHtcbiAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoXG4gICAgICAgIGxpdGBOZGlGbG93U2l6ZVJlcXVpcmVkYCxcbiAgICAgICAgJ05ESSByZXF1aXJlcyBMQVJHRSBmbG93IHNpemU7IHNldCBmbG93U2l6ZSB0byBGbG93U2l6ZS5MQVJHRScsXG4gICAgICAgIHRoaXMsXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIE5ESSBzb3VyY2VzIHJlcXVpcmUgTkRJIHRvIGJlIGVuYWJsZWQgb24gdGhlIGZsb3dcbiAgICBpZiAoc291cmNlQ29uZmlnLnByb3RvY29sID09PSBTb3VyY2VQcm90b2NvbC5ORElfU1BFRURfSFEudmFsdWVcbiAgICAgICYmIHByb3BzLm5kaUNvbmZpZz8ubmRpU3RhdGUgIT09IFN0YXRlLkVOQUJMRUQpIHtcbiAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoXG4gICAgICAgIGxpdGBOZGlTb3VyY2VSZXF1aXJlc05kaUNvbmZpZ2AsXG4gICAgICAgICdOREkgc291cmNlcyByZXF1aXJlIG5kaUNvbmZpZyB3aXRoIG5kaVN0YXRlIHNldCB0byBTdGF0ZS5FTkFCTEVEJyxcbiAgICAgICAgdGhpcyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gTkRJIHNvdXJjZXMgcmVxdWlyZSBMQVJHRSBmbG93IHNpemVcbiAgICBpZiAoc291cmNlQ29uZmlnLnByb3RvY29sID09PSBTb3VyY2VQcm90b2NvbC5ORElfU1BFRURfSFEudmFsdWVcbiAgICAgICYmIHByb3BzLmZsb3dTaXplPy52YWx1ZSAhPT0gRmxvd1NpemUuTEFSR0UudmFsdWUpIHtcbiAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoXG4gICAgICAgIGxpdGBOZGlTb3VyY2VGbG93U2l6ZVJlcXVpcmVkYCxcbiAgICAgICAgJ05ESSBzb3VyY2VzIHJlcXVpcmUgTEFSR0UgZmxvdyBzaXplOyBzZXQgZmxvd1NpemUgdG8gRmxvd1NpemUuTEFSR0UnLFxuICAgICAgICB0aGlzLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBOREkgc291cmNlcyByZXF1aXJlIGVuY29kaW5nQ29uZmlnIHRvIHRyYW5zY29kZSBpbnRvIGEgdHJhbnNwb3J0IHN0cmVhbVxuICAgIGlmIChzb3VyY2VDb25maWcucHJvdG9jb2wgPT09IFNvdXJjZVByb3RvY29sLk5ESV9TUEVFRF9IUS52YWx1ZVxuICAgICAgJiYgIXByb3BzLmVuY29kaW5nQ29uZmlnKSB7XG4gICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKFxuICAgICAgICBsaXRgTmRpU291cmNlUmVxdWlyZXNFbmNvZGluZ0NvbmZpZ2AsXG4gICAgICAgICdOREkgc291cmNlcyByZXF1aXJlIGVuY29kaW5nQ29uZmlnIHRvIHRyYW5zY29kZSB0aGUgTkRJIHNvdXJjZSBpbnRvIGEgdHJhbnNwb3J0IHN0cmVhbScsXG4gICAgICAgIHRoaXMsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBWYWxpZGF0ZSB0aGUgRUZBIFZQQy1pbnRlcmZhY2UgY291bnQgKGF0IG1vc3Qgb25lKSwgd2hlbiB0aGUgbGlzdCBpcyBjb25jcmV0ZS4gKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZVZwY0VmYUNvdW50KHByb3BzOiBGbG93UHJvcHMpOiB2b2lkIHtcbiAgICAvLyBTa2lwIEVGQS1jb3VudCB2YWxpZGF0aW9uIHdoZW4gdGhlIHVzZXIgcGFzc2VkIGEgdG9rZW5pemVkIHZwY0ludGVyZmFjZXMgbGlzdDtcbiAgICAvLyB3ZSBjYW4ndCBpbnNwZWN0IGluZGl2aWR1YWwgZW50cmllcyBpbiB0aGF0IGNhc2UuXG4gICAgY29uc3QgZWZhQ291bnQgPSBwcm9wcy52cGNJbnRlcmZhY2VzICE9PSB1bmRlZmluZWQgJiYgIVRva2VuLmlzVW5yZXNvbHZlZChwcm9wcy52cGNJbnRlcmZhY2VzKVxuICAgICAgPyBwcm9wcy52cGNJbnRlcmZhY2VzLmZpbHRlcih2cGMgPT4gdnBjLm5ldHdvcmtJbnRlcmZhY2VUeXBlPy52YWx1ZSA9PT0gTmV0d29ya0ludGVyZmFjZS5FRkEudmFsdWUpLmxlbmd0aFxuICAgICAgOiAwO1xuXG4gICAgaWYgKGVmYUNvdW50ID4gMSkge1xuICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihcbiAgICAgICAgbGl0YEZsb3dNYXhFZmFJbnRlcmZhY2VzYCxcbiAgICAgICAgYEEgZmxvdyBjYW4gaGF2ZSBhIG1heGltdW0gb2YgMSBFRkEgVlBDIGludGVyZmFjZSwgZ290ICR7ZWZhQ291bnR9YCxcbiAgICAgICAgdGhpcyxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIHRoZSBVUkwgZm9yIGEgbGlzdGVuZXItc3R5bGUgc291cmNlIHByb3RvY29sLiBUaGUgY2FsbGVyIG11c3QgaGF2ZSBhbHJlYWR5XG4gICAqIGNoZWNrZWQgYF9oYXNMaXN0ZW5lclNvdXJjZWA7IHRoaXMgbWV0aG9kIGFzc3VtZXMgdGhlIHByb3RvY29sIGlzIGluXG4gICAqIGBMSVNURU5FUl9QUk9UT0NPTF9TQ0hFTUVTYCBhbmQgdGhyb3dzIGFuIHVuc2NvcGVkIGVycm9yIG90aGVyd2lzZS5cbiAgICovXG4gIHByaXZhdGUgY29tcHV0ZUluZ2VzdFVybChwcm90b2NvbDogc3RyaW5nIHwgdW5kZWZpbmVkLCBpcDogc3RyaW5nLCBwb3J0OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IHNjaGVtZSA9IHByb3RvY29sID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBGbG93LkxJU1RFTkVSX1BST1RPQ09MX1NDSEVNRVMuZ2V0KHByb3RvY29sKTtcbiAgICBpZiAoc2NoZW1lID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBVbnNjb3BlZFZhbGlkYXRpb25FcnJvcihcbiAgICAgICAgbGl0YFNvdXJjZUluZ2VzdFVybENvbXB1dGVOb3RMaXN0ZW5lcmAsXG4gICAgICAgIGBpbnRlcm5hbDogY29tcHV0ZUluZ2VzdFVybCBjYWxsZWQgZm9yIG5vbi1saXN0ZW5lciBwcm90b2NvbCAnJHtwcm90b2NvbH0nYCxcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBGbi5qb2luKCcnLCBbYCR7c2NoZW1lfTovL2AsIGlwLCAnOicsIHBvcnRdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgYSBWUEMgaW50ZXJmYWNlIHRvIHRoaXMgZmxvdy5cbiAgICovXG4gIEBNZXRob2RNZXRhZGF0YSgpXG4gIHB1YmxpYyBhZGRWcGNJbnRlcmZhY2UodnBjOiBWcGNJbnRlcmZhY2VDb25maWcpIHtcbiAgICB0aGlzLnZwY0ludGVyZmFjZXMucHVzaCh7XG4gICAgICBuYW1lOiB2cGMubmFtZSxcbiAgICAgIG5ldHdvcmtJbnRlcmZhY2VJZHM6IHZwYy5uZXR3b3JrSW50ZXJmYWNlSWRzLFxuICAgICAgbmV0d29ya0ludGVyZmFjZVR5cGU6IHZwYy5uZXR3b3JrSW50ZXJmYWNlVHlwZT8udmFsdWUsXG4gICAgICBzZWN1cml0eUdyb3VwSWRzOiB2cGMuc2VjdXJpdHlHcm91cHMubWFwKHNnID0+IHNnLnNlY3VyaXR5R3JvdXBJZCksXG4gICAgICBzdWJuZXRJZDogdnBjLnN1Ym5ldC5zdWJuZXRJZCxcbiAgICAgIHJvbGVBcm46IHZwYy5yb2xlLnJvbGVBcm4sXG4gICAgfSk7XG4gICAgcmV0dXJuIHZwYztcbiAgfVxufVxuIl19