@decaf-ts/for-fabric 0.5.7 → 0.7.1
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/dist/for-fabric.cjs +2 -3797
- package/dist/for-fabric.cjs.map +1 -0
- package/dist/for-fabric.js +2 -3901
- package/dist/for-fabric.js.map +1 -0
- package/lib/cjs/bin/cli.cjs +9 -0
- package/lib/cjs/bin/cli.js.map +1 -0
- package/lib/cjs/cli-module.cjs +479 -0
- package/lib/cjs/cli-module.js.map +1 -0
- package/lib/cjs/cli-utils.cjs +309 -0
- package/lib/cjs/cli-utils.js.map +1 -0
- package/lib/cjs/client/FabricClientAdapter.cjs +1362 -0
- package/lib/cjs/client/FabricClientAdapter.js.map +1 -0
- package/lib/cjs/client/FabricClientDispatch.cjs +290 -0
- package/lib/cjs/client/FabricClientDispatch.js.map +1 -0
- package/lib/cjs/client/FabricClientPaginator.cjs +21 -0
- package/lib/cjs/client/FabricClientPaginator.js.map +1 -0
- package/lib/cjs/client/FabricClientRepository.cjs +259 -0
- package/lib/cjs/client/FabricClientRepository.js.map +1 -0
- package/lib/cjs/client/FabricClientStatement.cjs +451 -0
- package/lib/cjs/client/FabricClientStatement.js.map +1 -0
- package/lib/cjs/client/collections/generation.cjs +113 -0
- package/lib/cjs/client/collections/generation.js.map +1 -0
- package/lib/{client/indexes → cjs/client/collections}/index.cjs +1 -1
- package/lib/cjs/client/collections/index.js.map +1 -0
- package/lib/cjs/client/constants.cjs +16 -0
- package/lib/cjs/client/constants.js.map +1 -0
- package/lib/cjs/client/crypto.cjs +368 -0
- package/lib/cjs/client/crypto.js.map +1 -0
- package/lib/{esm/client/erc20/FabricERC20ClientRepository.d.ts → cjs/client/erc20/FabricERC20ClientRepository.cjs} +139 -30
- package/lib/cjs/client/erc20/FabricERC20ClientRepository.js.map +1 -0
- package/lib/{client → cjs/client}/erc20/index.cjs +1 -1
- package/lib/cjs/client/erc20/index.js.map +1 -0
- package/lib/cjs/client/fabric-fs.cjs +234 -0
- package/lib/cjs/client/fabric-fs.js.map +1 -0
- package/lib/cjs/client/fabric-hsm.cjs +165 -0
- package/lib/cjs/client/fabric-hsm.js.map +1 -0
- package/lib/cjs/client/ids/id-extraction.cjs +30 -0
- package/lib/cjs/client/ids/id-extraction.js.map +1 -0
- package/lib/{client → cjs/client}/ids/index.cjs +1 -1
- package/lib/cjs/client/ids/index.js.map +1 -0
- package/lib/{client → cjs/client}/index.cjs +1 -1
- package/lib/cjs/client/index.js.map +1 -0
- package/lib/cjs/client/indexes/generation.cjs +95 -0
- package/lib/cjs/client/indexes/generation.js.map +1 -0
- package/lib/{client/collections → cjs/client/indexes}/index.cjs +1 -1
- package/lib/cjs/client/indexes/index.js.map +1 -0
- package/lib/{esm/client/logging.d.ts → cjs/client/logging.cjs} +51 -9
- package/lib/cjs/client/logging.js.map +1 -0
- package/lib/cjs/client/services/FabricEnrollmentService.cjs +363 -0
- package/lib/cjs/client/services/FabricEnrollmentService.js.map +1 -0
- package/lib/cjs/client/services/FabricIdentityService.cjs +324 -0
- package/lib/cjs/client/services/FabricIdentityService.js.map +1 -0
- package/lib/cjs/client/services/RegistrationRequestBuilder.cjs +91 -0
- package/lib/cjs/client/services/RegistrationRequestBuilder.js.map +1 -0
- package/lib/{esm/client/services/constants.d.ts → cjs/client/services/constants.cjs} +10 -5
- package/lib/cjs/client/services/constants.js.map +1 -0
- package/lib/cjs/client/services/index.cjs +21 -0
- package/lib/cjs/client/services/index.js.map +1 -0
- package/lib/cjs/client/types.cjs +3 -0
- package/lib/cjs/client/types.js.map +1 -0
- package/lib/cjs/client/utils.cjs +262 -0
- package/lib/cjs/client/utils.js.map +1 -0
- package/lib/{contract → cjs/contract}/Address.cjs +1 -1
- package/lib/cjs/contract/Address.js.map +1 -0
- package/lib/{contract → cjs/contract}/AddressContract.cjs +1 -1
- package/lib/cjs/contract/AddressContract.js.map +1 -0
- package/lib/{contract → cjs/contract}/AuditContract.cjs +1 -1
- package/lib/cjs/contract/AuditContract.js.map +1 -0
- package/lib/{contract → cjs/contract}/BatchContract.cjs +1 -1
- package/lib/cjs/contract/BatchContract.js.map +1 -0
- package/lib/{contract → cjs/contract}/MarketContract.cjs +1 -1
- package/lib/cjs/contract/MarketContract.js.map +1 -0
- package/lib/{contract → cjs/contract}/OtherAuditContract.cjs +1 -1
- package/lib/cjs/contract/OtherAuditContract.js.map +1 -0
- package/lib/{contract → cjs/contract}/OtherBatchContract.cjs +1 -1
- package/lib/cjs/contract/OtherBatchContract.js.map +1 -0
- package/lib/{contract → cjs/contract}/OtherMarketContract.cjs +1 -1
- package/lib/cjs/contract/OtherMarketContract.js.map +1 -0
- package/lib/{contract → cjs/contract}/OtherProductContract.cjs +1 -1
- package/lib/cjs/contract/OtherProductContract.js.map +1 -0
- package/lib/{contract → cjs/contract}/OtherProductImageContract.cjs +1 -1
- package/lib/cjs/contract/OtherProductImageContract.js.map +1 -0
- package/lib/{contract → cjs/contract}/OtherProductSharedContract.cjs +1 -1
- package/lib/cjs/contract/OtherProductSharedContract.js.map +1 -0
- package/lib/{contract → cjs/contract}/OtherProductStrengthContract.cjs +1 -1
- package/lib/cjs/contract/OtherProductStrengthContract.js.map +1 -0
- package/lib/{contract → cjs/contract}/Product.cjs +1 -1
- package/lib/cjs/contract/Product.js.map +1 -0
- package/lib/{contract → cjs/contract}/ProductContract.cjs +1 -1
- package/lib/cjs/contract/ProductContract.js.map +1 -0
- package/lib/{contract → cjs/contract}/ProductStrengthContract.cjs +1 -1
- package/lib/cjs/contract/ProductStrengthContract.js.map +1 -0
- package/lib/{contract → cjs/contract}/SegregatedPrivateDocumentContract.cjs +1 -1
- package/lib/cjs/contract/SegregatedPrivateDocumentContract.js.map +1 -0
- package/lib/{contract → cjs/contract}/SegregatedSharedDocumentContract.cjs +1 -1
- package/lib/cjs/contract/SegregatedSharedDocumentContract.js.map +1 -0
- package/lib/{contract → cjs/contract}/User.cjs +1 -1
- package/lib/cjs/contract/User.js.map +1 -0
- package/lib/{contract → cjs/contract}/UserContract.cjs +1 -1
- package/lib/cjs/contract/UserContract.js.map +1 -0
- package/lib/cjs/contract/index.cjs +36 -0
- package/lib/cjs/contract/index.js.map +1 -0
- package/lib/cjs/contract/logging-context.cjs +77 -0
- package/lib/cjs/contract/logging-context.js.map +1 -0
- package/lib/cjs/contract/models/Audit.cjs +106 -0
- package/lib/cjs/contract/models/Audit.js.map +1 -0
- package/lib/{contract → cjs/contract}/models/BaseIdentifiedModel.cjs +1 -1
- package/lib/cjs/contract/models/BaseIdentifiedModel.js.map +1 -0
- package/lib/{contract → cjs/contract}/models/BaseModel.cjs +1 -1
- package/lib/cjs/contract/models/BaseModel.js.map +1 -0
- package/lib/cjs/contract/models/Batch.cjs +174 -0
- package/lib/cjs/contract/models/Batch.js.map +1 -0
- package/lib/cjs/contract/models/GtinOwner.cjs +59 -0
- package/lib/cjs/contract/models/GtinOwner.js.map +1 -0
- package/lib/cjs/contract/models/History.cjs +75 -0
- package/lib/cjs/contract/models/History.js.map +1 -0
- package/lib/cjs/contract/models/Leaflet.cjs +95 -0
- package/lib/cjs/contract/models/Leaflet.js.map +1 -0
- package/lib/cjs/contract/models/LeafletFile.cjs +58 -0
- package/lib/cjs/contract/models/LeafletFile.js.map +1 -0
- package/lib/cjs/contract/models/Market.cjs +75 -0
- package/lib/cjs/contract/models/Market.js.map +1 -0
- package/lib/cjs/contract/models/OtherAudit.cjs +118 -0
- package/lib/cjs/contract/models/OtherAudit.js.map +1 -0
- package/lib/cjs/contract/models/OtherBatchShared.cjs +127 -0
- package/lib/cjs/contract/models/OtherBatchShared.js.map +1 -0
- package/lib/cjs/contract/models/OtherLeaflet.cjs +115 -0
- package/lib/cjs/contract/models/OtherLeaflet.js.map +1 -0
- package/lib/cjs/contract/models/OtherLeafletFile.cjs +65 -0
- package/lib/cjs/contract/models/OtherLeafletFile.js.map +1 -0
- package/lib/cjs/contract/models/OtherMarket.cjs +84 -0
- package/lib/cjs/contract/models/OtherMarket.js.map +1 -0
- package/lib/cjs/contract/models/OtherProduct.cjs +77 -0
- package/lib/cjs/contract/models/OtherProduct.js.map +1 -0
- package/lib/cjs/contract/models/OtherProductImage.cjs +59 -0
- package/lib/cjs/contract/models/OtherProductImage.js.map +1 -0
- package/lib/cjs/contract/models/OtherProductShared.cjs +99 -0
- package/lib/cjs/contract/models/OtherProductShared.js.map +1 -0
- package/lib/cjs/contract/models/OtherProductStrength.cjs +87 -0
- package/lib/cjs/contract/models/OtherProductStrength.js.map +1 -0
- package/lib/cjs/contract/models/Product.cjs +78 -0
- package/lib/cjs/contract/models/Product.js.map +1 -0
- package/lib/cjs/contract/models/ProductStrength.cjs +78 -0
- package/lib/cjs/contract/models/ProductStrength.js.map +1 -0
- package/lib/{contract → cjs/contract}/models/SegregatedDocument.cjs +1 -1
- package/lib/cjs/contract/models/SegregatedDocument.js.map +1 -0
- package/lib/cjs/contract/models/constants.cjs +30 -0
- package/lib/cjs/contract/models/constants.js.map +1 -0
- package/lib/cjs/contract/models/decorators-private.cjs +158 -0
- package/lib/cjs/contract/models/decorators-private.js.map +1 -0
- package/lib/cjs/contract/models/decorators.cjs +182 -0
- package/lib/cjs/contract/models/decorators.js.map +1 -0
- package/lib/cjs/contract/models/gtin.cjs +88 -0
- package/lib/cjs/contract/models/gtin.js.map +1 -0
- package/lib/cjs/contract/models/history-dec.cjs +83 -0
- package/lib/cjs/contract/models/history-dec.js.map +1 -0
- package/lib/cjs/contracts/ContractAdapter.cjs +1193 -0
- package/lib/cjs/contracts/ContractAdapter.js.map +1 -0
- package/lib/cjs/contracts/ContractContext.cjs +157 -0
- package/lib/cjs/contracts/ContractContext.js.map +1 -0
- package/lib/cjs/contracts/FabricContractDispatch.cjs +79 -0
- package/lib/cjs/contracts/FabricContractDispatch.js.map +1 -0
- package/lib/{esm/contracts/FabricContractPaginator.d.ts → cjs/contracts/FabricContractPaginator.cjs} +77 -9
- package/lib/cjs/contracts/FabricContractPaginator.js.map +1 -0
- package/lib/cjs/contracts/FabricContractRepository.cjs +322 -0
- package/lib/cjs/contracts/FabricContractRepository.js.map +1 -0
- package/lib/{esm/contracts/FabricContractRepositoryObservableHandler.d.ts → cjs/contracts/FabricContractRepositoryObservableHandler.cjs} +42 -8
- package/lib/cjs/contracts/FabricContractRepositoryObservableHandler.js.map +1 -0
- package/lib/cjs/contracts/FabricContractSequence.cjs +338 -0
- package/lib/cjs/contracts/FabricContractSequence.js.map +1 -0
- package/lib/cjs/contracts/FabricContractStatement.cjs +180 -0
- package/lib/cjs/contracts/FabricContractStatement.js.map +1 -0
- package/lib/cjs/contracts/MigrationContract.cjs +147 -0
- package/lib/cjs/contracts/MigrationContract.js.map +1 -0
- package/lib/{contracts → cjs/contracts}/PrivateSequence.cjs +1 -1
- package/lib/cjs/contracts/PrivateSequence.js.map +1 -0
- package/lib/cjs/contracts/auth/decorators.cjs +84 -0
- package/lib/cjs/contracts/auth/decorators.js.map +1 -0
- package/lib/{contracts → cjs/contracts}/auth/index.cjs +1 -1
- package/lib/cjs/contracts/auth/index.js.map +1 -0
- package/lib/cjs/contracts/crud/crud-contract.cjs +416 -0
- package/lib/cjs/contracts/crud/crud-contract.js.map +1 -0
- package/lib/{contracts → cjs/contracts}/crud/index.cjs +1 -1
- package/lib/cjs/contracts/crud/index.js.map +1 -0
- package/lib/cjs/contracts/crud/serialized-crud-contract.cjs +284 -0
- package/lib/cjs/contracts/crud/serialized-crud-contract.js.map +1 -0
- package/lib/cjs/contracts/erc20/erc20contract.cjs +581 -0
- package/lib/cjs/contracts/erc20/erc20contract.js.map +1 -0
- package/lib/cjs/contracts/erc20/index.cjs +21 -0
- package/lib/cjs/contracts/erc20/index.js.map +1 -0
- package/lib/cjs/contracts/erc20/models.cjs +209 -0
- package/lib/cjs/contracts/erc20/models.js.map +1 -0
- package/lib/{contracts → cjs/contracts}/index.cjs +1 -1
- package/lib/cjs/contracts/index.js.map +1 -0
- package/lib/cjs/contracts/logging.cjs +118 -0
- package/lib/cjs/contracts/logging.js.map +1 -0
- package/lib/cjs/contracts/overrides.cjs +8 -0
- package/lib/cjs/contracts/overrides.js.map +1 -0
- package/lib/cjs/contracts/types.cjs +3 -0
- package/lib/cjs/contracts/types.js.map +1 -0
- package/lib/cjs/contracts/uuid.cjs +75 -0
- package/lib/cjs/contracts/uuid.js.map +1 -0
- package/lib/{index.cjs → cjs/index.cjs} +1 -1
- package/lib/cjs/index.js.map +1 -0
- package/lib/{shared/ClientSerializer.d.ts → cjs/shared/ClientSerializer.cjs} +35 -6
- package/lib/cjs/shared/ClientSerializer.js.map +1 -0
- package/lib/cjs/shared/DeterministicSerializer.cjs +106 -0
- package/lib/cjs/shared/DeterministicSerializer.js.map +1 -0
- package/lib/cjs/shared/SimpleDeterministicSerializer.cjs +69 -0
- package/lib/cjs/shared/SimpleDeterministicSerializer.js.map +1 -0
- package/lib/{shared/constants.d.ts → cjs/shared/constants.cjs} +18 -12
- package/lib/cjs/shared/constants.js.map +1 -0
- package/lib/cjs/shared/decorators.cjs +595 -0
- package/lib/cjs/shared/decorators.js.map +1 -0
- package/lib/{shared/erc20/erc20-constants.d.ts → cjs/shared/erc20/erc20-constants.cjs} +9 -4
- package/lib/cjs/shared/erc20/erc20-constants.js.map +1 -0
- package/lib/{shared → cjs/shared}/erc20/index.cjs +1 -1
- package/lib/cjs/shared/erc20/index.js.map +1 -0
- package/lib/cjs/shared/errors.cjs +190 -0
- package/lib/cjs/shared/errors.js.map +1 -0
- package/lib/{shared/events.d.ts → cjs/shared/events.cjs} +21 -7
- package/lib/cjs/shared/events.js.map +1 -0
- package/lib/cjs/shared/fabric-types.cjs +3 -0
- package/lib/cjs/shared/fabric-types.js.map +1 -0
- package/lib/{shared → cjs/shared}/index.cjs +1 -1
- package/lib/cjs/shared/index.js.map +1 -0
- package/lib/cjs/shared/interfaces/Checkable.cjs +3 -0
- package/lib/cjs/shared/interfaces/Checkable.js.map +1 -0
- package/lib/{shared → cjs/shared}/interfaces/index.cjs +1 -1
- package/lib/cjs/shared/interfaces/index.js.map +1 -0
- package/lib/cjs/shared/math.cjs +66 -0
- package/lib/cjs/shared/math.js.map +1 -0
- package/lib/{shared → cjs/shared}/model/FabricBaseModel.cjs +1 -1
- package/lib/cjs/shared/model/FabricBaseModel.js.map +1 -0
- package/lib/{shared → cjs/shared}/model/FabricIdentifiedBaseModel.cjs +1 -1
- package/lib/cjs/shared/model/FabricIdentifiedBaseModel.js.map +1 -0
- package/lib/cjs/shared/model/Identity.cjs +71 -0
- package/lib/cjs/shared/model/Identity.js.map +1 -0
- package/lib/cjs/shared/model/IdentityCredentials.cjs +66 -0
- package/lib/cjs/shared/model/IdentityCredentials.js.map +1 -0
- package/lib/cjs/shared/model/index.cjs +21 -0
- package/lib/cjs/shared/model/index.js.map +1 -0
- package/lib/cjs/shared/overrides/Model.cjs +4 -0
- package/lib/cjs/shared/overrides/Model.js.map +1 -0
- package/lib/{shared → cjs/shared}/overrides/index.cjs +1 -1
- package/lib/cjs/shared/overrides/index.js.map +1 -0
- package/lib/cjs/shared/overrides/overrides.cjs +93 -0
- package/lib/cjs/shared/overrides/overrides.js.map +1 -0
- package/lib/cjs/shared/types.cjs +3 -0
- package/lib/cjs/shared/types.js.map +1 -0
- package/lib/cjs/version.cjs +8 -0
- package/lib/cjs/version.js.map +1 -0
- package/lib/esm/bin/cli.js +1 -1
- package/lib/esm/bin/cli.js.map +1 -0
- package/lib/esm/cli-module.js +1 -1
- package/lib/esm/cli-module.js.map +1 -0
- package/lib/esm/cli-utils.js +1 -1
- package/lib/esm/cli-utils.js.map +1 -0
- package/lib/esm/client/FabricClientAdapter.js +1 -1
- package/lib/esm/client/FabricClientAdapter.js.map +1 -0
- package/lib/esm/client/FabricClientDispatch.js +1 -1
- package/lib/esm/client/FabricClientDispatch.js.map +1 -0
- package/lib/esm/client/FabricClientPaginator.js +1 -1
- package/lib/esm/client/FabricClientPaginator.js.map +1 -0
- package/lib/esm/client/FabricClientRepository.js +1 -1
- package/lib/esm/client/FabricClientRepository.js.map +1 -0
- package/lib/esm/client/FabricClientStatement.js +1 -1
- package/lib/esm/client/FabricClientStatement.js.map +1 -0
- package/lib/esm/client/collections/generation.js +1 -1
- package/lib/esm/client/collections/generation.js.map +1 -0
- package/lib/esm/client/collections/index.js +1 -1
- package/lib/esm/client/collections/index.js.map +1 -0
- package/lib/esm/client/constants.js +1 -1
- package/lib/esm/client/constants.js.map +1 -0
- package/lib/esm/client/crypto.js +1 -1
- package/lib/esm/client/crypto.js.map +1 -0
- package/lib/esm/client/erc20/FabricERC20ClientRepository.js +1 -1
- package/lib/esm/client/erc20/FabricERC20ClientRepository.js.map +1 -0
- package/lib/esm/client/erc20/index.js +1 -1
- package/lib/esm/client/erc20/index.js.map +1 -0
- package/lib/esm/client/fabric-fs.js +1 -1
- package/lib/esm/client/fabric-fs.js.map +1 -0
- package/lib/esm/client/fabric-hsm.js +1 -1
- package/lib/esm/client/fabric-hsm.js.map +1 -0
- package/lib/esm/client/ids/id-extraction.js +1 -1
- package/lib/esm/client/ids/id-extraction.js.map +1 -0
- package/lib/esm/client/ids/index.js +1 -1
- package/lib/esm/client/ids/index.js.map +1 -0
- package/lib/esm/client/index.js +1 -1
- package/lib/esm/client/index.js.map +1 -0
- package/lib/esm/client/indexes/generation.js +1 -1
- package/lib/esm/client/indexes/generation.js.map +1 -0
- package/lib/esm/client/indexes/index.js +1 -1
- package/lib/esm/client/indexes/index.js.map +1 -0
- package/lib/esm/client/logging.js +1 -1
- package/lib/esm/client/logging.js.map +1 -0
- package/lib/esm/client/services/FabricEnrollmentService.js +1 -1
- package/lib/esm/client/services/FabricEnrollmentService.js.map +1 -0
- package/lib/esm/client/services/FabricIdentityService.js +1 -1
- package/lib/esm/client/services/FabricIdentityService.js.map +1 -0
- package/lib/esm/client/services/RegistrationRequestBuilder.js +1 -1
- package/lib/esm/client/services/RegistrationRequestBuilder.js.map +1 -0
- package/lib/esm/client/services/constants.js +1 -1
- package/lib/esm/client/services/constants.js.map +1 -0
- package/lib/esm/client/services/index.js +1 -1
- package/lib/esm/client/services/index.js.map +1 -0
- package/lib/esm/client/types.js +1 -1
- package/lib/esm/client/types.js.map +1 -0
- package/lib/esm/client/utils.js +1 -1
- package/lib/esm/client/utils.js.map +1 -0
- package/lib/esm/contract/Address.js +1 -1
- package/lib/esm/contract/Address.js.map +1 -0
- package/lib/esm/contract/AddressContract.js +1 -1
- package/lib/esm/contract/AddressContract.js.map +1 -0
- package/lib/esm/contract/AuditContract.js +1 -1
- package/lib/esm/contract/AuditContract.js.map +1 -0
- package/lib/esm/contract/BatchContract.js +1 -1
- package/lib/esm/contract/BatchContract.js.map +1 -0
- package/lib/esm/contract/MarketContract.js +1 -1
- package/lib/esm/contract/MarketContract.js.map +1 -0
- package/lib/esm/contract/OtherAuditContract.js +1 -1
- package/lib/esm/contract/OtherAuditContract.js.map +1 -0
- package/lib/esm/contract/OtherBatchContract.js +1 -1
- package/lib/esm/contract/OtherBatchContract.js.map +1 -0
- package/lib/esm/contract/OtherMarketContract.js +1 -1
- package/lib/esm/contract/OtherMarketContract.js.map +1 -0
- package/lib/esm/contract/OtherProductContract.js +1 -1
- package/lib/esm/contract/OtherProductContract.js.map +1 -0
- package/lib/esm/contract/OtherProductImageContract.js +1 -1
- package/lib/esm/contract/OtherProductImageContract.js.map +1 -0
- package/lib/esm/contract/OtherProductSharedContract.js +1 -1
- package/lib/esm/contract/OtherProductSharedContract.js.map +1 -0
- package/lib/esm/contract/OtherProductStrengthContract.js +1 -1
- package/lib/esm/contract/OtherProductStrengthContract.js.map +1 -0
- package/lib/esm/contract/Product.js +1 -1
- package/lib/esm/contract/Product.js.map +1 -0
- package/lib/esm/contract/ProductContract.js +1 -1
- package/lib/esm/contract/ProductContract.js.map +1 -0
- package/lib/esm/contract/ProductStrengthContract.js +1 -1
- package/lib/esm/contract/ProductStrengthContract.js.map +1 -0
- package/lib/esm/contract/SegregatedPrivateDocumentContract.js +1 -1
- package/lib/esm/contract/SegregatedPrivateDocumentContract.js.map +1 -0
- package/lib/esm/contract/SegregatedSharedDocumentContract.js +1 -1
- package/lib/esm/contract/SegregatedSharedDocumentContract.js.map +1 -0
- package/lib/esm/contract/User.js +1 -1
- package/lib/esm/contract/User.js.map +1 -0
- package/lib/esm/contract/UserContract.js +1 -1
- package/lib/esm/contract/UserContract.js.map +1 -0
- package/lib/esm/contract/index.js +1 -1
- package/lib/esm/contract/index.js.map +1 -0
- package/lib/esm/contract/logging-context.js +1 -1
- package/lib/esm/contract/logging-context.js.map +1 -0
- package/lib/esm/contract/models/Audit.js +1 -1
- package/lib/esm/contract/models/Audit.js.map +1 -0
- package/lib/esm/contract/models/BaseIdentifiedModel.js +1 -1
- package/lib/esm/contract/models/BaseIdentifiedModel.js.map +1 -0
- package/lib/esm/contract/models/BaseModel.js +1 -1
- package/lib/esm/contract/models/BaseModel.js.map +1 -0
- package/lib/esm/contract/models/Batch.js +1 -1
- package/lib/esm/contract/models/Batch.js.map +1 -0
- package/lib/esm/contract/models/GtinOwner.js +1 -1
- package/lib/esm/contract/models/GtinOwner.js.map +1 -0
- package/lib/esm/contract/models/History.js +1 -1
- package/lib/esm/contract/models/History.js.map +1 -0
- package/lib/esm/contract/models/Leaflet.js +1 -1
- package/lib/esm/contract/models/Leaflet.js.map +1 -0
- package/lib/esm/contract/models/LeafletFile.js +1 -1
- package/lib/esm/contract/models/LeafletFile.js.map +1 -0
- package/lib/esm/contract/models/Market.js +1 -1
- package/lib/esm/contract/models/Market.js.map +1 -0
- package/lib/esm/contract/models/OtherAudit.js +1 -1
- package/lib/esm/contract/models/OtherAudit.js.map +1 -0
- package/lib/esm/contract/models/OtherBatchShared.js +1 -1
- package/lib/esm/contract/models/OtherBatchShared.js.map +1 -0
- package/lib/esm/contract/models/OtherLeaflet.js +1 -1
- package/lib/esm/contract/models/OtherLeaflet.js.map +1 -0
- package/lib/esm/contract/models/OtherLeafletFile.js +1 -1
- package/lib/esm/contract/models/OtherLeafletFile.js.map +1 -0
- package/lib/esm/contract/models/OtherMarket.js +1 -1
- package/lib/esm/contract/models/OtherMarket.js.map +1 -0
- package/lib/esm/contract/models/OtherProduct.js +1 -1
- package/lib/esm/contract/models/OtherProduct.js.map +1 -0
- package/lib/esm/contract/models/OtherProductImage.js +1 -1
- package/lib/esm/contract/models/OtherProductImage.js.map +1 -0
- package/lib/esm/contract/models/OtherProductShared.js +1 -1
- package/lib/esm/contract/models/OtherProductShared.js.map +1 -0
- package/lib/esm/contract/models/OtherProductStrength.js +1 -1
- package/lib/esm/contract/models/OtherProductStrength.js.map +1 -0
- package/lib/esm/contract/models/Product.js +1 -1
- package/lib/esm/contract/models/Product.js.map +1 -0
- package/lib/esm/contract/models/ProductStrength.js +1 -1
- package/lib/esm/contract/models/ProductStrength.js.map +1 -0
- package/lib/esm/contract/models/SegregatedDocument.js +1 -1
- package/lib/esm/contract/models/SegregatedDocument.js.map +1 -0
- package/lib/esm/contract/models/constants.js +1 -1
- package/lib/esm/contract/models/constants.js.map +1 -0
- package/lib/esm/contract/models/decorators-private.js +1 -1
- package/lib/esm/contract/models/decorators-private.js.map +1 -0
- package/lib/esm/contract/models/decorators.js +1 -1
- package/lib/esm/contract/models/decorators.js.map +1 -0
- package/lib/esm/contract/models/gtin.js +1 -1
- package/lib/esm/contract/models/gtin.js.map +1 -0
- package/lib/esm/contract/models/history-dec.js +1 -1
- package/lib/esm/contract/models/history-dec.js.map +1 -0
- package/lib/esm/contracts/ContractAdapter.js +1 -1
- package/lib/esm/contracts/ContractAdapter.js.map +1 -0
- package/lib/esm/contracts/ContractContext.js +1 -1
- package/lib/esm/contracts/ContractContext.js.map +1 -0
- package/lib/esm/contracts/FabricContractDispatch.js +1 -1
- package/lib/esm/contracts/FabricContractDispatch.js.map +1 -0
- package/lib/esm/contracts/FabricContractPaginator.js +1 -1
- package/lib/esm/contracts/FabricContractPaginator.js.map +1 -0
- package/lib/esm/contracts/FabricContractRepository.js +1 -1
- package/lib/esm/contracts/FabricContractRepository.js.map +1 -0
- package/lib/esm/contracts/FabricContractRepositoryObservableHandler.js +1 -1
- package/lib/esm/contracts/FabricContractRepositoryObservableHandler.js.map +1 -0
- package/lib/esm/contracts/FabricContractSequence.js +1 -1
- package/lib/esm/contracts/FabricContractSequence.js.map +1 -0
- package/lib/esm/contracts/FabricContractStatement.js +1 -1
- package/lib/esm/contracts/FabricContractStatement.js.map +1 -0
- package/lib/esm/contracts/MigrationContract.js +1 -1
- package/lib/esm/contracts/MigrationContract.js.map +1 -0
- package/lib/esm/contracts/PrivateSequence.js +1 -1
- package/lib/esm/contracts/PrivateSequence.js.map +1 -0
- package/lib/esm/contracts/auth/decorators.js +1 -1
- package/lib/esm/contracts/auth/decorators.js.map +1 -0
- package/lib/esm/contracts/auth/index.js +1 -1
- package/lib/esm/contracts/auth/index.js.map +1 -0
- package/lib/esm/contracts/crud/crud-contract.js +1 -1
- package/lib/esm/contracts/crud/crud-contract.js.map +1 -0
- package/lib/esm/contracts/crud/index.js +1 -1
- package/lib/esm/contracts/crud/index.js.map +1 -0
- package/lib/esm/contracts/crud/serialized-crud-contract.js +1 -1
- package/lib/esm/contracts/crud/serialized-crud-contract.js.map +1 -0
- package/lib/esm/contracts/erc20/erc20contract.js +1 -1
- package/lib/esm/contracts/erc20/erc20contract.js.map +1 -0
- package/lib/esm/contracts/erc20/index.js +1 -1
- package/lib/esm/contracts/erc20/index.js.map +1 -0
- package/lib/esm/contracts/erc20/models.js +1 -1
- package/lib/esm/contracts/erc20/models.js.map +1 -0
- package/lib/esm/contracts/index.js +1 -1
- package/lib/esm/contracts/index.js.map +1 -0
- package/lib/esm/contracts/logging.js +1 -1
- package/lib/esm/contracts/logging.js.map +1 -0
- package/lib/esm/contracts/overrides.js +1 -1
- package/lib/esm/contracts/overrides.js.map +1 -0
- package/lib/esm/contracts/types.js +1 -1
- package/lib/esm/contracts/types.js.map +1 -0
- package/lib/esm/contracts/uuid.js +1 -1
- package/lib/esm/contracts/uuid.js.map +1 -0
- package/lib/esm/index.js +1 -1
- package/lib/esm/index.js.map +1 -0
- package/lib/esm/shared/ClientSerializer.js +1 -1
- package/lib/esm/shared/ClientSerializer.js.map +1 -0
- package/lib/esm/shared/DeterministicSerializer.js +1 -1
- package/lib/esm/shared/DeterministicSerializer.js.map +1 -0
- package/lib/esm/shared/SimpleDeterministicSerializer.js +1 -1
- package/lib/esm/shared/SimpleDeterministicSerializer.js.map +1 -0
- package/lib/esm/shared/constants.js +1 -1
- package/lib/esm/shared/constants.js.map +1 -0
- package/lib/esm/shared/decorators.js +1 -1
- package/lib/esm/shared/decorators.js.map +1 -0
- package/lib/esm/shared/erc20/erc20-constants.js +1 -1
- package/lib/esm/shared/erc20/erc20-constants.js.map +1 -0
- package/lib/esm/shared/erc20/index.js +1 -1
- package/lib/esm/shared/erc20/index.js.map +1 -0
- package/lib/esm/shared/errors.js +1 -1
- package/lib/esm/shared/errors.js.map +1 -0
- package/lib/esm/shared/events.js +1 -1
- package/lib/esm/shared/events.js.map +1 -0
- package/lib/esm/shared/fabric-types.js +1 -1
- package/lib/esm/shared/fabric-types.js.map +1 -0
- package/lib/esm/shared/index.js +1 -1
- package/lib/esm/shared/index.js.map +1 -0
- package/lib/esm/shared/interfaces/Checkable.js +1 -1
- package/lib/esm/shared/interfaces/Checkable.js.map +1 -0
- package/lib/esm/shared/interfaces/index.js +1 -1
- package/lib/esm/shared/interfaces/index.js.map +1 -0
- package/lib/esm/shared/math.js +1 -1
- package/lib/esm/shared/math.js.map +1 -0
- package/lib/esm/shared/model/FabricBaseModel.js +1 -1
- package/lib/esm/shared/model/FabricBaseModel.js.map +1 -0
- package/lib/esm/shared/model/FabricIdentifiedBaseModel.js +1 -1
- package/lib/esm/shared/model/FabricIdentifiedBaseModel.js.map +1 -0
- package/lib/esm/shared/model/Identity.js +1 -1
- package/lib/esm/shared/model/Identity.js.map +1 -0
- package/lib/esm/shared/model/IdentityCredentials.js +1 -1
- package/lib/esm/shared/model/IdentityCredentials.js.map +1 -0
- package/lib/esm/shared/model/index.js +1 -1
- package/lib/esm/shared/model/index.js.map +1 -0
- package/lib/esm/shared/overrides/Model.js +1 -1
- package/lib/esm/shared/overrides/Model.js.map +1 -0
- package/lib/esm/shared/overrides/index.js +1 -1
- package/lib/esm/shared/overrides/index.js.map +1 -0
- package/lib/esm/shared/overrides/overrides.js +1 -1
- package/lib/esm/shared/overrides/overrides.js.map +1 -0
- package/lib/esm/shared/types.js +1 -1
- package/lib/esm/shared/types.js.map +1 -0
- package/lib/esm/version.js +2 -2
- package/lib/esm/version.js.map +1 -0
- package/lib/{esm → types}/version.d.ts +1 -1
- package/package.json +22 -18
- package/lib/bin/cli.cjs +0 -9
- package/lib/cli-module.cjs +0 -479
- package/lib/cli-utils.cjs +0 -309
- package/lib/client/FabricClientAdapter.cjs +0 -1362
- package/lib/client/FabricClientDispatch.cjs +0 -290
- package/lib/client/FabricClientPaginator.cjs +0 -21
- package/lib/client/FabricClientRepository.cjs +0 -259
- package/lib/client/FabricClientStatement.cjs +0 -451
- package/lib/client/collections/generation.cjs +0 -113
- package/lib/client/constants.cjs +0 -16
- package/lib/client/crypto.cjs +0 -368
- package/lib/client/erc20/FabricERC20ClientRepository.cjs +0 -363
- package/lib/client/fabric-fs.cjs +0 -234
- package/lib/client/fabric-hsm.cjs +0 -165
- package/lib/client/ids/id-extraction.cjs +0 -30
- package/lib/client/indexes/generation.cjs +0 -95
- package/lib/client/logging.cjs +0 -102
- package/lib/client/services/FabricEnrollmentService.cjs +0 -363
- package/lib/client/services/FabricIdentityService.cjs +0 -324
- package/lib/client/services/RegistrationRequestBuilder.cjs +0 -91
- package/lib/client/services/constants.cjs +0 -20
- package/lib/client/services/index.cjs +0 -21
- package/lib/client/types.cjs +0 -3
- package/lib/client/utils.cjs +0 -262
- package/lib/contract/index.cjs +0 -36
- package/lib/contract/logging-context.cjs +0 -77
- package/lib/contract/models/Audit.cjs +0 -106
- package/lib/contract/models/Batch.cjs +0 -174
- package/lib/contract/models/GtinOwner.cjs +0 -59
- package/lib/contract/models/History.cjs +0 -75
- package/lib/contract/models/Leaflet.cjs +0 -95
- package/lib/contract/models/LeafletFile.cjs +0 -58
- package/lib/contract/models/Market.cjs +0 -75
- package/lib/contract/models/OtherAudit.cjs +0 -118
- package/lib/contract/models/OtherBatchShared.cjs +0 -127
- package/lib/contract/models/OtherLeaflet.cjs +0 -115
- package/lib/contract/models/OtherLeafletFile.cjs +0 -65
- package/lib/contract/models/OtherMarket.cjs +0 -84
- package/lib/contract/models/OtherProduct.cjs +0 -77
- package/lib/contract/models/OtherProductImage.cjs +0 -59
- package/lib/contract/models/OtherProductShared.cjs +0 -99
- package/lib/contract/models/OtherProductStrength.cjs +0 -87
- package/lib/contract/models/Product.cjs +0 -78
- package/lib/contract/models/ProductStrength.cjs +0 -78
- package/lib/contract/models/constants.cjs +0 -30
- package/lib/contract/models/decorators-private.cjs +0 -158
- package/lib/contract/models/decorators.cjs +0 -182
- package/lib/contract/models/gtin.cjs +0 -88
- package/lib/contract/models/history-dec.cjs +0 -83
- package/lib/contracts/ContractAdapter.cjs +0 -1193
- package/lib/contracts/ContractContext.cjs +0 -157
- package/lib/contracts/FabricContractDispatch.cjs +0 -79
- package/lib/contracts/FabricContractPaginator.cjs +0 -173
- package/lib/contracts/FabricContractRepository.cjs +0 -322
- package/lib/contracts/FabricContractRepositoryObservableHandler.cjs +0 -96
- package/lib/contracts/FabricContractSequence.cjs +0 -338
- package/lib/contracts/FabricContractStatement.cjs +0 -180
- package/lib/contracts/MigrationContract.cjs +0 -147
- package/lib/contracts/auth/decorators.cjs +0 -84
- package/lib/contracts/crud/crud-contract.cjs +0 -416
- package/lib/contracts/crud/serialized-crud-contract.cjs +0 -284
- package/lib/contracts/erc20/erc20contract.cjs +0 -581
- package/lib/contracts/erc20/index.cjs +0 -21
- package/lib/contracts/erc20/models.cjs +0 -209
- package/lib/contracts/logging.cjs +0 -118
- package/lib/contracts/overrides.cjs +0 -8
- package/lib/contracts/types.cjs +0 -3
- package/lib/contracts/uuid.cjs +0 -75
- package/lib/esm/bin/cli.d.ts +0 -1
- package/lib/esm/cli-module.d.ts +0 -3
- package/lib/esm/cli-utils.d.ts +0 -21
- package/lib/esm/client/FabricClientAdapter.d.ts +0 -404
- package/lib/esm/client/FabricClientDispatch.d.ts +0 -133
- package/lib/esm/client/FabricClientPaginator.d.ts +0 -12
- package/lib/esm/client/FabricClientRepository.d.ts +0 -71
- package/lib/esm/client/FabricClientStatement.d.ts +0 -64
- package/lib/esm/client/collections/generation.d.ts +0 -46
- package/lib/esm/client/collections/index.d.ts +0 -1
- package/lib/esm/client/constants.d.ts +0 -2
- package/lib/esm/client/crypto.d.ts +0 -107
- package/lib/esm/client/erc20/index.d.ts +0 -1
- package/lib/esm/client/fabric-fs.d.ts +0 -92
- package/lib/esm/client/fabric-hsm.d.ts +0 -24
- package/lib/esm/client/ids/id-extraction.d.ts +0 -4
- package/lib/esm/client/ids/index.d.ts +0 -1
- package/lib/esm/client/index.d.ts +0 -23
- package/lib/esm/client/indexes/generation.d.ts +0 -10
- package/lib/esm/client/indexes/index.d.ts +0 -1
- package/lib/esm/client/services/FabricEnrollmentService.d.ts +0 -176
- package/lib/esm/client/services/FabricIdentityService.d.ts +0 -98
- package/lib/esm/client/services/RegistrationRequestBuilder.d.ts +0 -19
- package/lib/esm/client/services/index.d.ts +0 -4
- package/lib/esm/client/types.d.ts +0 -20
- package/lib/esm/client/utils.d.ts +0 -71
- package/lib/esm/contract/Address.d.ts +0 -13
- package/lib/esm/contract/AddressContract.d.ts +0 -5
- package/lib/esm/contract/AuditContract.d.ts +0 -5
- package/lib/esm/contract/BatchContract.d.ts +0 -5
- package/lib/esm/contract/MarketContract.d.ts +0 -5
- package/lib/esm/contract/OtherAuditContract.d.ts +0 -5
- package/lib/esm/contract/OtherBatchContract.d.ts +0 -5
- package/lib/esm/contract/OtherMarketContract.d.ts +0 -5
- package/lib/esm/contract/OtherProductContract.d.ts +0 -5
- package/lib/esm/contract/OtherProductImageContract.d.ts +0 -5
- package/lib/esm/contract/OtherProductSharedContract.d.ts +0 -5
- package/lib/esm/contract/OtherProductStrengthContract.d.ts +0 -5
- package/lib/esm/contract/Product.d.ts +0 -7
- package/lib/esm/contract/ProductContract.d.ts +0 -5
- package/lib/esm/contract/ProductStrengthContract.d.ts +0 -5
- package/lib/esm/contract/SegregatedPrivateDocumentContract.d.ts +0 -5
- package/lib/esm/contract/SegregatedSharedDocumentContract.d.ts +0 -5
- package/lib/esm/contract/User.d.ts +0 -7
- package/lib/esm/contract/UserContract.d.ts +0 -5
- package/lib/esm/contract/index.d.ts +0 -2
- package/lib/esm/contract/logging-context.d.ts +0 -8
- package/lib/esm/contract/models/Audit.d.ts +0 -13
- package/lib/esm/contract/models/BaseIdentifiedModel.d.ts +0 -7
- package/lib/esm/contract/models/BaseModel.d.ts +0 -7
- package/lib/esm/contract/models/Batch.d.ts +0 -18
- package/lib/esm/contract/models/GtinOwner.d.ts +0 -8
- package/lib/esm/contract/models/History.d.ts +0 -9
- package/lib/esm/contract/models/Leaflet.d.ts +0 -12
- package/lib/esm/contract/models/LeafletFile.d.ts +0 -9
- package/lib/esm/contract/models/Market.d.ts +0 -12
- package/lib/esm/contract/models/OtherAudit.d.ts +0 -15
- package/lib/esm/contract/models/OtherBatchShared.d.ts +0 -18
- package/lib/esm/contract/models/OtherLeaflet.d.ts +0 -16
- package/lib/esm/contract/models/OtherLeafletFile.d.ts +0 -10
- package/lib/esm/contract/models/OtherMarket.d.ts +0 -13
- package/lib/esm/contract/models/OtherProduct.d.ts +0 -12
- package/lib/esm/contract/models/OtherProductImage.d.ts +0 -9
- package/lib/esm/contract/models/OtherProductShared.d.ts +0 -18
- package/lib/esm/contract/models/OtherProductStrength.d.ts +0 -12
- package/lib/esm/contract/models/Product.d.ts +0 -15
- package/lib/esm/contract/models/ProductStrength.d.ts +0 -11
- package/lib/esm/contract/models/SegregatedDocument.d.ts +0 -18
- package/lib/esm/contract/models/constants.d.ts +0 -24
- package/lib/esm/contract/models/decorators-private.d.ts +0 -16
- package/lib/esm/contract/models/decorators.d.ts +0 -28
- package/lib/esm/contract/models/gtin.d.ts +0 -8
- package/lib/esm/contract/models/history-dec.d.ts +0 -6
- package/lib/esm/contracts/ContractAdapter.d.ts +0 -287
- package/lib/esm/contracts/ContractContext.d.ts +0 -89
- package/lib/esm/contracts/FabricContractDispatch.d.ts +0 -7
- package/lib/esm/contracts/FabricContractRepository.d.ts +0 -119
- package/lib/esm/contracts/FabricContractSequence.d.ts +0 -87
- package/lib/esm/contracts/FabricContractStatement.d.ts +0 -36
- package/lib/esm/contracts/MigrationContract.d.ts +0 -22
- package/lib/esm/contracts/PrivateSequence.d.ts +0 -15
- package/lib/esm/contracts/auth/decorators.d.ts +0 -6
- package/lib/esm/contracts/auth/index.d.ts +0 -1
- package/lib/esm/contracts/crud/crud-contract.d.ts +0 -199
- package/lib/esm/contracts/crud/index.d.ts +0 -2
- package/lib/esm/contracts/crud/serialized-crud-contract.d.ts +0 -42
- package/lib/esm/contracts/erc20/erc20contract.d.ts +0 -152
- package/lib/esm/contracts/erc20/index.d.ts +0 -2
- package/lib/esm/contracts/erc20/models.d.ts +0 -114
- package/lib/esm/contracts/index.d.ts +0 -19
- package/lib/esm/contracts/logging.d.ts +0 -54
- package/lib/esm/contracts/types.d.ts +0 -38
- package/lib/esm/contracts/uuid.d.ts +0 -2
- package/lib/esm/shared/overrides/overrides.d.ts +0 -1
- package/lib/index.d.ts +0 -8
- package/lib/shared/ClientSerializer.cjs +0 -81
- package/lib/shared/DeterministicSerializer.cjs +0 -106
- package/lib/shared/DeterministicSerializer.d.ts +0 -47
- package/lib/shared/SimpleDeterministicSerializer.cjs +0 -69
- package/lib/shared/SimpleDeterministicSerializer.d.ts +0 -7
- package/lib/shared/constants.cjs +0 -41
- package/lib/shared/decorators.cjs +0 -595
- package/lib/shared/decorators.d.ts +0 -81
- package/lib/shared/erc20/erc20-constants.cjs +0 -30
- package/lib/shared/erc20/index.d.ts +0 -1
- package/lib/shared/errors.cjs +0 -190
- package/lib/shared/errors.d.ts +0 -140
- package/lib/shared/events.cjs +0 -51
- package/lib/shared/fabric-types.cjs +0 -3
- package/lib/shared/fabric-types.d.ts +0 -32
- package/lib/shared/index.d.ts +0 -20
- package/lib/shared/interfaces/Checkable.cjs +0 -3
- package/lib/shared/interfaces/Checkable.d.ts +0 -23
- package/lib/shared/interfaces/index.d.ts +0 -1
- package/lib/shared/math.cjs +0 -66
- package/lib/shared/math.d.ts +0 -34
- package/lib/shared/model/FabricBaseModel.d.ts +0 -7
- package/lib/shared/model/FabricIdentifiedBaseModel.d.ts +0 -7
- package/lib/shared/model/Identity.cjs +0 -71
- package/lib/shared/model/Identity.d.ts +0 -42
- package/lib/shared/model/IdentityCredentials.cjs +0 -66
- package/lib/shared/model/IdentityCredentials.d.ts +0 -41
- package/lib/shared/model/index.cjs +0 -21
- package/lib/shared/model/index.d.ts +0 -4
- package/lib/shared/overrides/Model.cjs +0 -4
- package/lib/shared/overrides/Model.d.ts +0 -22
- package/lib/shared/overrides/index.d.ts +0 -2
- package/lib/shared/overrides/overrides.cjs +0 -93
- package/lib/shared/overrides/overrides.d.ts +0 -1
- package/lib/shared/types.cjs +0 -3
- package/lib/shared/types.d.ts +0 -125
- package/lib/version.cjs +0 -8
- package/lib/version.d.ts +0 -2
- /package/lib/{bin → types/bin}/cli.d.ts +0 -0
- /package/lib/{cli-module.d.ts → types/cli-module.d.ts} +0 -0
- /package/lib/{cli-utils.d.ts → types/cli-utils.d.ts} +0 -0
- /package/lib/{client → types/client}/FabricClientAdapter.d.ts +0 -0
- /package/lib/{client → types/client}/FabricClientDispatch.d.ts +0 -0
- /package/lib/{client → types/client}/FabricClientPaginator.d.ts +0 -0
- /package/lib/{client → types/client}/FabricClientRepository.d.ts +0 -0
- /package/lib/{client → types/client}/FabricClientStatement.d.ts +0 -0
- /package/lib/{client → types/client}/collections/generation.d.ts +0 -0
- /package/lib/{client → types/client}/collections/index.d.ts +0 -0
- /package/lib/{client → types/client}/constants.d.ts +0 -0
- /package/lib/{client → types/client}/crypto.d.ts +0 -0
- /package/lib/{client → types/client}/erc20/FabricERC20ClientRepository.d.ts +0 -0
- /package/lib/{client → types/client}/erc20/index.d.ts +0 -0
- /package/lib/{client → types/client}/fabric-fs.d.ts +0 -0
- /package/lib/{client → types/client}/fabric-hsm.d.ts +0 -0
- /package/lib/{client → types/client}/ids/id-extraction.d.ts +0 -0
- /package/lib/{client → types/client}/ids/index.d.ts +0 -0
- /package/lib/{client → types/client}/index.d.ts +0 -0
- /package/lib/{client → types/client}/indexes/generation.d.ts +0 -0
- /package/lib/{client → types/client}/indexes/index.d.ts +0 -0
- /package/lib/{client → types/client}/logging.d.ts +0 -0
- /package/lib/{client → types/client}/services/FabricEnrollmentService.d.ts +0 -0
- /package/lib/{client → types/client}/services/FabricIdentityService.d.ts +0 -0
- /package/lib/{client → types/client}/services/RegistrationRequestBuilder.d.ts +0 -0
- /package/lib/{client → types/client}/services/constants.d.ts +0 -0
- /package/lib/{client → types/client}/services/index.d.ts +0 -0
- /package/lib/{client → types/client}/types.d.ts +0 -0
- /package/lib/{client → types/client}/utils.d.ts +0 -0
- /package/lib/{contract → types/contract}/Address.d.ts +0 -0
- /package/lib/{contract → types/contract}/AddressContract.d.ts +0 -0
- /package/lib/{contract → types/contract}/AuditContract.d.ts +0 -0
- /package/lib/{contract → types/contract}/BatchContract.d.ts +0 -0
- /package/lib/{contract → types/contract}/MarketContract.d.ts +0 -0
- /package/lib/{contract → types/contract}/OtherAuditContract.d.ts +0 -0
- /package/lib/{contract → types/contract}/OtherBatchContract.d.ts +0 -0
- /package/lib/{contract → types/contract}/OtherMarketContract.d.ts +0 -0
- /package/lib/{contract → types/contract}/OtherProductContract.d.ts +0 -0
- /package/lib/{contract → types/contract}/OtherProductImageContract.d.ts +0 -0
- /package/lib/{contract → types/contract}/OtherProductSharedContract.d.ts +0 -0
- /package/lib/{contract → types/contract}/OtherProductStrengthContract.d.ts +0 -0
- /package/lib/{contract → types/contract}/Product.d.ts +0 -0
- /package/lib/{contract → types/contract}/ProductContract.d.ts +0 -0
- /package/lib/{contract → types/contract}/ProductStrengthContract.d.ts +0 -0
- /package/lib/{contract → types/contract}/SegregatedPrivateDocumentContract.d.ts +0 -0
- /package/lib/{contract → types/contract}/SegregatedSharedDocumentContract.d.ts +0 -0
- /package/lib/{contract → types/contract}/User.d.ts +0 -0
- /package/lib/{contract → types/contract}/UserContract.d.ts +0 -0
- /package/lib/{contract → types/contract}/index.d.ts +0 -0
- /package/lib/{contract → types/contract}/logging-context.d.ts +0 -0
- /package/lib/{contract → types/contract}/models/Audit.d.ts +0 -0
- /package/lib/{contract → types/contract}/models/BaseIdentifiedModel.d.ts +0 -0
- /package/lib/{contract → types/contract}/models/BaseModel.d.ts +0 -0
- /package/lib/{contract → types/contract}/models/Batch.d.ts +0 -0
- /package/lib/{contract → types/contract}/models/GtinOwner.d.ts +0 -0
- /package/lib/{contract → types/contract}/models/History.d.ts +0 -0
- /package/lib/{contract → types/contract}/models/Leaflet.d.ts +0 -0
- /package/lib/{contract → types/contract}/models/LeafletFile.d.ts +0 -0
- /package/lib/{contract → types/contract}/models/Market.d.ts +0 -0
- /package/lib/{contract → types/contract}/models/OtherAudit.d.ts +0 -0
- /package/lib/{contract → types/contract}/models/OtherBatchShared.d.ts +0 -0
- /package/lib/{contract → types/contract}/models/OtherLeaflet.d.ts +0 -0
- /package/lib/{contract → types/contract}/models/OtherLeafletFile.d.ts +0 -0
- /package/lib/{contract → types/contract}/models/OtherMarket.d.ts +0 -0
- /package/lib/{contract → types/contract}/models/OtherProduct.d.ts +0 -0
- /package/lib/{contract → types/contract}/models/OtherProductImage.d.ts +0 -0
- /package/lib/{contract → types/contract}/models/OtherProductShared.d.ts +0 -0
- /package/lib/{contract → types/contract}/models/OtherProductStrength.d.ts +0 -0
- /package/lib/{contract → types/contract}/models/Product.d.ts +0 -0
- /package/lib/{contract → types/contract}/models/ProductStrength.d.ts +0 -0
- /package/lib/{contract → types/contract}/models/SegregatedDocument.d.ts +0 -0
- /package/lib/{contract → types/contract}/models/constants.d.ts +0 -0
- /package/lib/{contract → types/contract}/models/decorators-private.d.ts +0 -0
- /package/lib/{contract → types/contract}/models/decorators.d.ts +0 -0
- /package/lib/{contract → types/contract}/models/gtin.d.ts +0 -0
- /package/lib/{contract → types/contract}/models/history-dec.d.ts +0 -0
- /package/lib/{contracts → types/contracts}/ContractAdapter.d.ts +0 -0
- /package/lib/{contracts → types/contracts}/ContractContext.d.ts +0 -0
- /package/lib/{contracts → types/contracts}/FabricContractDispatch.d.ts +0 -0
- /package/lib/{contracts → types/contracts}/FabricContractPaginator.d.ts +0 -0
- /package/lib/{contracts → types/contracts}/FabricContractRepository.d.ts +0 -0
- /package/lib/{contracts → types/contracts}/FabricContractRepositoryObservableHandler.d.ts +0 -0
- /package/lib/{contracts → types/contracts}/FabricContractSequence.d.ts +0 -0
- /package/lib/{contracts → types/contracts}/FabricContractStatement.d.ts +0 -0
- /package/lib/{contracts → types/contracts}/MigrationContract.d.ts +0 -0
- /package/lib/{contracts → types/contracts}/PrivateSequence.d.ts +0 -0
- /package/lib/{contracts → types/contracts}/auth/decorators.d.ts +0 -0
- /package/lib/{contracts → types/contracts}/auth/index.d.ts +0 -0
- /package/lib/{contracts → types/contracts}/crud/crud-contract.d.ts +0 -0
- /package/lib/{contracts → types/contracts}/crud/index.d.ts +0 -0
- /package/lib/{contracts → types/contracts}/crud/serialized-crud-contract.d.ts +0 -0
- /package/lib/{contracts → types/contracts}/erc20/erc20contract.d.ts +0 -0
- /package/lib/{contracts → types/contracts}/erc20/index.d.ts +0 -0
- /package/lib/{contracts → types/contracts}/erc20/models.d.ts +0 -0
- /package/lib/{contracts → types/contracts}/index.d.ts +0 -0
- /package/lib/{contracts → types/contracts}/logging.d.ts +0 -0
- /package/lib/{contracts → types/contracts}/overrides.d.ts +0 -0
- /package/lib/{contracts → types/contracts}/types.d.ts +0 -0
- /package/lib/{contracts → types/contracts}/uuid.d.ts +0 -0
- /package/lib/{esm → types}/index.d.ts +0 -0
- /package/lib/{esm → types}/shared/ClientSerializer.d.ts +0 -0
- /package/lib/{esm → types}/shared/DeterministicSerializer.d.ts +0 -0
- /package/lib/{esm → types}/shared/SimpleDeterministicSerializer.d.ts +0 -0
- /package/lib/{esm → types}/shared/constants.d.ts +0 -0
- /package/lib/{esm → types}/shared/decorators.d.ts +0 -0
- /package/lib/{esm → types}/shared/erc20/erc20-constants.d.ts +0 -0
- /package/lib/{esm → types}/shared/erc20/index.d.ts +0 -0
- /package/lib/{esm → types}/shared/errors.d.ts +0 -0
- /package/lib/{esm → types}/shared/events.d.ts +0 -0
- /package/lib/{esm → types}/shared/fabric-types.d.ts +0 -0
- /package/lib/{esm → types}/shared/index.d.ts +0 -0
- /package/lib/{esm → types}/shared/interfaces/Checkable.d.ts +0 -0
- /package/lib/{esm → types}/shared/interfaces/index.d.ts +0 -0
- /package/lib/{esm → types}/shared/math.d.ts +0 -0
- /package/lib/{esm → types}/shared/model/FabricBaseModel.d.ts +0 -0
- /package/lib/{esm → types}/shared/model/FabricIdentifiedBaseModel.d.ts +0 -0
- /package/lib/{esm → types}/shared/model/Identity.d.ts +0 -0
- /package/lib/{esm → types}/shared/model/IdentityCredentials.d.ts +0 -0
- /package/lib/{esm → types}/shared/model/index.d.ts +0 -0
- /package/lib/{esm → types}/shared/overrides/Model.d.ts +0 -0
- /package/lib/{esm → types}/shared/overrides/index.d.ts +0 -0
- /package/lib/{esm/contracts → types/shared/overrides}/overrides.d.ts +0 -0
- /package/lib/{esm → types}/shared/types.d.ts +0 -0
|
@@ -1,1193 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FabricContractAdapter = void 0;
|
|
4
|
-
exports.createdByOnFabricCreateUpdate = createdByOnFabricCreateUpdate;
|
|
5
|
-
const for_couchdb_1 = require("@decaf-ts/for-couchdb");
|
|
6
|
-
const decorator_validation_1 = require("@decaf-ts/decorator-validation");
|
|
7
|
-
const ContractContext_1 = require("./ContractContext.cjs");
|
|
8
|
-
const db_decorators_1 = require("@decaf-ts/db-decorators");
|
|
9
|
-
const fabric_contract_api_1 = require("fabric-contract-api");
|
|
10
|
-
const logging_1 = require("@decaf-ts/logging");
|
|
11
|
-
const core_1 = require("@decaf-ts/core");
|
|
12
|
-
const FabricContractRepository_1 = require("./FabricContractRepository.cjs");
|
|
13
|
-
const FabricContractStatement_1 = require("./FabricContractStatement.cjs");
|
|
14
|
-
const FabricContractSequence_1 = require("./FabricContractSequence.cjs");
|
|
15
|
-
const constants_1 = require("./../shared/constants.cjs");
|
|
16
|
-
const SimpleDeterministicSerializer_1 = require("./../shared/SimpleDeterministicSerializer.cjs");
|
|
17
|
-
const decoration_1 = require("@decaf-ts/decoration");
|
|
18
|
-
const FabricContractPaginator_1 = require("./FabricContractPaginator.cjs");
|
|
19
|
-
const errors_1 = require("./../shared/errors.cjs");
|
|
20
|
-
const FabricContractDispatch_1 = require("./FabricContractDispatch.cjs");
|
|
21
|
-
/**
|
|
22
|
-
* @description Sets the creator or updater field in a model based on the user in the context
|
|
23
|
-
* @summary Callback function used in decorators to automatically set the created_by or updated_by fields
|
|
24
|
-
* with the username from the context when a document is created or updated
|
|
25
|
-
* @template M - Type extending Model
|
|
26
|
-
* @template R - Type extending NanoRepository<M>
|
|
27
|
-
* @template V - Type extending RelationsMetadata
|
|
28
|
-
* @param {R} this - The repository instance
|
|
29
|
-
* @param {FabricContractContext} context - The operation context containing user information
|
|
30
|
-
* @param {V} data - The relation metadata
|
|
31
|
-
* @param {string} key - The property key to set with the username
|
|
32
|
-
* @param {M} model - The model instance being created or updated
|
|
33
|
-
* @return {Promise<void>} A promise that resolves when the operation is complete
|
|
34
|
-
* @function createdByOnFabricCreateUpdate
|
|
35
|
-
* @memberOf module:fabric.contracts
|
|
36
|
-
* @mermaid
|
|
37
|
-
* sequenceDiagram
|
|
38
|
-
* participant F as createdByOnNanoCreateUpdate
|
|
39
|
-
* participant C as Context
|
|
40
|
-
* participant M as Model
|
|
41
|
-
* F->>C: get("user")
|
|
42
|
-
* C-->>F: user object
|
|
43
|
-
* F->>M: set key to user.name
|
|
44
|
-
* Note over F: If no user in context
|
|
45
|
-
* F-->>F: throw UnsupportedError
|
|
46
|
-
*/
|
|
47
|
-
async function createdByOnFabricCreateUpdate(context, data, key, model) {
|
|
48
|
-
try {
|
|
49
|
-
const user = context.get("identity");
|
|
50
|
-
model[key] = user.getID();
|
|
51
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
52
|
-
}
|
|
53
|
-
catch (e) {
|
|
54
|
-
throw new core_1.UnsupportedError("No User found in context. Please provide a user in the context");
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* @description Adapter for Hyperledger Fabric chaincode state database operations
|
|
59
|
-
* @summary Provides a CouchDB-like interface for interacting with the Fabric state database from within a chaincode contract
|
|
60
|
-
* @template void - No configuration needed for contract adapter
|
|
61
|
-
* @template FabricContractFlags - Flags specific to Fabric contract operations
|
|
62
|
-
* @template FabricContractContext - Context type for Fabric contract operations
|
|
63
|
-
* @class FabricContractAdapter
|
|
64
|
-
* @example
|
|
65
|
-
* ```typescript
|
|
66
|
-
* // In a Fabric chaincode contract class
|
|
67
|
-
* import { FabricContractAdapter } from '@decaf-ts/for-fabric';
|
|
68
|
-
*
|
|
69
|
-
* export class MyContract extends Contract {
|
|
70
|
-
* private adapter = new FabricContractAdapter();
|
|
71
|
-
*
|
|
72
|
-
* @Transaction()
|
|
73
|
-
* async createAsset(ctx: Context, id: string, data: string): Promise<void> {
|
|
74
|
-
* const model = { id, data, timestamp: Date.now() };
|
|
75
|
-
* await this.adapter.create('assets', id, model, {}, { stub: ctx.stub });
|
|
76
|
-
* }
|
|
77
|
-
* }
|
|
78
|
-
* ```
|
|
79
|
-
* @mermaid
|
|
80
|
-
* sequenceDiagram
|
|
81
|
-
* participant Contract
|
|
82
|
-
* participant FabricContractAdapter
|
|
83
|
-
* participant Stub
|
|
84
|
-
* participant StateDB
|
|
85
|
-
*
|
|
86
|
-
* Contract->>FabricContractAdapter: create(tableName, id, model, transient, ctx)
|
|
87
|
-
* FabricContractAdapter->>FabricContractAdapter: Serialize model to JSON
|
|
88
|
-
* FabricContractAdapter->>Stub: putState(id, serializedData)
|
|
89
|
-
* Stub->>StateDB: Write data
|
|
90
|
-
* StateDB-->>Stub: Success
|
|
91
|
-
* Stub-->>FabricContractAdapter: Success
|
|
92
|
-
* FabricContractAdapter-->>Contract: model
|
|
93
|
-
*/
|
|
94
|
-
class FabricContractAdapter extends for_couchdb_1.CouchDBAdapter {
|
|
95
|
-
static { this.PRIVATE_BOOKMARK_PREFIX = "__dcf_pvtbm__"; }
|
|
96
|
-
static parseSyntheticPrivateBookmark(bookmark) {
|
|
97
|
-
if (typeof bookmark !== "string")
|
|
98
|
-
return undefined;
|
|
99
|
-
if (!bookmark.startsWith(FabricContractAdapter.PRIVATE_BOOKMARK_PREFIX))
|
|
100
|
-
return undefined;
|
|
101
|
-
const raw = bookmark.slice(FabricContractAdapter.PRIVATE_BOOKMARK_PREFIX.length);
|
|
102
|
-
const parsed = Number(raw);
|
|
103
|
-
return Number.isInteger(parsed) && parsed >= 0 ? parsed : undefined;
|
|
104
|
-
}
|
|
105
|
-
static buildSyntheticPrivateBookmark(offset) {
|
|
106
|
-
return `${FabricContractAdapter.PRIVATE_BOOKMARK_PREFIX}${offset}`;
|
|
107
|
-
}
|
|
108
|
-
getClient() {
|
|
109
|
-
throw new core_1.UnsupportedError("Client is not supported in Fabric contracts");
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* @description Text decoder for converting binary data to strings
|
|
113
|
-
*/
|
|
114
|
-
static { this.textDecoder = new TextDecoder("utf8"); }
|
|
115
|
-
static { this.serializer = new SimpleDeterministicSerializer_1.SimpleDeterministicSerializer(); }
|
|
116
|
-
/**
|
|
117
|
-
* @description Context constructor for this adapter
|
|
118
|
-
* @summary Overrides the base Context constructor with FabricContractContext
|
|
119
|
-
*/
|
|
120
|
-
get Context() {
|
|
121
|
-
return ContractContext_1.FabricContractContext;
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* @description Gets the repository constructor for this adapter
|
|
125
|
-
* @summary Returns the FabricContractRepository constructor for creating repositories
|
|
126
|
-
* @template M - Type extending Model
|
|
127
|
-
* @return {Constructor<Repository<M, MangoQuery, FabricContractAdapter, FabricContractFlags, FabricContractContext>>} The repository constructor
|
|
128
|
-
*/
|
|
129
|
-
repository() {
|
|
130
|
-
return FabricContractRepository_1.FabricContractRepository;
|
|
131
|
-
}
|
|
132
|
-
Paginator(query, size, clazz) {
|
|
133
|
-
return new FabricContractPaginator_1.FabricContractPaginator(this, query, size, clazz);
|
|
134
|
-
}
|
|
135
|
-
async Sequence(options) {
|
|
136
|
-
return new FabricContractSequence_1.FabricContractSequence(options, this);
|
|
137
|
-
}
|
|
138
|
-
Dispatch() {
|
|
139
|
-
return new FabricContractDispatch_1.FabricContractDispatch();
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* @description Creates a new FabricContractAdapter instance
|
|
143
|
-
* @summary Initializes an adapter for interacting with the Fabric state database
|
|
144
|
-
* @param {void} scope - Not used in this adapter
|
|
145
|
-
* @param {string} [alias] - Optional alias for the adapter instance
|
|
146
|
-
*/
|
|
147
|
-
constructor(scope, alias) {
|
|
148
|
-
super(scope, constants_1.FabricFlavour, alias);
|
|
149
|
-
}
|
|
150
|
-
for(config, ...args) {
|
|
151
|
-
return super.for(config, ...args);
|
|
152
|
-
}
|
|
153
|
-
getModelDefaults(clazz) {
|
|
154
|
-
const m = new clazz();
|
|
155
|
-
return (decoration_1.Metadata.properties(clazz) || []).reduce((acc, p) => {
|
|
156
|
-
if (typeof m[p] !== "undefined")
|
|
157
|
-
acc[p] = m[p];
|
|
158
|
-
return acc;
|
|
159
|
-
}, {});
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* @description Creates a record in the state database
|
|
163
|
-
* @summary Serializes a model and stores it in the Fabric state database
|
|
164
|
-
* @param {string} tableName - The name of the table/collection
|
|
165
|
-
* @param {string | number} id - The record identifier
|
|
166
|
-
* @param {Record<string, any>} model - The record data
|
|
167
|
-
* @param {Record<string, any>} transient - Transient data (not used in this implementation)
|
|
168
|
-
* @param {...any[]} args - Additional arguments, including the chaincode stub and logger
|
|
169
|
-
* @return {Promise<Record<string, any>>} Promise resolving to the created record
|
|
170
|
-
*/
|
|
171
|
-
async create(clazz, id, model, ...args) {
|
|
172
|
-
const { ctx, log } = this.logCtx(args, this.create);
|
|
173
|
-
this.enforceMirrorAuthorization(clazz, ctx);
|
|
174
|
-
log.info(`in ADAPTER create with args ${args}`);
|
|
175
|
-
const tableName = decorator_validation_1.Model.tableName(clazz);
|
|
176
|
-
const composedKey = ctx.stub.createCompositeKey(tableName, [String(id)]);
|
|
177
|
-
const mirrorCollection = ctx.getOrUndefined("mirrorCollection");
|
|
178
|
-
const fullySegregated = ctx.isFullySegregated && !mirrorCollection;
|
|
179
|
-
if (!mirrorCollection) {
|
|
180
|
-
let existing;
|
|
181
|
-
try {
|
|
182
|
-
existing = await this.readState(composedKey, ctx);
|
|
183
|
-
}
|
|
184
|
-
catch (e) {
|
|
185
|
-
// eslint-disable-next-line no-ex-assign
|
|
186
|
-
e = this.parseError(e);
|
|
187
|
-
if (!(e instanceof db_decorators_1.NotFoundError))
|
|
188
|
-
throw e;
|
|
189
|
-
}
|
|
190
|
-
if (existing)
|
|
191
|
-
throw new db_decorators_1.ConflictError(`record with id ${id} in table ${tableName} already exists`);
|
|
192
|
-
}
|
|
193
|
-
try {
|
|
194
|
-
log.info(`adding entry to ${tableName} table with pk ${id}`);
|
|
195
|
-
if (mirrorCollection) {
|
|
196
|
-
model = await this.forPrivate(mirrorCollection).putState(composedKey, model, ctx);
|
|
197
|
-
}
|
|
198
|
-
else {
|
|
199
|
-
const defaults = this.getModelDefaults(clazz);
|
|
200
|
-
// handle public data if not fully segregated
|
|
201
|
-
if (!fullySegregated) {
|
|
202
|
-
if (Object.keys(model).filter((k) => {
|
|
203
|
-
if (k === for_couchdb_1.CouchDBKeys.TABLE)
|
|
204
|
-
return false;
|
|
205
|
-
return !(defaults &&
|
|
206
|
-
k in defaults &&
|
|
207
|
-
defaults[k] === model[k]);
|
|
208
|
-
}).length)
|
|
209
|
-
model = await this.putState(composedKey, model, ctx);
|
|
210
|
-
}
|
|
211
|
-
// handle segregated writes
|
|
212
|
-
const data = ctx.getFromChildren("segregatedData");
|
|
213
|
-
if (data) {
|
|
214
|
-
for (const collection in data) {
|
|
215
|
-
Object.assign(model, await this.forPrivate(collection).putState(composedKey, data[collection][id], ctx));
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
catch (e) {
|
|
221
|
-
throw this.parseError(e);
|
|
222
|
-
}
|
|
223
|
-
return model;
|
|
224
|
-
}
|
|
225
|
-
async createAll(tableName, id, model, ...args) {
|
|
226
|
-
if (id.length !== model.length)
|
|
227
|
-
throw new db_decorators_1.InternalError("Ids and models must have the same length");
|
|
228
|
-
const { log, ctxArgs } = this.logCtx(args, this.createAll);
|
|
229
|
-
const tableLabel = decorator_validation_1.Model.tableName(tableName);
|
|
230
|
-
log.debug(`Creating ${id.length} entries ${tableLabel} table`);
|
|
231
|
-
return Promise.all(id.map((i, count) => this.create(tableName, i, model[count], ...ctxArgs)));
|
|
232
|
-
}
|
|
233
|
-
/**
|
|
234
|
-
* @description Reads a record from the state database
|
|
235
|
-
* @summary Retrieves and deserializes a record from the Fabric state database
|
|
236
|
-
* @param {string} tableName - The name of the table/collection
|
|
237
|
-
* @param {string | number} id - The record identifier
|
|
238
|
-
* @param {...any[]} args - Additional arguments, including the chaincode stub and logger
|
|
239
|
-
* @return {Promise<Record<string, any>>} Promise resolving to the retrieved record
|
|
240
|
-
*/
|
|
241
|
-
async read(clazz, id, ...args) {
|
|
242
|
-
const { ctx, log } = this.logCtx(args, this.read);
|
|
243
|
-
log.info(`in ADAPTER read with args ${args}`);
|
|
244
|
-
const tableName = decorator_validation_1.Model.tableName(clazz);
|
|
245
|
-
const composedKey = ctx.stub.createCompositeKey(tableName, [String(id)]);
|
|
246
|
-
const mirrorCollection = ctx.getOrUndefined("mirrorCollection");
|
|
247
|
-
const isMirror = ctx.getOrUndefined("mirror");
|
|
248
|
-
if (isMirror && mirrorCollection) {
|
|
249
|
-
try {
|
|
250
|
-
return await this.forPrivate(mirrorCollection).readState(composedKey, ctx);
|
|
251
|
-
}
|
|
252
|
-
catch (e) {
|
|
253
|
-
throw this.parseError(e);
|
|
254
|
-
}
|
|
255
|
-
finally {
|
|
256
|
-
ctx.put("mirror", undefined);
|
|
257
|
-
ctx.put("mirrorCollection", undefined);
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
let model;
|
|
261
|
-
try {
|
|
262
|
-
model = ctx.isFullySegregated
|
|
263
|
-
? {}
|
|
264
|
-
: await this.readState(composedKey, ctx);
|
|
265
|
-
}
|
|
266
|
-
catch (e) {
|
|
267
|
-
throw this.parseError(e);
|
|
268
|
-
}
|
|
269
|
-
const readCollections = new Set([
|
|
270
|
-
...(ctx.getReadCollections() || []),
|
|
271
|
-
...(ctx.consumeReadCollections() || []),
|
|
272
|
-
]);
|
|
273
|
-
for (const col of readCollections) {
|
|
274
|
-
try {
|
|
275
|
-
Object.assign(model, await this.forPrivate(col).readState(composedKey, ctx));
|
|
276
|
-
}
|
|
277
|
-
catch (e) {
|
|
278
|
-
const parsed = this.parseError(e);
|
|
279
|
-
if (parsed instanceof db_decorators_1.NotFoundError)
|
|
280
|
-
continue;
|
|
281
|
-
throw parsed;
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
if (!Object.keys(model).length) {
|
|
285
|
-
throw new db_decorators_1.NotFoundError(`record with id ${id} in table ${tableName} does not exist`);
|
|
286
|
-
}
|
|
287
|
-
return model;
|
|
288
|
-
}
|
|
289
|
-
/**
|
|
290
|
-
* @description Retrieves multiple records from the database
|
|
291
|
-
* @summary Fetches multiple records with the given IDs from the specified table
|
|
292
|
-
* @param {string} tableName - The name of the table to read from
|
|
293
|
-
* @param id - The identifiers of the records to retrieve
|
|
294
|
-
* @param {...any[]} args - Additional arguments specific to the adapter implementation
|
|
295
|
-
* @return A promise that resolves to an array of retrieved records
|
|
296
|
-
*/
|
|
297
|
-
async readAll(clazz, id, ...args) {
|
|
298
|
-
const { log, ctx } = this.logCtx(args, this.readAll);
|
|
299
|
-
const tableName = decorator_validation_1.Model.tableName(clazz);
|
|
300
|
-
log.debug(`Reading ${id.length} entries ${tableName} table`);
|
|
301
|
-
const breakOnSingleFailure = ctx.get("breakOnSingleFailureInBulk") ?? true;
|
|
302
|
-
const continueOnError = !breakOnSingleFailure;
|
|
303
|
-
const mirrorCollection = ctx.getOrUndefined("mirrorCollection");
|
|
304
|
-
const isMirror = ctx.getOrUndefined("mirror");
|
|
305
|
-
const readMirror = async (clazz, id, ...args) => {
|
|
306
|
-
if (!mirrorCollection)
|
|
307
|
-
throw new db_decorators_1.BadRequestError("Missing mirror collection for mirror read");
|
|
308
|
-
try {
|
|
309
|
-
const { ctx, log } = this.logCtx(args, readMirror);
|
|
310
|
-
log.info(`in ADAPTER read with args ${args}`);
|
|
311
|
-
const tableName = decorator_validation_1.Model.tableName(clazz);
|
|
312
|
-
const composedKey = ctx.stub.createCompositeKey(tableName, [
|
|
313
|
-
String(id),
|
|
314
|
-
]);
|
|
315
|
-
return await this.forPrivate(mirrorCollection).readState(composedKey, ctx);
|
|
316
|
-
}
|
|
317
|
-
catch (e) {
|
|
318
|
-
throw this.parseError(e);
|
|
319
|
-
}
|
|
320
|
-
};
|
|
321
|
-
try {
|
|
322
|
-
const tasks = id.map((i) => () => isMirror && mirrorCollection
|
|
323
|
-
? readMirror(clazz, i, ...args, ctx.override({ noEmitSingle: true }))
|
|
324
|
-
: this.read(clazz, i, ...args, ctx.override({ noEmitSingle: true })));
|
|
325
|
-
const rawResult = continueOnError
|
|
326
|
-
? await (0, core_1.promiseSequence)(tasks, true)
|
|
327
|
-
: await (0, core_1.promiseSequence)(tasks);
|
|
328
|
-
return (0, core_1.resolveBulkSequenceResult)(rawResult, continueOnError, log, db_decorators_1.BulkCrudOperationKeys.READ_ALL);
|
|
329
|
-
}
|
|
330
|
-
catch (e) {
|
|
331
|
-
throw this.parseError(e);
|
|
332
|
-
}
|
|
333
|
-
finally {
|
|
334
|
-
ctx.put("mirror", undefined);
|
|
335
|
-
ctx.put("mirrorCollection", undefined);
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
/**
|
|
339
|
-
* @description Updates a record in the state database
|
|
340
|
-
* @summary Serializes a model and updates it in the Fabric state database
|
|
341
|
-
* @param {string} tableName - The name of the table/collection
|
|
342
|
-
* @param {string | number} id - The record identifier
|
|
343
|
-
* @param {Record<string, any>} model - The updated record data
|
|
344
|
-
* @param {Record<string, any>} transient - Transient data (not used in this implementation)
|
|
345
|
-
* @param {...any[]} args - Additional arguments, including the chaincode stub and logger
|
|
346
|
-
* @return {Promise<Record<string, any>>} Promise resolving to the updated record
|
|
347
|
-
*/
|
|
348
|
-
async update(clazz, id, model, ...args) {
|
|
349
|
-
const { ctx, log } = this.logCtx(args, this.update);
|
|
350
|
-
this.enforceMirrorAuthorization(clazz, ctx);
|
|
351
|
-
log.info(`in ADAPTER update with args ${args}`);
|
|
352
|
-
const tableName = decorator_validation_1.Model.tableName(clazz);
|
|
353
|
-
const composedKey = ctx.stub.createCompositeKey(tableName, [String(id)]);
|
|
354
|
-
const mirrorCollection = ctx.getOrUndefined("mirrorCollection");
|
|
355
|
-
try {
|
|
356
|
-
log.info(`updating entry in ${tableName} table with pk ${id}`);
|
|
357
|
-
if (mirrorCollection) {
|
|
358
|
-
model = await this.forPrivate(mirrorCollection).putState(composedKey, model, ctx);
|
|
359
|
-
}
|
|
360
|
-
else {
|
|
361
|
-
const defaults = this.getModelDefaults(clazz);
|
|
362
|
-
// handle public data
|
|
363
|
-
if (Object.keys(model).filter((k) => {
|
|
364
|
-
if (k === for_couchdb_1.CouchDBKeys.TABLE)
|
|
365
|
-
return false;
|
|
366
|
-
return !(defaults &&
|
|
367
|
-
k in defaults &&
|
|
368
|
-
defaults[k] === model[k]);
|
|
369
|
-
}).length)
|
|
370
|
-
model = await this.putState(composedKey, model, ctx);
|
|
371
|
-
// handle segregated writes
|
|
372
|
-
const data = ctx.getFromChildren("segregatedData");
|
|
373
|
-
if (data) {
|
|
374
|
-
for (const collection in data) {
|
|
375
|
-
Object.assign(model, await this.forPrivate(collection).putState(composedKey, data[collection][id], ctx));
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
catch (e) {
|
|
381
|
-
throw this.parseError(e);
|
|
382
|
-
}
|
|
383
|
-
return model;
|
|
384
|
-
}
|
|
385
|
-
/**
|
|
386
|
-
* @description Deletes a record from the state database
|
|
387
|
-
* @summary Retrieves a record and then removes it from the Fabric state database
|
|
388
|
-
* @param {string} tableName - The name of the table/collection
|
|
389
|
-
* @param {string | number} id - The record identifier to delete
|
|
390
|
-
* @param {...any[]} args - Additional arguments, including the chaincode stub and logger
|
|
391
|
-
* @return {Promise<Record<string, any>>} Promise resolving to the deleted record
|
|
392
|
-
*/
|
|
393
|
-
async delete(clazz, id, ...args) {
|
|
394
|
-
const { ctx, log } = this.logCtx(args, this.delete);
|
|
395
|
-
this.enforceMirrorAuthorization(clazz, ctx);
|
|
396
|
-
const tableName = decorator_validation_1.Model.tableName(clazz);
|
|
397
|
-
const composedKey = ctx.stub.createCompositeKey(tableName, [String(id)]);
|
|
398
|
-
const mirrorCollection = ctx.getOrUndefined("mirrorCollection");
|
|
399
|
-
let model;
|
|
400
|
-
if (mirrorCollection) {
|
|
401
|
-
try {
|
|
402
|
-
model = await this.forPrivate(mirrorCollection).readState(composedKey, ctx);
|
|
403
|
-
await this.forPrivate(mirrorCollection).deleteState(composedKey, ctx);
|
|
404
|
-
}
|
|
405
|
-
catch (e) {
|
|
406
|
-
throw this.parseError(e);
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
else {
|
|
410
|
-
try {
|
|
411
|
-
model = ctx.isFullySegregated
|
|
412
|
-
? {}
|
|
413
|
-
: await this.readState(composedKey, ctx);
|
|
414
|
-
if (!ctx.isFullySegregated) {
|
|
415
|
-
log.debug(`Deleting entry ${composedKey} from public ledger`);
|
|
416
|
-
await this.deleteState(composedKey, ctx);
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
catch (e) {
|
|
420
|
-
throw this.parseError(e);
|
|
421
|
-
}
|
|
422
|
-
const collections = ctx.getReadCollections();
|
|
423
|
-
if (collections && collections.length) {
|
|
424
|
-
for (const col of collections) {
|
|
425
|
-
log.debug(`ensuring collection ${col} has entry for id ${composedKey} before deleting`);
|
|
426
|
-
Object.assign(model, await this.forPrivate(col).readState(composedKey, ctx));
|
|
427
|
-
log.debug(`Deleting private collection ${col} entry for id ${composedKey}`);
|
|
428
|
-
await this.forPrivate(col).deleteState(composedKey, ctx);
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
return model;
|
|
433
|
-
}
|
|
434
|
-
async deleteState(id, context) {
|
|
435
|
-
await context.stub.deleteState(id);
|
|
436
|
-
}
|
|
437
|
-
forPrivate(collection) {
|
|
438
|
-
const toOverride = [
|
|
439
|
-
this.putState,
|
|
440
|
-
this.readState,
|
|
441
|
-
this.deleteState,
|
|
442
|
-
this.queryResult,
|
|
443
|
-
this.queryResultPaginated,
|
|
444
|
-
].map((fn) => fn.name);
|
|
445
|
-
return new Proxy(this, {
|
|
446
|
-
get(target, prop, receiver) {
|
|
447
|
-
if (!toOverride.includes(prop))
|
|
448
|
-
return Reflect.get(target, prop, receiver);
|
|
449
|
-
return new Proxy(target[prop], {
|
|
450
|
-
async apply(fn, thisArg, argsList) {
|
|
451
|
-
switch (prop) {
|
|
452
|
-
case "putState": {
|
|
453
|
-
// putState signature: (id: string, model: Record<string, any>, ctx: FabricContractContext)
|
|
454
|
-
const [id, model, ctx] = argsList;
|
|
455
|
-
const log = ctx.logger.for(prop);
|
|
456
|
-
log.debug(`Private write to ${collection} for ${id.toString()}`);
|
|
457
|
-
const data = Buffer.from(FabricContractAdapter.serializer.serialize(model, false));
|
|
458
|
-
await ctx.stub.putPrivateData(collection, id.toString(), data);
|
|
459
|
-
return model;
|
|
460
|
-
}
|
|
461
|
-
case "deleteState": {
|
|
462
|
-
// deleteState signature: (id: string, context: FabricContractContext)
|
|
463
|
-
const [id, ctx] = argsList;
|
|
464
|
-
const log = ctx.logger.for(prop);
|
|
465
|
-
log.debug(`Private delete on ${collection} for ${id.toString()}`);
|
|
466
|
-
await ctx.stub.deletePrivateData(collection, id.toString());
|
|
467
|
-
return;
|
|
468
|
-
}
|
|
469
|
-
case "readState": {
|
|
470
|
-
// readState signature: (id: string, ctx: FabricContractContext)
|
|
471
|
-
const [id, ctx] = argsList;
|
|
472
|
-
const log = ctx.logger.for(prop);
|
|
473
|
-
log.debug(`Private read from ${collection} for ${id.toString()}`);
|
|
474
|
-
const data = await ctx.stub.getPrivateData(collection, id);
|
|
475
|
-
if (!data || !data.toString().length)
|
|
476
|
-
throw new db_decorators_1.NotFoundError(`Record with id ${id} not found`);
|
|
477
|
-
try {
|
|
478
|
-
return FabricContractAdapter.serializer.deserialize(data.toString("utf8"));
|
|
479
|
-
}
|
|
480
|
-
catch {
|
|
481
|
-
return data.toString("utf8");
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
case "queryResult": {
|
|
485
|
-
const [stub, rawInput, ...args] = argsList;
|
|
486
|
-
const { log } = thisArg["logCtx"](args, prop);
|
|
487
|
-
try {
|
|
488
|
-
log.debug(`Querying collection ${collection} for ${JSON.stringify(rawInput)}`);
|
|
489
|
-
const res = await stub.getPrivateDataQueryResult(collection, JSON.stringify(rawInput));
|
|
490
|
-
log.verbose(`iterator from collection ${collection} received`);
|
|
491
|
-
return res.iterator || res;
|
|
492
|
-
}
|
|
493
|
-
catch (e) {
|
|
494
|
-
log.error(e);
|
|
495
|
-
return [];
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
case "queryResultPaginated": {
|
|
499
|
-
const [stub, rawInput, limit, skip, bookmark, ...args] = argsList;
|
|
500
|
-
const { log } = thisArg["logCtx"](args, prop);
|
|
501
|
-
const pageSize = Math.max(1, Number(limit) || 250);
|
|
502
|
-
const query = { ...rawInput };
|
|
503
|
-
const skipValue = Number(skip);
|
|
504
|
-
const parsedSkip = Number.isInteger(skipValue) && skipValue >= 0
|
|
505
|
-
? skipValue
|
|
506
|
-
: undefined;
|
|
507
|
-
const syntheticOffset = FabricContractAdapter.parseSyntheticPrivateBookmark(bookmark) ??
|
|
508
|
-
parsedSkip ??
|
|
509
|
-
0;
|
|
510
|
-
const hasOpaqueBookmark = bookmark !== undefined &&
|
|
511
|
-
bookmark !== null &&
|
|
512
|
-
bookmark !== "" &&
|
|
513
|
-
typeof bookmark === "string" &&
|
|
514
|
-
!bookmark.startsWith(FabricContractAdapter.PRIVATE_BOOKMARK_PREFIX);
|
|
515
|
-
// Keep the query CouchDB-compatible and let Fabric/CouchDB own bookmark semantics.
|
|
516
|
-
// Synthetic mode fetches one extra record to detect whether a next page exists.
|
|
517
|
-
query.limit = hasOpaqueBookmark ? pageSize : pageSize + 1;
|
|
518
|
-
if (hasOpaqueBookmark) {
|
|
519
|
-
query.bookmark = bookmark.toString();
|
|
520
|
-
delete query.skip;
|
|
521
|
-
}
|
|
522
|
-
else {
|
|
523
|
-
delete query.bookmark;
|
|
524
|
-
if (syntheticOffset > 0) {
|
|
525
|
-
query.skip = syntheticOffset;
|
|
526
|
-
}
|
|
527
|
-
else {
|
|
528
|
-
delete query.skip;
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
log.debug(`Querying collection ${collection} for ${JSON.stringify(query)}`);
|
|
532
|
-
const response = await stub.getPrivateDataQueryResult(collection, JSON.stringify(query));
|
|
533
|
-
const iterator = (response.iterator ||
|
|
534
|
-
response);
|
|
535
|
-
const responseMetadata = response.metadata || iterator.metadata || {};
|
|
536
|
-
const responseBookmark = typeof responseMetadata.bookmark === "string"
|
|
537
|
-
? responseMetadata.bookmark
|
|
538
|
-
: "";
|
|
539
|
-
log.verbose(`iterator from collection ${collection} received`);
|
|
540
|
-
const paged = [];
|
|
541
|
-
let hasMore = false;
|
|
542
|
-
try {
|
|
543
|
-
while (true) {
|
|
544
|
-
const res = await iterator.next();
|
|
545
|
-
if (res.done)
|
|
546
|
-
break;
|
|
547
|
-
if (res.value && res.value.value) {
|
|
548
|
-
const key = res.value.key;
|
|
549
|
-
if (paged.length < pageSize) {
|
|
550
|
-
paged.push({
|
|
551
|
-
key,
|
|
552
|
-
value: Buffer.isBuffer(res.value.value)
|
|
553
|
-
? res.value.value
|
|
554
|
-
: Buffer.from(res.value.value.toString("utf8")),
|
|
555
|
-
});
|
|
556
|
-
}
|
|
557
|
-
else {
|
|
558
|
-
hasMore = true;
|
|
559
|
-
break; // early exit
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
finally {
|
|
565
|
-
await iterator.close();
|
|
566
|
-
}
|
|
567
|
-
// Wrap the page in an async iterator for resultIterator()
|
|
568
|
-
let idx = 0;
|
|
569
|
-
const arrayIterator = {
|
|
570
|
-
async next() {
|
|
571
|
-
if (idx < paged.length) {
|
|
572
|
-
return { value: paged[idx++], done: false };
|
|
573
|
-
}
|
|
574
|
-
return { value: undefined, done: true };
|
|
575
|
-
},
|
|
576
|
-
async close() { },
|
|
577
|
-
};
|
|
578
|
-
return {
|
|
579
|
-
iterator: arrayIterator,
|
|
580
|
-
metadata: {
|
|
581
|
-
fetchedRecordsCount: paged.length,
|
|
582
|
-
bookmark: responseBookmark ||
|
|
583
|
-
(hasMore
|
|
584
|
-
? FabricContractAdapter.buildSyntheticPrivateBookmark(syntheticOffset + paged.length)
|
|
585
|
-
: ""),
|
|
586
|
-
},
|
|
587
|
-
};
|
|
588
|
-
}
|
|
589
|
-
default:
|
|
590
|
-
throw new db_decorators_1.InternalError(`Unsupported method override ${String(prop)}`);
|
|
591
|
-
}
|
|
592
|
-
},
|
|
593
|
-
});
|
|
594
|
-
},
|
|
595
|
-
});
|
|
596
|
-
}
|
|
597
|
-
async putState(id, model, ctx) {
|
|
598
|
-
let data;
|
|
599
|
-
try {
|
|
600
|
-
data = Buffer.from(FabricContractAdapter.serializer.serialize(model, false));
|
|
601
|
-
}
|
|
602
|
-
catch (e) {
|
|
603
|
-
throw new db_decorators_1.SerializationError(`Failed to serialize record with id ${id}: ${e}`);
|
|
604
|
-
}
|
|
605
|
-
await ctx.stub.putState(id.toString(), data);
|
|
606
|
-
return model;
|
|
607
|
-
}
|
|
608
|
-
async readState(id, ctx) {
|
|
609
|
-
let result;
|
|
610
|
-
const { log } = this.logCtx([ctx], this.readState);
|
|
611
|
-
const res = (await ctx.stub.getState(id.toString())).toString();
|
|
612
|
-
if (!res)
|
|
613
|
-
throw new db_decorators_1.NotFoundError(`Record with id ${id} not found`);
|
|
614
|
-
log.silly(`state retrieved under id ${id}`);
|
|
615
|
-
try {
|
|
616
|
-
result = FabricContractAdapter.serializer.deserialize(res.toString());
|
|
617
|
-
}
|
|
618
|
-
catch (e) {
|
|
619
|
-
throw new db_decorators_1.SerializationError(`Failed to parse record: ${e}`);
|
|
620
|
-
}
|
|
621
|
-
return result;
|
|
622
|
-
}
|
|
623
|
-
async queryResult(stub, rawInput,
|
|
624
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
625
|
-
...args) {
|
|
626
|
-
return stub.getQueryResult(JSON.stringify(rawInput));
|
|
627
|
-
}
|
|
628
|
-
async queryResultPaginated(stub, rawInput, limit = 250, page, bookmark,
|
|
629
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
630
|
-
...args) {
|
|
631
|
-
return stub.getQueryResultWithPagination(JSON.stringify(rawInput), limit, bookmark?.toString());
|
|
632
|
-
}
|
|
633
|
-
/**
|
|
634
|
-
* @description Decodes binary data to string
|
|
635
|
-
* @summary Converts a Uint8Array to a string using UTF-8 encoding
|
|
636
|
-
* @param {Uint8Array} buffer - The binary data to decode
|
|
637
|
-
* @return {string} The decoded string
|
|
638
|
-
*/
|
|
639
|
-
decode(buffer) {
|
|
640
|
-
return FabricContractAdapter.textDecoder.decode(buffer);
|
|
641
|
-
}
|
|
642
|
-
/**
|
|
643
|
-
* @description Creates operation flags for Fabric contract operations
|
|
644
|
-
* @summary Merges default flags with Fabric-specific context information
|
|
645
|
-
* @template M - Type extending Model
|
|
646
|
-
* @param {OperationKeys} operation - The operation being performed
|
|
647
|
-
* @param {Constructor<M>} model - The model constructor
|
|
648
|
-
* @param {Partial<FabricContractFlags>} flags - Partial flags to merge with defaults
|
|
649
|
-
* @param {Ctx} ctx - The Fabric chaincode context
|
|
650
|
-
* @return {FabricContractFlags} The merged flags
|
|
651
|
-
*/
|
|
652
|
-
async flags(operation, model, flags) {
|
|
653
|
-
let baseFlags = {
|
|
654
|
-
segregated: false,
|
|
655
|
-
rebuildWithTransient: false,
|
|
656
|
-
fullySegregated: false,
|
|
657
|
-
};
|
|
658
|
-
if (flags instanceof ContractContext_1.FabricContractContext || flags instanceof core_1.Context) {
|
|
659
|
-
flags = flags.toOverrides();
|
|
660
|
-
}
|
|
661
|
-
baseFlags = Object.assign(baseFlags, flags);
|
|
662
|
-
const stubFromFlags = flags.stub || flags.stub;
|
|
663
|
-
const identityFromFlags = flags.identity ||
|
|
664
|
-
flags.clientIdentity;
|
|
665
|
-
if (stubFromFlags && identityFromFlags) {
|
|
666
|
-
const txId = stubFromFlags.getTxID();
|
|
667
|
-
Object.assign(baseFlags, {
|
|
668
|
-
stub: stubFromFlags,
|
|
669
|
-
identity: identityFromFlags,
|
|
670
|
-
cert: identityFromFlags.getIDBytes().toString(),
|
|
671
|
-
roles: identityFromFlags.getAttributeValue("roles"),
|
|
672
|
-
logger: logging_1.Logging.for(operation, {
|
|
673
|
-
logLevel: false,
|
|
674
|
-
timestamp: false,
|
|
675
|
-
correlationId: txId,
|
|
676
|
-
}, flags),
|
|
677
|
-
correlationId: txId,
|
|
678
|
-
});
|
|
679
|
-
}
|
|
680
|
-
else {
|
|
681
|
-
baseFlags = Object.assign(baseFlags, flags || {});
|
|
682
|
-
}
|
|
683
|
-
return (await super.flags(operation, model, baseFlags));
|
|
684
|
-
}
|
|
685
|
-
/**
|
|
686
|
-
* @description Creates an index for a model
|
|
687
|
-
* @summary This method is not implemented for Fabric contracts and returns a resolved promise
|
|
688
|
-
* @template M - Type extending Model
|
|
689
|
-
* @param {Constructor<M>} models - The model constructor
|
|
690
|
-
* @return {Promise<void>} Promise that resolves immediately
|
|
691
|
-
*/
|
|
692
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
693
|
-
index(models) {
|
|
694
|
-
return Promise.resolve(undefined);
|
|
695
|
-
}
|
|
696
|
-
/**
|
|
697
|
-
* @description Processes results from a state query iterator
|
|
698
|
-
* @summary Iterates through query results and converts them to a structured format
|
|
699
|
-
* @param {Logger} log - Logger instance for debugging
|
|
700
|
-
* @param {Iterators.StateQueryIterator} iterator - The state query iterator
|
|
701
|
-
* @param {boolean} [isHistory=false] - Whether this is a history query
|
|
702
|
-
* @return {Promise<any[]>} Promise resolving to an array of processed results
|
|
703
|
-
* @mermaid
|
|
704
|
-
* sequenceDiagram
|
|
705
|
-
* participant Caller
|
|
706
|
-
* participant ResultIterator
|
|
707
|
-
* participant Iterator
|
|
708
|
-
*
|
|
709
|
-
* Caller->>ResultIterator: resultIterator(log, iterator, isHistory)
|
|
710
|
-
* loop Until done
|
|
711
|
-
* ResultIterator->>Iterator: next()
|
|
712
|
-
* Iterator-->>ResultIterator: { value, done }
|
|
713
|
-
* alt Has value
|
|
714
|
-
* ResultIterator->>ResultIterator: Process value based on isHistory
|
|
715
|
-
* ResultIterator->>ResultIterator: Add to results array
|
|
716
|
-
* end
|
|
717
|
-
* end
|
|
718
|
-
* ResultIterator->>Iterator: close()
|
|
719
|
-
* ResultIterator-->>Caller: allResults
|
|
720
|
-
*/
|
|
721
|
-
async resultIterator(log, iterator, isHistory = false) {
|
|
722
|
-
const allResults = [];
|
|
723
|
-
let res = await iterator.next();
|
|
724
|
-
while (!res.done) {
|
|
725
|
-
if (res.value && res.value.value.toString()) {
|
|
726
|
-
let jsonRes = {};
|
|
727
|
-
log.debug(res.value.value.toString("utf8"));
|
|
728
|
-
if (isHistory /* && isHistory === true*/) {
|
|
729
|
-
jsonRes.TxId = res.value.txId;
|
|
730
|
-
jsonRes.Timestamp = res.value.timestamp;
|
|
731
|
-
try {
|
|
732
|
-
jsonRes.Value = JSON.parse(res.value.value.toString("utf8"));
|
|
733
|
-
}
|
|
734
|
-
catch (err) {
|
|
735
|
-
log.error(err);
|
|
736
|
-
jsonRes.Value = res.value.value.toString("utf8");
|
|
737
|
-
}
|
|
738
|
-
}
|
|
739
|
-
else {
|
|
740
|
-
try {
|
|
741
|
-
jsonRes = JSON.parse(res.value.value.toString("utf8"));
|
|
742
|
-
}
|
|
743
|
-
catch (err) {
|
|
744
|
-
log.error(err);
|
|
745
|
-
jsonRes = res.value.value.toString("utf8");
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
allResults.push(jsonRes);
|
|
749
|
-
}
|
|
750
|
-
res = await iterator.next();
|
|
751
|
-
}
|
|
752
|
-
log.debug(`Closing iterator after ${allResults.length} results`);
|
|
753
|
-
await iterator.close();
|
|
754
|
-
return allResults;
|
|
755
|
-
}
|
|
756
|
-
/**
|
|
757
|
-
* @description Executes a raw query against the state database
|
|
758
|
-
* @summary Performs a rich query using CouchDB syntax against the Fabric state database
|
|
759
|
-
* @template R - The return type
|
|
760
|
-
* @param {MangoQuery} rawInput - The Mango Query to execute
|
|
761
|
-
* @param {boolean} docsOnly - Whether to return only documents (not used in this implementation)
|
|
762
|
-
* @param {...any[]} args - Additional arguments, including the chaincode stub and logger
|
|
763
|
-
* @return {Promise<R>} Promise resolving to the query results
|
|
764
|
-
* @mermaid
|
|
765
|
-
* sequenceDiagram
|
|
766
|
-
* participant Caller
|
|
767
|
-
* participant FabricContractAdapter
|
|
768
|
-
* participant Stub
|
|
769
|
-
* participant StateDB
|
|
770
|
-
*
|
|
771
|
-
* Caller->>FabricContractAdapter: raw(rawInput, docsOnly, ctx)
|
|
772
|
-
* FabricContractAdapter->>FabricContractAdapter: Extract limit and skip
|
|
773
|
-
* alt With pagination
|
|
774
|
-
* FabricContractAdapter->>Stub: getQueryResultWithPagination(query, limit, skip)
|
|
775
|
-
* else Without pagination
|
|
776
|
-
* FabricContractAdapter->>Stub: getQueryResult(query)
|
|
777
|
-
* end
|
|
778
|
-
* Stub->>StateDB: Execute query
|
|
779
|
-
* StateDB-->>Stub: Iterator
|
|
780
|
-
* Stub-->>FabricContractAdapter: Iterator
|
|
781
|
-
* FabricContractAdapter->>FabricContractAdapter: resultIterator(log, iterator)
|
|
782
|
-
* FabricContractAdapter-->>Caller: results
|
|
783
|
-
*/
|
|
784
|
-
async raw(rawInput, docsOnly = true, ...args) {
|
|
785
|
-
const { log, ctx, ctxArgs } = this.logCtx(args, this.raw);
|
|
786
|
-
const enableSegregates = !args.length || args[0] !== true;
|
|
787
|
-
const fullySegregated = enableSegregates && ctx.isFullySegregated;
|
|
788
|
-
const { skip, limit } = rawInput;
|
|
789
|
-
const bookmark = rawInput["bookmark"];
|
|
790
|
-
const paginationActive = Boolean(limit || skip || bookmark);
|
|
791
|
-
let resp = { docs: [], bookmark: undefined };
|
|
792
|
-
// Query public state only when the model is NOT fully segregated
|
|
793
|
-
if (!fullySegregated) {
|
|
794
|
-
let iterator;
|
|
795
|
-
if (limit || skip) {
|
|
796
|
-
delete rawInput["limit"];
|
|
797
|
-
delete rawInput["skip"];
|
|
798
|
-
log.debug(`Retrieving public paginated iterator: limit: ${limit}/ skip: ${skip}`);
|
|
799
|
-
const response = (await this.queryResultPaginated(ctx.stub, rawInput, limit || Number.MAX_VALUE, skip?.toString(), bookmark, ...[ctx]));
|
|
800
|
-
resp.bookmark = response.metadata.bookmark;
|
|
801
|
-
iterator = response.iterator;
|
|
802
|
-
log.debug(`Retrieved public paging iterator`);
|
|
803
|
-
}
|
|
804
|
-
else {
|
|
805
|
-
log.debug("Retrieving listing public iterator");
|
|
806
|
-
iterator = (await this.queryResult(ctx.stub, rawInput, ctx));
|
|
807
|
-
}
|
|
808
|
-
log.debug(`Retrieved public listing iterator`);
|
|
809
|
-
resp.docs = (await this.resultIterator(log, iterator));
|
|
810
|
-
log.debug(`returning ${Array.isArray(resp.docs) ? resp.docs.length : 1} results`);
|
|
811
|
-
}
|
|
812
|
-
else {
|
|
813
|
-
// For fully segregated models, strip pagination fields from rawInput
|
|
814
|
-
// so the segregated query below can re-apply them cleanly
|
|
815
|
-
if (limit || skip) {
|
|
816
|
-
delete rawInput["limit"];
|
|
817
|
-
delete rawInput["skip"];
|
|
818
|
-
}
|
|
819
|
-
log.debug("Skipping public state query (fully segregated model)");
|
|
820
|
-
}
|
|
821
|
-
const collections = enableSegregates ? ctx.getReadCollections() : undefined;
|
|
822
|
-
if (collections && collections.length) {
|
|
823
|
-
// Build a fresh input with limit/skip/bookmark restored
|
|
824
|
-
const segregatedInput = { ...rawInput };
|
|
825
|
-
if (limit)
|
|
826
|
-
segregatedInput.limit = limit;
|
|
827
|
-
if (skip)
|
|
828
|
-
segregatedInput.skip = skip;
|
|
829
|
-
if (bookmark)
|
|
830
|
-
segregatedInput["bookmark"] = bookmark;
|
|
831
|
-
const segregated = [];
|
|
832
|
-
for (const collection of collections) {
|
|
833
|
-
log.debug(`Querying from ${collection}`);
|
|
834
|
-
const fromCols = await this.forPrivate(collection).raw({ ...segregatedInput }, false, true, ...ctxArgs);
|
|
835
|
-
log.verbose(`received ${fromCols.length} from ${collection}`);
|
|
836
|
-
segregated.push(fromCols);
|
|
837
|
-
}
|
|
838
|
-
if (paginationActive) {
|
|
839
|
-
// For paginated flows, keep source selection deterministic so
|
|
840
|
-
// externally generated opaque bookmarks stay valid across pages.
|
|
841
|
-
if (fullySegregated) {
|
|
842
|
-
resp = segregated[0] || resp;
|
|
843
|
-
}
|
|
844
|
-
else if (!resp.docs?.length && segregated.length) {
|
|
845
|
-
// Preserve public-state priority for mixed models, but allow a
|
|
846
|
-
// stable fallback when public query returns no docs.
|
|
847
|
-
resp = segregated[0];
|
|
848
|
-
}
|
|
849
|
-
}
|
|
850
|
-
else {
|
|
851
|
-
// Non-paginated reads can still prefer the richest response.
|
|
852
|
-
resp = segregated.reduce((acc, curr) => {
|
|
853
|
-
if (!acc)
|
|
854
|
-
return curr;
|
|
855
|
-
if (curr.docs && curr.docs.length >= acc?.docs.length)
|
|
856
|
-
return curr;
|
|
857
|
-
return acc;
|
|
858
|
-
}, resp);
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
if (docsOnly) {
|
|
862
|
-
return resp.docs;
|
|
863
|
-
}
|
|
864
|
-
return resp;
|
|
865
|
-
}
|
|
866
|
-
async view(
|
|
867
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
868
|
-
ddoc,
|
|
869
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
870
|
-
viewName,
|
|
871
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
872
|
-
options,
|
|
873
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
874
|
-
..._args) {
|
|
875
|
-
throw new core_1.UnsupportedError("Fabric contracts do not support CouchDB views.");
|
|
876
|
-
}
|
|
877
|
-
Statement(overrides) {
|
|
878
|
-
return new FabricContractStatement_1.FabricStatement(this, overrides);
|
|
879
|
-
}
|
|
880
|
-
async updateAll(tableName, id, model, ...args) {
|
|
881
|
-
if (id.length !== model.length)
|
|
882
|
-
throw new db_decorators_1.InternalError("Ids and models must have the same length");
|
|
883
|
-
const { log, ctxArgs } = this.logCtx(args, this.updateAll);
|
|
884
|
-
const tableLabel = decorator_validation_1.Model.tableName(tableName);
|
|
885
|
-
log.debug(`Updating ${id.length} entries ${tableLabel} table`);
|
|
886
|
-
return Promise.all(id.map((i, count) => this.update(tableName, i, model[count], ...ctxArgs)));
|
|
887
|
-
}
|
|
888
|
-
/**
|
|
889
|
-
*
|
|
890
|
-
* @param model
|
|
891
|
-
* @param {string} pk
|
|
892
|
-
* @param args
|
|
893
|
-
*/
|
|
894
|
-
prepare(model, ...args) {
|
|
895
|
-
const { log, ctx } = this.logCtx(args, this.prepare);
|
|
896
|
-
const split = decorator_validation_1.Model.segregate(model);
|
|
897
|
-
const tableName = decorator_validation_1.Model.tableName(model.constructor);
|
|
898
|
-
const pk = decorator_validation_1.Model.pk(model.constructor);
|
|
899
|
-
const id = model[pk];
|
|
900
|
-
const isMirror = ctx.getOrUndefined("mirror");
|
|
901
|
-
const mapToRecord = function (obj, keysOverride) {
|
|
902
|
-
if (keysOverride)
|
|
903
|
-
keysOverride = [...new Set([...keysOverride, pk])];
|
|
904
|
-
const result = Object.entries(obj).reduce((accum, [key, val]) => {
|
|
905
|
-
if (typeof val === "undefined")
|
|
906
|
-
return accum;
|
|
907
|
-
if (keysOverride && !keysOverride.includes(key))
|
|
908
|
-
return accum;
|
|
909
|
-
const mappedProp = decorator_validation_1.Model.columnName(model, key);
|
|
910
|
-
if (this.isReserved(mappedProp))
|
|
911
|
-
throw new db_decorators_1.InternalError(`Property name ${mappedProp} is reserved`);
|
|
912
|
-
val = val instanceof Date ? new Date(val) : val;
|
|
913
|
-
accum[mappedProp] = val;
|
|
914
|
-
return accum;
|
|
915
|
-
}, {});
|
|
916
|
-
if (Object.keys(result).filter((k) => Boolean(result[k])).length) {
|
|
917
|
-
// Add table identifier
|
|
918
|
-
result[for_couchdb_1.CouchDBKeys.TABLE] = tableName;
|
|
919
|
-
}
|
|
920
|
-
return result;
|
|
921
|
-
}.bind(this);
|
|
922
|
-
log.silly(`Preparing record for ${tableName} table with pk ${model[pk]}`);
|
|
923
|
-
const segregatedWriteKeys = ctx.getSegregatedWrites();
|
|
924
|
-
const segregatedWrites = {};
|
|
925
|
-
// Only apply segregated writes when the current model actually has a transient split.
|
|
926
|
-
// The same FabricContractContext can be reused across nested operations (for example
|
|
927
|
-
// sequence upserts during persistent version generation). In those cases, we must not
|
|
928
|
-
// attempt to apply parent-model segregated write keys to unrelated models.
|
|
929
|
-
if (segregatedWriteKeys && split.transient && typeof split.transient === "object") {
|
|
930
|
-
for (const collection in segregatedWriteKeys) {
|
|
931
|
-
segregatedWrites[collection] = segregatedWrites[collection] || {};
|
|
932
|
-
segregatedWrites[collection][id] = mapToRecord(ctx.getOrUndefined("forceSegregateWrite")
|
|
933
|
-
? split.model
|
|
934
|
-
: (split.transient || {}), segregatedWriteKeys[collection]);
|
|
935
|
-
}
|
|
936
|
-
}
|
|
937
|
-
// In mirror mode, the record should contain ALL model properties (full copy)
|
|
938
|
-
const record = isMirror ? mapToRecord(model) : mapToRecord(split.model);
|
|
939
|
-
return {
|
|
940
|
-
record,
|
|
941
|
-
id: model[pk],
|
|
942
|
-
transient: !isMirror && split.transient && Object.keys(split.transient).length
|
|
943
|
-
? mapToRecord(split.transient)
|
|
944
|
-
: undefined,
|
|
945
|
-
segregated: isMirror ? undefined : segregatedWrites,
|
|
946
|
-
};
|
|
947
|
-
}
|
|
948
|
-
revert(obj, clazz, id, transient, ...args) {
|
|
949
|
-
const { log, ctx } = this.logCtx(args, this.revert);
|
|
950
|
-
const ob = {};
|
|
951
|
-
const pk = decorator_validation_1.Model.pk(clazz);
|
|
952
|
-
const pkProps = decorator_validation_1.Model.pkProps(clazz);
|
|
953
|
-
if (pkProps?.type === Number && typeof id === "string") {
|
|
954
|
-
id = Number(id);
|
|
955
|
-
}
|
|
956
|
-
ob[pk] = id;
|
|
957
|
-
log.silly(`Rebuilding model ${clazz.name} id ${id}`);
|
|
958
|
-
function mapToModel(r) {
|
|
959
|
-
const m = (typeof clazz === "string" ? decorator_validation_1.Model.build(ob, clazz) : new clazz(ob));
|
|
960
|
-
const attributes = decorator_validation_1.Model.getAttributes(clazz);
|
|
961
|
-
const keys = attributes.length ? attributes : Object.keys(m);
|
|
962
|
-
return keys
|
|
963
|
-
.filter((k) => k !== pk)
|
|
964
|
-
.reduce((accum, key) => {
|
|
965
|
-
accum[key] =
|
|
966
|
-
r[decorator_validation_1.Model.columnName(accum, key)];
|
|
967
|
-
return accum;
|
|
968
|
-
}, m);
|
|
969
|
-
}
|
|
970
|
-
let result = mapToModel(obj);
|
|
971
|
-
if (transient && !this.shouldRebuildWithTransient(ctx)) {
|
|
972
|
-
log.debug(`filtering transient properties: ${Object.keys(transient).join(", ")}`);
|
|
973
|
-
result = Object.entries(result).reduce((acc, [key, v]) => {
|
|
974
|
-
if (key === pk || !(key in transient)) {
|
|
975
|
-
acc[key] = v;
|
|
976
|
-
}
|
|
977
|
-
return acc;
|
|
978
|
-
}, new clazz());
|
|
979
|
-
}
|
|
980
|
-
return result;
|
|
981
|
-
}
|
|
982
|
-
shouldRebuildWithTransient(ctx) {
|
|
983
|
-
if (!ctx)
|
|
984
|
-
return false;
|
|
985
|
-
if (ctx.getOrUndefined("rebuildWithTransient"))
|
|
986
|
-
return true;
|
|
987
|
-
const operation = ctx.getOrUndefined("operation");
|
|
988
|
-
if (!operation)
|
|
989
|
-
return true;
|
|
990
|
-
const op = operation.toString().toLowerCase();
|
|
991
|
-
return !core_1.TransactionOperationKeys.map((k) => k.toLowerCase()).includes(op);
|
|
992
|
-
}
|
|
993
|
-
getContextMsp(context) {
|
|
994
|
-
const identity = context.get("identity");
|
|
995
|
-
if (!identity)
|
|
996
|
-
return undefined;
|
|
997
|
-
if (typeof identity === "string")
|
|
998
|
-
return identity;
|
|
999
|
-
try {
|
|
1000
|
-
return identity.getMSPID();
|
|
1001
|
-
}
|
|
1002
|
-
catch {
|
|
1003
|
-
return undefined;
|
|
1004
|
-
}
|
|
1005
|
-
}
|
|
1006
|
-
enforceMirrorAuthorization(clazz, ctx) {
|
|
1007
|
-
const mirrorMeta = decorator_validation_1.Model.mirroredAt(clazz);
|
|
1008
|
-
if (!mirrorMeta)
|
|
1009
|
-
return;
|
|
1010
|
-
const msp = this.getContextMsp(ctx);
|
|
1011
|
-
if (!msp)
|
|
1012
|
-
return;
|
|
1013
|
-
if (msp === mirrorMeta.mspId ||
|
|
1014
|
-
(mirrorMeta.condition && mirrorMeta.condition(msp))) {
|
|
1015
|
-
throw new core_1.AuthorizationError(`Organization ${msp} is not authorized to modify mirrored data`);
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
createPrefix(tableName, id, model, ...args) {
|
|
1019
|
-
const { ctxArgs } = this.logCtx(args, this.createPrefix);
|
|
1020
|
-
const record = {};
|
|
1021
|
-
record[for_couchdb_1.CouchDBKeys.TABLE] = decorator_validation_1.Model.tableName(tableName);
|
|
1022
|
-
Object.assign(record, model);
|
|
1023
|
-
return [tableName, id, record, ...ctxArgs];
|
|
1024
|
-
}
|
|
1025
|
-
updatePrefix(tableName, id, model, ...args) {
|
|
1026
|
-
const { ctxArgs } = this.logCtx(args, this.updatePrefix);
|
|
1027
|
-
const record = {};
|
|
1028
|
-
record[for_couchdb_1.CouchDBKeys.TABLE] = decorator_validation_1.Model.tableName(tableName);
|
|
1029
|
-
Object.assign(record, model);
|
|
1030
|
-
return [tableName, id, record, ...ctxArgs];
|
|
1031
|
-
}
|
|
1032
|
-
createAllPrefix(tableName, ids, models, ...args) {
|
|
1033
|
-
if (ids.length !== models.length)
|
|
1034
|
-
throw new db_decorators_1.InternalError("Ids and models must have the same length");
|
|
1035
|
-
const ctx = args.pop();
|
|
1036
|
-
const records = ids.map((id, count) => {
|
|
1037
|
-
const record = {};
|
|
1038
|
-
record[for_couchdb_1.CouchDBKeys.TABLE] = decorator_validation_1.Model.tableName(tableName);
|
|
1039
|
-
Object.assign(record, models[count]);
|
|
1040
|
-
return record;
|
|
1041
|
-
});
|
|
1042
|
-
return [tableName, ids, records, ctx];
|
|
1043
|
-
}
|
|
1044
|
-
updateAllPrefix(tableName, ids, models, ...args) {
|
|
1045
|
-
if (ids.length !== models.length)
|
|
1046
|
-
throw new db_decorators_1.InternalError("Ids and models must have the same length");
|
|
1047
|
-
const ctx = args.pop();
|
|
1048
|
-
const records = ids.map((id, count) => {
|
|
1049
|
-
const record = {};
|
|
1050
|
-
record[for_couchdb_1.CouchDBKeys.TABLE] = decorator_validation_1.Model.tableName(tableName);
|
|
1051
|
-
Object.assign(record, models[count]);
|
|
1052
|
-
return record;
|
|
1053
|
-
});
|
|
1054
|
-
return [tableName, ids, records, ctx];
|
|
1055
|
-
}
|
|
1056
|
-
parseError(err, reason) {
|
|
1057
|
-
return FabricContractAdapter.parseError(reason || err);
|
|
1058
|
-
}
|
|
1059
|
-
logCtx(args, operation, allowCreate = false, overrides) {
|
|
1060
|
-
if (!allowCreate)
|
|
1061
|
-
return super.logCtx(args, operation, allowCreate, overrides);
|
|
1062
|
-
return super.logCtx
|
|
1063
|
-
.call(this, args, operation, allowCreate, overrides)
|
|
1064
|
-
.then((res) => {
|
|
1065
|
-
if (!(res.ctx instanceof ContractContext_1.FabricContractContext))
|
|
1066
|
-
throw new db_decorators_1.InternalError(`Invalid context binding`);
|
|
1067
|
-
return Object.assign(res, {
|
|
1068
|
-
stub: res.ctx.stub,
|
|
1069
|
-
identity: res.ctx.identity,
|
|
1070
|
-
});
|
|
1071
|
-
});
|
|
1072
|
-
}
|
|
1073
|
-
async updateObservers(table, event, id, ...args) {
|
|
1074
|
-
if (!this.observerHandler)
|
|
1075
|
-
throw new db_decorators_1.InternalError("ObserverHandler not initialized. Did you register any observables?");
|
|
1076
|
-
const { ctx, ctxArgs } = this.logCtx(args, this.updateObservers);
|
|
1077
|
-
if (ctx.isFullySegregated)
|
|
1078
|
-
return;
|
|
1079
|
-
if (ctx.getOrUndefined("noEmit"))
|
|
1080
|
-
return;
|
|
1081
|
-
if (!ctx.stub)
|
|
1082
|
-
return;
|
|
1083
|
-
const isBulk = Array.isArray(id);
|
|
1084
|
-
const emitSingle = !ctx.getOrUndefined("noEmitSingle");
|
|
1085
|
-
const emitBulk = !ctx.getOrUndefined("noEmitBulk");
|
|
1086
|
-
if ((isBulk && emitBulk) || (!isBulk && emitSingle)) {
|
|
1087
|
-
// Pass the MSP owner from stub and the result payload (if any) in the
|
|
1088
|
-
// positions the handler expects: (table, event, id, owner?, payload?, ctx)
|
|
1089
|
-
const mspId = ctx.stub.getMspID ? ctx.stub.getMspID() : undefined;
|
|
1090
|
-
const nonCtxArgs = ctxArgs.slice(0, -1); // everything before ctx
|
|
1091
|
-
const payload = nonCtxArgs.length > 0 ? nonCtxArgs[0] : undefined;
|
|
1092
|
-
await this.observerHandler.updateObservers(table, event, id, mspId, payload, ctx);
|
|
1093
|
-
}
|
|
1094
|
-
}
|
|
1095
|
-
static parseError(err) {
|
|
1096
|
-
// if (
|
|
1097
|
-
// MISSING_PRIVATE_DATA_REGEX.test(
|
|
1098
|
-
// typeof err === "string" ? err : err.message
|
|
1099
|
-
// )
|
|
1100
|
-
// )
|
|
1101
|
-
// return new UnauthorizedPrivateDataAccess(err) as E;
|
|
1102
|
-
const msg = typeof err === "string" ? err : err.message;
|
|
1103
|
-
if (msg.includes(db_decorators_1.NotFoundError.name))
|
|
1104
|
-
return new db_decorators_1.NotFoundError(err);
|
|
1105
|
-
if (msg.includes(db_decorators_1.ConflictError.name))
|
|
1106
|
-
return new db_decorators_1.ConflictError(err);
|
|
1107
|
-
if (msg.includes(db_decorators_1.BadRequestError.name))
|
|
1108
|
-
return new db_decorators_1.BadRequestError(err);
|
|
1109
|
-
if (msg.includes(core_1.QueryError.name))
|
|
1110
|
-
return new core_1.QueryError(err);
|
|
1111
|
-
if (msg.includes(core_1.PagingError.name))
|
|
1112
|
-
return new core_1.PagingError(err);
|
|
1113
|
-
if (msg.includes(core_1.UnsupportedError.name))
|
|
1114
|
-
return new core_1.UnsupportedError(err);
|
|
1115
|
-
if (msg.includes(core_1.MigrationError.name))
|
|
1116
|
-
return new core_1.MigrationError(err);
|
|
1117
|
-
if (msg.includes(core_1.ObserverError.name))
|
|
1118
|
-
return new core_1.ObserverError(err);
|
|
1119
|
-
if (msg.includes(core_1.AuthorizationError.name))
|
|
1120
|
-
return new core_1.AuthorizationError(err);
|
|
1121
|
-
if (msg.includes(core_1.ForbiddenError.name))
|
|
1122
|
-
return new core_1.ForbiddenError(err);
|
|
1123
|
-
if (msg.includes(core_1.ConnectionError.name))
|
|
1124
|
-
return new core_1.ConnectionError(err);
|
|
1125
|
-
if (msg.includes(db_decorators_1.SerializationError.name))
|
|
1126
|
-
return new db_decorators_1.SerializationError(err);
|
|
1127
|
-
if (msg.includes("no ledger context"))
|
|
1128
|
-
return new errors_1.MissingContextError(`No context found. this can be caused by debugging: ${msg}`);
|
|
1129
|
-
return new db_decorators_1.InternalError(err);
|
|
1130
|
-
}
|
|
1131
|
-
/**
|
|
1132
|
-
* @description Static method for decoration overrides
|
|
1133
|
-
* @summary Overrides/extends decaf decoration with Fabric-specific functionality
|
|
1134
|
-
* @static
|
|
1135
|
-
* @override
|
|
1136
|
-
* @return {void}
|
|
1137
|
-
*/
|
|
1138
|
-
static decoration() {
|
|
1139
|
-
super.decoration();
|
|
1140
|
-
decoration_1.Decoration.flavouredAs(constants_1.FabricFlavour)
|
|
1141
|
-
.for(core_1.PersistenceKeys.CREATED_BY)
|
|
1142
|
-
.define({
|
|
1143
|
-
decorator: function createdBy() {
|
|
1144
|
-
return (0, decoration_1.apply)((0, db_decorators_1.onCreate)(createdByOnFabricCreateUpdate), (0, decoration_1.propMetadata)(core_1.PersistenceKeys.CREATED_BY, {}));
|
|
1145
|
-
},
|
|
1146
|
-
})
|
|
1147
|
-
.apply();
|
|
1148
|
-
decoration_1.Decoration.flavouredAs(constants_1.FabricFlavour)
|
|
1149
|
-
.for(core_1.PersistenceKeys.UPDATED_BY)
|
|
1150
|
-
.define({
|
|
1151
|
-
decorator: function createdBy() {
|
|
1152
|
-
return (0, decoration_1.apply)((0, db_decorators_1.onCreateUpdate)(createdByOnFabricCreateUpdate), (0, decoration_1.propMetadata)(core_1.PersistenceKeys.UPDATED_BY, {}));
|
|
1153
|
-
},
|
|
1154
|
-
})
|
|
1155
|
-
.apply();
|
|
1156
|
-
decoration_1.Decoration.flavouredAs(constants_1.FabricFlavour)
|
|
1157
|
-
.for(core_1.PersistenceKeys.COLUMN)
|
|
1158
|
-
.extend((0, fabric_contract_api_1.Property)())
|
|
1159
|
-
.apply();
|
|
1160
|
-
decoration_1.Decoration.flavouredAs(constants_1.FabricFlavour)
|
|
1161
|
-
.for(decorator_validation_1.ValidationKeys.DATE)
|
|
1162
|
-
.extend(function fabricProperty() {
|
|
1163
|
-
return (target, prop) => {
|
|
1164
|
-
(0, fabric_contract_api_1.Property)(prop, "string:date")(target, prop);
|
|
1165
|
-
};
|
|
1166
|
-
});
|
|
1167
|
-
decoration_1.Decoration.flavouredAs(constants_1.FabricFlavour)
|
|
1168
|
-
.for(core_1.PersistenceKeys.TABLE)
|
|
1169
|
-
.extend(function table(obj) {
|
|
1170
|
-
const chain = [];
|
|
1171
|
-
let current = typeof obj === "function"
|
|
1172
|
-
? decoration_1.Metadata.constr(obj)
|
|
1173
|
-
: decoration_1.Metadata.constr(obj.constructor);
|
|
1174
|
-
while (current && current !== Object && current.prototype) {
|
|
1175
|
-
chain.push(current);
|
|
1176
|
-
current = Object.getPrototypeOf(current);
|
|
1177
|
-
}
|
|
1178
|
-
console.log(chain.map((c) => c.name || c));
|
|
1179
|
-
// Apply from the base class down to the decorated class
|
|
1180
|
-
while (chain.length > 0) {
|
|
1181
|
-
const constructor = chain.pop();
|
|
1182
|
-
console.log(`Calling on ${constructor.name}`);
|
|
1183
|
-
(0, fabric_contract_api_1.Object)()(constructor);
|
|
1184
|
-
}
|
|
1185
|
-
return (0, fabric_contract_api_1.Object)()(obj);
|
|
1186
|
-
})
|
|
1187
|
-
.apply();
|
|
1188
|
-
}
|
|
1189
|
-
}
|
|
1190
|
-
exports.FabricContractAdapter = FabricContractAdapter;
|
|
1191
|
-
FabricContractAdapter.decoration();
|
|
1192
|
-
core_1.Adapter.setCurrent(constants_1.FabricFlavour);
|
|
1193
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29udHJhY3RBZGFwdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbnRyYWN0cy9Db250cmFjdEFkYXB0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBdUhBLHNFQW9CQztBQTNJRCx1REFLK0I7QUFDL0IseUVBQXVFO0FBRXZFLDJEQUEwRDtBQUMxRCwyREFZaUM7QUFDakMsNkRBSzZCO0FBQzdCLCtDQUFvRDtBQUNwRCx5Q0FnQ3dCO0FBQ3hCLDZFQUFzRTtBQU90RSwyRUFBNEQ7QUFDNUQseUVBQWtFO0FBQ2xFLHlEQUFvRDtBQUNwRCxpR0FBd0Y7QUFDeEYscURBTThCO0FBQzlCLDJFQUFvRTtBQUNwRSxtREFBdUQ7QUFFdkQseUVBQWtFO0FBVWxFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBeUJHO0FBQ0ksS0FBSyxVQUFVLDZCQUE2QixDQU1qRCxPQUFxQixFQUNyQixJQUFPLEVBQ1AsR0FBWSxFQUNaLEtBQVE7SUFFUixJQUFJLENBQUM7UUFDSCxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBbUIsQ0FBQztRQUN2RCxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFBbUIsQ0FBQztRQUMzQyw2REFBNkQ7SUFDL0QsQ0FBQztJQUFDLE9BQU8sQ0FBVSxFQUFFLENBQUM7UUFDcEIsTUFBTSxJQUFJLHVCQUFnQixDQUN4QixnRUFBZ0UsQ0FDakUsQ0FBQztJQUNKLENBQUM7QUFDSCxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9DRztBQUNILE1BQWEscUJBQXNCLFNBQVEsNEJBSTFDO2FBQ3lCLDRCQUF1QixHQUFHLGVBQWUsQ0FBQztJQUUxRCxNQUFNLENBQUMsNkJBQTZCLENBQzFDLFFBQWlCO1FBRWpCLElBQUksT0FBTyxRQUFRLEtBQUssUUFBUTtZQUFFLE9BQU8sU0FBUyxDQUFDO1FBQ25ELElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLHFCQUFxQixDQUFDLHVCQUF1QixDQUFDO1lBQ3JFLE9BQU8sU0FBUyxDQUFDO1FBQ25CLE1BQU0sR0FBRyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQ3hCLHFCQUFxQixDQUFDLHVCQUF1QixDQUFDLE1BQU0sQ0FDckQsQ0FBQztRQUNGLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMzQixPQUFPLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLElBQUksTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDdEUsQ0FBQztJQUVPLE1BQU0sQ0FBQyw2QkFBNkIsQ0FBQyxNQUFjO1FBQ3pELE9BQU8sR0FBRyxxQkFBcUIsQ0FBQyx1QkFBdUIsR0FBRyxNQUFNLEVBQUUsQ0FBQztJQUNyRSxDQUFDO0lBRWtCLFNBQVM7UUFDMUIsTUFBTSxJQUFJLHVCQUFnQixDQUFDLDZDQUE2QyxDQUFDLENBQUM7SUFDNUUsQ0FBQztJQUNEOztPQUVHO2FBQ1ksZ0JBQVcsR0FBRyxJQUFJLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQzthQUUzQixlQUFVLEdBQUcsSUFBSSw2REFBNkIsRUFBRSxDQUFDO0lBRTNFOzs7T0FHRztJQUNILElBQXVCLE9BQU87UUFDNUIsT0FBTyx1Q0FBcUIsQ0FBQztJQUMvQixDQUFDO0lBQ0Q7Ozs7O09BS0c7SUFDTSxVQUFVO1FBTWpCLE9BQU8sbURBQXFELENBQUM7SUFDL0QsQ0FBQztJQUVRLFNBQVMsQ0FDaEIsS0FBaUIsRUFDakIsSUFBWSxFQUNaLEtBQXFCO1FBRXJCLE9BQU8sSUFBSSxpREFBdUIsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztJQUMvRCxDQUFDO0lBRVEsS0FBSyxDQUFDLFFBQVEsQ0FBQyxPQUF3QjtRQUM5QyxPQUFPLElBQUksK0NBQXNCLENBQUMsT0FBTyxFQUFFLElBQVcsQ0FBQyxDQUFDO0lBQzFELENBQUM7SUFFa0IsUUFBUTtRQUN6QixPQUFPLElBQUksK0NBQXNCLEVBQUUsQ0FBQztJQUN0QyxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxZQUFZLEtBQVcsRUFBRSxLQUFjO1FBQ3JDLEtBQUssQ0FBQyxLQUFLLEVBQUUseUJBQWEsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRVEsR0FBRyxDQUFDLE1BQW9CLEVBQUUsR0FBRyxJQUFTO1FBQzdDLE9BQU8sS0FBSyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBRVMsZ0JBQWdCLENBQWtCLEtBQXFCO1FBQy9ELE1BQU0sQ0FBQyxHQUFHLElBQUksS0FBSyxFQUFFLENBQUM7UUFDdEIsT0FBTyxDQUFDLHFCQUFRLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FDOUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDVCxJQUFJLE9BQU8sQ0FBQyxDQUFDLENBQVksQ0FBQyxLQUFLLFdBQVc7Z0JBQ3hDLEdBQUcsQ0FBQyxDQUFZLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBWSxDQUFDLENBQUM7WUFDdEMsT0FBTyxHQUFHLENBQUM7UUFDYixDQUFDLEVBQ0QsRUFBMEIsQ0FDM0IsQ0FBQztJQUNKLENBQUM7SUFFRDs7Ozs7Ozs7O09BU0c7SUFDTSxLQUFLLENBQUMsTUFBTSxDQUNuQixLQUFxQixFQUNyQixFQUFrQixFQUNsQixLQUEwQixFQUMxQixHQUFHLElBQWtEO1FBRXJELE1BQU0sRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3BELElBQUksQ0FBQywwQkFBMEIsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDNUMsR0FBRyxDQUFDLElBQUksQ0FBQywrQkFBK0IsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNoRCxNQUFNLFNBQVMsR0FBRyw0QkFBSyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN6QyxNQUFNLFdBQVcsR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFNBQVMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDekUsTUFBTSxnQkFBZ0IsR0FBRyxHQUFHLENBQUMsY0FBYyxDQUFDLGtCQUFrQixDQUVqRCxDQUFDO1FBQ2QsTUFBTSxlQUFlLEdBQUcsR0FBRyxDQUFDLGlCQUFpQixJQUFJLENBQUMsZ0JBQWdCLENBQUM7UUFFbkUsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDdEIsSUFBSSxRQUFhLENBQUM7WUFDbEIsSUFBSSxDQUFDO2dCQUNILFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQ3BELENBQUM7WUFBQyxPQUFPLENBQVUsRUFBRSxDQUFDO2dCQUNwQix3Q0FBd0M7Z0JBQ3hDLENBQUMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQVUsQ0FBQyxDQUFDO2dCQUNoQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFlBQVksNkJBQWEsQ0FBQztvQkFBRSxNQUFNLENBQUMsQ0FBQztZQUM3QyxDQUFDO1lBQ0QsSUFBSSxRQUFRO2dCQUNWLE1BQU0sSUFBSSw2QkFBYSxDQUNyQixrQkFBa0IsRUFBRSxhQUFhLFNBQVMsaUJBQWlCLENBQzVELENBQUM7UUFDTixDQUFDO1FBRUQsSUFBSSxDQUFDO1lBQ0gsR0FBRyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsU0FBUyxrQkFBa0IsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUU3RCxJQUFJLGdCQUFnQixFQUFFLENBQUM7Z0JBQ3JCLEtBQUssR0FBRyxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxRQUFRLENBQ3RELFdBQVcsRUFDWCxLQUFLLEVBQ0wsR0FBRyxDQUNKLENBQUM7WUFDSixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUM5Qyw2Q0FBNkM7Z0JBQzdDLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztvQkFDckIsSUFDRSxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO3dCQUM5QixJQUFJLENBQUMsS0FBSyx5QkFBVyxDQUFDLEtBQUs7NEJBQUUsT0FBTyxLQUFLLENBQUM7d0JBQzFDLE9BQU8sQ0FBQyxDQUNOLFFBQVE7NEJBQ1IsQ0FBQyxJQUFJLFFBQVE7NEJBQ2IsUUFBUSxDQUFDLENBQVksQ0FBQyxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FDcEMsQ0FBQztvQkFDSixDQUFDLENBQUMsQ0FBQyxNQUFNO3dCQUVULEtBQUssR0FBRyxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxFQUFFLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFDekQsQ0FBQztnQkFFRCwyQkFBMkI7Z0JBQzNCLE1BQU0sSUFBSSxHQUFHLEdBQUcsQ0FBQyxlQUFlLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztnQkFDbkQsSUFBSSxJQUFJLEVBQUUsQ0FBQztvQkFDVCxLQUFLLE1BQU0sVUFBVSxJQUFJLElBQUksRUFBRSxDQUFDO3dCQUM5QixNQUFNLENBQUMsTUFBTSxDQUNYLEtBQUssRUFDTCxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUMsUUFBUSxDQUN4QyxXQUFXLEVBQ1gsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLEVBQVMsQ0FBQyxFQUMzQixHQUFHLENBQ0osQ0FDRixDQUFDO29CQUNKLENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBQUMsT0FBTyxDQUFVLEVBQUUsQ0FBQztZQUNwQixNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBVSxDQUFDLENBQUM7UUFDcEMsQ0FBQztRQUVELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVRLEtBQUssQ0FBQyxTQUFTLENBQ3RCLFNBQXlCLEVBQ3pCLEVBQW9CLEVBQ3BCLEtBQTRCLEVBQzVCLEdBQUcsSUFBMkM7UUFFOUMsSUFBSSxFQUFFLENBQUMsTUFBTSxLQUFLLEtBQUssQ0FBQyxNQUFNO1lBQzVCLE1BQU0sSUFBSSw2QkFBYSxDQUFDLDBDQUEwQyxDQUFDLENBQUM7UUFDdEUsTUFBTSxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDM0QsTUFBTSxVQUFVLEdBQUcsNEJBQUssQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDOUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsQ0FBQyxNQUFNLFlBQVksVUFBVSxRQUFRLENBQUMsQ0FBQztRQUMvRCxPQUFPLE9BQU8sQ0FBQyxHQUFHLENBQ2hCLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FDMUUsQ0FBQztJQUNKLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ00sS0FBSyxDQUFDLElBQUksQ0FDakIsS0FBcUIsRUFDckIsRUFBa0IsRUFDbEIsR0FBRyxJQUFrRDtRQUVyRCxNQUFNLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNsRCxHQUFHLENBQUMsSUFBSSxDQUFDLDZCQUE2QixJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzlDLE1BQU0sU0FBUyxHQUFHLDRCQUFLLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXpDLE1BQU0sV0FBVyxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsU0FBUyxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN6RSxNQUFNLGdCQUFnQixHQUFHLEdBQUcsQ0FBQyxjQUFjLENBQUMsa0JBQWtCLENBRWpELENBQUM7UUFDZCxNQUFNLFFBQVEsR0FBRyxHQUFHLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBd0IsQ0FBQztRQUNyRSxJQUFJLFFBQVEsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO1lBQ2pDLElBQUksQ0FBQztnQkFDSCxPQUFPLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLFNBQVMsQ0FDdEQsV0FBVyxFQUNYLEdBQUcsQ0FDSixDQUFDO1lBQ0osQ0FBQztZQUFDLE9BQU8sQ0FBVSxFQUFFLENBQUM7Z0JBQ3BCLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFVLENBQUMsQ0FBQztZQUNwQyxDQUFDO29CQUFTLENBQUM7Z0JBQ1QsR0FBRyxDQUFDLEdBQUcsQ0FBQyxRQUFlLEVBQUUsU0FBUyxDQUFDLENBQUM7Z0JBQ3BDLEdBQUcsQ0FBQyxHQUFHLENBQUMsa0JBQXlCLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFDaEQsQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLEtBQTBCLENBQUM7UUFFL0IsSUFBSSxDQUFDO1lBQ0gsS0FBSyxHQUFHLEdBQUcsQ0FBQyxpQkFBaUI7Z0JBQzNCLENBQUMsQ0FBQyxFQUFFO2dCQUNKLENBQUMsQ0FBQyxNQUFNLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQzdDLENBQUM7UUFBQyxPQUFPLENBQVUsRUFBRSxDQUFDO1lBQ3BCLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFVLENBQUMsQ0FBQztRQUNwQyxDQUFDO1FBRUQsTUFBTSxlQUFlLEdBQUcsSUFBSSxHQUFHLENBQVM7WUFDdEMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsRUFBRSxJQUFJLEVBQUUsQ0FBQztZQUNuQyxHQUFHLENBQUMsR0FBRyxDQUFDLHNCQUFzQixFQUFFLElBQUksRUFBRSxDQUFDO1NBQ3hDLENBQUMsQ0FBQztRQUNILEtBQUssTUFBTSxHQUFHLElBQUksZUFBZSxFQUFFLENBQUM7WUFDbEMsSUFBSSxDQUFDO2dCQUNILE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxTQUFTLENBQUMsV0FBVyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDL0UsQ0FBQztZQUFDLE9BQU8sQ0FBVSxFQUFFLENBQUM7Z0JBQ3BCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBVSxDQUFDLENBQUM7Z0JBQzNDLElBQUksTUFBTSxZQUFZLDZCQUFhO29CQUFFLFNBQVM7Z0JBQzlDLE1BQU0sTUFBTSxDQUFDO1lBQ2YsQ0FBQztRQUNILENBQUM7UUFDRCxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUMvQixNQUFNLElBQUksNkJBQWEsQ0FDckIsa0JBQWtCLEVBQUUsYUFBYSxTQUFTLGlCQUFpQixDQUM1RCxDQUFDO1FBQ0osQ0FBQztRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDTSxLQUFLLENBQUMsT0FBTyxDQUNwQixLQUFxQixFQUNyQixFQUFvQixFQUNwQixHQUFHLElBQWtEO1FBRXJELE1BQU0sRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3JELE1BQU0sU0FBUyxHQUFHLDRCQUFLLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3pDLEdBQUcsQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUMsTUFBTSxZQUFZLFNBQVMsUUFBUSxDQUFDLENBQUM7UUFDN0QsTUFBTSxvQkFBb0IsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLDRCQUE0QixDQUFDLElBQUksSUFBSSxDQUFDO1FBQzNFLE1BQU0sZUFBZSxHQUFHLENBQUMsb0JBQW9CLENBQUM7UUFFOUMsTUFBTSxnQkFBZ0IsR0FBRyxHQUFHLENBQUMsY0FBYyxDQUFDLGtCQUFrQixDQUVqRCxDQUFDO1FBQ2QsTUFBTSxRQUFRLEdBQUcsR0FBRyxDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQXdCLENBQUM7UUFFckUsTUFBTSxVQUFVLEdBQUcsS0FBSyxFQUN0QixLQUFxQixFQUNyQixFQUFrQixFQUNsQixHQUFHLElBQWtELEVBQ3JELEVBQUU7WUFDRixJQUFJLENBQUMsZ0JBQWdCO2dCQUNuQixNQUFNLElBQUksK0JBQWUsQ0FBQywyQ0FBMkMsQ0FBQyxDQUFDO1lBQ3pFLElBQUksQ0FBQztnQkFDSCxNQUFNLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQyxDQUFDO2dCQUNuRCxHQUFHLENBQUMsSUFBSSxDQUFDLDZCQUE2QixJQUFJLEVBQUUsQ0FBQyxDQUFDO2dCQUM5QyxNQUFNLFNBQVMsR0FBRyw0QkFBSyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFFekMsTUFBTSxXQUFXLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLEVBQUU7b0JBQ3pELE1BQU0sQ0FBQyxFQUFFLENBQUM7aUJBQ1gsQ0FBQyxDQUFDO2dCQUVILE9BQU8sTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLGdCQUFnQixDQUFDLENBQUMsU0FBUyxDQUN0RCxXQUFXLEVBQ1gsR0FBRyxDQUNKLENBQUM7WUFDSixDQUFDO1lBQUMsT0FBTyxDQUFVLEVBQUUsQ0FBQztnQkFDcEIsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQVUsQ0FBQyxDQUFDO1lBQ3BDLENBQUM7UUFDSCxDQUFDLENBQUM7UUFFRixJQUFJLENBQUM7WUFDSCxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUMsR0FBRyxDQUNsQixDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLENBQ1YsUUFBUSxJQUFJLGdCQUFnQjtnQkFDMUIsQ0FBQyxDQUFDLFVBQVUsQ0FDUixLQUFLLEVBQ0wsQ0FBQyxFQUNELEdBQUcsSUFBSSxFQUNQLEdBQUcsQ0FBQyxRQUFRLENBQUMsRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FDckM7Z0JBQ0gsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBRSxHQUFHLElBQUksRUFBRSxHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FDekUsQ0FBQztZQUVGLE1BQU0sU0FBUyxHQUFHLGVBQWU7Z0JBQy9CLENBQUMsQ0FBQyxNQUFNLElBQUEsc0JBQWUsRUFBQyxLQUFLLEVBQUUsSUFBSSxDQUFDO2dCQUNwQyxDQUFDLENBQUMsTUFBTSxJQUFBLHNCQUFlLEVBQUMsS0FBSyxDQUFDLENBQUM7WUFDakMsT0FBTyxJQUFBLGdDQUF5QixFQUM5QixTQUFTLEVBQ1QsZUFBZSxFQUNmLEdBQUcsRUFDSCxxQ0FBcUIsQ0FBQyxRQUFRLENBQy9CLENBQUM7UUFDSixDQUFDO1FBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNYLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFVLENBQUMsQ0FBQztRQUNwQyxDQUFDO2dCQUFTLENBQUM7WUFDVCxHQUFHLENBQUMsR0FBRyxDQUFDLFFBQWUsRUFBRSxTQUFTLENBQUMsQ0FBQztZQUNwQyxHQUFHLENBQUMsR0FBRyxDQUFDLGtCQUF5QixFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ2hELENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ00sS0FBSyxDQUFDLE1BQU0sQ0FDbkIsS0FBcUIsRUFDckIsRUFBa0IsRUFDbEIsS0FBMEIsRUFDMUIsR0FBRyxJQUFrRDtRQUVyRCxNQUFNLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUVwRCxJQUFJLENBQUMsMEJBQTBCLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQzVDLEdBQUcsQ0FBQyxJQUFJLENBQUMsK0JBQStCLElBQUksRUFBRSxDQUFDLENBQUM7UUFDaEQsTUFBTSxTQUFTLEdBQUcsNEJBQUssQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDekMsTUFBTSxXQUFXLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3pFLE1BQU0sZ0JBQWdCLEdBQUcsR0FBRyxDQUFDLGNBQWMsQ0FBQyxrQkFBa0IsQ0FFakQsQ0FBQztRQUVkLElBQUksQ0FBQztZQUNILEdBQUcsQ0FBQyxJQUFJLENBQUMscUJBQXFCLFNBQVMsa0JBQWtCLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFFL0QsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO2dCQUNyQixLQUFLLEdBQUcsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLGdCQUFnQixDQUFDLENBQUMsUUFBUSxDQUN0RCxXQUFXLEVBQ1gsS0FBSyxFQUNMLEdBQUcsQ0FDSixDQUFDO1lBQ0osQ0FBQztpQkFBTSxDQUFDO2dCQUNOLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDOUMscUJBQXFCO2dCQUNyQixJQUNFLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7b0JBQzlCLElBQUksQ0FBQyxLQUFLLHlCQUFXLENBQUMsS0FBSzt3QkFBRSxPQUFPLEtBQUssQ0FBQztvQkFDMUMsT0FBTyxDQUFDLENBQ04sUUFBUTt3QkFDUixDQUFDLElBQUksUUFBUTt3QkFDYixRQUFRLENBQUMsQ0FBWSxDQUFDLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUNwQyxDQUFDO2dCQUNKLENBQUMsQ0FBQyxDQUFDLE1BQU07b0JBRVQsS0FBSyxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLEVBQUUsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO2dCQUV2RCwyQkFBMkI7Z0JBQzNCLE1BQU0sSUFBSSxHQUFHLEdBQUcsQ0FBQyxlQUFlLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztnQkFDbkQsSUFBSSxJQUFJLEVBQUUsQ0FBQztvQkFDVCxLQUFLLE1BQU0sVUFBVSxJQUFJLElBQUksRUFBRSxDQUFDO3dCQUM5QixNQUFNLENBQUMsTUFBTSxDQUNYLEtBQUssRUFDTCxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUMsUUFBUSxDQUN4QyxXQUFXLEVBQ1gsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLEVBQVMsQ0FBQyxFQUMzQixHQUFHLENBQ0osQ0FDRixDQUFDO29CQUNKLENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBQUMsT0FBTyxDQUFVLEVBQUUsQ0FBQztZQUNwQixNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBVSxDQUFDLENBQUM7UUFDcEMsQ0FBQztRQUVELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSCxLQUFLLENBQUMsTUFBTSxDQUNWLEtBQXFCLEVBQ3JCLEVBQWtCLEVBQ2xCLEdBQUcsSUFBa0Q7UUFFckQsTUFBTSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFcEQsSUFBSSxDQUFDLDBCQUEwQixDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztRQUM1QyxNQUFNLFNBQVMsR0FBRyw0QkFBSyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUV6QyxNQUFNLFdBQVcsR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFNBQVMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDekUsTUFBTSxnQkFBZ0IsR0FBRyxHQUFHLENBQUMsY0FBYyxDQUFDLGtCQUFrQixDQUVqRCxDQUFDO1FBQ2QsSUFBSSxLQUEwQixDQUFDO1FBRS9CLElBQUksZ0JBQWdCLEVBQUUsQ0FBQztZQUNyQixJQUFJLENBQUM7Z0JBQ0gsS0FBSyxHQUFHLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLFNBQVMsQ0FDdkQsV0FBVyxFQUNYLEdBQUcsQ0FDSixDQUFDO2dCQUNGLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxXQUFXLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDeEUsQ0FBQztZQUFDLE9BQU8sQ0FBVSxFQUFFLENBQUM7Z0JBQ3BCLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFVLENBQUMsQ0FBQztZQUNwQyxDQUFDO1FBQ0gsQ0FBQzthQUFNLENBQUM7WUFDTixJQUFJLENBQUM7Z0JBQ0gsS0FBSyxHQUFHLEdBQUcsQ0FBQyxpQkFBaUI7b0JBQzNCLENBQUMsQ0FBQyxFQUFFO29CQUNKLENBQUMsQ0FBQyxNQUFNLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxFQUFFLEdBQUcsQ0FBQyxDQUFDO2dCQUMzQyxJQUFJLENBQUMsR0FBRyxDQUFDLGlCQUFpQixFQUFFLENBQUM7b0JBQzNCLEdBQUcsQ0FBQyxLQUFLLENBQUMsa0JBQWtCLFdBQVcscUJBQXFCLENBQUMsQ0FBQztvQkFDOUQsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFDM0MsQ0FBQztZQUNILENBQUM7WUFBQyxPQUFPLENBQVUsRUFBRSxDQUFDO2dCQUNwQixNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBVSxDQUFDLENBQUM7WUFDcEMsQ0FBQztZQUVELE1BQU0sV0FBVyxHQUFHLEdBQUcsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1lBQzdDLElBQUksV0FBVyxJQUFJLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDdEMsS0FBSyxNQUFNLEdBQUcsSUFBSSxXQUFXLEVBQUUsQ0FBQztvQkFDOUIsR0FBRyxDQUFDLEtBQUssQ0FDUCx1QkFBdUIsR0FBRyxxQkFBcUIsV0FBVyxrQkFBa0IsQ0FDN0UsQ0FBQztvQkFDRixNQUFNLENBQUMsTUFBTSxDQUNYLEtBQUssRUFDTCxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsU0FBUyxDQUFDLFdBQVcsRUFBRSxHQUFHLENBQUMsQ0FDdkQsQ0FBQztvQkFDRixHQUFHLENBQUMsS0FBSyxDQUNQLCtCQUErQixHQUFHLGlCQUFpQixXQUFXLEVBQUUsQ0FDakUsQ0FBQztvQkFDRixNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsV0FBVyxDQUFDLFdBQVcsRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFDM0QsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRVMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxFQUFVLEVBQUUsT0FBOEI7UUFDcEUsTUFBTSxPQUFPLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRUQsVUFBVSxDQUFDLFVBQWtCO1FBQzNCLE1BQU0sVUFBVSxHQUFHO1lBQ2pCLElBQUksQ0FBQyxRQUFRO1lBQ2IsSUFBSSxDQUFDLFNBQVM7WUFDZCxJQUFJLENBQUMsV0FBVztZQUNoQixJQUFJLENBQUMsV0FBVztZQUNoQixJQUFJLENBQUMsb0JBQW9CO1NBQzFCLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdkIsT0FBTyxJQUFJLEtBQUssQ0FBQyxJQUFJLEVBQUU7WUFDckIsR0FBRyxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsUUFBUTtnQkFDeEIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsSUFBYyxDQUFDO29CQUN0QyxPQUFPLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQztnQkFDN0MsT0FBTyxJQUFJLEtBQUssQ0FBRSxNQUFjLENBQUMsSUFBSSxDQUFDLEVBQUU7b0JBQ3RDLEtBQUssQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLE9BQU8sRUFBRSxRQUFRO3dCQUMvQixRQUFRLElBQUksRUFBRSxDQUFDOzRCQUNiLEtBQUssVUFBVSxDQUFDLENBQUMsQ0FBQztnQ0FDaEIsMkZBQTJGO2dDQUMzRixNQUFNLENBQUMsRUFBRSxFQUFFLEtBQUssRUFBRSxHQUFHLENBQUMsR0FBRyxRQUFRLENBQUM7Z0NBQ2xDLE1BQU0sR0FBRyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO2dDQUNqQyxHQUFHLENBQUMsS0FBSyxDQUNQLG9CQUFvQixVQUFVLFFBQVEsRUFBRSxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQ3RELENBQUM7Z0NBQ0YsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FDdEIscUJBQXFCLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FDeEMsS0FBYyxFQUNkLEtBQUssQ0FDTixDQUNGLENBQUM7Z0NBQ0YsTUFBTSxHQUFHLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLFFBQVEsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO2dDQUMvRCxPQUFPLEtBQUssQ0FBQzs0QkFDZixDQUFDOzRCQUNELEtBQUssYUFBYSxDQUFDLENBQUMsQ0FBQztnQ0FDbkIsc0VBQXNFO2dDQUN0RSxNQUFNLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxHQUFHLFFBQVEsQ0FBQztnQ0FDM0IsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7Z0NBQ2pDLEdBQUcsQ0FBQyxLQUFLLENBQ1AscUJBQXFCLFVBQVUsUUFBUSxFQUFFLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FDdkQsQ0FBQztnQ0FDRixNQUFNLEdBQUcsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO2dDQUM1RCxPQUFPOzRCQUNULENBQUM7NEJBQ0QsS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDO2dDQUNqQixnRUFBZ0U7Z0NBQ2hFLE1BQU0sQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLEdBQUcsUUFBUSxDQUFDO2dDQUMzQixNQUFNLEdBQUcsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQ0FDakMsR0FBRyxDQUFDLEtBQUssQ0FDUCxxQkFBcUIsVUFBVSxRQUFRLEVBQUUsQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUN2RCxDQUFDO2dDQUNGLE1BQU0sSUFBSSxHQUFHLE1BQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsVUFBVSxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dDQUMzRCxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLE1BQU07b0NBQ2xDLE1BQU0sSUFBSSw2QkFBYSxDQUFDLGtCQUFrQixFQUFFLFlBQVksQ0FBQyxDQUFDO2dDQUM1RCxJQUFJLENBQUM7b0NBQ0gsT0FBTyxxQkFBcUIsQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUNqRCxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUN0QixDQUFDO2dDQUNKLENBQUM7Z0NBQUMsTUFBTSxDQUFDO29DQUNQLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztnQ0FDL0IsQ0FBQzs0QkFDSCxDQUFDOzRCQUNELEtBQUssYUFBYSxDQUFDLENBQUMsQ0FBQztnQ0FDbkIsTUFBTSxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxRQUFRLENBQUM7Z0NBQzNDLE1BQU0sRUFBRSxHQUFHLEVBQUUsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO2dDQUM5QyxJQUFJLENBQUM7b0NBQ0gsR0FBRyxDQUFDLEtBQUssQ0FDUCx1QkFBdUIsVUFBVSxRQUFRLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FDcEUsQ0FBQztvQ0FDRixNQUFNLEdBQUcsR0FBRyxNQUFNLElBQUksQ0FBQyx5QkFBeUIsQ0FDOUMsVUFBVSxFQUNWLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQ3pCLENBQUM7b0NBQ0YsR0FBRyxDQUFDLE9BQU8sQ0FDVCw0QkFBNEIsVUFBVSxXQUFXLENBQ2xELENBQUM7b0NBQ0YsT0FBTyxHQUFHLENBQUMsUUFBUSxJQUFJLEdBQUcsQ0FBQztnQ0FDN0IsQ0FBQztnQ0FBQyxPQUFPLENBQU0sRUFBRSxDQUFDO29DQUNoQixHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO29DQUNiLE9BQU8sRUFBRSxDQUFDO2dDQUNaLENBQUM7NEJBQ0gsQ0FBQzs0QkFDRCxLQUFLLHNCQUFzQixDQUFDLENBQUMsQ0FBQztnQ0FDNUIsTUFBTSxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxRQUFRLENBQUM7Z0NBQ2xFLE1BQU0sRUFBRSxHQUFHLEVBQUUsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO2dDQUM5QyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUM7Z0NBQ25ELE1BQU0sS0FBSyxHQUF3QixFQUFFLEdBQUcsUUFBUSxFQUFFLENBQUM7Z0NBQ25ELE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztnQ0FDL0IsTUFBTSxVQUFVLEdBQ2QsTUFBTSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsSUFBSSxTQUFTLElBQUksQ0FBQztvQ0FDM0MsQ0FBQyxDQUFDLFNBQVM7b0NBQ1gsQ0FBQyxDQUFDLFNBQVMsQ0FBQztnQ0FDaEIsTUFBTSxlQUFlLEdBQ25CLHFCQUFxQixDQUFDLDZCQUE2QixDQUFDLFFBQVEsQ0FBQztvQ0FDN0QsVUFBVTtvQ0FDVixDQUFDLENBQUM7Z0NBQ0osTUFBTSxpQkFBaUIsR0FDckIsUUFBUSxLQUFLLFNBQVM7b0NBQ3RCLFFBQVEsS0FBSyxJQUFJO29DQUNqQixRQUFRLEtBQUssRUFBRTtvQ0FDZixPQUFPLFFBQVEsS0FBSyxRQUFRO29DQUM1QixDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMscUJBQXFCLENBQUMsdUJBQXVCLENBQUMsQ0FBQztnQ0FDdEUsbUZBQW1GO2dDQUNuRixnRkFBZ0Y7Z0NBQ2hGLEtBQUssQ0FBQyxLQUFLLEdBQUcsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsUUFBUSxHQUFHLENBQUMsQ0FBQztnQ0FDMUQsSUFBSSxpQkFBaUIsRUFBRSxDQUFDO29DQUN0QixLQUFLLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQztvQ0FDckMsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDO2dDQUNwQixDQUFDO3FDQUFNLENBQUM7b0NBQ04sT0FBTyxLQUFLLENBQUMsUUFBUSxDQUFDO29DQUN0QixJQUFJLGVBQWUsR0FBRyxDQUFDLEVBQUUsQ0FBQzt3Q0FDeEIsS0FBSyxDQUFDLElBQUksR0FBRyxlQUFlLENBQUM7b0NBQy9CLENBQUM7eUNBQU0sQ0FBQzt3Q0FDTixPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUM7b0NBQ3BCLENBQUM7Z0NBQ0gsQ0FBQztnQ0FDRCxHQUFHLENBQUMsS0FBSyxDQUNQLHVCQUF1QixVQUFVLFFBQVEsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUNqRSxDQUFDO2dDQUNGLE1BQU0sUUFBUSxHQUFHLE1BQ2YsSUFDRCxDQUFDLHlCQUF5QixDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7Z0NBQy9ELE1BQU0sUUFBUSxHQUNaLENBQUUsUUFBZ0IsQ0FBQyxRQUFRO29DQUN6QixRQUFRLENBQWlDLENBQUM7Z0NBQzlDLE1BQU0sZ0JBQWdCLEdBQ25CLFFBQWdCLENBQUMsUUFBUSxJQUFLLFFBQWdCLENBQUMsUUFBUSxJQUFJLEVBQUUsQ0FBQztnQ0FDakUsTUFBTSxnQkFBZ0IsR0FDcEIsT0FBTyxnQkFBZ0IsQ0FBQyxRQUFRLEtBQUssUUFBUTtvQ0FDM0MsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLFFBQVE7b0NBQzNCLENBQUMsQ0FBQyxFQUFFLENBQUM7Z0NBRVQsR0FBRyxDQUFDLE9BQU8sQ0FBQyw0QkFBNEIsVUFBVSxXQUFXLENBQUMsQ0FBQztnQ0FDL0QsTUFBTSxLQUFLLEdBQTBDLEVBQUUsQ0FBQztnQ0FDeEQsSUFBSSxPQUFPLEdBQUcsS0FBSyxDQUFDO2dDQUVwQixJQUFJLENBQUM7b0NBQ0gsT0FBTyxJQUFJLEVBQUUsQ0FBQzt3Q0FDWixNQUFNLEdBQUcsR0FBRyxNQUFNLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQzt3Q0FDbEMsSUFBSSxHQUFHLENBQUMsSUFBSTs0Q0FBRSxNQUFNO3dDQUVwQixJQUFJLEdBQUcsQ0FBQyxLQUFLLElBQUksR0FBRyxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQzs0Q0FDakMsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFhLENBQUM7NENBQ3BDLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxRQUFRLEVBQUUsQ0FBQztnREFDNUIsS0FBSyxDQUFDLElBQUksQ0FBQztvREFDVCxHQUFHO29EQUNILEtBQUssRUFBRSxNQUFNLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDO3dEQUNyQyxDQUFDLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxLQUFLO3dEQUNqQixDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FDUixHQUFHLENBQUMsS0FBSyxDQUFDLEtBQWEsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQzFDO2lEQUNOLENBQUMsQ0FBQzs0Q0FDTCxDQUFDO2lEQUFNLENBQUM7Z0RBQ04sT0FBTyxHQUFHLElBQUksQ0FBQztnREFDZixNQUFNLENBQUMsYUFBYTs0Q0FDdEIsQ0FBQzt3Q0FDSCxDQUFDO29DQUNILENBQUM7Z0NBQ0gsQ0FBQzt3Q0FBUyxDQUFDO29DQUNULE1BQU0sUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDO2dDQUN6QixDQUFDO2dDQUVELDBEQUEwRDtnQ0FDMUQsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDO2dDQUNaLE1BQU0sYUFBYSxHQUFHO29DQUNwQixLQUFLLENBQUMsSUFBSTt3Q0FDUixJQUFJLEdBQUcsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7NENBQ3ZCLE9BQU8sRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDO3dDQUM5QyxDQUFDO3dDQUNELE9BQU8sRUFBRSxLQUFLLEVBQUUsU0FBZ0IsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUM7b0NBQ2pELENBQUM7b0NBQ0QsS0FBSyxDQUFDLEtBQUssS0FBSSxDQUFDO2lDQUNqQixDQUFDO2dDQUVGLE9BQU87b0NBQ0wsUUFBUSxFQUNOLGFBQXdEO29DQUMxRCxRQUFRLEVBQUU7d0NBQ1IsbUJBQW1CLEVBQUUsS0FBSyxDQUFDLE1BQU07d0NBQ2pDLFFBQVEsRUFDTixnQkFBZ0I7NENBQ2hCLENBQUMsT0FBTztnREFDTixDQUFDLENBQUMscUJBQXFCLENBQUMsNkJBQTZCLENBQ2pELGVBQWUsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUMvQjtnREFDSCxDQUFDLENBQUMsRUFBRSxDQUFDO3FDQUNWO2lDQUNGLENBQUM7NEJBQ0osQ0FBQzs0QkFDRDtnQ0FDRSxNQUFNLElBQUksNkJBQWEsQ0FDckIsK0JBQStCLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUM5QyxDQUFDO3dCQUNOLENBQUM7b0JBQ0gsQ0FBQztpQkFDRixDQUFDLENBQUM7WUFDTCxDQUFDO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVTLEtBQUssQ0FBQyxRQUFRLENBQ3RCLEVBQVUsRUFDVixLQUEwQixFQUMxQixHQUEwQjtRQUUxQixJQUFJLElBQVksQ0FBQztRQUVqQixJQUFJLENBQUM7WUFDSCxJQUFJLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FDaEIscUJBQXFCLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxLQUFjLEVBQUUsS0FBSyxDQUFDLENBQ2xFLENBQUM7UUFDSixDQUFDO1FBQUMsT0FBTyxDQUFVLEVBQUUsQ0FBQztZQUNwQixNQUFNLElBQUksa0NBQWtCLENBQzFCLHNDQUFzQyxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQ2pELENBQUM7UUFDSixDQUFDO1FBQ0QsTUFBTSxHQUFHLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsUUFBUSxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFFN0MsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRVMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxFQUFVLEVBQUUsR0FBMEI7UUFDOUQsSUFBSSxNQUFXLENBQUM7UUFFaEIsTUFBTSxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDbkQsTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDaEUsSUFBSSxDQUFDLEdBQUc7WUFBRSxNQUFNLElBQUksNkJBQWEsQ0FBQyxrQkFBa0IsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUNwRSxHQUFHLENBQUMsS0FBSyxDQUFDLDRCQUE0QixFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzVDLElBQUksQ0FBQztZQUNILE1BQU0sR0FBRyxxQkFBcUIsQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFBQyxPQUFPLENBQVUsRUFBRSxDQUFDO1lBQ3BCLE1BQU0sSUFBSSxrQ0FBa0IsQ0FBQywyQkFBMkIsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUMvRCxDQUFDO1FBRUQsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUVTLEtBQUssQ0FBQyxXQUFXLENBQ3pCLElBQW1CLEVBQ25CLFFBQWE7SUFDYiw2REFBNkQ7SUFDN0QsR0FBRyxJQUEyQztRQUU5QyxPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBQ3ZELENBQUM7SUFFUyxLQUFLLENBQUMsb0JBQW9CLENBQ2xDLElBQW1CLEVBQ25CLFFBQWEsRUFDYixRQUFnQixHQUFHLEVBQ25CLElBQWEsRUFDYixRQUEwQjtJQUMxQiw2REFBNkQ7SUFDN0QsR0FBRyxJQUFXO1FBRWQsT0FBTyxJQUFJLENBQUMsNEJBQTRCLENBQ3RDLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLEVBQ3hCLEtBQUssRUFDTCxRQUFRLEVBQUUsUUFBUSxFQUFFLENBQ3JCLENBQUM7SUFDSixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDTyxNQUFNLENBQUMsTUFBa0I7UUFDakMsT0FBTyxxQkFBcUIsQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzFELENBQUM7SUFFRDs7Ozs7Ozs7O09BU0c7SUFDZ0IsS0FBSyxDQUFDLEtBQUssQ0FDNUIsU0FBMkIsRUFDM0IsS0FBaUMsRUFDakMsS0FBdUU7UUFFdkUsSUFBSSxTQUFTLEdBQUc7WUFDZCxVQUFVLEVBQUUsS0FBSztZQUNqQixvQkFBb0IsRUFBRSxLQUFLO1lBQzNCLGVBQWUsRUFBRSxLQUFLO1NBQ3ZCLENBQUM7UUFDRixJQUFJLEtBQUssWUFBWSx1Q0FBcUIsSUFBSSxLQUFLLFlBQVksY0FBTyxFQUFFLENBQUM7WUFDdkUsS0FBSyxHQUFHLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUM5QixDQUFDO1FBRUQsU0FBUyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQzVDLE1BQU0sYUFBYSxHQUNoQixLQUErQixDQUFDLElBQUksSUFBSyxLQUFhLENBQUMsSUFBSSxDQUFDO1FBQy9ELE1BQU0saUJBQWlCLEdBQ3BCLEtBQStCLENBQUMsUUFBUTtZQUN4QyxLQUFhLENBQUMsY0FBYyxDQUFDO1FBQ2hDLElBQUksYUFBYSxJQUFJLGlCQUFpQixFQUFFLENBQUM7WUFDdkMsTUFBTSxJQUFJLEdBQUcsYUFBYSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3JDLE1BQU0sQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFO2dCQUN2QixJQUFJLEVBQUUsYUFBYTtnQkFDbkIsUUFBUSxFQUFFLGlCQUFpQjtnQkFDM0IsSUFBSSxFQUFFLGlCQUFpQixDQUFDLFVBQVUsRUFBRSxDQUFDLFFBQVEsRUFBRTtnQkFDL0MsS0FBSyxFQUFFLGlCQUFpQixDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQztnQkFDbkQsTUFBTSxFQUFFLGlCQUFPLENBQUMsR0FBRyxDQUNqQixTQUFTLEVBQ1Q7b0JBQ0UsUUFBUSxFQUFFLEtBQUs7b0JBQ2YsU0FBUyxFQUFFLEtBQUs7b0JBQ2hCLGFBQWEsRUFBRSxJQUFJO2lCQUNwQixFQUNELEtBQUssQ0FDTjtnQkFDRCxhQUFhLEVBQUUsSUFBSTthQUNwQixDQUFDLENBQUM7UUFDTCxDQUFDO2FBQU0sQ0FBQztZQUNOLFNBQVMsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxLQUFLLElBQUksRUFBRSxDQUFDLENBQUM7UUFDcEQsQ0FBQztRQUVELE9BQU8sQ0FBQyxNQUFNLEtBQUssQ0FBQyxLQUFLLENBQ3ZCLFNBQVMsRUFDVCxLQUFLLEVBQ0wsU0FBZ0IsQ0FDakIsQ0FBd0IsQ0FBQztJQUM1QixDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsNkRBQTZEO0lBQ25ELEtBQUssQ0FBSSxNQUFzQjtRQUN2QyxPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDcEMsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0F3Qkc7SUFDTyxLQUFLLENBQUMsY0FBYyxDQUM1QixHQUFXLEVBQ1gsUUFBc0MsRUFDdEMsU0FBUyxHQUFHLEtBQUs7UUFFakIsTUFBTSxVQUFVLEdBQUcsRUFBRSxDQUFDO1FBQ3RCLElBQUksR0FBRyxHQUFrQyxNQUFNLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUMvRCxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2pCLElBQUksR0FBRyxDQUFDLEtBQUssSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUFDO2dCQUM1QyxJQUFJLE9BQU8sR0FBUSxFQUFFLENBQUM7Z0JBQ3RCLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7Z0JBQzVDLElBQUksU0FBUyxDQUFDLDBCQUEwQixFQUFFLENBQUM7b0JBQ3pDLE9BQU8sQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUM7b0JBQzlCLE9BQU8sQ0FBQyxTQUFTLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUM7b0JBQ3hDLElBQUksQ0FBQzt3QkFDSCxPQUFPLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7b0JBQy9ELENBQUM7b0JBQUMsT0FBTyxHQUFRLEVBQUUsQ0FBQzt3QkFDbEIsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQzt3QkFDZixPQUFPLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztvQkFDbkQsQ0FBQztnQkFDSCxDQUFDO3FCQUFNLENBQUM7b0JBQ04sSUFBSSxDQUFDO3dCQUNILE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO29CQUN6RCxDQUFDO29CQUFDLE9BQU8sR0FBUSxFQUFFLENBQUM7d0JBQ2xCLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7d0JBQ2YsT0FBTyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztvQkFDN0MsQ0FBQztnQkFDSCxDQUFDO2dCQUNELFVBQVUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDM0IsQ0FBQztZQUNELEdBQUcsR0FBRyxNQUFNLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUM5QixDQUFDO1FBQ0QsR0FBRyxDQUFDLEtBQUssQ0FBQywwQkFBMEIsVUFBVSxDQUFDLE1BQU0sVUFBVSxDQUFDLENBQUM7UUFDakUsTUFBTSxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDdkIsT0FBTyxVQUFVLENBQUM7SUFDcEIsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0EyQkc7SUFDSCxLQUFLLENBQUMsR0FBRyxDQUNQLFFBQW9CLEVBQ3BCLFdBQWMsSUFBUyxFQUN2QixHQUFHLElBQTJDO1FBRTlDLE1BQU0sRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUUxRCxNQUFNLGdCQUFnQixHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDO1FBQzFELE1BQU0sZUFBZSxHQUFHLGdCQUFnQixJQUFJLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQztRQUVsRSxNQUFNLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxHQUFHLFFBQVEsQ0FBQztRQUNqQyxNQUFNLFFBQVEsR0FBRyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDdEMsTUFBTSxnQkFBZ0IsR0FBRyxPQUFPLENBQUMsS0FBSyxJQUFJLElBQUksSUFBSSxRQUFRLENBQUMsQ0FBQztRQUM1RCxJQUFJLElBQUksR0FBRyxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLFNBQStCLEVBQUUsQ0FBQztRQUVuRSxpRUFBaUU7UUFDakUsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ3JCLElBQUksUUFBc0MsQ0FBQztZQUMzQyxJQUFJLEtBQUssSUFBSSxJQUFJLEVBQUUsQ0FBQztnQkFDbEIsT0FBTyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQ3pCLE9BQU8sUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUN4QixHQUFHLENBQUMsS0FBSyxDQUNQLGdEQUFnRCxLQUFLLFdBQVcsSUFBSSxFQUFFLENBQ3ZFLENBQUM7Z0JBQ0YsTUFBTSxRQUFRLEdBQ1osQ0FBQyxNQUFNLElBQUksQ0FBQyxvQkFBb0IsQ0FDOUIsR0FBRyxDQUFDLElBQUksRUFDUixRQUFRLEVBQ1IsS0FBSyxJQUFJLE1BQU0sQ0FBQyxTQUFTLEVBQ3hCLElBQVksRUFBRSxRQUFRLEVBQUUsRUFDekIsUUFBUSxFQUNSLEdBQUcsQ0FBQyxHQUE0QixDQUFDLENBQ2xDLENBQXFELENBQUM7Z0JBQ3pELElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUM7Z0JBQzNDLFFBQVEsR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDO2dCQUM3QixHQUFHLENBQUMsS0FBSyxDQUFDLGtDQUFrQyxDQUFDLENBQUM7WUFDaEQsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLEdBQUcsQ0FBQyxLQUFLLENBQUMsb0NBQW9DLENBQUMsQ0FBQztnQkFDaEQsUUFBUSxHQUFHLENBQUMsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUNoQyxHQUFHLENBQUMsSUFBSSxFQUNSLFFBQVEsRUFDUixHQUFHLENBQ0osQ0FBaUMsQ0FBQztZQUNyQyxDQUFDO1lBQ0QsR0FBRyxDQUFDLEtBQUssQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFDO1lBRS9DLElBQUksQ0FBQyxJQUFJLEdBQUcsQ0FBQyxNQUFNLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQyxDQUFRLENBQUM7WUFDOUQsR0FBRyxDQUFDLEtBQUssQ0FDUCxhQUFhLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQ3ZFLENBQUM7UUFDSixDQUFDO2FBQU0sQ0FBQztZQUNOLHFFQUFxRTtZQUNyRSwwREFBMEQ7WUFDMUQsSUFBSSxLQUFLLElBQUksSUFBSSxFQUFFLENBQUM7Z0JBQ2xCLE9BQU8sUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUN6QixPQUFPLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUMxQixDQUFDO1lBQ0QsR0FBRyxDQUFDLEtBQUssQ0FBQyxzREFBc0QsQ0FBQyxDQUFDO1FBQ3BFLENBQUM7UUFFRCxNQUFNLFdBQVcsR0FBRyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLGtCQUFrQixFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztRQUU1RSxJQUFJLFdBQVcsSUFBSSxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDdEMsd0RBQXdEO1lBQ3hELE1BQU0sZUFBZSxHQUFHLEVBQUUsR0FBRyxRQUFRLEVBQUUsQ0FBQztZQUN4QyxJQUFJLEtBQUs7Z0JBQUUsZUFBZSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7WUFDekMsSUFBSSxJQUFJO2dCQUFFLGVBQWUsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1lBQ3RDLElBQUksUUFBUTtnQkFBRSxlQUFlLENBQUMsVUFBVSxDQUFDLEdBQUcsUUFBUSxDQUFDO1lBRXJELE1BQU0sVUFBVSxHQUFVLEVBQUUsQ0FBQztZQUM3QixLQUFLLE1BQU0sVUFBVSxJQUFJLFdBQVcsRUFBRSxDQUFDO2dCQUNyQyxHQUFHLENBQUMsS0FBSyxDQUFDLGlCQUFpQixVQUFVLEVBQUUsQ0FBQyxDQUFDO2dCQUN6QyxNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxDQUNwRCxFQUFFLEdBQUcsZUFBZSxFQUFFLEVBQ3RCLEtBQUssRUFDTCxJQUFJLEVBQ0osR0FBRyxPQUFPLENBQ1gsQ0FBQztnQkFDRixHQUFHLENBQUMsT0FBTyxDQUNULFlBQWEsUUFBNkIsQ0FBQyxNQUFNLFNBQVMsVUFBVSxFQUFFLENBQ3ZFLENBQUM7Z0JBQ0YsVUFBVSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUM1QixDQUFDO1lBQ0QsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO2dCQUNyQiw4REFBOEQ7Z0JBQzlELGlFQUFpRTtnQkFDakUsSUFBSSxlQUFlLEVBQUUsQ0FBQztvQkFDcEIsSUFBSSxHQUFJLFVBQVUsQ0FBQyxDQUFDLENBQVMsSUFBSSxJQUFJLENBQUM7Z0JBQ3hDLENBQUM7cUJBQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsTUFBTSxJQUFJLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztvQkFDbkQsK0RBQStEO29CQUMvRCxxREFBcUQ7b0JBQ3JELElBQUksR0FBRyxVQUFVLENBQUMsQ0FBQyxDQUFRLENBQUM7Z0JBQzlCLENBQUM7WUFDSCxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sNkRBQTZEO2dCQUM3RCxJQUFJLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsRUFBRTtvQkFDckMsSUFBSSxDQUFDLEdBQUc7d0JBQUUsT0FBTyxJQUFJLENBQUM7b0JBQ3RCLElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxHQUFHLEVBQUUsSUFBSSxDQUFDLE1BQU07d0JBQUUsT0FBTyxJQUFJLENBQUM7b0JBQ25FLE9BQU8sR0FBRyxDQUFDO2dCQUNiLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUNYLENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxRQUFRLEVBQUUsQ0FBQztZQUNiLE9BQU8sSUFBSSxDQUFDLElBQVcsQ0FBQztRQUMxQixDQUFDO1FBQ0QsT0FBTyxJQUFXLENBQUM7SUFDckIsQ0FBQztJQUVELEtBQUssQ0FBQyxJQUFJO0lBQ1IsNkRBQTZEO0lBQzdELElBQVk7SUFDWiw2REFBNkQ7SUFDN0QsUUFBZ0I7SUFDaEIsNkRBQTZEO0lBQzdELE9BQTRCO0lBQzVCLDZEQUE2RDtJQUM3RCxHQUFHLEtBQTRDO1FBRS9DLE1BQU0sSUFBSSx1QkFBZ0IsQ0FDeEIsZ0RBQWdELENBQ2pELENBQUM7SUFDSixDQUFDO0lBRVEsU0FBUyxDQUNoQixTQUFpQztRQUVqQyxPQUFPLElBQUkseUNBQWUsQ0FBQyxJQUFXLEVBQUUsU0FBUyxDQUFDLENBQUM7SUFDckQsQ0FBQztJQUVRLEtBQUssQ0FBQyxTQUFTLENBQ3RCLFNBQXlCLEVBQ3pCLEVBQW9CLEVBQ3BCLEtBQTRCLEVBQzVCLEdBQUcsSUFBMkM7UUFFOUMsSUFBSSxFQUFFLENBQUMsTUFBTSxLQUFLLEtBQUssQ0FBQyxNQUFNO1lBQzVCLE1BQU0sSUFBSSw2QkFBYSxDQUFDLDBDQUEwQyxDQUFDLENBQUM7UUFDdEUsTUFBTSxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDM0QsTUFBTSxVQUFVLEdBQUcsNEJBQUssQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDOUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsQ0FBQyxNQUFNLFlBQVksVUFBVSxRQUFRLENBQUMsQ0FBQztRQUMvRCxPQUFPLE9BQU8sQ0FBQyxHQUFHLENBQ2hCLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FDMUUsQ0FBQztJQUNKLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNNLE9BQU8sQ0FDZCxLQUFRLEVBQ1IsR0FBRyxJQUEyQztRQUk5QyxNQUFNLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNyRCxNQUFNLEtBQUssR0FBdUIsNEJBQUssQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDekQsTUFBTSxTQUFTLEdBQUcsNEJBQUssQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLFdBQWtCLENBQUMsQ0FBQztRQUM1RCxNQUFNLEVBQUUsR0FBRyw0QkFBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsV0FBa0IsQ0FBQyxDQUFDO1FBQzlDLE1BQU0sRUFBRSxHQUFHLEtBQUssQ0FBQyxFQUFhLENBQUMsQ0FBQztRQUVoQyxNQUFNLFFBQVEsR0FBRyxHQUFHLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBd0IsQ0FBQztRQUVyRSxNQUFNLFdBQVcsR0FBRyxVQUVsQixHQUF3QixFQUN4QixZQUF1QjtZQUV2QixJQUFJLFlBQVk7Z0JBQ2QsWUFBWSxHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEdBQUcsWUFBWSxFQUFFLEVBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMvRCxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FDdkMsQ0FBQyxLQUEwQixFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxFQUFFLEVBQUU7Z0JBQ3pDLElBQUksT0FBTyxHQUFHLEtBQUssV0FBVztvQkFBRSxPQUFPLEtBQUssQ0FBQztnQkFDN0MsSUFBSSxZQUFZLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQztvQkFBRSxPQUFPLEtBQUssQ0FBQztnQkFDOUQsTUFBTSxVQUFVLEdBQUcsNEJBQUssQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLEdBQVUsQ0FBQyxDQUFDO2dCQUN2RCxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDO29CQUM3QixNQUFNLElBQUksNkJBQWEsQ0FBQyxpQkFBaUIsVUFBVSxjQUFjLENBQUMsQ0FBQztnQkFDckUsR0FBRyxHQUFHLEdBQUcsWUFBWSxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7Z0JBQ2hELEtBQUssQ0FBQyxVQUFVLENBQUMsR0FBRyxHQUFHLENBQUM7Z0JBQ3hCLE9BQU8sS0FBSyxDQUFDO1lBQ2YsQ0FBQyxFQUNELEVBQUUsQ0FDSCxDQUFDO1lBQ0YsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQ2pFLHVCQUF1QjtnQkFDdkIsTUFBTSxDQUFDLHlCQUFXLENBQUMsS0FBSyxDQUFDLEdBQUcsU0FBUyxDQUFDO1lBQ3hDLENBQUM7WUFDRCxPQUFPLE1BQU0sQ0FBQztRQUNoQixDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRWIsR0FBRyxDQUFDLEtBQUssQ0FDUCx3QkFBd0IsU0FBUyxrQkFBbUIsS0FBYSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQ3hFLENBQUM7UUFFRixNQUFNLG1CQUFtQixHQUFHLEdBQUcsQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1FBQ3RELE1BQU0sZ0JBQWdCLEdBQXdCLEVBQUUsQ0FBQztRQUNqRCxzRkFBc0Y7UUFDdEYscUZBQXFGO1FBQ3JGLHNGQUFzRjtRQUN0RiwyRUFBMkU7UUFDM0UsSUFBSSxtQkFBbUIsSUFBSSxLQUFLLENBQUMsU0FBUyxJQUFJLE9BQU8sS0FBSyxDQUFDLFNBQVMsS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUNsRixLQUFLLE1BQU0sVUFBVSxJQUFJLG1CQUFtQixFQUFFLENBQUM7Z0JBQzdDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxHQUFHLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDbEUsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUMsRUFBUyxDQUFDLEdBQUcsV0FBVyxDQUNuRCxHQUFHLENBQUMsY0FBYyxDQUFDLHFCQUFxQixDQUFDO29CQUN2QyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUs7b0JBQ2IsQ0FBQyxDQUFDLENBQUUsS0FBSyxDQUFDLFNBQWlCLElBQUksRUFBRSxDQUFDLEVBQ3BDLG1CQUFtQixDQUFDLFVBQVUsQ0FBQyxDQUNoQyxDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7UUFFRCw2RUFBNkU7UUFDN0UsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFeEUsT0FBTztZQUNMLE1BQU07WUFDTixFQUFFLEVBQUcsS0FBYSxDQUFDLEVBQUUsQ0FBVztZQUNoQyxTQUFTLEVBQ1AsQ0FBQyxRQUFRLElBQUksS0FBSyxDQUFDLFNBQVMsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxNQUFNO2dCQUNqRSxDQUFDLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUM7Z0JBQzlCLENBQUMsQ0FBQyxTQUFTO1lBQ2YsVUFBVSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxnQkFBZ0I7U0FDcEQsQ0FBQztJQUNKLENBQUM7SUFFUSxNQUFNLENBQ2IsR0FBd0IsRUFDeEIsS0FBcUIsRUFDckIsRUFBa0IsRUFDbEIsU0FBK0IsRUFDL0IsR0FBRyxJQUEyQztRQUU5QyxNQUFNLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNwRCxNQUFNLEVBQUUsR0FBd0IsRUFBRSxDQUFDO1FBQ25DLE1BQU0sRUFBRSxHQUFHLDRCQUFLLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzNCLE1BQU0sT0FBTyxHQUFHLDRCQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3JDLElBQUksT0FBTyxFQUFFLElBQUksS0FBSyxNQUFNLElBQUksT0FBTyxFQUFFLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDdkQsRUFBRSxHQUFHLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNsQixDQUFDO1FBQ0QsRUFBRSxDQUFDLEVBQVksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUN0QixHQUFHLENBQUMsS0FBSyxDQUFDLG9CQUFvQixLQUFLLENBQUMsSUFBSSxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFckQsU0FBUyxVQUFVLENBQUMsQ0FBbUI7WUFDckMsTUFBTSxDQUFDLEdBQUcsQ0FDUixPQUFPLEtBQUssS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLDRCQUFLLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLENBQUMsRUFBRSxDQUFDLENBQzlELENBQUM7WUFDUCxNQUFNLFVBQVUsR0FBRyw0QkFBSyxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUM5QyxNQUFNLElBQUksR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDN0QsT0FBTyxJQUFJO2lCQUNSLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFNLEVBQWEsQ0FBQztpQkFDbkMsTUFBTSxDQUFDLENBQUMsS0FBUSxFQUFFLEdBQUcsRUFBRSxFQUFFO2dCQUN2QixLQUE2QixDQUFDLEdBQUcsQ0FBQztvQkFDakMsQ0FBQyxDQUFDLDRCQUFLLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxHQUFVLENBQUMsQ0FBQyxDQUFDO2dCQUN6QyxPQUFPLEtBQUssQ0FBQztZQUNmLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNWLENBQUM7UUFFRCxJQUFJLE1BQU0sR0FBRyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFN0IsSUFBSSxTQUFTLElBQUksQ0FBQyxJQUFJLENBQUMsMEJBQTBCLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN2RCxHQUFHLENBQUMsS0FBSyxDQUNQLG1DQUFtQyxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUN2RSxDQUFDO1lBQ0YsTUFBTSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUU7Z0JBQ3ZELElBQUksR0FBRyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLFNBQVMsQ0FBQyxFQUFFLENBQUM7b0JBQ3RDLEdBQUcsQ0FBQyxHQUFjLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQzFCLENBQUM7Z0JBQ0QsT0FBTyxHQUFHLENBQUM7WUFDYixDQUFDLEVBQUUsSUFBSSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ2xCLENBQUM7UUFFRCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRU8sMEJBQTBCLENBQUMsR0FBMEI7UUFDM0QsSUFBSSxDQUFDLEdBQUc7WUFBRSxPQUFPLEtBQUssQ0FBQztRQUN2QixJQUFJLEdBQUcsQ0FBQyxjQUFjLENBQUMsc0JBQXNCLENBQUM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUM1RCxNQUFNLFNBQVMsR0FBRyxHQUFHLENBQUMsY0FBYyxDQUFDLFdBQVcsQ0FBdUIsQ0FBQztRQUN4RSxJQUFJLENBQUMsU0FBUztZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQzVCLE1BQU0sRUFBRSxHQUFHLFNBQVMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUM5QyxPQUFPLENBQUMsK0JBQXdCLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDNUUsQ0FBQztJQUVPLGFBQWEsQ0FBQyxPQUE4QjtRQUNsRCxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FHMUIsQ0FBQztRQUNkLElBQUksQ0FBQyxRQUFRO1lBQUUsT0FBTyxTQUFTLENBQUM7UUFDaEMsSUFBSSxPQUFPLFFBQVEsS0FBSyxRQUFRO1lBQUUsT0FBTyxRQUFRLENBQUM7UUFDbEQsSUFBSSxDQUFDO1lBQ0gsT0FBTyxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDN0IsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLE9BQU8sU0FBUyxDQUFDO1FBQ25CLENBQUM7SUFDSCxDQUFDO0lBRU8sMEJBQTBCLENBQ2hDLEtBQXFCLEVBQ3JCLEdBQTBCO1FBRTFCLE1BQU0sVUFBVSxHQUFHLDRCQUFLLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzNDLElBQUksQ0FBQyxVQUFVO1lBQUUsT0FBTztRQUN4QixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxHQUFHO1lBQUUsT0FBTztRQUNqQixJQUNFLEdBQUcsS0FBSyxVQUFVLENBQUMsS0FBSztZQUN4QixDQUFDLFVBQVUsQ0FBQyxTQUFTLElBQUksVUFBVSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUNuRCxDQUFDO1lBQ0QsTUFBTSxJQUFJLHlCQUFrQixDQUMxQixnQkFBZ0IsR0FBRyw0Q0FBNEMsQ0FDaEUsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBRVEsWUFBWSxDQUNuQixTQUF5QixFQUN6QixFQUFrQixFQUNsQixLQUEwQixFQUMxQixHQUFHLElBQStDO1FBRWxELE1BQU0sRUFBRSxPQUFPLEVBQUUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDekQsTUFBTSxNQUFNLEdBQXdCLEVBQUUsQ0FBQztRQUN2QyxNQUFNLENBQUMseUJBQVcsQ0FBQyxLQUFLLENBQUMsR0FBRyw0QkFBSyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN2RCxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQztRQUU3QixPQUFPLENBQUMsU0FBUyxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsR0FBRyxPQUFPLENBTXhDLENBQUM7SUFDSixDQUFDO0lBRVEsWUFBWSxDQUNuQixTQUF5QixFQUN6QixFQUFrQixFQUNsQixLQUEwQixFQUMxQixHQUFHLElBQStDO1FBRWxELE1BQU0sRUFBRSxPQUFPLEVBQUUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDekQsTUFBTSxNQUFNLEdBQXdCLEVBQUUsQ0FBQztRQUN2QyxNQUFNLENBQUMseUJBQVcsQ0FBQyxLQUFLLENBQUMsR0FBRyw0QkFBSyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUN2RCxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQztRQUU3QixPQUFPLENBQUMsU0FBUyxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsR0FBRyxPQUFPLENBTXhDLENBQUM7SUFDSixDQUFDO0lBRWtCLGVBQWUsQ0FDaEMsU0FBeUIsRUFDekIsR0FBcUIsRUFDckIsTUFBNkIsRUFDN0IsR0FBRyxJQUFxQztRQUV4QyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssTUFBTSxDQUFDLE1BQU07WUFDOUIsTUFBTSxJQUFJLDZCQUFhLENBQUMsMENBQTBDLENBQUMsQ0FBQztRQUV0RSxNQUFNLEdBQUcsR0FBMEIsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBRTlDLE1BQU0sT0FBTyxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsS0FBSyxFQUFFLEVBQUU7WUFDcEMsTUFBTSxNQUFNLEdBQXdCLEVBQUUsQ0FBQztZQUN2QyxNQUFNLENBQUMseUJBQVcsQ0FBQyxLQUFLLENBQUMsR0FBRyw0QkFBSyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUN2RCxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUNyQyxPQUFPLE1BQU0sQ0FBQztRQUNoQixDQUFDLENBQUMsQ0FBQztRQUNILE9BQU8sQ0FBQyxTQUFTLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxHQUFVLENBQUMsQ0FBQztJQUMvQyxDQUFDO0lBRWtCLGVBQWUsQ0FDaEMsU0FBeUIsRUFDekIsR0FBcUIsRUFDckIsTUFBNkIsRUFDN0IsR0FBRyxJQUFxQztRQUV4QyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssTUFBTSxDQUFDLE1BQU07WUFDOUIsTUFBTSxJQUFJLDZCQUFhLENBQUMsMENBQTBDLENBQUMsQ0FBQztRQUV0RSxNQUFNLEdBQUcsR0FBMEIsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBRTlDLE1BQU0sT0FBTyxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsS0FBSyxFQUFFLEVBQUU7WUFDcEMsTUFBTSxNQUFNLEdBQXdCLEVBQUUsQ0FBQztZQUN2QyxNQUFNLENBQUMseUJBQVcsQ0FBQyxLQUFLLENBQUMsR0FBRyw0QkFBSyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUN2RCxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztZQUNyQyxPQUFPLE1BQU0sQ0FBQztRQUNoQixDQUFDLENBQUMsQ0FBQztRQUNILE9BQU8sQ0FBQyxTQUFTLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxHQUFVLENBQUMsQ0FBQztJQUMvQyxDQUFDO0lBRVEsVUFBVSxDQUNqQixHQUFtQixFQUNuQixNQUFlO1FBRWYsT0FBTyxxQkFBcUIsQ0FBQyxVQUFVLENBQUMsTUFBTSxJQUFJLEdBQUcsQ0FBQyxDQUFDO0lBQ3pELENBQUM7SUE0QmtCLE1BQU0sQ0FJdkIsSUFBcUQsRUFDckQsU0FBaUIsRUFDakIsY0FBdUIsS0FBSyxFQUM1QixTQUF5RDtRQU16RCxJQUFJLENBQUMsV0FBVztZQUNkLE9BQU8sS0FBSyxDQUFDLE1BQU0sQ0FDakIsSUFBSSxFQUNKLFNBQWdCLEVBQ2hCLFdBQWtCLEVBQ2xCLFNBQWdCLENBQ1YsQ0FBQztRQUVYLE9BQU8sS0FBSyxDQUFDLE1BQU07YUFDaEIsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsU0FBZ0IsRUFBRSxXQUFXLEVBQUUsU0FBZ0IsQ0FBQzthQUNqRSxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtZQUNaLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLFlBQVksdUNBQXFCLENBQUM7Z0JBQzdDLE1BQU0sSUFBSSw2QkFBYSxDQUFDLHlCQUF5QixDQUFDLENBQUM7WUFDckQsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRTtnQkFDeEIsSUFBSSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSTtnQkFDbEIsUUFBUSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsUUFBUTthQUMzQixDQUFDLENBQUM7UUFDTCxDQUFDLENBQVEsQ0FBQztJQUNkLENBQUM7SUFFUSxLQUFLLENBQUMsZUFBZSxDQUM1QixLQUFnQyxFQUNoQyxLQUFxRCxFQUNyRCxFQUFZLEVBQ1osR0FBRyxJQUEyQztRQUU5QyxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWU7WUFDdkIsTUFBTSxJQUFJLDZCQUFhLENBQ3JCLG9FQUFvRSxDQUNyRSxDQUFDO1FBQ0osTUFBTSxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDakUsSUFBSSxHQUFHLENBQUMsaUJBQWlCO1lBQUUsT0FBTztRQUNsQyxJQUFJLEdBQUcsQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDO1lBQUUsT0FBTztRQUN6QyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUk7WUFBRSxPQUFPO1FBQ3RCLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDakMsTUFBTSxVQUFVLEdBQUcsQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ3ZELE1BQU0sUUFBUSxHQUFHLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNuRCxJQUFJLENBQUMsTUFBTSxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLElBQUksVUFBVSxDQUFDLEVBQUUsQ0FBQztZQUNwRCxzRUFBc0U7WUFDdEUsMkVBQTJFO1lBQzNFLE1BQU0sS0FBSyxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFDbEUsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLHdCQUF3QjtZQUNqRSxNQUFNLE9BQU8sR0FBRyxVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFDbEUsTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDLGVBQWUsQ0FDeEMsS0FBSyxFQUNMLEtBQUssRUFDTCxFQUFFLEVBQ0YsS0FBSyxFQUNMLE9BQU8sRUFDUCxHQUFHLENBQ0osQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBRUQsTUFBTSxDQUFVLFVBQVUsQ0FBc0IsR0FBbUI7UUFDakUsT0FBTztRQUNQLHFDQUFxQztRQUNyQyxrREFBa0Q7UUFDbEQsTUFBTTtRQUNOLElBQUk7UUFDSix3REFBd0Q7UUFDeEQsTUFBTSxHQUFHLEdBQUcsT0FBTyxHQUFHLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUM7UUFDeEQsSUFBSSxHQUFHLENBQUMsUUFBUSxDQUFDLDZCQUFhLENBQUMsSUFBSSxDQUFDO1lBQUUsT0FBTyxJQUFJLDZCQUFhLENBQUMsR0FBRyxDQUFNLENBQUM7UUFDekUsSUFBSSxHQUFHLENBQUMsUUFBUSxDQUFDLDZCQUFhLENBQUMsSUFBSSxDQUFDO1lBQUUsT0FBTyxJQUFJLDZCQUFhLENBQUMsR0FBRyxDQUFNLENBQUM7UUFDekUsSUFBSSxHQUFHLENBQUMsUUFBUSxDQUFDLCtCQUFlLENBQUMsSUFBSSxDQUFDO1lBQ3BDLE9BQU8sSUFBSSwrQkFBZSxDQUFDLEdBQUcsQ0FBTSxDQUFDO1FBQ3ZDLElBQUksR0FBRyxDQUFDLFFBQVEsQ0FBQyxpQkFBVSxDQUFDLElBQUksQ0FBQztZQUFFLE9BQU8sSUFBSSxpQkFBVSxDQUFDLEdBQUcsQ0FBTSxDQUFDO1FBQ25FLElBQUksR0FBRyxDQUFDLFFBQVEsQ0FBQyxrQkFBVyxDQUFDLElBQUksQ0FBQztZQUFFLE9BQU8sSUFBSSxrQkFBVyxDQUFDLEdBQUcsQ0FBTSxDQUFDO1FBQ3JFLElBQUksR0FBRyxDQUFDLFFBQVEsQ0FBQyx1QkFBZ0IsQ0FBQyxJQUFJLENBQUM7WUFDckMsT0FBTyxJQUFJLHVCQUFnQixDQUFDLEdBQUcsQ0FBTSxDQUFDO1FBQ3hDLElBQUksR0FBRyxDQUFDLFFBQVEsQ0FBQyxxQkFBYyxDQUFDLElBQUksQ0FBQztZQUFFLE9BQU8sSUFBSSxxQkFBYyxDQUFDLEdBQUcsQ0FBTSxDQUFDO1FBQzNFLElBQUksR0FBRyxDQUFDLFFBQVEsQ0FBQyxvQkFBYSxDQUFDLElBQUksQ0FBQztZQUFFLE9BQU8sSUFBSSxvQkFBYSxDQUFDLEdBQUcsQ0FBTSxDQUFDO1FBQ3pFLElBQUksR0FBRyxDQUFDLFFBQVEsQ0FBQyx5QkFBa0IsQ0FBQyxJQUFJLENBQUM7WUFDdkMsT0FBTyxJQUFJLHlCQUFrQixDQUFDLEdBQUcsQ0FBTSxDQUFDO1FBQzFDLElBQUksR0FBRyxDQUFDLFFBQVEsQ0FBQyxxQkFBYyxDQUFDLElBQUksQ0FBQztZQUFFLE9BQU8sSUFBSSxxQkFBYyxDQUFDLEdBQUcsQ0FBTSxDQUFDO1FBQzNFLElBQUksR0FBRyxDQUFDLFFBQVEsQ0FBQyxzQkFBZSxDQUFDLElBQUksQ0FBQztZQUNwQyxPQUFPLElBQUksc0JBQWUsQ0FBQyxHQUFHLENBQU0sQ0FBQztRQUN2QyxJQUFJLEdBQUcsQ0FBQyxRQUFRLENBQUMsa0NBQWtCLENBQUMsSUFBSSxDQUFDO1lBQ3ZDLE9BQU8sSUFBSSxrQ0FBa0IsQ0FBQyxHQUFHLENBQU0sQ0FBQztRQUMxQyxJQUFJLEdBQUcsQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUM7WUFDbkMsT0FBTyxJQUFJLDRCQUFtQixDQUM1QixzREFBc0QsR0FBRyxFQUFFLENBQ3ZELENBQUM7UUFFVCxPQUFPLElBQUksNkJBQWEsQ0FBQyxHQUFHLENBQU0sQ0FBQztJQUNyQyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsTUFBTSxDQUFVLFVBQVU7UUFDeEIsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ25CLHVCQUFVLENBQUMsV0FBVyxDQUFDLHlCQUFhLENBQUM7YUFDbEMsR0FBRyxDQUFDLHNCQUFlLENBQUMsVUFBVSxDQUFDO2FBQy9CLE1BQU0sQ0FBQztZQUNOLFNBQVMsRUFBRSxTQUFTLFNBQVM7Z0JBQzNCLE9BQU8sSUFBQSxrQkFBSyxFQUNWLElBQUEsd0JBQVEsRUFBQyw2QkFBNkIsQ0FBQyxFQUN2QyxJQUFBLHlCQUFZLEVBQUMsc0JBQWUsQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLENBQzdDLENBQUM7WUFDSixDQUFDO1NBQ0ssQ0FBQzthQUNSLEtBQUssRUFBRSxDQUFDO1FBRVgsdUJBQVUsQ0FBQyxXQUFXLENBQUMseUJBQWEsQ0FBQzthQUNsQyxHQUFHLENBQUMsc0JBQWUsQ0FBQyxVQUFVLENBQUM7YUFDL0IsTUFBTSxDQUFDO1lBQ04sU0FBUyxFQUFFLFNBQVMsU0FBUztnQkFDM0IsT0FBTyxJQUFBLGtCQUFLLEVBQ1YsSUFBQSw4QkFBYyxFQUFDLDZCQUE2QixDQUFDLEVBQzdDLElBQUEseUJBQVksRUFBQyxzQkFBZSxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsQ0FDN0MsQ0FBQztZQUNKLENBQUM7U0FDSyxDQUFDO2FBQ1IsS0FBSyxFQUFFLENBQUM7UUFFWCx1QkFBVSxDQUFDLFdBQVcsQ0FBQyx5QkFBYSxDQUFDO2FBQ2xDLEdBQUcsQ0FBQyxzQkFBZSxDQUFDLE1BQU0sQ0FBQzthQUMzQixNQUFNLENBQUMsSUFBQSw4QkFBYyxHQUFFLENBQUM7YUFDeEIsS0FBSyxFQUFFLENBQUM7UUFFWCx1QkFBVSxDQUFDLFdBQVcsQ0FBQyx5QkFBYSxDQUFDO2FBQ2xDLEdBQUcsQ0FBQyxxQ0FBYyxDQUFDLElBQUksQ0FBQzthQUN4QixNQUFNLENBQUMsU0FBUyxjQUFjO1lBQzdCLE9BQU8sQ0FBQyxNQUFXLEVBQUUsSUFBVSxFQUFFLEVBQUU7Z0JBQ2pDLElBQUEsOEJBQVEsRUFBQyxJQUFJLEVBQUUsYUFBYSxDQUFDLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQzlDLENBQUMsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBRUwsdUJBQVUsQ0FBQyxXQUFXLENBQUMseUJBQWEsQ0FBQzthQUNsQyxHQUFHLENBQUMsc0JBQWUsQ0FBQyxLQUFLLENBQUM7YUFDMUIsTUFBTSxDQUFDLFNBQVMsS0FBSyxDQUFDLEdBQVE7WUFDN0IsTUFBTSxLQUFLLEdBQVUsRUFBRSxDQUFDO1lBQ3hCLElBQUksT0FBTyxHQUNULE9BQU8sR0FBRyxLQUFLLFVBQVU7Z0JBQ3ZCLENBQUMsQ0FBQyxxQkFBUSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUM7Z0JBQ3RCLENBQUMsQ0FBQyxxQkFBUSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUM7WUFFdkMsT0FBTyxPQUFPLElBQUksT0FBTyxLQUFLLE1BQU0sSUFBSSxPQUFPLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQzFELEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQ3BCLE9BQU8sR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzNDLENBQUM7WUFFRCxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUUzQyx3REFBd0Q7WUFDeEQsT0FBTyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUN4QixNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUM7Z0JBQ2hDLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxXQUFXLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztnQkFDOUMsSUFBQSw0QkFBWSxHQUFFLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDOUIsQ0FBQztZQUVELE9BQU8sSUFBQSw0QkFBWSxHQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDN0IsQ0FBQyxDQUFDO2FBQ0QsS0FBSyxFQUFFLENBQUM7SUFDYixDQUFDOztBQXQvQ0gsc0RBdS9DQztBQUVELHFCQUFxQixDQUFDLFVBQVUsRUFBRSxDQUFDO0FBQ25DLGNBQU8sQ0FBQyxVQUFVLENBQUMseUJBQWEsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ291Y2hEQkFkYXB0ZXIsXG4gIENvdWNoREJLZXlzLFxuICBNYW5nb1F1ZXJ5LFxuICBWaWV3UmVzcG9uc2UsXG59IGZyb20gXCJAZGVjYWYtdHMvZm9yLWNvdWNoZGJcIjtcbmltcG9ydCB7IE1vZGVsLCBWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IEZhYnJpY0NvbnRyYWN0RmxhZ3MgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgRmFicmljQ29udHJhY3RDb250ZXh0IH0gZnJvbSBcIi4vQ29udHJhY3RDb250ZXh0XCI7XG5pbXBvcnQge1xuICBCYWRSZXF1ZXN0RXJyb3IsXG4gIEJhc2VFcnJvcixcbiAgQnVsa0NydWRPcGVyYXRpb25LZXlzLFxuICBDb25mbGljdEVycm9yLFxuICBJbnRlcm5hbEVycm9yLFxuICBOb3RGb3VuZEVycm9yLFxuICBvbkNyZWF0ZSxcbiAgb25DcmVhdGVVcGRhdGUsXG4gIE9wZXJhdGlvbktleXMsXG4gIFByaW1hcnlLZXlUeXBlLFxuICBTZXJpYWxpemF0aW9uRXJyb3IsXG59IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHtcbiAgQ29udGV4dCBhcyBDdHgsXG4gIE9iamVjdCBhcyBGYWJyaWNPYmplY3QsXG4gIFByb3BlcnR5LFxuICBQcm9wZXJ0eSBhcyBGYWJyaWNQcm9wZXJ0eSxcbn0gZnJvbSBcImZhYnJpYy1jb250cmFjdC1hcGlcIjtcbmltcG9ydCB7IExvZ2dlciwgTG9nZ2luZyB9IGZyb20gXCJAZGVjYWYtdHMvbG9nZ2luZ1wiO1xuaW1wb3J0IHtcbiAgUGVyc2lzdGVuY2VLZXlzLFxuICBSZWxhdGlvbnNNZXRhZGF0YSxcbiAgU2VxdWVuY2UsXG4gIFNlcXVlbmNlT3B0aW9ucyxcbiAgVW5zdXBwb3J0ZWRFcnJvcixcbiAgQWRhcHRlcixcbiAgQWRhcHRlckZsYWdzLFxuICBQcmVwYXJlZE1vZGVsLFxuICBSZXBvc2l0b3J5LFxuICBRdWVyeUVycm9yLFxuICBQYWdpbmdFcnJvcixcbiAgTWlncmF0aW9uRXJyb3IsXG4gIE9ic2VydmVyRXJyb3IsXG4gIEF1dGhvcml6YXRpb25FcnJvcixcbiAgRm9yYmlkZGVuRXJyb3IsXG4gIENvbm5lY3Rpb25FcnJvcixcbiAgQ29udGV4dHVhbGl6ZWRBcmdzLFxuICBDb250ZXh0LFxuICBSYXdSZXN1bHQsXG4gIFBhZ2luYXRvcixcbiAgQ29udGV4dHVhbEFyZ3MsXG4gIE1heWJlQ29udGV4dHVhbEFyZyxcbiAgTWV0aG9kT3JPcGVyYXRpb24sXG4gIEFsbE9wZXJhdGlvbktleXMsXG4gIEZsYWdzT2YsXG4gIENvbnRleHRPZixcbiAgVHJhbnNhY3Rpb25PcGVyYXRpb25LZXlzLFxuICBFdmVudElkcyxcbiAgRGlzcGF0Y2gsXG4gIHByb21pc2VTZXF1ZW5jZSxcbiAgcmVzb2x2ZUJ1bGtTZXF1ZW5jZVJlc3VsdCxcbn0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBGYWJyaWNDb250cmFjdFJlcG9zaXRvcnkgfSBmcm9tIFwiLi9GYWJyaWNDb250cmFjdFJlcG9zaXRvcnlcIjtcbmltcG9ydCB7XG4gIENoYWluY29kZVN0dWIsXG4gIENsaWVudElkZW50aXR5LFxuICBJdGVyYXRvcnMsXG4gIFN0YXRlUXVlcnlSZXNwb25zZSxcbn0gZnJvbSBcImZhYnJpYy1zaGltLWFwaVwiO1xuaW1wb3J0IHsgRmFicmljU3RhdGVtZW50IH0gZnJvbSBcIi4vRmFicmljQ29udHJhY3RTdGF0ZW1lbnRcIjtcbmltcG9ydCB7IEZhYnJpY0NvbnRyYWN0U2VxdWVuY2UgfSBmcm9tIFwiLi9GYWJyaWNDb250cmFjdFNlcXVlbmNlXCI7XG5pbXBvcnQgeyBGYWJyaWNGbGF2b3VyIH0gZnJvbSBcIi4uL3NoYXJlZC9jb25zdGFudHNcIjtcbmltcG9ydCB7IFNpbXBsZURldGVybWluaXN0aWNTZXJpYWxpemVyIH0gZnJvbSBcIi4uL3NoYXJlZC9TaW1wbGVEZXRlcm1pbmlzdGljU2VyaWFsaXplclwiO1xuaW1wb3J0IHtcbiAgYXBwbHksXG4gIENvbnN0cnVjdG9yLFxuICBEZWNvcmF0aW9uLFxuICBNZXRhZGF0YSxcbiAgcHJvcE1ldGFkYXRhLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRpb25cIjtcbmltcG9ydCB7IEZhYnJpY0NvbnRyYWN0UGFnaW5hdG9yIH0gZnJvbSBcIi4vRmFicmljQ29udHJhY3RQYWdpbmF0b3JcIjtcbmltcG9ydCB7IE1pc3NpbmdDb250ZXh0RXJyb3IgfSBmcm9tIFwiLi4vc2hhcmVkL2Vycm9yc1wiO1xuaW1wb3J0IHsgU2VncmVnYXRlZE1vZGVsIH0gZnJvbSBcIi4uL3NoYXJlZC9pbmRleFwiO1xuaW1wb3J0IHsgRmFicmljQ29udHJhY3REaXNwYXRjaCB9IGZyb20gXCIuL0ZhYnJpY0NvbnRyYWN0RGlzcGF0Y2hcIjtcblxuZXhwb3J0IHR5cGUgRmFicmljQ29udGV4dHVhbGl6ZWRBcmdzPFxuICBBUkdTIGV4dGVuZHMgYW55W10gPSBhbnlbXSxcbiAgRVhURU5EIGV4dGVuZHMgYm9vbGVhbiA9IGZhbHNlLFxuPiA9IENvbnRleHR1YWxpemVkQXJnczxGYWJyaWNDb250cmFjdENvbnRleHQsIEFSR1MsIEVYVEVORD4gJiB7XG4gIHN0dWI6IENoYWluY29kZVN0dWI7XG4gIGlkZW50aXR5OiBDbGllbnRJZGVudGl0eTtcbn07XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFNldHMgdGhlIGNyZWF0b3Igb3IgdXBkYXRlciBmaWVsZCBpbiBhIG1vZGVsIGJhc2VkIG9uIHRoZSB1c2VyIGluIHRoZSBjb250ZXh0XG4gKiBAc3VtbWFyeSBDYWxsYmFjayBmdW5jdGlvbiB1c2VkIGluIGRlY29yYXRvcnMgdG8gYXV0b21hdGljYWxseSBzZXQgdGhlIGNyZWF0ZWRfYnkgb3IgdXBkYXRlZF9ieSBmaWVsZHNcbiAqIHdpdGggdGhlIHVzZXJuYW1lIGZyb20gdGhlIGNvbnRleHQgd2hlbiBhIGRvY3VtZW50IGlzIGNyZWF0ZWQgb3IgdXBkYXRlZFxuICogQHRlbXBsYXRlIE0gLSBUeXBlIGV4dGVuZGluZyBNb2RlbFxuICogQHRlbXBsYXRlIFIgLSBUeXBlIGV4dGVuZGluZyBOYW5vUmVwb3NpdG9yeTxNPlxuICogQHRlbXBsYXRlIFYgLSBUeXBlIGV4dGVuZGluZyBSZWxhdGlvbnNNZXRhZGF0YVxuICogQHBhcmFtIHtSfSB0aGlzIC0gVGhlIHJlcG9zaXRvcnkgaW5zdGFuY2VcbiAqIEBwYXJhbSB7RmFicmljQ29udHJhY3RDb250ZXh0fSBjb250ZXh0IC0gVGhlIG9wZXJhdGlvbiBjb250ZXh0IGNvbnRhaW5pbmcgdXNlciBpbmZvcm1hdGlvblxuICogQHBhcmFtIHtWfSBkYXRhIC0gVGhlIHJlbGF0aW9uIG1ldGFkYXRhXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IC0gVGhlIHByb3BlcnR5IGtleSB0byBzZXQgd2l0aCB0aGUgdXNlcm5hbWVcbiAqIEBwYXJhbSB7TX0gbW9kZWwgLSBUaGUgbW9kZWwgaW5zdGFuY2UgYmVpbmcgY3JlYXRlZCBvciB1cGRhdGVkXG4gKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBvcGVyYXRpb24gaXMgY29tcGxldGVcbiAqIEBmdW5jdGlvbiBjcmVhdGVkQnlPbkZhYnJpY0NyZWF0ZVVwZGF0ZVxuICogQG1lbWJlck9mIG1vZHVsZTpmYWJyaWMuY29udHJhY3RzXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IEYgYXMgY3JlYXRlZEJ5T25OYW5vQ3JlYXRlVXBkYXRlXG4gKiAgIHBhcnRpY2lwYW50IEMgYXMgQ29udGV4dFxuICogICBwYXJ0aWNpcGFudCBNIGFzIE1vZGVsXG4gKiAgIEYtPj5DOiBnZXQoXCJ1c2VyXCIpXG4gKiAgIEMtLT4+RjogdXNlciBvYmplY3RcbiAqICAgRi0+Pk06IHNldCBrZXkgdG8gdXNlci5uYW1lXG4gKiAgIE5vdGUgb3ZlciBGOiBJZiBubyB1c2VyIGluIGNvbnRleHRcbiAqICAgRi0tPj5GOiB0aHJvdyBVbnN1cHBvcnRlZEVycm9yXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjcmVhdGVkQnlPbkZhYnJpY0NyZWF0ZVVwZGF0ZTxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgRmFicmljQ29udHJhY3RSZXBvc2l0b3J5PE0+LFxuICBWIGV4dGVuZHMgUmVsYXRpb25zTWV0YWRhdGEsXG4+KFxuICB0aGlzOiBSLFxuICBjb250ZXh0OiBDb250ZXh0T2Y8Uj4sXG4gIGRhdGE6IFYsXG4gIGtleToga2V5b2YgTSxcbiAgbW9kZWw6IE1cbik6IFByb21pc2U8dm9pZD4ge1xuICB0cnkge1xuICAgIGNvbnN0IHVzZXIgPSBjb250ZXh0LmdldChcImlkZW50aXR5XCIpIGFzIENsaWVudElkZW50aXR5O1xuICAgIG1vZGVsW2tleV0gPSB1c2VyLmdldElEKCkgYXMgTVt0eXBlb2Yga2V5XTtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICB0aHJvdyBuZXcgVW5zdXBwb3J0ZWRFcnJvcihcbiAgICAgIFwiTm8gVXNlciBmb3VuZCBpbiBjb250ZXh0LiBQbGVhc2UgcHJvdmlkZSBhIHVzZXIgaW4gdGhlIGNvbnRleHRcIlxuICAgICk7XG4gIH1cbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQWRhcHRlciBmb3IgSHlwZXJsZWRnZXIgRmFicmljIGNoYWluY29kZSBzdGF0ZSBkYXRhYmFzZSBvcGVyYXRpb25zXG4gKiBAc3VtbWFyeSBQcm92aWRlcyBhIENvdWNoREItbGlrZSBpbnRlcmZhY2UgZm9yIGludGVyYWN0aW5nIHdpdGggdGhlIEZhYnJpYyBzdGF0ZSBkYXRhYmFzZSBmcm9tIHdpdGhpbiBhIGNoYWluY29kZSBjb250cmFjdFxuICogQHRlbXBsYXRlIHZvaWQgLSBObyBjb25maWd1cmF0aW9uIG5lZWRlZCBmb3IgY29udHJhY3QgYWRhcHRlclxuICogQHRlbXBsYXRlIEZhYnJpY0NvbnRyYWN0RmxhZ3MgLSBGbGFncyBzcGVjaWZpYyB0byBGYWJyaWMgY29udHJhY3Qgb3BlcmF0aW9uc1xuICogQHRlbXBsYXRlIEZhYnJpY0NvbnRyYWN0Q29udGV4dCAtIENvbnRleHQgdHlwZSBmb3IgRmFicmljIGNvbnRyYWN0IG9wZXJhdGlvbnNcbiAqIEBjbGFzcyBGYWJyaWNDb250cmFjdEFkYXB0ZXJcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBJbiBhIEZhYnJpYyBjaGFpbmNvZGUgY29udHJhY3QgY2xhc3NcbiAqIGltcG9ydCB7IEZhYnJpY0NvbnRyYWN0QWRhcHRlciB9IGZyb20gJ0BkZWNhZi10cy9mb3ItZmFicmljJztcbiAqXG4gKiBleHBvcnQgY2xhc3MgTXlDb250cmFjdCBleHRlbmRzIENvbnRyYWN0IHtcbiAqICAgcHJpdmF0ZSBhZGFwdGVyID0gbmV3IEZhYnJpY0NvbnRyYWN0QWRhcHRlcigpO1xuICpcbiAqICAgQFRyYW5zYWN0aW9uKClcbiAqICAgYXN5bmMgY3JlYXRlQXNzZXQoY3R4OiBDb250ZXh0LCBpZDogc3RyaW5nLCBkYXRhOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAqICAgICBjb25zdCBtb2RlbCA9IHsgaWQsIGRhdGEsIHRpbWVzdGFtcDogRGF0ZS5ub3coKSB9O1xuICogICAgIGF3YWl0IHRoaXMuYWRhcHRlci5jcmVhdGUoJ2Fzc2V0cycsIGlkLCBtb2RlbCwge30sIHsgc3R1YjogY3R4LnN0dWIgfSk7XG4gKiAgIH1cbiAqIH1cbiAqIGBgYFxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDb250cmFjdFxuICogICBwYXJ0aWNpcGFudCBGYWJyaWNDb250cmFjdEFkYXB0ZXJcbiAqICAgcGFydGljaXBhbnQgU3R1YlxuICogICBwYXJ0aWNpcGFudCBTdGF0ZURCXG4gKlxuICogICBDb250cmFjdC0+PkZhYnJpY0NvbnRyYWN0QWRhcHRlcjogY3JlYXRlKHRhYmxlTmFtZSwgaWQsIG1vZGVsLCB0cmFuc2llbnQsIGN0eClcbiAqICAgRmFicmljQ29udHJhY3RBZGFwdGVyLT4+RmFicmljQ29udHJhY3RBZGFwdGVyOiBTZXJpYWxpemUgbW9kZWwgdG8gSlNPTlxuICogICBGYWJyaWNDb250cmFjdEFkYXB0ZXItPj5TdHViOiBwdXRTdGF0ZShpZCwgc2VyaWFsaXplZERhdGEpXG4gKiAgIFN0dWItPj5TdGF0ZURCOiBXcml0ZSBkYXRhXG4gKiAgIFN0YXRlREItLT4+U3R1YjogU3VjY2Vzc1xuICogICBTdHViLS0+PkZhYnJpY0NvbnRyYWN0QWRhcHRlcjogU3VjY2Vzc1xuICogICBGYWJyaWNDb250cmFjdEFkYXB0ZXItLT4+Q29udHJhY3Q6IG1vZGVsXG4gKi9cbmV4cG9ydCBjbGFzcyBGYWJyaWNDb250cmFjdEFkYXB0ZXIgZXh0ZW5kcyBDb3VjaERCQWRhcHRlcjxcbiAgYW55LFxuICB2b2lkLFxuICBGYWJyaWNDb250cmFjdENvbnRleHRcbj4ge1xuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBQUklWQVRFX0JPT0tNQVJLX1BSRUZJWCA9IFwiX19kY2ZfcHZ0Ym1fX1wiO1xuXG4gIHByaXZhdGUgc3RhdGljIHBhcnNlU3ludGhldGljUHJpdmF0ZUJvb2ttYXJrKFxuICAgIGJvb2ttYXJrOiB1bmtub3duXG4gICk6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHR5cGVvZiBib29rbWFyayAhPT0gXCJzdHJpbmdcIikgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBpZiAoIWJvb2ttYXJrLnN0YXJ0c1dpdGgoRmFicmljQ29udHJhY3RBZGFwdGVyLlBSSVZBVEVfQk9PS01BUktfUFJFRklYKSlcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgY29uc3QgcmF3ID0gYm9va21hcmsuc2xpY2UoXG4gICAgICBGYWJyaWNDb250cmFjdEFkYXB0ZXIuUFJJVkFURV9CT09LTUFSS19QUkVGSVgubGVuZ3RoXG4gICAgKTtcbiAgICBjb25zdCBwYXJzZWQgPSBOdW1iZXIocmF3KTtcbiAgICByZXR1cm4gTnVtYmVyLmlzSW50ZWdlcihwYXJzZWQpICYmIHBhcnNlZCA+PSAwID8gcGFyc2VkIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgYnVpbGRTeW50aGV0aWNQcml2YXRlQm9va21hcmsob2Zmc2V0OiBudW1iZXIpOiBzdHJpbmcge1xuICAgIHJldHVybiBgJHtGYWJyaWNDb250cmFjdEFkYXB0ZXIuUFJJVkFURV9CT09LTUFSS19QUkVGSVh9JHtvZmZzZXR9YDtcbiAgfVxuXG4gIHByb3RlY3RlZCBvdmVycmlkZSBnZXRDbGllbnQoKTogdm9pZCB7XG4gICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRXJyb3IoXCJDbGllbnQgaXMgbm90IHN1cHBvcnRlZCBpbiBGYWJyaWMgY29udHJhY3RzXCIpO1xuICB9XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVGV4dCBkZWNvZGVyIGZvciBjb252ZXJ0aW5nIGJpbmFyeSBkYXRhIHRvIHN0cmluZ3NcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIHRleHREZWNvZGVyID0gbmV3IFRleHREZWNvZGVyKFwidXRmOFwiKTtcblxuICBwcm90ZWN0ZWQgc3RhdGljIHJlYWRvbmx5IHNlcmlhbGl6ZXIgPSBuZXcgU2ltcGxlRGV0ZXJtaW5pc3RpY1NlcmlhbGl6ZXIoKTtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENvbnRleHQgY29uc3RydWN0b3IgZm9yIHRoaXMgYWRhcHRlclxuICAgKiBAc3VtbWFyeSBPdmVycmlkZXMgdGhlIGJhc2UgQ29udGV4dCBjb25zdHJ1Y3RvciB3aXRoIEZhYnJpY0NvbnRyYWN0Q29udGV4dFxuICAgKi9cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIGdldCBDb250ZXh0KCk6IENvbnN0cnVjdG9yPEZhYnJpY0NvbnRyYWN0Q29udGV4dD4ge1xuICAgIHJldHVybiBGYWJyaWNDb250cmFjdENvbnRleHQ7XG4gIH1cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHZXRzIHRoZSByZXBvc2l0b3J5IGNvbnN0cnVjdG9yIGZvciB0aGlzIGFkYXB0ZXJcbiAgICogQHN1bW1hcnkgUmV0dXJucyB0aGUgRmFicmljQ29udHJhY3RSZXBvc2l0b3J5IGNvbnN0cnVjdG9yIGZvciBjcmVhdGluZyByZXBvc2l0b3JpZXNcbiAgICogQHRlbXBsYXRlIE0gLSBUeXBlIGV4dGVuZGluZyBNb2RlbFxuICAgKiBAcmV0dXJuIHtDb25zdHJ1Y3RvcjxSZXBvc2l0b3J5PE0sIE1hbmdvUXVlcnksIEZhYnJpY0NvbnRyYWN0QWRhcHRlciwgRmFicmljQ29udHJhY3RGbGFncywgRmFicmljQ29udHJhY3RDb250ZXh0Pj59IFRoZSByZXBvc2l0b3J5IGNvbnN0cnVjdG9yXG4gICAqL1xuICBvdmVycmlkZSByZXBvc2l0b3J5PFxuICAgIFIgZXh0ZW5kcyBSZXBvc2l0b3J5PFxuICAgICAgYW55LFxuICAgICAgQWRhcHRlcjxhbnksIHZvaWQsIE1hbmdvUXVlcnksIENvbnRleHQ8RmFicmljQ29udHJhY3RGbGFncz4+XG4gICAgPixcbiAgPigpOiBDb25zdHJ1Y3RvcjxSPiB7XG4gICAgcmV0dXJuIEZhYnJpY0NvbnRyYWN0UmVwb3NpdG9yeSBhcyB1bmtub3duIGFzIENvbnN0cnVjdG9yPFI+O1xuICB9XG5cbiAgb3ZlcnJpZGUgUGFnaW5hdG9yPE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgcXVlcnk6IE1hbmdvUXVlcnksXG4gICAgc2l6ZTogbnVtYmVyLFxuICAgIGNsYXp6OiBDb25zdHJ1Y3RvcjxNPlxuICApOiBQYWdpbmF0b3I8TSwgYW55LCBNYW5nb1F1ZXJ5PiB7XG4gICAgcmV0dXJuIG5ldyBGYWJyaWNDb250cmFjdFBhZ2luYXRvcih0aGlzLCBxdWVyeSwgc2l6ZSwgY2xhenopO1xuICB9XG5cbiAgb3ZlcnJpZGUgYXN5bmMgU2VxdWVuY2Uob3B0aW9uczogU2VxdWVuY2VPcHRpb25zKTogUHJvbWlzZTxTZXF1ZW5jZT4ge1xuICAgIHJldHVybiBuZXcgRmFicmljQ29udHJhY3RTZXF1ZW5jZShvcHRpb25zLCB0aGlzIGFzIGFueSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgRGlzcGF0Y2goKTogRGlzcGF0Y2g8RmFicmljQ29udHJhY3RBZGFwdGVyPiB7XG4gICAgcmV0dXJuIG5ldyBGYWJyaWNDb250cmFjdERpc3BhdGNoKCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBuZXcgRmFicmljQ29udHJhY3RBZGFwdGVyIGluc3RhbmNlXG4gICAqIEBzdW1tYXJ5IEluaXRpYWxpemVzIGFuIGFkYXB0ZXIgZm9yIGludGVyYWN0aW5nIHdpdGggdGhlIEZhYnJpYyBzdGF0ZSBkYXRhYmFzZVxuICAgKiBAcGFyYW0ge3ZvaWR9IHNjb3BlIC0gTm90IHVzZWQgaW4gdGhpcyBhZGFwdGVyXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbYWxpYXNdIC0gT3B0aW9uYWwgYWxpYXMgZm9yIHRoZSBhZGFwdGVyIGluc3RhbmNlXG4gICAqL1xuICBjb25zdHJ1Y3RvcihzY29wZTogdm9pZCwgYWxpYXM/OiBzdHJpbmcpIHtcbiAgICBzdXBlcihzY29wZSwgRmFicmljRmxhdm91ciwgYWxpYXMpO1xuICB9XG5cbiAgb3ZlcnJpZGUgZm9yKGNvbmZpZzogUGFydGlhbDxhbnk+LCAuLi5hcmdzOiBhbnkpOiB0eXBlb2YgdGhpcyB7XG4gICAgcmV0dXJuIHN1cGVyLmZvcihjb25maWcsIC4uLmFyZ3MpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldE1vZGVsRGVmYXVsdHM8TSBleHRlbmRzIE1vZGVsPihjbGF6ejogQ29uc3RydWN0b3I8TT4pIHtcbiAgICBjb25zdCBtID0gbmV3IGNsYXp6KCk7XG4gICAgcmV0dXJuIChNZXRhZGF0YS5wcm9wZXJ0aWVzKGNsYXp6KSB8fCBbXSkucmVkdWNlKFxuICAgICAgKGFjYywgcCkgPT4ge1xuICAgICAgICBpZiAodHlwZW9mIG1bcCBhcyBrZXlvZiBNXSAhPT0gXCJ1bmRlZmluZWRcIilcbiAgICAgICAgICBhY2NbcCBhcyBrZXlvZiBNXSA9IG1bcCBhcyBrZXlvZiBNXTtcbiAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgIH0sXG4gICAgICB7fSBhcyBSZWNvcmQ8a2V5b2YgTSwgYW55PlxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSByZWNvcmQgaW4gdGhlIHN0YXRlIGRhdGFiYXNlXG4gICAqIEBzdW1tYXJ5IFNlcmlhbGl6ZXMgYSBtb2RlbCBhbmQgc3RvcmVzIGl0IGluIHRoZSBGYWJyaWMgc3RhdGUgZGF0YWJhc2VcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZS9jb2xsZWN0aW9uXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgbnVtYmVyfSBpZCAtIFRoZSByZWNvcmQgaWRlbnRpZmllclxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IG1vZGVsIC0gVGhlIHJlY29yZCBkYXRhXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gdHJhbnNpZW50IC0gVHJhbnNpZW50IGRhdGEgKG5vdCB1c2VkIGluIHRoaXMgaW1wbGVtZW50YXRpb24pXG4gICAqIEBwYXJhbSB7Li4uYW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cywgaW5jbHVkaW5nIHRoZSBjaGFpbmNvZGUgc3R1YiBhbmQgbG9nZ2VyXG4gICAqIEByZXR1cm4ge1Byb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj59IFByb21pc2UgcmVzb2x2aW5nIHRvIHRoZSBjcmVhdGVkIHJlY29yZFxuICAgKi9cbiAgb3ZlcnJpZGUgYXN5bmMgY3JlYXRlPE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgY2xheno6IENvbnN0cnVjdG9yPE0+LFxuICAgIGlkOiBQcmltYXJ5S2V5VHlwZSxcbiAgICBtb2RlbDogUmVjb3JkPHN0cmluZywgYW55PixcbiAgICAuLi5hcmdzOiBDb250ZXh0dWFsQXJnczxDb250ZXh0PEZhYnJpY0NvbnRyYWN0RmxhZ3M+PlxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+IHtcbiAgICBjb25zdCB7IGN0eCwgbG9nIH0gPSB0aGlzLmxvZ0N0eChhcmdzLCB0aGlzLmNyZWF0ZSk7XG4gICAgdGhpcy5lbmZvcmNlTWlycm9yQXV0aG9yaXphdGlvbihjbGF6eiwgY3R4KTtcbiAgICBsb2cuaW5mbyhgaW4gQURBUFRFUiBjcmVhdGUgd2l0aCBhcmdzICR7YXJnc31gKTtcbiAgICBjb25zdCB0YWJsZU5hbWUgPSBNb2RlbC50YWJsZU5hbWUoY2xhenopO1xuICAgIGNvbnN0IGNvbXBvc2VkS2V5ID0gY3R4LnN0dWIuY3JlYXRlQ29tcG9zaXRlS2V5KHRhYmxlTmFtZSwgW1N0cmluZyhpZCldKTtcbiAgICBjb25zdCBtaXJyb3JDb2xsZWN0aW9uID0gY3R4LmdldE9yVW5kZWZpbmVkKFwibWlycm9yQ29sbGVjdGlvblwiKSBhc1xuICAgICAgfCBzdHJpbmdcbiAgICAgIHwgdW5kZWZpbmVkO1xuICAgIGNvbnN0IGZ1bGx5U2VncmVnYXRlZCA9IGN0eC5pc0Z1bGx5U2VncmVnYXRlZCAmJiAhbWlycm9yQ29sbGVjdGlvbjtcblxuICAgIGlmICghbWlycm9yQ29sbGVjdGlvbikge1xuICAgICAgbGV0IGV4aXN0aW5nOiBhbnk7XG4gICAgICB0cnkge1xuICAgICAgICBleGlzdGluZyA9IGF3YWl0IHRoaXMucmVhZFN0YXRlKGNvbXBvc2VkS2V5LCBjdHgpO1xuICAgICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZXgtYXNzaWduXG4gICAgICAgIGUgPSB0aGlzLnBhcnNlRXJyb3IoZSBhcyBFcnJvcik7XG4gICAgICAgIGlmICghKGUgaW5zdGFuY2VvZiBOb3RGb3VuZEVycm9yKSkgdGhyb3cgZTtcbiAgICAgIH1cbiAgICAgIGlmIChleGlzdGluZylcbiAgICAgICAgdGhyb3cgbmV3IENvbmZsaWN0RXJyb3IoXG4gICAgICAgICAgYHJlY29yZCB3aXRoIGlkICR7aWR9IGluIHRhYmxlICR7dGFibGVOYW1lfSBhbHJlYWR5IGV4aXN0c2BcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgbG9nLmluZm8oYGFkZGluZyBlbnRyeSB0byAke3RhYmxlTmFtZX0gdGFibGUgd2l0aCBwayAke2lkfWApO1xuXG4gICAgICBpZiAobWlycm9yQ29sbGVjdGlvbikge1xuICAgICAgICBtb2RlbCA9IGF3YWl0IHRoaXMuZm9yUHJpdmF0ZShtaXJyb3JDb2xsZWN0aW9uKS5wdXRTdGF0ZShcbiAgICAgICAgICBjb21wb3NlZEtleSxcbiAgICAgICAgICBtb2RlbCxcbiAgICAgICAgICBjdHhcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGRlZmF1bHRzID0gdGhpcy5nZXRNb2RlbERlZmF1bHRzKGNsYXp6KTtcbiAgICAgICAgLy8gaGFuZGxlIHB1YmxpYyBkYXRhIGlmIG5vdCBmdWxseSBzZWdyZWdhdGVkXG4gICAgICAgIGlmICghZnVsbHlTZWdyZWdhdGVkKSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgT2JqZWN0LmtleXMobW9kZWwpLmZpbHRlcigoaykgPT4ge1xuICAgICAgICAgICAgICBpZiAoayA9PT0gQ291Y2hEQktleXMuVEFCTEUpIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgcmV0dXJuICEoXG4gICAgICAgICAgICAgICAgZGVmYXVsdHMgJiZcbiAgICAgICAgICAgICAgICBrIGluIGRlZmF1bHRzICYmXG4gICAgICAgICAgICAgICAgZGVmYXVsdHNbayBhcyBrZXlvZiBNXSA9PT0gbW9kZWxba11cbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0pLmxlbmd0aFxuICAgICAgICAgIClcbiAgICAgICAgICAgIG1vZGVsID0gYXdhaXQgdGhpcy5wdXRTdGF0ZShjb21wb3NlZEtleSwgbW9kZWwsIGN0eCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBoYW5kbGUgc2VncmVnYXRlZCB3cml0ZXNcbiAgICAgICAgY29uc3QgZGF0YSA9IGN0eC5nZXRGcm9tQ2hpbGRyZW4oXCJzZWdyZWdhdGVkRGF0YVwiKTtcbiAgICAgICAgaWYgKGRhdGEpIHtcbiAgICAgICAgICBmb3IgKGNvbnN0IGNvbGxlY3Rpb24gaW4gZGF0YSkge1xuICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihcbiAgICAgICAgICAgICAgbW9kZWwsXG4gICAgICAgICAgICAgIGF3YWl0IHRoaXMuZm9yUHJpdmF0ZShjb2xsZWN0aW9uKS5wdXRTdGF0ZShcbiAgICAgICAgICAgICAgICBjb21wb3NlZEtleSxcbiAgICAgICAgICAgICAgICBkYXRhW2NvbGxlY3Rpb25dW2lkIGFzIGFueV0sXG4gICAgICAgICAgICAgICAgY3R4XG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgdGhpcy5wYXJzZUVycm9yKGUgYXMgRXJyb3IpO1xuICAgIH1cblxuICAgIHJldHVybiBtb2RlbDtcbiAgfVxuXG4gIG92ZXJyaWRlIGFzeW5jIGNyZWF0ZUFsbDxNIGV4dGVuZHMgTW9kZWw+KFxuICAgIHRhYmxlTmFtZTogQ29uc3RydWN0b3I8TT4sXG4gICAgaWQ6IFByaW1hcnlLZXlUeXBlW10sXG4gICAgbW9kZWw6IFJlY29yZDxzdHJpbmcsIGFueT5bXSxcbiAgICAuLi5hcmdzOiBDb250ZXh0dWFsQXJnczxGYWJyaWNDb250cmFjdENvbnRleHQ+XG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55PltdPiB7XG4gICAgaWYgKGlkLmxlbmd0aCAhPT0gbW9kZWwubGVuZ3RoKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJJZHMgYW5kIG1vZGVscyBtdXN0IGhhdmUgdGhlIHNhbWUgbGVuZ3RoXCIpO1xuICAgIGNvbnN0IHsgbG9nLCBjdHhBcmdzIH0gPSB0aGlzLmxvZ0N0eChhcmdzLCB0aGlzLmNyZWF0ZUFsbCk7XG4gICAgY29uc3QgdGFibGVMYWJlbCA9IE1vZGVsLnRhYmxlTmFtZSh0YWJsZU5hbWUpO1xuICAgIGxvZy5kZWJ1ZyhgQ3JlYXRpbmcgJHtpZC5sZW5ndGh9IGVudHJpZXMgJHt0YWJsZUxhYmVsfSB0YWJsZWApO1xuICAgIHJldHVybiBQcm9taXNlLmFsbChcbiAgICAgIGlkLm1hcCgoaSwgY291bnQpID0+IHRoaXMuY3JlYXRlKHRhYmxlTmFtZSwgaSwgbW9kZWxbY291bnRdLCAuLi5jdHhBcmdzKSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZWFkcyBhIHJlY29yZCBmcm9tIHRoZSBzdGF0ZSBkYXRhYmFzZVxuICAgKiBAc3VtbWFyeSBSZXRyaWV2ZXMgYW5kIGRlc2VyaWFsaXplcyBhIHJlY29yZCBmcm9tIHRoZSBGYWJyaWMgc3RhdGUgZGF0YWJhc2VcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZS9jb2xsZWN0aW9uXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgbnVtYmVyfSBpZCAtIFRoZSByZWNvcmQgaWRlbnRpZmllclxuICAgKiBAcGFyYW0gey4uLmFueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHMsIGluY2x1ZGluZyB0aGUgY2hhaW5jb2RlIHN0dWIgYW5kIGxvZ2dlclxuICAgKiBAcmV0dXJuIHtQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+fSBQcm9taXNlIHJlc29sdmluZyB0byB0aGUgcmV0cmlldmVkIHJlY29yZFxuICAgKi9cbiAgb3ZlcnJpZGUgYXN5bmMgcmVhZDxNIGV4dGVuZHMgTW9kZWw+KFxuICAgIGNsYXp6OiBDb25zdHJ1Y3RvcjxNPixcbiAgICBpZDogUHJpbWFyeUtleVR5cGUsXG4gICAgLi4uYXJnczogQ29udGV4dHVhbEFyZ3M8Q29udGV4dDxGYWJyaWNDb250cmFjdEZsYWdzPj5cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+PiB7XG4gICAgY29uc3QgeyBjdHgsIGxvZyB9ID0gdGhpcy5sb2dDdHgoYXJncywgdGhpcy5yZWFkKTtcbiAgICBsb2cuaW5mbyhgaW4gQURBUFRFUiByZWFkIHdpdGggYXJncyAke2FyZ3N9YCk7XG4gICAgY29uc3QgdGFibGVOYW1lID0gTW9kZWwudGFibGVOYW1lKGNsYXp6KTtcblxuICAgIGNvbnN0IGNvbXBvc2VkS2V5ID0gY3R4LnN0dWIuY3JlYXRlQ29tcG9zaXRlS2V5KHRhYmxlTmFtZSwgW1N0cmluZyhpZCldKTtcbiAgICBjb25zdCBtaXJyb3JDb2xsZWN0aW9uID0gY3R4LmdldE9yVW5kZWZpbmVkKFwibWlycm9yQ29sbGVjdGlvblwiKSBhc1xuICAgICAgfCBzdHJpbmdcbiAgICAgIHwgdW5kZWZpbmVkO1xuICAgIGNvbnN0IGlzTWlycm9yID0gY3R4LmdldE9yVW5kZWZpbmVkKFwibWlycm9yXCIpIGFzIGJvb2xlYW4gfCB1bmRlZmluZWQ7XG4gICAgaWYgKGlzTWlycm9yICYmIG1pcnJvckNvbGxlY3Rpb24pIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmZvclByaXZhdGUobWlycm9yQ29sbGVjdGlvbikucmVhZFN0YXRlKFxuICAgICAgICAgIGNvbXBvc2VkS2V5LFxuICAgICAgICAgIGN0eFxuICAgICAgICApO1xuICAgICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgICB0aHJvdyB0aGlzLnBhcnNlRXJyb3IoZSBhcyBFcnJvcik7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBjdHgucHV0KFwibWlycm9yXCIgYXMgYW55LCB1bmRlZmluZWQpO1xuICAgICAgICBjdHgucHV0KFwibWlycm9yQ29sbGVjdGlvblwiIGFzIGFueSwgdW5kZWZpbmVkKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBsZXQgbW9kZWw6IFJlY29yZDxzdHJpbmcsIGFueT47XG5cbiAgICB0cnkge1xuICAgICAgbW9kZWwgPSBjdHguaXNGdWxseVNlZ3JlZ2F0ZWRcbiAgICAgICAgPyB7fVxuICAgICAgICA6IGF3YWl0IHRoaXMucmVhZFN0YXRlKGNvbXBvc2VkS2V5LCBjdHgpO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHRocm93IHRoaXMucGFyc2VFcnJvcihlIGFzIEVycm9yKTtcbiAgICB9XG5cbiAgICBjb25zdCByZWFkQ29sbGVjdGlvbnMgPSBuZXcgU2V0PHN0cmluZz4oW1xuICAgICAgLi4uKGN0eC5nZXRSZWFkQ29sbGVjdGlvbnMoKSB8fCBbXSksXG4gICAgICAuLi4oY3R4LmNvbnN1bWVSZWFkQ29sbGVjdGlvbnMoKSB8fCBbXSksXG4gICAgXSk7XG4gICAgZm9yIChjb25zdCBjb2wgb2YgcmVhZENvbGxlY3Rpb25zKSB7XG4gICAgICB0cnkge1xuICAgICAgICBPYmplY3QuYXNzaWduKG1vZGVsLCBhd2FpdCB0aGlzLmZvclByaXZhdGUoY29sKS5yZWFkU3RhdGUoY29tcG9zZWRLZXksIGN0eCkpO1xuICAgICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgICBjb25zdCBwYXJzZWQgPSB0aGlzLnBhcnNlRXJyb3IoZSBhcyBFcnJvcik7XG4gICAgICAgIGlmIChwYXJzZWQgaW5zdGFuY2VvZiBOb3RGb3VuZEVycm9yKSBjb250aW51ZTtcbiAgICAgICAgdGhyb3cgcGFyc2VkO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoIU9iamVjdC5rZXlzKG1vZGVsKS5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBOb3RGb3VuZEVycm9yKFxuICAgICAgICBgcmVjb3JkIHdpdGggaWQgJHtpZH0gaW4gdGFibGUgJHt0YWJsZU5hbWV9IGRvZXMgbm90IGV4aXN0YFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIG1vZGVsO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgbXVsdGlwbGUgcmVjb3JkcyBmcm9tIHRoZSBkYXRhYmFzZVxuICAgKiBAc3VtbWFyeSBGZXRjaGVzIG11bHRpcGxlIHJlY29yZHMgd2l0aCB0aGUgZ2l2ZW4gSURzIGZyb20gdGhlIHNwZWNpZmllZCB0YWJsZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFibGVOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHRhYmxlIHRvIHJlYWQgZnJvbVxuICAgKiBAcGFyYW0gaWQgLSBUaGUgaWRlbnRpZmllcnMgb2YgdGhlIHJlY29yZHMgdG8gcmV0cmlldmVcbiAgICogQHBhcmFtIHsuLi5hbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzIHNwZWNpZmljIHRvIHRoZSBhZGFwdGVyIGltcGxlbWVudGF0aW9uXG4gICAqIEByZXR1cm4gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYW4gYXJyYXkgb2YgcmV0cmlldmVkIHJlY29yZHNcbiAgICovXG4gIG92ZXJyaWRlIGFzeW5jIHJlYWRBbGw8TSBleHRlbmRzIE1vZGVsPihcbiAgICBjbGF6ejogQ29uc3RydWN0b3I8TT4sXG4gICAgaWQ6IFByaW1hcnlLZXlUeXBlW10sXG4gICAgLi4uYXJnczogQ29udGV4dHVhbEFyZ3M8Q29udGV4dDxGYWJyaWNDb250cmFjdEZsYWdzPj5cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+W10+IHtcbiAgICBjb25zdCB7IGxvZywgY3R4IH0gPSB0aGlzLmxvZ0N0eChhcmdzLCB0aGlzLnJlYWRBbGwpO1xuICAgIGNvbnN0IHRhYmxlTmFtZSA9IE1vZGVsLnRhYmxlTmFtZShjbGF6eik7XG4gICAgbG9nLmRlYnVnKGBSZWFkaW5nICR7aWQubGVuZ3RofSBlbnRyaWVzICR7dGFibGVOYW1lfSB0YWJsZWApO1xuICAgIGNvbnN0IGJyZWFrT25TaW5nbGVGYWlsdXJlID0gY3R4LmdldChcImJyZWFrT25TaW5nbGVGYWlsdXJlSW5CdWxrXCIpID8/IHRydWU7XG4gICAgY29uc3QgY29udGludWVPbkVycm9yID0gIWJyZWFrT25TaW5nbGVGYWlsdXJlO1xuXG4gICAgY29uc3QgbWlycm9yQ29sbGVjdGlvbiA9IGN0eC5nZXRPclVuZGVmaW5lZChcIm1pcnJvckNvbGxlY3Rpb25cIikgYXNcbiAgICAgIHwgc3RyaW5nXG4gICAgICB8IHVuZGVmaW5lZDtcbiAgICBjb25zdCBpc01pcnJvciA9IGN0eC5nZXRPclVuZGVmaW5lZChcIm1pcnJvclwiKSBhcyBib29sZWFuIHwgdW5kZWZpbmVkO1xuXG4gICAgY29uc3QgcmVhZE1pcnJvciA9IGFzeW5jIDxNIGV4dGVuZHMgTW9kZWw+KFxuICAgICAgY2xheno6IENvbnN0cnVjdG9yPE0+LFxuICAgICAgaWQ6IFByaW1hcnlLZXlUeXBlLFxuICAgICAgLi4uYXJnczogQ29udGV4dHVhbEFyZ3M8Q29udGV4dDxGYWJyaWNDb250cmFjdEZsYWdzPj5cbiAgICApID0+IHtcbiAgICAgIGlmICghbWlycm9yQ29sbGVjdGlvbilcbiAgICAgICAgdGhyb3cgbmV3IEJhZFJlcXVlc3RFcnJvcihcIk1pc3NpbmcgbWlycm9yIGNvbGxlY3Rpb24gZm9yIG1pcnJvciByZWFkXCIpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgeyBjdHgsIGxvZyB9ID0gdGhpcy5sb2dDdHgoYXJncywgcmVhZE1pcnJvcik7XG4gICAgICAgIGxvZy5pbmZvKGBpbiBBREFQVEVSIHJlYWQgd2l0aCBhcmdzICR7YXJnc31gKTtcbiAgICAgICAgY29uc3QgdGFibGVOYW1lID0gTW9kZWwudGFibGVOYW1lKGNsYXp6KTtcblxuICAgICAgICBjb25zdCBjb21wb3NlZEtleSA9IGN0eC5zdHViLmNyZWF0ZUNvbXBvc2l0ZUtleSh0YWJsZU5hbWUsIFtcbiAgICAgICAgICBTdHJpbmcoaWQpLFxuICAgICAgICBdKTtcblxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5mb3JQcml2YXRlKG1pcnJvckNvbGxlY3Rpb24pLnJlYWRTdGF0ZShcbiAgICAgICAgICBjb21wb3NlZEtleSxcbiAgICAgICAgICBjdHhcbiAgICAgICAgKTtcbiAgICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgICAgdGhyb3cgdGhpcy5wYXJzZUVycm9yKGUgYXMgRXJyb3IpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgdGFza3MgPSBpZC5tYXAoXG4gICAgICAgIChpKSA9PiAoKSA9PlxuICAgICAgICAgIGlzTWlycm9yICYmIG1pcnJvckNvbGxlY3Rpb25cbiAgICAgICAgICAgID8gcmVhZE1pcnJvcihcbiAgICAgICAgICAgICAgICBjbGF6eixcbiAgICAgICAgICAgICAgICBpLFxuICAgICAgICAgICAgICAgIC4uLmFyZ3MsXG4gICAgICAgICAgICAgICAgY3R4Lm92ZXJyaWRlKHsgbm9FbWl0U2luZ2xlOiB0cnVlIH0pXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIDogdGhpcy5yZWFkKGNsYXp6LCBpLCAuLi5hcmdzLCBjdHgub3ZlcnJpZGUoeyBub0VtaXRTaW5nbGU6IHRydWUgfSkpXG4gICAgICApO1xuXG4gICAgICBjb25zdCByYXdSZXN1bHQgPSBjb250aW51ZU9uRXJyb3JcbiAgICAgICAgPyBhd2FpdCBwcm9taXNlU2VxdWVuY2UodGFza3MsIHRydWUpXG4gICAgICAgIDogYXdhaXQgcHJvbWlzZVNlcXVlbmNlKHRhc2tzKTtcbiAgICAgIHJldHVybiByZXNvbHZlQnVsa1NlcXVlbmNlUmVzdWx0KFxuICAgICAgICByYXdSZXN1bHQsXG4gICAgICAgIGNvbnRpbnVlT25FcnJvcixcbiAgICAgICAgbG9nLFxuICAgICAgICBCdWxrQ3J1ZE9wZXJhdGlvbktleXMuUkVBRF9BTExcbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhyb3cgdGhpcy5wYXJzZUVycm9yKGUgYXMgRXJyb3IpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBjdHgucHV0KFwibWlycm9yXCIgYXMgYW55LCB1bmRlZmluZWQpO1xuICAgICAgY3R4LnB1dChcIm1pcnJvckNvbGxlY3Rpb25cIiBhcyBhbnksIHVuZGVmaW5lZCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBVcGRhdGVzIGEgcmVjb3JkIGluIHRoZSBzdGF0ZSBkYXRhYmFzZVxuICAgKiBAc3VtbWFyeSBTZXJpYWxpemVzIGEgbW9kZWwgYW5kIHVwZGF0ZXMgaXQgaW4gdGhlIEZhYnJpYyBzdGF0ZSBkYXRhYmFzZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFibGVOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHRhYmxlL2NvbGxlY3Rpb25cbiAgICogQHBhcmFtIHtzdHJpbmcgfCBudW1iZXJ9IGlkIC0gVGhlIHJlY29yZCBpZGVudGlmaWVyXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gbW9kZWwgLSBUaGUgdXBkYXRlZCByZWNvcmQgZGF0YVxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IHRyYW5zaWVudCAtIFRyYW5zaWVudCBkYXRhIChub3QgdXNlZCBpbiB0aGlzIGltcGxlbWVudGF0aW9uKVxuICAgKiBAcGFyYW0gey4uLmFueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHMsIGluY2x1ZGluZyB0aGUgY2hhaW5jb2RlIHN0dWIgYW5kIGxvZ2dlclxuICAgKiBAcmV0dXJuIHtQcm9taXNlPFJlY29yZDxzdHJpbmcsIGFueT4+fSBQcm9taXNlIHJlc29sdmluZyB0byB0aGUgdXBkYXRlZCByZWNvcmRcbiAgICovXG4gIG92ZXJyaWRlIGFzeW5jIHVwZGF0ZTxNIGV4dGVuZHMgTW9kZWw+KFxuICAgIGNsYXp6OiBDb25zdHJ1Y3RvcjxNPixcbiAgICBpZDogUHJpbWFyeUtleVR5cGUsXG4gICAgbW9kZWw6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgLi4uYXJnczogQ29udGV4dHVhbEFyZ3M8Q29udGV4dDxGYWJyaWNDb250cmFjdEZsYWdzPj5cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+PiB7XG4gICAgY29uc3QgeyBjdHgsIGxvZyB9ID0gdGhpcy5sb2dDdHgoYXJncywgdGhpcy51cGRhdGUpO1xuXG4gICAgdGhpcy5lbmZvcmNlTWlycm9yQXV0aG9yaXphdGlvbihjbGF6eiwgY3R4KTtcbiAgICBsb2cuaW5mbyhgaW4gQURBUFRFUiB1cGRhdGUgd2l0aCBhcmdzICR7YXJnc31gKTtcbiAgICBjb25zdCB0YWJsZU5hbWUgPSBNb2RlbC50YWJsZU5hbWUoY2xhenopO1xuICAgIGNvbnN0IGNvbXBvc2VkS2V5ID0gY3R4LnN0dWIuY3JlYXRlQ29tcG9zaXRlS2V5KHRhYmxlTmFtZSwgW1N0cmluZyhpZCldKTtcbiAgICBjb25zdCBtaXJyb3JDb2xsZWN0aW9uID0gY3R4LmdldE9yVW5kZWZpbmVkKFwibWlycm9yQ29sbGVjdGlvblwiKSBhc1xuICAgICAgfCBzdHJpbmdcbiAgICAgIHwgdW5kZWZpbmVkO1xuXG4gICAgdHJ5IHtcbiAgICAgIGxvZy5pbmZvKGB1cGRhdGluZyBlbnRyeSBpbiAke3RhYmxlTmFtZX0gdGFibGUgd2l0aCBwayAke2lkfWApO1xuXG4gICAgICBpZiAobWlycm9yQ29sbGVjdGlvbikge1xuICAgICAgICBtb2RlbCA9IGF3YWl0IHRoaXMuZm9yUHJpdmF0ZShtaXJyb3JDb2xsZWN0aW9uKS5wdXRTdGF0ZShcbiAgICAgICAgICBjb21wb3NlZEtleSxcbiAgICAgICAgICBtb2RlbCxcbiAgICAgICAgICBjdHhcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGRlZmF1bHRzID0gdGhpcy5nZXRNb2RlbERlZmF1bHRzKGNsYXp6KTtcbiAgICAgICAgLy8gaGFuZGxlIHB1YmxpYyBkYXRhXG4gICAgICAgIGlmIChcbiAgICAgICAgICBPYmplY3Qua2V5cyhtb2RlbCkuZmlsdGVyKChrKSA9PiB7XG4gICAgICAgICAgICBpZiAoayA9PT0gQ291Y2hEQktleXMuVEFCTEUpIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIHJldHVybiAhKFxuICAgICAgICAgICAgICBkZWZhdWx0cyAmJlxuICAgICAgICAgICAgICBrIGluIGRlZmF1bHRzICYmXG4gICAgICAgICAgICAgIGRlZmF1bHRzW2sgYXMga2V5b2YgTV0gPT09IG1vZGVsW2tdXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pLmxlbmd0aFxuICAgICAgICApXG4gICAgICAgICAgbW9kZWwgPSBhd2FpdCB0aGlzLnB1dFN0YXRlKGNvbXBvc2VkS2V5LCBtb2RlbCwgY3R4KTtcblxuICAgICAgICAvLyBoYW5kbGUgc2VncmVnYXRlZCB3cml0ZXNcbiAgICAgICAgY29uc3QgZGF0YSA9IGN0eC5nZXRGcm9tQ2hpbGRyZW4oXCJzZWdyZWdhdGVkRGF0YVwiKTtcbiAgICAgICAgaWYgKGRhdGEpIHtcbiAgICAgICAgICBmb3IgKGNvbnN0IGNvbGxlY3Rpb24gaW4gZGF0YSkge1xuICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihcbiAgICAgICAgICAgICAgbW9kZWwsXG4gICAgICAgICAgICAgIGF3YWl0IHRoaXMuZm9yUHJpdmF0ZShjb2xsZWN0aW9uKS5wdXRTdGF0ZShcbiAgICAgICAgICAgICAgICBjb21wb3NlZEtleSxcbiAgICAgICAgICAgICAgICBkYXRhW2NvbGxlY3Rpb25dW2lkIGFzIGFueV0sXG4gICAgICAgICAgICAgICAgY3R4XG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgdGhyb3cgdGhpcy5wYXJzZUVycm9yKGUgYXMgRXJyb3IpO1xuICAgIH1cblxuICAgIHJldHVybiBtb2RlbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRGVsZXRlcyBhIHJlY29yZCBmcm9tIHRoZSBzdGF0ZSBkYXRhYmFzZVxuICAgKiBAc3VtbWFyeSBSZXRyaWV2ZXMgYSByZWNvcmQgYW5kIHRoZW4gcmVtb3ZlcyBpdCBmcm9tIHRoZSBGYWJyaWMgc3RhdGUgZGF0YWJhc2VcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRhYmxlTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB0YWJsZS9jb2xsZWN0aW9uXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgbnVtYmVyfSBpZCAtIFRoZSByZWNvcmQgaWRlbnRpZmllciB0byBkZWxldGVcbiAgICogQHBhcmFtIHsuLi5hbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzLCBpbmNsdWRpbmcgdGhlIGNoYWluY29kZSBzdHViIGFuZCBsb2dnZXJcbiAgICogQHJldHVybiB7UHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+Pn0gUHJvbWlzZSByZXNvbHZpbmcgdG8gdGhlIGRlbGV0ZWQgcmVjb3JkXG4gICAqL1xuICBhc3luYyBkZWxldGU8TSBleHRlbmRzIE1vZGVsPihcbiAgICBjbGF6ejogQ29uc3RydWN0b3I8TT4sXG4gICAgaWQ6IFByaW1hcnlLZXlUeXBlLFxuICAgIC4uLmFyZ3M6IENvbnRleHR1YWxBcmdzPENvbnRleHQ8RmFicmljQ29udHJhY3RGbGFncz4+XG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj4ge1xuICAgIGNvbnN0IHsgY3R4LCBsb2cgfSA9IHRoaXMubG9nQ3R4KGFyZ3MsIHRoaXMuZGVsZXRlKTtcblxuICAgIHRoaXMuZW5mb3JjZU1pcnJvckF1dGhvcml6YXRpb24oY2xhenosIGN0eCk7XG4gICAgY29uc3QgdGFibGVOYW1lID0gTW9kZWwudGFibGVOYW1lKGNsYXp6KTtcblxuICAgIGNvbnN0IGNvbXBvc2VkS2V5ID0gY3R4LnN0dWIuY3JlYXRlQ29tcG9zaXRlS2V5KHRhYmxlTmFtZSwgW1N0cmluZyhpZCldKTtcbiAgICBjb25zdCBtaXJyb3JDb2xsZWN0aW9uID0gY3R4LmdldE9yVW5kZWZpbmVkKFwibWlycm9yQ29sbGVjdGlvblwiKSBhc1xuICAgICAgfCBzdHJpbmdcbiAgICAgIHwgdW5kZWZpbmVkO1xuICAgIGxldCBtb2RlbDogUmVjb3JkPHN0cmluZywgYW55PjtcblxuICAgIGlmIChtaXJyb3JDb2xsZWN0aW9uKSB7XG4gICAgICB0cnkge1xuICAgICAgICBtb2RlbCA9IGF3YWl0IHRoaXMuZm9yUHJpdmF0ZShtaXJyb3JDb2xsZWN0aW9uKS5yZWFkU3RhdGUoXG4gICAgICAgICAgY29tcG9zZWRLZXksXG4gICAgICAgICAgY3R4XG4gICAgICAgICk7XG4gICAgICAgIGF3YWl0IHRoaXMuZm9yUHJpdmF0ZShtaXJyb3JDb2xsZWN0aW9uKS5kZWxldGVTdGF0ZShjb21wb3NlZEtleSwgY3R4KTtcbiAgICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgICAgdGhyb3cgdGhpcy5wYXJzZUVycm9yKGUgYXMgRXJyb3IpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0cnkge1xuICAgICAgICBtb2RlbCA9IGN0eC5pc0Z1bGx5U2VncmVnYXRlZFxuICAgICAgICAgID8ge31cbiAgICAgICAgICA6IGF3YWl0IHRoaXMucmVhZFN0YXRlKGNvbXBvc2VkS2V5LCBjdHgpO1xuICAgICAgICBpZiAoIWN0eC5pc0Z1bGx5U2VncmVnYXRlZCkge1xuICAgICAgICAgIGxvZy5kZWJ1ZyhgRGVsZXRpbmcgZW50cnkgJHtjb21wb3NlZEtleX0gZnJvbSBwdWJsaWMgbGVkZ2VyYCk7XG4gICAgICAgICAgYXdhaXQgdGhpcy5kZWxldGVTdGF0ZShjb21wb3NlZEtleSwgY3R4KTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgICB0aHJvdyB0aGlzLnBhcnNlRXJyb3IoZSBhcyBFcnJvcik7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNvbGxlY3Rpb25zID0gY3R4LmdldFJlYWRDb2xsZWN0aW9ucygpO1xuICAgICAgaWYgKGNvbGxlY3Rpb25zICYmIGNvbGxlY3Rpb25zLmxlbmd0aCkge1xuICAgICAgICBmb3IgKGNvbnN0IGNvbCBvZiBjb2xsZWN0aW9ucykge1xuICAgICAgICAgIGxvZy5kZWJ1ZyhcbiAgICAgICAgICAgIGBlbnN1cmluZyBjb2xsZWN0aW9uICR7Y29sfSBoYXMgZW50cnkgZm9yIGlkICR7Y29tcG9zZWRLZXl9IGJlZm9yZSBkZWxldGluZ2BcbiAgICAgICAgICApO1xuICAgICAgICAgIE9iamVjdC5hc3NpZ24oXG4gICAgICAgICAgICBtb2RlbCxcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZm9yUHJpdmF0ZShjb2wpLnJlYWRTdGF0ZShjb21wb3NlZEtleSwgY3R4KVxuICAgICAgICAgICk7XG4gICAgICAgICAgbG9nLmRlYnVnKFxuICAgICAgICAgICAgYERlbGV0aW5nIHByaXZhdGUgY29sbGVjdGlvbiAke2NvbH0gZW50cnkgZm9yIGlkICR7Y29tcG9zZWRLZXl9YFxuICAgICAgICAgICk7XG4gICAgICAgICAgYXdhaXQgdGhpcy5mb3JQcml2YXRlKGNvbCkuZGVsZXRlU3RhdGUoY29tcG9zZWRLZXksIGN0eCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1vZGVsO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGRlbGV0ZVN0YXRlKGlkOiBzdHJpbmcsIGNvbnRleHQ6IEZhYnJpY0NvbnRyYWN0Q29udGV4dCkge1xuICAgIGF3YWl0IGNvbnRleHQuc3R1Yi5kZWxldGVTdGF0ZShpZCk7XG4gIH1cblxuICBmb3JQcml2YXRlKGNvbGxlY3Rpb246IHN0cmluZyk6IEZhYnJpY0NvbnRyYWN0QWRhcHRlciB7XG4gICAgY29uc3QgdG9PdmVycmlkZSA9IFtcbiAgICAgIHRoaXMucHV0U3RhdGUsXG4gICAgICB0aGlzLnJlYWRTdGF0ZSxcbiAgICAgIHRoaXMuZGVsZXRlU3RhdGUsXG4gICAgICB0aGlzLnF1ZXJ5UmVzdWx0LFxuICAgICAgdGhpcy5xdWVyeVJlc3VsdFBhZ2luYXRlZCxcbiAgICBdLm1hcCgoZm4pID0+IGZuLm5hbWUpO1xuICAgIHJldHVybiBuZXcgUHJveHkodGhpcywge1xuICAgICAgZ2V0KHRhcmdldCwgcHJvcCwgcmVjZWl2ZXIpIHtcbiAgICAgICAgaWYgKCF0b092ZXJyaWRlLmluY2x1ZGVzKHByb3AgYXMgc3RyaW5nKSlcbiAgICAgICAgICByZXR1cm4gUmVmbGVjdC5nZXQodGFyZ2V0LCBwcm9wLCByZWNlaXZlcik7XG4gICAgICAgIHJldHVybiBuZXcgUHJveHkoKHRhcmdldCBhcyBhbnkpW3Byb3BdLCB7XG4gICAgICAgICAgYXN5bmMgYXBwbHkoZm4sIHRoaXNBcmcsIGFyZ3NMaXN0KSB7XG4gICAgICAgICAgICBzd2l0Y2ggKHByb3ApIHtcbiAgICAgICAgICAgICAgY2FzZSBcInB1dFN0YXRlXCI6IHtcbiAgICAgICAgICAgICAgICAvLyBwdXRTdGF0ZSBzaWduYXR1cmU6IChpZDogc3RyaW5nLCBtb2RlbDogUmVjb3JkPHN0cmluZywgYW55PiwgY3R4OiBGYWJyaWNDb250cmFjdENvbnRleHQpXG4gICAgICAgICAgICAgICAgY29uc3QgW2lkLCBtb2RlbCwgY3R4XSA9IGFyZ3NMaXN0O1xuICAgICAgICAgICAgICAgIGNvbnN0IGxvZyA9IGN0eC5sb2dnZXIuZm9yKHByb3ApO1xuICAgICAgICAgICAgICAgIGxvZy5kZWJ1ZyhcbiAgICAgICAgICAgICAgICAgIGBQcml2YXRlIHdyaXRlIHRvICR7Y29sbGVjdGlvbn0gZm9yICR7aWQudG9TdHJpbmcoKX1gXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBjb25zdCBkYXRhID0gQnVmZmVyLmZyb20oXG4gICAgICAgICAgICAgICAgICBGYWJyaWNDb250cmFjdEFkYXB0ZXIuc2VyaWFsaXplci5zZXJpYWxpemUoXG4gICAgICAgICAgICAgICAgICAgIG1vZGVsIGFzIE1vZGVsLFxuICAgICAgICAgICAgICAgICAgICBmYWxzZVxuICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY3R4LnN0dWIucHV0UHJpdmF0ZURhdGEoY29sbGVjdGlvbiwgaWQudG9TdHJpbmcoKSwgZGF0YSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG1vZGVsO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGNhc2UgXCJkZWxldGVTdGF0ZVwiOiB7XG4gICAgICAgICAgICAgICAgLy8gZGVsZXRlU3RhdGUgc2lnbmF0dXJlOiAoaWQ6IHN0cmluZywgY29udGV4dDogRmFicmljQ29udHJhY3RDb250ZXh0KVxuICAgICAgICAgICAgICAgIGNvbnN0IFtpZCwgY3R4XSA9IGFyZ3NMaXN0O1xuICAgICAgICAgICAgICAgIGNvbnN0IGxvZyA9IGN0eC5sb2dnZXIuZm9yKHByb3ApO1xuICAgICAgICAgICAgICAgIGxvZy5kZWJ1ZyhcbiAgICAgICAgICAgICAgICAgIGBQcml2YXRlIGRlbGV0ZSBvbiAke2NvbGxlY3Rpb259IGZvciAke2lkLnRvU3RyaW5nKCl9YFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgYXdhaXQgY3R4LnN0dWIuZGVsZXRlUHJpdmF0ZURhdGEoY29sbGVjdGlvbiwgaWQudG9TdHJpbmcoKSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGNhc2UgXCJyZWFkU3RhdGVcIjoge1xuICAgICAgICAgICAgICAgIC8vIHJlYWRTdGF0ZSBzaWduYXR1cmU6IChpZDogc3RyaW5nLCBjdHg6IEZhYnJpY0NvbnRyYWN0Q29udGV4dClcbiAgICAgICAgICAgICAgICBjb25zdCBbaWQsIGN0eF0gPSBhcmdzTGlzdDtcbiAgICAgICAgICAgICAgICBjb25zdCBsb2cgPSBjdHgubG9nZ2VyLmZvcihwcm9wKTtcbiAgICAgICAgICAgICAgICBsb2cuZGVidWcoXG4gICAgICAgICAgICAgICAgICBgUHJpdmF0ZSByZWFkIGZyb20gJHtjb2xsZWN0aW9ufSBmb3IgJHtpZC50b1N0cmluZygpfWBcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBjdHguc3R1Yi5nZXRQcml2YXRlRGF0YShjb2xsZWN0aW9uLCBpZCk7XG4gICAgICAgICAgICAgICAgaWYgKCFkYXRhIHx8ICFkYXRhLnRvU3RyaW5nKCkubGVuZ3RoKVxuICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IE5vdEZvdW5kRXJyb3IoYFJlY29yZCB3aXRoIGlkICR7aWR9IG5vdCBmb3VuZGApO1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gRmFicmljQ29udHJhY3RBZGFwdGVyLnNlcmlhbGl6ZXIuZGVzZXJpYWxpemUoXG4gICAgICAgICAgICAgICAgICAgIGRhdGEudG9TdHJpbmcoXCJ1dGY4XCIpXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEudG9TdHJpbmcoXCJ1dGY4XCIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBjYXNlIFwicXVlcnlSZXN1bHRcIjoge1xuICAgICAgICAgICAgICAgIGNvbnN0IFtzdHViLCByYXdJbnB1dCwgLi4uYXJnc10gPSBhcmdzTGlzdDtcbiAgICAgICAgICAgICAgICBjb25zdCB7IGxvZyB9ID0gdGhpc0FyZ1tcImxvZ0N0eFwiXShhcmdzLCBwcm9wKTtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgbG9nLmRlYnVnKFxuICAgICAgICAgICAgICAgICAgICBgUXVlcnlpbmcgY29sbGVjdGlvbiAke2NvbGxlY3Rpb259IGZvciAke0pTT04uc3RyaW5naWZ5KHJhd0lucHV0KX1gXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgc3R1Yi5nZXRQcml2YXRlRGF0YVF1ZXJ5UmVzdWx0KFxuICAgICAgICAgICAgICAgICAgICBjb2xsZWN0aW9uLFxuICAgICAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeShyYXdJbnB1dClcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICBsb2cudmVyYm9zZShcbiAgICAgICAgICAgICAgICAgICAgYGl0ZXJhdG9yIGZyb20gY29sbGVjdGlvbiAke2NvbGxlY3Rpb259IHJlY2VpdmVkYFxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgIHJldHVybiByZXMuaXRlcmF0b3IgfHwgcmVzO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICAgICAgICAgICAgbG9nLmVycm9yKGUpO1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBjYXNlIFwicXVlcnlSZXN1bHRQYWdpbmF0ZWRcIjoge1xuICAgICAgICAgICAgICAgIGNvbnN0IFtzdHViLCByYXdJbnB1dCwgbGltaXQsIHNraXAsIGJvb2ttYXJrLCAuLi5hcmdzXSA9IGFyZ3NMaXN0O1xuICAgICAgICAgICAgICAgIGNvbnN0IHsgbG9nIH0gPSB0aGlzQXJnW1wibG9nQ3R4XCJdKGFyZ3MsIHByb3ApO1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhZ2VTaXplID0gTWF0aC5tYXgoMSwgTnVtYmVyKGxpbWl0KSB8fCAyNTApO1xuICAgICAgICAgICAgICAgIGNvbnN0IHF1ZXJ5OiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0geyAuLi5yYXdJbnB1dCB9O1xuICAgICAgICAgICAgICAgIGNvbnN0IHNraXBWYWx1ZSA9IE51bWJlcihza2lwKTtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJzZWRTa2lwID1cbiAgICAgICAgICAgICAgICAgIE51bWJlci5pc0ludGVnZXIoc2tpcFZhbHVlKSAmJiBza2lwVmFsdWUgPj0gMFxuICAgICAgICAgICAgICAgICAgICA/IHNraXBWYWx1ZVxuICAgICAgICAgICAgICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICBjb25zdCBzeW50aGV0aWNPZmZzZXQgPVxuICAgICAgICAgICAgICAgICAgRmFicmljQ29udHJhY3RBZGFwdGVyLnBhcnNlU3ludGhldGljUHJpdmF0ZUJvb2ttYXJrKGJvb2ttYXJrKSA/P1xuICAgICAgICAgICAgICAgICAgcGFyc2VkU2tpcCA/P1xuICAgICAgICAgICAgICAgICAgMDtcbiAgICAgICAgICAgICAgICBjb25zdCBoYXNPcGFxdWVCb29rbWFyayA9XG4gICAgICAgICAgICAgICAgICBib29rbWFyayAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgICAgICAgICAgICBib29rbWFyayAhPT0gbnVsbCAmJlxuICAgICAgICAgICAgICAgICAgYm9va21hcmsgIT09IFwiXCIgJiZcbiAgICAgICAgICAgICAgICAgIHR5cGVvZiBib29rbWFyayA9PT0gXCJzdHJpbmdcIiAmJlxuICAgICAgICAgICAgICAgICAgIWJvb2ttYXJrLnN0YXJ0c1dpdGgoRmFicmljQ29udHJhY3RBZGFwdGVyLlBSSVZBVEVfQk9PS01BUktfUFJFRklYKTtcbiAgICAgICAgICAgICAgICAvLyBLZWVwIHRoZSBxdWVyeSBDb3VjaERCLWNvbXBhdGlibGUgYW5kIGxldCBGYWJyaWMvQ291Y2hEQiBvd24gYm9va21hcmsgc2VtYW50aWNzLlxuICAgICAgICAgICAgICAgIC8vIFN5bnRoZXRpYyBtb2RlIGZldGNoZXMgb25lIGV4dHJhIHJlY29yZCB0byBkZXRlY3Qgd2hldGhlciBhIG5leHQgcGFnZSBleGlzdHMuXG4gICAgICAgICAgICAgICAgcXVlcnkubGltaXQgPSBoYXNPcGFxdWVCb29rbWFyayA/IHBhZ2VTaXplIDogcGFnZVNpemUgKyAxO1xuICAgICAgICAgICAgICAgIGlmIChoYXNPcGFxdWVCb29rbWFyaykge1xuICAgICAgICAgICAgICAgICAgcXVlcnkuYm9va21hcmsgPSBib29rbWFyay50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgICAgZGVsZXRlIHF1ZXJ5LnNraXA7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIGRlbGV0ZSBxdWVyeS5ib29rbWFyaztcbiAgICAgICAgICAgICAgICAgIGlmIChzeW50aGV0aWNPZmZzZXQgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHF1ZXJ5LnNraXAgPSBzeW50aGV0aWNPZmZzZXQ7XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBkZWxldGUgcXVlcnkuc2tpcDtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbG9nLmRlYnVnKFxuICAgICAgICAgICAgICAgICAgYFF1ZXJ5aW5nIGNvbGxlY3Rpb24gJHtjb2xsZWN0aW9ufSBmb3IgJHtKU09OLnN0cmluZ2lmeShxdWVyeSl9YFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCAoXG4gICAgICAgICAgICAgICAgICBzdHViIGFzIENoYWluY29kZVN0dWJcbiAgICAgICAgICAgICAgICApLmdldFByaXZhdGVEYXRhUXVlcnlSZXN1bHQoY29sbGVjdGlvbiwgSlNPTi5zdHJpbmdpZnkocXVlcnkpKTtcbiAgICAgICAgICAgICAgICBjb25zdCBpdGVyYXRvciA9XG4gICAgICAgICAgICAgICAgICAoKHJlc3BvbnNlIGFzIGFueSkuaXRlcmF0b3IgfHxcbiAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UpIGFzIEl0ZXJhdG9ycy5TdGF0ZVF1ZXJ5SXRlcmF0b3I7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzcG9uc2VNZXRhZGF0YSA9XG4gICAgICAgICAgICAgICAgICAocmVzcG9uc2UgYXMgYW55KS5tZXRhZGF0YSB8fCAoaXRlcmF0b3IgYXMgYW55KS5tZXRhZGF0YSB8fCB7fTtcbiAgICAgICAgICAgICAgICBjb25zdCByZXNwb25zZUJvb2ttYXJrID1cbiAgICAgICAgICAgICAgICAgIHR5cGVvZiByZXNwb25zZU1ldGFkYXRhLmJvb2ttYXJrID09PSBcInN0cmluZ1wiXG4gICAgICAgICAgICAgICAgICAgID8gcmVzcG9uc2VNZXRhZGF0YS5ib29rbWFya1xuICAgICAgICAgICAgICAgICAgICA6IFwiXCI7XG5cbiAgICAgICAgICAgICAgICBsb2cudmVyYm9zZShgaXRlcmF0b3IgZnJvbSBjb2xsZWN0aW9uICR7Y29sbGVjdGlvbn0gcmVjZWl2ZWRgKTtcbiAgICAgICAgICAgICAgICBjb25zdCBwYWdlZDogQXJyYXk8eyBrZXk6IHN0cmluZzsgdmFsdWU6IEJ1ZmZlciB9PiA9IFtdO1xuICAgICAgICAgICAgICAgIGxldCBoYXNNb3JlID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgaXRlcmF0b3IubmV4dCgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzLmRvbmUpIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXMudmFsdWUgJiYgcmVzLnZhbHVlLnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgY29uc3Qga2V5ID0gcmVzLnZhbHVlLmtleSBhcyBzdHJpbmc7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKHBhZ2VkLmxlbmd0aCA8IHBhZ2VTaXplKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwYWdlZC5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogQnVmZmVyLmlzQnVmZmVyKHJlcy52YWx1ZS52YWx1ZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHJlcy52YWx1ZS52YWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogQnVmZmVyLmZyb20oXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChyZXMudmFsdWUudmFsdWUgYXMgYW55KS50b1N0cmluZyhcInV0ZjhcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgaGFzTW9yZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhazsgLy8gZWFybHkgZXhpdFxuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgICAgICAgICBhd2FpdCBpdGVyYXRvci5jbG9zZSgpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIFdyYXAgdGhlIHBhZ2UgaW4gYW4gYXN5bmMgaXRlcmF0b3IgZm9yIHJlc3VsdEl0ZXJhdG9yKClcbiAgICAgICAgICAgICAgICBsZXQgaWR4ID0gMDtcbiAgICAgICAgICAgICAgICBjb25zdCBhcnJheUl0ZXJhdG9yID0ge1xuICAgICAgICAgICAgICAgICAgYXN5bmMgbmV4dCgpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlkeCA8IHBhZ2VkLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7IHZhbHVlOiBwYWdlZFtpZHgrK10sIGRvbmU6IGZhbHNlIH07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgdmFsdWU6IHVuZGVmaW5lZCBhcyBhbnksIGRvbmU6IHRydWUgfTtcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBhc3luYyBjbG9zZSgpIHt9LFxuICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgaXRlcmF0b3I6XG4gICAgICAgICAgICAgICAgICAgIGFycmF5SXRlcmF0b3IgYXMgdW5rbm93biBhcyBJdGVyYXRvcnMuU3RhdGVRdWVyeUl0ZXJhdG9yLFxuICAgICAgICAgICAgICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgICAgICAgICAgICAgZmV0Y2hlZFJlY29yZHNDb3VudDogcGFnZWQubGVuZ3RoLFxuICAgICAgICAgICAgICAgICAgICBib29rbWFyazpcbiAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZUJvb2ttYXJrIHx8XG4gICAgICAgICAgICAgICAgICAgICAgKGhhc01vcmVcbiAgICAgICAgICAgICAgICAgICAgICAgID8gRmFicmljQ29udHJhY3RBZGFwdGVyLmJ1aWxkU3ludGhldGljUHJpdmF0ZUJvb2ttYXJrKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bnRoZXRpY09mZnNldCArIHBhZ2VkLmxlbmd0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgICA6IFwiXCIpLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgICAgICAgICAgICBgVW5zdXBwb3J0ZWQgbWV0aG9kIG92ZXJyaWRlICR7U3RyaW5nKHByb3ApfWBcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBwdXRTdGF0ZShcbiAgICBpZDogc3RyaW5nLFxuICAgIG1vZGVsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICAgIGN0eDogRmFicmljQ29udHJhY3RDb250ZXh0XG4gICkge1xuICAgIGxldCBkYXRhOiBCdWZmZXI7XG5cbiAgICB0cnkge1xuICAgICAgZGF0YSA9IEJ1ZmZlci5mcm9tKFxuICAgICAgICBGYWJyaWNDb250cmFjdEFkYXB0ZXIuc2VyaWFsaXplci5zZXJpYWxpemUobW9kZWwgYXMgTW9kZWwsIGZhbHNlKVxuICAgICAgKTtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICB0aHJvdyBuZXcgU2VyaWFsaXphdGlvbkVycm9yKFxuICAgICAgICBgRmFpbGVkIHRvIHNlcmlhbGl6ZSByZWNvcmQgd2l0aCBpZCAke2lkfTogJHtlfWBcbiAgICAgICk7XG4gICAgfVxuICAgIGF3YWl0IGN0eC5zdHViLnB1dFN0YXRlKGlkLnRvU3RyaW5nKCksIGRhdGEpO1xuXG4gICAgcmV0dXJuIG1vZGVsO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIHJlYWRTdGF0ZShpZDogc3RyaW5nLCBjdHg6IEZhYnJpY0NvbnRyYWN0Q29udGV4dCkge1xuICAgIGxldCByZXN1bHQ6IGFueTtcblxuICAgIGNvbnN0IHsgbG9nIH0gPSB0aGlzLmxvZ0N0eChbY3R4XSwgdGhpcy5yZWFkU3RhdGUpO1xuICAgIGNvbnN0IHJlcyA9IChhd2FpdCBjdHguc3R1Yi5nZXRTdGF0ZShpZC50b1N0cmluZygpKSkudG9TdHJpbmcoKTtcbiAgICBpZiAoIXJlcykgdGhyb3cgbmV3IE5vdEZvdW5kRXJyb3IoYFJlY29yZCB3aXRoIGlkICR7aWR9IG5vdCBmb3VuZGApO1xuICAgIGxvZy5zaWxseShgc3RhdGUgcmV0cmlldmVkIHVuZGVyIGlkICR7aWR9YCk7XG4gICAgdHJ5IHtcbiAgICAgIHJlc3VsdCA9IEZhYnJpY0NvbnRyYWN0QWRhcHRlci5zZXJpYWxpemVyLmRlc2VyaWFsaXplKHJlcy50b1N0cmluZygpKTtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICB0aHJvdyBuZXcgU2VyaWFsaXphdGlvbkVycm9yKGBGYWlsZWQgdG8gcGFyc2UgcmVjb3JkOiAke2V9YCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBxdWVyeVJlc3VsdChcbiAgICBzdHViOiBDaGFpbmNvZGVTdHViLFxuICAgIHJhd0lucHV0OiBhbnksXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIC4uLmFyZ3M6IENvbnRleHR1YWxBcmdzPEZhYnJpY0NvbnRyYWN0Q29udGV4dD5cbiAgKTogUHJvbWlzZTxJdGVyYXRvcnMuU3RhdGVRdWVyeUl0ZXJhdG9yPiB7XG4gICAgcmV0dXJuIHN0dWIuZ2V0UXVlcnlSZXN1bHQoSlNPTi5zdHJpbmdpZnkocmF3SW5wdXQpKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBxdWVyeVJlc3VsdFBhZ2luYXRlZChcbiAgICBzdHViOiBDaGFpbmNvZGVTdHViLFxuICAgIHJhd0lucHV0OiBhbnksXG4gICAgbGltaXQ6IG51bWJlciA9IDI1MCxcbiAgICBwYWdlPzogbnVtYmVyLFxuICAgIGJvb2ttYXJrPzogc3RyaW5nIHwgbnVtYmVyLFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPFN0YXRlUXVlcnlSZXNwb25zZTxJdGVyYXRvcnMuU3RhdGVRdWVyeUl0ZXJhdG9yPj4ge1xuICAgIHJldHVybiBzdHViLmdldFF1ZXJ5UmVzdWx0V2l0aFBhZ2luYXRpb24oXG4gICAgICBKU09OLnN0cmluZ2lmeShyYXdJbnB1dCksXG4gICAgICBsaW1pdCxcbiAgICAgIGJvb2ttYXJrPy50b1N0cmluZygpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRGVjb2RlcyBiaW5hcnkgZGF0YSB0byBzdHJpbmdcbiAgICogQHN1bW1hcnkgQ29udmVydHMgYSBVaW50OEFycmF5IHRvIGEgc3RyaW5nIHVzaW5nIFVURi04IGVuY29kaW5nXG4gICAqIEBwYXJhbSB7VWludDhBcnJheX0gYnVmZmVyIC0gVGhlIGJpbmFyeSBkYXRhIHRvIGRlY29kZVxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBkZWNvZGVkIHN0cmluZ1xuICAgKi9cbiAgcHJvdGVjdGVkIGRlY29kZShidWZmZXI6IFVpbnQ4QXJyYXkpIHtcbiAgICByZXR1cm4gRmFicmljQ29udHJhY3RBZGFwdGVyLnRleHREZWNvZGVyLmRlY29kZShidWZmZXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIG9wZXJhdGlvbiBmbGFncyBmb3IgRmFicmljIGNvbnRyYWN0IG9wZXJhdGlvbnNcbiAgICogQHN1bW1hcnkgTWVyZ2VzIGRlZmF1bHQgZmxhZ3Mgd2l0aCBGYWJyaWMtc3BlY2lmaWMgY29udGV4dCBpbmZvcm1hdGlvblxuICAgKiBAdGVtcGxhdGUgTSAtIFR5cGUgZXh0ZW5kaW5nIE1vZGVsXG4gICAqIEBwYXJhbSB7T3BlcmF0aW9uS2V5c30gb3BlcmF0aW9uIC0gVGhlIG9wZXJhdGlvbiBiZWluZyBwZXJmb3JtZWRcbiAgICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxNPn0gbW9kZWwgLSBUaGUgbW9kZWwgY29uc3RydWN0b3JcbiAgICogQHBhcmFtIHtQYXJ0aWFsPEZhYnJpY0NvbnRyYWN0RmxhZ3M+fSBmbGFncyAtIFBhcnRpYWwgZmxhZ3MgdG8gbWVyZ2Ugd2l0aCBkZWZhdWx0c1xuICAgKiBAcGFyYW0ge0N0eH0gY3R4IC0gVGhlIEZhYnJpYyBjaGFpbmNvZGUgY29udGV4dFxuICAgKiBAcmV0dXJuIHtGYWJyaWNDb250cmFjdEZsYWdzfSBUaGUgbWVyZ2VkIGZsYWdzXG4gICAqL1xuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgYXN5bmMgZmxhZ3M8TSBleHRlbmRzIE1vZGVsPihcbiAgICBvcGVyYXRpb246IEFsbE9wZXJhdGlvbktleXMsXG4gICAgbW9kZWw6IENvbnN0cnVjdG9yPE0+IHwgdW5kZWZpbmVkLFxuICAgIGZsYWdzOiBQYXJ0aWFsPEZhYnJpY0NvbnRyYWN0RmxhZ3M+IHwgRmFicmljQ29udHJhY3RDb250ZXh0IHwgQ3R4IHwgYW55XG4gICk6IFByb21pc2U8RmFicmljQ29udHJhY3RGbGFncz4ge1xuICAgIGxldCBiYXNlRmxhZ3MgPSB7XG4gICAgICBzZWdyZWdhdGVkOiBmYWxzZSxcbiAgICAgIHJlYnVpbGRXaXRoVHJhbnNpZW50OiBmYWxzZSxcbiAgICAgIGZ1bGx5U2VncmVnYXRlZDogZmFsc2UsXG4gICAgfTtcbiAgICBpZiAoZmxhZ3MgaW5zdGFuY2VvZiBGYWJyaWNDb250cmFjdENvbnRleHQgfHwgZmxhZ3MgaW5zdGFuY2VvZiBDb250ZXh0KSB7XG4gICAgICBmbGFncyA9IGZsYWdzLnRvT3ZlcnJpZGVzKCk7XG4gICAgfVxuXG4gICAgYmFzZUZsYWdzID0gT2JqZWN0LmFzc2lnbihiYXNlRmxhZ3MsIGZsYWdzKTtcbiAgICBjb25zdCBzdHViRnJvbUZsYWdzID1cbiAgICAgIChmbGFncyBhcyBGYWJyaWNDb250cmFjdENvbnRleHQpLnN0dWIgfHwgKGZsYWdzIGFzIEN0eCkuc3R1YjtcbiAgICBjb25zdCBpZGVudGl0eUZyb21GbGFncyA9XG4gICAgICAoZmxhZ3MgYXMgRmFicmljQ29udHJhY3RDb250ZXh0KS5pZGVudGl0eSB8fFxuICAgICAgKGZsYWdzIGFzIEN0eCkuY2xpZW50SWRlbnRpdHk7XG4gICAgaWYgKHN0dWJGcm9tRmxhZ3MgJiYgaWRlbnRpdHlGcm9tRmxhZ3MpIHtcbiAgICAgIGNvbnN0IHR4SWQgPSBzdHViRnJvbUZsYWdzLmdldFR4SUQoKTtcbiAgICAgIE9iamVjdC5hc3NpZ24oYmFzZUZsYWdzLCB7XG4gICAgICAgIHN0dWI6IHN0dWJGcm9tRmxhZ3MsXG4gICAgICAgIGlkZW50aXR5OiBpZGVudGl0eUZyb21GbGFncyxcbiAgICAgICAgY2VydDogaWRlbnRpdHlGcm9tRmxhZ3MuZ2V0SURCeXRlcygpLnRvU3RyaW5nKCksXG4gICAgICAgIHJvbGVzOiBpZGVudGl0eUZyb21GbGFncy5nZXRBdHRyaWJ1dGVWYWx1ZShcInJvbGVzXCIpLFxuICAgICAgICBsb2dnZXI6IExvZ2dpbmcuZm9yKFxuICAgICAgICAgIG9wZXJhdGlvbixcbiAgICAgICAgICB7XG4gICAgICAgICAgICBsb2dMZXZlbDogZmFsc2UsXG4gICAgICAgICAgICB0aW1lc3RhbXA6IGZhbHNlLFxuICAgICAgICAgICAgY29ycmVsYXRpb25JZDogdHhJZCxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGZsYWdzXG4gICAgICAgICksXG4gICAgICAgIGNvcnJlbGF0aW9uSWQ6IHR4SWQsXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgYmFzZUZsYWdzID0gT2JqZWN0LmFzc2lnbihiYXNlRmxhZ3MsIGZsYWdzIHx8IHt9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gKGF3YWl0IHN1cGVyLmZsYWdzKFxuICAgICAgb3BlcmF0aW9uLFxuICAgICAgbW9kZWwsXG4gICAgICBiYXNlRmxhZ3MgYXMgYW55XG4gICAgKSkgYXMgRmFicmljQ29udHJhY3RGbGFncztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhbiBpbmRleCBmb3IgYSBtb2RlbFxuICAgKiBAc3VtbWFyeSBUaGlzIG1ldGhvZCBpcyBub3QgaW1wbGVtZW50ZWQgZm9yIEZhYnJpYyBjb250cmFjdHMgYW5kIHJldHVybnMgYSByZXNvbHZlZCBwcm9taXNlXG4gICAqIEB0ZW1wbGF0ZSBNIC0gVHlwZSBleHRlbmRpbmcgTW9kZWxcbiAgICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxNPn0gbW9kZWxzIC0gVGhlIG1vZGVsIGNvbnN0cnVjdG9yXG4gICAqIEByZXR1cm4ge1Byb21pc2U8dm9pZD59IFByb21pc2UgdGhhdCByZXNvbHZlcyBpbW1lZGlhdGVseVxuICAgKi9cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBwcm90ZWN0ZWQgaW5kZXg8TT4obW9kZWxzOiBDb25zdHJ1Y3RvcjxNPik6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodW5kZWZpbmVkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUHJvY2Vzc2VzIHJlc3VsdHMgZnJvbSBhIHN0YXRlIHF1ZXJ5IGl0ZXJhdG9yXG4gICAqIEBzdW1tYXJ5IEl0ZXJhdGVzIHRocm91Z2ggcXVlcnkgcmVzdWx0cyBhbmQgY29udmVydHMgdGhlbSB0byBhIHN0cnVjdHVyZWQgZm9ybWF0XG4gICAqIEBwYXJhbSB7TG9nZ2VyfSBsb2cgLSBMb2dnZXIgaW5zdGFuY2UgZm9yIGRlYnVnZ2luZ1xuICAgKiBAcGFyYW0ge0l0ZXJhdG9ycy5TdGF0ZVF1ZXJ5SXRlcmF0b3J9IGl0ZXJhdG9yIC0gVGhlIHN0YXRlIHF1ZXJ5IGl0ZXJhdG9yXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2lzSGlzdG9yeT1mYWxzZV0gLSBXaGV0aGVyIHRoaXMgaXMgYSBoaXN0b3J5IHF1ZXJ5XG4gICAqIEByZXR1cm4ge1Byb21pc2U8YW55W10+fSBQcm9taXNlIHJlc29sdmluZyB0byBhbiBhcnJheSBvZiBwcm9jZXNzZWQgcmVzdWx0c1xuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDYWxsZXJcbiAgICogICBwYXJ0aWNpcGFudCBSZXN1bHRJdGVyYXRvclxuICAgKiAgIHBhcnRpY2lwYW50IEl0ZXJhdG9yXG4gICAqXG4gICAqICAgQ2FsbGVyLT4+UmVzdWx0SXRlcmF0b3I6IHJlc3VsdEl0ZXJhdG9yKGxvZywgaXRlcmF0b3IsIGlzSGlzdG9yeSlcbiAgICogICBsb29wIFVudGlsIGRvbmVcbiAgICogICAgIFJlc3VsdEl0ZXJhdG9yLT4+SXRlcmF0b3I6IG5leHQoKVxuICAgKiAgICAgSXRlcmF0b3ItLT4+UmVzdWx0SXRlcmF0b3I6IHsgdmFsdWUsIGRvbmUgfVxuICAgKiAgICAgYWx0IEhhcyB2YWx1ZVxuICAgKiAgICAgICBSZXN1bHRJdGVyYXRvci0+PlJlc3VsdEl0ZXJhdG9yOiBQcm9jZXNzIHZhbHVlIGJhc2VkIG9uIGlzSGlzdG9yeVxuICAgKiAgICAgICBSZXN1bHRJdGVyYXRvci0+PlJlc3VsdEl0ZXJhdG9yOiBBZGQgdG8gcmVzdWx0cyBhcnJheVxuICAgKiAgICAgZW5kXG4gICAqICAgZW5kXG4gICAqICAgUmVzdWx0SXRlcmF0b3ItPj5JdGVyYXRvcjogY2xvc2UoKVxuICAgKiAgIFJlc3VsdEl0ZXJhdG9yLS0+PkNhbGxlcjogYWxsUmVzdWx0c1xuICAgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIHJlc3VsdEl0ZXJhdG9yKFxuICAgIGxvZzogTG9nZ2VyLFxuICAgIGl0ZXJhdG9yOiBJdGVyYXRvcnMuU3RhdGVRdWVyeUl0ZXJhdG9yLFxuICAgIGlzSGlzdG9yeSA9IGZhbHNlXG4gICkge1xuICAgIGNvbnN0IGFsbFJlc3VsdHMgPSBbXTtcbiAgICBsZXQgcmVzOiB7IHZhbHVlOiBhbnk7IGRvbmU6IGJvb2xlYW4gfSA9IGF3YWl0IGl0ZXJhdG9yLm5leHQoKTtcbiAgICB3aGlsZSAoIXJlcy5kb25lKSB7XG4gICAgICBpZiAocmVzLnZhbHVlICYmIHJlcy52YWx1ZS52YWx1ZS50b1N0cmluZygpKSB7XG4gICAgICAgIGxldCBqc29uUmVzOiBhbnkgPSB7fTtcbiAgICAgICAgbG9nLmRlYnVnKHJlcy52YWx1ZS52YWx1ZS50b1N0cmluZyhcInV0ZjhcIikpO1xuICAgICAgICBpZiAoaXNIaXN0b3J5IC8qICYmIGlzSGlzdG9yeSA9PT0gdHJ1ZSovKSB7XG4gICAgICAgICAganNvblJlcy5UeElkID0gcmVzLnZhbHVlLnR4SWQ7XG4gICAgICAgICAganNvblJlcy5UaW1lc3RhbXAgPSByZXMudmFsdWUudGltZXN0YW1wO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBqc29uUmVzLlZhbHVlID0gSlNPTi5wYXJzZShyZXMudmFsdWUudmFsdWUudG9TdHJpbmcoXCJ1dGY4XCIpKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgICAgICAgICAgbG9nLmVycm9yKGVycik7XG4gICAgICAgICAgICBqc29uUmVzLlZhbHVlID0gcmVzLnZhbHVlLnZhbHVlLnRvU3RyaW5nKFwidXRmOFwiKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGpzb25SZXMgPSBKU09OLnBhcnNlKHJlcy52YWx1ZS52YWx1ZS50b1N0cmluZyhcInV0ZjhcIikpO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycjogYW55KSB7XG4gICAgICAgICAgICBsb2cuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgIGpzb25SZXMgPSByZXMudmFsdWUudmFsdWUudG9TdHJpbmcoXCJ1dGY4XCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBhbGxSZXN1bHRzLnB1c2goanNvblJlcyk7XG4gICAgICB9XG4gICAgICByZXMgPSBhd2FpdCBpdGVyYXRvci5uZXh0KCk7XG4gICAgfVxuICAgIGxvZy5kZWJ1ZyhgQ2xvc2luZyBpdGVyYXRvciBhZnRlciAke2FsbFJlc3VsdHMubGVuZ3RofSByZXN1bHRzYCk7XG4gICAgYXdhaXQgaXRlcmF0b3IuY2xvc2UoKTtcbiAgICByZXR1cm4gYWxsUmVzdWx0cztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRXhlY3V0ZXMgYSByYXcgcXVlcnkgYWdhaW5zdCB0aGUgc3RhdGUgZGF0YWJhc2VcbiAgICogQHN1bW1hcnkgUGVyZm9ybXMgYSByaWNoIHF1ZXJ5IHVzaW5nIENvdWNoREIgc3ludGF4IGFnYWluc3QgdGhlIEZhYnJpYyBzdGF0ZSBkYXRhYmFzZVxuICAgKiBAdGVtcGxhdGUgUiAtIFRoZSByZXR1cm4gdHlwZVxuICAgKiBAcGFyYW0ge01hbmdvUXVlcnl9IHJhd0lucHV0IC0gVGhlIE1hbmdvIFF1ZXJ5IHRvIGV4ZWN1dGVcbiAgICogQHBhcmFtIHtib29sZWFufSBkb2NzT25seSAtIFdoZXRoZXIgdG8gcmV0dXJuIG9ubHkgZG9jdW1lbnRzIChub3QgdXNlZCBpbiB0aGlzIGltcGxlbWVudGF0aW9uKVxuICAgKiBAcGFyYW0gey4uLmFueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHMsIGluY2x1ZGluZyB0aGUgY2hhaW5jb2RlIHN0dWIgYW5kIGxvZ2dlclxuICAgKiBAcmV0dXJuIHtQcm9taXNlPFI+fSBQcm9taXNlIHJlc29sdmluZyB0byB0aGUgcXVlcnkgcmVzdWx0c1xuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDYWxsZXJcbiAgICogICBwYXJ0aWNpcGFudCBGYWJyaWNDb250cmFjdEFkYXB0ZXJcbiAgICogICBwYXJ0aWNpcGFudCBTdHViXG4gICAqICAgcGFydGljaXBhbnQgU3RhdGVEQlxuICAgKlxuICAgKiAgIENhbGxlci0+PkZhYnJpY0NvbnRyYWN0QWRhcHRlcjogcmF3KHJhd0lucHV0LCBkb2NzT25seSwgY3R4KVxuICAgKiAgIEZhYnJpY0NvbnRyYWN0QWRhcHRlci0+PkZhYnJpY0NvbnRyYWN0QWRhcHRlcjogRXh0cmFjdCBsaW1pdCBhbmQgc2tpcFxuICAgKiAgIGFsdCBXaXRoIHBhZ2luYXRpb25cbiAgICogICAgIEZhYnJpY0NvbnRyYWN0QWRhcHRlci0+PlN0dWI6IGdldFF1ZXJ5UmVzdWx0V2l0aFBhZ2luYXRpb24ocXVlcnksIGxpbWl0LCBza2lwKVxuICAgKiAgIGVsc2UgV2l0aG91dCBwYWdpbmF0aW9uXG4gICAqICAgICBGYWJyaWNDb250cmFjdEFkYXB0ZXItPj5TdHViOiBnZXRRdWVyeVJlc3VsdChxdWVyeSlcbiAgICogICBlbmRcbiAgICogICBTdHViLT4+U3RhdGVEQjogRXhlY3V0ZSBxdWVyeVxuICAgKiAgIFN0YXRlREItLT4+U3R1YjogSXRlcmF0b3JcbiAgICogICBTdHViLS0+PkZhYnJpY0NvbnRyYWN0QWRhcHRlcjogSXRlcmF0b3JcbiAgICogICBGYWJyaWNDb250cmFjdEFkYXB0ZXItPj5GYWJyaWNDb250cmFjdEFkYXB0ZXI6IHJlc3VsdEl0ZXJhdG9yKGxvZywgaXRlcmF0b3IpXG4gICAqICAgRmFicmljQ29udHJhY3RBZGFwdGVyLS0+PkNhbGxlcjogcmVzdWx0c1xuICAgKi9cbiAgYXN5bmMgcmF3PFIsIEQgZXh0ZW5kcyBib29sZWFuPihcbiAgICByYXdJbnB1dDogTWFuZ29RdWVyeSxcbiAgICBkb2NzT25seTogRCA9IHRydWUgYXMgRCxcbiAgICAuLi5hcmdzOiBDb250ZXh0dWFsQXJnczxGYWJyaWNDb250cmFjdENvbnRleHQ+XG4gICk6IFByb21pc2U8UmF3UmVzdWx0PFIsIEQ+PiB7XG4gICAgY29uc3QgeyBsb2csIGN0eCwgY3R4QXJncyB9ID0gdGhpcy5sb2dDdHgoYXJncywgdGhpcy5yYXcpO1xuXG4gICAgY29uc3QgZW5hYmxlU2VncmVnYXRlcyA9ICFhcmdzLmxlbmd0aCB8fCBhcmdzWzBdICE9PSB0cnVlO1xuICAgIGNvbnN0IGZ1bGx5U2VncmVnYXRlZCA9IGVuYWJsZVNlZ3JlZ2F0ZXMgJiYgY3R4LmlzRnVsbHlTZWdyZWdhdGVkO1xuXG4gICAgY29uc3QgeyBza2lwLCBsaW1pdCB9ID0gcmF3SW5wdXQ7XG4gICAgY29uc3QgYm9va21hcmsgPSByYXdJbnB1dFtcImJvb2ttYXJrXCJdO1xuICAgIGNvbnN0IHBhZ2luYXRpb25BY3RpdmUgPSBCb29sZWFuKGxpbWl0IHx8IHNraXAgfHwgYm9va21hcmspO1xuICAgIGxldCByZXNwID0geyBkb2NzOiBbXSwgYm9va21hcms6IHVuZGVmaW5lZCBhcyBzdHJpbmcgfCB1bmRlZmluZWQgfTtcblxuICAgIC8vIFF1ZXJ5IHB1YmxpYyBzdGF0ZSBvbmx5IHdoZW4gdGhlIG1vZGVsIGlzIE5PVCBmdWxseSBzZWdyZWdhdGVkXG4gICAgaWYgKCFmdWxseVNlZ3JlZ2F0ZWQpIHtcbiAgICAgIGxldCBpdGVyYXRvcjogSXRlcmF0b3JzLlN0YXRlUXVlcnlJdGVyYXRvcjtcbiAgICAgIGlmIChsaW1pdCB8fCBza2lwKSB7XG4gICAgICAgIGRlbGV0ZSByYXdJbnB1dFtcImxpbWl0XCJdO1xuICAgICAgICBkZWxldGUgcmF3SW5wdXRbXCJza2lwXCJdO1xuICAgICAgICBsb2cuZGVidWcoXG4gICAgICAgICAgYFJldHJpZXZpbmcgcHVibGljIHBhZ2luYXRlZCBpdGVyYXRvcjogbGltaXQ6ICR7bGltaXR9LyBza2lwOiAke3NraXB9YFxuICAgICAgICApO1xuICAgICAgICBjb25zdCByZXNwb25zZTogU3RhdGVRdWVyeVJlc3BvbnNlPEl0ZXJhdG9ycy5TdGF0ZVF1ZXJ5SXRlcmF0b3I+ID1cbiAgICAgICAgICAoYXdhaXQgdGhpcy5xdWVyeVJlc3VsdFBhZ2luYXRlZChcbiAgICAgICAgICAgIGN0eC5zdHViLFxuICAgICAgICAgICAgcmF3SW5wdXQsXG4gICAgICAgICAgICBsaW1pdCB8fCBOdW1iZXIuTUFYX1ZBTFVFLFxuICAgICAgICAgICAgKHNraXAgYXMgYW55KT8udG9TdHJpbmcoKSxcbiAgICAgICAgICAgIGJvb2ttYXJrLFxuICAgICAgICAgICAgLi4uW2N0eCBhcyBGYWJyaWNDb250cmFjdENvbnRleHRdXG4gICAgICAgICAgKSkgYXMgU3RhdGVRdWVyeVJlc3BvbnNlPEl0ZXJhdG9ycy5TdGF0ZVF1ZXJ5SXRlcmF0b3I+O1xuICAgICAgICByZXNwLmJvb2ttYXJrID0gcmVzcG9uc2UubWV0YWRhdGEuYm9va21hcms7XG4gICAgICAgIGl0ZXJhdG9yID0gcmVzcG9uc2UuaXRlcmF0b3I7XG4gICAgICAgIGxvZy5kZWJ1ZyhgUmV0cmlldmVkIHB1YmxpYyBwYWdpbmcgaXRlcmF0b3JgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxvZy5kZWJ1ZyhcIlJldHJpZXZpbmcgbGlzdGluZyBwdWJsaWMgaXRlcmF0b3JcIik7XG4gICAgICAgIGl0ZXJhdG9yID0gKGF3YWl0IHRoaXMucXVlcnlSZXN1bHQoXG4gICAgICAgICAgY3R4LnN0dWIsXG4gICAgICAgICAgcmF3SW5wdXQsXG4gICAgICAgICAgY3R4XG4gICAgICAgICkpIGFzIEl0ZXJhdG9ycy5TdGF0ZVF1ZXJ5SXRlcmF0b3I7XG4gICAgICB9XG4gICAgICBsb2cuZGVidWcoYFJldHJpZXZlZCBwdWJsaWMgbGlzdGluZyBpdGVyYXRvcmApO1xuXG4gICAgICByZXNwLmRvY3MgPSAoYXdhaXQgdGhpcy5yZXN1bHRJdGVyYXRvcihsb2csIGl0ZXJhdG9yKSkgYXMgYW55O1xuICAgICAgbG9nLmRlYnVnKFxuICAgICAgICBgcmV0dXJuaW5nICR7QXJyYXkuaXNBcnJheShyZXNwLmRvY3MpID8gcmVzcC5kb2NzLmxlbmd0aCA6IDF9IHJlc3VsdHNgXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBGb3IgZnVsbHkgc2VncmVnYXRlZCBtb2RlbHMsIHN0cmlwIHBhZ2luYXRpb24gZmllbGRzIGZyb20gcmF3SW5wdXRcbiAgICAgIC8vIHNvIHRoZSBzZWdyZWdhdGVkIHF1ZXJ5IGJlbG93IGNhbiByZS1hcHBseSB0aGVtIGNsZWFubHlcbiAgICAgIGlmIChsaW1pdCB8fCBza2lwKSB7XG4gICAgICAgIGRlbGV0ZSByYXdJbnB1dFtcImxpbWl0XCJdO1xuICAgICAgICBkZWxldGUgcmF3SW5wdXRbXCJza2lwXCJdO1xuICAgICAgfVxuICAgICAgbG9nLmRlYnVnKFwiU2tpcHBpbmcgcHVibGljIHN0YXRlIHF1ZXJ5IChmdWxseSBzZWdyZWdhdGVkIG1vZGVsKVwiKTtcbiAgICB9XG5cbiAgICBjb25zdCBjb2xsZWN0aW9ucyA9IGVuYWJsZVNlZ3JlZ2F0ZXMgPyBjdHguZ2V0UmVhZENvbGxlY3Rpb25zKCkgOiB1bmRlZmluZWQ7XG5cbiAgICBpZiAoY29sbGVjdGlvbnMgJiYgY29sbGVjdGlvbnMubGVuZ3RoKSB7XG4gICAgICAvLyBCdWlsZCBhIGZyZXNoIGlucHV0IHdpdGggbGltaXQvc2tpcC9ib29rbWFyayByZXN0b3JlZFxuICAgICAgY29uc3Qgc2VncmVnYXRlZElucHV0ID0geyAuLi5yYXdJbnB1dCB9O1xuICAgICAgaWYgKGxpbWl0KSBzZWdyZWdhdGVkSW5wdXQubGltaXQgPSBsaW1pdDtcbiAgICAgIGlmIChza2lwKSBzZWdyZWdhdGVkSW5wdXQuc2tpcCA9IHNraXA7XG4gICAgICBpZiAoYm9va21hcmspIHNlZ3JlZ2F0ZWRJbnB1dFtcImJvb2ttYXJrXCJdID0gYm9va21hcms7XG5cbiAgICAgIGNvbnN0IHNlZ3JlZ2F0ZWQ6IGFueVtdID0gW107XG4gICAgICBmb3IgKGNvbnN0IGNvbGxlY3Rpb24gb2YgY29sbGVjdGlvbnMpIHtcbiAgICAgICAgbG9nLmRlYnVnKGBRdWVyeWluZyBmcm9tICR7Y29sbGVjdGlvbn1gKTtcbiAgICAgICAgY29uc3QgZnJvbUNvbHMgPSBhd2FpdCB0aGlzLmZvclByaXZhdGUoY29sbGVjdGlvbikucmF3KFxuICAgICAgICAgIHsgLi4uc2VncmVnYXRlZElucHV0IH0sXG4gICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICAuLi5jdHhBcmdzXG4gICAgICAgICk7XG4gICAgICAgIGxvZy52ZXJib3NlKFxuICAgICAgICAgIGByZWNlaXZlZCAkeyhmcm9tQ29scyBhcyB1bmtub3duIGFzIGFueVtdKS5sZW5ndGh9IGZyb20gJHtjb2xsZWN0aW9ufWBcbiAgICAgICAgKTtcbiAgICAgICAgc2VncmVnYXRlZC5wdXNoKGZyb21Db2xzKTtcbiAgICAgIH1cbiAgICAgIGlmIChwYWdpbmF0aW9uQWN0aXZlKSB7XG4gICAgICAgIC8vIEZvciBwYWdpbmF0ZWQgZmxvd3MsIGtlZXAgc291cmNlIHNlbGVjdGlvbiBkZXRlcm1pbmlzdGljIHNvXG4gICAgICAgIC8vIGV4dGVybmFsbHkgZ2VuZXJhdGVkIG9wYXF1ZSBib29rbWFya3Mgc3RheSB2YWxpZCBhY3Jvc3MgcGFnZXMuXG4gICAgICAgIGlmIChmdWxseVNlZ3JlZ2F0ZWQpIHtcbiAgICAgICAgICByZXNwID0gKHNlZ3JlZ2F0ZWRbMF0gYXMgYW55KSB8fCByZXNwO1xuICAgICAgICB9IGVsc2UgaWYgKCFyZXNwLmRvY3M/Lmxlbmd0aCAmJiBzZWdyZWdhdGVkLmxlbmd0aCkge1xuICAgICAgICAgIC8vIFByZXNlcnZlIHB1YmxpYy1zdGF0ZSBwcmlvcml0eSBmb3IgbWl4ZWQgbW9kZWxzLCBidXQgYWxsb3cgYVxuICAgICAgICAgIC8vIHN0YWJsZSBmYWxsYmFjayB3aGVuIHB1YmxpYyBxdWVyeSByZXR1cm5zIG5vIGRvY3MuXG4gICAgICAgICAgcmVzcCA9IHNlZ3JlZ2F0ZWRbMF0gYXMgYW55O1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBOb24tcGFnaW5hdGVkIHJlYWRzIGNhbiBzdGlsbCBwcmVmZXIgdGhlIHJpY2hlc3QgcmVzcG9uc2UuXG4gICAgICAgIHJlc3AgPSBzZWdyZWdhdGVkLnJlZHVjZSgoYWNjLCBjdXJyKSA9PiB7XG4gICAgICAgICAgaWYgKCFhY2MpIHJldHVybiBjdXJyO1xuICAgICAgICAgIGlmIChjdXJyLmRvY3MgJiYgY3Vyci5kb2NzLmxlbmd0aCA+PSBhY2M/LmRvY3MubGVuZ3RoKSByZXR1cm4gY3VycjtcbiAgICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgICB9LCByZXNwKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZG9jc09ubHkpIHtcbiAgICAgIHJldHVybiByZXNwLmRvY3MgYXMgYW55O1xuICAgIH1cbiAgICByZXR1cm4gcmVzcCBhcyBhbnk7XG4gIH1cblxuICBhc3luYyB2aWV3PFI+KFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICBkZG9jOiBzdHJpbmcsXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIHZpZXdOYW1lOiBzdHJpbmcsXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIG9wdGlvbnM6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIC4uLl9hcmdzOiBDb250ZXh0dWFsQXJnczxGYWJyaWNDb250cmFjdENvbnRleHQ+XG4gICk6IFByb21pc2U8Vmlld1Jlc3BvbnNlPFI+PiB7XG4gICAgdGhyb3cgbmV3IFVuc3VwcG9ydGVkRXJyb3IoXG4gICAgICBcIkZhYnJpYyBjb250cmFjdHMgZG8gbm90IHN1cHBvcnQgQ291Y2hEQiB2aWV3cy5cIlxuICAgICk7XG4gIH1cblxuICBvdmVycmlkZSBTdGF0ZW1lbnQ8TSBleHRlbmRzIE1vZGVsPihcbiAgICBvdmVycmlkZXM/OiBQYXJ0aWFsPEFkYXB0ZXJGbGFncz5cbiAgKTogRmFicmljU3RhdGVtZW50PE0sIGFueT4ge1xuICAgIHJldHVybiBuZXcgRmFicmljU3RhdGVtZW50KHRoaXMgYXMgYW55LCBvdmVycmlkZXMpO1xuICB9XG5cbiAgb3ZlcnJpZGUgYXN5bmMgdXBkYXRlQWxsPE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgdGFibGVOYW1lOiBDb25zdHJ1Y3RvcjxNPixcbiAgICBpZDogUHJpbWFyeUtleVR5cGVbXSxcbiAgICBtb2RlbDogUmVjb3JkPHN0cmluZywgYW55PltdLFxuICAgIC4uLmFyZ3M6IENvbnRleHR1YWxBcmdzPEZhYnJpY0NvbnRyYWN0Q29udGV4dD5cbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+W10+IHtcbiAgICBpZiAoaWQubGVuZ3RoICE9PSBtb2RlbC5sZW5ndGgpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIklkcyBhbmQgbW9kZWxzIG11c3QgaGF2ZSB0aGUgc2FtZSBsZW5ndGhcIik7XG4gICAgY29uc3QgeyBsb2csIGN0eEFyZ3MgfSA9IHRoaXMubG9nQ3R4KGFyZ3MsIHRoaXMudXBkYXRlQWxsKTtcbiAgICBjb25zdCB0YWJsZUxhYmVsID0gTW9kZWwudGFibGVOYW1lKHRhYmxlTmFtZSk7XG4gICAgbG9nLmRlYnVnKGBVcGRhdGluZyAke2lkLmxlbmd0aH0gZW50cmllcyAke3RhYmxlTGFiZWx9IHRhYmxlYCk7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKFxuICAgICAgaWQubWFwKChpLCBjb3VudCkgPT4gdGhpcy51cGRhdGUodGFibGVOYW1lLCBpLCBtb2RlbFtjb3VudF0sIC4uLmN0eEFyZ3MpKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICpcbiAgICogQHBhcmFtIG1vZGVsXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwa1xuICAgKiBAcGFyYW0gYXJnc1xuICAgKi9cbiAgb3ZlcnJpZGUgcHJlcGFyZTxNIGV4dGVuZHMgTW9kZWw+KFxuICAgIG1vZGVsOiBNLFxuICAgIC4uLmFyZ3M6IENvbnRleHR1YWxBcmdzPEZhYnJpY0NvbnRyYWN0Q29udGV4dD5cbiAgKTogUHJlcGFyZWRNb2RlbCAmIHtcbiAgICBzZWdyZWdhdGVkPzogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgYW55Pj47XG4gIH0ge1xuICAgIGNvbnN0IHsgbG9nLCBjdHggfSA9IHRoaXMubG9nQ3R4KGFyZ3MsIHRoaXMucHJlcGFyZSk7XG4gICAgY29uc3Qgc3BsaXQ6IFNlZ3JlZ2F0ZWRNb2RlbDxNPiA9IE1vZGVsLnNlZ3JlZ2F0ZShtb2RlbCk7XG4gICAgY29uc3QgdGFibGVOYW1lID0gTW9kZWwudGFibGVOYW1lKG1vZGVsLmNvbnN0cnVjdG9yIGFzIGFueSk7XG4gICAgY29uc3QgcGsgPSBNb2RlbC5wayhtb2RlbC5jb25zdHJ1Y3RvciBhcyBhbnkpO1xuICAgIGNvbnN0IGlkID0gbW9kZWxbcGsgYXMga2V5b2YgTV07XG5cbiAgICBjb25zdCBpc01pcnJvciA9IGN0eC5nZXRPclVuZGVmaW5lZChcIm1pcnJvclwiKSBhcyBib29sZWFuIHwgdW5kZWZpbmVkO1xuXG4gICAgY29uc3QgbWFwVG9SZWNvcmQgPSBmdW5jdGlvbiAoXG4gICAgICB0aGlzOiBGYWJyaWNDb250cmFjdEFkYXB0ZXIsXG4gICAgICBvYmo6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgICBrZXlzT3ZlcnJpZGU/OiBzdHJpbmdbXVxuICAgICkge1xuICAgICAgaWYgKGtleXNPdmVycmlkZSlcbiAgICAgICAga2V5c092ZXJyaWRlID0gWy4uLm5ldyBTZXQoWy4uLmtleXNPdmVycmlkZSwgcGsgYXMgc3RyaW5nXSldO1xuICAgICAgY29uc3QgcmVzdWx0ID0gT2JqZWN0LmVudHJpZXMob2JqKS5yZWR1Y2UoXG4gICAgICAgIChhY2N1bTogUmVjb3JkPHN0cmluZywgYW55PiwgW2tleSwgdmFsXSkgPT4ge1xuICAgICAgICAgIGlmICh0eXBlb2YgdmFsID09PSBcInVuZGVmaW5lZFwiKSByZXR1cm4gYWNjdW07XG4gICAgICAgICAgaWYgKGtleXNPdmVycmlkZSAmJiAha2V5c092ZXJyaWRlLmluY2x1ZGVzKGtleSkpIHJldHVybiBhY2N1bTtcbiAgICAgICAgICBjb25zdCBtYXBwZWRQcm9wID0gTW9kZWwuY29sdW1uTmFtZShtb2RlbCwga2V5IGFzIGFueSk7XG4gICAgICAgICAgaWYgKHRoaXMuaXNSZXNlcnZlZChtYXBwZWRQcm9wKSlcbiAgICAgICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKGBQcm9wZXJ0eSBuYW1lICR7bWFwcGVkUHJvcH0gaXMgcmVzZXJ2ZWRgKTtcbiAgICAgICAgICB2YWwgPSB2YWwgaW5zdGFuY2VvZiBEYXRlID8gbmV3IERhdGUodmFsKSA6IHZhbDtcbiAgICAgICAgICBhY2N1bVttYXBwZWRQcm9wXSA9IHZhbDtcbiAgICAgICAgICByZXR1cm4gYWNjdW07XG4gICAgICAgIH0sXG4gICAgICAgIHt9XG4gICAgICApO1xuICAgICAgaWYgKE9iamVjdC5rZXlzKHJlc3VsdCkuZmlsdGVyKChrKSA9PiBCb29sZWFuKHJlc3VsdFtrXSkpLmxlbmd0aCkge1xuICAgICAgICAvLyBBZGQgdGFibGUgaWRlbnRpZmllclxuICAgICAgICByZXN1bHRbQ291Y2hEQktleXMuVEFCTEVdID0gdGFibGVOYW1lO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9LmJpbmQodGhpcyk7XG5cbiAgICBsb2cuc2lsbHkoXG4gICAgICBgUHJlcGFyaW5nIHJlY29yZCBmb3IgJHt0YWJsZU5hbWV9IHRhYmxlIHdpdGggcGsgJHsobW9kZWwgYXMgYW55KVtwa119YFxuICAgICk7XG5cbiAgICBjb25zdCBzZWdyZWdhdGVkV3JpdGVLZXlzID0gY3R4LmdldFNlZ3JlZ2F0ZWRXcml0ZXMoKTtcbiAgICBjb25zdCBzZWdyZWdhdGVkV3JpdGVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG4gICAgLy8gT25seSBhcHBseSBzZWdyZWdhdGVkIHdyaXRlcyB3aGVuIHRoZSBjdXJyZW50IG1vZGVsIGFjdHVhbGx5IGhhcyBhIHRyYW5zaWVudCBzcGxpdC5cbiAgICAvLyBUaGUgc2FtZSBGYWJyaWNDb250cmFjdENvbnRleHQgY2FuIGJlIHJldXNlZCBhY3Jvc3MgbmVzdGVkIG9wZXJhdGlvbnMgKGZvciBleGFtcGxlXG4gICAgLy8gc2VxdWVuY2UgdXBzZXJ0cyBkdXJpbmcgcGVyc2lzdGVudCB2ZXJzaW9uIGdlbmVyYXRpb24pLiBJbiB0aG9zZSBjYXNlcywgd2UgbXVzdCBub3RcbiAgICAvLyBhdHRlbXB0IHRvIGFwcGx5IHBhcmVudC1tb2RlbCBzZWdyZWdhdGVkIHdyaXRlIGtleXMgdG8gdW5yZWxhdGVkIG1vZGVscy5cbiAgICBpZiAoc2VncmVnYXRlZFdyaXRlS2V5cyAmJiBzcGxpdC50cmFuc2llbnQgJiYgdHlwZW9mIHNwbGl0LnRyYW5zaWVudCA9PT0gXCJvYmplY3RcIikge1xuICAgICAgZm9yIChjb25zdCBjb2xsZWN0aW9uIGluIHNlZ3JlZ2F0ZWRXcml0ZUtleXMpIHtcbiAgICAgICAgc2VncmVnYXRlZFdyaXRlc1tjb2xsZWN0aW9uXSA9IHNlZ3JlZ2F0ZWRXcml0ZXNbY29sbGVjdGlvbl0gfHwge307XG4gICAgICAgIHNlZ3JlZ2F0ZWRXcml0ZXNbY29sbGVjdGlvbl1baWQgYXMgYW55XSA9IG1hcFRvUmVjb3JkKFxuICAgICAgICAgIGN0eC5nZXRPclVuZGVmaW5lZChcImZvcmNlU2VncmVnYXRlV3JpdGVcIilcbiAgICAgICAgICAgID8gc3BsaXQubW9kZWxcbiAgICAgICAgICAgIDogKChzcGxpdC50cmFuc2llbnQgYXMgYW55KSB8fCB7fSksXG4gICAgICAgICAgc2VncmVnYXRlZFdyaXRlS2V5c1tjb2xsZWN0aW9uXVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEluIG1pcnJvciBtb2RlLCB0aGUgcmVjb3JkIHNob3VsZCBjb250YWluIEFMTCBtb2RlbCBwcm9wZXJ0aWVzIChmdWxsIGNvcHkpXG4gICAgY29uc3QgcmVjb3JkID0gaXNNaXJyb3IgPyBtYXBUb1JlY29yZChtb2RlbCkgOiBtYXBUb1JlY29yZChzcGxpdC5tb2RlbCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgcmVjb3JkLFxuICAgICAgaWQ6IChtb2RlbCBhcyBhbnkpW3BrXSBhcyBzdHJpbmcsXG4gICAgICB0cmFuc2llbnQ6XG4gICAgICAgICFpc01pcnJvciAmJiBzcGxpdC50cmFuc2llbnQgJiYgT2JqZWN0LmtleXMoc3BsaXQudHJhbnNpZW50KS5sZW5ndGhcbiAgICAgICAgICA/IG1hcFRvUmVjb3JkKHNwbGl0LnRyYW5zaWVudClcbiAgICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgIHNlZ3JlZ2F0ZWQ6IGlzTWlycm9yID8gdW5kZWZpbmVkIDogc2VncmVnYXRlZFdyaXRlcyxcbiAgICB9O1xuICB9XG5cbiAgb3ZlcnJpZGUgcmV2ZXJ0PE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgb2JqOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICAgIGNsYXp6OiBDb25zdHJ1Y3RvcjxNPixcbiAgICBpZDogUHJpbWFyeUtleVR5cGUsXG4gICAgdHJhbnNpZW50PzogUmVjb3JkPHN0cmluZywgYW55PixcbiAgICAuLi5hcmdzOiBDb250ZXh0dWFsQXJnczxGYWJyaWNDb250cmFjdENvbnRleHQ+XG4gICk6IE0ge1xuICAgIGNvbnN0IHsgbG9nLCBjdHggfSA9IHRoaXMubG9nQ3R4KGFyZ3MsIHRoaXMucmV2ZXJ0KTtcbiAgICBjb25zdCBvYjogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xuICAgIGNvbnN0IHBrID0gTW9kZWwucGsoY2xhenopO1xuICAgIGNvbnN0IHBrUHJvcHMgPSBNb2RlbC5wa1Byb3BzKGNsYXp6KTtcbiAgICBpZiAocGtQcm9wcz8udHlwZSA9PT0gTnVtYmVyICYmIHR5cGVvZiBpZCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgaWQgPSBOdW1iZXIoaWQpO1xuICAgIH1cbiAgICBvYltwayBhcyBzdHJpbmddID0gaWQ7XG4gICAgbG9nLnNpbGx5KGBSZWJ1aWxkaW5nIG1vZGVsICR7Y2xhenoubmFtZX0gaWQgJHtpZH1gKTtcblxuICAgIGZ1bmN0aW9uIG1hcFRvTW9kZWwocjogUmVjb3JkPGFueSwgYW55Pikge1xuICAgICAgY29uc3QgbSA9IChcbiAgICAgICAgdHlwZW9mIGNsYXp6ID09PSBcInN0cmluZ1wiID8gTW9kZWwuYnVpbGQob2IsIGNsYXp6KSA6IG5ldyBjbGF6eihvYilcbiAgICAgICkgYXMgTTtcbiAgICAgIGNvbnN0IGF0dHJpYnV0ZXMgPSBNb2RlbC5nZXRBdHRyaWJ1dGVzKGNsYXp6KTtcbiAgICAgIGNvbnN0IGtleXMgPSBhdHRyaWJ1dGVzLmxlbmd0aCA/IGF0dHJpYnV0ZXMgOiBPYmplY3Qua2V5cyhtKTtcbiAgICAgIHJldHVybiBrZXlzXG4gICAgICAgIC5maWx0ZXIoKGspID0+IGsgIT09IChwayBhcyBzdHJpbmcpKVxuICAgICAgICAucmVkdWNlKChhY2N1bTogTSwga2V5KSA9PiB7XG4gICAgICAgICAgKGFjY3VtIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW2tleV0gPVxuICAgICAgICAgICAgcltNb2RlbC5jb2x1bW5OYW1lKGFjY3VtLCBrZXkgYXMgYW55KV07XG4gICAgICAgICAgcmV0dXJuIGFjY3VtO1xuICAgICAgICB9LCBtKTtcbiAgICB9XG5cbiAgICBsZXQgcmVzdWx0ID0gbWFwVG9Nb2RlbChvYmopO1xuXG4gICAgaWYgKHRyYW5zaWVudCAmJiAhdGhpcy5zaG91bGRSZWJ1aWxkV2l0aFRyYW5zaWVudChjdHgpKSB7XG4gICAgICBsb2cuZGVidWcoXG4gICAgICAgIGBmaWx0ZXJpbmcgdHJhbnNpZW50IHByb3BlcnRpZXM6ICR7T2JqZWN0LmtleXModHJhbnNpZW50KS5qb2luKFwiLCBcIil9YFxuICAgICAgKTtcbiAgICAgIHJlc3VsdCA9IE9iamVjdC5lbnRyaWVzKHJlc3VsdCkucmVkdWNlKChhY2MsIFtrZXksIHZdKSA9PiB7XG4gICAgICAgIGlmIChrZXkgPT09IHBrIHx8ICEoa2V5IGluIHRyYW5zaWVudCkpIHtcbiAgICAgICAgICBhY2Nba2V5IGFzIGtleW9mIE1dID0gdjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSwgbmV3IGNsYXp6KCkpO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcml2YXRlIHNob3VsZFJlYnVpbGRXaXRoVHJhbnNpZW50KGN0eDogRmFicmljQ29udHJhY3RDb250ZXh0KTogYm9vbGVhbiB7XG4gICAgaWYgKCFjdHgpIHJldHVybiBmYWxzZTtcbiAgICBpZiAoY3R4LmdldE9yVW5kZWZpbmVkKFwicmVidWlsZFdpdGhUcmFuc2llbnRcIikpIHJldHVybiB0cnVlO1xuICAgIGNvbnN0IG9wZXJhdGlvbiA9IGN0eC5nZXRPclVuZGVmaW5lZChcIm9wZXJhdGlvblwiKSBhcyBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgaWYgKCFvcGVyYXRpb24pIHJldHVybiB0cnVlO1xuICAgIGNvbnN0IG9wID0gb3BlcmF0aW9uLnRvU3RyaW5nKCkudG9Mb3dlckNhc2UoKTtcbiAgICByZXR1cm4gIVRyYW5zYWN0aW9uT3BlcmF0aW9uS2V5cy5tYXAoKGspID0+IGsudG9Mb3dlckNhc2UoKSkuaW5jbHVkZXMob3ApO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRDb250ZXh0TXNwKGNvbnRleHQ6IEZhYnJpY0NvbnRyYWN0Q29udGV4dCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgaWRlbnRpdHkgPSBjb250ZXh0LmdldChcImlkZW50aXR5XCIpIGFzXG4gICAgICB8IHN0cmluZ1xuICAgICAgfCBDbGllbnRJZGVudGl0eVxuICAgICAgfCB1bmRlZmluZWQ7XG4gICAgaWYgKCFpZGVudGl0eSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBpZiAodHlwZW9mIGlkZW50aXR5ID09PSBcInN0cmluZ1wiKSByZXR1cm4gaWRlbnRpdHk7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBpZGVudGl0eS5nZXRNU1BJRCgpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGVuZm9yY2VNaXJyb3JBdXRob3JpemF0aW9uPE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgY2xheno6IENvbnN0cnVjdG9yPE0+LFxuICAgIGN0eDogRmFicmljQ29udHJhY3RDb250ZXh0XG4gICk6IHZvaWQge1xuICAgIGNvbnN0IG1pcnJvck1ldGEgPSBNb2RlbC5taXJyb3JlZEF0KGNsYXp6KTtcbiAgICBpZiAoIW1pcnJvck1ldGEpIHJldHVybjtcbiAgICBjb25zdCBtc3AgPSB0aGlzLmdldENvbnRleHRNc3AoY3R4KTtcbiAgICBpZiAoIW1zcCkgcmV0dXJuO1xuICAgIGlmIChcbiAgICAgIG1zcCA9PT0gbWlycm9yTWV0YS5tc3BJZCB8fFxuICAgICAgKG1pcnJvck1ldGEuY29uZGl0aW9uICYmIG1pcnJvck1ldGEuY29uZGl0aW9uKG1zcCkpXG4gICAgKSB7XG4gICAgICB0aHJvdyBuZXcgQXV0aG9yaXphdGlvbkVycm9yKFxuICAgICAgICBgT3JnYW5pemF0aW9uICR7bXNwfSBpcyBub3QgYXV0aG9yaXplZCB0byBtb2RpZnkgbWlycm9yZWQgZGF0YWBcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgb3ZlcnJpZGUgY3JlYXRlUHJlZml4PE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgdGFibGVOYW1lOiBDb25zdHJ1Y3RvcjxNPixcbiAgICBpZDogUHJpbWFyeUtleVR5cGUsXG4gICAgbW9kZWw6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgLi4uYXJnczogTWF5YmVDb250ZXh0dWFsQXJnPEZhYnJpY0NvbnRyYWN0Q29udGV4dD5cbiAgKSB7XG4gICAgY29uc3QgeyBjdHhBcmdzIH0gPSB0aGlzLmxvZ0N0eChhcmdzLCB0aGlzLmNyZWF0ZVByZWZpeCk7XG4gICAgY29uc3QgcmVjb3JkOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG4gICAgcmVjb3JkW0NvdWNoREJLZXlzLlRBQkxFXSA9IE1vZGVsLnRhYmxlTmFtZSh0YWJsZU5hbWUpO1xuICAgIE9iamVjdC5hc3NpZ24ocmVjb3JkLCBtb2RlbCk7XG5cbiAgICByZXR1cm4gW3RhYmxlTmFtZSwgaWQsIHJlY29yZCwgLi4uY3R4QXJnc10gYXMgW1xuICAgICAgQ29uc3RydWN0b3I8TT4sXG4gICAgICBQcmltYXJ5S2V5VHlwZSxcbiAgICAgIFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgICAuLi5hbnlbXSxcbiAgICAgIEZhYnJpY0NvbnRyYWN0Q29udGV4dCxcbiAgICBdO1xuICB9XG5cbiAgb3ZlcnJpZGUgdXBkYXRlUHJlZml4PE0gZXh0ZW5kcyBNb2RlbD4oXG4gICAgdGFibGVOYW1lOiBDb25zdHJ1Y3RvcjxNPixcbiAgICBpZDogUHJpbWFyeUtleVR5cGUsXG4gICAgbW9kZWw6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgLi4uYXJnczogTWF5YmVDb250ZXh0dWFsQXJnPEZhYnJpY0NvbnRyYWN0Q29udGV4dD5cbiAgKTogYW55W10ge1xuICAgIGNvbnN0IHsgY3R4QXJncyB9ID0gdGhpcy5sb2dDdHgoYXJncywgdGhpcy51cGRhdGVQcmVmaXgpO1xuICAgIGNvbnN0IHJlY29yZDogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xuICAgIHJlY29yZFtDb3VjaERCS2V5cy5UQUJMRV0gPSBNb2RlbC50YWJsZU5hbWUodGFibGVOYW1lKTtcbiAgICBPYmplY3QuYXNzaWduKHJlY29yZCwgbW9kZWwpO1xuXG4gICAgcmV0dXJuIFt0YWJsZU5hbWUsIGlkLCByZWNvcmQsIC4uLmN0eEFyZ3NdIGFzIFtcbiAgICAgIENvbnN0cnVjdG9yPE0+LFxuICAgICAgUHJpbWFyeUtleVR5cGUsXG4gICAgICBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICAgICAgLi4uYW55W10sXG4gICAgICBGYWJyaWNDb250cmFjdENvbnRleHQsXG4gICAgXTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvdmVycmlkZSBjcmVhdGVBbGxQcmVmaXg8TSBleHRlbmRzIE1vZGVsPihcbiAgICB0YWJsZU5hbWU6IENvbnN0cnVjdG9yPE0+LFxuICAgIGlkczogUHJpbWFyeUtleVR5cGVbXSxcbiAgICBtb2RlbHM6IFJlY29yZDxzdHJpbmcsIGFueT5bXSxcbiAgICAuLi5hcmdzOiBbLi4uYW55LCBGYWJyaWNDb250cmFjdENvbnRleHRdXG4gICk6IChzdHJpbmcgfCBzdHJpbmdbXSB8IG51bWJlcltdIHwgUmVjb3JkPHN0cmluZywgYW55PltdKVtdIHtcbiAgICBpZiAoaWRzLmxlbmd0aCAhPT0gbW9kZWxzLmxlbmd0aClcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiSWRzIGFuZCBtb2RlbHMgbXVzdCBoYXZlIHRoZSBzYW1lIGxlbmd0aFwiKTtcblxuICAgIGNvbnN0IGN0eDogRmFicmljQ29udHJhY3RDb250ZXh0ID0gYXJncy5wb3AoKTtcblxuICAgIGNvbnN0IHJlY29yZHMgPSBpZHMubWFwKChpZCwgY291bnQpID0+IHtcbiAgICAgIGNvbnN0IHJlY29yZDogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xuICAgICAgcmVjb3JkW0NvdWNoREJLZXlzLlRBQkxFXSA9IE1vZGVsLnRhYmxlTmFtZSh0YWJsZU5hbWUpO1xuICAgICAgT2JqZWN0LmFzc2lnbihyZWNvcmQsIG1vZGVsc1tjb3VudF0pO1xuICAgICAgcmV0dXJuIHJlY29yZDtcbiAgICB9KTtcbiAgICByZXR1cm4gW3RhYmxlTmFtZSwgaWRzLCByZWNvcmRzLCBjdHggYXMgYW55XTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvdmVycmlkZSB1cGRhdGVBbGxQcmVmaXg8TSBleHRlbmRzIE1vZGVsPihcbiAgICB0YWJsZU5hbWU6IENvbnN0cnVjdG9yPE0+LFxuICAgIGlkczogUHJpbWFyeUtleVR5cGVbXSxcbiAgICBtb2RlbHM6IFJlY29yZDxzdHJpbmcsIGFueT5bXSxcbiAgICAuLi5hcmdzOiBbLi4uYW55LCBGYWJyaWNDb250cmFjdENvbnRleHRdXG4gICkge1xuICAgIGlmIChpZHMubGVuZ3RoICE9PSBtb2RlbHMubGVuZ3RoKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJJZHMgYW5kIG1vZGVscyBtdXN0IGhhdmUgdGhlIHNhbWUgbGVuZ3RoXCIpO1xuXG4gICAgY29uc3QgY3R4OiBGYWJyaWNDb250cmFjdENvbnRleHQgPSBhcmdzLnBvcCgpO1xuXG4gICAgY29uc3QgcmVjb3JkcyA9IGlkcy5tYXAoKGlkLCBjb3VudCkgPT4ge1xuICAgICAgY29uc3QgcmVjb3JkOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG4gICAgICByZWNvcmRbQ291Y2hEQktleXMuVEFCTEVdID0gTW9kZWwudGFibGVOYW1lKHRhYmxlTmFtZSk7XG4gICAgICBPYmplY3QuYXNzaWduKHJlY29yZCwgbW9kZWxzW2NvdW50XSk7XG4gICAgICByZXR1cm4gcmVjb3JkO1xuICAgIH0pO1xuICAgIHJldHVybiBbdGFibGVOYW1lLCBpZHMsIHJlY29yZHMsIGN0eCBhcyBhbnldO1xuICB9XG5cbiAgb3ZlcnJpZGUgcGFyc2VFcnJvcjxFIGV4dGVuZHMgQmFzZUVycm9yPihcbiAgICBlcnI6IEVycm9yIHwgc3RyaW5nLFxuICAgIHJlYXNvbj86IHN0cmluZ1xuICApOiBFIHtcbiAgICByZXR1cm4gRmFicmljQ29udHJhY3RBZGFwdGVyLnBhcnNlRXJyb3IocmVhc29uIHx8IGVycik7XG4gIH1cblxuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgbG9nQ3R4PFxuICAgIEFSR1MgZXh0ZW5kcyBhbnlbXSA9IGFueVtdLFxuICAgIE1FVEhPRCBleHRlbmRzIE1ldGhvZE9yT3BlcmF0aW9uID0gTWV0aG9kT3JPcGVyYXRpb24sXG4gID4oXG4gICAgYXJnczogTWF5YmVDb250ZXh0dWFsQXJnPEZhYnJpY0NvbnRyYWN0Q29udGV4dCwgQVJHUz4sXG4gICAgb3BlcmF0aW9uOiBNRVRIT0RcbiAgKTogRmFicmljQ29udGV4dHVhbGl6ZWRBcmdzPEFSR1MsIE1FVEhPRCBleHRlbmRzIHN0cmluZyA/IHRydWUgOiBmYWxzZT47XG4gIHByb3RlY3RlZCBvdmVycmlkZSBsb2dDdHg8XG4gICAgQVJHUyBleHRlbmRzIGFueVtdID0gYW55W10sXG4gICAgTUVUSE9EIGV4dGVuZHMgTWV0aG9kT3JPcGVyYXRpb24gPSBNZXRob2RPck9wZXJhdGlvbixcbiAgPihcbiAgICBhcmdzOiBNYXliZUNvbnRleHR1YWxBcmc8RmFicmljQ29udHJhY3RDb250ZXh0LCBBUkdTPixcbiAgICBvcGVyYXRpb246IE1FVEhPRCxcbiAgICBhbGxvd0NyZWF0ZTogZmFsc2VcbiAgKTogRmFicmljQ29udGV4dHVhbGl6ZWRBcmdzPEFSR1MsIE1FVEhPRCBleHRlbmRzIHN0cmluZyA/IHRydWUgOiBmYWxzZT47XG4gIHByb3RlY3RlZCBvdmVycmlkZSBsb2dDdHg8XG4gICAgQVJHUyBleHRlbmRzIGFueVtdID0gYW55W10sXG4gICAgTUVUSE9EIGV4dGVuZHMgTWV0aG9kT3JPcGVyYXRpb24gPSBNZXRob2RPck9wZXJhdGlvbixcbiAgPihcbiAgICBhcmdzOiBNYXliZUNvbnRleHR1YWxBcmc8RmFicmljQ29udHJhY3RDb250ZXh0LCBBUkdTPixcbiAgICBvcGVyYXRpb246IE1FVEhPRCxcbiAgICBhbGxvd0NyZWF0ZTogdHJ1ZSxcbiAgICBvdmVycmlkZXM/OiBQYXJ0aWFsPEZsYWdzT2Y8RmFicmljQ29udHJhY3RDb250ZXh0Pj5cbiAgKTogUHJvbWlzZTxcbiAgICBGYWJyaWNDb250ZXh0dWFsaXplZEFyZ3M8QVJHUywgTUVUSE9EIGV4dGVuZHMgc3RyaW5nID8gdHJ1ZSA6IGZhbHNlPlxuICA+O1xuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgbG9nQ3R4PFxuICAgIEFSR1MgZXh0ZW5kcyBhbnlbXSA9IGFueVtdLFxuICAgIE1FVEhPRCBleHRlbmRzIE1ldGhvZE9yT3BlcmF0aW9uID0gTWV0aG9kT3JPcGVyYXRpb24sXG4gID4oXG4gICAgYXJnczogTWF5YmVDb250ZXh0dWFsQXJnPEZhYnJpY0NvbnRyYWN0Q29udGV4dCwgQVJHUz4sXG4gICAgb3BlcmF0aW9uOiBNRVRIT0QsXG4gICAgYWxsb3dDcmVhdGU6IGJvb2xlYW4gPSBmYWxzZSxcbiAgICBvdmVycmlkZXM/OiBQYXJ0aWFsPEZsYWdzT2Y8RmFicmljQ29udHJhY3RDb250ZXh0Pj4gfCBDdHhcbiAgKTpcbiAgICB8IFByb21pc2U8XG4gICAgICAgIEZhYnJpY0NvbnRleHR1YWxpemVkQXJnczxBUkdTLCBNRVRIT0QgZXh0ZW5kcyBzdHJpbmcgPyB0cnVlIDogZmFsc2U+XG4gICAgICA+XG4gICAgfCBGYWJyaWNDb250ZXh0dWFsaXplZEFyZ3M8QVJHUywgTUVUSE9EIGV4dGVuZHMgc3RyaW5nID8gdHJ1ZSA6IGZhbHNlPiB7XG4gICAgaWYgKCFhbGxvd0NyZWF0ZSlcbiAgICAgIHJldHVybiBzdXBlci5sb2dDdHg8QVJHUywgTUVUSE9EPihcbiAgICAgICAgYXJncyxcbiAgICAgICAgb3BlcmF0aW9uIGFzIGFueSxcbiAgICAgICAgYWxsb3dDcmVhdGUgYXMgYW55LFxuICAgICAgICBvdmVycmlkZXMgYXMgYW55XG4gICAgICApIGFzIGFueTtcblxuICAgIHJldHVybiBzdXBlci5sb2dDdHhcbiAgICAgIC5jYWxsKHRoaXMsIGFyZ3MsIG9wZXJhdGlvbiBhcyBhbnksIGFsbG93Q3JlYXRlLCBvdmVycmlkZXMgYXMgYW55KVxuICAgICAgLnRoZW4oKHJlcykgPT4ge1xuICAgICAgICBpZiAoIShyZXMuY3R4IGluc3RhbmNlb2YgRmFicmljQ29udHJhY3RDb250ZXh0KSlcbiAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgSW52YWxpZCBjb250ZXh0IGJpbmRpbmdgKTtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24ocmVzLCB7XG4gICAgICAgICAgc3R1YjogcmVzLmN0eC5zdHViLFxuICAgICAgICAgIGlkZW50aXR5OiByZXMuY3R4LmlkZW50aXR5LFxuICAgICAgICB9KTtcbiAgICAgIH0pIGFzIGFueTtcbiAgfVxuXG4gIG92ZXJyaWRlIGFzeW5jIHVwZGF0ZU9ic2VydmVycyhcbiAgICB0YWJsZTogQ29uc3RydWN0b3I8YW55PiB8IHN0cmluZyxcbiAgICBldmVudDogT3BlcmF0aW9uS2V5cyB8IEJ1bGtDcnVkT3BlcmF0aW9uS2V5cyB8IHN0cmluZyxcbiAgICBpZDogRXZlbnRJZHMsXG4gICAgLi4uYXJnczogQ29udGV4dHVhbEFyZ3M8RmFicmljQ29udHJhY3RDb250ZXh0PlxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMub2JzZXJ2ZXJIYW5kbGVyKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgIFwiT2JzZXJ2ZXJIYW5kbGVyIG5vdCBpbml0aWFsaXplZC4gRGlkIHlvdSByZWdpc3RlciBhbnkgb2JzZXJ2YWJsZXM/XCJcbiAgICAgICk7XG4gICAgY29uc3QgeyBjdHgsIGN0eEFyZ3MgfSA9IHRoaXMubG9nQ3R4KGFyZ3MsIHRoaXMudXBkYXRlT2JzZXJ2ZXJzKTtcbiAgICBpZiAoY3R4LmlzRnVsbHlTZWdyZWdhdGVkKSByZXR1cm47XG4gICAgaWYgKGN0eC5nZXRPclVuZGVmaW5lZChcIm5vRW1pdFwiKSkgcmV0dXJuO1xuICAgIGlmICghY3R4LnN0dWIpIHJldHVybjtcbiAgICBjb25zdCBpc0J1bGsgPSBBcnJheS5pc0FycmF5KGlkKTtcbiAgICBjb25zdCBlbWl0U2luZ2xlID0gIWN0eC5nZXRPclVuZGVmaW5lZChcIm5vRW1pdFNpbmdsZVwiKTtcbiAgICBjb25zdCBlbWl0QnVsayA9ICFjdHguZ2V0T3JVbmRlZmluZWQoXCJub0VtaXRCdWxrXCIpO1xuICAgIGlmICgoaXNCdWxrICYmIGVtaXRCdWxrKSB8fCAoIWlzQnVsayAmJiBlbWl0U2luZ2xlKSkge1xuICAgICAgLy8gUGFzcyB0aGUgTVNQIG93bmVyIGZyb20gc3R1YiBhbmQgdGhlIHJlc3VsdCBwYXlsb2FkIChpZiBhbnkpIGluIHRoZVxuICAgICAgLy8gcG9zaXRpb25zIHRoZSBoYW5kbGVyIGV4cGVjdHM6ICh0YWJsZSwgZXZlbnQsIGlkLCBvd25lcj8sIHBheWxvYWQ/LCBjdHgpXG4gICAgICBjb25zdCBtc3BJZCA9IGN0eC5zdHViLmdldE1zcElEID8gY3R4LnN0dWIuZ2V0TXNwSUQoKSA6IHVuZGVmaW5lZDtcbiAgICAgIGNvbnN0IG5vbkN0eEFyZ3MgPSBjdHhBcmdzLnNsaWNlKDAsIC0xKTsgLy8gZXZlcnl0aGluZyBiZWZvcmUgY3R4XG4gICAgICBjb25zdCBwYXlsb2FkID0gbm9uQ3R4QXJncy5sZW5ndGggPiAwID8gbm9uQ3R4QXJnc1swXSA6IHVuZGVmaW5lZDtcbiAgICAgIGF3YWl0IHRoaXMub2JzZXJ2ZXJIYW5kbGVyLnVwZGF0ZU9ic2VydmVycyhcbiAgICAgICAgdGFibGUsXG4gICAgICAgIGV2ZW50LFxuICAgICAgICBpZCxcbiAgICAgICAgbXNwSWQsXG4gICAgICAgIHBheWxvYWQsXG4gICAgICAgIGN0eFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgb3ZlcnJpZGUgcGFyc2VFcnJvcjxFIGV4dGVuZHMgQmFzZUVycm9yPihlcnI6IEVycm9yIHwgc3RyaW5nKTogRSB7XG4gICAgLy8gaWYgKFxuICAgIC8vICAgTUlTU0lOR19QUklWQVRFX0RBVEFfUkVHRVgudGVzdChcbiAgICAvLyAgICAgdHlwZW9mIGVyciA9PT0gXCJzdHJpbmdcIiA/IGVyciA6IGVyci5tZXNzYWdlXG4gICAgLy8gICApXG4gICAgLy8gKVxuICAgIC8vICAgcmV0dXJuIG5ldyBVbmF1dGhvcml6ZWRQcml2YXRlRGF0YUFjY2VzcyhlcnIpIGFzIEU7XG4gICAgY29uc3QgbXNnID0gdHlwZW9mIGVyciA9PT0gXCJzdHJpbmdcIiA/IGVyciA6IGVyci5tZXNzYWdlO1xuICAgIGlmIChtc2cuaW5jbHVkZXMoTm90Rm91bmRFcnJvci5uYW1lKSkgcmV0dXJuIG5ldyBOb3RGb3VuZEVycm9yKGVycikgYXMgRTtcbiAgICBpZiAobXNnLmluY2x1ZGVzKENvbmZsaWN0RXJyb3IubmFtZSkpIHJldHVybiBuZXcgQ29uZmxpY3RFcnJvcihlcnIpIGFzIEU7XG4gICAgaWYgKG1zZy5pbmNsdWRlcyhCYWRSZXF1ZXN0RXJyb3IubmFtZSkpXG4gICAgICByZXR1cm4gbmV3IEJhZFJlcXVlc3RFcnJvcihlcnIpIGFzIEU7XG4gICAgaWYgKG1zZy5pbmNsdWRlcyhRdWVyeUVycm9yLm5hbWUpKSByZXR1cm4gbmV3IFF1ZXJ5RXJyb3IoZXJyKSBhcyBFO1xuICAgIGlmIChtc2cuaW5jbHVkZXMoUGFnaW5nRXJyb3IubmFtZSkpIHJldHVybiBuZXcgUGFnaW5nRXJyb3IoZXJyKSBhcyBFO1xuICAgIGlmIChtc2cuaW5jbHVkZXMoVW5zdXBwb3J0ZWRFcnJvci5uYW1lKSlcbiAgICAgIHJldHVybiBuZXcgVW5zdXBwb3J0ZWRFcnJvcihlcnIpIGFzIEU7XG4gICAgaWYgKG1zZy5pbmNsdWRlcyhNaWdyYXRpb25FcnJvci5uYW1lKSkgcmV0dXJuIG5ldyBNaWdyYXRpb25FcnJvcihlcnIpIGFzIEU7XG4gICAgaWYgKG1zZy5pbmNsdWRlcyhPYnNlcnZlckVycm9yLm5hbWUpKSByZXR1cm4gbmV3IE9ic2VydmVyRXJyb3IoZXJyKSBhcyBFO1xuICAgIGlmIChtc2cuaW5jbHVkZXMoQXV0aG9yaXphdGlvbkVycm9yLm5hbWUpKVxuICAgICAgcmV0dXJuIG5ldyBBdXRob3JpemF0aW9uRXJyb3IoZXJyKSBhcyBFO1xuICAgIGlmIChtc2cuaW5jbHVkZXMoRm9yYmlkZGVuRXJyb3IubmFtZSkpIHJldHVybiBuZXcgRm9yYmlkZGVuRXJyb3IoZXJyKSBhcyBFO1xuICAgIGlmIChtc2cuaW5jbHVkZXMoQ29ubmVjdGlvbkVycm9yLm5hbWUpKVxuICAgICAgcmV0dXJuIG5ldyBDb25uZWN0aW9uRXJyb3IoZXJyKSBhcyBFO1xuICAgIGlmIChtc2cuaW5jbHVkZXMoU2VyaWFsaXphdGlvbkVycm9yLm5hbWUpKVxuICAgICAgcmV0dXJuIG5ldyBTZXJpYWxpemF0aW9uRXJyb3IoZXJyKSBhcyBFO1xuICAgIGlmIChtc2cuaW5jbHVkZXMoXCJubyBsZWRnZXIgY29udGV4dFwiKSlcbiAgICAgIHJldHVybiBuZXcgTWlzc2luZ0NvbnRleHRFcnJvcihcbiAgICAgICAgYE5vIGNvbnRleHQgZm91bmQuIHRoaXMgY2FuIGJlIGNhdXNlZCBieSBkZWJ1Z2dpbmc6ICR7bXNnfWBcbiAgICAgICkgYXMgRTtcblxuICAgIHJldHVybiBuZXcgSW50ZXJuYWxFcnJvcihlcnIpIGFzIEU7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFN0YXRpYyBtZXRob2QgZm9yIGRlY29yYXRpb24gb3ZlcnJpZGVzXG4gICAqIEBzdW1tYXJ5IE92ZXJyaWRlcy9leHRlbmRzIGRlY2FmIGRlY29yYXRpb24gd2l0aCBGYWJyaWMtc3BlY2lmaWMgZnVuY3Rpb25hbGl0eVxuICAgKiBAc3RhdGljXG4gICAqIEBvdmVycmlkZVxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgc3RhdGljIG92ZXJyaWRlIGRlY29yYXRpb24oKTogdm9pZCB7XG4gICAgc3VwZXIuZGVjb3JhdGlvbigpO1xuICAgIERlY29yYXRpb24uZmxhdm91cmVkQXMoRmFicmljRmxhdm91cilcbiAgICAgIC5mb3IoUGVyc2lzdGVuY2VLZXlzLkNSRUFURURfQlkpXG4gICAgICAuZGVmaW5lKHtcbiAgICAgICAgZGVjb3JhdG9yOiBmdW5jdGlvbiBjcmVhdGVkQnkoKSB7XG4gICAgICAgICAgcmV0dXJuIGFwcGx5KFxuICAgICAgICAgICAgb25DcmVhdGUoY3JlYXRlZEJ5T25GYWJyaWNDcmVhdGVVcGRhdGUpLFxuICAgICAgICAgICAgcHJvcE1ldGFkYXRhKFBlcnNpc3RlbmNlS2V5cy5DUkVBVEVEX0JZLCB7fSlcbiAgICAgICAgICApO1xuICAgICAgICB9LFxuICAgICAgfSBhcyBhbnkpXG4gICAgICAuYXBwbHkoKTtcblxuICAgIERlY29yYXRpb24uZmxhdm91cmVkQXMoRmFicmljRmxhdm91cilcbiAgICAgIC5mb3IoUGVyc2lzdGVuY2VLZXlzLlVQREFURURfQlkpXG4gICAgICAuZGVmaW5lKHtcbiAgICAgICAgZGVjb3JhdG9yOiBmdW5jdGlvbiBjcmVhdGVkQnkoKSB7XG4gICAgICAgICAgcmV0dXJuIGFwcGx5KFxuICAgICAgICAgICAgb25DcmVhdGVVcGRhdGUoY3JlYXRlZEJ5T25GYWJyaWNDcmVhdGVVcGRhdGUpLFxuICAgICAgICAgICAgcHJvcE1ldGFkYXRhKFBlcnNpc3RlbmNlS2V5cy5VUERBVEVEX0JZLCB7fSlcbiAgICAgICAgICApO1xuICAgICAgICB9LFxuICAgICAgfSBhcyBhbnkpXG4gICAgICAuYXBwbHkoKTtcblxuICAgIERlY29yYXRpb24uZmxhdm91cmVkQXMoRmFicmljRmxhdm91cilcbiAgICAgIC5mb3IoUGVyc2lzdGVuY2VLZXlzLkNPTFVNTilcbiAgICAgIC5leHRlbmQoRmFicmljUHJvcGVydHkoKSlcbiAgICAgIC5hcHBseSgpO1xuXG4gICAgRGVjb3JhdGlvbi5mbGF2b3VyZWRBcyhGYWJyaWNGbGF2b3VyKVxuICAgICAgLmZvcihWYWxpZGF0aW9uS2V5cy5EQVRFKVxuICAgICAgLmV4dGVuZChmdW5jdGlvbiBmYWJyaWNQcm9wZXJ0eSgpIHtcbiAgICAgICAgcmV0dXJuICh0YXJnZXQ6IGFueSwgcHJvcD86IGFueSkgPT4ge1xuICAgICAgICAgIFByb3BlcnR5KHByb3AsIFwic3RyaW5nOmRhdGVcIikodGFyZ2V0LCBwcm9wKTtcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuXG4gICAgRGVjb3JhdGlvbi5mbGF2b3VyZWRBcyhGYWJyaWNGbGF2b3VyKVxuICAgICAgLmZvcihQZXJzaXN0ZW5jZUtleXMuVEFCTEUpXG4gICAgICAuZXh0ZW5kKGZ1bmN0aW9uIHRhYmxlKG9iajogYW55KSB7XG4gICAgICAgIGNvbnN0IGNoYWluOiBhbnlbXSA9IFtdO1xuICAgICAgICBsZXQgY3VycmVudCA9XG4gICAgICAgICAgdHlwZW9mIG9iaiA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgICAgICA/IE1ldGFkYXRhLmNvbnN0cihvYmopXG4gICAgICAgICAgICA6IE1ldGFkYXRhLmNvbnN0cihvYmouY29uc3RydWN0b3IpO1xuXG4gICAgICAgIHdoaWxlIChjdXJyZW50ICYmIGN1cnJlbnQgIT09IE9iamVjdCAmJiBjdXJyZW50LnByb3RvdHlwZSkge1xuICAgICAgICAgIGNoYWluLnB1c2goY3VycmVudCk7XG4gICAgICAgICAgY3VycmVudCA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihjdXJyZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnNvbGUubG9nKGNoYWluLm1hcCgoYykgPT4gYy5uYW1lIHx8IGMpKTtcblxuICAgICAgICAvLyBBcHBseSBmcm9tIHRoZSBiYXNlIGNsYXNzIGRvd24gdG8gdGhlIGRlY29yYXRlZCBjbGFzc1xuICAgICAgICB3aGlsZSAoY2hhaW4ubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGNvbnN0IGNvbnN0cnVjdG9yID0gY2hhaW4ucG9wKCk7XG4gICAgICAgICAgY29uc29sZS5sb2coYENhbGxpbmcgb24gJHtjb25zdHJ1Y3Rvci5uYW1lfWApO1xuICAgICAgICAgIEZhYnJpY09iamVjdCgpKGNvbnN0cnVjdG9yKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBGYWJyaWNPYmplY3QoKShvYmopO1xuICAgICAgfSlcbiAgICAgIC5hcHBseSgpO1xuICB9XG59XG5cbkZhYnJpY0NvbnRyYWN0QWRhcHRlci5kZWNvcmF0aW9uKCk7XG5BZGFwdGVyLnNldEN1cnJlbnQoRmFicmljRmxhdm91cik7XG4iXX0=
|