@dbx-tools/cli-tunnel 0.6.57 → 0.6.58

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
@@ -30,6 +30,12 @@ address against an allow-list, verified by a code sent over
30
30
  Android detect a code from that shape and offer it directly from the
31
31
  notification; novel phrasing is what breaks the detection. Both MIME parts carry
32
32
  the code as visible text, never an image, and no trailer follows the copy.
33
+ - The code rides in the SUBJECT and the preheader, not only the body:
34
+ `123456 is your verification code`. Mobile autofill reads an incoming
35
+ NOTIFICATION, and a notification contains the sender, the subject, and a short
36
+ snippet - nothing else - so a code that lives only in the body is unreachable
37
+ however cleanly the body is shaped. See
38
+ [Why the code is in the subject](#why-the-code-is-in-the-subject).
33
39
  - The two MIME parts are built separately, on purpose. The HTML part is the full
34
40
  branded template with the code as a large styled heading; the `text/plain` part
35
41
  is authored directly, keeping the prompt and the code on ONE line
@@ -43,9 +49,16 @@ address against an allow-list, verified by a code sent over
43
49
  machine-generated code reaches nobody. `EMAIL_FROM` is not required - see
44
50
  [`@dbx-tools/email`](../../node/email#sender-addresses).
45
51
  - Email one-time-code gate: a 6-digit code stored as a SHA-256 hash with an
46
- attempt counter, verified in constant time, in AppKit's `CacheManager` (memory
47
- by default, Lakebase when the app configures persistent `CacheStorage`) so TTL
48
- expiry and eviction are the cache's job.
52
+ attempt counter, verified in constant time, in AppKit's `CacheManager` (Lakebase
53
+ when a database is bound to the deployment, else memory) so TTL expiry and
54
+ eviction are the cache's job.
55
+ - The gate resolves Lakebase for itself, so its cache is actually persistent. The
56
+ gate is its own tiny AppKit app with no `lakebase()` plugin (it has no server to
57
+ mount routes on), and AppKit only chooses Lakebase for the cache when a pool can
58
+ be built from `LAKEBASE_ENDPOINT` **and** `PGHOST` **and** `PGDATABASE` - while a
59
+ Databricks App `postgres` binding supplies only the first. The gate fills in the
60
+ rest at boot, and skips entirely when nothing is bound rather than creating
61
+ infrastructure on someone else's behalf.
49
62
  - HS256 session JWT (via `jose`) carrying only the email, signed with a key that
50
63
  is PERSISTED in AppKit's cache for 30 days - so a signed-in browser stays signed
51
64
  in across the restarts a tunnel sees whenever the app it wraps reloads. An
@@ -151,6 +164,15 @@ Resolution order:
151
164
  across restarts - which a tunnel does often, since it restarts whenever the app
152
165
  it wraps reloads. On the default in-memory cache the key is per-process, the
153
166
  same as having no secret at all.
167
+
168
+ Getting that persistence is not automatic, and the gate does the work at boot:
169
+ it resolves `LAKEBASE_ENDPOINT` into the `PGHOST` / `PGDATABASE` the cache's
170
+ pool also needs. Without it AppKit cannot build the pool, silently uses an
171
+ in-memory cache, and every redeploy signs everyone out - so the startup log
172
+ says which one you got (`lakebase resolved for the gate cache`, or
173
+ `the gate cache stays in memory`). Bind a `postgres` resource to the app to
174
+ get the persistent path.
175
+
154
176
  3. **An ephemeral per-process key**, when there is no secret and no reachable
155
177
  cache. Sessions do not survive a restart, but the gate still serves: the key
156
178
  only validates an ALREADY-issued session, so losing it costs sessions, never
@@ -165,6 +187,35 @@ the one it minted. Set `TUNNEL_AUTH_JWT_SECRET` to remove the race entirely.
165
187
  purpose - a key that expired before the cookies it signed would sign everyone out
166
188
  for no reason.
167
189
 
190
+ ## Why The Code Is In The Subject
191
+
192
+ The subject line the gate SENDS is `123456 is your verification code` -
193
+ `--subject` is the template the code is spliced into, not the literal line.
194
+
195
+ Mobile autofill does not read the email; it reads the NOTIFICATION. iOS scans
196
+ incoming notification text for a code and offers to fill it - natively for
197
+ Messages and Mail, and since iOS 26 for any app's notification, which is what
198
+ finally made Gmail work. A notification carries the sender, the subject, and a
199
+ short snippet. That is all. A code sitting in the body is invisible to it no
200
+ matter how carefully the body is formatted, which is why a perfectly shaped
201
+ `text/plain` part alone produced no prompt in Gmail.
202
+
203
+ So the code goes in both strings a notification actually shows:
204
+
205
+ - **The subject**, code FIRST, because a notification and an inbox row both
206
+ truncate: `123456 is your verification code` survives the cut wherever it lands,
207
+ and keeps the code in the same sentence as the words the heuristics look for.
208
+ A subject that does not use the conventional `Your ...` phrasing is treated as
209
+ deliberate and only prefixed (`123456 - Acme Ops access`).
210
+ - **The preheader**, the hidden snippet a client shows beside the subject and puts
211
+ in the notification body, repeating the prompt with the code
212
+ (`Your verification code is: 123456`).
213
+
214
+ The body keeps the code as a large styled heading regardless, for a recipient
215
+ reading the mail rather than a notification. This is deliberately NOT Apple's
216
+ domain-bound `@domain #code` trailer, which binds a code to a single origin;
217
+ subject + preheader works across clients and needs no origin.
218
+
168
219
  ### Signing everyone out
169
220
 
170
221
  `--session-cutoff` / `TUNNEL_AUTH_SESSION_CUTOFF` invalidates every session issued
package/lib/src/app.d.ts CHANGED
@@ -3,8 +3,9 @@
3
3
  *
4
4
  * There is no HTTP server here: the tunnel proxy is the server, and it calls the
5
5
  * gate handlers in-process. `createApp` is used only for what it auto-wires:
6
- * - `CacheManager` (memory, or Lakebase when the deploy configures persistent
7
- * cache storage) - which the OTP `CodeStore` uses for storage + TTL eviction;
6
+ * - `CacheManager` (Lakebase when this process can reach it, else memory) -
7
+ * which the OTP `CodeStore` and the session signing key use for storage + TTL
8
+ * eviction;
8
9
  * - the `email()` transport (SMTP / outbox), primed from env, so `sendCode` can
9
10
  * deliver the one-time code;
10
11
  * - dbx-tools auto-configuration + branding via `@dbx-tools/appkit`.
@@ -59,6 +60,69 @@ export declare function codeEmailHtmlBody(code: string, opts: CodeCopy): string;
59
60
  * code to one origin and is not what the broadly-compatible shape needs.
60
61
  */
61
62
  export declare function codeEmailTextBody(code: string, opts: CodeCopy): string;
63
+ /**
64
+ * The SUBJECT line, with the code in it: `"123456 is your verification code"`.
65
+ *
66
+ * The code has to be here, not only in the body, because of what mobile autofill
67
+ * actually reads. iOS offers a code from an incoming NOTIFICATION - natively for
68
+ * Messages and Mail, and since iOS 26 for any app's notification text, which is
69
+ * what finally made Gmail work - and a notification contains the sender, the
70
+ * subject, and a short snippet. Nothing else. A code that lives in the body is
71
+ * invisible to it, however cleanly the body is formatted, which is why a perfectly
72
+ * shaped `text/plain` part still produced no autofill prompt in Gmail.
73
+ *
74
+ * `<code> is your <thing>` rather than `<thing>: <code>` because the leading code
75
+ * survives TRUNCATION: a notification and an inbox list both cut the subject, and
76
+ * the platform heuristics want the code in the same sentence as a recognized
77
+ * prompt ("code", "verification"). Putting it first keeps both intact no matter
78
+ * where the cut lands.
79
+ *
80
+ * `subject` is the configured line ("Your verification code"), lower-cased at its
81
+ * first word so the sentence reads naturally, and left ALONE when it does not look
82
+ * like the conventional phrasing - an operator who set a deliberate subject gets
83
+ * theirs with the code prefixed, not a mangled hybrid.
84
+ */
85
+ export declare function codeEmailSubject(code: string, subject: string): string;
86
+ /**
87
+ * The PREHEADER: the snippet beside the subject in an inbox list, and the body of
88
+ * the push notification. Carries the code for the same reason the subject does -
89
+ * it is the other half of what a notification shows - and repeats the prompt
90
+ * wording so a heuristic scanning the snippet alone finds a code next to a phrase
91
+ * it recognizes.
92
+ */
93
+ export declare function codeEmailPreview(code: string, opts: CodeCopy): string;
94
+ /**
95
+ * Fill in the Lakebase connection env AppKit's cache needs, so `CacheManager`
96
+ * chooses PERSISTENT storage instead of memory.
97
+ *
98
+ * This is what makes the gate's session signing key and outstanding one-time
99
+ * codes survive a restart, and it has to be done explicitly here. AppKit picks
100
+ * Lakebase for the cache only when `createLakebasePool()` succeeds, and that pool
101
+ * reads FOUR things off `process.env`: `LAKEBASE_ENDPOINT`, `PGHOST`,
102
+ * `PGDATABASE`, and a username (`PGUSER`, or `DATABRICKS_CLIENT_ID` for a service
103
+ * principal). A Databricks App `postgres` resource binding supplies only
104
+ * `LAKEBASE_ENDPOINT`. The resolver turns that one value into the host and
105
+ * database; the username is looked up separately, because missing it fails pool
106
+ * construction just as hard as a missing host - and it is what a LOCAL run (a
107
+ * developer on a PAT, with no `DATABRICKS_CLIENT_ID`) is always missing. Without
108
+ * all four the pool cannot be built, the cache silently degrades to in-memory, and
109
+ * every redeploy signs out every user (the exact symptom this exists to prevent).
110
+ *
111
+ * `@dbx-tools/appkit`'s `createApp` would normally do this via `autoConfigure`,
112
+ * but it gates that on a `lakebase()` plugin being registered - and this app
113
+ * registers none, because it has no server to mount Lakebase routes on. Calling
114
+ * the resolver directly also lets the gate be stricter than `autoConfigure` is:
115
+ *
116
+ * - It runs ONLY when a Lakebase env var is present. A tunnel is a wrapper
117
+ * around someone else's app and must not invent infrastructure, so with
118
+ * nothing bound it skips rather than falling through the resolver's
119
+ * list-or-CREATE-a-project path.
120
+ * - `autoCreate: false` for the same reason, in case a project happens to exist.
121
+ * - Every failure is a WARNING, never a throw. The cache is an optimization for
122
+ * session durability; admission still requires a code delivered to an
123
+ * allow-listed address, so a gate with a memory cache is safe, just forgetful.
124
+ */
125
+ export declare function resolveCacheStorageEnv(): Promise<boolean>;
62
126
  /**
63
127
  * Boot the gate app and return the API the proxy calls. Throws when email is not
64
128
  * in SMTP mode (no way to deliver a code) so a misconfigured gate fails fast at
package/lib/src/app.js CHANGED
@@ -3,8 +3,9 @@
3
3
  *
4
4
  * There is no HTTP server here: the tunnel proxy is the server, and it calls the
5
5
  * gate handlers in-process. `createApp` is used only for what it auto-wires:
6
- * - `CacheManager` (memory, or Lakebase when the deploy configures persistent
7
- * cache storage) - which the OTP `CodeStore` uses for storage + TTL eviction;
6
+ * - `CacheManager` (Lakebase when this process can reach it, else memory) -
7
+ * which the OTP `CodeStore` and the session signing key use for storage + TTL
8
+ * eviction;
8
9
  * - the `email()` transport (SMTP / outbox), primed from env, so `sendCode` can
9
10
  * deliver the one-time code;
10
11
  * - dbx-tools auto-configuration + branding via `@dbx-tools/appkit`.
@@ -23,10 +24,11 @@
23
24
  *
24
25
  * @module
25
26
  */
26
- import { createApp as createAppNs } from "@dbx-tools/appkit";
27
+ import { getUsernameWithApiLookup } from "@databricks/appkit";
28
+ import { createApp as createAppNs, lakebaseResolver } from "@dbx-tools/appkit";
27
29
  import { brand as nodeBrand } from "@dbx-tools/core";
28
30
  import { brand as emailBrand, email, sender, transport } from "@dbx-tools/email";
29
- import { log, string } from "@dbx-tools/shared-core";
31
+ import { env, log, string } from "@dbx-tools/shared-core";
30
32
  import { authGate } from "./plugin.js";
31
33
  const logger = log.logger("tunnel:app");
32
34
  /**
@@ -85,11 +87,120 @@ export function codeEmailTextBody(code, opts) {
85
87
  IGNORE_LINE,
86
88
  ].join("\n");
87
89
  }
90
+ /**
91
+ * The SUBJECT line, with the code in it: `"123456 is your verification code"`.
92
+ *
93
+ * The code has to be here, not only in the body, because of what mobile autofill
94
+ * actually reads. iOS offers a code from an incoming NOTIFICATION - natively for
95
+ * Messages and Mail, and since iOS 26 for any app's notification text, which is
96
+ * what finally made Gmail work - and a notification contains the sender, the
97
+ * subject, and a short snippet. Nothing else. A code that lives in the body is
98
+ * invisible to it, however cleanly the body is formatted, which is why a perfectly
99
+ * shaped `text/plain` part still produced no autofill prompt in Gmail.
100
+ *
101
+ * `<code> is your <thing>` rather than `<thing>: <code>` because the leading code
102
+ * survives TRUNCATION: a notification and an inbox list both cut the subject, and
103
+ * the platform heuristics want the code in the same sentence as a recognized
104
+ * prompt ("code", "verification"). Putting it first keeps both intact no matter
105
+ * where the cut lands.
106
+ *
107
+ * `subject` is the configured line ("Your verification code"), lower-cased at its
108
+ * first word so the sentence reads naturally, and left ALONE when it does not look
109
+ * like the conventional phrasing - an operator who set a deliberate subject gets
110
+ * theirs with the code prefixed, not a mangled hybrid.
111
+ */
112
+ export function codeEmailSubject(code, subject) {
113
+ const trimmed = subject.trim();
114
+ const conventional = /^your\s+/i.exec(trimmed);
115
+ const rest = conventional ? trimmed.slice(conventional[0].length) : trimmed;
116
+ return conventional ? `${code} is your ${rest}` : `${code} - ${trimmed}`;
117
+ }
118
+ /**
119
+ * The PREHEADER: the snippet beside the subject in an inbox list, and the body of
120
+ * the push notification. Carries the code for the same reason the subject does -
121
+ * it is the other half of what a notification shows - and repeats the prompt
122
+ * wording so a heuristic scanning the snippet alone finds a code next to a phrase
123
+ * it recognizes.
124
+ */
125
+ export function codeEmailPreview(code, opts) {
126
+ return `${opts.message} ${code}`;
127
+ }
88
128
  const { createApp } = createAppNs;
129
+ const { applyLakebaseToEnv, resolveLakebaseConnection } = lakebaseResolver;
89
130
  const { resolveSystemSenderAddress } = sender;
90
131
  const { getEmailRuntime, sendEmail } = transport;
91
132
  const { emailBrandFromContext } = emailBrand;
92
133
  const { loadBrandContext } = nodeBrand;
