velocious 1.0.529 → 1.0.532
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/README.md +5 -2
- package/build/background-jobs/job-runner.js +5 -3
- package/build/background-jobs/pooled-runner-child.js +53 -16
- package/build/background-jobs/worker.js +193 -42
- package/build/configuration-types.js +1 -0
- package/build/configuration.js +33 -4
- package/build/database/drivers/mysql/sql/alter-table.js +42 -0
- package/build/database/query/preloader/belongs-to.js +9 -9
- package/build/database/query/preloader/has-many.js +8 -8
- package/build/database/query/preloader/has-one.js +5 -5
- package/build/database/tenants/schema-cloner.js +46 -9
- package/build/src/background-jobs/job-runner.d.ts +3 -1
- package/build/src/background-jobs/job-runner.d.ts.map +1 -1
- package/build/src/background-jobs/job-runner.js +8 -4
- package/build/src/background-jobs/pooled-runner-child.js +49 -18
- package/build/src/background-jobs/worker.d.ts +85 -14
- package/build/src/background-jobs/worker.d.ts.map +1 -1
- package/build/src/background-jobs/worker.js +189 -45
- package/build/src/configuration-types.d.ts +5 -0
- package/build/src/configuration-types.d.ts.map +1 -1
- package/build/src/configuration-types.js +2 -1
- package/build/src/configuration.d.ts +6 -0
- package/build/src/configuration.d.ts.map +1 -1
- package/build/src/configuration.js +34 -4
- package/build/src/database/drivers/mysql/sql/alter-table.d.ts.map +1 -1
- package/build/src/database/drivers/mysql/sql/alter-table.js +36 -1
- package/build/src/database/query/preloader/belongs-to.js +10 -12
- package/build/src/database/query/preloader/has-many.js +9 -11
- package/build/src/database/query/preloader/has-one.js +6 -7
- package/build/src/database/tenants/schema-cloner.d.ts +10 -0
- package/build/src/database/tenants/schema-cloner.d.ts.map +1 -1
- package/build/src/database/tenants/schema-cloner.js +36 -9
- package/package.json +3 -1
- package/src/background-jobs/job-runner.js +5 -3
- package/src/background-jobs/pooled-runner-child.js +53 -16
- package/src/background-jobs/worker.js +193 -42
- package/src/configuration-types.js +1 -0
- package/src/configuration.js +33 -4
- package/src/database/drivers/mysql/sql/alter-table.js +42 -0
- package/src/database/query/preloader/belongs-to.js +9 -9
- package/src/database/query/preloader/has-many.js +8 -8
- package/src/database/query/preloader/has-one.js +5 -5
- package/src/database/tenants/schema-cloner.js +46 -9
|
@@ -119,6 +119,27 @@ export default class SchemaCloner {
|
|
|
119
119
|
for (const sourceColumn of columnsNeedingWidening) {
|
|
120
120
|
tableData.addColumn(sourceColumn.getName(), this.columnArgsFromSourceColumn(sourceColumn, { isNewColumn: false }));
|
|
121
121
|
}
|
|
122
|
+
if (this.targetDb.getType() === "mysql") {
|
|
123
|
+
const missingAutoIncrementColumnNames = new Set(missingColumns
|
|
124
|
+
.filter((sourceColumn) => sourceColumn.getAutoIncrement())
|
|
125
|
+
.map((sourceColumn) => sourceColumn.getName()));
|
|
126
|
+
const targetIndexesByName = new Map((await targetTable.getIndexes()).map((targetIndex) => [targetIndex.getName(), targetIndex]));
|
|
127
|
+
for (const sourceIndex of await sourceTable.getIndexes()) {
|
|
128
|
+
if (!sourceIndex.isPrimaryKey() &&
|
|
129
|
+
sourceIndex.isUnique() &&
|
|
130
|
+
missingAutoIncrementColumnNames.has(sourceIndex.getColumnNames()[0])) {
|
|
131
|
+
const targetIndex = targetIndexesByName.get(sourceIndex.getName());
|
|
132
|
+
if (targetIndex) {
|
|
133
|
+
if (this.indexesMatch(sourceIndex, targetIndex))
|
|
134
|
+
continue;
|
|
135
|
+
this.assertSafeIndexReplacement({ sourceIndex, tableName, targetIndex });
|
|
136
|
+
await this.dropTargetIndex({ tableName, targetIndex });
|
|
137
|
+
targetIndexesByName.delete(targetIndex.getName());
|
|
138
|
+
}
|
|
139
|
+
tableData.addIndex(this.tableDataIndexFromSourceIndex(sourceIndex));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
122
143
|
for (const alterSql of await this.targetDb.alterTableSQLs(tableData)) {
|
|
123
144
|
await this.targetDb.query(alterSql);
|
|
124
145
|
}
|
|
@@ -154,14 +175,7 @@ export default class SchemaCloner {
|
|
|
154
175
|
const targetIndex = this.targetDb.getType() === "sqlite" ? undefined : targetIndexesByName.get(sourceIndex.getName());
|
|
155
176
|
if (targetIndex) {
|
|
156
177
|
if (!this.indexesMatch(sourceIndex, targetIndex)) {
|
|
157
|
-
|
|
158
|
-
// the target may have duplicate values that will reject the new
|
|
159
|
-
// unique constraint, and the old index was already dropped by this
|
|
160
|
-
// point. The opposite direction (unique → non-unique) is always
|
|
161
|
-
// safe — non-unique indexes never fail on duplicate values.
|
|
162
|
-
if (sourceIndex.isUnique() && !targetIndex.isUnique()) {
|
|
163
|
-
throw new Error(`Schema clone index drift for ${tableName}.${sourceIndex.getName()}: cannot safely replace a non-unique index with a unique one.`);
|
|
164
|
-
}
|
|
178
|
+
this.assertSafeIndexReplacement({ sourceIndex, tableName, targetIndex });
|
|
165
179
|
await this.dropTargetIndex({ tableName, targetIndex });
|
|
166
180
|
targetIndexesByName.delete(targetIndex.getName());
|
|
167
181
|
targetIndexSignatures.delete(this.indexSignature(targetIndex));
|
|
@@ -200,6 +214,19 @@ export default class SchemaCloner {
|
|
|
200
214
|
await this.targetDb.query(sql);
|
|
201
215
|
}
|
|
202
216
|
}
|
|
217
|
+
/**
|
|
218
|
+
* Refuses index replacements that could fail after the existing index is dropped.
|
|
219
|
+
* @param {{sourceIndex: import("../drivers/base-columns-index.js").default, tableName: string, targetIndex: import("../drivers/base-columns-index.js").default}} args - Source and target index definitions.
|
|
220
|
+
* @returns {void}
|
|
221
|
+
*/
|
|
222
|
+
assertSafeIndexReplacement({ sourceIndex, tableName, targetIndex }) {
|
|
223
|
+
// Replacing a non-unique index with a unique one is unsafe because the
|
|
224
|
+
// target may have duplicate values that will reject the new constraint.
|
|
225
|
+
// The opposite direction is safe because non-unique indexes accept them.
|
|
226
|
+
if (sourceIndex.isUnique() && !targetIndex.isUnique()) {
|
|
227
|
+
throw new Error(`Schema clone index drift for ${tableName}.${sourceIndex.getName()}: cannot safely replace a non-unique index with a unique one.`);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
203
230
|
/**
|
|
204
231
|
* Baselines the target ledger so the cloned schema is recorded as already-applied.
|
|
205
232
|
* @returns {Promise<string[]>} The versions newly recorded on the target.
|
|
@@ -355,4 +382,4 @@ export default class SchemaCloner {
|
|
|
355
382
|
return columnArgs;
|
|
356
383
|
}
|
|
357
384
|
}
|
|
358
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZW1hLWNsb25lci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9kYXRhYmFzZS90ZW5hbnRzL3NjaGVtYS1jbG9uZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sZ0JBQWdCLE1BQU0seUJBQXlCLENBQUE7QUFDdEQsT0FBTyxTQUFTLE1BQU0sd0JBQXdCLENBQUE7QUFDOUMsT0FBTyxVQUFVLE1BQU0sOEJBQThCLENBQUE7QUFFckQsTUFBTSxzQkFBc0IsR0FBRyw2Q0FBNkMsQ0FBQTtBQUU1RSxxQ0FBcUM7QUFDckMsTUFBTSxlQUFlLEdBQUc7SUFDdEIsUUFBUSxFQUFFLENBQUM7SUFDWCxJQUFJLEVBQUUsQ0FBQztJQUNQLFVBQVUsRUFBRSxDQUFDO0lBQ2IsUUFBUSxFQUFFLENBQUM7Q0FDWixDQUFBO0FBRUQ7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUNILE1BQU0sQ0FBQyxPQUFPLE9BQU8sWUFBWTtJQUMvQjs7O09BR0c7SUFDSCxZQUFZLEVBQUMsUUFBUSxFQUFFLFFBQVEsRUFBQztRQUM5QixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQTtRQUN4QixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQTtJQUMxQixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxLQUFLLENBQUMsVUFBVSxDQUFDLFVBQVU7UUFDekIsS0FBSyxNQUFNLFNBQVMsSUFBSSxVQUFVLEVBQUUsQ0FBQztZQUNuQyxNQUFNLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUE7UUFDakMsQ0FBQztRQUVELE1BQU0sSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFBO0lBQzlCLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILEtBQUssQ0FBQyxTQUFTLENBQUMsU0FBUztRQUN2QixNQUFNLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQyxDQUFBO1FB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RUFBRSxFQUFFLENBQUM7WUFDakQsVUFBVSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUE7UUFDOUIsQ0FBQztRQUVELElBQUksWUFBWSxDQUFDLGdCQUFnQixFQUFFLEVBQUUsQ0FBQztZQUNwQyxVQUFVLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQTtRQUNqQyxDQUFDO1FBRUQsa0ZBQWtGO1FBQ2xGLGtGQUFrRjtRQUNsRiwrRUFBK0U7UUFDL0UsSUFBSSxTQUFTLEtBQUssU0FBUyxJQUFJLFNBQVMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUM5QyxVQUFVLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQTtRQUNsQyxDQUFDO1FBRUQsSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUNWLFVBQVUsQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFBO1FBQzFCLENBQUM7UUFFRCxJQUFJLFlBQVksS0FBSyxJQUFJLElBQUksWUFBWSxLQUFLLFNBQVMsSUFBSSxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUM3RyxVQUFVLENBQUMsT0FBTyxHQUFHLFlBQVksQ0FBQTtRQUNuQyxDQUFDO1FBRUQsT0FBTyxVQUFVLENBQUE7SUFDbkIsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCBNaWdyYXRpb25zTGVkZ2VyIGZyb20gXCIuLi9taWdyYXRpb25zLWxlZGdlci5qc1wiXG5pbXBvcnQgVGFibGVEYXRhIGZyb20gXCIuLi90YWJsZS1kYXRhL2luZGV4LmpzXCJcbmltcG9ydCBUYWJsZUluZGV4IGZyb20gXCIuLi90YWJsZS1kYXRhL3RhYmxlLWluZGV4LmpzXCJcblxuY29uc3QgU0lNUExFX0RFRkFVTFRfUEFUVEVSTiA9IC9eKD86LT9cXGQrKD86XFwuXFxkKyk/fFtBLVphLXowLTkgXy4sOi9AKy1dKikkL1xuXG4vKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIG51bWJlcj59ICovXG5jb25zdCBURVhUX1RZUEVfUkFOS1MgPSB7XG4gIHRpbnl0ZXh0OiAxLFxuICB0ZXh0OiAyLFxuICBtZWRpdW10ZXh0OiAzLFxuICBsb25ndGV4dDogNFxufVxuXG4vKipcbiAqIENsb25lcyB0YWJsZSBzdHJ1Y3R1cmUgKGNvbHVtbnMsIHRleHQtdHlwZSB3aWRlbmluZywgaW5kZXhlcykgZnJvbSBhIHNvdXJjZSBkYXRhYmFzZVxuICogaW50byBhIHRhcmdldCBkYXRhYmFzZSBmb3IgYSBnaXZlbiBzZXQgb2YgdGFibGVzLCB0aGVuIGJhc2VsaW5lcyB0aGUgdGFyZ2V0J3NcbiAqIGBzY2hlbWFfbWlncmF0aW9uc2AgbGVkZ2VyIHRvIHRoZSBzb3VyY2UgdmlhIHtAbGluayBNaWdyYXRpb25zTGVkZ2VyfS4gVGhpcyBpcyB0aGVcbiAqIG1lY2hhbmlzbSBtdWx0aS10ZW5hbnQgYXBwcyB1c2UgdG8gcHJvdmlzaW9uIGEgdGVuYW50IGRhdGFiYXNlIGZyb20gYSB0ZW1wbGF0ZS9nbG9iYWxcbiAqIGRhdGFiYXNlIHdpdGhvdXQgcmUtcnVubmluZyBtaWdyYXRpb25zOiB0aGUgc3RydWN0dXJlIGlzIGNvcGllZCBhbmQgdGhlIGxlZGdlciBpc1xuICogcmVjb3JkZWQgYXMgYWxyZWFkeS1hcHBsaWVkLCBzbyBhIGxhdGVyIGBkYjp0ZW5hbnRzOm1pZ3JhdGVgIGRvZXMgbm90IHJlLXJ1biBhblxuICogYGFkZENvbHVtbmAgd2hvc2UgY29sdW1uIGFscmVhZHkgZXhpc3RzLlxuICpcbiAqIFRoZSBjbG9uZXIgaXMgaW50ZW50aW9uYWxseSBwb2xpY3ktZnJlZSDigJQgdGhlIGNhbGxlciBkZWNpZGVzIHdoaWNoIHRhYmxlcyB0byBzeW5jIGFuZFxuICogd2hpY2ggZGF0YWJhc2VzIGFyZSBzb3VyY2UvdGFyZ2V0LiBJdCBpcyBpZGVtcG90ZW50OiBtaXNzaW5nIHRhYmxlcyBhcmUgY3JlYXRlZCxcbiAqIG1pc3NpbmcgY29sdW1ucyBhZGRlZCwgdG9vLW5hcnJvdyB0ZXh0IGNvbHVtbnMgd2lkZW5lZCwgYW5kIG1pc3NpbmcgaW5kZXhlcyBjcmVhdGVkO1xuICogYW4gaW5kZXggd2hvc2UgZGVmaW5pdGlvbiBkaXZlcmdlcyBmcm9tIHRoZSBzb3VyY2UgaXMgdHJlYXRlZCBhcyBkcmlmdCBhbmQgdGhyb3dzLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTY2hlbWFDbG9uZXIge1xuICAvKipcbiAgICogQ3JlYXRlcyBhIGNsb25lciB0aGF0IGNvcGllcyB0YWJsZSBzdHJ1Y3R1cmUgZnJvbSBgc291cmNlRGJgIGludG8gYHRhcmdldERiYC5cbiAgICogQHBhcmFtIHt7c291cmNlRGI6IGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0LCB0YXJnZXREYjogaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9fSBhcmdzIC0gRGF0YWJhc2VzIHRvIGNsb25lIHN0cnVjdHVyZSBmcm9tIGFuZCBpbnRvLlxuICAgKi9cbiAgY29uc3RydWN0b3Ioe3NvdXJjZURiLCB0YXJnZXREYn0pIHtcbiAgICB0aGlzLnNvdXJjZURiID0gc291cmNlRGJcbiAgICB0aGlzLnRhcmdldERiID0gdGFyZ2V0RGJcbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9uZXMgZXZlcnkgZ2l2ZW4gdGFibGUgZnJvbSB0aGUgc291cmNlIGludG8gdGhlIHRhcmdldCwgdGhlbiBiYXNlbGluZXMgdGhlXG4gICAqIHRhcmdldCdzIGxlZGdlciBzbyB0aGUgY2xvbmVkIHNjaGVtYSBpcyByZWNvcmRlZCBhcyBhbHJlYWR5LW1pZ3JhdGVkLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSB0YWJsZU5hbWVzIC0gU291cmNlIHRhYmxlcyB3aG9zZSBzdHJ1Y3R1cmUgc2hvdWxkIGJlIGNsb25lZC5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBhc3luYyBzeW5jVGFibGVzKHRhYmxlTmFtZXMpIHtcbiAgICBmb3IgKGNvbnN0IHRhYmxlTmFtZSBvZiB0YWJsZU5hbWVzKSB7XG4gICAgICBhd2FpdCB0aGlzLnN5bmNUYWJsZSh0YWJsZU5hbWUpXG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5yZWNvbmNpbGVMZWRnZXIoKVxuICB9XG5cbiAgLyoqXG4gICAqIENsb25lcyBhIHNpbmdsZSB0YWJsZSBmcm9tIHRoZSBzb3VyY2UgaW50byB0aGUgdGFyZ2V0LCBjcmVhdGluZyBpdCBvciBhZGRpbmcgYW5kXG4gICAqIHdpZGVuaW5nIGNvbHVtbnMgYW5kIGluZGV4ZXMgYXMgbmVlZGVkLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFibGVOYW1lIC0gU291cmNlIHRhYmxlIHRvIHN5bmNocm9uaXplIHdpdGggdGhlIHRhcmdldC5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBhc3luYyBzeW5jVGFibGUodGFibGVOYW1lKSB7XG4gICAgY29uc3Qgc291cmNlVGFibGUgPSBhd2FpdCB0aGlzLnNvdXJjZURiLmdldFRhYmxlQnlOYW1lKHRhYmxlTmFtZSlcblxuICAgIGlmICghc291cmNlVGFibGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgc291cmNlIHRhYmxlIHRvIGV4aXN0OiAke3RhYmxlTmFtZX1gKVxuICAgIH1cblxuICAgIGlmICghYXdhaXQgdGhpcy50YXJnZXREYi50YWJsZUV4aXN0cyh0YWJsZU5hbWUpKSB7XG4gICAgICBhd2FpdCB0aGlzLmNyZWF0ZVRhcmdldFRhYmxlKHtzb3VyY2VUYWJsZSwgdGFibGVOYW1lfSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IGNoYW5nZWRDb2x1bW5zID0gYXdhaXQgdGhpcy5lbnN1cmVUYXJnZXRDb2x1bW5zKHtzb3VyY2VUYWJsZSwgdGFibGVOYW1lfSlcblxuICAgIGlmIChjaGFuZ2VkQ29sdW1ucykge1xuICAgICAgdGhpcy50YXJnZXREYi5jbGVhclNjaGVtYUNhY2hlKClcbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLmVuc3VyZVRhcmdldEluZGV4ZXMoe3NvdXJjZVRhYmxlLCB0YWJsZU5hbWV9KVxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgdGhlIHRhYmxlIGluIHRoZSB0YXJnZXQgZnJvbSB0aGUgc291cmNlIHRhYmxlJ3MgY29sdW1ucyBhbmQgaXRzXG4gICAqIG5vbi1wcmltYXJ5LWtleSBpbmRleGVzLlxuICAgKiBAcGFyYW0ge3tzb3VyY2VUYWJsZTogaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLXRhYmxlLmpzXCIpLmRlZmF1bHQsIHRhYmxlTmFtZTogc3RyaW5nfX0gYXJncyAtIFNvdXJjZSB0YWJsZSBtZXRhZGF0YSBhbmQgdGFyZ2V0IHRhYmxlIG5hbWUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fVxuICAgKi9cbiAgYXN5bmMgY3JlYXRlVGFyZ2V0VGFibGUoe3NvdXJjZVRhYmxlLCB0YWJsZU5hbWV9KSB7XG4gICAgY29uc3QgdGFibGVEYXRhID0gbmV3IFRhYmxlRGF0YSh0YWJsZU5hbWUpXG5cbiAgICBmb3IgKGNvbnN0IHNvdXJjZUNvbHVtbiBvZiBhd2FpdCBzb3VyY2VUYWJsZS5nZXRDb2x1bW5zKCkpIHtcbiAgICAgIHRhYmxlRGF0YS5hZGRDb2x1bW4oc291cmNlQ29sdW1uLmdldE5hbWUoKSwgdGhpcy5jb2x1bW5BcmdzRnJvbVNvdXJjZUNvbHVtbihzb3VyY2VDb2x1bW4sIHtpc05ld0NvbHVtbjogZmFsc2V9KSlcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHNvdXJjZUluZGV4IG9mIGF3YWl0IHNvdXJjZVRhYmxlLmdldEluZGV4ZXMoKSkge1xuICAgICAgaWYgKCFzb3VyY2VJbmRleC5pc1ByaW1hcnlLZXkoKSkge1xuICAgICAgICB0YWJsZURhdGEuYWRkSW5kZXgodGhpcy50YWJsZURhdGFJbmRleEZyb21Tb3VyY2VJbmRleChzb3VyY2VJbmRleCkpXG4gICAgICB9XG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy50YXJnZXREYi5jcmVhdGVUYWJsZSh0YWJsZURhdGEpXG4gICAgdGhpcy50YXJnZXREYi5jbGVhclNjaGVtYUNhY2hlKClcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGNvbHVtbnMgcHJlc2VudCBvbiB0aGUgc291cmNlIGJ1dCBtaXNzaW5nIGZyb20gdGhlIHRhcmdldCwgYW5kIHdpZGVuc1xuICAgKiB0b28tbmFycm93IHRhcmdldCB0ZXh0IGNvbHVtbnMuXG4gICAqIEBwYXJhbSB7e3NvdXJjZVRhYmxlOiBpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UtdGFibGUuanNcIikuZGVmYXVsdCwgdGFibGVOYW1lOiBzdHJpbmd9fSBhcmdzIC0gU291cmNlIHRhYmxlIG1ldGFkYXRhIGFuZCB0YXJnZXQgdGFibGUgbmFtZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8Ym9vbGVhbj59IFdoZXRoZXIgYW55IGNvbHVtbiB3YXMgYWRkZWQgb3Igd2lkZW5lZC5cbiAgICovXG4gIGFzeW5jIGVuc3VyZVRhcmdldENvbHVtbnMoe3NvdXJjZVRhYmxlLCB0YWJsZU5hbWV9KSB7XG4gICAgY29uc3Qgc291cmNlQ29sdW1ucyA9IGF3YWl0IHNvdXJjZVRhYmxlLmdldENvbHVtbnMoKVxuICAgIGNvbnN0IHRhcmdldFRhYmxlID0gYXdhaXQgdGhpcy50YXJnZXREYi5nZXRUYWJsZUJ5TmFtZU9yRmFpbCh0YWJsZU5hbWUpXG4gICAgY29uc3QgdGFyZ2V0Q29sdW1uc0J5TmFtZSA9IG5ldyBNYXAoKVxuICAgIGNvbnN0IG1pc3NpbmdDb2x1bW5zID0gW11cbiAgICBjb25zdCBjb2x1bW5zTmVlZGluZ1dpZGVuaW5nID0gW11cblxuICAgIGZvciAoY29uc3QgdGFyZ2V0Q29sdW1uIG9mIGF3YWl0IHRhcmdldFRhYmxlLmdldENvbHVtbnMoKSkge1xuICAgICAgdGFyZ2V0Q29sdW1uc0J5TmFtZS5zZXQodGFyZ2V0Q29sdW1uLmdldE5hbWUoKSwgdGFyZ2V0Q29sdW1uKVxuICAgIH1cblxuICAgIGZvciAoY29uc3Qgc291cmNlQ29sdW1uIG9mIHNvdXJjZUNvbHVtbnMpIHtcbiAgICAgIGNvbnN0IHRhcmdldENvbHVtbiA9IHRhcmdldENvbHVtbnNCeU5hbWUuZ2V0KHNvdXJjZUNvbHVtbi5nZXROYW1lKCkpXG5cbiAgICAgIGlmICghdGFyZ2V0Q29sdW1uKSB7XG4gICAgICAgIG1pc3NpbmdDb2x1bW5zLnB1c2goc291cmNlQ29sdW1uKVxuICAgICAgfSBlbHNlIGlmICh0aGlzLmNvbHVtbk5lZWRzV2lkZW5pbmcoc291cmNlQ29sdW1uLCB0YXJnZXRDb2x1bW4pKSB7XG4gICAgICAgIGNvbHVtbnNOZWVkaW5nV2lkZW5pbmcucHVzaChzb3VyY2VDb2x1bW4pXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG1pc3NpbmdDb2x1bW5zLmxlbmd0aCA8PSAwICYmIGNvbHVtbnNOZWVkaW5nV2lkZW5pbmcubGVuZ3RoIDw9IDApIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIGNvbnN0IHRhYmxlRGF0YSA9IG5ldyBUYWJsZURhdGEodGFibGVOYW1lKVxuXG4gICAgZm9yIChjb25zdCBzb3VyY2VDb2x1bW4gb2YgbWlzc2luZ0NvbHVtbnMpIHtcbiAgICAgIHRhYmxlRGF0YS5hZGRDb2x1bW4oc291cmNlQ29sdW1uLmdldE5hbWUoKSwgdGhpcy5jb2x1bW5BcmdzRnJvbVNvdXJjZUNvbHVtbihzb3VyY2VDb2x1bW4sIHtpc05ld0NvbHVtbjogdHJ1ZX0pKVxuICAgIH1cblxuICAgIGZvciAoY29uc3Qgc291cmNlQ29sdW1uIG9mIGNvbHVtbnNOZWVkaW5nV2lkZW5pbmcpIHtcbiAgICAgIHRhYmxlRGF0YS5hZGRDb2x1bW4oc291cmNlQ29sdW1uLmdldE5hbWUoKSwgdGhpcy5jb2x1bW5BcmdzRnJvbVNvdXJjZUNvbHVtbihzb3VyY2VDb2x1bW4sIHtpc05ld0NvbHVtbjogZmFsc2V9KSlcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGFsdGVyU3FsIG9mIGF3YWl0IHRoaXMudGFyZ2V0RGIuYWx0ZXJUYWJsZVNRTHModGFibGVEYXRhKSkge1xuICAgICAgYXdhaXQgdGhpcy50YXJnZXREYi5xdWVyeShhbHRlclNxbClcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgbm9uLXByaW1hcnkta2V5IGluZGV4ZXMgcHJlc2VudCBvbiB0aGUgc291cmNlIGJ1dCBtaXNzaW5nIGZyb20gdGhlIHRhcmdldCxcbiAgICogYW5kIHJlcGxhY2VzIHRhcmdldCBpbmRleGVzIHdob3NlIGRlZmluaXRpb24gKGNvbHVtbnMgb3IgdW5pcXVlbmVzcykgZHJpZnRlZCBmcm9tXG4gICAqIHRoZSBzb3VyY2UuXG4gICAqIEBwYXJhbSB7e3NvdXJjZVRhYmxlOiBpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UtdGFibGUuanNcIikuZGVmYXVsdCwgdGFibGVOYW1lOiBzdHJpbmd9fSBhcmdzIC0gU291cmNlIHRhYmxlIG1ldGFkYXRhIGFuZCB0YXJnZXQgdGFibGUgbmFtZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBhc3luYyBlbnN1cmVUYXJnZXRJbmRleGVzKHtzb3VyY2VUYWJsZSwgdGFibGVOYW1lfSkge1xuICAgIGNvbnN0IHRhcmdldFRhYmxlID0gYXdhaXQgdGhpcy50YXJnZXREYi5nZXRUYWJsZUJ5TmFtZU9yRmFpbCh0YWJsZU5hbWUpXG4gICAgLyoqIEB0eXBlIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UtY29sdW1ucy1pbmRleC5qc1wiKS5kZWZhdWx0Pn0gKi9cbiAgICBjb25zdCB0YXJnZXRJbmRleGVzQnlOYW1lID0gbmV3IE1hcCgpXG4gICAgY29uc3QgdGFyZ2V0SW5kZXhTaWduYXR1cmVzID0gbmV3IFNldCgpXG4gICAgbGV0IGRpcnR5ID0gZmFsc2VcblxuICAgIGZvciAoY29uc3QgdGFyZ2V0SW5kZXggb2YgYXdhaXQgdGFyZ2V0VGFibGUuZ2V0SW5kZXhlcygpKSB7XG4gICAgICB0YXJnZXRJbmRleGVzQnlOYW1lLnNldCh0YXJnZXRJbmRleC5nZXROYW1lKCksIHRhcmdldEluZGV4KVxuICAgICAgdGFyZ2V0SW5kZXhTaWduYXR1cmVzLmFkZCh0aGlzLmluZGV4U2lnbmF0dXJlKHRhcmdldEluZGV4KSlcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHNvdXJjZUluZGV4IG9mIGF3YWl0IHNvdXJjZVRhYmxlLmdldEluZGV4ZXMoKSkge1xuICAgICAgaWYgKHNvdXJjZUluZGV4LmlzUHJpbWFyeUtleSgpKSB7XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHNvdXJjZUluZGV4U2lnbmF0dXJlID0gdGhpcy5pbmRleFNpZ25hdHVyZShzb3VyY2VJbmRleClcblxuICAgICAgLy8gU1FMaXRlIGluZGV4IG5hbWVzIGFyZSB1bmlxdWUgcGVyLWRhdGFiYXNlLCBub3QgcGVyLXRhYmxlLCBzbyBtYXRjaCBjbG9uZWRcbiAgICAgIC8vIGluZGV4ZXMgYnkgdGhlaXIgY29sdW1uL3VuaXF1ZW5lc3Mgc2lnbmF0dXJlIHJhdGhlciB0aGFuIHRoZWlyIG5hbWUuXG4gICAgICBpZiAodGhpcy50YXJnZXREYi5nZXRUeXBlKCkgPT09IFwic3FsaXRlXCIgJiYgdGFyZ2V0SW5kZXhTaWduYXR1cmVzLmhhcyhzb3VyY2VJbmRleFNpZ25hdHVyZSkpIHtcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgY29uc3QgdGFyZ2V0SW5kZXggPSB0aGlzLnRhcmdldERiLmdldFR5cGUoKSA9PT0gXCJzcWxpdGVcIiA/IHVuZGVmaW5lZCA6IHRhcmdldEluZGV4ZXNCeU5hbWUuZ2V0KHNvdXJjZUluZGV4LmdldE5hbWUoKSlcblxuICAgICAgaWYgKHRhcmdldEluZGV4KSB7XG4gICAgICAgIGlmICghdGhpcy5pbmRleGVzTWF0Y2goc291cmNlSW5kZXgsIHRhcmdldEluZGV4KSkge1xuICAgICAgICAgIC8vIFJlcGxhY2luZyBhIG5vbi11bmlxdWUgaW5kZXggd2l0aCBhIHVuaXF1ZSBvbmUgaXMgdW5zYWZlIGJlY2F1c2VcbiAgICAgICAgICAvLyB0aGUgdGFyZ2V0IG1heSBoYXZlIGR1cGxpY2F0ZSB2YWx1ZXMgdGhhdCB3aWxsIHJlamVjdCB0aGUgbmV3XG4gICAgICAgICAgLy8gdW5pcXVlIGNvbnN0cmFpbnQsIGFuZCB0aGUgb2xkIGluZGV4IHdhcyBhbHJlYWR5IGRyb3BwZWQgYnkgdGhpc1xuICAgICAgICAgIC8vIHBvaW50LiBUaGUgb3Bwb3NpdGUgZGlyZWN0aW9uICh1bmlxdWUg4oaSIG5vbi11bmlxdWUpIGlzIGFsd2F5c1xuICAgICAgICAgIC8vIHNhZmUg4oCUIG5vbi11bmlxdWUgaW5kZXhlcyBuZXZlciBmYWlsIG9uIGR1cGxpY2F0ZSB2YWx1ZXMuXG4gICAgICAgICAgaWYgKHNvdXJjZUluZGV4LmlzVW5pcXVlKCkgJiYgIXRhcmdldEluZGV4LmlzVW5pcXVlKCkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgU2NoZW1hIGNsb25lIGluZGV4IGRyaWZ0IGZvciAke3RhYmxlTmFtZX0uJHtzb3VyY2VJbmRleC5nZXROYW1lKCl9OiBjYW5ub3Qgc2FmZWx5IHJlcGxhY2UgYSBub24tdW5pcXVlIGluZGV4IHdpdGggYSB1bmlxdWUgb25lLmApXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYXdhaXQgdGhpcy5kcm9wVGFyZ2V0SW5kZXgoe3RhYmxlTmFtZSwgdGFyZ2V0SW5kZXh9KVxuICAgICAgICAgIHRhcmdldEluZGV4ZXNCeU5hbWUuZGVsZXRlKHRhcmdldEluZGV4LmdldE5hbWUoKSlcbiAgICAgICAgICB0YXJnZXRJbmRleFNpZ25hdHVyZXMuZGVsZXRlKHRoaXMuaW5kZXhTaWduYXR1cmUodGFyZ2V0SW5kZXgpKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gRHJvcCBhbnkgdGFyZ2V0IGluZGV4IHRoYXQgc2hhcmVzIHRoZSBzb3VyY2UgbmFtZSBidXQgc3Vydml2ZWQgdGhlXG4gICAgICAvLyBkcmlmdCBjaGVjayBhYm92ZSBiZWNhdXNlIHRoZSBkcml2ZXIgd2FzIHNraXBwZWQgKFNRTGl0ZSkuXG4gICAgICBjb25zdCBzYW1lTmFtZVRhcmdldEluZGV4ID0gdGFyZ2V0SW5kZXhlc0J5TmFtZS5nZXQoc291cmNlSW5kZXguZ2V0TmFtZSgpKVxuXG4gICAgICBpZiAoc2FtZU5hbWVUYXJnZXRJbmRleCkge1xuICAgICAgICBhd2FpdCB0aGlzLmRyb3BUYXJnZXRJbmRleCh7dGFibGVOYW1lLCB0YXJnZXRJbmRleDogc2FtZU5hbWVUYXJnZXRJbmRleH0pXG4gICAgICAgIHRhcmdldEluZGV4ZXNCeU5hbWUuZGVsZXRlKHNhbWVOYW1lVGFyZ2V0SW5kZXguZ2V0TmFtZSgpKVxuICAgICAgICB0YXJnZXRJbmRleFNpZ25hdHVyZXMuZGVsZXRlKHRoaXMuaW5kZXhTaWduYXR1cmUoc2FtZU5hbWVUYXJnZXRJbmRleCkpXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNyZWF0ZUluZGV4U3FscyA9IGF3YWl0IHRoaXMudGFyZ2V0RGIuY3JlYXRlSW5kZXhTUUxzKHRoaXMuY3JlYXRlSW5kZXhBcmdzRnJvbVNvdXJjZUluZGV4KHtzb3VyY2VJbmRleCwgdGFibGVOYW1lfSkpXG5cbiAgICAgIGZvciAoY29uc3QgY3JlYXRlSW5kZXhTcWwgb2YgY3JlYXRlSW5kZXhTcWxzKSB7XG4gICAgICAgIGF3YWl0IHRoaXMudGFyZ2V0RGIucXVlcnkoY3JlYXRlSW5kZXhTcWwpXG4gICAgICB9XG5cbiAgICAgIGRpcnR5ID0gdHJ1ZVxuICAgICAgdGFyZ2V0SW5kZXhTaWduYXR1cmVzLmFkZChzb3VyY2VJbmRleFNpZ25hdHVyZSlcbiAgICB9XG5cbiAgICBpZiAoZGlydHkpIHtcbiAgICAgIHRoaXMudGFyZ2V0RGIuY2xlYXJTY2hlbWFDYWNoZSgpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERyb3BzIGFuIGluZGV4IG9uIHRoZSB0YXJnZXQgZGF0YWJhc2UuXG4gICAqIEBwYXJhbSB7e3RhYmxlTmFtZTogc3RyaW5nLCB0YXJnZXRJbmRleDogaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLWNvbHVtbnMtaW5kZXguanNcIikuZGVmYXVsdH19IGFyZ3MgLSBUYXJnZXQgdGFibGUgYW5kIGluZGV4IHRvIHJlbW92ZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBhc3luYyBkcm9wVGFyZ2V0SW5kZXgoe3RhYmxlTmFtZSwgdGFyZ2V0SW5kZXh9KSB7XG4gICAgY29uc3QgZHJvcFNxbHMgPSBhd2FpdCB0aGlzLnRhcmdldERiLnJlbW92ZUluZGV4U1FMcyh7bmFtZTogdGFyZ2V0SW5kZXguZ2V0TmFtZSgpLCB0YWJsZU5hbWV9KVxuXG4gICAgZm9yIChjb25zdCBzcWwgb2YgZHJvcFNxbHMpIHtcbiAgICAgIGF3YWl0IHRoaXMudGFyZ2V0RGIucXVlcnkoc3FsKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBCYXNlbGluZXMgdGhlIHRhcmdldCBsZWRnZXIgc28gdGhlIGNsb25lZCBzY2hlbWEgaXMgcmVjb3JkZWQgYXMgYWxyZWFkeS1hcHBsaWVkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmdbXT59IFRoZSB2ZXJzaW9ucyBuZXdseSByZWNvcmRlZCBvbiB0aGUgdGFyZ2V0LlxuICAgKi9cbiAgYXN5bmMgcmVjb25jaWxlTGVkZ2VyKCkge1xuICAgIHJldHVybiBhd2FpdCBNaWdyYXRpb25zTGVkZ2VyLmJhc2VsaW5lRnJvbURhdGFiYXNlKHtzb3VyY2VEYjogdGhpcy5zb3VyY2VEYiwgdGFyZ2V0RGI6IHRoaXMudGFyZ2V0RGJ9KVxuICB9XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIHRhcmdldCBsZWRnZXIgaXMgbWlzc2luZyBhbnkgdmVyc2lvbiBhcHBsaWVkIG9uIHRoZSBzb3VyY2Ug4oCUIGkuZS4gdGhlXG4gICAqIHRhcmdldCBzY2hlbWEgbWF5IGhhdmUgYmVlbiBhZHZhbmNlZCBvdXQgb2YgYmFuZCB3aXRob3V0IHJlY29yZGluZyBpdC5cbiAgICogQHJldHVybnMge1Byb21pc2U8Ym9vbGVhbj59IC0gV2hldGhlciB0aGUgdGFyZ2V0IGxlZGdlciBkaWZmZXJzIGZyb20gdGhlIHNvdXJjZS5cbiAgICovXG4gIGFzeW5jIGxlZGdlckRyaWZ0c0Zyb21Tb3VyY2UoKSB7XG4gICAgaWYgKCFhd2FpdCBNaWdyYXRpb25zTGVkZ2VyLnRhYmxlRXhpc3RzKHRoaXMudGFyZ2V0RGIpKSB7XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIGNvbnN0IHNvdXJjZVZlcnNpb25zID0gYXdhaXQgTWlncmF0aW9uc0xlZGdlci5hcHBsaWVkVmVyc2lvbnModGhpcy5zb3VyY2VEYilcbiAgICBjb25zdCB0YXJnZXRWZXJzaW9uU2V0ID0gbmV3IFNldChhd2FpdCBNaWdyYXRpb25zTGVkZ2VyLmFwcGxpZWRWZXJzaW9ucyh0aGlzLnRhcmdldERiKSlcblxuICAgIHJldHVybiBzb3VyY2VWZXJzaW9ucy5zb21lKCh2ZXJzaW9uKSA9PiAhdGFyZ2V0VmVyc2lvblNldC5oYXModmVyc2lvbikpXG4gIH1cblxuICAvKipcbiAgICogTWFwcyBhIHNvdXJjZSBpbmRleCBpbnRvIGEgVGFibGVEYXRhIGluZGV4IGZvciB0YWJsZSBjcmVhdGlvbiAoU1FMaXRlIG9taXRzIHRoZVxuICAgKiBpbmRleCBuYW1lIHNvIHRoZSBkcml2ZXIgY2FuIGdlbmVyYXRlIGEgdW5pcXVlIG9uZSkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLWNvbHVtbnMtaW5kZXguanNcIikuZGVmYXVsdH0gc291cmNlSW5kZXggLSBTb3VyY2UgaW5kZXggZGVmaW5pdGlvbi5cbiAgICogQHJldHVybnMge1RhYmxlSW5kZXh9IC0gRnJhbWV3b3JrLWluZGVwZW5kZW50IGluZGV4IGRlZmluaXRpb24uXG4gICAqL1xuICB0YWJsZURhdGFJbmRleEZyb21Tb3VyY2VJbmRleChzb3VyY2VJbmRleCkge1xuICAgIC8qKiBAdHlwZSB7e25hbWU/OiBzdHJpbmcsIHVuaXF1ZTogYm9vbGVhbn19ICovXG4gICAgY29uc3QgYXJncyA9IHt1bmlxdWU6IHNvdXJjZUluZGV4LmlzVW5pcXVlKCl9XG5cbiAgICAvLyBTUUxpdGUgaW5kZXggbmFtZXMgYXJlIHVuaXF1ZSBwZXItZGF0YWJhc2UsIG5vdCBwZXItdGFibGUsIHNvIGxldCB0aGUgZHJpdmVyXG4gICAgLy8gZ2VuZXJhdGUgb25lOyBvdGhlciBkcml2ZXJzIHByZXNlcnZlIHRoZSBzb3VyY2UgaW5kZXggbmFtZS4gQnVpbGQgdGhlIFRhYmxlSW5kZXhcbiAgICAvLyBkaXJlY3RseSAocmF0aGVyIHRoYW4gdmlhIHRoZSBkcml2ZXIncyBnZXRUYWJsZURhdGFJbmRleCwgd2hpY2ggb25seSBNeVNRTCBhbmRcbiAgICAvLyBTUUxpdGUgaW1wbGVtZW50KSBzbyBjbG9uaW5nIGEgUG9zdGdyZVNRTCBvciBNUy1TUUwgc291cmNlIHRhYmxlIHdvcmtzIHRvby5cbiAgICBpZiAodGhpcy50YXJnZXREYi5nZXRUeXBlKCkgIT09IFwic3FsaXRlXCIpIHtcbiAgICAgIGFyZ3MubmFtZSA9IHNvdXJjZUluZGV4LmdldE5hbWUoKVxuICAgIH1cblxuICAgIHJldHVybiBuZXcgVGFibGVJbmRleChzb3VyY2VJbmRleC5nZXRDb2x1bW5OYW1lcygpLCBhcmdzKVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBkcml2ZXIgY3JlYXRlLWluZGV4IGFyZ3MgZnJvbSBhIHNvdXJjZSBpbmRleCAodGhlIGluZGV4IG5hbWUgaXMgb21pdHRlZCBvblxuICAgKiBTUUxpdGUsIHdoZXJlIGluZGV4IG5hbWVzIGFyZSB1bmlxdWUgcGVyLWRhdGFiYXNlIHJhdGhlciB0aGFuIHBlci10YWJsZSkuXG4gICAqIEBwYXJhbSB7e3NvdXJjZUluZGV4OiBpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UtY29sdW1ucy1pbmRleC5qc1wiKS5kZWZhdWx0LCB0YWJsZU5hbWU6IHN0cmluZ319IGFyZ3MgLSBTb3VyY2UgaW5kZXggYW5kIHRhcmdldCB0YWJsZSByZWNlaXZpbmcgaXQuXG4gICAqIEByZXR1cm5zIHt7Y29sdW1uczogc3RyaW5nW10sIG5hbWU/OiBzdHJpbmcsIHRhYmxlTmFtZTogc3RyaW5nLCB1bmlxdWU6IGJvb2xlYW59fSAtIEFyZ3VtZW50cyBmb3IgY3JlYXRpbmcgdGhlIHRhcmdldCBpbmRleC5cbiAgICovXG4gIGNyZWF0ZUluZGV4QXJnc0Zyb21Tb3VyY2VJbmRleCh7c291cmNlSW5kZXgsIHRhYmxlTmFtZX0pIHtcbiAgICAvKiogQHR5cGUge3tjb2x1bW5zOiBzdHJpbmdbXSwgbmFtZT86IHN0cmluZywgdGFibGVOYW1lOiBzdHJpbmcsIHVuaXF1ZTogYm9vbGVhbn19ICovXG4gICAgY29uc3QgY3JlYXRlSW5kZXhBcmdzID0ge1xuICAgICAgY29sdW1uczogc291cmNlSW5kZXguZ2V0Q29sdW1uTmFtZXMoKSxcbiAgICAgIHRhYmxlTmFtZSxcbiAgICAgIHVuaXF1ZTogc291cmNlSW5kZXguaXNVbmlxdWUoKVxuICAgIH1cblxuICAgIGlmICh0aGlzLnRhcmdldERiLmdldFR5cGUoKSAhPT0gXCJzcWxpdGVcIikge1xuICAgICAgY3JlYXRlSW5kZXhBcmdzLm5hbWUgPSBzb3VyY2VJbmRleC5nZXROYW1lKClcbiAgICB9XG5cbiAgICByZXR1cm4gY3JlYXRlSW5kZXhBcmdzXG4gIH1cblxuICAvKipcbiAgICogV2hldGhlciB0d28gaW5kZXhlcyBoYXZlIHRoZSBzYW1lIHVuaXF1ZW5lc3MgYW5kIG9yZGVyZWQgY29sdW1uIGxpc3QuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLWNvbHVtbnMtaW5kZXguanNcIikuZGVmYXVsdH0gc291cmNlSW5kZXggLSBTb3VyY2UgaW5kZXggZGVmaW5pdGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UtY29sdW1ucy1pbmRleC5qc1wiKS5kZWZhdWx0fSB0YXJnZXRJbmRleCAtIFRhcmdldCBpbmRleCBkZWZpbml0aW9uLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIGJvdGggaW5kZXhlcyBoYXZlIHRoZSBzYW1lIHNoYXBlLlxuICAgKi9cbiAgaW5kZXhlc01hdGNoKHNvdXJjZUluZGV4LCB0YXJnZXRJbmRleCkge1xuICAgIGNvbnN0IHNvdXJjZUNvbHVtbk5hbWVzID0gc291cmNlSW5kZXguZ2V0Q29sdW1uTmFtZXMoKVxuICAgIGNvbnN0IHRhcmdldENvbHVtbk5hbWVzID0gdGFyZ2V0SW5kZXguZ2V0Q29sdW1uTmFtZXMoKVxuXG4gICAgaWYgKHNvdXJjZUluZGV4LmlzVW5pcXVlKCkgIT09IHRhcmdldEluZGV4LmlzVW5pcXVlKCkpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cblxuICAgIGlmIChzb3VyY2VDb2x1bW5OYW1lcy5sZW5ndGggIT09IHRhcmdldENvbHVtbk5hbWVzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgZm9yIChsZXQgY29sdW1uSW5kZXggPSAwOyBjb2x1bW5JbmRleCA8IHNvdXJjZUNvbHVtbk5hbWVzLmxlbmd0aDsgY29sdW1uSW5kZXgrKykge1xuICAgICAgaWYgKHNvdXJjZUNvbHVtbk5hbWVzW2NvbHVtbkluZGV4XSAhPT0gdGFyZ2V0Q29sdW1uTmFtZXNbY29sdW1uSW5kZXhdKSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICAvKipcbiAgICogQSBzdGFibGUgc2lnbmF0dXJlIGZvciBhbiBpbmRleCwgdXNlZCB0byBtYXRjaCBjbG9uZWQgaW5kZXhlcyBieSBzaGFwZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UtY29sdW1ucy1pbmRleC5qc1wiKS5kZWZhdWx0fSBpbmRleCAtIEluZGV4IGRlZmluaXRpb24uXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IC0gU3RhYmxlIGluZGV4LXNoYXBlIHNpZ25hdHVyZS5cbiAgICovXG4gIGluZGV4U2lnbmF0dXJlKGluZGV4KSB7XG4gICAgcmV0dXJuIGAke2luZGV4LmlzVW5pcXVlKCkgPyBcInVuaXF1ZVwiIDogXCJpbmRleFwifToke2luZGV4LmdldENvbHVtbk5hbWVzKCkuam9pbihcIixcIil9YFxuICB9XG5cbiAgLyoqXG4gICAqIE5vcm1hbGl6ZXMgYSBjb2x1bW4gdHlwZSB0byBpdHMgY2Fub25pY2FsIGxvd2VyY2FzZSBmb3JtIChgaW50YCBiZWNvbWVzIGBpbnRlZ2VyYCkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjb2x1bW5UeXBlIC0gRGF0YWJhc2UgY29sdW1uIHR5cGUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IC0gQ2Fub25pY2FsIGxvd2VyY2FzZSBjb2x1bW4gdHlwZS5cbiAgICovXG4gIG5vcm1hbGl6ZWRDb2x1bW5UeXBlKGNvbHVtblR5cGUpIHtcbiAgICBjb25zdCBub3JtYWxpemVkVHlwZSA9IGNvbHVtblR5cGUudG9Mb3dlckNhc2UoKVxuXG4gICAgaWYgKG5vcm1hbGl6ZWRUeXBlID09PSBcImludFwiKSB7XG4gICAgICByZXR1cm4gXCJpbnRlZ2VyXCJcbiAgICB9XG5cbiAgICByZXR1cm4gbm9ybWFsaXplZFR5cGVcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgd2lkZW5pbmcgcmFuayBvZiBhIHRleHQgY29sdW1uIHR5cGUgKDAgd2hlbiBub3QgYSB0ZXh0IHR5cGUpLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gY29sdW1uVHlwZSAtIERhdGFiYXNlIGNvbHVtbiB0eXBlLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSAtIFRleHQtdHlwZSB3aWRlbmluZyByYW5rLlxuICAgKi9cbiAgdGV4dFR5cGVSYW5rKGNvbHVtblR5cGUpIHtcbiAgICByZXR1cm4gVEVYVF9UWVBFX1JBTktTW3RoaXMubm9ybWFsaXplZENvbHVtblR5cGUoY29sdW1uVHlwZSldIHx8IDBcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSB0YXJnZXQncyB0ZXh0IGNvbHVtbiBpcyBuYXJyb3dlciB0aGFuIHRoZSBzb3VyY2UncyBhbmQgbXVzdCBiZSB3aWRlbmVkLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS1jb2x1bW4uanNcIikuZGVmYXVsdH0gc291cmNlQ29sdW1uIC0gU291cmNlIGNvbHVtbiBkZWZpbml0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS1jb2x1bW4uanNcIikuZGVmYXVsdH0gdGFyZ2V0Q29sdW1uIC0gVGFyZ2V0IGNvbHVtbiBkZWZpbml0aW9uLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHRoZSB0YXJnZXQgdGV4dCBjb2x1bW4gbXVzdCBiZSB3aWRlbmVkLlxuICAgKi9cbiAgY29sdW1uTmVlZHNXaWRlbmluZyhzb3VyY2VDb2x1bW4sIHRhcmdldENvbHVtbikge1xuICAgIGNvbnN0IHNvdXJjZVJhbmsgPSB0aGlzLnRleHRUeXBlUmFuayhzb3VyY2VDb2x1bW4uZ2V0VHlwZSgpKVxuICAgIGNvbnN0IHRhcmdldFJhbmsgPSB0aGlzLnRleHRUeXBlUmFuayh0YXJnZXRDb2x1bW4uZ2V0VHlwZSgpKVxuXG4gICAgcmV0dXJuIHNvdXJjZVJhbmsgPiAwICYmIHRhcmdldFJhbmsgPiAwICYmIHNvdXJjZVJhbmsgPiB0YXJnZXRSYW5rXG4gIH1cblxuICAvKipcbiAgICogQnVpbGRzIFRhYmxlRGF0YSBjb2x1bW4gYXJncyBmcm9tIGEgc291cmNlIGNvbHVtbiwgY29weWluZyB0eXBlLCBudWxsYWJpbGl0eSxcbiAgICogbGVuZ3RoLCBub3Rlcywgc2ltcGxlIGRlZmF1bHRzIGFuZCAoZm9yIGZ1bGwgY2xvbmVzKSBwcmltYXJ5LWtleSBmbGFnLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS1jb2x1bW4uanNcIikuZGVmYXVsdH0gc291cmNlQ29sdW1uIC0gU291cmNlIGNvbHVtbiBkZWZpbml0aW9uLlxuICAgKiBAcGFyYW0ge3tpc05ld0NvbHVtbjogYm9vbGVhbn19IGFyZ3MgLSBXaGV0aGVyIHRoZSBjb2x1bW4gaXMgYmVpbmcgYWRkZWQgaW5zdGVhZCBvZiBjbG9uZWQgd2l0aCBpdHMgdGFibGUuXG4gICAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gLSBBcmd1bWVudHMgZm9yIGFsdGVyaW5nIHRoZSB0YXJnZXQgY29sdW1uLlxuICAgKi9cbiAgY29sdW1uQXJnc0Zyb21Tb3VyY2VDb2x1bW4oc291cmNlQ29sdW1uLCB7aXNOZXdDb2x1bW59KSB7XG4gICAgLyoqIEB0eXBlIHt7YXV0b0luY3JlbWVudD86IGJvb2xlYW4sIGRlZmF1bHQ/OiB1bmtub3duLCBpc05ld0NvbHVtbjogYm9vbGVhbiwgbWF4TGVuZ3RoPzogbnVtYmVyLCBub3Rlcz86IHN0cmluZywgbnVsbDogYm9vbGVhbiwgcHJpbWFyeUtleT86IGJvb2xlYW4sIHR5cGU6IHN0cmluZ319ICovXG4gICAgY29uc3QgY29sdW1uQXJncyA9IHtcbiAgICAgIGlzTmV3Q29sdW1uLFxuICAgICAgbnVsbDogc291cmNlQ29sdW1uLmdldE51bGwoKSxcbiAgICAgIHR5cGU6IHRoaXMubm9ybWFsaXplZENvbHVtblR5cGUoc291cmNlQ29sdW1uLmdldFR5cGUoKSlcbiAgICB9XG4gICAgY29uc3QgZGVmYXVsdFZhbHVlID0gc291cmNlQ29sdW1uLmdldERlZmF1bHQoKVxuICAgIGNvbnN0IG1heExlbmd0aCA9IHNvdXJjZUNvbHVtbi5nZXRNYXhMZW5ndGgoKVxuICAgIGNvbnN0IG5vdGVzID0gc291cmNlQ29sdW1uLmdldE5vdGVzKClcblxuICAgIGlmICghaXNOZXdDb2x1bW4gJiYgc291cmNlQ29sdW1uLmdldFByaW1hcnlLZXkoKSkge1xuICAgICAgY29sdW1uQXJncy5wcmltYXJ5S2V5ID0gdHJ1ZVxuICAgIH1cblxuICAgIGlmIChzb3VyY2VDb2x1bW4uZ2V0QXV0b0luY3JlbWVudCgpKSB7XG4gICAgICBjb2x1bW5BcmdzLmF1dG9JbmNyZW1lbnQgPSB0cnVlXG4gICAgfVxuXG4gICAgLy8gQSBtYXhMZW5ndGggb2YgLTEgaXMgdGhlIE1TLVNRTCBcIm1heFwiIHNlbnRpbmVsIChOVkFSQ0hBUihNQVgpIC8gVkFSQklOQVJZKE1BWCksXG4gICAgLy8gYmFja2luZyBWZWxvY2lvdXMgdGV4dC9qc29uL2Jsb2IgY29sdW1ucyk7IHRoZSBjb2x1bW4gdHlwZSBkcml2ZXMgdGhlIHVuYm91bmRlZFxuICAgIC8vIFNRTCwgc28gZG9uJ3QgZm9yd2FyZCAtMSBhcyBhbiBleHBsaWNpdCBsZW5ndGggKGl0IHdvdWxkIGVtaXQgTlZBUkNIQVIoLTEpKS5cbiAgICBpZiAobWF4TGVuZ3RoICE9PSB1bmRlZmluZWQgJiYgbWF4TGVuZ3RoID49IDApIHtcbiAgICAgIGNvbHVtbkFyZ3MubWF4TGVuZ3RoID0gbWF4TGVuZ3RoXG4gICAgfVxuXG4gICAgaWYgKG5vdGVzKSB7XG4gICAgICBjb2x1bW5BcmdzLm5vdGVzID0gbm90ZXNcbiAgICB9XG5cbiAgICBpZiAoZGVmYXVsdFZhbHVlICE9PSBudWxsICYmIGRlZmF1bHRWYWx1ZSAhPT0gdW5kZWZpbmVkICYmIFNJTVBMRV9ERUZBVUxUX1BBVFRFUk4udGVzdChTdHJpbmcoZGVmYXVsdFZhbHVlKSkpIHtcbiAgICAgIGNvbHVtbkFyZ3MuZGVmYXVsdCA9IGRlZmF1bHRWYWx1ZVxuICAgIH1cblxuICAgIHJldHVybiBjb2x1bW5BcmdzXG4gIH1cbn1cbiJdfQ==
|
|
385
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NoZW1hLWNsb25lci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9kYXRhYmFzZS90ZW5hbnRzL3NjaGVtYS1jbG9uZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sZ0JBQWdCLE1BQU0seUJBQXlCLENBQUE7QUFDdEQsT0FBTyxTQUFTLE1BQU0sd0JBQXdCLENBQUE7QUFDOUMsT0FBTyxVQUFVLE1BQU0sOEJBQThCLENBQUE7QUFFckQsTUFBTSxzQkFBc0IsR0FBRyw2Q0FBNkMsQ0FBQTtBQUU1RSxxQ0FBcUM7QUFDckMsTUFBTSxlQUFlLEdBQUc7SUFDdEIsUUFBUSxFQUFFLENBQUM7SUFDWCxJQUFJLEVBQUUsQ0FBQztJQUNQLFVBQVUsRUFBRSxDQUFDO0lBQ2IsUUFBUSxFQUFFLENBQUM7Q0FDWixDQUFBO0FBRUQ7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUNILE1BQU0sQ0FBQyxPQUFPLE9BQU8sWUFBWTtJQUMvQjs7O09BR0c7SUFDSCxZQUFZLEVBQUMsUUFBUSxFQUFFLFFBQVEsRUFBQztRQUM5QixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQTtRQUN4QixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQTtJQUMxQixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxLQUFLLENBQUMsVUFBVSxDQUFDLFVBQVU7UUFDekIsS0FBSyxNQUFNLFNBQVMsSUFBSSxVQUFVLEVBQUUsQ0FBQztZQUNuQyxNQUFNLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUE7UUFDakMsQ0FBQztRQUVELE1BQU0sSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFBO0lBQzlCLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILEtBQUssQ0FBQyxTQUFTLENBQUMsU0FBUztRQUN2QixNQUFNLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQyxDQUFBO1FB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blxuaW1wb3J0IE1pZ3JhdGlvbnNMZWRnZXIgZnJvbSBcIi4uL21pZ3JhdGlvbnMtbGVkZ2VyLmpzXCJcbmltcG9ydCBUYWJsZURhdGEgZnJvbSBcIi4uL3RhYmxlLWRhdGEvaW5kZXguanNcIlxuaW1wb3J0IFRhYmxlSW5kZXggZnJvbSBcIi4uL3RhYmxlLWRhdGEvdGFibGUtaW5kZXguanNcIlxuXG5jb25zdCBTSU1QTEVfREVGQVVMVF9QQVRURVJOID0gL14oPzotP1xcZCsoPzpcXC5cXGQrKT98W0EtWmEtejAtOSBfLiw6L0ArLV0qKSQvXG5cbi8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgbnVtYmVyPn0gKi9cbmNvbnN0IFRFWFRfVFlQRV9SQU5LUyA9IHtcbiAgdGlueXRleHQ6IDEsXG4gIHRleHQ6IDIsXG4gIG1lZGl1bXRleHQ6IDMsXG4gIGxvbmd0ZXh0OiA0XG59XG5cbi8qKlxuICogQ2xvbmVzIHRhYmxlIHN0cnVjdHVyZSAoY29sdW1ucywgdGV4dC10eXBlIHdpZGVuaW5nLCBpbmRleGVzKSBmcm9tIGEgc291cmNlIGRhdGFiYXNlXG4gKiBpbnRvIGEgdGFyZ2V0IGRhdGFiYXNlIGZvciBhIGdpdmVuIHNldCBvZiB0YWJsZXMsIHRoZW4gYmFzZWxpbmVzIHRoZSB0YXJnZXQnc1xuICogYHNjaGVtYV9taWdyYXRpb25zYCBsZWRnZXIgdG8gdGhlIHNvdXJjZSB2aWEge0BsaW5rIE1pZ3JhdGlvbnNMZWRnZXJ9LiBUaGlzIGlzIHRoZVxuICogbWVjaGFuaXNtIG11bHRpLXRlbmFudCBhcHBzIHVzZSB0byBwcm92aXNpb24gYSB0ZW5hbnQgZGF0YWJhc2UgZnJvbSBhIHRlbXBsYXRlL2dsb2JhbFxuICogZGF0YWJhc2Ugd2l0aG91dCByZS1ydW5uaW5nIG1pZ3JhdGlvbnM6IHRoZSBzdHJ1Y3R1cmUgaXMgY29waWVkIGFuZCB0aGUgbGVkZ2VyIGlzXG4gKiByZWNvcmRlZCBhcyBhbHJlYWR5LWFwcGxpZWQsIHNvIGEgbGF0ZXIgYGRiOnRlbmFudHM6bWlncmF0ZWAgZG9lcyBub3QgcmUtcnVuIGFuXG4gKiBgYWRkQ29sdW1uYCB3aG9zZSBjb2x1bW4gYWxyZWFkeSBleGlzdHMuXG4gKlxuICogVGhlIGNsb25lciBpcyBpbnRlbnRpb25hbGx5IHBvbGljeS1mcmVlIOKAlCB0aGUgY2FsbGVyIGRlY2lkZXMgd2hpY2ggdGFibGVzIHRvIHN5bmMgYW5kXG4gKiB3aGljaCBkYXRhYmFzZXMgYXJlIHNvdXJjZS90YXJnZXQuIEl0IGlzIGlkZW1wb3RlbnQ6IG1pc3NpbmcgdGFibGVzIGFyZSBjcmVhdGVkLFxuICogbWlzc2luZyBjb2x1bW5zIGFkZGVkLCB0b28tbmFycm93IHRleHQgY29sdW1ucyB3aWRlbmVkLCBhbmQgbWlzc2luZyBpbmRleGVzIGNyZWF0ZWQ7XG4gKiBhbiBpbmRleCB3aG9zZSBkZWZpbml0aW9uIGRpdmVyZ2VzIGZyb20gdGhlIHNvdXJjZSBpcyB0cmVhdGVkIGFzIGRyaWZ0IGFuZCB0aHJvd3MuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNjaGVtYUNsb25lciB7XG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgY2xvbmVyIHRoYXQgY29waWVzIHRhYmxlIHN0cnVjdHVyZSBmcm9tIGBzb3VyY2VEYmAgaW50byBgdGFyZ2V0RGJgLlxuICAgKiBAcGFyYW0ge3tzb3VyY2VEYjogaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQsIHRhcmdldERiOiBpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH19IGFyZ3MgLSBEYXRhYmFzZXMgdG8gY2xvbmUgc3RydWN0dXJlIGZyb20gYW5kIGludG8uXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7c291cmNlRGIsIHRhcmdldERifSkge1xuICAgIHRoaXMuc291cmNlRGIgPSBzb3VyY2VEYlxuICAgIHRoaXMudGFyZ2V0RGIgPSB0YXJnZXREYlxuICB9XG5cbiAgLyoqXG4gICAqIENsb25lcyBldmVyeSBnaXZlbiB0YWJsZSBmcm9tIHRoZSBzb3VyY2UgaW50byB0aGUgdGFyZ2V0LCB0aGVuIGJhc2VsaW5lcyB0aGVcbiAgICogdGFyZ2V0J3MgbGVkZ2VyIHNvIHRoZSBjbG9uZWQgc2NoZW1hIGlzIHJlY29yZGVkIGFzIGFscmVhZHktbWlncmF0ZWQuXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IHRhYmxlTmFtZXMgLSBTb3VyY2UgdGFibGVzIHdob3NlIHN0cnVjdHVyZSBzaG91bGQgYmUgY2xvbmVkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIGFzeW5jIHN5bmNUYWJsZXModGFibGVOYW1lcykge1xuICAgIGZvciAoY29uc3QgdGFibGVOYW1lIG9mIHRhYmxlTmFtZXMpIHtcbiAgICAgIGF3YWl0IHRoaXMuc3luY1RhYmxlKHRhYmxlTmFtZSlcbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLnJlY29uY2lsZUxlZGdlcigpXG4gIH1cblxuICAvKipcbiAgICogQ2xvbmVzIGEgc2luZ2xlIHRhYmxlIGZyb20gdGhlIHNvdXJjZSBpbnRvIHRoZSB0YXJnZXQsIGNyZWF0aW5nIGl0IG9yIGFkZGluZyBhbmRcbiAgICogd2lkZW5pbmcgY29sdW1ucyBhbmQgaW5kZXhlcyBhcyBuZWVkZWQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0YWJsZU5hbWUgLSBTb3VyY2UgdGFibGUgdG8gc3luY2hyb25pemUgd2l0aCB0aGUgdGFyZ2V0LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIGFzeW5jIHN5bmNUYWJsZSh0YWJsZU5hbWUpIHtcbiAgICBjb25zdCBzb3VyY2VUYWJsZSA9IGF3YWl0IHRoaXMuc291cmNlRGIuZ2V0VGFibGVCeU5hbWUodGFibGVOYW1lKVxuXG4gICAgaWYgKCFzb3VyY2VUYWJsZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBzb3VyY2UgdGFibGUgdG8gZXhpc3Q6ICR7dGFibGVOYW1lfWApXG4gICAgfVxuXG4gICAgaWYgKCFhd2FpdCB0aGlzLnRhcmdldERiLnRhYmxlRXhpc3RzKHRhYmxlTmFtZSkpIHtcbiAgICAgIGF3YWl0IHRoaXMuY3JlYXRlVGFyZ2V0VGFibGUoe3NvdXJjZVRhYmxlLCB0YWJsZU5hbWV9KVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3QgY2hhbmdlZENvbHVtbnMgPSBhd2FpdCB0aGlzLmVuc3VyZVRhcmdldENvbHVtbnMoe3NvdXJjZVRhYmxlLCB0YWJsZU5hbWV9KVxuXG4gICAgaWYgKGNoYW5nZWRDb2x1bW5zKSB7XG4gICAgICB0aGlzLnRhcmdldERiLmNsZWFyU2NoZW1hQ2FjaGUoKVxuICAgIH1cblxuICAgIGF3YWl0IHRoaXMuZW5zdXJlVGFyZ2V0SW5kZXhlcyh7c291cmNlVGFibGUsIHRhYmxlTmFtZX0pXG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyB0aGUgdGFibGUgaW4gdGhlIHRhcmdldCBmcm9tIHRoZSBzb3VyY2UgdGFibGUncyBjb2x1bW5zIGFuZCBpdHNcbiAgICogbm9uLXByaW1hcnkta2V5IGluZGV4ZXMuXG4gICAqIEBwYXJhbSB7e3NvdXJjZVRhYmxlOiBpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UtdGFibGUuanNcIikuZGVmYXVsdCwgdGFibGVOYW1lOiBzdHJpbmd9fSBhcmdzIC0gU291cmNlIHRhYmxlIG1ldGFkYXRhIGFuZCB0YXJnZXQgdGFibGUgbmFtZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBhc3luYyBjcmVhdGVUYXJnZXRUYWJsZSh7c291cmNlVGFibGUsIHRhYmxlTmFtZX0pIHtcbiAgICBjb25zdCB0YWJsZURhdGEgPSBuZXcgVGFibGVEYXRhKHRhYmxlTmFtZSlcblxuICAgIGZvciAoY29uc3Qgc291cmNlQ29sdW1uIG9mIGF3YWl0IHNvdXJjZVRhYmxlLmdldENvbHVtbnMoKSkge1xuICAgICAgdGFibGVEYXRhLmFkZENvbHVtbihzb3VyY2VDb2x1bW4uZ2V0TmFtZSgpLCB0aGlzLmNvbHVtbkFyZ3NGcm9tU291cmNlQ29sdW1uKHNvdXJjZUNvbHVtbiwge2lzTmV3Q29sdW1uOiBmYWxzZX0pKVxuICAgIH1cblxuICAgIGZvciAoY29uc3Qgc291cmNlSW5kZXggb2YgYXdhaXQgc291cmNlVGFibGUuZ2V0SW5kZXhlcygpKSB7XG4gICAgICBpZiAoIXNvdXJjZUluZGV4LmlzUHJpbWFyeUtleSgpKSB7XG4gICAgICAgIHRhYmxlRGF0YS5hZGRJbmRleCh0aGlzLnRhYmxlRGF0YUluZGV4RnJvbVNvdXJjZUluZGV4KHNvdXJjZUluZGV4KSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLnRhcmdldERiLmNyZWF0ZVRhYmxlKHRhYmxlRGF0YSlcbiAgICB0aGlzLnRhcmdldERiLmNsZWFyU2NoZW1hQ2FjaGUoKVxuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgY29sdW1ucyBwcmVzZW50IG9uIHRoZSBzb3VyY2UgYnV0IG1pc3NpbmcgZnJvbSB0aGUgdGFyZ2V0LCBhbmQgd2lkZW5zXG4gICAqIHRvby1uYXJyb3cgdGFyZ2V0IHRleHQgY29sdW1ucy5cbiAgICogQHBhcmFtIHt7c291cmNlVGFibGU6IGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS10YWJsZS5qc1wiKS5kZWZhdWx0LCB0YWJsZU5hbWU6IHN0cmluZ319IGFyZ3MgLSBTb3VyY2UgdGFibGUgbWV0YWRhdGEgYW5kIHRhcmdldCB0YWJsZSBuYW1lLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gV2hldGhlciBhbnkgY29sdW1uIHdhcyBhZGRlZCBvciB3aWRlbmVkLlxuICAgKi9cbiAgYXN5bmMgZW5zdXJlVGFyZ2V0Q29sdW1ucyh7c291cmNlVGFibGUsIHRhYmxlTmFtZX0pIHtcbiAgICBjb25zdCBzb3VyY2VDb2x1bW5zID0gYXdhaXQgc291cmNlVGFibGUuZ2V0Q29sdW1ucygpXG4gICAgY29uc3QgdGFyZ2V0VGFibGUgPSBhd2FpdCB0aGlzLnRhcmdldERiLmdldFRhYmxlQnlOYW1lT3JGYWlsKHRhYmxlTmFtZSlcbiAgICBjb25zdCB0YXJnZXRDb2x1bW5zQnlOYW1lID0gbmV3IE1hcCgpXG4gICAgY29uc3QgbWlzc2luZ0NvbHVtbnMgPSBbXVxuICAgIGNvbnN0IGNvbHVtbnNOZWVkaW5nV2lkZW5pbmcgPSBbXVxuXG4gICAgZm9yIChjb25zdCB0YXJnZXRDb2x1bW4gb2YgYXdhaXQgdGFyZ2V0VGFibGUuZ2V0Q29sdW1ucygpKSB7XG4gICAgICB0YXJnZXRDb2x1bW5zQnlOYW1lLnNldCh0YXJnZXRDb2x1bW4uZ2V0TmFtZSgpLCB0YXJnZXRDb2x1bW4pXG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBzb3VyY2VDb2x1bW4gb2Ygc291cmNlQ29sdW1ucykge1xuICAgICAgY29uc3QgdGFyZ2V0Q29sdW1uID0gdGFyZ2V0Q29sdW1uc0J5TmFtZS5nZXQoc291cmNlQ29sdW1uLmdldE5hbWUoKSlcblxuICAgICAgaWYgKCF0YXJnZXRDb2x1bW4pIHtcbiAgICAgICAgbWlzc2luZ0NvbHVtbnMucHVzaChzb3VyY2VDb2x1bW4pXG4gICAgICB9IGVsc2UgaWYgKHRoaXMuY29sdW1uTmVlZHNXaWRlbmluZyhzb3VyY2VDb2x1bW4sIHRhcmdldENvbHVtbikpIHtcbiAgICAgICAgY29sdW1uc05lZWRpbmdXaWRlbmluZy5wdXNoKHNvdXJjZUNvbHVtbilcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobWlzc2luZ0NvbHVtbnMubGVuZ3RoIDw9IDAgJiYgY29sdW1uc05lZWRpbmdXaWRlbmluZy5sZW5ndGggPD0gMCkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgY29uc3QgdGFibGVEYXRhID0gbmV3IFRhYmxlRGF0YSh0YWJsZU5hbWUpXG5cbiAgICBmb3IgKGNvbnN0IHNvdXJjZUNvbHVtbiBvZiBtaXNzaW5nQ29sdW1ucykge1xuICAgICAgdGFibGVEYXRhLmFkZENvbHVtbihzb3VyY2VDb2x1bW4uZ2V0TmFtZSgpLCB0aGlzLmNvbHVtbkFyZ3NGcm9tU291cmNlQ29sdW1uKHNvdXJjZUNvbHVtbiwge2lzTmV3Q29sdW1uOiB0cnVlfSkpXG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBzb3VyY2VDb2x1bW4gb2YgY29sdW1uc05lZWRpbmdXaWRlbmluZykge1xuICAgICAgdGFibGVEYXRhLmFkZENvbHVtbihzb3VyY2VDb2x1bW4uZ2V0TmFtZSgpLCB0aGlzLmNvbHVtbkFyZ3NGcm9tU291cmNlQ29sdW1uKHNvdXJjZUNvbHVtbiwge2lzTmV3Q29sdW1uOiBmYWxzZX0pKVxuICAgIH1cblxuICAgIGlmICh0aGlzLnRhcmdldERiLmdldFR5cGUoKSA9PT0gXCJteXNxbFwiKSB7XG4gICAgICBjb25zdCBtaXNzaW5nQXV0b0luY3JlbWVudENvbHVtbk5hbWVzID0gbmV3IFNldChcbiAgICAgICAgbWlzc2luZ0NvbHVtbnNcbiAgICAgICAgICAuZmlsdGVyKChzb3VyY2VDb2x1bW4pID0+IHNvdXJjZUNvbHVtbi5nZXRBdXRvSW5jcmVtZW50KCkpXG4gICAgICAgICAgLm1hcCgoc291cmNlQ29sdW1uKSA9PiBzb3VyY2VDb2x1bW4uZ2V0TmFtZSgpKVxuICAgICAgKVxuICAgICAgY29uc3QgdGFyZ2V0SW5kZXhlc0J5TmFtZSA9IG5ldyBNYXAoXG4gICAgICAgIChhd2FpdCB0YXJnZXRUYWJsZS5nZXRJbmRleGVzKCkpLm1hcCgodGFyZ2V0SW5kZXgpID0+IFt0YXJnZXRJbmRleC5nZXROYW1lKCksIHRhcmdldEluZGV4XSlcbiAgICAgIClcblxuICAgICAgZm9yIChjb25zdCBzb3VyY2VJbmRleCBvZiBhd2FpdCBzb3VyY2VUYWJsZS5nZXRJbmRleGVzKCkpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICFzb3VyY2VJbmRleC5pc1ByaW1hcnlLZXkoKSAmJlxuICAgICAgICAgIHNvdXJjZUluZGV4LmlzVW5pcXVlKCkgJiZcbiAgICAgICAgICBtaXNzaW5nQXV0b0luY3JlbWVudENvbHVtbk5hbWVzLmhhcyhzb3VyY2VJbmRleC5nZXRDb2x1bW5OYW1lcygpWzBdKVxuICAgICAgICApIHtcbiAgICAgICAgICBjb25zdCB0YXJnZXRJbmRleCA9IHRhcmdldEluZGV4ZXNCeU5hbWUuZ2V0KHNvdXJjZUluZGV4LmdldE5hbWUoKSlcblxuICAgICAgICAgIGlmICh0YXJnZXRJbmRleCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuaW5kZXhlc01hdGNoKHNvdXJjZUluZGV4LCB0YXJnZXRJbmRleCkpIGNvbnRpbnVlXG5cbiAgICAgICAgICAgIHRoaXMuYXNzZXJ0U2FmZUluZGV4UmVwbGFjZW1lbnQoe3NvdXJjZUluZGV4LCB0YWJsZU5hbWUsIHRhcmdldEluZGV4fSlcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZHJvcFRhcmdldEluZGV4KHt0YWJsZU5hbWUsIHRhcmdldEluZGV4fSlcbiAgICAgICAgICAgIHRhcmdldEluZGV4ZXNCeU5hbWUuZGVsZXRlKHRhcmdldEluZGV4LmdldE5hbWUoKSlcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0YWJsZURhdGEuYWRkSW5kZXgodGhpcy50YWJsZURhdGFJbmRleEZyb21Tb3VyY2VJbmRleChzb3VyY2VJbmRleCkpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGFsdGVyU3FsIG9mIGF3YWl0IHRoaXMudGFyZ2V0RGIuYWx0ZXJUYWJsZVNRTHModGFibGVEYXRhKSkge1xuICAgICAgYXdhaXQgdGhpcy50YXJnZXREYi5xdWVyeShhbHRlclNxbClcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgbm9uLXByaW1hcnkta2V5IGluZGV4ZXMgcHJlc2VudCBvbiB0aGUgc291cmNlIGJ1dCBtaXNzaW5nIGZyb20gdGhlIHRhcmdldCxcbiAgICogYW5kIHJlcGxhY2VzIHRhcmdldCBpbmRleGVzIHdob3NlIGRlZmluaXRpb24gKGNvbHVtbnMgb3IgdW5pcXVlbmVzcykgZHJpZnRlZCBmcm9tXG4gICAqIHRoZSBzb3VyY2UuXG4gICAqIEBwYXJhbSB7e3NvdXJjZVRhYmxlOiBpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UtdGFibGUuanNcIikuZGVmYXVsdCwgdGFibGVOYW1lOiBzdHJpbmd9fSBhcmdzIC0gU291cmNlIHRhYmxlIG1ldGFkYXRhIGFuZCB0YXJnZXQgdGFibGUgbmFtZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBhc3luYyBlbnN1cmVUYXJnZXRJbmRleGVzKHtzb3VyY2VUYWJsZSwgdGFibGVOYW1lfSkge1xuICAgIGNvbnN0IHRhcmdldFRhYmxlID0gYXdhaXQgdGhpcy50YXJnZXREYi5nZXRUYWJsZUJ5TmFtZU9yRmFpbCh0YWJsZU5hbWUpXG4gICAgLyoqIEB0eXBlIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UtY29sdW1ucy1pbmRleC5qc1wiKS5kZWZhdWx0Pn0gKi9cbiAgICBjb25zdCB0YXJnZXRJbmRleGVzQnlOYW1lID0gbmV3IE1hcCgpXG4gICAgY29uc3QgdGFyZ2V0SW5kZXhTaWduYXR1cmVzID0gbmV3IFNldCgpXG4gICAgbGV0IGRpcnR5ID0gZmFsc2VcblxuICAgIGZvciAoY29uc3QgdGFyZ2V0SW5kZXggb2YgYXdhaXQgdGFyZ2V0VGFibGUuZ2V0SW5kZXhlcygpKSB7XG4gICAgICB0YXJnZXRJbmRleGVzQnlOYW1lLnNldCh0YXJnZXRJbmRleC5nZXROYW1lKCksIHRhcmdldEluZGV4KVxuICAgICAgdGFyZ2V0SW5kZXhTaWduYXR1cmVzLmFkZCh0aGlzLmluZGV4U2lnbmF0dXJlKHRhcmdldEluZGV4KSlcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHNvdXJjZUluZGV4IG9mIGF3YWl0IHNvdXJjZVRhYmxlLmdldEluZGV4ZXMoKSkge1xuICAgICAgaWYgKHNvdXJjZUluZGV4LmlzUHJpbWFyeUtleSgpKSB7XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHNvdXJjZUluZGV4U2lnbmF0dXJlID0gdGhpcy5pbmRleFNpZ25hdHVyZShzb3VyY2VJbmRleClcblxuICAgICAgLy8gU1FMaXRlIGluZGV4IG5hbWVzIGFyZSB1bmlxdWUgcGVyLWRhdGFiYXNlLCBub3QgcGVyLXRhYmxlLCBzbyBtYXRjaCBjbG9uZWRcbiAgICAgIC8vIGluZGV4ZXMgYnkgdGhlaXIgY29sdW1uL3VuaXF1ZW5lc3Mgc2lnbmF0dXJlIHJhdGhlciB0aGFuIHRoZWlyIG5hbWUuXG4gICAgICBpZiAodGhpcy50YXJnZXREYi5nZXRUeXBlKCkgPT09IFwic3FsaXRlXCIgJiYgdGFyZ2V0SW5kZXhTaWduYXR1cmVzLmhhcyhzb3VyY2VJbmRleFNpZ25hdHVyZSkpIHtcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgY29uc3QgdGFyZ2V0SW5kZXggPSB0aGlzLnRhcmdldERiLmdldFR5cGUoKSA9PT0gXCJzcWxpdGVcIiA/IHVuZGVmaW5lZCA6IHRhcmdldEluZGV4ZXNCeU5hbWUuZ2V0KHNvdXJjZUluZGV4LmdldE5hbWUoKSlcblxuICAgICAgaWYgKHRhcmdldEluZGV4KSB7XG4gICAgICAgIGlmICghdGhpcy5pbmRleGVzTWF0Y2goc291cmNlSW5kZXgsIHRhcmdldEluZGV4KSkge1xuICAgICAgICAgIHRoaXMuYXNzZXJ0U2FmZUluZGV4UmVwbGFjZW1lbnQoe3NvdXJjZUluZGV4LCB0YWJsZU5hbWUsIHRhcmdldEluZGV4fSlcbiAgICAgICAgICBhd2FpdCB0aGlzLmRyb3BUYXJnZXRJbmRleCh7dGFibGVOYW1lLCB0YXJnZXRJbmRleH0pXG4gICAgICAgICAgdGFyZ2V0SW5kZXhlc0J5TmFtZS5kZWxldGUodGFyZ2V0SW5kZXguZ2V0TmFtZSgpKVxuICAgICAgICAgIHRhcmdldEluZGV4U2lnbmF0dXJlcy5kZWxldGUodGhpcy5pbmRleFNpZ25hdHVyZSh0YXJnZXRJbmRleCkpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBEcm9wIGFueSB0YXJnZXQgaW5kZXggdGhhdCBzaGFyZXMgdGhlIHNvdXJjZSBuYW1lIGJ1dCBzdXJ2aXZlZCB0aGVcbiAgICAgIC8vIGRyaWZ0IGNoZWNrIGFib3ZlIGJlY2F1c2UgdGhlIGRyaXZlciB3YXMgc2tpcHBlZCAoU1FMaXRlKS5cbiAgICAgIGNvbnN0IHNhbWVOYW1lVGFyZ2V0SW5kZXggPSB0YXJnZXRJbmRleGVzQnlOYW1lLmdldChzb3VyY2VJbmRleC5nZXROYW1lKCkpXG5cbiAgICAgIGlmIChzYW1lTmFtZVRhcmdldEluZGV4KSB7XG4gICAgICAgIGF3YWl0IHRoaXMuZHJvcFRhcmdldEluZGV4KHt0YWJsZU5hbWUsIHRhcmdldEluZGV4OiBzYW1lTmFtZVRhcmdldEluZGV4fSlcbiAgICAgICAgdGFyZ2V0SW5kZXhlc0J5TmFtZS5kZWxldGUoc2FtZU5hbWVUYXJnZXRJbmRleC5nZXROYW1lKCkpXG4gICAgICAgIHRhcmdldEluZGV4U2lnbmF0dXJlcy5kZWxldGUodGhpcy5pbmRleFNpZ25hdHVyZShzYW1lTmFtZVRhcmdldEluZGV4KSlcbiAgICAgIH1cblxuICAgICAgY29uc3QgY3JlYXRlSW5kZXhTcWxzID0gYXdhaXQgdGhpcy50YXJnZXREYi5jcmVhdGVJbmRleFNRTHModGhpcy5jcmVhdGVJbmRleEFyZ3NGcm9tU291cmNlSW5kZXgoe3NvdXJjZUluZGV4LCB0YWJsZU5hbWV9KSlcblxuICAgICAgZm9yIChjb25zdCBjcmVhdGVJbmRleFNxbCBvZiBjcmVhdGVJbmRleFNxbHMpIHtcbiAgICAgICAgYXdhaXQgdGhpcy50YXJnZXREYi5xdWVyeShjcmVhdGVJbmRleFNxbClcbiAgICAgIH1cblxuICAgICAgZGlydHkgPSB0cnVlXG4gICAgICB0YXJnZXRJbmRleFNpZ25hdHVyZXMuYWRkKHNvdXJjZUluZGV4U2lnbmF0dXJlKVxuICAgIH1cblxuICAgIGlmIChkaXJ0eSkge1xuICAgICAgdGhpcy50YXJnZXREYi5jbGVhclNjaGVtYUNhY2hlKClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRHJvcHMgYW4gaW5kZXggb24gdGhlIHRhcmdldCBkYXRhYmFzZS5cbiAgICogQHBhcmFtIHt7dGFibGVOYW1lOiBzdHJpbmcsIHRhcmdldEluZGV4OiBpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UtY29sdW1ucy1pbmRleC5qc1wiKS5kZWZhdWx0fX0gYXJncyAtIFRhcmdldCB0YWJsZSBhbmQgaW5kZXggdG8gcmVtb3ZlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIGFzeW5jIGRyb3BUYXJnZXRJbmRleCh7dGFibGVOYW1lLCB0YXJnZXRJbmRleH0pIHtcbiAgICBjb25zdCBkcm9wU3FscyA9IGF3YWl0IHRoaXMudGFyZ2V0RGIucmVtb3ZlSW5kZXhTUUxzKHtuYW1lOiB0YXJnZXRJbmRleC5nZXROYW1lKCksIHRhYmxlTmFtZX0pXG5cbiAgICBmb3IgKGNvbnN0IHNxbCBvZiBkcm9wU3Fscykge1xuICAgICAgYXdhaXQgdGhpcy50YXJnZXREYi5xdWVyeShzcWwpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlZnVzZXMgaW5kZXggcmVwbGFjZW1lbnRzIHRoYXQgY291bGQgZmFpbCBhZnRlciB0aGUgZXhpc3RpbmcgaW5kZXggaXMgZHJvcHBlZC5cbiAgICogQHBhcmFtIHt7c291cmNlSW5kZXg6IGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS1jb2x1bW5zLWluZGV4LmpzXCIpLmRlZmF1bHQsIHRhYmxlTmFtZTogc3RyaW5nLCB0YXJnZXRJbmRleDogaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLWNvbHVtbnMtaW5kZXguanNcIikuZGVmYXVsdH19IGFyZ3MgLSBTb3VyY2UgYW5kIHRhcmdldCBpbmRleCBkZWZpbml0aW9ucy5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBhc3NlcnRTYWZlSW5kZXhSZXBsYWNlbWVudCh7c291cmNlSW5kZXgsIHRhYmxlTmFtZSwgdGFyZ2V0SW5kZXh9KSB7XG4gICAgLy8gUmVwbGFjaW5nIGEgbm9uLXVuaXF1ZSBpbmRleCB3aXRoIGEgdW5pcXVlIG9uZSBpcyB1bnNhZmUgYmVjYXVzZSB0aGVcbiAgICAvLyB0YXJnZXQgbWF5IGhhdmUgZHVwbGljYXRlIHZhbHVlcyB0aGF0IHdpbGwgcmVqZWN0IHRoZSBuZXcgY29uc3RyYWludC5cbiAgICAvLyBUaGUgb3Bwb3NpdGUgZGlyZWN0aW9uIGlzIHNhZmUgYmVjYXVzZSBub24tdW5pcXVlIGluZGV4ZXMgYWNjZXB0IHRoZW0uXG4gICAgaWYgKHNvdXJjZUluZGV4LmlzVW5pcXVlKCkgJiYgIXRhcmdldEluZGV4LmlzVW5pcXVlKCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgU2NoZW1hIGNsb25lIGluZGV4IGRyaWZ0IGZvciAke3RhYmxlTmFtZX0uJHtzb3VyY2VJbmRleC5nZXROYW1lKCl9OiBjYW5ub3Qgc2FmZWx5IHJlcGxhY2UgYSBub24tdW5pcXVlIGluZGV4IHdpdGggYSB1bmlxdWUgb25lLmApXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEJhc2VsaW5lcyB0aGUgdGFyZ2V0IGxlZGdlciBzbyB0aGUgY2xvbmVkIHNjaGVtYSBpcyByZWNvcmRlZCBhcyBhbHJlYWR5LWFwcGxpZWQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHN0cmluZ1tdPn0gVGhlIHZlcnNpb25zIG5ld2x5IHJlY29yZGVkIG9uIHRoZSB0YXJnZXQuXG4gICAqL1xuICBhc3luYyByZWNvbmNpbGVMZWRnZXIoKSB7XG4gICAgcmV0dXJuIGF3YWl0IE1pZ3JhdGlvbnNMZWRnZXIuYmFzZWxpbmVGcm9tRGF0YWJhc2Uoe3NvdXJjZURiOiB0aGlzLnNvdXJjZURiLCB0YXJnZXREYjogdGhpcy50YXJnZXREYn0pXG4gIH1cblxuICAvKipcbiAgICogV2hldGhlciB0aGUgdGFyZ2V0IGxlZGdlciBpcyBtaXNzaW5nIGFueSB2ZXJzaW9uIGFwcGxpZWQgb24gdGhlIHNvdXJjZSDigJQgaS5lLiB0aGVcbiAgICogdGFyZ2V0IHNjaGVtYSBtYXkgaGF2ZSBiZWVuIGFkdmFuY2VkIG91dCBvZiBiYW5kIHdpdGhvdXQgcmVjb3JkaW5nIGl0LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gLSBXaGV0aGVyIHRoZSB0YXJnZXQgbGVkZ2VyIGRpZmZlcnMgZnJvbSB0aGUgc291cmNlLlxuICAgKi9cbiAgYXN5bmMgbGVkZ2VyRHJpZnRzRnJvbVNvdXJjZSgpIHtcbiAgICBpZiAoIWF3YWl0IE1pZ3JhdGlvbnNMZWRnZXIudGFibGVFeGlzdHModGhpcy50YXJnZXREYikpIHtcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgY29uc3Qgc291cmNlVmVyc2lvbnMgPSBhd2FpdCBNaWdyYXRpb25zTGVkZ2VyLmFwcGxpZWRWZXJzaW9ucyh0aGlzLnNvdXJjZURiKVxuICAgIGNvbnN0IHRhcmdldFZlcnNpb25TZXQgPSBuZXcgU2V0KGF3YWl0IE1pZ3JhdGlvbnNMZWRnZXIuYXBwbGllZFZlcnNpb25zKHRoaXMudGFyZ2V0RGIpKVxuXG4gICAgcmV0dXJuIHNvdXJjZVZlcnNpb25zLnNvbWUoKHZlcnNpb24pID0+ICF0YXJnZXRWZXJzaW9uU2V0Lmhhcyh2ZXJzaW9uKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBNYXBzIGEgc291cmNlIGluZGV4IGludG8gYSBUYWJsZURhdGEgaW5kZXggZm9yIHRhYmxlIGNyZWF0aW9uIChTUUxpdGUgb21pdHMgdGhlXG4gICAqIGluZGV4IG5hbWUgc28gdGhlIGRyaXZlciBjYW4gZ2VuZXJhdGUgYSB1bmlxdWUgb25lKS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UtY29sdW1ucy1pbmRleC5qc1wiKS5kZWZhdWx0fSBzb3VyY2VJbmRleCAtIFNvdXJjZSBpbmRleCBkZWZpbml0aW9uLlxuICAgKiBAcmV0dXJucyB7VGFibGVJbmRleH0gLSBGcmFtZXdvcmstaW5kZXBlbmRlbnQgaW5kZXggZGVmaW5pdGlvbi5cbiAgICovXG4gIHRhYmxlRGF0YUluZGV4RnJvbVNvdXJjZUluZGV4KHNvdXJjZUluZGV4KSB7XG4gICAgLyoqIEB0eXBlIHt7bmFtZT86IHN0cmluZywgdW5pcXVlOiBib29sZWFufX0gKi9cbiAgICBjb25zdCBhcmdzID0ge3VuaXF1ZTogc291cmNlSW5kZXguaXNVbmlxdWUoKX1cblxuICAgIC8vIFNRTGl0ZSBpbmRleCBuYW1lcyBhcmUgdW5pcXVlIHBlci1kYXRhYmFzZSwgbm90IHBlci10YWJsZSwgc28gbGV0IHRoZSBkcml2ZXJcbiAgICAvLyBnZW5lcmF0ZSBvbmU7IG90aGVyIGRyaXZlcnMgcHJlc2VydmUgdGhlIHNvdXJjZSBpbmRleCBuYW1lLiBCdWlsZCB0aGUgVGFibGVJbmRleFxuICAgIC8vIGRpcmVjdGx5IChyYXRoZXIgdGhhbiB2aWEgdGhlIGRyaXZlcidzIGdldFRhYmxlRGF0YUluZGV4LCB3aGljaCBvbmx5IE15U1FMIGFuZFxuICAgIC8vIFNRTGl0ZSBpbXBsZW1lbnQpIHNvIGNsb25pbmcgYSBQb3N0Z3JlU1FMIG9yIE1TLVNRTCBzb3VyY2UgdGFibGUgd29ya3MgdG9vLlxuICAgIGlmICh0aGlzLnRhcmdldERiLmdldFR5cGUoKSAhPT0gXCJzcWxpdGVcIikge1xuICAgICAgYXJncy5uYW1lID0gc291cmNlSW5kZXguZ2V0TmFtZSgpXG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBUYWJsZUluZGV4KHNvdXJjZUluZGV4LmdldENvbHVtbk5hbWVzKCksIGFyZ3MpXG4gIH1cblxuICAvKipcbiAgICogQnVpbGRzIGRyaXZlciBjcmVhdGUtaW5kZXggYXJncyBmcm9tIGEgc291cmNlIGluZGV4ICh0aGUgaW5kZXggbmFtZSBpcyBvbWl0dGVkIG9uXG4gICAqIFNRTGl0ZSwgd2hlcmUgaW5kZXggbmFtZXMgYXJlIHVuaXF1ZSBwZXItZGF0YWJhc2UgcmF0aGVyIHRoYW4gcGVyLXRhYmxlKS5cbiAgICogQHBhcmFtIHt7c291cmNlSW5kZXg6IGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS1jb2x1bW5zLWluZGV4LmpzXCIpLmRlZmF1bHQsIHRhYmxlTmFtZTogc3RyaW5nfX0gYXJncyAtIFNvdXJjZSBpbmRleCBhbmQgdGFyZ2V0IHRhYmxlIHJlY2VpdmluZyBpdC5cbiAgICogQHJldHVybnMge3tjb2x1bW5zOiBzdHJpbmdbXSwgbmFtZT86IHN0cmluZywgdGFibGVOYW1lOiBzdHJpbmcsIHVuaXF1ZTogYm9vbGVhbn19IC0gQXJndW1lbnRzIGZvciBjcmVhdGluZyB0aGUgdGFyZ2V0IGluZGV4LlxuICAgKi9cbiAgY3JlYXRlSW5kZXhBcmdzRnJvbVNvdXJjZUluZGV4KHtzb3VyY2VJbmRleCwgdGFibGVOYW1lfSkge1xuICAgIC8qKiBAdHlwZSB7e2NvbHVtbnM6IHN0cmluZ1tdLCBuYW1lPzogc3RyaW5nLCB0YWJsZU5hbWU6IHN0cmluZywgdW5pcXVlOiBib29sZWFufX0gKi9cbiAgICBjb25zdCBjcmVhdGVJbmRleEFyZ3MgPSB7XG4gICAgICBjb2x1bW5zOiBzb3VyY2VJbmRleC5nZXRDb2x1bW5OYW1lcygpLFxuICAgICAgdGFibGVOYW1lLFxuICAgICAgdW5pcXVlOiBzb3VyY2VJbmRleC5pc1VuaXF1ZSgpXG4gICAgfVxuXG4gICAgaWYgKHRoaXMudGFyZ2V0RGIuZ2V0VHlwZSgpICE9PSBcInNxbGl0ZVwiKSB7XG4gICAgICBjcmVhdGVJbmRleEFyZ3MubmFtZSA9IHNvdXJjZUluZGV4LmdldE5hbWUoKVxuICAgIH1cblxuICAgIHJldHVybiBjcmVhdGVJbmRleEFyZ3NcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHR3byBpbmRleGVzIGhhdmUgdGhlIHNhbWUgdW5pcXVlbmVzcyBhbmQgb3JkZXJlZCBjb2x1bW4gbGlzdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UtY29sdW1ucy1pbmRleC5qc1wiKS5kZWZhdWx0fSBzb3VyY2VJbmRleCAtIFNvdXJjZSBpbmRleCBkZWZpbml0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS1jb2x1bW5zLWluZGV4LmpzXCIpLmRlZmF1bHR9IHRhcmdldEluZGV4IC0gVGFyZ2V0IGluZGV4IGRlZmluaXRpb24uXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgYm90aCBpbmRleGVzIGhhdmUgdGhlIHNhbWUgc2hhcGUuXG4gICAqL1xuICBpbmRleGVzTWF0Y2goc291cmNlSW5kZXgsIHRhcmdldEluZGV4KSB7XG4gICAgY29uc3Qgc291cmNlQ29sdW1uTmFtZXMgPSBzb3VyY2VJbmRleC5nZXRDb2x1bW5OYW1lcygpXG4gICAgY29uc3QgdGFyZ2V0Q29sdW1uTmFtZXMgPSB0YXJnZXRJbmRleC5nZXRDb2x1bW5OYW1lcygpXG5cbiAgICBpZiAoc291cmNlSW5kZXguaXNVbmlxdWUoKSAhPT0gdGFyZ2V0SW5kZXguaXNVbmlxdWUoKSkge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgaWYgKHNvdXJjZUNvbHVtbk5hbWVzLmxlbmd0aCAhPT0gdGFyZ2V0Q29sdW1uTmFtZXMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZmFsc2VcbiAgICB9XG5cbiAgICBmb3IgKGxldCBjb2x1bW5JbmRleCA9IDA7IGNvbHVtbkluZGV4IDwgc291cmNlQ29sdW1uTmFtZXMubGVuZ3RoOyBjb2x1bW5JbmRleCsrKSB7XG4gICAgICBpZiAoc291cmNlQ29sdW1uTmFtZXNbY29sdW1uSW5kZXhdICE9PSB0YXJnZXRDb2x1bW5OYW1lc1tjb2x1bW5JbmRleF0pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIC8qKlxuICAgKiBBIHN0YWJsZSBzaWduYXR1cmUgZm9yIGFuIGluZGV4LCB1c2VkIHRvIG1hdGNoIGNsb25lZCBpbmRleGVzIGJ5IHNoYXBlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS1jb2x1bW5zLWluZGV4LmpzXCIpLmRlZmF1bHR9IGluZGV4IC0gSW5kZXggZGVmaW5pdGlvbi5cbiAgICogQHJldHVybnMge3N0cmluZ30gLSBTdGFibGUgaW5kZXgtc2hhcGUgc2lnbmF0dXJlLlxuICAgKi9cbiAgaW5kZXhTaWduYXR1cmUoaW5kZXgpIHtcbiAgICByZXR1cm4gYCR7aW5kZXguaXNVbmlxdWUoKSA/IFwidW5pcXVlXCIgOiBcImluZGV4XCJ9OiR7aW5kZXguZ2V0Q29sdW1uTmFtZXMoKS5qb2luKFwiLFwiKX1gXG4gIH1cblxuICAvKipcbiAgICogTm9ybWFsaXplcyBhIGNvbHVtbiB0eXBlIHRvIGl0cyBjYW5vbmljYWwgbG93ZXJjYXNlIGZvcm0gKGBpbnRgIGJlY29tZXMgYGludGVnZXJgKS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGNvbHVtblR5cGUgLSBEYXRhYmFzZSBjb2x1bW4gdHlwZS5cbiAgICogQHJldHVybnMge3N0cmluZ30gLSBDYW5vbmljYWwgbG93ZXJjYXNlIGNvbHVtbiB0eXBlLlxuICAgKi9cbiAgbm9ybWFsaXplZENvbHVtblR5cGUoY29sdW1uVHlwZSkge1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRUeXBlID0gY29sdW1uVHlwZS50b0xvd2VyQ2FzZSgpXG5cbiAgICBpZiAobm9ybWFsaXplZFR5cGUgPT09IFwiaW50XCIpIHtcbiAgICAgIHJldHVybiBcImludGVnZXJcIlxuICAgIH1cblxuICAgIHJldHVybiBub3JtYWxpemVkVHlwZVxuICB9XG5cbiAgLyoqXG4gICAqIFRoZSB3aWRlbmluZyByYW5rIG9mIGEgdGV4dCBjb2x1bW4gdHlwZSAoMCB3aGVuIG5vdCBhIHRleHQgdHlwZSkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjb2x1bW5UeXBlIC0gRGF0YWJhc2UgY29sdW1uIHR5cGUuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IC0gVGV4dC10eXBlIHdpZGVuaW5nIHJhbmsuXG4gICAqL1xuICB0ZXh0VHlwZVJhbmsoY29sdW1uVHlwZSkge1xuICAgIHJldHVybiBURVhUX1RZUEVfUkFOS1NbdGhpcy5ub3JtYWxpemVkQ29sdW1uVHlwZShjb2x1bW5UeXBlKV0gfHwgMFxuICB9XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIHRhcmdldCdzIHRleHQgY29sdW1uIGlzIG5hcnJvd2VyIHRoYW4gdGhlIHNvdXJjZSdzIGFuZCBtdXN0IGJlIHdpZGVuZWQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLWNvbHVtbi5qc1wiKS5kZWZhdWx0fSBzb3VyY2VDb2x1bW4gLSBTb3VyY2UgY29sdW1uIGRlZmluaXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLWNvbHVtbi5qc1wiKS5kZWZhdWx0fSB0YXJnZXRDb2x1bW4gLSBUYXJnZXQgY29sdW1uIGRlZmluaXRpb24uXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgdGhlIHRhcmdldCB0ZXh0IGNvbHVtbiBtdXN0IGJlIHdpZGVuZWQuXG4gICAqL1xuICBjb2x1bW5OZWVkc1dpZGVuaW5nKHNvdXJjZUNvbHVtbiwgdGFyZ2V0Q29sdW1uKSB7XG4gICAgY29uc3Qgc291cmNlUmFuayA9IHRoaXMudGV4dFR5cGVSYW5rKHNvdXJjZUNvbHVtbi5nZXRUeXBlKCkpXG4gICAgY29uc3QgdGFyZ2V0UmFuayA9IHRoaXMudGV4dFR5cGVSYW5rKHRhcmdldENvbHVtbi5nZXRUeXBlKCkpXG5cbiAgICByZXR1cm4gc291cmNlUmFuayA+IDAgJiYgdGFyZ2V0UmFuayA+IDAgJiYgc291cmNlUmFuayA+IHRhcmdldFJhbmtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgVGFibGVEYXRhIGNvbHVtbiBhcmdzIGZyb20gYSBzb3VyY2UgY29sdW1uLCBjb3B5aW5nIHR5cGUsIG51bGxhYmlsaXR5LFxuICAgKiBsZW5ndGgsIG5vdGVzLCBzaW1wbGUgZGVmYXVsdHMgYW5kIChmb3IgZnVsbCBjbG9uZXMpIHByaW1hcnkta2V5IGZsYWcuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLWNvbHVtbi5qc1wiKS5kZWZhdWx0fSBzb3VyY2VDb2x1bW4gLSBTb3VyY2UgY29sdW1uIGRlZmluaXRpb24uXG4gICAqIEBwYXJhbSB7e2lzTmV3Q29sdW1uOiBib29sZWFufX0gYXJncyAtIFdoZXRoZXIgdGhlIGNvbHVtbiBpcyBiZWluZyBhZGRlZCBpbnN0ZWFkIG9mIGNsb25lZCB3aXRoIGl0cyB0YWJsZS5cbiAgICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIHVua25vd24+fSAtIEFyZ3VtZW50cyBmb3IgYWx0ZXJpbmcgdGhlIHRhcmdldCBjb2x1bW4uXG4gICAqL1xuICBjb2x1bW5BcmdzRnJvbVNvdXJjZUNvbHVtbihzb3VyY2VDb2x1bW4sIHtpc05ld0NvbHVtbn0pIHtcbiAgICAvKiogQHR5cGUge3thdXRvSW5jcmVtZW50PzogYm9vbGVhbiwgZGVmYXVsdD86IHVua25vd24sIGlzTmV3Q29sdW1uOiBib29sZWFuLCBtYXhMZW5ndGg/OiBudW1iZXIsIG5vdGVzPzogc3RyaW5nLCBudWxsOiBib29sZWFuLCBwcmltYXJ5S2V5PzogYm9vbGVhbiwgdHlwZTogc3RyaW5nfX0gKi9cbiAgICBjb25zdCBjb2x1bW5BcmdzID0ge1xuICAgICAgaXNOZXdDb2x1bW4sXG4gICAgICBudWxsOiBzb3VyY2VDb2x1bW4uZ2V0TnVsbCgpLFxuICAgICAgdHlwZTogdGhpcy5ub3JtYWxpemVkQ29sdW1uVHlwZShzb3VyY2VDb2x1bW4uZ2V0VHlwZSgpKVxuICAgIH1cbiAgICBjb25zdCBkZWZhdWx0VmFsdWUgPSBzb3VyY2VDb2x1bW4uZ2V0RGVmYXVsdCgpXG4gICAgY29uc3QgbWF4TGVuZ3RoID0gc291cmNlQ29sdW1uLmdldE1heExlbmd0aCgpXG4gICAgY29uc3Qgbm90ZXMgPSBzb3VyY2VDb2x1bW4uZ2V0Tm90ZXMoKVxuXG4gICAgaWYgKCFpc05ld0NvbHVtbiAmJiBzb3VyY2VDb2x1bW4uZ2V0UHJpbWFyeUtleSgpKSB7XG4gICAgICBjb2x1bW5BcmdzLnByaW1hcnlLZXkgPSB0cnVlXG4gICAgfVxuXG4gICAgaWYgKHNvdXJjZUNvbHVtbi5nZXRBdXRvSW5jcmVtZW50KCkpIHtcbiAgICAgIGNvbHVtbkFyZ3MuYXV0b0luY3JlbWVudCA9IHRydWVcbiAgICB9XG5cbiAgICAvLyBBIG1heExlbmd0aCBvZiAtMSBpcyB0aGUgTVMtU1FMIFwibWF4XCIgc2VudGluZWwgKE5WQVJDSEFSKE1BWCkgLyBWQVJCSU5BUlkoTUFYKSxcbiAgICAvLyBiYWNraW5nIFZlbG9jaW91cyB0ZXh0L2pzb24vYmxvYiBjb2x1bW5zKTsgdGhlIGNvbHVtbiB0eXBlIGRyaXZlcyB0aGUgdW5ib3VuZGVkXG4gICAgLy8gU1FMLCBzbyBkb24ndCBmb3J3YXJkIC0xIGFzIGFuIGV4cGxpY2l0IGxlbmd0aCAoaXQgd291bGQgZW1pdCBOVkFSQ0hBUigtMSkpLlxuICAgIGlmIChtYXhMZW5ndGggIT09IHVuZGVmaW5lZCAmJiBtYXhMZW5ndGggPj0gMCkge1xuICAgICAgY29sdW1uQXJncy5tYXhMZW5ndGggPSBtYXhMZW5ndGhcbiAgICB9XG5cbiAgICBpZiAobm90ZXMpIHtcbiAgICAgIGNvbHVtbkFyZ3Mubm90ZXMgPSBub3Rlc1xuICAgIH1cblxuICAgIGlmIChkZWZhdWx0VmFsdWUgIT09IG51bGwgJiYgZGVmYXVsdFZhbHVlICE9PSB1bmRlZmluZWQgJiYgU0lNUExFX0RFRkFVTFRfUEFUVEVSTi50ZXN0KFN0cmluZyhkZWZhdWx0VmFsdWUpKSkge1xuICAgICAgY29sdW1uQXJncy5kZWZhdWx0ID0gZGVmYXVsdFZhbHVlXG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbHVtbkFyZ3NcbiAgfVxufVxuIl19
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"velocious": "build/bin/velocious.js"
|
|
4
4
|
},
|
|
5
5
|
"name": "velocious",
|
|
6
|
-
"version": "1.0.
|
|
6
|
+
"version": "1.0.532",
|
|
7
7
|
"main": "build/index.js",
|
|
8
8
|
"types": "build/index.d.ts",
|
|
9
9
|
"files": [
|
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
],
|
|
17
17
|
"scripts": {
|
|
18
18
|
"all-checks": "npm run lint && npm run test",
|
|
19
|
+
"benchmark:preloader-id-dedup": "node benchmark/preloader-id-dedup.js",
|
|
20
|
+
"benchmark:mysql-result-row-materialization": "node benchmark/mysql-result-row-materialization.js",
|
|
19
21
|
"build": "node scripts/clean-build.js && npm run compile",
|
|
20
22
|
"compile": "tsc -b && npm run copy:js && npm run copy:ejs && npm run copy:templates && node scripts/ensure-bin-executable.js",
|
|
21
23
|
"copy:js": "cpy \"index.js\" build && cpy \"bin/**/*.js\" build/bin && cpy \"src/**/*.js\" build --parents",
|
|
@@ -78,9 +78,10 @@ function runnerProcessTitle(JobClass, payload) {
|
|
|
78
78
|
* @param {import("./types.js").BackgroundJobPayload} payload - Payload.
|
|
79
79
|
* @param {object} [options] - Runner options.
|
|
80
80
|
* @param {boolean} [options.closeConnections] - Whether to gracefully close framework connections after the job.
|
|
81
|
+
* @param {boolean} [options.manageProcessTitle] - Whether to set the per-job process title and restore it afterwards. Off for concurrent pooled runners, where interleaved snapshot/restore of the single process-wide `process.title` would corrupt it; the pooled child owns an aggregate title instead.
|
|
81
82
|
* @returns {Promise<void>} - Resolves when complete.
|
|
82
83
|
*/
|
|
83
|
-
export default async function runJobPayload(payload, {closeConnections = true} = {}) {
|
|
84
|
+
export default async function runJobPayload(payload, {closeConnections = true, manageProcessTitle = true} = {}) {
|
|
84
85
|
const configuration = await configurationResolver()
|
|
85
86
|
configuration.setCurrent()
|
|
86
87
|
await configuration.initialize({type: "background-jobs-runner"})
|
|
@@ -98,8 +99,9 @@ export default async function runJobPayload(payload, {closeConnections = true} =
|
|
|
98
99
|
|
|
99
100
|
// Name the process after the job it is running so `ps`/`top` show what each
|
|
100
101
|
// runner is doing; restored in the `finally` below when the job finishes.
|
|
102
|
+
// Skipped for concurrent pooled runners, whose child owns an aggregate title.
|
|
101
103
|
const previousTitle = process.title
|
|
102
|
-
process.title = runnerProcessTitle(JobClass, payload)
|
|
104
|
+
if (manageProcessTitle) process.title = runnerProcessTitle(JobClass, payload)
|
|
103
105
|
|
|
104
106
|
try {
|
|
105
107
|
try {
|
|
@@ -136,7 +138,7 @@ export default async function runJobPayload(payload, {closeConnections = true} =
|
|
|
136
138
|
} finally {
|
|
137
139
|
// Restore the runner's base title so a lingering/idle runner (or a reused
|
|
138
140
|
// one) doesn't misreport a finished job as still running.
|
|
139
|
-
process.title = previousTitle
|
|
141
|
+
if (manageProcessTitle) process.title = previousTitle
|
|
140
142
|
if (closeConnections) {
|
|
141
143
|
try {
|
|
142
144
|
await configuration.disconnectBeacon()
|
|
@@ -3,8 +3,32 @@
|
|
|
3
3
|
import runJobPayload, { BackgroundJobPerformedFailure } from "./job-runner.js"
|
|
4
4
|
import setRunnerProcessTitle from "./runner-process-title.js"
|
|
5
5
|
|
|
6
|
+
const BASE_PROCESS_TITLE = "velocious background-jobs-runner"
|
|
7
|
+
|
|
6
8
|
setRunnerProcessTitle()
|
|
7
|
-
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Ids of jobs currently running in this child. A pooled child runs up to
|
|
12
|
+
* `pooledRunnerConcurrency` jobs at once (the worker only dispatches within that
|
|
13
|
+
* bound); the set dedupes a redelivered job id and lets each job settle
|
|
14
|
+
* independently.
|
|
15
|
+
* @type {Set<string>}
|
|
16
|
+
*/
|
|
17
|
+
const runningJobIds = new Set()
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Sets an aggregate process title from the current in-flight count. A child runs
|
|
21
|
+
* jobs concurrently, so a per-job title (which `runJobPayload` would snapshot and
|
|
22
|
+
* restore around a single job) cannot represent the process — interleaved
|
|
23
|
+
* completions would leave a stale label. Recomputing from `runningJobIds.size` is
|
|
24
|
+
* concurrency-safe and honest: `ps`/`top` show how many jobs the child is running.
|
|
25
|
+
* @returns {void}
|
|
26
|
+
*/
|
|
27
|
+
function updateProcessTitle() {
|
|
28
|
+
const count = runningJobIds.size
|
|
29
|
+
|
|
30
|
+
process.title = count > 0 ? `${BASE_PROCESS_TITLE}: ${count} ${count === 1 ? "job" : "jobs"}` : BASE_PROCESS_TITLE
|
|
31
|
+
}
|
|
8
32
|
|
|
9
33
|
/**
|
|
10
34
|
* Checks whether an IPC value is a runnable pooled job message.
|
|
@@ -46,33 +70,46 @@ function sendOutcome({jobId, acknowledged, status, error}) {
|
|
|
46
70
|
}
|
|
47
71
|
|
|
48
72
|
/**
|
|
49
|
-
*
|
|
50
|
-
*
|
|
73
|
+
* Runs one job concurrently with any siblings and reports its own terminal
|
|
74
|
+
* outcome. A single job's unexpected failure reports that job for reclamation
|
|
75
|
+
* (`acknowledged: false`) but does NOT take down the child — its concurrent
|
|
76
|
+
* siblings keep running. Only a process-level fault (which escapes every
|
|
77
|
+
* per-job try/catch) ends the child, which the worker sees as an exit and
|
|
78
|
+
* reclaims for the whole in-flight set.
|
|
79
|
+
* @param {import("./types.js").BackgroundJobPayload & {id: string}} payload - Job payload.
|
|
51
80
|
* @returns {Promise<void>} - Resolves after reporting.
|
|
52
81
|
*/
|
|
53
|
-
async function
|
|
54
|
-
if (running || !isJobMessage(message)) return
|
|
55
|
-
|
|
56
|
-
running = true
|
|
82
|
+
async function runJob(payload) {
|
|
57
83
|
try {
|
|
58
|
-
await runJobPayload(
|
|
59
|
-
await sendOutcome({jobId:
|
|
84
|
+
await runJobPayload(payload, {closeConnections: false, manageProcessTitle: false})
|
|
85
|
+
await sendOutcome({jobId: payload.id, acknowledged: true, status: "completed"})
|
|
60
86
|
} catch (error) {
|
|
61
87
|
if (error instanceof BackgroundJobPerformedFailure) {
|
|
62
|
-
await sendOutcome({jobId:
|
|
88
|
+
await sendOutcome({jobId: payload.id, acknowledged: true, status: "failed"})
|
|
63
89
|
} else {
|
|
64
90
|
const reportError = error instanceof Error ? error : new Error(String(error))
|
|
65
91
|
console.error("Pooled background job runner failed before terminal acknowledgement:", reportError)
|
|
66
|
-
await sendOutcome({jobId:
|
|
67
|
-
process.exitCode = 1
|
|
68
|
-
if (process.disconnect) process.disconnect()
|
|
69
|
-
setImmediate(() => process.exit(1))
|
|
92
|
+
await sendOutcome({jobId: payload.id, acknowledged: false, error: reportError})
|
|
70
93
|
}
|
|
71
94
|
} finally {
|
|
72
|
-
|
|
95
|
+
runningJobIds.delete(payload.id)
|
|
96
|
+
updateProcessTitle()
|
|
73
97
|
}
|
|
74
98
|
}
|
|
75
99
|
|
|
76
|
-
|
|
100
|
+
/**
|
|
101
|
+
* Handles a job message, starting it alongside any concurrent siblings.
|
|
102
|
+
* @param {?} message - IPC message.
|
|
103
|
+
* @returns {void}
|
|
104
|
+
*/
|
|
105
|
+
function handleMessage(message) {
|
|
106
|
+
if (!isJobMessage(message) || runningJobIds.has(message.payload.id)) return
|
|
107
|
+
|
|
108
|
+
runningJobIds.add(message.payload.id)
|
|
109
|
+
updateProcessTitle()
|
|
110
|
+
void runJob(message.payload)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
process.on("message", (message) => handleMessage(message))
|
|
77
114
|
process.once("disconnect", () => process.exit(0))
|
|
78
115
|
for (const signal of ["SIGTERM", "SIGINT"]) process.once(signal, () => process.exit(1))
|