@dbx-tools/model 0.9.5 → 0.9.6

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.
@@ -0,0 +1,198 @@
1
+ /**
2
+ * Live Databricks Model Serving catalogue access.
3
+ *
4
+ * Lists the workspace's `/serving-endpoints` and, when the caller supplies a
5
+ * trusted credential identity, caches the result per host and identity with a
6
+ * TTL via AppKit's `CacheManager`. Concurrent callers in the same scope share
7
+ * one in-flight promise. Surfaces each endpoint as a stable
8
+ * {@link ServingEndpointSummary} - including the Foundation Model API
9
+ * `quality` / `speed` / `cost` profile when present, the classified
10
+ * {@link ModelClass}, and (for embedding endpoints) the measured vector
11
+ * `dimension` - and snaps loose, human-typed names to real endpoint ids
12
+ * through the Rust model ranker so tokens like `"claude sonnet"` resolve to
13
+ * `databricks-claude-sonnet-4-6`.
14
+ *
15
+ * The class stamp and embedding dimension are computed once per cache load:
16
+ * every embedding endpoint is "pinged" in parallel and the resulting vector
17
+ * length recorded, so the cost is paid on a cache miss, not per read. The ping
18
+ * is best-effort - a failure logs at debug and leaves `dimension` unset rather
19
+ * than failing the whole listing.
20
+ *
21
+ * @module
22
+ */
23
+ import { createHash } from "node:crypto";
24
+ import { CacheManager } from "@databricks/appkit";
25
+ import { errorUtils, log } from "@dbx-tools/shared-core";
26
+ import { model } from "@dbx-tools/shared-model";
27
+ import { classifyEndpointClasses, normalizeEndpoints, rankEndpoints } from "./_native.js";
28
+ const { ModelClass } = model;
29
+ const logger = log.logger("model/serving");
30
+ /** Default TTL for the in-memory endpoint cache. Matches the Databricks SDK's session lifetime budget. */
31
+ export const DEFAULT_MODEL_CACHE_TTL_MS = 5 * 60 * 1000;
32
+ /** Default Rust distance threshold below which a fuzzy match is accepted. */
33
+ export const DEFAULT_FUZZY_THRESHOLD = 0.4;
34
+ /** Cache key parts under which endpoint listings are stored. */
35
+ const CACHE_KEY_NAMESPACE = "serving-endpoints";
36
+ /** Hash an opaque credential identity before handing it to CacheManager. */
37
+ function cacheUserKey(identity) {
38
+ return `model-${createHash("sha256").update(identity).digest("hex")}`;
39
+ }
40
+ /**
41
+ * List Model Serving endpoints for the workspace owning `client`, routed
42
+ * through AppKit's `CacheManager`. The manager gives us everything
43
+ * `cachetools.TTLCache` provides plus what `cachetools-async` adds on top:
44
+ * per-entry TTL, in-flight request coalescing (concurrent callers share one
45
+ * fetch via the manager's internal `inFlightRequests` map), bounded size,
46
+ * telemetry spans (`cache.getOrExecute`), and optional Lakebase persistence so
47
+ * the catalogue survives restarts when the lakebase plugin is wired up.
48
+ *
49
+ * Returns plain {@link ServingEndpointSummary} objects (a stable subset of the
50
+ * SDK type) so cache hits never expose stale SDK internals. Errors from
51
+ * `CacheManager` or the SDK fetch propagate to the caller - we don't swallow
52
+ * them so users see the real auth / network issue.
53
+ *
54
+ * @param host - Workspace host used as the cache key. Pass the value resolved
55
+ * from `client.config.getHost()` so multi-host apps share one entry per
56
+ * workspace.
57
+ * @param options.ttlMs - Override the default TTL just for this call. Forwarded
58
+ * to `CacheManager` as seconds.
59
+ */
60
+ export async function listServingEndpoints(client, host, options = {}) {
61
+ if (!options.cacheIdentity)
62
+ return fetchEndpoints(client);
63
+ const ttlSec = Math.max(1, Math.round((options.ttlMs ?? DEFAULT_MODEL_CACHE_TTL_MS) / 1000));
64
+ return CacheManager.getInstanceSync().getOrExecute([CACHE_KEY_NAMESPACE, host], () => fetchEndpoints(client), cacheUserKey(options.cacheIdentity), { ttl: ttlSec });
65
+ }
66
+ /**
67
+ * List the workspace's serving endpoints as minimal
68
+ * {@link ServingEndpointSummary} objects straight from the SDK: no caching, and
69
+ * none of the cache-load enrichment ({@link listServingEndpoints} adds the
70
+ * {@link ModelClass} stamp and the embedding-dimension probe). Use this for a
71
+ * one-shot, dependency-light listing - e.g. a CLI that only needs names/tasks
72
+ * for fuzzy resolution and doesn't want AppKit's `CacheManager` or the
73
+ * per-embedding ping cost. Prefer {@link listServingEndpoints} for the cached,
74
+ * enriched view.
75
+ */
76
+ export async function listServingEndpointsUncached(client) {
77
+ const endpoints = [];
78
+ for await (const ep of client.servingEndpoints.list()) {
79
+ endpoints.push(ep);
80
+ }
81
+ return normalizeEndpoints(endpoints);
82
+ }
83
+ async function fetchEndpoints(client) {
84
+ const startedAt = Date.now();
85
+ const out = await listServingEndpointsUncached(client);
86
+ stampModelClasses(out);
87
+ await measureEmbeddingDimensions(client, out);
88
+ logger.debug("listed", { count: out.length, elapsedMs: Date.now() - startedAt });
89
+ return out;
90
+ }
91
+ /**
92
+ * Stamp each summary's {@link ServingEndpointSummary.class} from the relative
93
+ * classification of the whole set. Mutates `summaries` in place. Endpoints the
94
+ * classifier doesn't recognize (custom, unscored, non-LLM) are left without a
95
+ * class.
96
+ */
97
+ function stampModelClasses(summaries) {
98
+ const classOf = classifyEndpointClasses(summaries);
99
+ for (const summary of summaries) {
100
+ const cls = classOf.get(summary.name);
101
+ if (cls !== undefined)
102
+ summary.class = cls;
103
+ }
104
+ }
105
+ /**
106
+ * Measure the embedding vector dimension of every {@link ModelClass.Embedding}
107
+ * endpoint by pinging it once, all in parallel. Mutates the matching summaries
108
+ * in place with the resulting `dimension`. Runs only on a cache miss (it's
109
+ * called from {@link fetchEndpoints}), so the probe cost is amortized across the
110
+ * cached TTL window. Per-endpoint failures are swallowed (logged at warn) so
111
+ * one unreachable embedding model never fails the listing.
112
+ */
113
+ async function measureEmbeddingDimensions(client, summaries) {
114
+ await Promise.all(summaries
115
+ .filter((s) => s.class === ModelClass.Embedding)
116
+ .map(async (summary) => {
117
+ const dimension = await pingEmbeddingDimension(client, summary.name);
118
+ if (dimension !== undefined)
119
+ summary.dimension = dimension;
120
+ }));
121
+ }
122
+ /**
123
+ * Best-effort embedding dimension probe: query `name` with a tiny `"ping"`
124
+ * input and return the length of the returned vector. Returns `undefined` (and
125
+ * logs at warn) when the endpoint can't be queried or returns no vector - the
126
+ * dimension is informational, never required.
127
+ */
128
+ async function pingEmbeddingDimension(client, name) {
129
+ try {
130
+ const response = await client.servingEndpoints.query({ name, input: "ping" });
131
+ const dimension = response.data?.[0]?.embedding?.length;
132
+ if (typeof dimension === "number" && dimension > 0)
133
+ return dimension;
134
+ logger.warn("embedding ping returned no vector", { name });
135
+ return undefined;
136
+ }
137
+ catch (err) {
138
+ logger.warn("embedding ping failed", { name, error: errorUtils.errorMessage(err) });
139
+ return undefined;
140
+ }
141
+ }
142
+ /**
143
+ * Force-evict cached endpoint listings via AppKit's `CacheManager`. A host and
144
+ * identity delete only that principal's workspace entry. Because CacheManager
145
+ * cannot enumerate a namespace, omitting either value clears the complete
146
+ * manager and should be reserved for tests or administrative refreshes.
147
+ */
148
+ export async function clearServingEndpointsCache(host, cacheIdentity) {
149
+ const cache = CacheManager.getInstanceSync();
150
+ if (host && cacheIdentity) {
151
+ const key = cache.generateKey([CACHE_KEY_NAMESPACE, host], cacheUserKey(cacheIdentity));
152
+ await cache.delete(key);
153
+ }
154
+ else {
155
+ await cache.clear();
156
+ }
157
+ }
158
+ /**
159
+ * Fuzzy-rank endpoints by how closely their `name` matches `input`, best
160
+ * (lowest score) first, keeping only those within `threshold`:
161
+ *
162
+ * 1. An exact name match short-circuits to a single `score: 0` result.
163
+ * 2. Otherwise Rust tokenizes the input and scores every endpoint through the
164
+ * same fuzzy-distance policy used by {@link lookupModels}.
165
+ *
166
+ * Returns `[]` for an empty endpoint list or when `input` tokenizes to nothing,
167
+ * so callers fall back to the raw input and let Databricks surface a clean 404.
168
+ * This multi-result core is shared by {@link resolveModelId} (single best) and
169
+ * the ranked `lookupModels` selector.
170
+ */
171
+ export function searchServingEndpoints(input, endpoints, options = {}) {
172
+ if (endpoints.length === 0 || !input.trim())
173
+ return [];
174
+ return rankEndpoints(endpoints, {
175
+ search: input,
176
+ ...(options.requiresTools !== undefined ? { requiresTools: options.requiresTools } : {}),
177
+ threshold: options.threshold ?? DEFAULT_FUZZY_THRESHOLD,
178
+ }, {
179
+ includeDeprecated: true,
180
+ modelClass: model.ModelClass.ChatBalanced,
181
+ task: "llm/v1/chat",
182
+ }).map((ranked) => ({ endpoint: ranked.endpoint, score: ranked.score ?? 0 }));
183
+ }
184
+ /**
185
+ * Snap a user-supplied model name to the single closest configured serving
186
+ * endpoint via {@link searchServingEndpoints}. Returns the input unchanged with
187
+ * `matched: false` when nothing scores within the threshold (or the catalogue
188
+ * is empty), so a deliberate model id is never silently rewritten to a
189
+ * similar-looking neighbour and the upstream call surfaces the canonical 404.
190
+ */
191
+ export function resolveModelId(input, endpoints, options = {}) {
192
+ const [best] = searchServingEndpoints(input, endpoints, options);
193
+ if (best) {
194
+ return { modelId: best.endpoint.name, matched: true, score: best.score };
195
+ }
196
+ return { modelId: input, matched: false };
197
+ }
198
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWwtY2F0YWxvZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9tb2RlbC1jYXRhbG9nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FxQkc7QUFFSCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUVsRCxPQUFPLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxLQUFLLEVBQStCLE1BQU0seUJBQXlCLENBQUM7QUFFN0UsT0FBTyxFQUFFLHVCQUF1QixFQUFFLGtCQUFrQixFQUFFLGFBQWEsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUUxRixNQUFNLEVBQUUsVUFBVSxFQUFFLEdBQUcsS0FBSyxDQUFDO0FBRTdCLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7QUFTM0MsMEdBQTBHO0FBQzFHLE1BQU0sQ0FBQyxNQUFNLDBCQUEwQixHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBRXhELDZFQUE2RTtBQUM3RSxNQUFNLENBQUMsTUFBTSx1QkFBdUIsR0FBRyxHQUFHLENBQUM7QUFFM0MsZ0VBQWdFO0FBQ2hFLE1BQU0sbUJBQW1CLEdBQUcsbUJBQW1CLENBQUM7QUFvQmhELDRFQUE0RTtBQUM1RSxTQUFTLFlBQVksQ0FBQyxRQUFnQjtJQUNwQyxPQUFPLFNBQVMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztBQUN4RSxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FtQkc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLG9CQUFvQixDQUN4QyxNQUEyQixFQUMzQixJ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LENBQUMsS0FBSyxFQUFFLENBQUM7SUFDM0UsQ0FBQztJQUNELE9BQU8sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQztBQUM1QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBMaXZlIERhdGFicmlja3MgTW9kZWwgU2VydmluZyBjYXRhbG9ndWUgYWNjZXNzLlxuICpcbiAqIExpc3RzIHRoZSB3b3Jrc3BhY2UncyBgL3NlcnZpbmctZW5kcG9pbnRzYCBhbmQsIHdoZW4gdGhlIGNhbGxlciBzdXBwbGllcyBhXG4gKiB0cnVzdGVkIGNyZWRlbnRpYWwgaWRlbnRpdHksIGNhY2hlcyB0aGUgcmVzdWx0IHBlciBob3N0IGFuZCBpZGVudGl0eSB3aXRoIGFcbiAqIFRUTCB2aWEgQXBwS2l0J3MgYENhY2hlTWFuYWdlcmAuIENvbmN1cnJlbnQgY2FsbGVycyBpbiB0aGUgc2FtZSBzY29wZSBzaGFyZVxuICogb25lIGluLWZsaWdodCBwcm9taXNlLiBTdXJmYWNlcyBlYWNoIGVuZHBvaW50IGFzIGEgc3RhYmxlXG4gKiB7QGxpbmsgU2VydmluZ0VuZHBvaW50U3VtbWFyeX0gLSBpbmNsdWRpbmcgdGhlIEZvdW5kYXRpb24gTW9kZWwgQVBJXG4gKiBgcXVhbGl0eWAgLyBgc3BlZWRgIC8gYGNvc3RgIHByb2ZpbGUgd2hlbiBwcmVzZW50LCB0aGUgY2xhc3NpZmllZFxuICoge0BsaW5rIE1vZGVsQ2xhc3N9LCBhbmQgKGZvciBlbWJlZGRpbmcgZW5kcG9pbnRzKSB0aGUgbWVhc3VyZWQgdmVjdG9yXG4gKiBgZGltZW5zaW9uYCAtIGFuZCBzbmFwcyBsb29zZSwgaHVtYW4tdHlwZWQgbmFtZXMgdG8gcmVhbCBlbmRwb2ludCBpZHNcbiAqIHRocm91Z2ggdGhlIFJ1c3QgbW9kZWwgcmFua2VyIHNvIHRva2VucyBsaWtlIGBcImNsYXVkZSBzb25uZXRcImAgcmVzb2x2ZSB0b1xuICogYGRhdGFicmlja3MtY2xhdWRlLXNvbm5ldC00LTZgLlxuICpcbiAqIFRoZSBjbGFzcyBzdGFtcCBhbmQgZW1iZWRkaW5nIGRpbWVuc2lvbiBhcmUgY29tcHV0ZWQgb25jZSBwZXIgY2FjaGUgbG9hZDpcbiAqIGV2ZXJ5IGVtYmVkZGluZyBlbmRwb2ludCBpcyBcInBpbmdlZFwiIGluIHBhcmFsbGVsIGFuZCB0aGUgcmVzdWx0aW5nIHZlY3RvclxuICogbGVuZ3RoIHJlY29yZGVkLCBzbyB0aGUgY29zdCBpcyBwYWlkIG9uIGEgY2FjaGUgbWlzcywgbm90IHBlciByZWFkLiBUaGUgcGluZ1xuICogaXMgYmVzdC1lZmZvcnQgLSBhIGZhaWx1cmUgbG9ncyBhdCBkZWJ1ZyBhbmQgbGVhdmVzIGBkaW1lbnNpb25gIHVuc2V0IHJhdGhlclxuICogdGhhbiBmYWlsaW5nIHRoZSB3aG9sZSBsaXN0aW5nLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBjcmVhdGVIYXNoIH0gZnJvbSBcIm5vZGU6Y3J5cHRvXCI7XG5pbXBvcnQgeyBDYWNoZU1hbmFnZXIgfSBmcm9tIFwiQGRhdGFicmlja3MvYXBwa2l0XCI7XG5pbXBvcnQgeyBhcHBraXQgfSBmcm9tIFwiQGRieC10b29scy9hcHBraXRcIjtcbmltcG9ydCB7IGVycm9yVXRpbHMsIGxvZyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgeyBtb2RlbCwgdHlwZSBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5IH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLW1vZGVsXCI7XG5cbmltcG9ydCB7IGNsYXNzaWZ5RW5kcG9pbnRDbGFzc2VzLCBub3JtYWxpemVFbmRwb2ludHMsIHJhbmtFbmRwb2ludHMgfSBmcm9tIFwiLi9fbmF0aXZlLnRzXCI7XG5cbmNvbnN0IHsgTW9kZWxDbGFzcyB9ID0gbW9kZWw7XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJtb2RlbC9zZXJ2aW5nXCIpO1xuXG4vKipcbiAqIFN0cnVjdHVyYWwgdHlwZSBmb3IgdGhlIERhdGFicmlja3Mgd29ya3NwYWNlIGNsaWVudCwgcmUtZXhwb3J0ZWQgc28gdGhlIHJlc3RcbiAqIG9mIHRoaXMgcGFja2FnZSBjYW4ga2VlcCBpbXBvcnRpbmcgaXQgZnJvbSBoZXJlLiBTZWVcbiAqIGBhcHBraXQuV29ya3NwYWNlQ2xpZW50TGlrZWAgKG5vZGUtYXBwa2l0KSBmb3IgdGhlIGNhbm9uaWNhbCBkZWZpbml0aW9uLlxuICovXG5leHBvcnQgdHlwZSBXb3Jrc3BhY2VDbGllbnRMaWtlID0gUGljazxhcHBraXQuV29ya3NwYWNlQ2xpZW50TGlrZSwgXCJzZXJ2aW5nRW5kcG9pbnRzXCI+O1xuXG4vKiogRGVmYXVsdCBUVEwgZm9yIHRoZSBpbi1tZW1vcnkgZW5kcG9pbnQgY2FjaGUuIE1hdGNoZXMgdGhlIERhdGFicmlja3MgU0RLJ3Mgc2Vzc2lvbiBsaWZldGltZSBidWRnZXQuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9NT0RFTF9DQUNIRV9UVExfTVMgPSA1ICogNjAgKiAxMDAwO1xuXG4vKiogRGVmYXVsdCBSdXN0IGRpc3RhbmNlIHRocmVzaG9sZCBiZWxvdyB3aGljaCBhIGZ1enp5IG1hdGNoIGlzIGFjY2VwdGVkLiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfRlVaWllfVEhSRVNIT0xEID0gMC40O1xuXG4vKiogQ2FjaGUga2V5IHBhcnRzIHVuZGVyIHdoaWNoIGVuZHBvaW50IGxpc3RpbmdzIGFyZSBzdG9yZWQuICovXG5jb25zdCBDQUNIRV9LRVlfTkFNRVNQQUNFID0gXCJzZXJ2aW5nLWVuZHBvaW50c1wiO1xuXG4vKiogT3B0aW9ucyBmb3Ige0BsaW5rIGxpc3RTZXJ2aW5nRW5kcG9pbnRzfS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTGlzdFNlcnZpbmdFbmRwb2ludHNPcHRpb25zIHtcbiAgLyoqXG4gICAqIE92ZXJyaWRlIHRoZSBkZWZhdWx0IGNhY2hlIFRUTCBmb3IgdGhpcyBjYWxsLCBpbiBtaWxsaXNlY29uZHMuIEZvcndhcmRlZCB0b1xuICAgKiBgQ2FjaGVNYW5hZ2VyYCBhcyBzZWNvbmRzLlxuICAgKi9cbiAgdHRsTXM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBUcnVzdGVkIGlkZW50aXR5IG9mIHRoZSBjcmVkZW50aWFsIHVzZWQgYnkgYGNsaWVudGAuXG4gICAqXG4gICAqIFRoZSB2YWx1ZSBpcyBoYXNoZWQgYmVmb3JlIGl0IGVudGVycyB0aGUgY2FjaGUga2V5IGFuZCBpcyBuZXZlciBsb2dnZWQuXG4gICAqIE9taXQgaXQgd2hlbiB0aGUgY2FsbGVyIGNhbm5vdCBwcm92ZSB0aGUgY3JlZGVudGlhbCBpZGVudGl0eTsgdGhhdCBjYWxsXG4gICAqIGJ5cGFzc2VzIHNoYXJlZCBjYWNoaW5nIHNvIG9uZSBwcmluY2lwYWwgY2FuIG5ldmVyIHJlYWQgYW5vdGhlcidzXG4gICAqIGNhdGFsb2d1ZS5cbiAgICovXG4gIGNhY2hlSWRlbnRpdHk/OiBzdHJpbmc7XG59XG5cbi8qKiBIYXNoIGFuIG9wYXF1ZSBjcmVkZW50aWFsIGlkZW50aXR5IGJlZm9yZSBoYW5kaW5nIGl0IHRvIENhY2hlTWFuYWdlci4gKi9cbmZ1bmN0aW9uIGNhY2hlVXNlcktleShpZGVudGl0eTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGBtb2RlbC0ke2NyZWF0ZUhhc2goXCJzaGEyNTZcIikudXBkYXRlKGlkZW50aXR5KS5kaWdlc3QoXCJoZXhcIil9YDtcbn1cblxuLyoqXG4gKiBMaXN0IE1vZGVsIFNlcnZpbmcgZW5kcG9pbnRzIGZvciB0aGUgd29ya3NwYWNlIG93bmluZyBgY2xpZW50YCwgcm91dGVkXG4gKiB0aHJvdWdoIEFwcEtpdCdzIGBDYWNoZU1hbmFnZXJgLiBUaGUgbWFuYWdlciBnaXZlcyB1cyBldmVyeXRoaW5nXG4gKiBgY2FjaGV0b29scy5UVExDYWNoZWAgcHJvdmlkZXMgcGx1cyB3aGF0IGBjYWNoZXRvb2xzLWFzeW5jYCBhZGRzIG9uIHRvcDpcbiAqIHBlci1lbnRyeSBUVEwsIGluLWZsaWdodCByZXF1ZXN0IGNvYWxlc2NpbmcgKGNvbmN1cnJlbnQgY2FsbGVycyBzaGFyZSBvbmVcbiAqIGZldGNoIHZpYSB0aGUgbWFuYWdlcidzIGludGVybmFsIGBpbkZsaWdodFJlcXVlc3RzYCBtYXApLCBib3VuZGVkIHNpemUsXG4gKiB0ZWxlbWV0cnkgc3BhbnMgKGBjYWNoZS5nZXRPckV4ZWN1dGVgKSwgYW5kIG9wdGlvbmFsIExha2ViYXNlIHBlcnNpc3RlbmNlIHNvXG4gKiB0aGUgY2F0YWxvZ3VlIHN1cnZpdmVzIHJlc3RhcnRzIHdoZW4gdGhlIGxha2ViYXNlIHBsdWdpbiBpcyB3aXJlZCB1cC5cbiAqXG4gKiBSZXR1cm5zIHBsYWluIHtAbGluayBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5fSBvYmplY3RzIChhIHN0YWJsZSBzdWJzZXQgb2YgdGhlXG4gKiBTREsgdHlwZSkgc28gY2FjaGUgaGl0cyBuZXZlciBleHBvc2Ugc3RhbGUgU0RLIGludGVybmFscy4gRXJyb3JzIGZyb21cbiAqIGBDYWNoZU1hbmFnZXJgIG9yIHRoZSBTREsgZmV0Y2ggcHJvcGFnYXRlIHRvIHRoZSBjYWxsZXIgLSB3ZSBkb24ndCBzd2FsbG93XG4gKiB0aGVtIHNvIHVzZXJzIHNlZSB0aGUgcmVhbCBhdXRoIC8gbmV0d29yayBpc3N1ZS5cbiAqXG4gKiBAcGFyYW0gaG9zdCAtIFdvcmtzcGFjZSBob3N0IHVzZWQgYXMgdGhlIGNhY2hlIGtleS4gUGFzcyB0aGUgdmFsdWUgcmVzb2x2ZWRcbiAqICAgZnJvbSBgY2xpZW50LmNvbmZpZy5nZXRIb3N0KClgIHNvIG11bHRpLWhvc3QgYXBwcyBzaGFyZSBvbmUgZW50cnkgcGVyXG4gKiAgIHdvcmtzcGFjZS5cbiAqIEBwYXJhbSBvcHRpb25zLnR0bE1zIC0gT3ZlcnJpZGUgdGhlIGRlZmF1bHQgVFRMIGp1c3QgZm9yIHRoaXMgY2FsbC4gRm9yd2FyZGVkXG4gKiAgIHRvIGBDYWNoZU1hbmFnZXJgIGFzIHNlY29uZHMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBsaXN0U2VydmluZ0VuZHBvaW50cyhcbiAgY2xpZW50OiBXb3Jrc3BhY2VDbGllbnRMaWtlLFxuICBob3N0OiBzdHJpbmcsXG4gIG9wdGlvbnM6IExpc3RTZXJ2aW5nRW5kcG9pbnRzT3B0aW9ucyA9IHt9LFxuKTogUHJvbWlzZTxTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5W10+IHtcbiAgaWYgKCFvcHRpb25zLmNhY2hlSWRlbnRpdHkpIHJldHVybiBmZXRjaEVuZHBvaW50cyhjbGllbnQpO1xuICBjb25zdCB0dGxTZWMgPSBNYXRoLm1heCgxLCBNYXRoLnJvdW5kKChvcHRpb25zLnR0bE1zID8/IERFRkFVTFRfTU9ERUxfQ0FDSEVfVFRMX01TKSAvIDEwMDApKTtcbiAgcmV0dXJuIENhY2hlTWFuYWdlci5nZXRJbnN0YW5jZVN5bmMoKS5nZXRPckV4ZWN1dGUoXG4gICAgW0NBQ0hFX0tFWV9OQU1FU1BBQ0UsIGhvc3RdLFxuICAgICgpID0+IGZldGNoRW5kcG9pbnRzKGNsaWVudCksXG4gICAgY2FjaGVVc2VyS2V5KG9wdGlvbnMuY2FjaGVJZGVudGl0eSksXG4gICAgeyB0dGw6IHR0bFNlYyB9LFxuICApO1xufVxuXG4vKipcbiAqIExpc3QgdGhlIHdvcmtzcGFjZSdzIHNlcnZpbmcgZW5kcG9pbnRzIGFzIG1pbmltYWxcbiAqIHtAbGluayBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5fSBvYmplY3RzIHN0cmFpZ2h0IGZyb20gdGhlIFNESzogbm8gY2FjaGluZywgYW5kXG4gKiBub25lIG9mIHRoZSBjYWNoZS1sb2FkIGVucmljaG1lbnQgKHtAbGluayBsaXN0U2VydmluZ0VuZHBvaW50c30gYWRkcyB0aGVcbiAqIHtAbGluayBNb2RlbENsYXNzfSBzdGFtcCBhbmQgdGhlIGVtYmVkZGluZy1kaW1lbnNpb24gcHJvYmUpLiBVc2UgdGhpcyBmb3IgYVxuICogb25lLXNob3QsIGRlcGVuZGVuY3ktbGlnaHQgbGlzdGluZyAtIGUuZy4gYSBDTEkgdGhhdCBvbmx5IG5lZWRzIG5hbWVzL3Rhc2tzXG4gKiBmb3IgZnV6enkgcmVzb2x1dGlvbiBhbmQgZG9lc24ndCB3YW50IEFwcEtpdCdzIGBDYWNoZU1hbmFnZXJgIG9yIHRoZVxuICogcGVyLWVtYmVkZGluZyBwaW5nIGNvc3QuIFByZWZlciB7QGxpbmsgbGlzdFNlcnZpbmdFbmRwb2ludHN9IGZvciB0aGUgY2FjaGVkLFxuICogZW5yaWNoZWQgdmlldy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxpc3RTZXJ2aW5nRW5kcG9pbnRzVW5jYWNoZWQoXG4gIGNsaWVudDogV29ya3NwYWNlQ2xpZW50TGlrZSxcbik6IFByb21pc2U8U2VydmluZ0VuZHBvaW50U3VtbWFyeVtdPiB7XG4gIGNvbnN0IGVuZHBvaW50czogdW5rbm93bltdID0gW107XG4gIGZvciBhd2FpdCAoY29uc3QgZXAgb2YgY2xpZW50LnNlcnZpbmdFbmRwb2ludHMubGlzdCgpKSB7XG4gICAgZW5kcG9pbnRzLnB1c2goZXApO1xuICB9XG4gIHJldHVybiBub3JtYWxpemVFbmRwb2ludHMoZW5kcG9pbnRzKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZmV0Y2hFbmRwb2ludHMoY2xpZW50OiBXb3Jrc3BhY2VDbGllbnRMaWtlKTogUHJvbWlzZTxTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5W10+IHtcbiAgY29uc3Qgc3RhcnRlZEF0ID0gRGF0ZS5ub3coKTtcbiAgY29uc3Qgb3V0ID0gYXdhaXQgbGlzdFNlcnZpbmdFbmRwb2ludHNVbmNhY2hlZChjbGllbnQpO1xuICBzdGFtcE1vZGVsQ2xhc3NlcyhvdXQpO1xuICBhd2FpdCBtZWFzdXJlRW1iZWRkaW5nRGltZW5zaW9ucyhjbGllbnQsIG91dCk7XG4gIGxvZ2dlci5kZWJ1ZyhcImxpc3RlZFwiLCB7IGNvdW50OiBvdXQubGVuZ3RoLCBlbGFwc2VkTXM6IERhdGUubm93KCkgLSBzdGFydGVkQXQgfSk7XG4gIHJldHVybiBvdXQ7XG59XG5cbi8qKlxuICogU3RhbXAgZWFjaCBzdW1tYXJ5J3Mge0BsaW5rIFNlcnZpbmdFbmRwb2ludFN1bW1hcnkuY2xhc3N9IGZyb20gdGhlIHJlbGF0aXZlXG4gKiBjbGFzc2lmaWNhdGlvbiBvZiB0aGUgd2hvbGUgc2V0LiBNdXRhdGVzIGBzdW1tYXJpZXNgIGluIHBsYWNlLiBFbmRwb2ludHMgdGhlXG4gKiBjbGFzc2lmaWVyIGRvZXNuJ3QgcmVjb2duaXplIChjdXN0b20sIHVuc2NvcmVkLCBub24tTExNKSBhcmUgbGVmdCB3aXRob3V0IGFcbiAqIGNsYXNzLlxuICovXG5mdW5jdGlvbiBzdGFtcE1vZGVsQ2xhc3NlcyhzdW1tYXJpZXM6IFNlcnZpbmdFbmRwb2ludFN1bW1hcnlbXSk6IHZvaWQge1xuICBjb25zdCBjbGFzc09mID0gY2xhc3NpZnlFbmRwb2ludENsYXNzZXMoc3VtbWFyaWVzKTtcbiAgZm9yIChjb25zdCBzdW1tYXJ5IG9mIHN1bW1hcmllcykge1xuICAgIGNvbnN0IGNscyA9IGNsYXNzT2YuZ2V0KHN1bW1hcnkubmFtZSk7XG4gICAgaWYgKGNscyAhPT0gdW5kZWZpbmVkKSBzdW1tYXJ5LmNsYXNzID0gY2xzO1xuICB9XG59XG5cbi8qKlxuICogTWVhc3VyZSB0aGUgZW1iZWRkaW5nIHZlY3RvciBkaW1lbnNpb24gb2YgZXZlcnkge0BsaW5rIE1vZGVsQ2xhc3MuRW1iZWRkaW5nfVxuICogZW5kcG9pbnQgYnkgcGluZ2luZyBpdCBvbmNlLCBhbGwgaW4gcGFyYWxsZWwuIE11dGF0ZXMgdGhlIG1hdGNoaW5nIHN1bW1hcmllc1xuICogaW4gcGxhY2Ugd2l0aCB0aGUgcmVzdWx0aW5nIGBkaW1lbnNpb25gLiBSdW5zIG9ubHkgb24gYSBjYWNoZSBtaXNzIChpdCdzXG4gKiBjYWxsZWQgZnJvbSB7QGxpbmsgZmV0Y2hFbmRwb2ludHN9KSwgc28gdGhlIHByb2JlIGNvc3QgaXMgYW1vcnRpemVkIGFjcm9zcyB0aGVcbiAqIGNhY2hlZCBUVEwgd2luZG93LiBQZXItZW5kcG9pbnQgZmFpbHVyZXMgYXJlIHN3YWxsb3dlZCAobG9nZ2VkIGF0IHdhcm4pIHNvXG4gKiBvbmUgdW5yZWFjaGFibGUgZW1iZWRkaW5nIG1vZGVsIG5ldmVyIGZhaWxzIHRoZSBsaXN0aW5nLlxuICovXG5hc3luYyBmdW5jdGlvbiBtZWFzdXJlRW1iZWRkaW5nRGltZW5zaW9ucyhcbiAgY2xpZW50OiBXb3Jrc3BhY2VDbGllbnRMaWtlLFxuICBzdW1tYXJpZXM6IFNlcnZpbmdFbmRwb2ludFN1bW1hcnlbXSxcbik6IFByb21pc2U8dm9pZD4ge1xuICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICBzdW1tYXJpZXNcbiAgICAgIC5maWx0ZXIoKHMpID0+IHMuY2xhc3MgPT09IE1vZGVsQ2xhc3MuRW1iZWRkaW5nKVxuICAgICAgLm1hcChhc3luYyAoc3VtbWFyeSkgPT4ge1xuICAgICAgICBjb25zdCBkaW1lbnNpb24gPSBhd2FpdCBwaW5nRW1iZWRkaW5nRGltZW5zaW9uKGNsaWVudCwgc3VtbWFyeS5uYW1lKTtcbiAgICAgICAgaWYgKGRpbWVuc2lvbiAhPT0gdW5kZWZpbmVkKSBzdW1tYXJ5LmRpbWVuc2lvbiA9IGRpbWVuc2lvbjtcbiAgICAgIH0pLFxuICApO1xufVxuXG4vKipcbiAqIEJlc3QtZWZmb3J0IGVtYmVkZGluZyBkaW1lbnNpb24gcHJvYmU6IHF1ZXJ5IGBuYW1lYCB3aXRoIGEgdGlueSBgXCJwaW5nXCJgXG4gKiBpbnB1dCBhbmQgcmV0dXJuIHRoZSBsZW5ndGggb2YgdGhlIHJldHVybmVkIHZlY3Rvci4gUmV0dXJucyBgdW5kZWZpbmVkYCAoYW5kXG4gKiBsb2dzIGF0IHdhcm4pIHdoZW4gdGhlIGVuZHBvaW50IGNhbid0IGJlIHF1ZXJpZWQgb3IgcmV0dXJucyBubyB2ZWN0b3IgLSB0aGVcbiAqIGRpbWVuc2lvbiBpcyBpbmZvcm1hdGlvbmFsLCBuZXZlciByZXF1aXJlZC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gcGluZ0VtYmVkZGluZ0RpbWVuc2lvbihcbiAgY2xpZW50OiBXb3Jrc3BhY2VDbGllbnRMaWtlLFxuICBuYW1lOiBzdHJpbmcsXG4pOiBQcm9taXNlPG51bWJlciB8IHVuZGVmaW5lZD4ge1xuICB0cnkge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgY2xpZW50LnNlcnZpbmdFbmRwb2ludHMucXVlcnkoeyBuYW1lLCBpbnB1dDogXCJwaW5nXCIgfSk7XG4gICAgY29uc3QgZGltZW5zaW9uID0gcmVzcG9uc2UuZGF0YT8uWzBdPy5lbWJlZGRpbmc/Lmxlbmd0aDtcbiAgICBpZiAodHlwZW9mIGRpbWVuc2lvbiA9PT0gXCJudW1iZXJcIiAmJiBkaW1lbnNpb24gPiAwKSByZXR1cm4gZGltZW5zaW9uO1xuICAgIGxvZ2dlci53YXJuKFwiZW1iZWRkaW5nIHBpbmcgcmV0dXJuZWQgbm8gdmVjdG9yXCIsIHsgbmFtZSB9KTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBsb2dnZXIud2FybihcImVtYmVkZGluZyBwaW5nIGZhaWxlZFwiLCB7IG5hbWUsIGVycm9yOiBlcnJvclV0aWxzLmVycm9yTWVzc2FnZShlcnIpIH0pO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuLyoqXG4gKiBGb3JjZS1ldmljdCBjYWNoZWQgZW5kcG9pbnQgbGlzdGluZ3MgdmlhIEFwcEtpdCdzIGBDYWNoZU1hbmFnZXJgLiBBIGhvc3QgYW5kXG4gKiBpZGVudGl0eSBkZWxldGUgb25seSB0aGF0IHByaW5jaXBhbCdzIHdvcmtzcGFjZSBlbnRyeS4gQmVjYXVzZSBDYWNoZU1hbmFnZXJcbiAqIGNhbm5vdCBlbnVtZXJhdGUgYSBuYW1lc3BhY2UsIG9taXR0aW5nIGVpdGhlciB2YWx1ZSBjbGVhcnMgdGhlIGNvbXBsZXRlXG4gKiBtYW5hZ2VyIGFuZCBzaG91bGQgYmUgcmVzZXJ2ZWQgZm9yIHRlc3RzIG9yIGFkbWluaXN0cmF0aXZlIHJlZnJlc2hlcy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNsZWFyU2VydmluZ0VuZHBvaW50c0NhY2hlKFxuICBob3N0Pzogc3RyaW5nLFxuICBjYWNoZUlkZW50aXR5Pzogc3RyaW5nLFxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IGNhY2hlID0gQ2FjaGVNYW5hZ2VyLmdldEluc3RhbmNlU3luYygpO1xuICBpZiAoaG9zdCAmJiBjYWNoZUlkZW50aXR5KSB7XG4gICAgY29uc3Qga2V5ID0gY2FjaGUuZ2VuZXJhdGVLZXkoW0NBQ0hFX0tFWV9OQU1FU1BBQ0UsIGhvc3RdLCBjYWNoZVVzZXJLZXkoY2FjaGVJZGVudGl0eSkpO1xuICAgIGF3YWl0IGNhY2hlLmRlbGV0ZShrZXkpO1xuICB9IGVsc2Uge1xuICAgIGF3YWl0IGNhY2hlLmNsZWFyKCk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXN1bHQgb2YgZnV6enktcmVzb2x2aW5nIGEgdXNlci1zdXBwbGllZCBtb2RlbCBuYW1lIGFnYWluc3QgdGhlIGxpdmVcbiAqIGVuZHBvaW50IGxpc3QuIGBzY29yZWAgaXMgdGhlIFJ1c3QgcmFua2VyJ3MgZGlzdGFuY2UgKGAwYCBpcyBleGFjdCwgYDFgIGlzIG5vIG1hdGNoKTtcbiAqIGBtYXRjaGVkYCBpcyBgZmFsc2VgIHdoZW4gdGhlIHNjb3JlIGV4Y2VlZHMgdGhlIGNvbmZpZ3VyZWQgdGhyZXNob2xkIHNvXG4gKiBjYWxsZXJzIGNhbiBmYWxsIGJhY2sgdG8gdGhlIG9yaWdpbmFsIGlucHV0IChEYXRhYnJpY2tzIHdpbGwgdGhlbiByZXR1cm4gYVxuICogY2xlYW4gNDA0KS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXNvbHZlZE1vZGVsIHtcbiAgbW9kZWxJZDogc3RyaW5nO1xuICBtYXRjaGVkOiBib29sZWFuO1xuICBzY29yZT86IG51bWJlcjtcbn1cblxuLyoqIE9wdGlvbnMgYWNjZXB0ZWQgYnkge0BsaW5rIHJlc29sdmVNb2RlbElkfSAvIHtAbGluayBzZWFyY2hTZXJ2aW5nRW5kcG9pbnRzfS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb2x2ZU1vZGVsT3B0aW9ucyB7XG4gIC8qKiBGdXp6eSBkaXN0YW5jZSB0aHJlc2hvbGQgKDAgPSBleGFjdCwgMSA9IGFueXRoaW5nKS4gRGVmYXVsdCBgMC40YC4gKi9cbiAgdGhyZXNob2xkPzogbnVtYmVyO1xuICAvKiogUmVxdWlyZSBhIG1vZGVsIHZlcmlmaWVkIGZvciBhIGNvbXBsZXRlIGZ1bmN0aW9uLXRvb2wgcm91bmQtdHJpcC4gKi9cbiAgcmVxdWlyZXNUb29scz86IGJvb2xlYW47XG59XG5cbi8qKiBBIHNlcnZpbmcgZW5kcG9pbnQgcGFpcmVkIHdpdGggaXRzIGZ1enp5LW1hdGNoIGRpc3RhbmNlIGZvciBhIHF1ZXJ5LiAqL1xuZXhwb3J0IGludGVyZmFjZSBTY29yZWRFbmRwb2ludCB7XG4gIGVuZHBvaW50OiBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5O1xuICAvKiogRnV6enkgZGlzdGFuY2U6IGAwYCBpcyBleGFjdCwgYDFgIGlzIG5vIG1hdGNoLiAqL1xuICBzY29yZTogbnVtYmVyO1xufVxuXG4vKipcbiAqIEZ1enp5LXJhbmsgZW5kcG9pbnRzIGJ5IGhvdyBjbG9zZWx5IHRoZWlyIGBuYW1lYCBtYXRjaGVzIGBpbnB1dGAsIGJlc3RcbiAqIChsb3dlc3Qgc2NvcmUpIGZpcnN0LCBrZWVwaW5nIG9ubHkgdGhvc2Ugd2l0aGluIGB0aHJlc2hvbGRgOlxuICpcbiAqIDEuIEFuIGV4YWN0IG5hbWUgbWF0Y2ggc2hvcnQtY2lyY3VpdHMgdG8gYSBzaW5nbGUgYHNjb3JlOiAwYCByZXN1bHQuXG4gKiAyLiBPdGhlcndpc2UgUnVzdCB0b2tlbml6ZXMgdGhlIGlucHV0IGFuZCBzY29yZXMgZXZlcnkgZW5kcG9pbnQgdGhyb3VnaCB0aGVcbiAqICAgIHNhbWUgZnV6enktZGlzdGFuY2UgcG9saWN5IHVzZWQgYnkge0BsaW5rIGxvb2t1cE1vZGVsc30uXG4gKlxuICogUmV0dXJucyBgW11gIGZvciBhbiBlbXB0eSBlbmRwb2ludCBsaXN0IG9yIHdoZW4gYGlucHV0YCB0b2tlbml6ZXMgdG8gbm90aGluZyxcbiAqIHNvIGNhbGxlcnMgZmFsbCBiYWNrIHRvIHRoZSByYXcgaW5wdXQgYW5kIGxldCBEYXRhYnJpY2tzIHN1cmZhY2UgYSBjbGVhbiA0MDQuXG4gKiBUaGlzIG11bHRpLXJlc3VsdCBjb3JlIGlzIHNoYXJlZCBieSB7QGxpbmsgcmVzb2x2ZU1vZGVsSWR9IChzaW5nbGUgYmVzdCkgYW5kXG4gKiB0aGUgcmFua2VkIGBsb29rdXBNb2RlbHNgIHNlbGVjdG9yLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2VhcmNoU2VydmluZ0VuZHBvaW50cyhcbiAgaW5wdXQ6IHN0cmluZyxcbiAgZW5kcG9pbnRzOiByZWFkb25seSBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5W10sXG4gIG9wdGlvbnM6IFJlc29sdmVNb2RlbE9wdGlvbnMgPSB7fSxcbik6IFNjb3JlZEVuZHBvaW50W10ge1xuICBpZiAoZW5kcG9pbnRzLmxlbmd0aCA9PT0gMCB8fCAhaW5wdXQudHJpbSgpKSByZXR1cm4gW107XG4gIHJldHVybiByYW5rRW5kcG9pbnRzKFxuICAgIGVuZHBvaW50cyxcbiAgICB7XG4gICAgICBzZWFyY2g6IGlucHV0LFxuICAgICAgLi4uKG9wdGlvbnMucmVxdWlyZXNUb29scyAhPT0gdW5kZWZpbmVkID8geyByZXF1aXJlc1Rvb2xzOiBvcHRpb25zLnJlcXVpcmVzVG9vbHMgfSA6IHt9KSxcbiAgICAgIHRocmVzaG9sZDogb3B0aW9ucy50aHJlc2hvbGQgPz8gREVGQVVMVF9GVVpaWV9USFJFU0hPTEQsXG4gICAgfSxcbiAgICB7XG4gICAgICBpbmNsdWRlRGVwcmVjYXRlZDogdHJ1ZSxcbiAgICAgIG1vZGVsQ2xhc3M6IG1vZGVsLk1vZGVsQ2xhc3MuQ2hhdEJhbGFuY2VkLFxuICAgICAgdGFzazogXCJsbG0vdjEvY2hhdFwiLFxuICAgIH0sXG4gICkubWFwKChyYW5rZWQpID0+ICh7IGVuZHBvaW50OiByYW5rZWQuZW5kcG9pbnQsIHNjb3JlOiByYW5rZWQuc2NvcmUgPz8gMCB9KSk7XG59XG5cbi8qKlxuICogU25hcCBhIHVzZXItc3VwcGxpZWQgbW9kZWwgbmFtZSB0byB0aGUgc2luZ2xlIGNsb3Nlc3QgY29uZmlndXJlZCBzZXJ2aW5nXG4gKiBlbmRwb2ludCB2aWEge0BsaW5rIHNlYXJjaFNlcnZpbmdFbmRwb2ludHN9LiBSZXR1cm5zIHRoZSBpbnB1dCB1bmNoYW5nZWQgd2l0aFxuICogYG1hdGNoZWQ6IGZhbHNlYCB3aGVuIG5vdGhpbmcgc2NvcmVzIHdpdGhpbiB0aGUgdGhyZXNob2xkIChvciB0aGUgY2F0YWxvZ3VlXG4gKiBpcyBlbXB0eSksIHNvIGEgZGVsaWJlcmF0ZSBtb2RlbCBpZCBpcyBuZXZlciBzaWxlbnRseSByZXdyaXR0ZW4gdG8gYVxuICogc2ltaWxhci1sb29raW5nIG5laWdoYm91ciBhbmQgdGhlIHVwc3RyZWFtIGNhbGwgc3VyZmFjZXMgdGhlIGNhbm9uaWNhbCA0MDQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlTW9kZWxJZChcbiAgaW5wdXQ6IHN0cmluZyxcbiAgZW5kcG9pbnRzOiByZWFkb25seSBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5W10sXG4gIG9wdGlvbnM6IFJlc29sdmVNb2RlbE9wdGlvbnMgPSB7fSxcbik6IFJlc29sdmVkTW9kZWwge1xuICBjb25zdCBbYmVzdF0gPSBzZWFyY2hTZXJ2aW5nRW5kcG9pbnRzKGlucHV0LCBlbmRwb2ludHMsIG9wdGlvbnMpO1xuICBpZiAoYmVzdCkge1xuICAgIHJldHVybiB7IG1vZGVsSWQ6IGJlc3QuZW5kcG9pbnQubmFtZSwgbWF0Y2hlZDogdHJ1ZSwgc2NvcmU6IGJlc3Quc2NvcmUgfTtcbiAgfVxuICByZXR1cm4geyBtb2RlbElkOiBpbnB1dCwgbWF0Y2hlZDogZmFsc2UgfTtcbn1cbiJdfQ==
@@ -3,8 +3,12 @@
3
3
  *