134
+ /**
135
+ * Env vars whose presence means a Lakebase database was bound to this deployment.
136
+ * `LAKEBASE_ENDPOINT` is what a Databricks App `postgres` resource binding sets;
137
+ * `PGHOST` is the local/manual spelling.
138
+ */
139
+ const LAKEBASE_ENV = ["LAKEBASE_ENDPOINT", "PGHOST"];
140
+ /**
141
+ * Upper bound on resolving the Lakebase connection. The gate is in the request
142
+ * path for every visitor, so a slow workspace API must not hold up boot
143
+ * indefinitely; a memory cache is a degraded gate, an unbooted one is no gate.
144
+ */
145
+ const LAKEBASE_RESOLVE_TIMEOUT_MS = 60_000;
146
+ /**
147
+ * Fill in the Lakebase connection env AppKit's cache needs, so `CacheManager`
148
+ * chooses PERSISTENT storage instead of memory.
149
+ *
150
+ * This is what makes the gate's session signing key and outstanding one-time
151
+ * codes survive a restart, and it has to be done explicitly here. AppKit picks
152
+ * Lakebase for the cache only when `createLakebasePool()` succeeds, and that pool
153
+ * reads FOUR things off `process.env`: `LAKEBASE_ENDPOINT`, `PGHOST`,
154
+ * `PGDATABASE`, and a username (`PGUSER`, or `DATABRICKS_CLIENT_ID` for a service
155
+ * principal). A Databricks App `postgres` resource binding supplies only
156
+ * `LAKEBASE_ENDPOINT`. The resolver turns that one value into the host and
157
+ * database; the username is looked up separately, because missing it fails pool
158
+ * construction just as hard as a missing host - and it is what a LOCAL run (a
159
+ * developer on a PAT, with no `DATABRICKS_CLIENT_ID`) is always missing. Without
160
+ * all four the pool cannot be built, the cache silently degrades to in-memory, and
161
+ * every redeploy signs out every user (the exact symptom this exists to prevent).
162
+ *
163
+ * `@dbx-tools/appkit`'s `createApp` would normally do this via `autoConfigure`,
164
+ * but it gates that on a `lakebase()` plugin being registered - and this app
165
+ * registers none, because it has no server to mount Lakebase routes on. Calling
166
+ * the resolver directly also lets the gate be stricter than `autoConfigure` is:
167
+ *
168
+ * - It runs ONLY when a Lakebase env var is present. A tunnel is a wrapper
169
+ * around someone else's app and must not invent infrastructure, so with
170
+ * nothing bound it skips rather than falling through the resolver's
171
+ * list-or-CREATE-a-project path.
172
+ * - `autoCreate: false` for the same reason, in case a project happens to exist.
173
+ * - Every failure is a WARNING, never a throw. The cache is an optimization for
174
+ * session durability; admission still requires a code delivered to an
175
+ * allow-listed address, so a gate with a memory cache is safe, just forgetful.
176
+ */
177
+ export async function resolveCacheStorageEnv() {
178
+ if (!env.text(LAKEBASE_ENV)) {
179
+ logger.info(`no ${env.name(LAKEBASE_ENV)} - the gate cache stays in memory; sessions and codes will not survive a restart`);
180
+ return false;
181
+ }
182
+ try {
183
+ const resolved = await resolveLakebaseConnection({ autoCreate: false }, AbortSignal.timeout(LAKEBASE_RESOLVE_TIMEOUT_MS));
184
+ applyLakebaseToEnv(resolved);
185
+ // `??=` so an explicitly configured PGUSER stays authoritative. The lookup
186
+ // falls back to the workspace API and returns undefined rather than throwing,
187
+ // so a failure here just leaves the pool to find its own username.
188
+ const user = await getUsernameWithApiLookup({});
189
+ if (user)
190
+ process.env.PGUSER ??= user;
191
+ logger.info("lakebase resolved for the gate cache", {
192
+ host: resolved.host,
193
+ database: resolved.database,
194
+ endpoint: resolved.endpoint,
195
+ user: process.env.PGUSER,
196
+ });
197
+ return true;
198
+ }
199
+ catch (error) {
200
+ logger.warn("could not resolve lakebase - the gate cache stays in memory; sessions and codes will not survive a restart", { error });
201
+ return false;
202
+ }
203
+ }
93
204
  /**
94
205
  * Boot the gate app and return the API the proxy calls. Throws when email is not
95
206
  * in SMTP mode (no way to deliver a code) so a misconfigured gate fails fast at
@@ -103,6 +214,10 @@ export async function startGateApp(config) {
103
214
  // display name the copy uses, so a deployment that themes its app themes its
104
215
  // sign-in email with it. An explicit `brandName` still wins (see below).
105
216
  const context = await loadBrandContext();
217
+ // Before `createApp`, because AppKit resolves the cache's storage during it and
218
+ // reads the connection out of `process.env` when it does. See the function's
219
+ // docs for why the gate resolves this itself.
220
+ await resolveCacheStorageEnv();
106
221
  // `sendCode` delivers the OTP through the email plugin's SHARED transport, which
107
222
  // the `email()` plugin primes during its `setup()` (awaited by `createApp`
108
223
  // below). Using the module-level `sendEmail` avoids a circular dependency on the
@@ -113,13 +228,20 @@ export async function startGateApp(config) {
113
228
  const from = resolveSystemSenderAddress(getEmailRuntime().config);
114
229
  await sendEmail({
115
230
  to: [to],
116
- subject: opts.subject,
231
+ // The code rides in the SUBJECT and the preheader, not just the body:
232
+ // those two strings are the whole of a push notification, and a
233
+ // notification is what mobile autofill reads. See `codeEmailSubject`.
234
+ subject: codeEmailSubject(code, opts.subject),
117
235
  body: codeEmailHtmlBody(code, opts),
118
- }, from, undefined, { text: codeEmailTextBody(code, opts) });
236
+ }, from, undefined, { text: codeEmailTextBody(code, opts), preview: codeEmailPreview(code, opts) });
119
237
  };
120
238
  // `createApp` namespaces each plugin's exports on the handle by manifest name;
121
239
  // `handle.authGate` is the in-process gate API the proxy drives.
240
+ //
241
+ // `autoConfigure: false` because {@link resolveCacheStorageEnv} above already
242
+ // did the one piece of it this app wants, on this app's terms.
122
243
  const handle = await createApp({
244
+ autoConfigure: false,
123
245
  plugins: [
124
246
  // Brand the code email from the resolved context, the same bridge every
125
247
  // other dbx-tools email surface uses (accent + font inlined, logo only when
@@ -143,4 +265,4 @@ export async function startGateApp(config) {
143
265
  logger.info("gate app ready (no server; proxy-driven)");
144
266
  return handle.authGate;
145
267
  }
146
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBd0JHO0FBRUgsT0FBTyxFQUFFLFNBQVMsSUFBSSxXQUFXLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsS0FBSyxJQUFJLFNBQVMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxLQUFLLElBQUksVUFBVSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDakYsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsUUFBUSxFQUErRCxNQUFNLGFBQWEsQ0FBQztBQUVwRyxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDO0FBRXhDOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSxTQUFTLENBQUMsT0FBZTtJQUN2QyxPQUFPLE9BQU8sSUFBSSxFQUFFLElBQUksT0FBTyxHQUFHLEVBQUUsS0FBSyxDQUFDO1FBQ3hDLENBQUMsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLE9BQU8sR0FBRyxFQUFFLEVBQUUsUUFBUSxDQUFDO1FBQzFDLENBQUMsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztBQUMxQyxDQUFDO0FBS0QsK0NBQStDO0FBQy9DLE1BQU0sV0FBVyxHQUFHLDhEQUE4RCxDQUFDO0FBRW5GOzs7R0FHRztBQUNILE1BQU0sVUFBVSxpQkFBaUIsQ0FBQyxJQUFZLEVBQUUsSUFBYztJQUM1RCxPQUFPO1FBQ0wsSUFBSSxDQUFDLE9BQU87UUFDWixFQUFFO1FBQ0YsTUFBTSxJQUFJLEVBQUU7UUFDWixFQUFFO1FBQ0Ysd0JBQXdCLFNBQVMsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUc7UUFDekQsRUFBRTtRQUNGLFdBQVc7S0FDWixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNmLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JHO0FBQ0gsTUFBTSxVQUFVLGlCQUFpQixDQUFDLElBQVksRUFBRSxJQUFjO0lBQzVELE9BQU87UUFDTCxHQUFHLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxFQUFFO1FBQ3pCLHdCQUF3QixTQUFTLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHO1FBQ3pELEVBQUU7UUFDRixXQUFXO0tBQ1osQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDZixDQUFDO0FBRUQsTUFBTSxFQUFFLFNBQVMsRUFBRSxHQUFHLFdBQVcsQ0FBQztBQUNsQyxNQUFNLEVBQUUsMEJBQTBCLEVBQUUsR0FBRyxNQUFNLENBQUM7QUFDOUMsTUFBTSxFQUFFLGVBQWUsRUFBRSxTQUFTLEVBQUUsR0FBRyxTQUFTLENBQUM7QUFDakQsTUFBTSxFQUFFLHFCQUFxQixFQUFFLEdBQUcsVUFBVSxDQUFDO0FBQzdDLE1BQU0sRUFBRSxnQkFBZ0IsRUFBRSxHQUFHLFNBQVMsQ0FBQztBQUV2Qzs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsWUFBWSxDQUFDLE1BQXNCO0lBQ3ZELDhFQUE4RTtJQUM5RSw4RUFBOEU7SUFDOUUsNkVBQTZFO0lBQzdFLDZFQUE2RTtJQUM3RSx5RUFBeUU7SUFDekUsTUFBTSxPQUFPLEdBQUcsTUFBTSxnQkFBZ0IsRUFBRSxDQUFDO0lBRXpDLGlGQUFpRjtJQUNqRiwyRUFBMkU7SUFDM0UsaUZBQWlGO0lBQ2pGLDhFQUE4RTtJQUM5RSwyRUFBMkU7SUFDM0UscUNBQXFDO0lBQ3JDLE1BQU0sUUFBUSxHQUE0QyxLQUFLLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsRUFBRTtRQUNqRixNQUFNLElBQUksR0FBRywwQkFBMEIsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNsRSxNQUFNLFNBQVMsQ0FDYjtZQUNFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUNSLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTztZQUNyQixJQUFJLEVBQUUsaUJBQWlCLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQztTQUNwQyxFQUNELElBQUksRUFDSixTQUFTLEVBQ1QsRUFBRSxJQUFJLEVBQUUsaUJBQWlCLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxFQUFFLENBQ3hDLENBQUM7SUFDSixDQUFDLENBQUM7SUFFRiwrRUFBK0U7SUFDL0UsaUVBQWlFO0lBQ2pFLE1BQU0sTUFBTSxHQUFHLE1BQU0sU0FBUyxDQUFDO1FBQzdCLE9BQU8sRUFBRTtZQUNQLHdFQUF3RTtZQUN4RSw0RUFBNEU7WUFDNUUsMEVBQTBFO1lBQzFFLEtBQUssQ0FBQyxFQUFFLEtBQUssRUFBRSxxQkFBcUIsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ2hELHdFQUF3RTtZQUN4RSw0RUFBNEU7WUFDNUUscUVBQXFFO1lBQ3JFLDJFQUEyRTtZQUMzRSxnRUFBZ0U7WUFDaEUsUUFBUSxDQUFDLEVBQUUsR0FBRyxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sQ0FBQyxTQUFTLElBQUksT0FBTyxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUUsQ0FBQztTQUMvRTtLQUNGLENBQUMsQ0FBQztJQUVILGlGQUFpRjtJQUNqRixnRkFBZ0Y7SUFDaEYsaUZBQWlGO0lBQ2pGLElBQUksZUFBZSxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxNQUFNLEVBQUUsQ0FBQztRQUM3QyxNQUFNLElBQUksS0FBSyxDQUNiLDhFQUE4RTtZQUM1RSwwR0FBMEcsQ0FDN0csQ0FBQztJQUNKLENBQUM7SUFFRCxNQUFNLENBQUMsSUFBSSxDQUFDLDBDQUEwQyxDQUFDLENBQUM7SUFDeEQsT0FBTyxNQUFNLENBQUMsUUFBdUIsQ0FBQztBQUN4QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUaGUgdHVubmVsIGdhdGUncyB0aW55IEFwcEtpdCBcImFwcFwiIC0gYGNyZWF0ZUFwcGAgV0lUSE9VVCBhIGBzZXJ2ZXIoKWAgcGx1Z2luLlxuICpcbiAqIFRoZXJlIGlzIG5vIEhUVFAgc2VydmVyIGhlcmU6IHRoZSB0dW5uZWwgcHJveHkgaXMgdGhlIHNlcnZlciwgYW5kIGl0IGNhbGxzIHRoZVxuICogZ2F0ZSBoYW5kbGVycyBpbi1wcm9jZXNzLiBgY3JlYXRlQXBwYCBpcyB1c2VkIG9ubHkgZm9yIHdoYXQgaXQgYXV0by13aXJlczpcbiAqICAgLSBgQ2FjaGVNYW5hZ2VyYCAobWVtb3J5LCBvciBMYWtlYmFzZSB3aGVuIHRoZSBkZXBsb3kgY29uZmlndXJlcyBwZXJzaXN0ZW50XG4gKiAgICAgY2FjaGUgc3RvcmFnZSkgLSB3aGljaCB0aGUgT1RQIGBDb2RlU3RvcmVgIHVzZXMgZm9yIHN0b3JhZ2UgKyBUVEwgZXZpY3Rpb247XG4gKiAgIC0gdGhlIGBlbWFpbCgpYCB0cmFuc3BvcnQgKFNNVFAgLyBvdXRib3gpLCBwcmltZWQgZnJvbSBlbnYsIHNvIGBzZW5kQ29kZWAgY2FuXG4gKiAgICAgZGVsaXZlciB0aGUgb25lLXRpbWUgY29kZTtcbiAqICAgLSBkYngtdG9vbHMgYXV0by1jb25maWd1cmF0aW9uICsgYnJhbmRpbmcgdmlhIGBAZGJ4LXRvb2xzL2FwcGtpdGAuXG4gKlxuICogSXQgcmV0dXJucyB0aGUge0BsaW5rIEF1dGhHYXRlQXBpfSB0aGUgcHJveHkgZHJpdmVzLiBgc2VuZENvZGVgIGlzIHdpcmVkIGhlcmVcbiAqICh0aGUgcGx1Z2luIGNhbid0IHJlc29sdmUgSE9XIHRvIHNlbmQgb24gaXRzIG93bikgdG8gdGhlIGVtYWlsIHBsdWdpbidzXG4gKiB0cmFuc3BvcnQuIEEgc2lnbi1pbiBjb2RlIGlzIFNZU1RFTSBtYWlsIC0gbm8gb24tYmVoYWxmLW9mIHVzZXIgYXNrZWQgZm9yIGl0XG4gKiBhbmQgbm8gcmVwbHkgdG8gaXQgcmVhY2hlcyBhbnlvbmUgLSBzbyBpdCBzZW5kcyBmcm9tIHRoZSBlbWFpbCBjb25maWcnc1xuICogZG8tbm90LXJlcGx5IGFkZHJlc3MgKGBuby1yZXBseUBFTUFJTF9ET01BSU5gIHVubGVzcyBFTUFJTF9TWVNURU1fRlJPTSBuYW1lc1xuICogYW5vdGhlcikuXG4gKlxuICogRkFJTCBGQVNUOiBhIGdhdGUgdGhhdCBjYW4ndCBlbWFpbCBhIGNvZGUgaXMgdXNlbGVzcywgc28gaWYgZW1haWwgZG9lcyBub3RcbiAqIHJlc29sdmUgdG8gU01UUCBtb2RlIChyZWFsIGRlbGl2ZXJ5KSwgdGhpcyB0aHJvd3MgLSB1bmxlc3MgYGluc2VjdXJlYCBpcyBzZXRcbiAqIChgLS1pbnNlY3VyZWAgLyBgVFVOTkVMX0lOU0VDVVJFPXRydWVgKSwgaW4gd2hpY2ggY2FzZSB0aGUgY2FsbGVyIHJ1bnMgdGhlXG4gKiB0dW5uZWwgT1BFTiB3aXRoIG5vIGdhdGUuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IGNyZWF0ZUFwcCBhcyBjcmVhdGVBcHBOcyB9IGZyb20gXCJAZGJ4LXRvb2xzL2FwcGtpdFwiO1xuaW1wb3J0IHsgYnJhbmQgYXMgbm9kZUJyYW5kIH0gZnJvbSBcIkBkYngtdG9vbHMvY29yZVwiO1xuaW1wb3J0IHsgYnJhbmQgYXMgZW1haWxCcmFuZCwgZW1haWwsIHNlbmRlciwgdHJhbnNwb3J0IH0gZnJvbSBcIkBkYngtdG9vbHMvZW1haWxcIjtcbmltcG9ydCB7IGxvZywgc3RyaW5nIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB7IGF1dGhHYXRlLCB0eXBlIEF1dGhHYXRlQXBpLCB0eXBlIEF1dGhHYXRlQ29uZmlnLCB0eXBlIFNlbmRDb2RlT3B0aW9ucyB9IGZyb20gXCIuL3BsdWdpbi50c1wiO1xuXG5jb25zdCBsb2dnZXIgPSBsb2cubG9nZ2VyKFwidHVubmVsOmFwcFwiKTtcblxuLyoqXG4gKiBBIGNvZGUgVFRMIGFzIHRoZSBwbGFpbiBwaHJhc2UgdGhlIGVtYWlsIHN0YXRlcyAoXCIxMCBtaW51dGVzXCIsIFwiNDUgc2Vjb25kc1wiKS5cbiAqXG4gKiBXaG9sZSBtaW51dGVzIHJlYWQgYXMgbWludXRlczsgYW55dGhpbmcgZWxzZSBzdGF5cyBpbiBzZWNvbmRzIHJhdGhlciB0aGFuXG4gKiByb3VuZGluZywgc28gYSA5MC1zZWNvbmQgVFRMIGlzIG5vdCBhZHZlcnRpc2VkIGFzIFwiMSBtaW51dGVcIiBhbmQgYSByZWNpcGllbnQgaXNcbiAqIG5ldmVyIHRvbGQgdGhlIGNvZGUgbGl2ZXMgbG9uZ2VyIHRoYW4gaXQgZG9lcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGV4cGlyZXNJbihzZWNvbmRzOiBudW1iZXIpOiBzdHJpbmcge1xuICByZXR1cm4gc2Vjb25kcyA+PSA2MCAmJiBzZWNvbmRzICUgNjAgPT09IDBcbiAgICA/IHN0cmluZy5wbHVyYWxpemUoc2Vjb25kcyAvIDYwLCBcIm1pbnV0ZVwiKVxuICAgIDogc3RyaW5nLnBsdXJhbGl6ZShzZWNvbmRzLCBcInNlY29uZFwiKTtcbn1cblxuLyoqIFRoZSBwYXJ0cyBvZiB7QGxpbmsgU2VuZENvZGVPcHRpb25zfSB0aGUgY29kZSBlbWFpbCdzIGNvcHkgaXMgYnVpbHQgZnJvbS4gKi9cbnR5cGUgQ29kZUNvcHkgPSBQaWNrPFNlbmRDb2RlT3B0aW9ucywgXCJtZXNzYWdlXCIgfCBcImNvZGVUdGxTZWNvbmRzXCI+O1xuXG4vKiogVGhlIHJlYXNzdXJhbmNlIGxpbmUgY2xvc2luZyBib3RoIHBhcnRzLiAqL1xuY29uc3QgSUdOT1JFX0xJTkUgPSBcIklmIHlvdSBkaWQgbm90IHJlcXVlc3QgdGhpcyBjb2RlLCB5b3UgY2FuIGlnbm9yZSB0aGlzIGVtYWlsLlwiO1xuXG4vKipcbiAqIFRoZSBIVE1MIHBhcnQncyBzb3VyY2U6IHRoZSBmdWxsIGJyYW5kZWQgdGVtcGxhdGUsIHdpdGggdGhlIGNvZGUgYXMgYSBsYXJnZVxuICogc3R5bGVkIGhlYWRpbmcgKGAjIyBgIGlzIHdoYXQgbWFrZXMgaXQgcHJvbWluZW50IGluIGFuIGluYm94KS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvZGVFbWFpbEh0bWxCb2R5KGNvZGU6IHN0cmluZywgb3B0czogQ29kZUNvcHkpOiBzdHJpbmcge1xuICByZXR1cm4gW1xuICAgIG9wdHMubWVzc2FnZSxcbiAgICBcIlwiLFxuICAgIGAjIyAke2NvZGV9YCxcbiAgICBcIlwiLFxuICAgIGBUaGlzIGNvZGUgZXhwaXJlcyBpbiAke2V4cGlyZXNJbihvcHRzLmNvZGVUdGxTZWNvbmRzKX0uYCxcbiAgICBcIlwiLFxuICAgIElHTk9SRV9MSU5FLFxuICBdLmpvaW4oXCJcXG5cIik7XG59XG5cbi8qKlxuICogVGhlIGB0ZXh0L3BsYWluYCBwYXJ0LCBzdXBwbGllZCBFWFBMSUNJVExZIHJhdGhlciB0aGFuIHJlbmRlcmVkIGZyb20gdGhlIHRyZWVcbiAqIGFib3ZlLiBCb3RoIHBhcnRzIHNheSB0aGUgc2FtZSB0aGluZzsgb25seSB0aGUgbGluZSBsYXlvdXQgZGlmZmVycy5cbiAqXG4gKiBUaGUgcHJvbXB0IGFuZCB0aGUgY29kZSBzaGFyZSBPTkUgbGluZSAoXCJZb3VyIHZlcmlmaWNhdGlvbiBjb2RlIGlzOiAxMjM0NTZcIikuXG4gKiBUaGF0IHNpbmdsZS1saW5lIHNoYXBlIGlzIHdoYXQgaU9TLCBHbWFpbCwgT3V0bG9vaywgYW5kIEFuZHJvaWQgY29kZSBkZXRlY3Rpb25cbiAqIGtleXMgb24gbW9zdCByZWxpYWJseSAtIHRoZSBoZXVyaXN0aWNzIGxvb2sgZm9yIGEgY29kZSBpbiB0aGUgc2FtZSBzZW50ZW5jZSBhc1xuICogYSByZWNvZ25pemVkIHByb21wdCwgc28gc3BsaXR0aW5nIHRoZW0gYWNyb3NzIGxpbmVzIG1ha2VzIGRldGVjdGlvbiBkZXBlbmRlbnRcbiAqIG9uIHRoZSBjbGllbnQsIGFuZCBhbnkgYmxhbmsgbGluZSBiZXR3ZWVuIHRoZW0gZGVmZWF0cyBpdCBvdXRyaWdodC5cbiAqXG4gKiBUaGUgR0VORVJBVEVEIHRleHQgcGFydCBjYW5ub3QgaG9sZCB0aGF0IHNoYXBlIGF0IGFsbDogaXQgaXMgYSByZW5kZXJpbmcgb2YgdGhlXG4gKiBIVE1MLCBzbyBpdCBjYXJyaWVzIHRoZSBicmFuZCBoZWFkZXIvZm9vdGVyIGFuZCB0dXJucyB0aGUgY29kZSBoZWFkaW5nJ3MgQ1NTXG4gKiBtYXJnaW4gaW50byBibGFuayBsaW5lcywgYXJyaXZpbmcgYXMgYHByb21wdFxcblxcblxcbmNvZGVgLlxuICpcbiAqIFRoZSBjb2RlIGlzIHZpc2libGUgdGV4dCBpbiBCT1RIIHBhcnRzLCBuZXZlciBhbiBpbWFnZSwgc28gYSBjbGllbnQgc2NyYXBpbmdcbiAqIGVpdGhlciBvbmUgZmluZHMgaXQuIE5vIHRyYWlsZXIgbGluZSBmb2xsb3dzIHRoZSBjb3B5IC0gQXBwbGUncyBkb21haW4tYm91bmRcbiAqIGBAZG9tYWluICNjb2RlYCBmb290ZXIgaXMgZGVsaWJlcmF0ZWx5IE5PVCBlbWl0dGVkLCBzaW5jZSBpdCBjb25zdHJhaW5zIHRoZVxuICogY29kZSB0byBvbmUgb3JpZ2luIGFuZCBpcyBub3Qgd2hhdCB0aGUgYnJvYWRseS1jb21wYXRpYmxlIHNoYXBlIG5lZWRzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29kZUVtYWlsVGV4dEJvZHkoY29kZTogc3RyaW5nLCBvcHRzOiBDb2RlQ29weSk6IHN0cmluZyB7XG4gIHJldHVybiBbXG4gICAgYCR7b3B0cy5tZXNzYWdlfSAke2NvZGV9YCxcbiAgICBgVGhpcyBjb2RlIGV4cGlyZXMgaW4gJHtleHBpcmVzSW4ob3B0cy5jb2RlVHRsU2Vjb25kcyl9LmAsXG4gICAgXCJcIixcbiAgICBJR05PUkVfTElORSxcbiAgXS5qb2luKFwiXFxuXCIpO1xufVxuXG5jb25zdCB7IGNyZWF0ZUFwcCB9ID0gY3JlYXRlQXBwTnM7XG5jb25zdCB7IHJlc29sdmVTeXN0ZW1TZW5kZXJBZGRyZXNzIH0gPSBzZW5kZXI7XG5jb25zdCB7IGdldEVtYWlsUnVudGltZSwgc2VuZEVtYWlsIH0gPSB0cmFuc3BvcnQ7XG5jb25zdCB7IGVtYWlsQnJhbmRGcm9tQ29udGV4dCB9ID0gZW1haWxCcmFuZDtcbmNvbnN0IHsgbG9hZEJyYW5kQ29udGV4dCB9ID0gbm9kZUJyYW5kO1xuXG4vKipcbiAqIEJvb3QgdGhlIGdhdGUgYXBwIGFuZCByZXR1cm4gdGhlIEFQSSB0aGUgcHJveHkgY2FsbHMuIFRocm93cyB3aGVuIGVtYWlsIGlzIG5vdFxuICogaW4gU01UUCBtb2RlIChubyB3YXkgdG8gZGVsaXZlciBhIGNvZGUpIHNvIGEgbWlzY29uZmlndXJlZCBnYXRlIGZhaWxzIGZhc3QgYXRcbiAqIHN0YXJ0dXAgcmF0aGVyIHRoYW4gc2lsZW50bHkgYWNjZXB0aW5nIG5vYm9keTsgdGhlIGNhbGxlciBtYXkgY2F0Y2ggdGhpcyBhbmRcbiAqIGZhbGwgYmFjayB0byBpbnNlY3VyZS9vcGVuIG1vZGUgd2hlbiB0aGUgb3BlcmF0b3Igb3B0ZWQgaW4uXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzdGFydEdhdGVBcHAoY29uZmlnOiBBdXRoR2F0ZUNvbmZpZyk6IFByb21pc2U8QXV0aEdhdGVBcGk+IHtcbiAgLy8gVGhlIGhvc3QgYXBwJ3Mgb3duIGJyYW5kIChgYnJhbmRpbmcvYnJhbmQueWFtbGAgZGlzY292ZXJlZCBmcm9tIGN3ZCkgb3IgdGhlXG4gIC8vIGRieC10b29scyBkZWZhdWx0LiBUaGlzIGlzIHRoZSBPTkUgYnJhbmQgc291cmNlIGZvciB0aGUgZ2F0ZTogaXQgc3R5bGVzIHRoZVxuICAvLyBjb2RlIGVtYWlsIChhY2NlbnQgYmFuZCwgZm9udCwgbG9nbykgdmlhIHRoZSBlbWFpbCBwbHVnaW4gQU5EIHN1cHBsaWVzIHRoZVxuICAvLyBkaXNwbGF5IG5hbWUgdGhlIGNvcHkgdXNlcywgc28gYSBkZXBsb3ltZW50IHRoYXQgdGhlbWVzIGl0cyBhcHAgdGhlbWVzIGl0c1xuICAvLyBzaWduLWluIGVtYWlsIHdpdGggaXQuIEFuIGV4cGxpY2l0IGBicmFuZE5hbWVgIHN0aWxsIHdpbnMgKHNlZSBiZWxvdykuXG4gIGNvbnN0IGNvbnRleHQgPSBhd2FpdCBsb2FkQnJhbmRDb250ZXh0KCk7XG5cbiAgLy8gYHNlbmRDb2RlYCBkZWxpdmVycyB0aGUgT1RQIHRocm91Z2ggdGhlIGVtYWlsIHBsdWdpbidzIFNIQVJFRCB0cmFuc3BvcnQsIHdoaWNoXG4gIC8vIHRoZSBgZW1haWwoKWAgcGx1Z2luIHByaW1lcyBkdXJpbmcgaXRzIGBzZXR1cCgpYCAoYXdhaXRlZCBieSBgY3JlYXRlQXBwYFxuICAvLyBiZWxvdykuIFVzaW5nIHRoZSBtb2R1bGUtbGV2ZWwgYHNlbmRFbWFpbGAgYXZvaWRzIGEgY2lyY3VsYXIgZGVwZW5kZW5jeSBvbiB0aGVcbiAgLy8gYXBwIGhhbmRsZSdzIGluZmVycmVkIHR5cGUuIFRoZSBgRnJvbWAgaXMgdGhlIFNZU1RFTSBzZW5kZXI6IGEgdmVyaWZpY2F0aW9uXG4gIC8vIGNvZGUgaXMgbWFjaGluZS1nZW5lcmF0ZWQgYW5kIHVuYW5zd2VyYWJsZSwgc28gaXQgbXVzdCBub3QgYXJyaXZlIGZyb20gYVxuICAvLyBwZXJzb24ncyBhZGRyZXNzIGludml0aW5nIGEgcmVwbHkuXG4gIGNvbnN0IHNlbmRDb2RlOiBOb25OdWxsYWJsZTxBdXRoR2F0ZUNvbmZpZ1tcInNlbmRDb2RlXCJdPiA9IGFzeW5jICh0bywgY29kZSwgb3B0cykgPT4ge1xuICAgIGNvbnN0IGZyb20gPSByZXNvbHZlU3lzdGVtU2VuZGVyQWRkcmVzcyhnZXRFbWFpbFJ1bnRpbWUoKS5jb25maWcpO1xuICAgIGF3YWl0IHNlbmRFbWFpbChcbiAgICAgIHtcbiAgICAgICAgdG86IFt0b10sXG4gICAgICAgIHN1YmplY3Q6IG9wdHMuc3ViamVjdCxcbiAgICAgICAgYm9keTogY29kZUVtYWlsSHRtbEJvZHkoY29kZSwgb3B0cyksXG4gICAgICB9LFxuICAgICAgZnJvbSxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHsgdGV4dDogY29kZUVtYWlsVGV4dEJvZHkoY29kZSwgb3B0cykgfSxcbiAgICApO1xuICB9O1xuXG4gIC8vIGBjcmVhdGVBcHBgIG5hbWVzcGFjZXMgZWFjaCBwbHVnaW4ncyBleHBvcnRzIG9uIHRoZSBoYW5kbGUgYnkgbWFuaWZlc3QgbmFtZTtcbiAgLy8gYGhhbmRsZS5hdXRoR2F0ZWAgaXMgdGhlIGluLXByb2Nlc3MgZ2F0ZSBBUEkgdGhlIHByb3h5IGRyaXZlcy5cbiAgY29uc3QgaGFuZGxlID0gYXdhaXQgY3JlYXRlQXBwKHtcbiAgICBwbHVnaW5zOiBbXG4gICAgICAvLyBCcmFuZCB0aGUgY29kZSBlbWFpbCBmcm9tIHRoZSByZXNvbHZlZCBjb250ZXh0LCB0aGUgc2FtZSBicmlkZ2UgZXZlcnlcbiAgICAgIC8vIG90aGVyIGRieC10b29scyBlbWFpbCBzdXJmYWNlIHVzZXMgKGFjY2VudCArIGZvbnQgaW5saW5lZCwgbG9nbyBvbmx5IHdoZW5cbiAgICAgIC8vIGl0IGlzIGEgZmV0Y2hhYmxlIFVSTCAtIGEgcGFja2FnZS1leHBvcnQgcGF0aCBjYW5ub3QgbG9hZCBpbiBhbiBpbmJveCkuXG4gICAgICBlbWFpbCh7IGJyYW5kOiBlbWFpbEJyYW5kRnJvbUNvbnRleHQoY29udGV4dCkgfSksXG4gICAgICAvLyBgYnJhbmROYW1lYCBmYWxscyBiYWNrIHRvIHRoZSByZXNvbHZlZCBjb250ZXh0J3MgZGlzcGxheSBuYW1lLCBzbyB0aGVcbiAgICAgIC8vIGVtYWlsIGNvcHkgbmFtZXMgdGhlIGFwcCByYXRoZXIgdGhhbiBhIGdlbmVyaWMgcGxhY2Vob2xkZXIuIFNwZWxsZWQgYXMgYW5cbiAgICAgIC8vIGV4cGxpY2l0IGA/P2AgcmF0aGVyIHRoYW4gYSBrZXkgYmVmb3JlIGAuLi5jb25maWdgOiBjb21tYW5kZXIgc2V0c1xuICAgICAgLy8gYGJyYW5kTmFtZWAgb24gdGhlIG9wdGlvbnMgb2JqZWN0IHdoZXRoZXIgb3Igbm90IHRoZSBmbGFnIHdhcyBwYXNzZWQsIHNvXG4gICAgICAvLyBzcHJlYWRpbmcgaXQgd291bGQgY2xvYmJlciB0aGUgY29udGV4dCBuYW1lIHdpdGggYHVuZGVmaW5lZGAuXG4gICAgICBhdXRoR2F0ZSh7IC4uLmNvbmZpZywgYnJhbmROYW1lOiBjb25maWcuYnJhbmROYW1lID8/IGNvbnRleHQubmFtZSwgc2VuZENvZGUgfSksXG4gICAgXSxcbiAgfSk7XG5cbiAgLy8gRmFpbCBmYXN0OiB0aGUgZ2F0ZSBuZWVkcyBTTVRQIHRvIGVtYWlsIGNvZGVzLiBgZ2V0RW1haWxSdW50aW1lKClgIHJlc29sdmVzIHRvXG4gIC8vIGBtb2RlOiBcImZpbGVcImAgKG91dGJveCkgb3IgdGhyb3dzIHdoZW4gbm8gU01UUCBjcmVkcyBhcmUgY29uZmlndXJlZCAtIG5laXRoZXJcbiAgLy8gY2FuIGRlbGl2ZXIgdG8gYSByZWFsIGluYm94LCBzbyByZWZ1c2UgdG8gYnJpbmcgdXAgYSBnYXRlIHRoYXQgbGV0cyBub2JvZHkgaW4uXG4gIGlmIChnZXRFbWFpbFJ1bnRpbWUoKS5jb25maWcubW9kZSAhPT0gXCJzbXRwXCIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBcImVtYWlsIGlzIG5vdCBjb25maWd1cmVkIGZvciBTTVRQIGRlbGl2ZXJ5IC0gdGhlIE9UUCBnYXRlIGNhbm5vdCBzZW5kIGNvZGVzLiBcIiArXG4gICAgICAgIFwiU2V0IFNNVFBfSE9TVC9TTVRQX1VTRVIvU01UUF9QQVNTV09SRCwgb3IgcGFzcyAtLWluc2VjdXJlIC8gVFVOTkVMX0lOU0VDVVJFPXRydWUgdG8gcnVuIHRoZSB0dW5uZWwgb3Blbi5cIixcbiAgICApO1xuICB9XG5cbiAgbG9nZ2VyLmluZm8oXCJnYXRlIGFwcCByZWFkeSAobm8gc2VydmVyOyBwcm94eS1kcml2ZW4pXCIpO1xuICByZXR1cm4gaGFuZGxlLmF1dGhHYXRlIGFzIEF1dGhHYXRlQXBpO1xufVxuIl19
268
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXlCRztBQUVILE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzlELE9BQU8sRUFBRSxTQUFTLElBQUksV0FBVyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDL0UsT0FBTyxFQUFFLEtBQUssSUFBSSxTQUFTLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsS0FBSyxJQUFJLFVBQVUsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2pGLE9BQU8sRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzFELE9BQU8sRUFBRSxRQUFRLEVBQStELE1BQU0sYUFBYSxDQUFDO0FBRXBHLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUM7QUFFeEM7Ozs7OztHQU1HO0FBQ0gsTUFBTSxVQUFVLFNBQVMsQ0FBQyxPQUFlO0lBQ3ZDLE9BQU8sT0FBTyxJQUFJLEVBQUUsSUFBSSxPQUFPLEdBQUcsRUFBRSxLQUFLLENBQUM7UUFDeEMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsT0FBTyxHQUFHLEVBQUUsRUFBRSxRQUFRLENBQUM7UUFDMUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQzFDLENBQUM7QUFLRCwrQ0FBK0M7QUFDL0MsTUFBTSxXQUFXLEdBQUcsOERBQThELENBQUM7QUFFbkY7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLGlCQUFpQixDQUFDLElBQVksRUFBRSxJQUFjO0lBQzVELE9BQU87UUFDTCxJQUFJ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QUMsSUFBSSxDQUFDLDBDQUEwQyxDQUFDLENBQUM7SUFDeEQsT0FBTyxNQUFNLENBQUMsUUFBdUIsQ0FBQztBQUN4QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUaGUgdHVubmVsIGdhdGUncyB0aW55IEFwcEtpdCBcImFwcFwiIC0gYGNyZWF0ZUFwcGAgV0lUSE9VVCBhIGBzZXJ2ZXIoKWAgcGx1Z2luLlxuICpcbiAqIFRoZXJlIGlzIG5vIEhUVFAgc2VydmVyIGhlcmU6IHRoZSB0dW5uZWwgcHJveHkgaXMgdGhlIHNlcnZlciwgYW5kIGl0IGNhbGxzIHRoZVxuICogZ2F0ZSBoYW5kbGVycyBpbi1wcm9jZXNzLiBgY3JlYXRlQXBwYCBpcyB1c2VkIG9ubHkgZm9yIHdoYXQgaXQgYXV0by13aXJlczpcbiAqICAgLSBgQ2FjaGVNYW5hZ2VyYCAoTGFrZWJhc2Ugd2hlbiB0aGlzIHByb2Nlc3MgY2FuIHJlYWNoIGl0LCBlbHNlIG1lbW9yeSkgLVxuICogICAgIHdoaWNoIHRoZSBPVFAgYENvZGVTdG9yZWAgYW5kIHRoZSBzZXNzaW9uIHNpZ25pbmcga2V5IHVzZSBmb3Igc3RvcmFnZSArIFRUTFxuICogICAgIGV2aWN0aW9uO1xuICogICAtIHRoZSBgZW1haWwoKWAgdHJhbnNwb3J0IChTTVRQIC8gb3V0Ym94KSwgcHJpbWVkIGZyb20gZW52LCBzbyBgc2VuZENvZGVgIGNhblxuICogICAgIGRlbGl2ZXIgdGhlIG9uZS10aW1lIGNvZGU7XG4gKiAgIC0gZGJ4LXRvb2xzIGF1dG8tY29uZmlndXJhdGlvbiArIGJyYW5kaW5nIHZpYSBgQGRieC10b29scy9hcHBraXRgLlxuICpcbiAqIEl0IHJldHVybnMgdGhlIHtAbGluayBBdXRoR2F0ZUFwaX0gdGhlIHByb3h5IGRyaXZlcy4gYHNlbmRDb2RlYCBpcyB3aXJlZCBoZXJlXG4gKiAodGhlIHBsdWdpbiBjYW4ndCByZXNvbHZlIEhPVyB0byBzZW5kIG9uIGl0cyBvd24pIHRvIHRoZSBlbWFpbCBwbHVnaW4nc1xuICogdHJhbnNwb3J0LiBBIHNpZ24taW4gY29kZSBpcyBTWVNURU0gbWFpbCAtIG5vIG9uLWJlaGFsZi1vZiB1c2VyIGFza2VkIGZvciBpdFxuICogYW5kIG5vIHJlcGx5IHRvIGl0IHJlYWNoZXMgYW55b25lIC0gc28gaXQgc2VuZHMgZnJvbSB0aGUgZW1haWwgY29uZmlnJ3NcbiAqIGRvLW5vdC1yZXBseSBhZGRyZXNzIChgbm8tcmVwbHlARU1BSUxfRE9NQUlOYCB1bmxlc3MgRU1BSUxfU1lTVEVNX0ZST00gbmFtZXNcbiAqIGFub3RoZXIpLlxuICpcbiAqIEZBSUwgRkFTVDogYSBnYXRlIHRoYXQgY2FuJ3QgZW1haWwgYSBjb2RlIGlzIHVzZWxlc3MsIHNvIGlmIGVtYWlsIGRvZXMgbm90XG4gKiByZXNvbHZlIHRvIFNNVFAgbW9kZSAocmVhbCBkZWxpdmVyeSksIHRoaXMgdGhyb3dzIC0gdW5sZXNzIGBpbnNlY3VyZWAgaXMgc2V0XG4gKiAoYC0taW5zZWN1cmVgIC8gYFRVTk5FTF9JTlNFQ1VSRT10cnVlYCksIGluIHdoaWNoIGNhc2UgdGhlIGNhbGxlciBydW5zIHRoZVxuICogdHVubmVsIE9QRU4gd2l0aCBubyBnYXRlLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBnZXRVc2VybmFtZVdpdGhBcGlMb29rdXAgfSBmcm9tIFwiQGRhdGFicmlja3MvYXBwa2l0XCI7XG5pbXBvcnQgeyBjcmVhdGVBcHAgYXMgY3JlYXRlQXBwTnMsIGxha2ViYXNlUmVzb2x2ZXIgfSBmcm9tIFwiQGRieC10b29scy9hcHBraXRcIjtcbmltcG9ydCB7IGJyYW5kIGFzIG5vZGVCcmFuZCB9IGZyb20gXCJAZGJ4LXRvb2xzL2NvcmVcIjtcbmltcG9ydCB7IGJyYW5kIGFzIGVtYWlsQnJhbmQsIGVtYWlsLCBzZW5kZXIsIHRyYW5zcG9ydCB9IGZyb20gXCJAZGJ4LXRvb2xzL2VtYWlsXCI7XG5pbXBvcnQgeyBlbnYsIGxvZywgc3RyaW5nIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB7IGF1dGhHYXRlLCB0eXBlIEF1dGhHYXRlQXBpLCB0eXBlIEF1dGhHYXRlQ29uZmlnLCB0eXBlIFNlbmRDb2RlT3B0aW9ucyB9IGZyb20gXCIuL3BsdWdpbi50c1wiO1xuXG5jb25zdCBsb2dnZXIgPSBsb2cubG9nZ2VyKFwidHVubmVsOmFwcFwiKTtcblxuLyoqXG4gKiBBIGNvZGUgVFRMIGFzIHRoZSBwbGFpbiBwaHJhc2UgdGhlIGVtYWlsIHN0YXRlcyAoXCIxMCBtaW51dGVzXCIsIFwiNDUgc2Vjb25kc1wiKS5cbiAqXG4gKiBXaG9sZSBtaW51dGVzIHJlYWQgYXMgbWludXRlczsgYW55dGhpbmcgZWxzZSBzdGF5cyBpbiBzZWNvbmRzIHJhdGhlciB0aGFuXG4gKiByb3VuZGluZywgc28gYSA5MC1zZWNvbmQgVFRMIGlzIG5vdCBhZHZlcnRpc2VkIGFzIFwiMSBtaW51dGVcIiBhbmQgYSByZWNpcGllbnQgaXNcbiAqIG5ldmVyIHRvbGQgdGhlIGNvZGUgbGl2ZXMgbG9uZ2VyIHRoYW4gaXQgZG9lcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGV4cGlyZXNJbihzZWNvbmRzOiBudW1iZXIpOiBzdHJpbmcge1xuICByZXR1cm4gc2Vjb25kcyA+PSA2MCAmJiBzZWNvbmRzICUgNjAgPT09IDBcbiAgICA/IHN0cmluZy5wbHVyYWxpemUoc2Vjb25kcyAvIDYwLCBcIm1pbnV0ZVwiKVxuICAgIDogc3RyaW5nLnBsdXJhbGl6ZShzZWNvbmRzLCBcInNlY29uZFwiKTtcbn1cblxuLyoqIFRoZSBwYXJ0cyBvZiB7QGxpbmsgU2VuZENvZGVPcHRpb25zfSB0aGUgY29kZSBlbWFpbCdzIGNvcHkgaXMgYnVpbHQgZnJvbS4gKi9cbnR5cGUgQ29kZUNvcHkgPSBQaWNrPFNlbmRDb2RlT3B0aW9ucywgXCJtZXNzYWdlXCIgfCBcImNvZGVUdGxTZWNvbmRzXCI+O1xuXG4vKiogVGhlIHJlYXNzdXJhbmNlIGxpbmUgY2xvc2luZyBib3RoIHBhcnRzLiAqL1xuY29uc3QgSUdOT1JFX0xJTkUgPSBcIklmIHlvdSBkaWQgbm90IHJlcXVlc3QgdGhpcyBjb2RlLCB5b3UgY2FuIGlnbm9yZSB0aGlzIGVtYWlsLlwiO1xuXG4vKipcbiAqIFRoZSBIVE1MIHBhcnQncyBzb3VyY2U6IHRoZSBmdWxsIGJyYW5kZWQgdGVtcGxhdGUsIHdpdGggdGhlIGNvZGUgYXMgYSBsYXJnZVxuICogc3R5bGVkIGhlYWRpbmcgKGAjIyBgIGlzIHdoYXQgbWFrZXMgaXQgcHJvbWluZW50IGluIGFuIGluYm94KS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvZGVFbWFpbEh0bWxCb2R5KGNvZGU6IHN0cmluZywgb3B0czogQ29kZUNvcHkpOiBzdHJpbmcge1xuICByZXR1cm4gW1xuICAgIG9wdHMubWVzc2FnZSxcbiAgICBcIlwiLFxuICAgIGAjIyAke2NvZGV9YCxcbiAgICBcIlwiLFxuICAgIGBUaGlzIGNvZGUgZXhwaXJlcyBpbiAke2V4cGlyZXNJbihvcHRzLmNvZGVUdGxTZWNvbmRzKX0uYCxcbiAgICBcIlwiLFxuICAgIElHTk9SRV9MSU5FLFxuICBdLmpvaW4oXCJcXG5cIik7XG59XG5cbi8qKlxuICogVGhlIGB0ZXh0L3BsYWluYCBwYXJ0LCBzdXBwbGllZCBFWFBMSUNJVExZIHJhdGhlciB0aGFuIHJlbmRlcmVkIGZyb20gdGhlIHRyZWVcbiAqIGFib3ZlLiBCb3RoIHBhcnRzIHNheSB0aGUgc2FtZSB0aGluZzsgb25seSB0aGUgbGluZSBsYXlvdXQgZGlmZmVycy5cbiAqXG4gKiBUaGUgcHJvbXB0IGFuZCB0aGUgY29kZSBzaGFyZSBPTkUgbGluZSAoXCJZb3VyIHZlcmlmaWNhdGlvbiBjb2RlIGlzOiAxMjM0NTZcIikuXG4gKiBUaGF0IHNpbmdsZS1saW5lIHNoYXBlIGlzIHdoYXQgaU9TLCBHbWFpbCwgT3V0bG9vaywgYW5kIEFuZHJvaWQgY29kZSBkZXRlY3Rpb25cbiAqIGtleXMgb24gbW9zdCByZWxpYWJseSAtIHRoZSBoZXVyaXN0aWNzIGxvb2sgZm9yIGEgY29kZSBpbiB0aGUgc2FtZSBzZW50ZW5jZSBhc1xuICogYSByZWNvZ25pemVkIHByb21wdCwgc28gc3BsaXR0aW5nIHRoZW0gYWNyb3NzIGxpbmVzIG1ha2VzIGRldGVjdGlvbiBkZXBlbmRlbnRcbiAqIG9uIHRoZSBjbGllbnQsIGFuZCBhbnkgYmxhbmsgbGluZSBiZXR3ZWVuIHRoZW0gZGVmZWF0cyBpdCBvdXRyaWdodC5cbiAqXG4gKiBUaGUgR0VORVJBVEVEIHRleHQgcGFydCBjYW5ub3QgaG9sZCB0aGF0IHNoYXBlIGF0IGFsbDogaXQgaXMgYSByZW5kZXJpbmcgb2YgdGhlXG4gKiBIVE1MLCBzbyBpdCBjYXJyaWVzIHRoZSBicmFuZCBoZWFkZXIvZm9vdGVyIGFuZCB0dXJucyB0aGUgY29kZSBoZWFkaW5nJ3MgQ1NTXG4gKiBtYXJnaW4gaW50byBibGFuayBsaW5lcywgYXJyaXZpbmcgYXMgYHByb21wdFxcblxcblxcbmNvZGVgLlxuICpcbiAqIFRoZSBjb2RlIGlzIHZpc2libGUgdGV4dCBpbiBCT1RIIHBhcnRzLCBuZXZlciBhbiBpbWFnZSwgc28gYSBjbGllbnQgc2NyYXBpbmdcbiAqIGVpdGhlciBvbmUgZmluZHMgaXQuIE5vIHRyYWlsZXIgbGluZSBmb2xsb3dzIHRoZSBjb3B5IC0gQXBwbGUncyBkb21haW4tYm91bmRcbiAqIGBAZG9tYWluICNjb2RlYCBmb290ZXIgaXMgZGVsaWJlcmF0ZWx5IE5PVCBlbWl0dGVkLCBzaW5jZSBpdCBjb25zdHJhaW5zIHRoZVxuICogY29kZSB0byBvbmUgb3JpZ2luIGFuZCBpcyBub3Qgd2hhdCB0aGUgYnJvYWRseS1jb21wYXRpYmxlIHNoYXBlIG5lZWRzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29kZUVtYWlsVGV4dEJvZHkoY29kZTogc3RyaW5nLCBvcHRzOiBDb2RlQ29weSk6IHN0cmluZyB7XG4gIHJldHVybiBbXG4gICAgYCR7b3B0cy5tZXNzYWdlfSAke2NvZGV9YCxcbiAgICBgVGhpcyBjb2RlIGV4cGlyZXMgaW4gJHtleHBpcmVzSW4ob3B0cy5jb2RlVHRsU2Vjb25kcyl9LmAsXG4gICAgXCJcIixcbiAgICBJR05PUkVfTElORSxcbiAgXS5qb2luKFwiXFxuXCIpO1xufVxuXG4vKipcbiAqIFRoZSBTVUJKRUNUIGxpbmUsIHdpdGggdGhlIGNvZGUgaW4gaXQ6IGBcIjEyMzQ1NiBpcyB5b3VyIHZlcmlmaWNhdGlvbiBjb2RlXCJgLlxuICpcbiAqIFRoZSBjb2RlIGhhcyB0byBiZSBoZXJlLCBub3Qgb25seSBpbiB0aGUgYm9keSwgYmVjYXVzZSBvZiB3aGF0IG1vYmlsZSBhdXRvZmlsbFxuICogYWN0dWFsbHkgcmVhZHMuIGlPUyBvZmZlcnMgYSBjb2RlIGZyb20gYW4gaW5jb21pbmcgTk9USUZJQ0FUSU9OIC0gbmF0aXZlbHkgZm9yXG4gKiBNZXNzYWdlcyBhbmQgTWFpbCwgYW5kIHNpbmNlIGlPUyAyNiBmb3IgYW55IGFwcCdzIG5vdGlmaWNhdGlvbiB0ZXh0LCB3aGljaCBpc1xuICogd2hhdCBmaW5hbGx5IG1hZGUgR21haWwgd29yayAtIGFuZCBhIG5vdGlmaWNhdGlvbiBjb250YWlucyB0aGUgc2VuZGVyLCB0aGVcbiAqIHN1YmplY3QsIGFuZCBhIHNob3J0IHNuaXBwZXQuIE5vdGhpbmcgZWxzZS4gQSBjb2RlIHRoYXQgbGl2ZXMgaW4gdGhlIGJvZHkgaXNcbiAqIGludmlzaWJsZSB0byBpdCwgaG93ZXZlciBjbGVhbmx5IHRoZSBib2R5IGlzIGZvcm1hdHRlZCwgd2hpY2ggaXMgd2h5IGEgcGVyZmVjdGx5XG4gKiBzaGFwZWQgYHRleHQvcGxhaW5gIHBhcnQgc3RpbGwgcHJvZHVjZWQgbm8gYXV0b2ZpbGwgcHJvbXB0IGluIEdtYWlsLlxuICpcbiAqIGA8Y29kZT4gaXMgeW91ciA8dGhpbmc+YCByYXRoZXIgdGhhbiBgPHRoaW5nPjogPGNvZGU+YCBiZWNhdXNlIHRoZSBsZWFkaW5nIGNvZGVcbiAqIHN1cnZpdmVzIFRSVU5DQVRJT046IGEgbm90aWZpY2F0aW9uIGFuZCBhbiBpbmJveCBsaXN0IGJvdGggY3V0IHRoZSBzdWJqZWN0LCBhbmRcbiAqIHRoZSBwbGF0Zm9ybSBoZXVyaXN0aWNzIHdhbnQgdGhlIGNvZGUgaW4gdGhlIHNhbWUgc2VudGVuY2UgYXMgYSByZWNvZ25pemVkXG4gKiBwcm9tcHQgKFwiY29kZVwiLCBcInZlcmlmaWNhdGlvblwiKS4gUHV0dGluZyBpdCBmaXJzdCBrZWVwcyBib3RoIGludGFjdCBubyBtYXR0ZXJcbiAqIHdoZXJlIHRoZSBjdXQgbGFuZHMuXG4gKlxuICogYHN1YmplY3RgIGlzIHRoZSBjb25maWd1cmVkIGxpbmUgKFwiWW91ciB2ZXJpZmljYXRpb24gY29kZVwiKSwgbG93ZXItY2FzZWQgYXQgaXRzXG4gKiBmaXJzdCB3b3JkIHNvIHRoZSBzZW50ZW5jZSByZWFkcyBuYXR1cmFsbHksIGFuZCBsZWZ0IEFMT05FIHdoZW4gaXQgZG9lcyBub3QgbG9va1xuICogbGlrZSB0aGUgY29udmVudGlvbmFsIHBocmFzaW5nIC0gYW4gb3BlcmF0b3Igd2hvIHNldCBhIGRlbGliZXJhdGUgc3ViamVjdCBnZXRzXG4gKiB0aGVpcnMgd2l0aCB0aGUgY29kZSBwcmVmaXhlZCwgbm90IGEgbWFuZ2xlZCBoeWJyaWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb2RlRW1haWxTdWJqZWN0KGNvZGU6IHN0cmluZywgc3ViamVjdDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgdHJpbW1lZCA9IHN1YmplY3QudHJpbSgpO1xuICBjb25zdCBjb252ZW50aW9uYWwgPSAvXnlvdXJcXHMrL2kuZXhlYyh0cmltbWVkKTtcbiAgY29uc3QgcmVzdCA9IGNvbnZlbnRpb25hbCA/IHRyaW1tZWQuc2xpY2UoY29udmVudGlvbmFsWzBdLmxlbmd0aCkgOiB0cmltbWVkO1xuICByZXR1cm4gY29udmVudGlvbmFsID8gYCR7Y29kZX0gaXMgeW91ciAke3Jlc3R9YCA6IGAke2NvZGV9IC0gJHt0cmltbWVkfWA7XG59XG5cbi8qKlxuICogVGhlIFBSRUhFQURFUjogdGhlIHNuaXBwZXQgYmVzaWRlIHRoZSBzdWJqZWN0IGluIGFuIGluYm94IGxpc3QsIGFuZCB0aGUgYm9keSBvZlxuICogdGhlIHB1c2ggbm90aWZpY2F0aW9uLiBDYXJyaWVzIHRoZSBjb2RlIGZvciB0aGUgc2FtZSByZWFzb24gdGhlIHN1YmplY3QgZG9lcyAtXG4gKiBpdCBpcyB0aGUgb3RoZXIgaGFsZiBvZiB3aGF0IGEgbm90aWZpY2F0aW9uIHNob3dzIC0gYW5kIHJlcGVhdHMgdGhlIHByb21wdFxuICogd29yZGluZyBzbyBhIGhldXJpc3RpYyBzY2FubmluZyB0aGUgc25pcHBldCBhbG9uZSBmaW5kcyBhIGNvZGUgbmV4dCB0byBhIHBocmFzZVxuICogaXQgcmVjb2duaXplcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvZGVFbWFpbFByZXZpZXcoY29kZTogc3RyaW5nLCBvcHRzOiBDb2RlQ29weSk6IHN0cmluZyB7XG4gIHJldHVybiBgJHtvcHRzLm1lc3NhZ2V9ICR7Y29kZX1gO1xufVxuXG5jb25zdCB7IGNyZWF0ZUFwcCB9ID0gY3JlYXRlQXBwTnM7XG5jb25zdCB7IGFwcGx5TGFrZWJhc2VUb0VudiwgcmVzb2x2ZUxha2ViYXNlQ29ubmVjdGlvbiB9ID0gbGFrZWJhc2VSZXNvbHZlcjtcbmNvbnN0IHsgcmVzb2x2ZVN5c3RlbVNlbmRlckFkZHJlc3MgfSA9IHNlbmRlcjtcbmNvbnN0IHsgZ2V0RW1haWxSdW50aW1lLCBzZW5kRW1haWwgfSA9IHRyYW5zcG9ydDtcbmNvbnN0IHsgZW1haWxCcmFuZEZyb21Db250ZXh0IH0gPSBlbWFpbEJyYW5kO1xuY29uc3QgeyBsb2FkQnJhbmRDb250ZXh0IH0gPSBub2RlQnJhbmQ7XG5cbi8qKlxuICogRW52IHZhcnMgd2hvc2UgcHJlc2VuY2UgbWVhbnMgYSBMYWtlYmFzZSBkYXRhYmFzZSB3YXMgYm91bmQgdG8gdGhpcyBkZXBsb3ltZW50LlxuICogYExBS0VCQVNFX0VORFBPSU5UYCBpcyB3aGF0IGEgRGF0YWJyaWNrcyBBcHAgYHBvc3RncmVzYCByZXNvdXJjZSBiaW5kaW5nIHNldHM7XG4gKiBgUEdIT1NUYCBpcyB0aGUgbG9jYWwvbWFudWFsIHNwZWxsaW5nLlxuICovXG5jb25zdCBMQUtFQkFTRV9FTlYgPSBbXCJMQUtFQkFTRV9FTkRQT0lOVFwiLCBcIlBHSE9TVFwiXSBhcyBjb25zdDtcblxuLyoqXG4gKiBVcHBlciBib3VuZCBvbiByZXNvbHZpbmcgdGhlIExha2ViYXNlIGNvbm5lY3Rpb24uIFRoZSBnYXRlIGlzIGluIHRoZSByZXF1ZXN0XG4gKiBwYXRoIGZvciBldmVyeSB2aXNpdG9yLCBzbyBhIHNsb3cgd29ya3NwYWNlIEFQSSBtdXN0IG5vdCBob2xkIHVwIGJvb3RcbiAqIGluZGVmaW5pdGVseTsgYSBtZW1vcnkgY2FjaGUgaXMgYSBkZWdyYWRlZCBnYXRlLCBhbiB1bmJvb3RlZCBvbmUgaXMgbm8gZ2F0ZS5cbiAqL1xuY29uc3QgTEFLRUJBU0VfUkVTT0xWRV9USU1FT1VUX01TID0gNjBfMDAwO1xuXG4vKipcbiAqIEZpbGwgaW4gdGhlIExha2ViYXNlIGNvbm5lY3Rpb24gZW52IEFwcEtpdCdzIGNhY2hlIG5lZWRzLCBzbyBgQ2FjaGVNYW5hZ2VyYFxuICogY2hvb3NlcyBQRVJTSVNURU5UIHN0b3JhZ2UgaW5zdGVhZCBvZiBtZW1vcnkuXG4gKlxuICogVGhpcyBpcyB3aGF0IG1ha2VzIHRoZSBnYXRlJ3Mgc2Vzc2lvbiBzaWduaW5nIGtleSBhbmQgb3V0c3RhbmRpbmcgb25lLXRpbWVcbiAqIGNvZGVzIHN1cnZpdmUgYSByZXN0YXJ0LCBhbmQgaXQgaGFzIHRvIGJlIGRvbmUgZXhwbGljaXRseSBoZXJlLiBBcHBLaXQgcGlja3NcbiAqIExha2ViYXNlIGZvciB0aGUgY2FjaGUgb25seSB3aGVuIGBjcmVhdGVMYWtlYmFzZVBvb2woKWAgc3VjY2VlZHMsIGFuZCB0aGF0IHBvb2xcbiAqIHJlYWRzIEZPVVIgdGhpbmdzIG9mZiBgcHJvY2Vzcy5lbnZgOiBgTEFLRUJBU0VfRU5EUE9JTlRgLCBgUEdIT1NUYCxcbiAqIGBQR0RBVEFCQVNFYCwgYW5kIGEgdXNlcm5hbWUgKGBQR1VTRVJgLCBvciBgREFUQUJSSUNLU19DTElFTlRfSURgIGZvciBhIHNlcnZpY2VcbiAqIHByaW5jaXBhbCkuIEEgRGF0YWJyaWNrcyBBcHAgYHBvc3RncmVzYCByZXNvdXJjZSBiaW5kaW5nIHN1cHBsaWVzIG9ubHlcbiAqIGBMQUtFQkFTRV9FTkRQT0lOVGAuIFRoZSByZXNvbHZlciB0dXJucyB0aGF0IG9uZSB2YWx1ZSBpbnRvIHRoZSBob3N0IGFuZFxuICogZGF0YWJhc2U7IHRoZSB1c2VybmFtZSBpcyBsb29rZWQgdXAgc2VwYXJhdGVseSwgYmVjYXVzZSBtaXNzaW5nIGl0IGZhaWxzIHBvb2xcbiAqIGNvbnN0cnVjdGlvbiBqdXN0IGFzIGhhcmQgYXMgYSBtaXNzaW5nIGhvc3QgLSBhbmQgaXQgaXMgd2hhdCBhIExPQ0FMIHJ1biAoYVxuICogZGV2ZWxvcGVyIG9uIGEgUEFULCB3aXRoIG5vIGBEQVRBQlJJQ0tTX0NMSUVOVF9JRGApIGlzIGFsd2F5cyBtaXNzaW5nLiBXaXRob3V0XG4gKiBhbGwgZm91ciB0aGUgcG9vbCBjYW5ub3QgYmUgYnVpbHQsIHRoZSBjYWNoZSBzaWxlbnRseSBkZWdyYWRlcyB0byBpbi1tZW1vcnksIGFuZFxuICogZXZlcnkgcmVkZXBsb3kgc2lnbnMgb3V0IGV2ZXJ5IHVzZXIgKHRoZSBleGFjdCBzeW1wdG9tIHRoaXMgZXhpc3RzIHRvIHByZXZlbnQpLlxuICpcbiAqIGBAZGJ4LXRvb2xzL2FwcGtpdGAncyBgY3JlYXRlQXBwYCB3b3VsZCBub3JtYWxseSBkbyB0aGlzIHZpYSBgYXV0b0NvbmZpZ3VyZWAsXG4gKiBidXQgaXQgZ2F0ZXMgdGhhdCBvbiBhIGBsYWtlYmFzZSgpYCBwbHVnaW4gYmVpbmcgcmVnaXN0ZXJlZCAtIGFuZCB0aGlzIGFwcFxuICogcmVnaXN0ZXJzIG5vbmUsIGJlY2F1c2UgaXQgaGFzIG5vIHNlcnZlciB0byBtb3VudCBMYWtlYmFzZSByb3V0ZXMgb24uIENhbGxpbmdcbiAqIHRoZSByZXNvbHZlciBkaXJlY3RseSBhbHNvIGxldHMgdGhlIGdhdGUgYmUgc3RyaWN0ZXIgdGhhbiBgYXV0b0NvbmZpZ3VyZWAgaXM6XG4gKlxuICogICAtIEl0IHJ1bnMgT05MWSB3aGVuIGEgTGFrZWJhc2UgZW52IHZhciBpcyBwcmVzZW50LiBBIHR1bm5lbCBpcyBhIHdyYXBwZXJcbiAqICAgICBhcm91bmQgc29tZW9uZSBlbHNlJ3MgYXBwIGFuZCBtdXN0IG5vdCBpbnZlbnQgaW5mcmFzdHJ1Y3R1cmUsIHNvIHdpdGhcbiAqICAgICBub3RoaW5nIGJvdW5kIGl0IHNraXBzIHJhdGhlciB0aGFuIGZhbGxpbmcgdGhyb3VnaCB0aGUgcmVzb2x2ZXInc1xuICogICAgIGxpc3Qtb3ItQ1JFQVRFLWEtcHJvamVjdCBwYXRoLlxuICogICAtIGBhdXRvQ3JlYXRlOiBmYWxzZWAgZm9yIHRoZSBzYW1lIHJlYXNvbiwgaW4gY2FzZSBhIHByb2plY3QgaGFwcGVucyB0byBleGlzdC5cbiAqICAgLSBFdmVyeSBmYWlsdXJlIGlzIGEgV0FSTklORywgbmV2ZXIgYSB0aHJvdy4gVGhlIGNhY2hlIGlzIGFuIG9wdGltaXphdGlvbiBmb3JcbiAqICAgICBzZXNzaW9uIGR1cmFiaWxpdHk7IGFkbWlzc2lvbiBzdGlsbCByZXF1aXJlcyBhIGNvZGUgZGVsaXZlcmVkIHRvIGFuXG4gKiAgICAgYWxsb3ctbGlzdGVkIGFkZHJlc3MsIHNvIGEgZ2F0ZSB3aXRoIGEgbWVtb3J5IGNhY2hlIGlzIHNhZmUsIGp1c3QgZm9yZ2V0ZnVsLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZUNhY2hlU3RvcmFnZUVudigpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgaWYgKCFlbnYudGV4dChMQUtFQkFTRV9FTlYpKSB7XG4gICAgbG9nZ2VyLmluZm8oXG4gICAgICBgbm8gJHtlbnYubmFtZShMQUtFQkFTRV9FTlYpfSAtIHRoZSBnYXRlIGNhY2hlIHN0YXlzIGluIG1lbW9yeTsgc2Vzc2lvbnMgYW5kIGNvZGVzIHdpbGwgbm90IHN1cnZpdmUgYSByZXN0YXJ0YCxcbiAgICApO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB0cnkge1xuICAgIGNvbnN0IHJlc29sdmVkID0gYXdhaXQgcmVzb2x2ZUxha2ViYXNlQ29ubmVjdGlvbihcbiAgICAgIHsgYXV0b0NyZWF0ZTogZmFsc2UgfSxcbiAgICAgIEFib3J0U2lnbmFsLnRpbWVvdXQoTEFLRUJBU0VfUkVTT0xWRV9USU1FT1VUX01TKSxcbiAgICApO1xuICAgIGFwcGx5TGFrZWJhc2VUb0VudihyZXNvbHZlZCk7XG4gICAgLy8gYD8/PWAgc28gYW4gZXhwbGljaXRseSBjb25maWd1cmVkIFBHVVNFUiBzdGF5cyBhdXRob3JpdGF0aXZlLiBUaGUgbG9va3VwXG4gICAgLy8gZmFsbHMgYmFjayB0byB0aGUgd29ya3NwYWNlIEFQSSBhbmQgcmV0dXJucyB1bmRlZmluZWQgcmF0aGVyIHRoYW4gdGhyb3dpbmcsXG4gICAgLy8gc28gYSBmYWlsdXJlIGhlcmUganVzdCBsZWF2ZXMgdGhlIHBvb2wgdG8gZmluZCBpdHMgb3duIHVzZXJuYW1lLlxuICAgIGNvbnN0IHVzZXIgPSBhd2FpdCBnZXRVc2VybmFtZVdpdGhBcGlMb29rdXAoe30pO1xuICAgIGlmICh1c2VyKSBwcm9jZXNzLmVudi5QR1VTRVIgPz89IHVzZXI7XG4gICAgbG9nZ2VyLmluZm8oXCJsYWtlYmFzZSByZXNvbHZlZCBmb3IgdGhlIGdhdGUgY2FjaGVcIiwge1xuICAgICAgaG9zdDogcmVzb2x2ZWQuaG9zdCxcbiAgICAgIGRhdGFiYXNlOiByZXNvbHZlZC5kYXRhYmFzZSxcbiAgICAgIGVuZHBvaW50OiByZXNvbHZlZC5lbmRwb2ludCxcbiAgICAgIHVzZXI6IHByb2Nlc3MuZW52LlBHVVNFUixcbiAgICB9KTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBsb2dnZXIud2FybihcbiAgICAgIFwiY291bGQgbm90IHJlc29sdmUgbGFrZWJhc2UgLSB0aGUgZ2F0ZSBjYWNoZSBzdGF5cyBpbiBtZW1vcnk7IHNlc3Npb25zIGFuZCBjb2RlcyB3aWxsIG5vdCBzdXJ2aXZlIGEgcmVzdGFydFwiLFxuICAgICAgeyBlcnJvciB9LFxuICAgICk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbi8qKlxuICogQm9vdCB0aGUgZ2F0ZSBhcHAgYW5kIHJldHVybiB0aGUgQVBJIHRoZSBwcm94eSBjYWxscy4gVGhyb3dzIHdoZW4gZW1haWwgaXMgbm90XG4gKiBpbiBTTVRQIG1vZGUgKG5vIHdheSB0byBkZWxpdmVyIGEgY29kZSkgc28gYSBtaXNjb25maWd1cmVkIGdhdGUgZmFpbHMgZmFzdCBhdFxuICogc3RhcnR1cCByYXRoZXIgdGhhbiBzaWxlbnRseSBhY2NlcHRpbmcgbm9ib2R5OyB0aGUgY2FsbGVyIG1heSBjYXRjaCB0aGlzIGFuZFxuICogZmFsbCBiYWNrIHRvIGluc2VjdXJlL29wZW4gbW9kZSB3aGVuIHRoZSBvcGVyYXRvciBvcHRlZCBpbi5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHN0YXJ0R2F0ZUFwcChjb25maWc6IEF1dGhHYXRlQ29uZmlnKTogUHJvbWlzZTxBdXRoR2F0ZUFwaT4ge1xuICAvLyBUaGUgaG9zdCBhcHAncyBvd24gYnJhbmQgKGBicmFuZGluZy9icmFuZC55YW1sYCBkaXNjb3ZlcmVkIGZyb20gY3dkKSBvciB0aGVcbiAgLy8gZGJ4LXRvb2xzIGRlZmF1bHQuIFRoaXMgaXMgdGhlIE9ORSBicmFuZCBzb3VyY2UgZm9yIHRoZSBnYXRlOiBpdCBzdHlsZXMgdGhlXG4gIC8vIGNvZGUgZW1haWwgKGFjY2VudCBiYW5kLCBmb250LCBsb2dvKSB2aWEgdGhlIGVtYWlsIHBsdWdpbiBBTkQgc3VwcGxpZXMgdGhlXG4gIC8vIGRpc3BsYXkgbmFtZSB0aGUgY29weSB1c2VzLCBzbyBhIGRlcGxveW1lbnQgdGhhdCB0aGVtZXMgaXRzIGFwcCB0aGVtZXMgaXRzXG4gIC8vIHNpZ24taW4gZW1haWwgd2l0aCBpdC4gQW4gZXhwbGljaXQgYGJyYW5kTmFtZWAgc3RpbGwgd2lucyAoc2VlIGJlbG93KS5cbiAgY29uc3QgY29udGV4dCA9IGF3YWl0IGxvYWRCcmFuZENvbnRleHQoKTtcblxuICAvLyBCZWZvcmUgYGNyZWF0ZUFwcGAsIGJlY2F1c2UgQXBwS2l0IHJlc29sdmVzIHRoZSBjYWNoZSdzIHN0b3JhZ2UgZHVyaW5nIGl0IGFuZFxuICAvLyByZWFkcyB0aGUgY29ubmVjdGlvbiBvdXQgb2YgYHByb2Nlc3MuZW52YCB3aGVuIGl0IGRvZXMuIFNlZSB0aGUgZnVuY3Rpb24nc1xuICAvLyBkb2NzIGZvciB3aHkgdGhlIGdhdGUgcmVzb2x2ZXMgdGhpcyBpdHNlbGYuXG4gIGF3YWl0IHJlc29sdmVDYWNoZVN0b3JhZ2VFbnYoKTtcblxuICAvLyBgc2VuZENvZGVgIGRlbGl2ZXJzIHRoZSBPVFAgdGhyb3VnaCB0aGUgZW1haWwgcGx1Z2luJ3MgU0hBUkVEIHRyYW5zcG9ydCwgd2hpY2hcbiAgLy8gdGhlIGBlbWFpbCgpYCBwbHVnaW4gcHJpbWVzIGR1cmluZyBpdHMgYHNldHVwKClgIChhd2FpdGVkIGJ5IGBjcmVhdGVBcHBgXG4gIC8vIGJlbG93KS4gVXNpbmcgdGhlIG1vZHVsZS1sZXZlbCBgc2VuZEVtYWlsYCBhdm9pZHMgYSBjaXJjdWxhciBkZXBlbmRlbmN5IG9uIHRoZVxuICAvLyBhcHAgaGFuZGxlJ3MgaW5mZXJyZWQgdHlwZS4gVGhlIGBGcm9tYCBpcyB0aGUgU1lTVEVNIHNlbmRlcjogYSB2ZXJpZmljYXRpb25cbiAgLy8gY29kZSBpcyBtYWNoaW5lLWdlbmVyYXRlZCBhbmQgdW5hbnN3ZXJhYmxlLCBzbyBpdCBtdXN0IG5vdCBhcnJpdmUgZnJvbSBhXG4gIC8vIHBlcnNvbidzIGFkZHJlc3MgaW52aXRpbmcgYSByZXBseS5cbiAgY29uc3Qgc2VuZENvZGU6IE5vbk51bGxhYmxlPEF1dGhHYXRlQ29uZmlnW1wic2VuZENvZGVcIl0+ID0gYXN5bmMgKHRvLCBjb2RlLCBvcHRzKSA9PiB7XG4gICAgY29uc3QgZnJvbSA9IHJlc29sdmVTeXN0ZW1TZW5kZXJBZGRyZXNzKGdldEVtYWlsUnVudGltZSgpLmNvbmZpZyk7XG4gICAgYXdhaXQgc2VuZEVtYWlsKFxuICAgICAge1xuICAgICAgICB0bzogW3RvXSxcbiAgICAgICAgLy8gVGhlIGNvZGUgcmlkZXMgaW4gdGhlIFNVQkpFQ1QgYW5kIHRoZSBwcmVoZWFkZXIsIG5vdCBqdXN0IHRoZSBib2R5OlxuICAgICAgICAvLyB0aG9zZSB0d28gc3RyaW5ncyBhcmUgdGhlIHdob2xlIG9mIGEgcHVzaCBub3RpZmljYXRpb24sIGFuZCBhXG4gICAgICAgIC8vIG5vdGlmaWNhdGlvbiBpcyB3aGF0IG1vYmlsZSBhdXRvZmlsbCByZWFkcy4gU2VlIGBjb2RlRW1haWxTdWJqZWN0YC5cbiAgICAgICAgc3ViamVjdDogY29kZUVtYWlsU3ViamVjdChjb2RlLCBvcHRzLnN1YmplY3QpLFxuICAgICAgICBib2R5OiBjb2RlRW1haWxIdG1sQm9keShjb2RlLCBvcHRzKSxcbiAgICAgIH0sXG4gICAgICBmcm9tLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgeyB0ZXh0OiBjb2RlRW1haWxUZXh0Qm9keShjb2RlLCBvcHRzKSwgcHJldmlldzogY29kZUVtYWlsUHJldmlldyhjb2RlLCBvcHRzKSB9LFxuICAgICk7XG4gIH07XG5cbiAgLy8gYGNyZWF0ZUFwcGAgbmFtZXNwYWNlcyBlYWNoIHBsdWdpbidzIGV4cG9ydHMgb24gdGhlIGhhbmRsZSBieSBtYW5pZmVzdCBuYW1lO1xuICAvLyBgaGFuZGxlLmF1dGhHYXRlYCBpcyB0aGUgaW4tcHJvY2VzcyBnYXRlIEFQSSB0aGUgcHJveHkgZHJpdmVzLlxuICAvL1xuICAvLyBgYXV0b0NvbmZpZ3VyZTogZmFsc2VgIGJlY2F1c2Uge0BsaW5rIHJlc29sdmVDYWNoZVN0b3JhZ2VFbnZ9IGFib3ZlIGFscmVhZHlcbiAgLy8gZGlkIHRoZSBvbmUgcGllY2Ugb2YgaXQgdGhpcyBhcHAgd2FudHMsIG9uIHRoaXMgYXBwJ3MgdGVybXMuXG4gIGNvbnN0IGhhbmRsZSA9IGF3YWl0IGNyZWF0ZUFwcCh7XG4gICAgYXV0b0NvbmZpZ3VyZTogZmFsc2UsXG4gICAgcGx1Z2luczogW1xuICAgICAgLy8gQnJhbmQgdGhlIGNvZGUgZW1haWwgZnJvbSB0aGUgcmVzb2x2ZWQgY29udGV4dCwgdGhlIHNhbWUgYnJpZGdlIGV2ZXJ5XG4gICAgICAvLyBvdGhlciBkYngtdG9vbHMgZW1haWwgc3VyZmFjZSB1c2VzIChhY2NlbnQgKyBmb250IGlubGluZWQsIGxvZ28gb25seSB3aGVuXG4gICAgICAvLyBpdCBpcyBhIGZldGNoYWJsZSBVUkwgLSBhIHBhY2thZ2UtZXhwb3J0IHBhdGggY2Fubm90IGxvYWQgaW4gYW4gaW5ib3gpLlxuICAgICAgZW1haWwoeyBicmFuZDogZW1haWxCcmFuZEZyb21Db250ZXh0KGNvbnRleHQpIH0pLFxuICAgICAgLy8gYGJyYW5kTmFtZWAgZmFsbHMgYmFjayB0byB0aGUgcmVzb2x2ZWQgY29udGV4dCdzIGRpc3BsYXkgbmFtZSwgc28gdGhlXG4gICAgICAvLyBlbWFpbCBjb3B5IG5hbWVzIHRoZSBhcHAgcmF0aGVyIHRoYW4gYSBnZW5lcmljIHBsYWNlaG9sZGVyLiBTcGVsbGVkIGFzIGFuXG4gICAgICAvLyBleHBsaWNpdCBgPz9gIHJhdGhlciB0aGFuIGEga2V5IGJlZm9yZSBgLi4uY29uZmlnYDogY29tbWFuZGVyIHNldHNcbiAgICAgIC8vIGBicmFuZE5hbWVgIG9uIHRoZSBvcHRpb25zIG9iamVjdCB3aGV0aGVyIG9yIG5vdCB0aGUgZmxhZyB3YXMgcGFzc2VkLCBzb1xuICAgICAgLy8gc3ByZWFkaW5nIGl0IHdvdWxkIGNsb2JiZXIgdGhlIGNvbnRleHQgbmFtZSB3aXRoIGB1bmRlZmluZWRgLlxuICAgICAgYXV0aEdhdGUoeyAuLi5jb25maWcsIGJyYW5kTmFtZTogY29uZmlnLmJyYW5kTmFtZSA/PyBjb250ZXh0Lm5hbWUsIHNlbmRDb2RlIH0pLFxuICAgIF0sXG4gIH0pO1xuXG4gIC8vIEZhaWwgZmFzdDogdGhlIGdhdGUgbmVlZHMgU01UUCB0byBlbWFpbCBjb2Rlcy4gYGdldEVtYWlsUnVudGltZSgpYCByZXNvbHZlcyB0b1xuICAvLyBgbW9kZTogXCJmaWxlXCJgIChvdXRib3gpIG9yIHRocm93cyB3aGVuIG5vIFNNVFAgY3JlZHMgYXJlIGNvbmZpZ3VyZWQgLSBuZWl0aGVyXG4gIC8vIGNhbiBkZWxpdmVyIHRvIGEgcmVhbCBpbmJveCwgc28gcmVmdXNlIHRvIGJyaW5nIHVwIGEgZ2F0ZSB0aGF0IGxldHMgbm9ib2R5IGluLlxuICBpZiAoZ2V0RW1haWxSdW50aW1lKCkuY29uZmlnLm1vZGUgIT09IFwic210cFwiKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgXCJlbWFpbCBpcyBub3QgY29uZmlndXJlZCBmb3IgU01UUCBkZWxpdmVyeSAtIHRoZSBPVFAgZ2F0ZSBjYW5ub3Qgc2VuZCBjb2Rlcy4gXCIgK1xuICAgICAgICBcIlNldCBTTVRQX0hPU1QvU01UUF9VU0VSL1NNVFBfUEFTU1dPUkQsIG9yIHBhc3MgLS1pbnNlY3VyZSAvIFRVTk5FTF9JTlNFQ1VSRT10cnVlIHRvIHJ1biB0aGUgdHVubmVsIG9wZW4uXCIsXG4gICAgKTtcbiAgfVxuXG4gIGxvZ2dlci5pbmZvKFwiZ2F0ZSBhcHAgcmVhZHkgKG5vIHNlcnZlcjsgcHJveHktZHJpdmVuKVwiKTtcbiAgcmV0dXJuIGhhbmRsZS5hdXRoR2F0ZSBhcyBBdXRoR2F0ZUFwaTtcbn1cbiJdfQ==
@@ -29,6 +29,11 @@ export interface AuthGateConfig extends BasePluginConfig {
29
29
  * anything branded: iOS, Gmail, Outlook, and Android all detect a one-time
30
30
  * code from this shape and offer to autofill it, and a novel phrasing is what
31
31
  * breaks that detection.
32
+ *
33
+ * This is the subject TEMPLATE, not the literal line sent: the code is spliced
34
+ * into it (`"123456 is your verification code"`) because a push notification
35
+ * shows only the subject and preheader, and that notification is what mobile
36
+ * autofill reads. See `codeEmailSubject` in `./app.ts`.
32
37
  */
