velocious 1.0.718 → 1.0.720
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 +2 -0
- package/build/configuration.js +20 -2
- package/build/database/advisory-lock-file-backend.js +21 -3
- package/build/database/advisory-lock-lock-server-backend.js +12 -2
- package/build/database/advisory-lock-runner.js +91 -1
- package/build/database/migrator.js +5 -5
- package/build/src/configuration.d.ts +18 -1
- package/build/src/configuration.d.ts.map +1 -1
- package/build/src/configuration.js +20 -3
- package/build/src/database/advisory-lock-file-backend.d.ts +2 -1
- package/build/src/database/advisory-lock-file-backend.d.ts.map +1 -1
- package/build/src/database/advisory-lock-file-backend.js +18 -5
- package/build/src/database/advisory-lock-lock-server-backend.d.ts +5 -1
- package/build/src/database/advisory-lock-lock-server-backend.d.ts.map +1 -1
- package/build/src/database/advisory-lock-lock-server-backend.js +11 -3
- package/build/src/database/advisory-lock-runner.d.ts +42 -0
- package/build/src/database/advisory-lock-runner.d.ts.map +1 -1
- package/build/src/database/advisory-lock-runner.js +82 -2
- package/build/src/database/migrator.js +6 -6
- package/package.json +1 -1
- package/src/configuration.js +20 -2
- package/src/database/advisory-lock-file-backend.js +21 -3
- package/src/database/advisory-lock-lock-server-backend.js +12 -2
- package/src/database/advisory-lock-runner.js +91 -1
- package/src/database/migrator.js +5 -5
|
@@ -55,11 +55,11 @@ export default class VelociousDatabaseMigrator {
|
|
|
55
55
|
* @returns {Promise<void>} - Resolves when complete.
|
|
56
56
|
*/
|
|
57
57
|
async prepare() {
|
|
58
|
-
|
|
58
|
+
this.logger.debug("prepare() start");
|
|
59
59
|
await this.createMigrationsTable();
|
|
60
|
-
|
|
60
|
+
this.logger.debug("createMigrationsTable done");
|
|
61
61
|
await this.loadMigrationsVersions();
|
|
62
|
-
|
|
62
|
+
this.logger.debug("prepare() done");
|
|
63
63
|
}
|
|
64
64
|
/**
|
|
65
65
|
* Runs create migrations table.
|
|
@@ -477,7 +477,7 @@ export default class VelociousDatabaseMigrator {
|
|
|
477
477
|
async runMigrationFile({ migration, requireMigration, direction = "up" }) {
|
|
478
478
|
if (!this.configuration)
|
|
479
479
|
throw new Error("No configuration set");
|
|
480
|
-
|
|
480
|
+
this.logger.debug("runMigrationFile", { file: migration && migration.file });
|
|
481
481
|
if (!this.configuration.isDatabasePoolInitialized())
|
|
482
482
|
await this.configuration.initializeDatabasePool();
|
|
483
483
|
if (!this.migrationsVersions)
|
|
@@ -532,7 +532,7 @@ export default class VelociousDatabaseMigrator {
|
|
|
532
532
|
//
|
|
533
533
|
// The version is re-read *inside* the lock: while this process waited, another process
|
|
534
534
|
// may already have applied the migration, in which case this one must become a no-op.
|
|
535
|
-
|
|
535
|
+
this.logger.debug("acquiring migration advisory lock", { databaseIdentifier: dbIdentifier, file: migration.file });
|
|
536
536
|
const runner = new AdvisoryLockRunner({
|
|
537
537
|
configuration: this.configuration,
|
|
538
538
|
connectionProvider: () => db,
|
|
@@ -617,4 +617,4 @@ export default class VelociousDatabaseMigrator {
|
|
|
617
617
|
return applied;
|
|
618
618
|
}
|
|
619
619
|
}
|
|
620
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlncmF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZGF0YWJhc2UvbWlncmF0b3IuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sRUFBQyxJQUFJLEVBQUMsTUFBTSxXQUFXLENBQUE7QUFDOUIsT0FBTyxLQUFLLFVBQVUsTUFBTSxZQUFZLENBQUE7QUFDeEMsT0FBTyxNQUFNLE1BQU0sY0FBYyxDQUFBO0FBQ2pDLE9BQU8sZ0JBQWdCLE1BQU0sd0JBQXdCLENBQUE7QUFDckQsT0FBTyxrQkFBa0IsTUFBTSwyQkFBMkIsQ0FBQTtBQUMxRCxPQUFPLEVBQUMsbUJBQW1CLEVBQUMsTUFBTSxzQkFBc0IsQ0FBQTtBQUN4RCxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQTtBQUN2RyxPQUFPLGFBQWEsTUFBTSw2QkFBNkIsQ0FBQTtBQUV2RDs7Ozs7Ozs7R0FRRztBQUNILFNBQVMsMEJBQTBCLENBQUMsWUFBWTtJQUM5QyxPQUFPLHdCQUF3QixZQUFZLEVBQUUsQ0FBQTtBQUMvQyxDQUFDO0FBRUQsTUFBTSxDQUFDLE9BQU8sT0FBTyx5QkFBeUI7SUFDNUM7O3lEQUVxRDtJQUNyRCxrQkFBa0IsR0FBRyxFQUFFLENBQUE7SUFFdkI7Ozs7OztPQU1HO0lBQ0gsWUFBWSxFQUFDLGFBQWEsRUFBRSxtQkFBbUIsRUFBRSxjQUFjLEVBQUUsR0FBRyxRQUFRLEVBQUM7UUFDM0UsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFBO1FBRXZCLElBQUksQ0FBQyxhQUFhO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxvQ0FBb0MsQ0FBQyxDQUFBO1FBRXpFLElBQUksQ0FBQyxhQUFhLEdBQUcsYUFBYSxDQUFBO1FBQ2xDLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxtQkFBbUIsQ0FBQTtRQUM5QyxJQUFJLENBQUMsY0FBYyxHQUFHLGNBQWMsS0FBSyxTQUFTLENBQUMs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d0JBQ0gsQ0FBQzs2QkFBTSxDQUFDOzRCQUNOLE1BQU0sV0FBVyxDQUFBO3dCQUNuQixDQUFDO29CQUNILENBQUM7b0JBRUQsTUFBTSxnQkFBZ0IsQ0FBQyxhQUFhLENBQUMsRUFBRSxFQUFFLFVBQVUsQ0FBQyxDQUFBO2dCQUN0RCxDQUFDO3FCQUFNLENBQUM7b0JBQ04sSUFBSSxDQUFDO3dCQUNILE1BQU0saUJBQWlCLENBQUMsSUFBSSxFQUFFLENBQUE7b0JBQ2hDLENBQUM7b0JBQUMsT0FBTyxTQUFTLEVBQUUsQ0FBQzt3QkFDbkIsSUFBSSxTQUFTLFlBQVksbUJBQW1CLEVBQUUsQ0FBQzs0QkFDN0MsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQ0FBcUMsU0FBUyxDQUFDLElBQUksbUVBQW1FLEVBQUUsRUFBQyxLQUFLLEVBQUUsU0FBUyxFQUFDLENBQUMsQ0FBQTt3QkFDN0osQ0FBQzs2QkFBTSxDQUFDOzRCQUNOLE1BQU0sU0FBUyxDQUFBO3dCQUNqQixDQUFDO29CQUNILENBQUM7b0JBRUQsTUFBTSxnQkFBZ0IsQ0FBQyxhQUFhLENBQUMsRUFBRSxFQUFFLFVBQVUsQ0FBQyxDQUFBO2dCQUN0RCxDQUFDO2dCQUVELE9BQU8sSUFBSSxDQUFBO1lBQ2IsQ0FBQztZQUNELDBFQUEwRTtZQUMxRSwyRUFBMkU7WUFDM0UsMEVBQTBFO1lBQzFFLEVBQUMsbUJBQW1CLEVBQUUsSUFBSSxFQUFDLENBQzVCLENBQUE7WUFFRCxJQUFJLENBQUMsYUFBYTtnQkFBRSxTQUFRO1lBRTVCLE9BQU8sR0FBRyxJQUFJLENBQUE7UUFDaEIsQ0FBQztRQUVELE9BQU8sT0FBTyxDQUFBO0lBQ2hCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQge2RpZ2d9IGZyb20gXCJkaWdnZXJpemVcIlxuaW1wb3J0ICogYXMgaW5mbGVjdGlvbiBmcm9tIFwiaW5mbGVjdGlvblwiXG5pbXBvcnQgTG9nZ2VyIGZyb20gXCIuLi9sb2dnZXIuanNcIlxuaW1wb3J0IE1pZ3JhdGlvbnNMZWRnZXIgZnJvbSBcIi4vbWlncmF0aW9ucy1sZWRnZXIuanNcIlxuaW1wb3J0IEFkdmlzb3J5TG9ja1J1bm5lciBmcm9tIFwiLi9hZHZpc29yeS1sb2NrLXJ1bm5lci5qc1wiXG5pbXBvcnQge05vdEltcGxlbWVudGVkRXJyb3J9IGZyb20gXCIuL21pZ3JhdGlvbi9pbmRleC5qc1wiXG5pbXBvcnQgeyBtaWdyYXRpb25FeGVjdXRpb25QaGFzZSwgbWlncmF0aW9uUnVuc0luRXhlY3V0aW9uUGhhc2UgfSBmcm9tIFwiLi9taWdyYXRpb24tZXhlY3V0aW9uLXBoYXNlLmpzXCJcbmltcG9ydCByZXN0QXJnc0Vycm9yIGZyb20gXCIuLi91dGlscy9yZXN0LWFyZ3MtZXJyb3IuanNcIlxuXG4vKipcbiAqIEJ1aWxkcyB0aGUgYWR2aXNvcnktbG9jayBuYW1lIHRoYXQgc2VyaWFsaXNlcyBtaWdyYXRpb25zIGZvciBvbmUgZGF0YWJhc2UgaWRlbnRpZmllci5cbiAqXG4gKiBUaGUgbmFtZSBpcyBkZXJpdmVkIGZyb20gdGhlIGRhdGFiYXNlIGlkZW50aWZpZXIgb25seSAobm90IHRoZSBtaWdyYXRpb24pIHNvIHRoYXRcbiAqIGNvbmN1cnJlbnQgcHJvY2Vzc2VzIHF1ZXVlIG9uIG9uZSBsb2NrIHdoaWxlIGFwcGx5aW5nIHRoZSBwZW5kaW5nIHNldCwgaW5zdGVhZCBvZlxuICogcmFjaW5nIG9uIGluZGl2aWR1YWwgRERMIHN0YXRlbWVudHMuXG4gKiBAcGFyYW0ge3N0cmluZ30gZGJJZGVudGlmaWVyIC0gRGF0YWJhc2UgaWRlbnRpZmllciBiZWluZyBtaWdyYXRlZC5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IC0gQWR2aXNvcnkgbG9jayBuYW1lLlxuICovXG5mdW5jdGlvbiBtaWdyYXRpb25zQWR2aXNvcnlMb2NrTmFtZShkYklkZW50aWZpZXIpIHtcbiAgcmV0dXJuIGB2ZWxvY2lvdXM6bWlncmF0aW9uczoke2RiSWRlbnRpZmllcn1gXG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFZlbG9jaW91c0RhdGFiYXNlTWlncmF0b3Ige1xuICAvKipcbiAgICogTWlncmF0aW9ucyB2ZXJzaW9ucy5cbiAgICogQHR5cGUge1JlY29yZDxzdHJpbmcsIFJlY29yZDxzdHJpbmcsIGJvb2xlYW4+Pn0gKi9cbiAgbWlncmF0aW9uc1ZlcnNpb25zID0ge31cblxuICAvKipcbiAgICogUnVucyBjb25zdHJ1Y3Rvci5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHR9IGFyZ3MuY29uZmlndXJhdGlvbiAtIENvbmZpZ3VyYXRpb24gaW5zdGFuY2UuXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IFthcmdzLmRhdGFiYXNlSWRlbnRpZmllcnNdIC0gT3B0aW9uYWwgZGF0YWJhc2UgaWRlbnRpZmllcnMgdG8gbWlncmF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL21pZ3JhdGlvbi1leGVjdXRpb24tcGhhc2UuanNcIikuTWlncmF0aW9uRXhlY3V0aW9uUGhhc2V9IFthcmdzLmV4ZWN1dGlvblBoYXNlXSAtIE9wdGlvbmFsIG1pZ3JhdGlvbiBleGVjdXRpb24gcGhhc2UgdG8gc2VsZWN0LlxuICAgKi9cbiAgY29uc3RydWN0b3Ioe2NvbmZpZ3VyYXRpb24sIGRhdGFiYXNlSWRlbnRpZmllcnMsIGV4ZWN1dGlvblBoYXNlLCAuLi5yZXN0QXJnc30pIHtcbiAgICByZXN0QXJnc0Vycm9yKHJlc3RBcmdzKVxuXG4gICAgaWYgKCFjb25maWd1cmF0aW9uKSB0aHJvdyBuZXcgRXJyb3IoXCJjb25maWd1cmF0aW9uIGFyZ3VtZW50IGlzIHJlcXVpcmVkXCIpXG5cbiAgICB0aGlzLmNvbmZpZ3VyYXRpb24gPSBjb25maWd1cmF0aW9uXG4gICAgdGhpcy5kYXRhYmFzZUlkZW50aWZpZXJzID0gZGF0YWJhc2VJZGVudGlmaWVyc1xuICAgIHRoaXMuZXhlY3V0aW9uUGhhc2UgPSBleGVjdXRpb25QaGFzZSA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogbWlncmF0aW9uRXhlY3V0aW9uUGhhc2UoZXhlY3V0aW9uUGhhc2UpXG4gICAgdGhpcy5sb2dnZXIgPSBuZXcgTG9nZ2VyKHRoaXMpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBoYW5kbGVzIGRhdGFiYXNlIGlkZW50aWZpZXIuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBkYklkZW50aWZpZXIgLSBEYXRhYmFzZSBpZGVudGlmaWVyLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHRoaXMgbWlncmF0b3Igc2hvdWxkIHRvdWNoIHRoZSBkYXRhYmFzZSBpZGVudGlmaWVyLlxuICAgKi9cbiAgaGFuZGxlc0RhdGFiYXNlSWRlbnRpZmllcihkYklkZW50aWZpZXIpIHtcbiAgICBpZiAoIXRoaXMuZGF0YWJhc2VJZGVudGlmaWVycykgcmV0dXJuIHRydWVcblxuICAgIHJldHVybiB0aGlzLmRhdGFiYXNlSWRlbnRpZmllcnMuaW5jbHVkZXMoZGJJZGVudGlmaWVyKVxuICB9XG5cblxuICAvKipcbiAgICogUnVucyBwcmVwYXJlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgcHJlcGFyZSgpIHtcbiAgICBjb25zb2xlLmVycm9yKFwiW01JRy1ERUJVR10gcHJlcGFyZSgpIHN0YXJ0XCIpXG4gICAgYXdhaXQgdGhpcy5jcmVhdGVNaWdyYXRpb25zVGFibGUoKVxuICAgIGNvbnNvbGUuZXJyb3IoXCJbTUlHLURFQlVHXSBjcmVhdGVNaWdyYXRpb25zVGFibGUgZG9uZVwiKVxuICAgIGF3YWl0IHRoaXMubG9hZE1pZ3JhdGlvbnNWZXJzaW9ucygpXG4gICAgY29uc29sZS5lcnJvcihcIltNSUctREVCVUddIHByZXBhcmUoKSBkb25lXCIpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBjcmVhdGUgbWlncmF0aW9ucyB0YWJsZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIGNyZWF0ZU1pZ3JhdGlvbnNUYWJsZSgpIHtcbiAgICBjb25zdCBkYnMgPSBhd2FpdCB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0Q3VycmVudENvbm5lY3Rpb25zKClcblxuICAgIGZvciAoY29uc3QgZGJJZGVudGlmaWVyIGluIGRicykge1xuICAgICAgaWYgKCF0aGlzLmhhbmRsZXNEYXRhYmFzZUlkZW50aWZpZXIoZGJJZGVudGlmaWVyKSkgY29udGludWVcblxuICAgICAgYXdhaXQgdGhpcy5jcmVhdGVNaWdyYXRpb25zVGFibGVGb3JEYXRhYmFzZSh7ZGJJZGVudGlmaWVyLCBkYjogZGJzW2RiSWRlbnRpZmllcl19KVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGNyZWF0ZSBtaWdyYXRpb25zIHRhYmxlIGZvciBkYXRhYmFzZS5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MuZGJJZGVudGlmaWVyIC0gRGF0YWJhc2UgaWRlbnRpZmllci5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBhcmdzLmRiIC0gRGF0YWJhc2UgY29ubmVjdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIGNyZWF0ZU1pZ3JhdGlvbnNUYWJsZUZvckRhdGFiYXNlKHtkYklkZW50aWZpZXIsIGRifSkge1xuICAgIGNvbnN0IGRhdGFiYXNlQ29uZmlndXJhdGlvbiA9IHRoaXMuY29uZmlndXJhdGlvbi5nZXREYXRhYmFzZUlkZW50aWZpZXIoZGJJZGVudGlmaWVyKVxuXG4gICAgaWYgKCFkYXRhYmFzZUNvbmZpZ3VyYXRpb24ubWlncmF0aW9ucykge1xuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoYCR7ZGJJZGVudGlmaWVyfSBpc24ndCBjb25maWd1cmVkIGZvciBtaWdyYXRpb25zIC0gc2tpcHBpbmcgY3JlYXRpbmcgbWlncmF0aW9ucyB0YWJsZSBmb3IgaXRgKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKGF3YWl0IHRoaXMubWlncmF0aW9uc1RhYmxlRXhpc3QoZGIpKSB7XG4gICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgJHtkYklkZW50aWZpZXJ9IG1pZ3JhdGlvbnMgdGFibGUgYWxyZWFkeSBleGlzdHMgLSBza2lwcGluZ2ApXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKFwiQ3JlYXRpbmcgc2NoZW1hX21pZ3JhdGlvbnMgdGFibGUgdmlhIE1pZ3JhdGlvbnNMZWRnZXJcIilcbiAgICAgIGF3YWl0IE1pZ3JhdGlvbnNMZWRnZXIuZW5zdXJlVGFibGUoZGIpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgaGFzIHJ1biBtaWdyYXRpb24gdmVyc2lvbi5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGRiSWRlbnRpZmllciAtIERiIGlkZW50aWZpZXIuXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB2ZXJzaW9uIC0gVmVyc2lvbi5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciBpdCBoYXMgcnVuIG1pZ3JhdGlvbiB2ZXJzaW9uLlxuICAgKi9cbiAgaGFzUnVuTWlncmF0aW9uVmVyc2lvbihkYklkZW50aWZpZXIsIHZlcnNpb24pIHtcbiAgICBpZiAoIXRoaXMubWlncmF0aW9uc1ZlcnNpb25zKSB0aHJvdyBuZXcgRXJyb3IoXCJNaWdyYXRpb25zIHZlcnNpb25zIGhhc24ndCBiZWVuIGxvYWRlZCB5ZXRcIilcbiAgICBpZiAoIXRoaXMubWlncmF0aW9uc1ZlcnNpb25zW2RiSWRlbnRpZmllcl0pIHRocm93IG5ldyBFcnJvcihgTWlncmF0aW9ucyB2ZXJzaW9ucyBoYXNuJ3QgYmVlbiBsb2FkZWQgeWV0IGZvciBkYjogJHtkYklkZW50aWZpZXJ9YClcblxuICAgIGlmICh2ZXJzaW9uIGluIHRoaXMubWlncmF0aW9uc1ZlcnNpb25zW2RiSWRlbnRpZmllcl0pIHtcbiAgICAgIHJldHVybiB0cnVlXG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICAvKipcbiAgICogQXBwbGljYXRpb24gbWlncmF0aW9ucyBiZWxvbmcgdG8gdGhlIHNjaGVtYS1vd25pbmcgbGlmZWN5Y2xlLiBIVFRQIHdvcmtlclxuICAgKiB0aHJlYWRzIChgcHJvY2Vzc0NvbnRleHQudHlwZSA9PT0gXCJ3b3JrZXItaGFuZGxlclwiYCkgZWFjaCBydW4gdGhlXG4gICAqIGFwcGxpY2F0aW9uJ3MgYGluaXRpYWxpemVNb2RlbHNgIGhvb2ssIHNvIGFuIGFwcCB0aGF0IG1pZ3JhdGVzIGZyb20gdGhhdCBob29rXG4gICAqIHdvdWxkIGFwcGx5IHRoZSBwZW5kaW5nIHNldCAoYW5kIHdyaXRlIHRoZSBzdHJ1Y3R1cmUgZHVtcCkgb25jZSBwZXIgd29ya2VyLlxuICAgKiBUaGUgc2VydmVyIHByb2Nlc3MgYW5kIGRlcGxveSBtaWdyYXRpb24gdGFza3MgbWlncmF0ZSBiZWZvcmUgd29ya2VycyBzdGFydCxcbiAgICogc28gd29ya2VycyBza2lwIGhlcmUgaW5zdGVhZCBvZiByZXBlYXRpbmcgdGhhdCB3b3JrLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gLSBXaGV0aGVyIHRoaXMgbGlmZWN5Y2xlIG11c3Qgc2tpcCBhcHBsaWNhdGlvbiBtaWdyYXRpb25zLlxuICAgKi9cbiAgYXN5bmMgX3NraXBBcHBsaWNhdGlvbk1pZ3JhdGlvbnNJbldvcmtlckxpZmVjeWNsZSgpIHtcbiAgICBjb25zdCBwcm9jZXNzQ29udGV4dCA9IHRoaXMuY29uZmlndXJhdGlvbi5nZXRBcHBsaWNhdGlvblByb2Nlc3NDb250ZXh0KClcblxuICAgIGlmIChwcm9jZXNzQ29udGV4dD8udHlwZSAhPT0gXCJ3b3JrZXItaGFuZGxlclwiKSByZXR1cm4gZmFsc2VcblxuICAgIGF3YWl0IHRoaXMubG9nZ2VyLmRlYnVnKFwiU2tpcHBpbmcgYXBwbGljYXRpb24gbWlncmF0aW9ucyBpbiBhbiBIVFRQIHdvcmtlciB0aHJlYWQgLSB0aGUgc2NoZW1hLW93bmluZyBwcm9jZXNzIG1pZ3JhdGVzIGJlZm9yZSB3b3JrZXJzIHN0YXJ0XCIsIHtcbiAgICAgIGluc3RhbmNlSWQ6IHByb2Nlc3NDb250ZXh0Lmluc3RhbmNlSWQsXG4gICAgICBwcm9jZXNzVHlwZTogcHJvY2Vzc0NvbnRleHQudHlwZVxuICAgIH0pXG5cbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgbWlncmF0ZSBmaWxlcy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL21pZ3JhdG9yL3R5cGVzLmpzXCIpLk1pZ3JhdGlvbk9iamVjdFR5cGVbXX0gZmlsZXMgLSBGaWxlcy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL21pZ3JhdG9yL3R5cGVzLmpzXCIpLkltcG9ydEZ1bGxwYXRoQ2FsbGJhY2tUeXBlfSBpbXBvcnRDYWxsYmFjayAtIEltcG9ydCBjYWxsYmFjay5cbiAgICogQHJldHVybnMge1Byb21pc2U8bnVtYmVyPn0gLSBOdW1iZXIgb2YgbWlncmF0aW9ucyBhY3R1YWxseSBhcHBsaWVkIChub3Qgc2tpcHBlZCBhcyBhbHJlYWR5LXJ1bikuXG4gICAqL1xuICBhc3luYyBtaWdyYXRlRmlsZXMoZmlsZXMsIGltcG9ydENhbGxiYWNrKSB7XG4gICAgaWYgKGF3YWl0IHRoaXMuX3NraXBBcHBsaWNhdGlvbk1pZ3JhdGlvbnNJbldvcmtlckxpZmVjeWNsZSgpKSByZXR1cm4gMFxuXG4gICAgbGV0IGFwcGxpZWRDb3VudCA9IDBcblxuICAgIGF3YWl0IHRoaXMuY29uZmlndXJhdGlvbi5lbnN1cmVDb25uZWN0aW9ucyh7ZGF0YWJhc2VJZGVudGlmaWVyczogdGhpcy5kYXRhYmFzZUlkZW50aWZpZXJzLCBuYW1lOiBcIkRhdGFiYXNlIG1pZ3JhdG9yOiBtaWdyYXRlIGZpbGVzXCJ9LCBhc3luYyAoKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IG1pZ3JhdGlvbiBvZiBmaWxlcykge1xuICAgICAgICBjb25zdCBhcHBsaWVkID0gYXdhaXQgdGhpcy5ydW5NaWdyYXRpb25GaWxlKHtcbiAgICAgICAgICBtaWdyYXRpb24sXG4gICAgICAgICAgcmVxdWlyZU1pZ3JhdGlvbjogYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgaWYgKCFtaWdyYXRpb24uZnVsbFBhdGgpIHRocm93IG5ldyBFcnJvcihgTWlncmF0aW9uIGRpZG4ndCBoYXZlIGEgZnVsbFBhdGgga2V5OiAke09iamVjdC5rZXlzKG1pZ3JhdGlvbikuam9pbihcIiwgXCIpfWApXG5cbiAgICAgICAgICAgIGNvbnN0IG1pZ3JhdGlvbkltcG9ydCA9IGF3YWl0IGltcG9ydENhbGxiYWNrKG1pZ3JhdGlvbi5mdWxsUGF0aClcblxuICAgICAgICAgICAgaWYgKCFtaWdyYXRpb25JbXBvcnQpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBNaWdyYXRpb24gZmlsZSBtdXN0IGV4cG9ydCBtaWdyYXRpb24gY2xhc3M6ICR7bWlncmF0aW9uLmZ1bGxQYXRofWApXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBtaWdyYXRpb25JbXBvcnRcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG5cbiAgICAgICAgaWYgKGFwcGxpZWQpIGFwcGxpZWRDb3VudCsrXG4gICAgICB9XG5cbiAgICAgIGF3YWl0IHRoaXMuX2FmdGVyTWlncmF0aW9ucygpXG4gICAgfSlcblxuICAgIHJldHVybiBhcHBsaWVkQ291bnRcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIG1pZ3JhdGUgZmlsZXMgZnJvbSByZXF1aXJlIGNvbnRleHQuXG4gICAqXG4gICAqIEFwcGxpY2F0aW9uIG1pZ3JhdGlvbnMgYmVsb25nIHRvIHRoZSBzY2hlbWEtb3duaW5nIGxpZmVjeWNsZTsgc2VlXG4gICAqIHtAbGluayBWZWxvY2lvdXNEYXRhYmFzZU1pZ3JhdG9yI19za2lwQXBwbGljYXRpb25NaWdyYXRpb25zSW5Xb3JrZXJMaWZlY3ljbGV9LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vbWlncmF0b3IvdHlwZXMuanNcIikuUmVxdWlyZU1pZ3JhdGlvbkNvbnRleHRUeXBlfSByZXF1aXJlQ29udGV4dCAtIFJlcXVpcmUgY29udGV4dC5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIG1pZ3JhdGVGaWxlc0Zyb21SZXF1aXJlQ29udGV4dChyZXF1aXJlQ29udGV4dCkge1xuICAgIGlmIChhd2FpdCB0aGlzLl9za2lwQXBwbGljYXRpb25NaWdyYXRpb25zSW5Xb3JrZXJMaWZlY3ljbGUoKSkgcmV0dXJuXG5cbiAgICBjb25zdCBmaWxlcyA9IHRoaXMubWlncmF0aW9uc0Zyb21SZXF1aXJlQ29udGV4dChyZXF1aXJlQ29udGV4dClcblxuICAgIGF3YWl0IHRoaXMuY29uZmlndXJhdGlvbi5lbnN1cmVDb25uZWN0aW9ucyh7ZGF0YWJhc2VJZGVudGlmaWVyczogdGhpcy5kYXRhYmFzZUlkZW50aWZpZXJzLCBuYW1lOiBcIkRhdGFiYXNlIG1pZ3JhdG9yOiBtaWdyYXRlIHJlcXVpcmUtY29udGV4dCBmaWxlc1wifSwgYXN5bmMgKCkgPT4ge1xuICAgICAgZm9yIChjb25zdCBtaWdyYXRpb24gb2YgZmlsZXMpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5ydW5NaWdyYXRpb25GaWxlKHtcbiAgICAgICAgICBtaWdyYXRpb24sXG4gICAgICAgICAgcmVxdWlyZU1pZ3JhdGlvbjogYXN5bmMgKCkgPT4gcmVxdWlyZUNvbnRleHQobWlncmF0aW9uLmZpbGUpLmRlZmF1bHRcbiAgICAgICAgfSlcbiAgICAgIH1cblxuICAgICAgYXdhaXQgdGhpcy5fYWZ0ZXJNaWdyYXRpb25zKClcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIE1pZ3JhdGVzIGV4YWN0bHkgb25lIGFscmVhZHktY2FwdHVyZWQgcGh5c2ljYWwgZGF0YWJhc2UuIFRoaXMgaXMgdGhlXG4gICAqIGZyb250ZW5kL3RlbmFudCBjb3VudGVycGFydCB0byB0aGUgYW1iaWVudCBtdWx0aS1kYXRhYmFzZSBlbnRyeXBvaW50czpcbiAgICogY2FsbGVycyBvd24gdGhlIGNhcHR1cmVkIGNvbm5lY3Rpb24gYW5kIG5vIGNvbmZpZ3VyYXRpb24gZmFsbGJhY2sgaXMgcmVhZC5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBDYXB0dXJlZCBtaWdyYXRpb24gYXJndW1lbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2NvbmZpZ3VyYXRpb24tdHlwZXMuanNcIikuRGF0YWJhc2VDb25maWd1cmF0aW9uVHlwZX0gYXJncy5kYXRhYmFzZUNvbmZpZ3VyYXRpb24gLSBDYXB0dXJlZCBwaHlzaWNhbCBkYXRhYmFzZSBjb25maWd1cmF0aW9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5kYXRhYmFzZUlkZW50aWZpZXIgLSBMb2dpY2FsIGRhdGFiYXNlIGlkZW50aWZpZXIuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gYXJncy5kYiAtIENhcHR1cmVkIHBoeXNpY2FsIGNvbm5lY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9taWdyYXRvci90eXBlcy5qc1wiKS5SZXF1aXJlTWlncmF0aW9uQ29udGV4dFR5cGV9IGFyZ3MucmVxdWlyZUNvbnRleHQgLSBGcm9udGVuZCBtaWdyYXRpb24gcmVxdWlyZSBjb250ZXh0LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxudW1iZXI+fSAtIE51bWJlciBvZiBuZXdseSBhcHBsaWVkIG1pZ3JhdGlvbnMuXG4gICAqL1xuICBhc3luYyBtaWdyYXRlUmVxdWlyZUNvbnRleHRGb3JEYXRhYmFzZSh7ZGF0YWJhc2VDb25maWd1cmF0aW9uLCBkYXRhYmFzZUlkZW50aWZpZXIsIGRiLCByZXF1aXJlQ29udGV4dH0pIHtcbiAgICBpZiAoIWRhdGFiYXNlQ29uZmlndXJhdGlvbi5taWdyYXRpb25zKSByZXR1cm4gMFxuXG4gICAgYXdhaXQgTWlncmF0aW9uc0xlZGdlci5lbnN1cmVUYWJsZShkYilcbiAgICBjb25zdCBhcHBsaWVkVmVyc2lvbnMgPSBuZXcgU2V0KGF3YWl0IE1pZ3JhdGlvbnNMZWRnZXIuYXBwbGllZFZlcnNpb25zKGRiKSlcbiAgICBjb25zdCBtaWdyYXRpb25zID0gdGhpcy5taWdyYXRpb25zRnJvbVJlcXVpcmVDb250ZXh0KHJlcXVpcmVDb250ZXh0KVxuICAgIGxldCBhcHBsaWVkQ291bnQgPSAwXG5cbiAgICBmb3IgKGNvbnN0IG1pZ3JhdGlvbiBvZiBtaWdyYXRpb25zKSB7XG4gICAgICBjb25zdCB2ZXJzaW9uID0gYCR7bWlncmF0aW9uLmRhdGV9YFxuXG4gICAgICBpZiAoYXBwbGllZFZlcnNpb25zLmhhcyh2ZXJzaW9uKSkgY29udGludWVcblxuICAgICAgY29uc3QgTWlncmF0aW9uQ2xhc3MgPSByZXF1aXJlQ29udGV4dChtaWdyYXRpb24uZmlsZSkuZGVmYXVsdFxuXG4gICAgICBpZiAoIU1pZ3JhdGlvbkNsYXNzIHx8IHR5cGVvZiBNaWdyYXRpb25DbGFzcyAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTWlncmF0aW9uICR7bWlncmF0aW9uLmZpbGV9IG11c3QgZXhwb3J0IGEgZGVmYXVsdCBtaWdyYXRpb24gY2xhc3MuIFR5cGU6ICR7dHlwZW9mIE1pZ3JhdGlvbkNsYXNzfWApXG4gICAgICB9XG4gICAgICBpZiAoIW1pZ3JhdGlvblJ1bnNJbkV4ZWN1dGlvblBoYXNlKE1pZ3JhdGlvbkNsYXNzLCB0aGlzLmV4ZWN1dGlvblBoYXNlKSkgY29udGludWVcbiAgICAgIGlmICghKE1pZ3JhdGlvbkNsYXNzLmdldERhdGFiYXNlSWRlbnRpZmllcnMoKSB8fCBbXCJkZWZhdWx0XCJdKS5pbmNsdWRlcyhkYXRhYmFzZUlkZW50aWZpZXIpKSBjb250aW51ZVxuXG4gICAgICBjb25zdCBtaWdyYXRpb25JbnN0YW5jZSA9IG5ldyBNaWdyYXRpb25DbGFzcyh7Y29uZmlndXJhdGlvbjogdGhpcy5jb25maWd1cmF0aW9uLCBkYXRhYmFzZUlkZW50aWZpZXIsIGRifSlcblxuICAgICAgYXdhaXQgdGhpcy5ydW5NaWdyYXRpb25VcCh7bWlncmF0aW9uLCBtaWdyYXRpb25JbnN0YW5jZX0pXG4gICAgICBhd2FpdCBNaWdyYXRpb25zTGVkZ2VyLnJlY29yZFZlcnNpb24oZGIsIHZlcnNpb24pXG4gICAgICBhcHBsaWVkVmVyc2lvbnMuYWRkKHZlcnNpb24pXG4gICAgICBhcHBsaWVkQ291bnQrK1xuICAgIH1cblxuICAgIHJldHVybiBhcHBsaWVkQ291bnRcbiAgfVxuXG4gIC8qKlxuICAgKiBQYXJzZXMgYW5kIG9yZGVycyBtaWdyYXRpb25zIGZyb20gYSBicm93c2VyL25hdGl2ZSByZXF1aXJlIGNvbnRleHQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9taWdyYXRvci90eXBlcy5qc1wiKS5SZXF1aXJlTWlncmF0aW9uQ29udGV4dFR5cGV9IHJlcXVpcmVDb250ZXh0IC0gTWlncmF0aW9uIHJlcXVpcmUgY29udGV4dC5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4vbWlncmF0b3IvdHlwZXMuanNcIikuTWlncmF0aW9uT2JqZWN0VHlwZVtdfSAtIE9yZGVyZWQgbWlncmF0aW9ucy5cbiAgICovXG4gIG1pZ3JhdGlvbnNGcm9tUmVxdWlyZUNvbnRleHQocmVxdWlyZUNvbnRleHQpIHtcbiAgICBjb25zdCBtaWdyYXRpb25zID0gW11cblxuICAgIGZvciAoY29uc3QgZmlsZSBvZiByZXF1aXJlQ29udGV4dC5rZXlzKCkpIHtcbiAgICAgIGNvbnN0IG1hdGNoID0gZmlsZS5tYXRjaCgvKFxcZHsxMywxNH0pLSguKylcXC5qcyQvKVxuXG4gICAgICBpZiAoIW1hdGNoKSBjb250aW51ZVxuXG4gICAgICBsZXQgZmlsZU5hbWUgPSBmaWxlXG4gICAgICBsZXQgZGF0ZU51bWJlciA9IG1hdGNoWzFdXG5cbiAgICAgIGlmIChkYXRlTnVtYmVyLmxlbmd0aCA9PSAxMykge1xuICAgICAgICBkYXRlTnVtYmVyID0gYDIke2RhdGVOdW1iZXJ9YFxuICAgICAgICBmaWxlTmFtZSA9IGAyJHtmaWxlTmFtZX1gXG4gICAgICB9XG5cbiAgICAgIG1pZ3JhdGlvbnMucHVzaCh7XG4gICAgICAgIGRhdGU6IHBhcnNlSW50KGRhdGVOdW1iZXIpLFxuICAgICAgICBmaWxlOiBmaWxlTmFtZSxcbiAgICAgICAgbWlncmF0aW9uQ2xhc3NOYW1lOiBpbmZsZWN0aW9uLmNhbWVsaXplKG1hdGNoWzJdLnJlcGxhY2VBbGwoXCItXCIsIFwiX1wiKSlcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgcmV0dXJuIG1pZ3JhdGlvbnMuc29ydCgobWlncmF0aW9uMSwgbWlncmF0aW9uMikgPT4gbWlncmF0aW9uMS5kYXRlIC0gbWlncmF0aW9uMi5kYXRlKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgb25lIG1pZ3JhdGlvbidzIHVwd2FyZCBpbXBsZW1lbnRhdGlvbi5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBNaWdyYXRpb24gYXJndW1lbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vbWlncmF0b3IvdHlwZXMuanNcIikuTWlncmF0aW9uT2JqZWN0VHlwZX0gYXJncy5taWdyYXRpb24gLSBNaWdyYXRpb24gZGVzY3JpcHRvci5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL21pZ3JhdGlvbi9pbmRleC5qc1wiKS5kZWZhdWx0fSBhcmdzLm1pZ3JhdGlvbkluc3RhbmNlIC0gTWlncmF0aW9uIGluc3RhbmNlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyBhZnRlciB0aGUgbWlncmF0aW9uIHN1Y2NlZWRzLlxuICAgKi9cbiAgYXN5bmMgcnVuTWlncmF0aW9uVXAoe21pZ3JhdGlvbiwgbWlncmF0aW9uSW5zdGFuY2V9KSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IG1pZ3JhdGlvbkluc3RhbmNlLmNoYW5nZSgpXG4gICAgfSBjYXRjaCAoY2hhbmdlRXJyb3IpIHtcbiAgICAgIGlmICghKGNoYW5nZUVycm9yIGluc3RhbmNlb2YgTm90SW1wbGVtZW50ZWRFcnJvcikpIHRocm93IGNoYW5nZUVycm9yXG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IG1pZ3JhdGlvbkluc3RhbmNlLnVwKClcbiAgICAgIH0gY2F0Y2ggKHVwRXJyb3IpIHtcbiAgICAgICAgaWYgKHVwRXJyb3IgaW5zdGFuY2VvZiBOb3RJbXBsZW1lbnRlZEVycm9yKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAnY2hhbmdlJyBvciAndXAnIGRpZG4ndCBleGlzdCBvbiBtaWdyYXRpb246ICR7bWlncmF0aW9uLmZpbGV9YCwge2NhdXNlOiB1cEVycm9yfSlcbiAgICAgICAgfVxuXG4gICAgICAgIHRocm93IHVwRXJyb3JcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBhZnRlciBtaWdyYXRpb25zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgX2FmdGVyTWlncmF0aW9ucygpIHtcbiAgICBjb25zdCBlbnZpcm9ubWVudEhhbmRsZXIgPSB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0RW52aXJvbm1lbnRIYW5kbGVyKClcbiAgICBjb25zdCBkYnMgPSBhd2FpdCB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0Q3VycmVudENvbm5lY3Rpb25zKClcbiAgICBjb25zdCBmaWx0ZXJlZERicyA9IE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgIE9iamVjdC5lbnRyaWVzKGRicykuZmlsdGVyKChbZGJJZGVudGlmaWVyXSkgPT4ge1xuICAgICAgICBpZiAoIXRoaXMuaGFuZGxlc0RhdGFiYXNlSWRlbnRpZmllcihkYklkZW50aWZpZXIpKSByZXR1cm4gZmFsc2VcblxuICAgICAgICByZXR1cm4gQm9vbGVhbih0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0RGF0YWJhc2VJZGVudGlmaWVyKGRiSWRlbnRpZmllcikubWlncmF0aW9ucylcbiAgICAgIH0pXG4gICAgKVxuXG4gICAgaWYgKCFlbnZpcm9ubWVudEhhbmRsZXIgfHwgT2JqZWN0LmtleXMoZmlsdGVyZWREYnMpLmxlbmd0aCA9PSAwKSByZXR1cm5cblxuICAgIC8vIFNlcmlhbGlzZSB0aGUgZnJhbWV3b3JrLXNjaGVtYSBib290c3RyYXAgYWNyb3NzIHByb2Nlc3Nlcy4gVGhpcyBjcmVhdGVzIHRoZSBhdHRhY2htZW50c1xuICAgIC8vIGFuZCBiYWNrZ3JvdW5kLWpvYnMgdGFibGVzLCBhbmQgaXQgcnVucyBvbmNlIHBlciBwcm9jZXNzIG91dHNpZGUgdGhlIHBlci1taWdyYXRpb24gbG9vcDpcbiAgICAvLyB3aXRob3V0IHRoaXMgbG9jaywgdHdvIHByb2Nlc3NlcyBib290c3RyYXBwaW5nIG9uZSBkYXRhYmFzZSByYWNlIG9uIENSRUFURSBUQUJMRSAvXG4gICAgLy8gQ1JFQVRFIElOREVYIGFuZCBvbmUgZGllcyBtaWQtYm9vdCAoZHVwbGljYXRlIG9iamVjdC9pbmRleCkuXG4gICAgZm9yIChjb25zdCBbZGJJZGVudGlmaWVyLCBkYl0gb2YgT2JqZWN0LmVudHJpZXMoZmlsdGVyZWREYnMpKSB7XG4gICAgICBjb25zdCBydW5uZXIgPSBuZXcgQWR2aXNvcnlMb2NrUnVubmVyKHtcbiAgICAgICAgY29uZmlndXJhdGlvbjogdGhpcy5jb25maWd1cmF0aW9uLFxuICAgICAgICBjb25uZWN0aW9uUHJvdmlkZXI6ICgpID0+IGRiLFxuICAgICAgICBkYXRhYmFzZUlkZW50aWZpZXI6IGRiSWRlbnRpZmllclxuICAgICAgfSlcblxuICAgICAgYXdhaXQgcnVubmVyLndpdGhBZHZpc29yeUxvY2soXG4gICAgICAgIG1pZ3JhdGlvbnNBZHZpc29yeUxvY2tOYW1lKGRiSWRlbnRpZmllciksXG4gICAgICAgIGFzeW5jICgpID0+IHtcbiAgICAgICAgICBhd2FpdCBlbnZpcm9ubWVudEhhbmRsZXIuZW5zdXJlRnJhbWV3b3JrU2NoZW1hKHtkYnM6IHtbZGJJZGVudGlmaWVyXTogZGJ9fSlcbiAgICAgICAgfSxcbiAgICAgICAge2RlZGljYXRlZENvbm5lY3Rpb246IHRydWV9XG4gICAgICApXG4gICAgfVxuXG4gICAgLy8gRW5zdXJlIFZlbG9jaW91cycgb3duIGZyYW1ld29yayBzY2hlbWEgYmVmb3JlIHRoZSBzdHJ1Y3R1cmUgZHVtcC4gVGhlIGR1bXAgaXNcbiAgICAvLyBnYXRlZCB0byBlbmFibGVkIGVudmlyb25tZW50cywgYnV0IG1pZ3JhdGlvbi1lbmFibGVkIGRhdGFiYXNlcyBtdXN0IGluY2x1ZGVcbiAgICAvLyBmcmFtZXdvcmsgdGFibGVzIHNvIGBkYjptaWdyYXRlYCBhbmQgc2NoZW1hOmxvYWQgcHJvZHVjZSBhIGNvbXBsZXRlIGRhdGFiYXNlLlxuICAgIGF3YWl0IGVudmlyb25tZW50SGFuZGxlci5hZnRlck1pZ3JhdGlvbnMoe2RiczogZmlsdGVyZWREYnN9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgbG9hZCBtaWdyYXRpb25zIHZlcnNpb25zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgbG9hZE1pZ3JhdGlvbnNWZXJzaW9ucygpIHtcbiAgICB0aGlzLm1pZ3JhdGlvbnNWZXJzaW9ucyA9IHt9XG5cbiAgICBjb25zdCBkYnMgPSBhd2FpdCB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0Q3VycmVudENvbm5lY3Rpb25zKClcblxuICAgIGZvciAoY29uc3QgZGJJZGVudGlmaWVyIGluIGRicykge1xuICAgICAgaWYgKCF0aGlzLmhhbmRsZXNEYXRhYmFzZUlkZW50aWZpZXIoZGJJZGVudGlmaWVyKSkgY29udGludWVcblxuICAgICAgYXdhaXQgdGhpcy5sb2FkTWlncmF0aW9uc1ZlcnNpb25zRm9yRGF0YWJhc2Uoe2RiSWRlbnRpZmllciwgZGI6IGRic1tkYklkZW50aWZpZXJdfSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBsb2FkIG1pZ3JhdGlvbnMgdmVyc2lvbnMgZm9yIGRhdGFiYXNlLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5kYklkZW50aWZpZXIgLSBEYXRhYmFzZSBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGFyZ3MuZGIgLSBEYXRhYmFzZSBjb25uZWN0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgbG9hZE1pZ3JhdGlvbnNWZXJzaW9uc0ZvckRhdGFiYXNlKHtkYklkZW50aWZpZXIsIGRifSkge1xuICAgIGNvbnN0IGRhdGFiYXNlQ29uZmlndXJhdGlvbiA9IHRoaXMuY29uZmlndXJhdGlvbi5nZXREYXRhYmFzZUlkZW50aWZpZXIoZGJJZGVudGlmaWVyKVxuXG4gICAgaWYgKCFkYXRhYmFzZUNvbmZpZ3VyYXRpb24ubWlncmF0aW9ucykge1xuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoYCR7ZGJJZGVudGlmaWVyfSBpc24ndCBjb25maWd1cmVkIGZvciBtaWdyYXRpb25zIC0gc2tpcHBpbmcgbG9hZGluZyBtaWdyYXRpb25zIHZlcnNpb25zIGZvciBpdGApXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAoIWF3YWl0IHRoaXMubWlncmF0aW9uc1RhYmxlRXhpc3QoZGIpKSB7XG4gICAgICB0aGlzLmxvZ2dlci5pbmZvKGBNaWdyYXRpb24gdGFibGUgZG9lcyBub3QgZXhpc3QgZm9yICR7ZGJJZGVudGlmaWVyfSAtIHNraXBwaW5nIGxvYWRpbmcgbWlncmF0aW9ucyB2ZXJzaW9ucyBmb3IgaXRgKVxuICAgICAgZGVsZXRlIHRoaXMubWlncmF0aW9uc1ZlcnNpb25zW2RiSWRlbnRpZmllcl1cbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IHZlcnNpb25zID0gYXdhaXQgTWlncmF0aW9uc0xlZGdlci5hcHBsaWVkVmVyc2lvbnMoZGIpXG5cbiAgICB0aGlzLm1pZ3JhdGlvbnNWZXJzaW9uc1tkYklkZW50aWZpZXJdID0ge31cblxuICAgIGZvciAoY29uc3QgdmVyc2lvbiBvZiB2ZXJzaW9ucykge1xuICAgICAgdGhpcy5taWdyYXRpb25zVmVyc2lvbnNbZGJJZGVudGlmaWVyXVt2ZXJzaW9uXSA9IHRydWVcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBtaWdyYXRpb25zIHRhYmxlIGV4aXN0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGRiIC0gRGF0YWJhc2UgY29ubmVjdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8Ym9vbGVhbj59IC0gUmVzb2x2ZXMgd2l0aCBXaGV0aGVyIG1pZ3JhdGlvbnMgdGFibGUgZXhpc3QuXG4gICAqL1xuICBhc3luYyBtaWdyYXRpb25zVGFibGVFeGlzdChkYikge1xuICAgIHJldHVybiBhd2FpdCBNaWdyYXRpb25zTGVkZ2VyLnRhYmxlRXhpc3RzKGRiKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZXhlY3V0ZSByZXF1aXJlIGNvbnRleHQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9taWdyYXRvci90eXBlcy5qc1wiKS5SZXF1aXJlTWlncmF0aW9uQ29udGV4dFR5cGV9IHJlcXVpcmVDb250ZXh0IC0gUmVxdWlyZSBjb250ZXh0LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgZXhlY3V0ZVJlcXVpcmVDb250ZXh0KHJlcXVpcmVDb250ZXh0KSB7XG4gICAgY29uc3QgbWlncmF0aW9uRmlsZXMgPSByZXF1aXJlQ29udGV4dC5rZXlzKClcblxuICAgIC8qKlxuICAgICAqIEZpbGVzLlxuICAgICAqIEB0eXBlIHtpbXBvcnQoXCIuL21pZ3JhdG9yL3R5cGVzLmpzXCIpLk1pZ3JhdGlvbk9iamVjdFR5cGVbXX0gKi9cbiAgICBsZXQgZmlsZXMgPSBbXVxuXG4gICAgZm9yIChjb25zdCBmaWxlIG9mIG1pZ3JhdGlvbkZpbGVzKSB7XG4gICAgICBjb25zdCBtYXRjaCA9IGZpbGUubWF0Y2goL14oXFxkezE0fSktKC4rKVxcLmpzJC8pXG5cbiAgICAgIGlmICghbWF0Y2gpIGNvbnRpbnVlXG5cbiAgICAgIGNvbnN0IGRhdGUgPSBwYXJzZUludChtYXRjaFsxXSlcbiAgICAgIGNvbnN0IG1pZ3JhdGlvbk5hbWUgPSBtYXRjaFsyXVxuICAgICAgY29uc3QgbWlncmF0aW9uQ2xhc3NOYW1lID0gaW5mbGVjdGlvbi5jYW1lbGl6ZShtaWdyYXRpb25OYW1lKVxuXG4gICAgICBjb25zdCBtaWdyYXRpb25PYmplY3QgPSAvKiogQHR5cGUge2ltcG9ydChcIi4vbWlncmF0b3IvdHlwZXMuanNcIikuTWlncmF0aW9uT2JqZWN0VHlwZX0gKi8gKHtcbiAgICAgICAgZmlsZSxcbiAgICAgICAgZGF0ZSxcbiAgICAgICAgbWlncmF0aW9uQ2xhc3NOYW1lXG4gICAgICB9KVxuXG4gICAgICBmaWxlcy5wdXNoKG1pZ3JhdGlvbk9iamVjdClcbiAgICB9XG5cbiAgICBmaWxlcyA9IGZpbGVzLnNvcnQoKG1pZ3JhdGlvbjEsIG1pZ3JhdGlvbjIpID0+IG1pZ3JhdGlvbjEuZGF0ZSAtIG1pZ3JhdGlvbjIuZGF0ZSlcblxuICAgIGZvciAoY29uc3QgbWlncmF0aW9uIG9mIGZpbGVzKSB7XG4gICAgICBhd2FpdCB0aGlzLnJ1bk1pZ3JhdGlvbkZpbGUoe1xuICAgICAgICBtaWdyYXRpb24sXG4gICAgICAgIHJlcXVpcmVNaWdyYXRpb246IGFzeW5jICgpID0+IHJlcXVpcmVDb250ZXh0KG1pZ3JhdGlvbi5maWxlKS5kZWZhdWx0XG4gICAgICB9KVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHJlc2V0LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgcmVzZXQoKSB7XG4gICAgY29uc3QgZGJzID0gYXdhaXQgdGhpcy5jb25maWd1cmF0aW9uLmdldEN1cnJlbnRDb25uZWN0aW9ucygpXG5cbiAgICBmb3IgKGNvbnN0IGRiSWRlbnRpZmllciBpbiBkYnMpIHtcbiAgICAgIGlmICghdGhpcy5oYW5kbGVzRGF0YWJhc2VJZGVudGlmaWVyKGRiSWRlbnRpZmllcikpIGNvbnRpbnVlXG5cbiAgICAgIGNvbnN0IGRiID0gZGJzW2RiSWRlbnRpZmllcl1cblxuICAgICAgYXdhaXQgZGIud2l0aERpc2FibGVkRm9yZWlnbktleXMoYXN5bmMgKCkgPT4ge1xuICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgIGNvbnN0IGVycm9ycyA9IFtdXG4gICAgICAgICAgbGV0IGFueVRhYmxlRHJvcHBlZCA9IGZhbHNlXG5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgZm9yIChjb25zdCB0YWJsZSBvZiBhd2FpdCBkYi5nZXRUYWJsZXMoKSkge1xuICAgICAgICAgICAgICB0aGlzLmxvZ2dlci5pbmZvKGBEcm9wcGluZyB0YWJsZSAke3RhYmxlLmdldE5hbWUoKX1gKVxuXG4gICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgZGIuZHJvcFRhYmxlKHRhYmxlLmdldE5hbWUoKSwge2Nhc2NhZGU6IHRydWV9KVxuICAgICAgICAgICAgICAgIGFueVRhYmxlRHJvcHBlZCA9IHRydWVcbiAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBlcnJvcnMucHVzaChlcnJvcilcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBicmVha1xuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICAgICAgICAgIGlmIChlcnJvcnMubGVuZ3RoID4gMCAmJiBhbnlUYWJsZURyb3BwZWQpIHtcbiAgICAgICAgICAgICAgLy8gUmV0cnlcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHRocm93IGVycm9yc1swXVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyByb2xsYmFjay5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL21pZ3JhdG9yL3R5cGVzLmpzXCIpLk1pZ3JhdGlvbk9iamVjdFR5cGVbXX0gZmlsZXMgLSBGaWxlcy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL21pZ3JhdG9yL3R5cGVzLmpzXCIpLkltcG9ydEZ1bGxwYXRoQ2FsbGJhY2tUeXBlfSBpbXBvcnRDYWxsYmFjayBGdW5jdGlvbiB0byBpbXBvcnQgYSBmaWxlXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyByb2xsYmFjayhmaWxlcywgaW1wb3J0Q2FsbGJhY2spIHtcbiAgICBjb25zdCBsYXRlc3RNaWdyYXRpb25WZXJzaW9uID0gYXdhaXQgdGhpcy5fbGF0ZXN0TWlncmF0aW9uVmVyc2lvbigpXG5cbiAgICBpZiAoIWxhdGVzdE1pZ3JhdGlvblZlcnNpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIG1pZ3JhdGlvbnMgaGF2ZSBiZWVuIHJ1biB5ZXRcIilcbiAgICB9XG5cbiAgICBjb25zdCBsYXRlc3RNaWdyYXRpb25WZXJzaW9uTnVtYmVyID0gcGFyc2VJbnQobGF0ZXN0TWlncmF0aW9uVmVyc2lvbilcbiAgICBjb25zdCBtaWdyYXRpb24gPSBmaWxlcy5maW5kKChmaWxlKSA9PiBmaWxlLmRhdGUgPT0gbGF0ZXN0TWlncmF0aW9uVmVyc2lvbk51bWJlcilcblxuICAgIGlmICghbWlncmF0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYE1pZ3JhdGlvbiBmaWxlIGZvciB2ZXJzaW9uICR7bGF0ZXN0TWlncmF0aW9uVmVyc2lvbk51bWJlcn0gbm90IGZvdW5kYClcbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLnJ1bk1pZ3JhdGlvbkZpbGUoe1xuICAgICAgbWlncmF0aW9uLFxuICAgICAgcmVxdWlyZU1pZ3JhdGlvbjogYXN5bmMgKCkgPT4ge1xuICAgICAgICBpZiAoIW1pZ3JhdGlvbi5mdWxsUGF0aCkgdGhyb3cgbmV3IEVycm9yKGBNaWdyYXRpb24gZGlkbid0IGhhdmUgYSBmdWxsUGF0aCBrZXk6ICR7T2JqZWN0LmtleXMobWlncmF0aW9uKS5qb2luKFwiLCBcIil9YClcblxuICAgICAgICByZXR1cm4gYXdhaXQgaW1wb3J0Q2FsbGJhY2sobWlncmF0aW9uLmZ1bGxQYXRoKVxuICAgICAgfSxcbiAgICAgIGRpcmVjdGlvbjogXCJkb3duXCJcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgbGF0ZXN0IG1pZ3JhdGlvbiB2ZXJzaW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+fSBUaGUgbGF0ZXN0IG1pZ3JhdGlvbiB2ZXJzaW9uXG4gICAqL1xuICBhc3luYyBfbGF0ZXN0TWlncmF0aW9uVmVyc2lvbigpIHtcbiAgICBpZiAoIXRoaXMubWlncmF0aW9uc1ZlcnNpb25zKSBhd2FpdCB0aGlzLmxvYWRNaWdyYXRpb25zVmVyc2lvbnMoKVxuXG4gICAgLyoqXG4gICAgICogRGVmaW5lcyBoaWdoZXN0VmVyc2lvbi5cbiAgICAgKiBAdHlwZSB7c3RyaW5nIHwgdW5kZWZpbmVkfSAqL1xuICAgIGxldCBoaWdoZXN0VmVyc2lvblxuXG4gICAgZm9yIChjb25zdCBkYklkZW50aWZpZXIgaW4gdGhpcy5taWdyYXRpb25zVmVyc2lvbnMpIHtcbiAgICAgIGZvciAoY29uc3QgbWlncmF0aW9uVmVyc2lvbiBpbiB0aGlzLm1pZ3JhdGlvbnNWZXJzaW9uc1tkYklkZW50aWZpZXJdKSB7XG4gICAgICAgIGlmICghaGlnaGVzdFZlcnNpb24gfHwgbWlncmF0aW9uVmVyc2lvbiA+IGhpZ2hlc3RWZXJzaW9uKSB7XG4gICAgICAgICAgaGlnaGVzdFZlcnNpb24gPSBtaWdyYXRpb25WZXJzaW9uXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gaGlnaGVzdFZlcnNpb25cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHJ1biBtaWdyYXRpb24gZmlsZS5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL21pZ3JhdG9yL3R5cGVzLmpzXCIpLk1pZ3JhdGlvbk9iamVjdFR5cGV9IGFyZ3MubWlncmF0aW9uIC0gTWlncmF0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vbWlncmF0b3IvdHlwZXMuanNcIikuUmVxdWlyZU1pZ3JhdGlvblR5cGV9IGFyZ3MucmVxdWlyZU1pZ3JhdGlvbiAtIFJlcXVpcmUgbWlncmF0aW9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2FyZ3MuZGlyZWN0aW9uXSAtIERpcmVjdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8Ym9vbGVhbj59IC0gV2hldGhlciB0aGUgbWlncmF0aW9uIHJhbiBvbiBhdCBsZWFzdCBvbmUgZGF0YWJhc2UgKGZhbHNlIGlmIHNraXBwZWQgYXMgYWxyZWFkeS1ydW4gZXZlcnl3aGVyZSkuXG4gICAqL1xuICBhc3luYyBydW5NaWdyYXRpb25GaWxlKHttaWdyYXRpb24sIHJlcXVpcmVNaWdyYXRpb24sIGRpcmVjdGlvbiA9IFwidXBcIn0pIHtcbiAgICBpZiAoIXRoaXMuY29uZmlndXJhdGlvbikgdGhyb3cgbmV3IEVycm9yKFwiTm8gY29uZmlndXJhdGlvbiBzZXRcIilcbiAgICBjb25zb2xlLmVycm9yKFwiW01JRy1ERUJVR10gcnVuTWlncmF0aW9uRmlsZSBmaWxlPVwiICsgKG1pZ3JhdGlvbiAmJiBtaWdyYXRpb24uZmlsZSkpXG4gICAgaWYgKCF0aGlzLmNvbmZpZ3VyYXRpb24uaXNEYXRhYmFzZVBvb2xJbml0aWFsaXplZCgpKSBhd2FpdCB0aGlzLmNvbmZpZ3VyYXRpb24uaW5pdGlhbGl6ZURhdGFiYXNlUG9vbCgpXG4gICAgaWYgKCF0aGlzLm1pZ3JhdGlvbnNWZXJzaW9ucykgYXdhaXQgdGhpcy5sb2FkTWlncmF0aW9uc1ZlcnNpb25zKClcblxuICAgIGxldCBhcHBsaWVkID0gZmFsc2VcbiAgICBjb25zdCBkYnMgPSBhd2FpdCB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0Q3VycmVudENvbm5lY3Rpb25zKClcblxuICAgIC8qKlxuICAgICAqIERiIGlkZW50aWZpZXJzIG5lZWRpbmcgbWlncmF0aW9uIHZlcnNpb25zLlxuICAgICAqIEB0eXBlIHtzdHJpbmdbXX0gKi9cbiAgICBjb25zdCBkYklkZW50aWZpZXJzTmVlZGluZ01pZ3JhdGlvblZlcnNpb25zID0gW11cblxuICAgIC8vIG1pZ3JhdGVGaWxlcygpIHdyYXBzIGV4ZWN1dGlvbiBpbiBlbnN1cmVDb25uZWN0aW9ucygpLCBzbyB0aGUgY3VycmVudFxuICAgIC8vIGFzeW5jIGNvbnRleHQgY2FuIGV4cG9zZSBEQiBpZGVudGlmaWVycyBub3QgbG9hZGVkIGJ5IHByZXBhcmUoKS5cbiAgICBmb3IgKGNvbnN0IGRiSWRlbnRpZmllciBpbiBkYnMpIHtcbiAgICAgIGlmICghdGhpcy5oYW5kbGVzRGF0YWJhc2VJZGVudGlmaWVyKGRiSWRlbnRpZmllcikpIGNvbnRpbnVlXG5cbiAgICAgIGNvbnN0IGRhdGFiYXNlQ29uZmlndXJhdGlvbiA9IHRoaXMuY29uZmlndXJhdGlvbi5nZXREYXRhYmFzZUlkZW50aWZpZXIoZGJJZGVudGlmaWVyKVxuXG4gICAgICBpZiAoIWRhdGFiYXNlQ29uZmlndXJhdGlvbi5taWdyYXRpb25zKSBjb250aW51ZVxuICAgICAgaWYgKHRoaXMubWlncmF0aW9uc1ZlcnNpb25zW2RiSWRlbnRpZmllcl0pIGNvbnRpbnVlXG5cbiAgICAgIGRiSWRlbnRpZmllcnNOZWVkaW5nTWlncmF0aW9uVmVyc2lvbnMucHVzaChkYklkZW50aWZpZXIpXG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBkYklkZW50aWZpZXIgb2YgZGJJZGVudGlmaWVyc05lZWRpbmdNaWdyYXRpb25WZXJzaW9ucykge1xuICAgICAgY29uc3QgZGIgPSBkYnNbZGJJZGVudGlmaWVyXVxuXG4gICAgICBhd2FpdCB0aGlzLmNyZWF0ZU1pZ3JhdGlvbnNUYWJsZUZvckRhdGFiYXNlKHtkYklkZW50aWZpZXIsIGRifSlcbiAgICAgIGF3YWl0IHRoaXMubG9hZE1pZ3JhdGlvbnNWZXJzaW9uc0ZvckRhdGFiYXNlKHtkYklkZW50aWZpZXIsIGRifSlcbiAgICB9XG5cbiAgICBjb25zdCBtaWdyYXRpb25DbGFzcyA9IGF3YWl0IHJlcXVpcmVNaWdyYXRpb24oKVxuXG4gICAgaWYgKCFtaWdyYXRpb25DbGFzcyB8fCB0eXBlb2YgbWlncmF0aW9uQ2xhc3MgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBNaWdyYXRpb24gJHttaWdyYXRpb24uZmlsZX0gbXVzdCBleHBvcnQgYSBkZWZhdWx0IG1pZ3JhdGlvbiBjbGFzcy4gVHlwZTogJHt0eXBlb2YgbWlncmF0aW9uQ2xhc3N9YClcbiAgICB9XG4gICAgaWYgKGRpcmVjdGlvbiA9PSBcInVwXCIgJiYgIW1pZ3JhdGlvblJ1bnNJbkV4ZWN1dGlvblBoYXNlKG1pZ3JhdGlvbkNsYXNzLCB0aGlzLmV4ZWN1dGlvblBoYXNlKSkgcmV0dXJuIGZhbHNlXG5cbiAgICBjb25zdCBtaWdyYXRpb25EYXRhYmFzZUlkZW50aWZpZXJzID0gbWlncmF0aW9uQ2xhc3MuZ2V0RGF0YWJhc2VJZGVudGlmaWVycygpIHx8IFtcImRlZmF1bHRcIl1cblxuICAgIGZvciAoY29uc3QgZGJJZGVudGlmaWVyIGluIGRicykge1xuICAgICAgaWYgKCF0aGlzLmhhbmRsZXNEYXRhYmFzZUlkZW50aWZpZXIoZGJJZGVudGlmaWVyKSkgY29udGludWVcblxuICAgICAgY29uc3QgZGF0YWJhc2VDb25maWd1cmF0aW9uID0gdGhpcy5jb25maWd1cmF0aW9uLmdldERhdGFiYXNlSWRlbnRpZmllcihkYklkZW50aWZpZXIpXG5cbiAgICAgIGlmICghZGF0YWJhc2VDb25maWd1cmF0aW9uLm1pZ3JhdGlvbnMpIHtcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoYCR7ZGJJZGVudGlmaWVyfSBpc24ndCBjb25maWd1cmVkIGZvciBtaWdyYXRpb25zIC0gc2tpcHBpbmcgbWlncmF0aW9uICR7ZGlnZyhtaWdyYXRpb24sIFwiZGF0ZVwiKX1gKVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBpZiAoIW1pZ3JhdGlvbkRhdGFiYXNlSWRlbnRpZmllcnMuaW5jbHVkZXMoZGJJZGVudGlmaWVyKSkge1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgJHtkYklkZW50aWZpZXJ9IHNob3VsZG4ndCBydW4gbWlncmF0aW9uICR7bWlncmF0aW9uLmZpbGV9YCwge21pZ3JhdGlvbkRhdGFiYXNlSWRlbnRpZmllcnN9KVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBjb25zdCBkYiA9IGRic1tkYklkZW50aWZpZXJdXG4gICAgICBjb25zdCBkYXRlU3RyaW5nID0gYCR7ZGlnZyhtaWdyYXRpb24sIFwiZGF0ZVwiKX1gXG5cbiAgICAgIC8vIFNlcmlhbGlzZSB0aGUgY2hlY2stdGhlbi1hcHBseSBhY3Jvc3MgcHJvY2Vzc2VzLiBXaXRob3V0IHRoaXMsIHR3byBzaGFyZHMgY2FuIGJvdGhcbiAgICAgIC8vIG9ic2VydmUgdGhlIG1pZ3JhdGlvbiBhcyB1bmFwcGxpZWQgYW5kIGJvdGggZXhlY3V0ZSBpdHMgRERMOyB0aGUgbG9zZXIgZGllcyB3aXRoIHRoZVxuICAgICAgLy8gZHJpdmVyJ3MgZHVwbGljYXRlLW9iamVjdCBlcnJvciBtaWQtYm9vdC5cbiAgICAgIC8vXG4gICAgICAvLyBUaGUgdmVyc2lvbiBpcyByZS1yZWFkICppbnNpZGUqIHRoZSBsb2NrOiB3aGlsZSB0aGlzIHByb2Nlc3Mgd2FpdGVkLCBhbm90aGVyIHByb2Nlc3NcbiAgICAgIC8vIG1heSBhbHJlYWR5IGhhdmUgYXBwbGllZCB0aGUgbWlncmF0aW9uLCBpbiB3aGljaCBjYXNlIHRoaXMgb25lIG11c3QgYmVjb21lIGEgbm8tb3AuXG4gICAgICBjb25zb2xlLmVycm9yKFwiW01JRy1ERUJVR10gYWNxdWlyaW5nIGxvY2sgZGI9XCIgKyBkYklkZW50aWZpZXIgKyBcIiBmaWxlPVwiICsgbWlncmF0aW9uLmZpbGUpXG4gICAgICBjb25zdCBydW5uZXIgPSBuZXcgQWR2aXNvcnlMb2NrUnVubmVyKHtcbiAgICAgICAgY29uZmlndXJhdGlvbjogdGhpcy5jb25maWd1cmF0aW9uLFxuICAgICAgICBjb25uZWN0aW9uUHJvdmlkZXI6ICgpID0+IGRiLFxuICAgICAgICBkYXRhYmFzZUlkZW50aWZpZXI6IGRiSWRlbnRpZmllclxuICAgICAgfSlcblxuICAgICAgY29uc3QgYXBwbGllZEluTG9jayA9IGF3YWl0IHJ1bm5lci53aXRoQWR2aXNvcnlMb2NrKFxuICAgICAgICBtaWdyYXRpb25zQWR2aXNvcnlMb2NrTmFtZShkYklkZW50aWZpZXIpLFxuICAgICAgICBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgLy8gUmUtcmVhZCB0aGUgYXBwbGllZCBzZXQgZnJvbSB0aGUgZGF0YWJhc2Ugd2hpbGUgaG9sZGluZyB0aGUgbG9jay4gVGhlIHZlcnNpb25cbiAgICAgICAgICAvLyBsaXN0IHdhcyBsb2FkZWQgZHVyaW5nIHByZXBhcmUoKSwgYmVmb3JlIGFueSBvdGhlciBwcm9jZXNzIG1heSBoYXZlIGZpbmlzaGVkXG4gICAgICAgICAgLy8gYXBwbHlpbmcgbWlncmF0aW9ucywgc28gdHJ1c3RpbmcgdGhhdCBjYWNoZWQgc25hcHNob3QgaGVyZSB3b3VsZCBsZXQgdGhpc1xuICAgICAgICAgIC8vIHByb2Nlc3MgcmUtcnVuIERETCB0aGF0IGFub3RoZXIgcHJvY2VzcyBoYXMgYWxyZWFkeSBjb21taXR0ZWQuXG4gICAgICAgICAgYXdhaXQgdGhpcy5sb2FkTWlncmF0aW9uc1ZlcnNpb25zRm9yRGF0YWJhc2Uoe2RiSWRlbnRpZmllciwgZGJ9KVxuXG4gICAgICAgICAgaWYgKGRpcmVjdGlvbiA9PSBcInVwXCIpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmhhc1J1bk1pZ3JhdGlvblZlcnNpb24oZGJJZGVudGlmaWVyLCBtaWdyYXRpb24uZGF0ZSkpIHtcbiAgICAgICAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoYCR7ZGJJZGVudGlmaWVyfSBoYXMgYWxyZWFkeSBydW4gbWlncmF0aW9uICR7bWlncmF0aW9uLmZpbGV9YClcbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmIChkaXJlY3Rpb24gPT0gXCJkb3duXCIpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5oYXNSdW5NaWdyYXRpb25WZXJzaW9uKGRiSWRlbnRpZmllciwgbWlncmF0aW9uLmRhdGUpKSB7XG4gICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGAke2RiSWRlbnRpZmllcn0gaGFzbid0IHJ1biBtaWdyYXRpb24gJHttaWdyYXRpb24uZmlsZX1gKVxuICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGRpcmVjdGlvbjogJHtkaXJlY3Rpb259YClcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgUnVubmluZyBtaWdyYXRpb24gb24gJHtkYklkZW50aWZpZXJ9OiAke21pZ3JhdGlvbi5maWxlfWAsIHttaWdyYXRpb25EYXRhYmFzZUlkZW50aWZpZXJzfSlcblxuICAgICAgICAgIGNvbnN0IE1pZ3JhdGlvbkNsYXNzID0gbWlncmF0aW9uQ2xhc3NcbiAgICAgICAgICBjb25zdCBtaWdyYXRpb25JbnN0YW5jZSA9IG5ldyBNaWdyYXRpb25DbGFzcyh7XG4gICAgICAgICAgICBjb25maWd1cmF0aW9uOiB0aGlzLmNvbmZpZ3VyYXRpb24sXG4gICAgICAgICAgICBkYXRhYmFzZUlkZW50aWZpZXI6IGRiSWRlbnRpZmllcixcbiAgICAgICAgICAgIGRiXG4gICAgICAgICAgfSlcblxuICAgICAgICAgIGlmIChkaXJlY3Rpb24gPT0gXCJ1cFwiKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBhd2FpdCBtaWdyYXRpb25JbnN0YW5jZS5jaGFuZ2UoKVxuICAgICAgICAgICAgfSBjYXRjaCAoY2hhbmdlRXJyb3IpIHtcbiAgICAgICAgICAgICAgaWYgKGNoYW5nZUVycm9yIGluc3RhbmNlb2YgTm90SW1wbGVtZW50ZWRFcnJvcikge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICBhd2FpdCBtaWdyYXRpb25JbnN0YW5jZS51cCgpXG4gICAgICAgICAgICAgICAgfSBjYXRjaCAodXBFcnJvcikge1xuICAgICAgICAgICAgICAgICAgaWYgKHVwRXJyb3IgaW5zdGFuY2VvZiBOb3RJbXBsZW1lbnRlZEVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJ2NoYW5nZScgb3IgJ3VwJyBkaWRuJ3QgZXhpc3Qgb24gbWlncmF0aW9uOiAke21pZ3JhdGlvbi5maWxlfWAsIHtjYXVzZTogdXBFcnJvcn0pXG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyB1cEVycm9yXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IGNoYW5nZUVycm9yXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgYXdhaXQgTWlncmF0aW9uc0xlZGdlci5yZWNvcmRWZXJzaW9uKGRiLCBkYXRlU3RyaW5nKVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBhd2FpdCBtaWdyYXRpb25JbnN0YW5jZS5kb3duKClcbiAgICAgICAgICAgIH0gY2F0Y2ggKGRvd25FcnJvcikge1xuICAgICAgICAgICAgICBpZiAoZG93bkVycm9yIGluc3RhbmNlb2YgTm90SW1wbGVtZW50ZWRFcnJvcikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJ2Rvd24nIGRpZG4ndCBleGlzdCBvbiBtaWdyYXRpb246ICR7bWlncmF0aW9uLmZpbGV9IG9yIG1pZ3JhdGluZyBkb3duIHdpdGggYSBjaGFuZ2UgbWV0aG9kIGlzbid0IGN1cnJlbnRseSBzdXBwb3J0ZWRgLCB7Y2F1c2U6IGRvd25FcnJvcn0pXG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgZG93bkVycm9yXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgYXdhaXQgTWlncmF0aW9uc0xlZGdlci5yZW1vdmVWZXJzaW9uKGRiLCBkYXRlU3RyaW5nKVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH0sXG4gICAgICAgIC8vIFBpbiB0aGUgbG9jayB0byBvbmUgcGh5c2ljYWwgc2Vzc2lvbjogTVNTUUwvZXhwbGljaXQgYWR2aXNvcnkgbG9ja3MgYXJlXG4gICAgICAgIC8vIHNlc3Npb24tc2NvcGVkLCBhbmQgYSBwb29sZWQgY29ubmVjdGlvbiBjYW4gcm91dGUgYWNxdWlyZSBhbmQgcmVsZWFzZSB0b1xuICAgICAgICAvLyBkaWZmZXJlbnQgc2Vzc2lvbnMsIHdoaWNoIHdvdWxkIGxldCB0d28gcHJvY2Vzc2VzIGJvdGggXCJob2xkXCIgdGhlIGxvY2suXG4gICAgICAgIHtkZWRpY2F0ZWRDb25uZWN0aW9uOiB0cnVlfVxuICAgICAgKVxuXG4gICAgICBpZiAoIWFwcGxpZWRJbkxvY2spIGNvbnRpbnVlXG5cbiAgICAgIGFwcGxpZWQgPSB0cnVlXG4gICAgfVxuXG4gICAgcmV0dXJuIGFwcGxpZWRcbiAgfVxufVxuIl19
|
|
620
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlncmF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZGF0YWJhc2UvbWlncmF0b3IuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sRUFBQyxJQUFJLEVBQUMsTUFBTSxXQUFXLENBQUE7QUFDOUIsT0FBTyxLQUFLLFVBQVUsTUFBTSxZQUFZLENBQUE7QUFDeEMsT0FBTyxNQUFNLE1BQU0sY0FBYyxDQUFBO0FBQ2pDLE9BQU8sZ0JBQWdCLE1BQU0sd0JBQXdCLENBQUE7QUFDckQsT0FBTyxrQkFBa0IsTUFBTSwyQkFBMkIsQ0FBQTtBQUMxRCxPQUFPLEVBQUMsbUJBQW1CLEVBQUMsTUFBTSxzQkFBc0IsQ0FBQTtBQUN4RCxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQTtBQUN2RyxPQUFPLGFBQWEsTUFBTSw2QkFBNkIsQ0FBQTtBQUV2RDs7Ozs7Ozs7R0FRRztBQUNILFNBQVMsMEJBQTBCLENBQUMsWUFBWTtJQUM5QyxPQUFPLHdCQUF3QixZQUFZLEVBQUUsQ0FBQTtBQUMvQyxDQUFDO0FBRUQsTUFBTSxDQUFDLE9BQU8sT0FBTyx5QkFBeUI7SUFDNUM7O3lEQUVxRDtJQUNyRCxrQkFBa0IsR0FBRyxFQUFFLENBQUE7SUFFdkI7Ozs7OztPQU1HO0lBQ0gsWUFBWSxFQUFDLGFBQWEsRUFBRSxtQkFBbUIsRUFBRSxjQUFjLEVBQUUsR0FBRyxRQUFRLEVBQUM7UUFDM0UsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFBO1FBRXZCLElBQUksQ0FBQyxhQUFhO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxvQ0FBb0MsQ0FBQyxDQUFBO1FBRXpFLElBQUksQ0FBQyxhQUFhLEdBQUcsYUFBYSxDQUFBO1FBQ2xDLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxtQkFBbUIsQ0FBQTtRQUM5QyxJQUFJLENBQUMsY0FBYyxHQUFHLGNBQWMsS0FBSyxTQUFTLENBQUMs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LEVBQUMsQ0FBQyxDQUFBO2dDQUNwRyxDQUFDO3FDQUFNLENBQUM7b0NBQ04sTUFBTSxPQUFPLENBQUE7Z0NBQ2YsQ0FBQzs0QkFDSCxDQUFDO3dCQUNILENBQUM7NkJBQU0sQ0FBQzs0QkFDTixNQUFNLFdBQVcsQ0FBQTt3QkFDbkIsQ0FBQztvQkFDSCxDQUFDO29CQUVELE1BQU0sZ0JBQWdCLENBQUMsYUFBYSxDQUFDLEVBQUUsRUFBRSxVQUFVLENBQUMsQ0FBQTtnQkFDdEQsQ0FBQztxQkFBTSxDQUFDO29CQUNOLElBQUksQ0FBQzt3QkFDSCxNQUFNLGlCQUFpQixDQUFDLElBQUksRUFBRSxDQUFBO29CQUNoQyxDQUFDO29CQUFDLE9BQU8sU0FBUyxFQUFFLENBQUM7d0JBQ25CLElBQUksU0FBUyxZQUFZLG1CQUFtQixFQUFFLENBQUM7NEJBQzdDLE1BQU0sSUFBSSxLQUFLLENBQUMscUNBQXFDLFNBQVMsQ0FBQyxJQUFJLG1FQUFtRSxFQUFFLEVBQUMsS0FBSyxFQUFFLFNBQVMsRUFBQyxDQUFDLENBQUE7d0JBQzdKLENBQUM7NkJBQU0sQ0FBQzs0QkFDTixNQUFNLFNBQVMsQ0FBQTt3QkFDakIsQ0FBQztvQkFDSCxDQUFDO29CQUVELE1BQU0sZ0JBQWdCLENBQUMsYUFBYSxDQUFDLEVBQUUsRUFBRSxVQUFVLENBQUMsQ0FBQTtnQkFDdEQsQ0FBQztnQkFFRCxPQUFPLElBQUksQ0FBQTtZQUNiLENBQUM7WUFDRCwwRUFBMEU7WUFDMUUsMkVBQTJFO1lBQzNFLDBFQUEwRTtZQUMxRSxFQUFDLG1CQUFtQixFQUFFLElBQUksRUFBQyxDQUM1QixDQUFBO1lBRUQsSUFBSSxDQUFDLGFBQWE7Z0JBQUUsU0FBUTtZQUU1QixPQUFPLEdBQUcsSUFBSSxDQUFBO1FBQ2hCLENBQUM7UUFFRCxPQUFPLE9BQU8sQ0FBQTtJQUNoQixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IHtkaWdnfSBmcm9tIFwiZGlnZ2VyaXplXCJcbmltcG9ydCAqIGFzIGluZmxlY3Rpb24gZnJvbSBcImluZmxlY3Rpb25cIlxuaW1wb3J0IExvZ2dlciBmcm9tIFwiLi4vbG9nZ2VyLmpzXCJcbmltcG9ydCBNaWdyYXRpb25zTGVkZ2VyIGZyb20gXCIuL21pZ3JhdGlvbnMtbGVkZ2VyLmpzXCJcbmltcG9ydCBBZHZpc29yeUxvY2tSdW5uZXIgZnJvbSBcIi4vYWR2aXNvcnktbG9jay1ydW5uZXIuanNcIlxuaW1wb3J0IHtOb3RJbXBsZW1lbnRlZEVycm9yfSBmcm9tIFwiLi9taWdyYXRpb24vaW5kZXguanNcIlxuaW1wb3J0IHsgbWlncmF0aW9uRXhlY3V0aW9uUGhhc2UsIG1pZ3JhdGlvblJ1bnNJbkV4ZWN1dGlvblBoYXNlIH0gZnJvbSBcIi4vbWlncmF0aW9uLWV4ZWN1dGlvbi1waGFzZS5qc1wiXG5pbXBvcnQgcmVzdEFyZ3NFcnJvciBmcm9tIFwiLi4vdXRpbHMvcmVzdC1hcmdzLWVycm9yLmpzXCJcblxuLyoqXG4gKiBCdWlsZHMgdGhlIGFkdmlzb3J5LWxvY2sgbmFtZSB0aGF0IHNlcmlhbGlzZXMgbWlncmF0aW9ucyBmb3Igb25lIGRhdGFiYXNlIGlkZW50aWZpZXIuXG4gKlxuICogVGhlIG5hbWUgaXMgZGVyaXZlZCBmcm9tIHRoZSBkYXRhYmFzZSBpZGVudGlmaWVyIG9ubHkgKG5vdCB0aGUgbWlncmF0aW9uKSBzbyB0aGF0XG4gKiBjb25jdXJyZW50IHByb2Nlc3NlcyBxdWV1ZSBvbiBvbmUgbG9jayB3aGlsZSBhcHBseWluZyB0aGUgcGVuZGluZyBzZXQsIGluc3RlYWQgb2ZcbiAqIHJhY2luZyBvbiBpbmRpdmlkdWFsIERETCBzdGF0ZW1lbnRzLlxuICogQHBhcmFtIHtzdHJpbmd9IGRiSWRlbnRpZmllciAtIERhdGFiYXNlIGlkZW50aWZpZXIgYmVpbmcgbWlncmF0ZWQuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSAtIEFkdmlzb3J5IGxvY2sgbmFtZS5cbiAqL1xuZnVuY3Rpb24gbWlncmF0aW9uc0Fkdmlzb3J5TG9ja05hbWUoZGJJZGVudGlmaWVyKSB7XG4gIHJldHVybiBgdmVsb2Npb3VzOm1pZ3JhdGlvbnM6JHtkYklkZW50aWZpZXJ9YFxufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWZWxvY2lvdXNEYXRhYmFzZU1pZ3JhdG9yIHtcbiAgLyoqXG4gICAqIE1pZ3JhdGlvbnMgdmVyc2lvbnMuXG4gICAqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCBib29sZWFuPj59ICovXG4gIG1pZ3JhdGlvbnNWZXJzaW9ucyA9IHt9XG5cbiAgLyoqXG4gICAqIFJ1bnMgY29uc3RydWN0b3IuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi5qc1wiKS5kZWZhdWx0fSBhcmdzLmNvbmZpZ3VyYXRpb24gLSBDb25maWd1cmF0aW9uIGluc3RhbmNlLlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdfSBbYXJncy5kYXRhYmFzZUlkZW50aWZpZXJzXSAtIE9wdGlvbmFsIGRhdGFiYXNlIGlkZW50aWZpZXJzIHRvIG1pZ3JhdGUuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9taWdyYXRpb24tZXhlY3V0aW9uLXBoYXNlLmpzXCIpLk1pZ3JhdGlvbkV4ZWN1dGlvblBoYXNlfSBbYXJncy5leGVjdXRpb25QaGFzZV0gLSBPcHRpb25hbCBtaWdyYXRpb24gZXhlY3V0aW9uIHBoYXNlIHRvIHNlbGVjdC5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHtjb25maWd1cmF0aW9uLCBkYXRhYmFzZUlkZW50aWZpZXJzLCBleGVjdXRpb25QaGFzZSwgLi4ucmVzdEFyZ3N9KSB7XG4gICAgcmVzdEFyZ3NFcnJvcihyZXN0QXJncylcblxuICAgIGlmICghY29uZmlndXJhdGlvbikgdGhyb3cgbmV3IEVycm9yKFwiY29uZmlndXJhdGlvbiBhcmd1bWVudCBpcyByZXF1aXJlZFwiKVxuXG4gICAgdGhpcy5jb25maWd1cmF0aW9uID0gY29uZmlndXJhdGlvblxuICAgIHRoaXMuZGF0YWJhc2VJZGVudGlmaWVycyA9IGRhdGFiYXNlSWRlbnRpZmllcnNcbiAgICB0aGlzLmV4ZWN1dGlvblBoYXNlID0gZXhlY3V0aW9uUGhhc2UgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IG1pZ3JhdGlvbkV4ZWN1dGlvblBoYXNlKGV4ZWN1dGlvblBoYXNlKVxuICAgIHRoaXMubG9nZ2VyID0gbmV3IExvZ2dlcih0aGlzKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgaGFuZGxlcyBkYXRhYmFzZSBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZGJJZGVudGlmaWVyIC0gRGF0YWJhc2UgaWRlbnRpZmllci5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciB0aGlzIG1pZ3JhdG9yIHNob3VsZCB0b3VjaCB0aGUgZGF0YWJhc2UgaWRlbnRpZmllci5cbiAgICovXG4gIGhhbmRsZXNEYXRhYmFzZUlkZW50aWZpZXIoZGJJZGVudGlmaWVyKSB7XG4gICAgaWYgKCF0aGlzLmRhdGFiYXNlSWRlbnRpZmllcnMpIHJldHVybiB0cnVlXG5cbiAgICByZXR1cm4gdGhpcy5kYXRhYmFzZUlkZW50aWZpZXJzLmluY2x1ZGVzKGRiSWRlbnRpZmllcilcbiAgfVxuXG5cbiAgLyoqXG4gICAqIFJ1bnMgcHJlcGFyZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHByZXBhcmUoKSB7XG4gICAgdGhpcy5sb2dnZXIuZGVidWcoXCJwcmVwYXJlKCkgc3RhcnRcIilcbiAgICBhd2FpdCB0aGlzLmNyZWF0ZU1pZ3JhdGlvbnNUYWJsZSgpXG4gICAgdGhpcy5sb2dnZXIuZGVidWcoXCJjcmVhdGVNaWdyYXRpb25zVGFibGUgZG9uZVwiKVxuICAgIGF3YWl0IHRoaXMubG9hZE1pZ3JhdGlvbnNWZXJzaW9ucygpXG4gICAgdGhpcy5sb2dnZXIuZGVidWcoXCJwcmVwYXJlKCkgZG9uZVwiKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgY3JlYXRlIG1pZ3JhdGlvbnMgdGFibGUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBjcmVhdGVNaWdyYXRpb25zVGFibGUoKSB7XG4gICAgY29uc3QgZGJzID0gYXdhaXQgdGhpcy5jb25maWd1cmF0aW9uLmdldEN1cnJlbnRDb25uZWN0aW9ucygpXG5cbiAgICBmb3IgKGNvbnN0IGRiSWRlbnRpZmllciBpbiBkYnMpIHtcbiAgICAgIGlmICghdGhpcy5oYW5kbGVzRGF0YWJhc2VJZGVudGlmaWVyKGRiSWRlbnRpZmllcikpIGNvbnRpbnVlXG5cbiAgICAgIGF3YWl0IHRoaXMuY3JlYXRlTWlncmF0aW9uc1RhYmxlRm9yRGF0YWJhc2Uoe2RiSWRlbnRpZmllciwgZGI6IGRic1tkYklkZW50aWZpZXJdfSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBjcmVhdGUgbWlncmF0aW9ucyB0YWJsZSBmb3IgZGF0YWJhc2UuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLmRiSWRlbnRpZmllciAtIERhdGFiYXNlIGlkZW50aWZpZXIuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gYXJncy5kYiAtIERhdGFiYXNlIGNvbm5lY3Rpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBjcmVhdGVNaWdyYXRpb25zVGFibGVGb3JEYXRhYmFzZSh7ZGJJZGVudGlmaWVyLCBkYn0pIHtcbiAgICBjb25zdCBkYXRhYmFzZUNvbmZpZ3VyYXRpb24gPSB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0RGF0YWJhc2VJZGVudGlmaWVyKGRiSWRlbnRpZmllcilcblxuICAgIGlmICghZGF0YWJhc2VDb25maWd1cmF0aW9uLm1pZ3JhdGlvbnMpIHtcbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGAke2RiSWRlbnRpZmllcn0gaXNuJ3QgY29uZmlndXJlZCBmb3IgbWlncmF0aW9ucyAtIHNraXBwaW5nIGNyZWF0aW5nIG1pZ3JhdGlvbnMgdGFibGUgZm9yIGl0YClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmIChhd2FpdCB0aGlzLm1pZ3JhdGlvbnNUYWJsZUV4aXN0KGRiKSkge1xuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoYCR7ZGJJZGVudGlmaWVyfSBtaWdyYXRpb25zIHRhYmxlIGFscmVhZHkgZXhpc3RzIC0gc2tpcHBpbmdgKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhcIkNyZWF0aW5nIHNjaGVtYV9taWdyYXRpb25zIHRhYmxlIHZpYSBNaWdyYXRpb25zTGVkZ2VyXCIpXG4gICAgICBhd2FpdCBNaWdyYXRpb25zTGVkZ2VyLmVuc3VyZVRhYmxlKGRiKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGhhcyBydW4gbWlncmF0aW9uIHZlcnNpb24uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBkYklkZW50aWZpZXIgLSBEYiBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0ge251bWJlcn0gdmVyc2lvbiAtIFZlcnNpb24uXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgaXQgaGFzIHJ1biBtaWdyYXRpb24gdmVyc2lvbi5cbiAgICovXG4gIGhhc1J1bk1pZ3JhdGlvblZlcnNpb24oZGJJZGVudGlmaWVyLCB2ZXJzaW9uKSB7XG4gICAgaWYgKCF0aGlzLm1pZ3JhdGlvbnNWZXJzaW9ucykgdGhyb3cgbmV3IEVycm9yKFwiTWlncmF0aW9ucyB2ZXJzaW9ucyBoYXNuJ3QgYmVlbiBsb2FkZWQgeWV0XCIpXG4gICAgaWYgKCF0aGlzLm1pZ3JhdGlvbnNWZXJzaW9uc1tkYklkZW50aWZpZXJdKSB0aHJvdyBuZXcgRXJyb3IoYE1pZ3JhdGlvbnMgdmVyc2lvbnMgaGFzbid0IGJlZW4gbG9hZGVkIHlldCBmb3IgZGI6ICR7ZGJJZGVudGlmaWVyfWApXG5cbiAgICBpZiAodmVyc2lvbiBpbiB0aGlzLm1pZ3JhdGlvbnNWZXJzaW9uc1tkYklkZW50aWZpZXJdKSB7XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgLyoqXG4gICAqIEFwcGxpY2F0aW9uIG1pZ3JhdGlvbnMgYmVsb25nIHRvIHRoZSBzY2hlbWEtb3duaW5nIGxpZmVjeWNsZS4gSFRUUCB3b3JrZXJcbiAgICogdGhyZWFkcyAoYHByb2Nlc3NDb250ZXh0LnR5cGUgPT09IFwid29ya2VyLWhhbmRsZXJcImApIGVhY2ggcnVuIHRoZVxuICAgKiBhcHBsaWNhdGlvbidzIGBpbml0aWFsaXplTW9kZWxzYCBob29rLCBzbyBhbiBhcHAgdGhhdCBtaWdyYXRlcyBmcm9tIHRoYXQgaG9va1xuICAgKiB3b3VsZCBhcHBseSB0aGUgcGVuZGluZyBzZXQgKGFuZCB3cml0ZSB0aGUgc3RydWN0dXJlIGR1bXApIG9uY2UgcGVyIHdvcmtlci5cbiAgICogVGhlIHNlcnZlciBwcm9jZXNzIGFuZCBkZXBsb3kgbWlncmF0aW9uIHRhc2tzIG1pZ3JhdGUgYmVmb3JlIHdvcmtlcnMgc3RhcnQsXG4gICAqIHNvIHdvcmtlcnMgc2tpcCBoZXJlIGluc3RlYWQgb2YgcmVwZWF0aW5nIHRoYXQgd29yay5cbiAgICogQHJldHVybnMge1Byb21pc2U8Ym9vbGVhbj59IC0gV2hldGhlciB0aGlzIGxpZmVjeWNsZSBtdXN0IHNraXAgYXBwbGljYXRpb24gbWlncmF0aW9ucy5cbiAgICovXG4gIGFzeW5jIF9za2lwQXBwbGljYXRpb25NaWdyYXRpb25zSW5Xb3JrZXJMaWZlY3ljbGUoKSB7XG4gICAgY29uc3QgcHJvY2Vzc0NvbnRleHQgPSB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0QXBwbGljYXRpb25Qcm9jZXNzQ29udGV4dCgpXG5cbiAgICBpZiAocHJvY2Vzc0NvbnRleHQ/LnR5cGUgIT09IFwid29ya2VyLWhhbmRsZXJcIikgcmV0dXJuIGZhbHNlXG5cbiAgICBhd2FpdCB0aGlzLmxvZ2dlci5kZWJ1ZyhcIlNraXBwaW5nIGFwcGxpY2F0aW9uIG1pZ3JhdGlvbnMgaW4gYW4gSFRUUCB3b3JrZXIgdGhyZWFkIC0gdGhlIHNjaGVtYS1vd25pbmcgcHJvY2VzcyBtaWdyYXRlcyBiZWZvcmUgd29ya2VycyBzdGFydFwiLCB7XG4gICAgICBpbnN0YW5jZUlkOiBwcm9jZXNzQ29udGV4dC5pbnN0YW5jZUlkLFxuICAgICAgcHJvY2Vzc1R5cGU6IHByb2Nlc3NDb250ZXh0LnR5cGVcbiAgICB9KVxuXG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIG1pZ3JhdGUgZmlsZXMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9taWdyYXRvci90eXBlcy5qc1wiKS5NaWdyYXRpb25PYmplY3RUeXBlW119IGZpbGVzIC0gRmlsZXMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9taWdyYXRvci90eXBlcy5qc1wiKS5JbXBvcnRGdWxscGF0aENhbGxiYWNrVHlwZX0gaW1wb3J0Q2FsbGJhY2sgLSBJbXBvcnQgY2FsbGJhY2suXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPG51bWJlcj59IC0gTnVtYmVyIG9mIG1pZ3JhdGlvbnMgYWN0dWFsbHkgYXBwbGllZCAobm90IHNraXBwZWQgYXMgYWxyZWFkeS1ydW4pLlxuICAgKi9cbiAgYXN5bmMgbWlncmF0ZUZpbGVzKGZpbGVzLCBpbXBvcnRDYWxsYmFjaykge1xuICAgIGlmIChhd2FpdCB0aGlzLl9za2lwQXBwbGljYXRpb25NaWdyYXRpb25zSW5Xb3JrZXJMaWZlY3ljbGUoKSkgcmV0dXJuIDBcblxuICAgIGxldCBhcHBsaWVkQ291bnQgPSAwXG5cbiAgICBhd2FpdCB0aGlzLmNvbmZpZ3VyYXRpb24uZW5zdXJlQ29ubmVjdGlvbnMoe2RhdGFiYXNlSWRlbnRpZmllcnM6IHRoaXMuZGF0YWJhc2VJZGVudGlmaWVycywgbmFtZTogXCJEYXRhYmFzZSBtaWdyYXRvcjogbWlncmF0ZSBmaWxlc1wifSwgYXN5bmMgKCkgPT4ge1xuICAgICAgZm9yIChjb25zdCBtaWdyYXRpb24gb2YgZmlsZXMpIHtcbiAgICAgICAgY29uc3QgYXBwbGllZCA9IGF3YWl0IHRoaXMucnVuTWlncmF0aW9uRmlsZSh7XG4gICAgICAgICAgbWlncmF0aW9uLFxuICAgICAgICAgIHJlcXVpcmVNaWdyYXRpb246IGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGlmICghbWlncmF0aW9uLmZ1bGxQYXRoKSB0aHJvdyBuZXcgRXJyb3IoYE1pZ3JhdGlvbiBkaWRuJ3QgaGF2ZSBhIGZ1bGxQYXRoIGtleTogJHtPYmplY3Qua2V5cyhtaWdyYXRpb24pLmpvaW4oXCIsIFwiKX1gKVxuXG4gICAgICAgICAgICBjb25zdCBtaWdyYXRpb25JbXBvcnQgPSBhd2FpdCBpbXBvcnRDYWxsYmFjayhtaWdyYXRpb24uZnVsbFBhdGgpXG5cbiAgICAgICAgICAgIGlmICghbWlncmF0aW9uSW1wb3J0KSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgTWlncmF0aW9uIGZpbGUgbXVzdCBleHBvcnQgbWlncmF0aW9uIGNsYXNzOiAke21pZ3JhdGlvbi5mdWxsUGF0aH1gKVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gbWlncmF0aW9uSW1wb3J0XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuXG4gICAgICAgIGlmIChhcHBsaWVkKSBhcHBsaWVkQ291bnQrK1xuICAgICAgfVxuXG4gICAgICBhd2FpdCB0aGlzLl9hZnRlck1pZ3JhdGlvbnMoKVxuICAgIH0pXG5cbiAgICByZXR1cm4gYXBwbGllZENvdW50XG4gIH1cblxuICAvKipcbiAgICogUnVucyBtaWdyYXRlIGZpbGVzIGZyb20gcmVxdWlyZSBjb250ZXh0LlxuICAgKlxuICAgKiBBcHBsaWNhdGlvbiBtaWdyYXRpb25zIGJlbG9uZyB0byB0aGUgc2NoZW1hLW93bmluZyBsaWZlY3ljbGU7IHNlZVxuICAgKiB7QGxpbmsgVmVsb2Npb3VzRGF0YWJhc2VNaWdyYXRvciNfc2tpcEFwcGxpY2F0aW9uTWlncmF0aW9uc0luV29ya2VyTGlmZWN5Y2xlfS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL21pZ3JhdG9yL3R5cGVzLmpzXCIpLlJlcXVpcmVNaWdyYXRpb25Db250ZXh0VHlwZX0gcmVxdWlyZUNvbnRleHQgLSBSZXF1aXJlIGNvbnRleHQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBtaWdyYXRlRmlsZXNGcm9tUmVxdWlyZUNvbnRleHQocmVxdWlyZUNvbnRleHQpIHtcbiAgICBpZiAoYXdhaXQgdGhpcy5fc2tpcEFwcGxpY2F0aW9uTWlncmF0aW9uc0luV29ya2VyTGlmZWN5Y2xlKCkpIHJldHVyblxuXG4gICAgY29uc3QgZmlsZXMgPSB0aGlzLm1pZ3JhdGlvbnNGcm9tUmVxdWlyZUNvbnRleHQocmVxdWlyZUNvbnRleHQpXG5cbiAgICBhd2FpdCB0aGlzLmNvbmZpZ3VyYXRpb24uZW5zdXJlQ29ubmVjdGlvbnMoe2RhdGFiYXNlSWRlbnRpZmllcnM6IHRoaXMuZGF0YWJhc2VJZGVudGlmaWVycywgbmFtZTogXCJEYXRhYmFzZSBtaWdyYXRvcjogbWlncmF0ZSByZXF1aXJlLWNvbnRleHQgZmlsZXNcIn0sIGFzeW5jICgpID0+IHtcbiAgICAgIGZvciAoY29uc3QgbWlncmF0aW9uIG9mIGZpbGVzKSB7XG4gICAgICAgIGF3YWl0IHRoaXMucnVuTWlncmF0aW9uRmlsZSh7XG4gICAgICAgICAgbWlncmF0aW9uLFxuICAgICAgICAgIHJlcXVpcmVNaWdyYXRpb246IGFzeW5jICgpID0+IHJlcXVpcmVDb250ZXh0KG1pZ3JhdGlvbi5maWxlKS5kZWZhdWx0XG4gICAgICAgIH0pXG4gICAgICB9XG5cbiAgICAgIGF3YWl0IHRoaXMuX2FmdGVyTWlncmF0aW9ucygpXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBNaWdyYXRlcyBleGFjdGx5IG9uZSBhbHJlYWR5LWNhcHR1cmVkIHBoeXNpY2FsIGRhdGFiYXNlLiBUaGlzIGlzIHRoZVxuICAgKiBmcm9udGVuZC90ZW5hbnQgY291bnRlcnBhcnQgdG8gdGhlIGFtYmllbnQgbXVsdGktZGF0YWJhc2UgZW50cnlwb2ludHM6XG4gICAqIGNhbGxlcnMgb3duIHRoZSBjYXB0dXJlZCBjb25uZWN0aW9uIGFuZCBubyBjb25maWd1cmF0aW9uIGZhbGxiYWNrIGlzIHJlYWQuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gQ2FwdHVyZWQgbWlncmF0aW9uIGFyZ3VtZW50cy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLkRhdGFiYXNlQ29uZmlndXJhdGlvblR5cGV9IGFyZ3MuZGF0YWJhc2VDb25maWd1cmF0aW9uIC0gQ2FwdHVyZWQgcGh5c2ljYWwgZGF0YWJhc2UgY29uZmlndXJhdGlvbi5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MuZGF0YWJhc2VJZGVudGlmaWVyIC0gTG9naWNhbCBkYXRhYmFzZSBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGFyZ3MuZGIgLSBDYXB0dXJlZCBwaHlzaWNhbCBjb25uZWN0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vbWlncmF0b3IvdHlwZXMuanNcIikuUmVxdWlyZU1pZ3JhdGlvbkNvbnRleHRUeXBlfSBhcmdzLnJlcXVpcmVDb250ZXh0IC0gRnJvbnRlbmQgbWlncmF0aW9uIHJlcXVpcmUgY29udGV4dC5cbiAgICogQHJldHVybnMge1Byb21pc2U8bnVtYmVyPn0gLSBOdW1iZXIgb2YgbmV3bHkgYXBwbGllZCBtaWdyYXRpb25zLlxuICAgKi9cbiAgYXN5bmMgbWlncmF0ZVJlcXVpcmVDb250ZXh0Rm9yRGF0YWJhc2Uoe2RhdGFiYXNlQ29uZmlndXJhdGlvbiwgZGF0YWJhc2VJZGVudGlmaWVyLCBkYiwgcmVxdWlyZUNvbnRleHR9KSB7XG4gICAgaWYgKCFkYXRhYmFzZUNvbmZpZ3VyYXRpb24ubWlncmF0aW9ucykgcmV0dXJuIDBcblxuICAgIGF3YWl0IE1pZ3JhdGlvbnNMZWRnZXIuZW5zdXJlVGFibGUoZGIpXG4gICAgY29uc3QgYXBwbGllZFZlcnNpb25zID0gbmV3IFNldChhd2FpdCBNaWdyYXRpb25zTGVkZ2VyLmFwcGxpZWRWZXJzaW9ucyhkYikpXG4gICAgY29uc3QgbWlncmF0aW9ucyA9IHRoaXMubWlncmF0aW9uc0Zyb21SZXF1aXJlQ29udGV4dChyZXF1aXJlQ29udGV4dClcbiAgICBsZXQgYXBwbGllZENvdW50ID0gMFxuXG4gICAgZm9yIChjb25zdCBtaWdyYXRpb24gb2YgbWlncmF0aW9ucykge1xuICAgICAgY29uc3QgdmVyc2lvbiA9IGAke21pZ3JhdGlvbi5kYXRlfWBcblxuICAgICAgaWYgKGFwcGxpZWRWZXJzaW9ucy5oYXModmVyc2lvbikpIGNvbnRpbnVlXG5cbiAgICAgIGNvbnN0IE1pZ3JhdGlvbkNsYXNzID0gcmVxdWlyZUNvbnRleHQobWlncmF0aW9uLmZpbGUpLmRlZmF1bHRcblxuICAgICAgaWYgKCFNaWdyYXRpb25DbGFzcyB8fCB0eXBlb2YgTWlncmF0aW9uQ2xhc3MgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE1pZ3JhdGlvbiAke21pZ3JhdGlvbi5maWxlfSBtdXN0IGV4cG9ydCBhIGRlZmF1bHQgbWlncmF0aW9uIGNsYXNzLiBUeXBlOiAke3R5cGVvZiBNaWdyYXRpb25DbGFzc31gKVxuICAgICAgfVxuICAgICAgaWYgKCFtaWdyYXRpb25SdW5zSW5FeGVjdXRpb25QaGFzZShNaWdyYXRpb25DbGFzcywgdGhpcy5leGVjdXRpb25QaGFzZSkpIGNvbnRpbnVlXG4gICAgICBpZiAoIShNaWdyYXRpb25DbGFzcy5nZXREYXRhYmFzZUlkZW50aWZpZXJzKCkgfHwgW1wiZGVmYXVsdFwiXSkuaW5jbHVkZXMoZGF0YWJhc2VJZGVudGlmaWVyKSkgY29udGludWVcblxuICAgICAgY29uc3QgbWlncmF0aW9uSW5zdGFuY2UgPSBuZXcgTWlncmF0aW9uQ2xhc3Moe2NvbmZpZ3VyYXRpb246IHRoaXMuY29uZmlndXJhdGlvbiwgZGF0YWJhc2VJZGVudGlmaWVyLCBkYn0pXG5cbiAgICAgIGF3YWl0IHRoaXMucnVuTWlncmF0aW9uVXAoe21pZ3JhdGlvbiwgbWlncmF0aW9uSW5zdGFuY2V9KVxuICAgICAgYXdhaXQgTWlncmF0aW9uc0xlZGdlci5yZWNvcmRWZXJzaW9uKGRiLCB2ZXJzaW9uKVxuICAgICAgYXBwbGllZFZlcnNpb25zLmFkZCh2ZXJzaW9uKVxuICAgICAgYXBwbGllZENvdW50KytcbiAgICB9XG5cbiAgICByZXR1cm4gYXBwbGllZENvdW50XG4gIH1cblxuICAvKipcbiAgICogUGFyc2VzIGFuZCBvcmRlcnMgbWlncmF0aW9ucyBmcm9tIGEgYnJvd3Nlci9uYXRpdmUgcmVxdWlyZSBjb250ZXh0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vbWlncmF0b3IvdHlwZXMuanNcIikuUmVxdWlyZU1pZ3JhdGlvbkNvbnRleHRUeXBlfSByZXF1aXJlQ29udGV4dCAtIE1pZ3JhdGlvbiByZXF1aXJlIGNvbnRleHQuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL21pZ3JhdG9yL3R5cGVzLmpzXCIpLk1pZ3JhdGlvbk9iamVjdFR5cGVbXX0gLSBPcmRlcmVkIG1pZ3JhdGlvbnMuXG4gICAqL1xuICBtaWdyYXRpb25zRnJvbVJlcXVpcmVDb250ZXh0KHJlcXVpcmVDb250ZXh0KSB7XG4gICAgY29uc3QgbWlncmF0aW9ucyA9IFtdXG5cbiAgICBmb3IgKGNvbnN0IGZpbGUgb2YgcmVxdWlyZUNvbnRleHQua2V5cygpKSB7XG4gICAgICBjb25zdCBtYXRjaCA9IGZpbGUubWF0Y2goLyhcXGR7MTMsMTR9KS0oLispXFwuanMkLylcblxuICAgICAgaWYgKCFtYXRjaCkgY29udGludWVcblxuICAgICAgbGV0IGZpbGVOYW1lID0gZmlsZVxuICAgICAgbGV0IGRhdGVOdW1iZXIgPSBtYXRjaFsxXVxuXG4gICAgICBpZiAoZGF0ZU51bWJlci5sZW5ndGggPT0gMTMpIHtcbiAgICAgICAgZGF0ZU51bWJlciA9IGAyJHtkYXRlTnVtYmVyfWBcbiAgICAgICAgZmlsZU5hbWUgPSBgMiR7ZmlsZU5hbWV9YFxuICAgICAgfVxuXG4gICAgICBtaWdyYXRpb25zLnB1c2goe1xuICAgICAgICBkYXRlOiBwYXJzZUludChkYXRlTnVtYmVyKSxcbiAgICAgICAgZmlsZTogZmlsZU5hbWUsXG4gICAgICAgIG1pZ3JhdGlvbkNsYXNzTmFtZTogaW5mbGVjdGlvbi5jYW1lbGl6ZShtYXRjaFsyXS5yZXBsYWNlQWxsKFwiLVwiLCBcIl9cIikpXG4gICAgICB9KVxuICAgIH1cblxuICAgIHJldHVybiBtaWdyYXRpb25zLnNvcnQoKG1pZ3JhdGlvbjEsIG1pZ3JhdGlvbjIpID0+IG1pZ3JhdGlvbjEuZGF0ZSAtIG1pZ3JhdGlvbjIuZGF0ZSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIG9uZSBtaWdyYXRpb24ncyB1cHdhcmQgaW1wbGVtZW50YXRpb24uXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gTWlncmF0aW9uIGFyZ3VtZW50cy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL21pZ3JhdG9yL3R5cGVzLmpzXCIpLk1pZ3JhdGlvbk9iamVjdFR5cGV9IGFyZ3MubWlncmF0aW9uIC0gTWlncmF0aW9uIGRlc2NyaXB0b3IuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9taWdyYXRpb24vaW5kZXguanNcIikuZGVmYXVsdH0gYXJncy5taWdyYXRpb25JbnN0YW5jZSAtIE1pZ3JhdGlvbiBpbnN0YW5jZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgYWZ0ZXIgdGhlIG1pZ3JhdGlvbiBzdWNjZWVkcy5cbiAgICovXG4gIGFzeW5jIHJ1bk1pZ3JhdGlvblVwKHttaWdyYXRpb24sIG1pZ3JhdGlvbkluc3RhbmNlfSkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBtaWdyYXRpb25JbnN0YW5jZS5jaGFuZ2UoKVxuICAgIH0gY2F0Y2ggKGNoYW5nZUVycm9yKSB7XG4gICAgICBpZiAoIShjaGFuZ2VFcnJvciBpbnN0YW5jZW9mIE5vdEltcGxlbWVudGVkRXJyb3IpKSB0aHJvdyBjaGFuZ2VFcnJvclxuXG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBtaWdyYXRpb25JbnN0YW5jZS51cCgpXG4gICAgICB9IGNhdGNoICh1cEVycm9yKSB7XG4gICAgICAgIGlmICh1cEVycm9yIGluc3RhbmNlb2YgTm90SW1wbGVtZW50ZWRFcnJvcikge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJ2NoYW5nZScgb3IgJ3VwJyBkaWRuJ3QgZXhpc3Qgb24gbWlncmF0aW9uOiAke21pZ3JhdGlvbi5maWxlfWAsIHtjYXVzZTogdXBFcnJvcn0pXG4gICAgICAgIH1cblxuICAgICAgICB0aHJvdyB1cEVycm9yXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYWZ0ZXIgbWlncmF0aW9ucy5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIF9hZnRlck1pZ3JhdGlvbnMoKSB7XG4gICAgY29uc3QgZW52aXJvbm1lbnRIYW5kbGVyID0gdGhpcy5jb25maWd1cmF0aW9uLmdldEVudmlyb25tZW50SGFuZGxlcigpXG4gICAgY29uc3QgZGJzID0gYXdhaXQgdGhpcy5jb25maWd1cmF0aW9uLmdldEN1cnJlbnRDb25uZWN0aW9ucygpXG4gICAgY29uc3QgZmlsdGVyZWREYnMgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICBPYmplY3QuZW50cmllcyhkYnMpLmZpbHRlcigoW2RiSWRlbnRpZmllcl0pID0+IHtcbiAgICAgICAgaWYgKCF0aGlzLmhhbmRsZXNEYXRhYmFzZUlkZW50aWZpZXIoZGJJZGVudGlmaWVyKSkgcmV0dXJuIGZhbHNlXG5cbiAgICAgICAgcmV0dXJuIEJvb2xlYW4odGhpcy5jb25maWd1cmF0aW9uLmdldERhdGFiYXNlSWRlbnRpZmllcihkYklkZW50aWZpZXIpLm1pZ3JhdGlvbnMpXG4gICAgICB9KVxuICAgIClcblxuICAgIGlmICghZW52aXJvbm1lbnRIYW5kbGVyIHx8IE9iamVjdC5rZXlzKGZpbHRlcmVkRGJzKS5sZW5ndGggPT0gMCkgcmV0dXJuXG5cbiAgICAvLyBTZXJpYWxpc2UgdGhlIGZyYW1ld29yay1zY2hlbWEgYm9vdHN0cmFwIGFjcm9zcyBwcm9jZXNzZXMuIFRoaXMgY3JlYXRlcyB0aGUgYXR0YWNobWVudHNcbiAgICAvLyBhbmQgYmFja2dyb3VuZC1qb2JzIHRhYmxlcywgYW5kIGl0IHJ1bnMgb25jZSBwZXIgcHJvY2VzcyBvdXRzaWRlIHRoZSBwZXItbWlncmF0aW9uIGxvb3A6XG4gICAgLy8gd2l0aG91dCB0aGlzIGxvY2ssIHR3byBwcm9jZXNzZXMgYm9vdHN0cmFwcGluZyBvbmUgZGF0YWJhc2UgcmFjZSBvbiBDUkVBVEUgVEFCTEUgL1xuICAgIC8vIENSRUFURSBJTkRFWCBhbmQgb25lIGRpZXMgbWlkLWJvb3QgKGR1cGxpY2F0ZSBvYmplY3QvaW5kZXgpLlxuICAgIGZvciAoY29uc3QgW2RiSWRlbnRpZmllciwgZGJdIG9mIE9iamVjdC5lbnRyaWVzKGZpbHRlcmVkRGJzKSkge1xuICAgICAgY29uc3QgcnVubmVyID0gbmV3IEFkdmlzb3J5TG9ja1J1bm5lcih7XG4gICAgICAgIGNvbmZpZ3VyYXRpb246IHRoaXMuY29uZmlndXJhdGlvbixcbiAgICAgICAgY29ubmVjdGlvblByb3ZpZGVyOiAoKSA9PiBkYixcbiAgICAgICAgZGF0YWJhc2VJZGVudGlmaWVyOiBkYklkZW50aWZpZXJcbiAgICAgIH0pXG5cbiAgICAgIGF3YWl0IHJ1bm5lci53aXRoQWR2aXNvcnlMb2NrKFxuICAgICAgICBtaWdyYXRpb25zQWR2aXNvcnlMb2NrTmFtZShkYklkZW50aWZpZXIpLFxuICAgICAgICBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgYXdhaXQgZW52aXJvbm1lbnRIYW5kbGVyLmVuc3VyZUZyYW1ld29ya1NjaGVtYSh7ZGJzOiB7W2RiSWRlbnRpZmllcl06IGRifX0pXG4gICAgICAgIH0sXG4gICAgICAgIHtkZWRpY2F0ZWRDb25uZWN0aW9uOiB0cnVlfVxuICAgICAgKVxuICAgIH1cblxuICAgIC8vIEVuc3VyZSBWZWxvY2lvdXMnIG93biBmcmFtZXdvcmsgc2NoZW1hIGJlZm9yZSB0aGUgc3RydWN0dXJlIGR1bXAuIFRoZSBkdW1wIGlzXG4gICAgLy8gZ2F0ZWQgdG8gZW5hYmxlZCBlbnZpcm9ubWVudHMsIGJ1dCBtaWdyYXRpb24tZW5hYmxlZCBkYXRhYmFzZXMgbXVzdCBpbmNsdWRlXG4gICAgLy8gZnJhbWV3b3JrIHRhYmxlcyBzbyBgZGI6bWlncmF0ZWAgYW5kIHNjaGVtYTpsb2FkIHByb2R1Y2UgYSBjb21wbGV0ZSBkYXRhYmFzZS5cbiAgICBhd2FpdCBlbnZpcm9ubWVudEhhbmRsZXIuYWZ0ZXJNaWdyYXRpb25zKHtkYnM6IGZpbHRlcmVkRGJzfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGxvYWQgbWlncmF0aW9ucyB2ZXJzaW9ucy5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIGxvYWRNaWdyYXRpb25zVmVyc2lvbnMoKSB7XG4gICAgdGhpcy5taWdyYXRpb25zVmVyc2lvbnMgPSB7fVxuXG4gICAgY29uc3QgZGJzID0gYXdhaXQgdGhpcy5jb25maWd1cmF0aW9uLmdldEN1cnJlbnRDb25uZWN0aW9ucygpXG5cbiAgICBmb3IgKGNvbnN0IGRiSWRlbnRpZmllciBpbiBkYnMpIHtcbiAgICAgIGlmICghdGhpcy5oYW5kbGVzRGF0YWJhc2VJZGVudGlmaWVyKGRiSWRlbnRpZmllcikpIGNvbnRpbnVlXG5cbiAgICAgIGF3YWl0IHRoaXMubG9hZE1pZ3JhdGlvbnNWZXJzaW9uc0ZvckRhdGFiYXNlKHtkYklkZW50aWZpZXIsIGRiOiBkYnNbZGJJZGVudGlmaWVyXX0pXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgbG9hZCBtaWdyYXRpb25zIHZlcnNpb25zIGZvciBkYXRhYmFzZS5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MuZGJJZGVudGlmaWVyIC0gRGF0YWJhc2UgaWRlbnRpZmllci5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBhcmdzLmRiIC0gRGF0YWJhc2UgY29ubmVjdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIGxvYWRNaWdyYXRpb25zVmVyc2lvbnNGb3JEYXRhYmFzZSh7ZGJJZGVudGlmaWVyLCBkYn0pIHtcbiAgICBjb25zdCBkYXRhYmFzZUNvbmZpZ3VyYXRpb24gPSB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0RGF0YWJhc2VJZGVudGlmaWVyKGRiSWRlbnRpZmllcilcblxuICAgIGlmICghZGF0YWJhc2VDb25maWd1cmF0aW9uLm1pZ3JhdGlvbnMpIHtcbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGAke2RiSWRlbnRpZmllcn0gaXNuJ3QgY29uZmlndXJlZCBmb3IgbWlncmF0aW9ucyAtIHNraXBwaW5nIGxvYWRpbmcgbWlncmF0aW9ucyB2ZXJzaW9ucyBmb3IgaXRgKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKCFhd2FpdCB0aGlzLm1pZ3JhdGlvbnNUYWJsZUV4aXN0KGRiKSkge1xuICAgICAgdGhpcy5sb2dnZXIuaW5mbyhgTWlncmF0aW9uIHRhYmxlIGRvZXMgbm90IGV4aXN0IGZvciAke2RiSWRlbnRpZmllcn0gLSBza2lwcGluZyBsb2FkaW5nIG1pZ3JhdGlvbnMgdmVyc2lvbnMgZm9yIGl0YClcbiAgICAgIGRlbGV0ZSB0aGlzLm1pZ3JhdGlvbnNWZXJzaW9uc1tkYklkZW50aWZpZXJdXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCB2ZXJzaW9ucyA9IGF3YWl0IE1pZ3JhdGlvbnNMZWRnZXIuYXBwbGllZFZlcnNpb25zKGRiKVxuXG4gICAgdGhpcy5taWdyYXRpb25zVmVyc2lvbnNbZGJJZGVudGlmaWVyXSA9IHt9XG5cbiAgICBmb3IgKGNvbnN0IHZlcnNpb24gb2YgdmVyc2lvbnMpIHtcbiAgICAgIHRoaXMubWlncmF0aW9uc1ZlcnNpb25zW2RiSWRlbnRpZmllcl1bdmVyc2lvbl0gPSB0cnVlXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgbWlncmF0aW9ucyB0YWJsZSBleGlzdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBkYiAtIERhdGFiYXNlIGNvbm5lY3Rpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGJvb2xlYW4+fSAtIFJlc29sdmVzIHdpdGggV2hldGhlciBtaWdyYXRpb25zIHRhYmxlIGV4aXN0LlxuICAgKi9cbiAgYXN5bmMgbWlncmF0aW9uc1RhYmxlRXhpc3QoZGIpIHtcbiAgICByZXR1cm4gYXdhaXQgTWlncmF0aW9uc0xlZGdlci50YWJsZUV4aXN0cyhkYilcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGV4ZWN1dGUgcmVxdWlyZSBjb250ZXh0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vbWlncmF0b3IvdHlwZXMuanNcIikuUmVxdWlyZU1pZ3JhdGlvbkNvbnRleHRUeXBlfSByZXF1aXJlQ29udGV4dCAtIFJlcXVpcmUgY29udGV4dC5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIGV4ZWN1dGVSZXF1aXJlQ29udGV4dChyZXF1aXJlQ29udGV4dCkge1xuICAgIGNvbnN0IG1pZ3JhdGlvbkZpbGVzID0gcmVxdWlyZUNvbnRleHQua2V5cygpXG5cbiAgICAvKipcbiAgICAgKiBGaWxlcy5cbiAgICAgKiBAdHlwZSB7aW1wb3J0KFwiLi9taWdyYXRvci90eXBlcy5qc1wiKS5NaWdyYXRpb25PYmplY3RUeXBlW119ICovXG4gICAgbGV0IGZpbGVzID0gW11cblxuICAgIGZvciAoY29uc3QgZmlsZSBvZiBtaWdyYXRpb25GaWxlcykge1xuICAgICAgY29uc3QgbWF0Y2ggPSBmaWxlLm1hdGNoKC9eKFxcZHsxNH0pLSguKylcXC5qcyQvKVxuXG4gICAgICBpZiAoIW1hdGNoKSBjb250aW51ZVxuXG4gICAgICBjb25zdCBkYXRlID0gcGFyc2VJbnQobWF0Y2hbMV0pXG4gICAgICBjb25zdCBtaWdyYXRpb25OYW1lID0gbWF0Y2hbMl1cbiAgICAgIGNvbnN0IG1pZ3JhdGlvbkNsYXNzTmFtZSA9IGluZmxlY3Rpb24uY2FtZWxpemUobWlncmF0aW9uTmFtZSlcblxuICAgICAgY29uc3QgbWlncmF0aW9uT2JqZWN0ID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuL21pZ3JhdG9yL3R5cGVzLmpzXCIpLk1pZ3JhdGlvbk9iamVjdFR5cGV9ICovICh7XG4gICAgICAgIGZpbGUsXG4gICAgICAgIGRhdGUsXG4gICAgICAgIG1pZ3JhdGlvbkNsYXNzTmFtZVxuICAgICAgfSlcblxuICAgICAgZmlsZXMucHVzaChtaWdyYXRpb25PYmplY3QpXG4gICAgfVxuXG4gICAgZmlsZXMgPSBmaWxlcy5zb3J0KChtaWdyYXRpb24xLCBtaWdyYXRpb24yKSA9PiBtaWdyYXRpb24xLmRhdGUgLSBtaWdyYXRpb24yLmRhdGUpXG5cbiAgICBmb3IgKGNvbnN0IG1pZ3JhdGlvbiBvZiBmaWxlcykge1xuICAgICAgYXdhaXQgdGhpcy5ydW5NaWdyYXRpb25GaWxlKHtcbiAgICAgICAgbWlncmF0aW9uLFxuICAgICAgICByZXF1aXJlTWlncmF0aW9uOiBhc3luYyAoKSA9PiByZXF1aXJlQ29udGV4dChtaWdyYXRpb24uZmlsZSkuZGVmYXVsdFxuICAgICAgfSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyByZXNldC5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHJlc2V0KCkge1xuICAgIGNvbnN0IGRicyA9IGF3YWl0IHRoaXMuY29uZmlndXJhdGlvbi5nZXRDdXJyZW50Q29ubmVjdGlvbnMoKVxuXG4gICAgZm9yIChjb25zdCBkYklkZW50aWZpZXIgaW4gZGJzKSB7XG4gICAgICBpZiAoIXRoaXMuaGFuZGxlc0RhdGFiYXNlSWRlbnRpZmllcihkYklkZW50aWZpZXIpKSBjb250aW51ZVxuXG4gICAgICBjb25zdCBkYiA9IGRic1tkYklkZW50aWZpZXJdXG5cbiAgICAgIGF3YWl0IGRiLndpdGhEaXNhYmxlZEZvcmVpZ25LZXlzKGFzeW5jICgpID0+IHtcbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICBjb25zdCBlcnJvcnMgPSBbXVxuICAgICAgICAgIGxldCBhbnlUYWJsZURyb3BwZWQgPSBmYWxzZVxuXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgdGFibGUgb2YgYXdhaXQgZGIuZ2V0VGFibGVzKCkpIHtcbiAgICAgICAgICAgICAgdGhpcy5sb2dnZXIuaW5mbyhgRHJvcHBpbmcgdGFibGUgJHt0YWJsZS5nZXROYW1lKCl9YClcblxuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGF3YWl0IGRiLmRyb3BUYWJsZSh0YWJsZS5nZXROYW1lKCksIHtjYXNjYWRlOiB0cnVlfSlcbiAgICAgICAgICAgICAgICBhbnlUYWJsZURyb3BwZWQgPSB0cnVlXG4gICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgZXJyb3JzLnB1c2goZXJyb3IpXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikgeyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG4gICAgICAgICAgICBpZiAoZXJyb3JzLmxlbmd0aCA+IDAgJiYgYW55VGFibGVEcm9wcGVkKSB7XG4gICAgICAgICAgICAgIC8vIFJldHJ5XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aHJvdyBlcnJvcnNbMF1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcm9sbGJhY2suXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9taWdyYXRvci90eXBlcy5qc1wiKS5NaWdyYXRpb25PYmplY3RUeXBlW119IGZpbGVzIC0gRmlsZXMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9taWdyYXRvci90eXBlcy5qc1wiKS5JbXBvcnRGdWxscGF0aENhbGxiYWNrVHlwZX0gaW1wb3J0Q2FsbGJhY2sgRnVuY3Rpb24gdG8gaW1wb3J0IGEgZmlsZVxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgcm9sbGJhY2soZmlsZXMsIGltcG9ydENhbGxiYWNrKSB7XG4gICAgY29uc3QgbGF0ZXN0TWlncmF0aW9uVmVyc2lvbiA9IGF3YWl0IHRoaXMuX2xhdGVzdE1pZ3JhdGlvblZlcnNpb24oKVxuXG4gICAgaWYgKCFsYXRlc3RNaWdyYXRpb25WZXJzaW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyBtaWdyYXRpb25zIGhhdmUgYmVlbiBydW4geWV0XCIpXG4gICAgfVxuXG4gICAgY29uc3QgbGF0ZXN0TWlncmF0aW9uVmVyc2lvbk51bWJlciA9IHBhcnNlSW50KGxhdGVzdE1pZ3JhdGlvblZlcnNpb24pXG4gICAgY29uc3QgbWlncmF0aW9uID0gZmlsZXMuZmluZCgoZmlsZSkgPT4gZmlsZS5kYXRlID09IGxhdGVzdE1pZ3JhdGlvblZlcnNpb25OdW1iZXIpXG5cbiAgICBpZiAoIW1pZ3JhdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBNaWdyYXRpb24gZmlsZSBmb3IgdmVyc2lvbiAke2xhdGVzdE1pZ3JhdGlvblZlcnNpb25OdW1iZXJ9IG5vdCBmb3VuZGApXG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5ydW5NaWdyYXRpb25GaWxlKHtcbiAgICAgIG1pZ3JhdGlvbixcbiAgICAgIHJlcXVpcmVNaWdyYXRpb246IGFzeW5jICgpID0+IHtcbiAgICAgICAgaWYgKCFtaWdyYXRpb24uZnVsbFBhdGgpIHRocm93IG5ldyBFcnJvcihgTWlncmF0aW9uIGRpZG4ndCBoYXZlIGEgZnVsbFBhdGgga2V5OiAke09iamVjdC5rZXlzKG1pZ3JhdGlvbikuam9pbihcIiwgXCIpfWApXG5cbiAgICAgICAgcmV0dXJuIGF3YWl0IGltcG9ydENhbGxiYWNrKG1pZ3JhdGlvbi5mdWxsUGF0aClcbiAgICAgIH0sXG4gICAgICBkaXJlY3Rpb246IFwiZG93blwiXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGxhdGVzdCBtaWdyYXRpb24gdmVyc2lvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPn0gVGhlIGxhdGVzdCBtaWdyYXRpb24gdmVyc2lvblxuICAgKi9cbiAgYXN5bmMgX2xhdGVzdE1pZ3JhdGlvblZlcnNpb24oKSB7XG4gICAgaWYgKCF0aGlzLm1pZ3JhdGlvbnNWZXJzaW9ucykgYXdhaXQgdGhpcy5sb2FkTWlncmF0aW9uc1ZlcnNpb25zKClcblxuICAgIC8qKlxuICAgICAqIERlZmluZXMgaGlnaGVzdFZlcnNpb24uXG4gICAgICogQHR5cGUge3N0cmluZyB8IHVuZGVmaW5lZH0gKi9cbiAgICBsZXQgaGlnaGVzdFZlcnNpb25cblxuICAgIGZvciAoY29uc3QgZGJJZGVudGlmaWVyIGluIHRoaXMubWlncmF0aW9uc1ZlcnNpb25zKSB7XG4gICAgICBmb3IgKGNvbnN0IG1pZ3JhdGlvblZlcnNpb24gaW4gdGhpcy5taWdyYXRpb25zVmVyc2lvbnNbZGJJZGVudGlmaWVyXSkge1xuICAgICAgICBpZiAoIWhpZ2hlc3RWZXJzaW9uIHx8IG1pZ3JhdGlvblZlcnNpb24gPiBoaWdoZXN0VmVyc2lvbikge1xuICAgICAgICAgIGhpZ2hlc3RWZXJzaW9uID0gbWlncmF0aW9uVmVyc2lvblxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGhpZ2hlc3RWZXJzaW9uXG4gIH1cblxuICAvKipcbiAgICogUnVucyBydW4gbWlncmF0aW9uIGZpbGUuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9taWdyYXRvci90eXBlcy5qc1wiKS5NaWdyYXRpb25PYmplY3RUeXBlfSBhcmdzLm1pZ3JhdGlvbiAtIE1pZ3JhdGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL21pZ3JhdG9yL3R5cGVzLmpzXCIpLlJlcXVpcmVNaWdyYXRpb25UeXBlfSBhcmdzLnJlcXVpcmVNaWdyYXRpb24gLSBSZXF1aXJlIG1pZ3JhdGlvbi5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFthcmdzLmRpcmVjdGlvbl0gLSBEaXJlY3Rpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGJvb2xlYW4+fSAtIFdoZXRoZXIgdGhlIG1pZ3JhdGlvbiByYW4gb24gYXQgbGVhc3Qgb25lIGRhdGFiYXNlIChmYWxzZSBpZiBza2lwcGVkIGFzIGFscmVhZHktcnVuIGV2ZXJ5d2hlcmUpLlxuICAgKi9cbiAgYXN5bmMgcnVuTWlncmF0aW9uRmlsZSh7bWlncmF0aW9uLCByZXF1aXJlTWlncmF0aW9uLCBkaXJlY3Rpb24gPSBcInVwXCJ9KSB7XG4gICAgaWYgKCF0aGlzLmNvbmZpZ3VyYXRpb24pIHRocm93IG5ldyBFcnJvcihcIk5vIGNvbmZpZ3VyYXRpb24gc2V0XCIpXG4gICAgdGhpcy5sb2dnZXIuZGVidWcoXCJydW5NaWdyYXRpb25GaWxlXCIsIHtmaWxlOiBtaWdyYXRpb24gJiYgbWlncmF0aW9uLmZpbGV9KVxuICAgIGlmICghdGhpcy5jb25maWd1cmF0aW9uLmlzRGF0YWJhc2VQb29sSW5pdGlhbGl6ZWQoKSkgYXdhaXQgdGhpcy5jb25maWd1cmF0aW9uLmluaXRpYWxpemVEYXRhYmFzZVBvb2woKVxuICAgIGlmICghdGhpcy5taWdyYXRpb25zVmVyc2lvbnMpIGF3YWl0IHRoaXMubG9hZE1pZ3JhdGlvbnNWZXJzaW9ucygpXG5cbiAgICBsZXQgYXBwbGllZCA9IGZhbHNlXG4gICAgY29uc3QgZGJzID0gYXdhaXQgdGhpcy5jb25maWd1cmF0aW9uLmdldEN1cnJlbnRDb25uZWN0aW9ucygpXG5cbiAgICAvKipcbiAgICAgKiBEYiBpZGVudGlmaWVycyBuZWVkaW5nIG1pZ3JhdGlvbiB2ZXJzaW9ucy5cbiAgICAgKiBAdHlwZSB7c3RyaW5nW119ICovXG4gICAgY29uc3QgZGJJZGVudGlmaWVyc05lZWRpbmdNaWdyYXRpb25WZXJzaW9ucyA9IFtdXG5cbiAgICAvLyBtaWdyYXRlRmlsZXMoKSB3cmFwcyBleGVjdXRpb24gaW4gZW5zdXJlQ29ubmVjdGlvbnMoKSwgc28gdGhlIGN1cnJlbnRcbiAgICAvLyBhc3luYyBjb250ZXh0IGNhbiBleHBvc2UgREIgaWRlbnRpZmllcnMgbm90IGxvYWRlZCBieSBwcmVwYXJlKCkuXG4gICAgZm9yIChjb25zdCBkYklkZW50aWZpZXIgaW4gZGJzKSB7XG4gICAgICBpZiAoIXRoaXMuaGFuZGxlc0RhdGFiYXNlSWRlbnRpZmllcihkYklkZW50aWZpZXIpKSBjb250aW51ZVxuXG4gICAgICBjb25zdCBkYXRhYmFzZUNvbmZpZ3VyYXRpb24gPSB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0RGF0YWJhc2VJZGVudGlmaWVyKGRiSWRlbnRpZmllcilcblxuICAgICAgaWYgKCFkYXRhYmFzZUNvbmZpZ3VyYXRpb24ubWlncmF0aW9ucykgY29udGludWVcbiAgICAgIGlmICh0aGlzLm1pZ3JhdGlvbnNWZXJzaW9uc1tkYklkZW50aWZpZXJdKSBjb250aW51ZVxuXG4gICAgICBkYklkZW50aWZpZXJzTmVlZGluZ01pZ3JhdGlvblZlcnNpb25zLnB1c2goZGJJZGVudGlmaWVyKVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgZGJJZGVudGlmaWVyIG9mIGRiSWRlbnRpZmllcnNOZWVkaW5nTWlncmF0aW9uVmVyc2lvbnMpIHtcbiAgICAgIGNvbnN0IGRiID0gZGJzW2RiSWRlbnRpZmllcl1cblxuICAgICAgYXdhaXQgdGhpcy5jcmVhdGVNaWdyYXRpb25zVGFibGVGb3JEYXRhYmFzZSh7ZGJJZGVudGlmaWVyLCBkYn0pXG4gICAgICBhd2FpdCB0aGlzLmxvYWRNaWdyYXRpb25zVmVyc2lvbnNGb3JEYXRhYmFzZSh7ZGJJZGVudGlmaWVyLCBkYn0pXG4gICAgfVxuXG4gICAgY29uc3QgbWlncmF0aW9uQ2xhc3MgPSBhd2FpdCByZXF1aXJlTWlncmF0aW9uKClcblxuICAgIGlmICghbWlncmF0aW9uQ2xhc3MgfHwgdHlwZW9mIG1pZ3JhdGlvbkNsYXNzICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTWlncmF0aW9uICR7bWlncmF0aW9uLmZpbGV9IG11c3QgZXhwb3J0IGEgZGVmYXVsdCBtaWdyYXRpb24gY2xhc3MuIFR5cGU6ICR7dHlwZW9mIG1pZ3JhdGlvbkNsYXNzfWApXG4gICAgfVxuICAgIGlmIChkaXJlY3Rpb24gPT0gXCJ1cFwiICYmICFtaWdyYXRpb25SdW5zSW5FeGVjdXRpb25QaGFzZShtaWdyYXRpb25DbGFzcywgdGhpcy5leGVjdXRpb25QaGFzZSkpIHJldHVybiBmYWxzZVxuXG4gICAgY29uc3QgbWlncmF0aW9uRGF0YWJhc2VJZGVudGlmaWVycyA9IG1pZ3JhdGlvbkNsYXNzLmdldERhdGFiYXNlSWRlbnRpZmllcnMoKSB8fCBbXCJkZWZhdWx0XCJdXG5cbiAgICBmb3IgKGNvbnN0IGRiSWRlbnRpZmllciBpbiBkYnMpIHtcbiAgICAgIGlmICghdGhpcy5oYW5kbGVzRGF0YWJhc2VJZGVudGlmaWVyKGRiSWRlbnRpZmllcikpIGNvbnRpbnVlXG5cbiAgICAgIGNvbnN0IGRhdGFiYXNlQ29uZmlndXJhdGlvbiA9IHRoaXMuY29uZmlndXJhdGlvbi5nZXREYXRhYmFzZUlkZW50aWZpZXIoZGJJZGVudGlmaWVyKVxuXG4gICAgICBpZiAoIWRhdGFiYXNlQ29uZmlndXJhdGlvbi5taWdyYXRpb25zKSB7XG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGAke2RiSWRlbnRpZmllcn0gaXNuJ3QgY29uZmlndXJlZCBmb3IgbWlncmF0aW9ucyAtIHNraXBwaW5nIG1pZ3JhdGlvbiAke2RpZ2cobWlncmF0aW9uLCBcImRhdGVcIil9YClcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgaWYgKCFtaWdyYXRpb25EYXRhYmFzZUlkZW50aWZpZXJzLmluY2x1ZGVzKGRiSWRlbnRpZmllcikpIHtcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoYCR7ZGJJZGVudGlmaWVyfSBzaG91bGRuJ3QgcnVuIG1pZ3JhdGlvbiAke21pZ3JhdGlvbi5maWxlfWAsIHttaWdyYXRpb25EYXRhYmFzZUlkZW50aWZpZXJzfSlcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgY29uc3QgZGIgPSBkYnNbZGJJZGVudGlmaWVyXVxuICAgICAgY29uc3QgZGF0ZVN0cmluZyA9IGAke2RpZ2cobWlncmF0aW9uLCBcImRhdGVcIil9YFxuXG4gICAgICAvLyBTZXJpYWxpc2UgdGhlIGNoZWNrLXRoZW4tYXBwbHkgYWNyb3NzIHByb2Nlc3Nlcy4gV2l0aG91dCB0aGlzLCB0d28gc2hhcmRzIGNhbiBib3RoXG4gICAgICAvLyBvYnNlcnZlIHRoZSBtaWdyYXRpb24gYXMgdW5hcHBsaWVkIGFuZCBib3RoIGV4ZWN1dGUgaXRzIERETDsgdGhlIGxvc2VyIGRpZXMgd2l0aCB0aGVcbiAgICAgIC8vIGRyaXZlcidzIGR1cGxpY2F0ZS1vYmplY3QgZXJyb3IgbWlkLWJvb3QuXG4gICAgICAvL1xuICAgICAgLy8gVGhlIHZlcnNpb24gaXMgcmUtcmVhZCAqaW5zaWRlKiB0aGUgbG9jazogd2hpbGUgdGhpcyBwcm9jZXNzIHdhaXRlZCwgYW5vdGhlciBwcm9jZXNzXG4gICAgICAvLyBtYXkgYWxyZWFkeSBoYXZlIGFwcGxpZWQgdGhlIG1pZ3JhdGlvbiwgaW4gd2hpY2ggY2FzZSB0aGlzIG9uZSBtdXN0IGJlY29tZSBhIG5vLW9wLlxuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoXCJhY3F1aXJpbmcgbWlncmF0aW9uIGFkdmlzb3J5IGxvY2tcIiwge2RhdGFiYXNlSWRlbnRpZmllcjogZGJJZGVudGlmaWVyLCBmaWxlOiBtaWdyYXRpb24uZmlsZX0pXG4gICAgICBjb25zdCBydW5uZXIgPSBuZXcgQWR2aXNvcnlMb2NrUnVubmVyKHtcbiAgICAgICAgY29uZmlndXJhdGlvbjogdGhpcy5jb25maWd1cmF0aW9uLFxuICAgICAgICBjb25uZWN0aW9uUHJvdmlkZXI6ICgpID0+IGRiLFxuICAgICAgICBkYXRhYmFzZUlkZW50aWZpZXI6IGRiSWRlbnRpZmllclxuICAgICAgfSlcblxuICAgICAgY29uc3QgYXBwbGllZEluTG9jayA9IGF3YWl0IHJ1bm5lci53aXRoQWR2aXNvcnlMb2NrKFxuICAgICAgICBtaWdyYXRpb25zQWR2aXNvcnlMb2NrTmFtZShkYklkZW50aWZpZXIpLFxuICAgICAgICBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgLy8gUmUtcmVhZCB0aGUgYXBwbGllZCBzZXQgZnJvbSB0aGUgZGF0YWJhc2Ugd2hpbGUgaG9sZGluZyB0aGUgbG9jay4gVGhlIHZlcnNpb25cbiAgICAgICAgICAvLyBsaXN0IHdhcyBsb2FkZWQgZHVyaW5nIHByZXBhcmUoKSwgYmVmb3JlIGFueSBvdGhlciBwcm9jZXNzIG1heSBoYXZlIGZpbmlzaGVkXG4gICAgICAgICAgLy8gYXBwbHlpbmcgbWlncmF0aW9ucywgc28gdHJ1c3RpbmcgdGhhdCBjYWNoZWQgc25hcHNob3QgaGVyZSB3b3VsZCBsZXQgdGhpc1xuICAgICAgICAgIC8vIHByb2Nlc3MgcmUtcnVuIERETCB0aGF0IGFub3RoZXIgcHJvY2VzcyBoYXMgYWxyZWFkeSBjb21taXR0ZWQuXG4gICAgICAgICAgYXdhaXQgdGhpcy5sb2FkTWlncmF0aW9uc1ZlcnNpb25zRm9yRGF0YWJhc2Uoe2RiSWRlbnRpZmllciwgZGJ9KVxuXG4gICAgICAgICAgaWYgKGRpcmVjdGlvbiA9PSBcInVwXCIpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmhhc1J1bk1pZ3JhdGlvblZlcnNpb24oZGJJZGVudGlmaWVyLCBtaWdyYXRpb24uZGF0ZSkpIHtcbiAgICAgICAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoYCR7ZGJJZGVudGlmaWVyfSBoYXMgYWxyZWFkeSBydW4gbWlncmF0aW9uICR7bWlncmF0aW9uLmZpbGV9YClcbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmIChkaXJlY3Rpb24gPT0gXCJkb3duXCIpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5oYXNSdW5NaWdyYXRpb25WZXJzaW9uKGRiSWRlbnRpZmllciwgbWlncmF0aW9uLmRhdGUpKSB7XG4gICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGAke2RiSWRlbnRpZmllcn0gaGFzbid0IHJ1biBtaWdyYXRpb24gJHttaWdyYXRpb24uZmlsZX1gKVxuICAgICAgICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGRpcmVjdGlvbjogJHtkaXJlY3Rpb259YClcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgUnVubmluZyBtaWdyYXRpb24gb24gJHtkYklkZW50aWZpZXJ9OiAke21pZ3JhdGlvbi5maWxlfWAsIHttaWdyYXRpb25EYXRhYmFzZUlkZW50aWZpZXJzfSlcblxuICAgICAgICAgIGNvbnN0IE1pZ3JhdGlvbkNsYXNzID0gbWlncmF0aW9uQ2xhc3NcbiAgICAgICAgICBjb25zdCBtaWdyYXRpb25JbnN0YW5jZSA9IG5ldyBNaWdyYXRpb25DbGFzcyh7XG4gICAgICAgICAgICBjb25maWd1cmF0aW9uOiB0aGlzLmNvbmZpZ3VyYXRpb24sXG4gICAgICAgICAgICBkYXRhYmFzZUlkZW50aWZpZXI6IGRiSWRlbnRpZmllcixcbiAgICAgICAgICAgIGRiXG4gICAgICAgICAgfSlcblxuICAgICAgICAgIGlmIChkaXJlY3Rpb24gPT0gXCJ1cFwiKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBhd2FpdCBtaWdyYXRpb25JbnN0YW5jZS5jaGFuZ2UoKVxuICAgICAgICAgICAgfSBjYXRjaCAoY2hhbmdlRXJyb3IpIHtcbiAgICAgICAgICAgICAgaWYgKGNoYW5nZUVycm9yIGluc3RhbmNlb2YgTm90SW1wbGVtZW50ZWRFcnJvcikge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICBhd2FpdCBtaWdyYXRpb25JbnN0YW5jZS51cCgpXG4gICAgICAgICAgICAgICAgfSBjYXRjaCAodXBFcnJvcikge1xuICAgICAgICAgICAgICAgICAgaWYgKHVwRXJyb3IgaW5zdGFuY2VvZiBOb3RJbXBsZW1lbnRlZEVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJ2NoYW5nZScgb3IgJ3VwJyBkaWRuJ3QgZXhpc3Qgb24gbWlncmF0aW9uOiAke21pZ3JhdGlvbi5maWxlfWAsIHtjYXVzZTogdXBFcnJvcn0pXG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyB1cEVycm9yXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IGNoYW5nZUVycm9yXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgYXdhaXQgTWlncmF0aW9uc0xlZGdlci5yZWNvcmRWZXJzaW9uKGRiLCBkYXRlU3RyaW5nKVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBhd2FpdCBtaWdyYXRpb25JbnN0YW5jZS5kb3duKClcbiAgICAgICAgICAgIH0gY2F0Y2ggKGRvd25FcnJvcikge1xuICAgICAgICAgICAgICBpZiAoZG93bkVycm9yIGluc3RhbmNlb2YgTm90SW1wbGVtZW50ZWRFcnJvcikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJ2Rvd24nIGRpZG4ndCBleGlzdCBvbiBtaWdyYXRpb246ICR7bWlncmF0aW9uLmZpbGV9IG9yIG1pZ3JhdGluZyBkb3duIHdpdGggYSBjaGFuZ2UgbWV0aG9kIGlzbid0IGN1cnJlbnRseSBzdXBwb3J0ZWRgLCB7Y2F1c2U6IGRvd25FcnJvcn0pXG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgZG93bkVycm9yXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgYXdhaXQgTWlncmF0aW9uc0xlZGdlci5yZW1vdmVWZXJzaW9uKGRiLCBkYXRlU3RyaW5nKVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH0sXG4gICAgICAgIC8vIFBpbiB0aGUgbG9jayB0byBvbmUgcGh5c2ljYWwgc2Vzc2lvbjogTVNTUUwvZXhwbGljaXQgYWR2aXNvcnkgbG9ja3MgYXJlXG4gICAgICAgIC8vIHNlc3Npb24tc2NvcGVkLCBhbmQgYSBwb29sZWQgY29ubmVjdGlvbiBjYW4gcm91dGUgYWNxdWlyZSBhbmQgcmVsZWFzZSB0b1xuICAgICAgICAvLyBkaWZmZXJlbnQgc2Vzc2lvbnMsIHdoaWNoIHdvdWxkIGxldCB0d28gcHJvY2Vzc2VzIGJvdGggXCJob2xkXCIgdGhlIGxvY2suXG4gICAgICAgIHtkZWRpY2F0ZWRDb25uZWN0aW9uOiB0cnVlfVxuICAgICAgKVxuXG4gICAgICBpZiAoIWFwcGxpZWRJbkxvY2spIGNvbnRpbnVlXG5cbiAgICAgIGFwcGxpZWQgPSB0cnVlXG4gICAgfVxuXG4gICAgcmV0dXJuIGFwcGxpZWRcbiAgfVxufVxuIl19
|
package/package.json
CHANGED
package/src/configuration.js
CHANGED
|
@@ -273,6 +273,7 @@ export default class VelociousConfiguration {
|
|
|
273
273
|
* served this lock" surface (design §3).
|
|
274
274
|
* @type {Map<string, {backend: import("./database/advisory-lock-backend-policy.js").AdvisoryLockTier, fencingSupported: boolean, servedAt: string}>} */
|
|
275
275
|
_advisoryLockAcquisitions = new Map()
|
|
276
|
+
_advisoryLockReentries = new Map()
|
|
276
277
|
|
|
277
278
|
/** @type {Map<string, number>} */
|
|
278
279
|
_schemaCacheGenerationsByReuseKey = new Map()
|
|
@@ -4355,19 +4356,36 @@ export default class VelociousConfiguration {
|
|
|
4355
4356
|
this._advisoryLockAcquisitions.set(lockName, {backend, fencingSupported, servedAt: new Date().toISOString()})
|
|
4356
4357
|
}
|
|
4357
4358
|
|
|
4359
|
+
/**
|
|
4360
|
+
* Counts one re-entry of an advisory lock the calling async context already
|
|
4361
|
+
* holds (`Monitor` semantics, see `advisory-lock-runner.js`).
|
|
4362
|
+
*
|
|
4363
|
+
* This is the measurement that decides whether a hand-passed `*LockHeld`
|
|
4364
|
+
* boolean is still load-bearing: a name whose reentries stay at zero over a
|
|
4365
|
+
* real workload is not nesting at all, while a name that reenters is one
|
|
4366
|
+
* where the framework now owns the depth and the application flag can go.
|
|
4367
|
+
* @param {object} args - Re-entry record.
|
|
4368
|
+
* @param {string} args.lockName - Lock name.
|
|
4369
|
+
* @returns {void}
|
|
4370
|
+
*/
|
|
4371
|
+
recordAdvisoryLockReentry({lockName}) {
|
|
4372
|
+
this._advisoryLockReentries.set(lockName, (this._advisoryLockReentries.get(lockName) ?? 0) + 1)
|
|
4373
|
+
}
|
|
4374
|
+
|
|
4358
4375
|
/**
|
|
4359
4376
|
* The "which backend served this lock" diagnostics surface (design §3):
|
|
4360
4377
|
* per lock name, the tier of the most recent acquisition, whether that tier
|
|
4361
4378
|
* carries fencing tokens, and the resolved policy (minimum/allowed/preferred
|
|
4362
4379
|
* tiers) for the name.
|
|
4363
4380
|
* @param {string} lockName - Lock name.
|
|
4364
|
-
* @returns {{acquisition: {backend: import("./database/advisory-lock-backend-policy.js").AdvisoryLockTier, fencingSupported: boolean, servedAt: string} | null, lockServer: {connected: boolean, lastError: string | null, lastProbeAt: string | null, leasedNames: string[]} | null, policy: import("./database/advisory-lock-backend-policy.js").ResolvedAdvisoryLockBackendPolicy}} - Backend status for the name.
|
|
4381
|
+
* @returns {{acquisition: {backend: import("./database/advisory-lock-backend-policy.js").AdvisoryLockTier, fencingSupported: boolean, servedAt: string} | null, lockServer: {connected: boolean, lastError: string | null, lastProbeAt: string | null, leasedNames: string[]} | null, policy: import("./database/advisory-lock-backend-policy.js").ResolvedAdvisoryLockBackendPolicy, reentries: number}} - Backend status for the name.
|
|
4365
4382
|
*/
|
|
4366
4383
|
getAdvisoryLockBackendStatus(lockName) {
|
|
4367
4384
|
return {
|
|
4368
4385
|
acquisition: this._advisoryLockAcquisitions.get(lockName) ?? null,
|
|
4369
4386
|
lockServer: this._advisoryLockLockServerBackend?.getStatus() ?? null,
|
|
4370
|
-
policy: this.resolveAdvisoryLockPolicy(lockName)
|
|
4387
|
+
policy: this.resolveAdvisoryLockPolicy(lockName),
|
|
4388
|
+
reentries: this._advisoryLockReentries.get(lockName) ?? 0
|
|
4371
4389
|
}
|
|
4372
4390
|
}
|
|
4373
4391
|
|
|
@@ -59,7 +59,7 @@ export default class AdvisoryLockFileBackend {
|
|
|
59
59
|
this.pathStyle = pathStyle
|
|
60
60
|
this.pollIntervalMs = pollIntervalMs
|
|
61
61
|
this.holderId = `${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`
|
|
62
|
-
/** @type {Map<string, {timer: ReturnType<typeof setInterval>}>} */
|
|
62
|
+
/** @type {Map<string, {depth: number, timer: ReturnType<typeof setInterval>}>} */
|
|
63
63
|
this.holdsByName = new Map()
|
|
64
64
|
}
|
|
65
65
|
|
|
@@ -113,7 +113,17 @@ export default class AdvisoryLockFileBackend {
|
|
|
113
113
|
* @returns {Promise<boolean>} - True when this backend became the lock owner.
|
|
114
114
|
*/
|
|
115
115
|
async tryAcquire(name) {
|
|
116
|
-
|
|
116
|
+
// Already held by this backend instance: a re-entrant acquisition
|
|
117
|
+
// (`Monitor` semantics) adds a level instead of contending with itself.
|
|
118
|
+
// Refusing it made a nested hold time out on this tier while the same
|
|
119
|
+
// nesting worked on the database tiers.
|
|
120
|
+
const existingHold = this.holdsByName.get(name)
|
|
121
|
+
|
|
122
|
+
if (existingHold) {
|
|
123
|
+
existingHold.depth += 1
|
|
124
|
+
|
|
125
|
+
return true
|
|
126
|
+
}
|
|
117
127
|
|
|
118
128
|
await this.ensureDirectory()
|
|
119
129
|
|
|
@@ -141,6 +151,14 @@ export default class AdvisoryLockFileBackend {
|
|
|
141
151
|
|
|
142
152
|
if (!hold) return false
|
|
143
153
|
|
|
154
|
+
// One release per acquisition: a re-entrant hold keeps the lock until its
|
|
155
|
+
// outermost level releases, exactly like the database tiers.
|
|
156
|
+
if (hold.depth > 1) {
|
|
157
|
+
hold.depth -= 1
|
|
158
|
+
|
|
159
|
+
return true
|
|
160
|
+
}
|
|
161
|
+
|
|
144
162
|
this.clearHold(name)
|
|
145
163
|
|
|
146
164
|
const owner = await this.readOwner(this.lockPathFor(name))
|
|
@@ -236,7 +254,7 @@ export default class AdvisoryLockFileBackend {
|
|
|
236
254
|
|
|
237
255
|
if (typeof timer.unref === "function") timer.unref()
|
|
238
256
|
|
|
239
|
-
this.holdsByName.set(name, {timer})
|
|
257
|
+
this.holdsByName.set(name, {depth: 1, timer})
|
|
240
258
|
|
|
241
259
|
return true
|
|
242
260
|
}
|
|
@@ -15,7 +15,7 @@ import {AdvisoryLockServiceUnavailableError} from "./advisory-lock-errors.js"
|
|
|
15
15
|
* @property {(type: string, args: {onMessage: (body: Record<string, unknown>) => void, params: Record<string, unknown>, timeoutMs: number}) => LockServerConnectionLike} openConnection - Opens the 1:1 connection.
|
|
16
16
|
* @property {() => Promise<void> | void} [close] - Closes the transport.
|
|
17
17
|
* @typedef {{epoch: number, name: string, timer: ReturnType<typeof setInterval>, leaseExpiresAt: number}} LockServerHold
|
|
18
|
-
* @typedef {{status: "acquired", epoch: number, leaseExpiresAt: number} | {status: "busy"} | {status: "timeout"}} LockServerAcquireResult
|
|
18
|
+
* @typedef {{status: "acquired", epoch: number, leaseExpiresAt: number} | {status: "already-held", epoch: number, leaseExpiresAt: number} | {status: "busy"} | {status: "timeout"}} LockServerAcquireResult
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
/** Protocol version spoken by the centralized lock server (consens-lock v2). */
|
|
@@ -181,6 +181,16 @@ export default class AdvisoryLockLockServerBackend {
|
|
|
181
181
|
return true
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
+
// `already-held` means the server says *this connection* already owns the
|
|
185
|
+
// lease: a re-entrant acquisition (`Monitor` semantics), not contention.
|
|
186
|
+
// Reporting it as "not acquired" is what turned every nested hold into a
|
|
187
|
+
// timeout once a name moved to this tier.
|
|
188
|
+
if (result.status === "already-held") {
|
|
189
|
+
this.startRenewal(name, result.epoch)
|
|
190
|
+
|
|
191
|
+
return true
|
|
192
|
+
}
|
|
193
|
+
|
|
184
194
|
if (result.status === "busy") return false
|
|
185
195
|
|
|
186
196
|
return false
|
|
@@ -197,7 +207,7 @@ export default class AdvisoryLockLockServerBackend {
|
|
|
197
207
|
/** @type {LockServerAcquireResult} */
|
|
198
208
|
const result = /** @type {LockServerAcquireResult} */ (await this.request("try-acquire", {name}))
|
|
199
209
|
|
|
200
|
-
if (result.status !== "acquired") return false
|
|
210
|
+
if (result.status !== "acquired" && result.status !== "already-held") return false
|
|
201
211
|
|
|
202
212
|
this.startRenewal(name, result.epoch)
|
|
203
213
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
|
+
import {AsyncLocalStorage} from "node:async_hooks"
|
|
3
4
|
import timeout, {TimeoutError} from "awaitery/build/timeout.js"
|
|
4
5
|
import {DEFAULT_ADVISORY_LOCK_ACQUIRE_TIMEOUT_MS} from "./advisory-lock-bound.js"
|
|
5
6
|
import {
|
|
@@ -59,6 +60,27 @@ class AdvisoryLockBusyError extends Error {
|
|
|
59
60
|
}
|
|
60
61
|
}
|
|
61
62
|
|
|
63
|
+
/**
|
|
64
|
+
* Advisory locks held by one async context, keyed by
|
|
65
|
+
* `<databaseIdentifier>\u0000<lock name>` and carrying the re-entry depth plus
|
|
66
|
+
* the provenance of the tier that actually holds the lock.
|
|
67
|
+
*
|
|
68
|
+
* Re-entry is scoped to the async context, not to the process: a nested call
|
|
69
|
+
* made inside a held callback belongs to the same logical operation and must
|
|
70
|
+
* not contend with itself, while an unrelated concurrent request in the same
|
|
71
|
+
* process is a different context and must still wait. That is Ruby's `Monitor`
|
|
72
|
+
* ("re-entrant for the holding thread") expressed with the async-context
|
|
73
|
+
* analogue of a thread.
|
|
74
|
+
*
|
|
75
|
+
* Without this, the four tiers disagreed on re-entry: a nested acquisition on
|
|
76
|
+
* a `dedicatedConnection` opened a second connection and self-deadlocked, the
|
|
77
|
+
* file tier refused it as held, and the lock-server tier received
|
|
78
|
+
* `already-held` and treated it as contention. Applications worked around it
|
|
79
|
+
* with hand-passed `*LockHeld` booleans, which is exactly the parameter a
|
|
80
|
+
* monitor makes redundant.
|
|
81
|
+
*/
|
|
82
|
+
const heldAdvisoryLocks = new AsyncLocalStorage()
|
|
83
|
+
|
|
62
84
|
/**
|
|
63
85
|
* Thrown when a callback holds an advisory lock longer than `holdTimeoutMs`.
|
|
64
86
|
*/
|
|
@@ -107,6 +129,10 @@ export default class AdvisoryLockRunner {
|
|
|
107
129
|
* @returns {Promise<T>} - Resolves with the callback result.
|
|
108
130
|
*/
|
|
109
131
|
async withAdvisoryLock(name, callback, args = {}) {
|
|
132
|
+
const heldEntry = this.heldEntryFor(name)
|
|
133
|
+
|
|
134
|
+
if (heldEntry) return await this.runReentrantCallback({callback, entry: heldEntry, name})
|
|
135
|
+
|
|
110
136
|
const lockServerResult = await this.attemptLockServer({args, callback, mode: "wait", name})
|
|
111
137
|
|
|
112
138
|
// The wait mode never returns a deferred outcome, so the value member is present.
|
|
@@ -159,6 +185,10 @@ export default class AdvisoryLockRunner {
|
|
|
159
185
|
* @returns {Promise<T>} - Resolves with the callback result.
|
|
160
186
|
*/
|
|
161
187
|
async withAdvisoryLockOrFail(name, callback, args = {}) {
|
|
188
|
+
const heldEntry = this.heldEntryFor(name)
|
|
189
|
+
|
|
190
|
+
if (heldEntry) return await this.runReentrantCallback({callback, entry: heldEntry, name})
|
|
191
|
+
|
|
162
192
|
const lockServerResult = await this.attemptLockServer({args, callback, mode: "or-fail", name})
|
|
163
193
|
|
|
164
194
|
// The or-fail mode throws on contention, so the value member is present.
|
|
@@ -218,6 +248,10 @@ export default class AdvisoryLockRunner {
|
|
|
218
248
|
* @returns {Promise<{acquired: true, result: T} | {acquired: false, reason: "contended", lockName: string}>} - Either the held-callback result or the defer outcome.
|
|
219
249
|
*/
|
|
220
250
|
async withAdvisoryLockOrDefer(name, callback, args = {}) {
|
|
251
|
+
const heldEntry = this.heldEntryFor(name)
|
|
252
|
+
|
|
253
|
+
if (heldEntry) return {acquired: true, result: await this.runReentrantCallback({callback, entry: heldEntry, name})}
|
|
254
|
+
|
|
221
255
|
const lockServerResult = await this.attemptLockServer({args, callback, mode: "defer", name})
|
|
222
256
|
|
|
223
257
|
if (lockServerResult) {
|
|
@@ -266,13 +300,69 @@ export default class AdvisoryLockRunner {
|
|
|
266
300
|
* @returns {Promise<T>} - Resolves with the callback result.
|
|
267
301
|
*/
|
|
268
302
|
async runLockedCallback({callback, holdTimeoutMs, lockBackend, name, release}) {
|
|
303
|
+
const store = new Map(heldAdvisoryLocks.getStore() ?? [])
|
|
304
|
+
|
|
305
|
+
store.set(this.lockStorageKey(name), {depth: 1, lockBackend})
|
|
306
|
+
|
|
269
307
|
try {
|
|
270
|
-
|
|
308
|
+
// The lock is released outside the context scope: a release path that
|
|
309
|
+
// touches the same name (a cleanup hook, an error reporter) must not look
|
|
310
|
+
// like a re-entry of a hold that is already over.
|
|
311
|
+
return await heldAdvisoryLocks.run(store, async () => await AdvisoryLockRunner.runWithAdvisoryLockHoldTimeout(name, callback, holdTimeoutMs, lockBackend))
|
|
271
312
|
} finally {
|
|
272
313
|
await release()
|
|
273
314
|
}
|
|
274
315
|
}
|
|
275
316
|
|
|
317
|
+
/**
|
|
318
|
+
* Returns the held entry when this async context already holds the lock.
|
|
319
|
+
* @param {string} name - Lock name.
|
|
320
|
+
* @returns {{depth: number, lockBackend: AdvisoryLockBackendProvenance} | null} - The held entry, or null when this context does not hold the lock.
|
|
321
|
+
*/
|
|
322
|
+
heldEntryFor(name) {
|
|
323
|
+
const store = heldAdvisoryLocks.getStore()
|
|
324
|
+
|
|
325
|
+
if (!store) return null
|
|
326
|
+
|
|
327
|
+
return store.get(this.lockStorageKey(name)) ?? null
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Runs a callback as a re-entry of a lock this async context already holds.
|
|
332
|
+
*
|
|
333
|
+
* The re-entry adds no backend round trip and cannot fail on contention: the
|
|
334
|
+
* outer hold already owns the lock, so mutual exclusion is unchanged. The
|
|
335
|
+
* outer hold owns the hold timeout and the lease; a re-entry does not start a
|
|
336
|
+
* second one, and the callback therefore receives the outer provenance without
|
|
337
|
+
* a `control`.
|
|
338
|
+
* @template T
|
|
339
|
+
* @param {{callback: (args?: {control?: import("awaitery/build/timeout.js").TimeoutControl, lockBackend: AdvisoryLockBackendProvenance}) => Promise<T>, entry: {depth: number, lockBackend: AdvisoryLockBackendProvenance}, name: string}} args - Re-entry request.
|
|
340
|
+
* @returns {Promise<T>} - Callback result.
|
|
341
|
+
*/
|
|
342
|
+
async runReentrantCallback({callback, entry, name}) {
|
|
343
|
+
entry.depth += 1
|
|
344
|
+
this.configuration.recordAdvisoryLockReentry({lockName: name})
|
|
345
|
+
|
|
346
|
+
try {
|
|
347
|
+
return await callback({lockBackend: entry.lockBackend})
|
|
348
|
+
} finally {
|
|
349
|
+
entry.depth -= 1
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Builds the async-context storage key for one lock name.
|
|
355
|
+
*
|
|
356
|
+
* The database identifier is part of the key because it is part of the lock's
|
|
357
|
+
* identity: two tenant databases reusing one name hold two different locks,
|
|
358
|
+
* and a nested call in the other database is not a re-entry.
|
|
359
|
+
* @param {string} name - Lock name.
|
|
360
|
+
* @returns {string} - Storage key for the held-entry map.
|
|
361
|
+
*/
|
|
362
|
+
lockStorageKey(name) {
|
|
363
|
+
return `${this.databaseIdentifier}\u0000${name}`
|
|
364
|
+
}
|
|
365
|
+
|
|
276
366
|
/**
|
|
277
367
|
* Serves one acquisition on the lock-server tier when the lock name prefers
|
|
278
368
|
* it (design §1/§9), falling *upward* to the driver path when the server is
|
package/src/database/migrator.js
CHANGED
|
@@ -63,11 +63,11 @@ export default class VelociousDatabaseMigrator {
|
|
|
63
63
|
* @returns {Promise<void>} - Resolves when complete.
|
|
64
64
|
*/
|
|
65
65
|
async prepare() {
|
|
66
|
-
|
|
66
|
+
this.logger.debug("prepare() start")
|
|
67
67
|
await this.createMigrationsTable()
|
|
68
|
-
|
|
68
|
+
this.logger.debug("createMigrationsTable done")
|
|
69
69
|
await this.loadMigrationsVersions()
|
|
70
|
-
|
|
70
|
+
this.logger.debug("prepare() done")
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
/**
|
|
@@ -552,7 +552,7 @@ export default class VelociousDatabaseMigrator {
|
|
|
552
552
|
*/
|
|
553
553
|
async runMigrationFile({migration, requireMigration, direction = "up"}) {
|
|
554
554
|
if (!this.configuration) throw new Error("No configuration set")
|
|
555
|
-
|
|
555
|
+
this.logger.debug("runMigrationFile", {file: migration && migration.file})
|
|
556
556
|
if (!this.configuration.isDatabasePoolInitialized()) await this.configuration.initializeDatabasePool()
|
|
557
557
|
if (!this.migrationsVersions) await this.loadMigrationsVersions()
|
|
558
558
|
|
|
@@ -617,7 +617,7 @@ export default class VelociousDatabaseMigrator {
|
|
|
617
617
|
//
|
|
618
618
|
// The version is re-read *inside* the lock: while this process waited, another process
|
|
619
619
|
// may already have applied the migration, in which case this one must become a no-op.
|
|
620
|
-
|
|
620
|
+
this.logger.debug("acquiring migration advisory lock", {databaseIdentifier: dbIdentifier, file: migration.file})
|
|
621
621
|
const runner = new AdvisoryLockRunner({
|
|
622
622
|
configuration: this.configuration,
|
|
623
623
|
connectionProvider: () => db,
|