@dbx-tools/appkit-mastra 0.9.58 → 0.9.61

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.
@@ -18,9 +18,11 @@
18
18
  * @module
19
19
  */
20
20
  import { StringDecoder } from "node:string_decoder";
21
- import { json, log, object } from "@dbx-tools/shared-core";
21
+ import { json, log, object, stringUtils } from "@dbx-tools/shared-core";
22
+ import { feedback, thread } from "@dbx-tools/shared-mastra";
22
23
  import { context, SpanKind, trace } from "@opentelemetry/api";
23
24
  import { getRPCMetadata, RPCType } from "@opentelemetry/core";
25
+ import { USER_EMAIL_HEADER, USER_ID_HEADER } from "./identity.js";
24
26
  const logger = log.logger("mastra/telemetry");
25
27
  /** Cap on each payload copied onto a span, so one turn cannot bloat the export. */
26
28
  export const TRACE_IO_LIMIT = 8_000;
@@ -47,6 +49,83 @@ export const CHAT_RESPONSE_ATTR = "appkit.mastra.chat.response";
47
49
  export const CHAT_IDENTITY_ATTR = "appkit.mastra.identity.mode";
48
50
  /** Whether the streamed turn emitted a Genie tool or progress event. */
49
51
  export const CHAT_GENIE_USED_ATTR = "appkit.mastra.genie.used";
52
+ /**
53
+ * MLflow span-type attribute. Databricks maps this (or `gen_ai.operation.name`)
54
+ * onto the type chip in the experiment UI. Custom values such as `GENIE` are
55
+ * allowed.
56
+ */
57
+ export const MLFLOW_SPAN_TYPE_ATTR = "mlflow.spanType";
58
+ /** GenAI semantic-convention operation name, an alternate span-type source. */
59
+ export const GEN_AI_OPERATION_NAME_ATTR = "gen_ai.operation.name";
60
+ /**
61
+ * Root-span user id the MLflow experiment UI's User column reads from OTel
62
+ * traces. Prefer the forwarded email when present so the column is human.
63
+ */
64
+ export const MLFLOW_USER_ATTR = "user.id";
65
+ /** Root-span session id that enables the MLflow Sessions tab. */
66
+ export const MLFLOW_SESSION_ATTR = "session.id";
67
+ /**
68
+ * Prefix Databricks/MLflow copies onto the unified-view `tags` map. The
69
+ * suffix after this prefix is the tag name shown in the experiment UI.
70
+ */
71
+ export const MLFLOW_TRACE_TAG_PREFIX = "mlflow.trace.tag.";
72
+ /** Experiment-UI tag marking a turn that called Genie. */
73
+ export const MLFLOW_GENIE_TAG = "genie";
74
+ /** Root-span type for a Mastra agent turn. */
75
+ export const MLFLOW_SPAN_TYPE_AGENT = "AGENT";
76
+ /** Span type for an `ask_genie` tool call. */
77
+ export const MLFLOW_SPAN_TYPE_GENIE = "GENIE";
78
+ /** Attribute key for the `genie` trace tag. */
79
+ export const MLFLOW_GENIE_TAG_ATTR = `${MLFLOW_TRACE_TAG_PREFIX}${MLFLOW_GENIE_TAG}`;
80
+ /** OpenTelemetry's sentinel for "no valid trace" - 32 zero hex chars. */
81
+ const INVALID_TRACE_ID = "0".repeat(32);
82
+ /**
83
+ * Publish the turn's MLflow trace id before the handler writes the body.
84
+ *
85
+ * The chat UI only shows thumbs when this header is present. Stamping it here
86
+ * (on the same span the middleware just resolved) avoids relying on async
87
+ * Express continuation still sitting inside `context.with()`.
88
+ */
89
+ /**
90
+ * Mark the active span as a Genie call so the experiment UI types it `GENIE`
91
+ * and tags the trace `genie=true`. Safe no-op when no recording span is active.
92
+ */
93
+ export function stampGenieToolSpan(span = trace.getActiveSpan()) {
94
+ if (!span?.isRecording())
95
+ return;
96
+ span.setAttribute(MLFLOW_SPAN_TYPE_ATTR, MLFLOW_SPAN_TYPE_GENIE);
97
+ span.setAttribute(GEN_AI_OPERATION_NAME_ATTR, "execute_tool");
98
+ span.setAttribute(MLFLOW_GENIE_TAG_ATTR, "true");
99
+ }
100
+ function requestHeader(req, name) {
101
+ const fromMethod = typeof req.header === "function" ? stringUtils.trimToNull(req.header(name)) : undefined;
102
+ if (fromMethod)
103
+ return fromMethod;
104
+ const raw = req.headers?.[name.toLowerCase()];
105
+ const value = Array.isArray(raw) ? raw[0] : raw;
106
+ return stringUtils.trimToNull(typeof value === "string" ? value : undefined) ?? undefined;
107
+ }
108
+ function requestQuery(req, name) {
109
+ const raw = req.query?.[name];
110
+ const value = Array.isArray(raw) ? raw[0] : raw;
111
+ return stringUtils.trimToNull(typeof value === "string" ? value : undefined) ?? undefined;
112
+ }
113
+ function stampMlflowActor(span, req) {
114
+ const user = requestHeader(req, USER_EMAIL_HEADER) ?? requestHeader(req, USER_ID_HEADER);
115
+ if (user)
116
+ span.setAttribute(MLFLOW_USER_ATTR, user);
117
+ const session = requestHeader(req, thread.THREAD_ID_HEADER) ?? requestQuery(req, thread.THREAD_ID_QUERY);
118
+ if (session)
119
+ span.setAttribute(MLFLOW_SESSION_ATTR, session);
120
+ }
121
+ function stampMlflowTraceId(res, span) {
122
+ if (res.headersSent)
123
+ return;
124
+ const traceId = span.spanContext().traceId;
125
+ if (!traceId || traceId === INVALID_TRACE_ID)
126
+ return;
127
+ res.setHeader(feedback.MLFLOW_TRACE_ID_HEADER, `tr-${traceId}`);
128
+ }
50
129
  /** Return one raw prompt when the request is exactly one text-only user message. */
