@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,64 @@
1
+ import { Context } from "@decaf-ts/db-decorators";
2
+ import { FabricContractFlags } from "./types";
3
+ import { ChaincodeStub, ClientIdentity } from "fabric-shim-api";
4
+ /**
5
+ * @description Context class for Fabric chaincode operations
6
+ * @summary Provides access to Fabric-specific context elements like stub, identity, and logger to be used by repositories and adapters during contract execution.
7
+ * @template F - Flags specific to Fabric contract operations
8
+ * @param {object} [args] - Optional initialization arguments passed to the base Context
9
+ * @return {void}
10
+ * @class FabricContractContext
11
+ * @example
12
+ * ```typescript
13
+ * // In a Fabric chaincode contract method
14
+ * const context = new FabricContractContext();
15
+ * // Optionally set values via the base Context API
16
+ * context.set('stub', ctx.stub);
17
+ * context.set('clientIdentity', ctx.clientIdentity);
18
+ * context.set('logger', contractLogger);
19
+ *
20
+ * // Access context properties
21
+ * const timestamp = context.timestamp;
22
+ * const creator = context.identity.getID();
23
+ * ```
24
+ * @mermaid
25
+ * sequenceDiagram
26
+ * participant Contract
27
+ * participant Context
28
+ * participant Ledger
29
+ * Contract->>Context: new FabricContractContext()
30
+ * Contract->>Context: set('stub'|'clientIdentity'|'logger', ...)
31
+ * Context-->>Contract: timestamp, identity, logger
32
+ * Contract->>Ledger: Interact via stub
33
+ */
34
+ export declare class FabricContractContext extends Context<FabricContractFlags> {
35
+ /**
36
+ * @description Creates a new FabricContractContext instance
37
+ * @summary Initializes the context with Fabric-specific flags
38
+ */
39
+ constructor();
40
+ /**
41
+ * @description Gets the chaincode stub
42
+ * @summary Returns the ChaincodeStub instance for interacting with the ledger
43
+ * @return {ChaincodeStub} The chaincode stub
44
+ */
45
+ get stub(): ChaincodeStub;
46
+ /**
47
+ * @description Gets the transaction timestamp
48
+ * @summary Overrides the base timestamp getter to use the stub's timestamp
49
+ * @return {Date} The transaction timestamp
50
+ */
51
+ get timestamp(): Date;
52
+ /**
53
+ * @description Gets the client identity
54
+ * @summary Returns the ClientIdentity instance for the transaction submitter
55
+ * @return {ClientIdentity} The client identity
56
+ */
57
+ get identity(): ClientIdentity;
58
+ /**
59
+ * @description Gets the logger
60
+ * @summary Returns the logger instance for the current context
61
+ * @return {any} The logger instance
62
+ */
63
+ get logger(): import("@decaf-ts/logging").Logger;
64
+ }
@@ -0,0 +1,81 @@
1
+ import { Context } from "@decaf-ts/db-decorators";
2
+ /**
3
+ * @description Context class for Fabric chaincode operations
4
+ * @summary Provides access to Fabric-specific context elements like stub, identity, and logger to be used by repositories and adapters during contract execution.
5
+ * @template F - Flags specific to Fabric contract operations
6
+ * @param {object} [args] - Optional initialization arguments passed to the base Context
7
+ * @return {void}
8
+ * @class FabricContractContext
9
+ * @example
10
+ * ```typescript
11
+ * // In a Fabric chaincode contract method
12
+ * const context = new FabricContractContext();
13
+ * // Optionally set values via the base Context API
14
+ * context.set('stub', ctx.stub);
15
+ * context.set('clientIdentity', ctx.clientIdentity);
16
+ * context.set('logger', contractLogger);
17
+ *
18
+ * // Access context properties
19
+ * const timestamp = context.timestamp;
20
+ * const creator = context.identity.getID();
21
+ * ```
22
+ * @mermaid
23
+ * sequenceDiagram
24
+ * participant Contract
25
+ * participant Context
26
+ * participant Ledger
27
+ * Contract->>Context: new FabricContractContext()
28
+ * Contract->>Context: set('stub'|'clientIdentity'|'logger', ...)
29
+ * Context-->>Contract: timestamp, identity, logger
30
+ * Contract->>Ledger: Interact via stub
31
+ */
32
+ export class FabricContractContext extends Context {
33
+ /**
34
+ * @description Creates a new FabricContractContext instance
35
+ * @summary Initializes the context with Fabric-specific flags
36
+ */
37
+ constructor() {
38
+ super();
39
+ }
40
+ /**
41
+ * @description Gets the chaincode stub
42
+ * @summary Returns the ChaincodeStub instance for interacting with the ledger
43
+ * @return {ChaincodeStub} The chaincode stub
44
+ */
45
+ get stub() {
46
+ return this.get("stub");
47
+ }
48
+ /**
49
+ * @description Gets the transaction timestamp
50
+ * @summary Overrides the base timestamp getter to use the stub's timestamp
51
+ * @return {Date} The transaction timestamp
52
+ */
53
+ get timestamp() {
54
+ return this.stub.getDateTimestamp();
55
+ }
56
+ /**
57
+ * @description Gets the client identity
58
+ * @summary Returns the ClientIdentity instance for the transaction submitter
59
+ * @return {ClientIdentity} The client identity
60
+ */
61
+ get identity() {
62
+ //TODO: Find what is happening it seems FabricContractContext is being created with FabricContractContext instead of the transaction context
63
+ // return this.get("clientIdentity");
64
+ try {
65
+ return this.get("clientIdentity");
66
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
67
+ }
68
+ catch (_) {
69
+ return this.get("identity");
70
+ }
71
+ }
72
+ /**
73
+ * @description Gets the logger
74
+ * @summary Returns the logger instance for the current context
75
+ * @return {any} The logger instance
76
+ */
77
+ get logger() {
78
+ return this.get("logger");
79
+ }
80
+ }
81
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29udHJhY3RDb250ZXh0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbnRyYWN0cy9Db250cmFjdENvbnRleHQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBSWxEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTZCRztBQUNILE1BQU0sT0FBTyxxQkFBc0IsU0FBUSxPQUE0QjtJQUNyRTs7O09BR0c7SUFDSDtRQUNFLEtBQUssRUFBRSxDQUFDO0lBQ1YsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxJQUFJLElBQUk7UUFDTixPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDMUIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxJQUFhLFNBQVM7UUFDcEIsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7SUFDdEMsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxJQUFJLFFBQVE7UUFDViw0SUFBNEk7UUFDNUkscUNBQXFDO1FBQ3JDLElBQUksQ0FBQztZQUNILE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ2xDLDZEQUE2RDtRQUMvRCxDQUFDO1FBQUMsT0FBTyxDQUFNLEVBQUUsQ0FBQztZQUNoQixPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBaUIsQ0FBQyxDQUFDO1FBQ3JDLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILElBQUksTUFBTTtRQUNSLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM1QixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb250ZXh0IH0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBGYWJyaWNDb250cmFjdEZsYWdzIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IENoYWluY29kZVN0dWIsIENsaWVudElkZW50aXR5IH0gZnJvbSBcImZhYnJpYy1zaGltLWFwaVwiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDb250ZXh0IGNsYXNzIGZvciBGYWJyaWMgY2hhaW5jb2RlIG9wZXJhdGlvbnNcbiAqIEBzdW1tYXJ5IFByb3ZpZGVzIGFjY2VzcyB0byBGYWJyaWMtc3BlY2lmaWMgY29udGV4dCBlbGVtZW50cyBsaWtlIHN0dWIsIGlkZW50aXR5LCBhbmQgbG9nZ2VyIHRvIGJlIHVzZWQgYnkgcmVwb3NpdG9yaWVzIGFuZCBhZGFwdGVycyBkdXJpbmcgY29udHJhY3QgZXhlY3V0aW9uLlxuICogQHRlbXBsYXRlIEYgLSBGbGFncyBzcGVjaWZpYyB0byBGYWJyaWMgY29udHJhY3Qgb3BlcmF0aW9uc1xuICogQHBhcmFtIHtvYmplY3R9IFthcmdzXSAtIE9wdGlvbmFsIGluaXRpYWxpemF0aW9uIGFyZ3VtZW50cyBwYXNzZWQgdG8gdGhlIGJhc2UgQ29udGV4dFxuICogQHJldHVybiB7dm9pZH1cbiAqIEBjbGFzcyBGYWJyaWNDb250cmFjdENvbnRleHRcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBJbiBhIEZhYnJpYyBjaGFpbmNvZGUgY29udHJhY3QgbWV0aG9kXG4gKiBjb25zdCBjb250ZXh0ID0gbmV3IEZhYnJpY0NvbnRyYWN0Q29udGV4dCgpO1xuICogLy8gT3B0aW9uYWxseSBzZXQgdmFsdWVzIHZpYSB0aGUgYmFzZSBDb250ZXh0IEFQSVxuICogY29udGV4dC5zZXQoJ3N0dWInLCBjdHguc3R1Yik7XG4gKiBjb250ZXh0LnNldCgnY2xpZW50SWRlbnRpdHknLCBjdHguY2xpZW50SWRlbnRpdHkpO1xuICogY29udGV4dC5zZXQoJ2xvZ2dlcicsIGNvbnRyYWN0TG9nZ2VyKTtcbiAqXG4gKiAvLyBBY2Nlc3MgY29udGV4dCBwcm9wZXJ0aWVzXG4gKiBjb25zdCB0aW1lc3RhbXAgPSBjb250ZXh0LnRpbWVzdGFtcDtcbiAqIGNvbnN0IGNyZWF0b3IgPSBjb250ZXh0LmlkZW50aXR5LmdldElEKCk7XG4gKiBgYGBcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ29udHJhY3RcbiAqICAgcGFydGljaXBhbnQgQ29udGV4dFxuICogICBwYXJ0aWNpcGFudCBMZWRnZXJcbiAqICAgQ29udHJhY3QtPj5Db250ZXh0OiBuZXcgRmFicmljQ29udHJhY3RDb250ZXh0KClcbiAqICAgQ29udHJhY3QtPj5Db250ZXh0OiBzZXQoJ3N0dWInfCdjbGllbnRJZGVudGl0eSd8J2xvZ2dlcicsIC4uLilcbiAqICAgQ29udGV4dC0tPj5Db250cmFjdDogdGltZXN0YW1wLCBpZGVudGl0eSwgbG9nZ2VyXG4gKiAgIENvbnRyYWN0LT4+TGVkZ2VyOiBJbnRlcmFjdCB2aWEgc3R1YlxuICovXG5leHBvcnQgY2xhc3MgRmFicmljQ29udHJhY3RDb250ZXh0IGV4dGVuZHMgQ29udGV4dDxGYWJyaWNDb250cmFjdEZsYWdzPiB7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIG5ldyBGYWJyaWNDb250cmFjdENvbnRleHQgaW5zdGFuY2VcbiAgICogQHN1bW1hcnkgSW5pdGlhbGl6ZXMgdGhlIGNvbnRleHQgd2l0aCBGYWJyaWMtc3BlY2lmaWMgZmxhZ3NcbiAgICovXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEdldHMgdGhlIGNoYWluY29kZSBzdHViXG4gICAqIEBzdW1tYXJ5IFJldHVybnMgdGhlIENoYWluY29kZVN0dWIgaW5zdGFuY2UgZm9yIGludGVyYWN0aW5nIHdpdGggdGhlIGxlZGdlclxuICAgKiBAcmV0dXJuIHtDaGFpbmNvZGVTdHVifSBUaGUgY2hhaW5jb2RlIHN0dWJcbiAgICovXG4gIGdldCBzdHViKCk6IENoYWluY29kZVN0dWIge1xuICAgIHJldHVybiB0aGlzLmdldChcInN0dWJcIik7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEdldHMgdGhlIHRyYW5zYWN0aW9uIHRpbWVzdGFtcFxuICAgKiBAc3VtbWFyeSBPdmVycmlkZXMgdGhlIGJhc2UgdGltZXN0YW1wIGdldHRlciB0byB1c2UgdGhlIHN0dWIncyB0aW1lc3RhbXBcbiAgICogQHJldHVybiB7RGF0ZX0gVGhlIHRyYW5zYWN0aW9uIHRpbWVzdGFtcFxuICAgKi9cbiAgb3ZlcnJpZGUgZ2V0IHRpbWVzdGFtcCgpOiBEYXRlIHtcbiAgICByZXR1cm4gdGhpcy5zdHViLmdldERhdGVUaW1lc3RhbXAoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gR2V0cyB0aGUgY2xpZW50IGlkZW50aXR5XG4gICAqIEBzdW1tYXJ5IFJldHVybnMgdGhlIENsaWVudElkZW50aXR5IGluc3RhbmNlIGZvciB0aGUgdHJhbnNhY3Rpb24gc3VibWl0dGVyXG4gICAqIEByZXR1cm4ge0NsaWVudElkZW50aXR5fSBUaGUgY2xpZW50IGlkZW50aXR5XG4gICAqL1xuICBnZXQgaWRlbnRpdHkoKTogQ2xpZW50SWRlbnRpdHkge1xuICAgIC8vVE9ETzogRmluZCB3aGF0IGlzIGhhcHBlbmluZyBpdCBzZWVtcyBGYWJyaWNDb250cmFjdENvbnRleHQgaXMgYmVpbmcgY3JlYXRlZCB3aXRoIEZhYnJpY0NvbnRyYWN0Q29udGV4dCBpbnN0ZWFkIG9mIHRoZSB0cmFuc2FjdGlvbiBjb250ZXh0XG4gICAgLy8gcmV0dXJuIHRoaXMuZ2V0KFwiY2xpZW50SWRlbnRpdHlcIik7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiB0aGlzLmdldChcImNsaWVudElkZW50aXR5XCIpO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIH0gY2F0Y2ggKF86IGFueSkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0KFwiaWRlbnRpdHlcIiBhcyBhbnkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gR2V0cyB0aGUgbG9nZ2VyXG4gICAqIEBzdW1tYXJ5IFJldHVybnMgdGhlIGxvZ2dlciBpbnN0YW5jZSBmb3IgdGhlIGN1cnJlbnQgY29udGV4dFxuICAgKiBAcmV0dXJuIHthbnl9IFRoZSBsb2dnZXIgaW5zdGFuY2VcbiAgICovXG4gIGdldCBsb2dnZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KFwibG9nZ2VyXCIpO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,74 @@
1
+ import { ChaincodeStub, Iterators, StateQueryResponse } from "fabric-shim";
2
+ import { FabricContractAdapter } from "./ContractAdapter";
3
+ import { Model } from "@decaf-ts/decorator-validation";
4
+ import { Sequence, SequenceOptions } from "@decaf-ts/core";
5
+ import { MangoQuery } from "@decaf-ts/for-couchdb";
6
+ export declare class FabricContractPrivateDataAdapter extends FabricContractAdapter {
7
+ private readonly collections?;
8
+ /**
9
+ * @description Creates a new FabricContractAdapter instance
10
+ * @summary Initializes an adapter for interacting with the Fabric state database
11
+ * @param {void} scope - Not used in this adapter
12
+ * @param {string} [alias] - Optional alias for the adapter instance
13
+ */
14
+ constructor(scope: void, alias?: string, collections?: string[] | undefined);
15
+ Sequence(options: SequenceOptions): Promise<Sequence>;
16
+ /**
17
+ * @description Reads a record from the state database
18
+ * @summary Retrieves and deserializes a record from the Fabric state database
19
+ * @param {string} tableName - The name of the table/collection
20
+ * @param {string | number} id - The record identifier
21
+ * @param {...any[]} args - Additional arguments, including the chaincode stub and logger
22
+ * @return {Promise<Record<string, any>>} Promise resolving to the retrieved record
23
+ */
24
+ read(tableName: string, id: string | number, instance: any, ...args: any[]): Promise<Record<string, any>>;
25
+ /**
26
+ * @description Deletes a record from the state database
27
+ * @summary Retrieves a record and then removes it from the Fabric state database
28
+ * @param {string} tableName - The name of the table/collection
29
+ * @param {string | number} id - The record identifier to delete
30
+ * @param {...any[]} args - Additional arguments, including the chaincode stub and logger
31
+ * @return {Promise<Record<string, any>>} Promise resolving to the deleted record
32
+ */
33
+ delete(tableName: string, id: string | number, instance: any, ...args: any[]): Promise<Record<string, any>>;
34
+ prepare<M extends Model>(model: M, pk: keyof M, ...args: any[]): {
35
+ record: Record<string, any>;
36
+ id: string;
37
+ transient?: Record<string, any>;
38
+ };
39
+ updatePrefix(tableName: string, id: string | number, model: Record<string, any>, ...args: any[]): (string | number | Record<string, any>)[];
40
+ putState(stub: ChaincodeStub, id: string, model: Record<string, any>, ...args: any[]): Promise<Record<string, any>>;
41
+ readState(stub: ChaincodeStub, tableName: string, id: string, instance: any, ...args: any[]): Promise<any[]>;
42
+ deleteState(stub: ChaincodeStub, tableName: string, id: string, instance: any, ...args: any[]): Promise<void>;
43
+ queryResult(stub: ChaincodeStub, rawInput: any, instance: any): Promise<Iterators.StateQueryIterator>;
44
+ queryResultPaginated(stub: ChaincodeStub, rawInput: any, limit: number | undefined, skip: number | undefined, instance: any): Promise<StateQueryResponse<Iterators.StateQueryIterator>>;
45
+ /**
46
+ * @description Executes a raw query against the state database
47
+ * @summary Performs a rich query using CouchDB syntax against the Fabric state database
48
+ * @template R - The return type
49
+ * @param {MangoQuery} rawInput - The Mango Query to execute
50
+ * @param {boolean} docsOnly - Whether to return only documents (not used in this implementation)
51
+ * @param {...any[]} args - Additional arguments, including the chaincode stub and logger
52
+ * @return {Promise<R>} Promise resolving to the query results
53
+ * @mermaid
54
+ * sequenceDiagram
55
+ * participant Caller
56
+ * participant FabricContractAdapter
57
+ * participant Stub
58
+ * participant StateDB
59
+ *
60
+ * Caller->>FabricContractAdapter: raw(rawInput, docsOnly, ctx)
61
+ * FabricContractAdapter->>FabricContractAdapter: Extract limit and skip
62
+ * alt With pagination
63
+ * FabricContractAdapter->>Stub: getQueryResultWithPagination(query, limit, skip)
64
+ * else Without pagination
65
+ * FabricContractAdapter->>Stub: getQueryResult(query)
66
+ * end
67
+ * Stub->>StateDB: Execute query
68
+ * StateDB-->>Stub: Iterator
69
+ * Stub-->>FabricContractAdapter: Iterator
70
+ * FabricContractAdapter->>FabricContractAdapter: resultIterator(log, iterator)
71
+ * FabricContractAdapter-->>Caller: results
72
+ */
73
+ raw<R>(rawInput: MangoQuery, docsOnly: boolean, ...args: any[]): Promise<R>;
74
+ }
@@ -0,0 +1,277 @@
1
+ import { FabricContractAdapter } from "./ContractAdapter.js";
2
+ import { NotFoundError, SerializationError, } from "@decaf-ts/db-decorators";
3
+ import { MISSING_PRIVATE_DATA_REGEX, modelToPrivate, processModel, } from "./private-data.js";
4
+ import { UnauthorizedPrivateDataAccess } from "./../shared/errors.js";
5
+ import { FabricContractSequence } from "./FabricContractSequence.js";
6
+ import { CouchDBKeys } from "@decaf-ts/for-couchdb";
7
+ export class FabricContractPrivateDataAdapter extends FabricContractAdapter {
8
+ /**
9
+ * @description Creates a new FabricContractAdapter instance
10
+ * @summary Initializes an adapter for interacting with the Fabric state database
11
+ * @param {void} scope - Not used in this adapter
12
+ * @param {string} [alias] - Optional alias for the adapter instance
13
+ */
14
+ constructor(scope, alias, collections) {
15
+ super(scope, alias);
16
+ this.collections = collections;
17
+ this.collections = collections || [];
18
+ }
19
+ async Sequence(options) {
20
+ return new FabricContractSequence(options, this, this.collections);
21
+ }
22
+ /**
23
+ * @description Reads a record from the state database
24
+ * @summary Retrieves and deserializes a record from the Fabric state database
25
+ * @param {string} tableName - The name of the table/collection
26
+ * @param {string | number} id - The record identifier
27
+ * @param {...any[]} args - Additional arguments, including the chaincode stub and logger
28
+ * @return {Promise<Record<string, any>>} Promise resolving to the retrieved record
29
+ */
30
+ async read(tableName, id, instance, ...args) {
31
+ const { stub, logger } = args.pop();
32
+ const log = logger.for(this.read);
33
+ let model;
34
+ try {
35
+ const results = await this.readState(stub, tableName, id.toString(), instance);
36
+ if (results.length < 1) {
37
+ log.debug(`No record found for id ${id} in ${tableName} table`);
38
+ throw new NotFoundError(`No record found for id ${id} in ${tableName} table`);
39
+ }
40
+ else if (results.length < 2) {
41
+ log.debug(`No record found for id ${id} in ${tableName} table`);
42
+ model = results.pop();
43
+ }
44
+ else {
45
+ model = this.mergeModels(results);
46
+ }
47
+ }
48
+ catch (e) {
49
+ throw this.parseError(e);
50
+ }
51
+ return model;
52
+ }
53
+ /**
54
+ * @description Deletes a record from the state database
55
+ * @summary Retrieves a record and then removes it from the Fabric state database
56
+ * @param {string} tableName - The name of the table/collection
57
+ * @param {string | number} id - The record identifier to delete
58
+ * @param {...any[]} args - Additional arguments, including the chaincode stub and logger
59
+ * @return {Promise<Record<string, any>>} Promise resolving to the deleted record
60
+ */
61
+ async delete(tableName, id, instance, ...args) {
62
+ const ctx = args.pop();
63
+ const { stub, logger } = ctx;
64
+ const log = logger.for(this.delete);
65
+ args.push(ctx);
66
+ let model;
67
+ try {
68
+ model = await this.read(tableName, id, instance, ...args);
69
+ log.verbose(`deleting entry with pk ${id} from ${tableName} table`);
70
+ this.deleteState(stub, tableName, id.toString(), instance);
71
+ }
72
+ catch (e) {
73
+ throw this.parseError(e);
74
+ }
75
+ return model;
76
+ }
77
+ prepare(model, pk, ...args) {
78
+ const { stub, logger } = args.pop();
79
+ const tableName = args.shift();
80
+ const log = logger.for(this.prepare);
81
+ const split = processModel(this, model);
82
+ // if ((model as any)[PersistenceKeys.METADATA]) {
83
+ // log.silly(
84
+ // `Passing along persistence metadata for ${(model as any)[PersistenceKeys.METADATA]}`
85
+ // );
86
+ // Object.defineProperty(split.result, PersistenceKeys.METADATA, {
87
+ // enumerable: false,
88
+ // writable: false,
89
+ // configurable: true,
90
+ // value: (model as any)[PersistenceKeys.METADATA],
91
+ // });
92
+ // }
93
+ log.info(`Preparing record for ${tableName} table with pk ${model[pk]}`);
94
+ return {
95
+ record: split.privateData,
96
+ id: stub.createCompositeKey(tableName, [String(model[pk])]),
97
+ transient: split.transient,
98
+ };
99
+ }
100
+ updatePrefix(tableName, id, model, ...args) {
101
+ const ctx = args.pop();
102
+ const collections = Object.keys(model);
103
+ for (const collection of collections) {
104
+ model[collection][CouchDBKeys.TABLE] = tableName;
105
+ }
106
+ const record = model;
107
+ return [tableName, id, record, ctx];
108
+ }
109
+ async putState(stub, id, model,
110
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
111
+ ...args) {
112
+ const collections = Object.keys(model);
113
+ let res = {};
114
+ let data;
115
+ for (const collection of collections) {
116
+ res = model[collection];
117
+ try {
118
+ data = Buffer.from(FabricContractAdapter.serializer.serialize(model[collection]));
119
+ }
120
+ catch (e) {
121
+ throw new SerializationError(`Failed to serialize record with id ${id}: ${e}`);
122
+ }
123
+ await stub.putPrivateData(collection, id.toString(), data);
124
+ }
125
+ return res;
126
+ }
127
+ async readState(stub, tableName, id, instance,
128
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
129
+ ...args) {
130
+ const composedKey = stub.createCompositeKey(tableName, [String(id)]);
131
+ const model = modelToPrivate(instance);
132
+ const collections = Object.keys(model.private);
133
+ const results = [];
134
+ for (const collection of collections) {
135
+ try {
136
+ let res = await stub.getPrivateData(collection, composedKey);
137
+ if (res.toString() === "") {
138
+ throw new NotFoundError(`Entry with id ${id} doesn't exist...`);
139
+ }
140
+ try {
141
+ res = FabricContractAdapter.serializer.deserialize(res.toString()
142
+ // model.constructor.name
143
+ );
144
+ }
145
+ catch (e) {
146
+ throw new SerializationError(`Failed to parse private data: ${e}`);
147
+ }
148
+ results.push(res);
149
+ }
150
+ catch (e) {
151
+ if (MISSING_PRIVATE_DATA_REGEX.test(e.message))
152
+ throw new UnauthorizedPrivateDataAccess(e);
153
+ throw e;
154
+ }
155
+ }
156
+ return results;
157
+ }
158
+ async deleteState(stub, tableName, id, instance,
159
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
160
+ ...args) {
161
+ const composedKey = stub.createCompositeKey(tableName, [String(id)]);
162
+ const model = modelToPrivate(instance);
163
+ const collections = Object.keys(model.private);
164
+ for (const collection of collections) {
165
+ await stub.deletePrivateData(collection, composedKey);
166
+ }
167
+ }
168
+ async queryResult(stub, rawInput, instance) {
169
+ const privateData = modelToPrivate(instance).private;
170
+ const collection = Object.keys(privateData)[0] || "";
171
+ const result = (await stub.getPrivateDataQueryResult(collection, JSON.stringify(rawInput)));
172
+ const iterator = result.iterator;
173
+ return iterator;
174
+ }
175
+ async queryResultPaginated(stub, rawInput, limit = 250, skip = undefined, instance) {
176
+ const privateData = modelToPrivate(instance).private;
177
+ const collection = Object.keys(privateData)[0] || "";
178
+ const iterator = await stub.getPrivateDataQueryResult(collection, JSON.stringify(rawInput));
179
+ const results = [];
180
+ let count = 0;
181
+ let reachedBookmark = skip ? false : true;
182
+ let lastKey = null;
183
+ while (true) {
184
+ const res = await iterator.next();
185
+ if (res.value && res.value.value.toString()) {
186
+ const recordKey = res.value.key;
187
+ const recordValue = res.value.value.toString("utf8");
188
+ // If we have a skip, skip until we reach it
189
+ if (!reachedBookmark) {
190
+ if (recordKey === skip?.toString()) {
191
+ reachedBookmark = true;
192
+ }
193
+ continue;
194
+ }
195
+ results.push({ Key: recordKey, Record: JSON.parse(recordValue) });
196
+ lastKey = recordKey;
197
+ count++;
198
+ if (count >= limit) {
199
+ await iterator.close();
200
+ return {
201
+ iterator: results,
202
+ metadata: {
203
+ fetchedRecordsCount: results.length,
204
+ bookmark: lastKey,
205
+ },
206
+ };
207
+ }
208
+ }
209
+ if (res.done) {
210
+ await iterator.close();
211
+ return {
212
+ iterator: results,
213
+ metadata: {
214
+ fetchedRecordsCount: results.length,
215
+ bookmark: "",
216
+ },
217
+ };
218
+ }
219
+ }
220
+ // return (await stub.getQueryResultWithPagination(
221
+ // JSON.stringify(rawInput),
222
+ // limit,
223
+ // skip?.toString()
224
+ // )) as StateQueryResponse<Iterators.StateQueryIterator>;
225
+ }
226
+ /**
227
+ * @description Executes a raw query against the state database
228
+ * @summary Performs a rich query using CouchDB syntax against the Fabric state database
229
+ * @template R - The return type
230
+ * @param {MangoQuery} rawInput - The Mango Query to execute
231
+ * @param {boolean} docsOnly - Whether to return only documents (not used in this implementation)
232
+ * @param {...any[]} args - Additional arguments, including the chaincode stub and logger
233
+ * @return {Promise<R>} Promise resolving to the query results
234
+ * @mermaid
235
+ * sequenceDiagram
236
+ * participant Caller
237
+ * participant FabricContractAdapter
238
+ * participant Stub
239
+ * participant StateDB
240
+ *
241
+ * Caller->>FabricContractAdapter: raw(rawInput, docsOnly, ctx)
242
+ * FabricContractAdapter->>FabricContractAdapter: Extract limit and skip
243
+ * alt With pagination
244
+ * FabricContractAdapter->>Stub: getQueryResultWithPagination(query, limit, skip)
245
+ * else Without pagination
246
+ * FabricContractAdapter->>Stub: getQueryResult(query)
247
+ * end
248
+ * Stub->>StateDB: Execute query
249
+ * StateDB-->>Stub: Iterator
250
+ * Stub-->>FabricContractAdapter: Iterator
251
+ * FabricContractAdapter->>FabricContractAdapter: resultIterator(log, iterator)
252
+ * FabricContractAdapter-->>Caller: results
253
+ */
254
+ async raw(rawInput, docsOnly, ...args) {
255
+ const { stub, logger } = args.pop();
256
+ const log = logger.for(this.raw);
257
+ const { skip, limit } = rawInput;
258
+ const instance = args.shift();
259
+ let iterator;
260
+ if (limit || skip) {
261
+ delete rawInput["limit"];
262
+ delete rawInput["skip"];
263
+ log.debug(`Retrieving paginated iterator: limit: ${limit}/ skip: ${skip}`);
264
+ const response = (await this.queryResultPaginated(stub, rawInput, limit || 250, skip?.toString(), instance));
265
+ iterator = response.iterator;
266
+ }
267
+ else {
268
+ log.debug("Retrieving iterator");
269
+ iterator = (await this.queryResult(stub, rawInput, instance));
270
+ }
271
+ log.debug("Iterator acquired");
272
+ const results = (await this.resultIterator(log, iterator));
273
+ log.debug(`returning {0} results`, `${Array.isArray(results) ? results.length : 1}`);
274
+ return results;
275
+ }
276
+ }
277
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29udHJhY3RQcml2YXRlRGF0YUFkYXB0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29udHJhY3RzL0NvbnRyYWN0UHJpdmF0ZURhdGFBZGFwdGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSw2QkFBMEI7QUFDMUQsT0FBTyxFQUVMLGFBQWEsRUFDYixrQkFBa0IsR0FDbkIsTUFBTSx5QkFBeUIsQ0FBQztBQUVqQyxPQUFPLEVBQ0wsMEJBQTBCLEVBQzFCLGNBQWMsRUFDZCxZQUFZLEdBQ2IsMEJBQXVCO0FBQ3hCLE9BQU8sRUFBRSw2QkFBNkIsRUFBRSw4QkFBeUI7QUFDakUsT0FBTyxFQUFFLHNCQUFzQixFQUFFLG9DQUFpQztBQUdsRSxPQUFPLEVBQUUsV0FBVyxFQUFjLE1BQU0sdUJBQXVCLENBQUM7QUFFaEUsTUFBTSxPQUFPLGdDQUFpQyxTQUFRLHFCQUFxQjtJQUN6RTs7Ozs7T0FLRztJQUNILFlBQ0UsS0FBVyxFQUNYLEtBQWMsRUFDRyxXQUFzQjtRQUV2QyxLQUFLLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBRkgsZ0JBQVcsR0FBWCxXQUFXLENBQVc7UUFHdkMsSUFBSSxDQUFDLFdBQVcsR0FBRyxXQUFXLElBQUksRUFBRSxDQUFDO0lBQ3ZDLENBQUM7SUFFUSxLQUFLLENBQUMsUUFBUSxDQUFDLE9BQXdCO1FBQzlDLE9BQU8sSUFBSSxzQkFBc0IsQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUNyRSxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNNLEtBQUssQ0FBQyxJQUFJLENBQ2pCLFNBQWlCLEVBQ2pCLEVBQW1CLEVBQ25CLFFBQWEsRUFDYixHQUFHLElBQVc7UUFFZCxNQUFNLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNwQyxN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QUFxRCxDQUFDO1lBQ3pELFFBQVEsR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDO1FBQy9CLENBQUM7YUFBTSxDQUFDO1lBQ04sR0FBRyxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1lBQ2pDLFFBQVEsR0FBRyxDQUFDLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FDaEMsSUFBSSxFQUNKLFFBQVEsRUFDUixRQUFRLENBQ1QsQ0FBaUMsQ0FBQztRQUNyQyxDQUFDO1FBQ0QsR0FBRyxDQUFDLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBRS9CLE1BQU0sT0FBTyxHQUFHLENBQUMsTUFBTSxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsQ0FBTSxDQUFDO1FBQ2hFLEdBQUcsQ0FBQyxLQUFLLENBQ1AsdUJBQXVCLEVBQ3ZCLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQ2pELENBQUM7UUFDRixPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGFpbmNvZGVTdHViLCBJdGVyYXRvcnMsIFN0YXRlUXVlcnlSZXNwb25zZSB9IGZyb20gXCJmYWJyaWMtc2hpbVwiO1xuaW1wb3J0IHsgRmFicmljQ29udHJhY3RBZGFwdGVyIH0gZnJvbSBcIi4vQ29udHJhY3RBZGFwdGVyXCI7XG5pbXBvcnQge1xuICBCYXNlRXJyb3IsXG4gIE5vdEZvdW5kRXJyb3IsXG4gIFNlcmlhbGl6YXRpb25FcnJvcixcbn0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7XG4gIE1JU1NJTkdfUFJJVkFURV9EQVRBX1JFR0VYLFxuICBtb2RlbFRvUHJpdmF0ZSxcbiAgcHJvY2Vzc01vZGVsLFxufSBmcm9tIFwiLi9wcml2YXRlLWRhdGFcIjtcbmltcG9ydCB7IFVuYXV0aG9yaXplZFByaXZhdGVEYXRhQWNjZXNzIH0gZnJvbSBcIi4uL3NoYXJlZC9lcnJvcnNcIjtcbmltcG9ydCB7IEZhYnJpY0NvbnRyYWN0U2VxdWVuY2UgfSBmcm9tIFwiLi9GYWJyaWNDb250cmFjdFNlcXVlbmNlXCI7XG5pbXBvcnQgeyBTZXF1ZW5jZSwgU2VxdWVuY2VPcHRpb25zIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBGYWJyaWNDb250cmFjdENvbnRleHQgfSBmcm9tIFwiLi9Db250cmFjdENvbnRleHRcIjtcbmltcG9ydCB7IENvdWNoREJLZXlzLCBNYW5nb1F1ZXJ5IH0gZnJvbSBcIkBkZWNhZi10cy9mb3ItY291Y2hkYlwiO1xuXG5leHBvcnQgY2xhc3MgRmFicmljQ29udHJhY3RQcml2YXRlRGF0YUFkYXB0ZXIgZXh0ZW5kcyBGYWJyaWNDb250cmFjdEFkYXB0ZXIge1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBuZXcgRmFicmljQ29udHJhY3RBZGFwdGVyIGluc3RhbmNlXG4gICAqIEBzdW1tYXJ5IEluaXRpYWxpemVzIGFuIGFkYXB0ZXIgZm9yIGludGVyYWN0aW5nIHdpdGggdGhlIEZhYnJpYyBzdGF0ZSBkYXRhYmFzZVxuICAgKiBAcGFyYW0ge3ZvaWR9IHNjb3BlIC0gTm90IHVzZWQgaW4gdGhpcyBhZGFwdGVyXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbYWxpYXNdIC0gT3B0aW9uYWwgYWxpYXMgZm9yIHRoZSBhZGFwdGVyIGluc3RhbmNlXG4gICAqL1xuICBjb25zdHJ1Y3RvcihcbiAgICBzY29wZTogdm9pZCxcbiAgICBhbGlhcz86IHN0cmluZyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNvbGxlY3Rpb25zPzogc3RyaW5nW11cbiAgKSB7XG4gICAgc3VwZXIoc2NvcGUsIGFsaWFzKTtcbiAgICB0aGlzLmNvbGxlY3Rpb25zID0gY29sbGVjdGlvbnMgfHwgW107XG4gIH1cblxuICBvdmVycmlkZSBhc3luYyBTZXF1ZW5jZShvcHRpb25zOiBTZXF1ZW5jZU9wdGlvbnMpOiBQcm9taXNlPFNlcXVlbmNlPiB7XG4gICAgcmV0dXJuIG5ldyBGYWJyaWNDb250cmFjdFNlcXVlbmNlKG9wdGlvbnMsIHRoaXMsIHRoaXMuY29sbGVjdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZWFkcyBhIHJlY29yZCBmcm9tIHRoZSBzdGF0ZSBkYXRhYmFzZVxuICAgKiBAc3VtbWFyeSBSZXRyaWV2ZXMgYW5kIGRlc2VyaWFsaXplcyBhIHJlY29yZCBmcm9tIHRoZSBGYWJyaWMgc3RhdGUgZGF0YWJhc2VcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZS9jb2xsZWN0aW9uXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgbnVtYmVyfSBpZCAtIFRoZSByZWNvcmQgaWRlbnRpZmllclxuICAgKiBAcGFyYW0gey4uLmFueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHMsIGluY2x1ZGluZyB0aGUgY2hhaW5jb2RlIHN0dWIgYW5kIGxvZ2dlclxuICAgKiBAcmV0dXJuIHtQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+fSBQcm9taXNlIHJlc29sdmluZyB0byB0aGUgcmV0cmlldmVkIHJlY29yZFxuICAgKi9cbiAgb3ZlcnJpZGUgYXN5bmMgcmVhZChcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZDogc3RyaW5nIHwgbnVtYmVyLFxuICAgIGluc3RhbmNlOiBhbnksXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+PiB7XG4gICAgY29uc3QgeyBzdHViLCBsb2dnZXIgfSA9IGFyZ3MucG9wKCk7XG4gICAgY29uc3QgbG9nID0gbG9nZ2VyLmZvcih0aGlzLnJlYWQpO1xuXG4gICAgbGV0IG1vZGVsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgdGhpcy5yZWFkU3RhdGUoXG4gICAgICAgIHN0dWIsXG4gICAgICAgIHRhYmxlTmFtZSxcbiAgICAgICAgaWQudG9TdHJpbmcoKSxcbiAgICAgICAgaW5zdGFuY2VcbiAgICAgICk7XG5cbiAgICAgIGlmIChyZXN1bHRzLmxlbmd0aCA8IDEpIHtcbiAgICAgICAgbG9nLmRlYnVnKGBObyByZWNvcmQgZm91bmQgZm9yIGlkICR7aWR9IGluICR7dGFibGVOYW1lfSB0YWJsZWApO1xuICAgICAgICB0aHJvdyBuZXcgTm90Rm91bmRFcnJvcihcbiAgICAgICAgICBgTm8gcmVjb3JkIGZvdW5kIGZvciBpZCAke2lkfSBpbiAke3RhYmxlTmFtZX0gdGFibGVgXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKHJlc3VsdHMubGVuZ3RoIDwgMikge1xuICAgICAgICBsb2cuZGVidWcoYE5vIHJlY29yZCBmb3VuZCBmb3IgaWQgJHtpZH0gaW4gJHt0YWJsZU5hbWV9IHRhYmxlYCk7XG4gICAgICAgIG1vZGVsID0gcmVzdWx0cy5wb3AoKSBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbW9kZWwgPSB0aGlzLm1lcmdlTW9kZWxzKHJlc3VsdHMpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHRocm93IHRoaXMucGFyc2VFcnJvcihlIGFzIEVycm9yKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbW9kZWw7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIERlbGV0ZXMgYSByZWNvcmQgZnJvbSB0aGUgc3RhdGUgZGF0YWJhc2VcbiAgICogQHN1bW1hcnkgUmV0cmlldmVzIGEgcmVjb3JkIGFuZCB0aGVuIHJlbW92ZXMgaXQgZnJvbSB0aGUgRmFicmljIHN0YXRlIGRhdGFiYXNlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0YWJsZU5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgdGFibGUvY29sbGVjdGlvblxuICAgKiBAcGFyYW0ge3N0cmluZyB8IG51bWJlcn0gaWQgLSBUaGUgcmVjb3JkIGlkZW50aWZpZXIgdG8gZGVsZXRlXG4gICAqIEBwYXJhbSB7Li4uYW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cywgaW5jbHVkaW5nIHRoZSBjaGFpbmNvZGUgc3R1YiBhbmQgbG9nZ2VyXG4gICAqIEByZXR1cm4ge1Byb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj59IFByb21pc2UgcmVzb2x2aW5nIHRvIHRoZSBkZWxldGVkIHJlY29yZFxuICAgKi9cbiAgb3ZlcnJpZGUgYXN5bmMgZGVsZXRlKFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkOiBzdHJpbmcgfCBudW1iZXIsXG4gICAgaW5zdGFuY2U6IGFueSxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+IHtcbiAgICBjb25zdCBjdHggPSBhcmdzLnBvcCgpO1xuICAgIGNvbnN0IHsgc3R1YiwgbG9nZ2VyIH0gPSBjdHg7XG4gICAgY29uc3QgbG9nID0gbG9nZ2VyLmZvcih0aGlzLmRlbGV0ZSk7XG5cbiAgICBhcmdzLnB1c2goY3R4KTtcblxuICAgIGxldCBtb2RlbDogUmVjb3JkPHN0cmluZywgYW55PjtcbiAgICB0cnkge1xuICAgICAgbW9kZWwgPSBhd2FpdCB0aGlzLnJlYWQodGFibGVOYW1lLCBpZCwgaW5zdGFuY2UsIC4uLmFyZ3MpO1xuICAgICAgbG9nLnZlcmJvc2UoYGRlbGV0aW5nIGVudHJ5IHdpdGggcGsgJHtpZH0gZnJvbSAke3RhYmxlTmFtZX0gdGFibGVgKTtcbiAgICAgIHRoaXMuZGVsZXRlU3RhdGUoc3R1YiwgdGFibGVOYW1lLCBpZC50b1N0cmluZygpLCBpbnN0YW5jZSk7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgdGhpcy5wYXJzZUVycm9yKGUgYXMgRXJyb3IpO1xuICAgIH1cblxuICAgIHJldHVybiBtb2RlbDtcbiAgfVxuICBvdmVycmlkZSBwcmVwYXJlPE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgbW9kZWw6IE0sXG4gICAgcGs6IGtleW9mIE0sXG4gICAgLi4uYXJnczogYW55W11cbiAgKToge1xuICAgIHJlY29yZDogUmVjb3JkPHN0cmluZywgYW55PjtcbiAgICBpZDogc3RyaW5nO1xuICAgIHRyYW5zaWVudD86IFJlY29yZDxzdHJpbmcsIGFueT47XG4gIH0ge1xuICAgIGNvbnN0IHsgc3R1YiwgbG9nZ2VyIH0gPSBhcmdzLnBvcCgpO1xuICAgIGNvbnN0IHRhYmxlTmFtZSA9IGFyZ3Muc2hpZnQoKTtcbiAgICBjb25zdCBsb2cgPSBsb2dnZXIuZm9yKHRoaXMucHJlcGFyZSk7XG5cbiAgICBjb25zdCBzcGxpdCA9IHByb2Nlc3NNb2RlbCh0aGlzLCBtb2RlbCk7XG4gICAgLy8gaWYgKChtb2RlbCBhcyBhbnkpW1BlcnNpc3RlbmNlS2V5cy5NRVRBREFUQV0pIHtcbiAgICAvLyAgIGxvZy5zaWxseShcbiAgICAvLyAgICAgYFBhc3NpbmcgYWxvbmcgcGVyc2lzdGVuY2UgbWV0YWRhdGEgZm9yICR7KG1vZGVsIGFzIGFueSlbUGVyc2lzdGVuY2VLZXlzLk1FVEFEQVRBXX1gXG4gICAgLy8gICApO1xuICAgIC8vICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHNwbGl0LnJlc3VsdCwgUGVyc2lzdGVuY2VLZXlzLk1FVEFEQVRBLCB7XG4gICAgLy8gICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgIC8vICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgLy8gICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICAvLyAgICAgdmFsdWU6IChtb2RlbCBhcyBhbnkpW1BlcnNpc3RlbmNlS2V5cy5NRVRBREFUQV0sXG4gICAgLy8gICB9KTtcbiAgICAvLyB9XG5cbiAgICBsb2cuaW5mbyhgUHJlcGFyaW5nIHJlY29yZCBmb3IgJHt0YWJsZU5hbWV9IHRhYmxlIHdpdGggcGsgJHttb2RlbFtwa119YCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgcmVjb3JkOiBzcGxpdC5wcml2YXRlRGF0YSBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICAgICAgaWQ6IHN0dWIuY3JlYXRlQ29tcG9zaXRlS2V5KHRhYmxlTmFtZSwgW1N0cmluZyhtb2RlbFtwa10pXSksXG4gICAgICB0cmFuc2llbnQ6IHNwbGl0LnRyYW5zaWVudCxcbiAgICB9O1xuICB9XG5cbiAgb3ZlcnJpZGUgdXBkYXRlUHJlZml4KFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkOiBzdHJpbmcgfCBudW1iZXIsXG4gICAgbW9kZWw6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogKHN0cmluZyB8IG51bWJlciB8IFJlY29yZDxzdHJpbmcsIGFueT4pW10ge1xuICAgIGNvbnN0IGN0eDogRmFicmljQ29udHJhY3RDb250ZXh0ID0gYXJncy5wb3AoKTtcbiAgICBjb25zdCBjb2xsZWN0aW9ucyA9IE9iamVjdC5rZXlzKG1vZGVsKTtcblxuICAgIGZvciAoY29uc3QgY29sbGVjdGlvbiBvZiBjb2xsZWN0aW9ucykge1xuICAgICAgbW9kZWxbY29sbGVjdGlvbl1bQ291Y2hEQktleXMuVEFCTEVdID0gdGFibGVOYW1lO1xuICAgIH1cblxuICAgIGNvbnN0IHJlY29yZDogUmVjb3JkPHN0cmluZywgYW55PiA9IG1vZGVsO1xuXG4gICAgcmV0dXJuIFt0YWJsZU5hbWUsIGlkLCByZWNvcmQsIGN0eF07XG4gIH1cbiAgb3ZlcnJpZGUgYXN5bmMgcHV0U3RhdGUoXG4gICAgc3R1YjogQ2hhaW5jb2RlU3R1YixcbiAgICBpZDogc3RyaW5nLFxuICAgIG1vZGVsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApIHtcbiAgICBjb25zdCBjb2xsZWN0aW9ucyA9IE9iamVjdC5rZXlzKG1vZGVsKTtcbiAgICBsZXQgcmVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG4gICAgbGV0IGRhdGE6IEJ1ZmZlcjtcblxuICAgIGZvciAoY29uc3QgY29sbGVjdGlvbiBvZiBjb2xsZWN0aW9ucykge1xuICAgICAgcmVzID0gbW9kZWwhW2NvbGxlY3Rpb25dO1xuICAgICAgdHJ5IHtcbiAgICAgICAgZGF0YSA9IEJ1ZmZlci5mcm9tKFxuICAgICAgICAgIEZhYnJpY0NvbnRyYWN0QWRhcHRlci5zZXJpYWxpemVyLnNlcmlhbGl6ZShcbiAgICAgICAgICAgIG1vZGVsIVtjb2xsZWN0aW9uXSBhcyBNb2RlbFxuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgICAgdGhyb3cgbmV3IFNlcmlhbGl6YXRpb25FcnJvcihcbiAgICAgICAgICBgRmFpbGVkIHRvIHNlcmlhbGl6ZSByZWNvcmQgd2l0aCBpZCAke2lkfTogJHtlfWBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHN0dWIucHV0UHJpdmF0ZURhdGEoY29sbGVjdGlvbiwgaWQudG9TdHJpbmcoKSwgZGF0YSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlcztcbiAgfVxuXG4gIG92ZXJyaWRlIGFzeW5jIHJlYWRTdGF0ZShcbiAgICBzdHViOiBDaGFpbmNvZGVTdHViLFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGlkOiBzdHJpbmcsXG4gICAgaW5zdGFuY2U6IGFueSxcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgLi4uYXJnczogYW55W11cbiAgKSB7XG4gICAgY29uc3QgY29tcG9zZWRLZXkgPSBzdHViLmNyZWF0ZUNvbXBvc2l0ZUtleSh0YWJsZU5hbWUsIFtTdHJpbmcoaWQpXSk7XG4gICAgY29uc3QgbW9kZWwgPSBtb2RlbFRvUHJpdmF0ZShpbnN0YW5jZSk7XG4gICAgY29uc3QgY29sbGVjdGlvbnMgPSBPYmplY3Qua2V5cyhtb2RlbC5wcml2YXRlISk7XG4gICAgY29uc3QgcmVzdWx0czogYW55W10gPSBbXTtcblxuICAgIGZvciAoY29uc3QgY29sbGVjdGlvbiBvZiBjb2xsZWN0aW9ucykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgbGV0IHJlczogQnVmZmVyIHwgUmVjb3JkPHN0cmluZywgYW55PiA9IGF3YWl0IHN0dWIuZ2V0UHJpdmF0ZURhdGEoXG4gICAgICAgICAgY29sbGVjdGlvbixcbiAgICAgICAgICBjb21wb3NlZEtleVxuICAgICAgICApO1xuICAgICAgICBpZiAocmVzLnRvU3RyaW5nKCkgPT09IFwiXCIpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgTm90Rm91bmRFcnJvcihgRW50cnkgd2l0aCBpZCAke2lkfSBkb2Vzbid0IGV4aXN0Li4uYCk7XG4gICAgICAgIH1cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXMgPSBGYWJyaWNDb250cmFjdEFkYXB0ZXIuc2VyaWFsaXplci5kZXNlcmlhbGl6ZShcbiAgICAgICAgICAgIHJlcy50b1N0cmluZygpXG4gICAgICAgICAgICAvLyBtb2RlbC5jb25zdHJ1Y3Rvci5uYW1lXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgICAgIHRocm93IG5ldyBTZXJpYWxpemF0aW9uRXJyb3IoYEZhaWxlZCB0byBwYXJzZSBwcml2YXRlIGRhdGE6ICR7ZX1gKTtcbiAgICAgICAgfVxuICAgICAgICByZXN1bHRzLnB1c2gocmVzKTtcbiAgICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgICAgaWYgKE1JU1NJTkdfUFJJVkFURV9EQVRBX1JFR0VYLnRlc3QoKGUgYXMgQmFzZUVycm9yKS5tZXNzYWdlKSlcbiAgICAgICAgICB0aHJvdyBuZXcgVW5hdXRob3JpemVkUHJpdmF0ZURhdGFBY2Nlc3MoZSBhcyBCYXNlRXJyb3IpO1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHRzO1xuICB9XG5cbiAgb3ZlcnJpZGUgYXN5bmMgZGVsZXRlU3RhdGUoXG4gICAgc3R1YjogQ2hhaW5jb2RlU3R1YixcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBpZDogc3RyaW5nLFxuICAgIGluc3RhbmNlOiBhbnksXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIC4uLmFyZ3M6IGFueVtdXG4gICkge1xuICAgIGNvbnN0IGNvbXBvc2VkS2V5ID0gc3R1Yi5jcmVhdGVDb21wb3NpdGVLZXkodGFibGVOYW1lLCBbU3RyaW5nKGlkKV0pO1xuICAgIGNvbnN0IG1vZGVsID0gbW9kZWxUb1ByaXZhdGUoaW5zdGFuY2UpO1xuICAgIGNvbnN0IGNvbGxlY3Rpb25zID0gT2JqZWN0LmtleXMobW9kZWwucHJpdmF0ZSEpO1xuXG4gICAgZm9yIChjb25zdCBjb2xsZWN0aW9uIG9mIGNvbGxlY3Rpb25zKSB7XG4gICAgICBhd2FpdCBzdHViLmRlbGV0ZVByaXZhdGVEYXRhKGNvbGxlY3Rpb24sIGNvbXBvc2VkS2V5KTtcbiAgICB9XG4gIH1cblxuICBvdmVycmlkZSBhc3luYyBxdWVyeVJlc3VsdChcbiAgICBzdHViOiBDaGFpbmNvZGVTdHViLFxuICAgIHJhd0lucHV0OiBhbnksXG4gICAgaW5zdGFuY2U6IGFueVxuICApOiBQcm9taXNlPEl0ZXJhdG9ycy5TdGF0ZVF1ZXJ5SXRlcmF0b3I+IHtcbiAgICBjb25zdCBwcml2YXRlRGF0YSA9IG1vZGVsVG9Qcml2YXRlKGluc3RhbmNlKS5wcml2YXRlITtcbiAgICBjb25zdCBjb2xsZWN0aW9uID0gT2JqZWN0LmtleXMocHJpdmF0ZURhdGEpWzBdIHx8IFwiXCI7XG5cbiAgICBjb25zdCByZXN1bHQgPSAoYXdhaXQgc3R1Yi5nZXRQcml2YXRlRGF0YVF1ZXJ5UmVzdWx0KFxuICAgICAgY29sbGVjdGlvbixcbiAgICAgIEpTT04uc3RyaW5naWZ5KHJhd0lucHV0KVxuICAgICkpIGFzIGFueTtcblxuICAgIGNvbnN0IGl0ZXJhdG9yID0gcmVzdWx0Lml0ZXJhdG9yIGFzIEl0ZXJhdG9ycy5TdGF0ZVF1ZXJ5SXRlcmF0b3I7XG5cbiAgICByZXR1cm4gaXRlcmF0b3I7XG4gIH1cblxuICBvdmVycmlkZSBhc3luYyBxdWVyeVJlc3VsdFBhZ2luYXRlZChcbiAgICBzdHViOiBDaGFpbmNvZGVTdHViLFxuICAgIHJhd0lucHV0OiBhbnksXG4gICAgbGltaXQ6IG51bWJlciA9IDI1MCxcbiAgICBza2lwOiBudW1iZXIgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQsXG4gICAgaW5zdGFuY2U6IGFueVxuICApOiBQcm9taXNlPFN0YXRlUXVlcnlSZXNwb25zZTxJdGVyYXRvcnMuU3RhdGVRdWVyeUl0ZXJhdG9yPj4ge1xuICAgIGNvbnN0IHByaXZhdGVEYXRhID0gbW9kZWxUb1ByaXZhdGUoaW5zdGFuY2UpLnByaXZhdGUhO1xuICAgIGNvbnN0IGNvbGxlY3Rpb24gPSBPYmplY3Qua2V5cyhwcml2YXRlRGF0YSlbMF0gfHwgXCJcIjtcblxuICAgIGNvbnN0IGl0ZXJhdG9yID0gYXdhaXQgc3R1Yi5nZXRQcml2YXRlRGF0YVF1ZXJ5UmVzdWx0KFxuICAgICAgY29sbGVjdGlvbixcbiAgICAgIEpTT04uc3RyaW5naWZ5KHJhd0lucHV0KVxuICAgICk7XG5cbiAgICBjb25zdCByZXN1bHRzOiBhbnlbXSA9IFtdO1xuICAgIGxldCBjb3VudCA9IDA7XG4gICAgbGV0IHJlYWNoZWRCb29rbWFyayA9IHNraXAgPyBmYWxzZSA6IHRydWU7XG4gICAgbGV0IGxhc3RLZXk6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGl0ZXJhdG9yLm5leHQoKTtcblxuICAgICAgaWYgKHJlcy52YWx1ZSAmJiByZXMudmFsdWUudmFsdWUudG9TdHJpbmcoKSkge1xuICAgICAgICBjb25zdCByZWNvcmRLZXkgPSByZXMudmFsdWUua2V5O1xuICAgICAgICBjb25zdCByZWNvcmRWYWx1ZSA9IChyZXMudmFsdWUudmFsdWUgYXMgYW55KS50b1N0cmluZyhcInV0ZjhcIik7XG5cbiAgICAgICAgLy8gSWYgd2UgaGF2ZSBhIHNraXAsIHNraXAgdW50aWwgd2UgcmVhY2ggaXRcbiAgICAgICAgaWYgKCFyZWFjaGVkQm9va21hcmspIHtcbiAgICAgICAgICBpZiAocmVjb3JkS2V5ID09PSBza2lwPy50b1N0cmluZygpKSB7XG4gICAgICAgICAgICByZWFjaGVkQm9va21hcmsgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJlc3VsdHMucHVzaCh7IEtleTogcmVjb3JkS2V5LCBSZWNvcmQ6IEpTT04ucGFyc2UocmVjb3JkVmFsdWUpIH0pO1xuICAgICAgICBsYXN0S2V5ID0gcmVjb3JkS2V5O1xuICAgICAgICBjb3VudCsrO1xuXG4gICAgICAgIGlmIChjb3VudCA+PSBsaW1pdCkge1xuICAgICAgICAgIGF3YWl0IGl0ZXJhdG9yLmNsb3NlKCk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGl0ZXJhdG9yOiByZXN1bHRzIGFzIHVua25vd24gYXMgSXRlcmF0b3JzLlN0YXRlUXVlcnlJdGVyYXRvcixcbiAgICAgICAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgICAgICAgIGZldGNoZWRSZWNvcmRzQ291bnQ6IHJlc3VsdHMubGVuZ3RoLFxuICAgICAgICAgICAgICBib29rbWFyazogbGFzdEtleSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAocmVzLmRvbmUpIHtcbiAgICAgICAgYXdhaXQgaXRlcmF0b3IuY2xvc2UoKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBpdGVyYXRvcjogcmVzdWx0cyBhcyB1bmtub3duIGFzIEl0ZXJhdG9ycy5TdGF0ZVF1ZXJ5SXRlcmF0b3IsXG4gICAgICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgICAgIGZldGNoZWRSZWNvcmRzQ291bnQ6IHJlc3VsdHMubGVuZ3RoLFxuICAgICAgICAgICAgYm9va21hcms6IFwiXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gcmV0dXJuIChhd2FpdCBzdHViLmdldFF1ZXJ5UmVzdWx0V2l0aFBhZ2luYXRpb24oXG4gICAgLy8gICBKU09OLnN0cmluZ2lmeShyYXdJbnB1dCksXG4gICAgLy8gICBsaW1pdCxcbiAgICAvLyAgIHNraXA/LnRvU3RyaW5nKClcbiAgICAvLyApKSBhcyBTdGF0ZVF1ZXJ5UmVzcG9uc2U8SXRlcmF0b3JzLlN0YXRlUXVlcnlJdGVyYXRvcj47XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEV4ZWN1dGVzIGEgcmF3IHF1ZXJ5IGFnYWluc3QgdGhlIHN0YXRlIGRhdGFiYXNlXG4gICAqIEBzdW1tYXJ5IFBlcmZvcm1zIGEgcmljaCBxdWVyeSB1c2luZyBDb3VjaERCIHN5bnRheCBhZ2FpbnN0IHRoZSBGYWJyaWMgc3RhdGUgZGF0YWJhc2VcbiAgICogQHRlbXBsYXRlIFIgLSBUaGUgcmV0dXJuIHR5cGVcbiAgICogQHBhcmFtIHtNYW5nb1F1ZXJ5fSByYXdJbnB1dCAtIFRoZSBNYW5nbyBRdWVyeSB0byBleGVjdXRlXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gZG9jc09ubHkgLSBXaGV0aGVyIHRvIHJldHVybiBvbmx5IGRvY3VtZW50cyAobm90IHVzZWQgaW4gdGhpcyBpbXBsZW1lbnRhdGlvbilcbiAgICogQHBhcmFtIHsuLi5hbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzLCBpbmNsdWRpbmcgdGhlIGNoYWluY29kZSBzdHViIGFuZCBsb2dnZXJcbiAgICogQHJldHVybiB7UHJvbWlzZTxSPn0gUHJvbWlzZSByZXNvbHZpbmcgdG8gdGhlIHF1ZXJ5IHJlc3VsdHNcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gICAqICAgcGFydGljaXBhbnQgRmFicmljQ29udHJhY3RBZGFwdGVyXG4gICAqICAgcGFydGljaXBhbnQgU3R1YlxuICAgKiAgIHBhcnRpY2lwYW50IFN0YXRlREJcbiAgICpcbiAgICogICBDYWxsZXItPj5GYWJyaWNDb250cmFjdEFkYXB0ZXI6IHJhdyhyYXdJbnB1dCwgZG9jc09ubHksIGN0eClcbiAgICogICBGYWJyaWNDb250cmFjdEFkYXB0ZXItPj5GYWJyaWNDb250cmFjdEFkYXB0ZXI6IEV4dHJhY3QgbGltaXQgYW5kIHNraXBcbiAgICogICBhbHQgV2l0aCBwYWdpbmF0aW9uXG4gICAqICAgICBGYWJyaWNDb250cmFjdEFkYXB0ZXItPj5TdHViOiBnZXRRdWVyeVJlc3VsdFdpdGhQYWdpbmF0aW9uKHF1ZXJ5LCBsaW1pdCwgc2tpcClcbiAgICogICBlbHNlIFdpdGhvdXQgcGFnaW5hdGlvblxuICAgKiAgICAgRmFicmljQ29udHJhY3RBZGFwdGVyLT4+U3R1YjogZ2V0UXVlcnlSZXN1bHQocXVlcnkpXG4gICAqICAgZW5kXG4gICAqICAgU3R1Yi0+PlN0YXRlREI6IEV4ZWN1dGUgcXVlcnlcbiAgICogICBTdGF0ZURCLS0+PlN0dWI6IEl0ZXJhdG9yXG4gICAqICAgU3R1Yi0tPj5GYWJyaWNDb250cmFjdEFkYXB0ZXI6IEl0ZXJhdG9yXG4gICAqICAgRmFicmljQ29udHJhY3RBZGFwdGVyLT4+RmFicmljQ29udHJhY3RBZGFwdGVyOiByZXN1bHRJdGVyYXRvcihsb2csIGl0ZXJhdG9yKVxuICAgKiAgIEZhYnJpY0NvbnRyYWN0QWRhcHRlci0tPj5DYWxsZXI6IHJlc3VsdHNcbiAgICovXG4gIG92ZXJyaWRlIGFzeW5jIHJhdzxSPihcbiAgICByYXdJbnB1dDogTWFuZ29RdWVyeSxcbiAgICBkb2NzT25seTogYm9vbGVhbixcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPFI+IHtcbiAgICBjb25zdCB7IHN0dWIsIGxvZ2dlciB9ID0gYXJncy5wb3AoKTtcbiAgICBjb25zdCBsb2cgPSBsb2dnZXIuZm9yKHRoaXMucmF3KTtcbiAgICBjb25zdCB7IHNraXAsIGxpbWl0IH0gPSByYXdJbnB1dDtcbiAgICBjb25zdCBpbnN0YW5jZSA9IGFyZ3Muc2hpZnQoKTtcbiAgICBsZXQgaXRlcmF0b3I6IEl0ZXJhdG9ycy5TdGF0ZVF1ZXJ5SXRlcmF0b3I7XG4gICAgaWYgKGxpbWl0IHx8IHNraXApIHtcbiAgICAgIGRlbGV0ZSByYXdJbnB1dFtcImxpbWl0XCJdO1xuICAgICAgZGVsZXRlIHJhd0lucHV0W1wic2tpcFwiXTtcbiAgICAgIGxvZy5kZWJ1ZyhcbiAgICAgICAgYFJldHJpZXZpbmcgcGFnaW5hdGVkIGl0ZXJhdG9yOiBsaW1pdDogJHtsaW1pdH0vIHNraXA6ICR7c2tpcH1gXG4gICAgICApO1xuICAgICAgY29uc3QgcmVzcG9uc2U6IFN0YXRlUXVlcnlSZXNwb25zZTxJdGVyYXRvcnMuU3RhdGVRdWVyeUl0ZXJhdG9yPiA9XG4gICAgICAgIChhd2FpdCB0aGlzLnF1ZXJ5UmVzdWx0UGFnaW5hdGVkKFxuICAgICAgICAgIHN0dWIsXG4gICAgICAgICAgcmF3SW5wdXQsXG4gICAgICAgICAgbGltaXQgfHwgMjUwLFxuICAgICAgICAgIChza2lwIGFzIGFueSk/LnRvU3RyaW5nKCksXG4gICAgICAgICAgaW5zdGFuY2VcbiAgICAgICAgKSkgYXMgU3RhdGVRdWVyeVJlc3BvbnNlPEl0ZXJhdG9ycy5TdGF0ZVF1ZXJ5SXRlcmF0b3I+O1xuICAgICAgaXRlcmF0b3IgPSByZXNwb25zZS5pdGVyYXRvcjtcbiAgICB9IGVsc2Uge1xuICAgICAgbG9nLmRlYnVnKFwiUmV0cmlldmluZyBpdGVyYXRvclwiKTtcbiAgICAgIGl0ZXJhdG9yID0gKGF3YWl0IHRoaXMucXVlcnlSZXN1bHQoXG4gICAgICAgIHN0dWIsXG4gICAgICAgIHJhd0lucHV0LFxuICAgICAgICBpbnN0YW5jZVxuICAgICAgKSkgYXMgSXRlcmF0b3JzLlN0YXRlUXVlcnlJdGVyYXRvcjtcbiAgICB9XG4gICAgbG9nLmRlYnVnKFwiSXRlcmF0b3IgYWNxdWlyZWRcIik7XG5cbiAgICBjb25zdCByZXN1bHRzID0gKGF3YWl0IHRoaXMucmVzdWx0SXRlcmF0b3IobG9nLCBpdGVyYXRvcikpIGFzIFI7XG4gICAgbG9nLmRlYnVnKFxuICAgICAgYHJldHVybmluZyB7MH0gcmVzdWx0c2AsXG4gICAgICBgJHtBcnJheS5pc0FycmF5KHJlc3VsdHMpID8gcmVzdWx0cy5sZW5ndGggOiAxfWBcbiAgICApO1xuICAgIHJldHVybiByZXN1bHRzO1xuICB9XG59XG4iXX0=