@stemy/backend 3.5.16 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/commands/clear-command.d.ts +6 -0
  2. package/commands/fixtures-command.d.ts +9 -0
  3. package/commands/index.d.ts +2 -0
  4. package/common-types.d.ts +29 -7
  5. package/esm2020/commands/clear-command.mjs +17 -0
  6. package/esm2020/commands/fixtures-command.mjs +23 -0
  7. package/esm2020/commands/index.mjs +7 -0
  8. package/esm2020/common-types.mjs +21 -0
  9. package/esm2020/public_api.mjs +379 -0
  10. package/esm2020/requests/asset-image-params.mjs +53 -0
  11. package/esm2020/rest-controllers/assets.controller.mjs +126 -0
  12. package/esm2020/rest-controllers/auth.controller.mjs +46 -0
  13. package/esm2020/rest-controllers/gallery.controller.mjs +21 -0
  14. package/esm2020/rest-controllers/progresses.controller.mjs +29 -0
  15. package/esm2020/rest-controllers/terminal-styles.mjs +67 -0
  16. package/esm2020/rest-controllers/terminal.controller.mjs +125 -0
  17. package/esm2020/rest-middlewares/container.middleware.mjs +20 -0
  18. package/esm2020/rest-middlewares/error-handler.middleware.mjs +74 -0
  19. package/esm2020/rest-middlewares/language.middleware.mjs +18 -0
  20. package/esm2020/rest-middlewares/request-ended.middleware.mjs +23 -0
  21. package/esm2020/rest-middlewares/request-started.middleware.mjs +22 -0
  22. package/esm2020/services/asset-processor.mjs +90 -0
  23. package/esm2020/services/asset-resolver.mjs +31 -0
  24. package/esm2020/services/assets.mjs +140 -0
  25. package/esm2020/services/backend-provider.mjs +22 -0
  26. package/esm2020/services/cache-processor.mjs +16 -0
  27. package/esm2020/services/cache.mjs +62 -0
  28. package/esm2020/services/configuration.mjs +65 -0
  29. package/esm2020/services/endpoint-provider.mjs +13 -0
  30. package/esm2020/services/entities/asset.mjs +43 -0
  31. package/esm2020/services/entities/base-entity.mjs +26 -0
  32. package/esm2020/services/entities/lazy-asset.mjs +73 -0
  33. package/esm2020/services/entities/progress.mjs +176 -0
  34. package/esm2020/services/entities/temp-asset.mjs +45 -0
  35. package/esm2020/services/fixtures.mjs +26 -0
  36. package/esm2020/services/gallery-cache.mjs +27 -0
  37. package/esm2020/services/gallery-image.mjs +37 -0
  38. package/esm2020/services/gallery.mjs +116 -0
  39. package/esm2020/services/id-generator.mjs +42 -0
  40. package/esm2020/services/job-manager.mjs +187 -0
  41. package/esm2020/services/lazy-assets.mjs +48 -0
  42. package/esm2020/services/logger.mjs +21 -0
  43. package/esm2020/services/mail-sender.mjs +36 -0
  44. package/esm2020/services/memory-cache.mjs +57 -0
  45. package/esm2020/services/mongo-connector.mjs +37 -0
  46. package/esm2020/services/open-api.mjs +114 -0
  47. package/esm2020/services/progresses.mjs +86 -0
  48. package/esm2020/services/template-renderer.mjs +64 -0
  49. package/esm2020/services/terminal-manager.mjs +77 -0
  50. package/esm2020/services/token-generator.mjs +35 -0
  51. package/esm2020/services/translation-provider.mjs +34 -0
  52. package/esm2020/services/translator.mjs +63 -0
  53. package/esm2020/services/user-manager.mjs +27 -0
  54. package/esm2020/socket-controllers/progress.controller.mjs +52 -0
  55. package/esm2020/socket-controllers/terminal.controller.mjs +48 -0
  56. package/esm2020/socket-controllers/terminal.mjs +85 -0
  57. package/esm2020/socket-middlewares/compression.middleware.mjs +14 -0
  58. package/esm2020/static.mjs +23 -0
  59. package/esm2020/utilities/decorators.mjs +52 -0
  60. package/esm2020/utilities/di-container.mjs +83 -0
  61. package/esm2020/utilities/empty-job.mjs +13 -0
  62. package/esm2020/utilities/lazy-asset-generator.mjs +35 -0
  63. package/esm2020/utilities/mongoose.mjs +216 -0
  64. package/esm2020/utils.mjs +693 -0
  65. package/esm2020/validators.mjs +46 -0
  66. package/fesm2015/{stemy-backend.js → stemy-backend.mjs} +1923 -2220
  67. package/fesm2015/stemy-backend.mjs.map +1 -0
  68. package/fesm2020/stemy-backend.mjs +4202 -0
  69. package/fesm2020/stemy-backend.mjs.map +1 -0
  70. package/{stemy-backend.d.ts → index.d.ts} +1 -0
  71. package/package.json +36 -23
  72. package/public_api.d.ts +3 -2
  73. package/rest-controllers/terminal-styles.d.ts +2 -0
  74. package/rest-controllers/terminal.controller.d.ts +10 -0
  75. package/services/asset-processor.d.ts +0 -3
  76. package/services/assets.d.ts +1 -0
  77. package/services/configuration.d.ts +2 -1
  78. package/services/entities/asset.d.ts +1 -0
  79. package/services/entities/temp-asset.d.ts +1 -0
  80. package/services/fixtures.d.ts +2 -2
  81. package/services/terminal-manager.d.ts +15 -0
  82. package/socket-controllers/terminal.controller.d.ts +13 -0
  83. package/socket-controllers/terminal.d.ts +20 -0
  84. package/utils.d.ts +7 -1
  85. package/bundles/stemy-backend.umd.js +0 -7081
  86. package/bundles/stemy-backend.umd.js.map +0 -1
  87. package/esm2015/common-types.js +0 -19
  88. package/esm2015/public_api.js +0 -359
  89. package/esm2015/requests/asset-image-params.js +0 -70
  90. package/esm2015/rest-controllers/assets.controller.js +0 -180
  91. package/esm2015/rest-controllers/auth.controller.js +0 -76
  92. package/esm2015/rest-controllers/gallery.controller.js +0 -37
  93. package/esm2015/rest-controllers/progresses.controller.js +0 -57
  94. package/esm2015/rest-middlewares/container.middleware.js +0 -32
  95. package/esm2015/rest-middlewares/error-handler.middleware.js +0 -99
  96. package/esm2015/rest-middlewares/language.middleware.js +0 -28
  97. package/esm2015/rest-middlewares/request-ended.middleware.js +0 -33
  98. package/esm2015/rest-middlewares/request-started.middleware.js +0 -32
  99. package/esm2015/rest-openapi.js +0 -44
  100. package/esm2015/services/asset-processor.js +0 -129
  101. package/esm2015/services/asset-resolver.js +0 -53
  102. package/esm2015/services/assets.js +0 -181
  103. package/esm2015/services/backend-provider.js +0 -32
  104. package/esm2015/services/cache-processor.js +0 -34
  105. package/esm2015/services/cache.js +0 -93
  106. package/esm2015/services/configuration.js +0 -69
  107. package/esm2015/services/endpoint-provider.js +0 -29
  108. package/esm2015/services/entities/asset.js +0 -60
  109. package/esm2015/services/entities/base-entity.js +0 -37
  110. package/esm2015/services/entities/lazy-asset.js +0 -90
  111. package/esm2015/services/entities/progress.js +0 -213
  112. package/esm2015/services/entities/temp-asset.js +0 -64
  113. package/esm2015/services/fixtures.js +0 -45
  114. package/esm2015/services/gallery-cache.js +0 -36
  115. package/esm2015/services/gallery-image.js +0 -48
  116. package/esm2015/services/gallery.js +0 -138
  117. package/esm2015/services/id-generator.js +0 -63
  118. package/esm2015/services/job-manager.js +0 -221
  119. package/esm2015/services/lazy-assets.js +0 -83
  120. package/esm2015/services/logger.js +0 -31
  121. package/esm2015/services/mail-sender.js +0 -58
  122. package/esm2015/services/memory-cache.js +0 -84
  123. package/esm2015/services/mongo-connector.js +0 -58
  124. package/esm2015/services/open-api.js +0 -140
  125. package/esm2015/services/progresses.js +0 -118
  126. package/esm2015/services/template-renderer.js +0 -89
  127. package/esm2015/services/token-generator.js +0 -55
  128. package/esm2015/services/translation-provider.js +0 -54
  129. package/esm2015/services/translator.js +0 -84
  130. package/esm2015/services/user-manager.js +0 -47
  131. package/esm2015/socket-controllers/progress.controller.js +0 -82
  132. package/esm2015/socket-middlewares/compression.middleware.js +0 -19
  133. package/esm2015/static.js +0 -33
  134. package/esm2015/utilities/decorators.js +0 -54
  135. package/esm2015/utilities/di-container.js +0 -84
  136. package/esm2015/utilities/empty-job.js +0 -29
  137. package/esm2015/utilities/lazy-asset-generator.js +0 -46
  138. package/esm2015/utilities/mongoose.js +0 -225
  139. package/esm2015/utils.js +0 -672
  140. package/esm2015/validators.js +0 -51
  141. package/fesm2015/stemy-backend.js.map +0 -1
  142. package/rest-openapi.d.ts +0 -3
  143. package/stemy-backend.metadata.json +0 -1
  144. /package/{esm2015/stemy-backend.js → esm2020/stemy-backend.mjs} +0 -0
  145. /package/{esm2015/utilities/base-doc.js → esm2020/utilities/base-doc.mjs} +0 -0
  146. /package/{esm2015/utilities/tree.js → esm2020/utilities/tree.mjs} +0 -0
