@dbx-tools/email 0.6.53 → 0.6.55

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
@@ -20,8 +20,10 @@ presentation lives in
20
20
  host's approval gate fires.
21
21
  - SMTP delivery for production and HTML outbox delivery for local development
22
22
  and tests.
23
- - Sender derivation from the current Databricks user, a fixed `EMAIL_FROM`, or a
24
- configured domain.
23
+ - Sender derivation from the current Databricks user: `EMAIL_DOMAIN` alone is
24
+ enough, with a fixed `EMAIL_FROM` as an override rather than a requirement.
25
+ - A separate do-not-reply sender for system mail (`no-reply@<domain>`, or
26
+ `EMAIL_SYSTEM_FROM`), used automatically when no user is in scope.
25
27
  - Deny-by-default sender policy with exact addresses, domains, domain wildcards,
26
28
  and a named `unrestricted` escape hatch.
27
29
  - React Email rendering with responsive components, matching HTML/plain-text
@@ -70,36 +72,38 @@ approval card and compose components.
70
72
 
71
73
  ## Configuration
72
74
 
73
- | Option | Type | Default | Description |
74
- | ---------------- | ------------------------------- | ----------------------------------------- | -------------------------------------------------------------------------------- |
75
- | `smtp.host` | `string` | `SMTP_HOST` | SMTP server hostname. Omit the whole `smtp` block to run in outbox mode. |
76
- | `smtp.port` | `number` | `SMTP_PORT`, then `587` | SMTP server port. |
77
- | `smtp.secure` | `boolean` | `SMTP_SECURE`, then `port === 465` | TLS-on-connect socket rather than STARTTLS. |
78
- | `smtp.user` | `string` | `SMTP_USER` | SMTP auth username. |
79
- | `smtp.password` | `string` | `SMTP_PASSWORD` | SMTP auth password or API key. |
80
- | `domain` | `string` | `EMAIL_DOMAIN` | Domain the sender is derived on, as `<user-local-part>@<domain>`. |
81
- | `from` | `string` | `EMAIL_FROM` | Fixed `From` address. Skips per-user derivation. |
82
- | `senderPolicy` | `"allowlist" \| "unrestricted"` | `EMAIL_SENDER_POLICY`, then `"allowlist"` | How the sender is restricted when `allowedSenders` is empty. |
83
- | `allowedSenders` | `string \| string[]` | `EMAIL_ALLOWED_SENDERS` | Permitted `From` patterns: exact addresses, `*@domain`, a bare `domain`, or `*`. |
84
- | `outDir` | `string` | `EMAIL_OUTBOX_DIR`, then `<cwd>/tmp` | Directory the outbox writes HTML previews to. |
85
- | `brand` | `EmailBrand` | dbx-tools brand | Colors, font, display name, footer, and optional logo applied to every message. |
75
+ | Option | Type | Default | Description |
76
+ | ---------------- | ------------------------------- | --------------------------------------------- | -------------------------------------------------------------------------------- |
77
+ | `smtp.host` | `string` | `SMTP_HOST` | SMTP server hostname. Omit the whole `smtp` block to run in outbox mode. |
78
+ | `smtp.port` | `number` | `SMTP_PORT`, then `587` | SMTP server port. |
79
+ | `smtp.secure` | `boolean` | `SMTP_SECURE`, then `port === 465` | TLS-on-connect socket rather than STARTTLS. |
80
+ | `smtp.user` | `string` | `SMTP_USER` | SMTP auth username. |
81
+ | `smtp.password` | `string` | `SMTP_PASSWORD` | SMTP auth password or API key. |
82
+ | `domain` | `string` | `EMAIL_DOMAIN` | Domain the sender is derived on, as `<user-local-part>@<domain>`. |
83
+ | `from` | `string` | `EMAIL_FROM` | Optional fixed `From`. Skips per-user derivation. |
84
+ | `systemFrom` | `string` | `EMAIL_SYSTEM_FROM`, then `no-reply@<domain>` | `From` for system mail (no user in scope). |
85
+ | `senderPolicy` | `"allowlist" \| "unrestricted"` | `EMAIL_SENDER_POLICY`, then `"allowlist"` | How the sender is restricted when `allowedSenders` is empty. |
86
+ | `allowedSenders` | `string \| string[]` | `EMAIL_ALLOWED_SENDERS` | Permitted `From` patterns: exact addresses, `*@domain`, a bare `domain`, or `*`. |
87
+ | `outDir` | `string` | `EMAIL_OUTBOX_DIR`, then `<cwd>/tmp` | Directory the outbox writes HTML previews to. |
88
+ | `brand` | `EmailBrand` | dbx-tools brand | Colors, font, display name, footer, and optional logo applied to every message. |
86
89
 
87
90
  Precedence per field is explicit config, then the environment variable, then the
88
91
  built-in default.
89
92
 
90
- | Environment variable | Purpose |
91
- | ----------------------- | ------------------------------------------------------------- |
92
- | `SMTP_HOST` | SMTP server hostname. |
93
- | `SMTP_PORT` | SMTP server port. |
94
- | `SMTP_SECURE` | Force or disable a TLS-on-connect socket. |
95
- | `SMTP_USER` | SMTP auth username. |
96
- | `SMTP_PASSWORD` | SMTP auth password or API key. |
97
- | `EMAIL_DOMAIN` | Domain for the derived sender address. |
98
- | `EMAIL_FROM` | Fixed `From` address. |
99
- | `EMAIL_SENDER_POLICY` | `allowlist` (default) or `unrestricted`. |
100
- | `EMAIL_ALLOWED_SENDERS` | Comma- or whitespace-separated `From` allow-list. |
101
- | `EMAIL_OUTBOX_MODE` | Opt in to writing messages to disk when SMTP is unconfigured. |
102
- | `EMAIL_OUTBOX_DIR` | Directory for outbox previews. |
93
+ | Environment variable | Purpose |
94
+ | ----------------------- | -------------------------------------------------------------- |
95
+ | `SMTP_HOST` | SMTP server hostname. |
96
+ | `SMTP_PORT` | SMTP server port. |
97
+ | `SMTP_SECURE` | Force or disable a TLS-on-connect socket. |
98
+ | `SMTP_USER` | SMTP auth username. |
99
+ | `SMTP_PASSWORD` | SMTP auth password or API key. |
100
+ | `EMAIL_DOMAIN` | Domain for the derived sender address. |
101
+ | `EMAIL_FROM` | Optional fixed `From` address, overriding per-user derivation. |
102
+ | `EMAIL_SYSTEM_FROM` | `From` for system mail; defaults to `no-reply@<domain>`. |
103
+ | `EMAIL_SENDER_POLICY` | `allowlist` (default) or `unrestricted`. |
104
+ | `EMAIL_ALLOWED_SENDERS` | Comma- or whitespace-separated `From` allow-list. |
105
+ | `EMAIL_OUTBOX_MODE` | Opt in to writing messages to disk when SMTP is unconfigured. |
106
+ | `EMAIL_OUTBOX_DIR` | Directory for outbox previews. |
103
107
 
104
108
  The `SMTP_*` names are unprefixed because SMTP is a third-party service, not a
105
109
  Databricks resource.
@@ -127,23 +131,26 @@ tools, so every path shares one connection pool, one sender policy, and one set
127
131
  of caps. A third argument accepts an `AbortSignal` when the caller wants to stop
128
132
  waiting on SMTP.
129
133
 
130
- A fourth argument carries delivery-time options that are deliberately NOT part of
131
- the message schema - that schema is the agent tool's input, so a field added there
132
- becomes one a model can set. Today that is `trailer`, a machine-read final line
133
- for Apple's domain-bound one-time-code AutoFill:
134
+ ### Control the plain-text part
134
135
 
135
- ```ts
136
- import { autofillTrailer } from "@dbx-tools/shared-email-template";
136
+ By default both MIME alternatives are rendered from one React Email tree, so the
137
+ `text/plain` part is a rendering of the HTML - it carries the brand header and
138
+ footer, and CSS margin becomes blank lines. That is right for prose and wrong for
139
+ content something PARSES. A fourth argument replaces just that part, leaving the
140
+ branded HTML untouched:
137
141
 
142
+ ```ts
138
143
  await transport.sendEmail(message, from, undefined, {
139
- trailer: autofillTrailer("app.example.com", code),
144
+ text: `Your verification code is: ${code}\nThis code expires in 10 minutes.`,
140
145
  });
141
146
  ```
142
147
 
143
- It renders after the branded footer, since iOS honours `@<domain> #<code>` only as
144
- the message's final line - see
145
- [`@dbx-tools/shared-email-template`](../../shared/email-template) for the format
146
- and [`@dbx-tools/cli-tunnel`](../../cli/tunnel) for a gate that uses it.
148
+ The motivating case is a one-time code: client code detection reads the code out
149
+ of the prompt line, and a styled `<h2>` code renders two blank lines below the
150
+ prompt, so autofill stops being offered even though the HTML looks perfect. Keep
151
+ the same information in both parts - a text alternative that disagrees with the
152
+ HTML reads as phishing to spam filters. See
153
+ [`@dbx-tools/cli-tunnel`](../../cli/tunnel) for a gate that does this.
147
154
 
148
155
  The plugin export is equivalent and resolves the sender for you when the caller
149
156
  is a Databricks user:
@@ -239,17 +246,39 @@ caller's own local part.
239
246
  Use this route to populate a `From` dropdown in a compose UI. If no dropdown is
240
247
  shown, the server can still derive the sender from the active user and config.
241
248
 
242
- ## Derive And Restrict Senders
249
+ ## Sender Addresses
243
250
 
244
251
  ```ts
245
252
  import { config, sender } from "@dbx-tools/email";
246
253
 
247
254
  const resolved = config.resolveEmailConfig({ domain: "mail.example.com" });
255
+
256
+ // A user caused this send, so it comes from them: alice@mail.example.com
248
257
  const from = sender.resolveSenderAddress(resolved, "alice@databricks.com");
249
258
 
259
+ // Nobody did, so it is system mail: no-reply@mail.example.com
260
+ const system = sender.resolveSystemSenderAddress(resolved);
261
+
250
262
  sender.assertSenderAllowed(from, resolved.allowedSenders);
251
263
  ```
252
264
 
265
+ `domain` is the only sender setting a deployment needs. The `From` for a normal
266
+ send is the on-behalf-of user's local part re-homed on it, so a recipient can
267
+ reply to the person who caused the message. `from` overrides that with one fixed
268
+ address and is entirely optional - set it only when every message really should
269
+ come from a single mailbox.
270
+
271
+ Mail that no user asked for - a sign-in code, a password reset, an alert - is
272
+ SYSTEM mail, and a reply to it reaches nobody. It sends from
273
+ `no-reply@<domain>` instead, which is also what `resolveSenderAddress()` returns
274
+ when there is no user in scope, so a service-context send never leaks a person's
275
+ address onto machine mail. That default outranks `from` on purpose (a fixed
276
+ `from` is normally a human or team address). Name the address yourself with
277
+ `systemFrom` / `EMAIL_SYSTEM_FROM` to route those replies to a monitored
278
+ `support@`, or just to spell the local part differently. The system sender is
279
+ folded into the effective allow-list, so the deny-by-default policy never blocks
280
+ the app's own sign-in mail.
281
+
253
282
  Sender helpers support exact addresses, domain wildcards, bare domains, and `*`.
254
283
  `sender.listSenderOptions(resolved, userEmail)` produces the concrete `From`
255
284
  choices for the current user, which is what the AppKit plugin exposes to clients.
@@ -353,14 +382,16 @@ handed to SMTP. The constants and the plugin's interceptor settings live in the
353
382
  - `tool` - approval-gated `emailTool()` Mastra tool and the shared
354
383
  `SEND_EMAIL_DESCRIPTION`.
355
384
  - `transport` - shared runtime, `getEmailRuntime()`, `resetEmailRuntime()`,
356
- `verifyEmailTransport()`, `sendEmail()`, its `SendEmailOptions` (the
357
- `trailer` delivery option), and the executor slot
385
+ `verifyEmailTransport()`, `sendEmail()`, its `SendEmailOptions` (an explicit
386
+ `text/plain` alternative), and the executor slot
358
387
  (`setEmailExecutor()`, `executeWrite()`) that puts every send on AppKit's
359
388
  interceptor chain.
360
389
  - `config` - SMTP/outbox config types, sender policy, JSON schema, and
361
390
  `resolveEmailConfig()`.
362
391
  - `defaults` - execution settings for the interceptor chain and the payload caps.
363
- - `sender` - sender derivation, allow-list parsing, and sender-option listing.
392
+ - `sender` - per-user sender derivation, the do-not-reply system sender
393
+ (`resolveSystemSenderAddress()`), allow-list parsing, and sender-option
394
+ listing.
364
395
  - `emailHtml` - Node rendering adapters over the shared template:
365
396
  `renderEmailHtml()`, `renderEmailText()`, and `renderEmail()` for both MIME
366
397
  alternatives from one component tree.
package/index.ts CHANGED
@@ -13,13 +13,14 @@ export * as sender from "./src/sender.ts";
13
13
  export * as tool from "./src/tool.ts";
14
14
  export * as transport from "./src/transport.ts";
15
15
  export { DEFAULT_SMTP_PORT, IMPLICIT_TLS_SMTP_PORT, EMAIL_CONFIG_SCHEMA } from "./src/config.ts";
16
- export type { SenderPolicy, SmtpConfig, EmailPluginConfig, ResolvedSmtpConfig, ResolvedFileConfig, ResolvedEmailConfig } from "./src/config.ts";
16
+ export type { SenderPolicy, SmtpConfig, EmailPluginConfig, ResolvedSender, ResolvedSmtpConfig, ResolvedFileConfig, ResolvedEmailConfig } from "./src/config.ts";
17
17
  export { SEND_TIMEOUT_MS, VERIFY_TIMEOUT_MS, VERIFY_ATTEMPTS, MAX_ATTACHMENT_BYTES, MAX_ATTACHMENTS_TOTAL_BYTES, MAX_ATTACHMENT_COUNT, MAX_BODY_CHARS, EMAIL_SEND_SETTINGS, EMAIL_VERIFY_SETTINGS, EMAIL_SENDERS_SETTINGS } from "./src/defaults.ts";
18
18
  export type { EmailExecuteConfig, EmailExecutionSettings } from "./src/defaults.ts";
19
19
  export { escapeHtml } from "./src/email-html.ts";
20
20
  export type { EmailHtmlOptions } from "./src/email-html.ts";
21
21
  export { normalizeMarkdown } from "./src/markdown.ts";
22
22
  export { EmailPlugin, email } from "./src/plugin.ts";
23
+ export { SYSTEM_SENDER_LOCAL_PART } from "./src/sender.ts";
23
24
  export { SEND_EMAIL_DESCRIPTION } from "./src/tool.ts";
24
25
  export type { EmailToolOptions } from "./src/tool.ts";
25
26
  export type { EmailExecutor, EmailRuntime, SendEmailOptions } from "./src/transport.ts";
package/lib/index.d.ts CHANGED
@@ -9,13 +9,14 @@ export * as sender from "./src/sender.ts";
9
9
  export * as tool from "./src/tool.ts";
10
10
  export * as transport from "./src/transport.ts";
11
11
  export { DEFAULT_SMTP_PORT, IMPLICIT_TLS_SMTP_PORT, EMAIL_CONFIG_SCHEMA } from "./src/config.ts";
12
- export type { SenderPolicy, SmtpConfig, EmailPluginConfig, ResolvedSmtpConfig, ResolvedFileConfig, ResolvedEmailConfig } from "./src/config.ts";
12
+ export type { SenderPolicy, SmtpConfig, EmailPluginConfig, ResolvedSender, ResolvedSmtpConfig, ResolvedFileConfig, ResolvedEmailConfig } from "./src/config.ts";
13
13
  export { SEND_TIMEOUT_MS, VERIFY_TIMEOUT_MS, VERIFY_ATTEMPTS, MAX_ATTACHMENT_BYTES, MAX_ATTACHMENTS_TOTAL_BYTES, MAX_ATTACHMENT_COUNT, MAX_BODY_CHARS, EMAIL_SEND_SETTINGS, EMAIL_VERIFY_SETTINGS, EMAIL_SENDERS_SETTINGS } from "./src/defaults.ts";
14
14
  export type { EmailExecuteConfig, EmailExecutionSettings } from "./src/defaults.ts";
15
15
  export { escapeHtml } from "./src/email-html.ts";
16
16
  export type { EmailHtmlOptions } from "./src/email-html.ts";
17
17
  export { normalizeMarkdown } from "./src/markdown.ts";
18
18
  export { EmailPlugin, email } from "./src/plugin.ts";
19
+ export { SYSTEM_SENDER_LOCAL_PART } from "./src/sender.ts";
19
20
  export { SEND_EMAIL_DESCRIPTION } from "./src/tool.ts";
20
21
  export type { EmailToolOptions } from "./src/tool.ts";
21
22
  export type { EmailExecutor, EmailRuntime, SendEmailOptions } from "./src/transport.ts";
