@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.
- package/LICENSE.md +22 -0
- package/README.md +647 -0
- package/dist/for-fabric.cjs +6223 -0
- package/dist/for-fabric.esm.cjs +6180 -0
- package/lib/client/FabricClientAdapter.cjs +760 -0
- package/lib/client/FabricClientAdapter.d.ts +381 -0
- package/lib/client/FabricClientDispatch.cjs +186 -0
- package/lib/client/FabricClientDispatch.d.ts +125 -0
- package/lib/client/FabricClientRepository.cjs +131 -0
- package/lib/client/FabricClientRepository.d.ts +100 -0
- package/lib/client/erc20/erc20ClientRepository.cjs +343 -0
- package/lib/client/erc20/erc20ClientRepository.d.ts +254 -0
- package/lib/client/fabric-fs.cjs +234 -0
- package/lib/client/fabric-fs.d.ts +92 -0
- package/lib/client/index.cjs +30 -0
- package/lib/client/index.d.ts +13 -0
- package/lib/client/logging.cjs +102 -0
- package/lib/client/logging.d.ts +60 -0
- package/lib/client/services/LoggedService.cjs +47 -0
- package/lib/client/services/LoggedService.d.ts +42 -0
- package/lib/client/services/constants.cjs +3 -0
- package/lib/client/services/constants.d.ts +15 -0
- package/lib/client/services/enrollementService.cjs +344 -0
- package/lib/client/services/enrollementService.d.ts +176 -0
- package/lib/client/services/index.cjs +18 -0
- package/lib/client/services/index.d.ts +1 -0
- package/lib/contracts/ContractAdapter.cjs +730 -0
- package/lib/contracts/ContractAdapter.d.ts +296 -0
- package/lib/contracts/ContractContext.cjs +85 -0
- package/lib/contracts/ContractContext.d.ts +64 -0
- package/lib/contracts/ContractPrivateDataAdapter.cjs +281 -0
- package/lib/contracts/ContractPrivateDataAdapter.d.ts +74 -0
- package/lib/contracts/FabricConstruction.cjs +441 -0
- package/lib/contracts/FabricConstruction.d.ts +304 -0
- package/lib/contracts/FabricContractRepository.cjs +306 -0
- package/lib/contracts/FabricContractRepository.d.ts +162 -0
- package/lib/contracts/FabricContractRepositoryObservableHandler.cjs +85 -0
- package/lib/contracts/FabricContractRepositoryObservableHandler.d.ts +62 -0
- package/lib/contracts/FabricContractSequence.cjs +139 -0
- package/lib/contracts/FabricContractSequence.d.ts +61 -0
- package/lib/contracts/FabricContractStatement.cjs +119 -0
- package/lib/contracts/FabricContractStatement.d.ts +34 -0
- package/lib/contracts/PrivateSequence.cjs +36 -0
- package/lib/contracts/PrivateSequence.d.ts +15 -0
- package/lib/contracts/crud/crud-contract.cjs +257 -0
- package/lib/contracts/crud/crud-contract.d.ts +168 -0
- package/lib/contracts/crud/index.cjs +19 -0
- package/lib/contracts/crud/index.d.ts +2 -0
- package/lib/contracts/crud/serialized-crud-contract.cjs +172 -0
- package/lib/contracts/crud/serialized-crud-contract.d.ts +37 -0
- package/lib/contracts/erc20/erc20contract.cjs +569 -0
- package/lib/contracts/erc20/erc20contract.d.ts +151 -0
- package/lib/contracts/erc20/index.cjs +21 -0
- package/lib/contracts/erc20/index.d.ts +2 -0
- package/lib/contracts/erc20/models.cjs +209 -0
- package/lib/contracts/erc20/models.d.ts +114 -0
- package/lib/contracts/index.cjs +32 -0
- package/lib/contracts/index.d.ts +15 -0
- package/lib/contracts/logging.cjs +96 -0
- package/lib/contracts/logging.d.ts +49 -0
- package/lib/contracts/private-data.cjs +121 -0
- package/lib/contracts/private-data.d.ts +16 -0
- package/lib/contracts/types.cjs +3 -0
- package/lib/contracts/types.d.ts +26 -0
- package/lib/esm/client/FabricClientAdapter.d.ts +381 -0
- package/lib/esm/client/FabricClientAdapter.js +723 -0
- package/lib/esm/client/FabricClientDispatch.d.ts +125 -0
- package/lib/esm/client/FabricClientDispatch.js +182 -0
- package/lib/esm/client/FabricClientRepository.d.ts +100 -0
- package/lib/esm/client/FabricClientRepository.js +127 -0
- package/lib/esm/client/erc20/erc20ClientRepository.d.ts +254 -0
- package/lib/esm/client/erc20/erc20ClientRepository.js +339 -0
- package/lib/esm/client/fabric-fs.d.ts +92 -0
- package/lib/esm/client/fabric-fs.js +191 -0
- package/lib/esm/client/index.d.ts +13 -0
- package/lib/esm/client/index.js +14 -0
- package/lib/esm/client/logging.d.ts +60 -0
- package/lib/esm/client/logging.js +98 -0
- package/lib/esm/client/services/LoggedService.d.ts +42 -0
- package/lib/esm/client/services/LoggedService.js +43 -0
- package/lib/esm/client/services/constants.d.ts +15 -0
- package/lib/esm/client/services/constants.js +2 -0
- package/lib/esm/client/services/enrollementService.d.ts +176 -0
- package/lib/esm/client/services/enrollementService.js +337 -0
- package/lib/esm/client/services/index.d.ts +1 -0
- package/lib/esm/client/services/index.js +2 -0
- package/lib/esm/contracts/ContractAdapter.d.ts +296 -0
- package/lib/esm/contracts/ContractAdapter.js +724 -0
- package/lib/esm/contracts/ContractContext.d.ts +64 -0
- package/lib/esm/contracts/ContractContext.js +81 -0
- package/lib/esm/contracts/ContractPrivateDataAdapter.d.ts +74 -0
- package/lib/esm/contracts/ContractPrivateDataAdapter.js +277 -0
- package/lib/esm/contracts/FabricConstruction.d.ts +304 -0
- package/lib/esm/contracts/FabricConstruction.js +433 -0
- package/lib/esm/contracts/FabricContractRepository.d.ts +162 -0
- package/lib/esm/contracts/FabricContractRepository.js +302 -0
- package/lib/esm/contracts/FabricContractRepositoryObservableHandler.d.ts +62 -0
- package/lib/esm/contracts/FabricContractRepositoryObservableHandler.js +81 -0
- package/lib/esm/contracts/FabricContractSequence.d.ts +61 -0
- package/lib/esm/contracts/FabricContractSequence.js +135 -0
- package/lib/esm/contracts/FabricContractStatement.d.ts +34 -0
- package/lib/esm/contracts/FabricContractStatement.js +115 -0
- package/lib/esm/contracts/PrivateSequence.d.ts +15 -0
- package/lib/esm/contracts/PrivateSequence.js +33 -0
- package/lib/esm/contracts/crud/crud-contract.d.ts +168 -0
- package/lib/esm/contracts/crud/crud-contract.js +253 -0
- package/lib/esm/contracts/crud/index.d.ts +2 -0
- package/lib/esm/contracts/crud/index.js +3 -0
- package/lib/esm/contracts/crud/serialized-crud-contract.d.ts +37 -0
- package/lib/esm/contracts/crud/serialized-crud-contract.js +168 -0
- package/lib/esm/contracts/erc20/erc20contract.d.ts +151 -0
- package/lib/esm/contracts/erc20/erc20contract.js +565 -0
- package/lib/esm/contracts/erc20/index.d.ts +2 -0
- package/lib/esm/contracts/erc20/index.js +4 -0
- package/lib/esm/contracts/erc20/models.d.ts +114 -0
- package/lib/esm/contracts/erc20/models.js +206 -0
- package/lib/esm/contracts/index.d.ts +15 -0
- package/lib/esm/contracts/index.js +16 -0
- package/lib/esm/contracts/logging.d.ts +49 -0
- package/lib/esm/contracts/logging.js +92 -0
- package/lib/esm/contracts/private-data.d.ts +16 -0
- package/lib/esm/contracts/private-data.js +113 -0
- package/lib/esm/contracts/types.d.ts +26 -0
- package/lib/esm/contracts/types.js +2 -0
- package/lib/esm/index.d.ts +8 -0
- package/lib/esm/index.js +9 -0
- package/lib/esm/shared/ClientSerializer.d.ts +52 -0
- package/lib/esm/shared/ClientSerializer.js +80 -0
- package/lib/esm/shared/DeterministicSerializer.d.ts +40 -0
- package/lib/esm/shared/DeterministicSerializer.js +50 -0
- package/lib/esm/shared/SimpleDeterministicSerializer.d.ts +7 -0
- package/lib/esm/shared/SimpleDeterministicSerializer.js +42 -0
- package/lib/esm/shared/constants.d.ts +39 -0
- package/lib/esm/shared/constants.js +42 -0
- package/lib/esm/shared/crypto.d.ts +107 -0
- package/lib/esm/shared/crypto.js +331 -0
- package/lib/esm/shared/decorators.d.ts +24 -0
- package/lib/esm/shared/decorators.js +98 -0
- package/lib/esm/shared/erc20/erc20-constants.d.ts +25 -0
- package/lib/esm/shared/erc20/erc20-constants.js +27 -0
- package/lib/esm/shared/errors.d.ts +116 -0
- package/lib/esm/shared/errors.js +132 -0
- package/lib/esm/shared/events.d.ts +39 -0
- package/lib/esm/shared/events.js +47 -0
- package/lib/esm/shared/fabric-types.d.ts +33 -0
- package/lib/esm/shared/fabric-types.js +2 -0
- package/lib/esm/shared/index.d.ts +13 -0
- package/lib/esm/shared/index.js +14 -0
- package/lib/esm/shared/interfaces/Checkable.d.ts +21 -0
- package/lib/esm/shared/interfaces/Checkable.js +2 -0
- package/lib/esm/shared/math.d.ts +34 -0
- package/lib/esm/shared/math.js +61 -0
- package/lib/esm/shared/model/Identity.d.ts +42 -0
- package/lib/esm/shared/model/Identity.js +78 -0
- package/lib/esm/shared/model/IdentityCredentials.d.ts +41 -0
- package/lib/esm/shared/model/IdentityCredentials.js +74 -0
- package/lib/esm/shared/model/index.d.ts +1 -0
- package/lib/esm/shared/model/index.js +2 -0
- package/lib/esm/shared/model/utils.d.ts +60 -0
- package/lib/esm/shared/model/utils.js +108 -0
- package/lib/esm/shared/types.d.ts +79 -0
- package/lib/esm/shared/types.js +2 -0
- package/lib/esm/shared/utils.d.ts +55 -0
- package/lib/esm/shared/utils.js +148 -0
- package/lib/index.cjs +25 -0
- package/lib/index.d.ts +8 -0
- package/lib/shared/ClientSerializer.cjs +84 -0
- package/lib/shared/ClientSerializer.d.ts +52 -0
- package/lib/shared/DeterministicSerializer.cjs +54 -0
- package/lib/shared/DeterministicSerializer.d.ts +40 -0
- package/lib/shared/SimpleDeterministicSerializer.cjs +46 -0
- package/lib/shared/SimpleDeterministicSerializer.d.ts +7 -0
- package/lib/shared/constants.cjs +45 -0
- package/lib/shared/constants.d.ts +39 -0
- package/lib/shared/crypto.cjs +369 -0
- package/lib/shared/crypto.d.ts +107 -0
- package/lib/shared/decorators.cjs +105 -0
- package/lib/shared/decorators.d.ts +24 -0
- package/lib/shared/erc20/erc20-constants.cjs +30 -0
- package/lib/shared/erc20/erc20-constants.d.ts +25 -0
- package/lib/shared/errors.cjs +142 -0
- package/lib/shared/errors.d.ts +116 -0
- package/lib/shared/events.cjs +51 -0
- package/lib/shared/events.d.ts +39 -0
- package/lib/shared/fabric-types.cjs +4 -0
- package/lib/shared/fabric-types.d.ts +33 -0
- package/lib/shared/index.cjs +30 -0
- package/lib/shared/index.d.ts +13 -0
- package/lib/shared/interfaces/Checkable.cjs +3 -0
- package/lib/shared/interfaces/Checkable.d.ts +21 -0
- package/lib/shared/math.cjs +66 -0
- package/lib/shared/math.d.ts +34 -0
- package/lib/shared/model/Identity.cjs +81 -0
- package/lib/shared/model/Identity.d.ts +42 -0
- package/lib/shared/model/IdentityCredentials.cjs +77 -0
- package/lib/shared/model/IdentityCredentials.d.ts +41 -0
- package/lib/shared/model/index.cjs +18 -0
- package/lib/shared/model/index.d.ts +1 -0
- package/lib/shared/model/utils.cjs +114 -0
- package/lib/shared/model/utils.d.ts +60 -0
- package/lib/shared/types.cjs +3 -0
- package/lib/shared/types.d.ts +79 -0
- package/lib/shared/utils.cjs +185 -0
- package/lib/shared/utils.d.ts +55 -0
- 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=
|