awscdk-construct-mediaconnect-flow 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.jsii +4351 -0
- package/API.md +343 -0
- package/LICENSE +19 -0
- package/README.md +75 -0
- package/lib/LiveFeedFromFile.d.ts +29 -0
- package/lib/LiveFeedFromFile.js +300 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +18 -0
- package/package.json +134 -0
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.LiveFeedFromFile = void 0;
|
|
5
|
+
exports.startFlow = startFlow;
|
|
6
|
+
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
|
7
|
+
const crypto = require("crypto");
|
|
8
|
+
const cdk = require("aws-cdk-lib");
|
|
9
|
+
const ec2 = require("aws-cdk-lib/aws-ec2");
|
|
10
|
+
const iam = require("aws-cdk-lib/aws-iam");
|
|
11
|
+
const aws_mediaconnect_1 = require("aws-cdk-lib/aws-mediaconnect");
|
|
12
|
+
const asm = require("aws-cdk-lib/aws-secretsmanager");
|
|
13
|
+
const custom_resources_1 = require("aws-cdk-lib/custom-resources");
|
|
14
|
+
const awscdk_construct_medialive_channel_1 = require("awscdk-construct-medialive-channel");
|
|
15
|
+
const constructs_1 = require("constructs");
|
|
16
|
+
const sourceIngestPort = 5000;
|
|
17
|
+
const discoveryServerPort = 5959;
|
|
18
|
+
const VPC_INTERFACE_NAME = 'vpcInterfaceName';
|
|
19
|
+
class LiveFeedFromFile extends constructs_1.Construct {
|
|
20
|
+
constructor(scope, id, props) {
|
|
21
|
+
super(scope, id);
|
|
22
|
+
const { file, source = {
|
|
23
|
+
protocol: 'SRT',
|
|
24
|
+
type: 'STANDARD-SOURCE',
|
|
25
|
+
}, vpcConfig, autoStart = true, } = props;
|
|
26
|
+
const uuid = `${crypto.randomUUID()}`;
|
|
27
|
+
const protocol = (() => {
|
|
28
|
+
switch (source.protocol) {
|
|
29
|
+
case 'RTP':
|
|
30
|
+
return 'rtp';
|
|
31
|
+
case 'RTP-FEC':
|
|
32
|
+
return 'rtp-fec';
|
|
33
|
+
case 'SRT':
|
|
34
|
+
default:
|
|
35
|
+
return 'srt-listener';
|
|
36
|
+
}
|
|
37
|
+
})();
|
|
38
|
+
// Create a VPC
|
|
39
|
+
const vpc = vpcConfig ? new ec2.Vpc(this, 'VPC', vpcConfig.props) : undefined;
|
|
40
|
+
vpc && vpc.applyRemovalPolicy(cdk.RemovalPolicy.DESTROY);
|
|
41
|
+
// Allocate an Elastic IP for the VPC interface
|
|
42
|
+
const eip = vpc ? new ec2.CfnEIP(this, 'EIP', {
|
|
43
|
+
domain: 'vpc', // Ensure the EIP is allocated in the VPC
|
|
44
|
+
}) : undefined;
|
|
45
|
+
// Create a security group to allow push input
|
|
46
|
+
const description = 'Allow Push input from MediaLive';
|
|
47
|
+
const sg = vpc ? new ec2.SecurityGroup(this, 'SecurityGroup', {
|
|
48
|
+
vpc,
|
|
49
|
+
description,
|
|
50
|
+
allowAllOutbound: true,
|
|
51
|
+
}) : undefined;
|
|
52
|
+
sg && sg.applyRemovalPolicy(cdk.RemovalPolicy.DESTROY);
|
|
53
|
+
sg && sg.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.udp(sourceIngestPort), description);
|
|
54
|
+
// Create an NDI discovery server
|
|
55
|
+
let ndiConfig;
|
|
56
|
+
if (vpc && vpcConfig?.enableNDI) {
|
|
57
|
+
const instance = createNdiDiscoveryServer(this, vpc);
|
|
58
|
+
ndiConfig = {
|
|
59
|
+
ndiDiscoveryServers: [{
|
|
60
|
+
discoveryServerAddress: instance.instancePrivateIp, // Use the private IP of the NDI Discovery Server
|
|
61
|
+
vpcInterfaceAdapter: VPC_INTERFACE_NAME,
|
|
62
|
+
discoveryServerPort,
|
|
63
|
+
}],
|
|
64
|
+
ndiState: 'ENABLED',
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
// Create a secret
|
|
68
|
+
const randomstring = Math.random().toString(36).slice(-8);
|
|
69
|
+
const sourcePassword = new asm.Secret(this, 'SourcePassword', {
|
|
70
|
+
secretName: `secret-${uuid}`,
|
|
71
|
+
generateSecretString: {
|
|
72
|
+
secretStringTemplate: JSON.stringify({ password: randomstring }),
|
|
73
|
+
generateStringKey: 'password',
|
|
74
|
+
excludePunctuation: true,
|
|
75
|
+
},
|
|
76
|
+
removalPolicy: cdk.RemovalPolicy.DESTROY,
|
|
77
|
+
});
|
|
78
|
+
// Create an IAM role for MediaConnect to access the VPC
|
|
79
|
+
const role = new iam.Role(this, 'MediaConnectRole', {
|
|
80
|
+
assumedBy: new iam.ServicePrincipal('mediaconnect.amazonaws.com'),
|
|
81
|
+
inlinePolicies: {
|
|
82
|
+
policy: new iam.PolicyDocument({
|
|
83
|
+
statements: [
|
|
84
|
+
new iam.PolicyStatement({
|
|
85
|
+
resources: [sourcePassword.secretArn],
|
|
86
|
+
actions: [
|
|
87
|
+
'secretsmanager:GetResourcePolicy',
|
|
88
|
+
'secretsmanager:GetSecretValue',
|
|
89
|
+
'secretsmanager:DescribeSecret',
|
|
90
|
+
'secretsmanager:ListSecretVersionIds',
|
|
91
|
+
],
|
|
92
|
+
}),
|
|
93
|
+
],
|
|
94
|
+
}),
|
|
95
|
+
},
|
|
96
|
+
managedPolicies: [
|
|
97
|
+
iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonVPCFullAccess'),
|
|
98
|
+
],
|
|
99
|
+
});
|
|
100
|
+
// Create a MediaConnect flow
|
|
101
|
+
const flow = new aws_mediaconnect_1.CfnFlow(this, 'MyCfnFlow', {
|
|
102
|
+
name: `lcp-demo-${uuid}`,
|
|
103
|
+
source: {
|
|
104
|
+
name: `lcp-demo-source-${uuid}`,
|
|
105
|
+
protocol,
|
|
106
|
+
// maxLatency: 2000,
|
|
107
|
+
// minLatency: 1000,
|
|
108
|
+
// vpcInterfaceName: VPC_INTERFACE_NAME,
|
|
109
|
+
whitelistCidr: source.type === 'STANDARD-SOURCE' ? '0.0.0.0/0' : undefined,
|
|
110
|
+
decryption: {
|
|
111
|
+
// algorithm: 'aes128',
|
|
112
|
+
roleArn: role.roleArn,
|
|
113
|
+
secretArn: sourcePassword.secretArn,
|
|
114
|
+
},
|
|
115
|
+
// sourceIngestPort: `${sourceIngestPort}`,
|
|
116
|
+
vpcInterfaceName: source.type === 'VPC-SOURCE' ? VPC_INTERFACE_NAME : undefined,
|
|
117
|
+
},
|
|
118
|
+
availabilityZone: vpcConfig?.availabilityZone ?? vpc?.availabilityZones[0],
|
|
119
|
+
flowSize: vpcConfig?.enableNDI ? 'LARGE' : 'MEDIUM',
|
|
120
|
+
ndiConfig,
|
|
121
|
+
sourceMonitoringConfig: {
|
|
122
|
+
thumbnailState: 'ENABLED',
|
|
123
|
+
contentQualityAnalysisState: 'ENABLED',
|
|
124
|
+
},
|
|
125
|
+
vpcInterfaces: vpc ? [{
|
|
126
|
+
name: VPC_INTERFACE_NAME,
|
|
127
|
+
roleArn: role.roleArn,
|
|
128
|
+
securityGroupIds: [sg.securityGroupId],
|
|
129
|
+
subnetId: vpcConfig?.subnetId ?? vpc.privateSubnets[0].subnetId,
|
|
130
|
+
}] : [],
|
|
131
|
+
});
|
|
132
|
+
flow.applyRemovalPolicy(cdk.RemovalPolicy.DESTROY);
|
|
133
|
+
// Start the MediaConnect Flow
|
|
134
|
+
autoStart && startFlow(this, 'StartMediaConnectFlow', flow.attrFlowArn);
|
|
135
|
+
// Create MediaLive channel
|
|
136
|
+
const eml = new awscdk_construct_medialive_channel_1.MediaLive(this, 'MediaLive', {
|
|
137
|
+
sources: [{ url: file.url.replace('s3://', 's3ssl://'), type: file.type ?? 'MP4_FILE' }],
|
|
138
|
+
destinations: [{
|
|
139
|
+
id: 'SRT',
|
|
140
|
+
srtSettings: [{
|
|
141
|
+
url: `srt://${flow.attrSourceIngestIp}:${flow.attrSourceSourceIngestPort}`, // Use the MediaConnect Flow URL
|
|
142
|
+
encryptionPassphraseSecretArn: sourcePassword.secretArn,
|
|
143
|
+
}],
|
|
144
|
+
}],
|
|
145
|
+
channelClass: 'SINGLE_PIPELINE',
|
|
146
|
+
encoderSpec: {
|
|
147
|
+
outputGroupSettingsList: [{
|
|
148
|
+
srtGroupSettings: {
|
|
149
|
+
inputLossAction: 'DROP_TS',
|
|
150
|
+
},
|
|
151
|
+
}],
|
|
152
|
+
outputSettingsList: [{
|
|
153
|
+
// Add valid OutputSettingsProperty fields here if needed
|
|
154
|
+
srtOutputSettings: {
|
|
155
|
+
latency: 2000, // Latency in milliseconds
|
|
156
|
+
destination: {
|
|
157
|
+
destinationRefId: 'SRT',
|
|
158
|
+
},
|
|
159
|
+
encryptionType: 'AES128', // Encryption type
|
|
160
|
+
containerSettings: {
|
|
161
|
+
m2TsSettings: {},
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
}],
|
|
165
|
+
gopLengthInSeconds: 2, // The length of the GOP in seconds.
|
|
166
|
+
timecodeBurninPrefix: 'Ch', // The prefix for the timecode burn-in.
|
|
167
|
+
},
|
|
168
|
+
vpc: source.type === 'VPC-SOURCE' && vpc ? {
|
|
169
|
+
publicAddressAllocationIds: [eip.attrAllocationId],
|
|
170
|
+
subnetIds: [vpc.privateSubnets[0].subnetId],
|
|
171
|
+
securityGroupIds: [sg.securityGroupId],
|
|
172
|
+
} : undefined,
|
|
173
|
+
secret: sourcePassword,
|
|
174
|
+
});
|
|
175
|
+
// Start the MediaLive channel
|
|
176
|
+
autoStart && (0, awscdk_construct_medialive_channel_1.startChannel)(this, 'StartMediaLiveChannel', eml.channel.ref);
|
|
177
|
+
this.flow = flow;
|
|
178
|
+
this.vpc = vpc;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
exports.LiveFeedFromFile = LiveFeedFromFile;
|
|
182
|
+
_a = JSII_RTTI_SYMBOL_1;
|
|
183
|
+
LiveFeedFromFile[_a] = { fqn: "awscdk-construct-mediaconnect-flow.LiveFeedFromFile", version: "0.0.0" };
|
|
184
|
+
function createNdiDiscoveryServer(scope, vpc) {
|
|
185
|
+
const description = 'Allow NDI Discovery Service';
|
|
186
|
+
const sg = new ec2.SecurityGroup(scope, 'NDISecurityGroup', {
|
|
187
|
+
vpc,
|
|
188
|
+
description,
|
|
189
|
+
allowAllOutbound: true,
|
|
190
|
+
});
|
|
191
|
+
sg.applyRemovalPolicy(cdk.RemovalPolicy.DESTROY);
|
|
192
|
+
sg.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(discoveryServerPort), description);
|
|
193
|
+
const instance = new ec2.Instance(scope, 'Instance', {
|
|
194
|
+
vpc,
|
|
195
|
+
instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE3, ec2.InstanceSize.MICRO),
|
|
196
|
+
machineImage: ec2.MachineImage.latestAmazonLinux2023(),
|
|
197
|
+
vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS },
|
|
198
|
+
securityGroup: sg,
|
|
199
|
+
});
|
|
200
|
+
instance.applyRemovalPolicy(cdk.RemovalPolicy.DESTROY);
|
|
201
|
+
// Get the CloudFormation logical ID for the instance
|
|
202
|
+
const cfnInstance = instance.node.defaultChild;
|
|
203
|
+
const logicalId = cfnInstance.logicalId;
|
|
204
|
+
instance.applyCloudFormationInit(ec2.CloudFormationInit.fromConfigSets({
|
|
205
|
+
configSets: {
|
|
206
|
+
// Applies the configs below in this order
|
|
207
|
+
default: ['configInstance', 'finalize'],
|
|
208
|
+
},
|
|
209
|
+
configs: {
|
|
210
|
+
configInstance: new ec2.InitConfig([
|
|
211
|
+
// NDI Discovery Service script
|
|
212
|
+
ec2.InitFile.fromString('/etc/systemd/ndi-discovery.service', `[Unit]
|
|
213
|
+
Description=NDI Discovery Service
|
|
214
|
+
|
|
215
|
+
[Service]
|
|
216
|
+
ExecStartPre=/bin/sleep 30
|
|
217
|
+
User=ec2-user
|
|
218
|
+
WorkingDirectory=/home/ec2-user/bin/x86_64-linux-gnu
|
|
219
|
+
ExecStart=/home/ec2-user/bin/x86_64-linux-gnu/ndi-discovery-server
|
|
220
|
+
Restart=always
|
|
221
|
+
|
|
222
|
+
[Install]
|
|
223
|
+
WantedBy=multi-user.target
|
|
224
|
+
`),
|
|
225
|
+
// NDI Discovery Server Installation script
|
|
226
|
+
ec2.InitFile.fromString('/tmp/install-ndi-discovery.sh', `#!/bin/bash -xe
|
|
227
|
+
cd /home/ec2-user
|
|
228
|
+
|
|
229
|
+
#Install updates
|
|
230
|
+
yum update -y
|
|
231
|
+
|
|
232
|
+
#Download the NDI Linux SDK and extract it and run the install script
|
|
233
|
+
wget https://downloads.ndi.tv/SDK/NDI_SDK_Linux/Install_NDI_SDK_v6_Linux.tar.gz
|
|
234
|
+
tar -xzf Install_NDI_SDK_v6_Linux.tar.gz
|
|
235
|
+
yes | sudo ./Install_NDI_SDK_v6_Linux.sh
|
|
236
|
+
|
|
237
|
+
#Clean up and prepare directories
|
|
238
|
+
rm -f Install_NDI_SDK_v6_Linux.tar.gz
|
|
239
|
+
rm -f Install_NDI_SDK_v6_Linux.sh
|
|
240
|
+
cp -r 'NDI SDK for Linux'/* ./
|
|
241
|
+
rm -r 'NDI SDK for Linux'/
|
|
242
|
+
`),
|
|
243
|
+
// Install the NDI Discovery Service
|
|
244
|
+
ec2.InitCommand.shellCommand('sudo bash /tmp/install-ndi-discovery.sh'),
|
|
245
|
+
// Run the NDI Discovery Service
|
|
246
|
+
ec2.InitCommand.shellCommand('sudo systemctl enable /etc/systemd/ndi-discovery.service'),
|
|
247
|
+
]),
|
|
248
|
+
finalize: new ec2.InitConfig([
|
|
249
|
+
// Start the NDI Discovery Service
|
|
250
|
+
ec2.InitCommand.shellCommand(cdk.Fn.sub('/opt/aws/bin/cfn-signal -e $? --stack ${StackName} --resource ${Resource} --region ${Region}', {
|
|
251
|
+
StackName: cdk.Aws.STACK_NAME,
|
|
252
|
+
Resource: logicalId,
|
|
253
|
+
Region: cdk.Aws.REGION,
|
|
254
|
+
})),
|
|
255
|
+
]),
|
|
256
|
+
},
|
|
257
|
+
}));
|
|
258
|
+
instance.addUserData(cdk.Fn.sub(`
|
|
259
|
+
#!/bin/bash -xe
|
|
260
|
+
yum install -y aws-cfn-bootstrap
|
|
261
|
+
sudo /opt/aws/bin/cfn-init --configsets default -v --stack \${StackName} --resource \${Resource} --region \${Region}
|
|
262
|
+
sudo reboot
|
|
263
|
+
`, {
|
|
264
|
+
StackName: cdk.Aws.STACK_NAME,
|
|
265
|
+
Resource: logicalId,
|
|
266
|
+
Region: cdk.Aws.REGION,
|
|
267
|
+
}));
|
|
268
|
+
return instance;
|
|
269
|
+
}
|
|
270
|
+
function startFlow(scope, id, flowArn) {
|
|
271
|
+
// Start channel
|
|
272
|
+
new custom_resources_1.AwsCustomResource(scope, id, {
|
|
273
|
+
onCreate: {
|
|
274
|
+
service: 'MediaConnect',
|
|
275
|
+
action: 'StartFlow',
|
|
276
|
+
parameters: {
|
|
277
|
+
FlowArn: flowArn,
|
|
278
|
+
},
|
|
279
|
+
physicalResourceId: custom_resources_1.PhysicalResourceId.of(`${crypto.randomUUID()}`),
|
|
280
|
+
// ignoreErrorCodesMatching: '*',
|
|
281
|
+
outputPaths: ['FlowArn', 'Status'],
|
|
282
|
+
},
|
|
283
|
+
onDelete: {
|
|
284
|
+
service: 'MediaConnect',
|
|
285
|
+
action: 'StopFlow',
|
|
286
|
+
parameters: {
|
|
287
|
+
FlowArn: flowArn,
|
|
288
|
+
},
|
|
289
|
+
physicalResourceId: custom_resources_1.PhysicalResourceId.of(`${crypto.randomUUID()}`),
|
|
290
|
+
// ignoreErrorCodesMatching: '*',
|
|
291
|
+
outputPaths: ['FlowArn', 'Status'],
|
|
292
|
+
},
|
|
293
|
+
//Will ignore any resource and use the assumedRoleArn as resource and 'sts:AssumeRole' for service:action
|
|
294
|
+
policy: custom_resources_1.AwsCustomResourcePolicy.fromSdkCalls({
|
|
295
|
+
resources: custom_resources_1.AwsCustomResourcePolicy.ANY_RESOURCE,
|
|
296
|
+
}),
|
|
297
|
+
});
|
|
298
|
+
return new Date();
|
|
299
|
+
}
|
|
300
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTGl2ZUZlZWRGcm9tRmlsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9MaXZlRmVlZEZyb21GaWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFvVUEsOEJBNkJDOztBQWpXRCxpQ0FBaUM7QUFDakMsbUNBQW1DO0FBQ25DLDJDQUEyQztBQUMzQywyQ0FBMkM7QUFDM0MsbUVBQXVEO0FBQ3ZELHNEQUFzRDtBQUN0RCxtRUFBOEc7QUFDOUcsMkZBQTZFO0FBQzdFLDJDQUF1QztBQTBCdkMsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7QUFDOUIsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLENBQUM7QUFDakMsTUFBTSxrQkFBa0IsR0FBRyxrQkFBa0IsQ0FBQztBQUU5QyxNQUFhLGdCQUFpQixTQUFRLHNCQUFTO0lBSTdDLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBNEI7UUFDcEUsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixNQUFNLEVBQ0osSUFBSSxFQUNKLE1BQU0sR0FBRztZQUNQLFFBQVEsRUFBRSxLQUFLO1lBQ2YsSUFBSSxFQUFFLGlCQUFpQjtTQUN4QixFQUNELFNBQVMsRUFDVCxTQUFTLEdBQUcsSUFBSSxHQUNqQixHQUFHLEtBQUssQ0FBQztRQUVWLE1BQU0sSUFBSSxHQUFHLEdBQUcsTUFBTSxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUM7UUFDdEMsTUFBTSxRQUFRLEdBQUcsQ0FBQyxHQUFHLEVBQUU7WUFDckIsUUFBUSxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ3hCLEtBQUssS0FBSztvQkFDUixPQUFPLEtBQUssQ0FBQztnQkFDZixLQUFLLFNBQVM7b0JBQ1osT0FBTyxTQUFTLENBQUM7Z0JBQ25CLEtBQUssS0FBSyxDQUFDO2dCQUNYO29CQUNFLE9BQU8sY0FBYyxDQUFDO1lBQzFCLENBQUM7UUFDSCxDQUFDLENBQUMsRUFBRSxDQUFDO1FBRUwsZUFBZTtR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QyxDQUFDLENBQUM7SUFDSixPQUFPLFFBQVEsQ0FBQztBQUNsQixDQUFDO0FBRUQsU0FBZ0IsU0FBUyxDQUFDLEtBQWdCLEVBQUUsRUFBVSxFQUFFLE9BQWU7SUFDckUsZ0JBQWdCO0lBQ2hCLElBQUksb0NBQWlCLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRTtRQUMvQixRQUFRLEVBQUU7WUFDUixPQUFPLEVBQUUsY0FBYztZQUN2QixNQUFNLEVBQUUsV0FBVztZQUNuQixVQUFVLEVBQUU7Z0JBQ1YsT0FBTyxFQUFFLE9BQU87YUFDakI7WUFDRCxrQkFBa0IsRUFBRSxxQ0FBa0IsQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQztZQUNuRSxpQ0FBaUM7WUFDakMsV0FBVyxFQUFFLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQztTQUNuQztRQUNELFFBQVEsRUFBRTtZQUNSLE9BQU8sRUFBRSxjQUFjO1lBQ3ZCLE1BQU0sRUFBRSxVQUFVO1lBQ2xCLFVBQVUsRUFBRTtnQkFDVixPQUFPLEVBQUUsT0FBTzthQUNqQjtZQUNELGtCQUFrQixFQUFFLHFDQUFrQixDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDO1lBQ25FLGlDQUFpQztZQUNqQyxXQUFXLEVBQUUsQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFDO1NBQ25DO1FBQ0QseUdBQXlHO1FBQ3pHLE1BQU0sRUFBRSwwQ0FBdUIsQ0FBQyxZQUFZLENBQUM7WUFDM0MsU0FBUyxFQUFFLDBDQUF1QixDQUFDLFlBQVk7U0FDaEQsQ0FBQztLQUNILENBQUMsQ0FBQztJQUNILE9BQU8sSUFBSSxJQUFJLEVBQUUsQ0FBQztBQUNwQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY3J5cHRvIGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgKiBhcyBjZGsgZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0ICogYXMgZWMyIGZyb20gJ2F3cy1jZGstbGliL2F3cy1lYzInO1xuaW1wb3J0ICogYXMgaWFtIGZyb20gJ2F3cy1jZGstbGliL2F3cy1pYW0nO1xuaW1wb3J0IHsgQ2ZuRmxvdyB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1tZWRpYWNvbm5lY3QnO1xuaW1wb3J0ICogYXMgYXNtIGZyb20gJ2F3cy1jZGstbGliL2F3cy1zZWNyZXRzbWFuYWdlcic7XG5pbXBvcnQgeyBBd3NDdXN0b21SZXNvdXJjZSwgQXdzQ3VzdG9tUmVzb3VyY2VQb2xpY3ksIFBoeXNpY2FsUmVzb3VyY2VJZCB9IGZyb20gJ2F3cy1jZGstbGliL2N1c3RvbS1yZXNvdXJjZXMnO1xuaW1wb3J0IHsgTWVkaWFMaXZlLCBzdGFydENoYW5uZWwgfSBmcm9tICdhd3NjZGstY29uc3RydWN0LW1lZGlhbGl2ZS1jaGFubmVsJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEZpbGVTcGVjIHtcbiAgcmVhZG9ubHkgdHlwZT86ICdNUDRfRklMRScgfCAnVFNfRklMRSc7IC8vIFR5cGUgb2YgdGhlIGlucHV0IGZpbGVcbiAgcmVhZG9ubHkgdXJsOiBzdHJpbmc7IC8vIFMzIFVSTCBvZiB0aGUgaW5wdXQgZmlsZVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIExpdmVTb3VyY2VTcGVjIHtcbiAgcmVhZG9ubHkgcHJvdG9jb2w6ICdSVFAnIHwgJ1JUUC1GRUMnIHwgJ1NSVCc7IC8vIFByb3RvY29sIG9mIHRoZSBsaXZlIHNvdXJjZVxuICByZWFkb25seSB0eXBlOiAnU1RBTkRBUkQtU09VUkNFJyB8ICdWUEMtU09VUkNFJzsgLy8gVHlwZSBvZiB0aGUgbGl2ZSBzb3VyY2Vcbn1cblxuZXhwb3J0IGludGVyZmFjZSBWcGNDb25maWcge1xuICByZWFkb25seSBwcm9wczogZWMyLlZwY1Byb3BzO1xuICByZWFkb25seSBhdmFpbGFiaWxpdHlab25lPzogc3RyaW5nO1xuICByZWFkb25seSBzdWJuZXRJZD86IHN0cmluZztcbiAgcmVhZG9ubHkgZW5hYmxlTkRJPzogYm9vbGVhbjsgLy8gU2V0dGluZ3MgZm9yIE5ESSBvdXRwdXRcbn1cblxuZXhwb3J0IGludGVyZmFjZSBMaXZlRmVlZEZyb21GaWxlUHJvcHMge1xuICByZWFkb25seSBmaWxlOiBGaWxlU3BlYzsgLy8gRmlsZSBzcGVjaWZpY2F0aW9uXG4gIHJlYWRvbmx5IHNvdXJjZT86IExpdmVTb3VyY2VTcGVjOyAvLyBPcHRpb25hbCBsaXZlIHNvdXJjZSBzcGVjaWZpY2F0aW9uXG4gIHJlYWRvbmx5IHZwY0NvbmZpZz86IFZwY0NvbmZpZzsgLy8gU2V0dGluZ3MgZm9yIFZQQy4gUmVxdWlyZWQgd2hlbiB0aGUgc291cmNlIHR5cGUgaXMgVlBDLVNPVVJDRSBhbmQvb3IgVlBDIG91dHB1dHMgd2lsbCBiZSBhZGRlZCB0byB0aGlzIGZsb3cuXG4gIHJlYWRvbmx5IGF1dG9TdGFydD86IGJvb2xlYW47IC8vIFdoZXRoZXIgdG8gYXV0b21hdGljYWxseSBzdGFydCB0aGUgTWVkaWFMaXZlIGNoYW5uZWwgYW5kIE1lZGlhQ29ubmVjdCBmbG93XG59XG5cbmNvbnN0IHNvdXJjZUluZ2VzdFBvcnQgPSA1MDAwO1xuY29uc3QgZGlzY292ZXJ5U2VydmVyUG9ydCA9IDU5NTk7XG5jb25zdCBWUENfSU5URVJGQUNFX05BTUUgPSAndnBjSW50ZXJmYWNlTmFtZSc7XG5cbmV4cG9ydCBjbGFzcyBMaXZlRmVlZEZyb21GaWxlIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgcHVibGljIHJlYWRvbmx5IGZsb3c6IENmbkZsb3c7XG4gIHB1YmxpYyByZWFkb25seSB2cGM/OiBlYzIuSVZwYztcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogTGl2ZUZlZWRGcm9tRmlsZVByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIGNvbnN0IHtcbiAgICAgIGZpbGUsXG4gICAgICBzb3VyY2UgPSB7XG4gICAgICAgIHByb3RvY29sOiAnU1JUJyxcbiAgICAgICAgdHlwZTogJ1NUQU5EQVJELVNPVVJDRScsXG4gICAgICB9LFxuICAgICAgdnBjQ29uZmlnLFxuICAgICAgYXV0b1N0YXJ0ID0gdHJ1ZSxcbiAgICB9ID0gcHJvcHM7XG5cbiAgICBjb25zdCB1dWlkID0gYCR7Y3J5cHRvLnJhbmRvbVVVSUQoKX1gO1xuICAgIGNvbnN0IHByb3RvY29sID0gKCgpID0+IHtcbiAgICAgIHN3aXRjaCAoc291cmNlLnByb3RvY29sKSB7XG4gICAgICAgIGNhc2UgJ1JUUCc6XG4gICAgICAgICAgcmV0dXJuICdydHAnO1xuICAgICAgICBjYXNlICdSVFAtRkVDJzpcbiAgICAgICAgICByZXR1cm4gJ3J0cC1mZWMnO1xuICAgICAgICBjYXNlICdTUlQnOlxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHJldHVybiAnc3J0LWxpc3RlbmVyJztcbiAgICAgIH1cbiAgICB9KSgpO1xuXG4gICAgLy8gQ3JlYXRlIGEgVlBDXG4gICAgY29uc3QgdnBjID0gdnBjQ29uZmlnID8gbmV3IGVjMi5WcGModGhpcywgJ1ZQQycsIHZwY0NvbmZpZy5wcm9wcykgOiB1bmRlZmluZWQ7XG4gICAgdnBjICYmIHZwYy5hcHBseVJlbW92YWxQb2xpY3koY2RrLlJlbW92YWxQb2xpY3kuREVTVFJPWSk7XG5cbiAgICAvLyBBbGxvY2F0ZSBhbiBFbGFzdGljIElQIGZvciB0aGUgVlBDIGludGVyZmFjZVxuICAgIGNvbnN0IGVpcCA9IHZwYyA/IG5ldyBlYzIuQ2ZuRUlQKHRoaXMsICdFSVAnLCB7XG4gICAgICBkb21haW46ICd2cGMnLCAvLyBFbnN1cmUgdGhlIEVJUCBpcyBhbGxvY2F0ZWQgaW4gdGhlIFZQQ1xuICAgIH0pIDogdW5kZWZpbmVkO1xuXG4gICAgLy8gQ3JlYXRlIGEgc2VjdXJpdHkgZ3JvdXAgdG8gYWxsb3cgcHVzaCBpbnB1dFxuICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gJ0FsbG93IFB1c2ggaW5wdXQgZnJvbSBNZWRpYUxpdmUnO1xuICAgIGNvbnN0IHNnID0gdnBjID8gbmV3IGVjMi5TZWN1cml0eUdyb3VwKHRoaXMsICdTZWN1cml0eUdyb3VwJywge1xuICAgICAgdnBjLFxuICAgICAgZGVzY3JpcHRpb24sXG4gICAgICBhbGxvd0FsbE91dGJvdW5kOiB0cnVlLFxuICAgIH0pOiB1bmRlZmluZWQ7XG4gICAgc2cgJiYgc2cuYXBwbHlSZW1vdmFsUG9saWN5KGNkay5SZW1vdmFsUG9saWN5LkRFU1RST1kpO1xuICAgIHNnICYmIHNnLmFkZEluZ3Jlc3NSdWxlKFxuICAgICAgZWMyLlBlZXIuYW55SXB2NCgpLFxuICAgICAgZWMyLlBvcnQudWRwKHNvdXJjZUluZ2VzdFBvcnQpLFxuICAgICAgZGVzY3JpcHRpb24sXG4gICAgKTtcblxuICAgIC8vIENyZWF0ZSBhbiBOREkgZGlzY292ZXJ5IHNlcnZlclxuICAgIGxldCBuZGlDb25maWc6IENmbkZsb3cuTmRpQ29uZmlnUHJvcGVydHkgfCB1bmRlZmluZWQ7XG4gICAgaWYgKHZwYyAmJiB2cGNDb25maWc/LmVuYWJsZU5ESSkge1xuICAgICAgY29uc3QgaW5zdGFuY2UgPSBjcmVhdGVOZGlEaXNjb3ZlcnlTZXJ2ZXIodGhpcywgdnBjKTtcbiAgICAgIG5kaUNvbmZpZyA9IHtcbiAgICAgICAgbmRpRGlzY292ZXJ5U2VydmVyczogW3tcbiAgICAgICAgICBkaXNjb3ZlcnlTZXJ2ZXJBZGRyZXNzOiBpbnN0YW5jZS5pbnN0YW5jZVByaXZhdGVJcCwgLy8gVXNlIHRoZSBwcml2YXRlIElQIG9mIHRoZSBOREkgRGlzY292ZXJ5IFNlcnZlclxuICAgICAgICAgIHZwY0ludGVyZmFjZUFkYXB0ZXI6IFZQQ19JTlRFUkZBQ0VfTkFNRSxcbiAgICAgICAgICBkaXNjb3ZlcnlTZXJ2ZXJQb3J0LFxuICAgICAgICB9XSxcbiAgICAgICAgbmRpU3RhdGU6ICdFTkFCTEVEJyxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gQ3JlYXRlIGEgc2VjcmV0XG4gICAgY29uc3QgcmFuZG9tc3RyaW5nID0gTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc2xpY2UoLTgpO1xuICAgIGNvbnN0IHNvdXJjZVBhc3N3b3JkID0gbmV3IGFzbS5TZWNyZXQodGhpcywgJ1NvdXJjZVBhc3N3b3JkJywge1xuICAgICAgc2VjcmV0TmFtZTogYHNlY3JldC0ke3V1aWR9YCxcbiAgICAgIGdlbmVyYXRlU2VjcmV0U3RyaW5nOiB7XG4gICAgICAgIHNlY3JldFN0cmluZ1RlbXBsYXRlOiBKU09OLnN0cmluZ2lmeSh7IHBhc3N3b3JkOiByYW5kb21zdHJpbmcgfSksXG4gICAgICAgIGdlbmVyYXRlU3RyaW5nS2V5OiAncGFzc3dvcmQnLFxuICAgICAgICBleGNsdWRlUHVuY3R1YXRpb246IHRydWUsXG4gICAgICB9LFxuICAgICAgcmVtb3ZhbFBvbGljeTogY2RrLlJlbW92YWxQb2xpY3kuREVTVFJPWSxcbiAgICB9KTtcblxuICAgIC8vIENyZWF0ZSBhbiBJQU0gcm9sZSBmb3IgTWVkaWFDb25uZWN0IHRvIGFjY2VzcyB0aGUgVlBDXG4gICAgY29uc3Qgcm9sZSA9IG5ldyBpYW0uUm9sZSh0aGlzLCAnTWVkaWFDb25uZWN0Um9sZScsIHtcbiAgICAgIGFzc3VtZWRCeTogbmV3IGlhbS5TZXJ2aWNlUHJpbmNpcGFsKCdtZWRpYWNvbm5lY3QuYW1hem9uYXdzLmNvbScpLFxuICAgICAgaW5saW5lUG9saWNpZXM6IHtcbiAgICAgICAgcG9saWN5OiBuZXcgaWFtLlBvbGljeURvY3VtZW50KHtcbiAgICAgICAgICBzdGF0ZW1lbnRzOiBbXG4gICAgICAgICAgICBuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgICAgICAgIHJlc291cmNlczogW3NvdXJjZVBhc3N3b3JkLnNlY3JldEFybl0sXG4gICAgICAgICAgICAgIGFjdGlvbnM6IFtcbiAgICAgICAgICAgICAgICAnc2VjcmV0c21hbmFnZXI6R2V0UmVzb3VyY2VQb2xpY3knLFxuICAgICAgICAgICAgICAgICdzZWNyZXRzbWFuYWdlcjpHZXRTZWNyZXRWYWx1ZScsXG4gICAgICAgICAgICAgICAgJ3NlY3JldHNtYW5hZ2VyOkRlc2NyaWJlU2VjcmV0JyxcbiAgICAgICAgICAgICAgICAnc2VjcmV0c21hbmFnZXI6TGlzdFNlY3JldFZlcnNpb25JZHMnLFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgXSxcbiAgICAgICAgfSksXG4gICAgICB9LFxuICAgICAgbWFuYWdlZFBvbGljaWVzOiBbXG4gICAgICAgIGlhbS5NYW5hZ2VkUG9saWN5LmZyb21Bd3NNYW5hZ2VkUG9saWN5TmFtZSgnQW1hem9uVlBDRnVsbEFjY2VzcycpLFxuICAgICAgXSxcbiAgICB9KTtcblxuICAgIC8vIENyZWF0ZSBhIE1lZGlhQ29ubmVjdCBmbG93XG4gICAgY29uc3QgZmxvdyA9IG5ldyBDZm5GbG93KHRoaXMsICdNeUNmbkZsb3cnLCB7XG4gICAgICBuYW1lOiBgbGNwLWRlbW8tJHt1dWlkfWAsXG4gICAgICBzb3VyY2U6IHtcbiAgICAgICAgbmFtZTogYGxjcC1kZW1vLXNvdXJjZS0ke3V1aWR9YCxcbiAgICAgICAgcHJvdG9jb2wsXG4gICAgICAgIC8vIG1heExhdGVuY3k6IDIwMDAsXG4gICAgICAgIC8vIG1pbkxhdGVuY3k6IDEwMDAsXG4gICAgICAgIC8vIHZwY0ludGVyZmFjZU5hbWU6IFZQQ19JTlRFUkZBQ0VfTkFNRSxcbiAgICAgICAgd2hpdGVsaXN0Q2lkcjogc291cmNlLnR5cGUgPT09ICdTVEFOREFSRC1TT1VSQ0UnID8gJzAuMC4wLjAvMCcgOiB1bmRlZmluZWQsXG4gICAgICAgIGRlY3J5cHRpb246IHtcbiAgICAgICAgICAvLyBhbGdvcml0aG06ICdhZXMxMjgnLFxuICAgICAgICAgIHJvbGVBcm46IHJvbGUucm9sZUFybixcbiAgICAgICAgICBzZWNyZXRBcm46IHNvdXJjZVBhc3N3b3JkLnNlY3JldEFybixcbiAgICAgICAgfSxcbiAgICAgICAgLy8gc291cmNlSW5nZXN0UG9ydDogYCR7c291cmNlSW5nZXN0UG9ydH1gLFxuICAgICAgICB2cGNJbnRlcmZhY2VOYW1lOiBzb3VyY2UudHlwZSA9PT0gJ1ZQQy1TT1VSQ0UnID8gVlBDX0lOVEVSRkFDRV9OQU1FIDogdW5kZWZpbmVkLFxuICAgICAgfSxcbiAgICAgIGF2YWlsYWJpbGl0eVpvbmU6IHZwY0NvbmZpZz8uYXZhaWxhYmlsaXR5Wm9uZSA/PyB2cGM/LmF2YWlsYWJpbGl0eVpvbmVzWzBdLFxuICAgICAgZmxvd1NpemU6IHZwY0NvbmZpZz8uZW5hYmxlTkRJID8gJ0xBUkdFJyA6ICdNRURJVU0nLFxuICAgICAgbmRpQ29uZmlnLFxuICAgICAgc291cmNlTW9uaXRvcmluZ0NvbmZpZzoge1xuICAgICAgICB0aHVtYm5haWxTdGF0ZTogJ0VOQUJMRUQnLFxuICAgICAgICBjb250ZW50UXVhbGl0eUFuYWx5c2lzU3RhdGU6ICdFTkFCTEVEJyxcbiAgICAgIH0sXG4gICAgICB2cGNJbnRlcmZhY2VzOiB2cGMgPyBbe1xuICAgICAgICBuYW1lOiBWUENfSU5URVJGQUNFX05BTUUsXG4gICAgICAgIHJvbGVBcm46IHJvbGUucm9sZUFybixcbiAgICAgICAgc2VjdXJpdHlHcm91cElkczogW3NnIS5zZWN1cml0eUdyb3VwSWRdLFxuICAgICAgICBzdWJuZXRJZDogdnBjQ29uZmlnPy5zdWJuZXRJZCA/PyB2cGMucHJpdmF0ZVN1Ym5ldHNbMF0uc3VibmV0SWQsXG4gICAgICB9XSA6IFtdLFxuICAgIH0pO1xuICAgIGZsb3cuYXBwbHlSZW1vdmFsUG9saWN5KGNkay5SZW1vdmFsUG9saWN5LkRFU1RST1kpO1xuXG4gICAgLy8gU3RhcnQgdGhlIE1lZGlhQ29ubmVjdCBGbG93XG4gICAgYXV0b1N0YXJ0ICYmIHN0YXJ0Rmxvdyh0aGlzLCAnU3RhcnRNZWRpYUNvbm5lY3RGbG93JywgZmxvdy5hdHRyRmxvd0Fybik7XG5cbiAgICAvLyBDcmVhdGUgTWVkaWFMaXZlIGNoYW5uZWxcbiAgICBjb25zdCBlbWwgPSBuZXcgTWVkaWFMaXZlKHRoaXMsICdNZWRpYUxpdmUnLCB7XG4gICAgICBzb3VyY2VzOiBbeyB1cmw6IGZpbGUudXJsLnJlcGxhY2UoJ3MzOi8vJywgJ3Mzc3NsOi8vJyksIHR5cGU6IGZpbGUudHlwZSA/PyAnTVA0X0ZJTEUnIH1dLFxuICAgICAgZGVzdGluYXRpb25zOiBbe1xuICAgICAgICBpZDogJ1NSVCcsXG4gICAgICAgIHNydFNldHRpbmdzOiBbe1xuICAgICAgICAgIHVybDogYHNydDovLyR7Zmxvdy5hdHRyU291cmNlSW5nZXN0SXB9OiR7Zmxvdy5hdHRyU291cmNlU291cmNlSW5nZXN0UG9ydH1gLCAvLyBVc2UgdGhlIE1lZGlhQ29ubmVjdCBGbG93IFVSTFxuICAgICAgICAgIGVuY3J5cHRpb25QYXNzcGhyYXNlU2VjcmV0QXJuOiBzb3VyY2VQYXNzd29yZC5zZWNyZXRBcm4sXG4gICAgICAgIH1dLFxuICAgICAgfV0sXG4gICAgICBjaGFubmVsQ2xhc3M6ICdTSU5HTEVfUElQRUxJTkUnLFxuICAgICAgZW5jb2RlclNwZWM6IHtcbiAgICAgICAgb3V0cHV0R3JvdXBTZXR0aW5nc0xpc3Q6IFt7XG4gICAgICAgICAgc3J0R3JvdXBTZXR0aW5nczoge1xuICAgICAgICAgICAgaW5wdXRMb3NzQWN0aW9uOiAnRFJPUF9UUycsXG4gICAgICAgICAgfSxcbiAgICAgICAgfV0sXG4gICAgICAgIG91dHB1dFNldHRpbmdzTGlzdDogW3tcbiAgICAgICAgICAvLyBBZGQgdmFsaWQgT3V0cHV0U2V0dGluZ3NQcm9wZXJ0eSBmaWVsZHMgaGVyZSBpZiBuZWVkZWRcbiAgICAgICAgICBzcnRPdXRwdXRTZXR0aW5nczoge1xuICAgICAgICAgICAgbGF0ZW5jeTogMjAwMCwgLy8gTGF0ZW5jeSBpbiBtaWxsaXNlY29uZHNcbiAgICAgICAgICAgIGRlc3RpbmF0aW9uOiB7XG4gICAgICAgICAgICAgIGRlc3RpbmF0aW9uUmVmSWQ6ICdTUlQnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGVuY3J5cHRpb25UeXBlOiAnQUVTMTI4JywgLy8gRW5jcnlwdGlvbiB0eXBlXG4gICAgICAgICAgICBjb250YWluZXJTZXR0aW5nczoge1xuICAgICAgICAgICAgICBtMlRzU2V0dGluZ3M6IHt9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9XSxcbiAgICAgICAgZ29wTGVuZ3RoSW5TZWNvbmRzOiAyLCAvLyBUaGUgbGVuZ3RoIG9mIHRoZSBHT1AgaW4gc2Vjb25kcy5cbiAgICAgICAgdGltZWNvZGVCdXJuaW5QcmVmaXg6ICdDaCcsIC8vIFRoZSBwcmVmaXggZm9yIHRoZSB0aW1lY29kZSBidXJuLWluLlxuICAgICAgfSxcbiAgICAgIHZwYzogc291cmNlLnR5cGUgPT09ICdWUEMtU09VUkNFJyAmJiB2cGMgPyB7XG4gICAgICAgIHB1YmxpY0FkZHJlc3NBbGxvY2F0aW9uSWRzOiBbZWlwIS5hdHRyQWxsb2NhdGlvbklkXSxcbiAgICAgICAgc3VibmV0SWRzOiBbdnBjLnByaXZhdGVTdWJuZXRzWzBdLnN1Ym5ldElkXSxcbiAgICAgICAgc2VjdXJpdHlHcm91cElkczogW3NnIS5zZWN1cml0eUdyb3VwSWRdLFxuICAgICAgfSA6IHVuZGVmaW5lZCxcbiAgICAgIHNlY3JldDogc291cmNlUGFzc3dvcmQsXG4gICAgfSk7XG5cbiAgICAvLyBTdGFydCB0aGUgTWVkaWFMaXZlIGNoYW5uZWxcbiAgICBhdXRvU3RhcnQgJiYgc3RhcnRDaGFubmVsKHRoaXMsICdTdGFydE1lZGlhTGl2ZUNoYW5uZWwnLCBlbWwuY2hhbm5lbC5yZWYpO1xuXG4gICAgdGhpcy5mbG93ID0gZmxvdztcbiAgICB0aGlzLnZwYyA9IHZwYztcbiAgfVxufVxuXG5mdW5jdGlvbiBjcmVhdGVOZGlEaXNjb3ZlcnlTZXJ2ZXIoc2NvcGU6IENvbnN0cnVjdCwgdnBjOiBlYzIuSVZwYyk6IGVjMi5JbnN0YW5jZSB7XG4gIGNvbnN0IGRlc2NyaXB0aW9uID0gJ0FsbG93IE5ESSBEaXNjb3ZlcnkgU2VydmljZSc7XG4gIGNvbnN0IHNnID0gbmV3IGVjMi5TZWN1cml0eUdyb3VwKHNjb3BlLCAnTkRJU2VjdXJpdHlHcm91cCcsIHtcbiAgICB2cGMsXG4gICAgZGVzY3JpcHRpb24sXG4gICAgYWxsb3dBbGxPdXRib3VuZDogdHJ1ZSxcbiAgfSk7XG4gIHNnLmFwcGx5UmVtb3ZhbFBvbGljeShjZGsuUmVtb3ZhbFBvbGljeS5ERVNUUk9ZKTtcbiAgc2cuYWRkSW5ncmVzc1J1bGUoXG4gICAgZWMyLlBlZXIuYW55SXB2NCgpLFxuICAgIGVjMi5Qb3J0LnRjcChkaXNjb3ZlcnlTZXJ2ZXJQb3J0KSxcbiAgICBkZXNjcmlwdGlvbixcbiAgKTtcbiAgY29uc3QgaW5zdGFuY2UgPSBuZXcgZWMyLkluc3RhbmNlKHNjb3BlLCAnSW5zdGFuY2UnLCB7XG4gICAgdnBjLFxuICAgIGluc3RhbmNlVHlwZTogZWMyLkluc3RhbmNlVHlwZS5vZihlYzIuSW5zdGFuY2VDbGFzcy5CVVJTVEFCTEUzLCBlYzIuSW5zdGFuY2VTaXplLk1JQ1JPKSxcbiAgICBtYWNoaW5lSW1hZ2U6IGVjMi5NYWNoaW5lSW1hZ2UubGF0ZXN0QW1hem9uTGludXgyMDIzKCksXG4gICAgdnBjU3VibmV0czogeyBzdWJuZXRUeXBlOiBlYzIuU3VibmV0VHlwZS5QUklWQVRFX1dJVEhfRUdSRVNTIH0sXG4gICAgc2VjdXJpdHlHcm91cDogc2csXG4gIH0pO1xuICBpbnN0YW5jZS5hcHBseVJlbW92YWxQb2xpY3koY2RrLlJlbW92YWxQb2xpY3kuREVTVFJPWSk7XG4gIC8vIEdldCB0aGUgQ2xvdWRGb3JtYXRpb24gbG9naWNhbCBJRCBmb3IgdGhlIGluc3RhbmNlXG4gIGNvbnN0IGNmbkluc3RhbmNlID0gaW5zdGFuY2Uubm9kZS5kZWZhdWx0Q2hpbGQgYXMgY2RrLkNmblJlc291cmNlO1xuICBjb25zdCBsb2dpY2FsSWQgPSBjZm5JbnN0YW5jZS5sb2dpY2FsSWQ7XG4gIGluc3RhbmNlLmFwcGx5Q2xvdWRGb3JtYXRpb25Jbml0KGVjMi5DbG91ZEZvcm1hdGlvbkluaXQuZnJvbUNvbmZpZ1NldHMoe1xuICAgIGNvbmZpZ1NldHM6IHtcbiAgICAgIC8vIEFwcGxpZXMgdGhlIGNvbmZpZ3MgYmVsb3cgaW4gdGhpcyBvcmRlclxuICAgICAgZGVmYXVsdDogWydjb25maWdJbnN0YW5jZScsICdmaW5hbGl6ZSddLFxuICAgIH0sXG4gICAgY29uZmlnczoge1xuICAgICAgY29uZmlnSW5zdGFuY2U6IG5ldyBlYzIuSW5pdENvbmZpZyhbXG4gICAgICAgIC8vIE5ESSBEaXNjb3ZlcnkgU2VydmljZSBzY3JpcHRcbiAgICAgICAgZWMyLkluaXRGaWxlLmZyb21TdHJpbmcoXG4gICAgICAgICAgJy9ldGMvc3lzdGVtZC9uZGktZGlzY292ZXJ5LnNlcnZpY2UnLFxuICAgICAgICAgIGBbVW5pdF1cbiAgICAgICAgICBEZXNjcmlwdGlvbj1OREkgRGlzY292ZXJ5IFNlcnZpY2VcbiAgICAgICAgICBcbiAgICAgICAgICBbU2VydmljZV1cbiAgICAgICAgICBFeGVjU3RhcnRQcmU9L2Jpbi9zbGVlcCAzMFxuICAgICAgICAgIFVzZXI9ZWMyLXVzZXJcbiAgICAgICAgICBXb3JraW5nRGlyZWN0b3J5PS9ob21lL2VjMi11c2VyL2Jpbi94ODZfNjQtbGludXgtZ251XG4gICAgICAgICAgRXhlY1N0YXJ0PS9ob21lL2VjMi11c2VyL2Jpbi94ODZfNjQtbGludXgtZ251L25kaS1kaXNjb3Zlcnktc2VydmVyXG4gICAgICAgICAgUmVzdGFydD1hbHdheXNcblxuICAgICAgICAgIFtJbnN0YWxsXVxuICAgICAgICAgIFdhbnRlZEJ5PW11bHRpLXVzZXIudGFyZ2V0XG4gICAgICAgIGApLFxuICAgICAgICAvLyBOREkgRGlzY292ZXJ5IFNlcnZlciBJbnN0YWxsYXRpb24gc2NyaXB0XG4gICAgICAgIGVjMi5Jbml0RmlsZS5mcm9tU3RyaW5nKFxuICAgICAgICAgICcvdG1wL2luc3RhbGwtbmRpLWRpc2NvdmVyeS5zaCcsXG4gICAgICAgICAgYCMhL2Jpbi9iYXNoIC14ZVxuICAgICAgICAgIGNkIC9ob21lL2VjMi11c2VyXG5cbiAgICAgICAgICAjSW5zdGFsbCB1cGRhdGVzXG4gICAgICAgICAgeXVtIHVwZGF0ZSAteVxuXG4gICAgICAgICAgI0Rvd25sb2FkIHRoZSBOREkgTGludXggU0RLIGFuZCBleHRyYWN0IGl0IGFuZCBydW4gdGhlIGluc3RhbGwgc2NyaXB0XG4gICAgICAgICAgd2dldCBodHRwczovL2Rvd25sb2Fkcy5uZGkudHYvU0RLL05ESV9TREtfTGludXgvSW5zdGFsbF9ORElfU0RLX3Y2X0xpbnV4LnRhci5nelxuICAgICAgICAgIHRhciAteHpmIEluc3RhbGxfTkRJX1NES192Nl9MaW51eC50YXIuZ3pcbiAgICAgICAgICB5ZXMgfCBzdWRvIC4vSW5zdGFsbF9ORElfU0RLX3Y2X0xpbnV4LnNoXG5cbiAgICAgICAgICAjQ2xlYW4gdXAgYW5kIHByZXBhcmUgZGlyZWN0b3JpZXNcbiAgICAgICAgICBybSAtZiBJbnN0YWxsX05ESV9TREtfdjZfTGludXgudGFyLmd6XG4gICAgICAgICAgcm0gLWYgSW5zdGFsbF9ORElfU0RLX3Y2X0xpbnV4LnNoXG4gICAgICAgICAgY3AgLXIgJ05ESSBTREsgZm9yIExpbnV4Jy8qIC4vXG4gICAgICAgICAgcm0gLXIgJ05ESSBTREsgZm9yIExpbnV4Jy9cbiAgICAgICAgYCksXG4gICAgICAgIC8vIEluc3RhbGwgdGhlIE5ESSBEaXNjb3ZlcnkgU2VydmljZVxuICAgICAgICBlYzIuSW5pdENvbW1hbmQuc2hlbGxDb21tYW5kKCdzdWRvIGJhc2ggL3RtcC9pbnN0YWxsLW5kaS1kaXNjb3Zlcnkuc2gnKSxcbiAgICAgICAgLy8gUnVuIHRoZSBOREkgRGlzY292ZXJ5IFNlcnZpY2VcbiAgICAgICAgZWMyLkluaXRDb21tYW5kLnNoZWxsQ29tbWFuZCgnc3VkbyBzeXN0ZW1jdGwgZW5hYmxlIC9ldGMvc3lzdGVtZC9uZGktZGlzY292ZXJ5LnNlcnZpY2UnKSxcbiAgICAgIF0pLFxuICAgICAgZmluYWxpemU6IG5ldyBlYzIuSW5pdENvbmZpZyhbXG4gICAgICAgIC8vIFN0YXJ0IHRoZSBOREkgRGlzY292ZXJ5IFNlcnZpY2VcbiAgICAgICAgZWMyLkluaXRDb21tYW5kLnNoZWxsQ29tbWFuZChcbiAgICAgICAgICBjZGsuRm4uc3ViKCcvb3B0L2F3cy9iaW4vY2ZuLXNpZ25hbCAtZSAkPyAtLXN0YWNrICR7U3RhY2tOYW1lfSAtLXJlc291cmNlICR7UmVzb3VyY2V9IC0tcmVnaW9uICR7UmVnaW9ufScsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIFN0YWNrTmFtZTogY2RrLkF3cy5TVEFDS19OQU1FLFxuICAgICAgICAgICAgICBSZXNvdXJjZTogbG9naWNhbElkLFxuICAgICAgICAgICAgICBSZWdpb246IGNkay5Bd3MuUkVHSU9OLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICksXG4gICAgICBdKSxcbiAgICB9LFxuICB9KSk7XG4gIGluc3RhbmNlLmFkZFVzZXJEYXRhKGNkay5Gbi5zdWIoYFxuICAgICMhL2Jpbi9iYXNoIC14ZVxuICAgIHl1bSBpbnN0YWxsIC15IGF3cy1jZm4tYm9vdHN0cmFwXG4gICAgc3VkbyAvb3B0L2F3cy9iaW4vY2ZuLWluaXQgLS1jb25maWdzZXRzIGRlZmF1bHQgLXYgLS1zdGFjayBcXCR7U3RhY2tOYW1lfSAtLXJlc291cmNlIFxcJHtSZXNvdXJjZX0gLS1yZWdpb24gXFwke1JlZ2lvbn1cbiAgICBzdWRvIHJlYm9vdFxuICBgLCB7XG4gICAgU3RhY2tOYW1lOiBjZGsuQXdzLlNUQUNLX05BTUUsXG4gICAgUmVzb3VyY2U6IGxvZ2ljYWxJZCxcbiAgICBSZWdpb246IGNkay5Bd3MuUkVHSU9OLFxuICB9KSk7XG4gIHJldHVybiBpbnN0YW5jZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHN0YXJ0RmxvdyhzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBmbG93QXJuOiBzdHJpbmcpOiBEYXRlIHtcbiAgLy8gU3RhcnQgY2hhbm5lbFxuICBuZXcgQXdzQ3VzdG9tUmVzb3VyY2Uoc2NvcGUsIGlkLCB7XG4gICAgb25DcmVhdGU6IHtcbiAgICAgIHNlcnZpY2U6ICdNZWRpYUNvbm5lY3QnLFxuICAgICAgYWN0aW9uOiAnU3RhcnRGbG93JyxcbiAgICAgIHBhcmFtZXRlcnM6IHtcbiAgICAgICAgRmxvd0FybjogZmxvd0FybixcbiAgICAgIH0sXG4gICAgICBwaHlzaWNhbFJlc291cmNlSWQ6IFBoeXNpY2FsUmVzb3VyY2VJZC5vZihgJHtjcnlwdG8ucmFuZG9tVVVJRCgpfWApLFxuICAgICAgLy8gaWdub3JlRXJyb3JDb2Rlc01hdGNoaW5nOiAnKicsXG4gICAgICBvdXRwdXRQYXRoczogWydGbG93QXJuJywgJ1N0YXR1cyddLFxuICAgIH0sXG4gICAgb25EZWxldGU6IHtcbiAgICAgIHNlcnZpY2U6ICdNZWRpYUNvbm5lY3QnLFxuICAgICAgYWN0aW9uOiAnU3RvcEZsb3cnLFxuICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICBGbG93QXJuOiBmbG93QXJuLFxuICAgICAgfSxcbiAgICAgIHBoeXNpY2FsUmVzb3VyY2VJZDogUGh5c2ljYWxSZXNvdXJjZUlkLm9mKGAke2NyeXB0by5yYW5kb21VVUlEKCl9YCksXG4gICAgICAvLyBpZ25vcmVFcnJvckNvZGVzTWF0Y2hpbmc6ICcqJyxcbiAgICAgIG91dHB1dFBhdGhzOiBbJ0Zsb3dBcm4nLCAnU3RhdHVzJ10sXG4gICAgfSxcbiAgICAvL1dpbGwgaWdub3JlIGFueSByZXNvdXJjZSBhbmQgdXNlIHRoZSBhc3N1bWVkUm9sZUFybiBhcyByZXNvdXJjZSBhbmQgJ3N0czpBc3N1bWVSb2xlJyBmb3Igc2VydmljZTphY3Rpb25cbiAgICBwb2xpY3k6IEF3c0N1c3RvbVJlc291cmNlUG9saWN5LmZyb21TZGtDYWxscyh7XG4gICAgICByZXNvdXJjZXM6IEF3c0N1c3RvbVJlc291cmNlUG9saWN5LkFOWV9SRVNPVVJDRSxcbiAgICB9KSxcbiAgfSk7XG4gIHJldHVybiBuZXcgRGF0ZSgpO1xufVxuIl19
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './LiveFeedFromFile';
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./LiveFeedFromFile"), exports);
|
|
18
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHFEQUFtQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vTGl2ZUZlZWRGcm9tRmlsZSc7Il19
|
package/package.json
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "awscdk-construct-mediaconnect-flow",
|
|
3
|
+
"repository": {
|
|
4
|
+
"type": "git",
|
|
5
|
+
"url": "https://github.com/kuu/awscdk-construct-mediaconnect-flow.git"
|
|
6
|
+
},
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "npx projen build",
|
|
9
|
+
"bump": "npx projen bump",
|
|
10
|
+
"clobber": "npx projen clobber",
|
|
11
|
+
"compat": "npx projen compat",
|
|
12
|
+
"compile": "npx projen compile",
|
|
13
|
+
"default": "npx projen default",
|
|
14
|
+
"docgen": "npx projen docgen",
|
|
15
|
+
"eject": "npx projen eject",
|
|
16
|
+
"eslint": "npx projen eslint",
|
|
17
|
+
"package": "npx projen package",
|
|
18
|
+
"package-all": "npx projen package-all",
|
|
19
|
+
"package:js": "npx projen package:js",
|
|
20
|
+
"post-compile": "npx projen post-compile",
|
|
21
|
+
"post-upgrade": "npx projen post-upgrade",
|
|
22
|
+
"pre-compile": "npx projen pre-compile",
|
|
23
|
+
"release": "npx projen release",
|
|
24
|
+
"test": "npx projen test",
|
|
25
|
+
"test:watch": "npx projen test:watch",
|
|
26
|
+
"unbump": "npx projen unbump",
|
|
27
|
+
"upgrade": "npx projen upgrade",
|
|
28
|
+
"watch": "npx projen watch",
|
|
29
|
+
"projen": "npx projen"
|
|
30
|
+
},
|
|
31
|
+
"author": {
|
|
32
|
+
"name": "Kuu Miyazaki",
|
|
33
|
+
"email": "miyazaqui@gmail.com",
|
|
34
|
+
"organization": false
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@stylistic/eslint-plugin": "^2",
|
|
38
|
+
"@types/jest": "^30.0.0",
|
|
39
|
+
"@types/node": "^24.0.7",
|
|
40
|
+
"@typescript-eslint/eslint-plugin": "^8",
|
|
41
|
+
"@typescript-eslint/parser": "^8",
|
|
42
|
+
"commit-and-tag-version": "^12",
|
|
43
|
+
"eslint": "^9",
|
|
44
|
+
"eslint-import-resolver-typescript": "^4.4.4",
|
|
45
|
+
"eslint-plugin-import": "^2.32.0",
|
|
46
|
+
"jest": "^30.0.3",
|
|
47
|
+
"jest-junit": "^16",
|
|
48
|
+
"jsii": "~5.8.9",
|
|
49
|
+
"jsii-diff": "^1.112.0",
|
|
50
|
+
"jsii-docgen": "^10.5.0",
|
|
51
|
+
"jsii-pacmak": "^1.112.0",
|
|
52
|
+
"jsii-rosetta": "~5.8.9",
|
|
53
|
+
"projen": "^0.94.0",
|
|
54
|
+
"ts-jest": "^29.4.0",
|
|
55
|
+
"ts-node": "^10.9.2",
|
|
56
|
+
"typescript": "^5.8.3"
|
|
57
|
+
},
|
|
58
|
+
"peerDependencies": {
|
|
59
|
+
"aws-cdk-lib": "^2.202.0",
|
|
60
|
+
"constructs": "^10.0.5"
|
|
61
|
+
},
|
|
62
|
+
"dependencies": {
|
|
63
|
+
"aws-cdk-lib": "^2.202.0",
|
|
64
|
+
"awscdk-construct-medialive-channel": "^0.0.6",
|
|
65
|
+
"constructs": "^10.4.2"
|
|
66
|
+
},
|
|
67
|
+
"keywords": [
|
|
68
|
+
"MediaConnect",
|
|
69
|
+
"cdk",
|
|
70
|
+
"cdk-construct"
|
|
71
|
+
],
|
|
72
|
+
"main": "lib/index.js",
|
|
73
|
+
"license": "MIT",
|
|
74
|
+
"publishConfig": {
|
|
75
|
+
"access": "public"
|
|
76
|
+
},
|
|
77
|
+
"version": "0.0.0",
|
|
78
|
+
"jest": {
|
|
79
|
+
"coverageProvider": "v8",
|
|
80
|
+
"testMatch": [
|
|
81
|
+
"<rootDir>/@(src|test)/**/*(*.)@(spec|test).ts?(x)",
|
|
82
|
+
"<rootDir>/@(src|test)/**/__tests__/**/*.ts?(x)",
|
|
83
|
+
"<rootDir>/@(projenrc)/**/*(*.)@(spec|test).ts?(x)",
|
|
84
|
+
"<rootDir>/@(projenrc)/**/__tests__/**/*.ts?(x)"
|
|
85
|
+
],
|
|
86
|
+
"clearMocks": true,
|
|
87
|
+
"collectCoverage": true,
|
|
88
|
+
"coverageReporters": [
|
|
89
|
+
"json",
|
|
90
|
+
"lcov",
|
|
91
|
+
"clover",
|
|
92
|
+
"cobertura",
|
|
93
|
+
"text"
|
|
94
|
+
],
|
|
95
|
+
"coverageDirectory": "coverage",
|
|
96
|
+
"coveragePathIgnorePatterns": [
|
|
97
|
+
"/node_modules/"
|
|
98
|
+
],
|
|
99
|
+
"testPathIgnorePatterns": [
|
|
100
|
+
"/node_modules/"
|
|
101
|
+
],
|
|
102
|
+
"watchPathIgnorePatterns": [
|
|
103
|
+
"/node_modules/"
|
|
104
|
+
],
|
|
105
|
+
"reporters": [
|
|
106
|
+
"default",
|
|
107
|
+
[
|
|
108
|
+
"jest-junit",
|
|
109
|
+
{
|
|
110
|
+
"outputDirectory": "test-reports"
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
],
|
|
114
|
+
"transform": {
|
|
115
|
+
"^.+\\.[t]sx?$": [
|
|
116
|
+
"ts-jest",
|
|
117
|
+
{
|
|
118
|
+
"tsconfig": "tsconfig.dev.json"
|
|
119
|
+
}
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
"types": "lib/index.d.ts",
|
|
124
|
+
"stability": "stable",
|
|
125
|
+
"jsii": {
|
|
126
|
+
"outdir": "dist",
|
|
127
|
+
"targets": {},
|
|
128
|
+
"tsc": {
|
|
129
|
+
"outDir": "lib",
|
|
130
|
+
"rootDir": "src"
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
"//": "~~ Generated by projen. To modify, edit .projenrc.ts and run \"npx projen\"."
|
|
134
|
+
}
|