@decaf-ts/for-fabric 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/LICENSE.md +22 -0
  2. package/README.md +647 -0
  3. package/dist/for-fabric.cjs +6223 -0
  4. package/dist/for-fabric.esm.cjs +6180 -0
  5. package/lib/client/FabricClientAdapter.cjs +760 -0
  6. package/lib/client/FabricClientAdapter.d.ts +381 -0
  7. package/lib/client/FabricClientDispatch.cjs +186 -0
  8. package/lib/client/FabricClientDispatch.d.ts +125 -0
  9. package/lib/client/FabricClientRepository.cjs +131 -0
  10. package/lib/client/FabricClientRepository.d.ts +100 -0
  11. package/lib/client/erc20/erc20ClientRepository.cjs +343 -0
  12. package/lib/client/erc20/erc20ClientRepository.d.ts +254 -0
  13. package/lib/client/fabric-fs.cjs +234 -0
  14. package/lib/client/fabric-fs.d.ts +92 -0
  15. package/lib/client/index.cjs +30 -0
  16. package/lib/client/index.d.ts +13 -0
  17. package/lib/client/logging.cjs +102 -0
  18. package/lib/client/logging.d.ts +60 -0
  19. package/lib/client/services/LoggedService.cjs +47 -0
  20. package/lib/client/services/LoggedService.d.ts +42 -0
  21. package/lib/client/services/constants.cjs +3 -0
  22. package/lib/client/services/constants.d.ts +15 -0
  23. package/lib/client/services/enrollementService.cjs +344 -0
  24. package/lib/client/services/enrollementService.d.ts +176 -0
  25. package/lib/client/services/index.cjs +18 -0
  26. package/lib/client/services/index.d.ts +1 -0
  27. package/lib/contracts/ContractAdapter.cjs +730 -0
  28. package/lib/contracts/ContractAdapter.d.ts +296 -0
  29. package/lib/contracts/ContractContext.cjs +85 -0
  30. package/lib/contracts/ContractContext.d.ts +64 -0
  31. package/lib/contracts/ContractPrivateDataAdapter.cjs +281 -0
  32. package/lib/contracts/ContractPrivateDataAdapter.d.ts +74 -0
  33. package/lib/contracts/FabricConstruction.cjs +441 -0
  34. package/lib/contracts/FabricConstruction.d.ts +304 -0
  35. package/lib/contracts/FabricContractRepository.cjs +306 -0
  36. package/lib/contracts/FabricContractRepository.d.ts +162 -0
  37. package/lib/contracts/FabricContractRepositoryObservableHandler.cjs +85 -0
  38. package/lib/contracts/FabricContractRepositoryObservableHandler.d.ts +62 -0
  39. package/lib/contracts/FabricContractSequence.cjs +139 -0
  40. package/lib/contracts/FabricContractSequence.d.ts +61 -0
  41. package/lib/contracts/FabricContractStatement.cjs +119 -0
  42. package/lib/contracts/FabricContractStatement.d.ts +34 -0
  43. package/lib/contracts/PrivateSequence.cjs +36 -0
  44. package/lib/contracts/PrivateSequence.d.ts +15 -0
  45. package/lib/contracts/crud/crud-contract.cjs +257 -0
  46. package/lib/contracts/crud/crud-contract.d.ts +168 -0
  47. package/lib/contracts/crud/index.cjs +19 -0
  48. package/lib/contracts/crud/index.d.ts +2 -0
  49. package/lib/contracts/crud/serialized-crud-contract.cjs +172 -0
  50. package/lib/contracts/crud/serialized-crud-contract.d.ts +37 -0
  51. package/lib/contracts/erc20/erc20contract.cjs +569 -0
  52. package/lib/contracts/erc20/erc20contract.d.ts +151 -0
  53. package/lib/contracts/erc20/index.cjs +21 -0
  54. package/lib/contracts/erc20/index.d.ts +2 -0
  55. package/lib/contracts/erc20/models.cjs +209 -0
  56. package/lib/contracts/erc20/models.d.ts +114 -0
  57. package/lib/contracts/index.cjs +32 -0
  58. package/lib/contracts/index.d.ts +15 -0
  59. package/lib/contracts/logging.cjs +96 -0
  60. package/lib/contracts/logging.d.ts +49 -0
  61. package/lib/contracts/private-data.cjs +121 -0
  62. package/lib/contracts/private-data.d.ts +16 -0
  63. package/lib/contracts/types.cjs +3 -0
  64. package/lib/contracts/types.d.ts +26 -0
  65. package/lib/esm/client/FabricClientAdapter.d.ts +381 -0
  66. package/lib/esm/client/FabricClientAdapter.js +723 -0
  67. package/lib/esm/client/FabricClientDispatch.d.ts +125 -0
  68. package/lib/esm/client/FabricClientDispatch.js +182 -0
  69. package/lib/esm/client/FabricClientRepository.d.ts +100 -0
  70. package/lib/esm/client/FabricClientRepository.js +127 -0
  71. package/lib/esm/client/erc20/erc20ClientRepository.d.ts +254 -0
  72. package/lib/esm/client/erc20/erc20ClientRepository.js +339 -0
  73. package/lib/esm/client/fabric-fs.d.ts +92 -0
  74. package/lib/esm/client/fabric-fs.js +191 -0
  75. package/lib/esm/client/index.d.ts +13 -0
  76. package/lib/esm/client/index.js +14 -0
  77. package/lib/esm/client/logging.d.ts +60 -0
  78. package/lib/esm/client/logging.js +98 -0
  79. package/lib/esm/client/services/LoggedService.d.ts +42 -0
  80. package/lib/esm/client/services/LoggedService.js +43 -0
  81. package/lib/esm/client/services/constants.d.ts +15 -0
  82. package/lib/esm/client/services/constants.js +2 -0
  83. package/lib/esm/client/services/enrollementService.d.ts +176 -0
  84. package/lib/esm/client/services/enrollementService.js +337 -0
  85. package/lib/esm/client/services/index.d.ts +1 -0
  86. package/lib/esm/client/services/index.js +2 -0
  87. package/lib/esm/contracts/ContractAdapter.d.ts +296 -0
  88. package/lib/esm/contracts/ContractAdapter.js +724 -0
  89. package/lib/esm/contracts/ContractContext.d.ts +64 -0
  90. package/lib/esm/contracts/ContractContext.js +81 -0
  91. package/lib/esm/contracts/ContractPrivateDataAdapter.d.ts +74 -0
  92. package/lib/esm/contracts/ContractPrivateDataAdapter.js +277 -0
  93. package/lib/esm/contracts/FabricConstruction.d.ts +304 -0
  94. package/lib/esm/contracts/FabricConstruction.js +433 -0
  95. package/lib/esm/contracts/FabricContractRepository.d.ts +162 -0
  96. package/lib/esm/contracts/FabricContractRepository.js +302 -0
  97. package/lib/esm/contracts/FabricContractRepositoryObservableHandler.d.ts +62 -0
  98. package/lib/esm/contracts/FabricContractRepositoryObservableHandler.js +81 -0
  99. package/lib/esm/contracts/FabricContractSequence.d.ts +61 -0
  100. package/lib/esm/contracts/FabricContractSequence.js +135 -0
  101. package/lib/esm/contracts/FabricContractStatement.d.ts +34 -0
  102. package/lib/esm/contracts/FabricContractStatement.js +115 -0
  103. package/lib/esm/contracts/PrivateSequence.d.ts +15 -0
  104. package/lib/esm/contracts/PrivateSequence.js +33 -0
  105. package/lib/esm/contracts/crud/crud-contract.d.ts +168 -0
  106. package/lib/esm/contracts/crud/crud-contract.js +253 -0
  107. package/lib/esm/contracts/crud/index.d.ts +2 -0
  108. package/lib/esm/contracts/crud/index.js +3 -0
  109. package/lib/esm/contracts/crud/serialized-crud-contract.d.ts +37 -0
  110. package/lib/esm/contracts/crud/serialized-crud-contract.js +168 -0
  111. package/lib/esm/contracts/erc20/erc20contract.d.ts +151 -0
  112. package/lib/esm/contracts/erc20/erc20contract.js +565 -0
  113. package/lib/esm/contracts/erc20/index.d.ts +2 -0
  114. package/lib/esm/contracts/erc20/index.js +4 -0
  115. package/lib/esm/contracts/erc20/models.d.ts +114 -0
  116. package/lib/esm/contracts/erc20/models.js +206 -0
  117. package/lib/esm/contracts/index.d.ts +15 -0
  118. package/lib/esm/contracts/index.js +16 -0
  119. package/lib/esm/contracts/logging.d.ts +49 -0
  120. package/lib/esm/contracts/logging.js +92 -0
  121. package/lib/esm/contracts/private-data.d.ts +16 -0
  122. package/lib/esm/contracts/private-data.js +113 -0
  123. package/lib/esm/contracts/types.d.ts +26 -0
  124. package/lib/esm/contracts/types.js +2 -0
  125. package/lib/esm/index.d.ts +8 -0
  126. package/lib/esm/index.js +9 -0
  127. package/lib/esm/shared/ClientSerializer.d.ts +52 -0
  128. package/lib/esm/shared/ClientSerializer.js +80 -0
  129. package/lib/esm/shared/DeterministicSerializer.d.ts +40 -0
  130. package/lib/esm/shared/DeterministicSerializer.js +50 -0
  131. package/lib/esm/shared/SimpleDeterministicSerializer.d.ts +7 -0
  132. package/lib/esm/shared/SimpleDeterministicSerializer.js +42 -0
  133. package/lib/esm/shared/constants.d.ts +39 -0
  134. package/lib/esm/shared/constants.js +42 -0
  135. package/lib/esm/shared/crypto.d.ts +107 -0
  136. package/lib/esm/shared/crypto.js +331 -0
  137. package/lib/esm/shared/decorators.d.ts +24 -0
  138. package/lib/esm/shared/decorators.js +98 -0
  139. package/lib/esm/shared/erc20/erc20-constants.d.ts +25 -0
  140. package/lib/esm/shared/erc20/erc20-constants.js +27 -0
  141. package/lib/esm/shared/errors.d.ts +116 -0
  142. package/lib/esm/shared/errors.js +132 -0
  143. package/lib/esm/shared/events.d.ts +39 -0
  144. package/lib/esm/shared/events.js +47 -0
  145. package/lib/esm/shared/fabric-types.d.ts +33 -0
  146. package/lib/esm/shared/fabric-types.js +2 -0
  147. package/lib/esm/shared/index.d.ts +13 -0
  148. package/lib/esm/shared/index.js +14 -0
  149. package/lib/esm/shared/interfaces/Checkable.d.ts +21 -0
  150. package/lib/esm/shared/interfaces/Checkable.js +2 -0
  151. package/lib/esm/shared/math.d.ts +34 -0
  152. package/lib/esm/shared/math.js +61 -0
  153. package/lib/esm/shared/model/Identity.d.ts +42 -0
  154. package/lib/esm/shared/model/Identity.js +78 -0
  155. package/lib/esm/shared/model/IdentityCredentials.d.ts +41 -0
  156. package/lib/esm/shared/model/IdentityCredentials.js +74 -0
  157. package/lib/esm/shared/model/index.d.ts +1 -0
  158. package/lib/esm/shared/model/index.js +2 -0
  159. package/lib/esm/shared/model/utils.d.ts +60 -0
  160. package/lib/esm/shared/model/utils.js +108 -0
  161. package/lib/esm/shared/types.d.ts +79 -0
  162. package/lib/esm/shared/types.js +2 -0
  163. package/lib/esm/shared/utils.d.ts +55 -0
  164. package/lib/esm/shared/utils.js +148 -0
  165. package/lib/index.cjs +25 -0
  166. package/lib/index.d.ts +8 -0
  167. package/lib/shared/ClientSerializer.cjs +84 -0
  168. package/lib/shared/ClientSerializer.d.ts +52 -0
  169. package/lib/shared/DeterministicSerializer.cjs +54 -0
  170. package/lib/shared/DeterministicSerializer.d.ts +40 -0
  171. package/lib/shared/SimpleDeterministicSerializer.cjs +46 -0
  172. package/lib/shared/SimpleDeterministicSerializer.d.ts +7 -0
  173. package/lib/shared/constants.cjs +45 -0
  174. package/lib/shared/constants.d.ts +39 -0
  175. package/lib/shared/crypto.cjs +369 -0
  176. package/lib/shared/crypto.d.ts +107 -0
  177. package/lib/shared/decorators.cjs +105 -0
  178. package/lib/shared/decorators.d.ts +24 -0
  179. package/lib/shared/erc20/erc20-constants.cjs +30 -0
  180. package/lib/shared/erc20/erc20-constants.d.ts +25 -0
  181. package/lib/shared/errors.cjs +142 -0
  182. package/lib/shared/errors.d.ts +116 -0
  183. package/lib/shared/events.cjs +51 -0
  184. package/lib/shared/events.d.ts +39 -0
  185. package/lib/shared/fabric-types.cjs +4 -0
  186. package/lib/shared/fabric-types.d.ts +33 -0
  187. package/lib/shared/index.cjs +30 -0
  188. package/lib/shared/index.d.ts +13 -0
  189. package/lib/shared/interfaces/Checkable.cjs +3 -0
  190. package/lib/shared/interfaces/Checkable.d.ts +21 -0
  191. package/lib/shared/math.cjs +66 -0
  192. package/lib/shared/math.d.ts +34 -0
  193. package/lib/shared/model/Identity.cjs +81 -0
  194. package/lib/shared/model/Identity.d.ts +42 -0
  195. package/lib/shared/model/IdentityCredentials.cjs +77 -0
  196. package/lib/shared/model/IdentityCredentials.d.ts +41 -0
  197. package/lib/shared/model/index.cjs +18 -0
  198. package/lib/shared/model/index.d.ts +1 -0
  199. package/lib/shared/model/utils.cjs +114 -0
  200. package/lib/shared/model/utils.d.ts +60 -0
  201. package/lib/shared/types.cjs +3 -0
  202. package/lib/shared/types.d.ts +79 -0
  203. package/lib/shared/utils.cjs +185 -0
  204. package/lib/shared/utils.d.ts +55 -0
  205. package/package.json +166 -0
