@nlabs/metropolisjs 0.3.4 → 0.3.5
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/.github/copilot-instructions.md +55 -167
- package/AGENTS.md +52 -10
- package/README.md +52 -2
- package/docs/ACTIONS.md +84 -22
- package/docs/assets/metropolisjs-logo.png +0 -0
- package/examples/factory-pattern-usage.ts +15 -10
- package/lex.config.mjs +5 -8
- package/lib/actions/appActions/appActions.d.ts.map +1 -1
- package/lib/actions/appActions/appActions.js +77 -6
- package/lib/actions/crmActions/crmActions.d.ts +87 -0
- package/lib/actions/crmActions/crmActions.d.ts.map +1 -0
- package/lib/actions/crmActions/crmActions.js +338 -0
- package/lib/actions/index.d.ts +2 -0
- package/lib/actions/index.d.ts.map +1 -1
- package/lib/actions/index.js +3 -1
- package/lib/actions/restActions/restActions.d.ts +19 -0
- package/lib/actions/restActions/restActions.d.ts.map +1 -0
- package/lib/actions/restActions/restActions.js +40 -0
- package/lib/actions/userActions/userActions.d.ts +12 -0
- package/lib/actions/userActions/userActions.d.ts.map +1 -1
- package/lib/actions/userActions/userActions.js +20 -4
- package/lib/adapters/appAdapter/appAdapter.d.ts +2 -2
- package/lib/adapters/appAdapter/appAdapter.d.ts.map +1 -1
- package/lib/adapters/arangoAdapter/arangoAdapter.d.ts +2 -2
- package/lib/adapters/arangoAdapter/arangoAdapter.d.ts.map +1 -1
- package/lib/adapters/contentAdapter/contentAdapter.d.ts +2 -2
- package/lib/adapters/contentAdapter/contentAdapter.d.ts.map +1 -1
- package/lib/adapters/conversationAdapter/conversationAdapter.d.ts +2 -2
- package/lib/adapters/conversationAdapter/conversationAdapter.d.ts.map +1 -1
- package/lib/adapters/eventAdapter/eventAdapter.d.ts +2 -2
- package/lib/adapters/eventAdapter/eventAdapter.d.ts.map +1 -1
- package/lib/adapters/fileAdapter/fileAdapter.d.ts +2 -2
- package/lib/adapters/fileAdapter/fileAdapter.d.ts.map +1 -1
- package/lib/adapters/groupAdapter/groupAdapter.d.ts +2 -2
- package/lib/adapters/groupAdapter/groupAdapter.d.ts.map +1 -1
- package/lib/adapters/imageAdapter/imageAdapter.d.ts +2 -2
- package/lib/adapters/imageAdapter/imageAdapter.d.ts.map +1 -1
- package/lib/adapters/locationAdapter/locationAdapter.d.ts +2 -2
- package/lib/adapters/locationAdapter/locationAdapter.d.ts.map +1 -1
- package/lib/adapters/messageAdapter/messageAdapter.d.ts +2 -2
- package/lib/adapters/messageAdapter/messageAdapter.d.ts.map +1 -1
- package/lib/adapters/permissionAdapter/permissionAdapter.d.ts +2 -2
- package/lib/adapters/permissionAdapter/permissionAdapter.d.ts.map +1 -1
- package/lib/adapters/personaAdapter/personaAdapter.d.ts +2 -2
- package/lib/adapters/personaAdapter/personaAdapter.d.ts.map +1 -1
- package/lib/adapters/postAdapter/postAdapter.d.ts +2 -2
- package/lib/adapters/postAdapter/postAdapter.d.ts.map +1 -1
- package/lib/adapters/reactionAdapter/reactionAdapter.d.ts +2 -2
- package/lib/adapters/reactionAdapter/reactionAdapter.d.ts.map +1 -1
- package/lib/adapters/reaktorAdapter/reaktorAdapter.d.ts +2 -2
- package/lib/adapters/reaktorAdapter/reaktorAdapter.d.ts.map +1 -1
- package/lib/adapters/sessionAdapter/sessionAdapter.d.ts +2 -2
- package/lib/adapters/sessionAdapter/sessionAdapter.d.ts.map +1 -1
- package/lib/adapters/tagAdapter/tagAdapter.d.ts +2 -2
- package/lib/adapters/tagAdapter/tagAdapter.d.ts.map +1 -1
- package/lib/adapters/translationAdapter/translationAdapter.d.ts +2 -2
- package/lib/adapters/translationAdapter/translationAdapter.d.ts.map +1 -1
- package/lib/adapters/userAdapter/userAdapter.d.ts +2 -2
- package/lib/adapters/userAdapter/userAdapter.d.ts.map +1 -1
- package/lib/adapters/videoAdapter/videoAdapter.d.ts +2 -2
- package/lib/adapters/videoAdapter/videoAdapter.d.ts.map +1 -1
- package/lib/config/index.d.ts +1 -0
- package/lib/config/index.d.ts.map +1 -1
- package/lib/config/index.js +1 -1
- package/lib/constants/Collections.d.ts +16 -0
- package/lib/constants/Collections.d.ts.map +1 -1
- package/lib/constants/Collections.js +17 -1
- package/lib/index.d.ts +4 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +5 -3
- package/lib/stores/appStore.d.ts +10 -0
- package/lib/stores/appStore.d.ts.map +1 -1
- package/lib/stores/appStore.js +12 -2
- package/lib/tests/actionTestScenarios.d.ts +20 -0
- package/lib/tests/actionTestScenarios.d.ts.map +1 -0
- package/lib/tests/actionTestScenarios.js +851 -0
- package/lib/tests/testGraphQLServer.d.ts.map +1 -0
- package/lib/tests/testGraphQLServer.js +197 -0
- package/lib/tests/testGraphQLServerSimple.d.ts.map +1 -0
- package/lib/tests/testGraphQLServerSimple.js +52 -0
- package/lib/types/crm.types.d.ts +100 -0
- package/lib/types/crm.types.d.ts.map +1 -0
- package/lib/types/crm.types.js +6 -0
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +2 -1
- package/lib/utils/actionFactory.d.ts +6 -4
- package/lib/utils/actionFactory.d.ts.map +1 -1
- package/lib/utils/actionFactory.js +9 -1
- package/lib/utils/api.d.ts +14 -2
- package/lib/utils/api.d.ts.map +1 -1
- package/lib/utils/api.js +114 -32
- package/lib/utils/baseActionFactory.d.ts +2 -2
- package/lib/utils/dateUtils.d.ts +1 -1
- package/lib/utils/dateUtils.d.ts.map +1 -1
- package/lib/utils/index.d.ts +2 -2
- package/lib/utils/index.d.ts.map +1 -1
- package/lib/utils/index.js +3 -3
- package/lib/utils/location.d.ts +1 -1
- package/lib/utils/location.d.ts.map +1 -1
- package/lib/utils/requestCache.d.ts +1 -1
- package/lib/utils/requestCache.d.ts.map +1 -1
- package/lib/utils/useMetropolis.d.ts +2 -0
- package/lib/utils/useMetropolis.d.ts.map +1 -1
- package/lib/utils/useMetropolis.js +19 -1
- package/lib/utils/validatorFactory.d.ts +1 -1
- package/lib/utils/validatorFactory.d.ts.map +1 -1
- package/package.json +9 -9
- package/tsconfig.lint.json +2 -2
- package/tsconfig.test.json +3 -2
- package/jest.config.mjs +0 -28
- package/lib/__tests__/e2e/helpers/testGraphQLServer.d.ts.map +0 -1
- package/lib/__tests__/e2e/helpers/testGraphQLServer.js +0 -197
- package/lib/__tests__/e2e/helpers/testGraphQLServerSimple.d.ts.map +0 -1
- package/lib/__tests__/e2e/helpers/testGraphQLServerSimple.js +0 -52
- /package/lib/{__tests__/e2e/helpers → tests}/testGraphQLServer.d.ts +0 -0
- /package/lib/{__tests__/e2e/helpers → tests}/testGraphQLServerSimple.d.ts +0 -0
|
@@ -0,0 +1,851 @@
|
|
|
1
|
+
import { expect, vi } from 'vitest';
|
|
2
|
+
const makeEntity = (dataType, operation)=>{
|
|
3
|
+
const idName = dataType.slice(0, -1) + 'Id';
|
|
4
|
+
return {
|
|
5
|
+
[idName]: `${operation}-id`,
|
|
6
|
+
id: `${dataType}/${operation}-id`,
|
|
7
|
+
itemId: 'item-1',
|
|
8
|
+
itemType: 'post',
|
|
9
|
+
key: 'welcome',
|
|
10
|
+
locale: 'en',
|
|
11
|
+
name: `${operation} name`,
|
|
12
|
+
value: `${operation} value`
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
const listEntity = (dataType, operation)=>[
|
|
16
|
+
makeEntity(dataType, operation)
|
|
17
|
+
];
|
|
18
|
+
const responseFor = (dataType, operation)=>{
|
|
19
|
+
const entity = makeEntity(dataType, operation);
|
|
20
|
+
const list = listEntity(dataType, operation);
|
|
21
|
+
return {
|
|
22
|
+
[dataType]: {
|
|
23
|
+
[operation]: operation.toLowerCase().includes('list') || operation.toLowerCase().includes('tags') ? list : entity,
|
|
24
|
+
abortMultipartUpload: true,
|
|
25
|
+
add: entity,
|
|
26
|
+
addConnection: true,
|
|
27
|
+
addEvent: entity,
|
|
28
|
+
addItem: entity,
|
|
29
|
+
addPersonaReaction: entity,
|
|
30
|
+
addPlan: entity,
|
|
31
|
+
addPost: entity,
|
|
32
|
+
addReaction: entity,
|
|
33
|
+
addSubscription: true,
|
|
34
|
+
addTag: entity,
|
|
35
|
+
addTagToItem: entity,
|
|
36
|
+
addUser: entity,
|
|
37
|
+
autocompleteLocation: list,
|
|
38
|
+
check: true,
|
|
39
|
+
completeMultipartUpload: entity,
|
|
40
|
+
createMultipartUpload: {
|
|
41
|
+
bucket: 'media',
|
|
42
|
+
key: 'videos/key',
|
|
43
|
+
partSize: 5,
|
|
44
|
+
partUrls: [
|
|
45
|
+
{
|
|
46
|
+
partNumber: 1,
|
|
47
|
+
url: 'https://example.com/part'
|
|
48
|
+
}
|
|
49
|
+
],
|
|
50
|
+
uploadId: 'upload-1',
|
|
51
|
+
video: entity,
|
|
52
|
+
videoId: 'video-1'
|
|
53
|
+
},
|
|
54
|
+
deleteConnection: true,
|
|
55
|
+
deleteContent: entity,
|
|
56
|
+
deleteEvent: entity,
|
|
57
|
+
deletePost: entity,
|
|
58
|
+
deletePersona: entity,
|
|
59
|
+
deletePersonaReaction: entity,
|
|
60
|
+
deleteReaction: entity,
|
|
61
|
+
deleteSubscription: true,
|
|
62
|
+
deleteTag: entity,
|
|
63
|
+
deleteTagFromItem: entity,
|
|
64
|
+
getConnections: list,
|
|
65
|
+
getContent: entity,
|
|
66
|
+
getContentByKey: entity,
|
|
67
|
+
getContentsByCategory: list,
|
|
68
|
+
getContentsList: list,
|
|
69
|
+
getConversations: list,
|
|
70
|
+
getCurrentLocation: entity,
|
|
71
|
+
getDirectConversation: entity,
|
|
72
|
+
getEvent: entity,
|
|
73
|
+
getEventsByReactions: list,
|
|
74
|
+
getEventsByTags: list,
|
|
75
|
+
getGoogleLocation: entity,
|
|
76
|
+
getImageById: entity,
|
|
77
|
+
getImagesByItem: list,
|
|
78
|
+
getLocation: entity,
|
|
79
|
+
getMessages: list,
|
|
80
|
+
getMultipartUploadPartUrls: [
|
|
81
|
+
{
|
|
82
|
+
partNumber: 1,
|
|
83
|
+
url: 'https://example.com/part'
|
|
84
|
+
}
|
|
85
|
+
],
|
|
86
|
+
getPersonaById: entity,
|
|
87
|
+
getPersonaListByIds: list,
|
|
88
|
+
getPlanByItem: entity,
|
|
89
|
+
getPost: entity,
|
|
90
|
+
getPostsByLatest: list,
|
|
91
|
+
getPostsByLocation: list,
|
|
92
|
+
getPostsByReactions: list,
|
|
93
|
+
getPostsByTags: list,
|
|
94
|
+
getReactionCount: 7,
|
|
95
|
+
getSubscriptionByItem: true,
|
|
96
|
+
getSubscriptionListByUser: list,
|
|
97
|
+
getTags: list,
|
|
98
|
+
getTagsByItem: list,
|
|
99
|
+
getTranslation: entity,
|
|
100
|
+
getTranslations: list,
|
|
101
|
+
getUser: entity,
|
|
102
|
+
getUserByAttribute: entity,
|
|
103
|
+
getUserListByIds: list,
|
|
104
|
+
getVideoById: entity,
|
|
105
|
+
getVideoListByItem: list,
|
|
106
|
+
getVideoListByReactions: list,
|
|
107
|
+
hasPersonaReaction: true,
|
|
108
|
+
hasReaction: true,
|
|
109
|
+
imagesByPersonaReactions: list,
|
|
110
|
+
imagesByReactions: list,
|
|
111
|
+
list,
|
|
112
|
+
listByRelation: list,
|
|
113
|
+
listByTags: list,
|
|
114
|
+
remove: entity,
|
|
115
|
+
removeConnection: true,
|
|
116
|
+
removeItem: entity,
|
|
117
|
+
removePermission: entity,
|
|
118
|
+
removeUser: entity,
|
|
119
|
+
rsvpEvent: entity,
|
|
120
|
+
search: list,
|
|
121
|
+
confirmSignUp: true,
|
|
122
|
+
forgotPassword: true,
|
|
123
|
+
resetPassword: true,
|
|
124
|
+
sendVerificationEmail: true,
|
|
125
|
+
session: entity,
|
|
126
|
+
signIn: {
|
|
127
|
+
session: {
|
|
128
|
+
expires: 60,
|
|
129
|
+
token: 'token-1',
|
|
130
|
+
userId: 'user-1'
|
|
131
|
+
},
|
|
132
|
+
user: entity
|
|
133
|
+
},
|
|
134
|
+
signOut: true,
|
|
135
|
+
signUp: entity,
|
|
136
|
+
update: entity,
|
|
137
|
+
updateContent: entity,
|
|
138
|
+
updateEvent: entity,
|
|
139
|
+
updateItem: entity,
|
|
140
|
+
updateLocation: entity,
|
|
141
|
+
updatePermission: entity,
|
|
142
|
+
updatePost: entity,
|
|
143
|
+
updateTag: entity,
|
|
144
|
+
updateUser: entity
|
|
145
|
+
},
|
|
146
|
+
addLocation: entity,
|
|
147
|
+
autocompleteLocation: list,
|
|
148
|
+
deleteLocation: entity,
|
|
149
|
+
getCurrentLocation: entity,
|
|
150
|
+
getGoogleLocation: entity,
|
|
151
|
+
getLocation: entity,
|
|
152
|
+
locationsByItem: list,
|
|
153
|
+
imageCount: 3,
|
|
154
|
+
updateLocation: entity
|
|
155
|
+
};
|
|
156
|
+
};
|
|
157
|
+
const apiMocks = vi.hoisted(()=>({
|
|
158
|
+
appMutation: vi.fn(async (flux, operation, dataType, _queryVariables, _props, options = {})=>{
|
|
159
|
+
const response = responseFor(dataType, operation);
|
|
160
|
+
return options.onSuccess ? await options.onSuccess(response) : response[dataType]?.[operation] ?? response;
|
|
161
|
+
}),
|
|
162
|
+
appQuery: vi.fn(async (flux, operation, dataType, _queryVariables, _props, options = {})=>{
|
|
163
|
+
const response = responseFor(dataType, operation);
|
|
164
|
+
return options.onSuccess ? await options.onSuccess(response) : response[dataType]?.[operation] ?? response;
|
|
165
|
+
}),
|
|
166
|
+
publicMutation: vi.fn(async (flux, operation, dataType, _queryVariables, _props, options = {})=>{
|
|
167
|
+
const response = responseFor(dataType, operation);
|
|
168
|
+
if (options.onSuccess) {
|
|
169
|
+
await options.onSuccess(response);
|
|
170
|
+
}
|
|
171
|
+
return response;
|
|
172
|
+
}),
|
|
173
|
+
publicQuery: vi.fn(async (flux, operation, dataType, _queryVariables, _props, options = {})=>{
|
|
174
|
+
const response = responseFor(dataType, operation);
|
|
175
|
+
if (options.onSuccess) {
|
|
176
|
+
await options.onSuccess(response);
|
|
177
|
+
}
|
|
178
|
+
return response;
|
|
179
|
+
}),
|
|
180
|
+
refreshSession: vi.fn(async ()=>({
|
|
181
|
+
expires: 60,
|
|
182
|
+
token: 'token-1',
|
|
183
|
+
userId: 'user-1'
|
|
184
|
+
})),
|
|
185
|
+
uploadImage: vi.fn(async ()=>({
|
|
186
|
+
image: makeEntity('images', 'uploadImage')
|
|
187
|
+
}))
|
|
188
|
+
}));
|
|
189
|
+
vi.mock('../utils/api.js', ()=>apiMocks);
|
|
190
|
+
vi.mock('../utils/location.js', ()=>({
|
|
191
|
+
autoCompleteLocation: vi.fn(async ()=>[
|
|
192
|
+
{
|
|
193
|
+
address: '123 Main',
|
|
194
|
+
latitude: 1,
|
|
195
|
+
longitude: 2
|
|
196
|
+
}
|
|
197
|
+
])
|
|
198
|
+
}));
|
|
199
|
+
const createFlux = ()=>{
|
|
200
|
+
const state = new Map([
|
|
201
|
+
[
|
|
202
|
+
'app.config',
|
|
203
|
+
{
|
|
204
|
+
api: {
|
|
205
|
+
url: 'https://example.com/graphql'
|
|
206
|
+
},
|
|
207
|
+
websocket: {
|
|
208
|
+
url: 'wss://example.com/ws'
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
],
|
|
212
|
+
[
|
|
213
|
+
'translations',
|
|
214
|
+
{
|
|
215
|
+
pendingKeys: new Set([
|
|
216
|
+
'common:welcome:en'
|
|
217
|
+
]),
|
|
218
|
+
translations: {
|
|
219
|
+
'common:welcome:en': {
|
|
220
|
+
value: 'Welcome'
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
],
|
|
225
|
+
[
|
|
226
|
+
'user.session',
|
|
227
|
+
{
|
|
228
|
+
personaId: 'persona-1',
|
|
229
|
+
token: 'token-1',
|
|
230
|
+
userId: 'user-1'
|
|
231
|
+
}
|
|
232
|
+
],
|
|
233
|
+
[
|
|
234
|
+
'user.session.personaId',
|
|
235
|
+
'persona-1'
|
|
236
|
+
],
|
|
237
|
+
[
|
|
238
|
+
'user.session.token',
|
|
239
|
+
'token-1'
|
|
240
|
+
],
|
|
241
|
+
[
|
|
242
|
+
'user.session.userId',
|
|
243
|
+
'user-1'
|
|
244
|
+
]
|
|
245
|
+
]);
|
|
246
|
+
return {
|
|
247
|
+
dispatch: vi.fn(async (action)=>action),
|
|
248
|
+
getState: vi.fn((path, fallback)=>path ? state.get(path) ?? fallback : Object.fromEntries(state)),
|
|
249
|
+
setState: vi.fn(async (path, value)=>{
|
|
250
|
+
state.set(path, value);
|
|
251
|
+
return value;
|
|
252
|
+
})
|
|
253
|
+
};
|
|
254
|
+
};
|
|
255
|
+
const expectFluxAction = async (promise, flux, expectedAction)=>{
|
|
256
|
+
await expect(promise).resolves.toEqual(expectedAction);
|
|
257
|
+
expect(flux.dispatch).toHaveBeenLastCalledWith(expectedAction);
|
|
258
|
+
};
|
|
259
|
+
const expectFluxError = async (promise, flux, error, type)=>{
|
|
260
|
+
await expect(promise).rejects.toThrow(error.message);
|
|
261
|
+
expect(flux.dispatch).toHaveBeenLastCalledWith({
|
|
262
|
+
error,
|
|
263
|
+
type
|
|
264
|
+
});
|
|
265
|
+
};
|
|
266
|
+
export const resetActionScenarioMocks = ()=>{
|
|
267
|
+
vi.clearAllMocks();
|
|
268
|
+
};
|
|
269
|
+
export const runAppActionsScenario = async ()=>{
|
|
270
|
+
const { createAppActions } = await import('../actions/appActions/appActions.js');
|
|
271
|
+
const flux = createFlux();
|
|
272
|
+
const actions = createAppActions(flux);
|
|
273
|
+
await expectFluxAction(actions.add({
|
|
274
|
+
appId: 'app-1',
|
|
275
|
+
name: 'App'
|
|
276
|
+
}), flux, {
|
|
277
|
+
app: makeEntity('apps', 'add'),
|
|
278
|
+
type: 'APP_ADD_ITEM_SUCCESS'
|
|
279
|
+
});
|
|
280
|
+
await expectFluxAction(actions.itemById('app-1'), flux, {
|
|
281
|
+
app: makeEntity('apps', 'itemById'),
|
|
282
|
+
type: 'APP_GET_ITEM_SUCCESS'
|
|
283
|
+
});
|
|
284
|
+
await expectFluxAction(actions.list(), flux, {
|
|
285
|
+
list: listEntity('apps', 'list'),
|
|
286
|
+
type: 'APP_GET_LIST_SUCCESS'
|
|
287
|
+
});
|
|
288
|
+
await expectFluxAction(actions.update({
|
|
289
|
+
appId: 'app-1',
|
|
290
|
+
name: 'Updated'
|
|
291
|
+
}), flux, {
|
|
292
|
+
app: makeEntity('apps', 'update'),
|
|
293
|
+
type: 'APP_UPDATE_ITEM_SUCCESS'
|
|
294
|
+
});
|
|
295
|
+
await expectFluxAction(actions.delete('app-1'), flux, {
|
|
296
|
+
app: makeEntity('apps', 'remove'),
|
|
297
|
+
type: 'APP_REMOVE_ITEM_SUCCESS'
|
|
298
|
+
});
|
|
299
|
+
actions.updateAppAdapter((input)=>input);
|
|
300
|
+
actions.updateAppAdapterOptions({
|
|
301
|
+
strict: true
|
|
302
|
+
});
|
|
303
|
+
const error = new Error('app failed');
|
|
304
|
+
apiMocks.appMutation.mockRejectedValueOnce(error);
|
|
305
|
+
await expectFluxError(actions.add({
|
|
306
|
+
appId: 'app-1',
|
|
307
|
+
name: 'App'
|
|
308
|
+
}), flux, error, 'APP_ADD_ITEM_ERROR');
|
|
309
|
+
};
|
|
310
|
+
export const runConnectionActionsScenario = async ()=>{
|
|
311
|
+
const { createConnectionActions } = await import('../actions/connectionActions/connectionActions.js');
|
|
312
|
+
const actions = createConnectionActions(createFlux());
|
|
313
|
+
const consoleError = vi.spyOn(console, 'error').mockImplementation(()=>undefined);
|
|
314
|
+
try {
|
|
315
|
+
await expect(actions.addConnection('users', 'user-1', 'posts', 'post-1')).resolves.toBe(true);
|
|
316
|
+
await expect(actions.getConnections('users', 'user-1', 'posts', {
|
|
317
|
+
connectionType: 'member'
|
|
318
|
+
}, {
|
|
319
|
+
cacheTimeout: 5
|
|
320
|
+
})).resolves.toBeDefined();
|
|
321
|
+
await expect(actions.getConnections('users', 'user-1', undefined, {}, {
|
|
322
|
+
cacheTimeout: 5
|
|
323
|
+
})).resolves.toBeDefined();
|
|
324
|
+
await expect(actions.removeConnection('users', 'user-1', 'posts', 'post-1')).resolves.toBe(true);
|
|
325
|
+
apiMocks.appMutation.mockRejectedValueOnce(new Error('connection failed'));
|
|
326
|
+
await expect(actions.addConnection('users', 'user-1', 'posts', 'post-1')).rejects.toThrow('connection failed');
|
|
327
|
+
apiMocks.appQuery.mockRejectedValueOnce(new Error('connection query failed'));
|
|
328
|
+
await expect(actions.getConnections('users', 'user-1')).rejects.toThrow('connection query failed');
|
|
329
|
+
apiMocks.appMutation.mockRejectedValueOnce(new Error('connection remove failed'));
|
|
330
|
+
await expect(actions.removeConnection('users', 'user-1', 'posts', 'post-1')).rejects.toThrow('connection remove failed');
|
|
331
|
+
} finally{
|
|
332
|
+
consoleError.mockRestore();
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
export const runPostActionsScenario = async ()=>{
|
|
336
|
+
const { createPostActions } = await import('../actions/postActions/postActions.js');
|
|
337
|
+
const actions = createPostActions(createFlux());
|
|
338
|
+
const post = {
|
|
339
|
+
content: 'hello',
|
|
340
|
+
latitude: 1,
|
|
341
|
+
longitude: 2,
|
|
342
|
+
name: 'Post',
|
|
343
|
+
postId: 'post-1',
|
|
344
|
+
tags: [
|
|
345
|
+
{
|
|
346
|
+
name: 'tag'
|
|
347
|
+
}
|
|
348
|
+
]
|
|
349
|
+
};
|
|
350
|
+
await expect(actions.add(post)).resolves.toBeDefined();
|
|
351
|
+
await expect(actions.itemById('post-1')).resolves.toBeDefined();
|
|
352
|
+
await expect(actions.itemById('post-1', [], {
|
|
353
|
+
cacheTimeout: 5
|
|
354
|
+
})).resolves.toBeDefined();
|
|
355
|
+
await expect(actions.itemById('post-1', [], {
|
|
356
|
+
cacheTimeout: 5
|
|
357
|
+
})).resolves.toBeDefined();
|
|
358
|
+
await expect(actions.listByLatest()).resolves.toBeDefined();
|
|
359
|
+
await expect(actions.listByLatest(0, 10, [], {
|
|
360
|
+
cacheTimeout: 5
|
|
361
|
+
})).resolves.toBeDefined();
|
|
362
|
+
await expect(actions.listByLatest(0, 10, [], {
|
|
363
|
+
cacheTimeout: 5
|
|
364
|
+
})).resolves.toBeDefined();
|
|
365
|
+
await expect(actions.listByLocation(1, 2)).resolves.toBeDefined();
|
|
366
|
+
await expect(actions.listByLocation(1, 2, 0, 10, [], {
|
|
367
|
+
cacheTimeout: 5
|
|
368
|
+
})).resolves.toBeDefined();
|
|
369
|
+
await expect(actions.listByLocation(1, 2, 0, 10, [], {
|
|
370
|
+
cacheTimeout: 5
|
|
371
|
+
})).resolves.toBeDefined();
|
|
372
|
+
await expect(actions.listByReactions([
|
|
373
|
+
'like'
|
|
374
|
+
], 1, 2)).resolves.toBeDefined();
|
|
375
|
+
await expect(actions.listByReactions([
|
|
376
|
+
'like'
|
|
377
|
+
], 1, 2, 0, 10, [], {
|
|
378
|
+
cacheTimeout: 5
|
|
379
|
+
})).resolves.toBeDefined();
|
|
380
|
+
await expect(actions.listByReactions([
|
|
381
|
+
'like'
|
|
382
|
+
], 1, 2, 0, 10, [], {
|
|
383
|
+
cacheTimeout: 5
|
|
384
|
+
})).resolves.toBeDefined();
|
|
385
|
+
await expect(actions.listByTags([
|
|
386
|
+
'tag'
|
|
387
|
+
], 1, 2)).resolves.toBeDefined();
|
|
388
|
+
await expect(actions.listByTags([
|
|
389
|
+
'tag'
|
|
390
|
+
], 1, 2, 0, 10, [], {
|
|
391
|
+
cacheTimeout: 5
|
|
392
|
+
})).resolves.toBeDefined();
|
|
393
|
+
await expect(actions.listByTags([
|
|
394
|
+
'tag'
|
|
395
|
+
], 1, 2, 0, 10, [], {
|
|
396
|
+
cacheTimeout: 5
|
|
397
|
+
})).resolves.toBeDefined();
|
|
398
|
+
await expect(actions.update(post)).resolves.toBeDefined();
|
|
399
|
+
await expect(actions.delete('post-1')).resolves.toBeDefined();
|
|
400
|
+
actions.updatePostAdapter((input)=>input);
|
|
401
|
+
actions.updatePostAdapterOptions({
|
|
402
|
+
strict: true
|
|
403
|
+
});
|
|
404
|
+
apiMocks.appQuery.mockRejectedValueOnce(new Error('post failed'));
|
|
405
|
+
await expect(actions.itemById('post-1')).rejects.toThrow('post failed');
|
|
406
|
+
};
|
|
407
|
+
export const runReactionActionsScenario = async ()=>{
|
|
408
|
+
const { createReactionActions } = await import('../actions/reactionActions/reactionActions.js');
|
|
409
|
+
const actions = createReactionActions(createFlux());
|
|
410
|
+
const reaction = {
|
|
411
|
+
name: 'like',
|
|
412
|
+
type: 'posts',
|
|
413
|
+
value: '1'
|
|
414
|
+
};
|
|
415
|
+
await expect(actions.addReaction('post-1', 'post', reaction)).resolves.toBeDefined();
|
|
416
|
+
await expect(actions.addPersonaReaction('persona-1', 'post-1', 'post', reaction)).resolves.toBeDefined();
|
|
417
|
+
await expect(actions.deleteReaction('post-1', 'post', 'like')).resolves.toBeDefined();
|
|
418
|
+
await expect(actions.deletePersonaReaction('persona-1', 'post-1', 'post', 'like')).resolves.toBeDefined();
|
|
419
|
+
await expect(actions.getReactionCount('post-1', 'post', 'like')).resolves.toBeDefined();
|
|
420
|
+
await expect(actions.hasReaction('post-1', 'post', 'like', 'up')).resolves.toBeDefined();
|
|
421
|
+
await expect(actions.hasPersonaReaction('persona-1', 'post-1', 'post', 'like')).resolves.toBeDefined();
|
|
422
|
+
expect(actions.abbreviateCount(1200)).toBe('1.2k');
|
|
423
|
+
actions.updateReactionAdapter((input)=>input);
|
|
424
|
+
actions.updateReactionAdapterOptions({
|
|
425
|
+
strict: true
|
|
426
|
+
});
|
|
427
|
+
};
|
|
428
|
+
export const runVideoActionsScenario = async ()=>{
|
|
429
|
+
const { createVideoActions } = await import('../actions/videoActions/videoActions.js');
|
|
430
|
+
const actions = createVideoActions(createFlux());
|
|
431
|
+
const video = {
|
|
432
|
+
itemId: 'post-1',
|
|
433
|
+
itemType: 'post',
|
|
434
|
+
name: 'Video',
|
|
435
|
+
videoId: 'video-1'
|
|
436
|
+
};
|
|
437
|
+
await expect(actions.add(video)).resolves.toBeDefined();
|
|
438
|
+
await expect(actions.getVideoById('video-1')).resolves.toBeDefined();
|
|
439
|
+
await expect(actions.getVideoById('video-1', [], {
|
|
440
|
+
cacheTimeout: 5
|
|
441
|
+
})).resolves.toBeDefined();
|
|
442
|
+
await expect(actions.getVideoById('video-1', [], {
|
|
443
|
+
cacheTimeout: 5
|
|
444
|
+
})).resolves.toBeDefined();
|
|
445
|
+
await expect(actions.createMultipartUpload(video, 1)).resolves.toBeDefined();
|
|
446
|
+
await expect(actions.getMultipartUploadPartUrls('video-1', 'upload-1', [
|
|
447
|
+
1
|
|
448
|
+
])).resolves.toBeDefined();
|
|
449
|
+
await expect(actions.completeMultipartUpload('video-1', 'upload-1', [
|
|
450
|
+
{
|
|
451
|
+
etag: 'etag-1',
|
|
452
|
+
partNumber: 1
|
|
453
|
+
}
|
|
454
|
+
])).resolves.toBeDefined();
|
|
455
|
+
await expect(actions.abortMultipartUpload('video-1', 'upload-1')).resolves.toBeDefined();
|
|
456
|
+
await expect(actions.list()).resolves.toBeDefined();
|
|
457
|
+
await expect(actions.list(0, 10, [], {
|
|
458
|
+
cacheTimeout: 5
|
|
459
|
+
})).resolves.toBeDefined();
|
|
460
|
+
await expect(actions.list(0, 10, [], {
|
|
461
|
+
cacheTimeout: 5
|
|
462
|
+
})).resolves.toBeDefined();
|
|
463
|
+
await expect(actions.listByItem('post-1')).resolves.toBeDefined();
|
|
464
|
+
await expect(actions.listByItem('post-1', 0, 10, [], {
|
|
465
|
+
cacheTimeout: 5
|
|
466
|
+
})).resolves.toBeDefined();
|
|
467
|
+
await expect(actions.listByItem('post-1', 0, 10, [], {
|
|
468
|
+
cacheTimeout: 5
|
|
469
|
+
})).resolves.toBeDefined();
|
|
470
|
+
await expect(actions.listByReactions([
|
|
471
|
+
'like'
|
|
472
|
+
])).resolves.toBeDefined();
|
|
473
|
+
await expect(actions.listByReactions([
|
|
474
|
+
'like'
|
|
475
|
+
], 0, 10, [], {
|
|
476
|
+
cacheTimeout: 5
|
|
477
|
+
})).resolves.toBeDefined();
|
|
478
|
+
await expect(actions.listByReactions([
|
|
479
|
+
'like'
|
|
480
|
+
], 0, 10, [], {
|
|
481
|
+
cacheTimeout: 5
|
|
482
|
+
})).resolves.toBeDefined();
|
|
483
|
+
await expect(actions.update(video)).resolves.toBeDefined();
|
|
484
|
+
await expect(actions.delete('video-1')).resolves.toBeDefined();
|
|
485
|
+
actions.updateVideoAdapter((input)=>input);
|
|
486
|
+
actions.updateVideoAdapterOptions({
|
|
487
|
+
strict: true
|
|
488
|
+
});
|
|
489
|
+
apiMocks.appMutation.mockRejectedValueOnce(new Error('video failed'));
|
|
490
|
+
await expect(actions.update(video)).rejects.toThrow('video failed');
|
|
491
|
+
apiMocks.appMutation.mockRejectedValueOnce(new Error('multipart failed'));
|
|
492
|
+
await expect(actions.getMultipartUploadPartUrls('video-1', 'upload-1', [
|
|
493
|
+
1
|
|
494
|
+
])).rejects.toThrow('multipart failed');
|
|
495
|
+
};
|
|
496
|
+
export const runGroupActionsScenario = async ()=>{
|
|
497
|
+
const { createGroupActions } = await import('../actions/groupActions/groupActions.js');
|
|
498
|
+
const actions = createGroupActions(createFlux());
|
|
499
|
+
const group = {
|
|
500
|
+
description: 'Group',
|
|
501
|
+
groupId: 'group-1',
|
|
502
|
+
name: 'Group'
|
|
503
|
+
};
|
|
504
|
+
await expect(actions.add(group)).resolves.toBeDefined();
|
|
505
|
+
await expect(actions.itemById('group-1')).resolves.toBeDefined();
|
|
506
|
+
await expect(actions.listByLatest()).resolves.toBeDefined();
|
|
507
|
+
await expect(actions.update(group)).resolves.toBeDefined();
|
|
508
|
+
await expect(actions.delete('group-1')).resolves.toBeDefined();
|
|
509
|
+
actions.updateGroupAdapter((input)=>input);
|
|
510
|
+
actions.updateGroupAdapterOptions({
|
|
511
|
+
strict: true
|
|
512
|
+
});
|
|
513
|
+
apiMocks.appQuery.mockRejectedValueOnce(new Error('group failed'));
|
|
514
|
+
await expect(actions.itemById('group-1')).rejects.toThrow('group failed');
|
|
515
|
+
};
|
|
516
|
+
export const runConversationActionsScenario = async ()=>{
|
|
517
|
+
const { createConversationActions } = await import('../actions/conversationActions/conversationActions.js');
|
|
518
|
+
const actions = createConversationActions(createFlux());
|
|
519
|
+
const conversation = {
|
|
520
|
+
conversationId: 'conversation-1',
|
|
521
|
+
name: 'Conversation',
|
|
522
|
+
type: 'direct'
|
|
523
|
+
};
|
|
524
|
+
await expect(actions.add(conversation)).resolves.toBeDefined();
|
|
525
|
+
await expect(actions.itemById('conversation-1')).resolves.toBeDefined();
|
|
526
|
+
await expect(actions.list()).resolves.toBeDefined();
|
|
527
|
+
await expect(actions.update(conversation)).resolves.toBeDefined();
|
|
528
|
+
await expect(actions.delete('conversation-1')).resolves.toBeDefined();
|
|
529
|
+
actions.updateConversationAdapter((input)=>input);
|
|
530
|
+
actions.updateConversationAdapterOptions({
|
|
531
|
+
strict: true
|
|
532
|
+
});
|
|
533
|
+
apiMocks.appQuery.mockRejectedValueOnce(new Error('conversation failed'));
|
|
534
|
+
await expect(actions.list()).rejects.toThrow('conversation failed');
|
|
535
|
+
};
|
|
536
|
+
export const runEventActionsScenario = async ()=>{
|
|
537
|
+
const { createEventActions } = await import('../actions/eventActions/eventActions.js');
|
|
538
|
+
const actions = createEventActions(createFlux());
|
|
539
|
+
const event = {
|
|
540
|
+
description: 'Event',
|
|
541
|
+
eventId: 'event-1',
|
|
542
|
+
name: 'Event',
|
|
543
|
+
tags: [
|
|
544
|
+
{
|
|
545
|
+
name: 'music'
|
|
546
|
+
}
|
|
547
|
+
]
|
|
548
|
+
};
|
|
549
|
+
await expect(actions.addEvent(event)).resolves.toBeDefined();
|
|
550
|
+
await expect(actions.getEvent('event-1')).resolves.toBeDefined();
|
|
551
|
+
await expect(actions.getEventsByTags([
|
|
552
|
+
'music'
|
|
553
|
+
], 1, 2)).resolves.toBeDefined();
|
|
554
|
+
await expect(actions.getEventsByReactions([
|
|
555
|
+
'like'
|
|
556
|
+
], 1, 2)).resolves.toBeDefined();
|
|
557
|
+
await expect(actions.rsvpEvent({
|
|
558
|
+
eventId: 'event-1',
|
|
559
|
+
status: 'going'
|
|
560
|
+
})).resolves.toBeDefined();
|
|
561
|
+
await expect(actions.updateEvent(event)).resolves.toBeDefined();
|
|
562
|
+
await expect(actions.deleteEvent('event-1')).resolves.toBeDefined();
|
|
563
|
+
actions.updateEventAdapter((input)=>input);
|
|
564
|
+
actions.updateEventAdapterOptions({
|
|
565
|
+
strict: true
|
|
566
|
+
});
|
|
567
|
+
apiMocks.appMutation.mockRejectedValueOnce(new Error('event failed'));
|
|
568
|
+
await expect(actions.updateEvent(event)).rejects.toThrow('event failed');
|
|
569
|
+
};
|
|
570
|
+
export const runLocationActionsScenario = async ()=>{
|
|
571
|
+
const { createLocationActions } = await import('../actions/locationActions/locationActions.js');
|
|
572
|
+
const actions = createLocationActions(createFlux());
|
|
573
|
+
const location = {
|
|
574
|
+
address: '123 Main',
|
|
575
|
+
itemId: 'event-1',
|
|
576
|
+
latitude: 1,
|
|
577
|
+
locationId: 'location-1',
|
|
578
|
+
longitude: 2
|
|
579
|
+
};
|
|
580
|
+
await expect(actions.autocompleteLocation('123 Main', 1, 2)).resolves.toBeDefined();
|
|
581
|
+
await expect(actions.add(location)).resolves.toBeDefined();
|
|
582
|
+
await expect(actions.getGoogleLocation('123 Main')).resolves.toBeDefined();
|
|
583
|
+
await expect(actions.getLocation(location)).resolves.toBeDefined();
|
|
584
|
+
await expect(actions.listByItem('event-1')).resolves.toBeDefined();
|
|
585
|
+
await expect(actions.update(location)).resolves.toBeDefined();
|
|
586
|
+
await expect(actions.delete('location-1')).resolves.toBeDefined();
|
|
587
|
+
actions.updateLocationAdapter((input)=>input);
|
|
588
|
+
actions.updateLocationAdapterOptions({
|
|
589
|
+
strict: true
|
|
590
|
+
});
|
|
591
|
+
apiMocks.appMutation.mockRejectedValueOnce(new Error('location failed'));
|
|
592
|
+
await expect(actions.update(location)).rejects.toThrow('location failed');
|
|
593
|
+
};
|
|
594
|
+
export const runPermissionActionsScenario = async ()=>{
|
|
595
|
+
const { createPermissionActions } = await import('../actions/permissionActions/permissionActions.js');
|
|
596
|
+
const actions = createPermissionActions(createFlux());
|
|
597
|
+
const permission = {
|
|
598
|
+
level: 1,
|
|
599
|
+
name: 'Read',
|
|
600
|
+
permissionId: 'permission-1',
|
|
601
|
+
resource: 'posts',
|
|
602
|
+
userId: 'user-1'
|
|
603
|
+
};
|
|
604
|
+
await expect(actions.add(permission)).resolves.toBeDefined();
|
|
605
|
+
await expect(actions.check('user-1', 'posts', 'read')).resolves.toBeDefined();
|
|
606
|
+
await expect(actions.itemById('permission-1')).resolves.toBeDefined();
|
|
607
|
+
await expect(actions.list()).resolves.toBeDefined();
|
|
608
|
+
await expect(actions.listByUser('user-1')).resolves.toBeDefined();
|
|
609
|
+
await expect(actions.update(permission)).resolves.toBeDefined();
|
|
610
|
+
await expect(actions.remove('permission-1')).resolves.toBeDefined();
|
|
611
|
+
actions.updatePermissionAdapter((input)=>input);
|
|
612
|
+
actions.updatePermissionAdapterOptions({
|
|
613
|
+
strict: true
|
|
614
|
+
});
|
|
615
|
+
};
|
|
616
|
+
export const runSubscriptionActionsScenario = async ()=>{
|
|
617
|
+
const { createSubscriptionActions } = await import('../actions/subscriptionActions/subscriptionActions.js');
|
|
618
|
+
const actions = createSubscriptionActions(createFlux());
|
|
619
|
+
const plan = {
|
|
620
|
+
amount: 100,
|
|
621
|
+
interval: 'month',
|
|
622
|
+
intervalCount: 1,
|
|
623
|
+
itemId: 'persona-1',
|
|
624
|
+
itemType: 'personas',
|
|
625
|
+
name: 'Plan'
|
|
626
|
+
};
|
|
627
|
+
const subscription = {
|
|
628
|
+
itemId: 'persona-1',
|
|
629
|
+
itemType: 'personas',
|
|
630
|
+
planId: 'plan-1',
|
|
631
|
+
userId: 'user-1'
|
|
632
|
+
};
|
|
633
|
+
await expect(actions.addPlan(plan)).resolves.toBeDefined();
|
|
634
|
+
await expect(actions.getPlanByItem('persona-1')).resolves.toBeDefined();
|
|
635
|
+
await expect(actions.addSubscription(subscription)).resolves.toBeDefined();
|
|
636
|
+
await expect(actions.getSubscriptionByItem('persona-1')).resolves.toBeDefined();
|
|
637
|
+
await expect(actions.getSubscriptionListByUser('user-1')).resolves.toBeDefined();
|
|
638
|
+
await expect(actions.deleteSubscription('persona-1')).resolves.toBeDefined();
|
|
639
|
+
apiMocks.appMutation.mockRejectedValueOnce(new Error('subscription failed'));
|
|
640
|
+
await expect(actions.addPlan(plan)).rejects.toThrow('subscription failed');
|
|
641
|
+
};
|
|
642
|
+
export const runTagActionsScenario = async ()=>{
|
|
643
|
+
const { createTagActions } = await import('../actions/tagActions/tagActions.js');
|
|
644
|
+
const actions = createTagActions(createFlux());
|
|
645
|
+
const tag = {
|
|
646
|
+
itemId: 'post-1',
|
|
647
|
+
itemType: 'posts',
|
|
648
|
+
name: 'tag',
|
|
649
|
+
tagId: 'tag-1'
|
|
650
|
+
};
|
|
651
|
+
await expect(actions.addTag(tag)).resolves.toBeDefined();
|
|
652
|
+
await expect(actions.addTagToItem('tag-1', 'post-1', 'posts')).resolves.toBeDefined();
|
|
653
|
+
await expect(actions.getTags()).resolves.toBeDefined();
|
|
654
|
+
await expect(actions.getTagsByItem('post-1', 'posts')).resolves.toBeDefined();
|
|
655
|
+
await expect(actions.updateTag(tag)).resolves.toBeDefined();
|
|
656
|
+
await expect(actions.deleteTagFromItem('tag-1', 'post-1', 'posts')).resolves.toBeDefined();
|
|
657
|
+
await expect(actions.deleteTag('tag-1')).resolves.toBeDefined();
|
|
658
|
+
actions.updateTagAdapter((input)=>input);
|
|
659
|
+
actions.updateTagAdapterOptions({
|
|
660
|
+
strict: true
|
|
661
|
+
});
|
|
662
|
+
apiMocks.appQuery.mockRejectedValueOnce(new Error('tag list failed'));
|
|
663
|
+
await expect(actions.getTags('tag')).rejects.toThrow('tag list failed');
|
|
664
|
+
apiMocks.appMutation.mockRejectedValueOnce(new Error('tag update failed'));
|
|
665
|
+
await expect(actions.updateTag(tag)).rejects.toThrow('tag update failed');
|
|
666
|
+
};
|
|
667
|
+
export const runImageActionsScenario = async ()=>{
|
|
668
|
+
const { createImageActions } = await import('../actions/imageActions/imageActions.js');
|
|
669
|
+
const actions = createImageActions(createFlux());
|
|
670
|
+
const image = {
|
|
671
|
+
imageId: 'image-1',
|
|
672
|
+
itemId: 'post-1',
|
|
673
|
+
itemType: 'posts',
|
|
674
|
+
src: 'https://example.com/image.jpg'
|
|
675
|
+
};
|
|
676
|
+
await expect(actions.getImageById('image-1')).resolves.toBeDefined();
|
|
677
|
+
await expect(actions.countByItem('post-1')).resolves.toBeDefined();
|
|
678
|
+
await expect(actions.listByItem('post-1', 'posts')).resolves.toBeDefined();
|
|
679
|
+
await expect(actions.listByReactions([
|
|
680
|
+
'like'
|
|
681
|
+
])).resolves.toBeDefined();
|
|
682
|
+
await expect(actions.listByPersonaReactions('persona-1', [
|
|
683
|
+
'like'
|
|
684
|
+
])).resolves.toBeDefined();
|
|
685
|
+
await expect(actions.add(image)).resolves.toBeDefined();
|
|
686
|
+
await expect(actions.update({
|
|
687
|
+
...image,
|
|
688
|
+
description: 'Updated'
|
|
689
|
+
})).resolves.toBeDefined();
|
|
690
|
+
await expect(actions.delete('image-1')).resolves.toBeDefined();
|
|
691
|
+
apiMocks.appQuery.mockRejectedValueOnce(new Error('image failed'));
|
|
692
|
+
await expect(actions.getImageById('image-1')).rejects.toThrow('image failed');
|
|
693
|
+
};
|
|
694
|
+
export const runMessageActionsScenario = async ()=>{
|
|
695
|
+
const { createMessageActions } = await import('../actions/messageActions/messageActions.js');
|
|
696
|
+
const actions = createMessageActions(createFlux());
|
|
697
|
+
const message = {
|
|
698
|
+
content: 'Hello',
|
|
699
|
+
conversationId: 'conversation-1',
|
|
700
|
+
messageId: 'message-1'
|
|
701
|
+
};
|
|
702
|
+
await expect(actions.sendMessage(message)).resolves.toBeDefined();
|
|
703
|
+
await expect(actions.getDirectConversation('user-1')).resolves.toBeDefined();
|
|
704
|
+
await expect(actions.getMessages('conversation-1')).resolves.toBeDefined();
|
|
705
|
+
await expect(actions.getConversations()).resolves.toBeDefined();
|
|
706
|
+
actions.updateMessageAdapter((input)=>input);
|
|
707
|
+
actions.updateMessageAdapterOptions({
|
|
708
|
+
strict: true
|
|
709
|
+
});
|
|
710
|
+
};
|
|
711
|
+
export const runContentActionsScenario = async ()=>{
|
|
712
|
+
const { createContentActions } = await import('../actions/contentActions/contentActions.js');
|
|
713
|
+
const actions = createContentActions(createFlux());
|
|
714
|
+
const content = {
|
|
715
|
+
content: 'Body',
|
|
716
|
+
contentId: 'content-1',
|
|
717
|
+
key: 'welcome',
|
|
718
|
+
locale: 'en'
|
|
719
|
+
};
|
|
720
|
+
await expect(actions.list()).resolves.toBeDefined();
|
|
721
|
+
await expect(actions.list([
|
|
722
|
+
'description'
|
|
723
|
+
], {
|
|
724
|
+
cacheTimeout: 5
|
|
725
|
+
})).resolves.toBeDefined();
|
|
726
|
+
await expect(actions.list([
|
|
727
|
+
'description'
|
|
728
|
+
], {
|
|
729
|
+
cacheTimeout: 5
|
|
730
|
+
})).resolves.toBeDefined();
|
|
731
|
+
await expect(actions.listByCategory('docs')).resolves.toBeDefined();
|
|
732
|
+
await expect(actions.itemById('content-1')).resolves.toBeDefined();
|
|
733
|
+
await expect(actions.itemByKey('welcome', 'en')).resolves.toBeDefined();
|
|
734
|
+
await expect(actions.add(content)).resolves.toBeDefined();
|
|
735
|
+
await expect(actions.update(content)).resolves.toBeDefined();
|
|
736
|
+
await expect(actions.delete('content-1')).resolves.toBeDefined();
|
|
737
|
+
apiMocks.appMutation.mockRejectedValueOnce(new Error('content failed'));
|
|
738
|
+
await expect(actions.add(content)).rejects.toThrow('content failed');
|
|
739
|
+
};
|
|
740
|
+
export const runTranslationActionsScenario = async ()=>{
|
|
741
|
+
const { createTranslationActions } = await import('../actions/translationActions/translationActions.js');
|
|
742
|
+
const actions = createTranslationActions(createFlux());
|
|
743
|
+
await expect(actions.addTranslations([
|
|
744
|
+
{
|
|
745
|
+
key: 'welcome',
|
|
746
|
+
locale: 'en',
|
|
747
|
+
value: 'Welcome'
|
|
748
|
+
}
|
|
749
|
+
])).resolves.toBeDefined();
|
|
750
|
+
expect(actions.getTranslation('welcome', 'en', 'common')).toBe('Welcome');
|
|
751
|
+
await expect(actions.getTranslations([
|
|
752
|
+
'welcome'
|
|
753
|
+
], 'en', 'common')).resolves.toBeDefined();
|
|
754
|
+
expect(actions.hasTranslation('welcome', 'en', 'common')).toBe(true);
|
|
755
|
+
actions.queueTranslationKey('headline', 'en', 'common');
|
|
756
|
+
await expect(actions.processPendingTranslations('en', 'common')).resolves.toBeUndefined();
|
|
757
|
+
actions.updateTranslationAdapter((input)=>input);
|
|
758
|
+
actions.updateTranslationAdapterOptions({
|
|
759
|
+
strict: true
|
|
760
|
+
});
|
|
761
|
+
apiMocks.appQuery.mockRejectedValueOnce(new Error('translation failed'));
|
|
762
|
+
await expect(actions.getTranslations([
|
|
763
|
+
'welcome'
|
|
764
|
+
], 'en', 'common')).rejects.toThrow('translation failed');
|
|
765
|
+
};
|
|
766
|
+
export const runPersonaActionsScenario = async ()=>{
|
|
767
|
+
const { createPersonaActions } = await import('../actions/personaActions/personaActions.js');
|
|
768
|
+
const actions = createPersonaActions(createFlux());
|
|
769
|
+
const persona = {
|
|
770
|
+
name: 'Persona',
|
|
771
|
+
personaId: 'persona-1',
|
|
772
|
+
tags: [
|
|
773
|
+
{
|
|
774
|
+
name: 'creator'
|
|
775
|
+
}
|
|
776
|
+
]
|
|
777
|
+
};
|
|
778
|
+
await expect(actions.addPersona(persona)).resolves.toBeDefined();
|
|
779
|
+
await expect(actions.getPersonaById('persona-1')).resolves.toBeDefined();
|
|
780
|
+
await expect(actions.getPersonaListByIds([
|
|
781
|
+
'persona-1'
|
|
782
|
+
])).resolves.toBeDefined();
|
|
783
|
+
await expect(actions.listByTags([
|
|
784
|
+
'creator'
|
|
785
|
+
])).resolves.toBeDefined();
|
|
786
|
+
await expect(actions.listByRelation('follow')).resolves.toBeDefined();
|
|
787
|
+
await expect(actions.followPersona('persona-2')).resolves.toBeDefined();
|
|
788
|
+
await expect(actions.unfollowPersona('persona-2')).resolves.toBeDefined();
|
|
789
|
+
await expect(actions.blockPersona('persona-2')).resolves.toBeDefined();
|
|
790
|
+
await expect(actions.unblockPersona('persona-2')).resolves.toBeDefined();
|
|
791
|
+
await expect(actions.updatePersona(persona)).resolves.toBeDefined();
|
|
792
|
+
await expect(actions.deletePersona('persona-1')).resolves.toBeDefined();
|
|
793
|
+
actions.updatePersonaAdapter((input)=>input);
|
|
794
|
+
actions.updatePersonaAdapterOptions({
|
|
795
|
+
strict: true
|
|
796
|
+
});
|
|
797
|
+
apiMocks.appQuery.mockRejectedValueOnce(new Error('persona failed'));
|
|
798
|
+
await expect(actions.getPersonaById('persona-1')).rejects.toThrow('persona failed');
|
|
799
|
+
};
|
|
800
|
+
export const runUserActionsScenario = async ()=>{
|
|
801
|
+
const { createUserActions } = await import('../actions/userActions/userActions.js');
|
|
802
|
+
const actions = createUserActions(createFlux());
|
|
803
|
+
const user = {
|
|
804
|
+
email: 'user@example.com',
|
|
805
|
+
password: 'secret123',
|
|
806
|
+
phone: '15551234567',
|
|
807
|
+
userId: 'user-1',
|
|
808
|
+
username: 'user'
|
|
809
|
+
};
|
|
810
|
+
await expect(actions.addUser(user)).resolves.toBeDefined();
|
|
811
|
+
await expect(actions.signUp(user)).resolves.toBeDefined();
|
|
812
|
+
await expect(actions.updateUser(user)).resolves.toBeDefined();
|
|
813
|
+
await expect(actions.confirmCode('123456', 'email')).resolves.toBeDefined();
|
|
814
|
+
await expect(actions.remove('user-1')).resolves.toBeDefined();
|
|
815
|
+
await expect(actions.session()).rejects.toThrow('invalid_session');
|
|
816
|
+
await expect(actions.itemById('user-1')).resolves.toBeDefined();
|
|
817
|
+
await expect(actions.getUserByAttribute('email', 'user@example.com')).resolves.toBeDefined();
|
|
818
|
+
await expect(actions.saveBillingCard('tok_123')).resolves.toBeDefined();
|
|
819
|
+
await expect(actions.deleteBillingCard()).resolves.toBeDefined();
|
|
820
|
+
await expect(actions.updatePlan('plan-1')).resolves.toBeDefined();
|
|
821
|
+
await expect(actions.list()).resolves.toBeDefined();
|
|
822
|
+
await expect(actions.listByLatest()).resolves.toBeDefined();
|
|
823
|
+
await expect(actions.listByConnection('follow')).resolves.toBeDefined();
|
|
824
|
+
await expect(actions.listByReactions([
|
|
825
|
+
'like'
|
|
826
|
+
])).resolves.toBeDefined();
|
|
827
|
+
await expect(actions.listByTags([
|
|
828
|
+
'creator'
|
|
829
|
+
])).resolves.toBeDefined();
|
|
830
|
+
await expect(actions.search('user')).resolves.toBeDefined();
|
|
831
|
+
expect(actions.isLoggedIn()).toBe(false);
|
|
832
|
+
await expect(actions.currentAuthenticatedUser()).resolves.toBeDefined();
|
|
833
|
+
await expect(actions.currentUser()).resolves.toBeDefined();
|
|
834
|
+
await expect(actions.refreshSession('token-1', 15)).resolves.toBeDefined();
|
|
835
|
+
await expect(actions.signIn({
|
|
836
|
+
password: 'secret123',
|
|
837
|
+
username: 'user'
|
|
838
|
+
})).resolves.toBeDefined();
|
|
839
|
+
await expect(actions.signOut()).resolves.toBeDefined();
|
|
840
|
+
await expect(actions.confirmSignUp('123456', 'email')).resolves.toBeDefined();
|
|
841
|
+
await expect(actions.forgotPassword('user')).resolves.toBeDefined();
|
|
842
|
+
await expect(actions.sendVerificationEmail('user@example.com')).resolves.toBeDefined();
|
|
843
|
+
await expect(actions.resetPassword('user', '123456', 'secret123')).resolves.toBeDefined();
|
|
844
|
+
await expect(actions.updatePassword('secret123', 'secret456')).resolves.toBe(true);
|
|
845
|
+
actions.updateUserAdapter((input)=>input);
|
|
846
|
+
actions.updateUserAdapterOptions({
|
|
847
|
+
strict: true
|
|
848
|
+
});
|
|
849
|
+
};
|
|
850
|
+
|
|
851
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9uaXRyb2c3L0RldmVsb3BtZW50L21ldHJvcG9saXNqcy9zcmMvdGVzdHMvYWN0aW9uVGVzdFNjZW5hcmlvcy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2V4cGVjdCwgdml9IGZyb20gJ3ZpdGVzdCc7XG5cbmNvbnN0IG1ha2VFbnRpdHkgPSAoZGF0YVR5cGU6IHN0cmluZywgb3BlcmF0aW9uOiBzdHJpbmcpID0+IHtcbiAgY29uc3QgaWROYW1lID0gZGF0YVR5cGUuc2xpY2UoMCwgLTEpICsgJ0lkJztcblxuICByZXR1cm4ge1xuICAgIFtpZE5hbWVdOiBgJHtvcGVyYXRpb259LWlkYCxcbiAgICBpZDogYCR7ZGF0YVR5cGV9LyR7b3BlcmF0aW9ufS1pZGAsXG4gICAgaXRlbUlkOiAnaXRlbS0xJyxcbiAgICBpdGVtVHlwZTogJ3Bvc3QnLFxuICAgIGtleTogJ3dlbGNvbWUnLFxuICAgIGxvY2FsZTogJ2VuJyxcbiAgICBuYW1lOiBgJHtvcGVyYXRpb259IG5hbWVgLFxuICAgIHZhbHVlOiBgJHtvcGVyYXRpb259IHZhbHVlYFxuICB9O1xufTtcblxuY29uc3QgbGlzdEVudGl0eSA9IChkYXRhVHlwZTogc3RyaW5nLCBvcGVyYXRpb246IHN0cmluZykgPT4gW1xuICBtYWtlRW50aXR5KGRhdGFUeXBlLCBvcGVyYXRpb24pXG5dO1xuXG5jb25zdCByZXNwb25zZUZvciA9IChkYXRhVHlwZTogc3RyaW5nLCBvcGVyYXRpb246IHN0cmluZykgPT4ge1xuICBjb25zdCBlbnRpdHkgPSBtYWtlRW50aXR5KGRhdGFUeXBlLCBvcGVyYXRpb24pO1xuICBjb25zdCBsaXN0ID0gbGlzdEVudGl0eShkYXRhVHlwZSwgb3BlcmF0aW9uKTtcblxuICByZXR1cm4ge1xuICAgIFtkYXRhVHlwZV06IHtcbiAgICAgIFtvcGVyYXRpb25dOiBvcGVyYXRpb24udG9Mb3dlckNhc2UoKS5pbmNsdWRlcygnbGlzdCcpIHx8IG9wZXJhdGlvbi50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKCd0YWdzJykgPyBsaXN0IDogZW50aXR5LFxuICAgICAgYWJvcnRNdWx0aXBhcnRVcGxvYWQ6IHRydWUsXG4gICAgICBhZGQ6IGVudGl0eSxcbiAgICAgIGFkZENvbm5lY3Rpb246IHRydWUsXG4gICAgICBhZGRFdmVudDogZW50aXR5LFxuICAgICAgYWRkSXRlbTogZW50aXR5LFxuICAgICAgYWRkUGVyc29uYVJlYWN0aW9uOiBlbnRpdHksXG4gICAgICBhZGRQbGFuOiBlbnRpdHksXG4gICAgICBhZGRQb3N0OiBlbnRpdHksXG4gICAgICBhZGRSZWFjdGlvbjogZW50aXR5LFxuICAgICAgYWRkU3Vic2NyaXB0aW9uOiB0cnVlLFxuICAgICAgYWRkVGFnOiBlbnRpdHksXG4gICAgICBhZGRUYWdUb0l0ZW06IGVudGl0eSxcbiAgICAgIGFkZFVzZXI6IGVudGl0eSxcbiAgICAgIGF1dG9jb21wbGV0ZUxvY2F0aW9uOiBsaXN0LFxuICAgICAgY2hlY2s6IHRydWUsXG4gICAgICBjb21wbGV0ZU11bHRpcGFydFVwbG9hZDogZW50aXR5LFxuICAgICAgY3JlYXRlTXVsdGlwYXJ0VXBsb2FkOiB7XG4gICAgICAgIGJ1Y2tldDogJ21lZGlhJyxcbiAgICAgICAga2V5OiAndmlkZW9zL2tleScsXG4gICAgICAgIHBhcnRTaXplOiA1LFxuICAgICAgICBwYXJ0VXJsczogW3twYXJ0TnVtYmVyOiAxLCB1cmw6ICdodHRwczovL2V4YW1wbGUuY29tL3BhcnQnfV0sXG4gICAgICAgIHVwbG9hZElkOiAndXBsb2FkLTEnLFxuICAgICAgICB2aWRlbzogZW50aXR5LFxuICAgICAgICB2aWRlb0lkOiAndmlkZW8tMSdcbiAgICAgIH0sXG4gICAgICBkZWxldGVDb25uZWN0aW9uOiB0cnVlLFxuICAgICAgZGVsZXRlQ29udGVudDogZW50aXR5LFxuICAgICAgZGVsZXRlRXZlbnQ6IGVudGl0eSxcbiAgICAgIGRlbGV0ZVBvc3Q6IGVudGl0eSxcbiAgICAgIGRlbGV0ZVBlcnNvbmE6IGVudGl0eSxcbiAgICAgIGRlbGV0ZVBlcnNvbmFSZWFjdGlvbjogZW50aXR5LFxuICAgICAgZGVsZXRlUmVhY3Rpb246IGVudGl0eSxcbiAgICAgIGRlbGV0ZVN1YnNjcmlwdGlvbjogdHJ1ZSxcbiAgICAgIGRlbGV0ZVRhZzogZW50aXR5LFxuICAgICAgZGVsZXRlVGFnRnJvbUl0ZW06IGVudGl0eSxcbiAgICAgIGdldENvbm5lY3Rpb25zOiBsaXN0LFxuICAgICAgZ2V0Q29udGVudDogZW50aXR5LFxuICAgICAgZ2V0Q29udGVudEJ5S2V5OiBlbnRpdHksXG4gICAgICBnZXRDb250ZW50c0J5Q2F0ZWdvcnk6IGxpc3QsXG4gICAgICBnZXRDb250ZW50c0xpc3Q6IGxpc3QsXG4gICAgICBnZXRDb252ZXJzYXRpb25zOiBsaXN0LFxuICAgICAgZ2V0Q3VycmVudExvY2F0aW9uOiBlbnRpdHksXG4gICAgICBnZXREaXJlY3RDb252ZXJzYXRpb246IGVudGl0eSxcbiAgICAgIGdldEV2ZW50OiBlbnRpdHksXG4gICAgICBnZXRFdmVudHNCeVJlYWN0aW9uczogbGlzdCxcbiAgICAgIGdldEV2ZW50c0J5VGFnczogbGlzdCxcbiAgICAgIGdldEdvb2dsZUxvY2F0aW9uOiBlbnRpdHksXG4gICAgICBnZXRJbWFnZUJ5SWQ6IGVudGl0eSxcbiAgICAgIGdldEltYWdlc0J5SXRlbTogbGlzdCxcbiAgICAgIGdldExvY2F0aW9uOiBlbnRpdHksXG4gICAgICBnZXRNZXNzYWdlczogbGlzdCxcbiAgICAgIGdldE11bHRpcGFydFVwbG9hZFBhcnRVcmxzOiBbe3BhcnROdW1iZXI6IDEsIHVybDogJ2h0dHBzOi8vZXhhbXBsZS5jb20vcGFydCd9XSxcbiAgICAgIGdldFBlcnNvbmFCeUlkOiBlbnRpdHksXG4gICAgICBnZXRQZXJzb25hTGlzdEJ5SWRzOiBsaXN0LFxuICAgICAgZ2V0UGxhbkJ5SXRlbTogZW50aXR5LFxuICAgICAgZ2V0UG9zdDogZW50aXR5LFxuICAgICAgZ2V0UG9zdHNCeUxhdGVzdDogbGlzdCxcbiAgICAgIGdldFBvc3RzQnlMb2NhdGlvbjogbGlzdCxcbiAgICAgIGdldFBvc3RzQnlSZWFjdGlvbnM6IGxpc3QsXG4gICAgICBnZXRQb3N0c0J5VGFnczogbGlzdCxcbiAgICAgIGdldFJlYWN0aW9uQ291bnQ6IDcsXG4gICAgICBnZXRTdWJzY3JpcHRpb25CeUl0ZW06IHRydWUsXG4gICAgICBnZXRTdWJzY3JpcHRpb25MaXN0QnlVc2VyOiBsaXN0LFxuICAgICAgZ2V0VGFnczogbGlzdCxcbiAgICAgIGdldFRhZ3NCeUl0ZW06IGxpc3QsXG4gICAgICBnZXRUcmFuc2xhdGlvbjogZW50aXR5LFxuICAgICAgZ2V0VHJhbnNsYXRpb25zOiBsaXN0LFxuICAgICAgZ2V0VXNlcjogZW50aXR5LFxuICAgICAgZ2V0VXNlckJ5QXR0cmlidXRlOiBlbnRpdHksXG4gICAgICBnZXRVc2VyTGlzdEJ5SWRzOiBsaXN0LFxuICAgICAgZ2V0VmlkZW9CeUlkOiBlbnRpdHksXG4gICAgICBnZXRWaWRlb0xpc3RCeUl0ZW06IGxpc3QsXG4gICAgICBnZXRWaWRlb0xpc3RCeVJlYWN0aW9uczogbGlzdCxcbiAgICAgIGhhc1BlcnNvbmFSZWFjdGlvbjogdHJ1ZSxcbiAgICAgIGhhc1JlYWN0aW9uOiB0cnVlLFxuICAgICAgaW1hZ2VzQnlQZXJzb25hUmVhY3Rpb25zOiBsaXN0LFxuICAgICAgaW1hZ2VzQnlSZWFjdGlvbnM6IGxpc3QsXG4gICAgICBsaXN0LFxuICAgICAgbGlzdEJ5UmVsYXRpb246IGxpc3QsXG4gICAgICBsaXN0QnlUYWdzOiBsaXN0LFxuICAgICAgcmVtb3ZlOiBlbnRpdHksXG4gICAgICByZW1vdmVDb25uZWN0aW9uOiB0cnVlLFxuICAgICAgcmVtb3ZlSXRlbTogZW50aXR5LFxuICAgICAgcmVtb3ZlUGVybWlzc2lvbjogZW50aXR5LFxuICAgICAgcmVtb3ZlVXNlcjogZW50aXR5LFxuICAgICAgcnN2cEV2ZW50OiBlbnRpdHksXG4gICAgICBzZWFyY2g6IGxpc3QsXG4gICAgICBjb25maXJtU2lnblVwOiB0cnVlLFxuICAgICAgZm9yZ290UGFzc3dvcmQ6IHRydWUsXG4gICAgICByZXNldFBhc3N3b3JkOiB0cnVlLFxuICAgICAgc2VuZFZlcmlmaWNhdGlvbkVtYWlsOiB0cnVlLFxuICAgICAgc2Vzc2lvbjogZW50aXR5LFxuICAgICAgc2lnbkluOiB7XG4gICAgICAgIHNlc3Npb246IHtleHBpcmVzOiA2MCwgdG9rZW46ICd0b2tlbi0xJywgdXNlcklkOiAndXNlci0xJ30sXG4gICAgICAgIHVzZXI6IGVudGl0eVxuICAgICAgfSxcbiAgICAgIHNpZ25PdXQ6IHRydWUsXG4gICAgICBzaWduVXA6IGVudGl0eSxcbiAgICAgIHVwZGF0ZTogZW50aXR5LFxuICAgICAgdXBkYXRlQ29udGVudDogZW50aXR5LFxuICAgICAgdXBkYXRlRXZlbnQ6IGVudGl0eSxcbiAgICAgIHVwZGF0ZUl0ZW06IGVudGl0eSxcbiAgICAgIHVwZGF0ZUxvY2F0aW9uOiBlbnRpdHksXG4gICAgICB1cGRhdGVQZXJtaXNzaW9uOiBlbnRpdHksXG4gICAgICB1cGRhdGVQb3N0OiBlbnRpdHksXG4gICAgICB1cGRhdGVUYWc6IGVudGl0eSxcbiAgICAgIHVwZGF0ZVVzZXI6IGVudGl0eVxuICAgIH0sXG4gICAgYWRkTG9jYXRpb246IGVudGl0eSxcbiAgICBhdXRvY29tcGxldGVMb2NhdGlvbjogbGlzdCxcbiAgICBkZWxldGVMb2NhdGlvbjogZW50aXR5LFxuICAgIGdldEN1cnJlbnRMb2NhdGlvbjogZW50aXR5LFxuICAgIGdldEdvb2dsZUxvY2F0aW9uOiBlbnRpdHksXG4gICAgZ2V0TG9jYXRpb246IGVudGl0eSxcbiAgICBsb2NhdGlvbnNCeUl0ZW06IGxpc3QsXG4gICAgaW1hZ2VDb3VudDogMyxcbiAgICB1cGRhdGVMb2NhdGlvbjogZW50aXR5XG4gIH07XG59O1xuXG5jb25zdCBhcGlNb2NrcyA9IHZpLmhvaXN0ZWQoKCkgPT4gKHtcbiAgYXBwTXV0YXRpb246IHZpLmZuKGFzeW5jIChmbHV4LCBvcGVyYXRpb24sIGRhdGFUeXBlLCBfcXVlcnlWYXJpYWJsZXMsIF9wcm9wcywgb3B0aW9ucyA9IHt9KSA9PiB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSByZXNwb25zZUZvcihkYXRhVHlwZSwgb3BlcmF0aW9uKTtcbiAgICByZXR1cm4gb3B0aW9ucy5vblN1Y2Nlc3MgPyBhd2FpdCBvcHRpb25zLm9uU3VjY2VzcyhyZXNwb25zZSkgOiByZXNwb25zZVtkYXRhVHlwZV0/LltvcGVyYXRpb25dID8/IHJlc3BvbnNlO1xuICB9KSxcbiAgYXBwUXVlcnk6IHZpLmZuKGFzeW5jIChmbHV4LCBvcGVyYXRpb24sIGRhdGFUeXBlLCBfcXVlcnlWYXJpYWJsZXMsIF9wcm9wcywgb3B0aW9ucyA9IHt9KSA9PiB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSByZXNwb25zZUZvcihkYXRhVHlwZSwgb3BlcmF0aW9uKTtcbiAgICByZXR1cm4gb3B0aW9ucy5vblN1Y2Nlc3MgPyBhd2FpdCBvcHRpb25zLm9uU3VjY2VzcyhyZXNwb25zZSkgOiByZXNwb25zZVtkYXRhVHlwZV0/LltvcGVyYXRpb25dID8/IHJlc3BvbnNlO1xuICB9KSxcbiAgcHVibGljTXV0YXRpb246IHZpLmZuKGFzeW5jIChmbHV4LCBvcGVyYXRpb24sIGRhdGFUeXBlLCBfcXVlcnlWYXJpYWJsZXMsIF9wcm9wcywgb3B0aW9ucyA9IHt9KSA9PiB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSByZXNwb25zZUZvcihkYXRhVHlwZSwgb3BlcmF0aW9uKTtcbiAgICBpZihvcHRpb25zLm9uU3VjY2Vzcykge1xuICAgICAgYXdhaXQgb3B0aW9ucy5vblN1Y2Nlc3MocmVzcG9uc2UpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzcG9uc2U7XG4gIH0pLFxuICBwdWJsaWNRdWVyeTogdmkuZm4oYXN5bmMgKGZsdXgsIG9wZXJhdGlvbiwgZGF0YVR5cGUsIF9xdWVyeVZhcmlhYmxlcywgX3Byb3BzLCBvcHRpb25zID0ge30pID0+IHtcbiAgICBjb25zdCByZXNwb25zZSA9IHJlc3BvbnNlRm9yKGRhdGFUeXBlLCBvcGVyYXRpb24pO1xuICAgIGlmKG9wdGlvbnMub25TdWNjZXNzKSB7XG4gICAgICBhd2FpdCBvcHRpb25zLm9uU3VjY2VzcyhyZXNwb25zZSk7XG4gICAgfVxuICAgIHJldHVybiByZXNwb25zZTtcbiAgfSksXG4gIHJlZnJlc2hTZXNzaW9uOiB2aS5mbihhc3luYyAoKSA9PiAoe2V4cGlyZXM6IDYwLCB0b2tlbjogJ3Rva2VuLTEnLCB1c2VySWQ6ICd1c2VyLTEnfSkpLFxuICB1cGxvYWRJbWFnZTogdmkuZm4oYXN5bmMgKCkgPT4gKHtpbWFnZTogbWFrZUVudGl0eSgnaW1hZ2VzJywgJ3VwbG9hZEltYWdlJyl9KSlcbn0pKTtcblxudmkubW9jaygnLi4vdXRpbHMvYXBpLmpzJywgKCkgPT4gYXBpTW9ja3MpO1xuXG52aS5tb2NrKCcuLi91dGlscy9sb2NhdGlvbi5qcycsICgpID0+ICh7XG4gIGF1dG9Db21wbGV0ZUxvY2F0aW9uOiB2aS5mbihhc3luYyAoKSA9PiBbe2FkZHJlc3M6ICcxMjMgTWFpbicsIGxhdGl0dWRlOiAxLCBsb25naXR1ZGU6IDJ9XSlcbn0pKTtcblxuY29uc3QgY3JlYXRlRmx1eCA9ICgpID0+IHtcbiAgY29uc3Qgc3RhdGUgPSBuZXcgTWFwPHN0cmluZywgdW5rbm93bj4oW1xuICAgIFsnYXBwLmNvbmZpZycsIHthcGk6IHt1cmw6ICdodHRwczovL2V4YW1wbGUuY29tL2dyYXBocWwnfSwgd2Vic29ja2V0OiB7dXJsOiAnd3NzOi8vZXhhbXBsZS5jb20vd3MnfX1dLFxuICAgIFsndHJhbnNsYXRpb25zJywge1xuICAgICAgcGVuZGluZ0tleXM6IG5ldyBTZXQoWydjb21tb246d2VsY29tZTplbiddKSxcbiAgICAgIHRyYW5zbGF0aW9uczoge1xuICAgICAgICAnY29tbW9uOndlbGNvbWU6ZW4nOiB7dmFsdWU6ICdXZWxjb21lJ31cbiAgICAgIH1cbiAgICB9XSxcbiAgICBbJ3VzZXIuc2Vzc2lvbicsIHtwZXJzb25hSWQ6ICdwZXJzb25hLTEnLCB0b2tlbjogJ3Rva2VuLTEnLCB1c2VySWQ6ICd1c2VyLTEnfV0sXG4gICAgWyd1c2VyLnNlc3Npb24ucGVyc29uYUlkJywgJ3BlcnNvbmEtMSddLFxuICAgIFsndXNlci5zZXNzaW9uLnRva2VuJywgJ3Rva2VuLTEnXSxcbiAgICBbJ3VzZXIuc2Vzc2lvbi51c2VySWQnLCAndXNlci0xJ11cbiAgXSk7XG5cbiAgcmV0dXJuIHtcbiAgICBkaXNwYXRjaDogdmkuZm4oYXN5bmMgKGFjdGlvbikgPT4gYWN0aW9uKSxcbiAgICBnZXRTdGF0ZTogdmkuZm4oKHBhdGg/OiBzdHJpbmcsIGZhbGxiYWNrPzogdW5rbm93bikgPT4gcGF0aCA/IHN0YXRlLmdldChwYXRoKSA/PyBmYWxsYmFjayA6IE9iamVjdC5mcm9tRW50cmllcyhzdGF0ZSkpLFxuICAgIHNldFN0YXRlOiB2aS5mbihhc3luYyAocGF0aDogc3RyaW5nLCB2YWx1ZTogdW5rbm93bikgPT4ge1xuICAgICAgc3RhdGUuc2V0KHBhdGgsIHZhbHVlKTtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9KVxuICB9O1xufTtcblxuY29uc3QgZXhwZWN0Rmx1eEFjdGlvbiA9IGFzeW5jIChwcm9taXNlOiBQcm9taXNlPHVua25vd24+LCBmbHV4OiBSZXR1cm5UeXBlPHR5cGVvZiBjcmVhdGVGbHV4PiwgZXhwZWN0ZWRBY3Rpb246IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PiB7XG4gIGF3YWl0IGV4cGVjdChwcm9taXNlKS5yZXNvbHZlcy50b0VxdWFsKGV4cGVjdGVkQWN0aW9uKTtcbiAgZXhwZWN0KGZsdXguZGlzcGF0Y2gpLnRvSGF2ZUJlZW5MYXN0Q2FsbGVkV2l0aChleHBlY3RlZEFjdGlvbik7XG59O1xuXG5jb25zdCBleHBlY3RGbHV4RXJyb3IgPSBhc3luYyAocHJvbWlzZTogUHJvbWlzZTx1bmtub3duPiwgZmx1eDogUmV0dXJuVHlwZTx0eXBlb2YgY3JlYXRlRmx1eD4sIGVycm9yOiBFcnJvciwgdHlwZTogc3RyaW5nKSA9PiB7XG4gIGF3YWl0IGV4cGVjdChwcm9taXNlKS5yZWplY3RzLnRvVGhyb3coZXJyb3IubWVzc2FnZSk7XG4gIGV4cGVjdChmbHV4LmRpc3BhdGNoKS50b0hhdmVCZWVuTGFzdENhbGxlZFdpdGgoe2Vycm9yLCB0eXBlfSk7XG59O1xuXG5leHBvcnQgY29uc3QgcmVzZXRBY3Rpb25TY2VuYXJpb01vY2tzID0gKCkgPT4ge1xuICB2aS5jbGVhckFsbE1vY2tzKCk7XG59O1xuXG5leHBvcnQgY29uc3QgcnVuQXBwQWN0aW9uc1NjZW5hcmlvID0gYXN5bmMgKCkgPT4ge1xuICBjb25zdCB7Y3JlYXRlQXBwQWN0aW9uc30gPSBhd2FpdCBpbXBvcnQoJy4uL2FjdGlvbnMvYXBwQWN0aW9ucy9hcHBBY3Rpb25zLmpzJyk7XG4gIGNvbnN0IGZsdXggPSBjcmVhdGVGbHV4KCk7XG4gIGNvbnN0IGFjdGlvbnMgPSBjcmVhdGVBcHBBY3Rpb25zKGZsdXggYXMgYW55KTtcblxuICBhd2FpdCBleHBlY3RGbHV4QWN0aW9uKGFjdGlvbnMuYWRkKHthcHBJZDogJ2FwcC0xJywgbmFtZTogJ0FwcCd9KSwgZmx1eCwge1xuICAgIGFwcDogbWFrZUVudGl0eSgnYXBwcycsICdhZGQnKSxcbiAgICB0eXBlOiAnQVBQX0FERF9JVEVNX1NVQ0NFU1MnXG4gIH0pO1xuICBhd2FpdCBleHBlY3RGbHV4QWN0aW9uKGFjdGlvbnMuaXRlbUJ5SWQoJ2FwcC0xJyksIGZsdXgsIHtcbiAgICBhcHA6IG1ha2VFbnRpdHkoJ2FwcHMnLCAnaXRlbUJ5SWQnKSxcbiAgICB0eXBlOiAnQVBQX0dFVF9JVEVNX1NVQ0NFU1MnXG4gIH0pO1xuICBhd2FpdCBleHBlY3RGbHV4QWN0aW9uKGFjdGlvbnMubGlzdCgpLCBmbHV4LCB7XG4gICAgbGlzdDogbGlzdEVudGl0eSgnYXBwcycsICdsaXN0JyksXG4gICAgdHlwZTogJ0FQUF9HRVRfTElTVF9TVUNDRVNTJ1xuICB9KTtcbiAgYXdhaXQgZXhwZWN0Rmx1eEFjdGlvbihhY3Rpb25zLnVwZGF0ZSh7YXBwSWQ6ICdhcHAtMScsIG5hbWU6ICdVcGRhdGVkJ30pLCBmbHV4LCB7XG4gICAgYXBwOiBtYWtlRW50aXR5KCdhcHBzJywgJ3VwZGF0ZScpLFxuICAgIHR5cGU6ICdBUFBfVVBEQVRFX0lURU1fU1VDQ0VTUydcbiAgfSk7XG4gIGF3YWl0IGV4cGVjdEZsdXhBY3Rpb24oYWN0aW9ucy5kZWxldGUoJ2FwcC0xJyksIGZsdXgsIHtcbiAgICBhcHA6IG1ha2VFbnRpdHkoJ2FwcHMnLCAncmVtb3ZlJyksXG4gICAgdHlwZTogJ0FQUF9SRU1PVkVfSVRFTV9TVUNDRVNTJ1xuICB9KTtcbiAgYWN0aW9ucy51cGRhdGVBcHBBZGFwdGVyKChpbnB1dCkgPT4gaW5wdXQpO1xuICBhY3Rpb25zLnVwZGF0ZUFwcEFkYXB0ZXJPcHRpb25zKHtzdHJpY3Q6IHRydWV9KTtcblxuICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcignYXBwIGZhaWxlZCcpO1xuICBhcGlNb2Nrcy5hcHBNdXRhdGlvbi5tb2NrUmVqZWN0ZWRWYWx1ZU9uY2UoZXJyb3IpO1xuICBhd2FpdCBleHBlY3RGbHV4RXJyb3IoYWN0aW9ucy5hZGQoe2FwcElkOiAnYXBwLTEnLCBuYW1lOiAnQXBwJ30pLCBmbHV4LCBlcnJvciwgJ0FQUF9BRERfSVRFTV9FUlJPUicpO1xufTtcblxuZXhwb3J0IGNvbnN0IHJ1bkNvbm5lY3Rpb25BY3Rpb25zU2NlbmFyaW8gPSBhc3luYyAoKSA9PiB7XG4gIGNvbnN0IHtjcmVhdGVDb25uZWN0aW9uQWN0aW9uc30gPSBhd2FpdCBpbXBvcnQoJy4uL2FjdGlvbnMvY29ubmVjdGlvbkFjdGlvbnMvY29ubmVjdGlvbkFjdGlvbnMuanMnKTtcbiAgY29uc3QgYWN0aW9ucyA9IGNyZWF0ZUNvbm5lY3Rpb25BY3Rpb25zKGNyZWF0ZUZsdXgoKSBhcyBhbnkpO1xuICBjb25zdCBjb25zb2xlRXJyb3IgPSB2aS5zcHlPbihjb25zb2xlLCAnZXJyb3InKS5tb2NrSW1wbGVtZW50YXRpb24oKCkgPT4gdW5kZWZpbmVkKTtcblxuICB0cnkge1xuICAgIGF3YWl0IGV4cGVjdChhY3Rpb25zLmFkZENvbm5lY3Rpb24oJ3VzZXJzJyBhcyBhbnksICd1c2VyLTEnLCAncG9zdHMnIGFzIGFueSwgJ3Bvc3QtMScpKS5yZXNvbHZlcy50b0JlKHRydWUpO1xuICAgIGF3YWl0IGV4cGVjdChhY3Rpb25zLmdldENvbm5lY3Rpb25zKCd1c2VycycgYXMgYW55LCAndXNlci0xJywgJ3Bvc3RzJyBhcyBhbnksIHtjb25uZWN0aW9uVHlwZTogJ21lbWJlcid9LCB7Y2FjaGVUaW1lb3V0OiA1fSkpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gICAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuZ2V0Q29ubmVjdGlvbnMoJ3VzZXJzJyBhcyBhbnksICd1c2VyLTEnLCB1bmRlZmluZWQsIHt9LCB7Y2FjaGVUaW1lb3V0OiA1fSkpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gICAgYXdhaXQgZXhwZWN0KGFjdGlvbnMucmVtb3ZlQ29ubmVjdGlvbigndXNlcnMnIGFzIGFueSwgJ3VzZXItMScsICdwb3N0cycgYXMgYW55LCAncG9zdC0xJykpLnJlc29sdmVzLnRvQmUodHJ1ZSk7XG5cbiAgICBhcGlNb2Nrcy5hcHBNdXRhdGlvbi5tb2NrUmVqZWN0ZWRWYWx1ZU9uY2UobmV3IEVycm9yKCdjb25uZWN0aW9uIGZhaWxlZCcpKTtcbiAgICBhd2FpdCBleHBlY3QoYWN0aW9ucy5hZGRDb25uZWN0aW9uKCd1c2VycycgYXMgYW55LCAndXNlci0xJywgJ3Bvc3RzJyBhcyBhbnksICdwb3N0LTEnKSkucmVqZWN0cy50b1Rocm93KCdjb25uZWN0aW9uIGZhaWxlZCcpO1xuXG4gICAgYXBpTW9ja3MuYXBwUXVlcnkubW9ja1JlamVjdGVkVmFsdWVPbmNlKG5ldyBFcnJvcignY29ubmVjdGlvbiBxdWVyeSBmYWlsZWQnKSk7XG4gICAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuZ2V0Q29ubmVjdGlvbnMoJ3VzZXJzJyBhcyBhbnksICd1c2VyLTEnKSkucmVqZWN0cy50b1Rocm93KCdjb25uZWN0aW9uIHF1ZXJ5IGZhaWxlZCcpO1xuXG4gICAgYXBpTW9ja3MuYXBwTXV0YXRpb24ubW9ja1JlamVjdGVkVmFsdWVPbmNlKG5ldyBFcnJvcignY29ubmVjdGlvbiByZW1vdmUgZmFpbGVkJykpO1xuICAgIGF3YWl0IGV4cGVjdChhY3Rpb25zLnJlbW92ZUNvbm5lY3Rpb24oJ3VzZXJzJyBhcyBhbnksICd1c2VyLTEnLCAncG9zdHMnIGFzIGFueSwgJ3Bvc3QtMScpKS5yZWplY3RzLnRvVGhyb3coJ2Nvbm5lY3Rpb24gcmVtb3ZlIGZhaWxlZCcpO1xuICB9IGZpbmFsbHkge1xuICAgIGNvbnNvbGVFcnJvci5tb2NrUmVzdG9yZSgpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgcnVuUG9zdEFjdGlvbnNTY2VuYXJpbyA9IGFzeW5jICgpID0+IHtcbiAgY29uc3Qge2NyZWF0ZVBvc3RBY3Rpb25zfSA9IGF3YWl0IGltcG9ydCgnLi4vYWN0aW9ucy9wb3N0QWN0aW9ucy9wb3N0QWN0aW9ucy5qcycpO1xuICBjb25zdCBhY3Rpb25zID0gY3JlYXRlUG9zdEFjdGlvbnMoY3JlYXRlRmx1eCgpIGFzIGFueSk7XG4gIGNvbnN0IHBvc3QgPSB7Y29udGVudDogJ2hlbGxvJywgbGF0aXR1ZGU6IDEsIGxvbmdpdHVkZTogMiwgbmFtZTogJ1Bvc3QnLCBwb3N0SWQ6ICdwb3N0LTEnLCB0YWdzOiBbe25hbWU6ICd0YWcnfV19O1xuXG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmFkZChwb3N0KSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuaXRlbUJ5SWQoJ3Bvc3QtMScpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5pdGVtQnlJZCgncG9zdC0xJywgW10sIHtjYWNoZVRpbWVvdXQ6IDV9KSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuaXRlbUJ5SWQoJ3Bvc3QtMScsIFtdLCB7Y2FjaGVUaW1lb3V0OiA1fSkpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmxpc3RCeUxhdGVzdCgpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5saXN0QnlMYXRlc3QoMCwgMTAsIFtdLCB7Y2FjaGVUaW1lb3V0OiA1fSkpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmxpc3RCeUxhdGVzdCgwLCAxMCwgW10sIHtjYWNoZVRpbWVvdXQ6IDV9KSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMubGlzdEJ5TG9jYXRpb24oMSwgMikpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmxpc3RCeUxvY2F0aW9uKDEsIDIsIDAsIDEwLCBbXSwge2NhY2hlVGltZW91dDogNX0pKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5saXN0QnlMb2NhdGlvbigxLCAyLCAwLCAxMCwgW10sIHtjYWNoZVRpbWVvdXQ6IDV9KSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMubGlzdEJ5UmVhY3Rpb25zKFsnbGlrZSddLCAxLCAyKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMubGlzdEJ5UmVhY3Rpb25zKFsnbGlrZSddLCAxLCAyLCAwLCAxMCwgW10sIHtjYWNoZVRpbWVvdXQ6IDV9KSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMubGlzdEJ5UmVhY3Rpb25zKFsnbGlrZSddLCAxLCAyLCAwLCAxMCwgW10sIHtjYWNoZVRpbWVvdXQ6IDV9KSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMubGlzdEJ5VGFncyhbJ3RhZyddLCAxLCAyKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMubGlzdEJ5VGFncyhbJ3RhZyddLCAxLCAyLCAwLCAxMCwgW10sIHtjYWNoZVRpbWVvdXQ6IDV9KSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMubGlzdEJ5VGFncyhbJ3RhZyddLCAxLCAyLCAwLCAxMCwgW10sIHtjYWNoZVRpbWVvdXQ6IDV9KSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMudXBkYXRlKHBvc3QpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5kZWxldGUoJ3Bvc3QtMScpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhY3Rpb25zLnVwZGF0ZVBvc3RBZGFwdGVyKChpbnB1dCkgPT4gaW5wdXQpO1xuICBhY3Rpb25zLnVwZGF0ZVBvc3RBZGFwdGVyT3B0aW9ucyh7c3RyaWN0OiB0cnVlfSk7XG5cbiAgYXBpTW9ja3MuYXBwUXVlcnkubW9ja1JlamVjdGVkVmFsdWVPbmNlKG5ldyBFcnJvcigncG9zdCBmYWlsZWQnKSk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLml0ZW1CeUlkKCdwb3N0LTEnKSkucmVqZWN0cy50b1Rocm93KCdwb3N0IGZhaWxlZCcpO1xufTtcblxuZXhwb3J0IGNvbnN0IHJ1blJlYWN0aW9uQWN0aW9uc1NjZW5hcmlvID0gYXN5bmMgKCkgPT4ge1xuICBjb25zdCB7Y3JlYXRlUmVhY3Rpb25BY3Rpb25zfSA9IGF3YWl0IGltcG9ydCgnLi4vYWN0aW9ucy9yZWFjdGlvbkFjdGlvbnMvcmVhY3Rpb25BY3Rpb25zLmpzJyk7XG4gIGNvbnN0IGFjdGlvbnMgPSBjcmVhdGVSZWFjdGlvbkFjdGlvbnMoY3JlYXRlRmx1eCgpIGFzIGFueSk7XG4gIGNvbnN0IHJlYWN0aW9uID0ge25hbWU6ICdsaWtlJywgdHlwZTogJ3Bvc3RzJyBhcyBjb25zdCwgdmFsdWU6ICcxJ307XG5cbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuYWRkUmVhY3Rpb24oJ3Bvc3QtMScsICdwb3N0JywgcmVhY3Rpb24pKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5hZGRQZXJzb25hUmVhY3Rpb24oJ3BlcnNvbmEtMScsICdwb3N0LTEnLCAncG9zdCcsIHJlYWN0aW9uKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuZGVsZXRlUmVhY3Rpb24oJ3Bvc3QtMScsICdwb3N0JywgJ2xpa2UnKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuZGVsZXRlUGVyc29uYVJlYWN0aW9uKCdwZXJzb25hLTEnLCAncG9zdC0xJywgJ3Bvc3QnLCAnbGlrZScpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5nZXRSZWFjdGlvbkNvdW50KCdwb3N0LTEnLCAncG9zdCcsICdsaWtlJykpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmhhc1JlYWN0aW9uKCdwb3N0LTEnLCAncG9zdCcsICdsaWtlJywgJ3VwJykpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmhhc1BlcnNvbmFSZWFjdGlvbigncGVyc29uYS0xJywgJ3Bvc3QtMScsICdwb3N0JywgJ2xpa2UnKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgZXhwZWN0KGFjdGlvbnMuYWJicmV2aWF0ZUNvdW50KDEyMDApKS50b0JlKCcxLjJrJyk7XG4gIGFjdGlvbnMudXBkYXRlUmVhY3Rpb25BZGFwdGVyKChpbnB1dCkgPT4gaW5wdXQpO1xuICBhY3Rpb25zLnVwZGF0ZVJlYWN0aW9uQWRhcHRlck9wdGlvbnMoe3N0cmljdDogdHJ1ZX0pO1xufTtcblxuZXhwb3J0IGNvbnN0IHJ1blZpZGVvQWN0aW9uc1NjZW5hcmlvID0gYXN5bmMgKCkgPT4ge1xuICBjb25zdCB7Y3JlYXRlVmlkZW9BY3Rpb25zfSA9IGF3YWl0IGltcG9ydCgnLi4vYWN0aW9ucy92aWRlb0FjdGlvbnMvdmlkZW9BY3Rpb25zLmpzJyk7XG4gIGNvbnN0IGFjdGlvbnMgPSBjcmVhdGVWaWRlb0FjdGlvbnMoY3JlYXRlRmx1eCgpIGFzIGFueSk7XG4gIGNvbnN0IHZpZGVvID0ge2l0ZW1JZDogJ3Bvc3QtMScsIGl0ZW1UeXBlOiAncG9zdCcsIG5hbWU6ICdWaWRlbycsIHZpZGVvSWQ6ICd2aWRlby0xJ307XG5cbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuYWRkKHZpZGVvKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuZ2V0VmlkZW9CeUlkKCd2aWRlby0xJykpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmdldFZpZGVvQnlJZCgndmlkZW8tMScsIFtdLCB7Y2FjaGVUaW1lb3V0OiA1fSkpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmdldFZpZGVvQnlJZCgndmlkZW8tMScsIFtdLCB7Y2FjaGVUaW1lb3V0OiA1fSkpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmNyZWF0ZU11bHRpcGFydFVwbG9hZCh2aWRlbywgMSkpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmdldE11bHRpcGFydFVwbG9hZFBhcnRVcmxzKCd2aWRlby0xJywgJ3VwbG9hZC0xJywgWzFdKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuY29tcGxldGVNdWx0aXBhcnRVcGxvYWQoJ3ZpZGVvLTEnLCAndXBsb2FkLTEnLCBbe2V0YWc6ICdldGFnLTEnLCBwYXJ0TnVtYmVyOiAxfSBhcyBhbnldKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuYWJvcnRNdWx0aXBhcnRVcGxvYWQoJ3ZpZGVvLTEnLCAndXBsb2FkLTEnKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMubGlzdCgpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5saXN0KDAsIDEwLCBbXSwge2NhY2hlVGltZW91dDogNX0pKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5saXN0KDAsIDEwLCBbXSwge2NhY2hlVGltZW91dDogNX0pKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5saXN0QnlJdGVtKCdwb3N0LTEnKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMubGlzdEJ5SXRlbSgncG9zdC0xJywgMCwgMTAsIFtdLCB7Y2FjaGVUaW1lb3V0OiA1fSkpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmxpc3RCeUl0ZW0oJ3Bvc3QtMScsIDAsIDEwLCBbXSwge2NhY2hlVGltZW91dDogNX0pKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5saXN0QnlSZWFjdGlvbnMoWydsaWtlJ10pKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5saXN0QnlSZWFjdGlvbnMoWydsaWtlJ10sIDAsIDEwLCBbXSwge2NhY2hlVGltZW91dDogNX0pKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5saXN0QnlSZWFjdGlvbnMoWydsaWtlJ10sIDAsIDEwLCBbXSwge2NhY2hlVGltZW91dDogNX0pKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy51cGRhdGUodmlkZW8pKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5kZWxldGUoJ3ZpZGVvLTEnKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYWN0aW9ucy51cGRhdGVWaWRlb0FkYXB0ZXIoKGlucHV0KSA9PiBpbnB1dCk7XG4gIGFjdGlvbnMudXBkYXRlVmlkZW9BZGFwdGVyT3B0aW9ucyh7c3RyaWN0OiB0cnVlfSk7XG5cbiAgYXBpTW9ja3MuYXBwTXV0YXRpb24ubW9ja1JlamVjdGVkVmFsdWVPbmNlKG5ldyBFcnJvcigndmlkZW8gZmFpbGVkJykpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy51cGRhdGUodmlkZW8pKS5yZWplY3RzLnRvVGhyb3coJ3ZpZGVvIGZhaWxlZCcpO1xuXG4gIGFwaU1vY2tzLmFwcE11dGF0aW9uLm1vY2tSZWplY3RlZFZhbHVlT25jZShuZXcgRXJyb3IoJ211bHRpcGFydCBmYWlsZWQnKSk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmdldE11bHRpcGFydFVwbG9hZFBhcnRVcmxzKCd2aWRlby0xJywgJ3VwbG9hZC0xJywgWzFdKSkucmVqZWN0cy50b1Rocm93KCdtdWx0aXBhcnQgZmFpbGVkJyk7XG59O1xuXG5leHBvcnQgY29uc3QgcnVuR3JvdXBBY3Rpb25zU2NlbmFyaW8gPSBhc3luYyAoKSA9PiB7XG4gIGNvbnN0IHtjcmVhdGVHcm91cEFjdGlvbnN9ID0gYXdhaXQgaW1wb3J0KCcuLi9hY3Rpb25zL2dyb3VwQWN0aW9ucy9ncm91cEFjdGlvbnMuanMnKTtcbiAgY29uc3QgYWN0aW9ucyA9IGNyZWF0ZUdyb3VwQWN0aW9ucyhjcmVhdGVGbHV4KCkgYXMgYW55KTtcbiAgY29uc3QgZ3JvdXAgPSB7ZGVzY3JpcHRpb246ICdHcm91cCcsIGdyb3VwSWQ6ICdncm91cC0xJywgbmFtZTogJ0dyb3VwJ307XG5cbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuYWRkKGdyb3VwKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuaXRlbUJ5SWQoJ2dyb3VwLTEnKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMubGlzdEJ5TGF0ZXN0KCkpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLnVwZGF0ZShncm91cCkpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmRlbGV0ZSgnZ3JvdXAtMScpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhY3Rpb25zLnVwZGF0ZUdyb3VwQWRhcHRlcigoaW5wdXQpID0+IGlucHV0KTtcbiAgYWN0aW9ucy51cGRhdGVHcm91cEFkYXB0ZXJPcHRpb25zKHtzdHJpY3Q6IHRydWV9KTtcblxuICBhcGlNb2Nrcy5hcHBRdWVyeS5tb2NrUmVqZWN0ZWRWYWx1ZU9uY2UobmV3IEVycm9yKCdncm91cCBmYWlsZWQnKSk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLml0ZW1CeUlkKCdncm91cC0xJykpLnJlamVjdHMudG9UaHJvdygnZ3JvdXAgZmFpbGVkJyk7XG59O1xuXG5leHBvcnQgY29uc3QgcnVuQ29udmVyc2F0aW9uQWN0aW9uc1NjZW5hcmlvID0gYXN5bmMgKCkgPT4ge1xuICBjb25zdCB7Y3JlYXRlQ29udmVyc2F0aW9uQWN0aW9uc30gPSBhd2FpdCBpbXBvcnQoJy4uL2FjdGlvbnMvY29udmVyc2F0aW9uQWN0aW9ucy9jb252ZXJzYXRpb25BY3Rpb25zLmpzJyk7XG4gIGNvbnN0IGFjdGlvbnMgPSBjcmVhdGVDb252ZXJzYXRpb25BY3Rpb25zKGNyZWF0ZUZsdXgoKSBhcyBhbnkpO1xuICBjb25zdCBjb252ZXJzYXRpb24gPSB7Y29udmVyc2F0aW9uSWQ6ICdjb252ZXJzYXRpb24tMScsIG5hbWU6ICdDb252ZXJzYXRpb24nLCB0eXBlOiAnZGlyZWN0J307XG5cbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuYWRkKGNvbnZlcnNhdGlvbikpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLml0ZW1CeUlkKCdjb252ZXJzYXRpb24tMScpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5saXN0KCkpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLnVwZGF0ZShjb252ZXJzYXRpb24pKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5kZWxldGUoJ2NvbnZlcnNhdGlvbi0xJykpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGFjdGlvbnMudXBkYXRlQ29udmVyc2F0aW9uQWRhcHRlcigoaW5wdXQpID0+IGlucHV0KTtcbiAgYWN0aW9ucy51cGRhdGVDb252ZXJzYXRpb25BZGFwdGVyT3B0aW9ucyh7c3RyaWN0OiB0cnVlfSk7XG5cbiAgYXBpTW9ja3MuYXBwUXVlcnkubW9ja1JlamVjdGVkVmFsdWVPbmNlKG5ldyBFcnJvcignY29udmVyc2F0aW9uIGZhaWxlZCcpKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMubGlzdCgpKS5yZWplY3RzLnRvVGhyb3coJ2NvbnZlcnNhdGlvbiBmYWlsZWQnKTtcbn07XG5cbmV4cG9ydCBjb25zdCBydW5FdmVudEFjdGlvbnNTY2VuYXJpbyA9IGFzeW5jICgpID0+IHtcbiAgY29uc3Qge2NyZWF0ZUV2ZW50QWN0aW9uc30gPSBhd2FpdCBpbXBvcnQoJy4uL2FjdGlvbnMvZXZlbnRBY3Rpb25zL2V2ZW50QWN0aW9ucy5qcycpO1xuICBjb25zdCBhY3Rpb25zID0gY3JlYXRlRXZlbnRBY3Rpb25zKGNyZWF0ZUZsdXgoKSBhcyBhbnkpO1xuICBjb25zdCBldmVudCA9IHtkZXNjcmlwdGlvbjogJ0V2ZW50JywgZXZlbnRJZDogJ2V2ZW50LTEnLCBuYW1lOiAnRXZlbnQnLCB0YWdzOiBbe25hbWU6ICdtdXNpYyd9XX07XG5cbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuYWRkRXZlbnQoZXZlbnQpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5nZXRFdmVudCgnZXZlbnQtMScpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5nZXRFdmVudHNCeVRhZ3MoWydtdXNpYyddLCAxLCAyKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuZ2V0RXZlbnRzQnlSZWFjdGlvbnMoWydsaWtlJ10sIDEsIDIpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5yc3ZwRXZlbnQoe2V2ZW50SWQ6ICdldmVudC0xJywgc3RhdHVzOiAnZ29pbmcnfSBhcyBhbnkpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy51cGRhdGVFdmVudChldmVudCkpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmRlbGV0ZUV2ZW50KCdldmVudC0xJykpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGFjdGlvbnMudXBkYXRlRXZlbnRBZGFwdGVyKChpbnB1dCkgPT4gaW5wdXQpO1xuICBhY3Rpb25zLnVwZGF0ZUV2ZW50QWRhcHRlck9wdGlvbnMoe3N0cmljdDogdHJ1ZX0pO1xuXG4gIGFwaU1vY2tzLmFwcE11dGF0aW9uLm1vY2tSZWplY3RlZFZhbHVlT25jZShuZXcgRXJyb3IoJ2V2ZW50IGZhaWxlZCcpKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMudXBkYXRlRXZlbnQoZXZlbnQpKS5yZWplY3RzLnRvVGhyb3coJ2V2ZW50IGZhaWxlZCcpO1xufTtcblxuZXhwb3J0IGNvbnN0IHJ1bkxvY2F0aW9uQWN0aW9uc1NjZW5hcmlvID0gYXN5bmMgKCkgPT4ge1xuICBjb25zdCB7Y3JlYXRlTG9jYXRpb25BY3Rpb25zfSA9IGF3YWl0IGltcG9ydCgnLi4vYWN0aW9ucy9sb2NhdGlvbkFjdGlvbnMvbG9jYXRpb25BY3Rpb25zLmpzJyk7XG4gIGNvbnN0IGFjdGlvbnMgPSBjcmVhdGVMb2NhdGlvbkFjdGlvbnMoY3JlYXRlRmx1eCgpIGFzIGFueSk7XG4gIGNvbnN0IGxvY2F0aW9uID0ge2FkZHJlc3M6ICcxMjMgTWFpbicsIGl0ZW1JZDogJ2V2ZW50LTEnLCBsYXRpdHVkZTogMSwgbG9jYXRpb25JZDogJ2xvY2F0aW9uLTEnLCBsb25naXR1ZGU6IDJ9O1xuXG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmF1dG9jb21wbGV0ZUxvY2F0aW9uKCcxMjMgTWFpbicsIDEsIDIpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5hZGQobG9jYXRpb24pKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5nZXRHb29nbGVMb2NhdGlvbignMTIzIE1haW4nKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuZ2V0TG9jYXRpb24obG9jYXRpb24pKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5saXN0QnlJdGVtKCdldmVudC0xJykpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLnVwZGF0ZShsb2NhdGlvbikpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmRlbGV0ZSgnbG9jYXRpb24tMScpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhY3Rpb25zLnVwZGF0ZUxvY2F0aW9uQWRhcHRlcigoaW5wdXQpID0+IGlucHV0KTtcbiAgYWN0aW9ucy51cGRhdGVMb2NhdGlvbkFkYXB0ZXJPcHRpb25zKHtzdHJpY3Q6IHRydWV9KTtcblxuICBhcGlNb2Nrcy5hcHBNdXRhdGlvbi5tb2NrUmVqZWN0ZWRWYWx1ZU9uY2UobmV3IEVycm9yKCdsb2NhdGlvbiBmYWlsZWQnKSk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLnVwZGF0ZShsb2NhdGlvbikpLnJlamVjdHMudG9UaHJvdygnbG9jYXRpb24gZmFpbGVkJyk7XG59O1xuXG5leHBvcnQgY29uc3QgcnVuUGVybWlzc2lvbkFjdGlvbnNTY2VuYXJpbyA9IGFzeW5jICgpID0+IHtcbiAgY29uc3Qge2NyZWF0ZVBlcm1pc3Npb25BY3Rpb25zfSA9IGF3YWl0IGltcG9ydCgnLi4vYWN0aW9ucy9wZXJtaXNzaW9uQWN0aW9ucy9wZXJtaXNzaW9uQWN0aW9ucy5qcycpO1xuICBjb25zdCBhY3Rpb25zID0gY3JlYXRlUGVybWlzc2lvbkFjdGlvbnMoY3JlYXRlRmx1eCgpIGFzIGFueSk7XG4gIGNvbnN0IHBlcm1pc3Npb24gPSB7bGV2ZWw6IDEsIG5hbWU6ICdSZWFkJywgcGVybWlzc2lvbklkOiAncGVybWlzc2lvbi0xJywgcmVzb3VyY2U6ICdwb3N0cycsIHVzZXJJZDogJ3VzZXItMSd9O1xuXG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmFkZChwZXJtaXNzaW9uKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuY2hlY2soJ3VzZXItMScsICdwb3N0cycsICdyZWFkJykpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLml0ZW1CeUlkKCdwZXJtaXNzaW9uLTEnKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMubGlzdCgpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5saXN0QnlVc2VyKCd1c2VyLTEnKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMudXBkYXRlKHBlcm1pc3Npb24pKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5yZW1vdmUoJ3Blcm1pc3Npb24tMScpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhY3Rpb25zLnVwZGF0ZVBlcm1pc3Npb25BZGFwdGVyKChpbnB1dCkgPT4gaW5wdXQpO1xuICBhY3Rpb25zLnVwZGF0ZVBlcm1pc3Npb25BZGFwdGVyT3B0aW9ucyh7c3RyaWN0OiB0cnVlfSk7XG59O1xuXG5leHBvcnQgY29uc3QgcnVuU3Vic2NyaXB0aW9uQWN0aW9uc1NjZW5hcmlvID0gYXN5bmMgKCkgPT4ge1xuICBjb25zdCB7Y3JlYXRlU3Vic2NyaXB0aW9uQWN0aW9uc30gPSBhd2FpdCBpbXBvcnQoJy4uL2FjdGlvbnMvc3Vic2NyaXB0aW9uQWN0aW9ucy9zdWJzY3JpcHRpb25BY3Rpb25zLmpzJyk7XG4gIGNvbnN0IGFjdGlvbnMgPSBjcmVhdGVTdWJzY3JpcHRpb25BY3Rpb25zKGNyZWF0ZUZsdXgoKSBhcyBhbnkpO1xuICBjb25zdCBwbGFuID0ge2Ftb3VudDogMTAwLCBpbnRlcnZhbDogJ21vbnRoJywgaW50ZXJ2YWxDb3VudDogMSwgaXRlbUlkOiAncGVyc29uYS0xJywgaXRlbVR5cGU6ICdwZXJzb25hcycsIG5hbWU6ICdQbGFuJ307XG4gIGNvbnN0IHN1YnNjcmlwdGlvbiA9IHtpdGVtSWQ6ICdwZXJzb25hLTEnLCBpdGVtVHlwZTogJ3BlcnNvbmFzJywgcGxhbklkOiAncGxhbi0xJywgdXNlcklkOiAndXNlci0xJ307XG5cbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuYWRkUGxhbihwbGFuKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuZ2V0UGxhbkJ5SXRlbSgncGVyc29uYS0xJykpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmFkZFN1YnNjcmlwdGlvbihzdWJzY3JpcHRpb24pKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5nZXRTdWJzY3JpcHRpb25CeUl0ZW0oJ3BlcnNvbmEtMScpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5nZXRTdWJzY3JpcHRpb25MaXN0QnlVc2VyKCd1c2VyLTEnKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuZGVsZXRlU3Vic2NyaXB0aW9uKCdwZXJzb25hLTEnKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcblxuICBhcGlNb2Nrcy5hcHBNdXRhdGlvbi5tb2NrUmVqZWN0ZWRWYWx1ZU9uY2UobmV3IEVycm9yKCdzdWJzY3JpcHRpb24gZmFpbGVkJykpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5hZGRQbGFuKHBsYW4pKS5yZWplY3RzLnRvVGhyb3coJ3N1YnNjcmlwdGlvbiBmYWlsZWQnKTtcbn07XG5cbmV4cG9ydCBjb25zdCBydW5UYWdBY3Rpb25zU2NlbmFyaW8gPSBhc3luYyAoKSA9PiB7XG4gIGNvbnN0IHtjcmVhdGVUYWdBY3Rpb25zfSA9IGF3YWl0IGltcG9ydCgnLi4vYWN0aW9ucy90YWdBY3Rpb25zL3RhZ0FjdGlvbnMuanMnKTtcbiAgY29uc3QgYWN0aW9ucyA9IGNyZWF0ZVRhZ0FjdGlvbnMoY3JlYXRlRmx1eCgpIGFzIGFueSk7XG4gIGNvbnN0IHRhZyA9IHtpdGVtSWQ6ICdwb3N0LTEnLCBpdGVtVHlwZTogJ3Bvc3RzJywgbmFtZTogJ3RhZycsIHRhZ0lkOiAndGFnLTEnfTtcblxuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5hZGRUYWcodGFnKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuYWRkVGFnVG9JdGVtKCd0YWctMScsICdwb3N0LTEnLCAncG9zdHMnKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuZ2V0VGFncygpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5nZXRUYWdzQnlJdGVtKCdwb3N0LTEnLCAncG9zdHMnKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMudXBkYXRlVGFnKHRhZykpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmRlbGV0ZVRhZ0Zyb21JdGVtKCd0YWctMScsICdwb3N0LTEnLCAncG9zdHMnKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuZGVsZXRlVGFnKCd0YWctMScpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhY3Rpb25zLnVwZGF0ZVRhZ0FkYXB0ZXIoKGlucHV0KSA9PiBpbnB1dCk7XG4gIGFjdGlvbnMudXBkYXRlVGFnQWRhcHRlck9wdGlvbnMoe3N0cmljdDogdHJ1ZX0pO1xuXG4gIGFwaU1vY2tzLmFwcFF1ZXJ5Lm1vY2tSZWplY3RlZFZhbHVlT25jZShuZXcgRXJyb3IoJ3RhZyBsaXN0IGZhaWxlZCcpKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuZ2V0VGFncygndGFnJykpLnJlamVjdHMudG9UaHJvdygndGFnIGxpc3QgZmFpbGVkJyk7XG5cbiAgYXBpTW9ja3MuYXBwTXV0YXRpb24ubW9ja1JlamVjdGVkVmFsdWVPbmNlKG5ldyBFcnJvcigndGFnIHVwZGF0ZSBmYWlsZWQnKSk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLnVwZGF0ZVRhZyh0YWcpKS5yZWplY3RzLnRvVGhyb3coJ3RhZyB1cGRhdGUgZmFpbGVkJyk7XG59O1xuXG5leHBvcnQgY29uc3QgcnVuSW1hZ2VBY3Rpb25zU2NlbmFyaW8gPSBhc3luYyAoKSA9PiB7XG4gIGNvbnN0IHtjcmVhdGVJbWFnZUFjdGlvbnN9ID0gYXdhaXQgaW1wb3J0KCcuLi9hY3Rpb25zL2ltYWdlQWN0aW9ucy9pbWFnZUFjdGlvbnMuanMnKTtcbiAgY29uc3QgYWN0aW9ucyA9IGNyZWF0ZUltYWdlQWN0aW9ucyhjcmVhdGVGbHV4KCkgYXMgYW55KTtcbiAgY29uc3QgaW1hZ2UgPSB7aW1hZ2VJZDogJ2ltYWdlLTEnLCBpdGVtSWQ6ICdwb3N0LTEnLCBpdGVtVHlwZTogJ3Bvc3RzJywgc3JjOiAnaHR0cHM6Ly9leGFtcGxlLmNvbS9pbWFnZS5qcGcnfTtcblxuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5nZXRJbWFnZUJ5SWQoJ2ltYWdlLTEnKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuY291bnRCeUl0ZW0oJ3Bvc3QtMScpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5saXN0QnlJdGVtKCdwb3N0LTEnLCAncG9zdHMnKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMubGlzdEJ5UmVhY3Rpb25zKFsnbGlrZSddKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMubGlzdEJ5UGVyc29uYVJlYWN0aW9ucygncGVyc29uYS0xJywgWydsaWtlJ10pKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5hZGQoaW1hZ2UpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy51cGRhdGUoey4uLmltYWdlLCBkZXNjcmlwdGlvbjogJ1VwZGF0ZWQnfSkpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmRlbGV0ZSgnaW1hZ2UtMScpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuXG4gIGFwaU1vY2tzLmFwcFF1ZXJ5Lm1vY2tSZWplY3RlZFZhbHVlT25jZShuZXcgRXJyb3IoJ2ltYWdlIGZhaWxlZCcpKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuZ2V0SW1hZ2VCeUlkKCdpbWFnZS0xJykpLnJlamVjdHMudG9UaHJvdygnaW1hZ2UgZmFpbGVkJyk7XG59O1xuXG5leHBvcnQgY29uc3QgcnVuTWVzc2FnZUFjdGlvbnNTY2VuYXJpbyA9IGFzeW5jICgpID0+IHtcbiAgY29uc3Qge2NyZWF0ZU1lc3NhZ2VBY3Rpb25zfSA9IGF3YWl0IGltcG9ydCgnLi4vYWN0aW9ucy9tZXNzYWdlQWN0aW9ucy9tZXNzYWdlQWN0aW9ucy5qcycpO1xuICBjb25zdCBhY3Rpb25zID0gY3JlYXRlTWVzc2FnZUFjdGlvbnMoY3JlYXRlRmx1eCgpIGFzIGFueSk7XG4gIGNvbnN0IG1lc3NhZ2UgPSB7Y29udGVudDogJ0hlbGxvJywgY29udmVyc2F0aW9uSWQ6ICdjb252ZXJzYXRpb24tMScsIG1lc3NhZ2VJZDogJ21lc3NhZ2UtMSd9O1xuXG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLnNlbmRNZXNzYWdlKG1lc3NhZ2UpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5nZXREaXJlY3RDb252ZXJzYXRpb24oJ3VzZXItMScpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5nZXRNZXNzYWdlcygnY29udmVyc2F0aW9uLTEnKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuZ2V0Q29udmVyc2F0aW9ucygpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhY3Rpb25zLnVwZGF0ZU1lc3NhZ2VBZGFwdGVyKChpbnB1dCkgPT4gaW5wdXQpO1xuICBhY3Rpb25zLnVwZGF0ZU1lc3NhZ2VBZGFwdGVyT3B0aW9ucyh7c3RyaWN0OiB0cnVlfSk7XG59O1xuXG5leHBvcnQgY29uc3QgcnVuQ29udGVudEFjdGlvbnNTY2VuYXJpbyA9IGFzeW5jICgpID0+IHtcbiAgY29uc3Qge2NyZWF0ZUNvbnRlbnRBY3Rpb25zfSA9IGF3YWl0IGltcG9ydCgnLi4vYWN0aW9ucy9jb250ZW50QWN0aW9ucy9jb250ZW50QWN0aW9ucy5qcycpO1xuICBjb25zdCBhY3Rpb25zID0gY3JlYXRlQ29udGVudEFjdGlvbnMoY3JlYXRlRmx1eCgpIGFzIGFueSk7XG4gIGNvbnN0IGNvbnRlbnQgPSB7Y29udGVudDogJ0JvZHknLCBjb250ZW50SWQ6ICdjb250ZW50LTEnLCBrZXk6ICd3ZWxjb21lJywgbG9jYWxlOiAnZW4nfTtcblxuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5saXN0KCkpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmxpc3QoWydkZXNjcmlwdGlvbiddLCB7Y2FjaGVUaW1lb3V0OiA1fSkpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmxpc3QoWydkZXNjcmlwdGlvbiddLCB7Y2FjaGVUaW1lb3V0OiA1fSkpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmxpc3RCeUNhdGVnb3J5KCdkb2NzJykpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLml0ZW1CeUlkKCdjb250ZW50LTEnKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuaXRlbUJ5S2V5KCd3ZWxjb21lJywgJ2VuJykpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmFkZChjb250ZW50KSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMudXBkYXRlKGNvbnRlbnQpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5kZWxldGUoJ2NvbnRlbnQtMScpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuXG4gIGFwaU1vY2tzLmFwcE11dGF0aW9uLm1vY2tSZWplY3RlZFZhbHVlT25jZShuZXcgRXJyb3IoJ2NvbnRlbnQgZmFpbGVkJykpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5hZGQoY29udGVudCkpLnJlamVjdHMudG9UaHJvdygnY29udGVudCBmYWlsZWQnKTtcbn07XG5cbmV4cG9ydCBjb25zdCBydW5UcmFuc2xhdGlvbkFjdGlvbnNTY2VuYXJpbyA9IGFzeW5jICgpID0+IHtcbiAgY29uc3Qge2NyZWF0ZVRyYW5zbGF0aW9uQWN0aW9uc30gPSBhd2FpdCBpbXBvcnQoJy4uL2FjdGlvbnMvdHJhbnNsYXRpb25BY3Rpb25zL3RyYW5zbGF0aW9uQWN0aW9ucy5qcycpO1xuICBjb25zdCBhY3Rpb25zID0gY3JlYXRlVHJhbnNsYXRpb25BY3Rpb25zKGNyZWF0ZUZsdXgoKSBhcyBhbnkpO1xuXG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmFkZFRyYW5zbGF0aW9ucyhbe2tleTogJ3dlbGNvbWUnLCBsb2NhbGU6ICdlbicsIHZhbHVlOiAnV2VsY29tZSd9XSkpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGV4cGVjdChhY3Rpb25zLmdldFRyYW5zbGF0aW9uKCd3ZWxjb21lJywgJ2VuJywgJ2NvbW1vbicpKS50b0JlKCdXZWxjb21lJyk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmdldFRyYW5zbGF0aW9ucyhbJ3dlbGNvbWUnXSwgJ2VuJywgJ2NvbW1vbicpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBleHBlY3QoYWN0aW9ucy5oYXNUcmFuc2xhdGlvbignd2VsY29tZScsICdlbicsICdjb21tb24nKSkudG9CZSh0cnVlKTtcbiAgYWN0aW9ucy5xdWV1ZVRyYW5zbGF0aW9uS2V5KCdoZWFkbGluZScsICdlbicsICdjb21tb24nKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMucHJvY2Vzc1BlbmRpbmdUcmFuc2xhdGlvbnMoJ2VuJywgJ2NvbW1vbicpKS5yZXNvbHZlcy50b0JlVW5kZWZpbmVkKCk7XG4gIGFjdGlvbnMudXBkYXRlVHJhbnNsYXRpb25BZGFwdGVyKChpbnB1dCkgPT4gaW5wdXQpO1xuICBhY3Rpb25zLnVwZGF0ZVRyYW5zbGF0aW9uQWRhcHRlck9wdGlvbnMoe3N0cmljdDogdHJ1ZX0pO1xuXG4gIGFwaU1vY2tzLmFwcFF1ZXJ5Lm1vY2tSZWplY3RlZFZhbHVlT25jZShuZXcgRXJyb3IoJ3RyYW5zbGF0aW9uIGZhaWxlZCcpKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuZ2V0VHJhbnNsYXRpb25zKFsnd2VsY29tZSddLCAnZW4nLCAnY29tbW9uJykpLnJlamVjdHMudG9UaHJvdygndHJhbnNsYXRpb24gZmFpbGVkJyk7XG59O1xuXG5leHBvcnQgY29uc3QgcnVuUGVyc29uYUFjdGlvbnNTY2VuYXJpbyA9IGFzeW5jICgpID0+IHtcbiAgY29uc3Qge2NyZWF0ZVBlcnNvbmFBY3Rpb25zfSA9IGF3YWl0IGltcG9ydCgnLi4vYWN0aW9ucy9wZXJzb25hQWN0aW9ucy9wZXJzb25hQWN0aW9ucy5qcycpO1xuICBjb25zdCBhY3Rpb25zID0gY3JlYXRlUGVyc29uYUFjdGlvbnMoY3JlYXRlRmx1eCgpIGFzIGFueSk7XG4gIGNvbnN0IHBlcnNvbmEgPSB7bmFtZTogJ1BlcnNvbmEnLCBwZXJzb25hSWQ6ICdwZXJzb25hLTEnLCB0YWdzOiBbe25hbWU6ICdjcmVhdG9yJ31dfTtcblxuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5hZGRQZXJzb25hKHBlcnNvbmEpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5nZXRQZXJzb25hQnlJZCgncGVyc29uYS0xJykpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmdldFBlcnNvbmFMaXN0QnlJZHMoWydwZXJzb25hLTEnXSkpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmxpc3RCeVRhZ3MoWydjcmVhdG9yJ10pKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5saXN0QnlSZWxhdGlvbignZm9sbG93JyBhcyBhbnkpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5mb2xsb3dQZXJzb25hKCdwZXJzb25hLTInKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMudW5mb2xsb3dQZXJzb25hKCdwZXJzb25hLTInKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuYmxvY2tQZXJzb25hKCdwZXJzb25hLTInKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMudW5ibG9ja1BlcnNvbmEoJ3BlcnNvbmEtMicpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy51cGRhdGVQZXJzb25hKHBlcnNvbmEpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5kZWxldGVQZXJzb25hKCdwZXJzb25hLTEnKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYWN0aW9ucy51cGRhdGVQZXJzb25hQWRhcHRlcigoaW5wdXQpID0+IGlucHV0KTtcbiAgYWN0aW9ucy51cGRhdGVQZXJzb25hQWRhcHRlck9wdGlvbnMoe3N0cmljdDogdHJ1ZX0pO1xuXG4gIGFwaU1vY2tzLmFwcFF1ZXJ5Lm1vY2tSZWplY3RlZFZhbHVlT25jZShuZXcgRXJyb3IoJ3BlcnNvbmEgZmFpbGVkJykpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5nZXRQZXJzb25hQnlJZCgncGVyc29uYS0xJykpLnJlamVjdHMudG9UaHJvdygncGVyc29uYSBmYWlsZWQnKTtcbn07XG5cbmV4cG9ydCBjb25zdCBydW5Vc2VyQWN0aW9uc1NjZW5hcmlvID0gYXN5bmMgKCkgPT4ge1xuICBjb25zdCB7Y3JlYXRlVXNlckFjdGlvbnN9ID0gYXdhaXQgaW1wb3J0KCcuLi9hY3Rpb25zL3VzZXJBY3Rpb25zL3VzZXJBY3Rpb25zLmpzJyk7XG4gIGNvbnN0IGFjdGlvbnMgPSBjcmVhdGVVc2VyQWN0aW9ucyhjcmVhdGVGbHV4KCkgYXMgYW55KTtcbiAgY29uc3QgdXNlciA9IHtlbWFpbDogJ3VzZXJAZXhhbXBsZS5jb20nLCBwYXNzd29yZDogJ3NlY3JldDEyMycsIHBob25lOiAnMTU1NTEyMzQ1NjcnLCB1c2VySWQ6ICd1c2VyLTEnLCB1c2VybmFtZTogJ3VzZXInfTtcblxuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5hZGRVc2VyKHVzZXIpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5zaWduVXAodXNlcikpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLnVwZGF0ZVVzZXIodXNlcikpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmNvbmZpcm1Db2RlKCcxMjM0NTYnLCAnZW1haWwnKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMucmVtb3ZlKCd1c2VyLTEnKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuc2Vzc2lvbigpKS5yZWplY3RzLnRvVGhyb3coJ2ludmFsaWRfc2Vzc2lvbicpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5pdGVtQnlJZCgndXNlci0xJykpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmdldFVzZXJCeUF0dHJpYnV0ZSgnZW1haWwnLCAndXNlckBleGFtcGxlLmNvbScpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5zYXZlQmlsbGluZ0NhcmQoJ3Rva18xMjMnIGFzIGFueSkpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmRlbGV0ZUJpbGxpbmdDYXJkKCkpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLnVwZGF0ZVBsYW4oJ3BsYW4tMScpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5saXN0KCkpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmxpc3RCeUxhdGVzdCgpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5saXN0QnlDb25uZWN0aW9uKCdmb2xsb3cnIGFzIGFueSkpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmxpc3RCeVJlYWN0aW9ucyhbJ2xpa2UnXSkpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmxpc3RCeVRhZ3MoWydjcmVhdG9yJ10pKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5zZWFyY2goJ3VzZXInKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgZXhwZWN0KGFjdGlvbnMuaXNMb2dnZWRJbigpKS50b0JlKGZhbHNlKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMuY3VycmVudEF1dGhlbnRpY2F0ZWRVc2VyKCkpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmN1cnJlbnRVc2VyKCkpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLnJlZnJlc2hTZXNzaW9uKCd0b2tlbi0xJywgMTUpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5zaWduSW4oe3Bhc3N3b3JkOiAnc2VjcmV0MTIzJywgdXNlcm5hbWU6ICd1c2VyJ30pKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5zaWduT3V0KCkpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLmNvbmZpcm1TaWduVXAoJzEyMzQ1NicsICdlbWFpbCcpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5mb3Jnb3RQYXNzd29yZCgndXNlcicpKS5yZXNvbHZlcy50b0JlRGVmaW5lZCgpO1xuICBhd2FpdCBleHBlY3QoYWN0aW9ucy5zZW5kVmVyaWZpY2F0aW9uRW1haWwoJ3VzZXJAZXhhbXBsZS5jb20nKSkucmVzb2x2ZXMudG9CZURlZmluZWQoKTtcbiAgYXdhaXQgZXhwZWN0KGFjdGlvbnMucmVzZXRQYXNzd29yZCgndXNlcicsICcxMjM0NTYnLCAnc2VjcmV0MTIzJykpLnJlc29sdmVzLnRvQmVEZWZpbmVkKCk7XG4gIGF3YWl0IGV4cGVjdChhY3Rpb25zLnVwZGF0ZVBhc3N3b3JkKCdzZWNyZXQxMjMnLCAnc2VjcmV0NDU2JykpLnJlc29sdmVzLnRvQmUodHJ1ZSk7XG4gIGFjdGlvbnMudXBkYXRlVXNlckFkYXB0ZXIoKGlucHV0KSA9PiBpbnB1dCk7XG4gIGFjdGlvbnMudXBkYXRlVXNlckFkYXB0ZXJPcHRpb25zKHtzdHJpY3Q6IHRydWV9KTtcbn07XG4iXSwibmFtZXMiOlsiZXhwZWN0IiwidmkiLCJtYWtlRW50aXR5IiwiZGF0YVR5cGUiLCJvcGVyYXRpb24iLCJpZE5hbWUiLCJzbGljZSIsImlkIiwiaXRlbUlkIiwiaXRlbVR5cGUiLCJrZXkiLCJsb2NhbGUiLCJuYW1lIiwidmFsdWUiLCJsaXN0RW50aXR5IiwicmVzcG9uc2VGb3IiLCJlbnRpdHkiLCJsaXN0IiwidG9Mb3dlckNhc2UiLCJpbmNsdWRlcyIsImFib3J0TXVsdGlwYXJ0VXBsb2FkIiwiYWRkIiwiYWRkQ29ubmVjdGlvbiIsImFkZEV2ZW50IiwiYWRkSXRlbSIsImFkZFBlcnNvbmFSZWFjdGlvbiIsImFkZFBsYW4iLCJhZGRQb3N0IiwiYWRkUmVhY3Rpb24iLCJhZGRTdWJzY3JpcHRpb24iLCJhZGRUYWciLCJhZGRUYWdUb0l0ZW0iLCJhZGRVc2VyIiwiYXV0b2NvbXBsZXRlTG9jYXRpb24iLCJjaGVjayIsImNvbXBsZXRlTXVsdGlwYXJ0VXBsb2FkIiwiY3JlYXRlTXVsdGlwYXJ0VXBsb2FkIiwiYnVja2V0IiwicGFydFNpemUiLCJwYXJ0VXJscyIsInBhcnROdW1iZXIiLCJ1cmwiLCJ1cGxvYWRJZCIsInZpZGVvIiwidmlkZW9JZCIsImRlbGV0ZUNvbm5lY3Rpb24iLCJkZWxldGVDb250ZW50IiwiZGVsZXRlRXZlbnQiLCJkZWxldGVQb3N0IiwiZGVsZXRlUGVyc29uYSIsImRlbGV0ZVBlcnNvbmFSZWFjdGlvbiIsImRlbGV0ZVJlYWN0aW9uIiwiZGVsZXRlU3Vic2NyaXB0aW9uIiwiZGVsZXRlVGFnIiwiZGVsZXRlVGFnRnJvbUl0ZW0iLCJnZXRDb25uZWN0aW9ucyIsImdldENvbnRlbnQiLCJnZXRDb250ZW50QnlLZXkiLCJnZXRDb250ZW50c0J5Q2F0ZWdvcnkiLCJnZXRDb250ZW50c0xpc3QiLCJnZXRDb252ZXJzYXRpb25zIiwiZ2V0Q3VycmVudExvY2F0aW9uIiwiZ2V0RGlyZWN0Q29udmVyc2F0aW9uIiwiZ2V0RXZlbnQiLCJnZXRFdmVudHNCeVJlYWN0aW9ucyIsImdldEV2ZW50c0J5VGFncyIsImdldEdvb2dsZUxvY2F0aW9uIiwiZ2V0SW1hZ2VCeUlkIiwiZ2V0SW1hZ2VzQnlJdGVtIiwiZ2V0TG9jYXRpb24iLCJnZXRNZXNzYWdlcyIsImdldE11bHRpcGFydFVwbG9hZFBhcnRVcmxzIiwiZ2V0UGVyc29uYUJ5SWQiLCJnZXRQZXJzb25hTGlzdEJ5SWRzIiwiZ2V0UGxhbkJ5SXRlbSIsImdldFBvc3QiLCJnZXRQb3N0c0J5TGF0ZXN0IiwiZ2V0UG9zdHNCeUxvY2F0aW9uIiwiZ2V0UG9zdHNCeVJlYWN0aW9ucyIsImdldFBvc3RzQnlUYWdzIiwiZ2V0UmVhY3Rpb25Db3VudCIsImdldFN1YnNjcmlwdGlvbkJ5SXRlbSIsImdldFN1YnNjcmlwdGlvbkxpc3RCeVVzZXIiLCJnZXRUYWdzIiwiZ2V0VGFnc0J5SXRlbSIsImdldFRyYW5zbGF0aW9uIiwiZ2V0VHJhbnNsYXRpb25zIiwiZ2V0VXNlciIsImdldFVzZXJCeUF0dHJpYnV0ZSIsImdldFVzZXJMaXN0QnlJZHMiLCJnZXRWaWRlb0J5SWQiLCJnZXRWaWRlb0xpc3RCeUl0ZW0iLCJnZXRWaWRlb0xpc3RCeVJlYWN0aW9ucyIsImhhc1BlcnNvbmFSZWFjdGlvbiIsImhhc1JlYWN0aW9uIiwiaW1hZ2VzQnlQZXJzb25hUmVhY3Rpb25zIiwiaW1hZ2VzQnlSZWFjdGlvbnMiLCJsaXN0QnlSZWxhdGlvbiIsImxpc3RCeVRhZ3MiLCJyZW1vdmUiLCJyZW1vdmVDb25uZWN0aW9uIiwicmVtb3ZlSXRlbSIsInJlbW92ZVBlcm1pc3Npb24iLCJyZW1vdmVVc2VyIiwicnN2cEV2ZW50Iiwic2VhcmNoIiwiY29uZmlybVNpZ25VcCIsImZvcmdvdFBhc3N3b3JkIiwicmVzZXRQYXNzd29yZCIsInNlbmRWZXJpZmljYXRpb25FbWFpbCIsInNlc3Npb24iLCJzaWduSW4iLCJleHBpcmVzIiwidG9rZW4iLCJ1c2VySWQiLCJ1c2VyIiwic2lnbk91dCIsInNpZ25VcCIsInVwZGF0ZSIsInVwZGF0ZUNvbnRlbnQiLCJ1cGRhdGVFdmVudCIsInVwZGF0ZUl0ZW0iLCJ1cGRhdGVMb2NhdGlvbiIsInVwZGF0ZVBlcm1pc3Npb24iLCJ1cGRhdGVQb3N0IiwidXBkYXRlVGFnIiwidXBkYXRlVXNlciIsImFkZExvY2F0aW9uIiwiZGVsZXRlTG9jYXRpb24iLCJsb2NhdGlvbnNCeUl0ZW0iLCJpbWFnZUNvdW50IiwiYXBpTW9ja3MiLCJob2lzdGVkIiwiYXBwTXV0YXRpb24iLCJmbiIsImZsdXgiLCJfcXVlcnlWYXJpYWJsZXMiLCJfcHJvcHMiLCJvcHRpb25zIiwicmVzcG9uc2UiLCJvblN1Y2Nlc3MiLCJhcHBRdWVyeSIsInB1YmxpY011dGF0aW9uIiwicHVibGljUXVlcnkiLCJyZWZyZXNoU2Vzc2lvbiIsInVwbG9hZEltYWdlIiwiaW1hZ2UiLCJtb2NrIiwiYXV0b0NvbXBsZXRlTG9jYXRpb24iLCJhZGRyZXNzIiwibGF0aXR1ZGUiLCJsb25naXR1ZGUiLCJjcmVhdGVGbHV4Iiwic3RhdGUiLCJNYXAiLCJhcGkiLCJ3ZWJzb2NrZXQiLCJwZW5kaW5nS2V5cyIsIlNldCIsInRyYW5zbGF0aW9ucyIsInBlcnNvbmFJZCIsImRpc3BhdGNoIiwiYWN0aW9uIiwiZ2V0U3RhdGUiLCJwYXRoIiwiZmFsbGJhY2siLCJnZXQiLCJPYmplY3QiLCJmcm9tRW50cmllcyIsInNldFN0YXRlIiwic2V0IiwiZXhwZWN0Rmx1eEFjdGlvbiIsInByb21pc2UiLCJleHBlY3RlZEFjdGlvbiIsInJlc29sdmVzIiwidG9FcXVhbCIsInRvSGF2ZUJlZW5MYXN0Q2FsbGVkV2l0aCIsImV4cGVjdEZsdXhFcnJvciIsImVycm9yIiwidHlwZSIsInJlamVjdHMiLCJ0b1Rocm93IiwibWVzc2FnZSIsInJlc2V0QWN0aW9uU2NlbmFyaW9Nb2NrcyIsImNsZWFyQWxsTW9ja3MiLCJydW5BcHBBY3Rpb25zU2NlbmFyaW8iLCJjcmVhdGVBcHBBY3Rpb25zIiwiYWN0aW9ucyIsImFwcElkIiwiYXBwIiwiaXRlbUJ5SWQiLCJkZWxldGUiLCJ1cGRhdGVBcHBBZGFwdGVyIiwiaW5wdXQiLCJ1cGRhdGVBcHBBZGFwdGVyT3B0aW9ucyIsInN0cmljdCIsIkVycm9yIiwibW9ja1JlamVjdGVkVmFsdWVPbmNlIiwicnVuQ29ubmVjdGlvbkFjdGlvbnNTY2VuYXJpbyIsImNyZWF0ZUNvbm5lY3Rpb25BY3Rpb25zIiwiY29uc29sZUVycm9yIiwic3B5T24iLCJjb25zb2xlIiwibW9ja0ltcGxlbWVudGF0aW9uIiwidW5kZWZpbmVkIiwidG9CZSIsImNvbm5lY3Rpb25UeXBlIiwiY2FjaGVUaW1lb3V0IiwidG9CZURlZmluZWQiLCJtb2NrUmVzdG9yZSIsInJ1blBvc3RBY3Rpb25zU2NlbmFyaW8iLCJjcmVhdGVQb3N0QWN0aW9ucyIsInBvc3QiLCJjb250ZW50IiwicG9zdElkIiwidGFncyIsImxpc3RCeUxhdGVzdCIsImxpc3RCeUxvY2F0aW9uIiwibGlzdEJ5UmVhY3Rpb25zIiwidXBkYXRlUG9zdEFkYXB0ZXIiLCJ1cGRhdGVQb3N0QWRhcHRlck9wdGlvbnMiLCJydW5SZWFjdGlvbkFjdGlvbnNTY2VuYXJpbyIsImNyZWF0ZVJlYWN0aW9uQWN0aW9ucyIsInJlYWN0aW9uIiwiYWJicmV2aWF0ZUNvdW50IiwidXBkYXRlUmVhY3Rpb25BZGFwdGVyIiwidXBkYXRlUmVhY3Rpb25BZGFwdGVyT3B0aW9ucyIsInJ1blZpZGVvQWN0aW9uc1NjZW5hcmlvIiwiY3JlYXRlVmlkZW9BY3Rpb25zIiwiZXRhZyIsImxpc3RCeUl0ZW0iLCJ1cGRhdGVWaWRlb0FkYXB0ZXIiLCJ1cGRhdGVWaWRlb0FkYXB0ZXJPcHRpb25zIiwicnVuR3JvdXBBY3Rpb25zU2NlbmFyaW8iLCJjcmVhdGVHcm91cEFjdGlvbnMiLCJncm91cCIsImRlc2NyaXB0aW9uIiwiZ3JvdXBJZCIsInVwZGF0ZUdyb3VwQWRhcHRlciIsInVwZGF0ZUdyb3VwQWRhcHRlck9wdGlvbnMiLCJydW5Db252ZXJzYXRpb25BY3Rpb25zU2NlbmFyaW8iLCJjcmVhdGVDb252ZXJzYXRpb25BY3Rpb25zIiwiY29udmVyc2F0aW9uIiwiY29udmVyc2F0aW9uSWQiLCJ1cGRhdGVDb252ZXJzYXRpb25BZGFwdGVyIiwidXBkYXRlQ29udmVyc2F0aW9uQWRhcHRlck9wdGlvbnMiLCJydW5FdmVudEFjdGlvbnNTY2VuYXJpbyIsImNyZWF0ZUV2ZW50QWN0aW9ucyIsImV2ZW50IiwiZXZlbnRJZCIsInN0YXR1cyIsInVwZGF0ZUV2ZW50QWRhcHRlciIsInVwZGF0ZUV2ZW50QWRhcHRlck9wdGlvbnMiLCJydW5Mb2NhdGlvbkFjdGlvbnNTY2VuYXJpbyIsImNyZWF0ZUxvY2F0aW9uQWN0aW9ucyIsImxvY2F0aW9uIiwibG9jYXRpb25JZCIsInVwZGF0ZUxvY2F0aW9uQWRhcHRlciIsInVwZGF0ZUxvY2F0aW9uQWRhcHRlck9wdGlvbnMiLCJydW5QZXJtaXNzaW9uQWN0aW9uc1NjZW5hcmlvIiwiY3JlYXRlUGVybWlzc2lvbkFjdGlvbnMiLCJwZXJtaXNzaW9uIiwibGV2ZWwiLCJwZXJtaXNzaW9uSWQiLCJyZXNvdXJjZSIsImxpc3RCeVVzZXIiLCJ1cGRhdGVQZXJtaXNzaW9uQWRhcHRlciIsInVwZGF0ZVBlcm1pc3Npb25BZGFwdGVyT3B0aW9ucyIsInJ1blN1YnNjcmlwdGlvbkFjdGlvbnNTY2VuYXJpbyIsImNyZWF0ZVN1YnNjcmlwdGlvbkFjdGlvbnMiLCJwbGFuIiwiYW1vdW50IiwiaW50ZXJ2YWwiLCJpbnRlcnZhbENvdW50Iiwic3Vic2NyaXB0aW9uIiwicGxhbklkIiwicnVuVGFnQWN0aW9uc1NjZW5hcmlvIiwiY3JlYXRlVGFnQWN0aW9ucyIsInRhZyIsInRhZ0lkIiwidXBkYXRlVGFnQWRhcHRlciIsInVwZGF0ZVRhZ0FkYXB0ZXJPcHRpb25zIiwicnVuSW1hZ2VBY3Rpb25zU2NlbmFyaW8iLCJjcmVhdGVJbWFnZUFjdGlvbnMiLCJpbWFnZUlkIiwic3JjIiwiY291bnRCeUl0ZW0iLCJsaXN0QnlQZXJzb25hUmVhY3Rpb25zIiwicnVuTWVzc2FnZUFjdGlvbnNTY2VuYXJpbyIsImNyZWF0ZU1lc3NhZ2VBY3Rpb25zIiwibWVzc2FnZUlkIiwic2VuZE1lc3NhZ2UiLCJ1cGRhdGVNZXNzYWdlQWRhcHRlciIsInVwZGF0ZU1lc3NhZ2VBZGFwdGVyT3B0aW9ucyIsInJ1bkNvbnRlbnRBY3Rpb25zU2NlbmFyaW8iLCJjcmVhdGVDb250ZW50QWN0aW9ucyIsImNvbnRlbnRJZCIsImxpc3RCeUNhdGVnb3J5IiwiaXRlbUJ5S2V5IiwicnVuVHJhbnNsYXRpb25BY3Rpb25zU2NlbmFyaW8iLCJjcmVhdGVUcmFuc2xhdGlvbkFjdGlvbnMiLCJhZGRUcmFuc2xhdGlvbnMiLCJoYXNUcmFuc2xhdGlvbiIsInF1ZXVlVHJhbnNsYXRpb25LZXkiLCJwcm9jZXNzUGVuZGluZ1RyYW5zbGF0aW9ucyIsInRvQmVVbmRlZmluZWQiLCJ1cGRhdGVUcmFuc2xhdGlvbkFkYXB0ZXIiLCJ1cGRhdGVUcmFuc2xhdGlvbkFkYXB0ZXJPcHRpb25zIiwicnVuUGVyc29uYUFjdGlvbnNTY2VuYXJpbyIsImNyZWF0ZVBlcnNvbmFBY3Rpb25zIiwicGVyc29uYSIsImFkZFBlcnNvbmEiLCJmb2xsb3dQZXJzb25hIiwidW5mb2xsb3dQZXJzb25hIiwiYmxvY2tQZXJzb25hIiwidW5ibG9ja1BlcnNvbmEiLCJ1cGRhdGVQZXJzb25hIiwidXBkYXRlUGVyc29uYUFkYXB0ZXIiLCJ1cGRhdGVQZXJzb25hQWRhcHRlck9wdGlvbnMiLCJydW5Vc2VyQWN0aW9uc1NjZW5hcmlvIiwiY3JlYXRlVXNlckFjdGlvbnMiLCJlbWFpbCIsInBhc3N3b3JkIiwicGhvbmUiLCJ1c2VybmFtZSIsImNvbmZpcm1Db2RlIiwic2F2ZUJpbGxpbmdDYXJkIiwiZGVsZXRlQmlsbGluZ0NhcmQiLCJ1cGRhdGVQbGFuIiwibGlzdEJ5Q29ubmVjdGlvbiIsImlzTG9nZ2VkSW4iLCJjdXJyZW50QXV0aGVudGljYXRlZFVzZXIiLCJjdXJyZW50VXNlciIsInVwZGF0ZVBhc3N3b3JkIiwidXBkYXRlVXNlckFkYXB0ZXIiLCJ1cGRhdGVVc2VyQWRhcHRlck9wdGlvbnMiXSwibWFwcGluZ3MiOiJBQUFBLFNBQVFBLE1BQU0sRUFBRUMsRUFBRSxRQUFPLFNBQVM7QUFFbEMsTUFBTUMsYUFBYSxDQUFDQyxVQUFrQkM7SUFDcEMsTUFBTUMsU0FBU0YsU0FBU0csS0FBSyxDQUFDLEdBQUcsQ0FBQyxLQUFLO0lBRXZDLE9BQU87UUFDTCxDQUFDRCxPQUFPLEVBQUUsR0FBR0QsVUFBVSxHQUFHLENBQUM7UUFDM0JHLElBQUksR0FBR0osU0FBUyxDQUFDLEVBQUVDLFVBQVUsR0FBRyxDQUFDO1FBQ2pDSSxRQUFRO1FBQ1JDLFVBQVU7UUFDVkMsS0FBSztRQUNMQyxRQUFRO1FBQ1JDLE1BQU0sR0FBR1IsVUFBVSxLQUFLLENBQUM7UUFDekJTLE9BQU8sR0FBR1QsVUFBVSxNQUFNLENBQUM7SUFDN0I7QUFDRjtBQUVBLE1BQU1VLGFBQWEsQ0FBQ1gsVUFBa0JDLFlBQXNCO1FBQzFERixXQUFXQyxVQUFVQztLQUN0QjtBQUVELE1BQU1XLGNBQWMsQ0FBQ1os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
|