33
38
  subject?: string;
34
39
  /**
package/lib/src/plugin.js CHANGED
@@ -135,4 +135,4 @@ export class AuthGatePlugin extends Plugin {
135
135
  }
136
136
  /** Factory: `authGate({ allow, subject, ... })` for an AppKit `plugins` array. */
137
137
  export const authGate = toPlugin(AuthGatePlugin);
138
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3BsdWdpbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQUVILE9BQU8sRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUE4QyxNQUFNLG9CQUFvQixDQUFDO0FBQ2xHLE9BQU8sRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFekUsT0FBTyxFQUFFLGNBQWMsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2xFLE9BQU8sRUFDTCxTQUFTLEVBQ1QsY0FBYyxFQUNkLFlBQVksRUFDWixXQUFXLEVBQ1gsZUFBZSxFQUNmLFdBQVcsR0FDWixNQUFNLFVBQVUsQ0FBQztBQUNsQixPQUFPLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxhQUFhLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDakUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxlQUFlLEVBQUUsb0JBQW9CLEVBQUUsVUFBVSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFckYsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQztBQW1GekMsTUFBTSxRQUFRLEdBQUc7SUFDZixPQUFPLEVBQUUsd0JBQXdCO0lBQ2pDLDhFQUE4RTtJQUM5RSwrRUFBK0U7SUFDL0Usa0VBQWtFO0lBQ2xFLGlFQUFpRTtJQUNqRSxnRkFBZ0Y7SUFDaEYsOENBQThDO0lBQzlDLFNBQVMsRUFBRSxLQUFLLENBQUMsbUJBQW1CLENBQUMsSUFBSTtJQUN6QyxPQUFPLEVBQUUsNEJBQTRCO0lBQ3JDLHVFQUF1RTtJQUN2RSxpQkFBaUIsRUFBRSxlQUFlO0lBQ2xDLGNBQWMsRUFBRSxHQUFHO0lBQ25CLFdBQVcsRUFBRSxDQUFDO0NBQ2YsQ0FBQztBQUVGLGtGQUFrRjtBQUNsRixNQUFNLFVBQVUscUJBQXFCLENBQUMsTUFBc0I7SUFDMUQsT0FBTztRQUNMLHlFQUF5RTtRQUN6RSw2RUFBNkU7UUFDN0UsNkVBQTZFO1FBQzdFLCtCQUErQjtRQUMvQixLQUFLLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFDcEYsT0FBTyxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxXQUFXLENBQUMsSUFBSSxRQUFRLENBQUMsT0FBTztRQUNwRSxTQUFTLEVBQUUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLGNBQWMsQ0FBQyxJQUFJLFFBQVEsQ0FBQyxTQUFTO1FBQzdFLE9BQU8sRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsV0FBVyxDQUFDLElBQUksUUFBUSxDQUFDLE9BQU87UUFDcEUsaUJBQWlCLEVBQUUsR0FBRyxDQUFDLFdBQVcsQ0FDaEMsTUFBTSxDQUFDLGlCQUFpQixFQUN4QixlQUFlLEVBQ2YsUUFBUSxDQUFDLGlCQUFpQixDQUMzQjtRQUNELGNBQWMsRUFBRSxHQUFHLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsWUFBWSxFQUFFLFFBQVEsQ0FBQyxjQUFjLENBQUM7UUFDN0YsV0FBVyxFQUFFLE1BQU0sQ0FBQyxXQUFXLElBQUksUUFBUSxDQUFDLFdBQVc7UUFDdkQsZUFBZSxFQUFFLG9CQUFvQixDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUM7S0FDNUQsQ0FBQztBQUNKLENBQUM7QUFvQkQsc0ZBQXNGO0FBQ3RGLE1BQU0sT0FBTyxjQUFlLFNBQVEsTUFBc0I7SUFDeEQsTUFBTSxDQUFDLFFBQVEsR0FBRztRQUNoQixJQUFJLEVBQUUsVUFBVTtRQUNoQixXQUFXLEVBQUUsV0FBVztRQUN4QixXQUFXLEVBQUUsMERBQTBEO1FBQ3ZFLFNBQVMsRUFBRSxNQUFNO1FBQ2pCLFNBQVMsRUFBRSxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRTtLQUNMLENBQUM7SUFFL0IsUUFBUSxDQUEwQjtJQUNsQyxLQUFLLENBQWE7SUFDMUIsNkVBQTZFO0lBQzdFLDBEQUEwRDtJQUN6QyxjQUFjLEdBQUcsSUFBSSxXQUFXLENBQUMsQ0FBQyxFQUFFLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUM7SUFDcEQsYUFBYSxHQUFHLElBQUksV0FBVyxDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDO0lBRTVELEtBQUssQ0FBQyxLQUFLO1FBQ2xCLElBQUksQ0FBQyxRQUFRLEdBQUcscUJBQXFCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ25ELElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxTQUFTLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxjQUFjLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUNwRiw2RUFBNkU7UUFDN0UseUVBQXlFO1FBQ3pFLGtFQUFrRTtRQUNsRSxNQUFNLEVBQUUsUUFBUSxFQUFFLEdBQUcsTUFBTSxVQUFVLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUNyRSxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRTtZQUNuQixRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsTUFBTTtZQUNwQyxpQkFBaUIsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLGlCQUFpQjtZQUNsRCxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsZUFBZSxFQUFFLFFBQVEsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7U0FDNUYsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVRLE9BQU87UUFDZCxPQUFPO1lBQ0wsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxpQkFBaUI7WUFDbEQsT0FBTyxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDO1lBQ3JELE1BQU0sRUFBRSxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDO1lBQy9ELE9BQU8sRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQztZQUN4QyxNQUFNLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDeEIsYUFBYSxFQUFFLE9BQU8sQ0FBQyxNQUFNLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDbEQsS0FBSyxFQUFFLENBQUMsTUFBTSxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxTQUFTO2dCQUNoRCxPQUFPLEVBQUUsSUFBSTthQUNkLENBQUM7U0FDSCxDQUFDO0lBQ0osQ0FBQztJQUVPLEtBQUssQ0FBQyxhQUFhLENBQ3pCLEtBQWEsRUFDYixFQUFVO1FBRVYsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQzNDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNqRCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxTQUFTLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDNUQsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDdEMsT0FBTyxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVLElBQUksT0FBTyxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ3pFLENBQUM7UUFDRCxJQUFJLGNBQWMsQ0FBQyxPQUFPLENBQUMsSUFBSSxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzlFLE1BQU0sSUFBSSxHQUFHLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDN0MsSUFBSSxDQUFDO2dCQUNILE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFO29CQUMxQyxPQUFPLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPO29CQUM5QixTQUFTLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTO29CQUNsQyxPQUFPLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPO29CQUM5QixjQUFjLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxjQUFjO2lCQUM3QyxDQUFDLENBQUM7WUFDTCxDQUFDO1lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztnQkFDZixNQUFNLENBQUMsSUFBSSxDQUFDLDBCQUEwQixFQUFFLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztZQUNyRCxDQUFDO1FBQ0gsQ0FBQztRQUNELE9BQU8sRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLENBQUM7SUFDdEIsQ0FBQztJQUVPLEtBQUssQ0FBQyxZQUFZLENBQ3hCLEtBQWEsRUFDYixJQUFZLEVBQ1osRUFBVTtRQUVWLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUMzQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDaEQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsU0FBUyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQzNELElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3RDLE9BQU8sRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVSxJQUFJLE9BQU8sQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUMxRSxDQUFDO1FBQ0QsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLEtBQUssSUFBSTtZQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLENBQUM7UUFDbkYsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsU0FBUyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQzlDLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLFNBQVMsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUM3QyxPQUFPLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsTUFBTSxXQUFXLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsaUJBQWlCLENBQUMsRUFBRSxDQUFDO0lBQzFGLENBQUM7O0FBR0gsa0ZBQWtGO0FBQ2xGLE1BQU0sQ0FBQyxNQUFNLFFBQVEsR0FBRyxRQUFRLENBQUMsY0FBYyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIGBhdXRoR2F0ZSgpYCAtIHRoZSBBcHBLaXQgcGx1Z2luIGJlaGluZCB0aGUgdHVubmVsJ3MgZW1haWwtT1RQIGdhdGUuXG4gKlxuICogSXQgaGFzIE5PIHJvdXRlcyBvZiBpdHMgb3duOiB0aGUgdHVubmVsIFBST1hZIChub3QgYW4gSFRUUCBzZXJ2ZXIpIGNhbGxzIHRoZVxuICogaGFuZGxlcnMgdGhpcyBwbHVnaW4gZXhwb3NlcyB2aWEge0BsaW5rIEF1dGhHYXRlUGx1Z2luLmV4cG9ydHN9LiBUaGUgcGx1Z2luXG4gKiBvd25zIHRoZSBhbGxvdy1saXN0LCB0aGUgcGVyLWVtYWlsL3Blci1JUCByYXRlIGxpbWl0ZXJzLCB0aGUgQ2FjaGVNYW5hZ2VyLWJhY2tlZFxuICogb25lLXRpbWUtY29kZSBzdG9yZSwgYW5kIHRoZSBzZXNzaW9uIEpXVC4gYGNyZWF0ZUFwcGAgKHdpdGggbm8gYHNlcnZlcigpYCkgaXNcbiAqIHVzZWQgb25seSB0byBhdXRvLWluaXQgYENhY2hlTWFuYWdlcmAgKyBwcmltZSB0aGUgc2libGluZyBgZW1haWxgIHRyYW5zcG9ydDtcbiAqIHRoaXMgcGx1Z2luIGlzIHdoZXJlIHRoZSBnYXRlIGxvZ2ljIGxpdmVzLlxuICpcbiAqIE9wdGlvbnMgY29tZSBmcm9tIENMSSBmbGFncyBPUiBlbnYsIHdpdGggc2Vuc2libGUgZGVmYXVsdHMgLSBzZWVcbiAqIHtAbGluayByZXNvbHZlQXV0aEdhdGVDb25maWd9LiBUaGUgb25lIHJ1bnRpbWUgZGVwZW5kZW5jeSB0aGUgcGx1Z2luIGNhbid0XG4gKiByZXNvbHZlIGl0c2VsZiBpcyBIT1cgdG8gZW1haWwgdGhlIGNvZGUsIHNvIGl0IHRha2VzIGEgYHNlbmRDb2RlYCBjYWxsYmFjayB0aGVcbiAqIGFwcCB3aXJlcyB0byB0aGUgZW1haWwgcGx1Z2luLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBQbHVnaW4sIHRvUGx1Z2luLCB0eXBlIEJhc2VQbHVnaW5Db25maWcsIHR5cGUgUGx1Z2luTWFuaWZlc3QgfSBmcm9tIFwiQGRhdGFicmlja3MvYXBwa2l0XCI7XG5pbXBvcnQgeyBicmFuZCwgZW52LCBsb2csIG9iamVjdCwgc3RyaW5nIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB0eXBlIHsgQXV0aFN0YXR1cyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1lbWFpbFwiO1xuaW1wb3J0IHsgbG9va3NMaWtlRW1haWwsIG1hdGNoZXNBbGxvd2xpc3QgfSBmcm9tIFwiLi9hbGxvd2xpc3QudHNcIjtcbmltcG9ydCB7XG4gIEFMTE9XX0VOVixcbiAgQlJBTkRfTkFNRV9FTlYsXG4gIENPREVfVFRMX0VOVixcbiAgTUVTU0FHRV9FTlYsXG4gIFNFU1NJT05fVFRMX0VOVixcbiAgU1VCSkVDVF9FTlYsXG59IGZyb20gXCIuL2Vudi50c1wiO1xuaW1wb3J0IHsgQ29kZVN0b3JlLCBzaWduU2Vzc2lvbiwgdmVyaWZ5U2Vzc2lvbiB9IGZyb20gXCIuL290cC50c1wiO1xuaW1wb3J0IHsgUmF0ZUxpbWl0ZXIgfSBmcm9tIFwiLi9yYXRlLWxpbWl0LnRzXCI7XG5pbXBvcnQgeyBLRVlfVFRMX1NFQ09ORFMsIHJlc29sdmVTZXNzaW9uQ3V0b2ZmLCBzaWduaW5nS2V5IH0gZnJvbSBcIi4vc2lnbmluZy1rZXkudHNcIjtcblxuY29uc3QgbG9nZ2VyID0gbG9nLmxvZ2dlcihcInR1bm5lbDphdXRoXCIpO1xuXG4vKiogT3B0aW9ucyBmb3IgdGhlIHtAbGluayBhdXRoR2F0ZX0gcGx1Z2luIChhbGwgcmVzb2x2YWJsZSBmcm9tIGVudiAtIHNlZSBiZWxvdykuICovXG5leHBvcnQgaW50ZXJmYWNlIEF1dGhHYXRlQ29uZmlnIGV4dGVuZHMgQmFzZVBsdWdpbkNvbmZpZyB7XG4gIC8qKiBBbGxvdy1saXN0IHBhdHRlcm5zIChkb21haW4gLyBnbG9iIC8gYC9yZWdleC9gKS4gRW1wdHkgPSBhbGxvdyBub2JvZHkuIEVudiBUVU5ORUxfQVVUSF9BTExPVy4gKi9cbiAgYWxsb3c/OiBzdHJpbmcgfCBzdHJpbmdbXTtcbiAgLyoqXG4gICAqIFN1YmplY3QgbGluZSBmb3IgdGhlIGNvZGUgZW1haWwuIEVudiBUVU5ORUxfQVVUSF9TVUJKRUNULlxuICAgKlxuICAgKiBEZWZhdWx0cyB0byBcIllvdXIgdmVyaWZpY2F0aW9uIGNvZGVcIi4gVGhlIHdvcmRpbmcgb2YgdGhlIHN1YmplY3QgYW5kXG4gICAqIHtAbGluayBtZXNzYWdlfSBpcyBkZWxpYmVyYXRlbHkgdGhlIGNvbnZlbnRpb25hbCBwaHJhc2luZyByYXRoZXIgdGhhblxuICAgKiBhbnl0aGluZyBicmFuZGVkOiBpT1MsIEdtYWlsLCBPdXRsb29rLCBhbmQgQW5kcm9pZCBhbGwgZGV0ZWN0IGEgb25lLXRpbWVcbiAgICogY29kZSBmcm9tIHRoaXMgc2hhcGUgYW5kIG9mZmVyIHRvIGF1dG9maWxsIGl0LCBhbmQgYSBub3ZlbCBwaHJhc2luZyBpcyB3aGF0XG4gICAqIGJyZWFrcyB0aGF0IGRldGVjdGlvbi5cbiAgICovXG4gIHN1YmplY3Q/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBEaXNwbGF5IG5hbWUgdXNlZCBpbiB0aGUgY29kZSBlbWFpbCBjb3B5LiBFbnYgVFVOTkVMX0FVVEhfQlJBTkRfTkFNRS5cbiAgICpcbiAgICogRGVmYXVsdHMgdG8gdGhlIGJyYW5kIGNvbnRleHQncyBgbmFtZWAgLSB0aGUgYXBwJ3Mgb3duIGBicmFuZGluZy9icmFuZC55YW1sYFxuICAgKiB3aGVuIGl0IGhhcyBvbmUsIGVsc2UgdGhlIGRieC10b29scyBkZWZhdWx0LiBTZXQgdGhpcyBvbmx5IHRvIG92ZXJyaWRlIHRoZVxuICAgKiBicmFuZCBmb3IgdGhpcyBnYXRlLlxuICAgKi9cbiAgYnJhbmROYW1lPzogc3RyaW5nO1xuICAvKipcbiAgICogTGluZSBzaG93biBpbW1lZGlhdGVseSBhYm92ZSB0aGUgY29kZSBpbiB0aGUgZW1haWwuIEVudiBUVU5ORUxfQVVUSF9NRVNTQUdFLlxuICAgKlxuICAgKiBLZWVwIHRoZSBjb2RlIG9uIGl0cyBPV04gbGluZSBkaXJlY3RseSBhZnRlciB0aGlzIHRleHQgLSB0aGF0IGFkamFjZW5jeSBpc1xuICAgKiB3aGF0IHRoZSBwbGF0Zm9ybSBjb2RlLWRldGVjdGlvbiBoZXVyaXN0aWNzIGtleSBvbi5cbiAgICovXG4gIG1lc3NhZ2U/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBTZXNzaW9uIGxpZmV0aW1lIChzZWNvbmRzKS4gRW52IFRVTk5FTF9BVVRIX1NFU1NJT05fVFRMLiBEZWZhdWx0IDI1OTIwMDAgKDMwZCkuXG4gICAqXG4gICAqIE1hdGNoZWQgdG8gdGhlIGNhY2hlLWJhY2tlZCBzaWduaW5nIGtleSdzIG93biAzMC1kYXkgVFRMIChzZWVcbiAgICogYC4vc2lnbmluZy1rZXkudHNgKTogdGhlIGNvb2tpZSBhbmQgdGhlIGtleSB0aGF0IHZhbGlkYXRlcyBpdCBzaG91bGQgZXhwaXJlXG4gICAqIHRvZ2V0aGVyLCBvciBvbmUgc2lsZW50bHkgb3V0bGl2ZXMgdGhlIG90aGVyLlxuICAgKi9cbiAgc2Vzc2lvblR0bFNlY29uZHM/OiBudW1iZXI7XG4gIC8qKiBPbmUtdGltZS1jb2RlIGxpZmV0aW1lIChzZWNvbmRzKS4gRW52IFRVTk5FTF9BVVRIX0NPREVfVFRMLiBEZWZhdWx0IDYwMCAoMTBtKS4gKi9cbiAgY29kZVR0bFNlY29uZHM/OiBudW1iZXI7XG4gIC8qKiBNYXggdmVyaWZ5IGF0dGVtcHRzIHBlciBpc3N1ZWQgY29kZS4gRGVmYXVsdCA1LiAqL1xuICBtYXhBdHRlbXB0cz86IG51bWJlcjtcbiAgLyoqXG4gICAqIEZvcmNlLWNsZWFyIGN1dG9mZjogZXZlcnkgc2Vzc2lvbiBpc3N1ZWQgQkVGT1JFIGl0IHN0b3BzIHZlcmlmeWluZywgc28gbW92aW5nXG4gICAqIGl0IGZvcndhcmQgc2lnbnMgZXZlcnlvbmUgb3V0LiBFbnYgVFVOTkVMX0FVVEhfU0VTU0lPTl9DVVRPRkYuXG4gICAqXG4gICAqIEFueXRoaW5nIGBvYmplY3QudG9EYXRlYCBhY2NlcHRzOiBhIGBEYXRlYCwgYDIwMjYtMDgtMDJgLCBhbiBJU08gaW5zdGFudCxcbiAgICogZXBvY2ggc2Vjb25kcy9taWxsaXMsIG9yIGEgcmVsYXRpdmUgZHVyYXRpb24gKGAtMzBkYCwgYDcgZGF5cyBhZ29gKS4gVW5zZXRcbiAgICogbWVhbnMgbm8gY3V0b2ZmLlxuICAgKi9cbiAgc2Vzc2lvbkN1dG9mZj86IHN0cmluZyB8IG51bWJlciB8IERhdGU7XG4gIC8qKiBEZWxpdmVyIGEgY29kZSB0byBhbiBhZGRyZXNzLiBXaXJlZCBieSB0aGUgYXBwIHRvIHRoZSBlbWFpbCBwbHVnaW4uICovXG4gIHNlbmRDb2RlPzogKGVtYWlsOiBzdHJpbmcsIGNvZGU6IHN0cmluZywgb3B0czogU2VuZENvZGVPcHRpb25zKSA9PiBQcm9taXNlPHZvaWQ+O1xufVxuXG4vKiogQnJhbmRpbmcvbWVzc2FnaW5nIHBhc3NlZCB0byB7QGxpbmsgQXV0aEdhdGVDb25maWcuc2VuZENvZGV9LiAqL1xuZXhwb3J0IGludGVyZmFjZSBTZW5kQ29kZU9wdGlvbnMge1xuICBzdWJqZWN0OiBzdHJpbmc7XG4gIGJyYW5kTmFtZTogc3RyaW5nO1xuICBtZXNzYWdlOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBMaWZldGltZSBvZiB0aGUgY29kZSBiZWluZyBzZW50LCBpbiBzZWNvbmRzIC0gdGhlIFJFU09MVkVEXG4gICAqIHtAbGluayBBdXRoR2F0ZUNvbmZpZy5jb2RlVHRsU2Vjb25kc30sIHNvIHRoZSBlbWFpbCBjYW4gc3RhdGUgdGhlIHJlYWxcbiAgICogZXhwaXJ5IChcIlRoaXMgY29kZSBleHBpcmVzIGluIDEwIG1pbnV0ZXNcIikgaW5zdGVhZCBvZiBhIHZhZ3VlIFwic2hvcnRseVwiXG4gICAqIHRoYXQgZHJpZnRzIGZyb20gdGhlIGNvbmZpZ3VyZWQgVFRMLlxuICAgKi9cbiAgY29kZVR0bFNlY29uZHM6IG51bWJlcjtcbn1cblxuLyoqIFJlc29sdmVkIGdhdGUgY29uZmlnIHdpdGggZW52IGZhbGxiYWNrcyArIGRlZmF1bHRzIGFwcGxpZWQuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlc29sdmVkQXV0aEdhdGVDb25maWcge1xuICBhbGxvdzogc3RyaW5nW107XG4gIHN1YmplY3Q6IHN0cmluZztcbiAgYnJhbmROYW1lOiBzdHJpbmc7XG4gIG1lc3NhZ2U6IHN0cmluZztcbiAgc2Vzc2lvblR0bFNlY29uZHM6IG51bWJlcjtcbiAgY29kZVR0bFNlY29uZHM6IG51bWJlcjtcbiAgbWF4QXR0ZW1wdHM6IG51bWJlcjtcbiAgLyoqIEZvcmNlLWNsZWFyIGN1dG9mZiBpbiBlcG9jaCBtczsgYDBgIHdoZW4gdW5zZXQuICovXG4gIHNlc3Npb25DdXRvZmZNczogbnVtYmVyO1xufVxuXG5jb25zdCBERUZBVUxUUyA9IHtcbiAgc3ViamVjdDogXCJZb3VyIHZlcmlmaWNhdGlvbiBjb2RlXCIsXG4gIC8vIFRoZSByZXBvLXdpZGUgYnJhbmQgY29udGV4dCdzIGRpc3BsYXkgbmFtZSwgTk9UIGEgaGFyZGNvZGVkIHByb2R1Y3Qgc3RyaW5nOlxuICAvLyB0aGlzIG5hbWUgaXMgd2hhdCB0aGUgcmVjaXBpZW50IHJlYWRzIGluIHRoZSBjb2RlIGVtYWlsLCBzbyBpdCBoYXMgdG8gYmUgdGhlXG4gIC8vIHNhbWUgaWRlbnRpdHkgdGhlIHJlc3Qgb2YgdGhlIGFwcCBwcmVzZW50cy4gQSBob3N0IHdpdGggaXRzIG93blxuICAvLyBgYnJhbmRpbmcvYnJhbmQueWFtbGAgb3ZlcnJpZGVzIGl0IGJ5IHBhc3NpbmcgYGJyYW5kTmFtZWAgKHNlZVxuICAvLyB7QGxpbmsgc3RhcnRHYXRlQXBwfSwgd2hpY2ggcmVzb2x2ZXMgdGhlIG9uLWRpc2sgY29udGV4dCk7IHRoZSBzaGFyZWQgZGVmYXVsdFxuICAvLyBpcyB0aGUgZmFsbGJhY2sgd2hlbiBub3RoaW5nIGlzIGNvbmZpZ3VyZWQuXG4gIGJyYW5kTmFtZTogYnJhbmQuZGVmYXVsdEJyYW5kQ29udGV4dC5uYW1lLFxuICBtZXNzYWdlOiBcIllvdXIgdmVyaWZpY2F0aW9uIGNvZGUgaXM6XCIsXG4gIC8vIDMwIGRheXMsIHRoZSBzYW1lIHdpbmRvdyB0aGUgY2FjaGUtYmFja2VkIHNpZ25pbmcga2V5IGlzIHN0b3JlZCBmb3IuXG4gIHNlc3Npb25UdGxTZWNvbmRzOiBLRVlfVFRMX1NFQ09ORFMsXG4gIGNvZGVUdGxTZWNvbmRzOiA2MDAsXG4gIG1heEF0dGVtcHRzOiA1LFxufTtcblxuLyoqIE1lcmdlIHtAbGluayBBdXRoR2F0ZUNvbmZpZ30gb3ZlciBlbnYgb3ZlciBkZWZhdWx0cyBpbnRvIGEgcmVzb2x2ZWQgY29uZmlnLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVBdXRoR2F0ZUNvbmZpZyhjb25maWc6IEF1dGhHYXRlQ29uZmlnKTogUmVzb2x2ZWRBdXRoR2F0ZUNvbmZpZyB7XG4gIHJldHVybiB7XG4gICAgLy8gQm90aCBzb3VyY2VzIGFyZSB1bmlvbmVkIHJhdGhlciB0aGFuIG9uZSBvdmVycmlkaW5nOiBhIGRlcGxveW1lbnQtd2lkZVxuICAgIC8vIFRVTk5FTF9BVVRIX0FMTE9XIGFuZCBhIHBlci1pbnZvY2F0aW9uIGAtLWFsbG93YCBzaG91bGQgYm90aCBncmFudCBhY2Nlc3MuXG4gICAgLy8gSGVuY2UgYHBhcnNlTGlzdGAgb24gZWFjaCByYXRoZXIgdGhhbiBgZW52Lmxpc3RgLCB3aGljaCBzdG9wcyBhdCB0aGUgZmlyc3RcbiAgICAvLyBzb3VyY2UgdGhhdCB5aWVsZHMgYW55dGhpbmcuXG4gICAgYWxsb3c6IFsuLi5zdHJpbmcucGFyc2VMaXN0KGNvbmZpZy5hbGxvdyksIC4uLnN0cmluZy5wYXJzZUxpc3QoZW52LnRleHQoQUxMT1dfRU5WKSldLFxuICAgIHN1YmplY3Q6IGVudi5zdHJpbmcoY29uZmlnLnN1YmplY3QsIFNVQkpFQ1RfRU5WKSA/PyBERUZBVUxUUy5zdWJqZWN0LFxuICAgIGJyYW5kTmFtZTogZW52LnN0cmluZyhjb25maWcuYnJhbmROYW1lLCBCUkFORF9OQU1FX0VOVikgPz8gREVGQVVMVFMuYnJhbmROYW1lLFxuICAgIG1lc3NhZ2U6IGVudi5zdHJpbmcoY29uZmlnLm1lc3NhZ2UsIE1FU1NBR0VfRU5WKSA/PyBERUZBVUxUUy5tZXNzYWdlLFxuICAgIHNlc3Npb25UdGxTZWNvbmRzOiBlbnYucG9zaXRpdmVJbnQoXG4gICAgICBjb25maWcuc2Vzc2lvblR0bFNlY29uZHMsXG4gICAgICBTRVNTSU9OX1RUTF9FTlYsXG4gICAgICBERUZBVUxUUy5zZXNzaW9uVHRsU2Vjb25kcyxcbiAgICApLFxuICAgIGNvZGVUdGxTZWNvbmRzOiBlbnYucG9zaXRpdmVJbnQoY29uZmlnLmNvZGVUdGxTZWNvbmRzLCBDT0RFX1RUTF9FTlYsIERFRkFVTFRTLmNvZGVUdGxTZWNvbmRzKSxcbiAgICBtYXhBdHRlbXB0czogY29uZmlnLm1heEF0dGVtcHRzID8/IERFRkFVTFRTLm1heEF0dGVtcHRzLFxuICAgIHNlc3Npb25DdXRvZmZNczogcmVzb2x2ZVNlc3Npb25DdXRvZmYoY29uZmlnLnNlc3Npb25DdXRvZmYpLFxuICB9O1xufVxuXG4vKiogVGhlIGhhbmRsZXJzIHRoZSBwcm94eSBjYWxscyBpbi1wcm9jZXNzIChyZXR1cm5lZCBieSB7QGxpbmsgQXV0aEdhdGVQbHVnaW4uZXhwb3J0c30pLiAqL1xuZXhwb3J0IGludGVyZmFjZSBBdXRoR2F0ZUFwaSB7XG4gIC8qKiBIYW5kbGUgYSBjb2RlIHJlcXVlc3QuIEFsd2F5cyByZXNvbHZlcyBgeyBvazogdHJ1ZSB9YCAoYW50aS1lbnVtZXJhdGlvbikuICovXG4gIHJlcXVlc3QoZW1haWw6IHN0cmluZywgaXA6IHN0cmluZyk6IFByb21pc2U8eyBvazogdHJ1ZTsgcmV0cnlBZnRlcj86IG51bWJlciB9PjtcbiAgLyoqIEhhbmRsZSBhIGNvZGUgdmVyaWZpY2F0aW9uLiBPbiBzdWNjZXNzIHJldHVybnMgdGhlIHNlc3Npb24gdG9rZW4gdG8gY29va2llLiAqL1xuICB2ZXJpZnkoXG4gICAgZW1haWw6IHN0cmluZyxcbiAgICBjb2RlOiBzdHJpbmcsXG4gICAgaXA6IHN0cmluZyxcbiAgKTogUHJvbWlzZTx7IG9rOiBib29sZWFuOyB0b2tlbj86IHN0cmluZzsgcmV0cnlBZnRlcj86IG51bWJlciB9PjtcbiAgLyoqIFJlc29sdmUgdGhlIGF1dGhlbnRpY2F0ZWQgZW1haWwgZm9yIGEgc2Vzc2lvbiB0b2tlbiwgb3IgdW5kZWZpbmVkLiAqL1xuICBzZXNzaW9uKHRva2VuOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBQcm9taXNlPHN0cmluZyB8IHVuZGVmaW5lZD47XG4gIC8qKiBTZXNzaW9uIFRUTCBpbiBzZWNvbmRzIChmb3IgdGhlIGNvb2tpZSBNYXgtQWdlKS4gKi9cbiAgcmVhZG9ubHkgc2Vzc2lvblR0bFNlY29uZHM6IG51bWJlcjtcbiAgLyoqIFRoZSBnYXRlIHN0YXR1cyBwYXlsb2FkIChgZW5hYmxlZGAgaXMgYWx3YXlzIHRydWUgd2hlbiB0aGlzIHBsdWdpbiBydW5zKS4gKi9cbiAgc3RhdHVzKHRva2VuOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBQcm9taXNlPEF1dGhTdGF0dXM+O1xufVxuXG4vKiogQXBwS2l0IHBsdWdpbiBvd25pbmcgdGhlIGVtYWlsLU9UUCBnYXRlJ3MgbG9naWMgKG5vIEhUVFAgcm91dGVzOyBwcm94eS1kcml2ZW4pLiAqL1xuZXhwb3J0IGNsYXNzIEF1dGhHYXRlUGx1Z2luIGV4dGVuZHMgUGx1Z2luPEF1dGhHYXRlQ29uZmlnPiB7XG4gIHN0YXRpYyBtYW5pZmVzdCA9IHtcbiAgICBuYW1lOiBcImF1dGhHYXRlXCIsXG4gICAgZGlzcGxheU5hbWU6IFwiQXV0aCBHYXRlXCIsXG4gICAgZGVzY3JpcHRpb246IFwiRW1haWwgb25lLXRpbWUtcGFzc3dvcmQgYWNjZXNzIGdhdGUgZm9yIGEgcHVibGljIHR1bm5lbC5cIixcbiAgICBzdGFiaWxpdHk6IFwiYmV0YVwiLFxuICAgIHJlc291cmNlczogeyByZXF1aXJlZDogW10sIG9wdGlvbmFsOiBbXSB9LFxuICB9IHNhdGlzZmllcyBQbHVnaW5NYW5pZmVzdDxcImF1dGhHYXRlXCI+O1xuXG4gIHByaXZhdGUgcmVzb2x2ZWQhOiBSZXNvbHZlZEF1dGhHYXRlQ29uZmlnO1xuICBwcml2YXRlIGNvZGVzITogQ29kZVN0b3JlO1xuICAvLyBSZXF1ZXN0aW5nIGEgY29kZSBpcyBlbWFpbC1zcGFtLXByb25lOyB2ZXJpZnlpbmcgaXMgYSBicnV0ZS1mb3JjZSBzdXJmYWNlLlxuICAvLyBQZXItZW1haWwgQU5EIHBlci1JUCBzbyBuZWl0aGVyIGF4aXMgYWxvbmUgaXMgYSBieXBhc3MuXG4gIHByaXZhdGUgcmVhZG9ubHkgcmVxdWVzdExpbWl0ZXIgPSBuZXcgUmF0ZUxpbWl0ZXIoNSwgMTUgKiA2MCAqIDEwMDApO1xuICBwcml2YXRlIHJlYWRvbmx5IHZlcmlmeUxpbWl0ZXIgPSBuZXcgUmF0ZUxpbWl0ZXIoMTAsIDE1ICogNjAgKiAxMDAwKTtcblxuICBvdmVycmlkZSBhc3luYyBzZXR1cCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLnJlc29sdmVkID0gcmVzb2x2ZUF1dGhHYXRlQ29uZmlnKHRoaXMuY29uZmlnKTtcbiAgICB0aGlzLmNvZGVzID0gbmV3IENvZGVTdG9yZSh0aGlzLnJlc29sdmVkLmNvZGVUdGxTZWNvbmRzLCB0aGlzLnJlc29sdmVkLm1heEF0dGVtcHRzKTtcbiAgICAvLyBSZXNvbHZlIHRoZSBzaWduaW5nIGtleSBIRVJFIHJhdGhlciB0aGFuIGxhemlseSBvbiB0aGUgZmlyc3Qgc2lnbi1pbiwgc28gYVxuICAgIC8vIGNhY2hlIHRoYXQgY2Fubm90IGhvbGQgaXQgKGFuZCB0aGUgcmVzdWx0aW5nIFwic2Vzc2lvbnMgd29uJ3Qgc3Vydml2ZSBhXG4gICAgLy8gcmVzdGFydFwiIHdhcm5pbmcpIHNob3dzIHVwIGluIHRoZSBzdGFydHVwIGxvZywgbm90IGhvdXJzIGxhdGVyLlxuICAgIGNvbnN0IHsgY3V0b2ZmTXMgfSA9IGF3YWl0IHNpZ25pbmdLZXkodGhpcy5yZXNvbHZlZC5zZXNzaW9uQ3V0b2ZmTXMpO1xuICAgIGxvZ2dlci5pbmZvKFwicmVhZHlcIiwge1xuICAgICAgcGF0dGVybnM6IHRoaXMucmVzb2x2ZWQuYWxsb3cubGVuZ3RoLFxuICAgICAgc2Vzc2lvblR0bFNlY29uZHM6IHRoaXMucmVzb2x2ZWQuc2Vzc2lvblR0bFNlY29uZHMsXG4gICAgICAuLi5vYmplY3Qub3B0aW9uYWwoXCJzZXNzaW9uQ3V0b2ZmXCIsIGN1dG9mZk1zID4gMCA/IG5ldyBEYXRlKGN1dG9mZk1zKS50b0lTT1N0cmluZygpIDogbnVsbCksXG4gICAgfSk7XG4gIH1cblxuICBvdmVycmlkZSBleHBvcnRzKCk6IEF1dGhHYXRlQXBpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc2Vzc2lvblR0bFNlY29uZHM6IHRoaXMucmVzb2x2ZWQuc2Vzc2lvblR0bFNlY29uZHMsXG4gICAgICByZXF1ZXN0OiAoZW1haWwsIGlwKSA9PiB0aGlzLmhhbmRsZVJlcXVlc3QoZW1haWwsIGlwKSxcbiAgICAgIHZlcmlmeTogKGVtYWlsLCBjb2RlLCBpcCkgPT4gdGhpcy5oYW5kbGVWZXJpZnkoZW1haWwsIGNvZGUsIGlwKSxcbiAgICAgIHNlc3Npb246ICh0b2tlbikgPT4gdmVyaWZ5U2Vzc2lvbih0b2tlbiksXG4gICAgICBzdGF0dXM6IGFzeW5jICh0b2tlbikgPT4gKHtcbiAgICAgICAgYXV0aGVudGljYXRlZDogQm9vbGVhbihhd2FpdCB2ZXJpZnlTZXNzaW9uKHRva2VuKSksXG4gICAgICAgIGVtYWlsOiAoYXdhaXQgdmVyaWZ5U2Vzc2lvbih0b2tlbikpID8/IHVuZGVmaW5lZCxcbiAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgIH0pLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGhhbmRsZVJlcXVlc3QoXG4gICAgZW1haWw6IHN0cmluZyxcbiAgICBpcDogc3RyaW5nLFxuICApOiBQcm9taXNlPHsgb2s6IHRydWU7IHJldHJ5QWZ0ZXI/OiBudW1iZXIgfT4ge1xuICAgIGNvbnN0IGFkZHJlc3MgPSBlbWFpbC50cmltKCkudG9Mb3dlckNhc2UoKTtcbiAgICBjb25zdCBieUlwID0gdGhpcy5yZXF1ZXN0TGltaXRlci5oaXQoYGlwOiR7aXB9YCk7XG4gICAgY29uc3QgYnlFbWFpbCA9IHRoaXMucmVxdWVzdExpbWl0ZXIuaGl0KGBlbWFpbDoke2FkZHJlc3N9YCk7XG4gICAgaWYgKCFieUlwLmFsbG93ZWQgfHwgIWJ5RW1haWwuYWxsb3dlZCkge1xuICAgICAgcmV0dXJuIHsgb2s6IHRydWUsIHJldHJ5QWZ0ZXI6IGJ5SXAucmV0cnlBZnRlciA/PyBieUVtYWlsLnJldHJ5QWZ0ZXIgfTtcbiAgICB9XG4gICAgaWYgKGxvb2tzTGlrZUVtYWlsKGFkZHJlc3MpICYmIG1hdGNoZXNBbGxvd2xpc3QoYWRkcmVzcywgdGhpcy5yZXNvbHZlZC5hbGxvdykpIHtcbiAgICAgIGNvbnN0IGNvZGUgPSBhd2FpdCB0aGlzLmNvZGVzLmlzc3VlKGFkZHJlc3MpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5jb25maWcuc2VuZENvZGU/LihhZGRyZXNzLCBjb2RlLCB7XG4gICAgICAgICAgc3ViamVjdDogdGhpcy5yZXNvbHZlZC5zdWJqZWN0LFxuICAgICAgICAgIGJyYW5kTmFtZTogdGhpcy5yZXNvbHZlZC5icmFuZE5hbWUsXG4gICAgICAgICAgbWVzc2FnZTogdGhpcy5yZXNvbHZlZC5tZXNzYWdlLFxuICAgICAgICAgIGNvZGVUdGxTZWNvbmRzOiB0aGlzLnJlc29sdmVkLmNvZGVUdGxTZWNvbmRzLFxuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKFwiZmFpbGVkIHRvIHNlbmQgT1RQIGVtYWlsXCIsIHsgZXJyb3IgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7IG9rOiB0cnVlIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGhhbmRsZVZlcmlmeShcbiAgICBlbWFpbDogc3RyaW5nLFxuICAgIGNvZGU6IHN0cmluZyxcbiAgICBpcDogc3RyaW5nLFxuICApOiBQcm9taXNlPHsgb2s6IGJvb2xlYW47IHRva2VuPzogc3RyaW5nOyByZXRyeUFmdGVyPzogbnVtYmVyIH0+IHtcbiAgICBjb25zdCBhZGRyZXNzID0gZW1haWwudHJpbSgpLnRvTG93ZXJDYXNlKCk7XG4gICAgY29uc3QgYnlJcCA9IHRoaXMudmVyaWZ5TGltaXRlci5oaXQoYGlwOiR7aXB9YCk7XG4gICAgY29uc3QgYnlFbWFpbCA9IHRoaXMudmVyaWZ5TGltaXRlci5oaXQoYGVtYWlsOiR7YWRkcmVzc31gKTtcbiAgICBpZiAoIWJ5SXAuYWxsb3dlZCB8fCAhYnlFbWFpbC5hbGxvd2VkKSB7XG4gICAgICByZXR1cm4geyBvazogZmFsc2UsIHJldHJ5QWZ0ZXI6IGJ5SXAucmV0cnlBZnRlciA/PyBieUVtYWlsLnJldHJ5QWZ0ZXIgfTtcbiAgICB9XG4gICAgaWYgKChhd2FpdCB0aGlzLmNvZGVzLnZlcmlmeShhZGRyZXNzLCBjb2RlLnRyaW0oKSkpICE9PSBcIm9rXCIpIHJldHVybiB7IG9rOiBmYWxzZSB9O1xuICAgIHRoaXMucmVxdWVzdExpbWl0ZXIucmVzZXQoYGVtYWlsOiR7YWRkcmVzc31gKTtcbiAgICB0aGlzLnZlcmlmeUxpbWl0ZXIucmVzZXQoYGVtYWlsOiR7YWRkcmVzc31gKTtcbiAgICByZXR1cm4geyBvazogdHJ1ZSwgdG9rZW46IGF3YWl0IHNpZ25TZXNzaW9uKGFkZHJlc3MsIHRoaXMucmVzb2x2ZWQuc2Vzc2lvblR0bFNlY29uZHMpIH07XG4gIH1cbn1cblxuLyoqIEZhY3Rvcnk6IGBhdXRoR2F0ZSh7IGFsbG93LCBzdWJqZWN0LCAuLi4gfSlgIGZvciBhbiBBcHBLaXQgYHBsdWdpbnNgIGFycmF5LiAqL1xuZXhwb3J0IGNvbnN0IGF1dGhHYXRlID0gdG9QbHVnaW4oQXV0aEdhdGVQbHVnaW4pO1xuIl19
138
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3BsdWdpbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQUVILE9BQU8sRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUE4QyxNQUFNLG9CQUFvQixDQUFDO0FBQ2xHLE9BQU8sRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFekUsT0FBTyxFQUFFLGNBQWMsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2xFLE9BQU8sRUFDTCxTQUFTLEVBQ1QsY0FBYyxFQUNkLFlBQVksRUFDWixXQUFXLEVBQ1gsZUFBZSxFQUNmLFdBQVcsR0FDWixNQUFNLFVBQVUsQ0FBQztBQUNsQixPQUFPLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxhQUFhLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDakUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxlQUFlLEVBQUUsb0JBQW9CLEVBQUUsVUFBVSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFckYsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQztBQXdGekMsTUFBTSxRQUFRLEdBQUc7SUFDZixPQUFPLEVBQUUsd0JBQXdCO0lBQ2pDLDhFQUE4RTtJQUM5RSwrRUFBK0U7SUFDL0Usa0VBQWtFO0lBQ2xFLGlFQUFpRTtJQUNqRSxnRkFBZ0Y7SUFDaEYsOENBQThDO0lBQzlDLFNBQVMsRUFBRSxLQUFLLENBQUMsbUJBQW1CLENBQUMsSUFBSTtJQUN6QyxPQUFPLEVBQUUsNEJBQTRCO0lBQ3JDLHVFQUF1RTtJQUN2RSxpQkFBaUIsRUFBRSxlQUFlO0lBQ2xDLGNBQWMsRUFBRSxHQUFHO0lBQ25CLFdBQVcsRUFBRSxD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LEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDaEQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsU0FBUyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQzNELElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3RDLE9BQU8sRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVSxJQUFJLE9BQU8sQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUMxRSxDQUFDO1FBQ0QsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLEtBQUssSUFBSTtZQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLENBQUM7UUFDbkYsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsU0FBUyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQzlDLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLFNBQVMsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUM3QyxPQUFPLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsTUFBTSxXQUFXLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsaUJBQWlCLENBQUMsRUFBRSxDQUFDO0lBQzFGLENBQUM7O0FBR0gsa0ZBQWtGO0FBQ2xGLE1BQU0sQ0FBQyxNQUFNLFFBQVEsR0FBRyxRQUFRLENBQUMsY0FBYyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIGBhdXRoR2F0ZSgpYCAtIHRoZSBBcHBLaXQgcGx1Z2luIGJlaGluZCB0aGUgdHVubmVsJ3MgZW1haWwtT1RQIGdhdGUuXG4gKlxuICogSXQgaGFzIE5PIHJvdXRlcyBvZiBpdHMgb3duOiB0aGUgdHVubmVsIFBST1hZIChub3QgYW4gSFRUUCBzZXJ2ZXIpIGNhbGxzIHRoZVxuICogaGFuZGxlcnMgdGhpcyBwbHVnaW4gZXhwb3NlcyB2aWEge0BsaW5rIEF1dGhHYXRlUGx1Z2luLmV4cG9ydHN9LiBUaGUgcGx1Z2luXG4gKiBvd25zIHRoZSBhbGxvdy1saXN0LCB0aGUgcGVyLWVtYWlsL3Blci1JUCByYXRlIGxpbWl0ZXJzLCB0aGUgQ2FjaGVNYW5hZ2VyLWJhY2tlZFxuICogb25lLXRpbWUtY29kZSBzdG9yZSwgYW5kIHRoZSBzZXNzaW9uIEpXVC4gYGNyZWF0ZUFwcGAgKHdpdGggbm8gYHNlcnZlcigpYCkgaXNcbiAqIHVzZWQgb25seSB0byBhdXRvLWluaXQgYENhY2hlTWFuYWdlcmAgKyBwcmltZSB0aGUgc2libGluZyBgZW1haWxgIHRyYW5zcG9ydDtcbiAqIHRoaXMgcGx1Z2luIGlzIHdoZXJlIHRoZSBnYXRlIGxvZ2ljIGxpdmVzLlxuICpcbiAqIE9wdGlvbnMgY29tZSBmcm9tIENMSSBmbGFncyBPUiBlbnYsIHdpdGggc2Vuc2libGUgZGVmYXVsdHMgLSBzZWVcbiAqIHtAbGluayByZXNvbHZlQXV0aEdhdGVDb25maWd9LiBUaGUgb25lIHJ1bnRpbWUgZGVwZW5kZW5jeSB0aGUgcGx1Z2luIGNhbid0XG4gKiByZXNvbHZlIGl0c2VsZiBpcyBIT1cgdG8gZW1haWwgdGhlIGNvZGUsIHNvIGl0IHRha2VzIGEgYHNlbmRDb2RlYCBjYWxsYmFjayB0aGVcbiAqIGFwcCB3aXJlcyB0byB0aGUgZW1haWwgcGx1Z2luLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBQbHVnaW4sIHRvUGx1Z2luLCB0eXBlIEJhc2VQbHVnaW5Db25maWcsIHR5cGUgUGx1Z2luTWFuaWZlc3QgfSBmcm9tIFwiQGRhdGFicmlja3MvYXBwa2l0XCI7XG5pbXBvcnQgeyBicmFuZCwgZW52LCBsb2csIG9iamVjdCwgc3RyaW5nIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB0eXBlIHsgQXV0aFN0YXR1cyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1lbWFpbFwiO1xuaW1wb3J0IHsgbG9va3NMaWtlRW1haWwsIG1hdGNoZXNBbGxvd2xpc3QgfSBmcm9tIFwiLi9hbGxvd2xpc3QudHNcIjtcbmltcG9ydCB7XG4gIEFMTE9XX0VOVixcbiAgQlJBTkRfTkFNRV9FTlYsXG4gIENPREVfVFRMX0VOVixcbiAgTUVTU0FHRV9FTlYsXG4gIFNFU1NJT05fVFRMX0VOVixcbiAgU1VCSkVDVF9FTlYsXG59IGZyb20gXCIuL2Vudi50c1wiO1xuaW1wb3J0IHsgQ29kZVN0b3JlLCBzaWduU2Vzc2lvbiwgdmVyaWZ5U2Vzc2lvbiB9IGZyb20gXCIuL290cC50c1wiO1xuaW1wb3J0IHsgUmF0ZUxpbWl0ZXIgfSBmcm9tIFwiLi9yYXRlLWxpbWl0LnRzXCI7XG5pbXBvcnQgeyBLRVlfVFRMX1NFQ09ORFMsIHJlc29sdmVTZXNzaW9uQ3V0b2ZmLCBzaWduaW5nS2V5IH0gZnJvbSBcIi4vc2lnbmluZy1rZXkudHNcIjtcblxuY29uc3QgbG9nZ2VyID0gbG9nLmxvZ2dlcihcInR1bm5lbDphdXRoXCIpO1xuXG4vKiogT3B0aW9ucyBmb3IgdGhlIHtAbGluayBhdXRoR2F0ZX0gcGx1Z2luIChhbGwgcmVzb2x2YWJsZSBmcm9tIGVudiAtIHNlZSBiZWxvdykuICovXG5leHBvcnQgaW50ZXJmYWNlIEF1dGhHYXRlQ29uZmlnIGV4dGVuZHMgQmFzZVBsdWdpbkNvbmZpZyB7XG4gIC8qKiBBbGxvdy1saXN0IHBhdHRlcm5zIChkb21haW4gLyBnbG9iIC8gYC9yZWdleC9gKS4gRW1wdHkgPSBhbGxvdyBub2JvZHkuIEVudiBUVU5ORUxfQVVUSF9BTExPVy4gKi9cbiAgYWxsb3c/OiBzdHJpbmcgfCBzdHJpbmdbXTtcbiAgLyoqXG4gICAqIFN1YmplY3QgbGluZSBmb3IgdGhlIGNvZGUgZW1haWwuIEVudiBUVU5ORUxfQVVUSF9TVUJKRUNULlxuICAgKlxuICAgKiBEZWZhdWx0cyB0byBcIllvdXIgdmVyaWZpY2F0aW9uIGNvZGVcIi4gVGhlIHdvcmRpbmcgb2YgdGhlIHN1YmplY3QgYW5kXG4gICAqIHtAbGluayBtZXNzYWdlfSBpcyBkZWxpYmVyYXRlbHkgdGhlIGNvbnZlbnRpb25hbCBwaHJhc2luZyByYXRoZXIgdGhhblxuICAgKiBhbnl0aGluZyBicmFuZGVkOiBpT1MsIEdtYWlsLCBPdXRsb29rLCBhbmQgQW5kcm9pZCBhbGwgZGV0ZWN0IGEgb25lLXRpbWVcbiAgICogY29kZSBmcm9tIHRoaXMgc2hhcGUgYW5kIG9mZmVyIHRvIGF1dG9maWxsIGl0LCBhbmQgYSBub3ZlbCBwaHJhc2luZyBpcyB3aGF0XG4gICAqIGJyZWFrcyB0aGF0IGRldGVjdGlvbi5cbiAgICpcbiAgICogVGhpcyBpcyB0aGUgc3ViamVjdCBURU1QTEFURSwgbm90IHRoZSBsaXRlcmFsIGxpbmUgc2VudDogdGhlIGNvZGUgaXMgc3BsaWNlZFxuICAgKiBpbnRvIGl0IChgXCIxMjM0NTYgaXMgeW91ciB2ZXJpZmljYXRpb24gY29kZVwiYCkgYmVjYXVzZSBhIHB1c2ggbm90aWZpY2F0aW9uXG4gICAqIHNob3dzIG9ubHkgdGhlIHN1YmplY3QgYW5kIHByZWhlYWRlciwgYW5kIHRoYXQgbm90aWZpY2F0aW9uIGlzIHdoYXQgbW9iaWxlXG4gICAqIGF1dG9maWxsIHJlYWRzLiBTZWUgYGNvZGVFbWFpbFN1YmplY3RgIGluIGAuL2FwcC50c2AuXG4gICAqL1xuICBzdWJqZWN0Pzogc3RyaW5nO1xuICAvKipcbiAgICogRGlzcGxheSBuYW1lIHVzZWQgaW4gdGhlIGNvZGUgZW1haWwgY29weS4gRW52IFRVTk5FTF9BVVRIX0JSQU5EX05BTUUuXG4gICAqXG4gICAqIERlZmF1bHRzIHRvIHRoZSBicmFuZCBjb250ZXh0J3MgYG5hbWVgIC0gdGhlIGFwcCdzIG93biBgYnJhbmRpbmcvYnJhbmQueWFtbGBcbiAgICogd2hlbiBpdCBoYXMgb25lLCBlbHNlIHRoZSBkYngtdG9vbHMgZGVmYXVsdC4gU2V0IHRoaXMgb25seSB0byBvdmVycmlkZSB0aGVcbiAgICogYnJhbmQgZm9yIHRoaXMgZ2F0ZS5cbiAgICovXG4gIGJyYW5kTmFtZT86IHN0cmluZztcbiAgLyoqXG4gICAqIExpbmUgc2hvd24gaW1tZWRpYXRlbHkgYWJvdmUgdGhlIGNvZGUgaW4gdGhlIGVtYWlsLiBFbnYgVFVOTkVMX0FVVEhfTUVTU0FHRS5cbiAgICpcbiAgICogS2VlcCB0aGUgY29kZSBvbiBpdHMgT1dOIGxpbmUgZGlyZWN0bHkgYWZ0ZXIgdGhpcyB0ZXh0IC0gdGhhdCBhZGphY2VuY3kgaXNcbiAgICogd2hhdCB0aGUgcGxhdGZvcm0gY29kZS1kZXRlY3Rpb24gaGV1cmlzdGljcyBrZXkgb24uXG4gICAqL1xuICBtZXNzYWdlPzogc3RyaW5nO1xuICAvKipcbiAgICogU2Vzc2lvbiBsaWZldGltZSAoc2Vjb25kcykuIEVudiBUVU5ORUxfQVVUSF9TRVNTSU9OX1RUTC4gRGVmYXVsdCAyNTkyMDAwICgzMGQpLlxuICAgKlxuICAgKiBNYXRjaGVkIHRvIHRoZSBjYWNoZS1iYWNrZWQgc2lnbmluZyBrZXkncyBvd24gMzAtZGF5IFRUTCAoc2VlXG4gICAqIGAuL3NpZ25pbmcta2V5LnRzYCk6IHRoZSBjb29raWUgYW5kIHRoZSBrZXkgdGhhdCB2YWxpZGF0ZXMgaXQgc2hvdWxkIGV4cGlyZVxuICAgKiB0b2dldGhlciwgb3Igb25lIHNpbGVudGx5IG91dGxpdmVzIHRoZSBvdGhlci5cbiAgICovXG4gIHNlc3Npb25UdGxTZWNvbmRzPzogbnVtYmVyO1xuICAvKiogT25lLXRpbWUtY29kZSBsaWZldGltZSAoc2Vjb25kcykuIEVudiBUVU5ORUxfQVVUSF9DT0RFX1RUTC4gRGVmYXVsdCA2MDAgKDEwbSkuICovXG4gIGNvZGVUdGxTZWNvbmRzPzogbnVtYmVyO1xuICAvKiogTWF4IHZlcmlmeSBhdHRlbXB0cyBwZXIgaXNzdWVkIGNvZGUuIERlZmF1bHQgNS4gKi9cbiAgbWF4QXR0ZW1wdHM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBGb3JjZS1jbGVhciBjdXRvZmY6IGV2ZXJ5IHNlc3Npb24gaXNzdWVkIEJFRk9SRSBpdCBzdG9wcyB2ZXJpZnlpbmcsIHNvIG1vdmluZ1xuICAgKiBpdCBmb3J3YXJkIHNpZ25zIGV2ZXJ5b25lIG91dC4gRW52IFRVTk5FTF9BVVRIX1NFU1NJT05fQ1VUT0ZGLlxuICAgKlxuICAgKiBBbnl0aGluZyBgb2JqZWN0LnRvRGF0ZWAgYWNjZXB0czogYSBgRGF0ZWAsIGAyMDI2LTA4LTAyYCwgYW4gSVNPIGluc3RhbnQsXG4gICAqIGVwb2NoIHNlY29uZHMvbWlsbGlzLCBvciBhIHJlbGF0aXZlIGR1cmF0aW9uIChgLTMwZGAsIGA3IGRheXMgYWdvYCkuIFVuc2V0XG4gICAqIG1lYW5zIG5vIGN1dG9mZi5cbiAgICovXG4gIHNlc3Npb25DdXRvZmY/OiBzdHJpbmcgfCBudW1iZXIgfCBEYXRlO1xuICAvKiogRGVsaXZlciBhIGNvZGUgdG8gYW4gYWRkcmVzcy4gV2lyZWQgYnkgdGhlIGFwcCB0byB0aGUgZW1haWwgcGx1Z2luLiAqL1xuICBzZW5kQ29kZT86IChlbWFpbDogc3RyaW5nLCBjb2RlOiBzdHJpbmcsIG9wdHM6IFNlbmRDb2RlT3B0aW9ucykgPT4gUHJvbWlzZTx2b2lkPjtcbn1cblxuLyoqIEJyYW5kaW5nL21lc3NhZ2luZyBwYXNzZWQgdG8ge0BsaW5rIEF1dGhHYXRlQ29uZmlnLnNlbmRDb2RlfS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2VuZENvZGVPcHRpb25zIHtcbiAgc3ViamVjdDogc3RyaW5nO1xuICBicmFuZE5hbWU6IHN0cmluZztcbiAgbWVzc2FnZTogc3RyaW5nO1xuICAvKipcbiAgICogTGlmZXRpbWUgb2YgdGhlIGNvZGUgYmVpbmcgc2VudCwgaW4gc2Vjb25kcyAtIHRoZSBSRVNPTFZFRFxuICAgKiB7QGxpbmsgQXV0aEdhdGVDb25maWcuY29kZVR0bFNlY29uZHN9LCBzbyB0aGUgZW1haWwgY2FuIHN0YXRlIHRoZSByZWFsXG4gICAqIGV4cGlyeSAoXCJUaGlzIGNvZGUgZXhwaXJlcyBpbiAxMCBtaW51dGVzXCIpIGluc3RlYWQgb2YgYSB2YWd1ZSBcInNob3J0bHlcIlxuICAgKiB0aGF0IGRyaWZ0cyBmcm9tIHRoZSBjb25maWd1cmVkIFRUTC5cbiAgICovXG4gIGNvZGVUdGxTZWNvbmRzOiBudW1iZXI7XG59XG5cbi8qKiBSZXNvbHZlZCBnYXRlIGNvbmZpZyB3aXRoIGVudiBmYWxsYmFja3MgKyBkZWZhdWx0cyBhcHBsaWVkLiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXNvbHZlZEF1dGhHYXRlQ29uZmlnIHtcbiAgYWxsb3c6IHN0cmluZ1tdO1xuICBzdWJqZWN0OiBzdHJpbmc7XG4gIGJyYW5kTmFtZTogc3RyaW5nO1xuICBtZXNzYWdlOiBzdHJpbmc7XG4gIHNlc3Npb25UdGxTZWNvbmRzOiBudW1iZXI7XG4gIGNvZGVUdGxTZWNvbmRzOiBudW1iZXI7XG4gIG1heEF0dGVtcHRzOiBudW1iZXI7XG4gIC8qKiBGb3JjZS1jbGVhciBjdXRvZmYgaW4gZXBvY2ggbXM7IGAwYCB3aGVuIHVuc2V0LiAqL1xuICBzZXNzaW9uQ3V0b2ZmTXM6IG51bWJlcjtcbn1cblxuY29uc3QgREVGQVVMVFMgPSB7XG4gIHN1YmplY3Q6IFwiWW91ciB2ZXJpZmljYXRpb24gY29kZVwiLFxuICAvLyBUaGUgcmVwby13aWRlIGJyYW5kIGNvbnRleHQncyBkaXNwbGF5IG5hbWUsIE5PVCBhIGhhcmRjb2RlZCBwcm9kdWN0IHN0cmluZzpcbiAgLy8gdGhpcyBuYW1lIGlzIHdoYXQgdGhlIHJlY2lwaWVudCByZWFkcyBpbiB0aGUgY29kZSBlbWFpbCwgc28gaXQgaGFzIHRvIGJlIHRoZVxuICAvLyBzYW1lIGlkZW50aXR5IHRoZSByZXN0IG9mIHRoZSBhcHAgcHJlc2VudHMuIEEgaG9zdCB3aXRoIGl0cyBvd25cbiAgLy8gYGJyYW5kaW5nL2JyYW5kLnlhbWxgIG92ZXJyaWRlcyBpdCBieSBwYXNzaW5nIGBicmFuZE5hbWVgIChzZWVcbiAgLy8ge0BsaW5rIHN0YXJ0R2F0ZUFwcH0sIHdoaWNoIHJlc29sdmVzIHRoZSBvbi1kaXNrIGNvbnRleHQpOyB0aGUgc2hhcmVkIGRlZmF1bHRcbiAgLy8gaXMgdGhlIGZhbGxiYWNrIHdoZW4gbm90aGluZyBpcyBjb25maWd1cmVkLlxuICBicmFuZE5hbWU6IGJyYW5kLmRlZmF1bHRCcmFuZENvbnRleHQubmFtZSxcbiAgbWVzc2FnZTogXCJZb3VyIHZlcmlmaWNhdGlvbiBjb2RlIGlzOlwiLFxuICAvLyAzMCBkYXlzLCB0aGUgc2FtZSB3aW5kb3cgdGhlIGNhY2hlLWJhY2tlZCBzaWduaW5nIGtleSBpcyBzdG9yZWQgZm9yLlxuICBzZXNzaW9uVHRsU2Vjb25kczogS0VZX1RUTF9TRUNPTkRTLFxuICBjb2RlVHRsU2Vjb25kczogNjAwLFxuICBtYXhBdHRlbXB0czogNSxcbn07XG5cbi8qKiBNZXJnZSB7QGxpbmsgQXV0aEdhdGVDb25maWd9IG92ZXIgZW52IG92ZXIgZGVmYXVsdHMgaW50byBhIHJlc29sdmVkIGNvbmZpZy4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlQXV0aEdhdGVDb25maWcoY29uZmlnOiBBdXRoR2F0ZUNvbmZpZyk6IFJlc29sdmVkQXV0aEdhdGVDb25maWcge1xuICByZXR1cm4ge1xuICAgIC8vIEJvdGggc291cmNlcyBhcmUgdW5pb25lZCByYXRoZXIgdGhhbiBvbmUgb3ZlcnJpZGluZzogYSBkZXBsb3ltZW50LXdpZGVcbiAgICAvLyBUVU5ORUxfQVVUSF9BTExPVyBhbmQgYSBwZXItaW52b2NhdGlvbiBgLS1hbGxvd2Agc2hvdWxkIGJvdGggZ3JhbnQgYWNjZXNzLlxuICAgIC8vIEhlbmNlIGBwYXJzZUxpc3RgIG9uIGVhY2ggcmF0aGVyIHRoYW4gYGVudi5saXN0YCwgd2hpY2ggc3RvcHMgYXQgdGhlIGZpcnN0XG4gICAgLy8gc291cmNlIHRoYXQgeWllbGRzIGFueXRoaW5nLlxuICAgIGFsbG93OiBbLi4uc3RyaW5nLnBhcnNlTGlzdChjb25maWcuYWxsb3cpLCAuLi5zdHJpbmcucGFyc2VMaXN0KGVudi50ZXh0KEFMTE9XX0VOVikpXSxcbiAgICBzdWJqZWN0OiBlbnYuc3RyaW5nKGNvbmZpZy5zdWJqZWN0LCBTVUJKRUNUX0VOVikgPz8gREVGQVVMVFMuc3ViamVjdCxcbiAgICBicmFuZE5hbWU6IGVudi5zdHJpbmcoY29uZmlnLmJyYW5kTmFtZSwgQlJBTkRfTkFNRV9FTlYpID8/IERFRkFVTFRTLmJyYW5kTmFtZSxcbiAgICBtZXNzYWdlOiBlbnYuc3RyaW5nKGNvbmZpZy5tZXNzYWdlLCBNRVNTQUdFX0VOVikgPz8gREVGQVVMVFMubWVzc2FnZSxcbiAgICBzZXNzaW9uVHRsU2Vjb25kczogZW52LnBvc2l0aXZlSW50KFxuICAgICAgY29uZmlnLnNlc3Npb25UdGxTZWNvbmRzLFxuICAgICAgU0VTU0lPTl9UVExfRU5WLFxuICAgICAgREVGQVVMVFMuc2Vzc2lvblR0bFNlY29uZHMsXG4gICAgKSxcbiAgICBjb2RlVHRsU2Vjb25kczogZW52LnBvc2l0aXZlSW50KGNvbmZpZy5jb2RlVHRsU2Vjb25kcywgQ09ERV9UVExfRU5WLCBERUZBVUxUUy5jb2RlVHRsU2Vjb25kcyksXG4gICAgbWF4QXR0ZW1wdHM6IGNvbmZpZy5tYXhBdHRlbXB0cyA/PyBERUZBVUxUUy5tYXhBdHRlbXB0cyxcbiAgICBzZXNzaW9uQ3V0b2ZmTXM6IHJlc29sdmVTZXNzaW9uQ3V0b2ZmKGNvbmZpZy5zZXNzaW9uQ3V0b2ZmKSxcbiAgfTtcbn1cblxuLyoqIFRoZSBoYW5kbGVycyB0aGUgcHJveHkgY2FsbHMgaW4tcHJvY2VzcyAocmV0dXJuZWQgYnkge0BsaW5rIEF1dGhHYXRlUGx1Z2luLmV4cG9ydHN9KS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXV0aEdhdGVBcGkge1xuICAvKiogSGFuZGxlIGEgY29kZSByZXF1ZXN0LiBBbHdheXMgcmVzb2x2ZXMgYHsgb2s6IHRydWUgfWAgKGFudGktZW51bWVyYXRpb24pLiAqL1xuICByZXF1ZXN0KGVtYWlsOiBzdHJpbmcsIGlwOiBzdHJpbmcpOiBQcm9taXNlPHsgb2s6IHRydWU7IHJldHJ5QWZ0ZXI/OiBudW1iZXIgfT47XG4gIC8qKiBIYW5kbGUgYSBjb2RlIHZlcmlmaWNhdGlvbi4gT24gc3VjY2VzcyByZXR1cm5zIHRoZSBzZXNzaW9uIHRva2VuIHRvIGNvb2tpZS4gKi9cbiAgdmVyaWZ5KFxuICAgIGVtYWlsOiBzdHJpbmcsXG4gICAgY29kZTogc3RyaW5nLFxuICAgIGlwOiBzdHJpbmcsXG4gICk6IFByb21pc2U8eyBvazogYm9vbGVhbjsgdG9rZW4/OiBzdHJpbmc7IHJldHJ5QWZ0ZXI/OiBudW1iZXIgfT47XG4gIC8qKiBSZXNvbHZlIHRoZSBhdXRoZW50aWNhdGVkIGVtYWlsIGZvciBhIHNlc3Npb24gdG9rZW4sIG9yIHVuZGVmaW5lZC4gKi9cbiAgc2Vzc2lvbih0b2tlbjogc3RyaW5nIHwgdW5kZWZpbmVkKTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+O1xuICAvKiogU2Vzc2lvbiBUVEwgaW4gc2Vjb25kcyAoZm9yIHRoZSBjb29raWUgTWF4LUFnZSkuICovXG4gIHJlYWRvbmx5IHNlc3Npb25UdGxTZWNvbmRzOiBudW1iZXI7XG4gIC8qKiBUaGUgZ2F0ZSBzdGF0dXMgcGF5bG9hZCAoYGVuYWJsZWRgIGlzIGFsd2F5cyB0cnVlIHdoZW4gdGhpcyBwbHVnaW4gcnVucykuICovXG4gIHN0YXR1cyh0b2tlbjogc3RyaW5nIHwgdW5kZWZpbmVkKTogUHJvbWlzZTxBdXRoU3RhdHVzPjtcbn1cblxuLyoqIEFwcEtpdCBwbHVnaW4gb3duaW5nIHRoZSBlbWFpbC1PVFAgZ2F0ZSdzIGxvZ2ljIChubyBIVFRQIHJvdXRlczsgcHJveHktZHJpdmVuKS4gKi9cbmV4cG9ydCBjbGFzcyBBdXRoR2F0ZVBsdWdpbiBleHRlbmRzIFBsdWdpbjxBdXRoR2F0ZUNvbmZpZz4ge1xuICBzdGF0aWMgbWFuaWZlc3QgPSB7XG4gICAgbmFtZTogXCJhdXRoR2F0ZVwiLFxuICAgIGRpc3BsYXlOYW1lOiBcIkF1dGggR2F0ZVwiLFxuICAgIGRlc2NyaXB0aW9uOiBcIkVtYWlsIG9uZS10aW1lLXBhc3N3b3JkIGFjY2VzcyBnYXRlIGZvciBhIHB1YmxpYyB0dW5uZWwuXCIsXG4gICAgc3RhYmlsaXR5OiBcImJldGFcIixcbiAgICByZXNvdXJjZXM6IHsgcmVxdWlyZWQ6IFtdLCBvcHRpb25hbDogW10gfSxcbiAgfSBzYXRpc2ZpZXMgUGx1Z2luTWFuaWZlc3Q8XCJhdXRoR2F0ZVwiPjtcblxuICBwcml2YXRlIHJlc29sdmVkITogUmVzb2x2ZWRBdXRoR2F0ZUNvbmZpZztcbiAgcHJpdmF0ZSBjb2RlcyE6IENvZGVTdG9yZTtcbiAgLy8gUmVxdWVzdGluZyBhIGNvZGUgaXMgZW1haWwtc3BhbS1wcm9uZTsgdmVyaWZ5aW5nIGlzIGEgYnJ1dGUtZm9yY2Ugc3VyZmFjZS5cbiAgLy8gUGVyLWVtYWlsIEFORCBwZXItSVAgc28gbmVpdGhlciBheGlzIGFsb25lIGlzIGEgYnlwYXNzLlxuICBwcml2YXRlIHJlYWRvbmx5IHJlcXVlc3RMaW1pdGVyID0gbmV3IFJhdGVMaW1pdGVyKDUsIDE1ICogNjAgKiAxMDAwKTtcbiAgcHJpdmF0ZSByZWFkb25seSB2ZXJpZnlMaW1pdGVyID0gbmV3IFJhdGVMaW1pdGVyKDEwLCAxNSAqIDYwICogMTAwMCk7XG5cbiAgb3ZlcnJpZGUgYXN5bmMgc2V0dXAoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5yZXNvbHZlZCA9IHJlc29sdmVBdXRoR2F0ZUNvbmZpZyh0aGlzLmNvbmZpZyk7XG4gICAgdGhpcy5jb2RlcyA9IG5ldyBDb2RlU3RvcmUodGhpcy5yZXNvbHZlZC5jb2RlVHRsU2Vjb25kcywgdGhpcy5yZXNvbHZlZC5tYXhBdHRlbXB0cyk7XG4gICAgLy8gUmVzb2x2ZSB0aGUgc2lnbmluZyBrZXkgSEVSRSByYXRoZXIgdGhhbiBsYXppbHkgb24gdGhlIGZpcnN0IHNpZ24taW4sIHNvIGFcbiAgICAvLyBjYWNoZSB0aGF0IGNhbm5vdCBob2xkIGl0IChhbmQgdGhlIHJlc3VsdGluZyBcInNlc3Npb25zIHdvbid0IHN1cnZpdmUgYVxuICAgIC8vIHJlc3RhcnRcIiB3YXJuaW5nKSBzaG93cyB1cCBpbiB0aGUgc3RhcnR1cCBsb2csIG5vdCBob3VycyBsYXRlci5cbiAgICBjb25zdCB7IGN1dG9mZk1zIH0gPSBhd2FpdCBzaWduaW5nS2V5KHRoaXMucmVzb2x2ZWQuc2Vzc2lvbkN1dG9mZk1zKTtcbiAgICBsb2dnZXIuaW5mbyhcInJlYWR5XCIsIHtcbiAgICAgIHBhdHRlcm5zOiB0aGlzLnJlc29sdmVkLmFsbG93Lmxlbmd0aCxcbiAgICAgIHNlc3Npb25UdGxTZWNvbmRzOiB0aGlzLnJlc29sdmVkLnNlc3Npb25UdGxTZWNvbmRzLFxuICAgICAgLi4ub2JqZWN0Lm9wdGlvbmFsKFwic2Vzc2lvbkN1dG9mZlwiLCBjdXRvZmZNcyA+IDAgPyBuZXcgRGF0ZShjdXRvZmZNcykudG9JU09TdHJpbmcoKSA6IG51bGwpLFxuICAgIH0pO1xuICB9XG5cbiAgb3ZlcnJpZGUgZXhwb3J0cygpOiBBdXRoR2F0ZUFwaSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNlc3Npb25UdGxTZWNvbmRzOiB0aGlzLnJlc29sdmVkLnNlc3Npb25UdGxTZWNvbmRzLFxuICAgICAgcmVxdWVzdDogKGVtYWlsLCBpcCkgPT4gdGhpcy5oYW5kbGVSZXF1ZXN0KGVtYWlsLCBpcCksXG4gICAgICB2ZXJpZnk6IChlbWFpbCwgY29kZSwgaXApID0+IHRoaXMuaGFuZGxlVmVyaWZ5KGVtYWlsLCBjb2RlLCBpcCksXG4gICAgICBzZXNzaW9uOiAodG9rZW4pID0+IHZlcmlmeVNlc3Npb24odG9rZW4pLFxuICAgICAgc3RhdHVzOiBhc3luYyAodG9rZW4pID0+ICh7XG4gICAgICAgIGF1dGhlbnRpY2F0ZWQ6IEJvb2xlYW4oYXdhaXQgdmVyaWZ5U2Vzc2lvbih0b2tlbikpLFxuICAgICAgICBlbWFpbDogKGF3YWl0IHZlcmlmeVNlc3Npb24odG9rZW4pKSA/PyB1bmRlZmluZWQsXG4gICAgICAgIGVuYWJsZWQ6IHRydWUsXG4gICAgICB9KSxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBoYW5kbGVSZXF1ZXN0KFxuICAgIGVtYWlsOiBzdHJpbmcsXG4gICAgaXA6IHN0cmluZyxcbiAgKTogUHJvbWlzZTx7IG9rOiB0cnVlOyByZXRyeUFmdGVyPzogbnVtYmVyIH0+IHtcbiAgICBjb25zdCBhZGRyZXNzID0gZW1haWwudHJpbSgpLnRvTG93ZXJDYXNlKCk7XG4gICAgY29uc3QgYnlJcCA9IHRoaXMucmVxdWVzdExpbWl0ZXIuaGl0KGBpcDoke2lwfWApO1xuICAgIGNvbnN0IGJ5RW1haWwgPSB0aGlzLnJlcXVlc3RMaW1pdGVyLmhpdChgZW1haWw6JHthZGRyZXNzfWApO1xuICAgIGlmICghYnlJcC5hbGxvd2VkIHx8ICFieUVtYWlsLmFsbG93ZWQpIHtcbiAgICAgIHJldHVybiB7IG9rOiB0cnVlLCByZXRyeUFmdGVyOiBieUlwLnJldHJ5QWZ0ZXIgPz8gYnlFbWFpbC5yZXRyeUFmdGVyIH07XG4gICAgfVxuICAgIGlmIChsb29rc0xpa2VFbWFpbChhZGRyZXNzKSAmJiBtYXRjaGVzQWxsb3dsaXN0KGFkZHJlc3MsIHRoaXMucmVzb2x2ZWQuYWxsb3cpKSB7XG4gICAgICBjb25zdCBjb2RlID0gYXdhaXQgdGhpcy5jb2Rlcy5pc3N1ZShhZGRyZXNzKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMuY29uZmlnLnNlbmRDb2RlPy4oYWRkcmVzcywgY29kZSwge1xuICAgICAgICAgIHN1YmplY3Q6IHRoaXMucmVzb2x2ZWQuc3ViamVjdCxcbiAgICAgICAgICBicmFuZE5hbWU6IHRoaXMucmVzb2x2ZWQuYnJhbmROYW1lLFxuICAgICAgICAgIG1lc3NhZ2U6IHRoaXMucmVzb2x2ZWQubWVzc2FnZSxcbiAgICAgICAgICBjb2RlVHRsU2Vjb25kczogdGhpcy5yZXNvbHZlZC5jb2RlVHRsU2Vjb25kcyxcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBsb2dnZXIud2FybihcImZhaWxlZCB0byBzZW5kIE9UUCBlbWFpbFwiLCB7IGVycm9yIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4geyBvazogdHJ1ZSB9O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBoYW5kbGVWZXJpZnkoXG4gICAgZW1haWw6IHN0cmluZyxcbiAgICBjb2RlOiBzdHJpbmcsXG4gICAgaXA6IHN0cmluZyxcbiAgKTogUHJvbWlzZTx7IG9rOiBib29sZWFuOyB0b2tlbj86IHN0cmluZzsgcmV0cnlBZnRlcj86IG51bWJlciB9PiB7XG4gICAgY29uc3QgYWRkcmVzcyA9IGVtYWlsLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuICAgIGNvbnN0IGJ5SXAgPSB0aGlzLnZlcmlmeUxpbWl0ZXIuaGl0KGBpcDoke2lwfWApO1xuICAgIGNvbnN0IGJ5RW1haWwgPSB0aGlzLnZlcmlmeUxpbWl0ZXIuaGl0KGBlbWFpbDoke2FkZHJlc3N9YCk7XG4gICAgaWYgKCFieUlwLmFsbG93ZWQgfHwgIWJ5RW1haWwuYWxsb3dlZCkge1xuICAgICAgcmV0dXJuIHsgb2s6IGZhbHNlLCByZXRyeUFmdGVyOiBieUlwLnJldHJ5QWZ0ZXIgPz8gYnlFbWFpbC5yZXRyeUFmdGVyIH07XG4gICAgfVxuICAgIGlmICgoYXdhaXQgdGhpcy5jb2Rlcy52ZXJpZnkoYWRkcmVzcywgY29kZS50cmltKCkpKSAhPT0gXCJva1wiKSByZXR1cm4geyBvazogZmFsc2UgfTtcbiAgICB0aGlzLnJlcXVlc3RMaW1pdGVyLnJlc2V0KGBlbWFpbDoke2FkZHJlc3N9YCk7XG4gICAgdGhpcy52ZXJpZnlMaW1pdGVyLnJlc2V0KGBlbWFpbDoke2FkZHJlc3N9YCk7XG4gICAgcmV0dXJuIHsgb2s6IHRydWUsIHRva2VuOiBhd2FpdCBzaWduU2Vzc2lvbihhZGRyZXNzLCB0aGlzLnJlc29sdmVkLnNlc3Npb25UdGxTZWNvbmRzKSB9O1xuICB9XG59XG5cbi8qKiBGYWN0b3J5OiBgYXV0aEdhdGUoeyBhbGxvdywgc3ViamVjdCwgLi4uIH0pYCBmb3IgYW4gQXBwS2l0IGBwbHVnaW5zYCBhcnJheS4gKi9cbmV4cG9ydCBjb25zdCBhdXRoR2F0ZSA9IHRvUGx1Z2luKEF1dGhHYXRlUGx1Z2luKTtcbiJdfQ==
package/package.json CHANGED
@@ -29,11 +29,11 @@
29
29
  "dependencies": {
30
30
  "@clack/prompts": "^1.7.0",
31
31
  "@databricks/appkit": "^0.43.0",
32
- "@dbx-tools/appkit": "0.6.57",
33
- "@dbx-tools/core": "0.6.57",
34
- "@dbx-tools/email": "0.6.57",
35
- "@dbx-tools/shared-core": "0.6.57",
36
- "@dbx-tools/shared-email": "0.6.57",
32
+ "@dbx-tools/appkit": "0.6.58",
33
+ "@dbx-tools/core": "0.6.58",
34
+ "@dbx-tools/email": "0.6.58",
35
+ "@dbx-tools/shared-core": "0.6.58",
36
+ "@dbx-tools/shared-email": "0.6.58",
37
37
  "commander": "^15.0.0",
38
38
  "http-proxy-3": "^1.23.3",
39
39
  "jose": "^6.2.3"
@@ -100,7 +100,7 @@
100
100
  "./package.json": "./package.json"
101
101
  }
