@odigos/aws-cdk 0.0.18 → 0.0.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -3,10 +3,18 @@
3
3
  Instrument AWS Lambda functions and ECS Fargate services with OpenTelemetry, from your own CDK app.
4
4
 
5
5
  ```bash
6
- npm install @odigos/aws-cdk # TypeScript / JavaScript
7
- pip install odigos-aws-cdk # Python
6
+ npm install @odigos/aws-cdk@0.0.19
8
7
  ```
9
8
 
9
+ The npm package is published. The corrections in this checkout need a new package release before
10
+ customers receive them through npm. To use this checkout locally, run `npm ci`, `npm run build`, and
11
+ `npm run package` in `cdk/`, then install `dist/js/aws-cdk@0.0.0.jsii.tgz` in the consuming app.
12
+
13
+ The Python distribution is built by jsii but is not published on PyPI;
14
+ `pip install odigos-aws-cdk` currently fails. Python examples below apply to a locally built wheel:
15
+ run `npm ci`, `npm run build`, then `npm run package` from `cdk/`, and install the wheel under `dist/python/`.
16
+ For customer installation until PyPI publishing is enabled, use the CloudFormation instructions instead.
17
+
10
18
  | | Lambda | ECS Fargate |
11
19
  |---|---|---|
12
20
  | Construct | `OdigosLambdaInstrumentation` | `OdigosFargateInstrumentation` |
@@ -15,7 +23,8 @@ pip install odigos-aws-cdk # Python
15
23
  | Where telemetry goes | a collector in the same Lambda sandbox, which forwards | your destination, from the application process |
16
24
  | Language detection | from the function's declared runtime | none — you state the language |
17
25
 
18
- Both write `ODIGOS_IAC` and never the connector's ownership marker: instrumented by Odigos, owned by you.
26
+ Lambda writes `odigos:iac=v1` and exact SDK/collector layer ARNs as function tags. Fargate writes an
27
+ `ODIGOS_IAC` environment marker on each application container. Neither claims connector-managed ownership.
19
28
 
20
29
  # AWS Lambda
21
30
 
@@ -37,8 +46,13 @@ OdigosLambdaInstrumentation(self, "Odigos",
37
46
  )
38
47
  ```
39
48
 
40
- That attaches the layer for each function's language and architecture, sets the exec wrapper that loads
41
- the OpenTelemetry SDK, and hands the in-Lambda collector its whole configuration.
49
+ That attaches the matching layer(s), sets `AWS_LAMBDA_EXEC_WRAPPER`, and writes the readable version-2
50
+ `ODIGOS_LAMBDA_CONFIG` JSON. The layer launcher builds SDK settings and collector pipelines at startup;
51
+ customer SDK environment variables remain saved unchanged in AWS. Public and in-account layers must be
52
+ from `v0.0.19` or newer to read this configuration; a custom `layerVersion` must have the same bootstrap.
53
+
54
+ Apply instrumentation before creating published versions and aliases, then deploy the updated version and
55
+ point all traffic-serving aliases at it. Updating `$LATEST` alone does not instrument older versions.
42
56
 
43
57
  ## How the telemetry actually leaves the function
44
58
 
@@ -87,8 +101,8 @@ If you mirror the layer somewhere yourself, pass `layerVersion` and neither path
87
101
 
88
102
  ## Versioning
89
103
 
90
- **The package version is the layer version.** `@odigos/aws-cdk@0.2.0` resolves to the layer built and
91
- published by Odigos release `v0.2.0`, and pins the SAR application to semantic version `0.2.0` — which is
104
+ **The package version is the artifact release version.** `@odigos/aws-cdk@0.0.19` resolves to layers built and
105
+ published by Odigos release `v0.0.19`, and pins the SAR application to semantic version `0.0.19` — which is
92
106
  immutable, so it means the same bytes forever.
93
107
 
94
108
  Nothing resolves at deploy time in the default path, so upgrading the layer is `npm update` and a
@@ -102,8 +116,9 @@ changed nothing, is not a property you want.
102
116
 
103
117
  `OdigosInstrumentationMode.WEB_SERVER` is for a function running a web server behind the
104
118
  [AWS Lambda Web Adapter](https://github.com/awslabs/aws-lambda-web-adapter). The adapter owns the exec
105
- wrapper, so this mode does not touch it and loads instrumentation through the language's own loader
106
- variable instead.
119
+ wrapper. This mode sets `AWS_LAMBDA_EXEC_WRAPPER=/opt/odigos-webserver`, records the previous wrapper in
120
+ `ODIGOS_LAMBDA_CONFIG.webWrapper`, loads the agent through its language loader, then invokes the saved
121
+ wrapper. Define the adapter's wrapper before applying instrumentation so it is preserved.
107
122
 
108
123
  ```ts