package/lib/index.js CHANGED
@@ -16,5 +16,6 @@ export { SEND_TIMEOUT_MS, VERIFY_TIMEOUT_MS, VERIFY_ATTEMPTS, MAX_ATTACHMENT_BYT
16
16
  export { escapeHtml } from "./src/email-html.js";
17
17
  export { normalizeMarkdown } from "./src/markdown.js";
18
18
  export { EmailPlugin, email } from "./src/plugin.js";
19
+ export { SYSTEM_SENDER_LOCAL_PART } from "./src/sender.js";
19
20
  export { SEND_EMAIL_DESCRIPTION } from "./src/tool.js";
20
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxPQUFPLEtBQUssS0FBSyxNQUFNLGdCQUFnQixDQUFDO0FBQ3hDLE9BQU8sS0FBSyxNQUFNLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxLQUFLLFFBQVEsTUFBTSxtQkFBbUIsQ0FBQztBQUM5QyxPQUFPLEtBQUssU0FBUyxNQUFNLHFCQUFxQixDQUFDO0FBQ2pELE9BQU8sS0FBSyxRQUFRLE1BQU0sbUJBQW1CLENBQUM7QUFDOUMsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssTUFBTSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxNQUFNLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxLQUFLLElBQUksTUFBTSxlQUFlLENBQUM7QUFDdEMsT0FBTyxLQUFLLFNBQVMsTUFBTSxvQkFBb0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsc0JBQXNCLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUVqRyxPQUFPLEVBQUUsZUFBZSxFQUFFLGlCQUFpQixFQUFFLGVBQWUsRUFBRSxvQkFBb0IsRUFBRSwyQkFBMkIsRUFBRSxvQkFBb0IsRUFBRSxjQUFjLEVBQUUsbUJBQW1CLEVBQUUscUJBQXFCLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUVyUCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFakQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDdEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxlQUFlLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBHRU5FUkFURUQgYnkgcHJvamVuIHdhdGNoIC0gRE8gTk9UIEVESVQuXG4vLyBSZWdlbmVyYXRlZCBmcm9tIHRoZSBleHBvcnRpbmcgbW9kdWxlcyBpbiAuL3NyYy5cbi8vIEhhbmQgZWRpdHMgYXJlIG92ZXJ3cml0dGVuIG9uIHRoZSBuZXh0IHdhdGNoOyB0aGlzIGZpbGUgaXMgcmVhZC1vbmx5LlxuXG5leHBvcnQgKiBhcyBicmFuZCBmcm9tIFwiLi9zcmMvYnJhbmQudHNcIjtcbmV4cG9ydCAqIGFzIGNvbmZpZyBmcm9tIFwiLi9zcmMvY29uZmlnLnRzXCI7XG5leHBvcnQgKiBhcyBkZWZhdWx0cyBmcm9tIFwiLi9zcmMvZGVmYXVsdHMudHNcIjtcbmV4cG9ydCAqIGFzIGVtYWlsSHRtbCBmcm9tIFwiLi9zcmMvZW1haWwtaHRtbC50c1wiO1xuZXhwb3J0ICogYXMgbWFya2Rvd24gZnJvbSBcIi4vc3JjL21hcmtkb3duLnRzXCI7XG5leHBvcnQgKiBhcyBvdXRib3ggZnJvbSBcIi4vc3JjL291dGJveC50c1wiO1xuZXhwb3J0ICogYXMgcGx1Z2luIGZyb20gXCIuL3NyYy9wbHVnaW4udHNcIjtcbmV4cG9ydCAqIGFzIHNlbmRlciBmcm9tIFwiLi9zcmMvc2VuZGVyLnRzXCI7XG5leHBvcnQgKiBhcyB0b29sIGZyb20gXCIuL3NyYy90b29sLnRzXCI7XG5leHBvcnQgKiBhcyB0cmFuc3BvcnQgZnJvbSBcIi4vc3JjL3RyYW5zcG9ydC50c1wiO1xuZXhwb3J0IHsgREVGQVVMVF9TTVRQX1BPUlQsIElNUExJQ0lUX1RMU19TTVRQX1BPUlQsIEVNQUlMX0NPTkZJR19TQ0hFTUEgfSBmcm9tIFwiLi9zcmMvY29uZmlnLnRzXCI7XG5leHBvcnQgdHlwZSB7IFNlbmRlclBvbGljeSwgU210cENvbmZpZywgRW1haWxQbHVnaW5Db25maWcsIFJlc29sdmVkU210cENvbmZpZywgUmVzb2x2ZWRGaWxlQ29uZmlnLCBSZXNvbHZlZEVtYWlsQ29uZmlnIH0gZnJvbSBcIi4vc3JjL2NvbmZpZy50c1wiO1xuZXhwb3J0IHsgU0VORF9USU1FT1VUX01TLCBWRVJJRllfVElNRU9VVF9NUywgVkVSSUZZX0FUVEVNUFRTLCBNQVhfQVRUQUNITUVOVF9CWVRFUywgTUFYX0FUVEFDSE1FTlRTX1RPVEFMX0JZVEVTLCBNQVhfQVRUQUNITUVOVF9DT1VOVCwgTUFYX0JPRFlfQ0hBUlMsIEVNQUlMX1NFTkRfU0VUVElOR1MsIEVNQUlMX1ZFUklGWV9TRVRUSU5HUywgRU1BSUxfU0VOREVSU19TRVRUSU5HUyB9IGZyb20gXCIuL3NyYy9kZWZhdWx0cy50c1wiO1xuZXhwb3J0IHR5cGUgeyBFbWFpbEV4ZWN1dGVDb25maWcsIEVtYWlsRXhlY3V0aW9uU2V0dGluZ3MgfSBmcm9tIFwiLi9zcmMvZGVmYXVsdHMudHNcIjtcbmV4cG9ydCB7IGVzY2FwZUh0bWwgfSBmcm9tIFwiLi9zcmMvZW1haWwtaHRtbC50c1wiO1xuZXhwb3J0IHR5cGUgeyBFbWFpbEh0bWxPcHRpb25zIH0gZnJvbSBcIi4vc3JjL2VtYWlsLWh0bWwudHNcIjtcbmV4cG9ydCB7IG5vcm1hbGl6ZU1hcmtkb3duIH0gZnJvbSBcIi4vc3JjL21hcmtkb3duLnRzXCI7XG5leHBvcnQgeyBFbWFpbFBsdWdpbiwgZW1haWwgfSBmcm9tIFwiLi9zcmMvcGx1Z2luLnRzXCI7XG5leHBvcnQgeyBTRU5EX0VNQUlMX0RFU0NSSVBUSU9OIH0gZnJvbSBcIi4vc3JjL3Rvb2wudHNcIjtcbmV4cG9ydCB0eXBlIHsgRW1haWxUb29sT3B0aW9ucyB9IGZyb20gXCIuL3NyYy90b29sLnRzXCI7XG5leHBvcnQgdHlwZSB7IEVtYWlsRXhlY3V0b3IsIEVtYWlsUnVudGltZSwgU2VuZEVtYWlsT3B0aW9ucyB9IGZyb20gXCIuL3NyYy90cmFuc3BvcnQudHNcIjtcbiJdfQ==
21
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxPQUFPLEtBQUssS0FBSyxNQUFNLGdCQUFnQixDQUFDO0FBQ3hDLE9BQU8sS0FBSyxNQUFNLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxLQUFLLFFBQVEsTUFBTSxtQkFBbUIsQ0FBQztBQUM5QyxPQUFPLEtBQUssU0FBUyxNQUFNLHFCQUFxQixDQUFDO0FBQ2pELE9BQU8sS0FBSyxRQUFRLE1BQU0sbUJBQW1CLENBQUM7QUFDOUMsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssTUFBTSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxNQUFNLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxLQUFLLElBQUksTUFBTSxlQUFlLENBQUM7QUFDdEMsT0FBTyxLQUFLLFNBQVMsTUFBTSxvQkFBb0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsc0JBQXNCLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUVqRyxPQUFPLEVBQUUsZUFBZSxFQUFFLGlCQUFpQixFQUFFLGVBQWUsRUFBRSxvQkFBb0IsRUFBRSwyQkFBMkIsRUFBRSxvQkFBb0IsRUFBRSxjQUFjLEVBQUUsbUJBQW1CLEVBQUUscUJBQXFCLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUVyUCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFakQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDdEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxlQUFlLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBHRU5FUkFURUQgYnkgcHJvamVuIHdhdGNoIC0gRE8gTk9UIEVESVQuXG4vLyBSZWdlbmVyYXRlZCBmcm9tIHRoZSBleHBvcnRpbmcgbW9kdWxlcyBpbiAuL3NyYy5cbi8vIEhhbmQgZWRpdHMgYXJlIG92ZXJ3cml0dGVuIG9uIHRoZSBuZXh0IHdhdGNoOyB0aGlzIGZpbGUgaXMgcmVhZC1vbmx5LlxuXG5leHBvcnQgKiBhcyBicmFuZCBmcm9tIFwiLi9zcmMvYnJhbmQudHNcIjtcbmV4cG9ydCAqIGFzIGNvbmZpZyBmcm9tIFwiLi9zcmMvY29uZmlnLnRzXCI7XG5leHBvcnQgKiBhcyBkZWZhdWx0cyBmcm9tIFwiLi9zcmMvZGVmYXVsdHMudHNcIjtcbmV4cG9ydCAqIGFzIGVtYWlsSHRtbCBmcm9tIFwiLi9zcmMvZW1haWwtaHRtbC50c1wiO1xuZXhwb3J0ICogYXMgbWFya2Rvd24gZnJvbSBcIi4vc3JjL21hcmtkb3duLnRzXCI7XG5leHBvcnQgKiBhcyBvdXRib3ggZnJvbSBcIi4vc3JjL291dGJveC50c1wiO1xuZXhwb3J0ICogYXMgcGx1Z2luIGZyb20gXCIuL3NyYy9wbHVnaW4udHNcIjtcbmV4cG9ydCAqIGFzIHNlbmRlciBmcm9tIFwiLi9zcmMvc2VuZGVyLnRzXCI7XG5leHBvcnQgKiBhcyB0b29sIGZyb20gXCIuL3NyYy90b29sLnRzXCI7XG5leHBvcnQgKiBhcyB0cmFuc3BvcnQgZnJvbSBcIi4vc3JjL3RyYW5zcG9ydC50c1wiO1xuZXhwb3J0IHsgREVGQVVMVF9TTVRQX1BPUlQsIElNUExJQ0lUX1RMU19TTVRQX1BPUlQsIEVNQUlMX0NPTkZJR19TQ0hFTUEgfSBmcm9tIFwiLi9zcmMvY29uZmlnLnRzXCI7XG5leHBvcnQgdHlwZSB7IFNlbmRlclBvbGljeSwgU210cENvbmZpZywgRW1haWxQbHVnaW5Db25maWcsIFJlc29sdmVkU2VuZGVyLCBSZXNvbHZlZFNtdHBDb25maWcsIFJlc29sdmVkRmlsZUNvbmZpZywgUmVzb2x2ZWRFbWFpbENvbmZpZyB9IGZyb20gXCIuL3NyYy9jb25maWcudHNcIjtcbmV4cG9ydCB7IFNFTkRfVElNRU9VVF9NUywgVkVSSUZZX1RJTUVPVVRfTVMsIFZFUklGWV9BVFRFTVBUUywgTUFYX0FUVEFDSE1FTlRfQllURVMsIE1BWF9BVFRBQ0hNRU5UU19UT1RBTF9CWVRFUywgTUFYX0FUVEFDSE1FTlRfQ09VTlQsIE1BWF9CT0RZX0NIQVJTLCBFTUFJTF9TRU5EX1NFVFRJTkdTLCBFTUFJTF9WRVJJRllfU0VUVElOR1MsIEVNQUlMX1NFTkRFUlNfU0VUVElOR1MgfSBmcm9tIFwiLi9zcmMvZGVmYXVsdHMudHNcIjtcbmV4cG9ydCB0eXBlIHsgRW1haWxFeGVjdXRlQ29uZmlnLCBFbWFpbEV4ZWN1dGlvblNldHRpbmdzIH0gZnJvbSBcIi4vc3JjL2RlZmF1bHRzLnRzXCI7XG5leHBvcnQgeyBlc2NhcGVIdG1sIH0gZnJvbSBcIi4vc3JjL2VtYWlsLWh0bWwudHNcIjtcbmV4cG9ydCB0eXBlIHsgRW1haWxIdG1sT3B0aW9ucyB9IGZyb20gXCIuL3NyYy9lbWFpbC1odG1sLnRzXCI7XG5leHBvcnQgeyBub3JtYWxpemVNYXJrZG93biB9IGZyb20gXCIuL3NyYy9tYXJrZG93bi50c1wiO1xuZXhwb3J0IHsgRW1haWxQbHVnaW4sIGVtYWlsIH0gZnJvbSBcIi4vc3JjL3BsdWdpbi50c1wiO1xuZXhwb3J0IHsgU1lTVEVNX1NFTkRFUl9MT0NBTF9QQVJUIH0gZnJvbSBcIi4vc3JjL3NlbmRlci50c1wiO1xuZXhwb3J0IHsgU0VORF9FTUFJTF9ERVNDUklQVElPTiB9IGZyb20gXCIuL3NyYy90b29sLnRzXCI7XG5leHBvcnQgdHlwZSB7IEVtYWlsVG9vbE9wdGlvbnMgfSBmcm9tIFwiLi9zcmMvdG9vbC50c1wiO1xuZXhwb3J0IHR5cGUgeyBFbWFpbEV4ZWN1dG9yLCBFbWFpbFJ1bnRpbWUsIFNlbmRFbWFpbE9wdGlvbnMgfSBmcm9tIFwiLi9zcmMvdHJhbnNwb3J0LnRzXCI7XG4iXX0=
@@ -47,10 +47,24 @@ export interface EmailPluginConfig extends BasePluginConfig {
47
47
  */
48
48
  domain?: string;
49
49
  /**
50
- * Explicit `From` address. When set, the sender is used verbatim and
51
- * the per-user derivation is skipped. Falls back to `EMAIL_FROM`.
50
+ * Explicit `From` address, OPTIONAL. When set, the sender is used verbatim
51
+ * and the per-user derivation is skipped. Falls back to `EMAIL_FROM`.
52
+ *
53
+ * Leave it unset in most deployments: {@link domain} alone is enough, and
54
+ * mail then comes from the address of the person who caused it, which is what
55
+ * a recipient expects to be able to reply to.
52
56
  */
53
57
  from?: string;
58
+ /**
59
+ * `From` for SYSTEM mail - a send with no on-behalf-of user, such as a
60
+ * sign-in code or a password reset. Falls back to `EMAIL_SYSTEM_FROM`, then
61
+ * to `no-reply@<domain>`, then to {@link from}.
62
+ *
63
+ * Machine mail gets a do-not-reply address by default because a reply to it
64
+ * reaches nobody. Set this to route those replies somewhere real (a monitored
65
+ * `support@`) or to spell the local part differently (`donotreply@`).
66
+ */
67
+ systemFrom?: string;
54
68
  /**
55
69
  * Directory for the file/outbox fallback. Falls back to
56
70
  * `EMAIL_OUTBOX_DIR`, then `<cwd>/tmp`. Only used when SMTP
@@ -82,11 +96,16 @@ export interface EmailPluginConfig extends BasePluginConfig {
82
96
  brand?: EmailBrand;
83
97
  }
84
98
  /** Config shared by both resolved modes. */
85
- interface ResolvedSender {
99
+ export interface ResolvedSender {
86
100
  /** Sender domain; present whenever {@link from} is absent. */
87
101
  domain?: string;
88
102
  /** Explicit sender override; present skips per-user derivation. */
89
103
  from?: string;
104
+ /**
105
+ * Explicit do-not-reply sender for system mail. Absent means it is derived -
106
+ * see {@link systemSenderAddress}.
107
+ */
108
+ systemFrom?: string;
90
109
  /**
91
110
  * Effective sender allow-list: the configured patterns when any were
92
111
  * given, else the patterns implied by the sender source under an
@@ -124,8 +143,9 @@ export declare const EMAIL_CONFIG_SCHEMA: JSONSchema7;
124
143
  * Resolve plugin config over environment defaults.
125
144
  *
126
145
  * When SMTP host + user + password are all present, returns `mode:
127
- * "smtp"` for real delivery (and throws if no sender source - domain or
128
- * from - is configured, since SMTP can't derive one from nothing).
146
+ * "smtp"` for real delivery (and throws if no sender source - domain,
147
+ * from, or systemFrom - is configured, since SMTP can't derive one from
148
+ * nothing; `domain` alone is the intended minimum).
129
149
  * When all three are absent and `EMAIL_OUTBOX_MODE` is enabled, returns
130
150
  * `mode: "file"` so the runtime writes messages to the outbox directory
131
151
  * for local testing; in that mode a sender source is optional (the
@@ -139,4 +159,3 @@ export declare const EMAIL_CONFIG_SCHEMA: JSONSchema7;
139
159
  * any other domain. See {@link SenderPolicy}.
140
160
  */
141
161
  export declare function resolveEmailConfig(config?: EmailPluginConfig): ResolvedEmailConfig;
142
- export {};
package/lib/src/config.js CHANGED
@@ -18,6 +18,7 @@
18
18
  * to a single SMTP server (e.g. SMTP2GO): `SMTP_HOST`, `SMTP_PORT`,
19
19
  * `SMTP_SECURE`, `SMTP_USER`, `SMTP_PASSWORD`, plus `EMAIL_DOMAIN` for
20
20
  * the derived sender's domain, `EMAIL_FROM` for an explicit override,
21
+ * `EMAIL_SYSTEM_FROM` for the do-not-reply address system mail sends from,
21
22
  * `EMAIL_SENDER_POLICY` for the sender restriction mode, and
22
23
  * `EMAIL_OUTBOX_DIR` for the outbox directory.
23
24
  *
@@ -27,7 +28,7 @@ import { resolve } from "node:path";
27
28
  import { ConfigurationError, ValidationError } from "@databricks/appkit";
28
29
  import { env, object } from "@dbx-tools/shared-core";
29
30
  import { defaultEmailBrand } from "./brand.js";
30
- import { parseAllowedSenders } from "./sender.js";
31
+ import { isSenderAllowed, parseAllowedSenders, systemSenderAddress } from "./sender.js";
31
32
  /** SMTP submission port used when none is configured. */
32
33
  export const DEFAULT_SMTP_PORT = 587;
33
34
  /** SMTP port that implies a TLS-on-connect socket rather than STARTTLS. */
@@ -62,7 +63,11 @@ export const EMAIL_CONFIG_SCHEMA = {
62
63
  },
63
64
  from: {
64
65
  type: "string",
65
- description: "Explicit From address; skips per-user derivation. Falls back to EMAIL_FROM.",
66
+ description: "Optional explicit From address; skips per-user derivation. Falls back to EMAIL_FROM.",
67
+ },
68
+ systemFrom: {
69
+ type: "string",
70
+ description: "From for system mail (no on-behalf-of user, e.g. a sign-in code). Falls back to EMAIL_SYSTEM_FROM, then no-reply@<domain>, then from.",
66
71
  },
67
72
  outDir: {
68
73
  type: "string",
@@ -134,12 +139,20 @@ function resolveSenderPolicy(policy) {
134
139
  * which only happens in outbox mode (where the sender falls back to the
135
140
  * on-behalf-of user's own address and cannot be enumerated up front).
136
141
  */
137
- function impliedSenderPatterns(domain, from) {
142
+ function impliedSenderPatterns(sender) {
138
143
  const patterns = [];
139
- if (from)
140
- patterns.push(from.trim().toLowerCase());
141
- if (domain)
142
- patterns.push(`*@${domain.trim().toLowerCase()}`);
144
+ if (sender.from)
145
+ patterns.push(sender.from.trim().toLowerCase());
146
+ if (sender.domain)
147
+ patterns.push(`*@${sender.domain.trim().toLowerCase()}`);
148
+ // The system sender too, when the patterns above do not already cover it: it
149
+ // is an address this app SENDS from, so a list derived from the sender source
150
+ // has to permit it, or the very policy meant to describe the app's own senders
151
+ // denies its sign-in mail. Usually redundant (`*@domain` already matches
152
+ // `no-reply@domain`) - it matters for a `systemFrom` on another domain.
153
+ const system = systemSenderAddress(sender)?.toLowerCase();
154
+ if (system && !isSenderAllowed(system, patterns))
155
+ patterns.push(system);
143
156
  return patterns;
144
157
  }
145
158
  /** Whether `EMAIL_OUTBOX_MODE` explicitly opts into the file/outbox fallback. */
@@ -156,8 +169,9 @@ function missingSmtpFields(host, user, pass) {
156
169
  * Resolve plugin config over environment defaults.
157
170
  *
158
171
  * When SMTP host + user + password are all present, returns `mode:
159
- * "smtp"` for real delivery (and throws if no sender source - domain or
160
- * from - is configured, since SMTP can't derive one from nothing).
172
+ * "smtp"` for real delivery (and throws if no sender source - domain,
173
+ * from, or systemFrom - is configured, since SMTP can't derive one from
174
+ * nothing; `domain` alone is the intended minimum).
161
175
  * When all three are absent and `EMAIL_OUTBOX_MODE` is enabled, returns
162
176
  * `mode: "file"` so the runtime writes messages to the outbox directory
163
177
  * for local testing; in that mode a sender source is optional (the
@@ -177,14 +191,16 @@ export function resolveEmailConfig(config = {}) {
177
191
  const pass = env.string(smtp.password, "SMTP_PASSWORD") ?? undefined;
178
192
  const domain = env.string(config.domain, "EMAIL_DOMAIN") ?? undefined;
179
193
  const from = env.string(config.from, "EMAIL_FROM") ?? undefined;
194
+ const systemFrom = env.string(config.systemFrom, "EMAIL_SYSTEM_FROM") ?? undefined;
180
195
  const senderPolicy = resolveSenderPolicy(config.senderPolicy);
181
196
  const configuredSenders = parseAllowedSenders(config.allowedSenders ?? env.text("EMAIL_ALLOWED_SENDERS") ?? undefined);
182
197
  const allowedSenders = configuredSenders.length > 0 || senderPolicy === "unrestricted"
183
198
  ? configuredSenders
184
- : impliedSenderPatterns(domain, from);
199
+ : impliedSenderPatterns({ domain, from, systemFrom });
185
200
  const sender = {
186
201
  ...object.optional("domain", domain),
187
202
  ...object.optional("from", from),
203
+ ...object.optional("systemFrom", systemFrom),
188
204
  allowedSenders,
189
205
  senderPolicy,
190
206
  brand: config.brand ?? defaultEmailBrand,
@@ -195,8 +211,8 @@ export function resolveEmailConfig(config = {}) {
195
211
  throw ValidationError.missingEnvVars(missingSmtpFields(host, user, pass));
196
212
  }
197
213
  if (hasAllSmtp) {
198
- if (!domain && !from) {
199
- throw ConfigurationError.resourceNotFound("Email sender source", "Set EMAIL_DOMAIN to derive <user-local-part>@<domain>, or EMAIL_FROM for a fixed address.");
214
+ if (!domain && !from && !systemFrom) {
215
+ throw ConfigurationError.resourceNotFound("Email sender source", "Set EMAIL_DOMAIN to derive <user-local-part>@<domain> (and no-reply@<domain> for system mail), or EMAIL_FROM for a fixed address.");
200
216
  }
201
217
  const port = env.positiveInt(smtp.port, "SMTP_PORT", DEFAULT_SMTP_PORT);
202
218
  return {
@@ -214,4 +230,4 @@ export function resolveEmailConfig(config = {}) {
214
230
  const outDir = resolve(env.string(config.outDir, "EMAIL_OUTBOX_DIR") ?? resolve(process.cwd(), "tmp"));
215
231
  return { mode: "file", outDir, ...sender };
216
232
  }
217
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBd0JHO0FBQ0gsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNwQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsZUFBZSxFQUF5QixNQUFNLG9CQUFvQixDQUFDO0FBQ2hHLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFckQsT0FBTyxFQUFFLGlCQUFpQixFQUFtQixNQUFNLFlBQVksQ0FBQztBQUNoRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFbEQseURBQXlEO0FBQ3pELE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHLEdBQUcsQ0FBQztBQUVyQywyRUFBMkU7QUFDM0UsTUFBTSxDQUFDLE1BQU0sc0JBQXNCLEdBQUcsR0FBRyxDQUFDO0FBdUgxQywrREFBK0Q7QUFDL0QsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQWdCO0lBQzlDLElBQUksRUFBRSxRQUFRO0lBQ2QsVUFBVSxFQUFFO1FBQ1YsSUFBSSxFQUFFO1lBQ0osSUFBSSxFQUFFLFFBQVE7WUFDZCxXQUFXLEVBQUUsMERBQTBEO1lBQ3ZFLFVBQVUsRUFBRTtnQkFDVixJQUFJLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxtQ0FBbUMsRUFBRTtnQkFDMUUsSUFBSSxFQUFFO29CQUNKLElBQUksRUFBRSxRQUFRO29CQUNkLFdBQVcsRUFBRSw2Q0FBNkMsaUJBQWlCLEdBQUc7aUJBQy9FO2dCQUNELE1BQU0sRUFBRTtvQkFDTixJQUFJLEVBQUUsU0FBUztvQkFDZixXQUFXLEVBQUUsNkRBQTZELHNCQUFzQixHQUFHO2lCQUNwRztnQkFDRCxJQUFJLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFB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RUFBdUUsQ0FDOUcsQ0FBQztJQUNKLENBQUM7SUFFRCxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQ3BCLEdBQUcsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxrQkFBa0IsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQy9FLENBQUM7SUFDRixPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxNQUFNLEVBQUUsQ0FBQztBQUM3QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBTTVRQIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBlbWFpbCBwbHVnaW46IHRoZSB0eXBlZFxuICoge0BsaW5rIEVtYWlsUGx1Z2luQ29uZmlnfSAodGhlIHBsdWdpbidzIHNsaWNlIG9mIEFwcEtpdCBjb25maWcpLCB0aGVcbiAqIEpTT04gU2NoZW1hIHRoZSBtYW5pZmVzdCBwdWJsaXNoZXMgZm9yIGl0LCBhbmQge0BsaW5rIHJlc29sdmVFbWFpbENvbmZpZ31cbiAqIHdoaWNoIGxheWVycyB0aGF0IGNvbmZpZyBvdmVyIGVudmlyb25tZW50IGRlZmF1bHRzIGludG8gdGhlIGNvbmNyZXRlXG4gKiB7QGxpbmsgUmVzb2x2ZWRFbWFpbENvbmZpZ30gdGhlIHJ1bnRpbWUgbmVlZHMuXG4gKlxuICogVHdvIG1vZGVzIGZhbGwgb3V0IG9mIHRoZSByZXNvbHV0aW9uLiBXaGVuIFNNVFAgY3JlZGVudGlhbHMgKGhvc3QgK1xuICogdXNlciArIHBhc3N3b3JkKSBhcmUgYWxsIHByZXNlbnQgaXQgcmVzb2x2ZXMgdG8gYG1vZGU6IFwic210cFwiYCBhbmRcbiAqIG1haWwgaXMgc2VudCBmb3IgcmVhbC4gV2hlbiB0aGV5IGFyZSBhYnNlbnQgYW5kIGBFTUFJTF9PVVRCT1hfTU9ERWBcbiAqIGlzIGV4cGxpY2l0bHkgZW5hYmxlZCBpdCByZXNvbHZlcyB0byBgbW9kZTogXCJmaWxlXCJgIChhbiBcIm91dGJveFwiKVxuICogYW5kIGVhY2ggbWVzc2FnZSBpcyB3cml0dGVuIHRvIGRpc2sgYXMgSFRNTCBpbnN0ZWFkIG9mIHNlbnQuIEFueVxuICogcGFydGlhbCBTTVRQIGNvbmZpZ3VyYXRpb24gb3IgYSBzZW5kIGF0dGVtcHQgd2l0aCBubyBjcmVkZW50aWFscyBhbmRcbiAqIG5vIG91dGJveCBvcHQtaW4gdGhyb3dzLlxuICpcbiAqIFByZWNlZGVuY2UgcGVyIGZpZWxkOiBleHBsaWNpdCBwbHVnaW4gY29uZmlnIHdpbnMsIHRoZW4gdGhlIG1hdGNoaW5nXG4gKiBlbnZpcm9ubWVudCB2YXJpYWJsZS4gRW52IG5hbWVzIGFyZSB1bnByZWZpeGVkIGJlY2F1c2UgdGhlIGFwcCB0YWxrc1xuICogdG8gYSBzaW5nbGUgU01UUCBzZXJ2ZXIgKGUuZy4gU01UUDJHTyk6IGBTTVRQX0hPU1RgLCBgU01UUF9QT1JUYCxcbiAqIGBTTVRQX1NFQ1VSRWAsIGBTTVRQX1VTRVJgLCBgU01UUF9QQVNTV09SRGAsIHBsdXMgYEVNQUlMX0RPTUFJTmAgZm9yXG4gKiB0aGUgZGVyaXZlZCBzZW5kZXIncyBkb21haW4sIGBFTUFJTF9GUk9NYCBmb3IgYW4gZXhwbGljaXQgb3ZlcnJpZGUsXG4gKiBgRU1BSUxfU0VOREVSX1BPTElDWWAgZm9yIHRoZSBzZW5kZXIgcmVzdHJpY3Rpb24gbW9kZSwgYW5kXG4gKiBgRU1BSUxfT1VUQk9YX0RJUmAgZm9yIHRoZSBvdXRib3ggZGlyZWN0b3J5LlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuaW1wb3J0IHsgcmVzb2x2ZSB9IGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IENvbmZpZ3VyYXRpb25FcnJvciwgVmFsaWRhdGlvbkVycm9yLCB0eXBlIEJhc2VQbHVnaW5Db25maWcgfSBmcm9tIFwiQGRhdGFicmlja3MvYXBwa2l0XCI7XG5pbXBvcnQgeyBlbnYsIG9iamVjdCB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgdHlwZSB7IEpTT05TY2hlbWE3IH0gZnJvbSBcImpzb24tc2NoZW1hXCI7XG5pbXBvcnQgeyBkZWZhdWx0RW1haWxCcmFuZCwgdHlwZSBFbWFpbEJyYW5kIH0gZnJvbSBcIi4vYnJhbmQudHNcIjtcbmltcG9ydCB7IHBhcnNlQWxsb3dlZFNlbmRlcnMgfSBmcm9tIFwiLi9zZW5kZXIudHNcIjtcblxuLyoqIFNNVFAgc3VibWlzc2lvbiBwb3J0IHVzZWQgd2hlbiBub25lIGlzIGNvbmZpZ3VyZWQuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9TTVRQX1BPUlQgPSA1ODc7XG5cbi8qKiBTTVRQIHBvcnQgdGhhdCBpbXBsaWVzIGEgVExTLW9uLWNvbm5lY3Qgc29ja2V0IHJhdGhlciB0aGFuIFNUQVJUVExTLiAqL1xuZXhwb3J0IGNvbnN0IElNUExJQ0lUX1RMU19TTVRQX1BPUlQgPSA0NjU7XG5cbi8qKlxuICogSG93IHRoZSBzZW5kZXIgKGBGcm9tYCkgYWRkcmVzcyBpcyByZXN0cmljdGVkLlxuICpcbiAqIGBcImFsbG93bGlzdFwiYCBpcyB0aGUgZGVmYXVsdCBhbmQgdGhlIGRlbnktYnktZGVmYXVsdCBwb3N0dXJlOiBhIHNlbmQgaXNcbiAqIHBlcm1pdHRlZCBvbmx5IGZyb20gYW4gYWRkcmVzcyB0aGUgY29uZmlndXJhdGlvbiBuYW1lcywgZWl0aGVyIHRocm91Z2hcbiAqIHtAbGluayBFbWFpbFBsdWdpbkNvbmZpZy5hbGxvd2VkU2VuZGVyc30gb3IsIHdoZW4gdGhhdCBpcyBlbXB0eSwgdGhyb3VnaFxuICogdGhlIGNvbmZpZ3VyZWQgc2VuZGVyIHNvdXJjZSAoe0BsaW5rIEVtYWlsUGx1Z2luQ29uZmlnLmZyb219IGFzIGFuIGV4YWN0XG4gKiBhZGRyZXNzLCB7QGxpbmsgRW1haWxQbHVnaW5Db25maWcuZG9tYWlufSBhcyBhIGAqQGRvbWFpbmAgd2lsZGNhcmQpLlxuICpcbiAqIGBcInVucmVzdHJpY3RlZFwiYCBpcyB0aGUgZXhwbGljaXQgb3B0LW91dDogYW55IGBGcm9tYCBhIGNhbGxlciBzdXBwbGllcyBpc1xuICogYWNjZXB0ZWQuIE9ubHkgcmVhY2ggZm9yIGl0IHdoZW4gYW4gdXBzdHJlYW0gc3lzdGVtIGFscmVhZHkgdmV0cyB0aGVcbiAqIHNlbmRlci5cbiAqL1xuZXhwb3J0IHR5cGUgU2VuZGVyUG9saWN5ID0gXCJhbGxvd2xpc3RcIiB8IFwidW5yZXN0cmljdGVkXCI7XG5cbi8qKiBTTVRQIGNvbm5lY3Rpb24gKyBjcmVkZW50aWFscy4gQWxsIGZpZWxkcyBmYWxsIGJhY2sgdG8gZW52IHdoZW4gdW5zZXQuICovXG5leHBvcnQgaW50ZXJmYWNlIFNtdHBDb25maWcge1xuICAvKiogU01UUCBzZXJ2ZXIgaG9zdG5hbWUgKGBTTVRQX0hPU1RgKS4gKi9cbiAgaG9zdD86IHN0cmluZztcbiAgLyoqIFNNVFAgc2VydmVyIHBvcnQgKGBTTVRQX1BPUlRgKS4gRGVmYXVsdHMgdG8ge0BsaW5rIERFRkFVTFRfU01UUF9QT1JUfS4gKi9cbiAgcG9ydD86IG51bWJlcjtcbiAgLyoqXG4gICAqIFVzZSBhIFRMUy1vbi1jb25uZWN0IHNvY2tldCAoYFNNVFBfU0VDVVJFYCkuIERlZmF1bHRzIHRvXG4gICAqIGBwb3J0ID09PSBgIHtAbGluayBJTVBMSUNJVF9UTFNfU01UUF9QT1JUfS5cbiAgICovXG4gIHNlY3VyZT86IGJvb2xlYW47XG4gIC8qKiBTTVRQIGF1dGggdXNlcm5hbWUgKGBTTVRQX1VTRVJgKS4gKi9cbiAgdXNlcj86IHN0cmluZztcbiAgLyoqIFNNVFAgYXV0aCBwYXNzd29yZCAvIEFQSSBrZXkgKGBTTVRQX1BBU1NXT1JEYCkuICovXG4gIHBhc3N3b3JkPzogc3RyaW5nO1xufVxuXG4vKiogQXBwS2l0IGNvbmZpZyBhY2NlcHRlZCBieSB0aGUgZW1haWwgcGx1Z2luLiAqL1xuZXhwb3J0IGludGVyZmFjZSBFbWFpbFBsdWdpbkNvbmZpZyBleHRlbmRzIEJhc2VQbHVnaW5Db25maWcge1xuICAvKiogU01UUCBjb25uZWN0aW9uICsgY3JlZGVudGlhbHMuIE9taXQgdG8gcnVuIGluIGZpbGUvb3V0Ym94IG1vZGUuICovXG4gIHNtdHA/OiBTbXRwQ29uZmlnO1xuICAvKipcbiAgICogRG9tYWluIHVzZWQgdG8gYnVpbGQgdGhlIHNlbmRlciBhZGRyZXNzIGZyb20gdGhlIG9uLWJlaGFsZi1vZiB1c2VyXG4gICAqIChgPGxvY2FsLXBhcnQ+QDxkb21haW4+YCkuIEZhbGxzIGJhY2sgdG8gYEVNQUlMX0RPTUFJTmAuIFJlcXVpcmVkIGluXG4gICAqIFNNVFAgbW9kZSB1bmxlc3Mge0BsaW5rIGZyb219IGlzIHNldDsgb3B0aW9uYWwgaW4gZmlsZSBtb2RlICh0aGVcbiAgICogb3V0Ym94IGZhbGxzIGJhY2sgdG8gdGhlIHVzZXIncyBvd24gZW1haWwgYWRkcmVzcykuXG4gICAqL1xuICBkb21haW4/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBFeHBsaWNpdCBgRnJvbWAgYWRkcmVzcy4gV2hlbiBzZXQsIHRoZSBzZW5kZXIgaXMgdXNlZCB2ZXJiYXRpbSBhbmRcbiAgICogdGhlIHBlci11c2VyIGRlcml2YXRpb24gaXMgc2tpcHBlZC4gRmFsbHMgYmFjayB0byBgRU1BSUxfRlJPTWAuXG4gICAqL1xuICBmcm9tPzogc3RyaW5nO1xuICAvKipcbiAgICogRGlyZWN0b3J5IGZvciB0aGUgZmlsZS9vdXRib3ggZmFsbGJhY2suIEZhbGxzIGJhY2sgdG9cbiAgICogYEVNQUlMX09VVEJPWF9ESVJgLCB0aGVuIGA8Y3dkPi90bXBgLiBPbmx5IHVzZWQgd2hlbiBTTVRQXG4gICAqIGNyZWRlbnRpYWxzIGFyZSBhYnNlbnQuXG4gICAqL1xuICBvdXREaXI/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBBbGxvdy1saXN0IHJlc3RyaWN0aW5nIHRoZSBzZW5kZXIgKGBGcm9tYCkgYWRkcmVzcy4gRWFjaCBlbnRyeSBpcyBhblxuICAgKiBleGFjdCBhZGRyZXNzIChgdXNlckBkb21haW4uY29tYCksIGEgZG9tYWluIHdpbGRjYXJkIChgKkBkb21haW4uY29tYFxuICAgKiBvciB0aGUgYmFyZSBgZG9tYWluLmNvbWAsIG1hdGNoaW5nIGFueSBsb2NhbCBwYXJ0IG9uIHRoYXQgZG9tYWluKSwgb3JcbiAgICogYCpgIChhbnkpLiBBIHJlc29sdmVkIC8gY2hvc2VuIHNlbmRlciB0aGF0IG1hdGNoZXMgbm8gZW50cnkgaXNcbiAgICogcmVqZWN0ZWQgYXQgc2VuZCB0aW1lLiBBY2NlcHRzIGEgYHN0cmluZ1tdYCBvciBhIHNpbmdsZSBjb21tYS0gL1xuICAgKiB3aGl0ZXNwYWNlLXNlcGFyYXRlZCBzdHJpbmc7IGZhbGxzIGJhY2sgdG8gYEVNQUlMX0FMTE9XRURfU0VOREVSU2AuXG4gICAqIFdoZW4gZW1wdHksIHRoZSB7QGxpbmsgc2VuZGVyUG9saWN5fSBkZWNpZGVzIHdoYXQgaXMgcGVybWl0dGVkLlxuICAgKi9cbiAgYWxsb3dlZFNlbmRlcnM/OiBzdHJpbmcgfCBzdHJpbmdbXTtcbiAgLyoqXG4gICAqIEhvdyB0aGUgc2VuZGVyIGFkZHJlc3MgaXMgcmVzdHJpY3RlZCB3aGVuIHtAbGluayBhbGxvd2VkU2VuZGVyc30gaXNcbiAgICogZW1wdHkgKGBFTUFJTF9TRU5ERVJfUE9MSUNZYCkuIERlZmF1bHRzIHRvIGBcImFsbG93bGlzdFwiYCwgd2hpY2hcbiAgICogbmFycm93cyBzZW5kcyB0byB0aGUgY29uZmlndXJlZCBzZW5kZXIgc291cmNlLiBTZWVcbiAgICoge0BsaW5rIFNlbmRlclBvbGljeX0uXG4gICAqL1xuICBzZW5kZXJQb2xpY3k/OiBTZW5kZXJQb2xpY3k7XG4gIC8qKlxuICAgKiBPcHRpb25hbCBicmFuZCBzdHlsaW5nIGFwcGxpZWQgdG8gZXZlcnkgcmVuZGVyZWQgbWVzc2FnZS4gT21pdCB0byB1c2UgdGhlXG4gICAqIHJlcG9zaXRvcnkncyBkYngtdG9vbHMgYnJhbmQuIFBhc3Mge0BsaW5rIGVtYWlsQnJhbmRGcm9tQ29udGV4dH0gdG8gZGVyaXZlXG4gICAqIGEgY3VzdG9tIHZhbHVlIGZyb20gYSBzaGFyZWQgYEJyYW5kQ29udGV4dGAuXG4gICAqL1xuICBicmFuZD86IEVtYWlsQnJhbmQ7XG59XG5cbi8qKiBDb25maWcgc2hhcmVkIGJ5IGJvdGggcmVzb2x2ZWQgbW9kZXMuICovXG5pbnRlcmZhY2UgUmVzb2x2ZWRTZW5kZXIge1xuICAvKiogU2VuZGVyIGRvbWFpbjsgcHJlc2VudCB3aGVuZXZlciB7QGxpbmsgZnJvbX0gaXMgYWJzZW50LiAqL1xuICBkb21haW4/OiBzdHJpbmc7XG4gIC8qKiBFeHBsaWNpdCBzZW5kZXIgb3ZlcnJpZGU7IHByZXNlbnQgc2tpcHMgcGVyLXVzZXIgZGVyaXZhdGlvbi4gKi9cbiAgZnJvbT86IHN0cmluZztcbiAgLyoqXG4gICAqIEVmZmVjdGl2ZSBzZW5kZXIgYWxsb3ctbGlzdDogdGhlIGNvbmZpZ3VyZWQgcGF0dGVybnMgd2hlbiBhbnkgd2VyZVxuICAgKiBnaXZlbiwgZWxzZSB0aGUgcGF0dGVybnMgaW1wbGllZCBieSB0aGUgc2VuZGVyIHNvdXJjZSB1bmRlciBhblxuICAgKiBgXCJhbGxvd2xpc3RcImAgcG9saWN5LiBFbXB0eSBtZWFucyB1bmVuZm9yY2VhYmxlIChhbiBgXCJ1bnJlc3RyaWN0ZWRcImBcbiAgICogcG9saWN5LCBvciBhbiBvdXRib3ggd2l0aCBubyBzZW5kZXIgc291cmNlIHRvIG5hcnJvdyB0bykuXG4gICAqL1xuICBhbGxvd2VkU2VuZGVyczogc3RyaW5nW107XG4gIC8qKiBUaGUgcmVzdHJpY3Rpb24gbW9kZSB0aGUgYWxsb3ctbGlzdCB3YXMgcmVzb2x2ZWQgdW5kZXIuICovXG4gIHNlbmRlclBvbGljeTogU2VuZGVyUG9saWN5O1xuICAvKiogQnJhbmQgc3R5bGluZyBhcHBsaWVkIHRvIHJlbmRlcmVkIEhUTUwuICovXG4gIGJyYW5kOiBFbWFpbEJyYW5kO1xufVxuXG4vKiogUmVzb2x2ZWQgY29uZmlnIGZvciByZWFsIFNNVFAgZGVsaXZlcnkuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlc29sdmVkU210cENvbmZpZyBleHRlbmRzIFJlc29sdmVkU2VuZGVyIHtcbiAgbW9kZTogXCJzbXRwXCI7XG4gIGhvc3Q6IHN0cmluZztcbiAgcG9ydDogbnVtYmVyO1xuICBzZWN1cmU6IGJvb2xlYW47XG4gIGF1dGg6IHsgdXNlcjogc3RyaW5nOyBwYXNzOiBzdHJpbmcgfTtcbn1cblxuLyoqIFJlc29sdmVkIGNvbmZpZyBmb3IgdGhlIGZpbGUvb3V0Ym94IGZhbGxiYWNrIChubyBTTVRQIGNyZWRlbnRpYWxzKS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb2x2ZWRGaWxlQ29uZmlnIGV4dGVuZHMgUmVzb2x2ZWRTZW5kZXIge1xuICBtb2RlOiBcImZpbGVcIjtcbiAgLyoqIEFic29sdXRlIGRpcmVjdG9yeSBtZXNzYWdlcyBhcmUgd3JpdHRlbiB1bmRlci4gKi9cbiAgb3V0RGlyOiBzdHJpbmc7XG59XG5cbi8qKiBDb25jcmV0ZSwgdmFsaWRhdGVkIGNvbmZpZyB0aGUgcnVudGltZSBkaXNwYXRjaGVzIHRocm91Z2guICovXG5leHBvcnQgdHlwZSBSZXNvbHZlZEVtYWlsQ29uZmlnID0gUmVzb2x2ZWRTbXRwQ29uZmlnIHwgUmVzb2x2ZWRGaWxlQ29uZmlnO1xuXG4vKiogSlNPTiBTY2hlbWEgcHVibGlzaGVkIG9uIHRoZSBtYW5pZmVzdCdzIGBjb25maWcuc2NoZW1hYC4gKi9cbmV4cG9ydCBjb25zdCBFTUFJTF9DT05GSUdfU0NIRU1BOiBKU09OU2NoZW1hNyA9IHtcbiAgdHlwZTogXCJvYmplY3RcIixcbiAgcHJvcGVydGllczoge1xuICAgIHNtdHA6IHtcbiAgICAgIHR5cGU6IFwib2JqZWN0XCIsXG4gICAgICBkZXNjcmlwdGlvbjogXCJTTVRQIGNvbm5lY3Rpb24gYW5kIGNyZWRlbnRpYWxzIChlbnYgZmFsbGJhY2tzOiBTTVRQXyopLlwiLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBob3N0OiB7IHR5cGU6IFwic3RyaW5nXCIsIGRlc2NyaXB0aW9uOiBcIlNNVFAgc2VydmVyIGhvc3RuYW1lIChTTVRQX0hPU1QpLlwiIH0sXG4gICAgICAgIHBvcnQ6IHtcbiAgICAgICAgICB0eXBlOiBcIm51bWJlclwiLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiBgU01UUCBzZXJ2ZXIgcG9ydCAoU01UUF9QT1JUKS4gRGVmYXVsdHMgdG8gJHtERUZBVUxUX1NNVFBfUE9SVH0uYCxcbiAgICAgICAgfSxcbiAgICAgICAgc2VjdXJlOiB7XG4gICAgICAgICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgICAgICAgZGVzY3JpcHRpb246IGBUTFMtb24tY29ubmVjdCBzb2NrZXQgKFNNVFBfU0VDVVJFKS4gRGVmYXVsdHMgdG8gcG9ydCA9PT0gJHtJTVBMSUNJVF9UTFNfU01UUF9QT1JUfS5gLFxuICAgICAgICB9LFxuICAgICAgICB1c2VyOiB7IHR5cGU6IFwic3RyaW5nXCIsIGRlc2NyaXB0aW9uOiBcIlNNVFAgYXV0aCB1c2VybmFtZSAoU01UUF9VU0VSKS5cIiB9LFxuICAgICAgICBwYXNzd29yZDoge1xuICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgZGVzY3JpcHRpb246IFwiU01UUCBhdXRoIHBhc3N3b3JkIC8gQVBJIGtleSAoU01UUF9QQVNTV09SRCkuXCIsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gICAgZG9tYWluOiB7XG4gICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgIFwiRG9tYWluIGZvciB0aGUgZGVyaXZlZCBzZW5kZXIgYWRkcmVzcyAoPHVzZXItbG9jYWwtcGFydD5APGRvbWFpbj4pLiBGYWxscyBiYWNrIHRvIEVNQUlMX0RPTUFJTi5cIixcbiAgICB9LFxuICAgIGZyb206IHtcbiAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICBkZXNjcmlwdGlvbjogXCJFeHBsaWNpdCBGcm9tIGFkZHJlc3M7IHNraXBzIHBlci11c2VyIGRlcml2YXRpb24uIEZhbGxzIGJhY2sgdG8gRU1BSUxfRlJPTS5cIixcbiAgICB9LFxuICAgIG91dERpcjoge1xuICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICBcIkRpcmVjdG9yeSBmb3IgdGhlIGZpbGUvb3V0Ym94IGZhbGxiYWNrIHdoZW4gU01UUCBpcyB1bmNvbmZpZ3VyZWQuIEZhbGxzIGJhY2sgdG8gRU1BSUxfT1VUQk9YX0RJUiwgdGhlbiA8Y3dkPi90bXAuXCIsXG4gICAgfSxcbiAgICBhbGxvd2VkU2VuZGVyczoge1xuICAgICAgdHlwZTogXCJhcnJheVwiLFxuICAgICAgaXRlbXM6IHsgdHlwZTogXCJzdHJpbmdcIiB9LFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdBbGxvdy1saXN0IG9mIHBlcm1pdHRlZCBzZW5kZXIgKEZyb20pIHBhdHRlcm5zOiBleGFjdCBhZGRyZXNzZXMgKFwidXNlckBkb21haW4uY29tXCIpLCBkb21haW4gd2lsZGNhcmRzIChcIipAZG9tYWluLmNvbVwiKSwgb3IgXCIqXCIuIEFsc28gYWNjZXB0cyBhIGNvbW1hL3NwYWNlLXNlcGFyYXRlZCBzdHJpbmcuIEZhbGxzIGJhY2sgdG8gRU1BSUxfQUxMT1dFRF9TRU5ERVJTLiBXaGVuIGVtcHR5LCBzZW5kZXJQb2xpY3kgZGVjaWRlcy4nLFxuICAgIH0sXG4gICAgc2VuZGVyUG9saWN5OiB7XG4gICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgZW51bTogW1wiYWxsb3dsaXN0XCIsIFwidW5yZXN0cmljdGVkXCJdLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdIb3cgdGhlIHNlbmRlciBpcyByZXN0cmljdGVkIHdoZW4gYWxsb3dlZFNlbmRlcnMgaXMgZW1wdHkgKEVNQUlMX1NFTkRFUl9QT0xJQ1kpLiBcImFsbG93bGlzdFwiIChkZWZhdWx0KSBuYXJyb3dzIHNlbmRzIHRvIHRoZSBjb25maWd1cmVkIHNlbmRlciBzb3VyY2U7IFwidW5yZXN0cmljdGVkXCIgYWNjZXB0cyBhbnkgRnJvbS4nLFxuICAgIH0sXG4gICAgYnJhbmQ6IHtcbiAgICAgIHR5cGU6IFwib2JqZWN0XCIsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgXCJCcmFuZCBzdHlsaW5nIGFwcGxpZWQgdG8gZXZlcnkgUmVhY3QgRW1haWwgbWVzc2FnZS4gT21pdCB0byB1c2UgdGhlIGRieC10b29scyBicmFuZC5cIixcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgYWNjZW50OiB7XG4gICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ0hlYWRlci1iYW5kIGJhY2tncm91bmQgYW5kIGJvZHkgbGluayBjb2xvciAoZS5nLiBcIiNGRjM2MjFcIikuJyxcbiAgICAgICAgfSxcbiAgICAgICAgb25BY2NlbnQ6IHtcbiAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIlRleHQgYW5kIGxvZ28gY29sb3IgcmVuZGVyZWQgb24gdGhlIGFjY2VudCBiYW5kLiBEZWZhdWx0cyB0byB3aGl0ZS5cIixcbiAgICAgICAgfSxcbiAgICAgICAgZm9udEZhbWlseToge1xuICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdCb2R5IGZvbnQgc3RhY2sgKGUuZy4gXCJJbnRlciwgdWktc2Fucy1zZXJpZiwgc3lzdGVtLXVpLCBzYW5zLXNlcmlmXCIpLicsXG4gICAgICAgIH0sXG4gICAgICAgIG5hbWU6IHtcbiAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIlByb2R1Y3QgLyBkaXNwbGF5IG5hbWUgdXNlZCBhcyB0aGUgaGVhZGVyIHRleHQgYW5kIHRoZSBsb2dvIGFsdCB0ZXh0LlwiLFxuICAgICAgICB9LFxuICAgICAgICBsb2dvVXJsOiB7XG4gICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgIFwiTG9nbyBpbWFnZSBmb3IgdGhlIGhlYWRlciBiYW5kLiBPbmx5IGFuIGh0dHAocyk6IG9yIGRhdGE6IFVSTCByZW5kZXJzOyBvdGhlciB2YWx1ZXMgYXJlIGRyb3BwZWQgYmVjYXVzZSBhIG1haWwgY2xpZW50IGNhbm5vdCBsb2FkIHRoZW0uXCIsXG4gICAgICAgIH0sXG4gICAgICAgIGJhY2tncm91bmQ6IHsgdHlwZTogXCJzdHJpbmdcIiwgZGVzY3JpcHRpb246IFwiSW5ib3ggY2FudmFzIGNvbG9yLlwiIH0sXG4gICAgICAgIHN1cmZhY2U6IHsgdHlwZTogXCJzdHJpbmdcIiwgZGVzY3JpcHRpb246IFwiTWVzc2FnZS1jYXJkIGNvbG9yLlwiIH0sXG4gICAgICAgIGZvcmVncm91bmQ6IHsgdHlwZTogXCJzdHJpbmdcIiwgZGVzY3JpcHRpb246IFwiUHJpbWFyeSB0ZXh0IGNvbG9yLlwiIH0sXG4gICAgICAgIG11dGVkOiB7IHR5cGU6IFwic3RyaW5nXCIsIGRlc2NyaXB0aW9uOiBcIlNlY29uZGFyeSB0ZXh0IGNvbG9yLlwiIH0sXG4gICAgICAgIGJvcmRlcjogeyB0eXBlOiBcInN0cmluZ1wiLCBkZXNjcmlwdGlvbjogXCJCb3JkZXIgYW5kIGRpdmlkZXIgY29sb3IuXCIgfSxcbiAgICAgICAgdGFnbGluZTogeyB0eXBlOiBcInN0cmluZ1wiLCBkZXNjcmlwdGlvbjogXCJGb290ZXIgcHJvZHVjdCBsaW5lLlwiIH0sXG4gICAgICAgIHdlYnNpdGU6IHsgdHlwZTogXCJzdHJpbmdcIiwgZGVzY3JpcHRpb246IFwiT3B0aW9uYWwgZm9vdGVyIHdlYnNpdGUgVVJMLlwiIH0sXG4gICAgICB9LFxuICAgICAgcmVxdWlyZWQ6IFtcImFjY2VudFwiLCBcImZvbnRGYW1pbHlcIl0sXG4gICAgfSxcbiAgfSxcbn07XG5cbi8qKiBQYXJzZSB0aGUgYFNNVFBfU0VDVVJFYCBlbnYgLyBjb25maWcgZmxhZywgZGVmYXVsdGluZyBieSBwb3J0LiAqL1xuZnVuY3Rpb24gcmVzb2x2ZVNlY3VyZShmbGFnOiBib29sZWFuIHwgdW5kZWZpbmVkLCBwb3J0OiBudW1iZXIpOiBib29sZWFuIHtcbiAgcmV0dXJuIGVudi5ib29sZWFuKGZsYWcsIFwiU01UUF9TRUNVUkVcIikgPz8gcG9ydCA9PT0gSU1QTElDSVRfVExTX1NNVFBfUE9SVDtcbn1cblxuLyoqIFBhcnNlIHRoZSBgRU1BSUxfU0VOREVSX1BPTElDWWAgZW52IC8gY29uZmlnIHZhbHVlLCBkZWZhdWx0aW5nIHRvIGRlbnktYnktZGVmYXVsdC4gKi9cbmZ1bmN0aW9uIHJlc29sdmVTZW5kZXJQb2xpY3kocG9saWN5OiBTZW5kZXJQb2xpY3kgfCB1bmRlZmluZWQpOiBTZW5kZXJQb2xpY3kge1xuICBjb25zdCByYXcgPSBwb2xpY3kgPz8gZW52LnRleHQoXCJFTUFJTF9TRU5ERVJfUE9MSUNZXCIpPy50b0xvd2VyQ2FzZSgpO1xuICBpZiAocmF3ID09PSBcInVucmVzdHJpY3RlZFwiKSByZXR1cm4gXCJ1bnJlc3RyaWN0ZWRcIjtcbiAgaWYgKHJhdyA9PT0gdW5kZWZpbmVkIHx8IHJhdyA9PT0gXCJcIiB8fCByYXcgPT09IFwiYWxsb3dsaXN0XCIpIHJldHVybiBcImFsbG93bGlzdFwiO1xuICB0aHJvdyBWYWxpZGF0aW9uRXJyb3IuaW52YWxpZFZhbHVlKFwic2VuZGVyUG9saWN5XCIsIHJhdywgJ1wiYWxsb3dsaXN0XCIgb3IgXCJ1bnJlc3RyaWN0ZWRcIicpO1xufVxuXG4vKipcbiAqIEVmZmVjdGl2ZSBhbGxvdy1saXN0IGZvciBhbiBgXCJhbGxvd2xpc3RcImAgcG9saWN5IHdpdGggbm8gZXhwbGljaXQgcGF0dGVybnM6XG4gKiB0aGUgc2VuZGVyIHNvdXJjZSBpdHNlbGYsIHNvIGEgY29uZmlndXJlZCBkb21haW4gb3IgZml4ZWQgYWRkcmVzcyBpcyB0aGVcbiAqIGJvdW5kYXJ5IHJhdGhlciB0aGFuIFwiYW55dGhpbmcgZ29lc1wiLiBZaWVsZHMgbm90aGluZyB3aGVuIG5laXRoZXIgaXMgc2V0LFxuICogd2hpY2ggb25seSBoYXBwZW5zIGluIG91dGJveCBtb2RlICh3aGVyZSB0aGUgc2VuZGVyIGZhbGxzIGJhY2sgdG8gdGhlXG4gKiBvbi1iZWhhbGYtb2YgdXNlcidzIG93biBhZGRyZXNzIGFuZCBjYW5ub3QgYmUgZW51bWVyYXRlZCB1cCBmcm9udCkuXG4gKi9cbmZ1bmN0aW9uIGltcGxpZWRTZW5kZXJQYXR0ZXJucyhkb21haW46IHN0cmluZyB8IHVuZGVmaW5lZCwgZnJvbTogc3RyaW5nIHwgdW5kZWZpbmVkKTogc3RyaW5nW10ge1xuICBjb25zdCBwYXR0ZXJuczogc3RyaW5nW10gPSBbXTtcbiAgaWYgKGZyb20pIHBhdHRlcm5zLnB1c2goZnJvbS50cmltKCkudG9Mb3dlckNhc2UoKSk7XG4gIGlmIChkb21haW4pIHBhdHRlcm5zLnB1c2goYCpAJHtkb21haW4udHJpbSgpLnRvTG93ZXJDYXNlKCl9YCk7XG4gIHJldHVybiBwYXR0ZXJucztcbn1cblxuLyoqIFdoZXRoZXIgYEVNQUlMX09VVEJPWF9NT0RFYCBleHBsaWNpdGx5IG9wdHMgaW50byB0aGUgZmlsZS9vdXRib3ggZmFsbGJhY2suICovXG5mdW5jdGlvbiBpc091dGJveE1vZGVFbmFibGVkKCk6IGJvb2xlYW4ge1xuICByZXR1cm4gZW52LmJvb2xlYW4odW5kZWZpbmVkLCBcIkVNQUlMX09VVEJPWF9NT0RFXCIpID8/IGZhbHNlO1xufVxuXG5jb25zdCBTTVRQX1JFUVVJUkVEX0ZJRUxEUyA9IFtcIlNNVFBfSE9TVFwiLCBcIlNNVFBfVVNFUlwiLCBcIlNNVFBfUEFTU1dPUkRcIl0gYXMgY29uc3Q7XG5cbi8qKiBMaXN0IGVudiBrZXlzIGZvciBTTVRQIGZpZWxkcyB0aGF0IGFyZSB1bnNldCBpbiB0aGUgcmVzb2x2ZWQgY3JlZGVudGlhbCBzZXQuICovXG5mdW5jdGlvbiBtaXNzaW5nU210cEZpZWxkcyhcbiAgaG9zdDogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICB1c2VyOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gIHBhc3M6IHN0cmluZyB8IHVuZGVmaW5lZCxcbik6IHN0cmluZ1tdIHtcbiAgY29uc3QgdmFsdWVzID0gW2hvc3QsIHVzZXIsIHBhc3NdIGFzIGNvbnN0O1xuICByZXR1cm4gU01UUF9SRVFVSVJFRF9GSUVMRFMuZmlsdGVyKChfLCBpbmRleCkgPT4gIXZhbHVlc1tpbmRleF0pO1xufVxuXG4vKipcbiAqIFJlc29sdmUgcGx1Z2luIGNvbmZpZyBvdmVyIGVudmlyb25tZW50IGRlZmF1bHRzLlxuICpcbiAqIFdoZW4gU01UUCBob3N0ICsgdXNlciArIHBhc3N3b3JkIGFyZSBhbGwgcHJlc2VudCwgcmV0dXJucyBgbW9kZTpcbiAqIFwic210cFwiYCBmb3IgcmVhbCBkZWxpdmVyeSAoYW5kIHRocm93cyBpZiBubyBzZW5kZXIgc291cmNlIC0gZG9tYWluIG9yXG4gKiBmcm9tIC0gaXMgY29uZmlndXJlZCwgc2luY2UgU01UUCBjYW4ndCBkZXJpdmUgb25lIGZyb20gbm90aGluZykuXG4gKiBXaGVuIGFsbCB0aHJlZSBhcmUgYWJzZW50IGFuZCBgRU1BSUxfT1VUQk9YX01PREVgIGlzIGVuYWJsZWQsIHJldHVybnNcbiAqIGBtb2RlOiBcImZpbGVcImAgc28gdGhlIHJ1bnRpbWUgd3JpdGVzIG1lc3NhZ2VzIHRvIHRoZSBvdXRib3ggZGlyZWN0b3J5XG4gKiBmb3IgbG9jYWwgdGVzdGluZzsgaW4gdGhhdCBtb2RlIGEgc2VuZGVyIHNvdXJjZSBpcyBvcHRpb25hbCAodGhlXG4gKiBvdXRib3ggZmFsbHMgYmFjayB0byB0aGUgT0JPIHVzZXIncyBvd24gYWRkcmVzcykuIFBhcnRpYWwgU01UUFxuICogY29uZmlndXJhdGlvbiBvciBhIHNlbmQgd2l0aCBubyBjcmVkZW50aWFscyBhbmQgbm8gb3V0Ym94IG9wdC1pblxuICogdGhyb3dzLlxuICpcbiAqIFRoZSBzZW5kZXIgYWxsb3ctbGlzdCBpcyByZXNvbHZlZCBoZXJlIHRvbzogdW5kZXIgdGhlIGRlZmF1bHRcbiAqIGBcImFsbG93bGlzdFwiYCBwb2xpY3kgYW4gZW1wdHkgbGlzdCBpcyBmaWxsZWQgaW4gZnJvbSB0aGUgc2VuZGVyIHNvdXJjZSxcbiAqIHNvIGEgZGVwbG95bWVudCB0aGF0IG9ubHkgc2V0cyBgRU1BSUxfRE9NQUlOYCBzdGlsbCByZWplY3RzIGEgYEZyb21gIG9uXG4gKiBhbnkgb3RoZXIgZG9tYWluLiBTZWUge0BsaW5rIFNlbmRlclBvbGljeX0uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlRW1haWxDb25maWcoY29uZmlnOiBFbWFpbFBsdWdpbkNvbmZpZyA9IHt9KTogUmVzb2x2ZWRFbWFpbENvbmZpZyB7XG4gIGNvbnN0IHNtdHAgPSBjb25maWcuc210cCA/PyB7fTtcbiAgY29uc3QgaG9zdCA9IGVudi5zdHJpbmcoc210cC5ob3N0LCBcIlNNVFBfSE9TVFwiKSA/PyB1bmRlZmluZWQ7XG4gIGNvbnN0IHVzZXIgPSBlbnYuc3RyaW5nKHNtdHAudXNlciwgXCJTTVRQX1VTRVJcIikgPz8gdW5kZWZpbmVkO1xuICBjb25zdCBwYXNzID0gZW52LnN0cmluZyhzbXRwLnBhc3N3b3JkLCBcIlNNVFBfUEFTU1dPUkRcIikgPz8gdW5kZWZpbmVkO1xuICBjb25zdCBkb21haW4gPSBlbnYuc3RyaW5nKGNvbmZpZy5kb21haW4sIFwiRU1BSUxfRE9NQUlOXCIpID8/IHVuZGVmaW5lZDtcbiAgY29uc3QgZnJvbSA9IGVudi5zdHJpbmcoY29uZmlnLmZyb20sIFwiRU1BSUxfRlJPTVwiKSA/PyB1bmRlZmluZWQ7XG4gIGNvbnN0IHNlbmRlclBvbGljeSA9IHJlc29sdmVTZW5kZXJQb2xpY3koY29uZmlnLnNlbmRlclBvbGljeSk7XG4gIGNvbnN0IGNvbmZpZ3VyZWRTZW5kZXJzID0gcGFyc2VBbGxvd2VkU2VuZGVycyhcbiAgICBjb25maWcuYWxsb3dlZFNlbmRlcnMgPz8gZW52LnRleHQoXCJFTUFJTF9BTExPV0VEX1NFTkRFUlNcIikgPz8gdW5kZWZpbmVkLFxuICApO1xuICBjb25zdCBhbGxvd2VkU2VuZGVycyA9XG4gICAgY29uZmlndXJlZFNlbmRlcnMubGVuZ3RoID4gMCB8fCBzZW5kZXJQb2xpY3kgPT09IFwidW5yZXN0cmljdGVkXCJcbiAgICAgID8gY29uZmlndXJlZFNlbmRlcnNcbiAgICAgIDogaW1wbGllZFNlbmRlclBhdHRlcm5zKGRvbWFpbiwgZnJvbSk7XG4gIGNvbnN0IHNlbmRlcjogUmVzb2x2ZWRTZW5kZXIgPSB7XG4gICAgLi4ub2JqZWN0Lm9wdGlvbmFsKFwiZG9tYWluXCIsIGRvbWFpbiksXG4gICAgLi4ub2JqZWN0Lm9wdGlvbmFsKFwiZnJvbVwiLCBmcm9tKSxcbiAgICBhbGxvd2VkU2VuZGVycyxcbiAgICBzZW5kZXJQb2xpY3ksXG4gICAgYnJhbmQ6IGNvbmZpZy5icmFuZCA/PyBkZWZhdWx0RW1haWxCcmFuZCxcbiAgfTtcblxuICBjb25zdCBoYXNBbGxTbXRwID0gQm9vbGVhbihob3N0ICYmIHVzZXIgJiYgcGFzcyk7XG4gIGNvbnN0IGhhc0FueVNtdHAgPSBCb29sZWFuKGhvc3QgfHwgdXNlciB8fCBwYXNzKTtcblxuICBpZiAoaGFzQW55U210cCAmJiAhaGFzQWxsU210cCkge1xuICAgIHRocm93IFZhbGlkYXRpb25FcnJvci5taXNzaW5nRW52VmFycyhtaXNzaW5nU210cEZpZWxkcyhob3N0LCB1c2VyLCBwYXNzKSk7XG4gIH1cblxuICBpZiAoaGFzQWxsU210cCkge1xuICAgIGlmICghZG9tYWluICYmICFmcm9tKSB7XG4gICAgICB0aHJvdyBDb25maWd1cmF0aW9uRXJyb3IucmVzb3VyY2VOb3RGb3VuZChcbiAgICAgICAgXCJFbWFpbCBzZW5kZXIgc291cmNlXCIsXG4gICAgICAgIFwiU2V0IEVNQUlMX0RPTUFJTiB0byBkZXJpdmUgPHVzZXItbG9jYWwtcGFydD5APGRvbWFpbj4sIG9yIEVNQUlMX0ZST00gZm9yIGEgZml4ZWQgYWRkcmVzcy5cIixcbiAgICAgICk7XG4gICAgfVxuICAgIGNvbnN0IHBvcnQgPSBlbnYucG9zaXRpdmVJbnQoc210cC5wb3J0LCBcIlNNVFBfUE9SVFwiLCBERUZBVUxUX1NNVFBfUE9SVCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIG1vZGU6IFwic210cFwiLFxuICAgICAgaG9zdDogaG9zdCEsXG4gICAgICBwb3J0LFxuICAgICAgc2VjdXJlOiByZXNvbHZlU2VjdXJlKHNtdHAuc2VjdXJlLCBwb3J0KSxcbiAgICAgIGF1dGg6IHsgdXNlcjogdXNlciEsIHBhc3M6IHBhc3MhIH0sXG4gICAgICAuLi5zZW5kZXIsXG4gICAgfTtcbiAgfVxuXG4gIGlmICghaXNPdXRib3hNb2RlRW5hYmxlZCgpKSB7XG4gICAgdGhyb3cgQ29uZmlndXJhdGlvbkVycm9yLmludmFsaWRDb25uZWN0aW9uKFxuICAgICAgXCJTTVRQXCIsXG4gICAgICBgU2V0ICR7U01UUF9SRVFVSVJFRF9GSUVMRFMuam9pbihcIiwgXCIpfSwgb3IgRU1BSUxfT1VUQk9YX01PREU9MSB0byB3cml0ZSBtZXNzYWdlcyB0byBhIGxvY2FsIG91dGJveCBpbnN0ZWFkLmAsXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IG91dERpciA9IHJlc29sdmUoXG4gICAgZW52LnN0cmluZyhjb25maWcub3V0RGlyLCBcIkVNQUlMX09VVEJPWF9ESVJcIikgPz8gcmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCBcInRtcFwiKSxcbiAgKTtcbiAgcmV0dXJuIHsgbW9kZTogXCJmaWxlXCIsIG91dERpciwgLi4uc2VuZGVyIH07XG59XG4iXX0=
233
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXlCRztBQUNILE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDcEMsT0FBTyxFQUFFLGtCQUFrQixFQUFFLGVBQWUsRUFBeUIsTUFBTSxvQkFBb0IsQ0FBQztBQUNoRyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRXJELE9BQU8sRUFBRSxpQkFBaUIsRUFBbUIsTUFBTSxZQUFZLENBQUM7QUFDaEUsT0FBTyxFQUFFLGVBQWUsRUFBRSxtQkFBbUIsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUV4Rix5REFBeUQ7QUFDekQsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQUcsR0FBRyxDQUFDO0FBRXJDLDJFQUEyRTtBQUMzRSxNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBRyxHQUFHLENBQUM7QUEwSTFDLCtEQUErRDtBQUMvRCxNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBZ0I7SUFDOUMsSUFBSSxFQUFFLFFBQVE7SUFDZCxVQUFVLEVBQUU7UUFDVixJQUFJLEVBQUU7WUFDSixJQUFJLEVBQUUsUUFBUTtZQUNkLFdBQVcsRUFBRSwwREFBMEQ7WUFDdkUsVUFBVSxFQUFFO2dCQUNWLElBQUksRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFFLG1DQUFtQyxFQUFFO2dCQUMxRSxJQUFJLEVBQUU7b0JBQ0osSUFBSSxFQUFFLFFBQVE7b0JBQ2QsV0FBVyxFQUFFLDZDQUE2QyxpQkFBaUIsR0FBRztpQkFDL0U7Z0JBQ0QsTUFBTSxFQUFFO29CQUNOLElBQUksRUFBRSxTQUFTO29CQUNmLFdBQVcsRUFBRSw2REFBNkQsc0JBQXNCLEdBQUc7aUJBQ3BHO2dCQUNELElBQUks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VUFBVSxFQUFFLENBQUM7WUFDcEMsTUFBTSxrQkFBa0IsQ0FBQyxnQkFBZ0IsQ0FDdkMscUJBQXFCLEVBQ3JCLG1JQUFtSSxDQUNwSSxDQUFDO1FBQ0osQ0FBQztRQUNELE1BQU0sSUFBSSxHQUFHLEdBQUcsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxXQUFXLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztRQUN4RSxPQUFPO1lBQ0wsSUFBSSxFQUFFLE1BQU07WUFDWixJQUFJLEVBQUUsSUFBSztZQUNYLElBQUk7WUFDSixNQUFNLEVBQUUsYUFBYSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDO1lBQ3hDLElBQUksRUFBRSxFQUFFLElBQUksRUFBRSxJQUFLLEVBQUUsSUFBSSxFQUFFLElBQUssRUFBRTtZQUNsQyxHQUFHLE1BQU07U0FDVixDQUFDO0lBQ0osQ0FBQztJQUVELElBQUksQ0FBQyxtQkFBbUIsRUFBRSxFQUFFLENBQUM7UUFDM0IsTUFBTSxrQkFBa0IsQ0FBQyxpQkFBaUIsQ0FDeEMsTUFBTSxFQUNOLE9BQU8sb0JBQW9CLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyx1RUFBdUUsQ0FDOUcsQ0FBQztJQUNKLENBQUM7SUFFRCxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQ3BCLEdBQUcsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxrQkFBa0IsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQy9FLENBQUM7SUFDRixPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxNQUFNLEVBQUUsQ0FBQztBQUM3QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBTTVRQIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBlbWFpbCBwbHVnaW46IHRoZSB0eXBlZFxuICoge0BsaW5rIEVtYWlsUGx1Z2luQ29uZmlnfSAodGhlIHBsdWdpbidzIHNsaWNlIG9mIEFwcEtpdCBjb25maWcpLCB0aGVcbiAqIEpTT04gU2NoZW1hIHRoZSBtYW5pZmVzdCBwdWJsaXNoZXMgZm9yIGl0LCBhbmQge0BsaW5rIHJlc29sdmVFbWFpbENvbmZpZ31cbiAqIHdoaWNoIGxheWVycyB0aGF0IGNvbmZpZyBvdmVyIGVudmlyb25tZW50IGRlZmF1bHRzIGludG8gdGhlIGNvbmNyZXRlXG4gKiB7QGxpbmsgUmVzb2x2ZWRFbWFpbENvbmZpZ30gdGhlIHJ1bnRpbWUgbmVlZHMuXG4gKlxuICogVHdvIG1vZGVzIGZhbGwgb3V0IG9mIHRoZSByZXNvbHV0aW9uLiBXaGVuIFNNVFAgY3JlZGVudGlhbHMgKGhvc3QgK1xuICogdXNlciArIHBhc3N3b3JkKSBhcmUgYWxsIHByZXNlbnQgaXQgcmVzb2x2ZXMgdG8gYG1vZGU6IFwic210cFwiYCBhbmRcbiAqIG1haWwgaXMgc2VudCBmb3IgcmVhbC4gV2hlbiB0aGV5IGFyZSBhYnNlbnQgYW5kIGBFTUFJTF9PVVRCT1hfTU9ERWBcbiAqIGlzIGV4cGxpY2l0bHkgZW5hYmxlZCBpdCByZXNvbHZlcyB0byBgbW9kZTogXCJmaWxlXCJgIChhbiBcIm91dGJveFwiKVxuICogYW5kIGVhY2ggbWVzc2FnZSBpcyB3cml0dGVuIHRvIGRpc2sgYXMgSFRNTCBpbnN0ZWFkIG9mIHNlbnQuIEFueVxuICogcGFydGlhbCBTTVRQIGNvbmZpZ3VyYXRpb24gb3IgYSBzZW5kIGF0dGVtcHQgd2l0aCBubyBjcmVkZW50aWFscyBhbmRcbiAqIG5vIG91dGJveCBvcHQtaW4gdGhyb3dzLlxuICpcbiAqIFByZWNlZGVuY2UgcGVyIGZpZWxkOiBleHBsaWNpdCBwbHVnaW4gY29uZmlnIHdpbnMsIHRoZW4gdGhlIG1hdGNoaW5nXG4gKiBlbnZpcm9ubWVudCB2YXJpYWJsZS4gRW52IG5hbWVzIGFyZSB1bnByZWZpeGVkIGJlY2F1c2UgdGhlIGFwcCB0YWxrc1xuICogdG8gYSBzaW5nbGUgU01UUCBzZXJ2ZXIgKGUuZy4gU01UUDJHTyk6IGBTTVRQX0hPU1RgLCBgU01UUF9QT1JUYCxcbiAqIGBTTVRQX1NFQ1VSRWAsIGBTTVRQX1VTRVJgLCBgU01UUF9QQVNTV09SRGAsIHBsdXMgYEVNQUlMX0RPTUFJTmAgZm9yXG4gKiB0aGUgZGVyaXZlZCBzZW5kZXIncyBkb21haW4sIGBFTUFJTF9GUk9NYCBmb3IgYW4gZXhwbGljaXQgb3ZlcnJpZGUsXG4gKiBgRU1BSUxfU1lTVEVNX0ZST01gIGZvciB0aGUgZG8tbm90LXJlcGx5IGFkZHJlc3Mgc3lzdGVtIG1haWwgc2VuZHMgZnJvbSxcbiAqIGBFTUFJTF9TRU5ERVJfUE9MSUNZYCBmb3IgdGhlIHNlbmRlciByZXN0cmljdGlvbiBtb2RlLCBhbmRcbiAqIGBFTUFJTF9PVVRCT1hfRElSYCBmb3IgdGhlIG91dGJveCBkaXJlY3RvcnkuXG4gKlxuICogQG1vZHVsZVxuICovXG5pbXBvcnQgeyByZXNvbHZlIH0gZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHsgQ29uZmlndXJhdGlvbkVycm9yLCBWYWxpZGF0aW9uRXJyb3IsIHR5cGUgQmFzZVBsdWdpbkNvbmZpZyB9IGZyb20gXCJAZGF0YWJyaWNrcy9hcHBraXRcIjtcbmltcG9ydCB7IGVudiwgb2JqZWN0IH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB0eXBlIHsgSlNPTlNjaGVtYTcgfSBmcm9tIFwianNvbi1zY2hlbWFcIjtcbmltcG9ydCB7IGRlZmF1bHRFbWFpbEJyYW5kLCB0eXBlIEVtYWlsQnJhbmQgfSBmcm9tIFwiLi9icmFuZC50c1wiO1xuaW1wb3J0IHsgaXNTZW5kZXJBbGxvd2VkLCBwYXJzZUFsbG93ZWRTZW5kZXJzLCBzeXN0ZW1TZW5kZXJBZGRyZXNzIH0gZnJvbSBcIi4vc2VuZGVyLnRzXCI7XG5cbi8qKiBTTVRQIHN1Ym1pc3Npb24gcG9ydCB1c2VkIHdoZW4gbm9uZSBpcyBjb25maWd1cmVkLiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfU01UUF9QT1JUID0gNTg3O1xuXG4vKiogU01UUCBwb3J0IHRoYXQgaW1wbGllcyBhIFRMUy1vbi1jb25uZWN0IHNvY2tldCByYXRoZXIgdGhhbiBTVEFSVFRMUy4gKi9cbmV4cG9ydCBjb25zdCBJTVBMSUNJVF9UTFNfU01UUF9QT1JUID0gNDY1O1xuXG4vKipcbiAqIEhvdyB0aGUgc2VuZGVyIChgRnJvbWApIGFkZHJlc3MgaXMgcmVzdHJpY3RlZC5cbiAqXG4gKiBgXCJhbGxvd2xpc3RcImAgaXMgdGhlIGRlZmF1bHQgYW5kIHRoZSBkZW55LWJ5LWRlZmF1bHQgcG9zdHVyZTogYSBzZW5kIGlzXG4gKiBwZXJtaXR0ZWQgb25seSBmcm9tIGFuIGFkZHJlc3MgdGhlIGNvbmZpZ3VyYXRpb24gbmFtZXMsIGVpdGhlciB0aHJvdWdoXG4gKiB7QGxpbmsgRW1haWxQbHVnaW5Db25maWcuYWxsb3dlZFNlbmRlcnN9IG9yLCB3aGVuIHRoYXQgaXMgZW1wdHksIHRocm91Z2hcbiAqIHRoZSBjb25maWd1cmVkIHNlbmRlciBzb3VyY2UgKHtAbGluayBFbWFpbFBsdWdpbkNvbmZpZy5mcm9tfSBhcyBhbiBleGFjdFxuICogYWRkcmVzcywge0BsaW5rIEVtYWlsUGx1Z2luQ29uZmlnLmRvbWFpbn0gYXMgYSBgKkBkb21haW5gIHdpbGRjYXJkKS5cbiAqXG4gKiBgXCJ1bnJlc3RyaWN0ZWRcImAgaXMgdGhlIGV4cGxpY2l0IG9wdC1vdXQ6IGFueSBgRnJvbWAgYSBjYWxsZXIgc3VwcGxpZXMgaXNcbiAqIGFjY2VwdGVkLiBPbmx5IHJlYWNoIGZvciBpdCB3aGVuIGFuIHVwc3RyZWFtIHN5c3RlbSBhbHJlYWR5IHZldHMgdGhlXG4gKiBzZW5kZXIuXG4gKi9cbmV4cG9ydCB0eXBlIFNlbmRlclBvbGljeSA9IFwiYWxsb3dsaXN0XCIgfCBcInVucmVzdHJpY3RlZFwiO1xuXG4vKiogU01UUCBjb25uZWN0aW9uICsgY3JlZGVudGlhbHMuIEFsbCBmaWVsZHMgZmFsbCBiYWNrIHRvIGVudiB3aGVuIHVuc2V0LiAqL1xuZXhwb3J0IGludGVyZmFjZSBTbXRwQ29uZmlnIHtcbiAgLyoqIFNNVFAgc2VydmVyIGhvc3RuYW1lIChgU01UUF9IT1NUYCkuICovXG4gIGhvc3Q/OiBzdHJpbmc7XG4gIC8qKiBTTVRQIHNlcnZlciBwb3J0IChgU01UUF9QT1JUYCkuIERlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX1NNVFBfUE9SVH0uICovXG4gIHBvcnQ/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBVc2UgYSBUTFMtb24tY29ubmVjdCBzb2NrZXQgKGBTTVRQX1NFQ1VSRWApLiBEZWZhdWx0cyB0b1xuICAgKiBgcG9ydCA9PT0gYCB7QGxpbmsgSU1QTElDSVRfVExTX1NNVFBfUE9SVH0uXG4gICAqL1xuICBzZWN1cmU/OiBib29sZWFuO1xuICAvKiogU01UUCBhdXRoIHVzZXJuYW1lIChgU01UUF9VU0VSYCkuICovXG4gIHVzZXI/OiBzdHJpbmc7XG4gIC8qKiBTTVRQIGF1dGggcGFzc3dvcmQgLyBBUEkga2V5IChgU01UUF9QQVNTV09SRGApLiAqL1xuICBwYXNzd29yZD86IHN0cmluZztcbn1cblxuLyoqIEFwcEtpdCBjb25maWcgYWNjZXB0ZWQgYnkgdGhlIGVtYWlsIHBsdWdpbi4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRW1haWxQbHVnaW5Db25maWcgZXh0ZW5kcyBCYXNlUGx1Z2luQ29uZmlnIHtcbiAgLyoqIFNNVFAgY29ubmVjdGlvbiArIGNyZWRlbnRpYWxzLiBPbWl0IHRvIHJ1biBpbiBmaWxlL291dGJveCBtb2RlLiAqL1xuICBzbXRwPzogU210cENvbmZpZztcbiAgLyoqXG4gICAqIERvbWFpbiB1c2VkIHRvIGJ1aWxkIHRoZSBzZW5kZXIgYWRkcmVzcyBmcm9tIHRoZSBvbi1iZWhhbGYtb2YgdXNlclxuICAgKiAoYDxsb2NhbC1wYXJ0PkA8ZG9tYWluPmApLiBGYWxscyBiYWNrIHRvIGBFTUFJTF9ET01BSU5gLiBSZXF1aXJlZCBpblxuICAgKiBTTVRQIG1vZGUgdW5sZXNzIHtAbGluayBmcm9tfSBpcyBzZXQ7IG9wdGlvbmFsIGluIGZpbGUgbW9kZSAodGhlXG4gICAqIG91dGJveCBmYWxscyBiYWNrIHRvIHRoZSB1c2VyJ3Mgb3duIGVtYWlsIGFkZHJlc3MpLlxuICAgKi9cbiAgZG9tYWluPzogc3RyaW5nO1xuICAvKipcbiAgICogRXhwbGljaXQgYEZyb21gIGFkZHJlc3MsIE9QVElPTkFMLiBXaGVuIHNldCwgdGhlIHNlbmRlciBpcyB1c2VkIHZlcmJhdGltXG4gICAqIGFuZCB0aGUgcGVyLXVzZXIgZGVyaXZhdGlvbiBpcyBza2lwcGVkLiBGYWxscyBiYWNrIHRvIGBFTUFJTF9GUk9NYC5cbiAgICpcbiAgICogTGVhdmUgaXQgdW5zZXQgaW4gbW9zdCBkZXBsb3ltZW50czoge0BsaW5rIGRvbWFpbn0gYWxvbmUgaXMgZW5vdWdoLCBhbmRcbiAgICogbWFpbCB0aGVuIGNvbWVzIGZyb20gdGhlIGFkZHJlc3Mgb2YgdGhlIHBlcnNvbiB3aG8gY2F1c2VkIGl0LCB3aGljaCBpcyB3aGF0XG4gICAqIGEgcmVjaXBpZW50IGV4cGVjdHMgdG8gYmUgYWJsZSB0byByZXBseSB0by5cbiAgICovXG4gIGZyb20/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBgRnJvbWAgZm9yIFNZU1RFTSBtYWlsIC0gYSBzZW5kIHdpdGggbm8gb24tYmVoYWxmLW9mIHVzZXIsIHN1Y2ggYXMgYVxuICAgKiBzaWduLWluIGNvZGUgb3IgYSBwYXNzd29yZCByZXNldC4gRmFsbHMgYmFjayB0byBgRU1BSUxfU1lTVEVNX0ZST01gLCB0aGVuXG4gICAqIHRvIGBuby1yZXBseUA8ZG9tYWluPmAsIHRoZW4gdG8ge0BsaW5rIGZyb219LlxuICAgKlxuICAgKiBNYWNoaW5lIG1haWwgZ2V0cyBhIGRvLW5vdC1yZXBseSBhZGRyZXNzIGJ5IGRlZmF1bHQgYmVjYXVzZSBhIHJlcGx5IHRvIGl0XG4gICAqIHJlYWNoZXMgbm9ib2R5LiBTZXQgdGhpcyB0byByb3V0ZSB0aG9zZSByZXBsaWVzIHNvbWV3aGVyZSByZWFsIChhIG1vbml0b3JlZFxuICAgKiBgc3VwcG9ydEBgKSBvciB0byBzcGVsbCB0aGUgbG9jYWwgcGFydCBkaWZmZXJlbnRseSAoYGRvbm90cmVwbHlAYCkuXG4gICAqL1xuICBzeXN0ZW1Gcm9tPzogc3RyaW5nO1xuICAvKipcbiAgICogRGlyZWN0b3J5IGZvciB0aGUgZmlsZS9vdXRib3ggZmFsbGJhY2suIEZhbGxzIGJhY2sgdG9cbiAgICogYEVNQUlMX09VVEJPWF9ESVJgLCB0aGVuIGA8Y3dkPi90bXBgLiBPbmx5IHVzZWQgd2hlbiBTTVRQXG4gICAqIGNyZWRlbnRpYWxzIGFyZSBhYnNlbnQuXG4gICAqL1xuICBvdXREaXI/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBBbGxvdy1saXN0IHJlc3RyaWN0aW5nIHRoZSBzZW5kZXIgKGBGcm9tYCkgYWRkcmVzcy4gRWFjaCBlbnRyeSBpcyBhblxuICAgKiBleGFjdCBhZGRyZXNzIChgdXNlckBkb21haW4uY29tYCksIGEgZG9tYWluIHdpbGRjYXJkIChgKkBkb21haW4uY29tYFxuICAgKiBvciB0aGUgYmFyZSBgZG9tYWluLmNvbWAsIG1hdGNoaW5nIGFueSBsb2NhbCBwYXJ0IG9uIHRoYXQgZG9tYWluKSwgb3JcbiAgICogYCpgIChhbnkpLiBBIHJlc29sdmVkIC8gY2hvc2VuIHNlbmRlciB0aGF0IG1hdGNoZXMgbm8gZW50cnkgaXNcbiAgICogcmVqZWN0ZWQgYXQgc2VuZCB0aW1lLiBBY2NlcHRzIGEgYHN0cmluZ1tdYCBvciBhIHNpbmdsZSBjb21tYS0gL1xuICAgKiB3aGl0ZXNwYWNlLXNlcGFyYXRlZCBzdHJpbmc7IGZhbGxzIGJhY2sgdG8gYEVNQUlMX0FMTE9XRURfU0VOREVSU2AuXG4gICAqIFdoZW4gZW1wdHksIHRoZSB7QGxpbmsgc2VuZGVyUG9saWN5fSBkZWNpZGVzIHdoYXQgaXMgcGVybWl0dGVkLlxuICAgKi9cbiAgYWxsb3dlZFNlbmRlcnM/OiBzdHJpbmcgfCBzdHJpbmdbXTtcbiAgLyoqXG4gICAqIEhvdyB0aGUgc2VuZGVyIGFkZHJlc3MgaXMgcmVzdHJpY3RlZCB3aGVuIHtAbGluayBhbGxvd2VkU2VuZGVyc30gaXNcbiAgICogZW1wdHkgKGBFTUFJTF9TRU5ERVJfUE9MSUNZYCkuIERlZmF1bHRzIHRvIGBcImFsbG93bGlzdFwiYCwgd2hpY2hcbiAgICogbmFycm93cyBzZW5kcyB0byB0aGUgY29uZmlndXJlZCBzZW5kZXIgc291cmNlLiBTZWVcbiAgICoge0BsaW5rIFNlbmRlclBvbGljeX0uXG4gICAqL1xuICBzZW5kZXJQb2xpY3k/OiBTZW5kZXJQb2xpY3k7XG4gIC8qKlxuICAgKiBPcHRpb25hbCBicmFuZCBzdHlsaW5nIGFwcGxpZWQgdG8gZXZlcnkgcmVuZGVyZWQgbWVzc2FnZS4gT21pdCB0byB1c2UgdGhlXG4gICAqIHJlcG9zaXRvcnkncyBkYngtdG9vbHMgYnJhbmQuIFBhc3Mge0BsaW5rIGVtYWlsQnJhbmRGcm9tQ29udGV4dH0gdG8gZGVyaXZlXG4gICAqIGEgY3VzdG9tIHZhbHVlIGZyb20gYSBzaGFyZWQgYEJyYW5kQ29udGV4dGAuXG4gICAqL1xuICBicmFuZD86IEVtYWlsQnJhbmQ7XG59XG5cbi8qKiBDb25maWcgc2hhcmVkIGJ5IGJvdGggcmVzb2x2ZWQgbW9kZXMuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlc29sdmVkU2VuZGVyIHtcbiAgLyoqIFNlbmRlciBkb21haW47IHByZXNlbnQgd2hlbmV2ZXIge0BsaW5rIGZyb219IGlzIGFic2VudC4gKi9cbiAgZG9tYWluPzogc3RyaW5nO1xuICAvKiogRXhwbGljaXQgc2VuZGVyIG92ZXJyaWRlOyBwcmVzZW50IHNraXBzIHBlci11c2VyIGRlcml2YXRpb24uICovXG4gIGZyb20/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBFeHBsaWNpdCBkby1ub3QtcmVwbHkgc2VuZGVyIGZvciBzeXN0ZW0gbWFpbC4gQWJzZW50IG1lYW5zIGl0IGlzIGRlcml2ZWQgLVxuICAgKiBzZWUge0BsaW5rIHN5c3RlbVNlbmRlckFkZHJlc3N9LlxuICAgKi9cbiAgc3lzdGVtRnJvbT86IHN0cmluZztcbiAgLyoqXG4gICAqIEVmZmVjdGl2ZSBzZW5kZXIgYWxsb3ctbGlzdDogdGhlIGNvbmZpZ3VyZWQgcGF0dGVybnMgd2hlbiBhbnkgd2VyZVxuICAgKiBnaXZlbiwgZWxzZSB0aGUgcGF0dGVybnMgaW1wbGllZCBieSB0aGUgc2VuZGVyIHNvdXJjZSB1bmRlciBhblxuICAgKiBgXCJhbGxvd2xpc3RcImAgcG9saWN5LiBFbXB0eSBtZWFucyB1bmVuZm9yY2VhYmxlIChhbiBgXCJ1bnJlc3RyaWN0ZWRcImBcbiAgICogcG9saWN5LCBvciBhbiBvdXRib3ggd2l0aCBubyBzZW5kZXIgc291cmNlIHRvIG5hcnJvdyB0bykuXG4gICAqL1xuICBhbGxvd2VkU2VuZGVyczogc3RyaW5nW107XG4gIC8qKiBUaGUgcmVzdHJpY3Rpb24gbW9kZSB0aGUgYWxsb3ctbGlzdCB3YXMgcmVzb2x2ZWQgdW5kZXIuICovXG4gIHNlbmRlclBvbGljeTogU2VuZGVyUG9saWN5O1xuICAvKiogQnJhbmQgc3R5bGluZyBhcHBsaWVkIHRvIHJlbmRlcmVkIEhUTUwuICovXG4gIGJyYW5kOiBFbWFpbEJyYW5kO1xufVxuXG4vKiogUmVzb2x2ZWQgY29uZmlnIGZvciByZWFsIFNNVFAgZGVsaXZlcnkuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlc29sdmVkU210cENvbmZpZyBleHRlbmRzIFJlc29sdmVkU2VuZGVyIHtcbiAgbW9kZTogXCJzbXRwXCI7XG4gIGhvc3Q6IHN0cmluZztcbiAgcG9ydDogbnVtYmVyO1xuICBzZWN1cmU6IGJvb2xlYW47XG4gIGF1dGg6IHsgdXNlcjogc3RyaW5nOyBwYXNzOiBzdHJpbmcgfTtcbn1cblxuLyoqIFJlc29sdmVkIGNvbmZpZyBmb3IgdGhlIGZpbGUvb3V0Ym94IGZhbGxiYWNrIChubyBTTVRQIGNyZWRlbnRpYWxzKS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb2x2ZWRGaWxlQ29uZmlnIGV4dGVuZHMgUmVzb2x2ZWRTZW5kZXIge1xuICBtb2RlOiBcImZpbGVcIjtcbiAgLyoqIEFic29sdXRlIGRpcmVjdG9yeSBtZXNzYWdlcyBhcmUgd3JpdHRlbiB1bmRlci4gKi9cbiAgb3V0RGlyOiBzdHJpbmc7XG59XG5cbi8qKiBDb25jcmV0ZSwgdmFsaWRhdGVkIGNvbmZpZyB0aGUgcnVudGltZSBkaXNwYXRjaGVzIHRocm91Z2guICovXG5leHBvcnQgdHlwZSBSZXNvbHZlZEVtYWlsQ29uZmlnID0gUmVzb2x2ZWRTbXRwQ29uZmlnIHwgUmVzb2x2ZWRGaWxlQ29uZmlnO1xuXG4vKiogSlNPTiBTY2hlbWEgcHVibGlzaGVkIG9uIHRoZSBtYW5pZmVzdCdzIGBjb25maWcuc2NoZW1hYC4gKi9cbmV4cG9ydCBjb25zdCBFTUFJTF9DT05GSUdfU0NIRU1BOiBKU09OU2NoZW1hNyA9IHtcbiAgdHlwZTogXCJvYmplY3RcIixcbiAgcHJvcGVydGllczoge1xuICAgIHNtdHA6IHtcbiAgICAgIHR5cGU6IFwib2JqZWN0XCIsXG4gICAgICBkZXNjcmlwdGlvbjogXCJTTVRQIGNvbm5lY3Rpb24gYW5kIGNyZWRlbnRpYWxzIChlbnYgZmFsbGJhY2tzOiBTTVRQXyopLlwiLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBob3N0OiB7IHR5cGU6IFwic3RyaW5nXCIsIGRlc2NyaXB0aW9uOiBcIlNNVFAgc2VydmVyIGhvc3RuYW1lIChTTVRQX0hPU1QpLlwiIH0sXG4gICAgICAgIHBvcnQ6IHtcbiAgICAgICAgICB0eXBlOiBcIm51bWJlclwiLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiBgU01UUCBzZXJ2ZXIgcG9ydCAoU01UUF9QT1JUKS4gRGVmYXVsdHMgdG8gJHtERUZBVUxUX1NNVFBfUE9SVH0uYCxcbiAgICAgICAgfSxcbiAgICAgICAgc2VjdXJlOiB7XG4gICAgICAgICAgdHlwZTogXCJib29sZWFuXCIsXG4gICAgICAgICAgZGVzY3JpcHRpb246IGBUTFMtb24tY29ubmVjdCBzb2NrZXQgKFNNVFBfU0VDVVJFKS4gRGVmYXVsdHMgdG8gcG9ydCA9PT0gJHtJTVBMSUNJVF9UTFNfU01UUF9QT1JUfS5gLFxuICAgICAgICB9LFxuICAgICAgICB1c2VyOiB7IHR5cGU6IFwic3RyaW5nXCIsIGRlc2NyaXB0aW9uOiBcIlNNVFAgYXV0aCB1c2VybmFtZSAoU01UUF9VU0VSKS5cIiB9LFxuICAgICAgICBwYXNzd29yZDoge1xuICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgZGVzY3JpcHRpb246IFwiU01UUCBhdXRoIHBhc3N3b3JkIC8gQVBJIGtleSAoU01UUF9QQVNTV09SRCkuXCIsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0sXG4gICAgZG9tYWluOiB7XG4gICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgIFwiRG9tYWluIGZvciB0aGUgZGVyaXZlZCBzZW5kZXIgYWRkcmVzcyAoPHVzZXItbG9jYWwtcGFydD5APGRvbWFpbj4pLiBGYWxscyBiYWNrIHRvIEVNQUlMX0RPTUFJTi5cIixcbiAgICB9LFxuICAgIGZyb206IHtcbiAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgXCJPcHRpb25hbCBleHBsaWNpdCBGcm9tIGFkZHJlc3M7IHNraXBzIHBlci11c2VyIGRlcml2YXRpb24uIEZhbGxzIGJhY2sgdG8gRU1BSUxfRlJPTS5cIixcbiAgICB9LFxuICAgIHN5c3RlbUZyb206IHtcbiAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgXCJGcm9tIGZvciBzeXN0ZW0gbWFpbCAobm8gb24tYmVoYWxmLW9mIHVzZXIsIGUuZy4gYSBzaWduLWluIGNvZGUpLiBGYWxscyBiYWNrIHRvIEVNQUlMX1NZU1RFTV9GUk9NLCB0aGVuIG5vLXJlcGx5QDxkb21haW4+LCB0aGVuIGZyb20uXCIsXG4gICAgfSxcbiAgICBvdXREaXI6IHtcbiAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgXCJEaXJlY3RvcnkgZm9yIHRoZSBmaWxlL291dGJveCBmYWxsYmFjayB3aGVuIFNNVFAgaXMgdW5jb25maWd1cmVkLiBGYWxscyBiYWNrIHRvIEVNQUlMX09VVEJPWF9ESVIsIHRoZW4gPGN3ZD4vdG1wLlwiLFxuICAgIH0sXG4gICAgYWxsb3dlZFNlbmRlcnM6IHtcbiAgICAgIHR5cGU6IFwiYXJyYXlcIixcbiAgICAgIGl0ZW1zOiB7IHR5cGU6IFwic3RyaW5nXCIgfSxcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnQWxsb3ctbGlzdCBvZiBwZXJtaXR0ZWQgc2VuZGVyIChGcm9tKSBwYXR0ZXJuczogZXhhY3QgYWRkcmVzc2VzIChcInVzZXJAZG9tYWluLmNvbVwiKSwgZG9tYWluIHdpbGRjYXJkcyAoXCIqQGRvbWFpbi5jb21cIiksIG9yIFwiKlwiLiBBbHNvIGFjY2VwdHMgYSBjb21tYS9zcGFjZS1zZXBhcmF0ZWQgc3RyaW5nLiBGYWxscyBiYWNrIHRvIEVNQUlMX0FMTE9XRURfU0VOREVSUy4gV2hlbiBlbXB0eSwgc2VuZGVyUG9saWN5IGRlY2lkZXMuJyxcbiAgICB9LFxuICAgIHNlbmRlclBvbGljeToge1xuICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgIGVudW06IFtcImFsbG93bGlzdFwiLCBcInVucmVzdHJpY3RlZFwiXSxcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnSG93IHRoZSBzZW5kZXIgaXMgcmVzdHJpY3RlZCB3aGVuIGFsbG93ZWRTZW5kZXJzIGlzIGVtcHR5IChFTUFJTF9TRU5ERVJfUE9MSUNZKS4gXCJhbGxvd2xpc3RcIiAoZGVmYXVsdCkgbmFycm93cyBzZW5kcyB0byB0aGUgY29uZmlndXJlZCBzZW5kZXIgc291cmNlOyBcInVucmVzdHJpY3RlZFwiIGFjY2VwdHMgYW55IEZyb20uJyxcbiAgICB9LFxuICAgIGJyYW5kOiB7XG4gICAgICB0eXBlOiBcIm9iamVjdFwiLFxuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgIFwiQnJhbmQgc3R5bGluZyBhcHBsaWVkIHRvIGV2ZXJ5IFJlYWN0IEVtYWlsIG1lc3NhZ2UuIE9taXQgdG8gdXNlIHRoZSBkYngtdG9vbHMgYnJhbmQuXCIsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGFjY2VudDoge1xuICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdIZWFkZXItYmFuZCBiYWNrZ3JvdW5kIGFuZCBib2R5IGxpbmsgY29sb3IgKGUuZy4gXCIjRkYzNjIxXCIpLicsXG4gICAgICAgIH0sXG4gICAgICAgIG9uQWNjZW50OiB7XG4gICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgICBkZXNjcmlwdGlvbjogXCJUZXh0IGFuZCBsb2dvIGNvbG9yIHJlbmRlcmVkIG9uIHRoZSBhY2NlbnQgYmFuZC4gRGVmYXVsdHMgdG8gd2hpdGUuXCIsXG4gICAgICAgIH0sXG4gICAgICAgIGZvbnRGYW1pbHk6IHtcbiAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnQm9keSBmb250IHN0YWNrIChlLmcuIFwiSW50ZXIsIHVpLXNhbnMtc2VyaWYsIHN5c3RlbS11aSwgc2Fucy1zZXJpZlwiKS4nLFxuICAgICAgICB9LFxuICAgICAgICBuYW1lOiB7XG4gICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgICBkZXNjcmlwdGlvbjogXCJQcm9kdWN0IC8gZGlzcGxheSBuYW1lIHVzZWQgYXMgdGhlIGhlYWRlciB0ZXh0IGFuZCB0aGUgbG9nbyBhbHQgdGV4dC5cIixcbiAgICAgICAgfSxcbiAgICAgICAgbG9nb1VybDoge1xuICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgICBcIkxvZ28gaW1hZ2UgZm9yIHRoZSBoZWFkZXIgYmFuZC4gT25seSBhbiBodHRwKHMpOiBvciBkYXRhOiBVUkwgcmVuZGVyczsgb3RoZXIgdmFsdWVzIGFyZSBkcm9wcGVkIGJlY2F1c2UgYSBtYWlsIGNsaWVudCBjYW5ub3QgbG9hZCB0aGVtLlwiLFxuICAgICAgICB9LFxuICAgICAgICBiYWNrZ3JvdW5kOiB7IHR5cGU6IFwic3RyaW5nXCIsIGRlc2NyaXB0aW9uOiBcIkluYm94IGNhbnZhcyBjb2xvci5cIiB9LFxuICAgICAgICBzdXJmYWNlOiB7IHR5cGU6IFwic3RyaW5nXCIsIGRlc2NyaXB0aW9uOiBcIk1lc3NhZ2UtY2FyZCBjb2xvci5cIiB9LFxuICAgICAgICBmb3JlZ3JvdW5kOiB7IHR5cGU6IFwic3RyaW5nXCIsIGRlc2NyaXB0aW9uOiBcIlByaW1hcnkgdGV4dCBjb2xvci5cIiB9LFxuICAgICAgICBtdXRlZDogeyB0eXBlOiBcInN0cmluZ1wiLCBkZXNjcmlwdGlvbjogXCJTZWNvbmRhcnkgdGV4dCBjb2xvci5cIiB9LFxuICAgICAgICBib3JkZXI6IHsgdHlwZTogXCJzdHJpbmdcIiwgZGVzY3JpcHRpb246IFwiQm9yZGVyIGFuZCBkaXZpZGVyIGNvbG9yLlwiIH0sXG4gICAgICAgIHRhZ2xpbmU6IHsgdHlwZTogXCJzdHJpbmdcIiwgZGVzY3JpcHRpb246IFwiRm9vdGVyIHByb2R1Y3QgbGluZS5cIiB9LFxuICAgICAgICB3ZWJzaXRlOiB7IHR5cGU6IFwic3RyaW5nXCIsIGRlc2NyaXB0aW9uOiBcIk9wdGlvbmFsIGZvb3RlciB3ZWJzaXRlIFVSTC5cIiB9LFxuICAgICAgfSxcbiAgICAgIHJlcXVpcmVkOiBbXCJhY2NlbnRcIiwgXCJmb250RmFtaWx5XCJdLFxuICAgIH0sXG4gIH0sXG59O1xuXG4vKiogUGFyc2UgdGhlIGBTTVRQX1NFQ1VSRWAgZW52IC8gY29uZmlnIGZsYWcsIGRlZmF1bHRpbmcgYnkgcG9ydC4gKi9cbmZ1bmN0aW9uIHJlc29sdmVTZWN1cmUoZmxhZzogYm9vbGVhbiB8IHVuZGVmaW5lZCwgcG9ydDogbnVtYmVyKTogYm9vbGVhbiB7XG4gIHJldHVybiBlbnYuYm9vbGVhbihmbGFnLCBcIlNNVFBfU0VDVVJFXCIpID8/IHBvcnQgPT09IElNUExJQ0lUX1RMU19TTVRQX1BPUlQ7XG59XG5cbi8qKiBQYXJzZSB0aGUgYEVNQUlMX1NFTkRFUl9QT0xJQ1lgIGVudiAvIGNvbmZpZyB2YWx1ZSwgZGVmYXVsdGluZyB0byBkZW55LWJ5LWRlZmF1bHQuICovXG5mdW5jdGlvbiByZXNvbHZlU2VuZGVyUG9saWN5KHBvbGljeTogU2VuZGVyUG9saWN5IHwgdW5kZWZpbmVkKTogU2VuZGVyUG9saWN5IHtcbiAgY29uc3QgcmF3ID0gcG9saWN5ID8/IGVudi50ZXh0KFwiRU1BSUxfU0VOREVSX1BPTElDWVwiKT8udG9Mb3dlckNhc2UoKTtcbiAgaWYgKHJhdyA9PT0gXCJ1bnJlc3RyaWN0ZWRcIikgcmV0dXJuIFwidW5yZXN0cmljdGVkXCI7XG4gIGlmIChyYXcgPT09IHVuZGVmaW5lZCB8fCByYXcgPT09IFwiXCIgfHwgcmF3ID09PSBcImFsbG93bGlzdFwiKSByZXR1cm4gXCJhbGxvd2xpc3RcIjtcbiAgdGhyb3cgVmFsaWRhdGlvbkVycm9yLmludmFsaWRWYWx1ZShcInNlbmRlclBvbGljeVwiLCByYXcsICdcImFsbG93bGlzdFwiIG9yIFwidW5yZXN0cmljdGVkXCInKTtcbn1cblxuLyoqXG4gKiBFZmZlY3RpdmUgYWxsb3ctbGlzdCBmb3IgYW4gYFwiYWxsb3dsaXN0XCJgIHBvbGljeSB3aXRoIG5vIGV4cGxpY2l0IHBhdHRlcm5zOlxuICogdGhlIHNlbmRlciBzb3VyY2UgaXRzZWxmLCBzbyBhIGNvbmZpZ3VyZWQgZG9tYWluIG9yIGZpeGVkIGFkZHJlc3MgaXMgdGhlXG4gKiBib3VuZGFyeSByYXRoZXIgdGhhbiBcImFueXRoaW5nIGdvZXNcIi4gWWllbGRzIG5vdGhpbmcgd2hlbiBuZWl0aGVyIGlzIHNldCxcbiAqIHdoaWNoIG9ubHkgaGFwcGVucyBpbiBvdXRib3ggbW9kZSAod2hlcmUgdGhlIHNlbmRlciBmYWxscyBiYWNrIHRvIHRoZVxuICogb24tYmVoYWxmLW9mIHVzZXIncyBvd24gYWRkcmVzcyBhbmQgY2Fubm90IGJlIGVudW1lcmF0ZWQgdXAgZnJvbnQpLlxuICovXG5mdW5jdGlvbiBpbXBsaWVkU2VuZGVyUGF0dGVybnMoc2VuZGVyOiB7XG4gIGRvbWFpbj86IHN0cmluZztcbiAgZnJvbT86IHN0cmluZztcbiAgc3lzdGVtRnJvbT86IHN0cmluZztcbn0pOiBzdHJpbmdbXSB7XG4gIGNvbnN0IHBhdHRlcm5zOiBzdHJpbmdbXSA9IFtdO1xuICBpZiAoc2VuZGVyLmZyb20pIHBhdHRlcm5zLnB1c2goc2VuZGVyLmZyb20udHJpbSgpLnRvTG93ZXJDYXNlKCkpO1xuICBpZiAoc2VuZGVyLmRvbWFpbikgcGF0dGVybnMucHVzaChgKkAke3NlbmRlci5kb21haW4udHJpbSgpLnRvTG93ZXJDYXNlKCl9YCk7XG4gIC8vIFRoZSBzeXN0ZW0gc2VuZGVyIHRvbywgd2hlbiB0aGUgcGF0dGVybnMgYWJvdmUgZG8gbm90IGFscmVhZHkgY292ZXIgaXQ6IGl0XG4gIC8vIGlzIGFuIGFkZHJlc3MgdGhpcyBhcHAgU0VORFMgZnJvbSwgc28gYSBsaXN0IGRlcml2ZWQgZnJvbSB0aGUgc2VuZGVyIHNvdXJjZVxuICAvLyBoYXMgdG8gcGVybWl0IGl0LCBvciB0aGUgdmVyeSBwb2xpY3kgbWVhbnQgdG8gZGVzY3JpYmUgdGhlIGFwcCdzIG93biBzZW5kZXJzXG4gIC8vIGRlbmllcyBpdHMgc2lnbi1pbiBtYWlsLiBVc3VhbGx5IHJlZHVuZGFudCAoYCpAZG9tYWluYCBhbHJlYWR5IG1hdGNoZXNcbiAgLy8gYG5vLXJlcGx5QGRvbWFpbmApIC0gaXQgbWF0dGVycyBmb3IgYSBgc3lzdGVtRnJvbWAgb24gYW5vdGhlciBkb21haW4uXG4gIGNvbnN0IHN5c3RlbSA9IHN5c3RlbVNlbmRlckFkZHJlc3Moc2VuZGVyKT8udG9Mb3dlckNhc2UoKTtcbiAgaWYgKHN5c3RlbSAmJiAhaXNTZW5kZXJBbGxvd2VkKHN5c3RlbSwgcGF0dGVybnMpKSBwYXR0ZXJucy5wdXNoKHN5c3RlbSk7XG4gIHJldHVybiBwYXR0ZXJucztcbn1cblxuLyoqIFdoZXRoZXIgYEVNQUlMX09VVEJPWF9NT0RFYCBleHBsaWNpdGx5IG9wdHMgaW50byB0aGUgZmlsZS9vdXRib3ggZmFsbGJhY2suICovXG5mdW5jdGlvbiBpc091dGJveE1vZGVFbmFibGVkKCk6IGJvb2xlYW4ge1xuICByZXR1cm4gZW52LmJvb2xlYW4odW5kZWZpbmVkLCBcIkVNQUlMX09VVEJPWF9NT0RFXCIpID8/IGZhbHNlO1xufVxuXG5jb25zdCBTTVRQX1JFUVVJUkVEX0ZJRUxEUyA9IFtcIlNNVFBfSE9TVFwiLCBcIlNNVFBfVVNFUlwiLCBcIlNNVFBfUEFTU1dPUkRcIl0gYXMgY29uc3Q7XG5cbi8qKiBMaXN0IGVudiBrZXlzIGZvciBTTVRQIGZpZWxkcyB0aGF0IGFyZSB1bnNldCBpbiB0aGUgcmVzb2x2ZWQgY3JlZGVudGlhbCBzZXQuICovXG5mdW5jdGlvbiBtaXNzaW5nU210cEZpZWxkcyhcbiAgaG9zdDogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICB1c2VyOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gIHBhc3M6IHN0cmluZyB8IHVuZGVmaW5lZCxcbik6IHN0cmluZ1tdIHtcbiAgY29uc3QgdmFsdWVzID0gW2hvc3QsIHVzZXIsIHBhc3NdIGFzIGNvbnN0O1xuICByZXR1cm4gU01UUF9SRVFVSVJFRF9GSUVMRFMuZmlsdGVyKChfLCBpbmRleCkgPT4gIXZhbHVlc1tpbmRleF0pO1xufVxuXG4vKipcbiAqIFJlc29sdmUgcGx1Z2luIGNvbmZpZyBvdmVyIGVudmlyb25tZW50IGRlZmF1bHRzLlxuICpcbiAqIFdoZW4gU01UUCBob3N0ICsgdXNlciArIHBhc3N3b3JkIGFyZSBhbGwgcHJlc2VudCwgcmV0dXJucyBgbW9kZTpcbiAqIFwic210cFwiYCBmb3IgcmVhbCBkZWxpdmVyeSAoYW5kIHRocm93cyBpZiBubyBzZW5kZXIgc291cmNlIC0gZG9tYWluLFxuICogZnJvbSwgb3Igc3lzdGVtRnJvbSAtIGlzIGNvbmZpZ3VyZWQsIHNpbmNlIFNNVFAgY2FuJ3QgZGVyaXZlIG9uZSBmcm9tXG4gKiBub3RoaW5nOyBgZG9tYWluYCBhbG9uZSBpcyB0aGUgaW50ZW5kZWQgbWluaW11bSkuXG4gKiBXaGVuIGFsbCB0aHJlZSBhcmUgYWJzZW50IGFuZCBgRU1BSUxfT1VUQk9YX01PREVgIGlzIGVuYWJsZWQsIHJldHVybnNcbiAqIGBtb2RlOiBcImZpbGVcImAgc28gdGhlIHJ1bnRpbWUgd3JpdGVzIG1lc3NhZ2VzIHRvIHRoZSBvdXRib3ggZGlyZWN0b3J5XG4gKiBmb3IgbG9jYWwgdGVzdGluZzsgaW4gdGhhdCBtb2RlIGEgc2VuZGVyIHNvdXJjZSBpcyBvcHRpb25hbCAodGhlXG4gKiBvdXRib3ggZmFsbHMgYmFjayB0byB0aGUgT0JPIHVzZXIncyBvd24gYWRkcmVzcykuIFBhcnRpYWwgU01UUFxuICogY29uZmlndXJhdGlvbiBvciBhIHNlbmQgd2l0aCBubyBjcmVkZW50aWFscyBhbmQgbm8gb3V0Ym94IG9wdC1pblxuICogdGhyb3dzLlxuICpcbiAqIFRoZSBzZW5kZXIgYWxsb3ctbGlzdCBpcyByZXNvbHZlZCBoZXJlIHRvbzogdW5kZXIgdGhlIGRlZmF1bHRcbiAqIGBcImFsbG93bGlzdFwiYCBwb2xpY3kgYW4gZW1wdHkgbGlzdCBpcyBmaWxsZWQgaW4gZnJvbSB0aGUgc2VuZGVyIHNvdXJjZSxcbiAqIHNvIGEgZGVwbG95bWVudCB0aGF0IG9ubHkgc2V0cyBgRU1BSUxfRE9NQUlOYCBzdGlsbCByZWplY3RzIGEgYEZyb21gIG9uXG4gKiBhbnkgb3RoZXIgZG9tYWluLiBTZWUge0BsaW5rIFNlbmRlclBvbGljeX0uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlRW1haWxDb25maWcoY29uZmlnOiBFbWFpbFBsdWdpbkNvbmZpZyA9IHt9KTogUmVzb2x2ZWRFbWFpbENvbmZpZyB7XG4gIGNvbnN0IHNtdHAgPSBjb25maWcuc210cCA/PyB7fTtcbiAgY29uc3QgaG9zdCA9IGVudi5zdHJpbmcoc210cC5ob3N0LCBcIlNNVFBfSE9TVFwiKSA/PyB1bmRlZmluZWQ7XG4gIGNvbnN0IHVzZXIgPSBlbnYuc3RyaW5nKHNtdHAudXNlciwgXCJTTVRQX1VTRVJcIikgPz8gdW5kZWZpbmVkO1xuICBjb25zdCBwYXNzID0gZW52LnN0cmluZyhzbXRwLnBhc3N3b3JkLCBcIlNNVFBfUEFTU1dPUkRcIikgPz8gdW5kZWZpbmVkO1xuICBjb25zdCBkb21haW4gPSBlbnYuc3RyaW5nKGNvbmZpZy5kb21haW4sIFwiRU1BSUxfRE9NQUlOXCIpID8/IHVuZGVmaW5lZDtcbiAgY29uc3QgZnJvbSA9IGVudi5zdHJpbmcoY29uZmlnLmZyb20sIFwiRU1BSUxfRlJPTVwiKSA/PyB1bmRlZmluZWQ7XG4gIGNvbnN0IHN5c3RlbUZyb20gPSBlbnYuc3RyaW5nKGNvbmZpZy5zeXN0ZW1Gcm9tLCBcIkVNQUlMX1NZU1RFTV9GUk9NXCIpID8/IHVuZGVmaW5lZDtcbiAgY29uc3Qgc2VuZGVyUG9saWN5ID0gcmVzb2x2ZVNlbmRlclBvbGljeShjb25maWcuc2VuZGVyUG9saWN5KTtcbiAgY29uc3QgY29uZmlndXJlZFNlbmRlcnMgPSBwYXJzZUFsbG93ZWRTZW5kZXJzKFxuICAgIGNvbmZpZy5hbGxvd2VkU2VuZGVycyA/PyBlbnYudGV4dChcIkVNQUlMX0FMTE9XRURfU0VOREVSU1wiKSA/PyB1bmRlZmluZWQsXG4gICk7XG4gIGNvbnN0IGFsbG93ZWRTZW5kZXJzID1cbiAgICBjb25maWd1cmVkU2VuZGVycy5sZW5ndGggPiAwIHx8IHNlbmRlclBvbGljeSA9PT0gXCJ1bnJlc3RyaWN0ZWRcIlxuICAgICAgPyBjb25maWd1cmVkU2VuZGVyc1xuICAgICAgOiBpbXBsaWVkU2VuZGVyUGF0dGVybnMoeyBkb21haW4sIGZyb20sIHN5c3RlbUZyb20gfSk7XG4gIGNvbnN0IHNlbmRlcjogUmVzb2x2ZWRTZW5kZXIgPSB7XG4gICAgLi4ub2JqZWN0Lm9wdGlvbmFsKFwiZG9tYWluXCIsIGRvbWFpbiksXG4gICAgLi4ub2JqZWN0Lm9wdGlvbmFsKFwiZnJvbVwiLCBmcm9tKSxcbiAgICAuLi5vYmplY3Qub3B0aW9uYWwoXCJzeXN0ZW1Gcm9tXCIsIHN5c3RlbUZyb20pLFxuICAgIGFsbG93ZWRTZW5kZXJzLFxuICAgIHNlbmRlclBvbGljeSxcbiAgICBicmFuZDogY29uZmlnLmJyYW5kID8/IGRlZmF1bHRFbWFpbEJyYW5kLFxuICB9O1xuXG4gIGNvbnN0IGhhc0FsbFNtdHAgPSBCb29sZWFuKGhvc3QgJiYgdXNlciAmJiBwYXNzKTtcbiAgY29uc3QgaGFzQW55U210cCA9IEJvb2xlYW4oaG9zdCB8fCB1c2VyIHx8IHBhc3MpO1xuXG4gIGlmIChoYXNBbnlTbXRwICYmICFoYXNBbGxTbXRwKSB7XG4gICAgdGhyb3cgVmFsaWRhdGlvbkVycm9yLm1pc3NpbmdFbnZWYXJzKG1pc3NpbmdTbXRwRmllbGRzKGhvc3QsIHVzZXIsIHBhc3MpKTtcbiAgfVxuXG4gIGlmIChoYXNBbGxTbXRwKSB7XG4gICAgaWYgKCFkb21haW4gJiYgIWZyb20gJiYgIXN5c3RlbUZyb20pIHtcbiAgICAgIHRocm93IENvbmZpZ3VyYXRpb25FcnJvci5yZXNvdXJjZU5vdEZvdW5kKFxuICAgICAgICBcIkVtYWlsIHNlbmRlciBzb3VyY2VcIixcbiAgICAgICAgXCJTZXQgRU1BSUxfRE9NQUlOIHRvIGRlcml2ZSA8dXNlci1sb2NhbC1wYXJ0PkA8ZG9tYWluPiAoYW5kIG5vLXJlcGx5QDxkb21haW4+IGZvciBzeXN0ZW0gbWFpbCksIG9yIEVNQUlMX0ZST00gZm9yIGEgZml4ZWQgYWRkcmVzcy5cIixcbiAgICAgICk7XG4gICAgfVxuICAgIGNvbnN0IHBvcnQgPSBlbnYucG9zaXRpdmVJbnQoc210cC5wb3J0LCBcIlNNVFBfUE9SVFwiLCBERUZBVUxUX1NNVFBfUE9SVCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIG1vZGU6IFwic210cFwiLFxuICAgICAgaG9zdDogaG9zdCEsXG4gICAgICBwb3J0LFxuICAgICAgc2VjdXJlOiByZXNvbHZlU2VjdXJlKHNtdHAuc2VjdXJlLCBwb3J0KSxcbiAgICAgIGF1dGg6IHsgdXNlcjogdXNlciEsIHBhc3M6IHBhc3MhIH0sXG4gICAgICAuLi5zZW5kZXIsXG4gICAgfTtcbiAgfVxuXG4gIGlmICghaXNPdXRib3hNb2RlRW5hYmxlZCgpKSB7XG4gICAgdGhyb3cgQ29uZmlndXJhdGlvbkVycm9yLmludmFsaWRDb25uZWN0aW9uKFxuICAgICAgXCJTTVRQXCIsXG4gICAgICBgU2V0ICR7U01UUF9SRVFVSVJFRF9GSUVMRFMuam9pbihcIiwgXCIpfSwgb3IgRU1BSUxfT1VUQk9YX01PREU9MSB0byB3cml0ZSBtZXNzYWdlcyB0byBhIGxvY2FsIG91dGJveCBpbnN0ZWFkLmAsXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IG91dERpciA9IHJlc29sdmUoXG4gICAgZW52LnN0cmluZyhjb25maWcub3V0RGlyLCBcIkVNQUlMX09VVEJPWF9ESVJcIikgPz8gcmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCBcInRtcFwiKSxcbiAgKTtcbiAgcmV0dXJuIHsgbW9kZTogXCJmaWxlXCIsIG91dERpciwgLi4uc2VuZGVyIH07XG59XG4iXX0=
@@ -19,6 +19,4 @@ import type { EmailBrand } from "./brand.ts";
19
19
  * absolute path. The per-sender folder mirrors the SMTP `From`, so test
20
20
  * output groups by who the message would have been sent as.
21
21
  */
22
- export declare function writeOutboxEmail(message: EmailMessage, from: string, dir: string, brand?: EmailBrand, options?: {
23
- trailer?: string;
24
- }): Promise<string>;
22
+ export declare function writeOutboxEmail(message: EmailMessage, from: string, dir: string, brand?: EmailBrand): Promise<string>;
package/lib/src/outbox.js CHANGED
@@ -43,7 +43,7 @@ function headerRows(message, from) {
43
43
  * absolute path. The per-sender folder mirrors the SMTP `From`, so test
44
44
  * output groups by who the message would have been sent as.
45
45
  */
46
- export async function writeOutboxEmail(message, from, dir, brand, options) {
46
+ export async function writeOutboxEmail(message, from, dir, brand) {
47
47
  const folder = resolve(dir, from);
48
48
  await mkdir(folder, { recursive: true });
49
49
  const path = join(folder, `${Date.now()}-${subjectSlug(message.subject)}.html`);
@@ -53,11 +53,8 @@ export async function writeOutboxEmail(message, from, dir, brand, options) {
53
53
  body: message.body,
54
54
  footer: "Local outbox preview - written to disk, not sent (no SMTP credentials configured).",
55
55
  ...(brand ? { brand } : {}),
56
- // Preserved so the preview shows the trailer in the same place a real send
57
- // puts it - the whole point being that it is the LAST line.
58
- ...(options?.trailer ? { trailer: options.trailer } : {}),
59
56
  });
60
57
  await writeFile(path, html, "utf8");
61
58
  return path;
62
59
  }
63
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3V0Ym94LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL291dGJveC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7OztHQWFHO0FBRUgsT0FBTyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNwRCxPQUFPLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUMxQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFHaEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRWxEOzs7R0FHRztBQUNILE1BQU0sdUJBQXVCLEdBQUcsRUFBRSxDQUFDO0FBRW5DLDZEQUE2RDtBQUM3RCxTQUFTLFdBQVcsQ0FBQyxPQUFlO0lBQ2xDLE9BQU8sTUFBTSxDQUFDLGlCQUFpQixDQUFDLEVBQUUsU0FBUyxFQUFFLHVCQUF1QixFQUFFLEVBQUUsT0FBTyxDQUFDLElBQUksT0FBTyxDQUFDO0FBQzlGLENBQUM7QUFFRCxrRUFBa0U7QUFDbEUsU0FBUyxVQUFVLENBQUMsT0FBcUIsRUFBRSxJQUFZO0lBQ3JELE1BQU0sSUFBSSxHQUFpRDtRQUN6RCxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUM7UUFDZCxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM3QixDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM5QixDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNoQyxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsT0FBTyxDQUFDO1FBQzVCLENBQUMsYUFBYSxFQUFFLE9BQU8sQ0FBQyxXQUFXLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzNFLENBQUMsTUFBTSxFQUFFLElBQUksSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUM7S0FDbkMsQ0FBQztJQUNGLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBMkIsRUFBRSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3hFLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxnQkFBZ0IsQ0FDcEMsT0FBcUIsRUFDckIsSUFBWSxFQUNaLEdBQVcsRUFDWCxLQUFrQixFQUNsQixPQUE4QjtJQUU5QixNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ2xDLE1BQU0sS0FBSyxDQUFDLE1BQU0sRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ3pDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksV0FBVyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDaEYsTUFBTSxJQUFJLEdBQUcsTUFBTSxlQUFlLENBQUM7UUFDakMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxPQUFPO1FBQ3hCLE9BQU8sRUFBRSxVQUFVLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQztRQUNsQyxJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUk7UUFDbEIsTUFBTSxFQUFFLG9GQUFvRjtRQUM1RixHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDM0IsMkVBQTJFO1FBQzNFLDREQUE0RDtRQUM1RCxHQUFHLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7S0FDMUQsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxTQUFTLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztJQUNwQyxPQUFPLElBQUksQ0FBQztBQUNkLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEZpbGVzeXN0ZW0gb3V0Ym94IGZvciB0aGUgbm8tU01UUCBmYWxsYmFjazoge0BsaW5rIHdyaXRlT3V0Ym94RW1haWx9XG4gKiBwZXJzaXN0cyBvbmUgZHJhZnRlZCBtZXNzYWdlIGFzIGEgc3RhbmRhbG9uZSBIVE1MIGZpbGUgdW5kZXJcbiAqIGA8ZGlyPi88ZnJvbT4vPHRpbWVzdGFtcD4tPHN1YmplY3Qtc2x1Zz4uaHRtbGAgaW5zdGVhZCBvZiBzZW5kaW5nIGl0LlxuICogVGhpcyBsZXRzIHRoZSBhcHByb3ZhbCBmbG93IGFuZCBhZ2VudHMgYmUgZXhlcmNpc2VkIGVuZC10by1lbmQgd2l0aFxuICogemVybyBlbWFpbCBjb25maWd1cmF0aW9uIC0gb3BlbiB0aGUgZmlsZSBpbiBhIGJyb3dzZXIgdG8gc2VlIGV4YWN0bHlcbiAqIHdoYXQgd291bGQgaGF2ZSBnb25lIG91dCAodGhlIEhUTUwgbWF0Y2hlcyB0aGUgU01UUCBzZW5kLCBoZWFkZXJzXG4gKiB0YWJsZSBhc2lkZSkuIFRoZSBib2R5IGlzIHJlbmRlcmVkICsgc3R5bGUtaW5saW5lZCBieVxuICoge0BsaW5rIHJlbmRlckVtYWlsSHRtbH0uIEF0dGFjaG1lbnRzIGFyZSBsaXN0ZWQgYnkgZmlsZW5hbWUgaW4gdGhlXG4gKiBoZWFkZXIgdGFibGUgYnV0IG5vdCB3cml0dGVuIHRvIGRpc2sgLSB0aGUgb3V0Ym94IHByZXZpZXdzIHRoZVxuICogZW52ZWxvcGUsIGl0IGRvZXNuJ3QgcmVwcm9kdWNlIHRoZSB3aXJlIHBheWxvYWQuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IG1rZGlyLCB3cml0ZUZpbGUgfSBmcm9tIFwibm9kZTpmcy9wcm9taXNlc1wiO1xuaW1wb3J0IHsgam9pbiwgcmVzb2x2ZSB9IGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IHN0cmluZyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgdHlwZSB7IEVtYWlsTWVzc2FnZSB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1lbWFpbFwiO1xuaW1wb3J0IHR5cGUgeyBFbWFpbEJyYW5kIH0gZnJvbSBcIi4vYnJhbmQudHNcIjtcbmltcG9ydCB7IHJlbmRlckVtYWlsSHRtbCB9IGZyb20gXCIuL2VtYWlsLWh0bWwudHNcIjtcblxuLyoqXG4gKiBMb25nZXN0IHN1YmplY3Qgc2x1ZyBrZXB0IGluIGFuIG91dGJveCBmaWxlIG5hbWUsIGxlYXZpbmcgcm9vbSBmb3IgdGhlXG4gKiB0aW1lc3RhbXAgcHJlZml4IGFuZCBleHRlbnNpb24gaW5zaWRlIGNvbW1vbiBmaWxlc3lzdGVtIG5hbWUgbGltaXRzLlxuICovXG5jb25zdCBTVUJKRUNUX1NMVUdfTUFYX0xFTkdUSCA9IDQ4O1xuXG4vKiogRmlsZXN5c3RlbS1zYWZlIHNsdWcgb2YgdGhlIHN1YmplY3QgZm9yIHRoZSBmaWxlIG5hbWUuICovXG5mdW5jdGlvbiBzdWJqZWN0U2x1ZyhzdWJqZWN0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gc3RyaW5nLnRvU2x1Z1dpdGhPcHRpb25zKHsgbWF4TGVuZ3RoOiBTVUJKRUNUX1NMVUdfTUFYX0xFTkdUSCB9LCBzdWJqZWN0KSB8fCBcImVtYWlsXCI7XG59XG5cbi8qKiBUaGUgZW52ZWxvcGUgcm93cyBzaG93biBhYm92ZSB0aGUgYm9keSBpbiB0aGUgcHJldmlldyBmaWxlLiAqL1xuZnVuY3Rpb24gaGVhZGVyUm93cyhtZXNzYWdlOiBFbWFpbE1lc3NhZ2UsIGZyb206IHN0cmluZyk6IEFycmF5PHJlYWRvbmx5IFtzdHJpbmcsIHN0cmluZ10+IHtcbiAgY29uc3Qgcm93czogQXJyYXk8cmVhZG9ubHkgW3N0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkXT4gPSBbXG4gICAgW1wiRnJvbVwiLCBmcm9tXSxcbiAgICBbXCJUb1wiLCBtZXNzYWdlLnRvLmpvaW4oXCIsIFwiKV0sXG4gICAgW1wiQ2NcIiwgbWVzc2FnZS5jYz8uam9pbihcIiwgXCIpXSxcbiAgICBbXCJCY2NcIiwgbWVzc2FnZS5iY2M/LmpvaW4oXCIsIFwiKV0sXG4gICAgW1wiU3ViamVjdFwiLCBtZXNzYWdlLnN1YmplY3RdLFxuICAgIFtcIkF0dGFjaG1lbnRzXCIsIG1lc3NhZ2UuYXR0YWNobWVudHM/Lm1hcCgoYXR0KSA9PiBhdHQuZmlsZW5hbWUpLmpvaW4oXCIsIFwiKV0sXG4gICAgW1wiRGF0ZVwiLCBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCldLFxuICBdO1xuICByZXR1cm4gcm93cy5maWx0ZXIoKHJvdyk6IHJvdyBpcyBbc3RyaW5nLCBzdHJpbmddID0+IEJvb2xlYW4ocm93WzFdKSk7XG59XG5cbi8qKlxuICogV3JpdGUgb25lIG1lc3NhZ2UgYXMgSFRNTCB1bmRlciBgPGRpcj4vPGZyb20+L2AgYW5kIHJldHVybiB0aGVcbiAqIGFic29sdXRlIHBhdGguIFRoZSBwZXItc2VuZGVyIGZvbGRlciBtaXJyb3JzIHRoZSBTTVRQIGBGcm9tYCwgc28gdGVzdFxuICogb3V0cHV0IGdyb3VwcyBieSB3aG8gdGhlIG1lc3NhZ2Ugd291bGQgaGF2ZSBiZWVuIHNlbnQgYXMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB3cml0ZU91dGJveEVtYWlsKFxuICBtZXNzYWdlOiBFbWFpbE1lc3NhZ2UsXG4gIGZyb206IHN0cmluZyxcbiAgZGlyOiBzdHJpbmcsXG4gIGJyYW5kPzogRW1haWxCcmFuZCxcbiAgb3B0aW9ucz86IHsgdHJhaWxlcj86IHN0cmluZyB9LFxuKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc3QgZm9sZGVyID0gcmVzb2x2ZShkaXIsIGZyb20pO1xuICBhd2FpdCBta2Rpcihmb2xkZXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICBjb25zdCBwYXRoID0gam9pbihmb2xkZXIsIGAke0RhdGUubm93KCl9LSR7c3ViamVjdFNsdWcobWVzc2FnZS5zdWJqZWN0KX0uaHRtbGApO1xuICBjb25zdCBodG1sID0gYXdhaXQgcmVuZGVyRW1haWxIdG1sKHtcbiAgICBzdWJqZWN0OiBtZXNzYWdlLnN1YmplY3QsXG4gICAgaGVhZGVyczogaGVhZGVyUm93cyhtZXNzYWdlLCBmcm9tKSxcbiAgICBib2R5OiBtZXNzYWdlLmJvZHksXG4gICAgZm9vdGVyOiBcIkxvY2FsIG91dGJveCBwcmV2aWV3IC0gd3JpdHRlbiB0byBkaXNrLCBub3Qgc2VudCAobm8gU01UUCBjcmVkZW50aWFscyBjb25maWd1cmVkKS5cIixcbiAgICAuLi4oYnJhbmQgPyB7IGJyYW5kIH0gOiB7fSksXG4gICAgLy8gUHJlc2VydmVkIHNvIHRoZSBwcmV2aWV3IHNob3dzIHRoZSB0cmFpbGVyIGluIHRoZSBzYW1lIHBsYWNlIGEgcmVhbCBzZW5kXG4gICAgLy8gcHV0cyBpdCAtIHRoZSB3aG9sZSBwb2ludCBiZWluZyB0aGF0IGl0IGlzIHRoZSBMQVNUIGxpbmUuXG4gICAgLi4uKG9wdGlvbnM/LnRyYWlsZXIgPyB7IHRyYWlsZXI6IG9wdGlvbnMudHJhaWxlciB9IDoge30pLFxuICB9KTtcbiAgYXdhaXQgd3JpdGVGaWxlKHBhdGgsIGh0bWwsIFwidXRmOFwiKTtcbiAgcmV0dXJuIHBhdGg7XG59XG4iXX0=
60
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3V0Ym94LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL291dGJveC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7OztHQWFHO0FBRUgsT0FBTyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNwRCxPQUFPLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUMxQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFHaEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRWxEOzs7R0FHRztBQUNILE1BQU0sdUJBQXVCLEdBQUcsRUFBRSxDQUFDO0FBRW5DLDZEQUE2RDtBQUM3RCxTQUFTLFdBQVcsQ0FBQyxPQUFlO0lBQ2xDLE9BQU8sTUFBTSxDQUFDLGlCQUFpQixDQUFDLEVBQUUsU0FBUyxFQUFFLHVCQUF1QixFQUFFLEVBQUUsT0FBTyxDQUFDLElBQUksT0FBTyxDQUFDO0FBQzlGLENBQUM7QUFFRCxrRUFBa0U7QUFDbEUsU0FBUyxVQUFVLENBQUMsT0FBcUIsRUFBRSxJQUFZO0lBQ3JELE1BQU0sSUFBSSxHQUFpRDtRQUN6RCxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUM7UUFDZCxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM3QixDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM5QixDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNoQyxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsT0FBTyxDQUFDO1FBQzVCLENBQUMsYUFBYSxFQUFFLE9BQU8sQ0FBQyxXQUFXLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzNFLENBQUMsTUFBTSxFQUFFLElBQUksSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUM7S0FDbkMsQ0FBQztJQUNGLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBMkIsRUFBRSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3hFLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxnQkFBZ0IsQ0FDcEMsT0FBcUIsRUFDckIsSUFBWSxFQUNaLEdBQVcsRUFDWCxLQUFrQjtJQUVsQixNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ2xDLE1BQU0sS0FBSyxDQUFDLE1BQU0sRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ3pDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksV0FBVyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDaEYsTUFBTSxJQUFJLEdBQUcsTUFBTSxlQUFlLENBQUM7UUFDakMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxPQUFPO1FBQ3hCLE9BQU8sRUFBRSxVQUFVLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQztRQUNsQyxJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUk7UUFDbEIsTUFBTSxFQUFFLG9GQUFvRjtRQUM1RixHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7S0FDNUIsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxTQUFTLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztJQUNwQyxPQUFPLElBQUksQ0FBQztBQUNkLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEZpbGVzeXN0ZW0gb3V0Ym94IGZvciB0aGUgbm8tU01UUCBmYWxsYmFjazoge0BsaW5rIHdyaXRlT3V0Ym94RW1haWx9XG4gKiBwZXJzaXN0cyBvbmUgZHJhZnRlZCBtZXNzYWdlIGFzIGEgc3RhbmRhbG9uZSBIVE1MIGZpbGUgdW5kZXJcbiAqIGA8ZGlyPi88ZnJvbT4vPHRpbWVzdGFtcD4tPHN1YmplY3Qtc2x1Zz4uaHRtbGAgaW5zdGVhZCBvZiBzZW5kaW5nIGl0LlxuICogVGhpcyBsZXRzIHRoZSBhcHByb3ZhbCBmbG93IGFuZCBhZ2VudHMgYmUgZXhlcmNpc2VkIGVuZC10by1lbmQgd2l0aFxuICogemVybyBlbWFpbCBjb25maWd1cmF0aW9uIC0gb3BlbiB0aGUgZmlsZSBpbiBhIGJyb3dzZXIgdG8gc2VlIGV4YWN0bHlcbiAqIHdoYXQgd291bGQgaGF2ZSBnb25lIG91dCAodGhlIEhUTUwgbWF0Y2hlcyB0aGUgU01UUCBzZW5kLCBoZWFkZXJzXG4gKiB0YWJsZSBhc2lkZSkuIFRoZSBib2R5IGlzIHJlbmRlcmVkICsgc3R5bGUtaW5saW5lZCBieVxuICoge0BsaW5rIHJlbmRlckVtYWlsSHRtbH0uIEF0dGFjaG1lbnRzIGFyZSBsaXN0ZWQgYnkgZmlsZW5hbWUgaW4gdGhlXG4gKiBoZWFkZXIgdGFibGUgYnV0IG5vdCB3cml0dGVuIHRvIGRpc2sgLSB0aGUgb3V0Ym94IHByZXZpZXdzIHRoZVxuICogZW52ZWxvcGUsIGl0IGRvZXNuJ3QgcmVwcm9kdWNlIHRoZSB3aXJlIHBheWxvYWQuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IG1rZGlyLCB3cml0ZUZpbGUgfSBmcm9tIFwibm9kZTpmcy9wcm9taXNlc1wiO1xuaW1wb3J0IHsgam9pbiwgcmVzb2x2ZSB9IGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IHN0cmluZyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgdHlwZSB7IEVtYWlsTWVzc2FnZSB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1lbWFpbFwiO1xuaW1wb3J0IHR5cGUgeyBFbWFpbEJyYW5kIH0gZnJvbSBcIi4vYnJhbmQudHNcIjtcbmltcG9ydCB7IHJlbmRlckVtYWlsSHRtbCB9IGZyb20gXCIuL2VtYWlsLWh0bWwudHNcIjtcblxuLyoqXG4gKiBMb25nZXN0IHN1YmplY3Qgc2x1ZyBrZXB0IGluIGFuIG91dGJveCBmaWxlIG5hbWUsIGxlYXZpbmcgcm9vbSBmb3IgdGhlXG4gKiB0aW1lc3RhbXAgcHJlZml4IGFuZCBleHRlbnNpb24gaW5zaWRlIGNvbW1vbiBmaWxlc3lzdGVtIG5hbWUgbGltaXRzLlxuICovXG5jb25zdCBTVUJKRUNUX1NMVUdfTUFYX0xFTkdUSCA9IDQ4O1xuXG4vKiogRmlsZXN5c3RlbS1zYWZlIHNsdWcgb2YgdGhlIHN1YmplY3QgZm9yIHRoZSBmaWxlIG5hbWUuICovXG5mdW5jdGlvbiBzdWJqZWN0U2x1ZyhzdWJqZWN0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gc3RyaW5nLnRvU2x1Z1dpdGhPcHRpb25zKHsgbWF4TGVuZ3RoOiBTVUJKRUNUX1NMVUdfTUFYX0xFTkdUSCB9LCBzdWJqZWN0KSB8fCBcImVtYWlsXCI7XG59XG5cbi8qKiBUaGUgZW52ZWxvcGUgcm93cyBzaG93biBhYm92ZSB0aGUgYm9keSBpbiB0aGUgcHJldmlldyBmaWxlLiAqL1xuZnVuY3Rpb24gaGVhZGVyUm93cyhtZXNzYWdlOiBFbWFpbE1lc3NhZ2UsIGZyb206IHN0cmluZyk6IEFycmF5PHJlYWRvbmx5IFtzdHJpbmcsIHN0cmluZ10+IHtcbiAgY29uc3Qgcm93czogQXJyYXk8cmVhZG9ubHkgW3N0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkXT4gPSBbXG4gICAgW1wiRnJvbVwiLCBmcm9tXSxcbiAgICBbXCJUb1wiLCBtZXNzYWdlLnRvLmpvaW4oXCIsIFwiKV0sXG4gICAgW1wiQ2NcIiwgbWVzc2FnZS5jYz8uam9pbihcIiwgXCIpXSxcbiAgICBbXCJCY2NcIiwgbWVzc2FnZS5iY2M/LmpvaW4oXCIsIFwiKV0sXG4gICAgW1wiU3ViamVjdFwiLCBtZXNzYWdlLnN1YmplY3RdLFxuICAgIFtcIkF0dGFjaG1lbnRzXCIsIG1lc3NhZ2UuYXR0YWNobWVudHM/Lm1hcCgoYXR0KSA9PiBhdHQuZmlsZW5hbWUpLmpvaW4oXCIsIFwiKV0sXG4gICAgW1wiRGF0ZVwiLCBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCldLFxuICBdO1xuICByZXR1cm4gcm93cy5maWx0ZXIoKHJvdyk6IHJvdyBpcyBbc3RyaW5nLCBzdHJpbmddID0+IEJvb2xlYW4ocm93WzFdKSk7XG59XG5cbi8qKlxuICogV3JpdGUgb25lIG1lc3NhZ2UgYXMgSFRNTCB1bmRlciBgPGRpcj4vPGZyb20+L2AgYW5kIHJldHVybiB0aGVcbiAqIGFic29sdXRlIHBhdGguIFRoZSBwZXItc2VuZGVyIGZvbGRlciBtaXJyb3JzIHRoZSBTTVRQIGBGcm9tYCwgc28gdGVzdFxuICogb3V0cHV0IGdyb3VwcyBieSB3aG8gdGhlIG1lc3NhZ2Ugd291bGQgaGF2ZSBiZWVuIHNlbnQgYXMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB3cml0ZU91dGJveEVtYWlsKFxuICBtZXNzYWdlOiBFbWFpbE1lc3NhZ2UsXG4gIGZyb206IHN0cmluZyxcbiAgZGlyOiBzdHJpbmcsXG4gIGJyYW5kPzogRW1haWxCcmFuZCxcbik6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IGZvbGRlciA9IHJlc29sdmUoZGlyLCBmcm9tKTtcbiAgYXdhaXQgbWtkaXIoZm9sZGVyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgY29uc3QgcGF0aCA9IGpvaW4oZm9sZGVyLCBgJHtEYXRlLm5vdygpfS0ke3N1YmplY3RTbHVnKG1lc3NhZ2Uuc3ViamVjdCl9Lmh0bWxgKTtcbiAgY29uc3QgaHRtbCA9IGF3YWl0IHJlbmRlckVtYWlsSHRtbCh7XG4gICAgc3ViamVjdDogbWVzc2FnZS5zdWJqZWN0LFxuICAgIGhlYWRlcnM6IGhlYWRlclJvd3MobWVzc2FnZSwgZnJvbSksXG4gICAgYm9keTogbWVzc2FnZS5ib2R5LFxuICAgIGZvb3RlcjogXCJMb2NhbCBvdXRib3ggcHJldmlldyAtIHdyaXR0ZW4gdG8gZGlzaywgbm90IHNlbnQgKG5vIFNNVFAgY3JlZGVudGlhbHMgY29uZmlndXJlZCkuXCIsXG4gICAgLi4uKGJyYW5kID8geyBicmFuZCB9IDoge30pLFxuICB9KTtcbiAgYXdhaXQgd3JpdGVGaWxlKHBhdGgsIGh0bWwsIFwidXRmOFwiKTtcbiAgcmV0dXJuIHBhdGg7XG59XG4iXX0=