velocious 1.0.534 → 1.0.535
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/build/database/drivers/mysql/index.js +24 -11
- package/build/database/tenants/data-copier.js +40 -5
- package/build/src/database/drivers/mysql/index.d.ts.map +1 -1
- package/build/src/database/drivers/mysql/index.js +19 -10
- package/build/src/database/tenants/data-copier.d.ts +31 -3
- package/build/src/database/tenants/data-copier.d.ts.map +1 -1
- package/build/src/database/tenants/data-copier.js +39 -6
- package/package.json +1 -1
- package/src/database/drivers/mysql/index.js +24 -11
- package/src/database/tenants/data-copier.js +40 -5
|
@@ -320,19 +320,32 @@ export default class VelociousDatabaseDriversMysql extends Base{
|
|
|
320
320
|
* @returns {import("../base.js").RetryableDatabaseErrorResult} - Retry info.
|
|
321
321
|
*/
|
|
322
322
|
retryableDatabaseError(error) {
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
message.
|
|
330
|
-
|
|
331
|
-
|
|
323
|
+
/** @type {Error | undefined} */
|
|
324
|
+
let currentError = error
|
|
325
|
+
let shouldReconnect = false
|
|
326
|
+
|
|
327
|
+
while (currentError) {
|
|
328
|
+
const errorCode = "code" in currentError && typeof currentError.code == "string" ? currentError.code : undefined
|
|
329
|
+
const message = currentError.message || ""
|
|
330
|
+
|
|
331
|
+
if (errorCode == "ER_CHECKREAD" || message.includes("Record has changed since last read")) {
|
|
332
|
+
return {retry: true, reconnect: false, waitMs: 50}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
shouldReconnect ||= (
|
|
336
|
+
errorCode == "ECONNREFUSED" ||
|
|
337
|
+
message.includes("ECONNREFUSED") ||
|
|
338
|
+
message.includes("connect ECONNREFUSED") ||
|
|
339
|
+
message.includes("PROTOCOL_CONNECTION_LOST") ||
|
|
340
|
+
message.includes("Connection lost")
|
|
341
|
+
)
|
|
342
|
+
|
|
343
|
+
currentError = currentError.cause instanceof Error ? currentError.cause : undefined
|
|
344
|
+
}
|
|
332
345
|
|
|
333
346
|
return {
|
|
334
|
-
retry:
|
|
335
|
-
reconnect:
|
|
347
|
+
retry: shouldReconnect,
|
|
348
|
+
reconnect: shouldReconnect,
|
|
336
349
|
waitMs: 50
|
|
337
350
|
}
|
|
338
351
|
}
|
|
@@ -130,6 +130,35 @@ export default class DataCopier {
|
|
|
130
130
|
* @returns {Promise<Map<string, Record<string, unknown>[]>>} - Loaded rows grouped by table name.
|
|
131
131
|
*/
|
|
132
132
|
async loadRows(db, keyValue) {
|
|
133
|
+
return (await this.traversePlan(db, keyValue)).rowsByTableName
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Loads only the ids for `keyValue` for every table in the plan from `db`, using the same
|
|
138
|
+
* parent/child traversal as {@link DataCopier#loadRows} but selecting just the id column.
|
|
139
|
+
* Callers that only need to compare row membership — for example verifying a tenant already
|
|
140
|
+
* holds every default row before a cleanup delete — should use this instead of loadRows so
|
|
141
|
+
* they never materialise full rows; for large tenants that is the difference between a few
|
|
142
|
+
* kilobytes of ids and gigabytes of row data.
|
|
143
|
+
* @param {import("../drivers/base.js").default} db - Source or target database to traverse.
|
|
144
|
+
* @param {string} keyValue - Tenant key selecting the root plan rows.
|
|
145
|
+
* @returns {Promise<Map<string, string[]>>} - Loaded ids grouped by table name.
|
|
146
|
+
*/
|
|
147
|
+
async loadRowIds(db, keyValue) {
|
|
148
|
+
return (await this.traversePlan(db, keyValue, [this.idColumn])).idsByTableName
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Traverses the table plan for `keyValue`, querying each table by its tenant key column or
|
|
153
|
+
* (for child tables) by the ids already selected for its parent, and returns both the ids
|
|
154
|
+
* and the loaded rows grouped by table name. `selectColumns` bounds the columns each query
|
|
155
|
+
* selects; pass `[idColumn]` for an id-only traversal, or omit it to load full rows.
|
|
156
|
+
* @param {import("../drivers/base.js").default} db - Source or target database to traverse.
|
|
157
|
+
* @param {string} keyValue - Tenant key selecting the root plan rows.
|
|
158
|
+
* @param {string[]} [selectColumns] - Columns to select; defaults to every column.
|
|
159
|
+
* @returns {Promise<{idsByTableName: Map<string, string[]>, rowsByTableName: Map<string, Record<string, unknown>[]>}>} - Ids and rows grouped by table name.
|
|
160
|
+
*/
|
|
161
|
+
async traversePlan(db, keyValue, selectColumns) {
|
|
133
162
|
/** @type {Map<string, string[]>} */
|
|
134
163
|
const idsByTableName = new Map()
|
|
135
164
|
/** @type {Map<string, Record<string, unknown>[]>} */
|
|
@@ -142,6 +171,7 @@ export default class DataCopier {
|
|
|
142
171
|
rows = await this.queryRowsByColumn({
|
|
143
172
|
columnName: tableConfig.keyColumn,
|
|
144
173
|
db,
|
|
174
|
+
selectColumns,
|
|
145
175
|
tableName: tableConfig.tableName,
|
|
146
176
|
values: [keyValue]
|
|
147
177
|
})
|
|
@@ -157,6 +187,7 @@ export default class DataCopier {
|
|
|
157
187
|
rows = await this.queryRowsByColumn({
|
|
158
188
|
columnName: tableConfig.parentColumn,
|
|
159
189
|
db,
|
|
190
|
+
selectColumns,
|
|
160
191
|
tableName: tableConfig.tableName,
|
|
161
192
|
values: idsByTableName.get(tableConfig.parentTableName) || []
|
|
162
193
|
})
|
|
@@ -170,15 +201,16 @@ export default class DataCopier {
|
|
|
170
201
|
rowsByTableName.set(tableConfig.tableName, rows)
|
|
171
202
|
}
|
|
172
203
|
|
|
173
|
-
return rowsByTableName
|
|
204
|
+
return {idsByTableName, rowsByTableName}
|
|
174
205
|
}
|
|
175
206
|
|
|
176
207
|
/**
|
|
177
|
-
* Selects
|
|
178
|
-
*
|
|
208
|
+
* Selects `tableName` rows in `db` whose `columnName` is in `values`, chunked. `selectColumns`
|
|
209
|
+
* bounds the projection and defaults to every column.
|
|
210
|
+
* @param {{columnName: string, db: import("../drivers/base.js").default, selectColumns?: string[], tableName: string, values: string[]}} args - Table, column, projection, database, and values for the chunked lookup.
|
|
179
211
|
* @returns {Promise<Record<string, unknown>[]>} - Rows matching the supplied column values.
|
|
180
212
|
*/
|
|
181
|
-
async queryRowsByColumn({columnName, db, tableName, values}) {
|
|
213
|
+
async queryRowsByColumn({columnName, db, selectColumns, tableName, values}) {
|
|
182
214
|
const normalizedValues = uniqueStrings(values)
|
|
183
215
|
|
|
184
216
|
if (normalizedValues.length <= 0) {
|
|
@@ -188,9 +220,12 @@ export default class DataCopier {
|
|
|
188
220
|
const rows = []
|
|
189
221
|
const quotedTable = db.quoteTable(tableName)
|
|
190
222
|
const quotedColumn = db.quoteColumn(columnName)
|
|
223
|
+
const selectList = selectColumns
|
|
224
|
+
? selectColumns.map((column) => `${quotedTable}.${db.quoteColumn(column)}`).join(", ")
|
|
225
|
+
: `${quotedTable}.*`
|
|
191
226
|
|
|
192
227
|
for (const valuesChunk of chunks(normalizedValues, this.queryChunkSize)) {
|
|
193
|
-
const sql = `SELECT ${
|
|
228
|
+
const sql = `SELECT ${selectList} FROM ${quotedTable} WHERE ${quotedColumn} IN (${this.quotedValuesSql(db, valuesChunk)})`
|
|
194
229
|
|
|
195
230
|
rows.push(...await this.executeQuietQuery(db, sql))
|
|
196
231
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/database/drivers/mysql/index.js"],"names":[],"mappings":"AAgCA;IACE,+CAA+C;IAC/C,MADW,OAAO,OAAO,EAAE,IAAI,GAAG,SAAS,CAC3B;IAEhB,4BAA4B;IAC5B,yBADW,MAAM,GAAG,IAAI,CACU;IAElC,4BAA4B;IAC5B,yBADW,MAAM,GAAG,IAAI,CACM;IAY9B;;;OAGG;IACH,cAAe,OAFJ,KAES,UAEnB;IAuDD;;;OAGG;IACH,6BAFa,MAAM,GAAG,IAAI,CAIzB;IAED;;;OAGG;IACH,oCAFW,MAAM,GAAG,IAAI,QAIvB;IAED;;;OAGG;IACH,6BAFa,MAAM,GAAG,IAAI,CAIzB;IAED;;OAEG;IACH,oCAEC;IAED;;;OAGG;IACH,yBAFa,OAAO,CAAC,OAAO,CAAC,CAU5B;IAED;;;;OAIG;IACH,6BAHW,MAAM,GACJ,OAAO,CAAC,OAAO,CAAC,CAS5B;IAED;;;OAGG;IACH,eAFa,MAAM,CAAC,MAAM,EAAE,OAAC,CAAC,CAmB7B;IAcD;;;;;;OAMG;IACH,gCALW,MAAM,SAEd;QAAuB,WAAW;KAClC,GAAU,MAAM,EAAE,CAOpB;IAoDD;;;OAGG;IACH,mBAFa,OAAO,CAAC,MAAM,CAAC,CAM3B;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/database/drivers/mysql/index.js"],"names":[],"mappings":"AAgCA;IACE,+CAA+C;IAC/C,MADW,OAAO,OAAO,EAAE,IAAI,GAAG,SAAS,CAC3B;IAEhB,4BAA4B;IAC5B,yBADW,MAAM,GAAG,IAAI,CACU;IAElC,4BAA4B;IAC5B,yBADW,MAAM,GAAG,IAAI,CACM;IAY9B;;;OAGG;IACH,cAAe,OAFJ,KAES,UAEnB;IAuDD;;;OAGG;IACH,6BAFa,MAAM,GAAG,IAAI,CAIzB;IAED;;;OAGG;IACH,oCAFW,MAAM,GAAG,IAAI,QAIvB;IAED;;;OAGG;IACH,6BAFa,MAAM,GAAG,IAAI,CAIzB;IAED;;OAEG;IACH,oCAEC;IAED;;;OAGG;IACH,yBAFa,OAAO,CAAC,OAAO,CAAC,CAU5B;IAED;;;;OAIG;IACH,6BAHW,MAAM,GACJ,OAAO,CAAC,OAAO,CAAC,CAS5B;IAED;;;OAGG;IACH,eAFa,MAAM,CAAC,MAAM,EAAE,OAAC,CAAC,CAmB7B;IAcD;;;;;;OAMG;IACH,gCALW,MAAM,SAEd;QAAuB,WAAW;KAClC,GAAU,MAAM,EAAE,CAOpB;IAoDD;;;OAGG;IACH,mBAFa,OAAO,CAAC,MAAM,CAAC,CAM3B;IA4ID;;;;OAIG;IACH,aAHW,MAAM,GACJ,MAAM,CAQlB;IAoEqB,8BAA2C;CAuGlE;iBAtlBgB,YAAY;oBAST,cAAc"}
|
|
@@ -274,16 +274,25 @@ export default class VelociousDatabaseDriversMysql extends Base {
|
|
|
274
274
|
* @returns {import("../base.js").RetryableDatabaseErrorResult} - Retry info.
|
|
275
275
|
*/
|
|
276
276
|
retryableDatabaseError(error) {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
message.
|
|
283
|
-
message.includes("
|
|
277
|
+
/** @type {Error | undefined} */
|
|
278
|
+
let currentError = error;
|
|
279
|
+
let shouldReconnect = false;
|
|
280
|
+
while (currentError) {
|
|
281
|
+
const errorCode = "code" in currentError && typeof currentError.code == "string" ? currentError.code : undefined;
|
|
282
|
+
const message = currentError.message || "";
|
|
283
|
+
if (errorCode == "ER_CHECKREAD" || message.includes("Record has changed since last read")) {
|
|
284
|
+
return { retry: true, reconnect: false, waitMs: 50 };
|
|
285
|
+
}
|
|
286
|
+
shouldReconnect ||= (errorCode == "ECONNREFUSED" ||
|
|
287
|
+
message.includes("ECONNREFUSED") ||
|
|
288
|
+
message.includes("connect ECONNREFUSED") ||
|
|
289
|
+
message.includes("PROTOCOL_CONNECTION_LOST") ||
|
|
290
|
+
message.includes("Connection lost"));
|
|
291
|
+
currentError = currentError.cause instanceof Error ? currentError.cause : undefined;
|
|
292
|
+
}
|
|
284
293
|
return {
|
|
285
|
-
retry:
|
|
286
|
-
reconnect:
|
|
294
|
+
retry: shouldReconnect,
|
|
295
|
+
reconnect: shouldReconnect,
|
|
287
296
|
waitMs: 50
|
|
288
297
|
};
|
|
289
298
|
}
|
|
@@ -509,4 +518,4 @@ export default class VelociousDatabaseDriversMysql extends Base {
|
|
|
509
518
|
return holder !== null && holder !== undefined;
|
|
510
519
|
}
|
|
511
520
|
}
|
|
512
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvZGF0YWJhc2UvZHJpdmVycy9teXNxbC9pbmRleC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxVQUFVLE1BQU0sc0JBQXNCLENBQUE7QUFDN0MsT0FBTyxJQUFJLE1BQU0sWUFBWSxDQUFBO0FBQzdCLE9BQU8sY0FBYyxNQUFNLDBCQUEwQixDQUFBO0FBQ3JELE9BQU8sV0FBVyxNQUFNLHVCQUF1QixDQUFBO0FBQy9DLE9BQU8sV0FBVyxNQUFNLHVCQUF1QixDQUFBO0FBQy9DLE9BQU8sTUFBTSxNQUFNLGlCQUFpQixDQUFBO0FBQ3BDLE9BQU8sRUFBQyxJQUFJLEVBQUMsTUFBTSxXQUFXLENBQUE7QUFDOUIsT0FBTyxZQUFZLE1BQU0sd0JBQXdCLENBQUE7QUFDakQsT0FBTyxTQUFTLE1BQU0scUJBQXFCLENBQUE7QUFDM0MsT0FBTyxNQUFNLE1BQU0saUJBQWlCLENBQUE7QUFDcEMsT0FBTyxPQUFPLE1BQU0sY0FBYyxDQUFBO0FBQ2xDLE9BQU8sS0FBSyxNQUFNLE9BQU8sQ0FBQTtBQUN6QixPQUFPLEtBQUssTUFBTSxZQUFZLENBQUE7QUFDOUIsT0FBTyxXQUFXLE1BQU0sbUJBQW1CLENBQUE7QUFDM0MsT0FBTyxXQUFXLE1BQU0sdUJBQXVCLENBQUE7QUFDL0MsT0FBTyxLQUFLLE1BQU0sWUFBWSxDQUFBO0FBQzlCLE9BQU8sWUFBWSxNQUFNLG9CQUFvQixDQUFBO0FBQzdDLE9BQU8sTUFBTSxNQUFNLGlCQUFpQixDQUFBO0FBQ3BDLE9BQU8sTUFBTSxNQUFNLGlCQUFpQixDQUFBO0FBRXBDOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLHFDQUFxQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQTtBQUVoRSxNQUFNLENBQUMsT0FBTyxPQUFPLDZCQUE4QixTQUFRLElBQUk7SUFDN0QsK0NB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QzFHLE1BQU0sTUFBTSxHQUFHLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLDhCQUE4QixDQUFBO1FBRXhELElBQUksTUFBTSxLQUFLLElBQUksSUFBSSxNQUFNLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDNUMsTUFBTSxJQUFJLEtBQUssQ0FBQyw0Q0FBNEMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsMERBQTBELENBQUMsQ0FBQTtRQUM3SSxDQUFDO1FBRUQsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQzdCLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsS0FBSyxDQUFDLG1CQUFtQixDQUFDLElBQUk7UUFDNUIsTUFBTSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLHVCQUF1QixJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFBO1FBQzNHLE1BQU0sTUFBTSxHQUFHLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLDhCQUE4QixDQUFBO1FBRXhELE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUM3QixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJO1FBQzNCLE1BQU0sSUFBSSxHQUFHLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyx1QkFBdUIsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMscUNBQXFDLENBQUMsQ0FBQTtRQUMzRyxNQUFNLE1BQU0sR0FBRyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSw4QkFBOEIsQ0FBQTtRQUV4RCxPQUFPLE1BQU0sS0FBSyxJQUFJLElBQUksTUFBTSxLQUFLLFNBQVMsQ0FBQTtJQUNoRCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IEFsdGVyVGFibGUgZnJvbSBcIi4vc3FsL2FsdGVyLXRhYmxlLmpzXCJcbmltcG9ydCBCYXNlIGZyb20gXCIuLi9iYXNlLmpzXCJcbmltcG9ydCBDcmVhdGVEYXRhYmFzZSBmcm9tIFwiLi9zcWwvY3JlYXRlLWRhdGFiYXNlLmpzXCJcbmltcG9ydCBDcmVhdGVJbmRleCBmcm9tIFwiLi9zcWwvY3JlYXRlLWluZGV4LmpzXCJcbmltcG9ydCBDcmVhdGVUYWJsZSBmcm9tIFwiLi9zcWwvY3JlYXRlLXRhYmxlLmpzXCJcbmltcG9ydCBEZWxldGUgZnJvbSBcIi4vc3FsL2RlbGV0ZS5qc1wiXG5pbXBvcnQge2RpZ2d9IGZyb20gXCJkaWdnZXJpemVcIlxuaW1wb3J0IERyb3BEYXRhYmFzZSBmcm9tIFwiLi9zcWwvZHJvcC1kYXRhYmFzZS5qc1wiXG5pbXBvcnQgRHJvcFRhYmxlIGZyb20gXCIuL3NxbC9kcm9wLXRhYmxlLmpzXCJcbmltcG9ydCBJbnNlcnQgZnJvbSBcIi4vc3FsL2luc2VydC5qc1wiXG5pbXBvcnQgT3B0aW9ucyBmcm9tIFwiLi9vcHRpb25zLmpzXCJcbmltcG9ydCBteXNxbCBmcm9tIFwibXlzcWxcIlxuaW1wb3J0IHF1ZXJ5IGZyb20gXCIuL3F1ZXJ5LmpzXCJcbmltcG9ydCBRdWVyeVBhcnNlciBmcm9tIFwiLi9xdWVyeS1wYXJzZXIuanNcIlxuaW1wb3J0IFJlbW92ZUluZGV4IGZyb20gXCIuL3NxbC9yZW1vdmUtaW5kZXguanNcIlxuaW1wb3J0IFRhYmxlIGZyb20gXCIuL3RhYmxlLmpzXCJcbmltcG9ydCBTdHJ1Y3R1cmVTcWwgZnJvbSBcIi4vc3RydWN0dXJlLXNxbC5qc1wiXG5pbXBvcnQgVXBzZXJ0IGZyb20gXCIuL3NxbC91cHNlcnQuanNcIlxuaW1wb3J0IFVwZGF0ZSBmcm9tIFwiLi9zcWwvdXBkYXRlLmpzXCJcblxuLyoqXG4gKiBTZW50aW5lbCB0aW1lb3V0IChpbiBzZWNvbmRzKSB1c2VkIGFzIHRoZSBcImJsb2NrIGZvcmV2ZXJcIiB2YWx1ZSB3aGVuIGFcbiAqIGNhbGxlciBhc2tzIGZvciBhbiBpbmRlZmluaXRlIGFkdmlzb3J5IGxvY2sgYWNxdWlyZS4gTXlTUUwgaGlzdG9yaWNhbGx5XG4gKiBhY2NlcHRlZCBuZWdhdGl2ZSB0aW1lb3V0cyBhcyBcImluZmluaXRlXCIsIGJ1dCBNYXJpYURCIDEwKyBzaWxlbnRseVxuICogcmV0dXJucyBOVUxMIGZyb20gYEdFVF9MT0NLYCB3aGVuIHRoZSB0aW1lb3V0IGlzIG5lZ2F0aXZlLCBzbyB0aGVcbiAqIGRyaXZlciBjbGFtcHMgdG8gYSBjb21mb3J0YWJseSBsYXJnZSBwb3NpdGl2ZSB2YWx1ZSAoMSB5ZWFyIOKJqyBhbnlcbiAqIHJlYWxpc3RpYyBjcml0aWNhbCBzZWN0aW9uKSBpbnN0ZWFkLlxuICovXG5jb25zdCBNWVNRTF9JTkRFRklOSVRFX0xPQ0tfVElNRU9VVF9TRUNPTkRTID0gNjAgKiA2MCAqIDI0ICogMzY1XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFZlbG9jaW91c0RhdGFiYXNlRHJpdmVyc015c3FsIGV4dGVuZHMgQmFzZXtcbiAgLyoqIEB0eXBlIHtpbXBvcnQoXCJteXNxbFwiKS5Qb29sIHwgdW5kZWZpbmVkfSAqL1xuICBwb29sID0gdW5kZWZpbmVkXG5cbiAgLyoqIEB0eXBlIHtzdHJpbmcgfCBudWxsfSAqL1xuICBfZGVzaXJlZFNlc3Npb25UaW1lWm9uZSA9IFwiKzAwOjAwXCJcblxuICAvKiogQHR5cGUge3N0cmluZyB8IG51bGx9ICovXG4gIF9jdXJyZW50U2Vzc2lvblRpbWVab25lID0gbnVsbFxuXG4gIC8qKlxuICAgKiBSdW5zIGNvbm5lY3QuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBjb25uZWN0KCkge1xuICAgIHRoaXMucmVzZXRDdXJyZW50U2Vzc2lvblRpbWVab25lKClcbiAgICB0aGlzLnBvb2wgPSBteXNxbC5jcmVhdGVQb29sKE9iamVjdC5hc3NpZ24oe2Nvbm5lY3Rpb25MaW1pdDogMX0sIHRoaXMuY29ubmVjdEFyZ3MoKSkpXG4gICAgdGhpcy5wb29sLm9uKFwiZXJyb3JcIiwgdGhpcy5vblBvb2xFcnJvcilcbiAgfVxuXG4gIC8qKlxuICAgKiBPbiBwb29sIGVycm9yLlxuICAgKiBAcGFyYW0ge0Vycm9yfSBlcnJvciAtIEVycm9yIGZyb20gdGhlIGNvbm5lY3Rpb24gYXR0ZW1wdC5cbiAgICovXG4gIG9uUG9vbEVycm9yID0gKGVycm9yKSA9PiB7XG4gICAgY29uc29sZS5lcnJvcihcIlZlbG9jaW91cyAvIE15U1FMIGRyaXZlciAvIFBvb2wgZXJyb3JcIiwgZXJyb3IpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBjbG9zZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIGNsb3NlKCkge1xuICAgIGF3YWl0IHRoaXMucG9vbD8uZW5kKClcbiAgICB0aGlzLnBvb2wgPSB1bmRlZmluZWRcbiAgICB0aGlzLnJlc2V0Q3VycmVudFNlc3Npb25UaW1lWm9uZSgpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBzZXQgY29ubmVjdGlvbiBjaGVja291dCBuYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZyB8IHVuZGVmaW5lZH0gbmFtZSAtIEh1bWFuLXJlYWRhYmxlIG5hbWUgZm9yIHRoaXMgYWN0aXZlIGNoZWNrb3V0LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgc2V0Q29ubmVjdGlvbkNoZWNrb3V0TmFtZShuYW1lKSB7XG4gICAgY29uc3QgcHJldmlvdXNOYW1lID0gdGhpcy5fY29ubmVjdGlvbkNoZWNrb3V0TmFtZVxuXG4gICAgYXdhaXQgc3VwZXIuc2V0Q29ubmVjdGlvbkNoZWNrb3V0TmFtZShuYW1lKVxuXG4gICAgaWYgKG5hbWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKHByZXZpb3VzTmFtZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGF3YWl0IHRoaXMucXVlcnkoXCJTRVQgQHZlbG9jaW91c19jb25uZWN0aW9uX2NoZWNrb3V0X25hbWUgPSBOVUxMXCIsIHtsb2dOYW1lOiBcIkNsZWFyIENvbm5lY3Rpb24gQ2hlY2tvdXQgTmFtZVwiLCBwcm9jZXNzTGlzdENvbW1lbnQ6IGZhbHNlLCBzZXNzaW9uVGltZVpvbmU6IGZhbHNlfSlcbiAgICAgIH1cblxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5xdWVyeShgU0VUIEB2ZWxvY2lvdXNfY29ubmVjdGlvbl9jaGVja291dF9uYW1lID0gJHt0aGlzLnF1b3RlKG5hbWUpfWAsIHtsb2dOYW1lOiBcIlNldCBDb25uZWN0aW9uIENoZWNrb3V0IE5hbWVcIiwgcHJvY2Vzc0xpc3RDb21tZW50OiBmYWxzZSwgc2Vzc2lvblRpbWVab25lOiBmYWxzZX0pXG4gIH1cblxuICAvKipcbiAgICogUnVucyBjbGVhciBjb25uZWN0aW9uIGNoZWNrb3V0IG5hbWUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBjbGVhckNvbm5lY3Rpb25DaGVja291dE5hbWUoKSB7XG4gICAgaWYgKHRoaXMuX2Nvbm5lY3Rpb25DaGVja291dE5hbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgYXdhaXQgdGhpcy5xdWVyeShcIlNFVCBAdmVsb2Npb3VzX2Nvbm5lY3Rpb25fY2hlY2tvdXRfbmFtZSA9IE5VTExcIiwge2xvZ05hbWU6IFwiQ2xlYXIgQ29ubmVjdGlvbiBDaGVja291dCBOYW1lXCIsIHByb2Nlc3NMaXN0Q29tbWVudDogZmFsc2UsIHNlc3Npb25UaW1lWm9uZTogZmFsc2V9KVxuICAgIH1cblxuICAgIGF3YWl0IHN1cGVyLmNsZWFyQ29ubmVjdGlvbkNoZWNrb3V0TmFtZSgpXG4gIH1cblxuICAvKipcbiAgICogSG9vayBiZWZvcmUgZXZlcnkgcXVlcnkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBfc3FsIC0gU1FMIHN0cmluZy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9iYXNlLmpzXCIpLlF1ZXJ5T3B0aW9uc30gb3B0aW9ucyAtIFF1ZXJ5IG9wdGlvbnMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBiZWZvcmVRdWVyeShfc3FsLCBvcHRpb25zKSB7XG4gICAgaWYgKG9wdGlvbnMuc2Vzc2lvblRpbWVab25lICE9PSBmYWxzZSkgYXdhaXQgdGhpcy5lbnN1cmVTZXNzaW9uVGltZVpvbmUoKVxuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGRlc2lyZWQgZGF0YWJhc2Ugc2Vzc2lvbiB0aW1lIHpvbmUgZm9yIHRoaXMgY29ubmVjdGlvbiBjb250ZXh0LlxuICAgKiBAcmV0dXJucyB7c3RyaW5nIHwgbnVsbH0gLSBEZXNpcmVkIHNlc3Npb24gdGltZSB6b25lLlxuICAgKi9cbiAgZ2V0RGVzaXJlZFNlc3Npb25UaW1lWm9uZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fZGVzaXJlZFNlc3Npb25UaW1lWm9uZVxuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIGRlc2lyZWQgZGF0YWJhc2Ugc2Vzc2lvbiB0aW1lIHpvbmUgd2l0aG91dCBxdWVyeWluZyBNeVNRTCBpbW1lZGlhdGVseS5cbiAgICogQHBhcmFtIHtzdHJpbmcgfCBudWxsfSB0aW1lWm9uZSAtIERlc2lyZWQgc2Vzc2lvbiB0aW1lIHpvbmUuXG4gICAqL1xuICBzZXREZXNpcmVkU2Vzc2lvblRpbWVab25lKHRpbWVab25lKSB7XG4gICAgdGhpcy5fZGVzaXJlZFNlc3Npb25UaW1lWm9uZSA9IHRpbWVab25lXG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgZGF0YWJhc2Ugc2Vzc2lvbiB0aW1lIHpvbmUgbGFzdCBjb25maXJtZWQgdGhyb3VnaCBTRVQgdGltZV96b25lLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nIHwgbnVsbH0gLSBDdXJyZW50IGtub3duIHNlc3Npb24gdGltZSB6b25lLlxuICAgKi9cbiAgZ2V0Q3VycmVudFNlc3Npb25UaW1lWm9uZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fY3VycmVudFNlc3Npb25UaW1lWm9uZVxuICB9XG5cbiAgLyoqXG4gICAqIENsZWFycyB0aGUgY3VycmVudCBrbm93biBkYXRhYmFzZSBzZXNzaW9uIHRpbWUgem9uZSB3aGVuIHRoZSBwaHlzaWNhbCBjb25uZWN0aW9uIGNoYW5nZXMuXG4gICAqL1xuICByZXNldEN1cnJlbnRTZXNzaW9uVGltZVpvbmUoKSB7XG4gICAgdGhpcy5fY3VycmVudFNlc3Npb25UaW1lWm9uZSA9IG51bGxcbiAgfVxuXG4gIC8qKlxuICAgKiBFbnN1cmVzIE15U1FMIGhhcyB0aGUgZGVzaXJlZCBzZXNzaW9uIHRpbWUgem9uZSBiZWZvcmUgdXNlciBTUUwgcnVucy5cbiAgICogQHJldHVybnMge1Byb21pc2U8Ym9vbGVhbj59IC0gVHJ1ZSB3aGVuIFNFVCB0aW1lX3pvbmUgd2FzIGV4ZWN1dGVkLlxuICAgKi9cbiAgYXN5bmMgZW5zdXJlU2Vzc2lvblRpbWVab25lKCkge1xuICAgIGNvbnN0IGRlc2lyZWRTZXNzaW9uVGltZVpvbmUgPSB0aGlzLmdldERlc2lyZWRTZXNzaW9uVGltZVpvbmUoKVxuXG4gICAgaWYgKGRlc2lyZWRTZXNzaW9uVGltZVpvbmUgPT09IG51bGwgfHwgdGhpcy5nZXRDdXJyZW50U2Vzc2lvblRpbWVab25lKCkgPT09IGRlc2lyZWRTZXNzaW9uVGltZVpvbmUpIHJldHVybiBmYWxzZVxuXG4gICAgYXdhaXQgdGhpcy5zZXRTZXNzaW9uVGltZVpvbmUoZGVzaXJlZFNlc3Npb25UaW1lWm9uZSlcblxuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgZGF0YWJhc2Ugc2Vzc2lvbiB0aW1lIHpvbmUgaWYgaXQgY2hhbmdlZCBmcm9tIHRoZSBsYXN0IGNvbmZpcm1lZCB2YWx1ZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHRpbWVab25lIC0gU2Vzc2lvbiB0aW1lIHpvbmUgdmFsdWUgYWNjZXB0ZWQgYnkgTXlTUUwuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGJvb2xlYW4+fSAtIFRydWUgd2hlbiBTRVQgdGltZV96b25lIHdhcyBleGVjdXRlZC5cbiAgICovXG4gIGFzeW5jIHNldFNlc3Npb25UaW1lWm9uZSh0aW1lWm9uZSkge1xuICAgIGlmICh0aGlzLmdldEN1cnJlbnRTZXNzaW9uVGltZVpvbmUoKSA9PT0gdGltZVpvbmUpIHJldHVybiBmYWxzZVxuXG4gICAgYXdhaXQgdGhpcy5fcXVlcnlBY3R1YWwoYFNFVCB0aW1lX3pvbmUgPSAke3RoaXMucXVvdGUodGltZVpvbmUpfWApXG4gICAgdGhpcy5fY3VycmVudFNlc3Npb25UaW1lWm9uZSA9IHRpbWVab25lXG5cbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgY29ubmVjdCBhcmdzLlxuICAgKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywgPz59IC0gVGhlIGNvbm5lY3QgYXJncy5cbiAgICovXG4gIGNvbm5lY3RBcmdzKCkge1xuICAgIGNvbnN0IGFyZ3MgPSB0aGlzLmdldEFyZ3MoKVxuICAgIGNvbnN0IGZvcndhcmQgPSBbXCJkYXRhYmFzZVwiLCBcImhvc3RcIiwgXCJwYXNzd29yZFwiXVxuXG4gICAgLyoqXG4gICAgICogQ29ubmVjdCBhcmdzLlxuICAgICAqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gKi9cbiAgICBjb25zdCBjb25uZWN0QXJncyA9IHtjaGFyc2V0OiBcInV0ZjhtYjRcIiwgdGltZXpvbmU6IFwiWlwifVxuXG4gICAgZm9yIChjb25zdCBmb3J3YXJkVmFsdWUgb2YgZm9yd2FyZCkge1xuICAgICAgaWYgKGZvcndhcmRWYWx1ZSBpbiBhcmdzKSBjb25uZWN0QXJnc1tmb3J3YXJkVmFsdWVdID0gZGlnZyhhcmdzLCBmb3J3YXJkVmFsdWUpXG4gICAgfVxuXG4gICAgaWYgKFwidXNlcm5hbWVcIiBpbiBhcmdzKSBjb25uZWN0QXJnc1tcInVzZXJcIl0gPSBhcmdzW1widXNlcm5hbWVcIl1cbiAgICBpZiAoXCJjaGFyc2V0XCIgaW4gYXJncykgY29ubmVjdEFyZ3NbXCJjaGFyc2V0XCJdID0gYXJnc1tcImNoYXJzZXRcIl1cblxuICAgIHJldHVybiBjb25uZWN0QXJnc1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYWx0ZXIgdGFibGUgc3Fscy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi90YWJsZS1kYXRhL2luZGV4LmpzXCIpLmRlZmF1bHR9IHRhYmxlRGF0YSAtIFRhYmxlIGRhdGEuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHN0cmluZ1tdPn0gLSBSZXNvbHZlcyB3aXRoIFNRTCBzdGF0ZW1lbnRzLlxuICAgKi9cbiAgYXN5bmMgYWx0ZXJUYWJsZVNRTHModGFibGVEYXRhKSB7XG4gICAgY29uc3QgYWx0ZXJBcmdzID0ge3RhYmxlRGF0YSwgZHJpdmVyOiB0aGlzfVxuICAgIGNvbnN0IGFsdGVyVGFibGUgPSBuZXcgQWx0ZXJUYWJsZShhbHRlckFyZ3MpXG5cbiAgICByZXR1cm4gYXdhaXQgYWx0ZXJUYWJsZS50b1NRTHMoKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgY3JlYXRlIGRhdGFiYXNlIHNxbC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGRhdGFiYXNlTmFtZSAtIERhdGFiYXNlIG5hbWUuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBbYXJnc10gLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHtib29sZWFufSBbYXJncy5pZk5vdEV4aXN0c10gLSBXaGV0aGVyIGlmIG5vdCBleGlzdHMuXG4gICAqIEByZXR1cm5zIHtzdHJpbmdbXX0gLSBTUUwgc3RhdGVtZW50cy5cbiAgICovXG4gIGNyZWF0ZURhdGFiYXNlU3FsKGRhdGFiYXNlTmFtZSwgYXJncykge1xuICAgIGNvbnN0IGNyZWF0ZUFyZ3MgPSBPYmplY3QuYXNzaWduKHtkYXRhYmFzZU5hbWUsIGRyaXZlcjogdGhpc30sIGFyZ3MpXG4gICAgY29uc3QgY3JlYXRlRGF0YWJhc2UgPSBuZXcgQ3JlYXRlRGF0YWJhc2UoY3JlYXRlQXJncylcblxuICAgIHJldHVybiBjcmVhdGVEYXRhYmFzZS50b1NxbCgpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBkcm9wIGRhdGFiYXNlIHNxbC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGRhdGFiYXNlTmFtZSAtIERhdGFiYXNlIG5hbWUuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBbYXJnc10gLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHtib29sZWFufSBbYXJncy5pZkV4aXN0c10gLSBXaGV0aGVyIGlmIGV4aXN0cy5cbiAgICogQHJldHVybnMge3N0cmluZ1tdfSAtIFNRTCBzdGF0ZW1lbnRzLlxuICAgKi9cbiAgZHJvcERhdGFiYXNlU3FsKGRhdGFiYXNlTmFtZSwgYXJncykge1xuICAgIGNvbnN0IGRyb3BBcmdzID0gT2JqZWN0LmFzc2lnbih7ZGF0YWJhc2VOYW1lLCBkcml2ZXI6IHRoaXN9LCBhcmdzKVxuICAgIGNvbnN0IGRyb3BEYXRhYmFzZSA9IG5ldyBEcm9wRGF0YWJhc2UoZHJvcEFyZ3MpXG5cbiAgICByZXR1cm4gZHJvcERhdGFiYXNlLnRvU3FsKClcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGNyZWF0ZSBpbmRleCBzcWxzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Jhc2UuanNcIikuQ3JlYXRlSW5kZXhTcWxBcmdzfSBpbmRleERhdGEgLSBJbmRleCBkYXRhLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmdbXT59IC0gUmVzb2x2ZXMgd2l0aCBTUUwgc3RhdGVtZW50cy5cbiAgICovXG4gIGFzeW5jIGNyZWF0ZUluZGV4U1FMcyhpbmRleERhdGEpIHtcbiAgICBjb25zdCBjcmVhdGVBcmdzID0gT2JqZWN0LmFzc2lnbih7ZHJpdmVyOiB0aGlzfSwgaW5kZXhEYXRhKVxuICAgIGNvbnN0IGNyZWF0ZUluZGV4ID0gbmV3IENyZWF0ZUluZGV4KGNyZWF0ZUFyZ3MpXG5cbiAgICByZXR1cm4gYXdhaXQgY3JlYXRlSW5kZXgudG9TUUxzKClcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHJlbW92ZSBpbmRleCBzcWxzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Jhc2UuanNcIikuUmVtb3ZlSW5kZXhTcWxBcmdzfSBpbmRleERhdGEgLSBJbmRleCBkYXRhLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmdbXT59IC0gUmVzb2x2ZXMgd2l0aCBTUUwgc3RhdGVtZW50cy5cbiAgICovXG4gIGFzeW5jIHJlbW92ZUluZGV4U1FMcyhpbmRleERhdGEpIHtcbiAgICBjb25zdCByZW1vdmVBcmdzID0gT2JqZWN0LmFzc2lnbih7ZHJpdmVyOiB0aGlzfSwgaW5kZXhEYXRhKVxuICAgIGNvbnN0IHJlbW92ZUluZGV4ID0gbmV3IFJlbW92ZUluZGV4KHJlbW92ZUFyZ3MpXG5cbiAgICByZXR1cm4gYXdhaXQgcmVtb3ZlSW5kZXgudG9TUUxzKClcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGNyZWF0ZSB0YWJsZSBzcWwuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vdGFibGUtZGF0YS9pbmRleC5qc1wiKS5kZWZhdWx0fSB0YWJsZURhdGEgLSBUYWJsZSBkYXRhLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmdbXT59IC0gUmVzb2x2ZXMgd2l0aCBTUUwgc3RhdGVtZW50cy5cbiAgICovXG4gIGFzeW5jIGNyZWF0ZVRhYmxlU3FsKHRhYmxlRGF0YSkge1xuICAgIGNvbnN0IGNyZWF0ZUFyZ3MgPSB7dGFibGVEYXRhLCBkcml2ZXI6IHRoaXN9XG4gICAgY29uc3QgY3JlYXRlVGFibGUgPSBuZXcgQ3JlYXRlVGFibGUoY3JlYXRlQXJncylcblxuICAgIHJldHVybiBjcmVhdGVUYWJsZS50b1NxbCgpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBjdXJyZW50IGRhdGFiYXNlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmc+fSAtIFJlc29sdmVzIHdpdGggdGhlIGN1cnJlbnQgZGF0YWJhc2UuXG4gICAqL1xuICBhc3luYyBjdXJyZW50RGF0YWJhc2UoKSB7XG4gICAgY29uc3Qgcm93cyA9IGF3YWl0IHRoaXMucXVlcnkoXCJTRUxFQ1QgREFUQUJBU0UoKSBBUyBkYl9uYW1lXCIpXG5cbiAgICByZXR1cm4gZGlnZyhyb3dzLCAwLCBcImRiX25hbWVcIilcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGRpc2FibGUgZm9yZWlnbiBrZXlzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgZGlzYWJsZUZvcmVpZ25LZXlzKCkge1xuICAgIGF3YWl0IHRoaXMucXVlcnkoXCJTRVQgRk9SRUlHTl9LRVlfQ0hFQ0tTID0gMFwiKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZW5hYmxlIGZvcmVpZ24ga2V5cy5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIGVuYWJsZUZvcmVpZ25LZXlzKCkge1xuICAgIGF3YWl0IHRoaXMucXVlcnkoXCJTRVQgRk9SRUlHTl9LRVlfQ0hFQ0tTID0gMVwiKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZHJvcCB0YWJsZSBzcWxzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFibGVOYW1lIC0gVGFibGUgbmFtZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9iYXNlLmpzXCIpLkRyb3BUYWJsZVNxbEFyZ3NUeXBlfSBbYXJnc10gLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHJldHVybnMge1Byb21pc2U8c3RyaW5nW10+fSAtIFJlc29sdmVzIHdpdGggU1FMIHN0YXRlbWVudHMuXG4gICAqL1xuICBhc3luYyBkcm9wVGFibGVTUUxzKHRhYmxlTmFtZSwgYXJncyA9IHt9KSB7XG4gICAgY29uc3QgZHJvcEFyZ3MgPSBPYmplY3QuYXNzaWduKHt0YWJsZU5hbWUsIGRyaXZlcjogdGhpc30sIGFyZ3MpXG4gICAgY29uc3QgZHJvcFRhYmxlID0gbmV3IERyb3BUYWJsZShkcm9wQXJncylcblxuICAgIHJldHVybiBhd2FpdCBkcm9wVGFibGUudG9TUUxzKClcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGdldCB0eXBlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSAtIFRoZSB0eXBlLlxuICAgKi9cbiAgZ2V0VHlwZSgpIHsgcmV0dXJuIFwibXlzcWxcIiB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcmV0cnlhYmxlIGRhdGFiYXNlIGVycm9yLlxuICAgKiBAcGFyYW0ge0Vycm9yfSBlcnJvciAtIEVycm9yIGluc3RhbmNlLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vYmFzZS5qc1wiKS5SZXRyeWFibGVEYXRhYmFzZUVycm9yUmVzdWx0fSAtIFJldHJ5IGluZm8uXG4gICAqL1xuICByZXRyeWFibGVEYXRhYmFzZUVycm9yKGVycm9yKSB7XG4gICAgY29uc3QgZXJyb3JDb2RlID0gLyoqIEB0eXBlIHs/fSAqLyAoZXJyb3IpLmNvZGVcbiAgICBjb25zdCBtZXNzYWdlID0gZXJyb3IubWVzc2FnZSB8fCBcIlwiXG4gICAgY29uc3Qgc2hvdWxkUmV0cnkgPSAoXG4gICAgICBlcnJvckNvZGUgPT0gXCJFQ09OTlJFRlVTRURcIiB8fFxuICAgICAgbWVzc2FnZS5pbmNsdWRlcyhcIkVDT05OUkVGVVNFRFwiKSB8fFxuICAgICAgbWVzc2FnZS5pbmNsdWRlcyhcImNvbm5lY3QgRUNPTk5SRUZVU0VEXCIpIHx8XG4gICAgICBtZXNzYWdlLmluY2x1ZGVzKFwiUFJPVE9DT0xfQ09OTkVDVElPTl9MT1NUXCIpIHx8XG4gICAgICBtZXNzYWdlLmluY2x1ZGVzKFwiQ29ubmVjdGlvbiBsb3N0XCIpXG4gICAgKVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHJldHJ5OiBzaG91bGRSZXRyeSxcbiAgICAgIHJlY29ubmVjdDogc2hvdWxkUmV0cnksXG4gICAgICB3YWl0TXM6IDUwXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcXVlcnkgYWN0dWFsLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3FsIC0gU1FMIHN0cmluZy5cbiAgICogQHJldHVybnMge1Byb21pc2U8aW1wb3J0KFwiLi4vYmFzZS5qc1wiKS5RdWVyeVJlc3VsdFR5cGU+fSAtIFJlc29sdmVzIHdpdGggdGhlIHF1ZXJ5IGFjdHVhbC5cbiAgICovXG4gIGFzeW5jIF9xdWVyeUFjdHVhbChzcWwpIHtcbiAgICBpZiAoIXRoaXMucG9vbCkgYXdhaXQgdGhpcy5jb25uZWN0KClcbiAgICBpZiAoIXRoaXMucG9vbCkgdGhyb3cgbmV3IEVycm9yKFwiTXlTUUwgcG9vbCBmYWlsZWQgdG8gaW5pdGlhbGl6ZVwiKVxuXG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCBxdWVyeSh0aGlzLnBvb2wsIHNxbClcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy8gUmUtdGhyb3cgdG8gdW4tY29ycnVwdCBzdGFja3RyYWNlXG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFF1ZXJ5IGZhaWxlZDogJHtlcnJvci5tZXNzYWdlfWAsIHtjYXVzZTogZXJyb3J9KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBRdWVyeSBmYWlsZWQ6ICR7ZXJyb3J9YCwge2NhdXNlOiBlcnJvcn0pXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEV4ZWN1dGVzIGEgbXV0YXRpb24gd2l0aCBhZmZlY3RlZC1yb3cgbWV0YWRhdGEuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzcWwgLSBNdXRhdGlvbiBTUUwuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPG51bWJlcj59IC0gQWZmZWN0ZWQgcm93IGNvdW50LlxuICAgKi9cbiAgYXN5bmMgX2FmZmVjdGVkUm93c0FjdHVhbChzcWwpIHtcbiAgICBpZiAoIXRoaXMucG9vbCkgYXdhaXQgdGhpcy5jb25uZWN0KClcbiAgICBpZiAoIXRoaXMucG9vbCkgdGhyb3cgbmV3IEVycm9yKFwiTXlTUUwgcG9vbCBmYWlsZWQgdG8gaW5pdGlhbGl6ZVwiKVxuICAgIGNvbnN0IHBvb2wgPSB0aGlzLnBvb2xcblxuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBwb29sLnF1ZXJ5KHNxbCwgKGVycm9yLCByZXN1bHQpID0+IHtcbiAgICAgICAgaWYgKGVycm9yKSByZWplY3QoZXJyb3IpXG4gICAgICAgIGVsc2UgcmVzb2x2ZShcImFmZmVjdGVkUm93c1wiIGluIHJlc3VsdCA/IHJlc3VsdC5hZmZlY3RlZFJvd3MgOiAwKVxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcXVlcnkgdG8gc3FsLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3F1ZXJ5L2luZGV4LmpzXCIpLmRlZmF1bHR9IHF1ZXJ5IC0gUXVlcnkgaW5zdGFuY2UuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IC0gU1FMIHN0cmluZy5cbiAgICovXG4gIHF1ZXJ5VG9TcWwocXVlcnkpIHsgcmV0dXJuIG5ldyBRdWVyeVBhcnNlcih7cXVlcnl9KS50b1NxbCgpIH1cblxuICAvKipcbiAgICogUnVucyBzaG91bGQgc2V0IGF1dG8gaW5jcmVtZW50IHdoZW4gcHJpbWFyeSBrZXkuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgc2V0IGF1dG8gaW5jcmVtZW50IHdoZW4gcHJpbWFyeSBrZXkuXG4gICAqL1xuICBzaG91bGRTZXRBdXRvSW5jcmVtZW50V2hlblByaW1hcnlLZXkoKSB7IHJldHVybiB0cnVlIH1cbiAgc3VwcG9ydHNEZWZhdWx0UHJpbWFyeUtleVVVSUQoKSB7IHJldHVybiBmYWxzZSB9XG4gIHN1cHBvcnRzQ3Jvc3NEYXRhYmFzZVJlZmVyZW5jZXMoKSB7IHJldHVybiB0cnVlIH1cblxuICAvKipcbiAgICogUnVucyBlc2NhcGUuXG4gICAqIEBwYXJhbSB7P30gdmFsdWUgLSBWYWx1ZSB0byB1c2UuXG4gICAqIEByZXR1cm5zIHs/fSAtIFRoZSBlc2NhcGUuXG4gICAqL1xuICBlc2NhcGUodmFsdWUpIHtcbiAgICBjb25zdCBlc2NhcGVkVmFsdWVXaXRoUXVvdGVzID0gdGhpcy5wb29sXG4gICAgICA/IHRoaXMucG9vbC5lc2NhcGUodGhpcy5fY29udmVydFZhbHVlKHZhbHVlKSlcbiAgICAgIDogbXlzcWwuZXNjYXBlKHRoaXMuX2NvbnZlcnRWYWx1ZSh2YWx1ZSkpXG5cbiAgICByZXR1cm4gZXNjYXBlZFZhbHVlV2l0aFF1b3Rlcy5zbGljZSgxLCBlc2NhcGVkVmFsdWVXaXRoUXVvdGVzLmxlbmd0aCAtIDEpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBxdW90ZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlIC0gVmFsdWUgdG8gdXNlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSAtIFRoZSBxdW90ZS5cbiAgICovXG4gIHF1b3RlKHZhbHVlKSB7XG4gICAgaWYgKHRoaXMucG9vbCkge1xuICAgICAgcmV0dXJuIHRoaXMucG9vbC5lc2NhcGUodGhpcy5fY29udmVydFZhbHVlKHZhbHVlKSlcbiAgICB9XG5cbiAgICByZXR1cm4gbXlzcWwuZXNjYXBlKHRoaXMuX2NvbnZlcnRWYWx1ZSh2YWx1ZSkpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBkZWxldGUgc3FsLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Jhc2UuanNcIikuRGVsZXRlU3FsQXJnc1R5cGV9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHJldHVybnMge3N0cmluZ30gLSBTUUwgc3RyaW5nLlxuICAgKi9cbiAgZGVsZXRlU3FsKHt0YWJsZU5hbWUsIGNvbmRpdGlvbnN9KSB7XG4gICAgY29uc3QgZGVsZXRlSW5zdHJ1Y3Rpb24gPSBuZXcgRGVsZXRlKHtjb25kaXRpb25zLCBkcml2ZXI6IHRoaXMsIHRhYmxlTmFtZX0pXG5cbiAgICByZXR1cm4gZGVsZXRlSW5zdHJ1Y3Rpb24udG9TcWwoKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgaW5zZXJ0IHNxbC5cbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vYmFzZS5qc1wiKS5JbnNlcnRTcWxBcmdzVHlwZX0gYXJncyAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSAtIFNRTCBzdHJpbmcuXG4gICAqL1xuICBpbnNlcnRTcWwoYXJncykge1xuICAgIGNvbnN0IGluc2VydEFyZ3MgPSBPYmplY3QuYXNzaWduKHtkcml2ZXI6IHRoaXN9LCBhcmdzKVxuICAgIGNvbnN0IGluc2VydCA9IG5ldyBJbnNlcnQoaW5zZXJ0QXJncylcblxuICAgIHJldHVybiBpbnNlcnQudG9TcWwoKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZ2V0IHRhYmxlcy5cbiAgICogQHJldHVybnMge1Byb21pc2U8QXJyYXk8aW1wb3J0KFwiLi4vYmFzZS10YWJsZS5qc1wiKS5kZWZhdWx0Pj59IC0gUmVzb2x2ZXMgd2l0aCB0aGUgdGFibGVzLlxuICAgKi9cbiAgYXN5bmMgZ2V0VGFibGVzKCkge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLl9jYWNoZWRTY2hlbWFNZXRhZGF0YShcInRhYmxlc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnF1ZXJ5KFwiU0hPVyBGVUxMIFRBQkxFU1wiKVxuICAgICAgY29uc3QgdGFibGVzID0gW11cblxuICAgICAgZm9yIChjb25zdCByb3cgb2YgcmVzdWx0KSB7XG4gICAgICAgIGNvbnN0IHRhYmxlID0gbmV3IFRhYmxlKHRoaXMsIC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgc3RyaW5nPn0gKi8gKHJvdykpXG5cbiAgICAgICAgdGFibGVzLnB1c2godGFibGUpXG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0YWJsZXNcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgc3RydWN0dXJlIHNxbC5cbiAgICogQHJldHVybnMge1Byb21pc2U8c3RyaW5nIHwgbnVsbD59IC0gUmVzb2x2ZXMgd2l0aCBTUUwgc3RyaW5nLlxuICAgKi9cbiAgYXN5bmMgc3RydWN0dXJlU3FsKCkge1xuICAgIHJldHVybiBhd2FpdCB0aGlzLl9jYWNoZWRTY2hlbWFNZXRhZGF0YShcInN0cnVjdHVyZVNxbFwiLCBhc3luYyAoKSA9PiBhd2FpdCBuZXcgU3RydWN0dXJlU3FsKHtkcml2ZXI6IHRoaXN9KS50b1NxbCgpKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgbGFzdCBpbnNlcnQgaWQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPG51bWJlcj59IC0gUmVzb2x2ZXMgd2l0aCB0aGUgbGFzdCBpbnNlcnQgaWQuXG4gICAqL1xuICBhc3luYyBsYXN0SW5zZXJ0SUQoKSB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5xdWVyeShcIlNFTEVDVCBMQVNUX0lOU0VSVF9JRCgpIEFTIGxhc3RfaW5zZXJ0X2lkXCIpXG5cbiAgICByZXR1cm4gZGlnZyhyZXN1bHQsIDAsIFwibGFzdF9pbnNlcnRfaWRcIilcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIG9wdGlvbnMuXG4gICAqIEByZXR1cm5zIHtPcHRpb25zfSAtIFRoZSBvcHRpb25zIG9wdGlvbnMuXG4gICAqL1xuICBvcHRpb25zKCkge1xuICAgIGlmICghdGhpcy5fb3B0aW9ucykgdGhpcy5fb3B0aW9ucyA9IG5ldyBPcHRpb25zKHtkcml2ZXI6IHRoaXN9KVxuXG4gICAgcmV0dXJuIHRoaXMuX29wdGlvbnNcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHN0YXJ0IHRyYW5zYWN0aW9uIGFjdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIF9zdGFydFRyYW5zYWN0aW9uQWN0aW9uKCkge1xuICAgIGF3YWl0IHRoaXMucXVlcnkoXCJTVEFSVCBUUkFOU0FDVElPTlwiKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgdXBkYXRlIHNxbC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9iYXNlLmpzXCIpLlVwZGF0ZVNxbEFyZ3NUeXBlfSBhcmdzIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IC0gU1FMIHN0cmluZy5cbiAgICovXG4gIHVwZGF0ZVNxbCh7Y29uZGl0aW9ucywgZGF0YSwgdGFibGVOYW1lfSkge1xuICAgIGNvbnN0IHVwZGF0ZSA9IG5ldyBVcGRhdGUoe2NvbmRpdGlvbnMsIGRhdGEsIGRyaXZlcjogdGhpcywgdGFibGVOYW1lfSlcblxuICAgIHJldHVybiB1cGRhdGUudG9TcWwoKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgdXBzZXJ0IHNxbC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9iYXNlLmpzXCIpLlVwc2VydFNxbEFyZ3NUeXBlfSBhcmdzIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IC0gU1FMIHN0cmluZy5cbiAgICovXG4gIHVwc2VydFNxbChhcmdzKSB7XG4gICAgY29uc3QgdXBzZXJ0ID0gbmV3IFVwc2VydCh7Li4uYXJncywgZHJpdmVyOiB0aGlzfSlcblxuICAgIHJldHVybiB1cHNlcnQudG9TcWwoKVxuICB9XG5cbiAgLyoqXG4gICAqIEJsb2NrcyB1bnRpbCBhIE15U1FML01hcmlhREIgdXNlci1sZXZlbCBsb2NrIGlzIGFjcXVpcmVkIG9uIHRoaXNcbiAgICogY29ubmVjdGlvbi4gSW1wbGVtZW50ZWQgdmlhIGBHRVRfTE9DSyhuYW1lLCB0aW1lb3V0KWAsIHdoZXJlIHRoZVxuICAgKiB0aW1lb3V0IGlzIGluIHNlY29uZHMuXG4gICAqXG4gICAqIE15U1FMIGhpc3RvcmljYWxseSBkb2N1bWVudGVkIGEgbmVnYXRpdmUgdGltZW91dCBhcyBcImluZmluaXRlXCIsXG4gICAqIGJ1dCBNYXJpYURCIDEwKyBzaWxlbnRseSByZWplY3RzIG5lZ2F0aXZlIHRpbWVvdXRzIGFuZCByZXR1cm5zXG4gICAqIGBOVUxMYCBmcm9tIGBHRVRfTE9DS2AuIFRvIG1ha2UgdGhlIGhlbHBlciBwb3J0YWJsZSBhY3Jvc3MgTXlTUUxcbiAgICogYW5kIE1hcmlhREIgdGhlIFwiaW5kZWZpbml0ZVwiIGNhc2UgaXMgZW5jb2RlZCBhcyBhIGxhcmdlIHBvc2l0aXZlXG4gICAqIHRpbWVvdXQgKG9uZSB5ZWFyKSwgd2hpY2ggaXMgY29tZm9ydGFibHkgbG9uZ2VyIHRoYW4gYW55XG4gICAqIHJlYWxpc3RpYyBjcml0aWNhbCBzZWN0aW9uIGFuZCB3b3JrcyBvbiBldmVyeSBzdXBwb3J0ZWQgdmVyc2lvbi5cbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBMb2NrIG5hbWUuXG4gICAqIEBwYXJhbSB7e3RpbWVvdXRNcz86IG51bWJlciB8IG51bGx9fSBbYXJnc10gLSBPcHRpb25hbCB0aW1lb3V0IGluIG1pbGxpc2Vjb25kczsgYG51bGxgLCBgdW5kZWZpbmVkYCwgb3IgbmVnYXRpdmUgYmxvY2tzIGZvciBgTVlTUUxfSU5ERUZJTklURV9MT0NLX1RJTUVPVVRfU0VDT05EU2AuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGJvb2xlYW4+fSAtIFRydWUgaWYgYWNxdWlyZWQsIGZhbHNlIGlmIHRoZSB0aW1lb3V0IGVsYXBzZWQuXG4gICAqL1xuICBhc3luYyBhY3F1aXJlQWR2aXNvcnlMb2NrKG5hbWUsIHt0aW1lb3V0TXN9ID0ge30pIHtcbiAgICBjb25zdCB0aW1lb3V0U2Vjb25kcyA9IHR5cGVvZiB0aW1lb3V0TXMgPT09IFwibnVtYmVyXCIgJiYgdGltZW91dE1zID49IDBcbiAgICAgID8gTWF0aC5jZWlsKHRpbWVvdXRNcyAvIDEwMDApXG4gICAgICA6IE1ZU1FMX0lOREVGSU5JVEVfTE9DS19USU1FT1VUX1NFQ09ORFNcbiAgICBjb25zdCByb3dzID0gYXdhaXQgdGhpcy5xdWVyeShgU0VMRUNUIEdFVF9MT0NLKCR7dGhpcy5xdW90ZShuYW1lKX0sICR7dGltZW91dFNlY29uZHN9KSBBUyB2ZWxvY2lvdXNfYWR2aXNvcnlfbG9ja19yZXN1bHRgKVxuICAgIGNvbnN0IHJlc3VsdCA9IHJvd3M/LlswXT8udmVsb2Npb3VzX2Fkdmlzb3J5X2xvY2tfcmVzdWx0XG5cbiAgICBpZiAocmVzdWx0ID09PSBudWxsIHx8IHJlc3VsdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEdFVF9MT0NLIHJldHVybmVkIE5VTEwgZm9yIGFkdmlzb3J5IGxvY2sgJHtKU09OLnN0cmluZ2lmeShuYW1lKX0gKHR5cGljYWxseSBhbiBvdXQtb2YtbWVtb3J5IG9yIHRocmVhZC1raWxsZWQgY29uZGl0aW9uKWApXG4gICAgfVxuXG4gICAgcmV0dXJuIE51bWJlcihyZXN1bHQpID09PSAxXG4gIH1cblxuICAvKipcbiAgICogUnVucyB0cnkgYWNxdWlyZSBhZHZpc29yeSBsb2NrLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIExvY2sgbmFtZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8Ym9vbGVhbj59IC0gVHJ1ZSBpZiB0aGUgbG9jayB3YXMgYWNxdWlyZWQsIGZhbHNlIGlmIGl0IHdhcyBhbHJlYWR5IGhlbGQuXG4gICAqL1xuICBhc3luYyB0cnlBY3F1aXJlQWR2aXNvcnlMb2NrKG5hbWUpIHtcbiAgICBjb25zdCByb3dzID0gYXdhaXQgdGhpcy5xdWVyeShgU0VMRUNUIEdFVF9MT0NLKCR7dGhpcy5xdW90ZShuYW1lKX0sIDApIEFTIHZlbG9jaW91c19hZHZpc29yeV9sb2NrX3Jlc3VsdGApXG4gICAgY29uc3QgcmVzdWx0ID0gcm93cz8uWzBdPy52ZWxvY2lvdXNfYWR2aXNvcnlfbG9ja19yZXN1bHRcblxuICAgIGlmIChyZXN1bHQgPT09IG51bGwgfHwgcmVzdWx0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgR0VUX0xPQ0sgcmV0dXJuZWQgTlVMTCBmb3IgYWR2aXNvcnkgbG9jayAke0pTT04uc3RyaW5naWZ5KG5hbWUpfSAodHlwaWNhbGx5IGFuIG91dC1vZi1tZW1vcnkgb3IgdGhyZWFkLWtpbGxlZCBjb25kaXRpb24pYClcbiAgICB9XG5cbiAgICByZXR1cm4gTnVtYmVyKHJlc3VsdCkgPT09IDFcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHJlbGVhc2UgYWR2aXNvcnkgbG9jay5cbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBMb2NrIG5hbWUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGJvb2xlYW4+fSAtIFRydWUgaWYgdGhlIGxvY2sgd2FzIGhlbGQgYnkgdGhpcyBzZXNzaW9uIGFuZCBoYXMgbm93IGJlZW4gcmVsZWFzZWQuXG4gICAqL1xuICBhc3luYyByZWxlYXNlQWR2aXNvcnlMb2NrKG5hbWUpIHtcbiAgICBjb25zdCByb3dzID0gYXdhaXQgdGhpcy5xdWVyeShgU0VMRUNUIFJFTEVBU0VfTE9DSygke3RoaXMucXVvdGUobmFtZSl9KSBBUyB2ZWxvY2lvdXNfYWR2aXNvcnlfbG9ja19yZXN1bHRgKVxuICAgIGNvbnN0IHJlc3VsdCA9IHJvd3M/LlswXT8udmVsb2Npb3VzX2Fkdmlzb3J5X2xvY2tfcmVzdWx0XG5cbiAgICByZXR1cm4gTnVtYmVyKHJlc3VsdCkgPT09IDFcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGlzIGFkdmlzb3J5IGxvY2sgaGVsZC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBMb2NrIG5hbWUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGJvb2xlYW4+fSAtIFRydWUgaWYgYW55IHNlc3Npb24gY3VycmVudGx5IGhvbGRzIHRoZSBsb2NrLlxuICAgKi9cbiAgYXN5bmMgaXNBZHZpc29yeUxvY2tIZWxkKG5hbWUpIHtcbiAgICBjb25zdCByb3dzID0gYXdhaXQgdGhpcy5xdWVyeShgU0VMRUNUIElTX1VTRURfTE9DSygke3RoaXMucXVvdGUobmFtZSl9KSBBUyB2ZWxvY2lvdXNfYWR2aXNvcnlfbG9ja19ob2xkZXJgKVxuICAgIGNvbnN0IGhvbGRlciA9IHJvd3M/LlswXT8udmVsb2Npb3VzX2Fkdmlzb3J5X2xvY2tfaG9sZGVyXG5cbiAgICByZXR1cm4gaG9sZGVyICE9PSBudWxsICYmIGhvbGRlciAhPT0gdW5kZWZpbmVkXG4gIH1cbn1cbiJdfQ==
|
|
521
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvZGF0YWJhc2UvZHJpdmVycy9teXNxbC9pbmRleC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxVQUFVLE1BQU0sc0JBQXNCLENBQUE7QUFDN0MsT0FBTyxJQUFJLE1BQU0sWUFBWSxDQUFBO0FBQzdCLE9BQU8sY0FBYyxNQUFNLDBCQUEwQixDQUFBO0FBQ3JELE9BQU8sV0FBVyxNQUFNLHVCQUF1QixDQUFBO0FBQy9DLE9BQU8sV0FBVyxNQUFNLHVCQUF1QixDQUFBO0FBQy9DLE9BQU8sTUFBTSxNQUFNLGlCQUFpQixDQUFBO0FBQ3BDLE9BQU8sRUFBQyxJQUFJLEVBQUMsTUFBTSxXQUFXLENBQUE7QUFDOUIsT0FBTyxZQUFZLE1BQU0sd0JBQXdCLENBQUE7QUFDakQsT0FBTyxTQUFTLE1BQU0scUJBQXFCLENBQUE7QUFDM0MsT0FBTyxNQUFNLE1BQU0saUJBQWlCLENBQUE7QUFDcEMsT0FBTyxPQUFPLE1BQU0sY0FBYyxDQUFBO0FBQ2xDLE9BQU8sS0FBSyxNQUFNLE9BQU8sQ0FBQTtBQUN6QixPQUFPLEtBQUssTUFBTSxZQUFZLENBQUE7QUFDOUIsT0FBTyxXQUFXLE1BQU0sbUJBQW1CLENBQUE7QUFDM0MsT0FBTyxXQUFXLE1BQU0sdUJBQXVCLENBQUE7QUFDL0MsT0FBTyxLQUFLLE1BQU0sWUFBWSxDQUFBO0FBQzlCLE9BQU8sWUFBWSxNQUFNLG9CQUFvQixDQUFBO0FBQzdDLE9BQU8sTUFBTSxNQUFNLGlCQUFpQixDQUFBO0FBQ3BDLE9BQU8sTUFBTSxNQUFNLGlCQUFpQixDQUFBO0FBRXBDOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLHFDQUFxQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQTtBQUVoRSxNQUFNLENBQUMsT0FBTyxPQUFPLDZCQUE4QixTQUFRLElBQUk7SUFDN0QsK0NB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LENBQUE7UUFFeEQsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQzdCLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsS0FBSyxDQUFDLGtCQUFrQixDQUFDLElBQUk7UUFDM0IsTUFBTSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLHVCQUF1QixJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFBO1FBQzNHLE1BQU0sTUFBTSxHQUFHLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLDhCQUE4QixDQUFBO1FBRXhELE9BQU8sTUFBTSxLQUFLLElBQUksSUFBSSxNQUFNLEtBQUssU0FBUyxDQUFBO0lBQ2hELENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgQWx0ZXJUYWJsZSBmcm9tIFwiLi9zcWwvYWx0ZXItdGFibGUuanNcIlxuaW1wb3J0IEJhc2UgZnJvbSBcIi4uL2Jhc2UuanNcIlxuaW1wb3J0IENyZWF0ZURhdGFiYXNlIGZyb20gXCIuL3NxbC9jcmVhdGUtZGF0YWJhc2UuanNcIlxuaW1wb3J0IENyZWF0ZUluZGV4IGZyb20gXCIuL3NxbC9jcmVhdGUtaW5kZXguanNcIlxuaW1wb3J0IENyZWF0ZVRhYmxlIGZyb20gXCIuL3NxbC9jcmVhdGUtdGFibGUuanNcIlxuaW1wb3J0IERlbGV0ZSBmcm9tIFwiLi9zcWwvZGVsZXRlLmpzXCJcbmltcG9ydCB7ZGlnZ30gZnJvbSBcImRpZ2dlcml6ZVwiXG5pbXBvcnQgRHJvcERhdGFiYXNlIGZyb20gXCIuL3NxbC9kcm9wLWRhdGFiYXNlLmpzXCJcbmltcG9ydCBEcm9wVGFibGUgZnJvbSBcIi4vc3FsL2Ryb3AtdGFibGUuanNcIlxuaW1wb3J0IEluc2VydCBmcm9tIFwiLi9zcWwvaW5zZXJ0LmpzXCJcbmltcG9ydCBPcHRpb25zIGZyb20gXCIuL29wdGlvbnMuanNcIlxuaW1wb3J0IG15c3FsIGZyb20gXCJteXNxbFwiXG5pbXBvcnQgcXVlcnkgZnJvbSBcIi4vcXVlcnkuanNcIlxuaW1wb3J0IFF1ZXJ5UGFyc2VyIGZyb20gXCIuL3F1ZXJ5LXBhcnNlci5qc1wiXG5pbXBvcnQgUmVtb3ZlSW5kZXggZnJvbSBcIi4vc3FsL3JlbW92ZS1pbmRleC5qc1wiXG5pbXBvcnQgVGFibGUgZnJvbSBcIi4vdGFibGUuanNcIlxuaW1wb3J0IFN0cnVjdHVyZVNxbCBmcm9tIFwiLi9zdHJ1Y3R1cmUtc3FsLmpzXCJcbmltcG9ydCBVcHNlcnQgZnJvbSBcIi4vc3FsL3Vwc2VydC5qc1wiXG5pbXBvcnQgVXBkYXRlIGZyb20gXCIuL3NxbC91cGRhdGUuanNcIlxuXG4vKipcbiAqIFNlbnRpbmVsIHRpbWVvdXQgKGluIHNlY29uZHMpIHVzZWQgYXMgdGhlIFwiYmxvY2sgZm9yZXZlclwiIHZhbHVlIHdoZW4gYVxuICogY2FsbGVyIGFza3MgZm9yIGFuIGluZGVmaW5pdGUgYWR2aXNvcnkgbG9jayBhY3F1aXJlLiBNeVNRTCBoaXN0b3JpY2FsbHlcbiAqIGFjY2VwdGVkIG5lZ2F0aXZlIHRpbWVvdXRzIGFzIFwiaW5maW5pdGVcIiwgYnV0IE1hcmlhREIgMTArIHNpbGVudGx5XG4gKiByZXR1cm5zIE5VTEwgZnJvbSBgR0VUX0xPQ0tgIHdoZW4gdGhlIHRpbWVvdXQgaXMgbmVnYXRpdmUsIHNvIHRoZVxuICogZHJpdmVyIGNsYW1wcyB0byBhIGNvbWZvcnRhYmx5IGxhcmdlIHBvc2l0aXZlIHZhbHVlICgxIHllYXIg4omrIGFueVxuICogcmVhbGlzdGljIGNyaXRpY2FsIHNlY3Rpb24pIGluc3RlYWQuXG4gKi9cbmNvbnN0IE1ZU1FMX0lOREVGSU5JVEVfTE9DS19USU1FT1VUX1NFQ09ORFMgPSA2MCAqIDYwICogMjQgKiAzNjVcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVmVsb2Npb3VzRGF0YWJhc2VEcml2ZXJzTXlzcWwgZXh0ZW5kcyBCYXNle1xuICAvKiogQHR5cGUge2ltcG9ydChcIm15c3FsXCIpLlBvb2wgfCB1bmRlZmluZWR9ICovXG4gIHBvb2wgPSB1bmRlZmluZWRcblxuICAvKiogQHR5cGUge3N0cmluZyB8IG51bGx9ICovXG4gIF9kZXNpcmVkU2Vzc2lvblRpbWVab25lID0gXCIrMDA6MDBcIlxuXG4gIC8qKiBAdHlwZSB7c3RyaW5nIHwgbnVsbH0gKi9cbiAgX2N1cnJlbnRTZXNzaW9uVGltZVpvbmUgPSBudWxsXG5cbiAgLyoqXG4gICAqIFJ1bnMgY29ubmVjdC5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIGNvbm5lY3QoKSB7XG4gICAgdGhpcy5yZXNldEN1cnJlbnRTZXNzaW9uVGltZVpvbmUoKVxuICAgIHRoaXMucG9vbCA9IG15c3FsLmNyZWF0ZVBvb2woT2JqZWN0LmFzc2lnbih7Y29ubmVjdGlvbkxpbWl0OiAxfSwgdGhpcy5jb25uZWN0QXJncygpKSlcbiAgICB0aGlzLnBvb2wub24oXCJlcnJvclwiLCB0aGlzLm9uUG9vbEVycm9yKVxuICB9XG5cbiAgLyoqXG4gICAqIE9uIHBvb2wgZXJyb3IuXG4gICAqIEBwYXJhbSB7RXJyb3J9IGVycm9yIC0gRXJyb3IgZnJvbSB0aGUgY29ubmVjdGlvbiBhdHRlbXB0LlxuICAgKi9cbiAgb25Qb29sRXJyb3IgPSAoZXJyb3IpID0+IHtcbiAgICBjb25zb2xlLmVycm9yKFwiVmVsb2Npb3VzIC8gTXlTUUwgZHJpdmVyIC8gUG9vbCBlcnJvclwiLCBlcnJvcilcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGNsb3NlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgY2xvc2UoKSB7XG4gICAgYXdhaXQgdGhpcy5wb29sPy5lbmQoKVxuICAgIHRoaXMucG9vbCA9IHVuZGVmaW5lZFxuICAgIHRoaXMucmVzZXRDdXJyZW50U2Vzc2lvblRpbWVab25lKClcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHNldCBjb25uZWN0aW9uIGNoZWNrb3V0IG5hbWUuXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgdW5kZWZpbmVkfSBuYW1lIC0gSHVtYW4tcmVhZGFibGUgbmFtZSBmb3IgdGhpcyBhY3RpdmUgY2hlY2tvdXQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBzZXRDb25uZWN0aW9uQ2hlY2tvdXROYW1lKG5hbWUpIHtcbiAgICBjb25zdCBwcmV2aW91c05hbWUgPSB0aGlzLl9jb25uZWN0aW9uQ2hlY2tvdXROYW1lXG5cbiAgICBhd2FpdCBzdXBlci5zZXRDb25uZWN0aW9uQ2hlY2tvdXROYW1lKG5hbWUpXG5cbiAgICBpZiAobmFtZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAocHJldmlvdXNOYW1lICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5xdWVyeShcIlNFVCBAdmVsb2Npb3VzX2Nvbm5lY3Rpb25fY2hlY2tvdXRfbmFtZSA9IE5VTExcIiwge2xvZ05hbWU6IFwiQ2xlYXIgQ29ubmVjdGlvbiBDaGVja291dCBOYW1lXCIsIHByb2Nlc3NMaXN0Q29tbWVudDogZmFsc2UsIHNlc3Npb25UaW1lWm9uZTogZmFsc2V9KVxuICAgICAgfVxuXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLnF1ZXJ5KGBTRVQgQHZlbG9jaW91c19jb25uZWN0aW9uX2NoZWNrb3V0X25hbWUgPSAke3RoaXMucXVvdGUobmFtZSl9YCwge2xvZ05hbWU6IFwiU2V0IENvbm5lY3Rpb24gQ2hlY2tvdXQgTmFtZVwiLCBwcm9jZXNzTGlzdENvbW1lbnQ6IGZhbHNlLCBzZXNzaW9uVGltZVpvbmU6IGZhbHNlfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGNsZWFyIGNvbm5lY3Rpb24gY2hlY2tvdXQgbmFtZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIGNsZWFyQ29ubmVjdGlvbkNoZWNrb3V0TmFtZSgpIHtcbiAgICBpZiAodGhpcy5fY29ubmVjdGlvbkNoZWNrb3V0TmFtZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBhd2FpdCB0aGlzLnF1ZXJ5KFwiU0VUIEB2ZWxvY2lvdXNfY29ubmVjdGlvbl9jaGVja291dF9uYW1lID0gTlVMTFwiLCB7bG9nTmFtZTogXCJDbGVhciBDb25uZWN0aW9uIENoZWNrb3V0IE5hbWVcIiwgcHJvY2Vzc0xpc3RDb21tZW50OiBmYWxzZSwgc2Vzc2lvblRpbWVab25lOiBmYWxzZX0pXG4gICAgfVxuXG4gICAgYXdhaXQgc3VwZXIuY2xlYXJDb25uZWN0aW9uQ2hlY2tvdXROYW1lKClcbiAgfVxuXG4gIC8qKlxuICAgKiBIb29rIGJlZm9yZSBldmVyeSBxdWVyeS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IF9zcWwgLSBTUUwgc3RyaW5nLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Jhc2UuanNcIikuUXVlcnlPcHRpb25zfSBvcHRpb25zIC0gUXVlcnkgb3B0aW9ucy5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIGJlZm9yZVF1ZXJ5KF9zcWwsIG9wdGlvbnMpIHtcbiAgICBpZiAob3B0aW9ucy5zZXNzaW9uVGltZVpvbmUgIT09IGZhbHNlKSBhd2FpdCB0aGlzLmVuc3VyZVNlc3Npb25UaW1lWm9uZSgpXG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgZGVzaXJlZCBkYXRhYmFzZSBzZXNzaW9uIHRpbWUgem9uZSBmb3IgdGhpcyBjb25uZWN0aW9uIGNvbnRleHQuXG4gICAqIEByZXR1cm5zIHtzdHJpbmcgfCBudWxsfSAtIERlc2lyZWQgc2Vzc2lvbiB0aW1lIHpvbmUuXG4gICAqL1xuICBnZXREZXNpcmVkU2Vzc2lvblRpbWVab25lKCkge1xuICAgIHJldHVybiB0aGlzLl9kZXNpcmVkU2Vzc2lvblRpbWVab25lXG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgZGVzaXJlZCBkYXRhYmFzZSBzZXNzaW9uIHRpbWUgem9uZSB3aXRob3V0IHF1ZXJ5aW5nIE15U1FMIGltbWVkaWF0ZWx5LlxuICAgKiBAcGFyYW0ge3N0cmluZyB8IG51bGx9IHRpbWVab25lIC0gRGVzaXJlZCBzZXNzaW9uIHRpbWUgem9uZS5cbiAgICovXG4gIHNldERlc2lyZWRTZXNzaW9uVGltZVpvbmUodGltZVpvbmUpIHtcbiAgICB0aGlzLl9kZXNpcmVkU2Vzc2lvblRpbWVab25lID0gdGltZVpvbmVcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBkYXRhYmFzZSBzZXNzaW9uIHRpbWUgem9uZSBsYXN0IGNvbmZpcm1lZCB0aHJvdWdoIFNFVCB0aW1lX3pvbmUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmcgfCBudWxsfSAtIEN1cnJlbnQga25vd24gc2Vzc2lvbiB0aW1lIHpvbmUuXG4gICAqL1xuICBnZXRDdXJyZW50U2Vzc2lvblRpbWVab25lKCkge1xuICAgIHJldHVybiB0aGlzLl9jdXJyZW50U2Vzc2lvblRpbWVab25lXG4gIH1cblxuICAvKipcbiAgICogQ2xlYXJzIHRoZSBjdXJyZW50IGtub3duIGRhdGFiYXNlIHNlc3Npb24gdGltZSB6b25lIHdoZW4gdGhlIHBoeXNpY2FsIGNvbm5lY3Rpb24gY2hhbmdlcy5cbiAgICovXG4gIHJlc2V0Q3VycmVudFNlc3Npb25UaW1lWm9uZSgpIHtcbiAgICB0aGlzLl9jdXJyZW50U2Vzc2lvblRpbWVab25lID0gbnVsbFxuICB9XG5cbiAgLyoqXG4gICAqIEVuc3VyZXMgTXlTUUwgaGFzIHRoZSBkZXNpcmVkIHNlc3Npb24gdGltZSB6b25lIGJlZm9yZSB1c2VyIFNRTCBydW5zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gLSBUcnVlIHdoZW4gU0VUIHRpbWVfem9uZSB3YXMgZXhlY3V0ZWQuXG4gICAqL1xuICBhc3luYyBlbnN1cmVTZXNzaW9uVGltZVpvbmUoKSB7XG4gICAgY29uc3QgZGVzaXJlZFNlc3Npb25UaW1lWm9uZSA9IHRoaXMuZ2V0RGVzaXJlZFNlc3Npb25UaW1lWm9uZSgpXG5cbiAgICBpZiAoZGVzaXJlZFNlc3Npb25UaW1lWm9uZSA9PT0gbnVsbCB8fCB0aGlzLmdldEN1cnJlbnRTZXNzaW9uVGltZVpvbmUoKSA9PT0gZGVzaXJlZFNlc3Npb25UaW1lWm9uZSkgcmV0dXJuIGZhbHNlXG5cbiAgICBhd2FpdCB0aGlzLnNldFNlc3Npb25UaW1lWm9uZShkZXNpcmVkU2Vzc2lvblRpbWVab25lKVxuXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBkYXRhYmFzZSBzZXNzaW9uIHRpbWUgem9uZSBpZiBpdCBjaGFuZ2VkIGZyb20gdGhlIGxhc3QgY29uZmlybWVkIHZhbHVlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGltZVpvbmUgLSBTZXNzaW9uIHRpbWUgem9uZSB2YWx1ZSBhY2NlcHRlZCBieSBNeVNRTC5cbiAgICogQHJldHVybnMge1Byb21pc2U8Ym9vbGVhbj59IC0gVHJ1ZSB3aGVuIFNFVCB0aW1lX3pvbmUgd2FzIGV4ZWN1dGVkLlxuICAgKi9cbiAgYXN5bmMgc2V0U2Vzc2lvblRpbWVab25lKHRpbWVab25lKSB7XG4gICAgaWYgKHRoaXMuZ2V0Q3VycmVudFNlc3Npb25UaW1lWm9uZSgpID09PSB0aW1lWm9uZSkgcmV0dXJuIGZhbHNlXG5cbiAgICBhd2FpdCB0aGlzLl9xdWVyeUFjdHVhbChgU0VUIHRpbWVfem9uZSA9ICR7dGhpcy5xdW90ZSh0aW1lWm9uZSl9YClcbiAgICB0aGlzLl9jdXJyZW50U2Vzc2lvblRpbWVab25lID0gdGltZVpvbmVcblxuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICAvKipcbiAgICogUnVucyBjb25uZWN0IGFyZ3MuXG4gICAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gLSBUaGUgY29ubmVjdCBhcmdzLlxuICAgKi9cbiAgY29ubmVjdEFyZ3MoKSB7XG4gICAgY29uc3QgYXJncyA9IHRoaXMuZ2V0QXJncygpXG4gICAgY29uc3QgZm9yd2FyZCA9IFtcImRhdGFiYXNlXCIsIFwiaG9zdFwiLCBcInBhc3N3b3JkXCJdXG5cbiAgICAvKipcbiAgICAgKiBDb25uZWN0IGFyZ3MuXG4gICAgICogQHR5cGUge1JlY29yZDxzdHJpbmcsID8+fSAqL1xuICAgIGNvbnN0IGNvbm5lY3RBcmdzID0ge2NoYXJzZXQ6IFwidXRmOG1iNFwiLCB0aW1lem9uZTogXCJaXCJ9XG5cbiAgICBmb3IgKGNvbnN0IGZvcndhcmRWYWx1ZSBvZiBmb3J3YXJkKSB7XG4gICAgICBpZiAoZm9yd2FyZFZhbHVlIGluIGFyZ3MpIGNvbm5lY3RBcmdzW2ZvcndhcmRWYWx1ZV0gPSBkaWdnKGFyZ3MsIGZvcndhcmRWYWx1ZSlcbiAgICB9XG5cbiAgICBpZiAoXCJ1c2VybmFtZVwiIGluIGFyZ3MpIGNvbm5lY3RBcmdzW1widXNlclwiXSA9IGFyZ3NbXCJ1c2VybmFtZVwiXVxuICAgIGlmIChcImNoYXJzZXRcIiBpbiBhcmdzKSBjb25uZWN0QXJnc1tcImNoYXJzZXRcIl0gPSBhcmdzW1wiY2hhcnNldFwiXVxuXG4gICAgcmV0dXJuIGNvbm5lY3RBcmdzXG4gIH1cblxuICAvKipcbiAgICogUnVucyBhbHRlciB0YWJsZSBzcWxzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL3RhYmxlLWRhdGEvaW5kZXguanNcIikuZGVmYXVsdH0gdGFibGVEYXRhIC0gVGFibGUgZGF0YS5cbiAgICogQHJldHVybnMge1Byb21pc2U8c3RyaW5nW10+fSAtIFJlc29sdmVzIHdpdGggU1FMIHN0YXRlbWVudHMuXG4gICAqL1xuICBhc3luYyBhbHRlclRhYmxlU1FMcyh0YWJsZURhdGEpIHtcbiAgICBjb25zdCBhbHRlckFyZ3MgPSB7dGFibGVEYXRhLCBkcml2ZXI6IHRoaXN9XG4gICAgY29uc3QgYWx0ZXJUYWJsZSA9IG5ldyBBbHRlclRhYmxlKGFsdGVyQXJncylcblxuICAgIHJldHVybiBhd2FpdCBhbHRlclRhYmxlLnRvU1FMcygpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBjcmVhdGUgZGF0YWJhc2Ugc3FsLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZGF0YWJhc2VOYW1lIC0gRGF0YWJhc2UgbmFtZS5cbiAgICogQHBhcmFtIHtvYmplY3R9IFthcmdzXSAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFthcmdzLmlmTm90RXhpc3RzXSAtIFdoZXRoZXIgaWYgbm90IGV4aXN0cy5cbiAgICogQHJldHVybnMge3N0cmluZ1tdfSAtIFNRTCBzdGF0ZW1lbnRzLlxuICAgKi9cbiAgY3JlYXRlRGF0YWJhc2VTcWwoZGF0YWJhc2VOYW1lLCBhcmdzKSB7XG4gICAgY29uc3QgY3JlYXRlQXJncyA9IE9iamVjdC5hc3NpZ24oe2RhdGFiYXNlTmFtZSwgZHJpdmVyOiB0aGlzfSwgYXJncylcbiAgICBjb25zdCBjcmVhdGVEYXRhYmFzZSA9IG5ldyBDcmVhdGVEYXRhYmFzZShjcmVhdGVBcmdzKVxuXG4gICAgcmV0dXJuIGNyZWF0ZURhdGFiYXNlLnRvU3FsKClcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGRyb3AgZGF0YWJhc2Ugc3FsLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZGF0YWJhc2VOYW1lIC0gRGF0YWJhc2UgbmFtZS5cbiAgICogQHBhcmFtIHtvYmplY3R9IFthcmdzXSAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFthcmdzLmlmRXhpc3RzXSAtIFdoZXRoZXIgaWYgZXhpc3RzLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nW119IC0gU1FMIHN0YXRlbWVudHMuXG4gICAqL1xuICBkcm9wRGF0YWJhc2VTcWwoZGF0YWJhc2VOYW1lLCBhcmdzKSB7XG4gICAgY29uc3QgZHJvcEFyZ3MgPSBPYmplY3QuYXNzaWduKHtkYXRhYmFzZU5hbWUsIGRyaXZlcjogdGhpc30sIGFyZ3MpXG4gICAgY29uc3QgZHJvcERhdGFiYXNlID0gbmV3IERyb3BEYXRhYmFzZShkcm9wQXJncylcblxuICAgIHJldHVybiBkcm9wRGF0YWJhc2UudG9TcWwoKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgY3JlYXRlIGluZGV4IHNxbHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vYmFzZS5qc1wiKS5DcmVhdGVJbmRleFNxbEFyZ3N9IGluZGV4RGF0YSAtIEluZGV4IGRhdGEuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHN0cmluZ1tdPn0gLSBSZXNvbHZlcyB3aXRoIFNRTCBzdGF0ZW1lbnRzLlxuICAgKi9cbiAgYXN5bmMgY3JlYXRlSW5kZXhTUUxzKGluZGV4RGF0YSkge1xuICAgIGNvbnN0IGNyZWF0ZUFyZ3MgPSBPYmplY3QuYXNzaWduKHtkcml2ZXI6IHRoaXN9LCBpbmRleERhdGEpXG4gICAgY29uc3QgY3JlYXRlSW5kZXggPSBuZXcgQ3JlYXRlSW5kZXgoY3JlYXRlQXJncylcblxuICAgIHJldHVybiBhd2FpdCBjcmVhdGVJbmRleC50b1NRTHMoKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcmVtb3ZlIGluZGV4IHNxbHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vYmFzZS5qc1wiKS5SZW1vdmVJbmRleFNxbEFyZ3N9IGluZGV4RGF0YSAtIEluZGV4IGRhdGEuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHN0cmluZ1tdPn0gLSBSZXNvbHZlcyB3aXRoIFNRTCBzdGF0ZW1lbnRzLlxuICAgKi9cbiAgYXN5bmMgcmVtb3ZlSW5kZXhTUUxzKGluZGV4RGF0YSkge1xuICAgIGNvbnN0IHJlbW92ZUFyZ3MgPSBPYmplY3QuYXNzaWduKHtkcml2ZXI6IHRoaXN9LCBpbmRleERhdGEpXG4gICAgY29uc3QgcmVtb3ZlSW5kZXggPSBuZXcgUmVtb3ZlSW5kZXgocmVtb3ZlQXJncylcblxuICAgIHJldHVybiBhd2FpdCByZW1vdmVJbmRleC50b1NRTHMoKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgY3JlYXRlIHRhYmxlIHNxbC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi90YWJsZS1kYXRhL2luZGV4LmpzXCIpLmRlZmF1bHR9IHRhYmxlRGF0YSAtIFRhYmxlIGRhdGEuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHN0cmluZ1tdPn0gLSBSZXNvbHZlcyB3aXRoIFNRTCBzdGF0ZW1lbnRzLlxuICAgKi9cbiAgYXN5bmMgY3JlYXRlVGFibGVTcWwodGFibGVEYXRhKSB7XG4gICAgY29uc3QgY3JlYXRlQXJncyA9IHt0YWJsZURhdGEsIGRyaXZlcjogdGhpc31cbiAgICBjb25zdCBjcmVhdGVUYWJsZSA9IG5ldyBDcmVhdGVUYWJsZShjcmVhdGVBcmdzKVxuXG4gICAgcmV0dXJuIGNyZWF0ZVRhYmxlLnRvU3FsKClcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGN1cnJlbnQgZGF0YWJhc2UuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHN0cmluZz59IC0gUmVzb2x2ZXMgd2l0aCB0aGUgY3VycmVudCBkYXRhYmFzZS5cbiAgICovXG4gIGFzeW5jIGN1cnJlbnREYXRhYmFzZSgpIHtcbiAgICBjb25zdCByb3dzID0gYXdhaXQgdGhpcy5xdWVyeShcIlNFTEVDVCBEQVRBQkFTRSgpIEFTIGRiX25hbWVcIilcblxuICAgIHJldHVybiBkaWdnKHJvd3MsIDAsIFwiZGJfbmFtZVwiKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZGlzYWJsZSBmb3JlaWduIGtleXMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBkaXNhYmxlRm9yZWlnbktleXMoKSB7XG4gICAgYXdhaXQgdGhpcy5xdWVyeShcIlNFVCBGT1JFSUdOX0tFWV9DSEVDS1MgPSAwXCIpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBlbmFibGUgZm9yZWlnbiBrZXlzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgZW5hYmxlRm9yZWlnbktleXMoKSB7XG4gICAgYXdhaXQgdGhpcy5xdWVyeShcIlNFVCBGT1JFSUdOX0tFWV9DSEVDS1MgPSAxXCIpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBkcm9wIHRhYmxlIHNxbHMuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0YWJsZU5hbWUgLSBUYWJsZSBuYW1lLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Jhc2UuanNcIikuRHJvcFRhYmxlU3FsQXJnc1R5cGV9IFthcmdzXSAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmdbXT59IC0gUmVzb2x2ZXMgd2l0aCBTUUwgc3RhdGVtZW50cy5cbiAgICovXG4gIGFzeW5jIGRyb3BUYWJsZVNRTHModGFibGVOYW1lLCBhcmdzID0ge30pIHtcbiAgICBjb25zdCBkcm9wQXJncyA9IE9iamVjdC5hc3NpZ24oe3RhYmxlTmFtZSwgZHJpdmVyOiB0aGlzfSwgYXJncylcbiAgICBjb25zdCBkcm9wVGFibGUgPSBuZXcgRHJvcFRhYmxlKGRyb3BBcmdzKVxuXG4gICAgcmV0dXJuIGF3YWl0IGRyb3BUYWJsZS50b1NRTHMoKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZ2V0IHR5cGUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IC0gVGhlIHR5cGUuXG4gICAqL1xuICBnZXRUeXBlKCkgeyByZXR1cm4gXCJteXNxbFwiIH1cblxuICAvKipcbiAgICogUnVucyByZXRyeWFibGUgZGF0YWJhc2UgZXJyb3IuXG4gICAqIEBwYXJhbSB7RXJyb3J9IGVycm9yIC0gRXJyb3IgaW5zdGFuY2UuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9iYXNlLmpzXCIpLlJldHJ5YWJsZURhdGFiYXNlRXJyb3JSZXN1bHR9IC0gUmV0cnkgaW5mby5cbiAgICovXG4gIHJldHJ5YWJsZURhdGFiYXNlRXJyb3IoZXJyb3IpIHtcbiAgICAvKiogQHR5cGUge0Vycm9yIHwgdW5kZWZpbmVkfSAqL1xuICAgIGxldCBjdXJyZW50RXJyb3IgPSBlcnJvclxuICAgIGxldCBzaG91bGRSZWNvbm5lY3QgPSBmYWxzZVxuXG4gICAgd2hpbGUgKGN1cnJlbnRFcnJvcikge1xuICAgICAgY29uc3QgZXJyb3JDb2RlID0gXCJjb2RlXCIgaW4gY3VycmVudEVycm9yICYmIHR5cGVvZiBjdXJyZW50RXJyb3IuY29kZSA9PSBcInN0cmluZ1wiID8gY3VycmVudEVycm9yLmNvZGUgOiB1bmRlZmluZWRcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBjdXJyZW50RXJyb3IubWVzc2FnZSB8fCBcIlwiXG5cbiAgICAgIGlmIChlcnJvckNvZGUgPT0gXCJFUl9DSEVDS1JFQURcIiB8fCBtZXNzYWdlLmluY2x1ZGVzKFwiUmVjb3JkIGhhcyBjaGFuZ2VkIHNpbmNlIGxhc3QgcmVhZFwiKSkge1xuICAgICAgICByZXR1cm4ge3JldHJ5OiB0cnVlLCByZWNvbm5lY3Q6IGZhbHNlLCB3YWl0TXM6IDUwfVxuICAgICAgfVxuXG4gICAgICBzaG91bGRSZWNvbm5lY3QgfHw9IChcbiAgICAgICAgZXJyb3JDb2RlID09IFwiRUNPTk5SRUZVU0VEXCIgfHxcbiAgICAgICAgbWVzc2FnZS5pbmNsdWRlcyhcIkVDT05OUkVGVVNFRFwiKSB8fFxuICAgICAgICBtZXNzYWdlLmluY2x1ZGVzKFwiY29ubmVjdCBFQ09OTlJFRlVTRURcIikgfHxcbiAgICAgICAgbWVzc2FnZS5pbmNsdWRlcyhcIlBST1RPQ09MX0NPTk5FQ1RJT05fTE9TVFwiKSB8fFxuICAgICAgICBtZXNzYWdlLmluY2x1ZGVzKFwiQ29ubmVjdGlvbiBsb3N0XCIpXG4gICAgICApXG5cbiAgICAgIGN1cnJlbnRFcnJvciA9IGN1cnJlbnRFcnJvci5jYXVzZSBpbnN0YW5jZW9mIEVycm9yID8gY3VycmVudEVycm9yLmNhdXNlIDogdW5kZWZpbmVkXG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHJldHJ5OiBzaG91bGRSZWNvbm5lY3QsXG4gICAgICByZWNvbm5lY3Q6IHNob3VsZFJlY29ubmVjdCxcbiAgICAgIHdhaXRNczogNTBcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBxdWVyeSBhY3R1YWwuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzcWwgLSBTUUwgc3RyaW5nLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxpbXBvcnQoXCIuLi9iYXNlLmpzXCIpLlF1ZXJ5UmVzdWx0VHlwZT59IC0gUmVzb2x2ZXMgd2l0aCB0aGUgcXVlcnkgYWN0dWFsLlxuICAgKi9cbiAgYXN5bmMgX3F1ZXJ5QWN0dWFsKHNxbCkge1xuICAgIGlmICghdGhpcy5wb29sKSBhd2FpdCB0aGlzLmNvbm5lY3QoKVxuICAgIGlmICghdGhpcy5wb29sKSB0aHJvdyBuZXcgRXJyb3IoXCJNeVNRTCBwb29sIGZhaWxlZCB0byBpbml0aWFsaXplXCIpXG5cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IHF1ZXJ5KHRoaXMucG9vbCwgc3FsKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBSZS10aHJvdyB0byB1bi1jb3JydXB0IHN0YWNrdHJhY2VcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgUXVlcnkgZmFpbGVkOiAke2Vycm9yLm1lc3NhZ2V9YCwge2NhdXNlOiBlcnJvcn0pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFF1ZXJ5IGZhaWxlZDogJHtlcnJvcn1gLCB7Y2F1c2U6IGVycm9yfSlcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRXhlY3V0ZXMgYSBtdXRhdGlvbiB3aXRoIGFmZmVjdGVkLXJvdyBtZXRhZGF0YS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHNxbCAtIE11dGF0aW9uIFNRTC5cbiAgICogQHJldHVybnMge1Byb21pc2U8bnVtYmVyPn0gLSBBZmZlY3RlZCByb3cgY291bnQuXG4gICAqL1xuICBhc3luYyBfYWZmZWN0ZWRSb3dzQWN0dWFsKHNxbCkge1xuICAgIGlmICghdGhpcy5wb29sKSBhd2FpdCB0aGlzLmNvbm5lY3QoKVxuICAgIGlmICghdGhpcy5wb29sKSB0aHJvdyBuZXcgRXJyb3IoXCJNeVNRTCBwb29sIGZhaWxlZCB0byBpbml0aWFsaXplXCIpXG4gICAgY29uc3QgcG9vbCA9IHRoaXMucG9vbFxuXG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHBvb2wucXVlcnkoc3FsLCAoZXJyb3IsIHJlc3VsdCkgPT4ge1xuICAgICAgICBpZiAoZXJyb3IpIHJlamVjdChlcnJvcilcbiAgICAgICAgZWxzZSByZXNvbHZlKFwiYWZmZWN0ZWRSb3dzXCIgaW4gcmVzdWx0ID8gcmVzdWx0LmFmZmVjdGVkUm93cyA6IDApXG4gICAgICB9KVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogUnVucyBxdWVyeSB0byBzcWwuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vcXVlcnkvaW5kZXguanNcIikuZGVmYXVsdH0gcXVlcnkgLSBRdWVyeSBpbnN0YW5jZS5cbiAgICogQHJldHVybnMge3N0cmluZ30gLSBTUUwgc3RyaW5nLlxuICAgKi9cbiAgcXVlcnlUb1NxbChxdWVyeSkgeyByZXR1cm4gbmV3IFF1ZXJ5UGFyc2VyKHtxdWVyeX0pLnRvU3FsKCkgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHNob3VsZCBzZXQgYXV0byBpbmNyZW1lbnQgd2hlbiBwcmltYXJ5IGtleS5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciBzZXQgYXV0byBpbmNyZW1lbnQgd2hlbiBwcmltYXJ5IGtleS5cbiAgICovXG4gIHNob3VsZFNldEF1dG9JbmNyZW1lbnRXaGVuUHJpbWFyeUtleSgpIHsgcmV0dXJuIHRydWUgfVxuICBzdXBwb3J0c0RlZmF1bHRQcmltYXJ5S2V5VVVJRCgpIHsgcmV0dXJuIGZhbHNlIH1cbiAgc3VwcG9ydHNDcm9zc0RhdGFiYXNlUmVmZXJlbmNlcygpIHsgcmV0dXJuIHRydWUgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGVzY2FwZS5cbiAgICogQHBhcmFtIHs/fSB2YWx1ZSAtIFZhbHVlIHRvIHVzZS5cbiAgICogQHJldHVybnMgez99IC0gVGhlIGVzY2FwZS5cbiAgICovXG4gIGVzY2FwZSh2YWx1ZSkge1xuICAgIGNvbnN0IGVzY2FwZWRWYWx1ZVdpdGhRdW90ZXMgPSB0aGlzLnBvb2xcbiAgICAgID8gdGhpcy5wb29sLmVzY2FwZSh0aGlzLl9jb252ZXJ0VmFsdWUodmFsdWUpKVxuICAgICAgOiBteXNxbC5lc2NhcGUodGhpcy5fY29udmVydFZhbHVlKHZhbHVlKSlcblxuICAgIHJldHVybiBlc2NhcGVkVmFsdWVXaXRoUXVvdGVzLnNsaWNlKDEsIGVzY2FwZWRWYWx1ZVdpdGhRdW90ZXMubGVuZ3RoIC0gMSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHF1b3RlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWUgLSBWYWx1ZSB0byB1c2UuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IC0gVGhlIHF1b3RlLlxuICAgKi9cbiAgcXVvdGUodmFsdWUpIHtcbiAgICBpZiAodGhpcy5wb29sKSB7XG4gICAgICByZXR1cm4gdGhpcy5wb29sLmVzY2FwZSh0aGlzLl9jb252ZXJ0VmFsdWUodmFsdWUpKVxuICAgIH1cblxuICAgIHJldHVybiBteXNxbC5lc2NhcGUodGhpcy5fY29udmVydFZhbHVlKHZhbHVlKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGRlbGV0ZSBzcWwuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vYmFzZS5qc1wiKS5EZWxldGVTcWxBcmdzVHlwZX0gYXJncyAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSAtIFNRTCBzdHJpbmcuXG4gICAqL1xuICBkZWxldGVTcWwoe3RhYmxlTmFtZSwgY29uZGl0aW9uc30pIHtcbiAgICBjb25zdCBkZWxldGVJbnN0cnVjdGlvbiA9IG5ldyBEZWxldGUoe2NvbmRpdGlvbnMsIGRyaXZlcjogdGhpcywgdGFibGVOYW1lfSlcblxuICAgIHJldHVybiBkZWxldGVJbnN0cnVjdGlvbi50b1NxbCgpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBpbnNlcnQgc3FsLlxuICAgKiBAYWJzdHJhY3RcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9iYXNlLmpzXCIpLkluc2VydFNxbEFyZ3NUeXBlfSBhcmdzIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IC0gU1FMIHN0cmluZy5cbiAgICovXG4gIGluc2VydFNxbChhcmdzKSB7XG4gICAgY29uc3QgaW5zZXJ0QXJncyA9IE9iamVjdC5hc3NpZ24oe2RyaXZlcjogdGhpc30sIGFyZ3MpXG4gICAgY29uc3QgaW5zZXJ0ID0gbmV3IEluc2VydChpbnNlcnRBcmdzKVxuXG4gICAgcmV0dXJuIGluc2VydC50b1NxbCgpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBnZXQgdGFibGVzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxBcnJheTxpbXBvcnQoXCIuLi9iYXNlLXRhYmxlLmpzXCIpLmRlZmF1bHQ+Pn0gLSBSZXNvbHZlcyB3aXRoIHRoZSB0YWJsZXMuXG4gICAqL1xuICBhc3luYyBnZXRUYWJsZXMoKSB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuX2NhY2hlZFNjaGVtYU1ldGFkYXRhKFwidGFibGVzXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMucXVlcnkoXCJTSE9XIEZVTEwgVEFCTEVTXCIpXG4gICAgICBjb25zdCB0YWJsZXMgPSBbXVxuXG4gICAgICBmb3IgKGNvbnN0IHJvdyBvZiByZXN1bHQpIHtcbiAgICAgICAgY29uc3QgdGFibGUgPSBuZXcgVGFibGUodGhpcywgLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+fSAqLyAocm93KSlcblxuICAgICAgICB0YWJsZXMucHVzaCh0YWJsZSlcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRhYmxlc1xuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogUnVucyBzdHJ1Y3R1cmUgc3FsLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmcgfCBudWxsPn0gLSBSZXNvbHZlcyB3aXRoIFNRTCBzdHJpbmcuXG4gICAqL1xuICBhc3luYyBzdHJ1Y3R1cmVTcWwoKSB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuX2NhY2hlZFNjaGVtYU1ldGFkYXRhKFwic3RydWN0dXJlU3FsXCIsIGFzeW5jICgpID0+IGF3YWl0IG5ldyBTdHJ1Y3R1cmVTcWwoe2RyaXZlcjogdGhpc30pLnRvU3FsKCkpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBsYXN0IGluc2VydCBpZC5cbiAgICogQHJldHVybnMge1Byb21pc2U8bnVtYmVyPn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBsYXN0IGluc2VydCBpZC5cbiAgICovXG4gIGFzeW5jIGxhc3RJbnNlcnRJRCgpIHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnF1ZXJ5KFwiU0VMRUNUIExBU1RfSU5TRVJUX0lEKCkgQVMgbGFzdF9pbnNlcnRfaWRcIilcblxuICAgIHJldHVybiBkaWdnKHJlc3VsdCwgMCwgXCJsYXN0X2luc2VydF9pZFwiKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgb3B0aW9ucy5cbiAgICogQHJldHVybnMge09wdGlvbnN9IC0gVGhlIG9wdGlvbnMgb3B0aW9ucy5cbiAgICovXG4gIG9wdGlvbnMoKSB7XG4gICAgaWYgKCF0aGlzLl9vcHRpb25zKSB0aGlzLl9vcHRpb25zID0gbmV3IE9wdGlvbnMoe2RyaXZlcjogdGhpc30pXG5cbiAgICByZXR1cm4gdGhpcy5fb3B0aW9uc1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgc3RhcnQgdHJhbnNhY3Rpb24gYWN0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgX3N0YXJ0VHJhbnNhY3Rpb25BY3Rpb24oKSB7XG4gICAgYXdhaXQgdGhpcy5xdWVyeShcIlNUQVJUIFRSQU5TQUNUSU9OXCIpXG4gIH1cblxuICAvKipcbiAgICogUnVucyB1cGRhdGUgc3FsLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Jhc2UuanNcIikuVXBkYXRlU3FsQXJnc1R5cGV9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHJldHVybnMge3N0cmluZ30gLSBTUUwgc3RyaW5nLlxuICAgKi9cbiAgdXBkYXRlU3FsKHtjb25kaXRpb25zLCBkYXRhLCB0YWJsZU5hbWV9KSB7XG4gICAgY29uc3QgdXBkYXRlID0gbmV3IFVwZGF0ZSh7Y29uZGl0aW9ucywgZGF0YSwgZHJpdmVyOiB0aGlzLCB0YWJsZU5hbWV9KVxuXG4gICAgcmV0dXJuIHVwZGF0ZS50b1NxbCgpXG4gIH1cblxuICAvKipcbiAgICogUnVucyB1cHNlcnQgc3FsLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Jhc2UuanNcIikuVXBzZXJ0U3FsQXJnc1R5cGV9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHJldHVybnMge3N0cmluZ30gLSBTUUwgc3RyaW5nLlxuICAgKi9cbiAgdXBzZXJ0U3FsKGFyZ3MpIHtcbiAgICBjb25zdCB1cHNlcnQgPSBuZXcgVXBzZXJ0KHsuLi5hcmdzLCBkcml2ZXI6IHRoaXN9KVxuXG4gICAgcmV0dXJuIHVwc2VydC50b1NxbCgpXG4gIH1cblxuICAvKipcbiAgICogQmxvY2tzIHVudGlsIGEgTXlTUUwvTWFyaWFEQiB1c2VyLWxldmVsIGxvY2sgaXMgYWNxdWlyZWQgb24gdGhpc1xuICAgKiBjb25uZWN0aW9uLiBJbXBsZW1lbnRlZCB2aWEgYEdFVF9MT0NLKG5hbWUsIHRpbWVvdXQpYCwgd2hlcmUgdGhlXG4gICAqIHRpbWVvdXQgaXMgaW4gc2Vjb25kcy5cbiAgICpcbiAgICogTXlTUUwgaGlzdG9yaWNhbGx5IGRvY3VtZW50ZWQgYSBuZWdhdGl2ZSB0aW1lb3V0IGFzIFwiaW5maW5pdGVcIixcbiAgICogYnV0IE1hcmlhREIgMTArIHNpbGVudGx5IHJlamVjdHMgbmVnYXRpdmUgdGltZW91dHMgYW5kIHJldHVybnNcbiAgICogYE5VTExgIGZyb20gYEdFVF9MT0NLYC4gVG8gbWFrZSB0aGUgaGVscGVyIHBvcnRhYmxlIGFjcm9zcyBNeVNRTFxuICAgKiBhbmQgTWFyaWFEQiB0aGUgXCJpbmRlZmluaXRlXCIgY2FzZSBpcyBlbmNvZGVkIGFzIGEgbGFyZ2UgcG9zaXRpdmVcbiAgICogdGltZW91dCAob25lIHllYXIpLCB3aGljaCBpcyBjb21mb3J0YWJseSBsb25nZXIgdGhhbiBhbnlcbiAgICogcmVhbGlzdGljIGNyaXRpY2FsIHNlY3Rpb24gYW5kIHdvcmtzIG9uIGV2ZXJ5IHN1cHBvcnRlZCB2ZXJzaW9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIExvY2sgbmFtZS5cbiAgICogQHBhcmFtIHt7dGltZW91dE1zPzogbnVtYmVyIHwgbnVsbH19IFthcmdzXSAtIE9wdGlvbmFsIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzOyBgbnVsbGAsIGB1bmRlZmluZWRgLCBvciBuZWdhdGl2ZSBibG9ja3MgZm9yIGBNWVNRTF9JTkRFRklOSVRFX0xPQ0tfVElNRU9VVF9TRUNPTkRTYC5cbiAgICogQHJldHVybnMge1Byb21pc2U8Ym9vbGVhbj59IC0gVHJ1ZSBpZiBhY3F1aXJlZCwgZmFsc2UgaWYgdGhlIHRpbWVvdXQgZWxhcHNlZC5cbiAgICovXG4gIGFzeW5jIGFjcXVpcmVBZHZpc29yeUxvY2sobmFtZSwge3RpbWVvdXRNc30gPSB7fSkge1xuICAgIGNvbnN0IHRpbWVvdXRTZWNvbmRzID0gdHlwZW9mIHRpbWVvdXRNcyA9PT0gXCJudW1iZXJcIiAmJiB0aW1lb3V0TXMgPj0gMFxuICAgICAgPyBNYXRoLmNlaWwodGltZW91dE1zIC8gMTAwMClcbiAgICAgIDogTVlTUUxfSU5ERUZJTklURV9MT0NLX1RJTUVPVVRfU0VDT05EU1xuICAgIGNvbnN0IHJvd3MgPSBhd2FpdCB0aGlzLnF1ZXJ5KGBTRUxFQ1QgR0VUX0xPQ0soJHt0aGlzLnF1b3RlKG5hbWUpfSwgJHt0aW1lb3V0U2Vjb25kc30pIEFTIHZlbG9jaW91c19hZHZpc29yeV9sb2NrX3Jlc3VsdGApXG4gICAgY29uc3QgcmVzdWx0ID0gcm93cz8uWzBdPy52ZWxvY2lvdXNfYWR2aXNvcnlfbG9ja19yZXN1bHRcblxuICAgIGlmIChyZXN1bHQgPT09IG51bGwgfHwgcmVzdWx0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgR0VUX0xPQ0sgcmV0dXJuZWQgTlVMTCBmb3IgYWR2aXNvcnkgbG9jayAke0pTT04uc3RyaW5naWZ5KG5hbWUpfSAodHlwaWNhbGx5IGFuIG91dC1vZi1tZW1vcnkgb3IgdGhyZWFkLWtpbGxlZCBjb25kaXRpb24pYClcbiAgICB9XG5cbiAgICByZXR1cm4gTnVtYmVyKHJlc3VsdCkgPT09IDFcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHRyeSBhY3F1aXJlIGFkdmlzb3J5IGxvY2suXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gTG9jayBuYW1lLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gLSBUcnVlIGlmIHRoZSBsb2NrIHdhcyBhY3F1aXJlZCwgZmFsc2UgaWYgaXQgd2FzIGFscmVhZHkgaGVsZC5cbiAgICovXG4gIGFzeW5jIHRyeUFjcXVpcmVBZHZpc29yeUxvY2sobmFtZSkge1xuICAgIGNvbnN0IHJvd3MgPSBhd2FpdCB0aGlzLnF1ZXJ5KGBTRUxFQ1QgR0VUX0xPQ0soJHt0aGlzLnF1b3RlKG5hbWUpfSwgMCkgQVMgdmVsb2Npb3VzX2Fkdmlzb3J5X2xvY2tfcmVzdWx0YClcbiAgICBjb25zdCByZXN1bHQgPSByb3dzPy5bMF0/LnZlbG9jaW91c19hZHZpc29yeV9sb2NrX3Jlc3VsdFxuXG4gICAgaWYgKHJlc3VsdCA9PT0gbnVsbCB8fCByZXN1bHQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBHRVRfTE9DSyByZXR1cm5lZCBOVUxMIGZvciBhZHZpc29yeSBsb2NrICR7SlNPTi5zdHJpbmdpZnkobmFtZSl9ICh0eXBpY2FsbHkgYW4gb3V0LW9mLW1lbW9yeSBvciB0aHJlYWQta2lsbGVkIGNvbmRpdGlvbilgKVxuICAgIH1cblxuICAgIHJldHVybiBOdW1iZXIocmVzdWx0KSA9PT0gMVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcmVsZWFzZSBhZHZpc29yeSBsb2NrLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIExvY2sgbmFtZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8Ym9vbGVhbj59IC0gVHJ1ZSBpZiB0aGUgbG9jayB3YXMgaGVsZCBieSB0aGlzIHNlc3Npb24gYW5kIGhhcyBub3cgYmVlbiByZWxlYXNlZC5cbiAgICovXG4gIGFzeW5jIHJlbGVhc2VBZHZpc29yeUxvY2sobmFtZSkge1xuICAgIGNvbnN0IHJvd3MgPSBhd2FpdCB0aGlzLnF1ZXJ5KGBTRUxFQ1QgUkVMRUFTRV9MT0NLKCR7dGhpcy5xdW90ZShuYW1lKX0pIEFTIHZlbG9jaW91c19hZHZpc29yeV9sb2NrX3Jlc3VsdGApXG4gICAgY29uc3QgcmVzdWx0ID0gcm93cz8uWzBdPy52ZWxvY2lvdXNfYWR2aXNvcnlfbG9ja19yZXN1bHRcblxuICAgIHJldHVybiBOdW1iZXIocmVzdWx0KSA9PT0gMVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgaXMgYWR2aXNvcnkgbG9jayBoZWxkLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIExvY2sgbmFtZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8Ym9vbGVhbj59IC0gVHJ1ZSBpZiBhbnkgc2Vzc2lvbiBjdXJyZW50bHkgaG9sZHMgdGhlIGxvY2suXG4gICAqL1xuICBhc3luYyBpc0Fkdmlzb3J5TG9ja0hlbGQobmFtZSkge1xuICAgIGNvbnN0IHJvd3MgPSBhd2FpdCB0aGlzLnF1ZXJ5KGBTRUxFQ1QgSVNfVVNFRF9MT0NLKCR7dGhpcy5xdW90ZShuYW1lKX0pIEFTIHZlbG9jaW91c19hZHZpc29yeV9sb2NrX2hvbGRlcmApXG4gICAgY29uc3QgaG9sZGVyID0gcm93cz8uWzBdPy52ZWxvY2lvdXNfYWR2aXNvcnlfbG9ja19ob2xkZXJcblxuICAgIHJldHVybiBob2xkZXIgIT09IG51bGwgJiYgaG9sZGVyICE9PSB1bmRlZmluZWRcbiAgfVxufVxuIl19
|
|
@@ -82,13 +82,41 @@ export default class DataCopier {
|
|
|
82
82
|
*/
|
|
83
83
|
loadRows(db: import("../drivers/base.js").default, keyValue: string): Promise<Map<string, Record<string, unknown>[]>>;
|
|
84
84
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
85
|
+
* Loads only the ids for `keyValue` for every table in the plan from `db`, using the same
|
|
86
|
+
* parent/child traversal as {@link DataCopier#loadRows} but selecting just the id column.
|
|
87
|
+
* Callers that only need to compare row membership — for example verifying a tenant already
|
|
88
|
+
* holds every default row before a cleanup delete — should use this instead of loadRows so
|
|
89
|
+
* they never materialise full rows; for large tenants that is the difference between a few
|
|
90
|
+
* kilobytes of ids and gigabytes of row data.
|
|
91
|
+
* @param {import("../drivers/base.js").default} db - Source or target database to traverse.
|
|
92
|
+
* @param {string} keyValue - Tenant key selecting the root plan rows.
|
|
93
|
+
* @returns {Promise<Map<string, string[]>>} - Loaded ids grouped by table name.
|
|
94
|
+
*/
|
|
95
|
+
loadRowIds(db: import("../drivers/base.js").default, keyValue: string): Promise<Map<string, string[]>>;
|
|
96
|
+
/**
|
|
97
|
+
* Traverses the table plan for `keyValue`, querying each table by its tenant key column or
|
|
98
|
+
* (for child tables) by the ids already selected for its parent, and returns both the ids
|
|
99
|
+
* and the loaded rows grouped by table name. `selectColumns` bounds the columns each query
|
|
100
|
+
* selects; pass `[idColumn]` for an id-only traversal, or omit it to load full rows.
|
|
101
|
+
* @param {import("../drivers/base.js").default} db - Source or target database to traverse.
|
|
102
|
+
* @param {string} keyValue - Tenant key selecting the root plan rows.
|
|
103
|
+
* @param {string[]} [selectColumns] - Columns to select; defaults to every column.
|
|
104
|
+
* @returns {Promise<{idsByTableName: Map<string, string[]>, rowsByTableName: Map<string, Record<string, unknown>[]>}>} - Ids and rows grouped by table name.
|
|
105
|
+
*/
|
|
106
|
+
traversePlan(db: import("../drivers/base.js").default, keyValue: string, selectColumns?: string[]): Promise<{
|
|
107
|
+
idsByTableName: Map<string, string[]>;
|
|
108
|
+
rowsByTableName: Map<string, Record<string, unknown>[]>;
|
|
109
|
+
}>;
|
|
110
|
+
/**
|
|
111
|
+
* Selects `tableName` rows in `db` whose `columnName` is in `values`, chunked. `selectColumns`
|
|
112
|
+
* bounds the projection and defaults to every column.
|
|
113
|
+
* @param {{columnName: string, db: import("../drivers/base.js").default, selectColumns?: string[], tableName: string, values: string[]}} args - Table, column, projection, database, and values for the chunked lookup.
|
|
87
114
|
* @returns {Promise<Record<string, unknown>[]>} - Rows matching the supplied column values.
|
|
88
115
|
*/
|
|
89
|
-
queryRowsByColumn({ columnName, db, tableName, values }: {
|
|
116
|
+
queryRowsByColumn({ columnName, db, selectColumns, tableName, values }: {
|
|
90
117
|
columnName: string;
|
|
91
118
|
db: import("../drivers/base.js").default;
|
|
119
|
+
selectColumns?: string[];
|
|
92
120
|
tableName: string;
|
|
93
121
|
values: string[];
|
|
94
122
|
}): Promise<Record<string, unknown>[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-copier.d.ts","sourceRoot":"","sources":["../../../../src/database/tenants/data-copier.js"],"names":[],"mappings":"AA+BA;;;;;;;;;;;;;;;;;;;GAmBG;AACH;IACE;;;;;;;;;;;OAWG;IACH,sGAVW;QACN,QAAQ,EAAE,OAAO,oBAAoB,EAAE,OAAO,CAAC;QAC/C,QAAQ,EAAE,OAAO,oBAAoB,EAAE,OAAO,CAAC;QAC/C,SAAS,EAAE,OAAO,wBAAwB,EAAE,oBAAoB,EAAE,CAAC;QACnE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;KACvC,EAUH;IAPC,+CAAwB;IACxB,+CAAwB;IACxB,mEAA0B;IAC1B,iBAAwB;IACxB,wBAAsC;IACtC,uBAAoC;IACpC,uBAV0B,MAAM,KAAK,IAAI,cAUb;IAG9B;;;;;;;OAOG;IACH,eAHW,MAAM,GACJ,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,CAc3D;IAED;;;;;;;;;;;;;;OAcG;IACH,2BAHW,MAAM,GACJ,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,CAY3D;IAED;;;;;;;OAOG;IACH,aAJW,OAAO,oBAAoB,EAAE,OAAO,YACpC,MAAM,GACJ,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"data-copier.d.ts","sourceRoot":"","sources":["../../../../src/database/tenants/data-copier.js"],"names":[],"mappings":"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"}
|
|
@@ -117,6 +117,33 @@ export default class DataCopier {
|
|
|
117
117
|
* @returns {Promise<Map<string, Record<string, unknown>[]>>} - Loaded rows grouped by table name.
|
|
118
118
|
*/
|
|
119
119
|
async loadRows(db, keyValue) {
|
|
120
|
+
return (await this.traversePlan(db, keyValue)).rowsByTableName;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Loads only the ids for `keyValue` for every table in the plan from `db`, using the same
|
|
124
|
+
* parent/child traversal as {@link DataCopier#loadRows} but selecting just the id column.
|
|
125
|
+
* Callers that only need to compare row membership — for example verifying a tenant already
|
|
126
|
+
* holds every default row before a cleanup delete — should use this instead of loadRows so
|
|
127
|
+
* they never materialise full rows; for large tenants that is the difference between a few
|
|
128
|
+
* kilobytes of ids and gigabytes of row data.
|
|
129
|
+
* @param {import("../drivers/base.js").default} db - Source or target database to traverse.
|
|
130
|
+
* @param {string} keyValue - Tenant key selecting the root plan rows.
|
|
131
|
+
* @returns {Promise<Map<string, string[]>>} - Loaded ids grouped by table name.
|
|
132
|
+
*/
|
|
133
|
+
async loadRowIds(db, keyValue) {
|
|
134
|
+
return (await this.traversePlan(db, keyValue, [this.idColumn])).idsByTableName;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Traverses the table plan for `keyValue`, querying each table by its tenant key column or
|
|
138
|
+
* (for child tables) by the ids already selected for its parent, and returns both the ids
|
|
139
|
+
* and the loaded rows grouped by table name. `selectColumns` bounds the columns each query
|
|
140
|
+
* selects; pass `[idColumn]` for an id-only traversal, or omit it to load full rows.
|
|
141
|
+
* @param {import("../drivers/base.js").default} db - Source or target database to traverse.
|
|
142
|
+
* @param {string} keyValue - Tenant key selecting the root plan rows.
|
|
143
|
+
* @param {string[]} [selectColumns] - Columns to select; defaults to every column.
|
|
144
|
+
* @returns {Promise<{idsByTableName: Map<string, string[]>, rowsByTableName: Map<string, Record<string, unknown>[]>}>} - Ids and rows grouped by table name.
|
|
145
|
+
*/
|
|
146
|
+
async traversePlan(db, keyValue, selectColumns) {
|
|
120
147
|
/** @type {Map<string, string[]>} */
|
|
121
148
|
const idsByTableName = new Map();
|
|
122
149
|
/** @type {Map<string, Record<string, unknown>[]>} */
|
|
@@ -127,6 +154,7 @@ export default class DataCopier {
|
|
|
127
154
|
rows = await this.queryRowsByColumn({
|
|
128
155
|
columnName: tableConfig.keyColumn,
|
|
129
156
|
db,
|
|
157
|
+
selectColumns,
|
|
130
158
|
tableName: tableConfig.tableName,
|
|
131
159
|
values: [keyValue]
|
|
132
160
|
});
|
|
@@ -141,6 +169,7 @@ export default class DataCopier {
|
|
|
141
169
|
rows = await this.queryRowsByColumn({
|
|
142
170
|
columnName: tableConfig.parentColumn,
|
|
143
171
|
db,
|
|
172
|
+
selectColumns,
|
|
144
173
|
tableName: tableConfig.tableName,
|
|
145
174
|
values: idsByTableName.get(tableConfig.parentTableName) || []
|
|
146
175
|
});
|
|
@@ -151,14 +180,15 @@ export default class DataCopier {
|
|
|
151
180
|
idsByTableName.set(tableConfig.tableName, uniqueStrings(rows.map((row) => row[this.idColumn])));
|
|
152
181
|
rowsByTableName.set(tableConfig.tableName, rows);
|
|
153
182
|
}
|
|
154
|
-
return rowsByTableName;
|
|
183
|
+
return { idsByTableName, rowsByTableName };
|
|
155
184
|
}
|
|
156
185
|
/**
|
|
157
|
-
* Selects
|
|
158
|
-
*
|
|
186
|
+
* Selects `tableName` rows in `db` whose `columnName` is in `values`, chunked. `selectColumns`
|
|
187
|
+
* bounds the projection and defaults to every column.
|
|
188
|
+
* @param {{columnName: string, db: import("../drivers/base.js").default, selectColumns?: string[], tableName: string, values: string[]}} args - Table, column, projection, database, and values for the chunked lookup.
|
|
159
189
|
* @returns {Promise<Record<string, unknown>[]>} - Rows matching the supplied column values.
|
|
160
190
|
*/
|
|
161
|
-
async queryRowsByColumn({ columnName, db, tableName, values }) {
|
|
191
|
+
async queryRowsByColumn({ columnName, db, selectColumns, tableName, values }) {
|
|
162
192
|
const normalizedValues = uniqueStrings(values);
|
|
163
193
|
if (normalizedValues.length <= 0) {
|
|
164
194
|
return [];
|
|
@@ -166,8 +196,11 @@ export default class DataCopier {
|
|
|
166
196
|
const rows = [];
|
|
167
197
|
const quotedTable = db.quoteTable(tableName);
|
|
168
198
|
const quotedColumn = db.quoteColumn(columnName);
|
|
199
|
+
const selectList = selectColumns
|
|
200
|
+
? selectColumns.map((column) => `${quotedTable}.${db.quoteColumn(column)}`).join(", ")
|
|
201
|
+
: `${quotedTable}.*`;
|
|
169
202
|
for (const valuesChunk of chunks(normalizedValues, this.queryChunkSize)) {
|
|
170
|
-
const sql = `SELECT ${
|
|
203
|
+
const sql = `SELECT ${selectList} FROM ${quotedTable} WHERE ${quotedColumn} IN (${this.quotedValuesSql(db, valuesChunk)})`;
|
|
171
204
|
rows.push(...await this.executeQuietQuery(db, sql));
|
|
172
205
|
}
|
|
173
206
|
return rows;
|
|
@@ -253,4 +286,4 @@ export default class DataCopier {
|
|
|
253
286
|
}
|
|
254
287
|
}
|
|
255
288
|
}
|
|
256
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS1jb3BpZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvZGF0YWJhc2UvdGVuYW50cy9kYXRhLWNvcGllci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosTUFBTSx5QkFBeUIsR0FBRyxHQUFHLENBQUE7QUFDckMsTUFBTSx3QkFBd0IsR0FBRyxHQUFHLENBQUE7QUFFcEM7Ozs7OztHQU1HO0FBQ0gsU0FBUyxNQUFNLENBQUMsTUFBTSxFQUFFLFNBQVM7SUFDL0IsTUFBTSxhQUFhLEdBQUcsRUFBRSxDQUFBO0lBRXhCLEtBQUssSUFBSSxLQUFLLEdBQUcsQ0FBQyxFQUFFLEtBQUssR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLEtBQUssSUFBSSxTQUFTLEVBQUUsQ0FBQztRQUM5RCxhQUFhLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLEtBQUssR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFBO0lBQzVELENBQUM7SUFFRCxPQUFPLGFBQWEsQ0FBQTtBQUN0QixDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQVMsYUFBYSxDQUFDLE1BQU07SUFDM0IsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFBO0FBQ2xHLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUNILE1BQU0sQ0FBQyxPQUFPLE9BQU8sVUFBVTtJQUM3Qjs7Ozs7Ozs7Ozs7T0FXRztJQUNILFlBQVksRUFBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxRQUFRLEdBQUcsSUFBSSxF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LENBQUMsVUFBVSxFQUFFLENBQUM7WUFDcEIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUMxQixDQUFDO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmNvbnN0IERFRkFVTFRfSU5TRVJUX0NIVU5LX1NJWkUgPSAxMDBcbmNvbnN0IERFRkFVTFRfUVVFUllfQ0hVTktfU0laRSA9IDUwMFxuXG4vKipcbiAqIFNwbGl0cyBhbiBhcnJheSBpbnRvIGNodW5rcyBvZiBhdCBtb3N0IGBjaHVua1NpemVgIGl0ZW1zLlxuICogQHRlbXBsYXRlIFRcbiAqIEBwYXJhbSB7VFtdfSB2YWx1ZXMgLSBPcmRlcmVkIGl0ZW1zIHRvIHBhcnRpdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBjaHVua1NpemUgLSBNYXhpbXVtIGl0ZW1zIHBlciBjaHVuay5cbiAqIEByZXR1cm5zIHtUW11bXX0gLSBDb25zZWN1dGl2ZSBjaHVua3MgcHJlc2VydmluZyBpbnB1dCBvcmRlci5cbiAqL1xuZnVuY3Rpb24gY2h1bmtzKHZhbHVlcywgY2h1bmtTaXplKSB7XG4gIGNvbnN0IGNodW5rZWRWYWx1ZXMgPSBbXVxuXG4gIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCB2YWx1ZXMubGVuZ3RoOyBpbmRleCArPSBjaHVua1NpemUpIHtcbiAgICBjaHVua2VkVmFsdWVzLnB1c2godmFsdWVzLnNsaWNlKGluZGV4LCBpbmRleCArIGNodW5rU2l6ZSkpXG4gIH1cblxuICByZXR1cm4gY2h1bmtlZFZhbHVlc1xufVxuXG4vKipcbiAqIFN0cmluZ2lmaWVzIHZhbHVlcyBhbmQgcmV0dXJucyB0aGUgZGlzdGluY3QsIG5vbi1ibGFuayBvbmVzLCBwcmVzZXJ2aW5nIGZpcnN0LXNlZW4gb3JkZXIuXG4gKiBAcGFyYW0ge3Vua25vd25bXX0gdmFsdWVzIC0gQ2FuZGlkYXRlIGRhdGFiYXNlIGlkZW50aWZpZXJzIHRvIHN0cmluZ2lmeSBhbmQgZGVkdXBsaWNhdGUuXG4gKiBAcmV0dXJucyB7c3RyaW5nW119IC0gRGlzdGluY3Qgbm9uLWJsYW5rIGlkZW50aWZpZXJzIGluIGZpcnN0LXNlZW4gb3JkZXIuXG4gKi9cbmZ1bmN0aW9uIHVuaXF1ZVN0cmluZ3ModmFsdWVzKSB7XG4gIHJldHVybiBBcnJheS5mcm9tKG5ldyBTZXQodmFsdWVzLm1hcCgodmFsdWUpID0+IFN0cmluZyh2YWx1ZSkpLmZpbHRlcigodmFsdWUpID0+IHZhbHVlLnRyaW0oKSkpKVxufVxuXG4vKipcbiAqIENvcGllcyBhIHNpbmdsZSB0ZW5hbnQncyByb3dzIGZyb20gYSBzb3VyY2UgZGF0YWJhc2UgaW50byBhIHRhcmdldCBkYXRhYmFzZSwgZm9sbG93aW5nIGFcbiAqIHRhYmxlIHBsYW4gdGhhdCBwYXJ0aXRpb25zIGVhY2ggdGFibGUgZWl0aGVyIGJ5IGEgZGlyZWN0IHRlbmFudCBrZXkgY29sdW1uIG9yIGJ5XG4gKiBwYXJlbnQtaWQgdHJhdmVyc2FsLiBUaGlzIGlzIHRoZSByb3ctbGV2ZWwgY291bnRlcnBhcnQgdG8gc2NoZW1hIGNsb25pbmc6IG11bHRpLXRlbmFudFxuICogYXBwcyB0aGF0IGtlZXAgZWFjaCB0ZW5hbnQncyBkYXRhIGluIGl0cyBvd24gZGF0YWJhc2UgdXNlIGl0IHRvIChyZSltYXRlcmlhbGlzZSB0aGVcbiAqIHRlbmFudCdzIHJvd3MgZnJvbSBhIGdsb2JhbC90ZW1wbGF0ZSBkYXRhYmFzZS5cbiAqXG4gKiBUaGUgY29weSBpcyBkZWxldGUtdGhlbi1yZWluc2VydCBhbmQgdGhlcmVmb3JlIGlkZW1wb3RlbnQsIGFuZCBpdCBtaXJyb3JzIHRoZSBzb3VyY2VcbiAqIHNuYXBzaG90OiB0aGUgcm93cyB0byBkZWxldGUgYXJlIHRoZSB0ZW5hbnQncyAqY3VycmVudCogcm93cyBpbiB0aGUgdGFyZ2V0IChzZWxlY3RlZCB3aXRoXG4gKiB0aGUgc2FtZSBwbGFuIHRyYXZlcnNhbCBydW4gYWdhaW5zdCB0aGUgdGFyZ2V0KSwgc28gYSByb3cgdGhhdCB3YXMgcmVtb3ZlZCBmcm9tIHRoZSBzb3VyY2VcbiAqIHNpbmNlIHRoZSBsYXN0IGNvcHkgaXMgZHJvcHBlZCBmcm9tIHRoZSB0YXJnZXQgdG9vIHJhdGhlciB0aGFuIGxpbmdlcmluZy4gVGhlIGRlbGV0ZXMgcnVuXG4gKiBjaGlsZHJlbiBmaXJzdCBhbmQgdGhlIHNvdXJjZSBpbnNlcnRzIHBhcmVudHMgZmlyc3QsIGFsbCBpbnNpZGUgb25lIHRhcmdldCB0cmFuc2FjdGlvbiB3aXRoXG4gKiBmb3JlaWduLWtleSBlbmZvcmNlbWVudCBkaXNhYmxlZCBzbyB0aGUgb3JkZXJpbmcgbmV2ZXIgdHJpcHMgYSBjb25zdHJhaW50LiBSZWFkcywgZGVsZXRlc1xuICogYW5kIGluc2VydHMgYXJlIGNodW5rZWQgdG8gYm91bmQgc3RhdGVtZW50IHNpemUuXG4gKlxuICogVGhlIGNvcGllciBpcyBwb2xpY3ktZnJlZTogdGhlIGNhbGxlciBzdXBwbGllcyB0aGUgcGxhbiwgdGhlIHNvdXJjZS90YXJnZXQgZGF0YWJhc2VzIGFuZFxuICogdGhlIHRlbmFudCBrZXksIGFuZCB7QGxpbmsgRGF0YUNvcGllciNjb3B5fSByZXR1cm5zIHRoZSBsb2FkZWQgcm93cyBrZXllZCBieSB0YWJsZSBuYW1lIHNvXG4gKiB0aGUgY2FsbGVyIGNhbiBwZXJmb3JtIGFueSBhcHAtc3BlY2lmaWMgcG9zdC1jb3B5IHdvcmsgKGZvciBleGFtcGxlIHJlZ2lzdGVyaW5nIHJlY29yZFxuICogbG9jYXRpb25zKSB3aXRob3V0IHRoYXQgcG9saWN5IGxlYWtpbmcgaW50byB0aGUgZnJhbWV3b3JrLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBEYXRhQ29waWVyIHtcbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBjb3BpZXIgdGhhdCBtb3ZlcyB0ZW5hbnQtb3duZWQgcm93cyBmcm9tIGBzb3VyY2VEYmAgaW50byBgdGFyZ2V0RGJgLlxuICAgKiBAcGFyYW0ge3tcbiAgICogICBzb3VyY2VEYjogaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQsXG4gICAqICAgdGFyZ2V0RGI6IGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0LFxuICAgKiAgIHRhYmxlUGxhbjogaW1wb3J0KFwiLi90ZW5hbnQtdGFibGUtcGxhbi5qc1wiKS5UZW5hbnRUYWJsZVBsYW5FbnRyeVtdLFxuICAgKiAgIGlkQ29sdW1uPzogc3RyaW5nLFxuICAgKiAgIGluc2VydENodW5rU2l6ZT86IG51bWJlcixcbiAgICogICBxdWVyeUNodW5rU2l6ZT86IG51bWJlcixcbiAgICogICBvblByb2dyZXNzPzogKG1lc3NhZ2U6IHN0cmluZykgPT4gdm9pZFxuICAgKiB9fSBhcmdzIC0gU291cmNlLCB0YXJnZXQsIHRyYXZlcnNhbCBwbGFuLCBjaHVuayBsaW1pdHMsIGFuZCBwcm9ncmVzcyBoYW5kbGVyLlxuICAgKi9cbiAgY29uc3RydWN0b3Ioe3NvdXJjZURiLCB0YXJnZXREYiwgdGFibGVQbGFuLCBpZENvbHVtbiA9IFwiaWRcIiwgaW5zZXJ0Q2h1bmtTaXplID0gREVGQVVMVF9JTlNFUlRfQ0hVTktfU0laRSwgcXVlcnlDaHVua1NpemUgPSBERUZBVUxUX1FVRVJZX0NIVU5LX1NJWkUsIG9uUHJvZ3Jlc3N9KSB7XG4gICAgdGhpcy5zb3VyY2VEYiA9IHNvdXJjZURiXG4gICAgdGhpcy50YXJnZXREYiA9IHRhcmdldERiXG4gICAgdGhpcy50YWJsZVBsYW4gPSB0YWJsZVBsYW5cbiAgICB0aGlzLmlkQ29sdW1uID0gaWRDb2x1bW5cbiAgICB0aGlzLmluc2VydENodW5rU2l6ZSA9IGluc2VydENodW5rU2l6ZVxuICAgIHRoaXMucXVlcnlDaHVua1NpemUgPSBxdWVyeUNodW5rU2l6ZVxuICAgIHRoaXMub25Qcm9ncmVzcyA9IG9uUHJvZ3Jlc3NcbiAgfVxuXG4gIC8qKlxuICAgKiBDb3BpZXMgZXZlcnkgcGxhbiB0YWJsZSdzIHJvd3MgZm9yIGBrZXlWYWx1ZWAgZnJvbSB0aGUgc291cmNlIGludG8gdGhlIHRhcmdldCBhbmRcbiAgICogcmV0dXJucyB0aGUgY29waWVkIHNvdXJjZSByb3dzIGtleWVkIGJ5IHRhYmxlIG5hbWUuIFRoZSB0YXJnZXQncyBjdXJyZW50IHRlbmFudCByb3dzXG4gICAqIGFyZSBkZWxldGVkIChjaGlsZHJlbiBmaXJzdCkgYW5kIHRoZSBzb3VyY2Ugcm93cyBpbnNlcnRlZCAocGFyZW50cyBmaXJzdCkgaW4gYSBzaW5nbGVcbiAgICogdGFyZ2V0IHRyYW5zYWN0aW9uIHdpdGggZm9yZWlnbiBrZXlzIGRpc2FibGVkLlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5VmFsdWUgLSBUZW5hbnQga2V5IHNlbGVjdGluZyB0aGUgcm93cyB0byBjb3B5LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxNYXA8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdPj59IC0gQ29waWVkIHNvdXJjZSByb3dzIGdyb3VwZWQgYnkgdGFibGUgbmFtZS5cbiAgICovXG4gIGFzeW5jIGNvcHkoa2V5VmFsdWUpIHtcbiAgICBjb25zdCBzb3VyY2VSb3dzQnlUYWJsZU5hbWUgPSBhd2FpdCB0aGlzLmxvYWRSb3dzKHRoaXMuc291cmNlRGIsIGtleVZhbHVlKVxuICAgIGNvbnN0IHRhcmdldFJvd3NCeVRhYmxlTmFtZSA9IGF3YWl0IHRoaXMubG9hZFJvd3ModGhpcy50YXJnZXREYiwga2V5VmFsdWUpXG5cbiAgICBhd2FpdCB0aGlzLnRhcmdldERiLndpdGhEaXNhYmxlZEZvcmVpZ25LZXlzKGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHRoaXMudGFyZ2V0RGIudHJhbnNhY3Rpb24oYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCB0aGlzLmRlbGV0ZVRhcmdldFJvd3ModGFyZ2V0Um93c0J5VGFibGVOYW1lKVxuICAgICAgICBhd2FpdCB0aGlzLmluc2VydFRhcmdldFJvd3Moc291cmNlUm93c0J5VGFibGVOYW1lKVxuICAgICAgfSlcbiAgICB9KVxuXG4gICAgcmV0dXJuIHNvdXJjZVJvd3NCeVRhYmxlTmFtZVxuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZXMgb25lIHRlbmFudCdzIHJvd3MgZnJvbSB0aGUgdGFyZ2V0IGRhdGFiYXNlLCBjaGlsZHJlbiBiZWZvcmUgcGFyZW50cywgd2l0aFxuICAgKiBmb3JlaWduIGtleXMgZGlzYWJsZWQgaW5zaWRlIGEgc2luZ2xlIHRyYW5zYWN0aW9uLiBUaGlzIGlzIGBjb3B5YCB3aXRob3V0IHRoZSByZWluc2VydDpcbiAgICogdGhlIHNhbWUgcGxhbiB0cmF2ZXJzYWwgc2VsZWN0cyB0aGUgdGVuYW50J3MgY3VycmVudCB0YXJnZXQgcm93cyBhbmQgYGRlbGV0ZVRhcmdldFJvd3NgXG4gICAqIHJlbW92ZXMgdGhlbSBjaGlsZHJlbi1maXJzdCBzbyB0aGUgb3JkZXJpbmcgbmV2ZXIgdHJpcHMgYSBmb3JlaWduIGtleS4gTXVsdGktdGVuYW50IGFwcHNcbiAgICogdXNlIGl0IHRvIHB1cmdlIGEgdGVuYW50IOKAlCBmb3IgZXhhbXBsZSBjbGVhcmluZyB0aGUgdGVuYW50J3MgbWFzdGVyIGNvcHkgaW4gdGhlXG4gICAqIGdsb2JhbC9kZWZhdWx0IGRhdGFiYXNlIG9uIHRlYXJkb3duLCBzbyBmb3JlaWduIGtleXMgc3RvcCByZWZlcmVuY2luZyB0aGUgdGVuYW50J3NcbiAgICogYWJvdXQtdG8tYmUtcmVtb3ZlZCByb290IHJvdy5cbiAgICpcbiAgICogUmV0dXJucyB0aGUgZGVsZXRlZCByb3dzIGtleWVkIGJ5IHRhYmxlIG5hbWUgc28gdGhlIGNhbGxlciBjYW4gcGVyZm9ybSBhbnkgYXBwLXNwZWNpZmljXG4gICAqIHBvc3QtZGVsZXRlIHdvcmsgKHJlY29yZC1sb2NhdGlvbiBjbGVhbnVwLCBhdWRpdGluZykgd2l0aG91dCB0aGF0IHBvbGljeSBsZWFraW5nIGludG8gdGhlXG4gICAqIGZyYW1ld29yay5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleVZhbHVlIC0gVGVuYW50IGtleSB3aG9zZSByb3dzIHNob3VsZCBiZSByZW1vdmVkIGZyb20gdGhlIHRhcmdldC5cbiAgICogQHJldHVybnMge1Byb21pc2U8TWFwPHN0cmluZywgUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXT4+fSAtIFRoZSBkZWxldGVkIHJvd3MgYnkgdGFibGUgbmFtZS5cbiAgICovXG4gIGFzeW5jIGRlbGV0ZVRlbmFudFJvd3Moa2V5VmFsdWUpIHtcbiAgICBjb25zdCByb3dzQnlUYWJsZU5hbWUgPSBhd2FpdCB0aGlzLmxvYWRSb3dzKHRoaXMudGFyZ2V0RGIsIGtleVZhbHVlKVxuXG4gICAgYXdhaXQgdGhpcy50YXJnZXREYi53aXRoRGlzYWJsZWRGb3JlaWduS2V5cyhhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCB0aGlzLnRhcmdldERiLnRyYW5zYWN0aW9uKGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5kZWxldGVUYXJnZXRSb3dzKHJvd3NCeVRhYmxlTmFtZSlcbiAgICAgIH0pXG4gICAgfSlcblxuICAgIHJldHVybiByb3dzQnlUYWJsZU5hbWVcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkcyB0aGUgcm93cyBmb3IgYGtleVZhbHVlYCBmb3IgZXZlcnkgdGFibGUgaW4gdGhlIHBsYW4gZnJvbSBgZGJgLCByZXNvbHZpbmdcbiAgICogcGFyZW50LXNjb3BlZCB0YWJsZXMgZnJvbSB0aGUgaWRzIGFscmVhZHkgc2VsZWN0ZWQgZm9yIHRoZWlyIHBhcmVudCB0YWJsZS4gVXNlZCBmb3JcbiAgICogYm90aCB0aGUgc291cmNlIHJvd3MgdG8gY29weSBhbmQgdGhlIHRhcmdldCdzIGN1cnJlbnQgdGVuYW50IHJvd3MgdG8gZGVsZXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBkYiAtIFNvdXJjZSBvciB0YXJnZXQgZGF0YWJhc2UgdG8gdHJhdmVyc2UuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXlWYWx1ZSAtIFRlbmFudCBrZXkgc2VsZWN0aW5nIHRoZSByb290IHBsYW4gcm93cy5cbiAgICogQHJldHVybnMge1Byb21pc2U8TWFwPHN0cmluZywgUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXT4+fSAtIExvYWRlZCByb3dzIGdyb3VwZWQgYnkgdGFibGUgbmFtZS5cbiAgICovXG4gIGFzeW5jIGxvYWRSb3dzKGRiLCBrZXlWYWx1ZSkge1xuICAgIC8qKiBAdHlwZSB7TWFwPHN0cmluZywgc3RyaW5nW10+fSAqL1xuICAgIGNvbnN0IGlkc0J5VGFibGVOYW1lID0gbmV3IE1hcCgpXG4gICAgLyoqIEB0eXBlIHtNYXA8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdPn0gKi9cbiAgICBjb25zdCByb3dzQnlUYWJsZU5hbWUgPSBuZXcgTWFwKClcblxuICAgIGZvciAoY29uc3QgdGFibGVDb25maWcgb2YgdGhpcy50YWJsZVBsYW4pIHtcbiAgICAgIGxldCByb3dzXG5cbiAgICAgIGlmICh0YWJsZUNvbmZpZy5rZXlDb2x1bW4pIHtcbiAgICAgICAgcm93cyA9IGF3YWl0IHRoaXMucXVlcnlSb3dzQnlDb2x1bW4oe1xuICAgICAgICAgIGNvbHVtbk5hbWU6IHRhYmxlQ29uZmlnLmtleUNvbHVtbixcbiAgICAgICAgICBkYixcbiAgICAgICAgICB0YWJsZU5hbWU6IHRhYmxlQ29uZmlnLnRhYmxlTmFtZSxcbiAgICAgICAgICB2YWx1ZXM6IFtrZXlWYWx1ZV1cbiAgICAgICAgfSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICghdGFibGVDb25maWcucGFyZW50Q29sdW1uIHx8ICF0YWJsZUNvbmZpZy5wYXJlbnRUYWJsZU5hbWUpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIGtleUNvbHVtbiBvciBwYXJlbnRUYWJsZU5hbWUrcGFyZW50Q29sdW1uIGZvciB0YWJsZSAke3RhYmxlQ29uZmlnLnRhYmxlTmFtZX0gaW4gdGhlIHRlbmFudCB0YWJsZSBwbGFuLmApXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWlkc0J5VGFibGVOYW1lLmhhcyh0YWJsZUNvbmZpZy5wYXJlbnRUYWJsZU5hbWUpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUZW5hbnQgdGFibGUgcGxhbiBlbnRyeSAke3RhYmxlQ29uZmlnLnRhYmxlTmFtZX0gcmVmZXJlbmNlcyBwYXJlbnQgdGFibGUgJHt0YWJsZUNvbmZpZy5wYXJlbnRUYWJsZU5hbWV9LCB3aGljaCBoYXMgbm90IGJlZW4gbG9hZGVkOyBwYXJlbnQgdGFibGVzIG11c3QgYXBwZWFyIGJlZm9yZSB0aGVpciBjaGlsZHJlbiBpbiB0aGUgcGxhbi5gKVxuICAgICAgICB9XG5cbiAgICAgICAgcm93cyA9IGF3YWl0IHRoaXMucXVlcnlSb3dzQnlDb2x1bW4oe1xuICAgICAgICAgIGNvbHVtbk5hbWU6IHRhYmxlQ29uZmlnLnBhcmVudENvbHVtbixcbiAgICAgICAgICBkYixcbiAgICAgICAgICB0YWJsZU5hbWU6IHRhYmxlQ29uZmlnLnRhYmxlTmFtZSxcbiAgICAgICAgICB2YWx1ZXM6IGlkc0J5VGFibGVOYW1lLmdldCh0YWJsZUNvbmZpZy5wYXJlbnRUYWJsZU5hbWUpIHx8IFtdXG4gICAgICAgIH0pXG4gICAgICB9XG5cbiAgICAgIGlmIChyb3dzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhpcy5yZXBvcnRQcm9ncmVzcyhgJHt0YWJsZUNvbmZpZy50YWJsZU5hbWV9OiBsb2FkZWQgJHtyb3dzLmxlbmd0aH0gcm93KHMpYClcbiAgICAgIH1cblxuICAgICAgaWRzQnlUYWJsZU5hbWUuc2V0KHRhYmxlQ29uZmlnLnRhYmxlTmFtZSwgdW5pcXVlU3RyaW5ncyhyb3dzLm1hcCgocm93KSA9PiByb3dbdGhpcy5pZENvbHVtbl0pKSlcbiAgICAgIHJvd3NCeVRhYmxlTmFtZS5zZXQodGFibGVDb25maWcudGFibGVOYW1lLCByb3dzKVxuICAgIH1cblxuICAgIHJldHVybiByb3dzQnlUYWJsZU5hbWVcbiAgfVxuXG4gIC8qKlxuICAgKiBTZWxlY3RzIGFsbCByb3dzIG9mIGB0YWJsZU5hbWVgIGluIGBkYmAgd2hvc2UgYGNvbHVtbk5hbWVgIGlzIGluIGB2YWx1ZXNgLCBjaHVua2VkLlxuICAgKiBAcGFyYW0ge3tjb2x1bW5OYW1lOiBzdHJpbmcsIGRiOiBpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCwgdGFibGVOYW1lOiBzdHJpbmcsIHZhbHVlczogc3RyaW5nW119fSBhcmdzIC0gVGFibGUsIGNvbHVtbiwgZGF0YWJhc2UsIGFuZCB2YWx1ZXMgZm9yIHRoZSBjaHVua2VkIGxvb2t1cC5cbiAgICogQHJldHVybnMge1Byb21pc2U8UmVjb3JkPHN0cmluZywgdW5rbm93bj5bXT59IC0gUm93cyBtYXRjaGluZyB0aGUgc3VwcGxpZWQgY29sdW1uIHZhbHVlcy5cbiAgICovXG4gIGFzeW5jIHF1ZXJ5Um93c0J5Q29sdW1uKHtjb2x1bW5OYW1lLCBkYiwgdGFibGVOYW1lLCB2YWx1ZXN9KSB7XG4gICAgY29uc3Qgbm9ybWFsaXplZFZhbHVlcyA9IHVuaXF1ZVN0cmluZ3ModmFsdWVzKVxuXG4gICAgaWYgKG5vcm1hbGl6ZWRWYWx1ZXMubGVuZ3RoIDw9IDApIHtcbiAgICAgIHJldHVybiBbXVxuICAgIH1cblxuICAgIGNvbnN0IHJvd3MgPSBbXVxuICAgIGNvbnN0IHF1b3RlZFRhYmxlID0gZGIucXVvdGVUYWJsZSh0YWJsZU5hbWUpXG4gICAgY29uc3QgcXVvdGVkQ29sdW1uID0gZGIucXVvdGVDb2x1bW4oY29sdW1uTmFtZSlcblxuICAgIGZvciAoY29uc3QgdmFsdWVzQ2h1bmsgb2YgY2h1bmtzKG5vcm1hbGl6ZWRWYWx1ZXMsIHRoaXMucXVlcnlDaHVua1NpemUpKSB7XG4gICAgICBjb25zdCBzcWwgPSBgU0VMRUNUICR7cXVvdGVkVGFibGV9LiogRlJPTSAke3F1b3RlZFRhYmxlfSBXSEVSRSAke3F1b3RlZENvbHVtbn0gSU4gKCR7dGhpcy5xdW90ZWRWYWx1ZXNTcWwoZGIsIHZhbHVlc0NodW5rKX0pYFxuXG4gICAgICByb3dzLnB1c2goLi4uYXdhaXQgdGhpcy5leGVjdXRlUXVpZXRRdWVyeShkYiwgc3FsKSlcbiAgICB9XG5cbiAgICByZXR1cm4gcm93c1xuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZXMgdGhlIG1hdGNoaW5nIHRhcmdldCByb3dzIGZvciBldmVyeSBwbGFuIHRhYmxlLCBjaGlsZHJlbiBiZWZvcmUgcGFyZW50cywgc28gdGhlXG4gICAqIHJlaW5zZXJ0IHRoYXQgZm9sbG93cyBzdGFydHMgZnJvbSBhIGNsZWFuIHNsYXRlIHdpdGhvdXQgdmlvbGF0aW5nIGZvcmVpZ24ga2V5cy5cbiAgICogQHBhcmFtIHtNYXA8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdPn0gcm93c0J5VGFibGVOYW1lIC0gUm93cyBncm91cGVkIGJ5IHRhYmxlIG5hbWUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fVxuICAgKi9cbiAgYXN5bmMgZGVsZXRlVGFyZ2V0Um93cyhyb3dzQnlUYWJsZU5hbWUpIHtcbiAgICBmb3IgKGNvbnN0IHRhYmxlQ29uZmlnIG9mIFsuLi50aGlzLnRhYmxlUGxhbl0ucmV2ZXJzZSgpKSB7XG4gICAgICBjb25zdCByb3dJZHMgPSB1bmlxdWVTdHJpbmdzKChyb3dzQnlUYWJsZU5hbWUuZ2V0KHRhYmxlQ29uZmlnLnRhYmxlTmFtZSkgfHwgW10pLm1hcCgocm93KSA9PiByb3dbdGhpcy5pZENvbHVtbl0pKVxuXG4gICAgICBpZiAocm93SWRzLmxlbmd0aCA8PSAwKSB7XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHF1b3RlZFRhYmxlID0gdGhpcy50YXJnZXREYi5xdW90ZVRhYmxlKHRhYmxlQ29uZmlnLnRhYmxlTmFtZSlcbiAgICAgIGNvbnN0IHF1b3RlZElkQ29sdW1uID0gdGhpcy50YXJnZXREYi5xdW90ZUNvbHVtbih0aGlzLmlkQ29sdW1uKVxuXG4gICAgICBmb3IgKGNvbnN0IHJvd0lkc0NodW5rIG9mIGNodW5rcyhyb3dJZHMsIHRoaXMucXVlcnlDaHVua1NpemUpKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuZXhlY3V0ZVF1aWV0UXVlcnkoXG4gICAgICAgICAgdGhpcy50YXJnZXREYixcbiAgICAgICAgICBgREVMRVRFIEZST00gJHtxdW90ZWRUYWJsZX0gV0hFUkUgJHtxdW90ZWRJZENvbHVtbn0gSU4gKCR7dGhpcy5xdW90ZWRWYWx1ZXNTcWwodGhpcy50YXJnZXREYiwgcm93SWRzQ2h1bmspfSlgXG4gICAgICAgIClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSW5zZXJ0cyB0aGUgbG9hZGVkIHNvdXJjZSByb3dzIGludG8gdGhlIHRhcmdldCBmb3IgZXZlcnkgcGxhbiB0YWJsZSwgcGFyZW50cyBiZWZvcmVcbiAgICogY2hpbGRyZW4sIGNodW5rZWQgdG8gYm91bmQgc3RhdGVtZW50IHNpemUuXG4gICAqIEBwYXJhbSB7TWFwPHN0cmluZywgUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXT59IHJvd3NCeVRhYmxlTmFtZSAtIFJvd3MgZ3JvdXBlZCBieSB0YWJsZSBuYW1lLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIGFzeW5jIGluc2VydFRhcmdldFJvd3Mocm93c0J5VGFibGVOYW1lKSB7XG4gICAgZm9yIChjb25zdCB0YWJsZUNvbmZpZyBvZiB0aGlzLnRhYmxlUGxhbikge1xuICAgICAgY29uc3Qgcm93cyA9IHJvd3NCeVRhYmxlTmFtZS5nZXQodGFibGVDb25maWcudGFibGVOYW1lKSB8fCBbXVxuXG4gICAgICBpZiAocm93cy5sZW5ndGggPD0gMCkge1xuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBjb25zdCBjb2x1bW5zID0gT2JqZWN0LmtleXMocm93c1swXSlcbiAgICAgIGNvbnN0IGluc2VydENodW5rcyA9IGNodW5rcyhyb3dzLCB0aGlzLmluc2VydENodW5rU2l6ZSlcblxuICAgICAgdGhpcy5yZXBvcnRQcm9ncmVzcyhgJHt0YWJsZUNvbmZpZy50YWJsZU5hbWV9OiBpbnNlcnRpbmcgJHtyb3dzLmxlbmd0aH0gcm93KHMpIGluICR7aW5zZXJ0Q2h1bmtzLmxlbmd0aH0gY2h1bmsocylgKVxuXG4gICAgICBmb3IgKGNvbnN0IHJvd3NDaHVuayBvZiBpbnNlcnRDaHVua3MpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5pbnNlcnRSb3dzUXVpZXRseSh7XG4gICAgICAgICAgY29sdW1ucyxcbiAgICAgICAgICBkYjogdGhpcy50YXJnZXREYixcbiAgICAgICAgICByb3dzOiByb3dzQ2h1bmsubWFwKChyb3cpID0+IGNvbHVtbnMubWFwKChjb2x1bW4pID0+IHJvd1tjb2x1bW5dKSksXG4gICAgICAgICAgdGFibGVOYW1lOiB0YWJsZUNvbmZpZy50YWJsZU5hbWVcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUXVvdGVzIGFuZCBjb21tYS1qb2lucyB2YWx1ZXMgZm9yIGFuIFNRTCBgSU4gKC4uLilgIGxpc3QgYWdhaW5zdCB0aGUgZ2l2ZW4gZGF0YWJhc2UuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGRiIC0gRGF0YWJhc2Ugd2hvc2UgcXVvdGluZyBydWxlcyBmb3JtYXQgdGhlIHZhbHVlcy5cbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gdmFsdWVzIC0gVmFsdWVzIHRvIHF1b3RlIGZvciB0aGUgYElOYCBsaXN0LlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSAtIFF1b3RlZCBTUUwgdmFsdWUgbGlzdC5cbiAgICovXG4gIHF1b3RlZFZhbHVlc1NxbChkYiwgdmFsdWVzKSB7XG4gICAgcmV0dXJuIHZhbHVlcy5tYXAoKHZhbHVlKSA9PiBkYi5xdW90ZSh2YWx1ZSkpLmpvaW4oXCIsIFwiKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYSBxdWVyeSB3aXRob3V0IHBlci1xdWVyeSBsb2dnaW5nLCB1c2VkIGZvciB0aGUgaGlnaC12b2x1bWUgY29weSBzdGF0ZW1lbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBkYiAtIERhdGFiYXNlIG9uIHdoaWNoIHRvIGV4ZWN1dGUgdGhlIGNvcHkgcXVlcnkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzcWwgLSBDb3B5LXJlbGF0ZWQgU1FMIHN0YXRlbWVudCB0byBleGVjdXRlIHF1aWV0bHkuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFJlY29yZDxzdHJpbmcsIHVua25vd24+W10+fSAtIFF1ZXJ5IHJlc3VsdCByb3dzLlxuICAgKi9cbiAgYXN5bmMgZXhlY3V0ZVF1aWV0UXVlcnkoZGIsIHNxbCkge1xuICAgIHJldHVybiBhd2FpdCBkYi5xdWVyeShzcWwsIHtsb2dRdWVyeTogZmFsc2V9KVxuICB9XG5cbiAgLyoqXG4gICAqIEluc2VydHMgY29sdW1uLWFsaWduZWQgcm93IHR1cGxlcyBpbnRvIGEgdGFibGUgd2l0aG91dCBwZXItcXVlcnkgbG9nZ2luZy5cbiAgICogQHBhcmFtIHt7Y29sdW1uczogc3RyaW5nW10sIGRiOiBpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCwgcm93czogQXJyYXk8QXJyYXk8dW5rbm93bj4+LCB0YWJsZU5hbWU6IHN0cmluZ319IGFyZ3MgLSBEZXN0aW5hdGlvbiB0YWJsZSBhbmQgY29sdW1uLWFsaWduZWQgcm93IHZhbHVlcyB0byBpbnNlcnQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fVxuICAgKi9cbiAgYXN5bmMgaW5zZXJ0Um93c1F1aWV0bHkoe2NvbHVtbnMsIGRiLCByb3dzLCB0YWJsZU5hbWV9KSB7XG4gICAgYXdhaXQgdGhpcy5leGVjdXRlUXVpZXRRdWVyeShkYiwgZGIuaW5zZXJ0U3FsKHtjb2x1bW5zLCB0YWJsZU5hbWUsIHJvd3N9KSlcbiAgfVxuXG4gIC8qKlxuICAgKiBGb3J3YXJkcyBhIHByb2dyZXNzIG1lc3NhZ2UgdG8gdGhlIG9wdGlvbmFsIGBvblByb2dyZXNzYCBjYWxsYmFjayB3aGVuIG9uZSB3YXMgZ2l2ZW4uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gQ29weSBwcm9ncmVzcyBtZXNzYWdlIHRvIGZvcndhcmQgd2hlbiByZXBvcnRpbmcgaXMgZW5hYmxlZC5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICByZXBvcnRQcm9ncmVzcyhtZXNzYWdlKSB7XG4gICAgaWYgKHRoaXMub25Qcm9ncmVzcykge1xuICAgICAgdGhpcy5vblByb2dyZXNzKG1lc3NhZ2UpXG4gICAgfVxuICB9XG59XG4iXX0=
|
|
289
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS1jb3BpZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvZGF0YWJhc2UvdGVuYW50cy9kYXRhLWNvcGllci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosTUFBTSx5QkFBeUIsR0FBRyxHQUFHLENBQUE7QUFDckMsTUFBTSx3QkFBd0IsR0FBRyxHQUFHLENBQUE7QUFFcEM7Ozs7OztHQU1HO0FBQ0gsU0FBUyxNQUFNLENBQUMsTUFBTSxFQUFFLFNBQVM7SUFDL0IsTUFBTSxhQUFhLEdBQUcsRUFBRSxDQUFBO0lBRXhCLEtBQUssSUFBSSxLQUFLLEdBQUcsQ0FBQyxFQUFFLEtBQUssR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLEtBQUssSUFBSSxTQUFTLEVBQUUsQ0FBQztRQUM5RCxhQUFhLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLEtBQUssR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFBO0lBQzVELENBQUM7SUFFRCxPQUFPLGFBQWEsQ0FBQTtBQUN0QixDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQVMsYUFBYSxDQUFDLE1BQU07SUFDM0IsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFBO0FBQ2xHLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUNILE1BQU0sQ0FBQyxPQUFPLE9BQU8sVUFBVTtJQUM3Qjs7Ozs7Ozs7Ozs7T0FXRztJQUNILFlBQVksRUFBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxRQUFRLEdBQUcsSUFBSSxF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LENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxlQUFlLENBQUMsRUFBRSxFQUFFLE1BQU07UUFDeEIsT0FBTyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO0lBQzFELENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLEVBQUUsR0FBRztRQUM3QixPQUFPLE1BQU0sRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsRUFBQyxRQUFRLEVBQUUsS0FBSyxFQUFDLENBQUMsQ0FBQTtJQUMvQyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxFQUFDLE9BQU8sRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBQztRQUNwRCxNQUFNLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxFQUFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFDLENBQUMsQ0FBQyxDQUFBO0lBQzVFLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsY0FBYyxDQUFDLE9BQU87UUFDcEIsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDcEIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUMxQixDQUFDO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmNvbnN0IERFRkFVTFRfSU5TRVJUX0NIVU5LX1NJWkUgPSAxMDBcbmNvbnN0IERFRkFVTFRfUVVFUllfQ0hVTktfU0laRSA9IDUwMFxuXG4vKipcbiAqIFNwbGl0cyBhbiBhcnJheSBpbnRvIGNodW5rcyBvZiBhdCBtb3N0IGBjaHVua1NpemVgIGl0ZW1zLlxuICogQHRlbXBsYXRlIFRcbiAqIEBwYXJhbSB7VFtdfSB2YWx1ZXMgLSBPcmRlcmVkIGl0ZW1zIHRvIHBhcnRpdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBjaHVua1NpemUgLSBNYXhpbXVtIGl0ZW1zIHBlciBjaHVuay5cbiAqIEByZXR1cm5zIHtUW11bXX0gLSBDb25zZWN1dGl2ZSBjaHVua3MgcHJlc2VydmluZyBpbnB1dCBvcmRlci5cbiAqL1xuZnVuY3Rpb24gY2h1bmtzKHZhbHVlcywgY2h1bmtTaXplKSB7XG4gIGNvbnN0IGNodW5rZWRWYWx1ZXMgPSBbXVxuXG4gIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCB2YWx1ZXMubGVuZ3RoOyBpbmRleCArPSBjaHVua1NpemUpIHtcbiAgICBjaHVua2VkVmFsdWVzLnB1c2godmFsdWVzLnNsaWNlKGluZGV4LCBpbmRleCArIGNodW5rU2l6ZSkpXG4gIH1cblxuICByZXR1cm4gY2h1bmtlZFZhbHVlc1xufVxuXG4vKipcbiAqIFN0cmluZ2lmaWVzIHZhbHVlcyBhbmQgcmV0dXJucyB0aGUgZGlzdGluY3QsIG5vbi1ibGFuayBvbmVzLCBwcmVzZXJ2aW5nIGZpcnN0LXNlZW4gb3JkZXIuXG4gKiBAcGFyYW0ge3Vua25vd25bXX0gdmFsdWVzIC0gQ2FuZGlkYXRlIGRhdGFiYXNlIGlkZW50aWZpZXJzIHRvIHN0cmluZ2lmeSBhbmQgZGVkdXBsaWNhdGUuXG4gKiBAcmV0dXJucyB7c3RyaW5nW119IC0gRGlzdGluY3Qgbm9uLWJsYW5rIGlkZW50aWZpZXJzIGluIGZpcnN0LXNlZW4gb3JkZXIuXG4gKi9cbmZ1bmN0aW9uIHVuaXF1ZVN0cmluZ3ModmFsdWVzKSB7XG4gIHJldHVybiBBcnJheS5mcm9tKG5ldyBTZXQodmFsdWVzLm1hcCgodmFsdWUpID0+IFN0cmluZyh2YWx1ZSkpLmZpbHRlcigodmFsdWUpID0+IHZhbHVlLnRyaW0oKSkpKVxufVxuXG4vKipcbiAqIENvcGllcyBhIHNpbmdsZSB0ZW5hbnQncyByb3dzIGZyb20gYSBzb3VyY2UgZGF0YWJhc2UgaW50byBhIHRhcmdldCBkYXRhYmFzZSwgZm9sbG93aW5nIGFcbiAqIHRhYmxlIHBsYW4gdGhhdCBwYXJ0aXRpb25zIGVhY2ggdGFibGUgZWl0aGVyIGJ5IGEgZGlyZWN0IHRlbmFudCBrZXkgY29sdW1uIG9yIGJ5XG4gKiBwYXJlbnQtaWQgdHJhdmVyc2FsLiBUaGlzIGlzIHRoZSByb3ctbGV2ZWwgY291bnRlcnBhcnQgdG8gc2NoZW1hIGNsb25pbmc6IG11bHRpLXRlbmFudFxuICogYXBwcyB0aGF0IGtlZXAgZWFjaCB0ZW5hbnQncyBkYXRhIGluIGl0cyBvd24gZGF0YWJhc2UgdXNlIGl0IHRvIChyZSltYXRlcmlhbGlzZSB0aGVcbiAqIHRlbmFudCdzIHJvd3MgZnJvbSBhIGdsb2JhbC90ZW1wbGF0ZSBkYXRhYmFzZS5cbiAqXG4gKiBUaGUgY29weSBpcyBkZWxldGUtdGhlbi1yZWluc2VydCBhbmQgdGhlcmVmb3JlIGlkZW1wb3RlbnQsIGFuZCBpdCBtaXJyb3JzIHRoZSBzb3VyY2VcbiAqIHNuYXBzaG90OiB0aGUgcm93cyB0byBkZWxldGUgYXJlIHRoZSB0ZW5hbnQncyAqY3VycmVudCogcm93cyBpbiB0aGUgdGFyZ2V0IChzZWxlY3RlZCB3aXRoXG4gKiB0aGUgc2FtZSBwbGFuIHRyYXZlcnNhbCBydW4gYWdhaW5zdCB0aGUgdGFyZ2V0KSwgc28gYSByb3cgdGhhdCB3YXMgcmVtb3ZlZCBmcm9tIHRoZSBzb3VyY2VcbiAqIHNpbmNlIHRoZSBsYXN0IGNvcHkgaXMgZHJvcHBlZCBmcm9tIHRoZSB0YXJnZXQgdG9vIHJhdGhlciB0aGFuIGxpbmdlcmluZy4gVGhlIGRlbGV0ZXMgcnVuXG4gKiBjaGlsZHJlbiBmaXJzdCBhbmQgdGhlIHNvdXJjZSBpbnNlcnRzIHBhcmVudHMgZmlyc3QsIGFsbCBpbnNpZGUgb25lIHRhcmdldCB0cmFuc2FjdGlvbiB3aXRoXG4gKiBmb3JlaWduLWtleSBlbmZvcmNlbWVudCBkaXNhYmxlZCBzbyB0aGUgb3JkZXJpbmcgbmV2ZXIgdHJpcHMgYSBjb25zdHJhaW50LiBSZWFkcywgZGVsZXRlc1xuICogYW5kIGluc2VydHMgYXJlIGNodW5rZWQgdG8gYm91bmQgc3RhdGVtZW50IHNpemUuXG4gKlxuICogVGhlIGNvcGllciBpcyBwb2xpY3ktZnJlZTogdGhlIGNhbGxlciBzdXBwbGllcyB0aGUgcGxhbiwgdGhlIHNvdXJjZS90YXJnZXQgZGF0YWJhc2VzIGFuZFxuICogdGhlIHRlbmFudCBrZXksIGFuZCB7QGxpbmsgRGF0YUNvcGllciNjb3B5fSByZXR1cm5zIHRoZSBsb2FkZWQgcm93cyBrZXllZCBieSB0YWJsZSBuYW1lIHNvXG4gKiB0aGUgY2FsbGVyIGNhbiBwZXJmb3JtIGFueSBhcHAtc3BlY2lmaWMgcG9zdC1jb3B5IHdvcmsgKGZvciBleGFtcGxlIHJlZ2lzdGVyaW5nIHJlY29yZFxuICogbG9jYXRpb25zKSB3aXRob3V0IHRoYXQgcG9saWN5IGxlYWtpbmcgaW50byB0aGUgZnJhbWV3b3JrLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBEYXRhQ29waWVyIHtcbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBjb3BpZXIgdGhhdCBtb3ZlcyB0ZW5hbnQtb3duZWQgcm93cyBmcm9tIGBzb3VyY2VEYmAgaW50byBgdGFyZ2V0RGJgLlxuICAgKiBAcGFyYW0ge3tcbiAgICogICBzb3VyY2VEYjogaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQsXG4gICAqICAgdGFyZ2V0RGI6IGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0LFxuICAgKiAgIHRhYmxlUGxhbjogaW1wb3J0KFwiLi90ZW5hbnQtdGFibGUtcGxhbi5qc1wiKS5UZW5hbnRUYWJsZVBsYW5FbnRyeVtdLFxuICAgKiAgIGlkQ29sdW1uPzogc3RyaW5nLFxuICAgKiAgIGluc2VydENodW5rU2l6ZT86IG51bWJlcixcbiAgICogICBxdWVyeUNodW5rU2l6ZT86IG51bWJlcixcbiAgICogICBvblByb2dyZXNzPzogKG1lc3NhZ2U6IHN0cmluZykgPT4gdm9pZFxuICAgKiB9fSBhcmdzIC0gU291cmNlLCB0YXJnZXQsIHRyYXZlcnNhbCBwbGFuLCBjaHVuayBsaW1pdHMsIGFuZCBwcm9ncmVzcyBoYW5kbGVyLlxuICAgKi9cbiAgY29uc3RydWN0b3Ioe3NvdXJjZURiLCB0YXJnZXREYiwgdGFibGVQbGFuLCBpZENvbHVtbiA9IFwiaWRcIiwgaW5zZXJ0Q2h1bmtTaXplID0gREVGQVVMVF9JTlNFUlRfQ0hVTktfU0laRSwgcXVlcnlDaHVua1NpemUgPSBERUZBVUxUX1FVRVJZX0NIVU5LX1NJWkUsIG9uUHJvZ3Jlc3N9KSB7XG4gICAgdGhpcy5zb3VyY2VEYiA9IHNvdXJjZURiXG4gICAgdGhpcy50YXJnZXREYiA9IHRhcmdldERiXG4gICAgdGhpcy50YWJsZVBsYW4gPSB0YWJsZVBsYW5cbiAgICB0aGlzLmlkQ29sdW1uID0gaWRDb2x1bW5cbiAgICB0aGlzLmluc2VydENodW5rU2l6ZSA9IGluc2VydENodW5rU2l6ZVxuICAgIHRoaXMucXVlcnlDaHVua1NpemUgPSBxdWVyeUNodW5rU2l6ZVxuICAgIHRoaXMub25Qcm9ncmVzcyA9IG9uUHJvZ3Jlc3NcbiAgfVxuXG4gIC8qKlxuICAgKiBDb3BpZXMgZXZlcnkgcGxhbiB0YWJsZSdzIHJvd3MgZm9yIGBrZXlWYWx1ZWAgZnJvbSB0aGUgc291cmNlIGludG8gdGhlIHRhcmdldCBhbmRcbiAgICogcmV0dXJucyB0aGUgY29waWVkIHNvdXJjZSByb3dzIGtleWVkIGJ5IHRhYmxlIG5hbWUuIFRoZSB0YXJnZXQncyBjdXJyZW50IHRlbmFudCByb3dzXG4gICAqIGFyZSBkZWxldGVkIChjaGlsZHJlbiBmaXJzdCkgYW5kIHRoZSBzb3VyY2Ugcm93cyBpbnNlcnRlZCAocGFyZW50cyBmaXJzdCkgaW4gYSBzaW5nbGVcbiAgICogdGFyZ2V0IHRyYW5zYWN0aW9uIHdpdGggZm9yZWlnbiBrZXlzIGRpc2FibGVkLlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5VmFsdWUgLSBUZW5hbnQga2V5IHNlbGVjdGluZyB0aGUgcm93cyB0byBjb3B5LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxNYXA8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdPj59IC0gQ29waWVkIHNvdXJjZSByb3dzIGdyb3VwZWQgYnkgdGFibGUgbmFtZS5cbiAgICovXG4gIGFzeW5jIGNvcHkoa2V5VmFsdWUpIHtcbiAgICBjb25zdCBzb3VyY2VSb3dzQnlUYWJsZU5hbWUgPSBhd2FpdCB0aGlzLmxvYWRSb3dzKHRoaXMuc291cmNlRGIsIGtleVZhbHVlKVxuICAgIGNvbnN0IHRhcmdldFJvd3NCeVRhYmxlTmFtZSA9IGF3YWl0IHRoaXMubG9hZFJvd3ModGhpcy50YXJnZXREYiwga2V5VmFsdWUpXG5cbiAgICBhd2FpdCB0aGlzLnRhcmdldERiLndpdGhEaXNhYmxlZEZvcmVpZ25LZXlzKGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHRoaXMudGFyZ2V0RGIudHJhbnNhY3Rpb24oYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCB0aGlzLmRlbGV0ZVRhcmdldFJvd3ModGFyZ2V0Um93c0J5VGFibGVOYW1lKVxuICAgICAgICBhd2FpdCB0aGlzLmluc2VydFRhcmdldFJvd3Moc291cmNlUm93c0J5VGFibGVOYW1lKVxuICAgICAgfSlcbiAgICB9KVxuXG4gICAgcmV0dXJuIHNvdXJjZVJvd3NCeVRhYmxlTmFtZVxuICB9XG5cbiAgLyoqXG4gICAqIERlbGV0ZXMgb25lIHRlbmFudCdzIHJvd3MgZnJvbSB0aGUgdGFyZ2V0IGRhdGFiYXNlLCBjaGlsZHJlbiBiZWZvcmUgcGFyZW50cywgd2l0aFxuICAgKiBmb3JlaWduIGtleXMgZGlzYWJsZWQgaW5zaWRlIGEgc2luZ2xlIHRyYW5zYWN0aW9uLiBUaGlzIGlzIGBjb3B5YCB3aXRob3V0IHRoZSByZWluc2VydDpcbiAgICogdGhlIHNhbWUgcGxhbiB0cmF2ZXJzYWwgc2VsZWN0cyB0aGUgdGVuYW50J3MgY3VycmVudCB0YXJnZXQgcm93cyBhbmQgYGRlbGV0ZVRhcmdldFJvd3NgXG4gICAqIHJlbW92ZXMgdGhlbSBjaGlsZHJlbi1maXJzdCBzbyB0aGUgb3JkZXJpbmcgbmV2ZXIgdHJpcHMgYSBmb3JlaWduIGtleS4gTXVsdGktdGVuYW50IGFwcHNcbiAgICogdXNlIGl0IHRvIHB1cmdlIGEgdGVuYW50IOKAlCBmb3IgZXhhbXBsZSBjbGVhcmluZyB0aGUgdGVuYW50J3MgbWFzdGVyIGNvcHkgaW4gdGhlXG4gICAqIGdsb2JhbC9kZWZhdWx0IGRhdGFiYXNlIG9uIHRlYXJkb3duLCBzbyBmb3JlaWduIGtleXMgc3RvcCByZWZlcmVuY2luZyB0aGUgdGVuYW50J3NcbiAgICogYWJvdXQtdG8tYmUtcmVtb3ZlZCByb290IHJvdy5cbiAgICpcbiAgICogUmV0dXJucyB0aGUgZGVsZXRlZCByb3dzIGtleWVkIGJ5IHRhYmxlIG5hbWUgc28gdGhlIGNhbGxlciBjYW4gcGVyZm9ybSBhbnkgYXBwLXNwZWNpZmljXG4gICAqIHBvc3QtZGVsZXRlIHdvcmsgKHJlY29yZC1sb2NhdGlvbiBjbGVhbnVwLCBhdWRpdGluZykgd2l0aG91dCB0aGF0IHBvbGljeSBsZWFraW5nIGludG8gdGhlXG4gICAqIGZyYW1ld29yay5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleVZhbHVlIC0gVGVuYW50IGtleSB3aG9zZSByb3dzIHNob3VsZCBiZSByZW1vdmVkIGZyb20gdGhlIHRhcmdldC5cbiAgICogQHJldHVybnMge1Byb21pc2U8TWFwPHN0cmluZywgUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXT4+fSAtIFRoZSBkZWxldGVkIHJvd3MgYnkgdGFibGUgbmFtZS5cbiAgICovXG4gIGFzeW5jIGRlbGV0ZVRlbmFudFJvd3Moa2V5VmFsdWUpIHtcbiAgICBjb25zdCByb3dzQnlUYWJsZU5hbWUgPSBhd2FpdCB0aGlzLmxvYWRSb3dzKHRoaXMudGFyZ2V0RGIsIGtleVZhbHVlKVxuXG4gICAgYXdhaXQgdGhpcy50YXJnZXREYi53aXRoRGlzYWJsZWRGb3JlaWduS2V5cyhhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCB0aGlzLnRhcmdldERiLnRyYW5zYWN0aW9uKGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5kZWxldGVUYXJnZXRSb3dzKHJvd3NCeVRhYmxlTmFtZSlcbiAgICAgIH0pXG4gICAgfSlcblxuICAgIHJldHVybiByb3dzQnlUYWJsZU5hbWVcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkcyB0aGUgcm93cyBmb3IgYGtleVZhbHVlYCBmb3IgZXZlcnkgdGFibGUgaW4gdGhlIHBsYW4gZnJvbSBgZGJgLCByZXNvbHZpbmdcbiAgICogcGFyZW50LXNjb3BlZCB0YWJsZXMgZnJvbSB0aGUgaWRzIGFscmVhZHkgc2VsZWN0ZWQgZm9yIHRoZWlyIHBhcmVudCB0YWJsZS4gVXNlZCBmb3JcbiAgICogYm90aCB0aGUgc291cmNlIHJvd3MgdG8gY29weSBhbmQgdGhlIHRhcmdldCdzIGN1cnJlbnQgdGVuYW50IHJvd3MgdG8gZGVsZXRlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBkYiAtIFNvdXJjZSBvciB0YXJnZXQgZGF0YWJhc2UgdG8gdHJhdmVyc2UuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXlWYWx1ZSAtIFRlbmFudCBrZXkgc2VsZWN0aW5nIHRoZSByb290IHBsYW4gcm93cy5cbiAgICogQHJldHVybnMge1Byb21pc2U8TWFwPHN0cmluZywgUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXT4+fSAtIExvYWRlZCByb3dzIGdyb3VwZWQgYnkgdGFibGUgbmFtZS5cbiAgICovXG4gIGFzeW5jIGxvYWRSb3dzKGRiLCBrZXlWYWx1ZSkge1xuICAgIHJldHVybiAoYXdhaXQgdGhpcy50cmF2ZXJzZVBsYW4oZGIsIGtleVZhbHVlKSkucm93c0J5VGFibGVOYW1lXG4gIH1cblxuICAvKipcbiAgICogTG9hZHMgb25seSB0aGUgaWRzIGZvciBga2V5VmFsdWVgIGZvciBldmVyeSB0YWJsZSBpbiB0aGUgcGxhbiBmcm9tIGBkYmAsIHVzaW5nIHRoZSBzYW1lXG4gICAqIHBhcmVudC9jaGlsZCB0cmF2ZXJzYWwgYXMge0BsaW5rIERhdGFDb3BpZXIjbG9hZFJvd3N9IGJ1dCBzZWxlY3RpbmcganVzdCB0aGUgaWQgY29sdW1uLlxuICAgKiBDYWxsZXJzIHRoYXQgb25seSBuZWVkIHRvIGNvbXBhcmUgcm93IG1lbWJlcnNoaXAg4oCUIGZvciBleGFtcGxlIHZlcmlmeWluZyBhIHRlbmFudCBhbHJlYWR5XG4gICAqIGhvbGRzIGV2ZXJ5IGRlZmF1bHQgcm93IGJlZm9yZSBhIGNsZWFudXAgZGVsZXRlIOKAlCBzaG91bGQgdXNlIHRoaXMgaW5zdGVhZCBvZiBsb2FkUm93cyBzb1xuICAgKiB0aGV5IG5ldmVyIG1hdGVyaWFsaXNlIGZ1bGwgcm93czsgZm9yIGxhcmdlIHRlbmFudHMgdGhhdCBpcyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIGEgZmV3XG4gICAqIGtpbG9ieXRlcyBvZiBpZHMgYW5kIGdpZ2FieXRlcyBvZiByb3cgZGF0YS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gZGIgLSBTb3VyY2Ugb3IgdGFyZ2V0IGRhdGFiYXNlIHRvIHRyYXZlcnNlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5VmFsdWUgLSBUZW5hbnQga2V5IHNlbGVjdGluZyB0aGUgcm9vdCBwbGFuIHJvd3MuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPE1hcDxzdHJpbmcsIHN0cmluZ1tdPj59IC0gTG9hZGVkIGlkcyBncm91cGVkIGJ5IHRhYmxlIG5hbWUuXG4gICAqL1xuICBhc3luYyBsb2FkUm93SWRzKGRiLCBrZXlWYWx1ZSkge1xuICAgIHJldHVybiAoYXdhaXQgdGhpcy50cmF2ZXJzZVBsYW4oZGIsIGtleVZhbHVlLCBbdGhpcy5pZENvbHVtbl0pKS5pZHNCeVRhYmxlTmFtZVxuICB9XG5cbiAgLyoqXG4gICAqIFRyYXZlcnNlcyB0aGUgdGFibGUgcGxhbiBmb3IgYGtleVZhbHVlYCwgcXVlcnlpbmcgZWFjaCB0YWJsZSBieSBpdHMgdGVuYW50IGtleSBjb2x1bW4gb3JcbiAgICogKGZvciBjaGlsZCB0YWJsZXMpIGJ5IHRoZSBpZHMgYWxyZWFkeSBzZWxlY3RlZCBmb3IgaXRzIHBhcmVudCwgYW5kIHJldHVybnMgYm90aCB0aGUgaWRzXG4gICAqIGFuZCB0aGUgbG9hZGVkIHJvd3MgZ3JvdXBlZCBieSB0YWJsZSBuYW1lLiBgc2VsZWN0Q29sdW1uc2AgYm91bmRzIHRoZSBjb2x1bW5zIGVhY2ggcXVlcnlcbiAgICogc2VsZWN0czsgcGFzcyBgW2lkQ29sdW1uXWAgZm9yIGFuIGlkLW9ubHkgdHJhdmVyc2FsLCBvciBvbWl0IGl0IHRvIGxvYWQgZnVsbCByb3dzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBkYiAtIFNvdXJjZSBvciB0YXJnZXQgZGF0YWJhc2UgdG8gdHJhdmVyc2UuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXlWYWx1ZSAtIFRlbmFudCBrZXkgc2VsZWN0aW5nIHRoZSByb290IHBsYW4gcm93cy5cbiAgICogQHBhcmFtIHtzdHJpbmdbXX0gW3NlbGVjdENvbHVtbnNdIC0gQ29sdW1ucyB0byBzZWxlY3Q7IGRlZmF1bHRzIHRvIGV2ZXJ5IGNvbHVtbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8e2lkc0J5VGFibGVOYW1lOiBNYXA8c3RyaW5nLCBzdHJpbmdbXT4sIHJvd3NCeVRhYmxlTmFtZTogTWFwPHN0cmluZywgUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXT59Pn0gLSBJZHMgYW5kIHJvd3MgZ3JvdXBlZCBieSB0YWJsZSBuYW1lLlxuICAgKi9cbiAgYXN5bmMgdHJhdmVyc2VQbGFuKGRiLCBrZXlWYWx1ZSwgc2VsZWN0Q29sdW1ucykge1xuICAgIC8qKiBAdHlwZSB7TWFwPHN0cmluZywgc3RyaW5nW10+fSAqL1xuICAgIGNvbnN0IGlkc0J5VGFibGVOYW1lID0gbmV3IE1hcCgpXG4gICAgLyoqIEB0eXBlIHtNYXA8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdPn0gKi9cbiAgICBjb25zdCByb3dzQnlUYWJsZU5hbWUgPSBuZXcgTWFwKClcblxuICAgIGZvciAoY29uc3QgdGFibGVDb25maWcgb2YgdGhpcy50YWJsZVBsYW4pIHtcbiAgICAgIGxldCByb3dzXG5cbiAgICAgIGlmICh0YWJsZUNvbmZpZy5rZXlDb2x1bW4pIHtcbiAgICAgICAgcm93cyA9IGF3YWl0IHRoaXMucXVlcnlSb3dzQnlDb2x1bW4oe1xuICAgICAgICAgIGNvbHVtbk5hbWU6IHRhYmxlQ29uZmlnLmtleUNvbHVtbixcbiAgICAgICAgICBkYixcbiAgICAgICAgICBzZWxlY3RDb2x1bW5zLFxuICAgICAgICAgIHRhYmxlTmFtZTogdGFibGVDb25maWcudGFibGVOYW1lLFxuICAgICAgICAgIHZhbHVlczogW2tleVZhbHVlXVxuICAgICAgICB9KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKCF0YWJsZUNvbmZpZy5wYXJlbnRDb2x1bW4gfHwgIXRhYmxlQ29uZmlnLnBhcmVudFRhYmxlTmFtZSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQga2V5Q29sdW1uIG9yIHBhcmVudFRhYmxlTmFtZStwYXJlbnRDb2x1bW4gZm9yIHRhYmxlICR7dGFibGVDb25maWcudGFibGVOYW1lfSBpbiB0aGUgdGVuYW50IHRhYmxlIHBsYW4uYClcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghaWRzQnlUYWJsZU5hbWUuaGFzKHRhYmxlQ29uZmlnLnBhcmVudFRhYmxlTmFtZSkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFRlbmFudCB0YWJsZSBwbGFuIGVudHJ5ICR7dGFibGVDb25maWcudGFibGVOYW1lfSByZWZlcmVuY2VzIHBhcmVudCB0YWJsZSAke3RhYmxlQ29uZmlnLnBhcmVudFRhYmxlTmFtZX0sIHdoaWNoIGhhcyBub3QgYmVlbiBsb2FkZWQ7IHBhcmVudCB0YWJsZXMgbXVzdCBhcHBlYXIgYmVmb3JlIHRoZWlyIGNoaWxkcmVuIGluIHRoZSBwbGFuLmApXG4gICAgICAgIH1cblxuICAgICAgICByb3dzID0gYXdhaXQgdGhpcy5xdWVyeVJvd3NCeUNvbHVtbih7XG4gICAgICAgICAgY29sdW1uTmFtZTogdGFibGVDb25maWcucGFyZW50Q29sdW1uLFxuICAgICAgICAgIGRiLFxuICAgICAgICAgIHNlbGVjdENvbHVtbnMsXG4gICAgICAgICAgdGFibGVOYW1lOiB0YWJsZUNvbmZpZy50YWJsZU5hbWUsXG4gICAgICAgICAgdmFsdWVzOiBpZHNCeVRhYmxlTmFtZS5nZXQodGFibGVDb25maWcucGFyZW50VGFibGVOYW1lKSB8fCBbXVxuICAgICAgICB9KVxuICAgICAgfVxuXG4gICAgICBpZiAocm93cy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRoaXMucmVwb3J0UHJvZ3Jlc3MoYCR7dGFibGVDb25maWcudGFibGVOYW1lfTogbG9hZGVkICR7cm93cy5sZW5ndGh9IHJvdyhzKWApXG4gICAgICB9XG5cbiAgICAgIGlkc0J5VGFibGVOYW1lLnNldCh0YWJsZUNvbmZpZy50YWJsZU5hbWUsIHVuaXF1ZVN0cmluZ3Mocm93cy5tYXAoKHJvdykgPT4gcm93W3RoaXMuaWRDb2x1bW5dKSkpXG4gICAgICByb3dzQnlUYWJsZU5hbWUuc2V0KHRhYmxlQ29uZmlnLnRhYmxlTmFtZSwgcm93cylcbiAgICB9XG5cbiAgICByZXR1cm4ge2lkc0J5VGFibGVOYW1lLCByb3dzQnlUYWJsZU5hbWV9XG4gIH1cblxuICAvKipcbiAgICogU2VsZWN0cyBgdGFibGVOYW1lYCByb3dzIGluIGBkYmAgd2hvc2UgYGNvbHVtbk5hbWVgIGlzIGluIGB2YWx1ZXNgLCBjaHVua2VkLiBgc2VsZWN0Q29sdW1uc2BcbiAgICogYm91bmRzIHRoZSBwcm9qZWN0aW9uIGFuZCBkZWZhdWx0cyB0byBldmVyeSBjb2x1bW4uXG4gICAqIEBwYXJhbSB7e2NvbHVtbk5hbWU6IHN0cmluZywgZGI6IGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0LCBzZWxlY3RDb2x1bW5zPzogc3RyaW5nW10sIHRhYmxlTmFtZTogc3RyaW5nLCB2YWx1ZXM6IHN0cmluZ1tdfX0gYXJncyAtIFRhYmxlLCBjb2x1bW4sIHByb2plY3Rpb24sIGRhdGFiYXNlLCBhbmQgdmFsdWVzIGZvciB0aGUgY2h1bmtlZCBsb29rdXAuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFJlY29yZDxzdHJpbmcsIHVua25vd24+W10+fSAtIFJvd3MgbWF0Y2hpbmcgdGhlIHN1cHBsaWVkIGNvbHVtbiB2YWx1ZXMuXG4gICAqL1xuICBhc3luYyBxdWVyeVJvd3NCeUNvbHVtbih7Y29sdW1uTmFtZSwgZGIsIHNlbGVjdENvbHVtbnMsIHRhYmxlTmFtZSwgdmFsdWVzfSkge1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRWYWx1ZXMgPSB1bmlxdWVTdHJpbmdzKHZhbHVlcylcblxuICAgIGlmIChub3JtYWxpemVkVmFsdWVzLmxlbmd0aCA8PSAwKSB7XG4gICAgICByZXR1cm4gW11cbiAgICB9XG5cbiAgICBjb25zdCByb3dzID0gW11cbiAgICBjb25zdCBxdW90ZWRUYWJsZSA9IGRiLnF1b3RlVGFibGUodGFibGVOYW1lKVxuICAgIGNvbnN0IHF1b3RlZENvbHVtbiA9IGRiLnF1b3RlQ29sdW1uKGNvbHVtbk5hbWUpXG4gICAgY29uc3Qgc2VsZWN0TGlzdCA9IHNlbGVjdENvbHVtbnNcbiAgICAgID8gc2VsZWN0Q29sdW1ucy5tYXAoKGNvbHVtbikgPT4gYCR7cXVvdGVkVGFibGV9LiR7ZGIucXVvdGVDb2x1bW4oY29sdW1uKX1gKS5qb2luKFwiLCBcIilcbiAgICAgIDogYCR7cXVvdGVkVGFibGV9LipgXG5cbiAgICBmb3IgKGNvbnN0IHZhbHVlc0NodW5rIG9mIGNodW5rcyhub3JtYWxpemVkVmFsdWVzLCB0aGlzLnF1ZXJ5Q2h1bmtTaXplKSkge1xuICAgICAgY29uc3Qgc3FsID0gYFNFTEVDVCAke3NlbGVjdExpc3R9IEZST00gJHtxdW90ZWRUYWJsZX0gV0hFUkUgJHtxdW90ZWRDb2x1bW59IElOICgke3RoaXMucXVvdGVkVmFsdWVzU3FsKGRiLCB2YWx1ZXNDaHVuayl9KWBcblxuICAgICAgcm93cy5wdXNoKC4uLmF3YWl0IHRoaXMuZXhlY3V0ZVF1aWV0UXVlcnkoZGIsIHNxbCkpXG4gICAgfVxuXG4gICAgcmV0dXJuIHJvd3NcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIHRoZSBtYXRjaGluZyB0YXJnZXQgcm93cyBmb3IgZXZlcnkgcGxhbiB0YWJsZSwgY2hpbGRyZW4gYmVmb3JlIHBhcmVudHMsIHNvIHRoZVxuICAgKiByZWluc2VydCB0aGF0IGZvbGxvd3Mgc3RhcnRzIGZyb20gYSBjbGVhbiBzbGF0ZSB3aXRob3V0IHZpb2xhdGluZyBmb3JlaWduIGtleXMuXG4gICAqIEBwYXJhbSB7TWFwPHN0cmluZywgUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXT59IHJvd3NCeVRhYmxlTmFtZSAtIFJvd3MgZ3JvdXBlZCBieSB0YWJsZSBuYW1lLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIGFzeW5jIGRlbGV0ZVRhcmdldFJvd3Mocm93c0J5VGFibGVOYW1lKSB7XG4gICAgZm9yIChjb25zdCB0YWJsZUNvbmZpZyBvZiBbLi4udGhpcy50YWJsZVBsYW5dLnJldmVyc2UoKSkge1xuICAgICAgY29uc3Qgcm93SWRzID0gdW5pcXVlU3RyaW5ncygocm93c0J5VGFibGVOYW1lLmdldCh0YWJsZUNvbmZpZy50YWJsZU5hbWUpIHx8IFtdKS5tYXAoKHJvdykgPT4gcm93W3RoaXMuaWRDb2x1bW5dKSlcblxuICAgICAgaWYgKHJvd0lkcy5sZW5ndGggPD0gMCkge1xuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBjb25zdCBxdW90ZWRUYWJsZSA9IHRoaXMudGFyZ2V0RGIucXVvdGVUYWJsZSh0YWJsZUNvbmZpZy50YWJsZU5hbWUpXG4gICAgICBjb25zdCBxdW90ZWRJZENvbHVtbiA9IHRoaXMudGFyZ2V0RGIucXVvdGVDb2x1bW4odGhpcy5pZENvbHVtbilcblxuICAgICAgZm9yIChjb25zdCByb3dJZHNDaHVuayBvZiBjaHVua3Mocm93SWRzLCB0aGlzLnF1ZXJ5Q2h1bmtTaXplKSkge1xuICAgICAgICBhd2FpdCB0aGlzLmV4ZWN1dGVRdWlldFF1ZXJ5KFxuICAgICAgICAgIHRoaXMudGFyZ2V0RGIsXG4gICAgICAgICAgYERFTEVURSBGUk9NICR7cXVvdGVkVGFibGV9IFdIRVJFICR7cXVvdGVkSWRDb2x1bW59IElOICgke3RoaXMucXVvdGVkVmFsdWVzU3FsKHRoaXMudGFyZ2V0RGIsIHJvd0lkc0NodW5rKX0pYFxuICAgICAgICApXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEluc2VydHMgdGhlIGxvYWRlZCBzb3VyY2Ugcm93cyBpbnRvIHRoZSB0YXJnZXQgZm9yIGV2ZXJ5IHBsYW4gdGFibGUsIHBhcmVudHMgYmVmb3JlXG4gICAqIGNoaWxkcmVuLCBjaHVua2VkIHRvIGJvdW5kIHN0YXRlbWVudCBzaXplLlxuICAgKiBAcGFyYW0ge01hcDxzdHJpbmcsIFJlY29yZDxzdHJpbmcsIHVua25vd24+W10+fSByb3dzQnlUYWJsZU5hbWUgLSBSb3dzIGdyb3VwZWQgYnkgdGFibGUgbmFtZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBhc3luYyBpbnNlcnRUYXJnZXRSb3dzKHJvd3NCeVRhYmxlTmFtZSkge1xuICAgIGZvciAoY29uc3QgdGFibGVDb25maWcgb2YgdGhpcy50YWJsZVBsYW4pIHtcbiAgICAgIGNvbnN0IHJvd3MgPSByb3dzQnlUYWJsZU5hbWUuZ2V0KHRhYmxlQ29uZmlnLnRhYmxlTmFtZSkgfHwgW11cblxuICAgICAgaWYgKHJvd3MubGVuZ3RoIDw9IDApIHtcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgY29uc3QgY29sdW1ucyA9IE9iamVjdC5rZXlzKHJvd3NbMF0pXG4gICAgICBjb25zdCBpbnNlcnRDaHVua3MgPSBjaHVua3Mocm93cywgdGhpcy5pbnNlcnRDaHVua1NpemUpXG5cbiAgICAgIHRoaXMucmVwb3J0UHJvZ3Jlc3MoYCR7dGFibGVDb25maWcudGFibGVOYW1lfTogaW5zZXJ0aW5nICR7cm93cy5sZW5ndGh9IHJvdyhzKSBpbiAke2luc2VydENodW5rcy5sZW5ndGh9IGNodW5rKHMpYClcblxuICAgICAgZm9yIChjb25zdCByb3dzQ2h1bmsgb2YgaW5zZXJ0Q2h1bmtzKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuaW5zZXJ0Um93c1F1aWV0bHkoe1xuICAgICAgICAgIGNvbHVtbnMsXG4gICAgICAgICAgZGI6IHRoaXMudGFyZ2V0RGIsXG4gICAgICAgICAgcm93czogcm93c0NodW5rLm1hcCgocm93KSA9PiBjb2x1bW5zLm1hcCgoY29sdW1uKSA9PiByb3dbY29sdW1uXSkpLFxuICAgICAgICAgIHRhYmxlTmFtZTogdGFibGVDb25maWcudGFibGVOYW1lXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFF1b3RlcyBhbmQgY29tbWEtam9pbnMgdmFsdWVzIGZvciBhbiBTUUwgYElOICguLi4pYCBsaXN0IGFnYWluc3QgdGhlIGdpdmVuIGRhdGFiYXNlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBkYiAtIERhdGFiYXNlIHdob3NlIHF1b3RpbmcgcnVsZXMgZm9ybWF0IHRoZSB2YWx1ZXMuXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IHZhbHVlcyAtIFZhbHVlcyB0byBxdW90ZSBmb3IgdGhlIGBJTmAgbGlzdC5cbiAgICogQHJldHVybnMge3N0cmluZ30gLSBRdW90ZWQgU1FMIHZhbHVlIGxpc3QuXG4gICAqL1xuICBxdW90ZWRWYWx1ZXNTcWwoZGIsIHZhbHVlcykge1xuICAgIHJldHVybiB2YWx1ZXMubWFwKCh2YWx1ZSkgPT4gZGIucXVvdGUodmFsdWUpKS5qb2luKFwiLCBcIilcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGEgcXVlcnkgd2l0aG91dCBwZXItcXVlcnkgbG9nZ2luZywgdXNlZCBmb3IgdGhlIGhpZ2gtdm9sdW1lIGNvcHkgc3RhdGVtZW50cy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gZGIgLSBEYXRhYmFzZSBvbiB3aGljaCB0byBleGVjdXRlIHRoZSBjb3B5IHF1ZXJ5LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc3FsIC0gQ29weS1yZWxhdGVkIFNRTCBzdGF0ZW1lbnQgdG8gZXhlY3V0ZSBxdWlldGx5LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdPn0gLSBRdWVyeSByZXN1bHQgcm93cy5cbiAgICovXG4gIGFzeW5jIGV4ZWN1dGVRdWlldFF1ZXJ5KGRiLCBzcWwpIHtcbiAgICByZXR1cm4gYXdhaXQgZGIucXVlcnkoc3FsLCB7bG9nUXVlcnk6IGZhbHNlfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBJbnNlcnRzIGNvbHVtbi1hbGlnbmVkIHJvdyB0dXBsZXMgaW50byBhIHRhYmxlIHdpdGhvdXQgcGVyLXF1ZXJ5IGxvZ2dpbmcuXG4gICAqIEBwYXJhbSB7e2NvbHVtbnM6IHN0cmluZ1tdLCBkYjogaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQsIHJvd3M6IEFycmF5PEFycmF5PHVua25vd24+PiwgdGFibGVOYW1lOiBzdHJpbmd9fSBhcmdzIC0gRGVzdGluYXRpb24gdGFibGUgYW5kIGNvbHVtbi1hbGlnbmVkIHJvdyB2YWx1ZXMgdG8gaW5zZXJ0LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIGFzeW5jIGluc2VydFJvd3NRdWlldGx5KHtjb2x1bW5zLCBkYiwgcm93cywgdGFibGVOYW1lfSkge1xuICAgIGF3YWl0IHRoaXMuZXhlY3V0ZVF1aWV0UXVlcnkoZGIsIGRiLmluc2VydFNxbCh7Y29sdW1ucywgdGFibGVOYW1lLCByb3dzfSkpXG4gIH1cblxuICAvKipcbiAgICogRm9yd2FyZHMgYSBwcm9ncmVzcyBtZXNzYWdlIHRvIHRoZSBvcHRpb25hbCBgb25Qcm9ncmVzc2AgY2FsbGJhY2sgd2hlbiBvbmUgd2FzIGdpdmVuLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSAtIENvcHkgcHJvZ3Jlc3MgbWVzc2FnZSB0byBmb3J3YXJkIHdoZW4gcmVwb3J0aW5nIGlzIGVuYWJsZWQuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgcmVwb3J0UHJvZ3Jlc3MobWVzc2FnZSkge1xuICAgIGlmICh0aGlzLm9uUHJvZ3Jlc3MpIHtcbiAgICAgIHRoaXMub25Qcm9ncmVzcyhtZXNzYWdlKVxuICAgIH1cbiAgfVxufVxuIl19
|
package/package.json
CHANGED
|
@@ -320,19 +320,32 @@ export default class VelociousDatabaseDriversMysql extends Base{
|
|
|
320
320
|
* @returns {import("../base.js").RetryableDatabaseErrorResult} - Retry info.
|
|
321
321
|
*/
|
|
322
322
|
retryableDatabaseError(error) {
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
message.
|
|
330
|
-
|
|
331
|
-
|
|
323
|
+
/** @type {Error | undefined} */
|
|
324
|
+
let currentError = error
|
|
325
|
+
let shouldReconnect = false
|
|
326
|
+
|
|
327
|
+
while (currentError) {
|
|
328
|
+
const errorCode = "code" in currentError && typeof currentError.code == "string" ? currentError.code : undefined
|
|
329
|
+
const message = currentError.message || ""
|
|
330
|
+
|
|
331
|
+
if (errorCode == "ER_CHECKREAD" || message.includes("Record has changed since last read")) {
|
|
332
|
+
return {retry: true, reconnect: false, waitMs: 50}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
shouldReconnect ||= (
|
|
336
|
+
errorCode == "ECONNREFUSED" ||
|
|
337
|
+
message.includes("ECONNREFUSED") ||
|
|
338
|
+
message.includes("connect ECONNREFUSED") ||
|
|
339
|
+
message.includes("PROTOCOL_CONNECTION_LOST") ||
|
|
340
|
+
message.includes("Connection lost")
|
|
341
|
+
)
|
|
342
|
+
|
|
343
|
+
currentError = currentError.cause instanceof Error ? currentError.cause : undefined
|
|
344
|
+
}
|
|
332
345
|
|
|
333
346
|
return {
|
|
334
|
-
retry:
|
|
335
|
-
reconnect:
|
|
347
|
+
retry: shouldReconnect,
|
|
348
|
+
reconnect: shouldReconnect,
|
|
336
349
|
waitMs: 50
|
|
337
350
|
}
|
|
338
351
|
}
|
|
@@ -130,6 +130,35 @@ export default class DataCopier {
|
|
|
130
130
|
* @returns {Promise<Map<string, Record<string, unknown>[]>>} - Loaded rows grouped by table name.
|
|
131
131
|
*/
|
|
132
132
|
async loadRows(db, keyValue) {
|
|
133
|
+
return (await this.traversePlan(db, keyValue)).rowsByTableName
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Loads only the ids for `keyValue` for every table in the plan from `db`, using the same
|
|
138
|
+
* parent/child traversal as {@link DataCopier#loadRows} but selecting just the id column.
|
|
139
|
+
* Callers that only need to compare row membership — for example verifying a tenant already
|
|
140
|
+
* holds every default row before a cleanup delete — should use this instead of loadRows so
|
|
141
|
+
* they never materialise full rows; for large tenants that is the difference between a few
|
|
142
|
+
* kilobytes of ids and gigabytes of row data.
|
|
143
|
+
* @param {import("../drivers/base.js").default} db - Source or target database to traverse.
|
|
144
|
+
* @param {string} keyValue - Tenant key selecting the root plan rows.
|
|
145
|
+
* @returns {Promise<Map<string, string[]>>} - Loaded ids grouped by table name.
|
|
146
|
+
*/
|
|
147
|
+
async loadRowIds(db, keyValue) {
|
|
148
|
+
return (await this.traversePlan(db, keyValue, [this.idColumn])).idsByTableName
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Traverses the table plan for `keyValue`, querying each table by its tenant key column or
|
|
153
|
+
* (for child tables) by the ids already selected for its parent, and returns both the ids
|
|
154
|
+
* and the loaded rows grouped by table name. `selectColumns` bounds the columns each query
|
|
155
|
+
* selects; pass `[idColumn]` for an id-only traversal, or omit it to load full rows.
|
|
156
|
+
* @param {import("../drivers/base.js").default} db - Source or target database to traverse.
|
|
157
|
+
* @param {string} keyValue - Tenant key selecting the root plan rows.
|
|
158
|
+
* @param {string[]} [selectColumns] - Columns to select; defaults to every column.
|
|
159
|
+
* @returns {Promise<{idsByTableName: Map<string, string[]>, rowsByTableName: Map<string, Record<string, unknown>[]>}>} - Ids and rows grouped by table name.
|
|
160
|
+
*/
|
|
161
|
+
async traversePlan(db, keyValue, selectColumns) {
|
|
133
162
|
/** @type {Map<string, string[]>} */
|
|
134
163
|
const idsByTableName = new Map()
|
|
135
164
|
/** @type {Map<string, Record<string, unknown>[]>} */
|
|
@@ -142,6 +171,7 @@ export default class DataCopier {
|
|
|
142
171
|
rows = await this.queryRowsByColumn({
|
|
143
172
|
columnName: tableConfig.keyColumn,
|
|
144
173
|
db,
|
|
174
|
+
selectColumns,
|
|
145
175
|
tableName: tableConfig.tableName,
|
|
146
176
|
values: [keyValue]
|
|
147
177
|
})
|
|
@@ -157,6 +187,7 @@ export default class DataCopier {
|
|
|
157
187
|
rows = await this.queryRowsByColumn({
|
|
158
188
|
columnName: tableConfig.parentColumn,
|
|
159
189
|
db,
|
|
190
|
+
selectColumns,
|
|
160
191
|
tableName: tableConfig.tableName,
|
|
161
192
|
values: idsByTableName.get(tableConfig.parentTableName) || []
|
|
162
193
|
})
|
|
@@ -170,15 +201,16 @@ export default class DataCopier {
|
|
|
170
201
|
rowsByTableName.set(tableConfig.tableName, rows)
|
|
171
202
|
}
|
|
172
203
|
|
|
173
|
-
return rowsByTableName
|
|
204
|
+
return {idsByTableName, rowsByTableName}
|
|
174
205
|
}
|
|
175
206
|
|
|
176
207
|
/**
|
|
177
|
-
* Selects
|
|
178
|
-
*
|
|
208
|
+
* Selects `tableName` rows in `db` whose `columnName` is in `values`, chunked. `selectColumns`
|
|
209
|
+
* bounds the projection and defaults to every column.
|
|
210
|
+
* @param {{columnName: string, db: import("../drivers/base.js").default, selectColumns?: string[], tableName: string, values: string[]}} args - Table, column, projection, database, and values for the chunked lookup.
|
|
179
211
|
* @returns {Promise<Record<string, unknown>[]>} - Rows matching the supplied column values.
|
|
180
212
|
*/
|
|
181
|
-
async queryRowsByColumn({columnName, db, tableName, values}) {
|
|
213
|
+
async queryRowsByColumn({columnName, db, selectColumns, tableName, values}) {
|
|
182
214
|
const normalizedValues = uniqueStrings(values)
|
|
183
215
|
|
|
184
216
|
if (normalizedValues.length <= 0) {
|
|
@@ -188,9 +220,12 @@ export default class DataCopier {
|
|
|
188
220
|
const rows = []
|
|
189
221
|
const quotedTable = db.quoteTable(tableName)
|
|
190
222
|
const quotedColumn = db.quoteColumn(columnName)
|
|
223
|
+
const selectList = selectColumns
|
|
224
|
+
? selectColumns.map((column) => `${quotedTable}.${db.quoteColumn(column)}`).join(", ")
|
|
225
|
+
: `${quotedTable}.*`
|
|
191
226
|
|
|
192
227
|
for (const valuesChunk of chunks(normalizedValues, this.queryChunkSize)) {
|
|
193
|
-
const sql = `SELECT ${
|
|
228
|
+
const sql = `SELECT ${selectList} FROM ${quotedTable} WHERE ${quotedColumn} IN (${this.quotedValuesSql(db, valuesChunk)})`
|
|
194
229
|
|
|
195
230
|
rows.push(...await this.executeQuietQuery(db, sql))
|
|
196
231
|
}
|