4
4
  * @module
5
5
  */
6
- import type { ReasoningEffort } from "@dbx-tools/shared-model";
6
+ import { type ReasoningEffort, type ServingEndpointSummary } from "@dbx-tools/shared-model";
7
7
  /** Return the normalized family parsed by the Rust model-name policy. */
8
8
  export declare function modelFamily(name: string): string | undefined;
9
9
  /** Return the reasoning efforts accepted by a model family. */
10
10
  export declare function modelReasoningEfforts(name: string): ReasoningEffort[];
11
+ /** Return whether Rust policy verifies a complete tool-calling round trip. */
12
+ export declare function modelSupportsTools(name: string): boolean;
13
+ /** Return whether a discovered endpoint can be used for a tool-calling chat. */
14
+ export declare function endpointSupportsTools(endpoint: ServingEndpointSummary): boolean;
package/lib/src/policy.js CHANGED
@@ -3,13 +3,24 @@
3
3
  *
4
4
  * @module
5
5
  */
6
- import { modelFamily as modelFamilyWithRust, reasoningEffortNamesByFamily, } from "@dbx-tools/model-rs";
6
+ import { modelFamily as modelFamilyWithRust, reasoningEffortNamesByFamily, supportsToolsByFamily as supportsToolsByFamilyWithRust, } from "@dbx-tools/model-rs";
7
+ import { model, ReasoningEffortSchema, } from "@dbx-tools/shared-model";
7
8
  /** Return the normalized family parsed by the Rust model-name policy. */
