@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.
@@ -0,0 +1,789 @@
1
+ "use strict";
2
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
3
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
4
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
5
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
6
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
7
+ var _, done = false;
8
+ for (var i = decorators.length - 1; i >= 0; i--) {
9
+ var context = {};
10
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
11
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
12
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
13
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
14
+ if (kind === "accessor") {
15
+ if (result === void 0) continue;
16
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
17
+ if (_ = accept(result.get)) descriptor.get = _;
18
+ if (_ = accept(result.set)) descriptor.set = _;
19
+ if (_ = accept(result.init)) initializers.unshift(_);
20
+ }
21
+ else if (_ = accept(result)) {
22
+ if (kind === "field") initializers.unshift(_);
23
+ else descriptor[key] = _;
24
+ }
25
+ }
26
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
27
+ done = true;
28
+ };
29
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
30
+ var useValue = arguments.length > 2;
31
+ for (var i = 0; i < initializers.length; i++) {
32
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
33
+ }
34
+ return useValue ? value : void 0;
35
+ };
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.RouterOutput = exports.RouterOutputConfiguration = exports.RouterOutputProtocol = exports.RouterOutputTier = exports.RouterOutputProtocolOptions = 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 shared_1 = require("./shared");
47
+ /**
48
+ * Protocol options available for Router Output configurations
49
+ */
50
+ class RouterOutputProtocolOptions {
51
+ value;
52
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-mediaconnect-alpha.RouterOutputProtocolOptions", version: "2.263.0-alpha.0" };
53
+ /** Real-time Transport Protocol */
54
+ static RTP = new RouterOutputProtocolOptions('RTP');
55
+ /** Reliable Internet Stream Transport */
56
+ static RIST = new RouterOutputProtocolOptions('RIST');
57
+ /** Secure Reliable Transport - Caller mode */
58
+ static SRT_CALLER = new RouterOutputProtocolOptions('SRT_CALLER');
59
+ /** Secure Reliable Transport - Listener mode */
60
+ static SRT_LISTENER = new RouterOutputProtocolOptions('SRT_LISTENER');
61
+ /**
62
+ * Use a custom protocol value
63
+ * @param value The protocol string value
64
+ */
65
+ static of(value) {
66
+ return new RouterOutputProtocolOptions(value);
67
+ }
68
+ /** @param value The protocol string value */
69
+ constructor(value) {
70
+ this.value = value;
71
+ }
72
+ /** Returns the string value */
73
+ toString() {
74
+ return this.value;
75
+ }
76
+ }
77
+ exports.RouterOutputProtocolOptions = RouterOutputProtocolOptions;
78
+ /**
79
+ * Routing tier that determines the maximum bitrate (in Mbps) for a Router Output.
80
+ */
81
+ class RouterOutputTier {
82
+ value;
83
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-mediaconnect-alpha.RouterOutputTier", version: "2.263.0-alpha.0" };
84
+ /** Up to 100 Mbps */
85
+ static OUTPUT_100 = new RouterOutputTier('OUTPUT_100');
86
+ /** Up to 50 Mbps */
87
+ static OUTPUT_50 = new RouterOutputTier('OUTPUT_50');
88
+ /** Up to 20 Mbps */
89
+ static OUTPUT_20 = new RouterOutputTier('OUTPUT_20');
90
+ /**
91
+ * Use a custom tier value
92
+ * @param value The tier string value
93
+ */
94
+ static of(value) {
95
+ return new RouterOutputTier(value);
96
+ }
97
+ /** @param value The tier string value */
98
+ constructor(value) {
99
+ this.value = value;
100
+ }
101
+ /** Returns the string value */
102
+ toString() {
103
+ return this.value;
104
+ }
105
+ }
106
+ exports.RouterOutputTier = RouterOutputTier;
107
+ /**
108
+ * Factory class for creating Router Output protocol configurations.
109
+ *
110
+ * Supported protocols: RTP, RIST, SRT (Listener and Caller).
111
+ */
112
+ class RouterOutputProtocol {
113
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-mediaconnect-alpha.RouterOutputProtocol", version: "2.263.0-alpha.0" };
114
+ /**
115
+ * Create an RTP protocol configuration
116
+ *
117
+ * @example
118
+ *
119
+ * RouterOutputProtocol.rtp({
120
+ * destinationAddress: '10.0.0.1',
121
+ * port: 5000,
122
+ * });
123
+ *
124
+ * @param props RTP protocol properties
125
+ * @returns RouterOutputProtocol instance configured for RTP
126
+ */
127
+ static rtp(props) {
128
+ try {
129
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_RtpOutputProtocolProps(props);
130
+ }
131
+ catch (error) {
132
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
133
+ Error.captureStackTrace(error, this.rtp);
134
+ }
135
+ throw error;
136
+ }
137
+ RouterOutputProtocol.validatePort(props.port);
138
+ return new RouterOutputProtocol(RouterOutputProtocolOptions.RTP, {
139
+ rtp: {
140
+ destinationAddress: props.destinationAddress,
141
+ destinationPort: props.port,
142
+ forwardErrorCorrection: props.forwardErrorCorrection,
143
+ },
144
+ });
145
+ }
146
+ /**
147
+ * Create a RIST protocol configuration
148
+ *
149
+ * @example
150
+ *
151
+ * RouterOutputProtocol.rist({
152
+ * destinationAddress: '10.0.0.1',
153
+ * port: 5000,
154
+ * });
155
+ *
156
+ * @param props RIST protocol properties
157
+ * @returns RouterOutputProtocol instance configured for RIST
158
+ */
159
+ static rist(props) {
160
+ try {
161
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_RistOutputProtocolProps(props);
162
+ }
163
+ catch (error) {
164
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
165
+ Error.captureStackTrace(error, this.rist);
166
+ }
167
+ throw error;
168
+ }
169
+ RouterOutputProtocol.validatePort(props.port);
170
+ return new RouterOutputProtocol(RouterOutputProtocolOptions.RIST, {
171
+ rist: {
172
+ destinationAddress: props.destinationAddress,
173
+ destinationPort: props.port,
174
+ },
175
+ });
176
+ }
177
+ /**
178
+ * Create an SRT Listener protocol configuration
179
+ *
180
+ * @example
181
+ *
182
+ * RouterOutputProtocol.srtListener({
183
+ * port: 5000,
184
+ * minimumLatency: Duration.millis(125),
185
+ * });
186
+ *
187
+ * @param props SRT Listener protocol properties
188
+ * @returns RouterOutputProtocol instance configured for SRT Listener
189
+ */
190
+ static srtListener(props) {
191
+ try {
192
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_SrtListenerOutputProtocolProps(props);
193
+ }
194
+ catch (error) {
195
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
196
+ Error.captureStackTrace(error, this.srtListener);
197
+ }
198
+ throw error;
199
+ }
200
+ RouterOutputProtocol.validatePort(props.port);
201
+ return new RouterOutputProtocol(RouterOutputProtocolOptions.SRT_LISTENER, {
202
+ srtListener: {
203
+ port: props.port,
204
+ minimumLatencyMilliseconds: props.minimumLatency.toMilliseconds(),
205
+ },
206
+ }, props.encryptionConfiguration);
207
+ }
208
+ /**
209
+ * Create an SRT Caller protocol configuration
210
+ *
211
+ * @example
212
+ *
213
+ * RouterOutputProtocol.srtCaller({
214
+ * destinationAddress: '10.0.0.1',
215
+ * destinationPort: 5000,
216
+ * minimumLatency: Duration.millis(125),
217
+ * });
218
+ *
219
+ * @param props SRT Caller protocol properties
220
+ * @returns RouterOutputProtocol instance configured for SRT Caller
221
+ */
222
+ static srtCaller(props) {
223
+ try {
224
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_SrtCallerOutputProtocolProps(props);
225
+ }
226
+ catch (error) {
227
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
228
+ Error.captureStackTrace(error, this.srtCaller);
229
+ }
230
+ throw error;
231
+ }
232
+ RouterOutputProtocol.validateSrtCallerPort(props.destinationPort);
233
+ return new RouterOutputProtocol(RouterOutputProtocolOptions.SRT_CALLER, {
234
+ srtCaller: {
235
+ destinationAddress: props.destinationAddress,
236
+ destinationPort: props.destinationPort,
237
+ minimumLatencyMilliseconds: props.minimumLatency.toMilliseconds(),
238
+ streamId: props.streamId,
239
+ },
240
+ }, props.encryptionConfiguration);
241
+ }
242
+ /**
243
+ * Validate that port is within the valid range (3000-30000)
244
+ */
245
+ static validatePort(port) {
246
+ if (!aws_cdk_lib_1.Token.isUnresolved(port) && (port < 3000 || port > 30000)) {
247
+ throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `RouterOutputPortRange`, `Port must be between 3000 and 30000, got ${port}`);
248
+ }
249
+ }
250
+ /**
251
+ * Validate that SRT Caller port is within the valid range (0-65535)
252
+ */
253
+ static validateSrtCallerPort(port) {
254
+ if (!aws_cdk_lib_1.Token.isUnresolved(port) && (port < 0 || port > 65535)) {
255
+ throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `SrtCallerPortRange`, `SRT Caller port must be between 0 and 65535, got ${port}`);
256
+ }
257
+ }
258
+ _protocolName;
259
+ _config;
260
+ _encryption;
261
+ constructor(protocolName, config, encryption) {
262
+ this._protocolName = protocolName;
263
+ this._config = config;
264
+ this._encryption = encryption;
265
+ }
266
+ /**
267
+ * Resolve this protocol to its CFN-ready form. Returns the protocol identifier
268
+ * and the CFN configuration shape with SRT encryption auto-role materialized if needed.
269
+ *
270
+ * @param scope Construct that scopes the auto-created encryption role
271
+ * @param routerOutputArn Optional ARN of the consuming router output — when provided,
272
+ * scopes the auto-created encryption role's trust policy.
273
+ *
274
+ * @internal
275
+ */
276
+ _bind(scope, routerOutputArn) {
277
+ if (!this._encryption) {
278
+ return { name: this._protocolName, config: this._config };
279
+ }
280
+ const { config: encryptionConfiguration, grant } = (0, shared_1.resolveRouterSrtEncryption)(scope, 'EncryptionRole', this._encryption, routerOutputArn);
281
+ if (this._config.srtListener) {
282
+ return {
283
+ name: this._protocolName,
284
+ config: { srtListener: { ...this._config.srtListener, encryptionConfiguration } },
285
+ grant,
286
+ };
287
+ }
288
+ if (this._config.srtCaller) {
289
+ return {
290
+ name: this._protocolName,
291
+ config: { srtCaller: { ...this._config.srtCaller, encryptionConfiguration } },
292
+ grant,
293
+ };
294
+ }
295
+ return { name: this._protocolName, config: this._config };
296
+ }
297
+ }
298
+ exports.RouterOutputProtocol = RouterOutputProtocol;
299
+ /**
300
+ * Factory class for creating Router Output configurations
301
+ */
302
+ class RouterOutputConfiguration {
303
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-mediaconnect-alpha.RouterOutputConfiguration", version: "2.263.0-alpha.0" };
304
+ /**
305
+ * Create a standard Router Output configuration with a single protocol
306
+ *
307
+ * @example
308
+ *
309
+ * declare const networkInterface: RouterNetworkInterface;
310
+ *
311
+ * RouterOutputConfiguration.standard({
312
+ * networkInterface,
313
+ * protocol: RouterOutputProtocol.rtp({
314
+ * destinationAddress: '10.0.0.1',
315
+ * port: 5000,
316
+ * }),
317
+ * });
318
+ *
319
+ * @param props Standard configuration properties
320
+ * @returns RouterOutputConfiguration instance for standard setup
321
+ */
322
+ static standard(props) {
323
+ try {
324
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_StandardOutputConfigurationProps(props);
325
+ }
326
+ catch (error) {
327
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
328
+ Error.captureStackTrace(error, this.standard);
329
+ }
330
+ throw error;
331
+ }
332
+ return new StandardRouterOutputConfig(props);
333
+ }
334
+ /**
335
+ * Create a MediaLive Router Output configuration with a specific input connection.
336
+ *
337
+ * Use this when the MediaLive input already exists and you want to connect immediately.
338
+ *
339
+ * @example
340
+ *
341
+ * RouterOutputConfiguration.mediaLiveInput({
342
+ * mediaLiveInputArn: 'arn:aws:medialive:us-east-1:123456789012:input:1234567',
343
+ * mediaLivePipelineId: MediaLivePipeline.PIPELINE_0,
344
+ * });
345
+ *
346
+ * @param props MediaLive input connection properties
347
+ * @returns RouterOutputConfiguration instance for MediaLive setup with input connection
348
+ */
349
+ static mediaLiveInput(props) {
350
+ try {
351
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_MediaLiveInputConnectionProps(props);
352
+ }
353
+ catch (error) {
354
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
355
+ Error.captureStackTrace(error, this.mediaLiveInput);
356
+ }
357
+ throw error;
358
+ }
359
+ return new MediaLiveInputRouterOutputConfig({
360
+ mediaLiveInputArn: props.mediaLiveInputArn,
361
+ mediaLivePipelineId: props.mediaLivePipelineId,
362
+ destinationTransitEncryption: props.destinationTransitEncryption,
363
+ });
364
+ }
365
+ /**
366
+ * Create a MediaLive Router Output configuration without a specific input connection.
367
+ *
368
+ * Use this when you want to set up the router output before the MediaLive input exists.
369
+ *
370
+ * @example
371
+ *
372
+ * RouterOutputConfiguration.mediaLiveInputWithoutConnection({
373
+ * availabilityZone: 'us-east-1a',
374
+ * });
375
+ *
376
+ * @param props MediaLive no input connection properties
377
+ * @returns RouterOutputConfiguration instance for MediaLive setup without input connection
378
+ */
379
+ static mediaLiveInputWithoutConnection(props) {
380
+ try {
381
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_MediaLiveNoInputConnectionProps(props);
382
+ }
383
+ catch (error) {
384
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
385
+ Error.captureStackTrace(error, this.mediaLiveInputWithoutConnection);
386
+ }
387
+ throw error;
388
+ }
389
+ return new MediaLiveInputRouterOutputConfig({ destinationTransitEncryption: props.destinationTransitEncryption }, props.availabilityZone);
390
+ }
391
+ /**
392
+ * Create a MediaConnect Flow Router Output configuration with a specific flow connection.
393
+ *
394
+ * Use this when the target flow already exists and you want to connect immediately.
395
+ *
396
+ * @example
397
+ *
398
+ * declare const flow: Flow;
399
+ *
400
+ * RouterOutputConfiguration.mediaConnectFlow({
401
+ * flow,
402
+ * });
403
+ *
404
+ * @param props MediaConnect Flow connection properties
405
+ * @returns RouterOutputConfiguration instance for MediaConnect Flow setup with flow connection
406
+ */
407
+ static mediaConnectFlow(props) {
408
+ try {
409
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_MediaConnectFlowConnectionProps(props);
410
+ }
411
+ catch (error) {
412
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
413
+ Error.captureStackTrace(error, this.mediaConnectFlow);
414
+ }
415
+ throw error;
416
+ }
417
+ return new MediaConnectFlowRouterOutputConfig({
418
+ flow: props.flow,
419
+ destinationTransitEncryption: props.destinationTransitEncryption,
420
+ });
421
+ }
422
+ /**
423
+ * Create a MediaConnect Flow Router Output configuration without a specific flow connection.
424
+ *
425
+ * Use this when you want to set up the router output before the target flow exists.
426
+ *
427
+ * @example
428
+ *
429
+ * RouterOutputConfiguration.mediaConnectFlowWithoutConnection({
430
+ * availabilityZone: 'us-east-1a',
431
+ * });
432
+ *
433
+ * @param props MediaConnect Flow no connection properties
434
+ * @returns RouterOutputConfiguration instance for MediaConnect Flow setup without flow connection
435
+ */
436
+ static mediaConnectFlowWithoutConnection(props) {
437
+ try {
438
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_MediaConnectFlowNoConnectionProps(props);
439
+ }
440
+ catch (error) {
441
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
442
+ Error.captureStackTrace(error, this.mediaConnectFlowWithoutConnection);
443
+ }
444
+ throw error;
445
+ }
446
+ return new MediaConnectFlowRouterOutputConfig({ destinationTransitEncryption: props.destinationTransitEncryption }, props.availabilityZone);
447
+ }
448
+ }
449
+ exports.RouterOutputConfiguration = RouterOutputConfiguration;
450
+ /**
451
+ * Concrete variant: standard (single-protocol) router output configuration.
452
+ * @internal
453
+ */
454
+ class StandardRouterOutputConfig extends RouterOutputConfiguration {
455
+ props;
456
+ constructor(props) {
457
+ super();
458
+ this.props = props;
459
+ }
460
+ _bind(scope, routerOutputArn) {
461
+ const protocol = this.props.protocol._bind(scope, routerOutputArn);
462
+ return {
463
+ config: {
464
+ standard: {
465
+ networkInterfaceArn: this.props.networkInterface.routerNetworkInterfaceArn,
466
+ protocol: protocol.name.value,
467
+ protocolConfiguration: protocol.config,
468
+ },
469
+ },
470
+ grant: protocol.grant,
471
+ };
472
+ }
473
+ }
474
+ /**
475
+ * Concrete variant: MediaLive Input router output configuration (with or without connection).
476
+ * @internal
477
+ */
478
+ class MediaLiveInputRouterOutputConfig extends RouterOutputConfiguration {
479
+ options;
480
+ availabilityZone;
481
+ constructor(options, availabilityZone) {
482
+ super();
483
+ this.options = options;
484
+ this.availabilityZone = availabilityZone;
485
+ }
486
+ _bind(scope, routerOutputArn) {
487
+ const transit = (0, shared_1.resolveTransitEncryption)(scope, 'DestinationTransitEncryptionRole', this.options.destinationTransitEncryption, routerOutputArn);
488
+ return {
489
+ config: {
490
+ mediaLiveInput: {
491
+ mediaLiveInputArn: this.options.mediaLiveInputArn,
492
+ mediaLivePipelineId: this.options.mediaLivePipelineId,
493
+ destinationTransitEncryption: transit.config,
494
+ },
495
+ },
496
+ availabilityZone: this.availabilityZone,
497
+ grant: transit.grant,
498
+ };
499
+ }
500
+ }
501
+ /**
502
+ * Concrete variant: MediaConnect Flow router output configuration (with or without connection).
503
+ * @internal
504
+ */
505
+ class MediaConnectFlowRouterOutputConfig extends RouterOutputConfiguration {
506
+ options;
507
+ availabilityZone;
508
+ constructor(options, availabilityZone) {
509
+ super();
510
+ this.options = options;
511
+ this.availabilityZone = availabilityZone;
512
+ }
513
+ _bind(scope, routerOutputArn) {
514
+ const transit = (0, shared_1.resolveTransitEncryption)(scope, 'DestinationTransitEncryptionRole', this.options.destinationTransitEncryption, routerOutputArn);
515
+ return {
516
+ config: {
517
+ mediaConnectFlow: {
518
+ flowArn: this.options.flow?.flowArn,
519
+ flowSourceArn: this.options.flow?.sourceArn,
520
+ destinationTransitEncryption: transit.config,
521
+ },
522
+ },
523
+ availabilityZone: this.availabilityZone,
524
+ grant: transit.grant,
525
+ };
526
+ }
527
+ }
528
+ /**
529
+ * A MediaConnect Router Output that sends media streams to destinations.
530
+ *
531
+ * Router Outputs support multiple configuration types:
532
+ * - Standard: Single protocol output
533
+ * - MediaLive Input: Output to AWS Elemental MediaLive
534
+ * - MediaConnect Flow: Output to another MediaConnect Flow
535
+ */
536
+ class RouterOutputBase extends aws_cdk_lib_1.Resource {
537
+ /**
538
+ * A reference to this Router Output resource.
539
+ * Required by the auto-generated IRouterOutputRef interface.
540
+ */
541
+ get routerOutputRef() {
542
+ return { routerOutputArn: this.routerOutputArn };
543
+ }
544
+ /**
545
+ * Create a CloudWatch metric for this router output.
546
+ */
547
+ metric(metricName, props) {
548
+ return new aws_cloudwatch_1.Metric({
549
+ metricName,
550
+ namespace: 'AWS/MediaConnect',
551
+ ...props,
552
+ dimensionsMap: {
553
+ RouterOutputARN: this.routerOutputArn,
554
+ ...props?.dimensionsMap,
555
+ },
556
+ }).attachTo(this);
557
+ }
558
+ /**
559
+ * Metric for the bitrate of the router output's payload.
560
+ */
561
+ metricBitrate(props) {
562
+ return this.metric('RouterOutputBitRate', {
563
+ statistic: 'avg',
564
+ period: aws_cdk_lib_1.Duration.seconds(60),
565
+ unit: aws_cloudwatch_1.Unit.BITS_PER_SECOND,
566
+ ...props,
567
+ });
568
+ }
569
+ /**
570
+ * Metric for the total number of packets sent by the router output.
571
+ */
572
+ metricTotalPackets(props) {
573
+ return this.metric('RouterOutputTotalPackets', {
574
+ statistic: 'sum',
575
+ period: aws_cdk_lib_1.Duration.seconds(60),
576
+ unit: aws_cloudwatch_1.Unit.COUNT,
577
+ ...props,
578
+ });
579
+ }
580
+ /**
581
+ * Metric for the router output connection state (1 connected, 0 disconnected). Applies to SRT outputs only.
582
+ */
583
+ metricConnected(props) {
584
+ return this.metric('RouterOutputConnected', {
585
+ statistic: 'min',
586
+ period: aws_cdk_lib_1.Duration.seconds(60),
587
+ unit: aws_cloudwatch_1.Unit.NONE,
588
+ ...props,
589
+ });
590
+ }
591
+ /**
592
+ * Metric for the number of retransmitted packets requested through ARQ. Applies to RIST and SRT outputs.
593
+ */
594
+ metricArqRequests(props) {
595
+ return this.metric('RouterOutputARQRequests', {
596
+ statistic: 'sum',
597
+ period: aws_cdk_lib_1.Duration.seconds(60),
598
+ unit: aws_cloudwatch_1.Unit.COUNT,
599
+ ...props,
600
+ });
601
+ }
602
+ }
603
+ /**
604
+ * Defines an AWS Elemental MediaConnect Router Output.
605
+ */
606
+ let RouterOutput = (() => {
607
+ let _classDecorators = [prop_injectable_1.propertyInjectable];
608
+ let _classDescriptor;
609
+ let _classExtraInitializers = [];
610
+ let _classThis;
611
+ let _classSuper = RouterOutputBase;
612
+ var RouterOutput = class extends _classSuper {
613
+ static { _classThis = this; }
614
+ static {
615
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
616
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
617
+ RouterOutput = _classThis = _classDescriptor.value;
618
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
619
+ }
620
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@aws-cdk/aws-mediaconnect-alpha.RouterOutput", version: "2.263.0-alpha.0" };
621
+ /** Uniquely identifies this class. */
622
+ static PROPERTY_INJECTION_ID = '@aws-cdk.aws-mediaconnect-alpha.RouterOutput';
623
+ /**
624
+ * Import an existing Router Output from its ARN.
625
+ *
626
+ * The ARN only contains the service-generated ID (not the router output name). Accessing
627
+ * `routerOutputName` on an ARN import throws — use `fromRouterOutputAttributes()` to provide
628
+ * the name explicitly.
629
+ *
630
+ * @param scope The parent construct
631
+ * @param id The construct id
632
+ * @param routerOutputArn The ARN of the Router Output
633
+ * @returns A Router Output construct
634
+ */
635
+ static fromRouterOutputArn(scope, id, routerOutputArn) {
636
+ return RouterOutput.fromRouterOutputAttributes(scope, id, { routerOutputArn });
637
+ }
638
+ /**
639
+ * Import an existing Router Output from attributes.
640
+ *
641
+ * Use this when you need to reference a router output by name.
642
+ *
643
+ * @param scope The parent construct
644
+ * @param id The construct id
645
+ * @param attrs The Router Output attributes
646
+ * @returns A Router Output construct
647
+ */
648
+ static fromRouterOutputAttributes(scope, id, attrs) {
649
+ try {
650
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_RouterOutputAttributes(attrs);
651
+ }
652
+ catch (error) {
653
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
654
+ Error.captureStackTrace(error, this.fromRouterOutputAttributes);
655
+ }
656
+ throw error;
657
+ }
658
+ // Derive the ID from the ARN using CFN intrinsics so this works with token ARNs too.
659
+ // The ARN format is arn:aws:mediaconnect:<region>:<account>:routerOutput:<id>, so the
660
+ // resource name is the ID.
661
+ const routerOutputId = attrs.routerOutputId ?? extractRouterOutputId(attrs.routerOutputArn);
662
+ class Import extends RouterOutputBase {
663
+ routerOutputArn = attrs.routerOutputArn;
664
+ routerOutputId = routerOutputId;
665
+ createdAt = undefined;
666
+ updatedAt = undefined;
667
+ get routerOutputName() {
668
+ if (attrs.routerOutputName)
669
+ return attrs.routerOutputName;
670
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `RouterOutputNameNotProvided`, `'routerOutputName' was not provided when importing RouterOutput ${this.node.path}; provide it in fromRouterOutputAttributes()`, this);
671
+ }
672
+ get ipAddress() {
673
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `RouterOutputIpAddressNotProvided`, `'ipAddress' is not available on imported RouterOutput ${this.node.path}`, this);
674
+ }
675
+ }
676
+ return new Import(scope, id);
677
+ }
678
+ /**
679
+ * Returns the maximum bitrate in Mbps for a known tier, or undefined for custom tiers.
680
+ */
681
+ static tierLimitMbps(tier) {
682
+ if (tier.value === RouterOutputTier.OUTPUT_20.value)
683
+ return 20;
684
+ if (tier.value === RouterOutputTier.OUTPUT_50.value)
685
+ return 50;
686
+ if (tier.value === RouterOutputTier.OUTPUT_100.value)
687
+ return 100;
688
+ return undefined;
689
+ }
690
+ routerOutputArn;
691
+ routerOutputName;
692
+ routerOutputId;
693
+ ipAddress;
694
+ createdAt;
695
+ updatedAt;
696
+ constructor(scope, id, props) {
697
+ super(scope, id, {
698
+ physicalName: props.routerOutputName ?? aws_cdk_lib_1.Lazy.string({ produce: () => aws_cdk_lib_1.Names.uniqueResourceName(this, { maxLength: 128 }) }),
699
+ });
700
+ try {
701
+ jsiiDeprecationWarnings._aws_cdk_aws_mediaconnect_alpha_RouterOutputProps(props);
702
+ }
703
+ catch (error) {
704
+ if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
705
+ Error.captureStackTrace(error, RouterOutput);
706
+ }
707
+ throw error;
708
+ }
709
+ // Validate router output name if provided
710
+ if (props.routerOutputName != null && props.routerOutputName !== '' && !aws_cdk_lib_1.Token.isUnresolved(props.routerOutputName)) {
711
+ if (props.routerOutputName.length > 128) {
712
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `RouterOutputNameLength`, `Router output name must be between 1 and 128 characters, got ${props.routerOutputName.length}`, this);
713
+ }
714
+ if (!/^[a-zA-Z0-9-]+$/.test(props.routerOutputName)) {
715
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `RouterOutputNameFormat`, `Router output name must contain only alphanumeric characters and hyphens, got '${props.routerOutputName}'`, this);
716
+ }
717
+ }
718
+ // Validate maximum bitrate
719
+ if (!props.maximumBitrate.isUnresolved() && props.maximumBitrate.toBps() < 1000000) {
720
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `RouterOutputMinBitrate`, `Maximum bitrate must be at least 1,000,000 bits/s (1 Mbps), got ${props.maximumBitrate.toBps()}`, this);
721
+ }
722
+ // Validate bitrate does not exceed tier limit
723
+ const resolvedTier = props.tier ?? RouterOutputTier.OUTPUT_20;
724
+ const tierMbps = RouterOutput.tierLimitMbps(resolvedTier);
725
+ if ((0, shared_1.exceedsRouterTierBitrate)(tierMbps, props.maximumBitrate)) {
726
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `RouterOutputBitrateExceedsTier`, `Maximum bitrate ${props.maximumBitrate.toBps() / 1_000_000} Mbps exceeds the ${resolvedTier.value} tier limit of ${tierMbps} Mbps`, this);
727
+ }
728
+ // Validate maintenance time format
729
+ if (props.maintenanceConfiguration) {
730
+ (0, shared_1.validateMaintenanceTime)(props.maintenanceConfiguration.time);
731
+ }
732
+ // Enhanced CDK Analytics Telemetry
733
+ (0, metadata_resource_1.addConstructMetadata)(this, props);
734
+ const stack = aws_cdk_lib_1.Stack.of(this);
735
+ const targetRegion = props.regionName ?? stack.region;
736
+ // Wildcard the id — pinning the live ARN (attrArn) would create a role → router-output → role cycle.
737
+ const routerOutputArn = stack.formatArn({
738
+ service: 'mediaconnect',
739
+ region: targetRegion,
740
+ resource: 'routerOutput',
741
+ resourceName: '*',
742
+ arnFormat: aws_cdk_lib_1.ArnFormat.COLON_RESOURCE_NAME,
743
+ });
744
+ const configBind = props.configuration._bind(this, routerOutputArn);
745
+ // Check to see if region specified is also compatible with AZ configured for some of the Router Outputs configurations
746
+ if (configBind.availabilityZone && !configBind.availabilityZone.startsWith(targetRegion)) {
747
+ throw new aws_cdk_lib_1.ValidationError((0, helpers_internal_1.lit) `RouterOutputAzRegionMismatch`, `Availability zone '${configBind.availabilityZone}' must be within region '${targetRegion}'`, this);
748
+ }
749
+ const routerOutput = new aws_mediaconnect_1.CfnRouterOutput(this, 'Resource', {
750
+ name: this.physicalName,
751
+ maximumBitrate: props.maximumBitrate.toBps(),
752
+ routingScope: props.routingScope.value,
753
+ tier: (props.tier ?? RouterOutputTier.OUTPUT_20).value,
754
+ availabilityZone: configBind.availabilityZone, // Only specified for MediaConnect Flow and MediaLive inputs (with no connection).
755
+ maintenanceConfiguration: props.maintenanceConfiguration ? {
756
+ preferredDayTime: props.maintenanceConfiguration,
757
+ } : {
758
+ default: {},
759
+ },
760
+ configuration: configBind.config,
761
+ regionName: targetRegion,
762
+ tags: props.tags ? (0, shared_1.renderTags)(props.tags) : undefined,
763
+ });
764
+ this.routerOutputArn = routerOutput.attrArn;
765
+ this.routerOutputName = this.physicalName;
766
+ this.routerOutputId = routerOutput.attrId;
767
+ this.ipAddress = routerOutput.attrIpAddress;
768
+ this.createdAt = routerOutput.attrCreatedAt;
769
+ this.updatedAt = routerOutput.attrUpdatedAt;
770
+ // Without this the router input can be created before the
771
+ // policy is attached ("access denied" at create time). Ordering the grant before the
772
+ // router input pulls the policy in as a dependency.
773
+ configBind.grant?.applyBefore(routerOutput);
774
+ }
775
+ static {
776
+ __runInitializers(_classThis, _classExtraInitializers);
777
+ }
778
+ };
779
+ return RouterOutput = _classThis;
780
+ })();
781
+ exports.RouterOutput = RouterOutput;
782
+ function extractRouterOutputId(routerOutputArn) {
783
+ const parsed = aws_cdk_lib_1.Arn.split(routerOutputArn, aws_cdk_lib_1.ArnFormat.COLON_RESOURCE_NAME).resourceName;
784
+ if (parsed === undefined) {
785
+ throw new aws_cdk_lib_1.UnscopedValidationError((0, helpers_internal_1.lit) `InvalidRouterOutputArn`, `Could not parse Router Output ARN: ${routerOutputArn}. Expected format: arn:<partition>:mediaconnect:<region>:<account>:routerOutput:<id>`);
786
+ }
787
+ return parsed;
788
+ }
789
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGVyLW91dHB1dC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInJvdXRlci1vdXRwdXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQ0EsNkNBQXNJO0FBRXRJLCtEQUEwRDtBQUUxRCxtRUFBK0Q7QUFFL0QsNEVBQTREO0FBQzVELDhFQUE4RTtBQUM5RSwwRUFBMEU7QUFNMUUscUNBQStJO0FBRS9JOztHQUVHO0FBQ0gsTUFBYSwyQkFBMkI7SUFtQkY7O0lBbEJwQyxtQ0FBbUM7SUFDNUIsTUFBTSxDQUFVLEdBQUcsR0FBRyxJQUFJLDJCQUEyQixDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3BFLHlDQUF5QztJQUNsQyxNQUFNLENBQVUsSUFBSSxHQUFHLElBQUksMkJBQTJCLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDdEUsOENBQThDO0lBQ3ZDLE1BQU0sQ0FBVSxVQUFVLEdBQUcsSUFBSSwyQkFBMkIsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUNsRixnREFBZ0Q7SUFDekMsTUFBTSxDQUFVLFlBQVksR0FBRyxJQUFJLDJCQUEyQixDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBRXRGOzs7T0FHRztJQUNJLE1BQU0sQ0FBQyxFQUFFLENBQUMsS0FBYTtRQUM1QixPQUFPLElBQUksMkJBQTJCLENBQUMsS0FBSyxDQUFDLENBQUM7S0FDL0M7SUFFRCw2Q0FBNkM7SUFDN0MsWUFBb0MsS0FBYTtRQUFiLFVBQUssR0FBTCxLQUFLLENBQVE7S0FBSTtJQUVyRCwrQkFBK0I7SUFDeEIsUUFBUTtRQUNiLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztLQUNuQjs7QUF4Qkgsa0VBeUJDO0FBRUQ7O0dBRUc7QUFDSCxNQUFhLGdCQUFnQjtJQWlCUzs7SUFoQnBDLHFCQUFxQjtJQUNkLE1BQU0sQ0FBVSxVQUFVLEdBQUcsSUFBSSxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUN2RSxvQkFB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QyxlQUFlLEVBQUUsdUJBQVMsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLFlBQVksQ0FBQztJQUN0RixJQUFJLE1BQU0sS0FBSyxTQUFTLEVBQUUsQ0FBQztRQUN6QixNQUFNLElBQUkscUNBQXVCLENBQy9CLElBQUEsc0JBQUcsRUFBQSx3QkFBd0IsRUFDM0Isc0NBQXNDLGVBQWUsc0ZBQXNGLENBQzVJLENBQUM7SUFDSixDQUFDO0lBQ0QsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgQml0cmF0ZSwgSVJlc291cmNlIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgQXJuLCBBcm5Gb3JtYXQsIER1cmF0aW9uLCBMYXp5LCBOYW1lcywgUmVzb3VyY2UsIFN0YWNrLCBUb2tlbiwgVW5zY29wZWRWYWxpZGF0aW9uRXJyb3IsIFZhbGlkYXRpb25FcnJvciB9IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCB0eXBlIHsgTWV0cmljT3B0aW9ucyB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1jbG91ZHdhdGNoJztcbmltcG9ydCB7IE1ldHJpYywgVW5pdCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1jbG91ZHdhdGNoJztcbmltcG9ydCB0eXBlIHsgR3JhbnQgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtaWFtJztcbmltcG9ydCB7IENmblJvdXRlck91dHB1dCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1tZWRpYWNvbm5lY3QnO1xuaW1wb3J0IHR5cGUgeyBJUm91dGVyT3V0cHV0UmVmLCBSb3V0ZXJPdXRwdXRSZWZlcmVuY2UgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbWVkaWFjb25uZWN0JztcbmltcG9ydCB7IGxpdCB9IGZyb20gJ2F3cy1jZGstbGliL2NvcmUvbGliL2hlbHBlcnMtaW50ZXJuYWwnO1xuaW1wb3J0IHsgYWRkQ29uc3RydWN0TWV0YWRhdGEgfSBmcm9tICdhd3MtY2RrLWxpYi9jb3JlL2xpYi9tZXRhZGF0YS1yZXNvdXJjZSc7XG5pbXBvcnQgeyBwcm9wZXJ0eUluamVjdGFibGUgfSBmcm9tICdhd3MtY2RrLWxpYi9jb3JlL2xpYi9wcm9wLWluamVjdGFibGUnO1xuaW1wb3J0IHR5cGUgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB0eXBlIHsgSUZsb3cgfSBmcm9tICcuL2Zsb3cnO1xuaW1wb3J0IHR5cGUgeyBNYWludGVuYW5jZUNvbmZpZ3VyYXRpb24sIEZvcndhcmRFcnJvckNvcnJlY3Rpb24sIFJvdXRpbmdTY29wZSB9IGZyb20gJy4vcm91dGVyLWlucHV0JztcbmltcG9ydCB0eXBlIHsgSVJvdXRlck5ldHdvcmtJbnRlcmZhY2UgfSBmcm9tICcuL3JvdXRlci1uZXR3b3JrLWludGVyZmFjZSc7XG5pbXBvcnQgdHlwZSB7IE1lZGlhTGl2ZVBpcGVsaW5lLCBSb3V0ZXJTcnRFbmNyeXB0aW9uLCBUcmFuc2l0RW5jcnlwdGlvbiB9IGZyb20gJy4vc2hhcmVkJztcbmltcG9ydCB7IHJlbmRlclRhZ3MsIGV4Y2VlZHNSb3V0ZXJUaWVyQml0cmF0ZSwgcmVzb2x2ZVJvdXRlclNydEVuY3J5cHRpb24sIHJlc29sdmVUcmFuc2l0RW5jcnlwdGlvbiwgdmFsaWRhdGVNYWludGVuYW5jZVRpbWUgfSBmcm9tICcuL3NoYXJlZCc7XG5cbi8qKlxuICogUHJvdG9jb2wgb3B0aW9ucyBhdmFpbGFibGUgZm9yIFJvdXRlciBPdXRwdXQgY29uZmlndXJhdGlvbnNcbiAqL1xuZXhwb3J0IGNsYXNzIFJvdXRlck91dHB1dFByb3RvY29sT3B0aW9ucyB7XG4gIC8qKiBSZWFsLXRpbWUgVHJhbnNwb3J0IFByb3RvY29sICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgUlRQID0gbmV3IFJvdXRlck91dHB1dFByb3RvY29sT3B0aW9ucygnUlRQJyk7XG4gIC8qKiBSZWxpYWJsZSBJbnRlcm5ldCBTdHJlYW0gVHJhbnNwb3J0ICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgUklTVCA9IG5ldyBSb3V0ZXJPdXRwdXRQcm90b2NvbE9wdGlvbnMoJ1JJU1QnKTtcbiAgLyoqIFNlY3VyZSBSZWxpYWJsZSBUcmFuc3BvcnQgLSBDYWxsZXIgbW9kZSAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IFNSVF9DQUxMRVIgPSBuZXcgUm91dGVyT3V0cHV0UHJvdG9jb2xPcHRpb25zKCdTUlRfQ0FMTEVSJyk7XG4gIC8qKiBTZWN1cmUgUmVsaWFibGUgVHJhbnNwb3J0IC0gTGlzdGVuZXIgbW9kZSAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IFNSVF9MSVNURU5FUiA9IG5ldyBSb3V0ZXJPdXRwdXRQcm90b2NvbE9wdGlvbnMoJ1NSVF9MSVNURU5FUicpO1xuXG4gIC8qKlxuICAgKiBVc2UgYSBjdXN0b20gcHJvdG9jb2wgdmFsdWVcbiAgICogQHBhcmFtIHZhbHVlIFRoZSBwcm90b2NvbCBzdHJpbmcgdmFsdWVcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgb2YodmFsdWU6IHN0cmluZyk6IFJvdXRlck91dHB1dFByb3RvY29sT3B0aW9ucyB7XG4gICAgcmV0dXJuIG5ldyBSb3V0ZXJPdXRwdXRQcm90b2NvbE9wdGlvbnModmFsdWUpO1xuICB9XG5cbiAgLyoqIEBwYXJhbSB2YWx1ZSBUaGUgcHJvdG9jb2wgc3RyaW5nIHZhbHVlICovXG4gIHByaXZhdGUgY29uc3RydWN0b3IocHVibGljIHJlYWRvbmx5IHZhbHVlOiBzdHJpbmcpIHt9XG5cbiAgLyoqIFJldHVybnMgdGhlIHN0cmluZyB2YWx1ZSAqL1xuICBwdWJsaWMgdG9TdHJpbmcoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy52YWx1ZTtcbiAgfVxufVxuXG4vKipcbiAqIFJvdXRpbmcgdGllciB0aGF0IGRldGVybWluZXMgdGhlIG1heGltdW0gYml0cmF0ZSAoaW4gTWJwcykgZm9yIGEgUm91dGVyIE91dHB1dC5cbiAqL1xuZXhwb3J0IGNsYXNzIFJvdXRlck91dHB1dFRpZXIge1xuICAvKiogVXAgdG8gMTAwIE1icHMgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBPVVRQVVRfMTAwID0gbmV3IFJvdXRlck91dHB1dFRpZXIoJ09VVFBVVF8xMDAnKTtcbiAgLyoqIFVwIHRvIDUwIE1icHMgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBPVVRQVVRfNTAgPSBuZXcgUm91dGVyT3V0cHV0VGllcignT1VUUFVUXzUwJyk7XG4gIC8qKiBVcCB0byAyMCBNYnBzICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgT1VUUFVUXzIwID0gbmV3IFJvdXRlck91dHB1dFRpZXIoJ09VVFBVVF8yMCcpO1xuXG4gIC8qKlxuICAgKiBVc2UgYSBjdXN0b20gdGllciB2YWx1ZVxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHRpZXIgc3RyaW5nIHZhbHVlXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIG9mKHZhbHVlOiBzdHJpbmcpOiBSb3V0ZXJPdXRwdXRUaWVyIHtcbiAgICByZXR1cm4gbmV3IFJvdXRlck91dHB1dFRpZXIodmFsdWUpO1xuICB9XG5cbiAgLyoqIEBwYXJhbSB2YWx1ZSBUaGUgdGllciBzdHJpbmcgdmFsdWUgKi9cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgdmFsdWU6IHN0cmluZykge31cblxuICAvKiogUmV0dXJucyB0aGUgc3RyaW5nIHZhbHVlICovXG4gIHB1YmxpYyB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnZhbHVlO1xuICB9XG59XG5cbi8qKlxuICogSW50ZXJmYWNlIGZvciBSb3V0ZXIgT3V0cHV0XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSVJvdXRlck91dHB1dCBleHRlbmRzIElSZXNvdXJjZSwgSVJvdXRlck91dHB1dFJlZiB7XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgcm91dGVyIG91dHB1dC5cbiAgICpcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcmVhZG9ubHkgcm91dGVyT3V0cHV0TmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgQW1hem9uIFJlc291cmNlIE5hbWUgKEFSTikgb2YgdGhlIHJvdXRlciBvdXRwdXQuXG4gICAqXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHJlYWRvbmx5IHJvdXRlck91dHB1dEFybjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgdW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIHJvdXRlciBvdXRwdXQuXG4gICAqXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHJlYWRvbmx5IHJvdXRlck91dHB1dElkOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBJUCBhZGRyZXNzIG9mIHRoZSByb3V0ZXIgb3V0cHV0LlxuICAgKlxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICByZWFkb25seSBpcEFkZHJlc3M6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHRpbWVzdGFtcCB3aGVuIHRoZSByb3V0ZXIgb3V0cHV0IHdhcyBjcmVhdGVkLlxuICAgKlxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICByZWFkb25seSBjcmVhdGVkQXQ/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSB0aW1lc3RhbXAgd2hlbiB0aGUgcm91dGVyIG91dHB1dCB3YXMgbGFzdCB1cGRhdGVkLlxuICAgKlxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICByZWFkb25seSB1cGRhdGVkQXQ/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIENsb3VkV2F0Y2ggbWV0cmljIGZvciB0aGlzIHJvdXRlciBvdXRwdXQuXG4gICAqXG4gICAqIFJvdXRlciBvdXRwdXQgbWV0cmljcyBhcmUgZGltZW5zaW9uZWQgYnkgYFJvdXRlck91dHB1dEFSTmAuIFNlZSB0aGUgTWVkaWFDb25uZWN0XG4gICAqIGRvY3VtZW50YXRpb24gZm9yIGF2YWlsYWJsZSBtZXRyaWMgbmFtZXMgKGUuZy4gYFJvdXRlck91dHB1dEJpdFJhdGVgLFxuICAgKiBgUm91dGVyT3V0cHV0VG90YWxQYWNrZXRzYCkuXG4gICAqL1xuICBtZXRyaWMobWV0cmljTmFtZTogc3RyaW5nLCBwcm9wcz86IE1ldHJpY09wdGlvbnMpOiBNZXRyaWM7XG5cbiAgLyoqXG4gICAqIE1ldHJpYyBmb3IgdGhlIGJpdHJhdGUgb2YgdGhlIHJvdXRlciBvdXRwdXQncyBwYXlsb2FkLlxuICAgKiBAZGVmYXVsdCAtIGF2ZXJhZ2Ugb3ZlciA2MCBzZWNvbmRzXG4gICAqL1xuICBtZXRyaWNCaXRyYXRlKHByb3BzPzogTWV0cmljT3B0aW9ucyk6IE1ldHJpYztcblxuICAvKipcbiAgICogTWV0cmljIGZvciB0aGUgdG90YWwgbnVtYmVyIG9mIHBhY2tldHMgc2VudCBieSB0aGUgcm91dGVyIG91dHB1dC5cbiAgICogQGRlZmF1bHQgLSBzdW0gb3ZlciA2MCBzZWNvbmRzXG4gICAqL1xuICBtZXRyaWNUb3RhbFBhY2tldHMocHJvcHM/OiBNZXRyaWNPcHRpb25zKTogTWV0cmljO1xuXG4gIC8qKlxuICAgKiBNZXRyaWMgZm9yIHRoZSByb3V0ZXIgb3V0cHV0IGNvbm5lY3Rpb24gc3RhdGUgKDEgY29ubmVjdGVkLCAwIGRpc2Nvbm5lY3RlZCkuIEFwcGxpZXMgdG8gU1JUIG91dHB1dHMgb25seS5cbiAgICogQGRlZmF1bHQgLSBtaW5pbXVtIG92ZXIgNjAgc2Vjb25kc1xuICAgKi9cbiAgbWV0cmljQ29ubmVjdGVkKHByb3BzPzogTWV0cmljT3B0aW9ucyk6IE1ldHJpYztcblxuICAvKipcbiAgICogTWV0cmljIGZvciB0aGUgbnVtYmVyIG9mIHJldHJhbnNtaXR0ZWQgcGFja2V0cyByZXF1ZXN0ZWQgdGhyb3VnaCBhdXRvbWF0aWMgcmVwZWF0IHJlcXVlc3QgKEFSUSkuXG4gICAqIEFwcGxpZXMgdG8gUklTVCBhbmQgU1JUIG91dHB1dHMgb25seS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBzdW0gb3ZlciA2MCBzZWNvbmRzXG4gICAqL1xuICBtZXRyaWNBcnFSZXF1ZXN0cyhwcm9wcz86IE1ldHJpY09wdGlvbnMpOiBNZXRyaWM7XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgY3JlYXRpbmcgYSBSb3V0ZXIgT3V0cHV0XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUm91dGVyT3V0cHV0UHJvcHMge1xuICAvKipcbiAgICogTmFtZSBvZiB0aGUgUm91dGVyIE91dHB1dFxuICAgKiBAZGVmYXVsdCAtIEdlbmVyYXRlZCBhdXRvbWF0aWNhbGx5XG4gICAqL1xuICByZWFkb25seSByb3V0ZXJPdXRwdXROYW1lPzogc3RyaW5nO1xuICAvKiogTWF4aW11bSBiaXRyYXRlIGluIGJpdHMgcGVyIHNlY29uZCB0aGF0IHRoZSBSb3V0ZXIgT3V0cHV0IGNhbiBoYW5kbGUgKi9cbiAgcmVhZG9ubHkgbWF4aW11bUJpdHJhdGU6IEJpdHJhdGU7XG4gIC8qKiBSb3V0aW5nIHNjb3BlIGZvciB0aGUgUm91dGVyIE91dHB1dCAqL1xuICByZWFkb25seSByb3V0aW5nU2NvcGU6IFJvdXRpbmdTY29wZTtcbiAgLyoqXG4gICAqIFJvdXRpbmcgdGllciB0aGF0IGRldGVybWluZXMgdGhlIG1heGltdW0gbnVtYmVyIG9mIG91dHB1dHMuXG4gICAqXG4gICAqIEBkZWZhdWx0IFJvdXRlck91dHB1dFRpZXIuT1VUUFVUXzIwXG4gICAqL1xuICByZWFkb25seSB0aWVyPzogUm91dGVyT3V0cHV0VGllcjtcbiAgLyoqIENvbmZpZ3VyYXRpb24gZm9yIHRoZSBSb3V0ZXIgT3V0cHV0IChzdGFuZGFyZCwgTWVkaWFDb25uZWN0IEZsb3csIG9yIE1lZGlhTGl2ZSkgKi9cbiAgcmVhZG9ubHkgY29uZmlndXJhdGlvbjogUm91dGVyT3V0cHV0Q29uZmlndXJhdGlvbjtcbiAgLyoqXG4gICAqIE1haW50ZW5hbmNlIHdpbmRvdyBjb25maWd1cmF0aW9uXG4gICAqIEBkZWZhdWx0IC0gRGVmYXVsdCBtYWludGVuYW5jZSB3aW5kb3cgd2lsbCBiZSB1c2VkXG4gICAqL1xuICByZWFkb25seSBtYWludGVuYW5jZUNvbmZpZ3VyYXRpb24/OiBNYWludGVuYW5jZUNvbmZpZ3VyYXRpb247XG4gIC8qKlxuICAgKiBBV1MgcmVnaW9uIHdoZXJlIHRoZSBSb3V0ZXIgT3V0cHV0IHdpbGwgYmUgY3JlYXRlZFxuICAgKiBAZGVmYXVsdCAtIERlZmF1bHRzIHRvIHRoZSBzYW1lIHJlZ2lvbiBhcyBzdGFja1xuICAgKi9cbiAgcmVhZG9ubHkgcmVnaW9uTmFtZT86IHN0cmluZztcbiAgLyoqXG4gICAqIFRhZ3MgdG8gYWRkIHRvIHRoZSBSb3V0ZXIgT3V0cHV0XG4gICAqIEBkZWZhdWx0IC0gTm8gdGFnZ2luZ1xuICAgKi9cbiAgcmVhZG9ubHkgdGFncz86IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH07XG59XG5cbi8qKlxuICogQXR0cmlidXRlcyBmb3IgaW1wb3J0aW5nIGFuIGV4aXN0aW5nIFJvdXRlciBPdXRwdXQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUm91dGVyT3V0cHV0QXR0cmlidXRlcyB7XG4gIC8qKlxuICAgKiBUaGUgQVJOIG9mIHRoZSByb3V0ZXIgb3V0cHV0LlxuICAgKi9cbiAgcmVhZG9ubHkgcm91dGVyT3V0cHV0QXJuOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSByb3V0ZXIgb3V0cHV0LlxuICAgKlxuICAgKiBUaGUgbmFtZSBpcyBub3QgZW5jb2RlZCBpbiB0aGUgQVJOICh0aGUgQVJOIGNvbnRhaW5zIG9ubHkgdGhlIHNlcnZpY2UtZ2VuZXJhdGVkIElEKSxcbiAgICogc28gcHJvdmlkZSBpdCBoZXJlIGlmIHlvdSBuZWVkIHRvIGFjY2VzcyBgcm91dGVyT3V0cHV0TmFtZWAgb24gdGhlIGltcG9ydGVkIGNvbnN0cnVjdC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSByb3V0ZXJPdXRwdXROYW1lIGlzIG5vdCBhdmFpbGFibGUgb24gdGhlIGltcG9ydGVkIGNvbnN0cnVjdFxuICAgKi9cbiAgcmVhZG9ubHkgcm91dGVyT3V0cHV0TmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHVuaXF1ZSBpZGVudGlmaWVyIG9mIHRoZSByb3V0ZXIgb3V0cHV0LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIHBhcnNlZCBmcm9tIHRoZSBBUk4gd2hlbiBhdmFpbGFibGVcbiAgICovXG4gIHJlYWRvbmx5IHJvdXRlck91dHB1dElkPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIFJUUCBwcm90b2NvbCBjb25maWd1cmF0aW9uIGZvciBvdXRwdXRzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUnRwT3V0cHV0UHJvdG9jb2xQcm9wcyB7XG4gIC8qKiBEZXN0aW5hdGlvbiBJUCBhZGRyZXNzIGZvciBSVFAgdHJhZmZpYyAqL1xuICByZWFkb25seSBkZXN0aW5hdGlvbkFkZHJlc3M6IHN0cmluZztcbiAgLyoqIFBvcnQgbnVtYmVyIGZvciBSVFAgdHJhZmZpYyAqL1xuICByZWFkb25seSBwb3J0OiBudW1iZXI7XG4gIC8qKlxuICAgKiBGb3J3YXJkIEVycm9yIENvcnJlY3Rpb24gc2V0dGluZ1xuICAgKiBAZGVmYXVsdCAtIHVuZGVmaW5lZDsgd2hlbiBvbWl0dGVkLCBNZWRpYUNvbm5lY3QgYXBwbGllcyBGb3J3YXJkRXJyb3JDb3JyZWN0aW9uLkRJU0FCTEVEIGF0IGRlcGxveSB0aW1lXG4gICAqL1xuICByZWFkb25seSBmb3J3YXJkRXJyb3JDb3JyZWN0aW9uPzogRm9yd2FyZEVycm9yQ29ycmVjdGlvbjtcbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBSSVNUIHByb3RvY29sIGNvbmZpZ3VyYXRpb24gZm9yIG91dHB1dHNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSaXN0T3V0cHV0UHJvdG9jb2xQcm9wcyB7XG4gIC8qKiBEZXN0aW5hdGlvbiBJUCBhZGRyZXNzIGZvciBSSVNUIHRyYWZmaWMgKi9cbiAgcmVhZG9ubHkgZGVzdGluYXRpb25BZGRyZXNzOiBzdHJpbmc7XG4gIC8qKiBQb3J0IG51bWJlciBmb3IgUklTVCB0cmFmZmljICovXG4gIHJlYWRvbmx5IHBvcnQ6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBTUlQgTGlzdGVuZXIgcHJvdG9jb2wgY29uZmlndXJhdGlvbiBmb3Igb3V0cHV0c1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFNydExpc3RlbmVyT3V0cHV0UHJvdG9jb2xQcm9wcyB7XG4gIC8qKiBQb3J0IG51bWJlciBmb3IgU1JUIGxpc3RlbmVyICovXG4gIHJlYWRvbmx5IHBvcnQ6IG51bWJlcjtcbiAgLyoqIE1pbmltdW0gbGF0ZW5jeSBmb3IgU1JUICovXG4gIHJlYWRvbmx5IG1pbmltdW1MYXRlbmN5OiBEdXJhdGlvbjtcbiAgLyoqXG4gICAqIE9wdGlvbmFsIGVuY3J5cHRpb24gY29uZmlndXJhdGlvbiBmb3IgU1JUIHN0cmVhbXNcbiAgICogQGRlZmF1bHQgLSBObyBlbmNyeXB0aW9uXG4gICAqL1xuICByZWFkb25seSBlbmNyeXB0aW9uQ29uZmlndXJhdGlvbj86IFJvdXRlclNydEVuY3J5cHRpb247XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgU1JUIENhbGxlciBwcm90b2NvbCBjb25maWd1cmF0aW9uIGZvciBvdXRwdXRzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3J0Q2FsbGVyT3V0cHV0UHJvdG9jb2xQcm9wcyB7XG4gIC8qKiBEZXN0aW5hdGlvbiBJUCBhZGRyZXNzIHRvIGNvbm5lY3QgdG8gKi9cbiAgcmVhZG9ubHkgZGVzdGluYXRpb25BZGRyZXNzOiBzdHJpbmc7XG4gIC8qKiBEZXN0aW5hdGlvbiBwb3J0IHRvIGNvbm5lY3QgdG8gKi9cbiAgcmVhZG9ubHkgZGVzdGluYXRpb25Qb3J0OiBudW1iZXI7XG4gIC8qKiBNaW5pbXVtIGxhdGVuY3kgZm9yIFNSVCAqL1xuICByZWFkb25seSBtaW5pbXVtTGF0ZW5jeTogRHVyYXRpb247XG4gIC8qKlxuICAgKiBPcHRpb25hbCBzdHJlYW0gSUQgZm9yIFNSVCBjb25uZWN0aW9uXG4gICAqIEBkZWZhdWx0IC0gTm8gc3RyZWFtIElEXG4gICAqL1xuICByZWFkb25seSBzdHJlYW1JZD86IHN0cmluZztcbiAgLyoqXG4gICAqIE9wdGlvbmFsIGVuY3J5cHRpb24gY29uZmlndXJhdGlvbiBmb3IgU1JUIHN0cmVhbXNcbiAgICogQGRlZmF1bHQgLSBObyBlbmNyeXB0aW9uXG4gICAqL1xuICByZWFkb25seSBlbmNyeXB0aW9uQ29uZmlndXJhdGlvbj86IFJvdXRlclNydEVuY3J5cHRpb247XG59XG5cbi8qKlxuICogRmFjdG9yeSBjbGFzcyBmb3IgY3JlYXRpbmcgUm91dGVyIE91dHB1dCBwcm90b2NvbCBjb25maWd1cmF0aW9ucy5cbiAqXG4gKiBTdXBwb3J0ZWQgcHJvdG9jb2xzOiBSVFAsIFJJU1QsIFNSVCAoTGlzdGVuZXIgYW5kIENhbGxlcikuXG4gKi9cbmV4cG9ydCBjbGFzcyBSb3V0ZXJPdXRwdXRQcm90b2NvbCB7XG4gIC8qKlxuICAgKiBDcmVhdGUgYW4gUlRQIHByb3RvY29sIGNvbmZpZ3VyYXRpb25cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICpcbiAgICogICAgUm91dGVyT3V0cHV0UHJvdG9jb2wucnRwKHtcbiAgICogICAgICBkZXN0aW5hdGlvbkFkZHJlc3M6ICcxMC4wLjAuMScsXG4gICAqICAgICAgcG9ydDogNTAwMCxcbiAgICogICAgfSk7XG4gICAqXG4gICAqIEBwYXJhbSBwcm9wcyBSVFAgcHJvdG9jb2wgcHJvcGVydGllc1xuICAgKiBAcmV0dXJucyBSb3V0ZXJPdXRwdXRQcm90b2NvbCBpbnN0YW5jZSBjb25maWd1cmVkIGZvciBSVFBcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcnRwKHByb3BzOiBSdHBPdXRwdXRQcm90b2NvbFByb3BzKTogUm91dGVyT3V0cHV0UHJvdG9jb2wge1xuICAgIFJvdXRlck91dHB1dFByb3RvY29sLnZhbGlkYXRlUG9ydChwcm9wcy5wb3J0KTtcbiAgICByZXR1cm4gbmV3IFJvdXRlck91dHB1dFByb3RvY29sKFJvdXRlck91dHB1dFByb3RvY29sT3B0aW9ucy5SVFAsIHtcbiAgICAgIHJ0cDoge1xuICAgICAgICBkZXN0aW5hdGlvbkFkZHJlc3M6IHByb3BzLmRlc3RpbmF0aW9uQWRkcmVzcyxcbiAgICAgICAgZGVzdGluYXRpb25Qb3J0OiBwcm9wcy5wb3J0LFxuICAgICAgICBmb3J3YXJkRXJyb3JDb3JyZWN0aW9uOiBwcm9wcy5mb3J3YXJkRXJyb3JDb3JyZWN0aW9uLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBSSVNUIHByb3RvY29sIGNvbmZpZ3VyYXRpb25cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICpcbiAgICogICAgUm91dGVyT3V0cHV0UHJvdG9jb2wucmlzdCh7XG4gICAqICAgICAgZGVzdGluYXRpb25BZGRyZXNzOiAnMTAuMC4wLjEnLFxuICAgKiAgICAgIHBvcnQ6IDUwMDAsXG4gICAqICAgIH0pO1xuICAgKlxuICAgKiBAcGFyYW0gcHJvcHMgUklTVCBwcm90b2NvbCBwcm9wZXJ0aWVzXG4gICAqIEByZXR1cm5zIFJvdXRlck91dHB1dFByb3RvY29sIGluc3RhbmNlIGNvbmZpZ3VyZWQgZm9yIFJJU1RcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcmlzdChwcm9wczogUmlzdE91dHB1dFByb3RvY29sUHJvcHMpOiBSb3V0ZXJPdXRwdXRQcm90b2NvbCB7XG4gICAgUm91dGVyT3V0cHV0UHJvdG9jb2wudmFsaWRhdGVQb3J0KHByb3BzLnBvcnQpO1xuICAgIHJldHVybiBuZXcgUm91dGVyT3V0cHV0UHJvdG9jb2woUm91dGVyT3V0cHV0UHJvdG9jb2xPcHRpb25zLlJJU1QsIHtcbiAgICAgIHJpc3Q6IHtcbiAgICAgICAgZGVzdGluYXRpb25BZGRyZXNzOiBwcm9wcy5kZXN0aW5hdGlvbkFkZHJlc3MsXG4gICAgICAgIGRlc3RpbmF0aW9uUG9ydDogcHJvcHMucG9ydCxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGFuIFNSVCBMaXN0ZW5lciBwcm90b2NvbCBjb25maWd1cmF0aW9uXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqXG4gICAqICAgIFJvdXRlck91dHB1dFByb3RvY29sLnNydExpc3RlbmVyKHtcbiAgICogICAgICBwb3J0OiA1MDAwLFxuICAgKiAgICAgIG1pbmltdW1MYXRlbmN5OiBEdXJhdGlvbi5taWxsaXMoMTI1KSxcbiAgICogICAgfSk7XG4gICAqXG4gICAqIEBwYXJhbSBwcm9wcyBTUlQgTGlzdGVuZXIgcHJvdG9jb2wgcHJvcGVydGllc1xuICAgKiBAcmV0dXJucyBSb3V0ZXJPdXRwdXRQcm90b2NvbCBpbnN0YW5jZSBjb25maWd1cmVkIGZvciBTUlQgTGlzdGVuZXJcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgc3J0TGlzdGVuZXIocHJvcHM6IFNydExpc3RlbmVyT3V0cHV0UHJvdG9jb2xQcm9wcyk6IFJvdXRlck91dHB1dFByb3RvY29sIHtcbiAgICBSb3V0ZXJPdXRwdXRQcm90b2NvbC52YWxpZGF0ZVBvcnQocHJvcHMucG9ydCk7XG4gICAgcmV0dXJuIG5ldyBSb3V0ZXJPdXRwdXRQcm90b2NvbChSb3V0ZXJPdXRwdXRQcm90b2NvbE9wdGlvbnMuU1JUX0xJU1RFTkVSLCB7XG4gICAgICBzcnRMaXN0ZW5lcjoge1xuICAgICAgICBwb3J0OiBwcm9wcy5wb3J0LFxuICAgICAgICBtaW5pbXVtTGF0ZW5jeU1pbGxpc2Vjb25kczogcHJvcHMubWluaW11bUxhdGVuY3kudG9NaWxsaXNlY29uZHMoKSxcbiAgICAgIH0sXG4gICAgfSwgcHJvcHMuZW5jcnlwdGlvbkNvbmZpZ3VyYXRpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhbiBTUlQgQ2FsbGVyIHByb3RvY29sIGNvbmZpZ3VyYXRpb25cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICpcbiAgICogICAgUm91dGVyT3V0cHV0UHJvdG9jb2wuc3J0Q2FsbGVyKHtcbiAgICogICAgICBkZXN0aW5hdGlvbkFkZHJlc3M6ICcxMC4wLjAuMScsXG4gICAqICAgICAgZGVzdGluYXRpb25Qb3J0OiA1MDAwLFxuICAgKiAgICAgIG1pbmltdW1MYXRlbmN5OiBEdXJhdGlvbi5taWxsaXMoMTI1KSxcbiAgICogICAgfSk7XG4gICAqXG4gICAqIEBwYXJhbSBwcm9wcyBTUlQgQ2FsbGVyIHByb3RvY29sIHByb3BlcnRpZXNcbiAgICogQHJldHVybnMgUm91dGVyT3V0cHV0UHJvdG9jb2wgaW5zdGFuY2UgY29uZmlndXJlZCBmb3IgU1JUIENhbGxlclxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBzcnRDYWxsZXIocHJvcHM6IFNydENhbGxlck91dHB1dFByb3RvY29sUHJvcHMpOiBSb3V0ZXJPdXRwdXRQcm90b2NvbCB7XG4gICAgUm91dGVyT3V0cHV0UHJvdG9jb2wudmFsaWRhdGVTcnRDYWxsZXJQb3J0KHByb3BzLmRlc3RpbmF0aW9uUG9ydCk7XG4gICAgcmV0dXJuIG5ldyBSb3V0ZXJPdXRwdXRQcm90b2NvbChSb3V0ZXJPdXRwdXRQcm90b2NvbE9wdGlvbnMuU1JUX0NBTExFUiwge1xuICAgICAgc3J0Q2FsbGVyOiB7XG4gICAgICAgIGRlc3RpbmF0aW9uQWRkcmVzczogcHJvcHMuZGVzdGluYXRpb25BZGRyZXNzLFxuICAgICAgICBkZXN0aW5hdGlvblBvcnQ6IHByb3BzLmRlc3RpbmF0aW9uUG9ydCxcbiAgICAgICAgbWluaW11bUxhdGVuY3lNaWxsaXNlY29uZHM6IHByb3BzLm1pbmltdW1MYXRlbmN5LnRvTWlsbGlzZWNvbmRzKCksXG4gICAgICAgIHN0cmVhbUlkOiBwcm9wcy5zdHJlYW1JZCxcbiAgICAgIH0sXG4gICAgfSwgcHJvcHMuZW5jcnlwdGlvbkNvbmZpZ3VyYXRpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIHRoYXQgcG9ydCBpcyB3aXRoaW4gdGhlIHZhbGlkIHJhbmdlICgzMDAwLTMwMDAwKVxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgdmFsaWRhdGVQb3J0KHBvcnQ6IG51bWJlcik6IHZvaWQge1xuICAgIGlmICghVG9rZW4uaXNVbnJlc29sdmVkKHBvcnQpICYmIChwb3J0IDwgMzAwMCB8fCBwb3J0ID4gMzAwMDApKSB7XG4gICAgICB0aHJvdyBuZXcgVW5zY29wZWRWYWxpZGF0aW9uRXJyb3IobGl0YFJvdXRlck91dHB1dFBvcnRSYW5nZWAsIGBQb3J0IG11c3QgYmUgYmV0d2VlbiAzMDAwIGFuZCAzMDAwMCwgZ290ICR7cG9ydH1gKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgdGhhdCBTUlQgQ2FsbGVyIHBvcnQgaXMgd2l0aGluIHRoZSB2YWxpZCByYW5nZSAoMC02NTUzNSlcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIHZhbGlkYXRlU3J0Q2FsbGVyUG9ydChwb3J0OiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAoIVRva2VuLmlzVW5yZXNvbHZlZChwb3J0KSAmJiAocG9ydCA8IDAgfHwgcG9ydCA+IDY1NTM1KSkge1xuICAgICAgdGhyb3cgbmV3IFVuc2NvcGVkVmFsaWRhdGlvbkVycm9yKGxpdGBTcnRDYWxsZXJQb3J0UmFuZ2VgLCBgU1JUIENhbGxlciBwb3J0IG11c3QgYmUgYmV0d2VlbiAwIGFuZCA2NTUzNSwgZ290ICR7cG9ydH1gKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlYWRvbmx5IF9wcm90b2NvbE5hbWU6IFJvdXRlck91dHB1dFByb3RvY29sT3B0aW9ucztcbiAgcHJpdmF0ZSByZWFkb25seSBfY29uZmlnOiBDZm5Sb3V0ZXJPdXRwdXQuUm91dGVyT3V0cHV0UHJvdG9jb2xDb25maWd1cmF0aW9uUHJvcGVydHk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2VuY3J5cHRpb24/OiBSb3V0ZXJTcnRFbmNyeXB0aW9uO1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoXG4gICAgcHJvdG9jb2xOYW1lOiBSb3V0ZXJPdXRwdXRQcm90b2NvbE9wdGlvbnMsXG4gICAgY29uZmlnOiBDZm5Sb3V0ZXJPdXRwdXQuUm91dGVyT3V0cHV0UHJvdG9jb2xDb25maWd1cmF0aW9uUHJvcGVydHksXG4gICAgZW5jcnlwdGlvbj86IFJvdXRlclNydEVuY3J5cHRpb24sXG4gICkge1xuICAgIHRoaXMuX3Byb3RvY29sTmFtZSA9IHByb3RvY29sTmFtZTtcbiAgICB0aGlzLl9jb25maWcgPSBjb25maWc7XG4gICAgdGhpcy5fZW5jcnlwdGlvbiA9IGVuY3J5cHRpb247XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZSB0aGlzIHByb3RvY29sIHRvIGl0cyBDRk4tcmVhZHkgZm9ybS4gUmV0dXJucyB0aGUgcHJvdG9jb2wgaWRlbnRpZmllclxuICAgKiBhbmQgdGhlIENGTiBjb25maWd1cmF0aW9uIHNoYXBlIHdpdGggU1JUIGVuY3J5cHRpb24gYXV0by1yb2xlIG1hdGVyaWFsaXplZCBpZiBuZWVkZWQuXG4gICAqXG4gICAqIEBwYXJhbSBzY29wZSAgICAgICAgICAgICBDb25zdHJ1Y3QgdGhhdCBzY29wZXMgdGhlIGF1dG8tY3JlYXRlZCBlbmNyeXB0aW9uIHJvbGVcbiAgICogQHBhcmFtIHJvdXRlck91dHB1dEFybiAgIE9wdGlvbmFsIEFSTiBvZiB0aGUgY29uc3VtaW5nIHJvdXRlciBvdXRwdXQg4oCUIHdoZW4gcHJvdmlkZWQsXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICBzY29wZXMgdGhlIGF1dG8tY3JlYXRlZCBlbmNyeXB0aW9uIHJvbGUncyB0cnVzdCBwb2xpY3kuXG4gICAqXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcHVibGljIF9iaW5kKHNjb3BlOiBDb25zdHJ1Y3QsIHJvdXRlck91dHB1dEFybj86IHN0cmluZyk6IHtcbiAgICBuYW1lOiBSb3V0ZXJPdXRwdXRQcm90b2NvbE9wdGlvbnM7XG4gICAgY29uZmlnOiBDZm5Sb3V0ZXJPdXRwdXQuUm91dGVyT3V0cHV0UHJvdG9jb2xDb25maWd1cmF0aW9uUHJvcGVydHk7XG4gICAgZ3JhbnQ/OiBHcmFudDtcbiAgfSB7XG4gICAgaWYgKCF0aGlzLl9lbmNyeXB0aW9uKSB7XG4gICAgICByZXR1cm4geyBuYW1lOiB0aGlzLl9wcm90b2NvbE5hbWUsIGNvbmZpZzogdGhpcy5fY29uZmlnIH07XG4gICAgfVxuXG4gICAgY29uc3QgeyBjb25maWc6IGVuY3J5cHRpb25Db25maWd1cmF0aW9uLCBncmFudCB9ID0gcmVzb2x2ZVJvdXRlclNydEVuY3J5cHRpb24oc2NvcGUsICdFbmNyeXB0aW9uUm9sZScsIHRoaXMuX2VuY3J5cHRpb24sIHJvdXRlck91dHB1dEFybik7XG5cbiAgICBpZiAodGhpcy5fY29uZmlnLnNydExpc3RlbmVyKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBuYW1lOiB0aGlzLl9wcm90b2NvbE5hbWUsXG4gICAgICAgIGNvbmZpZzogeyBzcnRMaXN0ZW5lcjogeyAuLi50aGlzLl9jb25maWcuc3J0TGlzdGVuZXIsIGVuY3J5cHRpb25Db25maWd1cmF0aW9uIH0gfSxcbiAgICAgICAgZ3JhbnQsXG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAodGhpcy5fY29uZmlnLnNydENhbGxlcikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbmFtZTogdGhpcy5fcHJvdG9jb2xOYW1lLFxuICAgICAgICBjb25maWc6IHsgc3J0Q2FsbGVyOiB7IC4uLnRoaXMuX2NvbmZpZy5zcnRDYWxsZXIsIGVuY3J5cHRpb25Db25maWd1cmF0aW9uIH0gfSxcbiAgICAgICAgZ3JhbnQsXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4geyBuYW1lOiB0aGlzLl9wcm90b2NvbE5hbWUsIGNvbmZpZzogdGhpcy5fY29uZmlnIH07XG4gIH1cbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBzdGFuZGFyZCBSb3V0ZXIgT3V0cHV0IGNvbmZpZ3VyYXRpb25cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdGFuZGFyZE91dHB1dENvbmZpZ3VyYXRpb25Qcm9wcyB7XG4gIC8qKiBOZXR3b3JrIGludGVyZmFjZSBmb3IgdGhlIFJvdXRlciBPdXRwdXQgKi9cbiAgcmVhZG9ubHkgbmV0d29ya0ludGVyZmFjZTogSVJvdXRlck5ldHdvcmtJbnRlcmZhY2U7XG4gIC8qKiBQcm90b2NvbCBjb25maWd1cmF0aW9uIGZvciB0aGUgb3V0cHV0ICovXG4gIHJlYWRvbmx5IHByb3RvY29sOiBSb3V0ZXJPdXRwdXRQcm90b2NvbDtcbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBNZWRpYUxpdmUgUm91dGVyIE91dHB1dCBjb25maWd1cmF0aW9uIHdpdGggc3BlY2lmaWMgaW5wdXQgY29ubmVjdGlvblxuICovXG5leHBvcnQgaW50ZXJmYWNlIE1lZGlhTGl2ZUlucHV0Q29ubmVjdGlvblByb3BzIHtcbiAgLyoqXG4gICAqIEFSTiBvZiB0aGUgTWVkaWFMaXZlIGlucHV0IHRvIHNlbmQgb3V0cHV0IHRvLlxuICAgKlxuICAgKiBOb3RlOiBUaGlzIHdpbGwgY2hhbmdlIHRvIGFjY2VwdCBhbiBJSW5wdXRSZWYgKHR5cGVkIE1lZGlhTGl2ZSBJbnB1dCByZWZlcmVuY2UpXG4gICAqIHdoZW4gdGhlIEBhd3MtY2RrL2F3cy1tZWRpYWxpdmUtYWxwaGEgTDIgY29uc3RydWN0IGlzIHJlbGVhc2VkLlxuICAgKi9cbiAgcmVhZG9ubHkgbWVkaWFMaXZlSW5wdXRBcm46IHN0cmluZztcbiAgLyoqIFBpcGVsaW5lIElEIGZvciBNZWRpYUxpdmUgaW5wdXQgKi9cbiAgcmVhZG9ubHkgbWVkaWFMaXZlUGlwZWxpbmVJZDogTWVkaWFMaXZlUGlwZWxpbmU7XG4gIC8qKlxuICAgKiBPcHRpb25hbCB0cmFuc2l0IGVuY3J5cHRpb24gY29uZmlndXJhdGlvblxuICAgKiBAZGVmYXVsdCAtIEF1dG9tYXRpYyBlbmNyeXB0aW9uIHdpbGwgYmUgdXNlZFxuICAgKi9cbiAgcmVhZG9ubHkgZGVzdGluYXRpb25UcmFuc2l0RW5jcnlwdGlvbj86IFRyYW5zaXRFbmNyeXB0aW9uO1xufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIE1lZGlhTGl2ZSBSb3V0ZXIgT3V0cHV0IGNvbmZpZ3VyYXRpb24gd2l0aG91dCBzcGVjaWZpYyBpbnB1dCBjb25uZWN0aW9uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWVkaWFMaXZlTm9JbnB1dENvbm5lY3Rpb25Qcm9wcyB7XG4gIC8qKiBBdmFpbGFiaWxpdHkgem9uZSBmb3IgdGhlIHJvdXRlciBvdXRwdXQgd2hlbiBub3QgY29ubmVjdGluZyB0byBhIHNwZWNpZmljIGlucHV0ICovXG4gIHJlYWRvbmx5IGF2YWlsYWJpbGl0eVpvbmU6IHN0cmluZztcbiAgLyoqXG4gICAqIE9wdGlvbmFsIHRyYW5zaXQgZW5jcnlwdGlvbiBjb25maWd1cmF0aW9uXG4gICAqIEBkZWZhdWx0IC0gQXV0b21hdGljIGVuY3J5cHRpb24gd2lsbCBiZSB1c2VkXG4gICAqL1xuICByZWFkb25seSBkZXN0aW5hdGlvblRyYW5zaXRFbmNyeXB0aW9uPzogVHJhbnNpdEVuY3J5cHRpb247XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgTWVkaWFDb25uZWN0IEZsb3cgUm91dGVyIE91dHB1dCBjb25maWd1cmF0aW9uIHdpdGggc3BlY2lmaWMgZmxvdyBjb25uZWN0aW9uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWVkaWFDb25uZWN0Rmxvd0Nvbm5lY3Rpb25Qcm9wcyB7XG4gIC8qKiBNZWRpYUNvbm5lY3QgRmxvdyB0byBzZW5kIG91dHB1dCB0byAqL1xuICByZWFkb25seSBmbG93OiBJRmxvdztcbiAgLyoqXG4gICAqIE9wdGlvbmFsIHRyYW5zaXQgZW5jcnlwdGlvbiBjb25maWd1cmF0aW9uXG4gICAqIEBkZWZhdWx0IC0gQXV0b21hdGljIGVuY3J5cHRpb24gd2lsbCBiZSB1c2VkXG4gICAqL1xuICByZWFkb25seSBkZXN0aW5hdGlvblRyYW5zaXRFbmNyeXB0aW9uPzogVHJhbnNpdEVuY3J5cHRpb247XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgTWVkaWFDb25uZWN0IEZsb3cgUm91dGVyIE91dHB1dCBjb25maWd1cmF0aW9uIHdpdGhvdXQgc3BlY2lmaWMgZmxvdyBjb25uZWN0aW9uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWVkaWFDb25uZWN0Rmxvd05vQ29ubmVjdGlvblByb3BzIHtcbiAgLyoqIEF2YWlsYWJpbGl0eSB6b25lIGZvciB0aGUgcm91dGVyIG91dHB1dCB3aGVuIG5vdCBjb25uZWN0aW5nIHRvIGEgc3BlY2lmaWMgZmxvdyAqL1xuICByZWFkb25seSBhdmFpbGFiaWxpdHlab25lOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBPcHRpb25hbCB0cmFuc2l0IGVuY3J5cHRpb24gY29uZmlndXJhdGlvblxuICAgKiBAZGVmYXVsdCAtIEF1dG9tYXRpYyBlbmNyeXB0aW9uIHdpbGwgYmUgdXNlZFxuICAgKi9cbiAgcmVhZG9ubHkgZGVzdGluYXRpb25UcmFuc2l0RW5jcnlwdGlvbj86IFRyYW5zaXRFbmNyeXB0aW9uO1xufVxuXG4vKipcbiAqIEZhY3RvcnkgY2xhc3MgZm9yIGNyZWF0aW5nIFJvdXRlciBPdXRwdXQgY29uZmlndXJhdGlvbnNcbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFJvdXRlck91dHB1dENvbmZpZ3VyYXRpb24ge1xuICAvKipcbiAgICogQ3JlYXRlIGEgc3RhbmRhcmQgUm91dGVyIE91dHB1dCBjb25maWd1cmF0aW9uIHdpdGggYSBzaW5nbGUgcHJvdG9jb2xcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICpcbiAgICogICAgZGVjbGFyZSBjb25zdCBuZXR3b3JrSW50ZXJmYWNlOiBSb3V0ZXJOZXR3b3JrSW50ZXJmYWNlO1xuICAgKlxuICAgKiAgICBSb3V0ZXJPdXRwdXRDb25maWd1cmF0aW9uLnN0YW5kYXJkKHtcbiAgICogICAgICBuZXR3b3JrSW50ZXJmYWNlLFxuICAgKiAgICAgIHByb3RvY29sOiBSb3V0ZXJPdXRwdXRQcm90b2NvbC5ydHAoe1xuICAgKiAgICAgICAgZGVzdGluYXRpb25BZGRyZXNzOiAnMTAuMC4wLjEnLFxuICAgKiAgICAgICAgcG9ydDogNTAwMCxcbiAgICogICAgICB9KSxcbiAgICogICAgfSk7XG4gICAqXG4gICAqIEBwYXJhbSBwcm9wcyBTdGFuZGFyZCBjb25maWd1cmF0aW9uIHByb3BlcnRpZXNcbiAgICogQHJldHVybnMgUm91dGVyT3V0cHV0Q29uZmlndXJhdGlvbiBpbnN0YW5jZSBmb3Igc3RhbmRhcmQgc2V0dXBcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgc3RhbmRhcmQocHJvcHM6IFN0YW5kYXJkT3V0cHV0Q29uZmlndXJhdGlvblByb3BzKTogUm91dGVyT3V0cHV0Q29uZmlndXJhdGlvbiB7XG4gICAgcmV0dXJuIG5ldyBTdGFuZGFyZFJvdXRlck91dHB1dENvbmZpZyhwcm9wcyk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgTWVkaWFMaXZlIFJvdXRlciBPdXRwdXQgY29uZmlndXJhdGlvbiB3aXRoIGEgc3BlY2lmaWMgaW5wdXQgY29ubmVjdGlvbi5cbiAgICpcbiAgICogVXNlIHRoaXMgd2hlbiB0aGUgTWVkaWFMaXZlIGlucHV0IGFscmVhZHkgZXhpc3RzIGFuZCB5b3Ugd2FudCB0byBjb25uZWN0IGltbWVkaWF0ZWx5LlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKlxuICAgKiAgICBSb3V0ZXJPdXRwdXRDb25maWd1cmF0aW9uLm1lZGlhTGl2ZUlucHV0KHtcbiAgICogICAgICBtZWRpYUxpdmVJbnB1dEFybjogJ2Fybjphd3M6bWVkaWFsaXZlOnVzLWVhc3QtMToxMjM0NTY3ODkwMTI6aW5wdXQ6MTIzNDU2NycsXG4gICAqICAgICAgbWVkaWFMaXZlUGlwZWxpbmVJZDogTWVkaWFMaXZlUGlwZWxpbmUuUElQRUxJTkVfMCxcbiAgICogICAgfSk7XG4gICAqXG4gICAqIEBwYXJhbSBwcm9wcyBNZWRpYUxpdmUgaW5wdXQgY29ubmVjdGlvbiBwcm9wZXJ0aWVzXG4gICAqIEByZXR1cm5zIFJvdXRlck91dHB1dENvbmZpZ3VyYXRpb24gaW5zdGFuY2UgZm9yIE1lZGlhTGl2ZSBzZXR1cCB3aXRoIGlucHV0IGNvbm5lY3Rpb25cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgbWVkaWFMaXZlSW5wdXQocHJvcHM6IE1lZGlhTGl2ZUlucHV0Q29ubmVjdGlvblByb3BzKTogUm91dGVyT3V0cHV0Q29uZmlndXJhdGlvbiB7XG4gICAgcmV0dXJuIG5ldyBNZWRpYUxpdmVJbnB1dFJvdXRlck91dHB1dENvbmZpZyh7XG4gICAgICBtZWRpYUxpdmVJbnB1dEFybjogcHJvcHMubWVkaWFMaXZlSW5wdXRBcm4sXG4gICAgICBtZWRpYUxpdmVQaXBlbGluZUlkOiBwcm9wcy5tZWRpYUxpdmVQaXBlbGluZUlkLFxuICAgICAgZGVzdGluYXRpb25UcmFuc2l0RW5jcnlwdGlvbjogcHJvcHMuZGVzdGluYXRpb25UcmFuc2l0RW5jcnlwdGlvbixcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBNZWRpYUxpdmUgUm91dGVyIE91dHB1dCBjb25maWd1cmF0aW9uIHdpdGhvdXQgYSBzcGVjaWZpYyBpbnB1dCBjb25uZWN0aW9uLlxuICAgKlxuICAgKiBVc2UgdGhpcyB3aGVuIHlvdSB3YW50IHRvIHNldCB1cCB0aGUgcm91dGVyIG91dHB1dCBiZWZvcmUgdGhlIE1lZGlhTGl2ZSBpbnB1dCBleGlzdHMuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqXG4gICAqICAgIFJvdXRlck91dHB1dENvbmZpZ3VyYXRpb24ubWVkaWFMaXZlSW5wdXRXaXRob3V0Q29ubmVjdGlvbih7XG4gICAqICAgICAgYXZhaWxhYmlsaXR5Wm9uZTogJ3VzLWVhc3QtMWEnLFxuICAgKiAgICB9KTtcbiAgICpcbiAgICogQHBhcmFtIHByb3BzIE1lZGlhTGl2ZSBubyBpbnB1dCBjb25uZWN0aW9uIHByb3BlcnRpZXNcbiAgICogQHJldHVybnMgUm91dGVyT3V0cHV0Q29uZmlndXJhdGlvbiBpbnN0YW5jZSBmb3IgTWVkaWFMaXZlIHNldHVwIHdpdGhvdXQgaW5wdXQgY29ubmVjdGlvblxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBtZWRpYUxpdmVJbnB1dFdpdGhvdXRDb25uZWN0aW9uKHByb3BzOiBNZWRpYUxpdmVOb0lucHV0Q29ubmVjdGlvblByb3BzKTogUm91dGVyT3V0cHV0Q29uZmlndXJhdGlvbiB7XG4gICAgcmV0dXJuIG5ldyBNZWRpYUxpdmVJbnB1dFJvdXRlck91dHB1dENvbmZpZyhcbiAgICAgIHsgZGVzdGluYXRpb25UcmFuc2l0RW5jcnlwdGlvbjogcHJvcHMuZGVzdGluYXRpb25UcmFuc2l0RW5jcnlwdGlvbiB9LFxuICAgICAgcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIE1lZGlhQ29ubmVjdCBGbG93IFJvdXRlciBPdXRwdXQgY29uZmlndXJhdGlvbiB3aXRoIGEgc3BlY2lmaWMgZmxvdyBjb25uZWN0aW9uLlxuICAgKlxuICAgKiBVc2UgdGhpcyB3aGVuIHRoZSB0YXJnZXQgZmxvdyBhbHJlYWR5IGV4aXN0cyBhbmQgeW91IHdhbnQgdG8gY29ubmVjdCBpbW1lZGlhdGVseS5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICpcbiAgICogICAgZGVjbGFyZSBjb25zdCBmbG93OiBGbG93O1xuICAgKlxuICAgKiAgICBSb3V0ZXJPdXRwdXRDb25maWd1cmF0aW9uLm1lZGlhQ29ubmVjdEZsb3coe1xuICAgKiAgICAgIGZsb3csXG4gICAqICAgIH0pO1xuICAgKlxuICAgKiBAcGFyYW0gcHJvcHMgTWVkaWFDb25uZWN0IEZsb3cgY29ubmVjdGlvbiBwcm9wZXJ0aWVzXG4gICAqIEByZXR1cm5zIFJvdXRlck91dHB1dENvbmZpZ3VyYXRpb24gaW5zdGFuY2UgZm9yIE1lZGlhQ29ubmVjdCBGbG93IHNldHVwIHdpdGggZmxvdyBjb25uZWN0aW9uXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIG1lZGlhQ29ubmVjdEZsb3cocHJvcHM6IE1lZGlhQ29ubmVjdEZsb3dDb25uZWN0aW9uUHJvcHMpOiBSb3V0ZXJPdXRwdXRDb25maWd1cmF0aW9uIHtcbiAgICByZXR1cm4gbmV3IE1lZGlhQ29ubmVjdEZsb3dSb3V0ZXJPdXRwdXRDb25maWcoe1xuICAgICAgZmxvdzogcHJvcHMuZmxvdyxcbiAgICAgIGRlc3RpbmF0aW9uVHJhbnNpdEVuY3J5cHRpb246IHByb3BzLmRlc3RpbmF0aW9uVHJhbnNpdEVuY3J5cHRpb24sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgTWVkaWFDb25uZWN0IEZsb3cgUm91dGVyIE91dHB1dCBjb25maWd1cmF0aW9uIHdpdGhvdXQgYSBzcGVjaWZpYyBmbG93IGNvbm5lY3Rpb24uXG4gICAqXG4gICAqIFVzZSB0aGlzIHdoZW4geW91IHdhbnQgdG8gc2V0IHVwIHRoZSByb3V0ZXIgb3V0cHV0IGJlZm9yZSB0aGUgdGFyZ2V0IGZsb3cgZXhpc3RzLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKlxuICAgKiAgICBSb3V0ZXJPdXRwdXRDb25maWd1cmF0aW9uLm1lZGlhQ29ubmVjdEZsb3dXaXRob3V0Q29ubmVjdGlvbih7XG4gICAqICAgICAgYXZhaWxhYmlsaXR5Wm9uZTogJ3VzLWVhc3QtMWEnLFxuICAgKiAgICB9KTtcbiAgICpcbiAgICogQHBhcmFtIHByb3BzIE1lZGlhQ29ubmVjdCBGbG93IG5vIGNvbm5lY3Rpb24gcHJvcGVydGllc1xuICAgKiBAcmV0dXJucyBSb3V0ZXJPdXRwdXRDb25maWd1cmF0aW9uIGluc3RhbmNlIGZvciBNZWRpYUNvbm5lY3QgRmxvdyBzZXR1cCB3aXRob3V0IGZsb3cgY29ubmVjdGlvblxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBtZWRpYUNvbm5lY3RGbG93V2l0aG91dENvbm5lY3Rpb24ocHJvcHM6IE1lZGlhQ29ubmVjdEZsb3dOb0Nvbm5lY3Rpb25Qcm9wcyk6IFJvdXRlck91dHB1dENvbmZpZ3VyYXRpb24ge1xuICAgIHJldHVybiBuZXcgTWVkaWFDb25uZWN0Rmxvd1JvdXRlck91dHB1dENvbmZpZyhcbiAgICAgIHsgZGVzdGluYXRpb25UcmFuc2l0RW5jcnlwdGlvbjogcHJvcHMuZGVzdGluYXRpb25UcmFuc2l0RW5jcnlwdGlvbiB9LFxuICAgICAgcHJvcHMuYXZhaWxhYmlsaXR5Wm9uZSxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmUgdGhpcyBjb25maWd1cmF0aW9uIHRvIGl0cyBDbG91ZEZvcm1hdGlvbiBzaGFwZS4gQ2FsbGVkIGJ5IHRoZSBSb3V0ZXJPdXRwdXRcbiAgICogY29uc3RydWN0b3Ig4oCUIGVhY2ggY29uY3JldGUgc3ViY2xhc3Mgc3VwcGxpZXMgaXRzIG93biB2YXJpYW50LXNwZWNpZmljIHJlbmRlcmluZy5cbiAgICogQGludGVybmFsXG4gICAqL1xuICBwdWJsaWMgYWJzdHJhY3QgX2JpbmQoc2NvcGU6IENvbnN0cnVjdCwgcm91dGVyT3V0cHV0QXJuPzogc3RyaW5nKToge1xuICAgIGNvbmZpZzogQ2ZuUm91dGVyT3V0cHV0LlJvdXRlck91dHB1dENvbmZpZ3VyYXRpb25Qcm9wZXJ0eTsgYXZhaWxhYmlsaXR5Wm9uZT86IHN0cmluZzsgZ3JhbnQ/OiBHcmFudDtcbiAgfTtcbn1cblxuLyoqXG4gKiBDb25jcmV0ZSB2YXJpYW50OiBzdGFuZGFyZCAoc2luZ2xlLXByb3RvY29sKSByb3V0ZXIgb3V0cHV0IGNvbmZpZ3VyYXRpb24uXG4gKiBAaW50ZXJuYWxcbiAqL1xuY2xhc3MgU3RhbmRhcmRSb3V0ZXJPdXRwdXRDb25maWcgZXh0ZW5kcyBSb3V0ZXJPdXRwdXRDb25maWd1cmF0aW9uIHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBwcm9wczogU3RhbmRhcmRPdXRwdXRDb25maWd1cmF0aW9uUHJvcHMpIHsgc3VwZXIoKTsgfVxuXG4gIHB1YmxpYyBfYmluZChzY29wZTogQ29uc3RydWN0LCByb3V0ZXJPdXRwdXRBcm4/OiBzdHJpbmcpIHtcbiAgICBjb25zdCBwcm90b2NvbCA9IHRoaXMucHJvcHMucHJvdG9jb2wuX2JpbmQoc2NvcGUsIHJvdXRlck91dHB1dEFybik7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbmZpZzoge1xuICAgICAgICBzdGFuZGFyZDoge1xuICAgICAgICAgIG5ldHdvcmtJbnRlcmZhY2VBcm46IHRoaXMucHJvcHMubmV0d29ya0ludGVyZmFjZS5yb3V0ZXJOZXR3b3JrSW50ZXJmYWNlQXJuLFxuICAgICAgICAgIHByb3RvY29sOiBwcm90b2NvbC5uYW1lLnZhbHVlLFxuICAgICAgICAgIHByb3RvY29sQ29uZmlndXJhdGlvbjogcHJvdG9jb2wuY29uZmlnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGdyYW50OiBwcm90b2NvbC5ncmFudCxcbiAgICB9O1xuICB9XG59XG5cbi8qKlxuICogQ29uY3JldGUgdmFyaWFudDogTWVkaWFMaXZlIElucHV0IHJvdXRlciBvdXRwdXQgY29uZmlndXJhdGlvbiAod2l0aCBvciB3aXRob3V0IGNvbm5lY3Rpb24pLlxuICogQGludGVybmFsXG4gKi9cbmNsYXNzIE1lZGlhTGl2ZUlucHV0Um91dGVyT3V0cHV0Q29uZmlnIGV4dGVuZHMgUm91dGVyT3V0cHV0Q29uZmlndXJhdGlvbiB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgb3B0aW9uczogTWVkaWFMaXZlSW5wdXRSb3V0ZXJPdXRwdXRPcHRpb25zLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgYXZhaWxhYmlsaXR5Wm9uZT86IHN0cmluZyxcbiAgKSB7IHN1cGVyKCk7IH1cblxuICBwdWJsaWMgX2JpbmQoc2NvcGU6IENvbnN0cnVjdCwgcm91dGVyT3V0cHV0QXJuPzogc3RyaW5nKSB7XG4gICAgY29uc3QgdHJhbnNpdCA9IHJlc29sdmVUcmFuc2l0RW5jcnlwdGlvbihzY29wZSwgJ0Rlc3RpbmF0aW9uVHJhbnNpdEVuY3J5cHRpb25Sb2xlJywgdGhpcy5vcHRpb25zLmRlc3RpbmF0aW9uVHJhbnNpdEVuY3J5cHRpb24sIHJvdXRlck91dHB1dEFybik7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbmZpZzoge1xuICAgICAgICBtZWRpYUxpdmVJbnB1dDoge1xuICAgICAgICAgIG1lZGlhTGl2ZUlucHV0QXJuOiB0aGlzLm9wdGlvbnMubWVkaWFMaXZlSW5wdXRBcm4sXG4gICAgICAgICAgbWVkaWFMaXZlUGlwZWxpbmVJZDogdGhpcy5vcHRpb25zLm1lZGlhTGl2ZVBpcGVsaW5lSWQsXG4gICAgICAgICAgZGVzdGluYXRpb25UcmFuc2l0RW5jcnlwdGlvbjogdHJhbnNpdC5jb25maWcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgYXZhaWxhYmlsaXR5Wm9uZTogdGhpcy5hdmFpbGFiaWxpdHlab25lLFxuICAgICAgZ3JhbnQ6IHRyYW5zaXQuZ3JhbnQsXG4gICAgfTtcbiAgfVxufVxuXG4vKipcbiAqIEludGVybmFsIG9wdGlvbnMgZm9yIHtAbGluayBNZWRpYUxpdmVJbnB1dFJvdXRlck91dHB1dENvbmZpZ30uIE5vdCBleHBvcnRlZDsganNpaSBuZXZlciBzZWVzIHRoaXMuXG4gKi9cbmludGVyZmFjZSBNZWRpYUxpdmVJbnB1dFJvdXRlck91dHB1dE9wdGlvbnMge1xuICByZWFkb25seSBtZWRpYUxpdmVJbnB1dEFybj86IHN0cmluZztcbiAgcmVhZG9ubHkgbWVkaWFMaXZlUGlwZWxpbmVJZD86IE1lZGlhTGl2ZVBpcGVsaW5lO1xuICByZWFkb25seSBkZXN0aW5hdGlvblRyYW5zaXRFbmNyeXB0aW9uPzogVHJhbnNpdEVuY3J5cHRpb247XG59XG5cbi8qKlxuICogQ29uY3JldGUgdmFyaWFudDogTWVkaWFDb25uZWN0IEZsb3cgcm91dGVyIG91dHB1dCBjb25maWd1cmF0aW9uICh3aXRoIG9yIHdpdGhvdXQgY29ubmVjdGlvbikuXG4gKiBAaW50ZXJuYWxcbiAqL1xuY2xhc3MgTWVkaWFDb25uZWN0Rmxvd1JvdXRlck91dHB1dENvbmZpZyBleHRlbmRzIFJvdXRlck91dHB1dENvbmZpZ3VyYXRpb24ge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IG9wdGlvbnM6IE1lZGlhQ29ubmVjdEZsb3dSb3V0ZXJPdXRwdXRPcHRpb25zLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgYXZhaWxhYmlsaXR5Wm9uZT86IHN0cmluZyxcbiAgKSB7IHN1cGVyKCk7IH1cblxuICBwdWJsaWMgX2JpbmQoc2NvcGU6IENvbnN0cnVjdCwgcm91dGVyT3V0cHV0QXJuPzogc3RyaW5nKSB7XG4gICAgY29uc3QgdHJhbnNpdCA9IHJlc29sdmVUcmFuc2l0RW5jcnlwdGlvbihzY29wZSwgJ0Rlc3RpbmF0aW9uVHJhbnNpdEVuY3J5cHRpb25Sb2xlJywgdGhpcy5vcHRpb25zLmRlc3RpbmF0aW9uVHJhbnNpdEVuY3J5cHRpb24sIHJvdXRlck91dHB1dEFybik7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbmZpZzoge1xuICAgICAgICBtZWRpYUNvbm5lY3RGbG93OiB7XG4gICAgICAgICAgZmxvd0FybjogdGhpcy5vcHRpb25zLmZsb3c/LmZsb3dBcm4sXG4gICAgICAgICAgZmxvd1NvdXJjZUFybjogdGhpcy5vcHRpb25zLmZsb3c/LnNvdXJjZUFybixcbiAgICAgICAgICBkZXN0aW5hdGlvblRyYW5zaXRFbmNyeXB0aW9uOiB0cmFuc2l0LmNvbmZpZyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBhdmFpbGFiaWxpdHlab25lOiB0aGlzLmF2YWlsYWJpbGl0eVpvbmUsXG4gICAgICBncmFudDogdHJhbnNpdC5ncmFudCxcbiAgICB9O1xuICB9XG59XG5cbi8qKlxuICogSW50ZXJuYWwgb3B0aW9ucyBmb3Ige0BsaW5rIE1lZGlhQ29ubmVjdEZsb3dSb3V0ZXJPdXRwdXRDb25maWd9LiBOb3QgZXhwb3J0ZWQ7IGpzaWkgbmV2ZXIgc2VlcyB0aGlzLlxuICovXG5pbnRlcmZhY2UgTWVkaWFDb25uZWN0Rmxvd1JvdXRlck91dHB1dE9wdGlvbnMge1xuICByZWFkb25seSBmbG93PzogSUZsb3c7XG4gIHJlYWRvbmx5IGRlc3RpbmF0aW9uVHJhbnNpdEVuY3J5cHRpb24/OiBUcmFuc2l0RW5jcnlwdGlvbjtcbn1cblxuLyoqXG4gKiBBIE1lZGlhQ29ubmVjdCBSb3V0ZXIgT3V0cHV0IHRoYXQgc2VuZHMgbWVkaWEgc3RyZWFtcyB0byBkZXN0aW5hdGlvbnMuXG4gKlxuICogUm91dGVyIE91dHB1dHMgc3VwcG9ydCBtdWx0aXBsZSBjb25maWd1cmF0aW9uIHR5cGVzOlxuICogLSBTdGFuZGFyZDogU2luZ2xlIHByb3RvY29sIG91dHB1dFxuICogLSBNZWRpYUxpdmUgSW5wdXQ6IE91dHB1dCB0byBBV1MgRWxlbWVudGFsIE1lZGlhTGl2ZVxuICogLSBNZWRpYUNvbm5lY3QgRmxvdzogT3V0cHV0IHRvIGFub3RoZXIgTWVkaWFDb25uZWN0IEZsb3dcbiAqL1xuYWJzdHJhY3QgY2xhc3MgUm91dGVyT3V0cHV0QmFzZSBleHRlbmRzIFJlc291cmNlIGltcGxlbWVudHMgSVJvdXRlck91dHB1dCB7XG4gIHB1YmxpYyBhYnN0cmFjdCByZWFkb25seSByb3V0ZXJPdXRwdXRBcm46IHN0cmluZztcbiAgcHVibGljIGFic3RyYWN0IHJlYWRvbmx5IHJvdXRlck91dHB1dE5hbWU6IHN0cmluZztcbiAgcHVibGljIGFic3RyYWN0IHJlYWRvbmx5IHJvdXRlck91dHB1dElkOiBzdHJpbmc7XG4gIHB1YmxpYyBhYnN0cmFjdCByZWFkb25seSBpcEFkZHJlc3M6IHN0cmluZztcbiAgcHVibGljIGFic3RyYWN0IHJlYWRvbmx5IGNyZWF0ZWRBdD86IHN0cmluZztcbiAgcHVibGljIGFic3RyYWN0IHJlYWRvbmx5IHVwZGF0ZWRBdD86IHN0cmluZztcblxuICAvKipcbiAgICogQSByZWZlcmVuY2UgdG8gdGhpcyBSb3V0ZXIgT3V0cHV0IHJlc291cmNlLlxuICAgKiBSZXF1aXJlZCBieSB0aGUgYXV0by1nZW5lcmF0ZWQgSVJvdXRlck91dHB1dFJlZiBpbnRlcmZhY2UuXG4gICAqL1xuICBwdWJsaWMgZ2V0IHJvdXRlck91dHB1dFJlZigpOiBSb3V0ZXJPdXRwdXRSZWZlcmVuY2Uge1xuICAgIHJldHVybiB7IHJvdXRlck91dHB1dEFybjogdGhpcy5yb3V0ZXJPdXRwdXRBcm4gfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBDbG91ZFdhdGNoIG1ldHJpYyBmb3IgdGhpcyByb3V0ZXIgb3V0cHV0LlxuICAgKi9cbiAgcHVibGljIG1ldHJpYyhtZXRyaWNOYW1lOiBzdHJpbmcsIHByb3BzPzogTWV0cmljT3B0aW9ucyk6IE1ldHJpYyB7XG4gICAgcmV0dXJuIG5ldyBNZXRyaWMoe1xuICAgICAgbWV0cmljTmFtZSxcbiAgICAgIG5hbWVzcGFjZTogJ0FXUy9NZWRpYUNvbm5lY3QnLFxuICAgICAgLi4ucHJvcHMsXG4gICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgIFJvdXRlck91dHB1dEFSTjogdGhpcy5yb3V0ZXJPdXRwdXRBcm4sXG4gICAgICAgIC4uLnByb3BzPy5kaW1lbnNpb25zTWFwLFxuICAgICAgfSxcbiAgICB9KS5hdHRhY2hUbyh0aGlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRyaWMgZm9yIHRoZSBiaXRyYXRlIG9mIHRoZSByb3V0ZXIgb3V0cHV0J3MgcGF5bG9hZC5cbiAgICovXG4gIHB1YmxpYyBtZXRyaWNCaXRyYXRlKHByb3BzPzogTWV0cmljT3B0aW9ucyk6IE1ldHJpYyB7XG4gICAgcmV0dXJuIHRoaXMubWV0cmljKCdSb3V0ZXJPdXRwdXRCaXRSYXRlJywge1xuICAgICAgc3RhdGlzdGljOiAnYXZnJyxcbiAgICAgIHBlcmlvZDogRHVyYXRpb24uc2Vjb25kcyg2MCksXG4gICAgICB1bml0OiBVbml0LkJJVFNfUEVSX1NFQ09ORCxcbiAgICAgIC4uLnByb3BzLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldHJpYyBmb3IgdGhlIHRvdGFsIG51bWJlciBvZiBwYWNrZXRzIHNlbnQgYnkgdGhlIHJvdXRlciBvdXRwdXQuXG4gICAqL1xuICBwdWJsaWMgbWV0cmljVG90YWxQYWNrZXRzKHByb3BzPzogTWV0cmljT3B0aW9ucyk6IE1ldHJpYyB7XG4gICAgcmV0dXJuIHRoaXMubWV0cmljKCdSb3V0ZXJPdXRwdXRUb3RhbFBhY2tldHMnLCB7XG4gICAgICBzdGF0aXN0aWM6ICdzdW0nLFxuICAgICAgcGVyaW9kOiBEdXJhdGlvbi5zZWNvbmRzKDYwKSxcbiAgICAgIHVuaXQ6IFVuaXQuQ09VTlQsXG4gICAgICAuLi5wcm9wcyxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRyaWMgZm9yIHRoZSByb3V0ZXIgb3V0cHV0IGNvbm5lY3Rpb24gc3RhdGUgKDEgY29ubmVjdGVkLCAwIGRpc2Nvbm5lY3RlZCkuIEFwcGxpZXMgdG8gU1JUIG91dHB1dHMgb25seS5cbiAgICovXG4gIHB1YmxpYyBtZXRyaWNDb25uZWN0ZWQocHJvcHM/OiBNZXRyaWNPcHRpb25zKTogTWV0cmljIHtcbiAgICByZXR1cm4gdGhpcy5tZXRyaWMoJ1JvdXRlck91dHB1dENvbm5lY3RlZCcsIHtcbiAgICAgIHN0YXRpc3RpYzogJ21pbicsXG4gICAgICBwZXJpb2Q6IER1cmF0aW9uLnNlY29uZHMoNjApLFxuICAgICAgdW5pdDogVW5pdC5OT05FLFxuICAgICAgLi4ucHJvcHMsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogTWV0cmljIGZvciB0aGUgbnVtYmVyIG9mIHJldHJhbnNtaXR0ZWQgcGFja2V0cyByZXF1ZXN0ZWQgdGhyb3VnaCBBUlEuIEFwcGxpZXMgdG8gUklTVCBhbmQgU1JUIG91dHB1dHMuXG4gICAqL1xuICBwdWJsaWMgbWV0cmljQXJxUmVxdWVzdHMocHJvcHM/OiBNZXRyaWNPcHRpb25zKTogTWV0cmljIHtcbiAgICByZXR1cm4gdGhpcy5tZXRyaWMoJ1JvdXRlck91dHB1dEFSUVJlcXVlc3RzJywge1xuICAgICAgc3RhdGlzdGljOiAnc3VtJyxcbiAgICAgIHBlcmlvZDogRHVyYXRpb24uc2Vjb25kcyg2MCksXG4gICAgICB1bml0OiBVbml0LkNPVU5ULFxuICAgICAgLi4ucHJvcHMsXG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBEZWZpbmVzIGFuIEFXUyBFbGVtZW50YWwgTWVkaWFDb25uZWN0IFJvdXRlciBPdXRwdXQuXG4gKi9cbkBwcm9wZXJ0eUluamVjdGFibGVcbmV4cG9ydCBjbGFzcyBSb3V0ZXJPdXRwdXQgZXh0ZW5kcyBSb3V0ZXJPdXRwdXRCYXNlIGltcGxlbWVudHMgSVJvdXRlck91dHB1dCB7XG4gIC8qKiBVbmlxdWVseSBpZGVudGlmaWVzIHRoaXMgY2xhc3MuICovXG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgUFJPUEVSVFlfSU5KRUNUSU9OX0lEOiBzdHJpbmcgPSAnQGF3cy1jZGsuYXdzLW1lZGlhY29ubmVjdC1hbHBoYS5Sb3V0ZXJPdXRwdXQnO1xuXG4gIC8qKlxuICAgKiBJbXBvcnQgYW4gZXhpc3RpbmcgUm91dGVyIE91dHB1dCBmcm9tIGl0cyBBUk4uXG4gICAqXG4gICAqIFRoZSBBUk4gb25seSBjb250YWlucyB0aGUgc2VydmljZS1nZW5lcmF0ZWQgSUQgKG5vdCB0aGUgcm91dGVyIG91dHB1dCBuYW1lKS4gQWNjZXNzaW5nXG4gICAqIGByb3V0ZXJPdXRwdXROYW1lYCBvbiBhbiBBUk4gaW1wb3J0IHRocm93cyDigJQgdXNlIGBmcm9tUm91dGVyT3V0cHV0QXR0cmlidXRlcygpYCB0byBwcm92aWRlXG4gICAqIHRoZSBuYW1lIGV4cGxpY2l0bHkuXG4gICAqXG4gICAqIEBwYXJhbSBzY29wZSBUaGUgcGFyZW50IGNvbnN0cnVjdFxuICAgKiBAcGFyYW0gaWQgVGhlIGNvbnN0cnVjdCBpZFxuICAgKiBAcGFyYW0gcm91dGVyT3V0cHV0QXJuIFRoZSBBUk4gb2YgdGhlIFJvdXRlciBPdXRwdXRcbiAgICogQHJldHVybnMgQSBSb3V0ZXIgT3V0cHV0IGNvbnN0cnVjdFxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBmcm9tUm91dGVyT3V0cHV0QXJuKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHJvdXRlck91dHB1dEFybjogc3RyaW5nKTogSVJvdXRlck91dHB1dCB7XG4gICAgcmV0dXJuIFJvdXRlck91dHB1dC5mcm9tUm91dGVyT3V0cHV0QXR0cmlidXRlcyhzY29wZSwgaWQsIHsgcm91dGVyT3V0cHV0QXJuIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEltcG9ydCBhbiBleGlzdGluZyBSb3V0ZXIgT3V0cHV0IGZyb20gYXR0cmlidXRlcy5cbiAgICpcbiAgICogVXNlIHRoaXMgd2hlbiB5b3UgbmVlZCB0byByZWZlcmVuY2UgYSByb3V0ZXIgb3V0cHV0IGJ5IG5hbWUuXG4gICAqXG4gICAqIEBwYXJhbSBzY29wZSBUaGUgcGFyZW50IGNvbnN0cnVjdFxuICAgKiBAcGFyYW0gaWQgVGhlIGNvbnN0cnVjdCBpZFxuICAgKiBAcGFyYW0gYXR0cnMgVGhlIFJvdXRlciBPdXRwdXQgYXR0cmlidXRlc1xuICAgKiBAcmV0dXJucyBBIFJvdXRlciBPdXRwdXQgY29uc3RydWN0XG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGZyb21Sb3V0ZXJPdXRwdXRBdHRyaWJ1dGVzKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIGF0dHJzOiBSb3V0ZXJPdXRwdXRBdHRyaWJ1dGVzKTogSVJvdXRlck91dHB1dCB7XG4gICAgLy8gRGVyaXZlIHRoZSBJRCBmcm9tIHRoZSBBUk4gdXNpbmcgQ0ZOIGludHJpbnNpY3Mgc28gdGhpcyB3b3JrcyB3aXRoIHRva2VuIEFSTnMgdG9vLlxuICAgIC8vIFRoZSBBUk4gZm9ybWF0IGlzIGFybjphd3M6bWVkaWFjb25uZWN0OjxyZWdpb24+OjxhY2NvdW50Pjpyb3V0ZXJPdXRwdXQ6PGlkPiwgc28gdGhlXG4gICAgLy8gcmVzb3VyY2UgbmFtZSBpcyB0aGUgSUQuXG4gICAgY29uc3Qgcm91dGVyT3V0cHV0SWQgPSBhdHRycy5yb3V0ZXJPdXRwdXRJZCA/PyBleHRyYWN0Um91dGVyT3V0cHV0SWQoYXR0cnMucm91dGVyT3V0cHV0QXJuKTtcblxuICAgIGNsYXNzIEltcG9ydCBleHRlbmRzIFJvdXRlck91dHB1dEJhc2UgaW1wbGVtZW50cyBJUm91dGVyT3V0cHV0IHtcbiAgICAgIHB1YmxpYyByZWFkb25seSByb3V0ZXJPdXRwdXRBcm4gPSBhdHRycy5yb3V0ZXJPdXRwdXRBcm47XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgcm91dGVyT3V0cHV0SWQgPSByb3V0ZXJPdXRwdXRJZDtcbiAgICAgIHB1YmxpYyByZWFkb25seSBjcmVhdGVkQXQgPSB1bmRlZmluZWQ7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgdXBkYXRlZEF0ID0gdW5kZWZpbmVkO1xuXG4gICAgICBwdWJsaWMgZ2V0IHJvdXRlck91dHB1dE5hbWUoKTogc3RyaW5nIHtcbiAgICAgICAgaWYgKGF0dHJzLnJvdXRlck91dHB1dE5hbWUpIHJldHVybiBhdHRycy5yb3V0ZXJPdXRwdXROYW1lO1xuICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKFxuICAgICAgICAgIGxpdGBSb3V0ZXJPdXRwdXROYW1lTm90UHJvdmlkZWRgLFxuICAgICAgICAgIGAncm91dGVyT3V0cHV0TmFtZScgd2FzIG5vdCBwcm92aWRlZCB3aGVuIGltcG9ydGluZyBSb3V0ZXJPdXRwdXQgJHt0aGlzLm5vZGUucGF0aH07IHByb3ZpZGUgaXQgaW4gZnJvbVJvdXRlck91dHB1dEF0dHJpYnV0ZXMoKWAsXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgcHVibGljIGdldCBpcEFkZHJlc3MoKTogc3RyaW5nIHtcbiAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihcbiAgICAgICAgICBsaXRgUm91dGVyT3V0cHV0SXBBZGRyZXNzTm90UHJvdmlkZWRgLFxuICAgICAgICAgIGAnaXBBZGRyZXNzJyBpcyBub3QgYXZhaWxhYmxlIG9uIGltcG9ydGVkIFJvdXRlck91dHB1dCAke3RoaXMubm9kZS5wYXRofWAsXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG5ldyBJbXBvcnQoc2NvcGUsIGlkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBtYXhpbXVtIGJpdHJhdGUgaW4gTWJwcyBmb3IgYSBrbm93biB0aWVyLCBvciB1bmRlZmluZWQgZm9yIGN1c3RvbSB0aWVycy5cbiAgICovXG4gIHByaXZhdGUgc3RhdGljIHRpZXJMaW1pdE1icHModGllcjogUm91dGVyT3V0cHV0VGllcik6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHRpZXIudmFsdWUgPT09IFJvdXRlck91dHB1dFRpZXIuT1VUUFVUXzIwLnZhbHVlKSByZXR1cm4gMjA7XG4gICAgaWYgKHRpZXIudmFsdWUgPT09IFJvdXRlck91dHB1dFRpZXIuT1VUUFVUXzUwLnZhbHVlKSByZXR1cm4gNTA7XG4gICAgaWYgKHRpZXIudmFsdWUgPT09IFJvdXRlck91dHB1dFRpZXIuT1VUUFVUXzEwMC52YWx1ZSkgcmV0dXJuIDEwMDtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgcHVibGljIHJlYWRvbmx5IHJvdXRlck91dHB1dEFybjogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgcm91dGVyT3V0cHV0TmFtZTogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgcm91dGVyT3V0cHV0SWQ6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IGlwQWRkcmVzczogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgY3JlYXRlZEF0Pzogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgdXBkYXRlZEF0Pzogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBSb3V0ZXJPdXRwdXRQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCwge1xuICAgICAgcGh5c2ljYWxOYW1lOiBwcm9wcy5yb3V0ZXJPdXRwdXROYW1lID8/IExhenkuc3RyaW5nKHsgcHJvZHVjZTogKCkgPT4gTmFtZXMudW5pcXVlUmVzb3VyY2VOYW1lKHRoaXMsIHsgbWF4TGVuZ3RoOiAxMjggfSkgfSksXG4gICAgfSk7XG5cbiAgICAvLyBWYWxpZGF0ZSByb3V0ZXIgb3V0cHV0IG5hbWUgaWYgcHJvdmlkZWRcbiAgICBpZiAocHJvcHMucm91dGVyT3V0cHV0TmFtZSAhPSBudWxsICYmIHByb3BzLnJvdXRlck91dHB1dE5hbWUgIT09ICcnICYmICFUb2tlbi5pc1VucmVzb2x2ZWQocHJvcHMucm91dGVyT3V0cHV0TmFtZSkpIHtcbiAgICAgIGlmIChwcm9wcy5yb3V0ZXJPdXRwdXROYW1lLmxlbmd0aCA+IDEyOCkge1xuICAgICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKGxpdGBSb3V0ZXJPdXRwdXROYW1lTGVuZ3RoYCwgYFJvdXRlciBvdXRwdXQgbmFtZSBtdXN0IGJlIGJldHdlZW4gMSBhbmQgMTI4IGNoYXJhY3RlcnMsIGdvdCAke3Byb3BzLnJvdXRlck91dHB1dE5hbWUubGVuZ3RofWAsIHRoaXMpO1xuICAgICAgfVxuICAgICAgaWYgKCEvXlthLXpBLVowLTktXSskLy50ZXN0KHByb3BzLnJvdXRlck91dHB1dE5hbWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IobGl0YFJvdXRlck91dHB1dE5hbWVGb3JtYXRgLCBgUm91dGVyIG91dHB1dCBuYW1lIG11c3QgY29udGFpbiBvbmx5IGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIGFuZCBoeXBoZW5zLCBnb3QgJyR7cHJvcHMucm91dGVyT3V0cHV0TmFtZX0nYCwgdGhpcyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgbWF4aW11bSBiaXRyYXRlXG4gICAgaWYgKCFwcm9wcy5tYXhpbXVtQml0cmF0ZS5pc1VucmVzb2x2ZWQoKSAmJiBwcm9wcy5tYXhpbXVtQml0cmF0ZS50b0JwcygpIDwgMTAwMDAwMCkge1xuICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihsaXRgUm91dGVyT3V0cHV0TWluQml0cmF0ZWAsIGBNYXhpbXVtIGJpdHJhdGUgbXVzdCBiZSBhdCBsZWFzdCAxLDAwMCwwMDAgYml0cy9zICgxIE1icHMpLCBnb3QgJHtwcm9wcy5tYXhpbXVtQml0cmF0ZS50b0JwcygpfWAsIHRoaXMpO1xuICAgIH1cblxuICAgIC8vIFZhbGlkYXRlIGJpdHJhdGUgZG9lcyBub3QgZXhjZWVkIHRpZXIgbGltaXRcbiAgICBjb25zdCByZXNvbHZlZFRpZXIgPSBwcm9wcy50aWVyID8/IFJvdXRlck91dHB1dFRpZXIuT1VUUFVUXzIwO1xuICAgIGNvbnN0IHRpZXJNYnBzID0gUm91dGVyT3V0cHV0LnRpZXJMaW1pdE1icHMocmVzb2x2ZWRUaWVyKTtcbiAgICBpZiAoZXhjZWVkc1JvdXRlclRpZXJCaXRyYXRlKHRpZXJNYnBzLCBwcm9wcy5tYXhpbXVtQml0cmF0ZSkpIHtcbiAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IobGl0YFJvdXRlck91dHB1dEJpdHJhdGVFeGNlZWRzVGllcmAsIGBNYXhpbXVtIGJpdHJhdGUgJHtwcm9wcy5tYXhpbXVtQml0cmF0ZS50b0JwcygpIC8gMV8wMDBfMDAwfSBNYnBzIGV4Y2VlZHMgdGhlICR7cmVzb2x2ZWRUaWVyLnZhbHVlfSB0aWVyIGxpbWl0IG9mICR7dGllck1icHN9IE1icHNgLCB0aGlzKTtcbiAgICB9XG5cbiAgICAvLyBWYWxpZGF0ZSBtYWludGVuYW5jZSB0aW1lIGZvcm1hdFxuICAgIGlmIChwcm9wcy5tYWludGVuYW5jZUNvbmZpZ3VyYXRpb24pIHtcbiAgICAgIHZhbGlkYXRlTWFpbnRlbmFuY2VUaW1lKHByb3BzLm1haW50ZW5hbmNlQ29uZmlndXJhdGlvbi50aW1lKTtcbiAgICB9XG5cbiAgICAvLyBFbmhhbmNlZCBDREsgQW5hbHl0aWNzIFRlbGVtZXRyeVxuICAgIGFkZENvbnN0cnVjdE1ldGFkYXRhKHRoaXMsIHByb3BzKTtcblxuICAgIGNvbnN0IHN0YWNrID0gU3RhY2sub2YodGhpcyk7XG4gICAgY29uc3QgdGFyZ2V0UmVnaW9uID0gcHJvcHMucmVnaW9uTmFtZSA/PyBzdGFjay5yZWdpb247XG5cbiAgICAvLyBXaWxkY2FyZCB0aGUgaWQg4oCUIHBpbm5pbmcgdGhlIGxpdmUgQVJOIChhdHRyQXJuKSB3b3VsZCBjcmVhdGUgYSByb2xlIOKGkiByb3V0ZXItb3V0cHV0IOKGkiByb2xlIGN5Y2xlLlxuICAgIGNvbnN0IHJvdXRlck91dHB1dEFybiA9IHN0YWNrLmZvcm1hdEFybih7XG4gICAgICBzZXJ2aWNlOiAnbWVkaWFjb25uZWN0JyxcbiAgICAgIHJlZ2lvbjogdGFyZ2V0UmVnaW9uLFxuICAgICAgcmVzb3VyY2U6ICdyb3V0ZXJPdXRwdXQnLFxuICAgICAgcmVzb3VyY2VOYW1lOiAnKicsXG4gICAgICBhcm5Gb3JtYXQ6IEFybkZvcm1hdC5DT0xPTl9SRVNPVVJDRV9OQU1FLFxuICAgIH0pO1xuXG4gICAgY29uc3QgY29uZmlnQmluZCA9IHByb3BzLmNvbmZpZ3VyYXRpb24uX2JpbmQodGhpcywgcm91dGVyT3V0cHV0QXJuKTtcblxuICAgIC8vIENoZWNrIHRvIHNlZSBpZiByZWdpb24gc3BlY2lmaWVkIGlzIGFsc28gY29tcGF0aWJsZSB3aXRoIEFaIGNvbmZpZ3VyZWQgZm9yIHNvbWUgb2YgdGhlIFJvdXRlciBPdXRwdXRzIGNvbmZpZ3VyYXRpb25zXG4gICAgaWYgKGNvbmZpZ0JpbmQuYXZhaWxhYmlsaXR5Wm9uZSAmJiAhY29uZmlnQmluZC5hdmFpbGFiaWxpdHlab25lLnN0YXJ0c1dpdGgodGFyZ2V0UmVnaW9uKSkge1xuICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihsaXRgUm91dGVyT3V0cHV0QXpSZWdpb25NaXNtYXRjaGAsIGBBdmFpbGFiaWxpdHkgem9uZSAnJHtjb25maWdCaW5kLmF2YWlsYWJpbGl0eVpvbmV9JyBtdXN0IGJlIHdpdGhpbiByZWdpb24gJyR7dGFyZ2V0UmVnaW9ufSdgLCB0aGlzKTtcbiAgICB9XG5cbiAgICBjb25zdCByb3V0ZXJPdXRwdXQgPSBuZXcgQ2ZuUm91dGVyT3V0cHV0KHRoaXMsICdSZXNvdXJjZScsIHtcbiAgICAgIG5hbWU6IHRoaXMucGh5c2ljYWxOYW1lLFxuICAgICAgbWF4aW11bUJpdHJhdGU6IHByb3BzLm1heGltdW1CaXRyYXRlLnRvQnBzKCksXG4gICAgICByb3V0aW5nU2NvcGU6IHByb3BzLnJvdXRpbmdTY29wZS52YWx1ZSxcbiAgICAgIHRpZXI6IChwcm9wcy50aWVyID8/IFJvdXRlck91dHB1dFRpZXIuT1VUUFVUXzIwKS52YWx1ZSxcbiAgICAgIGF2YWlsYWJpbGl0eVpvbmU6IGNvbmZpZ0JpbmQuYXZhaWxhYmlsaXR5Wm9uZSwgLy8gT25seSBzcGVjaWZpZWQgZm9yIE1lZGlhQ29ubmVjdCBGbG93IGFuZCBNZWRpYUxpdmUgaW5wdXRzICh3aXRoIG5vIGNvbm5lY3Rpb24pLlxuICAgICAgbWFpbnRlbmFuY2VDb25maWd1cmF0aW9uOiBwcm9wcy5tYWludGVuYW5jZUNvbmZpZ3VyYXRpb24gPyB7XG4gICAgICAgIHByZWZlcnJlZERheVRpbWU6IHByb3BzLm1haW50ZW5hbmNlQ29uZmlndXJhdGlvbixcbiAgICAgIH0gOiB7XG4gICAgICAgIGRlZmF1bHQ6IHt9LFxuICAgICAgfSxcbiAgICAgIGNvbmZpZ3VyYXRpb246IGNvbmZpZ0JpbmQuY29uZmlnLFxuICAgICAgcmVnaW9uTmFtZTogdGFyZ2V0UmVnaW9uLFxuICAgICAgdGFnczogcHJvcHMudGFncyA/IHJlbmRlclRhZ3MocHJvcHMudGFncykgOiB1bmRlZmluZWQsXG4gICAgfSk7XG5cbiAgICB0aGlzLnJvdXRlck91dHB1dEFybiA9IHJvdXRlck91dHB1dC5hdHRyQXJuO1xuICAgIHRoaXMucm91dGVyT3V0cHV0TmFtZSA9IHRoaXMucGh5c2ljYWxOYW1lO1xuICAgIHRoaXMucm91dGVyT3V0cHV0SWQgPSByb3V0ZXJPdXRwdXQuYXR0cklkO1xuICAgIHRoaXMuaXBBZGRyZXNzID0gcm91dGVyT3V0cHV0LmF0dHJJcEFkZHJlc3M7XG4gICAgdGhpcy5jcmVhdGVkQXQgPSByb3V0ZXJPdXRwdXQuYXR0ckNyZWF0ZWRBdDtcbiAgICB0aGlzLnVwZGF0ZWRBdCA9IHJvdXRlck91dHB1dC5hdHRyVXBkYXRlZEF0O1xuXG4gICAgLy8gV2l0aG91dCB0aGlzIHRoZSByb3V0ZXIgaW5wdXQgY2FuIGJlIGNyZWF0ZWQgYmVmb3JlIHRoZVxuICAgIC8vIHBvbGljeSBpcyBhdHRhY2hlZCAoXCJhY2Nlc3MgZGVuaWVkXCIgYXQgY3JlYXRlIHRpbWUpLiBPcmRlcmluZyB0aGUgZ3JhbnQgYmVmb3JlIHRoZVxuICAgIC8vIHJvdXRlciBpbnB1dCBwdWxscyB0aGUgcG9saWN5IGluIGFzIGEgZGVwZW5kZW5jeS5cbiAgICBjb25maWdCaW5kLmdyYW50Py5hcHBseUJlZm9yZShyb3V0ZXJPdXRwdXQpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGV4dHJhY3RSb3V0ZXJPdXRwdXRJZChyb3V0ZXJPdXRwdXRBcm46IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHBhcnNlZCA9IEFybi5zcGxpdChyb3V0ZXJPdXRwdXRBcm4sIEFybkZvcm1hdC5DT0xPTl9SRVNPVVJDRV9OQU1FKS5yZXNvdXJjZU5hbWU7XG4gIGlmIChwYXJzZWQgPT09IHVuZGVmaW5lZCkge1xuICAgIHRocm93IG5ldyBVbnNjb3BlZFZhbGlkYXRpb25FcnJvcihcbiAgICAgIGxpdGBJbnZhbGlkUm91dGVyT3V0cHV0QXJuYCxcbiAgICAgIGBDb3VsZCBub3QgcGFyc2UgUm91dGVyIE91dHB1dCBBUk46ICR7cm91dGVyT3V0cHV0QXJufS4gRXhwZWN0ZWQgZm9ybWF0OiBhcm46PHBhcnRpdGlvbj46bWVkaWFjb25uZWN0OjxyZWdpb24+OjxhY2NvdW50Pjpyb3V0ZXJPdXRwdXQ6PGlkPmAsXG4gICAgKTtcbiAgfVxuICByZXR1cm4gcGFyc2VkO1xufVxuIl19