@dbx-tools/appkit-mastra 0.6.12 → 0.6.13

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
@@ -276,6 +276,36 @@ optional peer to enable the richest source formats:
276
276
  pnpm add skills
277
277
  ```
278
278
 
279
+ ### Refresh policy
280
+
281
+ Provisioning runs on every app boot, and skill trees change rarely, so each
282
+ provisioned tree carries a `.metadata.json` at its root recording when each
283
+ source was last downloaded. A source is only re-downloaded once that record is
284
+ older than a day; inside the window the existing tree is reused and no network
285
+ call is made. The record travels with the tree rather than living in process
286
+ memory, so a container that restarts a dozen times an hour pulls each source
287
+ once, not a dozen times.
288
+
289
+ ```ts
290
+ mastra({
291
+ // Re-pull at most once an hour instead of once a day.
292
+ remoteSkills: { sources: ["aitools"], refreshTtlMs: 60 * 60 * 1000 },
293
+ });
294
+
295
+ // Per-source, and `0` to download on every boot:
296
+ mastra({
297
+ remoteSkills: {
298
+ sources: [{ source: "owner/skill-repo", refreshTtlMs: 0 }, "aitools"],
299
+ },
300
+ });
301
+ ```
302
+
303
+ The record is keyed by the source AND the options that change what it contains
304
+ (`skills`, `experimental`, `ref`), so narrowing a skill list or moving a `ref`
305
+ re-downloads immediately rather than serving the previous selection for a day.
306
+ A missing or unreadable record is treated as a cache miss, never as a startup
307
+ failure.
308
+
279
309
  ## Databricks AI Tools
280
310
 
281
311
  [Databricks AI Tools](https://github.com/databricks/databricks-agent-skills) are
@@ -571,8 +601,9 @@ requiring callers to assemble a Mastra server by hand.
571
601
  PgVector options. `true` resolves from `lakebase()` when present.
572
602
  - `remoteSkills` provisions `SKILL.md` sources from outside the workspace at
573
603
  startup (see [Remote Skills](#remote-skills)). Accepts a single source, a
574
- list, or an options bag with `failOnError`, `userEmail`, and
575
- `databricksBasePath`. A source is `"aitools"` (see
604
+ list, or an options bag with `failOnError`, `userEmail`,
605
+ `databricksBasePath`, and `refreshTtlMs` (how long a provisioned tree is
606
+ reused before re-downloading, a day by default). A source is `"aitools"` (see
576
607
  [Databricks AI Tools](#databricks-ai-tools)) or any URL-like.
577
608
  - `genieSpaces` maps aliases to Genie Space IDs (or to
578
609
  `{ spaceId, hint }` objects). Those aliases flow into tool names,
@@ -629,7 +660,9 @@ client that talks to these routes.
629
660
  - `remote-skills` - startup provisioning of remote `SKILL.md` sources into the
630
661
  Databricks Assistant skills tree (or a local temp dir): the `"aitools"`
631
662
  constant reads Databricks' own skill repo directly, and any other source goes
632
- through the optional `skills` CLI or a direct fetch.
663
+ through the optional `skills` CLI or a direct fetch. Each tree carries a
664
+ `.metadata.json` so a source is re-downloaded at most once a day
665
+ (`refreshTtlMs`).
633
666
  - `mcp` - MCP server construction.
634
667
  - `observability` / `mlflow` - tracing and feedback.
635
668
  - `server` / `rest` / `processors` - Express dispatch, Databricks REST helpers,
package/index.ts CHANGED
@@ -53,7 +53,7 @@ export type { PerPageBounds } from "./src/pagination.ts";
53
53
  export { MastraPlugin, mastra } from "./src/plugin.ts";
54
54
  export { stripStaleChartsProcessor, ResultProcessor } from "./src/processors.ts";
55
55
  export { AITOOLS_SOURCE } from "./src/remote-skills.ts";
56
- export type { AiToolsSource, RemoteSkillSourceOptions, RemoteSkillSource, RemoteSkillsOption, ProvisionRemoteSkillsOptions, ProvisionedRemoteSkills } from "./src/remote-skills.ts";
56
+ export type { AiToolsSource, RemoteSkillSourceOptions, RemoteSkillSource, RemoteSkillsOption, ProvisionRemoteSkillsOptions, ProvisionedRemoteSkills, RemoteSkillCacheEntry, RemoteSkillsMetadata } from "./src/remote-skills.ts";
57
57
  export type { DatabricksFetchInit } from "./src/rest.ts";
58
58
  export { MastraServer } from "./src/server.ts";
59
59
  export type { AttributedIdentity, MastraApiGateOptions } from "./src/server.ts";
package/lib/index.d.ts CHANGED
@@ -49,7 +49,7 @@ export type { PerPageBounds } from "./src/pagination.ts";
49
49
  export { MastraPlugin, mastra } from "./src/plugin.ts";
50
50
  export { stripStaleChartsProcessor, ResultProcessor } from "./src/processors.ts";
51
51
  export { AITOOLS_SOURCE } from "./src/remote-skills.ts";
52
- export type { AiToolsSource, RemoteSkillSourceOptions, RemoteSkillSource, RemoteSkillsOption, ProvisionRemoteSkillsOptions, ProvisionedRemoteSkills } from "./src/remote-skills.ts";
52
+ export type { AiToolsSource, RemoteSkillSourceOptions, RemoteSkillSource, RemoteSkillsOption, ProvisionRemoteSkillsOptions, ProvisionedRemoteSkills, RemoteSkillCacheEntry, RemoteSkillsMetadata } from "./src/remote-skills.ts";
53
53
  export type { DatabricksFetchInit } from "./src/rest.ts";
54
54
  export { MastraServer } from "./src/server.ts";
55
55
  export type { AttributedIdentity, MastraApiGateOptions } from "./src/server.ts";
package/lib/index.js CHANGED
@@ -44,4 +44,4 @@ export { MastraServer } from "./src/server.js";
44
44
  export { MASTRA_MODEL_OVERRIDE_KEY } from "./src/serving.js";
45
45
  export { STATEMENT_ROW_CAP } from "./src/statement.js";
46
46
  export { TITLE_INSTRUCTIONS } from "./src/summarize.js";
47
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxPQUFPLEtBQUssTUFBTSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxLQUFLLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEMsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssUUFBUSxNQUFNLG1CQUFtQixDQUFDO0FBQzlDLE9BQU8sS0FBSyxXQUFXLE1BQU0sc0JBQXNCLENBQUM7QUFDcEQsT0FBTyxLQUFLLEtBQUssTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QyxPQUFPLEtBQUssT0FBTyxNQUFNLGtCQUFrQixDQUFDO0FBQzVDLE9BQU8sS0FBSyxRQUFRLE1BQU0sbUJBQW1CLENBQUM7QUFDOUMsT0FBTyxLQUFLLEdBQUcsTUFBTSxjQUFjLENBQUM7QUFDcEMsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssTUFBTSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxLQUFLLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEMsT0FBTyxLQUFLLGFBQWEsTUFBTSx3QkFBd0IsQ0FBQztBQUN4RCxPQUFPLEtBQUssVUFBVSxNQUFNLHFCQUFxQixDQUFDO0FBQ2xELE9BQU8sS0FBSyxNQUFNLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxLQUFLLFVBQVUsTUFBTSxxQkFBcUIsQ0FBQztBQUNsRCxPQUFPLEtBQUssWUFBWSxNQUFNLHdCQUF3QixDQUFDO0FBQ3ZELE9BQU8sS0FBSyxJQUFJLE1BQU0sZUFBZSxDQUFDO0FBQ3RDLE9BQU8sS0FBSyxNQUFNLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxLQUFLLE9BQU8sTUFBTSxrQkFBa0IsQ0FBQztBQUM1QyxPQUFPLEtBQUssZUFBZSxNQUFNLDJCQUEyQixDQUFDO0FBQzdELE9BQU8sS0FBSyxTQUFTLE1BQU0sb0JBQW9CLENBQUM7QUFDaEQsT0FBTyxLQUFLLGFBQWEsTUFBTSx5QkFBeUIsQ0FBQztBQUN6RCxPQUFPLEtBQUssU0FBUyxNQUFNLG9CQUFvQixDQUFDO0FBQ2hELE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxLQUFLLFVBQVUsTUFBTSxxQkFBcUIsQ0FBQztBQUNsRCxPQUFPLEtBQUssVUFBVSxNQUFNLHFCQUFxQixDQUFDO0FBQ2xELE9BQU8sS0FBSyxNQUFNLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLHVCQUF1QixFQUFFLDBCQUEwQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFekcsT0FBTyxFQUFFLGVBQWUsRUFBRSx5QkFBeUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTVFLE9BQU8sRUFBRSxlQUFlLEVBQUUsb0JBQW9CLEVBQUUscUJBQXFCLEVBQUUscUJBQXFCLEVBQUUsaUJBQWlCLEVBQUUsMEJBQTBCLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUUzTCxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsdUJBQXVCLEVBQUUscUJBQXFCLEVBQUUsa0JBQWtCLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUN0SixPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUUvRCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUd6RSxPQUFPLEVBQUUsWUFBWSxFQUFFLGNBQWMsRUFBRSxxQkFBcUIsRUFBRSxjQUFjLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUczSCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFLaEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUseUJBQXlCLEVBQUUsZUFBZSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDakYsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBR3hELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUUvQyxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUc3RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN2RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEdFTkVSQVRFRCBieSBwcm9qZW4gd2F0Y2ggLSBETyBOT1QgRURJVC5cbi8vIFJlZ2VuZXJhdGVkIGZyb20gdGhlIGV4cG9ydGluZyBtb2R1bGVzIGluIC4vc3JjLlxuLy8gSGFuZCBlZGl0cyBhcmUgb3ZlcndyaXR0ZW4gb24gdGhlIG5leHQgd2F0Y2g7IHRoaXMgZmlsZSBpcyByZWFkLW9ubHkuXG5cbmV4cG9ydCAqIGFzIGFnZW50cyBmcm9tIFwiLi9zcmMvYWdlbnRzLnRzXCI7XG5leHBvcnQgKiBhcyBjaGFydCBmcm9tIFwiLi9zcmMvY2hhcnQudHNcIjtcbmV4cG9ydCAqIGFzIGNvbmZpZyBmcm9tIFwiLi9zcmMvY29uZmlnLnRzXCI7XG5leHBvcnQgKiBhcyBkZWZhdWx0cyBmcm9tIFwiLi9zcmMvZGVmYXVsdHMudHNcIjtcbmV4cG9ydCAqIGFzIGZpbGVzeXN0ZW1zIGZyb20gXCIuL3NyYy9maWxlc3lzdGVtcy50c1wiO1xuZXhwb3J0ICogYXMgZ2VuaWUgZnJvbSBcIi4vc3JjL2dlbmllLnRzXCI7XG5leHBvcnQgKiBhcyBoaXN0b3J5IGZyb20gXCIuL3NyYy9oaXN0b3J5LnRzXCI7XG5leHBvcnQgKiBhcyBpZGVudGl0eSBmcm9tIFwiLi9zcmMvaWRlbnRpdHkudHNcIjtcbmV4cG9ydCAqIGFzIG1jcCBmcm9tIFwiLi9zcmMvbWNwLnRzXCI7XG5leHBvcnQgKiBhcyBtZW1vcnkgZnJvbSBcIi4vc3JjL21lbW9yeS50c1wiO1xuZXhwb3J0ICogYXMgbWxmbG93IGZyb20gXCIuL3NyYy9tbGZsb3cudHNcIjtcbmV4cG9ydCAqIGFzIG1vZGVsIGZyb20gXCIuL3NyYy9tb2RlbC50c1wiO1xuZXhwb3J0ICogYXMgb2JzZXJ2YWJpbGl0eSBmcm9tIFwiLi9zcmMvb2JzZXJ2YWJpbGl0eS50c1wiO1xuZXhwb3J0ICogYXMgcGFnaW5hdGlvbiBmcm9tIFwiLi9zcmMvcGFnaW5hdGlvbi50c1wiO1xuZXhwb3J0ICogYXMgcGx1Z2luIGZyb20gXCIuL3NyYy9wbHVnaW4udHNcIjtcbmV4cG9ydCAqIGFzIHByb2Nlc3NvcnMgZnJvbSBcIi4vc3JjL3Byb2Nlc3NvcnMudHNcIjtcbmV4cG9ydCAqIGFzIHJlbW90ZVNraWxscyBmcm9tIFwiLi9zcmMvcmVtb3RlLXNraWxscy50c1wiO1xuZXhwb3J0ICogYXMgcmVzdCBmcm9tIFwiLi9zcmMvcmVzdC50c1wiO1xuZXhwb3J0ICogYXMgc2VydmVyIGZyb20gXCIuL3NyYy9zZXJ2ZXIudHNcIjtcbmV4cG9ydCAqIGFzIHNlcnZpbmcgZnJvbSBcIi4vc3JjL3NlcnZpbmcudHNcIjtcbmV4cG9ydCAqIGFzIHNlcnZpbmdTYW5pdGl6ZSBmcm9tIFwiLi9zcmMvc2VydmluZy1zYW5pdGl6ZS50c1wiO1xuZXhwb3J0ICogYXMgc3RhdGVtZW50IGZyb20gXCIuL3NyYy9zdGF0ZW1lbnQudHNcIjtcbmV4cG9ydCAqIGFzIHN0b3JhZ2VTY2hlbWEgZnJvbSBcIi4vc3JjL3N0b3JhZ2Utc2NoZW1hLnRzXCI7XG5leHBvcnQgKiBhcyBzdW1tYXJpemUgZnJvbSBcIi4vc3JjL3N1bW1hcml6ZS50c1wiO1xuZXhwb3J0ICogYXMgdGhyZWFkcyBmcm9tIFwiLi9zcmMvdGhyZWFkcy50c1wiO1xuZXhwb3J0ICogYXMgdmFsaWRhdGlvbiBmcm9tIFwiLi9zcmMvdmFsaWRhdGlvbi50c1wiO1xuZXhwb3J0ICogYXMgd29ya3NwYWNlcyBmcm9tIFwiLi9zcmMvd29ya3NwYWNlcy50c1wiO1xuZXhwb3J0ICogYXMgd3JpdGVyIGZyb20gXCIuL3NyYy93cml0ZXIudHNcIjtcbmV4cG9ydCB7IEZBTExCQUNLX0FHRU5UX0lELCBERUZBVUxUX0FHRU5UX01BWF9TVEVQUywgREVGQVVMVF9TVFlMRV9JTlNUUlVDVElPTlMgfSBmcm9tIFwiLi9zcmMvYWdlbnRzLnRzXCI7XG5leHBvcnQgdHlwZSB7IE1hc3RyYVRvb2xzLCBBcHBLaXRUb29sT3B0aW9ucywgVG9vbGtpdE9wdGlvbnMsIE1hc3RyYVBsdWdpblRvb2xraXRQcm92aWRlciwgTWFzdHJhUGx1Z2lucywgTWFzdHJhVG9vbHNGbiwgTWFzdHJhQWdlbnRXb3Jrc3BhY2VSZXNvbHZlciwgTWFzdHJhQWdlbnREZWZpbml0aW9uLCBNYXN0cmFTdG9yYWdlQ29uZmlnT3ZlcnJpZGUsIE1hc3RyYU1lbW9yeUNvbmZpZ092ZXJyaWRlLCBCdWlsdEFnZW50cyB9IGZyb20gXCIuL3NyYy9hZ2VudHMudHNcIjtcbmV4cG9ydCB7IGNoYXJ0UGxhblNjaGVtYSwgY2hhcnRQbGFubmVyUmVxdWVzdFNjaGVtYSB9IGZyb20gXCIuL3NyYy9jaGFydC50c1wiO1xuZXhwb3J0IHR5cGUgeyBDaGFydFBsYW5uZXJSZXF1ZXN0LCBQcmVwYXJlQ2hhcnRPcHRpb25zLCBGZXRjaENoYXJ0T3B0aW9ucyB9IGZyb20gXCIuL3NyYy9jaGFydC50c1wiO1xuZXhwb3J0IHsgTUFTVFJBX1VTRVJfS0VZLCBNQVNUUkFfVVNFUl9OQU1FX0tFWSwgTUFTVFJBX1VTRVJfRU1BSUxfS0VZLCBNQVNUUkFfUkVRVUVTVF9JRF9LRVksIE1BU1RSQV9TQ09QRVNfS0VZLCBUUkFDRV9SRVFVRVNUX0NPTlRFWFRfS0VZUywgTUFTVFJBX0NPTkZJR19TQ0hFTUEgfSBmcm9tIFwiLi9zcmMvY29uZmlnLnRzXCI7XG5leHBvcnQgdHlwZSB7IFVzZXIsIE1hc3RyYU1lbW9yeUNvbmZpZywgTWFzdHJhTWNwQ29uZmlnLCBNYXN0cmFQbHVnaW5Db25maWcgfSBmcm9tIFwiLi9zcmMvY29uZmlnLnRzXCI7XG5leHBvcnQgeyBtb2RlbENhdGFsb2d1ZURlZmF1bHRzLCBnZW5pZVN1Z2dlc3Rpb25EZWZhdWx0cywgc3RhdGVtZW50RGF0YURlZmF1bHRzLCBjaGFydEZldGNoRGVmYXVsdHMsIGZlZWRiYWNrV3JpdGVEZWZhdWx0cyB9IGZyb20gXCIuL3NyYy9kZWZhdWx0cy50c1wiO1xuZXhwb3J0IHsgTWFzdHJhRmlsZVN5c3RlbUFkYXB0ZXIgfSBmcm9tIFwiLi9zcmMvZmlsZXN5c3RlbXMudHNcIjtcbmV4cG9ydCB0eXBlIHsgTWFzdHJhRmlsZVN5c3RlbUFkYXB0ZXJPcHRpb25zIH0gZnJvbSBcIi4vc3JjL2ZpbGVzeXN0ZW1zLnRzXCI7XG5leHBvcnQgeyBERUZBVUxUX0dFTklFX0FMSUFTLCBHRU5JRV9JTlNUUlVDVElPTlMgfSBmcm9tIFwiLi9zcmMvZ2VuaWUudHNcIjtcbmV4cG9ydCB0eXBlIHsgR2VuaWVTcGFjZUNvbmZpZywgR2VuaWVTcGFjZXNDb25maWcgfSBmcm9tIFwiLi9zcmMvZ2VuaWUudHNcIjtcbmV4cG9ydCB0eXBlIHsgTG9hZEhpc3RvcnlPcHRpb25zLCBDbGVhckhpc3RvcnlPcHRpb25zLCBIaXN0b3J5Um91dGVPcHRpb25zIH0gZnJvbSBcIi4vc3JjL2hpc3RvcnkudHNcIjtcbmV4cG9ydCB7IElERU5USVRZX0VOViwgSURFTlRJVFlfTU9ERVMsIERFRkFVTFRfSURFTlRJVFlfTU9ERSwgVVNFUl9JRF9IRUFERVIsIFVTRVJfRU1BSUxfSEVBREVSIH0gZnJvbSBcIi4vc3JjL2lkZW50aXR5LnRzXCI7XG5leHBvcnQgdHlwZSB7IE1hc3RyYUlkZW50aXR5TW9kZSB9IGZyb20gXCIuL3NyYy9pZGVudGl0eS50c1wiO1xuZXhwb3J0IHR5cGUgeyBSZXNvbHZlZE1jcCB9IGZyb20gXCIuL3NyYy9tY3AudHNcIjtcbmV4cG9ydCB7IE1lbW9yeUJ1aWxkZXIgfSBmcm9tIFwiLi9zcmMvbWVtb3J5LnRzXCI7XG5leHBvcnQgdHlwZSB7IExvZ0ZlZWRiYWNrUGFyYW1zIH0gZnJvbSBcIi4vc3JjL21sZmxvdy50c1wiO1xuZXhwb3J0IHR5cGUgeyBCdWlsZE1vZGVsT3ZlcnJpZGVzIH0gZnJvbSBcIi4vc3JjL21vZGVsLnRzXCI7XG5leHBvcnQgdHlwZSB7IEJ1aWxkT2JzZXJ2YWJpbGl0eU9wdGlvbnMgfSBmcm9tIFwiLi9zcmMvb2JzZXJ2YWJpbGl0eS50c1wiO1xuZXhwb3J0IHR5cGUgeyBQZXJQYWdlQm91bmRzIH0gZnJvbSBcIi4vc3JjL3BhZ2luYXRpb24udHNcIjtcbmV4cG9ydCB7IE1hc3RyYVBsdWdpbiwgbWFzdHJhIH0gZnJvbSBcIi4vc3JjL3BsdWdpbi50c1wiO1xuZXhwb3J0IHsgc3RyaXBTdGFsZUNoYXJ0c1Byb2Nlc3NvciwgUmVzdWx0UHJvY2Vzc29yIH0gZnJvbSBcIi4vc3JjL3Byb2Nlc3NvcnMudHNcIjtcbmV4cG9ydCB7IEFJVE9PTFNfU09VUkNFIH0gZnJvbSBcIi4vc3JjL3JlbW90ZS1za2lsbHMudHNcIjtcbmV4cG9ydCB0eXBlIHsgQWlUb29sc1NvdXJjZSwgUmVtb3RlU2tpbGxTb3VyY2VPcHRpb25zLCBSZW1vdGVTa2lsbFNvdXJjZSwgUmVtb3RlU2tpbGxzT3B0aW9uLCBQcm92aXNpb25SZW1vdGVTa2lsbHNPcHRpb25zLCBQcm92aXNpb25lZFJlbW90ZVNraWxscyB9IGZyb20gXCIuL3NyYy9yZW1vdGUtc2tpbGxzLnRzXCI7XG5leHBvcnQgdHlwZSB7IERhdGFicmlja3NGZXRjaEluaXQgfSBmcm9tIFwiLi9zcmMvcmVzdC50c1wiO1xuZXhwb3J0IHsgTWFzdHJhU2VydmVyIH0gZnJvbSBcIi4vc3JjL3NlcnZlci50c1wiO1xuZXhwb3J0IHR5cGUgeyBBdHRyaWJ1dGVkSWRlbnRpdHksIE1hc3RyYUFwaUdhdGVPcHRpb25zIH0gZnJvbSBcIi4vc3JjL3NlcnZlci50c1wiO1xuZXhwb3J0IHsgTUFTVFJBX01PREVMX09WRVJSSURFX0tFWSB9IGZyb20gXCIuL3NyYy9zZXJ2aW5nLnRzXCI7XG5leHBvcnQgdHlwZSB7IE1vZGVsT3ZlcnJpZGVSZXF1ZXN0IH0gZnJvbSBcIi4vc3JjL3NlcnZpbmcudHNcIjtcbmV4cG9ydCB0eXBlIHsgU2VydmluZ0NoYXRNZXNzYWdlIH0gZnJvbSBcIi4vc3JjL3NlcnZpbmctc2FuaXRpemUudHNcIjtcbmV4cG9ydCB7IFNUQVRFTUVOVF9ST1dfQ0FQIH0gZnJvbSBcIi4vc3JjL3N0YXRlbWVudC50c1wiO1xuZXhwb3J0IHsgVElUTEVfSU5TVFJVQ1RJT05TIH0gZnJvbSBcIi4vc3JjL3N1bW1hcml6ZS50c1wiO1xuZXhwb3J0IHR5cGUgeyBTdW1tYXJpemVPcHRpb25zIH0gZnJvbSBcIi4vc3JjL3N1bW1hcml6ZS50c1wiO1xuZXhwb3J0IHR5cGUgeyBMaXN0VGhyZWFkc09wdGlvbnMsIERlbGV0ZVRocmVhZE9wdGlvbnMsIFJlbmFtZVRocmVhZE9wdGlvbnMsIFRocmVhZHNSb3V0ZU9wdGlvbnMgfSBmcm9tIFwiLi9zcmMvdGhyZWFkcy50c1wiO1xuZXhwb3J0IHR5cGUgeyBTY2hlbWFJc3N1ZXMgfSBmcm9tIFwiLi9zcmMvdmFsaWRhdGlvbi50c1wiO1xuZXhwb3J0IHR5cGUgeyBDcmVhdGVXb3Jrc3BhY2VPcHRpb25zIH0gZnJvbSBcIi4vc3JjL3dvcmtzcGFjZXMudHNcIjtcbiJdfQ==
47
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxPQUFPLEtBQUssTUFBTSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxLQUFLLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEMsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssUUFBUSxNQUFNLG1CQUFtQixDQUFDO0FBQzlDLE9BQU8sS0FBSyxXQUFXLE1BQU0sc0JBQXNCLENBQUM7QUFDcEQsT0FBTyxLQUFLLEtBQUssTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QyxPQUFPLEtBQUssT0FBTyxNQUFNLGtCQUFrQixDQUFDO0FBQzVDLE9BQU8sS0FBSyxRQUFRLE1BQU0sbUJBQW1CLENBQUM7QUFDOUMsT0FBTyxLQUFLLEdBQUcsTUFBTSxjQUFjLENBQUM7QUFDcEMsT0FBTyxLQUFLLE1BQU0sTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEtBQUssTUFBTSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxLQUFLLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEMsT0FBTyxLQUFLLGFBQWEsTUFBTSx3QkFBd0IsQ0FBQztBQUN4RCxPQUFPLEtBQUssVUFBVSxNQUFNLHFCQUFxQixDQUFDO0FBQ2xELE9BQU8sS0FBSyxNQUFNLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxLQUFLLFVBQVUsTUFBTSxxQkFBcUIsQ0FBQztBQUNsRCxPQUFPLEtBQUssWUFBWSxNQUFNLHdCQUF3QixDQUFDO0FBQ3ZELE9BQU8sS0FBSyxJQUFJLE1BQU0sZUFBZSxDQUFDO0FBQ3RDLE9BQU8sS0FBSyxNQUFNLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxLQUFLLE9BQU8sTUFBTSxrQkFBa0IsQ0FBQztBQUM1QyxPQUFPLEtBQUssZUFBZSxNQUFNLDJCQUEyQixDQUFDO0FBQzdELE9BQU8sS0FBSyxTQUFTLE1BQU0sb0JBQW9CLENBQUM7QUFDaEQsT0FBTyxLQUFLLGFBQWEsTUFBTSx5QkFBeUIsQ0FBQztBQUN6RCxPQUFPLEtBQUssU0FBUyxNQUFNLG9CQUFvQixDQUFDO0FBQ2hELE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxLQUFLLFVBQVUsTUFBTSxxQkFBcUIsQ0FBQztBQUNsRCxPQUFPLEtBQUssVUFBVSxNQUFNLHFCQUFxQixDQUFDO0FBQ2xELE9BQU8sS0FBSyxNQUFNLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLHVCQUF1QixFQUFFLDBCQUEwQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFekcsT0FBTyxFQUFFLGVBQWUsRUFBRSx5QkFBeUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTVFLE9BQU8sRUFBRSxlQUFlLEVBQUUsb0JBQW9CLEVBQUUscUJBQXFCLEVBQUUscUJBQXFCLEVBQUUsaUJBQWlCLEVBQUUsMEJBQTBCLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUUzTCxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsdUJBQXVCLEVBQUUscUJBQXFCLEVBQUUsa0JBQWtCLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUN0SixPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUUvRCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUd6RSxPQUFPLEVBQUUsWUFBWSxFQUFFLGNBQWMsRUFBRSxxQkFBcUIsRUFBRSxjQUFjLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUczSCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFLaEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUseUJBQXlCLEVBQUUsZUFBZSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDakYsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBR3hELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUUvQyxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUc3RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN2RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEdFTkVSQVRFRCBieSBwcm9qZW4gd2F0Y2ggLSBETyBOT1QgRURJVC5cbi8vIFJlZ2VuZXJhdGVkIGZyb20gdGhlIGV4cG9ydGluZyBtb2R1bGVzIGluIC4vc3JjLlxuLy8gSGFuZCBlZGl0cyBhcmUgb3ZlcndyaXR0ZW4gb24gdGhlIG5leHQgd2F0Y2g7IHRoaXMgZmlsZSBpcyByZWFkLW9ubHkuXG5cbmV4cG9ydCAqIGFzIGFnZW50cyBmcm9tIFwiLi9zcmMvYWdlbnRzLnRzXCI7XG5leHBvcnQgKiBhcyBjaGFydCBmcm9tIFwiLi9zcmMvY2hhcnQudHNcIjtcbmV4cG9ydCAqIGFzIGNvbmZpZyBmcm9tIFwiLi9zcmMvY29uZmlnLnRzXCI7XG5leHBvcnQgKiBhcyBkZWZhdWx0cyBmcm9tIFwiLi9zcmMvZGVmYXVsdHMudHNcIjtcbmV4cG9ydCAqIGFzIGZpbGVzeXN0ZW1zIGZyb20gXCIuL3NyYy9maWxlc3lzdGVtcy50c1wiO1xuZXhwb3J0ICogYXMgZ2VuaWUgZnJvbSBcIi4vc3JjL2dlbmllLnRzXCI7XG5leHBvcnQgKiBhcyBoaXN0b3J5IGZyb20gXCIuL3NyYy9oaXN0b3J5LnRzXCI7XG5leHBvcnQgKiBhcyBpZGVudGl0eSBmcm9tIFwiLi9zcmMvaWRlbnRpdHkudHNcIjtcbmV4cG9ydCAqIGFzIG1jcCBmcm9tIFwiLi9zcmMvbWNwLnRzXCI7XG5leHBvcnQgKiBhcyBtZW1vcnkgZnJvbSBcIi4vc3JjL21lbW9yeS50c1wiO1xuZXhwb3J0ICogYXMgbWxmbG93IGZyb20gXCIuL3NyYy9tbGZsb3cudHNcIjtcbmV4cG9ydCAqIGFzIG1vZGVsIGZyb20gXCIuL3NyYy9tb2RlbC50c1wiO1xuZXhwb3J0ICogYXMgb2JzZXJ2YWJpbGl0eSBmcm9tIFwiLi9zcmMvb2JzZXJ2YWJpbGl0eS50c1wiO1xuZXhwb3J0ICogYXMgcGFnaW5hdGlvbiBmcm9tIFwiLi9zcmMvcGFnaW5hdGlvbi50c1wiO1xuZXhwb3J0ICogYXMgcGx1Z2luIGZyb20gXCIuL3NyYy9wbHVnaW4udHNcIjtcbmV4cG9ydCAqIGFzIHByb2Nlc3NvcnMgZnJvbSBcIi4vc3JjL3Byb2Nlc3NvcnMudHNcIjtcbmV4cG9ydCAqIGFzIHJlbW90ZVNraWxscyBmcm9tIFwiLi9zcmMvcmVtb3RlLXNraWxscy50c1wiO1xuZXhwb3J0ICogYXMgcmVzdCBmcm9tIFwiLi9zcmMvcmVzdC50c1wiO1xuZXhwb3J0ICogYXMgc2VydmVyIGZyb20gXCIuL3NyYy9zZXJ2ZXIudHNcIjtcbmV4cG9ydCAqIGFzIHNlcnZpbmcgZnJvbSBcIi4vc3JjL3NlcnZpbmcudHNcIjtcbmV4cG9ydCAqIGFzIHNlcnZpbmdTYW5pdGl6ZSBmcm9tIFwiLi9zcmMvc2VydmluZy1zYW5pdGl6ZS50c1wiO1xuZXhwb3J0ICogYXMgc3RhdGVtZW50IGZyb20gXCIuL3NyYy9zdGF0ZW1lbnQudHNcIjtcbmV4cG9ydCAqIGFzIHN0b3JhZ2VTY2hlbWEgZnJvbSBcIi4vc3JjL3N0b3JhZ2Utc2NoZW1hLnRzXCI7XG5leHBvcnQgKiBhcyBzdW1tYXJpemUgZnJvbSBcIi4vc3JjL3N1bW1hcml6ZS50c1wiO1xuZXhwb3J0ICogYXMgdGhyZWFkcyBmcm9tIFwiLi9zcmMvdGhyZWFkcy50c1wiO1xuZXhwb3J0ICogYXMgdmFsaWRhdGlvbiBmcm9tIFwiLi9zcmMvdmFsaWRhdGlvbi50c1wiO1xuZXhwb3J0ICogYXMgd29ya3NwYWNlcyBmcm9tIFwiLi9zcmMvd29ya3NwYWNlcy50c1wiO1xuZXhwb3J0ICogYXMgd3JpdGVyIGZyb20gXCIuL3NyYy93cml0ZXIudHNcIjtcbmV4cG9ydCB7IEZBTExCQUNLX0FHRU5UX0lELCBERUZBVUxUX0FHRU5UX01BWF9TVEVQUywgREVGQVVMVF9TVFlMRV9JTlNUUlVDVElPTlMgfSBmcm9tIFwiLi9zcmMvYWdlbnRzLnRzXCI7XG5leHBvcnQgdHlwZSB7IE1hc3RyYVRvb2xzLCBBcHBLaXRUb29sT3B0aW9ucywgVG9vbGtpdE9wdGlvbnMsIE1hc3RyYVBsdWdpblRvb2xraXRQcm92aWRlciwgTWFzdHJhUGx1Z2lucywgTWFzdHJhVG9vbHNGbiwgTWFzdHJhQWdlbnRXb3Jrc3BhY2VSZXNvbHZlciwgTWFzdHJhQWdlbnREZWZpbml0aW9uLCBNYXN0cmFTdG9yYWdlQ29uZmlnT3ZlcnJpZGUsIE1hc3RyYU1lbW9yeUNvbmZpZ092ZXJyaWRlLCBCdWlsdEFnZW50cyB9IGZyb20gXCIuL3NyYy9hZ2VudHMudHNcIjtcbmV4cG9ydCB7IGNoYXJ0UGxhblNjaGVtYSwgY2hhcnRQbGFubmVyUmVxdWVzdFNjaGVtYSB9IGZyb20gXCIuL3NyYy9jaGFydC50c1wiO1xuZXhwb3J0IHR5cGUgeyBDaGFydFBsYW5uZXJSZXF1ZXN0LCBQcmVwYXJlQ2hhcnRPcHRpb25zLCBGZXRjaENoYXJ0T3B0aW9ucyB9IGZyb20gXCIuL3NyYy9jaGFydC50c1wiO1xuZXhwb3J0IHsgTUFTVFJBX1VTRVJfS0VZLCBNQVNUUkFfVVNFUl9OQU1FX0tFWSwgTUFTVFJBX1VTRVJfRU1BSUxfS0VZLCBNQVNUUkFfUkVRVUVTVF9JRF9LRVksIE1BU1RSQV9TQ09QRVNfS0VZLCBUUkFDRV9SRVFVRVNUX0NPTlRFWFRfS0VZUywgTUFTVFJBX0NPTkZJR19TQ0hFTUEgfSBmcm9tIFwiLi9zcmMvY29uZmlnLnRzXCI7XG5leHBvcnQgdHlwZSB7IFVzZXIsIE1hc3RyYU1lbW9yeUNvbmZpZywgTWFzdHJhTWNwQ29uZmlnLCBNYXN0cmFQbHVnaW5Db25maWcgfSBmcm9tIFwiLi9zcmMvY29uZmlnLnRzXCI7XG5leHBvcnQgeyBtb2RlbENhdGFsb2d1ZURlZmF1bHRzLCBnZW5pZVN1Z2dlc3Rpb25EZWZhdWx0cywgc3RhdGVtZW50RGF0YURlZmF1bHRzLCBjaGFydEZldGNoRGVmYXVsdHMsIGZlZWRiYWNrV3JpdGVEZWZhdWx0cyB9IGZyb20gXCIuL3NyYy9kZWZhdWx0cy50c1wiO1xuZXhwb3J0IHsgTWFzdHJhRmlsZVN5c3RlbUFkYXB0ZXIgfSBmcm9tIFwiLi9zcmMvZmlsZXN5c3RlbXMudHNcIjtcbmV4cG9ydCB0eXBlIHsgTWFzdHJhRmlsZVN5c3RlbUFkYXB0ZXJPcHRpb25zIH0gZnJvbSBcIi4vc3JjL2ZpbGVzeXN0ZW1zLnRzXCI7XG5leHBvcnQgeyBERUZBVUxUX0dFTklFX0FMSUFTLCBHRU5JRV9JTlNUUlVDVElPTlMgfSBmcm9tIFwiLi9zcmMvZ2VuaWUudHNcIjtcbmV4cG9ydCB0eXBlIHsgR2VuaWVTcGFjZUNvbmZpZywgR2VuaWVTcGFjZXNDb25maWcgfSBmcm9tIFwiLi9zcmMvZ2VuaWUudHNcIjtcbmV4cG9ydCB0eXBlIHsgTG9hZEhpc3RvcnlPcHRpb25zLCBDbGVhckhpc3RvcnlPcHRpb25zLCBIaXN0b3J5Um91dGVPcHRpb25zIH0gZnJvbSBcIi4vc3JjL2hpc3RvcnkudHNcIjtcbmV4cG9ydCB7IElERU5USVRZX0VOViwgSURFTlRJVFlfTU9ERVMsIERFRkFVTFRfSURFTlRJVFlfTU9ERSwgVVNFUl9JRF9IRUFERVIsIFVTRVJfRU1BSUxfSEVBREVSIH0gZnJvbSBcIi4vc3JjL2lkZW50aXR5LnRzXCI7XG5leHBvcnQgdHlwZSB7IE1hc3RyYUlkZW50aXR5TW9kZSB9IGZyb20gXCIuL3NyYy9pZGVudGl0eS50c1wiO1xuZXhwb3J0IHR5cGUgeyBSZXNvbHZlZE1jcCB9IGZyb20gXCIuL3NyYy9tY3AudHNcIjtcbmV4cG9ydCB7IE1lbW9yeUJ1aWxkZXIgfSBmcm9tIFwiLi9zcmMvbWVtb3J5LnRzXCI7XG5leHBvcnQgdHlwZSB7IExvZ0ZlZWRiYWNrUGFyYW1zIH0gZnJvbSBcIi4vc3JjL21sZmxvdy50c1wiO1xuZXhwb3J0IHR5cGUgeyBCdWlsZE1vZGVsT3ZlcnJpZGVzIH0gZnJvbSBcIi4vc3JjL21vZGVsLnRzXCI7XG5leHBvcnQgdHlwZSB7IEJ1aWxkT2JzZXJ2YWJpbGl0eU9wdGlvbnMgfSBmcm9tIFwiLi9zcmMvb2JzZXJ2YWJpbGl0eS50c1wiO1xuZXhwb3J0IHR5cGUgeyBQZXJQYWdlQm91bmRzIH0gZnJvbSBcIi4vc3JjL3BhZ2luYXRpb24udHNcIjtcbmV4cG9ydCB7IE1hc3RyYVBsdWdpbiwgbWFzdHJhIH0gZnJvbSBcIi4vc3JjL3BsdWdpbi50c1wiO1xuZXhwb3J0IHsgc3RyaXBTdGFsZUNoYXJ0c1Byb2Nlc3NvciwgUmVzdWx0UHJvY2Vzc29yIH0gZnJvbSBcIi4vc3JjL3Byb2Nlc3NvcnMudHNcIjtcbmV4cG9ydCB7IEFJVE9PTFNfU09VUkNFIH0gZnJvbSBcIi4vc3JjL3JlbW90ZS1za2lsbHMudHNcIjtcbmV4cG9ydCB0eXBlIHsgQWlUb29sc1NvdXJjZSwgUmVtb3RlU2tpbGxTb3VyY2VPcHRpb25zLCBSZW1vdGVTa2lsbFNvdXJjZSwgUmVtb3RlU2tpbGxzT3B0aW9uLCBQcm92aXNpb25SZW1vdGVTa2lsbHNPcHRpb25zLCBQcm92aXNpb25lZFJlbW90ZVNraWxscywgUmVtb3RlU2tpbGxDYWNoZUVudHJ5LCBSZW1vdGVTa2lsbHNNZXRhZGF0YSB9IGZyb20gXCIuL3NyYy9yZW1vdGUtc2tpbGxzLnRzXCI7XG5leHBvcnQgdHlwZSB7IERhdGFicmlja3NGZXRjaEluaXQgfSBmcm9tIFwiLi9zcmMvcmVzdC50c1wiO1xuZXhwb3J0IHsgTWFzdHJhU2VydmVyIH0gZnJvbSBcIi4vc3JjL3NlcnZlci50c1wiO1xuZXhwb3J0IHR5cGUgeyBBdHRyaWJ1dGVkSWRlbnRpdHksIE1hc3RyYUFwaUdhdGVPcHRpb25zIH0gZnJvbSBcIi4vc3JjL3NlcnZlci50c1wiO1xuZXhwb3J0IHsgTUFTVFJBX01PREVMX09WRVJSSURFX0tFWSB9IGZyb20gXCIuL3NyYy9zZXJ2aW5nLnRzXCI7XG5leHBvcnQgdHlwZSB7IE1vZGVsT3ZlcnJpZGVSZXF1ZXN0IH0gZnJvbSBcIi4vc3JjL3NlcnZpbmcudHNcIjtcbmV4cG9ydCB0eXBlIHsgU2VydmluZ0NoYXRNZXNzYWdlIH0gZnJvbSBcIi4vc3JjL3NlcnZpbmctc2FuaXRpemUudHNcIjtcbmV4cG9ydCB7IFNUQVRFTUVOVF9ST1dfQ0FQIH0gZnJvbSBcIi4vc3JjL3N0YXRlbWVudC50c1wiO1xuZXhwb3J0IHsgVElUTEVfSU5TVFJVQ1RJT05TIH0gZnJvbSBcIi4vc3JjL3N1bW1hcml6ZS50c1wiO1xuZXhwb3J0IHR5cGUgeyBTdW1tYXJpemVPcHRpb25zIH0gZnJvbSBcIi4vc3JjL3N1bW1hcml6ZS50c1wiO1xuZXhwb3J0IHR5cGUgeyBMaXN0VGhyZWFkc09wdGlvbnMsIERlbGV0ZVRocmVhZE9wdGlvbnMsIFJlbmFtZVRocmVhZE9wdGlvbnMsIFRocmVhZHNSb3V0ZU9wdGlvbnMgfSBmcm9tIFwiLi9zcmMvdGhyZWFkcy50c1wiO1xuZXhwb3J0IHR5cGUgeyBTY2hlbWFJc3N1ZXMgfSBmcm9tIFwiLi9zcmMvdmFsaWRhdGlvbi50c1wiO1xuZXhwb3J0IHR5cGUgeyBDcmVhdGVXb3Jrc3BhY2VPcHRpb25zIH0gZnJvbSBcIi4vc3JjL3dvcmtzcGFjZXMudHNcIjtcbiJdfQ==
@@ -26,6 +26,15 @@
26
26
  * source (or the top-level call) sets `failOnError: false`, in which case it is
27
27
  * logged and skipped so one bad source never takes the app down.
28
28
  *
29
+ * Every provisioned tree carries a {@link METADATA_FILE} recording when each
30
+ * source was last downloaded, and a source is only re-downloaded once that
31
+ * record is older than {@link DEFAULT_REFRESH_TTL_MS} (a day). This runs at app
32
+ * BOOT, so without it a container that restarts a dozen times an hour re-pulls
33
+ * the whole AI Tools set a dozen times for content that changes rarely. The
34
+ * record travels WITH the tree rather than in process memory, so the reuse
35
+ * survives a restart - which is the only way it helps a Databricks App at all.
36
+ * Pass `refreshTtlMs: 0` to download on every boot.
37
+ *
29
38
  * The default destination is the Databricks workspace Assistant skills tree
30
39
  * (`/Workspace/.assistant/skills`, the same tree a "save this as a skill"
31
40
  * action writes to), so provisioned skills persist across restarts and are
@@ -67,6 +76,13 @@ export interface RemoteSkillSourceOptions {
67
76
  ref?: string;
68
77
  /** Override the byte ceiling on a direct-fetch download for this source. */
69
78
  maxDownloadBytes?: number;
79
+ /**
80
+ * How long this source's provisioned tree is reused before it is downloaded
81
+ * again, in milliseconds. Overrides the top-level
82
+ * {@link ProvisionRemoteSkillsOptions.refreshTtlMs}; `0` re-downloads on
83
+ * every boot.
84
+ */
85
+ refreshTtlMs?: number;
70
86
  /**
71
87
  * When `false`, a source that fails to resolve is logged and skipped instead
72
88
  * of failing app startup. Overrides the top-level {@link ProvisionRemoteSkillsOptions.failOnError}.
@@ -104,6 +120,12 @@ export interface ProvisionRemoteSkillsOptions {
104
120
  userEmail?: string;
105
121
  /** Byte ceiling on a direct-fetch download. Defaults to 10 MiB. */
106
122
  maxDownloadBytes?: number;
123
+ /**
124
+ * How long a provisioned tree is reused before its source is downloaded
125
+ * again, in milliseconds. Defaults to a day; `0` re-downloads on every boot.
126
+ * A per-source `refreshTtlMs` wins over this.
127
+ */
128
+ refreshTtlMs?: number;
107
129
  }
108
130
  /** What {@link provisionRemoteSkills} resolved. */
109
131
  export interface ProvisionedRemoteSkills {
@@ -115,9 +137,39 @@ export interface ProvisionedRemoteSkills {
115
137
  localSkillPaths: string[];
116
138
  /** Absolute Databricks destination each source was written to, if any. */
117
139
  databricksBasePath?: string;
118
- /** Names of every skill directory that was provisioned. */
140
+ /**
141
+ * Names of every skill directory now available, whether it was downloaded on
142
+ * this boot or reused from a still-fresh tree (see {@link METADATA_FILE}).
143
+ */
119
144
  skillNames: string[];
120
145
  }
146
+ /**
147
+ * What one source's last download left behind, as recorded in
148
+ * {@link METADATA_FILE}.
149
+ */
150
+ export interface RemoteSkillCacheEntry {
151
+ /** The source string this entry was downloaded from, for readability. */
152
+ source: string;
153
+ /** When the download completed, ISO-8601. */
154
+ downloadedAt: string;
155
+ /** Skill directory names the download produced. */
156
+ skills: string[];
157
+ /**
158
+ * The content-affecting policy that download used. Also folded into the entry
159
+ * KEY, so narrowing `skills` or moving `ref` misses the cache instead of
160
+ * silently serving the previous selection.
161
+ */
162
+ policy?: {
163
+ skills?: string[];
164
+ experimental?: boolean;
165
+ ref?: string;
166
+ };
167
+ }
168
+ /** The {@link METADATA_FILE} document: one entry per provisioned source. */
169
+ export interface RemoteSkillsMetadata {
170
+ version: number;
171
+ sources: Record<string, RemoteSkillCacheEntry>;
172
+ }
121
173
  /** Normalize the `remoteSkills` option into a flat options bag. */
122
174
  export declare function normalizeRemoteSkillsOption(option: RemoteSkillsOption | undefined): ProvisionRemoteSkillsOptions | undefined;
123
175
  /**
@@ -26,6 +26,15 @@
26
26
  * source (or the top-level call) sets `failOnError: false`, in which case it is
27
27
  * logged and skipped so one bad source never takes the app down.
28
28
  *
29
+ * Every provisioned tree carries a {@link METADATA_FILE} recording when each
30
+ * source was last downloaded, and a source is only re-downloaded once that
31
+ * record is older than {@link DEFAULT_REFRESH_TTL_MS} (a day). This runs at app
32
+ * BOOT, so without it a container that restarts a dozen times an hour re-pulls
33
+ * the whole AI Tools set a dozen times for content that changes rarely. The
34
+ * record travels WITH the tree rather than in process memory, so the reuse
35
+ * survives a restart - which is the only way it helps a Databricks App at all.
36
+ * Pass `refreshTtlMs: 0` to download on every boot.
37
+ *
29
38
  * The default destination is the Databricks workspace Assistant skills tree
30
39
  * (`/Workspace/.assistant/skills`, the same tree a "save this as a skill"
31
40
  * action writes to), so provisioned skills persist across restarts and are
@@ -53,14 +62,33 @@ const ASSISTANT_SHARED_SKILLS_PATH = "/Workspace/.assistant/skills";
53
62
  function userAssistantSkillsPath(userEmail) {
54
63
  return `/Users/${userEmail.trim()}/.assistant/skills`;
55
64
  }
56
- /** npm agent id the `skills` CLI installs a bare `SKILL.md` tree under. */
57
- const SKILLS_CLI_AGENT = "agents";
65
+ /**
66
+ * Agent id the `skills` CLI installs a bare `SKILL.md` tree under.
67
+ *
68
+ * `universal` is the CLI's own name for "no particular agent, just the plain
69
+ * tree", which is what this module wants - it re-hosts the result itself. The
70
+ * id must be one the installed CLI knows: an unrecognized one is rejected
71
+ * outright (`Invalid agents: ...`), taking every non-`aitools` source down with
72
+ * it, since a CLI failure is a hard failure rather than a fall-through to
73
+ * {@link stageViaFetch}.
74
+ */
75
+ const SKILLS_CLI_AGENT = "universal";
58
76
  /** Where the `skills` CLI drops a plain `SKILL.md` tree under a target dir. */
59
77
  const SKILLS_CLI_LAYOUT = [".agents", "skills"];
60
78
  /** Cap on a direct-fetch download body, matching the `skills` CLI default. */
61
79
  const DEFAULT_MAX_DOWNLOAD_BYTES = 10 * 1024 * 1024;
62
80
  /** Stable temp directory holding one rebuilt skill tree per remote source. */
63
81
  const LOCAL_SKILLS_DIR = "mastra-local-skills";
82
+ /**
83
+ * Bookkeeping file written at the root of every provisioned skill tree, naming
84
+ * when each source was last downloaded. A dotfile so the skill scanners, which
85
+ * look for `<dir>/SKILL.md`, never mistake it for a skill.
86
+ */
87
+ const METADATA_FILE = ".metadata.json";
88
+ /** Shape marker for {@link METADATA_FILE}; an unknown version is ignored, not read. */
89
+ const METADATA_VERSION = 1;
90
+ /** How long a provisioned source is reused before being downloaded again. */
91
+ const DEFAULT_REFRESH_TTL_MS = 24 * 60 * 60 * 1000;
64
92
  /* ------------------------------ AI Tools ------------------------------ */
65
93
  /**
66
94
  * Source constant selecting Databricks' own AI Tools skill set.
@@ -119,6 +147,95 @@ function toSourceString(source) {
119
147
  function isAiToolsSource(source) {
120
148
  return source.trim().toLowerCase() === AITOOLS_SOURCE;
121
149
  }
150
+ /* -------------------------------- cache -------------------------------- */
151
+ /**
152
+ * The policy that decides what a source's download CONTAINS.
153
+ *
154
+ * Only these three change the resulting tree, so only these belong in the cache
155
+ * key - `failOnError` and `maxDownloadBytes` govern how a failure is handled,
156
+ * not what a success produces.
157
+ */
158
+ function cachePolicy(sourceOptions) {
159
+ const skills = string.parseList(sourceOptions.skills);
160
+ const policy = {
161
+ ...(skills.length > 0 ? { skills: [...skills].sort() } : {}),
162
+ ...(sourceOptions.experimental === true ? { experimental: true } : {}),
163
+ ...(string.trimToNull(sourceOptions.ref) ? { ref: sourceOptions.ref.trim() } : {}),
164
+ };
165
+ return Object.keys(policy).length > 0 ? policy : undefined;
166
+ }
167
+ /**
168
+ * Stable identity of a source AND its content-affecting policy.
169
+ *
170
+ * Keying on the source alone would let a changed `skills` filter or `ref` read
171
+ * back the previous download for a day; keying on both turns that into a miss.
172
+ * The skill list is sorted first so a reordered array is still the same key.
173
+ */
174
+ function cacheKey(sourceOptions) {
175
+ return hash.fnvHash(JSON.stringify({ source: sourceOptions.source, policy: cachePolicy(sourceOptions) ?? null }));
176
+ }
177
+ /** The effective reuse window: per-source, then top-level, then a day. */
178
+ function resolveRefreshTtl(sourceOptions, options) {
179
+ return sourceOptions.refreshTtlMs ?? options.refreshTtlMs ?? DEFAULT_REFRESH_TTL_MS;
180
+ }
181
+ /**
182
+ * Read the metadata document at the root of a provisioned tree, or `undefined`
183
+ * when there is none, it is unreadable, or it was written by a shape this
184
+ * version does not know.
185
+ *
186
+ * Never throws: a missing or corrupt record is a cache MISS, which costs a
187
+ * download - while letting it fail would take app startup down over
188
+ * bookkeeping.
189
+ */
190
+ async function readMetadata(fs) {
191
+ try {
192
+ if (!(await fs.exists(METADATA_FILE)))
193
+ return undefined;
194
+ const raw = await fs.readFile(METADATA_FILE, { encoding: "utf8" });
195
+ const parsed = json.parse(raw, undefined);
196
+ if (!object.isRecord(parsed) || parsed.version !== METADATA_VERSION)
197
+ return undefined;
198
+ return object.isRecord(parsed.sources) ? parsed : undefined;
199
+ }
200
+ catch (err) {
201
+ logger.debug("cache:unreadable", { error: error.errorMessage(err) });
202
+ return undefined;
203
+ }
204
+ }
205
+ /**
206
+ * Whether an entry is still inside its reuse window.
207
+ *
208
+ * A `ttlMs` of `0` disables reuse outright, and an unparseable or FUTURE
209
+ * timestamp counts as stale - a clock that moved backwards should cost one
210
+ * extra download, not pin a tree as fresh indefinitely.
211
+ */
212
+ function isFresh(entry, ttlMs) {
213
+ if (ttlMs <= 0 || !Array.isArray(entry.skills))
214
+ return false;
215
+ const downloadedAt = Date.parse(entry.downloadedAt ?? "");
216
+ if (Number.isNaN(downloadedAt))
217
+ return false;
218
+ const age = Date.now() - downloadedAt;
219
+ return age >= 0 && age < ttlMs;
220
+ }
221
+ /**
222
+ * Merge one source's entry into the tree's metadata document, preserving what
223
+ * other sources recorded - the Databricks destination is SHARED, so a blind
224
+ * overwrite would drop every sibling source's timestamp and re-download the
225
+ * lot on the next boot.
226
+ */
227
+ async function writeMetadata(fs, key, entry) {
228
+ const current = await readMetadata(fs);
229
+ const next = {
230
+ version: METADATA_VERSION,
231
+ sources: { ...current?.sources, [key]: entry },
232
+ };
233
+ await fs.writeFile(METADATA_FILE, `${JSON.stringify(next, null, 2)}\n`, { overwrite: true });
234
+ }
235
+ /** The stable local tree a source is rebuilt into, keyed by {@link cacheKey}. */
236
+ function localSkillsFS(key) {
237
+ return localFS.tmpFS(`${LOCAL_SKILLS_DIR}/${key}`);
238
+ }
122
239
  /**
123
240
  * Materialize every configured remote skill source at app startup.
124
241
  *
@@ -145,31 +262,60 @@ export async function provisionRemoteSkills(option) {
145
262
  const localSkillPaths = [];
146
263
  const skillNames = [];
147
264
  let staging;
265
+ // The destination roots the shared metadata document, so it has to exist
266
+ // before the first cache READ - `copySkillDirs` would otherwise be the first
267
+ // thing to create it, which is too late.
268
+ if (destination)
269
+ await destination.init();
148
270
  try {
149
271
  const sources = Array.isArray(options.sources) ? options.sources : [options.sources];
150
272
  for (const entry of sources) {
151
273
  const sourceOptions = toSourceOptions(entry);
152
274
  const failOnError = sourceOptions.failOnError ?? failDefault;
153
275
  try {
276
+ // Where this source's bookkeeping lives: the shared Databricks tree, or
277
+ // the source's own stable local dir.
278
+ const key = cacheKey(sourceOptions);
279
+ const cacheFS = destination ?? localSkillsFS(key);
280
+ const cached = (await readMetadata(cacheFS))?.sources[key];
281
+ if (cached && isFresh(cached, resolveRefreshTtl(sourceOptions, options))) {
282
+ skillNames.push(...cached.skills);
283
+ if (!destination)
284
+ localSkillPaths.push(cacheFS.root);
285
+ logger.debug("source:cached", {
286
+ source: sourceOptions.source,
287
+ downloadedAt: cached.downloadedAt,
288
+ skills: cached.skills,
289
+ });
290
+ continue;
291
+ }
154
292
  staging ??= await initializedScratch("mastra-remote-skills");
155
293
  const stagedDir = await stageSource(sourceOptions, staging.root, options);
156
294
  const staged = await collectSkillDirs(stagedDir);
157
295
  if (staged.length === 0) {
158
296
  throw new Error(`no SKILL.md found for source "${sourceOptions.source}"`);
159
297
  }
298
+ const policy = cachePolicy(sourceOptions);
299
+ const record = {
300
+ source: sourceOptions.source,
301
+ downloadedAt: new Date().toISOString(),
302
+ skills: staged.map((dir) => dir.name),
303
+ ...(policy ? { policy } : {}),
304
+ };
160
305
  if (destination && databricksBasePath) {
161
306
  await copySkillDirs(destination, staged);
162
- skillNames.push(...staged.map((dir) => dir.name));
307
+ // Only after the copy lands: a metadata entry written first would
308
+ // mark a failed provision as fresh and suppress the retry for a day.
309
+ await writeMetadata(destination, key, record);
163
310
  }
164
311
  else {
165
- const localDir = await persistLocally(sourceOptions.source, staged);
166
- localSkillPaths.push(localDir);
167
- skillNames.push(...staged.map((dir) => dir.name));
312
+ localSkillPaths.push(await persistLocally(key, staged, record));
168
313
  }
314
+ skillNames.push(...record.skills);
169
315
  logger.debug("source:provisioned", {
170
316
  source: sourceOptions.source,
171
317
  destination: databricksBasePath ?? "local-temp",
172
- skills: staged.map((dir) => dir.name),
318
+ skills: record.skills,
173
319
  });
174
320
  }
175
321
  catch (err) {
@@ -394,12 +540,21 @@ async function copySkillDirs(destination, dirs) {
394
540
  * return its root path.
395
541
  *
396
542
  * A given source resolves to the same content on almost every boot, so each
397
- * one owns a directory named for its {@link hash.fnvHash} rather than leaving
398
- * a fresh scratch dir behind per restart. Keying on the source (not the
399
- * content) is what keeps two different sources from overwriting each other.
543
+ * one owns a directory named for its {@link cacheKey} rather than leaving a
544
+ * fresh scratch dir behind per restart. Keying on the source and its policy
545
+ * (not the content) is what keeps two different sources from overwriting each
546
+ * other.
547
+ *
548
+ * The metadata is written INSIDE the rebuild rather than after it: `rebuildFS`
549
+ * replaces the stable root wholesale, so anything written afterwards would
550
+ * survive only until the next refresh, and anything written before would be
551
+ * thrown away by the swap.
400
552
  */
401
- async function persistLocally(source, dirs) {
402
- const stable = await localFS.rebuildFS(`${LOCAL_SKILLS_DIR}/${hash.fnvHash(source)}`, (scratch) => copySkillDirs(scratch, dirs));
553
+ async function persistLocally(key, dirs, record) {
554
+ const stable = await localFS.rebuildFS(`${LOCAL_SKILLS_DIR}/${key}`, async (scratch) => {
555
+ await copySkillDirs(scratch, dirs);
556
+ await writeMetadata(scratch, key, record);
557
+ });
403
558
  return stable.root;
404
559
  }
405
560
  /**
@@ -422,4 +577,4 @@ async function pathExists(path) {
422
577
  return false;
423
578
  }
424
579
  }
425
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVtb3RlLXNraWxscy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yZW1vdGUtc2tpbGxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXNDRztBQUVILE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2pGLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDNUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRWpELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUUzQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDdkMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDN0QsT0FBTyxFQUFFLE9BQU8sRUFBd0IsTUFBTSxlQUFlLENBQUM7QUFDOUQsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUlyRixNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLHNCQUFzQixDQUFDLENBQUM7QUFFbEQsaUZBQWlGO0FBQ2pGLE1BQU0sNEJBQTRCLEdBQUcsOEJBQThCLENBQUM7QUFFcEUsaUVBQWlFO0FBQ2pFLFNBQVMsdUJBQXVCLENBQUMsU0FBaUI7SUFDaEQsT0FBTyxVQUFVLFNBQVMsQ0FBQyxJQUFJLEVBQUUsb0JBQW9CLENBQUM7QUFDeEQsQ0FBQztBQUVELDJFQUEyRTtB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QUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDdEUsQ0FBQztJQUNILENBQUM7QUFDSCxDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxLQUFLLFVBQVUsY0FBYyxDQUFDLE1BQWMsRUFBRSxJQUFzQjtJQUNsRSxNQUFNLE1BQU0sR0FBRyxNQUFNLE9BQU8sQ0FBQyxTQUFTLENBQUMsR0FBRyxnQkFBZ0IsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUNoRyxhQUFhLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUM3QixDQUFDO0lBQ0YsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDO0FBQ3JCLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsS0FBSyxVQUFVLGtCQUFrQixDQUFDLE1BQWM7SUFDOUMsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMxQyxNQUFNLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNyQixPQUFPLE9BQU8sQ0FBQztBQUNqQixDQUFDO0FBRUQsbUNBQW1DO0FBQ25DLEtBQUssVUFBVSxVQUFVLENBQUMsSUFBWTtJQUNwQyxJQUFJLENBQUM7UUFDSCxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBTdGFydHVwIHByb3Zpc2lvbmluZyBvZiByZW1vdGUgQWdlbnQtU2tpbGwgc291cmNlcyBmb3IgYSBNYXN0cmEgd29ya3NwYWNlLlxuICpcbiAqIEEge0BsaW5rIFJlbW90ZVNraWxsU291cmNlfSBuYW1lcyBXSEVSRSBhIGBTS0lMTC5tZGAgdHJlZSBjb21lcyBmcm9tIC0gdGhlXG4gKiB7QGxpbmsgQUlUT09MU19TT1VSQ0V9IGNvbnN0YW50LCBhIEdpdEh1YiBgb3duZXIvcmVwb2AsIGFueSBnaXQgLyBHaXRMYWIgVVJMLFxuICogb3IgYSBkaXJlY3QgZG93bmxvYWQgVVJMIC0gYW5kIG9wdGlvbmFsIHBlci1zb3VyY2UgcG9saWN5LlxuICoge0BsaW5rIHByb3Zpc2lvblJlbW90ZVNraWxsc30gbWF0ZXJpYWxpemVzIGV2ZXJ5IHNvdXJjZSBpbnRvIGEgbG9jYWxcbiAqIGBTS0lMTC5tZGAgdHJlZSBhdCBhcHAgYm9vdCBhbmQgcmV0dXJucyB0aGUgZGlyZWN0b3JpZXMgdG8gaGFuZCBNYXN0cmEgYXNcbiAqIGV4dHJhIHNraWxsIHNjYW4gcGF0aHMuXG4gKlxuICogUmVzb2x1dGlvbiBwZXIgc291cmNlLCBpbiBvcmRlcjpcbiAqXG4gKiAxLiB0aGUge0BsaW5rIEFJVE9PTFNfU09VUkNFfSBjb25zdGFudCAoYFwiYWl0b29sc1wiYCk6IERhdGFicmlja3MnIG93biBza2lsbFxuICogICAgc2V0LCByZWFkIHN0cmFpZ2h0IGZyb20gdGhlIHB1YmxpYyByZXBvIHRoZSBgZGF0YWJyaWNrcyBhaXRvb2xzYCBDTElcbiAqICAgIHNvdXJjZXMgZnJvbS4gTm8gQ0xJLCBubyBEYXRhYnJpY2tzIGF1dGggLSB3aGljaCBpcyB3aGF0IG1ha2VzIGl0IHVzYWJsZVxuICogICAgaW5zaWRlIGEgRGF0YWJyaWNrcyBBcHAgY29udGFpbmVyLCB3aGVyZSB0aGUgQ0xJIGlzIG5vdCBpbnN0YWxsZWQ7XG4gKiAyLiB0aGUgT1BUSU9OQUwgYHNraWxsc2AgbnBtIENMSSAocGVlciBkZXApOiBpZiBpbnN0YWxsZWQsIGVhY2ggc291cmNlIGlzXG4gKiAgICBjb3BpZWQgaW50byBhIHN0YWdpbmcgZGlyIHdpdGggYHNraWxscyBhZGQgPHNvdXJjZT4gLS1hZ2VudCA8ZGlyPiAtLWNvcHlgLFxuICogICAgd2hpY2ggdW5kZXJzdGFuZHMgZXZlcnkgc291cmNlIGZvcm1hdCB0aGUgZWNvc3lzdGVtIGRvZXMgKEdpdEh1YlxuICogICAgc2hvcnRoYW5kLCBnaXQgVVJMcywgYXJjaGl2ZS9kb3dubG9hZCBVUkxzKTtcbiAqIDMuIG90aGVyd2lzZSBhIHBsYWluIHtAbGluayBmZXRjaH0gb2YgdGhlIHNvdXJjZSBVUkwgKGJ1aWx0IHdpdGhcbiAqICAgIHtAbGluayBuZXQudXJsQnVpbGRlcn0pLCB3cml0aW5nIHRoZSBkb3dubG9hZGVkIGBTS0lMTC5tZGAgdG8gYSBzdGFnaW5nXG4gKiAgICBkaXIuXG4gKlxuICogQSBzb3VyY2UgdGhhdCByZXNvbHZlcyB0aHJvdWdoIG5laXRoZXIgcGF0aCBmYWlscyBhcHAgc3RhcnR1cCwgdW5sZXNzIHRoZVxuICogc291cmNlIChvciB0aGUgdG9wLWxldmVsIGNhbGwpIHNldHMgYGZhaWxPbkVycm9yOiBmYWxzZWAsIGluIHdoaWNoIGNhc2UgaXQgaXNcbiAqIGxvZ2dlZCBhbmQgc2tpcHBlZCBzbyBvbmUgYmFkIHNvdXJjZSBuZXZlciB0YWtlcyB0aGUgYXBwIGRvd24uXG4gKlxuICogVGhlIGRlZmF1bHQgZGVzdGluYXRpb24gaXMgdGhlIERhdGFicmlja3Mgd29ya3NwYWNlIEFzc2lzdGFudCBza2lsbHMgdHJlZVxuICogKGAvV29ya3NwYWNlLy5hc3Npc3RhbnQvc2tpbGxzYCwgdGhlIHNhbWUgdHJlZSBhIFwic2F2ZSB0aGlzIGFzIGEgc2tpbGxcIlxuICogYWN0aW9uIHdyaXRlcyB0byksIHNvIHByb3Zpc2lvbmVkIHNraWxscyBwZXJzaXN0IGFjcm9zcyByZXN0YXJ0cyBhbmQgYXJlXG4gKiBkaXNjb3ZlcmVkIGJ5IHRoZSBidWlsdC1pbiBBc3Npc3RhbnQtc2tpbGxzIG1vdW50LiBQYXNzIGB1c2VyRW1haWxgIChvciBhblxuICogZXhwbGljaXQgYGRhdGFicmlja3NCYXNlUGF0aGApIHRvIHRhcmdldCBgL1VzZXJzLzxlbWFpbD4vLmFzc2lzdGFudC9za2lsbHNgXG4gKiBpbnN0ZWFkLiBXaGVuIG5vIERhdGFicmlja3MgY2xpZW50IGlzIHJlc29sdmFibGUgYXQgc3RhcnR1cCwgdGhlIHRyZWUgaXNcbiAqIHdyaXR0ZW4gdW5kZXIge0BsaW5rIGxvY2FsRlMudG1wRlN9IGFuZCByZXR1cm5lZCBhcyBhbiBleHRyYSBsb2NhbCBza2lsbCBwYXRoXG4gKiBmb3IgdGhlIGN1cnJlbnQgcHJvY2Vzcy5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgbWtkaXIsIHJlYWRkaXIsIHJlYWRGaWxlLCBybSwgc3RhdCwgd3JpdGVGaWxlIH0gZnJvbSBcIm5vZGU6ZnMvcHJvbWlzZXNcIjtcbmltcG9ydCB7IGNyZWF0ZVJlcXVpcmUgfSBmcm9tIFwibm9kZTptb2R1bGVcIjtcbmltcG9ydCB7IGRpcm5hbWUsIGpvaW4sIHBvc2l4IH0gZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHR5cGUgeyBXb3Jrc3BhY2VDbGllbnQgfSBmcm9tIFwiQGRhdGFicmlja3Mvc2RrLWV4cGVyaW1lbnRhbFwiO1xuaW1wb3J0IHsgYXBwa2l0IH0gZnJvbSBcIkBkYngtdG9vbHMvYXBwa2l0XCI7XG5pbXBvcnQgdHlwZSB7IFdvcmtzcGFjZUNsaWVudExpa2UgfSBmcm9tIFwiQGRieC10b29scy9hcHBraXRcIjtcbmltcG9ydCB7IGV4ZWMgfSBmcm9tIFwiQGRieC10b29scy9jb3JlXCI7XG5pbXBvcnQgeyBEYXRhYnJpY2tzRmlsZVN5c3RlbSB9IGZyb20gXCJAZGJ4LXRvb2xzL2RhdGFicmlja3NcIjtcbmltcG9ydCB7IGxvY2FsRlMsIHR5cGUgTG9jYWxGaWxlU3lzdGVtIH0gZnJvbSBcIkBkYngtdG9vbHMvZnNcIjtcbmltcG9ydCB7IGZpbmQgfSBmcm9tIFwiQGRieC10b29scy9wYXRoXCI7XG5pbXBvcnQgeyBlcnJvciwgaGFzaCwganNvbiwgbG9nLCBuZXQsIG9iamVjdCwgc3RyaW5nIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB0eXBlIHsgT25lT3JNYW55IH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB0eXBlIHsgRmlsZVN5c3RlbSB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1mc1wiO1xuXG5jb25zdCBsb2dnZXIgPSBsb2cubG9nZ2VyKFwibWFzdHJhL3JlbW90ZS1za2lsbHNcIik7XG5cbi8qKiBTaGFyZWQgQXNzaXN0YW50IHNraWxscyB0cmVlIGluIHRoZSBEYXRhYnJpY2tzIHdvcmtzcGFjZSAoZGVmYXVsdCB0YXJnZXQpLiAqL1xuY29uc3QgQVNTSVNUQU5UX1NIQVJFRF9TS0lMTFNfUEFUSCA9IFwiL1dvcmtzcGFjZS8uYXNzaXN0YW50L3NraWxsc1wiO1xuXG4vKiogQXNzaXN0YW50IHNraWxscyBkaXJlY3RvcnkgZm9yIGEgc3BlY2lmaWMgRGF0YWJyaWNrcyB1c2VyLiAqL1xuZnVuY3Rpb24gdXNlckFzc2lzdGFudFNraWxsc1BhdGgodXNlckVtYWlsOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYC9Vc2Vycy8ke3VzZXJFbWFpbC50cmltKCl9Ly5hc3Npc3RhbnQvc2tpbGxzYDtcbn1cblxuLyoqIG5wbSBhZ2VudCBpZCB0aGUgYHNraWxsc2AgQ0xJIGluc3RhbGxzIGEgYmFyZSBgU0tJTEwubWRgIHRyZWUgdW5kZXIuICovXG5jb25zdCBTS0lMTFNfQ0xJX0FHRU5UID0gXCJhZ2VudHNcIjtcblxuLyoqIFdoZXJlIHRoZSBgc2tpbGxzYCBDTEkgZHJvcHMgYSBwbGFpbiBgU0tJTEwubWRgIHRyZWUgdW5kZXIgYSB0YXJnZXQgZGlyLiAqL1xuY29uc3QgU0tJTExTX0NMSV9MQVlPVVQgPSBbXCIuYWdlbnRzXCIsIFwic2tpbGxzXCJdIGFzIGNvbnN0O1xuXG4vKiogQ2FwIG9uIGEgZGlyZWN0LWZldGNoIGRvd25sb2FkIGJvZHksIG1hdGNoaW5nIHRoZSBgc2tpbGxzYCBDTEkgZGVmYXVsdC4gKi9cbmNvbnN0IERFRkFVTFRfTUFYX0RPV05MT0FEX0JZVEVTID0gMTAgKiAxMDI0ICogMTAyNDtcblxuLyoqIFN0YWJsZSB0ZW1wIGRpcmVjdG9yeSBob2xkaW5nIG9uZSByZWJ1aWx0IHNraWxsIHRyZWUgcGVyIHJlbW90ZSBzb3VyY2UuICovXG5jb25zdCBMT0NBTF9TS0lMTFNfRElSID0gXCJtYXN0cmEtbG9jYWwtc2tpbGxzXCI7XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBBSSBUb29scyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuLyoqXG4gKiBTb3VyY2UgY29uc3RhbnQgc2VsZWN0aW5nIERhdGFicmlja3MnIG93biBBSSBUb29scyBza2lsbCBzZXQuXG4gKlxuICogQGV4YW1wbGVcbiAqIG1hc3RyYSh7IHJlbW90ZVNraWxsczogXCJhaXRvb2xzXCIgfSk7XG4gKi9cbmV4cG9ydCBjb25zdCBBSVRPT0xTX1NPVVJDRSA9IFwiYWl0b29sc1wiO1xuXG4vKiogVGhlIHtAbGluayBBSVRPT0xTX1NPVVJDRX0gbGl0ZXJhbCwgZm9yIGNhbGxlcnMgc3BlbGxpbmcgdGhlIHVuaW9uIG91dC4gKi9cbmV4cG9ydCB0eXBlIEFpVG9vbHNTb3VyY2UgPSB0eXBlb2YgQUlUT09MU19TT1VSQ0U7XG5cbi8qKlxuICogVGhlIFBVQkxJQyByZXBvIGBkYXRhYnJpY2tzIGFpdG9vbHMgaW5zdGFsbGAgc291cmNlcyBmcm9tLiBSZWFkaW5nIGl0XG4gKiBkaXJlY3RseSBpcyB3aGF0IGxldHMgYW4gYXBwIGdldCB0aGUgc2FtZSBza2lsbHMgdGhlIENMSSBpbnN0YWxscyB3aXRob3V0XG4gKiB0aGUgQ0xJIC0gd2hpY2ggYSBEYXRhYnJpY2tzIEFwcCBjb250YWluZXIgZG9lcyBub3Qgc2hpcC5cbiAqL1xuY29uc3QgQUlUT09MU19SRVBPID0gXCJkYXRhYnJpY2tzL2RhdGFicmlja3MtYWdlbnQtc2tpbGxzXCI7XG5cbi8qKiBSZXBvIHJlZiB0aGUgc2tpbGxzIGFyZSByZWFkIGZyb20uIE92ZXJyaWRlIHBlciBzb3VyY2Ugd2l0aCBgcmVmYC4gKi9cbmNvbnN0IEFJVE9PTFNfUkVGID0gXCJtYWluXCI7XG5cbi8qKiBTa2lsbCBmaWxlcyBkb3dubG9hZGVkIGF0IG9uY2U7IHRoZSBzZXQgaXMgfjMwIHNraWxscyBvZiBhIGZldyBmaWxlcyBlYWNoLiAqL1xuY29uc3QgQUlUT09MU19DT05DVVJSRU5DWSA9IDg7XG5cbi8qKiBUaGUgc3Vic2V0IG9mIHRoZSByZXBvJ3MgZ2VuZXJhdGVkIGBtYW5pZmVzdC5qc29uYCB0aGlzIG1vZHVsZSByZWFkcy4gKi9cbmludGVyZmFjZSBBaVRvb2xzTWFuaWZlc3Qge1xuICBza2lsbHM/OiBSZWNvcmQ8c3RyaW5nLCB7IGZpbGVzPzogc3RyaW5nW107IHJlcG9fZGlyPzogc3RyaW5nIH0+O1xufVxuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4vKipcbiAqIE9uZSByZW1vdGUgc2tpbGwgc291cmNlIGFuZCBpdHMgcGVyLXNvdXJjZSBwb2xpY3kuXG4gKlxuICogYHNvdXJjZWAgaXMge0BsaW5rIEFJVE9PTFNfU09VUkNFfSBvciBhbnl0aGluZyB0aGUgYHNraWxsc2AgZWNvc3lzdGVtXG4gKiB1bmRlcnN0YW5kczogYSBHaXRIdWIgYG93bmVyL3JlcG9gIHNob3J0aGFuZCwgYSBmdWxsIEdpdEh1YiAvIEdpdExhYiAvIGdpdFxuICogVVJMLCBvciBhIGRpcmVjdCBkb3dubG9hZCBVUkwgdG8gYSBgU0tJTEwubWRgIG9yIGFyY2hpdmUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVtb3RlU2tpbGxTb3VyY2VPcHRpb25zIHtcbiAgLyoqIGBcImFpdG9vbHNcImAsIGEgR2l0SHViIHNob3J0aGFuZCwgYSBnaXQgLyBHaXRMYWIgVVJMLCBvciBhIGRvd25sb2FkIFVSTC4gKi9cbiAgc291cmNlOiBuZXQuVXJsTGlrZSB8IEFpVG9vbHNTb3VyY2U7XG4gIC8qKiBJbnN0YWxsIG9ubHkgdGhlc2Ugc2tpbGwgbmFtZXMgZnJvbSB0aGUgc291cmNlLiAqL1xuICBza2lsbHM/OiBzdHJpbmcgfCBzdHJpbmdbXTtcbiAgLyoqIEluY2x1ZGUgZXhwZXJpbWVudGFsIHNraWxscy4gYFwiYWl0b29sc1wiYCBvbmx5LiAqL1xuICBleHBlcmltZW50YWw/OiBib29sZWFuO1xuICAvKiogUGluIHRoZSByZXBvIHJlZiAodGFnIC8gYnJhbmNoIC8gc2hhKS4gYFwiYWl0b29sc1wiYCBvbmx5OyBkZWZhdWx0cyB0byBgbWFpbmAuICovXG4gIHJlZj86IHN0cmluZztcbiAgLyoqIE92ZXJyaWRlIHRoZSBieXRlIGNlaWxpbmcgb24gYSBkaXJlY3QtZmV0Y2ggZG93bmxvYWQgZm9yIHRoaXMgc291cmNlLiAqL1xuICBtYXhEb3dubG9hZEJ5dGVzPzogbnVtYmVyO1xuICAvKipcbiAgICogV2hlbiBgZmFsc2VgLCBhIHNvdXJjZSB0aGF0IGZhaWxzIHRvIHJlc29sdmUgaXMgbG9nZ2VkIGFuZCBza2lwcGVkIGluc3RlYWRcbiAgICogb2YgZmFpbGluZyBhcHAgc3RhcnR1cC4gT3ZlcnJpZGVzIHRoZSB0b3AtbGV2ZWwge0BsaW5rIFByb3Zpc2lvblJlbW90ZVNraWxsc09wdGlvbnMuZmFpbE9uRXJyb3J9LlxuICAgKi9cbiAgZmFpbE9uRXJyb3I/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIEEgcmVtb3RlIHNraWxsIHNvdXJjZTogdGhlIHtAbGluayBBSVRPT0xTX1NPVVJDRX0gY29uc3RhbnQsIGEgVVJMLWxpa2VcbiAqIChzdHJpbmcgLyBgVVJMYCAvIGB7IHVybCB9YCksIG9yIGEge0BsaW5rIFJlbW90ZVNraWxsU291cmNlT3B0aW9uc30gYmFnIHdpdGhcbiAqIHBlci1zb3VyY2UgcG9saWN5LlxuICovXG5leHBvcnQgdHlwZSBSZW1vdGVTa2lsbFNvdXJjZSA9IG5ldC5VcmxMaWtlIHwgQWlUb29sc1NvdXJjZSB8IFJlbW90ZVNraWxsU291cmNlT3B0aW9ucztcblxuLyoqXG4gKiBUaGUgd29ya3NwYWNlIGByZW1vdGVTa2lsbHNgIG9wdGlvbjogb25lIHNvdXJjZSwgYSBub24tZW1wdHkgbGlzdCBvZiB0aGVtLCBvclxuICogYSB7QGxpbmsgUHJvdmlzaW9uUmVtb3RlU2tpbGxzT3B0aW9uc30gYmFnIHdoZW4gdG9wLWxldmVsIHBvbGljeSBpcyBuZWVkZWQuXG4gKi9cbmV4cG9ydCB0eXBlIFJlbW90ZVNraWxsc09wdGlvbiA9XG4gIFJlbW90ZVNraWxsU291cmNlIHwgT25lT3JNYW55PFJlbW90ZVNraWxsU291cmNlPiB8IFByb3Zpc2lvblJlbW90ZVNraWxsc09wdGlvbnM7XG5cbi8qKiBBIHNvdXJjZSBlbnRyeSB3aXRoIGl0cyBgc291cmNlYCBmbGF0dGVuZWQgdG8gYSBwbGFpbiBzdHJpbmcuICovXG50eXBlIE5vcm1hbGl6ZWRTb3VyY2UgPSBPbWl0PFJlbW90ZVNraWxsU291cmNlT3B0aW9ucywgXCJzb3VyY2VcIj4gJiB7IHNvdXJjZTogc3RyaW5nIH07XG5cbi8qKiBUb3AtbGV2ZWwgcmVtb3RlLXNraWxscyBwcm92aXNpb25pbmcgb3B0aW9ucy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHJvdmlzaW9uUmVtb3RlU2tpbGxzT3B0aW9ucyB7XG4gIC8qKiBTb3VyY2VzIHRvIG1hdGVyaWFsaXplIGF0IHN0YXJ0dXAuICovXG4gIHNvdXJjZXM6IFJlbW90ZVNraWxsU291cmNlIHwgT25lT3JNYW55PFJlbW90ZVNraWxsU291cmNlPjtcbiAgLyoqXG4gICAqIEZhaWwgYXBwIHN0YXJ0dXAgd2hlbiBhIHNvdXJjZSBjYW4ndCBiZSByZXNvbHZlZC4gRGVmYXVsdHMgdG8gYHRydWVgLiBBXG4gICAqIHBlci1zb3VyY2UgYGZhaWxPbkVycm9yYCB3aW5zIG92ZXIgdGhpcy5cbiAgICovXG4gIGZhaWxPbkVycm9yPzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIEFic29sdXRlIERhdGFicmlja3MgcGF0aCB0aGF0IHJvb3RzIHRoZSBkZXN0aW5hdGlvbiBBc3Npc3RhbnQgc2tpbGxzIHRyZWUuXG4gICAqIERlZmF1bHRzIHRvIHRoZSBPQk8gdXNlcidzIGAvVXNlcnMvPGVtYWlsPi8uYXNzaXN0YW50L3NraWxsc2AuXG4gICAqL1xuICBkYXRhYnJpY2tzQmFzZVBhdGg/OiBzdHJpbmc7XG4gIC8qKiBBdXRoLXNjb3BlZCBEYXRhYnJpY2tzIGNsaWVudC4gRGVmYXVsdHMgdG8gdGhlIEFwcEtpdCBleGVjdXRpb24gY29udGV4dC4gKi9cbiAgY2xpZW50PzogV29ya3NwYWNlQ2xpZW50TGlrZTtcbiAgLyoqIFVzZXIgZW1haWwgdXNlZCB0byBkZXJpdmUgdGhlIGRlZmF1bHQgRGF0YWJyaWNrcyBkZXN0aW5hdGlvbi4gKi9cbiAgdXNlckVtYWlsPzogc3RyaW5nO1xuICAvKiogQnl0ZSBjZWlsaW5nIG9uIGEgZGlyZWN0LWZldGNoIGRvd25sb2FkLiBEZWZhdWx0cyB0byAxMCBNaUIuICovXG4gIG1heERvd25sb2FkQnl0ZXM/OiBudW1iZXI7XG59XG5cbi8qKiBXaGF0IHtAbGluayBwcm92aXNpb25SZW1vdGVTa2lsbHN9IHJlc29sdmVkLiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcm92aXNpb25lZFJlbW90ZVNraWxscyB7XG4gIC8qKlxuICAgKiBFeHRyYSBMT0NBTCBza2lsbCBzY2FuIHBhdGhzIHRvIGhhbmQgTWFzdHJhIChhIHRlbXAgZGlyIHBlciBzb3VyY2UgdGhhdFxuICAgKiBjb3VsZG4ndCBiZSB3cml0dGVuIHRvIERhdGFicmlja3MpLiBFbXB0eSB3aGVuIGV2ZXJ5dGhpbmcgbGFuZGVkIGluIHRoZVxuICAgKiBEYXRhYnJpY2tzIEFzc2lzdGFudCB0cmVlLCB3aGljaCB0aGUgYnVpbHQtaW4gbW91bnQgYWxyZWFkeSBzY2Fucy5cbiAgICovXG4gIGxvY2FsU2tpbGxQYXRoczogc3RyaW5nW107XG4gIC8qKiBBYnNvbHV0ZSBEYXRhYnJpY2tzIGRlc3RpbmF0aW9uIGVhY2ggc291cmNlIHdhcyB3cml0dGVuIHRvLCBpZiBhbnkuICovXG4gIGRhdGFicmlja3NCYXNlUGF0aD86IHN0cmluZztcbiAgLyoqIE5hbWVzIG9mIGV2ZXJ5IHNraWxsIGRpcmVjdG9yeSB0aGF0IHdhcyBwcm92aXNpb25lZC4gKi9cbiAgc2tpbGxOYW1lczogc3RyaW5nW107XG59XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gaGVscGVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbi8qKiBOb3JtYWxpemUgdGhlIGByZW1vdGVTa2lsbHNgIG9wdGlvbiBpbnRvIGEgZmxhdCBvcHRpb25zIGJhZy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVSZW1vdGVTa2lsbHNPcHRpb24oXG4gIG9wdGlvbjogUmVtb3RlU2tpbGxzT3B0aW9uIHwgdW5kZWZpbmVkLFxuKTogUHJvdmlzaW9uUmVtb3RlU2tpbGxzT3B0aW9ucyB8IHVuZGVmaW5lZCB7XG4gIGlmIChvcHRpb24gPT09IHVuZGVmaW5lZCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3QgYmFnID0gaXNQcm92aXNpb25PcHRpb25zKG9wdGlvbikgPyBvcHRpb24gOiB1bmRlZmluZWQ7XG4gIGNvbnN0IHNvdXJjZXMgPSB0b1NvdXJjZUxpc3QoYmFnID8gYmFnLnNvdXJjZXMgOiAob3B0aW9uIGFzIFJlbW90ZVNraWxsU291cmNlKSk7XG4gIC8vIEFuIGVtcHR5IGxpc3QgaXMgdGhlIHNhbWUgYXMgbm8gY29uZmlndXJhdGlvbiBhdCBhbGwuXG4gIGlmICghb2JqZWN0LmlzT25lT3JNYW55KHNvdXJjZXMpKSByZXR1cm4gdW5kZWZpbmVkO1xuICByZXR1cm4geyAuLi5iYWcsIHNvdXJjZXMgfTtcbn1cblxuLyoqIEEgYHNvdXJjZXNgLWJlYXJpbmcgYmFnIGlzIHRoZSB0b3AtbGV2ZWwgb3B0aW9ucyBzaGFwZSwgbm90IGEgc2luZ2xlIHNvdXJjZS4gKi9cbmZ1bmN0aW9uIGlzUHJvdmlzaW9uT3B0aW9ucyh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFByb3Zpc2lvblJlbW90ZVNraWxsc09wdGlvbnMge1xuICByZXR1cm4gb2JqZWN0LmlzUmVjb3JkKHZhbHVlKSAmJiBcInNvdXJjZXNcIiBpbiB2YWx1ZTtcbn1cblxuLyoqIE9uZSBzb3VyY2Ugb3IgbWFueSwgYXMgYSBwbGFpbiBhcnJheS4gQSBzb3VyY2UgaXMgbmV2ZXIgaXRzZWxmIGFuIGFycmF5LiAqL1xuZnVuY3Rpb24gdG9Tb3VyY2VMaXN0KFxuICBpbnB1dDogUmVtb3RlU2tpbGxTb3VyY2UgfCBPbmVPck1hbnk8UmVtb3RlU2tpbGxTb3VyY2U+LFxuKTogUmVtb3RlU2tpbGxTb3VyY2VbXSB7XG4gIHJldHVybiBBcnJheS5pc0FycmF5KGlucHV0KSA/IFsuLi5pbnB1dF0gOiBbaW5wdXRdO1xufVxuXG4vKiogRmxhdHRlbiBhIHNvdXJjZSBlbnRyeSAtIHN0cmluZywgYFVSTGAsIGB7IHVybCB9YCwgb3Igb3B0aW9ucyBiYWcgLSB0byBhIHtAbGluayBOb3JtYWxpemVkU291cmNlfS4gKi9cbmZ1bmN0aW9uIHRvU291cmNlT3B0aW9ucyhzb3VyY2U6IFJlbW90ZVNraWxsU291cmNlKTogTm9ybWFsaXplZFNvdXJjZSB7XG4gIGlmICh0eXBlb2Ygc291cmNlID09PSBcInN0cmluZ1wiKSByZXR1cm4geyBzb3VyY2UgfTtcbiAgaWYgKHNvdXJjZSBpbnN0YW5jZW9mIFVSTCkgcmV0dXJuIHsgc291cmNlOiBzb3VyY2UudG9TdHJpbmcoKSB9O1xuICBpZiAoXCJzb3VyY2VcIiBpbiBzb3VyY2UpIHJldHVybiB7IC4uLnNvdXJjZSwgc291cmNlOiB0b1NvdXJjZVN0cmluZyhzb3VyY2Uuc291cmNlKSB9O1xuICByZXR1cm4geyBzb3VyY2U6IHNvdXJjZS51cmwgfTtcbn1cblxuLyoqIEEge0BsaW5rIG5ldC5VcmxMaWtlfSBhcyB0aGUgcGxhaW4gc3RyaW5nIHRoZSBzdGFnaW5nIHBhdGhzIHdvcmsgd2l0aC4gKi9cbmZ1bmN0aW9uIHRvU291cmNlU3RyaW5nKHNvdXJjZTogbmV0LlVybExpa2UpOiBzdHJpbmcge1xuICBpZiAodHlwZW9mIHNvdXJjZSA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIHNvdXJjZTtcbiAgcmV0dXJuIHNvdXJjZSBpbnN0YW5jZW9mIFVSTCA/IHNvdXJjZS50b1N0cmluZygpIDogc291cmNlLnVybDtcbn1cblxuLyoqIFRydWUgd2hlbiBhIHNvdXJjZSBzZWxlY3RzIHRoZSBidWlsdC1pbiBEYXRhYnJpY2tzIEFJIFRvb2xzIHNraWxsIHNldC4gKi9cbmZ1bmN0aW9uIGlzQWlUb29sc1NvdXJjZShzb3VyY2U6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gc291cmNlLnRyaW0oKS50b0xvd2VyQ2FzZSgpID09PSBBSVRPT0xTX1NPVVJDRTtcbn1cblxuLyoqXG4gKiBNYXRlcmlhbGl6ZSBldmVyeSBjb25maWd1cmVkIHJlbW90ZSBza2lsbCBzb3VyY2UgYXQgYXBwIHN0YXJ0dXAuXG4gKlxuICogV3JpdGVzIGVhY2ggcmVzb2x2ZWQgYFNLSUxMLm1kYCB0cmVlIHRvIHRoZSBEYXRhYnJpY2tzIHVzZXIgQXNzaXN0YW50IHNraWxsc1xuICogZm9sZGVyIHdoZW4gYSB3cml0YWJsZSB3b3Jrc3BhY2UgaXMgYXZhaWxhYmxlLCBlbHNlIHVuZGVyXG4gKiB7QGxpbmsgbG9jYWxGUy50bXBGU30gcmV0dXJuZWQgaW4ge0BsaW5rIFByb3Zpc2lvbmVkUmVtb3RlU2tpbGxzLmxvY2FsU2tpbGxQYXRoc30uXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwcm92aXNpb25SZW1vdGVTa2lsbHMoXG4gIG9wdGlvbjogUmVtb3RlU2tpbGxzT3B0aW9uIHwgdW5kZWZpbmVkLFxuKTogUHJvbWlzZTxQcm92aXNpb25lZFJlbW90ZVNraWxscz4ge1xuICBjb25zdCBvcHRpb25zID0gbm9ybWFsaXplUmVtb3RlU2tpbGxzT3B0aW9uKG9wdGlvbik7XG4gIGNvbnN0IGVtcHR5OiBQcm92aXNpb25lZFJlbW90ZVNraWxscyA9IHsgbG9jYWxTa2lsbFBhdGhzOiBbXSwgc2tpbGxOYW1lczogW10gfTtcbiAgaWYgKCFvcHRpb25zKSByZXR1cm4gZW1wdHk7XG5cbiAgY29uc3QgZmFpbERlZmF1bHQgPSBvcHRpb25zLmZhaWxPbkVycm9yICE9PSBmYWxzZTtcbiAgY29uc3QgY2xpZW50ID0gb3B0aW9ucy5jbGllbnQgPz8gYXBwa2l0LnRyeUdldEV4ZWN1dGlvbkNvbnRleHQoKT8uY2xpZW50O1xuICBjb25zdCBkYXRhYnJpY2tzQmFzZVBhdGggPSByZXNvbHZlRGF0YWJyaWNrc0Jhc2VQYXRoKG9wdGlvbnMsIGNsaWVudCk7XG4gIGNvbnN0IGRlc3RpbmF0aW9uID0gZGF0YWJyaWNrc0Jhc2VQYXRoXG4gICAgPyBuZXcgRGF0YWJyaWNrc0ZpbGVTeXN0ZW0oe1xuICAgICAgICBjbGllbnQ6IGNsaWVudCBhcyBXb3Jrc3BhY2VDbGllbnQsXG4gICAgICAgIHJvb3Q6IGRhdGFicmlja3NCYXNlUGF0aCxcbiAgICAgICAgcmVhZE9ubHk6IGZhbHNlLFxuICAgICAgICBjcmVhdGVSb290OiB0cnVlLFxuICAgICAgfSlcbiAgICA6IHVuZGVmaW5lZDtcblxuICBjb25zdCBsb2NhbFNraWxsUGF0aHM6IHN0cmluZ1tdID0gW107XG4gIGNvbnN0IHNraWxsTmFtZXM6IHN0cmluZ1tdID0gW107XG4gIGxldCBzdGFnaW5nOiBMb2NhbEZpbGVTeXN0ZW0gfCB1bmRlZmluZWQ7XG5cbiAgdHJ5IHtcbiAgICBjb25zdCBzb3VyY2VzID0gQXJyYXkuaXNBcnJheShvcHRpb25zLnNvdXJjZXMpID8gb3B0aW9ucy5zb3VyY2VzIDogW29wdGlvbnMuc291cmNlc107XG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiBzb3VyY2VzKSB7XG4gICAgICBjb25zdCBzb3VyY2VPcHRpb25zID0gdG9Tb3VyY2VPcHRpb25zKGVudHJ5KTtcbiAgICAgIGNvbnN0IGZhaWxPbkVycm9yID0gc291cmNlT3B0aW9ucy5mYWlsT25FcnJvciA/PyBmYWlsRGVmYXVsdDtcbiAgICAgIHRyeSB7XG4gICAgICAgIHN0YWdpbmcgPz89IGF3YWl0IGluaXRpYWxpemVkU2NyYXRjaChcIm1hc3RyYS1yZW1vdGUtc2tpbGxzXCIpO1xuICAgICAgICBjb25zdCBzdGFnZWREaXIgPSBhd2FpdCBzdGFnZVNvdXJjZShzb3VyY2VPcHRpb25zLCBzdGFnaW5nLnJvb3QsIG9wdGlvbnMpO1xuICAgICAgICBjb25zdCBzdGFnZWQgPSBhd2FpdCBjb2xsZWN0U2tpbGxEaXJzKHN0YWdlZERpcik7XG4gICAgICAgIGlmIChzdGFnZWQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBubyBTS0lMTC5tZCBmb3VuZCBmb3Igc291cmNlIFwiJHtzb3VyY2VPcHRpb25zLnNvdXJjZX1cImApO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkZXN0aW5hdGlvbiAmJiBkYXRhYnJpY2tzQmFzZVBhdGgpIHtcbiAgICAgICAgICBhd2FpdCBjb3B5U2tpbGxEaXJzKGRlc3RpbmF0aW9uLCBzdGFnZWQpO1xuICAgICAgICAgIHNraWxsTmFtZXMucHVzaCguLi5zdGFnZWQubWFwKChkaXIpID0+IGRpci5uYW1lKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgbG9jYWxEaXIgPSBhd2FpdCBwZXJzaXN0TG9jYWxseShzb3VyY2VPcHRpb25zLnNvdXJjZSwgc3RhZ2VkKTtcbiAgICAgICAgICBsb2NhbFNraWxsUGF0aHMucHVzaChsb2NhbERpcik7XG4gICAgICAgICAgc2tpbGxOYW1lcy5wdXNoKC4uLnN0YWdlZC5tYXAoKGRpcikgPT4gZGlyLm5hbWUpKTtcbiAgICAgICAgfVxuICAgICAgICBsb2dnZXIuZGVidWcoXCJzb3VyY2U6cHJvdmlzaW9uZWRcIiwge1xuICAgICAgICAgIHNvdXJjZTogc291cmNlT3B0aW9ucy5zb3VyY2UsXG4gICAgICAgICAgZGVzdGluYXRpb246IGRhdGFicmlja3NCYXNlUGF0aCA/PyBcImxvY2FsLXRlbXBcIixcbiAgICAgICAgICBza2lsbHM6IHN0YWdlZC5tYXAoKGRpcikgPT4gZGlyLm5hbWUpLFxuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBpZiAoZmFpbE9uRXJyb3IpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICBgZmFpbGVkIHRvIHByb3Zpc2lvbiByZW1vdGUgc2tpbGwgc291cmNlIFwiJHtzb3VyY2VPcHRpb25zLnNvdXJjZX1cIjogJHtlcnJvci5lcnJvck1lc3NhZ2UoZXJyKX1gLFxuICAgICAgICAgICAgeyBjYXVzZTogZXJyb3IudG9FcnJvcihlcnIpIH0sXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBsb2dnZXIud2FybihcInNvdXJjZTpza2lwcGVkXCIsIHtcbiAgICAgICAgICBzb3VyY2U6IHNvdXJjZU9wdGlvbnMuc291cmNlLFxuICAgICAgICAgIGVycm9yOiBlcnJvci5lcnJvck1lc3NhZ2UoZXJyKSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9IGZpbmFsbHkge1xuICAgIGlmIChzdGFnaW5nKSB7XG4gICAgICBhd2FpdCBybShzdGFnaW5nLnJvb3QsIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KS5jYXRjaCgoKSA9PiB1bmRlZmluZWQpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7IGxvY2FsU2tpbGxQYXRocywgZGF0YWJyaWNrc0Jhc2VQYXRoLCBza2lsbE5hbWVzIH07XG59XG5cbi8qKiBSZXNvbHZlIHRoZSBEYXRhYnJpY2tzIEFzc2lzdGFudCBza2lsbHMgZGVzdGluYXRpb24sIG9yIGB1bmRlZmluZWRgIGZvciBsb2NhbCB0ZW1wLiAqL1xuZnVuY3Rpb24gcmVzb2x2ZURhdGFicmlja3NCYXNlUGF0aChcbiAgb3B0aW9uczogUHJvdmlzaW9uUmVtb3RlU2tpbGxzT3B0aW9ucyxcbiAgY2xpZW50OiBXb3Jrc3BhY2VDbGllbnRMaWtlIHwgdW5kZWZpbmVkLFxuKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgaWYgKCFjbGllbnQpIHJldHVybiB1bmRlZmluZWQ7XG4gIGlmIChvcHRpb25zLmRhdGFicmlja3NCYXNlUGF0aCkgcmV0dXJuIG9wdGlvbnMuZGF0YWJyaWNrc0Jhc2VQYXRoLnRyaW0oKSB8fCB1bmRlZmluZWQ7XG4gIGNvbnN0IGVtYWlsID0gc3RyaW5nLnRyaW1Ub051bGwob3B0aW9ucy51c2VyRW1haWwpO1xuICAvLyBBIG5hbWVkIHVzZXIgdGFyZ2V0cyB0aGVpciBwZXJzb25hbCBBc3Npc3RhbnQgdHJlZSAodGhlIFwic2F2ZSBhIHNraWxsXCJcbiAgLy8gdGFyZ2V0KTsgb3RoZXJ3aXNlIHRoZSBzaGFyZWQgd29ya3NwYWNlIEFzc2lzdGFudCB0cmVlLCB3aGljaCB0aGUgYnVpbHQtaW5cbiAgLy8gQXNzaXN0YW50LXNraWxscyBtb3VudCBhbHJlYWR5IHNjYW5zLlxuICByZXR1cm4gZW1haWwgPyB1c2VyQXNzaXN0YW50U2tpbGxzUGF0aChlbWFpbCkgOiBBU1NJU1RBTlRfU0hBUkVEX1NLSUxMU19QQVRIO1xufVxuXG4vKipcbiAqIFN0YWdlIG9uZSBzb3VyY2UgaW50byBhIGZyZXNoIGRpciB1bmRlciBgc3RhZ2luZ1Jvb3RgLCBwcmVmZXJyaW5nIHRoZSBvcHRpb25hbFxuICogYHNraWxsc2AgQ0xJIGFuZCBmYWxsaW5nIGJhY2sgdG8gYSBkaXJlY3QgZmV0Y2guXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHN0YWdlU291cmNlKFxuICBzb3VyY2VPcHRpb25zOiBOb3JtYWxpemVkU291cmNlLFxuICBzdGFnaW5nUm9vdDogc3RyaW5nLFxuICBvcHRpb25zOiBQcm92aXNpb25SZW1vdGVTa2lsbHNPcHRpb25zLFxuKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc3QgdGFyZ2V0ID0gam9pbihzdGFnaW5nUm9vdCwgYHNyYy0ke2hhc2guaWQoKX1gKTtcbiAgYXdhaXQgbWtkaXIodGFyZ2V0LCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgLy8gQUkgVG9vbHMgcmVzb2x2ZXMgZnJvbSBhIGtub3duIHJlcG8gbGF5b3V0LCBzbyBpdCBuZXZlciBuZWVkcyB0aGUgQ0xJLlxuICBpZiAoaXNBaVRvb2xzU291cmNlKHNvdXJjZU9wdGlvbnMuc291cmNlKSkgcmV0dXJuIHN0YWdlQWlUb29scyhzb3VyY2VPcHRpb25zLCB0YXJnZXQsIG9wdGlvbnMpO1xuICBjb25zdCB2aWFDbGkgPSBhd2FpdCBzdGFnZVZpYVNraWxsc0NsaShzb3VyY2VPcHRpb25zLCB0YXJnZXQpO1xuICBpZiAodmlhQ2xpKSByZXR1cm4gdmlhQ2xpO1xuICByZXR1cm4gc3RhZ2VWaWFGZXRjaChzb3VyY2VPcHRpb25zLCB0YXJnZXQsIG9wdGlvbnMpO1xufVxuXG4vKipcbiAqIE1hdGVyaWFsaXplIHRoZSBEYXRhYnJpY2tzIEFJIFRvb2xzIHNraWxscyBpbnRvIGB0YXJnZXRgLlxuICpcbiAqIFJlYWRzIHRoZSByZXBvJ3Mgb3duIGdlbmVyYXRlZCBgbWFuaWZlc3QuanNvbmAgKHdoaWNoIG5hbWVzIGVhY2ggc2tpbGwnc1xuICogZmlsZXMgYW5kIHdoZXRoZXIgaXQgbGl2ZXMgdW5kZXIgYHNraWxscy9gIG9yIGBleHBlcmltZW50YWwvYCkgYW5kIGRvd25sb2Fkc1xuICogdGhlbSAtIHRoZSBzYW1lIHRoaW5nIGBkYXRhYnJpY2tzIGFpdG9vbHMgaW5zdGFsbGAgZG9lcywgbWludXMgdGhlIENMSSBhbmRcbiAqIG1pbnVzIGFueSBEYXRhYnJpY2tzIGF1dGgsIHNpbmNlIHRoZSByZXBvIGlzIHB1YmxpYy5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gc3RhZ2VBaVRvb2xzKFxuICBzb3VyY2VPcHRpb25zOiBOb3JtYWxpemVkU291cmNlLFxuICB0YXJnZXQ6IHN0cmluZyxcbiAgb3B0aW9uczogUHJvdmlzaW9uUmVtb3RlU2tpbGxzT3B0aW9ucyxcbik6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IG1heEJ5dGVzID0gcmVzb2x2ZU1heEJ5dGVzKHNvdXJjZU9wdGlvbnMsIG9wdGlvbnMpO1xuICBjb25zdCByZWYgPSBzdHJpbmcudHJpbVRvTnVsbChzb3VyY2VPcHRpb25zLnJlZikgPz8gQUlUT09MU19SRUY7XG4gIGNvbnN0IG1hbmlmZXN0ID0ganNvbi5wYXJzZShcbiAgICAoYXdhaXQgZG93bmxvYWQoYWlUb29sc1Jhd1VybChyZWYsIFwibWFuaWZlc3QuanNvblwiKSwgbWF4Qnl0ZXMpKS50b1N0cmluZyhcInV0ZjhcIiksXG4gICAgdW5kZWZpbmVkLFxuICApIGFzIEFpVG9vbHNNYW5pZmVzdCB8IHVuZGVmaW5lZDtcblxuICBjb25zdCB3YW50ZWQgPSBuZXcgU2V0KHN0cmluZy5wYXJzZUxpc3Qoc291cmNlT3B0aW9ucy5za2lsbHMpKTtcbiAgY29uc3Qgc2VsZWN0ZWQgPSBPYmplY3QuZW50cmllcyhtYW5pZmVzdD8uc2tpbGxzID8/IHt9KS5maWx0ZXIoKFtuYW1lLCBlbnRyeV0pID0+XG4gICAgd2FudGVkLnNpemUgPiAwXG4gICAgICA/IHdhbnRlZC5oYXMobmFtZSlcbiAgICAgIDogZW50cnkucmVwb19kaXIgIT09IFwiZXhwZXJpbWVudGFsXCIgfHwgc291cmNlT3B0aW9ucy5leHBlcmltZW50YWwgPT09IHRydWUsXG4gICk7XG4gIGlmIChzZWxlY3RlZC5sZW5ndGggPT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYG5vIG1hdGNoaW5nIHNraWxscyBpbiAke0FJVE9PTFNfUkVQT31AJHtyZWZ9YCk7XG4gIH1cblxuICBjb25zdCBmaWxlcyA9IHNlbGVjdGVkLmZsYXRNYXAoKFtuYW1lLCBlbnRyeV0pID0+XG4gICAgKGVudHJ5LmZpbGVzID8/IFtdKS5tYXAoKGZpbGUpID0+ICh7XG4gICAgICB1cmw6IGFpVG9vbHNSYXdVcmwocmVmLCBgJHtlbnRyeS5yZXBvX2RpciA/PyBcInNraWxsc1wifS8ke25hbWV9LyR7ZmlsZX1gKSxcbiAgICAgIHBhdGg6IGpvaW4odGFyZ2V0LCBuYW1lLCAuLi5maWxlLnNwbGl0KFwiL1wiKSksXG4gICAgfSkpLFxuICApO1xuICBhd2FpdCBtYXBDb25jdXJyZW50KGZpbGVzLCBBSVRPT0xTX0NPTkNVUlJFTkNZLCBhc3luYyAoaXRlbSkgPT4ge1xuICAgIGNvbnN0IGJvZHkgPSBhd2FpdCBkb3dubG9hZChpdGVtLnVybCwgbWF4Qnl0ZXMpO1xuICAgIGF3YWl0IG1rZGlyKGRpcm5hbWUoaXRlbS5wYXRoKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgYXdhaXQgd3JpdGVGaWxlKGl0ZW0ucGF0aCwgYm9keSk7XG4gIH0pO1xuXG4gIGxvZ2dlci5kZWJ1ZyhcImFpdG9vbHM6c3RhZ2VkXCIsIHsgcmVmLCBza2lsbHM6IHNlbGVjdGVkLmxlbmd0aCwgZmlsZXM6IGZpbGVzLmxlbmd0aCB9KTtcbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuLyoqIFJhdy1jb250ZW50IFVSTCBmb3IgYSBwYXRoIGluIHRoZSBBSSBUb29scyByZXBvIGF0IGByZWZgLiAqL1xuZnVuY3Rpb24gYWlUb29sc1Jhd1VybChyZWY6IHN0cmluZywgcGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGBodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vJHtBSVRPT0xTX1JFUE99LyR7cmVmfS8ke3BhdGh9YDtcbn1cblxuLyoqIFJ1biBgd29ya2VyYCBvdmVyIGBpdGVtc2AsIGF0IG1vc3QgYGxpbWl0YCBpbiBmbGlnaHQuICovXG5hc3luYyBmdW5jdGlvbiBtYXBDb25jdXJyZW50PFQ+KFxuICBpdGVtczogcmVhZG9ubHkgVFtdLFxuICBsaW1pdDogbnVtYmVyLFxuICB3b3JrZXI6IChpdGVtOiBUKSA9PiBQcm9taXNlPHZvaWQ+LFxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGxldCBjdXJzb3IgPSAwO1xuICBjb25zdCBydW5uZXJzID0gQXJyYXkuZnJvbSh7IGxlbmd0aDogTWF0aC5taW4obGltaXQsIGl0ZW1zLmxlbmd0aCkgfSwgYXN5bmMgKCkgPT4ge1xuICAgIHdoaWxlIChjdXJzb3IgPCBpdGVtcy5sZW5ndGgpIHtcbiAgICAgIGF3YWl0IHdvcmtlcihpdGVtc1tjdXJzb3IrK10hKTtcbiAgICB9XG4gIH0pO1xuICBhd2FpdCBQcm9taXNlLmFsbChydW5uZXJzKTtcbn1cblxuLyoqXG4gKiBDb3B5IGEgc291cmNlIGludG8gYHRhcmdldGAgd2l0aCB0aGUgYHNraWxsc2AgQ0xJIHdoZW4gaXQgaXMgaW5zdGFsbGVkLlxuICogUmV0dXJucyB0aGUgZGlyIGhvbGRpbmcgdGhlIGNvcGllZCBgU0tJTEwubWRgIHRyZWVzLCBvciBgdW5kZWZpbmVkYCB3aGVuIHRoZVxuICogQ0xJIGlzIGFic2VudCAoc28gdGhlIGNhbGxlciBjYW4gZmFsbCBiYWNrIHRvIGEgZmV0Y2gpLlxuICovXG5hc3luYyBmdW5jdGlvbiBzdGFnZVZpYVNraWxsc0NsaShcbiAgc291cmNlT3B0aW9uczogTm9ybWFsaXplZFNvdXJjZSxcbiAgdGFyZ2V0OiBzdHJpbmcsXG4pOiBQcm9taXNlPHN0cmluZyB8IHVuZGVmaW5lZD4ge1xuICBjb25zdCBjbGkgPSBhd2FpdCByZXNvbHZlU2tpbGxzQ2xpKCk7XG4gIGlmICghY2xpKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gIGNvbnN0IGFyZ3MgPSBbXG4gICAgLi4uY2xpLmFyZ3MsXG4gICAgXCJhZGRcIixcbiAgICBzb3VyY2VPcHRpb25zLnNvdXJjZSxcbiAgICBcIi0tYWdlbnRcIixcbiAgICBTS0lMTFNfQ0xJX0FHRU5ULFxuICAgIFwiLS1jb3B5XCIsXG4gICAgXCIteVwiLFxuICBdO1xuICBmb3IgKGNvbnN0IHNraWxsIG9mIHN0cmluZy5wYXJzZUxpc3Qoc291cmNlT3B0aW9ucy5za2lsbHMpKSB7XG4gICAgYXJncy5wdXNoKFwiLS1za2lsbFwiLCBza2lsbCk7XG4gIH1cbiAgaWYgKHN0cmluZy5wYXJzZUxpc3Qoc291cmNlT3B0aW9ucy5za2lsbHMpLmxlbmd0aCA9PT0gMCkgYXJncy5wdXNoKFwiLS1za2lsbFwiLCBcIipcIik7XG5cbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZXhlYy5zcGF3bihjbGkuY29tbWFuZCwgYXJncywge1xuICAgIGN3ZDogdGFyZ2V0LFxuICAgIHN0ZG91dDogXCJjYXB0dXJlXCIsXG4gICAgc3RkZXJyOiBcImNhcHR1cmVcIixcbiAgICBjaGVjazogZmFsc2UsXG4gIH0pO1xuICBpZiAocmVzdWx0LmV4aXRDb2RlICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYHNraWxscyBDTEkgZmFpbGVkIChleGl0ICR7cmVzdWx0LmV4aXRDb2RlfSk6ICR7cmVzdWx0LnN0ZGVyciB8fCByZXN1bHQuc3Rkb3V0fWAsXG4gICAgKTtcbiAgfVxuICByZXR1cm4gam9pbih0YXJnZXQsIC4uLlNLSUxMU19DTElfTEFZT1VUKTtcbn1cblxuLyoqXG4gKiBMb2NhdGUgdGhlIG9wdGlvbmFsIGBza2lsbHNgIENMSSBiaW4sIHJlc29sdmVkIGZyb20gVEhJUyBwYWNrYWdlJ3MgbW9kdWxlXG4gKiBncmFwaC4gUmV0dXJucyBgdW5kZWZpbmVkYCB3aGVuIHRoZSBwZWVyIGRlcCBpc24ndCBpbnN0YWxsZWQsIHNvIHRoZSBjYWxsZXJcbiAqIGZhbGxzIGJhY2sgdG8gYSBkaXJlY3QgZmV0Y2guXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVTa2lsbHNDbGkoKTogUHJvbWlzZTx7IGNvbW1hbmQ6IHN0cmluZzsgYXJnczogc3RyaW5nW10gfSB8IHVuZGVmaW5lZD4ge1xuICB0cnkge1xuICAgIGNvbnN0IHJlcXVpcmUgPSBjcmVhdGVSZXF1aXJlKGltcG9ydC5tZXRhLnVybCk7XG4gICAgY29uc3QgcGtnUGF0aCA9IHJlcXVpcmUucmVzb2x2ZShcInNraWxscy9wYWNrYWdlLmpzb25cIik7XG4gICAgY29uc3QgYmluID0gam9pbihwa2dQYXRoLCBcIi4uXCIsIFwiYmluXCIsIFwiY2xpLm1qc1wiKTtcbiAgICBpZiAoYXdhaXQgcGF0aEV4aXN0cyhiaW4pKSByZXR1cm4geyBjb21tYW5kOiBwcm9jZXNzLmV4ZWNQYXRoLCBhcmdzOiBbYmluXSB9O1xuICB9IGNhdGNoIHtcbiAgICAvLyBwZWVyIGRlcCBhYnNlbnQgb3IgdW5yZXNvbHZhYmxlIC0gZmV0Y2ggZmFsbGJhY2sgaGFuZGxlcyBpdFxuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogRmV0Y2ggYSBzb3VyY2UgVVJMIGFuZCB3cml0ZSB0aGUgZG93bmxvYWRlZCBgU0tJTEwubWRgIHVuZGVyIGB0YXJnZXRgLlxuICogVXNlZCB3aGVuIHRoZSBgc2tpbGxzYCBDTEkgaXNuJ3QgaW5zdGFsbGVkOyBzdXBwb3J0cyBhIGRpcmVjdCBgU0tJTEwubWRgIFVSTC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gc3RhZ2VWaWFGZXRjaChcbiAgc291cmNlT3B0aW9uczogTm9ybWFsaXplZFNvdXJjZSxcbiAgdGFyZ2V0OiBzdHJpbmcsXG4gIG9wdGlvbnM6IFByb3Zpc2lvblJlbW90ZVNraWxsc09wdGlvbnMsXG4pOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCB1cmwgPSBuZXQudXJsQnVpbGRlcihzb3VyY2VPcHRpb25zLnNvdXJjZSk7XG4gIGlmICghdXJsKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYHNvdXJjZSBcIiR7c291cmNlT3B0aW9ucy5zb3VyY2V9XCIgaXMgbm90IGEgVVJMIGFuZCB0aGUgb3B0aW9uYWwgXCJza2lsbHNcIiBwYWNrYWdlIGlzIG5vdCBpbnN0YWxsZWRgLFxuICAgICk7XG4gIH1cbiAgY29uc3QgYnVmZmVyID0gYXdhaXQgZG93bmxvYWQodXJsLnRvU3RyaW5nKCksIHJlc29sdmVNYXhCeXRlcyhzb3VyY2VPcHRpb25zLCBvcHRpb25zKSk7XG4gIGNvbnN0IG5hbWUgPSBzdHJpbmcudG9TbHVnKGRlcml2ZVNraWxsTmFtZSh1cmwudG9TdHJpbmcoKSkpIHx8IFwicmVtb3RlLXNraWxsXCI7XG4gIGNvbnN0IHNraWxsRGlyID0gam9pbih0YXJnZXQsIG5hbWUpO1xuICBhd2FpdCBta2Rpcihza2lsbERpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gIGF3YWl0IHdyaXRlRmlsZShqb2luKHNraWxsRGlyLCBcIlNLSUxMLm1kXCIpLCBidWZmZXIpO1xuICByZXR1cm4gdGFyZ2V0O1xufVxuXG4vKiogVGhlIGVmZmVjdGl2ZSBkb3dubG9hZCBjZWlsaW5nOiBwZXItc291cmNlLCB0aGVuIHRvcC1sZXZlbCwgdGhlbiB0aGUgZGVmYXVsdC4gKi9cbmZ1bmN0aW9uIHJlc29sdmVNYXhCeXRlcyhcbiAgc291cmNlT3B0aW9uczogTm9ybWFsaXplZFNvdXJjZSxcbiAgb3B0aW9uczogUHJvdmlzaW9uUmVtb3RlU2tpbGxzT3B0aW9ucyxcbik6IG51bWJlciB7XG4gIHJldHVybiBzb3VyY2VPcHRpb25zLm1heERvd25sb2FkQnl0ZXMgPz8gb3B0aW9ucy5tYXhEb3dubG9hZEJ5dGVzID8/IERFRkFVTFRfTUFYX0RPV05MT0FEX0JZVEVTO1xufVxuXG4vKiogR0VUIGEgVVJMLCBmYWlsaW5nIGxvdWRseSBvbiBhIG5vbi0yeHggc3RhdHVzIG9yIGFuIG92ZXJzaXplZCBib2R5LiAqL1xuYXN5bmMgZnVuY3Rpb24gZG93bmxvYWQodXJsOiBzdHJpbmcsIG1heEJ5dGVzOiBudW1iZXIpOiBQcm9taXNlPEJ1ZmZlcj4ge1xuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHVybCk7XG4gIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGRvd25sb2FkIGZhaWxlZDogJHtyZXNwb25zZS5zdGF0dXN9ICR7cmVzcG9uc2Uuc3RhdHVzVGV4dH0gKCR7dXJsfSlgKTtcbiAgfVxuICBjb25zdCBidWZmZXIgPSBCdWZmZXIuZnJvbShhd2FpdCByZXNwb25zZS5hcnJheUJ1ZmZlcigpKTtcbiAgaWYgKGJ1ZmZlci5ieXRlTGVuZ3RoID4gbWF4Qnl0ZXMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGRvd25sb2FkIGV4Y2VlZHMgJHttYXhCeXRlc30gYnl0ZXMgKCR7dXJsfSlgKTtcbiAgfVxuICByZXR1cm4gYnVmZmVyO1xufVxuXG4vKiogRGVyaXZlIGEgc2tpbGwgZGlyZWN0b3J5IG5hbWUgZnJvbSBhIGRvd25sb2FkIFVSTCdzIGxhc3QgcGF0aCBzZWdtZW50LiAqL1xuZnVuY3Rpb24gZGVyaXZlU2tpbGxOYW1lKHVybFN0cmluZzogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgdXJsID0gbmV0LnVybEJ1aWxkZXIodXJsU3RyaW5nKTtcbiAgY29uc3QgbGFzdCA9IHVybD8ucGF0aG5hbWUuc3BsaXQoXCIvXCIpLmZpbHRlcihCb29sZWFuKS5wb3AoKSA/PyBcIlwiO1xuICByZXR1cm4gbGFzdC5yZXBsYWNlKC9cXC4obWR8emlwfHRhcnx0Z3p8Z3opJC9pLCBcIlwiKTtcbn1cblxuLyoqIEEgc2tpbGwgZGlyZWN0b3J5IChob2xkaW5nIGEgYFNLSUxMLm1kYCkgc3RhZ2VkIG9uIGxvY2FsIGRpc2suICovXG5pbnRlcmZhY2UgU3RhZ2VkU2tpbGxEaXIge1xuICBuYW1lOiBzdHJpbmc7XG4gIGFic29sdXRlUGF0aDogc3RyaW5nO1xufVxuXG4vKipcbiAqIENvbGxlY3QgZXZlcnkgc2tpbGwgZGlyZWN0b3J5IHVuZGVyIGByb290YDogYSBgcm9vdC9TS0lMTC5tZGAgKHJvb3QgSVMgdGhlXG4gKiBza2lsbCkgb3IgZWFjaCBpbW1lZGlhdGUgY2hpbGQgZGlyIHRoYXQgY29udGFpbnMgYSBgU0tJTEwubWRgLlxuICovXG5hc3luYyBmdW5jdGlvbiBjb2xsZWN0U2tpbGxEaXJzKHJvb3Q6IHN0cmluZyk6IFByb21pc2U8U3RhZ2VkU2tpbGxEaXJbXT4ge1xuICBpZiAoIShhd2FpdCBwYXRoRXhpc3RzKHJvb3QpKSkgcmV0dXJuIFtdO1xuICBpZiAoYXdhaXQgcGF0aEV4aXN0cyhqb2luKHJvb3QsIFwiU0tJTEwubWRcIikpKSB7XG4gICAgY29uc3QgbmFtZSA9IHBvc2l4LmJhc2VuYW1lKHJvb3Quc3BsaXQoL1tcXFxcL10vKS5qb2luKFwiL1wiKSk7XG4gICAgcmV0dXJuIFt7IG5hbWUsIGFic29sdXRlUGF0aDogcm9vdCB9XTtcbiAgfVxuICBjb25zdCBkaXJzOiBTdGFnZWRTa2lsbERpcltdID0gW107XG4gIGZvciAoY29uc3QgZW50cnkgb2YgYXdhaXQgcmVhZGRpcihyb290LCB7IHdpdGhGaWxlVHlwZXM6IHRydWUgfSkpIHtcbiAgICBpZiAoIWVudHJ5LmlzRGlyZWN0b3J5KCkpIGNvbnRpbnVlO1xuICAgIGNvbnN0IGRpciA9IGpvaW4ocm9vdCwgZW50cnkubmFtZSk7XG4gICAgaWYgKGF3YWl0IHBhdGhFeGlzdHMoam9pbihkaXIsIFwiU0tJTEwubWRcIikpKSB7XG4gICAgICBkaXJzLnB1c2goeyBuYW1lOiBlbnRyeS5uYW1lLCBhYnNvbHV0ZVBhdGg6IGRpciB9KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGRpcnM7XG59XG5cbi8qKlxuICogQ29weSBldmVyeSBzdGFnZWQgc2tpbGwgZGlyZWN0b3J5IGludG8ge0BsaW5rIGRlc3RpbmF0aW9ufSwgcHJlc2VydmluZyB0aGVcbiAqIGA8c2tpbGw+LzxyZWxhdGl2ZT5gIGxheW91dC4gVGhlIGRlc3RpbmF0aW9uIGlzIGp1c3QgYSB7QGxpbmsgRmlsZVN5c3RlbX0sXG4gKiBzbyB0aGUgRGF0YWJyaWNrcyBBc3Npc3RhbnQgdHJlZSBhbmQgdGhlIGxvY2FsIGZhbGxiYWNrIHNoYXJlIG9uZSBjb3BpZXIuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGNvcHlTa2lsbERpcnMoZGVzdGluYXRpb246IEZpbGVTeXN0ZW0sIGRpcnM6IFN0YWdlZFNraWxsRGlyW10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgYXdhaXQgZGVzdGluYXRpb24uaW5pdCgpO1xuICBmb3IgKGNvbnN0IGRpciBvZiBkaXJzKSB7XG4gICAgZm9yIChjb25zdCByZWxhdGl2ZSBvZiBmaW5kLmZpbmRGaWxlcyhcIioqLypcIiwgeyBjd2Q6IGRpci5hYnNvbHV0ZVBhdGgsIG5vZGlyOiB0cnVlIH0pKSB7XG4gICAgICBjb25zdCBidWZmZXIgPSBhd2FpdCByZWFkRmlsZShqb2luKGRpci5hYnNvbHV0ZVBhdGgsIHJlbGF0aXZlKSk7XG4gICAgICBjb25zdCBza2lsbFBhdGggPSBwb3NpeC5qb2luKGRpci5uYW1lLCByZWxhdGl2ZS5zcGxpdCgvW1xcXFwvXS8pLmpvaW4oXCIvXCIpKTtcbiAgICAgIGF3YWl0IGRlc3RpbmF0aW9uLndyaXRlRmlsZShza2lsbFBhdGgsIGJ1ZmZlciwgeyBvdmVyd3JpdGU6IHRydWUgfSk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQ29weSBzdGFnZWQgc2tpbGwgZGlycyBpbnRvIGEgU1RBQkxFIGxvY2FsIHRyZWUga2V5ZWQgYnkgdGhlIHNvdXJjZSwgYW5kXG4gKiByZXR1cm4gaXRzIHJvb3QgcGF0aC5cbiAqXG4gKiBBIGdpdmVuIHNvdXJjZSByZXNvbHZlcyB0byB0aGUgc2FtZSBjb250ZW50IG9uIGFsbW9zdCBldmVyeSBib290LCBzbyBlYWNoXG4gKiBvbmUgb3ducyBhIGRpcmVjdG9yeSBuYW1lZCBmb3IgaXRzIHtAbGluayBoYXNoLmZudkhhc2h9IHJhdGhlciB0aGFuIGxlYXZpbmdcbiAqIGEgZnJlc2ggc2NyYXRjaCBkaXIgYmVoaW5kIHBlciByZXN0YXJ0LiBLZXlpbmcgb24gdGhlIHNvdXJjZSAobm90IHRoZVxuICogY29udGVudCkgaXMgd2hhdCBrZWVwcyB0d28gZGlmZmVyZW50IHNvdXJjZXMgZnJvbSBvdmVyd3JpdGluZyBlYWNoIG90aGVyLlxuICovXG5hc3luYyBmdW5jdGlvbiBwZXJzaXN0TG9jYWxseShzb3VyY2U6IHN0cmluZywgZGlyczogU3RhZ2VkU2tpbGxEaXJbXSk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IHN0YWJsZSA9IGF3YWl0IGxvY2FsRlMucmVidWlsZEZTKGAke0xPQ0FMX1NLSUxMU19ESVJ9LyR7aGFzaC5mbnZIYXNoKHNvdXJjZSl9YCwgKHNjcmF0Y2gpID0+XG4gICAgY29weVNraWxsRGlycyhzY3JhdGNoLCBkaXJzKSxcbiAgKTtcbiAgcmV0dXJuIHN0YWJsZS5yb290O1xufVxuXG4vKipcbiAqIEEgc2NyYXRjaCBmaWxlc3lzdGVtIHdob3NlIHJvb3QgZXhpc3RzIG9uIGRpc2ssIGZvciB0aGUgcGF0aHMgdGhhdCBoYW5kIGFcbiAqIHJlYWwgZGlyZWN0b3J5IHRvIGBub2RlOmZzYCBvciBhIGNoaWxkIHByb2Nlc3MgcmF0aGVyIHRoYW4gZ29pbmcgdGhyb3VnaFxuICogdGhlIHtAbGluayBGaWxlU3lzdGVtfSBBUEkuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGluaXRpYWxpemVkU2NyYXRjaChwcmVmaXg6IHN0cmluZyk6IFByb21pc2U8TG9jYWxGaWxlU3lzdGVtPiB7XG4gIGNvbnN0IHNjcmF0Y2ggPSBsb2NhbEZTLnNjcmF0Y2hGUyhwcmVmaXgpO1xuICBhd2FpdCBzY3JhdGNoLmluaXQoKTtcbiAgcmV0dXJuIHNjcmF0Y2g7XG59XG5cbi8qKiBCZXN0LWVmZm9ydCBleGlzdGVuY2UgY2hlY2suICovXG5hc3luYyBmdW5jdGlvbiBwYXRoRXhpc3RzKHBhdGg6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICB0cnkge1xuICAgIGF3YWl0IHN0YXQocGF0aCk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuIl19
580
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVtb3RlLXNraWxscy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yZW1vdGUtc2tpbGxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQStDRztBQUVILE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2pGLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDNUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRWpELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUUzQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDdkMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDN0QsT0FBTyxFQUFFLE9BQU8sRUFBd0IsTUFBTSxlQUFlLENBQUM7QUFDOUQsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUlyRixNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLHNCQUFzQixDQUFDLENBQUM7QUFFbEQsaUZBQWlGO0FBQ2pGLE1BQU0sNEJBQTRCLEdBQUcsOEJBQThCLENBQUM7QUFFcEUsaUVBQWlFO0FBQ2pFLFNBQVMsdUJBQXVCLENBQUMsU0FBaUI7SUFDaEQsT0FBTyxVQUFVLFNBQVMsQ0FBQyxJQUFJLEVBQUUsb0JBQW9CLENBQUM7QUFDeEQsQ0FBQztBQUVE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LEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUN0RSxDQUFDO0lBQ0gsQ0FBQztBQUNILENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILEtBQUssVUFBVSxjQUFjLENBQzNCLEdBQVcsRUFDWCxJQUFzQixFQUN0QixNQUE2QjtJQUU3QixNQUFNLE1BQU0sR0FBRyxNQUFNLE9BQU8sQ0FBQyxTQUFTLENBQUMsR0FBRyxnQkFBZ0IsSUFBSSxHQUFHLEVBQUUsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7UUFDckYsTUFBTSxhQUFhLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ25DLE1BQU0sYUFBYSxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDNUMsQ0FBQyxDQUFDLENBQUM7SUFDSCxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUM7QUFDckIsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxLQUFLLFVBQVUsa0JBQWtCLENBQUMsTUFBYztJQUM5QyxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzFDLE1BQU0sT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ3JCLE9BQU8sT0FBTyxDQUFDO0FBQ2pCLENBQUM7QUFFRCxtQ0FBbUM7QUFDbkMsS0FBSyxVQUFVLFVBQVUsQ0FBQyxJQUFZO0lBQ3BDLElBQUksQ0FBQztRQUNILE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2pCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFN0YXJ0dXAgcHJvdmlzaW9uaW5nIG9mIHJlbW90ZSBBZ2VudC1Ta2lsbCBzb3VyY2VzIGZvciBhIE1hc3RyYSB3b3Jrc3BhY2UuXG4gKlxuICogQSB7QGxpbmsgUmVtb3RlU2tpbGxTb3VyY2V9IG5hbWVzIFdIRVJFIGEgYFNLSUxMLm1kYCB0cmVlIGNvbWVzIGZyb20gLSB0aGVcbiAqIHtAbGluayBBSVRPT0xTX1NPVVJDRX0gY29uc3RhbnQsIGEgR2l0SHViIGBvd25lci9yZXBvYCwgYW55IGdpdCAvIEdpdExhYiBVUkwsXG4gKiBvciBhIGRpcmVjdCBkb3dubG9hZCBVUkwgLSBhbmQgb3B0aW9uYWwgcGVyLXNvdXJjZSBwb2xpY3kuXG4gKiB7QGxpbmsgcHJvdmlzaW9uUmVtb3RlU2tpbGxzfSBtYXRlcmlhbGl6ZXMgZXZlcnkgc291cmNlIGludG8gYSBsb2NhbFxuICogYFNLSUxMLm1kYCB0cmVlIGF0IGFwcCBib290IGFuZCByZXR1cm5zIHRoZSBkaXJlY3RvcmllcyB0byBoYW5kIE1hc3RyYSBhc1xuICogZXh0cmEgc2tpbGwgc2NhbiBwYXRocy5cbiAqXG4gKiBSZXNvbHV0aW9uIHBlciBzb3VyY2UsIGluIG9yZGVyOlxuICpcbiAqIDEuIHRoZSB7QGxpbmsgQUlUT09MU19TT1VSQ0V9IGNvbnN0YW50IChgXCJhaXRvb2xzXCJgKTogRGF0YWJyaWNrcycgb3duIHNraWxsXG4gKiAgICBzZXQsIHJlYWQgc3RyYWlnaHQgZnJvbSB0aGUgcHVibGljIHJlcG8gdGhlIGBkYXRhYnJpY2tzIGFpdG9vbHNgIENMSVxuICogICAgc291cmNlcyBmcm9tLiBObyBDTEksIG5vIERhdGFicmlja3MgYXV0aCAtIHdoaWNoIGlzIHdoYXQgbWFrZXMgaXQgdXNhYmxlXG4gKiAgICBpbnNpZGUgYSBEYXRhYnJpY2tzIEFwcCBjb250YWluZXIsIHdoZXJlIHRoZSBDTEkgaXMgbm90IGluc3RhbGxlZDtcbiAqIDIuIHRoZSBPUFRJT05BTCBgc2tpbGxzYCBucG0gQ0xJIChwZWVyIGRlcCk6IGlmIGluc3RhbGxlZCwgZWFjaCBzb3VyY2UgaXNcbiAqICAgIGNvcGllZCBpbnRvIGEgc3RhZ2luZyBkaXIgd2l0aCBgc2tpbGxzIGFkZCA8c291cmNlPiAtLWFnZW50IDxkaXI+IC0tY29weWAsXG4gKiAgICB3aGljaCB1bmRlcnN0YW5kcyBldmVyeSBzb3VyY2UgZm9ybWF0IHRoZSBlY29zeXN0ZW0gZG9lcyAoR2l0SHViXG4gKiAgICBzaG9ydGhhbmQsIGdpdCBVUkxzLCBhcmNoaXZlL2Rvd25sb2FkIFVSTHMpO1xuICogMy4gb3RoZXJ3aXNlIGEgcGxhaW4ge0BsaW5rIGZldGNofSBvZiB0aGUgc291cmNlIFVSTCAoYnVpbHQgd2l0aFxuICogICAge0BsaW5rIG5ldC51cmxCdWlsZGVyfSksIHdyaXRpbmcgdGhlIGRvd25sb2FkZWQgYFNLSUxMLm1kYCB0byBhIHN0YWdpbmdcbiAqICAgIGRpci5cbiAqXG4gKiBBIHNvdXJjZSB0aGF0IHJlc29sdmVzIHRocm91Z2ggbmVpdGhlciBwYXRoIGZhaWxzIGFwcCBzdGFydHVwLCB1bmxlc3MgdGhlXG4gKiBzb3VyY2UgKG9yIHRoZSB0b3AtbGV2ZWwgY2FsbCkgc2V0cyBgZmFpbE9uRXJyb3I6IGZhbHNlYCwgaW4gd2hpY2ggY2FzZSBpdCBpc1xuICogbG9nZ2VkIGFuZCBza2lwcGVkIHNvIG9uZSBiYWQgc291cmNlIG5ldmVyIHRha2VzIHRoZSBhcHAgZG93bi5cbiAqXG4gKiBFdmVyeSBwcm92aXNpb25lZCB0cmVlIGNhcnJpZXMgYSB7QGxpbmsgTUVUQURBVEFfRklMRX0gcmVjb3JkaW5nIHdoZW4gZWFjaFxuICogc291cmNlIHdhcyBsYXN0IGRvd25sb2FkZWQsIGFuZCBhIHNvdXJjZSBpcyBvbmx5IHJlLWRvd25sb2FkZWQgb25jZSB0aGF0XG4gKiByZWNvcmQgaXMgb2xkZXIgdGhhbiB7QGxpbmsgREVGQVVMVF9SRUZSRVNIX1RUTF9NU30gKGEgZGF5KS4gVGhpcyBydW5zIGF0IGFwcFxuICogQk9PVCwgc28gd2l0aG91dCBpdCBhIGNvbnRhaW5lciB0aGF0IHJlc3RhcnRzIGEgZG96ZW4gdGltZXMgYW4gaG91ciByZS1wdWxsc1xuICogdGhlIHdob2xlIEFJIFRvb2xzIHNldCBhIGRvemVuIHRpbWVzIGZvciBjb250ZW50IHRoYXQgY2hhbmdlcyByYXJlbHkuIFRoZVxuICogcmVjb3JkIHRyYXZlbHMgV0lUSCB0aGUgdHJlZSByYXRoZXIgdGhhbiBpbiBwcm9jZXNzIG1lbW9yeSwgc28gdGhlIHJldXNlXG4gKiBzdXJ2aXZlcyBhIHJlc3RhcnQgLSB3aGljaCBpcyB0aGUgb25seSB3YXkgaXQgaGVscHMgYSBEYXRhYnJpY2tzIEFwcCBhdCBhbGwuXG4gKiBQYXNzIGByZWZyZXNoVHRsTXM6IDBgIHRvIGRvd25sb2FkIG9uIGV2ZXJ5IGJvb3QuXG4gKlxuICogVGhlIGRlZmF1bHQgZGVzdGluYXRpb24gaXMgdGhlIERhdGFicmlja3Mgd29ya3NwYWNlIEFzc2lzdGFudCBza2lsbHMgdHJlZVxuICogKGAvV29ya3NwYWNlLy5hc3Npc3RhbnQvc2tpbGxzYCwgdGhlIHNhbWUgdHJlZSBhIFwic2F2ZSB0aGlzIGFzIGEgc2tpbGxcIlxuICogYWN0aW9uIHdyaXRlcyB0byksIHNvIHByb3Zpc2lvbmVkIHNraWxscyBwZXJzaXN0IGFjcm9zcyByZXN0YXJ0cyBhbmQgYXJlXG4gKiBkaXNjb3ZlcmVkIGJ5IHRoZSBidWlsdC1pbiBBc3Npc3RhbnQtc2tpbGxzIG1vdW50LiBQYXNzIGB1c2VyRW1haWxgIChvciBhblxuICogZXhwbGljaXQgYGRhdGFicmlja3NCYXNlUGF0aGApIHRvIHRhcmdldCBgL1VzZXJzLzxlbWFpbD4vLmFzc2lzdGFudC9za2lsbHNgXG4gKiBpbnN0ZWFkLiBXaGVuIG5vIERhdGFicmlja3MgY2xpZW50IGlzIHJlc29sdmFibGUgYXQgc3RhcnR1cCwgdGhlIHRyZWUgaXNcbiAqIHdyaXR0ZW4gdW5kZXIge0BsaW5rIGxvY2FsRlMudG1wRlN9IGFuZCByZXR1cm5lZCBhcyBhbiBleHRyYSBsb2NhbCBza2lsbCBwYXRoXG4gKiBmb3IgdGhlIGN1cnJlbnQgcHJvY2Vzcy5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgbWtkaXIsIHJlYWRkaXIsIHJlYWRGaWxlLCBybSwgc3RhdCwgd3JpdGVGaWxlIH0gZnJvbSBcIm5vZGU6ZnMvcHJvbWlzZXNcIjtcbmltcG9ydCB7IGNyZWF0ZVJlcXVpcmUgfSBmcm9tIFwibm9kZTptb2R1bGVcIjtcbmltcG9ydCB7IGRpcm5hbWUsIGpvaW4sIHBvc2l4IH0gZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHR5cGUgeyBXb3Jrc3BhY2VDbGllbnQgfSBmcm9tIFwiQGRhdGFicmlja3Mvc2RrLWV4cGVyaW1lbnRhbFwiO1xuaW1wb3J0IHsgYXBwa2l0IH0gZnJvbSBcIkBkYngtdG9vbHMvYXBwa2l0XCI7XG5pbXBvcnQgdHlwZSB7IFdvcmtzcGFjZUNsaWVudExpa2UgfSBmcm9tIFwiQGRieC10b29scy9hcHBraXRcIjtcbmltcG9ydCB7IGV4ZWMgfSBmcm9tIFwiQGRieC10b29scy9jb3JlXCI7XG5pbXBvcnQgeyBEYXRhYnJpY2tzRmlsZVN5c3RlbSB9IGZyb20gXCJAZGJ4LXRvb2xzL2RhdGFicmlja3NcIjtcbmltcG9ydCB7IGxvY2FsRlMsIHR5cGUgTG9jYWxGaWxlU3lzdGVtIH0gZnJvbSBcIkBkYngtdG9vbHMvZnNcIjtcbmltcG9ydCB7IGZpbmQgfSBmcm9tIFwiQGRieC10b29scy9wYXRoXCI7XG5pbXBvcnQgeyBlcnJvciwgaGFzaCwganNvbiwgbG9nLCBuZXQsIG9iamVjdCwgc3RyaW5nIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB0eXBlIHsgT25lT3JNYW55IH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB0eXBlIHsgRmlsZVN5c3RlbSB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1mc1wiO1xuXG5jb25zdCBsb2dnZXIgPSBsb2cubG9nZ2VyKFwibWFzdHJhL3JlbW90ZS1za2lsbHNcIik7XG5cbi8qKiBTaGFyZWQgQXNzaXN0YW50IHNraWxscyB0cmVlIGluIHRoZSBEYXRhYnJpY2tzIHdvcmtzcGFjZSAoZGVmYXVsdCB0YXJnZXQpLiAqL1xuY29uc3QgQVNTSVNUQU5UX1NIQVJFRF9TS0lMTFNfUEFUSCA9IFwiL1dvcmtzcGFjZS8uYXNzaXN0YW50L3NraWxsc1wiO1xuXG4vKiogQXNzaXN0YW50IHNraWxscyBkaXJlY3RvcnkgZm9yIGEgc3BlY2lmaWMgRGF0YWJyaWNrcyB1c2VyLiAqL1xuZnVuY3Rpb24gdXNlckFzc2lzdGFudFNraWxsc1BhdGgodXNlckVtYWlsOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYC9Vc2Vycy8ke3VzZXJFbWFpbC50cmltKCl9Ly5hc3Npc3RhbnQvc2tpbGxzYDtcbn1cblxuLyoqXG4gKiBBZ2VudCBpZCB0aGUgYHNraWxsc2AgQ0xJIGluc3RhbGxzIGEgYmFyZSBgU0tJTEwubWRgIHRyZWUgdW5kZXIuXG4gKlxuICogYHVuaXZlcnNhbGAgaXMgdGhlIENMSSdzIG93biBuYW1lIGZvciBcIm5vIHBhcnRpY3VsYXIgYWdlbnQsIGp1c3QgdGhlIHBsYWluXG4gKiB0cmVlXCIsIHdoaWNoIGlzIHdoYXQgdGhpcyBtb2R1bGUgd2FudHMgLSBpdCByZS1ob3N0cyB0aGUgcmVzdWx0IGl0c2VsZi4gVGhlXG4gKiBpZCBtdXN0IGJlIG9uZSB0aGUgaW5zdGFsbGVkIENMSSBrbm93czogYW4gdW5yZWNvZ25pemVkIG9uZSBpcyByZWplY3RlZFxuICogb3V0cmlnaHQgKGBJbnZhbGlkIGFnZW50czogLi4uYCksIHRha2luZyBldmVyeSBub24tYGFpdG9vbHNgIHNvdXJjZSBkb3duIHdpdGhcbiAqIGl0LCBzaW5jZSBhIENMSSBmYWlsdXJlIGlzIGEgaGFyZCBmYWlsdXJlIHJhdGhlciB0aGFuIGEgZmFsbC10aHJvdWdoIHRvXG4gKiB7QGxpbmsgc3RhZ2VWaWFGZXRjaH0uXG4gKi9cbmNvbnN0IFNLSUxMU19DTElfQUdFTlQgPSBcInVuaXZlcnNhbFwiO1xuXG4vKiogV2hlcmUgdGhlIGBza2lsbHNgIENMSSBkcm9wcyBhIHBsYWluIGBTS0lMTC5tZGAgdHJlZSB1bmRlciBhIHRhcmdldCBkaXIuICovXG5jb25zdCBTS0lMTFNfQ0xJX0xBWU9VVCA9IFtcIi5hZ2VudHNcIiwgXCJza2lsbHNcIl0gYXMgY29uc3Q7XG5cbi8qKiBDYXAgb24gYSBkaXJlY3QtZmV0Y2ggZG93bmxvYWQgYm9keSwgbWF0Y2hpbmcgdGhlIGBza2lsbHNgIENMSSBkZWZhdWx0LiAqL1xuY29uc3QgREVGQVVMVF9NQVhfRE9XTkxPQURfQllURVMgPSAxMCAqIDEwMjQgKiAxMDI0O1xuXG4vKiogU3RhYmxlIHRlbXAgZGlyZWN0b3J5IGhvbGRpbmcgb25lIHJlYnVpbHQgc2tpbGwgdHJlZSBwZXIgcmVtb3RlIHNvdXJjZS4gKi9cbmNvbnN0IExPQ0FMX1NLSUxMU19ESVIgPSBcIm1hc3RyYS1sb2NhbC1za2lsbHNcIjtcblxuLyoqXG4gKiBCb29ra2VlcGluZyBmaWxlIHdyaXR0ZW4gYXQgdGhlIHJvb3Qgb2YgZXZlcnkgcHJvdmlzaW9uZWQgc2tpbGwgdHJlZSwgbmFtaW5nXG4gKiB3aGVuIGVhY2ggc291cmNlIHdhcyBsYXN0IGRvd25sb2FkZWQuIEEgZG90ZmlsZSBzbyB0aGUgc2tpbGwgc2Nhbm5lcnMsIHdoaWNoXG4gKiBsb29rIGZvciBgPGRpcj4vU0tJTEwubWRgLCBuZXZlciBtaXN0YWtlIGl0IGZvciBhIHNraWxsLlxuICovXG5jb25zdCBNRVRBREFUQV9GSUxFID0gXCIubWV0YWRhdGEuanNvblwiO1xuXG4vKiogU2hhcGUgbWFya2VyIGZvciB7QGxpbmsgTUVUQURBVEFfRklMRX07IGFuIHVua25vd24gdmVyc2lvbiBpcyBpZ25vcmVkLCBub3QgcmVhZC4gKi9cbmNvbnN0IE1FVEFEQVRBX1ZFUlNJT04gPSAxO1xuXG4vKiogSG93IGxvbmcgYSBwcm92aXNpb25lZCBzb3VyY2UgaXMgcmV1c2VkIGJlZm9yZSBiZWluZyBkb3dubG9hZGVkIGFnYWluLiAqL1xuY29uc3QgREVGQVVMVF9SRUZSRVNIX1RUTF9NUyA9IDI0ICogNjAgKiA2MCAqIDEwMDA7XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBBSSBUb29scyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuLyoqXG4gKiBTb3VyY2UgY29uc3RhbnQgc2VsZWN0aW5nIERhdGFicmlja3MnIG93biBBSSBUb29scyBza2lsbCBzZXQuXG4gKlxuICogQGV4YW1wbGVcbiAqIG1hc3RyYSh7IHJlbW90ZVNraWxsczogXCJhaXRvb2xzXCIgfSk7XG4gKi9cbmV4cG9ydCBjb25zdCBBSVRPT0xTX1NPVVJDRSA9IFwiYWl0b29sc1wiO1xuXG4vKiogVGhlIHtAbGluayBBSVRPT0xTX1NPVVJDRX0gbGl0ZXJhbCwgZm9yIGNhbGxlcnMgc3BlbGxpbmcgdGhlIHVuaW9uIG91dC4gKi9cbmV4cG9ydCB0eXBlIEFpVG9vbHNTb3VyY2UgPSB0eXBlb2YgQUlUT09MU19TT1VSQ0U7XG5cbi8qKlxuICogVGhlIFBVQkxJQyByZXBvIGBkYXRhYnJpY2tzIGFpdG9vbHMgaW5zdGFsbGAgc291cmNlcyBmcm9tLiBSZWFkaW5nIGl0XG4gKiBkaXJlY3RseSBpcyB3aGF0IGxldHMgYW4gYXBwIGdldCB0aGUgc2FtZSBza2lsbHMgdGhlIENMSSBpbnN0YWxscyB3aXRob3V0XG4gKiB0aGUgQ0xJIC0gd2hpY2ggYSBEYXRhYnJpY2tzIEFwcCBjb250YWluZXIgZG9lcyBub3Qgc2hpcC5cbiAqL1xuY29uc3QgQUlUT09MU19SRVBPID0gXCJkYXRhYnJpY2tzL2RhdGFicmlja3MtYWdlbnQtc2tpbGxzXCI7XG5cbi8qKiBSZXBvIHJlZiB0aGUgc2tpbGxzIGFyZSByZWFkIGZyb20uIE92ZXJyaWRlIHBlciBzb3VyY2Ugd2l0aCBgcmVmYC4gKi9cbmNvbnN0IEFJVE9PTFNfUkVGID0gXCJtYWluXCI7XG5cbi8qKiBTa2lsbCBmaWxlcyBkb3dubG9hZGVkIGF0IG9uY2U7IHRoZSBzZXQgaXMgfjMwIHNraWxscyBvZiBhIGZldyBmaWxlcyBlYWNoLiAqL1xuY29uc3QgQUlUT09MU19DT05DVVJSRU5DWSA9IDg7XG5cbi8qKiBUaGUgc3Vic2V0IG9mIHRoZSByZXBvJ3MgZ2VuZXJhdGVkIGBtYW5pZmVzdC5qc29uYCB0aGlzIG1vZHVsZSByZWFkcy4gKi9cbmludGVyZmFjZSBBaVRvb2xzTWFuaWZlc3Qge1xuICBza2lsbHM/OiBSZWNvcmQ8c3RyaW5nLCB7IGZpbGVzPzogc3RyaW5nW107IHJlcG9fZGlyPzogc3RyaW5nIH0+O1xufVxuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4vKipcbiAqIE9uZSByZW1vdGUgc2tpbGwgc291cmNlIGFuZCBpdHMgcGVyLXNvdXJjZSBwb2xpY3kuXG4gKlxuICogYHNvdXJjZWAgaXMge0BsaW5rIEFJVE9PTFNfU09VUkNFfSBvciBhbnl0aGluZyB0aGUgYHNraWxsc2AgZWNvc3lzdGVtXG4gKiB1bmRlcnN0YW5kczogYSBHaXRIdWIgYG93bmVyL3JlcG9gIHNob3J0aGFuZCwgYSBmdWxsIEdpdEh1YiAvIEdpdExhYiAvIGdpdFxuICogVVJMLCBvciBhIGRpcmVjdCBkb3dubG9hZCBVUkwgdG8gYSBgU0tJTEwubWRgIG9yIGFyY2hpdmUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVtb3RlU2tpbGxTb3VyY2VPcHRpb25zIHtcbiAgLyoqIGBcImFpdG9vbHNcImAsIGEgR2l0SHViIHNob3J0aGFuZCwgYSBnaXQgLyBHaXRMYWIgVVJMLCBvciBhIGRvd25sb2FkIFVSTC4gKi9cbiAgc291cmNlOiBuZXQuVXJsTGlrZSB8IEFpVG9vbHNTb3VyY2U7XG4gIC8qKiBJbnN0YWxsIG9ubHkgdGhlc2Ugc2tpbGwgbmFtZXMgZnJvbSB0aGUgc291cmNlLiAqL1xuICBza2lsbHM/OiBzdHJpbmcgfCBzdHJpbmdbXTtcbiAgLyoqIEluY2x1ZGUgZXhwZXJpbWVudGFsIHNraWxscy4gYFwiYWl0b29sc1wiYCBvbmx5LiAqL1xuICBleHBlcmltZW50YWw/OiBib29sZWFuO1xuICAvKiogUGluIHRoZSByZXBvIHJlZiAodGFnIC8gYnJhbmNoIC8gc2hhKS4gYFwiYWl0b29sc1wiYCBvbmx5OyBkZWZhdWx0cyB0byBgbWFpbmAuICovXG4gIHJlZj86IHN0cmluZztcbiAgLyoqIE92ZXJyaWRlIHRoZSBieXRlIGNlaWxpbmcgb24gYSBkaXJlY3QtZmV0Y2ggZG93bmxvYWQgZm9yIHRoaXMgc291cmNlLiAqL1xuICBtYXhEb3dubG9hZEJ5dGVzPzogbnVtYmVyO1xuICAvKipcbiAgICogSG93IGxvbmcgdGhpcyBzb3VyY2UncyBwcm92aXNpb25lZCB0cmVlIGlzIHJldXNlZCBiZWZvcmUgaXQgaXMgZG93bmxvYWRlZFxuICAgKiBhZ2FpbiwgaW4gbWlsbGlzZWNvbmRzLiBPdmVycmlkZXMgdGhlIHRvcC1sZXZlbFxuICAgKiB7QGxpbmsgUHJvdmlzaW9uUmVtb3RlU2tpbGxzT3B0aW9ucy5yZWZyZXNoVHRsTXN9OyBgMGAgcmUtZG93bmxvYWRzIG9uXG4gICAqIGV2ZXJ5IGJvb3QuXG4gICAqL1xuICByZWZyZXNoVHRsTXM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBXaGVuIGBmYWxzZWAsIGEgc291cmNlIHRoYXQgZmFpbHMgdG8gcmVzb2x2ZSBpcyBsb2dnZWQgYW5kIHNraXBwZWQgaW5zdGVhZFxuICAgKiBvZiBmYWlsaW5nIGFwcCBzdGFydHVwLiBPdmVycmlkZXMgdGhlIHRvcC1sZXZlbCB7QGxpbmsgUHJvdmlzaW9uUmVtb3RlU2tpbGxzT3B0aW9ucy5mYWlsT25FcnJvcn0uXG4gICAqL1xuICBmYWlsT25FcnJvcj86IGJvb2xlYW47XG59XG5cbi8qKlxuICogQSByZW1vdGUgc2tpbGwgc291cmNlOiB0aGUge0BsaW5rIEFJVE9PTFNfU09VUkNFfSBjb25zdGFudCwgYSBVUkwtbGlrZVxuICogKHN0cmluZyAvIGBVUkxgIC8gYHsgdXJsIH1gKSwgb3IgYSB7QGxpbmsgUmVtb3RlU2tpbGxTb3VyY2VPcHRpb25zfSBiYWcgd2l0aFxuICogcGVyLXNvdXJjZSBwb2xpY3kuXG4gKi9cbmV4cG9ydCB0eXBlIFJlbW90ZVNraWxsU291cmNlID0gbmV0LlVybExpa2UgfCBBaVRvb2xzU291cmNlIHwgUmVtb3RlU2tpbGxTb3VyY2VPcHRpb25zO1xuXG4vKipcbiAqIFRoZSB3b3Jrc3BhY2UgYHJlbW90ZVNraWxsc2Agb3B0aW9uOiBvbmUgc291cmNlLCBhIG5vbi1lbXB0eSBsaXN0IG9mIHRoZW0sIG9yXG4gKiBhIHtAbGluayBQcm92aXNpb25SZW1vdGVTa2lsbHNPcHRpb25zfSBiYWcgd2hlbiB0b3AtbGV2ZWwgcG9saWN5IGlzIG5lZWRlZC5cbiAqL1xuZXhwb3J0IHR5cGUgUmVtb3RlU2tpbGxzT3B0aW9uID1cbiAgUmVtb3RlU2tpbGxTb3VyY2UgfCBPbmVPck1hbnk8UmVtb3RlU2tpbGxTb3VyY2U+IHwgUHJvdmlzaW9uUmVtb3RlU2tpbGxzT3B0aW9ucztcblxuLyoqIEEgc291cmNlIGVudHJ5IHdpdGggaXRzIGBzb3VyY2VgIGZsYXR0ZW5lZCB0byBhIHBsYWluIHN0cmluZy4gKi9cbnR5cGUgTm9ybWFsaXplZFNvdXJjZSA9IE9taXQ8UmVtb3RlU2tpbGxTb3VyY2VPcHRpb25zLCBcInNvdXJjZVwiPiAmIHsgc291cmNlOiBzdHJpbmcgfTtcblxuLyoqIFRvcC1sZXZlbCByZW1vdGUtc2tpbGxzIHByb3Zpc2lvbmluZyBvcHRpb25zLiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcm92aXNpb25SZW1vdGVTa2lsbHNPcHRpb25zIHtcbiAgLyoqIFNvdXJjZXMgdG8gbWF0ZXJpYWxpemUgYXQgc3RhcnR1cC4gKi9cbiAgc291cmNlczogUmVtb3RlU2tpbGxTb3VyY2UgfCBPbmVPck1hbnk8UmVtb3RlU2tpbGxTb3VyY2U+O1xuICAvKipcbiAgICogRmFpbCBhcHAgc3RhcnR1cCB3aGVuIGEgc291cmNlIGNhbid0IGJlIHJlc29sdmVkLiBEZWZhdWx0cyB0byBgdHJ1ZWAuIEFcbiAgICogcGVyLXNvdXJjZSBgZmFpbE9uRXJyb3JgIHdpbnMgb3ZlciB0aGlzLlxuICAgKi9cbiAgZmFpbE9uRXJyb3I/OiBib29sZWFuO1xuICAvKipcbiAgICogQWJzb2x1dGUgRGF0YWJyaWNrcyBwYXRoIHRoYXQgcm9vdHMgdGhlIGRlc3RpbmF0aW9uIEFzc2lzdGFudCBza2lsbHMgdHJlZS5cbiAgICogRGVmYXVsdHMgdG8gdGhlIE9CTyB1c2VyJ3MgYC9Vc2Vycy88ZW1haWw+Ly5hc3Npc3RhbnQvc2tpbGxzYC5cbiAgICovXG4gIGRhdGFicmlja3NCYXNlUGF0aD86IHN0cmluZztcbiAgLyoqIEF1dGgtc2NvcGVkIERhdGFicmlja3MgY2xpZW50LiBEZWZhdWx0cyB0byB0aGUgQXBwS2l0IGV4ZWN1dGlvbiBjb250ZXh0LiAqL1xuICBjbGllbnQ/OiBXb3Jrc3BhY2VDbGllbnRMaWtlO1xuICAvKiogVXNlciBlbWFpbCB1c2VkIHRvIGRlcml2ZSB0aGUgZGVmYXVsdCBEYXRhYnJpY2tzIGRlc3RpbmF0aW9uLiAqL1xuICB1c2VyRW1haWw/OiBzdHJpbmc7XG4gIC8qKiBCeXRlIGNlaWxpbmcgb24gYSBkaXJlY3QtZmV0Y2ggZG93bmxvYWQuIERlZmF1bHRzIHRvIDEwIE1pQi4gKi9cbiAgbWF4RG93bmxvYWRCeXRlcz86IG51bWJlcjtcbiAgLyoqXG4gICAqIEhvdyBsb25nIGEgcHJvdmlzaW9uZWQgdHJlZSBpcyByZXVzZWQgYmVmb3JlIGl0cyBzb3VyY2UgaXMgZG93bmxvYWRlZFxuICAgKiBhZ2FpbiwgaW4gbWlsbGlzZWNvbmRzLiBEZWZhdWx0cyB0byBhIGRheTsgYDBgIHJlLWRvd25sb2FkcyBvbiBldmVyeSBib290LlxuICAgKiBBIHBlci1zb3VyY2UgYHJlZnJlc2hUdGxNc2Agd2lucyBvdmVyIHRoaXMuXG4gICAqL1xuICByZWZyZXNoVHRsTXM/OiBudW1iZXI7XG59XG5cbi8qKiBXaGF0IHtAbGluayBwcm92aXNpb25SZW1vdGVTa2lsbHN9IHJlc29sdmVkLiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcm92aXNpb25lZFJlbW90ZVNraWxscyB7XG4gIC8qKlxuICAgKiBFeHRyYSBMT0NBTCBza2lsbCBzY2FuIHBhdGhzIHRvIGhhbmQgTWFzdHJhIChhIHRlbXAgZGlyIHBlciBzb3VyY2UgdGhhdFxuICAgKiBjb3VsZG4ndCBiZSB3cml0dGVuIHRvIERhdGFicmlja3MpLiBFbXB0eSB3aGVuIGV2ZXJ5dGhpbmcgbGFuZGVkIGluIHRoZVxuICAgKiBEYXRhYnJpY2tzIEFzc2lzdGFudCB0cmVlLCB3aGljaCB0aGUgYnVpbHQtaW4gbW91bnQgYWxyZWFkeSBzY2Fucy5cbiAgICovXG4gIGxvY2FsU2tpbGxQYXRoczogc3RyaW5nW107XG4gIC8qKiBBYnNvbHV0ZSBEYXRhYnJpY2tzIGRlc3RpbmF0aW9uIGVhY2ggc291cmNlIHdhcyB3cml0dGVuIHRvLCBpZiBhbnkuICovXG4gIGRhdGFicmlja3NCYXNlUGF0aD86IHN0cmluZztcbiAgLyoqXG4gICAqIE5hbWVzIG9mIGV2ZXJ5IHNraWxsIGRpcmVjdG9yeSBub3cgYXZhaWxhYmxlLCB3aGV0aGVyIGl0IHdhcyBkb3dubG9hZGVkIG9uXG4gICAqIHRoaXMgYm9vdCBvciByZXVzZWQgZnJvbSBhIHN0aWxsLWZyZXNoIHRyZWUgKHNlZSB7QGxpbmsgTUVUQURBVEFfRklMRX0pLlxuICAgKi9cbiAgc2tpbGxOYW1lczogc3RyaW5nW107XG59XG5cbi8qKlxuICogV2hhdCBvbmUgc291cmNlJ3MgbGFzdCBkb3dubG9hZCBsZWZ0IGJlaGluZCwgYXMgcmVjb3JkZWQgaW5cbiAqIHtAbGluayBNRVRBREFUQV9GSUxFfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZW1vdGVTa2lsbENhY2hlRW50cnkge1xuICAvKiogVGhlIHNvdXJjZSBzdHJpbmcgdGhpcyBlbnRyeSB3YXMgZG93bmxvYWRlZCBmcm9tLCBmb3IgcmVhZGFiaWxpdHkuICovXG4gIHNvdXJjZTogc3RyaW5nO1xuICAvKiogV2hlbiB0aGUgZG93bmxvYWQgY29tcGxldGVkLCBJU08tODYwMS4gKi9cbiAgZG93bmxvYWRlZEF0OiBzdHJpbmc7XG4gIC8qKiBTa2lsbCBkaXJlY3RvcnkgbmFtZXMgdGhlIGRvd25sb2FkIHByb2R1Y2VkLiAqL1xuICBza2lsbHM6IHN0cmluZ1tdO1xuICAvKipcbiAgICogVGhlIGNvbnRlbnQtYWZmZWN0aW5nIHBvbGljeSB0aGF0IGRvd25sb2FkIHVzZWQuIEFsc28gZm9sZGVkIGludG8gdGhlIGVudHJ5XG4gICAqIEtFWSwgc28gbmFycm93aW5nIGBza2lsbHNgIG9yIG1vdmluZyBgcmVmYCBtaXNzZXMgdGhlIGNhY2hlIGluc3RlYWQgb2ZcbiAgICogc2lsZW50bHkgc2VydmluZyB0aGUgcHJldmlvdXMgc2VsZWN0aW9uLlxuICAgKi9cbiAgcG9saWN5PzogeyBza2lsbHM/OiBzdHJpbmdbXTsgZXhwZXJpbWVudGFsPzogYm9vbGVhbjsgcmVmPzogc3RyaW5nIH07XG59XG5cbi8qKiBUaGUge0BsaW5rIE1FVEFEQVRBX0ZJTEV9IGRvY3VtZW50OiBvbmUgZW50cnkgcGVyIHByb3Zpc2lvbmVkIHNvdXJjZS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVtb3RlU2tpbGxzTWV0YWRhdGEge1xuICB2ZXJzaW9uOiBudW1iZXI7XG4gIHNvdXJjZXM6IFJlY29yZDxzdHJpbmcsIFJlbW90ZVNraWxsQ2FjaGVFbnRyeT47XG59XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gaGVscGVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbi8qKiBOb3JtYWxpemUgdGhlIGByZW1vdGVTa2lsbHNgIG9wdGlvbiBpbnRvIGEgZmxhdCBvcHRpb25zIGJhZy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVSZW1vdGVTa2lsbHNPcHRpb24oXG4gIG9wdGlvbjogUmVtb3RlU2tpbGxzT3B0aW9uIHwgdW5kZWZpbmVkLFxuKTogUHJvdmlzaW9uUmVtb3RlU2tpbGxzT3B0aW9ucyB8IHVuZGVmaW5lZCB7XG4gIGlmIChvcHRpb24gPT09IHVuZGVmaW5lZCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3QgYmFnID0gaXNQcm92aXNpb25PcHRpb25zKG9wdGlvbikgPyBvcHRpb24gOiB1bmRlZmluZWQ7XG4gIGNvbnN0IHNvdXJjZXMgPSB0b1NvdXJjZUxpc3QoYmFnID8gYmFnLnNvdXJjZXMgOiAob3B0aW9uIGFzIFJlbW90ZVNraWxsU291cmNlKSk7XG4gIC8vIEFuIGVtcHR5IGxpc3QgaXMgdGhlIHNhbWUgYXMgbm8gY29uZmlndXJhdGlvbiBhdCBhbGwuXG4gIGlmICghb2JqZWN0LmlzT25lT3JNYW55KHNvdXJjZXMpKSByZXR1cm4gdW5kZWZpbmVkO1xuICByZXR1cm4geyAuLi5iYWcsIHNvdXJjZXMgfTtcbn1cblxuLyoqIEEgYHNvdXJjZXNgLWJlYXJpbmcgYmFnIGlzIHRoZSB0b3AtbGV2ZWwgb3B0aW9ucyBzaGFwZSwgbm90IGEgc2luZ2xlIHNvdXJjZS4gKi9cbmZ1bmN0aW9uIGlzUHJvdmlzaW9uT3B0aW9ucyh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFByb3Zpc2lvblJlbW90ZVNraWxsc09wdGlvbnMge1xuICByZXR1cm4gb2JqZWN0LmlzUmVjb3JkKHZhbHVlKSAmJiBcInNvdXJjZXNcIiBpbiB2YWx1ZTtcbn1cblxuLyoqIE9uZSBzb3VyY2Ugb3IgbWFueSwgYXMgYSBwbGFpbiBhcnJheS4gQSBzb3VyY2UgaXMgbmV2ZXIgaXRzZWxmIGFuIGFycmF5LiAqL1xuZnVuY3Rpb24gdG9Tb3VyY2VMaXN0KFxuICBpbnB1dDogUmVtb3RlU2tpbGxTb3VyY2UgfCBPbmVPck1hbnk8UmVtb3RlU2tpbGxTb3VyY2U+LFxuKTogUmVtb3RlU2tpbGxTb3VyY2VbXSB7XG4gIHJldHVybiBBcnJheS5pc0FycmF5KGlucHV0KSA/IFsuLi5pbnB1dF0gOiBbaW5wdXRdO1xufVxuXG4vKiogRmxhdHRlbiBhIHNvdXJjZSBlbnRyeSAtIHN0cmluZywgYFVSTGAsIGB7IHVybCB9YCwgb3Igb3B0aW9ucyBiYWcgLSB0byBhIHtAbGluayBOb3JtYWxpemVkU291cmNlfS4gKi9cbmZ1bmN0aW9uIHRvU291cmNlT3B0aW9ucyhzb3VyY2U6IFJlbW90ZVNraWxsU291cmNlKTogTm9ybWFsaXplZFNvdXJjZSB7XG4gIGlmICh0eXBlb2Ygc291cmNlID09PSBcInN0cmluZ1wiKSByZXR1cm4geyBzb3VyY2UgfTtcbiAgaWYgKHNvdXJjZSBpbnN0YW5jZW9mIFVSTCkgcmV0dXJuIHsgc291cmNlOiBzb3VyY2UudG9TdHJpbmcoKSB9O1xuICBpZiAoXCJzb3VyY2VcIiBpbiBzb3VyY2UpIHJldHVybiB7IC4uLnNvdXJjZSwgc291cmNlOiB0b1NvdXJjZVN0cmluZyhzb3VyY2Uuc291cmNlKSB9O1xuICByZXR1cm4geyBzb3VyY2U6IHNvdXJjZS51cmwgfTtcbn1cblxuLyoqIEEge0BsaW5rIG5ldC5VcmxMaWtlfSBhcyB0aGUgcGxhaW4gc3RyaW5nIHRoZSBzdGFnaW5nIHBhdGhzIHdvcmsgd2l0aC4gKi9cbmZ1bmN0aW9uIHRvU291cmNlU3RyaW5nKHNvdXJjZTogbmV0LlVybExpa2UpOiBzdHJpbmcge1xuICBpZiAodHlwZW9mIHNvdXJjZSA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIHNvdXJjZTtcbiAgcmV0dXJuIHNvdXJjZSBpbnN0YW5jZW9mIFVSTCA/IHNvdXJjZS50b1N0cmluZygpIDogc291cmNlLnVybDtcbn1cblxuLyoqIFRydWUgd2hlbiBhIHNvdXJjZSBzZWxlY3RzIHRoZSBidWlsdC1pbiBEYXRhYnJpY2tzIEFJIFRvb2xzIHNraWxsIHNldC4gKi9cbmZ1bmN0aW9uIGlzQWlUb29sc1NvdXJjZShzb3VyY2U6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gc291cmNlLnRyaW0oKS50b0xvd2VyQ2FzZSgpID09PSBBSVRPT0xTX1NPVVJDRTtcbn1cblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gY2FjaGUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuLyoqXG4gKiBUaGUgcG9saWN5IHRoYXQgZGVjaWRlcyB3aGF0IGEgc291cmNlJ3MgZG93bmxvYWQgQ09OVEFJTlMuXG4gKlxuICogT25seSB0aGVzZSB0aHJlZSBjaGFuZ2UgdGhlIHJlc3VsdGluZyB0cmVlLCBzbyBvbmx5IHRoZXNlIGJlbG9uZyBpbiB0aGUgY2FjaGVcbiAqIGtleSAtIGBmYWlsT25FcnJvcmAgYW5kIGBtYXhEb3dubG9hZEJ5dGVzYCBnb3Zlcm4gaG93IGEgZmFpbHVyZSBpcyBoYW5kbGVkLFxuICogbm90IHdoYXQgYSBzdWNjZXNzIHByb2R1Y2VzLlxuICovXG5mdW5jdGlvbiBjYWNoZVBvbGljeShzb3VyY2VPcHRpb25zOiBOb3JtYWxpemVkU291cmNlKTogUmVtb3RlU2tpbGxDYWNoZUVudHJ5W1wicG9saWN5XCJdIHtcbiAgY29uc3Qgc2tpbGxzID0gc3RyaW5nLnBhcnNlTGlzdChzb3VyY2VPcHRpb25zLnNraWxscyk7XG4gIGNvbnN0IHBvbGljeSA9IHtcbiAgICAuLi4oc2tpbGxzLmxlbmd0aCA+IDAgPyB7IHNraWxsczogWy4uLnNraWxsc10uc29ydCgpIH0gOiB7fSksXG4gICAgLi4uKHNvdXJjZU9wdGlvbnMuZXhwZXJpbWVudGFsID09PSB0cnVlID8geyBleHBlcmltZW50YWw6IHRydWUgfSA6IHt9KSxcbiAgICAuLi4oc3RyaW5nLnRyaW1Ub051bGwoc291cmNlT3B0aW9ucy5yZWYpID8geyByZWY6IHNvdXJjZU9wdGlvbnMucmVmIS50cmltKCkgfSA6IHt9KSxcbiAgfTtcbiAgcmV0dXJuIE9iamVjdC5rZXlzKHBvbGljeSkubGVuZ3RoID4gMCA/IHBvbGljeSA6IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBTdGFibGUgaWRlbnRpdHkgb2YgYSBzb3VyY2UgQU5EIGl0cyBjb250ZW50LWFmZmVjdGluZyBwb2xpY3kuXG4gKlxuICogS2V5aW5nIG9uIHRoZSBzb3VyY2UgYWxvbmUgd291bGQgbGV0IGEgY2hhbmdlZCBgc2tpbGxzYCBmaWx0ZXIgb3IgYHJlZmAgcmVhZFxuICogYmFjayB0aGUgcHJldmlvdXMgZG93bmxvYWQgZm9yIGEgZGF5OyBrZXlpbmcgb24gYm90aCB0dXJucyB0aGF0IGludG8gYSBtaXNzLlxuICogVGhlIHNraWxsIGxpc3QgaXMgc29ydGVkIGZpcnN0IHNvIGEgcmVvcmRlcmVkIGFycmF5IGlzIHN0aWxsIHRoZSBzYW1lIGtleS5cbiAqL1xuZnVuY3Rpb24gY2FjaGVLZXkoc291cmNlT3B0aW9uczogTm9ybWFsaXplZFNvdXJjZSk6IHN0cmluZyB7XG4gIHJldHVybiBoYXNoLmZudkhhc2goXG4gICAgSlNPTi5zdHJpbmdpZnkoeyBzb3VyY2U6IHNvdXJjZU9wdGlvbnMuc291cmNlLCBwb2xpY3k6IGNhY2hlUG9saWN5KHNvdXJjZU9wdGlvbnMpID8/IG51bGwgfSksXG4gICk7XG59XG5cbi8qKiBUaGUgZWZmZWN0aXZlIHJldXNlIHdpbmRvdzogcGVyLXNvdXJjZSwgdGhlbiB0b3AtbGV2ZWwsIHRoZW4gYSBkYXkuICovXG5mdW5jdGlvbiByZXNvbHZlUmVmcmVzaFR0bChcbiAgc291cmNlT3B0aW9uczogTm9ybWFsaXplZFNvdXJjZSxcbiAgb3B0aW9uczogUHJvdmlzaW9uUmVtb3RlU2tpbGxzT3B0aW9ucyxcbik6IG51bWJlciB7XG4gIHJldHVybiBzb3VyY2VPcHRpb25zLnJlZnJlc2hUdGxNcyA/PyBvcHRpb25zLnJlZnJlc2hUdGxNcyA/PyBERUZBVUxUX1JFRlJFU0hfVFRMX01TO1xufVxuXG4vKipcbiAqIFJlYWQgdGhlIG1ldGFkYXRhIGRvY3VtZW50IGF0IHRoZSByb290IG9mIGEgcHJvdmlzaW9uZWQgdHJlZSwgb3IgYHVuZGVmaW5lZGBcbiAqIHdoZW4gdGhlcmUgaXMgbm9uZSwgaXQgaXMgdW5yZWFkYWJsZSwgb3IgaXQgd2FzIHdyaXR0ZW4gYnkgYSBzaGFwZSB0aGlzXG4gKiB2ZXJzaW9uIGRvZXMgbm90IGtub3cuXG4gKlxuICogTmV2ZXIgdGhyb3dzOiBhIG1pc3Npbmcgb3IgY29ycnVwdCByZWNvcmQgaXMgYSBjYWNoZSBNSVNTLCB3aGljaCBjb3N0cyBhXG4gKiBkb3dubG9hZCAtIHdoaWxlIGxldHRpbmcgaXQgZmFpbCB3b3VsZCB0YWtlIGFwcCBzdGFydHVwIGRvd24gb3ZlclxuICogYm9va2tlZXBpbmcuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlYWRNZXRhZGF0YShmczogRmlsZVN5c3RlbSk6IFByb21pc2U8UmVtb3RlU2tpbGxzTWV0YWRhdGEgfCB1bmRlZmluZWQ+IHtcbiAgdHJ5IHtcbiAgICBpZiAoIShhd2FpdCBmcy5leGlzdHMoTUVUQURBVEFfRklMRSkpKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGNvbnN0IHJhdyA9IGF3YWl0IGZzLnJlYWRGaWxlKE1FVEFEQVRBX0ZJTEUsIHsgZW5jb2Rpbmc6IFwidXRmOFwiIH0pO1xuICAgIGNvbnN0IHBhcnNlZCA9IGpzb24ucGFyc2UocmF3LCB1bmRlZmluZWQpIGFzIFJlbW90ZVNraWxsc01ldGFkYXRhIHwgdW5kZWZpbmVkO1xuICAgIGlmICghb2JqZWN0LmlzUmVjb3JkKHBhcnNlZCkgfHwgcGFyc2VkLnZlcnNpb24gIT09IE1FVEFEQVRBX1ZFUlNJT04pIHJldHVybiB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIG9iamVjdC5pc1JlY29yZChwYXJzZWQuc291cmNlcykgPyBwYXJzZWQgOiB1bmRlZmluZWQ7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGxvZ2dlci5kZWJ1ZyhcImNhY2hlOnVucmVhZGFibGVcIiwgeyBlcnJvcjogZXJyb3IuZXJyb3JNZXNzYWdlKGVycikgfSk7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuXG4vKipcbiAqIFdoZXRoZXIgYW4gZW50cnkgaXMgc3RpbGwgaW5zaWRlIGl0cyByZXVzZSB3aW5kb3cuXG4gKlxuICogQSBgdHRsTXNgIG9mIGAwYCBkaXNhYmxlcyByZXVzZSBvdXRyaWdodCwgYW5kIGFuIHVucGFyc2VhYmxlIG9yIEZVVFVSRVxuICogdGltZXN0YW1wIGNvdW50cyBhcyBzdGFsZSAtIGEgY2xvY2sgdGhhdCBtb3ZlZCBiYWNrd2FyZHMgc2hvdWxkIGNvc3Qgb25lXG4gKiBleHRyYSBkb3dubG9hZCwgbm90IHBpbiBhIHRyZWUgYXMgZnJlc2ggaW5kZWZpbml0ZWx5LlxuICovXG5mdW5jdGlvbiBpc0ZyZXNoKGVudHJ5OiBSZW1vdGVTa2lsbENhY2hlRW50cnksIHR0bE1zOiBudW1iZXIpOiBib29sZWFuIHtcbiAgaWYgKHR0bE1zIDw9IDAgfHwgIUFycmF5LmlzQXJyYXkoZW50cnkuc2tpbGxzKSkgcmV0dXJuIGZhbHNlO1xuICBjb25zdCBkb3dubG9hZGVkQXQgPSBEYXRlLnBhcnNlKGVudHJ5LmRvd25sb2FkZWRBdCA/PyBcIlwiKTtcbiAgaWYgKE51bWJlci5pc05hTihkb3dubG9hZGVkQXQpKSByZXR1cm4gZmFsc2U7XG4gIGNvbnN0IGFnZSA9IERhdGUubm93KCkgLSBkb3dubG9hZGVkQXQ7XG4gIHJldHVybiBhZ2UgPj0gMCAmJiBhZ2UgPCB0dGxNcztcbn1cblxuLyoqXG4gKiBNZXJnZSBvbmUgc291cmNlJ3MgZW50cnkgaW50byB0aGUgdHJlZSdzIG1ldGFkYXRhIGRvY3VtZW50LCBwcmVzZXJ2aW5nIHdoYXRcbiAqIG90aGVyIHNvdXJjZXMgcmVjb3JkZWQgLSB0aGUgRGF0YWJyaWNrcyBkZXN0aW5hdGlvbiBpcyBTSEFSRUQsIHNvIGEgYmxpbmRcbiAqIG92ZXJ3cml0ZSB3b3VsZCBkcm9wIGV2ZXJ5IHNpYmxpbmcgc291cmNlJ3MgdGltZXN0YW1wIGFuZCByZS1kb3dubG9hZCB0aGVcbiAqIGxvdCBvbiB0aGUgbmV4dCBib290LlxuICovXG5hc3luYyBmdW5jdGlvbiB3cml0ZU1ldGFkYXRhKFxuICBmczogRmlsZVN5c3RlbSxcbiAga2V5OiBzdHJpbmcsXG4gIGVudHJ5OiBSZW1vdGVTa2lsbENhY2hlRW50cnksXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgY3VycmVudCA9IGF3YWl0IHJlYWRNZXRhZGF0YShmcyk7XG4gIGNvbnN0IG5leHQ6IFJlbW90ZVNraWxsc01ldGFkYXRhID0ge1xuICAgIHZlcnNpb246IE1FVEFEQVRBX1ZFUlNJT04sXG4gICAgc291cmNlczogeyAuLi5jdXJyZW50Py5zb3VyY2VzLCBba2V5XTogZW50cnkgfSxcbiAgfTtcbiAgYXdhaXQgZnMud3JpdGVGaWxlKE1FVEFEQVRBX0ZJTEUsIGAke0pTT04uc3RyaW5naWZ5KG5leHQsIG51bGwsIDIpfVxcbmAsIHsgb3ZlcndyaXRlOiB0cnVlIH0pO1xufVxuXG4vKiogVGhlIHN0YWJsZSBsb2NhbCB0cmVlIGEgc291cmNlIGlzIHJlYnVpbHQgaW50bywga2V5ZWQgYnkge0BsaW5rIGNhY2hlS2V5fS4gKi9cbmZ1bmN0aW9uIGxvY2FsU2tpbGxzRlMoa2V5OiBzdHJpbmcpOiBMb2NhbEZpbGVTeXN0ZW0ge1xuICByZXR1cm4gbG9jYWxGUy50bXBGUyhgJHtMT0NBTF9TS0lMTFNfRElSfS8ke2tleX1gKTtcbn1cblxuLyoqXG4gKiBNYXRlcmlhbGl6ZSBldmVyeSBjb25maWd1cmVkIHJlbW90ZSBza2lsbCBzb3VyY2UgYXQgYXBwIHN0YXJ0dXAuXG4gKlxuICogV3JpdGVzIGVhY2ggcmVzb2x2ZWQgYFNLSUxMLm1kYCB0cmVlIHRvIHRoZSBEYXRhYnJpY2tzIHVzZXIgQXNzaXN0YW50IHNraWxsc1xuICogZm9sZGVyIHdoZW4gYSB3cml0YWJsZSB3b3Jrc3BhY2UgaXMgYXZhaWxhYmxlLCBlbHNlIHVuZGVyXG4gKiB7QGxpbmsgbG9jYWxGUy50bXBGU30gcmV0dXJuZWQgaW4ge0BsaW5rIFByb3Zpc2lvbmVkUmVtb3RlU2tpbGxzLmxvY2FsU2tpbGxQYXRoc30uXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwcm92aXNpb25SZW1vdGVTa2lsbHMoXG4gIG9wdGlvbjogUmVtb3RlU2tpbGxzT3B0aW9uIHwgdW5kZWZpbmVkLFxuKTogUHJvbWlzZTxQcm92aXNpb25lZFJlbW90ZVNraWxscz4ge1xuICBjb25zdCBvcHRpb25zID0gbm9ybWFsaXplUmVtb3RlU2tpbGxzT3B0aW9uKG9wdGlvbik7XG4gIGNvbnN0IGVtcHR5OiBQcm92aXNpb25lZFJlbW90ZVNraWxscyA9IHsgbG9jYWxTa2lsbFBhdGhzOiBbXSwgc2tpbGxOYW1lczogW10gfTtcbiAgaWYgKCFvcHRpb25zKSByZXR1cm4gZW1wdHk7XG5cbiAgY29uc3QgZmFpbERlZmF1bHQgPSBvcHRpb25zLmZhaWxPbkVycm9yICE9PSBmYWxzZTtcbiAgY29uc3QgY2xpZW50ID0gb3B0aW9ucy5jbGllbnQgPz8gYXBwa2l0LnRyeUdldEV4ZWN1dGlvbkNvbnRleHQoKT8uY2xpZW50O1xuICBjb25zdCBkYXRhYnJpY2tzQmFzZVBhdGggPSByZXNvbHZlRGF0YWJyaWNrc0Jhc2VQYXRoKG9wdGlvbnMsIGNsaWVudCk7XG4gIGNvbnN0IGRlc3RpbmF0aW9uID0gZGF0YWJyaWNrc0Jhc2VQYXRoXG4gICAgPyBuZXcgRGF0YWJyaWNrc0ZpbGVTeXN0ZW0oe1xuICAgICAgICBjbGllbnQ6IGNsaWVudCBhcyBXb3Jrc3BhY2VDbGllbnQsXG4gICAgICAgIHJvb3Q6IGRhdGFicmlja3NCYXNlUGF0aCxcbiAgICAgICAgcmVhZE9ubHk6IGZhbHNlLFxuICAgICAgICBjcmVhdGVSb290OiB0cnVlLFxuICAgICAgfSlcbiAgICA6IHVuZGVmaW5lZDtcblxuICBjb25zdCBsb2NhbFNraWxsUGF0aHM6IHN0cmluZ1tdID0gW107XG4gIGNvbnN0IHNraWxsTmFtZXM6IHN0cmluZ1tdID0gW107XG4gIGxldCBzdGFnaW5nOiBMb2NhbEZpbGVTeXN0ZW0gfCB1bmRlZmluZWQ7XG5cbiAgLy8gVGhlIGRlc3RpbmF0aW9uIHJvb3RzIHRoZSBzaGFyZWQgbWV0YWRhdGEgZG9jdW1lbnQsIHNvIGl0IGhhcyB0byBleGlzdFxuICAvLyBiZWZvcmUgdGhlIGZpcnN0IGNhY2hlIFJFQUQgLSBgY29weVNraWxsRGlyc2Agd291bGQgb3RoZXJ3aXNlIGJlIHRoZSBmaXJzdFxuICAvLyB0aGluZyB0byBjcmVhdGUgaXQsIHdoaWNoIGlzIHRvbyBsYXRlLlxuICBpZiAoZGVzdGluYXRpb24pIGF3YWl0IGRlc3RpbmF0aW9uLmluaXQoKTtcblxuICB0cnkge1xuICAgIGNvbnN0IHNvdXJjZXMgPSBBcnJheS5pc0FycmF5KG9wdGlvbnMuc291cmNlcykgPyBvcHRpb25zLnNvdXJjZXMgOiBbb3B0aW9ucy5zb3VyY2VzXTtcbiAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIHNvdXJjZXMpIHtcbiAgICAgIGNvbnN0IHNvdXJjZU9wdGlvbnMgPSB0b1NvdXJjZU9wdGlvbnMoZW50cnkpO1xuICAgICAgY29uc3QgZmFpbE9uRXJyb3IgPSBzb3VyY2VPcHRpb25zLmZhaWxPbkVycm9yID8/IGZhaWxEZWZhdWx0O1xuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gV2hlcmUgdGhpcyBzb3VyY2UncyBib29ra2VlcGluZyBsaXZlczogdGhlIHNoYXJlZCBEYXRhYnJpY2tzIHRyZWUsIG9yXG4gICAgICAgIC8vIHRoZSBzb3VyY2UncyBvd24gc3RhYmxlIGxvY2FsIGRpci5cbiAgICAgICAgY29uc3Qga2V5ID0gY2FjaGVLZXkoc291cmNlT3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IGNhY2hlRlMgPSBkZXN0aW5hdGlvbiA/PyBsb2NhbFNraWxsc0ZTKGtleSk7XG4gICAgICAgIGNvbnN0IGNhY2hlZCA9IChhd2FpdCByZWFkTWV0YWRhdGEoY2FjaGVGUykpPy5zb3VyY2VzW2tleV07XG4gICAgICAgIGlmIChjYWNoZWQgJiYgaXNGcmVzaChjYWNoZWQsIHJlc29sdmVSZWZyZXNoVHRsKHNvdXJjZU9wdGlvbnMsIG9wdGlvbnMpKSkge1xuICAgICAgICAgIHNraWxsTmFtZXMucHVzaCguLi5jYWNoZWQuc2tpbGxzKTtcbiAgICAgICAgICBpZiAoIWRlc3RpbmF0aW9uKSBsb2NhbFNraWxsUGF0aHMucHVzaChjYWNoZUZTLnJvb3QpO1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhcInNvdXJjZTpjYWNoZWRcIiwge1xuICAgICAgICAgICAgc291cmNlOiBzb3VyY2VPcHRpb25zLnNvdXJjZSxcbiAgICAgICAgICAgIGRvd25sb2FkZWRBdDogY2FjaGVkLmRvd25sb2FkZWRBdCxcbiAgICAgICAgICAgIHNraWxsczogY2FjaGVkLnNraWxscyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0YWdpbmcgPz89IGF3YWl0IGluaXRpYWxpemVkU2NyYXRjaChcIm1hc3RyYS1yZW1vdGUtc2tpbGxzXCIpO1xuICAgICAgICBjb25zdCBzdGFnZWREaXIgPSBhd2FpdCBzdGFnZVNvdXJjZShzb3VyY2VPcHRpb25zLCBzdGFnaW5nLnJvb3QsIG9wdGlvbnMpO1xuICAgICAgICBjb25zdCBzdGFnZWQgPSBhd2FpdCBjb2xsZWN0U2tpbGxEaXJzKHN0YWdlZERpcik7XG4gICAgICAgIGlmIChzdGFnZWQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBubyBTS0lMTC5tZCBmb3VuZCBmb3Igc291cmNlIFwiJHtzb3VyY2VPcHRpb25zLnNvdXJjZX1cImApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBvbGljeSA9IGNhY2hlUG9saWN5KHNvdXJjZU9wdGlvbnMpO1xuICAgICAgICBjb25zdCByZWNvcmQ6IFJlbW90ZVNraWxsQ2FjaGVFbnRyeSA9IHtcbiAgICAgICAgICBzb3VyY2U6IHNvdXJjZU9wdGlvbnMuc291cmNlLFxuICAgICAgICAgIGRvd25sb2FkZWRBdDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgIHNraWxsczogc3RhZ2VkLm1hcCgoZGlyKSA9PiBkaXIubmFtZSksXG4gICAgICAgICAgLi4uKHBvbGljeSA/IHsgcG9saWN5IH0gOiB7fSksXG4gICAgICAgIH07XG4gICAgICAgIGlmIChkZXN0aW5hdGlvbiAmJiBkYXRhYnJpY2tzQmFzZVBhdGgpIHtcbiAgICAgICAgICBhd2FpdCBjb3B5U2tpbGxEaXJzKGRlc3RpbmF0aW9uLCBzdGFnZWQpO1xuICAgICAgICAgIC8vIE9ubHkgYWZ0ZXIgdGhlIGNvcHkgbGFuZHM6IGEgbWV0YWRhdGEgZW50cnkgd3JpdHRlbiBmaXJzdCB3b3VsZFxuICAgICAgICAgIC8vIG1hcmsgYSBmYWlsZWQgcHJvdmlzaW9uIGFzIGZyZXNoIGFuZCBzdXBwcmVzcyB0aGUgcmV0cnkgZm9yIGEgZGF5LlxuICAgICAgICAgIGF3YWl0IHdyaXRlTWV0YWRhdGEoZGVzdGluYXRpb24sIGtleSwgcmVjb3JkKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsb2NhbFNraWxsUGF0aHMucHVzaChhd2FpdCBwZXJzaXN0TG9jYWxseShrZXksIHN0YWdlZCwgcmVjb3JkKSk7XG4gICAgICAgIH1cbiAgICAgICAgc2tpbGxOYW1lcy5wdXNoKC4uLnJlY29yZC5za2lsbHMpO1xuICAgICAgICBsb2dnZXIuZGVidWcoXCJzb3VyY2U6cHJvdmlzaW9uZWRcIiwge1xuICAgICAgICAgIHNvdXJjZTogc291cmNlT3B0aW9ucy5zb3VyY2UsXG4gICAgICAgICAgZGVzdGluYXRpb246IGRhdGFicmlja3NCYXNlUGF0aCA/PyBcImxvY2FsLXRlbXBcIixcbiAgICAgICAgICBza2lsbHM6IHJlY29yZC5za2lsbHMsXG4gICAgICAgIH0pO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGlmIChmYWlsT25FcnJvcikge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgIGBmYWlsZWQgdG8gcHJvdmlzaW9uIHJlbW90ZSBza2lsbCBzb3VyY2UgXCIke3NvdXJjZU9wdGlvbnMuc291cmNlfVwiOiAke2Vycm9yLmVycm9yTWVzc2FnZShlcnIpfWAsXG4gICAgICAgICAgICB7IGNhdXNlOiBlcnJvci50b0Vycm9yKGVycikgfSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGxvZ2dlci53YXJuKFwic291cmNlOnNraXBwZWRcIiwge1xuICAgICAgICAgIHNvdXJjZTogc291cmNlT3B0aW9ucy5zb3VyY2UsXG4gICAgICAgICAgZXJyb3I6IGVycm9yLmVycm9yTWVzc2FnZShlcnIpLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZmluYWxseSB7XG4gICAgaWYgKHN0YWdpbmcpIHtcbiAgICAgIGF3YWl0IHJtKHN0YWdpbmcucm9vdCwgeyByZWN1cnNpdmU6IHRydWUsIGZvcmNlOiB0cnVlIH0pLmNhdGNoKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsgbG9jYWxTa2lsbFBhdGhzLCBkYXRhYnJpY2tzQmFzZVBhdGgsIHNraWxsTmFtZXMgfTtcbn1cblxuLyoqIFJlc29sdmUgdGhlIERhdGFicmlja3MgQXNzaXN0YW50IHNraWxscyBkZXN0aW5hdGlvbiwgb3IgYHVuZGVmaW5lZGAgZm9yIGxvY2FsIHRlbXAuICovXG5mdW5jdGlvbiByZXNvbHZlRGF0YWJyaWNrc0Jhc2VQYXRoKFxuICBvcHRpb25zOiBQcm92aXNpb25SZW1vdGVTa2lsbHNPcHRpb25zLFxuICBjbGllbnQ6IFdvcmtzcGFjZUNsaWVudExpa2UgfCB1bmRlZmluZWQsXG4pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBpZiAoIWNsaWVudCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgaWYgKG9wdGlvbnMuZGF0YWJyaWNrc0Jhc2VQYXRoKSByZXR1cm4gb3B0aW9ucy5kYXRhYnJpY2tzQmFzZVBhdGgudHJpbSgpIHx8IHVuZGVmaW5lZDtcbiAgY29uc3QgZW1haWwgPSBzdHJpbmcudHJpbVRvTnVsbChvcHRpb25zLnVzZXJFbWFpbCk7XG4gIC8vIEEgbmFtZWQgdXNlciB0YXJnZXRzIHRoZWlyIHBlcnNvbmFsIEFzc2lzdGFudCB0cmVlICh0aGUgXCJzYXZlIGEgc2tpbGxcIlxuICAvLyB0YXJnZXQpOyBvdGhlcndpc2UgdGhlIHNoYXJlZCB3b3Jrc3BhY2UgQXNzaXN0YW50IHRyZWUsIHdoaWNoIHRoZSBidWlsdC1pblxuICAvLyBBc3Npc3RhbnQtc2tpbGxzIG1vdW50IGFscmVhZHkgc2NhbnMuXG4gIHJldHVybiBlbWFpbCA/IHVzZXJBc3Npc3RhbnRTa2lsbHNQYXRoKGVtYWlsKSA6IEFTU0lTVEFOVF9TSEFSRURfU0tJTExTX1BBVEg7XG59XG5cbi8qKlxuICogU3RhZ2Ugb25lIHNvdXJjZSBpbnRvIGEgZnJlc2ggZGlyIHVuZGVyIGBzdGFnaW5nUm9vdGAsIHByZWZlcnJpbmcgdGhlIG9wdGlvbmFsXG4gKiBgc2tpbGxzYCBDTEkgYW5kIGZhbGxpbmcgYmFjayB0byBhIGRpcmVjdCBmZXRjaC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gc3RhZ2VTb3VyY2UoXG4gIHNvdXJjZU9wdGlvbnM6IE5vcm1hbGl6ZWRTb3VyY2UsXG4gIHN0YWdpbmdSb290OiBzdHJpbmcsXG4gIG9wdGlvbnM6IFByb3Zpc2lvblJlbW90ZVNraWxsc09wdGlvbnMsXG4pOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCB0YXJnZXQgPSBqb2luKHN0YWdpbmdSb290LCBgc3JjLSR7aGFzaC5pZCgpfWApO1xuICBhd2FpdCBta2Rpcih0YXJnZXQsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAvLyBBSSBUb29scyByZXNvbHZlcyBmcm9tIGEga25vd24gcmVwbyBsYXlvdXQsIHNvIGl0IG5ldmVyIG5lZWRzIHRoZSBDTEkuXG4gIGlmIChpc0FpVG9vbHNTb3VyY2Uoc291cmNlT3B0aW9ucy5zb3VyY2UpKSByZXR1cm4gc3RhZ2VBaVRvb2xzKHNvdXJjZU9wdGlvbnMsIHRhcmdldCwgb3B0aW9ucyk7XG4gIGNvbnN0IHZpYUNsaSA9IGF3YWl0IHN0YWdlVmlhU2tpbGxzQ2xpKHNvdXJjZU9wdGlvbnMsIHRhcmdldCk7XG4gIGlmICh2aWFDbGkpIHJldHVybiB2aWFDbGk7XG4gIHJldHVybiBzdGFnZVZpYUZldGNoKHNvdXJjZU9wdGlvbnMsIHRhcmdldCwgb3B0aW9ucyk7XG59XG5cbi8qKlxuICogTWF0ZXJpYWxpemUgdGhlIERhdGFicmlja3MgQUkgVG9vbHMgc2tpbGxzIGludG8gYHRhcmdldGAuXG4gKlxuICogUmVhZHMgdGhlIHJlcG8ncyBvd24gZ2VuZXJhdGVkIGBtYW5pZmVzdC5qc29uYCAod2hpY2ggbmFtZXMgZWFjaCBza2lsbCdzXG4gKiBmaWxlcyBhbmQgd2hldGhlciBpdCBsaXZlcyB1bmRlciBgc2tpbGxzL2Agb3IgYGV4cGVyaW1lbnRhbC9gKSBhbmQgZG93bmxvYWRzXG4gKiB0aGVtIC0gdGhlIHNhbWUgdGhpbmcgYGRhdGFicmlja3MgYWl0b29scyBpbnN0YWxsYCBkb2VzLCBtaW51cyB0aGUgQ0xJIGFuZFxuICogbWludXMgYW55IERhdGFicmlja3MgYXV0aCwgc2luY2UgdGhlIHJlcG8gaXMgcHVibGljLlxuICovXG5hc3luYyBmdW5jdGlvbiBzdGFnZUFpVG9vbHMoXG4gIHNvdXJjZU9wdGlvbnM6IE5vcm1hbGl6ZWRTb3VyY2UsXG4gIHRhcmdldDogc3RyaW5nLFxuICBvcHRpb25zOiBQcm92aXNpb25SZW1vdGVTa2lsbHNPcHRpb25zLFxuKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc3QgbWF4Qnl0ZXMgPSByZXNvbHZlTWF4Qnl0ZXMoc291cmNlT3B0aW9ucywgb3B0aW9ucyk7XG4gIGNvbnN0IHJlZiA9IHN0cmluZy50cmltVG9OdWxsKHNvdXJjZU9wdGlvbnMucmVmKSA/PyBBSVRPT0xTX1JFRjtcbiAgY29uc3QgbWFuaWZlc3QgPSBqc29uLnBhcnNlKFxuICAgIChhd2FpdCBkb3dubG9hZChhaVRvb2xzUmF3VXJsKHJlZiwgXCJtYW5pZmVzdC5qc29uXCIpLCBtYXhCeXRlcykpLnRvU3RyaW5nKFwidXRmOFwiKSxcbiAgICB1bmRlZmluZWQsXG4gICkgYXMgQWlUb29sc01hbmlmZXN0IHwgdW5kZWZpbmVkO1xuXG4gIGNvbnN0IHdhbnRlZCA9IG5ldyBTZXQoc3RyaW5nLnBhcnNlTGlzdChzb3VyY2VPcHRpb25zLnNraWxscykpO1xuICBjb25zdCBzZWxlY3RlZCA9IE9iamVjdC5lbnRyaWVzKG1hbmlmZXN0Py5za2lsbHMgPz8ge30pLmZpbHRlcigoW25hbWUsIGVudHJ5XSkgPT5cbiAgICB3YW50ZWQuc2l6ZSA+IDBcbiAgICAgID8gd2FudGVkLmhhcyhuYW1lKVxuICAgICAgOiBlbnRyeS5yZXBvX2RpciAhPT0gXCJleHBlcmltZW50YWxcIiB8fCBzb3VyY2VPcHRpb25zLmV4cGVyaW1lbnRhbCA9PT0gdHJ1ZSxcbiAgKTtcbiAgaWYgKHNlbGVjdGVkLmxlbmd0aCA9PT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgbm8gbWF0Y2hpbmcgc2tpbGxzIGluICR7QUlUT09MU19SRVBPfUAke3JlZn1gKTtcbiAgfVxuXG4gIGNvbnN0IGZpbGVzID0gc2VsZWN0ZWQuZmxhdE1hcCgoW25hbWUsIGVudHJ5XSkgPT5cbiAgICAoZW50cnkuZmlsZXMgPz8gW10pLm1hcCgoZmlsZSkgPT4gKHtcbiAgICAgIHVybDogYWlUb29sc1Jhd1VybChyZWYsIGAke2VudHJ5LnJlcG9fZGlyID8/IFwic2tpbGxzXCJ9LyR7bmFtZX0vJHtmaWxlfWApLFxuICAgICAgcGF0aDogam9pbih0YXJnZXQsIG5hbWUsIC4uLmZpbGUuc3BsaXQoXCIvXCIpKSxcbiAgICB9KSksXG4gICk7XG4gIGF3YWl0IG1hcENvbmN1cnJlbnQoZmlsZXMsIEFJVE9PTFNfQ09OQ1VSUkVOQ1ksIGFzeW5jIChpdGVtKSA9PiB7XG4gICAgY29uc3QgYm9keSA9IGF3YWl0IGRvd25sb2FkKGl0ZW0udXJsLCBtYXhCeXRlcyk7XG4gICAgYXdhaXQgbWtkaXIoZGlybmFtZShpdGVtLnBhdGgpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICBhd2FpdCB3cml0ZUZpbGUoaXRlbS5wYXRoLCBib2R5KTtcbiAgfSk7XG5cbiAgbG9nZ2VyLmRlYnVnKFwiYWl0b29sczpzdGFnZWRcIiwgeyByZWYsIHNraWxsczogc2VsZWN0ZWQubGVuZ3RoLCBmaWxlczogZmlsZXMubGVuZ3RoIH0pO1xuICByZXR1cm4gdGFyZ2V0O1xufVxuXG4vKiogUmF3LWNvbnRlbnQgVVJMIGZvciBhIHBhdGggaW4gdGhlIEFJIFRvb2xzIHJlcG8gYXQgYHJlZmAuICovXG5mdW5jdGlvbiBhaVRvb2xzUmF3VXJsKHJlZjogc3RyaW5nLCBwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS8ke0FJVE9PTFNfUkVQT30vJHtyZWZ9LyR7cGF0aH1gO1xufVxuXG4vKiogUnVuIGB3b3JrZXJgIG92ZXIgYGl0ZW1zYCwgYXQgbW9zdCBgbGltaXRgIGluIGZsaWdodC4gKi9cbmFzeW5jIGZ1bmN0aW9uIG1hcENvbmN1cnJlbnQ8VD4oXG4gIGl0ZW1zOiByZWFkb25seSBUW10sXG4gIGxpbWl0OiBudW1iZXIsXG4gIHdvcmtlcjogKGl0ZW06IFQpID0+IFByb21pc2U8dm9pZD4sXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgbGV0IGN1cnNvciA9IDA7XG4gIGNvbnN0IHJ1bm5lcnMgPSBBcnJheS5mcm9tKHsgbGVuZ3RoOiBNYXRoLm1pbihsaW1pdCwgaXRlbXMubGVuZ3RoKSB9LCBhc3luYyAoKSA9PiB7XG4gICAgd2hpbGUgKGN1cnNvciA8IGl0ZW1zLmxlbmd0aCkge1xuICAgICAgYXdhaXQgd29ya2VyKGl0ZW1zW2N1cnNvcisrXSEpO1xuICAgIH1cbiAgfSk7XG4gIGF3YWl0IFByb21pc2UuYWxsKHJ1bm5lcnMpO1xufVxuXG4vKipcbiAqIENvcHkgYSBzb3VyY2UgaW50byBgdGFyZ2V0YCB3aXRoIHRoZSBgc2tpbGxzYCBDTEkgd2hlbiBpdCBpcyBpbnN0YWxsZWQuXG4gKiBSZXR1cm5zIHRoZSBkaXIgaG9sZGluZyB0aGUgY29waWVkIGBTS0lMTC5tZGAgdHJlZXMsIG9yIGB1bmRlZmluZWRgIHdoZW4gdGhlXG4gKiBDTEkgaXMgYWJzZW50IChzbyB0aGUgY2FsbGVyIGNhbiBmYWxsIGJhY2sgdG8gYSBmZXRjaCkuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHN0YWdlVmlhU2tpbGxzQ2xpKFxuICBzb3VyY2VPcHRpb25zOiBOb3JtYWxpemVkU291cmNlLFxuICB0YXJnZXQ6IHN0cmluZyxcbik6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gIGNvbnN0IGNsaSA9IGF3YWl0IHJlc29sdmVTa2lsbHNDbGkoKTtcbiAgaWYgKCFjbGkpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgY29uc3QgYXJncyA9IFtcbiAgICAuLi5jbGkuYXJncyxcbiAgICBcImFkZFwiLFxuICAgIHNvdXJjZU9wdGlvbnMuc291cmNlLFxuICAgIFwiLS1hZ2VudFwiLFxuICAgIFNLSUxMU19DTElfQUdFTlQsXG4gICAgXCItLWNvcHlcIixcbiAgICBcIi15XCIsXG4gIF07XG4gIGZvciAoY29uc3Qgc2tpbGwgb2Ygc3RyaW5nLnBhcnNlTGlzdChzb3VyY2VPcHRpb25zLnNraWxscykpIHtcbiAgICBhcmdzLnB1c2goXCItLXNraWxsXCIsIHNraWxsKTtcbiAgfVxuICBpZiAoc3RyaW5nLnBhcnNlTGlzdChzb3VyY2VPcHRpb25zLnNraWxscykubGVuZ3RoID09PSAwKSBhcmdzLnB1c2goXCItLXNraWxsXCIsIFwiKlwiKTtcblxuICBjb25zdCByZXN1bHQgPSBhd2FpdCBleGVjLnNwYXduKGNsaS5jb21tYW5kLCBhcmdzLCB7XG4gICAgY3dkOiB0YXJnZXQsXG4gICAgc3Rkb3V0OiBcImNhcHR1cmVcIixcbiAgICBzdGRlcnI6IFwiY2FwdHVyZVwiLFxuICAgIGNoZWNrOiBmYWxzZSxcbiAgfSk7XG4gIGlmIChyZXN1bHQuZXhpdENvZGUgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgc2tpbGxzIENMSSBmYWlsZWQgKGV4aXQgJHtyZXN1bHQuZXhpdENvZGV9KTogJHtyZXN1bHQuc3RkZXJyIHx8IHJlc3VsdC5zdGRvdXR9YCxcbiAgICApO1xuICB9XG4gIHJldHVybiBqb2luKHRhcmdldCwgLi4uU0tJTExTX0NMSV9MQVlPVVQpO1xufVxuXG4vKipcbiAqIExvY2F0ZSB0aGUgb3B0aW9uYWwgYHNraWxsc2AgQ0xJIGJpbiwgcmVzb2x2ZWQgZnJvbSBUSElTIHBhY2thZ2UncyBtb2R1bGVcbiAqIGdyYXBoLiBSZXR1cm5zIGB1bmRlZmluZWRgIHdoZW4gdGhlIHBlZXIgZGVwIGlzbid0IGluc3RhbGxlZCwgc28gdGhlIGNhbGxlclxuICogZmFsbHMgYmFjayB0byBhIGRpcmVjdCBmZXRjaC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZVNraWxsc0NsaSgpOiBQcm9taXNlPHsgY29tbWFuZDogc3RyaW5nOyBhcmdzOiBzdHJpbmdbXSB9IHwgdW5kZWZpbmVkPiB7XG4gIHRyeSB7XG4gICAgY29uc3QgcmVxdWlyZSA9IGNyZWF0ZVJlcXVpcmUoaW1wb3J0Lm1ldGEudXJsKTtcbiAgICBjb25zdCBwa2dQYXRoID0gcmVxdWlyZS5yZXNvbHZlKFwic2tpbGxzL3BhY2thZ2UuanNvblwiKTtcbiAgICBjb25zdCBiaW4gPSBqb2luKHBrZ1BhdGgsIFwiLi5cIiwgXCJiaW5cIiwgXCJjbGkubWpzXCIpO1xuICAgIGlmIChhd2FpdCBwYXRoRXhpc3RzKGJpbikpIHJldHVybiB7IGNvbW1hbmQ6IHByb2Nlc3MuZXhlY1BhdGgsIGFyZ3M6IFtiaW5dIH07XG4gIH0gY2F0Y2gge1xuICAgIC8vIHBlZXIgZGVwIGFic2VudCBvciB1bnJlc29sdmFibGUgLSBmZXRjaCBmYWxsYmFjayBoYW5kbGVzIGl0XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBGZXRjaCBhIHNvdXJjZSBVUkwgYW5kIHdyaXRlIHRoZSBkb3dubG9hZGVkIGBTS0lMTC5tZGAgdW5kZXIgYHRhcmdldGAuXG4gKiBVc2VkIHdoZW4gdGhlIGBza2lsbHNgIENMSSBpc24ndCBpbnN0YWxsZWQ7IHN1cHBvcnRzIGEgZGlyZWN0IGBTS0lMTC5tZGAgVVJMLlxuICovXG5hc3luYyBmdW5jdGlvbiBzdGFnZVZpYUZldGNoKFxuICBzb3VyY2VPcHRpb25zOiBOb3JtYWxpemVkU291cmNlLFxuICB0YXJnZXQ6IHN0cmluZyxcbiAgb3B0aW9uczogUHJvdmlzaW9uUmVtb3RlU2tpbGxzT3B0aW9ucyxcbik6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IHVybCA9IG5ldC51cmxCdWlsZGVyKHNvdXJjZU9wdGlvbnMuc291cmNlKTtcbiAgaWYgKCF1cmwpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgc291cmNlIFwiJHtzb3VyY2VPcHRpb25zLnNvdXJjZX1cIiBpcyBub3QgYSBVUkwgYW5kIHRoZSBvcHRpb25hbCBcInNraWxsc1wiIHBhY2thZ2UgaXMgbm90IGluc3RhbGxlZGAsXG4gICAgKTtcbiAgfVxuICBjb25zdCBidWZmZXIgPSBhd2FpdCBkb3dubG9hZCh1cmwudG9TdHJpbmcoKSwgcmVzb2x2ZU1heEJ5dGVzKHNvdXJjZU9wdGlvbnMsIG9wdGlvbnMpKTtcbiAgY29uc3QgbmFtZSA9IHN0cmluZy50b1NsdWcoZGVyaXZlU2tpbGxOYW1lKHVybC50b1N0cmluZygpKSkgfHwgXCJyZW1vdGUtc2tpbGxcIjtcbiAgY29uc3Qgc2tpbGxEaXIgPSBqb2luKHRhcmdldCwgbmFtZSk7XG4gIGF3YWl0IG1rZGlyKHNraWxsRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgYXdhaXQgd3JpdGVGaWxlKGpvaW4oc2tpbGxEaXIsIFwiU0tJTEwubWRcIiksIGJ1ZmZlcik7XG4gIHJldHVybiB0YXJnZXQ7XG59XG5cbi8qKiBUaGUgZWZmZWN0aXZlIGRvd25sb2FkIGNlaWxpbmc6IHBlci1zb3VyY2UsIHRoZW4gdG9wLWxldmVsLCB0aGVuIHRoZSBkZWZhdWx0LiAqL1xuZnVuY3Rpb24gcmVzb2x2ZU1heEJ5dGVzKFxuICBzb3VyY2VPcHRpb25zOiBOb3JtYWxpemVkU291cmNlLFxuICBvcHRpb25zOiBQcm92aXNpb25SZW1vdGVTa2lsbHNPcHRpb25zLFxuKTogbnVtYmVyIHtcbiAgcmV0dXJuIHNvdXJjZU9wdGlvbnMubWF4RG93bmxvYWRCeXRlcyA/PyBvcHRpb25zLm1heERvd25sb2FkQnl0ZXMgPz8gREVGQVVMVF9NQVhfRE9XTkxPQURfQllURVM7XG59XG5cbi8qKiBHRVQgYSBVUkwsIGZhaWxpbmcgbG91ZGx5IG9uIGEgbm9uLTJ4eCBzdGF0dXMgb3IgYW4gb3ZlcnNpemVkIGJvZHkuICovXG5hc3luYyBmdW5jdGlvbiBkb3dubG9hZCh1cmw6IHN0cmluZywgbWF4Qnl0ZXM6IG51bWJlcik6IFByb21pc2U8QnVmZmVyPiB7XG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsKTtcbiAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgIHRocm93IG5ldyBFcnJvcihgZG93bmxvYWQgZmFpbGVkOiAke3Jlc3BvbnNlLnN0YXR1c30gJHtyZXNwb25zZS5zdGF0dXNUZXh0fSAoJHt1cmx9KWApO1xuICB9XG4gIGNvbnN0IGJ1ZmZlciA9IEJ1ZmZlci5mcm9tKGF3YWl0IHJlc3BvbnNlLmFycmF5QnVmZmVyKCkpO1xuICBpZiAoYnVmZmVyLmJ5dGVMZW5ndGggPiBtYXhCeXRlcykge1xuICAgIHRocm93IG5ldyBFcnJvcihgZG93bmxvYWQgZXhjZWVkcyAke21heEJ5dGVzfSBieXRlcyAoJHt1cmx9KWApO1xuICB9XG4gIHJldHVybiBidWZmZXI7XG59XG5cbi8qKiBEZXJpdmUgYSBza2lsbCBkaXJlY3RvcnkgbmFtZSBmcm9tIGEgZG93bmxvYWQgVVJMJ3MgbGFzdCBwYXRoIHNlZ21lbnQuICovXG5mdW5jdGlvbiBkZXJpdmVTa2lsbE5hbWUodXJsU3RyaW5nOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCB1cmwgPSBuZXQudXJsQnVpbGRlcih1cmxTdHJpbmcpO1xuICBjb25zdCBsYXN0ID0gdXJsPy5wYXRobmFtZS5zcGxpdChcIi9cIikuZmlsdGVyKEJvb2xlYW4pLnBvcCgpID8/IFwiXCI7XG4gIHJldHVybiBsYXN0LnJlcGxhY2UoL1xcLihtZHx6aXB8dGFyfHRnenxneikkL2ksIFwiXCIpO1xufVxuXG4vKiogQSBza2lsbCBkaXJlY3RvcnkgKGhvbGRpbmcgYSBgU0tJTEwubWRgKSBzdGFnZWQgb24gbG9jYWwgZGlzay4gKi9cbmludGVyZmFjZSBTdGFnZWRTa2lsbERpciB7XG4gIG5hbWU6IHN0cmluZztcbiAgYWJzb2x1dGVQYXRoOiBzdHJpbmc7XG59XG5cbi8qKlxuICogQ29sbGVjdCBldmVyeSBza2lsbCBkaXJlY3RvcnkgdW5kZXIgYHJvb3RgOiBhIGByb290L1NLSUxMLm1kYCAocm9vdCBJUyB0aGVcbiAqIHNraWxsKSBvciBlYWNoIGltbWVkaWF0ZSBjaGlsZCBkaXIgdGhhdCBjb250YWlucyBhIGBTS0lMTC5tZGAuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGNvbGxlY3RTa2lsbERpcnMocm9vdDogc3RyaW5nKTogUHJvbWlzZTxTdGFnZWRTa2lsbERpcltdPiB7XG4gIGlmICghKGF3YWl0IHBhdGhFeGlzdHMocm9vdCkpKSByZXR1cm4gW107XG4gIGlmIChhd2FpdCBwYXRoRXhpc3RzKGpvaW4ocm9vdCwgXCJTS0lMTC5tZFwiKSkpIHtcbiAgICBjb25zdCBuYW1lID0gcG9zaXguYmFzZW5hbWUocm9vdC5zcGxpdCgvW1xcXFwvXS8pLmpvaW4oXCIvXCIpKTtcbiAgICByZXR1cm4gW3sgbmFtZSwgYWJzb2x1dGVQYXRoOiByb290IH1dO1xuICB9XG4gIGNvbnN0IGRpcnM6IFN0YWdlZFNraWxsRGlyW10gPSBbXTtcbiAgZm9yIChjb25zdCBlbnRyeSBvZiBhd2FpdCByZWFkZGlyKHJvb3QsIHsgd2l0aEZpbGVUeXBlczogdHJ1ZSB9KSkge1xuICAgIGlmICghZW50cnkuaXNEaXJlY3RvcnkoKSkgY29udGludWU7XG4gICAgY29uc3QgZGlyID0gam9pbihyb290LCBlbnRyeS5uYW1lKTtcbiAgICBpZiAoYXdhaXQgcGF0aEV4aXN0cyhqb2luKGRpciwgXCJTS0lMTC5tZFwiKSkpIHtcbiAgICAgIGRpcnMucHVzaCh7IG5hbWU6IGVudHJ5Lm5hbWUsIGFic29sdXRlUGF0aDogZGlyIH0pO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZGlycztcbn1cblxuLyoqXG4gKiBDb3B5IGV2ZXJ5IHN0YWdlZCBza2lsbCBkaXJlY3RvcnkgaW50byB7QGxpbmsgZGVzdGluYXRpb259LCBwcmVzZXJ2aW5nIHRoZVxuICogYDxza2lsbD4vPHJlbGF0aXZlPmAgbGF5b3V0LiBUaGUgZGVzdGluYXRpb24gaXMganVzdCBhIHtAbGluayBGaWxlU3lzdGVtfSxcbiAqIHNvIHRoZSBEYXRhYnJpY2tzIEFzc2lzdGFudCB0cmVlIGFuZCB0aGUgbG9jYWwgZmFsbGJhY2sgc2hhcmUgb25lIGNvcGllci5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gY29weVNraWxsRGlycyhkZXN0aW5hdGlvbjogRmlsZVN5c3RlbSwgZGlyczogU3RhZ2VkU2tpbGxEaXJbXSk6IFByb21pc2U8dm9pZD4ge1xuICBhd2FpdCBkZXN0aW5hdGlvbi5pbml0KCk7XG4gIGZvciAoY29uc3QgZGlyIG9mIGRpcnMpIHtcbiAgICBmb3IgKGNvbnN0IHJlbGF0aXZlIG9mIGZpbmQuZmluZEZpbGVzKFwiKiovKlwiLCB7IGN3ZDogZGlyLmFic29sdXRlUGF0aCwgbm9kaXI6IHRydWUgfSkpIHtcbiAgICAgIGNvbnN0IGJ1ZmZlciA9IGF3YWl0IHJlYWRGaWxlKGpvaW4oZGlyLmFic29sdXRlUGF0aCwgcmVsYXRpdmUpKTtcbiAgICAgIGNvbnN0IHNraWxsUGF0aCA9IHBvc2l4LmpvaW4oZGlyLm5hbWUsIHJlbGF0aXZlLnNwbGl0KC9bXFxcXC9dLykuam9pbihcIi9cIikpO1xuICAgICAgYXdhaXQgZGVzdGluYXRpb24ud3JpdGVGaWxlKHNraWxsUGF0aCwgYnVmZmVyLCB7IG92ZXJ3cml0ZTogdHJ1ZSB9KTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBDb3B5IHN0YWdlZCBza2lsbCBkaXJzIGludG8gYSBTVEFCTEUgbG9jYWwgdHJlZSBrZXllZCBieSB0aGUgc291cmNlLCBhbmRcbiAqIHJldHVybiBpdHMgcm9vdCBwYXRoLlxuICpcbiAqIEEgZ2l2ZW4gc291cmNlIHJlc29sdmVzIHRvIHRoZSBzYW1lIGNvbnRlbnQgb24gYWxtb3N0IGV2ZXJ5IGJvb3QsIHNvIGVhY2hcbiAqIG9uZSBvd25zIGEgZGlyZWN0b3J5IG5hbWVkIGZvciBpdHMge0BsaW5rIGNhY2hlS2V5fSByYXRoZXIgdGhhbiBsZWF2aW5nIGFcbiAqIGZyZXNoIHNjcmF0Y2ggZGlyIGJlaGluZCBwZXIgcmVzdGFydC4gS2V5aW5nIG9uIHRoZSBzb3VyY2UgYW5kIGl0cyBwb2xpY3lcbiAqIChub3QgdGhlIGNvbnRlbnQpIGlzIHdoYXQga2VlcHMgdHdvIGRpZmZlcmVudCBzb3VyY2VzIGZyb20gb3ZlcndyaXRpbmcgZWFjaFxuICogb3RoZXIuXG4gKlxuICogVGhlIG1ldGFkYXRhIGlzIHdyaXR0ZW4gSU5TSURFIHRoZSByZWJ1aWxkIHJhdGhlciB0aGFuIGFmdGVyIGl0OiBgcmVidWlsZEZTYFxuICogcmVwbGFjZXMgdGhlIHN0YWJsZSByb290IHdob2xlc2FsZSwgc28gYW55dGhpbmcgd3JpdHRlbiBhZnRlcndhcmRzIHdvdWxkXG4gKiBzdXJ2aXZlIG9ubHkgdW50aWwgdGhlIG5leHQgcmVmcmVzaCwgYW5kIGFueXRoaW5nIHdyaXR0ZW4gYmVmb3JlIHdvdWxkIGJlXG4gKiB0aHJvd24gYXdheSBieSB0aGUgc3dhcC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gcGVyc2lzdExvY2FsbHkoXG4gIGtleTogc3RyaW5nLFxuICBkaXJzOiBTdGFnZWRTa2lsbERpcltdLFxuICByZWNvcmQ6IFJlbW90ZVNraWxsQ2FjaGVFbnRyeSxcbik6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IHN0YWJsZSA9IGF3YWl0IGxvY2FsRlMucmVidWlsZEZTKGAke0xPQ0FMX1NLSUxMU19ESVJ9LyR7a2V5fWAsIGFzeW5jIChzY3JhdGNoKSA9PiB7XG4gICAgYXdhaXQgY29weVNraWxsRGlycyhzY3JhdGNoLCBkaXJzKTtcbiAgICBhd2FpdCB3cml0ZU1ldGFkYXRhKHNjcmF0Y2gsIGtleSwgcmVjb3JkKTtcbiAgfSk7XG4gIHJldHVybiBzdGFibGUucm9vdDtcbn1cblxuLyoqXG4gKiBBIHNjcmF0Y2ggZmlsZXN5c3RlbSB3aG9zZSByb290IGV4aXN0cyBvbiBkaXNrLCBmb3IgdGhlIHBhdGhzIHRoYXQgaGFuZCBhXG4gKiByZWFsIGRpcmVjdG9yeSB0byBgbm9kZTpmc2Agb3IgYSBjaGlsZCBwcm9jZXNzIHJhdGhlciB0aGFuIGdvaW5nIHRocm91Z2hcbiAqIHRoZSB7QGxpbmsgRmlsZVN5c3RlbX0gQVBJLlxuICovXG5hc3luYyBmdW5jdGlvbiBpbml0aWFsaXplZFNjcmF0Y2gocHJlZml4OiBzdHJpbmcpOiBQcm9taXNlPExvY2FsRmlsZVN5c3RlbT4ge1xuICBjb25zdCBzY3JhdGNoID0gbG9jYWxGUy5zY3JhdGNoRlMocHJlZml4KTtcbiAgYXdhaXQgc2NyYXRjaC5pbml0KCk7XG4gIHJldHVybiBzY3JhdGNoO1xufVxuXG4vKiogQmVzdC1lZmZvcnQgZXhpc3RlbmNlIGNoZWNrLiAqL1xuYXN5bmMgZnVuY3Rpb24gcGF0aEV4aXN0cyhwYXRoOiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgdHJ5IHtcbiAgICBhd2FpdCBzdGF0KHBhdGgpO1xuICAgIHJldHVybiB0cnVlO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cbiJdfQ==
package/package.json CHANGED
@@ -32,25 +32,25 @@
32
32
  "express": "^5.1.0",
33
33
  "pg": "^8.22.0",
34
34
  "zod": "4.3.6",
35
- "@dbx-tools/core": "0.6.12",
36
- "@dbx-tools/appkit": "0.6.12",
37
- "@dbx-tools/databricks": "0.6.12",
38
- "@dbx-tools/genie": "0.6.12",
39
- "@dbx-tools/model": "0.6.12",
40
- "@dbx-tools/path": "0.6.12",
41
- "@dbx-tools/fs": "0.6.12",
42
- "@dbx-tools/shared-fs": "0.6.12",
43
- "@dbx-tools/shared-genie": "0.6.12",
44
- "@dbx-tools/shared-core": "0.6.12",
45
- "@dbx-tools/shared-mastra": "0.6.12",
46
- "@dbx-tools/shared-model": "0.6.12"
35
+ "@dbx-tools/appkit": "0.6.13",
36
+ "@dbx-tools/core": "0.6.13",
37
+ "@dbx-tools/databricks": "0.6.13",
38
+ "@dbx-tools/genie": "0.6.13",
39
+ "@dbx-tools/fs": "0.6.13",
40
+ "@dbx-tools/model": "0.6.13",
41
+ "@dbx-tools/path": "0.6.13",
42
+ "@dbx-tools/shared-genie": "0.6.13",
43
+ "@dbx-tools/shared-model": "0.6.13",
44
+ "@dbx-tools/shared-fs": "0.6.13",
45
+ "@dbx-tools/shared-core": "0.6.13",
46
+ "@dbx-tools/shared-mastra": "0.6.13"
47
47
  },
48
48
  "main": "./lib/index.js",
49
49
  "license": "UNLICENSED",
50
50
  "publishConfig": {
51
51
  "access": "public"
52
52
  },
53
- "version": "0.6.12",
53
+ "version": "0.6.13",
54
54
  "types": "./lib/index.d.ts",
55
55
  "type": "module",
56
56
  "exports": {
@@ -26,6 +26,15 @@
26
26
  * source (or the top-level call) sets `failOnError: false`, in which case it is
27
27
  * logged and skipped so one bad source never takes the app down.
28
28
  *
29
+ * Every provisioned tree carries a {@link METADATA_FILE} recording when each
30
+ * source was last downloaded, and a source is only re-downloaded once that
31
+ * record is older than {@link DEFAULT_REFRESH_TTL_MS} (a day). This runs at app
32
+ * BOOT, so without it a container that restarts a dozen times an hour re-pulls
33
+ * the whole AI Tools set a dozen times for content that changes rarely. The
34
+ * record travels WITH the tree rather than in process memory, so the reuse
35
+ * survives a restart - which is the only way it helps a Databricks App at all.
36
+ * Pass `refreshTtlMs: 0` to download on every boot.
37
+ *
29
38
  * The default destination is the Databricks workspace Assistant skills tree
30
39
  * (`/Workspace/.assistant/skills`, the same tree a "save this as a skill"
31
40
  * action writes to), so provisioned skills persist across restarts and are
@@ -62,8 +71,17 @@ function userAssistantSkillsPath(userEmail: string): string {
62
71
  return `/Users/${userEmail.trim()}/.assistant/skills`;
63
72
  }
64
73
 
65
- /** npm agent id the `skills` CLI installs a bare `SKILL.md` tree under. */
66
- const SKILLS_CLI_AGENT = "agents";
74
+ /**
75
+ * Agent id the `skills` CLI installs a bare `SKILL.md` tree under.
76
+ *
77
+ * `universal` is the CLI's own name for "no particular agent, just the plain
78
+ * tree", which is what this module wants - it re-hosts the result itself. The
79
+ * id must be one the installed CLI knows: an unrecognized one is rejected
80
+ * outright (`Invalid agents: ...`), taking every non-`aitools` source down with
81
+ * it, since a CLI failure is a hard failure rather than a fall-through to
82
+ * {@link stageViaFetch}.
83
+ */
84
+ const SKILLS_CLI_AGENT = "universal";
67
85
 
68
86
  /** Where the `skills` CLI drops a plain `SKILL.md` tree under a target dir. */
69
87
  const SKILLS_CLI_LAYOUT = [".agents", "skills"] as const;
@@ -74,6 +92,19 @@ const DEFAULT_MAX_DOWNLOAD_BYTES = 10 * 1024 * 1024;
74
92
  /** Stable temp directory holding one rebuilt skill tree per remote source. */
75
93
  const LOCAL_SKILLS_DIR = "mastra-local-skills";
76
94
 
95
+ /**
96
+ * Bookkeeping file written at the root of every provisioned skill tree, naming
97
+ * when each source was last downloaded. A dotfile so the skill scanners, which
98
+ * look for `<dir>/SKILL.md`, never mistake it for a skill.
99
+ */
100
+ const METADATA_FILE = ".metadata.json";
101
+
102
+ /** Shape marker for {@link METADATA_FILE}; an unknown version is ignored, not read. */
103
+ const METADATA_VERSION = 1;
104
+
105
+ /** How long a provisioned source is reused before being downloaded again. */
106
+ const DEFAULT_REFRESH_TTL_MS = 24 * 60 * 60 * 1000;
107
+
77
108
  /* ------------------------------ AI Tools ------------------------------ */
78
109
 
79
110
  /**
@@ -125,6 +156,13 @@ export interface RemoteSkillSourceOptions {
125
156
  ref?: string;
126
157
  /** Override the byte ceiling on a direct-fetch download for this source. */
127
158
  maxDownloadBytes?: number;
159
+ /**
160
+ * How long this source's provisioned tree is reused before it is downloaded
161
+ * again, in milliseconds. Overrides the top-level
162
+ * {@link ProvisionRemoteSkillsOptions.refreshTtlMs}; `0` re-downloads on
163
+ * every boot.
164
+ */
165
+ refreshTtlMs?: number;
128
166
  /**
129
167
  * When `false`, a source that fails to resolve is logged and skipped instead
130
168
  * of failing app startup. Overrides the top-level {@link ProvisionRemoteSkillsOptions.failOnError}.
@@ -169,6 +207,12 @@ export interface ProvisionRemoteSkillsOptions {
169
207
  userEmail?: string;
170
208
  /** Byte ceiling on a direct-fetch download. Defaults to 10 MiB. */
171
209
  maxDownloadBytes?: number;
210
+ /**
211
+ * How long a provisioned tree is reused before its source is downloaded
212
+ * again, in milliseconds. Defaults to a day; `0` re-downloads on every boot.
213
+ * A per-source `refreshTtlMs` wins over this.
214
+ */
215
+ refreshTtlMs?: number;
172
216
  }
173
217
 
174
218
  /** What {@link provisionRemoteSkills} resolved. */
@@ -181,10 +225,38 @@ export interface ProvisionedRemoteSkills {
181
225
  localSkillPaths: string[];
182
226
  /** Absolute Databricks destination each source was written to, if any. */
183
227
  databricksBasePath?: string;
184
- /** Names of every skill directory that was provisioned. */
228
+ /**
229
+ * Names of every skill directory now available, whether it was downloaded on
230
+ * this boot or reused from a still-fresh tree (see {@link METADATA_FILE}).
231
+ */
185
232
  skillNames: string[];
186
233
  }
187
234
 
235
+ /**
236
+ * What one source's last download left behind, as recorded in
237
+ * {@link METADATA_FILE}.
238
+ */
239
+ export interface RemoteSkillCacheEntry {
240
+ /** The source string this entry was downloaded from, for readability. */
241
+ source: string;
242
+ /** When the download completed, ISO-8601. */
243
+ downloadedAt: string;
244
+ /** Skill directory names the download produced. */
245
+ skills: string[];
246
+ /**
247
+ * The content-affecting policy that download used. Also folded into the entry
248
+ * KEY, so narrowing `skills` or moving `ref` misses the cache instead of
249
+ * silently serving the previous selection.
250
+ */
251
+ policy?: { skills?: string[]; experimental?: boolean; ref?: string };
252
+ }
253
+
254
+ /** The {@link METADATA_FILE} document: one entry per provisioned source. */
255
+ export interface RemoteSkillsMetadata {
256
+ version: number;
257
+ sources: Record<string, RemoteSkillCacheEntry>;
258
+ }
259
+
188
260
  /* ------------------------------- helpers ------------------------------- */
189
261
 
190
262
  /** Normalize the `remoteSkills` option into a flat options bag. */
@@ -230,6 +302,107 @@ function isAiToolsSource(source: string): boolean {
230
302
  return source.trim().toLowerCase() === AITOOLS_SOURCE;
231
303
  }
232
304
 
305
+ /* -------------------------------- cache -------------------------------- */
306
+
307
+ /**
308
+ * The policy that decides what a source's download CONTAINS.
309
+ *
310
+ * Only these three change the resulting tree, so only these belong in the cache
311
+ * key - `failOnError` and `maxDownloadBytes` govern how a failure is handled,
312
+ * not what a success produces.
313
+ */
314
+ function cachePolicy(sourceOptions: NormalizedSource): RemoteSkillCacheEntry["policy"] {
315
+ const skills = string.parseList(sourceOptions.skills);
316
+ const policy = {
317
+ ...(skills.length > 0 ? { skills: [...skills].sort() } : {}),
318
+ ...(sourceOptions.experimental === true ? { experimental: true } : {}),
319
+ ...(string.trimToNull(sourceOptions.ref) ? { ref: sourceOptions.ref!.trim() } : {}),
320
+ };
321
+ return Object.keys(policy).length > 0 ? policy : undefined;
322
+ }
323
+
324
+ /**
325
+ * Stable identity of a source AND its content-affecting policy.
326
+ *
327
+ * Keying on the source alone would let a changed `skills` filter or `ref` read
328
+ * back the previous download for a day; keying on both turns that into a miss.
329
+ * The skill list is sorted first so a reordered array is still the same key.
330
+ */
331
+ function cacheKey(sourceOptions: NormalizedSource): string {
332
+ return hash.fnvHash(
333
+ JSON.stringify({ source: sourceOptions.source, policy: cachePolicy(sourceOptions) ?? null }),
334
+ );
335
+ }
336
+
337
+ /** The effective reuse window: per-source, then top-level, then a day. */
338
+ function resolveRefreshTtl(
339
+ sourceOptions: NormalizedSource,
340
+ options: ProvisionRemoteSkillsOptions,
341
+ ): number {
342
+ return sourceOptions.refreshTtlMs ?? options.refreshTtlMs ?? DEFAULT_REFRESH_TTL_MS;
343
+ }
344
+
345
+ /**
346
+ * Read the metadata document at the root of a provisioned tree, or `undefined`
347
+ * when there is none, it is unreadable, or it was written by a shape this
348
+ * version does not know.
349
+ *
350
+ * Never throws: a missing or corrupt record is a cache MISS, which costs a
351
+ * download - while letting it fail would take app startup down over
352
+ * bookkeeping.
353
+ */
354
+ async function readMetadata(fs: FileSystem): Promise<RemoteSkillsMetadata | undefined> {
355
+ try {
356
+ if (!(await fs.exists(METADATA_FILE))) return undefined;
357
+ const raw = await fs.readFile(METADATA_FILE, { encoding: "utf8" });
358
+ const parsed = json.parse(raw, undefined) as RemoteSkillsMetadata | undefined;
359
+ if (!object.isRecord(parsed) || parsed.version !== METADATA_VERSION) return undefined;
360
+ return object.isRecord(parsed.sources) ? parsed : undefined;
361
+ } catch (err) {
362
+ logger.debug("cache:unreadable", { error: error.errorMessage(err) });
363
+ return undefined;
364
+ }
365
+ }
366
+
367
+ /**
368
+ * Whether an entry is still inside its reuse window.
369
+ *
370
+ * A `ttlMs` of `0` disables reuse outright, and an unparseable or FUTURE
371
+ * timestamp counts as stale - a clock that moved backwards should cost one
372
+ * extra download, not pin a tree as fresh indefinitely.
373
+ */
374
+ function isFresh(entry: RemoteSkillCacheEntry, ttlMs: number): boolean {
375
+ if (ttlMs <= 0 || !Array.isArray(entry.skills)) return false;
376
+ const downloadedAt = Date.parse(entry.downloadedAt ?? "");
377
+ if (Number.isNaN(downloadedAt)) return false;
378
+ const age = Date.now() - downloadedAt;
379
+ return age >= 0 && age < ttlMs;
380
+ }
381
+
382
+ /**
383
+ * Merge one source's entry into the tree's metadata document, preserving what
384
+ * other sources recorded - the Databricks destination is SHARED, so a blind
385
+ * overwrite would drop every sibling source's timestamp and re-download the
386
+ * lot on the next boot.
387
+ */
388
+ async function writeMetadata(
389
+ fs: FileSystem,
390
+ key: string,
391
+ entry: RemoteSkillCacheEntry,
392
+ ): Promise<void> {
393
+ const current = await readMetadata(fs);
394
+ const next: RemoteSkillsMetadata = {
395
+ version: METADATA_VERSION,
396
+ sources: { ...current?.sources, [key]: entry },
397
+ };
398
+ await fs.writeFile(METADATA_FILE, `${JSON.stringify(next, null, 2)}\n`, { overwrite: true });
399
+ }
400
+
401
+ /** The stable local tree a source is rebuilt into, keyed by {@link cacheKey}. */
402
+ function localSkillsFS(key: string): LocalFileSystem {
403
+ return localFS.tmpFS(`${LOCAL_SKILLS_DIR}/${key}`);
404
+ }
405
+
233
406
  /**
234
407
  * Materialize every configured remote skill source at app startup.
235
408
  *
@@ -260,30 +433,59 @@ export async function provisionRemoteSkills(
260
433
  const skillNames: string[] = [];
261
434
  let staging: LocalFileSystem | undefined;
262
435
 
436
+ // The destination roots the shared metadata document, so it has to exist
437
+ // before the first cache READ - `copySkillDirs` would otherwise be the first
438
+ // thing to create it, which is too late.
439
+ if (destination) await destination.init();
440
+
263
441
  try {
264
442
  const sources = Array.isArray(options.sources) ? options.sources : [options.sources];
265
443
  for (const entry of sources) {
266
444
  const sourceOptions = toSourceOptions(entry);
267
445
  const failOnError = sourceOptions.failOnError ?? failDefault;
268
446
  try {
447
+ // Where this source's bookkeeping lives: the shared Databricks tree, or
448
+ // the source's own stable local dir.
449
+ const key = cacheKey(sourceOptions);
450
+ const cacheFS = destination ?? localSkillsFS(key);
451
+ const cached = (await readMetadata(cacheFS))?.sources[key];
452
+ if (cached && isFresh(cached, resolveRefreshTtl(sourceOptions, options))) {
453
+ skillNames.push(...cached.skills);
454
+ if (!destination) localSkillPaths.push(cacheFS.root);
455
+ logger.debug("source:cached", {
456
+ source: sourceOptions.source,
457
+ downloadedAt: cached.downloadedAt,
458
+ skills: cached.skills,
459
+ });
460
+ continue;
461
+ }
462
+
269
463
  staging ??= await initializedScratch("mastra-remote-skills");
270
464
  const stagedDir = await stageSource(sourceOptions, staging.root, options);
271
465
  const staged = await collectSkillDirs(stagedDir);
272
466
  if (staged.length === 0) {
273
467
  throw new Error(`no SKILL.md found for source "${sourceOptions.source}"`);
274
468
  }
469
+ const policy = cachePolicy(sourceOptions);
470
+ const record: RemoteSkillCacheEntry = {
471
+ source: sourceOptions.source,
472
+ downloadedAt: new Date().toISOString(),
473
+ skills: staged.map((dir) => dir.name),
474
+ ...(policy ? { policy } : {}),
475
+ };
275
476
  if (destination && databricksBasePath) {
276
477
  await copySkillDirs(destination, staged);
277
- skillNames.push(...staged.map((dir) => dir.name));
478
+ // Only after the copy lands: a metadata entry written first would
479
+ // mark a failed provision as fresh and suppress the retry for a day.
480
+ await writeMetadata(destination, key, record);
278
481
  } else {
279
- const localDir = await persistLocally(sourceOptions.source, staged);
280
- localSkillPaths.push(localDir);
281
- skillNames.push(...staged.map((dir) => dir.name));
482
+ localSkillPaths.push(await persistLocally(key, staged, record));
282
483
  }
484
+ skillNames.push(...record.skills);
283
485
  logger.debug("source:provisioned", {
284
486
  source: sourceOptions.source,
285
487
  destination: databricksBasePath ?? "local-temp",
286
- skills: staged.map((dir) => dir.name),
488
+ skills: record.skills,
287
489
  });
288
490
  } catch (err) {
289
491
  if (failOnError) {
@@ -561,14 +763,25 @@ async function copySkillDirs(destination: FileSystem, dirs: StagedSkillDir[]): P
561
763
  * return its root path.
562
764
  *
563
765
  * A given source resolves to the same content on almost every boot, so each
564
- * one owns a directory named for its {@link hash.fnvHash} rather than leaving
565
- * a fresh scratch dir behind per restart. Keying on the source (not the
566
- * content) is what keeps two different sources from overwriting each other.
766
+ * one owns a directory named for its {@link cacheKey} rather than leaving a
767
+ * fresh scratch dir behind per restart. Keying on the source and its policy
768
+ * (not the content) is what keeps two different sources from overwriting each
769
+ * other.
770
+ *
771
+ * The metadata is written INSIDE the rebuild rather than after it: `rebuildFS`
772
+ * replaces the stable root wholesale, so anything written afterwards would
773
+ * survive only until the next refresh, and anything written before would be
774
+ * thrown away by the swap.
567
775
  */
568
- async function persistLocally(source: string, dirs: StagedSkillDir[]): Promise<string> {
569
- const stable = await localFS.rebuildFS(`${LOCAL_SKILLS_DIR}/${hash.fnvHash(source)}`, (scratch) =>
570
- copySkillDirs(scratch, dirs),
571
- );
776
+ async function persistLocally(
777
+ key: string,
778
+ dirs: StagedSkillDir[],
779
+ record: RemoteSkillCacheEntry,
780
+ ): Promise<string> {
781
+ const stable = await localFS.rebuildFS(`${LOCAL_SKILLS_DIR}/${key}`, async (scratch) => {
782
+ await copySkillDirs(scratch, dirs);
783
+ await writeMetadata(scratch, key, record);
784
+ });
572
785
  return stable.root;
573
786
  }
574
787