function.js
  1  "use strict";
  2  var _a;
  3  Object.defineProperty(exports, "__esModule", { value: true });
  4  exports.verifyCodeConfig = exports.Function = exports.Tracing = void 0;
  5  const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
  6  const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
  7  const cloudwatch = require("@aws-cdk/aws-cloudwatch");
  8  const aws_codeguruprofiler_1 = require("@aws-cdk/aws-codeguruprofiler");
  9  const ec2 = require("@aws-cdk/aws-ec2");
 10  const iam = require("@aws-cdk/aws-iam");
 11  const logs = require("@aws-cdk/aws-logs");
 12  const sqs = require("@aws-cdk/aws-sqs");
 13  const core_1 = require("@aws-cdk/core");
 14  const function_base_1 = require("./function-base");
 15  const function_hash_1 = require("./function-hash");
 16  const handler_1 = require("./handler");
 17  const lambda_version_1 = require("./lambda-version");
 18  const lambda_generated_1 = require("./lambda.generated");
 19  const layers_1 = require("./layers");
 20  const runtime_1 = require("./runtime");
 21  /**
 22   * X-Ray Tracing Modes (https://docs.aws.amazon.com/lambda/latest/dg/API_TracingConfig.html).
 23   *
 24   * @stability stable
 25   */
 26  var Tracing;
 27  (function (Tracing) {
 28      Tracing["ACTIVE"] = "Active";
 29      Tracing["PASS_THROUGH"] = "PassThrough";
 30      Tracing["DISABLED"] = "Disabled";
 31  })(Tracing = exports.Tracing || (exports.Tracing = {}));
 32  /**
 33   * Deploys a file from inside the construct library as a function.
 34   *
 35   * The supplied file is subject to the 4096 bytes limit of being embedded in a
 36   * CloudFormation template.
 37   *
 38   * The construct includes an associated role with the lambda.
 39   *
 40   * This construct does not yet reproduce all features from the underlying resource
 41   * library.
 42   *
 43   * @stability stable
 44   */
 45  class Function extends function_base_1.FunctionBase {
 46      /**
 47       * @stability stable
 48       */
 49      constructor(scope, id, props) {
 50          var _b, _c, _d, _e, _f, _g, _h, _j;
 51          super(scope, id, {
 52              physicalName: props.functionName,
 53          });
 54          /**
 55           * The construct node where permissions are attached.
 56           *
 57           * @stability stable
 58           */
 59          this.permissionsNode = this.node;
 60          /**
 61           * Whether the addPermission() call adds any permissions.
 62           *
 63           * True for new Lambdas, false for version $LATEST and imported Lambdas
 64           * from different accounts.
 65           *
 66           * @stability stable
 67           */
 68          this.canCreatePermissions = true;
 69          this.layers = [];
 70          /**
 71           * Environment variables for this function
 72           */
 73          this.environment = {};
 74          jsiiDeprecationWarnings._aws_cdk_aws_lambda_FunctionProps(props);
 75          const managedPolicies = new Array();
 76          // the arn is in the form of - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
 77          managedPolicies.push(iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole'));
 78          if (props.vpc) {
 79              // Policy that will have ENI creation permissions
 80              managedPolicies.push(iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaVPCAccessExecutionRole'));
 81          }
 82          this.role = props.role || new iam.Role(this, 'ServiceRole', {
 83              assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
 84              managedPolicies,
 85          });
 86          this.grantPrincipal = this.role;
 87          // add additional managed policies when necessary
 88          if (props.filesystem) {
 89              const config = props.filesystem.config;
 90              if (config.policies) {
 91                  config.policies.forEach(p => {
 92                      var _b;
 93                      (_b = this.role) === null || _b === void 0 ? void 0 : _b.addToPrincipalPolicy(p);
 94                  });
 95              }
 96          }
 97          for (const statement of (props.initialPolicy || [])) {
 98              this.role.addToPrincipalPolicy(statement);
 99          }
100          const code = props.code.bind(this);
101          verifyCodeConfig(code, props);
102          let profilingGroupEnvironmentVariables = {};
103          if (props.profilingGroup && props.profiling !== false) {
104              this.validateProfiling(props);
105              props.profilingGroup.grantPublish(this.role);
106              profilingGroupEnvironmentVariables = {
107                  AWS_CODEGURU_PROFILER_GROUP_ARN: core_1.Stack.of(scope).formatArn({
108                      service: 'codeguru-profiler',
109                      resource: 'profilingGroup',
110                      resourceName: props.profilingGroup.profilingGroupName,
111                  }),
112                  AWS_CODEGURU_PROFILER_ENABLED: 'TRUE',
113              };
114          }
115          else if (props.profiling) {
116              this.validateProfiling(props);
117              const profilingGroup = new aws_codeguruprofiler_1.ProfilingGroup(this, 'ProfilingGroup', {
118                  computePlatform: aws_codeguruprofiler_1.ComputePlatform.AWS_LAMBDA,
119              });
120              profilingGroup.grantPublish(this.role);
121              profilingGroupEnvironmentVariables = {
122                  AWS_CODEGURU_PROFILER_GROUP_ARN: profilingGroup.profilingGroupArn,
123                  AWS_CODEGURU_PROFILER_ENABLED: 'TRUE',
124              };
125          }
126          const env = { ...profilingGroupEnvironmentVariables, ...props.environment };
127          for (const [key, value] of Object.entries(env)) {
128              this.addEnvironment(key, value);
129          }
130          this.deadLetterQueue = this.buildDeadLetterQueue(props);
131          let fileSystemConfigs = undefined;
132          if (props.filesystem) {
133              fileSystemConfigs = [{
134                      arn: props.filesystem.config.arn,
135                      localMountPath: props.filesystem.config.localMountPath,
136                  }];
137          }
138          if (props.architecture && props.architectures !== undefined) {
139              throw new Error('Either architecture or architectures must be specified but not both.');
140          }
141          if (props.architectures && props.architectures.length > 1) {
142              throw new Error('Only one architecture must be specified.');
143          }
144          const architecture = (_b = props.architecture) !== null && _b !== void 0 ? _b : (props.architectures && props.architectures[0]);
145          const resource = new lambda_generated_1.CfnFunction(this, 'Resource', {
146              functionName: this.physicalName,
147              description: props.description,
148              code: {
149                  s3Bucket: code.s3Location && code.s3Location.bucketName,
150                  s3Key: code.s3Location && code.s3Location.objectKey,
151                  s3ObjectVersion: code.s3Location && code.s3Location.objectVersion,
152                  zipFile: code.inlineCode,
153                  imageUri: (_c = code.image) === null || _c === void 0 ? void 0 : _c.imageUri,
154              },
155              layers: core_1.Lazy.list({ produce: () => this.layers.map(layer => layer.layerVersionArn) }, { omitEmpty: true }),
156              handler: props.handler === handler_1.Handler.FROM_IMAGE ? undefined : props.handler,
157              timeout: props.timeout && props.timeout.toSeconds(),
158              packageType: props.runtime === runtime_1.Runtime.FROM_IMAGE ? 'Image' : undefined,
159              runtime: props.runtime === runtime_1.Runtime.FROM_IMAGE ? undefined : props.runtime.name,
160              role: this.role.roleArn,
161              // Uncached because calling '_checkEdgeCompatibility', which gets called in the resolve of another
162              // Token, actually *modifies* the 'environment' map.
163              environment: core_1.Lazy.uncachedAny({ produce: () => this.renderEnvironment() }),
164              memorySize: props.memorySize,
165              vpcConfig: this.configureVpc(props),
166              deadLetterConfig: this.buildDeadLetterConfig(this.deadLetterQueue),
167              tracingConfig: this.buildTracingConfig(props),
168              reservedConcurrentExecutions: props.reservedConcurrentExecutions,
169              imageConfig: undefinedIfNoKeys({
170                  command: (_d = code.image) === null || _d === void 0 ? void 0 : _d.cmd,
171                  entryPoint: (_e = code.image) === null || _e === void 0 ? void 0 : _e.entrypoint,
172                  workingDirectory: (_f = code.image) === null || _f === void 0 ? void 0 : _f.workingDirectory,
173              }),
174              kmsKeyArn: (_g = props.environmentEncryption) === null || _g === void 0 ? void 0 : _g.keyArn,
175              fileSystemConfigs,
176              codeSigningConfigArn: (_h = props.codeSigningConfig) === null || _h === void 0 ? void 0 : _h.codeSigningConfigArn,
177              architectures: architecture ? [architecture.name] : undefined,
178          });
179          resource.node.addDependency(this.role);
180          this.functionName = this.getResourceNameAttribute(resource.ref);
181          this.functionArn = this.getResourceArnAttribute(resource.attrArn, {
182              service: 'lambda',
183              resource: 'function',
184              resourceName: this.physicalName,
185              arnFormat: core_1.ArnFormat.COLON_RESOURCE_NAME,
186          });
187          this.runtime = props.runtime;
188          this.architecture = props.architecture;
189          if (props.layers) {
190              if (props.runtime === runtime_1.Runtime.FROM_IMAGE) {
191                  throw new Error('Layers are not supported for container image functions');
192              }
193              this.addLayers(...props.layers);
194          }
195          for (const event of props.events || []) {
196              this.addEventSource(event);
197          }
198          // Log retention
199          if (props.logRetention) {
200              const logRetention = new logs.LogRetention(this, 'LogRetention', {
201                  logGroupName: `/aws/lambda/${this.functionName}`,
202                  retention: props.logRetention,
203                  role: props.logRetentionRole,
204                  logRetentionRetryOptions: props.logRetentionRetryOptions,
205              });
206              this._logGroup = logs.LogGroup.fromLogGroupArn(this, 'LogGroup', logRetention.logGroupArn);
207          }
208          props.code.bindToResource(resource);
209          // Event Invoke Config
210          if (props.onFailure || props.onSuccess || props.maxEventAge || props.retryAttempts !== undefined) {
211              this.configureAsyncInvoke({
212                  onFailure: props.onFailure,
213                  onSuccess: props.onSuccess,
214                  maxEventAge: props.maxEventAge,
215                  retryAttempts: props.retryAttempts,
216              });
217          }
218          this.currentVersionOptions = props.currentVersionOptions;
219          if (props.filesystem) {
220              if (!props.vpc) {
221                  throw new Error('Cannot configure \'filesystem\' without configuring a VPC.');
222              }
223              const config = props.filesystem.config;
224              if (config.dependency) {
225                  this.node.addDependency(...config.dependency);
226              }
227              // There could be a race if the Lambda is used in a CustomResource. It is possible for the Lambda to
228              // fail to attach to a given FileSystem if we do not have a dependency on the SecurityGroup ingress/egress
229              // rules that were created between this Lambda's SG & the Filesystem SG.
230              this.connections.securityGroups.forEach(sg => {
231                  sg.node.findAll().forEach(child => {
232                      if (child instanceof core_1.CfnResource && child.cfnResourceType === 'AWS::EC2::SecurityGroupEgress') {
233                          resource.node.addDependency(child);
234                      }
235                  });
236              });
237              (_j = config.connections) === null || _j === void 0 ? void 0 : _j.securityGroups.forEach(sg => {
238                  sg.node.findAll().forEach(child => {
239                      if (child instanceof core_1.CfnResource && child.cfnResourceType === 'AWS::EC2::SecurityGroupIngress') {
240                          resource.node.addDependency(child);
241                      }
242                  });
243              });
244          }
245          // Configure Lambda insights
246          this.configureLambdaInsights(props);
247      }
248      /**
249       * Returns a `lambda.Version` which represents the current version of this Lambda function. A new version will be created every time the function's configuration changes.
250       *
251       * You can specify options for this version using the `currentVersionOptions`
252       * prop when initializing the `lambda.Function`.
253       *
254       * @stability stable
255       */
256      get currentVersion() {
257          if (this._currentVersion) {
258              return this._currentVersion;
259          }
260          this._currentVersion = new lambda_version_1.Version(this, 'CurrentVersion', {
261              lambda: this,
262              ...this.currentVersionOptions,
263          });
264          // override the version's logical ID with a lazy string which includes the
265          // hash of the function itself, so a new version resource is created when
266          // the function configuration changes.
267          const cfn = this._currentVersion.node.defaultChild;
268          const originalLogicalId = this.stack.resolve(cfn.logicalId);
269          cfn.overrideLogicalId(core_1.Lazy.uncachedString({
270              produce: () => {
271                  const hash = function_hash_1.calculateFunctionHash(this);
272                  const logicalId = function_hash_1.trimFromStart(originalLogicalId, 255 - 32);
273                  return `${logicalId}${hash}`;
274              },
275          }));
276          return this._currentVersion;
277      }
278      /**
279       * Record whether specific properties in the `AWS::Lambda::Function` resource should also be associated to the Version resource.
280       *
281       * See 'currentVersion' section in the module README for more details.
282       *
283       * @param propertyName The property to classify.
284       * @param locked whether the property should be associated to the version or not.
285       * @stability stable
286       */
287      static classifyVersionProperty(propertyName, locked) {
288          this._VER_PROPS[propertyName] = locked;
289      }
290      /**
291       * Import a lambda function into the CDK using its ARN.
292       *
293       * @stability stable
294       */
295      static fromFunctionArn(scope, id, functionArn) {
296          return Function.fromFunctionAttributes(scope, id, { functionArn });
297      }
298      /**
299       * Creates a Lambda function object which represents a function not defined within this stack.
300       *
301       * @param scope The parent construct.
302       * @param id The name of the lambda construct.
303       * @param attrs the attributes of the function to import.
304       * @stability stable
305       */
306      static fromFunctionAttributes(scope, id, attrs) {
307          jsiiDeprecationWarnings._aws_cdk_aws_lambda_FunctionAttributes(attrs);
308          const functionArn = attrs.functionArn;
309          const functionName = extractNameFromArn(attrs.functionArn);
310          const role = attrs.role;
311          class Import extends function_base_1.FunctionBase {
312              constructor(s, i) {
313                  var _b;
314                  super(s, i);
315                  this.functionName = functionName;
316                  this.functionArn = functionArn;
317                  this.role = role;
318                  this.permissionsNode = this.node;
319                  this.canCreatePermissions = (_b = attrs.sameEnvironment) !== null && _b !== void 0 ? _b : this._isStackAccount();
320                  this.grantPrincipal = role || new iam.UnknownPrincipal({ resource: this });
321                  if (attrs.securityGroup) {
322                      this._connections = new ec2.Connections({
323                          securityGroups: [attrs.securityGroup],
324                      });
325                  }
326                  else if (attrs.securityGroupId) {
327                      this._connections = new ec2.Connections({
328                          securityGroups: [ec2.SecurityGroup.fromSecurityGroupId(scope, 'SecurityGroup', attrs.securityGroupId)],
329                      });
330                  }
331              }
332          }
333          return new Import(scope, id);
334      }
335      /**
336       * Return the given named metric for this Lambda.
337       *
338       * @stability stable
339       */
340      static metricAll(metricName, props) {
341          return new cloudwatch.Metric({
342              namespace: 'AWS/Lambda',
343              metricName,
344              ...props,
345          });
346      }
347      /**
348       * Metric for the number of Errors executing all Lambdas.
349       *
350       * @default sum over 5 minutes
351       * @stability stable
352       */
353      static metricAllErrors(props) {
354          return this.metricAll('Errors', { statistic: 'sum', ...props });
355      }
356      /**
357       * Metric for the Duration executing all Lambdas.
358       *
359       * @default average over 5 minutes
360       * @stability stable
361       */
362      static metricAllDuration(props) {
363          return this.metricAll('Duration', props);
364      }
365      /**
366       * Metric for the number of invocations of all Lambdas.
367       *
368       * @default sum over 5 minutes
369       * @stability stable
370       */
371      static metricAllInvocations(props) {
372          return this.metricAll('Invocations', { statistic: 'sum', ...props });
373      }
374      /**
375       * Metric for the number of throttled invocations of all Lambdas.
376       *
377       * @default sum over 5 minutes
378       * @stability stable
379       */
380      static metricAllThrottles(props) {
381          return this.metricAll('Throttles', { statistic: 'sum', ...props });
382      }
383      /**
384       * Metric for the number of concurrent executions across all Lambdas.
385       *
386       * @default max over 5 minutes
387       * @stability stable
388       */
389      static metricAllConcurrentExecutions(props) {
390          // Mini-FAQ: why max? This metric is a gauge that is emitted every
391          // minute, so either max or avg or a percentile make sense (but sum
392          // doesn't). Max is more sensitive to spiky load changes which is
393          // probably what you're interested in if you're looking at this metric
394          // (Load spikes may lead to concurrent execution errors that would
395          // otherwise not be visible in the avg)
396          return this.metricAll('ConcurrentExecutions', { statistic: 'max', ...props });
397      }
398      /**
399       * Metric for the number of unreserved concurrent executions across all Lambdas.
400       *
401       * @default max over 5 minutes
402       * @stability stable
403       */
404      static metricAllUnreservedConcurrentExecutions(props) {
405          return this.metricAll('UnreservedConcurrentExecutions', { statistic: 'max', ...props });
406      }
407      /**
408       * Adds an environment variable to this Lambda function.
409       *
410       * If this is a ref to a Lambda function, this operation results in a no-op.
411       *
412       * @param key The environment variable key.
413       * @param value The environment variable's value.
414       * @param options Environment variable options.
415       * @stability stable
416       */
417      addEnvironment(key, value, options) {
418          jsiiDeprecationWarnings._aws_cdk_aws_lambda_EnvironmentOptions(options);
419          this.environment[key] = { value, ...options };
420          return this;
421      }
422      /**
423       * Adds one or more Lambda Layers to this Lambda function.
424       *
425       * @param layers the layers to be added.
426       * @stability stable
427       * @throws if there are already 5 layers on this function, or the layer is incompatible with this function's runtime.
428       */
429      addLayers(...layers) {
430          jsiiDeprecationWarnings._aws_cdk_aws_lambda_ILayerVersion(layers);
431          for (const layer of layers) {
432              if (this.layers.length === 5) {
433                  throw new Error('Unable to add layer: this lambda function already uses 5 layers.');
434              }
435              if (layer.compatibleRuntimes && !layer.compatibleRuntimes.find(runtime => runtime.runtimeEquals(this.runtime))) {
436                  const runtimes = layer.compatibleRuntimes.map(runtime => runtime.name).join(', ');
437                  throw new Error(`This lambda function uses a runtime that is incompatible with this layer (${this.runtime.name} is not in [${runtimes}])`);
438              }
439              // Currently no validations for compatible architectures since Lambda service
440              // allows layers configured with one architecture to be used with a Lambda function
441              // from another architecture.
442              this.layers.push(layer);
443          }
444      }
445      /**
446       * (deprecated) Add a new version for this Lambda.
447       *
448       * If you want to deploy through CloudFormation and use aliases, you need to
449       * add a new version (with a new name) to your Lambda every time you want to
450       * deploy an update. An alias can then refer to the newly created Version.
451       *
452       * All versions should have distinct names, and you should not delete versions
453       * as long as your Alias needs to refer to them.
454       *
455       * @param name A unique name for this version.
456       * @param codeSha256 The SHA-256 hash of the most recently deployed Lambda source code, or omit to skip validation.
457       * @param description A description for this version.
458       * @param provisionedExecutions A provisioned concurrency configuration for a function's version.
459       * @param asyncInvokeConfig configuration for this version when it is invoked asynchronously.
460       * @returns A new Version object.
461       * @deprecated This method will create an AWS::Lambda::Version resource which
462       * snapshots the AWS Lambda function *at the time of its creation* and it
463       * won't get updated when the function changes. Instead, use
464       * `this.currentVersion` to obtain a reference to a version resource that gets
465       * automatically recreated when the function configuration (or code) changes.
466       */
467      addVersion(name, codeSha256, description, provisionedExecutions, asyncInvokeConfig = {}) {
468          jsiiDeprecationWarnings.print("@aws-cdk/aws-lambda.Function#addVersion", "This method will create an AWS::Lambda::Version resource which\nsnapshots the AWS Lambda function *at the time of its creation* and it\nwon't get updated when the function changes. Instead, use\n`this.currentVersion` to obtain a reference to a version resource that gets\nautomatically recreated when the function configuration (or code) changes.");
469          jsiiDeprecationWarnings._aws_cdk_aws_lambda_EventInvokeConfigOptions(asyncInvokeConfig);
470          return new lambda_version_1.Version(this, 'Version' + name, {
471              lambda: this,
472              codeSha256,
473              description,
474              provisionedConcurrentExecutions: provisionedExecutions,
475              ...asyncInvokeConfig,
476          });
477      }
478      /**
479       * The LogGroup where the Lambda function's logs are made available.
480       *
481       * If either `logRetention` is set or this property is called, a CloudFormation custom resource is added to the stack that
482       * pre-creates the log group as part of the stack deployment, if it already doesn't exist, and sets the correct log retention
483       * period (never expire, by default).
484       *
485       * Further, if the log group already exists and the `logRetention` is not set, the custom resource will reset the log retention
486       * to never expire even if it was configured with a different value.
487       *
488       * @stability stable
489       */
490      get logGroup() {
491          if (!this._logGroup) {
492              const logRetention = new logs.LogRetention(this, 'LogRetention', {
493                  logGroupName: `/aws/lambda/${this.functionName}`,
494                  retention: logs.RetentionDays.INFINITE,
495              });
496              this._logGroup = logs.LogGroup.fromLogGroupArn(this, `${this.node.id}-LogGroup`, logRetention.logGroupArn);
497          }
498          return this._logGroup;
499      }
500      /** @internal */
501      _checkEdgeCompatibility() {
502          // Check env vars
503          const envEntries = Object.entries(this.environment);
504          for (const [key, config] of envEntries) {
505              if (config.removeInEdge) {
506                  delete this.environment[key];
507                  core_1.Annotations.of(this).addInfo(`Removed ${key} environment variable for Lambda@Edge compatibility`);
508              }
509          }
510          const envKeys = Object.keys(this.environment);
511          if (envKeys.length !== 0) {
512              throw new Error(`The function ${this.node.path} contains environment variables [${envKeys}] and is not compatible with Lambda@Edge. \
513  Environment variables can be marked for removal when used in Lambda@Edge by setting the \'removeInEdge\' property in the \'addEnvironment()\' API.`);
514          }
515          return;
516      }
517      /**
518       * Configured lambda insights on the function if specified. This is acheived by adding an imported layer which is added to the
519       * list of lambda layers on synthesis.
520       *
521       * https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Lambda-Insights-extension-versions.html
522       */
523      configureLambdaInsights(props) {
524          var _b;
525          if (props.insightsVersion === undefined) {
526              return;
527          }
528          if (props.runtime !== runtime_1.Runtime.FROM_IMAGE) {
529              // Layers cannot be added to Lambda container images. The image should have the insights agent installed.
530              // See https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Lambda-Insights-Getting-Started-docker.html
531              this.addLayers(layers_1.LayerVersion.fromLayerVersionArn(this, 'LambdaInsightsLayer', props.insightsVersion.layerVersionArn));
532          }
533          (_b = this.role) === null || _b === void 0 ? void 0 : _b.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('CloudWatchLambdaInsightsExecutionRolePolicy'));
534      }
535      renderEnvironment() {
536          if (!this.environment || Object.keys(this.environment).length === 0) {
537              return undefined;
538          }
539          const variables = {};
540          // Sort environment so the hash of the function used to create
541          // `currentVersion` is not affected by key order (this is how lambda does
542          // it). For backwards compatibility we do not sort environment variables in case
543          // _currentVersion is not defined. Otherwise, this would have invalidated
544          // the template, and for example, may cause unneeded updates for nested
545          // stacks.
546          const keys = this._currentVersion
547              ? Object.keys(this.environment).sort()
548              : Object.keys(this.environment);
549          for (const key of keys) {
550              variables[key] = this.environment[key].value;
551          }
552          return { variables };
553      }
554      /**
555       * If configured, set up the VPC-related properties
556       *
557       * Returns the VpcConfig that should be added to the
558       * Lambda creation properties.
559       */
560      configureVpc(props) {
561          var _b;
562          if ((props.securityGroup || props.allowAllOutbound !== undefined) && !props.vpc) {
563              throw new Error('Cannot configure \'securityGroup\' or \'allowAllOutbound\' without configuring a VPC');
564          }
565          if (!props.vpc) {
566              return undefined;
567          }
568          if (props.securityGroup && props.allowAllOutbound !== undefined) {
569              throw new Error('Configure \'allowAllOutbound\' directly on the supplied SecurityGroup.');
570          }
571          let securityGroups;
572          if (props.securityGroup && props.securityGroups) {
573              throw new Error('Only one of the function props, securityGroup or securityGroups, is allowed');
574          }
575          if (props.securityGroups) {
576              securityGroups = props.securityGroups;
577          }
578          else {
579              const securityGroup = props.securityGroup || new ec2.SecurityGroup(this, 'SecurityGroup', {
580                  vpc: props.vpc,
581                  description: 'Automatic security group for Lambda Function ' + core_1.Names.uniqueId(this),
582                  allowAllOutbound: props.allowAllOutbound,
583              });
584              securityGroups = [securityGroup];
585          }
586          this._connections = new ec2.Connections({ securityGroups });
587          if (props.filesystem) {
588              if (props.filesystem.config.connections) {
589                  props.filesystem.config.connections.allowDefaultPortFrom(this);
590              }
591          }
592          const allowPublicSubnet = (_b = props.allowPublicSubnet) !== null && _b !== void 0 ? _b : false;
593          const { subnetIds } = props.vpc.selectSubnets(props.vpcSubnets);
594          const publicSubnetIds = new Set(props.vpc.publicSubnets.map(s => s.subnetId));
595          for (const subnetId of subnetIds) {
596              if (publicSubnetIds.has(subnetId) && !allowPublicSubnet) {
597                  throw new Error('Lambda Functions in a public subnet can NOT access the internet. ' +
598                      'If you are aware of this limitation and would still like to place the function int a public subnet, set `allowPublicSubnet` to true');
599              }
600          }
601          // List can't be empty here, if we got this far you intended to put your Lambda
602          // in subnets. We're going to guarantee that we get the nice error message by
603          // making VpcNetwork do the selection again.
604          return {
605              subnetIds,
606              securityGroupIds: securityGroups.map(sg => sg.securityGroupId),
607          };
608      }
609      buildDeadLetterQueue(props) {
610          if (props.deadLetterQueue && props.deadLetterQueueEnabled === false) {
611              throw Error('deadLetterQueue defined but deadLetterQueueEnabled explicitly set to false');
612          }
613          if (!props.deadLetterQueue && !props.deadLetterQueueEnabled) {
614              return undefined;
615          }
616          const deadLetterQueue = props.deadLetterQueue || new sqs.Queue(this, 'DeadLetterQueue', {
617              retentionPeriod: core_1.Duration.days(14),
618          });
619          this.addToRolePolicy(new iam.PolicyStatement({
620              actions: ['sqs:SendMessage'],
621              resources: [deadLetterQueue.queueArn],
622          }));
623          return deadLetterQueue;
624      }
625      buildDeadLetterConfig(deadLetterQueue) {
626          if (deadLetterQueue) {
627              return {
628                  targetArn: deadLetterQueue.queueArn,
629              };
630          }
631          else {
632              return undefined;
633          }
634      }
635      buildTracingConfig(props) {
636          if (props.tracing === undefined || props.tracing === Tracing.DISABLED) {
637              return undefined;
638          }
639          this.addToRolePolicy(new iam.PolicyStatement({
640              actions: ['xray:PutTraceSegments', 'xray:PutTelemetryRecords'],
641              resources: ['*'],
642          }));
643          return {
644              mode: props.tracing,
645          };
646      }
647      validateProfiling(props) {
648          if (!props.runtime.supportsCodeGuruProfiling) {
649              throw new Error(`CodeGuru profiling is not supported by runtime ${props.runtime.name}`);
650          }
651          if (props.environment && (props.environment.AWS_CODEGURU_PROFILER_GROUP_ARN || props.environment.AWS_CODEGURU_PROFILER_ENABLED)) {
652              throw new Error('AWS_CODEGURU_PROFILER_GROUP_ARN and AWS_CODEGURU_PROFILER_ENABLED must not be set when profiling options enabled');
653          }
654      }
655  }
656  exports.Function = Function;
657  _a = JSII_RTTI_SYMBOL_1;
658  Function[_a] = { fqn: "@aws-cdk/aws-lambda.Function", version: "1.134.0" };
659  /** @internal */
660  Function._VER_PROPS = {};
661  /**
662   * Given an opaque (token) ARN, returns a CloudFormation expression that extracts the function
663   * name from the ARN.
664   *
665   * Function ARNs look like this:
666   *
667   *   arn:aws:lambda:region:account-id:function:function-name
668   *
669   * ..which means that in order to extract the `function-name` component from the ARN, we can
670   * split the ARN using ":" and select the component in index 6.
671   *
672   * @returns `FnSelect(6, FnSplit(':', arn))`
673   */
674  function extractNameFromArn(arn) {
675      return core_1.Fn.select(6, core_1.Fn.split(':', arn));
676  }
677  function verifyCodeConfig(code, props) {
678      // mutually exclusive
679      const codeType = [code.inlineCode, code.s3Location, code.image];
680      if (codeType.filter(x => !!x).length !== 1) {
681          throw new Error('lambda.Code must specify exactly one of: "inlineCode", "s3Location", or "image"');
682      }
683      if (!!code.image === (props.handler !== handler_1.Handler.FROM_IMAGE)) {
684          throw new Error('handler must be `Handler.FROM_IMAGE` when using image asset for Lambda function');
685      }
686      if (!!code.image === (props.runtime !== runtime_1.Runtime.FROM_IMAGE)) {
687          throw new Error('runtime must be `Runtime.FROM_IMAGE` when using image asset for Lambda function');
688      }
689      // if this is inline code, check that the runtime supports
690      if (code.inlineCode && !props.runtime.supportsInlineCode) {
691          throw new Error(`Inline source not allowed for ${props.runtime.name}`);
692      }
693  }
694  exports.verifyCodeConfig = verifyCodeConfig;
695  function undefinedIfNoKeys(struct) {
696      const allUndefined = Object.values(struct).every(val => val === undefined);
697      return allUndefined ? undefined : struct;
698  }
699  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnVuY3Rpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJmdW5jdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxzREFBc0Q7QUFDdEQsd0VBQWlHO0FBQ2pHLHdDQUF3QztBQUN4Qyx3Q0FBd0M7QUFFeEMsMENBQTBDO0FBQzFDLHdDQUF3QztBQUN4Qyx3Q0FBc0c7QUFRdEcsbURBQThFO0FBQzlFLG1EQUF1RTtBQUN2RSx1Q0FBb0M7QUFFcEMscURBQTJEO0FBQzNELHlEQUFpRDtBQUNqRCxxQ0FBdUQ7QUFDdkQsdUNBQW9DOzs7Ozs7QUFPcEMsSUFBWSxPQU9YO0FBUEQsV0FBWSxPQUFPO0lBRWpCLDRCQUFpQixDQUFBO0lBRWpCLHVDQUE0QixDQUFBO0lBRTVCLGdDQUFxQixDQUFBO0FBQ3ZCLENBQUMsRUFQVyxPQUFPLEdBQVAsZUFBTyxLQUFQLGVBQU8sUUFPbEI7Ozs7Ozs7Ozs7Ozs7O0FBOEdELE1BQWEsUUFBUyxTQUFRLDRCQUFZOzs7O0lBK0p4QyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQW9COztRQUM1RCxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRTtZQUNmLFlBQVksRUFBRSxLQUFLLENBQUMsWUFBWTtTQUNqQyxDQUFDLENBQUM7Ozs7OztRQXBCVyxvQkFBZSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7Ozs7Ozs7OztRQUd6Qix5QkFBb0IsR0FBRyxJQUFJLENBQUM7UUFFOUIsV0FBTSxHQUFvQixFQUFFLENBQUM7UUFJOUM7O1dBRUc7UUFDSyxnQkFBVyxHQUF5QyxFQUFFLENBQUM7O1FBVTdELE1BQU0sZUFBZSxHQUFHLElBQUksS0FBSyxFQUFzQixDQUFDO1FBRXhELCtGQUErRjtRQUMvRixlQUFlLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsd0JBQXdCLENBQUMsMENBQTBDLENBQUMsQ0FBQyxDQUFDO1FBRTdHLElBQUksS0FBSyxDQUFDLEdBQUcsRUFBRTtZ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QUFJLENBQUMsVUFBVSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsRUFBRTtRQUN4RCxNQUFNLElBQUksS0FBSyxDQUFDLGlDQUFpQyxLQUFLLENBQUMsT0FBUSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7S0FDekU7QUFDSCxDQUFDO0FBcEJELDRDQW9CQztBQUVELFNBQVMsaUJBQWlCLENBQUksTUFBUztJQUNyQyxNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxTQUFTLENBQUMsQ0FBQztJQUMzRSxPQUFPLFlBQVksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7QUFDM0MsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGNsb3Vkd2F0Y2ggZnJvbSAnQGF3cy1jZGsvYXdzLWNsb3Vkd2F0Y2gnO1xuaW1wb3J0IHsgSVByb2ZpbGluZ0dyb3VwLCBQcm9maWxpbmdHcm91cCwgQ29tcHV0ZVBsYXRmb3JtIH0gZnJvbSAnQGF3cy1jZGsvYXdzLWNvZGVndXJ1cHJvZmlsZXInO1xuaW1wb3J0ICogYXMgZWMyIGZyb20gJ0Bhd3MtY2RrL2F3cy1lYzInO1xuaW1wb3J0ICogYXMgaWFtIGZyb20gJ0Bhd3MtY2RrL2F3cy1pYW0nO1xuaW1wb3J0ICogYXMga21zIGZyb20gJ0Bhd3MtY2RrL2F3cy1rbXMnO1xuaW1wb3J0ICogYXMgbG9ncyBmcm9tICdAYXdzLWNkay9hd3MtbG9ncyc7XG5pbXBvcnQgKiBhcyBzcXMgZnJvbSAnQGF3cy1jZGsvYXdzLXNxcyc7XG5pbXBvcnQgeyBBbm5vdGF0aW9ucywgQXJuRm9ybWF0LCBDZm5SZXNvdXJjZSwgRHVyYXRpb24sIEZuLCBMYXp5LCBOYW1lcywgU3RhY2sgfSBmcm9tICdAYXdzLWNkay9jb3JlJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgQXJjaGl0ZWN0dXJlIH0gZnJvbSAnLi9hcmNoaXRlY3R1cmUnO1xuaW1wb3J0IHsgQ29kZSwgQ29kZUNvbmZpZyB9IGZyb20gJy4vY29kZSc7XG5pbXBvcnQgeyBJQ29kZVNpZ25pbmdDb25maWcgfSBmcm9tICcuL2NvZGUtc2lnbmluZy1jb25maWcnO1xuaW1wb3J0IHsgRXZlbnRJbnZva2VDb25maWdPcHRpb25zIH0gZnJvbSAnLi9ldmVudC1pbnZva2UtY29uZmlnJztcbmltcG9ydCB7IElFdmVudFNvdXJjZSB9IGZyb20gJy4vZXZlbnQtc291cmNlJztcbmltcG9ydCB7IEZpbGVTeXN0ZW0gfSBmcm9tICcuL2ZpbGVzeXN0ZW0nO1xuaW1wb3J0IHsgRnVuY3Rpb25BdHRyaWJ1dGVzLCBGdW5jdGlvbkJhc2UsIElGdW5jdGlvbiB9IGZyb20gJy4vZnVuY3Rpb24tYmFzZSc7XG5pbXBvcnQgeyBjYWxjdWxhdGVGdW5jdGlvbkhhc2gsIHRyaW1Gcm9tU3RhcnQgfSBmcm9tICcuL2Z1bmN0aW9uLWhhc2gnO1xuaW1wb3J0IHsgSGFuZGxlciB9IGZyb20gJy4vaGFuZGxlcic7XG5pbXBvcnQgeyBMYW1iZGFJbnNpZ2h0c1ZlcnNpb24gfSBmcm9tICcuL2xhbWJkYS1pbnNpZ2h0cyc7XG5pbXBvcnQgeyBWZXJzaW9uLCBWZXJzaW9uT3B0aW9ucyB9IGZyb20gJy4vbGFtYmRhLXZlcnNpb24nO1xuaW1wb3J0IHsgQ2ZuRnVuY3Rpb24gfSBmcm9tICcuL2xhbWJkYS5nZW5lcmF0ZWQnO1xuaW1wb3J0IHsgTGF5ZXJWZXJzaW9uLCBJTGF5ZXJWZXJzaW9uIH0gZnJvbSAnLi9sYXllcnMnO1xuaW1wb3J0IHsgUnVudGltZSB9IGZyb20gJy4vcnVudGltZSc7XG5cbi8vIGtlZXAgdGhpcyBpbXBvcnQgc2VwYXJhdGUgZnJvbSBvdGhlciBpbXBvcnRzIHRvIHJlZHVjZSBjaGFuY2UgZm9yIG1lcmdlIGNvbmZsaWN0cyB3aXRoIHYyLW1haW5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuaW1wb3J0IHsgTG9nUmV0ZW50aW9uUmV0cnlPcHRpb25zIH0gZnJvbSAnLi9sb2ctcmV0ZW50aW9uJztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuZXhwb3J0IGVudW0gVHJhY2luZyB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBBQ1RJVkUgPSAnQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgUEFTU19USFJPVUdIID0gJ1Bhc3NUaHJvdWdoJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBESVNBQkxFRCA9ICdEaXNhYmxlZCdcbn1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG5leHBvcnQgaW50ZXJmYWNlIEZ1bmN0aW9uT3B0aW9ucyBleHRlbmRzIEV2ZW50SW52b2tlQ29uZmlnT3B0aW9ucyB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSB0aW1lb3V0PzogRHVyYXRpb247XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgZW52aXJvbm1lbnQ/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IGZ1bmN0aW9uTmFtZT86IHN0cmluZztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBtZW1vcnlTaXplPzogbnVtYmVyO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IGluaXRpYWxQb2xpY3k/OiBpYW0uUG9saWN5U3RhdGVtZW50W107XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgcm9sZT86IGlhbS5JUm9sZTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgdnBjPzogZWMyLklWcGM7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgdnBjU3VibmV0cz86IGVjMi5TdWJuZXRTZWxlY3Rpb247XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHNlY3VyaXR5R3JvdXA/OiBlYzIuSVNlY3VyaXR5R3JvdXA7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgc2VjdXJpdHlHcm91cHM/OiBlYzIuSVNlY3VyaXR5R3JvdXBbXTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IGFsbG93QWxsT3V0Ym91bmQ/OiBib29sZWFuO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgZGVhZExldHRlclF1ZXVlRW5hYmxlZD86IGJvb2xlYW47XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgZGVhZExldHRlclF1ZXVlPzogc3FzLklRdWV1ZTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgdHJhY2luZz86IFRyYWNpbmc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHByb2ZpbGluZz86IGJvb2xlYW47XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBwcm9maWxpbmdHcm91cD86IElQcm9maWxpbmdHcm91cDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgaW5zaWdodHNWZXJzaW9uPzogTGFtYmRhSW5zaWdodHNWZXJzaW9uO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBsYXllcnM/OiBJTGF5ZXJWZXJzaW9uW107XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgcmVzZXJ2ZWRDb25jdXJyZW50RXhlY3V0aW9ucz86IG51bWJlcjtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IGV2ZW50cz86IElFdmVudFNvdXJjZVtdO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgbG9nUmV0ZW50aW9uPzogbG9ncy5SZXRlbnRpb25EYXlzO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBsb2dSZXRlbnRpb25Sb2xlPzogaWFtLklSb2xlO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IGxvZ1JldGVudGlvblJldHJ5T3B0aW9ucz86IExvZ1JldGVudGlvblJldHJ5T3B0aW9ucztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgY3VycmVudFZlcnNpb25PcHRpb25zPzogVmVyc2lvbk9wdGlvbnM7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBmaWxlc3lzdGVtPzogRmlsZVN5c3RlbTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBhbGxvd1B1YmxpY1N1Ym5ldD86IGJvb2xlYW47XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IGVudmlyb25tZW50RW5jcnlwdGlvbj86IGttcy5JS2V5O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgY29kZVNpZ25pbmdDb25maWc/OiBJQ29kZVNpZ25pbmdDb25maWc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBhcmNoaXRlY3R1cmVzPzogQXJjaGl0ZWN0dXJlW107XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IGFyY2hpdGVjdHVyZT86IEFyY2hpdGVjdHVyZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBGdW5jdGlvblByb3BzIGV4dGVuZHMgRnVuY3Rpb25PcHRpb25zIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgcnVudGltZTogUnVudGltZTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICByZWFkb25seSBjb2RlOiBDb2RlO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcmVhZG9ubHkgaGFuZGxlcjogc3RyaW5nO1xufVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuZXhwb3J0IGNsYXNzIEZ1bmN0aW9uIGV4dGVuZHMgRnVuY3Rpb25CYXNlIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyBnZXQgY3VycmVudFZlcnNpb24oKTogVmVyc2lvbiB7XG4gICAgaWYgKHRoaXMuX2N1cnJlbnRWZXJzaW9uKSB7XG4gICAgICByZXR1cm4gdGhpcy5fY3VycmVudFZlcnNpb247XG4gICAgfVxuXG4gICAgdGhpcy5fY3VycmVudFZlcnNpb24gPSBuZXcgVmVyc2lvbih0aGlzLCAnQ3VycmVudFZlcnNpb24nLCB7XG4gICAgICBsYW1iZGE6IHRoaXMsXG4gICAgICAuLi50aGlzLmN1cnJlbnRWZXJzaW9uT3B0aW9ucyxcbiAgICB9KTtcblxuICAgIC8vIG92ZXJyaWRlIHRoZSB2ZXJzaW9uJ3MgbG9naWNhbCBJRCB3aXRoIGEgbGF6eSBzdHJpbmcgd2hpY2ggaW5jbHVkZXMgdGhlXG4gICAgLy8gaGFzaCBvZiB0aGUgZnVuY3Rpb24gaXRzZWxmLCBzbyBhIG5ldyB2ZXJzaW9uIHJlc291cmNlIGlzIGNyZWF0ZWQgd2hlblxuICAgIC8vIHRoZSBmdW5jdGlvbiBjb25maWd1cmF0aW9uIGNoYW5nZXMuXG4gICAgY29uc3QgY2ZuID0gdGhpcy5fY3VycmVudFZlcnNpb24ubm9kZS5kZWZhdWx0Q2hpbGQgYXMgQ2ZuUmVzb3VyY2U7XG4gICAgY29uc3Qgb3JpZ2luYWxMb2dpY2FsSWQgPSB0aGlzLnN0YWNrLnJlc29sdmUoY2ZuLmxvZ2ljYWxJZCkgYXMgc3RyaW5nO1xuXG4gICAgY2ZuLm92ZXJyaWRlTG9naWNhbElkKExhenkudW5jYWNoZWRTdHJpbmcoe1xuICAgICAgcHJvZHVjZTogKCkgPT4ge1xuICAgICAgICBjb25zdCBoYXNoID0gY2FsY3VsYXRlRnVuY3Rpb25IYXNoKHRoaXMpO1xuICAgICAgICBjb25zdCBsb2dpY2FsSWQgPSB0cmltRnJvbVN0YXJ0KG9yaWdpbmFsTG9naWNhbElkLCAyNTUgLSAzMik7XG4gICAgICAgIHJldHVybiBgJHtsb2dpY2FsSWR9JHtoYXNofWA7XG4gICAgICB9LFxuICAgIH0pKTtcblxuICAgIHJldHVybiB0aGlzLl9jdXJyZW50VmVyc2lvbjtcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHVibGljIHN0YXRpYyBfVkVSX1BST1BTOiB7IFtrZXk6IHN0cmluZ106IGJvb2xlYW4gfSA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHN0YXRpYyBjbGFzc2lmeVZlcnNpb25Qcm9wZXJ0eShwcm9wZXJ0eU5hbWU6IHN0cmluZywgbG9ja2VkOiBib29sZWFuKSB7XG4gICAgdGhpcy5fVkVSX1BST1BTW3Byb3BlcnR5TmFtZV0gPSBsb2NrZWQ7XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHN0YXRpYyBmcm9tRnVuY3Rpb25Bcm4oc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgZnVuY3Rpb25Bcm46IHN0cmluZyk6IElGdW5jdGlvbiB7XG4gICAgcmV0dXJuIEZ1bmN0aW9uLmZyb21GdW5jdGlvbkF0dHJpYnV0ZXMoc2NvcGUsIGlkLCB7IGZ1bmN0aW9uQXJuIH0pO1xuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgc3RhdGljIGZyb21GdW5jdGlvbkF0dHJpYnV0ZXMoc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgYXR0cnM6IEZ1bmN0aW9uQXR0cmlidXRlcyk6IElGdW5jdGlvbiB7XG4gICAgY29uc3QgZnVuY3Rpb25Bcm4gPSBhdHRycy5mdW5jdGlvbkFybjtcbiAgICBjb25zdCBmdW5jdGlvbk5hbWUgPSBleHRyYWN0TmFtZUZyb21Bcm4oYXR0cnMuZnVuY3Rpb25Bcm4pO1xuICAgIGNvbnN0IHJvbGUgPSBhdHRycy5yb2xlO1xuXG4gICAgY2xhc3MgSW1wb3J0IGV4dGVuZHMgRnVuY3Rpb25CYXNlIHtcbiAgICAgIHB1YmxpYyByZWFkb25seSBmdW5jdGlvbk5hbWUgPSBmdW5jdGlvbk5hbWU7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgZnVuY3Rpb25Bcm4gPSBmdW5jdGlvbkFybjtcbiAgICAgIHB1YmxpYyByZWFkb25seSBncmFudFByaW5jaXBhbDogaWFtLklQcmluY2lwYWw7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgcm9sZSA9IHJvbGU7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgcGVybWlzc2lvbnNOb2RlID0gdGhpcy5ub2RlO1xuXG4gICAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgY2FuQ3JlYXRlUGVybWlzc2lvbnMgPSBhdHRycy5zYW1lRW52aXJvbm1lbnQgPz8gdGhpcy5faXNTdGFja0FjY291bnQoKTtcblxuICAgICAgY29uc3RydWN0b3IoczogQ29uc3RydWN0LCBpOiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIocywgaSk7XG5cbiAgICAgICAgdGhpcy5ncmFudFByaW5jaXBhbCA9IHJvbGUgfHwgbmV3IGlhbS5Vbmtub3duUHJpbmNpcGFsKHsgcmVzb3VyY2U6IHRoaXMgfSk7XG5cbiAgICAgICAgaWYgKGF0dHJzLnNlY3VyaXR5R3JvdXApIHtcbiAgICAgICAgICB0aGlzLl9jb25uZWN0aW9ucyA9IG5ldyBlYzIuQ29ubmVjdGlvbnMoe1xuICAgICAgICAgICAgc2VjdXJpdHlHcm91cHM6IFthdHRycy5zZWN1cml0eUdyb3VwXSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIGlmIChhdHRycy5zZWN1cml0eUdyb3VwSWQpIHtcbiAgICAgICAgICB0aGlzLl9jb25uZWN0aW9ucyA9IG5ldyBlYzIuQ29ubmVjdGlvbnMoe1xuICAgICAgICAgICAgc2VjdXJpdHlHcm91cHM6IFtlYzIuU2VjdXJpdHlHcm91cC5mcm9tU2VjdXJpdHlHcm91cElkKHNjb3BlLCAnU2VjdXJpdHlHcm91cCcsIGF0dHJzLnNlY3VyaXR5R3JvdXBJZCldLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBJbXBvcnQoc2NvcGUsIGlkKTtcbiAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgc3RhdGljIG1ldHJpY0FsbChtZXRyaWNOYW1lOiBzdHJpbmcsIHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWMge1xuICAgIHJldHVybiBuZXcgY2xvdWR3YXRjaC5NZXRyaWMoe1xuICAgICAgbmFtZXNwYWNlOiAnQVdTL0xhbWJkYScsXG4gICAgICBtZXRyaWNOYW1lLFxuICAgICAgLi4ucHJvcHMsXG4gICAgfSk7XG4gIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgc3RhdGljIG1ldHJpY0FsbEVycm9ycyhwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyk6IGNsb3Vkd2F0Y2guTWV0cmljIHtcbiAgICByZXR1cm4gdGhpcy5tZXRyaWNBbGwoJ0Vycm9ycycsIHsgc3RhdGlzdGljOiAnc3VtJywgLi4ucHJvcHMgfSk7XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHN0YXRpYyBtZXRyaWNBbGxEdXJhdGlvbihwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyk6IGNsb3Vkd2F0Y2guTWV0cmljIHtcbiAgICByZXR1cm4gdGhpcy5tZXRyaWNBbGwoJ0R1cmF0aW9uJywgcHJvcHMpO1xuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHN0YXRpYyBtZXRyaWNBbGxJbnZvY2F0aW9ucyhwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyk6IGNsb3Vkd2F0Y2guTWV0cmljIHtcbiAgICByZXR1cm4gdGhpcy5tZXRyaWNBbGwoJ0ludm9jYXRpb25zJywgeyBzdGF0aXN0aWM6ICdzdW0nLCAuLi5wcm9wcyB9KTtcbiAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgc3RhdGljIG1ldHJpY0FsbFRocm90dGxlcyhwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyk6IGNsb3Vkd2F0Y2guTWV0cmljIHtcbiAgICByZXR1cm4gdGhpcy5tZXRyaWNBbGwoJ1Rocm90dGxlcycsIHsgc3RhdGlzdGljOiAnc3VtJywgLi4ucHJvcHMgfSk7XG4gIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyBzdGF0aWMgbWV0cmljQWxsQ29uY3VycmVudEV4ZWN1dGlvbnMocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpOiBjbG91ZHdhdGNoLk1ldHJpYyB7XG4gICAgLy8gTWluaS1GQVE6IHdoeSBtYXg/IFRoaXMgbWV0cmljIGlzIGEgZ2F1Z2UgdGhhdCBpcyBlbWl0dGVkIGV2ZXJ5XG4gICAgLy8gbWludXRlLCBzbyBlaXRoZXIgbWF4IG9yIGF2ZyBvciBhIHBlcmNlbnRpbGUgbWFrZSBzZW5zZSAoYnV0IHN1bVxuICAgIC8vIGRvZXNuJ3QpLiBNYXggaXMgbW9yZSBzZW5zaXRpdmUgdG8gc3Bpa3kgbG9hZCBjaGFuZ2VzIHdoaWNoIGlzXG4gICAgLy8gcHJvYmFibHkgd2hhdCB5b3UncmUgaW50ZXJlc3RlZCBpbiBpZiB5b3UncmUgbG9va2luZyBhdCB0aGlzIG1ldHJpY1xuICAgIC8vIChMb2FkIHNwaWtlcyBtYXkgbGVhZCB0byBjb25jdXJyZW50IGV4ZWN1dGlvbiBlcnJvcnMgdGhhdCB3b3VsZFxuICAgIC8vIG90aGVyd2lzZSBub3QgYmUgdmlzaWJsZSBpbiB0aGUgYXZnKVxuICAgIHJldHVybiB0aGlzLm1ldHJpY0FsbCgnQ29uY3VycmVudEV4ZWN1dGlvbnMnLCB7IHN0YXRpc3RpYzogJ21heCcsIC4uLnByb3BzIH0pO1xuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyBzdGF0aWMgbWV0cmljQWxsVW5yZXNlcnZlZENvbmN1cnJlbnRFeGVjdXRpb25zKHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWMge1xuICAgIHJldHVybiB0aGlzLm1ldHJpY0FsbCgnVW5yZXNlcnZlZENvbmN1cnJlbnRFeGVjdXRpb25zJywgeyBzdGF0aXN0aWM6ICdtYXgnLCAuLi5wcm9wcyB9KTtcbiAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgcmVhZG9ubHkgZnVuY3Rpb25OYW1lOiBzdHJpbmc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHJlYWRvbmx5IGZ1bmN0aW9uQXJuOiBzdHJpbmc7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIHJlYWRvbmx5IHJvbGU/OiBpYW0uSVJvbGU7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyByZWFkb25seSBydW50aW1lOiBSdW50aW1lO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgcmVhZG9ubHkgZ3JhbnRQcmluY2lwYWw6IGlhbS5JUHJpbmNpcGFsO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyByZWFkb25seSBkZWFkTGV0dGVyUXVldWU/OiBzcXMuSVF1ZXVlO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICBwdWJsaWMgcmVhZG9ubHkgYXJjaGl0ZWN0dXJlPzogQXJjaGl0ZWN0dXJlO1xuICBwdWJsaWMgcmVhZG9ubHkgcGVybWlzc2lvbnNOb2RlID0gdGhpcy5ub2RlO1xuXG5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGNhbkNyZWF0ZVBlcm1pc3Npb25zID0gdHJ1ZTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGxheWVyczogSUxheWVyVmVyc2lvbltdID0gW107XG5cbiAgcHJpdmF0ZSBfbG9nR3JvdXA/OiBsb2dzLklMb2dHcm91cDtcblxuICAvKipcbiAgICogRW52aXJvbm1lbnQgdmFyaWFibGVzIGZvciB0aGlzIGZ1bmN0aW9uXG4gICAqL1xuICBwcml2YXRlIGVudmlyb25tZW50OiB7IFtrZXk6IHN0cmluZ106IEVudmlyb25tZW50Q29uZmlnIH0gPSB7fTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGN1cnJlbnRWZXJzaW9uT3B0aW9ucz86IFZlcnNpb25PcHRpb25zO1xuICBwcml2YXRlIF9jdXJyZW50VmVyc2lvbj86IFZlcnNpb247XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IEZ1bmN0aW9uUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQsIHtcbiAgICAgIHBoeXNpY2FsTmFtZTogcHJvcHMuZnVuY3Rpb25OYW1lLFxuICAgIH0pO1xuXG4gICAgY29uc3QgbWFuYWdlZFBvbGljaWVzID0gbmV3IEFycmF5PGlhbS5JTWFuYWdlZFBvbGljeT4oKTtcblxuICAgIC8vIHRoZSBhcm4gaXMgaW4gdGhlIGZvcm0gb2YgLSBhcm46YXdzOmlhbTo6YXdzOnBvbGljeS9zZXJ2aWNlLXJvbGUvQVdTTGFtYmRhQmFzaWNFeGVjdXRpb25Sb2xlXG4gICAgbWFuYWdlZFBvbGljaWVzLnB1c2goaWFtLk1hbmFnZWRQb2xpY3kuZnJvbUF3c01hbmFnZWRQb2xpY3lOYW1lKCdzZXJ2aWNlLXJvbGUvQVdTTGFtYmRhQmFzaWNFeGVjdXRpb25Sb2xlJykpO1xuXG4gICAgaWYgKHByb3BzLnZwYykge1xuICAgICAgLy8gUG9saWN5IHRoYXQgd2lsbCBoYXZlIEVOSSBjcmVhdGlvbiBwZXJtaXNzaW9uc1xuICAgICAgbWFuYWdlZFBvbGljaWVzLnB1c2goaWFtLk1hbmFnZWRQb2xpY3kuZnJvbUF3c01hbmFnZWRQb2xpY3lOYW1lKCdzZXJ2aWNlLXJvbGUvQVdTTGFtYmRhVlBDQWNjZXNzRXhlY3V0aW9uUm9sZScpKTtcbiAgICB9XG5cbiAgICB0aGlzLnJvbGUgPSBwcm9wcy5yb2xlIHx8IG5ldyBpYW0uUm9sZSh0aGlzLCAnU2VydmljZVJvbGUnLCB7XG4gICAgICBhc3N1bWVkQnk6IG5ldyBpYW0uU2VydmljZVByaW5jaXBhbCgnbGFtYmRhLmFtYXpvbmF3cy5jb20nKSxcbiAgICAgIG1hbmFnZWRQb2xpY2llcyxcbiAgICB9KTtcbiAgICB0aGlzLmdyYW50UHJpbmNpcGFsID0gdGhpcy5yb2xlO1xuXG4gICAgLy8gYWRkIGFkZGl0aW9uYWwgbWFuYWdlZCBwb2xpY2llcyB3aGVuIG5lY2Vzc2FyeVxuICAgIGlmIChwcm9wcy5maWxlc3lzdGVtKSB7XG4gICAgICBjb25zdCBjb25maWcgPSBwcm9wcy5maWxlc3lzdGVtLmNvbmZpZztcbiAgICAgIGlmIChjb25maWcucG9saWNpZXMpIHtcbiAgICAgICAgY29uZmlnLnBvbGljaWVzLmZvckVhY2gocCA9PiB7XG4gICAgICAgICAgdGhpcy5yb2xlPy5hZGRUb1ByaW5jaXBhbFBvbGljeShwKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBzdGF0ZW1lbnQgb2YgKHByb3BzLmluaXRpYWxQb2xpY3kgfHwgW10pKSB7XG4gICAgICB0aGlzLnJvbGUuYWRkVG9QcmluY2lwYWxQb2xpY3koc3RhdGVtZW50KTtcbiAgICB9XG5cbiAgICBjb25zdCBjb2RlID0gcHJvcHMuY29kZS5iaW5kKHRoaXMpO1xuICAgIHZlcmlmeUNvZGVDb25maWcoY29kZSwgcHJvcHMpO1xuXG4gICAgbGV0IHByb2ZpbGluZ0dyb3VwRW52aXJvbm1lbnRWYXJpYWJsZXM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gPSB7fTtcbiAgICBpZiAocHJvcHMucHJvZmlsaW5nR3JvdXAgJiYgcHJvcHMucHJvZmlsaW5nICE9PSBmYWxzZSkge1xuICAgICAgdGhpcy52YWxpZGF0ZVByb2ZpbGluZyhwcm9wcyk7XG4gICAgICBwcm9wcy5wcm9maWxpbmdHcm91cC5ncmFudFB1Ymxpc2godGhpcy5yb2xlKTtcbiAgICAgIHByb2ZpbGluZ0dyb3VwRW52aXJvbm1lbnRWYXJpYWJsZXMgPSB7XG4gICAgICAgIEFXU19DT0RFR1VSVV9QUk9GSUxFUl9HUk9VUF9BUk46IFN0YWNrLm9mKHNjb3BlKS5mb3JtYXRBcm4oe1xuICAgICAgICAgIHNlcnZpY2U6ICdjb2RlZ3VydS1wcm9maWxlcicsXG4gICAgICAgICAgcmVzb3VyY2U6ICdwcm9maWxpbmdHcm91cCcsXG4gICAgICAgICAgcmVzb3VyY2VOYW1lOiBwcm9wcy5wcm9maWxpbmdHcm91cC5wcm9maWxpbmdHcm91cE5hbWUsXG4gICAgICAgIH0pLFxuICAgICAgICBBV1NfQ09ERUdVUlVfUFJPRklMRVJfRU5BQkxFRDogJ1RSVUUnLFxuICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKHByb3BzLnByb2ZpbGluZykge1xuICAgICAgdGhpcy52YWxpZGF0ZVByb2ZpbGluZyhwcm9wcyk7XG4gICAgICBjb25zdCBwcm9maWxpbmdHcm91cCA9IG5ldyBQcm9maWxpbmdHcm91cCh0aGlzLCAnUHJvZmlsaW5nR3JvdXAnLCB7XG4gICAgICAgIGNvbXB1dGVQbGF0Zm9ybTogQ29tcHV0ZVBsYXRmb3JtLkFXU19MQU1CREEsXG4gICAgICB9KTtcbiAgICAgIHByb2ZpbGluZ0dyb3VwLmdyYW50UHVibGlzaCh0aGlzLnJvbGUpO1xuICAgICAgcHJvZmlsaW5nR3JvdXBFbnZpcm9ubWVudFZhcmlhYmxlcyA9IHtcbiAgICAgICAgQVdTX0NPREVHVVJVX1BST0ZJTEVSX0dST1VQX0FSTjogcHJvZmlsaW5nR3JvdXAucHJvZmlsaW5nR3JvdXBBcm4sXG4gICAgICAgIEFXU19DT0RFR1VSVV9QUk9GSUxFUl9FTkFCTEVEOiAnVFJVRScsXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNvbnN0IGVudiA9IHsgLi4ucHJvZmlsaW5nR3JvdXBFbnZpcm9ubWVudFZhcmlhYmxlcywgLi4ucHJvcHMuZW52aXJvbm1lbnQgfTtcbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhlbnYpKSB7XG4gICAgICB0aGlzLmFkZEVudmlyb25tZW50KGtleSwgdmFsdWUpO1xuICAgIH1cblxuICAgIHRoaXMuZGVhZExldHRlclF1ZXVlID0gdGhpcy5idWlsZERlYWRMZXR0ZXJRdWV1ZShwcm9wcyk7XG5cbiAgICBsZXQgZmlsZVN5c3RlbUNvbmZpZ3M6IENmbkZ1bmN0aW9uLkZpbGVTeXN0ZW1Db25maWdQcm9wZXJ0eVtdIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIGlmIChwcm9wcy5maWxlc3lzdGVtKSB7XG4gICAgICBmaWxlU3lzdGVtQ29uZmlncyA9IFt7XG4gICAgICAgIGFybjogcHJvcHMuZmlsZXN5c3RlbS5jb25maWcuYXJuLFxuICAgICAgICBsb2NhbE1vdW50UGF0aDogcHJvcHMuZmlsZXN5c3RlbS5jb25maWcubG9jYWxNb3VudFBhdGgsXG4gICAgICB9XTtcbiAgICB9XG5cbiAgICBpZiAocHJvcHMuYXJjaGl0ZWN0dXJlICYmIHByb3BzLmFyY2hpdGVjdHVyZXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFaXRoZXIgYXJjaGl0ZWN0dXJlIG9yIGFyY2hpdGVjdHVyZXMgbXVzdCBiZSBzcGVjaWZpZWQgYnV0IG5vdCBib3RoLicpO1xuICAgIH1cbiAgICBpZiAocHJvcHMuYXJjaGl0ZWN0dXJlcyAmJiBwcm9wcy5hcmNoaXRlY3R1cmVzLmxlbmd0aCA+IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignT25seSBvbmUgYXJjaGl0ZWN0dXJlIG11c3QgYmUgc3BlY2lmaWVkLicpO1xuICAgIH1cbiAgICBjb25zdCBhcmNoaXRlY3R1cmUgPSBwcm9wcy5hcmNoaXRlY3R1cmUgPz8gKHByb3BzLmFyY2hpdGVjdHVyZXMgJiYgcHJvcHMuYXJjaGl0ZWN0dXJlc1swXSk7XG5cbiAgICBjb25zdCByZXNvdXJjZTogQ2ZuRnVuY3Rpb24gPSBuZXcgQ2ZuRnVuY3Rpb24odGhpcywgJ1Jlc291cmNlJywge1xuICAgICAgZnVuY3Rpb25OYW1lOiB0aGlzLnBoeXNpY2FsTmFtZSxcbiAgICAgIGRlc2NyaXB0aW9uOiBwcm9wcy5kZXNjcmlwdGlvbixcbiAgICAgIGNvZGU6IHtcbiAgICAgICAgczNCdWNrZXQ6IGNvZGUuczNMb2NhdGlvbiAmJiBjb2RlLnMzTG9jYXRpb24uYnVja2V0TmFtZSxcbiAgICAgICAgczNLZXk6IGNvZGUuczNMb2NhdGlvbiAmJiBjb2RlLnMzTG9jYXRpb24ub2JqZWN0S2V5LFxuICAgICAgICBzM09iamVjdFZlcnNpb246IGNvZGUuczNMb2NhdGlvbiAmJiBjb2RlLnMzTG9jYXRpb24ub2JqZWN0VmVyc2lvbixcbiAgICAgICAgemlwRmlsZTogY29kZS5pbmxpbmVDb2RlLFxuICAgICAgICBpbWFnZVVyaTogY29kZS5pbWFnZT8uaW1hZ2VVcmksXG4gICAgICB9LFxuICAgICAgbGF5ZXJzOiBMYXp5Lmxpc3QoeyBwcm9kdWNlOiAoKSA9PiB0aGlzLmxheWVycy5tYXAobGF5ZXIgPT4gbGF5ZXIubGF5ZXJWZXJzaW9uQXJuKSB9LCB7IG9taXRFbXB0eTogdHJ1ZSB9KSwgLy8gRXZhbHVhdGVkIG9uIHN5bnRoZXNpc1xuICAgICAgaGFuZGxlcjogcHJvcHMuaGFuZGxlciA9PT0gSGFuZGxlci5GUk9NX0lNQUdFID8gdW5kZWZpbmVkIDogcHJvcHMuaGFuZGxlcixcbiAgICAgIHRpbWVvdXQ6IHByb3BzLnRpbWVvdXQgJiYgcHJvcHMudGltZW91dC50b1NlY29uZHMoKSxcbiAgICAgIHBhY2thZ2VUeXBlOiBwcm9wcy5ydW50aW1lID09PSBSdW50aW1lLkZST01fSU1BR0UgPyAnSW1hZ2UnIDogdW5kZWZpbmVkLFxuICAgICAgcnVudGltZTogcHJvcHMucnVudGltZSA9PT0gUnVudGltZS5GUk9NX0lNQUdFID8gdW5kZWZpbmVkIDogcHJvcHMucnVudGltZS5uYW1lLFxuICAgICAgcm9sZTogdGhpcy5yb2xlLnJvbGVBcm4sXG4gICAgICAvLyBVbmNhY2hlZCBiZWNhdXNlIGNhbGxpbmcgJ19jaGVja0VkZ2VDb21wYXRpYmlsaXR5Jywgd2hpY2ggZ2V0cyBjYWxsZWQgaW4gdGhlIHJlc29sdmUgb2YgYW5vdGhlclxuICAgICAgLy8gVG9rZW4sIGFjdHVhbGx5ICptb2RpZmllcyogdGhlICdlbnZpcm9ubWVudCcgbWFwLlxuICAgICAgZW52aXJvbm1lbnQ6IExhenkudW5jYWNoZWRBbnkoeyBwcm9kdWNlOiAoKSA9PiB0aGlzLnJlbmRlckVudmlyb25tZW50KCkgfSksXG4gICAgICBtZW1vcnlTaXplOiBwcm9wcy5tZW1vcnlTaXplLFxuICAgICAgdnBjQ29uZmlnOiB0aGlzLmNvbmZpZ3VyZVZwYyhwcm9wcyksXG4gICAgICBkZWFkTGV0dGVyQ29uZmlnOiB0aGlzLmJ1aWxkRGVhZExldHRlckNvbmZpZyh0aGlzLmRlYWRMZXR0ZXJRdWV1ZSksXG4gICAgICB0cmFjaW5nQ29uZmlnOiB0aGlzLmJ1aWxkVHJhY2luZ0NvbmZpZyhwcm9wcyksXG4gICAgICByZXNlcnZlZENvbmN1cnJlbnRFeGVjdXRpb25zOiBwcm9wcy5yZXNlcnZlZENvbmN1cnJlbnRFeGVjdXRpb25zLFxuICAgICAgaW1hZ2VDb25maWc6IHVuZGVmaW5lZElmTm9LZXlzKHtcbiAgICAgICAgY29tbWFuZDogY29kZS5pbWFnZT8uY21kLFxuICAgICAgICBlbnRyeVBvaW50OiBjb2RlLmltYWdlPy5lbnRyeXBvaW50LFxuICAgICAgICB3b3JraW5nRGlyZWN0b3J5OiBjb2RlLmltYWdlPy53b3JraW5nRGlyZWN0b3J5LFxuICAgICAgfSksXG4gICAgICBrbXNLZXlBcm46IHByb3BzLmVudmlyb25tZW50RW5jcnlwdGlvbj8ua2V5QXJuLFxuICAgICAgZmlsZVN5c3RlbUNvbmZpZ3MsXG4gICAgICBjb2RlU2lnbmluZ0NvbmZpZ0FybjogcHJvcHMuY29kZVNpZ25pbmdDb25maWc/LmNvZGVTaWduaW5nQ29uZmlnQXJuLFxuICAgICAgYXJjaGl0ZWN0dXJlczogYXJjaGl0ZWN0dXJlID8gW2FyY2hpdGVjdHVyZS5uYW1lXSA6IHVuZGVmaW5lZCxcbiAgICB9KTtcblxuICAgIHJlc291cmNlLm5vZGUuYWRkRGVwZW5kZW5jeSh0aGlzLnJvbGUpO1xuXG4gICAgdGhpcy5mdW5jdGlvbk5hbWUgPSB0aGlzLmdldFJlc291cmNlTmFtZUF0dHJpYnV0ZShyZXNvdXJjZS5yZWYpO1xuICAgIHRoaXMuZnVuY3Rpb25Bcm4gPSB0aGlzLmdldFJlc291cmNlQXJuQXR0cmlidXRlKHJlc291cmNlLmF0dHJBcm4sIHtcbiAgICAgIHNlcnZpY2U6ICdsYW1iZGEnLFxuICAgICAgcmVzb3VyY2U6ICdmdW5jdGlvbicsXG4gICAgICByZXNvdXJjZU5hbWU6IHRoaXMucGh5c2ljYWxOYW1lLFxuICAgICAgYXJuRm9ybWF0OiBBcm5Gb3JtYXQuQ09MT05fUkVTT1VSQ0VfTkFNRSxcbiAgICB9KTtcblxuICAgIHRoaXMucnVudGltZSA9IHByb3BzLnJ1bnRpbWU7XG5cbiAgICB0aGlzLmFyY2hpdGVjdHVyZSA9IHByb3BzLmFyY2hpdGVjdHVyZTtcblxuICAgIGlmIChwcm9wcy5sYXllcnMpIHtcbiAgICAgIGlmIChwcm9wcy5ydW50aW1lID09PSBSdW50aW1lLkZST01fSU1BR0UpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdMYXllcnMgYXJlIG5vdCBzdXBwb3J0ZWQgZm9yIGNvbnRhaW5lciBpbWFnZSBmdW5jdGlvbnMnKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5hZGRMYXllcnMoLi4ucHJvcHMubGF5ZXJzKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGV2ZW50IG9mIHByb3BzLmV2ZW50cyB8fCBbXSkge1xuICAgICAgdGhpcy5hZGRFdmVudFNvdXJjZShldmVudCk7XG4gICAgfVxuXG4gICAgLy8gTG9nIHJldGVudGlvblxuICAgIGlmIChwcm9wcy5sb2dSZXRlbnRpb24pIHtcbiAgICAgIGNvbnN0IGxvZ1JldGVudGlvbiA9IG5ldyBsb2dzLkxvZ1JldGVudGlvbih0aGlzLCAnTG9nUmV0ZW50aW9uJywge1xuICAgICAgICBsb2dHcm91cE5hbWU6IGAvYXdzL2xhbWJkYS8ke3RoaXMuZnVuY3Rpb25OYW1lfWAsXG4gICAgICAgIHJldGVudGlvbjogcHJvcHMubG9nUmV0ZW50aW9uLFxuICAgICAgICByb2xlOiBwcm9wcy5sb2dSZXRlbnRpb25Sb2xlLFxuICAgICAgICBsb2dSZXRlbnRpb25SZXRyeU9wdGlvbnM6IHByb3BzLmxvZ1JldGVudGlvblJldHJ5T3B0aW9ucyBhcyBsb2dzLkxvZ1JldGVudGlvblJldHJ5T3B0aW9ucyxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5fbG9nR3JvdXAgPSBsb2dzLkxvZ0dyb3VwLmZyb21Mb2dHcm91cEFybih0aGlzLCAnTG9nR3JvdXAnLCBsb2dSZXRlbnRpb24ubG9nR3JvdXBBcm4pO1xuICAgIH1cblxuICAgIHByb3BzLmNvZGUuYmluZFRvUmVzb3VyY2UocmVzb3VyY2UpO1xuXG4gICAgLy8gRXZlbnQgSW52b2tlIENvbmZpZ1xuICAgIGlmIChwcm9wcy5vbkZhaWx1cmUgfHwgcHJvcHMub25TdWNjZXNzIHx8IHByb3BzLm1heEV2ZW50QWdlIHx8IHByb3BzLnJldHJ5QXR0ZW1wdHMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5jb25maWd1cmVBc3luY0ludm9rZSh7XG4gICAgICAgIG9uRmFpbHVyZTogcHJvcHMub25GYWlsdXJlLFxuICAgICAgICBvblN1Y2Nlc3M6IHByb3BzLm9uU3VjY2VzcyxcbiAgICAgICAgbWF4RXZlbnRBZ2U6IHByb3BzLm1heEV2ZW50QWdlLFxuICAgICAgICByZXRyeUF0dGVtcHRzOiBwcm9wcy5yZXRyeUF0dGVtcHRzLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5jdXJyZW50VmVyc2lvbk9wdGlvbnMgPSBwcm9wcy5jdXJyZW50VmVyc2lvbk9wdGlvbnM7XG5cbiAgICBpZiAocHJvcHMuZmlsZXN5c3RlbSkge1xuICAgICAgaWYgKCFwcm9wcy52cGMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgY29uZmlndXJlIFxcJ2ZpbGVzeXN0ZW1cXCcgd2l0aG91dCBjb25maWd1cmluZyBhIFZQQy4nKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGNvbmZpZyA9IHByb3BzLmZpbGVzeXN0ZW0uY29uZmlnO1xuICAgICAgaWYgKGNvbmZpZy5kZXBlbmRlbmN5KSB7XG4gICAgICAgIHRoaXMubm9kZS5hZGREZXBlbmRlbmN5KC4uLmNvbmZpZy5kZXBlbmRlbmN5KTtcbiAgICAgIH1cbiAgICAgIC8vIFRoZXJlIGNvdWxkIGJlIGEgcmFjZSBpZiB0aGUgTGFtYmRhIGlzIHVzZWQgaW4gYSBDdXN0b21SZXNvdXJjZS4gSXQgaXMgcG9zc2libGUgZm9yIHRoZSBMYW1iZGEgdG9cbiAgICAgIC8vIGZhaWwgdG8gYXR0YWNoIHRvIGEgZ2l2ZW4gRmlsZVN5c3RlbSBpZiB3ZSBkbyBub3QgaGF2ZSBhIGRlcGVuZGVuY3kgb24gdGhlIFNlY3VyaXR5R3JvdXAgaW5ncmVzcy9lZ3Jlc3NcbiAgICAgIC8vIHJ1bGVzIHRoYXQgd2VyZSBjcmVhdGVkIGJldHdlZW4gdGhpcyBMYW1iZGEncyBTRyAmIHRoZSBGaWxlc3lzdGVtIFNHLlxuICAgICAgdGhpcy5jb25uZWN0aW9ucy5zZWN1cml0eUdyb3Vwcy5mb3JFYWNoKHNnID0+IHtcbiAgICAgICAgc2cubm9kZS5maW5kQWxsKCkuZm9yRWFjaChjaGlsZCA9PiB7XG4gICAgICAgICAgaWYgKGNoaWxkIGluc3RhbmNlb2YgQ2ZuUmVzb3VyY2UgJiYgY2hpbGQuY2ZuUmVzb3VyY2VUeXBlID09PSAnQVdTOjpFQzI6OlNlY3VyaXR5R3JvdXBFZ3Jlc3MnKSB7XG4gICAgICAgICAgICByZXNvdXJjZS5ub2RlLmFkZERlcGVuZGVuY3koY2hpbGQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIGNvbmZpZy5jb25uZWN0aW9ucz8uc2VjdXJpdHlHcm91cHMuZm9yRWFjaChzZyA9PiB7XG4gICAgICAgIHNnLm5vZGUuZmluZEFsbCgpLmZvckVhY2goY2hpbGQgPT4ge1xuICAgICAgICAgIGlmIChjaGlsZCBpbnN0YW5jZW9mIENmblJlc291cmNlICYmIGNoaWxkLmNmblJlc291cmNlVHlwZSA9PT0gJ0FXUzo6RUMyOjpTZWN1cml0eUdyb3VwSW5ncmVzcycpIHtcbiAgICAgICAgICAgIHJlc291cmNlLm5vZGUuYWRkRGVwZW5kZW5jeShjaGlsZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIENvbmZpZ3VyZSBMYW1iZGEgaW5zaWdodHNcbiAgICB0aGlzLmNvbmZpZ3VyZUxhbWJkYUluc2lnaHRzKHByb3BzKTtcbiAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcbiAgcHVibGljIGFkZEVudmlyb25tZW50KGtleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nLCBvcHRpb25zPzogRW52aXJvbm1lbnRPcHRpb25zKTogdGhpcyB7XG4gICAgdGhpcy5lbnZpcm9ubWVudFtrZXldID0geyB2YWx1ZSwgLi4ub3B0aW9ucyB9O1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyBhZGRMYXllcnMoLi4ubGF5ZXJzOiBJTGF5ZXJWZXJzaW9uW10pOiB2b2lkIHtcbiAgICBmb3IgKGNvbnN0IGxheWVyIG9mIGxheWVycykge1xuICAgICAgaWYgKHRoaXMubGF5ZXJzLmxlbmd0aCA9PT0gNSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VuYWJsZSB0byBhZGQgbGF5ZXI6IHRoaXMgbGFtYmRhIGZ1bmN0aW9uIGFscmVhZHkgdXNlcyA1IGxheWVycy4nKTtcbiAgICAgIH1cbiAgICAgIGlmIChsYXllci5jb21wYXRpYmxlUnVudGltZXMgJiYgIWxheWVyLmNvbXBhdGlibGVSdW50aW1lcy5maW5kKHJ1bnRpbWUgPT4gcnVudGltZS5ydW50aW1lRXF1YWxzKHRoaXMucnVudGltZSkpKSB7XG4gICAgICAgIGNvbnN0IHJ1bnRpbWVzID0gbGF5ZXIuY29tcGF0aWJsZVJ1bnRpbWVzLm1hcChydW50aW1lID0+IHJ1bnRpbWUubmFtZSkuam9pbignLCAnKTtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGlzIGxhbWJkYSBmdW5jdGlvbiB1c2VzIGEgcnVudGltZSB0aGF0IGlzIGluY29tcGF0aWJsZSB3aXRoIHRoaXMgbGF5ZXIgKCR7dGhpcy5ydW50aW1lLm5hbWV9IGlzIG5vdCBpbiBbJHtydW50aW1lc31dKWApO1xuICAgICAgfVxuXG4gICAgICAvLyBDdXJyZW50bHkgbm8gdmFsaWRhdGlvbnMgZm9yIGNvbXBhdGlibGUgYXJjaGl0ZWN0dXJlcyBzaW5jZSBMYW1iZGEgc2VydmljZVxuICAgICAgLy8gYWxsb3dzIGxheWVycyBjb25maWd1cmVkIHdpdGggb25lIGFyY2hpdGVjdHVyZSB0byBiZSB1c2VkIHdpdGggYSBMYW1iZGEgZnVuY3Rpb25cbiAgICAgIC8vIGZyb20gYW5vdGhlciBhcmNoaXRlY3R1cmUuXG5cbiAgICAgIHRoaXMubGF5ZXJzLnB1c2gobGF5ZXIpO1xuICAgIH1cbiAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyBhZGRWZXJzaW9uKFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBjb2RlU2hhMjU2Pzogc3RyaW5nLFxuICAgIGRlc2NyaXB0aW9uPzogc3RyaW5nLFxuICAgIHByb3Zpc2lvbmVkRXhlY3V0aW9ucz86IG51bWJlcixcbiAgICBhc3luY0ludm9rZUNvbmZpZzogRXZlbnRJbnZva2VDb25maWdPcHRpb25zID0ge30pOiBWZXJzaW9uIHtcblxuICAgIHJldHVybiBuZXcgVmVyc2lvbih0aGlzLCAnVmVyc2lvbicgKyBuYW1lLCB7XG4gICAgICBsYW1iZGE6IHRoaXMsXG4gICAgICBjb2RlU2hhMjU2LFxuICAgICAgZGVzY3JpcHRpb24sXG4gICAgICBwcm92aXNpb25lZENvbmN1cnJlbnRFeGVjdXRpb25zOiBwcm92aXNpb25lZEV4ZWN1dGlvbnMsXG4gICAgICAuLi5hc3luY0ludm9rZUNvbmZpZyxcbiAgICB9KTtcbiAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHB1YmxpYyBnZXQgbG9nR3JvdXAoKTogbG9ncy5JTG9nR3JvdXAge1xuICAgIGlmICghdGhpcy5fbG9nR3JvdXApIHtcbiAgICAgIGNvbnN0IGxvZ1JldGVudGlvbiA9IG5ldyBsb2dzLkxvZ1JldGVudGlvbih0aGlzLCAnTG9nUmV0ZW50aW9uJywge1xuICAgICAgICBsb2dHcm91cE5hbWU6IGAvYXdzL2xhbWJkYS8ke3RoaXMuZnVuY3Rpb25OYW1lfWAsXG4gICAgICAgIHJldGVudGlvbjogbG9ncy5SZXRlbnRpb25EYXlzLklORklOSVRFLFxuICAgICAgfSk7XG4gICAgICB0aGlzLl9sb2dHcm91cCA9IGxvZ3MuTG9nR3JvdXAuZnJvbUxvZ0dyb3VwQXJuKHRoaXMsIGAke3RoaXMubm9kZS5pZH0tTG9nR3JvdXBgLCBsb2dSZXRlbnRpb24ubG9nR3JvdXBBcm4pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fbG9nR3JvdXA7XG4gIH1cblxuICAvKiogQGludGVybmFsICovXG4gIHB1YmxpYyBfY2hlY2tFZGdlQ29tcGF0aWJpbGl0eSgpOiB2b2lkIHtcbiAgICAvLyBDaGVjayBlbnYgdmFyc1xuICAgIGNvbnN0IGVudkVudHJpZXMgPSBPYmplY3QuZW50cmllcyh0aGlzLmVudmlyb25tZW50KTtcbiAgICBmb3IgKGNvbnN0IFtrZXksIGNvbmZpZ10gb2YgZW52RW50cmllcykge1xuICAgICAgaWYgKGNvbmZpZy5yZW1vdmVJbkVkZ2UpIHtcbiAgICAgICAgZGVsZXRlIHRoaXMuZW52aXJvbm1lbnRba2V5XTtcbiAgICAgICAgQW5ub3RhdGlvbnMub2YodGhpcykuYWRkSW5mbyhgUmVtb3ZlZCAke2tleX0gZW52aXJvbm1lbnQgdmFyaWFibGUgZm9yIExhbWJkYUBFZGdlIGNvbXBhdGliaWxpdHlgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgZW52S2V5cyA9IE9iamVjdC5rZXlzKHRoaXMuZW52aXJvbm1lbnQpO1xuICAgIGlmIChlbnZLZXlzLmxlbmd0aCAhPT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgZnVuY3Rpb24gJHt0aGlzLm5vZGUucGF0aH0gY29udGFpbnMgZW52aXJvbm1lbnQgdmFyaWFibGVzIFske2VudktleXN9XSBhbmQgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBMYW1iZGFARWRnZS4gXFxcbkVudmlyb25tZW50IHZhcmlhYmxlcyBjYW4gYmUgbWFya2VkIGZvciByZW1vdmFsIHdoZW4gdXNlZCBpbiBMYW1iZGFARWRnZSBieSBzZXR0aW5nIHRoZSBcXCdyZW1vdmVJbkVkZ2VcXCcgcHJvcGVydHkgaW4gdGhlIFxcJ2FkZEVudmlyb25tZW50KClcXCcgQVBJLmApO1xuICAgIH1cblxuICAgIHJldHVybjtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25maWd1cmVkIGxhbWJkYSBpbnNpZ2h0cyBvbiB0aGUgZnVuY3Rpb24gaWYgc3BlY2lmaWVkLiBUaGlzIGlzIGFjaGVpdmVkIGJ5IGFkZGluZyBhbiBpbXBvcnRlZCBsYXllciB3aGljaCBpcyBhZGRlZCB0byB0aGVcbiAgICogbGlzdCBvZiBsYW1iZGEgbGF5ZXJzIG9uIHN5bnRoZXNpcy5cbiAgICpcbiAgICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkNsb3VkV2F0Y2gvbGF0ZXN0L21vbml0b3JpbmcvTGFtYmRhLUluc2lnaHRzLWV4dGVuc2lvbi12ZXJzaW9ucy5odG1sXG4gICAqL1xuICBwcml2YXRlIGNvbmZpZ3VyZUxhbWJkYUluc2lnaHRzKHByb3BzOiBGdW5jdGlvblByb3BzKTogdm9pZCB7XG4gICAgaWYgKHByb3BzLmluc2lnaHRzVmVyc2lvbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChwcm9wcy5ydW50aW1lICE9PSBSdW50aW1lLkZST01fSU1BR0UpIHtcbiAgICAgIC8vIExheWVycyBjYW5ub3QgYmUgYWRkZWQgdG8gTGFtYmRhIGNvbnRhaW5lciBpbWFnZXMuIFRoZSBpbWFnZSBzaG91bGQgaGF2ZSB0aGUgaW5zaWdodHMgYWdlbnQgaW5zdGFsbGVkLlxuICAgICAgLy8gU2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25DbG91ZFdhdGNoL2xhdGVzdC9tb25pdG9yaW5nL0xhbWJkYS1JbnNpZ2h0cy1HZXR0aW5nLVN0YXJ0ZWQtZG9ja2VyLmh0bWxcbiAgICAgIHRoaXMuYWRkTGF5ZXJzKExheWVyVmVyc2lvbi5mcm9tTGF5ZXJWZXJzaW9uQXJuKHRoaXMsICdMYW1iZGFJbnNpZ2h0c0xheWVyJywgcHJvcHMuaW5zaWdodHNWZXJzaW9uLmxheWVyVmVyc2lvbkFybikpO1xuICAgIH1cbiAgICB0aGlzLnJvbGU/LmFkZE1hbmFnZWRQb2xpY3koaWFtLk1hbmFnZWRQb2xpY3kuZnJvbUF3c01hbmFnZWRQb2xpY3lOYW1lKCdDbG91ZFdhdGNoTGFtYmRhSW5zaWdodHNFeGVjdXRpb25Sb2xlUG9saWN5JykpO1xuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJFbnZpcm9ubWVudCgpIHtcbiAgICBpZiAoIXRoaXMuZW52aXJvbm1lbnQgfHwgT2JqZWN0LmtleXModGhpcy5lbnZpcm9ubWVudCkubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGNvbnN0IHZhcmlhYmxlczogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSA9IHt9O1xuICAgIC8vIFNvcnQgZW52aXJvbm1lbnQgc28gdGhlIGhhc2ggb2YgdGhlIGZ1bmN0aW9uIHVzZWQgdG8gY3JlYXRlXG4gICAgLy8gYGN1cnJlbnRWZXJzaW9uYCBpcyBub3QgYWZmZWN0ZWQgYnkga2V5IG9yZGVyICh0aGlzIGlzIGhvdyBsYW1iZGEgZG9lc1xuICAgIC8vIGl0KS4gRm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IHdlIGRvIG5vdCBzb3J0IGVudmlyb25tZW50IHZhcmlhYmxlcyBpbiBjYXNlXG4gICAgLy8gX2N1cnJlbnRWZXJzaW9uIGlzIG5vdCBkZWZpbmVkLiBPdGhlcndpc2UsIHRoaXMgd291bGQgaGF2ZSBpbnZhbGlkYXRlZFxuICAgIC8vIHRoZSB0ZW1wbGF0ZSwgYW5kIGZvciBleGFtcGxlLCBtYXkgY2F1c2UgdW5uZWVkZWQgdXBkYXRlcyBmb3IgbmVzdGVkXG4gICAgLy8gc3RhY2tzLlxuICAgIGNvbnN0IGtleXMgPSB0aGlzLl9jdXJyZW50VmVyc2lvblxuICAgICAgPyBPYmplY3Qua2V5cyh0aGlzLmVudmlyb25tZW50KS5zb3J0KClcbiAgICAgIDogT2JqZWN0LmtleXModGhpcy5lbnZpcm9ubWVudCk7XG5cbiAgICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzKSB7XG4gICAgICB2YXJpYWJsZXNba2V5XSA9IHRoaXMuZW52aXJvbm1lbnRba2V5XS52YWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4geyB2YXJpYWJsZXMgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJZiBjb25maWd1cmVkLCBzZXQgdXAgdGhlIFZQQy1yZWxhdGVkIHByb3BlcnRpZXNcbiAgICpcbiAgICogUmV0dXJucyB0aGUgVnBjQ29uZmlnIHRoYXQgc2hvdWxkIGJlIGFkZGVkIHRvIHRoZVxuICAgKiBMYW1iZGEgY3JlYXRpb24gcHJvcGVydGllcy5cbiAgICovXG4gIHByaXZhdGUgY29uZmlndXJlVnBjKHByb3BzOiBGdW5jdGlvblByb3BzKTogQ2ZuRnVuY3Rpb24uVnBjQ29uZmlnUHJvcGVydHkgfCB1bmRlZmluZWQge1xuICAgIGlmICgocHJvcHMuc2VjdXJpdHlHcm91cCB8fCBwcm9wcy5hbGxvd0FsbE91dGJvdW5kICE9PSB1bmRlZmluZWQpICYmICFwcm9wcy52cGMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGNvbmZpZ3VyZSBcXCdzZWN1cml0eUdyb3VwXFwnIG9yIFxcJ2FsbG93QWxsT3V0Ym91bmRcXCcgd2l0aG91dCBjb25maWd1cmluZyBhIFZQQycpO1xuICAgIH1cblxuICAgIGlmICghcHJvcHMudnBjKSB7IHJldHVybiB1bmRlZmluZWQ7IH1cblxuICAgIGlmIChwcm9wcy5zZWN1cml0eUdyb3VwICYmIHByb3BzLmFsbG93QWxsT3V0Ym91bmQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb25maWd1cmUgXFwnYWxsb3dBbGxPdXRib3VuZFxcJyBkaXJlY3RseSBvbiB0aGUgc3VwcGxpZWQgU2VjdXJpdHlHcm91cC4nKTtcbiAgICB9XG5cbiAgICBsZXQgc2VjdXJpdHlHcm91cHM6IGVjMi5JU2VjdXJpdHlHcm91cFtdO1xuXG4gICAgaWYgKHByb3BzLnNlY3VyaXR5R3JvdXAgJiYgcHJvcHMuc2VjdXJpdHlHcm91cHMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignT25seSBvbmUgb2YgdGhlIGZ1bmN0aW9uIHByb3BzLCBzZWN1cml0eUdyb3VwIG9yIHNlY3VyaXR5R3JvdXBzLCBpcyBhbGxvd2VkJyk7XG4gICAgfVxuXG4gICAgaWYgKHByb3BzLnNlY3VyaXR5R3JvdXBzKSB7XG4gICAgICBzZWN1cml0eUdyb3VwcyA9IHByb3BzLnNlY3VyaXR5R3JvdXBzO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBzZWN1cml0eUdyb3VwID0gcHJvcHMuc2VjdXJpdHlHcm91cCB8fCBuZXcgZWMyLlNlY3VyaXR5R3JvdXAodGhpcywgJ1NlY3VyaXR5R3JvdXAnLCB7XG4gICAgICAgIHZwYzogcHJvcHMudnBjLFxuICAgICAgICBkZXNjcmlwdGlvbjogJ0F1dG9tYXRpYyBzZWN1cml0eSBncm91cCBmb3IgTGFtYmRhIEZ1bmN0aW9uICcgKyBOYW1lcy51bmlxdWVJZCh0aGlzKSxcbiAgICAgICAgYWxsb3dBbGxPdXRib3VuZDogcHJvcHMuYWxsb3dBbGxPdXRib3VuZCxcbiAgICAgIH0pO1xuICAgICAgc2VjdXJpdHlHcm91cHMgPSBbc2VjdXJpdHlHcm91cF07XG4gICAgfVxuXG4gICAgdGhpcy5fY29ubmVjdGlvbnMgPSBuZXcgZWMyLkNvbm5lY3Rpb25zKHsgc2VjdXJpdHlHcm91cHMgfSk7XG5cbiAgICBpZiAocHJvcHMuZmlsZXN5c3RlbSkge1xuICAgICAgaWYgKHByb3BzLmZpbGVzeXN0ZW0uY29uZmlnLmNvbm5lY3Rpb25zKSB7XG4gICAgICAgIHByb3BzLmZpbGVzeXN0ZW0uY29uZmlnLmNvbm5lY3Rpb25zLmFsbG93RGVmYXVsdFBvcnRGcm9tKHRoaXMpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGFsbG93UHVibGljU3VibmV0ID0gcHJvcHMuYWxsb3dQdWJsaWNTdWJuZXQgPz8gZmFsc2U7XG4gICAgY29uc3QgeyBzdWJuZXRJZHMgfSA9IHByb3BzLnZwYy5zZWxlY3RTdWJuZXRzKHByb3BzLnZwY1N1Ym5ldHMpO1xuICAgIGNvbnN0IHB1YmxpY1N1Ym5ldElkcyA9IG5ldyBTZXQocHJvcHMudnBjLnB1YmxpY1N1Ym5ldHMubWFwKHMgPT4gcy5zdWJuZXRJZCkpO1xuICAgIGZvciAoY29uc3Qgc3VibmV0SWQgb2Ygc3VibmV0SWRzKSB7XG4gICAgICBpZiAocHVibGljU3VibmV0SWRzLmhhcyhzdWJuZXRJZCkgJiYgIWFsbG93UHVibGljU3VibmV0KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTGFtYmRhIEZ1bmN0aW9ucyBpbiBhIHB1YmxpYyBzdWJuZXQgY2FuIE5PVCBhY2Nlc3MgdGhlIGludGVybmV0LiAnICtcbiAgICAgICAgICAnSWYgeW91IGFyZSBhd2FyZSBvZiB0aGlzIGxpbWl0YXRpb24gYW5kIHdvdWxkIHN0aWxsIGxpa2UgdG8gcGxhY2UgdGhlIGZ1bmN0aW9uIGludCBhIHB1YmxpYyBzdWJuZXQsIHNldCBgYWxsb3dQdWJsaWNTdWJuZXRgIHRvIHRydWUnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBMaXN0IGNhbid0IGJlIGVtcHR5IGhlcmUsIGlmIHdlIGdvdCB0aGlzIGZhciB5b3UgaW50ZW5kZWQgdG8gcHV0IHlvdXIgTGFtYmRhXG4gICAgLy8gaW4gc3VibmV0cy4gV2UncmUgZ29pbmcgdG8gZ3VhcmFudGVlIHRoYXQgd2UgZ2V0IHRoZSBuaWNlIGVycm9yIG1lc3NhZ2UgYnlcbiAgICAvLyBtYWtpbmcgVnBjTmV0d29yayBkbyB0aGUgc2VsZWN0aW9uIGFnYWluLlxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHN1Ym5ldElkcyxcbiAgICAgIHNlY3VyaXR5R3JvdXBJZHM6IHNlY3VyaXR5R3JvdXBzLm1hcChzZyA9PiBzZy5zZWN1cml0eUdyb3VwSWQpLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkRGVhZExldHRlclF1ZXVlKHByb3BzOiBGdW5jdGlvblByb3BzKSB7XG4gICAgaWYgKHByb3BzLmRlYWRMZXR0ZXJRdWV1ZSAmJiBwcm9wcy5kZWFkTGV0dGVyUXVldWVFbmFibGVkID09PSBmYWxzZSkge1xuICAgICAgdGhyb3cgRXJyb3IoJ2RlYWRMZXR0ZXJRdWV1ZSBkZWZpbmVkIGJ1dCBkZWFkTGV0dGVyUXVldWVFbmFibGVkIGV4cGxpY2l0bHkgc2V0IHRvIGZhbHNlJyk7XG4gICAgfVxuXG4gICAgaWYgKCFwcm9wcy5kZWFkTGV0dGVyUXVldWUgJiYgIXByb3BzLmRlYWRMZXR0ZXJRdWV1ZUVuYWJsZWQpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc3QgZGVhZExldHRlclF1ZXVlID0gcHJvcHMuZGVhZExldHRlclF1ZXVlIHx8IG5ldyBzcXMuUXVldWUodGhpcywgJ0RlYWRMZXR0ZXJRdWV1ZScsIHtcbiAgICAgIHJldGVudGlvblBlcmlvZDogRHVyYXRpb24uZGF5cygxNCksXG4gICAgfSk7XG5cbiAgICB0aGlzLmFkZFRvUm9sZVBvbGljeShuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICBhY3Rpb25zOiBbJ3NxczpTZW5kTWVzc2FnZSddLFxuICAgICAgcmVzb3VyY2VzOiBbZGVhZExldHRlclF1ZXVlLnF1ZXVlQXJuXSxcbiAgICB9KSk7XG5cbiAgICByZXR1cm4gZGVhZExldHRlclF1ZXVlO1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZERlYWRMZXR0ZXJDb25maWcoZGVhZExldHRlclF1ZXVlPzogc3FzLklRdWV1ZSkge1xuICAgIGlmIChkZWFkTGV0dGVyUXVldWUpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHRhcmdldEFybjogZGVhZExldHRlclF1ZXVlLnF1ZXVlQXJuLFxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkVHJhY2luZ0NvbmZpZyhwcm9wczogRnVuY3Rpb25Qcm9wcykge1xuICAgIGlmIChwcm9wcy50cmFjaW5nID09PSB1bmRlZmluZWQgfHwgcHJvcHMudHJhY2luZyA9PT0gVHJhY2luZy5ESVNBQkxFRCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICB0aGlzLmFkZFRvUm9sZVBvbGljeShuZXcgaWFtLlBvbGljeVN0YXRlbWVudCh7XG4gICAgICBhY3Rpb25zOiBbJ3hyYXk6UHV0VHJhY2VTZWdtZW50cycsICd4cmF5OlB1dFRlbGVtZXRyeVJlY29yZHMnXSxcbiAgICAgIHJlc291cmNlczogWycqJ10sXG4gICAgfSkpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIG1vZGU6IHByb3BzLnRyYWNpbmcsXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgdmFsaWRhdGVQcm9maWxpbmcocHJvcHM6IEZ1bmN0aW9uUHJvcHMpIHtcbiAgICBpZiAoIXByb3BzLnJ1bnRpbWUuc3VwcG9ydHNDb2RlR3VydVByb2ZpbGluZykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDb2RlR3VydSBwcm9maWxpbmcgaXMgbm90IHN1cHBvcnRlZCBieSBydW50aW1lICR7cHJvcHMucnVudGltZS5uYW1lfWApO1xuICAgIH1cbiAgICBpZiAocHJvcHMuZW52aXJvbm1lbnQgJiYgKHByb3BzLmVudmlyb25tZW50LkFXU19DT0RFR1VSVV9QUk9GSUxFUl9HUk9VUF9BUk4gfHwgcHJvcHMuZW52aXJvbm1lbnQuQVdTX0NPREVHVVJVX1BST0ZJTEVSX0VOQUJMRUQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FXU19DT0RFR1VSVV9QUk9GSUxFUl9HUk9VUF9BUk4gYW5kIEFXU19DT0RFR1VSVV9QUk9GSUxFUl9FTkFCTEVEIG11c3Qgbm90IGJlIHNldCB3aGVuIHByb2ZpbGluZyBvcHRpb25zIGVuYWJsZWQnKTtcbiAgICB9XG4gIH1cbn1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuZXhwb3J0IGludGVyZmFjZSBFbnZpcm9ubWVudE9wdGlvbnMge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gIHJlYWRvbmx5IHJlbW92ZUluRWRnZT86IGJvb2xlYW5cbn1cblxuLyoqXG4gKiBDb25maWd1cmF0aW9uIGZvciBhbiBlbnZpcm9ubWVudCB2YXJpYWJsZVxuICovXG5pbnRlcmZhY2UgRW52aXJvbm1lbnRDb25maWcgZXh0ZW5kcyBFbnZpcm9ubWVudE9wdGlvbnMge1xuICByZWFkb25seSB2YWx1ZTogc3RyaW5nO1xufVxuXG4vKipcbiAqIEdpdmVuIGFuIG9wYXF1ZSAodG9rZW4pIEFSTiwgcmV0dXJucyBhIENsb3VkRm9ybWF0aW9uIGV4cHJlc3Npb24gdGhhdCBleHRyYWN0cyB0aGUgZnVuY3Rpb25cbiAqIG5hbWUgZnJvbSB0aGUgQVJOLlxuICpcbiAqIEZ1bmN0aW9uIEFSTnMgbG9vayBsaWtlIHRoaXM6XG4gKlxuICogICBhcm46YXdzOmxhbWJkYTpyZWdpb246YWNjb3VudC1pZDpmdW5jdGlvbjpmdW5jdGlvbi1uYW1lXG4gKlxuICogLi53aGljaCBtZWFucyB0aGF0IGluIG9yZGVyIHRvIGV4dHJhY3QgdGhlIGBmdW5jdGlvbi1uYW1lYCBjb21wb25lbnQgZnJvbSB0aGUgQVJOLCB3ZSBjYW5cbiAqIHNwbGl0IHRoZSBBUk4gdXNpbmcgXCI6XCIgYW5kIHNlbGVjdCB0aGUgY29tcG9uZW50IGluIGluZGV4IDYuXG4gKlxuICogQHJldHVybnMgYEZuU2VsZWN0KDYsIEZuU3BsaXQoJzonLCBhcm4pKWBcbiAqL1xuZnVuY3Rpb24gZXh0cmFjdE5hbWVGcm9tQXJuKGFybjogc3RyaW5nKSB7XG4gIHJldHVybiBGbi5zZWxlY3QoNiwgRm4uc3BsaXQoJzonLCBhcm4pKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHZlcmlmeUNvZGVDb25maWcoY29kZTogQ29kZUNvbmZpZywgcHJvcHM6IEZ1bmN0aW9uUHJvcHMpIHtcbiAgLy8gbXV0dWFsbHkgZXhjbHVzaXZlXG4gIGNvbnN0IGNvZGVUeXBlID0gW2NvZGUuaW5saW5lQ29kZSwgY29kZS5zM0xvY2F0aW9uLCBjb2RlLmltYWdlXTtcblxuICBpZiAoY29kZVR5cGUuZmlsdGVyKHggPT4gISF4KS5sZW5ndGggIT09IDEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2xhbWJkYS5Db2RlIG11c3Qgc3BlY2lmeSBleGFjdGx5IG9uZSBvZjogXCJpbmxpbmVDb2RlXCIsIFwiczNMb2NhdGlvblwiLCBvciBcImltYWdlXCInKTtcbiAgfVxuXG4gIGlmICghIWNvZGUuaW1hZ2UgPT09IChwcm9wcy5oYW5kbGVyICE9PSBIYW5kbGVyLkZST01fSU1BR0UpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdoYW5kbGVyIG11c3QgYmUgYEhhbmRsZXIuRlJPTV9JTUFHRWAgd2hlbiB1c2luZyBpbWFnZSBhc3NldCBmb3IgTGFtYmRhIGZ1bmN0aW9uJyk7XG4gIH1cblxuICBpZiAoISFjb2RlLmltYWdlID09PSAocHJvcHMucnVudGltZSAhPT0gUnVudGltZS5GUk9NX0lNQUdFKSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncnVudGltZSBtdXN0IGJlIGBSdW50aW1lLkZST01fSU1BR0VgIHdoZW4gdXNpbmcgaW1hZ2UgYXNzZXQgZm9yIExhbWJkYSBmdW5jdGlvbicpO1xuICB9XG5cbiAgLy8gaWYgdGhpcyBpcyBpbmxpbmUgY29kZSwgY2hlY2sgdGhhdCB0aGUgcnVudGltZSBzdXBwb3J0c1xuICBpZiAoY29kZS5pbmxpbmVDb2RlICYmICFwcm9wcy5ydW50aW1lLnN1cHBvcnRzSW5saW5lQ29kZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgSW5saW5lIHNvdXJjZSBub3QgYWxsb3dlZCBmb3IgJHtwcm9wcy5ydW50aW1lIS5uYW1lfWApO1xuICB9XG59XG5cbmZ1bmN0aW9uIHVuZGVmaW5lZElmTm9LZXlzPEE+KHN0cnVjdDogQSk6IEEgfCB1bmRlZmluZWQge1xuICBjb25zdCBhbGxVbmRlZmluZWQgPSBPYmplY3QudmFsdWVzKHN0cnVjdCkuZXZlcnkodmFsID0+IHZhbCA9PT0gdW5kZWZpbmVkKTtcbiAgcmV0dXJuIGFsbFVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IHN0cnVjdDtcbn1cbiJdfQ==