51
130
  export function textOnlyChatInput(messages) {
52
131
  if (typeof messages === "string")
@@ -242,6 +321,10 @@ export function chatTurnTelemetryMiddleware(req, res, next, options = {}) {
242
321
  next();
243
322
  return;
244
323
  }
324
+ stampMlflowTraceId(res, target.span);
325
+ stampMlflowActor(target.span, req);
326
+ target.span.setAttribute(MLFLOW_SPAN_TYPE_ATTR, MLFLOW_SPAN_TYPE_AGENT);
327
+ target.span.setAttribute(GEN_AI_OPERATION_NAME_ATTR, "invoke_agent");
245
328
  const identity = typeof options.identity === "function" ? options.identity(req) : options.identity;
246
329
  if (identity) {
247
330
  target.span.setAttribute(CHAT_IDENTITY_ATTR, identity);
@@ -273,8 +356,10 @@ export function chatTurnTelemetryMiddleware(req, res, next, options = {}) {
273
356
  fullOutputRecorded = true;
274
357
  };
275
358
  const recordGenie = (used) => {
276
- if (used)
277
- target.span.setAttribute(CHAT_GENIE_USED_ATTR, true);
359
+ if (!used)
360
+ return;
361
+ target.span.setAttribute(CHAT_GENIE_USED_ATTR, true);
362
+ target.span.setAttribute(MLFLOW_GENIE_TAG_ATTR, "true");
278
363
  };
279
364
  const endOwnedSpan = () => {
280
365
  if (!target.owned || ownedSpanEnded)
@@ -323,4 +408,4 @@ export function attachChatTurnTelemetry(app, options = {}) {
323
408
  app.use((req, res, next) => chatTurnTelemetryMiddleware(req, res, next, options));
324
409
  logger.info("chat turn telemetry middleware attached", options);
325
410
  }
326
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVsZW1ldHJ5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3RlbGVtZXRyeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JHO0FBRUgsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRXBELE9BQU8sRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzNELE9BQU8sRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBYSxNQUFNLG9CQUFvQixDQUFDO0FBQ3pFLE9BQU8sRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFHOUQsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0FBRTlDLG1GQUFtRjtBQUNuRixNQUFNLENBQUMsTUFBTSxjQUFjLEdBQUcsS0FBSyxDQUFDO0FBRXBDLHVGQUF1RjtBQUN2RixNQUFNLG1CQUFtQixHQUFHLGNBQWMsR0FBRyxDQUFDLENBQUM7QUFFL0MsK0VBQStFO0FBQy9FLE1BQU0sZ0JBQWdCLEdBQUcsb0NBQW9DLENBQUM7QUFFOUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLGdCQUFnQixHQUFHLG1FQUFtRSxDQUFDO0FBRTdGLG9GQUFvRjtBQUNwRixNQUFNLENBQUMsTUFBTSx1QkFBdUIsR0FBRyxtQkFBbUIsQ0FBQztBQUMzRCxpRkFBaUY7QUFDakYsTUFBTSxDQUFDLE1BQU0sd0JBQXdCLEdBQUcsb0JBQW9CLENBQUM7QUFDN0QsdUZBQXVGO0FBQ3ZGLE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLDZCQUE2QixDQUFDO0FBQ2hFLCtFQUErRTtBQUMvRSxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyw2QkFBNkIsQ0FBQztBQUNoRSxrRUFBa0U7QUFDbEUsTUFBTSxDQUFDLE1BQU0sa0JBQWtCLEdB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Q25DLElBQUksQ0FBQztZQUNILE9BQU8sY0FBYyxDQUFDLEtBQUssRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDO1FBQ3hDLENBQUM7Z0JBQVMsQ0FBQztZQUNULFlBQVksRUFBRSxDQUFDO1FBQ2pCLENBQUM7SUFDSCxDQUFDLENBQW1CLENBQUM7SUFFckIsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFO1FBQ3JCLFlBQVksQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUNqQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUN0QyxXQUFXLENBQUMsU0FBUyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7UUFDbkMsWUFBWSxFQUFFLENBQUM7SUFDakIsQ0FBQyxDQUFDLENBQUM7SUFFSCxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUNuRSxDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsTUFBTSxVQUFVLHVCQUF1QixDQUNyQyxHQUFvQixFQUNwQixVQUFvQyxFQUFFO0lBRXRDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsMkJBQTJCLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUNsRixNQUFNLENBQUMsSUFBSSxDQUFDLHlDQUF5QyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQ2xFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvcHkgZWFjaCBNYXN0cmEgY2hhdCB0dXJuJ3MgcmVxdWVzdC9yZXNwb25zZSBvbnRvIGl0cyBPVGVsIHJvb3Qgc3BhblxuICogc28gRGF0YWJyaWNrcy1tYW5hZ2VkIE1MZmxvdyBjYW4gZGlzcGxheSB0aGVtLlxuICpcbiAqIFdoeSB0aGlzIGV4aXN0czogTUxmbG93J3MgVUMgYDx0YXJnZXQ+X3RyYWNlX3VuaWZpZWRgIHZpZXcgcGlja3MgdGhlXG4gKiBvbmUgc3BhbiB3aG9zZSBgcGFyZW50X3NwYW5faWRgIGlzIGVtcHR5IGFuZCByZWFkcyByZXF1ZXN0L3Jlc3BvbnNlXG4gKiBmcm9tIGBtbGZsb3cuc3BhbklucHV0c2AgLyBgbWxmbG93LnNwYW5PdXRwdXRzYCAob3IgdGhlIGBnZW5fYWkuKmBcbiAqIGVxdWl2YWxlbnRzKSBvbiBUSEFUIHNwYW4gb25seS4gTWFzdHJhIHJlY29yZHMgdGhlIHR1cm4gb24gaXRzXG4gKiBgaW52b2tlX2FnZW50YCBjaGlsZCB1bmRlciBgbWFzdHJhLmFnZW50X3J1bi5pbnB1dGAgLyBgLm91dHB1dGAsIGtleXNcbiAqIHRoZSB2aWV3IG5ldmVyIHJlYWRzLCBzbyBjaGF0IHRyYWNlcyBhcnJpdmUgd2l0aCBib3RoIGNvbHVtbnMgbnVsbFxuICogZXZlbiB3aGVuIHRoZSBzcGFucyB0aGVtc2VsdmVzIGxvb2sgaGVhbHRoeS5cbiAqXG4gKiBBcHBLaXQncyBIVFRQIGluc3RydW1lbnRhdGlvbiByZWNvcmRzIHRoZSBzZXJ2ZXIgc3BhbiBpbiBPVGVsIFJQQyBtZXRhZGF0YSxcbiAqIHdoaWNoIHJlbWFpbnMgYXZhaWxhYmxlIGV2ZW4gd2hlbiBFeHByZXNzIG1ha2VzIGEgbWlkZGxld2FyZS1sYXllciBjaGlsZFxuICogYWN0aXZlLiBXaGVuIGluc3RydW1lbnRhdGlvbiBpcyB1bmF2YWlsYWJsZSwgdGhpcyBtb2R1bGUgY3JlYXRlcyBvbmVcbiAqIHJlcXVlc3QtbGlmZXRpbWUgc2VydmVyIHNwYW4gYW5kIHJ1bnMgTWFzdHJhIHVuZGVyIGl0LlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBTdHJpbmdEZWNvZGVyIH0gZnJvbSBcIm5vZGU6c3RyaW5nX2RlY29kZXJcIjtcblxuaW1wb3J0IHsganNvbiwgbG9nLCBvYmplY3QgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHsgY29udGV4dCwgU3BhbktpbmQsIHRyYWNlLCB0eXBlIFNwYW4gfSBmcm9tIFwiQG9wZW50ZWxlbWV0cnkvYXBpXCI7XG5pbXBvcnQgeyBnZXRSUENNZXRhZGF0YSwgUlBDVHlwZSB9IGZyb20gXCJAb3BlbnRlbGVtZXRyeS9jb3JlXCI7XG5pbXBvcnQgdHlwZSBleHByZXNzIGZyb20gXCJleHByZXNzXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJtYXN0cmEvdGVsZW1ldHJ5XCIpO1xuXG4vKiogQ2FwIG9uIGVhY2ggcGF5bG9hZCBjb3BpZWQgb250byBhIHNwYW4sIHNvIG9uZSB0dXJuIGNhbm5vdCBibG9hdCB0aGUgZXhwb3J0LiAqL1xuZXhwb3J0IGNvbnN0IFRSQUNFX0lPX0xJTUlUID0gOF8wMDA7XG5cbi8qKiBCb3VuZCBmb3IgYSBub24tc3RyZWFtaW5nIGJvZHkgY2FwdHVyZWQgdGhyb3VnaCBgcmVzLmVuZGAgaW5zdGVhZCBvZiBgcmVzLmpzb25gLiAqL1xuY29uc3QgUkVTUE9OU0VfQk9EWV9MSU1JVCA9IFRSQUNFX0lPX0xJTUlUICogNDtcblxuLyoqIFRyYWNlciBzY29wZSB1c2VkIG9ubHkgd2hlbiBBcHBLaXQgZGlkIG5vdCBjcmVhdGUgYSByZWNvcmRpbmcgSFRUUCBzcGFuLiAqL1xuY29uc3QgQ0hBVF9UVVJOX1RSQUNFUiA9IFwiQGRieC10b29scy9hcHBraXQtbWFzdHJhL3RlbGVtZXRyeVwiO1xuXG4vKipcbiAqIE1vdW50LXJlbGF0aXZlIE1hc3RyYSBhZ2VudCBpbnZva2UgcGF0aHMgdGhhdCBjYXJyeSBhIGNoYXQgdHVybiBib2R5XG4gKiAoYG1lc3NhZ2VzYCkgYW5kIHN0cmVhbSBhbiBhc3Npc3RhbnQgYW5zd2VyLiBSZXN1bWUgLyBhcHByb3ZlIHZlcmJzXG4gKiBhcmUgaW50ZW50aW9uYWxseSBleGNsdWRlZDogdGhlaXIgYm9kaWVzIGFyZSB0b29sIGRlY2lzaW9ucywgbm90IHRoZVxuICogdXNlciBwcm9tcHQsIGFuZCB0aGV5IHJhcmVseSBwcm9kdWNlIGEgZnJlc2ggYW5zd2VyIHdvcnRoIHN1cmZhY2luZy5cbiAqL1xuY29uc3QgQUdFTlRfVFVSTl9ST1VURSA9IC9eKD86XFwvYWdlbnRzXFwvW14vXStcXC8oPzpzdHJlYW18Z2VuZXJhdGUpKD86XFwvfCQpfFxcL2NoYXRcXC9bXi9dKyQpL2k7XG5cbi8qKiBBdHRyaWJ1dGUga2V5cyB0aGUgTUxmbG93IFVDIGAqX3RyYWNlX3VuaWZpZWRgIHZpZXcgcmVhZHMgZnJvbSB0aGUgcm9vdCBzcGFuLiAqL1xuZXhwb3J0IGNvbnN0IE1MRkxPV19TUEFOX0lOUFVUU19BVFRSID0gXCJtbGZsb3cuc3BhbklucHV0c1wiO1xuLyoqIFJvb3Qtc3BhbiBhdHRyaWJ1dGUgY29uc3VtZWQgYXMgY2hhdCBvdXRwdXQgYnkgTUxmbG93IHVuaWZpZWQgdHJhY2Ugdmlld3MuICovXG5leHBvcnQgY29uc3QgTUxGTE9XX1NQQU5fT1VUUFVUU19BVFRSID0gXCJtbGZsb3cuc3Bhbk91dHB1dHNcIjtcbi8qKiBGdWxsIHNlcmlhbGl6ZWQgcmVxdWVzdCBtZXNzYWdlcyByZXRhaW5lZCB3aGVuIHRoZSBNTGZsb3cgcHJldmlldyBpcyBwbGFpbiB0ZXh0LiAqL1xuZXhwb3J0IGNvbnN0IENIQVRfTUVTU0FHRVNfQVRUUiA9IFwiYXBwa2l0Lm1hc3RyYS5jaGF0Lm1lc3NhZ2VzXCI7XG4vKiogRnVsbCBzZXJpYWxpemVkIHJlc3BvbnNlIHJldGFpbmVkIHdoZW4gdGhlIE1MZmxvdyBwcmV2aWV3IGlzIHBsYWluIHRleHQuICovXG5leHBvcnQgY29uc3QgQ0hBVF9SRVNQT05TRV9BVFRSID0gXCJhcHBraXQubWFzdHJhLmNoYXQucmVzcG9uc2VcIjtcbi8qKiBDcmVkZW50aWFsIG1vZGUgdXNlZCBieSBEYXRhYnJpY2tzIGNhbGxzIGluIHRoaXMgY2hhdCB0dXJuLiAqL1xuZXhwb3J0IGNvbnN0IENIQVRfSURFTlRJVFlfQVRUUiA9IFwiYXBwa2l0Lm1hc3RyYS5pZGVudGl0eS5tb2RlXCI7XG4vKiogV2hldGhlciB0aGUgc3RyZWFtZWQgdHVybiBlbWl0dGVkIGEgR2VuaWUgdG9vbCBvciBwcm9ncmVzcyBldmVudC4gKi9cbmV4cG9ydCBjb25zdCBDSEFUX0dFTklFX1VTRURfQVRUUiA9IFwiYXBwa2l0Lm1hc3RyYS5nZW5pZS51c2VkXCI7XG5cbi8qKiBSb290LXNwYW4gbWV0YWRhdGEga25vd24gYmVmb3JlIGEgY2hhdCByZXF1ZXN0IGlzIGRpc3BhdGNoZWQuICovXG5leHBvcnQgaW50ZXJmYWNlIENoYXRUdXJuVGVsZW1ldHJ5T3B0aW9ucyB7XG4gIHJlYWRvbmx5IGlkZW50aXR5PzpcbiAgICBcIm9ib1wiIHwgXCJzZXJ2aWNlLXByaW5jaXBhbFwiIHwgKChyZXF1ZXN0OiBleHByZXNzLlJlcXVlc3QpID0+IFwib2JvXCIgfCBcInNlcnZpY2UtcHJpbmNpcGFsXCIpO1xufVxuXG5pbnRlcmZhY2UgVHJhY2VUYXJnZXQge1xuICBzcGFuOiBTcGFuO1xuICBvd25lZDogYm9vbGVhbjtcbn1cblxuLyoqIFJldHVybiBvbmUgcmF3IHByb21wdCB3aGVuIHRoZSByZXF1ZXN0IGlzIGV4YWN0bHkgb25lIHRleHQtb25seSB1c2VyIG1lc3NhZ2UuICovXG5leHBvcnQgZnVuY3Rpb24gdGV4dE9ubHlDaGF0SW5wdXQobWVzc2FnZXM6IHVua25vd24pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBpZiAodHlwZW9mIG1lc3NhZ2VzID09PSBcInN0cmluZ1wiKSByZXR1cm4gbWVzc2FnZXMgfHwgdW5kZWZpbmVkO1xuICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZXMpIHx8IG1lc3NhZ2VzLmxlbmd0aCAhPT0gMSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3QgbWVzc2FnZSA9IG1lc3NhZ2VzWzBdO1xuICBpZiAoIW9iamVjdC5pc1JlY29yZChtZXNzYWdlKSB8fCBtZXNzYWdlLnJvbGUgIT09IFwidXNlclwiKSByZXR1cm4gdW5kZWZpbmVkO1xuICBpZiAodHlwZW9mIG1lc3NhZ2UuY29udGVudCA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIG1lc3NhZ2UuY29udGVudCB8fCB1bmRlZmluZWQ7XG4gIHJldHVybiB0ZXh0RnJvbVBhcnRzKG1lc3NhZ2UucGFydHMpID8/IHRleHRGcm9tUGFydHMobWVzc2FnZS5jb250ZW50KTtcbn1cblxuZnVuY3Rpb24gdGV4dEZyb21QYXJ0cyh2YWx1ZTogdW5rbm93bik6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmICghQXJyYXkuaXNBcnJheSh2YWx1ZSkgfHwgdmFsdWUubGVuZ3RoID09PSAwKSByZXR1cm4gdW5kZWZpbmVkO1xuICBjb25zdCB0ZXh0OiBzdHJpbmdbXSA9IFtdO1xuICBmb3IgKGNvbnN0IHBhcnQgb2YgdmFsdWUpIHtcbiAgICBpZiAoIW9iamVjdC5pc1JlY29yZChwYXJ0KSB8fCBwYXJ0LnR5cGUgIT09IFwidGV4dFwiIHx8IHR5cGVvZiBwYXJ0LnRleHQgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHRleHQucHVzaChwYXJ0LnRleHQpO1xuICB9XG4gIGNvbnN0IGpvaW5lZCA9IHRleHQuam9pbihcIlwiKTtcbiAgcmV0dXJuIGpvaW5lZCB8fCB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIHNlcmlhbGl6ZWQodmFsdWU6IHVua25vd24sIGxpbWl0ID0gVFJBQ0VfSU9fTElNSVQpOiBzdHJpbmcge1xuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodmFsdWUpPy5zbGljZSgwLCBsaW1pdCkgPz8gU3RyaW5nKHZhbHVlKS5zbGljZSgwLCBsaW1pdCk7XG59XG5cbmZ1bmN0aW9uIHNzZUZyYW1lKGxpbmU6IHN0cmluZyk6IHVua25vd24ge1xuICBpZiAoIWxpbmUuc3RhcnRzV2l0aChcImRhdGE6XCIpKSByZXR1cm4gdW5kZWZpbmVkO1xuICByZXR1cm4ganNvbi5wYXJzZShsaW5lLnNsaWNlKDUpKTtcbn1cblxuZnVuY3Rpb24gdmFsdWVVc2VzR2VuaWUodmFsdWU6IHVua25vd24sIGRlcHRoID0gMCk6IGJvb2xlYW4ge1xuICBpZiAoZGVwdGggPiAzKSByZXR1cm4gZmFsc2U7XG4gIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkgcmV0dXJuIHZhbHVlLnNvbWUoKGl0ZW0pID0+IHZhbHVlVXNlc0dlbmllKGl0ZW0sIGRlcHRoICsgMSkpO1xuICBpZiAoIW9iamVjdC5pc1JlY29yZCh2YWx1ZSkpIHJldHVybiBmYWxzZTtcbiAgaWYgKFxuICAgIHZhbHVlLnR5cGUgPT09IFwiZGF0YS1nZW5pZS1wcm9ncmVzc1wiIHx8XG4gICAgdmFsdWUudHlwZSA9PT0gXCJhc2tfZ2VuaWVfZG9uZVwiIHx8XG4gICAgdmFsdWUudG9vbE5hbWUgPT09IFwiYXNrX2dlbmllXCIgfHxcbiAgICB2YWx1ZS50b29sX25hbWUgPT09IFwiYXNrX2dlbmllXCIgfHxcbiAgICB2YWx1ZS5uYW1lID09PSBcImFza19nZW5pZVwiXG4gICkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBbXCJkYXRhXCIsIFwiZXZlbnRcIiwgXCJwYXlsb2FkXCJdLnNvbWUoKGtleSkgPT4gdmFsdWVVc2VzR2VuaWUodmFsdWVba2V5XSwgZGVwdGggKyAxKSk7XG59XG5cbi8qKiBSZXR1cm4gdGhlIGFzc2lzdGFudCB0ZXh0IGZyb20gb25lIFNTRSBsaW5lLCBvciBhbiBlbXB0eSBzdHJpbmcuICovXG5mdW5jdGlvbiBhc3Npc3RhbnRUZXh0RnJvbVNzZUxpbmUobGluZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGFzc2lzdGFudFRleHRGcm9tU3NlRnJhbWUoc3NlRnJhbWUobGluZSkpO1xufVxuXG5mdW5jdGlvbiBhc3Npc3RhbnRUZXh0RnJvbVNzZUZyYW1lKGZyYW1lOiB1bmtub3duKTogc3RyaW5nIHtcbiAgaWYgKCFvYmplY3QuaXNSZWNvcmQoZnJhbWUpIHx8IGZyYW1lLnR5cGUgIT09IFwidGV4dC1kZWx0YVwiKSByZXR1cm4gXCJcIjtcbiAgY29uc3QgdGV4dCA9XG4gICAgdHlwZW9mIGZyYW1lLmRlbHRhID09PSBcInN0cmluZ1wiXG4gICAgICA/IGZyYW1lLmRlbHRhXG4gICAgICA6IG9iamVjdC5pc1JlY29yZChmcmFtZS5wYXlsb2FkKVxuICAgICAgICA/IGZyYW1lLnBheWxvYWQudGV4dFxuICAgICAgICA6IHVuZGVmaW5lZDtcbiAgcmV0dXJuIHR5cGVvZiB0ZXh0ID09PSBcInN0cmluZ1wiID8gdGV4dCA6IFwiXCI7XG59XG5cbi8qKlxuICogQ29uY2F0ZW5hdGUgdGhlIGFzc2lzdGFudCdzIGFuc3dlciBvdXQgb2YgYW4gQUkgU0RLIFNTRSB0cmFuc2NyaXB0LlxuICpcbiAqIFRoZSBhZ2VudCBzdHJlYW1zIGl0cyByZXBseSBhcyBgdGV4dC1kZWx0YWAgZnJhbWVzXG4gKiAoYGRhdGE6IHtcInR5cGVcIjpcInRleHQtZGVsdGFcIixcInBheWxvYWRcIjp7XCJ0ZXh0XCI6XCIuLi5cIn19YCksIHNvIHRoZSBmdWxsXG4gKiBhbnN3ZXIgb25seSBldmVyIGV4aXN0cyBhcyBkZWx0YXMgb24gdGhlIHdpcmUgYW5kIGhhcyB0byBiZVxuICogcmVhc3NlbWJsZWQgaGVyZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFzc2lzdGFudFRleHRGcm9tU3NlKGJvZHk6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHBhcnRzOiBzdHJpbmdbXSA9IFtdO1xuICBmb3IgKGNvbnN0IGxpbmUgb2YgYm9keS5zcGxpdChcIlxcblwiKSkge1xuICAgIGNvbnN0IHRleHQgPSBhc3Npc3RhbnRUZXh0RnJvbVNzZUxpbmUobGluZSk7XG4gICAgaWYgKHRleHQpIHBhcnRzLnB1c2godGV4dCk7XG4gIH1cbiAgcmV0dXJuIHBhcnRzLmpvaW4oXCJcIikuc2xpY2UoMCwgVFJBQ0VfSU9fTElNSVQpO1xufVxuXG4vKiogUmVhZCB0aGUgZmluYWwgYXNzaXN0YW50IHRleHQgZnJvbSBhIG5vbi1zdHJlYW1pbmcgTWFzdHJhIHJlc3BvbnNlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFzc2lzdGFudFRleHRGcm9tSnNvbihib2R5OiB1bmtub3duKTogc3RyaW5nIHtcbiAgaWYgKCFvYmplY3QuaXNSZWNvcmQoYm9keSkgfHwgdHlwZW9mIGJvZHkudGV4dCAhPT0gXCJzdHJpbmdcIikgcmV0dXJuIFwiXCI7XG4gIHJldHVybiBib2R5LnRleHQuc2xpY2UoMCwgVFJBQ0VfSU9fTElNSVQpO1xufVxuXG4vKiogSW5jcmVtZW50YWxseSBhc3NlbWJsZSBVVEYtOCBTU0UgdGV4dCB3aGlsZSByZXRhaW5pbmcgYSBib3VuZGVkIEpTT04gZmFsbGJhY2suICovXG5jbGFzcyBBc3Npc3RhbnRSZXNwb25zZUNvbGxlY3RvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgZGVjb2RlciA9IG5ldyBTdHJpbmdEZWNvZGVyKFwidXRmOFwiKTtcbiAgcHJpdmF0ZSBhbnN3ZXIgPSBcIlwiO1xuICBwcml2YXRlIGJvZHkgPSBcIlwiO1xuICBwcml2YXRlIHBlbmRpbmdMaW5lID0gXCJcIjtcbiAgcHJpdmF0ZSBmaW5pc2hlZCA9IGZhbHNlO1xuICBwcml2YXRlIGdlbmllID0gZmFsc2U7XG5cbiAgd3JpdGUoY2h1bms6IHVua25vd24pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5maW5pc2hlZCkgcmV0dXJuO1xuICAgIGlmICh0eXBlb2YgY2h1bmsgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIHRoaXMuY29uc3VtZShjaHVuayk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChBcnJheUJ1ZmZlci5pc1ZpZXcoY2h1bmspKSB7XG4gICAgICB0aGlzLmNvbnN1bWUoXG4gICAgICAgIHRoaXMuZGVjb2Rlci53cml0ZShCdWZmZXIuZnJvbShjaHVuay5idWZmZXIsIGNodW5rLmJ5dGVPZmZzZXQsIGNodW5rLmJ5dGVMZW5ndGgpKSxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgZmluaXNoKCk6IHN0cmluZyB7XG4gICAgaWYgKHRoaXMuZmluaXNoZWQpIHJldHVybiB0aGlzLmFuc3dlciB8fCB0aGlzLmpzb25BbnN3ZXIoKTtcbiAgICB0aGlzLmZpbmlzaGVkID0gdHJ1ZTtcbiAgICB0aGlzLmNvbnN1bWUodGhpcy5kZWNvZGVyLmVuZCgpKTtcbiAgICB0aGlzLmNvbnN1bWVTc2VMaW5lKHRoaXMucGVuZGluZ0xpbmUpO1xuICAgIHRoaXMucGVuZGluZ0xpbmUgPSBcIlwiO1xuICAgIHJldHVybiB0aGlzLmFuc3dlciB8fCB0aGlzLmpzb25BbnN3ZXIoKTtcbiAgfVxuXG4gIHJhd0JvZHkoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5ib2R5LnNsaWNlKDAsIFRSQUNFX0lPX0xJTUlUKTtcbiAgfVxuXG4gIHVzZWRHZW5pZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5nZW5pZTtcbiAgfVxuXG4gIHByaXZhdGUgY29uc3VtZSh0ZXh0OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAoIXRleHQpIHJldHVybjtcbiAgICBpZiAodGhpcy5ib2R5Lmxlbmd0aCA8IFJFU1BPTlNFX0JPRFlfTElNSVQpIHtcbiAgICAgIHRoaXMuYm9keSArPSB0ZXh0LnNsaWNlKDAsIFJFU1BPTlNFX0JPRFlfTElNSVQgLSB0aGlzLmJvZHkubGVuZ3RoKTtcbiAgICB9XG4gICAgdGhpcy5wZW5kaW5nTGluZSArPSB0ZXh0O1xuICAgIGxldCBuZXdsaW5lID0gdGhpcy5wZW5kaW5nTGluZS5pbmRleE9mKFwiXFxuXCIpO1xuICAgIHdoaWxlIChuZXdsaW5lID49IDApIHtcbiAgICAgIHRoaXMuY29uc3VtZVNzZUxpbmUodGhpcy5wZW5kaW5nTGluZS5zbGljZSgwLCBuZXdsaW5lKS5yZXBsYWNlKC9cXHIkLywgXCJcIikpO1xuICAgICAgdGhpcy5wZW5kaW5nTGluZSA9IHRoaXMucGVuZGluZ0xpbmUuc2xpY2UobmV3bGluZSArIDEpO1xuICAgICAgbmV3bGluZSA9IHRoaXMucGVuZGluZ0xpbmUuaW5kZXhPZihcIlxcblwiKTtcbiAgICB9XG4gICAgaWYgKHRoaXMucGVuZGluZ0xpbmUubGVuZ3RoID4gUkVTUE9OU0VfQk9EWV9MSU1JVCkge1xuICAgICAgdGhpcy5wZW5kaW5nTGluZSA9IHRoaXMucGVuZGluZ0xpbmUuc2xpY2UoLVJFU1BPTlNFX0JPRFlfTElNSVQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY29uc3VtZVNzZUxpbmUobGluZTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgZnJhbWUgPSBzc2VGcmFtZShsaW5lKTtcbiAgICB0aGlzLmdlbmllIHx8PSB2YWx1ZVVzZXNHZW5pZShmcmFtZSk7XG4gICAgaWYgKHRoaXMuYW5zd2VyLmxlbmd0aCA+PSBUUkFDRV9JT19MSU1JVCkgcmV0dXJuO1xuICAgIGNvbnN0IHRleHQgPSBhc3Npc3RhbnRUZXh0RnJvbVNzZUZyYW1lKGZyYW1lKTtcbiAgICB0aGlzLmFuc3dlciArPSB0ZXh0LnNsaWNlKDAsIFRSQUNFX0lPX0xJTUlUIC0gdGhpcy5hbnN3ZXIubGVuZ3RoKTtcbiAgfVxuXG4gIHByaXZhdGUganNvbkFuc3dlcigpOiBzdHJpbmcge1xuICAgIHJldHVybiBhc3Npc3RhbnRUZXh0RnJvbUpzb24oanNvbi5wYXJzZSh0aGlzLmJvZHkpKTtcbiAgfVxufVxuXG4vKipcbiAqIFNlbGVjdCB0aGUgc3BhbiBNTGZsb3cgdHJlYXRzIGFzIHRoZSByZXF1ZXN0IHJvb3QuXG4gKlxuICogT1RlbCBIVFRQIGluc3RydW1lbnRhdGlvbiBzdG9yZXMgaXRzIHNlcnZlciBzcGFuIGluIFJQQyBtZXRhZGF0YS4gVGhhdCBzcGFuXG4gKiB3aW5zIG92ZXIgYW4gYWN0aXZlIEV4cHJlc3MgY2hpbGQuIElmIG5vIHJlY29yZGluZyBsb2NhbCBzcGFuIGV4aXN0cywgY3JlYXRlXG4gKiBvbmUgdW5kZXIgdGhlIGN1cnJlbnQgY29udGV4dCBzbyBlbmFibGVkIFczQyBwcm9wYWdhdGlvbiByZW1haW5zIGludGFjdC5cbiAqL1xuZnVuY3Rpb24gcmVzb2x2ZVRyYWNlVGFyZ2V0KCk6IFRyYWNlVGFyZ2V0IHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgYWN0aXZlQ29udGV4dCA9IGNvbnRleHQuYWN0aXZlKCk7XG4gIGNvbnN0IHJwYyA9IGdldFJQQ01ldGFkYXRhKGFjdGl2ZUNvbnRleHQpO1xuICBpZiAocnBjPy50eXBlID09PSBSUENUeXBlLkhUVFAgJiYgcnBjLnNwYW4uaXNSZWNvcmRpbmcoKSkge1xuICAgIHJldHVybiB7IHNwYW46IHJwYy5zcGFuLCBvd25lZDogZmFsc2UgfTtcbiAgfVxuXG4gIGNvbnN0IGFjdGl2ZSA9IHRyYWNlLmdldEFjdGl2ZVNwYW4oKTtcbiAgaWYgKGFjdGl2ZT8uaXNSZWNvcmRpbmcoKSkgcmV0dXJuIHsgc3BhbjogYWN0aXZlLCBvd25lZDogZmFsc2UgfTtcblxuICBjb25zdCBzcGFuID0gdHJhY2VcbiAgICAuZ2V0VHJhY2VyKENIQVRfVFVSTl9UUkFDRVIpXG4gICAgLnN0YXJ0U3BhbihcIm1hc3RyYS5jaGF0X3R1cm5cIiwgeyBraW5kOiBTcGFuS2luZC5TRVJWRVIgfSwgYWN0aXZlQ29udGV4dCk7XG4gIGlmICghc3Bhbi5pc1JlY29yZGluZygpKSB7XG4gICAgc3Bhbi5lbmQoKTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIHJldHVybiB7IHNwYW4sIG93bmVkOiB0cnVlIH07XG59XG5cbi8qKlxuICogRXhwcmVzcyBtaWRkbGV3YXJlIHRoYXQgc3RhbXBzIGNoYXQgdHVybiBJL08gb250byB0aGUgZXhwb3J0ZWQgT1RlbCByb290LlxuICpcbiAqIFRlZSBgcmVzLndyaXRlYCwgYHJlcy5qc29uYCwgYW5kIGByZXMuZW5kYCBpbnN0ZWFkIG9mIGxpc3RlbmluZyBmb3IgYGZpbmlzaGA6XG4gKiBIVFRQIGluc3RydW1lbnRhdGlvbiBlbmRzIGl0cyBzZXJ2ZXIgc3BhbiBvbiBmaW5pc2gsIGFuZCBhdHRyaWJ1dGVzIHNldFxuICogYWZ0ZXIgYSBzcGFuIGVuZHMgbmV2ZXIgcmVhY2ggdGhlIGV4cG9ydGVyLlxuICpcbiAqIGBwYXRoYCBpcyBtb3VudC1yZWxhdGl2ZSAod2hhdCB0aGUgTWFzdHJhIHN1Yi1hcHAgc2VlcyksIGUuZy5cbiAqIGAvYWdlbnRzL3N1cHBvcnQvc3RyZWFtYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNoYXRUdXJuVGVsZW1ldHJ5TWlkZGxld2FyZShcbiAgcmVxOiBleHByZXNzLlJlcXVlc3QsXG4gIHJlczogZXhwcmVzcy5SZXNwb25zZSxcbiAgbmV4dDogZXhwcmVzcy5OZXh0RnVuY3Rpb24sXG4gIG9wdGlvbnM6IENoYXRUdXJuVGVsZW1ldHJ5T3B0aW9ucyA9IHt9LFxuKTogdm9pZCB7XG4gIGlmIChyZXEubWV0aG9kICE9PSBcIlBPU1RcIiB8fCAhQUdFTlRfVFVSTl9ST1VURS50ZXN0KHJlcS5wYXRoKSkge1xuICAgIG5leHQoKTtcbiAgICByZXR1cm47XG4gIH1cbiAgY29uc3QgdGFyZ2V0ID0gcmVzb2x2ZVRyYWNlVGFyZ2V0KCk7XG4gIGlmICghdGFyZ2V0KSB7XG4gICAgbmV4dCgpO1xuICAgIHJldHVybjtcbiAgfVxuICBjb25zdCBpZGVudGl0eSA9XG4gICAgdHlwZW9mIG9wdGlvbnMuaWRlbnRpdHkgPT09IFwiZnVuY3Rpb25cIiA/IG9wdGlvbnMuaWRlbnRpdHkocmVxKSA6IG9wdGlvbnMuaWRlbnRpdHk7XG4gIGlmIChpZGVudGl0eSkge1xuICAgIHRhcmdldC5zcGFuLnNldEF0dHJpYnV0ZShDSEFUX0lERU5USVRZX0FUVFIsIGlkZW50aXR5KTtcbiAgfVxuICB0YXJnZXQuc3Bhbi5zZXRBdHRyaWJ1dGUoQ0hBVF9HRU5JRV9VU0VEX0FUVFIsIGZhbHNlKTtcblxuICBjb25zdCBtZXNzYWdlcyA9IChyZXEuYm9keSBhcyB7IG1lc3NhZ2VzPzogdW5rbm93biB9IHwgdW5kZWZpbmVkKT8ubWVzc2FnZXM7XG4gIGlmIChtZXNzYWdlcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgY29uc3QgZnVsbElucHV0ID0gc2VyaWFsaXplZChtZXNzYWdlcyk7XG4gICAgdGFyZ2V0LnNwYW4uc2V0QXR0cmlidXRlKENIQVRfTUVTU0FHRVNfQVRUUiwgZnVsbElucHV0KTtcbiAgICB0YXJnZXQuc3Bhbi5zZXRBdHRyaWJ1dGUoXG4gICAgICBNTEZMT1dfU1BBTl9JTlBVVFNfQVRUUixcbiAgICAgICh0ZXh0T25seUNoYXRJbnB1dChtZXNzYWdlcykgPz8gZnVsbElucHV0KS5zbGljZSgwLCBUUkFDRV9JT19MSU1JVCksXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IGNvbGxlY3RvciA9IG5ldyBBc3Npc3RhbnRSZXNwb25zZUNvbGxlY3RvcigpO1xuICBsZXQgb3V0cHV0UmVjb3JkZWQgPSBmYWxzZTtcbiAgbGV0IGZ1bGxPdXRwdXRSZWNvcmRlZCA9IGZhbHNlO1xuICBsZXQgb3duZWRTcGFuRW5kZWQgPSBmYWxzZTtcbiAgY29uc3QgcGFzc1Rocm91Z2hXcml0ZSA9IHJlcy53cml0ZS5iaW5kKHJlcykgYXMgKC4uLmFyZ3M6IHVua25vd25bXSkgPT4gYm9vbGVhbjtcbiAgY29uc3QgcGFzc1Rocm91Z2hFbmQgPSByZXMuZW5kLmJpbmQocmVzKSBhcyAoLi4uYXJnczogdW5rbm93bltdKSA9PiB1bmtub3duO1xuICBjb25zdCBwYXNzVGhyb3VnaEpzb24gPSByZXMuanNvbi5iaW5kKHJlcykgYXMgKGJvZHk/OiB1bmtub3duKSA9PiBleHByZXNzLlJlc3BvbnNlO1xuICBjb25zdCByZWNvcmRPdXRwdXQgPSAoYW5zd2VyOiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgICBpZiAob3V0cHV0UmVjb3JkZWQgfHwgIWFuc3dlcikgcmV0dXJuO1xuICAgIHRhcmdldC5zcGFuLnNldEF0dHJpYnV0ZShNTEZMT1dfU1BBTl9PVVRQVVRTX0FUVFIsIGFuc3dlci5zbGljZSgwLCBUUkFDRV9JT19MSU1JVCkpO1xuICAgIG91dHB1dFJlY29yZGVkID0gdHJ1ZTtcbiAgfTtcbiAgY29uc3QgcmVjb3JkRnVsbE91dHB1dCA9IChyZXNwb25zZTogc3RyaW5nKTogdm9pZCA9PiB7XG4gICAgaWYgKGZ1bGxPdXRwdXRSZWNvcmRlZCB8fCAhcmVzcG9uc2UpIHJldHVybjtcbiAgICB0YXJnZXQuc3Bhbi5zZXRBdHRyaWJ1dGUoQ0hBVF9SRVNQT05TRV9BVFRSLCByZXNwb25zZS5zbGljZSgwLCBUUkFDRV9JT19MSU1JVCkpO1xuICAgIGZ1bGxPdXRwdXRSZWNvcmRlZCA9IHRydWU7XG4gIH07XG4gIGNvbnN0IHJlY29yZEdlbmllID0gKHVzZWQ6IGJvb2xlYW4pOiB2b2lkID0+IHtcbiAgICBpZiAodXNlZCkgdGFyZ2V0LnNwYW4uc2V0QXR0cmlidXRlKENIQVRfR0VOSUVfVVNFRF9BVFRSLCB0cnVlKTtcbiAgfTtcbiAgY29uc3QgZW5kT3duZWRTcGFuID0gKCk6IHZvaWQgPT4ge1xuICAgIGlmICghdGFyZ2V0Lm93bmVkIHx8IG93bmVkU3BhbkVuZGVkKSByZXR1cm47XG4gICAgb3duZWRTcGFuRW5kZWQgPSB0cnVlO1xuICAgIHRhcmdldC5zcGFuLmVuZCgpO1xuICB9O1xuXG4gIHJlcy53cml0ZSA9ICgoY2h1bms6IHVua25vd24sIC4uLnJlc3Q6IHVua25vd25bXSkgPT4ge1xuICAgIGNvbGxlY3Rvci53cml0ZShjaHVuayk7XG4gICAgcmV0dXJuIHBhc3NUaHJvdWdoV3JpdGUoY2h1bmssIC4uLnJlc3QpO1xuICB9KSBhcyB0eXBlb2YgcmVzLndyaXRlO1xuXG4gIHJlcy5qc29uID0gKChib2R5PzogdW5rbm93bikgPT4ge1xuICAgIHJlY29yZEZ1bGxPdXRwdXQoc2VyaWFsaXplZChib2R5KSk7XG4gICAgcmVjb3JkR2VuaWUodmFsdWVVc2VzR2VuaWUoYm9keSkpO1xuICAgIHJlY29yZE91dHB1dChhc3Npc3RhbnRUZXh0RnJvbUpzb24oYm9keSkpO1xuICAgIHJldHVybiBwYXNzVGhyb3VnaEpzb24oYm9keSk7XG4gIH0pIGFzIHR5cGVvZiByZXMuanNvbjtcblxuICByZXMuZW5kID0gKChjaHVuaz86IHVua25vd24sIC4uLnJlc3Q6IHVua25vd25bXSkgPT4ge1xuICAgIGNvbGxlY3Rvci53cml0ZShjaHVuayk7XG4gICAgcmVjb3JkT3V0cHV0KGNvbGxlY3Rvci5maW5pc2goKSk7XG4gICAgcmVjb3JkRnVsbE91dHB1dChjb2xsZWN0b3IucmF3Qm9keSgpKTtcbiAgICByZWNvcmRHZW5pZShjb2xsZWN0b3IudXNlZEdlbmllKCkpO1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gcGFzc1Rocm91Z2hFbmQoY2h1bmssIC4uLnJlc3QpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBlbmRPd25lZFNwYW4oKTtcbiAgICB9XG4gIH0pIGFzIHR5cGVvZiByZXMuZW5kO1xuXG4gIHJlcy5vbmNlKFwiY2xvc2VcIiwgKCkgPT4ge1xuICAgIHJlY29yZE91dHB1dChjb2xsZWN0b3IuZmluaXNoKCkpO1xuICAgIHJlY29yZEZ1bGxPdXRwdXQoY29sbGVjdG9yLnJhd0JvZHkoKSk7XG4gICAgcmVjb3JkR2VuaWUoY29sbGVjdG9yLnVzZWRHZW5pZSgpKTtcbiAgICBlbmRPd25lZFNwYW4oKTtcbiAgfSk7XG5cbiAgY29udGV4dC53aXRoKHRyYWNlLnNldFNwYW4oY29udGV4dC5hY3RpdmUoKSwgdGFyZ2V0LnNwYW4pLCBuZXh0KTtcbn1cblxuLyoqXG4gKiBJbnN0YWxsIHtAbGluayBjaGF0VHVyblRlbGVtZXRyeU1pZGRsZXdhcmV9IG9uIGEgTWFzdHJhIEV4cHJlc3Mgc3ViLWFwcC5cbiAqXG4gKiBDYWxsIGJlZm9yZSBgTWFzdHJhU2VydmVyLmluaXQoKWAgc28gdGhlIGxheWVyIHNpdHMgYWhlYWQgb2YgdGhlIGFnZW50XG4gKiByb3V0ZXMuIFNhZmUgdG8gY2FsbCB1bmNvbmRpdGlvbmFsbHk6IHdoZW4gbm8gcmVjb3JkaW5nIHRyYWNlciBpcyByZWdpc3RlcmVkLFxuICogdGhlIG1pZGRsZXdhcmUgaXMgYSBuby1vcC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGF0dGFjaENoYXRUdXJuVGVsZW1ldHJ5KFxuICBhcHA6IGV4cHJlc3MuRXhwcmVzcyxcbiAgb3B0aW9uczogQ2hhdFR1cm5UZWxlbWV0cnlPcHRpb25zID0ge30sXG4pOiB2b2lkIHtcbiAgYXBwLnVzZSgocmVxLCByZXMsIG5leHQpID0+IGNoYXRUdXJuVGVsZW1ldHJ5TWlkZGxld2FyZShyZXEsIHJlcywgbmV4dCwgb3B0aW9ucykpO1xuICBsb2dnZXIuaW5mbyhcImNoYXQgdHVybiB0ZWxlbWV0cnkgbWlkZGxld2FyZSBhdHRhY2hlZFwiLCBvcHRpb25zKTtcbn1cbiJdfQ==
411
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVsZW1ldHJ5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3RlbGVtZXRyeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JHO0FBRUgsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRXBELE9BQU8sRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN4RSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzVELE9BQU8sRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBYSxNQUFNLG9CQUFvQixDQUFDO0FBQ3pFLE9BQU8sRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFHOUQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLGNBQWMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVsRSxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLGtCQUFrQixDQUFDLENBQUM7QUFFOUMsbUZBQW1GO0FBQ25GLE1BQU0sQ0FBQyxNQUFNLGNBQWMsR0FBRyxLQUFLLENBQUM7QUFFcEMsdUZBQXVGO0FBQ3ZGLE1BQU0sbUJBQW1CLEdBQUcsY0FBYyxHQUFHLENBQUMsQ0FBQztBQUUvQywrRUFBK0U7QUFDL0UsTUFBTSxnQkFBZ0IsR0FBRyxvQ0FBb0MsQ0FBQztBQUU5RDs7Ozs7R0FLRztBQUNILE1BQU0sZ0JBQWdCLEdBQUcsbUVBQW1FLENBQUM7QUFFN0Ysb0ZBQW9GO0FBQ3BGLE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLG1CQUFtQixDQUFDO0FBQzNELGlGQUFpRjtBQUNqRixNQUFNLENBQUMsTUFBTSx3QkFBd0IsR0FBRyxvQkFBb0IsQ0FBQztBQUM3RCx1RkFBdUY7QUFDdkYsTUFBTSxDQUFDLE1BQU0sa0JBQWtCLEdB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cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb3B5IGVhY2ggTWFzdHJhIGNoYXQgdHVybidzIHJlcXVlc3QvcmVzcG9uc2Ugb250byBpdHMgT1RlbCByb290IHNwYW5cbiAqIHNvIERhdGFicmlja3MtbWFuYWdlZCBNTGZsb3cgY2FuIGRpc3BsYXkgdGhlbS5cbiAqXG4gKiBXaHkgdGhpcyBleGlzdHM6IE1MZmxvdydzIFVDIGA8dGFyZ2V0Pl90cmFjZV91bmlmaWVkYCB2aWV3IHBpY2tzIHRoZVxuICogb25lIHNwYW4gd2hvc2UgYHBhcmVudF9zcGFuX2lkYCBpcyBlbXB0eSBhbmQgcmVhZHMgcmVxdWVzdC9yZXNwb25zZVxuICogZnJvbSBgbWxmbG93LnNwYW5JbnB1dHNgIC8gYG1sZmxvdy5zcGFuT3V0cHV0c2AgKG9yIHRoZSBgZ2VuX2FpLipgXG4gKiBlcXVpdmFsZW50cykgb24gVEhBVCBzcGFuIG9ubHkuIE1hc3RyYSByZWNvcmRzIHRoZSB0dXJuIG9uIGl0c1xuICogYGludm9rZV9hZ2VudGAgY2hpbGQgdW5kZXIgYG1hc3RyYS5hZ2VudF9ydW4uaW5wdXRgIC8gYC5vdXRwdXRgLCBrZXlzXG4gKiB0aGUgdmlldyBuZXZlciByZWFkcywgc28gY2hhdCB0cmFjZXMgYXJyaXZlIHdpdGggYm90aCBjb2x1bW5zIG51bGxcbiAqIGV2ZW4gd2hlbiB0aGUgc3BhbnMgdGhlbXNlbHZlcyBsb29rIGhlYWx0aHkuXG4gKlxuICogQXBwS2l0J3MgSFRUUCBpbnN0cnVtZW50YXRpb24gcmVjb3JkcyB0aGUgc2VydmVyIHNwYW4gaW4gT1RlbCBSUEMgbWV0YWRhdGEsXG4gKiB3aGljaCByZW1haW5zIGF2YWlsYWJsZSBldmVuIHdoZW4gRXhwcmVzcyBtYWtlcyBhIG1pZGRsZXdhcmUtbGF5ZXIgY2hpbGRcbiAqIGFjdGl2ZS4gV2hlbiBpbnN0cnVtZW50YXRpb24gaXMgdW5hdmFpbGFibGUsIHRoaXMgbW9kdWxlIGNyZWF0ZXMgb25lXG4gKiByZXF1ZXN0LWxpZmV0aW1lIHNlcnZlciBzcGFuIGFuZCBydW5zIE1hc3RyYSB1bmRlciBpdC5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgU3RyaW5nRGVjb2RlciB9IGZyb20gXCJub2RlOnN0cmluZ19kZWNvZGVyXCI7XG5cbmltcG9ydCB7IGpzb24sIGxvZywgb2JqZWN0LCBzdHJpbmdVdGlscyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgeyBmZWVkYmFjaywgdGhyZWFkIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLW1hc3RyYVwiO1xuaW1wb3J0IHsgY29udGV4dCwgU3BhbktpbmQsIHRyYWNlLCB0eXBlIFNwYW4gfSBmcm9tIFwiQG9wZW50ZWxlbWV0cnkvYXBpXCI7XG5pbXBvcnQgeyBnZXRSUENNZXRhZGF0YSwgUlBDVHlwZSB9IGZyb20gXCJAb3BlbnRlbGVtZXRyeS9jb3JlXCI7XG5pbXBvcnQgdHlwZSBleHByZXNzIGZyb20gXCJleHByZXNzXCI7XG5cbmltcG9ydCB7IFVTRVJfRU1BSUxfSEVBREVSLCBVU0VSX0lEX0hFQURFUiB9IGZyb20gXCIuL2lkZW50aXR5LnRzXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJtYXN0cmEvdGVsZW1ldHJ5XCIpO1xuXG4vKiogQ2FwIG9uIGVhY2ggcGF5bG9hZCBjb3BpZWQgb250byBhIHNwYW4sIHNvIG9uZSB0dXJuIGNhbm5vdCBibG9hdCB0aGUgZXhwb3J0LiAqL1xuZXhwb3J0IGNvbnN0IFRSQUNFX0lPX0xJTUlUID0gOF8wMDA7XG5cbi8qKiBCb3VuZCBmb3IgYSBub24tc3RyZWFtaW5nIGJvZHkgY2FwdHVyZWQgdGhyb3VnaCBgcmVzLmVuZGAgaW5zdGVhZCBvZiBgcmVzLmpzb25gLiAqL1xuY29uc3QgUkVTUE9OU0VfQk9EWV9MSU1JVCA9IFRSQUNFX0lPX0xJTUlUICogNDtcblxuLyoqIFRyYWNlciBzY29wZSB1c2VkIG9ubHkgd2hlbiBBcHBLaXQgZGlkIG5vdCBjcmVhdGUgYSByZWNvcmRpbmcgSFRUUCBzcGFuLiAqL1xuY29uc3QgQ0hBVF9UVVJOX1RSQUNFUiA9IFwiQGRieC10b29scy9hcHBraXQtbWFzdHJhL3RlbGVtZXRyeVwiO1xuXG4vKipcbiAqIE1vdW50LXJlbGF0aXZlIE1hc3RyYSBhZ2VudCBpbnZva2UgcGF0aHMgdGhhdCBjYXJyeSBhIGNoYXQgdHVybiBib2R5XG4gKiAoYG1lc3NhZ2VzYCkgYW5kIHN0cmVhbSBhbiBhc3Npc3RhbnQgYW5zd2VyLiBSZXN1bWUgLyBhcHByb3ZlIHZlcmJzXG4gKiBhcmUgaW50ZW50aW9uYWxseSBleGNsdWRlZDogdGhlaXIgYm9kaWVzIGFyZSB0b29sIGRlY2lzaW9ucywgbm90IHRoZVxuICogdXNlciBwcm9tcHQsIGFuZCB0aGV5IHJhcmVseSBwcm9kdWNlIGEgZnJlc2ggYW5zd2VyIHdvcnRoIHN1cmZhY2luZy5cbiAqL1xuY29uc3QgQUdFTlRfVFVSTl9ST1VURSA9IC9eKD86XFwvYWdlbnRzXFwvW14vXStcXC8oPzpzdHJlYW18Z2VuZXJhdGUpKD86XFwvfCQpfFxcL2NoYXRcXC9bXi9dKyQpL2k7XG5cbi8qKiBBdHRyaWJ1dGUga2V5cyB0aGUgTUxmbG93IFVDIGAqX3RyYWNlX3VuaWZpZWRgIHZpZXcgcmVhZHMgZnJvbSB0aGUgcm9vdCBzcGFuLiAqL1xuZXhwb3J0IGNvbnN0IE1MRkxPV19TUEFOX0lOUFVUU19BVFRSID0gXCJtbGZsb3cuc3BhbklucHV0c1wiO1xuLyoqIFJvb3Qtc3BhbiBhdHRyaWJ1dGUgY29uc3VtZWQgYXMgY2hhdCBvdXRwdXQgYnkgTUxmbG93IHVuaWZpZWQgdHJhY2Ugdmlld3MuICovXG5leHBvcnQgY29uc3QgTUxGTE9XX1NQQU5fT1VUUFVUU19BVFRSID0gXCJtbGZsb3cuc3Bhbk91dHB1dHNcIjtcbi8qKiBGdWxsIHNlcmlhbGl6ZWQgcmVxdWVzdCBtZXNzYWdlcyByZXRhaW5lZCB3aGVuIHRoZSBNTGZsb3cgcHJldmlldyBpcyBwbGFpbiB0ZXh0LiAqL1xuZXhwb3J0IGNvbnN0IENIQVRfTUVTU0FHRVNfQVRUUiA9IFwiYXBwa2l0Lm1hc3RyYS5jaGF0Lm1lc3NhZ2VzXCI7XG4vKiogRnVsbCBzZXJpYWxpemVkIHJlc3BvbnNlIHJldGFpbmVkIHdoZW4gdGhlIE1MZmxvdyBwcmV2aWV3IGlzIHBsYWluIHRleHQuICovXG5leHBvcnQgY29uc3QgQ0hBVF9SRVNQT05TRV9BVFRSID0gXCJhcHBraXQubWFzdHJhLmNoYXQucmVzcG9uc2VcIjtcbi8qKiBDcmVkZW50aWFsIG1vZGUgdXNlZCBieSBEYXRhYnJpY2tzIGNhbGxzIGluIHRoaXMgY2hhdCB0dXJuLiAqL1xuZXhwb3J0IGNvbnN0IENIQVRfSURFTlRJVFlfQVRUUiA9IFwiYXBwa2l0Lm1hc3RyYS5pZGVudGl0eS5tb2RlXCI7XG4vKiogV2hldGhlciB0aGUgc3RyZWFtZWQgdHVybiBlbWl0dGVkIGEgR2VuaWUgdG9vbCBvciBwcm9ncmVzcyBldmVudC4gKi9cbmV4cG9ydCBjb25zdCBDSEFUX0dFTklFX1VTRURfQVRUUiA9IFwiYXBwa2l0Lm1hc3RyYS5nZW5pZS51c2VkXCI7XG4vKipcbiAqIE1MZmxvdyBzcGFuLXR5cGUgYXR0cmlidXRlLiBEYXRhYnJpY2tzIG1hcHMgdGhpcyAob3IgYGdlbl9haS5vcGVyYXRpb24ubmFtZWApXG4gKiBvbnRvIHRoZSB0eXBlIGNoaXAgaW4gdGhlIGV4cGVyaW1lbnQgVUkuIEN1c3RvbSB2YWx1ZXMgc3VjaCBhcyBgR0VOSUVgIGFyZVxuICogYWxsb3dlZC5cbiAqL1xuZXhwb3J0IGNvbnN0IE1MRkxPV19TUEFOX1RZUEVfQVRUUiA9IFwibWxmbG93LnNwYW5UeXBlXCI7XG4vKiogR2VuQUkgc2VtYW50aWMtY29udmVudGlvbiBvcGVyYXRpb24gbmFtZSwgYW4gYWx0ZXJuYXRlIHNwYW4tdHlwZSBzb3VyY2UuICovXG5leHBvcnQgY29uc3QgR0VOX0FJX09QRVJBVElPTl9OQU1FX0FUVFIgPSBcImdlbl9haS5vcGVyYXRpb24ubmFtZVwiO1xuLyoqXG4gKiBSb290LXNwYW4gdXNlciBpZCB0aGUgTUxmbG93IGV4cGVyaW1lbnQgVUkncyBVc2VyIGNvbHVtbiByZWFkcyBmcm9tIE9UZWxcbiAqIHRyYWNlcy4gUHJlZmVyIHRoZSBmb3J3YXJkZWQgZW1haWwgd2hlbiBwcmVzZW50IHNvIHRoZSBjb2x1bW4gaXMgaHVtYW4uXG4gKi9cbmV4cG9ydCBjb25zdCBNTEZMT1dfVVNFUl9BVFRSID0gXCJ1c2VyLmlkXCI7XG4vKiogUm9vdC1zcGFuIHNlc3Npb24gaWQgdGhhdCBlbmFibGVzIHRoZSBNTGZsb3cgU2Vzc2lvbnMgdGFiLiAqL1xuZXhwb3J0IGNvbnN0IE1MRkxPV19TRVNTSU9OX0FUVFIgPSBcInNlc3Npb24uaWRcIjtcbi8qKlxuICogUHJlZml4IERhdGFicmlja3MvTUxmbG93IGNvcGllcyBvbnRvIHRoZSB1bmlmaWVkLXZpZXcgYHRhZ3NgIG1hcC4gVGhlXG4gKiBzdWZmaXggYWZ0ZXIgdGhpcyBwcmVmaXggaXMgdGhlIHRhZyBuYW1lIHNob3duIGluIHRoZSBleHBlcmltZW50IFVJLlxuICovXG5leHBvcnQgY29uc3QgTUxGTE9XX1RSQUNFX1RBR19QUkVGSVggPSBcIm1sZmxvdy50cmFjZS50YWcuXCI7XG4vKiogRXhwZXJpbWVudC1VSSB0YWcgbWFya2luZyBhIHR1cm4gdGhhdCBjYWxsZWQgR2VuaWUuICovXG5leHBvcnQgY29uc3QgTUxGTE9XX0dFTklFX1RBRyA9IFwiZ2VuaWVcIjtcbi8qKiBSb290LXNwYW4gdHlwZSBmb3IgYSBNYXN0cmEgYWdlbnQgdHVybi4gKi9cbmV4cG9ydCBjb25zdCBNTEZMT1dfU1BBTl9UWVBFX0FHRU5UID0gXCJBR0VOVFwiO1xuLyoqIFNwYW4gdHlwZSBmb3IgYW4gYGFza19nZW5pZWAgdG9vbCBjYWxsLiAqL1xuZXhwb3J0IGNvbnN0IE1MRkxPV19TUEFOX1RZUEVfR0VOSUUgPSBcIkdFTklFXCI7XG4vKiogQXR0cmlidXRlIGtleSBmb3IgdGhlIGBnZW5pZWAgdHJhY2UgdGFnLiAqL1xuZXhwb3J0IGNvbnN0IE1MRkxPV19HRU5JRV9UQUdfQVRUUiA9IGAke01MRkxPV19UUkFDRV9UQUdfUFJFRklYfSR7TUxGTE9XX0dFTklFX1RBR31gO1xuXG4vKiogUm9vdC1zcGFuIG1ldGFkYXRhIGtub3duIGJlZm9yZSBhIGNoYXQgcmVxdWVzdCBpcyBkaXNwYXRjaGVkLiAqL1xuZXhwb3J0IGludGVyZmFjZSBDaGF0VHVyblRlbGVtZXRyeU9wdGlvbnMge1xuICByZWFkb25seSBpZGVudGl0eT86XG4gICAgXCJvYm9cIiB8IFwic2VydmljZS1wcmluY2lwYWxcIiB8ICgocmVxdWVzdDogZXhwcmVzcy5SZXF1ZXN0KSA9PiBcIm9ib1wiIHwgXCJzZXJ2aWNlLXByaW5jaXBhbFwiKTtcbn1cblxuaW50ZXJmYWNlIFRyYWNlVGFyZ2V0IHtcbiAgc3BhbjogU3BhbjtcbiAgb3duZWQ6IGJvb2xlYW47XG59XG5cbi8qKiBPcGVuVGVsZW1ldHJ5J3Mgc2VudGluZWwgZm9yIFwibm8gdmFsaWQgdHJhY2VcIiAtIDMyIHplcm8gaGV4IGNoYXJzLiAqL1xuY29uc3QgSU5WQUxJRF9UUkFDRV9JRCA9IFwiMFwiLnJlcGVhdCgzMik7XG5cbi8qKlxuICogUHVibGlzaCB0aGUgdHVybidzIE1MZmxvdyB0cmFjZSBpZCBiZWZvcmUgdGhlIGhhbmRsZXIgd3JpdGVzIHRoZSBib2R5LlxuICpcbiAqIFRoZSBjaGF0IFVJIG9ubHkgc2hvd3MgdGh1bWJzIHdoZW4gdGhpcyBoZWFkZXIgaXMgcHJlc2VudC4gU3RhbXBpbmcgaXQgaGVyZVxuICogKG9uIHRoZSBzYW1lIHNwYW4gdGhlIG1pZGRsZXdhcmUganVzdCByZXNvbHZlZCkgYXZvaWRzIHJlbHlpbmcgb24gYXN5bmNcbiAqIEV4cHJlc3MgY29udGludWF0aW9uIHN0aWxsIHNpdHRpbmcgaW5zaWRlIGBjb250ZXh0LndpdGgoKWAuXG4gKi9cbi8qKlxuICogTWFyayB0aGUgYWN0aXZlIHNwYW4gYXMgYSBHZW5pZSBjYWxsIHNvIHRoZSBleHBlcmltZW50IFVJIHR5cGVzIGl0IGBHRU5JRWBcbiAqIGFuZCB0YWdzIHRoZSB0cmFjZSBgZ2VuaWU9dHJ1ZWAuIFNhZmUgbm8tb3Agd2hlbiBubyByZWNvcmRpbmcgc3BhbiBpcyBhY3RpdmUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdGFtcEdlbmllVG9vbFNwYW4oc3BhbjogU3BhbiB8IHVuZGVmaW5lZCA9IHRyYWNlLmdldEFjdGl2ZVNwYW4oKSk6IHZvaWQge1xuICBpZiAoIXNwYW4/LmlzUmVjb3JkaW5nKCkpIHJldHVybjtcbiAgc3Bhbi5zZXRBdHRyaWJ1dGUoTUxGTE9XX1NQQU5fVFlQRV9BVFRSLCBNTEZMT1dfU1BBTl9UWVBFX0dFTklFKTtcbiAgc3Bhbi5zZXRBdHRyaWJ1dGUoR0VOX0FJX09QRVJBVElPTl9OQU1FX0FUVFIsIFwiZXhlY3V0ZV90b29sXCIpO1xuICBzcGFuLnNldEF0dHJpYnV0ZShNTEZMT1dfR0VOSUVfVEFHX0FUVFIsIFwidHJ1ZVwiKTtcbn1cblxuZnVuY3Rpb24gcmVxdWVzdEhlYWRlcihyZXE6IGV4cHJlc3MuUmVxdWVzdCwgbmFtZTogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgZnJvbU1ldGhvZCA9XG4gICAgdHlwZW9mIHJlcS5oZWFkZXIgPT09IFwiZnVuY3Rpb25cIiA/IHN0cmluZ1V0aWxzLnRyaW1Ub051bGwocmVxLmhlYWRlcihuYW1lKSkgOiB1bmRlZmluZWQ7XG4gIGlmIChmcm9tTWV0aG9kKSByZXR1cm4gZnJvbU1ldGhvZDtcbiAgY29uc3QgcmF3ID0gcmVxLmhlYWRlcnM/LltuYW1lLnRvTG93ZXJDYXNlKCldO1xuICBjb25zdCB2YWx1ZSA9IEFycmF5LmlzQXJyYXkocmF3KSA/IHJhd1swXSA6IHJhdztcbiAgcmV0dXJuIHN0cmluZ1V0aWxzLnRyaW1Ub051bGwodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiID8gdmFsdWUgOiB1bmRlZmluZWQpID8/IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gcmVxdWVzdFF1ZXJ5KHJlcTogZXhwcmVzcy5SZXF1ZXN0LCBuYW1lOiBzdHJpbmcpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCByYXcgPSByZXEucXVlcnk/LltuYW1lXTtcbiAgY29uc3QgdmFsdWUgPSBBcnJheS5pc0FycmF5KHJhdykgPyByYXdbMF0gOiByYXc7XG4gIHJldHVybiBzdHJpbmdVdGlscy50cmltVG9OdWxsKHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiA/IHZhbHVlIDogdW5kZWZpbmVkKSA/PyB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIHN0YW1wTWxmbG93QWN0b3Ioc3BhbjogU3BhbiwgcmVxOiBleHByZXNzLlJlcXVlc3QpOiB2b2lkIHtcbiAgY29uc3QgdXNlciA9IHJlcXVlc3RIZWFkZXIocmVxLCBVU0VSX0VNQUlMX0hFQURFUikgPz8gcmVxdWVzdEhlYWRlcihyZXEsIFVTRVJfSURfSEVBREVSKTtcbiAgaWYgKHVzZXIpIHNwYW4uc2V0QXR0cmlidXRlKE1MRkxPV19VU0VSX0FUVFIsIHVzZXIpO1xuICBjb25zdCBzZXNzaW9uID1cbiAgICByZXF1ZXN0SGVhZGVyKHJlcSwgdGhyZWFkLlRIUkVBRF9JRF9IRUFERVIpID8/IHJlcXVlc3RRdWVyeShyZXEsIHRocmVhZC5USFJFQURfSURfUVVFUlkpO1xuICBpZiAoc2Vzc2lvbikgc3Bhbi5zZXRBdHRyaWJ1dGUoTUxGTE9XX1NFU1NJT05fQVRUUiwgc2Vzc2lvbik7XG59XG5cbmZ1bmN0aW9uIHN0YW1wTWxmbG93VHJhY2VJZChyZXM6IGV4cHJlc3MuUmVzcG9uc2UsIHNwYW46IFNwYW4pOiB2b2lkIHtcbiAgaWYgKHJlcy5oZWFkZXJzU2VudCkgcmV0dXJuO1xuICBjb25zdCB0cmFjZUlkID0gc3Bhbi5zcGFuQ29udGV4dCgpLnRyYWNlSWQ7XG4gIGlmICghdHJhY2VJZCB8fCB0cmFjZUlkID09PSBJTlZBTElEX1RSQUNFX0lEKSByZXR1cm47XG4gIHJlcy5zZXRIZWFkZXIoZmVlZGJhY2suTUxGTE9XX1RSQUNFX0lEX0hFQURFUiwgYHRyLSR7dHJhY2VJZH1gKTtcbn1cblxuLyoqIFJldHVybiBvbmUgcmF3IHByb21wdCB3aGVuIHRoZSByZXF1ZXN0IGlzIGV4YWN0bHkgb25lIHRleHQtb25seSB1c2VyIG1lc3NhZ2UuICovXG5leHBvcnQgZnVuY3Rpb24gdGV4dE9ubHlDaGF0SW5wdXQobWVzc2FnZXM6IHVua25vd24pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBpZiAodHlwZW9mIG1lc3NhZ2VzID09PSBcInN0cmluZ1wiKSByZXR1cm4gbWVzc2FnZXMgfHwgdW5kZWZpbmVkO1xuICBpZiAoIUFycmF5LmlzQXJyYXkobWVzc2FnZXMpIHx8IG1lc3NhZ2VzLmxlbmd0aCAhPT0gMSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3QgbWVzc2FnZSA9IG1lc3NhZ2VzWzBdO1xuICBpZiAoIW9iamVjdC5pc1JlY29yZChtZXNzYWdlKSB8fCBtZXNzYWdlLnJvbGUgIT09IFwidXNlclwiKSByZXR1cm4gdW5kZWZpbmVkO1xuICBpZiAodHlwZW9mIG1lc3NhZ2UuY29udGVudCA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIG1lc3NhZ2UuY29udGVudCB8fCB1bmRlZmluZWQ7XG4gIHJldHVybiB0ZXh0RnJvbVBhcnRzKG1lc3NhZ2UucGFydHMpID8/IHRleHRGcm9tUGFydHMobWVzc2FnZS5jb250ZW50KTtcbn1cblxuZnVuY3Rpb24gdGV4dEZyb21QYXJ0cyh2YWx1ZTogdW5rbm93bik6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmICghQXJyYXkuaXNBcnJheSh2YWx1ZSkgfHwgdmFsdWUubGVuZ3RoID09PSAwKSByZXR1cm4gdW5kZWZpbmVkO1xuICBjb25zdCB0ZXh0OiBzdHJpbmdbXSA9IFtdO1xuICBmb3IgKGNvbnN0IHBhcnQgb2YgdmFsdWUpIHtcbiAgICBpZiAoIW9iamVjdC5pc1JlY29yZChwYXJ0KSB8fCBwYXJ0LnR5cGUgIT09IFwidGV4dFwiIHx8IHR5cGVvZiBwYXJ0LnRleHQgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHRleHQucHVzaChwYXJ0LnRleHQpO1xuICB9XG4gIGNvbnN0IGpvaW5lZCA9IHRleHQuam9pbihcIlwiKTtcbiAgcmV0dXJuIGpvaW5lZCB8fCB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIHNlcmlhbGl6ZWQodmFsdWU6IHVua25vd24sIGxpbWl0ID0gVFJBQ0VfSU9fTElNSVQpOiBzdHJpbmcge1xuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodmFsdWUpPy5zbGljZSgwLCBsaW1pdCkgPz8gU3RyaW5nKHZhbHVlKS5zbGljZSgwLCBsaW1pdCk7XG59XG5cbmZ1bmN0aW9uIHNzZUZyYW1lKGxpbmU6IHN0cmluZyk6IHVua25vd24ge1xuICBpZiAoIWxpbmUuc3RhcnRzV2l0aChcImRhdGE6XCIpKSByZXR1cm4gdW5kZWZpbmVkO1xuICByZXR1cm4ganNvbi5wYXJzZShsaW5lLnNsaWNlKDUpKTtcbn1cblxuZnVuY3Rpb24gdmFsdWVVc2VzR2VuaWUodmFsdWU6IHVua25vd24sIGRlcHRoID0gMCk6IGJvb2xlYW4ge1xuICBpZiAoZGVwdGggPiAzKSByZXR1cm4gZmFsc2U7XG4gIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkgcmV0dXJuIHZhbHVlLnNvbWUoKGl0ZW0pID0+IHZhbHVlVXNlc0dlbmllKGl0ZW0sIGRlcHRoICsgMSkpO1xuICBpZiAoIW9iamVjdC5pc1JlY29yZCh2YWx1ZSkpIHJldHVybiBmYWxzZTtcbiAgaWYgKFxuICAgIHZhbHVlLnR5cGUgPT09IFwiZGF0YS1nZW5pZS1wcm9ncmVzc1wiIHx8XG4gICAgdmFsdWUudHlwZSA9PT0gXCJhc2tfZ2VuaWVfZG9uZVwiIHx8XG4gICAgdmFsdWUudG9vbE5hbWUgPT09IFwiYXNrX2dlbmllXCIgfHxcbiAgICB2YWx1ZS50b29sX25hbWUgPT09IFwiYXNrX2dlbmllXCIgfHxcbiAgICB2YWx1ZS5uYW1lID09PSBcImFza19nZW5pZVwiXG4gICkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBbXCJkYXRhXCIsIFwiZXZlbnRcIiwgXCJwYXlsb2FkXCJdLnNvbWUoKGtleSkgPT4gdmFsdWVVc2VzR2VuaWUodmFsdWVba2V5XSwgZGVwdGggKyAxKSk7XG59XG5cbi8qKiBSZXR1cm4gdGhlIGFzc2lzdGFudCB0ZXh0IGZyb20gb25lIFNTRSBsaW5lLCBvciBhbiBlbXB0eSBzdHJpbmcuICovXG5mdW5jdGlvbiBhc3Npc3RhbnRUZXh0RnJvbVNzZUxpbmUobGluZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGFzc2lzdGFudFRleHRGcm9tU3NlRnJhbWUoc3NlRnJhbWUobGluZSkpO1xufVxuXG5mdW5jdGlvbiBhc3Npc3RhbnRUZXh0RnJvbVNzZUZyYW1lKGZyYW1lOiB1bmtub3duKTogc3RyaW5nIHtcbiAgaWYgKCFvYmplY3QuaXNSZWNvcmQoZnJhbWUpIHx8IGZyYW1lLnR5cGUgIT09IFwidGV4dC1kZWx0YVwiKSByZXR1cm4gXCJcIjtcbiAgY29uc3QgdGV4dCA9XG4gICAgdHlwZW9mIGZyYW1lLmRlbHRhID09PSBcInN0cmluZ1wiXG4gICAgICA/IGZyYW1lLmRlbHRhXG4gICAgICA6IG9iamVjdC5pc1JlY29yZChmcmFtZS5wYXlsb2FkKVxuICAgICAgICA/IGZyYW1lLnBheWxvYWQudGV4dFxuICAgICAgICA6IHVuZGVmaW5lZDtcbiAgcmV0dXJuIHR5cGVvZiB0ZXh0ID09PSBcInN0cmluZ1wiID8gdGV4dCA6IFwiXCI7XG59XG5cbi8qKlxuICogQ29uY2F0ZW5hdGUgdGhlIGFzc2lzdGFudCdzIGFuc3dlciBvdXQgb2YgYW4gQUkgU0RLIFNTRSB0cmFuc2NyaXB0LlxuICpcbiAqIFRoZSBhZ2VudCBzdHJlYW1zIGl0cyByZXBseSBhcyBgdGV4dC1kZWx0YWAgZnJhbWVzXG4gKiAoYGRhdGE6IHtcInR5cGVcIjpcInRleHQtZGVsdGFcIixcInBheWxvYWRcIjp7XCJ0ZXh0XCI6XCIuLi5cIn19YCksIHNvIHRoZSBmdWxsXG4gKiBhbnN3ZXIgb25seSBldmVyIGV4aXN0cyBhcyBkZWx0YXMgb24gdGhlIHdpcmUgYW5kIGhhcyB0byBiZVxuICogcmVhc3NlbWJsZWQgaGVyZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFzc2lzdGFudFRleHRGcm9tU3NlKGJvZHk6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHBhcnRzOiBzdHJpbmdbXSA9IFtdO1xuICBmb3IgKGNvbnN0IGxpbmUgb2YgYm9keS5zcGxpdChcIlxcblwiKSkge1xuICAgIGNvbnN0IHRleHQgPSBhc3Npc3RhbnRUZXh0RnJvbVNzZUxpbmUobGluZSk7XG4gICAgaWYgKHRleHQpIHBhcnRzLnB1c2godGV4dCk7XG4gIH1cbiAgcmV0dXJuIHBhcnRzLmpvaW4oXCJcIikuc2xpY2UoMCwgVFJBQ0VfSU9fTElNSVQpO1xufVxuXG4vKiogUmVhZCB0aGUgZmluYWwgYXNzaXN0YW50IHRleHQgZnJvbSBhIG5vbi1zdHJlYW1pbmcgTWFzdHJhIHJlc3BvbnNlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFzc2lzdGFudFRleHRGcm9tSnNvbihib2R5OiB1bmtub3duKTogc3RyaW5nIHtcbiAgaWYgKCFvYmplY3QuaXNSZWNvcmQoYm9keSkgfHwgdHlwZW9mIGJvZHkudGV4dCAhPT0gXCJzdHJpbmdcIikgcmV0dXJuIFwiXCI7XG4gIHJldHVybiBib2R5LnRleHQuc2xpY2UoMCwgVFJBQ0VfSU9fTElNSVQpO1xufVxuXG4vKiogSW5jcmVtZW50YWxseSBhc3NlbWJsZSBVVEYtOCBTU0UgdGV4dCB3aGlsZSByZXRhaW5pbmcgYSBib3VuZGVkIEpTT04gZmFsbGJhY2suICovXG5jbGFzcyBBc3Npc3RhbnRSZXNwb25zZUNvbGxlY3RvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgZGVjb2RlciA9IG5ldyBTdHJpbmdEZWNvZGVyKFwidXRmOFwiKTtcbiAgcHJpdmF0ZSBhbnN3ZXIgPSBcIlwiO1xuICBwcml2YXRlIGJvZHkgPSBcIlwiO1xuICBwcml2YXRlIHBlbmRpbmdMaW5lID0gXCJcIjtcbiAgcHJpdmF0ZSBmaW5pc2hlZCA9IGZhbHNlO1xuICBwcml2YXRlIGdlbmllID0gZmFsc2U7XG5cbiAgd3JpdGUoY2h1bms6IHVua25vd24pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5maW5pc2hlZCkgcmV0dXJuO1xuICAgIGlmICh0eXBlb2YgY2h1bmsgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIHRoaXMuY29uc3VtZShjaHVuayk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChBcnJheUJ1ZmZlci5pc1ZpZXcoY2h1bmspKSB7XG4gICAgICB0aGlzLmNvbnN1bWUoXG4gICAgICAgIHRoaXMuZGVjb2Rlci53cml0ZShCdWZmZXIuZnJvbShjaHVuay5idWZmZXIsIGNodW5rLmJ5dGVPZmZzZXQsIGNodW5rLmJ5dGVMZW5ndGgpKSxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgZmluaXNoKCk6IHN0cmluZyB7XG4gICAgaWYgKHRoaXMuZmluaXNoZWQpIHJldHVybiB0aGlzLmFuc3dlciB8fCB0aGlzLmpzb25BbnN3ZXIoKTtcbiAgICB0aGlzLmZpbmlzaGVkID0gdHJ1ZTtcbiAgICB0aGlzLmNvbnN1bWUodGhpcy5kZWNvZGVyLmVuZCgpKTtcbiAgICB0aGlzLmNvbnN1bWVTc2VMaW5lKHRoaXMucGVuZGluZ0xpbmUpO1xuICAgIHRoaXMucGVuZGluZ0xpbmUgPSBcIlwiO1xuICAgIHJldHVybiB0aGlzLmFuc3dlciB8fCB0aGlzLmpzb25BbnN3ZXIoKTtcbiAgfVxuXG4gIHJhd0JvZHkoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5ib2R5LnNsaWNlKDAsIFRSQUNFX0lPX0xJTUlUKTtcbiAgfVxuXG4gIHVzZWRHZW5pZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5nZW5pZTtcbiAgfVxuXG4gIHByaXZhdGUgY29uc3VtZSh0ZXh0OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAoIXRleHQpIHJldHVybjtcbiAgICBpZiAodGhpcy5ib2R5Lmxlbmd0aCA8IFJFU1BPTlNFX0JPRFlfTElNSVQpIHtcbiAgICAgIHRoaXMuYm9keSArPSB0ZXh0LnNsaWNlKDAsIFJFU1BPTlNFX0JPRFlfTElNSVQgLSB0aGlzLmJvZHkubGVuZ3RoKTtcbiAgICB9XG4gICAgdGhpcy5wZW5kaW5nTGluZSArPSB0ZXh0O1xuICAgIGxldCBuZXdsaW5lID0gdGhpcy5wZW5kaW5nTGluZS5pbmRleE9mKFwiXFxuXCIpO1xuICAgIHdoaWxlIChuZXdsaW5lID49IDApIHtcbiAgICAgIHRoaXMuY29uc3VtZVNzZUxpbmUodGhpcy5wZW5kaW5nTGluZS5zbGljZSgwLCBuZXdsaW5lKS5yZXBsYWNlKC9cXHIkLywgXCJcIikpO1xuICAgICAgdGhpcy5wZW5kaW5nTGluZSA9IHRoaXMucGVuZGluZ0xpbmUuc2xpY2UobmV3bGluZSArIDEpO1xuICAgICAgbmV3bGluZSA9IHRoaXMucGVuZGluZ0xpbmUuaW5kZXhPZihcIlxcblwiKTtcbiAgICB9XG4gICAgaWYgKHRoaXMucGVuZGluZ0xpbmUubGVuZ3RoID4gUkVTUE9OU0VfQk9EWV9MSU1JVCkge1xuICAgICAgdGhpcy5wZW5kaW5nTGluZSA9IHRoaXMucGVuZGluZ0xpbmUuc2xpY2UoLVJFU1BPTlNFX0JPRFlfTElNSVQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY29uc3VtZVNzZUxpbmUobGluZTogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgZnJhbWUgPSBzc2VGcmFtZShsaW5lKTtcbiAgICB0aGlzLmdlbmllIHx8PSB2YWx1ZVVzZXNHZW5pZShmcmFtZSk7XG4gICAgaWYgKHRoaXMuYW5zd2VyLmxlbmd0aCA+PSBUUkFDRV9JT19MSU1JVCkgcmV0dXJuO1xuICAgIGNvbnN0IHRleHQgPSBhc3Npc3RhbnRUZXh0RnJvbVNzZUZyYW1lKGZyYW1lKTtcbiAgICB0aGlzLmFuc3dlciArPSB0ZXh0LnNsaWNlKDAsIFRSQUNFX0lPX0xJTUlUIC0gdGhpcy5hbnN3ZXIubGVuZ3RoKTtcbiAgfVxuXG4gIHByaXZhdGUganNvbkFuc3dlcigpOiBzdHJpbmcge1xuICAgIHJldHVybiBhc3Npc3RhbnRUZXh0RnJvbUpzb24oanNvbi5wYXJzZSh0aGlzLmJvZHkpKTtcbiAgfVxufVxuXG4vKipcbiAqIFNlbGVjdCB0aGUgc3BhbiBNTGZsb3cgdHJlYXRzIGFzIHRoZSByZXF1ZXN0IHJvb3QuXG4gKlxuICogT1RlbCBIVFRQIGluc3RydW1lbnRhdGlvbiBzdG9yZXMgaXRzIHNlcnZlciBzcGFuIGluIFJQQyBtZXRhZGF0YS4gVGhhdCBzcGFuXG4gKiB3aW5zIG92ZXIgYW4gYWN0aXZlIEV4cHJlc3MgY2hpbGQuIElmIG5vIHJlY29yZGluZyBsb2NhbCBzcGFuIGV4aXN0cywgY3JlYXRlXG4gKiBvbmUgdW5kZXIgdGhlIGN1cnJlbnQgY29udGV4dCBzbyBlbmFibGVkIFczQyBwcm9wYWdhdGlvbiByZW1haW5zIGludGFjdC5cbiAqL1xuZnVuY3Rpb24gcmVzb2x2ZVRyYWNlVGFyZ2V0KCk6IFRyYWNlVGFyZ2V0IHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgYWN0aXZlQ29udGV4dCA9IGNvbnRleHQuYWN0aXZlKCk7XG4gIGNvbnN0IHJwYyA9IGdldFJQQ01ldGFkYXRhKGFjdGl2ZUNvbnRleHQpO1xuICBpZiAocnBjPy50eXBlID09PSBSUENUeXBlLkhUVFAgJiYgcnBjLnNwYW4uaXNSZWNvcmRpbmcoKSkge1xuICAgIHJldHVybiB7IHNwYW46IHJwYy5zcGFuLCBvd25lZDogZmFsc2UgfTtcbiAgfVxuXG4gIGNvbnN0IGFjdGl2ZSA9IHRyYWNlLmdldEFjdGl2ZVNwYW4oKTtcbiAgaWYgKGFjdGl2ZT8uaXNSZWNvcmRpbmcoKSkgcmV0dXJuIHsgc3BhbjogYWN0aXZlLCBvd25lZDogZmFsc2UgfTtcblxuICBjb25zdCBzcGFuID0gdHJhY2VcbiAgICAuZ2V0VHJhY2VyKENIQVRfVFVSTl9UUkFDRVIpXG4gICAgLnN0YXJ0U3BhbihcIm1hc3RyYS5jaGF0X3R1cm5cIiwgeyBraW5kOiBTcGFuS2luZC5TRVJWRVIgfSwgYWN0aXZlQ29udGV4dCk7XG4gIGlmICghc3Bhbi5pc1JlY29yZGluZygpKSB7XG4gICAgc3Bhbi5lbmQoKTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIHJldHVybiB7IHNwYW4sIG93bmVkOiB0cnVlIH07XG59XG5cbi8qKlxuICogRXhwcmVzcyBtaWRkbGV3YXJlIHRoYXQgc3RhbXBzIGNoYXQgdHVybiBJL08gb250byB0aGUgZXhwb3J0ZWQgT1RlbCByb290LlxuICpcbiAqIFRlZSBgcmVzLndyaXRlYCwgYHJlcy5qc29uYCwgYW5kIGByZXMuZW5kYCBpbnN0ZWFkIG9mIGxpc3RlbmluZyBmb3IgYGZpbmlzaGA6XG4gKiBIVFRQIGluc3RydW1lbnRhdGlvbiBlbmRzIGl0cyBzZXJ2ZXIgc3BhbiBvbiBmaW5pc2gsIGFuZCBhdHRyaWJ1dGVzIHNldFxuICogYWZ0ZXIgYSBzcGFuIGVuZHMgbmV2ZXIgcmVhY2ggdGhlIGV4cG9ydGVyLlxuICpcbiAqIGBwYXRoYCBpcyBtb3VudC1yZWxhdGl2ZSAod2hhdCB0aGUgTWFzdHJhIHN1Yi1hcHAgc2VlcyksIGUuZy5cbiAqIGAvYWdlbnRzL3N1cHBvcnQvc3RyZWFtYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNoYXRUdXJuVGVsZW1ldHJ5TWlkZGxld2FyZShcbiAgcmVxOiBleHByZXNzLlJlcXVlc3QsXG4gIHJlczogZXhwcmVzcy5SZXNwb25zZSxcbiAgbmV4dDogZXhwcmVzcy5OZXh0RnVuY3Rpb24sXG4gIG9wdGlvbnM6IENoYXRUdXJuVGVsZW1ldHJ5T3B0aW9ucyA9IHt9LFxuKTogdm9pZCB7XG4gIGlmIChyZXEubWV0aG9kICE9PSBcIlBPU1RcIiB8fCAhQUdFTlRfVFVSTl9ST1VURS50ZXN0KHJlcS5wYXRoKSkge1xuICAgIG5leHQoKTtcbiAgICByZXR1cm47XG4gIH1cbiAgY29uc3QgdGFyZ2V0ID0gcmVzb2x2ZVRyYWNlVGFyZ2V0KCk7XG4gIGlmICghdGFyZ2V0KSB7XG4gICAgbmV4dCgpO1xuICAgIHJldHVybjtcbiAgfVxuICBzdGFtcE1sZmxvd1RyYWNlSWQocmVzLCB0YXJnZXQuc3Bhbik7XG4gIHN0YW1wTWxmbG93QWN0b3IodGFyZ2V0LnNwYW4sIHJlcSk7XG4gIHRhcmdldC5zcGFuLnNldEF0dHJpYnV0ZShNTEZMT1dfU1BBTl9UWVBFX0FUVFIsIE1MRkxPV19TUEFOX1RZUEVfQUdFTlQpO1xuICB0YXJnZXQuc3Bhbi5zZXRBdHRyaWJ1dGUoR0VOX0FJX09QRVJBVElPTl9OQU1FX0FUVFIsIFwiaW52b2tlX2FnZW50XCIpO1xuICBjb25zdCBpZGVudGl0eSA9XG4gICAgdHlwZW9mIG9wdGlvbnMuaWRlbnRpdHkgPT09IFwiZnVuY3Rpb25cIiA/IG9wdGlvbnMuaWRlbnRpdHkocmVxKSA6IG9wdGlvbnMuaWRlbnRpdHk7XG4gIGlmIChpZGVudGl0eSkge1xuICAgIHRhcmdldC5zcGFuLnNldEF0dHJpYnV0ZShDSEFUX0lERU5USVRZX0FUVFIsIGlkZW50aXR5KTtcbiAgfVxuICB0YXJnZXQuc3Bhbi5zZXRBdHRyaWJ1dGUoQ0hBVF9HRU5JRV9VU0VEX0FUVFIsIGZhbHNlKTtcblxuICBjb25zdCBtZXNzYWdlcyA9IChyZXEuYm9keSBhcyB7IG1lc3NhZ2VzPzogdW5rbm93biB9IHwgdW5kZWZpbmVkKT8ubWVzc2FnZXM7XG4gIGlmIChtZXNzYWdlcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgY29uc3QgZnVsbElucHV0ID0gc2VyaWFsaXplZChtZXNzYWdlcyk7XG4gICAgdGFyZ2V0LnNwYW4uc2V0QXR0cmlidXRlKENIQVRfTUVTU0FHRVNfQVRUUiwgZnVsbElucHV0KTtcbiAgICB0YXJnZXQuc3Bhbi5zZXRBdHRyaWJ1dGUoXG4gICAgICBNTEZMT1dfU1BBTl9JTlBVVFNfQVRUUixcbiAgICAgICh0ZXh0T25seUNoYXRJbnB1dChtZXNzYWdlcykgPz8gZnVsbElucHV0KS5zbGljZSgwLCBUUkFDRV9JT19MSU1JVCksXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IGNvbGxlY3RvciA9IG5ldyBBc3Npc3RhbnRSZXNwb25zZUNvbGxlY3RvcigpO1xuICBsZXQgb3V0cHV0UmVjb3JkZWQgPSBmYWxzZTtcbiAgbGV0IGZ1bGxPdXRwdXRSZWNvcmRlZCA9IGZhbHNlO1xuICBsZXQgb3duZWRTcGFuRW5kZWQgPSBmYWxzZTtcbiAgY29uc3QgcGFzc1Rocm91Z2hXcml0ZSA9IHJlcy53cml0ZS5iaW5kKHJlcykgYXMgKC4uLmFyZ3M6IHVua25vd25bXSkgPT4gYm9vbGVhbjtcbiAgY29uc3QgcGFzc1Rocm91Z2hFbmQgPSByZXMuZW5kLmJpbmQocmVzKSBhcyAoLi4uYXJnczogdW5rbm93bltdKSA9PiB1bmtub3duO1xuICBjb25zdCBwYXNzVGhyb3VnaEpzb24gPSByZXMuanNvbi5iaW5kKHJlcykgYXMgKGJvZHk/OiB1bmtub3duKSA9PiBleHByZXNzLlJlc3BvbnNlO1xuICBjb25zdCByZWNvcmRPdXRwdXQgPSAoYW5zd2VyOiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgICBpZiAob3V0cHV0UmVjb3JkZWQgfHwgIWFuc3dlcikgcmV0dXJuO1xuICAgIHRhcmdldC5zcGFuLnNldEF0dHJpYnV0ZShNTEZMT1dfU1BBTl9PVVRQVVRTX0FUVFIsIGFuc3dlci5zbGljZSgwLCBUUkFDRV9JT19MSU1JVCkpO1xuICAgIG91dHB1dFJlY29yZGVkID0gdHJ1ZTtcbiAgfTtcbiAgY29uc3QgcmVjb3JkRnVsbE91dHB1dCA9IChyZXNwb25zZTogc3RyaW5nKTogdm9pZCA9PiB7XG4gICAgaWYgKGZ1bGxPdXRwdXRSZWNvcmRlZCB8fCAhcmVzcG9uc2UpIHJldHVybjtcbiAgICB0YXJnZXQuc3Bhbi5zZXRBdHRyaWJ1dGUoQ0hBVF9SRVNQT05TRV9BVFRSLCByZXNwb25zZS5zbGljZSgwLCBUUkFDRV9JT19MSU1JVCkpO1xuICAgIGZ1bGxPdXRwdXRSZWNvcmRlZCA9IHRydWU7XG4gIH07XG4gIGNvbnN0IHJlY29yZEdlbmllID0gKHVzZWQ6IGJvb2xlYW4pOiB2b2lkID0+IHtcbiAgICBpZiAoIXVzZWQpIHJldHVybjtcbiAgICB0YXJnZXQuc3Bhbi5zZXRBdHRyaWJ1dGUoQ0hBVF9HRU5JRV9VU0VEX0FUVFIsIHRydWUpO1xuICAgIHRhcmdldC5zcGFuLnNldEF0dHJpYnV0ZShNTEZMT1dfR0VOSUVfVEFHX0FUVFIsIFwidHJ1ZVwiKTtcbiAgfTtcbiAgY29uc3QgZW5kT3duZWRTcGFuID0gKCk6IHZvaWQgPT4ge1xuICAgIGlmICghdGFyZ2V0Lm93bmVkIHx8IG93bmVkU3BhbkVuZGVkKSByZXR1cm47XG4gICAgb3duZWRTcGFuRW5kZWQgPSB0cnVlO1xuICAgIHRhcmdldC5zcGFuLmVuZCgpO1xuICB9O1xuXG4gIHJlcy53cml0ZSA9ICgoY2h1bms6IHVua25vd24sIC4uLnJlc3Q6IHVua25vd25bXSkgPT4ge1xuICAgIGNvbGxlY3Rvci53cml0ZShjaHVuayk7XG4gICAgcmV0dXJuIHBhc3NUaHJvdWdoV3JpdGUoY2h1bmssIC4uLnJlc3QpO1xuICB9KSBhcyB0eXBlb2YgcmVzLndyaXRlO1xuXG4gIHJlcy5qc29uID0gKChib2R5PzogdW5rbm93bikgPT4ge1xuICAgIHJlY29yZEZ1bGxPdXRwdXQoc2VyaWFsaXplZChib2R5KSk7XG4gICAgcmVjb3JkR2VuaWUodmFsdWVVc2VzR2VuaWUoYm9keSkpO1xuICAgIHJlY29yZE91dHB1dChhc3Npc3RhbnRUZXh0RnJvbUpzb24oYm9keSkpO1xuICAgIHJldHVybiBwYXNzVGhyb3VnaEpzb24oYm9keSk7XG4gIH0pIGFzIHR5cGVvZiByZXMuanNvbjtcblxuICByZXMuZW5kID0gKChjaHVuaz86IHVua25vd24sIC4uLnJlc3Q6IHVua25vd25bXSkgPT4ge1xuICAgIGNvbGxlY3Rvci53cml0ZShjaHVuayk7XG4gICAgcmVjb3JkT3V0cHV0KGNvbGxlY3Rvci5maW5pc2goKSk7XG4gICAgcmVjb3JkRnVsbE91dHB1dChjb2xsZWN0b3IucmF3Qm9keSgpKTtcbiAgICByZWNvcmRHZW5pZShjb2xsZWN0b3IudXNlZEdlbmllKCkpO1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gcGFzc1Rocm91Z2hFbmQoY2h1bmssIC4uLnJlc3QpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBlbmRPd25lZFNwYW4oKTtcbiAgICB9XG4gIH0pIGFzIHR5cGVvZiByZXMuZW5kO1xuXG4gIHJlcy5vbmNlKFwiY2xvc2VcIiwgKCkgPT4ge1xuICAgIHJlY29yZE91dHB1dChjb2xsZWN0b3IuZmluaXNoKCkpO1xuICAgIHJlY29yZEZ1bGxPdXRwdXQoY29sbGVjdG9yLnJhd0JvZHkoKSk7XG4gICAgcmVjb3JkR2VuaWUoY29sbGVjdG9yLnVzZWRHZW5pZSgpKTtcbiAgICBlbmRPd25lZFNwYW4oKTtcbiAgfSk7XG5cbiAgY29udGV4dC53aXRoKHRyYWNlLnNldFNwYW4oY29udGV4dC5hY3RpdmUoKSwgdGFyZ2V0LnNwYW4pLCBuZXh0KTtcbn1cblxuLyoqXG4gKiBJbnN0YWxsIHtAbGluayBjaGF0VHVyblRlbGVtZXRyeU1pZGRsZXdhcmV9IG9uIGEgTWFzdHJhIEV4cHJlc3Mgc3ViLWFwcC5cbiAqXG4gKiBDYWxsIGJlZm9yZSBgTWFzdHJhU2VydmVyLmluaXQoKWAgc28gdGhlIGxheWVyIHNpdHMgYWhlYWQgb2YgdGhlIGFnZW50XG4gKiByb3V0ZXMuIFNhZmUgdG8gY2FsbCB1bmNvbmRpdGlvbmFsbHk6IHdoZW4gbm8gcmVjb3JkaW5nIHRyYWNlciBpcyByZWdpc3RlcmVkLFxuICogdGhlIG1pZGRsZXdhcmUgaXMgYSBuby1vcC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGF0dGFjaENoYXRUdXJuVGVsZW1ldHJ5KFxuICBhcHA6IGV4cHJlc3MuRXhwcmVzcyxcbiAgb3B0aW9uczogQ2hhdFR1cm5UZWxlbWV0cnlPcHRpb25zID0ge30sXG4pOiB2b2lkIHtcbiAgYXBwLnVzZSgocmVxLCByZXMsIG5leHQpID0+IGNoYXRUdXJuVGVsZW1ldHJ5TWlkZGxld2FyZShyZXEsIHJlcywgbmV4dCwgb3B0aW9ucykpO1xuICBsb2dnZXIuaW5mbyhcImNoYXQgdHVybiB0ZWxlbWV0cnkgbWlkZGxld2FyZSBhdHRhY2hlZFwiLCBvcHRpb25zKTtcbn1cbiJdfQ==
@@ -1,14 +1,3 @@
1
- /**
2
- * Request-body validation helpers shared by every route that parses a JSON
3
- * body with a schema from `@dbx-tools/shared-mastra`.
4
- *
5
- * A schema library's own issue text quotes the received body back, so it is
6
- * logged rather than returned. What a client gets instead is a stable message
7
- * plus the field paths that failed, which is enough to highlight the offending
8
- * inputs.
9
- *
10
- * @module
11
- */
12
1
  /** The subset of a failed parse result these helpers read. */
13
2
  export interface SchemaIssues {
14
3
  issues: ReadonlyArray<{
@@ -9,9 +9,15 @@
9
9
  *
10
10
  * @module
11
11
  */
12
+ import { object } from "@dbx-tools/shared-core";
12
13
  /** Distinct dot-joined field paths a failed parse flagged. */
13
14
  export function invalidFields(error) {
14
- const fields = error.issues.map((issue) => issue.path.map(String).join(".")).filter(Boolean);
15
- return [...new Set(fields)];
15
+ return [
16
+ ...object
17
+ .sequence(error.issues)
18
+ .map((issue) => issue.path.map(String).join("."))
19
+ .filter(Boolean)
20
+ .distinct(),
21
+ ];
16
22
  }
17
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92YWxpZGF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7O0dBVUc7QUFPSCw4REFBOEQ7QUFDOUQsTUFBTSxVQUFVLGFBQWEsQ0FBQyxLQUFtQjtJQUMvQyxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzdGLE9BQU8sQ0FBQyxHQUFHLElBQUksR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7QUFDOUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUmVxdWVzdC1ib2R5IHZhbGlkYXRpb24gaGVscGVycyBzaGFyZWQgYnkgZXZlcnkgcm91dGUgdGhhdCBwYXJzZXMgYSBKU09OXG4gKiBib2R5IHdpdGggYSBzY2hlbWEgZnJvbSBgQGRieC10b29scy9zaGFyZWQtbWFzdHJhYC5cbiAqXG4gKiBBIHNjaGVtYSBsaWJyYXJ5J3Mgb3duIGlzc3VlIHRleHQgcXVvdGVzIHRoZSByZWNlaXZlZCBib2R5IGJhY2ssIHNvIGl0IGlzXG4gKiBsb2dnZWQgcmF0aGVyIHRoYW4gcmV0dXJuZWQuIFdoYXQgYSBjbGllbnQgZ2V0cyBpbnN0ZWFkIGlzIGEgc3RhYmxlIG1lc3NhZ2VcbiAqIHBsdXMgdGhlIGZpZWxkIHBhdGhzIHRoYXQgZmFpbGVkLCB3aGljaCBpcyBlbm91Z2ggdG8gaGlnaGxpZ2h0IHRoZSBvZmZlbmRpbmdcbiAqIGlucHV0cy5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuLyoqIFRoZSBzdWJzZXQgb2YgYSBmYWlsZWQgcGFyc2UgcmVzdWx0IHRoZXNlIGhlbHBlcnMgcmVhZC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2NoZW1hSXNzdWVzIHtcbiAgaXNzdWVzOiBSZWFkb25seUFycmF5PHsgcGF0aDogUHJvcGVydHlLZXlbXSB9Pjtcbn1cblxuLyoqIERpc3RpbmN0IGRvdC1qb2luZWQgZmllbGQgcGF0aHMgYSBmYWlsZWQgcGFyc2UgZmxhZ2dlZC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbnZhbGlkRmllbGRzKGVycm9yOiBTY2hlbWFJc3N1ZXMpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IGZpZWxkcyA9IGVycm9yLmlzc3Vlcy5tYXAoKGlzc3VlKSA9PiBpc3N1ZS5wYXRoLm1hcChTdHJpbmcpLmpvaW4oXCIuXCIpKS5maWx0ZXIoQm9vbGVhbik7XG4gIHJldHVybiBbLi4ubmV3IFNldChmaWVsZHMpXTtcbn1cbiJdfQ==
23
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92YWxpZGF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7O0dBVUc7QUFDSCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFPaEQsOERBQThEO0FBQzlELE1BQU0sVUFBVSxhQUFhLENBQUMsS0FBbUI7SUFDL0MsT0FBTztRQUNMLEdBQUcsTUFBTTthQUNOLFFBQVEsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDO2FBQ3RCLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2FBQ2hELE1BQU0sQ0FBQyxPQUFPLENBQUM7YUFDZixRQUFRLEVBQUU7S0FDZCxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUmVxdWVzdC1ib2R5IHZhbGlkYXRpb24gaGVscGVycyBzaGFyZWQgYnkgZXZlcnkgcm91dGUgdGhhdCBwYXJzZXMgYSBKU09OXG4gKiBib2R5IHdpdGggYSBzY2hlbWEgZnJvbSBgQGRieC10b29scy9zaGFyZWQtbWFzdHJhYC5cbiAqXG4gKiBBIHNjaGVtYSBsaWJyYXJ5J3Mgb3duIGlzc3VlIHRleHQgcXVvdGVzIHRoZSByZWNlaXZlZCBib2R5IGJhY2ssIHNvIGl0IGlzXG4gKiBsb2dnZWQgcmF0aGVyIHRoYW4gcmV0dXJuZWQuIFdoYXQgYSBjbGllbnQgZ2V0cyBpbnN0ZWFkIGlzIGEgc3RhYmxlIG1lc3NhZ2VcbiAqIHBsdXMgdGhlIGZpZWxkIHBhdGhzIHRoYXQgZmFpbGVkLCB3aGljaCBpcyBlbm91Z2ggdG8gaGlnaGxpZ2h0IHRoZSBvZmZlbmRpbmdcbiAqIGlucHV0cy5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cbmltcG9ydCB7IG9iamVjdCB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5cbi8qKiBUaGUgc3Vic2V0IG9mIGEgZmFpbGVkIHBhcnNlIHJlc3VsdCB0aGVzZSBoZWxwZXJzIHJlYWQuICovXG5leHBvcnQgaW50ZXJmYWNlIFNjaGVtYUlzc3VlcyB7XG4gIGlzc3VlczogUmVhZG9ubHlBcnJheTx7IHBhdGg6IFByb3BlcnR5S2V5W10gfT47XG59XG5cbi8qKiBEaXN0aW5jdCBkb3Qtam9pbmVkIGZpZWxkIHBhdGhzIGEgZmFpbGVkIHBhcnNlIGZsYWdnZWQuICovXG5leHBvcnQgZnVuY3Rpb24gaW52YWxpZEZpZWxkcyhlcnJvcjogU2NoZW1hSXNzdWVzKTogc3RyaW5nW10ge1xuICByZXR1cm4gW1xuICAgIC4uLm9iamVjdFxuICAgICAgLnNlcXVlbmNlKGVycm9yLmlzc3VlcylcbiAgICAgIC5tYXAoKGlzc3VlKSA9PiBpc3N1ZS5wYXRoLm1hcChTdHJpbmcpLmpvaW4oXCIuXCIpKVxuICAgICAgLmZpbHRlcihCb29sZWFuKVxuICAgICAgLmRpc3RpbmN0KCksXG4gIF07XG59XG4iXX0=
package/package.json CHANGED
@@ -33,18 +33,19 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "@databricks/appkit": "0.81.0",
36
- "@dbx-tools/appkit": "^0.9.58",
37
- "@dbx-tools/core": "^0.9.58",
38
- "@dbx-tools/databricks": "^0.9.58",
39
- "@dbx-tools/fs": "^0.9.58",
40
- "@dbx-tools/genie": "^0.9.58",
41
- "@dbx-tools/model": "^0.9.58",
42
- "@dbx-tools/path": "^0.9.58",
43
- "@dbx-tools/shared-core": "^0.9.58",
44
- "@dbx-tools/shared-fs": "^0.9.58",
45
- "@dbx-tools/shared-genie": "^0.9.58",
46
- "@dbx-tools/shared-mastra": "^0.9.58",
47
- "@dbx-tools/shared-model": "^0.9.58",
36
+ "@dbx-tools/appkit": "^0.9.61",
37
+ "@dbx-tools/core": "^0.9.61",
38
+ "@dbx-tools/databricks": "^0.9.61",
39
+ "@dbx-tools/fs": "^0.9.61",
40
+ "@dbx-tools/genie": "^0.9.61",
41
+ "@dbx-tools/model": "^0.9.61",
42
+ "@dbx-tools/path": "^0.9.61",
43
+ "@dbx-tools/postgres": "^0.9.61",
44
+ "@dbx-tools/shared-core": "^0.9.61",
45
+ "@dbx-tools/shared-fs": "^0.9.61",
46
+ "@dbx-tools/shared-genie": "^0.9.61",
47
+ "@dbx-tools/shared-mastra": "^0.9.61",
48
+ "@dbx-tools/shared-model": "^0.9.61",
48
49
  "@mastra/ai-sdk": "1.10.5",
49
50
  "@mastra/core": "1.71.0",
50
51
  "@mastra/express": "1.5.15",
@@ -204,7 +205,7 @@
204
205
  "./package.json": "./package.json"
205
206
  }
206
207
  },
207
- "version": "0.9.58",
208
+ "version": "0.9.61",
208
209
  "types": "./lib/index.d.ts",
209
210
  "dbxToolsConfig": {
210
211
  "tags": [
package/src/config.ts CHANGED
@@ -464,9 +464,10 @@ export interface MastraPluginConfig extends BasePluginConfig {
464
464
  * is named (the same signals the observability pipeline needs to
465
465
  * ship traces to MLflow). Otherwise off, since there'd be no trace
466
466
  * to attach feedback to.
467
- * - `true`: force on. Feedback controls show and writes are attempted
468
- * regardless of env detection (use when the env is configured in a
469
- * way the auto-probe doesn't recognize).
467
+ * - `true`: force on. Requires `MLFLOW_EXPERIMENT_ID` or
468
+ * `MLFLOW_EXPERIMENT_NAME`; app startup fails when neither is configured.
469
+ * Use this when trace export is wired in a way the auto-probe does not
470
+ * recognize.
470
471
  * - `false`: force off. No trace-id header, no feedback route, no UI.
471
472
  *
472
473
  * Feedback attaches to a turn's MLflow trace via the OpenTelemetry
@@ -720,7 +721,7 @@ export const MASTRA_CONFIG_SCHEMA: ConfigSchema = {
720
721
  feedback: {
721
722
  type: "boolean",
722
723
  description:
723
- "Log thumbs / comment assessments to MLflow and surface the feedback controls. Defaults to on only when an OTLP endpoint and MLFLOW_EXPERIMENT_ID or MLFLOW_EXPERIMENT_NAME are set.",
724
+ "Log thumbs / comment assessments to MLflow and surface the feedback controls. Defaults to on only when an OTLP endpoint and MLFLOW_EXPERIMENT_ID or MLFLOW_EXPERIMENT_NAME are set. Explicit true fails startup unless an experiment id or name is configured.",
724
725
  },
725
726
  mcp: {
726
727
  type: ["boolean", "object"],
package/src/genie.ts CHANGED
@@ -59,6 +59,7 @@ import { chartPlannerRequestSchema, chartToolOutputSchema, prepareChart } from "
59
59
  import { MASTRA_USER_KEY, resolveUserKey } from "./config.ts";
60
60
  import type { MastraPluginConfig, User } from "./config.ts";
61
61
  import { fetchStatementData } from "./statement.ts";
62
+ import { stampGenieToolSpan } from "./telemetry.ts";
62
63
  import { safeWriteProgress } from "./writer.ts";
63
64
 
64
65
  const logger = log.logger("mastra/genie");
@@ -428,6 +429,7 @@ function buildAskGenieTool(opts: {
428
429
  }),
429
430
  execute: async ({ question }, ctxRaw) => {
430
431
  const ctx = ctxRaw as ToolExecuteCtx;
432
+ stampGenieToolSpan();
431
433
  const { client, requestContext } = requireClient(ctx, toolId);
432
434
  const writer = ctx?.writer;
433
435
  const toolCallId = ctx?.agent?.toolCallId;
package/src/memory.ts CHANGED
@@ -34,6 +34,7 @@
34
34
 
35
35
  import { getUsernameWithApiLookup } from "@databricks/appkit";
36
36
  import { migration as appkitMigration } from "@dbx-tools/appkit";
37
+ import { postgresConnectionOptions } from "@dbx-tools/postgres";
37
38
  import { hash, log } from "@dbx-tools/shared-core";
38
39
  import { fastembed } from "@mastra/fastembed";
39
40
  import { Memory } from "@mastra/memory";
@@ -123,7 +124,7 @@ export async function createServicePrincipalPool(pgConfig: PoolConfig): Promise<
123
124
  // lookup (e.g. local dev authenticating via PAT) so the pool always
124
125
  // has an identity to connect with.
125
126
  const user = pgConfig.user ?? (await getUsernameWithApiLookup());
126
- return new Pool({ ...pgConfig, user });
127
+ return new Pool(postgresConnectionOptions({ ...pgConfig, user }));
127
128
  }
128
129
 
129
130
  /** Effective per-knob setting after the plugin/agent cascade. */