@dbx-tools/tunnel 0.6.89 → 0.6.91

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/lib/src/gate.js CHANGED
@@ -6,8 +6,8 @@
6
6
  * nothing to forward to. It either short-circuits (401, or answers the open login
7
7
  * routes) or calls `next()` to let the app's real handlers run. It is the
8
8
  * "stands in for AppKit auth" path:
9
- * a portr caller proves an email via OTP, and on success the gate injects the
10
- * identity headers AppKit reads, so a gated request runs like a front-door one.
9
+ * a portr caller authenticates with Better Auth OTP or a passkey, and on
10
+ * success the gate injects the identity headers AppKit reads.
11
11
  *
12
12
  * WHICH TRAFFIC IS GATED - the `Host` header, not the socket. portr's client
13
13
  * forwards with Go's `httputil.NewSingleHostReverseProxy` and a `Director` that
@@ -21,11 +21,9 @@
21
21
  *
22
22
  * @module
23
23
  */
24
- import { http, json, log, token } from "@dbx-tools/shared-core";
25
- import { authRequestSchema, authVerifySchema, SESSION_COOKIE_NAME } from "@dbx-tools/shared-email";
24
+ import { log, token } from "@dbx-tools/shared-core";
26
25
  import { toHeaderPolicy } from "./headers.js";
27
26
  const logger = log.logger("tunnel:gate");
28
- /** Route prefix the login flow lives under (open, answered in-process). */
29
27
  export const AUTH_PREFIX = "/api/email/auth";
30
28
  /**
31
29
  * True when the request's `Host` is the tunnel's public domain - i.e. it came in
@@ -38,21 +36,6 @@ export function isTunnelHost(req, publicDomain) {
38
36
  const host = (req.headers.host ?? "").toLowerCase().split(":")[0];
39
37
  return host === publicDomain.toLowerCase().split(":")[0];
40
38
  }
41
- /** The session cookie for a verified email, as a Set-Cookie string. */
42
- function sessionCookie(value, maxAgeSeconds) {
43
- return [
44
- `${SESSION_COOKIE_NAME}=${value}`,
45
- "Path=/",
46
- "HttpOnly",
47
- "SameSite=Lax",
48
- `Max-Age=${maxAgeSeconds}`,
49
- // Real enforcement in production: the session cookie must be Secure so it is
50
- // never sent over plaintext. Local dev (http) omits it so the cookie works.
51
- process.env.NODE_ENV === "production" ? "Secure" : "",
52
- ]
53
- .filter(Boolean)
54
- .join("; ");
55
- }
56
39
  /**
57
40
  * Client IP for rate-limiting: the RIGHTMOST `x-forwarded-for` entry (the value
58
41
  * the nearest trusted hop - portr - wrote), else the socket address. Reading the
@@ -79,19 +62,19 @@ function stripSessionCookie(req) {
79
62
  const kept = raw
80
63
  .split(";")
81
64
  .map((c) => c.trim())
82
- .filter((c) => c && !c.startsWith(`${SESSION_COOKIE_NAME}=`));
65
+ .filter((c) => c && !c.startsWith("dbx-tools-auth=") && !c.startsWith("dbx-tools-passkey="));
83
66
  if (kept.length)
84
67
  req.headers.cookie = kept.join("; ");
85
68
  else
86
69
  delete req.headers.cookie;
87
70
  }
88
71
  /**
89
- * Present an OTP-authenticated caller to the app the SAME way a platform front
72
+ * Present a passwordless-authenticated caller to the app the SAME way a platform front
90
73
  * door does: set the front-door identity headers to the verified address (AppKit
91
74
  * reads {@link token.USER_ID_HEADER} for the OBO user id), so the app needs no
92
75
  * gate-specific code path.
93
76
  *
94
- * What the gate CANNOT set is {@link token.ACCESS_TOKEN_HEADER}: an OTP session
77
+ * What the gate CANNOT set is {@link token.ACCESS_TOKEN_HEADER}: an auth session
95
78
  * proves an email, not possession of a Databricks credential. Its absence is what
96
79
  * `@dbx-tools/appkit`'s `identity: "auto"` detects, so a gated request runs as the
97
80
  * app service principal instead of throwing.
@@ -100,11 +83,6 @@ function injectIdentity(req, email) {
100
83
  req.headers[token.USER_ID_HEADER] = email;
101
84
  req.headers[token.USER_EMAIL_HEADER] = email;
102
85
  }
103
- function sendJson(res, status, body, setCookie) {
104
- if (setCookie)
105
- res.setHeader("set-cookie", setCookie);
106
- res.status(status).json(body);
107
- }
108
86
  /** Read the raw request body as text (AppKit parses JSON, but the gate routes
109
87
  * are mounted before that runs for tunnel traffic, so read defensively). */
110
88
  function readBody(req) {
@@ -119,6 +97,43 @@ function readBody(req) {
119
97
  req.on("error", () => resolve(data));
120
98
  });
121
99
  }
100
+ export function webHeaders(req) {
101
+ const headers = new Headers();
102
+ for (const [name, value] of Object.entries(req.headers)) {
103
+ if (Array.isArray(value)) {
104
+ for (const item of value)
105
+ headers.append(name, item);
106
+ }
107
+ else if (value !== undefined) {
108
+ headers.set(name, value);
109
+ }
110
+ }
111
+ headers.set("x-real-ip", clientIp(req));
112
+ return headers;
113
+ }
114
+ export async function webRequest(req) {
115
+ const host = req.headers.host ?? "localhost";
116
+ const hostname = host.split(":")[0]?.toLowerCase();
117
+ const protocol = hostname === "localhost" || hostname === "127.0.0.1" ? "http" : "https";
118
+ const method = (req.method ?? "GET").toUpperCase();
119
+ const body = method === "GET" || method === "HEAD" ? undefined : await readBody(req);
120
+ return new globalThis.Request(`${protocol}://${host}${req.originalUrl || req.url}`, {
121
+ method,
122
+ headers: webHeaders(req),
123
+ ...(body ? { body } : {}),
124
+ });
125
+ }
126
+ export async function sendWebResponse(res, response) {
127
+ for (const [name, value] of response.headers.entries()) {
128
+ if (name.toLowerCase() !== "set-cookie")
129
+ res.setHeader(name, value);
130
+ }
131
+ const cookies = response.headers.getSetCookie();
132
+ if (cookies.length)
133
+ res.setHeader("set-cookie", cookies);
134
+ const body = Buffer.from(await response.arrayBuffer());
135
+ res.status(response.status).send(body);
136
+ }
122
137
  /**
123
138
  * THE gating decision, for one request, independent of how it will be answered.
124
139
  *
@@ -154,9 +169,8 @@ export async function gateRequest(req, options) {
154
169
  stripSessionCookie(req);
155
170
  return "pass";
156
171
  }
157
- // Every other /api/* needs a valid OTP session.
158
- const cookie = http.parseCookies(req.headers.cookie ?? null)[SESSION_COOKIE_NAME];
159
- const email = await gate.session(cookie);
172
+ // Every other /api/* needs a valid Better Auth session.
173
+ const email = await gate.session(webHeaders(req));
160
174
  if (!email)
161
175
  return "deny";
162
176
  injectIdentity(req, email);
@@ -168,12 +182,6 @@ export const UNAUTHORIZED_BODY = {
168
182
  error: "authentication required",
169
183
  loginPath: AUTH_PREFIX,
170
184
  };
171
- /** The `Set-Cookie` value that issues a verified session. */
172
- export function sessionSetCookie(sessionToken, maxAgeSeconds) {
173
- return sessionCookie(sessionToken, maxAgeSeconds);
174
- }
175
- /** The `Set-Cookie` value that clears the session. */
176
- export const LOGOUT_SET_COOKIE = `${SESSION_COOKIE_NAME}=; Path=/; HttpOnly; Max-Age=0`;
177
185
  /**
178
186
  * Register the login routes and the gating middleware on the app's Express
179
187
  * instance. Called from {@link AuthGatePlugin} with the router AppKit hands
@@ -183,64 +191,34 @@ export const LOGOUT_SET_COOKIE = `${SESSION_COOKIE_NAME}=; Path=/; HttpOnly; Max
183
191
  * routes live at an ABSOLUTE path (`/api/email/auth/*`, the client's contract),
184
192
  * not under the plugin's `/api/authGate` base.
185
193
  */
