@dbx-tools/search 0.6.222 → 0.6.224
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -3
- package/index.ts +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +2 -2
- package/lib/src/plugin.d.ts +9 -5
- package/lib/src/plugin.js +26 -28
- package/lib/src/runtime.d.ts +19 -12
- package/lib/src/runtime.js +30 -22
- package/lib/src/tool.d.ts +17 -7
- package/lib/src/tool.js +31 -17
- package/package.json +7 -7
- package/src/plugin.ts +27 -30
- package/src/runtime.ts +32 -23
- package/src/tool.ts +45 -17
package/lib/src/runtime.js
CHANGED
|
@@ -1,34 +1,42 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
2
|
+
* AI Search runtime construction helpers.
|
|
3
|
+
*
|
|
4
|
+
* Each plugin and standalone tool set owns its runtime and client. Provider
|
|
5
|
+
* attachment updates only that runtime, so two apps in one process can use
|
|
6
|
+
* different backends without sharing state.
|
|
7
7
|
*
|
|
8
8
|
* @module
|
|
9
9
|
*/
|
|
10
10
|
import { createSearchClient } from "./client.js";
|
|
11
11
|
import { resolveSearchConfig, } from "./config.js";
|
|
12
|
-
|
|
12
|
+
/** Build an isolated runtime for one plugin instance or standalone tool set. */
|
|
13
|
+
export function createSearchRuntime(options = {}) {
|
|
14
|
+
const config = resolveSearchConfig(options.config);
|
|
15
|
+
return {
|
|
16
|
+
config,
|
|
17
|
+
client: createSearchClient(config, undefined, options.readBackend),
|
|
18
|
+
...(options.readBackend ? { readBackend: options.readBackend } : {}),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/** Attach a provider to one runtime while preserving its object identity. */
|
|
22
|
+
export function setSearchReadBackend(runtime, readBackend) {
|
|
23
|
+
runtime.readBackend = readBackend;
|
|
24
|
+
runtime.client = createSearchClient(runtime.config, undefined, readBackend);
|
|
25
|
+
}
|
|
13
26
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
27
|
+
* Build an isolated standalone runtime.
|
|
28
|
+
*
|
|
29
|
+
* @deprecated Use {@link createSearchRuntime}. This compatibility helper
|
|
30
|
+
* returns a new runtime on every call and never reads or updates plugin state.
|
|
18
31
|
*/
|
|
19
32
|
export function getSearchRuntime(options) {
|
|
20
|
-
|
|
21
|
-
const config = resolveSearchConfig(options?.config);
|
|
22
|
-
runtime = {
|
|
23
|
-
config,
|
|
24
|
-
client: createSearchClient(config, undefined, options?.readBackend),
|
|
25
|
-
...(options?.readBackend ? { readBackend: options.readBackend } : {}),
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
return runtime;
|
|
33
|
+
return createSearchRuntime(options);
|
|
29
34
|
}
|
|
30
|
-
/**
|
|
35
|
+
/**
|
|
36
|
+
* @deprecated Plugin runtimes are instance-owned and need no global reset.
|
|
37
|
+
* This compatibility helper is intentionally a no-op.
|
|
38
|
+
*/
|
|
31
39
|
export function resetSearchRuntime() {
|
|
32
|
-
|
|
40
|
+
return;
|
|
33
41
|
}
|
|
34
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
42
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVudGltZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydW50aW1lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7OztHQVFHO0FBRUgsT0FBTyxFQUFFLGtCQUFrQixFQUF3QyxNQUFNLGFBQWEsQ0FBQztBQUN2RixPQUFPLEVBQ0wsbUJBQW1CLEdBR3BCLE1BQU0sYUFBYSxDQUFDO0FBZXJCLGdGQUFnRjtBQUNoRixNQUFNLFVBQVUsbUJBQW1CLENBQUMsVUFBZ0MsRUFBRTtJQUNwRSxNQUFNLE1BQU0sR0FBRyxtQkFBbUIsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDbkQsT0FBTztRQUNMLE1BQU07UUFDTixNQUFNLEVBQUUsa0JBQWtCLENBQUMsTUFBTSxFQUFFLFNBQVMsRUFBRSxPQUFPLENBQUMsV0FBVyxDQUFDO1FBQ2xFLEdBQUcsQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLFdBQVcsRUFBRSxPQUFPLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztLQUNyRSxDQUFDO0FBQ0osQ0FBQztBQUVELDZFQUE2RTtBQUM3RSxNQUFNLFVBQVUsb0JBQW9CLENBQUMsT0FBc0IsRUFBRSxXQUE4QjtJQUN6RixPQUFPLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQztJQUNsQyxPQUFPLENBQUMsTUFBTSxHQUFHLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsU0FBUyxFQUFFLFdBQVcsQ0FBQyxDQUFDO0FBQzlFLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxnQkFBZ0IsQ0FBQyxPQUE4QjtJQUM3RCxPQUFPLG1CQUFtQixDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3RDLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsa0JBQWtCO0lBQ2hDLE9BQU87QUFDVCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBBSSBTZWFyY2ggcnVudGltZSBjb25zdHJ1Y3Rpb24gaGVscGVycy5cbiAqXG4gKiBFYWNoIHBsdWdpbiBhbmQgc3RhbmRhbG9uZSB0b29sIHNldCBvd25zIGl0cyBydW50aW1lIGFuZCBjbGllbnQuIFByb3ZpZGVyXG4gKiBhdHRhY2htZW50IHVwZGF0ZXMgb25seSB0aGF0IHJ1bnRpbWUsIHNvIHR3byBhcHBzIGluIG9uZSBwcm9jZXNzIGNhbiB1c2VcbiAqIGRpZmZlcmVudCBiYWNrZW5kcyB3aXRob3V0IHNoYXJpbmcgc3RhdGUuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IGNyZWF0ZVNlYXJjaENsaWVudCwgU2VhcmNoQ2xpZW50LCB0eXBlIFNlYXJjaFJlYWRCYWNrZW5kIH0gZnJvbSBcIi4vY2xpZW50LnRzXCI7XG5pbXBvcnQge1xuICByZXNvbHZlU2VhcmNoQ29uZmlnLFxuICB0eXBlIFNlYXJjaFBsdWdpbkNvbmZpZyxcbiAgdHlwZSBSZXNvbHZlZFNlYXJjaENvbmZpZyxcbn0gZnJvbSBcIi4vY29uZmlnLnRzXCI7XG5cbi8qKiBDb25maWd1cmF0aW9uIGFuZCBwcm92aWRlciB1c2VkIHRvIGJ1aWxkIGFuIGV4dGVuc2lvbiBydW50aW1lLiAqL1xuZXhwb3J0IGludGVyZmFjZSBTZWFyY2hSdW50aW1lT3B0aW9ucyB7XG4gIGNvbmZpZz86IFNlYXJjaFBsdWdpbkNvbmZpZztcbiAgcmVhZEJhY2tlbmQ/OiBTZWFyY2hSZWFkQmFja2VuZDtcbn1cblxuLyoqIFRoZSByZXNvbHZlZCBjb25maWcgcGx1cyB0aGUgY2xpZW50IHJlYWRzIHJ1biB0aHJvdWdoLiAqL1xuZXhwb3J0IGludGVyZmFjZSBTZWFyY2hSdW50aW1lIHtcbiAgY29uZmlnOiBSZXNvbHZlZFNlYXJjaENvbmZpZztcbiAgY2xpZW50OiBTZWFyY2hDbGllbnQ7XG4gIHJlYWRCYWNrZW5kPzogU2VhcmNoUmVhZEJhY2tlbmQ7XG59XG5cbi8qKiBCdWlsZCBhbiBpc29sYXRlZCBydW50aW1lIGZvciBvbmUgcGx1Z2luIGluc3RhbmNlIG9yIHN0YW5kYWxvbmUgdG9vbCBzZXQuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlU2VhcmNoUnVudGltZShvcHRpb25zOiBTZWFyY2hSdW50aW1lT3B0aW9ucyA9IHt9KTogU2VhcmNoUnVudGltZSB7XG4gIGNvbnN0IGNvbmZpZyA9IHJlc29sdmVTZWFyY2hDb25maWcob3B0aW9ucy5jb25maWcpO1xuICByZXR1cm4ge1xuICAgIGNvbmZpZyxcbiAgICBjbGllbnQ6IGNyZWF0ZVNlYXJjaENsaWVudChjb25maWcsIHVuZGVmaW5lZCwgb3B0aW9ucy5yZWFkQmFja2VuZCksXG4gICAgLi4uKG9wdGlvbnMucmVhZEJhY2tlbmQgPyB7IHJlYWRCYWNrZW5kOiBvcHRpb25zLnJlYWRCYWNrZW5kIH0gOiB7fSksXG4gIH07XG59XG5cbi8qKiBBdHRhY2ggYSBwcm92aWRlciB0byBvbmUgcnVudGltZSB3aGlsZSBwcmVzZXJ2aW5nIGl0cyBvYmplY3QgaWRlbnRpdHkuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0U2VhcmNoUmVhZEJhY2tlbmQocnVudGltZTogU2VhcmNoUnVudGltZSwgcmVhZEJhY2tlbmQ6IFNlYXJjaFJlYWRCYWNrZW5kKTogdm9pZCB7XG4gIHJ1bnRpbWUucmVhZEJhY2tlbmQgPSByZWFkQmFja2VuZDtcbiAgcnVudGltZS5jbGllbnQgPSBjcmVhdGVTZWFyY2hDbGllbnQocnVudGltZS5jb25maWcsIHVuZGVmaW5lZCwgcmVhZEJhY2tlbmQpO1xufVxuXG4vKipcbiAqIEJ1aWxkIGFuIGlzb2xhdGVkIHN0YW5kYWxvbmUgcnVudGltZS5cbiAqXG4gKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rIGNyZWF0ZVNlYXJjaFJ1bnRpbWV9LiBUaGlzIGNvbXBhdGliaWxpdHkgaGVscGVyXG4gKiByZXR1cm5zIGEgbmV3IHJ1bnRpbWUgb24gZXZlcnkgY2FsbCBhbmQgbmV2ZXIgcmVhZHMgb3IgdXBkYXRlcyBwbHVnaW4gc3RhdGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRTZWFyY2hSdW50aW1lKG9wdGlvbnM/OiBTZWFyY2hSdW50aW1lT3B0aW9ucyk6IFNlYXJjaFJ1bnRpbWUge1xuICByZXR1cm4gY3JlYXRlU2VhcmNoUnVudGltZShvcHRpb25zKTtcbn1cblxuLyoqXG4gKiBAZGVwcmVjYXRlZCBQbHVnaW4gcnVudGltZXMgYXJlIGluc3RhbmNlLW93bmVkIGFuZCBuZWVkIG5vIGdsb2JhbCByZXNldC5cbiAqIFRoaXMgY29tcGF0aWJpbGl0eSBoZWxwZXIgaXMgaW50ZW50aW9uYWxseSBhIG5vLW9wLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzZXRTZWFyY2hSdW50aW1lKCk6IHZvaWQge1xuICByZXR1cm47XG59XG4iXX0=
|
package/lib/src/tool.d.ts
CHANGED
|
@@ -2,21 +2,31 @@
|
|
|
2
2
|
* The `search`, `universal_search`, and (opt-in) `add_documents`,
|
|
3
3
|
* `create_index`, and `sync_index` Mastra tools.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
5
|
+
* App-integrated agents should consume the plugin's native toolkit so calls
|
|
6
|
+
* retain that plugin's config and provider backend. These standalone factories
|
|
7
|
+
* capture an explicit runtime or build an isolated one from config plus a
|
|
8
|
+
* provider. They run under the caller's OBO scope (the client resolves the
|
|
9
|
+
* execution context's workspace client), so search runs as the requesting user
|
|
10
|
+
* and Unity Catalog ACLs apply.
|
|
10
11
|
*
|
|
11
12
|
* The same tools are exposed to AppKit's own agents through the plugin's
|
|
12
|
-
* `ToolProvider` (see `plugin.ts`)
|
|
13
|
+
* `ToolProvider` (see `plugin.ts`).
|
|
13
14
|
*
|
|
14
15
|
* @module
|
|
15
16
|
*/
|
|
16
|
-
|
|
17
|
+
import type { SearchReadBackend } from "./client.ts";
|
|
18
|
+
import type { SearchPluginConfig } from "./config.ts";
|
|
19
|
+
import { type SearchRuntime } from "./runtime.ts";
|
|
20
|
+
/** Options accepted by every standalone tool factory. */
|
|
17
21
|
export interface SearchToolOptions {
|
|
18
22
|
/** Override the tool id (defaults per tool). */
|
|
19
23
|
id?: string;
|
|
24
|
+
/** Isolated runtime used by this standalone tool. Mutually exclusive with config/backend. */
|
|
25
|
+
runtime?: SearchRuntime;
|
|
26
|
+
/** Config used to create an isolated runtime. */
|
|
27
|
+
config?: SearchPluginConfig;
|
|
28
|
+
/** Provider used when creating a runtime from config. */
|
|
29
|
+
readBackend?: SearchReadBackend;
|
|
20
30
|
}
|
|
21
31
|
/**
|
|
22
32
|
* Build the `search` tool. Spread it into any agent that should be able to look
|
package/lib/src/tool.js
CHANGED
|
@@ -2,25 +2,37 @@
|
|
|
2
2
|
* The `search`, `universal_search`, and (opt-in) `add_documents`,
|
|
3
3
|
* `create_index`, and `sync_index` Mastra tools.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
5
|
+
* App-integrated agents should consume the plugin's native toolkit so calls
|
|
6
|
+
* retain that plugin's config and provider backend. These standalone factories
|
|
7
|
+
* capture an explicit runtime or build an isolated one from config plus a
|
|
8
|
+
* provider. They run under the caller's OBO scope (the client resolves the
|
|
9
|
+
* execution context's workspace client), so search runs as the requesting user
|
|
10
|
+
* and Unity Catalog ACLs apply.
|
|
10
11
|
*
|
|
11
12
|
* The same tools are exposed to AppKit's own agents through the plugin's
|
|
12
|
-
* `ToolProvider` (see `plugin.ts`)
|
|
13
|
+
* `ToolProvider` (see `plugin.ts`).
|
|
13
14
|
*
|
|
14
15
|
* @module
|
|
15
16
|
*/
|
|
16
17
|
import { search as sharedSearch } from "@dbx-tools/shared-search";
|
|
17
18
|
import { createTool } from "@mastra/core/tools";
|
|
18
19
|
import { z } from "zod";
|
|
20
|
+
import { toSearchOptions, toUniversalSearchOptions } from "./_search-options.js";
|
|
19
21
|
import { toCreateIndexOptions } from "./index-tools.js";
|
|
20
22
|
import { toDocumentArray } from "./query.js";
|
|
21
|
-
import {
|
|
22
|
-
import { toSearchOptions, toUniversalSearchOptions } from "./_search-options.js";
|
|
23
|
+
import { createSearchRuntime } from "./runtime.js";
|
|
23
24
|
import { ADD_DOCUMENTS_TOOL_DESCRIPTION, CREATE_INDEX_TOOL_DESCRIPTION, SEARCH_TOOL_DESCRIPTION, SYNC_INDEX_TOOL_DESCRIPTION, UNIVERSAL_SEARCH_TOOL_DESCRIPTION, createIndexToolSchema, indexInfoSchema, searchResultSchema, searchToolSchema, syncIndexToolSchema, universalSearchToolSchema, } from "./schema.js";
|
|
25
|
+
/** Resolve the isolated runtime captured by one standalone tool factory. */
|
|
26
|
+
function toolRuntime(options) {
|
|
27
|
+
if (options.runtime && (options.config || options.readBackend)) {
|
|
28
|
+
throw new TypeError("search tool options accept runtime or config/readBackend, not both");
|
|
29
|
+
}
|
|
30
|
+
return (options.runtime ??
|
|
31
|
+
createSearchRuntime({
|
|
32
|
+
config: options.config,
|
|
33
|
+
readBackend: options.readBackend,
|
|
34
|
+
}));
|
|
35
|
+
}
|
|
24
36
|
/**
|
|
25
37
|
* Build the `search` tool. Spread it into any agent that should be able to look
|
|
26
38
|
* things up in an index.
|
|
@@ -37,6 +49,7 @@ import { ADD_DOCUMENTS_TOOL_DESCRIPTION, CREATE_INDEX_TOOL_DESCRIPTION, SEARCH_T
|
|
|
37
49
|
* ```
|
|
38
50
|
*/
|
|
39
51
|
export function searchTool(options = {}) {
|
|
52
|
+
const runtime = toolRuntime(options);
|
|
40
53
|
return createTool({
|
|
41
54
|
id: options.id ?? "search",
|
|
42
55
|
description: SEARCH_TOOL_DESCRIPTION,
|
|
@@ -44,13 +57,13 @@ export function searchTool(options = {}) {
|
|
|
44
57
|
outputSchema: searchResultSchema,
|
|
45
58
|
execute: async (input, context) => {
|
|
46
59
|
const request = searchToolSchema.parse(input);
|
|
47
|
-
|
|
48
|
-
return client.search(request.query, toSearchOptions(request, context?.abortSignal));
|
|
60
|
+
return runtime.client.search(request.query, toSearchOptions(request, context?.abortSignal));
|
|
49
61
|
},
|
|
50
62
|
});
|
|
51
63
|
}
|
|
52
64
|
/** Build the `universal_search` tool (federated search across every index). */
|
|
53
65
|
export function universalSearchTool(options = {}) {
|
|
66
|
+
const runtime = toolRuntime(options);
|
|
54
67
|
return createTool({
|
|
55
68
|
id: options.id ?? "universal_search",
|
|
56
69
|
description: UNIVERSAL_SEARCH_TOOL_DESCRIPTION,
|
|
@@ -58,8 +71,7 @@ export function universalSearchTool(options = {}) {
|
|
|
58
71
|
outputSchema: searchResultSchema,
|
|
59
72
|
execute: async (input, context) => {
|
|
60
73
|
const request = universalSearchToolSchema.parse(input);
|
|
61
|
-
|
|
62
|
-
return client.universalSearch(request.query, toUniversalSearchOptions(request, context?.abortSignal));
|
|
74
|
+
return runtime.client.universalSearch(request.query, toUniversalSearchOptions(request, context?.abortSignal));
|
|
63
75
|
},
|
|
64
76
|
});
|
|
65
77
|
}
|
|
@@ -68,6 +80,7 @@ export function universalSearchTool(options = {}) {
|
|
|
68
80
|
* Only install it when the plugin's write surface is enabled.
|
|
69
81
|
*/
|
|
70
82
|
export function addDocumentsTool(options = {}) {
|
|
83
|
+
const runtime = toolRuntime(options);
|
|
71
84
|
const inputSchema = sharedSearch.searchDocumentSchema
|
|
72
85
|
.array()
|
|
73
86
|
.describe("Documents to add or update. Each must include the index primary key.");
|
|
@@ -79,7 +92,7 @@ export function addDocumentsTool(options = {}) {
|
|
|
79
92
|
.extend({ documents: inputSchema }),
|
|
80
93
|
outputSchema: sharedSearch.upsertResultSchema,
|
|
81
94
|
execute: async (input, context) => {
|
|
82
|
-
const { client, config } =
|
|
95
|
+
const { client, config } = runtime;
|
|
83
96
|
const record = input;
|
|
84
97
|
const documents = toDocumentArray(record.documents);
|
|
85
98
|
const index = record.index ?? config.defaultIndex ?? "";
|
|
@@ -94,6 +107,7 @@ export function addDocumentsTool(options = {}) {
|
|
|
94
107
|
* key, and columns from the request + plugin config.
|
|
95
108
|
*/
|
|
96
109
|
export function createIndexTool(options = {}) {
|
|
110
|
+
const runtime = toolRuntime(options);
|
|
97
111
|
return createTool({
|
|
98
112
|
id: options.id ?? "create_index",
|
|
99
113
|
description: CREATE_INDEX_TOOL_DESCRIPTION,
|
|
@@ -101,8 +115,7 @@ export function createIndexTool(options = {}) {
|
|
|
101
115
|
outputSchema: indexInfoSchema,
|
|
102
116
|
execute: async (input, context) => {
|
|
103
117
|
const request = createIndexToolSchema.parse(input);
|
|
104
|
-
|
|
105
|
-
return client.createIndex(request.name, toCreateIndexOptions(request, context?.abortSignal));
|
|
118
|
+
return runtime.client.createIndex(request.name, toCreateIndexOptions(request, context?.abortSignal));
|
|
106
119
|
},
|
|
107
120
|
});
|
|
108
121
|
}
|
|
@@ -116,6 +129,7 @@ const syncIndexResultSchema = z.object({
|
|
|
116
129
|
* source table). Only install it when the plugin's write surface is enabled.
|
|
117
130
|
*/
|
|
118
131
|
export function syncIndexTool(options = {}) {
|
|
132
|
+
const runtime = toolRuntime(options);
|
|
119
133
|
return createTool({
|
|
120
134
|
id: options.id ?? "sync_index",
|
|
121
135
|
description: SYNC_INDEX_TOOL_DESCRIPTION,
|
|
@@ -123,11 +137,11 @@ export function syncIndexTool(options = {}) {
|
|
|
123
137
|
outputSchema: syncIndexResultSchema,
|
|
124
138
|
execute: async (input, context) => {
|
|
125
139
|
const request = syncIndexToolSchema.parse(input);
|
|
126
|
-
const { client, config } =
|
|
140
|
+
const { client, config } = runtime;
|
|
127
141
|
const index = request.index ?? config.defaultIndex ?? "";
|
|
128
142
|
await client.syncIndex(index, context?.abortSignal);
|
|
129
143
|
return { index, synced: true };
|
|
130
144
|
},
|
|
131
145
|
});
|
|
132
146
|
}
|
|
133
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90b29sLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBRUgsT0FBTyxFQUFFLE1BQU0sSUFBSSxZQUFZLEVBQXFCLE1BQU0sMEJBQTBCLENBQUM7QUFDckYsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxDQUFDLEVBQUUsTUFBTSxLQUFLLENBQUM7QUFDeEIsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDeEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUM3QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDaEQsT0FBTyxFQUFFLGVBQWUsRUFBRSx3QkFBd0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2pGLE9BQU8sRUFDTCw4QkFBOEIsRUFDOUIsNkJBQTZCLEVBQzdCLHVCQUF1QixFQUN2QiwyQkFBMkIsRUFDM0IsaUNBQWlDLEVBQ2pDLHFCQUFxQixFQUNyQixlQUFlLEVBQ2Ysa0JBQWtCLEVBQ2xCLGdCQUFnQixFQUNoQixtQkFBbUIsRUFDbkIseUJBQXlCLEdBQzFCLE1BQU0sYUFBYSxDQUFDO0FBUXJCOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBQ0gsTUFBTSxVQUFVLFVBQVUsQ0FBQyxVQUE2QixFQUFFO0lBQ3hELE9BQU8sVUFBVSxDQUFDO1FBQ2hCLEVBQUUsRUFBRSxPQUFPLENBQUMsRUFBRSxJQUFJLFFBQVE7UUFDMUIsV0FBVyxFQUFFLHVCQUF1QjtRQUNwQyxXQUFXLEVBQUUsZ0JBQWdCO1FBQzdCLFlBQVksRUFBRSxrQkFBa0I7UUFDaEMsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7WUFDaEMsTUFBTSxPQUFPLEdBQUcsZ0JBQWdCLENBQUMsS0FBSyxDQUFD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IjpbIi8qKlxuICogVGhlIGBzZWFyY2hgLCBgdW5pdmVyc2FsX3NlYXJjaGAsIGFuZCAob3B0LWluKSBgYWRkX2RvY3VtZW50c2AsXG4gKiBgY3JlYXRlX2luZGV4YCwgYW5kIGBzeW5jX2luZGV4YCBNYXN0cmEgdG9vbHMuXG4gKlxuICogQWxsIHRocmVlIHJlYWQgdGhlIHNoYXJlZCBydW50aW1lIHByaW1lZCBieSB0aGUgcGx1Z2luLCBzbyBhIHRvb2wgc3ByZWFkXG4gKiBpbnRvIGFuIGFnZW50IHVzZXMgdGhlIGRlcGxveW1lbnQncyBkZWZhdWx0IGluZGV4LCBjb2x1bW5zLCBwYWdlIHNpemUsIGFuZFxuICogbW9kZSB3aXRob3V0IGFueSBwZXItdG9vbCB3aXJpbmcuIFRoZXkgcnVuIHVuZGVyIHRoZSBjYWxsZXIncyBPQk8gc2NvcGUgKHRoZVxuICogY2xpZW50IHJlc29sdmVzIHRoZSBleGVjdXRpb24gY29udGV4dCdzIHdvcmtzcGFjZSBjbGllbnQpLCBzbyBzZWFyY2ggcnVucyBhc1xuICogdGhlIHJlcXVlc3RpbmcgdXNlciBhbmQgVW5pdHkgQ2F0YWxvZyBBQ0xzIGFwcGx5LlxuICpcbiAqIFRoZSBzYW1lIHRvb2xzIGFyZSBleHBvc2VkIHRvIEFwcEtpdCdzIG93biBhZ2VudHMgdGhyb3VnaCB0aGUgcGx1Z2luJ3NcbiAqIGBUb29sUHJvdmlkZXJgIChzZWUgYHBsdWdpbi50c2ApOyB0aGlzIG1vZHVsZSBpcyB0aGUgTWFzdHJhIGhhbGYuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IHNlYXJjaCBhcyBzaGFyZWRTZWFyY2gsIHR5cGUgVXBzZXJ0UmVzdWx0IH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLXNlYXJjaFwiO1xuaW1wb3J0IHsgY3JlYXRlVG9vbCB9IGZyb20gXCJAbWFzdHJhL2NvcmUvdG9vbHNcIjtcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5pbXBvcnQgeyB0b0NyZWF0ZUluZGV4T3B0aW9ucyB9IGZyb20gXCIuL2luZGV4LXRvb2xzLnRzXCI7XG5pbXBvcnQgeyB0b0RvY3VtZW50QXJyYXkgfSBmcm9tIFwiLi9xdWVyeS50c1wiO1xuaW1wb3J0IHsgZ2V0U2VhcmNoUnVudGltZSB9IGZyb20gXCIuL3J1bnRpbWUudHNcIjtcbmltcG9ydCB7IHRvU2VhcmNoT3B0aW9ucywgdG9Vbml2ZXJzYWxTZWFyY2hPcHRpb25zIH0gZnJvbSBcIi4vX3NlYXJjaC1vcHRpb25zLnRzXCI7XG5pbXBvcnQge1xuICBBRERfRE9DVU1FTlRTX1RPT0xfREVTQ1JJUFRJT04sXG4gIENSRUFURV9JTkRFWF9UT09MX0RFU0NSSVBUSU9OLFxuICBTRUFSQ0hfVE9PTF9ERVNDUklQVElPTixcbiAgU1lOQ19JTkRFWF9UT09MX0RFU0NSSVBUSU9OLFxuICBVTklWRVJTQUxfU0VBUkNIX1RPT0xfREVTQ1JJUFRJT04sXG4gIGNyZWF0ZUluZGV4VG9vbFNjaGVtYSxcbiAgaW5kZXhJbmZvU2NoZW1hLFxuICBzZWFyY2hSZXN1bHRTY2hlbWEsXG4gIHNlYXJjaFRvb2xTY2hlbWEsXG4gIHN5bmNJbmRleFRvb2xTY2hlbWEsXG4gIHVuaXZlcnNhbFNlYXJjaFRvb2xTY2hlbWEsXG59IGZyb20gXCIuL3NjaGVtYS50c1wiO1xuXG4vKiogQ29tbW9uIG9wdGlvbiBhY2NlcHRlZCBieSBldmVyeSB0b29sIGZhY3Rvcnk6IG92ZXJyaWRlIHRoZSB0b29sIGlkLiAqL1xuZXhwb3J0IGludGVyZmFjZSBTZWFyY2hUb29sT3B0aW9ucyB7XG4gIC8qKiBPdmVycmlkZSB0aGUgdG9vbCBpZCAoZGVmYXVsdHMgcGVyIHRvb2wpLiAqL1xuICBpZD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBCdWlsZCB0aGUgYHNlYXJjaGAgdG9vbC4gU3ByZWFkIGl0IGludG8gYW55IGFnZW50IHRoYXQgc2hvdWxkIGJlIGFibGUgdG8gbG9va1xuICogdGhpbmdzIHVwIGluIGFuIGluZGV4LlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgc2VhcmNoVG9vbCB9IGZyb20gXCJAZGJ4LXRvb2xzL3NlYXJjaFwiO1xuICogaW1wb3J0IHsgY3JlYXRlQWdlbnQgfSBmcm9tIFwiQGRieC10b29scy9hcHBraXQtbWFzdHJhXCI7XG4gKlxuICogY29uc3Qgc3VwcG9ydCA9IGNyZWF0ZUFnZW50KHtcbiAqICAgaW5zdHJ1Y3Rpb25zOiBcIkFuc3dlciBmcm9tIHRoZSBkb2NzLiBVc2UgYHNlYXJjaGAgdG8gZmluZCB0aGVtLlwiLFxuICogICB0b29sczogKCkgPT4gKHsgc2VhcmNoOiBzZWFyY2hUb29sKCkgfSksXG4gKiB9KTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gc2VhcmNoVG9vbChvcHRpb25zOiBTZWFyY2hUb29sT3B0aW9ucyA9IHt9KSB7XG4gIHJldHVybiBjcmVhdGVUb29sKHtcbiAgICBpZDogb3B0aW9ucy5pZCA/PyBcInNlYXJjaFwiLFxuICAgIGRlc2NyaXB0aW9uOiBTRUFSQ0hfVE9PTF9ERVNDUklQVElPTixcbiAgICBpbnB1dFNjaGVtYTogc2VhcmNoVG9vbFNjaGVtYSxcbiAgICBvdXRwdXRTY2hlbWE6IHNlYXJjaFJlc3VsdFNjaGVtYSxcbiAgICBleGVjdXRlOiBhc3luYyAoaW5wdXQsIGNvbnRleHQpID0+IHtcbiAgICAgIGNvbnN0IHJlcXVlc3QgPSBzZWFyY2hUb29sU2NoZW1hLnBhcnNlKGlucHV0KTtcbiAgICAgIGNvbnN0IHsgY2xpZW50IH0gPSBnZXRTZWFyY2hSdW50aW1lKCk7XG4gICAgICByZXR1cm4gY2xpZW50LnNlYXJjaChyZXF1ZXN0LnF1ZXJ5LCB0b1NlYXJjaE9wdGlvbnMocmVxdWVzdCwgY29udGV4dD8uYWJvcnRTaWduYWwpKTtcbiAgICB9LFxuICB9KTtcbn1cblxuLyoqIEJ1aWxkIHRoZSBgdW5pdmVyc2FsX3NlYXJjaGAgdG9vbCAoZmVkZXJhdGVkIHNlYXJjaCBhY3Jvc3MgZXZlcnkgaW5kZXgpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVuaXZlcnNhbFNlYXJjaFRvb2wob3B0aW9uczogU2VhcmNoVG9vbE9wdGlvbnMgPSB7fSkge1xuICByZXR1cm4gY3JlYXRlVG9vbCh7XG4gICAgaWQ6IG9wdGlvbnMuaWQgPz8gXCJ1bml2ZXJzYWxfc2VhcmNoXCIsXG4gICAgZGVzY3JpcHRpb246IFVOSVZFUlNBTF9TRUFSQ0hfVE9PTF9ERVNDUklQVElPTixcbiAgICBpbnB1dFNjaGVtYTogdW5pdmVyc2FsU2VhcmNoVG9vbFNjaGVtYSxcbiAgICBvdXRwdXRTY2hlbWE6IHNlYXJjaFJlc3VsdFNjaGVtYSxcbiAgICBleGVjdXRlOiBhc3luYyAoaW5wdXQsIGNvbnRleHQpID0+IHtcbiAgICAgIGNvbnN0IHJlcXVlc3QgPSB1bml2ZXJzYWxTZWFyY2hUb29sU2NoZW1hLnBhcnNlKGlucHV0KTtcbiAgICAgIGNvbnN0IHsgY2xpZW50IH0gPSBnZXRTZWFyY2hSdW50aW1lKCk7XG4gICAgICByZXR1cm4gY2xpZW50LnVuaXZlcnNhbFNlYXJjaChcbiAgICAgICAgcmVxdWVzdC5xdWVyeSxcbiAgICAgICAgdG9Vbml2ZXJzYWxTZWFyY2hPcHRpb25zKHJlcXVlc3QsIGNvbnRleHQ/LmFib3J0U2lnbmFsKSxcbiAgICAgICk7XG4gICAgfSxcbiAgfSk7XG59XG5cbi8qKlxuICogQnVpbGQgdGhlIG9wdC1pbiBgYWRkX2RvY3VtZW50c2AgdG9vbCAod3JpdGUgaW50byBhIGRpcmVjdC1hY2Nlc3MgaW5kZXgpLlxuICogT25seSBpbnN0YWxsIGl0IHdoZW4gdGhlIHBsdWdpbidzIHdyaXRlIHN1cmZhY2UgaXMgZW5hYmxlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZERvY3VtZW50c1Rvb2wob3B0aW9uczogU2VhcmNoVG9vbE9wdGlvbnMgPSB7fSkge1xuICBjb25zdCBpbnB1dFNjaGVtYSA9IHNoYXJlZFNlYXJjaC5zZWFyY2hEb2N1bWVudFNjaGVtYVxuICAgIC5hcnJheSgpXG4gICAgLmRlc2NyaWJlKFwiRG9jdW1lbnRzIHRvIGFkZCBvciB1cGRhdGUuIEVhY2ggbXVzdCBpbmNsdWRlIHRoZSBpbmRleCBwcmltYXJ5IGtleS5cIik7XG4gIHJldHVybiBjcmVhdGVUb29sKHtcbiAgICBpZDogb3B0aW9ucy5pZCA/PyBcImFkZF9kb2N1bWVudHNcIixcbiAgICBkZXNjcmlwdGlvbjogQUREX0RPQ1VNRU5UU19UT09MX0RFU0NSSVBUSU9OLFxuICAgIGlucHV0U2NoZW1hOiBzaGFyZWRTZWFyY2guc2VhcmNoUmVxdWVzdFNjaGVtYVxuICAgICAgLnBpY2soeyBpbmRleDogdHJ1ZSB9KVxuICAgICAgLmV4dGVuZCh7IGRvY3VtZW50czogaW5wdXRTY2hlbWEgfSksXG4gICAgb3V0cHV0U2NoZW1hOiBzaGFyZWRTZWFyY2gudXBzZXJ0UmVzdWx0U2NoZW1hLFxuICAgIGV4ZWN1dGU6IGFzeW5jIChpbnB1dCwgY29udGV4dCk6IFByb21pc2U8VXBzZXJ0UmVzdWx0PiA9PiB7XG4gICAgICBjb25zdCB7IGNsaWVudCwgY29uZmlnIH0gPSBnZXRTZWFyY2hSdW50aW1lKCk7XG4gICAgICBjb25zdCByZWNvcmQgPSBpbnB1dCBhcyB7IGluZGV4Pzogc3RyaW5nOyBkb2N1bWVudHM6IHVua25vd24gfTtcbiAgICAgIGNvbnN0IGRvY3VtZW50cyA9IHRvRG9jdW1lbnRBcnJheShyZWNvcmQuZG9jdW1lbnRzKTtcbiAgICAgIGNvbnN0IGluZGV4ID0gcmVjb3JkLmluZGV4ID8/IGNvbmZpZy5kZWZhdWx0SW5kZXggPz8gXCJcIjtcbiAgICAgIHJldHVybiBjbGllbnQuYWRkRG9jdW1lbnRzKGluZGV4LCBkb2N1bWVudHMsIGNvbnRleHQ/LmFib3J0U2lnbmFsKTtcbiAgICB9LFxuICB9KTtcbn1cblxuLyoqXG4gKiBCdWlsZCB0aGUgb3B0LWluIGBjcmVhdGVfaW5kZXhgIHRvb2wgKHByb3Zpc2lvbiBhIFZlY3RvciBTZWFyY2ggaW5kZXgpLlxuICogT25seSBpbnN0YWxsIGl0IHdoZW4gdGhlIHBsdWdpbidzIHdyaXRlIHN1cmZhY2UgaXMgZW5hYmxlZC4gRGVsZWdhdGVzIHRvXG4gKiB7QGxpbmsgU2VhcmNoQ2xpZW50LmNyZWF0ZUluZGV4fSwgaW5mZXJyaW5nIHRoZSBlbmRwb2ludCwgZW1iZWRkaW5nIG1vZGVsLFxuICoga2V5LCBhbmQgY29sdW1ucyBmcm9tIHRoZSByZXF1ZXN0ICsgcGx1Z2luIGNvbmZpZy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUluZGV4VG9vbChvcHRpb25zOiBTZWFyY2hUb29sT3B0aW9ucyA9IHt9KSB7XG4gIHJldHVybiBjcmVhdGVUb29sKHtcbiAgICBpZDogb3B0aW9ucy5pZCA/PyBcImNyZWF0ZV9pbmRleFwiLFxuICAgIGRlc2NyaXB0aW9uOiBDUkVBVEVfSU5ERVhfVE9PTF9ERVNDUklQVElPTixcbiAgICBpbnB1dFNjaGVtYTogY3JlYXRlSW5kZXhUb29sU2NoZW1hLFxuICAgIG91dHB1dFNjaGVtYTogaW5kZXhJbmZvU2NoZW1hLFxuICAgIGV4ZWN1dGU6IGFzeW5jIChpbnB1dCwgY29udGV4dCkgPT4ge1xuICAgICAgY29uc3QgcmVxdWVzdCA9IGNyZWF0ZUluZGV4VG9vbFNjaGVtYS5wYXJzZShpbnB1dCk7XG4gICAgICBjb25zdCB7IGNsaWVudCB9ID0gZ2V0U2VhcmNoUnVudGltZSgpO1xuICAgICAgcmV0dXJuIGNsaWVudC5jcmVhdGVJbmRleChyZXF1ZXN0Lm5hbWUsIHRvQ3JlYXRlSW5kZXhPcHRpb25zKHJlcXVlc3QsIGNvbnRleHQ/LmFib3J0U2lnbmFsKSk7XG4gICAgfSxcbiAgfSk7XG59XG5cbi8qKiBPdXRwdXQgc2NoZW1hIGZvciB0aGUgYHN5bmNfaW5kZXhgIHRvb2wuICovXG5jb25zdCBzeW5jSW5kZXhSZXN1bHRTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIGluZGV4OiB6LnN0cmluZygpLmRlc2NyaWJlKFwiVGhlIGluZGV4IHRoYXQgd2FzIHN5bmNlZC5cIiksXG4gIHN5bmNlZDogei5ib29sZWFuKCkuZGVzY3JpYmUoXCJUcnVlIG9uY2UgdGhlIHN5bmMgd2FzIHRyaWdnZXJlZC5cIiksXG59KTtcblxuLyoqXG4gKiBCdWlsZCB0aGUgb3B0LWluIGBzeW5jX2luZGV4YCB0b29sIChyZWZyZXNoIGEgRGVsdGEgU3luYyBpbmRleCBmcm9tIGl0c1xuICogc291cmNlIHRhYmxlKS4gT25seSBpbnN0YWxsIGl0IHdoZW4gdGhlIHBsdWdpbidzIHdyaXRlIHN1cmZhY2UgaXMgZW5hYmxlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN5bmNJbmRleFRvb2wob3B0aW9uczogU2VhcmNoVG9vbE9wdGlvbnMgPSB7fSkge1xuICByZXR1cm4gY3JlYXRlVG9vbCh7XG4gICAgaWQ6IG9wdGlvbnMuaWQgPz8gXCJzeW5jX2luZGV4XCIsXG4gICAgZGVzY3JpcHRpb246IFNZTkNfSU5ERVhfVE9PTF9ERVNDUklQVElPTixcbiAgICBpbnB1dFNjaGVtYTogc3luY0luZGV4VG9vbFNjaGVtYSxcbiAgICBvdXRwdXRTY2hlbWE6IHN5bmNJbmRleFJlc3VsdFNjaGVtYSxcbiAgICBleGVjdXRlOiBhc3luYyAoaW5wdXQsIGNvbnRleHQpID0+IHtcbiAgICAgIGNvbnN0IHJlcXVlc3QgPSBzeW5jSW5kZXhUb29sU2NoZW1hLnBhcnNlKGlucHV0KTtcbiAgICAgIGNvbnN0IHsgY2xpZW50LCBjb25maWcgfSA9IGdldFNlYXJjaFJ1bnRpbWUoKTtcbiAgICAgIGNvbnN0IGluZGV4ID0gcmVxdWVzdC5pbmRleCA/PyBjb25maWcuZGVmYXVsdEluZGV4ID8/IFwiXCI7XG4gICAgICBhd2FpdCBjbGllbnQuc3luY0luZGV4KGluZGV4LCBjb250ZXh0Py5hYm9ydFNpZ25hbCk7XG4gICAgICByZXR1cm4geyBpbmRleCwgc3luY2VkOiB0cnVlIH07XG4gICAgfSxcbiAgfSk7XG59XG4iXX0=
|
|
147
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90b29sLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUVILE9BQU8sRUFBRSxNQUFNLElBQUksWUFBWSxFQUFxQixNQUFNLDBCQUEwQixDQUFDO0FBQ3JGLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsQ0FBQyxFQUFFLE1BQU0sS0FBSyxDQUFDO0FBQ3hCLE9BQU8sRUFBRSxlQUFlLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUdqRixPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUN4RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQzdDLE9BQU8sRUFBRSxtQkFBbUIsRUFBc0IsTUFBTSxjQUFjLENBQUM7QUFDdkUsT0FBTyxFQUNMLDhCQUE4QixFQUM5Qiw2QkFBNkIsRUFDN0IsdUJBQXVCLEVBQ3ZCLDJCQUEyQixFQUMzQixpQ0FBaUMsRUFDakMscUJBQXFCLEVBQ3JCLGVBQWUsRUFDZixrQkFBa0IsRUFDbEIsZ0JBQWdCLEVBQ2hCLG1CQUFtQixFQUNuQix5QkFBeUIsR0FDMUIsTUFBTSxhQUFhLENBQUM7QUFjckIsNEVBQTRFO0FBQzVFLFNBQVMsV0FBVyxDQUFDLE9BQTBCO0lBQzdDLElBQUksT0FBTyxDQUFDLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLElBQUksT0FBTyxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7UUFDL0QsTUFBTSxJQUFJLFNBQVMsQ0FBQyxvRUFBb0UsQ0FBQyxDQUFDO0lBQzVGLENBQUM7SUFDRCxPQUFPLENBQ0wsT0FBTyxDQUFDLE9BQU87UUFDZixtQkFBbUIsQ0FBQztZQUNsQixNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU07WUFDdEIsV0FBVyxFQUFFLE9BQU8sQ0FBQyxXQUFXO1NBQ2pDLENBQUMsQ0FDSCxDQUFDO0FBQ0osQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBQ0gsTUFBTSxVQUFVLFVBQVUsQ0FBQyxVQUE2QixFQUFFO0lBQ3hELE1BQU0sT0FBTyxHQUFHLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNyQyxPQUFPLFVBQVUsQ0FBQztRQUNoQixFQUFFLEVBQUUsT0FBTyxDQUFDLEVBQUUsSUFBSSxRQUFRO1FBQzFCLFdBQVcsRUFBRSx1QkFBdUI7UUFDcEMsV0FBVyxFQUFFLGdCQUFnQjtRQUM3QixZQUFZLEVBQUUsa0JBQWtCO1FBQ2hDLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFO1lBQ2hDLE1BQU0sT0FBTyxHQUFHLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUM5QyxPQUFPLE9BQU8sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsZUFBZSxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQztRQUM5RixDQUFDO0tBQ0YsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELCtFQUErRTtBQUMvRSxNQUFNLFVBQVUsbUJBQW1CLENBQUMsVUFBNkIsRUFBRTtJQUNqRSxNQUFNLE9BQU8sR0FBRyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDckMsT0FBTyxVQUFVLENBQUM7UUFDaEIsRUFBRSxFQUFFLE9BQU8sQ0FBQyxFQUFFLElBQUksa0JBQWtCO1FBQ3BDLFdBQVcsRUFBRSxpQ0FBaUM7UUFDOUMsV0FBVyxFQUFFLHlCQUF5QjtRQUN0QyxZQUFZLEVBQUUsa0JBQWtCO1FBQ2hDLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFO1lBQ2hDLE1BQU0sT0FBTyxHQUFHLHlCQUF5QixDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN2RCxPQUFPLE9BQU8sQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUNuQyxPQUFPLENBQUMsS0FBSyxFQUNiLHdCQUF3QixDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsV0FBVyxDQUFDLENBQ3hELENBQUM7UUFDSixDQUFDO0tBQ0YsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVEOzs7R0FHRztBQUNILE1BQU0sVUFBVSxnQkFBZ0IsQ0FBQyxVQUE2QixFQUFFO0lBQzlELE1BQU0sT0FBTyxHQUFHLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNyQyxNQUFNLFdBQVcsR0FBRyxZQUFZLENBQUMsb0JBQW9CO1NBQ2xELEtBQUssRUFBRTtTQUNQLFFBQVEsQ0FBQyxzRUFBc0UsQ0FBQyxDQUFDO0lBQ3BGLE9BQU8sVUFBVSxDQUFDO1FBQ2hCLEVBQUUsRUFBRSxPQUFPLENBQUMsRUFBRSxJQUFJLGVBQWU7UUFDakMsV0FBVyxFQUFFLDhCQUE4QjtRQUMzQyxXQUFXLEVBQUUsWUFBWSxDQUFDLG1CQUFtQjthQUMxQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUM7YUFDckIsTUFBTSxDQUFDLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxDQUFDO1FBQ3JDLFlBQVksRUFBRSxZQUFZLENBQUMsa0JBQWtCO1FBQzdDLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBeUIsRUFBRTtZQUN2RCxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLE9BQU8sQ0FBQztZQUNuQyxNQUFNLE1BQU0sR0FBRyxLQUErQyxDQUFDO1lBQy9ELE1BQU0sU0FBUyxHQUFHLGVBQWUsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDcEQsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLEtBQUssSUFBSSxNQUFNLENBQUMsWUFBWSxJQUFJLEVBQUUsQ0FBQztZQUN4RCxPQUFPLE1BQU0sQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDckUsQ0FBQztLQUNGLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxlQUFlLENBQUMsVUFBNkIsRUFBRTtJQUM3RCxNQUFNLE9BQU8sR0FBRyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDckMsT0FBTyxVQUFVLENBQUM7UUFDaEIsRUFBRSxFQUFFLE9BQU8sQ0FBQyxFQUFFLElBQUksY0FBYztRQUNoQyxXQUFXLEVBQUUsNkJBQTZCO1FBQzFDLFdBQVcsRUFBRSxxQkFBcUI7UUFDbEMsWUFBWSxFQUFFLGVBQWU7UUFDN0IsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7WUFDaEMsTUFBTSxPQUFPLEdBQUcscUJBQXFCLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ25ELE9BQU8sT0FBTyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQy9CLE9BQU8sQ0FBQyxJQUFJLEVBQ1osb0JBQW9CLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxXQUFXLENBQUMsQ0FDcEQsQ0FBQztRQUNKLENBQUM7S0FDRixDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQsK0NBQStDO0FBQy9DLE1BQU0scUJBQXFCLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUNyQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyw0QkFBNEIsQ0FBQztJQUN4RCxNQUFNLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLFFBQVEsQ0FBQyxtQ0FBbUMsQ0FBQztDQUNsRSxDQUFDLENBQUM7QUFFSDs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsYUFBYSxDQUFDLFVBQTZCLEVBQUU7SUFDM0QsTUFBTSxPQUFPLEdBQUcsV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3JDLE9BQU8sVUFBVSxDQUFDO1FBQ2hCLEVBQUUsRUFBRSxPQUFPLENBQUMsRUFBRSxJQUFJLFlBQVk7UUFDOUIsV0FBVyxFQUFFLDJCQUEyQjtRQUN4QyxXQUFXLEVBQUUsbUJBQW1CO1FBQ2hDLFlBQVksRUFBRSxxQkFBcUI7UUFDbkMsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7WUFDaEMsTUFBTSxPQUFPLEdBQUcsbUJBQW1CLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2pELE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsT0FBTyxDQUFDO1lBQ25DLE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxLQUFLLElBQUksTUFBTSxDQUFDLFlBQVksSUFBSSxFQUFFLENBQUM7WUFDekQsTUFBTSxNQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsV0FBVyxDQUFDLENBQUM7WUFDcEQsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUM7UUFDakMsQ0FBQztLQUNGLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFRoZSBgc2VhcmNoYCwgYHVuaXZlcnNhbF9zZWFyY2hgLCBhbmQgKG9wdC1pbikgYGFkZF9kb2N1bWVudHNgLFxuICogYGNyZWF0ZV9pbmRleGAsIGFuZCBgc3luY19pbmRleGAgTWFzdHJhIHRvb2xzLlxuICpcbiAqIEFwcC1pbnRlZ3JhdGVkIGFnZW50cyBzaG91bGQgY29uc3VtZSB0aGUgcGx1Z2luJ3MgbmF0aXZlIHRvb2xraXQgc28gY2FsbHNcbiAqIHJldGFpbiB0aGF0IHBsdWdpbidzIGNvbmZpZyBhbmQgcHJvdmlkZXIgYmFja2VuZC4gVGhlc2Ugc3RhbmRhbG9uZSBmYWN0b3JpZXNcbiAqIGNhcHR1cmUgYW4gZXhwbGljaXQgcnVudGltZSBvciBidWlsZCBhbiBpc29sYXRlZCBvbmUgZnJvbSBjb25maWcgcGx1cyBhXG4gKiBwcm92aWRlci4gVGhleSBydW4gdW5kZXIgdGhlIGNhbGxlcidzIE9CTyBzY29wZSAodGhlIGNsaWVudCByZXNvbHZlcyB0aGVcbiAqIGV4ZWN1dGlvbiBjb250ZXh0J3Mgd29ya3NwYWNlIGNsaWVudCksIHNvIHNlYXJjaCBydW5zIGFzIHRoZSByZXF1ZXN0aW5nIHVzZXJcbiAqIGFuZCBVbml0eSBDYXRhbG9nIEFDTHMgYXBwbHkuXG4gKlxuICogVGhlIHNhbWUgdG9vbHMgYXJlIGV4cG9zZWQgdG8gQXBwS2l0J3Mgb3duIGFnZW50cyB0aHJvdWdoIHRoZSBwbHVnaW4nc1xuICogYFRvb2xQcm92aWRlcmAgKHNlZSBgcGx1Z2luLnRzYCkuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IHNlYXJjaCBhcyBzaGFyZWRTZWFyY2gsIHR5cGUgVXBzZXJ0UmVzdWx0IH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLXNlYXJjaFwiO1xuaW1wb3J0IHsgY3JlYXRlVG9vbCB9IGZyb20gXCJAbWFzdHJhL2NvcmUvdG9vbHNcIjtcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5pbXBvcnQgeyB0b1NlYXJjaE9wdGlvbnMsIHRvVW5pdmVyc2FsU2VhcmNoT3B0aW9ucyB9IGZyb20gXCIuL19zZWFyY2gtb3B0aW9ucy50c1wiO1xuaW1wb3J0IHR5cGUgeyBTZWFyY2hSZWFkQmFja2VuZCB9IGZyb20gXCIuL2NsaWVudC50c1wiO1xuaW1wb3J0IHR5cGUgeyBTZWFyY2hQbHVnaW5Db25maWcgfSBmcm9tIFwiLi9jb25maWcudHNcIjtcbmltcG9ydCB7IHRvQ3JlYXRlSW5kZXhPcHRpb25zIH0gZnJvbSBcIi4vaW5kZXgtdG9vbHMudHNcIjtcbmltcG9ydCB7IHRvRG9jdW1lbnRBcnJheSB9IGZyb20gXCIuL3F1ZXJ5LnRzXCI7XG5pbXBvcnQgeyBjcmVhdGVTZWFyY2hSdW50aW1lLCB0eXBlIFNlYXJjaFJ1bnRpbWUgfSBmcm9tIFwiLi9ydW50aW1lLnRzXCI7XG5pbXBvcnQge1xuICBBRERfRE9DVU1FTlRTX1RPT0xfREVTQ1JJUFRJT04sXG4gIENSRUFURV9JTkRFWF9UT09MX0RFU0NSSVBUSU9OLFxuICBTRUFSQ0hfVE9PTF9ERVNDUklQVElPTixcbiAgU1lOQ19JTkRFWF9UT09MX0RFU0NSSVBUSU9OLFxuICBVTklWRVJTQUxfU0VBUkNIX1RPT0xfREVTQ1JJUFRJT04sXG4gIGNyZWF0ZUluZGV4VG9vbFNjaGVtYSxcbiAgaW5kZXhJbmZvU2NoZW1hLFxuICBzZWFyY2hSZXN1bHRTY2hlbWEsXG4gIHNlYXJjaFRvb2xTY2hlbWEsXG4gIHN5bmNJbmRleFRvb2xTY2hlbWEsXG4gIHVuaXZlcnNhbFNlYXJjaFRvb2xTY2hlbWEsXG59IGZyb20gXCIuL3NjaGVtYS50c1wiO1xuXG4vKiogT3B0aW9ucyBhY2NlcHRlZCBieSBldmVyeSBzdGFuZGFsb25lIHRvb2wgZmFjdG9yeS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2VhcmNoVG9vbE9wdGlvbnMge1xuICAvKiogT3ZlcnJpZGUgdGhlIHRvb2wgaWQgKGRlZmF1bHRzIHBlciB0b29sKS4gKi9cbiAgaWQ/OiBzdHJpbmc7XG4gIC8qKiBJc29sYXRlZCBydW50aW1lIHVzZWQgYnkgdGhpcyBzdGFuZGFsb25lIHRvb2wuIE11dHVhbGx5IGV4Y2x1c2l2ZSB3aXRoIGNvbmZpZy9iYWNrZW5kLiAqL1xuICBydW50aW1lPzogU2VhcmNoUnVudGltZTtcbiAgLyoqIENvbmZpZyB1c2VkIHRvIGNyZWF0ZSBhbiBpc29sYXRlZCBydW50aW1lLiAqL1xuICBjb25maWc/OiBTZWFyY2hQbHVnaW5Db25maWc7XG4gIC8qKiBQcm92aWRlciB1c2VkIHdoZW4gY3JlYXRpbmcgYSBydW50aW1lIGZyb20gY29uZmlnLiAqL1xuICByZWFkQmFja2VuZD86IFNlYXJjaFJlYWRCYWNrZW5kO1xufVxuXG4vKiogUmVzb2x2ZSB0aGUgaXNvbGF0ZWQgcnVudGltZSBjYXB0dXJlZCBieSBvbmUgc3RhbmRhbG9uZSB0b29sIGZhY3RvcnkuICovXG5mdW5jdGlvbiB0b29sUnVudGltZShvcHRpb25zOiBTZWFyY2hUb29sT3B0aW9ucyk6IFNlYXJjaFJ1bnRpbWUge1xuICBpZiAob3B0aW9ucy5ydW50aW1lICYmIChvcHRpb25zLmNvbmZpZyB8fCBvcHRpb25zLnJlYWRCYWNrZW5kKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJzZWFyY2ggdG9vbCBvcHRpb25zIGFjY2VwdCBydW50aW1lIG9yIGNvbmZpZy9yZWFkQmFja2VuZCwgbm90IGJvdGhcIik7XG4gIH1cbiAgcmV0dXJuIChcbiAgICBvcHRpb25zLnJ1bnRpbWUgPz9cbiAgICBjcmVhdGVTZWFyY2hSdW50aW1lKHtcbiAgICAgIGNvbmZpZzogb3B0aW9ucy5jb25maWcsXG4gICAgICByZWFkQmFja2VuZDogb3B0aW9ucy5yZWFkQmFja2VuZCxcbiAgICB9KVxuICApO1xufVxuXG4vKipcbiAqIEJ1aWxkIHRoZSBgc2VhcmNoYCB0b29sLiBTcHJlYWQgaXQgaW50byBhbnkgYWdlbnQgdGhhdCBzaG91bGQgYmUgYWJsZSB0byBsb29rXG4gKiB0aGluZ3MgdXAgaW4gYW4gaW5kZXguXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBzZWFyY2hUb29sIH0gZnJvbSBcIkBkYngtdG9vbHMvc2VhcmNoXCI7XG4gKiBpbXBvcnQgeyBjcmVhdGVBZ2VudCB9IGZyb20gXCJAZGJ4LXRvb2xzL2FwcGtpdC1tYXN0cmFcIjtcbiAqXG4gKiBjb25zdCBzdXBwb3J0ID0gY3JlYXRlQWdlbnQoe1xuICogICBpbnN0cnVjdGlvbnM6IFwiQW5zd2VyIGZyb20gdGhlIGRvY3MuIFVzZSBgc2VhcmNoYCB0byBmaW5kIHRoZW0uXCIsXG4gKiAgIHRvb2xzOiAoKSA9PiAoeyBzZWFyY2g6IHNlYXJjaFRvb2woKSB9KSxcbiAqIH0pO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZWFyY2hUb29sKG9wdGlvbnM6IFNlYXJjaFRvb2xPcHRpb25zID0ge30pIHtcbiAgY29uc3QgcnVudGltZSA9IHRvb2xSdW50aW1lKG9wdGlvbnMpO1xuICByZXR1cm4gY3JlYXRlVG9vbCh7XG4gICAgaWQ6IG9wdGlvbnMuaWQgPz8gXCJzZWFyY2hcIixcbiAgICBkZXNjcmlwdGlvbjogU0VBUkNIX1RPT0xfREVTQ1JJUFRJT04sXG4gICAgaW5wdXRTY2hlbWE6IHNlYXJjaFRvb2xTY2hlbWEsXG4gICAgb3V0cHV0U2NoZW1hOiBzZWFyY2hSZXN1bHRTY2hlbWEsXG4gICAgZXhlY3V0ZTogYXN5bmMgKGlucHV0LCBjb250ZXh0KSA9PiB7XG4gICAgICBjb25zdCByZXF1ZXN0ID0gc2VhcmNoVG9vbFNjaGVtYS5wYXJzZShpbnB1dCk7XG4gICAgICByZXR1cm4gcnVudGltZS5jbGllbnQuc2VhcmNoKHJlcXVlc3QucXVlcnksIHRvU2VhcmNoT3B0aW9ucyhyZXF1ZXN0LCBjb250ZXh0Py5hYm9ydFNpZ25hbCkpO1xuICAgIH0sXG4gIH0pO1xufVxuXG4vKiogQnVpbGQgdGhlIGB1bml2ZXJzYWxfc2VhcmNoYCB0b29sIChmZWRlcmF0ZWQgc2VhcmNoIGFjcm9zcyBldmVyeSBpbmRleCkuICovXG5leHBvcnQgZnVuY3Rpb24gdW5pdmVyc2FsU2VhcmNoVG9vbChvcHRpb25zOiBTZWFyY2hUb29sT3B0aW9ucyA9IHt9KSB7XG4gIGNvbnN0IHJ1bnRpbWUgPSB0b29sUnVudGltZShvcHRpb25zKTtcbiAgcmV0dXJuIGNyZWF0ZVRvb2woe1xuICAgIGlkOiBvcHRpb25zLmlkID8/IFwidW5pdmVyc2FsX3NlYXJjaFwiLFxuICAgIGRlc2NyaXB0aW9uOiBVTklWRVJTQUxfU0VBUkNIX1RPT0xfREVTQ1JJUFRJT04sXG4gICAgaW5wdXRTY2hlbWE6IHVuaXZlcnNhbFNlYXJjaFRvb2xTY2hlbWEsXG4gICAgb3V0cHV0U2NoZW1hOiBzZWFyY2hSZXN1bHRTY2hlbWEsXG4gICAgZXhlY3V0ZTogYXN5bmMgKGlucHV0LCBjb250ZXh0KSA9PiB7XG4gICAgICBjb25zdCByZXF1ZXN0ID0gdW5pdmVyc2FsU2VhcmNoVG9vbFNjaGVtYS5wYXJzZShpbnB1dCk7XG4gICAgICByZXR1cm4gcnVudGltZS5jbGllbnQudW5pdmVyc2FsU2VhcmNoKFxuICAgICAgICByZXF1ZXN0LnF1ZXJ5LFxuICAgICAgICB0b1VuaXZlcnNhbFNlYXJjaE9wdGlvbnMocmVxdWVzdCwgY29udGV4dD8uYWJvcnRTaWduYWwpLFxuICAgICAgKTtcbiAgICB9LFxuICB9KTtcbn1cblxuLyoqXG4gKiBCdWlsZCB0aGUgb3B0LWluIGBhZGRfZG9jdW1lbnRzYCB0b29sICh3cml0ZSBpbnRvIGEgZGlyZWN0LWFjY2VzcyBpbmRleCkuXG4gKiBPbmx5IGluc3RhbGwgaXQgd2hlbiB0aGUgcGx1Z2luJ3Mgd3JpdGUgc3VyZmFjZSBpcyBlbmFibGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYWRkRG9jdW1lbnRzVG9vbChvcHRpb25zOiBTZWFyY2hUb29sT3B0aW9ucyA9IHt9KSB7XG4gIGNvbnN0IHJ1bnRpbWUgPSB0b29sUnVudGltZShvcHRpb25zKTtcbiAgY29uc3QgaW5wdXRTY2hlbWEgPSBzaGFyZWRTZWFyY2guc2VhcmNoRG9jdW1lbnRTY2hlbWFcbiAgICAuYXJyYXkoKVxuICAgIC5kZXNjcmliZShcIkRvY3VtZW50cyB0byBhZGQgb3IgdXBkYXRlLiBFYWNoIG11c3QgaW5jbHVkZSB0aGUgaW5kZXggcHJpbWFyeSBrZXkuXCIpO1xuICByZXR1cm4gY3JlYXRlVG9vbCh7XG4gICAgaWQ6IG9wdGlvbnMuaWQgPz8gXCJhZGRfZG9jdW1lbnRzXCIsXG4gICAgZGVzY3JpcHRpb246IEFERF9ET0NVTUVOVFNfVE9PTF9ERVNDUklQVElPTixcbiAgICBpbnB1dFNjaGVtYTogc2hhcmVkU2VhcmNoLnNlYXJjaFJlcXVlc3RTY2hlbWFcbiAgICAgIC5waWNrKHsgaW5kZXg6IHRydWUgfSlcbiAgICAgIC5leHRlbmQoeyBkb2N1bWVudHM6IGlucHV0U2NoZW1hIH0pLFxuICAgIG91dHB1dFNjaGVtYTogc2hhcmVkU2VhcmNoLnVwc2VydFJlc3VsdFNjaGVtYSxcbiAgICBleGVjdXRlOiBhc3luYyAoaW5wdXQsIGNvbnRleHQpOiBQcm9taXNlPFVwc2VydFJlc3VsdD4gPT4ge1xuICAgICAgY29uc3QgeyBjbGllbnQsIGNvbmZpZyB9ID0gcnVudGltZTtcbiAgICAgIGNvbnN0IHJlY29yZCA9IGlucHV0IGFzIHsgaW5kZXg/OiBzdHJpbmc7IGRvY3VtZW50czogdW5rbm93biB9O1xuICAgICAgY29uc3QgZG9jdW1lbnRzID0gdG9Eb2N1bWVudEFycmF5KHJlY29yZC5kb2N1bWVudHMpO1xuICAgICAgY29uc3QgaW5kZXggPSByZWNvcmQuaW5kZXggPz8gY29uZmlnLmRlZmF1bHRJbmRleCA/PyBcIlwiO1xuICAgICAgcmV0dXJuIGNsaWVudC5hZGREb2N1bWVudHMoaW5kZXgsIGRvY3VtZW50cywgY29udGV4dD8uYWJvcnRTaWduYWwpO1xuICAgIH0sXG4gIH0pO1xufVxuXG4vKipcbiAqIEJ1aWxkIHRoZSBvcHQtaW4gYGNyZWF0ZV9pbmRleGAgdG9vbCAocHJvdmlzaW9uIGEgVmVjdG9yIFNlYXJjaCBpbmRleCkuXG4gKiBPbmx5IGluc3RhbGwgaXQgd2hlbiB0aGUgcGx1Z2luJ3Mgd3JpdGUgc3VyZmFjZSBpcyBlbmFibGVkLiBEZWxlZ2F0ZXMgdG9cbiAqIHtAbGluayBTZWFyY2hDbGllbnQuY3JlYXRlSW5kZXh9LCBpbmZlcnJpbmcgdGhlIGVuZHBvaW50LCBlbWJlZGRpbmcgbW9kZWwsXG4gKiBrZXksIGFuZCBjb2x1bW5zIGZyb20gdGhlIHJlcXVlc3QgKyBwbHVnaW4gY29uZmlnLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlSW5kZXhUb29sKG9wdGlvbnM6IFNlYXJjaFRvb2xPcHRpb25zID0ge30pIHtcbiAgY29uc3QgcnVudGltZSA9IHRvb2xSdW50aW1lKG9wdGlvbnMpO1xuICByZXR1cm4gY3JlYXRlVG9vbCh7XG4gICAgaWQ6IG9wdGlvbnMuaWQgPz8gXCJjcmVhdGVfaW5kZXhcIixcbiAgICBkZXNjcmlwdGlvbjogQ1JFQVRFX0lOREVYX1RPT0xfREVTQ1JJUFRJT04sXG4gICAgaW5wdXRTY2hlbWE6IGNyZWF0ZUluZGV4VG9vbFNjaGVtYSxcbiAgICBvdXRwdXRTY2hlbWE6IGluZGV4SW5mb1NjaGVtYSxcbiAgICBleGVjdXRlOiBhc3luYyAoaW5wdXQsIGNvbnRleHQpID0+IHtcbiAgICAgIGNvbnN0IHJlcXVlc3QgPSBjcmVhdGVJbmRleFRvb2xTY2hlbWEucGFyc2UoaW5wdXQpO1xuICAgICAgcmV0dXJuIHJ1bnRpbWUuY2xpZW50LmNyZWF0ZUluZGV4KFxuICAgICAgICByZXF1ZXN0Lm5hbWUsXG4gICAgICAgIHRvQ3JlYXRlSW5kZXhPcHRpb25zKHJlcXVlc3QsIGNvbnRleHQ/LmFib3J0U2lnbmFsKSxcbiAgICAgICk7XG4gICAgfSxcbiAgfSk7XG59XG5cbi8qKiBPdXRwdXQgc2NoZW1hIGZvciB0aGUgYHN5bmNfaW5kZXhgIHRvb2wuICovXG5jb25zdCBzeW5jSW5kZXhSZXN1bHRTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIGluZGV4OiB6LnN0cmluZygpLmRlc2NyaWJlKFwiVGhlIGluZGV4IHRoYXQgd2FzIHN5bmNlZC5cIiksXG4gIHN5bmNlZDogei5ib29sZWFuKCkuZGVzY3JpYmUoXCJUcnVlIG9uY2UgdGhlIHN5bmMgd2FzIHRyaWdnZXJlZC5cIiksXG59KTtcblxuLyoqXG4gKiBCdWlsZCB0aGUgb3B0LWluIGBzeW5jX2luZGV4YCB0b29sIChyZWZyZXNoIGEgRGVsdGEgU3luYyBpbmRleCBmcm9tIGl0c1xuICogc291cmNlIHRhYmxlKS4gT25seSBpbnN0YWxsIGl0IHdoZW4gdGhlIHBsdWdpbidzIHdyaXRlIHN1cmZhY2UgaXMgZW5hYmxlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN5bmNJbmRleFRvb2wob3B0aW9uczogU2VhcmNoVG9vbE9wdGlvbnMgPSB7fSkge1xuICBjb25zdCBydW50aW1lID0gdG9vbFJ1bnRpbWUob3B0aW9ucyk7XG4gIHJldHVybiBjcmVhdGVUb29sKHtcbiAgICBpZDogb3B0aW9ucy5pZCA/PyBcInN5bmNfaW5kZXhcIixcbiAgICBkZXNjcmlwdGlvbjogU1lOQ19JTkRFWF9UT09MX0RFU0NSSVBUSU9OLFxuICAgIGlucHV0U2NoZW1hOiBzeW5jSW5kZXhUb29sU2NoZW1hLFxuICAgIG91dHB1dFNjaGVtYTogc3luY0luZGV4UmVzdWx0U2NoZW1hLFxuICAgIGV4ZWN1dGU6IGFzeW5jIChpbnB1dCwgY29udGV4dCkgPT4ge1xuICAgICAgY29uc3QgcmVxdWVzdCA9IHN5bmNJbmRleFRvb2xTY2hlbWEucGFyc2UoaW5wdXQpO1xuICAgICAgY29uc3QgeyBjbGllbnQsIGNvbmZpZyB9ID0gcnVudGltZTtcbiAgICAgIGNvbnN0IGluZGV4ID0gcmVxdWVzdC5pbmRleCA/PyBjb25maWcuZGVmYXVsdEluZGV4ID8/IFwiXCI7XG4gICAgICBhd2FpdCBjbGllbnQuc3luY0luZGV4KGluZGV4LCBjb250ZXh0Py5hYm9ydFNpZ25hbCk7XG4gICAgICByZXR1cm4geyBpbmRleCwgc3luY2VkOiB0cnVlIH07XG4gICAgfSxcbiAgfSk7XG59XG4iXX0=
|
package/package.json
CHANGED
|
@@ -29,12 +29,12 @@
|
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@databricks/appkit": "^0.60.0",
|
|
31
31
|
"@databricks/sdk-experimental": "^0.17.0",
|
|
32
|
-
"@dbx-tools/appkit": "0.6.
|
|
33
|
-
"@dbx-tools/core": "0.6.
|
|
34
|
-
"@dbx-tools/model": "0.6.
|
|
35
|
-
"@dbx-tools/shared-core": "0.6.
|
|
36
|
-
"@dbx-tools/shared-model": "0.6.
|
|
37
|
-
"@dbx-tools/shared-search": "0.6.
|
|
32
|
+
"@dbx-tools/appkit": "0.6.224",
|
|
33
|
+
"@dbx-tools/core": "0.6.224",
|
|
34
|
+
"@dbx-tools/model": "0.6.224",
|
|
35
|
+
"@dbx-tools/shared-core": "0.6.224",
|
|
36
|
+
"@dbx-tools/shared-model": "0.6.224",
|
|
37
|
+
"@dbx-tools/shared-search": "0.6.224",
|
|
38
38
|
"@mastra/core": "1.71.0",
|
|
39
39
|
"pg": "^8.22.0",
|
|
40
40
|
"zod": "4.3.6"
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"./package.json": "./package.json"
|
|
54
54
|
}
|
|
55
55
|
},
|
|
56
|
-
"version": "0.6.
|
|
56
|
+
"version": "0.6.224",
|
|
57
57
|
"types": "./lib/index.d.ts",
|
|
58
58
|
"type": "module",
|
|
59
59
|
"exports": {
|
package/src/plugin.ts
CHANGED
|
@@ -34,12 +34,12 @@ import {
|
|
|
34
34
|
import { plugin as appkitPlugin } from "@dbx-tools/appkit";
|
|
35
35
|
import { error as sharedError, log, string } from "@dbx-tools/shared-core";
|
|
36
36
|
import { search as sharedSearch, type SearchClientConfig } from "@dbx-tools/shared-search";
|
|
37
|
+
import { toSearchOptions, toUniversalSearchOptions } from "./_search-options.ts";
|
|
37
38
|
import { SEARCH_CONFIG_SCHEMA, resolveSearchConfig, type SearchPluginConfig } from "./config.ts";
|
|
38
39
|
import { toCreateIndexOptions } from "./index-tools.ts";
|
|
39
40
|
import { nativeAiSearchBackend } from "./native.ts";
|
|
40
41
|
import { toDocumentArray } from "./query.ts";
|
|
41
|
-
import {
|
|
42
|
-
import { toSearchOptions, toUniversalSearchOptions } from "./_search-options.ts";
|
|
42
|
+
import { createSearchRuntime, setSearchReadBackend, type SearchRuntime } from "./runtime.ts";
|
|
43
43
|
import {
|
|
44
44
|
ADD_DOCUMENTS_TOOL_DESCRIPTION,
|
|
45
45
|
CREATE_INDEX_TOOL_DESCRIPTION,
|
|
@@ -110,6 +110,9 @@ export class SearchPlugin extends Plugin<SearchPluginConfig> implements ToolProv
|
|
|
110
110
|
config: { schema: SEARCH_CONFIG_SCHEMA },
|
|
111
111
|
} satisfies PluginManifest<"search">;
|
|
112
112
|
|
|
113
|
+
/** Runtime owned exclusively by this plugin instance. */
|
|
114
|
+
private readonly runtime: SearchRuntime = createSearchRuntime({ config: this.config });
|
|
115
|
+
|
|
113
116
|
/** The base path AppKit mounts this plugin's routes under. */
|
|
114
117
|
private get basePath(): string {
|
|
115
118
|
return `/api/${SearchPlugin.manifest.name}`;
|
|
@@ -123,7 +126,7 @@ export class SearchPlugin extends Plugin<SearchPluginConfig> implements ToolProv
|
|
|
123
126
|
* granted explicitly.
|
|
124
127
|
*/
|
|
125
128
|
private get tools(): ToolRegistry {
|
|
126
|
-
const { config, readBackend } =
|
|
129
|
+
const { config, readBackend } = this.runtime;
|
|
127
130
|
const registry: ToolRegistry = {
|
|
128
131
|
search: defineTool({
|
|
129
132
|
description: SEARCH_TOOL_DESCRIPTION,
|
|
@@ -170,16 +173,11 @@ export class SearchPlugin extends Plugin<SearchPluginConfig> implements ToolProv
|
|
|
170
173
|
return registry;
|
|
171
174
|
}
|
|
172
175
|
|
|
173
|
-
/**
|
|
176
|
+
/** Attach the registered provider and log the effective policy at boot. */
|
|
174
177
|
override async setup(): Promise<void> {
|
|
175
178
|
const readBackend = this.resolveProviderBackend();
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
resetSearchRuntime();
|
|
179
|
-
const { config } = getSearchRuntime({
|
|
180
|
-
config: this.config,
|
|
181
|
-
readBackend,
|
|
182
|
-
});
|
|
179
|
+
setSearchReadBackend(this.runtime, readBackend);
|
|
180
|
+
const { config } = this.runtime;
|
|
183
181
|
logger.info("ready", {
|
|
184
182
|
backend: readBackend.supportsLifecycle ? "appkit-ai-search" : "lakebase-ai-search",
|
|
185
183
|
defaultIndex: config.defaultIndex ?? "(none - pass per request)",
|
|
@@ -211,9 +209,7 @@ export class SearchPlugin extends Plugin<SearchPluginConfig> implements ToolProv
|
|
|
211
209
|
* out-of-request fallback. Failures are logged, never thrown - a search app
|
|
212
210
|
* should still start even if provisioning is slow or a permission is missing.
|
|
213
211
|
*/
|
|
214
|
-
private async runEnsureOnSetup(
|
|
215
|
-
config: ReturnType<typeof getSearchRuntime>["config"],
|
|
216
|
-
): Promise<void> {
|
|
212
|
+
private async runEnsureOnSetup(config: SearchRuntime["config"]): Promise<void> {
|
|
217
213
|
const spec = config.ensureOnSetup;
|
|
218
214
|
if (!spec) return;
|
|
219
215
|
const index = string.trimToNull(spec.index) ?? config.defaultIndex;
|
|
@@ -232,7 +228,7 @@ export class SearchPlugin extends Plugin<SearchPluginConfig> implements ToolProv
|
|
|
232
228
|
: undefined);
|
|
233
229
|
try {
|
|
234
230
|
logger.info("ensure-start", { index });
|
|
235
|
-
const { client } =
|
|
231
|
+
const { client } = this.runtime;
|
|
236
232
|
const info = await client.provision(index, {
|
|
237
233
|
...(spec.endpoint ? { endpoint: spec.endpoint } : {}),
|
|
238
234
|
...(spec.primaryKey ? { primaryKey: spec.primaryKey } : {}),
|
|
@@ -274,14 +270,13 @@ export class SearchPlugin extends Plugin<SearchPluginConfig> implements ToolProv
|
|
|
274
270
|
return schema;
|
|
275
271
|
}
|
|
276
272
|
|
|
277
|
-
/**
|
|
278
|
-
|
|
279
|
-
|
|
273
|
+
/** Release this plugin's instance-owned runtime. */
|
|
274
|
+
shutdown(): void {
|
|
275
|
+
return;
|
|
280
276
|
}
|
|
281
277
|
|
|
282
278
|
override abortActiveOperations(): void {
|
|
283
279
|
super.abortActiveOperations();
|
|
284
|
-
void this.shutdown();
|
|
285
280
|
}
|
|
286
281
|
|
|
287
282
|
/**
|
|
@@ -313,7 +308,7 @@ export class SearchPlugin extends Plugin<SearchPluginConfig> implements ToolProv
|
|
|
313
308
|
method: "post",
|
|
314
309
|
path: DOCUMENTS_ROUTE,
|
|
315
310
|
handler: async (req, res) => {
|
|
316
|
-
const { config } =
|
|
311
|
+
const { config } = this.runtime;
|
|
317
312
|
if (!config.allowWrite) {
|
|
318
313
|
res.status(403).json({ error: "the document write surface is disabled" });
|
|
319
314
|
return;
|
|
@@ -328,7 +323,7 @@ export class SearchPlugin extends Plugin<SearchPluginConfig> implements ToolProv
|
|
|
328
323
|
method: "post",
|
|
329
324
|
path: INDEX_ROUTE,
|
|
330
325
|
handler: async (req, res) => {
|
|
331
|
-
const { config, readBackend } =
|
|
326
|
+
const { config, readBackend } = this.runtime;
|
|
332
327
|
if (!config.allowWrite || !readBackend?.supportsLifecycle) {
|
|
333
328
|
res.status(403).json({ error: "the index write surface is disabled" });
|
|
334
329
|
return;
|
|
@@ -343,7 +338,7 @@ export class SearchPlugin extends Plugin<SearchPluginConfig> implements ToolProv
|
|
|
343
338
|
method: "post",
|
|
344
339
|
path: INDEX_SYNC_ROUTE,
|
|
345
340
|
handler: async (req, res) => {
|
|
346
|
-
const { config, readBackend } =
|
|
341
|
+
const { config, readBackend } = this.runtime;
|
|
347
342
|
if (!config.allowWrite || !readBackend?.supportsLifecycle) {
|
|
348
343
|
res.status(403).json({ error: "the index write surface is disabled" });
|
|
349
344
|
return;
|
|
@@ -378,7 +373,7 @@ export class SearchPlugin extends Plugin<SearchPluginConfig> implements ToolProv
|
|
|
378
373
|
|
|
379
374
|
/** Surface the index catalogue + defaults so a search box needs no round-trip. */
|
|
380
375
|
override clientConfig(): Record<string, unknown> {
|
|
381
|
-
const { config } =
|
|
376
|
+
const { config } = this.runtime;
|
|
382
377
|
const payload: SearchClientConfig = {
|
|
383
378
|
indexes: config.indexes.map((index) => ({
|
|
384
379
|
name: index.name,
|
|
@@ -426,19 +421,19 @@ export class SearchPlugin extends Plugin<SearchPluginConfig> implements ToolProv
|
|
|
426
421
|
|
|
427
422
|
private async runSearch(args: unknown, signal?: AbortSignal) {
|
|
428
423
|
const request = sharedSearch.searchRequestSchema.parse(args);
|
|
429
|
-
const { client } =
|
|
424
|
+
const { client } = this.runtime;
|
|
430
425
|
return client.search(request.query, toSearchOptions(request, signal));
|
|
431
426
|
}
|
|
432
427
|
|
|
433
428
|
private async runUniversalSearch(args: unknown, signal?: AbortSignal) {
|
|
434
429
|
const request = sharedSearch.universalSearchRequestSchema.parse(args);
|
|
435
|
-
const { client } =
|
|
430
|
+
const { client } = this.runtime;
|
|
436
431
|
return client.universalSearch(request.query, toUniversalSearchOptions(request, signal));
|
|
437
432
|
}
|
|
438
433
|
|
|
439
434
|
private async runAddDocuments(args: unknown, signal?: AbortSignal) {
|
|
440
435
|
const record = (args ?? {}) as { index?: string; documents: unknown };
|
|
441
|
-
const { client, config } =
|
|
436
|
+
const { client, config } = this.runtime;
|
|
442
437
|
const documents = toDocumentArray(record.documents);
|
|
443
438
|
const index = record.index ?? config.defaultIndex ?? "";
|
|
444
439
|
return client.addDocuments(index, documents, signal);
|
|
@@ -446,13 +441,13 @@ export class SearchPlugin extends Plugin<SearchPluginConfig> implements ToolProv
|
|
|
446
441
|
|
|
447
442
|
private async runCreateIndex(args: unknown, signal?: AbortSignal) {
|
|
448
443
|
const request = sharedSearch.createIndexRequestSchema.parse(args);
|
|
449
|
-
const { client } =
|
|
444
|
+
const { client } = this.runtime;
|
|
450
445
|
return client.createIndex(request.name, toCreateIndexOptions(request, signal));
|
|
451
446
|
}
|
|
452
447
|
|
|
453
448
|
private async runSyncIndex(args: unknown, signal?: AbortSignal) {
|
|
454
449
|
const request = sharedSearch.syncIndexRequestSchema.parse(args);
|
|
455
|
-
const { client, config } =
|
|
450
|
+
const { client, config } = this.runtime;
|
|
456
451
|
const index = request.index ?? config.defaultIndex ?? "";
|
|
457
452
|
await client.syncIndex(index, signal);
|
|
458
453
|
return { index, synced: true };
|
|
@@ -465,12 +460,14 @@ export class SearchPlugin extends Plugin<SearchPluginConfig> implements ToolProv
|
|
|
465
460
|
* @example
|
|
466
461
|
* ```ts
|
|
467
462
|
* import { createApp, server } from "@databricks/appkit";
|
|
468
|
-
* import { plugin as searchPlugin
|
|
463
|
+
* import { plugin as searchPlugin } from "@dbx-tools/search";
|
|
469
464
|
* import { agents, plugin as mastraPlugin } from "@dbx-tools/appkit-mastra";
|
|
470
465
|
*
|
|
471
466
|
* const support = agents.createAgent({
|
|
472
467
|
* instructions: "Answer from the docs; use `search` to find them.",
|
|
473
|
-
* tools
|
|
468
|
+
* async tools(plugins) {
|
|
469
|
+
* return { ...(await plugins.search.toolkit()) };
|
|
470
|
+
* },
|
|
474
471
|
* });
|
|
475
472
|
*
|
|
476
473
|
* await createApp({
|
package/src/runtime.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
2
|
+
* AI Search runtime construction helpers.
|
|
3
|
+
*
|
|
4
|
+
* Each plugin and standalone tool set owns its runtime and client. Provider
|
|
5
|
+
* attachment updates only that runtime, so two apps in one process can use
|
|
6
|
+
* different backends without sharing state.
|
|
7
7
|
*
|
|
8
8
|
* @module
|
|
9
9
|
*/
|
|
@@ -15,40 +15,49 @@ import {
|
|
|
15
15
|
type ResolvedSearchConfig,
|
|
16
16
|
} from "./config.ts";
|
|
17
17
|
|
|
18
|
-
/** Configuration and provider used to build
|
|
18
|
+
/** Configuration and provider used to build an extension runtime. */
|
|
19
19
|
export interface SearchRuntimeOptions {
|
|
20
20
|
config?: SearchPluginConfig;
|
|
21
21
|
readBackend?: SearchReadBackend;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
/** The
|
|
24
|
+
/** The resolved config plus the client reads run through. */
|
|
25
25
|
export interface SearchRuntime {
|
|
26
26
|
config: ResolvedSearchConfig;
|
|
27
27
|
client: SearchClient;
|
|
28
28
|
readBackend?: SearchReadBackend;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
/** Build an isolated runtime for one plugin instance or standalone tool set. */
|
|
32
|
+
export function createSearchRuntime(options: SearchRuntimeOptions = {}): SearchRuntime {
|
|
33
|
+
const config = resolveSearchConfig(options.config);
|
|
34
|
+
return {
|
|
35
|
+
config,
|
|
36
|
+
client: createSearchClient(config, undefined, options.readBackend),
|
|
37
|
+
...(options.readBackend ? { readBackend: options.readBackend } : {}),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Attach a provider to one runtime while preserving its object identity. */
|
|
42
|
+
export function setSearchReadBackend(runtime: SearchRuntime, readBackend: SearchReadBackend): void {
|
|
43
|
+
runtime.readBackend = readBackend;
|
|
44
|
+
runtime.client = createSearchClient(runtime.config, undefined, readBackend);
|
|
45
|
+
}
|
|
32
46
|
|
|
33
47
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
48
|
+
* Build an isolated standalone runtime.
|
|
49
|
+
*
|
|
50
|
+
* @deprecated Use {@link createSearchRuntime}. This compatibility helper
|
|
51
|
+
* returns a new runtime on every call and never reads or updates plugin state.
|
|
38
52
|
*/
|
|
39
53
|
export function getSearchRuntime(options?: SearchRuntimeOptions): SearchRuntime {
|
|
40
|
-
|
|
41
|
-
const config = resolveSearchConfig(options?.config);
|
|
42
|
-
runtime = {
|
|
43
|
-
config,
|
|
44
|
-
client: createSearchClient(config, undefined, options?.readBackend),
|
|
45
|
-
...(options?.readBackend ? { readBackend: options.readBackend } : {}),
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
return runtime;
|
|
54
|
+
return createSearchRuntime(options);
|
|
49
55
|
}
|
|
50
56
|
|
|
51
|
-
/**
|
|
57
|
+
/**
|
|
58
|
+
* @deprecated Plugin runtimes are instance-owned and need no global reset.
|
|
59
|
+
* This compatibility helper is intentionally a no-op.
|
|
60
|
+
*/
|
|
52
61
|
export function resetSearchRuntime(): void {
|
|
53
|
-
|
|
62
|
+
return;
|
|
54
63
|
}
|