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.
@@ -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
+ }