186
- export function mountGate(opts, addRoute, addMiddleware) {
194
+ export function mountGate(opts, _addRoute, addMiddleware) {
187
195
  const { gate, publicDomain, forwardHeaders } = opts;
188
196
  const headerPolicy = toHeaderPolicy(forwardHeaders);
189
197
  logger.debug("gate mounted", { publicDomain, forward: headerPolicy.patterns });
190
- // --- Login routes (open on tunnel traffic; answered in-process) ---
191
- const statusHandler = (async (req, res) => {
192
- // A local or front-door caller is never gated, so the honest answer is that
193
- // the gate does not apply - not the session state of a cookie it would never
194
- // check. Without this, a browser on `localhost` renders the OTP login screen
195
- // for a request that would have passed through untouched.
196
- if (!isTunnelHost(req, publicDomain)) {
197
- sendJson(res, 200, { authenticated: false, enabled: false });
198
- return;
199
- }
200
- const cookie = http.parseCookies(req.headers.cookie ?? null)[SESSION_COOKIE_NAME];
201
- sendJson(res, 200, await gate.status(cookie));
202
- });
203
- const requestHandler = (async (req, res) => {
204
- if (!isTunnelHost(req, publicDomain)) {
205
- sendJson(res, 404, { error: "not found" });
206
- return;
207
- }
208
- const parsed = authRequestSchema.safeParse(json.parseRecord(await readBody(req)));
209
- if (!parsed.success)
210
- return sendJson(res, 200, { ok: true }); // anti-enumeration
211
- sendJson(res, 200, await gate.request(parsed.data.email, clientIp(req)));
212
- });
213
- const verifyHandler = (async (req, res) => {
214
- if (!isTunnelHost(req, publicDomain)) {
215
- sendJson(res, 404, { error: "not found" });
216
- return;
217
- }
218
- const parsed = authVerifySchema.safeParse(json.parseRecord(await readBody(req)));
219
- if (!parsed.success)
220
- return sendJson(res, 200, { ok: false });
221
- const result = await gate.verify(parsed.data.email, parsed.data.code, clientIp(req));
222
- const cookie = result.ok && result.token ? sessionCookie(result.token, gate.sessionTtlSeconds) : undefined;
223
- sendJson(res, 200, { ok: result.ok, ...(result.retryAfter ? { retryAfter: result.retryAfter } : {}) }, cookie);
224
- });
225
- const logoutHandler = ((req, res) => {
198
+ // Better Auth and the compatibility routes share one fetch-compatible
199
+ // handler in both hosting modes.
200
+ const authHandler = (async (req, res) => {
226
201
  if (!isTunnelHost(req, publicDomain)) {
227
- sendJson(res, 404, { error: "not found" });
202
+ const path = (req.url ?? "/").split("?")[0] ?? "/";
203
+ if (path.endsWith("/status")) {
204
+ res.status(200).json({ authenticated: false, enabled: false, passkeysEnabled: false });
205
+ }
206
+ else {
207
+ res.status(404).json({ error: "not found" });
208
+ }
228
209
  return;
229
210
  }
230
- sendJson(res, 200, { ok: true }, LOGOUT_SET_COOKIE);
211
+ await sendWebResponse(res, await gate.handler(await webRequest(req)));
231
212
  });
232
- addRoute("get", `${AUTH_PREFIX}/status`, statusHandler);
233
- addRoute("post", `${AUTH_PREFIX}/request`, requestHandler);
234
- addRoute("post", `${AUTH_PREFIX}/verify`, verifyHandler);
235
- addRoute("post", `${AUTH_PREFIX}/logout`, logoutHandler);
213
+ addMiddleware(AUTH_PREFIX, authHandler);
236
214
  // --- The gate middleware (runs before static + the app's /api handlers) ---
237
215
  const gateMiddleware = (async (req, res, next) => {
238
216
  const action = await gateRequest(req, { gate, publicDomain, headerPolicy });
239
217
  if (action === "deny")
240
- sendJson(res, 401, UNAUTHORIZED_BODY);
218
+ res.status(401).json(UNAUTHORIZED_BODY);
241
219
  else
242
220
  next();
243
221
  });
244
222
  addMiddleware("/", gateMiddleware);
245
223
  }
246
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2F0ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9nYXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBc0JHO0FBR0gsT0FBTyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxnQkFBZ0IsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRW5HLE9BQU8sRUFBRSxjQUFjLEVBQXFCLE1BQU0sY0FBYyxDQUFDO0FBR2pFLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUM7QUFFekMsMkVBQTJFO0FBQzNFLE1BQU0sQ0FBQyxNQUFNLFdBQVcsR0FBRyxpQkFBaUIsQ0FBQztBQW9CN0M7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxZQUFZLENBQUMsR0FBb0IsRUFBRSxZQUFnQztJQUNqRixJQUFJLENBQUMsWUFBWTtRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQ2hDLE1BQU0sSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2xFLE9BQU8sSUFBSSxLQUFLLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDM0QsQ0FBQztBQUVELHVFQUF1RTtBQUN2RSxTQUFTLGFBQWEsQ0FBQyxLQUFhLEVBQUUsYUFBcUI7SUFDekQsT0FBTztRQUNMLEdBQUcsbUJBQW1CLElBQUksS0FBSyxFQUFFO1FBQ2pDLFFBQVE7UUFDUixVQUFVO1FBQ1YsY0FBYztRQUNkLFdBQVcsYUFBYSxFQUFFO1FBQzFCLDZF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QUcsV0FBVyxTQUFTLEVBQUUsYUFBYSxDQUFDLENBQUM7SUFDekQsUUFBUSxDQUFDLE1BQU0sRUFBRSxHQUFHLFdBQVcsU0FBUyxFQUFFLGFBQWEsQ0FBQyxDQUFDO0lBRXpELDZFQUE2RTtJQUU3RSxNQUFNLGNBQWMsR0FBRyxDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxFQUFFO1FBQy9DLE1BQU0sTUFBTSxHQUFHLE1BQU0sV0FBVyxDQUFDLEdBQUcsRUFBRSxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQztRQUM1RSxJQUFJLE1BQU0sS0FBSyxNQUFNO1lBQUUsUUFBUSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsaUJBQWlCLENBQUMsQ0FBQzs7WUFDeEQsSUFBSSxFQUFFLENBQUM7SUFDZCxDQUFDLENBQW1CLENBQUM7SUFFckIsYUFBYSxDQUFDLEdBQUcsRUFBRSxjQUFjLENBQUMsQ0FBQztBQUNyQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUaGUgdHVubmVsJ3MgaW4tYXBwIEFVVEggR0FURSAtIEV4cHJlc3MgbWlkZGxld2FyZSArIGxvZ2luIHJvdXRlcyB0aGVcbiAqIHtAbGluayBBdXRoR2F0ZVBsdWdpbn0gcmVnaXN0ZXJzIG9uIHRoZSBhcHAncyBPV04gc2VydmVyIHZpYSBgdGhpcy5jb250ZXh0YC5cbiAqXG4gKiBUaGUgZ2F0ZSBpcyBNSURETEVXQVJFLCBub3QgYSByZXZlcnNlIHByb3h5IC0gdGhlIGFwcCBpcyB0aGUgcHJvY2Vzcywgc28gdGhlcmUgaXNcbiAqIG5vdGhpbmcgdG8gZm9yd2FyZCB0by4gSXQgZWl0aGVyIHNob3J0LWNpcmN1aXRzICg0MDEsIG9yIGFuc3dlcnMgdGhlIG9wZW4gbG9naW5cbiAqIHJvdXRlcykgb3IgY2FsbHMgYG5leHQoKWAgdG8gbGV0IHRoZSBhcHAncyByZWFsIGhhbmRsZXJzIHJ1bi4gSXQgaXMgdGhlXG4gKiBcInN0YW5kcyBpbiBmb3IgQXBwS2l0IGF1dGhcIiBwYXRoOlxuICogYSBwb3J0ciBjYWxsZXIgcHJvdmVzIGFuIGVtYWlsIHZpYSBPVFAsIGFuZCBvbiBzdWNjZXNzIHRoZSBnYXRlIGluamVjdHMgdGhlXG4gKiBpZGVudGl0eSBoZWFkZXJzIEFwcEtpdCByZWFkcywgc28gYSBnYXRlZCByZXF1ZXN0IHJ1bnMgbGlrZSBhIGZyb250LWRvb3Igb25lLlxuICpcbiAqIFdISUNIIFRSQUZGSUMgSVMgR0FURUQgLSB0aGUgYEhvc3RgIGhlYWRlciwgbm90IHRoZSBzb2NrZXQuIHBvcnRyJ3MgY2xpZW50XG4gKiBmb3J3YXJkcyB3aXRoIEdvJ3MgYGh0dHB1dGlsLk5ld1NpbmdsZUhvc3RSZXZlcnNlUHJveHlgIGFuZCBhIGBEaXJlY3RvcmAgdGhhdFxuICogUFJFU0VSVkVTIHRoZSBvcmlnaW5hbCBgSG9zdGAsIHNvIHR1bm5lbCByZXF1ZXN0cyBhcnJpdmUgd2l0aFxuICogYEhvc3Q6IDxzdWJkb21haW4+LjxzZXJ2ZXI+YCAodGhlIHB1YmxpYyBkb21haW4pLiBBIGxvY2FsIHByb2Nlc3MgaGl0dGluZyB0aGVcbiAqIGFwcCBkaXJlY3RseSBzZW5kcyBgSG9zdDogMTI3LjAuMC4xOjxwb3J0PmAgLyBgbG9jYWxob3N0YC4gU28gT05MWSByZXF1ZXN0cyB3aG9zZVxuICogYEhvc3RgIG1hdGNoZXMgdGhlIGNvbmZpZ3VyZWQgcHVibGljIGRvbWFpbiBhcmUgZ2F0ZWQ7IHRoZSBwbGF0Zm9ybSBmcm9udCBkb29yXG4gKiBhbmQgYW55IG90aGVyIGxvY2FsIGNsaWVudCBwYXNzIHRocm91Z2ggdW50b3VjaGVkLiBUaGVyZSBpcyBubyBwb3J0ci1pbmplY3RlZFxuICogaWRlbnRpZnlpbmcgaGVhZGVyIGFuZCBubyBUQ1Avc291cmNlLUlQIHNpZ25hbCB0byB1c2UgaW5zdGVhZCAodGhlIGNsaWVudCBkaWFsc1xuICogdGhlIHRhcmdldCBvdmVyIHBsYWluIGxvb3BiYWNrKS5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBJbmNvbWluZ01lc3NhZ2UgfSBmcm9tIFwibm9kZTpodHRwXCI7XG5pbXBvcnQgeyBodHRwLCBqc29uLCBsb2csIHRva2VuIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB7IGF1dGhSZXF1ZXN0U2NoZW1hLCBhdXRoVmVyaWZ5U2NoZW1hLCBTRVNTSU9OX0NPT0tJRV9OQU1FIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWVtYWlsXCI7XG5pbXBvcnQgdHlwZSB7IFJlcXVlc3QsIFJlcXVlc3RIYW5kbGVyLCBSZXNwb25zZSB9IGZyb20gXCJleHByZXNzXCI7XG5pbXBvcnQgeyB0b0hlYWRlclBvbGljeSwgdHlwZSBIZWFkZXJQb2xpY3kgfSBmcm9tIFwiLi9oZWFkZXJzLnRzXCI7XG5pbXBvcnQgdHlwZSB7IEF1dGhHYXRlQXBpIH0gZnJvbSBcIi4vcGx1Z2luLnRzXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJ0dW5uZWw6Z2F0ZVwiKTtcblxuLyoqIFJvdXRlIHByZWZpeCB0aGUgbG9naW4gZmxvdyBsaXZlcyB1bmRlciAob3BlbiwgYW5zd2VyZWQgaW4tcHJvY2VzcykuICovXG5leHBvcnQgY29uc3QgQVVUSF9QUkVGSVggPSBcIi9hcGkvZW1haWwvYXV0aFwiO1xuXG4vKiogT3B0aW9ucyBmb3Ige0BsaW5rIG1vdW50R2F0ZX0uICovXG5leHBvcnQgaW50ZXJmYWNlIEdhdGVPcHRpb25zIHtcbiAgLyoqIFRoZSBpbi1wcm9jZXNzIGdhdGUgQVBJIChzZXNzaW9uL3JlcXVlc3QvdmVyaWZ5L3N0YXR1cykuICovXG4gIGdhdGU6IEF1dGhHYXRlQXBpO1xuICAvKipcbiAgICogVGhlIHB1YmxpYyBgPHN1YmRvbWFpbj4uPHNlcnZlcj5gIHRoYXQgaWRlbnRpZmllcyBwb3J0ciB0cmFmZmljIGJ5IGBIb3N0YC5cbiAgICogV2hlbiBhYnNlbnQsIG5vIHJlcXVlc3QgaXMgZXZlciBjbGFzc2lmaWVkIGFzIHR1bm5lbCB0cmFmZmljIGFuZCB0aGUgZ2F0ZSBpc1xuICAgKiBpbmVydCAoZXZlcnl0aGluZyBwYXNzZXMgdGhyb3VnaCkgLSBhIHR1bm5lbCB3aXRoIG5vIHB1YmxpYyBkb21haW4gZ2F0ZXNcbiAgICogbm90aGluZy5cbiAgICovXG4gIHB1YmxpY0RvbWFpbj86IHN0cmluZztcbiAgLyoqXG4gICAqIEV4dHJhIGB4LWAgcmVxdWVzdCBoZWFkZXJzIHR1bm5lbCB0cmFmZmljIG1heSBmb3J3YXJkICh1bmlvbmVkIHdpdGggdGhlXG4gICAqIGJ1aWx0LWluIGFsbG93LWxpc3QpLiBFdmVyeSBvdGhlciBgeC1gIGhlYWRlciBpcyBzdHJpcHBlZCBmcm9tIHR1bm5lbCB0cmFmZmljLlxuICAgKi9cbiAgZm9yd2FyZEhlYWRlcnM/OiByZWFkb25seSBzdHJpbmdbXTtcbn1cblxuLyoqXG4gKiBUcnVlIHdoZW4gdGhlIHJlcXVlc3QncyBgSG9zdGAgaXMgdGhlIHR1bm5lbCdzIHB1YmxpYyBkb21haW4gLSBpLmUuIGl0IGNhbWUgaW5cbiAqIG92ZXIgcG9ydHIuIENhc2UtaW5zZW5zaXRpdmU7IHRoZSBvcHRpb25hbCBgOnBvcnRgIGlzIGlnbm9yZWQuIFdoZW4gbm8gcHVibGljXG4gKiBkb21haW4gaXMgY29uZmlndXJlZCwgbm90aGluZyBpcyB0dW5uZWwgdHJhZmZpYy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVHVubmVsSG9zdChyZXE6IEluY29taW5nTWVzc2FnZSwgcHVibGljRG9tYWluOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBib29sZWFuIHtcbiAgaWYgKCFwdWJsaWNEb21haW4pIHJldHVybiBmYWxzZTtcbiAgY29uc3QgaG9zdCA9IChyZXEuaGVhZGVycy5ob3N0ID8/IFwiXCIpLnRvTG93ZXJDYXNlKCkuc3BsaXQoXCI6XCIpWzBdO1xuICByZXR1cm4gaG9zdCA9PT0gcHVibGljRG9tYWluLnRvTG93ZXJDYXNlKCkuc3BsaXQoXCI6XCIpWzBdO1xufVxuXG4vKiogVGhlIHNlc3Npb24gY29va2llIGZvciBhIHZlcmlmaWVkIGVtYWlsLCBhcyBhIFNldC1Db29raWUgc3RyaW5nLiAqL1xuZnVuY3Rpb24gc2Vzc2lvbkNvb2tpZSh2YWx1ZTogc3RyaW5nLCBtYXhBZ2VTZWNvbmRzOiBudW1iZXIpOiBzdHJpbmcge1xuICByZXR1cm4gW1xuICAgIGAke1NFU1NJT05fQ09PS0lFX05BTUV9PSR7dmFsdWV9YCxcbiAgICBcIlBhdGg9L1wiLFxuICAgIFwiSHR0cE9ubHlcIixcbiAgICBcIlNhbWVTaXRlPUxheFwiLFxuICAgIGBNYXgtQWdlPSR7bWF4QWdlU2Vjb25kc31gLFxuICAgIC8vIFJlYWwgZW5mb3JjZW1lbnQgaW4gcHJvZHVjdGlvbjogdGhlIHNlc3Npb24gY29va2llIG11c3QgYmUgU2VjdXJlIHNvIGl0IGlzXG4gICAgLy8gbmV2ZXIgc2VudCBvdmVyIHBsYWludGV4dC4gTG9jYWwgZGV2IChodHRwKSBvbWl0cyBpdCBzbyB0aGUgY29va2llIHdvcmtzLlxuICAgIHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSBcInByb2R1Y3Rpb25cIiA/IFwiU2VjdXJlXCIgOiBcIlwiLFxuICBdXG4gICAgLmZpbHRlcihCb29sZWFuKVxuICAgIC5qb2luKFwiOyBcIik7XG59XG5cbi8qKlxuICogQ2xpZW50IElQIGZvciByYXRlLWxpbWl0aW5nOiB0aGUgUklHSFRNT1NUIGB4LWZvcndhcmRlZC1mb3JgIGVudHJ5ICh0aGUgdmFsdWVcbiAqIHRoZSBuZWFyZXN0IHRydXN0ZWQgaG9wIC0gcG9ydHIgLSB3cm90ZSksIGVsc2UgdGhlIHNvY2tldCBhZGRyZXNzLiBSZWFkaW5nIHRoZVxuICogcmlnaHRtb3N0LCBub3QgdGhlIGxlZnRtb3N0LCBzdG9wcyBhIGNhbGxlciBtaW50aW5nIGEgZnJlc2ggcmF0ZS1saW1pdCBidWNrZXQgYnlcbiAqIHZhcnlpbmcgdGhlIGhlYWRlci4gQ2FsbGVkIGJlZm9yZSB7QGxpbmsgc3RyaXBIZWFkZXJzfS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsaWVudElwKHJlcTogSW5jb21pbmdNZXNzYWdlKTogc3RyaW5nIHtcbiAgY29uc3QgZm9yd2FyZGVkID0gcmVxLmhlYWRlcnNbXCJ4LWZvcndhcmRlZC1mb3JcIl07XG4gIGNvbnN0IGNoYWluID0gKEFycmF5LmlzQXJyYXkoZm9yd2FyZGVkKSA/IGZvcndhcmRlZC5qb2luKFwiLFwiKSA6IChmb3J3YXJkZWQgPz8gXCJcIikpXG4gICAgLnNwbGl0KFwiLFwiKVxuICAgIC5tYXAoKGVudHJ5KSA9PiBlbnRyeS50cmltKCkpXG4gICAgLmZpbHRlcihCb29sZWFuKTtcbiAgcmV0dXJuIGNoYWluLmF0KC0xKSA/PyByZXEuc29ja2V0LnJlbW90ZUFkZHJlc3MgPz8gXCJ1bmtub3duXCI7XG59XG5cbi8qKlxuICogUmVtb3ZlIHRoZSBnYXRlJ3Mgc2Vzc2lvbiBjb29raWUgZnJvbSB0aGUgYENvb2tpZWAgaGVhZGVyIGJlZm9yZSB0aGUgYXBwJ3NcbiAqIGhhbmRsZXJzIHJ1biwgc28gdGhlIGFwcCBuZXZlciBzZWVzIGBkYnhfYXV0aGAgKGl0IGlzIHRoZSBnYXRlJ3MgY29uY2VybikuXG4gKiBQcmVzZXJ2ZXMgb3RoZXIgY29va2llczsgZGVsZXRlcyB0aGUgaGVhZGVyIHdoZW4gaXQgYmVjb21lcyBlbXB0eS5cbiAqL1xuZnVuY3Rpb24gc3RyaXBTZXNzaW9uQ29va2llKHJlcTogSW5jb21pbmdNZXNzYWdlKTogdm9pZCB7XG4gIGNvbnN0IHJhdyA9IHJlcS5oZWFkZXJzLmNvb2tpZTtcbiAgaWYgKCFyYXcpIHJldHVybjtcbiAgY29uc3Qga2VwdCA9IHJhd1xuICAgIC5zcGxpdChcIjtcIilcbiAgICAubWFwKChjKSA9PiBjLnRyaW0oKSlcbiAgICAuZmlsdGVyKChjKSA9PiBjICYmICFjLnN0YXJ0c1dpdGgoYCR7U0VTU0lPTl9DT09LSUVfTkFNRX09YCkpO1xuICBpZiAoa2VwdC5sZW5ndGgpIHJlcS5oZWFkZXJzLmNvb2tpZSA9IGtlcHQuam9pbihcIjsgXCIpO1xuICBlbHNlIGRlbGV0ZSByZXEuaGVhZGVycy5jb29raWU7XG59XG5cbi8qKlxuICogUHJlc2VudCBhbiBPVFAtYXV0aGVudGljYXRlZCBjYWxsZXIgdG8gdGhlIGFwcCB0aGUgU0FNRSB3YXkgYSBwbGF0Zm9ybSBmcm9udFxuICogZG9vciBkb2VzOiBzZXQgdGhlIGZyb250LWRvb3IgaWRlbnRpdHkgaGVhZGVycyB0byB0aGUgdmVyaWZpZWQgYWRkcmVzcyAoQXBwS2l0XG4gKiByZWFkcyB7QGxpbmsgdG9rZW4uVVNFUl9JRF9IRUFERVJ9IGZvciB0aGUgT0JPIHVzZXIgaWQpLCBzbyB0aGUgYXBwIG5lZWRzIG5vXG4gKiBnYXRlLXNwZWNpZmljIGNvZGUgcGF0aC5cbiAqXG4gKiBXaGF0IHRoZSBnYXRlIENBTk5PVCBzZXQgaXMge0BsaW5rIHRva2VuLkFDQ0VTU19UT0tFTl9IRUFERVJ9OiBhbiBPVFAgc2Vzc2lvblxuICogcHJvdmVzIGFuIGVtYWlsLCBub3QgcG9zc2Vzc2lvbiBvZiBhIERhdGFicmlja3MgY3JlZGVudGlhbC4gSXRzIGFic2VuY2UgaXMgd2hhdFxuICogYEBkYngtdG9vbHMvYXBwa2l0YCdzIGBpZGVudGl0eTogXCJhdXRvXCJgIGRldGVjdHMsIHNvIGEgZ2F0ZWQgcmVxdWVzdCBydW5zIGFzIHRoZVxuICogYXBwIHNlcnZpY2UgcHJpbmNpcGFsIGluc3RlYWQgb2YgdGhyb3dpbmcuXG4gKi9cbmZ1bmN0aW9uIGluamVjdElkZW50aXR5KHJlcTogSW5jb21pbmdNZXNzYWdlLCBlbWFpbDogc3RyaW5nKTogdm9pZCB7XG4gIHJlcS5oZWFkZXJzW3Rva2VuLlVTRVJfSURfSEVBREVSXSA9IGVtYWlsO1xuICByZXEuaGVhZGVyc1t0b2tlbi5VU0VSX0VNQUlMX0hFQURFUl0gPSBlbWFpbDtcbn1cblxuZnVuY3Rpb24gc2VuZEpzb24ocmVzOiBSZXNwb25zZSwgc3RhdHVzOiBudW1iZXIsIGJvZHk6IHVua25vd24sIHNldENvb2tpZT86IHN0cmluZyk6IHZvaWQge1xuICBpZiAoc2V0Q29va2llKSByZXMuc2V0SGVhZGVyKFwic2V0LWNvb2tpZVwiLCBzZXRDb29raWUpO1xuICByZXMuc3RhdHVzKHN0YXR1cykuanNvbihib2R5KTtcbn1cblxuLyoqIFJlYWQgdGhlIHJhdyByZXF1ZXN0IGJvZHkgYXMgdGV4dCAoQXBwS2l0IHBhcnNlcyBKU09OLCBidXQgdGhlIGdhdGUgcm91dGVzXG4gKiBhcmUgbW91bnRlZCBiZWZvcmUgdGhhdCBydW5zIGZvciB0dW5uZWwgdHJhZmZpYywgc28gcmVhZCBkZWZlbnNpdmVseSkuICovXG5mdW5jdGlvbiByZWFkQm9keShyZXE6IFJlcXVlc3QpOiBQcm9taXNlPHN0cmluZz4ge1xuICAvLyBBcHBLaXQncyBqc29uIGJvZHktcGFyc2VyIG1heSBoYXZlIGFscmVhZHkgcG9wdWxhdGVkIHJlcS5ib2R5OyBwcmVmZXIgaXQuXG4gIGlmIChyZXEuYm9keSAhPT0gdW5kZWZpbmVkICYmIHJlcS5ib2R5ICE9PSBudWxsKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0eXBlb2YgcmVxLmJvZHkgPT09IFwic3RyaW5nXCIgPyByZXEuYm9keSA6IEpTT04uc3RyaW5naWZ5KHJlcS5ib2R5KSk7XG4gIH1cbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgbGV0IGRhdGEgPSBcIlwiO1xuICAgIHJlcS5vbihcImRhdGFcIiwgKGNodW5rKSA9PiAoZGF0YSArPSBjaHVuaykpO1xuICAgIHJlcS5vbihcImVuZFwiLCAoKSA9PiByZXNvbHZlKGRhdGEpKTtcbiAgICByZXEub24oXCJlcnJvclwiLCAoKSA9PiByZXNvbHZlKGRhdGEpKTtcbiAgfSk7XG59XG5cbi8qKlxuICogV2hhdCB0aGUgY2FsbGVyIHNob3VsZCBkbyB3aXRoIGEgcmVxdWVzdCwgZnJvbSB7QGxpbmsgZ2F0ZVJlcXVlc3R9LlxuICpcbiAqICAgLSBgcGFzc2AgLSBub3QgdHVubmVsIHRyYWZmaWMsIG9yIGFuIG9wZW4gbG9naW4gcm91dGUuIEZvcndhcmQgdW50b3VjaGVkLlxuICogICAtIGBhbGxvd2AgLSB0dW5uZWwgdHJhZmZpYyB0aGF0IGlzIGF1dGhvcml6ZWQuIFRoZSByZXF1ZXN0J3MgaGVhZGVycyBoYXZlXG4gKiAgICAgQUxSRUFEWSBiZWVuIHJld3JpdHRlbiAocG9saWN5IGFwcGxpZWQsIGlkZW50aXR5IGluamVjdGVkLCBzZXNzaW9uIGNvb2tpZVxuICogICAgIHN0cmlwcGVkKSwgc28gZm9yd2FyZCBpdCBhcyBpdCBub3cgc3RhbmRzLlxuICogICAtIGBkZW55YCAtIHR1bm5lbCB0cmFmZmljIHdpdGggbm8gdmFsaWQgc2Vzc2lvbi4gQW5zd2VyIGA0MDFgIHdpdGhcbiAqICAgICB7QGxpbmsgQVVUSF9QUkVGSVh9IGFzIHRoZSBsb2dpbiBwYXRoLlxuICovXG5leHBvcnQgdHlwZSBHYXRlQWN0aW9uID0gXCJwYXNzXCIgfCBcImFsbG93XCIgfCBcImRlbnlcIjtcblxuLyoqXG4gKiBUSEUgZ2F0aW5nIGRlY2lzaW9uLCBmb3Igb25lIHJlcXVlc3QsIGluZGVwZW5kZW50IG9mIGhvdyBpdCB3aWxsIGJlIGFuc3dlcmVkLlxuICpcbiAqIEJvdGggcGF0aHMgY2FsbCB0aGlzOiB0aGUgRXhwcmVzcyBtaWRkbGV3YXJlIGJlbG93ICh3aGVyZSB0aGUgYXBwIGlzIHRoZVxuICogcHJvY2VzcykgYW5kIGBAZGJ4LXRvb2xzL2NsaS10dW5uZWxgJ3MgcmV2ZXJzZSBwcm94eSAod2hlcmUgdGhlIGFwcCBpcyBhIGNoaWxkXG4gKiBwcm9jZXNzIG9uIGEgcHJpdmF0ZSBwb3J0KS4gQSBkaXZlcmdlbmNlIGJldHdlZW4gdGhlbSB3b3VsZCBiZSBhIHNlY3VyaXR5IGJ1Z1xuICogdGhlIHNlY29uZCBwYXRoIGNvdWxkIG5vdCBiZSB0ZXN0ZWQgaW50byBhZ3JlZW1lbnQgLSBvbmUgcGF0aCBmb3JnZXR0aW5nIHRvXG4gKiBzdHJpcCBgeC1mb3J3YXJkZWQtYWNjZXNzLXRva2VuYCBpcyBlbm91Z2ggLSBzbyB0aGUgZGVjaXNpb24sIHRoZSBoZWFkZXJcbiAqIHJld3JpdGluZywgYW5kIHRoZSBpZGVudGl0eSBpbmplY3Rpb24gbGl2ZSBoZXJlIG9uY2UgYW5kIHRoZSB0cmFuc3BvcnRzIG9ubHlcbiAqIGRpZmZlciBpbiBob3cgdGhleSBXUklURSB0aGUgb3V0Y29tZS5cbiAqXG4gKiBNdXRhdGVzIGByZXEuaGVhZGVyc2Agb24gdGhlIGBhbGxvd2AvYHBhc3NgLXdpdGgtY29va2llIHBhdGhzLCB3aGljaCBpcyBleGFjdGx5XG4gKiB3aGF0IGJvdGggY2FsbGVycyB3YW50OiBFeHByZXNzIGhhbmRzIHRoZSBzYW1lIG9iamVjdCB0byB0aGUgYXBwJ3MgaGFuZGxlcnMsIGFuZFxuICogdGhlIHByb3h5IGZvcndhcmRzIGl0IHVwc3RyZWFtLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2F0ZVJlcXVlc3QoXG4gIHJlcTogSW5jb21pbmdNZXNzYWdlLFxuICBvcHRpb25zOiBHYXRlT3B0aW9ucyAmIHsgaGVhZGVyUG9saWN5PzogSGVhZGVyUG9saWN5IH0sXG4pOiBQcm9taXNlPEdhdGVBY3Rpb24+IHtcbiAgY29uc3QgeyBnYXRlLCBwdWJsaWNEb21haW4gfSA9IG9wdGlvbnM7XG4gIC8vIE5vdCB0dW5uZWwgdHJhZmZpYyAocGxhdGZvcm0gZnJvbnQgZG9vciwgb3IgYW55IG90aGVyIGxvY2FsIGNhbGxlcik6IHRoZVxuICAvLyByZXF1ZXN0IGlzIGFscmVhZHkgYXV0aGVudGljYXRlZCwgb3IgaXMgbm90IG91cnMgdG8gZ2F0ZS5cbiAgaWYgKCFpc1R1bm5lbEhvc3QocmVxLCBwdWJsaWNEb21haW4pKSByZXR1cm4gXCJwYXNzXCI7XG5cbiAgY29uc3QgcGF0aCA9IChyZXEudXJsID8/IFwiL1wiKS5zcGxpdChcIj9cIilbMF0gPz8gXCIvXCI7XG4gIC8vIFRoZSBsb2dpbiBmbG93IGlzIG9wZW4gc28gdGhlIGJyb3dzZXIgY2FuIHJlbmRlciA8QXV0aEdhdGU+IGFuZCBzaWduIGluLlxuICBpZiAocGF0aC5zdGFydHNXaXRoKEFVVEhfUFJFRklYKSkgcmV0dXJuIFwicGFzc1wiO1xuXG4gIC8vIEFudGktc3Bvb2Y6IG9ubHkgdGhlIGdhdGUgbWF5IGFzc2VydCBpZGVudGl0eSBvbiB0dW5uZWwgdHJhZmZpYy5cbiAgY29uc3QgcG9saWN5ID0gb3B0aW9ucy5oZWFkZXJQb2xpY3kgPz8gdG9IZWFkZXJQb2xpY3kob3B0aW9ucy5mb3J3YXJkSGVhZGVycyk7XG4gIGNvbnN0IHJlbW92ZWQgPSBwb2xpY3kuYXBwbHkocmVxLmhlYWRlcnMgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pO1xuICBpZiAocmVtb3ZlZC5sZW5ndGgpIGxvZ2dlci5kZWJ1ZyhcInN0cmlwcGVkIGluYm91bmQgaGVhZGVyc1wiLCB7IHJlbW92ZWQgfSk7XG5cbiAgLy8gU3RhdGljIChub24tQVBJKSBsb2FkcyBmcmVlbHkgc28gdGhlIFNQQSBjYW4gcmVuZGVyOyBkcm9wIHRoZSBnYXRlIGNvb2tpZS5cbiAgaWYgKCFwYXRoLnN0YXJ0c1dpdGgoXCIvYXBpL1wiKSkge1xuICAgIHN0cmlwU2Vzc2lvbkNvb2tpZShyZXEpO1xuICAgIHJldHVybiBcInBhc3NcIjtcbiAgfVxuXG4gIC8vIEV2ZXJ5IG90aGVyIC9hcGkvKiBuZWVkcyBhIHZhbGlkIE9UUCBzZXNzaW9uLlxuICBjb25zdCBjb29raWUgPSBodHRwLnBhcnNlQ29va2llcyhyZXEuaGVhZGVycy5jb29raWUgPz8gbnVsbClbU0VTU0lPTl9DT09LSUVfTkFNRV07XG4gIGNvbnN0IGVtYWlsID0gYXdhaXQgZ2F0ZS5zZXNzaW9uKGNvb2tpZSk7XG4gIGlmICghZW1haWwpIHJldHVybiBcImRlbnlcIjtcbiAgaW5qZWN0SWRlbnRpdHkocmVxLCBlbWFpbCk7XG4gIHN0cmlwU2Vzc2lvbkNvb2tpZShyZXEpO1xuICByZXR1cm4gXCJhbGxvd1wiO1xufVxuXG4vKiogVGhlIGJvZHkgb2YgYSBgZGVueWAsIHNoYXJlZCBzbyBib3RoIHBhdGhzIGFuc3dlciBhIDQwMSBpZGVudGljYWxseS4gKi9cbmV4cG9ydCBjb25zdCBVTkFVVEhPUklaRURfQk9EWSA9IHtcbiAgZXJyb3I6IFwiYXV0aGVudGljYXRpb24gcmVxdWlyZWRcIixcbiAgbG9naW5QYXRoOiBBVVRIX1BSRUZJWCxcbn0gYXMgY29uc3Q7XG5cbi8qKiBUaGUgYFNldC1Db29raWVgIHZhbHVlIHRoYXQgaXNzdWVzIGEgdmVyaWZpZWQgc2Vzc2lvbi4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXNzaW9uU2V0Q29va2llKHNlc3Npb25Ub2tlbjogc3RyaW5nLCBtYXhBZ2VTZWNvbmRzOiBudW1iZXIpOiBzdHJpbmcge1xuICByZXR1cm4gc2Vzc2lvbkNvb2tpZShzZXNzaW9uVG9rZW4sIG1heEFnZVNlY29uZHMpO1xufVxuXG4vKiogVGhlIGBTZXQtQ29va2llYCB2YWx1ZSB0aGF0IGNsZWFycyB0aGUgc2Vzc2lvbi4gKi9cbmV4cG9ydCBjb25zdCBMT0dPVVRfU0VUX0NPT0tJRSA9IGAke1NFU1NJT05fQ09PS0lFX05BTUV9PTsgUGF0aD0vOyBIdHRwT25seTsgTWF4LUFnZT0wYDtcblxuLyoqXG4gKiBSZWdpc3RlciB0aGUgbG9naW4gcm91dGVzIGFuZCB0aGUgZ2F0aW5nIG1pZGRsZXdhcmUgb24gdGhlIGFwcCdzIEV4cHJlc3NcbiAqIGluc3RhbmNlLiBDYWxsZWQgZnJvbSB7QGxpbmsgQXV0aEdhdGVQbHVnaW59IHdpdGggdGhlIHJvdXRlciBBcHBLaXQgaGFuZHNcbiAqIGBpbmplY3RSb3V0ZXNgLCBwbHVzIGB0aGlzLmNvbnRleHQuYWRkTWlkZGxld2FyZWAgZm9yIHRoZSBnbG9iYWwgZ2F0ZS5cbiAqXG4gKiBgYWRkUm91dGVgL2BhZGRNaWRkbGV3YXJlYCBhcmUgdXNlZCAodmlhIHRoZSBwYXNzZWQgY2FsbGJhY2tzKSBiZWNhdXNlIHRoZSBsb2dpblxuICogcm91dGVzIGxpdmUgYXQgYW4gQUJTT0xVVEUgcGF0aCAoYC9hcGkvZW1haWwvYXV0aC8qYCwgdGhlIGNsaWVudCdzIGNvbnRyYWN0KSxcbiAqIG5vdCB1bmRlciB0aGUgcGx1Z2luJ3MgYC9hcGkvYXV0aEdhdGVgIGJhc2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtb3VudEdhdGUoXG4gIG9wdHM6IEdhdGVPcHRpb25zLFxuICBhZGRSb3V0ZTogKG1ldGhvZDogXCJnZXRcIiB8IFwicG9zdFwiLCBwYXRoOiBzdHJpbmcsIGhhbmRsZXI6IFJlcXVlc3RIYW5kbGVyKSA9PiB2b2lkLFxuICBhZGRNaWRkbGV3YXJlOiAocGF0aDogc3RyaW5nLCBoYW5kbGVyOiBSZXF1ZXN0SGFuZGxlcikgPT4gdm9pZCxcbik6IHZvaWQge1xuICBjb25zdCB7IGdhdGUsIHB1YmxpY0RvbWFpbiwgZm9yd2FyZEhlYWRlcnMgfSA9IG9wdHM7XG4gIGNvbnN0IGhlYWRlclBvbGljeSA9IHRvSGVhZGVyUG9saWN5KGZvcndhcmRIZWFkZXJzKTtcbiAgbG9nZ2VyLmRlYnVnKFwiZ2F0ZSBtb3VudGVkXCIsIHsgcHVibGljRG9tYWluLCBmb3J3YXJkOiBoZWFkZXJQb2xpY3kucGF0dGVybnMgfSk7XG5cbiAgLy8gLS0tIExvZ2luIHJvdXRlcyAob3BlbiBvbiB0dW5uZWwgdHJhZmZpYzsgYW5zd2VyZWQgaW4tcHJvY2VzcykgLS0tXG5cbiAgY29uc3Qgc3RhdHVzSGFuZGxlciA9IChhc3luYyAocmVxLCByZXMpID0+IHtcbiAgICAvLyBBIGxvY2FsIG9yIGZyb250LWRvb3IgY2FsbGVyIGlzIG5ldmVyIGdhdGVkLCBzbyB0aGUgaG9uZXN0IGFuc3dlciBpcyB0aGF0XG4gICAgLy8gdGhlIGdhdGUgZG9lcyBub3QgYXBwbHkgLSBub3QgdGhlIHNlc3Npb24gc3RhdGUgb2YgYSBjb29raWUgaXQgd291bGQgbmV2ZXJcbiAgICAvLyBjaGVjay4gV2l0aG91dCB0aGlzLCBhIGJyb3dzZXIgb24gYGxvY2FsaG9zdGAgcmVuZGVycyB0aGUgT1RQIGxvZ2luIHNjcmVlblxuICAgIC8vIGZvciBhIHJlcXVlc3QgdGhhdCB3b3VsZCBoYXZlIHBhc3NlZCB0aHJvdWdoIHVudG91Y2hlZC5cbiAgICBpZiAoIWlzVHVubmVsSG9zdChyZXEsIHB1YmxpY0RvbWFpbikpIHtcbiAgICAgIHNlbmRKc29uKHJlcywgMjAwLCB7IGF1dGhlbnRpY2F0ZWQ6IGZhbHNlLCBlbmFibGVkOiBmYWxzZSB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgY29va2llID0gaHR0cC5wYXJzZUNvb2tpZXMocmVxLmhlYWRlcnMuY29va2llID8/IG51bGwpW1NFU1NJT05fQ09PS0lFX05BTUVdO1xuICAgIHNlbmRKc29uKHJlcywgMjAwLCBhd2FpdCBnYXRlLnN0YXR1cyhjb29raWUpKTtcbiAgfSkgYXMgUmVxdWVzdEhhbmRsZXI7XG5cbiAgY29uc3QgcmVxdWVzdEhhbmRsZXIgPSAoYXN5bmMgKHJlcSwgcmVzKSA9PiB7XG4gICAgaWYgKCFpc1R1bm5lbEhvc3QocmVxLCBwdWJsaWNEb21haW4pKSB7XG4gICAgICBzZW5kSnNvbihyZXMsIDQwNCwgeyBlcnJvcjogXCJub3QgZm91bmRcIiB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcGFyc2VkID0gYXV0aFJlcXVlc3RTY2hlbWEuc2FmZVBhcnNlKGpzb24ucGFyc2VSZWNvcmQoYXdhaXQgcmVhZEJvZHkocmVxKSkpO1xuICAgIGlmICghcGFyc2VkLnN1Y2Nlc3MpIHJldHVybiBzZW5kSnNvbihyZXMsIDIwMCwgeyBvazogdHJ1ZSB9KTsgLy8gYW50aS1lbnVtZXJhdGlvblxuICAgIHNlbmRKc29uKHJlcywgMjAwLCBhd2FpdCBnYXRlLnJlcXVlc3QocGFyc2VkLmRhdGEuZW1haWwsIGNsaWVudElwKHJlcSkpKTtcbiAgfSkgYXMgUmVxdWVzdEhhbmRsZXI7XG5cbiAgY29uc3QgdmVyaWZ5SGFuZGxlciA9IChhc3luYyAocmVxLCByZXMpID0+IHtcbiAgICBpZiAoIWlzVHVubmVsSG9zdChyZXEsIHB1YmxpY0RvbWFpbikpIHtcbiAgICAgIHNlbmRKc29uKHJlcywgNDA0LCB7IGVycm9yOiBcIm5vdCBmb3VuZFwiIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBwYXJzZWQgPSBhdXRoVmVyaWZ5U2NoZW1hLnNhZmVQYXJzZShqc29uLnBhcnNlUmVjb3JkKGF3YWl0IHJlYWRCb2R5KHJlcSkpKTtcbiAgICBpZiAoIXBhcnNlZC5zdWNjZXNzKSByZXR1cm4gc2VuZEpzb24ocmVzLCAyMDAsIHsgb2s6IGZhbHNlIH0pO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGdhdGUudmVyaWZ5KHBhcnNlZC5kYXRhLmVtYWlsLCBwYXJzZWQuZGF0YS5jb2RlLCBjbGllbnRJcChyZXEpKTtcbiAgICBjb25zdCBjb29raWUgPVxuICAgICAgcmVzdWx0Lm9rICYmIHJlc3VsdC50b2tlbiA/IHNlc3Npb25Db29raWUocmVzdWx0LnRva2VuLCBnYXRlLnNlc3Npb25UdGxTZWNvbmRzKSA6IHVuZGVmaW5lZDtcbiAgICBzZW5kSnNvbihcbiAgICAgIHJlcyxcbiAgICAgIDIwMCxcbiAgICAgIHsgb2s6IHJlc3VsdC5vaywgLi4uKHJlc3VsdC5yZXRyeUFmdGVyID8geyByZXRyeUFmdGVyOiByZXN1bHQucmV0cnlBZnRlciB9IDoge30pIH0sXG4gICAgICBjb29raWUsXG4gICAgKTtcbiAgfSkgYXMgUmVxdWVzdEhhbmRsZXI7XG5cbiAgY29uc3QgbG9nb3V0SGFuZGxlciA9ICgocmVxLCByZXMpID0+IHtcbiAgICBpZiAoIWlzVHVubmVsSG9zdChyZXEsIHB1YmxpY0RvbWFpbikpIHtcbiAgICAgIHNlbmRKc29uKHJlcywgNDA0LCB7IGVycm9yOiBcIm5vdCBmb3VuZFwiIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzZW5kSnNvbihyZXMsIDIwMCwgeyBvazogdHJ1ZSB9LCBMT0dPVVRfU0VUX0NPT0tJRSk7XG4gIH0pIGFzIFJlcXVlc3RIYW5kbGVyO1xuXG4gIGFkZFJvdXRlKFwiZ2V0XCIsIGAke0FVVEhfUFJFRklYfS9zdGF0dXNgLCBzdGF0dXNIYW5kbGVyKTtcbiAgYWRkUm91dGUoXCJwb3N0XCIsIGAke0FVVEhfUFJFRklYfS9yZXF1ZXN0YCwgcmVxdWVzdEhhbmRsZXIpO1xuICBhZGRSb3V0ZShcInBvc3RcIiwgYCR7QVVUSF9QUkVGSVh9L3ZlcmlmeWAsIHZlcmlmeUhhbmRsZXIpO1xuICBhZGRSb3V0ZShcInBvc3RcIiwgYCR7QVVUSF9QUkVGSVh9L2xvZ291dGAsIGxvZ291dEhhbmRsZXIpO1xuXG4gIC8vIC0tLSBUaGUgZ2F0ZSBtaWRkbGV3YXJlIChydW5zIGJlZm9yZSBzdGF0aWMgKyB0aGUgYXBwJ3MgL2FwaSBoYW5kbGVycykgLS0tXG5cbiAgY29uc3QgZ2F0ZU1pZGRsZXdhcmUgPSAoYXN5bmMgKHJlcSwgcmVzLCBuZXh0KSA9PiB7XG4gICAgY29uc3QgYWN0aW9uID0gYXdhaXQgZ2F0ZVJlcXVlc3QocmVxLCB7IGdhdGUsIHB1YmxpY0RvbWFpbiwgaGVhZGVyUG9saWN5IH0pO1xuICAgIGlmIChhY3Rpb24gPT09IFwiZGVueVwiKSBzZW5kSnNvbihyZXMsIDQwMSwgVU5BVVRIT1JJWkVEX0JPRFkpO1xuICAgIGVsc2UgbmV4dCgpO1xuICB9KSBhcyBSZXF1ZXN0SGFuZGxlcjtcblxuICBhZGRNaWRkbGV3YXJlKFwiL1wiLCBnYXRlTWlkZGxld2FyZSk7XG59XG4iXX0=
224
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2F0ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9nYXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBc0JHO0FBR0gsT0FBTyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUVwRCxPQUFPLEVBQUUsY0FBYyxFQUFxQixNQUFNLGNBQWMsQ0FBQztBQUdqRSxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0FBT3pDLE1BQU0sQ0FBQyxNQUFNLFdBQVcsR0FBRyxpQkFBaUIsQ0FBQztBQW9CN0M7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxZQUFZLENBQUMsR0FBb0IsRUFBRSxZQUFnQztJQUNqRixJQUFJLENBQUMsWUFBWTtRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQ2hDLE1BQU0sSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2xFLE9BQU8sSUFBSSxLQUFLLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDM0QsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLFFBQVEsQ0FBQyxHQUFvQjtJQUMzQyxNQUFNLFNBQVMsR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDakQsTUFBTSxLQUFLLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsSUFBSSxFQUFFLENBQUMsQ0FBQztTQUMv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TUFBTSxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hFLENBQUMsQ0FBbUIsQ0FBQztJQUNyQixhQUFhLENBQUMsV0FBVyxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBRXhDLDZFQUE2RTtJQUU3RSxNQUFNLGNBQWMsR0FBRyxDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxFQUFFO1FBQy9DLE1BQU0sTUFBTSxHQUFHLE1BQU0sV0FBVyxDQUFDLEdBQUcsRUFBRSxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQztRQUM1RSxJQUFJLE1BQU0sS0FBSyxNQUFNO1lBQUUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQzs7WUFDMUQsSUFBSSxFQUFFLENBQUM7SUFDZCxDQUFDLENBQW1CLENBQUM7SUFFckIsYUFBYSxDQUFDLEdBQUcsRUFBRSxjQUFjLENBQUMsQ0FBQztBQUNyQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUaGUgdHVubmVsJ3MgaW4tYXBwIEFVVEggR0FURSAtIEV4cHJlc3MgbWlkZGxld2FyZSArIGxvZ2luIHJvdXRlcyB0aGVcbiAqIHtAbGluayBBdXRoR2F0ZVBsdWdpbn0gcmVnaXN0ZXJzIG9uIHRoZSBhcHAncyBPV04gc2VydmVyIHZpYSBgdGhpcy5jb250ZXh0YC5cbiAqXG4gKiBUaGUgZ2F0ZSBpcyBNSURETEVXQVJFLCBub3QgYSByZXZlcnNlIHByb3h5IC0gdGhlIGFwcCBpcyB0aGUgcHJvY2Vzcywgc28gdGhlcmUgaXNcbiAqIG5vdGhpbmcgdG8gZm9yd2FyZCB0by4gSXQgZWl0aGVyIHNob3J0LWNpcmN1aXRzICg0MDEsIG9yIGFuc3dlcnMgdGhlIG9wZW4gbG9naW5cbiAqIHJvdXRlcykgb3IgY2FsbHMgYG5leHQoKWAgdG8gbGV0IHRoZSBhcHAncyByZWFsIGhhbmRsZXJzIHJ1bi4gSXQgaXMgdGhlXG4gKiBcInN0YW5kcyBpbiBmb3IgQXBwS2l0IGF1dGhcIiBwYXRoOlxuICogYSBwb3J0ciBjYWxsZXIgYXV0aGVudGljYXRlcyB3aXRoIEJldHRlciBBdXRoIE9UUCBvciBhIHBhc3NrZXksIGFuZCBvblxuICogc3VjY2VzcyB0aGUgZ2F0ZSBpbmplY3RzIHRoZSBpZGVudGl0eSBoZWFkZXJzIEFwcEtpdCByZWFkcy5cbiAqXG4gKiBXSElDSCBUUkFGRklDIElTIEdBVEVEIC0gdGhlIGBIb3N0YCBoZWFkZXIsIG5vdCB0aGUgc29ja2V0LiBwb3J0cidzIGNsaWVudFxuICogZm9yd2FyZHMgd2l0aCBHbydzIGBodHRwdXRpbC5OZXdTaW5nbGVIb3N0UmV2ZXJzZVByb3h5YCBhbmQgYSBgRGlyZWN0b3JgIHRoYXRcbiAqIFBSRVNFUlZFUyB0aGUgb3JpZ2luYWwgYEhvc3RgLCBzbyB0dW5uZWwgcmVxdWVzdHMgYXJyaXZlIHdpdGhcbiAqIGBIb3N0OiA8c3ViZG9tYWluPi48c2VydmVyPmAgKHRoZSBwdWJsaWMgZG9tYWluKS4gQSBsb2NhbCBwcm9jZXNzIGhpdHRpbmcgdGhlXG4gKiBhcHAgZGlyZWN0bHkgc2VuZHMgYEhvc3Q6IDEyNy4wLjAuMTo8cG9ydD5gIC8gYGxvY2FsaG9zdGAuIFNvIE9OTFkgcmVxdWVzdHMgd2hvc2VcbiAqIGBIb3N0YCBtYXRjaGVzIHRoZSBjb25maWd1cmVkIHB1YmxpYyBkb21haW4gYXJlIGdhdGVkOyB0aGUgcGxhdGZvcm0gZnJvbnQgZG9vclxuICogYW5kIGFueSBvdGhlciBsb2NhbCBjbGllbnQgcGFzcyB0aHJvdWdoIHVudG91Y2hlZC4gVGhlcmUgaXMgbm8gcG9ydHItaW5qZWN0ZWRcbiAqIGlkZW50aWZ5aW5nIGhlYWRlciBhbmQgbm8gVENQL3NvdXJjZS1JUCBzaWduYWwgdG8gdXNlIGluc3RlYWQgKHRoZSBjbGllbnQgZGlhbHNcbiAqIHRoZSB0YXJnZXQgb3ZlciBwbGFpbiBsb29wYmFjaykuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB0eXBlIHsgSW5jb21pbmdNZXNzYWdlIH0gZnJvbSBcIm5vZGU6aHR0cFwiO1xuaW1wb3J0IHsgbG9nLCB0b2tlbiB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgdHlwZSB7IFJlcXVlc3RIYW5kbGVyLCBSZXNwb25zZSB9IGZyb20gXCJleHByZXNzXCI7XG5pbXBvcnQgeyB0b0hlYWRlclBvbGljeSwgdHlwZSBIZWFkZXJQb2xpY3kgfSBmcm9tIFwiLi9oZWFkZXJzLnRzXCI7XG5pbXBvcnQgdHlwZSB7IEF1dGhHYXRlQXBpIH0gZnJvbSBcIi4vcGx1Z2luLnRzXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJ0dW5uZWw6Z2F0ZVwiKTtcblxudHlwZSBXZWJSZXF1ZXN0SW5wdXQgPSBJbmNvbWluZ01lc3NhZ2UgJiB7XG4gIGJvZHk/OiB1bmtub3duO1xuICBvcmlnaW5hbFVybD86IHN0cmluZztcbn07XG5cbmV4cG9ydCBjb25zdCBBVVRIX1BSRUZJWCA9IFwiL2FwaS9lbWFpbC9hdXRoXCI7XG5cbi8qKiBPcHRpb25zIGZvciB7QGxpbmsgbW91bnRHYXRlfS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgR2F0ZU9wdGlvbnMge1xuICAvKiogVGhlIGluLXByb2Nlc3MgZ2F0ZSBBUEkgKHNlc3Npb24vcmVxdWVzdC92ZXJpZnkvc3RhdHVzKS4gKi9cbiAgZ2F0ZTogQXV0aEdhdGVBcGk7XG4gIC8qKlxuICAgKiBUaGUgcHVibGljIGA8c3ViZG9tYWluPi48c2VydmVyPmAgdGhhdCBpZGVudGlmaWVzIHBvcnRyIHRyYWZmaWMgYnkgYEhvc3RgLlxuICAgKiBXaGVuIGFic2VudCwgbm8gcmVxdWVzdCBpcyBldmVyIGNsYXNzaWZpZWQgYXMgdHVubmVsIHRyYWZmaWMgYW5kIHRoZSBnYXRlIGlzXG4gICAqIGluZXJ0IChldmVyeXRoaW5nIHBhc3NlcyB0aHJvdWdoKSAtIGEgdHVubmVsIHdpdGggbm8gcHVibGljIGRvbWFpbiBnYXRlc1xuICAgKiBub3RoaW5nLlxuICAgKi9cbiAgcHVibGljRG9tYWluPzogc3RyaW5nO1xuICAvKipcbiAgICogRXh0cmEgYHgtYCByZXF1ZXN0IGhlYWRlcnMgdHVubmVsIHRyYWZmaWMgbWF5IGZvcndhcmQgKHVuaW9uZWQgd2l0aCB0aGVcbiAgICogYnVpbHQtaW4gYWxsb3ctbGlzdCkuIEV2ZXJ5IG90aGVyIGB4LWAgaGVhZGVyIGlzIHN0cmlwcGVkIGZyb20gdHVubmVsIHRyYWZmaWMuXG4gICAqL1xuICBmb3J3YXJkSGVhZGVycz86IHJlYWRvbmx5IHN0cmluZ1tdO1xufVxuXG4vKipcbiAqIFRydWUgd2hlbiB0aGUgcmVxdWVzdCdzIGBIb3N0YCBpcyB0aGUgdHVubmVsJ3MgcHVibGljIGRvbWFpbiAtIGkuZS4gaXQgY2FtZSBpblxuICogb3ZlciBwb3J0ci4gQ2FzZS1pbnNlbnNpdGl2ZTsgdGhlIG9wdGlvbmFsIGA6cG9ydGAgaXMgaWdub3JlZC4gV2hlbiBubyBwdWJsaWNcbiAqIGRvbWFpbiBpcyBjb25maWd1cmVkLCBub3RoaW5nIGlzIHR1bm5lbCB0cmFmZmljLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNUdW5uZWxIb3N0KHJlcTogSW5jb21pbmdNZXNzYWdlLCBwdWJsaWNEb21haW46IHN0cmluZyB8IHVuZGVmaW5lZCk6IGJvb2xlYW4ge1xuICBpZiAoIXB1YmxpY0RvbWFpbikgcmV0dXJuIGZhbHNlO1xuICBjb25zdCBob3N0ID0gKHJlcS5oZWFkZXJzLmhvc3QgPz8gXCJcIikudG9Mb3dlckNhc2UoKS5zcGxpdChcIjpcIilbMF07XG4gIHJldHVybiBob3N0ID09PSBwdWJsaWNEb21haW4udG9Mb3dlckNhc2UoKS5zcGxpdChcIjpcIilbMF07XG59XG5cbi8qKlxuICogQ2xpZW50IElQIGZvciByYXRlLWxpbWl0aW5nOiB0aGUgUklHSFRNT1NUIGB4LWZvcndhcmRlZC1mb3JgIGVudHJ5ICh0aGUgdmFsdWVcbiAqIHRoZSBuZWFyZXN0IHRydXN0ZWQgaG9wIC0gcG9ydHIgLSB3cm90ZSksIGVsc2UgdGhlIHNvY2tldCBhZGRyZXNzLiBSZWFkaW5nIHRoZVxuICogcmlnaHRtb3N0LCBub3QgdGhlIGxlZnRtb3N0LCBzdG9wcyBhIGNhbGxlciBtaW50aW5nIGEgZnJlc2ggcmF0ZS1saW1pdCBidWNrZXQgYnlcbiAqIHZhcnlpbmcgdGhlIGhlYWRlci4gQ2FsbGVkIGJlZm9yZSB7QGxpbmsgc3RyaXBIZWFkZXJzfS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsaWVudElwKHJlcTogSW5jb21pbmdNZXNzYWdlKTogc3RyaW5nIHtcbiAgY29uc3QgZm9yd2FyZGVkID0gcmVxLmhlYWRlcnNbXCJ4LWZvcndhcmRlZC1mb3JcIl07XG4gIGNvbnN0IGNoYWluID0gKEFycmF5LmlzQXJyYXkoZm9yd2FyZGVkKSA/IGZvcndhcmRlZC5qb2luKFwiLFwiKSA6IChmb3J3YXJkZWQgPz8gXCJcIikpXG4gICAgLnNwbGl0KFwiLFwiKVxuICAgIC5tYXAoKGVudHJ5KSA9PiBlbnRyeS50cmltKCkpXG4gICAgLmZpbHRlcihCb29sZWFuKTtcbiAgcmV0dXJuIGNoYWluLmF0KC0xKSA/PyByZXEuc29ja2V0LnJlbW90ZUFkZHJlc3MgPz8gXCJ1bmtub3duXCI7XG59XG5cbi8qKlxuICogUmVtb3ZlIHRoZSBnYXRlJ3Mgc2Vzc2lvbiBjb29raWUgZnJvbSB0aGUgYENvb2tpZWAgaGVhZGVyIGJlZm9yZSB0aGUgYXBwJ3NcbiAqIGhhbmRsZXJzIHJ1biwgc28gdGhlIGFwcCBuZXZlciBzZWVzIGBkYnhfYXV0aGAgKGl0IGlzIHRoZSBnYXRlJ3MgY29uY2VybikuXG4gKiBQcmVzZXJ2ZXMgb3RoZXIgY29va2llczsgZGVsZXRlcyB0aGUgaGVhZGVyIHdoZW4gaXQgYmVjb21lcyBlbXB0eS5cbiAqL1xuZnVuY3Rpb24gc3RyaXBTZXNzaW9uQ29va2llKHJlcTogSW5jb21pbmdNZXNzYWdlKTogdm9pZCB7XG4gIGNvbnN0IHJhdyA9IHJlcS5oZWFkZXJzLmNvb2tpZTtcbiAgaWYgKCFyYXcpIHJldHVybjtcbiAgY29uc3Qga2VwdCA9IHJhd1xuICAgIC5zcGxpdChcIjtcIilcbiAgICAubWFwKChjKSA9PiBjLnRyaW0oKSlcbiAgICAuZmlsdGVyKChjKSA9PiBjICYmICFjLnN0YXJ0c1dpdGgoXCJkYngtdG9vbHMtYXV0aD1cIikgJiYgIWMuc3RhcnRzV2l0aChcImRieC10b29scy1wYXNza2V5PVwiKSk7XG4gIGlmIChrZXB0Lmxlbmd0aCkgcmVxLmhlYWRlcnMuY29va2llID0ga2VwdC5qb2luKFwiOyBcIik7XG4gIGVsc2UgZGVsZXRlIHJlcS5oZWFkZXJzLmNvb2tpZTtcbn1cblxuLyoqXG4gKiBQcmVzZW50IGEgcGFzc3dvcmRsZXNzLWF1dGhlbnRpY2F0ZWQgY2FsbGVyIHRvIHRoZSBhcHAgdGhlIFNBTUUgd2F5IGEgcGxhdGZvcm0gZnJvbnRcbiAqIGRvb3IgZG9lczogc2V0IHRoZSBmcm9udC1kb29yIGlkZW50aXR5IGhlYWRlcnMgdG8gdGhlIHZlcmlmaWVkIGFkZHJlc3MgKEFwcEtpdFxuICogcmVhZHMge0BsaW5rIHRva2VuLlVTRVJfSURfSEVBREVSfSBmb3IgdGhlIE9CTyB1c2VyIGlkKSwgc28gdGhlIGFwcCBuZWVkcyBub1xuICogZ2F0ZS1zcGVjaWZpYyBjb2RlIHBhdGguXG4gKlxuICogV2hhdCB0aGUgZ2F0ZSBDQU5OT1Qgc2V0IGlzIHtAbGluayB0b2tlbi5BQ0NFU1NfVE9LRU5fSEVBREVSfTogYW4gYXV0aCBzZXNzaW9uXG4gKiBwcm92ZXMgYW4gZW1haWwsIG5vdCBwb3NzZXNzaW9uIG9mIGEgRGF0YWJyaWNrcyBjcmVkZW50aWFsLiBJdHMgYWJzZW5jZSBpcyB3aGF0XG4gKiBgQGRieC10b29scy9hcHBraXRgJ3MgYGlkZW50aXR5OiBcImF1dG9cImAgZGV0ZWN0cywgc28gYSBnYXRlZCByZXF1ZXN0IHJ1bnMgYXMgdGhlXG4gKiBhcHAgc2VydmljZSBwcmluY2lwYWwgaW5zdGVhZCBvZiB0aHJvd2luZy5cbiAqL1xuZnVuY3Rpb24gaW5qZWN0SWRlbnRpdHkocmVxOiBJbmNvbWluZ01lc3NhZ2UsIGVtYWlsOiBzdHJpbmcpOiB2b2lkIHtcbiAgcmVxLmhlYWRlcnNbdG9rZW4uVVNFUl9JRF9IRUFERVJdID0gZW1haWw7XG4gIHJlcS5oZWFkZXJzW3Rva2VuLlVTRVJfRU1BSUxfSEVBREVSXSA9IGVtYWlsO1xufVxuXG4vKiogUmVhZCB0aGUgcmF3IHJlcXVlc3QgYm9keSBhcyB0ZXh0IChBcHBLaXQgcGFyc2VzIEpTT04sIGJ1dCB0aGUgZ2F0ZSByb3V0ZXNcbiAqIGFyZSBtb3VudGVkIGJlZm9yZSB0aGF0IHJ1bnMgZm9yIHR1bm5lbCB0cmFmZmljLCBzbyByZWFkIGRlZmVuc2l2ZWx5KS4gKi9cbmZ1bmN0aW9uIHJlYWRCb2R5KHJlcTogV2ViUmVxdWVzdElucHV0KTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgLy8gQXBwS2l0J3MganNvbiBib2R5LXBhcnNlciBtYXkgaGF2ZSBhbHJlYWR5IHBvcHVsYXRlZCByZXEuYm9keTsgcHJlZmVyIGl0LlxuICBpZiAocmVxLmJvZHkgIT09IHVuZGVmaW5lZCAmJiByZXEuYm9keSAhPT0gbnVsbCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodHlwZW9mIHJlcS5ib2R5ID09PSBcInN0cmluZ1wiID8gcmVxLmJvZHkgOiBKU09OLnN0cmluZ2lmeShyZXEuYm9keSkpO1xuICB9XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgIGxldCBkYXRhID0gXCJcIjtcbiAgICByZXEub24oXCJkYXRhXCIsIChjaHVuaykgPT4gKGRhdGEgKz0gY2h1bmspKTtcbiAgICByZXEub24oXCJlbmRcIiwgKCkgPT4gcmVzb2x2ZShkYXRhKSk7XG4gICAgcmVxLm9uKFwiZXJyb3JcIiwgKCkgPT4gcmVzb2x2ZShkYXRhKSk7XG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gd2ViSGVhZGVycyhyZXE6IEluY29taW5nTWVzc2FnZSk6IEhlYWRlcnMge1xuICBjb25zdCBoZWFkZXJzID0gbmV3IEhlYWRlcnMoKTtcbiAgZm9yIChjb25zdCBbbmFtZSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHJlcS5oZWFkZXJzKSkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgZm9yIChjb25zdCBpdGVtIG9mIHZhbHVlKSBoZWFkZXJzLmFwcGVuZChuYW1lLCBpdGVtKTtcbiAgICB9IGVsc2UgaWYgKHZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGhlYWRlcnMuc2V0KG5hbWUsIHZhbHVlKTtcbiAgICB9XG4gIH1cbiAgaGVhZGVycy5zZXQoXCJ4LXJlYWwtaXBcIiwgY2xpZW50SXAocmVxKSk7XG4gIHJldHVybiBoZWFkZXJzO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gd2ViUmVxdWVzdChyZXE6IFdlYlJlcXVlc3RJbnB1dCk6IFByb21pc2U8Z2xvYmFsVGhpcy5SZXF1ZXN0PiB7XG4gIGNvbnN0IGhvc3QgPSByZXEuaGVhZGVycy5ob3N0ID8/IFwibG9jYWxob3N0XCI7XG4gIGNvbnN0IGhvc3RuYW1lID0gaG9zdC5zcGxpdChcIjpcIilbMF0/LnRvTG93ZXJDYXNlKCk7XG4gIGNvbnN0IHByb3RvY29sID0gaG9zdG5hbWUgPT09IFwibG9jYWxob3N0XCIgfHwgaG9zdG5hbWUgPT09IFwiMTI3LjAuMC4xXCIgPyBcImh0dHBcIiA6IFwiaHR0cHNcIjtcbiAgY29uc3QgbWV0aG9kID0gKHJlcS5tZXRob2QgPz8gXCJHRVRcIikudG9VcHBlckNhc2UoKTtcbiAgY29uc3QgYm9keSA9IG1ldGhvZCA9PT0gXCJHRVRcIiB8fCBtZXRob2QgPT09IFwiSEVBRFwiID8gdW5kZWZpbmVkIDogYXdhaXQgcmVhZEJvZHkocmVxKTtcbiAgcmV0dXJuIG5ldyBnbG9iYWxUaGlzLlJlcXVlc3QoYCR7cHJvdG9jb2x9Oi8vJHtob3N0fSR7cmVxLm9yaWdpbmFsVXJsIHx8IHJlcS51cmx9YCwge1xuICAgIG1ldGhvZCxcbiAgICBoZWFkZXJzOiB3ZWJIZWFkZXJzKHJlcSksXG4gICAgLi4uKGJvZHkgPyB7IGJvZHkgfSA6IHt9KSxcbiAgfSk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzZW5kV2ViUmVzcG9uc2UocmVzOiBSZXNwb25zZSwgcmVzcG9uc2U6IGdsb2JhbFRoaXMuUmVzcG9uc2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgZm9yIChjb25zdCBbbmFtZSwgdmFsdWVdIG9mIHJlc3BvbnNlLmhlYWRlcnMuZW50cmllcygpKSB7XG4gICAgaWYgKG5hbWUudG9Mb3dlckNhc2UoKSAhPT0gXCJzZXQtY29va2llXCIpIHJlcy5zZXRIZWFkZXIobmFtZSwgdmFsdWUpO1xuICB9XG4gIGNvbnN0IGNvb2tpZXMgPSByZXNwb25zZS5oZWFkZXJzLmdldFNldENvb2tpZSgpO1xuICBpZiAoY29va2llcy5sZW5ndGgpIHJlcy5zZXRIZWFkZXIoXCJzZXQtY29va2llXCIsIGNvb2tpZXMpO1xuICBjb25zdCBib2R5ID0gQnVmZmVyLmZyb20oYXdhaXQgcmVzcG9uc2UuYXJyYXlCdWZmZXIoKSk7XG4gIHJlcy5zdGF0dXMocmVzcG9uc2Uuc3RhdHVzKS5zZW5kKGJvZHkpO1xufVxuXG4vKipcbiAqIFdoYXQgdGhlIGNhbGxlciBzaG91bGQgZG8gd2l0aCBhIHJlcXVlc3QsIGZyb20ge0BsaW5rIGdhdGVSZXF1ZXN0fS5cbiAqXG4gKiAgIC0gYHBhc3NgIC0gbm90IHR1bm5lbCB0cmFmZmljLCBvciBhbiBvcGVuIGxvZ2luIHJvdXRlLiBGb3J3YXJkIHVudG91Y2hlZC5cbiAqICAgLSBgYWxsb3dgIC0gdHVubmVsIHRyYWZmaWMgdGhhdCBpcyBhdXRob3JpemVkLiBUaGUgcmVxdWVzdCdzIGhlYWRlcnMgaGF2ZVxuICogICAgIEFMUkVBRFkgYmVlbiByZXdyaXR0ZW4gKHBvbGljeSBhcHBsaWVkLCBpZGVudGl0eSBpbmplY3RlZCwgc2Vzc2lvbiBjb29raWVcbiAqICAgICBzdHJpcHBlZCksIHNvIGZvcndhcmQgaXQgYXMgaXQgbm93IHN0YW5kcy5cbiAqICAgLSBgZGVueWAgLSB0dW5uZWwgdHJhZmZpYyB3aXRoIG5vIHZhbGlkIHNlc3Npb24uIEFuc3dlciBgNDAxYCB3aXRoXG4gKiAgICAge0BsaW5rIEFVVEhfUFJFRklYfSBhcyB0aGUgbG9naW4gcGF0aC5cbiAqL1xuZXhwb3J0IHR5cGUgR2F0ZUFjdGlvbiA9IFwicGFzc1wiIHwgXCJhbGxvd1wiIHwgXCJkZW55XCI7XG5cbi8qKlxuICogVEhFIGdhdGluZyBkZWNpc2lvbiwgZm9yIG9uZSByZXF1ZXN0LCBpbmRlcGVuZGVudCBvZiBob3cgaXQgd2lsbCBiZSBhbnN3ZXJlZC5cbiAqXG4gKiBCb3RoIHBhdGhzIGNhbGwgdGhpczogdGhlIEV4cHJlc3MgbWlkZGxld2FyZSBiZWxvdyAod2hlcmUgdGhlIGFwcCBpcyB0aGVcbiAqIHByb2Nlc3MpIGFuZCBgQGRieC10b29scy9jbGktdHVubmVsYCdzIHJldmVyc2UgcHJveHkgKHdoZXJlIHRoZSBhcHAgaXMgYSBjaGlsZFxuICogcHJvY2VzcyBvbiBhIHByaXZhdGUgcG9ydCkuIEEgZGl2ZXJnZW5jZSBiZXR3ZWVuIHRoZW0gd291bGQgYmUgYSBzZWN1cml0eSBidWdcbiAqIHRoZSBzZWNvbmQgcGF0aCBjb3VsZCBub3QgYmUgdGVzdGVkIGludG8gYWdyZWVtZW50IC0gb25lIHBhdGggZm9yZ2V0dGluZyB0b1xuICogc3RyaXAgYHgtZm9yd2FyZGVkLWFjY2Vzcy10b2tlbmAgaXMgZW5vdWdoIC0gc28gdGhlIGRlY2lzaW9uLCB0aGUgaGVhZGVyXG4gKiByZXdyaXRpbmcsIGFuZCB0aGUgaWRlbnRpdHkgaW5qZWN0aW9uIGxpdmUgaGVyZSBvbmNlIGFuZCB0aGUgdHJhbnNwb3J0cyBvbmx5XG4gKiBkaWZmZXIgaW4gaG93IHRoZXkgV1JJVEUgdGhlIG91dGNvbWUuXG4gKlxuICogTXV0YXRlcyBgcmVxLmhlYWRlcnNgIG9uIHRoZSBgYWxsb3dgL2BwYXNzYC13aXRoLWNvb2tpZSBwYXRocywgd2hpY2ggaXMgZXhhY3RseVxuICogd2hhdCBib3RoIGNhbGxlcnMgd2FudDogRXhwcmVzcyBoYW5kcyB0aGUgc2FtZSBvYmplY3QgdG8gdGhlIGFwcCdzIGhhbmRsZXJzLCBhbmRcbiAqIHRoZSBwcm94eSBmb3J3YXJkcyBpdCB1cHN0cmVhbS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdhdGVSZXF1ZXN0KFxuICByZXE6IEluY29taW5nTWVzc2FnZSxcbiAgb3B0aW9uczogR2F0ZU9wdGlvbnMgJiB7IGhlYWRlclBvbGljeT86IEhlYWRlclBvbGljeSB9LFxuKTogUHJvbWlzZTxHYXRlQWN0aW9uPiB7XG4gIGNvbnN0IHsgZ2F0ZSwgcHVibGljRG9tYWluIH0gPSBvcHRpb25zO1xuICAvLyBOb3QgdHVubmVsIHRyYWZmaWMgKHBsYXRmb3JtIGZyb250IGRvb3IsIG9yIGFueSBvdGhlciBsb2NhbCBjYWxsZXIpOiB0aGVcbiAgLy8gcmVxdWVzdCBpcyBhbHJlYWR5IGF1dGhlbnRpY2F0ZWQsIG9yIGlzIG5vdCBvdXJzIHRvIGdhdGUuXG4gIGlmICghaXNUdW5uZWxIb3N0KHJlcSwgcHVibGljRG9tYWluKSkgcmV0dXJuIFwicGFzc1wiO1xuXG4gIGNvbnN0IHBhdGggPSAocmVxLnVybCA/PyBcIi9cIikuc3BsaXQoXCI/XCIpWzBdID8/IFwiL1wiO1xuICAvLyBUaGUgbG9naW4gZmxvdyBpcyBvcGVuIHNvIHRoZSBicm93c2VyIGNhbiByZW5kZXIgPEF1dGhHYXRlPiBhbmQgc2lnbiBpbi5cbiAgaWYgKHBhdGguc3RhcnRzV2l0aChBVVRIX1BSRUZJWCkpIHJldHVybiBcInBhc3NcIjtcblxuICAvLyBBbnRpLXNwb29mOiBvbmx5IHRoZSBnYXRlIG1heSBhc3NlcnQgaWRlbnRpdHkgb24gdHVubmVsIHRyYWZmaWMuXG4gIGNvbnN0IHBvbGljeSA9IG9wdGlvbnMuaGVhZGVyUG9saWN5ID8/IHRvSGVhZGVyUG9saWN5KG9wdGlvbnMuZm9yd2FyZEhlYWRlcnMpO1xuICBjb25zdCByZW1vdmVkID0gcG9saWN5LmFwcGx5KHJlcS5oZWFkZXJzIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KTtcbiAgaWYgKHJlbW92ZWQubGVuZ3RoKSBsb2dnZXIuZGVidWcoXCJzdHJpcHBlZCBpbmJvdW5kIGhlYWRlcnNcIiwgeyByZW1vdmVkIH0pO1xuXG4gIC8vIFN0YXRpYyAobm9uLUFQSSkgbG9hZHMgZnJlZWx5IHNvIHRoZSBTUEEgY2FuIHJlbmRlcjsgZHJvcCB0aGUgZ2F0ZSBjb29raWUuXG4gIGlmICghcGF0aC5zdGFydHNXaXRoKFwiL2FwaS9cIikpIHtcbiAgICBzdHJpcFNlc3Npb25Db29raWUocmVxKTtcbiAgICByZXR1cm4gXCJwYXNzXCI7XG4gIH1cblxuICAvLyBFdmVyeSBvdGhlciAvYXBpLyogbmVlZHMgYSB2YWxpZCBCZXR0ZXIgQXV0aCBzZXNzaW9uLlxuICBjb25zdCBlbWFpbCA9IGF3YWl0IGdhdGUuc2Vzc2lvbih3ZWJIZWFkZXJzKHJlcSkpO1xuICBpZiAoIWVtYWlsKSByZXR1cm4gXCJkZW55XCI7XG4gIGluamVjdElkZW50aXR5KHJlcSwgZW1haWwpO1xuICBzdHJpcFNlc3Npb25Db29raWUocmVxKTtcbiAgcmV0dXJuIFwiYWxsb3dcIjtcbn1cblxuLyoqIFRoZSBib2R5IG9mIGEgYGRlbnlgLCBzaGFyZWQgc28gYm90aCBwYXRocyBhbnN3ZXIgYSA0MDEgaWRlbnRpY2FsbHkuICovXG5leHBvcnQgY29uc3QgVU5BVVRIT1JJWkVEX0JPRFkgPSB7XG4gIGVycm9yOiBcImF1dGhlbnRpY2F0aW9uIHJlcXVpcmVkXCIsXG4gIGxvZ2luUGF0aDogQVVUSF9QUkVGSVgsXG59IGFzIGNvbnN0O1xuXG4vKipcbiAqIFJlZ2lzdGVyIHRoZSBsb2dpbiByb3V0ZXMgYW5kIHRoZSBnYXRpbmcgbWlkZGxld2FyZSBvbiB0aGUgYXBwJ3MgRXhwcmVzc1xuICogaW5zdGFuY2UuIENhbGxlZCBmcm9tIHtAbGluayBBdXRoR2F0ZVBsdWdpbn0gd2l0aCB0aGUgcm91dGVyIEFwcEtpdCBoYW5kc1xuICogYGluamVjdFJvdXRlc2AsIHBsdXMgYHRoaXMuY29udGV4dC5hZGRNaWRkbGV3YXJlYCBmb3IgdGhlIGdsb2JhbCBnYXRlLlxuICpcbiAqIGBhZGRSb3V0ZWAvYGFkZE1pZGRsZXdhcmVgIGFyZSB1c2VkICh2aWEgdGhlIHBhc3NlZCBjYWxsYmFja3MpIGJlY2F1c2UgdGhlIGxvZ2luXG4gKiByb3V0ZXMgbGl2ZSBhdCBhbiBBQlNPTFVURSBwYXRoIChgL2FwaS9lbWFpbC9hdXRoLypgLCB0aGUgY2xpZW50J3MgY29udHJhY3QpLFxuICogbm90IHVuZGVyIHRoZSBwbHVnaW4ncyBgL2FwaS9hdXRoR2F0ZWAgYmFzZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1vdW50R2F0ZShcbiAgb3B0czogR2F0ZU9wdGlvbnMsXG4gIF9hZGRSb3V0ZTogKG1ldGhvZDogXCJnZXRcIiB8IFwicG9zdFwiLCBwYXRoOiBzdHJpbmcsIGhhbmRsZXI6IFJlcXVlc3RIYW5kbGVyKSA9PiB2b2lkLFxuICBhZGRNaWRkbGV3YXJlOiAocGF0aDogc3RyaW5nLCBoYW5kbGVyOiBSZXF1ZXN0SGFuZGxlcikgPT4gdm9pZCxcbik6IHZvaWQge1xuICBjb25zdCB7IGdhdGUsIHB1YmxpY0RvbWFpbiwgZm9yd2FyZEhlYWRlcnMgfSA9IG9wdHM7XG4gIGNvbnN0IGhlYWRlclBvbGljeSA9IHRvSGVhZGVyUG9saWN5KGZvcndhcmRIZWFkZXJzKTtcbiAgbG9nZ2VyLmRlYnVnKFwiZ2F0ZSBtb3VudGVkXCIsIHsgcHVibGljRG9tYWluLCBmb3J3YXJkOiBoZWFkZXJQb2xpY3kucGF0dGVybnMgfSk7XG5cbiAgLy8gQmV0dGVyIEF1dGggYW5kIHRoZSBjb21wYXRpYmlsaXR5IHJvdXRlcyBzaGFyZSBvbmUgZmV0Y2gtY29tcGF0aWJsZVxuICAvLyBoYW5kbGVyIGluIGJvdGggaG9zdGluZyBtb2Rlcy5cbiAgY29uc3QgYXV0aEhhbmRsZXIgPSAoYXN5bmMgKHJlcSwgcmVzKSA9PiB7XG4gICAgaWYgKCFpc1R1bm5lbEhvc3QocmVxLCBwdWJsaWNEb21haW4pKSB7XG4gICAgICBjb25zdCBwYXRoID0gKHJlcS51cmwgPz8gXCIvXCIpLnNwbGl0KFwiP1wiKVswXSA/PyBcIi9cIjtcbiAgICAgIGlmIChwYXRoLmVuZHNXaXRoKFwiL3N0YXR1c1wiKSkge1xuICAgICAgICByZXMuc3RhdHVzKDIwMCkuanNvbih7IGF1dGhlbnRpY2F0ZWQ6IGZhbHNlLCBlbmFibGVkOiBmYWxzZSwgcGFzc2tleXNFbmFibGVkOiBmYWxzZSB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlcy5zdGF0dXMoNDA0KS5qc29uKHsgZXJyb3I6IFwibm90IGZvdW5kXCIgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGF3YWl0IHNlbmRXZWJSZXNwb25zZShyZXMsIGF3YWl0IGdhdGUuaGFuZGxlcihhd2FpdCB3ZWJSZXF1ZXN0KHJlcSkpKTtcbiAgfSkgYXMgUmVxdWVzdEhhbmRsZXI7XG4gIGFkZE1pZGRsZXdhcmUoQVVUSF9QUkVGSVgsIGF1dGhIYW5kbGVyKTtcblxuICAvLyAtLS0gVGhlIGdhdGUgbWlkZGxld2FyZSAocnVucyBiZWZvcmUgc3RhdGljICsgdGhlIGFwcCdzIC9hcGkgaGFuZGxlcnMpIC0tLVxuXG4gIGNvbnN0IGdhdGVNaWRkbGV3YXJlID0gKGFzeW5jIChyZXEsIHJlcywgbmV4dCkgPT4ge1xuICAgIGNvbnN0IGFjdGlvbiA9IGF3YWl0IGdhdGVSZXF1ZXN0KHJlcSwgeyBnYXRlLCBwdWJsaWNEb21haW4sIGhlYWRlclBvbGljeSB9KTtcbiAgICBpZiAoYWN0aW9uID09PSBcImRlbnlcIikgcmVzLnN0YXR1cyg0MDEpLmpzb24oVU5BVVRIT1JJWkVEX0JPRFkpO1xuICAgIGVsc2UgbmV4dCgpO1xuICB9KSBhcyBSZXF1ZXN0SGFuZGxlcjtcblxuICBhZGRNaWRkbGV3YXJlKFwiL1wiLCBnYXRlTWlkZGxld2FyZSk7XG59XG4iXX0=
@@ -9,7 +9,7 @@
9
9
  * app's public port, binds the child process to the app, and stops portr during an
10
10
  * orderly AppKit shutdown.
11
11
  *
12
- * The email-OTP GATE is a separate concern: it is the `authGate` AppKit plugin,
12
+ * The passwordless GATE is a separate concern: it is the `authGate` AppKit plugin,
13
13
  * which registers the login routes + a gating middleware on the app's own server.
14
14
  * Register it in the app's `plugins` for gated traffic. This interceptor is only
15
15
  * the portr half - "update the host, bind portr" - the smallest useful unit.
@@ -9,7 +9,7 @@
9
9
  * app's public port, binds the child process to the app, and stops portr during an
10
10
  * orderly AppKit shutdown.
11
11
  *
12
- * The email-OTP GATE is a separate concern: it is the `authGate` AppKit plugin,
12
+ * The passwordless GATE is a separate concern: it is the `authGate` AppKit plugin,
13
13
  * which registers the login routes + a gating middleware on the app's own server.
14
14
  * Register it in the app's `plugins` for gated traffic. This interceptor is only
15
15
  * the portr half - "update the host, bind portr" - the smallest useful unit.
@@ -65,4 +65,4 @@ export function tunnelInterceptor(options = {}) {
65
65
  logger.info(`tunnel bound: portr -> :${port} (${portrConfig.subdomain}.${portrConfig.server})`);
66
66
  };
67
67
  }
68
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJjZXB0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW50ZXJjZXB0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBR0gsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsWUFBWSxFQUFFLGtCQUFrQixFQUFFLFVBQVUsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUU1RixNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLG9CQUFvQixDQUFDLENBQUM7QUFnQmhELHFGQUFxRjtBQUNyRixTQUFTLGlCQUFpQixDQUFDLElBQWE7SUFDdEMsT0FBTyxJQUFJLElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixDQUFDLElBQUksSUFBSSxDQUFDO0FBQzFFLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFDSCxNQUFNLFVBQVUsaUJBQWlCLENBQUMsVUFBb0MsRUFBRTtJQUN0RSxPQUFPLEtBQUssRUFBRSxHQUF1QixFQUFpQixFQUFFO1FBQ3RELElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUMzQixPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsS0FBSyxHQUFHLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQztRQUN6RCxDQUFDO1FBRUQsTUFBTSxJQUFJLEdBQUcsaUJBQWlCLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzdDLE1BQU0sV0FBVyxHQUFHLGtCQUFrQixDQUFDO1lBQ3JDLFlBQVksRUFBRSxPQUFPLENBQUMsWUFBWTtZQUNsQyxTQUFTLEVBQUUsT0FBTyxDQUFDLFNBQVM7WUFDNUIsSUFBSTtTQUNMLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNqQixNQUFNLENBQUMsSUFBSSxDQUFDLDRFQUE0RSxDQUFDLENBQUM7WUFDMUYsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLFFBQVEsR0FBRyxNQUFNLFlBQVksRUFBRSxDQUFDO1FBQ3RDLE1BQU0sZ0JBQWdCLENBQUMsV0FBVyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzlDLE1BQU0sS0FBSyxHQUFHLE1BQU0sVUFBVSxDQUFDLFdBQVcsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUN0RCxHQUFHLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXZCLEdBQUcsQ0FBQyxXQUFXLENBQUMsVUFBVSxFQUFFLEdBQUcsRUFBRTtZQUMvQixJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU07Z0JBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMzQyxDQUFDLENBQUMsQ0FBQztRQUVILE1BQU0sQ0FBQyxJQUFJLENBQUMsMkJBQTJCLElBQUksS0FBSyxXQUFXLENBQUMsU0FBUyxJQUFJLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ2xHLENBQUMsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIGB0dW5uZWxJbnRlcmNlcHRvcigpYCAtIHRoZSB7QGxpbmsgSW50ZXJjZXB0b3J9IHRoYXQgZnJvbnRzIGFuIGFwcCB3aXRoIGEgcHVibGljXG4gKiBwb3J0ciB0dW5uZWwsIGNvbnN1bWluZyB0aGUge0BsaW5rIEludGVyY2VwdG9yQ29udGV4dH0gYEBkYngtdG9vbHMvYXBwa2l0YCdzXG4gKiBgY3JlYXRlQXBwYCBoYW5kcyBpdC5cbiAqXG4gKiBUaGUgdHVubmVsIHJ1bnMgSU4tUFJPQ0VTUzogdGhlIEFQUCBpcyB0aGUgbWFpbiBwcm9jZXNzIGFuZCBoYW5kcyB0aGlzIGludGVyY2VwdG9yXG4gKiBpdHMgY29udGV4dCwgcmF0aGVyIHRoYW4gYSB3cmFwcGVyIHByb2Nlc3Mgc3Bhd25pbmcgdGhlIGFwcCBhcyBhIGNoaWxkLiBUaGVcbiAqIGludGVyY2VwdG9yIGFwcGxpZXMgdGhlIGNvbXB1dGVkIHdvcmtzcGFjZSBob3N0LCBpbnN0YWxscyBhbmQgbGF1bmNoZXMgcG9ydHIgb24gdGhlXG4gKiBhcHAncyBwdWJsaWMgcG9ydCwgYmluZHMgdGhlIGNoaWxkIHByb2Nlc3MgdG8gdGhlIGFwcCwgYW5kIHN0b3BzIHBvcnRyIGR1cmluZyBhblxuICogb3JkZXJseSBBcHBLaXQgc2h1dGRvd24uXG4gKlxuICogVGhlIGVtYWlsLU9UUCBHQVRFIGlzIGEgc2VwYXJhdGUgY29uY2VybjogaXQgaXMgdGhlIGBhdXRoR2F0ZWAgQXBwS2l0IHBsdWdpbixcbiAqIHdoaWNoIHJlZ2lzdGVycyB0aGUgbG9naW4gcm91dGVzICsgYSBnYXRpbmcgbWlkZGxld2FyZSBvbiB0aGUgYXBwJ3Mgb3duIHNlcnZlci5cbiAqIFJlZ2lzdGVyIGl0IGluIHRoZSBhcHAncyBgcGx1Z2luc2AgZm9yIGdhdGVkIHRyYWZmaWMuIFRoaXMgaW50ZXJjZXB0b3IgaXMgb25seVxuICogdGhlIHBvcnRyIGhhbGYgLSBcInVwZGF0ZSB0aGUgaG9zdCwgYmluZCBwb3J0clwiIC0gdGhlIHNtYWxsZXN0IHVzZWZ1bCB1bml0LlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgdHlwZSB7IEludGVyY2VwdG9yLCBJbnRlcmNlcHRvckNvbnRleHQgfSBmcm9tIFwiQGRieC10b29scy9hcHBraXRcIjtcbmltcG9ydCB7IGxvZywgb2JqZWN0IH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB7IGluc3RhbGxQb3J0ciwgcmVzb2x2ZVBvcnRyQ29uZmlnLCBzdGFydFBvcnRyLCB3cml0ZVBvcnRyQ29uZmlnIH0gZnJvbSBcIi4vcG9ydHIudHNcIjtcblxuY29uc3QgbG9nZ2VyID0gbG9nLmxvZ2dlcihcInR1bm5lbDppbnRlcmNlcHRvclwiKTtcblxuLyoqIE9wdGlvbnMgZm9yIHtAbGluayB0dW5uZWxJbnRlcmNlcHRvcn0gKGVhY2ggYWxzbyByZXNvbHZhYmxlIGZyb20gZW52KS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVHVubmVsSW50ZXJjZXB0b3JPcHRpb25zIHtcbiAgLyoqIHBvcnRyIGA8c3ViZG9tYWluPi48c2VydmVyPmAgdG8gc2VydmUgb24uIEVudiBgVFVOTkVMX1BVQkxJQ19ET01BSU5gLiAqL1xuICBwdWJsaWNEb21haW4/OiBzdHJpbmc7XG4gIC8qKiBwb3J0ciBzdWJkb21haW4gKGVsc2UgZGVyaXZlZCBmcm9tIHtAbGluayBwdWJsaWNEb21haW59KS4gKi9cbiAgc3ViZG9tYWluPzogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIFBVQkxJQyBwb3J0IHBvcnRyIGZvcndhcmRzIHRvIC0gdGhlIHBvcnQgdGhlIGFwcCBpdHNlbGYgbGlzdGVucyBvbi5cbiAgICogRGVmYXVsdHMgdG8gdGhlIERhdGFicmlja3MgQXBwcyBydW50aW1lIGNvbnRyYWN0IGBEQVRBQlJJQ0tTX0FQUF9QT1JUYFxuICAgKiAodGhlbiBgODAwMGApLCB3aGljaCBpcyB0aGUgcG9ydCB0aGUgcGxhdGZvcm0gcm91dGVzIHRvLlxuICAgKi9cbiAgcG9ydD86IG51bWJlcjtcbn1cblxuLyoqIFJlc29sdmUgdGhlIHB1YmxpYyBwb3J0IHBvcnRyIHNob3VsZCB0YXJnZXQ6IGV4cGxpY2l0LCBlbHNlIHRoZSBBcHBzIGNvbnRyYWN0LiAqL1xuZnVuY3Rpb24gcmVzb2x2ZVB1YmxpY1BvcnQocG9ydD86IG51bWJlcik6IG51bWJlciB7XG4gIHJldHVybiBwb3J0ID8/IG9iamVjdC50b051bWJlcihwcm9jZXNzLmVudi5EQVRBQlJJQ0tTX0FQUF9QT1JUKSA/PyA4MDAwO1xufVxuXG4vKipcbiAqIEJ1aWxkIHRoZSB0dW5uZWwge0BsaW5rIEludGVyY2VwdG9yfS4gUGFzcyBpdCB0byBgY3JlYXRlQXBwKHsgaW50ZXJjZXB0b3IgfSlgLlxuICpcbiAqIEEgbm8tb3AgKGxvZ3MgYW5kIHJldHVybnMpIHdoZW4gbm8gcG9ydHIgdHVubmVsIGlzIGNvbmZpZ3VyZWQgLSBubyBgUE9SVFJfVE9LRU5gXG4gKiBvciBubyByZXNvbHZhYmxlIGA8c3ViZG9tYWluPi48c2VydmVyPmAgLSBzbyBhbiBhcHAgY2FuIHJlZ2lzdGVyIGl0XG4gKiB1bmNvbmRpdGlvbmFsbHkgYW5kIG9ubHkgYWN0dWFsbHkgdHVubmVscyB3aGVyZSB0aGUgZGVwbG95bWVudCB3aXJlZCBwb3J0ci5cbiAqXG4gKiBAZXhhbXBsZVxuICogaW1wb3J0IHsgYXBwa2l0IH0gZnJvbSBcIkBkYngtdG9vbHMvYXBwa2l0XCI7XG4gKiBpbXBvcnQgeyB0dW5uZWxJbnRlcmNlcHRvciB9IGZyb20gXCJAZGJ4LXRvb2xzL3R1bm5lbFwiO1xuICpcbiAqIGF3YWl0IGFwcGtpdC5jcmVhdGVBcHAoe1xuICogICBwbHVnaW5zOiBbc2VydmVyKHsgaG9zdCwgc3RhdGljUGF0aCB9KV0sXG4gKiAgIGludGVyY2VwdG9yOiB0dW5uZWxJbnRlcmNlcHRvcigpLFxuICogfSk7XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0dW5uZWxJbnRlcmNlcHRvcihvcHRpb25zOiBUdW5uZWxJbnRlcmNlcHRvck9wdGlvbnMgPSB7fSk6IEludGVyY2VwdG9yIHtcbiAgcmV0dXJuIGFzeW5jIChjdHg6IEludGVyY2VwdG9yQ29udGV4dCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIGlmIChjdHguZW52LmRhdGFicmlja3NIb3N0KSB7XG4gICAgICBwcm9jZXNzLmVudi5EQVRBQlJJQ0tTX0hPU1QgPz89IGN0eC5lbnYuZGF0YWJyaWNrc0hvc3Q7XG4gICAgfVxuXG4gICAgY29uc3QgcG9ydCA9IHJlc29sdmVQdWJsaWNQb3J0KG9wdGlvbnMucG9ydCk7XG4gICAgY29uc3QgcG9ydHJDb25maWcgPSByZXNvbHZlUG9ydHJDb25maWcoe1xuICAgICAgcHVibGljRG9tYWluOiBvcHRpb25zLnB1YmxpY0RvbWFpbixcbiAgICAgIHN1YmRvbWFpbjogb3B0aW9ucy5zdWJkb21haW4sXG4gICAgICBwb3J0LFxuICAgIH0pO1xuICAgIGlmICghcG9ydHJDb25maWcpIHtcbiAgICAgIGxvZ2dlci5pbmZvKFwibm8gUE9SVFJfVE9LRU4vVFVOTkVMX1BVQkxJQ19ET01BSU4gLSB0aGUgYXBwIHJ1bnMgd2l0aG91dCBhIHB1YmxpYyB0dW5uZWxcIik7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcG9ydHJFbnYgPSBhd2FpdCBpbnN0YWxsUG9ydHIoKTtcbiAgICBhd2FpdCB3cml0ZVBvcnRyQ29uZmlnKHBvcnRyQ29uZmlnLCBwb3J0ckVudik7XG4gICAgY29uc3QgcG9ydHIgPSBhd2FpdCBzdGFydFBvcnRyKHBvcnRyQ29uZmlnLCBwb3J0ckVudik7XG4gICAgY3R4LmJpbmRQcm9jZXNzKHBvcnRyKTtcblxuICAgIGN0eC5vbkxpZmVjeWNsZShcInNodXRkb3duXCIsICgpID0+IHtcbiAgICAgIGlmICghcG9ydHIua2lsbGVkKSBwb3J0ci5raWxsKFwiU0lHVEVSTVwiKTtcbiAgICB9KTtcblxuICAgIGxvZ2dlci5pbmZvKGB0dW5uZWwgYm91bmQ6IHBvcnRyIC0+IDoke3BvcnR9ICgke3BvcnRyQ29uZmlnLnN1YmRvbWFpbn0uJHtwb3J0ckNvbmZpZy5zZXJ2ZXJ9KWApO1xuICB9O1xufVxuIl19
68
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJjZXB0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW50ZXJjZXB0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBR0gsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsWUFBWSxFQUFFLGtCQUFrQixFQUFFLFVBQVUsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUU1RixNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLG9CQUFvQixDQUFDLENBQUM7QUFnQmhELHFGQUFxRjtBQUNyRixTQUFTLGlCQUFpQixDQUFDLElBQWE7SUFDdEMsT0FBTyxJQUFJLElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixDQUFDLElBQUksSUFBSSxDQUFDO0FBQzFFLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFDSCxNQUFNLFVBQVUsaUJBQWlCLENBQUMsVUFBb0MsRUFBRTtJQUN0RSxPQUFPLEtBQUssRUFBRSxHQUF1QixFQUFpQixFQUFFO1FBQ3RELElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUMzQixPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsS0FBSyxHQUFHLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQztRQUN6RCxDQUFDO1FBRUQsTUFBTSxJQUFJLEdBQUcsaUJBQWlCLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzdDLE1BQU0sV0FBVyxHQUFHLGtCQUFrQixDQUFDO1lBQ3JDLFlBQVksRUFBRSxPQUFPLENBQUMsWUFBWTtZQUNsQyxTQUFTLEVBQUUsT0FBTyxDQUFDLFNBQVM7WUFDNUIsSUFBSTtTQUNMLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNqQixNQUFNLENBQUMsSUFBSSxDQUFDLDRFQUE0RSxDQUFDLENBQUM7WUFDMUYsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLFFBQVEsR0FBRyxNQUFNLFlBQVksRUFBRSxDQUFDO1FBQ3RDLE1BQU0sZ0JBQWdCLENBQUMsV0FBVyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzlDLE1BQU0sS0FBSyxHQUFHLE1BQU0sVUFBVSxDQUFDLFdBQVcsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUN0RCxHQUFHLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXZCLEdBQUcsQ0FBQyxXQUFXLENBQUMsVUFBVSxFQUFFLEdBQUcsRUFBRTtZQUMvQixJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU07Z0JBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMzQyxDQUFDLENBQUMsQ0FBQztRQUVILE1BQU0sQ0FBQyxJQUFJLENBQUMsMkJBQTJCLElBQUksS0FBSyxXQUFXLENBQUMsU0FBUyxJQUFJLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ2xHLENBQUMsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIGB0dW5uZWxJbnRlcmNlcHRvcigpYCAtIHRoZSB7QGxpbmsgSW50ZXJjZXB0b3J9IHRoYXQgZnJvbnRzIGFuIGFwcCB3aXRoIGEgcHVibGljXG4gKiBwb3J0ciB0dW5uZWwsIGNvbnN1bWluZyB0aGUge0BsaW5rIEludGVyY2VwdG9yQ29udGV4dH0gYEBkYngtdG9vbHMvYXBwa2l0YCdzXG4gKiBgY3JlYXRlQXBwYCBoYW5kcyBpdC5cbiAqXG4gKiBUaGUgdHVubmVsIHJ1bnMgSU4tUFJPQ0VTUzogdGhlIEFQUCBpcyB0aGUgbWFpbiBwcm9jZXNzIGFuZCBoYW5kcyB0aGlzIGludGVyY2VwdG9yXG4gKiBpdHMgY29udGV4dCwgcmF0aGVyIHRoYW4gYSB3cmFwcGVyIHByb2Nlc3Mgc3Bhd25pbmcgdGhlIGFwcCBhcyBhIGNoaWxkLiBUaGVcbiAqIGludGVyY2VwdG9yIGFwcGxpZXMgdGhlIGNvbXB1dGVkIHdvcmtzcGFjZSBob3N0LCBpbnN0YWxscyBhbmQgbGF1bmNoZXMgcG9ydHIgb24gdGhlXG4gKiBhcHAncyBwdWJsaWMgcG9ydCwgYmluZHMgdGhlIGNoaWxkIHByb2Nlc3MgdG8gdGhlIGFwcCwgYW5kIHN0b3BzIHBvcnRyIGR1cmluZyBhblxuICogb3JkZXJseSBBcHBLaXQgc2h1dGRvd24uXG4gKlxuICogVGhlIHBhc3N3b3JkbGVzcyBHQVRFIGlzIGEgc2VwYXJhdGUgY29uY2VybjogaXQgaXMgdGhlIGBhdXRoR2F0ZWAgQXBwS2l0IHBsdWdpbixcbiAqIHdoaWNoIHJlZ2lzdGVycyB0aGUgbG9naW4gcm91dGVzICsgYSBnYXRpbmcgbWlkZGxld2FyZSBvbiB0aGUgYXBwJ3Mgb3duIHNlcnZlci5cbiAqIFJlZ2lzdGVyIGl0IGluIHRoZSBhcHAncyBgcGx1Z2luc2AgZm9yIGdhdGVkIHRyYWZmaWMuIFRoaXMgaW50ZXJjZXB0b3IgaXMgb25seVxuICogdGhlIHBvcnRyIGhhbGYgLSBcInVwZGF0ZSB0aGUgaG9zdCwgYmluZCBwb3J0clwiIC0gdGhlIHNtYWxsZXN0IHVzZWZ1bCB1bml0LlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgdHlwZSB7IEludGVyY2VwdG9yLCBJbnRlcmNlcHRvckNvbnRleHQgfSBmcm9tIFwiQGRieC10b29scy9hcHBraXRcIjtcbmltcG9ydCB7IGxvZywgb2JqZWN0IH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB7IGluc3RhbGxQb3J0ciwgcmVzb2x2ZVBvcnRyQ29uZmlnLCBzdGFydFBvcnRyLCB3cml0ZVBvcnRyQ29uZmlnIH0gZnJvbSBcIi4vcG9ydHIudHNcIjtcblxuY29uc3QgbG9nZ2VyID0gbG9nLmxvZ2dlcihcInR1bm5lbDppbnRlcmNlcHRvclwiKTtcblxuLyoqIE9wdGlvbnMgZm9yIHtAbGluayB0dW5uZWxJbnRlcmNlcHRvcn0gKGVhY2ggYWxzbyByZXNvbHZhYmxlIGZyb20gZW52KS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVHVubmVsSW50ZXJjZXB0b3JPcHRpb25zIHtcbiAgLyoqIHBvcnRyIGA8c3ViZG9tYWluPi48c2VydmVyPmAgdG8gc2VydmUgb24uIEVudiBgVFVOTkVMX1BVQkxJQ19ET01BSU5gLiAqL1xuICBwdWJsaWNEb21haW4/OiBzdHJpbmc7XG4gIC8qKiBwb3J0ciBzdWJkb21haW4gKGVsc2UgZGVyaXZlZCBmcm9tIHtAbGluayBwdWJsaWNEb21haW59KS4gKi9cbiAgc3ViZG9tYWluPzogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIFBVQkxJQyBwb3J0IHBvcnRyIGZvcndhcmRzIHRvIC0gdGhlIHBvcnQgdGhlIGFwcCBpdHNlbGYgbGlzdGVucyBvbi5cbiAgICogRGVmYXVsdHMgdG8gdGhlIERhdGFicmlja3MgQXBwcyBydW50aW1lIGNvbnRyYWN0IGBEQVRBQlJJQ0tTX0FQUF9QT1JUYFxuICAgKiAodGhlbiBgODAwMGApLCB3aGljaCBpcyB0aGUgcG9ydCB0aGUgcGxhdGZvcm0gcm91dGVzIHRvLlxuICAgKi9cbiAgcG9ydD86IG51bWJlcjtcbn1cblxuLyoqIFJlc29sdmUgdGhlIHB1YmxpYyBwb3J0IHBvcnRyIHNob3VsZCB0YXJnZXQ6IGV4cGxpY2l0LCBlbHNlIHRoZSBBcHBzIGNvbnRyYWN0LiAqL1xuZnVuY3Rpb24gcmVzb2x2ZVB1YmxpY1BvcnQocG9ydD86IG51bWJlcik6IG51bWJlciB7XG4gIHJldHVybiBwb3J0ID8/IG9iamVjdC50b051bWJlcihwcm9jZXNzLmVudi5EQVRBQlJJQ0tTX0FQUF9QT1JUKSA/PyA4MDAwO1xufVxuXG4vKipcbiAqIEJ1aWxkIHRoZSB0dW5uZWwge0BsaW5rIEludGVyY2VwdG9yfS4gUGFzcyBpdCB0byBgY3JlYXRlQXBwKHsgaW50ZXJjZXB0b3IgfSlgLlxuICpcbiAqIEEgbm8tb3AgKGxvZ3MgYW5kIHJldHVybnMpIHdoZW4gbm8gcG9ydHIgdHVubmVsIGlzIGNvbmZpZ3VyZWQgLSBubyBgUE9SVFJfVE9LRU5gXG4gKiBvciBubyByZXNvbHZhYmxlIGA8c3ViZG9tYWluPi48c2VydmVyPmAgLSBzbyBhbiBhcHAgY2FuIHJlZ2lzdGVyIGl0XG4gKiB1bmNvbmRpdGlvbmFsbHkgYW5kIG9ubHkgYWN0dWFsbHkgdHVubmVscyB3aGVyZSB0aGUgZGVwbG95bWVudCB3aXJlZCBwb3J0ci5cbiAqXG4gKiBAZXhhbXBsZVxuICogaW1wb3J0IHsgYXBwa2l0IH0gZnJvbSBcIkBkYngtdG9vbHMvYXBwa2l0XCI7XG4gKiBpbXBvcnQgeyB0dW5uZWxJbnRlcmNlcHRvciB9IGZyb20gXCJAZGJ4LXRvb2xzL3R1bm5lbFwiO1xuICpcbiAqIGF3YWl0IGFwcGtpdC5jcmVhdGVBcHAoe1xuICogICBwbHVnaW5zOiBbc2VydmVyKHsgaG9zdCwgc3RhdGljUGF0aCB9KV0sXG4gKiAgIGludGVyY2VwdG9yOiB0dW5uZWxJbnRlcmNlcHRvcigpLFxuICogfSk7XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0dW5uZWxJbnRlcmNlcHRvcihvcHRpb25zOiBUdW5uZWxJbnRlcmNlcHRvck9wdGlvbnMgPSB7fSk6IEludGVyY2VwdG9yIHtcbiAgcmV0dXJuIGFzeW5jIChjdHg6IEludGVyY2VwdG9yQ29udGV4dCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIGlmIChjdHguZW52LmRhdGFicmlja3NIb3N0KSB7XG4gICAgICBwcm9jZXNzLmVudi5EQVRBQlJJQ0tTX0hPU1QgPz89IGN0eC5lbnYuZGF0YWJyaWNrc0hvc3Q7XG4gICAgfVxuXG4gICAgY29uc3QgcG9ydCA9IHJlc29sdmVQdWJsaWNQb3J0KG9wdGlvbnMucG9ydCk7XG4gICAgY29uc3QgcG9ydHJDb25maWcgPSByZXNvbHZlUG9ydHJDb25maWcoe1xuICAgICAgcHVibGljRG9tYWluOiBvcHRpb25zLnB1YmxpY0RvbWFpbixcbiAgICAgIHN1YmRvbWFpbjogb3B0aW9ucy5zdWJkb21haW4sXG4gICAgICBwb3J0LFxuICAgIH0pO1xuICAgIGlmICghcG9ydHJDb25maWcpIHtcbiAgICAgIGxvZ2dlci5pbmZvKFwibm8gUE9SVFJfVE9LRU4vVFVOTkVMX1BVQkxJQ19ET01BSU4gLSB0aGUgYXBwIHJ1bnMgd2l0aG91dCBhIHB1YmxpYyB0dW5uZWxcIik7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcG9ydHJFbnYgPSBhd2FpdCBpbnN0YWxsUG9ydHIoKTtcbiAgICBhd2FpdCB3cml0ZVBvcnRyQ29uZmlnKHBvcnRyQ29uZmlnLCBwb3J0ckVudik7XG4gICAgY29uc3QgcG9ydHIgPSBhd2FpdCBzdGFydFBvcnRyKHBvcnRyQ29uZmlnLCBwb3J0ckVudik7XG4gICAgY3R4LmJpbmRQcm9jZXNzKHBvcnRyKTtcblxuICAgIGN0eC5vbkxpZmVjeWNsZShcInNodXRkb3duXCIsICgpID0+IHtcbiAgICAgIGlmICghcG9ydHIua2lsbGVkKSBwb3J0ci5raWxsKFwiU0lHVEVSTVwiKTtcbiAgICB9KTtcblxuICAgIGxvZ2dlci5pbmZvKGB0dW5uZWwgYm91bmQ6IHBvcnRyIC0+IDoke3BvcnR9ICgke3BvcnRyQ29uZmlnLnN1YmRvbWFpbn0uJHtwb3J0ckNvbmZpZy5zZXJ2ZXJ9KWApO1xuICB9O1xufVxuIl19
@@ -1,12 +1,11 @@
1
1
  /**
2
- * `authGate()` - the AppKit plugin behind the tunnel's email-OTP gate.
2
+ * `authGate()` - the AppKit adapter around `@dbx-tools/auth`.
3
3
  *
4
4
  * It has NO routes of its own: the tunnel PROXY (not an HTTP server) calls the
5
5
  * handlers this plugin exposes via {@link AuthGatePlugin.exports}. The plugin
6
- * owns the allow-list, the per-email/per-IP rate limiters, the CacheManager-backed
7
- * one-time-code store, and the session JWT. `createApp` (with no `server()`) is
8
- * used only to auto-init `CacheManager` + prime the sibling `email` transport;
9
- * this plugin is where the gate logic lives.
6
+ * owns tunnel authorization, AppKit Lakebase discovery, email delivery, and
7
+ * transport mounting. Better Auth owns users, OTPs, sessions, rate limits, and
8
+ * passkeys. `createApp` can run this plugin with or without `server()`.
10
9
  *
11
10
  * Options come from CLI flags OR env, with sensible defaults - see
12
11
  * {@link resolveAuthGateConfig}. The one runtime dependency the plugin can't
@@ -15,8 +14,9 @@
15
14
  *
16
15
  * @module
17
16
  */
18
- import { Plugin, type BasePluginConfig } from "@databricks/appkit";
19
- import type { AuthStatus } from "@dbx-tools/shared-email";
17
+ import { Plugin, type BasePluginConfig, type ResourceRequirement, ResourceType } from "@databricks/appkit";
18
+ import { type AuthorizeIdentity, type AuthStorageConfig, type AuthStorageMode } from "@dbx-tools/auth";
19
+ import type { AuthStatus } from "@dbx-tools/shared-auth";
20
20
  import type { RequestHandler } from "express";
21
21
  import { type GateOptions } from "./gate.ts";
22
22
  interface GateMountContext {
@@ -26,7 +26,7 @@ interface GateMountContext {
26
26
  }
27
27
  export declare function mountGateOnContext(context: GateMountContext, options: GateOptions): void;
28
28
  /** Options for the {@link authGate} plugin (all resolvable from env - see below). */
29
- export interface AuthGateConfig extends BasePluginConfig {
29
+ export interface AuthGateConfig extends BasePluginConfig, AuthStorageConfig {
30
30
  /** Allow-list patterns (domain / glob / `/regex/`). Empty = allow nobody. Env TUNNEL_AUTH_ALLOW. */
31
31
  allow?: string | string[];
32
32
  /**
@@ -86,6 +86,11 @@ export interface AuthGateConfig extends BasePluginConfig {
86
86
  * different delivery path.
87
87
  */
88
88
  sendCode?: (email: string, code: string, opts: SendCodeOptions) => Promise<void>;
89
+ /**
90
+ * Identity authorization independent of authentication. Defaults to the
91
+ * configured allow-list and is re-evaluated for every accepted session.
92
+ */
93
+ authorizeIdentity?: AuthorizeIdentity;
89
94
  /**
90
95
  * The public `<subdomain>.<server>` that identifies portr traffic by its `Host`
91
96
  * header. Only requests whose `Host` matches this are gated; everything else
@@ -136,31 +141,26 @@ export interface ResolvedAuthGateConfig {
136
141
  forwardHeaders: string[];
137
142
  /** Run OPEN with no gate. */
138
143
  insecure: boolean;
144
+ storage: AuthStorageMode;
145
+ sqlitePath?: string;
139
146
  }
140
147
  /** Merge {@link AuthGateConfig} over env over defaults into a resolved config. */
141
148
  export declare function resolveAuthGateConfig(config: AuthGateConfig): ResolvedAuthGateConfig;
142
149
  /** The handlers the gate middleware calls in-process (returned by {@link AuthGatePlugin.exports}). */
143
150
  export interface AuthGateApi {
144
- /** Handle a code request. Always resolves `{ ok: true }` (anti-enumeration). */
145
- request(email: string, ip: string): Promise<{
146
- ok: true;
147
- retryAfter?: number;
148
- }>;
149
- /** Handle a code verification. On success returns the session token to cookie. */
150
- verify(email: string, code: string, ip: string): Promise<{
151
- ok: boolean;
152
- token?: string;
153
- retryAfter?: number;
154
- }>;
155
- /** Resolve the authenticated email for a session token, or undefined. */
156
- session(token: string | undefined): Promise<string | undefined>;
157
- /** Session TTL in seconds (for the cookie Max-Age). */
158
- readonly sessionTtlSeconds: number;
159
- /** The gate status payload (`enabled` is always true when this plugin runs). */
160
- status(token: string | undefined): Promise<AuthStatus>;
151
+ /** Better Auth and compatibility routes under `/api/email/auth/*`. */
152
+ handler(request: Request): Promise<Response>;
153
+ /** Resolve the authorized email for request headers, or undefined. */
154
+ session(headers: Headers): Promise<string | undefined>;
155
+ /** The gate status payload. */
156
+ status(headers: Headers): Promise<AuthStatus>;
157
+ /** Whether the runtime exposes passkey enrollment and authentication. */
158
+ readonly passkeysEnabled: boolean;
159
+ /** Close auth storage owned by this runtime. */
160
+ close(): Promise<void>;
161
161
  }
162
162
  /**
163
- * AppKit plugin owning the email-OTP gate. On `setup()` it registers the login
163
+ * AppKit plugin adapting `@dbx-tools/auth` to tunnel traffic. On `setup()` it registers the login
164
164
  * routes (`/api/email/auth/*`) and a gating middleware on the app's OWN Express
165
165
  * server via `this.context`, so a public portr caller must prove an email before
166
166
  * reaching the app's `/api/*` - see `./gate`. Front-door (platform) traffic and
@@ -174,14 +174,28 @@ export declare class AuthGatePlugin extends Plugin<AuthGateConfig> {
174
174
  stability: "beta";
175
175
  resources: {
176
176
  required: never[];
177
- optional: never[];
177
+ optional: {
178
+ type: ResourceType.POSTGRES;
179
+ alias: string;
180
+ resourceKey: string;
181
+ description: string;
182
+ permission: "CAN_CONNECT_AND_CREATE";
183
+ fields: {
184
+ instance_name: {
185
+ env: string;
186
+ };
187
+ database_name: {
188
+ env: string;
189
+ };
190
+ };
191
+ }[];
178
192
  };
179
193
  };
180
194
  private resolved;
181
- private codes;
182
- private readonly requestLimiter;
183
- private readonly verifyLimiter;
195
+ private runtime?;
196
+ static getResourceRequirements(config: AuthGateConfig): ResourceRequirement[];
184
197
  setup(): Promise<void>;
198
+ shutdown(): Promise<void>;
185
199
  /**
186
200
  * Register the login routes (`/api/email/auth/*`) and the gating middleware on
187
201
  * the app's OWN Express server. At `setup:complete`, the deferred server plugin
@@ -192,9 +206,8 @@ export declare class AuthGatePlugin extends Plugin<AuthGateConfig> {
192
206
  private mountGateRoutes;
193
207
  /** The code sender: the configured `sendCode`, else the shared-transport default. */
194
208
  private get sendCode();
209
+ private authorizeIdentity;
195
210
  exports(): AuthGateApi;
196
- private handleRequest;
197
- private handleVerify;
198
211
  }
199
212
  /** Factory: `authGate({ allow, subject, ... })` for an AppKit `plugins` array. */
200
213
  export declare const authGate: import("@databricks/appkit").ToPlugin<typeof AuthGatePlugin, AuthGateConfig, "authGate">;