8
9
  export function modelFamily(name) {
9
10
  return modelFamilyWithRust(name);
10
11
  }
11
12
  /** Return the reasoning efforts accepted by a model family. */
12
13
  export function modelReasoningEfforts(name) {
13
- return reasoningEffortNamesByFamily(name);
14
+ return ReasoningEffortSchema.array().parse(reasoningEffortNamesByFamily(name));
14
15
  }
15
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9saWN5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3BvbGljeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBRUgsT0FBTyxFQUNMLFdBQVcsSUFBSSxtQkFBbUIsRUFDbEMsNEJBQTRCLEdBQzdCLE1BQU0scUJBQXFCLENBQUM7QUFHN0IseUVBQXlFO0FBQ3pFLE1BQU0sVUFBVSxXQUFXLENBQUMsSUFBWTtJQUN0QyxPQUFPLG1CQUFtQixDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ25DLENBQUM7QUFFRCwrREFBK0Q7QUFDL0QsTUFBTSxVQUFVLHFCQUFxQixDQUFDLElBQVk7SUFDaEQsT0FBTyw0QkFBNEIsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUM1QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBCcm93c2VyLXNhZmUgbW9kZWwgbWV0YWRhdGEgcHJvamVjdGVkIGZyb20gdGhlIFJ1c3QgcG9saWN5IGJpbmRpbmdzLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQge1xuICBtb2RlbEZhbWlseSBhcyBtb2RlbEZhbWlseVdpdGhSdXN0LFxuICByZWFzb25pbmdFZmZvcnROYW1lc0J5RmFtaWx5LFxufSBmcm9tIFwiQGRieC10b29scy9tb2RlbC1yc1wiO1xuaW1wb3J0IHR5cGUgeyBSZWFzb25pbmdFZmZvcnQgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtbW9kZWxcIjtcblxuLyoqIFJldHVybiB0aGUgbm9ybWFsaXplZCBmYW1pbHkgcGFyc2VkIGJ5IHRoZSBSdXN0IG1vZGVsLW5hbWUgcG9saWN5LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1vZGVsRmFtaWx5KG5hbWU6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiBtb2RlbEZhbWlseVdpdGhSdXN0KG5hbWUpO1xufVxuXG4vKiogUmV0dXJuIHRoZSByZWFzb25pbmcgZWZmb3J0cyBhY2NlcHRlZCBieSBhIG1vZGVsIGZhbWlseS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtb2RlbFJlYXNvbmluZ0VmZm9ydHMobmFtZTogc3RyaW5nKTogUmVhc29uaW5nRWZmb3J0W10ge1xuICByZXR1cm4gcmVhc29uaW5nRWZmb3J0TmFtZXNCeUZhbWlseShuYW1lKTtcbn1cbiJdfQ==
16
+ /** Return whether Rust policy verifies a complete tool-calling round trip. */
17
+ export function modelSupportsTools(name) {
18
+ return supportsToolsByFamilyWithRust(name);
19
+ }
20
+ /** Return whether a discovered endpoint can be used for a tool-calling chat. */
21
+ export function endpointSupportsTools(endpoint) {
22
+ const embedding = endpoint.task === "llm/v1/embeddings" || endpoint.class === model.ModelClass.Embedding;
23
+ const chat = !embedding && (endpoint.task === "llm/v1/chat" || endpoint.class !== undefined);
24
+ return chat && (endpoint.supportsTools ?? modelSupportsTools(endpoint.name));
25
+ }
26
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9saWN5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3BvbGljeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBRUgsT0FBTyxFQUNMLFdBQVcsSUFBSSxtQkFBbUIsRUFDbEMsNEJBQTRCLEVBQzVCLHFCQUFxQixJQUFJLDZCQUE2QixHQUN2RCxNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sRUFDTCxLQUFLLEVBQ0wscUJBQXFCLEdBR3RCLE1BQU0seUJBQXlCLENBQUM7QUFFakMseUVBQXlFO0FBQ3pFLE1BQU0sVUFBVSxXQUFXLENBQUMsSUFBWTtJQUN0QyxPQUFPLG1CQUFtQixDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ25DLENBQUM7QUFFRCwrREFBK0Q7QUFDL0QsTUFBTSxVQUFVLHFCQUFxQixDQUFDLElBQVk7SUFDaEQsT0FBTyxxQkFBcUIsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxLQUFLLENBQUMsNEJBQTRCLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztBQUNqRixDQUFDO0FBRUQsOEVBQThFO0FBQzlFLE1BQU0sVUFBVSxrQkFBa0IsQ0FBQyxJQUFZO0lBQzdDLE9BQU8sNkJBQTZCLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDN0MsQ0FBQztBQUVELGdGQUFnRjtBQUNoRixNQUFNLFVBQVUscUJBQXFCLENBQUMsUUFBZ0M7SUFDcEUsTUFBTSxTQUFTLEdBQ2IsUUFBUSxDQUFDLElBQUksS0FBSyxtQkFBbUIsSUFBSSxRQUFRLENBQUMsS0FBSyxLQUFLLEtBQUssQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDO0lBQ3pGLE1BQU0sSUFBSSxHQUFHLENBQUMsU0FBUyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksS0FBSyxhQUFhLElBQUksUUFBUSxDQUFDLEtBQUssS0FBSyxTQUFTLENBQUMsQ0FBQztJQUM3RixPQUFPLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLElBQUksa0JBQWtCLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7QUFDL0UsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQnJvd3Nlci1zYWZlIG1vZGVsIG1ldGFkYXRhIHByb2plY3RlZCBmcm9tIHRoZSBSdXN0IHBvbGljeSBiaW5kaW5ncy5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHtcbiAgbW9kZWxGYW1pbHkgYXMgbW9kZWxGYW1pbHlXaXRoUnVzdCxcbiAgcmVhc29uaW5nRWZmb3J0TmFtZXNCeUZhbWlseSxcbiAgc3VwcG9ydHNUb29sc0J5RmFtaWx5IGFzIHN1cHBvcnRzVG9vbHNCeUZhbWlseVdpdGhSdXN0LFxufSBmcm9tIFwiQGRieC10b29scy9tb2RlbC1yc1wiO1xuaW1wb3J0IHtcbiAgbW9kZWwsXG4gIFJlYXNvbmluZ0VmZm9ydFNjaGVtYSxcbiAgdHlwZSBSZWFzb25pbmdFZmZvcnQsXG4gIHR5cGUgU2VydmluZ0VuZHBvaW50U3VtbWFyeSxcbn0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLW1vZGVsXCI7XG5cbi8qKiBSZXR1cm4gdGhlIG5vcm1hbGl6ZWQgZmFtaWx5IHBhcnNlZCBieSB0aGUgUnVzdCBtb2RlbC1uYW1lIHBvbGljeS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtb2RlbEZhbWlseShuYW1lOiBzdHJpbmcpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICByZXR1cm4gbW9kZWxGYW1pbHlXaXRoUnVzdChuYW1lKTtcbn1cblxuLyoqIFJldHVybiB0aGUgcmVhc29uaW5nIGVmZm9ydHMgYWNjZXB0ZWQgYnkgYSBtb2RlbCBmYW1pbHkuICovXG5leHBvcnQgZnVuY3Rpb24gbW9kZWxSZWFzb25pbmdFZmZvcnRzKG5hbWU6IHN0cmluZyk6IFJlYXNvbmluZ0VmZm9ydFtdIHtcbiAgcmV0dXJuIFJlYXNvbmluZ0VmZm9ydFNjaGVtYS5hcnJheSgpLnBhcnNlKHJlYXNvbmluZ0VmZm9ydE5hbWVzQnlGYW1pbHkobmFtZSkpO1xufVxuXG4vKiogUmV0dXJuIHdoZXRoZXIgUnVzdCBwb2xpY3kgdmVyaWZpZXMgYSBjb21wbGV0ZSB0b29sLWNhbGxpbmcgcm91bmQgdHJpcC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtb2RlbFN1cHBvcnRzVG9vbHMobmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBzdXBwb3J0c1Rvb2xzQnlGYW1pbHlXaXRoUnVzdChuYW1lKTtcbn1cblxuLyoqIFJldHVybiB3aGV0aGVyIGEgZGlzY292ZXJlZCBlbmRwb2ludCBjYW4gYmUgdXNlZCBmb3IgYSB0b29sLWNhbGxpbmcgY2hhdC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbmRwb2ludFN1cHBvcnRzVG9vbHMoZW5kcG9pbnQ6IFNlcnZpbmdFbmRwb2ludFN1bW1hcnkpOiBib29sZWFuIHtcbiAgY29uc3QgZW1iZWRkaW5nID1cbiAgICBlbmRwb2ludC50YXNrID09PSBcImxsbS92MS9lbWJlZGRpbmdzXCIgfHwgZW5kcG9pbnQuY2xhc3MgPT09IG1vZGVsLk1vZGVsQ2xhc3MuRW1iZWRkaW5nO1xuICBjb25zdCBjaGF0ID0gIWVtYmVkZGluZyAmJiAoZW5kcG9pbnQudGFzayA9PT0gXCJsbG0vdjEvY2hhdFwiIHx8IGVuZHBvaW50LmNsYXNzICE9PSB1bmRlZmluZWQpO1xuICByZXR1cm4gY2hhdCAmJiAoZW5kcG9pbnQuc3VwcG9ydHNUb29scyA/PyBtb2RlbFN1cHBvcnRzVG9vbHMoZW5kcG9pbnQubmFtZSkpO1xufVxuIl19
@@ -20,7 +20,7 @@
20
20
  * @module
21
21
  */
22
22
  import { model, type ModelQuery, type RankedModel, type ServingEndpointSummary } from "@dbx-tools/shared-model";
23
- import { type ResolvedModel, type ResolveModelOptions, type WorkspaceClientLike } from "./serving.ts";
23
+ import { type ResolvedModel, type ResolveModelOptions, type WorkspaceClientLike } from "./model-catalog.ts";
24
24
  type ModelClass = model.ModelClass;
25
25
  /** Caller intent passed to {@link resolveModel}. */
