@cloudsnorkel/cdk-github-runners 0.14.24 → 0.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/.jsii +5953 -602
  2. package/API.md +1349 -115
  3. package/README.md +53 -1
  4. package/assets/delete-failed-runner.lambda/index.js +122 -9
  5. package/assets/idle-runner-repear.lambda/index.js +153 -14
  6. package/assets/image-builders/aws-image-builder/delete-resources.lambda/index.js +1 -1
  7. package/assets/image-builders/build-image.lambda/index.js +1 -1
  8. package/assets/providers/ami-root-device.lambda/index.js +1 -1
  9. package/assets/setup.lambda/index.html +7 -7
  10. package/assets/setup.lambda/index.js +118 -8
  11. package/assets/status.lambda/index.js +121 -8
  12. package/assets/token-retriever.lambda/index.js +121 -8
  13. package/assets/warm-runner-manager.lambda/index.js +5909 -0
  14. package/assets/webhook-handler.lambda/index.js +126 -11
  15. package/assets/webhook-redelivery.lambda/index.js +139 -24
  16. package/lib/access.js +1 -1
  17. package/lib/delete-failed-runner.lambda.js +2 -2
  18. package/lib/idle-runner-repear.lambda.js +33 -7
  19. package/lib/image-builders/api.js +1 -1
  20. package/lib/image-builders/aws-image-builder/base-image.d.ts +13 -0
  21. package/lib/image-builders/aws-image-builder/base-image.js +36 -3
  22. package/lib/image-builders/aws-image-builder/builder.js +4 -4
  23. package/lib/image-builders/aws-image-builder/delete-resources.lambda.js +2 -2
  24. package/lib/image-builders/aws-image-builder/deprecated/ami.js +1 -1
  25. package/lib/image-builders/aws-image-builder/deprecated/container.js +1 -1
  26. package/lib/image-builders/aws-image-builder/deprecated/linux-components.js +1 -1
  27. package/lib/image-builders/aws-image-builder/deprecated/windows-components.js +1 -1
  28. package/lib/image-builders/build-image.lambda.js +2 -2
  29. package/lib/image-builders/codebuild-deprecated.js +1 -1
  30. package/lib/image-builders/components.js +3 -3
  31. package/lib/image-builders/static.js +1 -1
  32. package/lib/index.d.ts +1 -0
  33. package/lib/index.js +2 -1
  34. package/lib/lambda-github.d.ts +1 -1
  35. package/lib/lambda-github.js +3 -2
  36. package/lib/lambda-helpers.js +4 -4
  37. package/lib/providers/ami-root-device.lambda.js +2 -2
  38. package/lib/providers/codebuild.d.ts +18 -2
  39. package/lib/providers/codebuild.js +15 -4
  40. package/lib/providers/common.d.ts +47 -3
  41. package/lib/providers/common.js +29 -5
  42. package/lib/providers/composite.js +14 -19
  43. package/lib/providers/ec2.d.ts +9 -2
  44. package/lib/providers/ec2.js +84 -42
  45. package/lib/providers/ecs.d.ts +19 -2
  46. package/lib/providers/ecs.js +49 -44
  47. package/lib/providers/fargate.d.ts +2 -2
  48. package/lib/providers/fargate.js +19 -36
  49. package/lib/providers/lambda.d.ts +2 -2
  50. package/lib/providers/lambda.js +3 -3
  51. package/lib/runner.d.ts +31 -3
  52. package/lib/runner.js +171 -46
  53. package/lib/secrets.js +1 -1
  54. package/lib/setup.lambda.js +2 -2
  55. package/lib/utils.d.ts +10 -1
  56. package/lib/utils.js +15 -1
  57. package/lib/warm-runner-manager-function.d.ts +18 -0
  58. package/lib/warm-runner-manager-function.js +24 -0
  59. package/lib/warm-runner-manager.lambda.d.ts +41 -0
  60. package/lib/warm-runner-manager.lambda.js +487 -0
  61. package/lib/warm-runner.d.ts +155 -0
  62. package/lib/warm-runner.js +217 -0
  63. package/lib/webhook-handler.lambda.js +5 -3
  64. package/lib/webhook-redelivery.lambda.js +17 -16
  65. package/lib/webhook.d.ts +4 -0
  66. package/lib/webhook.js +2 -1
  67. package/node_modules/cron-parser/LICENSE +21 -0
  68. package/node_modules/cron-parser/README.md +408 -0
  69. package/node_modules/cron-parser/dist/CronDate.js +518 -0
  70. package/node_modules/cron-parser/dist/CronExpression.js +520 -0
  71. package/node_modules/cron-parser/dist/CronExpressionParser.js +382 -0
  72. package/node_modules/cron-parser/dist/CronFieldCollection.js +371 -0
  73. package/node_modules/cron-parser/dist/CronFileParser.js +109 -0
  74. package/node_modules/cron-parser/dist/fields/CronDayOfMonth.js +44 -0
  75. package/node_modules/cron-parser/dist/fields/CronDayOfWeek.js +51 -0
  76. package/node_modules/cron-parser/dist/fields/CronField.js +214 -0
  77. package/node_modules/cron-parser/dist/fields/CronHour.js +40 -0
  78. package/node_modules/cron-parser/dist/fields/CronMinute.js +40 -0
  79. package/node_modules/cron-parser/dist/fields/CronMonth.js +44 -0
  80. package/node_modules/cron-parser/dist/fields/CronSecond.js +40 -0
  81. package/node_modules/cron-parser/dist/fields/index.js +24 -0
  82. package/node_modules/cron-parser/dist/fields/types.js +2 -0
  83. package/node_modules/cron-parser/dist/index.js +31 -0
  84. package/node_modules/cron-parser/dist/types/CronDate.d.ts +288 -0
  85. package/node_modules/cron-parser/dist/types/CronExpression.d.ts +118 -0
  86. package/node_modules/cron-parser/dist/types/CronExpressionParser.d.ts +70 -0
  87. package/node_modules/cron-parser/dist/types/CronFieldCollection.d.ts +153 -0
  88. package/node_modules/cron-parser/dist/types/CronFileParser.d.ts +30 -0
  89. package/node_modules/cron-parser/dist/types/fields/CronDayOfMonth.d.ts +25 -0
  90. package/node_modules/cron-parser/dist/types/fields/CronDayOfWeek.d.ts +30 -0
  91. package/node_modules/cron-parser/dist/types/fields/CronField.d.ts +130 -0
  92. package/node_modules/cron-parser/dist/types/fields/CronHour.d.ts +23 -0
  93. package/node_modules/cron-parser/dist/types/fields/CronMinute.d.ts +23 -0
  94. package/node_modules/cron-parser/dist/types/fields/CronMonth.d.ts +24 -0
  95. package/node_modules/cron-parser/dist/types/fields/CronSecond.d.ts +23 -0
  96. package/node_modules/cron-parser/dist/types/fields/index.d.ts +8 -0
  97. package/node_modules/cron-parser/dist/types/fields/types.d.ts +18 -0
  98. package/node_modules/cron-parser/dist/types/index.d.ts +8 -0
  99. package/node_modules/cron-parser/dist/types/utils/random.d.ts +10 -0
  100. package/node_modules/cron-parser/dist/utils/random.js +38 -0
  101. package/node_modules/cron-parser/package.json +117 -0
  102. package/node_modules/luxon/LICENSE.md +7 -0
  103. package/node_modules/luxon/README.md +55 -0
  104. package/node_modules/luxon/build/amd/luxon.js +8741 -0
  105. package/node_modules/luxon/build/amd/luxon.js.map +1 -0
  106. package/node_modules/luxon/build/cjs-browser/luxon.js +8739 -0
  107. package/node_modules/luxon/build/cjs-browser/luxon.js.map +1 -0
  108. package/node_modules/luxon/build/es6/luxon.mjs +8133 -0
  109. package/node_modules/luxon/build/es6/luxon.mjs.map +1 -0
  110. package/node_modules/luxon/build/global/luxon.js +8744 -0
  111. package/node_modules/luxon/build/global/luxon.js.map +1 -0
  112. package/node_modules/luxon/build/global/luxon.min.js +1 -0
  113. package/node_modules/luxon/build/global/luxon.min.js.map +1 -0
  114. package/node_modules/luxon/build/node/luxon.js +7792 -0
  115. package/node_modules/luxon/build/node/luxon.js.map +1 -0
  116. package/node_modules/luxon/package.json +87 -0
  117. package/node_modules/luxon/src/datetime.js +2603 -0
  118. package/node_modules/luxon/src/duration.js +1009 -0
  119. package/node_modules/luxon/src/errors.js +61 -0
  120. package/node_modules/luxon/src/impl/conversions.js +206 -0
  121. package/node_modules/luxon/src/impl/diff.js +95 -0
  122. package/node_modules/luxon/src/impl/digits.js +94 -0
  123. package/node_modules/luxon/src/impl/english.js +233 -0
  124. package/node_modules/luxon/src/impl/formats.js +176 -0
  125. package/node_modules/luxon/src/impl/formatter.js +434 -0
  126. package/node_modules/luxon/src/impl/invalid.js +14 -0
  127. package/node_modules/luxon/src/impl/locale.js +569 -0
  128. package/node_modules/luxon/src/impl/regexParser.js +335 -0
  129. package/node_modules/luxon/src/impl/tokenParser.js +505 -0
  130. package/node_modules/luxon/src/impl/util.js +330 -0
  131. package/node_modules/luxon/src/impl/zoneUtil.js +34 -0
  132. package/node_modules/luxon/src/info.js +205 -0
  133. package/node_modules/luxon/src/interval.js +669 -0
  134. package/node_modules/luxon/src/luxon.js +26 -0
  135. package/node_modules/luxon/src/package.json +4 -0
  136. package/node_modules/luxon/src/settings.js +180 -0
  137. package/node_modules/luxon/src/zone.js +97 -0
  138. package/node_modules/luxon/src/zones/IANAZone.js +235 -0
  139. package/node_modules/luxon/src/zones/fixedOffsetZone.js +150 -0
  140. package/node_modules/luxon/src/zones/invalidZone.js +53 -0
  141. package/node_modules/luxon/src/zones/systemZone.js +61 -0
  142. package/package.json +33 -24
