@shuttl-io/core 0.2.0 → 0.4.2
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/.jsii +5562 -0
- package/.package.env +1 -0
- package/CHANGELOG.md +67 -0
- package/README.md +353 -1
- package/dist/Server.d.ts +1 -0
- package/dist/Server.js +1 -1
- package/dist/agent.js +2 -2
- package/dist/app.d.ts +2 -2
- package/dist/app.js +8 -6
- package/dist/model.js +1 -1
- package/dist/outcomes/CombinationOutcome.js +1 -1
- package/dist/outcomes/IOutcomes.js +1 -1
- package/dist/outcomes/StreamingOutcome.js +1 -1
- package/dist/secrets.js +2 -2
- package/dist/server/http.d.ts +44 -0
- package/dist/server/http.js +721 -4
- package/dist/tools/tool.js +2 -2
- package/dist/tools/toolkit.js +1 -1
- package/dist/trigger/ApiTrigger.js +1 -1
- package/dist/trigger/EmailTrigger.js +1 -1
- package/dist/trigger/FileTrigger.js +1 -1
- package/dist/trigger/ITrigger.js +1 -1
- package/dist/trigger/RateTrigger.js +1 -1
- package/package.json +2 -2
- package/publish.sh +149 -8
- package/dist/src/Server.d.ts +0 -5
- package/dist/src/Server.js +0 -3
- package/dist/src/Triggers.d.ts +0 -0
- package/dist/src/Triggers.js +0 -2
- package/dist/src/agent.d.ts +0 -49
- package/dist/src/agent.js +0 -251
- package/dist/src/app.d.ts +0 -17
- package/dist/src/app.js +0 -46
- package/dist/src/index.d.ts +0 -12
- package/dist/src/index.js +0 -29
- package/dist/src/model.d.ts +0 -6
- package/dist/src/model.js +0 -16
- package/dist/src/models/openAi.d.ts +0 -38
- package/dist/src/models/openAi.js +0 -344
- package/dist/src/models/types.d.ts +0 -101
- package/dist/src/models/types.js +0 -27
- package/dist/src/outcomes/CombinationOutcome.d.ts +0 -9
- package/dist/src/outcomes/CombinationOutcome.js +0 -41
- package/dist/src/outcomes/IOutcomes.d.ts +0 -9
- package/dist/src/outcomes/IOutcomes.js +0 -19
- package/dist/src/outcomes/StreamingOutcome.d.ts +0 -6
- package/dist/src/outcomes/StreamingOutcome.js +0 -30
- package/dist/src/outcomes/index.d.ts +0 -3
- package/dist/src/outcomes/index.js +0 -20
- package/dist/src/secrets.d.ts +0 -19
- package/dist/src/secrets.js +0 -34
- package/dist/src/server/http.d.ts +0 -68
- package/dist/src/server/http.js +0 -654
- package/dist/src/server/index.d.ts +0 -1
- package/dist/src/server/index.js +0 -18
- package/dist/src/tools/tool.d.ts +0 -33
- package/dist/src/tools/tool.js +0 -49
- package/dist/src/tools/toolkit.d.ts +0 -13
- package/dist/src/tools/toolkit.js +0 -19
- package/dist/src/trigger/ApiTrigger.d.ts +0 -37
- package/dist/src/trigger/ApiTrigger.js +0 -106
- package/dist/src/trigger/EmailTrigger.d.ts +0 -15
- package/dist/src/trigger/EmailTrigger.js +0 -22
- package/dist/src/trigger/FileTrigger.d.ts +0 -14
- package/dist/src/trigger/FileTrigger.js +0 -37
- package/dist/src/trigger/ITrigger.d.ts +0 -89
- package/dist/src/trigger/ITrigger.js +0 -35
- package/dist/src/trigger/RateTrigger.d.ts +0 -23
- package/dist/src/trigger/RateTrigger.js +0 -58
- package/dist/src/trigger/index.d.ts +0 -5
- package/dist/src/trigger/index.js +0 -22
- package/dist/tests/agent.test.d.ts +0 -1
- package/dist/tests/agent.test.js +0 -388
- package/dist/tests/agentStreamer.test.d.ts +0 -1
- package/dist/tests/agentStreamer.test.js +0 -530
- package/dist/tests/app.test.d.ts +0 -1
- package/dist/tests/app.test.js +0 -423
- package/dist/tests/model.test.d.ts +0 -1
- package/dist/tests/model.test.js +0 -310
- package/dist/tests/openAi.test.d.ts +0 -1
- package/dist/tests/openAi.test.js +0 -701
- package/dist/tests/outcomes.test.d.ts +0 -1
- package/dist/tests/outcomes.test.js +0 -257
- package/dist/tests/secrets.test.d.ts +0 -1
- package/dist/tests/secrets.test.js +0 -263
- package/dist/tests/server/http.test.d.ts +0 -1
- package/dist/tests/server/http.test.js +0 -553
- package/dist/tests/tool.test.d.ts +0 -1
- package/dist/tests/tool.test.js +0 -315
- package/dist/tests/toolkit.test.d.ts +0 -1
- package/dist/tests/toolkit.test.js +0 -189
- package/dist/tests/triggers.test.d.ts +0 -1
- package/dist/tests/triggers.test.js +0 -203
- package/dist/tests/types.test.d.ts +0 -1
- package/dist/tests/types.test.js +0 -429
package/dist/tests/app.test.js
DELETED
|
@@ -1,423 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const app_1 = require("../src/app");
|
|
4
|
-
const agent_1 = require("../src/agent");
|
|
5
|
-
const model_1 = require("../src/model");
|
|
6
|
-
const secrets_1 = require("../src/secrets");
|
|
7
|
-
const toolkit_1 = require("../src/tools/toolkit");
|
|
8
|
-
const tool_1 = require("../src/tools/tool");
|
|
9
|
-
// Mock tool implementation for testing
|
|
10
|
-
class MockTool {
|
|
11
|
-
constructor(name, description, args = {}) {
|
|
12
|
-
this.name = name;
|
|
13
|
-
this.description = description;
|
|
14
|
-
this.schema = tool_1.Schema.objectValue(args);
|
|
15
|
-
}
|
|
16
|
-
execute(_args) {
|
|
17
|
-
return { executed: true };
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
// Mock server implementation for testing
|
|
21
|
-
class MockServer {
|
|
22
|
-
constructor() {
|
|
23
|
-
this.acceptedApp = null;
|
|
24
|
-
this.started = false;
|
|
25
|
-
this.stopped = false;
|
|
26
|
-
this.acceptCalls = 0;
|
|
27
|
-
this.startCalls = 0;
|
|
28
|
-
this.stopCalls = 0;
|
|
29
|
-
}
|
|
30
|
-
accept(app) {
|
|
31
|
-
this.acceptedApp = app;
|
|
32
|
-
this.acceptCalls++;
|
|
33
|
-
}
|
|
34
|
-
async start() {
|
|
35
|
-
this.started = true;
|
|
36
|
-
this.startCalls++;
|
|
37
|
-
}
|
|
38
|
-
async stop() {
|
|
39
|
-
this.stopped = true;
|
|
40
|
-
this.stopCalls++;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
// Mock streamer for testing
|
|
44
|
-
class MockStreamer {
|
|
45
|
-
constructor() {
|
|
46
|
-
this.receivedResponses = [];
|
|
47
|
-
this.receivedModels = [];
|
|
48
|
-
}
|
|
49
|
-
async recieve(model, content) {
|
|
50
|
-
this.receivedModels.push(model);
|
|
51
|
-
this.receivedResponses.push(content);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
// Mock model for testing without real API calls
|
|
55
|
-
class MockModel {
|
|
56
|
-
constructor() {
|
|
57
|
-
this.threadId = "mock-thread-id";
|
|
58
|
-
}
|
|
59
|
-
async invoke(prompt, streamer) {
|
|
60
|
-
await streamer.recieve(this, {
|
|
61
|
-
eventName: "response.output_text.done",
|
|
62
|
-
data: {
|
|
63
|
-
typeName: "output_text",
|
|
64
|
-
outputText: {
|
|
65
|
-
outputType: "output_text",
|
|
66
|
-
text: `Mock response to: ${prompt[0]?.content || "empty"}`,
|
|
67
|
-
},
|
|
68
|
-
},
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
// Mock factory for testing
|
|
73
|
-
class MockModelFactory {
|
|
74
|
-
async create(_props) {
|
|
75
|
-
return new MockModel();
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
describe("App", () => {
|
|
79
|
-
let mockServer;
|
|
80
|
-
let defaultModelFactory;
|
|
81
|
-
beforeEach(() => {
|
|
82
|
-
mockServer = new MockServer();
|
|
83
|
-
defaultModelFactory = model_1.Model.openAI("gpt-4", secrets_1.Secret.fromEnv("OPENAI_API_KEY"));
|
|
84
|
-
});
|
|
85
|
-
describe("constructor", () => {
|
|
86
|
-
it("should create an App with name and server", () => {
|
|
87
|
-
const app = new app_1.App("TestApp", mockServer);
|
|
88
|
-
expect(app.name).toBe("TestApp");
|
|
89
|
-
expect(app.server).toBe(mockServer);
|
|
90
|
-
expect(app.agents).toEqual([]);
|
|
91
|
-
expect(app.toolkits.size).toBe(0);
|
|
92
|
-
});
|
|
93
|
-
it("should call server.accept() during construction", () => {
|
|
94
|
-
const app = new app_1.App("TestApp", mockServer);
|
|
95
|
-
expect(mockServer.acceptCalls).toBe(1);
|
|
96
|
-
expect(mockServer.acceptedApp).toBe(app);
|
|
97
|
-
});
|
|
98
|
-
it("should create an App with empty string name", () => {
|
|
99
|
-
const app = new app_1.App("", mockServer);
|
|
100
|
-
expect(app.name).toBe("");
|
|
101
|
-
});
|
|
102
|
-
it("should initialize agents as empty array", () => {
|
|
103
|
-
const app = new app_1.App("TestApp", mockServer);
|
|
104
|
-
expect(app.agents).toBeDefined();
|
|
105
|
-
expect(Array.isArray(app.agents)).toBe(true);
|
|
106
|
-
expect(app.agents).toHaveLength(0);
|
|
107
|
-
});
|
|
108
|
-
it("should initialize toolkits as empty Set", () => {
|
|
109
|
-
const app = new app_1.App("TestApp", mockServer);
|
|
110
|
-
expect(app.toolkits).toBeDefined();
|
|
111
|
-
expect(app.toolkits).toBeInstanceOf(Set);
|
|
112
|
-
expect(app.toolkits.size).toBe(0);
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
describe("addAgent()", () => {
|
|
116
|
-
it("should add an agent to the app", () => {
|
|
117
|
-
const app = new app_1.App("TestApp", mockServer);
|
|
118
|
-
const agent = new agent_1.Agent({
|
|
119
|
-
name: "TestAgent",
|
|
120
|
-
toolkits: [],
|
|
121
|
-
systemPrompt: "Test prompt",
|
|
122
|
-
model: defaultModelFactory,
|
|
123
|
-
});
|
|
124
|
-
app.addAgent(agent);
|
|
125
|
-
expect(app.agents).toHaveLength(1);
|
|
126
|
-
expect(app.agents[0]).toBe(agent);
|
|
127
|
-
});
|
|
128
|
-
it("should add multiple agents", () => {
|
|
129
|
-
const app = new app_1.App("TestApp", mockServer);
|
|
130
|
-
const agent1 = new agent_1.Agent({
|
|
131
|
-
name: "Agent1",
|
|
132
|
-
toolkits: [],
|
|
133
|
-
systemPrompt: "Prompt 1",
|
|
134
|
-
model: defaultModelFactory,
|
|
135
|
-
});
|
|
136
|
-
const agent2 = new agent_1.Agent({
|
|
137
|
-
name: "Agent2",
|
|
138
|
-
toolkits: [],
|
|
139
|
-
systemPrompt: "Prompt 2",
|
|
140
|
-
model: defaultModelFactory,
|
|
141
|
-
});
|
|
142
|
-
app.addAgent(agent1);
|
|
143
|
-
app.addAgent(agent2);
|
|
144
|
-
expect(app.agents).toHaveLength(2);
|
|
145
|
-
expect(app.agents[0]).toBe(agent1);
|
|
146
|
-
expect(app.agents[1]).toBe(agent2);
|
|
147
|
-
});
|
|
148
|
-
it("should add agent toolkits to app toolkits", () => {
|
|
149
|
-
const app = new app_1.App("TestApp", mockServer);
|
|
150
|
-
const toolkit = new toolkit_1.Toolkit({ name: "TestToolkit" });
|
|
151
|
-
const agent = new agent_1.Agent({
|
|
152
|
-
name: "TestAgent",
|
|
153
|
-
toolkits: [toolkit],
|
|
154
|
-
systemPrompt: "Test prompt",
|
|
155
|
-
model: defaultModelFactory,
|
|
156
|
-
});
|
|
157
|
-
app.addAgent(agent);
|
|
158
|
-
expect(app.toolkits.size).toBe(1);
|
|
159
|
-
expect(app.toolkits.has(toolkit)).toBe(true);
|
|
160
|
-
});
|
|
161
|
-
it("should add multiple toolkits from agent", () => {
|
|
162
|
-
const app = new app_1.App("TestApp", mockServer);
|
|
163
|
-
const toolkit1 = new toolkit_1.Toolkit({ name: "Toolkit1" });
|
|
164
|
-
const toolkit2 = new toolkit_1.Toolkit({ name: "Toolkit2" });
|
|
165
|
-
const agent = new agent_1.Agent({
|
|
166
|
-
name: "TestAgent",
|
|
167
|
-
toolkits: [toolkit1, toolkit2],
|
|
168
|
-
systemPrompt: "Test prompt",
|
|
169
|
-
model: defaultModelFactory,
|
|
170
|
-
});
|
|
171
|
-
app.addAgent(agent);
|
|
172
|
-
expect(app.toolkits.size).toBe(2);
|
|
173
|
-
expect(app.toolkits.has(toolkit1)).toBe(true);
|
|
174
|
-
expect(app.toolkits.has(toolkit2)).toBe(true);
|
|
175
|
-
});
|
|
176
|
-
it("should not duplicate toolkits when adding same toolkit from multiple agents", () => {
|
|
177
|
-
const app = new app_1.App("TestApp", mockServer);
|
|
178
|
-
const sharedToolkit = new toolkit_1.Toolkit({ name: "SharedToolkit" });
|
|
179
|
-
const agent1 = new agent_1.Agent({
|
|
180
|
-
name: "Agent1",
|
|
181
|
-
toolkits: [sharedToolkit],
|
|
182
|
-
systemPrompt: "Prompt 1",
|
|
183
|
-
model: defaultModelFactory,
|
|
184
|
-
});
|
|
185
|
-
const agent2 = new agent_1.Agent({
|
|
186
|
-
name: "Agent2",
|
|
187
|
-
toolkits: [sharedToolkit],
|
|
188
|
-
systemPrompt: "Prompt 2",
|
|
189
|
-
model: defaultModelFactory,
|
|
190
|
-
});
|
|
191
|
-
app.addAgent(agent1);
|
|
192
|
-
app.addAgent(agent2);
|
|
193
|
-
expect(app.toolkits.size).toBe(1);
|
|
194
|
-
expect(app.toolkits.has(sharedToolkit)).toBe(true);
|
|
195
|
-
});
|
|
196
|
-
it("should allow adding the same agent twice", () => {
|
|
197
|
-
const app = new app_1.App("TestApp", mockServer);
|
|
198
|
-
const agent = new agent_1.Agent({
|
|
199
|
-
name: "TestAgent",
|
|
200
|
-
toolkits: [],
|
|
201
|
-
systemPrompt: "Test prompt",
|
|
202
|
-
model: defaultModelFactory,
|
|
203
|
-
});
|
|
204
|
-
app.addAgent(agent);
|
|
205
|
-
app.addAgent(agent);
|
|
206
|
-
expect(app.agents).toHaveLength(2);
|
|
207
|
-
expect(app.agents[0]).toBe(agent);
|
|
208
|
-
expect(app.agents[1]).toBe(agent);
|
|
209
|
-
});
|
|
210
|
-
it("should handle agent with no toolkits", () => {
|
|
211
|
-
const app = new app_1.App("TestApp", mockServer);
|
|
212
|
-
const agent = new agent_1.Agent({
|
|
213
|
-
name: "NoToolkitAgent",
|
|
214
|
-
toolkits: [],
|
|
215
|
-
systemPrompt: "No toolkits",
|
|
216
|
-
model: defaultModelFactory,
|
|
217
|
-
});
|
|
218
|
-
app.addAgent(agent);
|
|
219
|
-
expect(app.agents).toHaveLength(1);
|
|
220
|
-
expect(app.toolkits.size).toBe(0);
|
|
221
|
-
});
|
|
222
|
-
});
|
|
223
|
-
describe("addToolkit()", () => {
|
|
224
|
-
it("should add a toolkit to the app", () => {
|
|
225
|
-
const app = new app_1.App("TestApp", mockServer);
|
|
226
|
-
const toolkit = new toolkit_1.Toolkit({ name: "TestToolkit" });
|
|
227
|
-
app.addToolkit(toolkit);
|
|
228
|
-
expect(app.toolkits.size).toBe(1);
|
|
229
|
-
expect(app.toolkits.has(toolkit)).toBe(true);
|
|
230
|
-
});
|
|
231
|
-
it("should add multiple toolkits", () => {
|
|
232
|
-
const app = new app_1.App("TestApp", mockServer);
|
|
233
|
-
const toolkit1 = new toolkit_1.Toolkit({ name: "Toolkit1" });
|
|
234
|
-
const toolkit2 = new toolkit_1.Toolkit({ name: "Toolkit2" });
|
|
235
|
-
app.addToolkit(toolkit1);
|
|
236
|
-
app.addToolkit(toolkit2);
|
|
237
|
-
expect(app.toolkits.size).toBe(2);
|
|
238
|
-
expect(app.toolkits.has(toolkit1)).toBe(true);
|
|
239
|
-
expect(app.toolkits.has(toolkit2)).toBe(true);
|
|
240
|
-
});
|
|
241
|
-
it("should not duplicate toolkit when adding same toolkit twice", () => {
|
|
242
|
-
const app = new app_1.App("TestApp", mockServer);
|
|
243
|
-
const toolkit = new toolkit_1.Toolkit({ name: "TestToolkit" });
|
|
244
|
-
app.addToolkit(toolkit);
|
|
245
|
-
app.addToolkit(toolkit);
|
|
246
|
-
expect(app.toolkits.size).toBe(1);
|
|
247
|
-
});
|
|
248
|
-
it("should add toolkit with tools", () => {
|
|
249
|
-
const app = new app_1.App("TestApp", mockServer);
|
|
250
|
-
const tool = new MockTool("testTool", "A test tool");
|
|
251
|
-
const toolkit = new toolkit_1.Toolkit({
|
|
252
|
-
name: "TestToolkit",
|
|
253
|
-
tools: [tool],
|
|
254
|
-
});
|
|
255
|
-
app.addToolkit(toolkit);
|
|
256
|
-
expect(app.toolkits.size).toBe(1);
|
|
257
|
-
const addedToolkit = Array.from(app.toolkits)[0];
|
|
258
|
-
expect(addedToolkit.tools).toHaveLength(1);
|
|
259
|
-
expect(addedToolkit.tools[0].name).toBe("testTool");
|
|
260
|
-
});
|
|
261
|
-
});
|
|
262
|
-
describe("serve()", () => {
|
|
263
|
-
it("should call server.start()", () => {
|
|
264
|
-
const app = new app_1.App("TestApp", mockServer);
|
|
265
|
-
app.serve();
|
|
266
|
-
expect(mockServer.startCalls).toBe(1);
|
|
267
|
-
expect(mockServer.started).toBe(true);
|
|
268
|
-
});
|
|
269
|
-
it("should be callable multiple times", () => {
|
|
270
|
-
const app = new app_1.App("TestApp", mockServer);
|
|
271
|
-
app.serve();
|
|
272
|
-
app.serve();
|
|
273
|
-
app.serve();
|
|
274
|
-
expect(mockServer.startCalls).toBe(3);
|
|
275
|
-
});
|
|
276
|
-
});
|
|
277
|
-
describe("integration scenarios", () => {
|
|
278
|
-
it("should work with complete app setup", () => {
|
|
279
|
-
const app = new app_1.App("CompleteApp", mockServer);
|
|
280
|
-
// Create tools
|
|
281
|
-
const searchTool = new MockTool("search", "Search for items");
|
|
282
|
-
const createTool = new MockTool("create", "Create new item");
|
|
283
|
-
// Create toolkits
|
|
284
|
-
const searchToolkit = new toolkit_1.Toolkit({
|
|
285
|
-
name: "SearchToolkit",
|
|
286
|
-
description: "Tools for searching",
|
|
287
|
-
tools: [searchTool],
|
|
288
|
-
});
|
|
289
|
-
const crudToolkit = new toolkit_1.Toolkit({
|
|
290
|
-
name: "CRUDToolkit",
|
|
291
|
-
description: "CRUD operations",
|
|
292
|
-
tools: [createTool],
|
|
293
|
-
});
|
|
294
|
-
// Create agents
|
|
295
|
-
const searchAgent = new agent_1.Agent({
|
|
296
|
-
name: "SearchAgent",
|
|
297
|
-
toolkits: [searchToolkit],
|
|
298
|
-
systemPrompt: "You are a search agent",
|
|
299
|
-
model: defaultModelFactory,
|
|
300
|
-
});
|
|
301
|
-
const crudAgent = new agent_1.Agent({
|
|
302
|
-
name: "CRUDAgent",
|
|
303
|
-
toolkits: [crudToolkit],
|
|
304
|
-
systemPrompt: "You are a CRUD agent",
|
|
305
|
-
model: defaultModelFactory,
|
|
306
|
-
});
|
|
307
|
-
// Add agents to app
|
|
308
|
-
app.addAgent(searchAgent);
|
|
309
|
-
app.addAgent(crudAgent);
|
|
310
|
-
// Add additional toolkit directly
|
|
311
|
-
const utilToolkit = new toolkit_1.Toolkit({ name: "UtilToolkit" });
|
|
312
|
-
app.addToolkit(utilToolkit);
|
|
313
|
-
// Verify state
|
|
314
|
-
expect(app.name).toBe("CompleteApp");
|
|
315
|
-
expect(app.agents).toHaveLength(2);
|
|
316
|
-
expect(app.toolkits.size).toBe(3);
|
|
317
|
-
expect(mockServer.acceptedApp).toBe(app);
|
|
318
|
-
});
|
|
319
|
-
it("should maintain references correctly", () => {
|
|
320
|
-
const app = new app_1.App("RefApp", mockServer);
|
|
321
|
-
const toolkit = new toolkit_1.Toolkit({ name: "SharedToolkit" });
|
|
322
|
-
const agent = new agent_1.Agent({
|
|
323
|
-
name: "RefAgent",
|
|
324
|
-
toolkits: [toolkit],
|
|
325
|
-
systemPrompt: "Test",
|
|
326
|
-
model: defaultModelFactory,
|
|
327
|
-
});
|
|
328
|
-
app.addAgent(agent);
|
|
329
|
-
app.addToolkit(toolkit);
|
|
330
|
-
// Agent toolkit and app toolkit should be same reference
|
|
331
|
-
expect(app.agents[0].toolkits[0]).toBe(toolkit);
|
|
332
|
-
expect(Array.from(app.toolkits)[0]).toBe(toolkit);
|
|
333
|
-
});
|
|
334
|
-
it("should allow iteration over toolkits", () => {
|
|
335
|
-
const app = new app_1.App("IterApp", mockServer);
|
|
336
|
-
const toolkit1 = new toolkit_1.Toolkit({ name: "Toolkit1" });
|
|
337
|
-
const toolkit2 = new toolkit_1.Toolkit({ name: "Toolkit2" });
|
|
338
|
-
app.addToolkit(toolkit1);
|
|
339
|
-
app.addToolkit(toolkit2);
|
|
340
|
-
const toolkitNames = [];
|
|
341
|
-
app.toolkits.forEach((toolkit) => {
|
|
342
|
-
toolkitNames.push(toolkit.name);
|
|
343
|
-
});
|
|
344
|
-
expect(toolkitNames).toContain("Toolkit1");
|
|
345
|
-
expect(toolkitNames).toContain("Toolkit2");
|
|
346
|
-
});
|
|
347
|
-
});
|
|
348
|
-
describe("readonly properties", () => {
|
|
349
|
-
it("should have readonly name property", () => {
|
|
350
|
-
const app = new app_1.App("ReadonlyApp", mockServer);
|
|
351
|
-
expect(app.name).toBeDefined();
|
|
352
|
-
expect(typeof app.name).toBe("string");
|
|
353
|
-
});
|
|
354
|
-
it("should have agents array that can be read", () => {
|
|
355
|
-
const app = new app_1.App("TestApp", mockServer);
|
|
356
|
-
expect(app.agents).toBeDefined();
|
|
357
|
-
expect(Array.isArray(app.agents)).toBe(true);
|
|
358
|
-
});
|
|
359
|
-
it("should have toolkits Set that can be read", () => {
|
|
360
|
-
const app = new app_1.App("TestApp", mockServer);
|
|
361
|
-
expect(app.toolkits).toBeDefined();
|
|
362
|
-
expect(app.toolkits).toBeInstanceOf(Set);
|
|
363
|
-
});
|
|
364
|
-
it("should have server that can be read", () => {
|
|
365
|
-
const app = new app_1.App("TestApp", mockServer);
|
|
366
|
-
expect(app.server).toBeDefined();
|
|
367
|
-
expect(app.server).toBe(mockServer);
|
|
368
|
-
});
|
|
369
|
-
});
|
|
370
|
-
describe("IServer interface compliance", () => {
|
|
371
|
-
it("should work with any IServer implementation", () => {
|
|
372
|
-
class CustomServer {
|
|
373
|
-
constructor() {
|
|
374
|
-
this.accepted = false;
|
|
375
|
-
this.running = false;
|
|
376
|
-
}
|
|
377
|
-
accept(_app) {
|
|
378
|
-
this.accepted = true;
|
|
379
|
-
}
|
|
380
|
-
async start() {
|
|
381
|
-
this.running = true;
|
|
382
|
-
}
|
|
383
|
-
async stop() {
|
|
384
|
-
this.running = false;
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
const customServer = new CustomServer();
|
|
388
|
-
const app = new app_1.App("CustomApp", customServer);
|
|
389
|
-
expect(customServer.accepted).toBe(true);
|
|
390
|
-
app.serve();
|
|
391
|
-
expect(customServer.running).toBe(true);
|
|
392
|
-
});
|
|
393
|
-
});
|
|
394
|
-
});
|
|
395
|
-
describe("Model factory methods", () => {
|
|
396
|
-
describe("Model.openAI()", () => {
|
|
397
|
-
it("should create an OpenAI model factory with env secret", () => {
|
|
398
|
-
const secret = secrets_1.Secret.fromEnv("OPENAI_API_KEY");
|
|
399
|
-
const factory = model_1.Model.openAI("gpt-4", secret);
|
|
400
|
-
expect(factory).toBeDefined();
|
|
401
|
-
expect(typeof factory.create).toBe("function");
|
|
402
|
-
});
|
|
403
|
-
it("should create model factories with different identifiers", () => {
|
|
404
|
-
const secret = secrets_1.Secret.fromEnv("OPENAI_API_KEY");
|
|
405
|
-
const gpt4 = model_1.Model.openAI("gpt-4", secret);
|
|
406
|
-
const gpt35 = model_1.Model.openAI("gpt-3.5-turbo", secret);
|
|
407
|
-
expect(gpt4).toBeDefined();
|
|
408
|
-
expect(gpt35).toBeDefined();
|
|
409
|
-
});
|
|
410
|
-
it("should create model instances from mock factory and invoke with streamer", async () => {
|
|
411
|
-
const mockFactory = new MockModelFactory();
|
|
412
|
-
const model = await mockFactory.create({
|
|
413
|
-
systemPrompt: "You are a helpful assistant.",
|
|
414
|
-
});
|
|
415
|
-
const streamer = new MockStreamer();
|
|
416
|
-
await model.invoke([{ content: "Hello", role: "user" }], streamer);
|
|
417
|
-
expect(streamer.receivedResponses.length).toBeGreaterThan(0);
|
|
418
|
-
expect(streamer.receivedModels[0]).toBe(model);
|
|
419
|
-
expect(model.threadId).toBe("mock-thread-id");
|
|
420
|
-
});
|
|
421
|
-
});
|
|
422
|
-
});
|
|
423
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90ZXN0cy9hcHAudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLG9DQUFpQztBQUNqQyx3Q0FBcUM7QUFDckMsd0NBQXFDO0FBQ3JDLDRDQUF3QztBQUV4QyxrREFBK0M7QUFFL0MsNENBQWtFO0FBRWxFLHVDQUF1QztBQUN2QyxNQUFNLFFBQVE7SUFLVixZQUFZLElBQVksRUFBRSxXQUFtQixFQUFFLE9BQXVDLEVBQUU7UUFDcEYsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUM7UUFDL0IsSUFBSSxDQUFDLE1BQU0sR0FBRyxhQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFFRCxPQUFPLENBQUMsS0FBOEI7UUFDbEMsT0FBTyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQztJQUM5QixDQUFDO0NBQ0o7QUFFRCx5Q0FBeUM7QUFDekMsTUFBTSxVQUFVO0lBQWhCO1FBQ1csZ0JBQVcsR0FBbUIsSUFBSSxDQUFDO1FBQ25DLFlBQU8sR0FBWSxLQUFLLENBQUM7UUFDekIsWUFBTyxHQUFZLEtBQUssQ0FBQztRQUN6QixnQkFBVyxHQUFXLENBQUMsQ0FBQztRQUN4QixlQUFVLEdBQVcsQ0FBQyxDQUFDO1FBQ3ZCLGNBQVMsR0FBVyxDQUFDLENBQUM7SUFnQmpDLENBQUM7SUFkRyxNQUFNLENBQUMsR0FBWTtRQUNmLElBQUksQ0FBQyxXQUFXLEdBQUcsR0FBRyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUN2QixDQUFDO0lBRUQsS0FBSyxDQUFDLEtBQUs7UUFDUCxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztRQUNwQixJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7SUFDdEIsQ0FBQztJQUVELEtBQUssQ0FBQyxJQUFJ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cFwiO1xuaW1wb3J0IHsgQWdlbnQgfSBmcm9tIFwiLi4vc3JjL2FnZW50XCI7XG5pbXBvcnQgeyBNb2RlbCB9IGZyb20gXCIuLi9zcmMvbW9kZWxcIjtcbmltcG9ydCB7IFNlY3JldCB9IGZyb20gXCIuLi9zcmMvc2VjcmV0c1wiO1xuaW1wb3J0IHsgSU1vZGVsRmFjdG9yeSwgSU1vZGVsU3RyZWFtZXIsIE1vZGVsQ29udGVudCwgSU1vZGVsLCBNb2RlbFJlc3BvbnNlIH0gZnJvbSBcIi4uL3NyYy9tb2RlbHMvdHlwZXNcIjtcbmltcG9ydCB7IFRvb2xraXQgfSBmcm9tIFwiLi4vc3JjL3Rvb2xzL3Rvb2xraXRcIjtcbmltcG9ydCB7IElTZXJ2ZXIgfSBmcm9tIFwiLi4vc3JjL1NlcnZlclwiO1xuaW1wb3J0IHsgSVRvb2wsIFNjaGVtYSwgVG9vbEFyZ0J1aWxkZXIgfSBmcm9tIFwiLi4vc3JjL3Rvb2xzL3Rvb2xcIjtcblxuLy8gTW9jayB0b29sIGltcGxlbWVudGF0aW9uIGZvciB0ZXN0aW5nXG5jbGFzcyBNb2NrVG9vbCBpbXBsZW1lbnRzIElUb29sIHtcbiAgICBwdWJsaWMgbmFtZTogc3RyaW5nO1xuICAgIHB1YmxpYyBkZXNjcmlwdGlvbjogc3RyaW5nO1xuICAgIHB1YmxpYyBzY2hlbWE6IFNjaGVtYTtcblxuICAgIGNvbnN0cnVjdG9yKG5hbWU6IHN0cmluZywgZGVzY3JpcHRpb246IHN0cmluZywgYXJnczogUmVjb3JkPHN0cmluZywgVG9vbEFyZ0J1aWxkZXI+ID0ge30pIHtcbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcbiAgICAgICAgdGhpcy5kZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uO1xuICAgICAgICB0aGlzLnNjaGVtYSA9IFNjaGVtYS5vYmplY3RWYWx1ZShhcmdzKTtcbiAgICB9XG5cbiAgICBleGVjdXRlKF9hcmdzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IHVua25vd24ge1xuICAgICAgICByZXR1cm4geyBleGVjdXRlZDogdHJ1ZSB9O1xuICAgIH1cbn1cblxuLy8gTW9jayBzZXJ2ZXIgaW1wbGVtZW50YXRpb24gZm9yIHRlc3RpbmdcbmNsYXNzIE1vY2tTZXJ2ZXIgaW1wbGVtZW50cyBJU2VydmVyIHtcbiAgICBwdWJsaWMgYWNjZXB0ZWRBcHA6IHVua25vd24gfCBudWxsID0gbnVsbDtcbiAgICBwdWJsaWMgc3RhcnRlZDogYm9vbGVhbiA9IGZhbHNlO1xuICAgIHB1YmxpYyBzdG9wcGVkOiBib29sZWFuID0gZmFsc2U7XG4gICAgcHVibGljIGFjY2VwdENhbGxzOiBudW1iZXIgPSAwO1xuICAgIHB1YmxpYyBzdGFydENhbGxzOiBudW1iZXIgPSAwO1xuICAgIHB1YmxpYyBzdG9wQ2FsbHM6IG51bWJlciA9IDA7XG5cbiAgICBhY2NlcHQoYXBwOiB1bmtub3duKTogdm9pZCB7XG4gICAgICAgIHRoaXMuYWNjZXB0ZWRBcHAgPSBhcHA7XG4gICAgICAgIHRoaXMuYWNjZXB0Q2FsbHMrKztcbiAgICB9XG5cbiAgICBhc3luYyBzdGFydCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5zdGFydGVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5zdGFydENhbGxzKys7XG4gICAgfVxuXG4gICAgYXN5bmMgc3RvcCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5zdG9wcGVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5zdG9wQ2FsbHMrKztcbiAgICB9XG59XG5cbi8vIE1vY2sgc3RyZWFtZXIgZm9yIHRlc3RpbmdcbmNsYXNzIE1vY2tTdHJlYW1lciBpbXBsZW1lbnRzIElNb2RlbFN0cmVhbWVyIHtcbiAgICBwdWJsaWMgcmVjZWl2ZWRSZXNwb25zZXM6IE1vZGVsUmVzcG9uc2VbXSA9IFtdO1xuICAgIHB1YmxpYyByZWNlaXZlZE1vZGVsczogSU1vZGVsW10gPSBbXTtcblxuICAgIGFzeW5jIHJlY2lldmUobW9kZWw6IElNb2RlbCwgY29udGVudDogTW9kZWxSZXNwb25zZSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0aGlzLnJlY2VpdmVkTW9kZWxzLnB1c2gobW9kZWwpO1xuICAgICAgICB0aGlzLnJlY2VpdmVkUmVzcG9uc2VzLnB1c2goY29udGVudCk7XG4gICAgfVxufVxuXG4vLyBNb2NrIG1vZGVsIGZvciB0ZXN0aW5nIHdpdGhvdXQgcmVhbCBBUEkgY2FsbHNcbmNsYXNzIE1vY2tNb2RlbCBpbXBsZW1lbnRzIElNb2RlbCB7XG4gICAgcHVibGljIHJlYWRvbmx5IHRocmVhZElkPzogc3RyaW5nID0gXCJtb2NrLXRocmVhZC1pZFwiO1xuXG4gICAgYXN5bmMgaW52b2tlKHByb21wdDogTW9kZWxDb250ZW50W10sIHN0cmVhbWVyOiBJTW9kZWxTdHJlYW1lcik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCBzdHJlYW1lci5yZWNpZXZlKHRoaXMsIHtcbiAgICAgICAgICAgIGV2ZW50TmFtZTogXCJyZXNwb25zZS5vdXRwdXRfdGV4dC5kb25lXCIsXG4gICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgICAgdHlwZU5hbWU6IFwib3V0cHV0X3RleHRcIixcbiAgICAgICAgICAgICAgICBvdXRwdXRUZXh0OiB7XG4gICAgICAgICAgICAgICAgICAgIG91dHB1dFR5cGU6IFwib3V0cHV0X3RleHRcIixcbiAgICAgICAgICAgICAgICAgICAgdGV4dDogYE1vY2sgcmVzcG9uc2UgdG86ICR7cHJvbXB0WzBdPy5jb250ZW50IHx8IFwiZW1wdHlcIn1gLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICB9XG59XG5cbi8vIE1vY2sgZmFjdG9yeSBmb3IgdGVzdGluZ1xuY2xhc3MgTW9ja01vZGVsRmFjdG9yeSBpbXBsZW1lbnRzIElNb2RlbEZhY3Rvcnkge1xuICAgIGFzeW5jIGNyZWF0ZShfcHJvcHM6IHsgc3lzdGVtUHJvbXB0OiBzdHJpbmcgfSk6IFByb21pc2U8SU1vZGVsPiB7XG4gICAgICAgIHJldHVybiBuZXcgTW9ja01vZGVsKCk7XG4gICAgfVxufVxuXG5kZXNjcmliZShcIkFwcFwiLCAoKSA9PiB7XG4gICAgbGV0IG1vY2tTZXJ2ZXI6IE1vY2tTZXJ2ZXI7XG4gICAgbGV0IGRlZmF1bHRNb2RlbEZhY3Rvcnk6IElNb2RlbEZhY3Rvcnk7XG5cbiAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgICAgbW9ja1NlcnZlciA9IG5ldyBNb2NrU2VydmVyKCk7XG4gICAgICAgIGRlZmF1bHRNb2RlbEZhY3RvcnkgPSBNb2RlbC5vcGVuQUkoXCJncHQtNFwiLCBTZWNyZXQuZnJvbUVudihcIk9QRU5BSV9BUElfS0VZXCIpKTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKFwiY29uc3RydWN0b3JcIiwgKCkgPT4ge1xuICAgICAgICBpdChcInNob3VsZCBjcmVhdGUgYW4gQXBwIHdpdGggbmFtZSBhbmQgc2VydmVyXCIsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFwcCA9IG5ldyBBcHAoXCJUZXN0QXBwXCIsIG1vY2tTZXJ2ZXIpO1xuXG4gICAgICAgICAgICBleHBlY3QoYXBwLm5hbWUpLnRvQmUoXCJUZXN0QXBwXCIpO1xuICAgICAgICAgICAgZXhwZWN0KGFwcC5zZXJ2ZXIpLnRvQmUobW9ja1NlcnZlcik7XG4gICAgICAgICAgICBleHBlY3QoYXBwLmFnZW50cykudG9FcXVhbChbXSk7XG4gICAgICAgICAgICBleHBlY3QoYXBwLnRvb2xraXRzLnNpemUpLnRvQmUoMCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KFwic2hvdWxkIGNhbGwgc2VydmVyLmFjY2VwdCgpIGR1cmluZyBjb25zdHJ1Y3Rpb25cIiwgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYXBwID0gbmV3IEFwcChcIlRlc3RBcHBcIiwgbW9ja1NlcnZlcik7XG5cbiAgICAgICAgICAgIGV4cGVjdChtb2NrU2VydmVyLmFjY2VwdENhbGxzKS50b0JlKDEpO1xuICAgICAgICAgICAgZXhwZWN0KG1vY2tTZXJ2ZXIuYWNjZXB0ZWRBcHApLnRvQmUoYXBwKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoXCJzaG91bGQgY3JlYXRlIGFuIEFwcCB3aXRoIGVtcHR5IHN0cmluZyBuYW1lXCIsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFwcCA9IG5ldyBBcHAoXCJcIiwgbW9ja1NlcnZlcik7XG5cbiAgICAgICAgICAgIGV4cGVjdChhcHAubmFtZSkudG9CZShcIlwiKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoXCJzaG91bGQgaW5pdGlhbGl6ZSBhZ2VudHMgYXMgZW1wdHkgYXJyYXlcIiwgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYXBwID0gbmV3IEFwcChcIlRlc3RBcHBcIiwgbW9ja1NlcnZlcik7XG5cbiAgICAgICAgICAgIGV4cGVjdChhcHAuYWdlbnRzKS50b0JlRGVmaW5lZCgpO1xuICAgICAgICAgICAgZXhwZWN0KEFycmF5LmlzQXJyYXkoYXBwLmFnZW50cykpLnRvQmUodHJ1ZSk7XG4gICAgICAgICAgICBleHBlY3QoYXBwLmFnZW50cykudG9IYXZlTGVuZ3RoKDApO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdChcInNob3VsZCBpbml0aWFsaXplIHRvb2xraXRzIGFzIGVtcHR5IFNldFwiLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhcHAgPSBuZXcgQXBwKFwiVGVzdEFwcFwiLCBtb2NrU2VydmVyKTtcblxuICAgICAgICAgICAgZXhwZWN0KGFwcC50b29sa2l0cykudG9CZURlZmluZWQoKTtcbiAgICAgICAgICAgIGV4cGVjdChhcHAudG9vbGtpdHMpLnRvQmVJbnN0YW5jZU9mKFNldCk7XG4gICAgICAgICAgICBleHBlY3QoYXBwLnRvb2xraXRzLnNpemUpLnRvQmUoMCk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoXCJhZGRBZ2VudCgpXCIsICgpID0+IHtcbiAgICAgICAgaXQoXCJzaG91bGQgYWRkIGFuIGFnZW50IHRvIHRoZSBhcHBcIiwgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYXBwID0gbmV3IEFwcChcIlRlc3RBcHBcIiwgbW9ja1NlcnZlcik7XG4gICAgICAgICAgICBjb25zdCBhZ2VudCA9IG5ldyBBZ2VudCh7XG4gICAgICAgICAgICAgICAgbmFtZTogXCJUZXN0QWdlbnRcIixcbiAgICAgICAgICAgICAgICB0b29sa2l0czogW10sXG4gICAgICAgICAgICAgICAgc3lzdGVtUHJvbXB0OiBcIlRlc3QgcHJvbXB0XCIsXG4gICAgICAgICAgICAgICAgbW9kZWw6IGRlZmF1bHRNb2RlbEZhY3RvcnksXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgYXBwLmFkZEFnZW50KGFnZW50KTtcblxuICAgICAgICAgICAgZXhwZWN0KGFwcC5hZ2VudHMpLnRvSGF2ZUxlbmd0aCgxKTtcbiAgICAgICAgICAgIGV4cGVjdChhcHAuYWdlbnRzWzBdKS50b0JlKGFnZW50KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoXCJzaG91bGQgYWRkIG11bHRpcGxlIGFnZW50c1wiLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhcHAgPSBuZXcgQXBwKFwiVGVzdEFwcFwiLCBtb2NrU2VydmVyKTtcbiAgICAgICAgICAgIGNvbnN0IGFnZW50MSA9IG5ldyBBZ2VudCh7XG4gICAgICAgICAgICAgICAgbmFtZTogXCJBZ2VudDFcIixcbiAgICAgICAgICAgICAgICB0b29sa2l0czogW10sXG4gICAgICAgICAgICAgICAgc3lzdGVtUHJvbXB0OiBcIlByb21wdCAxXCIsXG4gICAgICAgICAgICAgICAgbW9kZWw6IGRlZmF1bHRNb2RlbEZhY3RvcnksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IGFnZW50MiA9IG5ldyBBZ2VudCh7XG4gICAgICAgICAgICAgICAgbmFtZTogXCJBZ2VudDJcIixcbiAgICAgICAgICAgICAgICB0b29sa2l0czogW10sXG4gICAgICAgICAgICAgICAgc3lzdGVtUHJvbXB0OiBcIlByb21wdCAyXCIsXG4gICAgICAgICAgICAgICAgbW9kZWw6IGRlZmF1bHRNb2RlbEZhY3RvcnksXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgYXBwLmFkZEFnZW50KGFnZW50MSk7XG4gICAgICAgICAgICBhcHAuYWRkQWdlbnQoYWdlbnQyKTtcblxuICAgICAgICAgICAgZXhwZWN0KGFwcC5hZ2VudHMpLnRvSGF2ZUxlbmd0aCgyKTtcbiAgICAgICAgICAgIGV4cGVjdChhcHAuYWdlbnRzWzBdKS50b0JlKGFnZW50MSk7XG4gICAgICAgICAgICBleHBlY3QoYXBwLmFnZW50c1sxXSkudG9CZShhZ2VudDIpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdChcInNob3VsZCBhZGQgYWdlbnQgdG9vbGtpdHMgdG8gYXBwIHRvb2xraXRzXCIsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFwcCA9IG5ldyBBcHAoXCJUZXN0QXBwXCIsIG1vY2tTZXJ2ZXIpO1xuICAgICAgICAgICAgY29uc3QgdG9vbGtpdCA9IG5ldyBUb29sa2l0KHsgbmFtZTogXCJUZXN0VG9vbGtpdFwiIH0pO1xuICAgICAgICAgICAgY29uc3QgYWdlbnQgPSBuZXcgQWdlbnQoe1xuICAgICAgICAgICAgICAgIG5hbWU6IFwiVGVzdEFnZW50XCIsXG4gICAgICAgICAgICAgICAgdG9vbGtpdHM6IFt0b29sa2l0XSxcbiAgICAgICAgICAgICAgICBzeXN0ZW1Qcm9tcHQ6IFwiVGVzdCBwcm9tcHRcIixcbiAgICAgICAgICAgICAgICBtb2RlbDogZGVmYXVsdE1vZGVsRmFjdG9yeSxcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBhcHAuYWRkQWdlbnQoYWdlbnQpO1xuXG4gICAgICAgICAgICBleHBlY3QoYXBwLnRvb2xraXRzLnNpemUpLnRvQmUoMSk7XG4gICAgICAgICAgICBleHBlY3QoYXBwLnRvb2xraXRzLmhhcyh0b29sa2l0KSkudG9CZSh0cnVlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoXCJzaG91bGQgYWRkIG11bHRpcGxlIHRvb2xraXRzIGZyb20gYWdlbnRcIiwgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYXBwID0gbmV3IEFwcChcIlRlc3RBcHBcIiwgbW9ja1NlcnZlcik7XG4gICAgICAgICAgICBjb25zdCB0b29sa2l0MSA9IG5ldyBUb29sa2l0KHsgbmFtZTogXCJUb29sa2l0MVwiIH0pO1xuICAgICAgICAgICAgY29uc3QgdG9vbGtpdDIgPSBuZXcgVG9vbGtpdCh7IG5hbWU6IFwiVG9vbGtpdDJcIiB9KTtcbiAgICAgICAgICAgIGNvbnN0IGFnZW50ID0gbmV3IEFnZW50KHtcbiAgICAgICAgICAgICAgICBuYW1lOiBcIlRlc3RBZ2VudFwiLFxuICAgICAgICAgICAgICAgIHRvb2xraXRzOiBbdG9vbGtpdDEsIHRvb2xraXQyXSxcbiAgICAgICAgICAgICAgICBzeXN0ZW1Qcm9tcHQ6IFwiVGVzdCBwcm9tcHRcIixcbiAgICAgICAgICAgICAgICBtb2RlbDogZGVmYXVsdE1vZGVsRmFjdG9yeSxcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBhcHAuYWRkQWdlbnQoYWdlbnQpO1xuXG4gICAgICAgICAgICBleHBlY3QoYXBwLnRvb2xraXRzLnNpemUpLnRvQmUoMik7XG4gICAgICAgICAgICBleHBlY3QoYXBwLnRvb2xraXRzLmhhcyh0b29sa2l0MSkpLnRvQmUodHJ1ZSk7XG4gICAgICAgICAgICBleHBlY3QoYXBwLnRvb2xraXRzLmhhcyh0b29sa2l0MikpLnRvQmUodHJ1ZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KFwic2hvdWxkIG5vdCBkdXBsaWNhdGUgdG9vbGtpdHMgd2hlbiBhZGRpbmcgc2FtZSB0b29sa2l0IGZyb20gbXVsdGlwbGUgYWdlbnRzXCIsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFwcCA9IG5ldyBBcHAoXCJUZXN0QXBwXCIsIG1vY2tTZXJ2ZXIpO1xuICAgICAgICAgICAgY29uc3Qgc2hhcmVkVG9vbGtpdCA9IG5ldyBUb29sa2l0KHsgbmFtZTogXCJTaGFyZWRUb29sa2l0XCIgfSk7XG4gICAgICAgICAgICBjb25zdCBhZ2VudDEgPSBuZXcgQWdlbnQoe1xuICAgICAgICAgICAgICAgIG5hbWU6IFwiQWdlbnQxXCIsXG4gICAgICAgICAgICAgICAgdG9vbGtpdHM6IFtzaGFyZWRUb29sa2l0XSxcbiAgICAgICAgICAgICAgICBzeXN0ZW1Qcm9tcHQ6IFwiUHJvbXB0IDFcIixcbiAgICAgICAgICAgICAgICBtb2RlbDogZGVmYXVsdE1vZGVsRmFjdG9yeSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29uc3QgYWdlbnQyID0gbmV3IEFnZW50KHtcbiAgICAgICAgICAgICAgICBuYW1lOiBcIkFnZW50MlwiLFxuICAgICAgICAgICAgICAgIHRvb2xraXRzOiBbc2hhcmVkVG9vbGtpdF0sXG4gICAgICAgICAgICAgICAgc3lzdGVtUHJvbXB0OiBcIlByb21wdCAyXCIsXG4gICAgICAgICAgICAgICAgbW9kZWw6IGRlZmF1bHRNb2RlbEZhY3RvcnksXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgYXBwLmFkZEFnZW50KGFnZW50MSk7XG4gICAgICAgICAgICBhcHAuYWRkQWdlbnQoYWdlbnQyKTtcblxuICAgICAgICAgICAgZXhwZWN0KGFwcC50b29sa2l0cy5zaXplKS50b0JlKDEpO1xuICAgICAgICAgICAgZXhwZWN0KGFwcC50b29sa2l0cy5oYXMoc2hhcmVkVG9vbGtpdCkpLnRvQmUodHJ1ZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KFwic2hvdWxkIGFsbG93IGFkZGluZyB0aGUgc2FtZSBhZ2VudCB0d2ljZVwiLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhcHAgPSBuZXcgQXBwKFwiVGVzdEFwcFwiLCBtb2NrU2VydmVyKTtcbiAgICAgICAgICAgIGNvbnN0IGFnZW50ID0gbmV3IEFnZW50KHtcbiAgICAgICAgICAgICAgICBuYW1lOiBcIlRlc3RBZ2VudFwiLFxuICAgICAgICAgICAgICAgIHRvb2xraXRzOiBbXSxcbiAgICAgICAgICAgICAgICBzeXN0ZW1Qcm9tcHQ6IFwiVGVzdCBwcm9tcHRcIixcbiAgICAgICAgICAgICAgICBtb2RlbDogZGVmYXVsdE1vZGVsRmFjdG9yeSxcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBhcHAuYWRkQWdlbnQoYWdlbnQpO1xuICAgICAgICAgICAgYXBwLmFkZEFnZW50KGFnZW50KTtcblxuICAgICAgICAgICAgZXhwZWN0KGFwcC5hZ2VudHMpLnRvSGF2ZUxlbmd0aCgyKTtcbiAgICAgICAgICAgIGV4cGVjdChhcHAuYWdlbnRzWzBdKS50b0JlKGFnZW50KTtcbiAgICAgICAgICAgIGV4cGVjdChhcHAuYWdlbnRzWzFdKS50b0JlKGFnZW50KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoXCJzaG91bGQgaGFuZGxlIGFnZW50IHdpdGggbm8gdG9vbGtpdHNcIiwgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYXBwID0gbmV3IEFwcChcIlRlc3RBcHBcIiwgbW9ja1NlcnZlcik7XG4gICAgICAgICAgICBjb25zdCBhZ2VudCA9IG5ldyBBZ2VudCh7XG4gICAgICAgICAgICAgICAgbmFtZTogXCJOb1Rvb2xraXRBZ2VudFwiLFxuICAgICAgICAgICAgICAgIHRvb2xraXRzOiBbXSxcbiAgICAgICAgICAgICAgICBzeXN0ZW1Qcm9tcHQ6IFwiTm8gdG9vbGtpdHNcIixcbiAgICAgICAgICAgICAgICBtb2RlbDogZGVmYXVsdE1vZGVsRmFjdG9yeSxcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBhcHAuYWRkQWdlbnQoYWdlbnQpO1xuXG4gICAgICAgICAgICBleHBlY3QoYXBwLmFnZW50cykudG9IYXZlTGVuZ3RoKDEpO1xuICAgICAgICAgICAgZXhwZWN0KGFwcC50b29sa2l0cy5zaXplKS50b0JlKDApO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKFwiYWRkVG9vbGtpdCgpXCIsICgpID0+IHtcbiAgICAgICAgaXQoXCJzaG91bGQgYWRkIGEgdG9vbGtpdCB0byB0aGUgYXBwXCIsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFwcCA9IG5ldyBBcHAoXCJUZXN0QXBwXCIsIG1vY2tTZXJ2ZXIpO1xuICAgICAgICAgICAgY29uc3QgdG9vbGtpdCA9IG5ldyBUb29sa2l0KHsgbmFtZTogXCJUZXN0VG9vbGtpdFwiIH0pO1xuXG4gICAgICAgICAgICBhcHAuYWRkVG9vbGtpdCh0b29sa2l0KTtcblxuICAgICAgICAgICAgZXhwZWN0KGFwcC50b29sa2l0cy5zaXplKS50b0JlKDEpO1xuICAgICAgICAgICAgZXhwZWN0KGFwcC50b29sa2l0cy5oYXModG9vbGtpdCkpLnRvQmUodHJ1ZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KFwic2hvdWxkIGFkZCBtdWx0aXBsZSB0b29sa2l0c1wiLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhcHAgPSBuZXcgQXBwKFwiVGVzdEFwcFwiLCBtb2NrU2VydmVyKTtcbiAgICAgICAgICAgIGNvbnN0IHRvb2xraXQxID0gbmV3IFRvb2xraXQoeyBuYW1lOiBcIlRvb2xraXQxXCIgfSk7XG4gICAgICAgICAgICBjb25zdCB0b29sa2l0MiA9IG5ldyBUb29sa2l0KHsgbmFtZTogXCJUb29sa2l0MlwiIH0pO1xuXG4gICAgICAgICAgICBhcHAuYWRkVG9vbGtpdCh0b29sa2l0MSk7XG4gICAgICAgICAgICBhcHAuYWRkVG9vbGtpdCh0b29sa2l0Mik7XG5cbiAgICAgICAgICAgIGV4cGVjdChhcHAudG9vbGtpdHMuc2l6ZSkudG9CZSgyKTtcbiAgICAgICAgICAgIGV4cGVjdChhcHAudG9vbGtpdHMuaGFzKHRvb2xraXQxKSkudG9CZSh0cnVlKTtcbiAgICAgICAgICAgIGV4cGVjdChhcHAudG9vbGtpdHMuaGFzKHRvb2xraXQyKSkudG9CZSh0cnVlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoXCJzaG91bGQgbm90IGR1cGxpY2F0ZSB0b29sa2l0IHdoZW4gYWRkaW5nIHNhbWUgdG9vbGtpdCB0d2ljZVwiLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhcHAgPSBuZXcgQXBwKFwiVGVzdEFwcFwiLCBtb2NrU2VydmVyKTtcbiAgICAgICAgICAgIGNvbnN0IHRvb2xraXQgPSBuZXcgVG9vbGtpdCh7IG5hbWU6IFwiVGVzdFRvb2xraXRcIiB9KTtcblxuICAgICAgICAgICAgYXBwLmFkZFRvb2xraXQodG9vbGtpdCk7XG4gICAgICAgICAgICBhcHAuYWRkVG9vbGtpdCh0b29sa2l0KTtcblxuICAgICAgICAgICAgZXhwZWN0KGFwcC50b29sa2l0cy5zaXplKS50b0JlKDEpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdChcInNob3VsZCBhZGQgdG9vbGtpdCB3aXRoIHRvb2xzXCIsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFwcCA9IG5ldyBBcHAoXCJUZXN0QXBwXCIsIG1vY2tTZXJ2ZXIpO1xuICAgICAgICAgICAgY29uc3QgdG9vbCA9IG5ldyBNb2NrVG9vbChcInRlc3RUb29sXCIsIFwiQSB0ZXN0IHRvb2xcIik7XG4gICAgICAgICAgICBjb25zdCB0b29sa2l0ID0gbmV3IFRvb2xraXQoe1xuICAgICAgICAgICAgICAgIG5hbWU6IFwiVGVzdFRvb2xraXRcIixcbiAgICAgICAgICAgICAgICB0b29sczogW3Rvb2xdLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGFwcC5hZGRUb29sa2l0KHRvb2xraXQpO1xuXG4gICAgICAgICAgICBleHBlY3QoYXBwLnRvb2xraXRzLnNpemUpLnRvQmUoMSk7XG4gICAgICAgICAgICBjb25zdCBhZGRlZFRvb2xraXQgPSBBcnJheS5mcm9tKGFwcC50b29sa2l0cylbMF07XG4gICAgICAgICAgICBleHBlY3QoYWRkZWRUb29sa2l0LnRvb2xzKS50b0hhdmVMZW5ndGgoMSk7XG4gICAgICAgICAgICBleHBlY3QoYWRkZWRUb29sa2l0LnRvb2xzWzBdLm5hbWUpLnRvQmUoXCJ0ZXN0VG9vbFwiKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZShcInNlcnZlKClcIiwgKCkgPT4ge1xuICAgICAgICBpdChcInNob3VsZCBjYWxsIHNlcnZlci5zdGFydCgpXCIsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFwcCA9IG5ldyBBcHAoXCJUZXN0QXBwXCIsIG1vY2tTZXJ2ZXIpO1xuXG4gICAgICAgICAgICBhcHAuc2VydmUoKTtcblxuICAgICAgICAgICAgZXhwZWN0KG1vY2tTZXJ2ZXIuc3RhcnRDYWxscykudG9CZSgxKTtcbiAgICAgICAgICAgIGV4cGVjdChtb2NrU2VydmVyLnN0YXJ0ZWQpLnRvQmUodHJ1ZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KFwic2hvdWxkIGJlIGNhbGxhYmxlIG11bHRpcGxlIHRpbWVzXCIsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFwcCA9IG5ldyBBcHAoXCJUZXN0QXBwXCIsIG1vY2tTZXJ2ZXIpO1xuXG4gICAgICAgICAgICBhcHAuc2VydmUoKTtcbiAgICAgICAgICAgIGFwcC5zZXJ2ZSgpO1xuICAgICAgICAgICAgYXBwLnNlcnZlKCk7XG5cbiAgICAgICAgICAgIGV4cGVjdChtb2NrU2VydmVyLnN0YXJ0Q2FsbHMpLnRvQmUoMyk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoXCJpbnRlZ3JhdGlvbiBzY2VuYXJpb3NcIiwgKCkgPT4ge1xuICAgICAgICBpdChcInNob3VsZCB3b3JrIHdpdGggY29tcGxldGUgYXBwIHNldHVwXCIsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFwcCA9IG5ldyBBcHAoXCJDb21wbGV0ZUFwcFwiLCBtb2NrU2VydmVyKTtcblxuICAgICAgICAgICAgLy8gQ3JlYXRlIHRvb2xzXG4gICAgICAgICAgICBjb25zdCBzZWFyY2hUb29sID0gbmV3IE1vY2tUb29sKFwic2VhcmNoXCIsIFwiU2VhcmNoIGZvciBpdGVtc1wiKTtcbiAgICAgICAgICAgIGNvbnN0IGNyZWF0ZVRvb2wgPSBuZXcgTW9ja1Rvb2woXCJjcmVhdGVcIiwgXCJDcmVhdGUgbmV3IGl0ZW1cIik7XG5cbiAgICAgICAgICAgIC8vIENyZWF0ZSB0b29sa2l0c1xuICAgICAgICAgICAgY29uc3Qgc2VhcmNoVG9vbGtpdCA9IG5ldyBUb29sa2l0KHtcbiAgICAgICAgICAgICAgICBuYW1lOiBcIlNlYXJjaFRvb2xraXRcIixcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJUb29scyBmb3Igc2VhcmNoaW5nXCIsXG4gICAgICAgICAgICAgICAgdG9vbHM6IFtzZWFyY2hUb29sXSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29uc3QgY3J1ZFRvb2xraXQgPSBuZXcgVG9vbGtpdCh7XG4gICAgICAgICAgICAgICAgbmFtZTogXCJDUlVEVG9vbGtpdFwiLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkNSVUQgb3BlcmF0aW9uc1wiLFxuICAgICAgICAgICAgICAgIHRvb2xzOiBbY3JlYXRlVG9vbF0sXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gQ3JlYXRlIGFnZW50c1xuICAgICAgICAgICAgY29uc3Qgc2VhcmNoQWdlbnQgPSBuZXcgQWdlbnQoe1xuICAgICAgICAgICAgICAgIG5hbWU6IFwiU2VhcmNoQWdlbnRcIixcbiAgICAgICAgICAgICAgICB0b29sa2l0czogW3NlYXJjaFRvb2xraXRdLFxuICAgICAgICAgICAgICAgIHN5c3RlbVByb21wdDogXCJZb3UgYXJlIGEgc2VhcmNoIGFnZW50XCIsXG4gICAgICAgICAgICAgICAgbW9kZWw6IGRlZmF1bHRNb2RlbEZhY3RvcnksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnN0IGNydWRBZ2VudCA9IG5ldyBBZ2VudCh7XG4gICAgICAgICAgICAgICAgbmFtZTogXCJDUlVEQWdlbnRcIixcbiAgICAgICAgICAgICAgICB0b29sa2l0czogW2NydWRUb29sa2l0XSxcbiAgICAgICAgICAgICAgICBzeXN0ZW1Qcm9tcHQ6IFwiWW91IGFyZSBhIENSVUQgYWdlbnRcIixcbiAgICAgICAgICAgICAgICBtb2RlbDogZGVmYXVsdE1vZGVsRmFjdG9yeSxcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBBZGQgYWdlbnRzIHRvIGFwcFxuICAgICAgICAgICAgYXBwLmFkZEFnZW50KHNlYXJjaEFnZW50KTtcbiAgICAgICAgICAgIGFwcC5hZGRBZ2VudChjcnVkQWdlbnQpO1xuXG4gICAgICAgICAgICAvLyBBZGQgYWRkaXRpb25hbCB0b29sa2l0IGRpcmVjdGx5XG4gICAgICAgICAgICBjb25zdCB1dGlsVG9vbGtpdCA9IG5ldyBUb29sa2l0KHsgbmFtZTogXCJVdGlsVG9vbGtpdFwiIH0pO1xuICAgICAgICAgICAgYXBwLmFkZFRvb2xraXQodXRpbFRvb2xraXQpO1xuXG4gICAgICAgICAgICAvLyBWZXJpZnkgc3RhdGVcbiAgICAgICAgICAgIGV4cGVjdChhcHAubmFtZSkudG9CZShcIkNvbXBsZXRlQXBwXCIpO1xuICAgICAgICAgICAgZXhwZWN0KGFwcC5hZ2VudHMpLnRvSGF2ZUxlbmd0aCgyKTtcbiAgICAgICAgICAgIGV4cGVjdChhcHAudG9vbGtpdHMuc2l6ZSkudG9CZSgzKTtcbiAgICAgICAgICAgIGV4cGVjdChtb2NrU2VydmVyLmFjY2VwdGVkQXBwKS50b0JlKGFwcCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KFwic2hvdWxkIG1haW50YWluIHJlZmVyZW5jZXMgY29ycmVjdGx5XCIsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFwcCA9IG5ldyBBcHAoXCJSZWZBcHBcIiwgbW9ja1NlcnZlcik7XG4gICAgICAgICAgICBjb25zdCB0b29sa2l0ID0gbmV3IFRvb2xraXQoeyBuYW1lOiBcIlNoYXJlZFRvb2xraXRcIiB9KTtcbiAgICAgICAgICAgIGNvbnN0IGFnZW50ID0gbmV3IEFnZW50KHtcbiAgICAgICAgICAgICAgICBuYW1lOiBcIlJlZkFnZW50XCIsXG4gICAgICAgICAgICAgICAgdG9vbGtpdHM6IFt0b29sa2l0XSxcbiAgICAgICAgICAgICAgICBzeXN0ZW1Qcm9tcHQ6IFwiVGVzdFwiLFxuICAgICAgICAgICAgICAgIG1vZGVsOiBkZWZhdWx0TW9kZWxGYWN0b3J5LFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGFwcC5hZGRBZ2VudChhZ2VudCk7XG4gICAgICAgICAgICBhcHAuYWRkVG9vbGtpdCh0b29sa2l0KTtcblxuICAgICAgICAgICAgLy8gQWdlbnQgdG9vbGtpdCBhbmQgYXBwIHRvb2xraXQgc2hvdWxkIGJlIHNhbWUgcmVmZXJlbmNlXG4gICAgICAgICAgICBleHBlY3QoYXBwLmFnZW50c1swXS50b29sa2l0c1swXSkudG9CZSh0b29sa2l0KTtcbiAgICAgICAgICAgIGV4cGVjdChBcnJheS5mcm9tKGFwcC50b29sa2l0cylbMF0pLnRvQmUodG9vbGtpdCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KFwic2hvdWxkIGFsbG93IGl0ZXJhdGlvbiBvdmVyIHRvb2xraXRzXCIsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFwcCA9IG5ldyBBcHAoXCJJdGVyQXBwXCIsIG1vY2tTZXJ2ZXIpO1xuICAgICAgICAgICAgY29uc3QgdG9vbGtpdDEgPSBuZXcgVG9vbGtpdCh7IG5hbWU6IFwiVG9vbGtpdDFcIiB9KTtcbiAgICAgICAgICAgIGNvbnN0IHRvb2xraXQyID0gbmV3IFRvb2xraXQoeyBuYW1lOiBcIlRvb2xraXQyXCIgfSk7XG5cbiAgICAgICAgICAgIGFwcC5hZGRUb29sa2l0KHRvb2xraXQxKTtcbiAgICAgICAgICAgIGFwcC5hZGRUb29sa2l0KHRvb2xraXQyKTtcblxuICAgICAgICAgICAgY29uc3QgdG9vbGtpdE5hbWVzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgICAgICAgYXBwLnRvb2xraXRzLmZvckVhY2goKHRvb2xraXQpID0+IHtcbiAgICAgICAgICAgICAgICB0b29sa2l0TmFtZXMucHVzaCh0b29sa2l0Lm5hbWUpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGV4cGVjdCh0b29sa2l0TmFtZXMpLnRvQ29udGFpbihcIlRvb2xraXQxXCIpO1xuICAgICAgICAgICAgZXhwZWN0KHRvb2xraXROYW1lcykudG9Db250YWluKFwiVG9vbGtpdDJcIik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoXCJyZWFkb25seSBwcm9wZXJ0aWVzXCIsICgpID0+IHtcbiAgICAgICAgaXQoXCJzaG91bGQgaGF2ZSByZWFkb25seSBuYW1lIHByb3BlcnR5XCIsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFwcCA9IG5ldyBBcHAoXCJSZWFkb25seUFwcFwiLCBtb2NrU2VydmVyKTtcblxuICAgICAgICAgICAgZXhwZWN0KGFwcC5uYW1lKS50b0JlRGVmaW5lZCgpO1xuICAgICAgICAgICAgZXhwZWN0KHR5cGVvZiBhcHAubmFtZSkudG9CZShcInN0cmluZ1wiKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoXCJzaG91bGQgaGF2ZSBhZ2VudHMgYXJyYXkgdGhhdCBjYW4gYmUgcmVhZFwiLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhcHAgPSBuZXcgQXBwKFwiVGVzdEFwcFwiLCBtb2NrU2VydmVyKTtcblxuICAgICAgICAgICAgZXhwZWN0KGFwcC5hZ2VudHMpLnRvQmVEZWZpbmVkKCk7XG4gICAgICAgICAgICBleHBlY3QoQXJyYXkuaXNBcnJheShhcHAuYWdlbnRzKSkudG9CZSh0cnVlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoXCJzaG91bGQgaGF2ZSB0b29sa2l0cyBTZXQgdGhhdCBjYW4gYmUgcmVhZFwiLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhcHAgPSBuZXcgQXBwKFwiVGVzdEFwcFwiLCBtb2NrU2VydmVyKTtcblxuICAgICAgICAgICAgZXhwZWN0KGFwcC50b29sa2l0cykudG9CZURlZmluZWQoKTtcbiAgICAgICAgICAgIGV4cGVjdChhcHAudG9vbGtpdHMpLnRvQmVJbnN0YW5jZU9mKFNldCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KFwic2hvdWxkIGhhdmUgc2VydmVyIHRoYXQgY2FuIGJlIHJlYWRcIiwgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYXBwID0gbmV3IEFwcChcIlRlc3RBcHBcIiwgbW9ja1NlcnZlcik7XG5cbiAgICAgICAgICAgIGV4cGVjdChhcHAuc2VydmVyKS50b0JlRGVmaW5lZCgpO1xuICAgICAgICAgICAgZXhwZWN0KGFwcC5zZXJ2ZXIpLnRvQmUobW9ja1NlcnZlcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoXCJJU2VydmVyIGludGVyZmFjZSBjb21wbGlhbmNlXCIsICgpID0+IHtcbiAgICAgICAgaXQoXCJzaG91bGQgd29yayB3aXRoIGFueSBJU2VydmVyIGltcGxlbWVudGF0aW9uXCIsICgpID0+IHtcbiAgICAgICAgICAgIGNsYXNzIEN1c3RvbVNlcnZlciBpbXBsZW1lbnRzIElTZXJ2ZXIge1xuICAgICAgICAgICAgICAgIHB1YmxpYyBhY2NlcHRlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHB1YmxpYyBydW5uaW5nID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICBhY2NlcHQoX2FwcDogdW5rbm93bik6IHZvaWQge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmFjY2VwdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBhc3luYyBzdGFydCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ydW5uaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBhc3luYyBzdG9wKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnJ1bm5pbmcgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGN1c3RvbVNlcnZlciA9IG5ldyBDdXN0b21TZXJ2ZXIoKTtcbiAgICAgICAgICAgIGNvbnN0IGFwcCA9IG5ldyBBcHAoXCJDdXN0b21BcHBcIiwgY3VzdG9tU2VydmVyKTtcblxuICAgICAgICAgICAgZXhwZWN0KGN1c3RvbVNlcnZlci5hY2NlcHRlZCkudG9CZSh0cnVlKTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgYXBwLnNlcnZlKCk7XG4gICAgICAgICAgICBleHBlY3QoY3VzdG9tU2VydmVyLnJ1bm5pbmcpLnRvQmUodHJ1ZSk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xufSk7XG5cbmRlc2NyaWJlKFwiTW9kZWwgZmFjdG9yeSBtZXRob2RzXCIsICgpID0+IHtcbiAgICBkZXNjcmliZShcIk1vZGVsLm9wZW5BSSgpXCIsICgpID0+IHtcbiAgICAgICAgaXQoXCJzaG91bGQgY3JlYXRlIGFuIE9wZW5BSSBtb2RlbCBmYWN0b3J5IHdpdGggZW52IHNlY3JldFwiLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzZWNyZXQgPSBTZWNyZXQuZnJvbUVudihcIk9QRU5BSV9BUElfS0VZXCIpO1xuICAgICAgICAgICAgY29uc3QgZmFjdG9yeSA9IE1vZGVsLm9wZW5BSShcImdwdC00XCIsIHNlY3JldCk7XG5cbiAgICAgICAgICAgIGV4cGVjdChmYWN0b3J5KS50b0JlRGVmaW5lZCgpO1xuICAgICAgICAgICAgZXhwZWN0KHR5cGVvZiBmYWN0b3J5LmNyZWF0ZSkudG9CZShcImZ1bmN0aW9uXCIpO1xuICAgICAgICB9KTtcblxuICAgICAgICBpdChcInNob3VsZCBjcmVhdGUgbW9kZWwgZmFjdG9yaWVzIHdpdGggZGlmZmVyZW50IGlkZW50aWZpZXJzXCIsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHNlY3JldCA9IFNlY3JldC5mcm9tRW52KFwiT1BFTkFJX0FQSV9LRVlcIik7XG4gICAgICAgICAgICBjb25zdCBncHQ0ID0gTW9kZWwub3BlbkFJKFwiZ3B0LTRcIiwgc2VjcmV0KTtcbiAgICAgICAgICAgIGNvbnN0IGdwdDM1ID0gTW9kZWwub3BlbkFJKFwiZ3B0LTMuNS10dXJib1wiLCBzZWNyZXQpO1xuXG4gICAgICAgICAgICBleHBlY3QoZ3B0NCkudG9CZURlZmluZWQoKTtcbiAgICAgICAgICAgIGV4cGVjdChncHQzNSkudG9CZURlZmluZWQoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoXCJzaG91bGQgY3JlYXRlIG1vZGVsIGluc3RhbmNlcyBmcm9tIG1vY2sgZmFjdG9yeSBhbmQgaW52b2tlIHdpdGggc3RyZWFtZXJcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgbW9ja0ZhY3RvcnkgPSBuZXcgTW9ja01vZGVsRmFjdG9yeSgpO1xuXG4gICAgICAgICAgICBjb25zdCBtb2RlbCA9IGF3YWl0IG1vY2tGYWN0b3J5LmNyZWF0ZSh7XG4gICAgICAgICAgICAgICAgc3lzdGVtUHJvbXB0OiBcIllvdSBhcmUgYSBoZWxwZnVsIGFzc2lzdGFudC5cIixcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBjb25zdCBzdHJlYW1lciA9IG5ldyBNb2NrU3RyZWFtZXIoKTtcbiAgICAgICAgICAgIGF3YWl0IG1vZGVsLmludm9rZShbeyBjb250ZW50OiBcIkhlbGxvXCIsIHJvbGU6IFwidXNlclwiIH1dLCBzdHJlYW1lcik7XG5cbiAgICAgICAgICAgIGV4cGVjdChzdHJlYW1lci5yZWNlaXZlZFJlc3BvbnNlcy5sZW5ndGgpLnRvQmVHcmVhdGVyVGhhbigwKTtcbiAgICAgICAgICAgIGV4cGVjdChzdHJlYW1lci5yZWNlaXZlZE1vZGVsc1swXSkudG9CZShtb2RlbCk7XG4gICAgICAgICAgICBleHBlY3QobW9kZWwudGhyZWFkSWQpLnRvQmUoXCJtb2NrLXRocmVhZC1pZFwiKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG59KTtcbiJdfQ==
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|