102
102
  },
103
- "version": "0.6.57",
103
+ "version": "0.6.58",
104
104
  "types": "./lib/index.d.ts",
105
105
  "type": "module",
106
106
  "exports": {
package/src/app.ts CHANGED
@@ -3,8 +3,9 @@
3
3
  *
4
4
  * There is no HTTP server here: the tunnel proxy is the server, and it calls the
5
5
  * gate handlers in-process. `createApp` is used only for what it auto-wires:
6
- * - `CacheManager` (memory, or Lakebase when the deploy configures persistent
7
- * cache storage) - which the OTP `CodeStore` uses for storage + TTL eviction;
6
+ * - `CacheManager` (Lakebase when this process can reach it, else memory) -
7
+ * which the OTP `CodeStore` and the session signing key use for storage + TTL
8
+ * eviction;
8
9
  * - the `email()` transport (SMTP / outbox), primed from env, so `sendCode` can
9
10
  * deliver the one-time code;
10
11
  * - dbx-tools auto-configuration + branding via `@dbx-tools/appkit`.
@@ -24,10 +25,11 @@
24
25
  * @module
25
26
  */
26
27
 
27
- import { createApp as createAppNs } from "@dbx-tools/appkit";
28
+ import { getUsernameWithApiLookup } from "@databricks/appkit";
29
+ import { createApp as createAppNs, lakebaseResolver } from "@dbx-tools/appkit";
28
30
  import { brand as nodeBrand } from "@dbx-tools/core";
29
31
  import { brand as emailBrand, email, sender, transport } from "@dbx-tools/email";
30
- import { log, string } from "@dbx-tools/shared-core";
32
+ import { env, log, string } from "@dbx-tools/shared-core";
31
33
  import { authGate, type AuthGateApi, type AuthGateConfig, type SendCodeOptions } from "./plugin.ts";
32
34
 
33
35
  const logger = log.logger("tunnel:app");
@@ -95,12 +97,132 @@ export function codeEmailTextBody(code: string, opts: CodeCopy): string {
95
97
  ].join("\n");
96
98
  }