@@ -0,0 +1,155 @@
1
+ import * as cdk from 'aws-cdk-lib';
2
+ import { aws_events as events } from 'aws-cdk-lib';
3
+ import { Construct } from 'constructs';
4
+ import { ICompositeProvider, IRunnerProvider } from './providers';
5
+ import { GitHubRunners } from './runner';
6
+ import { WarmRunnerFillPayload } from './warm-runner-manager.lambda';
7
+ /**
8
+ * Common properties for warm runner constructs.
9
+ *
10
+ * @internal
11
+ */
12
+ export interface WarmRunnerBaseProps {
13
+ /**
14
+ * The GitHubRunners construct that owns the shared warm runner infrastructure.
15
+ */
16
+ readonly runners: GitHubRunners;
17
+ /**
18
+ * Provider to use. Warm runners bypass the provider selector — they always use
19
+ * this provider, regardless of job characteristics. Labels cannot be modified.
20
+ */
21
+ readonly provider: IRunnerProvider | ICompositeProvider;
22
+ /**
23
+ * Number of warm runners to maintain.
24
+ */
25
+ readonly count: number;
26
+ /**
27
+ * GitHub owner where runners will be registered (org or user login).
28
+ */
29
+ readonly owner: string;
30
+ /**
31
+ * Registration level — must match how your runners are set up in GitHub. Choose
32
+ * 'org' for org-wide runners, 'repo' for repo-level. See the setup wizard for choosing repo vs org.
33
+ *
34
+ * @see https://github.com/CloudSnorkel/cdk-github-runners/blob/main/SETUP_GITHUB.md
35
+ *
36
+ * @default 'repo'
37
+ */
38
+ readonly registrationLevel?: 'org' | 'repo';
39
+ /**
40
+ * Repository name (without owner) where runners will be registered. Required when `registrationLevel` is 'repo'.
41
+ */
42
+ readonly repo?: string;
43
+ }
44
+ /**
45
+ * Properties for always on warm runners.
46
+ */
47
+ export interface AlwaysOnWarmRunnerProps extends WarmRunnerBaseProps {
48
+ }
49
+ /**
50
+ * Properties for scheduled warm runners.
51
+ */
52
+ export interface ScheduledWarmRunnerProps extends WarmRunnerBaseProps {
53
+ /**
54
+ * When to start filling the pool (e.g. start of business hours).
55
+ */
56
+ readonly schedule: events.Schedule;
57
+ /**
58
+ * How long the warm runners should be maintained from the fill time (schedule). Defines the end of the
59
+ * window (schedule time + duration).
60
+ */
61
+ readonly duration: cdk.Duration;
62
+ }
63
+ /**
64
+ * Warm runners that run 24/7. Fills at midnight UTC and each runner stays alive for 24 hours.
65
+ *
66
+ * Runners will be provisioned using the specified provider and registered in the specified repository or organization.
67
+ *
68
+ * Registration level must match the one selected during setup.
69
+ *
70
+ * @see https://github.com/CloudSnorkel/cdk-github-runners/blob/main/SETUP_GITHUB.md
71
+ *
72
+ * ## Limitations
73
+ *
74
+ * - Jobs will still trigger provisioning of on-demand runners, even if a warm runner ends up being used.
75
+ * - You may briefly see more than `count` runners when changing config or at rotation.
76
+ * - To remove: set `count` to 0, deploy, wait for warm runners to stop, then remove and deploy again.
77
+ * If you don't follow this procedure, warm runners may linger until they expire.
78
+ * - Provider failures or timeouts (like Lambda provider timing out after 15 minutes) will result in a
79
+ * gap in coverage until the retry succeeds. Current retry mechanism has built-in back-off rate and
80
+ * can be tweaked using `retryOptions`. This will be improved in the future.
81
+ *
82
+ * ```typescript
83
+ * new AlwaysOnWarmRunner(stack, 'AlwaysOnLinux', {
84
+ * runners,
85
+ * provider: myProvider,
86
+ * count: 3,
87
+ * owner: 'my-org',
88
+ * repo: 'my-repo',
89
+ * });
90
+ * ```
91
+ */
92
+ export declare class AlwaysOnWarmRunner extends Construct {
93
+ /**
94
+ * The fill payload for this warm runner configuration.
95
+ * @internal
96
+ */
97
+ readonly _fillPayload: WarmRunnerFillPayload;
98
+ constructor(scope: Construct, id: string, props: AlwaysOnWarmRunnerProps);
99
+ }
100
+ /**
101
+ * Warm runners active during a time window specified by start time (`schedule`) and duration (`duration`).
102
+ *
103
+ * Runners will be provisioned using the specified provider and registered in the specified repository or organization.
104
+ *
105
+ * Registration level must match the one selected during setup.
106
+ *
107
+ * @see https://github.com/CloudSnorkel/cdk-github-runners/blob/main/SETUP_GITHUB.md
108
+ *
109
+ * ## Limitations
110
+ *
111
+ * - **No deployment-fill**: Unlike `AlwaysOnWarmRunner`, scheduled warm runners do not get an initial
112
+ * fill on deploy. The first fill happens at the next schedule occurrence. If you deploy at 1pm for
113
+ * a 2pm schedule, runners will not appear until 2pm.
114
+ * - Jobs will still trigger provisioning of on-demand runners, even if a warm runner ends up being used.
115
+ * - You may briefly see more than `count` runners when changing config or at rotation.
116
+ * - To remove: set `count` to 0, deploy, wait for warm runners to stop, then remove and deploy again.
117
+ * If you don't follow this procedure, warm runners may linger until they expire.
118
+ * - Provider failures or timeouts (like Lambda provider timing out after 15 minutes) will result in a
119
+ * gap in coverage until the retry succeeds. Current retry mechanism has built-in back-off rate and
120
+ * can be tweaked using `retryOptions`. This will be improved in the future.
121
+ *
122
+ * ```typescript
123
+ * // Cron: fill at 1pm on weekdays
124
+ * new ScheduledWarmRunner(stack, 'Business Hours', {
125
+ * runners,
126
+ * provider: myProvider,
127
+ * count: 3,
128
+ * owner: 'my-org',
129
+ * repo: 'my-repo',
130
+ * schedule: events.Schedule.cron({ hour: '13', minute: '0', weekDay: 'MON-FRI' }),
131
+ * duration: cdk.Duration.hours(2),
132
+ * });
133
+ * ```
134
+ *
135
+ * ```typescript
136
+ * // Rate: fill every 12 hours
137
+ * new ScheduledWarmRunner(stack, 'Every 12 Hours', {
138
+ * runners,
139
+ * provider: myProvider,
140
+ * count: 2,
141
+ * owner: 'my-org',
142
+ * repo: 'my-repo',
143
+ * schedule: events.Schedule.rate(cdk.Duration.hours(5)),
144
+ * duration: cdk.Duration.hours(12),
145
+ * });
146
+ * ```
147
+ */
148
+ export declare class ScheduledWarmRunner extends Construct {
149
+ /**
150
+ * The fill payload for this warm runner configuration.
151
+ * @internal
152
+ */
153
+ readonly _fillPayload: WarmRunnerFillPayload;
154
+ constructor(scope: Construct, id: string, props: ScheduledWarmRunnerProps);
155
+ }
@@ -0,0 +1,217 @@
1
+ "use strict";
2
+ var _a, _b;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.ScheduledWarmRunner = exports.AlwaysOnWarmRunner = void 0;
5
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
6
+ const crypto = require("crypto");
7
+ const cdk = require("aws-cdk-lib");
8
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
9
+ const constructs_1 = require("constructs");
10
+ const cron_parser_1 = require("cron-parser");
11
+ function buildWarmRunner(scope, props, schedule, duration, createInitialFill) {
12
+ const registrationLevel = props.registrationLevel ?? 'repo';
13
+ if (registrationLevel === 'org' && props.repo) {
14
+ cdk.Annotations.of(scope).addError('Do not specify repo when registrationLevel is \'org\'');
15
+ }
16
+ if (registrationLevel === 'repo' && !props.repo) {
17
+ cdk.Annotations.of(scope).addError('repo is required when registrationLevel is \'repo\'');
18
+ }
19
+ const providerPath = props.provider.node.path;
20
+ if (!props.runners.providers.some(p => p.node.path === providerPath)) {
21
+ cdk.Annotations.of(scope).addError(`Provider ${providerPath} is not in the providers list of the GitHubRunners construct`);
22
+ }
23
+ const labels = props.provider.labels;
24
+ const repo = registrationLevel === 'repo' ? (props.repo ?? '') : '';
25
+ const configHash = crypto.createHash('sha256')
26
+ .update(JSON.stringify({ providerPath, providerLabels: labels, count: props.count, duration, owner: props.owner, repo }))
27
+ .digest('hex')
28
+ .slice(0, 16);
29
+ const fillPayload = {
30
+ action: 'fill',
31
+ providerPath,
32
+ providerLabels: labels,
33
+ count: props.count,
34
+ duration,
35
+ owner: props.owner,
36
+ repo,
37
+ configHash,
38
+ };
39
+ const { lambda: managerFn, queue } = props.runners._ensureWarmRunnerInfra();
40
+ props.runners._registerWarmConfigHash(configHash);
41
+ // Schedule to fill the warm pool (usually daily). Sends to SQS so we get stable messageId for idempotent fills.
42
+ new aws_cdk_lib_1.aws_events.Rule(scope, 'Schedule', {
43
+ schedule,
44
+ targets: [new aws_cdk_lib_1.aws_events_targets.SqsQueue(queue, {
45
+ message: aws_cdk_lib_1.aws_events.RuleTargetInput.fromObject(fillPayload),
46
+ })],
47
+ });
48
+ // Fill the warm pool immediately on deploy (AlwaysOnWarmRunner only).
49
+ // ScheduledWarmRunner does not get deployment-fill. First fill happens at the next schedule fire.
50
+ if (createInitialFill) {
51
+ new cdk.CustomResource(scope, 'Initial Fill', {
52
+ serviceToken: managerFn.functionArn,
53
+ resourceType: 'Custom::WarmRunnerFill',
54
+ properties: fillPayload,
55
+ });
56
+ }
57
+ return fillPayload;
58
+ }
59
+ /**
60
+ * Warm runners that run 24/7. Fills at midnight UTC and each runner stays alive for 24 hours.
61
+ *
62
+ * Runners will be provisioned using the specified provider and registered in the specified repository or organization.
63
+ *
64
+ * Registration level must match the one selected during setup.
65
+ *
66
+ * @see https://github.com/CloudSnorkel/cdk-github-runners/blob/main/SETUP_GITHUB.md
67
+ *
68
+ * ## Limitations
69
+ *
70
+ * - Jobs will still trigger provisioning of on-demand runners, even if a warm runner ends up being used.
71
+ * - You may briefly see more than `count` runners when changing config or at rotation.
72
+ * - To remove: set `count` to 0, deploy, wait for warm runners to stop, then remove and deploy again.
73
+ * If you don't follow this procedure, warm runners may linger until they expire.
74
+ * - Provider failures or timeouts (like Lambda provider timing out after 15 minutes) will result in a
75
+ * gap in coverage until the retry succeeds. Current retry mechanism has built-in back-off rate and
76
+ * can be tweaked using `retryOptions`. This will be improved in the future.
77
+ *
78
+ * ```typescript
79
+ * new AlwaysOnWarmRunner(stack, 'AlwaysOnLinux', {
80
+ * runners,
81
+ * provider: myProvider,
82
+ * count: 3,
83
+ * owner: 'my-org',
84
+ * repo: 'my-repo',
85
+ * });
86
+ * ```
87
+ */
88
+ class AlwaysOnWarmRunner extends constructs_1.Construct {
89
+ constructor(scope, id, props) {
90
+ super(scope, id);
91
+ this._fillPayload = buildWarmRunner(this, props, aws_cdk_lib_1.aws_events.Schedule.cron({ hour: '0', minute: '0' }), cdk.Duration.days(1).toSeconds(), true);
92
+ }
93
+ }
94
+ exports.AlwaysOnWarmRunner = AlwaysOnWarmRunner;
95
+ _a = JSII_RTTI_SYMBOL_1;
96
+ AlwaysOnWarmRunner[_a] = { fqn: "@cloudsnorkel/cdk-github-runners.AlwaysOnWarmRunner", version: "0.15.1" };
97
+ /**
98
+ * Convert AWS EventBridge cron format to cron-parser format.
99
+ * AWS: cron(min hour dom month dow year), cron-parser: sec min hour dom month dow
100
+ */
101
+ function awsCronToParserFormat(expressionString) {
102
+ const match = expressionString.match(/^cron\((.+)\)$/);
103
+ if (!match)
104
+ return expressionString;
105
+ const [, inner] = match;
106
+ const parts = inner.trim().split(/\s+/);
107
+ if (parts.length !== 6)
108
+ return expressionString;
109
+ const [minute, hour, dom, month, dow] = parts;
110
+ return `0 ${minute} ${hour} ${dom} ${month} ${dow}`;
111
+ }
112
+ /**
113
+ * Parse AWS EventBridge rate expression and return interval in seconds.
114
+ * Format: rate(value unit) e.g. rate(2 hours), rate(5 minutes), rate(1 day)
115
+ */
116
+ function parseRateInterval(expressionString) {
117
+ const match = expressionString.match(/^rate\((\d+)\s+(minute|minutes|hour|hours|day|days)\)$/i);
118
+ if (!match)
119
+ return undefined;
120
+ const value = parseInt(match[1], 10);
121
+ const unit = match[2].toLowerCase();
122
+ if (value <= 0)
123
+ return undefined;
124
+ const secondsPerUnit = {
125
+ minute: 60,
126
+ minutes: 60,
127
+ hour: 3600,
128
+ hours: 3600,
129
+ day: 86400,
130
+ days: 86400,
131
+ };
132
+ return value * secondsPerUnit[unit];
133
+ }
134
+ /**
135
+ * Get the interval between schedule occurrences in seconds.
136
+ * Supports both cron and rate expressions.
137
+ */
138
+ function getScheduleIntervalSeconds(expressionString) {
139
+ const rateInterval = parseRateInterval(expressionString);
140
+ if (rateInterval !== undefined)
141
+ return rateInterval;
142
+ try {
143
+ const cronExpression = cron_parser_1.CronExpressionParser.parse(awsCronToParserFormat(expressionString));
144
+ const next = cronExpression.take(2);
145
+ return (next[1].getTime() - next[0].getTime()) / 1000;
146
+ }
147
+ catch {
148
+ return undefined;
149
+ }
150
+ }
151
+ /**
152
+ * Warm runners active during a time window specified by start time (`schedule`) and duration (`duration`).
153
+ *
154
+ * Runners will be provisioned using the specified provider and registered in the specified repository or organization.
155
+ *
156
+ * Registration level must match the one selected during setup.
157
+ *
158
+ * @see https://github.com/CloudSnorkel/cdk-github-runners/blob/main/SETUP_GITHUB.md
159
+ *
160
+ * ## Limitations
161
+ *
162
+ * - **No deployment-fill**: Unlike `AlwaysOnWarmRunner`, scheduled warm runners do not get an initial
163
+ * fill on deploy. The first fill happens at the next schedule occurrence. If you deploy at 1pm for
164
+ * a 2pm schedule, runners will not appear until 2pm.
165
+ * - Jobs will still trigger provisioning of on-demand runners, even if a warm runner ends up being used.
166
+ * - You may briefly see more than `count` runners when changing config or at rotation.
167
+ * - To remove: set `count` to 0, deploy, wait for warm runners to stop, then remove and deploy again.
168
+ * If you don't follow this procedure, warm runners may linger until they expire.
169
+ * - Provider failures or timeouts (like Lambda provider timing out after 15 minutes) will result in a
170
+ * gap in coverage until the retry succeeds. Current retry mechanism has built-in back-off rate and
171
+ * can be tweaked using `retryOptions`. This will be improved in the future.
172
+ *
173
+ * ```typescript
174
+ * // Cron: fill at 1pm on weekdays
175
+ * new ScheduledWarmRunner(stack, 'Business Hours', {
176
+ * runners,
177
+ * provider: myProvider,
178
+ * count: 3,
179
+ * owner: 'my-org',
180
+ * repo: 'my-repo',
181
+ * schedule: events.Schedule.cron({ hour: '13', minute: '0', weekDay: 'MON-FRI' }),
182
+ * duration: cdk.Duration.hours(2),
183
+ * });
184
+ * ```
185
+ *
186
+ * ```typescript
187
+ * // Rate: fill every 12 hours
188
+ * new ScheduledWarmRunner(stack, 'Every 12 Hours', {
189
+ * runners,
190
+ * provider: myProvider,
191
+ * count: 2,
192
+ * owner: 'my-org',
193
+ * repo: 'my-repo',
194
+ * schedule: events.Schedule.rate(cdk.Duration.hours(5)),
195
+ * duration: cdk.Duration.hours(12),
196
+ * });
197
+ * ```
198
+ */
199
+ class ScheduledWarmRunner extends constructs_1.Construct {
200
+ constructor(scope, id, props) {
201
+ super(scope, id);
202
+ // make sure the duration is not longer than the interval between next two schedule occurrences
203
+ const interval = getScheduleIntervalSeconds(props.schedule.expressionString);
204
+ if (interval !== undefined && interval < props.duration.toSeconds()) {
205
+ cdk.Annotations.of(this).addError(`ScheduledWarmRunner duration ${props.duration.toHumanString()} is longer than the interval ${cdk.Duration.seconds(interval).toHumanString()} between next two schedule occurrences. This will result in overlapping warm runners at the start of the next schedule occurrence.`);
206
+ }
207
+ // warn for short interval
208
+ if (interval !== undefined && interval < cdk.Duration.hours(1).toSeconds()) {
209
+ cdk.Annotations.of(this).addWarningV2('@cloudsnorkel/cdk-github-runners:ScheduledWarmRunner.intervalTooShort', `ScheduledWarmRunner interval ${cdk.Duration.seconds(interval).toHumanString()} is less than 1 hour, which may result in more warm runners than expected`);
210
+ }
211
+ this._fillPayload = buildWarmRunner(this, props, props.schedule, props.duration.toSeconds(), false);
212
+ }
213
+ }
214
+ exports.ScheduledWarmRunner = ScheduledWarmRunner;
215
+ _b = JSII_RTTI_SYMBOL_1;
216
+ ScheduledWarmRunner[_b] = { fqn: "@cloudsnorkel/cdk-github-runners.ScheduledWarmRunner", version: "0.15.1" };
217
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FybS1ydW5uZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvd2FybS1ydW5uZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxpQ0FBaUM7QUFDakMsbUNBQW1DO0FBQ25DLDZDQUdxQjtBQUNyQiwyQ0FBdUM7QUFDdkMsNkNBQW1EO0FBcUVuRCxTQUFTLGVBQWUsQ0FBQyxLQUFnQixFQUFFLEtBQTBCLEVBQUUsUUFBeUIsRUFBRSxRQUFnQixFQUFFLGlCQUEwQjtJQUM1SSxNQUFNLGlCQUFpQixHQUFHLEtBQUssQ0FBQyxpQkFBaUIsSUFBSSxNQUFNLENBQUM7SUFDNUQsSUFBSSxpQkFBaUIsS0FBSyxLQUFLLElBQUksS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQzlDLEdBQUcsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLFFBQVEsQ0FBQyx1REFBdUQsQ0FBQyxDQUFDO0lBQzlGLENBQUM7SUFDRCxJQUFJLGlCQUFpQixLQUFLLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNoRCxHQUFHLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxRQUFRLENBQUMscURBQXFELENBQUMsQ0FBQztJQUM1RixDQUFDO0lBRUQsTUFBTSxZQUFZLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO0lBQzlDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxZQUFZLENBQUMsRUFBRSxDQUFDO1FBQ3JFLEdBQUcsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLFFBQVEsQ0FBQyxZQUFZLFlBQVksOERBQThELENBQUMsQ0FBQztJQUM3SCxDQUFDO0lBRUQsTUFB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QixJQUFJLFFBQVEsS0FBSyxTQUFTLElBQUksUUFBUSxHQUFHLEdBQUcsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUM7WUFDM0UsR0FBRyxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsWUFBWSxDQUNuQyx1RUFBdUUsRUFDdkUsZ0NBQWdDLEdBQUcsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLGFBQWEsRUFBRSwyRUFBMkUsQ0FDMUosQ0FBQztRQUNKLENBQUM7UUFFRCxJQUFJLENBQUMsWUFBWSxHQUFHLGVBQWUsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLFFBQVEsQ0FBQyxTQUFTLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUN0RyxDQUFDOztBQXpCSCxrREEwQkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBjcnlwdG8gZnJvbSAnY3J5cHRvJztcbmltcG9ydCAqIGFzIGNkayBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQge1xuICBhd3NfZXZlbnRzIGFzIGV2ZW50cyxcbiAgYXdzX2V2ZW50c190YXJnZXRzIGFzIGV2ZW50c190YXJnZXRzLFxufSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7IENyb25FeHByZXNzaW9uUGFyc2VyIH0gZnJvbSAnY3Jvbi1wYXJzZXInO1xuaW1wb3J0IHsgSUNvbXBvc2l0ZVByb3ZpZGVyLCBJUnVubmVyUHJvdmlkZXIgfSBmcm9tICcuL3Byb3ZpZGVycyc7XG5pbXBvcnQgeyBHaXRIdWJSdW5uZXJzIH0gZnJvbSAnLi9ydW5uZXInO1xuaW1wb3J0IHsgV2FybVJ1bm5lckZpbGxQYXlsb2FkIH0gZnJvbSAnLi93YXJtLXJ1bm5lci1tYW5hZ2VyLmxhbWJkYSc7XG5cbi8qKlxuICogQ29tbW9uIHByb3BlcnRpZXMgZm9yIHdhcm0gcnVubmVyIGNvbnN0cnVjdHMuXG4gKlxuICogQGludGVybmFsXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgV2FybVJ1bm5lckJhc2VQcm9wcyB7XG4gIC8qKlxuICAgKiBUaGUgR2l0SHViUnVubmVycyBjb25zdHJ1Y3QgdGhhdCBvd25zIHRoZSBzaGFyZWQgd2FybSBydW5uZXIgaW5mcmFzdHJ1Y3R1cmUuXG4gICAqL1xuICByZWFkb25seSBydW5uZXJzOiBHaXRIdWJSdW5uZXJzO1xuXG4gIC8qKlxuICAgKiBQcm92aWRlciB0byB1c2UuIFdhcm0gcnVubmVycyBieXBhc3MgdGhlIHByb3ZpZGVyIHNlbGVjdG9yIOKAlCB0aGV5IGFsd2F5cyB1c2VcbiAgICogdGhpcyBwcm92aWRlciwgcmVnYXJkbGVzcyBvZiBqb2IgY2hhcmFjdGVyaXN0aWNzLiBMYWJlbHMgY2Fubm90IGJlIG1vZGlmaWVkLlxuICAgKi9cbiAgcmVhZG9ubHkgcHJvdmlkZXI6IElSdW5uZXJQcm92aWRlciB8IElDb21wb3NpdGVQcm92aWRlcjtcblxuICAvKipcbiAgICogTnVtYmVyIG9mIHdhcm0gcnVubmVycyB0byBtYWludGFpbi5cbiAgICovXG4gIHJlYWRvbmx5IGNvdW50OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEdpdEh1YiBvd25lciB3aGVyZSBydW5uZXJzIHdpbGwgYmUgcmVnaXN0ZXJlZCAob3JnIG9yIHVzZXIgbG9naW4pLlxuICAgKi9cbiAgcmVhZG9ubHkgb3duZXI6IHN0cmluZztcblxuICAvKipcbiAgICogUmVnaXN0cmF0aW9uIGxldmVsIOKAlCBtdXN0IG1hdGNoIGhvdyB5b3VyIHJ1bm5lcnMgYXJlIHNldCB1cCBpbiBHaXRIdWIuIENob29zZVxuICAgKiAnb3JnJyBmb3Igb3JnLXdpZGUgcnVubmVycywgJ3JlcG8nIGZvciByZXBvLWxldmVsLiBTZWUgdGhlIHNldHVwIHdpemFyZCBmb3IgY2hvb3NpbmcgcmVwbyB2cyBvcmcuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL0Nsb3VkU25vcmtlbC9jZGstZ2l0aHViLXJ1bm5lcnMvYmxvYi9tYWluL1NFVFVQX0dJVEhVQi5tZFxuICAgKlxuICAgKiBAZGVmYXVsdCAncmVwbydcbiAgICovXG4gIHJlYWRvbmx5IHJlZ2lzdHJhdGlvbkxldmVsPzogJ29yZycgfCAncmVwbyc7XG5cbiAgLyoqXG4gICAqIFJlcG9zaXRvcnkgbmFtZSAod2l0aG91dCBvd25lcikgd2hlcmUgcnVubmVycyB3aWxsIGJlIHJlZ2lzdGVyZWQuIFJlcXVpcmVkIHdoZW4gYHJlZ2lzdHJhdGlvbkxldmVsYCBpcyAncmVwbycuXG4gICAqL1xuICByZWFkb25seSByZXBvPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGFsd2F5cyBvbiB3YXJtIHJ1bm5lcnMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWx3YXlzT25XYXJtUnVubmVyUHJvcHMgZXh0ZW5kcyBXYXJtUnVubmVyQmFzZVByb3BzIHsgfVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIHNjaGVkdWxlZCB3YXJtIHJ1bm5lcnMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2NoZWR1bGVkV2FybVJ1bm5lclByb3BzIGV4dGVuZHMgV2FybVJ1bm5lckJhc2VQcm9wcyB7XG4gIC8qKlxuICAgKiBXaGVuIHRvIHN0YXJ0IGZpbGxpbmcgdGhlIHBvb2wgKGUuZy4gc3RhcnQgb2YgYnVzaW5lc3MgaG91cnMpLlxuICAgKi9cbiAgcmVhZG9ubHkgc2NoZWR1bGU6IGV2ZW50cy5TY2hlZHVsZTtcblxuICAvKipcbiAgICogSG93IGxvbmcgdGhlIHdhcm0gcnVubmVycyBzaG91bGQgYmUgbWFpbnRhaW5lZCBmcm9tIHRoZSBmaWxsIHRpbWUgKHNjaGVkdWxlKS4gRGVmaW5lcyB0aGUgZW5kIG9mIHRoZVxuICAgKiB3aW5kb3cgKHNjaGVkdWxlIHRpbWUgKyBkdXJhdGlvbikuXG4gICAqL1xuICByZWFkb25seSBkdXJhdGlvbjogY2RrLkR1cmF0aW9uO1xufVxuXG5mdW5jdGlvbiBidWlsZFdhcm1SdW5uZXIoc2NvcGU6IENvbnN0cnVjdCwgcHJvcHM6IFdhcm1SdW5uZXJCYXNlUHJvcHMsIHNjaGVkdWxlOiBldmVudHMuU2NoZWR1bGUsIGR1cmF0aW9uOiBudW1iZXIsIGNyZWF0ZUluaXRpYWxGaWxsOiBib29sZWFuKSB7XG4gIGNvbnN0IHJlZ2lzdHJhdGlvbkxldmVsID0gcHJvcHMucmVnaXN0cmF0aW9uTGV2ZWwgPz8gJ3JlcG8nO1xuICBpZiAocmVnaXN0cmF0aW9uTGV2ZWwgPT09ICdvcmcnICYmIHByb3BzLnJlcG8pIHtcbiAgICBjZGsuQW5ub3RhdGlvbnMub2Yoc2NvcGUpLmFkZEVycm9yKCdEbyBub3Qgc3BlY2lmeSByZXBvIHdoZW4gcmVnaXN0cmF0aW9uTGV2ZWwgaXMgXFwnb3JnXFwnJyk7XG4gIH1cbiAgaWYgKHJlZ2lzdHJhdGlvbkxldmVsID09PSAncmVwbycgJiYgIXByb3BzLnJlcG8pIHtcbiAgICBjZGsuQW5ub3RhdGlvbnMub2Yoc2NvcGUpLmFkZEVycm9yKCdyZXBvIGlzIHJlcXVpcmVkIHdoZW4gcmVnaXN0cmF0aW9uTGV2ZWwgaXMgXFwncmVwb1xcJycpO1xuICB9XG5cbiAgY29uc3QgcHJvdmlkZXJQYXRoID0gcHJvcHMucHJvdmlkZXIubm9kZS5wYXRoO1xuICBpZiAoIXByb3BzLnJ1bm5lcnMucHJvdmlkZXJzLnNvbWUocCA9PiBwLm5vZGUucGF0aCA9PT0gcHJvdmlkZXJQYXRoKSkge1xuICAgIGNkay5Bbm5vdGF0aW9ucy5vZihzY29wZSkuYWRkRXJyb3IoYFByb3ZpZGVyICR7cHJvdmlkZXJQYXRofSBpcyBub3QgaW4gdGhlIHByb3ZpZGVycyBsaXN0IG9mIHRoZSBHaXRIdWJSdW5uZXJzIGNvbnN0cnVjdGApO1xuICB9XG5cbiAgY29uc3QgbGFiZWxzID0gcHJvcHMucHJvdmlkZXIubGFiZWxzO1xuXG4gIGNvbnN0IHJlcG8gPSByZWdpc3RyYXRpb25MZXZlbCA9PT0gJ3JlcG8nID8gKHByb3BzLnJlcG8gPz8gJycpIDogJyc7XG4gIGNvbnN0IGNvbmZpZ0hhc2ggPSBjcnlwdG8uY3JlYXRlSGFzaCgnc2hhMjU2JylcbiAgICAudXBkYXRlKEpTT04uc3RyaW5naWZ5KHsgcHJvdmlkZXJQYXRoLCBwcm92aWRlckxhYmVsczogbGFiZWxzLCBjb3VudDogcHJvcHMuY291bnQsIGR1cmF0aW9uLCBvd25lcjogcHJvcHMub3duZXIsIHJlcG8gfSkpXG4gICAgLmRpZ2VzdCgnaGV4JylcbiAgICAuc2xpY2UoMCwgMTYpO1xuXG4gIGNvbnN0IGZpbGxQYXlsb2FkOiBXYXJtUnVubmVyRmlsbFBheWxvYWQgPSB7XG4gICAgYWN0aW9uOiAnZmlsbCcgYXMgY29uc3QsXG4gICAgcHJvdmlkZXJQYXRoLFxuICAgIHByb3ZpZGVyTGFiZWxzOiBsYWJlbHMsXG4gICAgY291bnQ6IHByb3BzLmNvdW50LFxuICAgIGR1cmF0aW9uLFxuICAgIG93bmVyOiBwcm9wcy5vd25lcixcbiAgICByZXBvLFxuICAgIGNvbmZpZ0hhc2gsXG4gIH07XG5cbiAgY29uc3QgeyBsYW1iZGE6IG1hbmFnZXJGbiwgcXVldWUgfSA9IHByb3BzLnJ1bm5lcnMuX2Vuc3VyZVdhcm1SdW5uZXJJbmZyYSgpO1xuICBwcm9wcy5ydW5uZXJzLl9yZWdpc3Rlcldhcm1Db25maWdIYXNoKGNvbmZpZ0hhc2gpO1xuXG4gIC8vIFNjaGVkdWxlIHRvIGZpbGwgdGhlIHdhcm0gcG9vbCAodXN1YWxseSBkYWlseSkuIFNlbmRzIHRvIFNRUyBzbyB3ZSBnZXQgc3RhYmxlIG1lc3NhZ2VJZCBmb3IgaWRlbXBvdGVudCBmaWxscy5cbiAgbmV3IGV2ZW50cy5SdWxlKHNjb3BlLCAnU2NoZWR1bGUnLCB7XG4gICAgc2NoZWR1bGUsXG4gICAgdGFyZ2V0czogW25ldyBldmVudHNfdGFyZ2V0cy5TcXNRdWV1ZShxdWV1ZSwge1xuICAgICAgbWVzc2FnZTogZXZlbnRzLlJ1bGVUYXJnZXRJbnB1dC5mcm9tT2JqZWN0KGZpbGxQYXlsb2FkKSxcbiAgICB9KV0sXG4gIH0pO1xuXG4gIC8vIEZpbGwgdGhlIHdhcm0gcG9vbCBpbW1lZGlhdGVseSBvbiBkZXBsb3kgKEFsd2F5c09uV2FybVJ1bm5lciBvbmx5KS5cbiAgLy8gU2NoZWR1bGVkV2FybVJ1bm5lciBkb2VzIG5vdCBnZXQgZGVwbG95bWVudC1maWxsLiBGaXJzdCBmaWxsIGhhcHBlbnMgYXQgdGhlIG5leHQgc2NoZWR1bGUgZmlyZS5cbiAgaWYgKGNyZWF0ZUluaXRpYWxGaWxsKSB7XG4gICAgbmV3IGNkay5DdXN0b21SZXNvdXJjZShzY29wZSwgJ0luaXRpYWwgRmlsbCcsIHtcbiAgICAgIHNlcnZpY2VUb2tlbjogbWFuYWdlckZuLmZ1bmN0aW9uQXJuLFxuICAgICAgcmVzb3VyY2VUeXBlOiAnQ3VzdG9tOjpXYXJtUnVubmVyRmlsbCcsXG4gICAgICBwcm9wZXJ0aWVzOiBmaWxsUGF5bG9hZCxcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBmaWxsUGF5bG9hZDtcbn1cblxuLyoqXG4gKiBXYXJtIHJ1bm5lcnMgdGhhdCBydW4gMjQvNy4gRmlsbHMgYXQgbWlkbmlnaHQgVVRDIGFuZCBlYWNoIHJ1bm5lciBzdGF5cyBhbGl2ZSBmb3IgMjQgaG91cnMuXG4gKlxuICogUnVubmVycyB3aWxsIGJlIHByb3Zpc2lvbmVkIHVzaW5nIHRoZSBzcGVjaWZpZWQgcHJvdmlkZXIgYW5kIHJlZ2lzdGVyZWQgaW4gdGhlIHNwZWNpZmllZCByZXBvc2l0b3J5IG9yIG9yZ2FuaXphdGlvbi5cbiAqXG4gKiBSZWdpc3RyYXRpb24gbGV2ZWwgbXVzdCBtYXRjaCB0aGUgb25lIHNlbGVjdGVkIGR1cmluZyBzZXR1cC5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9DbG91ZFNub3JrZWwvY2RrLWdpdGh1Yi1ydW5uZXJzL2Jsb2IvbWFpbi9TRVRVUF9HSVRIVUIubWRcbiAqXG4gKiAjIyBMaW1pdGF0aW9uc1xuICpcbiAqIC0gSm9icyB3aWxsIHN0aWxsIHRyaWdnZXIgcHJvdmlzaW9uaW5nIG9mIG9uLWRlbWFuZCBydW5uZXJzLCBldmVuIGlmIGEgd2FybSBydW5uZXIgZW5kcyB1cCBiZWluZyB1c2VkLlxuICogLSBZb3UgbWF5IGJyaWVmbHkgc2VlIG1vcmUgdGhhbiBgY291bnRgIHJ1bm5lcnMgd2hlbiBjaGFuZ2luZyBjb25maWcgb3IgYXQgcm90YXRpb24uXG4gKiAtIFRvIHJlbW92ZTogc2V0IGBjb3VudGAgdG8gMCwgZGVwbG95LCB3YWl0IGZvciB3YXJtIHJ1bm5lcnMgdG8gc3RvcCwgdGhlbiByZW1vdmUgYW5kIGRlcGxveSBhZ2Fpbi5cbiAqICAgSWYgeW91IGRvbid0IGZvbGxvdyB0aGlzIHByb2NlZHVyZSwgd2FybSBydW5uZXJzIG1heSBsaW5nZXIgdW50aWwgdGhleSBleHBpcmUuXG4gKiAtIFByb3ZpZGVyIGZhaWx1cmVzIG9yIHRpbWVvdXRzIChsaWtlIExhbWJkYSBwcm92aWRlciB0aW1pbmcgb3V0IGFmdGVyIDE1IG1pbnV0ZXMpIHdpbGwgcmVzdWx0IGluIGFcbiAqICAgZ2FwIGluIGNvdmVyYWdlIHVudGlsIHRoZSByZXRyeSBzdWNjZWVkcy4gQ3VycmVudCByZXRyeSBtZWNoYW5pc20gaGFzIGJ1aWx0LWluIGJhY2stb2ZmIHJhdGUgYW5kXG4gKiAgIGNhbiBiZSB0d2Vha2VkIHVzaW5nIGByZXRyeU9wdGlvbnNgLiBUaGlzIHdpbGwgYmUgaW1wcm92ZWQgaW4gdGhlIGZ1dHVyZS5cbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBuZXcgQWx3YXlzT25XYXJtUnVubmVyKHN0YWNrLCAnQWx3YXlzT25MaW51eCcsIHtcbiAqICAgcnVubmVycyxcbiAqICAgcHJvdmlkZXI6IG15UHJvdmlkZXIsXG4gKiAgIGNvdW50OiAzLFxuICogICBvd25lcjogJ215LW9yZycsXG4gKiAgIHJlcG86ICdteS1yZXBvJyxcbiAqIH0pO1xuICogYGBgXG4gKi9cbmV4cG9ydCBjbGFzcyBBbHdheXNPbldhcm1SdW5uZXIgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICAvKipcbiAgICogVGhlIGZpbGwgcGF5bG9hZCBmb3IgdGhpcyB3YXJtIHJ1bm5lciBjb25maWd1cmF0aW9uLlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBfZmlsbFBheWxvYWQ6IFdhcm1SdW5uZXJGaWxsUGF5bG9hZDtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQWx3YXlzT25XYXJtUnVubmVyUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuICAgIHRoaXMuX2ZpbGxQYXlsb2FkID0gYnVpbGRXYXJtUnVubmVyKHRoaXMsIHByb3BzLCBldmVudHMuU2NoZWR1bGUuY3Jvbih7IGhvdXI6ICcwJywgbWludXRlOiAnMCcgfSksIGNkay5EdXJhdGlvbi5kYXlzKDEpLnRvU2Vjb25kcygpLCB0cnVlKTtcbiAgfVxufVxuXG4vKipcbiAqIENvbnZlcnQgQVdTIEV2ZW50QnJpZGdlIGNyb24gZm9ybWF0IHRvIGNyb24tcGFyc2VyIGZvcm1hdC5cbiAqIEFXUzogY3JvbihtaW4gaG91ciBkb20gbW9udGggZG93IHllYXIpLCBjcm9uLXBhcnNlcjogc2VjIG1pbiBob3VyIGRvbSBtb250aCBkb3dcbiAqL1xuZnVuY3Rpb24gYXdzQ3JvblRvUGFyc2VyRm9ybWF0KGV4cHJlc3Npb25TdHJpbmc6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IG1hdGNoID0gZXhwcmVzc2lvblN0cmluZy5tYXRjaCgvXmNyb25cXCgoLispXFwpJC8pO1xuICBpZiAoIW1hdGNoKSByZXR1cm4gZXhwcmVzc2lvblN0cmluZztcbiAgY29uc3QgWywgaW5uZXJdID0gbWF0Y2g7XG4gIGNvbnN0IHBhcnRzID0gaW5uZXIudHJpbSgpLnNwbGl0KC9cXHMrLyk7XG4gIGlmIChwYXJ0cy5sZW5ndGggIT09IDYpIHJldHVybiBleHByZXNzaW9uU3RyaW5nO1xuICBjb25zdCBbbWludXRlLCBob3VyLCBkb20sIG1vbnRoLCBkb3ddID0gcGFydHM7XG4gIHJldHVybiBgMCAke21pbnV0ZX0gJHtob3VyfSAke2RvbX0gJHttb250aH0gJHtkb3d9YDtcbn1cblxuLyoqXG4gKiBQYXJzZSBBV1MgRXZlbnRCcmlkZ2UgcmF0ZSBleHByZXNzaW9uIGFuZCByZXR1cm4gaW50ZXJ2YWwgaW4gc2Vjb25kcy5cbiAqIEZvcm1hdDogcmF0ZSh2YWx1ZSB1bml0KSBlLmcuIHJhdGUoMiBob3VycyksIHJhdGUoNSBtaW51dGVzKSwgcmF0ZSgxIGRheSlcbiAqL1xuZnVuY3Rpb24gcGFyc2VSYXRlSW50ZXJ2YWwoZXhwcmVzc2lvblN0cmluZzogc3RyaW5nKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgbWF0Y2ggPSBleHByZXNzaW9uU3RyaW5nLm1hdGNoKC9ecmF0ZVxcKChcXGQrKVxccysobWludXRlfG1pbnV0ZXN8aG91cnxob3Vyc3xkYXl8ZGF5cylcXCkkL2kpO1xuICBpZiAoIW1hdGNoKSByZXR1cm4gdW5kZWZpbmVkO1xuICBjb25zdCB2YWx1ZSA9IHBhcnNlSW50KG1hdGNoWzFdLCAxMCk7XG4gIGNvbnN0IHVuaXQgPSBtYXRjaFsyXS50b0xvd2VyQ2FzZSgpO1xuICBpZiAodmFsdWUgPD0gMCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3Qgc2Vjb25kc1BlclVuaXQ6IFJlY29yZDxzdHJpbmcsIG51bWJlcj4gPSB7XG4gICAgbWludXRlOiA2MCxcbiAgICBtaW51dGVzOiA2MCxcbiAgICBob3VyOiAzNjAwLFxuICAgIGhvdXJzOiAzNjAwLFxuICAgIGRheTogODY0MDAsXG4gICAgZGF5czogODY0MDAsXG4gIH07XG4gIHJldHVybiB2YWx1ZSAqIHNlY29uZHNQZXJVbml0W3VuaXRdO1xufVxuXG4vKipcbiAqIEdldCB0aGUgaW50ZXJ2YWwgYmV0d2VlbiBzY2hlZHVsZSBvY2N1cnJlbmNlcyBpbiBzZWNvbmRzLlxuICogU3VwcG9ydHMgYm90aCBjcm9uIGFuZCByYXRlIGV4cHJlc3Npb25zLlxuICovXG5mdW5jdGlvbiBnZXRTY2hlZHVsZUludGVydmFsU2Vjb25kcyhleHByZXNzaW9uU3RyaW5nOiBzdHJpbmcpOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICBjb25zdCByYXRlSW50ZXJ2YWwgPSBwYXJzZVJhdGVJbnRlcnZhbChleHByZXNzaW9uU3RyaW5nKTtcbiAgaWYgKHJhdGVJbnRlcnZhbCAhPT0gdW5kZWZpbmVkKSByZXR1cm4gcmF0ZUludGVydmFsO1xuXG4gIHRyeSB7XG4gICAgY29uc3QgY3JvbkV4cHJlc3Npb24gPSBDcm9uRXhwcmVzc2lvblBhcnNlci5wYXJzZShhd3NDcm9uVG9QYXJzZXJGb3JtYXQoZXhwcmVzc2lvblN0cmluZykpO1xuICAgIGNvbnN0IG5leHQgPSBjcm9uRXhwcmVzc2lvbi50YWtlKDIpO1xuICAgIHJldHVybiAobmV4dFsxXS5nZXRUaW1lKCkgLSBuZXh0WzBdLmdldFRpbWUoKSkgLyAxMDAwO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59XG5cbi8qKlxuICogV2FybSBydW5uZXJzIGFjdGl2ZSBkdXJpbmcgYSB0aW1lIHdpbmRvdyBzcGVjaWZpZWQgYnkgc3RhcnQgdGltZSAoYHNjaGVkdWxlYCkgYW5kIGR1cmF0aW9uIChgZHVyYXRpb25gKS5cbiAqXG4gKiBSdW5uZXJzIHdpbGwgYmUgcHJvdmlzaW9uZWQgdXNpbmcgdGhlIHNwZWNpZmllZCBwcm92aWRlciBhbmQgcmVnaXN0ZXJlZCBpbiB0aGUgc3BlY2lmaWVkIHJlcG9zaXRvcnkgb3Igb3JnYW5pemF0aW9uLlxuICpcbiAqIFJlZ2lzdHJhdGlvbiBsZXZlbCBtdXN0IG1hdGNoIHRoZSBvbmUgc2VsZWN0ZWQgZHVyaW5nIHNldHVwLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL0Nsb3VkU25vcmtlbC9jZGstZ2l0aHViLXJ1bm5lcnMvYmxvYi9tYWluL1NFVFVQX0dJVEhVQi5tZFxuICpcbiAqICMjIExpbWl0YXRpb25zXG4gKlxuICogLSAqKk5vIGRlcGxveW1lbnQtZmlsbCoqOiBVbmxpa2UgYEFsd2F5c09uV2FybVJ1bm5lcmAsIHNjaGVkdWxlZCB3YXJtIHJ1bm5lcnMgZG8gbm90IGdldCBhbiBpbml0aWFsXG4gKiAgIGZpbGwgb24gZGVwbG95LiBUaGUgZmlyc3QgZmlsbCBoYXBwZW5zIGF0IHRoZSBuZXh0IHNjaGVkdWxlIG9jY3VycmVuY2UuIElmIHlvdSBkZXBsb3kgYXQgMXBtIGZvclxuICogICBhIDJwbSBzY2hlZHVsZSwgcnVubmVycyB3aWxsIG5vdCBhcHBlYXIgdW50aWwgMnBtLlxuICogLSBKb2JzIHdpbGwgc3RpbGwgdHJpZ2dlciBwcm92aXNpb25pbmcgb2Ygb24tZGVtYW5kIHJ1bm5lcnMsIGV2ZW4gaWYgYSB3YXJtIHJ1bm5lciBlbmRzIHVwIGJlaW5nIHVzZWQuXG4gKiAtIFlvdSBtYXkgYnJpZWZseSBzZWUgbW9yZSB0aGFuIGBjb3VudGAgcnVubmVycyB3aGVuIGNoYW5naW5nIGNvbmZpZyBvciBhdCByb3RhdGlvbi5cbiAqIC0gVG8gcmVtb3ZlOiBzZXQgYGNvdW50YCB0byAwLCBkZXBsb3ksIHdhaXQgZm9yIHdhcm0gcnVubmVycyB0byBzdG9wLCB0aGVuIHJlbW92ZSBhbmQgZGVwbG95IGFnYWluLlxuICogICBJZiB5b3UgZG9uJ3QgZm9sbG93IHRoaXMgcHJvY2VkdXJlLCB3YXJtIHJ1bm5lcnMgbWF5IGxpbmdlciB1bnRpbCB0aGV5IGV4cGlyZS5cbiAqIC0gUHJvdmlkZXIgZmFpbHVyZXMgb3IgdGltZW91dHMgKGxpa2UgTGFtYmRhIHByb3ZpZGVyIHRpbWluZyBvdXQgYWZ0ZXIgMTUgbWludXRlcykgd2lsbCByZXN1bHQgaW4gYVxuICogICBnYXAgaW4gY292ZXJhZ2UgdW50aWwgdGhlIHJldHJ5IHN1Y2NlZWRzLiBDdXJyZW50IHJldHJ5IG1lY2hhbmlzbSBoYXMgYnVpbHQtaW4gYmFjay1vZmYgcmF0ZSBhbmRcbiAqICAgY2FuIGJlIHR3ZWFrZWQgdXNpbmcgYHJldHJ5T3B0aW9uc2AuIFRoaXMgd2lsbCBiZSBpbXByb3ZlZCBpbiB0aGUgZnV0dXJlLlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIENyb246IGZpbGwgYXQgMXBtIG9uIHdlZWtkYXlzXG4gKiBuZXcgU2NoZWR1bGVkV2FybVJ1bm5lcihzdGFjaywgJ0J1c2luZXNzIEhvdXJzJywge1xuICogICBydW5uZXJzLFxuICogICBwcm92aWRlcjogbXlQcm92aWRlcixcbiAqICAgY291bnQ6IDMsXG4gKiAgIG93bmVyOiAnbXktb3JnJyxcbiAqICAgcmVwbzogJ215LXJlcG8nLFxuICogICBzY2hlZHVsZTogZXZlbnRzLlNjaGVkdWxlLmNyb24oeyBob3VyOiAnMTMnLCBtaW51dGU6ICcwJywgd2Vla0RheTogJ01PTi1GUkknIH0pLFxuICogICBkdXJhdGlvbjogY2RrLkR1cmF0aW9uLmhvdXJzKDIpLFxuICogfSk7XG4gKiBgYGBcbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBSYXRlOiBmaWxsIGV2ZXJ5IDEyIGhvdXJzXG4gKiBuZXcgU2NoZWR1bGVkV2FybVJ1bm5lcihzdGFjaywgJ0V2ZXJ5IDEyIEhvdXJzJywge1xuICogICBydW5uZXJzLFxuICogICBwcm92aWRlcjogbXlQcm92aWRlcixcbiAqICAgY291bnQ6IDIsXG4gKiAgIG93bmVyOiAnbXktb3JnJyxcbiAqICAgcmVwbzogJ215LXJlcG8nLFxuICogICBzY2hlZHVsZTogZXZlbnRzLlNjaGVkdWxlLnJhdGUoY2RrLkR1cmF0aW9uLmhvdXJzKDUpKSxcbiAqICAgZHVyYXRpb246IGNkay5EdXJhdGlvbi5ob3VycygxMiksXG4gKiB9KTtcbiAqIGBgYFxuICovXG5leHBvcnQgY2xhc3MgU2NoZWR1bGVkV2FybVJ1bm5lciBleHRlbmRzIENvbnN0cnVjdCB7XG4gIC8qKlxuICAgKiBUaGUgZmlsbCBwYXlsb2FkIGZvciB0aGlzIHdhcm0gcnVubmVyIGNvbmZpZ3VyYXRpb24uXG4gICAqIEBpbnRlcm5hbFxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IF9maWxsUGF5bG9hZDogV2FybVJ1bm5lckZpbGxQYXlsb2FkO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBTY2hlZHVsZWRXYXJtUnVubmVyUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgLy8gbWFrZSBzdXJlIHRoZSBkdXJhdGlvbiBpcyBub3QgbG9uZ2VyIHRoYW4gdGhlIGludGVydmFsIGJldHdlZW4gbmV4dCB0d28gc2NoZWR1bGUgb2NjdXJyZW5jZXNcbiAgICBjb25zdCBpbnRlcnZhbCA9IGdldFNjaGVkdWxlSW50ZXJ2YWxTZWNvbmRzKHByb3BzLnNjaGVkdWxlLmV4cHJlc3Npb25TdHJpbmcpO1xuICAgIGlmIChpbnRlcnZhbCAhPT0gdW5kZWZpbmVkICYmIGludGVydmFsIDwgcHJvcHMuZHVyYXRpb24udG9TZWNvbmRzKCkpIHtcbiAgICAgIGNkay5Bbm5vdGF0aW9ucy5vZih0aGlzKS5hZGRFcnJvcihgU2NoZWR1bGVkV2FybVJ1bm5lciBkdXJhdGlvbiAke3Byb3BzLmR1cmF0aW9uLnRvSHVtYW5TdHJpbmcoKX0gaXMgbG9uZ2VyIHRoYW4gdGhlIGludGVydmFsICR7Y2RrLkR1cmF0aW9uLnNlY29uZHMoaW50ZXJ2YWwpLnRvSHVtYW5TdHJpbmcoKX0gYmV0d2VlbiBuZXh0IHR3byBzY2hlZHVsZSBvY2N1cnJlbmNlcy4gVGhpcyB3aWxsIHJlc3VsdCBpbiBvdmVybGFwcGluZyB3YXJtIHJ1bm5lcnMgYXQgdGhlIHN0YXJ0IG9mIHRoZSBuZXh0IHNjaGVkdWxlIG9jY3VycmVuY2UuYCk7XG4gICAgfVxuXG4gICAgLy8gd2FybiBmb3Igc2hvcnQgaW50ZXJ2YWxcbiAgICBpZiAoaW50ZXJ2YWwgIT09IHVuZGVmaW5lZCAmJiBpbnRlcnZhbCA8IGNkay5EdXJhdGlvbi5ob3VycygxKS50b1NlY29uZHMoKSkge1xuICAgICAgY2RrLkFubm90YXRpb25zLm9mKHRoaXMpLmFkZFdhcm5pbmdWMihcbiAgICAgICAgJ0BjbG91ZHNub3JrZWwvY2RrLWdpdGh1Yi1ydW5uZXJzOlNjaGVkdWxlZFdhcm1SdW5uZXIuaW50ZXJ2YWxUb29TaG9ydCcsXG4gICAgICAgIGBTY2hlZHVsZWRXYXJtUnVubmVyIGludGVydmFsICR7Y2RrLkR1cmF0aW9uLnNlY29uZHMoaW50ZXJ2YWwpLnRvSHVtYW5TdHJpbmcoKX0gaXMgbGVzcyB0aGFuIDEgaG91ciwgd2hpY2ggbWF5IHJlc3VsdCBpbiBtb3JlIHdhcm0gcnVubmVycyB0aGFuIGV4cGVjdGVkYCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdGhpcy5fZmlsbFBheWxvYWQgPSBidWlsZFdhcm1SdW5uZXIodGhpcywgcHJvcHMsIHByb3BzLnNjaGVkdWxlLCBwcm9wcy5kdXJhdGlvbi50b1NlY29uZHMoKSwgZmFsc2UpO1xuICB9XG59XG4iXX0=
@@ -63,7 +63,7 @@ async function isDeploymentPending(payload) {
63
63
  catch (e) {
64
64
  console.error({
65
65
  notice: 'Unable to check deployment. Try adding deployment read permission.',
66
- error: `${e}`,
66
+ error: e,
67
67
  });
68
68
  return false;
69
69
  }
@@ -178,7 +178,7 @@ async function handler(event) {
178
178
  catch (e) {
179
179
  console.error({
180
180
  notice: 'Bad signature',
181
- error: `${e}`,
181
+ error: e,
182
182
  });
183
183
  return {
184
184
  statusCode: 403,
@@ -259,6 +259,7 @@ async function handler(event) {
259
259
  }
260
260
  // start execution
261
261
  const executionName = generateExecutionName(event, payload);
262
+ const idleTimeoutSeconds = process.env.IDLE_TIMEOUT_SECONDS ? parseInt(process.env.IDLE_TIMEOUT_SECONDS, 10) : 300; // default 5 minutes
262
263
  const input = {
263
264
  owner: payload.repository.owner.login,
264
265
  repo: payload.repository.name,
@@ -268,6 +269,7 @@ async function handler(event) {
268
269
  jobLabels: payload.workflow_job.labels.join(','), // original labels requested by the job
269
270
  provider: selection.provider,
270
271
  labels: selection.labels.join(','), // labels to use when registering runner
272
+ maxIdleSeconds: idleTimeoutSeconds,
271
273
  };
272
274
  const execution = await sf.send(new client_sfn_1.StartExecutionCommand({
273
275
  stateMachineArn: process.env.STEP_FUNCTION_ARN,
@@ -286,4 +288,4 @@ async function handler(event) {
286
288
  body: executionName,
287
289
  };
288
290
  }
289
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ViaG9vay1oYW5kbGVyLmxhbWJkYS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy93ZWJob29rLWhhbmRsZXIubGFtYmRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBNEJBLGdDQTRCQztBQTJDRCxvREFxQ0M7QUFNRCx3Q0FzQ0M7QUFTRCxzREFJQztBQUVELDBCQW1JQztBQXRVRCxpQ0FBaUM7QUFDakMsMERBQXFFO0FBQ3JFLG9EQUF1RTtBQUV2RSxtREFBNkM7QUFDN0MscURBQXNEO0FBR3RELE1BQU0sRUFBRSxHQUFHLElBQUksc0JBQVMsRUFBRSxDQUFDO0FBQzNCLE1BQU0sWUFBWSxHQUFHLElBQUksNEJBQVksRUFBRSxDQUFDO0FBRXhDLDhCQUE4QjtBQUU5QixTQUFTLFNBQVMsQ0FBQyxLQUF1QyxFQUFFLE1BQWM7SUFDeEUsb0ZBQW9GO0lBQ3BGLEtBQUssTUFBTSxVQUFVLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztRQUNwRCxJQUFJLFVBQVUsQ0FBQyxXQUFXLEVBQUUsS0FBSyxNQUFNLENBQUMsV0FBVyxFQUFFLEVBQUUsQ0FBQztZQUN0RCxPQUFPLEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDbkMsQ0FBQztJQUNILENBQUM7SUFFRCxPQUFPLFNBQVMsQ0FBQztBQUNuQixDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsU0FBZ0IsVUFBVSxDQUFDLEtBQXVDLEVBQUUsTUFBVztJQUM3RSxNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUscUJBQXFCLENBQUMsSUFBSSxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFFL0UsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNoQixNQUFNLElBQUksS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzdCLENBQUM7SUFFRCxJ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O1FBQ3JDLGNBQWMsRUFBRSxPQUFPLENBQUMsWUFBWSxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxxRUFBcUU7UUFDckgsU0FBUyxFQUFFLE9BQU8sQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSx1Q0FBdUM7UUFDekYsUUFBUSxFQUFFLFNBQVMsQ0FBQyxRQUFRO1FBQzVCLE1BQU0sRUFBRSxTQUFTLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSx3Q0FBd0M7S0FDN0UsQ0FBQztJQUNGLE1BQU0sU0FBUyxHQUFHLE1BQU0sRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLGtDQUFxQixDQUFDO1FBQ3hELGVBQWUsRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQjtRQUM5QyxLQUFLLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUM7UUFDNUIsa0dBQWtHO1FBQ2xHLElBQUksRUFBRSxhQUFhO0tBQ3BCLENBQUMsQ0FBQyxDQUFDO0lBRUosT0FBTyxDQUFDLEdBQUcsQ0FBQztRQUNWLE1BQU0sRUFBRSxzQkFBc0I7UUFDOUIsU0FBUyxFQUFFLFNBQVMsQ0FBQyxZQUFZO1FBQ2pDLFFBQVEsRUFBRSxLQUFLO1FBQ2YsR0FBRyxFQUFFLE9BQU8sQ0FBQyxZQUFZO0tBQzFCLENBQUMsQ0FBQztJQUVILE9BQU87UUFDTCxVQUFVLEVBQUUsR0FBRztRQUNmLElBQUksRUFBRSxhQUFhO0tBQ3BCLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY3J5cHRvIGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgeyBJbnZva2VDb21tYW5kLCBMYW1iZGFDbGllbnQgfSBmcm9tICdAYXdzLXNkay9jbGllbnQtbGFtYmRhJztcbmltcG9ydCB7IFNGTkNsaWVudCwgU3RhcnRFeGVjdXRpb25Db21tYW5kIH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LXNmbic7XG5pbXBvcnQgKiBhcyBBV1NMYW1iZGEgZnJvbSAnYXdzLWxhbWJkYSc7XG5pbXBvcnQgeyBnZXRPY3Rva2l0IH0gZnJvbSAnLi9sYW1iZGEtZ2l0aHViJztcbmltcG9ydCB7IGdldFNlY3JldEpzb25WYWx1ZSB9IGZyb20gJy4vbGFtYmRhLWhlbHBlcnMnO1xuaW1wb3J0IHsgUHJvdmlkZXJTZWxlY3RvcklucHV0LCBQcm92aWRlclNlbGVjdG9yUmVzdWx0IH0gZnJvbSAnLi93ZWJob29rJztcblxuY29uc3Qgc2YgPSBuZXcgU0ZOQ2xpZW50KCk7XG5jb25zdCBsYW1iZGFDbGllbnQgPSBuZXcgTGFtYmRhQ2xpZW50KCk7XG5cbi8vIFRPRE8gdXNlIEBvY3Rva2l0L3dlYmhvb2tzP1xuXG5mdW5jdGlvbiBnZXRIZWFkZXIoZXZlbnQ6IEFXU0xhbWJkYS5BUElHYXRld2F5UHJveHlFdmVudFYyLCBoZWFkZXI6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIC8vIEFQSSBHYXRld2F5IGRvZXNuJ3QgbG93ZXJjYXNlIGhlYWRlcnMgKFYxIGV2ZW50KSBidXQgTGFtYmRhIFVSTHMgZG8gKFYyIGV2ZW50KSA6KFxuICBmb3IgKGNvbnN0IGhlYWRlck5hbWUgb2YgT2JqZWN0LmtleXMoZXZlbnQuaGVhZGVycykpIHtcbiAgICBpZiAoaGVhZGVyTmFtZS50b0xvd2VyQ2FzZSgpID09PSBoZWFkZXIudG9Mb3dlckNhc2UoKSkge1xuICAgICAgcmV0dXJuIGV2ZW50LmhlYWRlcnNbaGVhZGVyTmFtZV07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBFeHBvcnRlZCBmb3IgdW5pdCB0ZXN0aW5nLlxuICogQGludGVybmFsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZXJpZnlCb2R5KGV2ZW50OiBBV1NMYW1iZGEuQVBJR2F0ZXdheVByb3h5RXZlbnRWMiwgc2VjcmV0OiBhbnkpOiBzdHJpbmcge1xuICBjb25zdCBzaWcgPSBCdWZmZXIuZnJvbShnZXRIZWFkZXIoZXZlbnQsICd4LWh1Yi1zaWduYXR1cmUtMjU2JykgfHwgJycsICd1dGY4Jyk7XG5cbiAgaWYgKCFldmVudC5ib2R5KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdObyBib2R5Jyk7XG4gIH1cblxuICBsZXQgYm9keTogQnVmZmVyO1xuICBpZiAoZXZlbnQuaXNCYXNlNjRFbmNvZGVkKSB7XG4gICAgYm9keSA9IEJ1ZmZlci5mcm9tKGV2ZW50LmJvZHksICdiYXNlNjQnKTtcbiAgfSBlbHNlIHtcbiAgICBib2R5ID0gQnVmZmVyLmZyb20oZXZlbnQuYm9keSB8fCAnJywgJ3V0ZjgnKTtcbiAgfVxuXG4gIGNvbnN0IGhtYWMgPSBjcnlwdG8uY3JlYXRlSG1hYygnc2hhMjU2Jywgc2VjcmV0KTtcbiAgaG1hYy51cGRhdGUoYm9keSk7XG4gIGNvbnN0IGV4cGVjdGVkU2lnID0gQnVmZmVyLmZyb20oYHNoYTI1Nj0ke2htYWMuZGlnZXN0KCdoZXgnKX1gLCAndXRmOCcpO1xuXG4gIGNvbnNvbGUubG9nKHtcbiAgICBub3RpY2U6ICdDYWxjdWxhdGVkIHNpZ25hdHVyZScsXG4gICAgc2lnbmF0dXJlOiBleHBlY3RlZFNpZy50b1N0cmluZygpLFxuICB9KTtcblxuICBpZiAoc2lnLmxlbmd0aCAhPT0gZXhwZWN0ZWRTaWcubGVuZ3RoIHx8ICFjcnlwdG8udGltaW5nU2FmZUVxdWFsKHNpZywgZXhwZWN0ZWRTaWcpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBTaWduYXR1cmUgbWlzbWF0Y2guIEV4cGVjdGVkICR7ZXhwZWN0ZWRTaWcudG9TdHJpbmcoKX0gYnV0IGdvdCAke3NpZy50b1N0cmluZygpfWApO1xuICB9XG5cbiAgcmV0dXJuIGJvZHkudG9TdHJpbmcoKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gaXNEZXBsb3ltZW50UGVuZGluZyhwYXlsb2FkOiBhbnkpIHtcbiAgY29uc3Qgc3RhdHVzZXNVcmwgPSBwYXlsb2FkLmRlcGxveW1lbnQ/LnN0YXR1c2VzX3VybDtcbiAgaWYgKHN0YXR1c2VzVXJsID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB0cnkge1xuICAgIGNvbnN0IHsgb2N0b2tpdCB9ID0gYXdhaXQgZ2V0T2N0b2tpdChwYXlsb2FkLmluc3RhbGxhdGlvbj8uaWQpO1xuICAgIGNvbnN0IHN0YXR1c2VzID0gYXdhaXQgb2N0b2tpdC5yZXF1ZXN0KHN0YXR1c2VzVXJsKTtcblxuICAgIHJldHVybiBzdGF0dXNlcy5kYXRhWzBdPy5zdGF0ZSA9PT0gJ3dhaXRpbmcnO1xuICB9IGNhdGNoIChlKSB7XG4gICAgY29uc29sZS5lcnJvcih7XG4gICAgICBub3RpY2U6ICdVbmFibGUgdG8gY2hlY2sgZGVwbG95bWVudC4gVHJ5IGFkZGluZyBkZXBsb3ltZW50IHJlYWQgcGVybWlzc2lvbi4nLFxuICAgICAgZXJyb3I6IGAke2V9YCxcbiAgICB9KTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuLyoqXG4gKiBNYXRjaCBqb2IgbGFiZWxzIHRvIGEgcHJvdmlkZXIgdXNpbmcgZGVmYXVsdCBsYWJlbCBtYXRjaGluZyBsb2dpYy5cbiAqL1xuZnVuY3Rpb24gbWF0Y2hMYWJlbHNUb1Byb3ZpZGVyKGpvYkxhYmVsczogc3RyaW5nW10sIHByb3ZpZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nW10+KTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgY29uc3Qgam9iTGFiZWxMb3dlckNhc2UgPSBqb2JMYWJlbHMubWFwKChsYWJlbCkgPT4gbGFiZWwudG9Mb3dlckNhc2UoKSk7XG5cbiAgLy8gaXMgZXZlcnkgbGFiZWwgdGhlIGpvYiByZXF1aXJlcyBhdmFpbGFibGUgaW4gdGhlIHJ1bm5lciBwcm92aWRlcj9cbiAgZm9yIChjb25zdCBwcm92aWRlciBvZiBPYmplY3Qua2V5cyhwcm92aWRlcnMpKSB7XG4gICAgY29uc3QgcHJvdmlkZXJMYWJlbHNMb3dlckNhc2UgPSBwcm92aWRlcnNbcHJvdmlkZXJdLm1hcCgobGFiZWwpID0+IGxhYmVsLnRvTG93ZXJDYXNlKCkpO1xuICAgIGlmIChqb2JMYWJlbExvd2VyQ2FzZS5ldmVyeShsYWJlbCA9PiBsYWJlbCA9PSAnc2VsZi1ob3N0ZWQnIHx8IHByb3ZpZGVyTGFiZWxzTG93ZXJDYXNlLmluY2x1ZGVzKGxhYmVsKSkpIHtcbiAgICAgIHJldHVybiBwcm92aWRlcjtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIENhbGwgdGhlIHByb3ZpZGVyIHNlbGVjdG9yIExhbWJkYSBmdW5jdGlvbiBpZiBjb25maWd1cmVkLlxuICogQGludGVybmFsXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjYWxsUHJvdmlkZXJTZWxlY3RvcihcbiAgcGF5bG9hZDogYW55LFxuICBwcm92aWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZ1tdPixcbiAgZGVmYXVsdFNlbGVjdGlvbjogUHJvdmlkZXJTZWxlY3RvclJlc3VsdCxcbik6IFByb21pc2U8UHJvdmlkZXJTZWxlY3RvclJlc3VsdCB8IHVuZGVmaW5lZD4ge1xuICBpZiAoIXByb2Nlc3MuZW52LlBST1ZJREVSX1NFTEVDVE9SX0FSTikge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25zdCBzZWxlY3RvcklucHV0OiBQcm92aWRlclNlbGVjdG9ySW5wdXQgPSB7XG4gICAgcGF5bG9hZDogcGF5bG9hZCxcbiAgICBwcm92aWRlcnM6IHByb3ZpZGVycyxcbiAgICBkZWZhdWx0UHJvdmlkZXI6IGRlZmF1bHRTZWxlY3Rpb24ucHJvdmlkZXIsXG4gICAgZGVmYXVsdExhYmVsczogZGVmYXVsdFNlbGVjdGlvbi5sYWJlbHMsXG4gIH07XG5cbiAgLy8gZG9uJ3QgY2F0Y2ggZXJyb3JzIC0tIHRoZSB3aG9sZSB3ZWJob29rIGhhbmRsZXIgd2lsbCBiZSByZXRyaWVkIG9uIHVuaGFuZGxlZCBlcnJvcnNcbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgbGFtYmRhQ2xpZW50LnNlbmQobmV3IEludm9rZUNvbW1hbmQoe1xuICAgIEZ1bmN0aW9uTmFtZTogcHJvY2Vzcy5lbnYuUFJPVklERVJfU0VMRUNUT1JfQVJOLFxuICAgIFBheWxvYWQ6IEpTT04uc3RyaW5naWZ5KHNlbGVjdG9ySW5wdXQpLFxuICB9KSk7XG5cbiAgaWYgKHJlc3VsdC5GdW5jdGlvbkVycm9yKSB7XG4gICAgY29uc3Qgc2VsZWN0b3JSZXNwb25zZVBheWxvYWQgPSByZXN1bHQuUGF5bG9hZCA/IEJ1ZmZlci5mcm9tKHJlc3VsdC5QYXlsb2FkKS50b1N0cmluZygpIDogdW5kZWZpbmVkO1xuICAgIGNvbnNvbGUuZXJyb3Ioe1xuICAgICAgbm90aWNlOiAnUHJvdmlkZXIgc2VsZWN0b3IgZmFpbGVkJyxcbiAgICAgIGZ1bmN0aW9uRXJyb3I6IHJlc3VsdC5GdW5jdGlvbkVycm9yLFxuICAgICAgcGF5bG9hZDogc2VsZWN0b3JSZXNwb25zZVBheWxvYWQsXG4gICAgfSk7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdQcm92aWRlciBzZWxlY3RvciBmYWlsZWQnKTtcbiAgfVxuXG4gIGlmICghcmVzdWx0LlBheWxvYWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Byb3ZpZGVyIHNlbGVjdG9yIHJldHVybmVkIG5vIHBheWxvYWQnKTtcbiAgfVxuXG4gIHJldHVybiBKU09OLnBhcnNlKEJ1ZmZlci5mcm9tKHJlc3VsdC5QYXlsb2FkKS50b1N0cmluZygpKSBhcyBQcm92aWRlclNlbGVjdG9yUmVzdWx0O1xufVxuXG4vKipcbiAqIEV4cG9ydGVkIGZvciB1bml0IHRlc3RpbmcuXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNlbGVjdFByb3ZpZGVyKHBheWxvYWQ6IGFueSwgam9iTGFiZWxzOiBzdHJpbmdbXSwgaG9vayA9IGNhbGxQcm92aWRlclNlbGVjdG9yKTogUHJvbWlzZTxQcm92aWRlclNlbGVjdG9yUmVzdWx0PiB7XG4gIGNvbnN0IHByb3ZpZGVycyA9IEpTT04ucGFyc2UocHJvY2Vzcy5lbnYuUFJPVklERVJTISk7XG4gIGNvbnN0IGRlZmF1bHRQcm92aWRlciA9IG1hdGNoTGFiZWxzVG9Qcm92aWRlcihqb2JMYWJlbHMsIHByb3ZpZGVycyk7XG4gIGNvbnN0IGRlZmF1bHRMYWJlbHMgPSBkZWZhdWx0UHJvdmlkZXIgPyBwcm92aWRlcnNbZGVmYXVsdFByb3ZpZGVyXSA6IHVuZGVmaW5lZDtcbiAgY29uc3QgZGVmYXVsdFNlbGVjdGlvbiA9IHsgcHJvdmlkZXI6IGRlZmF1bHRQcm92aWRlciwgbGFiZWxzOiBkZWZhdWx0TGFiZWxzIH07XG4gIGNvbnN0IHNlbGVjdG9yUmVzdWx0ID0gYXdhaXQgaG9vayhwYXlsb2FkLCBwcm92aWRlcnMsIGRlZmF1bHRTZWxlY3Rpb24pO1xuXG4gIGlmIChzZWxlY3RvclJlc3VsdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGRlZmF1bHRTZWxlY3Rpb247XG4gIH1cblxuICBjb25zb2xlLmxvZyh7XG4gICAgbm90aWNlOiAnQmVmb3JlIHByb3ZpZGVyIHNlbGVjdG9yJyxcbiAgICBwcm92aWRlcjogZGVmYXVsdFByb3ZpZGVyLFxuICAgIGxhYmVsczogZGVmYXVsdExhYmVscyxcbiAgICBqb2JMYWJlbHM6IGpvYkxhYmVscyxcbiAgfSk7XG4gIGNvbnNvbGUubG9nKHtcbiAgICBub3RpY2U6ICdBZnRlciBwcm92aWRlciBzZWxlY3RvcicsXG4gICAgcHJvdmlkZXI6IHNlbGVjdG9yUmVzdWx0LnByb3ZpZGVyLFxuICAgIGxhYmVsczogc2VsZWN0b3JSZXN1bHQubGFiZWxzLFxuICAgIGpvYkxhYmVsczogam9iTGFiZWxzLFxuICB9KTtcblxuICAvLyBhbnkgZXJyb3IgaGVyZSB3aWxsIGZhaWwgdGhlIHdlYmhvb2sgYW5kIGNhdXNlIGEgcmV0cnkgc28gdGhlIHNlbGVjdG9yIGhhcyBhbm90aGVyIGNoYW5jZSB0byBnZXQgaXQgcmlnaHRcbiAgaWYgKHNlbGVjdG9yUmVzdWx0LnByb3ZpZGVyICE9PSB1bmRlZmluZWQpIHtcbiAgICBpZiAoc2VsZWN0b3JSZXN1bHQucHJvdmlkZXIgPT09ICcnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Byb3ZpZGVyIHNlbGVjdG9yIHJldHVybmVkIGVtcHR5IHByb3ZpZGVyJyk7XG4gICAgfVxuICAgIGlmICghcHJvdmlkZXJzW3NlbGVjdG9yUmVzdWx0LnByb3ZpZGVyXSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBQcm92aWRlciBzZWxlY3RvciByZXR1cm5lZCB1bmtub3duIHByb3ZpZGVyICR7c2VsZWN0b3JSZXN1bHQucHJvdmlkZXJ9YCk7XG4gICAgfVxuICAgIGlmIChzZWxlY3RvclJlc3VsdC5sYWJlbHMgPT09IHVuZGVmaW5lZCB8fCBzZWxlY3RvclJlc3VsdC5sYWJlbHMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Byb3ZpZGVyIHNlbGVjdG9yIG11c3QgcmV0dXJuIG5vbi1lbXB0eSBsYWJlbHMgd2hlbiBwcm92aWRlciBpcyBzZXQnKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gc2VsZWN0b3JSZXN1bHQ7XG59XG5cbi8qKlxuICogR2VuZXJhdGUgYSB1bmlxdWUgZXhlY3V0aW9uIG5hbWUgd2hpY2ggaXMgbGltaXRlZCB0byA2NCBjaGFyYWN0ZXJzIChhbHNvIHVzZWQgYXMgcnVubmVyIG5hbWUpLlxuICpcbiAqIEV4cG9ydGVkIGZvciB1bml0IHRlc3RpbmcuXG4gKlxuICogQGludGVybmFsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZUV4ZWN1dGlvbk5hbWUoZXZlbnQ6IGFueSwgcGF5bG9hZDogYW55KTogc3RyaW5nIHtcbiAgY29uc3QgZGVsaXZlcnlJZCA9IGdldEhlYWRlcihldmVudCwgJ3gtZ2l0aHViLWRlbGl2ZXJ5JykgPz8gYCR7TWF0aC5yYW5kb20oKX1gO1xuICBjb25zdCByZXBvTmFtZVRydW5jYXRlZCA9IHBheWxvYWQucmVwb3NpdG9yeS5uYW1lLnNsaWNlKDAsIDY0IC0gZGVsaXZlcnlJZC5sZW5ndGggLSAxKTtcbiAgcmV0dXJuIGAke3JlcG9OYW1lVHJ1bmNhdGVkfS0ke2RlbGl2ZXJ5SWR9YDtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZXIoZXZlbnQ6IEFXU0xhbWJkYS5BUElHYXRld2F5UHJveHlFdmVudFYyKTogUHJvbWlzZTxBV1NMYW1iZGEuQVBJR2F0ZXdheVByb3h5UmVzdWx0VjI+IHtcbiAgaWYgKCFwcm9jZXNzLmVudi5XRUJIT09LX1NFQ1JFVF9BUk4gfHwgIXByb2Nlc3MuZW52LlNURVBfRlVOQ1RJT05fQVJOIHx8ICFwcm9jZXNzLmVudi5QUk9WSURFUlMgfHwgIXByb2Nlc3MuZW52LlJFUVVJUkVfU0VMRl9IT1NURURfTEFCRUwpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgZW52aXJvbm1lbnQgdmFyaWFibGVzJyk7XG4gIH1cblxuICBjb25zdCB3ZWJob29rU2VjcmV0ID0gKGF3YWl0IGdldFNlY3JldEpzb25WYWx1ZShwcm9jZXNzLmVudi5XRUJIT09LX1NFQ1JFVF9BUk4pKS53ZWJob29rU2VjcmV0O1xuXG4gIGxldCBib2R5O1xuICB0cnkge1xuICAgIGJvZHkgPSB2ZXJpZnlCb2R5KGV2ZW50LCB3ZWJob29rU2VjcmV0KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGNvbnNvbGUuZXJyb3Ioe1xuICAgICAgbm90aWNlOiAnQmFkIHNpZ25hdHVyZScsXG4gICAgICBlcnJvcjogYCR7ZX1gLFxuICAgIH0pO1xuICAgIHJldHVybiB7XG4gICAgICBzdGF0dXNDb2RlOiA0MDMsXG4gICAgICBib2R5OiAnQmFkIHNpZ25hdHVyZScsXG4gICAgfTtcbiAgfVxuXG4gIGlmIChnZXRIZWFkZXIoZXZlbnQsICdjb250ZW50LXR5cGUnKSAhPT0gJ2FwcGxpY2F0aW9uL2pzb24nKSB7XG4gICAgY29uc29sZS5lcnJvcih7XG4gICAgICBub3RpY2U6ICdUaGlzIHdlYmhvb2sgb25seSBhY2NlcHRzIEpTT04gcGF5bG9hZHMnLFxuICAgICAgY29udGVudFR5cGU6IGdldEhlYWRlcihldmVudCwgJ2NvbnRlbnQtdHlwZScpLFxuICAgIH0pO1xuICAgIHJldHVybiB7XG4gICAgICBzdGF0dXNDb2RlOiA0MDAsXG4gICAgICBib2R5OiAnRXhwZWN0aW5nIEpTT04gcGF5bG9hZCcsXG4gICAgfTtcbiAgfVxuXG4gIGlmIChnZXRIZWFkZXIoZXZlbnQsICd4LWdpdGh1Yi1ldmVudCcpID09PSAncGluZycpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzQ29kZTogMjAwLFxuICAgICAgYm9keTogJ1BvbmcnLFxuICAgIH07XG4gIH1cblxuICAvLyBpZiAoZ2V0SGVhZGVyKGV2ZW50LCAneC1naXRodWItZXZlbnQnKSAhPT0gJ3dvcmtmbG93X2pvYicgJiYgZ2V0SGVhZGVyKGV2ZW50LCAneC1naXRodWItZXZlbnQnKSAhPT0gJ3dvcmtmbG93X3J1bicpIHtcbiAgLy8gICAgIGNvbnNvbGUuZXJyb3IoYFRoaXMgd2ViaG9vayBvbmx5IGFjY2VwdHMgd29ya2Zsb3dfam9iIGFuZCB3b3JrZmxvd19ydW4sIGdvdCAke2dldEhlYWRlcihldmVudCwgJ3gtZ2l0aHViLWV2ZW50Jyl9YCk7XG4gIGlmIChnZXRIZWFkZXIoZXZlbnQsICd4LWdpdGh1Yi1ldmVudCcpICE9PSAnd29ya2Zsb3dfam9iJykge1xuICAgIGNvbnNvbGUuZXJyb3Ioe1xuICAgICAgbm90aWNlOiAnVGhpcyB3ZWJob29rIG9ubHkgYWNjZXB0cyB3b3JrZmxvd19qb2InLFxuICAgICAgZ2l0aHViRXZlbnQ6IGdldEhlYWRlcihldmVudCwgJ3gtZ2l0aHViLWV2ZW50JyksXG4gICAgfSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXR1c0NvZGU6IDIwMCxcbiAgICAgIGJvZHk6ICdFeHBlY3Rpbmcgd29ya2Zsb3dfam9iJyxcbiAgICB9O1xuICB9XG5cbiAgY29uc3QgcGF5bG9hZCA9IEpTT04ucGFyc2UoYm9keSk7XG5cbiAgaWYgKHBheWxvYWQuYWN0aW9uICE9PSAncXVldWVkJykge1xuICAgIGNvbnNvbGUubG9nKHtcbiAgICAgIG5vdGljZTogYElnbm9yaW5nIGFjdGlvbiBcIiR7cGF5bG9hZC5hY3Rpb259XCIsIGV4cGVjdGluZyBcInF1ZXVlZFwiYCxcbiAgICAgIGpvYjogcGF5bG9hZC53b3JrZmxvd19qb2IsXG4gICAgfSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXR1c0NvZGU6IDIwMCxcbiAgICAgIGJvZHk6ICdPSy4gTm8gcnVubmVyIHN0YXJ0ZWQgKGFjdGlvbiBpcyBub3QgXCJxdWV1ZWRcIikuJyxcbiAgICB9O1xuICB9XG5cbiAgaWYgKHByb2Nlc3MuZW52LlJFUVVJUkVfU0VMRl9IT1NURURfTEFCRUwgPT09ICcxJyAmJiAhcGF5bG9hZC53b3JrZmxvd19qb2IubGFiZWxzLmluY2x1ZGVzKCdzZWxmLWhvc3RlZCcpKSB7XG4gICAgY29uc29sZS5sb2coe1xuICAgICAgbm90aWNlOiBgSWdub3JpbmcgbGFiZWxzIFwiJHtwYXlsb2FkLndvcmtmbG93X2pvYi5sYWJlbHN9XCIsIGV4cGVjdGluZyBcInNlbGYtaG9zdGVkXCJgLFxuICAgICAgam9iOiBwYXlsb2FkLndvcmtmbG93X2pvYixcbiAgICB9KTtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzQ29kZTogMjAwLFxuICAgICAgYm9keTogJ09LLiBObyBydW5uZXIgc3RhcnRlZCAobm8gXCJzZWxmLWhvc3RlZFwiIGxhYmVsKS4nLFxuICAgIH07XG4gIH1cblxuICAvLyBTZWxlY3QgcHJvdmlkZXIgYW5kIGxhYmVsc1xuICBjb25zdCBzZWxlY3Rpb24gPSBhd2FpdCBzZWxlY3RQcm92aWRlcihwYXlsb2FkLCBwYXlsb2FkLndvcmtmbG93X2pvYi5sYWJlbHMpO1xuICBpZiAoIXNlbGVjdGlvbi5wcm92aWRlciB8fCAhc2VsZWN0aW9uLmxhYmVscykge1xuICAgIGNvbnNvbGUubG9nKHtcbiAgICAgIG5vdGljZTogYElnbm9yaW5nIGxhYmVscyBcIiR7cGF5bG9hZC53b3JrZmxvd19qb2IubGFiZWxzfVwiLCBhcyB0aGV5IGRvbid0IG1hdGNoIGEgc3VwcG9ydGVkIHJ1bm5lciBwcm92aWRlcmAsXG4gICAgICBqb2I6IHBheWxvYWQud29ya2Zsb3dfam9iLFxuICAgIH0pO1xuICAgIHJldHVybiB7XG4gICAgICBzdGF0dXNDb2RlOiAyMDAsXG4gICAgICBib2R5OiAnT0suIE5vIHJ1bm5lciBzdGFydGVkIChubyBwcm92aWRlciB3aXRoIG1hdGNoaW5nIGxhYmVscykuJyxcbiAgICB9O1xuICB9XG5cbiAgLy8gZG9uJ3Qgc3RhcnQgcnVubmVycyBmb3IgYSBkZXBsb3ltZW50IHRoYXQncyBzdGlsbCBwZW5kaW5nIGFzIEdpdEh1YiB3aWxsIHNlbmQgYW5vdGhlciBldmVudCB3aGVuIGl0J3MgcmVhZHlcbiAgaWYgKGF3YWl0IGlzRGVwbG95bWVudFBlbmRpbmcocGF5bG9hZCkpIHtcbiAgICBjb25zb2xlLmxvZyh7XG4gICAgICBub3RpY2U6ICdJZ25vcmluZyBqb2IgYXMgaXRzIGRlcGxveW1lbnQgaXMgc3RpbGwgcGVuZGluZycsXG4gICAgICBqb2I6IHBheWxvYWQud29ya2Zsb3dfam9iLFxuICAgIH0pO1xuICAgIHJldHVybiB7XG4gICAgICBzdGF0dXNDb2RlOiAyMDAsXG4gICAgICBib2R5OiAnT0suIE5vIHJ1bm5lciBzdGFydGVkIChkZXBsb3ltZW50IHBlbmRpbmcpLicsXG4gICAgfTtcbiAgfVxuXG4gIC8vIHN0YXJ0IGV4ZWN1dGlvblxuICBjb25zdCBleGVjdXRpb25OYW1lID0gZ2VuZXJhdGVFeGVjdXRpb25OYW1lKGV2ZW50LCBwYXlsb2FkKTtcbiAgY29uc3QgaW5wdXQgPSB7XG4gICAgb3duZXI6IHBheWxvYWQucmVwb3NpdG9yeS5vd25lci5sb2dpbixcbiAgICByZXBvOiBwYXlsb2FkLnJlcG9zaXRvcnkubmFtZSxcbiAgICBqb2JJZDogcGF5bG9hZC53b3JrZmxvd19qb2IuaWQsXG4gICAgam9iVXJsOiBwYXlsb2FkLndvcmtmbG93X2pvYi5odG1sX3VybCxcbiAgICBpbnN0YWxsYXRpb25JZDogcGF5bG9hZC5pbnN0YWxsYXRpb24/LmlkID8/IC0xLCAvLyBhbHdheXMgcGFzcyB2YWx1ZSBiZWNhdXNlIHN0ZXAgZnVuY3Rpb24gY2FuJ3QgaGFuZGxlIG1pc3NpbmcgaW5wdXRcbiAgICBqb2JMYWJlbHM6IHBheWxvYWQud29ya2Zsb3dfam9iLmxhYmVscy5qb2luKCcsJyksIC8vIG9yaWdpbmFsIGxhYmVscyByZXF1ZXN0ZWQgYnkgdGhlIGpvYlxuICAgIHByb3ZpZGVyOiBzZWxlY3Rpb24ucHJvdmlkZXIsXG4gICAgbGFiZWxzOiBzZWxlY3Rpb24ubGFiZWxzLmpvaW4oJywnKSwgLy8gbGFiZWxzIHRvIHVzZSB3aGVuIHJlZ2lzdGVyaW5nIHJ1bm5lclxuICB9O1xuICBjb25zdCBleGVjdXRpb24gPSBhd2FpdCBzZi5zZW5kKG5ldyBTdGFydEV4ZWN1dGlvbkNvbW1hbmQoe1xuICAgIHN0YXRlTWFjaGluZUFybjogcHJvY2Vzcy5lbnYuU1RFUF9GVU5DVElPTl9BUk4sXG4gICAgaW5wdXQ6IEpTT04uc3RyaW5naWZ5KGlucHV0KSxcbiAgICAvLyBuYW1lIGlzIG5vdCByYW5kb20gc28gbXVsdGlwbGUgZXhlY3V0aW9uIG9mIHRoaXMgd2ViaG9vayB3b24ndCBjYXVzZSBtdWx0aXBsZSBidWlsZGVycyB0byBzdGFydFxuICAgIG5hbWU6IGV4ZWN1dGlvbk5hbWUsXG4gIH0pKTtcblxuICBjb25zb2xlLmxvZyh7XG4gICAgbm90aWNlOiAnU3RhcnRlZCBvcmNoZXN0cmF0b3InLFxuICAgIGV4ZWN1dGlvbjogZXhlY3V0aW9uLmV4ZWN1dGlvbkFybixcbiAgICBzZm5JbnB1dDogaW5wdXQsXG4gICAgam9iOiBwYXlsb2FkLndvcmtmbG93X2pvYixcbiAgfSk7XG5cbiAgcmV0dXJuIHtcbiAgICBzdGF0dXNDb2RlOiAyMDIsXG4gICAgYm9keTogZXhlY3V0aW9uTmFtZSxcbiAgfTtcbn1cbiJdfQ==
291
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ViaG9vay1oYW5kbGVyLmxhbWJkYS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy93ZWJob29rLWhhbmRsZXIubGFtYmRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBNEJBLGdDQTRCQztBQTJDRCxvREFxQ0M7QUFNRCx3Q0FzQ0M7QUFTRCxzREFJQztBQUVELDBCQXFJQztBQXhVRCxpQ0FBaUM7QUFDakMsMERBQXFFO0FBQ3JFLG9EQUF1RTtBQUV2RSxtREFBNkM7QUFDN0MscURBQXNEO0FBR3RELE1BQU0sRUFBRSxHQUFHLElBQUksc0JBQVMsRUFBRSxDQUFDO0FBQzNCLE1BQU0sWUFBWSxHQUFHLElBQUksNEJBQVksRUFBRSxDQUFDO0FBRXhDLDhCQUE4QjtBQUU5QixTQUFTLFNBQVMsQ0FBQyxLQUF1QyxFQUFFLE1BQWM7SUFDeEUsb0ZBQW9GO0lBQ3BGLEtBQUssTUFBTSxVQUFVLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztRQUNwRCxJQUFJLFVBQVUsQ0FBQyxXQUFXLEVBQUUsS0FBSyxNQUFNLENBQUMsV0FBVyxFQUFFLEVBQUUsQ0FBQztZQUN0RCxPQUFPLEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDbkMsQ0FBQztJQUNILENBQUM7SUFFRCxPQUFPLFNBQVMsQ0FBQztBQUNuQixDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsU0FBZ0IsVUFBVSxDQUFDLEtBQXVDLEVBQUUsTUFBVztJQUM3RSxNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUscUJBQXFCLENBQUMsSUFBSSxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFFL0UsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNoQixNQUFNLElBQUksS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzdCLENBQUM7SUFFRCxJ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SW52b2tlQ29tbWFuZCwgTGFtYmRhQ2xpZW50IH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LWxhbWJkYSc7XG5pbXBvcnQgeyBTRk5DbGllbnQsIFN0YXJ0RXhlY3V0aW9uQ29tbWFuZCB9IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1zZm4nO1xuaW1wb3J0ICogYXMgQVdTTGFtYmRhIGZyb20gJ2F3cy1sYW1iZGEnO1xuaW1wb3J0IHsgZ2V0T2N0b2tpdCB9IGZyb20gJy4vbGFtYmRhLWdpdGh1Yic7XG5pbXBvcnQgeyBnZXRTZWNyZXRKc29uVmFsdWUgfSBmcm9tICcuL2xhbWJkYS1oZWxwZXJzJztcbmltcG9ydCB7IFByb3ZpZGVyU2VsZWN0b3JJbnB1dCwgUHJvdmlkZXJTZWxlY3RvclJlc3VsdCB9IGZyb20gJy4vd2ViaG9vayc7XG5cbmNvbnN0IHNmID0gbmV3IFNGTkNsaWVudCgpO1xuY29uc3QgbGFtYmRhQ2xpZW50ID0gbmV3IExhbWJkYUNsaWVudCgpO1xuXG4vLyBUT0RPIHVzZSBAb2N0b2tpdC93ZWJob29rcz9cblxuZnVuY3Rpb24gZ2V0SGVhZGVyKGV2ZW50OiBBV1NMYW1iZGEuQVBJR2F0ZXdheVByb3h5RXZlbnRWMiwgaGVhZGVyOiBzdHJpbmcpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAvLyBBUEkgR2F0ZXdheSBkb2Vzbid0IGxvd2VyY2FzZSBoZWFkZXJzIChWMSBldmVudCkgYnV0IExhbWJkYSBVUkxzIGRvIChWMiBldmVudCkgOihcbiAgZm9yIChjb25zdCBoZWFkZXJOYW1lIG9mIE9iamVjdC5rZXlzKGV2ZW50LmhlYWRlcnMpKSB7XG4gICAgaWYgKGhlYWRlck5hbWUudG9Mb3dlckNhc2UoKSA9PT0gaGVhZGVyLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgIHJldHVybiBldmVudC5oZWFkZXJzW2hlYWRlck5hbWVdO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogRXhwb3J0ZWQgZm9yIHVuaXQgdGVzdGluZy5cbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgZnVuY3Rpb24gdmVyaWZ5Qm9keShldmVudDogQVdTTGFtYmRhLkFQSUdhdGV3YXlQcm94eUV2ZW50VjIsIHNlY3JldDogYW55KTogc3RyaW5nIHtcbiAgY29uc3Qgc2lnID0gQnVmZmVyLmZyb20oZ2V0SGVhZGVyKGV2ZW50LCAneC1odWItc2lnbmF0dXJlLTI1NicpIHx8ICcnLCAndXRmOCcpO1xuXG4gIGlmICghZXZlbnQuYm9keSkge1xuICAgIHRocm93IG5ldyBFcnJvcignTm8gYm9keScpO1xuICB9XG5cbiAgbGV0IGJvZHk6IEJ1ZmZlcjtcbiAgaWYgKGV2ZW50LmlzQmFzZTY0RW5jb2RlZCkge1xuICAgIGJvZHkgPSBCdWZmZXIuZnJvbShldmVudC5ib2R5LCAnYmFzZTY0Jyk7XG4gIH0gZWxzZSB7XG4gICAgYm9keSA9IEJ1ZmZlci5mcm9tKGV2ZW50LmJvZHkgfHwgJycsICd1dGY4Jyk7XG4gIH1cblxuICBjb25zdCBobWFjID0gY3J5cHRvLmNyZWF0ZUhtYWMoJ3NoYTI1NicsIHNlY3JldCk7XG4gIGhtYWMudXBkYXRlKGJvZHkpO1xuICBjb25zdCBleHBlY3RlZFNpZyA9IEJ1ZmZlci5mcm9tKGBzaGEyNTY9JHtobWFjLmRpZ2VzdCgnaGV4Jyl9YCwgJ3V0ZjgnKTtcblxuICBjb25zb2xlLmxvZyh7XG4gICAgbm90aWNlOiAnQ2FsY3VsYXRlZCBzaWduYXR1cmUnLFxuICAgIHNpZ25hdHVyZTogZXhwZWN0ZWRTaWcudG9TdHJpbmcoKSxcbiAgfSk7XG5cbiAgaWYgKHNpZy5sZW5ndGggIT09IGV4cGVjdGVkU2lnLmxlbmd0aCB8fCAhY3J5cHRvLnRpbWluZ1NhZmVFcXVhbChzaWcsIGV4cGVjdGVkU2lnKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgU2lnbmF0dXJlIG1pc21hdGNoLiBFeHBlY3RlZCAke2V4cGVjdGVkU2lnLnRvU3RyaW5nKCl9IGJ1dCBnb3QgJHtzaWcudG9TdHJpbmcoKX1gKTtcbiAgfVxuXG4gIHJldHVybiBib2R5LnRvU3RyaW5nKCk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGlzRGVwbG95bWVudFBlbmRpbmcocGF5bG9hZDogYW55KSB7XG4gIGNvbnN0IHN0YXR1c2VzVXJsID0gcGF5bG9hZC5kZXBsb3ltZW50Py5zdGF0dXNlc191cmw7XG4gIGlmIChzdGF0dXNlc1VybCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBjb25zdCB7IG9jdG9raXQgfSA9IGF3YWl0IGdldE9jdG9raXQocGF5bG9hZC5pbnN0YWxsYXRpb24/LmlkKTtcbiAgICBjb25zdCBzdGF0dXNlcyA9IGF3YWl0IG9jdG9raXQucmVxdWVzdChzdGF0dXNlc1VybCk7XG5cbiAgICByZXR1cm4gc3RhdHVzZXMuZGF0YVswXT8uc3RhdGUgPT09ICd3YWl0aW5nJztcbiAgfSBjYXRjaCAoZSkge1xuICAgIGNvbnNvbGUuZXJyb3Ioe1xuICAgICAgbm90aWNlOiAnVW5hYmxlIHRvIGNoZWNrIGRlcGxveW1lbnQuIFRyeSBhZGRpbmcgZGVwbG95bWVudCByZWFkIHBlcm1pc3Npb24uJyxcbiAgICAgIGVycm9yOiBlLFxuICAgIH0pO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG4vKipcbiAqIE1hdGNoIGpvYiBsYWJlbHMgdG8gYSBwcm92aWRlciB1c2luZyBkZWZhdWx0IGxhYmVsIG1hdGNoaW5nIGxvZ2ljLlxuICovXG5mdW5jdGlvbiBtYXRjaExhYmVsc1RvUHJvdmlkZXIoam9iTGFiZWxzOiBzdHJpbmdbXSwgcHJvdmlkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmdbXT4pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCBqb2JMYWJlbExvd2VyQ2FzZSA9IGpvYkxhYmVscy5tYXAoKGxhYmVsKSA9PiBsYWJlbC50b0xvd2VyQ2FzZSgpKTtcblxuICAvLyBpcyBldmVyeSBsYWJlbCB0aGUgam9iIHJlcXVpcmVzIGF2YWlsYWJsZSBpbiB0aGUgcnVubmVyIHByb3ZpZGVyP1xuICBmb3IgKGNvbnN0IHByb3ZpZGVyIG9mIE9iamVjdC5rZXlzKHByb3ZpZGVycykpIHtcbiAgICBjb25zdCBwcm92aWRlckxhYmVsc0xvd2VyQ2FzZSA9IHByb3ZpZGVyc1twcm92aWRlcl0ubWFwKChsYWJlbCkgPT4gbGFiZWwudG9Mb3dlckNhc2UoKSk7XG4gICAgaWYgKGpvYkxhYmVsTG93ZXJDYXNlLmV2ZXJ5KGxhYmVsID0+IGxhYmVsID09ICdzZWxmLWhvc3RlZCcgfHwgcHJvdmlkZXJMYWJlbHNMb3dlckNhc2UuaW5jbHVkZXMobGFiZWwpKSkge1xuICAgICAgcmV0dXJuIHByb3ZpZGVyO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogQ2FsbCB0aGUgcHJvdmlkZXIgc2VsZWN0b3IgTGFtYmRhIGZ1bmN0aW9uIGlmIGNvbmZpZ3VyZWQuXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNhbGxQcm92aWRlclNlbGVjdG9yKFxuICBwYXlsb2FkOiBhbnksXG4gIHByb3ZpZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nW10+LFxuICBkZWZhdWx0U2VsZWN0aW9uOiBQcm92aWRlclNlbGVjdG9yUmVzdWx0LFxuKTogUHJvbWlzZTxQcm92aWRlclNlbGVjdG9yUmVzdWx0IHwgdW5kZWZpbmVkPiB7XG4gIGlmICghcHJvY2Vzcy5lbnYuUFJPVklERVJfU0VMRUNUT1JfQVJOKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGNvbnN0IHNlbGVjdG9ySW5wdXQ6IFByb3ZpZGVyU2VsZWN0b3JJbnB1dCA9IHtcbiAgICBwYXlsb2FkOiBwYXlsb2FkLFxuICAgIHByb3ZpZGVyczogcHJvdmlkZXJzLFxuICAgIGRlZmF1bHRQcm92aWRlcjogZGVmYXVsdFNlbGVjdGlvbi5wcm92aWRlcixcbiAgICBkZWZhdWx0TGFiZWxzOiBkZWZhdWx0U2VsZWN0aW9uLmxhYmVscyxcbiAgfTtcblxuICAvLyBkb24ndCBjYXRjaCBlcnJvcnMgLS0gdGhlIHdob2xlIHdlYmhvb2sgaGFuZGxlciB3aWxsIGJlIHJldHJpZWQgb24gdW5oYW5kbGVkIGVycm9yc1xuICBjb25zdCByZXN1bHQgPSBhd2FpdCBsYW1iZGFDbGllbnQuc2VuZChuZXcgSW52b2tlQ29tbWFuZCh7XG4gICAgRnVuY3Rpb25OYW1lOiBwcm9jZXNzLmVudi5QUk9WSURFUl9TRUxFQ1RPUl9BUk4sXG4gICAgUGF5bG9hZDogSlNPTi5zdHJpbmdpZnkoc2VsZWN0b3JJbnB1dCksXG4gIH0pKTtcblxuICBpZiAocmVzdWx0LkZ1bmN0aW9uRXJyb3IpIHtcbiAgICBjb25zdCBzZWxlY3RvclJlc3BvbnNlUGF5bG9hZCA9IHJlc3VsdC5QYXlsb2FkID8gQnVmZmVyLmZyb20ocmVzdWx0LlBheWxvYWQpLnRvU3RyaW5nKCkgOiB1bmRlZmluZWQ7XG4gICAgY29uc29sZS5lcnJvcih7XG4gICAgICBub3RpY2U6ICdQcm92aWRlciBzZWxlY3RvciBmYWlsZWQnLFxuICAgICAgZnVuY3Rpb25FcnJvcjogcmVzdWx0LkZ1bmN0aW9uRXJyb3IsXG4gICAgICBwYXlsb2FkOiBzZWxlY3RvclJlc3BvbnNlUGF5bG9hZCxcbiAgICB9KTtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Byb3ZpZGVyIHNlbGVjdG9yIGZhaWxlZCcpO1xuICB9XG5cbiAgaWYgKCFyZXN1bHQuUGF5bG9hZCkge1xuICAgIHRocm93IG5ldyBFcnJvcignUHJvdmlkZXIgc2VsZWN0b3IgcmV0dXJuZWQgbm8gcGF5bG9hZCcpO1xuICB9XG5cbiAgcmV0dXJuIEpTT04ucGFyc2UoQnVmZmVyLmZyb20ocmVzdWx0LlBheWxvYWQpLnRvU3RyaW5nKCkpIGFzIFByb3ZpZGVyU2VsZWN0b3JSZXN1bHQ7XG59XG5cbi8qKlxuICogRXhwb3J0ZWQgZm9yIHVuaXQgdGVzdGluZy5cbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2VsZWN0UHJvdmlkZXIocGF5bG9hZDogYW55LCBqb2JMYWJlbHM6IHN0cmluZ1tdLCBob29rID0gY2FsbFByb3ZpZGVyU2VsZWN0b3IpOiBQcm9taXNlPFByb3ZpZGVyU2VsZWN0b3JSZXN1bHQ+IHtcbiAgY29uc3QgcHJvdmlkZXJzID0gSlNPTi5wYXJzZShwcm9jZXNzLmVudi5QUk9WSURFUlMhKTtcbiAgY29uc3QgZGVmYXVsdFByb3ZpZGVyID0gbWF0Y2hMYWJlbHNUb1Byb3ZpZGVyKGpvYkxhYmVscywgcHJvdmlkZXJzKTtcbiAgY29uc3QgZGVmYXVsdExhYmVscyA9IGRlZmF1bHRQcm92aWRlciA/IHByb3ZpZGVyc1tkZWZhdWx0UHJvdmlkZXJdIDogdW5kZWZpbmVkO1xuICBjb25zdCBkZWZhdWx0U2VsZWN0aW9uID0geyBwcm92aWRlcjogZGVmYXVsdFByb3ZpZGVyLCBsYWJlbHM6IGRlZmF1bHRMYWJlbHMgfTtcbiAgY29uc3Qgc2VsZWN0b3JSZXN1bHQgPSBhd2FpdCBob29rKHBheWxvYWQsIHByb3ZpZGVycywgZGVmYXVsdFNlbGVjdGlvbik7XG5cbiAgaWYgKHNlbGVjdG9yUmVzdWx0ID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gZGVmYXVsdFNlbGVjdGlvbjtcbiAgfVxuXG4gIGNvbnNvbGUubG9nKHtcbiAgICBub3RpY2U6ICdCZWZvcmUgcHJvdmlkZXIgc2VsZWN0b3InLFxuICAgIHByb3ZpZGVyOiBkZWZhdWx0UHJvdmlkZXIsXG4gICAgbGFiZWxzOiBkZWZhdWx0TGFiZWxzLFxuICAgIGpvYkxhYmVsczogam9iTGFiZWxzLFxuICB9KTtcbiAgY29uc29sZS5sb2coe1xuICAgIG5vdGljZTogJ0FmdGVyIHByb3ZpZGVyIHNlbGVjdG9yJyxcbiAgICBwcm92aWRlcjogc2VsZWN0b3JSZXN1bHQucHJvdmlkZXIsXG4gICAgbGFiZWxzOiBzZWxlY3RvclJlc3VsdC5sYWJlbHMsXG4gICAgam9iTGFiZWxzOiBqb2JMYWJlbHMsXG4gIH0pO1xuXG4gIC8vIGFueSBlcnJvciBoZXJlIHdpbGwgZmFpbCB0aGUgd2ViaG9vayBhbmQgY2F1c2UgYSByZXRyeSBzbyB0aGUgc2VsZWN0b3IgaGFzIGFub3RoZXIgY2hhbmNlIHRvIGdldCBpdCByaWdodFxuICBpZiAoc2VsZWN0b3JSZXN1bHQucHJvdmlkZXIgIT09IHVuZGVmaW5lZCkge1xuICAgIGlmIChzZWxlY3RvclJlc3VsdC5wcm92aWRlciA9PT0gJycpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUHJvdmlkZXIgc2VsZWN0b3IgcmV0dXJuZWQgZW1wdHkgcHJvdmlkZXInKTtcbiAgICB9XG4gICAgaWYgKCFwcm92aWRlcnNbc2VsZWN0b3JSZXN1bHQucHJvdmlkZXJdKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFByb3ZpZGVyIHNlbGVjdG9yIHJldHVybmVkIHVua25vd24gcHJvdmlkZXIgJHtzZWxlY3RvclJlc3VsdC5wcm92aWRlcn1gKTtcbiAgICB9XG4gICAgaWYgKHNlbGVjdG9yUmVzdWx0LmxhYmVscyA9PT0gdW5kZWZpbmVkIHx8IHNlbGVjdG9yUmVzdWx0LmxhYmVscy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUHJvdmlkZXIgc2VsZWN0b3IgbXVzdCByZXR1cm4gbm9uLWVtcHR5IGxhYmVscyB3aGVuIHByb3ZpZGVyIGlzIHNldCcpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBzZWxlY3RvclJlc3VsdDtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSBhIHVuaXF1ZSBleGVjdXRpb24gbmFtZSB3aGljaCBpcyBsaW1pdGVkIHRvIDY0IGNoYXJhY3RlcnMgKGFsc28gdXNlZCBhcyBydW5uZXIgbmFtZSkuXG4gKlxuICogRXhwb3J0ZWQgZm9yIHVuaXQgdGVzdGluZy5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlRXhlY3V0aW9uTmFtZShldmVudDogYW55LCBwYXlsb2FkOiBhbnkpOiBzdHJpbmcge1xuICBjb25zdCBkZWxpdmVyeUlkID0gZ2V0SGVhZGVyKGV2ZW50LCAneC1naXRodWItZGVsaXZlcnknKSA/PyBgJHtNYXRoLnJhbmRvbSgpfWA7XG4gIGNvbnN0IHJlcG9OYW1lVHJ1bmNhdGVkID0gcGF5bG9hZC5yZXBvc2l0b3J5Lm5hbWUuc2xpY2UoMCwgNjQgLSBkZWxpdmVyeUlkLmxlbmd0aCAtIDEpO1xuICByZXR1cm4gYCR7cmVwb05hbWVUcnVuY2F0ZWR9LSR7ZGVsaXZlcnlJZH1gO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaGFuZGxlcihldmVudDogQVdTTGFtYmRhLkFQSUdhdGV3YXlQcm94eUV2ZW50VjIpOiBQcm9taXNlPEFXU0xhbWJkYS5BUElHYXRld2F5UHJveHlSZXN1bHRWMj4ge1xuICBpZiAoIXByb2Nlc3MuZW52LldFQkhPT0tfU0VDUkVUX0FSTiB8fCAhcHJvY2Vzcy5lbnYuU1RFUF9GVU5DVElPTl9BUk4gfHwgIXByb2Nlc3MuZW52LlBST1ZJREVSUyB8fCAhcHJvY2Vzcy5lbnYuUkVRVUlSRV9TRUxGX0hPU1RFRF9MQUJFTCkge1xuICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBlbnZpcm9ubWVudCB2YXJpYWJsZXMnKTtcbiAgfVxuXG4gIGNvbnN0IHdlYmhvb2tTZWNyZXQgPSAoYXdhaXQgZ2V0U2VjcmV0SnNvblZhbHVlKHByb2Nlc3MuZW52LldFQkhPT0tfU0VDUkVUX0FSTikpLndlYmhvb2tTZWNyZXQ7XG5cbiAgbGV0IGJvZHk7XG4gIHRyeSB7XG4gICAgYm9keSA9IHZlcmlmeUJvZHkoZXZlbnQsIHdlYmhvb2tTZWNyZXQpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgY29uc29sZS5lcnJvcih7XG4gICAgICBub3RpY2U6ICdCYWQgc2lnbmF0dXJlJyxcbiAgICAgIGVycm9yOiBlLFxuICAgIH0pO1xuICAgIHJldHVybiB7XG4gICAgICBzdGF0dXNDb2RlOiA0MDMsXG4gICAgICBib2R5OiAnQmFkIHNpZ25hdHVyZScsXG4gICAgfTtcbiAgfVxuXG4gIGlmIChnZXRIZWFkZXIoZXZlbnQsICdjb250ZW50LXR5cGUnKSAhPT0gJ2FwcGxpY2F0aW9uL2pzb24nKSB7XG4gICAgY29uc29sZS5lcnJvcih7XG4gICAgICBub3RpY2U6ICdUaGlzIHdlYmhvb2sgb25seSBhY2NlcHRzIEpTT04gcGF5bG9hZHMnLFxuICAgICAgY29udGVudFR5cGU6IGdldEhlYWRlcihldmVudCwgJ2NvbnRlbnQtdHlwZScpLFxuICAgIH0pO1xuICAgIHJldHVybiB7XG4gICAgICBzdGF0dXNDb2RlOiA0MDAsXG4gICAgICBib2R5OiAnRXhwZWN0aW5nIEpTT04gcGF5bG9hZCcsXG4gICAgfTtcbiAgfVxuXG4gIGlmIChnZXRIZWFkZXIoZXZlbnQsICd4LWdpdGh1Yi1ldmVudCcpID09PSAncGluZycpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzQ29kZTogMjAwLFxuICAgICAgYm9keTogJ1BvbmcnLFxuICAgIH07XG4gIH1cblxuICAvLyBpZiAoZ2V0SGVhZGVyKGV2ZW50LCAneC1naXRodWItZXZlbnQnKSAhPT0gJ3dvcmtmbG93X2pvYicgJiYgZ2V0SGVhZGVyKGV2ZW50LCAneC1naXRodWItZXZlbnQnKSAhPT0gJ3dvcmtmbG93X3J1bicpIHtcbiAgLy8gICAgIGNvbnNvbGUuZXJyb3IoYFRoaXMgd2ViaG9vayBvbmx5IGFjY2VwdHMgd29ya2Zsb3dfam9iIGFuZCB3b3JrZmxvd19ydW4sIGdvdCAke2dldEhlYWRlcihldmVudCwgJ3gtZ2l0aHViLWV2ZW50Jyl9YCk7XG4gIGlmIChnZXRIZWFkZXIoZXZlbnQsICd4LWdpdGh1Yi1ldmVudCcpICE9PSAnd29ya2Zsb3dfam9iJykge1xuICAgIGNvbnNvbGUuZXJyb3Ioe1xuICAgICAgbm90aWNlOiAnVGhpcyB3ZWJob29rIG9ubHkgYWNjZXB0cyB3b3JrZmxvd19qb2InLFxuICAgICAgZ2l0aHViRXZlbnQ6IGdldEhlYWRlcihldmVudCwgJ3gtZ2l0aHViLWV2ZW50JyksXG4gICAgfSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXR1c0NvZGU6IDIwMCxcbiAgICAgIGJvZHk6ICdFeHBlY3Rpbmcgd29ya2Zsb3dfam9iJyxcbiAgICB9O1xuICB9XG5cbiAgY29uc3QgcGF5bG9hZCA9IEpTT04ucGFyc2UoYm9keSk7XG5cbiAgaWYgKHBheWxvYWQuYWN0aW9uICE9PSAncXVldWVkJykge1xuICAgIGNvbnNvbGUubG9nKHtcbiAgICAgIG5vdGljZTogYElnbm9yaW5nIGFjdGlvbiBcIiR7cGF5bG9hZC5hY3Rpb259XCIsIGV4cGVjdGluZyBcInF1ZXVlZFwiYCxcbiAgICAgIGpvYjogcGF5bG9hZC53b3JrZmxvd19qb2IsXG4gICAgfSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXR1c0NvZGU6IDIwMCxcbiAgICAgIGJvZHk6ICdPSy4gTm8gcnVubmVyIHN0YXJ0ZWQgKGFjdGlvbiBpcyBub3QgXCJxdWV1ZWRcIikuJyxcbiAgICB9O1xuICB9XG5cbiAgaWYgKHByb2Nlc3MuZW52LlJFUVVJUkVfU0VMRl9IT1NURURfTEFCRUwgPT09ICcxJyAmJiAhcGF5bG9hZC53b3JrZmxvd19qb2IubGFiZWxzLmluY2x1ZGVzKCdzZWxmLWhvc3RlZCcpKSB7XG4gICAgY29uc29sZS5sb2coe1xuICAgICAgbm90aWNlOiBgSWdub3JpbmcgbGFiZWxzIFwiJHtwYXlsb2FkLndvcmtmbG93X2pvYi5sYWJlbHN9XCIsIGV4cGVjdGluZyBcInNlbGYtaG9zdGVkXCJgLFxuICAgICAgam9iOiBwYXlsb2FkLndvcmtmbG93X2pvYixcbiAgICB9KTtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzQ29kZTogMjAwLFxuICAgICAgYm9keTogJ09LLiBObyBydW5uZXIgc3RhcnRlZCAobm8gXCJzZWxmLWhvc3RlZFwiIGxhYmVsKS4nLFxuICAgIH07XG4gIH1cblxuICAvLyBTZWxlY3QgcHJvdmlkZXIgYW5kIGxhYmVsc1xuICBjb25zdCBzZWxlY3Rpb24gPSBhd2FpdCBzZWxlY3RQcm92aWRlcihwYXlsb2FkLCBwYXlsb2FkLndvcmtmbG93X2pvYi5sYWJlbHMpO1xuICBpZiAoIXNlbGVjdGlvbi5wcm92aWRlciB8fCAhc2VsZWN0aW9uLmxhYmVscykge1xuICAgIGNvbnNvbGUubG9nKHtcbiAgICAgIG5vdGljZTogYElnbm9yaW5nIGxhYmVscyBcIiR7cGF5bG9hZC53b3JrZmxvd19qb2IubGFiZWxzfVwiLCBhcyB0aGV5IGRvbid0IG1hdGNoIGEgc3VwcG9ydGVkIHJ1bm5lciBwcm92aWRlcmAsXG4gICAgICBqb2I6IHBheWxvYWQud29ya2Zsb3dfam9iLFxuICAgIH0pO1xuICAgIHJldHVybiB7XG4gICAgICBzdGF0dXNDb2RlOiAyMDAsXG4gICAgICBib2R5OiAnT0suIE5vIHJ1bm5lciBzdGFydGVkIChubyBwcm92aWRlciB3aXRoIG1hdGNoaW5nIGxhYmVscykuJyxcbiAgICB9O1xuICB9XG5cbiAgLy8gZG9uJ3Qgc3RhcnQgcnVubmVycyBmb3IgYSBkZXBsb3ltZW50IHRoYXQncyBzdGlsbCBwZW5kaW5nIGFzIEdpdEh1YiB3aWxsIHNlbmQgYW5vdGhlciBldmVudCB3aGVuIGl0J3MgcmVhZHlcbiAgaWYgKGF3YWl0IGlzRGVwbG95bWVudFBlbmRpbmcocGF5bG9hZCkpIHtcbiAgICBjb25zb2xlLmxvZyh7XG4gICAgICBub3RpY2U6ICdJZ25vcmluZyBqb2IgYXMgaXRzIGRlcGxveW1lbnQgaXMgc3RpbGwgcGVuZGluZycsXG4gICAgICBqb2I6IHBheWxvYWQud29ya2Zsb3dfam9iLFxuICAgIH0pO1xuICAgIHJldHVybiB7XG4gICAgICBzdGF0dXNDb2RlOiAyMDAsXG4gICAgICBib2R5OiAnT0suIE5vIHJ1bm5lciBzdGFydGVkIChkZXBsb3ltZW50IHBlbmRpbmcpLicsXG4gICAgfTtcbiAgfVxuXG4gIC8vIHN0YXJ0IGV4ZWN1dGlvblxuICBjb25zdCBleGVjdXRpb25OYW1lID0gZ2VuZXJhdGVFeGVjdXRpb25OYW1lKGV2ZW50LCBwYXlsb2FkKTtcbiAgY29uc3QgaWRsZVRpbWVvdXRTZWNvbmRzID0gcHJvY2Vzcy5lbnYuSURMRV9USU1FT1VUX1NFQ09ORFMgPyBwYXJzZUludChwcm9jZXNzLmVudi5JRExFX1RJTUVPVVRfU0VDT05EUywgMTApIDogMzAwOyAvLyBkZWZhdWx0IDUgbWludXRlc1xuICBjb25zdCBpbnB1dCA9IHtcbiAgICBvd25lcjogcGF5bG9hZC5yZXBvc2l0b3J5Lm93bmVyLmxvZ2luLFxuICAgIHJlcG86IHBheWxvYWQucmVwb3NpdG9yeS5uYW1lLFxuICAgIGpvYklkOiBwYXlsb2FkLndvcmtmbG93X2pvYi5pZCxcbiAgICBqb2JVcmw6IHBheWxvYWQud29ya2Zsb3dfam9iLmh0bWxfdXJsLFxuICAgIGluc3RhbGxhdGlvbklkOiBwYXlsb2FkLmluc3RhbGxhdGlvbj8uaWQgPz8gLTEsIC8vIGFsd2F5cyBwYXNzIHZhbHVlIGJlY2F1c2Ugc3RlcCBmdW5jdGlvbiBjYW4ndCBoYW5kbGUgbWlzc2luZyBpbnB1dFxuICAgIGpvYkxhYmVsczogcGF5bG9hZC53b3JrZmxvd19qb2IubGFiZWxzLmpvaW4oJywnKSwgLy8gb3JpZ2luYWwgbGFiZWxzIHJlcXVlc3RlZCBieSB0aGUgam9iXG4gICAgcHJvdmlkZXI6IHNlbGVjdGlvbi5wcm92aWRlcixcbiAgICBsYWJlbHM6IHNlbGVjdGlvbi5sYWJlbHMuam9pbignLCcpLCAvLyBsYWJlbHMgdG8gdXNlIHdoZW4gcmVnaXN0ZXJpbmcgcnVubmVyXG4gICAgbWF4SWRsZVNlY29uZHM6IGlkbGVUaW1lb3V0U2Vjb25kcyxcbiAgfTtcbiAgY29uc3QgZXhlY3V0aW9uID0gYXdhaXQgc2Yuc2VuZChuZXcgU3RhcnRFeGVjdXRpb25Db21tYW5kKHtcbiAgICBzdGF0ZU1hY2hpbmVBcm46IHByb2Nlc3MuZW52LlNURVBfRlVOQ1RJT05fQVJOLFxuICAgIGlucHV0OiBKU09OLnN0cmluZ2lmeShpbnB1dCksXG4gICAgLy8gbmFtZSBpcyBub3QgcmFuZG9tIHNvIG11bHRpcGxlIGV4ZWN1dGlvbiBvZiB0aGlzIHdlYmhvb2sgd29uJ3QgY2F1c2UgbXVsdGlwbGUgYnVpbGRlcnMgdG8gc3RhcnRcbiAgICBuYW1lOiBleGVjdXRpb25OYW1lLFxuICB9KSk7XG5cbiAgY29uc29sZS5sb2coe1xuICAgIG5vdGljZTogJ1N0YXJ0ZWQgb3JjaGVzdHJhdG9yJyxcbiAgICBleGVjdXRpb246IGV4ZWN1dGlvbi5leGVjdXRpb25Bcm4sXG4gICAgc2ZuSW5wdXQ6IGlucHV0LFxuICAgIGpvYjogcGF5bG9hZC53b3JrZmxvd19qb2IsXG4gIH0pO1xuXG4gIHJldHVybiB7XG4gICAgc3RhdHVzQ29kZTogMjAyLFxuICAgIGJvZHk6IGV4ZWN1dGlvbk5hbWUsXG4gIH07XG59XG4iXX0=