@fairspec/agent 0.9.0

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.
Files changed (90) hide show
  1. package/LICENSE.md +9 -0
  2. package/README.md +3 -0
  3. package/build/actions/tableSchema/asHtml.d.ts +4 -0
  4. package/build/actions/tableSchema/asHtml.js +82 -0
  5. package/build/actions/tableSchema/asHtml.spec.d.ts +1 -0
  6. package/build/actions/tableSchema/asHtml.spec.js +356 -0
  7. package/build/actions/tableSchema/asMarkdown.d.ts +4 -0
  8. package/build/actions/tableSchema/asMarkdown.js +65 -0
  9. package/build/actions/tableSchema/asMarkdown.spec.d.ts +1 -0
  10. package/build/actions/tableSchema/asMarkdown.spec.js +133 -0
  11. package/build/document/Document.d.ts +2 -0
  12. package/build/document/Document.js +2 -0
  13. package/build/document/index.d.ts +3 -0
  14. package/build/document/index.js +3 -0
  15. package/build/document/types/Base.d.ts +3 -0
  16. package/build/document/types/Base.js +2 -0
  17. package/build/document/types/Json.d.ts +5 -0
  18. package/build/document/types/Json.js +2 -0
  19. package/build/document/validate.d.ts +5 -0
  20. package/build/document/validate.js +23 -0
  21. package/build/document/validate.spec.d.ts +1 -0
  22. package/build/document/validate.spec.js +71 -0
  23. package/build/index.d.ts +1 -0
  24. package/build/index.js +2 -0
  25. package/build/package.json +39 -0
  26. package/build/plugin.d.ts +6 -0
  27. package/build/plugin.js +15 -0
  28. package/build/schema/convert/toHtml.d.ts +4 -0
  29. package/build/schema/convert/toHtml.js +107 -0
  30. package/build/schema/convert/toHtml.spec.d.ts +1 -0
  31. package/build/schema/convert/toHtml.spec.js +432 -0
  32. package/build/schema/convert/toMarkdown.d.ts +4 -0
  33. package/build/schema/convert/toMarkdown.js +75 -0
  34. package/build/schema/convert/toMarkdown.spec.d.ts +1 -0
  35. package/build/schema/convert/toMarkdown.spec.js +137 -0
  36. package/build/schema/index.d.ts +2 -0
  37. package/build/schema/index.js +3 -0
  38. package/build/server.d.ts +2 -0
  39. package/build/server.js +29 -0
  40. package/build/tableSchema/convert/toHtml.d.ts +4 -0
  41. package/build/tableSchema/convert/toHtml.js +80 -0
  42. package/build/tableSchema/convert/toHtml.spec.d.ts +1 -0
  43. package/build/tableSchema/convert/toHtml.spec.js +375 -0
  44. package/build/tableSchema/convert/toMarkdown.d.ts +4 -0
  45. package/build/tableSchema/convert/toMarkdown.js +57 -0
  46. package/build/tableSchema/convert/toMarkdown.spec.d.ts +1 -0
  47. package/build/tableSchema/convert/toMarkdown.spec.js +141 -0
  48. package/build/tableSchema/index.d.ts +2 -0
  49. package/build/tableSchema/index.js +3 -0
  50. package/build/tools/data/validate.d.ts +971 -0
  51. package/build/tools/data/validate.js +15 -0
  52. package/build/tools/data/validate.spec.d.ts +1 -0
  53. package/build/tools/data/validate.spec.js +228 -0
  54. package/build/tools/dataSchema/infer.d.ts +797 -0
  55. package/build/tools/dataSchema/infer.js +15 -0
  56. package/build/tools/dataSchema/infer.spec.d.ts +1 -0
  57. package/build/tools/dataSchema/infer.spec.js +215 -0
  58. package/build/tools/dataSchema/validate.d.ts +177 -0
  59. package/build/tools/dataSchema/validate.js +17 -0
  60. package/build/tools/dataSchema/validate.spec.d.ts +1 -0
  61. package/build/tools/dataSchema/validate.spec.js +148 -0
  62. package/build/tools/dataset/infer.d.ts +1985 -0
  63. package/build/tools/dataset/infer.js +15 -0
  64. package/build/tools/dataset/infer.spec.d.ts +1 -0
  65. package/build/tools/dataset/infer.spec.js +181 -0
  66. package/build/tools/dataset/validate.d.ts +1168 -0
  67. package/build/tools/dataset/validate.js +17 -0
  68. package/build/tools/dataset/validate.spec.d.ts +1 -0
  69. package/build/tools/dataset/validate.spec.js +212 -0
  70. package/build/tools/dialect/infer.d.ts +889 -0
  71. package/build/tools/dialect/infer.js +16 -0
  72. package/build/tools/dialect/infer.spec.d.ts +1 -0
  73. package/build/tools/dialect/infer.spec.js +138 -0
  74. package/build/tools/table/query.d.ts +798 -0
  75. package/build/tools/table/query.js +24 -0
  76. package/build/tools/table/query.spec.d.ts +1 -0
  77. package/build/tools/table/query.spec.js +138 -0
  78. package/build/tools/table/validate.d.ts +999 -0
  79. package/build/tools/table/validate.js +16 -0
  80. package/build/tools/table/validate.spec.d.ts +1 -0
  81. package/build/tools/table/validate.spec.js +106 -0
  82. package/build/tools/tableSchema/infer.d.ts +1316 -0
  83. package/build/tools/tableSchema/infer.js +16 -0
  84. package/build/tools/tableSchema/infer.spec.d.ts +1 -0
  85. package/build/tools/tableSchema/infer.spec.js +152 -0
  86. package/build/tools/tableSchema/validate.d.ts +177 -0
  87. package/build/tools/tableSchema/validate.js +17 -0
  88. package/build/tools/tableSchema/validate.spec.d.ts +1 -0
  89. package/build/tools/tableSchema/validate.spec.js +121 -0
  90. package/package.json +39 -0