109
124
  new OdigosLambdaInstrumentation(this, 'Odigos', {
@@ -120,9 +135,9 @@ layers, which at synth time are frequently unresolved tokens; a detector that wa
120
135
  would silently break the functions it got wrong. **Applying `HANDLER` to a web-adapter function
121
136
  overwrites the adapter's wrapper and the function stops serving.**
122
137
 
123
- `existingLoaderValue` has to be passed explicitly because CDK's `lambda.Function` exposes no way to read
124
- back an environment variable set elsewhere in your app. Omit it and the loader variable is set to the
125
- Odigos value alone — for `NODE_OPTIONS` that can mean losing a flag your app needs to boot.
138
+ The launcher preserves and joins the function's existing loader value at startup. `existingLoaderValue`
139
+ is an optional override: when supplied, CDK saves it unchanged as the customer's loader variable, and the
140
+ launcher adds instrumentation in its child process. Omit it to preserve the loader already in the function.
126
141
 
127
142
  Ruby has no verified web-server loader and is rejected at synth in this mode.
128
143
 
@@ -137,14 +152,35 @@ javaHandlerDistro: OdigosJavaHandlerDistro.OTEL_STREAM_HANDLER
137
152
 
138
153
  | Distro | For |
139
154
  |---|---|
140
- | `OTEL_HANDLER` (default) | `RequestHandler` |
155
+ | `OTEL_HANDLER` | `RequestHandler` |
141
156
  | `OTEL_PROXY_HANDLER` | API Gateway proxy events (enriched) |
142
157
  | `OTEL_SQS_HANDLER` | SQS events (enriched) |
143
158
  | `OTEL_STREAM_HANDLER` | `RequestStreamHandler` |
144
159
 
145
- `OTEL_HANDLER` installs a `RequestHandler` implementation. A `RequestStreamHandler` function has a
146
- different signature entirely, so wrapping it with the default **breaks the invocation** — it does not
147
- merely produce thinner spans.
160
+ Java defaults to the full `java-lambda-otel-agent`, which supports handler and stream interfaces. The
161
+ legacy `javaHandlerDistro` option explicitly selects a lightweight wrapper. `OTEL_HANDLER` implements
162
+ `RequestHandler`; use `OTEL_STREAM_HANDLER` for `RequestStreamHandler` when selecting a lightweight wrapper.
163
+ Prefer the equivalent `distro` IDs below. Do not set both options.
164
+
165
+ ## Distributions and ADOT
166
+
167
+ Set `distro` to the exact connector catalog ID. A fixed distro must match every function on that construct.
168
+
169
+ | Language | Default | Alternatives |
170
+ |---|---|---|
171
+ | Java | `java-lambda-otel-agent` | `java-lambda-otel-wrapper`, `java-lambda-otel-proxy-wrapper`, `java-lambda-otel-sqs-wrapper`, `java-lambda-otel-stream-wrapper`, `java-lambda-adot`, `java-lambda-adot-application-signals` |
172
+ | Node.js | `nodejs-lambda-otel` | `nodejs-lambda-adot`, `nodejs-lambda-adot-application-signals` |
173
+ | Python | `python-lambda-otel` | `python-lambda-adot`, `python-lambda-adot-application-signals` |
174
+ | Ruby | `ruby-lambda-otel` | none |
175
+
176
+ ADOT uses two architecture-matched layers: the language SDK and `adot-collector`. If mirroring the SDK
177
+ with `layerVersion`, also supply `collectorLayerVersion` or let `layerSource` resolve the collector.
178
+ ADOT supports Java 11/17/21, Node.js 18/20/22/24, and Python 3.10–3.13. ADOT and lightweight Java wrappers
179
+ cannot use `WEB_SERVER` mode. Plain ADOT disables Application Signals. The Application Signals presets
180
+ require traces **and** metrics, add `CloudWatchLambdaApplicationSignalsExecutionRolePolicy` to the Lambda
181
+ role, and require one-time CloudWatch Application Signals account/region setup. For an immutable imported
182
+ role, attach the policy separately. These presets also send enriched spans to Lambda's embedded AWS agent;
183
+ Node.js/Python's AWS-derived service metrics do not become ordinary OTLP metrics at a custom destination.
148
184
 
149
185
  ## Signals
150
186
 
@@ -164,9 +200,8 @@ duration. Traces are what nearly every destination accepts; the other two are a
164
200
  destination, so they are made deliberately.
165
201
 
166
202
  A disabled signal gets no collector pipeline **and** the SDK is told not to produce it
167
- (`OTEL_METRICS_EXPORTER=none`). Both halves matter: a signal with no pipeline is refused at the receiver on
168
- every batch, so suppressing it at the source is what stops the error loop. An enabled signal's variable
169
- stays unset, because `otlp` is already the SDK default.
203
+ (`OTEL_METRICS_EXPORTER=none`) inside the launcher's child process. Enabled signals explicitly select
204
+ `otlp` there. Both halves matter: a signal with no pipeline would otherwise be refused on every batch.
170
205
 
171
206
  `traces: false` with neither of the others on throws at synth — a collector with no pipeline fails to
172
207
  start, which would leave the function instrumented and silent.
@@ -191,27 +226,19 @@ because explicitly asking to instrument a Go function is a mistake worth failing
191
226
 
192
227
  ## Credentials in `headers`
193
228
 
194
- `destination.headers` is rendered into `OPENTELEMETRY_COLLECTOR_CONFIG_URI`, which is a plain Lambda
229
+ `destination.headers` is rendered into `ODIGOS_LAMBDA_CONFIG`, which is a plain Lambda
195
230
  environment variable — readable by anyone with `lambda:GetFunctionConfiguration` and visible in the
196
231
  console. For a long-lived credential, prefer a destination that authenticates by network position, or
197
232
  terminate at a collector you control.
198
233
 
199
234
  ## How Odigos recognises the function
200
235
 
201
- These constructs write `ODIGOS_IAC` on every function they instrument, recording the layer ARN they attached
202
- and the package version that attached it. That variable is what Odigos reads to attribute the function to
203
- itself; without it a function reports as `Absent` — "awaiting your deployment" — however completely the layer,
204
- wrapper and collector configuration are applied. There is nothing to switch on.
205
-
206
- The recorded layer ARN matters beyond attribution: it is what the connector checks the function against, so a
207
- version you pinned is respected instead of being reported as drift the day Odigos publishes a newer one. It
208
- works in `IN_ACCOUNT` mode too, where the ARN is a deploy-time reference your own code has no way to obtain.
236
+ Lambda attribution uses `odigos:iac=v1`, `odigos:sdk-layer`, and (for ADOT) `odigos:collector-layer`
237
+ function tags. The recorded ARNs identify the exact attached layer versions, including SAR output tokens.
238
+ There is no Lambda `ODIGOS_IAC` environment marker. Fargate uses its per-container environment marker.
209
239
 
210
- What these constructs never write is `ODIGOS_MANAGED`. That is the connector's own record of a mutation *it*
211
- performed, including the `prevEnv` snapshot it restores from on rollback, and it is written only when you hand
212
- a function to the connector by enabling it as an automatic-mode source. A CDK stack has no such snapshot to
213
- offer — nothing was mutated, your stack *is* the function's definition — so writing it would claim a rollback
214
- that was never recorded. Do not add it by hand.
240
+ The connector's `odigos:managed` Lambda tag and `ODIGOS_MANAGED` Fargate marker describe mutations and
241
+ rollback snapshots owned by the connector. Do not add them to an IaC-managed workload.
215
242
 
216
243
  ## Service names
217
244
 
@@ -233,8 +260,7 @@ source ends up owned by both: each `cdk deploy` reasserts the CDK's environment,
233
260
  the connector's, and every round trip publishes a new function version.
234
261
 
235
262
  Pick one per function. Discovery-only (manual) mode is the combination that works: Odigos watches and
236
- reports, your stack owns the configuration. That is what `ODIGOS_IAC` expresses — instrumented by Odigos,
237
- owned by you — and it is why these constructs never write the connector's ownership marker.
263
+ reports, your stack owns the configuration. The IaC markers express that ownership.
238
264
 
239
265
  # ECS Fargate
240
266
 
@@ -338,8 +364,10 @@ taskDefinition.addContainer('App', {
338
364
  // becomes: -Xmx512m -javaagent:/var/odigos/java/javaagent.jar
339
365
  ```
340
366
 
341
- Pass `existingLoaderValue` when the value is not visible at synth — set by an `environmentFiles` entry,
342
- baked into the image's own `ENV`, or supplied through `secrets`.
367
+ Pass `existingLoaderValue` when the value is not visible at synth — set by an `environmentFiles` entry
368
+ or baked into the image's own `ENV`. Do not supply a generated instrumentation variable through ECS
369
+ `secrets`: it conflicts with the ordinary environment setting and is rejected. Move loader options into
370
+ ordinary application configuration before applying instrumentation.
343
371
 
344
372
  `PHP_INI_SCAN_DIR` and `RUBYOPT` are the exception: Odigos compares them **exactly**, so they are set
345
373
  outright and a value already there is reported as a synth warning rather than merged. Fold what your
@@ -366,18 +394,18 @@ Endpoint and protocol are one decision, and are compared as one. Pairing an endp
366
394
  protocol fails at runtime as a connection reset that points nowhere near the cause, so an endpoint on the
367
395
  other protocol's standard port (4317 with `http/protobuf`, 4318 with `grpc`) is a synth warning.
368
396
 
369
- Unlike Lambda, `destination.headers` is rendered into `OTEL_EXPORTER_OTLP_HEADERS` on the container. The
370
- connector does not set or compare that variable when it instruments a Fargate task itself, so it is
371
- neither reconciled nor reported as drift — it is here because a task with no collector of its own has
372
- nowhere else to hold a credential. Same exposure caveat as Lambda: `ecs:DescribeTaskDefinition` and the
373
- console can read it.
397
+ On Fargate, `destination.headers` is rendered into `OTEL_EXPORTER_OTLP_HEADERS` as a sorted, URL-encoded
398
+ header list matching the connector. Pass raw header values, such as `Bearer token`, and let the construct
399
+ encode them. The connector compares the transport, endpoint and headers against the selected destination.
400
+ `ecs:DescribeTaskDefinition` and the console can read these values; task revisions can retain them.
374
401
 
375
402
  ## Signals
376
403
 
377
404
  Same defaults as Lambda — traces on, metrics and logs opt-in — and the same requirement that they match
378
405
  what Odigos has configured for the destination. All three `OTEL_*_EXPORTER` variables are written
379
- explicitly here, unlike Lambda where an enabled signal's variable is left unset, because the connector's
380
- Fargate check compares all three by value.
406
+ explicitly here. Lambda sets the same selectors inside the launcher rather than storing them in AWS.
407
+ Ruby Fargate supports traces only; Ruby Lambda also supports function stdout/stderr logs, but no metrics.
408
+ Unsupported Ruby signals and profiles generate synth warnings; they do not activate missing exporters.
381
409
 
382
410
  ## A task definition with more than one application
383
411
 
@@ -394,7 +422,11 @@ odigos.instrumentAll([
394
422
  ```
395
423
 
396
424
  AWS caps a task definition at 10 containers and the staging container needs one of them; a definition
397
- already at the limit fails at synth rather than on `RegisterTaskDefinition`.
425
+ already at the limit fails at synth rather than on `RegisterTaskDefinition`. Several constructs can share
426
+ the staging container only when they use the same agents image. Instrument each application container once.
427
+ Existing manual `odigos-agent` containers/volumes and conflicting mounts are rejected; remove those manual
428
+ resources before adopting the construct. Use Linux Fargate platform version `1.3.0` or newer (`LATEST` is
429
+ recommended) so the `SUCCESS` startup dependency is supported.
398
430
 
399
431
  ## The agents image
400
432
 
@@ -404,7 +436,7 @@ task's execution role at every task start**, so a task in a private subnet with
404
436
  endpoint cannot pull it. Mirror it into a registry your tasks can reach and pass `agentsImage`:
405
437
 
406
438
  ```ts
407
- agentsImage: '111122223333.dkr.ecr.eu-west-1.amazonaws.com/odigos-fargate-agents:v0.0.13',
439
+ agentsImage: '111122223333.dkr.ecr.eu-west-1.amazonaws.com/odigos-fargate-agents:v0.0.19',
408
440
  ```
409
441
 
410
442
  A mirror has to be the same bundle — the activation environment names exact paths inside it. The bundle is
@@ -426,6 +458,38 @@ automatic-mode source is owned by both: each `cdk deploy` reasserts your stack's
426
458
  reconcile reasserts the connector's, and every round trip registers a revision and rolls the service.
427
459
  Discovery-only (manual) mode is the combination that works.
428
460
 
461
+ # Bill of materials and removal
462
+
463
+ | Flow | Resources and configuration left by deployment |
464
+ |---|---|
465
+ | Lambda public/custom layer | Layer reference(s), wrapper and compact config environment variables, IaC layer tags, new published versions/aliases if your app creates them |
466
+ | Lambda `IN_ACCOUNT` | The above plus one SAR nested stack/layer per artifact family and architecture; ADOT adds the shared collector application |
467
+ | Application Signals | The above plus a managed-policy attachment on the Lambda role; account-wide discovery is configured separately |
468
+ | Fargate | A task-definition revision with one non-essential copier, one shared volume, mounts/dependencies, activation/export environment and per-container IaC marker; an ECS deployment when the service references that revision |
469
+
470
+ The constructs do not create a regional Collector, network routes, telemetry destination, or customer
471
+ credentials. Provision and remove those using their separate guides. Registry access and destination
472
+ reachability are deployment prerequisites.
473
+
474
+ To uninstall instrumentation while keeping the application:
475
+
476
+ 1. Disable automatic connector ownership for the workload, then remove the instrumentation construct,
477
+ `instrument()` calls or aspect from your app. Restore any explicit loader override you no longer want.
478
+ 2. Run `cdk diff`, review removal of the instrumentation resources/settings, then run `cdk deploy`.
479
+ For Lambda, publish the uninstrumented version and move every serving alias to it. For Fargate,
480
+ ensure the service references the new task revision and wait for the rollout to finish.
481
+ 3. Verify the application is healthy and sends no new Odigos telemetry. Old published Lambda versions
482
+ and ECS revisions remain instrumented until retired; review all traffic and rollback references first.
483
+ 4. SAR layers use retention policies and can remain after stack removal. After no function or published
484
+ version references one, remove that exact retained layer version with
485
+ `aws lambda delete-layer-version --layer-name "<LAYER_NAME>" --version-number "<LAYER_VERSION>"`.
486
+ Never delete a shared layer still in use. Retire unused task revisions through your existing ECS lifecycle.
487
+ 5. Remove dedicated, unused role policy attachments and telemetry credentials after confirming no other
488
+ consumer needs them. Configurations retained in versions, task revisions and IaC history may still hold
489
+ headers. Account-wide Application Signals discovery and its service-linked role are separate resources.
490
+
491
+ `cdk destroy` removes the entire application stack and is only appropriate when retiring that application.
492
+
429
493
  # API
430
494
 
431
495
  | Export | |
@@ -439,7 +503,7 @@ Discovery-only (manual) mode is the combination that works.
439
503
  | `OdigosLayerSource` | `ODIGOS_PUBLIC` \| `IN_ACCOUNT` |
440
504
  | `OdigosInstrumentationMode` | `HANDLER` \| `WEB_SERVER` |
441
505
  | `OdigosJavaHandlerDistro` | the four Java wrappers |
442
- | `renderCollectorConfig` | the Lambda collector config renderer, if you want to inspect what gets set |
506
+ | `renderCollectorConfig` | legacy inline collector config renderer for validation; the compact launcher generates the deployed config |
443
507
  | `sidecarCommand`, `evaluateAppendPattern` | the Fargate staging command and loader-value rendering |
444
508
  | `LAYER_ARNS`, `ODIGOS_VERSION` | the baked layer table and the release it came from |
445
509
  | `FARGATE_AGENTS_IMAGE`, `FARGATE_DISTROS_VERSION` | the agents image this build stages, and the distros release its recipes mirror |
@@ -92,6 +92,8 @@ export declare function signalActivation(language: string, dest: OdigosDestinati
92
92
  * @throws if the destination names neither transport, both transports, or no signals at all.
93
93
  */
94
94
  export declare function renderCollectorConfig(dest: OdigosDestination): string;
95
+ /** Validate both transports before generating Lambda configuration or mutating an ECS task. */
96
+ export declare function validateDestination(dest: OdigosDestination, allowBoth?: boolean): void;
95
97
  /** The Lambda Node layer registers only dns/http/net unless explicitly configured. */
96
98
  export declare function lambdaSignalActivation(language: string, dest: OdigosDestination): {
97
99
  [key: string]: string;
@@ -8,7 +8,9 @@ exports.exporterOverrideFor = exporterOverrideFor;
8
8
  exports.signalTransportOverrides = signalTransportOverrides;
9
9
  exports.signalActivation = signalActivation;
10
10
  exports.renderCollectorConfig = renderCollectorConfig;
11
+ exports.validateDestination = validateDestination;
11
12
  exports.lambdaSignalActivation = lambdaSignalActivation;
13
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
12
14
  /**
13
15
  * Renders the legacy in-Lambda collector configuration for validation and parity tests as an inline
14
16
  * `OPENTELEMETRY_COLLECTOR_CONFIG_URI` value.
@@ -207,22 +209,7 @@ function signalActivation(language, dest) {
207
209
  * @throws if the destination names neither transport, both transports, or no signals at all.
208
210
  */
209
211
  function renderCollectorConfig(dest) {
210
- if (dest.endpoint && dest.httpEndpoint) {
211
- throw new Error('Odigos destination sets both `endpoint` (OTLP/gRPC) and `httpEndpoint` (OTLP/HTTP); ' +
212
- 'they select different collector exporters, so exactly one must be set.');
213
- }
214
- // The two fields have different endpoint GRAMMARS, and getting them wrong is the worst failure mode this
215
- // package has: the collector accepts the configuration, fails to build its exporter, and exits — leaving
216
- // the function instrumented, reporting healthy, and exporting nothing. Both checks are therefore synth
217
- // errors rather than documentation.
218
- if (dest.endpoint && dest.endpoint.includes('://')) {
219
- throw new Error(`Odigos destination \`endpoint\` is "${dest.endpoint}", but the gRPC exporter takes host:port with ` +
220
- 'no scheme. Use `httpEndpoint` for a scheme-qualified OTLP/HTTP URL.');
221
- }
222
- if (dest.httpEndpoint && !/^https?:\/\//.test(dest.httpEndpoint)) {
223
- throw new Error(`Odigos destination \`httpEndpoint\` is "${dest.httpEndpoint}", but the OTLP/HTTP exporter takes a ` +
224
- 'scheme-qualified URL (http:// or https://). Use `endpoint` for a bare gRPC host:port.');
225
- }
212
+ validateDestination(dest);
226
213
  const exporter = renderExporter(dest);
227
214
  const pipelines = renderPipelines(dest, exporterNameFor(dest));
228
215
  if (pipelines === '') {
@@ -243,6 +230,42 @@ function renderCollectorConfig(dest) {
243
230
  pipelines +
244
231
  '}}');
245
232
  }
233
+ /** Validate both transports before generating Lambda configuration or mutating an ECS task. */
234
+ function validateDestination(dest, allowBoth = false) {
235
+ if (dest.endpoint && dest.httpEndpoint && !allowBoth) {
236
+ throw new Error('Odigos destination sets both `endpoint` (OTLP/gRPC) and `httpEndpoint` (OTLP/HTTP); exactly one must be set for Lambda.');
237
+ }
238
+ if (!dest.endpoint && !dest.httpEndpoint) {
239
+ throw new Error('Odigos destination has neither `endpoint` (OTLP/gRPC) nor `httpEndpoint` (OTLP/HTTP).');
240
+ }
241
+ if (dest.endpoint && !aws_cdk_lib_1.Token.isUnresolved(dest.endpoint)) {
242
+ if (dest.endpoint.includes('://')) {
243
+ throw new Error('Odigos destination `endpoint` takes host:port with no scheme. Use `httpEndpoint` for an HTTP URL.');
244
+ }
245
+ let url;
246
+ try {
247
+ url = new URL(`http://${dest.endpoint}`);
248
+ }
249
+ catch {
250
+ throw new Error('Odigos destination `endpoint` must be a valid gRPC host:port.');
251
+ }
252
+ if (!url.hostname || url.username || url.password || url.pathname !== '/' || url.search || url.hash || /\s/.test(dest.endpoint)) {
253
+ throw new Error('Odigos destination `endpoint` must be a bare gRPC host:port without credentials, paths or query parameters.');
254
+ }
255
+ }
256
+ if (dest.httpEndpoint && !aws_cdk_lib_1.Token.isUnresolved(dest.httpEndpoint)) {
257
+ let url;
258
+ try {
259
+ url = new URL(dest.httpEndpoint);
260
+ }
261
+ catch {
262
+ throw new Error('Odigos destination `httpEndpoint` requires a valid scheme-qualified URL (http:// or https://).');
263
+ }
264
+ if (!['http:', 'https:'].includes(url.protocol) || !url.hostname || url.username || url.password || url.hash || /\s/.test(dest.httpEndpoint)) {
265
+ throw new Error('Odigos destination `httpEndpoint` requires a scheme-qualified URL (http:// or https://) without embedded credentials or fragments.');
266
+ }
267
+ }
268
+ }
246
269
  /** The Lambda Node layer registers only dns/http/net unless explicitly configured. */
247
270
  function lambdaSignalActivation(language, dest) {
248
271
  const env = signalActivation(language, dest);
@@ -252,4 +275,4 @@ function lambdaSignalActivation(language, dest) {
252
275
  }
253
276
  return env;
254
277
  }
255
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGVjdG9yLWNvbmZpZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb2xsZWN0b3ItY29uZmlnLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQStFQSxzQ0FFQztBQWdCRCwwQ0FNQztBQW1CRCwwQ0FFQztBQWtFRCxrREFFQztBQUdELDREQUlDO0FBR0QsNENBWUM7QUFPRCxzREFpREM7QUFHRCx3REFPQztBQXRSRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E2Qkc7QUFFSDs7Ozs7O0dBTUc7QUFDVSxRQUFBLHdCQUF3QixHQUFHLG9DQUFvQyxDQUFDO0FBRTdFOzs7O0dBSUc7QUFDSCxNQUFNLHVCQUF1QixHQUFHLE9BQU8sQ0FBQztBQUV4Qzs7Ozs7Ozs7Ozs7R0FXRztBQUNILE1BQU0sb0JBQW9CLEdBQ3hCLDJGQUEyRjtJQUMzRixnRUFBZ0UsQ0FBQztBQUVuRSxpRUFBaUU7QUFDcEQsUUFBQSxhQUFhLEdBQUcsTUFBTSxDQUFDO0FBRXBDLHFGQUFxRjtBQUN4RSxRQUFBLG1CQUFtQixHQUFHLHNCQUFzQixDQUFDO0FBQzdDLFFBQUEsb0JBQW9CLEdBQUcsdUJBQXVCLENBQUM7QUFDL0MsUUFBQSxpQkFBaUIsR0FBRyxvQkFBb0IsQ0FBQztBQUV0RDs7Ozs7R0FLRztBQUNILFNBQWdCLGFBQWEsQ0FBQyxLQUEwQixFQUFFLGNBQXVCO0lBQy9FLE9BQU8sS0FBSyxJQUFJLGNBQWMsQ0FBQztBQUNqQyxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7R0FVRztBQUNVLFFBQUEsZUFBZSxHQUFHLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsQ0FBQztBQUU3RSxvR0FBb0c7QUFDcEcsU0FBZ0IsZUFBZSxDQUFDLElBQXVCO0lBQ3JELE9BQU87UUFDTCxNQUFNLEVBQUUsYUFBYSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsdUJBQWUsQ0FBQyxNQUFN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Q2pDLHFHQUFxRztRQUNyRyx1RUFBdUU7UUFDdkUsOEVBQThFO1FBQzlFLGNBQWM7UUFDZCxvQkFBb0I7UUFDcEIsZUFBZTtRQUNmLFFBQVE7UUFDUiw4REFBOEQ7UUFDOUQsU0FBUztRQUNULElBQUksQ0FDTCxDQUFDO0FBQ0osQ0FBQztBQUVELHNGQUFzRjtBQUN0RixTQUFnQixzQkFBc0IsQ0FBQyxRQUFnQixFQUFFLElBQXVCO0lBQzlFLE1BQU0sR0FBRyxHQUFHLGdCQUFnQixDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUM3QyxHQUFHLENBQUMsMkJBQTJCLEdBQUcsZUFBZSxDQUFDO0lBQ2xELElBQUksUUFBUSxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQzFCLEdBQUcsQ0FBQyxrQ0FBa0MsR0FBRywwTkFBME4sQ0FBQztJQUN0USxDQUFDO0lBQ0QsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgT2RpZ29zRGVzdGluYXRpb24gfSBmcm9tICcuL3R5cGVzJztcblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBsZWdhY3kgaW4tTGFtYmRhIGNvbGxlY3RvciBjb25maWd1cmF0aW9uIGZvciB2YWxpZGF0aW9uIGFuZCBwYXJpdHkgdGVzdHMgYXMgYW4gaW5saW5lXG4gKiBgT1BFTlRFTEVNRVRSWV9DT0xMRUNUT1JfQ09ORklHX1VSSWAgdmFsdWUuXG4gKlxuICogVGhpcyBpcyBhIFBPUlQgb2YgYHJlbmRlckNvbGxlY3RvckNvbmZpZ2AgaW4gdGhlIGNvbm5lY3RvclxuICogKGNvbm5lY3RvcnMvcHJvdmlkZXJzL2F3cy9wa2cvd29ya2xvYWQvaW5zdHJ1bWVudG9yL2NvbGxlY3Rvcl9jb25maWcuZ28pIGFuZCBpcyBkZWxpYmVyYXRlbHlcbiAqIGJ5dGUtZm9yLWJ5dGUgY29tcGF0aWJsZSB3aXRoIGl0LiBUaGF0IGVxdWl2YWxlbmNlIGlzIG5vdCBjb3NtZXRpYzogYSBmdW5jdGlvbiBpbnN0cnVtZW50ZWQgaGVyZSBhbmRcbiAqIGxhdGVyIGVuYWJsZWQgYXMgYSBjb25uZWN0b3Igc291cmNlIGlzIGNvbXBhcmVkIGFnYWluc3QgdGhlIGNvbm5lY3RvcidzIHJlbmRlcmluZyB0byBkZWNpZGUgd2hldGhlciBpdFxuICogbmVlZHMgY29udmVyZ2luZy4gQSBzdHJheSBzcGFjZSB3b3VsZCBtYWtlIGV2ZXJ5IHJlY29uY2lsZSBzZWUgZHJpZnQgYW5kIGNodXJuIGEgbmV3IGZ1bmN0aW9uIHZlcnNpb25cbiAqIGZvcmV2ZXIuXG4gKlxuICogV0hZIFRIRSBXSE9MRSBET0NVTUVOVCwgUkFUSEVSIFRIQU4gQSBGRVcgVkFSSUFCTEVTLiBUaGUgbGF5ZXIgc2hpcHMgYSBiYWtlZFxuICogL29wdC9jb2xsZWN0b3ItY29uZmlnL2NvbmZpZy55YW1sLCBidXQgdGhhdCBmaWxlIGlzIE9ORSBkb2N1bWVudCBzaGFyZWQgYnkgZXZlcnkgZnVuY3Rpb24sIHNvIGl0IGNhblxuICogb25seSByZWFjaCBhIGRlc3RpbmF0aW9uIHRocm91Z2ggZW52IGluZGlyZWN0aW9uIOKAlCBgJHtlbnY6U09NRVRISU5HfWAuIFRoYXQgbWFkZSB0aHJlZSB0aGluZ3NcbiAqIGltcG9zc2libGUgYXQgb25jZTpcbiAqXG4gKiAgIC0gQVVUSC4gQSBjcmVkZW50aWFsIGlzIGEgaGVhZGVycyBtYXAsIG5vdCBhIHNjYWxhci4gQSBiYWtlZCBmaWxlIGNhbiBzdWJzdGl0dXRlIGEgdmFsdWUgYnV0IGNhbm5vdFxuICogICAgIGNvbmRpdGlvbmFsbHkgZ3JvdyBhIGBoZWFkZXJzOmAgYmxvY2ssIHNvIGFuIGF1dGhlbnRpY2F0ZWQgZGVzdGluYXRpb24gd2FzIHVucmVhY2hhYmxlLlxuICogICAtIE9UTFAvSFRUUCBERVNUSU5BVElPTlMuIFRoZSBiYWtlZCBmaWxlIGhhcmRjb2RlcyBhIGdSUEMgYG90bHBgIGV4cG9ydGVyLiBBbiBvdGxwaHR0cC1vbmx5XG4gKiAgICAgZGVzdGluYXRpb24gcmVzb2x2ZXMgd2l0aCBhbiBlbXB0eSBnUlBDIGVuZHBvaW50LCBhbmQgdGhlIGNvbGxlY3RvciBkb2VzIG5vdCBkZWdyYWRlIOKAlCBpdCBmYWlscyB0b1xuICogICAgIGJ1aWxkIHRoZSBwaXBlbGluZSBhbmQgZXhpdHMsIHNvIHRoZSBmdW5jdGlvbiBpcyBpbnN0cnVtZW50ZWQsIGxvb2tzIGhlYWx0aHksIGFuZCBleHBvcnRzIG5vdGhpbmcuXG4gKiAgIC0gUEVSLVNJR05BTCBQSVBFTElORVMuIFRoZSBiYWtlZCBmaWxlIGRlY2xhcmVzIGFsbCB0aHJlZSBwaXBlbGluZXMgdW5jb25kaXRpb25hbGx5LCBzbyBhIHNpZ25hbCB0aGVcbiAqICAgICBkZXN0aW5hdGlvbiBkb2VzIG5vdCBhY2NlcHQgaXMgcmVjZWl2ZWQgYW5kIHRoZW4gZmFpbHMgb24gZXhwb3J0IHJhdGhlciB0aGFuIG5ldmVyIGJlaW5nIGJ1aWx0LlxuICpcbiAqIEZMT1cgU1RZTEUgSVMgTE9BRC1CRUFSSU5HLiBUaGUgZG9jdW1lbnQgaXMgZW1pdHRlZCBvbiBhIHNpbmdsZSBsaW5lIGJlY2F1c2UgaXQgaGFzIHRvIHN1cnZpdmUgYXMgYW5cbiAqIGVudmlyb25tZW50IHZhcmlhYmxlIHZhbHVlLiBJbiBhIFlBTUwgZmxvdyBtYXBwaW5nIGEgY29sb24gbXVzdCBiZSBmb2xsb3dlZCBieSBhIHNwYWNlLCBvciB0aGUgcGFyc2VyXG4gKiByZWFkcyBgYTpiYCBhcyB0aGUgcGxhaW4gc2NhbGFyIGBcImE6YlwiYCByYXRoZXIgdGhhbiBhIG1hcHBpbmcuIFdyaXR0ZW4gd2l0aG91dCB0aGUgc3BhY2VzIHRoZSBjb2xsZWN0b3JcbiAqIGFjY2VwdHMgdGhlIHZhcmlhYmxlLCByZXBvcnRzIHRoZSBVUkkgaXQgcmVhZCwgYW5kIHRoZW4gZmFpbHMgdG8gc3RhcnQgd2l0aCBhIGJhcmVcbiAqIGBvdGVsY29sIHN0YXRlIGlzIENsb3NlZGAg4oCUIG5vIHBhcnNlIGVycm9yLCBubyBtZW50aW9uIG9mIHRoZSBjb25maWcuIEV2ZXJ5IGA6IGAgYmVsb3cgZWFybnMgaXRzIHBsYWNlLlxuICovXG5cbi8qKlxuICogVGhlIGNvbGxlY3RvciBsYXllcidzIG93biBjb25maWctc291cmNlIHZhcmlhYmxlIOKAlCB1cHN0cmVhbSdzIG5hbWUsIG5vdCBvdXJzLiBQb2ludGVkIGF0IGEgYHlhbWw6YCBVUklcbiAqIGl0IGNhcnJpZXMgdGhlIGVudGlyZSBjb25maWd1cmF0aW9uIGlubGluZSwgc28gbm8gc2Vjb25kIHZhcmlhYmxlIGlzIG5lZWRlZCB0byBob2xkIGl0LlxuICpcbiAqIFVwc3RyZWFtIGFsc28gcmVhZHMgdGhlIG9sZGVyIGBPUEVOVEVMRU1FVFJZX0NPTExFQ1RPUl9DT05GSUdfRklMRWAgYW5kIGxvZ3MgYSBkZXByZWNhdGlvbiB3YXJuaW5nIGZvclxuICogaXQ7IHRoaXMgaXMgdGhlIGN1cnJlbnQgbmFtZS5cbiAqL1xuZXhwb3J0IGNvbnN0IEVOVl9DT0xMRUNUT1JfQ09ORklHX1VSSSA9ICdPUEVOVEVMRU1FVFJZX0NPTExFQ1RPUl9DT05GSUdfVVJJJztcblxuLyoqXG4gKiBUaGUgY29uZm1hcCBwcm92aWRlciB0aGF0IHJlYWRzIGEgY29uZmlndXJhdGlvbiBvdXQgb2YgdGhlIFVSSSBpdHNlbGYuIFRoZSBjb2xsZWN0b3IgcmVnaXN0ZXJzXG4gKiBlbnYvZmlsZS95YW1sL2h0dHAvaHR0cHMvczMgcHJvdmlkZXJzOyBgeWFtbDpgIGlzIHRoZSBvbmx5IG9uZSB0aGF0IG5lZWRzIG5vIHNlY29uZCB2YXJpYWJsZSBhbmQgbm9cbiAqIG5ldHdvcmsgcmVhZCBvbiBhIGNvbGQgc3RhcnQuXG4gKi9cbmNvbnN0IENPTExFQ1RPUl9DT05GSUdfU0NIRU1FID0gJ3lhbWw6JztcblxuLyoqXG4gKiBNaXJyb3JzIHRoZSBiYWtlZCBjb25maWcncyBwcm9jZXNzb3Igc2V0LCBhbmQgdGhlIE9SREVSIGlzIHRoZSBjb250cmFjdDpcbiAqXG4gKiAgIC0gYG1lbW9yeV9saW1pdGVyYCBmaXJzdCwgc28gYW4gZXhwb3J0IGJhY2tsb2cgaXMgc2hlZCBiZWZvcmUgaXQgaXMgY2hhcmdlZCB0byB0aGUgc2FtZSBtZW1vcnkgYnVkZ2V0XG4gKiAgICAgdGhlIGN1c3RvbWVyJ3MgaGFuZGxlciBhbGxvY2F0ZXMgZnJvbS4gUGVyY2VudGFnZXMsIG5vdCBgbGltaXRfbWliYCwgYmVjYXVzZSBvbmUgbGF5ZXIgc2VydmVzXG4gKiAgICAgZnVuY3Rpb25zIGZyb20gMTI4TUIgdG8gMTBHQi5cbiAqICAgLSBgZGVjb3VwbGVgIExBU1QuIExhbWJkYSBmcmVlemVzIHRoZSBzYW5kYm94IG9uY2UgdGhlIGhhbmRsZXIgcmV0dXJucyBhbmQgZXZlcnkgZXh0ZW5zaW9uIGhhcyBjYWxsZWRcbiAqICAgICAvbmV4dDsgYSBmcm96ZW4gc2FuZGJveCBydW5zIG5vIHRpbWVycywgc28gYSBiYXRjaCBzaXR0aW5nIGJlaGluZCBpdHMgdGltZW91dCBpcyBmbHVzaGVkIG9uIGEgbGF0ZXJcbiAqICAgICBpbnZvY2F0aW9uIG9yIGRyb3BwZWQgd2hlbiB0aGUgc2FuZGJveCBpcyByZWFwZWQuIGBkZWNvdXBsZWAgYWNrbm93bGVkZ2VzIHRoZSByZWNlaXZlIHBhdGhcbiAqICAgICBpbW1lZGlhdGVseSBhbmQgdHJhY2tzIGluLWZsaWdodCBleHBvcnRzLCB3aGljaCBpcyB3aGF0IGxldHMgdGhlIGV4dGVuc2lvbiBob2xkIC9uZXh0IG9wZW4gdW50aWwgdGhlXG4gKiAgICAgcXVldWUgZHJhaW5zIOKAlCBhZnRlciB0aGUgY2FsbGVyIGFscmVhZHkgaGFzIGl0cyByZXNwb25zZS5cbiAqL1xuY29uc3QgQ09MTEVDVE9SX1BST0NFU1NPUlMgPVxuICAne21lbW9yeV9saW1pdGVyOiB7Y2hlY2tfaW50ZXJ2YWw6IDFzLCBsaW1pdF9wZXJjZW50YWdlOiA1MCwgc3Bpa2VfbGltaXRfcGVyY2VudGFnZTogMjB9LCAnICtcbiAgJ2JhdGNoOiB7c2VuZF9iYXRjaF9zaXplOiA1MTIsIHRpbWVvdXQ6IDIwMG1zfSwgZGVjb3VwbGU6IG51bGx9JztcblxuLyoqIFZhbHVlIGFuIHVuc3VwcG9ydGVkIHNpZ25hbCdzIGBPVEVMXypfRVhQT1JURVJgIGlzIHNldCB0by4gKi9cbmV4cG9ydCBjb25zdCBFWFBPUlRFUl9OT05FID0gJ25vbmUnO1xuXG4vKiogVGhlIHRocmVlIGBPVEVMXypfRVhQT1JURVJgIHZhcmlhYmxlcywgaW4gdGhlIG9yZGVyIHRoZSBjb25uZWN0b3Igd3JpdGVzIHRoZW0uICovXG5leHBvcnQgY29uc3QgRU5WX1RSQUNFU19FWFBPUlRFUiA9ICdPVEVMX1RSQUNFU19FWFBPUlRFUic7XG5leHBvcnQgY29uc3QgRU5WX01FVFJJQ1NfRVhQT1JURVIgPSAnT1RFTF9NRVRSSUNTX0VYUE9SVEVSJztcbmV4cG9ydCBjb25zdCBFTlZfTE9HU19FWFBPUlRFUiA9ICdPVEVMX0xPR1NfRVhQT1JURVInO1xuXG4vKipcbiAqIFdoZXRoZXIgYSBzaWduYWwgaXMgZW5hYmxlZCwgZ2l2ZW4gdGhlIGNhbGxlcidzIHZhbHVlIGFuZCB0aGUgc2lnbmFsJ3Mgb3duIGRlZmF1bHQuXG4gKlxuICogVGhlIGRlZmF1bHRzIGFyZSBOT1QgdW5pZm9ybTogdHJhY2VzIGFyZSBvbiwgbWV0cmljcyBhbmQgbG9ncyBhcmUgb2ZmIChzZWUgYFNJR05BTF9ERUZBVUxUU2ApLiBTbyB0aGVcbiAqIGRlZmF1bHQgaGFzIHRvIHRyYXZlbCB3aXRoIHRoZSBzaWduYWwgcmF0aGVyIHRoYW4gYmVpbmcgZm9sZGVkIGludG8gb25lIFwidW5zZXQgbWVhbnMgb25cIiBydWxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2lnbmFsRW5hYmxlZCh2YWx1ZTogYm9vbGVhbiB8IHVuZGVmaW5lZCwgZGVmYXVsdEVuYWJsZWQ6IGJvb2xlYW4pOiBib29sZWFuIHtcbiAgcmV0dXJuIHZhbHVlID8/IGRlZmF1bHRFbmFibGVkO1xufVxuXG4vKipcbiAqIFdoaWNoIHNpZ25hbHMgYSBkZXN0aW5hdGlvbiBjYXJyaWVzIHdoZW4gdGhlIGNhbGxlciBzYXlzIG5vdGhpbmcuXG4gKlxuICogVFJBQ0VTIE9OTFkuIE1ldHJpY3MgYW5kIGxvZ3MgYXJlIG9wdC1pbiBiZWNhdXNlIHRoZSBjb3N0IG9mIGhhdmluZyB0aGVtIG9uIGJ5IGRlZmF1bHQgZmFsbHMgb24gcGVvcGxlXG4gKiB3aG8gbmV2ZXIgYXNrZWQgZm9yIHRoZW06IGEgZGVzdGluYXRpb24gdGhhdCBkb2VzIG5vdCBpbXBsZW1lbnQgYSBzaWduYWwgcmVmdXNlcyBldmVyeSBiYXRjaCBvZiBpdCwgYW5kXG4gKiB0aGUgaW4tTGFtYmRhIGNvbGxlY3RvciB0aGVuIHJldHJpZXMgb24gYW4gZXhwb25lbnRpYWwgYmFja29mZiBpbnNpZGUgYmlsbGVkIGR1cmF0aW9uLiBUcmFjZXMgYXJlIHdoYXRcbiAqIGFsbW9zdCBldmVyeSBkZXN0aW5hdGlvbiBhY2NlcHRzIGFuZCB3aGF0IGFsbW9zdCBldmVyeW9uZSBpbnN0cnVtZW50cyBmb3I7IHRoZSBvdGhlciB0d28gYXJlIGFcbiAqIGRlbGliZXJhdGUgY2hvaWNlIGFib3V0IHRoZSBkZXN0aW5hdGlvbiwgc28gdGhleSBhcmUgbWFkZSBkZWxpYmVyYXRlbHkuXG4gKlxuICogVHVybmluZyBvbmUgb24gaXMgYG1ldHJpY3M6IHRydWVgLiBFbmFibGluZyBhIHNpZ25hbCBzZXRzIGBPVEVMXypfRVhQT1JURVI9b3RscGAgZXhwbGljaXRseS5cbiAqL1xuZXhwb3J0IGNvbnN0IFNJR05BTF9ERUZBVUxUUyA9IHsgdHJhY2VzOiB0cnVlLCBtZXRyaWNzOiBmYWxzZSwgbG9nczogZmFsc2UgfTtcblxuLyoqIFRoZSB0aHJlZSBzaWduYWxzIHJlc29sdmVkIGFnYWluc3QgdGhlaXIgZGVmYXVsdHMg4oCUIHRoZSBzaW5nbGUgcGxhY2UgdGhhdCBwYWlyaW5nIGlzIGRlY2lkZWQuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZWRTaWduYWxzKGRlc3Q6IE9kaWdvc0Rlc3RpbmF0aW9uKTogeyB0cmFjZXM6IGJvb2xlYW47IG1ldHJpY3M6IGJvb2xlYW47IGxvZ3M6IGJvb2xlYW4gfSB7XG4gIHJldHVybiB7XG4gICAgdHJhY2VzOiBzaWduYWxFbmFibGVkKGRlc3QudHJhY2VzLCBTSUdOQUxfREVGQVVMVFMudHJhY2VzKSxcbiAgICBtZXRyaWNzOiBzaWduYWxFbmFibGVkKGRlc3QubWV0cmljcywgU0lHTkFMX0RFRkFVTFRTLm1ldHJpY3MpLFxuICAgIGxvZ3M6IHNpZ25hbEVuYWJsZWQoZGVzdC5sb2dzLCBTSUdOQUxfREVGQVVMVFMubG9ncyksXG4gIH07XG59XG5cbi8qKlxuICogUmVuZGVycyBhIGRvdWJsZS1xdW90ZWQgWUFNTCBzY2FsYXIuXG4gKlxuICogUXVvdGluZyB1bmNvbmRpdGlvbmFsbHkgaXMgd2hhdCBrZWVwcyBhIHZhbHVlIHN1Y2ggYXMgYSBiYXJlIGBob3N0OjQzMTdgIGZyb20gYmVpbmcgcmUtcmVhZCBhcyBhIG5lc3RlZFxuICogbWFwcGluZyBpbiBmbG93IGNvbnRleHQuIGBKU09OLnN0cmluZ2lmeWAgaXMgdGhlIFR5cGVTY3JpcHQgZXF1aXZhbGVudCBvZiB0aGUgY29ubmVjdG9yJ3NcbiAqIGBzdHJjb252LlF1b3RlYCBmb3IgdGhlIHZvY2FidWxhcnkgdGhhdCBtYXR0ZXJzIGhlcmUgKGBcXFwiYCBhbmQgYFxcXFxgKTsgYm90aCBwcm9kdWNlIHRoZSBzYW1lIG91dHB1dCBmb3JcbiAqIHRoZSBBU0NJSSBlbmRwb2ludHMsIGhlYWRlciBuYW1lcyBhbmQgY3JlZGVudGlhbHMgdGhpcyBldmVyIHNlZXMuXG4gKi9cbmZ1bmN0aW9uIHlhbWxTdHJpbmcoczogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHMpO1xufVxuXG4vKipcbiAqIFBpY2tzIHRoZSBleHBvcnRlciBieSB0aGUgdHJhbnNwb3J0IHRoZSBkZXN0aW5hdGlvbiBjb25maWd1cmVkLiBBIGRlc3RpbmF0aW9uIGNhcnJpZXMgYSBnUlBDIGVuZHBvaW50XG4gKiAodHlwZSBgb3RscGApIG9yIGFuIE9UTFAvSFRUUCBvbmUgKHR5cGUgYG90bHBodHRwYCk7IHRoZSB0d28gYXJlIGRpZmZlcmVudCBjb2xsZWN0b3IgY29tcG9uZW50cyB3aXRoXG4gKiBkaWZmZXJlbnQgZW5kcG9pbnQgZ3JhbW1hcnMsIHNvIHRoaXMgaXMgYSBnZW51aW5lIGJyYW5jaC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGV4cG9ydGVyTmFtZUZvcihkZXN0OiBPZGlnb3NEZXN0aW5hdGlvbik6IHN0cmluZyB7XG4gIHJldHVybiBkZXN0LmVuZHBvaW50ID8gJ290bHAnIDogJ290bHBodHRwJztcbn1cblxuLyoqXG4gKiBFbWl0cyB0aGUgZGVzdGluYXRpb24ncyBwZXItcmVxdWVzdCBoZWFkZXJzIOKAlCBpbiBwcmFjdGljZSBpdHMgY3JlZGVudGlhbC4gRW1wdHkgd2hlbiB0aGUgZGVzdGluYXRpb25cbiAqIG5lZWRzIG5vbmUsIHNvIG5vIGhlYWRlciBibG9jayBpcyB3cml0dGVuIGF0IGFsbCByYXRoZXIgdGhhbiBhbiBlbXB0eSBvbmUuXG4gKlxuICogS2V5cyBhcmUgc29ydGVkIHNvIHRoZSByZW5kZXJlZCBjb25maWcgaXMgYnl0ZS1pZGVudGljYWwgYWNyb3NzIHN5bnRocy4gVGhlIHN0cmluZyBpcyBjb21wYXJlZCBhZ2FpbnN0XG4gKiB0aGUgbGl2ZSBmdW5jdGlvbidzIGVudmlyb25tZW50IHRvIGRlY2lkZSB3aGV0aGVyIGFuIHVwZGF0ZSBpcyBuZWVkZWQsIGFuZCBtYXAgb3JkZXIgd291bGQgb3RoZXJ3aXNlXG4gKiBtYWtlIGV2ZXJ5IGRlcGxveSBsb29rIGxpa2UgYSBjaGFuZ2UuXG4gKi9cbmZ1bmN0aW9uIHJlbmRlckhlYWRlcnMoaGVhZGVycz86IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0pOiBzdHJpbmcge1xuICBpZiAoIWhlYWRlcnMpIHtcbiAgICByZXR1cm4gJyc7XG4gIH1cbiAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKGhlYWRlcnMpLnNvcnQoKTtcbiAgaWYgKGtleXMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG4gIGNvbnN0IHJlbmRlcmVkID0ga2V5cy5tYXAoKGspID0+IGAke3lhbWxTdHJpbmcoayl9OiAke3lhbWxTdHJpbmcoaGVhZGVyc1trXSl9YCkuam9pbignLCAnKTtcbiAgcmV0dXJuIGAsIGhlYWRlcnM6IHske3JlbmRlcmVkfX1gO1xufVxuXG5mdW5jdGlvbiByZW5kZXJFeHBvcnRlcihkZXN0OiBPZGlnb3NEZXN0aW5hdGlvbik6IHN0cmluZyB7XG4gIGxldCBvdXQ6IHN0cmluZztcbiAgaWYgKGRlc3QuZW5kcG9pbnQpIHtcbiAgICAvLyB0bHMuaW5zZWN1cmUgYXBwbGllcyB0byB0aGUgZ1JQQyBleHBvcnRlciBvbmx5OyB0aGUgSFRUUCBleHBvcnRlciB0YWtlcyB0aGUgc2NoZW1lIGZyb20gdGhlIFVSTC5cbiAgICBvdXQgPSBge290bHA6IHtlbmRwb2ludDogJHt5YW1sU3RyaW5nKGRlc3QuZW5kcG9pbnQpfSwgdGxzOiB7aW5zZWN1cmU6ICR7ZGVzdC5pbnNlY3VyZSA9PT0gdHJ1ZX19YDtcbiAgfSBlbHNlIGlmIChkZXN0Lmh0dHBFbmRwb2ludCkge1xuICAgIG91dCA9IGB7b3RscGh0dHA6IHtlbmRwb2ludDogJHt5YW1sU3RyaW5nKGRlc3QuaHR0cEVuZHBvaW50KX1gO1xuICB9IGVsc2Uge1xuICAgIC8vIFJlYWNoZWQgd2hlbiBhIGRlc3RpbmF0aW9uIGNhcnJpZXMgbmVpdGhlciB0cmFuc3BvcnQuIEZhaWxpbmcgaGVyZSBpcyB0aGUgd2hvbGUgcG9pbnQ6IHRoZVxuICAgIC8vIGFsdGVybmF0aXZlIGlzIGEgY29sbGVjdG9yIHRoYXQgZXhpdHMgb24gc3RhcnR1cCB3aGlsZSB0aGUgZnVuY3Rpb24gaXMgcmVwb3J0ZWQgaGVhbHRoeS5cbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnT2RpZ29zIGRlc3RpbmF0aW9uIGhhcyBuZWl0aGVyIGBlbmRwb2ludGAgKE9UTFAvZ1JQQykgbm9yIGBodHRwRW5kcG9pbnRgIChPVExQL0hUVFApLCAnICtcbiAgICAgICAgJ3NvIHRoZSBpbi1MYW1iZGEgY29sbGVjdG9yIHdvdWxkIGhhdmUgbm93aGVyZSB0byBleHBvcnQuJyxcbiAgICApO1xuICB9XG4gIHJldHVybiBgJHtvdXR9JHtyZW5kZXJIZWFkZXJzKGRlc3QuaGVhZGVycyl9fX1gO1xufVxuXG4vKipcbiAqIEJ1aWxkcyBhIHBpcGVsaW5lIG9ubHkgZm9yIHRoZSBzaWduYWxzIHRoZSBkZXN0aW5hdGlvbiBhY2NlcHRzLiBBIHNpZ25hbCB3aXRoIG5vIHBpcGVsaW5lIGlzIHJlZnVzZWQgYXRcbiAqIHRoZSByZWNlaXZlciwgd2hpY2ggaXMgdGhlIGJlaGF2aW91ciB3ZSB3YW50OiB0aGUgU0RLIGlzIHRvbGQgbm90IHRvIHByb2R1Y2UgaXQgZWl0aGVyIChzZWVcbiAqIGBleHBvcnRlck92ZXJyaWRlRm9yYCksIGFuZCB0aGUgdHdvIHRvZ2V0aGVyIG1lYW4gYW4gdW5hY2NlcHRlZCBzaWduYWwgaXMgbmV2ZXIgZ2VuZXJhdGVkLCBuZXZlclxuICogZXhwb3J0ZWQsIGFuZCBuZXZlciBhIHBlci1iYXRjaCBlcnJvciBhZ2FpbnN0IGEgYmFja2VuZCB0aGF0IGRvZXMgbm90IGltcGxlbWVudCBpdC5cbiAqL1xuZnVuY3Rpb24gcmVuZGVyUGlwZWxpbmVzKGRlc3Q6IE9kaWdvc0Rlc3RpbmF0aW9uLCBleHBvcnRlck5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHBhcnRzOiBzdHJpbmdbXSA9IFtdO1xuICBjb25zdCBlbmFibGVkID0gcmVzb2x2ZWRTaWduYWxzKGRlc3QpO1xuICBjb25zdCBzaWduYWxzOiBBcnJheTxbc3RyaW5nLCBib29sZWFuXT4gPSBbXG4gICAgWyd0cmFjZXMnLCBlbmFibGVkLnRyYWNlc10sXG4gICAgWydtZXRyaWNzJywgZW5hYmxlZC5tZXRyaWNzXSxcbiAgICBbJ2xvZ3MnLCBlbmFibGVkLmxvZ3NdLFxuICBdO1xuICBmb3IgKGNvbnN0IFtuYW1lLCBlbmFibGVkXSBvZiBzaWduYWxzKSB7XG4gICAgaWYgKCFlbmFibGVkKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgcGFydHMucHVzaChcbiAgICAgIGAke25hbWV9OiB7cmVjZWl2ZXJzOiBbb3RscF0sIHByb2Nlc3NvcnM6IFttZW1vcnlfbGltaXRlciwgYmF0Y2gsIGRlY291cGxlXSwgZXhwb3J0ZXJzOiBbJHtleHBvcnRlck5hbWV9XX1gLFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIHBhcnRzLmxlbmd0aCA9PT0gMCA/ICcnIDogYHske3BhcnRzLmpvaW4oJywgJyl9fWA7XG59XG5cbi8qKiBFeHBsaWNpdCBleHBvcnRlciBzZWxlY3RvcnMgbWlycm9yIHRoZSBiYXNlIGNvbm5lY3RvciBwb2xpY3k7IFNESyBkZWZhdWx0cyB2YXJ5LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGV4cG9ydGVyT3ZlcnJpZGVGb3IoZW5hYmxlZDogYm9vbGVhbik6IHN0cmluZyB7XG4gIHJldHVybiBlbmFibGVkID8gJ290bHAnIDogRVhQT1JURVJfTk9ORTtcbn1cblxuLyoqIFBlci1zaWduYWwgdHJhbnNwb3J0IG92ZXJyaWRlcyBieXBhc3MgdGhlIGRlc3RpbmF0aW9uIGFuZCBtdXN0IG5vdCBjb2V4aXN0IHdpdGggaXQuICovXG5leHBvcnQgZnVuY3Rpb24gc2lnbmFsVHJhbnNwb3J0T3ZlcnJpZGVzKCk6IHN0cmluZ1tdIHtcbiAgcmV0dXJuIFsnVFJBQ0VTJywgJ01FVFJJQ1MnLCAnTE9HUyddLmZsYXRNYXAoKHNpZ25hbCkgPT5cbiAgICBbJ0VORFBPSU5UJywgJ1BST1RPQ09MJywgJ0hFQURFUlMnLCAnSU5TRUNVUkUnXS5tYXAoKHNldHRpbmcpID0+IGBPVEVMX0VYUE9SVEVSX09UTFBfJHtzaWduYWx9XyR7c2V0dGluZ31gKSxcbiAgKTtcbn1cblxuLyoqIExhbmd1YWdlLXNwZWNpZmljIFNESyBhY3RpdmF0aW9uLCBzaGFyZWQgYnkgTGFtYmRhIGFuZCBGYXJnYXRlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNpZ25hbEFjdGl2YXRpb24obGFuZ3VhZ2U6IHN0cmluZywgZGVzdDogT2RpZ29zRGVzdGluYXRpb24pOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9IHtcbiAgY29uc3QgZW5hYmxlZCA9IHJlc29sdmVkU2lnbmFscyhkZXN0KTtcbiAgY29uc3QgZW52OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9ID0ge1xuICAgIE9URUxfU0RLX0RJU0FCTEVEOiAnZmFsc2UnLFxuICAgIFtFTlZfVFJBQ0VTX0VYUE9SVEVSXTogZXhwb3J0ZXJPdmVycmlkZUZvcihlbmFibGVkLnRyYWNlcyksXG4gICAgW0VOVl9NRVRSSUNTX0VYUE9SVEVSXTogZXhwb3J0ZXJPdmVycmlkZUZvcihlbmFibGVkLm1ldHJpY3MpLFxuICAgIFtFTlZfTE9HU19FWFBPUlRFUl06IGV4cG9ydGVyT3ZlcnJpZGVGb3IoZW5hYmxlZC5sb2dzKSxcbiAgfTtcbiAgaWYgKGxhbmd1YWdlID09PSAncHl0aG9uJykge1xuICAgIGVudi5PVEVMX1BZVEhPTl9MT0dHSU5HX0FVVE9fSU5TVFJVTUVOVEFUSU9OX0VOQUJMRUQgPSBTdHJpbmcoZW5hYmxlZC5sb2dzKTtcbiAgfVxuICByZXR1cm4gZW52O1xufVxuXG4vKipcbiAqIFJlbmRlcnMgdGhlIGNvbXBsZXRlIGNvbGxlY3RvciBjb25maWd1cmF0aW9uIGZvciBvbmUgZGVzdGluYXRpb24uXG4gKlxuICogQHRocm93cyBpZiB0aGUgZGVzdGluYXRpb24gbmFtZXMgbmVpdGhlciB0cmFuc3BvcnQsIGJvdGggdHJhbnNwb3J0cywgb3Igbm8gc2lnbmFscyBhdCBhbGwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW5kZXJDb2xsZWN0b3JDb25maWcoZGVzdDogT2RpZ29zRGVzdGluYXRpb24pOiBzdHJpbmcge1xuICBpZiAoZGVzdC5lbmRwb2ludCAmJiBkZXN0Lmh0dHBFbmRwb2ludCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICdPZGlnb3MgZGVzdGluYXRpb24gc2V0cyBib3RoIGBlbmRwb2ludGAgKE9UTFAvZ1JQQykgYW5kIGBodHRwRW5kcG9pbnRgIChPVExQL0hUVFApOyAnICtcbiAgICAgICAgJ3RoZXkgc2VsZWN0IGRpZmZlcmVudCBjb2xsZWN0b3IgZXhwb3J0ZXJzLCBzbyBleGFjdGx5IG9uZSBtdXN0IGJlIHNldC4nLFxuICAgICk7XG4gIH1cblxuICAvLyBUaGUgdHdvIGZpZWxkcyBoYXZlIGRpZmZlcmVudCBlbmRwb2ludCBHUkFNTUFSUywgYW5kIGdldHRpbmcgdGhlbSB3cm9uZyBpcyB0aGUgd29yc3QgZmFpbHVyZSBtb2RlIHRoaXNcbiAgLy8gcGFja2FnZSBoYXM6IHRoZSBjb2xsZWN0b3IgYWNjZXB0cyB0aGUgY29uZmlndXJhdGlvbiwgZmFpbHMgdG8gYnVpbGQgaXRzIGV4cG9ydGVyLCBhbmQgZXhpdHMg4oCUIGxlYXZpbmdcbiAgLy8gdGhlIGZ1bmN0aW9uIGluc3RydW1lbnRlZCwgcmVwb3J0aW5nIGhlYWx0aHksIGFuZCBleHBvcnRpbmcgbm90aGluZy4gQm90aCBjaGVja3MgYXJlIHRoZXJlZm9yZSBzeW50aFxuICAvLyBlcnJvcnMgcmF0aGVyIHRoYW4gZG9jdW1lbnRhdGlvbi5cbiAgaWYgKGRlc3QuZW5kcG9pbnQgJiYgZGVzdC5lbmRwb2ludC5pbmNsdWRlcygnOi8vJykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgT2RpZ29zIGRlc3RpbmF0aW9uIFxcYGVuZHBvaW50XFxgIGlzIFwiJHtkZXN0LmVuZHBvaW50fVwiLCBidXQgdGhlIGdSUEMgZXhwb3J0ZXIgdGFrZXMgaG9zdDpwb3J0IHdpdGggYCArXG4gICAgICAgICdubyBzY2hlbWUuIFVzZSBgaHR0cEVuZHBvaW50YCBmb3IgYSBzY2hlbWUtcXVhbGlmaWVkIE9UTFAvSFRUUCBVUkwuJyxcbiAgICApO1xuICB9XG4gIGlmIChkZXN0Lmh0dHBFbmRwb2ludCAmJiAhL15odHRwcz86XFwvXFwvLy50ZXN0KGRlc3QuaHR0cEVuZHBvaW50KSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBPZGlnb3MgZGVzdGluYXRpb24gXFxgaHR0cEVuZHBvaW50XFxgIGlzIFwiJHtkZXN0Lmh0dHBFbmRwb2ludH1cIiwgYnV0IHRoZSBPVExQL0hUVFAgZXhwb3J0ZXIgdGFrZXMgYSBgICtcbiAgICAgICAgJ3NjaGVtZS1xdWFsaWZpZWQgVVJMIChodHRwOi8vIG9yIGh0dHBzOi8vKS4gVXNlIGBlbmRwb2ludGAgZm9yIGEgYmFyZSBnUlBDIGhvc3Q6cG9ydC4nLFxuICAgICk7XG4gIH1cblxuICBjb25zdCBleHBvcnRlciA9IHJlbmRlckV4cG9ydGVyKGRlc3QpO1xuICBjb25zdCBwaXBlbGluZXMgPSByZW5kZXJQaXBlbGluZXMoZGVzdCwgZXhwb3J0ZXJOYW1lRm9yKGRlc3QpKTtcbiAgaWYgKHBpcGVsaW5lcyA9PT0gJycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnT2RpZ29zIGRlc3RpbmF0aW9uIGFjY2VwdHMgbm8gdGVsZW1ldHJ5IHNpZ25hbHMsIHNvIHRoZSBjb2xsZWN0b3Igd291bGQgaGF2ZSBubyBwaXBlbGluZSB0byBidWlsZCAnICtcbiAgICAgICAgJ2FuZCB3b3VsZCBmYWlsIHRvIHN0YXJ0LiBOb3RlIHRoYXQgbWV0cmljcyBhbmQgbG9ncyBhcmUgT0ZGIGJ5IGRlZmF1bHQg4oCUIHdpdGggYHRyYWNlczogZmFsc2VgIHRoZSAnICtcbiAgICAgICAgJ2Rlc3RpbmF0aW9uIGhhcyBub3RoaW5nIGxlZnQgdW5sZXNzIHlvdSBhbHNvIHBhc3MgYG1ldHJpY3M6IHRydWVgIG9yIGBsb2dzOiB0cnVlYC4nLFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gKFxuICAgIENPTExFQ1RPUl9DT05GSUdfU0NIRU1FICtcbiAgICAne3JlY2VpdmVyczoge290bHA6IHtwcm90b2NvbHM6ICcgK1xuICAgIC8vIEJvdW5kIHRvIGxvY2FsaG9zdDogdGhlIHJlY2VpdmVyIGV4aXN0cyBvbmx5IGZvciB0aGUgaW4tcHJvY2VzcyBTREsuIEJpbmRpbmcgaXQgd2lkZXIgd291bGQgZXhwb3NlXG4gICAgLy8gYW4gdW5hdXRoZW50aWNhdGVkIE9UTFAgZW5kcG9pbnQgb24gdGhlIHNhbmRib3gncyBuZXR3b3JrIGludGVyZmFjZS5cbiAgICAne2dycGM6IHtlbmRwb2ludDogXCJsb2NhbGhvc3Q6NDMxN1wifSwgaHR0cDoge2VuZHBvaW50OiBcImxvY2FsaG9zdDo0MzE4XCJ9fX19LCAnICtcbiAgICAncHJvY2Vzc29yczogJyArXG4gICAgQ09MTEVDVE9SX1BST0NFU1NPUlMgK1xuICAgICcsIGV4cG9ydGVyczogJyArXG4gICAgZXhwb3J0ZXIgK1xuICAgICcsIHNlcnZpY2U6IHt0ZWxlbWV0cnk6IHttZXRyaWNzOiB7bGV2ZWw6IG5vbmV9fSwgcGlwZWxpbmVzOiAnICtcbiAgICBwaXBlbGluZXMgK1xuICAgICd9fSdcbiAgKTtcbn1cblxuLyoqIFRoZSBMYW1iZGEgTm9kZSBsYXllciByZWdpc3RlcnMgb25seSBkbnMvaHR0cC9uZXQgdW5sZXNzIGV4cGxpY2l0bHkgY29uZmlndXJlZC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsYW1iZGFTaWduYWxBY3RpdmF0aW9uKGxhbmd1YWdlOiBzdHJpbmcsIGRlc3Q6IE9kaWdvc0Rlc3RpbmF0aW9uKTogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSB7XG4gIGNvbnN0IGVudiA9IHNpZ25hbEFjdGl2YXRpb24obGFuZ3VhZ2UsIGRlc3QpO1xuICBlbnYuT1RFTF9FWFBPUlRFUl9PVExQX1BST1RPQ09MID0gJ2h0dHAvcHJvdG9idWYnO1xuICBpZiAobGFuZ3VhZ2UgPT09ICdub2RlanMnKSB7XG4gICAgZW52Lk9URUxfTk9ERV9FTkFCTEVEX0lOU1RSVU1FTlRBVElPTlMgPSAnYW1xcGxpYixidW55YW4sY2Fzc2FuZHJhLWRyaXZlcixjb25uZWN0LGRhdGFsb2FkZXIsZG5zLGV4cHJlc3MsZnMsZ3JhcGhxbCxncnBjLGhhcGksaHR0cCxpb3JlZGlzLGthZmthanMsa25leCxrb2EsbWVtY2FjaGVkLG1vbmdvZGIsbW9uZ29vc2UsbXlzcWwsbXlzcWwyLG5lc3Rqcy1jb3JlLG5ldCxwZyxwaW5vLHJlZGlzLHJlc3RpZnksc29ja2V0LmlvLHVuZGljaSx3aW5zdG9uJztcbiAgfVxuICByZXR1cm4gZW52O1xufVxuIl19
278
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGVjdG9yLWNvbmZpZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb2xsZWN0b3ItY29uZmlnLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQWdGQSxzQ0FFQztBQWdCRCwwQ0FNQztBQW1CRCwwQ0FFQztBQWtFRCxrREFFQztBQUdELDREQUlDO0FBR0QsNENBWUM7QUFPRCxzREEyQkM7QUFHRCxrREE0QkM7QUFHRCx3REFPQztBQWxTRCw2Q0FBb0M7QUFHcEM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBNkJHO0FBRUg7Ozs7OztHQU1HO0FBQ1UsUUFBQSx3QkFBd0IsR0FBRyxvQ0FBb0MsQ0FBQztBQUU3RTs7OztHQUlHO0FBQ0gsTUFBTSx1QkFBdUIsR0FBRyxPQUFPLENBQUM7QUFFeEM7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxNQUFNLG9CQUFvQixHQUN4QiwyRkFBMkY7SUFDM0YsZ0VBQWdFLENBQUM7QUFFbkUsaUVBQWlFO0FBQ3BELFFBQUEsYUFBYSxHQUFHLE1BQU0sQ0FBQztBQUVwQyxxRkFBcUY7QUFDeEUsUUFBQSxtQkFBbUIsR0FBRyxzQkFBc0IsQ0FBQztBQUM3QyxRQUFBLG9CQUFvQixHQUFHLHVCQUF1QixDQUFDO0FBQy9DLFFBQUEsaUJBQWlCLEdBQUcsb0JBQW9CLENBQUM7QUFFdEQ7Ozs7O0dBS0c7QUFDSCxTQUFnQixhQUFhLENBQUMsS0FBMEIsRUFBRSxjQUF1QjtJQUMvRSxPQUFPLEtBQUssSUFBSSxjQUFjLENBQUM7QUFDakMsQ0FBQztBQUVEOzs7Ozs7Ozs7O0dBVUc7QUFDVSxRQUFBLGVBQWUsR0FBRyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLENBQUM7QUFFN0Usb0dBQW9HO0FBQ3BHLFNBQWdCLGVBQWUsQ0FBQyxJQUF1QjtJQUNyRCxPQUFPO1FBQ0wsTUFBTSxFQUFFLGFBQWEsQ0FBQyxJQUFJLENBQUMs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LEVBQUUsUUFBUSxDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLElBQUksR0FBRyxDQUFDLFFBQVEsSUFBSSxHQUFHLENBQUMsUUFBUSxJQUFJLEdBQUcsQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztZQUM3SSxNQUFNLElBQUksS0FBSyxDQUFDLG9JQUFvSSxDQUFDLENBQUM7UUFDeEosQ0FBQztJQUNILENBQUM7QUFDSCxDQUFDO0FBRUQsc0ZBQXNGO0FBQ3RGLFNBQWdCLHNCQUFzQixDQUFDLFFBQWdCLEVBQUUsSUFBdUI7SUFDOUUsTUFBTSxHQUFHLEdBQUcsZ0JBQWdCLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQzdDLEdBQUcsQ0FBQywyQkFBMkIsR0FBRyxlQUFlLENBQUM7SUFDbEQsSUFBSSxRQUFRLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDMUIsR0FBRyxDQUFDLGtDQUFrQyxHQUFHLDBOQUEwTixDQUFDO0lBQ3RRLENBQUM7SUFDRCxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBUb2tlbiB9IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCB7IE9kaWdvc0Rlc3RpbmF0aW9uIH0gZnJvbSAnLi90eXBlcyc7XG5cbi8qKlxuICogUmVuZGVycyB0aGUgbGVnYWN5IGluLUxhbWJkYSBjb2xsZWN0b3IgY29uZmlndXJhdGlvbiBmb3IgdmFsaWRhdGlvbiBhbmQgcGFyaXR5IHRlc3RzIGFzIGFuIGlubGluZVxuICogYE9QRU5URUxFTUVUUllfQ09MTEVDVE9SX0NPTkZJR19VUklgIHZhbHVlLlxuICpcbiAqIFRoaXMgaXMgYSBQT1JUIG9mIGByZW5kZXJDb2xsZWN0b3JDb25maWdgIGluIHRoZSBjb25uZWN0b3JcbiAqIChjb25uZWN0b3JzL3Byb3ZpZGVycy9hd3MvcGtnL3dvcmtsb2FkL2luc3RydW1lbnRvci9jb2xsZWN0b3JfY29uZmlnLmdvKSBhbmQgaXMgZGVsaWJlcmF0ZWx5XG4gKiBieXRlLWZvci1ieXRlIGNvbXBhdGlibGUgd2l0aCBpdC4gVGhhdCBlcXVpdmFsZW5jZSBpcyBub3QgY29zbWV0aWM6IGEgZnVuY3Rpb24gaW5zdHJ1bWVudGVkIGhlcmUgYW5kXG4gKiBsYXRlciBlbmFibGVkIGFzIGEgY29ubmVjdG9yIHNvdXJjZSBpcyBjb21wYXJlZCBhZ2FpbnN0IHRoZSBjb25uZWN0b3IncyByZW5kZXJpbmcgdG8gZGVjaWRlIHdoZXRoZXIgaXRcbiAqIG5lZWRzIGNvbnZlcmdpbmcuIEEgc3RyYXkgc3BhY2Ugd291bGQgbWFrZSBldmVyeSByZWNvbmNpbGUgc2VlIGRyaWZ0IGFuZCBjaHVybiBhIG5ldyBmdW5jdGlvbiB2ZXJzaW9uXG4gKiBmb3JldmVyLlxuICpcbiAqIFdIWSBUSEUgV0hPTEUgRE9DVU1FTlQsIFJBVEhFUiBUSEFOIEEgRkVXIFZBUklBQkxFUy4gVGhlIGxheWVyIHNoaXBzIGEgYmFrZWRcbiAqIC9vcHQvY29sbGVjdG9yLWNvbmZpZy9jb25maWcueWFtbCwgYnV0IHRoYXQgZmlsZSBpcyBPTkUgZG9jdW1lbnQgc2hhcmVkIGJ5IGV2ZXJ5IGZ1bmN0aW9uLCBzbyBpdCBjYW5cbiAqIG9ubHkgcmVhY2ggYSBkZXN0aW5hdGlvbiB0aHJvdWdoIGVudiBpbmRpcmVjdGlvbiDigJQgYCR7ZW52OlNPTUVUSElOR31gLiBUaGF0IG1hZGUgdGhyZWUgdGhpbmdzXG4gKiBpbXBvc3NpYmxlIGF0IG9uY2U6XG4gKlxuICogICAtIEFVVEguIEEgY3JlZGVudGlhbCBpcyBhIGhlYWRlcnMgbWFwLCBub3QgYSBzY2FsYXIuIEEgYmFrZWQgZmlsZSBjYW4gc3Vic3RpdHV0ZSBhIHZhbHVlIGJ1dCBjYW5ub3RcbiAqICAgICBjb25kaXRpb25hbGx5IGdyb3cgYSBgaGVhZGVyczpgIGJsb2NrLCBzbyBhbiBhdXRoZW50aWNhdGVkIGRlc3RpbmF0aW9uIHdhcyB1bnJlYWNoYWJsZS5cbiAqICAgLSBPVExQL0hUVFAgREVTVElOQVRJT05TLiBUaGUgYmFrZWQgZmlsZSBoYXJkY29kZXMgYSBnUlBDIGBvdGxwYCBleHBvcnRlci4gQW4gb3RscGh0dHAtb25seVxuICogICAgIGRlc3RpbmF0aW9uIHJlc29sdmVzIHdpdGggYW4gZW1wdHkgZ1JQQyBlbmRwb2ludCwgYW5kIHRoZSBjb2xsZWN0b3IgZG9lcyBub3QgZGVncmFkZSDigJQgaXQgZmFpbHMgdG9cbiAqICAgICBidWlsZCB0aGUgcGlwZWxpbmUgYW5kIGV4aXRzLCBzbyB0aGUgZnVuY3Rpb24gaXMgaW5zdHJ1bWVudGVkLCBsb29rcyBoZWFsdGh5LCBhbmQgZXhwb3J0cyBub3RoaW5nLlxuICogICAtIFBFUi1TSUdOQUwgUElQRUxJTkVTLiBUaGUgYmFrZWQgZmlsZSBkZWNsYXJlcyBhbGwgdGhyZWUgcGlwZWxpbmVzIHVuY29uZGl0aW9uYWxseSwgc28gYSBzaWduYWwgdGhlXG4gKiAgICAgZGVzdGluYXRpb24gZG9lcyBub3QgYWNjZXB0IGlzIHJlY2VpdmVkIGFuZCB0aGVuIGZhaWxzIG9uIGV4cG9ydCByYXRoZXIgdGhhbiBuZXZlciBiZWluZyBidWlsdC5cbiAqXG4gKiBGTE9XIFNUWUxFIElTIExPQUQtQkVBUklORy4gVGhlIGRvY3VtZW50IGlzIGVtaXR0ZWQgb24gYSBzaW5nbGUgbGluZSBiZWNhdXNlIGl0IGhhcyB0byBzdXJ2aXZlIGFzIGFuXG4gKiBlbnZpcm9ubWVudCB2YXJpYWJsZSB2YWx1ZS4gSW4gYSBZQU1MIGZsb3cgbWFwcGluZyBhIGNvbG9uIG11c3QgYmUgZm9sbG93ZWQgYnkgYSBzcGFjZSwgb3IgdGhlIHBhcnNlclxuICogcmVhZHMgYGE6YmAgYXMgdGhlIHBsYWluIHNjYWxhciBgXCJhOmJcImAgcmF0aGVyIHRoYW4gYSBtYXBwaW5nLiBXcml0dGVuIHdpdGhvdXQgdGhlIHNwYWNlcyB0aGUgY29sbGVjdG9yXG4gKiBhY2NlcHRzIHRoZSB2YXJpYWJsZSwgcmVwb3J0cyB0aGUgVVJJIGl0IHJlYWQsIGFuZCB0aGVuIGZhaWxzIHRvIHN0YXJ0IHdpdGggYSBiYXJlXG4gKiBgb3RlbGNvbCBzdGF0ZSBpcyBDbG9zZWRgIOKAlCBubyBwYXJzZSBlcnJvciwgbm8gbWVudGlvbiBvZiB0aGUgY29uZmlnLiBFdmVyeSBgOiBgIGJlbG93IGVhcm5zIGl0cyBwbGFjZS5cbiAqL1xuXG4vKipcbiAqIFRoZSBjb2xsZWN0b3IgbGF5ZXIncyBvd24gY29uZmlnLXNvdXJjZSB2YXJpYWJsZSDigJQgdXBzdHJlYW0ncyBuYW1lLCBub3Qgb3Vycy4gUG9pbnRlZCBhdCBhIGB5YW1sOmAgVVJJXG4gKiBpdCBjYXJyaWVzIHRoZSBlbnRpcmUgY29uZmlndXJhdGlvbiBpbmxpbmUsIHNvIG5vIHNlY29uZCB2YXJpYWJsZSBpcyBuZWVkZWQgdG8gaG9sZCBpdC5cbiAqXG4gKiBVcHN0cmVhbSBhbHNvIHJlYWRzIHRoZSBvbGRlciBgT1BFTlRFTEVNRVRSWV9DT0xMRUNUT1JfQ09ORklHX0ZJTEVgIGFuZCBsb2dzIGEgZGVwcmVjYXRpb24gd2FybmluZyBmb3JcbiAqIGl0OyB0aGlzIGlzIHRoZSBjdXJyZW50IG5hbWUuXG4gKi9cbmV4cG9ydCBjb25zdCBFTlZfQ09MTEVDVE9SX0NPTkZJR19VUkkgPSAnT1BFTlRFTEVNRVRSWV9DT0xMRUNUT1JfQ09ORklHX1VSSSc7XG5cbi8qKlxuICogVGhlIGNvbmZtYXAgcHJvdmlkZXIgdGhhdCByZWFkcyBhIGNvbmZpZ3VyYXRpb24gb3V0IG9mIHRoZSBVUkkgaXRzZWxmLiBUaGUgY29sbGVjdG9yIHJlZ2lzdGVyc1xuICogZW52L2ZpbGUveWFtbC9odHRwL2h0dHBzL3MzIHByb3ZpZGVyczsgYHlhbWw6YCBpcyB0aGUgb25seSBvbmUgdGhhdCBuZWVkcyBubyBzZWNvbmQgdmFyaWFibGUgYW5kIG5vXG4gKiBuZXR3b3JrIHJlYWQgb24gYSBjb2xkIHN0YXJ0LlxuICovXG5jb25zdCBDT0xMRUNUT1JfQ09ORklHX1NDSEVNRSA9ICd5YW1sOic7XG5cbi8qKlxuICogTWlycm9ycyB0aGUgYmFrZWQgY29uZmlnJ3MgcHJvY2Vzc29yIHNldCwgYW5kIHRoZSBPUkRFUiBpcyB0aGUgY29udHJhY3Q6XG4gKlxuICogICAtIGBtZW1vcnlfbGltaXRlcmAgZmlyc3QsIHNvIGFuIGV4cG9ydCBiYWNrbG9nIGlzIHNoZWQgYmVmb3JlIGl0IGlzIGNoYXJnZWQgdG8gdGhlIHNhbWUgbWVtb3J5IGJ1ZGdldFxuICogICAgIHRoZSBjdXN0b21lcidzIGhhbmRsZXIgYWxsb2NhdGVzIGZyb20uIFBlcmNlbnRhZ2VzLCBub3QgYGxpbWl0X21pYmAsIGJlY2F1c2Ugb25lIGxheWVyIHNlcnZlc1xuICogICAgIGZ1bmN0aW9ucyBmcm9tIDEyOE1CIHRvIDEwR0IuXG4gKiAgIC0gYGRlY291cGxlYCBMQVNULiBMYW1iZGEgZnJlZXplcyB0aGUgc2FuZGJveCBvbmNlIHRoZSBoYW5kbGVyIHJldHVybnMgYW5kIGV2ZXJ5IGV4dGVuc2lvbiBoYXMgY2FsbGVkXG4gKiAgICAgL25leHQ7IGEgZnJvemVuIHNhbmRib3ggcnVucyBubyB0aW1lcnMsIHNvIGEgYmF0Y2ggc2l0dGluZyBiZWhpbmQgaXRzIHRpbWVvdXQgaXMgZmx1c2hlZCBvbiBhIGxhdGVyXG4gKiAgICAgaW52b2NhdGlvbiBvciBkcm9wcGVkIHdoZW4gdGhlIHNhbmRib3ggaXMgcmVhcGVkLiBgZGVjb3VwbGVgIGFja25vd2xlZGdlcyB0aGUgcmVjZWl2ZSBwYXRoXG4gKiAgICAgaW1tZWRpYXRlbHkgYW5kIHRyYWNrcyBpbi1mbGlnaHQgZXhwb3J0cywgd2hpY2ggaXMgd2hhdCBsZXRzIHRoZSBleHRlbnNpb24gaG9sZCAvbmV4dCBvcGVuIHVudGlsIHRoZVxuICogICAgIHF1ZXVlIGRyYWlucyDigJQgYWZ0ZXIgdGhlIGNhbGxlciBhbHJlYWR5IGhhcyBpdHMgcmVzcG9uc2UuXG4gKi9cbmNvbnN0IENPTExFQ1RPUl9QUk9DRVNTT1JTID1cbiAgJ3ttZW1vcnlfbGltaXRlcjoge2NoZWNrX2ludGVydmFsOiAxcywgbGltaXRfcGVyY2VudGFnZTogNTAsIHNwaWtlX2xpbWl0X3BlcmNlbnRhZ2U6IDIwfSwgJyArXG4gICdiYXRjaDoge3NlbmRfYmF0Y2hfc2l6ZTogNTEyLCB0aW1lb3V0OiAyMDBtc30sIGRlY291cGxlOiBudWxsfSc7XG5cbi8qKiBWYWx1ZSBhbiB1bnN1cHBvcnRlZCBzaWduYWwncyBgT1RFTF8qX0VYUE9SVEVSYCBpcyBzZXQgdG8uICovXG5leHBvcnQgY29uc3QgRVhQT1JURVJfTk9ORSA9ICdub25lJztcblxuLyoqIFRoZSB0aHJlZSBgT1RFTF8qX0VYUE9SVEVSYCB2YXJpYWJsZXMsIGluIHRoZSBvcmRlciB0aGUgY29ubmVjdG9yIHdyaXRlcyB0aGVtLiAqL1xuZXhwb3J0IGNvbnN0IEVOVl9UUkFDRVNfRVhQT1JURVIgPSAnT1RFTF9UUkFDRVNfRVhQT1JURVInO1xuZXhwb3J0IGNvbnN0IEVOVl9NRVRSSUNTX0VYUE9SVEVSID0gJ09URUxfTUVUUklDU19FWFBPUlRFUic7XG5leHBvcnQgY29uc3QgRU5WX0xPR1NfRVhQT1JURVIgPSAnT1RFTF9MT0dTX0VYUE9SVEVSJztcblxuLyoqXG4gKiBXaGV0aGVyIGEgc2lnbmFsIGlzIGVuYWJsZWQsIGdpdmVuIHRoZSBjYWxsZXIncyB2YWx1ZSBhbmQgdGhlIHNpZ25hbCdzIG93biBkZWZhdWx0LlxuICpcbiAqIFRoZSBkZWZhdWx0cyBhcmUgTk9UIHVuaWZvcm06IHRyYWNlcyBhcmUgb24sIG1ldHJpY3MgYW5kIGxvZ3MgYXJlIG9mZiAoc2VlIGBTSUdOQUxfREVGQVVMVFNgKS4gU28gdGhlXG4gKiBkZWZhdWx0IGhhcyB0byB0cmF2ZWwgd2l0aCB0aGUgc2lnbmFsIHJhdGhlciB0aGFuIGJlaW5nIGZvbGRlZCBpbnRvIG9uZSBcInVuc2V0IG1lYW5zIG9uXCIgcnVsZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNpZ25hbEVuYWJsZWQodmFsdWU6IGJvb2xlYW4gfCB1bmRlZmluZWQsIGRlZmF1bHRFbmFibGVkOiBib29sZWFuKTogYm9vbGVhbiB7XG4gIHJldHVybiB2YWx1ZSA/PyBkZWZhdWx0RW5hYmxlZDtcbn1cblxuLyoqXG4gKiBXaGljaCBzaWduYWxzIGEgZGVzdGluYXRpb24gY2FycmllcyB3aGVuIHRoZSBjYWxsZXIgc2F5cyBub3RoaW5nLlxuICpcbiAqIFRSQUNFUyBPTkxZLiBNZXRyaWNzIGFuZCBsb2dzIGFyZSBvcHQtaW4gYmVjYXVzZSB0aGUgY29zdCBvZiBoYXZpbmcgdGhlbSBvbiBieSBkZWZhdWx0IGZhbGxzIG9uIHBlb3BsZVxuICogd2hvIG5ldmVyIGFza2VkIGZvciB0aGVtOiBhIGRlc3RpbmF0aW9uIHRoYXQgZG9lcyBub3QgaW1wbGVtZW50IGEgc2lnbmFsIHJlZnVzZXMgZXZlcnkgYmF0Y2ggb2YgaXQsIGFuZFxuICogdGhlIGluLUxhbWJkYSBjb2xsZWN0b3IgdGhlbiByZXRyaWVzIG9uIGFuIGV4cG9uZW50aWFsIGJhY2tvZmYgaW5zaWRlIGJpbGxlZCBkdXJhdGlvbi4gVHJhY2VzIGFyZSB3aGF0XG4gKiBhbG1vc3QgZXZlcnkgZGVzdGluYXRpb24gYWNjZXB0cyBhbmQgd2hhdCBhbG1vc3QgZXZlcnlvbmUgaW5zdHJ1bWVudHMgZm9yOyB0aGUgb3RoZXIgdHdvIGFyZSBhXG4gKiBkZWxpYmVyYXRlIGNob2ljZSBhYm91dCB0aGUgZGVzdGluYXRpb24sIHNvIHRoZXkgYXJlIG1hZGUgZGVsaWJlcmF0ZWx5LlxuICpcbiAqIFR1cm5pbmcgb25lIG9uIGlzIGBtZXRyaWNzOiB0cnVlYC4gRW5hYmxpbmcgYSBzaWduYWwgc2V0cyBgT1RFTF8qX0VYUE9SVEVSPW90bHBgIGV4cGxpY2l0bHkuXG4gKi9cbmV4cG9ydCBjb25zdCBTSUdOQUxfREVGQVVMVFMgPSB7IHRyYWNlczogdHJ1ZSwgbWV0cmljczogZmFsc2UsIGxvZ3M6IGZhbHNlIH07XG5cbi8qKiBUaGUgdGhyZWUgc2lnbmFscyByZXNvbHZlZCBhZ2FpbnN0IHRoZWlyIGRlZmF1bHRzIOKAlCB0aGUgc2luZ2xlIHBsYWNlIHRoYXQgcGFpcmluZyBpcyBkZWNpZGVkLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVkU2lnbmFscyhkZXN0OiBPZGlnb3NEZXN0aW5hdGlvbik6IHsgdHJhY2VzOiBib29sZWFuOyBtZXRyaWNzOiBib29sZWFuOyBsb2dzOiBib29sZWFuIH0ge1xuICByZXR1cm4ge1xuICAgIHRyYWNlczogc2lnbmFsRW5hYmxlZChkZXN0LnRyYWNlcywgU0lHTkFMX0RFRkFVTFRTLnRyYWNlcyksXG4gICAgbWV0cmljczogc2lnbmFsRW5hYmxlZChkZXN0Lm1ldHJpY3MsIFNJR05BTF9ERUZBVUxUUy5tZXRyaWNzKSxcbiAgICBsb2dzOiBzaWduYWxFbmFibGVkKGRlc3QubG9ncywgU0lHTkFMX0RFRkFVTFRTLmxvZ3MpLFxuICB9O1xufVxuXG4vKipcbiAqIFJlbmRlcnMgYSBkb3VibGUtcXVvdGVkIFlBTUwgc2NhbGFyLlxuICpcbiAqIFF1b3RpbmcgdW5jb25kaXRpb25hbGx5IGlzIHdoYXQga2VlcHMgYSB2YWx1ZSBzdWNoIGFzIGEgYmFyZSBgaG9zdDo0MzE3YCBmcm9tIGJlaW5nIHJlLXJlYWQgYXMgYSBuZXN0ZWRcbiAqIG1hcHBpbmcgaW4gZmxvdyBjb250ZXh0LiBgSlNPTi5zdHJpbmdpZnlgIGlzIHRoZSBUeXBlU2NyaXB0IGVxdWl2YWxlbnQgb2YgdGhlIGNvbm5lY3RvcidzXG4gKiBgc3RyY29udi5RdW90ZWAgZm9yIHRoZSB2b2NhYnVsYXJ5IHRoYXQgbWF0dGVycyBoZXJlIChgXFxcImAgYW5kIGBcXFxcYCk7IGJvdGggcHJvZHVjZSB0aGUgc2FtZSBvdXRwdXQgZm9yXG4gKiB0aGUgQVNDSUkgZW5kcG9pbnRzLCBoZWFkZXIgbmFtZXMgYW5kIGNyZWRlbnRpYWxzIHRoaXMgZXZlciBzZWVzLlxuICovXG5mdW5jdGlvbiB5YW1sU3RyaW5nKHM6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBKU09OLnN0cmluZ2lmeShzKTtcbn1cblxuLyoqXG4gKiBQaWNrcyB0aGUgZXhwb3J0ZXIgYnkgdGhlIHRyYW5zcG9ydCB0aGUgZGVzdGluYXRpb24gY29uZmlndXJlZC4gQSBkZXN0aW5hdGlvbiBjYXJyaWVzIGEgZ1JQQyBlbmRwb2ludFxuICogKHR5cGUgYG90bHBgKSBvciBhbiBPVExQL0hUVFAgb25lICh0eXBlIGBvdGxwaHR0cGApOyB0aGUgdHdvIGFyZSBkaWZmZXJlbnQgY29sbGVjdG9yIGNvbXBvbmVudHMgd2l0aFxuICogZGlmZmVyZW50IGVuZHBvaW50IGdyYW1tYXJzLCBzbyB0aGlzIGlzIGEgZ2VudWluZSBicmFuY2guXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBleHBvcnRlck5hbWVGb3IoZGVzdDogT2RpZ29zRGVzdGluYXRpb24pOiBzdHJpbmcge1xuICByZXR1cm4gZGVzdC5lbmRwb2ludCA/ICdvdGxwJyA6ICdvdGxwaHR0cCc7XG59XG5cbi8qKlxuICogRW1pdHMgdGhlIGRlc3RpbmF0aW9uJ3MgcGVyLXJlcXVlc3QgaGVhZGVycyDigJQgaW4gcHJhY3RpY2UgaXRzIGNyZWRlbnRpYWwuIEVtcHR5IHdoZW4gdGhlIGRlc3RpbmF0aW9uXG4gKiBuZWVkcyBub25lLCBzbyBubyBoZWFkZXIgYmxvY2sgaXMgd3JpdHRlbiBhdCBhbGwgcmF0aGVyIHRoYW4gYW4gZW1wdHkgb25lLlxuICpcbiAqIEtleXMgYXJlIHNvcnRlZCBzbyB0aGUgcmVuZGVyZWQgY29uZmlnIGlzIGJ5dGUtaWRlbnRpY2FsIGFjcm9zcyBzeW50aHMuIFRoZSBzdHJpbmcgaXMgY29tcGFyZWQgYWdhaW5zdFxuICogdGhlIGxpdmUgZnVuY3Rpb24ncyBlbnZpcm9ubWVudCB0byBkZWNpZGUgd2hldGhlciBhbiB1cGRhdGUgaXMgbmVlZGVkLCBhbmQgbWFwIG9yZGVyIHdvdWxkIG90aGVyd2lzZVxuICogbWFrZSBldmVyeSBkZXBsb3kgbG9vayBsaWtlIGEgY2hhbmdlLlxuICovXG5mdW5jdGlvbiByZW5kZXJIZWFkZXJzKGhlYWRlcnM/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9KTogc3RyaW5nIHtcbiAgaWYgKCFoZWFkZXJzKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG4gIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhoZWFkZXJzKS5zb3J0KCk7XG4gIGlmIChrZXlzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiAnJztcbiAgfVxuICBjb25zdCByZW5kZXJlZCA9IGtleXMubWFwKChrKSA9PiBgJHt5YW1sU3RyaW5nKGspfTogJHt5YW1sU3RyaW5nKGhlYWRlcnNba10pfWApLmpvaW4oJywgJyk7XG4gIHJldHVybiBgLCBoZWFkZXJzOiB7JHtyZW5kZXJlZH19YDtcbn1cblxuZnVuY3Rpb24gcmVuZGVyRXhwb3J0ZXIoZGVzdDogT2RpZ29zRGVzdGluYXRpb24pOiBzdHJpbmcge1xuICBsZXQgb3V0OiBzdHJpbmc7XG4gIGlmIChkZXN0LmVuZHBvaW50KSB7XG4gICAgLy8gdGxzLmluc2VjdXJlIGFwcGxpZXMgdG8gdGhlIGdSUEMgZXhwb3J0ZXIgb25seTsgdGhlIEhUVFAgZXhwb3J0ZXIgdGFrZXMgdGhlIHNjaGVtZSBmcm9tIHRoZSBVUkwuXG4gICAgb3V0ID0gYHtvdGxwOiB7ZW5kcG9pbnQ6ICR7eWFtbFN0cmluZyhkZXN0LmVuZHBvaW50KX0sIHRsczoge2luc2VjdXJlOiAke2Rlc3QuaW5zZWN1cmUgPT09IHRydWV9fWA7XG4gIH0gZWxzZSBpZiAoZGVzdC5odHRwRW5kcG9pbnQpIHtcbiAgICBvdXQgPSBge290bHBodHRwOiB7ZW5kcG9pbnQ6ICR7eWFtbFN0cmluZyhkZXN0Lmh0dHBFbmRwb2ludCl9YDtcbiAgfSBlbHNlIHtcbiAgICAvLyBSZWFjaGVkIHdoZW4gYSBkZXN0aW5hdGlvbiBjYXJyaWVzIG5laXRoZXIgdHJhbnNwb3J0LiBGYWlsaW5nIGhlcmUgaXMgdGhlIHdob2xlIHBvaW50OiB0aGVcbiAgICAvLyBhbHRlcm5hdGl2ZSBpcyBhIGNvbGxlY3RvciB0aGF0IGV4aXRzIG9uIHN0YXJ0dXAgd2hpbGUgdGhlIGZ1bmN0aW9uIGlzIHJlcG9ydGVkIGhlYWx0aHkuXG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgJ09kaWdvcyBkZXN0aW5hdGlvbiBoYXMgbmVpdGhlciBgZW5kcG9pbnRgIChPVExQL2dSUEMpIG5vciBgaHR0cEVuZHBvaW50YCAoT1RMUC9IVFRQKSwgJyArXG4gICAgICAgICdzbyB0aGUgaW4tTGFtYmRhIGNvbGxlY3RvciB3b3VsZCBoYXZlIG5vd2hlcmUgdG8gZXhwb3J0LicsXG4gICAgKTtcbiAgfVxuICByZXR1cm4gYCR7b3V0fSR7cmVuZGVySGVhZGVycyhkZXN0LmhlYWRlcnMpfX19YDtcbn1cblxuLyoqXG4gKiBCdWlsZHMgYSBwaXBlbGluZSBvbmx5IGZvciB0aGUgc2lnbmFscyB0aGUgZGVzdGluYXRpb24gYWNjZXB0cy4gQSBzaWduYWwgd2l0aCBubyBwaXBlbGluZSBpcyByZWZ1c2VkIGF0XG4gKiB0aGUgcmVjZWl2ZXIsIHdoaWNoIGlzIHRoZSBiZWhhdmlvdXIgd2Ugd2FudDogdGhlIFNESyBpcyB0b2xkIG5vdCB0byBwcm9kdWNlIGl0IGVpdGhlciAoc2VlXG4gKiBgZXhwb3J0ZXJPdmVycmlkZUZvcmApLCBhbmQgdGhlIHR3byB0b2dldGhlciBtZWFuIGFuIHVuYWNjZXB0ZWQgc2lnbmFsIGlzIG5ldmVyIGdlbmVyYXRlZCwgbmV2ZXJcbiAqIGV4cG9ydGVkLCBhbmQgbmV2ZXIgYSBwZXItYmF0Y2ggZXJyb3IgYWdhaW5zdCBhIGJhY2tlbmQgdGhhdCBkb2VzIG5vdCBpbXBsZW1lbnQgaXQuXG4gKi9cbmZ1bmN0aW9uIHJlbmRlclBpcGVsaW5lcyhkZXN0OiBPZGlnb3NEZXN0aW5hdGlvbiwgZXhwb3J0ZXJOYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBwYXJ0czogc3RyaW5nW10gPSBbXTtcbiAgY29uc3QgZW5hYmxlZCA9IHJlc29sdmVkU2lnbmFscyhkZXN0KTtcbiAgY29uc3Qgc2lnbmFsczogQXJyYXk8W3N0cmluZywgYm9vbGVhbl0+ID0gW1xuICAgIFsndHJhY2VzJywgZW5hYmxlZC50cmFjZXNdLFxuICAgIFsnbWV0cmljcycsIGVuYWJsZWQubWV0cmljc10sXG4gICAgWydsb2dzJywgZW5hYmxlZC5sb2dzXSxcbiAgXTtcbiAgZm9yIChjb25zdCBbbmFtZSwgZW5hYmxlZF0gb2Ygc2lnbmFscykge1xuICAgIGlmICghZW5hYmxlZCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIHBhcnRzLnB1c2goXG4gICAgICBgJHtuYW1lfToge3JlY2VpdmVyczogW290bHBdLCBwcm9jZXNzb3JzOiBbbWVtb3J5X2xpbWl0ZXIsIGJhdGNoLCBkZWNvdXBsZV0sIGV4cG9ydGVyczogWyR7ZXhwb3J0ZXJOYW1lfV19YCxcbiAgICApO1xuICB9XG4gIHJldHVybiBwYXJ0cy5sZW5ndGggPT09IDAgPyAnJyA6IGB7JHtwYXJ0cy5qb2luKCcsICcpfX1gO1xufVxuXG4vKiogRXhwbGljaXQgZXhwb3J0ZXIgc2VsZWN0b3JzIG1pcnJvciB0aGUgYmFzZSBjb25uZWN0b3IgcG9saWN5OyBTREsgZGVmYXVsdHMgdmFyeS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBleHBvcnRlck92ZXJyaWRlRm9yKGVuYWJsZWQ6IGJvb2xlYW4pOiBzdHJpbmcge1xuICByZXR1cm4gZW5hYmxlZCA/ICdvdGxwJyA6IEVYUE9SVEVSX05PTkU7XG59XG5cbi8qKiBQZXItc2lnbmFsIHRyYW5zcG9ydCBvdmVycmlkZXMgYnlwYXNzIHRoZSBkZXN0aW5hdGlvbiBhbmQgbXVzdCBub3QgY29leGlzdCB3aXRoIGl0LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNpZ25hbFRyYW5zcG9ydE92ZXJyaWRlcygpOiBzdHJpbmdbXSB7XG4gIHJldHVybiBbJ1RSQUNFUycsICdNRVRSSUNTJywgJ0xPR1MnXS5mbGF0TWFwKChzaWduYWwpID0+XG4gICAgWydFTkRQT0lOVCcsICdQUk9UT0NPTCcsICdIRUFERVJTJywgJ0lOU0VDVVJFJ10ubWFwKChzZXR0aW5nKSA9PiBgT1RFTF9FWFBPUlRFUl9PVExQXyR7c2lnbmFsfV8ke3NldHRpbmd9YCksXG4gICk7XG59XG5cbi8qKiBMYW5ndWFnZS1zcGVjaWZpYyBTREsgYWN0aXZhdGlvbiwgc2hhcmVkIGJ5IExhbWJkYSBhbmQgRmFyZ2F0ZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzaWduYWxBY3RpdmF0aW9uKGxhbmd1YWdlOiBzdHJpbmcsIGRlc3Q6IE9kaWdvc0Rlc3RpbmF0aW9uKTogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSB7XG4gIGNvbnN0IGVuYWJsZWQgPSByZXNvbHZlZFNpZ25hbHMoZGVzdCk7XG4gIGNvbnN0IGVudjogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSA9IHtcbiAgICBPVEVMX1NES19ESVNBQkxFRDogJ2ZhbHNlJyxcbiAgICBbRU5WX1RSQUNFU19FWFBPUlRFUl06IGV4cG9ydGVyT3ZlcnJpZGVGb3IoZW5hYmxlZC50cmFjZXMpLFxuICAgIFtFTlZfTUVUUklDU19FWFBPUlRFUl06IGV4cG9ydGVyT3ZlcnJpZGVGb3IoZW5hYmxlZC5tZXRyaWNzKSxcbiAgICBbRU5WX0xPR1NfRVhQT1JURVJdOiBleHBvcnRlck92ZXJyaWRlRm9yKGVuYWJsZWQubG9ncyksXG4gIH07XG4gIGlmIChsYW5ndWFnZSA9PT0gJ3B5dGhvbicpIHtcbiAgICBlbnYuT1RFTF9QWVRIT05fTE9HR0lOR19BVVRPX0lOU1RSVU1FTlRBVElPTl9FTkFCTEVEID0gU3RyaW5nKGVuYWJsZWQubG9ncyk7XG4gIH1cbiAgcmV0dXJuIGVudjtcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBjb21wbGV0ZSBjb2xsZWN0b3IgY29uZmlndXJhdGlvbiBmb3Igb25lIGRlc3RpbmF0aW9uLlxuICpcbiAqIEB0aHJvd3MgaWYgdGhlIGRlc3RpbmF0aW9uIG5hbWVzIG5laXRoZXIgdHJhbnNwb3J0LCBib3RoIHRyYW5zcG9ydHMsIG9yIG5vIHNpZ25hbHMgYXQgYWxsLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVuZGVyQ29sbGVjdG9yQ29uZmlnKGRlc3Q6IE9kaWdvc0Rlc3RpbmF0aW9uKTogc3RyaW5nIHtcbiAgdmFsaWRhdGVEZXN0aW5hdGlvbihkZXN0KTtcblxuICBjb25zdCBleHBvcnRlciA9IHJlbmRlckV4cG9ydGVyKGRlc3QpO1xuICBjb25zdCBwaXBlbGluZXMgPSByZW5kZXJQaXBlbGluZXMoZGVzdCwgZXhwb3J0ZXJOYW1lRm9yKGRlc3QpKTtcbiAgaWYgKHBpcGVsaW5lcyA9PT0gJycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnT2RpZ29zIGRlc3RpbmF0aW9uIGFjY2VwdHMgbm8gdGVsZW1ldHJ5IHNpZ25hbHMsIHNvIHRoZSBjb2xsZWN0b3Igd291bGQgaGF2ZSBubyBwaXBlbGluZSB0byBidWlsZCAnICtcbiAgICAgICAgJ2FuZCB3b3VsZCBmYWlsIHRvIHN0YXJ0LiBOb3RlIHRoYXQgbWV0cmljcyBhbmQgbG9ncyBhcmUgT0ZGIGJ5IGRlZmF1bHQg4oCUIHdpdGggYHRyYWNlczogZmFsc2VgIHRoZSAnICtcbiAgICAgICAgJ2Rlc3RpbmF0aW9uIGhhcyBub3RoaW5nIGxlZnQgdW5sZXNzIHlvdSBhbHNvIHBhc3MgYG1ldHJpY3M6IHRydWVgIG9yIGBsb2dzOiB0cnVlYC4nLFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gKFxuICAgIENPTExFQ1RPUl9DT05GSUdfU0NIRU1FICtcbiAgICAne3JlY2VpdmVyczoge290bHA6IHtwcm90b2NvbHM6ICcgK1xuICAgIC8vIEJvdW5kIHRvIGxvY2FsaG9zdDogdGhlIHJlY2VpdmVyIGV4aXN0cyBvbmx5IGZvciB0aGUgaW4tcHJvY2VzcyBTREsuIEJpbmRpbmcgaXQgd2lkZXIgd291bGQgZXhwb3NlXG4gICAgLy8gYW4gdW5hdXRoZW50aWNhdGVkIE9UTFAgZW5kcG9pbnQgb24gdGhlIHNhbmRib3gncyBuZXR3b3JrIGludGVyZmFjZS5cbiAgICAne2dycGM6IHtlbmRwb2ludDogXCJsb2NhbGhvc3Q6NDMxN1wifSwgaHR0cDoge2VuZHBvaW50OiBcImxvY2FsaG9zdDo0MzE4XCJ9fX19LCAnICtcbiAgICAncHJvY2Vzc29yczogJyArXG4gICAgQ09MTEVDVE9SX1BST0NFU1NPUlMgK1xuICAgICcsIGV4cG9ydGVyczogJyArXG4gICAgZXhwb3J0ZXIgK1xuICAgICcsIHNlcnZpY2U6IHt0ZWxlbWV0cnk6IHttZXRyaWNzOiB7bGV2ZWw6IG5vbmV9fSwgcGlwZWxpbmVzOiAnICtcbiAgICBwaXBlbGluZXMgK1xuICAgICd9fSdcbiAgKTtcbn1cblxuLyoqIFZhbGlkYXRlIGJvdGggdHJhbnNwb3J0cyBiZWZvcmUgZ2VuZXJhdGluZyBMYW1iZGEgY29uZmlndXJhdGlvbiBvciBtdXRhdGluZyBhbiBFQ1MgdGFzay4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZURlc3RpbmF0aW9uKGRlc3Q6IE9kaWdvc0Rlc3RpbmF0aW9uLCBhbGxvd0JvdGggPSBmYWxzZSk6IHZvaWQge1xuICBpZiAoZGVzdC5lbmRwb2ludCAmJiBkZXN0Lmh0dHBFbmRwb2ludCAmJiAhYWxsb3dCb3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdPZGlnb3MgZGVzdGluYXRpb24gc2V0cyBib3RoIGBlbmRwb2ludGAgKE9UTFAvZ1JQQykgYW5kIGBodHRwRW5kcG9pbnRgIChPVExQL0hUVFApOyBleGFjdGx5IG9uZSBtdXN0IGJlIHNldCBmb3IgTGFtYmRhLicpO1xuICB9XG4gIGlmICghZGVzdC5lbmRwb2ludCAmJiAhZGVzdC5odHRwRW5kcG9pbnQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ09kaWdvcyBkZXN0aW5hdGlvbiBoYXMgbmVpdGhlciBgZW5kcG9pbnRgIChPVExQL2dSUEMpIG5vciBgaHR0cEVuZHBvaW50YCAoT1RMUC9IVFRQKS4nKTtcbiAgfVxuICBpZiAoZGVzdC5lbmRwb2ludCAmJiAhVG9rZW4uaXNVbnJlc29sdmVkKGRlc3QuZW5kcG9pbnQpKSB7XG4gICAgaWYgKGRlc3QuZW5kcG9pbnQuaW5jbHVkZXMoJzovLycpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ09kaWdvcyBkZXN0aW5hdGlvbiBgZW5kcG9pbnRgIHRha2VzIGhvc3Q6cG9ydCB3aXRoIG5vIHNjaGVtZS4gVXNlIGBodHRwRW5kcG9pbnRgIGZvciBhbiBIVFRQIFVSTC4nKTtcbiAgICB9XG4gICAgbGV0IHVybDogVVJMO1xuICAgIHRyeSB7IHVybCA9IG5ldyBVUkwoYGh0dHA6Ly8ke2Rlc3QuZW5kcG9pbnR9YCk7IH0gY2F0Y2gge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdPZGlnb3MgZGVzdGluYXRpb24gYGVuZHBvaW50YCBtdXN0IGJlIGEgdmFsaWQgZ1JQQyBob3N0OnBvcnQuJyk7XG4gICAgfVxuICAgIGlmICghdXJsLmhvc3RuYW1lIHx8IHVybC51c2VybmFtZSB8fCB1cmwucGFzc3dvcmQgfHwgdXJsLnBhdGhuYW1lICE9PSAnLycgfHwgdXJsLnNlYXJjaCB8fCB1cmwuaGFzaCB8fCAvXFxzLy50ZXN0KGRlc3QuZW5kcG9pbnQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ09kaWdvcyBkZXN0aW5hdGlvbiBgZW5kcG9pbnRgIG11c3QgYmUgYSBiYXJlIGdSUEMgaG9zdDpwb3J0IHdpdGhvdXQgY3JlZGVudGlhbHMsIHBhdGhzIG9yIHF1ZXJ5IHBhcmFtZXRlcnMuJyk7XG4gICAgfVxuICB9XG4gIGlmIChkZXN0Lmh0dHBFbmRwb2ludCAmJiAhVG9rZW4uaXNVbnJlc29sdmVkKGRlc3QuaHR0cEVuZHBvaW50KSkge1xuICAgIGxldCB1cmw6IFVSTDtcbiAgICB0cnkgeyB1cmwgPSBuZXcgVVJMKGRlc3QuaHR0cEVuZHBvaW50KTsgfSBjYXRjaCB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ09kaWdvcyBkZXN0aW5hdGlvbiBgaHR0cEVuZHBvaW50YCByZXF1aXJlcyBhIHZhbGlkIHNjaGVtZS1xdWFsaWZpZWQgVVJMIChodHRwOi8vIG9yIGh0dHBzOi8vKS4nKTtcbiAgICB9XG4gICAgaWYgKCFbJ2h0dHA6JywgJ2h0dHBzOiddLmluY2x1ZGVzKHVybC5wcm90b2NvbCkgfHwgIXVybC5ob3N0bmFtZSB8fCB1cmwudXNlcm5hbWUgfHwgdXJsLnBhc3N3b3JkIHx8IHVybC5oYXNoIHx8IC9cXHMvLnRlc3QoZGVzdC5odHRwRW5kcG9pbnQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ09kaWdvcyBkZXN0aW5hdGlvbiBgaHR0cEVuZHBvaW50YCByZXF1aXJlcyBhIHNjaGVtZS1xdWFsaWZpZWQgVVJMIChodHRwOi8vIG9yIGh0dHBzOi8vKSB3aXRob3V0IGVtYmVkZGVkIGNyZWRlbnRpYWxzIG9yIGZyYWdtZW50cy4nKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqIFRoZSBMYW1iZGEgTm9kZSBsYXllciByZWdpc3RlcnMgb25seSBkbnMvaHR0cC9uZXQgdW5sZXNzIGV4cGxpY2l0bHkgY29uZmlndXJlZC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsYW1iZGFTaWduYWxBY3RpdmF0aW9uKGxhbmd1YWdlOiBzdHJpbmcsIGRlc3Q6IE9kaWdvc0Rlc3RpbmF0aW9uKTogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSB7XG4gIGNvbnN0IGVudiA9IHNpZ25hbEFjdGl2YXRpb24obGFuZ3VhZ2UsIGRlc3QpO1xuICBlbnYuT1RFTF9FWFBPUlRFUl9PVExQX1BST1RPQ09MID0gJ2h0dHAvcHJvdG9idWYnO1xuICBpZiAobGFuZ3VhZ2UgPT09ICdub2RlanMnKSB7XG4gICAgZW52Lk9URUxfTk9ERV9FTkFCTEVEX0lOU1RSVU1FTlRBVElPTlMgPSAnYW1xcGxpYixidW55YW4sY2Fzc2FuZHJhLWRyaXZlcixjb25uZWN0LGRhdGFsb2FkZXIsZG5zLGV4cHJlc3MsZnMsZ3JhcGhxbCxncnBjLGhhcGksaHR0cCxpb3JlZGlzLGthZmthanMsa25leCxrb2EsbWVtY2FjaGVkLG1vbmdvZGIsbW9uZ29vc2UsbXlzcWwsbXlzcWwyLG5lc3Rqcy1jb3JlLG5ldCxwZyxwaW5vLHJlZGlzLHJlc3RpZnksc29ja2V0LmlvLHVuZGljaSx3aW5zdG9uJztcbiAgfVxuICByZXR1cm4gZW52O1xufVxuIl19