@@ -0,0 +1,760 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
22
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
23
+ };
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ var __metadata = (this && this.__metadata) || function (k, v) {
42
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
43
+ };
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.FabricClientAdapter = void 0;
46
+ const for_couchdb_1 = require("@decaf-ts/for-couchdb");
47
+ const grpc_js_1 = require("@grpc/grpc-js");
48
+ const grpc = __importStar(require("@grpc/grpc-js"));
49
+ const decorator_validation_1 = require("@decaf-ts/decorator-validation");
50
+ const logging_1 = require("@decaf-ts/logging");
51
+ const fabric_gateway_1 = require("@hyperledger/fabric-gateway");
52
+ const fabric_fs_1 = require("./fabric-fs.cjs");
53
+ const db_decorators_1 = require("@decaf-ts/db-decorators");
54
+ const core_1 = require("@decaf-ts/core");
55
+ const FabricClientRepository_1 = require("./FabricClientRepository.cjs");
56
+ const constants_1 = require("./../shared/constants.cjs");
57
+ const ClientSerializer_1 = require("./../shared/ClientSerializer.cjs");
58
+ const FabricClientDispatch_1 = require("./FabricClientDispatch.cjs");
59
+ /**
60
+ * @description Adapter for interacting with Hyperledger Fabric networks
61
+ * @summary The FabricAdapter extends CouchDBAdapter to provide a seamless interface for interacting with Hyperledger Fabric networks.
62
+ * It handles connection management, transaction submission, and CRUD operations against Fabric chaincode.
63
+ * @template PeerConfig - Configuration type for connecting to a Fabric peer
64
+ * @template FabricFlags - Flags specific to Fabric operations
65
+ * @template Context<FabricFlags> - Context type containing Fabric-specific flags
66
+ * @param config - Configuration for connecting to a Fabric peer
67
+ * @param alias - Optional alias for the adapter instance
68
+ * @class FabricClientAdapter
69
+ * @example
70
+ * ```typescript
71
+ * // Create a new FabricAdapter instance
72
+ * const config: PeerConfig = {
73
+ * mspId: 'Org1MSP',
74
+ * peerEndpoint: 'localhost:7051',
75
+ * channelName: 'mychannel',
76
+ * chaincodeName: 'mycc',
77
+ * contractName: 'mycontract',
78
+ * tlsCertPath: '/path/to/tls/cert',
79
+ * certDirectoryPath: '/path/to/cert/dir',
80
+ * keyDirectoryPath: '/path/to/key/dir'
81
+ * };
82
+ *
83
+ * const adapter = new FabricAdapter(config, 'org1-adapter');
84
+ *
85
+ * // Use the adapter to interact with the Fabric network
86
+ * const result = await adapter.read('users', 'user1', mySerializer);
87
+ * ```
88
+ * @mermaid
89
+ * sequenceDiagram
90
+ * participant Client
91
+ * participant FabricAdapter
92
+ * participant Gateway
93
+ * participant Network
94
+ * participant Contract
95
+ * participant Chaincode
96
+ *
97
+ * Client->>FabricAdapter: create(tableName, id, model, transient, serializer)
98
+ * FabricAdapter->>FabricAdapter: submitTransaction(OperationKeys.CREATE, [serializedModel], transient)
99
+ * FabricAdapter->>Gateway: connect()
100
+ * Gateway->>Network: getNetwork(channelName)
101
+ * Network->>Contract: getContract(chaincodeName, contractName)
102
+ * FabricAdapter->>Contract: submit(api, proposalOptions)
103
+ * Contract->>Chaincode: invoke
104
+ * Chaincode-->>Contract: response
105
+ * Contract-->>FabricAdapter: result
106
+ * FabricAdapter->>FabricAdapter: decode(result)
107
+ * FabricAdapter->>FabricAdapter: serializer.deserialize(decodedResult)
108
+ * FabricAdapter-->>Client: deserializedResult
109
+ */
110
+ class FabricClientAdapter extends for_couchdb_1.CouchDBAdapter {
111
+ /**
112
+ * @description Static text decoder for converting Uint8Array to string
113
+ */
114
+ static { this.decoder = new TextDecoder("utf8"); }
115
+ static { this.serializer = new ClientSerializer_1.ClientSerializer(); }
116
+ /**
117
+ * @description Static logger instance for the FabricAdapter class
118
+ */
119
+ static { this.log = logging_1.Logging.for(FabricClientAdapter); }
120
+ /**
121
+ * @description Gets the logger instance for this adapter
122
+ * @summary Returns the static logger instance for the FabricAdapter class
123
+ * @return {Logger} The logger instance
124
+ */
125
+ get log() {
126
+ return FabricClientAdapter.log;
127
+ }
128
+ /**
129
+ * @description Creates a new FabricAdapter instance
130
+ * @summary Initializes a new adapter for interacting with a Hyperledger Fabric network
131
+ * @param {PeerConfig} config - Configuration for connecting to a Fabric peer
132
+ * @param {string} [alias] - Optional alias for the adapter instance
133
+ */
134
+ constructor(config, alias) {
135
+ super(config, constants_1.FabricFlavour, alias);
136
+ this.serializer = FabricClientAdapter.serializer;
137
+ }
138
+ /**
139
+ * @description Decodes a Uint8Array to a string
140
+ * @summary Converts binary data received from Fabric to a string using UTF-8 encoding
141
+ * @param {Uint8Array} data - The binary data to decode
142
+ * @return {string} The decoded string
143
+ */
144
+ decode(data) {
145
+ return FabricClientAdapter.decoder.decode(data);
146
+ }
147
+ repository() {
148
+ return FabricClientRepository_1.FabricClientRepository;
149
+ }
150
+ /**
151
+ * @description Creates multiple records in a single transaction
152
+ * @summary Submits a transaction to create multiple records in the Fabric ledger
153
+ * @param {string} tableName - The name of the table/collection
154
+ * @param {string[] | number[]} ids - Array of record identifiers
155
+ * @param {Array<Record<string, any>>} models - Array of record data
156
+ * @param {Record<string, any>} transient - Transient data for the transaction
157
+ * @return {Promise<Array<Record<string, any>>>} Promise resolving to the created records
158
+ */
159
+ async createAll(tableName, ids, models, transient) {
160
+ const log = this.log.for(this.createAll);
161
+ if (ids.length !== models.length)
162
+ throw new db_decorators_1.InternalError(`Ids and models must have the same length: ${ids.length} != ${models.length}`);
163
+ log.info(`adding ${ids.length} entries to ${tableName} table`);
164
+ log.verbose(`pks: ${ids}`);
165
+ const result = await this.submitTransaction(db_decorators_1.BulkCrudOperationKeys.CREATE_ALL, [ids, models.map((m) => this.serializer.serialize(m, tableName))], transient);
166
+ try {
167
+ return JSON.parse(this.decode(result)).map((r) => JSON.parse(r));
168
+ }
169
+ catch (e) {
170
+ throw new db_decorators_1.SerializationError(e);
171
+ }
172
+ }
173
+ /**
174
+ * @description Reads multiple records in a single transaction
175
+ * @summary Submits a transaction to read multiple records from the Fabric ledger
176
+ * @param {string} tableName - The name of the table/collection
177
+ * @param {string[] | number[]} ids - Array of record identifiers to read
178
+ * @return {Promise<Array<Record<string, any>>>} Promise resolving to the retrieved records
179
+ */
180
+ async readAll(tableName, ids) {
181
+ const log = this.log.for(this.readAll);
182
+ log.info(`reading ${ids.length} entries to ${tableName} table`);
183
+ log.verbose(`pks: ${ids}`);
184
+ const result = await this.submitTransaction(db_decorators_1.BulkCrudOperationKeys.READ_ALL, [ids]);
185
+ try {
186
+ return JSON.parse(this.decode(result)).map((r) => JSON.parse(r));
187
+ }
188
+ catch (e) {
189
+ throw new db_decorators_1.SerializationError(e);
190
+ }
191
+ }
192
+ /**
193
+ * @description Updates multiple records in a single transaction
194
+ * @summary Submits a transaction to update multiple records in the Fabric ledger
195
+ * @param {string} tableName - The name of the table/collection
196
+ * @param {string[] | number[]} ids - Array of record identifiers
197
+ * @param {Array<Record<string, any>>} models - Array of updated record data
198
+ * @param {Record<string, any>} transient - Transient data for the transaction
199
+ * @return {Promise<Array<Record<string, any>>>} Promise resolving to the updated records
200
+ */
201
+ async updateAll(tableName, ids, models, transient) {
202
+ const log = this.log.for(this.updateAll);
203
+ if (ids.length !== models.length)
204
+ throw new db_decorators_1.InternalError(`Ids and models must have the same length: ${ids.length} != ${models.length}`);
205
+ log.info(`updating ${ids.length} entries to ${tableName} table`);
206
+ log.verbose(`pks: ${ids}`);
207
+ const result = await this.submitTransaction(db_decorators_1.BulkCrudOperationKeys.UPDATE_ALL, [ids, models.map((m) => this.serializer.serialize(m, tableName))], transient);
208
+ try {
209
+ return JSON.parse(this.decode(result)).map((r) => JSON.parse(r));
210
+ }
211
+ catch (e) {
212
+ throw new db_decorators_1.SerializationError(e);
213
+ }
214
+ }
215
+ /**
216
+ * @description Deletes multiple records in a single transaction
217
+ * @summary Submits a transaction to delete multiple records from the Fabric ledger
218
+ * @param {string} tableName - The name of the table/collection
219
+ * @param {Array<string | number | bigint>} ids - Array of record identifiers to delete
220
+ * @param {Serializer<any>} serializer - Serializer for the model data
221
+ * @return {Promise<Array<Record<string, any>>>} Promise resolving to the deleted records
222
+ */
223
+ async deleteAll(tableName, ids) {
224
+ const log = this.log.for(this.deleteAll);
225
+ log.info(`deleting ${ids.length} entries to ${tableName} table`);
226
+ log.verbose(`pks: ${ids}`);
227
+ const result = await this.submitTransaction(db_decorators_1.BulkCrudOperationKeys.DELETE_ALL, [ids]);
228
+ try {
229
+ return JSON.parse(this.decode(result)).map((r) => JSON.parse(r));
230
+ }
231
+ catch (e) {
232
+ throw new db_decorators_1.SerializationError(e);
233
+ }
234
+ }
235
+ /**
236
+ * @description Prepares a model for persistence
237
+ * @summary Converts a model instance into a format suitable for database storage,
238
+ * handling column mapping and separating transient properties
239
+ * @template M - The model type
240
+ * @param {M} model - The model instance to prepare
241
+ * @param pk - The primary key property name
242
+ * @return The prepared data
243
+ */
244
+ prepare(model, pk) {
245
+ const log = this.log.for(this.prepare);
246
+ const split = (0, db_decorators_1.modelToTransient)(model);
247
+ if (model[core_1.PersistenceKeys.METADATA]) {
248
+ log.silly(`Passing along persistence metadata for ${model[core_1.PersistenceKeys.METADATA]}`);
249
+ Object.defineProperty(split.model, core_1.PersistenceKeys.METADATA, {
250
+ enumerable: false,
251
+ writable: false,
252
+ configurable: true,
253
+ value: model[core_1.PersistenceKeys.METADATA],
254
+ });
255
+ }
256
+ return {
257
+ record: split.model,
258
+ id: model[pk],
259
+ transient: split.transient,
260
+ };
261
+ }
262
+ /**
263
+ * @description Converts database data back into a model instance
264
+ * @summary Reconstructs a model instance from database data, handling column mapping
265
+ * and reattaching transient properties
266
+ * @template M - The model type
267
+ * @param obj - The database record
268
+ * @param {string|Constructor<M>} clazz - The model class or name
269
+ * @param pk - The primary key property name
270
+ * @param {string|number|bigint} id - The primary key value
271
+ * @param [transient] - Transient properties to reattach
272
+ * @return {M} The reconstructed model instance
273
+ */
274
+ revert(obj, clazz, pk, id, transient) {
275
+ const log = this.log.for(this.revert);
276
+ const ob = {};
277
+ ob[pk] = id;
278
+ const m = (typeof clazz === "string" ? decorator_validation_1.Model.build(ob, clazz) : new clazz(ob));
279
+ log.silly(`Rebuilding model ${m.constructor.name} id ${id}`);
280
+ const metadata = obj[core_1.PersistenceKeys.METADATA];
281
+ const result = Object.keys(m).reduce((accum, key) => {
282
+ accum[key] = obj[key];
283
+ return accum;
284
+ }, m);
285
+ if (transient) {
286
+ log.verbose(`re-adding transient properties: ${Object.keys(transient).join(", ")}`);
287
+ Object.entries(transient).forEach(([key, val]) => {
288
+ if (key in result && result[key] !== undefined)
289
+ throw new db_decorators_1.InternalError(`Transient property ${key} already exists on model ${m.constructor.name}. should be impossible`);
290
+ result[key] = val;
291
+ });
292
+ }
293
+ if (metadata) {
294
+ log.silly(`Passing along ${this.flavour} persistence metadata for ${m.constructor.name} id ${id}: ${metadata}`);
295
+ Object.defineProperty(result, core_1.PersistenceKeys.METADATA, {
296
+ enumerable: false,
297
+ configurable: false,
298
+ writable: false,
299
+ value: metadata,
300
+ });
301
+ }
302
+ return result;
303
+ }
304
+ /**
305
+ * @description Creates an index for a model
306
+ * @summary This method is not implemented for Fabric and will throw an error
307
+ * @template M - Type extending Model
308
+ * @param {Constructor<M>} models - The model constructor
309
+ * @return {Promise<void>} Promise that will throw an error
310
+ */
311
+ index(models) {
312
+ throw new Error();
313
+ }
314
+ /**
315
+ * @description Creates a single record
316
+ * @summary Submits a transaction to create a record in the Fabric ledger
317
+ * @param {string} tableName - The name of the table/collection
318
+ * @param {string | number} id - The record identifier
319
+ * @param {Record<string, any>} model - The record data
320
+ * @param {Record<string, any>} transient - Transient data for the transaction
321
+ * @return {Promise<Record<string, any>>} Promise resolving to the created record
322
+ */
323
+ async create(tableName, id, model, transient) {
324
+ const log = this.log.for(this.create);
325
+ log.verbose(`adding entry to ${tableName} table`);
326
+ log.debug(`pk: ${id}`);
327
+ const result = await this.submitTransaction(db_decorators_1.OperationKeys.CREATE, [this.serializer.serialize(model, tableName)], transient);
328
+ return this.serializer.deserialize(this.decode(result));
329
+ }
330
+ /**
331
+ * @description Reads a single record
332
+ * @summary Evaluates a transaction to read a record from the Fabric ledger
333
+ * @param {string} tableName - The name of the table/collection
334
+ * @param {string | number} id - The record identifier
335
+ * @return {Promise<Record<string, any>>} Promise resolving to the retrieved record
336
+ */
337
+ async read(tableName, id) {
338
+ const log = this.log.for(this.read);
339
+ log.verbose(`reading entry from ${tableName} table`);
340
+ log.debug(`pk: ${id}`);
341
+ const result = await this.evaluateTransaction(db_decorators_1.OperationKeys.READ, [
342
+ id.toString(),
343
+ ]);
344
+ return this.serializer.deserialize(this.decode(result));
345
+ }
346
+ /**
347
+ * @description Updates a single record
348
+ * @summary Submits a transaction to update a record in the Fabric ledger
349
+ * @param {string} tableName - The name of the table/collection
350
+ * @param {string | number} id - The record identifier
351
+ * @param {Record<string, any>} model - The updated record data
352
+ * @param {Record<string, any>} transient - Transient data for the transaction
353
+ * @return {Promise<Record<string, any>>} Promise resolving to the updated record
354
+ */
355
+ async update(tableName, id, model, transient) {
356
+ const log = this.log.for(this.update);
357
+ log.verbose(`updating entry to ${tableName} table`);
358
+ log.debug(`pk: ${id}`);
359
+ const result = await this.submitTransaction(db_decorators_1.OperationKeys.UPDATE, [this.serializer.serialize(model, tableName)], transient);
360
+ return this.serializer.deserialize(this.decode(result));
361
+ }
362
+ /**
363
+ * @description Deletes a single record
364
+ * @summary Submits a transaction to delete a record from the Fabric ledger
365
+ * @param {string} tableName - The name of the table/collection
366
+ * @param {string | number} id - The record identifier to delete
367
+ * @return {Promise<Record<string, any>>} Promise resolving to the deleted record
368
+ */
369
+ async delete(tableName, id) {
370
+ const log = this.log.for(this.delete);
371
+ log.verbose(`deleting entry from ${tableName} table`);
372
+ log.debug(`pk: ${id}`);
373
+ const result = await this.submitTransaction(db_decorators_1.OperationKeys.DELETE, [
374
+ tableName,
375
+ id,
376
+ ]);
377
+ return this.serializer.deserialize(this.decode(result));
378
+ }
379
+ /**
380
+ * @description Executes a raw query against the Fabric ledger
381
+ * @summary Evaluates a transaction to perform a query using Mango Query syntax
382
+ * @template V - The return type
383
+ * @param {MangoQuery} rawInput - The Mango Query to execute
384
+ * @param {boolean} process - Whether to process the result
385
+ * @return {Promise<V>} Promise resolving to the query result
386
+ * @mermaid
387
+ * sequenceDiagram
388
+ * participant Client
389
+ * participant FabricAdapter
390
+ * participant Contract
391
+ * participant Chaincode
392
+ *
393
+ * Client->>FabricAdapter: raw(rawInput, process)
394
+ * FabricAdapter->>FabricAdapter: JSON.stringify(rawInput)
395
+ * FabricAdapter->>FabricAdapter: evaluateTransaction("query", [input])
396
+ * FabricAdapter->>Contract: evaluate("query", proposalOptions)
397
+ * Contract->>Chaincode: invoke
398
+ * Chaincode-->>Contract: response
399
+ * Contract-->>FabricAdapter: result
400
+ * FabricAdapter->>FabricAdapter: JSON.parse(decode(result))
401
+ * FabricAdapter->>FabricAdapter: Process result based on type
402
+ * FabricAdapter-->>Client: processed result
403
+ */
404
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
405
+ async raw(rawInput, process) {
406
+ const log = this.log.for(this.raw);
407
+ log.info(`Performing raw query on table`);
408
+ log.debug(`processing raw input for query: ${JSON.stringify(rawInput)}`);
409
+ let input;
410
+ try {
411
+ input = JSON.stringify(rawInput);
412
+ }
413
+ catch (e) {
414
+ throw new db_decorators_1.SerializationError(`Failed to process raw input for query: ${e}`);
415
+ }
416
+ let transactionResult;
417
+ try {
418
+ transactionResult = await this.evaluateTransaction("query", [input]);
419
+ }
420
+ catch (e) {
421
+ throw this.parseError(e);
422
+ }
423
+ let result;
424
+ try {
425
+ result = JSON.parse(this.decode(transactionResult));
426
+ }
427
+ catch (e) {
428
+ throw new db_decorators_1.SerializationError(`Failed to process result: ${e}`);
429
+ }
430
+ const parseRecord = (record) => {
431
+ if (decorator_validation_1.Model.isModel(record))
432
+ return decorator_validation_1.Model.build(record);
433
+ return record;
434
+ };
435
+ if (Array.isArray(result)) {
436
+ if (!result.length)
437
+ return result;
438
+ const el = result[0];
439
+ if (decorator_validation_1.Model.isModel(el))
440
+ // if the first one is a model, all are models
441
+ return result.map((el) => decorator_validation_1.Model.build(el));
442
+ return result;
443
+ }
444
+ return parseRecord(result);
445
+ }
446
+ /**
447
+ * @description Gets or creates a gRPC client for the Fabric peer
448
+ * @summary Returns a cached client or creates a new one if none exists
449
+ * @return {Promise<Client>} Promise resolving to the gRPC client
450
+ */
451
+ getClient() {
452
+ if (!this._client)
453
+ this._client = FabricClientAdapter.getClient(this.config);
454
+ return this._client;
455
+ }
456
+ /**
457
+ * @description Gets a Gateway instance for the Fabric network
458
+ * @summary Creates a new Gateway instance using the current client
459
+ * @return {Promise<Gateway>} Promise resolving to the Gateway instance
460
+ */
461
+ async Gateway() {
462
+ return FabricClientAdapter.getGateway(this.config, this.client);
463
+ }
464
+ /**
465
+ * @description Gets a Contract instance for the Fabric chaincode
466
+ * @summary Creates a new Contract instance using the current Gateway
467
+ * @return {Promise<Contrakt>} Promise resolving to the Contract instance
468
+ */
469
+ async Contract() {
470
+ return FabricClientAdapter.getContract(await this.Gateway(), this.config);
471
+ }
472
+ /**
473
+ * @description Executes a transaction on the Fabric network
474
+ * @summary Submits or evaluates a transaction on the Fabric chaincode
475
+ * @param {string} api - The chaincode function to call
476
+ * @param {boolean} submit - Whether to submit (true) or evaluate (false) the transaction
477
+ * @param {any[]} [args] - Arguments to pass to the chaincode function
478
+ * @param {Record<string, string>} [transientData] - Transient data for the transaction
479
+ * @param {Array<string>} [endorsingOrganizations] - Organizations that must endorse the transaction
480
+ * @return {Promise<Uint8Array>} Promise resolving to the transaction result
481
+ * @mermaid
482
+ * sequenceDiagram
483
+ * participant FabricAdapter
484
+ * participant Gateway
485
+ * participant Contract
486
+ * participant Chaincode
487
+ *
488
+ * FabricAdapter->>Gateway: connect()
489
+ * FabricAdapter->>Contract: getContract()
490
+ * alt submit transaction
491
+ * FabricAdapter->>Contract: submit(api, proposalOptions)
492
+ * else evaluate transaction
493
+ * FabricAdapter->>Contract: evaluate(api, proposalOptions)
494
+ * end
495
+ * Contract->>Chaincode: invoke
496
+ * Chaincode-->>Contract: response
497
+ * Contract-->>FabricAdapter: result
498
+ * FabricAdapter->>Gateway: close()
499
+ */
500
+ async transaction(api, submit = true, args, transientData, endorsingOrganizations) {
501
+ const log = this.log.for(this.transaction);
502
+ const gateway = await this.Gateway();
503
+ try {
504
+ const contract = await this.Contract();
505
+ log.verbose(`${submit ? "Submit" : "Evaluate"}ting transaction ${this.config.contractName}.${api}`);
506
+ log.debug(`args: ${args?.map((a) => a.toString()).join("\n") || "none"}`);
507
+ const method = submit ? contract.submit : contract.evaluate;
508
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
509
+ endorsingOrganizations = endorsingOrganizations?.length
510
+ ? endorsingOrganizations
511
+ : undefined;
512
+ const proposalOptions = {
513
+ arguments: args || [],
514
+ transientData: transientData,
515
+ // ...(endorsingOrganizations && { endorsingOrganizations }) // mspId list
516
+ };
517
+ return await method.call(contract, api, proposalOptions);
518
+ }
519
+ catch (e) {
520
+ if (e.code === 10) {
521
+ throw new Error(`${e.details[0].message}`);
522
+ }
523
+ throw this.parseError(e);
524
+ }
525
+ finally {
526
+ this.log.debug(`Closing ${this.config.mspId} gateway connection`);
527
+ gateway.close();
528
+ }
529
+ }
530
+ /**
531
+ * @description Parses an error into a BaseError
532
+ * @summary Converts any error into a standardized BaseError
533
+ * @param {Error | string} err - The error to parse
534
+ * @param {string} [reason] - Optional reason for the error
535
+ * @return {BaseError} The parsed error
536
+ */
537
+ parseError(err, reason) {
538
+ return FabricClientAdapter.parseError(err, reason);
539
+ }
540
+ /**
541
+ * @description Submits a transaction to the Fabric network
542
+ * @summary Executes a transaction that modifies the ledger state
543
+ * @param {string} api - The chaincode function to call
544
+ * @param {any[]} [args] - Arguments to pass to the chaincode function
545
+ * @param {Record<string, string>} [transientData] - Transient data for the transaction
546
+ * @param {Array<string>} [endorsingOrganizations] - Organizations that must endorse the transaction
547
+ * @return {Promise<Uint8Array>} Promise resolving to the transaction result
548
+ */
549
+ async submitTransaction(api, args, transientData, endorsingOrganizations) {
550
+ return this.transaction(api, true, args, transientData, endorsingOrganizations);
551
+ }
552
+ /**
553
+ * @description Evaluates a transaction on the Fabric network
554
+ * @summary Executes a transaction that does not modify the ledger state
555
+ * @param {string} api - The chaincode function to call
556
+ * @param {any[]} [args] - Arguments to pass to the chaincode function
557
+ * @param {Record<string, string>} [transientData] - Transient data for the transaction
558
+ * @param {Array<string>} [endorsingOrganizations] - Organizations that must endorse the transaction
559
+ * @return {Promise<Uint8Array>} Promise resolving to the transaction result
560
+ */
561
+ async evaluateTransaction(api, args, transientData, endorsingOrganizations) {
562
+ return this.transaction(api, false, args, transientData, endorsingOrganizations);
563
+ }
564
+ /**
565
+ * @description Closes the connection to the Fabric network
566
+ * @summary Closes the gRPC client if it exists
567
+ * @return {Promise<void>} Promise that resolves when the client is closed
568
+ */
569
+ async close() {
570
+ if (this.client) {
571
+ this.log.verbose(`Closing ${this.config.mspId} gateway client`);
572
+ this.client.close();
573
+ }
574
+ }
575
+ /**
576
+ * @description Gets a Contract instance from a Gateway
577
+ * @summary Retrieves a chaincode contract from the specified network
578
+ * @param {Gateway} gateway - The Gateway instance
579
+ * @param {PeerConfig} config - The peer configuration
580
+ * @return {Contrakt} The Contract instance
581
+ */
582
+ static getContract(gateway, config) {
583
+ const log = this.log.for(this.getContract);
584
+ const network = this.getNetwork(gateway, config.channel);
585
+ let contract;
586
+ try {
587
+ log.debug(`Retrieving chaincode ${config.chaincodeName} contract ${config.contractName} from network ${config.channel}`);
588
+ contract = network.getContract(config.chaincodeName, config.contractName);
589
+ }
590
+ catch (e) {
591
+ throw this.parseError(e);
592
+ }
593
+ return contract;
594
+ }
595
+ /**
596
+ * @description Gets a Network instance from a Gateway
597
+ * @summary Connects to a specific channel on the Fabric network
598
+ * @param {Gateway} gateway - The Gateway instance
599
+ * @param {string} channelName - The name of the channel to connect to
600
+ * @return {Network} The Network instance
601
+ */
602
+ static getNetwork(gateway, channelName) {
603
+ const log = this.log.for(this.getNetwork);
604
+ let network;
605
+ try {
606
+ log.debug(`Connecting to channel ${channelName}`);
607
+ network = gateway.getNetwork(channelName);
608
+ }
609
+ catch (e) {
610
+ throw this.parseError(e);
611
+ }
612
+ return network;
613
+ }
614
+ /**
615
+ * @description Gets a Gateway instance for connecting to the Fabric network
616
+ * @summary Creates a Gateway using the provided configuration and client
617
+ * @param {PeerConfig} config - The peer configuration
618
+ * @param {Client} [client] - Optional gRPC client, will be created if not provided
619
+ * @return {Promise<Gateway>} Promise resolving to the Gateway instance
620
+ */
621
+ static async getGateway(config, client) {
622
+ return (await this.getConnection(client || (await this.getClient(config)), config));
623
+ }
624
+ /**
625
+ * @description Creates a gRPC client for connecting to a Fabric peer
626
+ * @summary Initializes a client with TLS credentials for secure communication
627
+ * @param {PeerConfig} config - The peer configuration
628
+ * @return {Client} Promise resolving to the gRPC client
629
+ */
630
+ static getClient(config) {
631
+ const log = this.log.for(this.getClient);
632
+ log.debug(`generating TLS credentials for msp ${config.mspId}`);
633
+ const tlsCredentials = grpc.credentials.createSsl(typeof config.tlsCert === "string"
634
+ ? Buffer.from(config.tlsCert)
635
+ : config.tlsCert);
636
+ log.debug(`generating Gateway Client for url ${config.peerEndpoint}`);
637
+ return new grpc_js_1.Client(config.peerEndpoint, tlsCredentials);
638
+ }
639
+ /**
640
+ * @description Establishes a connection to the Fabric network
641
+ * @summary Creates a Gateway connection with identity and signer
642
+ * @param {Client} client - The gRPC client
643
+ * @param {PeerConfig} config - The peer configuration
644
+ * @return {Promise<Gateway>} Promise resolving to the connected Gateway
645
+ * @mermaid
646
+ * sequenceDiagram
647
+ * participant Caller
648
+ * participant FabricAdapter
649
+ * participant Identity
650
+ * participant Signer
651
+ * participant Gateway
652
+ *
653
+ * Caller->>FabricAdapter: getConnection(client, config)
654
+ * FabricAdapter->>Identity: getIdentity(mspId, certDirectoryPath)
655
+ * Identity-->>FabricAdapter: identity
656
+ * FabricAdapter->>Signer: getSigner(keyDirectoryPath)
657
+ * Signer-->>FabricAdapter: signer
658
+ * FabricAdapter->>FabricAdapter: Create ConnectOptions
659
+ * FabricAdapter->>Gateway: connect(options)
660
+ * Gateway-->>FabricAdapter: gateway
661
+ * FabricAdapter-->>Caller: gateway
662
+ */
663
+ static async getConnection(client, config) {
664
+ const log = this.log.for(this.getConnection);
665
+ log.debug(`Retrieving Peer Identity for ${config.mspId} under ${config.certCertOrDirectoryPath}`);
666
+ const identity = await (0, fabric_fs_1.getIdentity)(config.mspId, config.certCertOrDirectoryPath);
667
+ log.debug(`Retrieving signer key from ${config.keyCertOrDirectoryPath}`);
668
+ const signer = await (0, fabric_fs_1.getSigner)(config.keyCertOrDirectoryPath);
669
+ const options = {
670
+ client,
671
+ identity: identity,
672
+ signer: signer,
673
+ // Default timeouts for different gRPC calls
674
+ evaluateOptions: () => {
675
+ return { deadline: Date.now() + 5000 }; // 5 seconds
676
+ },
677
+ endorseOptions: () => {
678
+ return { deadline: Date.now() + 15000 }; // 15 seconds
679
+ },
680
+ submitOptions: () => {
681
+ return { deadline: Date.now() + 5000 }; // 5 seconds
682
+ },
683
+ commitStatusOptions: () => {
684
+ return { deadline: Date.now() + 60000 }; // 1 minute
685
+ },
686
+ };
687
+ log.debug(`Connecting to ${config.mspId}`);
688
+ return (0, fabric_gateway_1.connect)(options);
689
+ }
690
+ /**
691
+ * @description Creates a new Dispatch instance for the Fabric client.
692
+ * @summary This function is responsible for creating a new FabricClientDispatch instance that can be used to interact with the Fabric network.
693
+ * @returns {Dispatch} A new Dispatch instance configured for the Fabric client.
694
+ * @remarks The Dispatch instance is used to encapsulate the logic for interacting with the Fabric network, such as submitting transactions or querying data.
695
+ * @example
696
+ * const fabricDispatch = fabricClientAdapter.Dispatch();
697
+ * fabricDispatch.submitTransaction('createProduct', { name: 'Product A', price: 100 });
698
+ */
699
+ Dispatch() {
700
+ return new FabricClientDispatch_1.FabricClientDispatch(this.getClient());
701
+ }
702
+ /**
703
+ * @description Parses an error into a BaseError
704
+ * @summary Converts any error into a standardized BaseError using the parent class implementation
705
+ * @param {Error | string} err - The error to parse
706
+ * @param {string} [reason] - Optional reason for the error
707
+ * @return {BaseError} The parsed error
708
+ */
709
+ static parseError(err, reason) {
710
+ return super.parseError(err, reason);
711
+ }
712
+ }
713
+ exports.FabricClientAdapter = FabricClientAdapter;
714
+ __decorate([
715
+ (0, logging_1.debug)(true)
716
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
717
+ ,
718
+ __metadata("design:type", Function),
719
+ __metadata("design:paramtypes", [Object]),
720
+ __metadata("design:returntype", Promise)
721
+ ], FabricClientAdapter.prototype, "index", null);
722
+ __decorate([
723
+ (0, logging_1.debug)(true),
724
+ (0, core_1.final)(),
725
+ __metadata("design:type", Function),
726
+ __metadata("design:paramtypes", [String, Object, Object, Object]),
727
+ __metadata("design:returntype", Promise)
728
+ ], FabricClientAdapter.prototype, "create", null);
729
+ __decorate([
730
+ (0, logging_1.debug)(true),
731
+ (0, core_1.final)(),
732
+ __metadata("design:type", Function),
733
+ __metadata("design:paramtypes", [String, Object]),
734
+ __metadata("design:returntype", Promise)
735
+ ], FabricClientAdapter.prototype, "read", null);
736
+ __decorate([
737
+ (0, logging_1.debug)(true),
738
+ (0, core_1.final)(),
739
+ __metadata("design:type", Function),
740
+ __metadata("design:paramtypes", [String, Object, Object, Object]),
741
+ __metadata("design:returntype", Promise)
742
+ ], FabricClientAdapter.prototype, "update", null);
743
+ __decorate([
744
+ (0, logging_1.debug)(true),
745
+ (0, core_1.final)(),
746
+ __metadata("design:type", Function),
747
+ __metadata("design:paramtypes", [String, Object]),
748
+ __metadata("design:returntype", Promise)
749
+ ], FabricClientAdapter.prototype, "delete", null);
750
+ __decorate([
751
+ (0, logging_1.debug)(true)
752
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
753
+ ,
754
+ __metadata("design:type", Function),
755
+ __metadata("design:paramtypes", [Object, Boolean]),
756
+ __metadata("design:returntype", Promise)
757
+ ], FabricClientAdapter.prototype, "raw", null);
758
+ FabricClientAdapter.decoration();
759
+ core_1.Adapter.setCurrent(constants_1.FabricFlavour);
760
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRmFicmljQ2xpZW50QWRhcHRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGllbnQvRmFicmljQ2xpZW50QWRhcHRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSx1REFBd0U7QUFDeEUsMkNBQXVDO0FBQ3ZDLG9EQUFzQztBQUV0Qyx5RUFJd0M7QUFDeEMsK0NBQTJEO0FBRTNELGdFQU9xQztBQUNyQywrQ0FBcUQ7QUFDckQsMkRBUWlDO0FBQ2pDLHlDQU13QjtBQUN4Qix5RUFBa0U7QUFDbEUseURBQW9EO0FBQ3BELHVFQUE4RDtBQUM5RCxxRUFBOEQ7QUFFOUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0RHO0FBQ0gsTUFBYSxtQkFBb0IsU0FBUSw0QkFLeEM7SUFDQzs7T0FFRzthQUNZLFlBQU8sR0FBRyxJQUFJLFdBQVcsQ0FBQyxNQUFNLENBQUMsQUFBMUIsQ0FBMkI7YUFFbEMsZUFBVSxHQUFHLElBQUksbUNBQWdCLEVBQUUsQUFBekIsQ0FBMEI7SUFFbkQ7O09BRUc7YUFDWSxRQUFHLEdBQVcsaUJBQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLENBQUMsQUFBM0MsQ0FBNEM7SUFFOUQ7Ozs7T0FJRztJQUNILElBQXVCLEdBQUc7UUFDeEIsT0FBTyxtQkFBbUIsQ0FBQyxHQUFHLENBQUM7SUFDakMsQ0FBQztJQUtEOzs7OztPQUtHO0lBQ0gsWUFBWSxNQUFrQixFQUFFLEtBQWM7UUFDNUMsS0FBSyxDQUFDLE1BQU0sRUFBRSx5QkFBYSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBVm5CLGVBQVUsR0FDM0IsbUJBQW1CLENBQUMsVUFBVSxDQUFDO0lBVWpDLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILE1BQU0sQ0FBQyxJQUFnQjtRQUNyQixPQUFPLG1CQUFtQixDQUFDLE9BQU8s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LEdBQUU7Ozs7aURBZ0JQO0FBV0s7SUFGTCxJQUFBLGVBQUssRUFBQyxJQUFJLENBQUM7SUFDWCxJQUFBLFlBQUssR0FBRTs7OztpREFhUDtBQTZCSztJQUZMLElBQUEsZUFBSyxFQUFDLElBQUksQ0FBQztJQUNaLDZEQUE2RDs7Ozs7OENBeUM1RDtBQTJVSCxtQkFBbUIsQ0FBQyxVQUFVLEVBQUUsQ0FBQztBQUNqQyxjQUFPLENBQUMsVUFBVSxDQUFDLHlCQUFhLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvdWNoREJBZGFwdGVyLCB0eXBlIE1hbmdvUXVlcnkgfSBmcm9tIFwiQGRlY2FmLXRzL2Zvci1jb3VjaGRiXCI7XG5pbXBvcnQgeyBDbGllbnQgfSBmcm9tIFwiQGdycGMvZ3JwYy1qc1wiO1xuaW1wb3J0ICogYXMgZ3JwYyBmcm9tIFwiQGdycGMvZ3JwYy1qc1wiO1xuXG5pbXBvcnQge1xuICB0eXBlIENvbnN0cnVjdG9yLFxuICBNb2RlbCxcbiAgdHlwZSBTZXJpYWxpemVyLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBkZWJ1ZywgTG9nZ2VyLCBMb2dnaW5nIH0gZnJvbSBcIkBkZWNhZi10cy9sb2dnaW5nXCI7XG5pbXBvcnQgeyBGYWJyaWNGbGFncywgUGVlckNvbmZpZyB9IGZyb20gXCIuLi9zaGFyZWQvdHlwZXNcIjtcbmltcG9ydCB7XG4gIGNvbm5lY3QsXG4gIENvbm5lY3RPcHRpb25zLFxuICBHYXRld2F5LFxuICBOZXR3b3JrLFxuICBQcm9wb3NhbE9wdGlvbnMsXG4gIENvbnRyYWN0IGFzIENvbnRyYWt0LFxufSBmcm9tIFwiQGh5cGVybGVkZ2VyL2ZhYnJpYy1nYXRld2F5XCI7XG5pbXBvcnQgeyBnZXRJZGVudGl0eSwgZ2V0U2lnbmVyIH0gZnJvbSBcIi4vZmFicmljLWZzXCI7XG5pbXBvcnQge1xuICBCYXNlRXJyb3IsXG4gIENvbnRleHQsXG4gIEludGVybmFsRXJyb3IsXG4gIE9wZXJhdGlvbktleXMsXG4gIFNlcmlhbGl6YXRpb25FcnJvcixcbiAgQnVsa0NydWRPcGVyYXRpb25LZXlzLFxuICBtb2RlbFRvVHJhbnNpZW50LFxufSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7XG4gIEFkYXB0ZXIsXG4gIERpc3BhdGNoLFxuICBmaW5hbCxcbiAgUGVyc2lzdGVuY2VLZXlzLFxuICBSZXBvc2l0b3J5LFxufSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IEZhYnJpY0NsaWVudFJlcG9zaXRvcnkgfSBmcm9tIFwiLi9GYWJyaWNDbGllbnRSZXBvc2l0b3J5XCI7XG5pbXBvcnQgeyBGYWJyaWNGbGF2b3VyIH0gZnJvbSBcIi4uL3NoYXJlZC9jb25zdGFudHNcIjtcbmltcG9ydCB7IENsaWVudFNlcmlhbGl6ZXIgfSBmcm9tIFwiLi4vc2hhcmVkL0NsaWVudFNlcmlhbGl6ZXJcIjtcbmltcG9ydCB7IEZhYnJpY0NsaWVudERpc3BhdGNoIH0gZnJvbSBcIi4vRmFicmljQ2xpZW50RGlzcGF0Y2hcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQWRhcHRlciBmb3IgaW50ZXJhY3Rpbmcgd2l0aCBIeXBlcmxlZGdlciBGYWJyaWMgbmV0d29ya3NcbiAqIEBzdW1tYXJ5IFRoZSBGYWJyaWNBZGFwdGVyIGV4dGVuZHMgQ291Y2hEQkFkYXB0ZXIgdG8gcHJvdmlkZSBhIHNlYW1sZXNzIGludGVyZmFjZSBmb3IgaW50ZXJhY3Rpbmcgd2l0aCBIeXBlcmxlZGdlciBGYWJyaWMgbmV0d29ya3MuXG4gKiBJdCBoYW5kbGVzIGNvbm5lY3Rpb24gbWFuYWdlbWVudCwgdHJhbnNhY3Rpb24gc3VibWlzc2lvbiwgYW5kIENSVUQgb3BlcmF0aW9ucyBhZ2FpbnN0IEZhYnJpYyBjaGFpbmNvZGUuXG4gKiBAdGVtcGxhdGUgUGVlckNvbmZpZyAtIENvbmZpZ3VyYXRpb24gdHlwZSBmb3IgY29ubmVjdGluZyB0byBhIEZhYnJpYyBwZWVyXG4gKiBAdGVtcGxhdGUgRmFicmljRmxhZ3MgLSBGbGFncyBzcGVjaWZpYyB0byBGYWJyaWMgb3BlcmF0aW9uc1xuICogQHRlbXBsYXRlIENvbnRleHQ8RmFicmljRmxhZ3M+IC0gQ29udGV4dCB0eXBlIGNvbnRhaW5pbmcgRmFicmljLXNwZWNpZmljIGZsYWdzXG4gKiBAcGFyYW0gY29uZmlnIC0gQ29uZmlndXJhdGlvbiBmb3IgY29ubmVjdGluZyB0byBhIEZhYnJpYyBwZWVyXG4gKiBAcGFyYW0gYWxpYXMgLSBPcHRpb25hbCBhbGlhcyBmb3IgdGhlIGFkYXB0ZXIgaW5zdGFuY2VcbiAqIEBjbGFzcyBGYWJyaWNDbGllbnRBZGFwdGVyXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogLy8gQ3JlYXRlIGEgbmV3IEZhYnJpY0FkYXB0ZXIgaW5zdGFuY2VcbiAqIGNvbnN0IGNvbmZpZzogUGVlckNvbmZpZyA9IHtcbiAqICAgbXNwSWQ6ICdPcmcxTVNQJyxcbiAqICAgcGVlckVuZHBvaW50OiAnbG9jYWxob3N0OjcwNTEnLFxuICogICBjaGFubmVsTmFtZTogJ215Y2hhbm5lbCcsXG4gKiAgIGNoYWluY29kZU5hbWU6ICdteWNjJyxcbiAqICAgY29udHJhY3ROYW1lOiAnbXljb250cmFjdCcsXG4gKiAgIHRsc0NlcnRQYXRoOiAnL3BhdGgvdG8vdGxzL2NlcnQnLFxuICogICBjZXJ0RGlyZWN0b3J5UGF0aDogJy9wYXRoL3RvL2NlcnQvZGlyJyxcbiAqICAga2V5RGlyZWN0b3J5UGF0aDogJy9wYXRoL3RvL2tleS9kaXInXG4gKiB9O1xuICpcbiAqIGNvbnN0IGFkYXB0ZXIgPSBuZXcgRmFicmljQWRhcHRlcihjb25maWcsICdvcmcxLWFkYXB0ZXInKTtcbiAqXG4gKiAvLyBVc2UgdGhlIGFkYXB0ZXIgdG8gaW50ZXJhY3Qgd2l0aCB0aGUgRmFicmljIG5ldHdvcmtcbiAqIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGFkYXB0ZXIucmVhZCgndXNlcnMnLCAndXNlcjEnLCBteVNlcmlhbGl6ZXIpO1xuICogYGBgXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICogICBwYXJ0aWNpcGFudCBGYWJyaWNBZGFwdGVyXG4gKiAgIHBhcnRpY2lwYW50IEdhdGV3YXlcbiAqICAgcGFydGljaXBhbnQgTmV0d29ya1xuICogICBwYXJ0aWNpcGFudCBDb250cmFjdFxuICogICBwYXJ0aWNpcGFudCBDaGFpbmNvZGVcbiAqXG4gKiAgIENsaWVudC0+PkZhYnJpY0FkYXB0ZXI6IGNyZWF0ZSh0YWJsZU5hbWUsIGlkLCBtb2RlbCwgdHJhbnNpZW50LCBzZXJpYWxpemVyKVxuICogICBGYWJyaWNBZGFwdGVyLT4+RmFicmljQWRhcHRlcjogc3VibWl0VHJhbnNhY3Rpb24oT3BlcmF0aW9uS2V5cy5DUkVBVEUsIFtzZXJpYWxpemVkTW9kZWxdLCB0cmFuc2llbnQpXG4gKiAgIEZhYnJpY0FkYXB0ZXItPj5HYXRld2F5OiBjb25uZWN0KClcbiAqICAgR2F0ZXdheS0+Pk5ldHdvcms6IGdldE5ldHdvcmsoY2hhbm5lbE5hbWUpXG4gKiAgIE5ldHdvcmstPj5Db250cmFjdDogZ2V0Q29udHJhY3QoY2hhaW5jb2RlTmFtZSwgY29udHJhY3ROYW1lKVxuICogICBGYWJyaWNBZGFwdGVyLT4+Q29udHJhY3Q6IHN1Ym1pdChhcGksIHByb3Bvc2FsT3B0aW9ucylcbiAqICAgQ29udHJhY3QtPj5DaGFpbmNvZGU6IGludm9rZVxuICogICBDaGFpbmNvZGUtLT4+Q29udHJhY3Q6IHJlc3BvbnNlXG4gKiAgIENvbnRyYWN0LS0+PkZhYnJpY0FkYXB0ZXI6IHJlc3VsdFxuICogICBGYWJyaWNBZGFwdGVyLT4+RmFicmljQWRhcHRlcjogZGVjb2RlKHJlc3VsdClcbiAqICAgRmFicmljQWRhcHRlci0+PkZhYnJpY0FkYXB0ZXI6IHNlcmlhbGl6ZXIuZGVzZXJpYWxpemUoZGVjb2RlZFJlc3VsdClcbiAqICAgRmFicmljQWRhcHRlci0tPj5DbGllbnQ6IGRlc2VyaWFsaXplZFJlc3VsdFxuICovXG5leHBvcnQgY2xhc3MgRmFicmljQ2xpZW50QWRhcHRlciBleHRlbmRzIENvdWNoREJBZGFwdGVyPFxuICBQZWVyQ29uZmlnLFxuICBDbGllbnQsXG4gIEZhYnJpY0ZsYWdzLFxuICBDb250ZXh0PEZhYnJpY0ZsYWdzPlxuPiB7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU3RhdGljIHRleHQgZGVjb2RlciBmb3IgY29udmVydGluZyBVaW50OEFycmF5IHRvIHN0cmluZ1xuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcihcInV0ZjhcIik7XG5cbiAgcHJpdmF0ZSBzdGF0aWMgc2VyaWFsaXplciA9IG5ldyBDbGllbnRTZXJpYWxpemVyKCk7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTdGF0aWMgbG9nZ2VyIGluc3RhbmNlIGZvciB0aGUgRmFicmljQWRhcHRlciBjbGFzc1xuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgbG9nOiBMb2dnZXIgPSBMb2dnaW5nLmZvcihGYWJyaWNDbGllbnRBZGFwdGVyKTtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEdldHMgdGhlIGxvZ2dlciBpbnN0YW5jZSBmb3IgdGhpcyBhZGFwdGVyXG4gICAqIEBzdW1tYXJ5IFJldHVybnMgdGhlIHN0YXRpYyBsb2dnZXIgaW5zdGFuY2UgZm9yIHRoZSBGYWJyaWNBZGFwdGVyIGNsYXNzXG4gICAqIEByZXR1cm4ge0xvZ2dlcn0gVGhlIGxvZ2dlciBpbnN0YW5jZVxuICAgKi9cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIGdldCBsb2coKTogTG9nZ2VyIHtcbiAgICByZXR1cm4gRmFicmljQ2xpZW50QWRhcHRlci5sb2c7XG4gIH1cblxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgc2VyaWFsaXplcjogU2VyaWFsaXplcjxhbnk+ID1cbiAgICBGYWJyaWNDbGllbnRBZGFwdGVyLnNlcmlhbGl6ZXI7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgbmV3IEZhYnJpY0FkYXB0ZXIgaW5zdGFuY2VcbiAgICogQHN1bW1hcnkgSW5pdGlhbGl6ZXMgYSBuZXcgYWRhcHRlciBmb3IgaW50ZXJhY3Rpbmcgd2l0aCBhIEh5cGVybGVkZ2VyIEZhYnJpYyBuZXR3b3JrXG4gICAqIEBwYXJhbSB7UGVlckNvbmZpZ30gY29uZmlnIC0gQ29uZmlndXJhdGlvbiBmb3IgY29ubmVjdGluZyB0byBhIEZhYnJpYyBwZWVyXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbYWxpYXNdIC0gT3B0aW9uYWwgYWxpYXMgZm9yIHRoZSBhZGFwdGVyIGluc3RhbmNlXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihjb25maWc6IFBlZXJDb25maWcsIGFsaWFzPzogc3RyaW5nKSB7XG4gICAgc3VwZXIoY29uZmlnLCBGYWJyaWNGbGF2b3VyLCBhbGlhcyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIERlY29kZXMgYSBVaW50OEFycmF5IHRvIGEgc3RyaW5nXG4gICAqIEBzdW1tYXJ5IENvbnZlcnRzIGJpbmFyeSBkYXRhIHJlY2VpdmVkIGZyb20gRmFicmljIHRvIGEgc3RyaW5nIHVzaW5nIFVURi04IGVuY29kaW5nXG4gICAqIEBwYXJhbSB7VWludDhBcnJheX0gZGF0YSAtIFRoZSBiaW5hcnkgZGF0YSB0byBkZWNvZGVcbiAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgZGVjb2RlZCBzdHJpbmdcbiAgICovXG4gIGRlY29kZShkYXRhOiBVaW50OEFycmF5KTogc3RyaW5nIHtcbiAgICByZXR1cm4gRmFicmljQ2xpZW50QWRhcHRlci5kZWNvZGVyLmRlY29kZShkYXRhKTtcbiAgfVxuXG4gIG92ZXJyaWRlIHJlcG9zaXRvcnk8TSBleHRlbmRzIE1vZGVsPHRydWUgfCBmYWxzZT4+KCk6IENvbnN0cnVjdG9yPFxuICAgIFJlcG9zaXRvcnk8XG4gICAgICBNLFxuICAgICAgTWFuZ29RdWVyeSxcbiAgICAgIEFkYXB0ZXI8XG4gICAgICAgIFBlZXJDb25maWcsXG4gICAgICAgIENsaWVudCxcbiAgICAgICAgTWFuZ29RdWVyeSxcbiAgICAgICAgRmFicmljRmxhZ3MsXG4gICAgICAgIENvbnRleHQ8RmFicmljRmxhZ3M+XG4gICAgICA+LFxuICAgICAgRmFicmljRmxhZ3MsXG4gICAgICBDb250ZXh0PEZhYnJpY0ZsYWdzPlxuICAgID5cbiAgPiB7XG4gICAgcmV0dXJuIEZhYnJpY0NsaWVudFJlcG9zaXRvcnk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgbXVsdGlwbGUgcmVjb3JkcyBpbiBhIHNpbmdsZSB0cmFuc2FjdGlvblxuICAgKiBAc3VtbWFyeSBTdWJtaXRzIGEgdHJhbnNhY3Rpb24gdG8gY3JlYXRlIG11bHRpcGxlIHJlY29yZHMgaW4gdGhlIEZhYnJpYyBsZWRnZXJcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZS9jb2xsZWN0aW9uXG4gICAqIEBwYXJhbSB7c3RyaW5nW10gfCBudW1iZXJbXX0gaWRzIC0gQXJyYXkgb2YgcmVjb3JkIGlkZW50aWZpZXJzXG4gICAqIEBwYXJhbSB7QXJyYXk8UmVjb3JkPHN0cmluZywgYW55Pj59IG1vZGVscyAtIEFycmF5IG9mIHJlY29yZCBkYXRhXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gdHJhbnNpZW50IC0gVHJhbnNpZW50IGRhdGEgZm9yIHRoZSB0cmFuc2FjdGlvblxuICAgKiBAcmV0dXJuIHtQcm9taXNlPEFycmF5PFJlY29yZDxzdHJpbmcsIGFueT4+Pn0gUHJvbWlzZSByZXNvbHZpbmcgdG8gdGhlIGNyZWF0ZWQgcmVjb3Jkc1xuICAgKi9cbiAgb3ZlcnJpZGUgYXN5bmMgY3JlYXRlQWxsKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkczogc3RyaW5nW10gfCBudW1iZXJbXSxcbiAgICBtb2RlbHM6IFJlY29yZDxzdHJpbmcsIGFueT5bXSxcbiAgICB0cmFuc2llbnQ6IFJlY29yZDxzdHJpbmcsIGFueT5cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+W10+IHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5jcmVhdGVBbGwpO1xuICAgIGlmIChpZHMubGVuZ3RoICE9PSBtb2RlbHMubGVuZ3RoKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgIGBJZHMgYW5kIG1vZGVscyBtdXN0IGhhdmUgdGhlIHNhbWUgbGVuZ3RoOiAke2lkcy5sZW5ndGh9ICE9ICR7bW9kZWxzLmxlbmd0aH1gXG4gICAgICApO1xuICAgIGxvZy5pbmZvKGBhZGRpbmcgJHtpZHMubGVuZ3RofSBlbnRyaWVzIHRvICR7dGFibGVOYW1lfSB0YWJsZWApO1xuICAgIGxvZy52ZXJib3NlKGBwa3M6ICR7aWRzfWApO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuc3VibWl0VHJhbnNhY3Rpb24oXG4gICAgICBCdWxrQ3J1ZE9wZXJhdGlvbktleXMuQ1JFQVRFX0FMTCxcbiAgICAgIFtpZHMsIG1vZGVscy5tYXAoKG0pID0+IHRoaXMuc2VyaWFsaXplci5zZXJpYWxpemUobSwgdGFibGVOYW1lKSldLFxuICAgICAgdHJhbnNpZW50XG4gICAgKTtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIEpTT04ucGFyc2UodGhpcy5kZWNvZGUocmVzdWx0KSkubWFwKChyOiBhbnkpID0+IEpTT04ucGFyc2UocikpO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHRocm93IG5ldyBTZXJpYWxpemF0aW9uRXJyb3IoZSBhcyBFcnJvcik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZWFkcyBtdWx0aXBsZSByZWNvcmRzIGluIGEgc2luZ2xlIHRyYW5zYWN0aW9uXG4gICAqIEBzdW1tYXJ5IFN1Ym1pdHMgYSB0cmFuc2FjdGlvbiB0byByZWFkIG11bHRpcGxlIHJlY29yZHMgZnJvbSB0aGUgRmFicmljIGxlZGdlclxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFibGVOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHRhYmxlL2NvbGxlY3Rpb25cbiAgICogQHBhcmFtIHtzdHJpbmdbXSB8IG51bWJlcltdfSBpZHMgLSBBcnJheSBvZiByZWNvcmQgaWRlbnRpZmllcnMgdG8gcmVhZFxuICAgKiBAcmV0dXJuIHtQcm9taXNlPEFycmF5PFJlY29yZDxzdHJpbmcsIGFueT4+Pn0gUHJvbWlzZSByZXNvbHZpbmcgdG8gdGhlIHJldHJpZXZlZCByZWNvcmRzXG4gICAqL1xuICBvdmVycmlkZSBhc3luYyByZWFkQWxsKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkczogc3RyaW5nW10gfCBudW1iZXJbXVxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT5bXT4ge1xuICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nLmZvcih0aGlzLnJlYWRBbGwpO1xuICAgIGxvZy5pbmZvKGByZWFkaW5nICR7aWRzLmxlbmd0aH0gZW50cmllcyB0byAke3RhYmxlTmFtZX0gdGFibGVgKTtcbiAgICBsb2cudmVyYm9zZShgcGtzOiAke2lkc31gKTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnN1Ym1pdFRyYW5zYWN0aW9uKFxuICAgICAgQnVsa0NydWRPcGVyYXRpb25LZXlzLlJFQURfQUxMLFxuICAgICAgW2lkc11cbiAgICApO1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gSlNPTi5wYXJzZSh0aGlzLmRlY29kZShyZXN1bHQpKS5tYXAoKHI6IGFueSkgPT4gSlNPTi5wYXJzZShyKSk7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgbmV3IFNlcmlhbGl6YXRpb25FcnJvcihlIGFzIEVycm9yKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFVwZGF0ZXMgbXVsdGlwbGUgcmVjb3JkcyBpbiBhIHNpbmdsZSB0cmFuc2FjdGlvblxuICAgKiBAc3VtbWFyeSBTdWJtaXRzIGEgdHJhbnNhY3Rpb24gdG8gdXBkYXRlIG11bHRpcGxlIHJlY29yZHMgaW4gdGhlIEZhYnJpYyBsZWRnZXJcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZS9jb2xsZWN0aW9uXG4gICAqIEBwYXJhbSB7c3RyaW5nW10gfCBudW1iZXJbXX0gaWRzIC0gQXJyYXkgb2YgcmVjb3JkIGlkZW50aWZpZXJzXG4gICAqIEBwYXJhbSB7QXJyYXk8UmVjb3JkPHN0cmluZywgYW55Pj59IG1vZGVscyAtIEFycmF5IG9mIHVwZGF0ZWQgcmVjb3JkIGRhdGFcbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSB0cmFuc2llbnQgLSBUcmFuc2llbnQgZGF0YSBmb3IgdGhlIHRyYW5zYWN0aW9uXG4gICAqIEByZXR1cm4ge1Byb21pc2U8QXJyYXk8UmVjb3JkPHN0cmluZywgYW55Pj4+fSBQcm9taXNlIHJlc29sdmluZyB0byB0aGUgdXBkYXRlZCByZWNvcmRzXG4gICAqL1xuICBvdmVycmlkZSBhc3luYyB1cGRhdGVBbGwoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWRzOiBzdHJpbmdbXSB8IG51bWJlcltdLFxuICAgIG1vZGVsczogUmVjb3JkPHN0cmluZywgYW55PltdLFxuICAgIHRyYW5zaWVudDogUmVjb3JkPHN0cmluZywgYW55PlxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT5bXT4ge1xuICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nLmZvcih0aGlzLnVwZGF0ZUFsbCk7XG4gICAgaWYgKGlkcy5sZW5ndGggIT09IG1vZGVscy5sZW5ndGgpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgYElkcyBhbmQgbW9kZWxzIG11c3QgaGF2ZSB0aGUgc2FtZSBsZW5ndGg6ICR7aWRzLmxlbmd0aH0gIT0gJHttb2RlbHMubGVuZ3RofWBcbiAgICAgICk7XG4gICAgbG9nLmluZm8oYHVwZGF0aW5nICR7aWRzLmxlbmd0aH0gZW50cmllcyB0byAke3RhYmxlTmFtZX0gdGFibGVgKTtcbiAgICBsb2cudmVyYm9zZShgcGtzOiAke2lkc31gKTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnN1Ym1pdFRyYW5zYWN0aW9uKFxuICAgICAgQnVsa0NydWRPcGVyYXRpb25LZXlzLlVQREFURV9BTEwsXG4gICAgICBbaWRzLCBtb2RlbHMubWFwKChtKSA9PiB0aGlzLnNlcmlhbGl6ZXIuc2VyaWFsaXplKG0sIHRhYmxlTmFtZSkpXSxcbiAgICAgIHRyYW5zaWVudFxuICAgICk7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBKU09OLnBhcnNlKHRoaXMuZGVjb2RlKHJlc3VsdCkpLm1hcCgocjogYW55KSA9PiBKU09OLnBhcnNlKHIpKTtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICB0aHJvdyBuZXcgU2VyaWFsaXphdGlvbkVycm9yKGUgYXMgRXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRGVsZXRlcyBtdWx0aXBsZSByZWNvcmRzIGluIGEgc2luZ2xlIHRyYW5zYWN0aW9uXG4gICAqIEBzdW1tYXJ5IFN1Ym1pdHMgYSB0cmFuc2FjdGlvbiB0byBkZWxldGUgbXVsdGlwbGUgcmVjb3JkcyBmcm9tIHRoZSBGYWJyaWMgbGVkZ2VyXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0YWJsZU5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgdGFibGUvY29sbGVjdGlvblxuICAgKiBAcGFyYW0ge0FycmF5PHN0cmluZyB8IG51bWJlciB8IGJpZ2ludD59IGlkcyAtIEFycmF5IG9mIHJlY29yZCBpZGVudGlmaWVycyB0byBkZWxldGVcbiAgICogQHBhcmFtIHtTZXJpYWxpemVyPGFueT59IHNlcmlhbGl6ZXIgLSBTZXJpYWxpemVyIGZvciB0aGUgbW9kZWwgZGF0YVxuICAgKiBAcmV0dXJuIHtQcm9taXNlPEFycmF5PFJlY29yZDxzdHJpbmcsIGFueT4+Pn0gUHJvbWlzZSByZXNvbHZpbmcgdG8gdGhlIGRlbGV0ZWQgcmVjb3Jkc1xuICAgKi9cbiAgb3ZlcnJpZGUgYXN5bmMgZGVsZXRlQWxsKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkczogKHN0cmluZyB8IG51bWJlciB8IGJpZ2ludClbXVxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT5bXT4ge1xuICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nLmZvcih0aGlzLmRlbGV0ZUFsbCk7XG4gICAgbG9nLmluZm8oYGRlbGV0aW5nICR7aWRzLmxlbmd0aH0gZW50cmllcyB0byAke3RhYmxlTmFtZX0gdGFibGVgKTtcbiAgICBsb2cudmVyYm9zZShgcGtzOiAke2lkc31gKTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnN1Ym1pdFRyYW5zYWN0aW9uKFxuICAgICAgQnVsa0NydWRPcGVyYXRpb25LZXlzLkRFTEVURV9BTEwsXG4gICAgICBbaWRzXVxuICAgICk7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBKU09OLnBhcnNlKHRoaXMuZGVjb2RlKHJlc3VsdCkpLm1hcCgocjogYW55KSA9PiBKU09OLnBhcnNlKHIpKTtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICB0aHJvdyBuZXcgU2VyaWFsaXphdGlvbkVycm9yKGUgYXMgRXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUHJlcGFyZXMgYSBtb2RlbCBmb3IgcGVyc2lzdGVuY2VcbiAgICogQHN1bW1hcnkgQ29udmVydHMgYSBtb2RlbCBpbnN0YW5jZSBpbnRvIGEgZm9ybWF0IHN1aXRhYmxlIGZvciBkYXRhYmFzZSBzdG9yYWdlLFxuICAgKiBoYW5kbGluZyBjb2x1bW4gbWFwcGluZyBhbmQgc2VwYXJhdGluZyB0cmFuc2llbnQgcHJvcGVydGllc1xuICAgKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlXG4gICAqIEBwYXJhbSB7TX0gbW9kZWwgLSBUaGUgbW9kZWwgaW5zdGFuY2UgdG8gcHJlcGFyZVxuICAgKiBAcGFyYW0gcGsgLSBUaGUgcHJpbWFyeSBrZXkgcHJvcGVydHkgbmFtZVxuICAgKiBAcmV0dXJuIFRoZSBwcmVwYXJlZCBkYXRhXG4gICAqL1xuICBvdmVycmlkZSBwcmVwYXJlPE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgbW9kZWw6IE0sXG4gICAgcGs6IGtleW9mIE1cbiAgKToge1xuICAgIHJlY29yZDogUmVjb3JkPHN0cmluZywgYW55PjtcbiAgICBpZDogc3RyaW5nO1xuICAgIHRyYW5zaWVudD86IFJlY29yZDxzdHJpbmcsIGFueT47XG4gIH0ge1xuICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nLmZvcih0aGlzLnByZXBhcmUpO1xuICAgIGNvbnN0IHNwbGl0ID0gbW9kZWxUb1RyYW5zaWVudChtb2RlbCk7XG4gICAgaWYgKChtb2RlbCBhcyBhbnkpW1BlcnNpc3RlbmNlS2V5cy5NRVRBREFUQV0pIHtcbiAgICAgIGxvZy5zaWxseShcbiAgICAgICAgYFBhc3NpbmcgYWxvbmcgcGVyc2lzdGVuY2UgbWV0YWRhdGEgZm9yICR7KG1vZGVsIGFzIGFueSlbUGVyc2lzdGVuY2VLZXlzLk1FVEFEQVRBXX1gXG4gICAgICApO1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHNwbGl0Lm1vZGVsLCBQZXJzaXN0ZW5jZUtleXMuTUVUQURBVEEsIHtcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICB2YWx1ZTogKG1vZGVsIGFzIGFueSlbUGVyc2lzdGVuY2VLZXlzLk1FVEFEQVRBXSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICByZWNvcmQ6IHNwbGl0Lm1vZGVsLFxuICAgICAgaWQ6IG1vZGVsW3BrXSBhcyBzdHJpbmcsXG4gICAgICB0cmFuc2llbnQ6IHNwbGl0LnRyYW5zaWVudCxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDb252ZXJ0cyBkYXRhYmFzZSBkYXRhIGJhY2sgaW50byBhIG1vZGVsIGluc3RhbmNlXG4gICAqIEBzdW1tYXJ5IFJlY29uc3RydWN0cyBhIG1vZGVsIGluc3RhbmNlIGZyb20gZGF0YWJhc2UgZGF0YSwgaGFuZGxpbmcgY29sdW1uIG1hcHBpbmdcbiAgICogYW5kIHJlYXR0YWNoaW5nIHRyYW5zaWVudCBwcm9wZXJ0aWVzXG4gICAqIEB0ZW1wbGF0ZSBNIC0gVGhlIG1vZGVsIHR5cGVcbiAgICogQHBhcmFtIG9iaiAtIFRoZSBkYXRhYmFzZSByZWNvcmRcbiAgICogQHBhcmFtIHtzdHJpbmd8Q29uc3RydWN0b3I8TT59IGNsYXp6IC0gVGhlIG1vZGVsIGNsYXNzIG9yIG5hbWVcbiAgICogQHBhcmFtIHBrIC0gVGhlIHByaW1hcnkga2V5IHByb3BlcnR5IG5hbWVcbiAgICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfGJpZ2ludH0gaWQgLSBUaGUgcHJpbWFyeSBrZXkgdmFsdWVcbiAgICogQHBhcmFtIFt0cmFuc2llbnRdIC0gVHJhbnNpZW50IHByb3BlcnRpZXMgdG8gcmVhdHRhY2hcbiAgICogQHJldHVybiB7TX0gVGhlIHJlY29uc3RydWN0ZWQgbW9kZWwgaW5zdGFuY2VcbiAgICovXG4gIG92ZXJyaWRlIHJldmVydDxNIGV4dGVuZHMgTW9kZWw+KFxuICAgIG9iajogUmVjb3JkPHN0cmluZywgYW55PixcbiAgICBjbGF6ejogc3RyaW5nIHwgQ29uc3RydWN0b3I8TT4sXG4gICAgcGs6IGtleW9mIE0sXG4gICAgaWQ6IHN0cmluZyB8IG51bWJlciB8IGJpZ2ludCxcbiAgICB0cmFuc2llbnQ/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gICk6IE0ge1xuICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nLmZvcih0aGlzLnJldmVydCk7XG4gICAgY29uc3Qgb2I6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcbiAgICBvYltwayBhcyBzdHJpbmddID0gaWQ7XG4gICAgY29uc3QgbSA9IChcbiAgICAgIHR5cGVvZiBjbGF6eiA9PT0gXCJzdHJpbmdcIiA/IE1vZGVsLmJ1aWxkKG9iLCBjbGF6eikgOiBuZXcgY2xhenoob2IpXG4gICAgKSBhcyBNO1xuICAgIGxvZy5zaWxseShgUmVidWlsZGluZyBtb2RlbCAke20uY29uc3RydWN0b3IubmFtZX0gaWQgJHtpZH1gKTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IG9ialtQZXJzaXN0ZW5jZUtleXMuTUVUQURBVEFdO1xuICAgIGNvbnN0IHJlc3VsdCA9IE9iamVjdC5rZXlzKG0pLnJlZHVjZSgoYWNjdW06IE0sIGtleSkgPT4ge1xuICAgICAgKGFjY3VtIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW2tleV0gPSBvYmpba2V5XTtcbiAgICAgIHJldHVybiBhY2N1bTtcbiAgICB9LCBtKTtcblxuICAgIGlmICh0cmFuc2llbnQpIHtcbiAgICAgIGxvZy52ZXJib3NlKFxuICAgICAgICBgcmUtYWRkaW5nIHRyYW5zaWVudCBwcm9wZXJ0aWVzOiAke09iamVjdC5rZXlzKHRyYW5zaWVudCkuam9pbihcIiwgXCIpfWBcbiAgICAgICk7XG4gICAgICBPYmplY3QuZW50cmllcyh0cmFuc2llbnQpLmZvckVhY2goKFtrZXksIHZhbF0pID0+IHtcbiAgICAgICAgaWYgKGtleSBpbiByZXN1bHQgJiYgKHJlc3VsdCBhcyBhbnkpW2tleV0gIT09IHVuZGVmaW5lZClcbiAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgICAgIGBUcmFuc2llbnQgcHJvcGVydHkgJHtrZXl9IGFscmVhZHkgZXhpc3RzIG9uIG1vZGVsICR7bS5jb25zdHJ1Y3Rvci5uYW1lfS4gc2hvdWxkIGJlIGltcG9zc2libGVgXG4gICAgICAgICAgKTtcbiAgICAgICAgcmVzdWx0W2tleSBhcyBrZXlvZiBNXSA9IHZhbDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChtZXRhZGF0YSkge1xuICAgICAgbG9nLnNpbGx5KFxuICAgICAgICBgUGFzc2luZyBhbG9uZyAke3RoaXMuZmxhdm91cn0gcGVyc2lzdGVuY2UgbWV0YWRhdGEgZm9yICR7bS5jb25zdHJ1Y3Rvci5uYW1lfSBpZCAke2lkfTogJHttZXRhZGF0YX1gXG4gICAgICApO1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHJlc3VsdCwgUGVyc2lzdGVuY2VLZXlzLk1FVEFEQVRBLCB7XG4gICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgICBjb25maWd1cmFibGU6IGZhbHNlLFxuICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICAgIHZhbHVlOiBtZXRhZGF0YSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYW4gaW5kZXggZm9yIGEgbW9kZWxcbiAgICogQHN1bW1hcnkgVGhpcyBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkIGZvciBGYWJyaWMgYW5kIHdpbGwgdGhyb3cgYW4gZXJyb3JcbiAgICogQHRlbXBsYXRlIE0gLSBUeXBlIGV4dGVuZGluZyBNb2RlbFxuICAgKiBAcGFyYW0ge0NvbnN0cnVjdG9yPE0+fSBtb2RlbHMgLSBUaGUgbW9kZWwgY29uc3RydWN0b3JcbiAgICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gUHJvbWlzZSB0aGF0IHdpbGwgdGhyb3cgYW4gZXJyb3JcbiAgICovXG4gIEBkZWJ1Zyh0cnVlKVxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIHByb3RlY3RlZCBpbmRleDxNPihtb2RlbHM6IENvbnN0cnVjdG9yPE0+KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBzaW5nbGUgcmVjb3JkXG4gICAqIEBzdW1tYXJ5IFN1Ym1pdHMgYSB0cmFuc2FjdGlvbiB0byBjcmVhdGUgYSByZWNvcmQgaW4gdGhlIEZhYnJpYyBsZWRnZXJcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZS9jb2xsZWN0aW9uXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgbnVtYmVyfSBpZCAtIFRoZSByZWNvcmQgaWRlbnRpZmllclxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IG1vZGVsIC0gVGhlIHJlY29yZCBkYXRhXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gdHJhbnNpZW50IC0gVHJhbnNpZW50IGRhdGEgZm9yIHRoZSB0cmFuc2FjdGlvblxuICAgKiBAcmV0dXJuIHtQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+fSBQcm9taXNlIHJlc29sdmluZyB0byB0aGUgY3JlYXRlZCByZWNvcmRcbiAgICovXG4gIEBkZWJ1Zyh0cnVlKVxuICBAZmluYWwoKVxuICBvdmVycmlkZSBhc3luYyBjcmVhdGUoXG4gICAgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgaWQ6IHN0cmluZyB8IG51bWJlcixcbiAgICBtb2RlbDogUmVjb3JkPHN0cmluZywgYW55PixcbiAgICB0cmFuc2llbnQ6IFJlY29yZDxzdHJpbmcsIGFueT5cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+PiB7XG4gICAgY29uc3QgbG9nID0gdGhpcy5sb2cuZm9yKHRoaXMuY3JlYXRlKTtcbiAgICBsb2cudmVyYm9zZShgYWRkaW5nIGVudHJ5IHRvICR7dGFibGVOYW1lfSB0YWJsZWApO1xuICAgIGxvZy5kZWJ1ZyhgcGs6ICR7aWR9YCk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5zdWJtaXRUcmFuc2FjdGlvbihcbiAgICAgIE9wZXJhdGlvbktleXMuQ1JFQVRFLFxuICAgICAgW3RoaXMuc2VyaWFsaXplci5zZXJpYWxpemUobW9kZWwsIHRhYmxlTmFtZSldLFxuICAgICAgdHJhbnNpZW50XG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5zZXJpYWxpemVyLmRlc2VyaWFsaXplKHRoaXMuZGVjb2RlKHJlc3VsdCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZWFkcyBhIHNpbmdsZSByZWNvcmRcbiAgICogQHN1bW1hcnkgRXZhbHVhdGVzIGEgdHJhbnNhY3Rpb24gdG8gcmVhZCBhIHJlY29yZCBmcm9tIHRoZSBGYWJyaWMgbGVkZ2VyXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0YWJsZU5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgdGFibGUvY29sbGVjdGlvblxuICAgKiBAcGFyYW0ge3N0cmluZyB8IG51bWJlcn0gaWQgLSBUaGUgcmVjb3JkIGlkZW50aWZpZXJcbiAgICogQHJldHVybiB7UHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+Pn0gUHJvbWlzZSByZXNvbHZpbmcgdG8gdGhlIHJldHJpZXZlZCByZWNvcmRcbiAgICovXG4gIEBkZWJ1Zyh0cnVlKVxuICBAZmluYWwoKVxuICBhc3luYyByZWFkKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkOiBzdHJpbmcgfCBudW1iZXJcbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+PiB7XG4gICAgY29uc3QgbG9nID0gdGhpcy5sb2cuZm9yKHRoaXMucmVhZCk7XG4gICAgbG9nLnZlcmJvc2UoYHJlYWRpbmcgZW50cnkgZnJvbSAke3RhYmxlTmFtZX0gdGFibGVgKTtcbiAgICBsb2cuZGVidWcoYHBrOiAke2lkfWApO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuZXZhbHVhdGVUcmFuc2FjdGlvbihPcGVyYXRpb25LZXlzLlJFQUQsIFtcbiAgICAgIGlkLnRvU3RyaW5nKCksXG4gICAgXSk7XG4gICAgcmV0dXJuIHRoaXMuc2VyaWFsaXplci5kZXNlcmlhbGl6ZSh0aGlzLmRlY29kZShyZXN1bHQpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVXBkYXRlcyBhIHNpbmdsZSByZWNvcmRcbiAgICogQHN1bW1hcnkgU3VibWl0cyBhIHRyYW5zYWN0aW9uIHRvIHVwZGF0ZSBhIHJlY29yZCBpbiB0aGUgRmFicmljIGxlZGdlclxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFibGVOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHRhYmxlL2NvbGxlY3Rpb25cbiAgICogQHBhcmFtIHtzdHJpbmcgfCBudW1iZXJ9IGlkIC0gVGhlIHJlY29yZCBpZGVudGlmaWVyXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gbW9kZWwgLSBUaGUgdXBkYXRlZCByZWNvcmQgZGF0YVxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IHRyYW5zaWVudCAtIFRyYW5zaWVudCBkYXRhIGZvciB0aGUgdHJhbnNhY3Rpb25cbiAgICogQHJldHVybiB7UHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+Pn0gUHJvbWlzZSByZXNvbHZpbmcgdG8gdGhlIHVwZGF0ZWQgcmVjb3JkXG4gICAqL1xuICBAZGVidWcodHJ1ZSlcbiAgQGZpbmFsKClcbiAgYXN5bmMgdXBkYXRlKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkOiBzdHJpbmcgfCBudW1iZXIsXG4gICAgbW9kZWw6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgdHJhbnNpZW50OiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj4ge1xuICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nLmZvcih0aGlzLnVwZGF0ZSk7XG4gICAgbG9nLnZlcmJvc2UoYHVwZGF0aW5nIGVudHJ5IHRvICR7dGFibGVOYW1lfSB0YWJsZWApO1xuICAgIGxvZy5kZWJ1ZyhgcGs6ICR7aWR9YCk7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5zdWJtaXRUcmFuc2FjdGlvbihcbiAgICAgIE9wZXJhdGlvbktleXMuVVBEQVRFLFxuICAgICAgW3RoaXMuc2VyaWFsaXplci5zZXJpYWxpemUobW9kZWwsIHRhYmxlTmFtZSldLFxuICAgICAgdHJhbnNpZW50XG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5zZXJpYWxpemVyLmRlc2VyaWFsaXplKHRoaXMuZGVjb2RlKHJlc3VsdCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBEZWxldGVzIGEgc2luZ2xlIHJlY29yZFxuICAgKiBAc3VtbWFyeSBTdWJtaXRzIGEgdHJhbnNhY3Rpb24gdG8gZGVsZXRlIGEgcmVjb3JkIGZyb20gdGhlIEZhYnJpYyBsZWRnZXJcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZS9jb2xsZWN0aW9uXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgbnVtYmVyfSBpZCAtIFRoZSByZWNvcmQgaWRlbnRpZmllciB0byBkZWxldGVcbiAgICogQHJldHVybiB7UHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+Pn0gUHJvbWlzZSByZXNvbHZpbmcgdG8gdGhlIGRlbGV0ZWQgcmVjb3JkXG4gICAqL1xuICBAZGVidWcodHJ1ZSlcbiAgQGZpbmFsKClcbiAgYXN5bmMgZGVsZXRlKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkOiBzdHJpbmcgfCBudW1iZXJcbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+PiB7XG4gICAgY29uc3QgbG9nID0gdGhpcy5sb2cuZm9yKHRoaXMuZGVsZXRlKTtcbiAgICBsb2cudmVyYm9zZShgZGVsZXRpbmcgZW50cnkgZnJvbSAke3RhYmxlTmFtZX0gdGFibGVgKTtcbiAgICBsb2cuZGVidWcoYHBrOiAke2lkfWApO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuc3VibWl0VHJhbnNhY3Rpb24oT3BlcmF0aW9uS2V5cy5ERUxFVEUsIFtcbiAgICAgIHRhYmxlTmFtZSxcbiAgICAgIGlkLFxuICAgIF0pO1xuICAgIHJldHVybiB0aGlzLnNlcmlhbGl6ZXIuZGVzZXJpYWxpemUodGhpcy5kZWNvZGUocmVzdWx0KSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEV4ZWN1dGVzIGEgcmF3IHF1ZXJ5IGFnYWluc3QgdGhlIEZhYnJpYyBsZWRnZXJcbiAgICogQHN1bW1hcnkgRXZhbHVhdGVzIGEgdHJhbnNhY3Rpb24gdG8gcGVyZm9ybSBhIHF1ZXJ5IHVzaW5nIE1hbmdvIFF1ZXJ5IHN5bnRheFxuICAgKiBAdGVtcGxhdGUgViAtIFRoZSByZXR1cm4gdHlwZVxuICAgKiBAcGFyYW0ge01hbmdvUXVlcnl9IHJhd0lucHV0IC0gVGhlIE1hbmdvIFF1ZXJ5IHRvIGV4ZWN1dGVcbiAgICogQHBhcmFtIHtib29sZWFufSBwcm9jZXNzIC0gV2hldGhlciB0byBwcm9jZXNzIHRoZSByZXN1bHRcbiAgICogQHJldHVybiB7UHJvbWlzZTxWPn0gUHJvbWlzZSByZXNvbHZpbmcgdG8gdGhlIHF1ZXJ5IHJlc3VsdFxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDbGllbnRcbiAgICogICBwYXJ0aWNpcGFudCBGYWJyaWNBZGFwdGVyXG4gICAqICAgcGFydGljaXBhbnQgQ29udHJhY3RcbiAgICogICBwYXJ0aWNpcGFudCBDaGFpbmNvZGVcbiAgICpcbiAgICogICBDbGllbnQtPj5GYWJyaWNBZGFwdGVyOiByYXcocmF3SW5wdXQsIHByb2Nlc3MpXG4gICAqICAgRmFicmljQWRhcHRlci0+PkZhYnJpY0FkYXB0ZXI6IEpTT04uc3RyaW5naWZ5KHJhd0lucHV0KVxuICAgKiAgIEZhYnJpY0FkYXB0ZXItPj5GYWJyaWNBZGFwdGVyOiBldmFsdWF0ZVRyYW5zYWN0aW9uKFwicXVlcnlcIiwgW2lucHV0XSlcbiAgICogICBGYWJyaWNBZGFwdGVyLT4+Q29udHJhY3Q6IGV2YWx1YXRlKFwicXVlcnlcIiwgcHJvcG9zYWxPcHRpb25zKVxuICAgKiAgIENvbnRyYWN0LT4+Q2hhaW5jb2RlOiBpbnZva2VcbiAgICogICBDaGFpbmNvZGUtLT4+Q29udHJhY3Q6IHJlc3BvbnNlXG4gICAqICAgQ29udHJhY3QtLT4+RmFicmljQWRhcHRlcjogcmVzdWx0XG4gICAqICAgRmFicmljQWRhcHRlci0+PkZhYnJpY0FkYXB0ZXI6IEpTT04ucGFyc2UoZGVjb2RlKHJlc3VsdCkpXG4gICAqICAgRmFicmljQWRhcHRlci0+PkZhYnJpY0FkYXB0ZXI6IFByb2Nlc3MgcmVzdWx0IGJhc2VkIG9uIHR5cGVcbiAgICogICBGYWJyaWNBZGFwdGVyLS0+PkNsaWVudDogcHJvY2Vzc2VkIHJlc3VsdFxuICAgKi9cbiAgQGRlYnVnKHRydWUpXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgYXN5bmMgcmF3PFY+KHJhd0lucHV0OiBNYW5nb1F1ZXJ5LCBwcm9jZXNzOiBib29sZWFuKTogUHJvbWlzZTxWPiB7XG4gICAgY29uc3QgbG9nID0gdGhpcy5sb2cuZm9yKHRoaXMucmF3KTtcbiAgICBsb2cuaW5mbyhgUGVyZm9ybWluZyByYXcgIHF1ZXJ5IG9uIHRhYmxlYCk7XG4gICAgbG9nLmRlYnVnKGBwcm9jZXNzaW5nIHJhdyBpbnB1dCBmb3IgcXVlcnk6ICR7SlNPTi5zdHJpbmdpZnkocmF3SW5wdXQpfWApO1xuICAgIGxldCBpbnB1dDogc3RyaW5nO1xuICAgIHRyeSB7XG4gICAgICBpbnB1dCA9IEpTT04uc3RyaW5naWZ5KHJhd0lucHV0KTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHRocm93IG5ldyBTZXJpYWxpemF0aW9uRXJyb3IoXG4gICAgICAgIGBGYWlsZWQgdG8gcHJvY2VzcyByYXcgaW5wdXQgZm9yIHF1ZXJ5OiAke2V9YFxuICAgICAgKTtcbiAgICB9XG4gICAgbGV0IHRyYW5zYWN0aW9uUmVzdWx0OiBhbnk7XG4gICAgdHJ5IHtcbiAgICAgIHRyYW5zYWN0aW9uUmVzdWx0ID0gYXdhaXQgdGhpcy5ldmFsdWF0ZVRyYW5zYWN0aW9uKFwicXVlcnlcIiwgW2lucHV0XSk7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgdGhpcy5wYXJzZUVycm9yKGUgYXMgRXJyb3IpO1xuICAgIH1cbiAgICBsZXQgcmVzdWx0OiBhbnk7XG4gICAgdHJ5IHtcbiAgICAgIHJlc3VsdCA9IEpTT04ucGFyc2UodGhpcy5kZWNvZGUodHJhbnNhY3Rpb25SZXN1bHQpKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHRocm93IG5ldyBTZXJpYWxpemF0aW9uRXJyb3IoYEZhaWxlZCB0byBwcm9jZXNzIHJlc3VsdDogJHtlfWApO1xuICAgIH1cblxuICAgIGNvbnN0IHBhcnNlUmVjb3JkID0gKHJlY29yZDogUmVjb3JkPGFueSwgYW55PikgPT4ge1xuICAgICAgaWYgKE1vZGVsLmlzTW9kZWwocmVjb3JkKSkgcmV0dXJuIE1vZGVsLmJ1aWxkKHJlY29yZCk7XG4gICAgICByZXR1cm4gcmVjb3JkO1xuICAgIH07XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShyZXN1bHQpKSB7XG4gICAgICBpZiAoIXJlc3VsdC5sZW5ndGgpIHJldHVybiByZXN1bHQgYXMgVjtcbiAgICAgIGNvbnN0IGVsID0gcmVzdWx0WzBdO1xuICAgICAgaWYgKE1vZGVsLmlzTW9kZWwoZWwpKVxuICAgICAgICAvLyBpZiB0aGUgZmlyc3Qgb25lIGlzIGEgbW9kZWwsIGFsbCBhcmUgbW9kZWxzXG4gICAgICAgIHJldHVybiByZXN1bHQubWFwKChlbCkgPT4gTW9kZWwuYnVpbGQoZWwpKSBhcyBWO1xuICAgICAgcmV0dXJuIHJlc3VsdCBhcyBWO1xuICAgIH1cblxuICAgIHJldHVybiBwYXJzZVJlY29yZChyZXN1bHQgYXMgYW55KSBhcyBWO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHZXRzIG9yIGNyZWF0ZXMgYSBnUlBDIGNsaWVudCBmb3IgdGhlIEZhYnJpYyBwZWVyXG4gICAqIEBzdW1tYXJ5IFJldHVybnMgYSBjYWNoZWQgY2xpZW50IG9yIGNyZWF0ZXMgYSBuZXcgb25lIGlmIG5vbmUgZXhpc3RzXG4gICAqIEByZXR1cm4ge1Byb21pc2U8Q2xpZW50Pn0gUHJvbWlzZSByZXNvbHZpbmcgdG8gdGhlIGdSUEMgY2xpZW50XG4gICAqL1xuICBvdmVycmlkZSBnZXRDbGllbnQoKTogQ2xpZW50IHtcbiAgICBpZiAoIXRoaXMuX2NsaWVudClcbiAgICAgIHRoaXMuX2NsaWVudCA9IEZhYnJpY0NsaWVudEFkYXB0ZXIuZ2V0Q2xpZW50KHRoaXMuY29uZmlnKTtcbiAgICByZXR1cm4gdGhpcy5fY2xpZW50O1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHZXRzIGEgR2F0ZXdheSBpbnN0YW5jZSBmb3IgdGhlIEZhYnJpYyBuZXR3b3JrXG4gICAqIEBzdW1tYXJ5IENyZWF0ZXMgYSBuZXcgR2F0ZXdheSBpbnN0YW5jZSB1c2luZyB0aGUgY3VycmVudCBjbGllbnRcbiAgICogQHJldHVybiB7UHJvbWlzZTxHYXRld2F5Pn0gUHJvbWlzZSByZXNvbHZpbmcgdG8gdGhlIEdhdGV3YXkgaW5zdGFuY2VcbiAgICovXG4gIHByb3RlY3RlZCBhc3luYyBHYXRld2F5KCk6IFByb21pc2U8R2F0ZXdheT4ge1xuICAgIHJldHVybiBGYWJyaWNDbGllbnRBZGFwdGVyLmdldEdhdGV3YXkodGhpcy5jb25maWcsIHRoaXMuY2xpZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gR2V0cyBhIENvbnRyYWN0IGluc3RhbmNlIGZvciB0aGUgRmFicmljIGNoYWluY29kZVxuICAgKiBAc3VtbWFyeSBDcmVhdGVzIGEgbmV3IENvbnRyYWN0IGluc3RhbmNlIHVzaW5nIHRoZSBjdXJyZW50IEdhdGV3YXlcbiAgICogQHJldHVybiB7UHJvbWlzZTxDb250cmFrdD59IFByb21pc2UgcmVzb2x2aW5nIHRvIHRoZSBDb250cmFjdCBpbnN0YW5jZVxuICAgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIENvbnRyYWN0KCk6IFByb21pc2U8Q29udHJha3Q+IHtcbiAgICByZXR1cm4gRmFicmljQ2xpZW50QWRhcHRlci5nZXRDb250cmFjdChhd2FpdCB0aGlzLkdhdGV3YXkoKSwgdGhpcy5jb25maWcpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBFeGVjdXRlcyBhIHRyYW5zYWN0aW9uIG9uIHRoZSBGYWJyaWMgbmV0d29ya1xuICAgKiBAc3VtbWFyeSBTdWJtaXRzIG9yIGV2YWx1YXRlcyBhIHRyYW5zYWN0aW9uIG9uIHRoZSBGYWJyaWMgY2hhaW5jb2RlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcGkgLSBUaGUgY2hhaW5jb2RlIGZ1bmN0aW9uIHRvIGNhbGxcbiAgICogQHBhcmFtIHtib29sZWFufSBzdWJtaXQgLSBXaGV0aGVyIHRvIHN1Ym1pdCAodHJ1ZSkgb3IgZXZhbHVhdGUgKGZhbHNlKSB0aGUgdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIHthbnlbXX0gW2FyZ3NdIC0gQXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIGNoYWluY29kZSBmdW5jdGlvblxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIHN0cmluZz59IFt0cmFuc2llbnREYXRhXSAtIFRyYW5zaWVudCBkYXRhIGZvciB0aGUgdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIHtBcnJheTxzdHJpbmc+fSBbZW5kb3JzaW5nT3JnYW5pemF0aW9uc10gLSBPcmdhbml6YXRpb25zIHRoYXQgbXVzdCBlbmRvcnNlIHRoZSB0cmFuc2FjdGlvblxuICAgKiBAcmV0dXJuIHtQcm9taXNlPFVpbnQ4QXJyYXk+fSBQcm9taXNlIHJlc29sdmluZyB0byB0aGUgdHJhbnNhY3Rpb24gcmVzdWx0XG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IEZhYnJpY0FkYXB0ZXJcbiAgICogICBwYXJ0aWNpcGFudCBHYXRld2F5XG4gICAqICAgcGFydGljaXBhbnQgQ29udHJhY3RcbiAgICogICBwYXJ0aWNpcGFudCBDaGFpbmNvZGVcbiAgICpcbiAgICogICBGYWJyaWNBZGFwdGVyLT4+R2F0ZXdheTogY29ubmVjdCgpXG4gICAqICAgRmFicmljQWRhcHRlci0+PkNvbnRyYWN0OiBnZXRDb250cmFjdCgpXG4gICAqICAgYWx0IHN1Ym1pdCB0cmFuc2FjdGlvblxuICAgKiAgICAgRmFicmljQWRhcHRlci0+PkNvbnRyYWN0OiBzdWJtaXQoYXBpLCBwcm9wb3NhbE9wdGlvbnMpXG4gICAqICAgZWxzZSBldmFsdWF0ZSB0cmFuc2FjdGlvblxuICAgKiAgICAgRmFicmljQWRhcHRlci0+PkNvbnRyYWN0OiBldmFsdWF0ZShhcGksIHByb3Bvc2FsT3B0aW9ucylcbiAgICogICBlbmRcbiAgICogICBDb250cmFjdC0+PkNoYWluY29kZTogaW52b2tlXG4gICAqICAgQ2hhaW5jb2RlLS0+PkNvbnRyYWN0OiByZXNwb25zZVxuICAgKiAgIENvbnRyYWN0LS0+PkZhYnJpY0FkYXB0ZXI6IHJlc3VsdFxuICAgKiAgIEZhYnJpY0FkYXB0ZXItPj5HYXRld2F5OiBjbG9zZSgpXG4gICAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgdHJhbnNhY3Rpb24oXG4gICAgYXBpOiBzdHJpbmcsXG4gICAgc3VibWl0ID0gdHJ1ZSxcbiAgICBhcmdzPzogYW55W10sXG4gICAgdHJhbnNpZW50RGF0YT86IFJlY29yZDxzdHJpbmcsIHN0cmluZz4sXG4gICAgZW5kb3JzaW5nT3JnYW5pemF0aW9ucz86IEFycmF5PHN0cmluZz5cbiAgKTogUHJvbWlzZTxVaW50OEFycmF5PiB7XG4gICAgY29uc3QgbG9nID0gdGhpcy5sb2cuZm9yKHRoaXMudHJhbnNhY3Rpb24pO1xuICAgIGNvbnN0IGdhdGV3YXkgPSBhd2FpdCB0aGlzLkdhdGV3YXkoKTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgY29udHJhY3QgPSBhd2FpdCB0aGlzLkNvbnRyYWN0KCk7XG4gICAgICBsb2cudmVyYm9zZShcbiAgICAgICAgYCR7c3VibWl0ID8gXCJTdWJtaXRcIiA6IFwiRXZhbHVhdGVcIn10aW5nIHRyYW5zYWN0aW9uICR7dGhpcy5jb25maWcuY29udHJhY3ROYW1lfS4ke2FwaX1gXG4gICAgICApO1xuICAgICAgbG9nLmRlYnVnKGBhcmdzOiAke2FyZ3M/Lm1hcCgoYSkgPT4gYS50b1N0cmluZygpKS5qb2luKFwiXFxuXCIpIHx8IFwibm9uZVwifWApO1xuICAgICAgY29uc3QgbWV0aG9kID0gc3VibWl0ID8gY29udHJhY3Quc3VibWl0IDogY29udHJhY3QuZXZhbHVhdGU7XG5cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICAgIGVuZG9yc2luZ09yZ2FuaXphdGlvbnMgPSBlbmRvcnNpbmdPcmdhbml6YXRpb25zPy5sZW5ndGhcbiAgICAgICAgPyBlbmRvcnNpbmdPcmdhbml6YXRpb25zXG4gICAgICAgIDogdW5kZWZpbmVkO1xuICAgICAgY29uc3QgcHJvcG9zYWxPcHRpb25zOiBQcm9wb3NhbE9wdGlvbnMgPSB7XG4gICAgICAgIGFyZ3VtZW50czogYXJncyB8fCBbXSxcbiAgICAgICAgdHJhbnNpZW50RGF0YTogdHJhbnNpZW50RGF0YSxcbiAgICAgICAgLy8gLi4uKGVuZG9yc2luZ09yZ2FuaXphdGlvbnMgJiYgeyBlbmRvcnNpbmdPcmdhbml6YXRpb25zIH0pIC8vIG1zcElkIGxpc3RcbiAgICAgIH07XG5cbiAgICAgIHJldHVybiBhd2FpdCBtZXRob2QuY2FsbChjb250cmFjdCwgYXBpLCBwcm9wb3NhbE9wdGlvbnMpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgaWYgKGUuY29kZSA9PT0gMTApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2UuZGV0YWlsc1swXS5tZXNzYWdlfWApO1xuICAgICAgfVxuICAgICAgdGhyb3cgdGhpcy5wYXJzZUVycm9yKGUpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhgQ2xvc2luZyAke3RoaXMuY29uZmlnLm1zcElkfSBnYXRld2F5IGNvbm5lY3Rpb25gKTtcbiAgICAgIGdhdGV3YXkuY2xvc2UoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFBhcnNlcyBhbiBlcnJvciBpbnRvIGEgQmFzZUVycm9yXG4gICAqIEBzdW1tYXJ5IENvbnZlcnRzIGFueSBlcnJvciBpbnRvIGEgc3RhbmRhcmRpemVkIEJhc2VFcnJvclxuICAgKiBAcGFyYW0ge0Vycm9yIHwgc3RyaW5nfSBlcnIgLSBUaGUgZXJyb3IgdG8gcGFyc2VcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtyZWFzb25dIC0gT3B0aW9uYWwgcmVhc29uIGZvciB0aGUgZXJyb3JcbiAgICogQHJldHVybiB7QmFzZUVycm9yfSBUaGUgcGFyc2VkIGVycm9yXG4gICAqL1xuICBvdmVycmlkZSBwYXJzZUVycm9yKGVycjogRXJyb3IgfCBzdHJpbmcsIHJlYXNvbj86IHN0cmluZyk6IEJhc2VFcnJvciB7XG4gICAgcmV0dXJuIEZhYnJpY0NsaWVudEFkYXB0ZXIucGFyc2VFcnJvcihlcnIsIHJlYXNvbik7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFN1Ym1pdHMgYSB0cmFuc2FjdGlvbiB0byB0aGUgRmFicmljIG5ldHdvcmtcbiAgICogQHN1bW1hcnkgRXhlY3V0ZXMgYSB0cmFuc2FjdGlvbiB0aGF0IG1vZGlmaWVzIHRoZSBsZWRnZXIgc3RhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IGFwaSAtIFRoZSBjaGFpbmNvZGUgZnVuY3Rpb24gdG8gY2FsbFxuICAgKiBAcGFyYW0ge2FueVtdfSBbYXJnc10gLSBBcmd1bWVudHMgdG8gcGFzcyB0byB0aGUgY2hhaW5jb2RlIGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgc3RyaW5nPn0gW3RyYW5zaWVudERhdGFdIC0gVHJhbnNpZW50IGRhdGEgZm9yIHRoZSB0cmFuc2FjdGlvblxuICAgKiBAcGFyYW0ge0FycmF5PHN0cmluZz59IFtlbmRvcnNpbmdPcmdhbml6YXRpb25zXSAtIE9yZ2FuaXphdGlvbnMgdGhhdCBtdXN0IGVuZG9yc2UgdGhlIHRyYW5zYWN0aW9uXG4gICAqIEByZXR1cm4ge1Byb21pc2U8VWludDhBcnJheT59IFByb21pc2UgcmVzb2x2aW5nIHRvIHRoZSB0cmFuc2FjdGlvbiByZXN1bHRcbiAgICovXG4gIGFzeW5jIHN1Ym1pdFRyYW5zYWN0aW9uKFxuICAgIGFwaTogc3RyaW5nLFxuICAgIGFyZ3M/OiBhbnlbXSxcbiAgICB0cmFuc2llbnREYXRhPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPixcbiAgICBlbmRvcnNpbmdPcmdhbml6YXRpb25zPzogQXJyYXk8c3RyaW5nPlxuICApOiBQcm9taXNlPFVpbnQ4QXJyYXk+IHtcbiAgICByZXR1cm4gdGhpcy50cmFuc2FjdGlvbihcbiAgICAgIGFwaSxcbiAgICAgIHRydWUsXG4gICAgICBhcmdzLFxuICAgICAgdHJhbnNpZW50RGF0YSxcbiAgICAgIGVuZG9yc2luZ09yZ2FuaXphdGlvbnNcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBFdmFsdWF0ZXMgYSB0cmFuc2FjdGlvbiBvbiB0aGUgRmFicmljIG5ldHdvcmtcbiAgICogQHN1bW1hcnkgRXhlY3V0ZXMgYSB0cmFuc2FjdGlvbiB0aGF0IGRvZXMgbm90IG1vZGlmeSB0aGUgbGVkZ2VyIHN0YXRlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcGkgLSBUaGUgY2hhaW5jb2RlIGZ1bmN0aW9uIHRvIGNhbGxcbiAgICogQHBhcmFtIHthbnlbXX0gW2FyZ3NdIC0gQXJndW1lbnRzIHRvIHBhc3MgdG8gdGhlIGNoYWluY29kZSBmdW5jdGlvblxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIHN0cmluZz59IFt0cmFuc2llbnREYXRhXSAtIFRyYW5zaWVudCBkYXRhIGZvciB0aGUgdHJhbnNhY3Rpb25cbiAgICogQHBhcmFtIHtBcnJheTxzdHJpbmc+fSBbZW5kb3JzaW5nT3JnYW5pemF0aW9uc10gLSBPcmdhbml6YXRpb25zIHRoYXQgbXVzdCBlbmRvcnNlIHRoZSB0cmFuc2FjdGlvblxuICAgKiBAcmV0dXJuIHtQcm9taXNlPFVpbnQ4QXJyYXk+fSBQcm9taXNlIHJlc29sdmluZyB0byB0aGUgdHJhbnNhY3Rpb24gcmVzdWx0XG4gICAqL1xuICBhc3luYyBldmFsdWF0ZVRyYW5zYWN0aW9uKFxuICAgIGFwaTogc3RyaW5nLFxuICAgIGFyZ3M/OiBhbnlbXSxcbiAgICB0cmFuc2llbnREYXRhPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPixcbiAgICBlbmRvcnNpbmdPcmdhbml6YXRpb25zPzogQXJyYXk8c3RyaW5nPlxuICApOiBQcm9taXNlPFVpbnQ4QXJyYXk+IHtcbiAgICByZXR1cm4gdGhpcy50cmFuc2FjdGlvbihcbiAgICAgIGFwaSxcbiAgICAgIGZhbHNlLFxuICAgICAgYXJncyxcbiAgICAgIHRyYW5zaWVudERhdGEsXG4gICAgICBlbmRvcnNpbmdPcmdhbml6YXRpb25zXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ2xvc2VzIHRoZSBjb25uZWN0aW9uIHRvIHRoZSBGYWJyaWMgbmV0d29ya1xuICAgKiBAc3VtbWFyeSBDbG9zZXMgdGhlIGdSUEMgY2xpZW50IGlmIGl0IGV4aXN0c1xuICAgKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGUgY2xpZW50IGlzIGNsb3NlZFxuICAgKi9cbiAgYXN5bmMgY2xvc2UoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuY2xpZW50KSB7XG4gICAgICB0aGlzLmxvZy52ZXJib3NlKGBDbG9zaW5nICR7dGhpcy5jb25maWcubXNwSWR9IGdhdGV3YXkgY2xpZW50YCk7XG4gICAgICB0aGlzLmNsaWVudC5jbG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gR2V0cyBhIENvbnRyYWN0IGluc3RhbmNlIGZyb20gYSBHYXRld2F5XG4gICAqIEBzdW1tYXJ5IFJldHJpZXZlcyBhIGNoYWluY29kZSBjb250cmFjdCBmcm9tIHRoZSBzcGVjaWZpZWQgbmV0d29ya1xuICAgKiBAcGFyYW0ge0dhdGV3YXl9IGdhdGV3YXkgLSBUaGUgR2F0ZXdheSBpbnN0YW5jZVxuICAgKiBAcGFyYW0ge1BlZXJDb25maWd9IGNvbmZpZyAtIFRoZSBwZWVyIGNvbmZpZ3VyYXRpb25cbiAgICogQHJldHVybiB7Q29udHJha3R9IFRoZSBDb250cmFjdCBpbnN0YW5jZVxuICAgKi9cbiAgc3RhdGljIGdldENvbnRyYWN0KGdhdGV3YXk6IEdhdGV3YXksIGNvbmZpZzogUGVlckNvbmZpZyk6IENvbnRyYWt0IHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5nZXRDb250cmFjdCk7XG4gICAgY29uc3QgbmV0d29yayA9IHRoaXMuZ2V0TmV0d29yayhnYXRld2F5LCBjb25maWcuY2hhbm5lbCk7XG4gICAgbGV0IGNvbnRyYWN0OiBDb250cmFrdDtcbiAgICB0cnkge1xuICAgICAgbG9nLmRlYnVnKFxuICAgICAgICBgUmV0cmlldmluZyBjaGFpbmNvZGUgJHtjb25maWcuY2hhaW5jb2RlTmFtZX0gY29udHJhY3QgJHtjb25maWcuY29udHJhY3ROYW1lfSBmcm9tIG5ldHdvcmsgJHtjb25maWcuY2hhbm5lbH1gXG4gICAgICApO1xuICAgICAgY29udHJhY3QgPSBuZXR3b3JrLmdldENvbnRyYWN0KGNvbmZpZy5jaGFpbmNvZGVOYW1lLCBjb25maWcuY29udHJhY3ROYW1lKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHRocm93IHRoaXMucGFyc2VFcnJvcihlKTtcbiAgICB9XG4gICAgcmV0dXJuIGNvbnRyYWN0O1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHZXRzIGEgTmV0d29yayBpbnN0YW5jZSBmcm9tIGEgR2F0ZXdheVxuICAgKiBAc3VtbWFyeSBDb25uZWN0cyB0byBhIHNwZWNpZmljIGNoYW5uZWwgb24gdGhlIEZhYnJpYyBuZXR3b3JrXG4gICAqIEBwYXJhbSB7R2F0ZXdheX0gZ2F0ZXdheSAtIFRoZSBHYXRld2F5IGluc3RhbmNlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjaGFubmVsTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBjaGFubmVsIHRvIGNvbm5lY3QgdG9cbiAgICogQHJldHVybiB7TmV0d29ya30gVGhlIE5ldHdvcmsgaW5zdGFuY2VcbiAgICovXG4gIHN0YXRpYyBnZXROZXR3b3JrKGdhdGV3YXk6IEdhdGV3YXksIGNoYW5uZWxOYW1lOiBzdHJpbmcpOiBOZXR3b3JrIHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5nZXROZXR3b3JrKTtcbiAgICBsZXQgbmV0d29yazogTmV0d29yaztcbiAgICB0cnkge1xuICAgICAgbG9nLmRlYnVnKGBDb25uZWN0aW5nIHRvIGNoYW5uZWwgJHtjaGFubmVsTmFtZX1gKTtcbiAgICAgIG5ldHdvcmsgPSBnYXRld2F5LmdldE5ldHdvcmsoY2hhbm5lbE5hbWUpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgdGhyb3cgdGhpcy5wYXJzZUVycm9yKGUpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXR3b3JrO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHZXRzIGEgR2F0ZXdheSBpbnN0YW5jZSBmb3IgY29ubmVjdGluZyB0byB0aGUgRmFicmljIG5ldHdvcmtcbiAgICogQHN1bW1hcnkgQ3JlYXRlcyBhIEdhdGV3YXkgdXNpbmcgdGhlIHByb3ZpZGVkIGNvbmZpZ3VyYXRpb24gYW5kIGNsaWVudFxuICAgKiBAcGFyYW0ge1BlZXJDb25maWd9IGNvbmZpZyAtIFRoZSBwZWVyIGNvbmZpZ3VyYXRpb25cbiAgICogQHBhcmFtIHtDbGllbnR9IFtjbGllbnRdIC0gT3B0aW9uYWwgZ1JQQyBjbGllbnQsIHdpbGwgYmUgY3JlYXRlZCBpZiBub3QgcHJvdmlkZWRcbiAgICogQHJldHVybiB7UHJvbWlzZTxHYXRld2F5Pn0gUHJvbWlzZSByZXNvbHZpbmcgdG8gdGhlIEdhdGV3YXkgaW5zdGFuY2VcbiAgICovXG4gIHN0YXRpYyBhc3luYyBnZXRHYXRld2F5KGNvbmZpZzogUGVlckNvbmZpZywgY2xpZW50PzogQ2xpZW50KSB7XG4gICAgcmV0dXJuIChhd2FpdCB0aGlzLmdldENvbm5lY3Rpb24oXG4gICAgICBjbGllbnQgfHwgKGF3YWl0IHRoaXMuZ2V0Q2xpZW50KGNvbmZpZykpLFxuICAgICAgY29uZmlnXG4gICAgKSkgYXMgR2F0ZXdheTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIGdSUEMgY2xpZW50IGZvciBjb25uZWN0aW5nIHRvIGEgRmFicmljIHBlZXJcbiAgICogQHN1bW1hcnkgSW5pdGlhbGl6ZXMgYSBjbGllbnQgd2l0aCBUTFMgY3JlZGVudGlhbHMgZm9yIHNlY3VyZSBjb21tdW5pY2F0aW9uXG4gICAqIEBwYXJhbSB7UGVlckNvbmZpZ30gY29uZmlnIC0gVGhlIHBlZXIgY29uZmlndXJhdGlvblxuICAgKiBAcmV0dXJuIHtDbGllbnR9IFByb21pc2UgcmVzb2x2aW5nIHRvIHRoZSBnUlBDIGNsaWVudFxuICAgKi9cbiAgc3RhdGljIGdldENsaWVudChjb25maWc6IFBlZXJDb25maWcpOiBDbGllbnQge1xuICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nLmZvcih0aGlzLmdldENsaWVudCk7XG4gICAgbG9nLmRlYnVnKGBnZW5lcmF0aW5nIFRMUyBjcmVkZW50aWFscyBmb3IgbXNwICR7Y29uZmlnLm1zcElkfWApO1xuICAgIGNvbnN0IHRsc0NyZWRlbnRpYWxzID0gZ3JwYy5jcmVkZW50aWFscy5jcmVhdGVTc2woXG4gICAgICB0eXBlb2YgY29uZmlnLnRsc0NlcnQgPT09IFwic3RyaW5nXCJcbiAgICAgICAgPyBCdWZmZXIuZnJvbShjb25maWcudGxzQ2VydClcbiAgICAgICAgOiBjb25maWcudGxzQ2VydFxuICAgICk7XG4gICAgbG9nLmRlYnVnKGBnZW5lcmF0aW5nIEdhdGV3YXkgQ2xpZW50IGZvciB1cmwgJHtjb25maWcucGVlckVuZHBvaW50fWApO1xuICAgIHJldHVybiBuZXcgQ2xpZW50KGNvbmZpZy5wZWVyRW5kcG9pbnQsIHRsc0NyZWRlbnRpYWxzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRXN0YWJsaXNoZXMgYSBjb25uZWN0aW9uIHRvIHRoZSBGYWJyaWMgbmV0d29ya1xuICAgKiBAc3VtbWFyeSBDcmVhdGVzIGEgR2F0ZXdheSBjb25uZWN0aW9uIHdpdGggaWRlbnRpdHkgYW5kIHNpZ25lclxuICAgKiBAcGFyYW0ge0NsaWVudH0gY2xpZW50IC0gVGhlIGdSUEMgY2xpZW50XG4gICAqIEBwYXJhbSB7UGVlckNvbmZpZ30gY29uZmlnIC0gVGhlIHBlZXIgY29uZmlndXJhdGlvblxuICAgKiBAcmV0dXJuIHtQcm9taXNlPEdhdGV3YXk+fSBQcm9taXNlIHJlc29sdmluZyB0byB0aGUgY29ubmVjdGVkIEdhdGV3YXlcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gICAqICAgcGFydGljaXBhbnQgRmFicmljQWRhcHRlclxuICAgKiAgIHBhcnRpY2lwYW50IElkZW50aXR5XG4gICAqICAgcGFydGljaXBhbnQgU2lnbmVyXG4gICAqICAgcGFydGljaXBhbnQgR2F0ZXdheVxuICAgKlxuICAgKiAgIENhbGxlci0+PkZhYnJpY0FkYXB0ZXI6IGdldENvbm5lY3Rpb24oY2xpZW50LCBjb25maWcpXG4gICAqICAgRmFicmljQWRhcHRlci0+PklkZW50aXR5OiBnZXRJZGVudGl0eShtc3BJZCwgY2VydERpcmVjdG9yeVBhdGgpXG4gICAqICAgSWRlbnRpdHktLT4+RmFicmljQWRhcHRlcjogaWRlbnRpdHlcbiAgICogICBGYWJyaWNBZGFwdGVyLT4+U2lnbmVyOiBnZXRTaWduZXIoa2V5RGlyZWN0b3J5UGF0aClcbiAgICogICBTaWduZXItLT4+RmFicmljQWRhcHRlcjogc2lnbmVyXG4gICAqICAgRmFicmljQWRhcHRlci0+PkZhYnJpY0FkYXB0ZXI6IENyZWF0ZSBDb25uZWN0T3B0aW9uc1xuICAgKiAgIEZhYnJpY0FkYXB0ZXItPj5HYXRld2F5OiBjb25uZWN0KG9wdGlvbnMpXG4gICAqICAgR2F0ZXdheS0tPj5GYWJyaWNBZGFwdGVyOiBnYXRld2F5XG4gICAqICAgRmFicmljQWRhcHRlci0tPj5DYWxsZXI6IGdhdGV3YXlcbiAgICovXG4gIHN0YXRpYyBhc3luYyBnZXRDb25uZWN0aW9uKGNsaWVudDogQ2xpZW50LCBjb25maWc6IFBlZXJDb25maWcpIHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5nZXRDb25uZWN0aW9uKTtcbiAgICBsb2cuZGVidWcoXG4gICAgICBgUmV0cmlldmluZyBQZWVyIElkZW50aXR5IGZvciAke2NvbmZpZy5tc3BJZH0gdW5kZXIgJHtjb25maWcuY2VydENlcnRPckRpcmVjdG9yeVBhdGh9YFxuICAgICk7XG4gICAgY29uc3QgaWRlbnRpdHkgPSBhd2FpdCBnZXRJZGVudGl0eShcbiAgICAgIGNvbmZpZy5tc3BJZCxcbiAgICAgIGNvbmZpZy5jZXJ0Q2VydE9yRGlyZWN0b3J5UGF0aFxuICAgICk7XG4gICAgbG9nLmRlYnVnKGBSZXRyaWV2aW5nIHNpZ25lciBrZXkgZnJvbSAke2NvbmZpZy5rZXlDZXJ0T3JEaXJlY3RvcnlQYXRofWApO1xuXG4gICAgY29uc3Qgc2lnbmVyID0gYXdhaXQgZ2V0U2lnbmVyKGNvbmZpZy5rZXlDZXJ0T3JEaXJlY3RvcnlQYXRoKTtcblxuICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICBjbGllbnQsXG4gICAgICBpZGVudGl0eTogaWRlbnRpdHksXG4gICAgICBzaWduZXI6IHNpZ25lcixcbiAgICAgIC8vIERlZmF1bHQgdGltZW91dHMgZm9yIGRpZmZlcmVudCBnUlBDIGNhbGxzXG4gICAgICBldmFsdWF0ZU9wdGlvbnM6ICgpID0+IHtcbiAgICAgICAgcmV0dXJuIHsgZGVhZGxpbmU6IERhdGUubm93KCkgKyA1MDAwIH07IC8vIDUgc2Vjb25kc1xuICAgICAgfSxcbiAgICAgIGVuZG9yc2VPcHRpb25zOiAoKSA9PiB7XG4gICAgICAgIHJldHVybiB7IGRlYWRsaW5lOiBEYXRlLm5vdygpICsgMTUwMDAgfTsgLy8gMTUgc2Vjb25kc1xuICAgICAgfSxcbiAgICAgIHN1Ym1pdE9wdGlvbnM6ICgpID0+IHtcbiAgICAgICAgcmV0dXJuIHsgZGVhZGxpbmU6IERhdGUubm93KCkgKyA1MDAwIH07IC8vIDUgc2Vjb25kc1xuICAgICAgfSxcbiAgICAgIGNvbW1pdFN0YXR1c09wdGlvbnM6ICgpID0+IHtcbiAgICAgICAgcmV0dXJuIHsgZGVhZGxpbmU6IERhdGUubm93KCkgKyA2MDAwMCB9OyAvLyAxIG1pbnV0ZVxuICAgICAgfSxcbiAgICB9IGFzIENvbm5lY3RPcHRpb25zO1xuXG4gICAgbG9nLmRlYnVnKGBDb25uZWN0aW5nIHRvICR7Y29uZmlnLm1zcElkfWApO1xuICAgIHJldHVybiBjb25uZWN0KG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgbmV3IERpc3BhdGNoIGluc3RhbmNlIGZvciB0aGUgRmFicmljIGNsaWVudC5cbiAgICogQHN1bW1hcnkgVGhpcyBmdW5jdGlvbiBpcyByZXNwb25zaWJsZSBmb3IgY3JlYXRpbmcgYSBuZXcgRmFicmljQ2xpZW50RGlzcGF0Y2ggaW5zdGFuY2UgdGhhdCBjYW4gYmUgdXNlZCB0byBpbnRlcmFjdCB3aXRoIHRoZSBGYWJyaWMgbmV0d29yay5cbiAgICogQHJldHVybnMge0Rpc3BhdGNofSBBIG5ldyBEaXNwYXRjaCBpbnN0YW5jZSBjb25maWd1cmVkIGZvciB0aGUgRmFicmljIGNsaWVudC5cbiAgICogQHJlbWFya3MgVGhlIERpc3BhdGNoIGluc3RhbmNlIGlzIHVzZWQgdG8gZW5jYXBzdWxhdGUgdGhlIGxvZ2ljIGZvciBpbnRlcmFjdGluZyB3aXRoIHRoZSBGYWJyaWMgbmV0d29yaywgc3VjaCBhcyBzdWJtaXR0aW5nIHRyYW5zYWN0aW9ucyBvciBxdWVyeWluZyBkYXRhLlxuICAgKiBAZXhhbXBsZVxuICAgKiBjb25zdCBmYWJyaWNEaXNwYXRjaCA9IGZhYnJpY0NsaWVudEFkYXB0ZXIuRGlzcGF0Y2goKTtcbiAgICogZmFicmljRGlzcGF0Y2guc3VibWl0VHJhbnNhY3Rpb24oJ2NyZWF0ZVByb2R1Y3QnLCB7IG5hbWU6ICdQcm9kdWN0IEEnLCBwcmljZTogMTAwIH0pO1xuICAgKi9cbiAgb3ZlcnJpZGUgRGlzcGF0Y2goKTogRGlzcGF0Y2gge1xuICAgIHJldHVybiBuZXcgRmFicmljQ2xpZW50RGlzcGF0Y2godGhpcy5nZXRDbGllbnQoKSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFBhcnNlcyBhbiBlcnJvciBpbnRvIGEgQmFzZUVycm9yXG4gICAqIEBzdW1tYXJ5IENvbnZlcnRzIGFueSBlcnJvciBpbnRvIGEgc3RhbmRhcmRpemVkIEJhc2VFcnJvciB1c2luZyB0aGUgcGFyZW50IGNsYXNzIGltcGxlbWVudGF0aW9uXG4gICAqIEBwYXJhbSB7RXJyb3IgfCBzdHJpbmd9IGVyciAtIFRoZSBlcnJvciB0byBwYXJzZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW3JlYXNvbl0gLSBPcHRpb25hbCByZWFzb24gZm9yIHRoZSBlcnJvclxuICAgKiBAcmV0dXJuIHtCYXNlRXJyb3J9IFRoZSBwYXJzZWQgZXJyb3JcbiAgICovXG4gIHByb3RlY3RlZCBzdGF0aWMgb3ZlcnJpZGUgcGFyc2VFcnJvcihcbiAgICBlcnI6IEVycm9yIHwgc3RyaW5nLFxuICAgIHJlYXNvbj86IHN0cmluZ1xuICApOiBCYXNlRXJyb3Ige1xuICAgIHJldHVybiBzdXBlci5wYXJzZUVycm9yKGVyciwgcmVhc29uKTtcbiAgfVxufVxuXG5GYWJyaWNDbGllbnRBZGFwdGVyLmRlY29yYXRpb24oKTtcbkFkYXB0ZXIuc2V0Q3VycmVudChGYWJyaWNGbGF2b3VyKTtcbiJdfQ==