@dbx-tools/shared-search 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.
package/README.md CHANGED
@@ -24,9 +24,9 @@ Key features:
24
24
  ## Validate A Search Request
25
25
 
26
26
  ```ts
27
- import { search, type SearchRequest } from "@dbx-tools/shared-search";
27
+ import { searchSchemas, type SearchRequest } from "@dbx-tools/shared-search";
28
28
 
29
- const request: SearchRequest = search.searchRequestSchema.parse({
29
+ const request: SearchRequest = searchSchemas.searchRequestSchema.parse({
30
30
  query: "reset my password",
31
31
  index: "main.support.docs",
32
32
  limit: 5,
package/index.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  // Hand edits are overwritten on the next watch; this file is read-only.
4
4
 
5
5
  export const PACKAGE_IDENTIFIER = "@dbx-tools/shared-search";
6
- export const PACKAGE_VERSION = "0.9.5";
7
- export * as search from "./src/search.ts";
8
- export { searchModeSchema, searchRequestSchema, searchHitSchema, searchResultSchema, universalSearchRequestSchema, searchDocumentSchema, upsertResultSchema, searchIndexInfoSchema, searchClientConfigSchema, createIndexRequestSchema, syncIndexRequestSchema, indexInfoSchema } from "./src/search.ts";
9
- export type { SearchMode, AiSearchQueryType, SearchRequest, SearchHit, SearchResult, UniversalSearchRequest, SearchDocument, UpsertResult, SearchIndexInfo, SearchClientConfig, CreateIndexRequest, SyncIndexRequest, IndexInfo } from "./src/search.ts";
6
+ export const PACKAGE_VERSION = "0.9.6";
7
+ export * as searchSchemas from "./src/search-schemas.ts";
8
+ export { searchModeSchema, searchRequestSchema, searchHitSchema, searchResultSchema, universalSearchRequestSchema, searchDocumentSchema, upsertResultSchema, searchIndexInfoSchema, searchClientConfigSchema, createIndexRequestSchema, syncIndexRequestSchema, indexInfoSchema } from "./src/search-schemas.ts";
9
+ export type { SearchMode, AiSearchQueryType, SearchRequest, SearchHit, SearchResult, UniversalSearchRequest, SearchDocument, UpsertResult, SearchIndexInfo, SearchClientConfig, CreateIndexRequest, SyncIndexRequest, IndexInfo } from "./src/search-schemas.ts";
package/lib/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export declare const PACKAGE_IDENTIFIER = "@dbx-tools/shared-search";
2
- export declare const PACKAGE_VERSION = "0.9.5";
3
- export * as search from "./src/search.ts";
4
- export { searchModeSchema, searchRequestSchema, searchHitSchema, searchResultSchema, universalSearchRequestSchema, searchDocumentSchema, upsertResultSchema, searchIndexInfoSchema, searchClientConfigSchema, createIndexRequestSchema, syncIndexRequestSchema, indexInfoSchema } from "./src/search.ts";
5
- export type { SearchMode, AiSearchQueryType, SearchRequest, SearchHit, SearchResult, UniversalSearchRequest, SearchDocument, UpsertResult, SearchIndexInfo, SearchClientConfig, CreateIndexRequest, SyncIndexRequest, IndexInfo } from "./src/search.ts";
2
+ export declare const PACKAGE_VERSION = "0.9.6";
3
+ export * as searchSchemas from "./src/search-schemas.ts";
4
+ export { searchModeSchema, searchRequestSchema, searchHitSchema, searchResultSchema, universalSearchRequestSchema, searchDocumentSchema, upsertResultSchema, searchIndexInfoSchema, searchClientConfigSchema, createIndexRequestSchema, syncIndexRequestSchema, indexInfoSchema } from "./src/search-schemas.ts";
5
+ export type { SearchMode, AiSearchQueryType, SearchRequest, SearchHit, SearchResult, UniversalSearchRequest, SearchDocument, UpsertResult, SearchIndexInfo, SearchClientConfig, CreateIndexRequest, SyncIndexRequest, IndexInfo } from "./src/search-schemas.ts";
package/lib/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // Regenerated from the exporting modules in ./src.
3
3
  // Hand edits are overwritten on the next watch; this file is read-only.
4
4
  export const PACKAGE_IDENTIFIER = "@dbx-tools/shared-search";
5
- export const PACKAGE_VERSION = "0.9.5";
6
- export * as search from "./src/search.js";
7
- export { searchModeSchema, searchRequestSchema, searchHitSchema, searchResultSchema, universalSearchRequestSchema, searchDocumentSchema, upsertResultSchema, searchIndexInfoSchema, searchClientConfigSchema, createIndexRequestSchema, syncIndexRequestSchema, indexInfoSchema } from "./src/search.js";
8
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRywwQkFBMEIsQ0FBQztBQUM3RCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsT0FBTyxDQUFDO0FBQ3ZDLE9BQU8sS0FBSyxNQUFNLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLG1CQUFtQixFQUFFLGVBQWUsRUFBRSxrQkFBa0IsRUFBRSw0QkFBNEIsRUFBRSxvQkFBb0IsRUFBRSxrQkFBa0IsRUFBRSxxQkFBcUIsRUFBRSx3QkFBd0IsRUFBRSx3QkFBd0IsRUFBRSxzQkFBc0IsRUFBRSxlQUFlLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEdFTkVSQVRFRCBieSBwcm9qZW4gd2F0Y2ggLSBETyBOT1QgRURJVC5cbi8vIFJlZ2VuZXJhdGVkIGZyb20gdGhlIGV4cG9ydGluZyBtb2R1bGVzIGluIC4vc3JjLlxuLy8gSGFuZCBlZGl0cyBhcmUgb3ZlcndyaXR0ZW4gb24gdGhlIG5leHQgd2F0Y2g7IHRoaXMgZmlsZSBpcyByZWFkLW9ubHkuXG5cbmV4cG9ydCBjb25zdCBQQUNLQUdFX0lERU5USUZJRVIgPSBcIkBkYngtdG9vbHMvc2hhcmVkLXNlYXJjaFwiO1xuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfVkVSU0lPTiA9IFwiMC45LjVcIjtcbmV4cG9ydCAqIGFzIHNlYXJjaCBmcm9tIFwiLi9zcmMvc2VhcmNoLnRzXCI7XG5leHBvcnQgeyBzZWFyY2hNb2RlU2NoZW1hLCBzZWFyY2hSZXF1ZXN0U2NoZW1hLCBzZWFyY2hIaXRTY2hlbWEsIHNlYXJjaFJlc3VsdFNjaGVtYSwgdW5pdmVyc2FsU2VhcmNoUmVxdWVzdFNjaGVtYSwgc2VhcmNoRG9jdW1lbnRTY2hlbWEsIHVwc2VydFJlc3VsdFNjaGVtYSwgc2VhcmNoSW5kZXhJbmZvU2NoZW1hLCBzZWFyY2hDbGllbnRDb25maWdTY2hlbWEsIGNyZWF0ZUluZGV4UmVxdWVzdFNjaGVtYSwgc3luY0luZGV4UmVxdWVzdFNjaGVtYSwgaW5kZXhJbmZvU2NoZW1hIH0gZnJvbSBcIi4vc3JjL3NlYXJjaC50c1wiO1xuZXhwb3J0IHR5cGUgeyBTZWFyY2hNb2RlLCBBaVNlYXJjaFF1ZXJ5VHlwZSwgU2VhcmNoUmVxdWVzdCwgU2VhcmNoSGl0LCBTZWFyY2hSZXN1bHQsIFVuaXZlcnNhbFNlYXJjaFJlcXVlc3QsIFNlYXJjaERvY3VtZW50LCBVcHNlcnRSZXN1bHQsIFNlYXJjaEluZGV4SW5mbywgU2VhcmNoQ2xpZW50Q29uZmlnLCBDcmVhdGVJbmRleFJlcXVlc3QsIFN5bmNJbmRleFJlcXVlc3QsIEluZGV4SW5mbyB9IGZyb20gXCIuL3NyYy9zZWFyY2gudHNcIjtcbiJdfQ==
5
+ export const PACKAGE_VERSION = "0.9.6";
6
+ export * as searchSchemas from "./src/search-schemas.js";
7
+ export { searchModeSchema, searchRequestSchema, searchHitSchema, searchResultSchema, universalSearchRequestSchema, searchDocumentSchema, upsertResultSchema, searchIndexInfoSchema, searchClientConfigSchema, createIndexRequestSchema, syncIndexRequestSchema, indexInfoSchema } from "./src/search-schemas.js";
8
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRywwQkFBMEIsQ0FBQztBQUM3RCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsT0FBTyxDQUFDO0FBQ3ZDLE9BQU8sS0FBSyxhQUFhLE1BQU0seUJBQXlCLENBQUM7QUFDekQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLG1CQUFtQixFQUFFLGVBQWUsRUFBRSxrQkFBa0IsRUFBRSw0QkFBNEIsRUFBRSxvQkFBb0IsRUFBRSxrQkFBa0IsRUFBRSxxQkFBcUIsRUFBRSx3QkFBd0IsRUFBRSx3QkFBd0IsRUFBRSxzQkFBc0IsRUFBRSxlQUFlLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEdFTkVSQVRFRCBieSBwcm9qZW4gd2F0Y2ggLSBETyBOT1QgRURJVC5cbi8vIFJlZ2VuZXJhdGVkIGZyb20gdGhlIGV4cG9ydGluZyBtb2R1bGVzIGluIC4vc3JjLlxuLy8gSGFuZCBlZGl0cyBhcmUgb3ZlcndyaXR0ZW4gb24gdGhlIG5leHQgd2F0Y2g7IHRoaXMgZmlsZSBpcyByZWFkLW9ubHkuXG5cbmV4cG9ydCBjb25zdCBQQUNLQUdFX0lERU5USUZJRVIgPSBcIkBkYngtdG9vbHMvc2hhcmVkLXNlYXJjaFwiO1xuZXhwb3J0IGNvbnN0IFBBQ0tBR0VfVkVSU0lPTiA9IFwiMC45LjZcIjtcbmV4cG9ydCAqIGFzIHNlYXJjaFNjaGVtYXMgZnJvbSBcIi4vc3JjL3NlYXJjaC1zY2hlbWFzLnRzXCI7XG5leHBvcnQgeyBzZWFyY2hNb2RlU2NoZW1hLCBzZWFyY2hSZXF1ZXN0U2NoZW1hLCBzZWFyY2hIaXRTY2hlbWEsIHNlYXJjaFJlc3VsdFNjaGVtYSwgdW5pdmVyc2FsU2VhcmNoUmVxdWVzdFNjaGVtYSwgc2VhcmNoRG9jdW1lbnRTY2hlbWEsIHVwc2VydFJlc3VsdFNjaGVtYSwgc2VhcmNoSW5kZXhJbmZvU2NoZW1hLCBzZWFyY2hDbGllbnRDb25maWdTY2hlbWEsIGNyZWF0ZUluZGV4UmVxdWVzdFNjaGVtYSwgc3luY0luZGV4UmVxdWVzdFNjaGVtYSwgaW5kZXhJbmZvU2NoZW1hIH0gZnJvbSBcIi4vc3JjL3NlYXJjaC1zY2hlbWFzLnRzXCI7XG5leHBvcnQgdHlwZSB7IFNlYXJjaE1vZGUsIEFpU2VhcmNoUXVlcnlUeXBlLCBTZWFyY2hSZXF1ZXN0LCBTZWFyY2hIaXQsIFNlYXJjaFJlc3VsdCwgVW5pdmVyc2FsU2VhcmNoUmVxdWVzdCwgU2VhcmNoRG9jdW1lbnQsIFVwc2VydFJlc3VsdCwgU2VhcmNoSW5kZXhJbmZvLCBTZWFyY2hDbGllbnRDb25maWcsIENyZWF0ZUluZGV4UmVxdWVzdCwgU3luY0luZGV4UmVxdWVzdCwgSW5kZXhJbmZvIH0gZnJvbSBcIi4vc3JjL3NlYXJjaC1zY2hlbWFzLnRzXCI7XG4iXX0=
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Wire-format contract for the AI Search add-on: the query a caller (a UI
3
+ * search box, a Mastra tool, a universal-search route) sends and the hits it
4
+ * gets back, plus the document shape used to add / update index contents.
5
+ *
6
+ * Pure (zod + inferred types, no Node-only imports) so the server-side client
7
+ * in `@dbx-tools/search`, the Mastra tool, the `POST /api/search` route,
8
+ * and the React search box all validate / type against ONE definition.
9
+ *
10
+ * "AI Search" is Databricks' current name for Vector Search: an index built
11
+ * from a Delta table (or written directly) that answers a natural-language
12
+ * query with the most relevant rows, combining vector similarity with BM25
13
+ * keyword matching (hybrid). This contract is index-agnostic - it names the
14
+ * index by its Unity Catalog path and returns hits as `{ id, score, fields }`
15
+ * so the same shape serves an autocomplete box, a docs lookup, and a
16
+ * federated search across many indexes.
17
+ *
18
+ * Array fields intentionally avoid `.min()` / `.nonempty()`: those emit
19
+ * `minItems` in the JSON schema, which some Model Serving endpoints reject
20
+ * when the schema is forwarded as a tool definition.
21
+ *
22
+ * @module
23
+ */
24
+ import { z } from "zod";
25
+ /**
26
+ * How a query is matched. `hybrid` (the default) fuses vector similarity with
27
+ * BM25 keyword ranking - the right choice for most search boxes and for source
28
+ * data with exact identifiers (SKUs, error codes). `vector` is pure semantic
29
+ * similarity; `keyword` is pure BM25 full-text (Beta on Databricks). The
30
+ * value maps onto the serving API's `query_type` (`ANN` / `HYBRID`).
31
+ */
32
+ export const searchModeSchema = z
33
+ .enum(["hybrid", "vector", "keyword"])
34
+ .describe("Match strategy: 'hybrid' fuses semantic similarity with keyword ranking (default, best for most searches), 'vector' is pure semantic, 'keyword' is pure full-text.");
35
+ /** Map the dbx-tools extension vocabulary onto AppKit AI Search. */
36
+ export function toAiSearchQueryType(mode) {
37
+ if (mode === "vector")
38
+ return "ann";
39
+ if (mode === "keyword")
40
+ return "full_text";
41
+ if (mode === "hybrid")
42
+ return "hybrid";
43
+ return undefined;
44
+ }
45
+ /** Schema for a search request against a single index. */
46
+ export const searchRequestSchema = z.object({
47
+ query: z
48
+ .string()
49
+ .describe("What to search for, as natural language or keywords. Prefix fragments work for autocomplete."),
50
+ index: z
51
+ .string()
52
+ .optional()
53
+ .describe("Unity Catalog name of the index to search (catalog.schema.index). Defaults to the plugin's configured index. Accepts a short alias when one is configured."),
54
+ limit: z
55
+ .number()
56
+ .int()
57
+ .positive()
58
+ .optional()
59
+ .describe("Maximum number of hits to return. Defaults to the plugin's configured page size."),
60
+ mode: searchModeSchema.optional(),
61
+ columns: z
62
+ .array(z.string())
63
+ .optional()
64
+ .describe("Which document columns to return per hit. Defaults to the plugin's configured columns (or all indexed columns)."),
65
+ filter: z
66
+ .record(z.string(), z.union([z.string(), z.number(), z.boolean(), z.array(z.union([z.string(), z.number()]))]))
67
+ .optional()
68
+ .describe("AppKit AI Search attribute filters as { column: scalarOrArray }. Combined with AND."),
69
+ scoreThreshold: z
70
+ .number()
71
+ .optional()
72
+ .describe("Drop hits whose relevance score is below this value."),
73
+ });
74
+ /** Schema for a single search hit. */
75
+ export const searchHitSchema = z.object({
76
+ id: z.string().describe("The document's primary-key value."),
77
+ score: z.number().describe("Relevance score; higher is more relevant."),
78
+ fields: z
79
+ .record(z.string(), z.unknown())
80
+ .describe("The returned columns for this document, keyed by column name."),
81
+ index: z
82
+ .string()
83
+ .optional()
84
+ .describe("Which index the hit came from (set on universal/federated results)."),
85
+ });
86
+ /** Schema for the result of a search. */
87
+ export const searchResultSchema = z.object({
88
+ query: z.string().describe("Echo of the query that was searched."),
89
+ hits: z.array(searchHitSchema).describe("Matching documents, most relevant first."),
90
+ index: z.string().optional().describe("The index searched (omitted for a universal search)."),
91
+ count: z.number().int().describe("Number of hits returned."),
92
+ });
93
+ /** Schema for a universal (federated) search across several indexes at once. */
94
+ export const universalSearchRequestSchema = z.object({
95
+ query: z.string().describe("What to search for across every configured index."),
96
+ indexes: z
97
+ .array(z.string())
98
+ .optional()
99
+ .describe("Which indexes to search. Defaults to every index the plugin knows about."),
100
+ limit: z
101
+ .number()
102
+ .int()
103
+ .positive()
104
+ .optional()
105
+ .describe("Maximum hits PER index before results are merged and re-ranked."),
106
+ mode: searchModeSchema.optional(),
107
+ });
108
+ /** Schema for a document written to a direct-access index. */
109
+ export const searchDocumentSchema = z
110
+ .record(z.string(), z.unknown())
111
+ .describe("A document as { column: value }. Must include the index primary-key column.");
112
+ /** Schema for the result of adding / updating documents. */
113
+ export const upsertResultSchema = z.object({
114
+ index: z.string().describe("The index the documents were written to."),
115
+ count: z.number().int().describe("Number of documents accepted."),
116
+ });
117
+ /**
118
+ * Schema for the boot-time index catalogue a UI reads to populate a search box
119
+ * (the payload of the plugin's client config / `GET /api/search/indexes`). An
120
+ * entry names an index, an optional short alias, and the columns worth
121
+ * showing, so a search box needs no server round-trip to render.
122
+ */
123
+ export const searchIndexInfoSchema = z.object({
124
+ name: z.string().describe("Unity Catalog name of the index (catalog.schema.index)."),
125
+ alias: z.string().optional().describe("Short alias the plugin accepts in place of `name`."),
126
+ primaryKey: z.string().optional().describe("The index's primary-key column, when known."),
127
+ columns: z
128
+ .array(z.string())
129
+ .optional()
130
+ .describe("Columns returned by default, in display order."),
131
+ isDefault: z.boolean().optional().describe("True for the plugin's default index."),
132
+ });
133
+ /** Schema for the plugin's client config surfaced to a UI. */
134
+ export const searchClientConfigSchema = z.object({
135
+ indexes: z.array(searchIndexInfoSchema).describe("Indexes the search UI may query."),
136
+ defaultIndex: z.string().optional().describe("The index a search box selects by default."),
137
+ pageSize: z.number().int().describe("Default number of hits a search returns."),
138
+ basePath: z
139
+ .string()
140
+ .describe("Base path the search routes are mounted under (e.g. /api/search)."),
141
+ });
142
+ /**
143
+ * Schema for creating an index (the `create_index` tool input / the
144
+ * `POST /api/search/index` body). Two shapes, both inferring aggressively:
145
+ * pass `sourceTable` for a Delta Sync index (Databricks computes embeddings and
146
+ * keeps it synced) or `embeddingDimension` for a direct-access index you write
147
+ * vectors to yourself.
148
+ */
149
+ export const createIndexRequestSchema = z.object({
150
+ name: z.string().describe("Unity Catalog name for the new index (catalog.schema.index)."),
151
+ sourceTable: z
152
+ .string()
153
+ .optional()
154
+ .describe("Delta table (catalog.schema.table) to build a synced index from. Provide this OR embeddingDimension."),
155
+ primaryKey: z.string().optional().describe("Primary-key column. Defaults to 'id'."),
156
+ embeddingSourceColumn: z
157
+ .string()
158
+ .optional()
159
+ .describe("Text column embeddings are computed from (Delta Sync). Defaults to the first of text/content/body."),
160
+ embeddingModel: z
161
+ .string()
162
+ .optional()
163
+ .describe("Embedding model endpoint (name or loose name). Defaults to the app's embedding model, or the best embedding endpoint in the workspace."),
164
+ endpoint: z
165
+ .string()
166
+ .optional()
167
+ .describe("Vector Search endpoint to host the index on. Defaults to the app's configured endpoint."),
168
+ embeddingDimension: z
169
+ .number()
170
+ .int()
171
+ .positive()
172
+ .optional()
173
+ .describe("For a direct-access index (no source table): the embedding vector dimension."),
174
+ pipelineType: z
175
+ .enum(["TRIGGERED", "CONTINUOUS"])
176
+ .optional()
177
+ .describe("Delta Sync mode: 'TRIGGERED' (default) syncs on demand; 'CONTINUOUS' keeps the index fresh."),
178
+ columnsToSync: z
179
+ .array(z.string())
180
+ .optional()
181
+ .describe("Extra columns to sync alongside the embedding source column (Delta Sync)."),
182
+ });
183
+ /** Schema for the `sync_index` tool input / the `POST /api/search/index/sync` body. */
184
+ export const syncIndexRequestSchema = z.object({
185
+ index: z
186
+ .string()
187
+ .describe("The index to sync (name or configured alias). Defaults to the app's default index when omitted.")
188
+ .optional(),
189
+ });
190
+ /** Schema for a resolved index definition (the create/get result). */
191
+ export const indexInfoSchema = z.object({
192
+ name: z.string().describe("Unity Catalog name of the index."),
193
+ endpoint: z.string().optional().describe("The Vector Search endpoint hosting the index."),
194
+ primaryKey: z.string().optional().describe("The index's primary-key column."),
195
+ columns: z.array(z.string()).describe("Columns available on the index."),
196
+ ready: z.boolean().describe("True when the index has finished provisioning and can be queried."),
197
+ rowCount: z.number().int().optional().describe("Number of indexed rows, when known."),
198
+ });
199
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VhcmNoLXNjaGVtYXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VhcmNoLXNjaGVtYXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FzQkc7QUFFSCxPQUFPLEVBQUUsQ0FBQyxFQUFFLE1BQU0sS0FBSyxDQUFDO0FBRXhCOzs7Ozs7R0FNRztBQUNILE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUFHLENBQUM7S0FDOUIsSUFBSSxDQUFDLENBQUMsUUFBUSxFQUFFLFFBQVEsRUFBRSxTQUFTLENBQUMsQ0FBQztLQUNyQyxRQUFRLENBQ1Asb0tBQW9LLENBQ3JLLENBQUM7QUFRSixvRUFBb0U7QUFDcEUsTUFBTSxVQUFVLG1CQUFtQixDQUFDLElBQTRCO0lBQzlELElBQUksSUFBSSxLQUFLLFFBQVE7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUNwQyxJQUFJLElBQUksS0FBSyxTQUFTO1FBQUUsT0FBTyxXQUFXLENBQUM7SUFDM0MsSUFBSSxJQUFJLEtBQUssUUFBUTtRQUFFLE9BQU8sUUFBUSxDQUFDO0lBQ3ZDLE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUM7QUFFRCwwREFBMEQ7QUFDMUQsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUMxQyxLQUFLLEVBQUUsQ0FBQztTQUNMLE1BQU0sRUFBRTtTQUNSLFFBQVEsQ0FDUCw4RkFBOEYsQ0FDL0Y7SUFDSCxLQUFLLEVBQUUsQ0FBQztTQUNMLE1BQU0sRUFBRTtTQUNSLFFBQVEsRUFBRTtTQUNWLFFBQVEsQ0FDUCw0SkFBNEosQ0FDN0o7SUFDSCxLQUFLLEVBQUUsQ0FBQztTQUNMLE1BQU0sRUFBRTtTQUNSLEdBQUcsRUFBRTtTQUNMLFFBQVEsRUFBRTtTQUNWLFFBQVEsRUFBRTtTQUNWLFFBQVEsQ0FBQyxrRkFBa0YsQ0FBQztJQUMvRixJQUFJLEVBQUUsZ0JBQWdCLENBQUMsUUFBUSxF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IjpbIi8qKlxuICogV2lyZS1mb3JtYXQgY29udHJhY3QgZm9yIHRoZSBBSSBTZWFyY2ggYWRkLW9uOiB0aGUgcXVlcnkgYSBjYWxsZXIgKGEgVUlcbiAqIHNlYXJjaCBib3gsIGEgTWFzdHJhIHRvb2wsIGEgdW5pdmVyc2FsLXNlYXJjaCByb3V0ZSkgc2VuZHMgYW5kIHRoZSBoaXRzIGl0XG4gKiBnZXRzIGJhY2ssIHBsdXMgdGhlIGRvY3VtZW50IHNoYXBlIHVzZWQgdG8gYWRkIC8gdXBkYXRlIGluZGV4IGNvbnRlbnRzLlxuICpcbiAqIFB1cmUgKHpvZCArIGluZmVycmVkIHR5cGVzLCBubyBOb2RlLW9ubHkgaW1wb3J0cykgc28gdGhlIHNlcnZlci1zaWRlIGNsaWVudFxuICogaW4gYEBkYngtdG9vbHMvc2VhcmNoYCwgdGhlIE1hc3RyYSB0b29sLCB0aGUgYFBPU1QgL2FwaS9zZWFyY2hgIHJvdXRlLFxuICogYW5kIHRoZSBSZWFjdCBzZWFyY2ggYm94IGFsbCB2YWxpZGF0ZSAvIHR5cGUgYWdhaW5zdCBPTkUgZGVmaW5pdGlvbi5cbiAqXG4gKiBcIkFJIFNlYXJjaFwiIGlzIERhdGFicmlja3MnIGN1cnJlbnQgbmFtZSBmb3IgVmVjdG9yIFNlYXJjaDogYW4gaW5kZXggYnVpbHRcbiAqIGZyb20gYSBEZWx0YSB0YWJsZSAob3Igd3JpdHRlbiBkaXJlY3RseSkgdGhhdCBhbnN3ZXJzIGEgbmF0dXJhbC1sYW5ndWFnZVxuICogcXVlcnkgd2l0aCB0aGUgbW9zdCByZWxldmFudCByb3dzLCBjb21iaW5pbmcgdmVjdG9yIHNpbWlsYXJpdHkgd2l0aCBCTTI1XG4gKiBrZXl3b3JkIG1hdGNoaW5nIChoeWJyaWQpLiBUaGlzIGNvbnRyYWN0IGlzIGluZGV4LWFnbm9zdGljIC0gaXQgbmFtZXMgdGhlXG4gKiBpbmRleCBieSBpdHMgVW5pdHkgQ2F0YWxvZyBwYXRoIGFuZCByZXR1cm5zIGhpdHMgYXMgYHsgaWQsIHNjb3JlLCBmaWVsZHMgfWBcbiAqIHNvIHRoZSBzYW1lIHNoYXBlIHNlcnZlcyBhbiBhdXRvY29tcGxldGUgYm94LCBhIGRvY3MgbG9va3VwLCBhbmQgYVxuICogZmVkZXJhdGVkIHNlYXJjaCBhY3Jvc3MgbWFueSBpbmRleGVzLlxuICpcbiAqIEFycmF5IGZpZWxkcyBpbnRlbnRpb25hbGx5IGF2b2lkIGAubWluKClgIC8gYC5ub25lbXB0eSgpYDogdGhvc2UgZW1pdFxuICogYG1pbkl0ZW1zYCBpbiB0aGUgSlNPTiBzY2hlbWEsIHdoaWNoIHNvbWUgTW9kZWwgU2VydmluZyBlbmRwb2ludHMgcmVqZWN0XG4gKiB3aGVuIHRoZSBzY2hlbWEgaXMgZm9yd2FyZGVkIGFzIGEgdG9vbCBkZWZpbml0aW9uLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyB6IH0gZnJvbSBcInpvZFwiO1xuXG4vKipcbiAqIEhvdyBhIHF1ZXJ5IGlzIG1hdGNoZWQuIGBoeWJyaWRgICh0aGUgZGVmYXVsdCkgZnVzZXMgdmVjdG9yIHNpbWlsYXJpdHkgd2l0aFxuICogQk0yNSBrZXl3b3JkIHJhbmtpbmcgLSB0aGUgcmlnaHQgY2hvaWNlIGZvciBtb3N0IHNlYXJjaCBib3hlcyBhbmQgZm9yIHNvdXJjZVxuICogZGF0YSB3aXRoIGV4YWN0IGlkZW50aWZpZXJzIChTS1VzLCBlcnJvciBjb2RlcykuIGB2ZWN0b3JgIGlzIHB1cmUgc2VtYW50aWNcbiAqIHNpbWlsYXJpdHk7IGBrZXl3b3JkYCBpcyBwdXJlIEJNMjUgZnVsbC10ZXh0IChCZXRhIG9uIERhdGFicmlja3MpLiBUaGVcbiAqIHZhbHVlIG1hcHMgb250byB0aGUgc2VydmluZyBBUEkncyBgcXVlcnlfdHlwZWAgKGBBTk5gIC8gYEhZQlJJRGApLlxuICovXG5leHBvcnQgY29uc3Qgc2VhcmNoTW9kZVNjaGVtYSA9IHpcbiAgLmVudW0oW1wiaHlicmlkXCIsIFwidmVjdG9yXCIsIFwia2V5d29yZFwiXSlcbiAgLmRlc2NyaWJlKFxuICAgIFwiTWF0Y2ggc3RyYXRlZ3k6ICdoeWJyaWQnIGZ1c2VzIHNlbWFudGljIHNpbWlsYXJpdHkgd2l0aCBrZXl3b3JkIHJhbmtpbmcgKGRlZmF1bHQsIGJlc3QgZm9yIG1vc3Qgc2VhcmNoZXMpLCAndmVjdG9yJyBpcyBwdXJlIHNlbWFudGljLCAna2V5d29yZCcgaXMgcHVyZSBmdWxsLXRleHQuXCIsXG4gICk7XG5cbi8qKiBIb3cgYSBxdWVyeSBpcyBtYXRjaGVkIChzZWUge0BsaW5rIHNlYXJjaE1vZGVTY2hlbWF9KS4gKi9cbmV4cG9ydCB0eXBlIFNlYXJjaE1vZGUgPSB6LmluZmVyPHR5cGVvZiBzZWFyY2hNb2RlU2NoZW1hPjtcblxuLyoqIEFwcEtpdCBBSSBTZWFyY2ggcXVlcnkgbW9kZXMuICovXG5leHBvcnQgdHlwZSBBaVNlYXJjaFF1ZXJ5VHlwZSA9IFwiYW5uXCIgfCBcImh5YnJpZFwiIHwgXCJmdWxsX3RleHRcIjtcblxuLyoqIE1hcCB0aGUgZGJ4LXRvb2xzIGV4dGVuc2lvbiB2b2NhYnVsYXJ5IG9udG8gQXBwS2l0IEFJIFNlYXJjaC4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b0FpU2VhcmNoUXVlcnlUeXBlKG1vZGU6IFNlYXJjaE1vZGUgfCB1bmRlZmluZWQpOiBBaVNlYXJjaFF1ZXJ5VHlwZSB8IHVuZGVmaW5lZCB7XG4gIGlmIChtb2RlID09PSBcInZlY3RvclwiKSByZXR1cm4gXCJhbm5cIjtcbiAgaWYgKG1vZGUgPT09IFwia2V5d29yZFwiKSByZXR1cm4gXCJmdWxsX3RleHRcIjtcbiAgaWYgKG1vZGUgPT09IFwiaHlicmlkXCIpIHJldHVybiBcImh5YnJpZFwiO1xuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG4vKiogU2NoZW1hIGZvciBhIHNlYXJjaCByZXF1ZXN0IGFnYWluc3QgYSBzaW5nbGUgaW5kZXguICovXG5leHBvcnQgY29uc3Qgc2VhcmNoUmVxdWVzdFNjaGVtYSA9IHoub2JqZWN0KHtcbiAgcXVlcnk6IHpcbiAgICAuc3RyaW5nKClcbiAgICAuZGVzY3JpYmUoXG4gICAgICBcIldoYXQgdG8gc2VhcmNoIGZvciwgYXMgbmF0dXJhbCBsYW5ndWFnZSBvciBrZXl3b3Jkcy4gUHJlZml4IGZyYWdtZW50cyB3b3JrIGZvciBhdXRvY29tcGxldGUuXCIsXG4gICAgKSxcbiAgaW5kZXg6IHpcbiAgICAuc3RyaW5nKClcbiAgICAub3B0aW9uYWwoKVxuICAgIC5kZXNjcmliZShcbiAgICAgIFwiVW5pdHkgQ2F0YWxvZyBuYW1lIG9mIHRoZSBpbmRleCB0byBzZWFyY2ggKGNhdGFsb2cuc2NoZW1hLmluZGV4KS4gRGVmYXVsdHMgdG8gdGhlIHBsdWdpbidzIGNvbmZpZ3VyZWQgaW5kZXguIEFjY2VwdHMgYSBzaG9ydCBhbGlhcyB3aGVuIG9uZSBpcyBjb25maWd1cmVkLlwiLFxuICAgICksXG4gIGxpbWl0OiB6XG4gICAgLm51bWJlcigpXG4gICAgLmludCgpXG4gICAgLnBvc2l0aXZlKClcbiAgICAub3B0aW9uYWwoKVxuICAgIC5kZXNjcmliZShcIk1heGltdW0gbnVtYmVyIG9mIGhpdHMgdG8gcmV0dXJuLiBEZWZhdWx0cyB0byB0aGUgcGx1Z2luJ3MgY29uZmlndXJlZCBwYWdlIHNpemUuXCIpLFxuICBtb2RlOiBzZWFyY2hNb2RlU2NoZW1hLm9wdGlvbmFsKCksXG4gIGNvbHVtbnM6IHpcbiAgICAuYXJyYXkoei5zdHJpbmcoKSlcbiAgICAub3B0aW9uYWwoKVxuICAgIC5kZXNjcmliZShcbiAgICAgIFwiV2hpY2ggZG9jdW1lbnQgY29sdW1ucyB0byByZXR1cm4gcGVyIGhpdC4gRGVmYXVsdHMgdG8gdGhlIHBsdWdpbidzIGNvbmZpZ3VyZWQgY29sdW1ucyAob3IgYWxsIGluZGV4ZWQgY29sdW1ucykuXCIsXG4gICAgKSxcbiAgZmlsdGVyOiB6XG4gICAgLnJlY29yZChcbiAgICAgIHouc3RyaW5nKCksXG4gICAgICB6LnVuaW9uKFt6LnN0cmluZygpLCB6Lm51bWJlcigpLCB6LmJvb2xlYW4oKSwgei5hcnJheSh6LnVuaW9uKFt6LnN0cmluZygpLCB6Lm51bWJlcigpXSkpXSksXG4gICAgKVxuICAgIC5vcHRpb25hbCgpXG4gICAgLmRlc2NyaWJlKFxuICAgICAgXCJBcHBLaXQgQUkgU2VhcmNoIGF0dHJpYnV0ZSBmaWx0ZXJzIGFzIHsgY29sdW1uOiBzY2FsYXJPckFycmF5IH0uIENvbWJpbmVkIHdpdGggQU5ELlwiLFxuICAgICksXG4gIHNjb3JlVGhyZXNob2xkOiB6XG4gICAgLm51bWJlcigpXG4gICAgLm9wdGlvbmFsKClcbiAgICAuZGVzY3JpYmUoXCJEcm9wIGhpdHMgd2hvc2UgcmVsZXZhbmNlIHNjb3JlIGlzIGJlbG93IHRoaXMgdmFsdWUuXCIpLFxufSk7XG5cbi8qKiBBIHZhbGlkYXRlZCBzZWFyY2ggcmVxdWVzdCAoe0BsaW5rIHNlYXJjaFJlcXVlc3RTY2hlbWF9KS4gKi9cbmV4cG9ydCB0eXBlIFNlYXJjaFJlcXVlc3QgPSB6LmluZmVyPHR5cGVvZiBzZWFyY2hSZXF1ZXN0U2NoZW1hPjtcblxuLyoqIFNjaGVtYSBmb3IgYSBzaW5nbGUgc2VhcmNoIGhpdC4gKi9cbmV4cG9ydCBjb25zdCBzZWFyY2hIaXRTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIGlkOiB6LnN0cmluZygpLmRlc2NyaWJlKFwiVGhlIGRvY3VtZW50J3MgcHJpbWFyeS1rZXkgdmFsdWUuXCIpLFxuICBzY29yZTogei5udW1iZXIoKS5kZXNjcmliZShcIlJlbGV2YW5jZSBzY29yZTsgaGlnaGVyIGlzIG1vcmUgcmVsZXZhbnQuXCIpLFxuICBmaWVsZHM6IHpcbiAgICAucmVjb3JkKHouc3RyaW5nKCksIHoudW5rbm93bigpKVxuICAgIC5kZXNjcmliZShcIlRoZSByZXR1cm5lZCBjb2x1bW5zIGZvciB0aGlzIGRvY3VtZW50LCBrZXllZCBieSBjb2x1bW4gbmFtZS5cIiksXG4gIGluZGV4OiB6XG4gICAgLnN0cmluZygpXG4gICAgLm9wdGlvbmFsKClcbiAgICAuZGVzY3JpYmUoXCJXaGljaCBpbmRleCB0aGUgaGl0IGNhbWUgZnJvbSAoc2V0IG9uIHVuaXZlcnNhbC9mZWRlcmF0ZWQgcmVzdWx0cykuXCIpLFxufSk7XG5cbi8qKiBBIHNpbmdsZSBzZWFyY2ggaGl0ICh7QGxpbmsgc2VhcmNoSGl0U2NoZW1hfSkuICovXG5leHBvcnQgdHlwZSBTZWFyY2hIaXQgPSB6LmluZmVyPHR5cGVvZiBzZWFyY2hIaXRTY2hlbWE+O1xuXG4vKiogU2NoZW1hIGZvciB0aGUgcmVzdWx0IG9mIGEgc2VhcmNoLiAqL1xuZXhwb3J0IGNvbnN0IHNlYXJjaFJlc3VsdFNjaGVtYSA9IHoub2JqZWN0KHtcbiAgcXVlcnk6IHouc3RyaW5nKCkuZGVzY3JpYmUoXCJFY2hvIG9mIHRoZSBxdWVyeSB0aGF0IHdhcyBzZWFyY2hlZC5cIiksXG4gIGhpdHM6IHouYXJyYXkoc2VhcmNoSGl0U2NoZW1hKS5kZXNjcmliZShcIk1hdGNoaW5nIGRvY3VtZW50cywgbW9zdCByZWxldmFudCBmaXJzdC5cIiksXG4gIGluZGV4OiB6LnN0cmluZygpLm9wdGlvbmFsKCkuZGVzY3JpYmUoXCJUaGUgaW5kZXggc2VhcmNoZWQgKG9taXR0ZWQgZm9yIGEgdW5pdmVyc2FsIHNlYXJjaCkuXCIpLFxuICBjb3VudDogei5udW1iZXIoKS5pbnQoKS5kZXNjcmliZShcIk51bWJlciBvZiBoaXRzIHJldHVybmVkLlwiKSxcbn0pO1xuXG4vKiogVGhlIG91dGNvbWUgb2YgYSBzZWFyY2ggKHtAbGluayBzZWFyY2hSZXN1bHRTY2hlbWF9KS4gKi9cbmV4cG9ydCB0eXBlIFNlYXJjaFJlc3VsdCA9IHouaW5mZXI8dHlwZW9mIHNlYXJjaFJlc3VsdFNjaGVtYT47XG5cbi8qKiBTY2hlbWEgZm9yIGEgdW5pdmVyc2FsIChmZWRlcmF0ZWQpIHNlYXJjaCBhY3Jvc3Mgc2V2ZXJhbCBpbmRleGVzIGF0IG9uY2UuICovXG5leHBvcnQgY29uc3QgdW5pdmVyc2FsU2VhcmNoUmVxdWVzdFNjaGVtYSA9IHoub2JqZWN0KHtcbiAgcXVlcnk6IHouc3RyaW5nKCkuZGVzY3JpYmUoXCJXaGF0IHRvIHNlYXJjaCBmb3IgYWNyb3NzIGV2ZXJ5IGNvbmZpZ3VyZWQgaW5kZXguXCIpLFxuICBpbmRleGVzOiB6XG4gICAgLmFycmF5KHouc3RyaW5nKCkpXG4gICAgLm9wdGlvbmFsKClcbiAgICAuZGVzY3JpYmUoXCJXaGljaCBpbmRleGVzIHRvIHNlYXJjaC4gRGVmYXVsdHMgdG8gZXZlcnkgaW5kZXggdGhlIHBsdWdpbiBrbm93cyBhYm91dC5cIiksXG4gIGxpbWl0OiB6XG4gICAgLm51bWJlcigpXG4gICAgLmludCgpXG4gICAgLnBvc2l0aXZlKClcbiAgICAub3B0aW9uYWwoKVxuICAgIC5kZXNjcmliZShcIk1heGltdW0gaGl0cyBQRVIgaW5kZXggYmVmb3JlIHJlc3VsdHMgYXJlIG1lcmdlZCBhbmQgcmUtcmFua2VkLlwiKSxcbiAgbW9kZTogc2VhcmNoTW9kZVNjaGVtYS5vcHRpb25hbCgpLFxufSk7XG5cbi8qKiBBIHZhbGlkYXRlZCB1bml2ZXJzYWwtc2VhcmNoIHJlcXVlc3QgKHtAbGluayB1bml2ZXJzYWxTZWFyY2hSZXF1ZXN0U2NoZW1hfSkuICovXG5leHBvcnQgdHlwZSBVbml2ZXJzYWxTZWFyY2hSZXF1ZXN0ID0gei5pbmZlcjx0eXBlb2YgdW5pdmVyc2FsU2VhcmNoUmVxdWVzdFNjaGVtYT47XG5cbi8qKiBTY2hlbWEgZm9yIGEgZG9jdW1lbnQgd3JpdHRlbiB0byBhIGRpcmVjdC1hY2Nlc3MgaW5kZXguICovXG5leHBvcnQgY29uc3Qgc2VhcmNoRG9jdW1lbnRTY2hlbWEgPSB6XG4gIC5yZWNvcmQoei5zdHJpbmcoKSwgei51bmtub3duKCkpXG4gIC5kZXNjcmliZShcIkEgZG9jdW1lbnQgYXMgeyBjb2x1bW46IHZhbHVlIH0uIE11c3QgaW5jbHVkZSB0aGUgaW5kZXggcHJpbWFyeS1rZXkgY29sdW1uLlwiKTtcblxuLyoqIEEgZG9jdW1lbnQgd3JpdHRlbiB0byBhbiBpbmRleCAoe0BsaW5rIHNlYXJjaERvY3VtZW50U2NoZW1hfSkuICovXG5leHBvcnQgdHlwZSBTZWFyY2hEb2N1bWVudCA9IHouaW5mZXI8dHlwZW9mIHNlYXJjaERvY3VtZW50U2NoZW1hPjtcblxuLyoqIFNjaGVtYSBmb3IgdGhlIHJlc3VsdCBvZiBhZGRpbmcgLyB1cGRhdGluZyBkb2N1bWVudHMuICovXG5leHBvcnQgY29uc3QgdXBzZXJ0UmVzdWx0U2NoZW1hID0gei5vYmplY3Qoe1xuICBpbmRleDogei5zdHJpbmcoKS5kZXNjcmliZShcIlRoZSBpbmRleCB0aGUgZG9jdW1lbnRzIHdlcmUgd3JpdHRlbiB0by5cIiksXG4gIGNvdW50OiB6Lm51bWJlcigpLmludCgpLmRlc2NyaWJlKFwiTnVtYmVyIG9mIGRvY3VtZW50cyBhY2NlcHRlZC5cIiksXG59KTtcblxuLyoqIFRoZSBvdXRjb21lIG9mIGFuIGFkZC1kb2N1bWVudHMgY2FsbCAoe0BsaW5rIHVwc2VydFJlc3VsdFNjaGVtYX0pLiAqL1xuZXhwb3J0IHR5cGUgVXBzZXJ0UmVzdWx0ID0gei5pbmZlcjx0eXBlb2YgdXBzZXJ0UmVzdWx0U2NoZW1hPjtcblxuLyoqXG4gKiBTY2hlbWEgZm9yIHRoZSBib290LXRpbWUgaW5kZXggY2F0YWxvZ3VlIGEgVUkgcmVhZHMgdG8gcG9wdWxhdGUgYSBzZWFyY2ggYm94XG4gKiAodGhlIHBheWxvYWQgb2YgdGhlIHBsdWdpbidzIGNsaWVudCBjb25maWcgLyBgR0VUIC9hcGkvc2VhcmNoL2luZGV4ZXNgKS4gQW5cbiAqIGVudHJ5IG5hbWVzIGFuIGluZGV4LCBhbiBvcHRpb25hbCBzaG9ydCBhbGlhcywgYW5kIHRoZSBjb2x1bW5zIHdvcnRoXG4gKiBzaG93aW5nLCBzbyBhIHNlYXJjaCBib3ggbmVlZHMgbm8gc2VydmVyIHJvdW5kLXRyaXAgdG8gcmVuZGVyLlxuICovXG5leHBvcnQgY29uc3Qgc2VhcmNoSW5kZXhJbmZvU2NoZW1hID0gei5vYmplY3Qoe1xuICBuYW1lOiB6LnN0cmluZygpLmRlc2NyaWJlKFwiVW5pdHkgQ2F0YWxvZyBuYW1lIG9mIHRoZSBpbmRleCAoY2F0YWxvZy5zY2hlbWEuaW5kZXgpLlwiKSxcbiAgYWxpYXM6IHouc3RyaW5nKCkub3B0aW9uYWwoKS5kZXNjcmliZShcIlNob3J0IGFsaWFzIHRoZSBwbHVnaW4gYWNjZXB0cyBpbiBwbGFjZSBvZiBgbmFtZWAuXCIpLFxuICBwcmltYXJ5S2V5OiB6LnN0cmluZygpLm9wdGlvbmFsKCkuZGVzY3JpYmUoXCJUaGUgaW5kZXgncyBwcmltYXJ5LWtleSBjb2x1bW4sIHdoZW4ga25vd24uXCIpLFxuICBjb2x1bW5zOiB6XG4gICAgLmFycmF5KHouc3RyaW5nKCkpXG4gICAgLm9wdGlvbmFsKClcbiAgICAuZGVzY3JpYmUoXCJDb2x1bW5zIHJldHVybmVkIGJ5IGRlZmF1bHQsIGluIGRpc3BsYXkgb3JkZXIuXCIpLFxuICBpc0RlZmF1bHQ6IHouYm9vbGVhbigpLm9wdGlvbmFsKCkuZGVzY3JpYmUoXCJUcnVlIGZvciB0aGUgcGx1Z2luJ3MgZGVmYXVsdCBpbmRleC5cIiksXG59KTtcblxuLyoqIE9uZSBlbnRyeSBpbiB0aGUgaW5kZXggY2F0YWxvZ3VlICh7QGxpbmsgc2VhcmNoSW5kZXhJbmZvU2NoZW1hfSkuICovXG5leHBvcnQgdHlwZSBTZWFyY2hJbmRleEluZm8gPSB6LmluZmVyPHR5cGVvZiBzZWFyY2hJbmRleEluZm9TY2hlbWE+O1xuXG4vKiogU2NoZW1hIGZvciB0aGUgcGx1Z2luJ3MgY2xpZW50IGNvbmZpZyBzdXJmYWNlZCB0byBhIFVJLiAqL1xuZXhwb3J0IGNvbnN0IHNlYXJjaENsaWVudENvbmZpZ1NjaGVtYSA9IHoub2JqZWN0KHtcbiAgaW5kZXhlczogei5hcnJheShzZWFyY2hJbmRleEluZm9TY2hlbWEpLmRlc2NyaWJlKFwiSW5kZXhlcyB0aGUgc2VhcmNoIFVJIG1heSBxdWVyeS5cIiksXG4gIGRlZmF1bHRJbmRleDogei5zdHJpbmcoKS5vcHRpb25hbCgpLmRlc2NyaWJlKFwiVGhlIGluZGV4IGEgc2VhcmNoIGJveCBzZWxlY3RzIGJ5IGRlZmF1bHQuXCIpLFxuICBwYWdlU2l6ZTogei5udW1iZXIoKS5pbnQoKS5kZXNjcmliZShcIkRlZmF1bHQgbnVtYmVyIG9mIGhpdHMgYSBzZWFyY2ggcmV0dXJucy5cIiksXG4gIGJhc2VQYXRoOiB6XG4gICAgLnN0cmluZygpXG4gICAgLmRlc2NyaWJlKFwiQmFzZSBwYXRoIHRoZSBzZWFyY2ggcm91dGVzIGFyZSBtb3VudGVkIHVuZGVyIChlLmcuIC9hcGkvc2VhcmNoKS5cIiksXG59KTtcblxuLyoqIFRoZSBwbHVnaW4ncyBjbGllbnQgY29uZmlnICh7QGxpbmsgc2VhcmNoQ2xpZW50Q29uZmlnU2NoZW1hfSkuICovXG5leHBvcnQgdHlwZSBTZWFyY2hDbGllbnRDb25maWcgPSB6LmluZmVyPHR5cGVvZiBzZWFyY2hDbGllbnRDb25maWdTY2hlbWE+O1xuXG4vKipcbiAqIFNjaGVtYSBmb3IgY3JlYXRpbmcgYW4gaW5kZXggKHRoZSBgY3JlYXRlX2luZGV4YCB0b29sIGlucHV0IC8gdGhlXG4gKiBgUE9TVCAvYXBpL3NlYXJjaC9pbmRleGAgYm9keSkuIFR3byBzaGFwZXMsIGJvdGggaW5mZXJyaW5nIGFnZ3Jlc3NpdmVseTpcbiAqIHBhc3MgYHNvdXJjZVRhYmxlYCBmb3IgYSBEZWx0YSBTeW5jIGluZGV4IChEYXRhYnJpY2tzIGNvbXB1dGVzIGVtYmVkZGluZ3MgYW5kXG4gKiBrZWVwcyBpdCBzeW5jZWQpIG9yIGBlbWJlZGRpbmdEaW1lbnNpb25gIGZvciBhIGRpcmVjdC1hY2Nlc3MgaW5kZXggeW91IHdyaXRlXG4gKiB2ZWN0b3JzIHRvIHlvdXJzZWxmLlxuICovXG5leHBvcnQgY29uc3QgY3JlYXRlSW5kZXhSZXF1ZXN0U2NoZW1hID0gei5vYmplY3Qoe1xuICBuYW1lOiB6LnN0cmluZygpLmRlc2NyaWJlKFwiVW5pdHkgQ2F0YWxvZyBuYW1lIGZvciB0aGUgbmV3IGluZGV4IChjYXRhbG9nLnNjaGVtYS5pbmRleCkuXCIpLFxuICBzb3VyY2VUYWJsZTogelxuICAgIC5zdHJpbmcoKVxuICAgIC5vcHRpb25hbCgpXG4gICAgLmRlc2NyaWJlKFxuICAgICAgXCJEZWx0YSB0YWJsZSAoY2F0YWxvZy5zY2hlbWEudGFibGUpIHRvIGJ1aWxkIGEgc3luY2VkIGluZGV4IGZyb20uIFByb3ZpZGUgdGhpcyBPUiBlbWJlZGRpbmdEaW1lbnNpb24uXCIsXG4gICAgKSxcbiAgcHJpbWFyeUtleTogei5zdHJpbmcoKS5vcHRpb25hbCgpLmRlc2NyaWJlKFwiUHJpbWFyeS1rZXkgY29sdW1uLiBEZWZhdWx0cyB0byAnaWQnLlwiKSxcbiAgZW1iZWRkaW5nU291cmNlQ29sdW1uOiB6XG4gICAgLnN0cmluZygpXG4gICAgLm9wdGlvbmFsKClcbiAgICAuZGVzY3JpYmUoXG4gICAgICBcIlRleHQgY29sdW1uIGVtYmVkZGluZ3MgYXJlIGNvbXB1dGVkIGZyb20gKERlbHRhIFN5bmMpLiBEZWZhdWx0cyB0byB0aGUgZmlyc3Qgb2YgdGV4dC9jb250ZW50L2JvZHkuXCIsXG4gICAgKSxcbiAgZW1iZWRkaW5nTW9kZWw6IHpcbiAgICAuc3RyaW5nKClcbiAgICAub3B0aW9uYWwoKVxuICAgIC5kZXNjcmliZShcbiAgICAgIFwiRW1iZWRkaW5nIG1vZGVsIGVuZHBvaW50IChuYW1lIG9yIGxvb3NlIG5hbWUpLiBEZWZhdWx0cyB0byB0aGUgYXBwJ3MgZW1iZWRkaW5nIG1vZGVsLCBvciB0aGUgYmVzdCBlbWJlZGRpbmcgZW5kcG9pbnQgaW4gdGhlIHdvcmtzcGFjZS5cIixcbiAgICApLFxuICBlbmRwb2ludDogelxuICAgIC5zdHJpbmcoKVxuICAgIC5vcHRpb25hbCgpXG4gICAgLmRlc2NyaWJlKFxuICAgICAgXCJWZWN0b3IgU2VhcmNoIGVuZHBvaW50IHRvIGhvc3QgdGhlIGluZGV4IG9uLiBEZWZhdWx0cyB0byB0aGUgYXBwJ3MgY29uZmlndXJlZCBlbmRwb2ludC5cIixcbiAgICApLFxuICBlbWJlZGRpbmdEaW1lbnNpb246IHpcbiAgICAubnVtYmVyKClcbiAgICAuaW50KClcbiAgICAucG9zaXRpdmUoKVxuICAgIC5vcHRpb25hbCgpXG4gICAgLmRlc2NyaWJlKFwiRm9yIGEgZGlyZWN0LWFjY2VzcyBpbmRleCAobm8gc291cmNlIHRhYmxlKTogdGhlIGVtYmVkZGluZyB2ZWN0b3IgZGltZW5zaW9uLlwiKSxcbiAgcGlwZWxpbmVUeXBlOiB6XG4gICAgLmVudW0oW1wiVFJJR0dFUkVEXCIsIFwiQ09OVElOVU9VU1wiXSlcbiAgICAub3B0aW9uYWwoKVxuICAgIC5kZXNjcmliZShcbiAgICAgIFwiRGVsdGEgU3luYyBtb2RlOiAnVFJJR0dFUkVEJyAoZGVmYXVsdCkgc3luY3Mgb24gZGVtYW5kOyAnQ09OVElOVU9VUycga2VlcHMgdGhlIGluZGV4IGZyZXNoLlwiLFxuICAgICksXG4gIGNvbHVtbnNUb1N5bmM6IHpcbiAgICAuYXJyYXkoei5zdHJpbmcoKSlcbiAgICAub3B0aW9uYWwoKVxuICAgIC5kZXNjcmliZShcIkV4dHJhIGNvbHVtbnMgdG8gc3luYyBhbG9uZ3NpZGUgdGhlIGVtYmVkZGluZyBzb3VyY2UgY29sdW1uIChEZWx0YSBTeW5jKS5cIiksXG59KTtcblxuLyoqIEEgdmFsaWRhdGVkIGNyZWF0ZS1pbmRleCByZXF1ZXN0ICh7QGxpbmsgY3JlYXRlSW5kZXhSZXF1ZXN0U2NoZW1hfSkuICovXG5leHBvcnQgdHlwZSBDcmVhdGVJbmRleFJlcXVlc3QgPSB6LmluZmVyPHR5cGVvZiBjcmVhdGVJbmRleFJlcXVlc3RTY2hlbWE+O1xuXG4vKiogU2NoZW1hIGZvciB0aGUgYHN5bmNfaW5kZXhgIHRvb2wgaW5wdXQgLyB0aGUgYFBPU1QgL2FwaS9zZWFyY2gvaW5kZXgvc3luY2AgYm9keS4gKi9cbmV4cG9ydCBjb25zdCBzeW5jSW5kZXhSZXF1ZXN0U2NoZW1hID0gei5vYmplY3Qoe1xuICBpbmRleDogelxuICAgIC5zdHJpbmcoKVxuICAgIC5kZXNjcmliZShcbiAgICAgIFwiVGhlIGluZGV4IHRvIHN5bmMgKG5hbWUgb3IgY29uZmlndXJlZCBhbGlhcykuIERlZmF1bHRzIHRvIHRoZSBhcHAncyBkZWZhdWx0IGluZGV4IHdoZW4gb21pdHRlZC5cIixcbiAgICApXG4gICAgLm9wdGlvbmFsKCksXG59KTtcblxuLyoqIEEgdmFsaWRhdGVkIHN5bmMtaW5kZXggcmVxdWVzdCAoe0BsaW5rIHN5bmNJbmRleFJlcXVlc3RTY2hlbWF9KS4gKi9cbmV4cG9ydCB0eXBlIFN5bmNJbmRleFJlcXVlc3QgPSB6LmluZmVyPHR5cGVvZiBzeW5jSW5kZXhSZXF1ZXN0U2NoZW1hPjtcblxuLyoqIFNjaGVtYSBmb3IgYSByZXNvbHZlZCBpbmRleCBkZWZpbml0aW9uICh0aGUgY3JlYXRlL2dldCByZXN1bHQpLiAqL1xuZXhwb3J0IGNvbnN0IGluZGV4SW5mb1NjaGVtYSA9IHoub2JqZWN0KHtcbiAgbmFtZTogei5zdHJpbmcoKS5kZXNjcmliZShcIlVuaXR5IENhdGFsb2cgbmFtZSBvZiB0aGUgaW5kZXguXCIpLFxuICBlbmRwb2ludDogei5zdHJpbmcoKS5vcHRpb25hbCgpLmRlc2NyaWJlKFwiVGhlIFZlY3RvciBTZWFyY2ggZW5kcG9pbnQgaG9zdGluZyB0aGUgaW5kZXguXCIpLFxuICBwcmltYXJ5S2V5OiB6LnN0cmluZygpLm9wdGlvbmFsKCkuZGVzY3JpYmUoXCJUaGUgaW5kZXgncyBwcmltYXJ5LWtleSBjb2x1bW4uXCIpLFxuICBjb2x1bW5zOiB6LmFycmF5KHouc3RyaW5nKCkpLmRlc2NyaWJlKFwiQ29sdW1ucyBhdmFpbGFibGUgb24gdGhlIGluZGV4LlwiKSxcbiAgcmVhZHk6IHouYm9vbGVhbigpLmRlc2NyaWJlKFwiVHJ1ZSB3aGVuIHRoZSBpbmRleCBoYXMgZmluaXNoZWQgcHJvdmlzaW9uaW5nIGFuZCBjYW4gYmUgcXVlcmllZC5cIiksXG4gIHJvd0NvdW50OiB6Lm51bWJlcigpLmludCgpLm9wdGlvbmFsKCkuZGVzY3JpYmUoXCJOdW1iZXIgb2YgaW5kZXhlZCByb3dzLCB3aGVuIGtub3duLlwiKSxcbn0pO1xuXG4vKiogQSByZXNvbHZlZCBpbmRleCBkZWZpbml0aW9uICh7QGxpbmsgaW5kZXhJbmZvU2NoZW1hfSkuICovXG5leHBvcnQgdHlwZSBJbmRleEluZm8gPSB6LmluZmVyPHR5cGVvZiBpbmRleEluZm9TY2hlbWE+O1xuIl19
@@ -1 +1 @@
1
- {"root":["../src/search.ts","../index.ts"],"version":"5.9.3"}
1
+ {"root":["../src/search-schemas.ts","../index.ts"],"version":"5.9.3"}
package/package.json CHANGED
@@ -40,7 +40,7 @@
40
40
  "./package.json": "./package.json"
41
41
  }
42
42
  },
43
- "version": "0.9.5",
43
+ "version": "0.9.6",
44
44
  "types": "./lib/index.d.ts",
45
45
  "type": "module",
46
46
  "exports": {
package/lib/src/search.js DELETED
@@ -1,199 +0,0 @@
1
- /**
2
- * Wire-format contract for the AI Search add-on: the query a caller (a UI
3
- * search box, a Mastra tool, a universal-search route) sends and the hits it
4
- * gets back, plus the document shape used to add / update index contents.
5
- *
6
- * Pure (zod + inferred types, no Node-only imports) so the server-side client
7
- * in `@dbx-tools/search`, the Mastra tool, the `POST /api/search` route,
8
- * and the React search box all validate / type against ONE definition.
9
- *
10
- * "AI Search" is Databricks' current name for Vector Search: an index built
11
- * from a Delta table (or written directly) that answers a natural-language
12
- * query with the most relevant rows, combining vector similarity with BM25
13
- * keyword matching (hybrid). This contract is index-agnostic - it names the
14
- * index by its Unity Catalog path and returns hits as `{ id, score, fields }`
15
- * so the same shape serves an autocomplete box, a docs lookup, and a
16
- * federated search across many indexes.
17
- *
18
- * Array fields intentionally avoid `.min()` / `.nonempty()`: those emit
19
- * `minItems` in the JSON schema, which some Model Serving endpoints reject
20
- * when the schema is forwarded as a tool definition.
21
- *
22
- * @module
23
- */
24
- import { z } from "zod";
25
- /**
26
- * How a query is matched. `hybrid` (the default) fuses vector similarity with
27
- * BM25 keyword ranking - the right choice for most search boxes and for source
28
- * data with exact identifiers (SKUs, error codes). `vector` is pure semantic
29
- * similarity; `keyword` is pure BM25 full-text (Beta on Databricks). The
30
- * value maps onto the serving API's `query_type` (`ANN` / `HYBRID`).
31
- */
32
- export const searchModeSchema = z
33
- .enum(["hybrid", "vector", "keyword"])
34
- .describe("Match strategy: 'hybrid' fuses semantic similarity with keyword ranking (default, best for most searches), 'vector' is pure semantic, 'keyword' is pure full-text.");
35
- /** Map the dbx-tools extension vocabulary onto AppKit AI Search. */
36
- export function toAiSearchQueryType(mode) {
37
- if (mode === "vector")
38
- return "ann";
39
- if (mode === "keyword")
40
- return "full_text";
41
- if (mode === "hybrid")
42
- return "hybrid";
43
- return undefined;
44
- }
45
- /** Schema for a search request against a single index. */
46
- export const searchRequestSchema = z.object({
47
- query: z
48
- .string()
49
- .describe("What to search for, as natural language or keywords. Prefix fragments work for autocomplete."),
50
- index: z
51
- .string()
52
- .optional()
53
- .describe("Unity Catalog name of the index to search (catalog.schema.index). Defaults to the plugin's configured index. Accepts a short alias when one is configured."),
54
- limit: z
55
- .number()
56
- .int()
57
- .positive()
58
- .optional()
59
- .describe("Maximum number of hits to return. Defaults to the plugin's configured page size."),
60
- mode: searchModeSchema.optional(),
61
- columns: z
62
- .array(z.string())
63
- .optional()
64
- .describe("Which document columns to return per hit. Defaults to the plugin's configured columns (or all indexed columns)."),
65
- filter: z
66
- .record(z.string(), z.union([z.string(), z.number(), z.boolean(), z.array(z.union([z.string(), z.number()]))]))
67
- .optional()
68
- .describe("AppKit AI Search attribute filters as { column: scalarOrArray }. Combined with AND."),
69
- scoreThreshold: z
70
- .number()
71
- .optional()
72
- .describe("Drop hits whose relevance score is below this value."),
73
- });
74
- /** Schema for a single search hit. */
75
- export const searchHitSchema = z.object({
76
- id: z.string().describe("The document's primary-key value."),
77
- score: z.number().describe("Relevance score; higher is more relevant."),
78
- fields: z
79
- .record(z.string(), z.unknown())
80
- .describe("The returned columns for this document, keyed by column name."),
81
- index: z
82
- .string()
83
- .optional()
84
- .describe("Which index the hit came from (set on universal/federated results)."),
85
- });
86
- /** Schema for the result of a search. */
87
- export const searchResultSchema = z.object({
88
- query: z.string().describe("Echo of the query that was searched."),
89
- hits: z.array(searchHitSchema).describe("Matching documents, most relevant first."),
90
- index: z.string().optional().describe("The index searched (omitted for a universal search)."),
91
- count: z.number().int().describe("Number of hits returned."),
92
- });
93
- /** Schema for a universal (federated) search across several indexes at once. */
94
- export const universalSearchRequestSchema = z.object({
95
- query: z.string().describe("What to search for across every configured index."),
96
- indexes: z
97
- .array(z.string())
98
- .optional()
99
- .describe("Which indexes to search. Defaults to every index the plugin knows about."),
100
- limit: z
101
- .number()
102
- .int()
103
- .positive()
104
- .optional()
105
- .describe("Maximum hits PER index before results are merged and re-ranked."),
106
- mode: searchModeSchema.optional(),
107
- });
108
- /** Schema for a document written to a direct-access index. */
109
- export const searchDocumentSchema = z
110
- .record(z.string(), z.unknown())
111
- .describe("A document as { column: value }. Must include the index primary-key column.");
112
- /** Schema for the result of adding / updating documents. */
113
- export const upsertResultSchema = z.object({
114
- index: z.string().describe("The index the documents were written to."),
115
- count: z.number().int().describe("Number of documents accepted."),
116
- });
117
- /**
118
- * Schema for the boot-time index catalogue a UI reads to populate a search box
119
- * (the payload of the plugin's client config / `GET /api/search/indexes`). An
120
- * entry names an index, an optional short alias, and the columns worth
121
- * showing, so a search box needs no server round-trip to render.
122
- */
123
- export const searchIndexInfoSchema = z.object({
124
- name: z.string().describe("Unity Catalog name of the index (catalog.schema.index)."),
125
- alias: z.string().optional().describe("Short alias the plugin accepts in place of `name`."),
126
- primaryKey: z.string().optional().describe("The index's primary-key column, when known."),
127
- columns: z
128
- .array(z.string())
129
- .optional()
130
- .describe("Columns returned by default, in display order."),
131
- isDefault: z.boolean().optional().describe("True for the plugin's default index."),
132
- });
133
- /** Schema for the plugin's client config surfaced to a UI. */
134
- export const searchClientConfigSchema = z.object({
135
- indexes: z.array(searchIndexInfoSchema).describe("Indexes the search UI may query."),
136
- defaultIndex: z.string().optional().describe("The index a search box selects by default."),
137
- pageSize: z.number().int().describe("Default number of hits a search returns."),
138
- basePath: z
139
- .string()
140
- .describe("Base path the search routes are mounted under (e.g. /api/search)."),
141
- });
142
- /**
143
- * Schema for creating an index (the `create_index` tool input / the
144
- * `POST /api/search/index` body). Two shapes, both inferring aggressively:
145
- * pass `sourceTable` for a Delta Sync index (Databricks computes embeddings and
146
- * keeps it synced) or `embeddingDimension` for a direct-access index you write
147
- * vectors to yourself.
148
- */
149
- export const createIndexRequestSchema = z.object({
150
- name: z.string().describe("Unity Catalog name for the new index (catalog.schema.index)."),
151
- sourceTable: z
152
- .string()
153
- .optional()
154
- .describe("Delta table (catalog.schema.table) to build a synced index from. Provide this OR embeddingDimension."),
155
- primaryKey: z.string().optional().describe("Primary-key column. Defaults to 'id'."),
156
- embeddingSourceColumn: z
157
- .string()
158
- .optional()
159
- .describe("Text column embeddings are computed from (Delta Sync). Defaults to the first of text/content/body."),
160
- embeddingModel: z
161
- .string()
162
- .optional()
163
- .describe("Embedding model endpoint (name or loose name). Defaults to the app's embedding model, or the best embedding endpoint in the workspace."),
164
- endpoint: z
165
- .string()
166
- .optional()
167
- .describe("Vector Search endpoint to host the index on. Defaults to the app's configured endpoint."),
168
- embeddingDimension: z
169
- .number()
170
- .int()
171
- .positive()
172
- .optional()
173
- .describe("For a direct-access index (no source table): the embedding vector dimension."),
174
- pipelineType: z
175
- .enum(["TRIGGERED", "CONTINUOUS"])
176
- .optional()
177
- .describe("Delta Sync mode: 'TRIGGERED' (default) syncs on demand; 'CONTINUOUS' keeps the index fresh."),
178
- columnsToSync: z
179
- .array(z.string())
180
- .optional()
181
- .describe("Extra columns to sync alongside the embedding source column (Delta Sync)."),
182
- });
183
- /** Schema for the `sync_index` tool input / the `POST /api/search/index/sync` body. */
184
- export const syncIndexRequestSchema = z.object({
185
- index: z
186
- .string()
187
- .describe("The index to sync (name or configured alias). Defaults to the app's default index when omitted.")
188
- .optional(),
189
- });
190
- /** Schema for a resolved index definition (the create/get result). */
191
- export const indexInfoSchema = z.object({
192
- name: z.string().describe("Unity Catalog name of the index."),
193
- endpoint: z.string().optional().describe("The Vector Search endpoint hosting the index."),
194
- primaryKey: z.string().optional().describe("The index's primary-key column."),
195
- columns: z.array(z.string()).describe("Columns available on the index."),
196
- ready: z.boolean().describe("True when the index has finished provisioning and can be queried."),
197
- rowCount: z.number().int().optional().describe("Number of indexed rows, when known."),
198
- });
199
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VhcmNoLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlYXJjaC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXNCRztBQUVILE9BQU8sRUFBRSxDQUFDLEVBQUUsTUFBTSxLQUFLLENBQUM7QUFFeEI7Ozs7OztHQU1HO0FBQ0gsTUFBTSxDQUFDLE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQztLQUM5QixJQUFJLENBQUMsQ0FBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0tBQ3JDLFFBQVEsQ0FDUCxvS0FBb0ssQ0FDckssQ0FBQztBQVFKLG9FQUFvRTtBQUNwRSxNQUFNLFVBQVUsbUJBQW1CLENBQUMsSUFBNEI7SUFDOUQsSUFBSSxJQUFJLEtBQUssUUFBUTtRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQ3BDLElBQUksSUFBSSxLQUFLLFNBQVM7UUFBRSxPQUFPLFdBQVcsQ0FBQztJQUMzQyxJQUFJLElBQUksS0FBSyxRQUFRO1FBQUUsT0FBTyxRQUFRLENBQUM7SUFDdkMsT0FBTyxTQUFTLENBQUM7QUFDbkIsQ0FBQztBQUVELDBEQUEwRDtBQUMxRCxNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDO0lBQzFDLEtBQUssRUFBRSxDQUFDO1NBQ0wsTUFBTSxFQUFFO1NBQ1IsUUFBUSxDQUNQLDhGQUE4RixDQUMvRjtJQUNILEtBQUssRUFBRSxDQUFDO1NBQ0wsTUFBTSxFQUFFO1NBQ1IsUUFBUSxFQUFFO1NBQ1YsUUFBUSxDQUNQLDRKQUE0SixDQUM3SjtJQUNILEtBQUssRUFBRSxDQUFDO1NBQ0wsTUFBTSxFQUFFO1NBQ1IsR0FBRyxFQUFFO1NBQ0wsUUFBUSxFQUFFO1NBQ1YsUUFBUSxFQUFFO1NBQ1YsUUFBUSxDQUFDLGtGQUFrRixDQUFDO0lBQy9GLElBQUksRUFBRSxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUU7SUFDakMsT0FBTyxF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LWZvcm1hdCBjb250cmFjdCBmb3IgdGhlIEFJIFNlYXJjaCBhZGQtb246IHRoZSBxdWVyeSBhIGNhbGxlciAoYSBVSVxuICogc2VhcmNoIGJveCwgYSBNYXN0cmEgdG9vbCwgYSB1bml2ZXJzYWwtc2VhcmNoIHJvdXRlKSBzZW5kcyBhbmQgdGhlIGhpdHMgaXRcbiAqIGdldHMgYmFjaywgcGx1cyB0aGUgZG9jdW1lbnQgc2hhcGUgdXNlZCB0byBhZGQgLyB1cGRhdGUgaW5kZXggY29udGVudHMuXG4gKlxuICogUHVyZSAoem9kICsgaW5mZXJyZWQgdHlwZXMsIG5vIE5vZGUtb25seSBpbXBvcnRzKSBzbyB0aGUgc2VydmVyLXNpZGUgY2xpZW50XG4gKiBpbiBgQGRieC10b29scy9zZWFyY2hgLCB0aGUgTWFzdHJhIHRvb2wsIHRoZSBgUE9TVCAvYXBpL3NlYXJjaGAgcm91dGUsXG4gKiBhbmQgdGhlIFJlYWN0IHNlYXJjaCBib3ggYWxsIHZhbGlkYXRlIC8gdHlwZSBhZ2FpbnN0IE9ORSBkZWZpbml0aW9uLlxuICpcbiAqIFwiQUkgU2VhcmNoXCIgaXMgRGF0YWJyaWNrcycgY3VycmVudCBuYW1lIGZvciBWZWN0b3IgU2VhcmNoOiBhbiBpbmRleCBidWlsdFxuICogZnJvbSBhIERlbHRhIHRhYmxlIChvciB3cml0dGVuIGRpcmVjdGx5KSB0aGF0IGFuc3dlcnMgYSBuYXR1cmFsLWxhbmd1YWdlXG4gKiBxdWVyeSB3aXRoIHRoZSBtb3N0IHJlbGV2YW50IHJvd3MsIGNvbWJpbmluZyB2ZWN0b3Igc2ltaWxhcml0eSB3aXRoIEJNMjVcbiAqIGtleXdvcmQgbWF0Y2hpbmcgKGh5YnJpZCkuIFRoaXMgY29udHJhY3QgaXMgaW5kZXgtYWdub3N0aWMgLSBpdCBuYW1lcyB0aGVcbiAqIGluZGV4IGJ5IGl0cyBVbml0eSBDYXRhbG9nIHBhdGggYW5kIHJldHVybnMgaGl0cyBhcyBgeyBpZCwgc2NvcmUsIGZpZWxkcyB9YFxuICogc28gdGhlIHNhbWUgc2hhcGUgc2VydmVzIGFuIGF1dG9jb21wbGV0ZSBib3gsIGEgZG9jcyBsb29rdXAsIGFuZCBhXG4gKiBmZWRlcmF0ZWQgc2VhcmNoIGFjcm9zcyBtYW55IGluZGV4ZXMuXG4gKlxuICogQXJyYXkgZmllbGRzIGludGVudGlvbmFsbHkgYXZvaWQgYC5taW4oKWAgLyBgLm5vbmVtcHR5KClgOiB0aG9zZSBlbWl0XG4gKiBgbWluSXRlbXNgIGluIHRoZSBKU09OIHNjaGVtYSwgd2hpY2ggc29tZSBNb2RlbCBTZXJ2aW5nIGVuZHBvaW50cyByZWplY3RcbiAqIHdoZW4gdGhlIHNjaGVtYSBpcyBmb3J3YXJkZWQgYXMgYSB0b29sIGRlZmluaXRpb24uXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5cbi8qKlxuICogSG93IGEgcXVlcnkgaXMgbWF0Y2hlZC4gYGh5YnJpZGAgKHRoZSBkZWZhdWx0KSBmdXNlcyB2ZWN0b3Igc2ltaWxhcml0eSB3aXRoXG4gKiBCTTI1IGtleXdvcmQgcmFua2luZyAtIHRoZSByaWdodCBjaG9pY2UgZm9yIG1vc3Qgc2VhcmNoIGJveGVzIGFuZCBmb3Igc291cmNlXG4gKiBkYXRhIHdpdGggZXhhY3QgaWRlbnRpZmllcnMgKFNLVXMsIGVycm9yIGNvZGVzKS4gYHZlY3RvcmAgaXMgcHVyZSBzZW1hbnRpY1xuICogc2ltaWxhcml0eTsgYGtleXdvcmRgIGlzIHB1cmUgQk0yNSBmdWxsLXRleHQgKEJldGEgb24gRGF0YWJyaWNrcykuIFRoZVxuICogdmFsdWUgbWFwcyBvbnRvIHRoZSBzZXJ2aW5nIEFQSSdzIGBxdWVyeV90eXBlYCAoYEFOTmAgLyBgSFlCUklEYCkuXG4gKi9cbmV4cG9ydCBjb25zdCBzZWFyY2hNb2RlU2NoZW1hID0gelxuICAuZW51bShbXCJoeWJyaWRcIiwgXCJ2ZWN0b3JcIiwgXCJrZXl3b3JkXCJdKVxuICAuZGVzY3JpYmUoXG4gICAgXCJNYXRjaCBzdHJhdGVneTogJ2h5YnJpZCcgZnVzZXMgc2VtYW50aWMgc2ltaWxhcml0eSB3aXRoIGtleXdvcmQgcmFua2luZyAoZGVmYXVsdCwgYmVzdCBmb3IgbW9zdCBzZWFyY2hlcyksICd2ZWN0b3InIGlzIHB1cmUgc2VtYW50aWMsICdrZXl3b3JkJyBpcyBwdXJlIGZ1bGwtdGV4dC5cIixcbiAgKTtcblxuLyoqIEhvdyBhIHF1ZXJ5IGlzIG1hdGNoZWQgKHNlZSB7QGxpbmsgc2VhcmNoTW9kZVNjaGVtYX0pLiAqL1xuZXhwb3J0IHR5cGUgU2VhcmNoTW9kZSA9IHouaW5mZXI8dHlwZW9mIHNlYXJjaE1vZGVTY2hlbWE+O1xuXG4vKiogQXBwS2l0IEFJIFNlYXJjaCBxdWVyeSBtb2Rlcy4gKi9cbmV4cG9ydCB0eXBlIEFpU2VhcmNoUXVlcnlUeXBlID0gXCJhbm5cIiB8IFwiaHlicmlkXCIgfCBcImZ1bGxfdGV4dFwiO1xuXG4vKiogTWFwIHRoZSBkYngtdG9vbHMgZXh0ZW5zaW9uIHZvY2FidWxhcnkgb250byBBcHBLaXQgQUkgU2VhcmNoLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvQWlTZWFyY2hRdWVyeVR5cGUobW9kZTogU2VhcmNoTW9kZSB8IHVuZGVmaW5lZCk6IEFpU2VhcmNoUXVlcnlUeXBlIHwgdW5kZWZpbmVkIHtcbiAgaWYgKG1vZGUgPT09IFwidmVjdG9yXCIpIHJldHVybiBcImFublwiO1xuICBpZiAobW9kZSA9PT0gXCJrZXl3b3JkXCIpIHJldHVybiBcImZ1bGxfdGV4dFwiO1xuICBpZiAobW9kZSA9PT0gXCJoeWJyaWRcIikgcmV0dXJuIFwiaHlicmlkXCI7XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKiBTY2hlbWEgZm9yIGEgc2VhcmNoIHJlcXVlc3QgYWdhaW5zdCBhIHNpbmdsZSBpbmRleC4gKi9cbmV4cG9ydCBjb25zdCBzZWFyY2hSZXF1ZXN0U2NoZW1hID0gei5vYmplY3Qoe1xuICBxdWVyeTogelxuICAgIC5zdHJpbmcoKVxuICAgIC5kZXNjcmliZShcbiAgICAgIFwiV2hhdCB0byBzZWFyY2ggZm9yLCBhcyBuYXR1cmFsIGxhbmd1YWdlIG9yIGtleXdvcmRzLiBQcmVmaXggZnJhZ21lbnRzIHdvcmsgZm9yIGF1dG9jb21wbGV0ZS5cIixcbiAgICApLFxuICBpbmRleDogelxuICAgIC5zdHJpbmcoKVxuICAgIC5vcHRpb25hbCgpXG4gICAgLmRlc2NyaWJlKFxuICAgICAgXCJVbml0eSBDYXRhbG9nIG5hbWUgb2YgdGhlIGluZGV4IHRvIHNlYXJjaCAoY2F0YWxvZy5zY2hlbWEuaW5kZXgpLiBEZWZhdWx0cyB0byB0aGUgcGx1Z2luJ3MgY29uZmlndXJlZCBpbmRleC4gQWNjZXB0cyBhIHNob3J0IGFsaWFzIHdoZW4gb25lIGlzIGNvbmZpZ3VyZWQuXCIsXG4gICAgKSxcbiAgbGltaXQ6IHpcbiAgICAubnVtYmVyKClcbiAgICAuaW50KClcbiAgICAucG9zaXRpdmUoKVxuICAgIC5vcHRpb25hbCgpXG4gICAgLmRlc2NyaWJlKFwiTWF4aW11bSBudW1iZXIgb2YgaGl0cyB0byByZXR1cm4uIERlZmF1bHRzIHRvIHRoZSBwbHVnaW4ncyBjb25maWd1cmVkIHBhZ2Ugc2l6ZS5cIiksXG4gIG1vZGU6IHNlYXJjaE1vZGVTY2hlbWEub3B0aW9uYWwoKSxcbiAgY29sdW1uczogelxuICAgIC5hcnJheSh6LnN0cmluZygpKVxuICAgIC5vcHRpb25hbCgpXG4gICAgLmRlc2NyaWJlKFxuICAgICAgXCJXaGljaCBkb2N1bWVudCBjb2x1bW5zIHRvIHJldHVybiBwZXIgaGl0LiBEZWZhdWx0cyB0byB0aGUgcGx1Z2luJ3MgY29uZmlndXJlZCBjb2x1bW5zIChvciBhbGwgaW5kZXhlZCBjb2x1bW5zKS5cIixcbiAgICApLFxuICBmaWx0ZXI6IHpcbiAgICAucmVjb3JkKFxuICAgICAgei5zdHJpbmcoKSxcbiAgICAgIHoudW5pb24oW3ouc3RyaW5nKCksIHoubnVtYmVyKCksIHouYm9vbGVhbigpLCB6LmFycmF5KHoudW5pb24oW3ouc3RyaW5nKCksIHoubnVtYmVyKCldKSldKSxcbiAgICApXG4gICAgLm9wdGlvbmFsKClcbiAgICAuZGVzY3JpYmUoXG4gICAgICBcIkFwcEtpdCBBSSBTZWFyY2ggYXR0cmlidXRlIGZpbHRlcnMgYXMgeyBjb2x1bW46IHNjYWxhck9yQXJyYXkgfS4gQ29tYmluZWQgd2l0aCBBTkQuXCIsXG4gICAgKSxcbiAgc2NvcmVUaHJlc2hvbGQ6IHpcbiAgICAubnVtYmVyKClcbiAgICAub3B0aW9uYWwoKVxuICAgIC5kZXNjcmliZShcIkRyb3AgaGl0cyB3aG9zZSByZWxldmFuY2Ugc2NvcmUgaXMgYmVsb3cgdGhpcyB2YWx1ZS5cIiksXG59KTtcblxuLyoqIEEgdmFsaWRhdGVkIHNlYXJjaCByZXF1ZXN0ICh7QGxpbmsgc2VhcmNoUmVxdWVzdFNjaGVtYX0pLiAqL1xuZXhwb3J0IHR5cGUgU2VhcmNoUmVxdWVzdCA9IHouaW5mZXI8dHlwZW9mIHNlYXJjaFJlcXVlc3RTY2hlbWE+O1xuXG4vKiogU2NoZW1hIGZvciBhIHNpbmdsZSBzZWFyY2ggaGl0LiAqL1xuZXhwb3J0IGNvbnN0IHNlYXJjaEhpdFNjaGVtYSA9IHoub2JqZWN0KHtcbiAgaWQ6IHouc3RyaW5nKCkuZGVzY3JpYmUoXCJUaGUgZG9jdW1lbnQncyBwcmltYXJ5LWtleSB2YWx1ZS5cIiksXG4gIHNjb3JlOiB6Lm51bWJlcigpLmRlc2NyaWJlKFwiUmVsZXZhbmNlIHNjb3JlOyBoaWdoZXIgaXMgbW9yZSByZWxldmFudC5cIiksXG4gIGZpZWxkczogelxuICAgIC5yZWNvcmQoei5zdHJpbmcoKSwgei51bmtub3duKCkpXG4gICAgLmRlc2NyaWJlKFwiVGhlIHJldHVybmVkIGNvbHVtbnMgZm9yIHRoaXMgZG9jdW1lbnQsIGtleWVkIGJ5IGNvbHVtbiBuYW1lLlwiKSxcbiAgaW5kZXg6IHpcbiAgICAuc3RyaW5nKClcbiAgICAub3B0aW9uYWwoKVxuICAgIC5kZXNjcmliZShcIldoaWNoIGluZGV4IHRoZSBoaXQgY2FtZSBmcm9tIChzZXQgb24gdW5pdmVyc2FsL2ZlZGVyYXRlZCByZXN1bHRzKS5cIiksXG59KTtcblxuLyoqIEEgc2luZ2xlIHNlYXJjaCBoaXQgKHtAbGluayBzZWFyY2hIaXRTY2hlbWF9KS4gKi9cbmV4cG9ydCB0eXBlIFNlYXJjaEhpdCA9IHouaW5mZXI8dHlwZW9mIHNlYXJjaEhpdFNjaGVtYT47XG5cbi8qKiBTY2hlbWEgZm9yIHRoZSByZXN1bHQgb2YgYSBzZWFyY2guICovXG5leHBvcnQgY29uc3Qgc2VhcmNoUmVzdWx0U2NoZW1hID0gei5vYmplY3Qoe1xuICBxdWVyeTogei5zdHJpbmcoKS5kZXNjcmliZShcIkVjaG8gb2YgdGhlIHF1ZXJ5IHRoYXQgd2FzIHNlYXJjaGVkLlwiKSxcbiAgaGl0czogei5hcnJheShzZWFyY2hIaXRTY2hlbWEpLmRlc2NyaWJlKFwiTWF0Y2hpbmcgZG9jdW1lbnRzLCBtb3N0IHJlbGV2YW50IGZpcnN0LlwiKSxcbiAgaW5kZXg6IHouc3RyaW5nKCkub3B0aW9uYWwoKS5kZXNjcmliZShcIlRoZSBpbmRleCBzZWFyY2hlZCAob21pdHRlZCBmb3IgYSB1bml2ZXJzYWwgc2VhcmNoKS5cIiksXG4gIGNvdW50OiB6Lm51bWJlcigpLmludCgpLmRlc2NyaWJlKFwiTnVtYmVyIG9mIGhpdHMgcmV0dXJuZWQuXCIpLFxufSk7XG5cbi8qKiBUaGUgb3V0Y29tZSBvZiBhIHNlYXJjaCAoe0BsaW5rIHNlYXJjaFJlc3VsdFNjaGVtYX0pLiAqL1xuZXhwb3J0IHR5cGUgU2VhcmNoUmVzdWx0ID0gei5pbmZlcjx0eXBlb2Ygc2VhcmNoUmVzdWx0U2NoZW1hPjtcblxuLyoqIFNjaGVtYSBmb3IgYSB1bml2ZXJzYWwgKGZlZGVyYXRlZCkgc2VhcmNoIGFjcm9zcyBzZXZlcmFsIGluZGV4ZXMgYXQgb25jZS4gKi9cbmV4cG9ydCBjb25zdCB1bml2ZXJzYWxTZWFyY2hSZXF1ZXN0U2NoZW1hID0gei5vYmplY3Qoe1xuICBxdWVyeTogei5zdHJpbmcoKS5kZXNjcmliZShcIldoYXQgdG8gc2VhcmNoIGZvciBhY3Jvc3MgZXZlcnkgY29uZmlndXJlZCBpbmRleC5cIiksXG4gIGluZGV4ZXM6IHpcbiAgICAuYXJyYXkoei5zdHJpbmcoKSlcbiAgICAub3B0aW9uYWwoKVxuICAgIC5kZXNjcmliZShcIldoaWNoIGluZGV4ZXMgdG8gc2VhcmNoLiBEZWZhdWx0cyB0byBldmVyeSBpbmRleCB0aGUgcGx1Z2luIGtub3dzIGFib3V0LlwiKSxcbiAgbGltaXQ6IHpcbiAgICAubnVtYmVyKClcbiAgICAuaW50KClcbiAgICAucG9zaXRpdmUoKVxuICAgIC5vcHRpb25hbCgpXG4gICAgLmRlc2NyaWJlKFwiTWF4aW11bSBoaXRzIFBFUiBpbmRleCBiZWZvcmUgcmVzdWx0cyBhcmUgbWVyZ2VkIGFuZCByZS1yYW5rZWQuXCIpLFxuICBtb2RlOiBzZWFyY2hNb2RlU2NoZW1hLm9wdGlvbmFsKCksXG59KTtcblxuLyoqIEEgdmFsaWRhdGVkIHVuaXZlcnNhbC1zZWFyY2ggcmVxdWVzdCAoe0BsaW5rIHVuaXZlcnNhbFNlYXJjaFJlcXVlc3RTY2hlbWF9KS4gKi9cbmV4cG9ydCB0eXBlIFVuaXZlcnNhbFNlYXJjaFJlcXVlc3QgPSB6LmluZmVyPHR5cGVvZiB1bml2ZXJzYWxTZWFyY2hSZXF1ZXN0U2NoZW1hPjtcblxuLyoqIFNjaGVtYSBmb3IgYSBkb2N1bWVudCB3cml0dGVuIHRvIGEgZGlyZWN0LWFjY2VzcyBpbmRleC4gKi9cbmV4cG9ydCBjb25zdCBzZWFyY2hEb2N1bWVudFNjaGVtYSA9IHpcbiAgLnJlY29yZCh6LnN0cmluZygpLCB6LnVua25vd24oKSlcbiAgLmRlc2NyaWJlKFwiQSBkb2N1bWVudCBhcyB7IGNvbHVtbjogdmFsdWUgfS4gTXVzdCBpbmNsdWRlIHRoZSBpbmRleCBwcmltYXJ5LWtleSBjb2x1bW4uXCIpO1xuXG4vKiogQSBkb2N1bWVudCB3cml0dGVuIHRvIGFuIGluZGV4ICh7QGxpbmsgc2VhcmNoRG9jdW1lbnRTY2hlbWF9KS4gKi9cbmV4cG9ydCB0eXBlIFNlYXJjaERvY3VtZW50ID0gei5pbmZlcjx0eXBlb2Ygc2VhcmNoRG9jdW1lbnRTY2hlbWE+O1xuXG4vKiogU2NoZW1hIGZvciB0aGUgcmVzdWx0IG9mIGFkZGluZyAvIHVwZGF0aW5nIGRvY3VtZW50cy4gKi9cbmV4cG9ydCBjb25zdCB1cHNlcnRSZXN1bHRTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIGluZGV4OiB6LnN0cmluZygpLmRlc2NyaWJlKFwiVGhlIGluZGV4IHRoZSBkb2N1bWVudHMgd2VyZSB3cml0dGVuIHRvLlwiKSxcbiAgY291bnQ6IHoubnVtYmVyKCkuaW50KCkuZGVzY3JpYmUoXCJOdW1iZXIgb2YgZG9jdW1lbnRzIGFjY2VwdGVkLlwiKSxcbn0pO1xuXG4vKiogVGhlIG91dGNvbWUgb2YgYW4gYWRkLWRvY3VtZW50cyBjYWxsICh7QGxpbmsgdXBzZXJ0UmVzdWx0U2NoZW1hfSkuICovXG5leHBvcnQgdHlwZSBVcHNlcnRSZXN1bHQgPSB6LmluZmVyPHR5cGVvZiB1cHNlcnRSZXN1bHRTY2hlbWE+O1xuXG4vKipcbiAqIFNjaGVtYSBmb3IgdGhlIGJvb3QtdGltZSBpbmRleCBjYXRhbG9ndWUgYSBVSSByZWFkcyB0byBwb3B1bGF0ZSBhIHNlYXJjaCBib3hcbiAqICh0aGUgcGF5bG9hZCBvZiB0aGUgcGx1Z2luJ3MgY2xpZW50IGNvbmZpZyAvIGBHRVQgL2FwaS9zZWFyY2gvaW5kZXhlc2ApLiBBblxuICogZW50cnkgbmFtZXMgYW4gaW5kZXgsIGFuIG9wdGlvbmFsIHNob3J0IGFsaWFzLCBhbmQgdGhlIGNvbHVtbnMgd29ydGhcbiAqIHNob3dpbmcsIHNvIGEgc2VhcmNoIGJveCBuZWVkcyBubyBzZXJ2ZXIgcm91bmQtdHJpcCB0byByZW5kZXIuXG4gKi9cbmV4cG9ydCBjb25zdCBzZWFyY2hJbmRleEluZm9TY2hlbWEgPSB6Lm9iamVjdCh7XG4gIG5hbWU6IHouc3RyaW5nKCkuZGVzY3JpYmUoXCJVbml0eSBDYXRhbG9nIG5hbWUgb2YgdGhlIGluZGV4IChjYXRhbG9nLnNjaGVtYS5pbmRleCkuXCIpLFxuICBhbGlhczogei5zdHJpbmcoKS5vcHRpb25hbCgpLmRlc2NyaWJlKFwiU2hvcnQgYWxpYXMgdGhlIHBsdWdpbiBhY2NlcHRzIGluIHBsYWNlIG9mIGBuYW1lYC5cIiksXG4gIHByaW1hcnlLZXk6IHouc3RyaW5nKCkub3B0aW9uYWwoKS5kZXNjcmliZShcIlRoZSBpbmRleCdzIHByaW1hcnkta2V5IGNvbHVtbiwgd2hlbiBrbm93bi5cIiksXG4gIGNvbHVtbnM6IHpcbiAgICAuYXJyYXkoei5zdHJpbmcoKSlcbiAgICAub3B0aW9uYWwoKVxuICAgIC5kZXNjcmliZShcIkNvbHVtbnMgcmV0dXJuZWQgYnkgZGVmYXVsdCwgaW4gZGlzcGxheSBvcmRlci5cIiksXG4gIGlzRGVmYXVsdDogei5ib29sZWFuKCkub3B0aW9uYWwoKS5kZXNjcmliZShcIlRydWUgZm9yIHRoZSBwbHVnaW4ncyBkZWZhdWx0IGluZGV4LlwiKSxcbn0pO1xuXG4vKiogT25lIGVudHJ5IGluIHRoZSBpbmRleCBjYXRhbG9ndWUgKHtAbGluayBzZWFyY2hJbmRleEluZm9TY2hlbWF9KS4gKi9cbmV4cG9ydCB0eXBlIFNlYXJjaEluZGV4SW5mbyA9IHouaW5mZXI8dHlwZW9mIHNlYXJjaEluZGV4SW5mb1NjaGVtYT47XG5cbi8qKiBTY2hlbWEgZm9yIHRoZSBwbHVnaW4ncyBjbGllbnQgY29uZmlnIHN1cmZhY2VkIHRvIGEgVUkuICovXG5leHBvcnQgY29uc3Qgc2VhcmNoQ2xpZW50Q29uZmlnU2NoZW1hID0gei5vYmplY3Qoe1xuICBpbmRleGVzOiB6LmFycmF5KHNlYXJjaEluZGV4SW5mb1NjaGVtYSkuZGVzY3JpYmUoXCJJbmRleGVzIHRoZSBzZWFyY2ggVUkgbWF5IHF1ZXJ5LlwiKSxcbiAgZGVmYXVsdEluZGV4OiB6LnN0cmluZygpLm9wdGlvbmFsKCkuZGVzY3JpYmUoXCJUaGUgaW5kZXggYSBzZWFyY2ggYm94IHNlbGVjdHMgYnkgZGVmYXVsdC5cIiksXG4gIHBhZ2VTaXplOiB6Lm51bWJlcigpLmludCgpLmRlc2NyaWJlKFwiRGVmYXVsdCBudW1iZXIgb2YgaGl0cyBhIHNlYXJjaCByZXR1cm5zLlwiKSxcbiAgYmFzZVBhdGg6IHpcbiAgICAuc3RyaW5nKClcbiAgICAuZGVzY3JpYmUoXCJCYXNlIHBhdGggdGhlIHNlYXJjaCByb3V0ZXMgYXJlIG1vdW50ZWQgdW5kZXIgKGUuZy4gL2FwaS9zZWFyY2gpLlwiKSxcbn0pO1xuXG4vKiogVGhlIHBsdWdpbidzIGNsaWVudCBjb25maWcgKHtAbGluayBzZWFyY2hDbGllbnRDb25maWdTY2hlbWF9KS4gKi9cbmV4cG9ydCB0eXBlIFNlYXJjaENsaWVudENvbmZpZyA9IHouaW5mZXI8dHlwZW9mIHNlYXJjaENsaWVudENvbmZpZ1NjaGVtYT47XG5cbi8qKlxuICogU2NoZW1hIGZvciBjcmVhdGluZyBhbiBpbmRleCAodGhlIGBjcmVhdGVfaW5kZXhgIHRvb2wgaW5wdXQgLyB0aGVcbiAqIGBQT1NUIC9hcGkvc2VhcmNoL2luZGV4YCBib2R5KS4gVHdvIHNoYXBlcywgYm90aCBpbmZlcnJpbmcgYWdncmVzc2l2ZWx5OlxuICogcGFzcyBgc291cmNlVGFibGVgIGZvciBhIERlbHRhIFN5bmMgaW5kZXggKERhdGFicmlja3MgY29tcHV0ZXMgZW1iZWRkaW5ncyBhbmRcbiAqIGtlZXBzIGl0IHN5bmNlZCkgb3IgYGVtYmVkZGluZ0RpbWVuc2lvbmAgZm9yIGEgZGlyZWN0LWFjY2VzcyBpbmRleCB5b3Ugd3JpdGVcbiAqIHZlY3RvcnMgdG8geW91cnNlbGYuXG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGVJbmRleFJlcXVlc3RTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIG5hbWU6IHouc3RyaW5nKCkuZGVzY3JpYmUoXCJVbml0eSBDYXRhbG9nIG5hbWUgZm9yIHRoZSBuZXcgaW5kZXggKGNhdGFsb2cuc2NoZW1hLmluZGV4KS5cIiksXG4gIHNvdXJjZVRhYmxlOiB6XG4gICAgLnN0cmluZygpXG4gICAgLm9wdGlvbmFsKClcbiAgICAuZGVzY3JpYmUoXG4gICAgICBcIkRlbHRhIHRhYmxlIChjYXRhbG9nLnNjaGVtYS50YWJsZSkgdG8gYnVpbGQgYSBzeW5jZWQgaW5kZXggZnJvbS4gUHJvdmlkZSB0aGlzIE9SIGVtYmVkZGluZ0RpbWVuc2lvbi5cIixcbiAgICApLFxuICBwcmltYXJ5S2V5OiB6LnN0cmluZygpLm9wdGlvbmFsKCkuZGVzY3JpYmUoXCJQcmltYXJ5LWtleSBjb2x1bW4uIERlZmF1bHRzIHRvICdpZCcuXCIpLFxuICBlbWJlZGRpbmdTb3VyY2VDb2x1bW46IHpcbiAgICAuc3RyaW5nKClcbiAgICAub3B0aW9uYWwoKVxuICAgIC5kZXNjcmliZShcbiAgICAgIFwiVGV4dCBjb2x1bW4gZW1iZWRkaW5ncyBhcmUgY29tcHV0ZWQgZnJvbSAoRGVsdGEgU3luYykuIERlZmF1bHRzIHRvIHRoZSBmaXJzdCBvZiB0ZXh0L2NvbnRlbnQvYm9keS5cIixcbiAgICApLFxuICBlbWJlZGRpbmdNb2RlbDogelxuICAgIC5zdHJpbmcoKVxuICAgIC5vcHRpb25hbCgpXG4gICAgLmRlc2NyaWJlKFxuICAgICAgXCJFbWJlZGRpbmcgbW9kZWwgZW5kcG9pbnQgKG5hbWUgb3IgbG9vc2UgbmFtZSkuIERlZmF1bHRzIHRvIHRoZSBhcHAncyBlbWJlZGRpbmcgbW9kZWwsIG9yIHRoZSBiZXN0IGVtYmVkZGluZyBlbmRwb2ludCBpbiB0aGUgd29ya3NwYWNlLlwiLFxuICAgICksXG4gIGVuZHBvaW50OiB6XG4gICAgLnN0cmluZygpXG4gICAgLm9wdGlvbmFsKClcbiAgICAuZGVzY3JpYmUoXG4gICAgICBcIlZlY3RvciBTZWFyY2ggZW5kcG9pbnQgdG8gaG9zdCB0aGUgaW5kZXggb24uIERlZmF1bHRzIHRvIHRoZSBhcHAncyBjb25maWd1cmVkIGVuZHBvaW50LlwiLFxuICAgICksXG4gIGVtYmVkZGluZ0RpbWVuc2lvbjogelxuICAgIC5udW1iZXIoKVxuICAgIC5pbnQoKVxuICAgIC5wb3NpdGl2ZSgpXG4gICAgLm9wdGlvbmFsKClcbiAgICAuZGVzY3JpYmUoXCJGb3IgYSBkaXJlY3QtYWNjZXNzIGluZGV4IChubyBzb3VyY2UgdGFibGUpOiB0aGUgZW1iZWRkaW5nIHZlY3RvciBkaW1lbnNpb24uXCIpLFxuICBwaXBlbGluZVR5cGU6IHpcbiAgICAuZW51bShbXCJUUklHR0VSRURcIiwgXCJDT05USU5VT1VTXCJdKVxuICAgIC5vcHRpb25hbCgpXG4gICAgLmRlc2NyaWJlKFxuICAgICAgXCJEZWx0YSBTeW5jIG1vZGU6ICdUUklHR0VSRUQnIChkZWZhdWx0KSBzeW5jcyBvbiBkZW1hbmQ7ICdDT05USU5VT1VTJyBrZWVwcyB0aGUgaW5kZXggZnJlc2guXCIsXG4gICAgKSxcbiAgY29sdW1uc1RvU3luYzogelxuICAgIC5hcnJheSh6LnN0cmluZygpKVxuICAgIC5vcHRpb25hbCgpXG4gICAgLmRlc2NyaWJlKFwiRXh0cmEgY29sdW1ucyB0byBzeW5jIGFsb25nc2lkZSB0aGUgZW1iZWRkaW5nIHNvdXJjZSBjb2x1bW4gKERlbHRhIFN5bmMpLlwiKSxcbn0pO1xuXG4vKiogQSB2YWxpZGF0ZWQgY3JlYXRlLWluZGV4IHJlcXVlc3QgKHtAbGluayBjcmVhdGVJbmRleFJlcXVlc3RTY2hlbWF9KS4gKi9cbmV4cG9ydCB0eXBlIENyZWF0ZUluZGV4UmVxdWVzdCA9IHouaW5mZXI8dHlwZW9mIGNyZWF0ZUluZGV4UmVxdWVzdFNjaGVtYT47XG5cbi8qKiBTY2hlbWEgZm9yIHRoZSBgc3luY19pbmRleGAgdG9vbCBpbnB1dCAvIHRoZSBgUE9TVCAvYXBpL3NlYXJjaC9pbmRleC9zeW5jYCBib2R5LiAqL1xuZXhwb3J0IGNvbnN0IHN5bmNJbmRleFJlcXVlc3RTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIGluZGV4OiB6XG4gICAgLnN0cmluZygpXG4gICAgLmRlc2NyaWJlKFxuICAgICAgXCJUaGUgaW5kZXggdG8gc3luYyAobmFtZSBvciBjb25maWd1cmVkIGFsaWFzKS4gRGVmYXVsdHMgdG8gdGhlIGFwcCdzIGRlZmF1bHQgaW5kZXggd2hlbiBvbWl0dGVkLlwiLFxuICAgIClcbiAgICAub3B0aW9uYWwoKSxcbn0pO1xuXG4vKiogQSB2YWxpZGF0ZWQgc3luYy1pbmRleCByZXF1ZXN0ICh7QGxpbmsgc3luY0luZGV4UmVxdWVzdFNjaGVtYX0pLiAqL1xuZXhwb3J0IHR5cGUgU3luY0luZGV4UmVxdWVzdCA9IHouaW5mZXI8dHlwZW9mIHN5bmNJbmRleFJlcXVlc3RTY2hlbWE+O1xuXG4vKiogU2NoZW1hIGZvciBhIHJlc29sdmVkIGluZGV4IGRlZmluaXRpb24gKHRoZSBjcmVhdGUvZ2V0IHJlc3VsdCkuICovXG5leHBvcnQgY29uc3QgaW5kZXhJbmZvU2NoZW1hID0gei5vYmplY3Qoe1xuICBuYW1lOiB6LnN0cmluZygpLmRlc2NyaWJlKFwiVW5pdHkgQ2F0YWxvZyBuYW1lIG9mIHRoZSBpbmRleC5cIiksXG4gIGVuZHBvaW50OiB6LnN0cmluZygpLm9wdGlvbmFsKCkuZGVzY3JpYmUoXCJUaGUgVmVjdG9yIFNlYXJjaCBlbmRwb2ludCBob3N0aW5nIHRoZSBpbmRleC5cIiksXG4gIHByaW1hcnlLZXk6IHouc3RyaW5nKCkub3B0aW9uYWwoKS5kZXNjcmliZShcIlRoZSBpbmRleCdzIHByaW1hcnkta2V5IGNvbHVtbi5cIiksXG4gIGNvbHVtbnM6IHouYXJyYXkoei5zdHJpbmcoKSkuZGVzY3JpYmUoXCJDb2x1bW5zIGF2YWlsYWJsZSBvbiB0aGUgaW5kZXguXCIpLFxuICByZWFkeTogei5ib29sZWFuKCkuZGVzY3JpYmUoXCJUcnVlIHdoZW4gdGhlIGluZGV4IGhhcyBmaW5pc2hlZCBwcm92aXNpb25pbmcgYW5kIGNhbiBiZSBxdWVyaWVkLlwiKSxcbiAgcm93Q291bnQ6IHoubnVtYmVyKCkuaW50KCkub3B0aW9uYWwoKS5kZXNjcmliZShcIk51bWJlciBvZiBpbmRleGVkIHJvd3MsIHdoZW4ga25vd24uXCIpLFxufSk7XG5cbi8qKiBBIHJlc29sdmVkIGluZGV4IGRlZmluaXRpb24gKHtAbGluayBpbmRleEluZm9TY2hlbWF9KS4gKi9cbmV4cG9ydCB0eXBlIEluZGV4SW5mbyA9IHouaW5mZXI8dHlwZW9mIGluZGV4SW5mb1NjaGVtYT47XG4iXX0=
File without changes
File without changes