velocious 1.0.301 → 1.0.303

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 CHANGED
@@ -649,6 +649,29 @@ await project.loadTasks()
649
649
  const tasks = project.tasks().loaded()
650
650
  ```
651
651
 
652
+ ## Through relationships
653
+
654
+ Use the `through` option on `hasMany` to define a relationship that traverses an intermediate (join) table:
655
+
656
+ ```js
657
+ Invoice.hasMany("invoiceGroupLinks")
658
+ Invoice.hasMany("invoiceGroups", {through: "invoiceGroupLinks", className: "InvoiceGroup"})
659
+ ```
660
+
661
+ Through relationships work with both instance-level loading and batch preloading:
662
+
663
+ ```js
664
+ // Instance-level loading
665
+ const invoice = await Invoice.find(1)
666
+ const groups = await invoice.invoiceGroups().toArray()
667
+
668
+ // Batch preloading
669
+ const invoices = await Invoice.preload({invoiceGroups: true}).toArray()
670
+ const groups = invoices[0].invoiceGroupsLoaded()
671
+ ```
672
+
673
+ The intermediate relationship (e.g. `invoiceGroupLinks`) must be defined as a separate `hasMany` on the same model. The `foreignKey` option on the through relationship specifies the column on the target table that points to the intermediate table (defaults to the conventional foreign key).
674
+
652
675
  ## Relationship scopes
653
676
 
654
677
  You can pass a scope callback to `hasMany`, `hasOne`, or `belongsTo` to add custom filters. The callback receives the query and is also bound as `this`:
@@ -10,6 +10,19 @@ export default class VelociousDatabaseQueryPreloaderHasMany {
10
10
  });
11
11
  models: import("../../record/index.js").default[];
12
12
  relationship: import("../../record/relationships/has-many.js").default;
13
+ /** @returns {Promise<import("../../record/index.js").default[]>} - Loaded target models. */
13
14
  run(): Promise<import("../../record/index.js").default[]>;
15
+ /**
16
+ * Preload through a join table (e.g. hasMany("invoiceGroups", {through: "invoiceGroupLinks"})).
17
+ *
18
+ * @returns {Promise<import("../../record/index.js").default[]>} - Loaded target models.
19
+ */
20
+ _runThrough(): Promise<import("../../record/index.js").default[]>;
21
+ /**
22
+ * Preload direct has-many relationships.
23
+ *
24
+ * @returns {Promise<import("../../record/index.js").default[]>} - Loaded target models.
25
+ */
26
+ _runDirect(): Promise<import("../../record/index.js").default[]>;
14
27
  }
15
28
  //# sourceMappingURL=has-many.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"has-many.d.ts","sourceRoot":"","sources":["../../../../../src/database/query/preloader/has-many.js"],"names":[],"mappings":"AAIA;IACE;;;;OAIG;IACH,mDAHG;QAAwD,MAAM,EAAtD,OAAO,uBAAuB,EAAE,OAAO,EAAE;QACsB,YAAY,EAA3E,OAAO,wCAAwC,EAAE,OAAO;KAClE,EAMA;IAFC,kDAAoB;IACpB,uEAAgC;IAGlC,0DA0EC;CACF"}
1
+ {"version":3,"file":"has-many.d.ts","sourceRoot":"","sources":["../../../../../src/database/query/preloader/has-many.js"],"names":[],"mappings":"AAIA;IACE;;;;OAIG;IACH,mDAHG;QAAwD,MAAM,EAAtD,OAAO,uBAAuB,EAAE,OAAO,EAAE;QACsB,YAAY,EAA3E,OAAO,wCAAwC,EAAE,OAAO;KAClE,EAMA;IAFC,kDAAoB;IACpB,uEAAgC;IAGlC,4FAA4F;IAC5F,OADc,OAAO,CAAC,OAAO,uBAAuB,EAAE,OAAO,EAAE,CAAC,CAO/D;IAED;;;;OAIG;IACH,eAFa,OAAO,CAAC,OAAO,uBAAuB,EAAE,OAAO,EAAE,CAAC,CAwH9D;IAED;;;;OAIG;IACH,cAFa,OAAO,CAAC,OAAO,uBAAuB,EAAE,OAAO,EAAE,CAAC,CA0E9D;CACF"}
@@ -11,7 +11,115 @@ export default class VelociousDatabaseQueryPreloaderHasMany {
11
11
  this.models = models;
12
12
  this.relationship = relationship;
13
13
  }
14
+ /** @returns {Promise<import("../../record/index.js").default[]>} - Loaded target models. */
14
15
  async run() {
16
+ if (this.relationship.through) {
17
+ return await this._runThrough();
18
+ }
19
+ return await this._runDirect();
20
+ }
21
+ /**
22
+ * Preload through a join table (e.g. hasMany("invoiceGroups", {through: "invoiceGroupLinks"})).
23
+ *
24
+ * @returns {Promise<import("../../record/index.js").default[]>} - Loaded target models.
25
+ */
26
+ async _runThrough() {
27
+ const primaryKey = this.relationship.getPrimaryKey();
28
+ if (!primaryKey) {
29
+ throw new Error(`${this.relationship.getModelClass().name}#${this.relationship.getRelationshipName()} doesn't have a primary key`);
30
+ }
31
+ const throughRelationshipName = /** @type {string} */ (this.relationship.through);
32
+ const parentModelClass = this.relationship.getModelClass();
33
+ const throughRelationship = parentModelClass.getRelationshipByName(throughRelationshipName);
34
+ const throughModelClass = throughRelationship.getTargetModelClass();
35
+ if (!throughModelClass)
36
+ throw new Error(`Through relationship ${throughRelationshipName} has no target model class`);
37
+ const targetModelClass = this.relationship.getTargetModelClass();
38
+ if (!targetModelClass)
39
+ throw new Error("No target model class could be gotten from relationship");
40
+ const throughForeignKey = throughRelationship.getForeignKey();
41
+ /** @type {Array<number | string>} */
42
+ const modelsPrimaryKeyValues = [];
43
+ /** @type {Record<number | string, Array<import("../../record/index.js").default>>} */
44
+ const modelsByPrimaryKeyValue = {};
45
+ /** @type {Record<number | string, Array<import("../../record/index.js").default>>} */
46
+ const preloadCollections = {};
47
+ for (const model of this.models) {
48
+ const primaryKeyValue = /** @type {string | number} */ (model.readColumn(primaryKey));
49
+ preloadCollections[primaryKeyValue] = [];
50
+ if (!modelsPrimaryKeyValues.includes(primaryKeyValue))
51
+ modelsPrimaryKeyValues.push(primaryKeyValue);
52
+ if (!(primaryKeyValue in modelsByPrimaryKeyValue))
53
+ modelsByPrimaryKeyValue[primaryKeyValue] = [];
54
+ modelsByPrimaryKeyValue[primaryKeyValue].push(model);
55
+ }
56
+ // Step 1: Query the through table to build parent→target ID mapping
57
+ const throughModels = await throughModelClass
58
+ .where({ [throughForeignKey]: modelsPrimaryKeyValues })
59
+ .toArray();
60
+ /** @type {Record<string | number, Array<string | number>>} */
61
+ const parentToTargetIds = {};
62
+ /** @type {Set<string | number>} */
63
+ const allTargetIds = new Set();
64
+ const targetForeignKey = this.relationship.getForeignKey();
65
+ for (const throughModel of throughModels) {
66
+ const parentId = /** @type {string | number} */ (throughModel.readColumn(throughForeignKey));
67
+ const throughId = /** @type {string | number} */ (throughModel.readColumn(throughModelClass.primaryKey()));
68
+ if (!(parentId in parentToTargetIds))
69
+ parentToTargetIds[parentId] = [];
70
+ parentToTargetIds[parentId].push(throughId);
71
+ allTargetIds.add(throughId);
72
+ }
73
+ // Step 2: Load target models by the foreign key that points to the through table
74
+ /** @type {import("../../record/index.js").default[]} */
75
+ let targetModels = [];
76
+ if (allTargetIds.size > 0) {
77
+ let query = targetModelClass.where({ [targetForeignKey]: [...allTargetIds] });
78
+ query = this.relationship.applyScope(query);
79
+ targetModels = await query.toArray();
80
+ }
81
+ // Step 3: Index target models by their foreign key (maps to through model ID)
82
+ /** @type {Record<string | number, Array<import("../../record/index.js").default>>} */
83
+ const targetModelsByForeignKey = {};
84
+ for (const targetModel of targetModels) {
85
+ const fkValue = /** @type {string | number} */ (targetModel.readColumn(targetForeignKey));
86
+ if (!(fkValue in targetModelsByForeignKey))
87
+ targetModelsByForeignKey[fkValue] = [];
88
+ targetModelsByForeignKey[fkValue].push(targetModel);
89
+ }
90
+ // Step 4: Map targets to parents via the through mapping
91
+ for (const parentId in parentToTargetIds) {
92
+ const throughIds = parentToTargetIds[parentId];
93
+ for (const throughId of throughIds) {
94
+ const matchingTargets = targetModelsByForeignKey[throughId] || [];
95
+ for (const targetModel of matchingTargets) {
96
+ if (parentId in preloadCollections) {
97
+ preloadCollections[parentId].push(targetModel);
98
+ }
99
+ }
100
+ }
101
+ }
102
+ for (const modelValue in preloadCollections) {
103
+ const preloadedCollection = preloadCollections[modelValue];
104
+ for (const model of modelsByPrimaryKeyValue[modelValue]) {
105
+ const modelRelationship = model.getRelationshipByName(this.relationship.getRelationshipName());
106
+ if (preloadedCollection.length == 0) {
107
+ modelRelationship.setLoaded([]);
108
+ }
109
+ else {
110
+ modelRelationship.addToLoaded(preloadedCollection);
111
+ }
112
+ modelRelationship.setPreloaded(true);
113
+ }
114
+ }
115
+ return targetModels;
116
+ }
117
+ /**
118
+ * Preload direct has-many relationships.
119
+ *
120
+ * @returns {Promise<import("../../record/index.js").default[]>} - Loaded target models.
121
+ */
122
+ async _runDirect() {
15
123
  /** @type {Array<number | string>} */
16
124
  const modelsPrimaryKeyValues = [];
17
125
  /** @type {Record<number | string, Array<import("../../record/index.js").default>>} */
@@ -42,7 +150,6 @@ export default class VelociousDatabaseQueryPreloaderHasMany {
42
150
  const targetModelClass = this.relationship.getTargetModelClass();
43
151
  if (!targetModelClass)
44
152
  throw new Error("No target model class could be gotten from relationship");
45
- // Load target models to be preloaded on the given models
46
153
  let query = targetModelClass.where(whereArgs);
47
154
  query = this.relationship.applyScope(query);
48
155
  const targetModels = await query.toArray();
@@ -50,7 +157,6 @@ export default class VelociousDatabaseQueryPreloaderHasMany {
50
157
  const foreignKeyValue = /** @type {string | number} */ (targetModel.readColumn(foreignKey));
51
158
  preloadCollections[foreignKeyValue].push(targetModel);
52
159
  }
53
- // Set the target preloaded models on the given models
54
160
  for (const modelValue in preloadCollections) {
55
161
  const preloadedCollection = preloadCollections[modelValue];
56
162
  for (const model of modelsByPrimaryKeyValue[modelValue]) {
@@ -67,4 +173,4 @@ export default class VelociousDatabaseQueryPreloaderHasMany {
67
173
  return targetModels;
68
174
  }
69
175
  }
70
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGFzLW1hbnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvZGF0YWJhc2UvcXVlcnkvcHJlbG9hZGVyL2hhcy1tYW55LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLGFBQWEsTUFBTSxtQ0FBbUMsQ0FBQTtBQUU3RCxNQUFNLENBQUMsT0FBTyxPQUFPLHNDQUFzQztJQUN6RDs7OztPQUlHO0lBQ0gsWUFBWSxFQUFDLE1BQU0sRUFBRSxZQUFZLEVBQUUsR0FBRyxRQUFRLEVBQUM7UUFDN0MsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFBO1FBRXZCLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFBO1FBQ3BCLElBQUksQ0FBQyxZQUFZLEdBQUcsWUFBWSxDQUFBO0lBQ2xDLENBQUM7SUFFRCxLQUFLLENBQUMsR0FBRztRQUNQLHFDQUFxQztRQUNyQyxNQUFNLHNCQUFzQixHQUFHLEVBQUUsQ0FBQTtRQUVqQyxzRkFBc0Y7UUFDdEYsTUFBTSx1QkFBdUIsR0FBRyxFQUFFLENBQUE7UUFFbEMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxhQUFhLEVBQUUsQ0FBQTtRQUNwRCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsRUFBRSxDQUFBO1FBRXBELHNGQUFzRjtRQUN0RixNQUFNLGtCQUFrQixHQUFHLEVBQUUsQ0FBQTtRQUU3QixJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDaEIsTUFBTSxJQUFJLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsYUFBYSxFQUFFLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsbUJBQW1CLEVBQUUsNkJBQTZCLENBQUMsQ0FBQTtRQUNwSSxDQUFDO1FBRUQsS0FBSyxNQUFNLEtBQUssSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDaEMsTUFBTSxlQUFlLEdBQUcsOEJBQThCLENBQUMsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUE7WUFFckYsa0JBQWtCLENBQUMsZUFBZSxDQUFDLEdBQUcsRUFBRSxDQUFBO1lBRXhDLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDO2dCQUFFLHNCQUFzQixDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQTtZQUNuRyxJQUFJLENBQUMsQ0FBQyxlQUFlLElBQUksdUJBQXVCLENBQUM7Z0JBQUUsdUJBQXVCLENBQUMsZUFBZSxDQUFDLEdBQUcsRUFBRSxDQUFBO1lBRWhHLHVCQUF1QixDQUFDLGVBQWUsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUN0RCxDQUFDO1FBRUQsdUVBQXVFO1FBQ3ZFLE1BQU0sU0FBUyxHQUFHLEVBQUUsQ0FBQTtRQUVwQixTQUFTLENBQUMsVUFBVSxDQUFDLEdBQUcsc0JBQXNCLENBQUE7UUFFOUMsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLGNBQWMsRUFBRSxFQUFFLENBQUM7WUFDdkMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyx3QkFBd0IsRUFBRSxDQUFBO1lBRS9ELFNBQVMsQ0FBQyxVQUFVLENBQUMsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsRUFBRSxDQUFDLFlBQVksRUFBRSxDQUFBO1FBQzFFLENBQUM7UUFFRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsbUJBQW1CLEVBQUUsQ0FBQTtRQUVoRSxJQUFJLENBQUMsZ0JBQWdCO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyx5REFBeUQsQ0FBQyxDQUFBO1FBRWpHLHlEQUF5RDtRQUN6RCxJQUFJLEtBQUssR0FBRyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUE7UUFFN0MsS0FBSyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBRTNDLE1BQU0sWUFBWSxHQUFHLE1BQU0sS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFBO1FBRTFDLEtBQUssTUFBTSxXQUFXLElBQUksWUFBWSxFQUFFLENBQUM7WUFDdkMsTUFBTSxlQUFlLEdBQUcsOEJBQThCLENBQUMsQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUE7WUFFM0Ysa0JBQWtCLENBQUMsZUFBZSxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFBO1FBQ3ZELENBQUM7UUFFRCxzREFBc0Q7UUFDdEQsS0FBSyxNQUFNLFVBQVUsSUFBSSxrQkFBa0IsRUFBRSxDQUFDO1lBQzVDLE1BQU0sbUJBQW1CLEdBQUcsa0JBQWtCLENBQUMsVUFBVSxDQUFDLENBQUE7WUFFMUQsS0FBSyxNQUFNLEtBQUssSUFBSSx1QkFBdUIsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO2dCQUN4RCxNQUFNLGlCQUFpQixHQUFHLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLG1CQUFtQixFQUFFLENBQUMsQ0FBQTtnQkFFOUYsSUFBSSxtQkFBbUIsQ0FBQyxNQUFNLElBQUksQ0FBQyxFQUFFLENBQUM7b0JBQ3BDLGlCQUFpQixDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQTtnQkFDakMsQ0FBQztxQkFBTSxDQUFDO29CQUNOLGlCQUFpQixDQUFDLFdBQVcsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFBO2dCQUNwRCxDQUFDO2dCQUVELGlCQUFpQixDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQTtZQUN0QyxDQUFDO1FBQ0gsQ0FBQztRQUVELE9BQU8sWUFBWSxDQUFBO0lBQ3JCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgcmVzdEFyZ3NFcnJvciBmcm9tIFwiLi4vLi4vLi4vdXRpbHMvcmVzdC1hcmdzLWVycm9yLmpzXCJcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVmVsb2Npb3VzRGF0YWJhc2VRdWVyeVByZWxvYWRlckhhc01hbnkge1xuICAvKipcbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdFtdfSBhcmdzLm1vZGVscyAtIE1vZGVsIGluc3RhbmNlcy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9yZWNvcmQvcmVsYXRpb25zaGlwcy9oYXMtbWFueS5qc1wiKS5kZWZhdWx0fSBhcmdzLnJlbGF0aW9uc2hpcCAtIFJlbGF0aW9uc2hpcC5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHttb2RlbHMsIHJlbGF0aW9uc2hpcCwgLi4ucmVzdEFyZ3N9KSB7XG4gICAgcmVzdEFyZ3NFcnJvcihyZXN0QXJncylcblxuICAgIHRoaXMubW9kZWxzID0gbW9kZWxzXG4gICAgdGhpcy5yZWxhdGlvbnNoaXAgPSByZWxhdGlvbnNoaXBcbiAgfVxuXG4gIGFzeW5jIHJ1bigpIHtcbiAgICAvKiogQHR5cGUge0FycmF5PG51bWJlciB8IHN0cmluZz59ICovXG4gICAgY29uc3QgbW9kZWxzUHJpbWFyeUtleVZhbHVlcyA9IFtdXG5cbiAgICAvKiogQHR5cGUge1JlY29yZDxudW1iZXIgfCBzdHJpbmcsIEFycmF5PGltcG9ydChcIi4uLy4uL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0Pj59ICovXG4gICAgY29uc3QgbW9kZWxzQnlQcmltYXJ5S2V5VmFsdWUgPSB7fVxuXG4gICAgY29uc3QgZm9yZWlnbktleSA9IHRoaXMucmVsYXRpb25zaGlwLmdldEZvcmVpZ25LZXkoKVxuICAgIGNvbnN0IHByaW1hcnlLZXkgPSB0aGlzLnJlbGF0aW9uc2hpcC5nZXRQcmltYXJ5S2V5KClcblxuICAgIC8qKiBAdHlwZSB7UmVjb3JkPG51bWJlciB8IHN0cmluZywgQXJyYXk8aW1wb3J0KFwiLi4vLi4vcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHQ+Pn0gKi9cbiAgICBjb25zdCBwcmVsb2FkQ29sbGVjdGlvbnMgPSB7fVxuXG4gICAgaWYgKCFwcmltYXJ5S2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7dGhpcy5yZWxhdGlvbnNoaXAuZ2V0TW9kZWxDbGFzcygpLm5hbWV9IyR7dGhpcy5yZWxhdGlvbnNoaXAuZ2V0UmVsYXRpb25zaGlwTmFtZSgpfSBkb2Vzbid0IGhhdmUgYSBwcmltYXJ5IGtleWApXG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBtb2RlbCBvZiB0aGlzLm1vZGVscykge1xuICAgICAgY29uc3QgcHJpbWFyeUtleVZhbHVlID0gLyoqIEB0eXBlIHtzdHJpbmcgfCBudW1iZXJ9ICovIChtb2RlbC5yZWFkQ29sdW1uKHByaW1hcnlLZXkpKVxuXG4gICAgICBwcmVsb2FkQ29sbGVjdGlvbnNbcHJpbWFyeUtleVZhbHVlXSA9IFtdXG5cbiAgICAgIGlmICghbW9kZWxzUHJpbWFyeUtleVZhbHVlcy5pbmNsdWRlcyhwcmltYXJ5S2V5VmFsdWUpKSBtb2RlbHNQcmltYXJ5S2V5VmFsdWVzLnB1c2gocHJpbWFyeUtleVZhbHVlKVxuICAgICAgaWYgKCEocHJpbWFyeUtleVZhbHVlIGluIG1vZGVsc0J5UHJpbWFyeUtleVZhbHVlKSkgbW9kZWxzQnlQcmltYXJ5S2V5VmFsdWVbcHJpbWFyeUtleVZhbHVlXSA9IFtdXG5cbiAgICAgIG1vZGVsc0J5UHJpbWFyeUtleVZhbHVlW3ByaW1hcnlLZXlWYWx1ZV0ucHVzaChtb2RlbClcbiAgICB9XG5cbiAgICAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIHN0cmluZyB8IG51bWJlciB8IEFycmF5PHN0cmluZyB8IG51bWJlcj4+fSAqL1xuICAgIGNvbnN0IHdoZXJlQXJncyA9IHt9XG5cbiAgICB3aGVyZUFyZ3NbZm9yZWlnbktleV0gPSBtb2RlbHNQcmltYXJ5S2V5VmFsdWVzXG5cbiAgICBpZiAodGhpcy5yZWxhdGlvbnNoaXAuZ2V0UG9seW1vcnBoaWMoKSkge1xuICAgICAgY29uc3QgdHlwZUNvbHVtbiA9IHRoaXMucmVsYXRpb25zaGlwLmdldFBvbHltb3JwaGljVHlwZUNvbHVtbigpXG5cbiAgICAgIHdoZXJlQXJnc1t0eXBlQ29sdW1uXSA9IHRoaXMucmVsYXRpb25zaGlwLmdldE1vZGVsQ2xhc3MoKS5nZXRNb2RlbE5hbWUoKVxuICAgIH1cblxuICAgIGNvbnN0IHRhcmdldE1vZGVsQ2xhc3MgPSB0aGlzLnJlbGF0aW9uc2hpcC5nZXRUYXJnZXRNb2RlbENsYXNzKClcblxuICAgIGlmICghdGFyZ2V0TW9kZWxDbGFzcykgdGhyb3cgbmV3IEVycm9yKFwiTm8gdGFyZ2V0IG1vZGVsIGNsYXNzIGNvdWxkIGJlIGdvdHRlbiBmcm9tIHJlbGF0aW9uc2hpcFwiKVxuXG4gICAgLy8gTG9hZCB0YXJnZXQgbW9kZWxzIHRvIGJlIHByZWxvYWRlZCBvbiB0aGUgZ2l2ZW4gbW9kZWxzXG4gICAgbGV0IHF1ZXJ5ID0gdGFyZ2V0TW9kZWxDbGFzcy53aGVyZSh3aGVyZUFyZ3MpXG5cbiAgICBxdWVyeSA9IHRoaXMucmVsYXRpb25zaGlwLmFwcGx5U2NvcGUocXVlcnkpXG5cbiAgICBjb25zdCB0YXJnZXRNb2RlbHMgPSBhd2FpdCBxdWVyeS50b0FycmF5KClcblxuICAgIGZvciAoY29uc3QgdGFyZ2V0TW9kZWwgb2YgdGFyZ2V0TW9kZWxzKSB7XG4gICAgICBjb25zdCBmb3JlaWduS2V5VmFsdWUgPSAvKiogQHR5cGUge3N0cmluZyB8IG51bWJlcn0gKi8gKHRhcmdldE1vZGVsLnJlYWRDb2x1bW4oZm9yZWlnbktleSkpXG5cbiAgICAgIHByZWxvYWRDb2xsZWN0aW9uc1tmb3JlaWduS2V5VmFsdWVdLnB1c2godGFyZ2V0TW9kZWwpXG4gICAgfVxuXG4gICAgLy8gU2V0IHRoZSB0YXJnZXQgcHJlbG9hZGVkIG1vZGVscyBvbiB0aGUgZ2l2ZW4gbW9kZWxzXG4gICAgZm9yIChjb25zdCBtb2RlbFZhbHVlIGluIHByZWxvYWRDb2xsZWN0aW9ucykge1xuICAgICAgY29uc3QgcHJlbG9hZGVkQ29sbGVjdGlvbiA9IHByZWxvYWRDb2xsZWN0aW9uc1ttb2RlbFZhbHVlXVxuXG4gICAgICBmb3IgKGNvbnN0IG1vZGVsIG9mIG1vZGVsc0J5UHJpbWFyeUtleVZhbHVlW21vZGVsVmFsdWVdKSB7XG4gICAgICAgIGNvbnN0IG1vZGVsUmVsYXRpb25zaGlwID0gbW9kZWwuZ2V0UmVsYXRpb25zaGlwQnlOYW1lKHRoaXMucmVsYXRpb25zaGlwLmdldFJlbGF0aW9uc2hpcE5hbWUoKSlcblxuICAgICAgICBpZiAocHJlbG9hZGVkQ29sbGVjdGlvbi5sZW5ndGggPT0gMCkge1xuICAgICAgICAgIG1vZGVsUmVsYXRpb25zaGlwLnNldExvYWRlZChbXSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBtb2RlbFJlbGF0aW9uc2hpcC5hZGRUb0xvYWRlZChwcmVsb2FkZWRDb2xsZWN0aW9uKVxuICAgICAgICB9XG5cbiAgICAgICAgbW9kZWxSZWxhdGlvbnNoaXAuc2V0UHJlbG9hZGVkKHRydWUpXG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRhcmdldE1vZGVsc1xuICB9XG59XG4iXX0=
176
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGFzLW1hbnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvZGF0YWJhc2UvcXVlcnkvcHJlbG9hZGVyL2hhcy1tYW55LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLGFBQWEsTUFBTSxtQ0FBbUMsQ0FBQTtBQUU3RCxNQUFNLENBQUMsT0FBTyxPQUFPLHNDQUFzQztJQUN6RDs7OztPQUlHO0lBQ0gsWUFBWSxFQUFDLE1BQU0sRUFBRSxZQUFZLEVBQUUsR0FBRyxRQUFRLEVBQUM7UUFDN0MsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFBO1FBRXZCLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFBO1FBQ3BCLElBQUksQ0FBQyxZQUFZLEdBQUcsWUFBWSxDQUFBO0lBQ2xDLENBQUM7SUFFRCw0RkFBNEY7SUFDNUYsS0FBSyxDQUFDLEdBQUc7UUFDUCxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDOUIsT0FBTyxNQUFNLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQTtRQUNqQyxDQUFDO1FBRUQsT0FBTyxNQUFNLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQTtJQUNoQyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILEtBQUssQ0FBQyxXQUFXO1FBQ2YsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxhQUFhLEVBQUUsQ0FBQTtRQUVwRCxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDaEIsTUFBTSxJQUFJLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsYUFBYSxFQUFFLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsbUJBQW1CLEVBQUUsNkJBQTZCLENBQUMsQ0FBQTtRQUNwSSxDQUFDO1FBRUQsTUFBTSx1QkFBdUIsR0FBRyxxQkFBcUIsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUE7UUFDakYsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsRUFBRSxDQUFBO1FBQzFELE1BQU0sbUJBQW1CLEdBQUcsZ0JBQWdCLENBQUMscUJBQXFCLENBQUMsdUJBQXVCLENBQUMsQ0FBQTtRQUMzRixNQUFNLGlCQUFpQixHQUFHLG1CQUFtQixDQUFDLG1CQUFtQixFQUFFLENBQUE7UUFFbkUsSUFBSSxDQUFDLGlCQUFpQjtZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsd0JBQXdCLHVCQUF1Qiw0QkFBNEIsQ0FBQyxDQUFBO1FBRXBILE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxtQkFBbUIsRUFBRSxDQUFBO1FBRWhFLElBQUksQ0FBQyxnQkFBZ0I7WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLHlEQUF5RCxDQUFDLENBQUE7UUFFakcsTUFBTSxpQkFBaUIsR0FBRyxtQkFBbUIsQ0FBQyxhQUFhLEVBQUUsQ0FBQTtRQUU3RCxxQ0FBcUM7UUFDckMsTUFBTSxzQkFBc0IsR0FBRyxFQUFFLENBQUE7UUFFakMsc0ZBQXNGO1FBQ3RGLE1BQU0sdUJBQXVCLEdBQUcsRUFBRSxDQUFBO1FBRWxDLHNGQUFzRjtRQUN0RixNQUFNLGtCQUFrQixHQUFHLEVBQUUsQ0FBQTtRQUU3QixLQUFLLE1BQU0sS0FBSyxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNoQyxNQUFNLGVBQWUsR0FBRyw4QkFBOEIsQ0FBQyxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQTtZQUVyRixrQkFBa0IsQ0FBQyxlQUFlLENBQUMsR0FBRyxFQUFFLENBQUE7WUFFeEMsSUFBSSxDQUFDLHNCQUFzQixDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUM7Z0JBQUUsc0JBQXNCLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFBO1lBQ25HLElBQUksQ0FBQyxDQUFDLGVBQWUsSUFBSSx1QkFBdUIsQ0FBQztnQkFBRSx1QkFBdUIsQ0FBQyxlQUFlLENBQUMsR0FBRyxFQUFFLENBQUE7WUFFaEcsdUJBQXVCLENBQUMsZUFBZSxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ3RELENBQUM7UUFFRCxvRUFBb0U7UUFDcEUsTUFBTSxhQUFhLEdBQUcsTUFBTSxpQkFBaUI7YUFDMUMsS0FBSyxDQUFDLEVBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLHNCQUFzQixFQUFDLENBQUM7YUFDcEQsT0FBTyxFQUFFLENBQUE7UUFFWiw4REFBOEQ7UUFDOUQsTUFBTSxpQkFBaUIsR0FBRyxFQUFFLENBQUE7UUFFNUIsbUNBQW1DO1FBQ25DLE1BQU0sWUFBWSxHQUFHLElBQUksR0FBRyxFQUFFLENBQUE7UUFFOUIsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsRUFBRSxDQUFBO1FBRTFELEtBQUssTUFBTSxZQUFZLElBQUksYUFBYSxFQUFFLENBQUM7WUFDekMsTUFBTSxRQUFRLEdBQUcsOEJBQThCLENBQUMsQ0FBQyxZQUFZLENBQUMsVUFBVSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQTtZQUM1RixNQUFNLFNBQVMsR0FBRyw4QkFBOEIsQ0FBQyxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsaUJBQWlCLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQyxDQUFBO1lBRTFHLElBQUksQ0FBQyxDQUFDLFFBQVEsSUFBSSxpQkFBaUIsQ0FBQztnQkFBRSxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUE7WUFFdEUsaUJBQWlCLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFBO1lBQzNDLFlBQVksQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUE7UUFDN0IsQ0FBQztRQUVELGlGQUFpRjtRQUNqRix3REFBd0Q7UUFDeEQsSUFBSSxZQUFZLEdBQUcsRUFBRSxDQUFBO1FBRXJCLElBQUksWUFBWSxDQUFDLElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUMxQixJQUFJLEtBQUssR0FBRyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsRUFBQyxDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQyxHQUFHLFlBQVksQ0FBQyxFQUFDLENBQUMsQ0FBQTtZQUUzRSxLQUFLLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUE7WUFDM0MsWUFBWSxHQUFHLE1BQU0sS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFBO1FBQ3RDLENBQUM7UUFFRCw4RUFBOEU7UUFDOUUsc0ZBQXNGO1FBQ3RGLE1BQU0sd0JBQXdCLEdBQUcsRUFBRSxDQUFBO1FBRW5DLEtBQUssTUFBTSxXQUFXLElBQUksWUFBWSxFQUFFLENBQUM7WUFDdkMsTUFBTSxPQUFPLEdBQUcsOEJBQThCLENBQUMsQ0FBQyxXQUFXLENBQUMsVUFBVSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQTtZQUV6RixJQUFJLENBQUMsQ0FBQyxPQUFPLElBQUksd0JBQXdCLENBQUM7Z0JBQUUsd0JBQXdCLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFBO1lBRWxGLHdCQUF3QixDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQTtRQUNyRCxDQUFDO1FBRUQseURBQXlEO1FBQ3pELEtBQUssTUFBTSxRQUFRLElBQUksaUJBQWlCLEVBQUUsQ0FBQztZQUN6QyxNQUFNLFVBQVUsR0FBRyxpQkFBaUIsQ0FBQyxRQUFRLENBQUMsQ0FBQTtZQUU5QyxLQUFLLE1BQU0sU0FBUyxJQUFJLFVBQVUsRUFBRSxDQUFDO2dCQUNuQyxNQUFNLGVBQWUsR0FBRyx3QkFBd0IsQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUE7Z0JBRWpFLEtBQUssTUFBTSxXQUFXLElBQUksZUFBZSxFQUFFLENBQUM7b0JBQzFDLElBQUksUUFBUSxJQUFJLGtCQUFrQixFQUFFLENBQUM7d0JBQ25DLGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQTtvQkFDaEQsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7UUFFRCxLQUFLLE1BQU0sVUFBVSxJQUFJLGtCQUFrQixFQUFFLENBQUM7WUFDNUMsTUFBTSxtQkFBbUIsR0FBRyxrQkFBa0IsQ0FBQyxVQUFVLENBQUMsQ0FBQTtZQUUxRCxLQUFLLE1BQU0sS0FBSyxJQUFJLHVCQUF1QixDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7Z0JBQ3hELE1BQU0saUJBQWlCLEdBQUcsS0FBSyxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsbUJBQW1CLEVBQUUsQ0FBQyxDQUFBO2dCQUU5RixJQUFJLG1CQUFtQixDQUFDLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQztvQkFDcEMsaUJBQWlCLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFBO2dCQUNqQyxDQUFDO3FCQUFNLENBQUM7b0JBQ04saUJBQWlCLENBQUMsV0FBVyxDQUFDLG1CQUFtQixDQUFDLENBQUE7Z0JBQ3BELENBQUM7Z0JBRUQsaUJBQWlCLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFBO1lBQ3RDLENBQUM7UUFDSCxDQUFDO1FBRUQsT0FBTyxZQUFZLENBQUE7SUFDckIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxLQUFLLENBQUMsVUFBVTtRQUNkLHFDQUFxQztRQUNyQyxNQUFNLHNCQUFzQixHQUFHLEVBQUUsQ0FBQTtRQUVqQyxzRkFBc0Y7UUFDdEYsTUFBTSx1QkFBdUIsR0FBRyxFQUFFLENBQUE7UUFFbEMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxhQUFhLEVBQUUsQ0FBQTtRQUNwRCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsRUFBRSxDQUFBO1FBRXBELHNGQUFzRjtRQUN0RixNQUFNLGtCQUFrQixHQUFHLEVBQUUsQ0FBQTtRQUU3QixJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDaEIsTUFBTSxJQUFJLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsYUFBYSxFQUFFLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsbUJBQW1CLEVBQUUsNkJBQTZCLENBQUMsQ0FBQTtRQUNwSSxDQUFDO1FBRUQsS0FBSyxNQUFNLEtBQUssSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDaEMsTUFBTSxlQUFlLEdBQUcsOEJBQThCLENBQUMsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUE7WUFFckYsa0JBQWtCLENBQUMsZUFBZSxDQUFDLEdBQUcsRUFBRSxDQUFBO1lBRXhDLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDO2dCQUFFLHNCQUFzQixDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQTtZQUNuRyxJQUFJLENBQUMsQ0FBQyxlQUFlLElBQUksdUJBQXVCLENBQUM7Z0JBQUUsdUJBQXVCLENBQUMsZUFBZSxDQUFDLEdBQUcsRUFBRSxDQUFBO1lBRWhHLHVCQUF1QixDQUFDLGVBQWUsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUN0RCxDQUFDO1FBRUQsdUVBQXVFO1FBQ3ZFLE1BQU0sU0FBUyxHQUFHLEVBQUUsQ0FBQTtRQUVwQixTQUFTLENBQUMsVUFBVSxDQUFDLEdBQUcsc0JBQXNCLENBQUE7UUFFOUMsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLGNBQWMsRUFBRSxFQUFFLENBQUM7WUFDdkMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyx3QkFBd0IsRUFBRSxDQUFBO1lBRS9ELFNBQVMsQ0FBQyxVQUFVLENBQUMsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsRUFBRSxDQUFDLFlBQVksRUFBRSxDQUFBO1FBQzFFLENBQUM7UUFFRCxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsbUJBQW1CLEVBQUUsQ0FBQTtRQUVoRSxJQUFJLENBQUMsZ0JBQWdCO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyx5REFBeUQsQ0FBQyxDQUFBO1FBRWpHLElBQUksS0FBSyxHQUFHLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQTtRQUU3QyxLQUFLLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUE7UUFFM0MsTUFBTSxZQUFZLEdBQUcsTUFBTSxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUE7UUFFMUMsS0FBSyxNQUFNLFdBQVcsSUFBSSxZQUFZLEVBQUUsQ0FBQztZQUN2QyxNQUFNLGVBQWUsR0FBRyw4QkFBOEIsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQTtZQUUzRixrQkFBa0IsQ0FBQyxlQUFlLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUE7UUFDdkQsQ0FBQztRQUVELEtBQUssTUFBTSxVQUFVLElBQUksa0JBQWtCLEVBQUUsQ0FBQztZQUM1QyxNQUFNLG1CQUFtQixHQUFHLGtCQUFrQixDQUFDLFVBQVUsQ0FBQyxDQUFBO1lBRTFELEtBQUssTUFBTSxLQUFLLElBQUksdUJBQXVCLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztnQkFDeEQsTUFBTSxpQkFBaUIsR0FBRyxLQUFLLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDLENBQUE7Z0JBRTlGLElBQUksbUJBQW1CLENBQUMsTUFBTSxJQUFJLENBQUMsRUFBRSxDQUFDO29CQUNwQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLENBQUE7Z0JBQ2pDLENBQUM7cUJBQU0sQ0FBQztvQkFDTixpQkFBaUIsQ0FBQyxXQUFXLENBQUMsbUJBQW1CLENBQUMsQ0FBQTtnQkFDcEQsQ0FBQztnQkFFRCxpQkFBaUIsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUE7WUFDdEMsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLFlBQVksQ0FBQTtJQUNyQixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IHJlc3RBcmdzRXJyb3IgZnJvbSBcIi4uLy4uLy4uL3V0aWxzL3Jlc3QtYXJncy1lcnJvci5qc1wiXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFZlbG9jaW91c0RhdGFiYXNlUXVlcnlQcmVsb2FkZXJIYXNNYW55IHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHRbXX0gYXJncy5tb2RlbHMgLSBNb2RlbCBpbnN0YW5jZXMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vcmVjb3JkL3JlbGF0aW9uc2hpcHMvaGFzLW1hbnkuanNcIikuZGVmYXVsdH0gYXJncy5yZWxhdGlvbnNoaXAgLSBSZWxhdGlvbnNoaXAuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7bW9kZWxzLCByZWxhdGlvbnNoaXAsIC4uLnJlc3RBcmdzfSkge1xuICAgIHJlc3RBcmdzRXJyb3IocmVzdEFyZ3MpXG5cbiAgICB0aGlzLm1vZGVscyA9IG1vZGVsc1xuICAgIHRoaXMucmVsYXRpb25zaGlwID0gcmVsYXRpb25zaGlwXG4gIH1cblxuICAvKiogQHJldHVybnMge1Byb21pc2U8aW1wb3J0KFwiLi4vLi4vcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHRbXT59IC0gTG9hZGVkIHRhcmdldCBtb2RlbHMuICovXG4gIGFzeW5jIHJ1bigpIHtcbiAgICBpZiAodGhpcy5yZWxhdGlvbnNoaXAudGhyb3VnaCkge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuX3J1blRocm91Z2goKVxuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLl9ydW5EaXJlY3QoKVxuICB9XG5cbiAgLyoqXG4gICAqIFByZWxvYWQgdGhyb3VnaCBhIGpvaW4gdGFibGUgKGUuZy4gaGFzTWFueShcImludm9pY2VHcm91cHNcIiwge3Rocm91Z2g6IFwiaW52b2ljZUdyb3VwTGlua3NcIn0pKS5cbiAgICpcbiAgICogQHJldHVybnMge1Byb21pc2U8aW1wb3J0KFwiLi4vLi4vcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHRbXT59IC0gTG9hZGVkIHRhcmdldCBtb2RlbHMuXG4gICAqL1xuICBhc3luYyBfcnVuVGhyb3VnaCgpIHtcbiAgICBjb25zdCBwcmltYXJ5S2V5ID0gdGhpcy5yZWxhdGlvbnNoaXAuZ2V0UHJpbWFyeUtleSgpXG5cbiAgICBpZiAoIXByaW1hcnlLZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLnJlbGF0aW9uc2hpcC5nZXRNb2RlbENsYXNzKCkubmFtZX0jJHt0aGlzLnJlbGF0aW9uc2hpcC5nZXRSZWxhdGlvbnNoaXBOYW1lKCl9IGRvZXNuJ3QgaGF2ZSBhIHByaW1hcnkga2V5YClcbiAgICB9XG5cbiAgICBjb25zdCB0aHJvdWdoUmVsYXRpb25zaGlwTmFtZSA9IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAodGhpcy5yZWxhdGlvbnNoaXAudGhyb3VnaClcbiAgICBjb25zdCBwYXJlbnRNb2RlbENsYXNzID0gdGhpcy5yZWxhdGlvbnNoaXAuZ2V0TW9kZWxDbGFzcygpXG4gICAgY29uc3QgdGhyb3VnaFJlbGF0aW9uc2hpcCA9IHBhcmVudE1vZGVsQ2xhc3MuZ2V0UmVsYXRpb25zaGlwQnlOYW1lKHRocm91Z2hSZWxhdGlvbnNoaXBOYW1lKVxuICAgIGNvbnN0IHRocm91Z2hNb2RlbENsYXNzID0gdGhyb3VnaFJlbGF0aW9uc2hpcC5nZXRUYXJnZXRNb2RlbENsYXNzKClcblxuICAgIGlmICghdGhyb3VnaE1vZGVsQ2xhc3MpIHRocm93IG5ldyBFcnJvcihgVGhyb3VnaCByZWxhdGlvbnNoaXAgJHt0aHJvdWdoUmVsYXRpb25zaGlwTmFtZX0gaGFzIG5vIHRhcmdldCBtb2RlbCBjbGFzc2ApXG5cbiAgICBjb25zdCB0YXJnZXRNb2RlbENsYXNzID0gdGhpcy5yZWxhdGlvbnNoaXAuZ2V0VGFyZ2V0TW9kZWxDbGFzcygpXG5cbiAgICBpZiAoIXRhcmdldE1vZGVsQ2xhc3MpIHRocm93IG5ldyBFcnJvcihcIk5vIHRhcmdldCBtb2RlbCBjbGFzcyBjb3VsZCBiZSBnb3R0ZW4gZnJvbSByZWxhdGlvbnNoaXBcIilcblxuICAgIGNvbnN0IHRocm91Z2hGb3JlaWduS2V5ID0gdGhyb3VnaFJlbGF0aW9uc2hpcC5nZXRGb3JlaWduS2V5KClcblxuICAgIC8qKiBAdHlwZSB7QXJyYXk8bnVtYmVyIHwgc3RyaW5nPn0gKi9cbiAgICBjb25zdCBtb2RlbHNQcmltYXJ5S2V5VmFsdWVzID0gW11cblxuICAgIC8qKiBAdHlwZSB7UmVjb3JkPG51bWJlciB8IHN0cmluZywgQXJyYXk8aW1wb3J0KFwiLi4vLi4vcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHQ+Pn0gKi9cbiAgICBjb25zdCBtb2RlbHNCeVByaW1hcnlLZXlWYWx1ZSA9IHt9XG5cbiAgICAvKiogQHR5cGUge1JlY29yZDxudW1iZXIgfCBzdHJpbmcsIEFycmF5PGltcG9ydChcIi4uLy4uL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0Pj59ICovXG4gICAgY29uc3QgcHJlbG9hZENvbGxlY3Rpb25zID0ge31cblxuICAgIGZvciAoY29uc3QgbW9kZWwgb2YgdGhpcy5tb2RlbHMpIHtcbiAgICAgIGNvbnN0IHByaW1hcnlLZXlWYWx1ZSA9IC8qKiBAdHlwZSB7c3RyaW5nIHwgbnVtYmVyfSAqLyAobW9kZWwucmVhZENvbHVtbihwcmltYXJ5S2V5KSlcblxuICAgICAgcHJlbG9hZENvbGxlY3Rpb25zW3ByaW1hcnlLZXlWYWx1ZV0gPSBbXVxuXG4gICAgICBpZiAoIW1vZGVsc1ByaW1hcnlLZXlWYWx1ZXMuaW5jbHVkZXMocHJpbWFyeUtleVZhbHVlKSkgbW9kZWxzUHJpbWFyeUtleVZhbHVlcy5wdXNoKHByaW1hcnlLZXlWYWx1ZSlcbiAgICAgIGlmICghKHByaW1hcnlLZXlWYWx1ZSBpbiBtb2RlbHNCeVByaW1hcnlLZXlWYWx1ZSkpIG1vZGVsc0J5UHJpbWFyeUtleVZhbHVlW3ByaW1hcnlLZXlWYWx1ZV0gPSBbXVxuXG4gICAgICBtb2RlbHNCeVByaW1hcnlLZXlWYWx1ZVtwcmltYXJ5S2V5VmFsdWVdLnB1c2gobW9kZWwpXG4gICAgfVxuXG4gICAgLy8gU3RlcCAxOiBRdWVyeSB0aGUgdGhyb3VnaCB0YWJsZSB0byBidWlsZCBwYXJlbnTihpJ0YXJnZXQgSUQgbWFwcGluZ1xuICAgIGNvbnN0IHRocm91Z2hNb2RlbHMgPSBhd2FpdCB0aHJvdWdoTW9kZWxDbGFzc1xuICAgICAgLndoZXJlKHtbdGhyb3VnaEZvcmVpZ25LZXldOiBtb2RlbHNQcmltYXJ5S2V5VmFsdWVzfSlcbiAgICAgIC50b0FycmF5KClcblxuICAgIC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZyB8IG51bWJlciwgQXJyYXk8c3RyaW5nIHwgbnVtYmVyPj59ICovXG4gICAgY29uc3QgcGFyZW50VG9UYXJnZXRJZHMgPSB7fVxuXG4gICAgLyoqIEB0eXBlIHtTZXQ8c3RyaW5nIHwgbnVtYmVyPn0gKi9cbiAgICBjb25zdCBhbGxUYXJnZXRJZHMgPSBuZXcgU2V0KClcblxuICAgIGNvbnN0IHRhcmdldEZvcmVpZ25LZXkgPSB0aGlzLnJlbGF0aW9uc2hpcC5nZXRGb3JlaWduS2V5KClcblxuICAgIGZvciAoY29uc3QgdGhyb3VnaE1vZGVsIG9mIHRocm91Z2hNb2RlbHMpIHtcbiAgICAgIGNvbnN0IHBhcmVudElkID0gLyoqIEB0eXBlIHtzdHJpbmcgfCBudW1iZXJ9ICovICh0aHJvdWdoTW9kZWwucmVhZENvbHVtbih0aHJvdWdoRm9yZWlnbktleSkpXG4gICAgICBjb25zdCB0aHJvdWdoSWQgPSAvKiogQHR5cGUge3N0cmluZyB8IG51bWJlcn0gKi8gKHRocm91Z2hNb2RlbC5yZWFkQ29sdW1uKHRocm91Z2hNb2RlbENsYXNzLnByaW1hcnlLZXkoKSkpXG5cbiAgICAgIGlmICghKHBhcmVudElkIGluIHBhcmVudFRvVGFyZ2V0SWRzKSkgcGFyZW50VG9UYXJnZXRJZHNbcGFyZW50SWRdID0gW11cblxuICAgICAgcGFyZW50VG9UYXJnZXRJZHNbcGFyZW50SWRdLnB1c2godGhyb3VnaElkKVxuICAgICAgYWxsVGFyZ2V0SWRzLmFkZCh0aHJvdWdoSWQpXG4gICAgfVxuXG4gICAgLy8gU3RlcCAyOiBMb2FkIHRhcmdldCBtb2RlbHMgYnkgdGhlIGZvcmVpZ24ga2V5IHRoYXQgcG9pbnRzIHRvIHRoZSB0aHJvdWdoIHRhYmxlXG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi8uLi9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdFtdfSAqL1xuICAgIGxldCB0YXJnZXRNb2RlbHMgPSBbXVxuXG4gICAgaWYgKGFsbFRhcmdldElkcy5zaXplID4gMCkge1xuICAgICAgbGV0IHF1ZXJ5ID0gdGFyZ2V0TW9kZWxDbGFzcy53aGVyZSh7W3RhcmdldEZvcmVpZ25LZXldOiBbLi4uYWxsVGFyZ2V0SWRzXX0pXG5cbiAgICAgIHF1ZXJ5ID0gdGhpcy5yZWxhdGlvbnNoaXAuYXBwbHlTY29wZShxdWVyeSlcbiAgICAgIHRhcmdldE1vZGVscyA9IGF3YWl0IHF1ZXJ5LnRvQXJyYXkoKVxuICAgIH1cblxuICAgIC8vIFN0ZXAgMzogSW5kZXggdGFyZ2V0IG1vZGVscyBieSB0aGVpciBmb3JlaWduIGtleSAobWFwcyB0byB0aHJvdWdoIG1vZGVsIElEKVxuICAgIC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZyB8IG51bWJlciwgQXJyYXk8aW1wb3J0KFwiLi4vLi4vcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHQ+Pn0gKi9cbiAgICBjb25zdCB0YXJnZXRNb2RlbHNCeUZvcmVpZ25LZXkgPSB7fVxuXG4gICAgZm9yIChjb25zdCB0YXJnZXRNb2RlbCBvZiB0YXJnZXRNb2RlbHMpIHtcbiAgICAgIGNvbnN0IGZrVmFsdWUgPSAvKiogQHR5cGUge3N0cmluZyB8IG51bWJlcn0gKi8gKHRhcmdldE1vZGVsLnJlYWRDb2x1bW4odGFyZ2V0Rm9yZWlnbktleSkpXG5cbiAgICAgIGlmICghKGZrVmFsdWUgaW4gdGFyZ2V0TW9kZWxzQnlGb3JlaWduS2V5KSkgdGFyZ2V0TW9kZWxzQnlGb3JlaWduS2V5W2ZrVmFsdWVdID0gW11cblxuICAgICAgdGFyZ2V0TW9kZWxzQnlGb3JlaWduS2V5W2ZrVmFsdWVdLnB1c2godGFyZ2V0TW9kZWwpXG4gICAgfVxuXG4gICAgLy8gU3RlcCA0OiBNYXAgdGFyZ2V0cyB0byBwYXJlbnRzIHZpYSB0aGUgdGhyb3VnaCBtYXBwaW5nXG4gICAgZm9yIChjb25zdCBwYXJlbnRJZCBpbiBwYXJlbnRUb1RhcmdldElkcykge1xuICAgICAgY29uc3QgdGhyb3VnaElkcyA9IHBhcmVudFRvVGFyZ2V0SWRzW3BhcmVudElkXVxuXG4gICAgICBmb3IgKGNvbnN0IHRocm91Z2hJZCBvZiB0aHJvdWdoSWRzKSB7XG4gICAgICAgIGNvbnN0IG1hdGNoaW5nVGFyZ2V0cyA9IHRhcmdldE1vZGVsc0J5Rm9yZWlnbktleVt0aHJvdWdoSWRdIHx8IFtdXG5cbiAgICAgICAgZm9yIChjb25zdCB0YXJnZXRNb2RlbCBvZiBtYXRjaGluZ1RhcmdldHMpIHtcbiAgICAgICAgICBpZiAocGFyZW50SWQgaW4gcHJlbG9hZENvbGxlY3Rpb25zKSB7XG4gICAgICAgICAgICBwcmVsb2FkQ29sbGVjdGlvbnNbcGFyZW50SWRdLnB1c2godGFyZ2V0TW9kZWwpXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBtb2RlbFZhbHVlIGluIHByZWxvYWRDb2xsZWN0aW9ucykge1xuICAgICAgY29uc3QgcHJlbG9hZGVkQ29sbGVjdGlvbiA9IHByZWxvYWRDb2xsZWN0aW9uc1ttb2RlbFZhbHVlXVxuXG4gICAgICBmb3IgKGNvbnN0IG1vZGVsIG9mIG1vZGVsc0J5UHJpbWFyeUtleVZhbHVlW21vZGVsVmFsdWVdKSB7XG4gICAgICAgIGNvbnN0IG1vZGVsUmVsYXRpb25zaGlwID0gbW9kZWwuZ2V0UmVsYXRpb25zaGlwQnlOYW1lKHRoaXMucmVsYXRpb25zaGlwLmdldFJlbGF0aW9uc2hpcE5hbWUoKSlcblxuICAgICAgICBpZiAocHJlbG9hZGVkQ29sbGVjdGlvbi5sZW5ndGggPT0gMCkge1xuICAgICAgICAgIG1vZGVsUmVsYXRpb25zaGlwLnNldExvYWRlZChbXSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBtb2RlbFJlbGF0aW9uc2hpcC5hZGRUb0xvYWRlZChwcmVsb2FkZWRDb2xsZWN0aW9uKVxuICAgICAgICB9XG5cbiAgICAgICAgbW9kZWxSZWxhdGlvbnNoaXAuc2V0UHJlbG9hZGVkKHRydWUpXG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRhcmdldE1vZGVsc1xuICB9XG5cbiAgLyoqXG4gICAqIFByZWxvYWQgZGlyZWN0IGhhcy1tYW55IHJlbGF0aW9uc2hpcHMuXG4gICAqXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGltcG9ydChcIi4uLy4uL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0W10+fSAtIExvYWRlZCB0YXJnZXQgbW9kZWxzLlxuICAgKi9cbiAgYXN5bmMgX3J1bkRpcmVjdCgpIHtcbiAgICAvKiogQHR5cGUge0FycmF5PG51bWJlciB8IHN0cmluZz59ICovXG4gICAgY29uc3QgbW9kZWxzUHJpbWFyeUtleVZhbHVlcyA9IFtdXG5cbiAgICAvKiogQHR5cGUge1JlY29yZDxudW1iZXIgfCBzdHJpbmcsIEFycmF5PGltcG9ydChcIi4uLy4uL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0Pj59ICovXG4gICAgY29uc3QgbW9kZWxzQnlQcmltYXJ5S2V5VmFsdWUgPSB7fVxuXG4gICAgY29uc3QgZm9yZWlnbktleSA9IHRoaXMucmVsYXRpb25zaGlwLmdldEZvcmVpZ25LZXkoKVxuICAgIGNvbnN0IHByaW1hcnlLZXkgPSB0aGlzLnJlbGF0aW9uc2hpcC5nZXRQcmltYXJ5S2V5KClcblxuICAgIC8qKiBAdHlwZSB7UmVjb3JkPG51bWJlciB8IHN0cmluZywgQXJyYXk8aW1wb3J0KFwiLi4vLi4vcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHQ+Pn0gKi9cbiAgICBjb25zdCBwcmVsb2FkQ29sbGVjdGlvbnMgPSB7fVxuXG4gICAgaWYgKCFwcmltYXJ5S2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7dGhpcy5yZWxhdGlvbnNoaXAuZ2V0TW9kZWxDbGFzcygpLm5hbWV9IyR7dGhpcy5yZWxhdGlvbnNoaXAuZ2V0UmVsYXRpb25zaGlwTmFtZSgpfSBkb2Vzbid0IGhhdmUgYSBwcmltYXJ5IGtleWApXG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBtb2RlbCBvZiB0aGlzLm1vZGVscykge1xuICAgICAgY29uc3QgcHJpbWFyeUtleVZhbHVlID0gLyoqIEB0eXBlIHtzdHJpbmcgfCBudW1iZXJ9ICovIChtb2RlbC5yZWFkQ29sdW1uKHByaW1hcnlLZXkpKVxuXG4gICAgICBwcmVsb2FkQ29sbGVjdGlvbnNbcHJpbWFyeUtleVZhbHVlXSA9IFtdXG5cbiAgICAgIGlmICghbW9kZWxzUHJpbWFyeUtleVZhbHVlcy5pbmNsdWRlcyhwcmltYXJ5S2V5VmFsdWUpKSBtb2RlbHNQcmltYXJ5S2V5VmFsdWVzLnB1c2gocHJpbWFyeUtleVZhbHVlKVxuICAgICAgaWYgKCEocHJpbWFyeUtleVZhbHVlIGluIG1vZGVsc0J5UHJpbWFyeUtleVZhbHVlKSkgbW9kZWxzQnlQcmltYXJ5S2V5VmFsdWVbcHJpbWFyeUtleVZhbHVlXSA9IFtdXG5cbiAgICAgIG1vZGVsc0J5UHJpbWFyeUtleVZhbHVlW3ByaW1hcnlLZXlWYWx1ZV0ucHVzaChtb2RlbClcbiAgICB9XG5cbiAgICAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIHN0cmluZyB8IG51bWJlciB8IEFycmF5PHN0cmluZyB8IG51bWJlcj4+fSAqL1xuICAgIGNvbnN0IHdoZXJlQXJncyA9IHt9XG5cbiAgICB3aGVyZUFyZ3NbZm9yZWlnbktleV0gPSBtb2RlbHNQcmltYXJ5S2V5VmFsdWVzXG5cbiAgICBpZiAodGhpcy5yZWxhdGlvbnNoaXAuZ2V0UG9seW1vcnBoaWMoKSkge1xuICAgICAgY29uc3QgdHlwZUNvbHVtbiA9IHRoaXMucmVsYXRpb25zaGlwLmdldFBvbHltb3JwaGljVHlwZUNvbHVtbigpXG5cbiAgICAgIHdoZXJlQXJnc1t0eXBlQ29sdW1uXSA9IHRoaXMucmVsYXRpb25zaGlwLmdldE1vZGVsQ2xhc3MoKS5nZXRNb2RlbE5hbWUoKVxuICAgIH1cblxuICAgIGNvbnN0IHRhcmdldE1vZGVsQ2xhc3MgPSB0aGlzLnJlbGF0aW9uc2hpcC5nZXRUYXJnZXRNb2RlbENsYXNzKClcblxuICAgIGlmICghdGFyZ2V0TW9kZWxDbGFzcykgdGhyb3cgbmV3IEVycm9yKFwiTm8gdGFyZ2V0IG1vZGVsIGNsYXNzIGNvdWxkIGJlIGdvdHRlbiBmcm9tIHJlbGF0aW9uc2hpcFwiKVxuXG4gICAgbGV0IHF1ZXJ5ID0gdGFyZ2V0TW9kZWxDbGFzcy53aGVyZSh3aGVyZUFyZ3MpXG5cbiAgICBxdWVyeSA9IHRoaXMucmVsYXRpb25zaGlwLmFwcGx5U2NvcGUocXVlcnkpXG5cbiAgICBjb25zdCB0YXJnZXRNb2RlbHMgPSBhd2FpdCBxdWVyeS50b0FycmF5KClcblxuICAgIGZvciAoY29uc3QgdGFyZ2V0TW9kZWwgb2YgdGFyZ2V0TW9kZWxzKSB7XG4gICAgICBjb25zdCBmb3JlaWduS2V5VmFsdWUgPSAvKiogQHR5cGUge3N0cmluZyB8IG51bWJlcn0gKi8gKHRhcmdldE1vZGVsLnJlYWRDb2x1bW4oZm9yZWlnbktleSkpXG5cbiAgICAgIHByZWxvYWRDb2xsZWN0aW9uc1tmb3JlaWduS2V5VmFsdWVdLnB1c2godGFyZ2V0TW9kZWwpXG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBtb2RlbFZhbHVlIGluIHByZWxvYWRDb2xsZWN0aW9ucykge1xuICAgICAgY29uc3QgcHJlbG9hZGVkQ29sbGVjdGlvbiA9IHByZWxvYWRDb2xsZWN0aW9uc1ttb2RlbFZhbHVlXVxuXG4gICAgICBmb3IgKGNvbnN0IG1vZGVsIG9mIG1vZGVsc0J5UHJpbWFyeUtleVZhbHVlW21vZGVsVmFsdWVdKSB7XG4gICAgICAgIGNvbnN0IG1vZGVsUmVsYXRpb25zaGlwID0gbW9kZWwuZ2V0UmVsYXRpb25zaGlwQnlOYW1lKHRoaXMucmVsYXRpb25zaGlwLmdldFJlbGF0aW9uc2hpcE5hbWUoKSlcblxuICAgICAgICBpZiAocHJlbG9hZGVkQ29sbGVjdGlvbi5sZW5ndGggPT0gMCkge1xuICAgICAgICAgIG1vZGVsUmVsYXRpb25zaGlwLnNldExvYWRlZChbXSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBtb2RlbFJlbGF0aW9uc2hpcC5hZGRUb0xvYWRlZChwcmVsb2FkZWRDb2xsZWN0aW9uKVxuICAgICAgICB9XG5cbiAgICAgICAgbW9kZWxSZWxhdGlvbnNoaXAuc2V0UHJlbG9hZGVkKHRydWUpXG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRhcmdldE1vZGVsc1xuICB9XG59XG4iXX0=