@@ -0,0 +1,15 @@
1
+ import { Dataset, inferDataset } from "@fairspec/library";
2
+ import { createTool } from "@mastra/core/tools";
3
+ import { z } from "zod";
4
+ export const inferDatasetTool = createTool({
5
+ id: "infer-dataset",
6
+ description: "Infer metadata for all resources in a dataset. Analyzes each resource to determine schemas and dialects.",
7
+ inputSchema: z.object({
8
+ dataset: Dataset.describe("The dataset to infer metadata for"),
9
+ }),
10
+ outputSchema: Dataset,
11
+ execute: async (input) => {
12
+ return await inferDataset(input.dataset);
13
+ },
14
+ });
15
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5mZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90b29scy9kYXRhc2V0L2luZmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFDekQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLG9CQUFvQixDQUFBO0FBQy9DLE9BQU8sRUFBRSxDQUFDLEVBQUUsTUFBTSxLQUFLLENBQUE7QUFFdkIsTUFBTSxDQUFDLE1BQU0sZ0JBQWdCLEdBQUcsVUFBVSxDQUFDO0lBQ3pDLEVBQUUsRUFBRSxlQUFlO0lBQ25CLFdBQVcsRUFDVCwwR0FBMEc7SUFDNUcsV0FBVyxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUM7UUFDcEIsT0FBTyxFQUFFLE9BQU8sQ0FBQyxRQUFRLENBQUMsbUNBQW1DLENBQUM7S0FDL0QsQ0FBQztJQUNGLFlBQVksRUFBRSxPQUFPO0lBQ3JCLE9BQU8sRUFBRSxLQUFLLEVBQUMsS0FBSyxFQUFDLEVBQUU7UUFDckIsT0FBTyxNQUFNLFlBQVksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUE7SUFDMUMsQ0FBQztDQUNGLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERhdGFzZXQsIGluZmVyRGF0YXNldCB9IGZyb20gXCJAZmFpcnNwZWMvbGlicmFyeVwiXG5pbXBvcnQgeyBjcmVhdGVUb29sIH0gZnJvbSBcIkBtYXN0cmEvY29yZS90b29sc1wiXG5pbXBvcnQgeyB6IH0gZnJvbSBcInpvZFwiXG5cbmV4cG9ydCBjb25zdCBpbmZlckRhdGFzZXRUb29sID0gY3JlYXRlVG9vbCh7XG4gIGlkOiBcImluZmVyLWRhdGFzZXRcIixcbiAgZGVzY3JpcHRpb246XG4gICAgXCJJbmZlciBtZXRhZGF0YSBmb3IgYWxsIHJlc291cmNlcyBpbiBhIGRhdGFzZXQuIEFuYWx5emVzIGVhY2ggcmVzb3VyY2UgdG8gZGV0ZXJtaW5lIHNjaGVtYXMgYW5kIGRpYWxlY3RzLlwiLFxuICBpbnB1dFNjaGVtYTogei5vYmplY3Qoe1xuICAgIGRhdGFzZXQ6IERhdGFzZXQuZGVzY3JpYmUoXCJUaGUgZGF0YXNldCB0byBpbmZlciBtZXRhZGF0YSBmb3JcIiksXG4gIH0pLFxuICBvdXRwdXRTY2hlbWE6IERhdGFzZXQsXG4gIGV4ZWN1dGU6IGFzeW5jIGlucHV0ID0+IHtcbiAgICByZXR1cm4gYXdhaXQgaW5mZXJEYXRhc2V0KGlucHV0LmRhdGFzZXQpXG4gIH0sXG59KVxuIl19
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,181 @@
1
+ import { writeTempFile } from "@fairspec/library";
2
+ import { describe, expect, it } from "vitest";
3
+ import { inferDatasetTool } from "./infer.js";
4
+ describe("inferDatasetTool", () => {
5
+ it("validates tool structure", () => {
6
+ expect(inferDatasetTool.id).toBe("infer-dataset");
7
+ expect(inferDatasetTool.description).toBeTruthy();
8
+ expect(inferDatasetTool.inputSchema).toBeTruthy();
9
+ expect(inferDatasetTool.outputSchema).toBeTruthy();
10
+ expect(inferDatasetTool.execute).toBeTypeOf("function");
11
+ });
12
+ it("infers dataset with single resource", async () => {
13
+ const path = await writeTempFile("id,name\n1,alice\n2,bob");
14
+ const source = {
15
+ language: "en",
16
+ resources: [{ data: path, dialect: { format: "csv" } }],
17
+ };
18
+ const result = await inferDatasetTool.execute?.({
19
+ dataset: source,
20
+ }, {});
21
+ expect.assert(result);
22
+ expect.assert(!("error" in result));
23
+ expect(result.language).toBe("en");
24
+ expect(result.resources).toHaveLength(1);
25
+ expect(result.resources?.[0]?.tableSchema).toEqual({
26
+ properties: {
27
+ id: { type: "integer" },
28
+ name: { type: "string" },
29
+ },
30
+ });
31
+ });
32
+ it("infers dataset with multiple resources", async () => {
33
+ const path1 = await writeTempFile("id,name\n1,alice\n2,bob");
34
+ const path2 = await writeTempFile("id,value\n1,100\n2,200");
35
+ const source = {
36
+ language: "en",
37
+ resources: [
38
+ { data: path1, dialect: { format: "csv" } },
39
+ { data: path2, dialect: { format: "csv" } },
40
+ ],
41
+ };
42
+ const result = await inferDatasetTool.execute?.({
43
+ dataset: source,
44
+ }, {});
45
+ expect.assert(result);
46
+ expect.assert(!("error" in result));
47
+ expect(result.language).toBe("en");
48
+ expect(result.resources).toHaveLength(2);
49
+ expect(result.resources?.[0]?.tableSchema).toBeDefined();
50
+ expect(result.resources?.[1]?.tableSchema).toBeDefined();
51
+ });
52
+ it("infers dataset with inline data resources", async () => {
53
+ const source = {
54
+ language: "en",
55
+ resources: [
56
+ {
57
+ data: [
58
+ { id: 1, name: "alice" },
59
+ { id: 2, name: "bob" },
60
+ ],
61
+ },
62
+ ],
63
+ };
64
+ const result = await inferDatasetTool.execute?.({
65
+ dataset: source,
66
+ }, {});
67
+ expect.assert(result);
68
+ expect.assert(!("error" in result));
69
+ expect(result.language).toBe("en");
70
+ expect(result.resources).toHaveLength(1);
71
+ expect(result.resources?.[0]?.tableSchema).toEqual({
72
+ properties: {
73
+ id: { type: "integer" },
74
+ name: { type: "string" },
75
+ },
76
+ });
77
+ });
78
+ it("preserves existing resource properties", async () => {
79
+ const path = await writeTempFile("id,name\n1,alice\n2,bob");
80
+ const source = {
81
+ language: "en",
82
+ resources: [
83
+ {
84
+ data: path,
85
+ dialect: { format: "csv" },
86
+ tableSchema: {
87
+ properties: {
88
+ id: { type: "string" },
89
+ name: { type: "string" },
90
+ },
91
+ },
92
+ },
93
+ ],
94
+ };
95
+ const result = await inferDatasetTool.execute?.({
96
+ dataset: source,
97
+ }, {});
98
+ expect.assert(result);
99
+ expect.assert(!("error" in result));
100
+ expect(result.resources?.[0]?.tableSchema).toEqual({
101
+ properties: {
102
+ id: { type: "string" },
103
+ name: { type: "string" },
104
+ },
105
+ });
106
+ });
107
+ it("infers dataset with empty resources", async () => {
108
+ const source = {
109
+ resources: [],
110
+ };
111
+ const result = await inferDatasetTool.execute?.({
112
+ dataset: source,
113
+ }, {});
114
+ expect.assert(result);
115
+ expect.assert(!("error" in result));
116
+ expect(result.resources).toHaveLength(0);
117
+ });
118
+ it("infers resource names when not provided", async () => {
119
+ const path1 = await writeTempFile("id,name\n1,alice");
120
+ const path2 = await writeTempFile("id,value\n1,100");
121
+ const source = {
122
+ resources: [
123
+ { data: path1, dialect: { format: "csv" } },
124
+ { data: path2, dialect: { format: "csv" } },
125
+ ],
126
+ };
127
+ const result = await inferDatasetTool.execute?.({
128
+ dataset: source,
129
+ }, {});
130
+ expect.assert(result);
131
+ expect.assert(!("error" in result));
132
+ expect(result.resources?.[0]?.name).toBeDefined();
133
+ expect(result.resources?.[1]?.name).toBeDefined();
134
+ });
135
+ it("infers schemas for different data types", async () => {
136
+ const source = {
137
+ resources: [
138
+ {
139
+ data: [
140
+ { id: 1, name: "alice", active: true },
141
+ { id: 2, name: "bob", active: false },
142
+ ],
143
+ },
144
+ ],
145
+ };
146
+ const result = await inferDatasetTool.execute?.({
147
+ dataset: source,
148
+ }, {});
149
+ expect.assert(result);
150
+ expect.assert(!("error" in result));
151
+ const tableSchema = result.resources?.[0]?.tableSchema;
152
+ expect(tableSchema).toBeDefined();
153
+ expect(typeof tableSchema).not.toBe("string");
154
+ if (typeof tableSchema === "object" && tableSchema !== null) {
155
+ expect(tableSchema.properties).toMatchObject({
156
+ id: { type: "integer" },
157
+ name: { type: "string" },
158
+ active: { type: "boolean" },
159
+ });
160
+ }
161
+ });
162
+ it("preserves dataset metadata", async () => {
163
+ const source = {
164
+ language: "en",
165
+ version: "1.0.0",
166
+ resources: [
167
+ {
168
+ data: [{ id: 1, name: "alice" }],
169
+ },
170
+ ],
171
+ };
172
+ const result = await inferDatasetTool.execute?.({
173
+ dataset: source,
174
+ }, {});
175
+ expect.assert(result);
176
+ expect.assert(!("error" in result));
177
+ expect(result.language).toBe("en");
178
+ expect(result.version).toBe("1.0.0");
179
+ });
180
+ });
181
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5mZXIuc3BlYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Rvb2xzL2RhdGFzZXQvaW5mZXIuc3BlYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFDakQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLE1BQU0sUUFBUSxDQUFBO0FBQzdDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUU3QyxRQUFRLENBQUMsa0JBQWtCLEVBQUUsR0FBRyxFQUFFO0lBQ2hDLEVBQUUsQ0FBQywwQkFBMEIsRUFBRSxHQUFHLEVBQUU7UUFDbEMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQTtRQUNqRCxNQUFNLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxDQUFDLENBQUMsVUFBVSxFQUFFLENBQUE7UUFDakQsTUFBTSxDQUFDLGdCQUFnQixDQUFDLFdBQVcsQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFBO1FBQ2pELE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQyxVQUFVLEVBQUUsQ0FBQTtRQUNsRCxNQUFNLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFBO0lBQ3pELENBQUMsQ0FBQyxDQUFBO0lBRUYsRUFBRSxDQUFDLHFDQUFxQyxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ25ELE1BQU0sSUFBSSxHQUFHLE1BQU0sYUFBYSxDQUFDLHlCQUF5QixDQUFDLENBQUE7UUFDM0QsTUFBTSxNQUFNLEdBQVk7WUFDdEIsUUFBUSxFQUFFLElBQUk7WUFDZCxTQUFTLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUM7U0FDeEQsQ0FBQTtRQUVELE1BQU0sTUFBTSxHQUFHLE1BQU0sZ0JBQWdCLENBQUMsT0FBTyxFQUFFLENBQzdDO1lBQ0UsT0FBTyxFQUFFLE1BQU07U0FDaEIsRUFDRCxFQUFFLENBQ0gsQ0FBQTtRQUVELE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDckIsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsT0FBTyxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUE7UUFFbkMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDbEMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDeEMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxXQUFXLENBQUMsQ0FBQyxPQUFPLENBQUM7WUFDakQsVUFBVSxFQUFFO2dCQUNWLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUU7Z0JBQ3ZCLElBQUksRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUU7YUFDekI7U0FDRixDQUFDLENBQUE7SUFDSixDQUFDLENBQUMsQ0FBQTtJQUVGLEVBQUUsQ0FBQyx3Q0FBd0MsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN0RCxNQUFNLEtBQUssR0FBRyxNQUFNLGFBQWEsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFBO1FBQzVELE1BQU0sS0FBSyxHQUFHLE1BQU0sYUFBYSxDQUFDLHdCQUF3QixDQUFDLENBQUE7UUFDM0QsTUFBTSxNQUFNLEdBQVk7WUFDdEIsUUFBUSxFQUFFLElBQUk7WUFDZCxTQUFTLEVBQUU7Z0JBQ1QsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsRUFBRTtnQkFDM0MsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsRUFBRTthQUM1QztTQUNGLENBQUE7UUFFRCxNQUFNLE1BQU0sR0FBRyxNQUFNLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxDQUM3QztZQUNFLE9BQU8sRUFBRSxNQUFNO1NBQ2hCLEVBQ0QsRUFBRSxDQUNILENBQUE7UUFFRCxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFBO1FBQ3JCLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE9BQU8sSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFBO1FBRW5DLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQ2xDLE1BQU0sQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBQ3hDLE1BQU0sQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUE7UUFDeEQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxXQUFXLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQTtJQUMxRCxDQUFDLENBQUMsQ0FBQTtJQUVGLEVBQUUsQ0FBQywyQ0FBMkMsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN6RCxNQUFNLE1BQU0sR0FBWTtZQUN0QixRQUFRLEVBQUUsSUFBSTtZQUNkLFNBQVMsRUFBRTtnQkFDVDtvQkFDRSxJQUFJLEVBQUU7d0JBQ0osRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUU7d0JBQ3hCLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFO3FCQUN2QjtpQkFDRjthQUNGO1NBQ0YsQ0FBQTtRQUVELE1BQU0sTUFBTSxHQUFHLE1BQU0sZ0JBQWdCLENBQUMsT0FBTyxFQUFFLENBQzdDO1lBQ0UsT0FBTyxFQUFFLE1BQU07U0FDaEIsRUFDRCxFQUFFLENBQ0gsQ0FBQTtRQUVELE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDckIsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsT0FBTyxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUE7UUFFbkMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDbEMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDeEMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxXQUFXLENBQUMsQ0FBQyxPQUFPLENBQUM7WUFDakQsVUFBVSxFQUFFO2dCQUNWLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUU7Z0JBQ3ZCLElBQUksRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUU7YUFDekI7U0FDRixDQUFDLENBQUE7SUFDSixDQUFDLENBQUMsQ0FBQTtJQUVGLEVBQUUsQ0FBQyx3Q0FBd0MsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN0RCxNQUFNLElBQUksR0FBRyxNQUFNLGFBQWEsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFBO1FBQzNELE1BQU0sTUFBTSxHQUFZO1lBQ3RCLFFBQVEsRUFBRSxJQUFJO1lBQ2QsU0FBUyxFQUFFO2dCQUNUO29CQUNFLElBQUksRUFBRSxJQUFJO29CQUNWLE9BQU8sRUFBRSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUU7b0JBQzFCLFdBQVcsRUFBRTt3QkFDWCxVQUFVLEVBQUU7NEJBQ1YsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRTs0QkFDdEIsSUFBSSxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRTt5QkFDekI7cUJBQ0Y7aUJBQ0Y7YUFDRjtTQUNGLENBQUE7UUFFRCxNQUFNLE1BQU0sR0FBRyxNQUFNLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxDQUM3QztZQUNFLE9BQU8sRUFBRSxNQUFNO1NBQ2hCLEVBQ0QsRUFBRSxDQUNILENBQUE7UUFFRCxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFBO1FBQ3JCLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE9BQU8sSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFBO1FBRW5DLE1BQU0sQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUMsT0FBTyxDQUFDO1lBQ2pELFVBQVUsRUFBRTtnQkFDVixFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFO2dCQUN0QixJQUFJLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFO2FBQ3pCO1NBQ0YsQ0FBQyxDQUFBO0lBQ0osQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMscUNBQXFDLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDbkQsTUFBTSxNQUFNLEdBQVk7WUFDdEIsU0FBUyxFQUFFLEVBQUU7U0FDZCxDQUFBO1FBRUQsTUFBTSxNQUFNLEdBQUcsTUFBTSxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsQ0FDN0M7WUFDRSxPQUFPLEVBQUUsTUFBTTtTQUNoQixFQUNELEVBQUUsQ0FDSCxDQUFBO1FBRUQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUNyQixNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQTtRQUVuQyxNQUFNLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUMxQyxDQUFDLENBQUMsQ0FBQTtJQUVGLEVBQUUsQ0FBQyx5Q0FBeUMsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN2RCxNQUFNLEtBQUssR0FBRyxNQUFNLGFBQWEsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFBO1FBQ3JELE1BQU0sS0FBSyxHQUFHLE1BQU0sYUFBYSxDQUFDLGlCQUFpQixDQUFDLENBQUE7UUFDcEQsTUFBTSxNQUFNLEdBQVk7WUFDdEIsU0FBUyxFQUFFO2dCQUNULEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLEVBQUU7Z0JBQzNDLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLEVBQUU7YUFDNUM7U0FDRixDQUFBO1FBRUQsTUFBTSxNQUFNLEdBQUcsTUFBTSxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsQ0FDN0M7WUFDRSxPQUFPLEVBQUUsTUFBTTtTQUNoQixFQUNELEVBQUUsQ0FDSCxDQUFBO1FBRUQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUNyQixNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQTtRQUVuQyxNQUFNLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFBO1FBQ2pELE1BQU0sQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUE7SUFDbkQsQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMseUNBQXlDLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDdkQsTUFBTSxNQUFNLEdBQVk7WUFDdEIsU0FBUyxFQUFFO2dCQUNUO29CQUNFLElBQUksRUFBRTt3QkFDSixFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO3dCQUN0QyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFO3FCQUN0QztpQkFDRjthQUNGO1NBQ0YsQ0FBQTtRQUVELE1BQU0sTUFBTSxHQUFHLE1BQU0sZ0JBQWdCLENBQUMsT0FBTyxFQUFFLENBQzdDO1lBQ0UsT0FBTyxFQUFFLE1BQU07U0FDaEIsRUFDRCxFQUFFLENBQ0gsQ0FBQTtRQUVELE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDckIsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsT0FBTyxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUE7UUFFbkMsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLFdBQVcsQ0FBQTtRQUN0RCxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUE7UUFDakMsTUFBTSxDQUFDLE9BQU8sV0FBVyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUM3QyxJQUFJLE9BQU8sV0FBVyxLQUFLLFFBQVEsSUFBSSxXQUFXLEtBQUssSUFBSSxFQUFFLENBQUM7WUFDNUQsTUFBTSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxhQUFhLENBQUM7Z0JBQzNDLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUU7Z0JBQ3ZCLElBQUksRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUU7Z0JBQ3hCLE1BQU0sRUFBRSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUU7YUFDNUIsQ0FBQyxDQUFBO1FBQ0osQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFBO0lBRUYsRUFBRSxDQUFDLDRCQUE0QixFQUFFLEtBQUssSUFBSSxFQUFFO1FBQzFDLE1BQU0sTUFBTSxHQUFZO1lBQ3RCLFFBQVEsRUFBRSxJQUFJO1lBQ2QsT0FBTyxFQUFFLE9BQU87WUFDaEIsU0FBUyxFQUFFO2dCQUNUO29CQUNFLElBQUksRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLENBQUM7aUJBQ2pDO2FBQ0Y7U0FDRixDQUFBO1FBRUQsTUFBTSxNQUFNLEdBQUcsTUFBTSxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsQ0FDN0M7WUFDRSxPQUFPLEVBQUUsTUFBTTtTQUNoQixFQUNELEVBQUUsQ0FDSCxDQUFBO1FBRUQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUNyQixNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQTtRQUVuQyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUNsQyxNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQTtJQUN0QyxDQUFDLENBQUMsQ0FBQTtBQUNKLENBQUMsQ0FBQyxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBEYXRhc2V0IH0gZnJvbSBcIkBmYWlyc3BlYy9saWJyYXJ5XCJcbmltcG9ydCB7IHdyaXRlVGVtcEZpbGUgfSBmcm9tIFwiQGZhaXJzcGVjL2xpYnJhcnlcIlxuaW1wb3J0IHsgZGVzY3JpYmUsIGV4cGVjdCwgaXQgfSBmcm9tIFwidml0ZXN0XCJcbmltcG9ydCB7IGluZmVyRGF0YXNldFRvb2wgfSBmcm9tIFwiLi9pbmZlci50c1wiXG5cbmRlc2NyaWJlKFwiaW5mZXJEYXRhc2V0VG9vbFwiLCAoKSA9PiB7XG4gIGl0KFwidmFsaWRhdGVzIHRvb2wgc3RydWN0dXJlXCIsICgpID0+IHtcbiAgICBleHBlY3QoaW5mZXJEYXRhc2V0VG9vbC5pZCkudG9CZShcImluZmVyLWRhdGFzZXRcIilcbiAgICBleHBlY3QoaW5mZXJEYXRhc2V0VG9vbC5kZXNjcmlwdGlvbikudG9CZVRydXRoeSgpXG4gICAgZXhwZWN0KGluZmVyRGF0YXNldFRvb2wuaW5wdXRTY2hlbWEpLnRvQmVUcnV0aHkoKVxuICAgIGV4cGVjdChpbmZlckRhdGFzZXRUb29sLm91dHB1dFNjaGVtYSkudG9CZVRydXRoeSgpXG4gICAgZXhwZWN0KGluZmVyRGF0YXNldFRvb2wuZXhlY3V0ZSkudG9CZVR5cGVPZihcImZ1bmN0aW9uXCIpXG4gIH0pXG5cbiAgaXQoXCJpbmZlcnMgZGF0YXNldCB3aXRoIHNpbmdsZSByZXNvdXJjZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcGF0aCA9IGF3YWl0IHdyaXRlVGVtcEZpbGUoXCJpZCxuYW1lXFxuMSxhbGljZVxcbjIsYm9iXCIpXG4gICAgY29uc3Qgc291cmNlOiBEYXRhc2V0ID0ge1xuICAgICAgbGFuZ3VhZ2U6IFwiZW5cIixcbiAgICAgIHJlc291cmNlczogW3sgZGF0YTogcGF0aCwgZGlhbGVjdDogeyBmb3JtYXQ6IFwiY3N2XCIgfSB9XSxcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBpbmZlckRhdGFzZXRUb29sLmV4ZWN1dGU/LihcbiAgICAgIHtcbiAgICAgICAgZGF0YXNldDogc291cmNlLFxuICAgICAgfSxcbiAgICAgIHt9LFxuICAgIClcblxuICAgIGV4cGVjdC5hc3NlcnQocmVzdWx0KVxuICAgIGV4cGVjdC5hc3NlcnQoIShcImVycm9yXCIgaW4gcmVzdWx0KSlcblxuICAgIGV4cGVjdChyZXN1bHQubGFuZ3VhZ2UpLnRvQmUoXCJlblwiKVxuICAgIGV4cGVjdChyZXN1bHQucmVzb3VyY2VzKS50b0hhdmVMZW5ndGgoMSlcbiAgICBleHBlY3QocmVzdWx0LnJlc291cmNlcz8uWzBdPy50YWJsZVNjaGVtYSkudG9FcXVhbCh7XG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGlkOiB7IHR5cGU6IFwiaW50ZWdlclwiIH0sXG4gICAgICAgIG5hbWU6IHsgdHlwZTogXCJzdHJpbmdcIiB9LFxuICAgICAgfSxcbiAgICB9KVxuICB9KVxuXG4gIGl0KFwiaW5mZXJzIGRhdGFzZXQgd2l0aCBtdWx0aXBsZSByZXNvdXJjZXNcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHBhdGgxID0gYXdhaXQgd3JpdGVUZW1wRmlsZShcImlkLG5hbWVcXG4xLGFsaWNlXFxuMixib2JcIilcbiAgICBjb25zdCBwYXRoMiA9IGF3YWl0IHdyaXRlVGVtcEZpbGUoXCJpZCx2YWx1ZVxcbjEsMTAwXFxuMiwyMDBcIilcbiAgICBjb25zdCBzb3VyY2U6IERhdGFzZXQgPSB7XG4gICAgICBsYW5ndWFnZTogXCJlblwiLFxuICAgICAgcmVzb3VyY2VzOiBbXG4gICAgICAgIHsgZGF0YTogcGF0aDEsIGRpYWxlY3Q6IHsgZm9ybWF0OiBcImNzdlwiIH0gfSxcbiAgICAgICAgeyBkYXRhOiBwYXRoMiwgZGlhbGVjdDogeyBmb3JtYXQ6IFwiY3N2XCIgfSB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBpbmZlckRhdGFzZXRUb29sLmV4ZWN1dGU/LihcbiAgICAgIHtcbiAgICAgICAgZGF0YXNldDogc291cmNlLFxuICAgICAgfSxcbiAgICAgIHt9LFxuICAgIClcblxuICAgIGV4cGVjdC5hc3NlcnQocmVzdWx0KVxuICAgIGV4cGVjdC5hc3NlcnQoIShcImVycm9yXCIgaW4gcmVzdWx0KSlcblxuICAgIGV4cGVjdChyZXN1bHQubGFuZ3VhZ2UpLnRvQmUoXCJlblwiKVxuICAgIGV4cGVjdChyZXN1bHQucmVzb3VyY2VzKS50b0hhdmVMZW5ndGgoMilcbiAgICBleHBlY3QocmVzdWx0LnJlc291cmNlcz8uWzBdPy50YWJsZVNjaGVtYSkudG9CZURlZmluZWQoKVxuICAgIGV4cGVjdChyZXN1bHQucmVzb3VyY2VzPy5bMV0/LnRhYmxlU2NoZW1hKS50b0JlRGVmaW5lZCgpXG4gIH0pXG5cbiAgaXQoXCJpbmZlcnMgZGF0YXNldCB3aXRoIGlubGluZSBkYXRhIHJlc291cmNlc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3Qgc291cmNlOiBEYXRhc2V0ID0ge1xuICAgICAgbGFuZ3VhZ2U6IFwiZW5cIixcbiAgICAgIHJlc291cmNlczogW1xuICAgICAgICB7XG4gICAgICAgICAgZGF0YTogW1xuICAgICAgICAgICAgeyBpZDogMSwgbmFtZTogXCJhbGljZVwiIH0sXG4gICAgICAgICAgICB7IGlkOiAyLCBuYW1lOiBcImJvYlwiIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgaW5mZXJEYXRhc2V0VG9vbC5leGVjdXRlPy4oXG4gICAgICB7XG4gICAgICAgIGRhdGFzZXQ6IHNvdXJjZSxcbiAgICAgIH0sXG4gICAgICB7fSxcbiAgICApXG5cbiAgICBleHBlY3QuYXNzZXJ0KHJlc3VsdClcbiAgICBleHBlY3QuYXNzZXJ0KCEoXCJlcnJvclwiIGluIHJlc3VsdCkpXG5cbiAgICBleHBlY3QocmVzdWx0Lmxhbmd1YWdlKS50b0JlKFwiZW5cIilcbiAgICBleHBlY3QocmVzdWx0LnJlc291cmNlcykudG9IYXZlTGVuZ3RoKDEpXG4gICAgZXhwZWN0KHJlc3VsdC5yZXNvdXJjZXM/LlswXT8udGFibGVTY2hlbWEpLnRvRXF1YWwoe1xuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBpZDogeyB0eXBlOiBcImludGVnZXJcIiB9LFxuICAgICAgICBuYW1lOiB7IHR5cGU6IFwic3RyaW5nXCIgfSxcbiAgICAgIH0sXG4gICAgfSlcbiAgfSlcblxuICBpdChcInByZXNlcnZlcyBleGlzdGluZyByZXNvdXJjZSBwcm9wZXJ0aWVzXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBwYXRoID0gYXdhaXQgd3JpdGVUZW1wRmlsZShcImlkLG5hbWVcXG4xLGFsaWNlXFxuMixib2JcIilcbiAgICBjb25zdCBzb3VyY2U6IERhdGFzZXQgPSB7XG4gICAgICBsYW5ndWFnZTogXCJlblwiLFxuICAgICAgcmVzb3VyY2VzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBkYXRhOiBwYXRoLFxuICAgICAgICAgIGRpYWxlY3Q6IHsgZm9ybWF0OiBcImNzdlwiIH0sXG4gICAgICAgICAgdGFibGVTY2hlbWE6IHtcbiAgICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgaWQ6IHsgdHlwZTogXCJzdHJpbmdcIiB9LFxuICAgICAgICAgICAgICBuYW1lOiB7IHR5cGU6IFwic3RyaW5nXCIgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgaW5mZXJEYXRhc2V0VG9vbC5leGVjdXRlPy4oXG4gICAgICB7XG4gICAgICAgIGRhdGFzZXQ6IHNvdXJjZSxcbiAgICAgIH0sXG4gICAgICB7fSxcbiAgICApXG5cbiAgICBleHBlY3QuYXNzZXJ0KHJlc3VsdClcbiAgICBleHBlY3QuYXNzZXJ0KCEoXCJlcnJvclwiIGluIHJlc3VsdCkpXG5cbiAgICBleHBlY3QocmVzdWx0LnJlc291cmNlcz8uWzBdPy50YWJsZVNjaGVtYSkudG9FcXVhbCh7XG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGlkOiB7IHR5cGU6IFwic3RyaW5nXCIgfSxcbiAgICAgICAgbmFtZTogeyB0eXBlOiBcInN0cmluZ1wiIH0sXG4gICAgICB9LFxuICAgIH0pXG4gIH0pXG5cbiAgaXQoXCJpbmZlcnMgZGF0YXNldCB3aXRoIGVtcHR5IHJlc291cmNlc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3Qgc291cmNlOiBEYXRhc2V0ID0ge1xuICAgICAgcmVzb3VyY2VzOiBbXSxcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBpbmZlckRhdGFzZXRUb29sLmV4ZWN1dGU/LihcbiAgICAgIHtcbiAgICAgICAgZGF0YXNldDogc291cmNlLFxuICAgICAgfSxcbiAgICAgIHt9LFxuICAgIClcblxuICAgIGV4cGVjdC5hc3NlcnQocmVzdWx0KVxuICAgIGV4cGVjdC5hc3NlcnQoIShcImVycm9yXCIgaW4gcmVzdWx0KSlcblxuICAgIGV4cGVjdChyZXN1bHQucmVzb3VyY2VzKS50b0hhdmVMZW5ndGgoMClcbiAgfSlcblxuICBpdChcImluZmVycyByZXNvdXJjZSBuYW1lcyB3aGVuIG5vdCBwcm92aWRlZFwiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcGF0aDEgPSBhd2FpdCB3cml0ZVRlbXBGaWxlKFwiaWQsbmFtZVxcbjEsYWxpY2VcIilcbiAgICBjb25zdCBwYXRoMiA9IGF3YWl0IHdyaXRlVGVtcEZpbGUoXCJpZCx2YWx1ZVxcbjEsMTAwXCIpXG4gICAgY29uc3Qgc291cmNlOiBEYXRhc2V0ID0ge1xuICAgICAgcmVzb3VyY2VzOiBbXG4gICAgICAgIHsgZGF0YTogcGF0aDEsIGRpYWxlY3Q6IHsgZm9ybWF0OiBcImNzdlwiIH0gfSxcbiAgICAgICAgeyBkYXRhOiBwYXRoMiwgZGlhbGVjdDogeyBmb3JtYXQ6IFwiY3N2XCIgfSB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBpbmZlckRhdGFzZXRUb29sLmV4ZWN1dGU/LihcbiAgICAgIHtcbiAgICAgICAgZGF0YXNldDogc291cmNlLFxuICAgICAgfSxcbiAgICAgIHt9LFxuICAgIClcblxuICAgIGV4cGVjdC5hc3NlcnQocmVzdWx0KVxuICAgIGV4cGVjdC5hc3NlcnQoIShcImVycm9yXCIgaW4gcmVzdWx0KSlcblxuICAgIGV4cGVjdChyZXN1bHQucmVzb3VyY2VzPy5bMF0/Lm5hbWUpLnRvQmVEZWZpbmVkKClcbiAgICBleHBlY3QocmVzdWx0LnJlc291cmNlcz8uWzFdPy5uYW1lKS50b0JlRGVmaW5lZCgpXG4gIH0pXG5cbiAgaXQoXCJpbmZlcnMgc2NoZW1hcyBmb3IgZGlmZmVyZW50IGRhdGEgdHlwZXNcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHNvdXJjZTogRGF0YXNldCA9IHtcbiAgICAgIHJlc291cmNlczogW1xuICAgICAgICB7XG4gICAgICAgICAgZGF0YTogW1xuICAgICAgICAgICAgeyBpZDogMSwgbmFtZTogXCJhbGljZVwiLCBhY3RpdmU6IHRydWUgfSxcbiAgICAgICAgICAgIHsgaWQ6IDIsIG5hbWU6IFwiYm9iXCIsIGFjdGl2ZTogZmFsc2UgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBpbmZlckRhdGFzZXRUb29sLmV4ZWN1dGU/LihcbiAgICAgIHtcbiAgICAgICAgZGF0YXNldDogc291cmNlLFxuICAgICAgfSxcbiAgICAgIHt9LFxuICAgIClcblxuICAgIGV4cGVjdC5hc3NlcnQocmVzdWx0KVxuICAgIGV4cGVjdC5hc3NlcnQoIShcImVycm9yXCIgaW4gcmVzdWx0KSlcblxuICAgIGNvbnN0IHRhYmxlU2NoZW1hID0gcmVzdWx0LnJlc291cmNlcz8uWzBdPy50YWJsZVNjaGVtYVxuICAgIGV4cGVjdCh0YWJsZVNjaGVtYSkudG9CZURlZmluZWQoKVxuICAgIGV4cGVjdCh0eXBlb2YgdGFibGVTY2hlbWEpLm5vdC50b0JlKFwic3RyaW5nXCIpXG4gICAgaWYgKHR5cGVvZiB0YWJsZVNjaGVtYSA9PT0gXCJvYmplY3RcIiAmJiB0YWJsZVNjaGVtYSAhPT0gbnVsbCkge1xuICAgICAgZXhwZWN0KHRhYmxlU2NoZW1hLnByb3BlcnRpZXMpLnRvTWF0Y2hPYmplY3Qoe1xuICAgICAgICBpZDogeyB0eXBlOiBcImludGVnZXJcIiB9LFxuICAgICAgICBuYW1lOiB7IHR5cGU6IFwic3RyaW5nXCIgfSxcbiAgICAgICAgYWN0aXZlOiB7IHR5cGU6IFwiYm9vbGVhblwiIH0sXG4gICAgICB9KVxuICAgIH1cbiAgfSlcblxuICBpdChcInByZXNlcnZlcyBkYXRhc2V0IG1ldGFkYXRhXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBzb3VyY2U6IERhdGFzZXQgPSB7XG4gICAgICBsYW5ndWFnZTogXCJlblwiLFxuICAgICAgdmVyc2lvbjogXCIxLjAuMFwiLFxuICAgICAgcmVzb3VyY2VzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBkYXRhOiBbeyBpZDogMSwgbmFtZTogXCJhbGljZVwiIH1dLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBpbmZlckRhdGFzZXRUb29sLmV4ZWN1dGU/LihcbiAgICAgIHtcbiAgICAgICAgZGF0YXNldDogc291cmNlLFxuICAgICAgfSxcbiAgICAgIHt9LFxuICAgIClcblxuICAgIGV4cGVjdC5hc3NlcnQocmVzdWx0KVxuICAgIGV4cGVjdC5hc3NlcnQoIShcImVycm9yXCIgaW4gcmVzdWx0KSlcblxuICAgIGV4cGVjdChyZXN1bHQubGFuZ3VhZ2UpLnRvQmUoXCJlblwiKVxuICAgIGV4cGVjdChyZXN1bHQudmVyc2lvbikudG9CZShcIjEuMC4wXCIpXG4gIH0pXG59KVxuIl19