97
99
 
100
+ /**
101
+ * The SUBJECT line, with the code in it: `"123456 is your verification code"`.
102
+ *
103
+ * The code has to be here, not only in the body, because of what mobile autofill
104
+ * actually reads. iOS offers a code from an incoming NOTIFICATION - natively for
105
+ * Messages and Mail, and since iOS 26 for any app's notification text, which is
106
+ * what finally made Gmail work - and a notification contains the sender, the
107
+ * subject, and a short snippet. Nothing else. A code that lives in the body is
108
+ * invisible to it, however cleanly the body is formatted, which is why a perfectly
109
+ * shaped `text/plain` part still produced no autofill prompt in Gmail.
110
+ *
111
+ * `<code> is your <thing>` rather than `<thing>: <code>` because the leading code
112
+ * survives TRUNCATION: a notification and an inbox list both cut the subject, and
113
+ * the platform heuristics want the code in the same sentence as a recognized
114
+ * prompt ("code", "verification"). Putting it first keeps both intact no matter
115
+ * where the cut lands.
116
+ *
117
+ * `subject` is the configured line ("Your verification code"), lower-cased at its
118
+ * first word so the sentence reads naturally, and left ALONE when it does not look
119
+ * like the conventional phrasing - an operator who set a deliberate subject gets
120
+ * theirs with the code prefixed, not a mangled hybrid.
121
+ */
122
+ export function codeEmailSubject(code: string, subject: string): string {
123
+ const trimmed = subject.trim();
124
+ const conventional = /^your\s+/i.exec(trimmed);
125
+ const rest = conventional ? trimmed.slice(conventional[0].length) : trimmed;
126
+ return conventional ? `${code} is your ${rest}` : `${code} - ${trimmed}`;
127
+ }
128
+
129
+ /**
130
+ * The PREHEADER: the snippet beside the subject in an inbox list, and the body of
131
+ * the push notification. Carries the code for the same reason the subject does -
132
+ * it is the other half of what a notification shows - and repeats the prompt
133
+ * wording so a heuristic scanning the snippet alone finds a code next to a phrase
134
+ * it recognizes.
135
+ */
136
+ export function codeEmailPreview(code: string, opts: CodeCopy): string {
137
+ return `${opts.message} ${code}`;
138
+ }
139
+
98
140
  const { createApp } = createAppNs;