26
26
  export interface ResolveModelInput {
@@ -36,7 +36,7 @@ export interface ResolveModelInput {
36
36
  * doesn't exist).
37
37
  */
38
38
  fuzzy?: boolean;
39
- /** Fuse.js threshold forwarded to the fuzzy `search` match ({@link searchServingEndpoints}). */
39
+ /** Rust fuzzy-distance threshold forwarded to the search match. */
40
40
  threshold?: number;
41
41
  /** Require a model that supports a complete function-tool round-trip. */
42
42
  requiresTools?: boolean;
@@ -69,11 +69,15 @@ export interface ResolvedModelSelection {
69
69
  export interface SelectModelInput extends ResolveModelInput {
70
70
  /** TTL override for the cached `/serving-endpoints` listing, in ms. */
71
71
  ttlMs?: number;
72
+ /** Trusted opaque identity of the credential used by the workspace client. */
73
+ cacheIdentity?: string;
72
74
  }
73
75
  /** TTL override merged into a {@link ModelQuery} for {@link searchModels}. */
74
76
  export interface SearchModelsInput extends ModelQuery {
75
77
  /** TTL override for the cached `/serving-endpoints` listing, in ms. */
76
78
  ttlMs?: number;
79
+ /** Trusted opaque identity of the credential used by the workspace client. */
80
+ cacheIdentity?: string;
77
81
  }
78
82
  /**
79
83
  * Rank the live catalogue against a {@link ModelQuery}, best-first.
@@ -89,10 +93,10 @@ export declare function lookupModels(endpoints: readonly ServingEndpointSummary[
89
93
  * in a catalogue snapshot, or the input verbatim when nothing scores within the
90
94
  * threshold.
91
95
  *
92
- * The rank-based counterpart to the Fuse-only {@link resolveModelId}: equal
96
+ * The ranked counterpart to {@link resolveModelId}: equal
93
97
  * match scores are broken by class and then within-class version, so a loose
94
98
  * `"opus"` prefers `opus-5` over `opus-4-7` instead of picking whichever
95
- * sibling Fuse happened to order first. Returning the input unmatched (rather
99
+ * sibling appeared first. Returning the input unmatched (rather
96
100
  * than a near neighbour) is deliberate - a deliberate endpoint id is never
97
101
  * silently rewritten, and Databricks surfaces a clean 404.
98
102
  */
@@ -20,18 +20,12 @@
20
20
  * @module
21
21
  */
22
22
  import { object } from "@dbx-tools/shared-core";
23
- import { ModelClass as ModelRsModelClass, rankModels as rankModelsWithRust, } from "@dbx-tools/model-rs";
24
- import { classify, model, } from "@dbx-tools/shared-model";
23
+ import { rankEndpoints } from "./_native.js";
25
24
  import { FALLBACK_MODEL_IDS, modelsForClass } from "./fallback.js";
26
- import { listServingEndpoints, } from "./serving.js";
25
+ import { listServingEndpoints, } from "./model-catalog.js";
26
+ import { endpointSupportsTools } from "./policy.js";
27
27
  /** Preferred live family for an unconfigured general-purpose chat default. */
28
28
  const DEFAULT_MODEL_FAMILY_SEARCH = "gpt";
29
- const MODEL_CLASS_TO_RS = {
30
- [model.ModelClass.ChatThinking]: ModelRsModelClass.ChatThinking,
31
- [model.ModelClass.ChatBalanced]: ModelRsModelClass.ChatBalanced,
32
- [model.ModelClass.ChatFast]: ModelRsModelClass.ChatFast,
33
- [model.ModelClass.Embedding]: ModelRsModelClass.Embedding,
34
- };
35
29
  /**
36
30
  * Rank the live catalogue against a {@link ModelQuery}, best-first.
37
31
  *
@@ -41,69 +35,17 @@ const MODEL_CLASS_TO_RS = {
41
35
  * available unchanged.
42
36
  */
43
37
  export function lookupModels(endpoints, query = {}) {
44
- const endpointsByName = new Map(endpoints.map((endpoint) => [endpoint.name, endpoint]));
45
- return rankModelsWithRust(endpoints.map(toModelRsEndpoint), toModelRsQuery(query)).map((ranked) => {
46
- const endpoint = endpointsByName.get(ranked.endpoint.name);
47
- if (!endpoint) {
48
- throw new Error(`Rust model ranking returned unknown endpoint "${ranked.endpoint.name}"`);
49
- }
50
- return {
51
- endpoint,
52
- modelClass: fromModelRsClass(ranked.modelClass),
53
- ...(ranked.score !== undefined ? { score: ranked.score } : {}),
54
- };
55
- });
56
- }
57
- /** Convert a public model query to the generated Rust ranking contract. */
58
- function toModelRsQuery(query) {
59
- return {
60
- search: query.search,
61
- modelClass: query.modelClass === undefined ? undefined : MODEL_CLASS_TO_RS[query.modelClass],
62
- requiresTools: query.requiresTools ?? false,
63
- includeDeprecated: false,
64
- limit: query.limit,
65
- threshold: query.threshold,
66
- };
67
- }
68
- /** Convert a discovered endpoint to the generated Rust ranking contract. */
69
- function toModelRsEndpoint(endpoint) {
70
- return {
71
- name: endpoint.name,
72
- displayName: endpoint.displayName,
73
- task: endpoint.task,
74
- state: endpoint.state,
75
- description: endpoint.description,
76
- supportsTools: endpoint.supportsTools,
77
- profile: endpoint.profile,
78
- modelClass: endpoint.class === undefined ? undefined : MODEL_CLASS_TO_RS[endpoint.class],
79
- serviceNames: new Map(Object.entries(endpoint.serviceNames ?? {})),
80
- modelServiceName: endpoint.modelServiceName,
81
- reasoningEfforts: [],
82
- status: { deprecated: endpoint.status?.deprecated ?? false },
83
- };
84
- }
85
- /** Convert a generated Rust class to the browser-safe public enum. */
86
- function fromModelRsClass(modelClass) {
87
- switch (modelClass) {
88
- case ModelRsModelClass.ChatThinking:
89
- return model.ModelClass.ChatThinking;
90
- case ModelRsModelClass.ChatBalanced:
91
- return model.ModelClass.ChatBalanced;
92
- case ModelRsModelClass.ChatFast:
93
- return model.ModelClass.ChatFast;
94
- case ModelRsModelClass.Embedding:
95
- return model.ModelClass.Embedding;
96
- }
38
+ return rankEndpoints(endpoints, query);
97
39
  }
98
40
  /**
99
41
  * Collapse {@link lookupModels} to a single id: the closest endpoint to `search`
100
42
  * in a catalogue snapshot, or the input verbatim when nothing scores within the
101
43
  * threshold.
102
44
  *
103
- * The rank-based counterpart to the Fuse-only {@link resolveModelId}: equal
45
+ * The ranked counterpart to {@link resolveModelId}: equal
104
46
  * match scores are broken by class and then within-class version, so a loose
105
47
  * `"opus"` prefers `opus-5` over `opus-4-7` instead of picking whichever
106
- * sibling Fuse happened to order first. Returning the input unmatched (rather
48
+ * sibling appeared first. Returning the input unmatched (rather
107
49
  * than a near neighbour) is deliberate - a deliberate endpoint id is never
108
50
  * silently rewritten, and Databricks surfaces a clean 404.
109
51
  */
@@ -149,7 +91,10 @@ export async function rankModelIdLive(load, search, options = {}) {
149
91
  * from `client.config.getHost()`.
150
92
  */
151
93
  export async function searchModels(client, host, input = {}) {
152
- const endpoints = await listServingEndpoints(client, host, input.ttlMs !== undefined ? { ttlMs: input.ttlMs } : {});
94
+ const endpoints = await listServingEndpoints(client, host, {
95
+ ...(input.ttlMs !== undefined ? { ttlMs: input.ttlMs } : {}),
96
+ ...(input.cacheIdentity !== undefined ? { cacheIdentity: input.cacheIdentity } : {}),
97
+ });
153
98
  return lookupModels(endpoints, input);
154
99
  }
155
100
  /**
@@ -172,6 +117,7 @@ export async function selectModel(client, host, input = {}) {
172
117
  }
173
118
  const endpoints = await listServingEndpoints(client, host, {
174
119
  ...(input.ttlMs !== undefined ? { ttlMs: input.ttlMs } : {}),
120
+ ...(input.cacheIdentity !== undefined ? { cacheIdentity: input.cacheIdentity } : {}),
175
121
  });
176
122
  return resolveModel(endpoints, input);
177
123
  }
@@ -205,7 +151,7 @@ export function resolveModel(endpoints, input = {}) {
205
151
  // workspace restricted to an approved subset).
206
152
  if (input.modelClass === undefined && input.fallbacks && input.fallbacks.length > 0) {
207
153
  const present = new Set(endpoints
208
- .filter((endpoint) => !input.requiresTools || classify.endpointCapabilities(endpoint).tools)
154
+ .filter((endpoint) => !input.requiresTools || endpointSupportsTools(endpoint))
209
155
  .map((endpoint) => endpoint.name));
210
156
  const pinned = input.fallbacks.find((id) => present.has(id));
211
157
  if (pinned)
@@ -227,9 +173,7 @@ export function resolveModel(endpoints, input = {}) {
227
173
  const floorSource = input.modelClass !== undefined ? modelsForClass(input.modelClass) : (input.fallbacks ?? []);
228
174
  const floor = object.sequence(floorSource).concat(FALLBACK_MODEL_IDS).distinct().toArray();
229
175
  if (input.requiresTools) {
230
- const available = new Set(endpoints
231
- .filter((endpoint) => classify.endpointCapabilities(endpoint).tools)
232
- .map((endpoint) => endpoint.name));
176
+ const available = new Set(endpoints.filter(endpointSupportsTools).map((endpoint) => endpoint.name));
233
177
  const selected = floor.find((id) => available.has(id));
234
178
  if (!selected)
235
179
  throw new Error("No tool-capable model is available");
@@ -250,7 +194,7 @@ function buildQuery(input, search) {
250
194
  /** Throw when an explicit id is absent or not verified for function tools. */
251
195
  function assertToolSupport(endpoints, modelId) {
252
196
  const endpoint = endpoints.find((candidate) => candidate.name === modelId);
253
- if (!endpoint || !classify.endpointCapabilities(endpoint).tools) {
197
+ if (!endpoint || !endpointSupportsTools(endpoint)) {
254
198
  throw new Error(`Model "${modelId}" does not support function tools`);
255
199
  }
256
200
  }
@@ -268,4 +212,4 @@ function pickFirstAvailable(candidates, endpoints) {
268
212
  }
269
213
  return candidates[0] ?? FALLBACK_MODEL_IDS[0];
270
214
  }
271
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzb2x2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yZXNvbHZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9CRztBQUVILE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNoRCxPQUFPLEVBQ0wsVUFBVSxJQUFJLGlCQUFpQixFQUMvQixVQUFVLElBQUksa0JBQWtCLEdBR2pDLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUNMLFFBQVEsRUFDUixLQUFLLEdBSU4sTUFBTSx5QkFBeUIsQ0FBQztBQUVqQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsY0FBYyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25FLE9BQU8sRUFDTCxvQkFBb0IsR0FLckIsTUFBTSxjQUFjLENBQUM7QUFJdEIsOEVBQThFO0FBQzlFLE1BQU0sMkJBQTJCLEdBQUcsS0FBSyxDQUFDO0FBRTFDLE1BQU0saUJBQWlCLEdBQW9EO0lBQ3pFLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsRUFBRSxpQkFBaUIsQ0FBQyxZQUFZO0lBQy9ELENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsRUFBRSxpQkFBaUIsQ0FBQyxZQUFZO0lBQy9ELENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsRUFBRSxpQkFBaUIsQ0FBQyxRQUFRO0lBQ3ZELENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsRUFBRSxpQkFBaUIsQ0FBQyxTQUFTO0NBQzFELENBQUM7QUEyREY7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxZQUFZLENBQzFCLFNBQTRDLEVBQzVDLFFBQW9CLEVBQUU7SUFFdEIsTUFBTSxlQUFlLEdBQUcsSUFBSSxHQUFHLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQyxRQUFRLENB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LFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ3RELEtBQUssTUFBTSxTQUFTLElBQUksVUFBVSxFQUFFLENBQUM7UUFDbkMsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQztZQUFFLE9BQU8sU0FBUyxDQUFDO0lBQy9DLENBQUM7SUFDRCxPQUFPLFVBQVUsQ0FBQyxDQUFDLENBQUMsSUFBSSxrQkFBa0IsQ0FBQyxDQUFDLENBQUUsQ0FBQztBQUNqRCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBXb3Jrc3BhY2UtYXdhcmUgbW9kZWwgc2VsZWN0aW9uLlxuICpcbiAqIEdpdmVuIGEgY2FsbGVyJ3MgaW50ZW50IC0gYSBzZWFyY2ggc3RyaW5nLCBhIGNhcGFiaWxpdHkge0BsaW5rIE1vZGVsQ2xhc3N9XG4gKiBjZWlsaW5nLCBib3RoLCBvciBub3RoaW5nIC0gdGhlIHRvb2xraXQgcmV0dXJucyBtYXRjaGluZyBlbmRwb2ludHMgcmFua2VkIGJ5XG4gKiBtYXRjaCBxdWFsaXR5IHRoZW4gY2xhc3MsIG9yIGNvbGxhcHNlcyB0byB0aGUgc2luZ2xlIGJlc3QgaWQgdGhlIHdvcmtzcGFjZVxuICogYWN0dWFsbHkgaGFzLCBkZWdyYWRpbmcgZnJvbSBcImJlc3QgaW4gcmFuZ2VcIiBkb3duIHRvIHRoZSBzdGF0aWMgZmFsbGJhY2tcbiAqIGZsb29yLiBTZWxlY3Rpb24gaXMgY2hhdC1vbmx5OiBlbWJlZGRpbmcgZW5kcG9pbnRzIHN1cmZhY2Ugb25seSB3aGVuXG4gKiBgbW9kZWxDbGFzc2AgaXMgZXhwbGljaXRseSB7QGxpbmsgTW9kZWxDbGFzcy5FbWJlZGRpbmd9LlxuICpcbiAqIFR3byBzaGFwZXMgb2Ygc2VsZWN0aW9uLCBlYWNoIGluIGEgcHVyZSBmb3JtIChvdmVyIGFuIGVuZHBvaW50IGxpc3QgdGhlXG4gKiBjYWxsZXIgYWxyZWFkeSBob2xkcykgYW5kIGFuIEkvTyB3cmFwcGVyICh0aGF0IGxpc3RzIGAvc2VydmluZy1lbmRwb2ludHNgXG4gKiBmaXJzdCk6IHJhbmtpbmcsIHdoaWNoIHJldHVybnMgYSBtYXRjaC0gdGhlbiBjbGFzcy1vcmRlcmVkIGxpc3QsIGFuZFxuICogc2luZ2xlLXNlbGVjdGlvbiwgd2hpY2ggY29sbGFwc2VzIHRvIG9uZSBpZCBwbHVzIGhvdyBpdCB3YXMgcmVhY2hlZCBhbmRcbiAqIGxheWVycyB0aGUgb3BlcmF0b3ItcGlubmVkIGZhbGxiYWNrIC8gc3RhdGljLWZsb29yIHNhZmV0eSBuZXQgb24gdG9wLiBBIGNoYXRcbiAqIGBtb2RlbENsYXNzYCBhY3RzIGFzIGEgY2VpbGluZzogdGhhdCBiYW5kIGFuZCB0aGUgbGVzcy1jYXBhYmxlIGNoYXQgYmFuZHNcbiAqIGJlbG93IGl0IGFyZSBlbGlnaWJsZSAoc2VlIHtAbGluayBjbGFzc2VzQXRPckJlbG93fSksIHNvIGEgYGNoYXQtYmFsYW5jZWRgXG4gKiBhc2sgY2FuIGZhbGwgdG8gYGNoYXQtZmFzdGAgYnV0IG5ldmVyIGVzY2FsYXRlIHRvIGBjaGF0LXRoaW5raW5nYC5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgb2JqZWN0IH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB7XG4gIE1vZGVsQ2xhc3MgYXMgTW9kZWxSc01vZGVsQ2xhc3MsXG4gIHJhbmtNb2RlbHMgYXMgcmFua01vZGVsc1dpdGhSdXN0LFxuICB0eXBlIE1vZGVsUXVlcnkgYXMgTW9kZWxSc01vZGVsUXVlcnksXG4gIHR5cGUgU2VydmluZ0VuZHBvaW50U3VtbWFyeSBhcyBNb2RlbFJzU2VydmluZ0VuZHBvaW50U3VtbWFyeSxcbn0gZnJvbSBcIkBkYngtdG9vbHMvbW9kZWwtcnNcIjtcbmltcG9ydCB7XG4gIGNsYXNzaWZ5LFxuICBtb2RlbCxcbiAgdHlwZSBNb2RlbFF1ZXJ5LFxuICB0eXBlIFJhbmtlZE1vZGVsLFxuICB0eXBlIFNlcnZpbmdFbmRwb2ludFN1bW1hcnksXG59IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1tb2RlbFwiO1xuXG5pbXBvcnQgeyBGQUxMQkFDS19NT0RFTF9JRFMsIG1vZGVsc0ZvckNsYXNzIH0gZnJvbSBcIi4vZmFsbGJhY2sudHNcIjtcbmltcG9ydCB7XG4gIGxpc3RTZXJ2aW5nRW5kcG9pbnRzLFxuICBzZWFyY2hTZXJ2aW5nRW5kcG9pbnRzLFxuICB0eXBlIFJlc29sdmVkTW9kZWwsXG4gIHR5cGUgUmVzb2x2ZU1vZGVsT3B0aW9ucyxcbiAgdHlwZSBXb3Jrc3BhY2VDbGllbnRMaWtlLFxufSBmcm9tIFwiLi9zZXJ2aW5nLnRzXCI7XG5cbnR5cGUgTW9kZWxDbGFzcyA9IG1vZGVsLk1vZGVsQ2xhc3M7XG5cbi8qKiBQcmVmZXJyZWQgbGl2ZSBmYW1pbHkgZm9yIGFuIHVuY29uZmlndXJlZCBnZW5lcmFsLXB1cnBvc2UgY2hhdCBkZWZhdWx0LiAqL1xuY29uc3QgREVGQVVMVF9NT0RFTF9GQU1JTFlfU0VBUkNIID0gXCJncHRcIjtcblxuY29uc3QgTU9ERUxfQ0xBU1NfVE9fUlM6IFJlYWRvbmx5PFJlY29yZDxNb2RlbENsYXNzLCBNb2RlbFJzTW9kZWxDbGFzcz4+ID0ge1xuICBbbW9kZWwuTW9kZWxDbGFzcy5DaGF0VGhpbmtpbmddOiBNb2RlbFJzTW9kZWxDbGFzcy5DaGF0VGhpbmtpbmcsXG4gIFttb2RlbC5Nb2RlbENsYXNzLkNoYXRCYWxhbmNlZF06IE1vZGVsUnNNb2RlbENsYXNzLkNoYXRCYWxhbmNlZCxcbiAgW21vZGVsLk1vZGVsQ2xhc3MuQ2hhdEZhc3RdOiBNb2RlbFJzTW9kZWxDbGFzcy5DaGF0RmFzdCxcbiAgW21vZGVsLk1vZGVsQ2xhc3MuRW1iZWRkaW5nXTogTW9kZWxSc01vZGVsQ2xhc3MuRW1iZWRkaW5nLFxufTtcblxuLyoqIENhbGxlciBpbnRlbnQgcGFzc2VkIHRvIHtAbGluayByZXNvbHZlTW9kZWx9LiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXNvbHZlTW9kZWxJbnB1dCB7XG4gIC8qKlxuICAgKiBFeHBsaWNpdCBtb2RlbCBpZCAvIGxvb3NlIG5hbWUgKHBlci1yZXF1ZXN0IG92ZXJyaWRlLCBhZ2VudCAvIHBsdWdpblxuICAgKiBkZWZhdWx0LCBvciBlbnYgdmFyKS4gV2hlbiBzZXQgaXQgd2lucyBvdmVyIGBtb2RlbENsYXNzYCBhbmQgYGZhbGxiYWNrc2AuXG4gICAqL1xuICBleHBsaWNpdD86IHN0cmluZztcbiAgLyoqXG4gICAqIEZ1enp5LW1hdGNoIGFuIGBleHBsaWNpdGAgbmFtZSBhZ2FpbnN0IHRoZSBsaXZlIGNhdGFsb2d1ZSBzbyBsb29zZSBuYW1lc1xuICAgKiBsaWtlIGBcImNsYXVkZSBzb25uZXRcImAgcmVzb2x2ZS4gRGVmYXVsdCBgdHJ1ZWAuIFdoZW4gYGZhbHNlYCB0aGUgZXhwbGljaXRcbiAgICogaW5wdXQgaXMgcmV0dXJuZWQgdmVyYmF0aW0gKERhdGFicmlja3Mgc3VyZmFjZXMgdGhlIGNhbm9uaWNhbCA0MDQgaWYgaXRcbiAgICogZG9lc24ndCBleGlzdCkuXG4gICAqL1xuICBmdXp6eT86IGJvb2xlYW47XG4gIC8qKiBGdXNlLmpzIHRocmVzaG9sZCBmb3J3YXJkZWQgdG8gdGhlIGZ1enp5IGBzZWFyY2hgIG1hdGNoICh7QGxpbmsgc2VhcmNoU2VydmluZ0VuZHBvaW50c30pLiAqL1xuICB0aHJlc2hvbGQ/OiBudW1iZXI7XG4gIC8qKiBSZXF1aXJlIGEgbW9kZWwgdGhhdCBzdXBwb3J0cyBhIGNvbXBsZXRlIGZ1bmN0aW9uLXRvb2wgcm91bmQtdHJpcC4gKi9cbiAgcmVxdWlyZXNUb29scz86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBDaGF0IGNhcGFiaWxpdHkgY2xhc3MgdG8gcmVzb2x2ZSB3aGVuIG5vIGBleHBsaWNpdGAgaWQgaXMgZ2l2ZW4uIFRoZSBsaXZlXG4gICAqIGNhdGFsb2d1ZSBpcyBjbGFzc2lmaWVkIGJ5IGl0cyBGb3VuZGF0aW9uIE1vZGVsIEFQSSBzY29yZXMgYW5kIHRoZSB0b3BcbiAgICogYXZhaWxhYmxlIG1vZGVsIGluIHRoZSBjbGFzcyAoYW5kIHRoZSBjaGF0IGJhbmRzIGJlbG93IGl0KSB3aW5zLCBmYWxsaW5nXG4gICAqIGJhY2sgdG8gdGhlIGNsYXNzJ3Mgc21hbGwgc3RhdGljIGxpc3QuXG4gICAqL1xuICBtb2RlbENsYXNzPzogTW9kZWxDbGFzcztcbiAgLyoqXG4gICAqIE9wZXJhdG9yLXN1cHBsaWVkIGZhbGxiYWNrIGlkcyB0cmllZCAqZmlyc3QqIGluIHRoZSBuby1leHBsaWNpdCwgbm8tY2xhc3NcbiAgICogcGF0aCAoZS5nLiBhIHJlZ3VsYXRlZCB3b3Jrc3BhY2UgcGlubmVkIHRvIGFuIGFwcHJvdmVkIHN1YnNldCksIGFoZWFkIG9mXG4gICAqIHRoZSBhdXRvLWNsYXNzaWZpZWQgY2F0YWxvZ3VlLlxuICAgKi9cbiAgZmFsbGJhY2tzPzogcmVhZG9ubHkgc3RyaW5nW107XG4gIC8qKlxuICAgKiBSZWZ1c2UgdGhlIHN0YXRpYyBvZmZsaW5lIGZsb29yIHdoZW4gdGhlIGxpdmUgY2F0YWxvZ3VlIGhhcyBubyBtYXRjaC5cbiAgICogVXNlIGZvciB1bnBpbm5lZCBkZWZhdWx0cyB0aGF0IG11c3QgYWx3YXlzIG5hbWUgYSBjdXJyZW50bHkgYXZhaWxhYmxlXG4gICAqIGVuZHBvaW50LlxuICAgKi9cbiAgbGl2ZU9ubHk/OiBib29sZWFuO1xufVxuXG4vKiogT3V0Y29tZSBvZiB7QGxpbmsgcmVzb2x2ZU1vZGVsfTogdGhlIGNob3NlbiBpZCBwbHVzIGhvdyBpdCB3YXMgcmVhY2hlZC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb2x2ZWRNb2RlbFNlbGVjdGlvbiB7XG4gIG1vZGVsSWQ6IHN0cmluZztcbiAgc291cmNlOiBcImV4cGxpY2l0XCIgfCBcImZ1enp5LW1hdGNoXCIgfCBcImNsYXNzXCIgfCBcImZhbGxiYWNrXCI7XG59XG5cbi8qKiBJbnRlbnQgKyBjYXRhbG9ndWUga25vYnMgcGFzc2VkIHRvIHtAbGluayBzZWxlY3RNb2RlbH0uICovXG5leHBvcnQgaW50ZXJmYWNlIFNlbGVjdE1vZGVsSW5wdXQgZXh0ZW5kcyBSZXNvbHZlTW9kZWxJbnB1dCB7XG4gIC8qKiBUVEwgb3ZlcnJpZGUgZm9yIHRoZSBjYWNoZWQgYC9zZXJ2aW5nLWVuZHBvaW50c2AgbGlzdGluZywgaW4gbXMuICovXG4gIHR0bE1zPzogbnVtYmVyO1xufVxuXG4vKiogVFRMIG92ZXJyaWRlIG1lcmdlZCBpbnRvIGEge0BsaW5rIE1vZGVsUXVlcnl9IGZvciB7QGxpbmsgc2VhcmNoTW9kZWxzfS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2VhcmNoTW9kZWxzSW5wdXQgZXh0ZW5kcyBNb2RlbFF1ZXJ5IHtcbiAgLyoqIFRUTCBvdmVycmlkZSBmb3IgdGhlIGNhY2hlZCBgL3NlcnZpbmctZW5kcG9pbnRzYCBsaXN0aW5nLCBpbiBtcy4gKi9cbiAgdHRsTXM/OiBudW1iZXI7XG59XG5cbi8qKlxuICogUmFuayB0aGUgbGl2ZSBjYXRhbG9ndWUgYWdhaW5zdCBhIHtAbGluayBNb2RlbFF1ZXJ5fSwgYmVzdC1maXJzdC5cbiAqXG4gKiBSdXN0IG93bnMgY2xhc3NpZmljYXRpb24sIGZ1enp5IHNjb3JpbmcsIGZhbWlseS12ZXJzaW9uIG9yZGVyaW5nLCBwcmVmZXJyZWRcbiAqIHZhcmlhbnRzLCBjbGFzcyBjZWlsaW5ncywgdG9vbCBmaWx0ZXJpbmcsIGFuZCByZXN1bHQgbGltaXRpbmcuIE5vZGUgcmV0YWluc1xuICogdGhlIGNhbGxlcidzIGVuZHBvaW50IG9iamVjdHMgc28gZmllbGRzIG91dHNpZGUgdGhlIHJhbmtpbmcgY29udHJhY3QgcmVtYWluXG4gKiBhdmFpbGFibGUgdW5jaGFuZ2VkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbG9va3VwTW9kZWxzKFxuICBlbmRwb2ludHM6IHJlYWRvbmx5IFNlcnZpbmdFbmRwb2ludFN1bW1hcnlbXSxcbiAgcXVlcnk6IE1vZGVsUXVlcnkgPSB7fSxcbik6IFJhbmtlZE1vZGVsW10ge1xuICBjb25zdCBlbmRwb2ludHNCeU5hbWUgPSBuZXcgTWFwKGVuZHBvaW50cy5tYXAoKGVuZHBvaW50KSA9PiBbZW5kcG9pbnQubmFtZSwgZW5kcG9pbnRdKSk7XG4gIHJldHVybiByYW5rTW9kZWxzV2l0aFJ1c3QoZW5kcG9pbnRzLm1hcCh0b01vZGVsUnNFbmRwb2ludCksIHRvTW9kZWxSc1F1ZXJ5KHF1ZXJ5KSkubWFwKFxuICAgIChyYW5rZWQpID0+IHtcbiAgICAgIGNvbnN0IGVuZHBvaW50ID0gZW5kcG9pbnRzQnlOYW1lLmdldChyYW5rZWQuZW5kcG9pbnQubmFtZSk7XG4gICAgICBpZiAoIWVuZHBvaW50KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgUnVzdCBtb2RlbCByYW5raW5nIHJldHVybmVkIHVua25vd24gZW5kcG9pbnQgXCIke3JhbmtlZC5lbmRwb2ludC5uYW1lfVwiYCk7XG4gICAgICB9XG4gICAgICByZXR1cm4ge1xuICAgICAgICBlbmRwb2ludCxcbiAgICAgICAgbW9kZWxDbGFzczogZnJvbU1vZGVsUnNDbGFzcyhyYW5rZWQubW9kZWxDbGFzcyksXG4gICAgICAgIC4uLihyYW5rZWQuc2NvcmUgIT09IHVuZGVmaW5lZCA/IHsgc2NvcmU6IHJhbmtlZC5zY29yZSB9IDoge30pLFxuICAgICAgfTtcbiAgICB9LFxuICApO1xufVxuXG4vKiogQ29udmVydCBhIHB1YmxpYyBtb2RlbCBxdWVyeSB0byB0aGUgZ2VuZXJhdGVkIFJ1c3QgcmFua2luZyBjb250cmFjdC4gKi9cbmZ1bmN0aW9uIHRvTW9kZWxSc1F1ZXJ5KHF1ZXJ5OiBNb2RlbFF1ZXJ5KTogTW9kZWxSc01vZGVsUXVlcnkge1xuICByZXR1cm4ge1xuICAgIHNlYXJjaDogcXVlcnkuc2VhcmNoLFxuICAgIG1vZGVsQ2xhc3M6IHF1ZXJ5Lm1vZGVsQ2xhc3MgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IE1PREVMX0NMQVNTX1RPX1JTW3F1ZXJ5Lm1vZGVsQ2xhc3NdLFxuICAgIHJlcXVpcmVzVG9vbHM6IHF1ZXJ5LnJlcXVpcmVzVG9vbHMgPz8gZmFsc2UsXG4gICAgaW5jbHVkZURlcHJlY2F0ZWQ6IGZhbHNlLFxuICAgIGxpbWl0OiBxdWVyeS5saW1pdCxcbiAgICB0aHJlc2hvbGQ6IHF1ZXJ5LnRocmVzaG9sZCxcbiAgfTtcbn1cblxuLyoqIENvbnZlcnQgYSBkaXNjb3ZlcmVkIGVuZHBvaW50IHRvIHRoZSBnZW5lcmF0ZWQgUnVzdCByYW5raW5nIGNvbnRyYWN0LiAqL1xuZnVuY3Rpb24gdG9Nb2RlbFJzRW5kcG9pbnQoZW5kcG9pbnQ6IFNlcnZpbmdFbmRwb2ludFN1bW1hcnkpOiBNb2RlbFJzU2VydmluZ0VuZHBvaW50U3VtbWFyeSB7XG4gIHJldHVybiB7XG4gICAgbmFtZTogZW5kcG9pbnQubmFtZSxcbiAgICBkaXNwbGF5TmFtZTogZW5kcG9pbnQuZGlzcGxheU5hbWUsXG4gICAgdGFzazogZW5kcG9pbnQudGFzayxcbiAgICBzdGF0ZTogZW5kcG9pbnQuc3RhdGUsXG4gICAgZGVzY3JpcHRpb246IGVuZHBvaW50LmRlc2NyaXB0aW9uLFxuICAgIHN1cHBvcnRzVG9vbHM6IGVuZHBvaW50LnN1cHBvcnRzVG9vbHMsXG4gICAgcHJvZmlsZTogZW5kcG9pbnQucHJvZmlsZSxcbiAgICBtb2RlbENsYXNzOiBlbmRwb2ludC5jbGFzcyA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogTU9ERUxfQ0xBU1NfVE9fUlNbZW5kcG9pbnQuY2xhc3NdLFxuICAgIHNlcnZpY2VOYW1lczogbmV3IE1hcChPYmplY3QuZW50cmllcyhlbmRwb2ludC5zZXJ2aWNlTmFtZXMgPz8ge30pKSxcbiAgICBtb2RlbFNlcnZpY2VOYW1lOiBlbmRwb2ludC5tb2RlbFNlcnZpY2VOYW1lLFxuICAgIHJlYXNvbmluZ0VmZm9ydHM6IFtdLFxuICAgIHN0YXR1czogeyBkZXByZWNhdGVkOiBlbmRwb2ludC5zdGF0dXM/LmRlcHJlY2F0ZWQgPz8gZmFsc2UgfSxcbiAgfTtcbn1cblxuLyoqIENvbnZlcnQgYSBnZW5lcmF0ZWQgUnVzdCBjbGFzcyB0byB0aGUgYnJvd3Nlci1zYWZlIHB1YmxpYyBlbnVtLiAqL1xuZnVuY3Rpb24gZnJvbU1vZGVsUnNDbGFzcyhtb2RlbENsYXNzOiBNb2RlbFJzTW9kZWxDbGFzcyk6IE1vZGVsQ2xhc3Mge1xuICBzd2l0Y2ggKG1vZGVsQ2xhc3MpIHtcbiAgICBjYXNlIE1vZGVsUnNNb2RlbENsYXNzLkNoYXRUaGlua2luZzpcbiAgICAgIHJldHVybiBtb2RlbC5Nb2RlbENsYXNzLkNoYXRUaGlua2luZztcbiAgICBjYXNlIE1vZGVsUnNNb2RlbENsYXNzLkNoYXRCYWxhbmNlZDpcbiAgICAgIHJldHVybiBtb2RlbC5Nb2RlbENsYXNzLkNoYXRCYWxhbmNlZDtcbiAgICBjYXNlIE1vZGVsUnNNb2RlbENsYXNzLkNoYXRGYXN0OlxuICAgICAgcmV0dXJuIG1vZGVsLk1vZGVsQ2xhc3MuQ2hhdEZhc3Q7XG4gICAgY2FzZSBNb2RlbFJzTW9kZWxDbGFzcy5FbWJlZGRpbmc6XG4gICAgICByZXR1cm4gbW9kZWwuTW9kZWxDbGFzcy5FbWJlZGRpbmc7XG4gIH1cbn1cblxuLyoqXG4gKiBDb2xsYXBzZSB7QGxpbmsgbG9va3VwTW9kZWxzfSB0byBhIHNpbmdsZSBpZDogdGhlIGNsb3Nlc3QgZW5kcG9pbnQgdG8gYHNlYXJjaGBcbiAqIGluIGEgY2F0YWxvZ3VlIHNuYXBzaG90LCBvciB0aGUgaW5wdXQgdmVyYmF0aW0gd2hlbiBub3RoaW5nIHNjb3JlcyB3aXRoaW4gdGhlXG4gKiB0aHJlc2hvbGQuXG4gKlxuICogVGhlIHJhbmstYmFzZWQgY291bnRlcnBhcnQgdG8gdGhlIEZ1c2Utb25seSB7QGxpbmsgcmVzb2x2ZU1vZGVsSWR9OiBlcXVhbFxuICogbWF0Y2ggc2NvcmVzIGFyZSBicm9rZW4gYnkgY2xhc3MgYW5kIHRoZW4gd2l0aGluLWNsYXNzIHZlcnNpb24sIHNvIGEgbG9vc2VcbiAqIGBcIm9wdXNcImAgcHJlZmVycyBgb3B1cy01YCBvdmVyIGBvcHVzLTQtN2AgaW5zdGVhZCBvZiBwaWNraW5nIHdoaWNoZXZlclxuICogc2libGluZyBGdXNlIGhhcHBlbmVkIHRvIG9yZGVyIGZpcnN0LiBSZXR1cm5pbmcgdGhlIGlucHV0IHVubWF0Y2hlZCAocmF0aGVyXG4gKiB0aGFuIGEgbmVhciBuZWlnaGJvdXIpIGlzIGRlbGliZXJhdGUgLSBhIGRlbGliZXJhdGUgZW5kcG9pbnQgaWQgaXMgbmV2ZXJcbiAqIHNpbGVudGx5IHJld3JpdHRlbiwgYW5kIERhdGFicmlja3Mgc3VyZmFjZXMgYSBjbGVhbiA0MDQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByYW5rTW9kZWxJZChcbiAgZW5kcG9pbnRzOiByZWFkb25seSBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5W10sXG4gIHNlYXJjaDogc3RyaW5nLFxuICBvcHRpb25zOiBSZXNvbHZlTW9kZWxPcHRpb25zID0ge30sXG4pOiBSZXNvbHZlZE1vZGVsIHtcbiAgY29uc3QgW3RvcF0gPSBsb29rdXBNb2RlbHMoZW5kcG9pbnRzLCB7XG4gICAgc2VhcmNoLFxuICAgIGxpbWl0OiAxLFxuICAgIC4uLihvcHRpb25zLnRocmVzaG9sZCAhPT0gdW5kZWZpbmVkID8geyB0aHJlc2hvbGQ6IG9wdGlvbnMudGhyZXNob2xkIH0gOiB7fSksXG4gICAgLi4uKG9wdGlvbnMucmVxdWlyZXNUb29scyAhPT0gdW5kZWZpbmVkID8geyByZXF1aXJlc1Rvb2xzOiBvcHRpb25zLnJlcXVpcmVzVG9vbHMgfSA6IHt9KSxcbiAgfSk7XG4gIGlmICghdG9wKSByZXR1cm4geyBtb2RlbElkOiBzZWFyY2gsIG1hdGNoZWQ6IGZhbHNlIH07XG4gIHJldHVybiB7IG1vZGVsSWQ6IHRvcC5lbmRwb2ludC5uYW1lLCBtYXRjaGVkOiB0cnVlLCBzY29yZTogdG9wLnNjb3JlIH07XG59XG5cbi8qKlxuICoge0BsaW5rIHJhbmtNb2RlbElkfSBhZ2FpbnN0IGEgY2F0YWxvZ3VlIHRoZSBjYWxsZXIgbWF5IGJlIGhvbGRpbmcgc3RhbGU6XG4gKiBtYXRjaCB0aGUgbG9hZGVkIHNuYXBzaG90LCBhbmQgb24gYSBtaXNzIHJlbG9hZCBvbmNlIHdpdGggYGZvcmNlYCBhbmQgbWF0Y2hcbiAqIGFnYWluLiBUaGF0IHdheSBhIG1vZGVsIGRlcGxveWVkIGFmdGVyIHRoZSBjYXRhbG9ndWUgd2FzIGNhY2hlZCBzdGlsbFxuICogcmVzb2x2ZXMgb24gZmlyc3QgdXNlLCB3aXRob3V0IGEgcmVzdGFydCBhbmQgd2l0aG91dCBnaXZpbmcgdXAgY2FjaGluZy5cbiAqXG4gKiBUaGUgY2F0YWxvZ3VlIGFycml2ZXMgYXMgYSBsb2FkZXIgcmF0aGVyIHRoYW4gYSBjbGllbnQgc28gdGhlIGNhbGxlciBrZWVwc1xuICogb3duZXJzaGlwIG9mICpob3cqIGl0IGlzIGNhY2hlZCAtIHtAbGluayBsaXN0U2VydmluZ0VuZHBvaW50c30gYW5kIGl0c1xuICogYENhY2hlTWFuYWdlcmAsIGEgcGxhaW4gcHJvY2Vzcy1saWZldGltZSBmaWVsZCBpbiBhIENMSSwgb3IgYSB0ZXN0IGRvdWJsZS5cbiAqIE9ubHkgb25lIHJlbG9hZCBpcyBhdHRlbXB0ZWQ6IGEgZ2VudWluZWx5IHVua25vd24gbmFtZSBzaG91bGQgZmFpbCBmYXN0XG4gKiByYXRoZXIgdGhhbiByZS1saXN0IG9uIGV2ZXJ5IHJlcXVlc3QuXG4gKlxuICogQHBhcmFtIGxvYWQgLSBSZXR1cm5zIHRoZSBjYXRhbG9ndWU7IGBmb3JjZWAgYXNrcyBpdCB0byBieXBhc3MgaXRzIGNhY2hlLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmFua01vZGVsSWRMaXZlKFxuICBsb2FkOiAoZm9yY2U6IGJvb2xlYW4pID0+IFByb21pc2U8cmVhZG9ubHkgU2VydmluZ0VuZHBvaW50U3VtbWFyeVtdPixcbiAgc2VhcmNoOiBzdHJpbmcsXG4gIG9wdGlvbnM6IFJlc29sdmVNb2RlbE9wdGlvbnMgPSB7fSxcbik6IFByb21pc2U8UmVzb2x2ZWRNb2RlbD4ge1xuICBjb25zdCByZXNvbHZlZCA9IHJhbmtNb2RlbElkKGF3YWl0IGxvYWQoZmFsc2UpLCBzZWFyY2gsIG9wdGlvbnMpO1xuICBpZiAocmVzb2x2ZWQubWF0Y2hlZCkgcmV0dXJuIHJlc29sdmVkO1xuICByZXR1cm4gcmFua01vZGVsSWQoYXdhaXQgbG9hZCh0cnVlKSwgc2VhcmNoLCBvcHRpb25zKTtcbn1cblxuLyoqXG4gKiBSYW5rIGEgd29ya3NwYWNlJ3MgY2F0YWxvZ3VlIGluIG9uZSBjYWxsOiBsaXN0IGl0cyBgL3NlcnZpbmctZW5kcG9pbnRzYFxuICogKGNhY2hlZCkgYW5kIHJ1biB7QGxpbmsgbG9va3VwTW9kZWxzfSBvdmVyIHRoZSByZXN1bHQuIFRoZSBsaXN0IGNvdW50ZXJwYXJ0IHRvXG4gKiB7QGxpbmsgc2VsZWN0TW9kZWx9LCBmb3IgYSBjb25zdW1lciB0aGF0IHdhbnRzIHRoZSBmdWxsIHJhbmtlZCBzZXQgKGEgbW9kZWxcbiAqIHBpY2tlciwgYSBDTEkpIHJhdGhlciB0aGFuIGEgc2luZ2xlIGlkLiBDYXRhbG9ndWUgZmV0Y2hlcyBmYWlsIGxvdWQ6IG5ldHdvcmtcbiAqIC8gYXV0aCBlcnJvcnMgcHJvcGFnYXRlIHNvIHRoZSBjYWxsZXIgc2VlcyB0aGUgcmVhbCBTREsgbWVzc2FnZS5cbiAqXG4gKiBAcGFyYW0gaG9zdCAtIFdvcmtzcGFjZSBob3N0IHVzZWQgYXMgdGhlIGNhY2hlIGtleS4gUGFzcyB0aGUgdmFsdWUgcmVzb2x2ZWRcbiAqICAgZnJvbSBgY2xpZW50LmNvbmZpZy5nZXRIb3N0KClgLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2VhcmNoTW9kZWxzKFxuICBjbGllbnQ6IFdvcmtzcGFjZUNsaWVudExpa2UsXG4gIGhvc3Q6IHN0cmluZyxcbiAgaW5wdXQ6IFNlYXJjaE1vZGVsc0lucHV0ID0ge30sXG4pOiBQcm9taXNlPFJhbmtlZE1vZGVsW10+IHtcbiAgY29uc3QgZW5kcG9pbnRzID0gYXdhaXQgbGlzdFNlcnZpbmdFbmRwb2ludHMoXG4gICAgY2xpZW50LFxuICAgIGhvc3QsXG4gICAgaW5wdXQudHRsTXMgIT09IHVuZGVmaW5lZCA/IHsgdHRsTXM6IGlucHV0LnR0bE1zIH0gOiB7fSxcbiAgKTtcbiAgcmV0dXJuIGxvb2t1cE1vZGVscyhlbmRwb2ludHMsIGlucHV0KTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIGEgbW9kZWwgaWQgZm9yIGEgd29ya3NwYWNlIGluIG9uZSBjYWxsOiBsaXN0IGl0cyBgL3NlcnZpbmctZW5kcG9pbnRzYFxuICogKGNhY2hlZCkgYW5kIHJ1biB7QGxpbmsgcmVzb2x2ZU1vZGVsfSBvdmVyIHRoZSByZXN1bHQuIFRoaXMgaXMgdGhlIGVudHJ5XG4gKiBwb2ludCBmb3IgYW55IGNvbnN1bWVyIHRoYXQgaG9sZHMgYSBgV29ya3NwYWNlQ2xpZW50YCBhbmQganVzdCB3YW50cyBhIHVzYWJsZVxuICogbW9kZWwgbmFtZSAtIGEgTGFrZWZsb3cgam9iLCBhIG9uZS1vZmYgc2NyaXB0LCBvciB0aGUgTWFzdHJhIHBsdWdpbiBhbGlrZS5cbiAqXG4gKiBDaGVhcCBleGl0OiB3aGVuIGFuIGBleHBsaWNpdGAgbmFtZSBpcyBnaXZlbiwgYGZ1enp5YCBpcyBvZmYsIGFuZCB0b29sXG4gKiBjYXBhYmlsaXR5IGlzIG5vdCByZXF1aXJlZCwgdGhlIGNhdGFsb2d1ZSBpcyBuZXZlciBmZXRjaGVkLiBDYXRhbG9ndWVcbiAqIGZldGNoZXMgb3RoZXJ3aXNlIGZhaWwgbG91ZDogbmV0d29yayAvIGF1dGggZXJyb3JzIHByb3BhZ2F0ZSBzbyB0aGUgY2FsbGVyXG4gKiBzZWVzIHRoZSByZWFsIFNESyBtZXNzYWdlIGluc3RlYWQgb2YgYSBzaWxlbnQgZmFsbGJhY2suXG4gKlxuICogQHBhcmFtIGhvc3QgLSBXb3Jrc3BhY2UgaG9zdCB1c2VkIGFzIHRoZSBjYWNoZSBrZXkuIFBhc3MgdGhlIHZhbHVlIHJlc29sdmVkXG4gKiAgIGZyb20gYGNsaWVudC5jb25maWcuZ2V0SG9zdCgpYC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNlbGVjdE1vZGVsKFxuICBjbGllbnQ6IFdvcmtzcGFjZUNsaWVudExpa2UsXG4gIGhvc3Q6IHN0cmluZyxcbiAgaW5wdXQ6IFNlbGVjdE1vZGVsSW5wdXQgPSB7fSxcbik6IFByb21pc2U8UmVzb2x2ZWRNb2RlbFNlbGVjdGlvbj4ge1xuICBpZiAoaW5wdXQuZXhwbGljaXQgIT09IHVuZGVmaW5lZCAmJiBpbnB1dC5mdXp6eSA9PT0gZmFsc2UgJiYgIWlucHV0LnJlcXVpcmVzVG9vbHMpIHtcbiAgICByZXR1cm4geyBtb2RlbElkOiBpbnB1dC5leHBsaWNpdCwgc291cmNlOiBcImV4cGxpY2l0XCIgfTtcbiAgfVxuICBjb25zdCBlbmRwb2ludHMgPSBhd2FpdCBsaXN0U2VydmluZ0VuZHBvaW50cyhjbGllbnQsIGhvc3QsIHtcbiAgICAuLi4oaW5wdXQudHRsTXMgIT09IHVuZGVmaW5lZCA/IHsgdHRsTXM6IGlucHV0LnR0bE1zIH0gOiB7fSksXG4gIH0pO1xuICByZXR1cm4gcmVzb2x2ZU1vZGVsKGVuZHBvaW50cywgaW5wdXQpO1xufVxuXG4vKipcbiAqIFJlc29sdmUgYSBzaW5nbGUgbW9kZWwgaWQgZnJvbSB0aGUgbGl2ZSBjYXRhbG9ndWUgYW5kIGNhbGxlciBpbnRlbnQsXG4gKiBkZWxlZ2F0aW5nIHRoZSBsaXZlIHNlbGVjdGlvbiB0byB7QGxpbmsgbG9va3VwTW9kZWxzfSB3aXRoIGBsaW1pdDogMWAuXG4gKlxuICogMS4gKipFeHBsaWNpdCBhc2sqKjogd2l0aCBgZnV6enlgIG9mZiwgcmV0dXJuZWQgdmVyYmF0aW07IG90aGVyd2lzZVxuICogICAgZnV6enktcmFua2VkIHdpdGhpbiB0aGUgKG9wdGlvbmFsKSBjbGFzcyBjZWlsaW5nIGFuZCB0aGUgYmVzdCB0YWtlbixcbiAqICAgIGZhbGxpbmcgYmFjayB0byB0aGUgaW5wdXQgdmVyYmF0aW0gd2hlbiBub3RoaW5nIG1hdGNoZXMuXG4gKiAyLiAqKk5vIGV4cGxpY2l0IGFzayoqOiBhbiBvcGVyYXRvci1waW5uZWQgYGZhbGxiYWNrYCB0aGF0IGV4aXN0cyBpbiB0aGUgbGl2ZVxuICogICAgY2F0YWxvZ3VlIHdpbnMgZmlyc3QuIEEgY2xhc3MgcmVxdWVzdCByYW5rcyB3aXRoaW4gdGhhdCBjZWlsaW5nLiBBXG4gKiAgICBnZW5lcmFsIHJlcXVlc3QgcHJlZmVycyB0aGUgaGlnaGVzdC1yYW5rZWQgbGl2ZSBHUFQsIHRoZW4gYW55IHJhbmtlZCBsaXZlXG4gKiAgICBjaGF0IG1vZGVsLiBUaGUgc3RhdGljIHtAbGluayBGQUxMQkFDS19NT0RFTF9JRFN9IGZsb29yIGlzIHVzZWQgb25seSB3aGVuXG4gKiAgICB0aGUgY2F0YWxvZ3VlIHlpZWxkcyBub3RoaW5nIGluIHJhbmdlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZU1vZGVsKFxuICBlbmRwb2ludHM6IHJlYWRvbmx5IFNlcnZpbmdFbmRwb2ludFN1bW1hcnlbXSxcbiAgaW5wdXQ6IFJlc29sdmVNb2RlbElucHV0ID0ge30sXG4pOiBSZXNvbHZlZE1vZGVsU2VsZWN0aW9uIHtcbiAgaWYgKGlucHV0LmV4cGxpY2l0ICE9PSB1bmRlZmluZWQpIHtcbiAgICBpZiAoaW5wdXQuZnV6enkgPT09IGZhbHNlKSB7XG4gICAgICBpZiAoaW5wdXQucmVxdWlyZXNUb29scykgYXNzZXJ0VG9vbFN1cHBvcnQoZW5kcG9pbnRzLCBpbnB1dC5leHBsaWNpdCk7XG4gICAgICByZXR1cm4geyBtb2RlbElkOiBpbnB1dC5leHBsaWNpdCwgc291cmNlOiBcImV4cGxpY2l0XCIgfTtcbiAgICB9XG4gICAgY29uc3QgW3RvcF0gPSBsb29rdXBNb2RlbHMoZW5kcG9pbnRzLCBidWlsZFF1ZXJ5KGlucHV0LCBpbnB1dC5leHBsaWNpdCkpO1xuICAgIGlmIChpbnB1dC5yZXF1aXJlc1Rvb2xzICYmICF0b3ApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gdG9vbC1jYXBhYmxlIG1vZGVsIG1hdGNoZXMgXCIke2lucHV0LmV4cGxpY2l0fVwiYCk7XG4gICAgfVxuICAgIHJldHVybiB7IG1vZGVsSWQ6IHRvcD8uZW5kcG9pbnQubmFtZSA/PyBpbnB1dC5leHBsaWNpdCwgc291cmNlOiBcImZ1enp5LW1hdGNoXCIgfTtcbiAgfVxuXG4gIC8vIE9wZXJhdG9yLXBpbm5lZCBmYWxsYmFja3Mgd2luIHdoZW4gcHJlc2VudCBhbmQgbGl2ZSAoZS5nLiBhIHJlZ3VsYXRlZFxuICAvLyB3b3Jrc3BhY2UgcmVzdHJpY3RlZCB0byBhbiBhcHByb3ZlZCBzdWJzZXQpLlxuICBpZiAoaW5wdXQubW9kZWxDbGFzcyA9PT0gdW5kZWZpbmVkICYmIGlucHV0LmZhbGxiYWNrcyAmJiBpbnB1dC5mYWxsYmFja3MubGVuZ3RoID4gMCkge1xuICAgIGNvbnN0IHByZXNlbnQgPSBuZXcgU2V0KFxuICAgICAgZW5kcG9pbnRzXG4gICAgICAgIC5maWx0ZXIoKGVuZHBvaW50KSA9PiAhaW5wdXQucmVxdWlyZXNUb29scyB8fCBjbGFzc2lmeS5lbmRwb2ludENhcGFiaWxpdGllcyhlbmRwb2ludCkudG9vbHMpXG4gICAgICAgIC5tYXAoKGVuZHBvaW50KSA9PiBlbmRwb2ludC5uYW1lKSxcbiAgICApO1xuICAgIGNvbnN0IHBpbm5lZCA9IGlucHV0LmZhbGxiYWNrcy5maW5kKChpZCkgPT4gcHJlc2VudC5oYXMoaWQpKTtcbiAgICBpZiAocGlubmVkKSByZXR1cm4geyBtb2RlbElkOiBwaW5uZWQsIHNvdXJjZTogXCJmYWxsYmFja1wiIH07XG4gIH1cblxuICBjb25zdCBzb3VyY2UgPSBpbnB1dC5tb2RlbENsYXNzICE9PSB1bmRlZmluZWQgPyBcImNsYXNzXCIgOiBcImZhbGxiYWNrXCI7XG4gIGlmIChpbnB1dC5tb2RlbENsYXNzID09PSB1bmRlZmluZWQpIHtcbiAgICBjb25zdCBbcHJlZmVycmVkXSA9IGxvb2t1cE1vZGVscyhlbmRwb2ludHMsIGJ1aWxkUXVlcnkoaW5wdXQsIERFRkFVTFRfTU9ERUxfRkFNSUxZX1NFQVJDSCkpO1xuICAgIGlmIChwcmVmZXJyZWQpIHJldHVybiB7IG1vZGVsSWQ6IHByZWZlcnJlZC5lbmRwb2ludC5uYW1lLCBzb3VyY2UgfTtcbiAgfVxuICBjb25zdCBbdG9wXSA9IGxvb2t1cE1vZGVscyhlbmRwb2ludHMsIGJ1aWxkUXVlcnkoaW5wdXQsIHVuZGVmaW5lZCkpO1xuICBpZiAodG9wKSByZXR1cm4geyBtb2RlbElkOiB0b3AuZW5kcG9pbnQubmFtZSwgc291cmNlIH07XG5cbiAgaWYgKGlucHV0LmxpdmVPbmx5KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiTm8gbWF0Y2hpbmcgbGl2ZSBNb2RlbCBTZXJ2aW5nIGVuZHBvaW50IGlzIGF2YWlsYWJsZVwiKTtcbiAgfVxuXG4gIC8vIExpdmUgY2F0YWxvZ3VlIHlpZWxkZWQgbm90aGluZyBpbiByYW5nZTogd2FsayB0aGUgc3RhdGljIGZsb29yLlxuICBjb25zdCBmbG9vclNvdXJjZSA9XG4gICAgaW5wdXQubW9kZWxDbGFzcyAhPT0gdW5kZWZpbmVkID8gbW9kZWxzRm9yQ2xhc3MoaW5wdXQubW9kZWxDbGFzcykgOiAoaW5wdXQuZmFsbGJhY2tzID8/IFtdKTtcbiAgY29uc3QgZmxvb3IgPSBvYmplY3Quc2VxdWVuY2UoZmxvb3JTb3VyY2UpLmNvbmNhdChGQUxMQkFDS19NT0RFTF9JRFMpLmRpc3RpbmN0KCkudG9BcnJheSgpO1xuICBpZiAoaW5wdXQucmVxdWlyZXNUb29scykge1xuICAgIGNvbnN0IGF2YWlsYWJsZSA9IG5ldyBTZXQoXG4gICAgICBlbmRwb2ludHNcbiAgICAgICAgLmZpbHRlcigoZW5kcG9pbnQpID0+IGNsYXNzaWZ5LmVuZHBvaW50Q2FwYWJpbGl0aWVzKGVuZHBvaW50KS50b29scylcbiAgICAgICAgLm1hcCgoZW5kcG9pbnQpID0+IGVuZHBvaW50Lm5hbWUpLFxuICAgICk7XG4gICAgY29uc3Qgc2VsZWN0ZWQgPSBmbG9vci5maW5kKChpZCkgPT4gYXZhaWxhYmxlLmhhcyhpZCkpO1xuICAgIGlmICghc2VsZWN0ZWQpIHRocm93IG5ldyBFcnJvcihcIk5vIHRvb2wtY2FwYWJsZSBtb2RlbCBpcyBhdmFpbGFibGVcIik7XG4gICAgcmV0dXJuIHsgbW9kZWxJZDogc2VsZWN0ZWQsIHNvdXJjZSB9O1xuICB9XG4gIHJldHVybiB7IG1vZGVsSWQ6IHBpY2tGaXJzdEF2YWlsYWJsZShmbG9vciwgZW5kcG9pbnRzKSwgc291cmNlIH07XG59XG5cbi8qKiBCdWlsZCBhIHtAbGluayBNb2RlbFF1ZXJ5fSBmcm9tIHtAbGluayBSZXNvbHZlTW9kZWxJbnB1dH0gZm9yIHRoZSBgbGltaXQ6IDFgIGRlbGVnYXRpb24uICovXG5mdW5jdGlvbiBidWlsZFF1ZXJ5KGlucHV0OiBSZXNvbHZlTW9kZWxJbnB1dCwgc2VhcmNoOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBNb2RlbFF1ZXJ5IHtcbiAgcmV0dXJuIHtcbiAgICAuLi4oc2VhcmNoICE9PSB1bmRlZmluZWQgPyB7IHNlYXJjaCB9IDoge30pLFxuICAgIC4uLihpbnB1dC5tb2RlbENsYXNzICE9PSB1bmRlZmluZWQgPyB7IG1vZGVsQ2xhc3M6IGlucHV0Lm1vZGVsQ2xhc3MgfSA6IHt9KSxcbiAgICAuLi4oaW5wdXQucmVxdWlyZXNUb29scyAhPT0gdW5kZWZpbmVkID8geyByZXF1aXJlc1Rvb2xzOiBpbnB1dC5yZXF1aXJlc1Rvb2xzIH0gOiB7fSksXG4gICAgLi4uKGlucHV0LnRocmVzaG9sZCAhPT0gdW5kZWZpbmVkID8geyB0aHJlc2hvbGQ6IGlucHV0LnRocmVzaG9sZCB9IDoge30pLFxuICAgIGxpbWl0OiAxLFxuICB9O1xufVxuXG4vKiogVGhyb3cgd2hlbiBhbiBleHBsaWNpdCBpZCBpcyBhYnNlbnQgb3Igbm90IHZlcmlmaWVkIGZvciBmdW5jdGlvbiB0b29scy4gKi9cbmZ1bmN0aW9uIGFzc2VydFRvb2xTdXBwb3J0KGVuZHBvaW50czogcmVhZG9ubHkgU2VydmluZ0VuZHBvaW50U3VtbWFyeVtdLCBtb2RlbElkOiBzdHJpbmcpOiB2b2lkIHtcbiAgY29uc3QgZW5kcG9pbnQgPSBlbmRwb2ludHMuZmluZCgoY2FuZGlkYXRlKSA9PiBjYW5kaWRhdGUubmFtZSA9PT0gbW9kZWxJZCk7XG4gIGlmICghZW5kcG9pbnQgfHwgIWNsYXNzaWZ5LmVuZHBvaW50Q2FwYWJpbGl0aWVzKGVuZHBvaW50KS50b29scykge1xuICAgIHRocm93IG5ldyBFcnJvcihgTW9kZWwgXCIke21vZGVsSWR9XCIgZG9lcyBub3Qgc3VwcG9ydCBmdW5jdGlvbiB0b29sc2ApO1xuICB9XG59XG5cbi8qKlxuICogRmluZCB0aGUgZmlyc3QgaWQgaW4gYGNhbmRpZGF0ZXNgIHdob3NlIGVuZHBvaW50IGlzIHByZXNlbnQgaW4gYGVuZHBvaW50c2AuXG4gKiBSZXR1cm5zIHRoZSB0b3AgY2FuZGlkYXRlIHdoZW4gdGhlIHdvcmtzcGFjZSBoYXMgbm9uZSBvZiB0aGVtIHNvIGNhbGxlcnNcbiAqIGFsd2F5cyBnZXQgYSBzdHJpbmc7IGFuIG9mZmxpbmUgd29ya3NwYWNlIHRoZW4gcmVjZWl2ZXMgYSBjbGVhbiA0MDQgZnJvbVxuICogRGF0YWJyaWNrcyBpbnN0ZWFkIG9mIGEgbWFsZm9ybWVkIGNvbmZpZy5cbiAqL1xuZnVuY3Rpb24gcGlja0ZpcnN0QXZhaWxhYmxlKFxuICBjYW5kaWRhdGVzOiByZWFkb25seSBzdHJpbmdbXSxcbiAgZW5kcG9pbnRzOiByZWFkb25seSBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5W10sXG4pOiBzdHJpbmcge1xuICBjb25zdCBwcmVzZW50ID0gbmV3IFNldChlbmRwb2ludHMubWFwKChlKSA9PiBlLm5hbWUpKTtcbiAgZm9yIChjb25zdCBjYW5kaWRhdGUgb2YgY2FuZGlkYXRlcykge1xuICAgIGlmIChwcmVzZW50LmhhcyhjYW5kaWRhdGUpKSByZXR1cm4gY2FuZGlkYXRlO1xuICB9XG4gIHJldHVybiBjYW5kaWRhdGVzWzBdID8/IEZBTExCQUNLX01PREVMX0lEU1swXSE7XG59XG4iXX0=
215
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzb2x2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yZXNvbHZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9CRztBQUVILE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQVFoRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQzdDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxjQUFjLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkUsT0FBTyxFQUNMLG9CQUFvQixHQUlyQixNQUFNLG9CQUFvQixDQUFDO0FBQzVCLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUlwRCw4RUFBOEU7QUFDOUUsTUFBTSwyQkFBMkIsR0FBRyxLQUFLLENBQUM7QUErRDFDOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLFVBQVUsWUFBWSxDQUMxQixTQUE0QyxFQUM1QyxRQUFvQixFQUFFO0lBRXRCLE9BQU8sYUFBYSxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQztBQUN6QyxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxNQUFNLFVBQVUsV0FBVyxDQUN6QixTQUE0QyxFQUM1QyxNQUFjLEVBQ2QsVUFBK0IsRUFBRTtJQUVqQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsWUFBWSxDQUFDLFNBQVMsRUFBRTtRQUNwQyxNQUFNO1FBQ04sS0FBSyxFQUFFLENBQUM7UUFDUixHQUFHLENBQUMsT0FBTyxDQUFDLFNBQVMsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQzVFLEdBQUcsQ0FBQyxPQUFPLENBQUMsYUFBYSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxhQUFhLEVBQUUsT0FBTyxDQUFDLGFBQWEsRUFBRSxD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cGFjZS1hd2FyZSBtb2RlbCBzZWxlY3Rpb24uXG4gKlxuICogR2l2ZW4gYSBjYWxsZXIncyBpbnRlbnQgLSBhIHNlYXJjaCBzdHJpbmcsIGEgY2FwYWJpbGl0eSB7QGxpbmsgTW9kZWxDbGFzc31cbiAqIGNlaWxpbmcsIGJvdGgsIG9yIG5vdGhpbmcgLSB0aGUgdG9vbGtpdCByZXR1cm5zIG1hdGNoaW5nIGVuZHBvaW50cyByYW5rZWQgYnlcbiAqIG1hdGNoIHF1YWxpdHkgdGhlbiBjbGFzcywgb3IgY29sbGFwc2VzIHRvIHRoZSBzaW5nbGUgYmVzdCBpZCB0aGUgd29ya3NwYWNlXG4gKiBhY3R1YWxseSBoYXMsIGRlZ3JhZGluZyBmcm9tIFwiYmVzdCBpbiByYW5nZVwiIGRvd24gdG8gdGhlIHN0YXRpYyBmYWxsYmFja1xuICogZmxvb3IuIFNlbGVjdGlvbiBpcyBjaGF0LW9ubHk6IGVtYmVkZGluZyBlbmRwb2ludHMgc3VyZmFjZSBvbmx5IHdoZW5cbiAqIGBtb2RlbENsYXNzYCBpcyBleHBsaWNpdGx5IHtAbGluayBNb2RlbENsYXNzLkVtYmVkZGluZ30uXG4gKlxuICogVHdvIHNoYXBlcyBvZiBzZWxlY3Rpb24sIGVhY2ggaW4gYSBwdXJlIGZvcm0gKG92ZXIgYW4gZW5kcG9pbnQgbGlzdCB0aGVcbiAqIGNhbGxlciBhbHJlYWR5IGhvbGRzKSBhbmQgYW4gSS9PIHdyYXBwZXIgKHRoYXQgbGlzdHMgYC9zZXJ2aW5nLWVuZHBvaW50c2BcbiAqIGZpcnN0KTogcmFua2luZywgd2hpY2ggcmV0dXJucyBhIG1hdGNoLSB0aGVuIGNsYXNzLW9yZGVyZWQgbGlzdCwgYW5kXG4gKiBzaW5nbGUtc2VsZWN0aW9uLCB3aGljaCBjb2xsYXBzZXMgdG8gb25lIGlkIHBsdXMgaG93IGl0IHdhcyByZWFjaGVkIGFuZFxuICogbGF5ZXJzIHRoZSBvcGVyYXRvci1waW5uZWQgZmFsbGJhY2sgLyBzdGF0aWMtZmxvb3Igc2FmZXR5IG5ldCBvbiB0b3AuIEEgY2hhdFxuICogYG1vZGVsQ2xhc3NgIGFjdHMgYXMgYSBjZWlsaW5nOiB0aGF0IGJhbmQgYW5kIHRoZSBsZXNzLWNhcGFibGUgY2hhdCBiYW5kc1xuICogYmVsb3cgaXQgYXJlIGVsaWdpYmxlIChzZWUge0BsaW5rIGNsYXNzZXNBdE9yQmVsb3d9KSwgc28gYSBgY2hhdC1iYWxhbmNlZGBcbiAqIGFzayBjYW4gZmFsbCB0byBgY2hhdC1mYXN0YCBidXQgbmV2ZXIgZXNjYWxhdGUgdG8gYGNoYXQtdGhpbmtpbmdgLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBvYmplY3QgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHtcbiAgbW9kZWwsXG4gIHR5cGUgTW9kZWxRdWVyeSxcbiAgdHlwZSBSYW5rZWRNb2RlbCxcbiAgdHlwZSBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5LFxufSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtbW9kZWxcIjtcblxuaW1wb3J0IHsgcmFua0VuZHBvaW50cyB9IGZyb20gXCIuL19uYXRpdmUudHNcIjtcbmltcG9ydCB7IEZBTExCQUNLX01PREVMX0lEUywgbW9kZWxzRm9yQ2xhc3MgfSBmcm9tIFwiLi9mYWxsYmFjay50c1wiO1xuaW1wb3J0IHtcbiAgbGlzdFNlcnZpbmdFbmRwb2ludHMsXG4gIHR5cGUgUmVzb2x2ZWRNb2RlbCxcbiAgdHlwZSBSZXNvbHZlTW9kZWxPcHRpb25zLFxuICB0eXBlIFdvcmtzcGFjZUNsaWVudExpa2UsXG59IGZyb20gXCIuL21vZGVsLWNhdGFsb2cudHNcIjtcbmltcG9ydCB7IGVuZHBvaW50U3VwcG9ydHNUb29scyB9IGZyb20gXCIuL3BvbGljeS50c1wiO1xuXG50eXBlIE1vZGVsQ2xhc3MgPSBtb2RlbC5Nb2RlbENsYXNzO1xuXG4vKiogUHJlZmVycmVkIGxpdmUgZmFtaWx5IGZvciBhbiB1bmNvbmZpZ3VyZWQgZ2VuZXJhbC1wdXJwb3NlIGNoYXQgZGVmYXVsdC4gKi9cbmNvbnN0IERFRkFVTFRfTU9ERUxfRkFNSUxZX1NFQVJDSCA9IFwiZ3B0XCI7XG5cbi8qKiBDYWxsZXIgaW50ZW50IHBhc3NlZCB0byB7QGxpbmsgcmVzb2x2ZU1vZGVsfS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb2x2ZU1vZGVsSW5wdXQge1xuICAvKipcbiAgICogRXhwbGljaXQgbW9kZWwgaWQgLyBsb29zZSBuYW1lIChwZXItcmVxdWVzdCBvdmVycmlkZSwgYWdlbnQgLyBwbHVnaW5cbiAgICogZGVmYXVsdCwgb3IgZW52IHZhcikuIFdoZW4gc2V0IGl0IHdpbnMgb3ZlciBgbW9kZWxDbGFzc2AgYW5kIGBmYWxsYmFja3NgLlxuICAgKi9cbiAgZXhwbGljaXQ/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBGdXp6eS1tYXRjaCBhbiBgZXhwbGljaXRgIG5hbWUgYWdhaW5zdCB0aGUgbGl2ZSBjYXRhbG9ndWUgc28gbG9vc2UgbmFtZXNcbiAgICogbGlrZSBgXCJjbGF1ZGUgc29ubmV0XCJgIHJlc29sdmUuIERlZmF1bHQgYHRydWVgLiBXaGVuIGBmYWxzZWAgdGhlIGV4cGxpY2l0XG4gICAqIGlucHV0IGlzIHJldHVybmVkIHZlcmJhdGltIChEYXRhYnJpY2tzIHN1cmZhY2VzIHRoZSBjYW5vbmljYWwgNDA0IGlmIGl0XG4gICAqIGRvZXNuJ3QgZXhpc3QpLlxuICAgKi9cbiAgZnV6enk/OiBib29sZWFuO1xuICAvKiogUnVzdCBmdXp6eS1kaXN0YW5jZSB0aHJlc2hvbGQgZm9yd2FyZGVkIHRvIHRoZSBzZWFyY2ggbWF0Y2guICovXG4gIHRocmVzaG9sZD86IG51bWJlcjtcbiAgLyoqIFJlcXVpcmUgYSBtb2RlbCB0aGF0IHN1cHBvcnRzIGEgY29tcGxldGUgZnVuY3Rpb24tdG9vbCByb3VuZC10cmlwLiAqL1xuICByZXF1aXJlc1Rvb2xzPzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIENoYXQgY2FwYWJpbGl0eSBjbGFzcyB0byByZXNvbHZlIHdoZW4gbm8gYGV4cGxpY2l0YCBpZCBpcyBnaXZlbi4gVGhlIGxpdmVcbiAgICogY2F0YWxvZ3VlIGlzIGNsYXNzaWZpZWQgYnkgaXRzIEZvdW5kYXRpb24gTW9kZWwgQVBJIHNjb3JlcyBhbmQgdGhlIHRvcFxuICAgKiBhdmFpbGFibGUgbW9kZWwgaW4gdGhlIGNsYXNzIChhbmQgdGhlIGNoYXQgYmFuZHMgYmVsb3cgaXQpIHdpbnMsIGZhbGxpbmdcbiAgICogYmFjayB0byB0aGUgY2xhc3MncyBzbWFsbCBzdGF0aWMgbGlzdC5cbiAgICovXG4gIG1vZGVsQ2xhc3M/OiBNb2RlbENsYXNzO1xuICAvKipcbiAgICogT3BlcmF0b3Itc3VwcGxpZWQgZmFsbGJhY2sgaWRzIHRyaWVkICpmaXJzdCogaW4gdGhlIG5vLWV4cGxpY2l0LCBuby1jbGFzc1xuICAgKiBwYXRoIChlLmcuIGEgcmVndWxhdGVkIHdvcmtzcGFjZSBwaW5uZWQgdG8gYW4gYXBwcm92ZWQgc3Vic2V0KSwgYWhlYWQgb2ZcbiAgICogdGhlIGF1dG8tY2xhc3NpZmllZCBjYXRhbG9ndWUuXG4gICAqL1xuICBmYWxsYmFja3M/OiByZWFkb25seSBzdHJpbmdbXTtcbiAgLyoqXG4gICAqIFJlZnVzZSB0aGUgc3RhdGljIG9mZmxpbmUgZmxvb3Igd2hlbiB0aGUgbGl2ZSBjYXRhbG9ndWUgaGFzIG5vIG1hdGNoLlxuICAgKiBVc2UgZm9yIHVucGlubmVkIGRlZmF1bHRzIHRoYXQgbXVzdCBhbHdheXMgbmFtZSBhIGN1cnJlbnRseSBhdmFpbGFibGVcbiAgICogZW5kcG9pbnQuXG4gICAqL1xuICBsaXZlT25seT86IGJvb2xlYW47XG59XG5cbi8qKiBPdXRjb21lIG9mIHtAbGluayByZXNvbHZlTW9kZWx9OiB0aGUgY2hvc2VuIGlkIHBsdXMgaG93IGl0IHdhcyByZWFjaGVkLiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXNvbHZlZE1vZGVsU2VsZWN0aW9uIHtcbiAgbW9kZWxJZDogc3RyaW5nO1xuICBzb3VyY2U6IFwiZXhwbGljaXRcIiB8IFwiZnV6enktbWF0Y2hcIiB8IFwiY2xhc3NcIiB8IFwiZmFsbGJhY2tcIjtcbn1cblxuLyoqIEludGVudCArIGNhdGFsb2d1ZSBrbm9icyBwYXNzZWQgdG8ge0BsaW5rIHNlbGVjdE1vZGVsfS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2VsZWN0TW9kZWxJbnB1dCBleHRlbmRzIFJlc29sdmVNb2RlbElucHV0IHtcbiAgLyoqIFRUTCBvdmVycmlkZSBmb3IgdGhlIGNhY2hlZCBgL3NlcnZpbmctZW5kcG9pbnRzYCBsaXN0aW5nLCBpbiBtcy4gKi9cbiAgdHRsTXM/OiBudW1iZXI7XG4gIC8qKiBUcnVzdGVkIG9wYXF1ZSBpZGVudGl0eSBvZiB0aGUgY3JlZGVudGlhbCB1c2VkIGJ5IHRoZSB3b3Jrc3BhY2UgY2xpZW50LiAqL1xuICBjYWNoZUlkZW50aXR5Pzogc3RyaW5nO1xufVxuXG4vKiogVFRMIG92ZXJyaWRlIG1lcmdlZCBpbnRvIGEge0BsaW5rIE1vZGVsUXVlcnl9IGZvciB7QGxpbmsgc2VhcmNoTW9kZWxzfS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2VhcmNoTW9kZWxzSW5wdXQgZXh0ZW5kcyBNb2RlbFF1ZXJ5IHtcbiAgLyoqIFRUTCBvdmVycmlkZSBmb3IgdGhlIGNhY2hlZCBgL3NlcnZpbmctZW5kcG9pbnRzYCBsaXN0aW5nLCBpbiBtcy4gKi9cbiAgdHRsTXM/OiBudW1iZXI7XG4gIC8qKiBUcnVzdGVkIG9wYXF1ZSBpZGVudGl0eSBvZiB0aGUgY3JlZGVudGlhbCB1c2VkIGJ5IHRoZSB3b3Jrc3BhY2UgY2xpZW50LiAqL1xuICBjYWNoZUlkZW50aXR5Pzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFJhbmsgdGhlIGxpdmUgY2F0YWxvZ3VlIGFnYWluc3QgYSB7QGxpbmsgTW9kZWxRdWVyeX0sIGJlc3QtZmlyc3QuXG4gKlxuICogUnVzdCBvd25zIGNsYXNzaWZpY2F0aW9uLCBmdXp6eSBzY29yaW5nLCBmYW1pbHktdmVyc2lvbiBvcmRlcmluZywgcHJlZmVycmVkXG4gKiB2YXJpYW50cywgY2xhc3MgY2VpbGluZ3MsIHRvb2wgZmlsdGVyaW5nLCBhbmQgcmVzdWx0IGxpbWl0aW5nLiBOb2RlIHJldGFpbnNcbiAqIHRoZSBjYWxsZXIncyBlbmRwb2ludCBvYmplY3RzIHNvIGZpZWxkcyBvdXRzaWRlIHRoZSByYW5raW5nIGNvbnRyYWN0IHJlbWFpblxuICogYXZhaWxhYmxlIHVuY2hhbmdlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxvb2t1cE1vZGVscyhcbiAgZW5kcG9pbnRzOiByZWFkb25seSBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5W10sXG4gIHF1ZXJ5OiBNb2RlbFF1ZXJ5ID0ge30sXG4pOiBSYW5rZWRNb2RlbFtdIHtcbiAgcmV0dXJuIHJhbmtFbmRwb2ludHMoZW5kcG9pbnRzLCBxdWVyeSk7XG59XG5cbi8qKlxuICogQ29sbGFwc2Uge0BsaW5rIGxvb2t1cE1vZGVsc30gdG8gYSBzaW5nbGUgaWQ6IHRoZSBjbG9zZXN0IGVuZHBvaW50IHRvIGBzZWFyY2hgXG4gKiBpbiBhIGNhdGFsb2d1ZSBzbmFwc2hvdCwgb3IgdGhlIGlucHV0IHZlcmJhdGltIHdoZW4gbm90aGluZyBzY29yZXMgd2l0aGluIHRoZVxuICogdGhyZXNob2xkLlxuICpcbiAqIFRoZSByYW5rZWQgY291bnRlcnBhcnQgdG8ge0BsaW5rIHJlc29sdmVNb2RlbElkfTogZXF1YWxcbiAqIG1hdGNoIHNjb3JlcyBhcmUgYnJva2VuIGJ5IGNsYXNzIGFuZCB0aGVuIHdpdGhpbi1jbGFzcyB2ZXJzaW9uLCBzbyBhIGxvb3NlXG4gKiBgXCJvcHVzXCJgIHByZWZlcnMgYG9wdXMtNWAgb3ZlciBgb3B1cy00LTdgIGluc3RlYWQgb2YgcGlja2luZyB3aGljaGV2ZXJcbiAqIHNpYmxpbmcgYXBwZWFyZWQgZmlyc3QuIFJldHVybmluZyB0aGUgaW5wdXQgdW5tYXRjaGVkIChyYXRoZXJcbiAqIHRoYW4gYSBuZWFyIG5laWdoYm91cikgaXMgZGVsaWJlcmF0ZSAtIGEgZGVsaWJlcmF0ZSBlbmRwb2ludCBpZCBpcyBuZXZlclxuICogc2lsZW50bHkgcmV3cml0dGVuLCBhbmQgRGF0YWJyaWNrcyBzdXJmYWNlcyBhIGNsZWFuIDQwNC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJhbmtNb2RlbElkKFxuICBlbmRwb2ludHM6IHJlYWRvbmx5IFNlcnZpbmdFbmRwb2ludFN1bW1hcnlbXSxcbiAgc2VhcmNoOiBzdHJpbmcsXG4gIG9wdGlvbnM6IFJlc29sdmVNb2RlbE9wdGlvbnMgPSB7fSxcbik6IFJlc29sdmVkTW9kZWwge1xuICBjb25zdCBbdG9wXSA9IGxvb2t1cE1vZGVscyhlbmRwb2ludHMsIHtcbiAgICBzZWFyY2gsXG4gICAgbGltaXQ6IDEsXG4gICAgLi4uKG9wdGlvbnMudGhyZXNob2xkICE9PSB1bmRlZmluZWQgPyB7IHRocmVzaG9sZDogb3B0aW9ucy50aHJlc2hvbGQgfSA6IHt9KSxcbiAgICAuLi4ob3B0aW9ucy5yZXF1aXJlc1Rvb2xzICE9PSB1bmRlZmluZWQgPyB7IHJlcXVpcmVzVG9vbHM6IG9wdGlvbnMucmVxdWlyZXNUb29scyB9IDoge30pLFxuICB9KTtcbiAgaWYgKCF0b3ApIHJldHVybiB7IG1vZGVsSWQ6IHNlYXJjaCwgbWF0Y2hlZDogZmFsc2UgfTtcbiAgcmV0dXJuIHsgbW9kZWxJZDogdG9wLmVuZHBvaW50Lm5hbWUsIG1hdGNoZWQ6IHRydWUsIHNjb3JlOiB0b3Auc2NvcmUgfTtcbn1cblxuLyoqXG4gKiB7QGxpbmsgcmFua01vZGVsSWR9IGFnYWluc3QgYSBjYXRhbG9ndWUgdGhlIGNhbGxlciBtYXkgYmUgaG9sZGluZyBzdGFsZTpcbiAqIG1hdGNoIHRoZSBsb2FkZWQgc25hcHNob3QsIGFuZCBvbiBhIG1pc3MgcmVsb2FkIG9uY2Ugd2l0aCBgZm9yY2VgIGFuZCBtYXRjaFxuICogYWdhaW4uIFRoYXQgd2F5IGEgbW9kZWwgZGVwbG95ZWQgYWZ0ZXIgdGhlIGNhdGFsb2d1ZSB3YXMgY2FjaGVkIHN0aWxsXG4gKiByZXNvbHZlcyBvbiBmaXJzdCB1c2UsIHdpdGhvdXQgYSByZXN0YXJ0IGFuZCB3aXRob3V0IGdpdmluZyB1cCBjYWNoaW5nLlxuICpcbiAqIFRoZSBjYXRhbG9ndWUgYXJyaXZlcyBhcyBhIGxvYWRlciByYXRoZXIgdGhhbiBhIGNsaWVudCBzbyB0aGUgY2FsbGVyIGtlZXBzXG4gKiBvd25lcnNoaXAgb2YgKmhvdyogaXQgaXMgY2FjaGVkIC0ge0BsaW5rIGxpc3RTZXJ2aW5nRW5kcG9pbnRzfSBhbmQgaXRzXG4gKiBgQ2FjaGVNYW5hZ2VyYCwgYSBwbGFpbiBwcm9jZXNzLWxpZmV0aW1lIGZpZWxkIGluIGEgQ0xJLCBvciBhIHRlc3QgZG91YmxlLlxuICogT25seSBvbmUgcmVsb2FkIGlzIGF0dGVtcHRlZDogYSBnZW51aW5lbHkgdW5rbm93biBuYW1lIHNob3VsZCBmYWlsIGZhc3RcbiAqIHJhdGhlciB0aGFuIHJlLWxpc3Qgb24gZXZlcnkgcmVxdWVzdC5cbiAqXG4gKiBAcGFyYW0gbG9hZCAtIFJldHVybnMgdGhlIGNhdGFsb2d1ZTsgYGZvcmNlYCBhc2tzIGl0IHRvIGJ5cGFzcyBpdHMgY2FjaGUuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByYW5rTW9kZWxJZExpdmUoXG4gIGxvYWQ6IChmb3JjZTogYm9vbGVhbikgPT4gUHJvbWlzZTxyZWFkb25seSBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5W10+LFxuICBzZWFyY2g6IHN0cmluZyxcbiAgb3B0aW9uczogUmVzb2x2ZU1vZGVsT3B0aW9ucyA9IHt9LFxuKTogUHJvbWlzZTxSZXNvbHZlZE1vZGVsPiB7XG4gIGNvbnN0IHJlc29sdmVkID0gcmFua01vZGVsSWQoYXdhaXQgbG9hZChmYWxzZSksIHNlYXJjaCwgb3B0aW9ucyk7XG4gIGlmIChyZXNvbHZlZC5tYXRjaGVkKSByZXR1cm4gcmVzb2x2ZWQ7XG4gIHJldHVybiByYW5rTW9kZWxJZChhd2FpdCBsb2FkKHRydWUpLCBzZWFyY2gsIG9wdGlvbnMpO1xufVxuXG4vKipcbiAqIFJhbmsgYSB3b3Jrc3BhY2UncyBjYXRhbG9ndWUgaW4gb25lIGNhbGw6IGxpc3QgaXRzIGAvc2VydmluZy1lbmRwb2ludHNgXG4gKiAoY2FjaGVkKSBhbmQgcnVuIHtAbGluayBsb29rdXBNb2RlbHN9IG92ZXIgdGhlIHJlc3VsdC4gVGhlIGxpc3QgY291bnRlcnBhcnQgdG9cbiAqIHtAbGluayBzZWxlY3RNb2RlbH0sIGZvciBhIGNvbnN1bWVyIHRoYXQgd2FudHMgdGhlIGZ1bGwgcmFua2VkIHNldCAoYSBtb2RlbFxuICogcGlja2VyLCBhIENMSSkgcmF0aGVyIHRoYW4gYSBzaW5nbGUgaWQuIENhdGFsb2d1ZSBmZXRjaGVzIGZhaWwgbG91ZDogbmV0d29ya1xuICogLyBhdXRoIGVycm9ycyBwcm9wYWdhdGUgc28gdGhlIGNhbGxlciBzZWVzIHRoZSByZWFsIFNESyBtZXNzYWdlLlxuICpcbiAqIEBwYXJhbSBob3N0IC0gV29ya3NwYWNlIGhvc3QgdXNlZCBhcyB0aGUgY2FjaGUga2V5LiBQYXNzIHRoZSB2YWx1ZSByZXNvbHZlZFxuICogICBmcm9tIGBjbGllbnQuY29uZmlnLmdldEhvc3QoKWAuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzZWFyY2hNb2RlbHMoXG4gIGNsaWVudDogV29ya3NwYWNlQ2xpZW50TGlrZSxcbiAgaG9zdDogc3RyaW5nLFxuICBpbnB1dDogU2VhcmNoTW9kZWxzSW5wdXQgPSB7fSxcbik6IFByb21pc2U8UmFua2VkTW9kZWxbXT4ge1xuICBjb25zdCBlbmRwb2ludHMgPSBhd2FpdCBsaXN0U2VydmluZ0VuZHBvaW50cyhjbGllbnQsIGhvc3QsIHtcbiAgICAuLi4oaW5wdXQudHRsTXMgIT09IHVuZGVmaW5lZCA/IHsgdHRsTXM6IGlucHV0LnR0bE1zIH0gOiB7fSksXG4gICAgLi4uKGlucHV0LmNhY2hlSWRlbnRpdHkgIT09IHVuZGVmaW5lZCA/IHsgY2FjaGVJZGVudGl0eTogaW5wdXQuY2FjaGVJZGVudGl0eSB9IDoge30pLFxuICB9KTtcbiAgcmV0dXJuIGxvb2t1cE1vZGVscyhlbmRwb2ludHMsIGlucHV0KTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIGEgbW9kZWwgaWQgZm9yIGEgd29ya3NwYWNlIGluIG9uZSBjYWxsOiBsaXN0IGl0cyBgL3NlcnZpbmctZW5kcG9pbnRzYFxuICogKGNhY2hlZCkgYW5kIHJ1biB7QGxpbmsgcmVzb2x2ZU1vZGVsfSBvdmVyIHRoZSByZXN1bHQuIFRoaXMgaXMgdGhlIGVudHJ5XG4gKiBwb2ludCBmb3IgYW55IGNvbnN1bWVyIHRoYXQgaG9sZHMgYSBgV29ya3NwYWNlQ2xpZW50YCBhbmQganVzdCB3YW50cyBhIHVzYWJsZVxuICogbW9kZWwgbmFtZSAtIGEgTGFrZWZsb3cgam9iLCBhIG9uZS1vZmYgc2NyaXB0LCBvciB0aGUgTWFzdHJhIHBsdWdpbiBhbGlrZS5cbiAqXG4gKiBDaGVhcCBleGl0OiB3aGVuIGFuIGBleHBsaWNpdGAgbmFtZSBpcyBnaXZlbiwgYGZ1enp5YCBpcyBvZmYsIGFuZCB0b29sXG4gKiBjYXBhYmlsaXR5IGlzIG5vdCByZXF1aXJlZCwgdGhlIGNhdGFsb2d1ZSBpcyBuZXZlciBmZXRjaGVkLiBDYXRhbG9ndWVcbiAqIGZldGNoZXMgb3RoZXJ3aXNlIGZhaWwgbG91ZDogbmV0d29yayAvIGF1dGggZXJyb3JzIHByb3BhZ2F0ZSBzbyB0aGUgY2FsbGVyXG4gKiBzZWVzIHRoZSByZWFsIFNESyBtZXNzYWdlIGluc3RlYWQgb2YgYSBzaWxlbnQgZmFsbGJhY2suXG4gKlxuICogQHBhcmFtIGhvc3QgLSBXb3Jrc3BhY2UgaG9zdCB1c2VkIGFzIHRoZSBjYWNoZSBrZXkuIFBhc3MgdGhlIHZhbHVlIHJlc29sdmVkXG4gKiAgIGZyb20gYGNsaWVudC5jb25maWcuZ2V0SG9zdCgpYC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNlbGVjdE1vZGVsKFxuICBjbGllbnQ6IFdvcmtzcGFjZUNsaWVudExpa2UsXG4gIGhvc3Q6IHN0cmluZyxcbiAgaW5wdXQ6IFNlbGVjdE1vZGVsSW5wdXQgPSB7fSxcbik6IFByb21pc2U8UmVzb2x2ZWRNb2RlbFNlbGVjdGlvbj4ge1xuICBpZiAoaW5wdXQuZXhwbGljaXQgIT09IHVuZGVmaW5lZCAmJiBpbnB1dC5mdXp6eSA9PT0gZmFsc2UgJiYgIWlucHV0LnJlcXVpcmVzVG9vbHMpIHtcbiAgICByZXR1cm4geyBtb2RlbElkOiBpbnB1dC5leHBsaWNpdCwgc291cmNlOiBcImV4cGxpY2l0XCIgfTtcbiAgfVxuICBjb25zdCBlbmRwb2ludHMgPSBhd2FpdCBsaXN0U2VydmluZ0VuZHBvaW50cyhjbGllbnQsIGhvc3QsIHtcbiAgICAuLi4oaW5wdXQudHRsTXMgIT09IHVuZGVmaW5lZCA/IHsgdHRsTXM6IGlucHV0LnR0bE1zIH0gOiB7fSksXG4gICAgLi4uKGlucHV0LmNhY2hlSWRlbnRpdHkgIT09IHVuZGVmaW5lZCA/IHsgY2FjaGVJZGVudGl0eTogaW5wdXQuY2FjaGVJZGVudGl0eSB9IDoge30pLFxuICB9KTtcbiAgcmV0dXJuIHJlc29sdmVNb2RlbChlbmRwb2ludHMsIGlucHV0KTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIGEgc2luZ2xlIG1vZGVsIGlkIGZyb20gdGhlIGxpdmUgY2F0YWxvZ3VlIGFuZCBjYWxsZXIgaW50ZW50LFxuICogZGVsZWdhdGluZyB0aGUgbGl2ZSBzZWxlY3Rpb24gdG8ge0BsaW5rIGxvb2t1cE1vZGVsc30gd2l0aCBgbGltaXQ6IDFgLlxuICpcbiAqIDEuICoqRXhwbGljaXQgYXNrKio6IHdpdGggYGZ1enp5YCBvZmYsIHJldHVybmVkIHZlcmJhdGltOyBvdGhlcndpc2VcbiAqICAgIGZ1enp5LXJhbmtlZCB3aXRoaW4gdGhlIChvcHRpb25hbCkgY2xhc3MgY2VpbGluZyBhbmQgdGhlIGJlc3QgdGFrZW4sXG4gKiAgICBmYWxsaW5nIGJhY2sgdG8gdGhlIGlucHV0IHZlcmJhdGltIHdoZW4gbm90aGluZyBtYXRjaGVzLlxuICogMi4gKipObyBleHBsaWNpdCBhc2sqKjogYW4gb3BlcmF0b3ItcGlubmVkIGBmYWxsYmFja2AgdGhhdCBleGlzdHMgaW4gdGhlIGxpdmVcbiAqICAgIGNhdGFsb2d1ZSB3aW5zIGZpcnN0LiBBIGNsYXNzIHJlcXVlc3QgcmFua3Mgd2l0aGluIHRoYXQgY2VpbGluZy4gQVxuICogICAgZ2VuZXJhbCByZXF1ZXN0IHByZWZlcnMgdGhlIGhpZ2hlc3QtcmFua2VkIGxpdmUgR1BULCB0aGVuIGFueSByYW5rZWQgbGl2ZVxuICogICAgY2hhdCBtb2RlbC4gVGhlIHN0YXRpYyB7QGxpbmsgRkFMTEJBQ0tfTU9ERUxfSURTfSBmbG9vciBpcyB1c2VkIG9ubHkgd2hlblxuICogICAgdGhlIGNhdGFsb2d1ZSB5aWVsZHMgbm90aGluZyBpbiByYW5nZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVNb2RlbChcbiAgZW5kcG9pbnRzOiByZWFkb25seSBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5W10sXG4gIGlucHV0OiBSZXNvbHZlTW9kZWxJbnB1dCA9IHt9LFxuKTogUmVzb2x2ZWRNb2RlbFNlbGVjdGlvbiB7XG4gIGlmIChpbnB1dC5leHBsaWNpdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKGlucHV0LmZ1enp5ID09PSBmYWxzZSkge1xuICAgICAgaWYgKGlucHV0LnJlcXVpcmVzVG9vbHMpIGFzc2VydFRvb2xTdXBwb3J0KGVuZHBvaW50cywgaW5wdXQuZXhwbGljaXQpO1xuICAgICAgcmV0dXJuIHsgbW9kZWxJZDogaW5wdXQuZXhwbGljaXQsIHNvdXJjZTogXCJleHBsaWNpdFwiIH07XG4gICAgfVxuICAgIGNvbnN0IFt0b3BdID0gbG9va3VwTW9kZWxzKGVuZHBvaW50cywgYnVpbGRRdWVyeShpbnB1dCwgaW5wdXQuZXhwbGljaXQpKTtcbiAgICBpZiAoaW5wdXQucmVxdWlyZXNUb29scyAmJiAhdG9wKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIHRvb2wtY2FwYWJsZSBtb2RlbCBtYXRjaGVzIFwiJHtpbnB1dC5leHBsaWNpdH1cImApO1xuICAgIH1cbiAgICByZXR1cm4geyBtb2RlbElkOiB0b3A/LmVuZHBvaW50Lm5hbWUgPz8gaW5wdXQuZXhwbGljaXQsIHNvdXJjZTogXCJmdXp6eS1tYXRjaFwiIH07XG4gIH1cblxuICAvLyBPcGVyYXRvci1waW5uZWQgZmFsbGJhY2tzIHdpbiB3aGVuIHByZXNlbnQgYW5kIGxpdmUgKGUuZy4gYSByZWd1bGF0ZWRcbiAgLy8gd29ya3NwYWNlIHJlc3RyaWN0ZWQgdG8gYW4gYXBwcm92ZWQgc3Vic2V0KS5cbiAgaWYgKGlucHV0Lm1vZGVsQ2xhc3MgPT09IHVuZGVmaW5lZCAmJiBpbnB1dC5mYWxsYmFja3MgJiYgaW5wdXQuZmFsbGJhY2tzLmxlbmd0aCA+IDApIHtcbiAgICBjb25zdCBwcmVzZW50ID0gbmV3IFNldChcbiAgICAgIGVuZHBvaW50c1xuICAgICAgICAuZmlsdGVyKChlbmRwb2ludCkgPT4gIWlucHV0LnJlcXVpcmVzVG9vbHMgfHwgZW5kcG9pbnRTdXBwb3J0c1Rvb2xzKGVuZHBvaW50KSlcbiAgICAgICAgLm1hcCgoZW5kcG9pbnQpID0+IGVuZHBvaW50Lm5hbWUpLFxuICAgICk7XG4gICAgY29uc3QgcGlubmVkID0gaW5wdXQuZmFsbGJhY2tzLmZpbmQoKGlkKSA9PiBwcmVzZW50LmhhcyhpZCkpO1xuICAgIGlmIChwaW5uZWQpIHJldHVybiB7IG1vZGVsSWQ6IHBpbm5lZCwgc291cmNlOiBcImZhbGxiYWNrXCIgfTtcbiAgfVxuXG4gIGNvbnN0IHNvdXJjZSA9IGlucHV0Lm1vZGVsQ2xhc3MgIT09IHVuZGVmaW5lZCA/IFwiY2xhc3NcIiA6IFwiZmFsbGJhY2tcIjtcbiAgaWYgKGlucHV0Lm1vZGVsQ2xhc3MgPT09IHVuZGVmaW5lZCkge1xuICAgIGNvbnN0IFtwcmVmZXJyZWRdID0gbG9va3VwTW9kZWxzKGVuZHBvaW50cywgYnVpbGRRdWVyeShpbnB1dCwgREVGQVVMVF9NT0RFTF9GQU1JTFlfU0VBUkNIKSk7XG4gICAgaWYgKHByZWZlcnJlZCkgcmV0dXJuIHsgbW9kZWxJZDogcHJlZmVycmVkLmVuZHBvaW50Lm5hbWUsIHNvdXJjZSB9O1xuICB9XG4gIGNvbnN0IFt0b3BdID0gbG9va3VwTW9kZWxzKGVuZHBvaW50cywgYnVpbGRRdWVyeShpbnB1dCwgdW5kZWZpbmVkKSk7XG4gIGlmICh0b3ApIHJldHVybiB7IG1vZGVsSWQ6IHRvcC5lbmRwb2ludC5uYW1lLCBzb3VyY2UgfTtcblxuICBpZiAoaW5wdXQubGl2ZU9ubHkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyBtYXRjaGluZyBsaXZlIE1vZGVsIFNlcnZpbmcgZW5kcG9pbnQgaXMgYXZhaWxhYmxlXCIpO1xuICB9XG5cbiAgLy8gTGl2ZSBjYXRhbG9ndWUgeWllbGRlZCBub3RoaW5nIGluIHJhbmdlOiB3YWxrIHRoZSBzdGF0aWMgZmxvb3IuXG4gIGNvbnN0IGZsb29yU291cmNlID1cbiAgICBpbnB1dC5tb2RlbENsYXNzICE9PSB1bmRlZmluZWQgPyBtb2RlbHNGb3JDbGFzcyhpbnB1dC5tb2RlbENsYXNzKSA6IChpbnB1dC5mYWxsYmFja3MgPz8gW10pO1xuICBjb25zdCBmbG9vciA9IG9iamVjdC5zZXF1ZW5jZShmbG9vclNvdXJjZSkuY29uY2F0KEZBTExCQUNLX01PREVMX0lEUykuZGlzdGluY3QoKS50b0FycmF5KCk7XG4gIGlmIChpbnB1dC5yZXF1aXJlc1Rvb2xzKSB7XG4gICAgY29uc3QgYXZhaWxhYmxlID0gbmV3IFNldChcbiAgICAgIGVuZHBvaW50cy5maWx0ZXIoZW5kcG9pbnRTdXBwb3J0c1Rvb2xzKS5tYXAoKGVuZHBvaW50KSA9PiBlbmRwb2ludC5uYW1lKSxcbiAgICApO1xuICAgIGNvbnN0IHNlbGVjdGVkID0gZmxvb3IuZmluZCgoaWQpID0+IGF2YWlsYWJsZS5oYXMoaWQpKTtcbiAgICBpZiAoIXNlbGVjdGVkKSB0aHJvdyBuZXcgRXJyb3IoXCJObyB0b29sLWNhcGFibGUgbW9kZWwgaXMgYXZhaWxhYmxlXCIpO1xuICAgIHJldHVybiB7IG1vZGVsSWQ6IHNlbGVjdGVkLCBzb3VyY2UgfTtcbiAgfVxuICByZXR1cm4geyBtb2RlbElkOiBwaWNrRmlyc3RBdmFpbGFibGUoZmxvb3IsIGVuZHBvaW50cyksIHNvdXJjZSB9O1xufVxuXG4vKiogQnVpbGQgYSB7QGxpbmsgTW9kZWxRdWVyeX0gZnJvbSB7QGxpbmsgUmVzb2x2ZU1vZGVsSW5wdXR9IGZvciB0aGUgYGxpbWl0OiAxYCBkZWxlZ2F0aW9uLiAqL1xuZnVuY3Rpb24gYnVpbGRRdWVyeShpbnB1dDogUmVzb2x2ZU1vZGVsSW5wdXQsIHNlYXJjaDogc3RyaW5nIHwgdW5kZWZpbmVkKTogTW9kZWxRdWVyeSB7XG4gIHJldHVybiB7XG4gICAgLi4uKHNlYXJjaCAhPT0gdW5kZWZpbmVkID8geyBzZWFyY2ggfSA6IHt9KSxcbiAgICAuLi4oaW5wdXQubW9kZWxDbGFzcyAhPT0gdW5kZWZpbmVkID8geyBtb2RlbENsYXNzOiBpbnB1dC5tb2RlbENsYXNzIH0gOiB7fSksXG4gICAgLi4uKGlucHV0LnJlcXVpcmVzVG9vbHMgIT09IHVuZGVmaW5lZCA/IHsgcmVxdWlyZXNUb29sczogaW5wdXQucmVxdWlyZXNUb29scyB9IDoge30pLFxuICAgIC4uLihpbnB1dC50aHJlc2hvbGQgIT09IHVuZGVmaW5lZCA/IHsgdGhyZXNob2xkOiBpbnB1dC50aHJlc2hvbGQgfSA6IHt9KSxcbiAgICBsaW1pdDogMSxcbiAgfTtcbn1cblxuLyoqIFRocm93IHdoZW4gYW4gZXhwbGljaXQgaWQgaXMgYWJzZW50IG9yIG5vdCB2ZXJpZmllZCBmb3IgZnVuY3Rpb24gdG9vbHMuICovXG5mdW5jdGlvbiBhc3NlcnRUb29sU3VwcG9ydChlbmRwb2ludHM6IHJlYWRvbmx5IFNlcnZpbmdFbmRwb2ludFN1bW1hcnlbXSwgbW9kZWxJZDogc3RyaW5nKTogdm9pZCB7XG4gIGNvbnN0IGVuZHBvaW50ID0gZW5kcG9pbnRzLmZpbmQoKGNhbmRpZGF0ZSkgPT4gY2FuZGlkYXRlLm5hbWUgPT09IG1vZGVsSWQpO1xuICBpZiAoIWVuZHBvaW50IHx8ICFlbmRwb2ludFN1cHBvcnRzVG9vbHMoZW5kcG9pbnQpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBNb2RlbCBcIiR7bW9kZWxJZH1cIiBkb2VzIG5vdCBzdXBwb3J0IGZ1bmN0aW9uIHRvb2xzYCk7XG4gIH1cbn1cblxuLyoqXG4gKiBGaW5kIHRoZSBmaXJzdCBpZCBpbiBgY2FuZGlkYXRlc2Agd2hvc2UgZW5kcG9pbnQgaXMgcHJlc2VudCBpbiBgZW5kcG9pbnRzYC5cbiAqIFJldHVybnMgdGhlIHRvcCBjYW5kaWRhdGUgd2hlbiB0aGUgd29ya3NwYWNlIGhhcyBub25lIG9mIHRoZW0gc28gY2FsbGVyc1xuICogYWx3YXlzIGdldCBhIHN0cmluZzsgYW4gb2ZmbGluZSB3b3Jrc3BhY2UgdGhlbiByZWNlaXZlcyBhIGNsZWFuIDQwNCBmcm9tXG4gKiBEYXRhYnJpY2tzIGluc3RlYWQgb2YgYSBtYWxmb3JtZWQgY29uZmlnLlxuICovXG5mdW5jdGlvbiBwaWNrRmlyc3RBdmFpbGFibGUoXG4gIGNhbmRpZGF0ZXM6IHJlYWRvbmx5IHN0cmluZ1tdLFxuICBlbmRwb2ludHM6IHJlYWRvbmx5IFNlcnZpbmdFbmRwb2ludFN1bW1hcnlbXSxcbik6IHN0cmluZyB7XG4gIGNvbnN0IHByZXNlbnQgPSBuZXcgU2V0KGVuZHBvaW50cy5tYXAoKGUpID0+IGUubmFtZSkpO1xuICBmb3IgKGNvbnN0IGNhbmRpZGF0ZSBvZiBjYW5kaWRhdGVzKSB7XG4gICAgaWYgKHByZXNlbnQuaGFzKGNhbmRpZGF0ZSkpIHJldHVybiBjYW5kaWRhdGU7XG4gIH1cbiAgcmV0dXJuIGNhbmRpZGF0ZXNbMF0gPz8gRkFMTEJBQ0tfTU9ERUxfSURTWzBdITtcbn1cbiJdfQ==
@@ -1 +1 @@
1
- {"root":["../src/classes.ts","../src/fallback.ts","../src/invoke.ts","../src/policy.ts","../src/resolve.ts","../src/serving.ts","../index.ts"],"version":"5.9.3"}
1
+ {"root":["../src/_native.ts","../src/classes.ts","../src/fallback.ts","../src/invoke.ts","../src/model-catalog.ts","../src/policy.ts","../src/resolve.ts","../index.ts"],"version":"5.9.3"}