@@ -0,0 +1,216 @@
1
+ import { model, Types } from "mongoose";
2
+ import { getValue as getMongoValue, setValue as setMongoValue } from "mongoose/lib/utils";
3
+ import { BadRequestError, createParamDecorator, HttpError } from "routing-controllers";
4
+ import { diContainers, isArray, isFunction, isObject, isString, valueToPromise } from "../utils";
5
+ const pluginsKey = "typegoose:plugins";
6
+ /**
7
+ * A mongoose/typegoose plugin to inject services from the main di container to a schema as virtuals
8
+ * @param schema
9
+ * @param services
10
+ */
11
+ export function injectServices(schema, services) {
12
+ const serviceMap = {};
13
+ if (!isObject(services)) {
14
+ throw new Error(`services object should be defined to inject services to schema!`);
15
+ }
16
+ Object.keys(services).forEach(prop => {
17
+ schema
18
+ .virtual(prop)
19
+ .get(() => {
20
+ const diContainer = diContainers.appContainer;
21
+ serviceMap[prop] = serviceMap[prop] || (!diContainer ? {} : diContainer.resolve(services[prop]));
22
+ return serviceMap[prop];
23
+ });
24
+ });
25
+ }
26
+ /**
27
+ * Decorates a property to inject a service with the help of the injectServices mongoose/typegoose plugin
28
+ * @param token optional InjectionToken to use
29
+ * @return PropertyDecorator
30
+ */
31
+ export function service(token) {
32
+ return (target, propertyKey) => {
33
+ const propertyType = Reflect.getOwnMetadata("design:type", target, propertyKey);
34
+ const plugins = Array.from(Reflect.getMetadata(pluginsKey, target.constructor) ?? []);
35
+ let plugin = plugins.find(t => t.mongoosePlugin === injectServices);
36
+ if (!plugin) {
37
+ plugin = { mongoosePlugin: injectServices, options: {} };
38
+ plugins.push(plugin);
39
+ }
40
+ plugin.options = Object.assign(plugin.options || {}, { [propertyKey]: token ?? propertyType });
41
+ Reflect.defineMetadata(pluginsKey, plugins, target.constructor);
42
+ };
43
+ }
44
+ /**
45
+ * Paginate using a typegoose model using a simple where query and pagination params
46
+ * @param model Typegoose model
47
+ * @param where Simple query to filter the results
48
+ * @param params Pagination params
49
+ */
50
+ export function paginate(model, where, params) {
51
+ return model.countDocuments(where).then(count => {
52
+ let query = model.find(where);
53
+ if (isString(params.sort)) {
54
+ query = query.sort(params.sort);
55
+ }
56
+ if (isArray(params.populate)) {
57
+ params.populate.forEach(field => {
58
+ query = query.populate(field);
59
+ });
60
+ }
61
+ return (params.limit > 0 ? query.skip(params.page * params.limit).limit(params.limit) : query).then(items => {
62
+ const meta = { total: count };
63
+ return { count, items, meta };
64
+ });
65
+ });
66
+ }
67
+ export function lookupStages(from, localField, as = null, foreignField = "_id", shouldUnwind = true) {
68
+ as = as || localField.replace("Id", "");
69
+ const stages = [
70
+ {
71
+ $lookup: {
72
+ from,
73
+ localField,
74
+ foreignField,
75
+ as
76
+ }
77
+ },
78
+ {
79
+ $unwind: {
80
+ path: `$${as}`,
81
+ preserveNullAndEmptyArrays: true
82
+ }
83
+ }
84
+ ];
85
+ if (!shouldUnwind) {
86
+ stages.splice(1, 1);
87
+ }
88
+ return stages;
89
+ }
90
+ export function letsLookupStage(from, pipeline, as = null, letFields = null) {
91
+ as = as || from;
92
+ letFields = letFields || { id: "$_id" };
93
+ return {
94
+ $lookup: {
95
+ from,
96
+ let: letFields,
97
+ pipeline,
98
+ as
99
+ }
100
+ };
101
+ }
102
+ export function matchStage(match) {
103
+ return { $match: match };
104
+ }
105
+ export function matchField(field, filter, when) {
106
+ return { field, filter, when };
107
+ }
108
+ export function matchFieldStages(...fields) {
109
+ const match = {};
110
+ fields.forEach(field => {
111
+ if (field.when) {
112
+ match[field.field] = field.filter;
113
+ }
114
+ });
115
+ return Object.keys(match).length > 0 ? [matchStage(match)] : [];
116
+ }
117
+ export function projectStage(fields) {
118
+ return { $project: fields };
119
+ }
120
+ export function unwindStage(fieldOrOpts) {
121
+ return { $unwind: fieldOrOpts };
122
+ }
123
+ export function hydratePopulated(modelType, json) {
124
+ let object = modelType.hydrate(json);
125
+ for (const [path, obj] of Object.entries(modelType.schema.obj)) {
126
+ let { ref, type } = obj;
127
+ if (Array.isArray(type) && type.length > 0) {
128
+ ref = type[0].ref;
129
+ }
130
+ if (!ref)
131
+ continue;
132
+ const value = getMongoValue(path, json);
133
+ const hydrateVal = val => {
134
+ if (val == null || val instanceof Types.ObjectId)
135
+ return val;
136
+ return hydratePopulated(model(ref), val);
137
+ };
138
+ if (Array.isArray(value)) {
139
+ setMongoValue(path, value.map(hydrateVal), object);
140
+ continue;
141
+ }
142
+ setMongoValue(path, hydrateVal(value), object);
143
+ }
144
+ return object;
145
+ }
146
+ export async function paginateAggregations(model, aggregations, params, metaProjection = {}) {
147
+ const sortField = !isString(params.sort) || !params.sort ? null : (params.sort.startsWith("-") ? params.sort.substr(1) : params.sort);
148
+ const sortAggregation = !sortField ? [] : [{
149
+ $sort: { [sortField]: sortField == params.sort ? 1 : -1 }
150
+ }];
151
+ const result = await model.aggregate([
152
+ ...aggregations,
153
+ ...sortAggregation,
154
+ {
155
+ $group: {
156
+ _id: "results",
157
+ result: { $push: "$$CURRENT" }
158
+ }
159
+ },
160
+ {
161
+ $project: {
162
+ _id: 0,
163
+ items: params.limit > 0 ? { $slice: ["$result", params.page * params.limit, params.limit] } : "$result",
164
+ count: { $size: "$result" },
165
+ meta: {
166
+ total: { $size: "$result" },
167
+ ...metaProjection
168
+ }
169
+ }
170
+ }
171
+ ]);
172
+ const pagination = result[0];
173
+ if (!pagination) {
174
+ return { items: [], count: 0, meta: { total: 0 } };
175
+ }
176
+ pagination.items = pagination.items.map(i => hydratePopulated(model, i));
177
+ return pagination;
178
+ }
179
+ export function ResolveEntity(model, extraCheck) {
180
+ const modelName = model.modelName;
181
+ const paramName = modelName.toLowerCase();
182
+ return createParamDecorator({
183
+ required: false,
184
+ value: async (action) => {
185
+ const req = action.request;
186
+ const token = req.header(`x-${paramName}-token`);
187
+ const id = req.params[`${paramName}Id`];
188
+ if (!id && !token) {
189
+ throw new BadRequestError(`${modelName} id or token should be defined!`);
190
+ }
191
+ const query = !token
192
+ ? model.findById(id)
193
+ : model.findOne({ token });
194
+ let doc = null;
195
+ if (isFunction(extraCheck)) {
196
+ try {
197
+ doc = await valueToPromise(extraCheck(query, action));
198
+ }
199
+ catch (e) {
200
+ throw new BadRequestError(`${modelName} check error: ${e.message || e}`);
201
+ }
202
+ }
203
+ else {
204
+ doc = await query;
205
+ }
206
+ if (!doc) {
207
+ throw new HttpError(404, !token
208
+ ? `${modelName} could not be found with id: ${id}`
209
+ : `${modelName} could not be found with token: ${token}`);
210
+ }
211
+ action.request[paramName] = doc;
212
+ return doc;
213
+ }
214
+ });
215
+ }
216
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9uZ29vc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdXRpbGl0aWVzL21vbmdvb3NlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBd0IsS0FBSyxFQUF1QyxLQUFLLEVBQUMsTUFBTSxVQUFVLENBQUM7QUFDbEcsT0FBTyxFQUFDLFFBQVEsSUFBSSxhQUFhLEVBQUUsUUFBUSxJQUFJLGFBQWEsRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBRXhGLE9BQU8sRUFBUyxlQUFlLEVBQUUsb0JBQW9CLEVBQUUsU0FBUyxFQUFDLE1BQU0scUJBQXFCLENBQUM7QUFZN0YsT0FBTyxFQUFDLFlBQVksRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsY0FBYyxFQUFDLE1BQU0sVUFBVSxDQUFDO0FBRS9GLE1BQU0sVUFBVSxHQUFHLG1CQUFtQixDQUFDO0FBT3ZDOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsY0FBYyxDQUFDLE1BQW1CLEVBQUUsUUFBa0Q7SUFDbEcsTUFBTSxVQUFVLEdBQTRCLEVBQUUsQ0FBQztJQUMvQyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFO1FBQ3JCLE1BQU0sSUFBSSxLQUFLLENBQUMsaUVBQWlFLENBQUMsQ0FBQTtLQUNyRjtJQUNELE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFO1FBQ2pDLE1BQU07YUFDRCxPQUFPLENBQUMsSUFBSSxDQUFDO2FBQ2IsR0FBRyxDQUFDLEdBQUcsRUFBRTtZQUNOLE1BQU0sV0FBVyxHQUFHLFlBQVksQ0FBQyxZQUFZLENBQUM7WUFDOUMsVUFBVSxDQUFDLElBQUksQ0FBQyxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNqRyxPQUFPLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM1QixDQUFDLENBQUMsQ0FBQztJQUNYLENBQUMsQ0FBQyxDQUFDO0FBQ1AsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsT0FBTyxDQUFDLEtBQTJCO0lBQy9DLE9BQU8sQ0FBQyxNQUFXLEVBQUUsV0FBbUIsRUFBUSxFQUFFO1FBQzlDLE1BQU0sWUFBWSxHQUFHLE9BQU8sQ0FBQyxjQUFjLENBQUMsYUFBYSxFQUFFLE1BQU0sRUFBRSxXQUFXLENBQUMsQ0FBQztRQUNoRixNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLENBQXlCLENBQUM7UUFDOUcsSUFBSSxNQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxjQUFjLEtBQUssY0FBYyxDQUFDLENBQUM7UUFDcEUsSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNULE1BQU0sR0FBRyxFQUFFLGNBQWMsRUFBRSxjQUFjLEVBQUUsT0FBTyxFQUFFLEVBQUUsRUFBRSxDQUFDO1lBQ3pELE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7U0FDeEI7UUFDRCxNQUFNLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sSUFBSSxFQUFFLEVBQUUsRUFBQyxDQUFDLFdBQVcsQ0FBQyxFQUFFLEtBQUssSUFBSSxZQUFZLEVBQUMsQ0FBQyxDQUFDO1FBQzdGLE9BQU8sQ0FBQyxjQUFjLENBQUMsVUFBVSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDcEUsQ0FBQyxDQUFDO0FBQ04sQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLFFBQVEsQ0FBMkMsS0FBeUIsRUFBRSxLQUFtQyxFQUFFLE1BQXlCO0lBQ3hKLE9BQU8sS0FBSyxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUU7UUFDNUMsSUFBSSxLQUFLLEdBQW9CLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDL0MsSUFBSSxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQ3ZCLEtBQUssR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUNuQztRQUNELElBQUksT0FBTyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsRUFBRTtZQUMxQixNQUFNLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRTtnQkFDNUIsS0FBSyxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDbEMsQ0FBQyxDQUFDLENBQUM7U0FDTjtRQUNELE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDeEcsTUFBTSxJQUFJLEdBQUcsRUFBQyxLQUFLLEVBQUUsS0FBSyxFQUFDLENBQUM7WUFDNUIsT0FBTyxFQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFDLENBQUM7UUFDaEMsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDLENBQUMsQ0FBQztBQUNQLENBQUM7QUFFRCxNQUFNLFVBQVUsWUFBWSxDQUFDLElBQVksRUFBRSxVQUFrQixFQUFFLEtBQWEsSUFBSSxFQUFFLGVBQXVCLEtBQUssRUFBRSxlQUF3QixJQUFJO0lBQ3hJLEVBQUUsR0FBRyxFQUFFLElBQUksVUFBVSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDeEMsTUFBTSxNQUFNLEdBQWlEO1FBQ3pEO1lBQ0ksT0FBTyxFQUFFO2dCQUNMLElBQUk7Z0JBQ0osVUFBVTtnQkFDVixZQUFZO2dCQUNaLEVBQUU7YUFDTDtTQUNKO1FBQ0Q7WUFDSSxPQUFPLEVBQUU7Z0JBQ0wsSUFBSSxFQUFFLElBQUksRUFBRSxFQUFFO2dCQUNkLDBCQUEwQixFQUFFLElBQUk7YUFDbkM7U0FDSjtLQUNKLENBQUM7SUFDRixJQUFJLENBQUMsWUFBWSxFQUFFO1FBQ2YsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7S0FDdkI7SUFDRCxPQUFPLE1BQU0sQ0FBQztBQUNsQixDQUFDO0FBRUQsTUFBTSxVQUFVLGVBQWUsQ0FBQyxJQUFZLEVBQUUsUUFBa0csRUFBRSxLQUFhLElBQUksRUFBRSxZQUFpQixJQUFJO0lBQ3RMLEVBQUUsR0FBRyxFQUFFLElBQUksSUFBSSxDQUFDO0lBQ2hCLFNBQVMsR0FBRyxTQUFTLElBQUksRUFBQyxFQUFFLEVBQUUsTUFBTSxFQUFDLENBQUM7SUFDdEMsT0FBTztRQUNILE9BQU8sRUFBRTtZQUNMLElBQUk7WUFDSixHQUFHLEVBQUUsU0FBUztZQUNkLFFBQVE7WUFDUixFQUFFO1NBQ0w7S0FDSixDQUFDO0FBQ04sQ0FBQztBQUVELE1BQU0sVUFBVSxVQUFVLENBQUMsS0FBdUI7SUFDOUMsT0FBTyxFQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUMsQ0FBQztBQUMzQixDQUFDO0FBRUQsTUFBTSxVQUFVLFVBQVUsQ0FBQyxLQUFhLEVBQUUsTUFBVyxFQUFFLElBQWE7SUFDaEUsT0FBTyxFQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFDLENBQUM7QUFDakMsQ0FBQztBQUVELE1BQU0sVUFBVSxnQkFBZ0IsQ0FBQyxHQUFHLE1BQXFCO0lBQ3JELE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQztJQUNqQixNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFO1FBQ25CLElBQUksS0FBSyxDQUFDLElBQUksRUFBRTtZQUNaLEtBQUssQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQztTQUNyQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0gsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztBQUNwRSxDQUFDO0FBRUQsTUFBTSxVQUFVLFlBQVksQ0FBQyxNQUF1QjtJQUNoRCxPQUFPLEVBQUMsUUFBUSxFQUFFLE1BQU0sRUFBQyxDQUFDO0FBQzlCLENBQUM7QUFFRCxNQUFNLFVBQVUsV0FBVyxDQUFDLFdBQW9DO0lBQzVELE9BQU8sRUFBQyxPQUFPLEVBQUUsV0FBVyxFQUFDLENBQUM7QUFDbEMsQ0FBQztBQUVELE1BQU0sVUFBVSxnQkFBZ0IsQ0FBcUIsU0FBbUIsRUFBRSxJQUFTO0lBQy9FLElBQUksTUFBTSxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7SUFFckMsS0FBSyxNQUFNLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRTtRQUM1RCxJQUFJLEVBQUMsR0FBRyxFQUFFLElBQUksRUFBQyxHQUFHLEdBQVUsQ0FBQztRQUM3QixJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7WUFDeEMsR0FBRyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7U0FDckI7UUFDRCxJQUFJLENBQUMsR0FBRztZQUFFLFNBQVM7UUFDbkIsTUFBTSxLQUFLLEdBQUcsYUFBYSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztRQUN4QyxNQUFNLFVBQVUsR0FBRyxHQUFHLENBQUMsRUFBRTtZQUNyQixJQUFJLEdBQUcsSUFBSSxJQUFJLElBQUksR0FBRyxZQUFZLEtBQUssQ0FBQyxRQUFRO2dCQUFFLE9BQU8sR0FBRyxDQUFDO1lBQzdELE9BQU8sZ0JBQWdCLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBUSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3BELENBQUMsQ0FBQztRQUNGLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUN0QixhQUFhLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDbkQsU0FBUztTQUNaO1FBQ0QsYUFBYSxDQUFDLElBQUksRUFBRSxVQUFVLENBQUMsS0FBSyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7S0FDbEQ7SUFFRCxPQUFPLE1BQU0sQ0FBQztBQUVsQixDQUFDO0FBRUQsTUFBTSxDQUFDLEtBQUssVUFBVSxvQkFBb0IsQ0FBMkMsS0FBeUIsRUFBRSxZQUE2QixFQUFFLE1BQXlCLEVBQUUsaUJBQXNCLEVBQUU7SUFDOUwsTUFBTSxTQUFTLEdBQUcsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3RJLE1BQU0sZUFBZSxHQUF5QixDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzdELEtBQUssRUFBRSxFQUFDLENBQUMsU0FBUyxDQUFDLEVBQUUsU0FBUyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUM7U0FDMUQsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxNQUFNLEdBQUcsTUFBTSxLQUFLLENBQUMsU0FBUyxDQUFDO1FBQ2pDLEdBQUcsWUFBWTtRQUNmLEdBQUcsZUFBZTtRQUNsQjtZQUNJLE1BQU0sRUFBRTtnQkFDSixHQUFHLEVBQUUsU0FBUztnQkFDZCxNQUFNLEVBQUUsRUFBQyxLQUFLLEVBQUUsV0FBVyxFQUFDO2FBQy9CO1NBQ0o7UUFDRDtZQUNJLFFBQVEsRUFBRTtnQkFDTixHQUFHLEVBQUUsQ0FBQztnQkFDTixLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUMsTUFBTSxFQUFFLENBQUMsU0FBUyxFQUFFLE1BQU0sQ0FBQyxJQUFJLEdBQUcsTUFBTSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUztnQkFDckcsS0FBSyxFQUFFLEVBQUMsS0FBSyxFQUFFLFNBQVMsRUFBQztnQkFDekIsSUFBSSxFQUFFO29CQUNGLEtBQUssRUFBRSxFQUFDLEtBQUssRUFBRSxTQUFTLEVBQUM7b0JBQ3pCLEdBQUcsY0FBYztpQkFDcEI7YUFDSjtTQUNKO0tBQ0osQ0FBQyxDQUFDO0lBQ0gsTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBcUMsQ0FBQztJQUNqRSxJQUFJLENBQUMsVUFBVSxFQUFFO1FBQ2IsT0FBTyxFQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFBQyxLQUFLLEVBQUUsQ0FBQyxFQUFDLEVBQUMsQ0FBQztLQUNsRDtJQUNELFVBQVUsQ0FBQyxLQUFLLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFRLENBQUMsQ0FBQztJQUNoRixPQUFPLFVBQVUsQ0FBQztBQUN0QixDQUFDO0FBRUQsTUFBTSxVQUFVLGFBQWEsQ0FBMkMsS0FBeUIsRUFBRSxVQUE2RjtJQUM1TCxNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDO0lBQ2xDLE1BQU0sU0FBUyxHQUFHLFNBQVMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUMxQyxPQUFPLG9CQUFvQixDQUFDO1FBQ3hCLFFBQVEsRUFBRSxLQUFLO1FBQ2YsS0FBSyxFQUFFLEtBQUssRUFBQyxNQUFNLEVBQUMsRUFBRTtZQUNsQixNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsT0FBbUIsQ0FBQztZQUN2QyxNQUFNLEtBQUssR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssU0FBUyxRQUFRLENBQUMsQ0FBQztZQUNqRCxNQUFNLEVBQUUsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsU0FBUyxJQUFJLENBQVcsQ0FBQztZQUNsRCxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFO2dCQUNmLE1BQU0sSUFBSSxlQUFlLENBQUMsR0FBRyxTQUFTLGlDQUFpQyxDQUFDLENBQUM7YUFDNUU7WUFDRCxNQUFNLEtBQUssR0FBRyxDQUFDLEtBQUs7Z0JBQ2hCLENBQUMsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztnQkFDcEIsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBQyxLQUFLLEVBQVEsQ0FBQyxDQUFDO1lBQ3BDLElBQUksR0FBRyxHQUFhLElBQUksQ0FBQztZQUN6QixJQUFJLFVBQVUsQ0FBQyxVQUFVLENBQUMsRUFBRTtnQkFDeEIsSUFBSTtvQkFDQSxHQUFHLEdBQUcsTUFBTSxjQUFjLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO2lCQUN6RDtnQkFBQyxPQUFPLENBQUMsRUFBRTtvQkFDUixNQUFNLElBQUksZUFBZSxDQUFDLEdBQUcsU0FBUyxpQkFBaUIsQ0FBQyxDQUFDLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2lCQUM1RTthQUNKO2lCQUFNO2dCQUNILEdBQUcsR0FBRyxNQUFNLEtBQUssQ0FBQzthQUNyQjtZQUNELElBQUksQ0FBQyxHQUFHLEVBQUU7Z0JBQ04sTUFBTSxJQUFJLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxLQUFLO29CQUMzQixDQUFDLENBQUMsR0FBRyxTQUFTLGdDQUFnQyxFQUFFLEVBQUU7b0JBQ2xELENBQUMsQ0FBQyxHQUFHLFNBQVMsbUNBQW1DLEtBQUssRUFBRSxDQUFDLENBQUM7YUFDakU7WUFDRCxNQUFNLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztZQUNoQyxPQUFPLEdBQUcsQ0FBQztRQUNmLENBQUM7S0FDSixDQUFDLENBQUM7QUFDUCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtEb2N1bWVudCwgRmlsdGVyUXVlcnksIG1vZGVsLCBNb2RlbCwgUGlwZWxpbmVTdGFnZSwgUXVlcnksIFNjaGVtYSwgVHlwZXN9IGZyb20gXCJtb25nb29zZVwiO1xyXG5pbXBvcnQge2dldFZhbHVlIGFzIGdldE1vbmdvVmFsdWUsIHNldFZhbHVlIGFzIHNldE1vbmdvVmFsdWV9IGZyb20gXCJtb25nb29zZS9saWIvdXRpbHNcIjtcclxuaW1wb3J0IHtEb2N1bWVudFR5cGUsIFJldHVybk1vZGVsVHlwZX0gZnJvbSBcIkB0eXBlZ29vc2UvdHlwZWdvb3NlXCI7XHJcbmltcG9ydCB7QWN0aW9uLCBCYWRSZXF1ZXN0RXJyb3IsIGNyZWF0ZVBhcmFtRGVjb3JhdG9yLCBIdHRwRXJyb3J9IGZyb20gXCJyb3V0aW5nLWNvbnRyb2xsZXJzXCI7XHJcbmltcG9ydCB7SW5qZWN0aW9uVG9rZW59IGZyb20gXCJ0c3lyaW5nZVwiO1xyXG5pbXBvcnQge1xyXG4gICAgSU1hdGNoRmllbGQsXHJcbiAgICBJbmZlckdlbmVyaWMsXHJcbiAgICBJUGFnaW5hdGlvbkJhc2UsXHJcbiAgICBJUGFnaW5hdGlvblBhcmFtcyxcclxuICAgIElQcm9qZWN0T3B0aW9ucyxcclxuICAgIElSZXF1ZXN0LFxyXG4gICAgSVVud2luZE9wdGlvbnMsXHJcbiAgICBUeXBlXHJcbn0gZnJvbSBcIi4uL2NvbW1vbi10eXBlc1wiO1xyXG5pbXBvcnQge2RpQ29udGFpbmVycywgaXNBcnJheSwgaXNGdW5jdGlvbiwgaXNPYmplY3QsIGlzU3RyaW5nLCB2YWx1ZVRvUHJvbWlzZX0gZnJvbSBcIi4uL3V0aWxzXCI7XHJcblxyXG5jb25zdCBwbHVnaW5zS2V5ID0gXCJ0eXBlZ29vc2U6cGx1Z2luc1wiO1xyXG5cclxuaW50ZXJmYWNlIElQbHVnaW5XaXRoT3B0aW9ucyB7XHJcbiAgICBtb25nb29zZVBsdWdpbjogRnVuY3Rpb247XHJcbiAgICBvcHRpb25zOiBhbnk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBBIG1vbmdvb3NlL3R5cGVnb29zZSBwbHVnaW4gdG8gaW5qZWN0IHNlcnZpY2VzIGZyb20gdGhlIG1haW4gZGkgY29udGFpbmVyIHRvIGEgc2NoZW1hIGFzIHZpcnR1YWxzXHJcbiAqIEBwYXJhbSBzY2hlbWFcclxuICogQHBhcmFtIHNlcnZpY2VzXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gaW5qZWN0U2VydmljZXMoc2NoZW1hOiBTY2hlbWE8YW55Piwgc2VydmljZXM/OiB7IFtwcm9wOiBzdHJpbmddOiBJbmplY3Rpb25Ub2tlbjxhbnk+IH0pOiB2b2lkIHtcclxuICAgIGNvbnN0IHNlcnZpY2VNYXA6IHsgW3Byb3A6IHN0cmluZ106IGFueSB9ID0ge307XHJcbiAgICBpZiAoIWlzT2JqZWN0KHNlcnZpY2VzKSkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgc2VydmljZXMgb2JqZWN0IHNob3VsZCBiZSBkZWZpbmVkIHRvIGluamVjdCBzZXJ2aWNlcyB0byBzY2hlbWEhYClcclxuICAgIH1cclxuICAgIE9iamVjdC5rZXlzKHNlcnZpY2VzKS5mb3JFYWNoKHByb3AgPT4ge1xyXG4gICAgICAgIHNjaGVtYVxyXG4gICAgICAgICAgICAudmlydHVhbChwcm9wKVxyXG4gICAgICAgICAgICAuZ2V0KCgpID0+IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGRpQ29udGFpbmVyID0gZGlDb250YWluZXJzLmFwcENvbnRhaW5lcjtcclxuICAgICAgICAgICAgICAgIHNlcnZpY2VNYXBbcHJvcF0gPSBzZXJ2aWNlTWFwW3Byb3BdIHx8ICghZGlDb250YWluZXIgPyB7fSA6IGRpQ29udGFpbmVyLnJlc29sdmUoc2VydmljZXNbcHJvcF0pKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBzZXJ2aWNlTWFwW3Byb3BdO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgIH0pO1xyXG59XHJcblxyXG4vKipcclxuICogRGVjb3JhdGVzIGEgcHJvcGVydHkgdG8gaW5qZWN0IGEgc2VydmljZSB3aXRoIHRoZSBoZWxwIG9mIHRoZSBpbmplY3RTZXJ2aWNlcyBtb25nb29zZS90eXBlZ29vc2UgcGx1Z2luXHJcbiAqIEBwYXJhbSB0b2tlbiBvcHRpb25hbCBJbmplY3Rpb25Ub2tlbiB0byB1c2VcclxuICogQHJldHVybiBQcm9wZXJ0eURlY29yYXRvclxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIHNlcnZpY2UodG9rZW4/OiBJbmplY3Rpb25Ub2tlbjxhbnk+KTogUHJvcGVydHlEZWNvcmF0b3Ige1xyXG4gICAgcmV0dXJuICh0YXJnZXQ6IGFueSwgcHJvcGVydHlLZXk6IHN0cmluZyk6IHZvaWQgPT4ge1xyXG4gICAgICAgIGNvbnN0IHByb3BlcnR5VHlwZSA9IFJlZmxlY3QuZ2V0T3duTWV0YWRhdGEoXCJkZXNpZ246dHlwZVwiLCB0YXJnZXQsIHByb3BlcnR5S2V5KTtcclxuICAgICAgICBjb25zdCBwbHVnaW5zID0gQXJyYXkuZnJvbShSZWZsZWN0LmdldE1ldGFkYXRhKHBsdWdpbnNLZXksIHRhcmdldC5jb25zdHJ1Y3RvcikgPz8gW10pIGFzIElQbHVnaW5XaXRoT3B0aW9uc1tdO1xyXG4gICAgICAgIGxldCBwbHVnaW4gPSBwbHVnaW5zLmZpbmQodCA9PiB0Lm1vbmdvb3NlUGx1Z2luID09PSBpbmplY3RTZXJ2aWNlcyk7XHJcbiAgICAgICAgaWYgKCFwbHVnaW4pIHtcclxuICAgICAgICAgICAgcGx1Z2luID0geyBtb25nb29zZVBsdWdpbjogaW5qZWN0U2VydmljZXMsIG9wdGlvbnM6IHt9IH07XHJcbiAgICAgICAgICAgIHBsdWdpbnMucHVzaChwbHVnaW4pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBwbHVnaW4ub3B0aW9ucyA9IE9iamVjdC5hc3NpZ24ocGx1Z2luLm9wdGlvbnMgfHwge30sIHtbcHJvcGVydHlLZXldOiB0b2tlbiA/PyBwcm9wZXJ0eVR5cGV9KTtcclxuICAgICAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKHBsdWdpbnNLZXksIHBsdWdpbnMsIHRhcmdldC5jb25zdHJ1Y3Rvcik7XHJcbiAgICB9O1xyXG59XHJcblxyXG4vKipcclxuICogUGFnaW5hdGUgdXNpbmcgYSB0eXBlZ29vc2UgbW9kZWwgdXNpbmcgYSBzaW1wbGUgd2hlcmUgcXVlcnkgYW5kIHBhZ2luYXRpb24gcGFyYW1zXHJcbiAqIEBwYXJhbSBtb2RlbCBUeXBlZ29vc2UgbW9kZWxcclxuICogQHBhcmFtIHdoZXJlIFNpbXBsZSBxdWVyeSB0byBmaWx0ZXIgdGhlIHJlc3VsdHNcclxuICogQHBhcmFtIHBhcmFtcyBQYWdpbmF0aW9uIHBhcmFtc1xyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIHBhZ2luYXRlPFQgZXh0ZW5kcyBUeXBlPGFueT4sIFUgPSBJbmZlckdlbmVyaWM8VD4+KG1vZGVsOiBSZXR1cm5Nb2RlbFR5cGU8VD4sIHdoZXJlOiBGaWx0ZXJRdWVyeTxEb2N1bWVudFR5cGU8VT4+LCBwYXJhbXM6IElQYWdpbmF0aW9uUGFyYW1zKTogUHJvbWlzZTxJUGFnaW5hdGlvbkJhc2U8RG9jdW1lbnRUeXBlPFU+Pj4ge1xyXG4gICAgcmV0dXJuIG1vZGVsLmNvdW50RG9jdW1lbnRzKHdoZXJlKS50aGVuKGNvdW50ID0+IHtcclxuICAgICAgICBsZXQgcXVlcnk6IFF1ZXJ5PGFueSwgYW55PiA9IG1vZGVsLmZpbmQod2hlcmUpO1xyXG4gICAgICAgIGlmIChpc1N0cmluZyhwYXJhbXMuc29ydCkpIHtcclxuICAgICAgICAgICAgcXVlcnkgPSBxdWVyeS5zb3J0KHBhcmFtcy5zb3J0KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGlzQXJyYXkocGFyYW1zLnBvcHVsYXRlKSkge1xyXG4gICAgICAgICAgICBwYXJhbXMucG9wdWxhdGUuZm9yRWFjaChmaWVsZCA9PiB7XHJcbiAgICAgICAgICAgICAgICBxdWVyeSA9IHF1ZXJ5LnBvcHVsYXRlKGZpZWxkKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiAocGFyYW1zLmxpbWl0ID4gMCA/IHF1ZXJ5LnNraXAocGFyYW1zLnBhZ2UgKiBwYXJhbXMubGltaXQpLmxpbWl0KHBhcmFtcy5saW1pdCkgOiBxdWVyeSkudGhlbihpdGVtcyA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IG1ldGEgPSB7dG90YWw6IGNvdW50fTtcclxuICAgICAgICAgICAgcmV0dXJuIHtjb3VudCwgaXRlbXMsIG1ldGF9O1xyXG4gICAgICAgIH0pO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBsb29rdXBTdGFnZXMoZnJvbTogc3RyaW5nLCBsb2NhbEZpZWxkOiBzdHJpbmcsIGFzOiBzdHJpbmcgPSBudWxsLCBmb3JlaWduRmllbGQ6IHN0cmluZyA9IFwiX2lkXCIsIHNob3VsZFVud2luZDogYm9vbGVhbiA9IHRydWUpOiBbUGlwZWxpbmVTdGFnZS5Mb29rdXAsIFBpcGVsaW5lU3RhZ2UuVW53aW5kXSB7XHJcbiAgICBhcyA9IGFzIHx8IGxvY2FsRmllbGQucmVwbGFjZShcIklkXCIsIFwiXCIpO1xyXG4gICAgY29uc3Qgc3RhZ2VzOiBbUGlwZWxpbmVTdGFnZS5Mb29rdXAsIFBpcGVsaW5lU3RhZ2UuVW53aW5kXSA9IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICAgICRsb29rdXA6IHtcclxuICAgICAgICAgICAgICAgIGZyb20sXHJcbiAgICAgICAgICAgICAgICBsb2NhbEZpZWxkLFxyXG4gICAgICAgICAgICAgICAgZm9yZWlnbkZpZWxkLFxyXG4gICAgICAgICAgICAgICAgYXNcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgICAkdW53aW5kOiB7XHJcbiAgICAgICAgICAgICAgICBwYXRoOiBgJCR7YXN9YCxcclxuICAgICAgICAgICAgICAgIHByZXNlcnZlTnVsbEFuZEVtcHR5QXJyYXlzOiB0cnVlXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICBdO1xyXG4gICAgaWYgKCFzaG91bGRVbndpbmQpIHtcclxuICAgICAgICBzdGFnZXMuc3BsaWNlKDEsIDEpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHN0YWdlcztcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGxldHNMb29rdXBTdGFnZShmcm9tOiBzdHJpbmcsIHBpcGVsaW5lOiBFeGNsdWRlPFBpcGVsaW5lU3RhZ2UsIFBpcGVsaW5lU3RhZ2UuTWVyZ2UgfCBQaXBlbGluZVN0YWdlLk91dCB8IFBpcGVsaW5lU3RhZ2UuU2VhcmNoPltdLCBhczogc3RyaW5nID0gbnVsbCwgbGV0RmllbGRzOiBhbnkgPSBudWxsKTogUGlwZWxpbmVTdGFnZS5Mb29rdXAge1xyXG4gICAgYXMgPSBhcyB8fCBmcm9tO1xyXG4gICAgbGV0RmllbGRzID0gbGV0RmllbGRzIHx8IHtpZDogXCIkX2lkXCJ9O1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICAkbG9va3VwOiB7XHJcbiAgICAgICAgICAgIGZyb20sXHJcbiAgICAgICAgICAgIGxldDogbGV0RmllbGRzLFxyXG4gICAgICAgICAgICBwaXBlbGluZSxcclxuICAgICAgICAgICAgYXNcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gbWF0Y2hTdGFnZShtYXRjaDogRmlsdGVyUXVlcnk8YW55Pik6IFBpcGVsaW5lU3RhZ2UuTWF0Y2gge1xyXG4gICAgcmV0dXJuIHskbWF0Y2g6IG1hdGNofTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIG1hdGNoRmllbGQoZmllbGQ6IHN0cmluZywgZmlsdGVyOiBhbnksIHdoZW46IGJvb2xlYW4pOiBJTWF0Y2hGaWVsZCB7XHJcbiAgICByZXR1cm4ge2ZpZWxkLCBmaWx0ZXIsIHdoZW59O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gbWF0Y2hGaWVsZFN0YWdlcyguLi5maWVsZHM6IElNYXRjaEZpZWxkW10pOiBSZWFkb25seUFycmF5PFBpcGVsaW5lU3RhZ2UuTWF0Y2g+IHtcclxuICAgIGNvbnN0IG1hdGNoID0ge307XHJcbiAgICBmaWVsZHMuZm9yRWFjaChmaWVsZCA9PiB7XHJcbiAgICAgICAgaWYgKGZpZWxkLndoZW4pIHtcclxuICAgICAgICAgICAgbWF0Y2hbZmllbGQuZmllbGRdID0gZmllbGQuZmlsdGVyO1xyXG4gICAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKG1hdGNoKS5sZW5ndGggPiAwID8gW21hdGNoU3RhZ2UobWF0Y2gpXSA6IFtdO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gcHJvamVjdFN0YWdlKGZpZWxkczogSVByb2plY3RPcHRpb25zKTogUGlwZWxpbmVTdGFnZS5Qcm9qZWN0IHtcclxuICAgIHJldHVybiB7JHByb2plY3Q6IGZpZWxkc307XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiB1bndpbmRTdGFnZShmaWVsZE9yT3B0czogc3RyaW5nIHwgSVVud2luZE9wdGlvbnMpOiBQaXBlbGluZVN0YWdlLlVud2luZCB7XHJcbiAgICByZXR1cm4geyR1bndpbmQ6IGZpZWxkT3JPcHRzfTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGh5ZHJhdGVQb3B1bGF0ZWQ8VCBleHRlbmRzIERvY3VtZW50Pihtb2RlbFR5cGU6IE1vZGVsPFQ+LCBqc29uOiBhbnkpOiBUIHtcclxuICAgIGxldCBvYmplY3QgPSBtb2RlbFR5cGUuaHlkcmF0ZShqc29uKTtcclxuXHJcbiAgICBmb3IgKGNvbnN0IFtwYXRoLCBvYmpdIG9mIE9iamVjdC5lbnRyaWVzKG1vZGVsVHlwZS5zY2hlbWEub2JqKSkge1xyXG4gICAgICAgIGxldCB7cmVmLCB0eXBlfSA9IG9iaiBhcyBhbnk7XHJcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodHlwZSkgJiYgdHlwZS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIHJlZiA9IHR5cGVbMF0ucmVmO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIXJlZikgY29udGludWU7XHJcbiAgICAgICAgY29uc3QgdmFsdWUgPSBnZXRNb25nb1ZhbHVlKHBhdGgsIGpzb24pO1xyXG4gICAgICAgIGNvbnN0IGh5ZHJhdGVWYWwgPSB2YWwgPT4ge1xyXG4gICAgICAgICAgICBpZiAodmFsID09IG51bGwgfHwgdmFsIGluc3RhbmNlb2YgVHlwZXMuT2JqZWN0SWQpIHJldHVybiB2YWw7XHJcbiAgICAgICAgICAgIHJldHVybiBoeWRyYXRlUG9wdWxhdGVkKG1vZGVsKHJlZikgYXMgYW55LCB2YWwpO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XHJcbiAgICAgICAgICAgIHNldE1vbmdvVmFsdWUocGF0aCwgdmFsdWUubWFwKGh5ZHJhdGVWYWwpLCBvYmplY3QpO1xyXG4gICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgc2V0TW9uZ29WYWx1ZShwYXRoLCBoeWRyYXRlVmFsKHZhbHVlKSwgb2JqZWN0KTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gb2JqZWN0O1xyXG5cclxufVxyXG5cclxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHBhZ2luYXRlQWdncmVnYXRpb25zPFQgZXh0ZW5kcyBUeXBlPGFueT4sIFUgPSBJbmZlckdlbmVyaWM8VD4+KG1vZGVsOiBSZXR1cm5Nb2RlbFR5cGU8VD4sIGFnZ3JlZ2F0aW9uczogUGlwZWxpbmVTdGFnZVtdLCBwYXJhbXM6IElQYWdpbmF0aW9uUGFyYW1zLCBtZXRhUHJvamVjdGlvbjogYW55ID0ge30pOiBQcm9taXNlPElQYWdpbmF0aW9uQmFzZTxEb2N1bWVudFR5cGU8VT4+PiB7XHJcbiAgICBjb25zdCBzb3J0RmllbGQgPSAhaXNTdHJpbmcocGFyYW1zLnNvcnQpIHx8ICFwYXJhbXMuc29ydCA/IG51bGwgOiAocGFyYW1zLnNvcnQuc3RhcnRzV2l0aChcIi1cIikgPyBwYXJhbXMuc29ydC5zdWJzdHIoMSkgOiBwYXJhbXMuc29ydCk7XHJcbiAgICBjb25zdCBzb3J0QWdncmVnYXRpb246IFBpcGVsaW5lU3RhZ2UuU29ydFtdID0gIXNvcnRGaWVsZCA/IFtdIDogW3tcclxuICAgICAgICAkc29ydDoge1tzb3J0RmllbGRdOiBzb3J0RmllbGQgPT0gcGFyYW1zLnNvcnQgPyAxIDogLTF9XHJcbiAgICB9XTtcclxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IG1vZGVsLmFnZ3JlZ2F0ZShbXHJcbiAgICAgICAgLi4uYWdncmVnYXRpb25zLFxyXG4gICAgICAgIC4uLnNvcnRBZ2dyZWdhdGlvbixcclxuICAgICAgICB7XHJcbiAgICAgICAgICAgICRncm91cDoge1xyXG4gICAgICAgICAgICAgICAgX2lkOiBcInJlc3VsdHNcIixcclxuICAgICAgICAgICAgICAgIHJlc3VsdDogeyRwdXNoOiBcIiQkQ1VSUkVOVFwifVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICAgICRwcm9qZWN0OiB7XHJcbiAgICAgICAgICAgICAgICBfaWQ6IDAsXHJcbiAgICAgICAgICAgICAgICBpdGVtczogcGFyYW1zLmxpbWl0ID4gMCA/IHskc2xpY2U6IFtcIiRyZXN1bHRcIiwgcGFyYW1zLnBhZ2UgKiBwYXJhbXMubGltaXQsIHBhcmFtcy5saW1pdF19IDogXCIkcmVzdWx0XCIsXHJcbiAgICAgICAgICAgICAgICBjb3VudDogeyRzaXplOiBcIiRyZXN1bHRcIn0sXHJcbiAgICAgICAgICAgICAgICBtZXRhOiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdG90YWw6IHskc2l6ZTogXCIkcmVzdWx0XCJ9LFxyXG4gICAgICAgICAgICAgICAgICAgIC4uLm1ldGFQcm9qZWN0aW9uXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICBdKTtcclxuICAgIGNvbnN0IHBhZ2luYXRpb24gPSByZXN1bHRbMF0gYXMgSVBhZ2luYXRpb25CYXNlPERvY3VtZW50VHlwZTxVPj47XHJcbiAgICBpZiAoIXBhZ2luYXRpb24pIHtcclxuICAgICAgICByZXR1cm4ge2l0ZW1zOiBbXSwgY291bnQ6IDAsIG1ldGE6IHt0b3RhbDogMH19O1xyXG4gICAgfVxyXG4gICAgcGFnaW5hdGlvbi5pdGVtcyA9IHBhZ2luYXRpb24uaXRlbXMubWFwKGkgPT4gaHlkcmF0ZVBvcHVsYXRlZChtb2RlbCwgaSkgYXMgYW55KTtcclxuICAgIHJldHVybiBwYWdpbmF0aW9uO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gUmVzb2x2ZUVudGl0eTxUIGV4dGVuZHMgVHlwZTxhbnk+LCBVID0gSW5mZXJHZW5lcmljPFQ+Pihtb2RlbDogUmV0dXJuTW9kZWxUeXBlPFQ+LCBleHRyYUNoZWNrPzogKHF1ZXJ5OiBRdWVyeTxEb2N1bWVudFR5cGU8VT4sIGFueT4sIGFjdGlvbjogQWN0aW9uKSA9PiBQcm9taXNlPERvY3VtZW50VHlwZTxVPj4pOiBQYXJhbWV0ZXJEZWNvcmF0b3Ige1xyXG4gICAgY29uc3QgbW9kZWxOYW1lID0gbW9kZWwubW9kZWxOYW1lO1xyXG4gICAgY29uc3QgcGFyYW1OYW1lID0gbW9kZWxOYW1lLnRvTG93ZXJDYXNlKCk7XHJcbiAgICByZXR1cm4gY3JlYXRlUGFyYW1EZWNvcmF0b3Ioe1xyXG4gICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcclxuICAgICAgICB2YWx1ZTogYXN5bmMgYWN0aW9uID0+IHtcclxuICAgICAgICAgICAgY29uc3QgcmVxID0gYWN0aW9uLnJlcXVlc3QgYXMgSVJlcXVlc3Q7XHJcbiAgICAgICAgICAgIGNvbnN0IHRva2VuID0gcmVxLmhlYWRlcihgeC0ke3BhcmFtTmFtZX0tdG9rZW5gKTtcclxuICAgICAgICAgICAgY29uc3QgaWQgPSByZXEucGFyYW1zW2Ake3BhcmFtTmFtZX1JZGBdIGFzIHN0cmluZztcclxuICAgICAgICAgICAgaWYgKCFpZCAmJiAhdG9rZW4pIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXJyb3IoYCR7bW9kZWxOYW1lfSBpZCBvciB0b2tlbiBzaG91bGQgYmUgZGVmaW5lZCFgKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjb25zdCBxdWVyeSA9ICF0b2tlblxyXG4gICAgICAgICAgICAgICAgPyBtb2RlbC5maW5kQnlJZChpZClcclxuICAgICAgICAgICAgICAgIDogbW9kZWwuZmluZE9uZSh7dG9rZW59IGFzIGFueSk7XHJcbiAgICAgICAgICAgIGxldCBkb2M6IERvY3VtZW50ID0gbnVsbDtcclxuICAgICAgICAgICAgaWYgKGlzRnVuY3Rpb24oZXh0cmFDaGVjaykpIHtcclxuICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZG9jID0gYXdhaXQgdmFsdWVUb1Byb21pc2UoZXh0cmFDaGVjayhxdWVyeSwgYWN0aW9uKSk7XHJcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEJhZFJlcXVlc3RFcnJvcihgJHttb2RlbE5hbWV9IGNoZWNrIGVycm9yOiAke2UubWVzc2FnZSB8fCBlfWApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgZG9jID0gYXdhaXQgcXVlcnk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKCFkb2MpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBIdHRwRXJyb3IoNDA0LCAhdG9rZW5cclxuICAgICAgICAgICAgICAgICAgICA/IGAke21vZGVsTmFtZX0gY291bGQgbm90IGJlIGZvdW5kIHdpdGggaWQ6ICR7aWR9YFxyXG4gICAgICAgICAgICAgICAgICAgIDogYCR7bW9kZWxOYW1lfSBjb3VsZCBub3QgYmUgZm91bmQgd2l0aCB0b2tlbjogJHt0b2tlbn1gKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBhY3Rpb24ucmVxdWVzdFtwYXJhbU5hbWVdID0gZG9jO1xyXG4gICAgICAgICAgICByZXR1cm4gZG9jO1xyXG4gICAgICAgIH1cclxuICAgIH0pO1xyXG59XHJcbiJdfQ==