141
+ const { applyLakebaseToEnv, resolveLakebaseConnection } = lakebaseResolver;
99
142
  const { resolveSystemSenderAddress } = sender;
100
143
  const { getEmailRuntime, sendEmail } = transport;
101
144
  const { emailBrandFromContext } = emailBrand;
102
145
  const { loadBrandContext } = nodeBrand;
103
146
 
147
+ /**
148
+ * Env vars whose presence means a Lakebase database was bound to this deployment.
149
+ * `LAKEBASE_ENDPOINT` is what a Databricks App `postgres` resource binding sets;
150
+ * `PGHOST` is the local/manual spelling.
151
+ */
152
+ const LAKEBASE_ENV = ["LAKEBASE_ENDPOINT", "PGHOST"] as const;
153
+
154
+ /**
155
+ * Upper bound on resolving the Lakebase connection. The gate is in the request
156
+ * path for every visitor, so a slow workspace API must not hold up boot
157
+ * indefinitely; a memory cache is a degraded gate, an unbooted one is no gate.
158
+ */
159
+ const LAKEBASE_RESOLVE_TIMEOUT_MS = 60_000;
160
+
161
+ /**
162
+ * Fill in the Lakebase connection env AppKit's cache needs, so `CacheManager`
163
+ * chooses PERSISTENT storage instead of memory.
164
+ *
165
+ * This is what makes the gate's session signing key and outstanding one-time
166
+ * codes survive a restart, and it has to be done explicitly here. AppKit picks
167
+ * Lakebase for the cache only when `createLakebasePool()` succeeds, and that pool
168
+ * reads FOUR things off `process.env`: `LAKEBASE_ENDPOINT`, `PGHOST`,
169
+ * `PGDATABASE`, and a username (`PGUSER`, or `DATABRICKS_CLIENT_ID` for a service
170
+ * principal). A Databricks App `postgres` resource binding supplies only
171
+ * `LAKEBASE_ENDPOINT`. The resolver turns that one value into the host and
172
+ * database; the username is looked up separately, because missing it fails pool
173
+ * construction just as hard as a missing host - and it is what a LOCAL run (a
174
+ * developer on a PAT, with no `DATABRICKS_CLIENT_ID`) is always missing. Without
175
+ * all four the pool cannot be built, the cache silently degrades to in-memory, and
176
+ * every redeploy signs out every user (the exact symptom this exists to prevent).
177
+ *
178
+ * `@dbx-tools/appkit`'s `createApp` would normally do this via `autoConfigure`,
179
+ * but it gates that on a `lakebase()` plugin being registered - and this app
180
+ * registers none, because it has no server to mount Lakebase routes on. Calling
181
+ * the resolver directly also lets the gate be stricter than `autoConfigure` is:
182
+ *
183
+ * - It runs ONLY when a Lakebase env var is present. A tunnel is a wrapper
184
+ * around someone else's app and must not invent infrastructure, so with
185
+ * nothing bound it skips rather than falling through the resolver's
186
+ * list-or-CREATE-a-project path.
187
+ * - `autoCreate: false` for the same reason, in case a project happens to exist.
188
+ * - Every failure is a WARNING, never a throw. The cache is an optimization for
189
+ * session durability; admission still requires a code delivered to an
190
+ * allow-listed address, so a gate with a memory cache is safe, just forgetful.
191
+ */
192
+ export async function resolveCacheStorageEnv(): Promise<boolean> {
193
+ if (!env.text(LAKEBASE_ENV)) {
194
+ logger.info(
195
+ `no ${env.name(LAKEBASE_ENV)} - the gate cache stays in memory; sessions and codes will not survive a restart`,
196
+ );
197
+ return false;
198
+ }
199
+ try {
200
+ const resolved = await resolveLakebaseConnection(
201
+ { autoCreate: false },
202
+ AbortSignal.timeout(LAKEBASE_RESOLVE_TIMEOUT_MS),
203
+ );
204
+ applyLakebaseToEnv(resolved);
205
+ // `??=` so an explicitly configured PGUSER stays authoritative. The lookup
206
+ // falls back to the workspace API and returns undefined rather than throwing,
207
+ // so a failure here just leaves the pool to find its own username.
208
+ const user = await getUsernameWithApiLookup({});
209
+ if (user) process.env.PGUSER ??= user;
210
+ logger.info("lakebase resolved for the gate cache", {
211
+ host: resolved.host,
212
+ database: resolved.database,
213
+ endpoint: resolved.endpoint,
214
+ user: process.env.PGUSER,
215
+ });
216
+ return true;
217
+ } catch (error) {
218
+ logger.warn(
219
+ "could not resolve lakebase - the gate cache stays in memory; sessions and codes will not survive a restart",
220
+ { error },
221
+ );
222
+ return false;
223
+ }
224
+ }
225
+
104
226
  /**
105
227
  * Boot the gate app and return the API the proxy calls. Throws when email is not
106
228
  * in SMTP mode (no way to deliver a code) so a misconfigured gate fails fast at
@@ -115,6 +237,11 @@ export async function startGateApp(config: AuthGateConfig): Promise<AuthGateApi>
115
237
  // sign-in email with it. An explicit `brandName` still wins (see below).
116
238
  const context = await loadBrandContext();
117
239
 
240
+ // Before `createApp`, because AppKit resolves the cache's storage during it and
241
+ // reads the connection out of `process.env` when it does. See the function's
242
+ // docs for why the gate resolves this itself.
243
+ await resolveCacheStorageEnv();
244
+
118
245
  // `sendCode` delivers the OTP through the email plugin's SHARED transport, which
119
246
  // the `email()` plugin primes during its `setup()` (awaited by `createApp`
120
247
  // below). Using the module-level `sendEmail` avoids a circular dependency on the
@@ -126,18 +253,25 @@ export async function startGateApp(config: AuthGateConfig): Promise<AuthGateApi>
126
253
  await sendEmail(
127
254
  {
128
255
  to: [to],
129
- subject: opts.subject,
256
+ // The code rides in the SUBJECT and the preheader, not just the body:
257
+ // those two strings are the whole of a push notification, and a
258
+ // notification is what mobile autofill reads. See `codeEmailSubject`.
259
+ subject: codeEmailSubject(code, opts.subject),
130
260
  body: codeEmailHtmlBody(code, opts),
131
261
  },
132
262
  from,
133
263
  undefined,
134
- { text: codeEmailTextBody(code, opts) },
264
+ { text: codeEmailTextBody(code, opts), preview: codeEmailPreview(code, opts) },
135
265
  );
136
266
  };
137
267
 
138
268
  // `createApp` namespaces each plugin's exports on the handle by manifest name;
139
269
  // `handle.authGate` is the in-process gate API the proxy drives.
270
+ //
271
+ // `autoConfigure: false` because {@link resolveCacheStorageEnv} above already
272
+ // did the one piece of it this app wants, on this app's terms.
140
273
  const handle = await createApp({
274
+ autoConfigure: false,
141
275
  plugins: [
142
276
  // Brand the code email from the resolved context, the same bridge every
143
277
  // other dbx-tools email surface uses (accent + font inlined, logo only when
package/src/plugin.ts CHANGED
@@ -46,6 +46,11 @@ export interface AuthGateConfig extends BasePluginConfig {
46
46
  * anything branded: iOS, Gmail, Outlook, and Android all detect a one-time
47
47
  * code from this shape and offer to autofill it, and a novel phrasing is what
48
48
  * breaks that detection.
49
+ *
50
+ * This is the subject TEMPLATE, not the literal line sent: the code is spliced
51
+ * into it (`"123456 is your verification code"`) because a push notification
52
+ * shows only the subject and preheader, and that notification is what mobile
53
+ * autofill reads. See `codeEmailSubject` in `./app.ts`.
49
54
  */
50
55
  subject?: string;
51
56
  /**