@decaf-ts/integrations 0.3.11 → 0.3.12
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/integrations.cjs +1649 -2
- package/dist/integrations.js +1885 -2
- package/lib/cjs/blob/azure/AzureBlobStoreService.cjs +2 -2
- package/lib/cjs/blob/azure/index.cjs +2 -2
- package/lib/cjs/blob/core/BlobErrors.cjs +2 -2
- package/lib/cjs/blob/core/BlobKey.cjs +2 -2
- package/lib/cjs/blob/core/BlobStoreFactory.cjs +2 -2
- package/lib/cjs/blob/core/BlobStoreService.cjs +2 -2
- package/lib/cjs/blob/core/BlobTypes.cjs +2 -2
- package/lib/cjs/blob/core/BlobValue.cjs +2 -2
- package/lib/cjs/blob/core/index.cjs +2 -2
- package/lib/cjs/blob/gcp/GcsBlobStoreService.cjs +2 -2
- package/lib/cjs/blob/gcp/index.cjs +2 -2
- package/lib/cjs/blob/index.cjs +2 -2
- package/lib/cjs/blob/ipfs/IpfsBlobStoreService.cjs +2 -2
- package/lib/cjs/blob/ipfs/IpfsKeyIndex.cjs +2 -2
- package/lib/cjs/blob/ipfs/LocalJsonIpfsKeyIndex.cjs +2 -2
- package/lib/cjs/blob/ipfs/MemoryIpfsKeyIndex.cjs +2 -2
- package/lib/cjs/blob/ipfs/PostgresIpfsKeyIndex.cjs +2 -2
- package/lib/cjs/blob/ipfs/index.cjs +2 -2
- package/lib/cjs/blob/local/LocalBlobStoreService.cjs +2 -2
- package/lib/cjs/blob/local/index.cjs +2 -2
- package/lib/cjs/blob/memory/MemoryBlobStoreService.cjs +2 -2
- package/lib/cjs/blob/memory/index.cjs +2 -2
- package/lib/cjs/blob/s3/MinioBlobStoreService.cjs +2 -2
- package/lib/cjs/blob/s3/R2BlobStoreService.cjs +2 -2
- package/lib/cjs/blob/s3/S3BlobStoreService.cjs +2 -2
- package/lib/cjs/blob/s3/index.cjs +2 -2
- package/lib/cjs/docker/DockerComposeService.cjs +2 -2
- package/lib/cjs/docker/index.cjs +2 -2
- package/lib/cjs/graph/engine/constants.cjs +2 -2
- package/lib/cjs/graph/engine/decorators.cjs +2 -2
- package/lib/cjs/graph/engine/errors/GraphCycleError.cjs +2 -2
- package/lib/cjs/graph/engine/errors/GraphExecutionError.cjs +2 -2
- package/lib/cjs/graph/engine/errors/GraphInputError.cjs +2 -2
- package/lib/cjs/graph/engine/errors/GraphLoopLimitError.cjs +2 -2
- package/lib/cjs/graph/engine/errors/GraphPinningError.cjs +2 -2
- package/lib/cjs/graph/engine/errors/GraphPortError.cjs +2 -2
- package/lib/cjs/graph/engine/errors/GraphStoreError.cjs +2 -2
- package/lib/cjs/graph/engine/errors/GraphTopologyError.cjs +2 -2
- package/lib/cjs/graph/engine/errors/index.cjs +2 -2
- package/lib/cjs/graph/engine/events/GraphExecutionEvent.cjs +2 -2
- package/lib/cjs/graph/engine/events/GraphExecutionEventEmitter.cjs +2 -2
- package/lib/cjs/graph/engine/events/GraphExecutionEventFactory.cjs +2 -2
- package/lib/cjs/graph/engine/events/GraphExecutionObserver.cjs +2 -2
- package/lib/cjs/graph/engine/events/index.cjs +2 -2
- package/lib/cjs/graph/engine/execution/CodeGraphNodeExecutor.cjs +28 -31
- package/lib/cjs/graph/engine/execution/CodeSandboxEvaluator.cjs +2 -2
- package/lib/cjs/graph/engine/execution/GraphExecutionContext.cjs +2 -2
- package/lib/cjs/graph/engine/execution/GraphExecutionEngine.cjs +22 -3
- package/lib/cjs/graph/engine/execution/GraphExecutionFrame.cjs +2 -2
- package/lib/cjs/graph/engine/execution/GraphExecutionResult.cjs +2 -2
- package/lib/cjs/graph/engine/execution/GraphNodeExecutor.cjs +2 -2
- package/lib/cjs/graph/engine/execution/IsolatedVmCodeSandboxEvaluator.cjs +128 -2
- package/lib/cjs/graph/engine/execution/LogGraphNodeExecutor.cjs +19 -0
- package/lib/cjs/graph/engine/execution/SwitchGraphNodeExecutor.cjs +23 -6
- package/lib/cjs/graph/engine/execution/index.cjs +3 -2
- package/lib/cjs/graph/engine/index.cjs +3 -2
- package/lib/cjs/graph/engine/loops/ConditionExpressionEvaluator.cjs +2 -2
- package/lib/cjs/graph/engine/loops/ForeachGraphNodeExecutor.cjs +3 -2
- package/lib/cjs/graph/engine/loops/GraphConditionEvaluator.cjs +2 -2
- package/lib/cjs/graph/engine/loops/GraphLoopExecutionContext.cjs +2 -2
- package/lib/cjs/graph/engine/loops/UntilGraphNodeExecutor.cjs +2 -2
- package/lib/cjs/graph/engine/loops/WhileGraphNodeExecutor.cjs +2 -2
- package/lib/cjs/graph/engine/loops/index.cjs +2 -2
- package/lib/cjs/graph/engine/pinning/GraphPinningDependencyResolver.cjs +2 -2
- package/lib/cjs/graph/engine/pinning/GraphPinningMetadata.cjs +2 -2
- package/lib/cjs/graph/engine/pinning/GraphPinningPolicy.cjs +2 -2
- package/lib/cjs/graph/engine/pinning/GraphPinningService.cjs +2 -2
- package/lib/cjs/graph/engine/pinning/index.cjs +2 -2
- package/lib/cjs/graph/engine/planning/GraphExecutionPlan.cjs +2 -2
- package/lib/cjs/graph/engine/planning/GraphExecutionPlanEdge.cjs +2 -2
- package/lib/cjs/graph/engine/planning/GraphExecutionPlanLayer.cjs +2 -2
- package/lib/cjs/graph/engine/planning/GraphExecutionPlanNode.cjs +2 -2
- package/lib/cjs/graph/engine/planning/GraphExecutionPlanner.cjs +2 -2
- package/lib/cjs/graph/engine/planning/GraphRelationResolver.cjs +2 -2
- package/lib/cjs/graph/engine/planning/GraphTopology.cjs +2 -2
- package/lib/cjs/graph/engine/planning/index.cjs +2 -2
- package/lib/cjs/graph/engine/registry/GraphNodeExecutorRegistry.cjs +2 -2
- package/lib/cjs/graph/engine/registry/GraphNodeExecutorResolver.cjs +2 -2
- package/lib/cjs/graph/engine/registry/index.cjs +2 -2
- package/lib/cjs/graph/engine/snapshots/GraphExecutionSnapshotMapper.cjs +2 -2
- package/lib/cjs/graph/engine/snapshots/index.cjs +2 -2
- package/lib/cjs/graph/engine/store/GraphCachedValue.cjs +2 -2
- package/lib/cjs/graph/engine/store/GraphValueKey.cjs +2 -2
- package/lib/cjs/graph/engine/store/GraphValueStore.cjs +2 -2
- package/lib/cjs/graph/engine/store/GraphValueStoreAdapter.cjs +2 -2
- package/lib/cjs/graph/engine/store/InMemoryGraphValueStoreAdapter.cjs +2 -2
- package/lib/cjs/graph/engine/store/index.cjs +2 -2
- package/lib/cjs/graph/engine/types.cjs +2 -2
- package/lib/cjs/graph/engine/validation/GraphDefinitionValidator.cjs +2 -2
- package/lib/cjs/graph/engine/validation/GraphPortSchemaResolver.cjs +2 -2
- package/lib/cjs/graph/engine/validation/GraphValueValidator.cjs +2 -2
- package/lib/cjs/graph/engine/validation/index.cjs +2 -2
- package/lib/cjs/graph/index.cjs +2 -2
- package/lib/cjs/graph/shared/constants.cjs +2 -2
- package/lib/cjs/graph/shared/index.cjs +2 -2
- package/lib/cjs/graph/shared/nodes/agent.cjs +2 -2
- package/lib/cjs/graph/shared/nodes/base.cjs +2 -2
- package/lib/cjs/graph/shared/nodes/category-styles.cjs +2 -2
- package/lib/cjs/graph/shared/nodes/flow-control.cjs +92 -11
- package/lib/cjs/graph/shared/nodes/index.cjs +2 -2
- package/lib/cjs/graph/shared/nodes/triggers.cjs +2 -2
- package/lib/cjs/graph/shared/types.cjs +2 -2
- package/lib/cjs/index.cjs +5 -5
- package/lib/cjs/keycloak/index.cjs +2 -2
- package/lib/cjs/keycloak/services/KeycloakAuthService.cjs +2 -2
- package/lib/cjs/keycloak/services/KeycloakClientService.cjs +2 -2
- package/lib/cjs/keycloak/services/KeycloakIdentityProviderService.cjs +2 -2
- package/lib/cjs/keycloak/services/KeycloakRealmService.cjs +2 -2
- package/lib/cjs/keycloak/services/KeycloakRoleService.cjs +2 -2
- package/lib/cjs/keycloak/services/KeycloakService.cjs +2 -2
- package/lib/cjs/keycloak/services/KeycloakUserService.cjs +2 -2
- package/lib/cjs/keycloak/services/index.cjs +2 -2
- package/lib/cjs/keycloak/services/runtime.cjs +2 -2
- package/lib/cjs/keycloak/types.cjs +2 -2
- package/lib/cjs/kibana/helpers.cjs +2 -2
- package/lib/cjs/kibana/index.cjs +2 -2
- package/lib/cjs/kibana/services/KibanaAuthService.cjs +2 -2
- package/lib/cjs/kibana/services/KibanaDashboardService.cjs +2 -2
- package/lib/cjs/kibana/services/KibanaDataViewService.cjs +2 -2
- package/lib/cjs/kibana/services/KibanaRoleService.cjs +2 -2
- package/lib/cjs/kibana/services/KibanaService.cjs +2 -2
- package/lib/cjs/kibana/services/KibanaSpaceService.cjs +2 -2
- package/lib/cjs/kibana/services/KibanaUserService.cjs +2 -2
- package/lib/cjs/kibana/services/index.cjs +2 -2
- package/lib/cjs/kibana/services/runtime.cjs +2 -2
- package/lib/cjs/kibana/types.cjs +2 -2
- package/lib/cjs/namespaces/index.cjs +2 -2
- package/lib/cjs/namespaces/models/authorization-model.cjs +2 -2
- package/lib/cjs/namespaces/models/effective-permission.model.cjs +2 -2
- package/lib/cjs/namespaces/models/group-membership.model.cjs +2 -2
- package/lib/cjs/namespaces/models/group.model.cjs +2 -2
- package/lib/cjs/namespaces/models/index.cjs +2 -2
- package/lib/cjs/namespaces/models/inheritance-block.model.cjs +2 -2
- package/lib/cjs/namespaces/models/org-unit-closure.model.cjs +2 -2
- package/lib/cjs/namespaces/models/org-unit-membership.model.cjs +2 -2
- package/lib/cjs/namespaces/models/org-unit-profile.model.cjs +2 -2
- package/lib/cjs/namespaces/models/org-unit.model.cjs +2 -2
- package/lib/cjs/namespaces/models/permission.model.cjs +2 -2
- package/lib/cjs/namespaces/models/principal.model.cjs +2 -2
- package/lib/cjs/namespaces/models/protected-resource.model.cjs +2 -2
- package/lib/cjs/namespaces/models/resource-grant.model.cjs +2 -2
- package/lib/cjs/namespaces/models/role-assignment.model.cjs +2 -2
- package/lib/cjs/namespaces/models/role-permission.model.cjs +2 -2
- package/lib/cjs/namespaces/models/role.model.cjs +2 -2
- package/lib/cjs/namespaces/models/storage-binding.model.cjs +2 -2
- package/lib/cjs/namespaces/models/tenant-membership.model.cjs +2 -2
- package/lib/cjs/namespaces/models/tenant-profile.model.cjs +2 -2
- package/lib/cjs/namespaces/models/tenant.model.cjs +2 -2
- package/lib/cjs/namespaces/models/user.model.cjs +2 -2
- package/lib/cjs/namespaces/org-based-authorization-system.cjs +2 -2
- package/lib/cjs/namespaces/org-based-authorization-system.models.cjs +2 -2
- package/lib/cjs/namespaces/org-based-authorization-system.services.cjs +2 -2
- package/lib/cjs/namespaces/services/authz.service.cjs +2 -2
- package/lib/cjs/namespaces/services/bootstrap.service.cjs +2 -2
- package/lib/cjs/namespaces/services/effective-permission.service.cjs +2 -2
- package/lib/cjs/namespaces/services/group-membership.service.cjs +2 -2
- package/lib/cjs/namespaces/services/group.service.cjs +2 -2
- package/lib/cjs/namespaces/services/index.cjs +2 -2
- package/lib/cjs/namespaces/services/inheritance-block.service.cjs +2 -2
- package/lib/cjs/namespaces/services/org-unit-closure.service.cjs +2 -2
- package/lib/cjs/namespaces/services/org-unit-membership.service.cjs +2 -2
- package/lib/cjs/namespaces/services/org-unit-profile.service.cjs +2 -2
- package/lib/cjs/namespaces/services/org-unit.service.cjs +2 -2
- package/lib/cjs/namespaces/services/permission.service.cjs +2 -2
- package/lib/cjs/namespaces/services/principal.service.cjs +2 -2
- package/lib/cjs/namespaces/services/protected-resource.service.cjs +2 -2
- package/lib/cjs/namespaces/services/resource-grant.service.cjs +2 -2
- package/lib/cjs/namespaces/services/resource-lifecycle.service.cjs +2 -2
- package/lib/cjs/namespaces/services/role-assignment.service.cjs +2 -2
- package/lib/cjs/namespaces/services/role-permission.service.cjs +2 -2
- package/lib/cjs/namespaces/services/role.service.cjs +2 -2
- package/lib/cjs/namespaces/services/storage-binding.service.cjs +2 -2
- package/lib/cjs/namespaces/services/system-management.service.cjs +2 -2
- package/lib/cjs/namespaces/services/tenant-membership.service.cjs +2 -2
- package/lib/cjs/namespaces/services/tenant-profile.service.cjs +2 -2
- package/lib/cjs/namespaces/services/tenant.service.cjs +2 -2
- package/lib/cjs/namespaces/services/user.service.cjs +2 -2
- package/lib/cjs/namespaces/types.cjs +2 -2
- package/lib/cjs/namespaces/utils.cjs +2 -2
- package/lib/cjs/nest/authService.cjs +2 -2
- package/lib/cjs/nest/graph/GraphExecutionController.cjs +41 -52
- package/lib/cjs/nest/graph/GraphExecutionModule.cjs +47 -42
- package/lib/cjs/nest/graph/GraphExecutionResultModel.cjs +2 -20
- package/lib/cjs/nest/graph/GraphExecutorRegistryFactory.cjs +13 -48
- package/lib/cjs/nest/graph/GraphResultService.cjs +54 -0
- package/lib/cjs/nest/graph/GraphWorkflowModel.cjs +44 -0
- package/lib/cjs/nest/graph/GraphWorkflowService.cjs +62 -0
- package/lib/cjs/nest/graph/index.cjs +5 -8
- package/lib/cjs/nest/graph/main.cjs +3 -3
- package/lib/cjs/nest/index.cjs +2 -2
- package/lib/cjs/nest/keycloakAuthHandler.cjs +2 -2
- package/lib/cjs/nest/keycloakModule.cjs +2 -2
- package/lib/cjs/nest/logging.cjs +2 -2
- package/lib/cjs/nest/types.cjs +2 -2
- package/lib/cjs/nest/utils.cjs +2 -2
- package/lib/cjs/secrets/aws/AwsSecretService.cjs +2 -2
- package/lib/cjs/secrets/aws/AwsSecretServiceConfig.cjs +2 -2
- package/lib/cjs/secrets/aws/index.cjs +2 -2
- package/lib/cjs/secrets/azure/AzureKeyVaultSecretService.cjs +2 -2
- package/lib/cjs/secrets/azure/AzureKeyVaultSecretServiceConfig.cjs +2 -2
- package/lib/cjs/secrets/azure/index.cjs +2 -2
- package/lib/cjs/secrets/core/SecretErrors.cjs +2 -2
- package/lib/cjs/secrets/core/SecretName.cjs +2 -2
- package/lib/cjs/secrets/core/SecretReference.cjs +2 -2
- package/lib/cjs/secrets/core/SecretSerialization.cjs +2 -2
- package/lib/cjs/secrets/core/SecretService.cjs +2 -2
- package/lib/cjs/secrets/core/SecretTypes.cjs +2 -2
- package/lib/cjs/secrets/core/index.cjs +2 -2
- package/lib/cjs/secrets/gcp/GcpSecretManagerService.cjs +2 -2
- package/lib/cjs/secrets/gcp/GcpSecretManagerServiceConfig.cjs +2 -2
- package/lib/cjs/secrets/gcp/index.cjs +2 -2
- package/lib/cjs/secrets/index.cjs +2 -2
- package/lib/cjs/secrets/model/ModelSecretCrypto.cjs +2 -2
- package/lib/cjs/secrets/model/ModelSecretService.cjs +2 -2
- package/lib/cjs/secrets/model/ModelSecretServiceConfig.cjs +2 -2
- package/lib/cjs/secrets/model/Secret.cjs +2 -2
- package/lib/cjs/secrets/model/index.cjs +2 -2
- package/lib/cjs/secrets/onepassword/OnePasswordSecretService.cjs +2 -2
- package/lib/cjs/secrets/onepassword/OnePasswordSecretServiceConfig.cjs +2 -2
- package/lib/cjs/secrets/onepassword/index.cjs +2 -2
- package/lib/cjs/secrets/vault/VaultSecretService.cjs +2 -2
- package/lib/cjs/secrets/vault/VaultSecretServiceConfig.cjs +2 -2
- package/lib/cjs/secrets/vault/index.cjs +2 -2
- package/lib/cjs/shared/runtime.cjs +2 -2
- package/lib/cjs/utils.cjs +2 -2
- package/lib/esm/blob/azure/AzureBlobStoreService.js +1 -1
- package/lib/esm/blob/azure/index.js +1 -1
- package/lib/esm/blob/core/BlobErrors.js +1 -1
- package/lib/esm/blob/core/BlobKey.js +1 -1
- package/lib/esm/blob/core/BlobStoreFactory.js +1 -1
- package/lib/esm/blob/core/BlobStoreService.js +1 -1
- package/lib/esm/blob/core/BlobTypes.js +1 -1
- package/lib/esm/blob/core/BlobValue.js +1 -1
- package/lib/esm/blob/core/index.js +1 -1
- package/lib/esm/blob/gcp/GcsBlobStoreService.js +1 -1
- package/lib/esm/blob/gcp/index.js +1 -1
- package/lib/esm/blob/index.js +1 -1
- package/lib/esm/blob/ipfs/IpfsBlobStoreService.js +1 -1
- package/lib/esm/blob/ipfs/IpfsKeyIndex.js +1 -1
- package/lib/esm/blob/ipfs/LocalJsonIpfsKeyIndex.js +1 -1
- package/lib/esm/blob/ipfs/MemoryIpfsKeyIndex.js +1 -1
- package/lib/esm/blob/ipfs/PostgresIpfsKeyIndex.js +1 -1
- package/lib/esm/blob/ipfs/index.js +1 -1
- package/lib/esm/blob/local/LocalBlobStoreService.js +1 -1
- package/lib/esm/blob/local/index.js +1 -1
- package/lib/esm/blob/memory/MemoryBlobStoreService.js +1 -1
- package/lib/esm/blob/memory/index.js +1 -1
- package/lib/esm/blob/s3/MinioBlobStoreService.js +1 -1
- package/lib/esm/blob/s3/R2BlobStoreService.js +1 -1
- package/lib/esm/blob/s3/S3BlobStoreService.js +1 -1
- package/lib/esm/blob/s3/index.js +1 -1
- package/lib/esm/docker/DockerComposeService.js +1 -1
- package/lib/esm/docker/index.js +1 -1
- package/lib/esm/graph/engine/constants.js +1 -1
- package/lib/esm/graph/engine/decorators.js +1 -1
- package/lib/esm/graph/engine/errors/GraphCycleError.js +1 -1
- package/lib/esm/graph/engine/errors/GraphExecutionError.js +1 -1
- package/lib/esm/graph/engine/errors/GraphInputError.js +1 -1
- package/lib/esm/graph/engine/errors/GraphLoopLimitError.js +1 -1
- package/lib/esm/graph/engine/errors/GraphPinningError.js +1 -1
- package/lib/esm/graph/engine/errors/GraphPortError.js +1 -1
- package/lib/esm/graph/engine/errors/GraphStoreError.js +1 -1
- package/lib/esm/graph/engine/errors/GraphTopologyError.js +1 -1
- package/lib/esm/graph/engine/errors/index.js +1 -1
- package/lib/esm/graph/engine/events/GraphExecutionEvent.js +1 -1
- package/lib/esm/graph/engine/events/GraphExecutionEventEmitter.js +1 -1
- package/lib/esm/graph/engine/events/GraphExecutionEventFactory.js +1 -1
- package/lib/esm/graph/engine/events/GraphExecutionObserver.js +1 -1
- package/lib/esm/graph/engine/events/index.js +1 -1
- package/lib/esm/graph/engine/execution/CodeGraphNodeExecutor.js +27 -30
- package/lib/esm/graph/engine/execution/CodeSandboxEvaluator.js +1 -1
- package/lib/esm/graph/engine/execution/GraphExecutionContext.js +1 -1
- package/lib/esm/graph/engine/execution/GraphExecutionEngine.js +21 -2
- package/lib/esm/graph/engine/execution/GraphExecutionFrame.js +1 -1
- package/lib/esm/graph/engine/execution/GraphExecutionResult.js +1 -1
- package/lib/esm/graph/engine/execution/GraphNodeExecutor.js +1 -1
- package/lib/esm/graph/engine/execution/IsolatedVmCodeSandboxEvaluator.js +127 -1
- package/lib/esm/graph/engine/execution/LogGraphNodeExecutor.js +14 -0
- package/lib/esm/graph/engine/execution/SwitchGraphNodeExecutor.js +22 -5
- package/lib/esm/graph/engine/execution/index.js +2 -1
- package/lib/esm/graph/engine/index.js +2 -1
- package/lib/esm/graph/engine/loops/ConditionExpressionEvaluator.js +1 -1
- package/lib/esm/graph/engine/loops/ForeachGraphNodeExecutor.js +2 -1
- package/lib/esm/graph/engine/loops/GraphConditionEvaluator.js +1 -1
- package/lib/esm/graph/engine/loops/GraphLoopExecutionContext.js +1 -1
- package/lib/esm/graph/engine/loops/UntilGraphNodeExecutor.js +1 -1
- package/lib/esm/graph/engine/loops/WhileGraphNodeExecutor.js +1 -1
- package/lib/esm/graph/engine/loops/index.js +1 -1
- package/lib/esm/graph/engine/pinning/GraphPinningDependencyResolver.js +1 -1
- package/lib/esm/graph/engine/pinning/GraphPinningMetadata.js +1 -1
- package/lib/esm/graph/engine/pinning/GraphPinningPolicy.js +1 -1
- package/lib/esm/graph/engine/pinning/GraphPinningService.js +1 -1
- package/lib/esm/graph/engine/pinning/index.js +1 -1
- package/lib/esm/graph/engine/planning/GraphExecutionPlan.js +1 -1
- package/lib/esm/graph/engine/planning/GraphExecutionPlanEdge.js +1 -1
- package/lib/esm/graph/engine/planning/GraphExecutionPlanLayer.js +1 -1
- package/lib/esm/graph/engine/planning/GraphExecutionPlanNode.js +1 -1
- package/lib/esm/graph/engine/planning/GraphExecutionPlanner.js +1 -1
- package/lib/esm/graph/engine/planning/GraphRelationResolver.js +1 -1
- package/lib/esm/graph/engine/planning/GraphTopology.js +1 -1
- package/lib/esm/graph/engine/planning/index.js +1 -1
- package/lib/esm/graph/engine/registry/GraphNodeExecutorRegistry.js +1 -1
- package/lib/esm/graph/engine/registry/GraphNodeExecutorResolver.js +1 -1
- package/lib/esm/graph/engine/registry/index.js +1 -1
- package/lib/esm/graph/engine/snapshots/GraphExecutionSnapshotMapper.js +1 -1
- package/lib/esm/graph/engine/snapshots/index.js +1 -1
- package/lib/esm/graph/engine/store/GraphCachedValue.js +1 -1
- package/lib/esm/graph/engine/store/GraphValueKey.js +1 -1
- package/lib/esm/graph/engine/store/GraphValueStore.js +1 -1
- package/lib/esm/graph/engine/store/GraphValueStoreAdapter.js +1 -1
- package/lib/esm/graph/engine/store/InMemoryGraphValueStoreAdapter.js +1 -1
- package/lib/esm/graph/engine/store/index.js +1 -1
- package/lib/esm/graph/engine/types.js +1 -1
- package/lib/esm/graph/engine/validation/GraphDefinitionValidator.js +1 -1
- package/lib/esm/graph/engine/validation/GraphPortSchemaResolver.js +1 -1
- package/lib/esm/graph/engine/validation/GraphValueValidator.js +1 -1
- package/lib/esm/graph/engine/validation/index.js +1 -1
- package/lib/esm/graph/index.js +1 -1
- package/lib/esm/graph/shared/constants.js +1 -1
- package/lib/esm/graph/shared/index.js +1 -1
- package/lib/esm/graph/shared/nodes/agent.js +1 -1
- package/lib/esm/graph/shared/nodes/base.js +1 -1
- package/lib/esm/graph/shared/nodes/category-styles.js +1 -1
- package/lib/esm/graph/shared/nodes/flow-control.js +91 -10
- package/lib/esm/graph/shared/nodes/index.js +1 -1
- package/lib/esm/graph/shared/nodes/triggers.js +1 -1
- package/lib/esm/graph/shared/types.js +1 -1
- package/lib/esm/index.js +4 -4
- package/lib/esm/keycloak/index.js +1 -1
- package/lib/esm/keycloak/services/KeycloakAuthService.js +1 -1
- package/lib/esm/keycloak/services/KeycloakClientService.js +1 -1
- package/lib/esm/keycloak/services/KeycloakIdentityProviderService.js +1 -1
- package/lib/esm/keycloak/services/KeycloakRealmService.js +1 -1
- package/lib/esm/keycloak/services/KeycloakRoleService.js +1 -1
- package/lib/esm/keycloak/services/KeycloakService.js +1 -1
- package/lib/esm/keycloak/services/KeycloakUserService.js +1 -1
- package/lib/esm/keycloak/services/index.js +1 -1
- package/lib/esm/keycloak/services/runtime.js +1 -1
- package/lib/esm/keycloak/types.js +1 -1
- package/lib/esm/kibana/helpers.js +1 -1
- package/lib/esm/kibana/index.js +1 -1
- package/lib/esm/kibana/services/KibanaAuthService.js +1 -1
- package/lib/esm/kibana/services/KibanaDashboardService.js +1 -1
- package/lib/esm/kibana/services/KibanaDataViewService.js +1 -1
- package/lib/esm/kibana/services/KibanaRoleService.js +1 -1
- package/lib/esm/kibana/services/KibanaService.js +1 -1
- package/lib/esm/kibana/services/KibanaSpaceService.js +1 -1
- package/lib/esm/kibana/services/KibanaUserService.js +1 -1
- package/lib/esm/kibana/services/index.js +1 -1
- package/lib/esm/kibana/services/runtime.js +1 -1
- package/lib/esm/kibana/types.js +1 -1
- package/lib/esm/namespaces/index.js +1 -1
- package/lib/esm/namespaces/models/authorization-model.js +1 -1
- package/lib/esm/namespaces/models/effective-permission.model.js +1 -1
- package/lib/esm/namespaces/models/group-membership.model.js +1 -1
- package/lib/esm/namespaces/models/group.model.js +1 -1
- package/lib/esm/namespaces/models/index.js +1 -1
- package/lib/esm/namespaces/models/inheritance-block.model.js +1 -1
- package/lib/esm/namespaces/models/org-unit-closure.model.js +1 -1
- package/lib/esm/namespaces/models/org-unit-membership.model.js +1 -1
- package/lib/esm/namespaces/models/org-unit-profile.model.js +1 -1
- package/lib/esm/namespaces/models/org-unit.model.js +1 -1
- package/lib/esm/namespaces/models/permission.model.js +1 -1
- package/lib/esm/namespaces/models/principal.model.js +1 -1
- package/lib/esm/namespaces/models/protected-resource.model.js +1 -1
- package/lib/esm/namespaces/models/resource-grant.model.js +1 -1
- package/lib/esm/namespaces/models/role-assignment.model.js +1 -1
- package/lib/esm/namespaces/models/role-permission.model.js +1 -1
- package/lib/esm/namespaces/models/role.model.js +1 -1
- package/lib/esm/namespaces/models/storage-binding.model.js +1 -1
- package/lib/esm/namespaces/models/tenant-membership.model.js +1 -1
- package/lib/esm/namespaces/models/tenant-profile.model.js +1 -1
- package/lib/esm/namespaces/models/tenant.model.js +1 -1
- package/lib/esm/namespaces/models/user.model.js +1 -1
- package/lib/esm/namespaces/org-based-authorization-system.js +1 -1
- package/lib/esm/namespaces/org-based-authorization-system.models.js +1 -1
- package/lib/esm/namespaces/org-based-authorization-system.services.js +1 -1
- package/lib/esm/namespaces/services/authz.service.js +1 -1
- package/lib/esm/namespaces/services/bootstrap.service.js +1 -1
- package/lib/esm/namespaces/services/effective-permission.service.js +1 -1
- package/lib/esm/namespaces/services/group-membership.service.js +1 -1
- package/lib/esm/namespaces/services/group.service.js +1 -1
- package/lib/esm/namespaces/services/index.js +1 -1
- package/lib/esm/namespaces/services/inheritance-block.service.js +1 -1
- package/lib/esm/namespaces/services/org-unit-closure.service.js +1 -1
- package/lib/esm/namespaces/services/org-unit-membership.service.js +1 -1
- package/lib/esm/namespaces/services/org-unit-profile.service.js +1 -1
- package/lib/esm/namespaces/services/org-unit.service.js +1 -1
- package/lib/esm/namespaces/services/permission.service.js +1 -1
- package/lib/esm/namespaces/services/principal.service.js +1 -1
- package/lib/esm/namespaces/services/protected-resource.service.js +1 -1
- package/lib/esm/namespaces/services/resource-grant.service.js +1 -1
- package/lib/esm/namespaces/services/resource-lifecycle.service.js +1 -1
- package/lib/esm/namespaces/services/role-assignment.service.js +1 -1
- package/lib/esm/namespaces/services/role-permission.service.js +1 -1
- package/lib/esm/namespaces/services/role.service.js +1 -1
- package/lib/esm/namespaces/services/storage-binding.service.js +1 -1
- package/lib/esm/namespaces/services/system-management.service.js +1 -1
- package/lib/esm/namespaces/services/tenant-membership.service.js +1 -1
- package/lib/esm/namespaces/services/tenant-profile.service.js +1 -1
- package/lib/esm/namespaces/services/tenant.service.js +1 -1
- package/lib/esm/namespaces/services/user.service.js +1 -1
- package/lib/esm/namespaces/types.js +1 -1
- package/lib/esm/namespaces/utils.js +1 -1
- package/lib/esm/nest/authService.js +1 -1
- package/lib/esm/nest/graph/GraphExecutionController.js +40 -51
- package/lib/esm/nest/graph/GraphExecutionModule.js +12 -40
- package/lib/esm/nest/graph/GraphExecutionResultModel.js +1 -19
- package/lib/esm/nest/graph/GraphExecutorRegistryFactory.js +13 -48
- package/lib/esm/nest/graph/GraphResultService.js +45 -0
- package/lib/esm/nest/graph/GraphWorkflowModel.js +35 -0
- package/lib/esm/nest/graph/GraphWorkflowService.js +53 -0
- package/lib/esm/nest/graph/index.js +4 -7
- package/lib/esm/nest/graph/main.js +2 -2
- package/lib/esm/nest/index.js +1 -1
- package/lib/esm/nest/keycloakAuthHandler.js +1 -1
- package/lib/esm/nest/keycloakModule.js +1 -1
- package/lib/esm/nest/logging.js +1 -1
- package/lib/esm/nest/types.js +1 -1
- package/lib/esm/nest/utils.js +1 -1
- package/lib/esm/secrets/aws/AwsSecretService.js +1 -1
- package/lib/esm/secrets/aws/AwsSecretServiceConfig.js +1 -1
- package/lib/esm/secrets/aws/index.js +1 -1
- package/lib/esm/secrets/azure/AzureKeyVaultSecretService.js +1 -1
- package/lib/esm/secrets/azure/AzureKeyVaultSecretServiceConfig.js +1 -1
- package/lib/esm/secrets/azure/index.js +1 -1
- package/lib/esm/secrets/core/SecretErrors.js +1 -1
- package/lib/esm/secrets/core/SecretName.js +1 -1
- package/lib/esm/secrets/core/SecretReference.js +1 -1
- package/lib/esm/secrets/core/SecretSerialization.js +1 -1
- package/lib/esm/secrets/core/SecretService.js +1 -1
- package/lib/esm/secrets/core/SecretTypes.js +1 -1
- package/lib/esm/secrets/core/index.js +1 -1
- package/lib/esm/secrets/gcp/GcpSecretManagerService.js +1 -1
- package/lib/esm/secrets/gcp/GcpSecretManagerServiceConfig.js +1 -1
- package/lib/esm/secrets/gcp/index.js +1 -1
- package/lib/esm/secrets/index.js +1 -1
- package/lib/esm/secrets/model/ModelSecretCrypto.js +1 -1
- package/lib/esm/secrets/model/ModelSecretService.js +1 -1
- package/lib/esm/secrets/model/ModelSecretServiceConfig.js +1 -1
- package/lib/esm/secrets/model/Secret.js +1 -1
- package/lib/esm/secrets/model/index.js +1 -1
- package/lib/esm/secrets/onepassword/OnePasswordSecretService.js +1 -1
- package/lib/esm/secrets/onepassword/OnePasswordSecretServiceConfig.js +1 -1
- package/lib/esm/secrets/onepassword/index.js +1 -1
- package/lib/esm/secrets/vault/VaultSecretService.js +1 -1
- package/lib/esm/secrets/vault/VaultSecretServiceConfig.js +1 -1
- package/lib/esm/secrets/vault/index.js +1 -1
- package/lib/esm/shared/runtime.js +1 -1
- package/lib/esm/utils.js +1 -1
- package/lib/types/graph/engine/execution/CodeGraphNodeExecutor.d.cts +17 -17
- package/lib/types/graph/engine/execution/CodeGraphNodeExecutor.d.mts +17 -17
- package/lib/types/graph/engine/execution/CodeSandboxEvaluator.d.cts +23 -0
- package/lib/types/graph/engine/execution/CodeSandboxEvaluator.d.mts +23 -0
- package/lib/types/graph/engine/execution/GraphExecutionEngine.d.cts +6 -0
- package/lib/types/graph/engine/execution/GraphExecutionEngine.d.mts +6 -0
- package/lib/types/graph/engine/execution/IsolatedVmCodeSandboxEvaluator.d.cts +18 -0
- package/lib/types/graph/engine/execution/IsolatedVmCodeSandboxEvaluator.d.mts +18 -0
- package/lib/types/graph/engine/execution/LogGraphNodeExecutor.d.cts +19 -0
- package/lib/types/graph/engine/execution/LogGraphNodeExecutor.d.mts +19 -0
- package/lib/types/graph/engine/execution/SwitchGraphNodeExecutor.d.cts +3 -2
- package/lib/types/graph/engine/execution/SwitchGraphNodeExecutor.d.mts +3 -2
- package/lib/types/graph/engine/execution/index.d.cts +1 -0
- package/lib/types/graph/engine/execution/index.d.mts +1 -0
- package/lib/types/graph/engine/index.d.cts +1 -0
- package/lib/types/graph/engine/index.d.mts +1 -0
- package/lib/types/graph/shared/nodes/flow-control.d.cts +29 -3
- package/lib/types/graph/shared/nodes/flow-control.d.mts +29 -3
- package/lib/types/graph/shared/types.d.cts +6 -0
- package/lib/types/graph/shared/types.d.mts +6 -0
- package/lib/types/index.d.cts +2 -2
- package/lib/types/index.d.mts +2 -2
- package/lib/types/nest/graph/GraphExecutionController.d.cts +11 -42
- package/lib/types/nest/graph/GraphExecutionController.d.mts +11 -42
- package/lib/types/nest/graph/GraphExecutionModule.d.cts +9 -29
- package/lib/types/nest/graph/GraphExecutionModule.d.mts +9 -29
- package/lib/types/nest/graph/GraphExecutionResultModel.d.cts +0 -34
- package/lib/types/nest/graph/GraphExecutionResultModel.d.mts +0 -34
- package/lib/types/nest/graph/GraphExecutorRegistryFactory.d.cts +9 -9
- package/lib/types/nest/graph/GraphExecutorRegistryFactory.d.mts +9 -9
- package/lib/types/nest/graph/GraphResultService.d.cts +8 -0
- package/lib/types/nest/graph/GraphResultService.d.mts +8 -0
- package/lib/types/nest/graph/GraphWorkflowModel.d.cts +7 -0
- package/lib/types/nest/graph/GraphWorkflowModel.d.mts +7 -0
- package/lib/types/nest/graph/GraphWorkflowService.d.cts +7 -0
- package/lib/types/nest/graph/GraphWorkflowService.d.mts +7 -0
- package/lib/types/nest/graph/index.d.cts +3 -6
- package/lib/types/nest/graph/index.d.mts +3 -6
- package/package.json +1 -1
- package/dist/integrations.cjs.map +0 -1
- package/dist/integrations.js.map +0 -1
- package/lib/cjs/blob/azure/AzureBlobStoreService.cjs.map +0 -1
- package/lib/cjs/blob/azure/index.cjs.map +0 -1
- package/lib/cjs/blob/core/BlobErrors.cjs.map +0 -1
- package/lib/cjs/blob/core/BlobKey.cjs.map +0 -1
- package/lib/cjs/blob/core/BlobStoreFactory.cjs.map +0 -1
- package/lib/cjs/blob/core/BlobStoreService.cjs.map +0 -1
- package/lib/cjs/blob/core/BlobTypes.cjs.map +0 -1
- package/lib/cjs/blob/core/BlobValue.cjs.map +0 -1
- package/lib/cjs/blob/core/index.cjs.map +0 -1
- package/lib/cjs/blob/gcp/GcsBlobStoreService.cjs.map +0 -1
- package/lib/cjs/blob/gcp/index.cjs.map +0 -1
- package/lib/cjs/blob/index.cjs.map +0 -1
- package/lib/cjs/blob/ipfs/IpfsBlobStoreService.cjs.map +0 -1
- package/lib/cjs/blob/ipfs/IpfsKeyIndex.cjs.map +0 -1
- package/lib/cjs/blob/ipfs/LocalJsonIpfsKeyIndex.cjs.map +0 -1
- package/lib/cjs/blob/ipfs/MemoryIpfsKeyIndex.cjs.map +0 -1
- package/lib/cjs/blob/ipfs/PostgresIpfsKeyIndex.cjs.map +0 -1
- package/lib/cjs/blob/ipfs/index.cjs.map +0 -1
- package/lib/cjs/blob/local/LocalBlobStoreService.cjs.map +0 -1
- package/lib/cjs/blob/local/index.cjs.map +0 -1
- package/lib/cjs/blob/memory/MemoryBlobStoreService.cjs.map +0 -1
- package/lib/cjs/blob/memory/index.cjs.map +0 -1
- package/lib/cjs/blob/s3/MinioBlobStoreService.cjs.map +0 -1
- package/lib/cjs/blob/s3/R2BlobStoreService.cjs.map +0 -1
- package/lib/cjs/blob/s3/S3BlobStoreService.cjs.map +0 -1
- package/lib/cjs/blob/s3/index.cjs.map +0 -1
- package/lib/cjs/docker/DockerComposeService.cjs.map +0 -1
- package/lib/cjs/docker/index.cjs.map +0 -1
- package/lib/cjs/graph/engine/constants.cjs.map +0 -1
- package/lib/cjs/graph/engine/decorators.cjs.map +0 -1
- package/lib/cjs/graph/engine/errors/GraphCycleError.cjs.map +0 -1
- package/lib/cjs/graph/engine/errors/GraphExecutionError.cjs.map +0 -1
- package/lib/cjs/graph/engine/errors/GraphInputError.cjs.map +0 -1
- package/lib/cjs/graph/engine/errors/GraphLoopLimitError.cjs.map +0 -1
- package/lib/cjs/graph/engine/errors/GraphPinningError.cjs.map +0 -1
- package/lib/cjs/graph/engine/errors/GraphPortError.cjs.map +0 -1
- package/lib/cjs/graph/engine/errors/GraphStoreError.cjs.map +0 -1
- package/lib/cjs/graph/engine/errors/GraphTopologyError.cjs.map +0 -1
- package/lib/cjs/graph/engine/errors/index.cjs.map +0 -1
- package/lib/cjs/graph/engine/events/GraphExecutionEvent.cjs.map +0 -1
- package/lib/cjs/graph/engine/events/GraphExecutionEventEmitter.cjs.map +0 -1
- package/lib/cjs/graph/engine/events/GraphExecutionEventFactory.cjs.map +0 -1
- package/lib/cjs/graph/engine/events/GraphExecutionObserver.cjs.map +0 -1
- package/lib/cjs/graph/engine/events/index.cjs.map +0 -1
- package/lib/cjs/graph/engine/execution/CodeGraphNodeExecutor.cjs.map +0 -1
- package/lib/cjs/graph/engine/execution/CodeSandboxEvaluator.cjs.map +0 -1
- package/lib/cjs/graph/engine/execution/GraphExecutionContext.cjs.map +0 -1
- package/lib/cjs/graph/engine/execution/GraphExecutionEngine.cjs.map +0 -1
- package/lib/cjs/graph/engine/execution/GraphExecutionFrame.cjs.map +0 -1
- package/lib/cjs/graph/engine/execution/GraphExecutionResult.cjs.map +0 -1
- package/lib/cjs/graph/engine/execution/GraphNodeExecutor.cjs.map +0 -1
- package/lib/cjs/graph/engine/execution/IsolatedVmCodeSandboxEvaluator.cjs.map +0 -1
- package/lib/cjs/graph/engine/execution/SwitchGraphNodeExecutor.cjs.map +0 -1
- package/lib/cjs/graph/engine/execution/index.cjs.map +0 -1
- package/lib/cjs/graph/engine/index.cjs.map +0 -1
- package/lib/cjs/graph/engine/loops/ConditionExpressionEvaluator.cjs.map +0 -1
- package/lib/cjs/graph/engine/loops/ForeachGraphNodeExecutor.cjs.map +0 -1
- package/lib/cjs/graph/engine/loops/GraphConditionEvaluator.cjs.map +0 -1
- package/lib/cjs/graph/engine/loops/GraphLoopExecutionContext.cjs.map +0 -1
- package/lib/cjs/graph/engine/loops/UntilGraphNodeExecutor.cjs.map +0 -1
- package/lib/cjs/graph/engine/loops/WhileGraphNodeExecutor.cjs.map +0 -1
- package/lib/cjs/graph/engine/loops/index.cjs.map +0 -1
- package/lib/cjs/graph/engine/pinning/GraphPinningDependencyResolver.cjs.map +0 -1
- package/lib/cjs/graph/engine/pinning/GraphPinningMetadata.cjs.map +0 -1
- package/lib/cjs/graph/engine/pinning/GraphPinningPolicy.cjs.map +0 -1
- package/lib/cjs/graph/engine/pinning/GraphPinningService.cjs.map +0 -1
- package/lib/cjs/graph/engine/pinning/index.cjs.map +0 -1
- package/lib/cjs/graph/engine/planning/GraphExecutionPlan.cjs.map +0 -1
- package/lib/cjs/graph/engine/planning/GraphExecutionPlanEdge.cjs.map +0 -1
- package/lib/cjs/graph/engine/planning/GraphExecutionPlanLayer.cjs.map +0 -1
- package/lib/cjs/graph/engine/planning/GraphExecutionPlanNode.cjs.map +0 -1
- package/lib/cjs/graph/engine/planning/GraphExecutionPlanner.cjs.map +0 -1
- package/lib/cjs/graph/engine/planning/GraphRelationResolver.cjs.map +0 -1
- package/lib/cjs/graph/engine/planning/GraphTopology.cjs.map +0 -1
- package/lib/cjs/graph/engine/planning/index.cjs.map +0 -1
- package/lib/cjs/graph/engine/registry/GraphNodeExecutorRegistry.cjs.map +0 -1
- package/lib/cjs/graph/engine/registry/GraphNodeExecutorResolver.cjs.map +0 -1
- package/lib/cjs/graph/engine/registry/index.cjs.map +0 -1
- package/lib/cjs/graph/engine/snapshots/GraphExecutionSnapshotMapper.cjs.map +0 -1
- package/lib/cjs/graph/engine/snapshots/index.cjs.map +0 -1
- package/lib/cjs/graph/engine/store/GraphCachedValue.cjs.map +0 -1
- package/lib/cjs/graph/engine/store/GraphValueKey.cjs.map +0 -1
- package/lib/cjs/graph/engine/store/GraphValueStore.cjs.map +0 -1
- package/lib/cjs/graph/engine/store/GraphValueStoreAdapter.cjs.map +0 -1
- package/lib/cjs/graph/engine/store/InMemoryGraphValueStoreAdapter.cjs.map +0 -1
- package/lib/cjs/graph/engine/store/index.cjs.map +0 -1
- package/lib/cjs/graph/engine/types.cjs.map +0 -1
- package/lib/cjs/graph/engine/validation/GraphDefinitionValidator.cjs.map +0 -1
- package/lib/cjs/graph/engine/validation/GraphPortSchemaResolver.cjs.map +0 -1
- package/lib/cjs/graph/engine/validation/GraphValueValidator.cjs.map +0 -1
- package/lib/cjs/graph/engine/validation/index.cjs.map +0 -1
- package/lib/cjs/graph/index.cjs.map +0 -1
- package/lib/cjs/graph/shared/constants.cjs.map +0 -1
- package/lib/cjs/graph/shared/index.cjs.map +0 -1
- package/lib/cjs/graph/shared/nodes/agent.cjs.map +0 -1
- package/lib/cjs/graph/shared/nodes/base.cjs.map +0 -1
- package/lib/cjs/graph/shared/nodes/category-styles.cjs.map +0 -1
- package/lib/cjs/graph/shared/nodes/flow-control.cjs.map +0 -1
- package/lib/cjs/graph/shared/nodes/index.cjs.map +0 -1
- package/lib/cjs/graph/shared/nodes/triggers.cjs.map +0 -1
- package/lib/cjs/graph/shared/types.cjs.map +0 -1
- package/lib/cjs/index.cjs.map +0 -1
- package/lib/cjs/keycloak/index.cjs.map +0 -1
- package/lib/cjs/keycloak/services/KeycloakAuthService.cjs.map +0 -1
- package/lib/cjs/keycloak/services/KeycloakClientService.cjs.map +0 -1
- package/lib/cjs/keycloak/services/KeycloakIdentityProviderService.cjs.map +0 -1
- package/lib/cjs/keycloak/services/KeycloakRealmService.cjs.map +0 -1
- package/lib/cjs/keycloak/services/KeycloakRoleService.cjs.map +0 -1
- package/lib/cjs/keycloak/services/KeycloakService.cjs.map +0 -1
- package/lib/cjs/keycloak/services/KeycloakUserService.cjs.map +0 -1
- package/lib/cjs/keycloak/services/index.cjs.map +0 -1
- package/lib/cjs/keycloak/services/runtime.cjs.map +0 -1
- package/lib/cjs/keycloak/types.cjs.map +0 -1
- package/lib/cjs/kibana/helpers.cjs.map +0 -1
- package/lib/cjs/kibana/index.cjs.map +0 -1
- package/lib/cjs/kibana/services/KibanaAuthService.cjs.map +0 -1
- package/lib/cjs/kibana/services/KibanaDashboardService.cjs.map +0 -1
- package/lib/cjs/kibana/services/KibanaDataViewService.cjs.map +0 -1
- package/lib/cjs/kibana/services/KibanaRoleService.cjs.map +0 -1
- package/lib/cjs/kibana/services/KibanaService.cjs.map +0 -1
- package/lib/cjs/kibana/services/KibanaSpaceService.cjs.map +0 -1
- package/lib/cjs/kibana/services/KibanaUserService.cjs.map +0 -1
- package/lib/cjs/kibana/services/index.cjs.map +0 -1
- package/lib/cjs/kibana/services/runtime.cjs.map +0 -1
- package/lib/cjs/kibana/types.cjs.map +0 -1
- package/lib/cjs/namespaces/index.cjs.map +0 -1
- package/lib/cjs/namespaces/models/authorization-model.cjs.map +0 -1
- package/lib/cjs/namespaces/models/effective-permission.model.cjs.map +0 -1
- package/lib/cjs/namespaces/models/group-membership.model.cjs.map +0 -1
- package/lib/cjs/namespaces/models/group.model.cjs.map +0 -1
- package/lib/cjs/namespaces/models/index.cjs.map +0 -1
- package/lib/cjs/namespaces/models/inheritance-block.model.cjs.map +0 -1
- package/lib/cjs/namespaces/models/org-unit-closure.model.cjs.map +0 -1
- package/lib/cjs/namespaces/models/org-unit-membership.model.cjs.map +0 -1
- package/lib/cjs/namespaces/models/org-unit-profile.model.cjs.map +0 -1
- package/lib/cjs/namespaces/models/org-unit.model.cjs.map +0 -1
- package/lib/cjs/namespaces/models/permission.model.cjs.map +0 -1
- package/lib/cjs/namespaces/models/principal.model.cjs.map +0 -1
- package/lib/cjs/namespaces/models/protected-resource.model.cjs.map +0 -1
- package/lib/cjs/namespaces/models/resource-grant.model.cjs.map +0 -1
- package/lib/cjs/namespaces/models/role-assignment.model.cjs.map +0 -1
- package/lib/cjs/namespaces/models/role-permission.model.cjs.map +0 -1
- package/lib/cjs/namespaces/models/role.model.cjs.map +0 -1
- package/lib/cjs/namespaces/models/storage-binding.model.cjs.map +0 -1
- package/lib/cjs/namespaces/models/tenant-membership.model.cjs.map +0 -1
- package/lib/cjs/namespaces/models/tenant-profile.model.cjs.map +0 -1
- package/lib/cjs/namespaces/models/tenant.model.cjs.map +0 -1
- package/lib/cjs/namespaces/models/user.model.cjs.map +0 -1
- package/lib/cjs/namespaces/org-based-authorization-system.cjs.map +0 -1
- package/lib/cjs/namespaces/org-based-authorization-system.models.cjs.map +0 -1
- package/lib/cjs/namespaces/org-based-authorization-system.services.cjs.map +0 -1
- package/lib/cjs/namespaces/services/authz.service.cjs.map +0 -1
- package/lib/cjs/namespaces/services/bootstrap.service.cjs.map +0 -1
- package/lib/cjs/namespaces/services/effective-permission.service.cjs.map +0 -1
- package/lib/cjs/namespaces/services/group-membership.service.cjs.map +0 -1
- package/lib/cjs/namespaces/services/group.service.cjs.map +0 -1
- package/lib/cjs/namespaces/services/index.cjs.map +0 -1
- package/lib/cjs/namespaces/services/inheritance-block.service.cjs.map +0 -1
- package/lib/cjs/namespaces/services/org-unit-closure.service.cjs.map +0 -1
- package/lib/cjs/namespaces/services/org-unit-membership.service.cjs.map +0 -1
- package/lib/cjs/namespaces/services/org-unit-profile.service.cjs.map +0 -1
- package/lib/cjs/namespaces/services/org-unit.service.cjs.map +0 -1
- package/lib/cjs/namespaces/services/permission.service.cjs.map +0 -1
- package/lib/cjs/namespaces/services/principal.service.cjs.map +0 -1
- package/lib/cjs/namespaces/services/protected-resource.service.cjs.map +0 -1
- package/lib/cjs/namespaces/services/resource-grant.service.cjs.map +0 -1
- package/lib/cjs/namespaces/services/resource-lifecycle.service.cjs.map +0 -1
- package/lib/cjs/namespaces/services/role-assignment.service.cjs.map +0 -1
- package/lib/cjs/namespaces/services/role-permission.service.cjs.map +0 -1
- package/lib/cjs/namespaces/services/role.service.cjs.map +0 -1
- package/lib/cjs/namespaces/services/storage-binding.service.cjs.map +0 -1
- package/lib/cjs/namespaces/services/system-management.service.cjs.map +0 -1
- package/lib/cjs/namespaces/services/tenant-membership.service.cjs.map +0 -1
- package/lib/cjs/namespaces/services/tenant-profile.service.cjs.map +0 -1
- package/lib/cjs/namespaces/services/tenant.service.cjs.map +0 -1
- package/lib/cjs/namespaces/services/user.service.cjs.map +0 -1
- package/lib/cjs/namespaces/types.cjs.map +0 -1
- package/lib/cjs/namespaces/utils.cjs.map +0 -1
- package/lib/cjs/nest/authService.cjs.map +0 -1
- package/lib/cjs/nest/graph/GraphExecutionController.cjs.map +0 -1
- package/lib/cjs/nest/graph/GraphExecutionModule.cjs.map +0 -1
- package/lib/cjs/nest/graph/GraphExecutionResultModel.cjs.map +0 -1
- package/lib/cjs/nest/graph/GraphExecutionResultRepository.cjs +0 -66
- package/lib/cjs/nest/graph/GraphExecutionResultRepository.cjs.map +0 -1
- package/lib/cjs/nest/graph/GraphExecutorRegistryFactory.cjs.map +0 -1
- package/lib/cjs/nest/graph/index.cjs.map +0 -1
- package/lib/cjs/nest/graph/main.cjs.map +0 -1
- package/lib/cjs/nest/index.cjs.map +0 -1
- package/lib/cjs/nest/keycloakAuthHandler.cjs.map +0 -1
- package/lib/cjs/nest/keycloakModule.cjs.map +0 -1
- package/lib/cjs/nest/logging.cjs.map +0 -1
- package/lib/cjs/nest/types.cjs.map +0 -1
- package/lib/cjs/nest/utils.cjs.map +0 -1
- package/lib/cjs/secrets/aws/AwsSecretService.cjs.map +0 -1
- package/lib/cjs/secrets/aws/AwsSecretServiceConfig.cjs.map +0 -1
- package/lib/cjs/secrets/aws/index.cjs.map +0 -1
- package/lib/cjs/secrets/azure/AzureKeyVaultSecretService.cjs.map +0 -1
- package/lib/cjs/secrets/azure/AzureKeyVaultSecretServiceConfig.cjs.map +0 -1
- package/lib/cjs/secrets/azure/index.cjs.map +0 -1
- package/lib/cjs/secrets/core/SecretErrors.cjs.map +0 -1
- package/lib/cjs/secrets/core/SecretName.cjs.map +0 -1
- package/lib/cjs/secrets/core/SecretReference.cjs.map +0 -1
- package/lib/cjs/secrets/core/SecretSerialization.cjs.map +0 -1
- package/lib/cjs/secrets/core/SecretService.cjs.map +0 -1
- package/lib/cjs/secrets/core/SecretTypes.cjs.map +0 -1
- package/lib/cjs/secrets/core/index.cjs.map +0 -1
- package/lib/cjs/secrets/gcp/GcpSecretManagerService.cjs.map +0 -1
- package/lib/cjs/secrets/gcp/GcpSecretManagerServiceConfig.cjs.map +0 -1
- package/lib/cjs/secrets/gcp/index.cjs.map +0 -1
- package/lib/cjs/secrets/index.cjs.map +0 -1
- package/lib/cjs/secrets/model/ModelSecretCrypto.cjs.map +0 -1
- package/lib/cjs/secrets/model/ModelSecretService.cjs.map +0 -1
- package/lib/cjs/secrets/model/ModelSecretServiceConfig.cjs.map +0 -1
- package/lib/cjs/secrets/model/Secret.cjs.map +0 -1
- package/lib/cjs/secrets/model/index.cjs.map +0 -1
- package/lib/cjs/secrets/onepassword/OnePasswordSecretService.cjs.map +0 -1
- package/lib/cjs/secrets/onepassword/OnePasswordSecretServiceConfig.cjs.map +0 -1
- package/lib/cjs/secrets/onepassword/index.cjs.map +0 -1
- package/lib/cjs/secrets/vault/VaultSecretService.cjs.map +0 -1
- package/lib/cjs/secrets/vault/VaultSecretServiceConfig.cjs.map +0 -1
- package/lib/cjs/secrets/vault/index.cjs.map +0 -1
- package/lib/cjs/shared/runtime.cjs.map +0 -1
- package/lib/cjs/utils.cjs.map +0 -1
- package/lib/esm/blob/azure/AzureBlobStoreService.js.map +0 -1
- package/lib/esm/blob/azure/index.js.map +0 -1
- package/lib/esm/blob/core/BlobErrors.js.map +0 -1
- package/lib/esm/blob/core/BlobKey.js.map +0 -1
- package/lib/esm/blob/core/BlobStoreFactory.js.map +0 -1
- package/lib/esm/blob/core/BlobStoreService.js.map +0 -1
- package/lib/esm/blob/core/BlobTypes.js.map +0 -1
- package/lib/esm/blob/core/BlobValue.js.map +0 -1
- package/lib/esm/blob/core/index.js.map +0 -1
- package/lib/esm/blob/gcp/GcsBlobStoreService.js.map +0 -1
- package/lib/esm/blob/gcp/index.js.map +0 -1
- package/lib/esm/blob/index.js.map +0 -1
- package/lib/esm/blob/ipfs/IpfsBlobStoreService.js.map +0 -1
- package/lib/esm/blob/ipfs/IpfsKeyIndex.js.map +0 -1
- package/lib/esm/blob/ipfs/LocalJsonIpfsKeyIndex.js.map +0 -1
- package/lib/esm/blob/ipfs/MemoryIpfsKeyIndex.js.map +0 -1
- package/lib/esm/blob/ipfs/PostgresIpfsKeyIndex.js.map +0 -1
- package/lib/esm/blob/ipfs/index.js.map +0 -1
- package/lib/esm/blob/local/LocalBlobStoreService.js.map +0 -1
- package/lib/esm/blob/local/index.js.map +0 -1
- package/lib/esm/blob/memory/MemoryBlobStoreService.js.map +0 -1
- package/lib/esm/blob/memory/index.js.map +0 -1
- package/lib/esm/blob/s3/MinioBlobStoreService.js.map +0 -1
- package/lib/esm/blob/s3/R2BlobStoreService.js.map +0 -1
- package/lib/esm/blob/s3/S3BlobStoreService.js.map +0 -1
- package/lib/esm/blob/s3/index.js.map +0 -1
- package/lib/esm/docker/DockerComposeService.js.map +0 -1
- package/lib/esm/docker/index.js.map +0 -1
- package/lib/esm/graph/engine/constants.js.map +0 -1
- package/lib/esm/graph/engine/decorators.js.map +0 -1
- package/lib/esm/graph/engine/errors/GraphCycleError.js.map +0 -1
- package/lib/esm/graph/engine/errors/GraphExecutionError.js.map +0 -1
- package/lib/esm/graph/engine/errors/GraphInputError.js.map +0 -1
- package/lib/esm/graph/engine/errors/GraphLoopLimitError.js.map +0 -1
- package/lib/esm/graph/engine/errors/GraphPinningError.js.map +0 -1
- package/lib/esm/graph/engine/errors/GraphPortError.js.map +0 -1
- package/lib/esm/graph/engine/errors/GraphStoreError.js.map +0 -1
- package/lib/esm/graph/engine/errors/GraphTopologyError.js.map +0 -1
- package/lib/esm/graph/engine/errors/index.js.map +0 -1
- package/lib/esm/graph/engine/events/GraphExecutionEvent.js.map +0 -1
- package/lib/esm/graph/engine/events/GraphExecutionEventEmitter.js.map +0 -1
- package/lib/esm/graph/engine/events/GraphExecutionEventFactory.js.map +0 -1
- package/lib/esm/graph/engine/events/GraphExecutionObserver.js.map +0 -1
- package/lib/esm/graph/engine/events/index.js.map +0 -1
- package/lib/esm/graph/engine/execution/CodeGraphNodeExecutor.js.map +0 -1
- package/lib/esm/graph/engine/execution/CodeSandboxEvaluator.js.map +0 -1
- package/lib/esm/graph/engine/execution/GraphExecutionContext.js.map +0 -1
- package/lib/esm/graph/engine/execution/GraphExecutionEngine.js.map +0 -1
- package/lib/esm/graph/engine/execution/GraphExecutionFrame.js.map +0 -1
- package/lib/esm/graph/engine/execution/GraphExecutionResult.js.map +0 -1
- package/lib/esm/graph/engine/execution/GraphNodeExecutor.js.map +0 -1
- package/lib/esm/graph/engine/execution/IsolatedVmCodeSandboxEvaluator.js.map +0 -1
- package/lib/esm/graph/engine/execution/SwitchGraphNodeExecutor.js.map +0 -1
- package/lib/esm/graph/engine/execution/index.js.map +0 -1
- package/lib/esm/graph/engine/index.js.map +0 -1
- package/lib/esm/graph/engine/loops/ConditionExpressionEvaluator.js.map +0 -1
- package/lib/esm/graph/engine/loops/ForeachGraphNodeExecutor.js.map +0 -1
- package/lib/esm/graph/engine/loops/GraphConditionEvaluator.js.map +0 -1
- package/lib/esm/graph/engine/loops/GraphLoopExecutionContext.js.map +0 -1
- package/lib/esm/graph/engine/loops/UntilGraphNodeExecutor.js.map +0 -1
- package/lib/esm/graph/engine/loops/WhileGraphNodeExecutor.js.map +0 -1
- package/lib/esm/graph/engine/loops/index.js.map +0 -1
- package/lib/esm/graph/engine/pinning/GraphPinningDependencyResolver.js.map +0 -1
- package/lib/esm/graph/engine/pinning/GraphPinningMetadata.js.map +0 -1
- package/lib/esm/graph/engine/pinning/GraphPinningPolicy.js.map +0 -1
- package/lib/esm/graph/engine/pinning/GraphPinningService.js.map +0 -1
- package/lib/esm/graph/engine/pinning/index.js.map +0 -1
- package/lib/esm/graph/engine/planning/GraphExecutionPlan.js.map +0 -1
- package/lib/esm/graph/engine/planning/GraphExecutionPlanEdge.js.map +0 -1
- package/lib/esm/graph/engine/planning/GraphExecutionPlanLayer.js.map +0 -1
- package/lib/esm/graph/engine/planning/GraphExecutionPlanNode.js.map +0 -1
- package/lib/esm/graph/engine/planning/GraphExecutionPlanner.js.map +0 -1
- package/lib/esm/graph/engine/planning/GraphRelationResolver.js.map +0 -1
- package/lib/esm/graph/engine/planning/GraphTopology.js.map +0 -1
- package/lib/esm/graph/engine/planning/index.js.map +0 -1
- package/lib/esm/graph/engine/registry/GraphNodeExecutorRegistry.js.map +0 -1
- package/lib/esm/graph/engine/registry/GraphNodeExecutorResolver.js.map +0 -1
- package/lib/esm/graph/engine/registry/index.js.map +0 -1
- package/lib/esm/graph/engine/snapshots/GraphExecutionSnapshotMapper.js.map +0 -1
- package/lib/esm/graph/engine/snapshots/index.js.map +0 -1
- package/lib/esm/graph/engine/store/GraphCachedValue.js.map +0 -1
- package/lib/esm/graph/engine/store/GraphValueKey.js.map +0 -1
- package/lib/esm/graph/engine/store/GraphValueStore.js.map +0 -1
- package/lib/esm/graph/engine/store/GraphValueStoreAdapter.js.map +0 -1
- package/lib/esm/graph/engine/store/InMemoryGraphValueStoreAdapter.js.map +0 -1
- package/lib/esm/graph/engine/store/index.js.map +0 -1
- package/lib/esm/graph/engine/types.js.map +0 -1
- package/lib/esm/graph/engine/validation/GraphDefinitionValidator.js.map +0 -1
- package/lib/esm/graph/engine/validation/GraphPortSchemaResolver.js.map +0 -1
- package/lib/esm/graph/engine/validation/GraphValueValidator.js.map +0 -1
- package/lib/esm/graph/engine/validation/index.js.map +0 -1
- package/lib/esm/graph/index.js.map +0 -1
- package/lib/esm/graph/shared/constants.js.map +0 -1
- package/lib/esm/graph/shared/index.js.map +0 -1
- package/lib/esm/graph/shared/nodes/agent.js.map +0 -1
- package/lib/esm/graph/shared/nodes/base.js.map +0 -1
- package/lib/esm/graph/shared/nodes/category-styles.js.map +0 -1
- package/lib/esm/graph/shared/nodes/flow-control.js.map +0 -1
- package/lib/esm/graph/shared/nodes/index.js.map +0 -1
- package/lib/esm/graph/shared/nodes/triggers.js.map +0 -1
- package/lib/esm/graph/shared/types.js.map +0 -1
- package/lib/esm/index.js.map +0 -1
- package/lib/esm/keycloak/index.js.map +0 -1
- package/lib/esm/keycloak/services/KeycloakAuthService.js.map +0 -1
- package/lib/esm/keycloak/services/KeycloakClientService.js.map +0 -1
- package/lib/esm/keycloak/services/KeycloakIdentityProviderService.js.map +0 -1
- package/lib/esm/keycloak/services/KeycloakRealmService.js.map +0 -1
- package/lib/esm/keycloak/services/KeycloakRoleService.js.map +0 -1
- package/lib/esm/keycloak/services/KeycloakService.js.map +0 -1
- package/lib/esm/keycloak/services/KeycloakUserService.js.map +0 -1
- package/lib/esm/keycloak/services/index.js.map +0 -1
- package/lib/esm/keycloak/services/runtime.js.map +0 -1
- package/lib/esm/keycloak/types.js.map +0 -1
- package/lib/esm/kibana/helpers.js.map +0 -1
- package/lib/esm/kibana/index.js.map +0 -1
- package/lib/esm/kibana/services/KibanaAuthService.js.map +0 -1
- package/lib/esm/kibana/services/KibanaDashboardService.js.map +0 -1
- package/lib/esm/kibana/services/KibanaDataViewService.js.map +0 -1
- package/lib/esm/kibana/services/KibanaRoleService.js.map +0 -1
- package/lib/esm/kibana/services/KibanaService.js.map +0 -1
- package/lib/esm/kibana/services/KibanaSpaceService.js.map +0 -1
- package/lib/esm/kibana/services/KibanaUserService.js.map +0 -1
- package/lib/esm/kibana/services/index.js.map +0 -1
- package/lib/esm/kibana/services/runtime.js.map +0 -1
- package/lib/esm/kibana/types.js.map +0 -1
- package/lib/esm/namespaces/index.js.map +0 -1
- package/lib/esm/namespaces/models/authorization-model.js.map +0 -1
- package/lib/esm/namespaces/models/effective-permission.model.js.map +0 -1
- package/lib/esm/namespaces/models/group-membership.model.js.map +0 -1
- package/lib/esm/namespaces/models/group.model.js.map +0 -1
- package/lib/esm/namespaces/models/index.js.map +0 -1
- package/lib/esm/namespaces/models/inheritance-block.model.js.map +0 -1
- package/lib/esm/namespaces/models/org-unit-closure.model.js.map +0 -1
- package/lib/esm/namespaces/models/org-unit-membership.model.js.map +0 -1
- package/lib/esm/namespaces/models/org-unit-profile.model.js.map +0 -1
- package/lib/esm/namespaces/models/org-unit.model.js.map +0 -1
- package/lib/esm/namespaces/models/permission.model.js.map +0 -1
- package/lib/esm/namespaces/models/principal.model.js.map +0 -1
- package/lib/esm/namespaces/models/protected-resource.model.js.map +0 -1
- package/lib/esm/namespaces/models/resource-grant.model.js.map +0 -1
- package/lib/esm/namespaces/models/role-assignment.model.js.map +0 -1
- package/lib/esm/namespaces/models/role-permission.model.js.map +0 -1
- package/lib/esm/namespaces/models/role.model.js.map +0 -1
- package/lib/esm/namespaces/models/storage-binding.model.js.map +0 -1
- package/lib/esm/namespaces/models/tenant-membership.model.js.map +0 -1
- package/lib/esm/namespaces/models/tenant-profile.model.js.map +0 -1
- package/lib/esm/namespaces/models/tenant.model.js.map +0 -1
- package/lib/esm/namespaces/models/user.model.js.map +0 -1
- package/lib/esm/namespaces/org-based-authorization-system.js.map +0 -1
- package/lib/esm/namespaces/org-based-authorization-system.models.js.map +0 -1
- package/lib/esm/namespaces/org-based-authorization-system.services.js.map +0 -1
- package/lib/esm/namespaces/services/authz.service.js.map +0 -1
- package/lib/esm/namespaces/services/bootstrap.service.js.map +0 -1
- package/lib/esm/namespaces/services/effective-permission.service.js.map +0 -1
- package/lib/esm/namespaces/services/group-membership.service.js.map +0 -1
- package/lib/esm/namespaces/services/group.service.js.map +0 -1
- package/lib/esm/namespaces/services/index.js.map +0 -1
- package/lib/esm/namespaces/services/inheritance-block.service.js.map +0 -1
- package/lib/esm/namespaces/services/org-unit-closure.service.js.map +0 -1
- package/lib/esm/namespaces/services/org-unit-membership.service.js.map +0 -1
- package/lib/esm/namespaces/services/org-unit-profile.service.js.map +0 -1
- package/lib/esm/namespaces/services/org-unit.service.js.map +0 -1
- package/lib/esm/namespaces/services/permission.service.js.map +0 -1
- package/lib/esm/namespaces/services/principal.service.js.map +0 -1
- package/lib/esm/namespaces/services/protected-resource.service.js.map +0 -1
- package/lib/esm/namespaces/services/resource-grant.service.js.map +0 -1
- package/lib/esm/namespaces/services/resource-lifecycle.service.js.map +0 -1
- package/lib/esm/namespaces/services/role-assignment.service.js.map +0 -1
- package/lib/esm/namespaces/services/role-permission.service.js.map +0 -1
- package/lib/esm/namespaces/services/role.service.js.map +0 -1
- package/lib/esm/namespaces/services/storage-binding.service.js.map +0 -1
- package/lib/esm/namespaces/services/system-management.service.js.map +0 -1
- package/lib/esm/namespaces/services/tenant-membership.service.js.map +0 -1
- package/lib/esm/namespaces/services/tenant-profile.service.js.map +0 -1
- package/lib/esm/namespaces/services/tenant.service.js.map +0 -1
- package/lib/esm/namespaces/services/user.service.js.map +0 -1
- package/lib/esm/namespaces/types.js.map +0 -1
- package/lib/esm/namespaces/utils.js.map +0 -1
- package/lib/esm/nest/authService.js.map +0 -1
- package/lib/esm/nest/graph/GraphExecutionController.js.map +0 -1
- package/lib/esm/nest/graph/GraphExecutionModule.js.map +0 -1
- package/lib/esm/nest/graph/GraphExecutionResultModel.js.map +0 -1
- package/lib/esm/nest/graph/GraphExecutionResultRepository.js +0 -60
- package/lib/esm/nest/graph/GraphExecutionResultRepository.js.map +0 -1
- package/lib/esm/nest/graph/GraphExecutorRegistryFactory.js.map +0 -1
- package/lib/esm/nest/graph/index.js.map +0 -1
- package/lib/esm/nest/graph/main.js.map +0 -1
- package/lib/esm/nest/index.js.map +0 -1
- package/lib/esm/nest/keycloakAuthHandler.js.map +0 -1
- package/lib/esm/nest/keycloakModule.js.map +0 -1
- package/lib/esm/nest/logging.js.map +0 -1
- package/lib/esm/nest/types.js.map +0 -1
- package/lib/esm/nest/utils.js.map +0 -1
- package/lib/esm/secrets/aws/AwsSecretService.js.map +0 -1
- package/lib/esm/secrets/aws/AwsSecretServiceConfig.js.map +0 -1
- package/lib/esm/secrets/aws/index.js.map +0 -1
- package/lib/esm/secrets/azure/AzureKeyVaultSecretService.js.map +0 -1
- package/lib/esm/secrets/azure/AzureKeyVaultSecretServiceConfig.js.map +0 -1
- package/lib/esm/secrets/azure/index.js.map +0 -1
- package/lib/esm/secrets/core/SecretErrors.js.map +0 -1
- package/lib/esm/secrets/core/SecretName.js.map +0 -1
- package/lib/esm/secrets/core/SecretReference.js.map +0 -1
- package/lib/esm/secrets/core/SecretSerialization.js.map +0 -1
- package/lib/esm/secrets/core/SecretService.js.map +0 -1
- package/lib/esm/secrets/core/SecretTypes.js.map +0 -1
- package/lib/esm/secrets/core/index.js.map +0 -1
- package/lib/esm/secrets/gcp/GcpSecretManagerService.js.map +0 -1
- package/lib/esm/secrets/gcp/GcpSecretManagerServiceConfig.js.map +0 -1
- package/lib/esm/secrets/gcp/index.js.map +0 -1
- package/lib/esm/secrets/index.js.map +0 -1
- package/lib/esm/secrets/model/ModelSecretCrypto.js.map +0 -1
- package/lib/esm/secrets/model/ModelSecretService.js.map +0 -1
- package/lib/esm/secrets/model/ModelSecretServiceConfig.js.map +0 -1
- package/lib/esm/secrets/model/Secret.js.map +0 -1
- package/lib/esm/secrets/model/index.js.map +0 -1
- package/lib/esm/secrets/onepassword/OnePasswordSecretService.js.map +0 -1
- package/lib/esm/secrets/onepassword/OnePasswordSecretServiceConfig.js.map +0 -1
- package/lib/esm/secrets/onepassword/index.js.map +0 -1
- package/lib/esm/secrets/vault/VaultSecretService.js.map +0 -1
- package/lib/esm/secrets/vault/VaultSecretServiceConfig.js.map +0 -1
- package/lib/esm/secrets/vault/index.js.map +0 -1
- package/lib/esm/shared/runtime.js.map +0 -1
- package/lib/esm/utils.js.map +0 -1
- package/lib/types/nest/graph/GraphExecutionResultRepository.d.cts +0 -38
- package/lib/types/nest/graph/GraphExecutionResultRepository.d.mts +0 -38
package/dist/integrations.js
CHANGED
|
@@ -1,2 +1,1885 @@
|
|
|
1
|
-
import{exec as e}from"child_process";import{LogLevel as t}from"@decaf-ts/logging";import{InternalError as i}from"@decaf-ts/db-decorators";import{Cascade as n,ModelService as r,pk as s,uuid as o,manyToOne as a,column as p,createdAt as d,updatedAt as c,table as y,unique as l,oneToMany as g,transactional as u,AuthorizationError as m}from"@decaf-ts/core";export{AuthorizationError,transactional}from"@decaf-ts/core";import{Model as v,required as h,type as w,option as f,model as S}from"@decaf-ts/decorator-validation";import{__decorate as b,__metadata as O}from"tslib";async function A(n,r,s,o=t.info){return s.debug("Executing: "+n),new Promise((t,a)=>{const p=e(n,r),d=[],c=[];p.stdout?.on("data",e=>{d.push(e),s[o](e.trim())}),p.stderr?.on("data",e=>{c.push(e),s.debug(e.trim())}),p.on("close",e=>{0===e?(s.silly("Command completed successfully"),t({stdout:d.join("\n"),stderr:c.join("\n")})):(s.critical(`Command failed with code ${e}:\n ${c.join("\n")}`),a(new i(`Command failed with code ${e}: ${c.join("\n")}`)))}),p.on("error",e=>{s.critical("Command execution error",e),a(e)})})}var I,_,j,P,U,K,k,T;(e=>{e.Pooled="pooled",e.Bridge="bridge",e.Silo="silo"})(I||(I={})),(e=>{e.Invited="invited",e.Active="active",e.Suspended="suspended",e.Removed="removed"})(_||(_={})),(e=>{e.User="user",e.Group="group",e.ServiceAccount="service_account",e.Agent="agent",e.ApiKey="api_key"})(j||(j={})),(e=>{e.Tenant="tenant",e.OrgUnit="org_unit",e.Resource="resource"})(P||(P={})),(e=>{e.Admin="admin",e.ContentRead="content_read",e.ContentWrite="content_write",e.Memory="memory",e.Graph="graph",e.Vector="vector",e.Export="export",e.Billing="billing",e.Audit="audit",e.Security="security",e.Data="data",e.Automation="automation"})(U||(U={})),(e=>{e.Private="private",e.ResourceAcl="resource_acl",e.OrgUnit="org_unit",e.OrgSubtree="org_subtree",e.Tenant="tenant"})(K||(K={})),(e=>{e.Postgres="postgres",e.Arango="arango",e.Qdrant="qdrant",e.ObjectStorage="object_storage"})(k||(k={})),(e=>{e.Shared="shared",e.Dedicated="dedicated"})(T||(T={}));const x=Object.values(I),D=Object.values(_),F=Object.values(j),R=Object.values(P),B=Object.values(U),C=Object.values(K),G=Object.values(k),N=Object.values(T),E={update:n.NONE,delete:n.NONE,nullable:!1},$={update:n.NONE,delete:n.NONE,nullable:!0},L={update:n.CASCADE,delete:n.CASCADE,nullable:!1},M={update:n.CASCADE,delete:n.NONE,nullable:!1};function V(e){return{tenantId:e.tenantId,principalId:e.principalId,permissionKey:e.permissionKey,allowedOrgUnitIds:[...e.allowedOrgUnitIds],allowedResourceIds:[...e.allowedResourceIds]}}function W(e){return{must:[{key:"tenant_id",match:{value:e.tenantId}},{should:[{key:"org_unit_id",match:{any:e.allowedOrgUnitIds}},{key:"protected_resource_id",match:{any:e.allowedResourceIds}},{key:"owner_principal_id",match:{value:e.principalId}}]}]}}function q(e,t){return`${e}:${t}`}function z(){return new Date}function Q(e){return e??[]}function H(e,t){return ie(e)===t}function J(e,t){return!!t&&ie(e)===t}function X(e){return e.trim().toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")||"item"}function Y(e,t,i){const n=e??new Date;return!(t&&t>n||i&&n>i)}function Z(e){const t={},i={};for(const n of e.permissions){const e=q(n.scopeKind,n.scopeId);t[e]=t[e]??[],t[e].push(n.permissionKey),n.scopeKind===P.OrgUnit&&(i[n.permissionKey]=i[n.permissionKey]??[],i[n.permissionKey].push(n.scopeId))}return{tenantId:e.tenantId,principalId:e.principalId,permissionsByScope:t,allowedOrgUnitIdsByPermission:i,resourceGrants:e.grants.map(e=>({resourceId:e.resourceId,permissionKey:e.permissionKey}))}}class ee extends r{constructor(e){super(e)}newModel(e,t){return Object.assign(new e,t)}async create(e,...t){return this.repo.create(Object.assign({},e),...t)}async createOne(e,...t){return this.create(e,...t)}async getById(e,...t){return this.repo.read(e,...t)}async updateOne(e,t,...i){const n=await this.repo.read(e,...i);return this.repo.update(Object.assign(n,t),...i)}async deleteById(e,...t){await this.repo.delete(e,...t)}async findOneBy(e,t,...i){return this.repo.findOneBy(e,t,...i)}async findManyBy(e,t,...i){return this.repo.select().where({[e]:t}).execute(...i)}async listAll(...e){return this.repo.select().execute(...e)}}function te(){return crypto.randomUUID()}function ie(e){return"string"==typeof e?e:e.id}class ne extends v{constructor(e){super(e)}}let re=class extends ne{constructor(e){super(e)}};b([s({type:String}),o(),O("design:type",String)],re.prototype,"id",void 0),b([a(()=>we,L,!1,void 0,"fk_tenant_memberships_tenant"),h(),O("design:type",Object)],re.prototype,"tenant",void 0),b([a(()=>se,L,!1,void 0,"fk_tenant_memberships_user"),h(),O("design:type",Object)],re.prototype,"user",void 0),b([h(),w(String),f(D),p(),O("design:type",String)],re.prototype,"status",void 0),b([d(),O("design:type",Date)],re.prototype,"createdAt",void 0),b([c(),O("design:type",Date)],re.prototype,"updatedAt",void 0),re=b([y("tenant_memberships"),S(),O("design:paramtypes",[Object])],re);let se=class extends ne{constructor(e){super(e)}};b([s({type:String}),o(),O("design:type",String)],se.prototype,"id",void 0),b([l(),w(String),p(),O("design:type",String)],se.prototype,"email",void 0),b([l(),w(String),p(),O("design:type",String)],se.prototype,"phone",void 0),b([h(),w(String),p(),O("design:type",String)],se.prototype,"displayName",void 0),b([g(()=>re,E,!1),O("design:type",Array)],se.prototype,"tenantMemberships",void 0),b([g(()=>oe,E,!1),O("design:type",Array)],se.prototype,"orgUnitMemberships",void 0),b([d(),O("design:type",Date)],se.prototype,"createdAt",void 0),b([c(),O("design:type",Date)],se.prototype,"updatedAt",void 0),se=b([y("users"),S(),O("design:paramtypes",[Object])],se);let oe=class extends ne{constructor(e){super(e)}};b([s({type:String}),o(),O("design:type",String)],oe.prototype,"id",void 0),b([a(()=>we,L,!1,void 0,"fk_org_memberships_tenant"),h(),O("design:type",Object)],oe.prototype,"tenant",void 0),b([a(()=>ve,L,!1,void 0,"fk_org_memberships_org_unit"),h(),O("design:type",Object)],oe.prototype,"orgUnit",void 0),b([a(()=>se,E,!1,void 0,"fk_org_memberships_user"),h(),O("design:type",Object)],oe.prototype,"user",void 0),b([h(),w(String),f(D),p(),O("design:type",String)],oe.prototype,"status",void 0),b([d(),O("design:type",Date)],oe.prototype,"createdAt",void 0),b([c(),O("design:type",Date)],oe.prototype,"updatedAt",void 0),oe=b([y("org_unit_memberships"),S(),O("design:paramtypes",[Object])],oe);let ae=class extends ne{constructor(e){super(e)}};b([s({type:String}),o(),O("design:type",String)],ae.prototype,"id",void 0),b([a(()=>we,L,!1,void 0,"fk_org_closure_tenant"),h(),O("design:type",Object)],ae.prototype,"tenant",void 0),b([a(()=>ve,L,!1,void 0,"fk_org_closure_ancestor"),h(),O("design:type",Object)],ae.prototype,"ancestor",void 0),b([a(()=>ve,L,!1,void 0,"fk_org_closure_descendant"),h(),O("design:type",Object)],ae.prototype,"descendant",void 0),b([h(),w(Number),p(),O("design:type",Number)],ae.prototype,"depth",void 0),b([d(),O("design:type",Date)],ae.prototype,"createdAt",void 0),ae=b([y("org_unit_closure"),S(),O("design:paramtypes",[Object])],ae);let pe=class extends ne{constructor(e){super(e)}};b([s({type:String}),o(),O("design:type",String)],pe.prototype,"id",void 0),b([l(),h(),w(String),p(),O("design:type",String)],pe.prototype,"key",void 0),b([h(),w(String),f(B),p(),O("design:type",String)],pe.prototype,"category",void 0),b([w(String),p(),O("design:type",String)],pe.prototype,"description",void 0),b([g(()=>de,E,!1),O("design:type",Array)],pe.prototype,"rolePermissions",void 0),pe=b([y("permissions"),S(),O("design:paramtypes",[Object])],pe);let de=class extends ne{constructor(e){super(e)}};b([s({type:String}),o(),O("design:type",String)],de.prototype,"id",void 0),b([a(()=>ce,L,!1,void 0,"fk_role_permissions_role"),h(),O("design:type",Object)],de.prototype,"role",void 0),b([a(()=>pe,L,!1,void 0,"fk_role_permissions_permission"),h(),O("design:type",Object)],de.prototype,"permission",void 0),b([d(),O("design:type",Date)],de.prototype,"createdAt",void 0),de=b([y("role_permissions"),S(),O("design:paramtypes",[Object])],de);let ce=class extends ne{constructor(e){super(e)}};b([s({type:String}),o(),O("design:type",String)],ce.prototype,"id",void 0),b([a(()=>we,$,!1,void 0,"fk_roles_tenant"),O("design:type",Object)],ce.prototype,"tenant",void 0),b([h(),w(String),p(),O("design:type",String)],ce.prototype,"key",void 0),b([h(),w(String),p(),O("design:type",String)],ce.prototype,"name",void 0),b([w(String),p(),O("design:type",String)],ce.prototype,"description",void 0),b([w(Object),p(),O("design:type",Object)],ce.prototype,"metadata",void 0),b([g(()=>de,E,!1),O("design:type",Array)],ce.prototype,"rolePermissions",void 0),b([g(()=>ye,E,!1),O("design:type",Array)],ce.prototype,"assignments",void 0),b([d(),O("design:type",Date)],ce.prototype,"createdAt",void 0),b([c(),O("design:type",Date)],ce.prototype,"updatedAt",void 0),ce=b([y("roles"),S(),O("design:paramtypes",[Object])],ce);let ye=class extends ne{constructor(e){super(e)}};b([s({type:String}),o(),O("design:type",String)],ye.prototype,"id",void 0),b([a(()=>we,L,!1,void 0,"fk_role_assignments_tenant"),h(),O("design:type",Object)],ye.prototype,"tenant",void 0),b([a(()=>ge,L,!1,void 0,"fk_role_assignments_principal"),h(),O("design:type",Object)],ye.prototype,"principal",void 0),b([a(()=>ce,E,!1,void 0,"fk_role_assignments_role"),h(),O("design:type",Object)],ye.prototype,"role",void 0),b([h(),w(String),f(R),p(),O("design:type",String)],ye.prototype,"scopeKind",void 0),b([h(),w(String),p(),O("design:type",String)],ye.prototype,"scopeId",void 0),b([h(),w(Boolean),p(),O("design:type",Boolean)],ye.prototype,"inheritDown",void 0),b([p(),O("design:type",Date)],ye.prototype,"startsAt",void 0),b([p(),O("design:type",Date)],ye.prototype,"expiresAt",void 0),b([w(Object),p(),O("design:type",Object)],ye.prototype,"conditions",void 0),b([d(),O("design:type",Date)],ye.prototype,"createdAt",void 0),b([c(),O("design:type",Date)],ye.prototype,"updatedAt",void 0),ye=b([y("role_assignments"),S(),O("design:paramtypes",[Object])],ye);let le=class extends ne{constructor(e){super(e)}};b([s({type:String}),o(),O("design:type",String)],le.prototype,"id",void 0),b([a(()=>we,L,!1,void 0,"fk_resource_grants_tenant"),h(),O("design:type",Object)],le.prototype,"tenant",void 0),b([a(()=>ue,L,!1,void 0,"fk_resource_grants_resource"),h(),O("design:type",Object)],le.prototype,"resource",void 0),b([a(()=>ge,L,!1,void 0,"fk_resource_grants_principal"),h(),O("design:type",Object)],le.prototype,"principal",void 0),b([h(),w(String),p(),O("design:type",String)],le.prototype,"permissionKey",void 0),b([p(),O("design:type",Date)],le.prototype,"startsAt",void 0),b([p(),O("design:type",Date)],le.prototype,"expiresAt",void 0),b([w(Object),p(),O("design:type",Object)],le.prototype,"conditions",void 0),b([a(()=>ge,E,!1,void 0,"fk_resource_grants_created_by"),O("design:type",Object)],le.prototype,"createdBy",void 0),b([d(),O("design:type",Date)],le.prototype,"createdAt",void 0),b([c(),O("design:type",Date)],le.prototype,"updatedAt",void 0),le=b([y("resource_grants"),S(),O("design:paramtypes",[Object])],le);let ge=class extends ne{constructor(e){super(e)}};b([s({type:String}),o(),O("design:type",String)],ge.prototype,"id",void 0),b([a(()=>we,E,!1,void 0,"fk_principals_tenant"),h(),O("design:type",Object)],ge.prototype,"tenant",void 0),b([h(),w(String),f(F),p(),O("design:type",String)],ge.prototype,"kind",void 0),b([h(),w(String),p(),O("design:type",String)],ge.prototype,"subjectId",void 0),b([g(()=>ye,E,!1),O("design:type",Array)],ge.prototype,"roleAssignments",void 0),b([g(()=>le,E,!1),O("design:type",Array)],ge.prototype,"resourceGrants",void 0),b([d(),O("design:type",Date)],ge.prototype,"createdAt",void 0),b([c(),O("design:type",Date)],ge.prototype,"updatedAt",void 0),ge=b([y("principals"),S(),O("design:paramtypes",[Object])],ge);let ue=class extends ne{constructor(e){super(e)}};b([s({type:String}),o(),O("design:type",String)],ue.prototype,"id",void 0),b([a(()=>we,E,!1,void 0,"fk_protected_resources_tenant"),h(),O("design:type",Object)],ue.prototype,"tenant",void 0),b([a(()=>ve,E,!1,void 0,"fk_protected_resources_org_unit"),h(),O("design:type",Object)],ue.prototype,"orgUnit",void 0),b([h(),w(String),p(),O("design:type",String)],ue.prototype,"resourceType",void 0),b([h(),w(String),p(),O("design:type",String)],ue.prototype,"resourceId",void 0),b([h(),w(String),f(C),p(),O("design:type",String)],ue.prototype,"visibility",void 0),b([a(()=>ge,$,!1,void 0,"fk_protected_resources_owner"),O("design:type",Object)],ue.prototype,"owner",void 0),b([w(String),p(),O("design:type",String)],ue.prototype,"sensitivity",void 0),b([w(Object),p(),O("design:type",Object)],ue.prototype,"metadata",void 0),b([g(()=>le,E,!1),O("design:type",Array)],ue.prototype,"grants",void 0),b([d(),O("design:type",Date)],ue.prototype,"createdAt",void 0),b([c(),O("design:type",Date)],ue.prototype,"updatedAt",void 0),ue=b([y("protected_resources"),S(),O("design:paramtypes",[Object])],ue);let me=class extends ne{constructor(e){super(e)}};b([s({type:String}),o(),O("design:type",String)],me.prototype,"id",void 0),b([a(()=>we,L,!1,void 0,"fk_inheritance_blocks_tenant"),h(),O("design:type",Object)],me.prototype,"tenant",void 0),b([a(()=>ve,L,!1,void 0,"fk_inheritance_blocks_org_unit"),h(),O("design:type",Object)],me.prototype,"orgUnit",void 0),b([a(()=>ve,$,!1,void 0,"fk_inheritance_blocks_blocked_ancestor"),O("design:type",Object)],me.prototype,"blockedFromAncestor",void 0),b([h(),w(String),f(B),p(),O("design:type",String)],me.prototype,"permissionCategory",void 0),b([w(String),p(),O("design:type",String)],me.prototype,"reason",void 0),b([d(),O("design:type",Date)],me.prototype,"createdAt",void 0),b([c(),O("design:type",Date)],me.prototype,"updatedAt",void 0),me=b([y("inheritance_blocks"),S(),O("design:paramtypes",[Object])],me);let ve=class extends ne{constructor(e){super(e)}};b([s({type:String}),o(),O("design:type",String)],ve.prototype,"id",void 0),b([a(()=>we,E,!1,void 0,"fk_org_units_tenant"),h(),O("design:type",Object)],ve.prototype,"tenant",void 0),b([a(()=>ve,E,!1,void 0,"fk_org_units_parent"),O("design:type",Object)],ve.prototype,"parent",void 0),b([g(()=>ve,E,!1),O("design:type",Array)],ve.prototype,"children",void 0),b([h(),w(String),p(),O("design:type",String)],ve.prototype,"name",void 0),b([h(),w(String),p(),O("design:type",String)],ve.prototype,"path",void 0),b([w(Object),p(),O("design:type",Object)],ve.prototype,"metadata",void 0),b([g(()=>oe,E,!1),O("design:type",Array)],ve.prototype,"memberships",void 0),b([g(()=>ue,E,!1),O("design:type",Array)],ve.prototype,"resources",void 0),b([g(()=>me,E,!1),O("design:type",Array)],ve.prototype,"inheritanceBlocks",void 0),b([g(()=>ae,E,!1),O("design:type",Array)],ve.prototype,"ancestorLinks",void 0),b([g(()=>ae,E,!1),O("design:type",Array)],ve.prototype,"descendantLinks",void 0),b([d(),O("design:type",Date)],ve.prototype,"createdAt",void 0),b([c(),O("design:type",Date)],ve.prototype,"updatedAt",void 0),ve=b([y("org_units"),S(),O("design:paramtypes",[Object])],ve);let he=class extends ne{constructor(e){super(e)}};b([s({type:String}),o(),O("design:type",String)],he.prototype,"id",void 0),b([a(()=>we,L,!1,void 0,"fk_storage_bindings_tenant"),h(),O("design:type",Object)],he.prototype,"tenant",void 0),b([h(),w(String),f(G),p(),O("design:type",String)],he.prototype,"storageKind",void 0),b([h(),w(String),f(N),p(),O("design:type",String)],he.prototype,"bindingKind",void 0),b([h(),w(String),p(),O("design:type",String)],he.prototype,"bindingKey",void 0),b([h(),w(String),p(),O("design:type",String)],he.prototype,"region",void 0),b([w(Object),p(),O("design:type",Object)],he.prototype,"config",void 0),b([d(),O("design:type",Date)],he.prototype,"createdAt",void 0),b([c(),O("design:type",Date)],he.prototype,"updatedAt",void 0),he=b([y("storage_bindings"),S(),O("design:paramtypes",[Object])],he);let we=class extends ne{constructor(e){super(e)}};b([s({type:String}),o(),O("design:type",String)],we.prototype,"id",void 0),b([l(),h(),w(String),p(),O("design:type",String)],we.prototype,"slug",void 0),b([h(),w(String),p(),O("design:type",String)],we.prototype,"name",void 0),b([h(),w(String),f(x),p(),O("design:type",String)],we.prototype,"isolationTier",void 0),b([g(()=>ve,E,!1),O("design:type",Array)],we.prototype,"orgUnits",void 0),b([g(()=>re,E,!1),O("design:type",Array)],we.prototype,"memberships",void 0),b([g(()=>ge,E,!1),O("design:type",Array)],we.prototype,"principals",void 0),b([g(()=>he,E,!1),O("design:type",Array)],we.prototype,"storageBindings",void 0),b([d(),O("design:type",Date)],we.prototype,"createdAt",void 0),b([c(),O("design:type",Date)],we.prototype,"updatedAt",void 0),we=b([y("tenants"),S(),O("design:paramtypes",[Object])],we);let fe=class extends ne{constructor(e){super(e)}};b([s({type:String}),o(),O("design:type",String)],fe.prototype,"id",void 0),b([a(()=>we,L,!1,void 0,"fk_tenant_profiles_tenant"),h(),O("design:type",Object)],fe.prototype,"tenant",void 0),b([h(),w(String),p(),O("design:type",String)],fe.prototype,"profileKey",void 0),b([w(Object),p(),O("design:type",Object)],fe.prototype,"metadata",void 0),b([d(),O("design:type",Date)],fe.prototype,"createdAt",void 0),b([c(),O("design:type",Date)],fe.prototype,"updatedAt",void 0),fe=b([y("tenant_profiles"),S(),O("design:paramtypes",[Object])],fe);let Se=class extends ne{constructor(e){super(e)}};b([s({type:String}),o(),O("design:type",String)],Se.prototype,"id",void 0),b([a(()=>ve,L,!1,void 0,"fk_org_unit_profiles_org_unit"),h(),O("design:type",Object)],Se.prototype,"orgUnit",void 0),b([h(),w(String),p(),O("design:type",String)],Se.prototype,"profileKey",void 0),b([w(Object),p(),O("design:type",Object)],Se.prototype,"metadata",void 0),b([d(),O("design:type",Date)],Se.prototype,"createdAt",void 0),b([c(),O("design:type",Date)],Se.prototype,"updatedAt",void 0),Se=b([y("org_unit_profiles"),S(),O("design:paramtypes",[Object])],Se);let be=class extends ne{constructor(e){super(e)}};b([s({type:String}),o(),O("design:type",String)],be.prototype,"id",void 0),b([a(()=>we,L,!1,void 0,"fk_group_memberships_tenant"),h(),O("design:type",Object)],be.prototype,"tenant",void 0),b([a(()=>Oe,L,!1,void 0,"fk_group_memberships_group"),h(),O("design:type",Object)],be.prototype,"group",void 0),b([a(()=>ge,L,!1,void 0,"fk_group_memberships_principal"),h(),O("design:type",Object)],be.prototype,"principal",void 0),b([w(Object),p(),O("design:type",Object)],be.prototype,"metadata",void 0),b([d(),O("design:type",Date)],be.prototype,"createdAt",void 0),be=b([y("group_memberships"),S(),O("design:paramtypes",[Object])],be);let Oe=class extends ne{constructor(e){super(e)}};b([s({type:String}),o(),O("design:type",String)],Oe.prototype,"id",void 0),b([a(()=>we,E,!1,void 0,"fk_groups_tenant"),h(),O("design:type",Object)],Oe.prototype,"tenant",void 0),b([a(()=>ve,$,!1,void 0,"fk_groups_org_unit"),O("design:type",Object)],Oe.prototype,"orgUnit",void 0),b([h(),w(String),p(),O("design:type",String)],Oe.prototype,"name",void 0),b([w(Object),p(),O("design:type",Object)],Oe.prototype,"metadata",void 0),b([g(()=>be,E,!1),O("design:type",Array)],Oe.prototype,"members",void 0),b([d(),O("design:type",Date)],Oe.prototype,"createdAt",void 0),b([c(),O("design:type",Date)],Oe.prototype,"updatedAt",void 0),Oe=b([y("groups"),S(),O("design:paramtypes",[Object])],Oe);let Ae=class extends ne{constructor(e){super(e)}};b([s({type:String}),o(),O("design:type",String)],Ae.prototype,"id",void 0),b([a(()=>we,L,!1,void 0,"fk_effective_permissions_tenant"),h(),O("design:type",Object)],Ae.prototype,"tenant",void 0),b([a(()=>ge,L,!1,void 0,"fk_effective_permissions_principal"),h(),O("design:type",Object)],Ae.prototype,"principal",void 0),b([h(),w(String),p(),O("design:type",String)],Ae.prototype,"permissionKey",void 0),b([h(),w(String),f(R),p(),O("design:type",String)],Ae.prototype,"scopeKind",void 0),b([h(),w(String),p(),O("design:type",String)],Ae.prototype,"scopeId",void 0),b([h(),w(String),p(),O("design:type",String)],Ae.prototype,"sourceKind",void 0),b([h(),w(String),p(),O("design:type",String)],Ae.prototype,"sourceId",void 0),b([p(),O("design:type",Date)],Ae.prototype,"startsAt",void 0),b([p(),O("design:type",Date)],Ae.prototype,"expiresAt",void 0),b([d(),O("design:type",Date)],Ae.prototype,"createdAt",void 0),Ae=b([y("effective_permissions"),S(),O("design:paramtypes",[Object])],Ae);class Ie extends ee{constructor(){super(fe)}async createProfile(e,t,i,...n){return this.create({tenant:e,profileKey:t,metadata:i},...n)}async listForTenant(e,...t){return(await this.listAll(...t)).filter(t=>H(t.tenant,e))}async deleteForTenant(e,...t){for(const i of await this.listForTenant(e,...t))await this.deleteById(i.id,...t)}}class _e extends ee{constructor(){super(Se)}async createProfile(e,t,i,...n){return this.create({orgUnit:e,profileKey:t,metadata:i},...n)}async listForOrgUnit(e,...t){return(await this.listAll(...t)).filter(t=>J(t.orgUnit,e))}}class je extends ee{constructor(){super(ae)}async listAncestors(e,t,...i){return(await this.listAll(...i)).filter(i=>H(i.tenant,e)&&J(i.descendant,t)).sort((e,t)=>e.depth-t.depth)}async listDescendants(e,t,...i){return(await this.listAll(...i)).filter(i=>H(i.tenant,e)&&J(i.ancestor,t)).sort((e,t)=>e.depth-t.depth)}async isAncestorOf(e,t,i,...n){return(await this.listAncestors(e,i,...n)).some(e=>J(e.ancestor,t))}async createSelfLink(e,t,...i){return this.create({tenant:e,ancestor:t,descendant:t,depth:0},...i)}async insertAncestorLinksForNewChild(e,t,i,...n){const r=await this.listAncestors(e,t,...n);for(const t of r)await this.create({tenant:e,ancestor:t.ancestor,descendant:i,depth:t.depth+1},...n)}async deleteLinksForSubtree(e,t,...i){const n=await this.listDescendants(e,t,...i),r=new Set([t,...n.map(e=>ie(e.descendant))]),s=new Set([t,...n.map(e=>ie(e.ancestor))]),o=(await this.listAll(...i)).filter(t=>H(t.tenant,e)&&(r.has(ie(t.descendant))||s.has(ie(t.ancestor))));for(const e of o)await this.deleteById(e.id,...i)}}class Pe extends ee{constructor(){super(me)}async blockCategory(e,t,i,n,r,...s){return this.create({tenant:e,orgUnit:t,blockedFromAncestor:n,permissionCategory:i,reason:r},...s)}async unblockCategory(e,...t){await this.deleteById(e,...t)}async listForOrgUnit(e,t,...i){return(await this.listAll(...i)).filter(i=>H(i.tenant,e)&&J(i.orgUnit,t))}async categoryBlockedForAncestor(e,t,i,n,...r){return(await this.listForOrgUnit(e,t,...r)).some(e=>e.permissionCategory===n&&(!e.blockedFromAncestor||J(e.blockedFromAncestor,i)))}}class Ue extends ee{constructor(){super(we)}async createTenant(e,...t){return this.create({slug:e.slug,name:e.name,isolationTier:e.isolationTier??I.Pooled},...t)}async getBySlug(e,...t){return this.findOneBy("slug",e,...t)}async renameTenant(e,t,...i){return this.updateOne(e,{name:t},...i)}async changeSlug(e,t,...i){return this.updateOne(e,{slug:t},...i)}async setIsolationTier(e,t,...i){return this.updateOne(e,{isolationTier:t},...i)}async deleteTenantControlled(e,...t){await this.deleteById(e,...t)}}async function Ke(e,t,...i){for(const n of t)await e.deleteById(n.id,...i)}class ke extends ee{constructor(){super(ve)}orgUnitPath(e,t){const i=X(t);return e?`${e.replace(/\/+$/,"")}/${i}`:"/"+i}async createProfileIfNeeded(e,t,i,...n){t&&await(new _e).createProfile(e,t,i,...n)}async createRoot(e,t,i,n,r,...s){const o=await this.create({tenant:e,name:t,path:this.orgUnitPath(void 0,t),metadata:i},...s);return await this.createProfileIfNeeded(o.id,n,r,...s),await(new je).createSelfLink(e,o.id,...s),o}async createChild(e,...t){const i=e.parentOrgUnitId?await this.getById(e.parentOrgUnitId,...t):void 0,n=await this.create({tenant:e.tenantId,parent:i?.id??e.parentOrgUnitId,name:e.name,path:this.orgUnitPath(i?.path,e.name),metadata:e.metadata},...t);await this.createProfileIfNeeded(n.id,e.profileKey,e.profileMetadata,...t);const r=new je;return await r.createSelfLink(e.tenantId,n.id,...t),e.parentOrgUnitId&&await r.insertAncestorLinksForNewChild(e.tenantId,e.parentOrgUnitId,n.id,...t),n}async listChildren(e,...t){return(await this.listAll(...t)).filter(t=>J(t.parent,e))}async listTenantOrgUnits(e,...t){return(await this.listAll(...t)).filter(t=>H(t.tenant,e))}async listDescendantOrgUnits(e,t,i=!1,...n){const r=await(new je).listDescendants(e,t,...n),s=new Set(r.map(e=>ie(e.descendant)));return i&&s.add(t),(await this.listTenantOrgUnits(e,...n)).filter(e=>s.has(e.id))}async listAncestorOrgUnits(e,t,i=!1,...n){const r=await(new je).listAncestors(e,t,...n),s=new Set(r.map(e=>ie(e.ancestor)));return i&&s.add(t),(await this.listTenantOrgUnits(e,...n)).filter(e=>s.has(e.id))}async renameOrgUnit(e,t,...i){const n=await this.getById(e,...i);return this.updateOne(e,{name:t,path:this.orgUnitPath(n.path.includes("/")?n.path.replace(/\/[^/]+$/,""):void 0,t)},...i)}async moveOrgUnit(e,t,i,...n){const r=await this.getById(i,...n),s=await this.getById(t,...n),o=await this.updateOne(t,{parent:r.id,path:this.orgUnitPath(r.path,s.name)},...n);return await this.rebuildTenantClosure(e,...n),o}async rebuildTenantClosure(e,...t){const i=new je,n=await i.listAll(...t);await Ke(i,n.filter(t=>H(t.tenant,e)),...t);const r=(await this.listTenantOrgUnits(e,...t)).sort((e,t)=>e.path.split("/").filter(Boolean).length-t.path.split("/").filter(Boolean).length);for(const n of r)await i.createSelfLink(e,n.id,...t),n.parent&&await i.insertAncestorLinksForNewChild(e,ie(n.parent),n.id,...t)}async deleteOrgUnitTree(e,t,...i){const n=new je,r=await this.listDescendantOrgUnits(e,t,!0,...i),s=new Set(r.map(e=>e.id)),o=(await this.listTenantOrgUnits(e,...i)).filter(e=>s.has(e.id));await Ke(this,o,...i),await n.deleteLinksForSubtree(e,t,...i)}}b([u(),O("design:type",Function),O("design:paramtypes",[String,String,Object,String,Object,Object]),O("design:returntype",Promise)],ke.prototype,"createRoot",null),b([u(),O("design:type",Function),O("design:paramtypes",[Object,Object]),O("design:returntype",Promise)],ke.prototype,"createChild",null),b([u(),O("design:type",Function),O("design:paramtypes",[String,String,String,Object]),O("design:returntype",Promise)],ke.prototype,"moveOrgUnit",null),b([u(),O("design:type",Function),O("design:paramtypes",[String,Object]),O("design:returntype",Promise)],ke.prototype,"rebuildTenantClosure",null),b([u(),O("design:type",Function),O("design:paramtypes",[String,String,Object]),O("design:returntype",Promise)],ke.prototype,"deleteOrgUnitTree",null);class Te extends ee{constructor(){super(se)}async createUser(e,...t){return this.create({email:e.email,phone:e.phone,displayName:e.displayName},...t)}async getByEmail(e,...t){return(await this.listAll(...t)).find(t=>t.email===e)}async updateDisplayName(e,t,...i){return this.updateOne(e,{displayName:t},...i)}async updateEmail(e,t,...i){return this.updateOne(e,{email:t},...i)}async updatePhone(e,t,...i){return this.updateOne(e,{phone:t},...i)}}class xe extends ee{constructor(){super(ge)}async createPrincipal(e,t,i,...n){return this.create({tenant:e,kind:t,subjectId:i},...n)}async getForSubject(e,t,i,...n){return(await this.listAll(...n)).find(n=>H(n.tenant,e)&&n.kind===t&&n.subjectId===i)}async getOrCreateForSubject(e,t,i,...n){return await this.getForSubject(e,t,i,...n)??await this.createPrincipal(e,t,i,...n)}async getUserPrincipal(e,t,...i){return this.getOrCreateForSubject(e,j.User,t,...i)}async getGroupPrincipal(e,t,...i){return this.getOrCreateForSubject(e,j.Group,t,...i)}}class De extends ee{constructor(){super(re)}async addUserToTenant(e,t,i=_.Active,...n){return this.create({tenant:e,user:t,status:i},...n)}async setStatus(e,t,...i){return this.updateOne(e,{status:t},...i)}async listUserTenants(e,...t){return(await this.listAll(...t)).filter(t=>J(t.user,e))}async listTenantUsers(e,...t){return(await this.listAll(...t)).filter(t=>H(t.tenant,e))}async removeUserFromTenant(e,...t){await this.deleteById(e,...t)}}class Fe extends ee{constructor(){super(oe)}async addUserToOrgUnit(e,t,i,n=_.Active,...r){return this.create({tenant:e,orgUnit:t,user:i,status:n},...r)}async setStatus(e,t,...i){return this.updateOne(e,{status:t},...i)}async listUserOrgUnits(e,...t){return(await this.listAll(...t)).filter(t=>J(t.user,e))}async listOrgUnitUsers(e,...t){return(await this.listAll(...t)).filter(t=>J(t.orgUnit,e))}async removeUserFromOrgUnit(e,...t){await this.deleteById(e,...t)}}class Re extends ee{constructor(){super(Oe)}async createGroup(e,t,i,n,...r){return this.create({tenant:e,orgUnit:i,name:t,metadata:n},...r)}async renameGroup(e,t,...i){return this.updateOne(e,{name:t},...i)}async moveGroupToOrgUnit(e,t,...i){return this.updateOne(e,{orgUnit:t},...i)}async listTenantGroups(e,...t){return(await this.listAll(...t)).filter(t=>H(t.tenant,e))}}class Be extends ee{constructor(){super(be)}async addPrincipalToGroup(e,t,i,n,...r){return this.create({tenant:e,group:t,principal:i,metadata:n},...r)}async listGroupMembers(e,...t){return(await this.listAll(...t)).filter(t=>J(t.group,e))}async listPrincipalGroups(e,...t){return(await this.listAll(...t)).filter(t=>J(t.principal,e))}async removePrincipalFromGroup(e,...t){await this.deleteById(e,...t)}async resolveGroupPrincipalIdsForPrincipal(e,...t){const i=new xe,n=await this.listPrincipalGroups(e,...t);return await Promise.all(n.map(async e=>{const n=ie(e.tenant),r=ie(e.group);return(await i.getGroupPrincipal(n,r,...t)).id}))}}class Ce extends ee{constructor(){super(pe)}async createPermission(e,...t){return this.create({key:e.key,category:e.category,description:e.description},...t)}async getByKey(e,...t){return(await this.listAll(...t)).find(t=>t.key===e)}async listByCategory(e,...t){return(await this.listAll(...t)).filter(t=>t.category===e)}async updateDescription(e,t,...i){return this.updateOne(e,{description:t},...i)}}class Ge extends ee{constructor(){super(ce)}async createRole(e,...t){return this.create({tenant:e.tenantId,key:e.key,name:e.name,description:e.description,metadata:e.metadata},...t)}async getSystemRoleByKey(e,...t){const i=(await this.listAll(...t)).find(t=>!t.tenant&&t.key===e);if(!i)throw Error(`Role "${e}" not found`);return i}async getTenantRoleByKey(e,t,...i){const n=(await this.listAll(...i)).find(i=>H(i.tenant,e)&&i.key===t);if(!n)throw Error(`Role "${t}" not found for tenant ${e}`);return n}async renameRole(e,t,...i){return this.updateOne(e,{name:t},...i)}async updateRoleMetadata(e,t,...i){return this.updateOne(e,{metadata:t},...i)}async listTenantRoles(e,t=!1,...i){return(await this.listAll(...i)).filter(i=>t&&!i.tenant||H(i.tenant,e))}}class Ne extends ee{constructor(){super(de)}async addPermissionToRole(e,t,...i){return this.create({role:e,permission:t},...i)}async addPermissionKeyToRole(e,t,...i){const n=await(new Ce).getByKey(t,...i);return this.addPermissionToRole(e,n.id,...i)}async removePermissionFromRole(e,...t){await this.deleteById(e,...t)}async listRolePermissions(e,...t){return(await this.listAll(...t)).filter(t=>J(t.role,e))}async listPermissionRoles(e,...t){return(await this.listAll(...t)).filter(t=>J(t.permission,e))}async replaceRolePermissions(e,t,...i){const n=await this.listRolePermissions(e,...i);return await(async(e,t,...i)=>{for(const n of t)await e.deleteById(n.id,...i)})(this,n,...i),Promise.all(t.map(t=>this.addPermissionToRole(e,t,...i)))}async createRoleWithPermissions(e,t,...i){const n=await(new Ge).createRole(e,...i);for(const e of t)await this.addPermissionKeyToRole(n.id,e,...i);return n}}class Ee extends ee{constructor(){super(ye)}async assignRole(e,...t){return this.create({tenant:e.tenantId,principal:e.principalId,role:e.roleId,scopeKind:e.scopeKind,scopeId:e.scopeId,inheritDown:e.inheritDown??!1,startsAt:e.startsAt,expiresAt:e.expiresAt,conditions:e.conditions},...t)}async revokeAssignment(e,...t){await this.deleteById(e,...t)}async listPrincipalAssignments(e,t,...i){return(await this.listAll(...i)).filter(i=>H(i.tenant,e)&&J(i.principal,t))}async listRoleAssignments(e,...t){return(await this.listAll(...t)).filter(t=>J(t.role,e))}async listTenantAssignments(e,...t){return(await this.listAll(...t)).filter(t=>H(t.tenant,e))}async updateAssignmentWindow(e,t,i,...n){return this.updateOne(e,{startsAt:t,expiresAt:i},...n)}}class $e extends ee{constructor(){super(Ae)}async listForPrincipal(e,t,...i){return(await this.listAll(...i)).filter(i=>H(i.tenant,e)&&J(i.principal,t))}async listForScope(e,t,i,...n){return(await this.listAll(...n)).filter(n=>H(n.tenant,e)&&n.scopeKind===t&&n.scopeId===i)}async hasPermission(e,t,i,n,r,s,...o){return(await this.listForPrincipal(e,t,...o)).some(e=>!(e.permissionKey!==i||e.scopeKind!==n||e.scopeId!==r||e.startsAt&&s&&e.startsAt>s||e.expiresAt&&s&&e.expiresAt<s))}async deleteForPrincipal(e,t,...i){for(const n of await this.listForPrincipal(e,t,...i))await this.deleteById(n.id,...i)}async deleteForTenant(e,...t){for(const i of(await this.listAll(...t)).filter(t=>H(t.tenant,e)))await this.deleteById(i.id,...t)}async rebuildForPrincipal(e,t,...i){await this.deleteForPrincipal(e,t,...i);const n=new Ee,r=new Ne,s=new Ce,o=new Be,a=new xe,p=new je,d=new Pe,c=[],y=await n.listPrincipalAssignments(e,t,...i),l=await o.listPrincipalGroups(t,...i),g=[...y,...(await Promise.all(l.map(async t=>{const r=await a.getGroupPrincipal(ie(t.tenant),ie(t.group),...i);return n.listPrincipalAssignments(e,r.id,...i)}))).flat()];for(const n of g){const o=await r.listRolePermissions(ie(n.role),...i),a=await Promise.all(o.map(async e=>s.findOneBy("id",ie(e.permission),...i)));for(const r of a){if(!r)continue;const s=n.scopeKind,o=n.scopeId,a=[];if(s===P.Tenant)a.push({scopeKind:s,scopeId:e});else if(s===P.Resource)a.push({scopeKind:s,scopeId:o});else if(s!==P.OrgUnit||n.inheritDown){if(s===P.OrgUnit&&n.inheritDown){const t=await p.listDescendants(e,o,...i);a.push(...t.map(e=>({scopeKind:s,scopeId:ie(e.descendant)})))}}else a.push({scopeKind:s,scopeId:o});for(const p of a)s===P.OrgUnit&&n.inheritDown&&p.scopeId!==o&&await d.categoryBlockedForAncestor(e,p.scopeId,o,r.category,...i)||c.push({id:"",tenantId:e,principalId:t,permissionKey:r.key,scopeKind:p.scopeKind,scopeId:p.scopeId,sourceKind:"role_assignment",sourceId:n.id,startsAt:n.startsAt,expiresAt:n.expiresAt})}}return await Promise.all(c.map(e=>this.create({tenant:e.tenantId,principal:e.principalId,permissionKey:e.permissionKey,scopeKind:e.scopeKind,scopeId:e.scopeId,sourceKind:e.sourceKind,sourceId:e.sourceId,startsAt:e.startsAt,expiresAt:e.expiresAt},...i)))}async rebuildForTenant(e,...t){const i=(await(new xe).listAll(...t)).filter(t=>H(t.tenant,e));for(const n of i)await this.rebuildForPrincipal(e,n.id,...t)}}b([u(),O("design:type",Function),O("design:paramtypes",[String,String,Object]),O("design:returntype",Promise)],$e.prototype,"rebuildForPrincipal",null),b([u(),O("design:type",Function),O("design:paramtypes",[String,Object]),O("design:returntype",Promise)],$e.prototype,"rebuildForTenant",null);class Le extends ee{constructor(){super(ue)}async registerResource(e,...t){return this.create({tenant:e.tenantId,orgUnit:e.orgUnitId,resourceType:e.resourceType,resourceId:e.resourceId,visibility:e.visibility,owner:e.ownerPrincipalId,sensitivity:e.sensitivity,metadata:e.metadata},...t)}async getByDomainResource(e,t,i,...n){return(await this.listAll(...n)).find(n=>H(n.tenant,e)&&n.resourceType===t&&n.resourceId===i)}async moveResourceToOrgUnit(e,t,...i){return this.updateOne(e,{orgUnit:t},...i)}async setVisibility(e,t,...i){return this.updateOne(e,{visibility:t},...i)}async transferOwnership(e,t,...i){return this.updateOne(e,{owner:t},...i)}async listOrgUnitResources(e,...t){return(await this.listAll(...t)).filter(t=>J(t.orgUnit,e))}async listTenantResources(e,...t){return(await this.listAll(...t)).filter(t=>H(t.tenant,e))}}class Me extends ee{constructor(){super(le)}async grantResource(e,...t){return this.create({tenant:e.tenantId,resource:e.resourceId,principal:e.principalId,permissionKey:e.permissionKey,startsAt:e.startsAt,expiresAt:e.expiresAt,conditions:e.conditions,createdBy:e.createdByPrincipalId},...t)}async revokeGrant(e,...t){await this.deleteById(e,...t)}async listResourceGrants(e,...t){return(await this.listAll(...t)).filter(t=>J(t.resource,e))}async listPrincipalGrants(e,t,...i){return(await this.listAll(...i)).filter(i=>H(i.tenant,e)&&J(i.principal,t))}async hasGrant(e,t,i,n,r,...s){return(await this.listPrincipalGrants(e,t,...s)).some(e=>J(e.resource,i)&&e.permissionKey===n&&(!e.startsAt||!r||e.startsAt<=r)&&(!e.expiresAt||!r||e.expiresAt>=r))}async deleteAllForResource(e,...t){for(const i of await this.listResourceGrants(e,...t))await this.deleteById(i.id,...t)}}class Ve{async unregisterResource(e,...t){await(new Me).deleteAllForResource(e,...t),await(new Le).deleteById(e,...t)}async resolveResourceScope(e,...t){const i=await(new Le).getById(e,...t);return{tenantId:ie(i.tenant),orgUnitId:ie(i.orgUnit),visibility:i.visibility,ownerPrincipalId:i.owner?ie(i.owner):void 0}}}class We extends ee{constructor(){super(he)}async createBinding(e,...t){return this.create({tenant:e.tenantId,storageKind:e.storageKind,bindingKind:e.bindingKind,bindingKey:e.bindingKey,region:e.region,config:e.config},...t)}async listTenantBindings(e,...t){return(await this.listAll(...t)).filter(t=>ie(t.tenant)===e)}async getBinding(e,t,...i){return(await this.listTenantBindings(e,...i)).find(e=>e.storageKind===t)}async setBindingConfig(e,t,...i){return this.updateOne(e,{config:t},...i)}async promoteToDedicated(e,t,i,n,...r){return this.updateOne(e,{bindingKind:T.Dedicated,bindingKey:t,region:i,config:n},...r)}async setShared(e,t,i,n,...r){return this.updateOne(e,{bindingKind:T.Shared,bindingKey:t,region:i,config:n},...r)}}class qe{constructor(){this.tenantService=new Ue,this.tenantProfileService=new Ie,this.orgUnitService=new ke,this.orgUnitProfileService=new _e,this.userService=new Te,this.membershipService=new De,this.principalService=new xe,this.permissionService=new Ce,this.roleService=new Ge,this.rolePermissionService=new Ne,this.roleAssignmentService=new Ee,this.effectivePermissionService=new $e}async bootstrapTenantFromTemplate(e,...t){const i=await this.tenantService.createTenant(e.tenant,...t);e.tenant.profileKey&&await this.tenantProfileService.createProfile(i.id,e.tenant.profileKey,e.tenant.profileMetadata,...t);const n=async(e,r)=>{const s=void 0===e?await this.orgUnitService.createRoot(i.id,r.name,r.metadata,r.profileKey,r.metadata,...t):await this.orgUnitService.createChild({tenantId:i.id,parentOrgUnitId:e,name:r.name,metadata:r.metadata,profileKey:r.profileKey,profileMetadata:r.metadata},...t);for(const e of r.children??[])await n(s.id,e);return s},r=await n(void 0,e.rootOrgUnit),s=await this.userService.createUser(e.ownerUser,...t);await this.membershipService.addUserToTenant(i.id,s.id,_.Active,...t);const o=await this.principalService.getUserPrincipal(i.id,s.id,...t);for(const i of e.permissions)await this.permissionService.createPermission(i,...t);for(const n of e.roles){const e=await this.roleService.createRole({tenantId:i.id,key:n.key,name:n.name,description:n.description},...t);for(const i of n.permissionKeys)await this.rolePermissionService.addPermissionKeyToRole(e.id,i,...t)}const a=await this.roleService.getTenantRoleByKey(i.id,e.ownerRoleKey,...t);return await this.roleAssignmentService.assignRole({tenantId:i.id,principalId:o.id,roleId:a.id,scopeKind:P.OrgUnit,scopeId:r.id,inheritDown:!0},...t),await this.effectivePermissionService.rebuildForPrincipal(i.id,o.id,...t),{tenantId:i.id,rootOrgUnitId:r.id,ownerUserId:s.id,ownerPrincipalId:o.id}}}b([u(),O("design:type",Function),O("design:paramtypes",[Object,Object]),O("design:returntype",Promise)],qe.prototype,"bootstrapTenantFromTemplate",null);class ze{constructor(){this.membershipService=new De,this.orgMembershipService=new Fe,this.principalService=new xe,this.roleService=new Ge,this.roleAssignmentService=new Ee,this.effectivePermissionService=new $e}async onboardUserToTenantAndOrgUnit(e,t,i,n,...r){await this.membershipService.addUserToTenant(e,t,_.Active,...r),await this.orgMembershipService.addUserToOrgUnit(e,i,t,_.Active,...r);const s=await this.principalService.getUserPrincipal(e,t,...r),o=await this.roleService.getTenantRoleByKey(e,n,...r);return await this.roleAssignmentService.assignRole({tenantId:e,principalId:s.id,roleId:o.id,scopeKind:P.OrgUnit,scopeId:i,inheritDown:!0},...r),await this.effectivePermissionService.rebuildForPrincipal(e,s.id,...r),{principalId:s.id}}async changeUserOrgRole(e,t,i,n,r,...s){const o=await this.roleService.getTenantRoleByKey(e,n,...s),a=await this.roleAssignmentService.listPrincipalAssignments(e,t,...s);for(const e of a.filter(e=>e.scopeKind===P.OrgUnit&&e.scopeId===i))await this.roleAssignmentService.revokeAssignment(e.id,...s);await this.roleAssignmentService.assignRole({tenantId:e,principalId:t,roleId:o.id,scopeKind:P.OrgUnit,scopeId:i,inheritDown:r},...s),await this.effectivePermissionService.rebuildForPrincipal(e,t,...s)}async suspendUserInTenant(e,t,i,...n){await this.membershipService.setStatus(e,_.Suspended,...n),await this.effectivePermissionService.deleteForPrincipal(t,i,...n)}async reactivateUserInTenant(e,t,i,...n){await this.membershipService.setStatus(e,_.Active,...n),await this.effectivePermissionService.rebuildForPrincipal(t,i,...n)}}b([u(),O("design:type",Function),O("design:paramtypes",[String,String,String,String,Object]),O("design:returntype",Promise)],ze.prototype,"onboardUserToTenantAndOrgUnit",null),b([u(),O("design:type",Function),O("design:paramtypes",[String,String,String,String,Boolean,Object]),O("design:returntype",Promise)],ze.prototype,"changeUserOrgRole",null),b([u(),O("design:type",Function),O("design:paramtypes",[String,String,String,Object]),O("design:returntype",Promise)],ze.prototype,"suspendUserInTenant",null),b([u(),O("design:type",Function),O("design:paramtypes",[String,String,String,Object]),O("design:returntype",Promise)],ze.prototype,"reactivateUserInTenant",null);class Qe{constructor(e={}){this.dataSources=e}async canAccess(e,...t){const i=e.at??new Date;if(e.scopeKind&&e.scopeId)return Q(await(this.dataSources.listEffectivePermissionsForScope?.(e.tenantId,e.scopeKind,e.scopeId))).some(t=>t.permissionKey===e.permissionKey&&Y(i,t.startsAt,t.expiresAt));if(!e.resourceProtectedId)return!1;const n=await(this.dataSources.loadResource?.(e.tenantId,e.resourceProtectedId));if(!n)return!1;if(n.tenantId!==e.tenantId)return!1;if(n.ownerPrincipalId===e.principalId)return!0;if(Q(await(this.dataSources.listResourceGrants?.(e.tenantId,e.resourceProtectedId))).filter(t=>t.principalId===e.principalId&&t.permissionKey===e.permissionKey&&Y(i,t.startsAt,t.expiresAt)).length>0)return!0;const r=n.visibility;return r!==K.Private&&r!==K.ResourceAcl&&(r===K.OrgUnit||r===K.OrgSubtree?Q(await(this.dataSources.listEffectivePermissionsForScope?.(e.tenantId,P.OrgUnit,n.orgUnitId))).some(t=>t.permissionKey===e.permissionKey&&Y(i,t.startsAt,t.expiresAt)):r===K.Tenant&&Q(await(this.dataSources.listEffectivePermissionsForScope?.(e.tenantId,P.Tenant,e.tenantId))).some(t=>t.permissionKey===e.permissionKey&&Y(i,t.startsAt,t.expiresAt)))}async requireAccess(e,...t){if(!await this.canAccess(e,...t))throw new m(`Access denied for ${e.permissionKey} on ${e.resourceProtectedId??(i=e.scopeKind??P.Resource,n=e.scopeId??"",`${i}:${n}`)}`);var i,n}async buildAccessContext(e,t,...i){return Z({tenantId:e,principalId:t,permissions:Q(await(this.dataSources.listEffectivePermissions?.(e,t))),grants:Q(await(this.dataSources.listPrincipalGrants?.(e,t)))})}async buildArangoContext(e,t,i,...n){const r=await this.buildAccessContext(e,t,...n),s=r.allowedOrgUnitIdsByPermission[i]??[],o=r.resourceGrants.filter(e=>e.permissionKey===i).map(e=>e.resourceId);return V({tenantId:e,principalId:t,permissionKey:i,allowedOrgUnitIds:s,allowedResourceIds:o})}async buildQdrantFilter(e,t,i,...n){const r=await this.buildAccessContext(e,t,...n);return W({tenantId:e,principalId:t,allowedOrgUnitIds:r.allowedOrgUnitIdsByPermission[i]??[],allowedResourceIds:r.resourceGrants.filter(e=>e.permissionKey===i).map(e=>e.resourceId)})}}const He="##VERSION##",Je="##COMMIT##",Xe="##FULL_VERSION##",Ye="##PACKAGE##";export{ne as AuthorizationModel,Qe as AuthzService,ee as BaseModelService,qe as BootstrapService,Je as COMMIT,Ae as EffectivePermission,$e as EffectivePermissionService,Xe as FULL_VERSION,Oe as Group,be as GroupMembership,Be as GroupMembershipService,Re as GroupService,me as InheritanceBlock,Pe as InheritanceBlockService,I as IsolationTier,x as IsolationTierOptions,_ as MembershipStatus,D as MembershipStatusOptions,ve as OrgUnit,ae as OrgUnitClosure,je as OrgUnitClosureService,oe as OrgUnitMembership,Fe as OrgUnitMembershipService,Se as OrgUnitProfile,_e as OrgUnitProfileService,ke as OrgUnitService,Ye as PACKAGE_NAME,pe as Permission,U as PermissionCategory,B as PermissionCategoryOptions,Ce as PermissionService,ge as Principal,j as PrincipalKind,F as PrincipalKindOptions,xe as PrincipalService,ue as ProtectedResource,Le as ProtectedResourceService,L as REL_CASCADE_DEPENDENT,M as REL_CASCADE_INSERT_UPDATE,$ as REL_NULLIFY,E as REL_RESTRICT,le as ResourceGrant,Me as ResourceGrantService,Ve as ResourceLifecycleService,K as ResourceVisibility,C as ResourceVisibilityOptions,ce as Role,ye as RoleAssignment,Ee as RoleAssignmentService,de as RolePermission,Ne as RolePermissionService,Ge as RoleService,P as ScopeKind,R as ScopeKindOptions,he as StorageBinding,T as StorageBindingKind,N as StorageBindingKindOptions,We as StorageBindingService,k as StorageKind,G as StorageKindOptions,ze as SystemManagementService,we as Tenant,re as TenantMembership,De as TenantMembershipService,fe as TenantProfile,Ie as TenantProfileService,Ue as TenantService,se as User,Te as UserService,He as VERSION,Q as asArray,Z as buildAccessContext,V as buildArangoContext,W as buildQdrantFilter,A as execWithLogging,te as id,Y as isTimeValid,X as lowerSlug,z as nowIso,ie as relationId,J as relationMatch,H as sameTenant};
|
|
2
|
-
|
|
1
|
+
import { exec } from "child_process";
|
|
2
|
+
|
|
3
|
+
import { LogLevel } from "@decaf-ts/logging";
|
|
4
|
+
|
|
5
|
+
import { InternalError } from "@decaf-ts/db-decorators";
|
|
6
|
+
|
|
7
|
+
import { Cascade, ModelService, pk, uuid, manyToOne, column, createdAt, updatedAt, table, unique, oneToMany, transactional, AuthorizationError } from "@decaf-ts/core";
|
|
8
|
+
|
|
9
|
+
export { AuthorizationError, transactional } from "@decaf-ts/core";
|
|
10
|
+
|
|
11
|
+
import { Model, required, type, option, model } from "@decaf-ts/decorator-validation";
|
|
12
|
+
|
|
13
|
+
import { __decorate, __metadata } from "tslib";
|
|
14
|
+
|
|
15
|
+
async function execWithLogging(command, options, log, level = LogLevel.info) {
|
|
16
|
+
log.debug(`Executing: ${command}`);
|
|
17
|
+
return new Promise((resolve, reject) => {
|
|
18
|
+
const child = exec(command, options);
|
|
19
|
+
const stdout = [];
|
|
20
|
+
const stderr = [];
|
|
21
|
+
child.stdout?.on("data", data => {
|
|
22
|
+
stdout.push(data);
|
|
23
|
+
log[level](data.trim());
|
|
24
|
+
});
|
|
25
|
+
child.stderr?.on("data", data => {
|
|
26
|
+
stderr.push(data);
|
|
27
|
+
log.debug(data.trim());
|
|
28
|
+
});
|
|
29
|
+
child.on("close", code => {
|
|
30
|
+
if (code === 0) {
|
|
31
|
+
log.silly(`Command completed successfully`);
|
|
32
|
+
resolve({
|
|
33
|
+
stdout: stdout.join("\n"),
|
|
34
|
+
stderr: stderr.join("\n")
|
|
35
|
+
});
|
|
36
|
+
} else {
|
|
37
|
+
log.critical(`Command failed with code ${code}:\n ${stderr.join("\n")}`);
|
|
38
|
+
reject(new InternalError(`Command failed with code ${code}: ${stderr.join("\n")}`));
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
child.on("error", err => {
|
|
42
|
+
log.critical(`Command execution error`, err);
|
|
43
|
+
reject(err);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
var IsolationTier;
|
|
49
|
+
|
|
50
|
+
(function(IsolationTier) {
|
|
51
|
+
IsolationTier["Pooled"] = "pooled";
|
|
52
|
+
IsolationTier["Bridge"] = "bridge";
|
|
53
|
+
IsolationTier["Silo"] = "silo";
|
|
54
|
+
})(IsolationTier || (IsolationTier = {}));
|
|
55
|
+
|
|
56
|
+
var MembershipStatus;
|
|
57
|
+
|
|
58
|
+
(function(MembershipStatus) {
|
|
59
|
+
MembershipStatus["Invited"] = "invited";
|
|
60
|
+
MembershipStatus["Active"] = "active";
|
|
61
|
+
MembershipStatus["Suspended"] = "suspended";
|
|
62
|
+
MembershipStatus["Removed"] = "removed";
|
|
63
|
+
})(MembershipStatus || (MembershipStatus = {}));
|
|
64
|
+
|
|
65
|
+
var PrincipalKind;
|
|
66
|
+
|
|
67
|
+
(function(PrincipalKind) {
|
|
68
|
+
PrincipalKind["User"] = "user";
|
|
69
|
+
PrincipalKind["Group"] = "group";
|
|
70
|
+
PrincipalKind["ServiceAccount"] = "service_account";
|
|
71
|
+
PrincipalKind["Agent"] = "agent";
|
|
72
|
+
PrincipalKind["ApiKey"] = "api_key";
|
|
73
|
+
})(PrincipalKind || (PrincipalKind = {}));
|
|
74
|
+
|
|
75
|
+
var ScopeKind;
|
|
76
|
+
|
|
77
|
+
(function(ScopeKind) {
|
|
78
|
+
ScopeKind["Tenant"] = "tenant";
|
|
79
|
+
ScopeKind["OrgUnit"] = "org_unit";
|
|
80
|
+
ScopeKind["Resource"] = "resource";
|
|
81
|
+
})(ScopeKind || (ScopeKind = {}));
|
|
82
|
+
|
|
83
|
+
var PermissionCategory;
|
|
84
|
+
|
|
85
|
+
(function(PermissionCategory) {
|
|
86
|
+
PermissionCategory["Admin"] = "admin";
|
|
87
|
+
PermissionCategory["ContentRead"] = "content_read";
|
|
88
|
+
PermissionCategory["ContentWrite"] = "content_write";
|
|
89
|
+
PermissionCategory["Memory"] = "memory";
|
|
90
|
+
PermissionCategory["Graph"] = "graph";
|
|
91
|
+
PermissionCategory["Vector"] = "vector";
|
|
92
|
+
PermissionCategory["Export"] = "export";
|
|
93
|
+
PermissionCategory["Billing"] = "billing";
|
|
94
|
+
PermissionCategory["Audit"] = "audit";
|
|
95
|
+
PermissionCategory["Security"] = "security";
|
|
96
|
+
PermissionCategory["Data"] = "data";
|
|
97
|
+
PermissionCategory["Automation"] = "automation";
|
|
98
|
+
})(PermissionCategory || (PermissionCategory = {}));
|
|
99
|
+
|
|
100
|
+
var ResourceVisibility;
|
|
101
|
+
|
|
102
|
+
(function(ResourceVisibility) {
|
|
103
|
+
ResourceVisibility["Private"] = "private";
|
|
104
|
+
ResourceVisibility["ResourceAcl"] = "resource_acl";
|
|
105
|
+
ResourceVisibility["OrgUnit"] = "org_unit";
|
|
106
|
+
ResourceVisibility["OrgSubtree"] = "org_subtree";
|
|
107
|
+
ResourceVisibility["Tenant"] = "tenant";
|
|
108
|
+
})(ResourceVisibility || (ResourceVisibility = {}));
|
|
109
|
+
|
|
110
|
+
var StorageKind;
|
|
111
|
+
|
|
112
|
+
(function(StorageKind) {
|
|
113
|
+
StorageKind["Postgres"] = "postgres";
|
|
114
|
+
StorageKind["Arango"] = "arango";
|
|
115
|
+
StorageKind["Qdrant"] = "qdrant";
|
|
116
|
+
StorageKind["ObjectStorage"] = "object_storage";
|
|
117
|
+
})(StorageKind || (StorageKind = {}));
|
|
118
|
+
|
|
119
|
+
var StorageBindingKind;
|
|
120
|
+
|
|
121
|
+
(function(StorageBindingKind) {
|
|
122
|
+
StorageBindingKind["Shared"] = "shared";
|
|
123
|
+
StorageBindingKind["Dedicated"] = "dedicated";
|
|
124
|
+
})(StorageBindingKind || (StorageBindingKind = {}));
|
|
125
|
+
|
|
126
|
+
const IsolationTierOptions = Object.values(IsolationTier);
|
|
127
|
+
|
|
128
|
+
const MembershipStatusOptions = Object.values(MembershipStatus);
|
|
129
|
+
|
|
130
|
+
const PrincipalKindOptions = Object.values(PrincipalKind);
|
|
131
|
+
|
|
132
|
+
const ScopeKindOptions = Object.values(ScopeKind);
|
|
133
|
+
|
|
134
|
+
const PermissionCategoryOptions = Object.values(PermissionCategory);
|
|
135
|
+
|
|
136
|
+
const ResourceVisibilityOptions = Object.values(ResourceVisibility);
|
|
137
|
+
|
|
138
|
+
const StorageKindOptions = Object.values(StorageKind);
|
|
139
|
+
|
|
140
|
+
const StorageBindingKindOptions = Object.values(StorageBindingKind);
|
|
141
|
+
|
|
142
|
+
const REL_RESTRICT = {
|
|
143
|
+
update: Cascade.NONE,
|
|
144
|
+
delete: Cascade.NONE,
|
|
145
|
+
nullable: false
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
const REL_NULLIFY = {
|
|
149
|
+
update: Cascade.NONE,
|
|
150
|
+
delete: Cascade.NONE,
|
|
151
|
+
nullable: true
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const REL_CASCADE_DEPENDENT = {
|
|
155
|
+
update: Cascade.CASCADE,
|
|
156
|
+
delete: Cascade.CASCADE,
|
|
157
|
+
nullable: false
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const REL_CASCADE_INSERT_UPDATE = {
|
|
161
|
+
update: Cascade.CASCADE,
|
|
162
|
+
delete: Cascade.NONE,
|
|
163
|
+
nullable: false
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
function buildArangoContext(options) {
|
|
167
|
+
return {
|
|
168
|
+
tenantId: options.tenantId,
|
|
169
|
+
principalId: options.principalId,
|
|
170
|
+
permissionKey: options.permissionKey,
|
|
171
|
+
allowedOrgUnitIds: [ ...options.allowedOrgUnitIds ],
|
|
172
|
+
allowedResourceIds: [ ...options.allowedResourceIds ]
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function buildQdrantFilter(options) {
|
|
177
|
+
return {
|
|
178
|
+
must: [ {
|
|
179
|
+
key: "tenant_id",
|
|
180
|
+
match: {
|
|
181
|
+
value: options.tenantId
|
|
182
|
+
}
|
|
183
|
+
}, {
|
|
184
|
+
should: [ {
|
|
185
|
+
key: "org_unit_id",
|
|
186
|
+
match: {
|
|
187
|
+
any: options.allowedOrgUnitIds
|
|
188
|
+
}
|
|
189
|
+
}, {
|
|
190
|
+
key: "protected_resource_id",
|
|
191
|
+
match: {
|
|
192
|
+
any: options.allowedResourceIds
|
|
193
|
+
}
|
|
194
|
+
}, {
|
|
195
|
+
key: "owner_principal_id",
|
|
196
|
+
match: {
|
|
197
|
+
value: options.principalId
|
|
198
|
+
}
|
|
199
|
+
} ]
|
|
200
|
+
} ]
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function scopeKey$1(scopeKind, scopeId) {
|
|
205
|
+
return `${scopeKind}:${scopeId}`;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function nowIso() {
|
|
209
|
+
return new Date;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function asArray(value) {
|
|
213
|
+
return value ?? [];
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function sameTenant(rowTenant, tenantId) {
|
|
217
|
+
return relationId(rowTenant) === tenantId;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function relationMatch(value, target) {
|
|
221
|
+
return target ? relationId(value) === target : false;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function lowerSlug(value) {
|
|
225
|
+
return value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "item";
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function isTimeValid(at, startsAt, expiresAt) {
|
|
229
|
+
const instant = at ?? new Date;
|
|
230
|
+
if (startsAt && instant < startsAt) return false;
|
|
231
|
+
if (expiresAt && instant > expiresAt) return false;
|
|
232
|
+
return true;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function buildAccessContext(options) {
|
|
236
|
+
const permissionsByScope = {};
|
|
237
|
+
const allowedOrgUnitIdsByPermission = {};
|
|
238
|
+
for (const permission of options.permissions) {
|
|
239
|
+
const key = scopeKey$1(permission.scopeKind, permission.scopeId);
|
|
240
|
+
permissionsByScope[key] = permissionsByScope[key] ?? [];
|
|
241
|
+
permissionsByScope[key].push(permission.permissionKey);
|
|
242
|
+
if (permission.scopeKind === ScopeKind.OrgUnit) {
|
|
243
|
+
allowedOrgUnitIdsByPermission[permission.permissionKey] = allowedOrgUnitIdsByPermission[permission.permissionKey] ?? [];
|
|
244
|
+
allowedOrgUnitIdsByPermission[permission.permissionKey].push(permission.scopeId);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return {
|
|
248
|
+
tenantId: options.tenantId,
|
|
249
|
+
principalId: options.principalId,
|
|
250
|
+
permissionsByScope: permissionsByScope,
|
|
251
|
+
allowedOrgUnitIdsByPermission: allowedOrgUnitIdsByPermission,
|
|
252
|
+
resourceGrants: options.grants.map(grant => ({
|
|
253
|
+
resourceId: grant.resourceId,
|
|
254
|
+
permissionKey: grant.permissionKey
|
|
255
|
+
}))
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
class BaseModelService extends ModelService {
|
|
260
|
+
constructor(clazz) {
|
|
261
|
+
super(clazz);
|
|
262
|
+
}
|
|
263
|
+
newModel(clazz, data) {
|
|
264
|
+
return Object.assign(new clazz, data);
|
|
265
|
+
}
|
|
266
|
+
async create(data, ...args) {
|
|
267
|
+
return this.repo.create(Object.assign({}, data), ...args);
|
|
268
|
+
}
|
|
269
|
+
async createOne(data, ...args) {
|
|
270
|
+
return this.create(data, ...args);
|
|
271
|
+
}
|
|
272
|
+
async getById(id, ...args) {
|
|
273
|
+
return this.repo.read(id, ...args);
|
|
274
|
+
}
|
|
275
|
+
async updateOne(id, patch, ...args) {
|
|
276
|
+
const existing = await this.repo.read(id, ...args);
|
|
277
|
+
return this.repo.update(Object.assign(existing, patch), ...args);
|
|
278
|
+
}
|
|
279
|
+
async deleteById(id, ...args) {
|
|
280
|
+
await this.repo.delete(id, ...args);
|
|
281
|
+
}
|
|
282
|
+
async findOneBy(key, value, ...args) {
|
|
283
|
+
return this.repo.findOneBy(key, value, ...args);
|
|
284
|
+
}
|
|
285
|
+
async findManyBy(key, value, ...args) {
|
|
286
|
+
return this.repo.select().where({
|
|
287
|
+
[key]: value
|
|
288
|
+
}).execute(...args);
|
|
289
|
+
}
|
|
290
|
+
async listAll(...args) {
|
|
291
|
+
return this.repo.select().execute(...args);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
function id() {
|
|
296
|
+
return crypto.randomUUID();
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
function relationId(value) {
|
|
300
|
+
return typeof value === "string" ? value : value.id;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
class AuthorizationModel extends Model {
|
|
304
|
+
constructor(data) {
|
|
305
|
+
super(data);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
let TenantMembership = class TenantMembership extends AuthorizationModel {
|
|
310
|
+
constructor(data) {
|
|
311
|
+
super(data);
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
__decorate([ pk({
|
|
316
|
+
type: String
|
|
317
|
+
}), uuid(), __metadata("design:type", String) ], TenantMembership.prototype, "id", void 0);
|
|
318
|
+
|
|
319
|
+
__decorate([ manyToOne(() => Tenant, REL_CASCADE_DEPENDENT, false, undefined, "fk_tenant_memberships_tenant"), required(), __metadata("design:type", Object) ], TenantMembership.prototype, "tenant", void 0);
|
|
320
|
+
|
|
321
|
+
__decorate([ manyToOne(() => User, REL_CASCADE_DEPENDENT, false, undefined, "fk_tenant_memberships_user"), required(), __metadata("design:type", Object) ], TenantMembership.prototype, "user", void 0);
|
|
322
|
+
|
|
323
|
+
__decorate([ required(), type(String), option(MembershipStatusOptions), column(), __metadata("design:type", String) ], TenantMembership.prototype, "status", void 0);
|
|
324
|
+
|
|
325
|
+
__decorate([ createdAt(), __metadata("design:type", Date) ], TenantMembership.prototype, "createdAt", void 0);
|
|
326
|
+
|
|
327
|
+
__decorate([ updatedAt(), __metadata("design:type", Date) ], TenantMembership.prototype, "updatedAt", void 0);
|
|
328
|
+
|
|
329
|
+
TenantMembership = __decorate([ table("tenant_memberships"), model(), __metadata("design:paramtypes", [ Object ]) ], TenantMembership);
|
|
330
|
+
|
|
331
|
+
let User = class User extends AuthorizationModel {
|
|
332
|
+
constructor(data) {
|
|
333
|
+
super(data);
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
|
|
337
|
+
__decorate([ pk({
|
|
338
|
+
type: String
|
|
339
|
+
}), uuid(), __metadata("design:type", String) ], User.prototype, "id", void 0);
|
|
340
|
+
|
|
341
|
+
__decorate([ unique(), type(String), column(), __metadata("design:type", String) ], User.prototype, "email", void 0);
|
|
342
|
+
|
|
343
|
+
__decorate([ unique(), type(String), column(), __metadata("design:type", String) ], User.prototype, "phone", void 0);
|
|
344
|
+
|
|
345
|
+
__decorate([ required(), type(String), column(), __metadata("design:type", String) ], User.prototype, "displayName", void 0);
|
|
346
|
+
|
|
347
|
+
__decorate([ oneToMany(() => TenantMembership, REL_RESTRICT, false), __metadata("design:type", Array) ], User.prototype, "tenantMemberships", void 0);
|
|
348
|
+
|
|
349
|
+
__decorate([ oneToMany(() => OrgUnitMembership, REL_RESTRICT, false), __metadata("design:type", Array) ], User.prototype, "orgUnitMemberships", void 0);
|
|
350
|
+
|
|
351
|
+
__decorate([ createdAt(), __metadata("design:type", Date) ], User.prototype, "createdAt", void 0);
|
|
352
|
+
|
|
353
|
+
__decorate([ updatedAt(), __metadata("design:type", Date) ], User.prototype, "updatedAt", void 0);
|
|
354
|
+
|
|
355
|
+
User = __decorate([ table("users"), model(), __metadata("design:paramtypes", [ Object ]) ], User);
|
|
356
|
+
|
|
357
|
+
let OrgUnitMembership = class OrgUnitMembership extends AuthorizationModel {
|
|
358
|
+
constructor(data) {
|
|
359
|
+
super(data);
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
__decorate([ pk({
|
|
364
|
+
type: String
|
|
365
|
+
}), uuid(), __metadata("design:type", String) ], OrgUnitMembership.prototype, "id", void 0);
|
|
366
|
+
|
|
367
|
+
__decorate([ manyToOne(() => Tenant, REL_CASCADE_DEPENDENT, false, undefined, "fk_org_memberships_tenant"), required(), __metadata("design:type", Object) ], OrgUnitMembership.prototype, "tenant", void 0);
|
|
368
|
+
|
|
369
|
+
__decorate([ manyToOne(() => OrgUnit, REL_CASCADE_DEPENDENT, false, undefined, "fk_org_memberships_org_unit"), required(), __metadata("design:type", Object) ], OrgUnitMembership.prototype, "orgUnit", void 0);
|
|
370
|
+
|
|
371
|
+
__decorate([ manyToOne(() => User, REL_RESTRICT, false, undefined, "fk_org_memberships_user"), required(), __metadata("design:type", Object) ], OrgUnitMembership.prototype, "user", void 0);
|
|
372
|
+
|
|
373
|
+
__decorate([ required(), type(String), option(MembershipStatusOptions), column(), __metadata("design:type", String) ], OrgUnitMembership.prototype, "status", void 0);
|
|
374
|
+
|
|
375
|
+
__decorate([ createdAt(), __metadata("design:type", Date) ], OrgUnitMembership.prototype, "createdAt", void 0);
|
|
376
|
+
|
|
377
|
+
__decorate([ updatedAt(), __metadata("design:type", Date) ], OrgUnitMembership.prototype, "updatedAt", void 0);
|
|
378
|
+
|
|
379
|
+
OrgUnitMembership = __decorate([ table("org_unit_memberships"), model(), __metadata("design:paramtypes", [ Object ]) ], OrgUnitMembership);
|
|
380
|
+
|
|
381
|
+
let OrgUnitClosure = class OrgUnitClosure extends AuthorizationModel {
|
|
382
|
+
constructor(data) {
|
|
383
|
+
super(data);
|
|
384
|
+
}
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
__decorate([ pk({
|
|
388
|
+
type: String
|
|
389
|
+
}), uuid(), __metadata("design:type", String) ], OrgUnitClosure.prototype, "id", void 0);
|
|
390
|
+
|
|
391
|
+
__decorate([ manyToOne(() => Tenant, REL_CASCADE_DEPENDENT, false, undefined, "fk_org_closure_tenant"), required(), __metadata("design:type", Object) ], OrgUnitClosure.prototype, "tenant", void 0);
|
|
392
|
+
|
|
393
|
+
__decorate([ manyToOne(() => OrgUnit, REL_CASCADE_DEPENDENT, false, undefined, "fk_org_closure_ancestor"), required(), __metadata("design:type", Object) ], OrgUnitClosure.prototype, "ancestor", void 0);
|
|
394
|
+
|
|
395
|
+
__decorate([ manyToOne(() => OrgUnit, REL_CASCADE_DEPENDENT, false, undefined, "fk_org_closure_descendant"), required(), __metadata("design:type", Object) ], OrgUnitClosure.prototype, "descendant", void 0);
|
|
396
|
+
|
|
397
|
+
__decorate([ required(), type(Number), column(), __metadata("design:type", Number) ], OrgUnitClosure.prototype, "depth", void 0);
|
|
398
|
+
|
|
399
|
+
__decorate([ createdAt(), __metadata("design:type", Date) ], OrgUnitClosure.prototype, "createdAt", void 0);
|
|
400
|
+
|
|
401
|
+
OrgUnitClosure = __decorate([ table("org_unit_closure"), model(), __metadata("design:paramtypes", [ Object ]) ], OrgUnitClosure);
|
|
402
|
+
|
|
403
|
+
let Permission = class Permission extends AuthorizationModel {
|
|
404
|
+
constructor(data) {
|
|
405
|
+
super(data);
|
|
406
|
+
}
|
|
407
|
+
};
|
|
408
|
+
|
|
409
|
+
__decorate([ pk({
|
|
410
|
+
type: String
|
|
411
|
+
}), uuid(), __metadata("design:type", String) ], Permission.prototype, "id", void 0);
|
|
412
|
+
|
|
413
|
+
__decorate([ unique(), required(), type(String), column(), __metadata("design:type", String) ], Permission.prototype, "key", void 0);
|
|
414
|
+
|
|
415
|
+
__decorate([ required(), type(String), option(PermissionCategoryOptions), column(), __metadata("design:type", String) ], Permission.prototype, "category", void 0);
|
|
416
|
+
|
|
417
|
+
__decorate([ type(String), column(), __metadata("design:type", String) ], Permission.prototype, "description", void 0);
|
|
418
|
+
|
|
419
|
+
__decorate([ oneToMany(() => RolePermission, REL_RESTRICT, false), __metadata("design:type", Array) ], Permission.prototype, "rolePermissions", void 0);
|
|
420
|
+
|
|
421
|
+
Permission = __decorate([ table("permissions"), model(), __metadata("design:paramtypes", [ Object ]) ], Permission);
|
|
422
|
+
|
|
423
|
+
let RolePermission = class RolePermission extends AuthorizationModel {
|
|
424
|
+
constructor(data) {
|
|
425
|
+
super(data);
|
|
426
|
+
}
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
__decorate([ pk({
|
|
430
|
+
type: String
|
|
431
|
+
}), uuid(), __metadata("design:type", String) ], RolePermission.prototype, "id", void 0);
|
|
432
|
+
|
|
433
|
+
__decorate([ manyToOne(() => Role, REL_CASCADE_DEPENDENT, false, undefined, "fk_role_permissions_role"), required(), __metadata("design:type", Object) ], RolePermission.prototype, "role", void 0);
|
|
434
|
+
|
|
435
|
+
__decorate([ manyToOne(() => Permission, REL_CASCADE_DEPENDENT, false, undefined, "fk_role_permissions_permission"), required(), __metadata("design:type", Object) ], RolePermission.prototype, "permission", void 0);
|
|
436
|
+
|
|
437
|
+
__decorate([ createdAt(), __metadata("design:type", Date) ], RolePermission.prototype, "createdAt", void 0);
|
|
438
|
+
|
|
439
|
+
RolePermission = __decorate([ table("role_permissions"), model(), __metadata("design:paramtypes", [ Object ]) ], RolePermission);
|
|
440
|
+
|
|
441
|
+
let Role = class Role extends AuthorizationModel {
|
|
442
|
+
constructor(data) {
|
|
443
|
+
super(data);
|
|
444
|
+
}
|
|
445
|
+
};
|
|
446
|
+
|
|
447
|
+
__decorate([ pk({
|
|
448
|
+
type: String
|
|
449
|
+
}), uuid(), __metadata("design:type", String) ], Role.prototype, "id", void 0);
|
|
450
|
+
|
|
451
|
+
__decorate([ manyToOne(() => Tenant, REL_NULLIFY, false, undefined, "fk_roles_tenant"), __metadata("design:type", Object) ], Role.prototype, "tenant", void 0);
|
|
452
|
+
|
|
453
|
+
__decorate([ required(), type(String), column(), __metadata("design:type", String) ], Role.prototype, "key", void 0);
|
|
454
|
+
|
|
455
|
+
__decorate([ required(), type(String), column(), __metadata("design:type", String) ], Role.prototype, "name", void 0);
|
|
456
|
+
|
|
457
|
+
__decorate([ type(String), column(), __metadata("design:type", String) ], Role.prototype, "description", void 0);
|
|
458
|
+
|
|
459
|
+
__decorate([ type(Object), column(), __metadata("design:type", Object) ], Role.prototype, "metadata", void 0);
|
|
460
|
+
|
|
461
|
+
__decorate([ oneToMany(() => RolePermission, REL_RESTRICT, false), __metadata("design:type", Array) ], Role.prototype, "rolePermissions", void 0);
|
|
462
|
+
|
|
463
|
+
__decorate([ oneToMany(() => RoleAssignment, REL_RESTRICT, false), __metadata("design:type", Array) ], Role.prototype, "assignments", void 0);
|
|
464
|
+
|
|
465
|
+
__decorate([ createdAt(), __metadata("design:type", Date) ], Role.prototype, "createdAt", void 0);
|
|
466
|
+
|
|
467
|
+
__decorate([ updatedAt(), __metadata("design:type", Date) ], Role.prototype, "updatedAt", void 0);
|
|
468
|
+
|
|
469
|
+
Role = __decorate([ table("roles"), model(), __metadata("design:paramtypes", [ Object ]) ], Role);
|
|
470
|
+
|
|
471
|
+
let RoleAssignment = class RoleAssignment extends AuthorizationModel {
|
|
472
|
+
constructor(data) {
|
|
473
|
+
super(data);
|
|
474
|
+
}
|
|
475
|
+
};
|
|
476
|
+
|
|
477
|
+
__decorate([ pk({
|
|
478
|
+
type: String
|
|
479
|
+
}), uuid(), __metadata("design:type", String) ], RoleAssignment.prototype, "id", void 0);
|
|
480
|
+
|
|
481
|
+
__decorate([ manyToOne(() => Tenant, REL_CASCADE_DEPENDENT, false, undefined, "fk_role_assignments_tenant"), required(), __metadata("design:type", Object) ], RoleAssignment.prototype, "tenant", void 0);
|
|
482
|
+
|
|
483
|
+
__decorate([ manyToOne(() => Principal, REL_CASCADE_DEPENDENT, false, undefined, "fk_role_assignments_principal"), required(), __metadata("design:type", Object) ], RoleAssignment.prototype, "principal", void 0);
|
|
484
|
+
|
|
485
|
+
__decorate([ manyToOne(() => Role, REL_RESTRICT, false, undefined, "fk_role_assignments_role"), required(), __metadata("design:type", Object) ], RoleAssignment.prototype, "role", void 0);
|
|
486
|
+
|
|
487
|
+
__decorate([ required(), type(String), option(ScopeKindOptions), column(), __metadata("design:type", String) ], RoleAssignment.prototype, "scopeKind", void 0);
|
|
488
|
+
|
|
489
|
+
__decorate([ required(), type(String), column(), __metadata("design:type", String) ], RoleAssignment.prototype, "scopeId", void 0);
|
|
490
|
+
|
|
491
|
+
__decorate([ required(), type(Boolean), column(), __metadata("design:type", Boolean) ], RoleAssignment.prototype, "inheritDown", void 0);
|
|
492
|
+
|
|
493
|
+
__decorate([ column(), __metadata("design:type", Date) ], RoleAssignment.prototype, "startsAt", void 0);
|
|
494
|
+
|
|
495
|
+
__decorate([ column(), __metadata("design:type", Date) ], RoleAssignment.prototype, "expiresAt", void 0);
|
|
496
|
+
|
|
497
|
+
__decorate([ type(Object), column(), __metadata("design:type", Object) ], RoleAssignment.prototype, "conditions", void 0);
|
|
498
|
+
|
|
499
|
+
__decorate([ createdAt(), __metadata("design:type", Date) ], RoleAssignment.prototype, "createdAt", void 0);
|
|
500
|
+
|
|
501
|
+
__decorate([ updatedAt(), __metadata("design:type", Date) ], RoleAssignment.prototype, "updatedAt", void 0);
|
|
502
|
+
|
|
503
|
+
RoleAssignment = __decorate([ table("role_assignments"), model(), __metadata("design:paramtypes", [ Object ]) ], RoleAssignment);
|
|
504
|
+
|
|
505
|
+
let ResourceGrant = class ResourceGrant extends AuthorizationModel {
|
|
506
|
+
constructor(data) {
|
|
507
|
+
super(data);
|
|
508
|
+
}
|
|
509
|
+
};
|
|
510
|
+
|
|
511
|
+
__decorate([ pk({
|
|
512
|
+
type: String
|
|
513
|
+
}), uuid(), __metadata("design:type", String) ], ResourceGrant.prototype, "id", void 0);
|
|
514
|
+
|
|
515
|
+
__decorate([ manyToOne(() => Tenant, REL_CASCADE_DEPENDENT, false, undefined, "fk_resource_grants_tenant"), required(), __metadata("design:type", Object) ], ResourceGrant.prototype, "tenant", void 0);
|
|
516
|
+
|
|
517
|
+
__decorate([ manyToOne(() => ProtectedResource, REL_CASCADE_DEPENDENT, false, undefined, "fk_resource_grants_resource"), required(), __metadata("design:type", Object) ], ResourceGrant.prototype, "resource", void 0);
|
|
518
|
+
|
|
519
|
+
__decorate([ manyToOne(() => Principal, REL_CASCADE_DEPENDENT, false, undefined, "fk_resource_grants_principal"), required(), __metadata("design:type", Object) ], ResourceGrant.prototype, "principal", void 0);
|
|
520
|
+
|
|
521
|
+
__decorate([ required(), type(String), column(), __metadata("design:type", String) ], ResourceGrant.prototype, "permissionKey", void 0);
|
|
522
|
+
|
|
523
|
+
__decorate([ column(), __metadata("design:type", Date) ], ResourceGrant.prototype, "startsAt", void 0);
|
|
524
|
+
|
|
525
|
+
__decorate([ column(), __metadata("design:type", Date) ], ResourceGrant.prototype, "expiresAt", void 0);
|
|
526
|
+
|
|
527
|
+
__decorate([ type(Object), column(), __metadata("design:type", Object) ], ResourceGrant.prototype, "conditions", void 0);
|
|
528
|
+
|
|
529
|
+
__decorate([ manyToOne(() => Principal, REL_RESTRICT, false, undefined, "fk_resource_grants_created_by"), __metadata("design:type", Object) ], ResourceGrant.prototype, "createdBy", void 0);
|
|
530
|
+
|
|
531
|
+
__decorate([ createdAt(), __metadata("design:type", Date) ], ResourceGrant.prototype, "createdAt", void 0);
|
|
532
|
+
|
|
533
|
+
__decorate([ updatedAt(), __metadata("design:type", Date) ], ResourceGrant.prototype, "updatedAt", void 0);
|
|
534
|
+
|
|
535
|
+
ResourceGrant = __decorate([ table("resource_grants"), model(), __metadata("design:paramtypes", [ Object ]) ], ResourceGrant);
|
|
536
|
+
|
|
537
|
+
let Principal = class Principal extends AuthorizationModel {
|
|
538
|
+
constructor(data) {
|
|
539
|
+
super(data);
|
|
540
|
+
}
|
|
541
|
+
};
|
|
542
|
+
|
|
543
|
+
__decorate([ pk({
|
|
544
|
+
type: String
|
|
545
|
+
}), uuid(), __metadata("design:type", String) ], Principal.prototype, "id", void 0);
|
|
546
|
+
|
|
547
|
+
__decorate([ manyToOne(() => Tenant, REL_RESTRICT, false, undefined, "fk_principals_tenant"), required(), __metadata("design:type", Object) ], Principal.prototype, "tenant", void 0);
|
|
548
|
+
|
|
549
|
+
__decorate([ required(), type(String), option(PrincipalKindOptions), column(), __metadata("design:type", String) ], Principal.prototype, "kind", void 0);
|
|
550
|
+
|
|
551
|
+
__decorate([ required(), type(String), column(), __metadata("design:type", String) ], Principal.prototype, "subjectId", void 0);
|
|
552
|
+
|
|
553
|
+
__decorate([ oneToMany(() => RoleAssignment, REL_RESTRICT, false), __metadata("design:type", Array) ], Principal.prototype, "roleAssignments", void 0);
|
|
554
|
+
|
|
555
|
+
__decorate([ oneToMany(() => ResourceGrant, REL_RESTRICT, false), __metadata("design:type", Array) ], Principal.prototype, "resourceGrants", void 0);
|
|
556
|
+
|
|
557
|
+
__decorate([ createdAt(), __metadata("design:type", Date) ], Principal.prototype, "createdAt", void 0);
|
|
558
|
+
|
|
559
|
+
__decorate([ updatedAt(), __metadata("design:type", Date) ], Principal.prototype, "updatedAt", void 0);
|
|
560
|
+
|
|
561
|
+
Principal = __decorate([ table("principals"), model(), __metadata("design:paramtypes", [ Object ]) ], Principal);
|
|
562
|
+
|
|
563
|
+
let ProtectedResource = class ProtectedResource extends AuthorizationModel {
|
|
564
|
+
constructor(data) {
|
|
565
|
+
super(data);
|
|
566
|
+
}
|
|
567
|
+
};
|
|
568
|
+
|
|
569
|
+
__decorate([ pk({
|
|
570
|
+
type: String
|
|
571
|
+
}), uuid(), __metadata("design:type", String) ], ProtectedResource.prototype, "id", void 0);
|
|
572
|
+
|
|
573
|
+
__decorate([ manyToOne(() => Tenant, REL_RESTRICT, false, undefined, "fk_protected_resources_tenant"), required(), __metadata("design:type", Object) ], ProtectedResource.prototype, "tenant", void 0);
|
|
574
|
+
|
|
575
|
+
__decorate([ manyToOne(() => OrgUnit, REL_RESTRICT, false, undefined, "fk_protected_resources_org_unit"), required(), __metadata("design:type", Object) ], ProtectedResource.prototype, "orgUnit", void 0);
|
|
576
|
+
|
|
577
|
+
__decorate([ required(), type(String), column(), __metadata("design:type", String) ], ProtectedResource.prototype, "resourceType", void 0);
|
|
578
|
+
|
|
579
|
+
__decorate([ required(), type(String), column(), __metadata("design:type", String) ], ProtectedResource.prototype, "resourceId", void 0);
|
|
580
|
+
|
|
581
|
+
__decorate([ required(), type(String), option(ResourceVisibilityOptions), column(), __metadata("design:type", String) ], ProtectedResource.prototype, "visibility", void 0);
|
|
582
|
+
|
|
583
|
+
__decorate([ manyToOne(() => Principal, REL_NULLIFY, false, undefined, "fk_protected_resources_owner"), __metadata("design:type", Object) ], ProtectedResource.prototype, "owner", void 0);
|
|
584
|
+
|
|
585
|
+
__decorate([ type(String), column(), __metadata("design:type", String) ], ProtectedResource.prototype, "sensitivity", void 0);
|
|
586
|
+
|
|
587
|
+
__decorate([ type(Object), column(), __metadata("design:type", Object) ], ProtectedResource.prototype, "metadata", void 0);
|
|
588
|
+
|
|
589
|
+
__decorate([ oneToMany(() => ResourceGrant, REL_RESTRICT, false), __metadata("design:type", Array) ], ProtectedResource.prototype, "grants", void 0);
|
|
590
|
+
|
|
591
|
+
__decorate([ createdAt(), __metadata("design:type", Date) ], ProtectedResource.prototype, "createdAt", void 0);
|
|
592
|
+
|
|
593
|
+
__decorate([ updatedAt(), __metadata("design:type", Date) ], ProtectedResource.prototype, "updatedAt", void 0);
|
|
594
|
+
|
|
595
|
+
ProtectedResource = __decorate([ table("protected_resources"), model(), __metadata("design:paramtypes", [ Object ]) ], ProtectedResource);
|
|
596
|
+
|
|
597
|
+
let InheritanceBlock = class InheritanceBlock extends AuthorizationModel {
|
|
598
|
+
constructor(data) {
|
|
599
|
+
super(data);
|
|
600
|
+
}
|
|
601
|
+
};
|
|
602
|
+
|
|
603
|
+
__decorate([ pk({
|
|
604
|
+
type: String
|
|
605
|
+
}), uuid(), __metadata("design:type", String) ], InheritanceBlock.prototype, "id", void 0);
|
|
606
|
+
|
|
607
|
+
__decorate([ manyToOne(() => Tenant, REL_CASCADE_DEPENDENT, false, undefined, "fk_inheritance_blocks_tenant"), required(), __metadata("design:type", Object) ], InheritanceBlock.prototype, "tenant", void 0);
|
|
608
|
+
|
|
609
|
+
__decorate([ manyToOne(() => OrgUnit, REL_CASCADE_DEPENDENT, false, undefined, "fk_inheritance_blocks_org_unit"), required(), __metadata("design:type", Object) ], InheritanceBlock.prototype, "orgUnit", void 0);
|
|
610
|
+
|
|
611
|
+
__decorate([ manyToOne(() => OrgUnit, REL_NULLIFY, false, undefined, "fk_inheritance_blocks_blocked_ancestor"), __metadata("design:type", Object) ], InheritanceBlock.prototype, "blockedFromAncestor", void 0);
|
|
612
|
+
|
|
613
|
+
__decorate([ required(), type(String), option(PermissionCategoryOptions), column(), __metadata("design:type", String) ], InheritanceBlock.prototype, "permissionCategory", void 0);
|
|
614
|
+
|
|
615
|
+
__decorate([ type(String), column(), __metadata("design:type", String) ], InheritanceBlock.prototype, "reason", void 0);
|
|
616
|
+
|
|
617
|
+
__decorate([ createdAt(), __metadata("design:type", Date) ], InheritanceBlock.prototype, "createdAt", void 0);
|
|
618
|
+
|
|
619
|
+
__decorate([ updatedAt(), __metadata("design:type", Date) ], InheritanceBlock.prototype, "updatedAt", void 0);
|
|
620
|
+
|
|
621
|
+
InheritanceBlock = __decorate([ table("inheritance_blocks"), model(), __metadata("design:paramtypes", [ Object ]) ], InheritanceBlock);
|
|
622
|
+
|
|
623
|
+
let OrgUnit = class OrgUnit extends AuthorizationModel {
|
|
624
|
+
constructor(data) {
|
|
625
|
+
super(data);
|
|
626
|
+
}
|
|
627
|
+
};
|
|
628
|
+
|
|
629
|
+
__decorate([ pk({
|
|
630
|
+
type: String
|
|
631
|
+
}), uuid(), __metadata("design:type", String) ], OrgUnit.prototype, "id", void 0);
|
|
632
|
+
|
|
633
|
+
__decorate([ manyToOne(() => Tenant, REL_RESTRICT, false, undefined, "fk_org_units_tenant"), required(), __metadata("design:type", Object) ], OrgUnit.prototype, "tenant", void 0);
|
|
634
|
+
|
|
635
|
+
__decorate([ manyToOne(() => OrgUnit, REL_RESTRICT, false, undefined, "fk_org_units_parent"), __metadata("design:type", Object) ], OrgUnit.prototype, "parent", void 0);
|
|
636
|
+
|
|
637
|
+
__decorate([ oneToMany(() => OrgUnit, REL_RESTRICT, false), __metadata("design:type", Array) ], OrgUnit.prototype, "children", void 0);
|
|
638
|
+
|
|
639
|
+
__decorate([ required(), type(String), column(), __metadata("design:type", String) ], OrgUnit.prototype, "name", void 0);
|
|
640
|
+
|
|
641
|
+
__decorate([ required(), type(String), column(), __metadata("design:type", String) ], OrgUnit.prototype, "path", void 0);
|
|
642
|
+
|
|
643
|
+
__decorate([ type(Object), column(), __metadata("design:type", Object) ], OrgUnit.prototype, "metadata", void 0);
|
|
644
|
+
|
|
645
|
+
__decorate([ oneToMany(() => OrgUnitMembership, REL_RESTRICT, false), __metadata("design:type", Array) ], OrgUnit.prototype, "memberships", void 0);
|
|
646
|
+
|
|
647
|
+
__decorate([ oneToMany(() => ProtectedResource, REL_RESTRICT, false), __metadata("design:type", Array) ], OrgUnit.prototype, "resources", void 0);
|
|
648
|
+
|
|
649
|
+
__decorate([ oneToMany(() => InheritanceBlock, REL_RESTRICT, false), __metadata("design:type", Array) ], OrgUnit.prototype, "inheritanceBlocks", void 0);
|
|
650
|
+
|
|
651
|
+
__decorate([ oneToMany(() => OrgUnitClosure, REL_RESTRICT, false), __metadata("design:type", Array) ], OrgUnit.prototype, "ancestorLinks", void 0);
|
|
652
|
+
|
|
653
|
+
__decorate([ oneToMany(() => OrgUnitClosure, REL_RESTRICT, false), __metadata("design:type", Array) ], OrgUnit.prototype, "descendantLinks", void 0);
|
|
654
|
+
|
|
655
|
+
__decorate([ createdAt(), __metadata("design:type", Date) ], OrgUnit.prototype, "createdAt", void 0);
|
|
656
|
+
|
|
657
|
+
__decorate([ updatedAt(), __metadata("design:type", Date) ], OrgUnit.prototype, "updatedAt", void 0);
|
|
658
|
+
|
|
659
|
+
OrgUnit = __decorate([ table("org_units"), model(), __metadata("design:paramtypes", [ Object ]) ], OrgUnit);
|
|
660
|
+
|
|
661
|
+
let StorageBinding = class StorageBinding extends AuthorizationModel {
|
|
662
|
+
constructor(data) {
|
|
663
|
+
super(data);
|
|
664
|
+
}
|
|
665
|
+
};
|
|
666
|
+
|
|
667
|
+
__decorate([ pk({
|
|
668
|
+
type: String
|
|
669
|
+
}), uuid(), __metadata("design:type", String) ], StorageBinding.prototype, "id", void 0);
|
|
670
|
+
|
|
671
|
+
__decorate([ manyToOne(() => Tenant, REL_CASCADE_DEPENDENT, false, undefined, "fk_storage_bindings_tenant"), required(), __metadata("design:type", Object) ], StorageBinding.prototype, "tenant", void 0);
|
|
672
|
+
|
|
673
|
+
__decorate([ required(), type(String), option(StorageKindOptions), column(), __metadata("design:type", String) ], StorageBinding.prototype, "storageKind", void 0);
|
|
674
|
+
|
|
675
|
+
__decorate([ required(), type(String), option(StorageBindingKindOptions), column(), __metadata("design:type", String) ], StorageBinding.prototype, "bindingKind", void 0);
|
|
676
|
+
|
|
677
|
+
__decorate([ required(), type(String), column(), __metadata("design:type", String) ], StorageBinding.prototype, "bindingKey", void 0);
|
|
678
|
+
|
|
679
|
+
__decorate([ required(), type(String), column(), __metadata("design:type", String) ], StorageBinding.prototype, "region", void 0);
|
|
680
|
+
|
|
681
|
+
__decorate([ type(Object), column(), __metadata("design:type", Object) ], StorageBinding.prototype, "config", void 0);
|
|
682
|
+
|
|
683
|
+
__decorate([ createdAt(), __metadata("design:type", Date) ], StorageBinding.prototype, "createdAt", void 0);
|
|
684
|
+
|
|
685
|
+
__decorate([ updatedAt(), __metadata("design:type", Date) ], StorageBinding.prototype, "updatedAt", void 0);
|
|
686
|
+
|
|
687
|
+
StorageBinding = __decorate([ table("storage_bindings"), model(), __metadata("design:paramtypes", [ Object ]) ], StorageBinding);
|
|
688
|
+
|
|
689
|
+
let Tenant = class Tenant extends AuthorizationModel {
|
|
690
|
+
constructor(data) {
|
|
691
|
+
super(data);
|
|
692
|
+
}
|
|
693
|
+
};
|
|
694
|
+
|
|
695
|
+
__decorate([ pk({
|
|
696
|
+
type: String
|
|
697
|
+
}), uuid(), __metadata("design:type", String) ], Tenant.prototype, "id", void 0);
|
|
698
|
+
|
|
699
|
+
__decorate([ unique(), required(), type(String), column(), __metadata("design:type", String) ], Tenant.prototype, "slug", void 0);
|
|
700
|
+
|
|
701
|
+
__decorate([ required(), type(String), column(), __metadata("design:type", String) ], Tenant.prototype, "name", void 0);
|
|
702
|
+
|
|
703
|
+
__decorate([ required(), type(String), option(IsolationTierOptions), column(), __metadata("design:type", String) ], Tenant.prototype, "isolationTier", void 0);
|
|
704
|
+
|
|
705
|
+
__decorate([ oneToMany(() => OrgUnit, REL_RESTRICT, false), __metadata("design:type", Array) ], Tenant.prototype, "orgUnits", void 0);
|
|
706
|
+
|
|
707
|
+
__decorate([ oneToMany(() => TenantMembership, REL_RESTRICT, false), __metadata("design:type", Array) ], Tenant.prototype, "memberships", void 0);
|
|
708
|
+
|
|
709
|
+
__decorate([ oneToMany(() => Principal, REL_RESTRICT, false), __metadata("design:type", Array) ], Tenant.prototype, "principals", void 0);
|
|
710
|
+
|
|
711
|
+
__decorate([ oneToMany(() => StorageBinding, REL_RESTRICT, false), __metadata("design:type", Array) ], Tenant.prototype, "storageBindings", void 0);
|
|
712
|
+
|
|
713
|
+
__decorate([ createdAt(), __metadata("design:type", Date) ], Tenant.prototype, "createdAt", void 0);
|
|
714
|
+
|
|
715
|
+
__decorate([ updatedAt(), __metadata("design:type", Date) ], Tenant.prototype, "updatedAt", void 0);
|
|
716
|
+
|
|
717
|
+
Tenant = __decorate([ table("tenants"), model(), __metadata("design:paramtypes", [ Object ]) ], Tenant);
|
|
718
|
+
|
|
719
|
+
let TenantProfile = class TenantProfile extends AuthorizationModel {
|
|
720
|
+
constructor(data) {
|
|
721
|
+
super(data);
|
|
722
|
+
}
|
|
723
|
+
};
|
|
724
|
+
|
|
725
|
+
__decorate([ pk({
|
|
726
|
+
type: String
|
|
727
|
+
}), uuid(), __metadata("design:type", String) ], TenantProfile.prototype, "id", void 0);
|
|
728
|
+
|
|
729
|
+
__decorate([ manyToOne(() => Tenant, REL_CASCADE_DEPENDENT, false, undefined, "fk_tenant_profiles_tenant"), required(), __metadata("design:type", Object) ], TenantProfile.prototype, "tenant", void 0);
|
|
730
|
+
|
|
731
|
+
__decorate([ required(), type(String), column(), __metadata("design:type", String) ], TenantProfile.prototype, "profileKey", void 0);
|
|
732
|
+
|
|
733
|
+
__decorate([ type(Object), column(), __metadata("design:type", Object) ], TenantProfile.prototype, "metadata", void 0);
|
|
734
|
+
|
|
735
|
+
__decorate([ createdAt(), __metadata("design:type", Date) ], TenantProfile.prototype, "createdAt", void 0);
|
|
736
|
+
|
|
737
|
+
__decorate([ updatedAt(), __metadata("design:type", Date) ], TenantProfile.prototype, "updatedAt", void 0);
|
|
738
|
+
|
|
739
|
+
TenantProfile = __decorate([ table("tenant_profiles"), model(), __metadata("design:paramtypes", [ Object ]) ], TenantProfile);
|
|
740
|
+
|
|
741
|
+
let OrgUnitProfile = class OrgUnitProfile extends AuthorizationModel {
|
|
742
|
+
constructor(data) {
|
|
743
|
+
super(data);
|
|
744
|
+
}
|
|
745
|
+
};
|
|
746
|
+
|
|
747
|
+
__decorate([ pk({
|
|
748
|
+
type: String
|
|
749
|
+
}), uuid(), __metadata("design:type", String) ], OrgUnitProfile.prototype, "id", void 0);
|
|
750
|
+
|
|
751
|
+
__decorate([ manyToOne(() => OrgUnit, REL_CASCADE_DEPENDENT, false, undefined, "fk_org_unit_profiles_org_unit"), required(), __metadata("design:type", Object) ], OrgUnitProfile.prototype, "orgUnit", void 0);
|
|
752
|
+
|
|
753
|
+
__decorate([ required(), type(String), column(), __metadata("design:type", String) ], OrgUnitProfile.prototype, "profileKey", void 0);
|
|
754
|
+
|
|
755
|
+
__decorate([ type(Object), column(), __metadata("design:type", Object) ], OrgUnitProfile.prototype, "metadata", void 0);
|
|
756
|
+
|
|
757
|
+
__decorate([ createdAt(), __metadata("design:type", Date) ], OrgUnitProfile.prototype, "createdAt", void 0);
|
|
758
|
+
|
|
759
|
+
__decorate([ updatedAt(), __metadata("design:type", Date) ], OrgUnitProfile.prototype, "updatedAt", void 0);
|
|
760
|
+
|
|
761
|
+
OrgUnitProfile = __decorate([ table("org_unit_profiles"), model(), __metadata("design:paramtypes", [ Object ]) ], OrgUnitProfile);
|
|
762
|
+
|
|
763
|
+
let GroupMembership = class GroupMembership extends AuthorizationModel {
|
|
764
|
+
constructor(data) {
|
|
765
|
+
super(data);
|
|
766
|
+
}
|
|
767
|
+
};
|
|
768
|
+
|
|
769
|
+
__decorate([ pk({
|
|
770
|
+
type: String
|
|
771
|
+
}), uuid(), __metadata("design:type", String) ], GroupMembership.prototype, "id", void 0);
|
|
772
|
+
|
|
773
|
+
__decorate([ manyToOne(() => Tenant, REL_CASCADE_DEPENDENT, false, undefined, "fk_group_memberships_tenant"), required(), __metadata("design:type", Object) ], GroupMembership.prototype, "tenant", void 0);
|
|
774
|
+
|
|
775
|
+
__decorate([ manyToOne(() => Group, REL_CASCADE_DEPENDENT, false, undefined, "fk_group_memberships_group"), required(), __metadata("design:type", Object) ], GroupMembership.prototype, "group", void 0);
|
|
776
|
+
|
|
777
|
+
__decorate([ manyToOne(() => Principal, REL_CASCADE_DEPENDENT, false, undefined, "fk_group_memberships_principal"), required(), __metadata("design:type", Object) ], GroupMembership.prototype, "principal", void 0);
|
|
778
|
+
|
|
779
|
+
__decorate([ type(Object), column(), __metadata("design:type", Object) ], GroupMembership.prototype, "metadata", void 0);
|
|
780
|
+
|
|
781
|
+
__decorate([ createdAt(), __metadata("design:type", Date) ], GroupMembership.prototype, "createdAt", void 0);
|
|
782
|
+
|
|
783
|
+
GroupMembership = __decorate([ table("group_memberships"), model(), __metadata("design:paramtypes", [ Object ]) ], GroupMembership);
|
|
784
|
+
|
|
785
|
+
let Group = class Group extends AuthorizationModel {
|
|
786
|
+
constructor(data) {
|
|
787
|
+
super(data);
|
|
788
|
+
}
|
|
789
|
+
};
|
|
790
|
+
|
|
791
|
+
__decorate([ pk({
|
|
792
|
+
type: String
|
|
793
|
+
}), uuid(), __metadata("design:type", String) ], Group.prototype, "id", void 0);
|
|
794
|
+
|
|
795
|
+
__decorate([ manyToOne(() => Tenant, REL_RESTRICT, false, undefined, "fk_groups_tenant"), required(), __metadata("design:type", Object) ], Group.prototype, "tenant", void 0);
|
|
796
|
+
|
|
797
|
+
__decorate([ manyToOne(() => OrgUnit, REL_NULLIFY, false, undefined, "fk_groups_org_unit"), __metadata("design:type", Object) ], Group.prototype, "orgUnit", void 0);
|
|
798
|
+
|
|
799
|
+
__decorate([ required(), type(String), column(), __metadata("design:type", String) ], Group.prototype, "name", void 0);
|
|
800
|
+
|
|
801
|
+
__decorate([ type(Object), column(), __metadata("design:type", Object) ], Group.prototype, "metadata", void 0);
|
|
802
|
+
|
|
803
|
+
__decorate([ oneToMany(() => GroupMembership, REL_RESTRICT, false), __metadata("design:type", Array) ], Group.prototype, "members", void 0);
|
|
804
|
+
|
|
805
|
+
__decorate([ createdAt(), __metadata("design:type", Date) ], Group.prototype, "createdAt", void 0);
|
|
806
|
+
|
|
807
|
+
__decorate([ updatedAt(), __metadata("design:type", Date) ], Group.prototype, "updatedAt", void 0);
|
|
808
|
+
|
|
809
|
+
Group = __decorate([ table("groups"), model(), __metadata("design:paramtypes", [ Object ]) ], Group);
|
|
810
|
+
|
|
811
|
+
let EffectivePermission = class EffectivePermission extends AuthorizationModel {
|
|
812
|
+
constructor(data) {
|
|
813
|
+
super(data);
|
|
814
|
+
}
|
|
815
|
+
};
|
|
816
|
+
|
|
817
|
+
__decorate([ pk({
|
|
818
|
+
type: String
|
|
819
|
+
}), uuid(), __metadata("design:type", String) ], EffectivePermission.prototype, "id", void 0);
|
|
820
|
+
|
|
821
|
+
__decorate([ manyToOne(() => Tenant, REL_CASCADE_DEPENDENT, false, undefined, "fk_effective_permissions_tenant"), required(), __metadata("design:type", Object) ], EffectivePermission.prototype, "tenant", void 0);
|
|
822
|
+
|
|
823
|
+
__decorate([ manyToOne(() => Principal, REL_CASCADE_DEPENDENT, false, undefined, "fk_effective_permissions_principal"), required(), __metadata("design:type", Object) ], EffectivePermission.prototype, "principal", void 0);
|
|
824
|
+
|
|
825
|
+
__decorate([ required(), type(String), column(), __metadata("design:type", String) ], EffectivePermission.prototype, "permissionKey", void 0);
|
|
826
|
+
|
|
827
|
+
__decorate([ required(), type(String), option(ScopeKindOptions), column(), __metadata("design:type", String) ], EffectivePermission.prototype, "scopeKind", void 0);
|
|
828
|
+
|
|
829
|
+
__decorate([ required(), type(String), column(), __metadata("design:type", String) ], EffectivePermission.prototype, "scopeId", void 0);
|
|
830
|
+
|
|
831
|
+
__decorate([ required(), type(String), column(), __metadata("design:type", String) ], EffectivePermission.prototype, "sourceKind", void 0);
|
|
832
|
+
|
|
833
|
+
__decorate([ required(), type(String), column(), __metadata("design:type", String) ], EffectivePermission.prototype, "sourceId", void 0);
|
|
834
|
+
|
|
835
|
+
__decorate([ column(), __metadata("design:type", Date) ], EffectivePermission.prototype, "startsAt", void 0);
|
|
836
|
+
|
|
837
|
+
__decorate([ column(), __metadata("design:type", Date) ], EffectivePermission.prototype, "expiresAt", void 0);
|
|
838
|
+
|
|
839
|
+
__decorate([ createdAt(), __metadata("design:type", Date) ], EffectivePermission.prototype, "createdAt", void 0);
|
|
840
|
+
|
|
841
|
+
EffectivePermission = __decorate([ table("effective_permissions"), model(), __metadata("design:paramtypes", [ Object ]) ], EffectivePermission);
|
|
842
|
+
|
|
843
|
+
class TenantProfileService extends BaseModelService {
|
|
844
|
+
constructor() {
|
|
845
|
+
super(TenantProfile);
|
|
846
|
+
}
|
|
847
|
+
async createProfile(tenantId, profileKey, metadata, ...args) {
|
|
848
|
+
return this.create({
|
|
849
|
+
tenant: tenantId,
|
|
850
|
+
profileKey: profileKey,
|
|
851
|
+
metadata: metadata
|
|
852
|
+
}, ...args);
|
|
853
|
+
}
|
|
854
|
+
async listForTenant(tenantId, ...args) {
|
|
855
|
+
return (await this.listAll(...args)).filter(profile => sameTenant(profile.tenant, tenantId));
|
|
856
|
+
}
|
|
857
|
+
async deleteForTenant(tenantId, ...args) {
|
|
858
|
+
for (const row of await this.listForTenant(tenantId, ...args)) {
|
|
859
|
+
await this.deleteById(row.id, ...args);
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
class OrgUnitProfileService extends BaseModelService {
|
|
865
|
+
constructor() {
|
|
866
|
+
super(OrgUnitProfile);
|
|
867
|
+
}
|
|
868
|
+
async createProfile(orgUnitId, profileKey, metadata, ...args) {
|
|
869
|
+
return this.create({
|
|
870
|
+
orgUnit: orgUnitId,
|
|
871
|
+
profileKey: profileKey,
|
|
872
|
+
metadata: metadata
|
|
873
|
+
}, ...args);
|
|
874
|
+
}
|
|
875
|
+
async listForOrgUnit(orgUnitId, ...args) {
|
|
876
|
+
return (await this.listAll(...args)).filter(profile => relationMatch(profile.orgUnit, orgUnitId));
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
class OrgUnitClosureService extends BaseModelService {
|
|
881
|
+
constructor() {
|
|
882
|
+
super(OrgUnitClosure);
|
|
883
|
+
}
|
|
884
|
+
async listAncestors(tenantId, orgUnitId, ...args) {
|
|
885
|
+
return (await this.listAll(...args)).filter(row => sameTenant(row.tenant, tenantId) && relationMatch(row.descendant, orgUnitId)).sort((left, right) => left.depth - right.depth);
|
|
886
|
+
}
|
|
887
|
+
async listDescendants(tenantId, orgUnitId, ...args) {
|
|
888
|
+
return (await this.listAll(...args)).filter(row => sameTenant(row.tenant, tenantId) && relationMatch(row.ancestor, orgUnitId)).sort((left, right) => left.depth - right.depth);
|
|
889
|
+
}
|
|
890
|
+
async isAncestorOf(tenantId, ancestorOrgUnitId, descendantOrgUnitId, ...args) {
|
|
891
|
+
return (await this.listAncestors(tenantId, descendantOrgUnitId, ...args)).some(row => relationMatch(row.ancestor, ancestorOrgUnitId));
|
|
892
|
+
}
|
|
893
|
+
async createSelfLink(tenantId, orgUnitId, ...args) {
|
|
894
|
+
return this.create({
|
|
895
|
+
tenant: tenantId,
|
|
896
|
+
ancestor: orgUnitId,
|
|
897
|
+
descendant: orgUnitId,
|
|
898
|
+
depth: 0
|
|
899
|
+
}, ...args);
|
|
900
|
+
}
|
|
901
|
+
async insertAncestorLinksForNewChild(tenantId, parentOrgUnitId, childOrgUnitId, ...args) {
|
|
902
|
+
const ancestorLinks = await this.listAncestors(tenantId, parentOrgUnitId, ...args);
|
|
903
|
+
for (const link of ancestorLinks) {
|
|
904
|
+
await this.create({
|
|
905
|
+
tenant: tenantId,
|
|
906
|
+
ancestor: link.ancestor,
|
|
907
|
+
descendant: childOrgUnitId,
|
|
908
|
+
depth: link.depth + 1
|
|
909
|
+
}, ...args);
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
async deleteLinksForSubtree(tenantId, orgUnitId, ...args) {
|
|
913
|
+
const subtree = await this.listDescendants(tenantId, orgUnitId, ...args);
|
|
914
|
+
const descendantIds = new Set([ orgUnitId, ...subtree.map(row => relationId(row.descendant)) ]);
|
|
915
|
+
const ancestorIds = new Set([ orgUnitId, ...subtree.map(row => relationId(row.ancestor)) ]);
|
|
916
|
+
const rows = (await this.listAll(...args)).filter(row => sameTenant(row.tenant, tenantId) && (descendantIds.has(relationId(row.descendant)) || ancestorIds.has(relationId(row.ancestor))));
|
|
917
|
+
for (const row of rows) {
|
|
918
|
+
await this.deleteById(row.id, ...args);
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
class InheritanceBlockService extends BaseModelService {
|
|
924
|
+
constructor() {
|
|
925
|
+
super(InheritanceBlock);
|
|
926
|
+
}
|
|
927
|
+
async blockCategory(tenantId, orgUnitId, permissionCategory, blockedFromAncestorId, reason, ...args) {
|
|
928
|
+
return this.create({
|
|
929
|
+
tenant: tenantId,
|
|
930
|
+
orgUnit: orgUnitId,
|
|
931
|
+
blockedFromAncestor: blockedFromAncestorId,
|
|
932
|
+
permissionCategory: permissionCategory,
|
|
933
|
+
reason: reason
|
|
934
|
+
}, ...args);
|
|
935
|
+
}
|
|
936
|
+
async unblockCategory(blockId, ...args) {
|
|
937
|
+
await this.deleteById(blockId, ...args);
|
|
938
|
+
}
|
|
939
|
+
async listForOrgUnit(tenantId, orgUnitId, ...args) {
|
|
940
|
+
return (await this.listAll(...args)).filter(block => sameTenant(block.tenant, tenantId) && relationMatch(block.orgUnit, orgUnitId));
|
|
941
|
+
}
|
|
942
|
+
async categoryBlockedForAncestor(tenantId, orgUnitId, ancestorOrgUnitId, category, ...args) {
|
|
943
|
+
return (await this.listForOrgUnit(tenantId, orgUnitId, ...args)).some(block => block.permissionCategory === category && (!block.blockedFromAncestor || relationMatch(block.blockedFromAncestor, ancestorOrgUnitId)));
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
class TenantService extends BaseModelService {
|
|
948
|
+
constructor() {
|
|
949
|
+
super(Tenant);
|
|
950
|
+
}
|
|
951
|
+
async createTenant(input, ...args) {
|
|
952
|
+
return this.create({
|
|
953
|
+
slug: input.slug,
|
|
954
|
+
name: input.name,
|
|
955
|
+
isolationTier: input.isolationTier ?? IsolationTier.Pooled
|
|
956
|
+
}, ...args);
|
|
957
|
+
}
|
|
958
|
+
async getBySlug(slug, ...args) {
|
|
959
|
+
return this.findOneBy("slug", slug, ...args);
|
|
960
|
+
}
|
|
961
|
+
async renameTenant(tenantId, name, ...args) {
|
|
962
|
+
return this.updateOne(tenantId, {
|
|
963
|
+
name: name
|
|
964
|
+
}, ...args);
|
|
965
|
+
}
|
|
966
|
+
async changeSlug(tenantId, slug, ...args) {
|
|
967
|
+
return this.updateOne(tenantId, {
|
|
968
|
+
slug: slug
|
|
969
|
+
}, ...args);
|
|
970
|
+
}
|
|
971
|
+
async setIsolationTier(tenantId, isolationTier, ...args) {
|
|
972
|
+
return this.updateOne(tenantId, {
|
|
973
|
+
isolationTier: isolationTier
|
|
974
|
+
}, ...args);
|
|
975
|
+
}
|
|
976
|
+
async deleteTenantControlled(tenantId, ...args) {
|
|
977
|
+
await this.deleteById(tenantId, ...args);
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
async function deleteRowsById$1(service, rows, ...args) {
|
|
982
|
+
for (const row of rows) {
|
|
983
|
+
await service.deleteById(row.id, ...args);
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
class OrgUnitService extends BaseModelService {
|
|
988
|
+
constructor() {
|
|
989
|
+
super(OrgUnit);
|
|
990
|
+
}
|
|
991
|
+
orgUnitPath(parentPath, name) {
|
|
992
|
+
const segment = lowerSlug(name);
|
|
993
|
+
return parentPath ? `${parentPath.replace(/\/+$/, "")}/${segment}` : `/${segment}`;
|
|
994
|
+
}
|
|
995
|
+
async createProfileIfNeeded(orgUnitId, profileKey, profileMetadata, ...args) {
|
|
996
|
+
if (!profileKey) return;
|
|
997
|
+
await (new OrgUnitProfileService).createProfile(orgUnitId, profileKey, profileMetadata, ...args);
|
|
998
|
+
}
|
|
999
|
+
async createRoot(tenantId, name, metadata, profileKey, profileMetadata, ...args) {
|
|
1000
|
+
const orgUnit = await this.create({
|
|
1001
|
+
tenant: tenantId,
|
|
1002
|
+
name: name,
|
|
1003
|
+
path: this.orgUnitPath(undefined, name),
|
|
1004
|
+
metadata: metadata
|
|
1005
|
+
}, ...args);
|
|
1006
|
+
await this.createProfileIfNeeded(orgUnit.id, profileKey, profileMetadata, ...args);
|
|
1007
|
+
await (new OrgUnitClosureService).createSelfLink(tenantId, orgUnit.id, ...args);
|
|
1008
|
+
return orgUnit;
|
|
1009
|
+
}
|
|
1010
|
+
async createChild(input, ...args) {
|
|
1011
|
+
const parent = input.parentOrgUnitId ? await this.getById(input.parentOrgUnitId, ...args) : undefined;
|
|
1012
|
+
const orgUnit = await this.create({
|
|
1013
|
+
tenant: input.tenantId,
|
|
1014
|
+
parent: parent?.id ?? input.parentOrgUnitId,
|
|
1015
|
+
name: input.name,
|
|
1016
|
+
path: this.orgUnitPath(parent?.path, input.name),
|
|
1017
|
+
metadata: input.metadata
|
|
1018
|
+
}, ...args);
|
|
1019
|
+
await this.createProfileIfNeeded(orgUnit.id, input.profileKey, input.profileMetadata, ...args);
|
|
1020
|
+
const closureService = new OrgUnitClosureService;
|
|
1021
|
+
await closureService.createSelfLink(input.tenantId, orgUnit.id, ...args);
|
|
1022
|
+
if (input.parentOrgUnitId) {
|
|
1023
|
+
await closureService.insertAncestorLinksForNewChild(input.tenantId, input.parentOrgUnitId, orgUnit.id, ...args);
|
|
1024
|
+
}
|
|
1025
|
+
return orgUnit;
|
|
1026
|
+
}
|
|
1027
|
+
async listChildren(parentOrgUnitId, ...args) {
|
|
1028
|
+
return (await this.listAll(...args)).filter(orgUnit => relationMatch(orgUnit.parent, parentOrgUnitId));
|
|
1029
|
+
}
|
|
1030
|
+
async listTenantOrgUnits(tenantId, ...args) {
|
|
1031
|
+
return (await this.listAll(...args)).filter(orgUnit => sameTenant(orgUnit.tenant, tenantId));
|
|
1032
|
+
}
|
|
1033
|
+
async listDescendantOrgUnits(tenantId, orgUnitId, includeSelf = false, ...args) {
|
|
1034
|
+
const descendants = await (new OrgUnitClosureService).listDescendants(tenantId, orgUnitId, ...args);
|
|
1035
|
+
const ids = new Set(descendants.map(row => relationId(row.descendant)));
|
|
1036
|
+
if (includeSelf) ids.add(orgUnitId);
|
|
1037
|
+
return (await this.listTenantOrgUnits(tenantId, ...args)).filter(orgUnit => ids.has(orgUnit.id));
|
|
1038
|
+
}
|
|
1039
|
+
async listAncestorOrgUnits(tenantId, orgUnitId, includeSelf = false, ...args) {
|
|
1040
|
+
const ancestors = await (new OrgUnitClosureService).listAncestors(tenantId, orgUnitId, ...args);
|
|
1041
|
+
const ids = new Set(ancestors.map(row => relationId(row.ancestor)));
|
|
1042
|
+
if (includeSelf) ids.add(orgUnitId);
|
|
1043
|
+
return (await this.listTenantOrgUnits(tenantId, ...args)).filter(orgUnit => ids.has(orgUnit.id));
|
|
1044
|
+
}
|
|
1045
|
+
async renameOrgUnit(orgUnitId, name, ...args) {
|
|
1046
|
+
const existing = await this.getById(orgUnitId, ...args);
|
|
1047
|
+
return this.updateOne(orgUnitId, {
|
|
1048
|
+
name: name,
|
|
1049
|
+
path: this.orgUnitPath(existing.path.includes("/") ? existing.path.replace(/\/[^/]+$/, "") : undefined, name)
|
|
1050
|
+
}, ...args);
|
|
1051
|
+
}
|
|
1052
|
+
async moveOrgUnit(tenantId, orgUnitId, newParentOrgUnitId, ...args) {
|
|
1053
|
+
const newParent = await this.getById(newParentOrgUnitId, ...args);
|
|
1054
|
+
const existing = await this.getById(orgUnitId, ...args);
|
|
1055
|
+
const updated = await this.updateOne(orgUnitId, {
|
|
1056
|
+
parent: newParent.id,
|
|
1057
|
+
path: this.orgUnitPath(newParent.path, existing.name)
|
|
1058
|
+
}, ...args);
|
|
1059
|
+
await this.rebuildTenantClosure(tenantId, ...args);
|
|
1060
|
+
return updated;
|
|
1061
|
+
}
|
|
1062
|
+
async rebuildTenantClosure(tenantId, ...args) {
|
|
1063
|
+
const closureService = new OrgUnitClosureService;
|
|
1064
|
+
const existingLinks = await closureService.listAll(...args);
|
|
1065
|
+
await deleteRowsById$1(closureService, existingLinks.filter(row => sameTenant(row.tenant, tenantId)), ...args);
|
|
1066
|
+
const orgUnits = (await this.listTenantOrgUnits(tenantId, ...args)).sort((left, right) => {
|
|
1067
|
+
const leftDepth = left.path.split("/").filter(Boolean).length;
|
|
1068
|
+
const rightDepth = right.path.split("/").filter(Boolean).length;
|
|
1069
|
+
return leftDepth - rightDepth;
|
|
1070
|
+
});
|
|
1071
|
+
for (const orgUnit of orgUnits) {
|
|
1072
|
+
await closureService.createSelfLink(tenantId, orgUnit.id, ...args);
|
|
1073
|
+
if (orgUnit.parent) {
|
|
1074
|
+
await closureService.insertAncestorLinksForNewChild(tenantId, relationId(orgUnit.parent), orgUnit.id, ...args);
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
async deleteOrgUnitTree(tenantId, orgUnitId, ...args) {
|
|
1079
|
+
const closureService = new OrgUnitClosureService;
|
|
1080
|
+
const descendants = await this.listDescendantOrgUnits(tenantId, orgUnitId, true, ...args);
|
|
1081
|
+
const descendantIds = new Set(descendants.map(orgUnit => orgUnit.id));
|
|
1082
|
+
const orgUnits = (await this.listTenantOrgUnits(tenantId, ...args)).filter(orgUnit => descendantIds.has(orgUnit.id));
|
|
1083
|
+
await deleteRowsById$1(this, orgUnits, ...args);
|
|
1084
|
+
await closureService.deleteLinksForSubtree(tenantId, orgUnitId, ...args);
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
__decorate([ transactional(), __metadata("design:type", Function), __metadata("design:paramtypes", [ String, String, Object, String, Object, Object ]), __metadata("design:returntype", Promise) ], OrgUnitService.prototype, "createRoot", null);
|
|
1089
|
+
|
|
1090
|
+
__decorate([ transactional(), __metadata("design:type", Function), __metadata("design:paramtypes", [ Object, Object ]), __metadata("design:returntype", Promise) ], OrgUnitService.prototype, "createChild", null);
|
|
1091
|
+
|
|
1092
|
+
__decorate([ transactional(), __metadata("design:type", Function), __metadata("design:paramtypes", [ String, String, String, Object ]), __metadata("design:returntype", Promise) ], OrgUnitService.prototype, "moveOrgUnit", null);
|
|
1093
|
+
|
|
1094
|
+
__decorate([ transactional(), __metadata("design:type", Function), __metadata("design:paramtypes", [ String, Object ]), __metadata("design:returntype", Promise) ], OrgUnitService.prototype, "rebuildTenantClosure", null);
|
|
1095
|
+
|
|
1096
|
+
__decorate([ transactional(), __metadata("design:type", Function), __metadata("design:paramtypes", [ String, String, Object ]), __metadata("design:returntype", Promise) ], OrgUnitService.prototype, "deleteOrgUnitTree", null);
|
|
1097
|
+
|
|
1098
|
+
class UserService extends BaseModelService {
|
|
1099
|
+
constructor() {
|
|
1100
|
+
super(User);
|
|
1101
|
+
}
|
|
1102
|
+
async createUser(input, ...args) {
|
|
1103
|
+
return this.create({
|
|
1104
|
+
email: input.email,
|
|
1105
|
+
phone: input.phone,
|
|
1106
|
+
displayName: input.displayName
|
|
1107
|
+
}, ...args);
|
|
1108
|
+
}
|
|
1109
|
+
async getByEmail(email, ...args) {
|
|
1110
|
+
return (await this.listAll(...args)).find(user => user.email === email);
|
|
1111
|
+
}
|
|
1112
|
+
async updateDisplayName(userId, displayName, ...args) {
|
|
1113
|
+
return this.updateOne(userId, {
|
|
1114
|
+
displayName: displayName
|
|
1115
|
+
}, ...args);
|
|
1116
|
+
}
|
|
1117
|
+
async updateEmail(userId, email, ...args) {
|
|
1118
|
+
return this.updateOne(userId, {
|
|
1119
|
+
email: email
|
|
1120
|
+
}, ...args);
|
|
1121
|
+
}
|
|
1122
|
+
async updatePhone(userId, phone, ...args) {
|
|
1123
|
+
return this.updateOne(userId, {
|
|
1124
|
+
phone: phone
|
|
1125
|
+
}, ...args);
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
class PrincipalService extends BaseModelService {
|
|
1130
|
+
constructor() {
|
|
1131
|
+
super(Principal);
|
|
1132
|
+
}
|
|
1133
|
+
async createPrincipal(tenantId, kind, subjectId, ...args) {
|
|
1134
|
+
return this.create({
|
|
1135
|
+
tenant: tenantId,
|
|
1136
|
+
kind: kind,
|
|
1137
|
+
subjectId: subjectId
|
|
1138
|
+
}, ...args);
|
|
1139
|
+
}
|
|
1140
|
+
async getForSubject(tenantId, kind, subjectId, ...args) {
|
|
1141
|
+
return (await this.listAll(...args)).find(principal => sameTenant(principal.tenant, tenantId) && principal.kind === kind && principal.subjectId === subjectId);
|
|
1142
|
+
}
|
|
1143
|
+
async getOrCreateForSubject(tenantId, kind, subjectId, ...args) {
|
|
1144
|
+
return await this.getForSubject(tenantId, kind, subjectId, ...args) ?? await this.createPrincipal(tenantId, kind, subjectId, ...args);
|
|
1145
|
+
}
|
|
1146
|
+
async getUserPrincipal(tenantId, userId, ...args) {
|
|
1147
|
+
return this.getOrCreateForSubject(tenantId, PrincipalKind.User, userId, ...args);
|
|
1148
|
+
}
|
|
1149
|
+
async getGroupPrincipal(tenantId, groupId, ...args) {
|
|
1150
|
+
return this.getOrCreateForSubject(tenantId, PrincipalKind.Group, groupId, ...args);
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
class TenantMembershipService extends BaseModelService {
|
|
1155
|
+
constructor() {
|
|
1156
|
+
super(TenantMembership);
|
|
1157
|
+
}
|
|
1158
|
+
async addUserToTenant(tenantId, userId, status = MembershipStatus.Active, ...args) {
|
|
1159
|
+
return this.create({
|
|
1160
|
+
tenant: tenantId,
|
|
1161
|
+
user: userId,
|
|
1162
|
+
status: status
|
|
1163
|
+
}, ...args);
|
|
1164
|
+
}
|
|
1165
|
+
async setStatus(membershipId, status, ...args) {
|
|
1166
|
+
return this.updateOne(membershipId, {
|
|
1167
|
+
status: status
|
|
1168
|
+
}, ...args);
|
|
1169
|
+
}
|
|
1170
|
+
async listUserTenants(userId, ...args) {
|
|
1171
|
+
return (await this.listAll(...args)).filter(membership => relationMatch(membership.user, userId));
|
|
1172
|
+
}
|
|
1173
|
+
async listTenantUsers(tenantId, ...args) {
|
|
1174
|
+
return (await this.listAll(...args)).filter(membership => sameTenant(membership.tenant, tenantId));
|
|
1175
|
+
}
|
|
1176
|
+
async removeUserFromTenant(membershipId, ...args) {
|
|
1177
|
+
await this.deleteById(membershipId, ...args);
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
class OrgUnitMembershipService extends BaseModelService {
|
|
1182
|
+
constructor() {
|
|
1183
|
+
super(OrgUnitMembership);
|
|
1184
|
+
}
|
|
1185
|
+
async addUserToOrgUnit(tenantId, orgUnitId, userId, status = MembershipStatus.Active, ...args) {
|
|
1186
|
+
return this.create({
|
|
1187
|
+
tenant: tenantId,
|
|
1188
|
+
orgUnit: orgUnitId,
|
|
1189
|
+
user: userId,
|
|
1190
|
+
status: status
|
|
1191
|
+
}, ...args);
|
|
1192
|
+
}
|
|
1193
|
+
async setStatus(membershipId, status, ...args) {
|
|
1194
|
+
return this.updateOne(membershipId, {
|
|
1195
|
+
status: status
|
|
1196
|
+
}, ...args);
|
|
1197
|
+
}
|
|
1198
|
+
async listUserOrgUnits(userId, ...args) {
|
|
1199
|
+
return (await this.listAll(...args)).filter(membership => relationMatch(membership.user, userId));
|
|
1200
|
+
}
|
|
1201
|
+
async listOrgUnitUsers(orgUnitId, ...args) {
|
|
1202
|
+
return (await this.listAll(...args)).filter(membership => relationMatch(membership.orgUnit, orgUnitId));
|
|
1203
|
+
}
|
|
1204
|
+
async removeUserFromOrgUnit(membershipId, ...args) {
|
|
1205
|
+
await this.deleteById(membershipId, ...args);
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
class GroupService extends BaseModelService {
|
|
1210
|
+
constructor() {
|
|
1211
|
+
super(Group);
|
|
1212
|
+
}
|
|
1213
|
+
async createGroup(tenantId, name, orgUnitId, metadata, ...args) {
|
|
1214
|
+
return this.create({
|
|
1215
|
+
tenant: tenantId,
|
|
1216
|
+
orgUnit: orgUnitId,
|
|
1217
|
+
name: name,
|
|
1218
|
+
metadata: metadata
|
|
1219
|
+
}, ...args);
|
|
1220
|
+
}
|
|
1221
|
+
async renameGroup(groupId, name, ...args) {
|
|
1222
|
+
return this.updateOne(groupId, {
|
|
1223
|
+
name: name
|
|
1224
|
+
}, ...args);
|
|
1225
|
+
}
|
|
1226
|
+
async moveGroupToOrgUnit(groupId, orgUnitId, ...args) {
|
|
1227
|
+
return this.updateOne(groupId, {
|
|
1228
|
+
orgUnit: orgUnitId
|
|
1229
|
+
}, ...args);
|
|
1230
|
+
}
|
|
1231
|
+
async listTenantGroups(tenantId, ...args) {
|
|
1232
|
+
return (await this.listAll(...args)).filter(group => sameTenant(group.tenant, tenantId));
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
class GroupMembershipService extends BaseModelService {
|
|
1237
|
+
constructor() {
|
|
1238
|
+
super(GroupMembership);
|
|
1239
|
+
}
|
|
1240
|
+
async addPrincipalToGroup(tenantId, groupId, principalId, metadata, ...args) {
|
|
1241
|
+
return this.create({
|
|
1242
|
+
tenant: tenantId,
|
|
1243
|
+
group: groupId,
|
|
1244
|
+
principal: principalId,
|
|
1245
|
+
metadata: metadata
|
|
1246
|
+
}, ...args);
|
|
1247
|
+
}
|
|
1248
|
+
async listGroupMembers(groupId, ...args) {
|
|
1249
|
+
return (await this.listAll(...args)).filter(membership => relationMatch(membership.group, groupId));
|
|
1250
|
+
}
|
|
1251
|
+
async listPrincipalGroups(principalId, ...args) {
|
|
1252
|
+
return (await this.listAll(...args)).filter(membership => relationMatch(membership.principal, principalId));
|
|
1253
|
+
}
|
|
1254
|
+
async removePrincipalFromGroup(membershipId, ...args) {
|
|
1255
|
+
await this.deleteById(membershipId, ...args);
|
|
1256
|
+
}
|
|
1257
|
+
async resolveGroupPrincipalIdsForPrincipal(principalId, ...args) {
|
|
1258
|
+
const principalService = new PrincipalService;
|
|
1259
|
+
const memberships = await this.listPrincipalGroups(principalId, ...args);
|
|
1260
|
+
const principals = await Promise.all(memberships.map(async membership => {
|
|
1261
|
+
const tenantId = relationId(membership.tenant);
|
|
1262
|
+
const groupId = relationId(membership.group);
|
|
1263
|
+
const principal = await principalService.getGroupPrincipal(tenantId, groupId, ...args);
|
|
1264
|
+
return principal.id;
|
|
1265
|
+
}));
|
|
1266
|
+
return principals;
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
class PermissionService extends BaseModelService {
|
|
1271
|
+
constructor() {
|
|
1272
|
+
super(Permission);
|
|
1273
|
+
}
|
|
1274
|
+
async createPermission(input, ...args) {
|
|
1275
|
+
return this.create({
|
|
1276
|
+
key: input.key,
|
|
1277
|
+
category: input.category,
|
|
1278
|
+
description: input.description
|
|
1279
|
+
}, ...args);
|
|
1280
|
+
}
|
|
1281
|
+
async getByKey(key, ...args) {
|
|
1282
|
+
return (await this.listAll(...args)).find(permission => permission.key === key);
|
|
1283
|
+
}
|
|
1284
|
+
async listByCategory(category, ...args) {
|
|
1285
|
+
return (await this.listAll(...args)).filter(permission => permission.category === category);
|
|
1286
|
+
}
|
|
1287
|
+
async updateDescription(permissionId, description, ...args) {
|
|
1288
|
+
return this.updateOne(permissionId, {
|
|
1289
|
+
description: description
|
|
1290
|
+
}, ...args);
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
class RoleService extends BaseModelService {
|
|
1295
|
+
constructor() {
|
|
1296
|
+
super(Role);
|
|
1297
|
+
}
|
|
1298
|
+
async createRole(input, ...args) {
|
|
1299
|
+
return this.create({
|
|
1300
|
+
tenant: input.tenantId,
|
|
1301
|
+
key: input.key,
|
|
1302
|
+
name: input.name,
|
|
1303
|
+
description: input.description,
|
|
1304
|
+
metadata: input.metadata
|
|
1305
|
+
}, ...args);
|
|
1306
|
+
}
|
|
1307
|
+
async getSystemRoleByKey(key, ...args) {
|
|
1308
|
+
const role = (await this.listAll(...args)).find(candidate => !candidate.tenant && candidate.key === key);
|
|
1309
|
+
if (!role) {
|
|
1310
|
+
throw new Error(`Role "${key}" not found`);
|
|
1311
|
+
}
|
|
1312
|
+
return role;
|
|
1313
|
+
}
|
|
1314
|
+
async getTenantRoleByKey(tenantId, key, ...args) {
|
|
1315
|
+
const role = (await this.listAll(...args)).find(candidate => sameTenant(candidate.tenant, tenantId) && candidate.key === key);
|
|
1316
|
+
if (!role) {
|
|
1317
|
+
throw new Error(`Role "${key}" not found for tenant ${tenantId}`);
|
|
1318
|
+
}
|
|
1319
|
+
return role;
|
|
1320
|
+
}
|
|
1321
|
+
async renameRole(roleId, name, ...args) {
|
|
1322
|
+
return this.updateOne(roleId, {
|
|
1323
|
+
name: name
|
|
1324
|
+
}, ...args);
|
|
1325
|
+
}
|
|
1326
|
+
async updateRoleMetadata(roleId, metadata, ...args) {
|
|
1327
|
+
return this.updateOne(roleId, {
|
|
1328
|
+
metadata: metadata
|
|
1329
|
+
}, ...args);
|
|
1330
|
+
}
|
|
1331
|
+
async listTenantRoles(tenantId, includeSystem = false, ...args) {
|
|
1332
|
+
return (await this.listAll(...args)).filter(role => includeSystem ? !role.tenant || sameTenant(role.tenant, tenantId) : sameTenant(role.tenant, tenantId));
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
|
|
1336
|
+
async function deleteRowsById(service, rows, ...args) {
|
|
1337
|
+
for (const row of rows) {
|
|
1338
|
+
await service.deleteById(row.id, ...args);
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
class RolePermissionService extends BaseModelService {
|
|
1343
|
+
constructor() {
|
|
1344
|
+
super(RolePermission);
|
|
1345
|
+
}
|
|
1346
|
+
async addPermissionToRole(roleId, permissionId, ...args) {
|
|
1347
|
+
return this.create({
|
|
1348
|
+
role: roleId,
|
|
1349
|
+
permission: permissionId
|
|
1350
|
+
}, ...args);
|
|
1351
|
+
}
|
|
1352
|
+
async addPermissionKeyToRole(roleId, permissionKey, ...args) {
|
|
1353
|
+
const permission = await (new PermissionService).getByKey(permissionKey, ...args);
|
|
1354
|
+
return this.addPermissionToRole(roleId, permission.id, ...args);
|
|
1355
|
+
}
|
|
1356
|
+
async removePermissionFromRole(rolePermissionId, ...args) {
|
|
1357
|
+
await this.deleteById(rolePermissionId, ...args);
|
|
1358
|
+
}
|
|
1359
|
+
async listRolePermissions(roleId, ...args) {
|
|
1360
|
+
return (await this.listAll(...args)).filter(rolePermission => relationMatch(rolePermission.role, roleId));
|
|
1361
|
+
}
|
|
1362
|
+
async listPermissionRoles(permissionId, ...args) {
|
|
1363
|
+
return (await this.listAll(...args)).filter(rolePermission => relationMatch(rolePermission.permission, permissionId));
|
|
1364
|
+
}
|
|
1365
|
+
async replaceRolePermissions(roleId, permissionIds, ...args) {
|
|
1366
|
+
const existing = await this.listRolePermissions(roleId, ...args);
|
|
1367
|
+
await deleteRowsById(this, existing, ...args);
|
|
1368
|
+
return Promise.all(permissionIds.map(permissionId => this.addPermissionToRole(roleId, permissionId, ...args)));
|
|
1369
|
+
}
|
|
1370
|
+
async createRoleWithPermissions(input, permissionKeys, ...args) {
|
|
1371
|
+
const role = await (new RoleService).createRole(input, ...args);
|
|
1372
|
+
for (const permissionKey of permissionKeys) {
|
|
1373
|
+
await this.addPermissionKeyToRole(role.id, permissionKey, ...args);
|
|
1374
|
+
}
|
|
1375
|
+
return role;
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
class RoleAssignmentService extends BaseModelService {
|
|
1380
|
+
constructor() {
|
|
1381
|
+
super(RoleAssignment);
|
|
1382
|
+
}
|
|
1383
|
+
async assignRole(input, ...args) {
|
|
1384
|
+
return this.create({
|
|
1385
|
+
tenant: input.tenantId,
|
|
1386
|
+
principal: input.principalId,
|
|
1387
|
+
role: input.roleId,
|
|
1388
|
+
scopeKind: input.scopeKind,
|
|
1389
|
+
scopeId: input.scopeId,
|
|
1390
|
+
inheritDown: input.inheritDown ?? false,
|
|
1391
|
+
startsAt: input.startsAt,
|
|
1392
|
+
expiresAt: input.expiresAt,
|
|
1393
|
+
conditions: input.conditions
|
|
1394
|
+
}, ...args);
|
|
1395
|
+
}
|
|
1396
|
+
async revokeAssignment(assignmentId, ...args) {
|
|
1397
|
+
await this.deleteById(assignmentId, ...args);
|
|
1398
|
+
}
|
|
1399
|
+
async listPrincipalAssignments(tenantId, principalId, ...args) {
|
|
1400
|
+
return (await this.listAll(...args)).filter(assignment => sameTenant(assignment.tenant, tenantId) && relationMatch(assignment.principal, principalId));
|
|
1401
|
+
}
|
|
1402
|
+
async listRoleAssignments(roleId, ...args) {
|
|
1403
|
+
return (await this.listAll(...args)).filter(assignment => relationMatch(assignment.role, roleId));
|
|
1404
|
+
}
|
|
1405
|
+
async listTenantAssignments(tenantId, ...args) {
|
|
1406
|
+
return (await this.listAll(...args)).filter(assignment => sameTenant(assignment.tenant, tenantId));
|
|
1407
|
+
}
|
|
1408
|
+
async updateAssignmentWindow(assignmentId, startsAt, expiresAt, ...args) {
|
|
1409
|
+
return this.updateOne(assignmentId, {
|
|
1410
|
+
startsAt: startsAt,
|
|
1411
|
+
expiresAt: expiresAt
|
|
1412
|
+
}, ...args);
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1416
|
+
class EffectivePermissionService extends BaseModelService {
|
|
1417
|
+
constructor() {
|
|
1418
|
+
super(EffectivePermission);
|
|
1419
|
+
}
|
|
1420
|
+
async listForPrincipal(tenantId, principalId, ...args) {
|
|
1421
|
+
return (await this.listAll(...args)).filter(permission => sameTenant(permission.tenant, tenantId) && relationMatch(permission.principal, principalId));
|
|
1422
|
+
}
|
|
1423
|
+
async listForScope(tenantId, scopeKind, scopeId, ...args) {
|
|
1424
|
+
return (await this.listAll(...args)).filter(permission => sameTenant(permission.tenant, tenantId) && permission.scopeKind === scopeKind && permission.scopeId === scopeId);
|
|
1425
|
+
}
|
|
1426
|
+
async hasPermission(tenantId, principalId, permissionKey, scopeKind, scopeId, at, ...args) {
|
|
1427
|
+
return (await this.listForPrincipal(tenantId, principalId, ...args)).some(permission => permission.permissionKey === permissionKey && permission.scopeKind === scopeKind && permission.scopeId === scopeId && (!permission.startsAt || !at || permission.startsAt <= at) && (!permission.expiresAt || !at || permission.expiresAt >= at));
|
|
1428
|
+
}
|
|
1429
|
+
async deleteForPrincipal(tenantId, principalId, ...args) {
|
|
1430
|
+
for (const row of await this.listForPrincipal(tenantId, principalId, ...args)) {
|
|
1431
|
+
await this.deleteById(row.id, ...args);
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
async deleteForTenant(tenantId, ...args) {
|
|
1435
|
+
for (const row of (await this.listAll(...args)).filter(permission => sameTenant(permission.tenant, tenantId))) {
|
|
1436
|
+
await this.deleteById(row.id, ...args);
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
async rebuildForPrincipal(tenantId, principalId, ...args) {
|
|
1440
|
+
await this.deleteForPrincipal(tenantId, principalId, ...args);
|
|
1441
|
+
const roleAssignmentService = new RoleAssignmentService;
|
|
1442
|
+
const rolePermissionService = new RolePermissionService;
|
|
1443
|
+
const permissionService = new PermissionService;
|
|
1444
|
+
const groupMembershipService = new GroupMembershipService;
|
|
1445
|
+
const principalService = new PrincipalService;
|
|
1446
|
+
const orgUnitClosureService = new OrgUnitClosureService;
|
|
1447
|
+
const inheritanceBlockService = new InheritanceBlockService;
|
|
1448
|
+
const materialized = [];
|
|
1449
|
+
const sourceAssignments = await roleAssignmentService.listPrincipalAssignments(tenantId, principalId, ...args);
|
|
1450
|
+
const groupMemberships = await groupMembershipService.listPrincipalGroups(principalId, ...args);
|
|
1451
|
+
const groupAssignments = (await Promise.all(groupMemberships.map(async membership => {
|
|
1452
|
+
const groupPrincipal = await principalService.getGroupPrincipal(relationId(membership.tenant), relationId(membership.group), ...args);
|
|
1453
|
+
return roleAssignmentService.listPrincipalAssignments(tenantId, groupPrincipal.id, ...args);
|
|
1454
|
+
}))).flat();
|
|
1455
|
+
const assignments = [ ...sourceAssignments, ...groupAssignments ];
|
|
1456
|
+
for (const assignment of assignments) {
|
|
1457
|
+
const rolePermissions = await rolePermissionService.listRolePermissions(relationId(assignment.role), ...args);
|
|
1458
|
+
const permissions = await Promise.all(rolePermissions.map(async rolePermission => permissionService.findOneBy("id", relationId(rolePermission.permission), ...args)));
|
|
1459
|
+
for (const permission of permissions) {
|
|
1460
|
+
if (!permission) continue;
|
|
1461
|
+
const scopeKind = assignment.scopeKind;
|
|
1462
|
+
const scopeId = assignment.scopeId;
|
|
1463
|
+
const scopes = [];
|
|
1464
|
+
if (scopeKind === ScopeKind.Tenant) {
|
|
1465
|
+
scopes.push({
|
|
1466
|
+
scopeKind: scopeKind,
|
|
1467
|
+
scopeId: tenantId
|
|
1468
|
+
});
|
|
1469
|
+
} else if (scopeKind === ScopeKind.Resource) {
|
|
1470
|
+
scopes.push({
|
|
1471
|
+
scopeKind: scopeKind,
|
|
1472
|
+
scopeId: scopeId
|
|
1473
|
+
});
|
|
1474
|
+
} else if (scopeKind === ScopeKind.OrgUnit && !assignment.inheritDown) {
|
|
1475
|
+
scopes.push({
|
|
1476
|
+
scopeKind: scopeKind,
|
|
1477
|
+
scopeId: scopeId
|
|
1478
|
+
});
|
|
1479
|
+
} else if (scopeKind === ScopeKind.OrgUnit && assignment.inheritDown) {
|
|
1480
|
+
const descendants = await orgUnitClosureService.listDescendants(tenantId, scopeId, ...args);
|
|
1481
|
+
scopes.push(...descendants.map(row => ({
|
|
1482
|
+
scopeKind: scopeKind,
|
|
1483
|
+
scopeId: relationId(row.descendant)
|
|
1484
|
+
})));
|
|
1485
|
+
}
|
|
1486
|
+
for (const scoped of scopes) {
|
|
1487
|
+
if (scopeKind === ScopeKind.OrgUnit && assignment.inheritDown && scoped.scopeId !== scopeId && await inheritanceBlockService.categoryBlockedForAncestor(tenantId, scoped.scopeId, scopeId, permission.category, ...args)) {
|
|
1488
|
+
continue;
|
|
1489
|
+
}
|
|
1490
|
+
materialized.push({
|
|
1491
|
+
id: "",
|
|
1492
|
+
tenantId: tenantId,
|
|
1493
|
+
principalId: principalId,
|
|
1494
|
+
permissionKey: permission.key,
|
|
1495
|
+
scopeKind: scoped.scopeKind,
|
|
1496
|
+
scopeId: scoped.scopeId,
|
|
1497
|
+
sourceKind: "role_assignment",
|
|
1498
|
+
sourceId: assignment.id,
|
|
1499
|
+
startsAt: assignment.startsAt,
|
|
1500
|
+
expiresAt: assignment.expiresAt
|
|
1501
|
+
});
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
const created = await Promise.all(materialized.map(permission => this.create({
|
|
1506
|
+
tenant: permission.tenantId,
|
|
1507
|
+
principal: permission.principalId,
|
|
1508
|
+
permissionKey: permission.permissionKey,
|
|
1509
|
+
scopeKind: permission.scopeKind,
|
|
1510
|
+
scopeId: permission.scopeId,
|
|
1511
|
+
sourceKind: permission.sourceKind,
|
|
1512
|
+
sourceId: permission.sourceId,
|
|
1513
|
+
startsAt: permission.startsAt,
|
|
1514
|
+
expiresAt: permission.expiresAt
|
|
1515
|
+
}, ...args)));
|
|
1516
|
+
return created;
|
|
1517
|
+
}
|
|
1518
|
+
async rebuildForTenant(tenantId, ...args) {
|
|
1519
|
+
const principals = (await (new PrincipalService).listAll(...args)).filter(principal => sameTenant(principal.tenant, tenantId));
|
|
1520
|
+
for (const principal of principals) {
|
|
1521
|
+
await this.rebuildForPrincipal(tenantId, principal.id, ...args);
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
__decorate([ transactional(), __metadata("design:type", Function), __metadata("design:paramtypes", [ String, String, Object ]), __metadata("design:returntype", Promise) ], EffectivePermissionService.prototype, "rebuildForPrincipal", null);
|
|
1527
|
+
|
|
1528
|
+
__decorate([ transactional(), __metadata("design:type", Function), __metadata("design:paramtypes", [ String, Object ]), __metadata("design:returntype", Promise) ], EffectivePermissionService.prototype, "rebuildForTenant", null);
|
|
1529
|
+
|
|
1530
|
+
class ProtectedResourceService extends BaseModelService {
|
|
1531
|
+
constructor() {
|
|
1532
|
+
super(ProtectedResource);
|
|
1533
|
+
}
|
|
1534
|
+
async registerResource(input, ...args) {
|
|
1535
|
+
return this.create({
|
|
1536
|
+
tenant: input.tenantId,
|
|
1537
|
+
orgUnit: input.orgUnitId,
|
|
1538
|
+
resourceType: input.resourceType,
|
|
1539
|
+
resourceId: input.resourceId,
|
|
1540
|
+
visibility: input.visibility,
|
|
1541
|
+
owner: input.ownerPrincipalId,
|
|
1542
|
+
sensitivity: input.sensitivity,
|
|
1543
|
+
metadata: input.metadata
|
|
1544
|
+
}, ...args);
|
|
1545
|
+
}
|
|
1546
|
+
async getByDomainResource(tenantId, resourceType, resourceId, ...args) {
|
|
1547
|
+
return (await this.listAll(...args)).find(resource => sameTenant(resource.tenant, tenantId) && resource.resourceType === resourceType && resource.resourceId === resourceId);
|
|
1548
|
+
}
|
|
1549
|
+
async moveResourceToOrgUnit(protectedResourceId, orgUnitId, ...args) {
|
|
1550
|
+
return this.updateOne(protectedResourceId, {
|
|
1551
|
+
orgUnit: orgUnitId
|
|
1552
|
+
}, ...args);
|
|
1553
|
+
}
|
|
1554
|
+
async setVisibility(protectedResourceId, visibility, ...args) {
|
|
1555
|
+
return this.updateOne(protectedResourceId, {
|
|
1556
|
+
visibility: visibility
|
|
1557
|
+
}, ...args);
|
|
1558
|
+
}
|
|
1559
|
+
async transferOwnership(protectedResourceId, ownerPrincipalId, ...args) {
|
|
1560
|
+
return this.updateOne(protectedResourceId, {
|
|
1561
|
+
owner: ownerPrincipalId
|
|
1562
|
+
}, ...args);
|
|
1563
|
+
}
|
|
1564
|
+
async listOrgUnitResources(orgUnitId, ...args) {
|
|
1565
|
+
return (await this.listAll(...args)).filter(resource => relationMatch(resource.orgUnit, orgUnitId));
|
|
1566
|
+
}
|
|
1567
|
+
async listTenantResources(tenantId, ...args) {
|
|
1568
|
+
return (await this.listAll(...args)).filter(resource => sameTenant(resource.tenant, tenantId));
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
|
|
1572
|
+
class ResourceGrantService extends BaseModelService {
|
|
1573
|
+
constructor() {
|
|
1574
|
+
super(ResourceGrant);
|
|
1575
|
+
}
|
|
1576
|
+
async grantResource(input, ...args) {
|
|
1577
|
+
return this.create({
|
|
1578
|
+
tenant: input.tenantId,
|
|
1579
|
+
resource: input.resourceId,
|
|
1580
|
+
principal: input.principalId,
|
|
1581
|
+
permissionKey: input.permissionKey,
|
|
1582
|
+
startsAt: input.startsAt,
|
|
1583
|
+
expiresAt: input.expiresAt,
|
|
1584
|
+
conditions: input.conditions,
|
|
1585
|
+
createdBy: input.createdByPrincipalId
|
|
1586
|
+
}, ...args);
|
|
1587
|
+
}
|
|
1588
|
+
async revokeGrant(grantId, ...args) {
|
|
1589
|
+
await this.deleteById(grantId, ...args);
|
|
1590
|
+
}
|
|
1591
|
+
async listResourceGrants(protectedResourceId, ...args) {
|
|
1592
|
+
return (await this.listAll(...args)).filter(grant => relationMatch(grant.resource, protectedResourceId));
|
|
1593
|
+
}
|
|
1594
|
+
async listPrincipalGrants(tenantId, principalId, ...args) {
|
|
1595
|
+
return (await this.listAll(...args)).filter(grant => sameTenant(grant.tenant, tenantId) && relationMatch(grant.principal, principalId));
|
|
1596
|
+
}
|
|
1597
|
+
async hasGrant(tenantId, principalId, protectedResourceId, permissionKey, at, ...args) {
|
|
1598
|
+
return (await this.listPrincipalGrants(tenantId, principalId, ...args)).some(grant => relationMatch(grant.resource, protectedResourceId) && grant.permissionKey === permissionKey && (!grant.startsAt || !at || grant.startsAt <= at) && (!grant.expiresAt || !at || grant.expiresAt >= at));
|
|
1599
|
+
}
|
|
1600
|
+
async deleteAllForResource(protectedResourceId, ...args) {
|
|
1601
|
+
for (const row of await this.listResourceGrants(protectedResourceId, ...args)) {
|
|
1602
|
+
await this.deleteById(row.id, ...args);
|
|
1603
|
+
}
|
|
1604
|
+
}
|
|
1605
|
+
}
|
|
1606
|
+
|
|
1607
|
+
class ResourceLifecycleService {
|
|
1608
|
+
async unregisterResource(protectedResourceId, ...args) {
|
|
1609
|
+
await (new ResourceGrantService).deleteAllForResource(protectedResourceId, ...args);
|
|
1610
|
+
await (new ProtectedResourceService).deleteById(protectedResourceId, ...args);
|
|
1611
|
+
}
|
|
1612
|
+
async resolveResourceScope(protectedResourceId, ...args) {
|
|
1613
|
+
const resource = await (new ProtectedResourceService).getById(protectedResourceId, ...args);
|
|
1614
|
+
return {
|
|
1615
|
+
tenantId: relationId(resource.tenant),
|
|
1616
|
+
orgUnitId: relationId(resource.orgUnit),
|
|
1617
|
+
visibility: resource.visibility,
|
|
1618
|
+
ownerPrincipalId: resource.owner ? relationId(resource.owner) : undefined
|
|
1619
|
+
};
|
|
1620
|
+
}
|
|
1621
|
+
}
|
|
1622
|
+
|
|
1623
|
+
class StorageBindingService extends BaseModelService {
|
|
1624
|
+
constructor() {
|
|
1625
|
+
super(StorageBinding);
|
|
1626
|
+
}
|
|
1627
|
+
async createBinding(input, ...args) {
|
|
1628
|
+
return this.create({
|
|
1629
|
+
tenant: input.tenantId,
|
|
1630
|
+
storageKind: input.storageKind,
|
|
1631
|
+
bindingKind: input.bindingKind,
|
|
1632
|
+
bindingKey: input.bindingKey,
|
|
1633
|
+
region: input.region,
|
|
1634
|
+
config: input.config
|
|
1635
|
+
}, ...args);
|
|
1636
|
+
}
|
|
1637
|
+
async listTenantBindings(tenantId, ...args) {
|
|
1638
|
+
return (await this.listAll(...args)).filter(binding => relationId(binding.tenant) === tenantId);
|
|
1639
|
+
}
|
|
1640
|
+
async getBinding(tenantId, storageKind, ...args) {
|
|
1641
|
+
return (await this.listTenantBindings(tenantId, ...args)).find(binding => binding.storageKind === storageKind);
|
|
1642
|
+
}
|
|
1643
|
+
async setBindingConfig(bindingId, config, ...args) {
|
|
1644
|
+
return this.updateOne(bindingId, {
|
|
1645
|
+
config: config
|
|
1646
|
+
}, ...args);
|
|
1647
|
+
}
|
|
1648
|
+
async promoteToDedicated(bindingId, bindingKey, region, config, ...args) {
|
|
1649
|
+
return this.updateOne(bindingId, {
|
|
1650
|
+
bindingKind: StorageBindingKind.Dedicated,
|
|
1651
|
+
bindingKey: bindingKey,
|
|
1652
|
+
region: region,
|
|
1653
|
+
config: config
|
|
1654
|
+
}, ...args);
|
|
1655
|
+
}
|
|
1656
|
+
async setShared(bindingId, bindingKey, region, config, ...args) {
|
|
1657
|
+
return this.updateOne(bindingId, {
|
|
1658
|
+
bindingKind: StorageBindingKind.Shared,
|
|
1659
|
+
bindingKey: bindingKey,
|
|
1660
|
+
region: region,
|
|
1661
|
+
config: config
|
|
1662
|
+
}, ...args);
|
|
1663
|
+
}
|
|
1664
|
+
}
|
|
1665
|
+
|
|
1666
|
+
class BootstrapService {
|
|
1667
|
+
constructor() {
|
|
1668
|
+
this.tenantService = new TenantService;
|
|
1669
|
+
this.tenantProfileService = new TenantProfileService;
|
|
1670
|
+
this.orgUnitService = new OrgUnitService;
|
|
1671
|
+
this.orgUnitProfileService = new OrgUnitProfileService;
|
|
1672
|
+
this.userService = new UserService;
|
|
1673
|
+
this.membershipService = new TenantMembershipService;
|
|
1674
|
+
this.principalService = new PrincipalService;
|
|
1675
|
+
this.permissionService = new PermissionService;
|
|
1676
|
+
this.roleService = new RoleService;
|
|
1677
|
+
this.rolePermissionService = new RolePermissionService;
|
|
1678
|
+
this.roleAssignmentService = new RoleAssignmentService;
|
|
1679
|
+
this.effectivePermissionService = new EffectivePermissionService;
|
|
1680
|
+
}
|
|
1681
|
+
async bootstrapTenantFromTemplate(template, ...args) {
|
|
1682
|
+
const tenant = await this.tenantService.createTenant(template.tenant, ...args);
|
|
1683
|
+
if (template.tenant.profileKey) {
|
|
1684
|
+
await this.tenantProfileService.createProfile(tenant.id, template.tenant.profileKey, template.tenant.profileMetadata, ...args);
|
|
1685
|
+
}
|
|
1686
|
+
const createOrgTree = async (parentId, orgUnit) => {
|
|
1687
|
+
const created = parentId === undefined ? await this.orgUnitService.createRoot(tenant.id, orgUnit.name, orgUnit.metadata, orgUnit.profileKey, orgUnit.metadata, ...args) : await this.orgUnitService.createChild({
|
|
1688
|
+
tenantId: tenant.id,
|
|
1689
|
+
parentOrgUnitId: parentId,
|
|
1690
|
+
name: orgUnit.name,
|
|
1691
|
+
metadata: orgUnit.metadata,
|
|
1692
|
+
profileKey: orgUnit.profileKey,
|
|
1693
|
+
profileMetadata: orgUnit.metadata
|
|
1694
|
+
}, ...args);
|
|
1695
|
+
for (const child of orgUnit.children ?? []) {
|
|
1696
|
+
await createOrgTree(created.id, child);
|
|
1697
|
+
}
|
|
1698
|
+
return created;
|
|
1699
|
+
};
|
|
1700
|
+
const rootOrgUnit = await createOrgTree(undefined, template.rootOrgUnit);
|
|
1701
|
+
const owner = await this.userService.createUser(template.ownerUser, ...args);
|
|
1702
|
+
await this.membershipService.addUserToTenant(tenant.id, owner.id, MembershipStatus.Active, ...args);
|
|
1703
|
+
const ownerPrincipal = await this.principalService.getUserPrincipal(tenant.id, owner.id, ...args);
|
|
1704
|
+
for (const permission of template.permissions) {
|
|
1705
|
+
await this.permissionService.createPermission(permission, ...args);
|
|
1706
|
+
}
|
|
1707
|
+
for (const role of template.roles) {
|
|
1708
|
+
const createdRole = await this.roleService.createRole({
|
|
1709
|
+
tenantId: tenant.id,
|
|
1710
|
+
key: role.key,
|
|
1711
|
+
name: role.name,
|
|
1712
|
+
description: role.description
|
|
1713
|
+
}, ...args);
|
|
1714
|
+
for (const permissionKey of role.permissionKeys) {
|
|
1715
|
+
await this.rolePermissionService.addPermissionKeyToRole(createdRole.id, permissionKey, ...args);
|
|
1716
|
+
}
|
|
1717
|
+
}
|
|
1718
|
+
const ownerRole = await this.roleService.getTenantRoleByKey(tenant.id, template.ownerRoleKey, ...args);
|
|
1719
|
+
await this.roleAssignmentService.assignRole({
|
|
1720
|
+
tenantId: tenant.id,
|
|
1721
|
+
principalId: ownerPrincipal.id,
|
|
1722
|
+
roleId: ownerRole.id,
|
|
1723
|
+
scopeKind: ScopeKind.OrgUnit,
|
|
1724
|
+
scopeId: rootOrgUnit.id,
|
|
1725
|
+
inheritDown: true
|
|
1726
|
+
}, ...args);
|
|
1727
|
+
await this.effectivePermissionService.rebuildForPrincipal(tenant.id, ownerPrincipal.id, ...args);
|
|
1728
|
+
return {
|
|
1729
|
+
tenantId: tenant.id,
|
|
1730
|
+
rootOrgUnitId: rootOrgUnit.id,
|
|
1731
|
+
ownerUserId: owner.id,
|
|
1732
|
+
ownerPrincipalId: ownerPrincipal.id
|
|
1733
|
+
};
|
|
1734
|
+
}
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1737
|
+
__decorate([ transactional(), __metadata("design:type", Function), __metadata("design:paramtypes", [ Object, Object ]), __metadata("design:returntype", Promise) ], BootstrapService.prototype, "bootstrapTenantFromTemplate", null);
|
|
1738
|
+
|
|
1739
|
+
class SystemManagementService {
|
|
1740
|
+
constructor() {
|
|
1741
|
+
this.membershipService = new TenantMembershipService;
|
|
1742
|
+
this.orgMembershipService = new OrgUnitMembershipService;
|
|
1743
|
+
this.principalService = new PrincipalService;
|
|
1744
|
+
this.roleService = new RoleService;
|
|
1745
|
+
this.roleAssignmentService = new RoleAssignmentService;
|
|
1746
|
+
this.effectivePermissionService = new EffectivePermissionService;
|
|
1747
|
+
}
|
|
1748
|
+
async onboardUserToTenantAndOrgUnit(tenantId, userId, orgUnitId, roleKey, ...args) {
|
|
1749
|
+
await this.membershipService.addUserToTenant(tenantId, userId, MembershipStatus.Active, ...args);
|
|
1750
|
+
await this.orgMembershipService.addUserToOrgUnit(tenantId, orgUnitId, userId, MembershipStatus.Active, ...args);
|
|
1751
|
+
const principal = await this.principalService.getUserPrincipal(tenantId, userId, ...args);
|
|
1752
|
+
const role = await this.roleService.getTenantRoleByKey(tenantId, roleKey, ...args);
|
|
1753
|
+
await this.roleAssignmentService.assignRole({
|
|
1754
|
+
tenantId: tenantId,
|
|
1755
|
+
principalId: principal.id,
|
|
1756
|
+
roleId: role.id,
|
|
1757
|
+
scopeKind: ScopeKind.OrgUnit,
|
|
1758
|
+
scopeId: orgUnitId,
|
|
1759
|
+
inheritDown: true
|
|
1760
|
+
}, ...args);
|
|
1761
|
+
await this.effectivePermissionService.rebuildForPrincipal(tenantId, principal.id, ...args);
|
|
1762
|
+
return {
|
|
1763
|
+
principalId: principal.id
|
|
1764
|
+
};
|
|
1765
|
+
}
|
|
1766
|
+
async changeUserOrgRole(tenantId, principalId, orgUnitId, roleKey, inheritDown, ...args) {
|
|
1767
|
+
const role = await this.roleService.getTenantRoleByKey(tenantId, roleKey, ...args);
|
|
1768
|
+
const currentAssignments = await this.roleAssignmentService.listPrincipalAssignments(tenantId, principalId, ...args);
|
|
1769
|
+
for (const assignment of currentAssignments.filter(row => row.scopeKind === ScopeKind.OrgUnit && row.scopeId === orgUnitId)) {
|
|
1770
|
+
await this.roleAssignmentService.revokeAssignment(assignment.id, ...args);
|
|
1771
|
+
}
|
|
1772
|
+
await this.roleAssignmentService.assignRole({
|
|
1773
|
+
tenantId: tenantId,
|
|
1774
|
+
principalId: principalId,
|
|
1775
|
+
roleId: role.id,
|
|
1776
|
+
scopeKind: ScopeKind.OrgUnit,
|
|
1777
|
+
scopeId: orgUnitId,
|
|
1778
|
+
inheritDown: inheritDown
|
|
1779
|
+
}, ...args);
|
|
1780
|
+
await this.effectivePermissionService.rebuildForPrincipal(tenantId, principalId, ...args);
|
|
1781
|
+
}
|
|
1782
|
+
async suspendUserInTenant(tenantMembershipId, tenantId, principalId, ...args) {
|
|
1783
|
+
await this.membershipService.setStatus(tenantMembershipId, MembershipStatus.Suspended, ...args);
|
|
1784
|
+
await this.effectivePermissionService.deleteForPrincipal(tenantId, principalId, ...args);
|
|
1785
|
+
}
|
|
1786
|
+
async reactivateUserInTenant(tenantMembershipId, tenantId, principalId, ...args) {
|
|
1787
|
+
await this.membershipService.setStatus(tenantMembershipId, MembershipStatus.Active, ...args);
|
|
1788
|
+
await this.effectivePermissionService.rebuildForPrincipal(tenantId, principalId, ...args);
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
1791
|
+
|
|
1792
|
+
__decorate([ transactional(), __metadata("design:type", Function), __metadata("design:paramtypes", [ String, String, String, String, Object ]), __metadata("design:returntype", Promise) ], SystemManagementService.prototype, "onboardUserToTenantAndOrgUnit", null);
|
|
1793
|
+
|
|
1794
|
+
__decorate([ transactional(), __metadata("design:type", Function), __metadata("design:paramtypes", [ String, String, String, String, Boolean, Object ]), __metadata("design:returntype", Promise) ], SystemManagementService.prototype, "changeUserOrgRole", null);
|
|
1795
|
+
|
|
1796
|
+
__decorate([ transactional(), __metadata("design:type", Function), __metadata("design:paramtypes", [ String, String, String, Object ]), __metadata("design:returntype", Promise) ], SystemManagementService.prototype, "suspendUserInTenant", null);
|
|
1797
|
+
|
|
1798
|
+
__decorate([ transactional(), __metadata("design:type", Function), __metadata("design:paramtypes", [ String, String, String, Object ]), __metadata("design:returntype", Promise) ], SystemManagementService.prototype, "reactivateUserInTenant", null);
|
|
1799
|
+
|
|
1800
|
+
function scopeKey(scopeKind, scopeId) {
|
|
1801
|
+
return `${scopeKind}:${scopeId}`;
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
class AuthzService {
|
|
1805
|
+
constructor(dataSources = {}) {
|
|
1806
|
+
this.dataSources = dataSources;
|
|
1807
|
+
}
|
|
1808
|
+
async canAccess(input, ...args) {
|
|
1809
|
+
const at = input.at ?? new Date;
|
|
1810
|
+
if (input.scopeKind && input.scopeId) {
|
|
1811
|
+
const permissions = await (this.dataSources.listEffectivePermissionsForScope?.(input.tenantId, input.scopeKind, input.scopeId));
|
|
1812
|
+
return asArray(permissions).some(permission => permission.permissionKey === input.permissionKey && isTimeValid(at, permission.startsAt, permission.expiresAt));
|
|
1813
|
+
}
|
|
1814
|
+
if (!input.resourceProtectedId) return false;
|
|
1815
|
+
const resource = await (this.dataSources.loadResource?.(input.tenantId, input.resourceProtectedId));
|
|
1816
|
+
if (!resource) return false;
|
|
1817
|
+
if (resource.tenantId !== input.tenantId) return false;
|
|
1818
|
+
if (resource.ownerPrincipalId === input.principalId) return true;
|
|
1819
|
+
const grants = asArray(await (this.dataSources.listResourceGrants?.(input.tenantId, input.resourceProtectedId))).filter(grant => grant.principalId === input.principalId && grant.permissionKey === input.permissionKey && isTimeValid(at, grant.startsAt, grant.expiresAt));
|
|
1820
|
+
if (grants.length > 0) return true;
|
|
1821
|
+
const visibility = resource.visibility;
|
|
1822
|
+
if (visibility === ResourceVisibility.Private || visibility === ResourceVisibility.ResourceAcl) {
|
|
1823
|
+
return false;
|
|
1824
|
+
}
|
|
1825
|
+
if (visibility === ResourceVisibility.OrgUnit || visibility === ResourceVisibility.OrgSubtree) {
|
|
1826
|
+
const effectivePermissions = asArray(await (this.dataSources.listEffectivePermissionsForScope?.(input.tenantId, ScopeKind.OrgUnit, resource.orgUnitId)));
|
|
1827
|
+
return effectivePermissions.some(permission => permission.permissionKey === input.permissionKey && isTimeValid(at, permission.startsAt, permission.expiresAt));
|
|
1828
|
+
}
|
|
1829
|
+
if (visibility === ResourceVisibility.Tenant) {
|
|
1830
|
+
const effectivePermissions = asArray(await (this.dataSources.listEffectivePermissionsForScope?.(input.tenantId, ScopeKind.Tenant, input.tenantId)));
|
|
1831
|
+
return effectivePermissions.some(permission => permission.permissionKey === input.permissionKey && isTimeValid(at, permission.startsAt, permission.expiresAt));
|
|
1832
|
+
}
|
|
1833
|
+
return false;
|
|
1834
|
+
}
|
|
1835
|
+
async requireAccess(input, ...args) {
|
|
1836
|
+
if (!await this.canAccess(input, ...args)) {
|
|
1837
|
+
throw new AuthorizationError(`Access denied for ${input.permissionKey} on ${input.resourceProtectedId ?? scopeKey(input.scopeKind ?? ScopeKind.Resource, input.scopeId ?? "")}`);
|
|
1838
|
+
}
|
|
1839
|
+
}
|
|
1840
|
+
async buildAccessContext(tenantId, principalId, ...args) {
|
|
1841
|
+
const permissions = asArray(await (this.dataSources.listEffectivePermissions?.(tenantId, principalId)));
|
|
1842
|
+
const grants = asArray(await (this.dataSources.listPrincipalGrants?.(tenantId, principalId)));
|
|
1843
|
+
return buildAccessContext({
|
|
1844
|
+
tenantId: tenantId,
|
|
1845
|
+
principalId: principalId,
|
|
1846
|
+
permissions: permissions,
|
|
1847
|
+
grants: grants
|
|
1848
|
+
});
|
|
1849
|
+
}
|
|
1850
|
+
async buildArangoContext(tenantId, principalId, permissionKey, ...args) {
|
|
1851
|
+
const access = await this.buildAccessContext(tenantId, principalId, ...args);
|
|
1852
|
+
const allowedOrgUnitIds = access.allowedOrgUnitIdsByPermission[permissionKey] ?? [];
|
|
1853
|
+
const allowedResourceIds = access.resourceGrants.filter(grant => grant.permissionKey === permissionKey).map(grant => grant.resourceId);
|
|
1854
|
+
return buildArangoContext({
|
|
1855
|
+
tenantId: tenantId,
|
|
1856
|
+
principalId: principalId,
|
|
1857
|
+
permissionKey: permissionKey,
|
|
1858
|
+
allowedOrgUnitIds: allowedOrgUnitIds,
|
|
1859
|
+
allowedResourceIds: allowedResourceIds
|
|
1860
|
+
});
|
|
1861
|
+
}
|
|
1862
|
+
async buildQdrantFilter(tenantId, principalId, permissionKey, ...args) {
|
|
1863
|
+
const access = await this.buildAccessContext(tenantId, principalId, ...args);
|
|
1864
|
+
const allowedOrgUnitIds = access.allowedOrgUnitIdsByPermission[permissionKey] ?? [];
|
|
1865
|
+
const allowedResourceIds = access.resourceGrants.filter(grant => grant.permissionKey === permissionKey).map(grant => grant.resourceId);
|
|
1866
|
+
return buildQdrantFilter({
|
|
1867
|
+
tenantId: tenantId,
|
|
1868
|
+
principalId: principalId,
|
|
1869
|
+
permissionKey: permissionKey,
|
|
1870
|
+
allowedOrgUnitIds: allowedOrgUnitIds,
|
|
1871
|
+
allowedResourceIds: allowedResourceIds
|
|
1872
|
+
});
|
|
1873
|
+
}
|
|
1874
|
+
}
|
|
1875
|
+
|
|
1876
|
+
const VERSION = "0.3.11";
|
|
1877
|
+
|
|
1878
|
+
const COMMIT = "e2c4409";
|
|
1879
|
+
|
|
1880
|
+
const FULL_VERSION = "0.3.11-e2c4409";
|
|
1881
|
+
|
|
1882
|
+
const PACKAGE_NAME = "@decaf-ts/integrations";
|
|
1883
|
+
|
|
1884
|
+
export { AuthorizationModel, AuthzService, BaseModelService, BootstrapService, COMMIT, EffectivePermission, EffectivePermissionService, FULL_VERSION, Group, GroupMembership, GroupMembershipService, GroupService, InheritanceBlock, InheritanceBlockService, IsolationTier, IsolationTierOptions, MembershipStatus, MembershipStatusOptions, OrgUnit, OrgUnitClosure, OrgUnitClosureService, OrgUnitMembership, OrgUnitMembershipService, OrgUnitProfile, OrgUnitProfileService, OrgUnitService, PACKAGE_NAME, Permission, PermissionCategory, PermissionCategoryOptions, PermissionService, Principal, PrincipalKind, PrincipalKindOptions, PrincipalService, ProtectedResource, ProtectedResourceService, REL_CASCADE_DEPENDENT, REL_CASCADE_INSERT_UPDATE, REL_NULLIFY, REL_RESTRICT, ResourceGrant, ResourceGrantService, ResourceLifecycleService, ResourceVisibility, ResourceVisibilityOptions, Role, RoleAssignment, RoleAssignmentService, RolePermission, RolePermissionService, RoleService, ScopeKind, ScopeKindOptions, StorageBinding, StorageBindingKind, StorageBindingKindOptions, StorageBindingService, StorageKind, StorageKindOptions, SystemManagementService, Tenant, TenantMembership, TenantMembershipService, TenantProfile, TenantProfileService, TenantService, User, UserService, VERSION, asArray, buildAccessContext, buildArangoContext, buildQdrantFilter, execWithLogging, id, isTimeValid, lowerSlug, nowIso, relationId, relationMatch, sameTenant };
|
|
1885
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZWdyYXRpb25zLmpzIiwic291cmNlcyI6WyIuLi9zcmMvdXRpbHMudHMiLCIuLi9zcmMvbmFtZXNwYWNlcy90eXBlcy50cyIsIi4uL3NyYy9uYW1lc3BhY2VzL3V0aWxzLnRzIiwiLi4vc3JjL25hbWVzcGFjZXMvbW9kZWxzL2F1dGhvcml6YXRpb24tbW9kZWwudHMiLCIuLi9zcmMvbmFtZXNwYWNlcy9tb2RlbHMvdGVuYW50LW1lbWJlcnNoaXAubW9kZWwudHMiLCIuLi9zcmMvbmFtZXNwYWNlcy9tb2RlbHMvdXNlci5tb2RlbC50cyIsIi4uL3NyYy9uYW1lc3BhY2VzL21vZGVscy9vcmctdW5pdC1tZW1iZXJzaGlwLm1vZGVsLnRzIiwiLi4vc3JjL25hbWVzcGFjZXMvbW9kZWxzL29yZy11bml0LWNsb3N1cmUubW9kZWwudHMiLCIuLi9zcmMvbmFtZXNwYWNlcy9tb2RlbHMvcGVybWlzc2lvbi5tb2RlbC50cyIsIi4uL3NyYy9uYW1lc3BhY2VzL21vZGVscy9yb2xlLXBlcm1pc3Npb24ubW9kZWwudHMiLCIuLi9zcmMvbmFtZXNwYWNlcy9tb2RlbHMvcm9sZS5tb2RlbC50cyIsIi4uL3NyYy9uYW1lc3BhY2VzL21vZGVscy9yb2xlLWFzc2lnbm1lbnQubW9kZWwudHMiLCIuLi9zcmMvbmFtZXNwYWNlcy9tb2RlbHMvcmVzb3VyY2UtZ3JhbnQubW9kZWwudHMiLCIuLi9zcmMvbmFtZXNwYWNlcy9tb2RlbHMvcHJpbmNpcGFsLm1vZGVsLnRzIiwiLi4vc3JjL25hbWVzcGFjZXMvbW9kZWxzL3Byb3RlY3RlZC1yZXNvdXJjZS5tb2RlbC50cyIsIi4uL3NyYy9uYW1lc3BhY2VzL21vZGVscy9pbmhlcml0YW5jZS1ibG9jay5tb2RlbC50cyIsIi4uL3NyYy9uYW1lc3BhY2VzL21vZGVscy9vcmctdW5pdC5tb2RlbC50cyIsIi4uL3NyYy9uYW1lc3BhY2VzL21vZGVscy9zdG9yYWdlLWJpbmRpbmcubW9kZWwudHMiLCIuLi9zcmMvbmFtZXNwYWNlcy9tb2RlbHMvdGVuYW50Lm1vZGVsLnRzIiwiLi4vc3JjL25hbWVzcGFjZXMvbW9kZWxzL3RlbmFudC1wcm9maWxlLm1vZGVsLnRzIiwiLi4vc3JjL25hbWVzcGFjZXMvbW9kZWxzL29yZy11bml0LXByb2ZpbGUubW9kZWwudHMiLCIuLi9zcmMvbmFtZXNwYWNlcy9tb2RlbHMvZ3JvdXAtbWVtYmVyc2hpcC5tb2RlbC50cyIsIi4uL3NyYy9uYW1lc3BhY2VzL21vZGVscy9ncm91cC5tb2RlbC50cyIsIi4uL3NyYy9uYW1lc3BhY2VzL21vZGVscy9lZmZlY3RpdmUtcGVybWlzc2lvbi5tb2RlbC50cyIsIi4uL3NyYy9uYW1lc3BhY2VzL3NlcnZpY2VzL3RlbmFudC1wcm9maWxlLnNlcnZpY2UudHMiLCIuLi9zcmMvbmFtZXNwYWNlcy9zZXJ2aWNlcy9vcmctdW5pdC1wcm9maWxlLnNlcnZpY2UudHMiLCIuLi9zcmMvbmFtZXNwYWNlcy9zZXJ2aWNlcy9vcmctdW5pdC1jbG9zdXJlLnNlcnZpY2UudHMiLCIuLi9zcmMvbmFtZXNwYWNlcy9zZXJ2aWNlcy9pbmhlcml0YW5jZS1ibG9jay5zZXJ2aWNlLnRzIiwiLi4vc3JjL25hbWVzcGFjZXMvc2VydmljZXMvdGVuYW50LnNlcnZpY2UudHMiLCIuLi9zcmMvbmFtZXNwYWNlcy9zZXJ2aWNlcy9vcmctdW5pdC5zZXJ2aWNlLnRzIiwiLi4vc3JjL25hbWVzcGFjZXMvc2VydmljZXMvdXNlci5zZXJ2aWNlLnRzIiwiLi4vc3JjL25hbWVzcGFjZXMvc2VydmljZXMvcHJpbmNpcGFsLnNlcnZpY2UudHMiLCIuLi9zcmMvbmFtZXNwYWNlcy9zZXJ2aWNlcy90ZW5hbnQtbWVtYmVyc2hpcC5zZXJ2aWNlLnRzIiwiLi4vc3JjL25hbWVzcGFjZXMvc2VydmljZXMvb3JnLXVuaXQtbWVtYmVyc2hpcC5zZXJ2aWNlLnRzIiwiLi4vc3JjL25hbWVzcGFjZXMvc2VydmljZXMvZ3JvdXAuc2VydmljZS50cyIsIi4uL3NyYy9uYW1lc3BhY2VzL3NlcnZpY2VzL2dyb3VwLW1lbWJlcnNoaXAuc2VydmljZS50cyIsIi4uL3NyYy9uYW1lc3BhY2VzL3NlcnZpY2VzL3Blcm1pc3Npb24uc2VydmljZS50cyIsIi4uL3NyYy9uYW1lc3BhY2VzL3NlcnZpY2VzL3JvbGUuc2VydmljZS50cyIsIi4uL3NyYy9uYW1lc3BhY2VzL3NlcnZpY2VzL3JvbGUtcGVybWlzc2lvbi5zZXJ2aWNlLnRzIiwiLi4vc3JjL25hbWVzcGFjZXMvc2VydmljZXMvcm9sZS1hc3NpZ25tZW50LnNlcnZpY2UudHMiLCIuLi9zcmMvbmFtZXNwYWNlcy9zZXJ2aWNlcy9lZmZlY3RpdmUtcGVybWlzc2lvbi5zZXJ2aWNlLnRzIiwiLi4vc3JjL25hbWVzcGFjZXMvc2VydmljZXMvcHJvdGVjdGVkLXJlc291cmNlLnNlcnZpY2UudHMiLCIuLi9zcmMvbmFtZXNwYWNlcy9zZXJ2aWNlcy9yZXNvdXJjZS1ncmFudC5zZXJ2aWNlLnRzIiwiLi4vc3JjL25hbWVzcGFjZXMvc2VydmljZXMvcmVzb3VyY2UtbGlmZWN5Y2xlLnNlcnZpY2UudHMiLCIuLi9zcmMvbmFtZXNwYWNlcy9zZXJ2aWNlcy9zdG9yYWdlLWJpbmRpbmcuc2VydmljZS50cyIsIi4uL3NyYy9uYW1lc3BhY2VzL3NlcnZpY2VzL2Jvb3RzdHJhcC5zZXJ2aWNlLnRzIiwiLi4vc3JjL25hbWVzcGFjZXMvc2VydmljZXMvc3lzdGVtLW1hbmFnZW1lbnQuc2VydmljZS50cyIsIi4uL3NyYy9uYW1lc3BhY2VzL3NlcnZpY2VzL2F1dGh6LnNlcnZpY2UudHMiLCIuLi9zcmMvaW5kZXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbW9kdWxlIGludGVncmF0aW9ucy91dGlsc1xuICogQHN1bW1hcnkgU2hhcmVkIGludGVncmF0aW9uIHV0aWxpdGllcy5cbiAqIEBkZXNjcmlwdGlvbiBVdGlsaXR5IGhlbHBlcnMgdXNlZCBhY3Jvc3MgdGhlIGludGVncmF0aW9ucyBwYWNrYWdlLlxuICovXG5pbXBvcnQgeyBleGVjIH0gZnJvbSBcImNoaWxkX3Byb2Nlc3NcIjtcbmltcG9ydCB7IExvZ2dlciwgTG9nTGV2ZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2xvZ2dpbmdcIjtcbmltcG9ydCB7IEludGVybmFsRXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGV4ZWNXaXRoTG9nZ2luZyhcbiAgY29tbWFuZDogc3RyaW5nLFxuICBvcHRpb25zOiB7IGN3ZDogc3RyaW5nIH0sXG4gIGxvZzogTG9nZ2VyLFxuICBsZXZlbDogTG9nTGV2ZWwgPSBMb2dMZXZlbC5pbmZvXG4pOiBQcm9taXNlPHsgc3Rkb3V0OiBzdHJpbmc7IHN0ZGVycjogc3RyaW5nIH0+IHtcbiAgbG9nLmRlYnVnKGBFeGVjdXRpbmc6ICR7Y29tbWFuZH1gKTtcblxuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IGNoaWxkID0gZXhlYyhjb21tYW5kLCBvcHRpb25zKTtcblxuICAgIGNvbnN0IHN0ZG91dDogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCBzdGRlcnI6IHN0cmluZ1tdID0gW107XG5cbiAgICBjaGlsZC5zdGRvdXQ/Lm9uKFwiZGF0YVwiLCAoZGF0YTogc3RyaW5nKSA9PiB7XG4gICAgICBzdGRvdXQucHVzaChkYXRhKTtcbiAgICAgIGxvZ1tsZXZlbF0oZGF0YS50cmltKCkpO1xuICAgIH0pO1xuXG4gICAgY2hpbGQuc3RkZXJyPy5vbihcImRhdGFcIiwgKGRhdGE6IHN0cmluZykgPT4ge1xuICAgICAgc3RkZXJyLnB1c2goZGF0YSk7XG4gICAgICBsb2cuZGVidWcoZGF0YS50cmltKCkpO1xuICAgIH0pO1xuXG4gICAgY2hpbGQub24oXCJjbG9zZVwiLCAoY29kZTogbnVtYmVyKSA9PiB7XG4gICAgICBpZiAoY29kZSA9PT0gMCkge1xuICAgICAgICBsb2cuc2lsbHkoYENvbW1hbmQgY29tcGxldGVkIHN1Y2Nlc3NmdWxseWApO1xuICAgICAgICByZXNvbHZlKHsgc3Rkb3V0OiBzdGRvdXQuam9pbihcIlxcblwiKSwgc3RkZXJyOiBzdGRlcnIuam9pbihcIlxcblwiKSB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxvZy5jcml0aWNhbChcbiAgICAgICAgICBgQ29tbWFuZCBmYWlsZWQgd2l0aCBjb2RlICR7Y29kZX06XFxuICR7c3RkZXJyLmpvaW4oXCJcXG5cIil9YFxuICAgICAgICApO1xuICAgICAgICByZWplY3QoXG4gICAgICAgICAgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgICAgICBgQ29tbWFuZCBmYWlsZWQgd2l0aCBjb2RlICR7Y29kZX06ICR7c3RkZXJyLmpvaW4oXCJcXG5cIil9YFxuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGNoaWxkLm9uKFwiZXJyb3JcIiwgKGVycjogRXJyb3IpID0+IHtcbiAgICAgIGxvZy5jcml0aWNhbChgQ29tbWFuZCBleGVjdXRpb24gZXJyb3JgLCBlcnIpO1xuICAgICAgcmVqZWN0KGVycik7XG4gICAgfSk7XG4gIH0pO1xufVxuIiwiZXhwb3J0IGVudW0gSXNvbGF0aW9uVGllciB7XG4gIFBvb2xlZCA9IFwicG9vbGVkXCIsXG4gIEJyaWRnZSA9IFwiYnJpZGdlXCIsXG4gIFNpbG8gPSBcInNpbG9cIixcbn1cblxuZXhwb3J0IGVudW0gTWVtYmVyc2hpcFN0YXR1cyB7XG4gIEludml0ZWQgPSBcImludml0ZWRcIixcbiAgQWN0aXZlID0gXCJhY3RpdmVcIixcbiAgU3VzcGVuZGVkID0gXCJzdXNwZW5kZWRcIixcbiAgUmVtb3ZlZCA9IFwicmVtb3ZlZFwiLFxufVxuXG5leHBvcnQgZW51bSBQcmluY2lwYWxLaW5kIHtcbiAgVXNlciA9IFwidXNlclwiLFxuICBHcm91cCA9IFwiZ3JvdXBcIixcbiAgU2VydmljZUFjY291bnQgPSBcInNlcnZpY2VfYWNjb3VudFwiLFxuICBBZ2VudCA9IFwiYWdlbnRcIixcbiAgQXBpS2V5ID0gXCJhcGlfa2V5XCIsXG59XG5cbmV4cG9ydCBlbnVtIFNjb3BlS2luZCB7XG4gIFRlbmFudCA9IFwidGVuYW50XCIsXG4gIE9yZ1VuaXQgPSBcIm9yZ191bml0XCIsXG4gIFJlc291cmNlID0gXCJyZXNvdXJjZVwiLFxufVxuXG5leHBvcnQgZW51bSBQZXJtaXNzaW9uQ2F0ZWdvcnkge1xuICBBZG1pbiA9IFwiYWRtaW5cIixcbiAgQ29udGVudFJlYWQgPSBcImNvbnRlbnRfcmVhZFwiLFxuICBDb250ZW50V3JpdGUgPSBcImNvbnRlbnRfd3JpdGVcIixcbiAgTWVtb3J5ID0gXCJtZW1vcnlcIixcbiAgR3JhcGggPSBcImdyYXBoXCIsXG4gIFZlY3RvciA9IFwidmVjdG9yXCIsXG4gIEV4cG9ydCA9IFwiZXhwb3J0XCIsXG4gIEJpbGxpbmcgPSBcImJpbGxpbmdcIixcbiAgQXVkaXQgPSBcImF1ZGl0XCIsXG4gIFNlY3VyaXR5ID0gXCJzZWN1cml0eVwiLFxuICBEYXRhID0gXCJkYXRhXCIsXG4gIEF1dG9tYXRpb24gPSBcImF1dG9tYXRpb25cIixcbn1cblxuZXhwb3J0IGVudW0gUmVzb3VyY2VWaXNpYmlsaXR5IHtcbiAgUHJpdmF0ZSA9IFwicHJpdmF0ZVwiLFxuICBSZXNvdXJjZUFjbCA9IFwicmVzb3VyY2VfYWNsXCIsXG4gIE9yZ1VuaXQgPSBcIm9yZ191bml0XCIsXG4gIE9yZ1N1YnRyZWUgPSBcIm9yZ19zdWJ0cmVlXCIsXG4gIFRlbmFudCA9IFwidGVuYW50XCIsXG59XG5cbmV4cG9ydCBlbnVtIFN0b3JhZ2VLaW5kIHtcbiAgUG9zdGdyZXMgPSBcInBvc3RncmVzXCIsXG4gIEFyYW5nbyA9IFwiYXJhbmdvXCIsXG4gIFFkcmFudCA9IFwicWRyYW50XCIsXG4gIE9iamVjdFN0b3JhZ2UgPSBcIm9iamVjdF9zdG9yYWdlXCIsXG59XG5cbmV4cG9ydCBlbnVtIFN0b3JhZ2VCaW5kaW5nS2luZCB7XG4gIFNoYXJlZCA9IFwic2hhcmVkXCIsXG4gIERlZGljYXRlZCA9IFwiZGVkaWNhdGVkXCIsXG59XG5cbmV4cG9ydCBjb25zdCBJc29sYXRpb25UaWVyT3B0aW9ucyA9IE9iamVjdC52YWx1ZXMoSXNvbGF0aW9uVGllcik7XG5leHBvcnQgY29uc3QgTWVtYmVyc2hpcFN0YXR1c09wdGlvbnMgPSBPYmplY3QudmFsdWVzKE1lbWJlcnNoaXBTdGF0dXMpO1xuZXhwb3J0IGNvbnN0IFByaW5jaXBhbEtpbmRPcHRpb25zID0gT2JqZWN0LnZhbHVlcyhQcmluY2lwYWxLaW5kKTtcbmV4cG9ydCBjb25zdCBTY29wZUtpbmRPcHRpb25zID0gT2JqZWN0LnZhbHVlcyhTY29wZUtpbmQpO1xuZXhwb3J0IGNvbnN0IFBlcm1pc3Npb25DYXRlZ29yeU9wdGlvbnMgPSBPYmplY3QudmFsdWVzKFBlcm1pc3Npb25DYXRlZ29yeSk7XG5leHBvcnQgY29uc3QgUmVzb3VyY2VWaXNpYmlsaXR5T3B0aW9ucyA9IE9iamVjdC52YWx1ZXMoUmVzb3VyY2VWaXNpYmlsaXR5KTtcbmV4cG9ydCBjb25zdCBTdG9yYWdlS2luZE9wdGlvbnMgPSBPYmplY3QudmFsdWVzKFN0b3JhZ2VLaW5kKTtcbmV4cG9ydCBjb25zdCBTdG9yYWdlQmluZGluZ0tpbmRPcHRpb25zID0gT2JqZWN0LnZhbHVlcyhTdG9yYWdlQmluZGluZ0tpbmQpO1xuXG5leHBvcnQgdHlwZSBUeEFyZ3MgPSBhbnlbXTtcblxuZXhwb3J0IGludGVyZmFjZSBDcmVhdGVUZW5hbnRJbnB1dCB7XG4gIHNsdWc6IHN0cmluZztcbiAgbmFtZTogc3RyaW5nO1xuICBpc29sYXRpb25UaWVyPzogSXNvbGF0aW9uVGllcjtcbiAgcHJvZmlsZUtleT86IHN0cmluZztcbiAgcHJvZmlsZU1ldGFkYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ3JlYXRlVXNlcklucHV0IHtcbiAgZW1haWw/OiBzdHJpbmc7XG4gIHBob25lPzogc3RyaW5nO1xuICBkaXNwbGF5TmFtZTogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENyZWF0ZU9yZ1VuaXRJbnB1dCB7XG4gIHRlbmFudElkOiBzdHJpbmc7XG4gIHBhcmVudE9yZ1VuaXRJZD86IHN0cmluZztcbiAgbmFtZTogc3RyaW5nO1xuICBtZXRhZGF0YT86IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICBwcm9maWxlS2V5Pzogc3RyaW5nO1xuICBwcm9maWxlTWV0YWRhdGE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDcmVhdGVSb2xlSW5wdXQge1xuICB0ZW5hbnRJZD86IHN0cmluZztcbiAga2V5OiBzdHJpbmc7XG4gIG5hbWU6IHN0cmluZztcbiAgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG4gIG1ldGFkYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ3JlYXRlUGVybWlzc2lvbklucHV0IHtcbiAga2V5OiBzdHJpbmc7XG4gIGNhdGVnb3J5OiBQZXJtaXNzaW9uQ2F0ZWdvcnk7XG4gIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFzc2lnblJvbGVJbnB1dCB7XG4gIHRlbmFudElkOiBzdHJpbmc7XG4gIHByaW5jaXBhbElkOiBzdHJpbmc7XG4gIHJvbGVJZDogc3RyaW5nO1xuICBzY29wZUtpbmQ6IFNjb3BlS2luZDtcbiAgc2NvcGVJZDogc3RyaW5nO1xuICBpbmhlcml0RG93bj86IGJvb2xlYW47XG4gIHN0YXJ0c0F0PzogRGF0ZTtcbiAgZXhwaXJlc0F0PzogRGF0ZTtcbiAgY29uZGl0aW9ucz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlZ2lzdGVyUmVzb3VyY2VJbnB1dCB7XG4gIHRlbmFudElkOiBzdHJpbmc7XG4gIG9yZ1VuaXRJZDogc3RyaW5nO1xuICByZXNvdXJjZVR5cGU6IHN0cmluZztcbiAgcmVzb3VyY2VJZDogc3RyaW5nO1xuICB2aXNpYmlsaXR5OiBSZXNvdXJjZVZpc2liaWxpdHk7XG4gIG93bmVyUHJpbmNpcGFsSWQ/OiBzdHJpbmc7XG4gIHNlbnNpdGl2aXR5Pzogc3RyaW5nO1xuICBtZXRhZGF0YT86IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdyYW50UmVzb3VyY2VJbnB1dCB7XG4gIHRlbmFudElkOiBzdHJpbmc7XG4gIHJlc291cmNlSWQ6IHN0cmluZztcbiAgcHJpbmNpcGFsSWQ6IHN0cmluZztcbiAgcGVybWlzc2lvbktleTogc3RyaW5nO1xuICBzdGFydHNBdD86IERhdGU7XG4gIGV4cGlyZXNBdD86IERhdGU7XG4gIGNvbmRpdGlvbnM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgY3JlYXRlZEJ5UHJpbmNpcGFsSWQ/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2FuQWNjZXNzSW5wdXQge1xuICB0ZW5hbnRJZDogc3RyaW5nO1xuICBwcmluY2lwYWxJZDogc3RyaW5nO1xuICBwZXJtaXNzaW9uS2V5OiBzdHJpbmc7XG4gIHJlc291cmNlUHJvdGVjdGVkSWQ/OiBzdHJpbmc7XG4gIHNjb3BlS2luZD86IFNjb3BlS2luZDtcbiAgc2NvcGVJZD86IHN0cmluZztcbiAgYXQ/OiBEYXRlO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFjY2Vzc0NvbnRleHQge1xuICB0ZW5hbnRJZDogc3RyaW5nO1xuICBwcmluY2lwYWxJZDogc3RyaW5nO1xuICBwZXJtaXNzaW9uc0J5U2NvcGU6IFJlY29yZDxzdHJpbmcsIHN0cmluZ1tdPjtcbiAgYWxsb3dlZE9yZ1VuaXRJZHNCeVBlcm1pc3Npb246IFJlY29yZDxzdHJpbmcsIHN0cmluZ1tdPjtcbiAgcmVzb3VyY2VHcmFudHM6IEFycmF5PHsgcmVzb3VyY2VJZDogc3RyaW5nOyBwZXJtaXNzaW9uS2V5OiBzdHJpbmcgfT47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXJhbmdvQXV0aENvbnRleHQge1xuICB0ZW5hbnRJZDogc3RyaW5nO1xuICBwcmluY2lwYWxJZDogc3RyaW5nO1xuICBwZXJtaXNzaW9uS2V5OiBzdHJpbmc7XG4gIGFsbG93ZWRPcmdVbml0SWRzOiBzdHJpbmdbXTtcbiAgYWxsb3dlZFJlc291cmNlSWRzOiBzdHJpbmdbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBRZHJhbnRBdXRoRmlsdGVyIHtcbiAgbXVzdDogQXJyYXk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+O1xuICBtdXN0X25vdD86IEFycmF5PFJlY29yZDxzdHJpbmcsIHVua25vd24+Pjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDcmVhdGVTdG9yYWdlQmluZGluZ0lucHV0IHtcbiAgdGVuYW50SWQ6IHN0cmluZztcbiAgc3RvcmFnZUtpbmQ6IFN0b3JhZ2VLaW5kO1xuICBiaW5kaW5nS2luZDogU3RvcmFnZUJpbmRpbmdLaW5kO1xuICBiaW5kaW5nS2V5OiBzdHJpbmc7XG4gIHJlZ2lvbjogc3RyaW5nO1xuICBjb25maWc/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBCb290c3RyYXBQZXJtaXNzaW9uIHtcbiAga2V5OiBzdHJpbmc7XG4gIGNhdGVnb3J5OiBQZXJtaXNzaW9uQ2F0ZWdvcnk7XG4gIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJvb3RzdHJhcFJvbGUge1xuICBrZXk6IHN0cmluZztcbiAgbmFtZTogc3RyaW5nO1xuICBkZXNjcmlwdGlvbj86IHN0cmluZztcbiAgcGVybWlzc2lvbktleXM6IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJvb3RzdHJhcE9yZ1VuaXQge1xuICBuYW1lOiBzdHJpbmc7XG4gIHByb2ZpbGVLZXk/OiBzdHJpbmc7XG4gIG1ldGFkYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIGNoaWxkcmVuPzogQm9vdHN0cmFwT3JnVW5pdFtdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJvb3RzdHJhcFRlbXBsYXRlIHtcbiAgdGVuYW50OiBDcmVhdGVUZW5hbnRJbnB1dDtcbiAgcm9vdE9yZ1VuaXQ6IEJvb3RzdHJhcE9yZ1VuaXQ7XG4gIHBlcm1pc3Npb25zOiBCb290c3RyYXBQZXJtaXNzaW9uW107XG4gIHJvbGVzOiBCb290c3RyYXBSb2xlW107XG4gIG93bmVyVXNlcjogQ3JlYXRlVXNlcklucHV0O1xuICBvd25lclJvbGVLZXk6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXNvdXJjZVNuYXBzaG90IHtcbiAgaWQ6IHN0cmluZztcbiAgdGVuYW50SWQ6IHN0cmluZztcbiAgb3JnVW5pdElkOiBzdHJpbmc7XG4gIHJlc291cmNlVHlwZTogc3RyaW5nO1xuICByZXNvdXJjZUlkOiBzdHJpbmc7XG4gIHZpc2liaWxpdHk6IFJlc291cmNlVmlzaWJpbGl0eTtcbiAgb3duZXJQcmluY2lwYWxJZD86IHN0cmluZztcbiAgc2Vuc2l0aXZpdHk/OiBzdHJpbmc7XG4gIG1ldGFkYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR3JhbnRTbmFwc2hvdCB7XG4gIGlkOiBzdHJpbmc7XG4gIHRlbmFudElkOiBzdHJpbmc7XG4gIHJlc291cmNlSWQ6IHN0cmluZztcbiAgcHJpbmNpcGFsSWQ6IHN0cmluZztcbiAgcGVybWlzc2lvbktleTogc3RyaW5nO1xuICBzdGFydHNBdD86IERhdGU7XG4gIGV4cGlyZXNBdD86IERhdGU7XG4gIGNvbmRpdGlvbnM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgY3JlYXRlZEJ5UHJpbmNpcGFsSWQ/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRWZmZWN0aXZlUGVybWlzc2lvblNuYXBzaG90IHtcbiAgaWQ6IHN0cmluZztcbiAgdGVuYW50SWQ6IHN0cmluZztcbiAgcHJpbmNpcGFsSWQ6IHN0cmluZztcbiAgcGVybWlzc2lvbktleTogc3RyaW5nO1xuICBzY29wZUtpbmQ6IFNjb3BlS2luZDtcbiAgc2NvcGVJZDogc3RyaW5nO1xuICBzb3VyY2VLaW5kOiBzdHJpbmc7XG4gIHNvdXJjZUlkOiBzdHJpbmc7XG4gIHN0YXJ0c0F0PzogRGF0ZTtcbiAgZXhwaXJlc0F0PzogRGF0ZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBdXRoekRhdGFTb3VyY2VzIHtcbiAgbG9hZFJlc291cmNlPzogKHRlbmFudElkOiBzdHJpbmcsIHByb3RlY3RlZFJlc291cmNlSWQ6IHN0cmluZykgPT4gUHJvbWlzZTxSZXNvdXJjZVNuYXBzaG90IHwgdW5kZWZpbmVkPjtcbiAgbGlzdFJlc291cmNlR3JhbnRzPzogKHRlbmFudElkOiBzdHJpbmcsIHByb3RlY3RlZFJlc291cmNlSWQ6IHN0cmluZykgPT4gUHJvbWlzZTxHcmFudFNuYXBzaG90W10+O1xuICBsaXN0UHJpbmNpcGFsR3JhbnRzPzogKHRlbmFudElkOiBzdHJpbmcsIHByaW5jaXBhbElkOiBzdHJpbmcpID0+IFByb21pc2U8R3JhbnRTbmFwc2hvdFtdPjtcbiAgbGlzdEVmZmVjdGl2ZVBlcm1pc3Npb25zPzogKFxuICAgIHRlbmFudElkOiBzdHJpbmcsXG4gICAgcHJpbmNpcGFsSWQ6IHN0cmluZ1xuICApID0+IFByb21pc2U8RWZmZWN0aXZlUGVybWlzc2lvblNuYXBzaG90W10+O1xuICBsaXN0RWZmZWN0aXZlUGVybWlzc2lvbnNGb3JTY29wZT86IChcbiAgICB0ZW5hbnRJZDogc3RyaW5nLFxuICAgIHNjb3BlS2luZDogU2NvcGVLaW5kLFxuICAgIHNjb3BlSWQ6IHN0cmluZ1xuICApID0+IFByb21pc2U8RWZmZWN0aXZlUGVybWlzc2lvblNuYXBzaG90W10+O1xufVxuIiwiaW1wb3J0IHsgQ2FzY2FkZSwgTW9kZWxTZXJ2aWNlLCBSZXBvc2l0b3J5IH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7XG4gIEFjY2Vzc0NvbnRleHQsXG4gIEFyYW5nb0F1dGhDb250ZXh0LFxuICBFZmZlY3RpdmVQZXJtaXNzaW9uU25hcHNob3QsXG4gIEdyYW50U25hcHNob3QsXG4gIFFkcmFudEF1dGhGaWx0ZXIsXG4gIFNjb3BlS2luZCxcbn0gZnJvbSBcIi4vdHlwZXNcIjtcblxuZXhwb3J0IGNvbnN0IFJFTF9SRVNUUklDVCA9IHtcbiAgdXBkYXRlOiBDYXNjYWRlLk5PTkUsXG4gIGRlbGV0ZTogQ2FzY2FkZS5OT05FLFxuICBudWxsYWJsZTogZmFsc2UsXG59IGFzIGNvbnN0O1xuXG5leHBvcnQgY29uc3QgUkVMX05VTExJRlkgPSB7XG4gIHVwZGF0ZTogQ2FzY2FkZS5OT05FLFxuICBkZWxldGU6IENhc2NhZGUuTk9ORSxcbiAgbnVsbGFibGU6IHRydWUsXG59IGFzIGNvbnN0O1xuXG5leHBvcnQgY29uc3QgUkVMX0NBU0NBREVfREVQRU5ERU5UID0ge1xuICB1cGRhdGU6IENhc2NhZGUuQ0FTQ0FERSxcbiAgZGVsZXRlOiBDYXNjYWRlLkNBU0NBREUsXG4gIG51bGxhYmxlOiBmYWxzZSxcbn0gYXMgY29uc3Q7XG5cbmV4cG9ydCBjb25zdCBSRUxfQ0FTQ0FERV9JTlNFUlRfVVBEQVRFID0ge1xuICB1cGRhdGU6IENhc2NhZGUuQ0FTQ0FERSxcbiAgZGVsZXRlOiBDYXNjYWRlLk5PTkUsXG4gIG51bGxhYmxlOiBmYWxzZSxcbn0gYXMgY29uc3Q7XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZEFyYW5nb0NvbnRleHQob3B0aW9uczoge1xuICB0ZW5hbnRJZDogc3RyaW5nO1xuICBwcmluY2lwYWxJZDogc3RyaW5nO1xuICBwZXJtaXNzaW9uS2V5OiBzdHJpbmc7XG4gIGFsbG93ZWRPcmdVbml0SWRzOiBzdHJpbmdbXTtcbiAgYWxsb3dlZFJlc291cmNlSWRzOiBzdHJpbmdbXTtcbn0pOiBBcmFuZ29BdXRoQ29udGV4dCB7XG4gIHJldHVybiB7XG4gICAgdGVuYW50SWQ6IG9wdGlvbnMudGVuYW50SWQsXG4gICAgcHJpbmNpcGFsSWQ6IG9wdGlvbnMucHJpbmNpcGFsSWQsXG4gICAgcGVybWlzc2lvbktleTogb3B0aW9ucy5wZXJtaXNzaW9uS2V5LFxuICAgIGFsbG93ZWRPcmdVbml0SWRzOiBbLi4ub3B0aW9ucy5hbGxvd2VkT3JnVW5pdElkc10sXG4gICAgYWxsb3dlZFJlc291cmNlSWRzOiBbLi4ub3B0aW9ucy5hbGxvd2VkUmVzb3VyY2VJZHNdLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRRZHJhbnRGaWx0ZXIob3B0aW9uczoge1xuICB0ZW5hbnRJZDogc3RyaW5nO1xuICBwcmluY2lwYWxJZDogc3RyaW5nO1xuICBwZXJtaXNzaW9uS2V5OiBzdHJpbmc7XG4gIGFsbG93ZWRPcmdVbml0SWRzOiBzdHJpbmdbXTtcbiAgYWxsb3dlZFJlc291cmNlSWRzOiBzdHJpbmdbXTtcbn0pOiBRZHJhbnRBdXRoRmlsdGVyIHtcbiAgcmV0dXJuIHtcbiAgICBtdXN0OiBbXG4gICAgICB7XG4gICAgICAgIGtleTogXCJ0ZW5hbnRfaWRcIixcbiAgICAgICAgbWF0Y2g6IHsgdmFsdWU6IG9wdGlvbnMudGVuYW50SWQgfSxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIHNob3VsZDogW1xuICAgICAgICAgIHsga2V5OiBcIm9yZ191bml0X2lkXCIsIG1hdGNoOiB7IGFueTogb3B0aW9ucy5hbGxvd2VkT3JnVW5pdElkcyB9IH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAga2V5OiBcInByb3RlY3RlZF9yZXNvdXJjZV9pZFwiLFxuICAgICAgICAgICAgbWF0Y2g6IHsgYW55OiBvcHRpb25zLmFsbG93ZWRSZXNvdXJjZUlkcyB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgeyBrZXk6IFwib3duZXJfcHJpbmNpcGFsX2lkXCIsIG1hdGNoOiB7IHZhbHVlOiBvcHRpb25zLnByaW5jaXBhbElkIH0gfSxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgXSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gc2NvcGVLZXkoc2NvcGVLaW5kOiBTY29wZUtpbmQsIHNjb3BlSWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgJHtzY29wZUtpbmR9OiR7c2NvcGVJZH1gO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbm93SXNvKCk6IERhdGUge1xuICByZXR1cm4gbmV3IERhdGUoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFzQXJyYXk8VD4odmFsdWU6IFRbXSB8IHVuZGVmaW5lZCk6IFRbXSB7XG4gIHJldHVybiB2YWx1ZSA/PyBbXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNhbWVUZW5hbnQocm93VGVuYW50OiB1bmtub3duLCB0ZW5hbnRJZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiByZWxhdGlvbklkKHJvd1RlbmFudCBhcyB7IGlkOiBzdHJpbmcgfSB8IHN0cmluZykgPT09IHRlbmFudElkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVsYXRpb25NYXRjaChcbiAgdmFsdWU6IHVua25vd24sXG4gIHRhcmdldDogc3RyaW5nIHwgdW5kZWZpbmVkXG4pOiBib29sZWFuIHtcbiAgcmV0dXJuIHRhcmdldFxuICAgID8gcmVsYXRpb25JZCh2YWx1ZSBhcyB7IGlkOiBzdHJpbmcgfSB8IHN0cmluZykgPT09IHRhcmdldFxuICAgIDogZmFsc2U7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBsb3dlclNsdWcodmFsdWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiAoXG4gICAgdmFsdWVcbiAgICAgIC50cmltKClcbiAgICAgIC50b0xvd2VyQ2FzZSgpXG4gICAgICAucmVwbGFjZSgvW15hLXowLTldKy9nLCBcIi1cIilcbiAgICAgIC5yZXBsYWNlKC9eLSt8LSskL2csIFwiXCIpIHx8IFwiaXRlbVwiXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1RpbWVWYWxpZChcbiAgYXQ6IERhdGUgfCB1bmRlZmluZWQsXG4gIHN0YXJ0c0F0PzogRGF0ZSxcbiAgZXhwaXJlc0F0PzogRGF0ZVxuKTogYm9vbGVhbiB7XG4gIGNvbnN0IGluc3RhbnQgPSBhdCA/PyBuZXcgRGF0ZSgpO1xuICBpZiAoc3RhcnRzQXQgJiYgaW5zdGFudCA8IHN0YXJ0c0F0KSByZXR1cm4gZmFsc2U7XG4gIGlmIChleHBpcmVzQXQgJiYgaW5zdGFudCA+IGV4cGlyZXNBdCkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkQWNjZXNzQ29udGV4dChvcHRpb25zOiB7XG4gIHRlbmFudElkOiBzdHJpbmc7XG4gIHByaW5jaXBhbElkOiBzdHJpbmc7XG4gIHBlcm1pc3Npb25zOiBFZmZlY3RpdmVQZXJtaXNzaW9uU25hcHNob3RbXTtcbiAgZ3JhbnRzOiBHcmFudFNuYXBzaG90W107XG59KTogQWNjZXNzQ29udGV4dCB7XG4gIGNvbnN0IHBlcm1pc3Npb25zQnlTY29wZTogUmVjb3JkPHN0cmluZywgc3RyaW5nW10+ID0ge307XG4gIGNvbnN0IGFsbG93ZWRPcmdVbml0SWRzQnlQZXJtaXNzaW9uOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmdbXT4gPSB7fTtcblxuICBmb3IgKGNvbnN0IHBlcm1pc3Npb24gb2Ygb3B0aW9ucy5wZXJtaXNzaW9ucykge1xuICAgIGNvbnN0IGtleSA9IHNjb3BlS2V5KHBlcm1pc3Npb24uc2NvcGVLaW5kLCBwZXJtaXNzaW9uLnNjb3BlSWQpO1xuICAgIHBlcm1pc3Npb25zQnlTY29wZVtrZXldID0gcGVybWlzc2lvbnNCeVNjb3BlW2tleV0gPz8gW107XG4gICAgcGVybWlzc2lvbnNCeVNjb3BlW2tleV0ucHVzaChwZXJtaXNzaW9uLnBlcm1pc3Npb25LZXkpO1xuICAgIGlmIChwZXJtaXNzaW9uLnNjb3BlS2luZCA9PT0gU2NvcGVLaW5kLk9yZ1VuaXQpIHtcbiAgICAgIGFsbG93ZWRPcmdVbml0SWRzQnlQZXJtaXNzaW9uW3Blcm1pc3Npb24ucGVybWlzc2lvbktleV0gPVxuICAgICAgICBhbGxvd2VkT3JnVW5pdElkc0J5UGVybWlzc2lvbltwZXJtaXNzaW9uLnBlcm1pc3Npb25LZXldID8/IFtdO1xuICAgICAgYWxsb3dlZE9yZ1VuaXRJZHNCeVBlcm1pc3Npb25bcGVybWlzc2lvbi5wZXJtaXNzaW9uS2V5XS5wdXNoKFxuICAgICAgICBwZXJtaXNzaW9uLnNjb3BlSWRcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB0ZW5hbnRJZDogb3B0aW9ucy50ZW5hbnRJZCxcbiAgICBwcmluY2lwYWxJZDogb3B0aW9ucy5wcmluY2lwYWxJZCxcbiAgICBwZXJtaXNzaW9uc0J5U2NvcGUsXG4gICAgYWxsb3dlZE9yZ1VuaXRJZHNCeVBlcm1pc3Npb24sXG4gICAgcmVzb3VyY2VHcmFudHM6IG9wdGlvbnMuZ3JhbnRzLm1hcCgoZ3JhbnQpID0+ICh7XG4gICAgICByZXNvdXJjZUlkOiBncmFudC5yZXNvdXJjZUlkLFxuICAgICAgcGVybWlzc2lvbktleTogZ3JhbnQucGVybWlzc2lvbktleSxcbiAgICB9KSksXG4gIH07XG59XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBCYXNlTW9kZWxTZXJ2aWNlPFxuICBNIGV4dGVuZHMgTW9kZWw8Ym9vbGVhbj4gJiB7IGlkOiBzdHJpbmcgfSxcbj4gZXh0ZW5kcyBNb2RlbFNlcnZpY2U8TSwgUmVwb3NpdG9yeTxNLCBhbnk+PiB7XG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihjbGF6ejogbmV3ICgpID0+IE0pIHtcbiAgICBzdXBlcihjbGF6eik7XG4gIH1cblxuICBwcm90ZWN0ZWQgbmV3TW9kZWw8VD4oY2xheno6IG5ldyAoKSA9PiBULCBkYXRhOiBQYXJ0aWFsPFQ+KTogVCB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24obmV3IGNsYXp6KCkgYXMgb2JqZWN0LCBkYXRhIGFzIG9iamVjdCkgYXMgVDtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZShkYXRhOiBQYXJ0aWFsPE0+LCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8TT4ge1xuICAgIHJldHVybiB0aGlzLnJlcG8uY3JlYXRlKE9iamVjdC5hc3NpZ24oe30gYXMgTSwgZGF0YSBhcyBvYmplY3QpLCAuLi5hcmdzKTtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZU9uZShkYXRhOiBQYXJ0aWFsPE0+LCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8TT4ge1xuICAgIHJldHVybiB0aGlzLmNyZWF0ZShkYXRhLCAuLi5hcmdzKTtcbiAgfVxuXG4gIGFzeW5jIGdldEJ5SWQoaWQ6IHN0cmluZywgLi4uYXJnczogYW55W10pOiBQcm9taXNlPE0+IHtcbiAgICByZXR1cm4gdGhpcy5yZXBvLnJlYWQoaWQsIC4uLmFyZ3MpO1xuICB9XG5cbiAgYXN5bmMgdXBkYXRlT25lKGlkOiBzdHJpbmcsIHBhdGNoOiBQYXJ0aWFsPE0+LCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8TT4ge1xuICAgIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgdGhpcy5yZXBvLnJlYWQoaWQsIC4uLmFyZ3MpO1xuICAgIHJldHVybiB0aGlzLnJlcG8udXBkYXRlKE9iamVjdC5hc3NpZ24oZXhpc3RpbmcsIHBhdGNoKSwgLi4uYXJncyk7XG4gIH1cblxuICBhc3luYyBkZWxldGVCeUlkKGlkOiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5yZXBvLmRlbGV0ZShpZCwgLi4uYXJncyk7XG4gIH1cblxuICBhc3luYyBmaW5kT25lQnk8SyBleHRlbmRzIGtleW9mIE0gJiBzdHJpbmc+KFxuICAgIGtleTogSyxcbiAgICB2YWx1ZTogTVtLXSxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPE0+IHtcbiAgICByZXR1cm4gdGhpcy5yZXBvLmZpbmRPbmVCeShrZXksIHZhbHVlLCAuLi5hcmdzKTtcbiAgfVxuXG4gIGFzeW5jIGZpbmRNYW55Qnk8SyBleHRlbmRzIGtleW9mIE0gJiBzdHJpbmc+KFxuICAgIGtleTogSyxcbiAgICB2YWx1ZTogTVtLXSxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPE1bXT4ge1xuICAgIHJldHVybiB0aGlzLnJlcG9cbiAgICAgIC5zZWxlY3QoKVxuICAgICAgLndoZXJlKHsgW2tleV06IHZhbHVlIH0gYXMgYW55KVxuICAgICAgLmV4ZWN1dGUoLi4uYXJncyk7XG4gIH1cblxuICBhc3luYyBsaXN0QWxsKC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxNW10+IHtcbiAgICByZXR1cm4gdGhpcy5yZXBvLnNlbGVjdCgpLmV4ZWN1dGUoLi4uYXJncyk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlkKCk6IHN0cmluZyB7XG4gIHJldHVybiBjcnlwdG8ucmFuZG9tVVVJRCgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVsYXRpb25JZCh2YWx1ZTogc3RyaW5nIHwgeyBpZDogc3RyaW5nIH0pOiBzdHJpbmcge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiID8gdmFsdWUgOiB2YWx1ZS5pZDtcbn1cblxuZXhwb3J0IHsgQXV0aG9yaXphdGlvbkVycm9yLCB0cmFuc2FjdGlvbmFsIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG4iLCJpbXBvcnQgeyBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEF1dGhvcml6YXRpb25Nb2RlbCBleHRlbmRzIE1vZGVsIHtcbiAgY29uc3RydWN0b3IoZGF0YT86IHVua25vd24pIHtcbiAgICBzdXBlcihkYXRhIGFzIG5ldmVyKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgY29sdW1uLCBjcmVhdGVkQXQsIG1hbnlUb09uZSwgcGssIHRhYmxlLCB1cGRhdGVkQXQsIHV1aWQgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IG1vZGVsLCBvcHRpb24sIHJlcXVpcmVkLCB0eXBlIGFzIHR5cGVPZiB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IE1lbWJlcnNoaXBTdGF0dXMsIE1lbWJlcnNoaXBTdGF0dXNPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBSRUxfQ0FTQ0FERV9ERVBFTkRFTlQgfSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCB7IEF1dGhvcml6YXRpb25Nb2RlbCB9IGZyb20gXCIuL2F1dGhvcml6YXRpb24tbW9kZWxcIjtcbmltcG9ydCB7IFRlbmFudCB9IGZyb20gXCIuL3RlbmFudC5tb2RlbFwiO1xuaW1wb3J0IHsgVXNlciB9IGZyb20gXCIuL3VzZXIubW9kZWxcIjtcblxuQHRhYmxlKFwidGVuYW50X21lbWJlcnNoaXBzXCIpXG5AbW9kZWwoKVxuZXhwb3J0IGNsYXNzIFRlbmFudE1lbWJlcnNoaXAgZXh0ZW5kcyBBdXRob3JpemF0aW9uTW9kZWwge1xuICBjb25zdHJ1Y3RvcihkYXRhPzogdW5rbm93bikge1xuICAgIHN1cGVyKGRhdGEpO1xuICB9XG5cbiAgQHBrKHsgdHlwZTogU3RyaW5nIH0pIEB1dWlkKCkgaWQhOiBzdHJpbmc7XG4gIEBtYW55VG9PbmUoKCkgPT4gVGVuYW50LCBSRUxfQ0FTQ0FERV9ERVBFTkRFTlQsIGZhbHNlLCB1bmRlZmluZWQsIFwiZmtfdGVuYW50X21lbWJlcnNoaXBzX3RlbmFudFwiKVxuICBAcmVxdWlyZWQoKVxuICB0ZW5hbnQhOiBUZW5hbnQgfCBzdHJpbmc7XG4gIEBtYW55VG9PbmUoKCkgPT4gVXNlciwgUkVMX0NBU0NBREVfREVQRU5ERU5ULCBmYWxzZSwgdW5kZWZpbmVkLCBcImZrX3RlbmFudF9tZW1iZXJzaGlwc191c2VyXCIpXG4gIEByZXF1aXJlZCgpXG4gIHVzZXIhOiBVc2VyIHwgc3RyaW5nO1xuICBAcmVxdWlyZWQoKSBAdHlwZU9mKFN0cmluZykgQG9wdGlvbihNZW1iZXJzaGlwU3RhdHVzT3B0aW9ucykgQGNvbHVtbigpIHN0YXR1cyE6IE1lbWJlcnNoaXBTdGF0dXM7XG4gIEBjcmVhdGVkQXQoKSBjcmVhdGVkQXQhOiBEYXRlO1xuICBAdXBkYXRlZEF0KCkgdXBkYXRlZEF0ITogRGF0ZTtcbn1cbiIsImltcG9ydCB7XG4gIGNvbHVtbixcbiAgY3JlYXRlZEF0LFxuICBvbmVUb01hbnksXG4gIHBrLFxuICB0YWJsZSxcbiAgdW5pcXVlLFxuICB1cGRhdGVkQXQsXG4gIHV1aWQsXG59IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHsgbW9kZWwsIHJlcXVpcmVkLCB0eXBlIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgUkVMX1JFU1RSSUNUIH0gZnJvbSBcIi4uL3V0aWxzXCI7XG5pbXBvcnQgeyBBdXRob3JpemF0aW9uTW9kZWwgfSBmcm9tIFwiLi9hdXRob3JpemF0aW9uLW1vZGVsXCI7XG5pbXBvcnQgeyBUZW5hbnRNZW1iZXJzaGlwIH0gZnJvbSBcIi4vdGVuYW50LW1lbWJlcnNoaXAubW9kZWxcIjtcbmltcG9ydCB7IE9yZ1VuaXRNZW1iZXJzaGlwIH0gZnJvbSBcIi4vb3JnLXVuaXQtbWVtYmVyc2hpcC5tb2RlbFwiO1xuXG5AdGFibGUoXCJ1c2Vyc1wiKVxuQG1vZGVsKClcbmV4cG9ydCBjbGFzcyBVc2VyIGV4dGVuZHMgQXV0aG9yaXphdGlvbk1vZGVsIHtcbiAgQHBrKHsgdHlwZTogU3RyaW5nIH0pXG4gIEB1dWlkKClcbiAgaWQhOiBzdHJpbmc7XG5cbiAgQHVuaXF1ZSgpXG4gIEB0eXBlKFN0cmluZylcbiAgQGNvbHVtbigpXG4gIGVtYWlsPzogc3RyaW5nO1xuXG4gIEB1bmlxdWUoKVxuICBAdHlwZShTdHJpbmcpXG4gIEBjb2x1bW4oKVxuICBwaG9uZT86IHN0cmluZztcblxuICBAcmVxdWlyZWQoKVxuICBAdHlwZShTdHJpbmcpXG4gIEBjb2x1bW4oKVxuICBkaXNwbGF5TmFtZSE6IHN0cmluZztcblxuICBAb25lVG9NYW55KCgpID0+IFRlbmFudE1lbWJlcnNoaXAsIFJFTF9SRVNUUklDVCwgZmFsc2UpXG4gIHRlbmFudE1lbWJlcnNoaXBzPzogVGVuYW50TWVtYmVyc2hpcFtdIHwgc3RyaW5nW107XG5cbiAgQG9uZVRvTWFueSgoKSA9PiBPcmdVbml0TWVtYmVyc2hpcCwgUkVMX1JFU1RSSUNULCBmYWxzZSlcbiAgb3JnVW5pdE1lbWJlcnNoaXBzPzogT3JnVW5pdE1lbWJlcnNoaXBbXSB8IHN0cmluZ1tdO1xuXG4gIEBjcmVhdGVkQXQoKVxuICBjcmVhdGVkQXQhOiBEYXRlO1xuXG4gIEB1cGRhdGVkQXQoKVxuICB1cGRhdGVkQXQhOiBEYXRlO1xuXG4gIGNvbnN0cnVjdG9yKGRhdGE/OiB1bmtub3duKSB7XG4gICAgc3VwZXIoZGF0YSk7XG4gIH1cbn1cbiIsImltcG9ydCB7IGNvbHVtbiwgY3JlYXRlZEF0LCBtYW55VG9PbmUsIHBrLCB0YWJsZSwgdXBkYXRlZEF0LCB1dWlkIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBtb2RlbCwgb3B0aW9uLCByZXF1aXJlZCwgdHlwZSBhcyB0eXBlT2YgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBNZW1iZXJzaGlwU3RhdHVzLCBNZW1iZXJzaGlwU3RhdHVzT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgUkVMX0NBU0NBREVfREVQRU5ERU5ULCBSRUxfUkVTVFJJQ1QgfSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCB7IEF1dGhvcml6YXRpb25Nb2RlbCB9IGZyb20gXCIuL2F1dGhvcml6YXRpb24tbW9kZWxcIjtcbmltcG9ydCB7IFRlbmFudCB9IGZyb20gXCIuL3RlbmFudC5tb2RlbFwiO1xuaW1wb3J0IHsgT3JnVW5pdCB9IGZyb20gXCIuL29yZy11bml0Lm1vZGVsXCI7XG5pbXBvcnQgeyBVc2VyIH0gZnJvbSBcIi4vdXNlci5tb2RlbFwiO1xuXG5AdGFibGUoXCJvcmdfdW5pdF9tZW1iZXJzaGlwc1wiKVxuQG1vZGVsKClcbmV4cG9ydCBjbGFzcyBPcmdVbml0TWVtYmVyc2hpcCBleHRlbmRzIEF1dGhvcml6YXRpb25Nb2RlbCB7XG4gIGNvbnN0cnVjdG9yKGRhdGE/OiB1bmtub3duKSB7XG4gICAgc3VwZXIoZGF0YSk7XG4gIH1cblxuICBAcGsoeyB0eXBlOiBTdHJpbmcgfSkgQHV1aWQoKSBpZCE6IHN0cmluZztcbiAgQG1hbnlUb09uZSgoKSA9PiBUZW5hbnQsIFJFTF9DQVNDQURFX0RFUEVOREVOVCwgZmFsc2UsIHVuZGVmaW5lZCwgXCJma19vcmdfbWVtYmVyc2hpcHNfdGVuYW50XCIpXG4gIEByZXF1aXJlZCgpXG4gIHRlbmFudCE6IFRlbmFudCB8IHN0cmluZztcbiAgQG1hbnlUb09uZSgoKSA9PiBPcmdVbml0LCBSRUxfQ0FTQ0FERV9ERVBFTkRFTlQsIGZhbHNlLCB1bmRlZmluZWQsIFwiZmtfb3JnX21lbWJlcnNoaXBzX29yZ191bml0XCIpXG4gIEByZXF1aXJlZCgpXG4gIG9yZ1VuaXQhOiBPcmdVbml0IHwgc3RyaW5nO1xuICBAbWFueVRvT25lKCgpID0+IFVzZXIsIFJFTF9SRVNUUklDVCwgZmFsc2UsIHVuZGVmaW5lZCwgXCJma19vcmdfbWVtYmVyc2hpcHNfdXNlclwiKVxuICBAcmVxdWlyZWQoKVxuICB1c2VyITogVXNlciB8IHN0cmluZztcbiAgQHJlcXVpcmVkKCkgQHR5cGVPZihTdHJpbmcpIEBvcHRpb24oTWVtYmVyc2hpcFN0YXR1c09wdGlvbnMpIEBjb2x1bW4oKSBzdGF0dXMhOiBNZW1iZXJzaGlwU3RhdHVzO1xuICBAY3JlYXRlZEF0KCkgY3JlYXRlZEF0ITogRGF0ZTtcbiAgQHVwZGF0ZWRBdCgpIHVwZGF0ZWRBdCE6IERhdGU7XG59XG4iLCJpbXBvcnQgeyBjb2x1bW4sIGNyZWF0ZWRBdCwgbWFueVRvT25lLCBwaywgdGFibGUsIHV1aWQgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IG1vZGVsLCByZXF1aXJlZCwgdHlwZSBhcyB0eXBlT2YgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBSRUxfQ0FTQ0FERV9ERVBFTkRFTlQgfSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCB7IEF1dGhvcml6YXRpb25Nb2RlbCB9IGZyb20gXCIuL2F1dGhvcml6YXRpb24tbW9kZWxcIjtcbmltcG9ydCB7IFRlbmFudCB9IGZyb20gXCIuL3RlbmFudC5tb2RlbFwiO1xuaW1wb3J0IHsgT3JnVW5pdCB9IGZyb20gXCIuL29yZy11bml0Lm1vZGVsXCI7XG5cbkB0YWJsZShcIm9yZ191bml0X2Nsb3N1cmVcIilcbkBtb2RlbCgpXG5leHBvcnQgY2xhc3MgT3JnVW5pdENsb3N1cmUgZXh0ZW5kcyBBdXRob3JpemF0aW9uTW9kZWwge1xuICBjb25zdHJ1Y3RvcihkYXRhPzogdW5rbm93bikge1xuICAgIHN1cGVyKGRhdGEpO1xuICB9XG5cbiAgQHBrKHsgdHlwZTogU3RyaW5nIH0pIEB1dWlkKCkgaWQhOiBzdHJpbmc7XG4gIEBtYW55VG9PbmUoKCkgPT4gVGVuYW50LCBSRUxfQ0FTQ0FERV9ERVBFTkRFTlQsIGZhbHNlLCB1bmRlZmluZWQsIFwiZmtfb3JnX2Nsb3N1cmVfdGVuYW50XCIpXG4gIEByZXF1aXJlZCgpXG4gIHRlbmFudCE6IFRlbmFudCB8IHN0cmluZztcbiAgQG1hbnlUb09uZSgoKSA9PiBPcmdVbml0LCBSRUxfQ0FTQ0FERV9ERVBFTkRFTlQsIGZhbHNlLCB1bmRlZmluZWQsIFwiZmtfb3JnX2Nsb3N1cmVfYW5jZXN0b3JcIilcbiAgQHJlcXVpcmVkKClcbiAgYW5jZXN0b3IhOiBPcmdVbml0IHwgc3RyaW5nO1xuICBAbWFueVRvT25lKCgpID0+IE9yZ1VuaXQsIFJFTF9DQVNDQURFX0RFUEVOREVOVCwgZmFsc2UsIHVuZGVmaW5lZCwgXCJma19vcmdfY2xvc3VyZV9kZXNjZW5kYW50XCIpXG4gIEByZXF1aXJlZCgpXG4gIGRlc2NlbmRhbnQhOiBPcmdVbml0IHwgc3RyaW5nO1xuICBAcmVxdWlyZWQoKSBAdHlwZU9mKE51bWJlcikgQGNvbHVtbigpIGRlcHRoITogbnVtYmVyO1xuICBAY3JlYXRlZEF0KCkgY3JlYXRlZEF0ITogRGF0ZTtcbn1cbiIsImltcG9ydCB7IGNvbHVtbiwgb25lVG9NYW55LCBwaywgdGFibGUsIHVuaXF1ZSwgdXVpZCB9IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHsgbW9kZWwsIG9wdGlvbiwgcmVxdWlyZWQsIHR5cGUgYXMgdHlwZU9mIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgUGVybWlzc2lvbkNhdGVnb3J5LCBQZXJtaXNzaW9uQ2F0ZWdvcnlPcHRpb25zIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBSRUxfUkVTVFJJQ1QgfSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCB7IEF1dGhvcml6YXRpb25Nb2RlbCB9IGZyb20gXCIuL2F1dGhvcml6YXRpb24tbW9kZWxcIjtcbmltcG9ydCB7IFJvbGVQZXJtaXNzaW9uIH0gZnJvbSBcIi4vcm9sZS1wZXJtaXNzaW9uLm1vZGVsXCI7XG5cbkB0YWJsZShcInBlcm1pc3Npb25zXCIpXG5AbW9kZWwoKVxuZXhwb3J0IGNsYXNzIFBlcm1pc3Npb24gZXh0ZW5kcyBBdXRob3JpemF0aW9uTW9kZWwge1xuICBjb25zdHJ1Y3RvcihkYXRhPzogdW5rbm93bikge1xuICAgIHN1cGVyKGRhdGEpO1xuICB9XG5cbiAgQHBrKHsgdHlwZTogU3RyaW5nIH0pIEB1dWlkKCkgaWQhOiBzdHJpbmc7XG4gIEB1bmlxdWUoKSBAcmVxdWlyZWQoKSBAdHlwZU9mKFN0cmluZykgQGNvbHVtbigpIGtleSE6IHN0cmluZztcbiAgQHJlcXVpcmVkKCkgQHR5cGVPZihTdHJpbmcpIEBvcHRpb24oUGVybWlzc2lvbkNhdGVnb3J5T3B0aW9ucykgQGNvbHVtbigpIGNhdGVnb3J5ITogUGVybWlzc2lvbkNhdGVnb3J5O1xuICBAdHlwZU9mKFN0cmluZykgQGNvbHVtbigpIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuICBAb25lVG9NYW55KCgpID0+IFJvbGVQZXJtaXNzaW9uLCBSRUxfUkVTVFJJQ1QsIGZhbHNlKSByb2xlUGVybWlzc2lvbnM/OiBSb2xlUGVybWlzc2lvbltdIHwgc3RyaW5nW107XG59XG4iLCJpbXBvcnQgeyBjcmVhdGVkQXQsIG1hbnlUb09uZSwgcGssIHRhYmxlLCB1dWlkIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBtb2RlbCwgcmVxdWlyZWQgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBSRUxfQ0FTQ0FERV9ERVBFTkRFTlQgfSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCB7IEF1dGhvcml6YXRpb25Nb2RlbCB9IGZyb20gXCIuL2F1dGhvcml6YXRpb24tbW9kZWxcIjtcbmltcG9ydCB7IFJvbGUgfSBmcm9tIFwiLi9yb2xlLm1vZGVsXCI7XG5pbXBvcnQgeyBQZXJtaXNzaW9uIH0gZnJvbSBcIi4vcGVybWlzc2lvbi5tb2RlbFwiO1xuXG5AdGFibGUoXCJyb2xlX3Blcm1pc3Npb25zXCIpXG5AbW9kZWwoKVxuZXhwb3J0IGNsYXNzIFJvbGVQZXJtaXNzaW9uIGV4dGVuZHMgQXV0aG9yaXphdGlvbk1vZGVsIHtcbiAgY29uc3RydWN0b3IoZGF0YT86IHVua25vd24pIHtcbiAgICBzdXBlcihkYXRhKTtcbiAgfVxuXG4gIEBwayh7IHR5cGU6IFN0cmluZyB9KSBAdXVpZCgpIGlkITogc3RyaW5nO1xuICBAbWFueVRvT25lKCgpID0+IFJvbGUsIFJFTF9DQVNDQURFX0RFUEVOREVOVCwgZmFsc2UsIHVuZGVmaW5lZCwgXCJma19yb2xlX3Blcm1pc3Npb25zX3JvbGVcIilcbiAgQHJlcXVpcmVkKClcbiAgcm9sZSE6IFJvbGUgfCBzdHJpbmc7XG4gIEBtYW55VG9PbmUoKCkgPT4gUGVybWlzc2lvbiwgUkVMX0NBU0NBREVfREVQRU5ERU5ULCBmYWxzZSwgdW5kZWZpbmVkLCBcImZrX3JvbGVfcGVybWlzc2lvbnNfcGVybWlzc2lvblwiKVxuICBAcmVxdWlyZWQoKVxuICBwZXJtaXNzaW9uITogUGVybWlzc2lvbiB8IHN0cmluZztcbiAgQGNyZWF0ZWRBdCgpIGNyZWF0ZWRBdCE6IERhdGU7XG59XG4iLCJpbXBvcnQgeyBjb2x1bW4sIGNyZWF0ZWRBdCwgbWFueVRvT25lLCBvbmVUb01hbnksIHBrLCB0YWJsZSwgdXBkYXRlZEF0LCB1dWlkIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBtb2RlbCwgcmVxdWlyZWQsIHR5cGUgYXMgdHlwZU9mIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgUkVMX05VTExJRlksIFJFTF9SRVNUUklDVCB9IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHsgQXV0aG9yaXphdGlvbk1vZGVsIH0gZnJvbSBcIi4vYXV0aG9yaXphdGlvbi1tb2RlbFwiO1xuaW1wb3J0IHsgVGVuYW50IH0gZnJvbSBcIi4vdGVuYW50Lm1vZGVsXCI7XG5pbXBvcnQgeyBSb2xlUGVybWlzc2lvbiB9IGZyb20gXCIuL3JvbGUtcGVybWlzc2lvbi5tb2RlbFwiO1xuaW1wb3J0IHsgUm9sZUFzc2lnbm1lbnQgfSBmcm9tIFwiLi9yb2xlLWFzc2lnbm1lbnQubW9kZWxcIjtcblxuQHRhYmxlKFwicm9sZXNcIilcbkBtb2RlbCgpXG5leHBvcnQgY2xhc3MgUm9sZSBleHRlbmRzIEF1dGhvcml6YXRpb25Nb2RlbCB7XG4gIGNvbnN0cnVjdG9yKGRhdGE/OiB1bmtub3duKSB7XG4gICAgc3VwZXIoZGF0YSk7XG4gIH1cblxuICBAcGsoeyB0eXBlOiBTdHJpbmcgfSkgQHV1aWQoKSBpZCE6IHN0cmluZztcbiAgQG1hbnlUb09uZSgoKSA9PiBUZW5hbnQsIFJFTF9OVUxMSUZZLCBmYWxzZSwgdW5kZWZpbmVkLCBcImZrX3JvbGVzX3RlbmFudFwiKVxuICB0ZW5hbnQ/OiBUZW5hbnQgfCBzdHJpbmc7XG4gIEByZXF1aXJlZCgpIEB0eXBlT2YoU3RyaW5nKSBAY29sdW1uKCkga2V5ITogc3RyaW5nO1xuICBAcmVxdWlyZWQoKSBAdHlwZU9mKFN0cmluZykgQGNvbHVtbigpIG5hbWUhOiBzdHJpbmc7XG4gIEB0eXBlT2YoU3RyaW5nKSBAY29sdW1uKCkgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG4gIEB0eXBlT2YoT2JqZWN0KSBAY29sdW1uKCkgbWV0YWRhdGE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgQG9uZVRvTWFueSgoKSA9PiBSb2xlUGVybWlzc2lvbiwgUkVMX1JFU1RSSUNULCBmYWxzZSkgcm9sZVBlcm1pc3Npb25zPzogUm9sZVBlcm1pc3Npb25bXSB8IHN0cmluZ1tdO1xuICBAb25lVG9NYW55KCgpID0+IFJvbGVBc3NpZ25tZW50LCBSRUxfUkVTVFJJQ1QsIGZhbHNlKSBhc3NpZ25tZW50cz86IFJvbGVBc3NpZ25tZW50W10gfCBzdHJpbmdbXTtcbiAgQGNyZWF0ZWRBdCgpIGNyZWF0ZWRBdCE6IERhdGU7XG4gIEB1cGRhdGVkQXQoKSB1cGRhdGVkQXQhOiBEYXRlO1xufVxuIiwiaW1wb3J0IHsgY29sdW1uLCBjcmVhdGVkQXQsIG1hbnlUb09uZSwgcGssIHRhYmxlLCB1cGRhdGVkQXQsIHV1aWQgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IG1vZGVsLCBvcHRpb24sIHJlcXVpcmVkLCB0eXBlIGFzIHR5cGVPZiB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IFNjb3BlS2luZCwgU2NvcGVLaW5kT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgUkVMX0NBU0NBREVfREVQRU5ERU5ULCBSRUxfUkVTVFJJQ1QgfSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCB7IEF1dGhvcml6YXRpb25Nb2RlbCB9IGZyb20gXCIuL2F1dGhvcml6YXRpb24tbW9kZWxcIjtcbmltcG9ydCB7IFRlbmFudCB9IGZyb20gXCIuL3RlbmFudC5tb2RlbFwiO1xuaW1wb3J0IHsgUHJpbmNpcGFsIH0gZnJvbSBcIi4vcHJpbmNpcGFsLm1vZGVsXCI7XG5pbXBvcnQgeyBSb2xlIH0gZnJvbSBcIi4vcm9sZS5tb2RlbFwiO1xuXG5AdGFibGUoXCJyb2xlX2Fzc2lnbm1lbnRzXCIpXG5AbW9kZWwoKVxuZXhwb3J0IGNsYXNzIFJvbGVBc3NpZ25tZW50IGV4dGVuZHMgQXV0aG9yaXphdGlvbk1vZGVsIHtcbiAgY29uc3RydWN0b3IoZGF0YT86IHVua25vd24pIHtcbiAgICBzdXBlcihkYXRhKTtcbiAgfVxuXG4gIEBwayh7IHR5cGU6IFN0cmluZyB9KSBAdXVpZCgpIGlkITogc3RyaW5nO1xuICBAbWFueVRvT25lKCgpID0+IFRlbmFudCwgUkVMX0NBU0NBREVfREVQRU5ERU5ULCBmYWxzZSwgdW5kZWZpbmVkLCBcImZrX3JvbGVfYXNzaWdubWVudHNfdGVuYW50XCIpXG4gIEByZXF1aXJlZCgpXG4gIHRlbmFudCE6IFRlbmFudCB8IHN0cmluZztcbiAgQG1hbnlUb09uZSgoKSA9PiBQcmluY2lwYWwsIFJFTF9DQVNDQURFX0RFUEVOREVOVCwgZmFsc2UsIHVuZGVmaW5lZCwgXCJma19yb2xlX2Fzc2lnbm1lbnRzX3ByaW5jaXBhbFwiKVxuICBAcmVxdWlyZWQoKVxuICBwcmluY2lwYWwhOiBQcmluY2lwYWwgfCBzdHJpbmc7XG4gIEBtYW55VG9PbmUoKCkgPT4gUm9sZSwgUkVMX1JFU1RSSUNULCBmYWxzZSwgdW5kZWZpbmVkLCBcImZrX3JvbGVfYXNzaWdubWVudHNfcm9sZVwiKVxuICBAcmVxdWlyZWQoKVxuICByb2xlITogUm9sZSB8IHN0cmluZztcbiAgQHJlcXVpcmVkKCkgQHR5cGVPZihTdHJpbmcpIEBvcHRpb24oU2NvcGVLaW5kT3B0aW9ucykgQGNvbHVtbigpIHNjb3BlS2luZCE6IFNjb3BlS2luZDtcbiAgQHJlcXVpcmVkKCkgQHR5cGVPZihTdHJpbmcpIEBjb2x1bW4oKSBzY29wZUlkITogc3RyaW5nO1xuICBAcmVxdWlyZWQoKSBAdHlwZU9mKEJvb2xlYW4pIEBjb2x1bW4oKSBpbmhlcml0RG93biE6IGJvb2xlYW47XG4gIEBjb2x1bW4oKSBzdGFydHNBdD86IERhdGU7XG4gIEBjb2x1bW4oKSBleHBpcmVzQXQ/OiBEYXRlO1xuICBAdHlwZU9mKE9iamVjdCkgQGNvbHVtbigpIGNvbmRpdGlvbnM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgQGNyZWF0ZWRBdCgpIGNyZWF0ZWRBdCE6IERhdGU7XG4gIEB1cGRhdGVkQXQoKSB1cGRhdGVkQXQhOiBEYXRlO1xufVxuIiwiaW1wb3J0IHsgY29sdW1uLCBjcmVhdGVkQXQsIG1hbnlUb09uZSwgcGssIHRhYmxlLCB1cGRhdGVkQXQsIHV1aWQgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcbmltcG9ydCB7IG1vZGVsLCByZXF1aXJlZCwgdHlwZSBhcyB0eXBlT2YgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBSRUxfQ0FTQ0FERV9ERVBFTkRFTlQsIFJFTF9SRVNUUklDVCB9IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHsgQXV0aG9yaXphdGlvbk1vZGVsIH0gZnJvbSBcIi4vYXV0aG9yaXphdGlvbi1tb2RlbFwiO1xuaW1wb3J0IHsgVGVuYW50IH0gZnJvbSBcIi4vdGVuYW50Lm1vZGVsXCI7XG5pbXBvcnQgeyBQcmluY2lwYWwgfSBmcm9tIFwiLi9wcmluY2lwYWwubW9kZWxcIjtcbmltcG9ydCB7IFByb3RlY3RlZFJlc291cmNlIH0gZnJvbSBcIi4vcHJvdGVjdGVkLXJlc291cmNlLm1vZGVsXCI7XG5cbkB0YWJsZShcInJlc291cmNlX2dyYW50c1wiKVxuQG1vZGVsKClcbmV4cG9ydCBjbGFzcyBSZXNvdXJjZUdyYW50IGV4dGVuZHMgQXV0aG9yaXphdGlvbk1vZGVsIHtcbiAgY29uc3RydWN0b3IoZGF0YT86IHVua25vd24pIHtcbiAgICBzdXBlcihkYXRhKTtcbiAgfVxuXG4gIEBwayh7IHR5cGU6IFN0cmluZyB9KSBAdXVpZCgpIGlkITogc3RyaW5nO1xuICBAbWFueVRvT25lKCgpID0+IFRlbmFudCwgUkVMX0NBU0NBREVfREVQRU5ERU5ULCBmYWxzZSwgdW5kZWZpbmVkLCBcImZrX3Jlc291cmNlX2dyYW50c190ZW5hbnRcIilcbiAgQHJlcXVpcmVkKClcbiAgdGVuYW50ITogVGVuYW50IHwgc3RyaW5nO1xuICBAbWFueVRvT25lKCgpID0+IFByb3RlY3RlZFJlc291cmNlLCBSRUxfQ0FTQ0FERV9ERVBFTkRFTlQsIGZhbHNlLCB1bmRlZmluZWQsIFwiZmtfcmVzb3VyY2VfZ3JhbnRzX3Jlc291cmNlXCIpXG4gIEByZXF1aXJlZCgpXG4gIHJlc291cmNlITogUHJvdGVjdGVkUmVzb3VyY2UgfCBzdHJpbmc7XG4gIEBtYW55VG9PbmUoKCkgPT4gUHJpbmNpcGFsLCBSRUxfQ0FTQ0FERV9ERVBFTkRFTlQsIGZhbHNlLCB1bmRlZmluZWQsIFwiZmtfcmVzb3VyY2VfZ3JhbnRzX3ByaW5jaXBhbFwiKVxuICBAcmVxdWlyZWQoKVxuICBwcmluY2lwYWwhOiBQcmluY2lwYWwgfCBzdHJpbmc7XG4gIEByZXF1aXJlZCgpIEB0eXBlT2YoU3RyaW5nKSBAY29sdW1uKCkgcGVybWlzc2lvbktleSE6IHN0cmluZztcbiAgQGNvbHVtbigpIHN0YXJ0c0F0PzogRGF0ZTtcbiAgQGNvbHVtbigpIGV4cGlyZXNBdD86IERhdGU7XG4gIEB0eXBlT2YoT2JqZWN0KSBAY29sdW1uKCkgY29uZGl0aW9ucz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICBAbWFueVRvT25lKCgpID0+IFByaW5jaXBhbCwgUkVMX1JFU1RSSUNULCBmYWxzZSwgdW5kZWZpbmVkLCBcImZrX3Jlc291cmNlX2dyYW50c19jcmVhdGVkX2J5XCIpXG4gIGNyZWF0ZWRCeT86IFByaW5jaXBhbCB8IHN0cmluZztcbiAgQGNyZWF0ZWRBdCgpIGNyZWF0ZWRBdCE6IERhdGU7XG4gIEB1cGRhdGVkQXQoKSB1cGRhdGVkQXQhOiBEYXRlO1xufVxuIiwiaW1wb3J0IHsgY29sdW1uLCBjcmVhdGVkQXQsIG1hbnlUb09uZSwgb25lVG9NYW55LCBwaywgdGFibGUsIHVwZGF0ZWRBdCwgdXVpZCB9IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHsgbW9kZWwsIG9wdGlvbiwgcmVxdWlyZWQsIHR5cGUgYXMgdHlwZU9mIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgUHJpbmNpcGFsS2luZCwgUHJpbmNpcGFsS2luZE9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IFJFTF9SRVNUUklDVCB9IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHsgQXV0aG9yaXphdGlvbk1vZGVsIH0gZnJvbSBcIi4vYXV0aG9yaXphdGlvbi1tb2RlbFwiO1xuaW1wb3J0IHsgVGVuYW50IH0gZnJvbSBcIi4vdGVuYW50Lm1vZGVsXCI7XG5pbXBvcnQgeyBSb2xlQXNzaWdubWVudCB9IGZyb20gXCIuL3JvbGUtYXNzaWdubWVudC5tb2RlbFwiO1xuaW1wb3J0IHsgUmVzb3VyY2VHcmFudCB9IGZyb20gXCIuL3Jlc291cmNlLWdyYW50Lm1vZGVsXCI7XG5cbkB0YWJsZShcInByaW5jaXBhbHNcIilcbkBtb2RlbCgpXG5leHBvcnQgY2xhc3MgUHJpbmNpcGFsIGV4dGVuZHMgQXV0aG9yaXphdGlvbk1vZGVsIHtcbiAgY29uc3RydWN0b3IoZGF0YT86IHVua25vd24pIHtcbiAgICBzdXBlcihkYXRhKTtcbiAgfVxuXG4gIEBwayh7IHR5cGU6IFN0cmluZyB9KSBAdXVpZCgpIGlkITogc3RyaW5nO1xuICBAbWFueVRvT25lKCgpID0+IFRlbmFudCwgUkVMX1JFU1RSSUNULCBmYWxzZSwgdW5kZWZpbmVkLCBcImZrX3ByaW5jaXBhbHNfdGVuYW50XCIpXG4gIEByZXF1aXJlZCgpXG4gIHRlbmFudCE6IFRlbmFudCB8IHN0cmluZztcbiAgQHJlcXVpcmVkKCkgQHR5cGVPZihTdHJpbmcpIEBvcHRpb24oUHJpbmNpcGFsS2luZE9wdGlvbnMpIEBjb2x1bW4oKSBraW5kITogUHJpbmNpcGFsS2luZDtcbiAgQHJlcXVpcmVkKCkgQHR5cGVPZihTdHJpbmcpIEBjb2x1bW4oKSBzdWJqZWN0SWQhOiBzdHJpbmc7XG4gIEBvbmVUb01hbnkoKCkgPT4gUm9sZUFzc2lnbm1lbnQsIFJFTF9SRVNUUklDVCwgZmFsc2UpIHJvbGVBc3NpZ25tZW50cz86IFJvbGVBc3NpZ25tZW50W10gfCBzdHJpbmdbXTtcbiAgQG9uZVRvTWFueSgoKSA9PiBSZXNvdXJjZUdyYW50LCBSRUxfUkVTVFJJQ1QsIGZhbHNlKSByZXNvdXJjZUdyYW50cz86IFJlc291cmNlR3JhbnRbXSB8IHN0cmluZ1tdO1xuICBAY3JlYXRlZEF0KCkgY3JlYXRlZEF0ITogRGF0ZTtcbiAgQHVwZGF0ZWRBdCgpIHVwZGF0ZWRBdCE6IERhdGU7XG59XG4iLCJpbXBvcnQgeyBjb2x1bW4sIGNyZWF0ZWRBdCwgbWFueVRvT25lLCBvbmVUb01hbnksIHBrLCB0YWJsZSwgdXBkYXRlZEF0LCB1dWlkIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBtb2RlbCwgb3B0aW9uLCByZXF1aXJlZCwgdHlwZSBhcyB0eXBlT2YgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBSRUxfTlVMTElGWSwgUkVMX1JFU1RSSUNUIH0gZnJvbSBcIi4uL3V0aWxzXCI7XG5pbXBvcnQgeyBSZXNvdXJjZVZpc2liaWxpdHksIFJlc291cmNlVmlzaWJpbGl0eU9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IEF1dGhvcml6YXRpb25Nb2RlbCB9IGZyb20gXCIuL2F1dGhvcml6YXRpb24tbW9kZWxcIjtcbmltcG9ydCB7IFRlbmFudCB9IGZyb20gXCIuL3RlbmFudC5tb2RlbFwiO1xuaW1wb3J0IHsgT3JnVW5pdCB9IGZyb20gXCIuL29yZy11bml0Lm1vZGVsXCI7XG5pbXBvcnQgeyBQcmluY2lwYWwgfSBmcm9tIFwiLi9wcmluY2lwYWwubW9kZWxcIjtcbmltcG9ydCB7IFJlc291cmNlR3JhbnQgfSBmcm9tIFwiLi9yZXNvdXJjZS1ncmFudC5tb2RlbFwiO1xuXG5AdGFibGUoXCJwcm90ZWN0ZWRfcmVzb3VyY2VzXCIpXG5AbW9kZWwoKVxuZXhwb3J0IGNsYXNzIFByb3RlY3RlZFJlc291cmNlIGV4dGVuZHMgQXV0aG9yaXphdGlvbk1vZGVsIHtcbiAgY29uc3RydWN0b3IoZGF0YT86IHVua25vd24pIHtcbiAgICBzdXBlcihkYXRhKTtcbiAgfVxuXG4gIEBwayh7IHR5cGU6IFN0cmluZyB9KSBAdXVpZCgpIGlkITogc3RyaW5nO1xuICBAbWFueVRvT25lKCgpID0+IFRlbmFudCwgUkVMX1JFU1RSSUNULCBmYWxzZSwgdW5kZWZpbmVkLCBcImZrX3Byb3RlY3RlZF9yZXNvdXJjZXNfdGVuYW50XCIpXG4gIEByZXF1aXJlZCgpXG4gIHRlbmFudCE6IFRlbmFudCB8IHN0cmluZztcbiAgQG1hbnlUb09uZSgoKSA9PiBPcmdVbml0LCBSRUxfUkVTVFJJQ1QsIGZhbHNlLCB1bmRlZmluZWQsIFwiZmtfcHJvdGVjdGVkX3Jlc291cmNlc19vcmdfdW5pdFwiKVxuICBAcmVxdWlyZWQoKVxuICBvcmdVbml0ITogT3JnVW5pdCB8IHN0cmluZztcbiAgQHJlcXVpcmVkKCkgQHR5cGVPZihTdHJpbmcpIEBjb2x1bW4oKSByZXNvdXJjZVR5cGUhOiBzdHJpbmc7XG4gIEByZXF1aXJlZCgpIEB0eXBlT2YoU3RyaW5nKSBAY29sdW1uKCkgcmVzb3VyY2VJZCE6IHN0cmluZztcbiAgQHJlcXVpcmVkKCkgQHR5cGVPZihTdHJpbmcpIEBvcHRpb24oUmVzb3VyY2VWaXNpYmlsaXR5T3B0aW9ucykgQGNvbHVtbigpIHZpc2liaWxpdHkhOiBSZXNvdXJjZVZpc2liaWxpdHk7XG4gIEBtYW55VG9PbmUoKCkgPT4gUHJpbmNpcGFsLCBSRUxfTlVMTElGWSwgZmFsc2UsIHVuZGVmaW5lZCwgXCJma19wcm90ZWN0ZWRfcmVzb3VyY2VzX293bmVyXCIpXG4gIG93bmVyPzogUHJpbmNpcGFsIHwgc3RyaW5nO1xuICBAdHlwZU9mKFN0cmluZykgQGNvbHVtbigpIHNlbnNpdGl2aXR5Pzogc3RyaW5nO1xuICBAdHlwZU9mKE9iamVjdCkgQGNvbHVtbigpIG1ldGFkYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIEBvbmVUb01hbnkoKCkgPT4gUmVzb3VyY2VHcmFudCwgUkVMX1JFU1RSSUNULCBmYWxzZSkgZ3JhbnRzPzogUmVzb3VyY2VHcmFudFtdIHwgc3RyaW5nW107XG4gIEBjcmVhdGVkQXQoKSBjcmVhdGVkQXQhOiBEYXRlO1xuICBAdXBkYXRlZEF0KCkgdXBkYXRlZEF0ITogRGF0ZTtcbn1cbiIsImltcG9ydCB7IGNvbHVtbiwgY3JlYXRlZEF0LCBtYW55VG9PbmUsIHBrLCB0YWJsZSwgdXBkYXRlZEF0LCB1dWlkIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBtb2RlbCwgb3B0aW9uLCByZXF1aXJlZCwgdHlwZSBhcyB0eXBlT2YgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBQZXJtaXNzaW9uQ2F0ZWdvcnksIFBlcm1pc3Npb25DYXRlZ29yeU9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IFJFTF9DQVNDQURFX0RFUEVOREVOVCwgUkVMX05VTExJRlkgfSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCB7IEF1dGhvcml6YXRpb25Nb2RlbCB9IGZyb20gXCIuL2F1dGhvcml6YXRpb24tbW9kZWxcIjtcbmltcG9ydCB7IFRlbmFudCB9IGZyb20gXCIuL3RlbmFudC5tb2RlbFwiO1xuaW1wb3J0IHsgT3JnVW5pdCB9IGZyb20gXCIuL29yZy11bml0Lm1vZGVsXCI7XG5cbkB0YWJsZShcImluaGVyaXRhbmNlX2Jsb2Nrc1wiKVxuQG1vZGVsKClcbmV4cG9ydCBjbGFzcyBJbmhlcml0YW5jZUJsb2NrIGV4dGVuZHMgQXV0aG9yaXphdGlvbk1vZGVsIHtcbiAgY29uc3RydWN0b3IoZGF0YT86IHVua25vd24pIHtcbiAgICBzdXBlcihkYXRhKTtcbiAgfVxuXG4gIEBwayh7IHR5cGU6IFN0cmluZyB9KSBAdXVpZCgpIGlkITogc3RyaW5nO1xuICBAbWFueVRvT25lKCgpID0+IFRlbmFudCwgUkVMX0NBU0NBREVfREVQRU5ERU5ULCBmYWxzZSwgdW5kZWZpbmVkLCBcImZrX2luaGVyaXRhbmNlX2Jsb2Nrc190ZW5hbnRcIilcbiAgQHJlcXVpcmVkKClcbiAgdGVuYW50ITogVGVuYW50IHwgc3RyaW5nO1xuICBAbWFueVRvT25lKCgpID0+IE9yZ1VuaXQsIFJFTF9DQVNDQURFX0RFUEVOREVOVCwgZmFsc2UsIHVuZGVmaW5lZCwgXCJma19pbmhlcml0YW5jZV9ibG9ja3Nfb3JnX3VuaXRcIilcbiAgQHJlcXVpcmVkKClcbiAgb3JnVW5pdCE6IE9yZ1VuaXQgfCBzdHJpbmc7XG4gIEBtYW55VG9PbmUoKCkgPT4gT3JnVW5pdCwgUkVMX05VTExJRlksIGZhbHNlLCB1bmRlZmluZWQsIFwiZmtfaW5oZXJpdGFuY2VfYmxvY2tzX2Jsb2NrZWRfYW5jZXN0b3JcIilcbiAgYmxvY2tlZEZyb21BbmNlc3Rvcj86IE9yZ1VuaXQgfCBzdHJpbmc7XG4gIEByZXF1aXJlZCgpIEB0eXBlT2YoU3RyaW5nKSBAb3B0aW9uKFBlcm1pc3Npb25DYXRlZ29yeU9wdGlvbnMpIEBjb2x1bW4oKSBwZXJtaXNzaW9uQ2F0ZWdvcnkhOiBQZXJtaXNzaW9uQ2F0ZWdvcnk7XG4gIEB0eXBlT2YoU3RyaW5nKSBAY29sdW1uKCkgcmVhc29uPzogc3RyaW5nO1xuICBAY3JlYXRlZEF0KCkgY3JlYXRlZEF0ITogRGF0ZTtcbiAgQHVwZGF0ZWRBdCgpIHVwZGF0ZWRBdCE6IERhdGU7XG59XG4iLCJpbXBvcnQgeyBjb2x1bW4sIGNyZWF0ZWRBdCwgbWFueVRvT25lLCBvbmVUb01hbnksIHBrLCB0YWJsZSwgdXBkYXRlZEF0LCB1dWlkIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBtb2RlbCwgcmVxdWlyZWQsIHR5cGUgYXMgdHlwZU9mIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgUkVMX1JFU1RSSUNUIH0gZnJvbSBcIi4uL3V0aWxzXCI7XG5pbXBvcnQgeyBBdXRob3JpemF0aW9uTW9kZWwgfSBmcm9tIFwiLi9hdXRob3JpemF0aW9uLW1vZGVsXCI7XG5pbXBvcnQgeyBUZW5hbnQgfSBmcm9tIFwiLi90ZW5hbnQubW9kZWxcIjtcbmltcG9ydCB7IE9yZ1VuaXRNZW1iZXJzaGlwIH0gZnJvbSBcIi4vb3JnLXVuaXQtbWVtYmVyc2hpcC5tb2RlbFwiO1xuaW1wb3J0IHsgT3JnVW5pdENsb3N1cmUgfSBmcm9tIFwiLi9vcmctdW5pdC1jbG9zdXJlLm1vZGVsXCI7XG5pbXBvcnQgeyBQcm90ZWN0ZWRSZXNvdXJjZSB9IGZyb20gXCIuL3Byb3RlY3RlZC1yZXNvdXJjZS5tb2RlbFwiO1xuaW1wb3J0IHsgSW5oZXJpdGFuY2VCbG9jayB9IGZyb20gXCIuL2luaGVyaXRhbmNlLWJsb2NrLm1vZGVsXCI7XG5cbkB0YWJsZShcIm9yZ191bml0c1wiKVxuQG1vZGVsKClcbmV4cG9ydCBjbGFzcyBPcmdVbml0IGV4dGVuZHMgQXV0aG9yaXphdGlvbk1vZGVsIHtcbiAgY29uc3RydWN0b3IoZGF0YT86IHVua25vd24pIHtcbiAgICBzdXBlcihkYXRhKTtcbiAgfVxuXG4gIEBwayh7IHR5cGU6IFN0cmluZyB9KSBAdXVpZCgpIGlkITogc3RyaW5nO1xuICBAbWFueVRvT25lKCgpID0+IFRlbmFudCwgUkVMX1JFU1RSSUNULCBmYWxzZSwgdW5kZWZpbmVkLCBcImZrX29yZ191bml0c190ZW5hbnRcIilcbiAgQHJlcXVpcmVkKClcbiAgdGVuYW50ITogVGVuYW50IHwgc3RyaW5nO1xuICBAbWFueVRvT25lKCgpID0+IE9yZ1VuaXQsIFJFTF9SRVNUUklDVCwgZmFsc2UsIHVuZGVmaW5lZCwgXCJma19vcmdfdW5pdHNfcGFyZW50XCIpXG4gIHBhcmVudD86IE9yZ1VuaXQgfCBzdHJpbmc7XG4gIEBvbmVUb01hbnkoKCkgPT4gT3JnVW5pdCwgUkVMX1JFU1RSSUNULCBmYWxzZSkgY2hpbGRyZW4/OiBPcmdVbml0W10gfCBzdHJpbmdbXTtcbiAgQHJlcXVpcmVkKCkgQHR5cGVPZihTdHJpbmcpIEBjb2x1bW4oKSBuYW1lITogc3RyaW5nO1xuICBAcmVxdWlyZWQoKSBAdHlwZU9mKFN0cmluZykgQGNvbHVtbigpIHBhdGghOiBzdHJpbmc7XG4gIEB0eXBlT2YoT2JqZWN0KSBAY29sdW1uKCkgbWV0YWRhdGE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgQG9uZVRvTWFueSgoKSA9PiBPcmdVbml0TWVtYmVyc2hpcCwgUkVMX1JFU1RSSUNULCBmYWxzZSkgbWVtYmVyc2hpcHM/OiBPcmdVbml0TWVtYmVyc2hpcFtdIHwgc3RyaW5nW107XG4gIEBvbmVUb01hbnkoKCkgPT4gUHJvdGVjdGVkUmVzb3VyY2UsIFJFTF9SRVNUUklDVCwgZmFsc2UpIHJlc291cmNlcz86IFByb3RlY3RlZFJlc291cmNlW10gfCBzdHJpbmdbXTtcbiAgQG9uZVRvTWFueSgoKSA9PiBJbmhlcml0YW5jZUJsb2NrLCBSRUxfUkVTVFJJQ1QsIGZhbHNlKSBpbmhlcml0YW5jZUJsb2Nrcz86IEluaGVyaXRhbmNlQmxvY2tbXSB8IHN0cmluZ1tdO1xuICBAb25lVG9NYW55KCgpID0+IE9yZ1VuaXRDbG9zdXJlLCBSRUxfUkVTVFJJQ1QsIGZhbHNlKSBhbmNlc3RvckxpbmtzPzogT3JnVW5pdENsb3N1cmVbXSB8IHN0cmluZ1tdO1xuICBAb25lVG9NYW55KCgpID0+IE9yZ1VuaXRDbG9zdXJlLCBSRUxfUkVTVFJJQ1QsIGZhbHNlKSBkZXNjZW5kYW50TGlua3M/OiBPcmdVbml0Q2xvc3VyZVtdIHwgc3RyaW5nW107XG4gIEBjcmVhdGVkQXQoKSBjcmVhdGVkQXQhOiBEYXRlO1xuICBAdXBkYXRlZEF0KCkgdXBkYXRlZEF0ITogRGF0ZTtcbn1cbiIsImltcG9ydCB7IGNvbHVtbiwgY3JlYXRlZEF0LCBtYW55VG9PbmUsIHBrLCB0YWJsZSwgdXBkYXRlZEF0LCB1dWlkIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBtb2RlbCwgb3B0aW9uLCByZXF1aXJlZCwgdHlwZSBhcyB0eXBlT2YgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBTdG9yYWdlQmluZGluZ0tpbmQsIFN0b3JhZ2VCaW5kaW5nS2luZE9wdGlvbnMsIFN0b3JhZ2VLaW5kLCBTdG9yYWdlS2luZE9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IFJFTF9DQVNDQURFX0RFUEVOREVOVCB9IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHsgQXV0aG9yaXphdGlvbk1vZGVsIH0gZnJvbSBcIi4vYXV0aG9yaXphdGlvbi1tb2RlbFwiO1xuaW1wb3J0IHsgVGVuYW50IH0gZnJvbSBcIi4vdGVuYW50Lm1vZGVsXCI7XG5cbkB0YWJsZShcInN0b3JhZ2VfYmluZGluZ3NcIilcbkBtb2RlbCgpXG5leHBvcnQgY2xhc3MgU3RvcmFnZUJpbmRpbmcgZXh0ZW5kcyBBdXRob3JpemF0aW9uTW9kZWwge1xuICBjb25zdHJ1Y3RvcihkYXRhPzogdW5rbm93bikge1xuICAgIHN1cGVyKGRhdGEpO1xuICB9XG5cbiAgQHBrKHsgdHlwZTogU3RyaW5nIH0pIEB1dWlkKCkgaWQhOiBzdHJpbmc7XG4gIEBtYW55VG9PbmUoKCkgPT4gVGVuYW50LCBSRUxfQ0FTQ0FERV9ERVBFTkRFTlQsIGZhbHNlLCB1bmRlZmluZWQsIFwiZmtfc3RvcmFnZV9iaW5kaW5nc190ZW5hbnRcIilcbiAgQHJlcXVpcmVkKClcbiAgdGVuYW50ITogVGVuYW50IHwgc3RyaW5nO1xuICBAcmVxdWlyZWQoKSBAdHlwZU9mKFN0cmluZykgQG9wdGlvbihTdG9yYWdlS2luZE9wdGlvbnMpIEBjb2x1bW4oKSBzdG9yYWdlS2luZCE6IFN0b3JhZ2VLaW5kO1xuICBAcmVxdWlyZWQoKSBAdHlwZU9mKFN0cmluZykgQG9wdGlvbihTdG9yYWdlQmluZGluZ0tpbmRPcHRpb25zKSBAY29sdW1uKCkgYmluZGluZ0tpbmQhOiBTdG9yYWdlQmluZGluZ0tpbmQ7XG4gIEByZXF1aXJlZCgpIEB0eXBlT2YoU3RyaW5nKSBAY29sdW1uKCkgYmluZGluZ0tleSE6IHN0cmluZztcbiAgQHJlcXVpcmVkKCkgQHR5cGVPZihTdHJpbmcpIEBjb2x1bW4oKSByZWdpb24hOiBzdHJpbmc7XG4gIEB0eXBlT2YoT2JqZWN0KSBAY29sdW1uKCkgY29uZmlnPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIEBjcmVhdGVkQXQoKSBjcmVhdGVkQXQhOiBEYXRlO1xuICBAdXBkYXRlZEF0KCkgdXBkYXRlZEF0ITogRGF0ZTtcbn1cbiIsImltcG9ydCB7XG4gIGNvbHVtbixcbiAgY3JlYXRlZEF0LFxuICBvbmVUb01hbnksXG4gIHBrLFxuICB0YWJsZSxcbiAgdW5pcXVlLFxuICB1cGRhdGVkQXQsXG4gIHV1aWQsXG59IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHtcbiAgbW9kZWwsXG4gIG9wdGlvbixcbiAgcmVxdWlyZWQsXG4gIHR5cGUgYXMgdHlwZU9mLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBJc29sYXRpb25UaWVyLCBJc29sYXRpb25UaWVyT3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgUkVMX1JFU1RSSUNUIH0gZnJvbSBcIi4uL3V0aWxzXCI7XG5pbXBvcnQgeyBBdXRob3JpemF0aW9uTW9kZWwgfSBmcm9tIFwiLi9hdXRob3JpemF0aW9uLW1vZGVsXCI7XG5pbXBvcnQgeyBPcmdVbml0IH0gZnJvbSBcIi4vb3JnLXVuaXQubW9kZWxcIjtcbmltcG9ydCB7IFRlbmFudE1lbWJlcnNoaXAgfSBmcm9tIFwiLi90ZW5hbnQtbWVtYmVyc2hpcC5tb2RlbFwiO1xuaW1wb3J0IHsgUHJpbmNpcGFsIH0gZnJvbSBcIi4vcHJpbmNpcGFsLm1vZGVsXCI7XG5pbXBvcnQgeyBTdG9yYWdlQmluZGluZyB9IGZyb20gXCIuL3N0b3JhZ2UtYmluZGluZy5tb2RlbFwiO1xuXG5AdGFibGUoXCJ0ZW5hbnRzXCIpXG5AbW9kZWwoKVxuZXhwb3J0IGNsYXNzIFRlbmFudCBleHRlbmRzIEF1dGhvcml6YXRpb25Nb2RlbCB7XG4gIGNvbnN0cnVjdG9yKGRhdGE/OiB1bmtub3duKSB7XG4gICAgc3VwZXIoZGF0YSk7XG4gIH1cblxuICBAcGsoeyB0eXBlOiBTdHJpbmcgfSkgQHV1aWQoKSBpZCE6IHN0cmluZztcbiAgQHVuaXF1ZSgpIEByZXF1aXJlZCgpIEB0eXBlT2YoU3RyaW5nKSBAY29sdW1uKCkgc2x1ZyE6IHN0cmluZztcbiAgQHJlcXVpcmVkKCkgQHR5cGVPZihTdHJpbmcpIEBjb2x1bW4oKSBuYW1lITogc3RyaW5nO1xuICBAcmVxdWlyZWQoKVxuICBAdHlwZU9mKFN0cmluZylcbiAgQG9wdGlvbihJc29sYXRpb25UaWVyT3B0aW9ucylcbiAgQGNvbHVtbigpXG4gIGlzb2xhdGlvblRpZXIhOiBJc29sYXRpb25UaWVyO1xuICBAb25lVG9NYW55KCgpID0+IE9yZ1VuaXQsIFJFTF9SRVNUUklDVCwgZmFsc2UpIG9yZ1VuaXRzPzpcbiAgICB8IE9yZ1VuaXRbXVxuICAgIHwgc3RyaW5nW107XG4gIEBvbmVUb01hbnkoKCkgPT4gVGVuYW50TWVtYmVyc2hpcCwgUkVMX1JFU1RSSUNULCBmYWxzZSkgbWVtYmVyc2hpcHM/OlxuICAgIHwgVGVuYW50TWVtYmVyc2hpcFtdXG4gICAgfCBzdHJpbmdbXTtcbiAgQG9uZVRvTWFueSgoKSA9PiBQcmluY2lwYWwsIFJFTF9SRVNUUklDVCwgZmFsc2UpIHByaW5jaXBhbHM/OlxuICAgIHwgUHJpbmNpcGFsW11cbiAgICB8IHN0cmluZ1tdO1xuICBAb25lVG9NYW55KCgpID0+IFN0b3JhZ2VCaW5kaW5nLCBSRUxfUkVTVFJJQ1QsIGZhbHNlKSBzdG9yYWdlQmluZGluZ3M/OlxuICAgIHwgU3RvcmFnZUJpbmRpbmdbXVxuICAgIHwgc3RyaW5nW107XG4gIEBjcmVhdGVkQXQoKSBjcmVhdGVkQXQhOiBEYXRlO1xuICBAdXBkYXRlZEF0KCkgdXBkYXRlZEF0ITogRGF0ZTtcbn1cbiIsImltcG9ydCB7IGNvbHVtbiwgY3JlYXRlZEF0LCBtYW55VG9PbmUsIHBrLCB0YWJsZSwgdXBkYXRlZEF0LCB1dWlkIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBtb2RlbCwgcmVxdWlyZWQsIHR5cGUgYXMgdHlwZU9mIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgUkVMX0NBU0NBREVfREVQRU5ERU5UIH0gZnJvbSBcIi4uL3V0aWxzXCI7XG5pbXBvcnQgeyBBdXRob3JpemF0aW9uTW9kZWwgfSBmcm9tIFwiLi9hdXRob3JpemF0aW9uLW1vZGVsXCI7XG5pbXBvcnQgeyBUZW5hbnQgfSBmcm9tIFwiLi90ZW5hbnQubW9kZWxcIjtcblxuQHRhYmxlKFwidGVuYW50X3Byb2ZpbGVzXCIpXG5AbW9kZWwoKVxuZXhwb3J0IGNsYXNzIFRlbmFudFByb2ZpbGUgZXh0ZW5kcyBBdXRob3JpemF0aW9uTW9kZWwge1xuICBjb25zdHJ1Y3RvcihkYXRhPzogdW5rbm93bikge1xuICAgIHN1cGVyKGRhdGEpO1xuICB9XG5cbiAgQHBrKHsgdHlwZTogU3RyaW5nIH0pIEB1dWlkKCkgaWQhOiBzdHJpbmc7XG4gIEBtYW55VG9PbmUoKCkgPT4gVGVuYW50LCBSRUxfQ0FTQ0FERV9ERVBFTkRFTlQsIGZhbHNlLCB1bmRlZmluZWQsIFwiZmtfdGVuYW50X3Byb2ZpbGVzX3RlbmFudFwiKVxuICBAcmVxdWlyZWQoKVxuICB0ZW5hbnQhOiBUZW5hbnQgfCBzdHJpbmc7XG4gIEByZXF1aXJlZCgpIEB0eXBlT2YoU3RyaW5nKSBAY29sdW1uKCkgcHJvZmlsZUtleSE6IHN0cmluZztcbiAgQHR5cGVPZihPYmplY3QpIEBjb2x1bW4oKSBtZXRhZGF0YT86IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICBAY3JlYXRlZEF0KCkgY3JlYXRlZEF0ITogRGF0ZTtcbiAgQHVwZGF0ZWRBdCgpIHVwZGF0ZWRBdCE6IERhdGU7XG59XG4iLCJpbXBvcnQgeyBjb2x1bW4sIGNyZWF0ZWRBdCwgbWFueVRvT25lLCBwaywgdGFibGUsIHVwZGF0ZWRBdCwgdXVpZCB9IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHsgbW9kZWwsIHJlcXVpcmVkLCB0eXBlIGFzIHR5cGVPZiB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IFJFTF9DQVNDQURFX0RFUEVOREVOVCB9IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHsgQXV0aG9yaXphdGlvbk1vZGVsIH0gZnJvbSBcIi4vYXV0aG9yaXphdGlvbi1tb2RlbFwiO1xuaW1wb3J0IHsgT3JnVW5pdCB9IGZyb20gXCIuL29yZy11bml0Lm1vZGVsXCI7XG5cbkB0YWJsZShcIm9yZ191bml0X3Byb2ZpbGVzXCIpXG5AbW9kZWwoKVxuZXhwb3J0IGNsYXNzIE9yZ1VuaXRQcm9maWxlIGV4dGVuZHMgQXV0aG9yaXphdGlvbk1vZGVsIHtcbiAgY29uc3RydWN0b3IoZGF0YT86IHVua25vd24pIHtcbiAgICBzdXBlcihkYXRhKTtcbiAgfVxuXG4gIEBwayh7IHR5cGU6IFN0cmluZyB9KSBAdXVpZCgpIGlkITogc3RyaW5nO1xuICBAbWFueVRvT25lKCgpID0+IE9yZ1VuaXQsIFJFTF9DQVNDQURFX0RFUEVOREVOVCwgZmFsc2UsIHVuZGVmaW5lZCwgXCJma19vcmdfdW5pdF9wcm9maWxlc19vcmdfdW5pdFwiKVxuICBAcmVxdWlyZWQoKVxuICBvcmdVbml0ITogT3JnVW5pdCB8IHN0cmluZztcbiAgQHJlcXVpcmVkKCkgQHR5cGVPZihTdHJpbmcpIEBjb2x1bW4oKSBwcm9maWxlS2V5ITogc3RyaW5nO1xuICBAdHlwZU9mKE9iamVjdCkgQGNvbHVtbigpIG1ldGFkYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIEBjcmVhdGVkQXQoKSBjcmVhdGVkQXQhOiBEYXRlO1xuICBAdXBkYXRlZEF0KCkgdXBkYXRlZEF0ITogRGF0ZTtcbn1cbiIsImltcG9ydCB7IGNvbHVtbiwgY3JlYXRlZEF0LCBtYW55VG9PbmUsIHBrLCB0YWJsZSwgdXVpZCB9IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHsgbW9kZWwsIHJlcXVpcmVkLCB0eXBlIGFzIHR5cGVPZiB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IFJFTF9DQVNDQURFX0RFUEVOREVOVCB9IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHsgQXV0aG9yaXphdGlvbk1vZGVsIH0gZnJvbSBcIi4vYXV0aG9yaXphdGlvbi1tb2RlbFwiO1xuaW1wb3J0IHsgVGVuYW50IH0gZnJvbSBcIi4vdGVuYW50Lm1vZGVsXCI7XG5pbXBvcnQgeyBHcm91cCB9IGZyb20gXCIuL2dyb3VwLm1vZGVsXCI7XG5pbXBvcnQgeyBQcmluY2lwYWwgfSBmcm9tIFwiLi9wcmluY2lwYWwubW9kZWxcIjtcblxuQHRhYmxlKFwiZ3JvdXBfbWVtYmVyc2hpcHNcIilcbkBtb2RlbCgpXG5leHBvcnQgY2xhc3MgR3JvdXBNZW1iZXJzaGlwIGV4dGVuZHMgQXV0aG9yaXphdGlvbk1vZGVsIHtcbiAgY29uc3RydWN0b3IoZGF0YT86IHVua25vd24pIHtcbiAgICBzdXBlcihkYXRhKTtcbiAgfVxuXG4gIEBwayh7IHR5cGU6IFN0cmluZyB9KSBAdXVpZCgpIGlkITogc3RyaW5nO1xuICBAbWFueVRvT25lKCgpID0+IFRlbmFudCwgUkVMX0NBU0NBREVfREVQRU5ERU5ULCBmYWxzZSwgdW5kZWZpbmVkLCBcImZrX2dyb3VwX21lbWJlcnNoaXBzX3RlbmFudFwiKVxuICBAcmVxdWlyZWQoKVxuICB0ZW5hbnQhOiBUZW5hbnQgfCBzdHJpbmc7XG4gIEBtYW55VG9PbmUoKCkgPT4gR3JvdXAsIFJFTF9DQVNDQURFX0RFUEVOREVOVCwgZmFsc2UsIHVuZGVmaW5lZCwgXCJma19ncm91cF9tZW1iZXJzaGlwc19ncm91cFwiKVxuICBAcmVxdWlyZWQoKVxuICBncm91cCE6IEdyb3VwIHwgc3RyaW5nO1xuICBAbWFueVRvT25lKCgpID0+IFByaW5jaXBhbCwgUkVMX0NBU0NBREVfREVQRU5ERU5ULCBmYWxzZSwgdW5kZWZpbmVkLCBcImZrX2dyb3VwX21lbWJlcnNoaXBzX3ByaW5jaXBhbFwiKVxuICBAcmVxdWlyZWQoKVxuICBwcmluY2lwYWwhOiBQcmluY2lwYWwgfCBzdHJpbmc7XG4gIEB0eXBlT2YoT2JqZWN0KSBAY29sdW1uKCkgbWV0YWRhdGE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgQGNyZWF0ZWRBdCgpIGNyZWF0ZWRBdCE6IERhdGU7XG59XG4iLCJpbXBvcnQgeyBjb2x1bW4sIGNyZWF0ZWRBdCwgbWFueVRvT25lLCBvbmVUb01hbnksIHBrLCB0YWJsZSwgdXBkYXRlZEF0LCB1dWlkIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBtb2RlbCwgcmVxdWlyZWQsIHR5cGUgYXMgdHlwZU9mIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgUkVMX05VTExJRlksIFJFTF9SRVNUUklDVCB9IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHsgQXV0aG9yaXphdGlvbk1vZGVsIH0gZnJvbSBcIi4vYXV0aG9yaXphdGlvbi1tb2RlbFwiO1xuaW1wb3J0IHsgVGVuYW50IH0gZnJvbSBcIi4vdGVuYW50Lm1vZGVsXCI7XG5pbXBvcnQgeyBPcmdVbml0IH0gZnJvbSBcIi4vb3JnLXVuaXQubW9kZWxcIjtcbmltcG9ydCB7IEdyb3VwTWVtYmVyc2hpcCB9IGZyb20gXCIuL2dyb3VwLW1lbWJlcnNoaXAubW9kZWxcIjtcblxuQHRhYmxlKFwiZ3JvdXBzXCIpXG5AbW9kZWwoKVxuZXhwb3J0IGNsYXNzIEdyb3VwIGV4dGVuZHMgQXV0aG9yaXphdGlvbk1vZGVsIHtcbiAgY29uc3RydWN0b3IoZGF0YT86IHVua25vd24pIHtcbiAgICBzdXBlcihkYXRhKTtcbiAgfVxuXG4gIEBwayh7IHR5cGU6IFN0cmluZyB9KSBAdXVpZCgpIGlkITogc3RyaW5nO1xuICBAbWFueVRvT25lKCgpID0+IFRlbmFudCwgUkVMX1JFU1RSSUNULCBmYWxzZSwgdW5kZWZpbmVkLCBcImZrX2dyb3Vwc190ZW5hbnRcIilcbiAgQHJlcXVpcmVkKClcbiAgdGVuYW50ITogVGVuYW50IHwgc3RyaW5nO1xuICBAbWFueVRvT25lKCgpID0+IE9yZ1VuaXQsIFJFTF9OVUxMSUZZLCBmYWxzZSwgdW5kZWZpbmVkLCBcImZrX2dyb3Vwc19vcmdfdW5pdFwiKVxuICBvcmdVbml0PzogT3JnVW5pdCB8IHN0cmluZztcbiAgQHJlcXVpcmVkKCkgQHR5cGVPZihTdHJpbmcpIEBjb2x1bW4oKSBuYW1lITogc3RyaW5nO1xuICBAdHlwZU9mKE9iamVjdCkgQGNvbHVtbigpIG1ldGFkYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIEBvbmVUb01hbnkoKCkgPT4gR3JvdXBNZW1iZXJzaGlwLCBSRUxfUkVTVFJJQ1QsIGZhbHNlKSBtZW1iZXJzPzogR3JvdXBNZW1iZXJzaGlwW10gfCBzdHJpbmdbXTtcbiAgQGNyZWF0ZWRBdCgpIGNyZWF0ZWRBdCE6IERhdGU7XG4gIEB1cGRhdGVkQXQoKSB1cGRhdGVkQXQhOiBEYXRlO1xufVxuIiwiaW1wb3J0IHsgY29sdW1uLCBjcmVhdGVkQXQsIG1hbnlUb09uZSwgcGssIHRhYmxlLCB1dWlkIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBtb2RlbCwgb3B0aW9uLCByZXF1aXJlZCwgdHlwZSBhcyB0eXBlT2YgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBTY29wZUtpbmQsIFNjb3BlS2luZE9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IFJFTF9DQVNDQURFX0RFUEVOREVOVCB9IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHsgQXV0aG9yaXphdGlvbk1vZGVsIH0gZnJvbSBcIi4vYXV0aG9yaXphdGlvbi1tb2RlbFwiO1xuaW1wb3J0IHsgVGVuYW50IH0gZnJvbSBcIi4vdGVuYW50Lm1vZGVsXCI7XG5pbXBvcnQgeyBQcmluY2lwYWwgfSBmcm9tIFwiLi9wcmluY2lwYWwubW9kZWxcIjtcblxuQHRhYmxlKFwiZWZmZWN0aXZlX3Blcm1pc3Npb25zXCIpXG5AbW9kZWwoKVxuZXhwb3J0IGNsYXNzIEVmZmVjdGl2ZVBlcm1pc3Npb24gZXh0ZW5kcyBBdXRob3JpemF0aW9uTW9kZWwge1xuICBjb25zdHJ1Y3RvcihkYXRhPzogdW5rbm93bikge1xuICAgIHN1cGVyKGRhdGEpO1xuICB9XG5cbiAgQHBrKHsgdHlwZTogU3RyaW5nIH0pIEB1dWlkKCkgaWQhOiBzdHJpbmc7XG4gIEBtYW55VG9PbmUoKCkgPT4gVGVuYW50LCBSRUxfQ0FTQ0FERV9ERVBFTkRFTlQsIGZhbHNlLCB1bmRlZmluZWQsIFwiZmtfZWZmZWN0aXZlX3Blcm1pc3Npb25zX3RlbmFudFwiKVxuICBAcmVxdWlyZWQoKVxuICB0ZW5hbnQhOiBUZW5hbnQgfCBzdHJpbmc7XG4gIEBtYW55VG9PbmUoKCkgPT4gUHJpbmNpcGFsLCBSRUxfQ0FTQ0FERV9ERVBFTkRFTlQsIGZhbHNlLCB1bmRlZmluZWQsIFwiZmtfZWZmZWN0aXZlX3Blcm1pc3Npb25zX3ByaW5jaXBhbFwiKVxuICBAcmVxdWlyZWQoKVxuICBwcmluY2lwYWwhOiBQcmluY2lwYWwgfCBzdHJpbmc7XG4gIEByZXF1aXJlZCgpIEB0eXBlT2YoU3RyaW5nKSBAY29sdW1uKCkgcGVybWlzc2lvbktleSE6IHN0cmluZztcbiAgQHJlcXVpcmVkKCkgQHR5cGVPZihTdHJpbmcpIEBvcHRpb24oU2NvcGVLaW5kT3B0aW9ucykgQGNvbHVtbigpIHNjb3BlS2luZCE6IFNjb3BlS2luZDtcbiAgQHJlcXVpcmVkKCkgQHR5cGVPZihTdHJpbmcpIEBjb2x1bW4oKSBzY29wZUlkITogc3RyaW5nO1xuICBAcmVxdWlyZWQoKSBAdHlwZU9mKFN0cmluZykgQGNvbHVtbigpIHNvdXJjZUtpbmQhOiBzdHJpbmc7XG4gIEByZXF1aXJlZCgpIEB0eXBlT2YoU3RyaW5nKSBAY29sdW1uKCkgc291cmNlSWQhOiBzdHJpbmc7XG4gIEBjb2x1bW4oKSBzdGFydHNBdD86IERhdGU7XG4gIEBjb2x1bW4oKSBleHBpcmVzQXQ/OiBEYXRlO1xuICBAY3JlYXRlZEF0KCkgY3JlYXRlZEF0ITogRGF0ZTtcbn1cbiIsImltcG9ydCB7IEJhc2VNb2RlbFNlcnZpY2UsIHNhbWVUZW5hbnQgfSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCB7IFRlbmFudFByb2ZpbGUgfSBmcm9tIFwiLi4vbW9kZWxzL3RlbmFudC1wcm9maWxlLm1vZGVsXCI7XG5cbmV4cG9ydCBjbGFzcyBUZW5hbnRQcm9maWxlU2VydmljZSBleHRlbmRzIEJhc2VNb2RlbFNlcnZpY2U8VGVuYW50UHJvZmlsZT4ge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcihUZW5hbnRQcm9maWxlKTtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZVByb2ZpbGUoXG4gICAgdGVuYW50SWQ6IHN0cmluZyxcbiAgICBwcm9maWxlS2V5OiBzdHJpbmcsXG4gICAgbWV0YWRhdGE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPFRlbmFudFByb2ZpbGU+IHtcbiAgICByZXR1cm4gdGhpcy5jcmVhdGUoXG4gICAgICB7XG4gICAgICAgIHRlbmFudDogdGVuYW50SWQsXG4gICAgICAgIHByb2ZpbGVLZXksXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgfSxcbiAgICAgIC4uLmFyZ3NcbiAgICApO1xuICB9XG5cbiAgYXN5bmMgbGlzdEZvclRlbmFudChcbiAgICB0ZW5hbnRJZDogc3RyaW5nLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8VGVuYW50UHJvZmlsZVtdPiB7XG4gICAgcmV0dXJuIChhd2FpdCB0aGlzLmxpc3RBbGwoLi4uYXJncykpLmZpbHRlcigocHJvZmlsZSkgPT5cbiAgICAgIHNhbWVUZW5hbnQocHJvZmlsZS50ZW5hbnQsIHRlbmFudElkKVxuICAgICk7XG4gIH1cblxuICBhc3luYyBkZWxldGVGb3JUZW5hbnQodGVuYW50SWQ6IHN0cmluZywgLi4uYXJnczogYW55W10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBmb3IgKGNvbnN0IHJvdyBvZiBhd2FpdCB0aGlzLmxpc3RGb3JUZW5hbnQodGVuYW50SWQsIC4uLmFyZ3MpKSB7XG4gICAgICBhd2FpdCB0aGlzLmRlbGV0ZUJ5SWQocm93LmlkLCAuLi5hcmdzKTtcbiAgICB9XG4gIH1cbn1cbiIsImltcG9ydCB7IEJhc2VNb2RlbFNlcnZpY2UsIHJlbGF0aW9uTWF0Y2ggfSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCB7IE9yZ1VuaXRQcm9maWxlIH0gZnJvbSBcIi4uL21vZGVscy9vcmctdW5pdC1wcm9maWxlLm1vZGVsXCI7XG5cbmV4cG9ydCBjbGFzcyBPcmdVbml0UHJvZmlsZVNlcnZpY2UgZXh0ZW5kcyBCYXNlTW9kZWxTZXJ2aWNlPE9yZ1VuaXRQcm9maWxlPiB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKE9yZ1VuaXRQcm9maWxlKTtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZVByb2ZpbGUoXG4gICAgb3JnVW5pdElkOiBzdHJpbmcsXG4gICAgcHJvZmlsZUtleTogc3RyaW5nLFxuICAgIG1ldGFkYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxPcmdVbml0UHJvZmlsZT4ge1xuICAgIHJldHVybiB0aGlzLmNyZWF0ZShcbiAgICAgIHtcbiAgICAgICAgb3JnVW5pdDogb3JnVW5pdElkLFxuICAgICAgICBwcm9maWxlS2V5LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgIH0sXG4gICAgICAuLi5hcmdzXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIGxpc3RGb3JPcmdVbml0KFxuICAgIG9yZ1VuaXRJZDogc3RyaW5nLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8T3JnVW5pdFByb2ZpbGVbXT4ge1xuICAgIHJldHVybiAoYXdhaXQgdGhpcy5saXN0QWxsKC4uLmFyZ3MpKS5maWx0ZXIoKHByb2ZpbGUpID0+XG4gICAgICByZWxhdGlvbk1hdGNoKHByb2ZpbGUub3JnVW5pdCwgb3JnVW5pdElkKVxuICAgICk7XG4gIH1cbn1cbiIsImltcG9ydCB7XG4gIEJhc2VNb2RlbFNlcnZpY2UsXG4gIHJlbGF0aW9uSWQsXG4gIHJlbGF0aW9uTWF0Y2gsXG4gIHNhbWVUZW5hbnQsXG59IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHsgT3JnVW5pdENsb3N1cmUgfSBmcm9tIFwiLi4vbW9kZWxzL29yZy11bml0LWNsb3N1cmUubW9kZWxcIjtcblxuZXhwb3J0IGNsYXNzIE9yZ1VuaXRDbG9zdXJlU2VydmljZSBleHRlbmRzIEJhc2VNb2RlbFNlcnZpY2U8T3JnVW5pdENsb3N1cmU+IHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoT3JnVW5pdENsb3N1cmUpO1xuICB9XG5cbiAgYXN5bmMgbGlzdEFuY2VzdG9ycyhcbiAgICB0ZW5hbnRJZDogc3RyaW5nLFxuICAgIG9yZ1VuaXRJZDogc3RyaW5nLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8T3JnVW5pdENsb3N1cmVbXT4ge1xuICAgIHJldHVybiAoYXdhaXQgdGhpcy5saXN0QWxsKC4uLmFyZ3MpKVxuICAgICAgLmZpbHRlcihcbiAgICAgICAgKHJvdykgPT5cbiAgICAgICAgICBzYW1lVGVuYW50KHJvdy50ZW5hbnQsIHRlbmFudElkKSAmJlxuICAgICAgICAgIHJlbGF0aW9uTWF0Y2gocm93LmRlc2NlbmRhbnQsIG9yZ1VuaXRJZClcbiAgICAgIClcbiAgICAgIC5zb3J0KChsZWZ0LCByaWdodCkgPT4gbGVmdC5kZXB0aCAtIHJpZ2h0LmRlcHRoKTtcbiAgfVxuXG4gIGFzeW5jIGxpc3REZXNjZW5kYW50cyhcbiAgICB0ZW5hbnRJZDogc3RyaW5nLFxuICAgIG9yZ1VuaXRJZDogc3RyaW5nLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8T3JnVW5pdENsb3N1cmVbXT4ge1xuICAgIHJldHVybiAoYXdhaXQgdGhpcy5saXN0QWxsKC4uLmFyZ3MpKVxuICAgICAgLmZpbHRlcihcbiAgICAgICAgKHJvdykgPT5cbiAgICAgICAgICBzYW1lVGVuYW50KHJvdy50ZW5hbnQsIHRlbmFudElkKSAmJlxuICAgICAgICAgIHJlbGF0aW9uTWF0Y2gocm93LmFuY2VzdG9yLCBvcmdVbml0SWQpXG4gICAgICApXG4gICAgICAuc29ydCgobGVmdCwgcmlnaHQpID0+IGxlZnQuZGVwdGggLSByaWdodC5kZXB0aCk7XG4gIH1cblxuICBhc3luYyBpc0FuY2VzdG9yT2YoXG4gICAgdGVuYW50SWQ6IHN0cmluZyxcbiAgICBhbmNlc3Rvck9yZ1VuaXRJZDogc3RyaW5nLFxuICAgIGRlc2NlbmRhbnRPcmdVbml0SWQ6IHN0cmluZyxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gKFxuICAgICAgYXdhaXQgdGhpcy5saXN0QW5jZXN0b3JzKHRlbmFudElkLCBkZXNjZW5kYW50T3JnVW5pdElkLCAuLi5hcmdzKVxuICAgICkuc29tZSgocm93KSA9PiByZWxhdGlvbk1hdGNoKHJvdy5hbmNlc3RvciwgYW5jZXN0b3JPcmdVbml0SWQpKTtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZVNlbGZMaW5rKFxuICAgIHRlbmFudElkOiBzdHJpbmcsXG4gICAgb3JnVW5pdElkOiBzdHJpbmcsXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxPcmdVbml0Q2xvc3VyZT4ge1xuICAgIHJldHVybiB0aGlzLmNyZWF0ZShcbiAgICAgIHtcbiAgICAgICAgdGVuYW50OiB0ZW5hbnRJZCxcbiAgICAgICAgYW5jZXN0b3I6IG9yZ1VuaXRJZCxcbiAgICAgICAgZGVzY2VuZGFudDogb3JnVW5pdElkLFxuICAgICAgICBkZXB0aDogMCxcbiAgICAgIH0sXG4gICAgICAuLi5hcmdzXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIGluc2VydEFuY2VzdG9yTGlua3NGb3JOZXdDaGlsZChcbiAgICB0ZW5hbnRJZDogc3RyaW5nLFxuICAgIHBhcmVudE9yZ1VuaXRJZDogc3RyaW5nLFxuICAgIGNoaWxkT3JnVW5pdElkOiBzdHJpbmcsXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgYW5jZXN0b3JMaW5rcyA9IGF3YWl0IHRoaXMubGlzdEFuY2VzdG9ycyhcbiAgICAgIHRlbmFudElkLFxuICAgICAgcGFyZW50T3JnVW5pdElkLFxuICAgICAgLi4uYXJnc1xuICAgICk7XG4gICAgZm9yIChjb25zdCBsaW5rIG9mIGFuY2VzdG9yTGlua3MpIHtcbiAgICAgIGF3YWl0IHRoaXMuY3JlYXRlKFxuICAgICAgICB7XG4gICAgICAgICAgdGVuYW50OiB0ZW5hbnRJZCxcbiAgICAgICAgICBhbmNlc3RvcjogbGluay5hbmNlc3RvcixcbiAgICAgICAgICBkZXNjZW5kYW50OiBjaGlsZE9yZ1VuaXRJZCxcbiAgICAgICAgICBkZXB0aDogbGluay5kZXB0aCArIDEsXG4gICAgICAgIH0sXG4gICAgICAgIC4uLmFyZ3NcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZGVsZXRlTGlua3NGb3JTdWJ0cmVlKFxuICAgIHRlbmFudElkOiBzdHJpbmcsXG4gICAgb3JnVW5pdElkOiBzdHJpbmcsXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3Qgc3VidHJlZSA9IGF3YWl0IHRoaXMubGlzdERlc2NlbmRhbnRzKHRlbmFudElkLCBvcmdVbml0SWQsIC4uLmFyZ3MpO1xuICAgIGNvbnN0IGRlc2NlbmRhbnRJZHMgPSBuZXcgU2V0KFtcbiAgICAgIG9yZ1VuaXRJZCxcbiAgICAgIC4uLnN1YnRyZWUubWFwKChyb3cpID0+IHJlbGF0aW9uSWQocm93LmRlc2NlbmRhbnQpKSxcbiAgICBdKTtcbiAgICBjb25zdCBhbmNlc3RvcklkcyA9IG5ldyBTZXQoW1xuICAgICAgb3JnVW5pdElkLFxuICAgICAgLi4uc3VidHJlZS5tYXAoKHJvdykgPT4gcmVsYXRpb25JZChyb3cuYW5jZXN0b3IpKSxcbiAgICBdKTtcbiAgICBjb25zdCByb3dzID0gKGF3YWl0IHRoaXMubGlzdEFsbCguLi5hcmdzKSkuZmlsdGVyKFxuICAgICAgKHJvdykgPT5cbiAgICAgICAgc2FtZVRlbmFudChyb3cudGVuYW50LCB0ZW5hbnRJZCkgJiZcbiAgICAgICAgKGRlc2NlbmRhbnRJZHMuaGFzKHJlbGF0aW9uSWQocm93LmRlc2NlbmRhbnQpKSB8fFxuICAgICAgICAgIGFuY2VzdG9ySWRzLmhhcyhyZWxhdGlvbklkKHJvdy5hbmNlc3RvcikpKVxuICAgICk7XG4gICAgZm9yIChjb25zdCByb3cgb2Ygcm93cykge1xuICAgICAgYXdhaXQgdGhpcy5kZWxldGVCeUlkKHJvdy5pZCwgLi4uYXJncyk7XG4gICAgfVxuICB9XG59XG4iLCJpbXBvcnQgeyBCYXNlTW9kZWxTZXJ2aWNlLCByZWxhdGlvbk1hdGNoLCBzYW1lVGVuYW50IH0gZnJvbSBcIi4uL3V0aWxzXCI7XG5pbXBvcnQgeyBQZXJtaXNzaW9uQ2F0ZWdvcnkgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IEluaGVyaXRhbmNlQmxvY2sgfSBmcm9tIFwiLi4vbW9kZWxzL2luaGVyaXRhbmNlLWJsb2NrLm1vZGVsXCI7XG5cbmV4cG9ydCBjbGFzcyBJbmhlcml0YW5jZUJsb2NrU2VydmljZSBleHRlbmRzIEJhc2VNb2RlbFNlcnZpY2U8SW5oZXJpdGFuY2VCbG9jaz4ge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcihJbmhlcml0YW5jZUJsb2NrKTtcbiAgfVxuXG4gIGFzeW5jIGJsb2NrQ2F0ZWdvcnkoXG4gICAgdGVuYW50SWQ6IHN0cmluZyxcbiAgICBvcmdVbml0SWQ6IHN0cmluZyxcbiAgICBwZXJtaXNzaW9uQ2F0ZWdvcnk6IFBlcm1pc3Npb25DYXRlZ29yeSxcbiAgICBibG9ja2VkRnJvbUFuY2VzdG9ySWQ/OiBzdHJpbmcsXG4gICAgcmVhc29uPzogc3RyaW5nLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8SW5oZXJpdGFuY2VCbG9jaz4ge1xuICAgIHJldHVybiB0aGlzLmNyZWF0ZShcbiAgICAgIHtcbiAgICAgICAgdGVuYW50OiB0ZW5hbnRJZCxcbiAgICAgICAgb3JnVW5pdDogb3JnVW5pdElkLFxuICAgICAgICBibG9ja2VkRnJvbUFuY2VzdG9yOiBibG9ja2VkRnJvbUFuY2VzdG9ySWQsXG4gICAgICAgIHBlcm1pc3Npb25DYXRlZ29yeSxcbiAgICAgICAgcmVhc29uLFxuICAgICAgfSxcbiAgICAgIC4uLmFyZ3NcbiAgICApO1xuICB9XG5cbiAgYXN5bmMgdW5ibG9ja0NhdGVnb3J5KGJsb2NrSWQ6IHN0cmluZywgLi4uYXJnczogYW55W10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLmRlbGV0ZUJ5SWQoYmxvY2tJZCwgLi4uYXJncyk7XG4gIH1cblxuICBhc3luYyBsaXN0Rm9yT3JnVW5pdChcbiAgICB0ZW5hbnRJZDogc3RyaW5nLFxuICAgIG9yZ1VuaXRJZDogc3RyaW5nLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8SW5oZXJpdGFuY2VCbG9ja1tdPiB7XG4gICAgcmV0dXJuIChhd2FpdCB0aGlzLmxpc3RBbGwoLi4uYXJncykpLmZpbHRlcihcbiAgICAgIChibG9jaykgPT5cbiAgICAgICAgc2FtZVRlbmFudChibG9jay50ZW5hbnQsIHRlbmFudElkKSAmJlxuICAgICAgICByZWxhdGlvbk1hdGNoKGJsb2NrLm9yZ1VuaXQsIG9yZ1VuaXRJZClcbiAgICApO1xuICB9XG5cbiAgYXN5bmMgY2F0ZWdvcnlCbG9ja2VkRm9yQW5jZXN0b3IoXG4gICAgdGVuYW50SWQ6IHN0cmluZyxcbiAgICBvcmdVbml0SWQ6IHN0cmluZyxcbiAgICBhbmNlc3Rvck9yZ1VuaXRJZDogc3RyaW5nLFxuICAgIGNhdGVnb3J5OiBQZXJtaXNzaW9uQ2F0ZWdvcnksXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIChhd2FpdCB0aGlzLmxpc3RGb3JPcmdVbml0KHRlbmFudElkLCBvcmdVbml0SWQsIC4uLmFyZ3MpKS5zb21lKFxuICAgICAgKGJsb2NrKSA9PlxuICAgICAgICBibG9jay5wZXJtaXNzaW9uQ2F0ZWdvcnkgPT09IGNhdGVnb3J5ICYmXG4gICAgICAgICghYmxvY2suYmxvY2tlZEZyb21BbmNlc3RvciB8fFxuICAgICAgICAgIHJlbGF0aW9uTWF0Y2goYmxvY2suYmxvY2tlZEZyb21BbmNlc3RvciwgYW5jZXN0b3JPcmdVbml0SWQpKVxuICAgICk7XG4gIH1cbn1cbiIsImltcG9ydCB7IEJhc2VNb2RlbFNlcnZpY2UgfSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCB7IElzb2xhdGlvblRpZXIsIENyZWF0ZVRlbmFudElucHV0IH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBUZW5hbnQgfSBmcm9tIFwiLi4vbW9kZWxzL3RlbmFudC5tb2RlbFwiO1xuXG5leHBvcnQgY2xhc3MgVGVuYW50U2VydmljZSBleHRlbmRzIEJhc2VNb2RlbFNlcnZpY2U8VGVuYW50PiB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKFRlbmFudCk7XG4gIH1cblxuICBhc3luYyBjcmVhdGVUZW5hbnQoaW5wdXQ6IENyZWF0ZVRlbmFudElucHV0LCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8VGVuYW50PiB7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlKFxuICAgICAge1xuICAgICAgICBzbHVnOiBpbnB1dC5zbHVnLFxuICAgICAgICBuYW1lOiBpbnB1dC5uYW1lLFxuICAgICAgICBpc29sYXRpb25UaWVyOiBpbnB1dC5pc29sYXRpb25UaWVyID8/IElzb2xhdGlvblRpZXIuUG9vbGVkLFxuICAgICAgfSxcbiAgICAgIC4uLmFyZ3NcbiAgICApO1xuICB9XG5cbiAgYXN5bmMgZ2V0QnlTbHVnKHNsdWc6IHN0cmluZywgLi4uYXJnczogYW55W10pOiBQcm9taXNlPFRlbmFudD4ge1xuICAgIHJldHVybiB0aGlzLmZpbmRPbmVCeShcInNsdWdcIiwgc2x1ZyBhcyBuZXZlciwgLi4uYXJncyk7XG4gIH1cblxuICBhc3luYyByZW5hbWVUZW5hbnQodGVuYW50SWQ6IHN0cmluZywgbmFtZTogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8VGVuYW50PiB7XG4gICAgcmV0dXJuIHRoaXMudXBkYXRlT25lKHRlbmFudElkLCB7IG5hbWUgfSwgLi4uYXJncyk7XG4gIH1cblxuICBhc3luYyBjaGFuZ2VTbHVnKHRlbmFudElkOiBzdHJpbmcsIHNsdWc6IHN0cmluZywgLi4uYXJnczogYW55W10pOiBQcm9taXNlPFRlbmFudD4ge1xuICAgIHJldHVybiB0aGlzLnVwZGF0ZU9uZSh0ZW5hbnRJZCwgeyBzbHVnIH0sIC4uLmFyZ3MpO1xuICB9XG5cbiAgYXN5bmMgc2V0SXNvbGF0aW9uVGllcihcbiAgICB0ZW5hbnRJZDogc3RyaW5nLFxuICAgIGlzb2xhdGlvblRpZXI6IElzb2xhdGlvblRpZXIsXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxUZW5hbnQ+IHtcbiAgICByZXR1cm4gdGhpcy51cGRhdGVPbmUodGVuYW50SWQsIHsgaXNvbGF0aW9uVGllciB9LCAuLi5hcmdzKTtcbiAgfVxuXG4gIGFzeW5jIGRlbGV0ZVRlbmFudENvbnRyb2xsZWQodGVuYW50SWQ6IHN0cmluZywgLi4uYXJnczogYW55W10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLmRlbGV0ZUJ5SWQodGVuYW50SWQsIC4uLmFyZ3MpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBCYXNlTW9kZWxTZXJ2aWNlLCBsb3dlclNsdWcsIHJlbGF0aW9uSWQsIHJlbGF0aW9uTWF0Y2gsIHNhbWVUZW5hbnQgfSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCB0eXBlIHsgQ3JlYXRlT3JnVW5pdElucHV0IH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBPcmdVbml0IH0gZnJvbSBcIi4uL21vZGVscy9vcmctdW5pdC5tb2RlbFwiO1xuaW1wb3J0IHsgT3JnVW5pdFByb2ZpbGVTZXJ2aWNlIH0gZnJvbSBcIi4vb3JnLXVuaXQtcHJvZmlsZS5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBPcmdVbml0Q2xvc3VyZVNlcnZpY2UgfSBmcm9tIFwiLi9vcmctdW5pdC1jbG9zdXJlLnNlcnZpY2VcIjtcbmltcG9ydCB7IHRyYW5zYWN0aW9uYWwgfSBmcm9tIFwiLi4vdXRpbHNcIjtcblxuYXN5bmMgZnVuY3Rpb24gZGVsZXRlUm93c0J5SWQoXG4gIHNlcnZpY2U6IEJhc2VNb2RlbFNlcnZpY2U8YW55PixcbiAgcm93czogQXJyYXk8eyBpZDogc3RyaW5nIH0+LFxuICAuLi5hcmdzOiBhbnlbXVxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICBhd2FpdCBzZXJ2aWNlLmRlbGV0ZUJ5SWQocm93LmlkLCAuLi5hcmdzKTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgT3JnVW5pdFNlcnZpY2UgZXh0ZW5kcyBCYXNlTW9kZWxTZXJ2aWNlPE9yZ1VuaXQ+IHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoT3JnVW5pdCk7XG4gIH1cblxuICBwcml2YXRlIG9yZ1VuaXRQYXRoKHBhcmVudFBhdGg6IHN0cmluZyB8IHVuZGVmaW5lZCwgbmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBzZWdtZW50ID0gbG93ZXJTbHVnKG5hbWUpO1xuICAgIHJldHVybiBwYXJlbnRQYXRoID8gYCR7cGFyZW50UGF0aC5yZXBsYWNlKC9cXC8rJC8sIFwiXCIpfS8ke3NlZ21lbnR9YCA6IGAvJHtzZWdtZW50fWA7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGNyZWF0ZVByb2ZpbGVJZk5lZWRlZChcbiAgICBvcmdVbml0SWQ6IHN0cmluZyxcbiAgICBwcm9maWxlS2V5OiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gICAgcHJvZmlsZU1ldGFkYXRhOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB8IHVuZGVmaW5lZCxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXByb2ZpbGVLZXkpIHJldHVybjtcbiAgICBhd2FpdCBuZXcgT3JnVW5pdFByb2ZpbGVTZXJ2aWNlKCkuY3JlYXRlUHJvZmlsZShvcmdVbml0SWQsIHByb2ZpbGVLZXksIHByb2ZpbGVNZXRhZGF0YSwgLi4uYXJncyk7XG4gIH1cblxuICBAdHJhbnNhY3Rpb25hbCgpXG4gIGFzeW5jIGNyZWF0ZVJvb3QoXG4gICAgdGVuYW50SWQ6IHN0cmluZyxcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgbWV0YWRhdGE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcbiAgICBwcm9maWxlS2V5Pzogc3RyaW5nLFxuICAgIHByb2ZpbGVNZXRhZGF0YT86IFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8T3JnVW5pdD4ge1xuICAgIGNvbnN0IG9yZ1VuaXQgPSBhd2FpdCB0aGlzLmNyZWF0ZShcbiAgICAgIHtcbiAgICAgICAgdGVuYW50OiB0ZW5hbnRJZCxcbiAgICAgICAgbmFtZSxcbiAgICAgICAgcGF0aDogdGhpcy5vcmdVbml0UGF0aCh1bmRlZmluZWQsIG5hbWUpLFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgIH0sXG4gICAgICAuLi5hcmdzXG4gICAgKTtcbiAgICBhd2FpdCB0aGlzLmNyZWF0ZVByb2ZpbGVJZk5lZWRlZChvcmdVbml0LmlkLCBwcm9maWxlS2V5LCBwcm9maWxlTWV0YWRhdGEsIC4uLmFyZ3MpO1xuICAgIGF3YWl0IG5ldyBPcmdVbml0Q2xvc3VyZVNlcnZpY2UoKS5jcmVhdGVTZWxmTGluayh0ZW5hbnRJZCwgb3JnVW5pdC5pZCwgLi4uYXJncyk7XG4gICAgcmV0dXJuIG9yZ1VuaXQ7XG4gIH1cblxuICBAdHJhbnNhY3Rpb25hbCgpXG4gIGFzeW5jIGNyZWF0ZUNoaWxkKGlucHV0OiBDcmVhdGVPcmdVbml0SW5wdXQsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxPcmdVbml0PiB7XG4gICAgY29uc3QgcGFyZW50ID0gaW5wdXQucGFyZW50T3JnVW5pdElkID8gYXdhaXQgdGhpcy5nZXRCeUlkKGlucHV0LnBhcmVudE9yZ1VuaXRJZCwgLi4uYXJncykgOiB1bmRlZmluZWQ7XG4gICAgY29uc3Qgb3JnVW5pdCA9IGF3YWl0IHRoaXMuY3JlYXRlKFxuICAgICAge1xuICAgICAgICB0ZW5hbnQ6IGlucHV0LnRlbmFudElkLFxuICAgICAgICBwYXJlbnQ6IHBhcmVudD8uaWQgPz8gaW5wdXQucGFyZW50T3JnVW5pdElkLFxuICAgICAgICBuYW1lOiBpbnB1dC5uYW1lLFxuICAgICAgICBwYXRoOiB0aGlzLm9yZ1VuaXRQYXRoKHBhcmVudD8ucGF0aCwgaW5wdXQubmFtZSksXG4gICAgICAgIG1ldGFkYXRhOiBpbnB1dC5tZXRhZGF0YSxcbiAgICAgIH0sXG4gICAgICAuLi5hcmdzXG4gICAgKTtcbiAgICBhd2FpdCB0aGlzLmNyZWF0ZVByb2ZpbGVJZk5lZWRlZChvcmdVbml0LmlkLCBpbnB1dC5wcm9maWxlS2V5LCBpbnB1dC5wcm9maWxlTWV0YWRhdGEsIC4uLmFyZ3MpO1xuICAgIGNvbnN0IGNsb3N1cmVTZXJ2aWNlID0gbmV3IE9yZ1VuaXRDbG9zdXJlU2VydmljZSgpO1xuICAgIGF3YWl0IGNsb3N1cmVTZXJ2aWNlLmNyZWF0ZVNlbGZMaW5rKGlucHV0LnRlbmFudElkLCBvcmdVbml0LmlkLCAuLi5hcmdzKTtcbiAgICBpZiAoaW5wdXQucGFyZW50T3JnVW5pdElkKSB7XG4gICAgICBhd2FpdCBjbG9zdXJlU2VydmljZS5pbnNlcnRBbmNlc3RvckxpbmtzRm9yTmV3Q2hpbGQoXG4gICAgICAgIGlucHV0LnRlbmFudElkLFxuICAgICAgICBpbnB1dC5wYXJlbnRPcmdVbml0SWQsXG4gICAgICAgIG9yZ1VuaXQuaWQsXG4gICAgICAgIC4uLmFyZ3NcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBvcmdVbml0O1xuICB9XG5cbiAgYXN5bmMgbGlzdENoaWxkcmVuKHBhcmVudE9yZ1VuaXRJZDogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8T3JnVW5pdFtdPiB7XG4gICAgcmV0dXJuIChhd2FpdCB0aGlzLmxpc3RBbGwoLi4uYXJncykpLmZpbHRlcigob3JnVW5pdCkgPT4gcmVsYXRpb25NYXRjaChvcmdVbml0LnBhcmVudCwgcGFyZW50T3JnVW5pdElkKSk7XG4gIH1cblxuICBhc3luYyBsaXN0VGVuYW50T3JnVW5pdHModGVuYW50SWQ6IHN0cmluZywgLi4uYXJnczogYW55W10pOiBQcm9taXNlPE9yZ1VuaXRbXT4ge1xuICAgIHJldHVybiAoYXdhaXQgdGhpcy5saXN0QWxsKC4uLmFyZ3MpKS5maWx0ZXIoKG9yZ1VuaXQpID0+IHNhbWVUZW5hbnQob3JnVW5pdC50ZW5hbnQsIHRlbmFudElkKSk7XG4gIH1cblxuICBhc3luYyBsaXN0RGVzY2VuZGFudE9yZ1VuaXRzKFxuICAgIHRlbmFudElkOiBzdHJpbmcsXG4gICAgb3JnVW5pdElkOiBzdHJpbmcsXG4gICAgaW5jbHVkZVNlbGYgPSBmYWxzZSxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPE9yZ1VuaXRbXT4ge1xuICAgIGNvbnN0IGRlc2NlbmRhbnRzID0gYXdhaXQgbmV3IE9yZ1VuaXRDbG9zdXJlU2VydmljZSgpLmxpc3REZXNjZW5kYW50cyh0ZW5hbnRJZCwgb3JnVW5pdElkLCAuLi5hcmdzKTtcbiAgICBjb25zdCBpZHMgPSBuZXcgU2V0KGRlc2NlbmRhbnRzLm1hcCgocm93KSA9PiByZWxhdGlvbklkKHJvdy5kZXNjZW5kYW50KSkpO1xuICAgIGlmIChpbmNsdWRlU2VsZikgaWRzLmFkZChvcmdVbml0SWQpO1xuICAgIHJldHVybiAoYXdhaXQgdGhpcy5saXN0VGVuYW50T3JnVW5pdHModGVuYW50SWQsIC4uLmFyZ3MpKS5maWx0ZXIoKG9yZ1VuaXQpID0+IGlkcy5oYXMob3JnVW5pdC5pZCkpO1xuICB9XG5cbiAgYXN5bmMgbGlzdEFuY2VzdG9yT3JnVW5pdHMoXG4gICAgdGVuYW50SWQ6IHN0cmluZyxcbiAgICBvcmdVbml0SWQ6IHN0cmluZyxcbiAgICBpbmNsdWRlU2VsZiA9IGZhbHNlLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8T3JnVW5pdFtdPiB7XG4gICAgY29uc3QgYW5jZXN0b3JzID0gYXdhaXQgbmV3IE9yZ1VuaXRDbG9zdXJlU2VydmljZSgpLmxpc3RBbmNlc3RvcnModGVuYW50SWQsIG9yZ1VuaXRJZCwgLi4uYXJncyk7XG4gICAgY29uc3QgaWRzID0gbmV3IFNldChhbmNlc3RvcnMubWFwKChyb3cpID0+IHJlbGF0aW9uSWQocm93LmFuY2VzdG9yKSkpO1xuICAgIGlmIChpbmNsdWRlU2VsZikgaWRzLmFkZChvcmdVbml0SWQpO1xuICAgIHJldHVybiAoYXdhaXQgdGhpcy5saXN0VGVuYW50T3JnVW5pdHModGVuYW50SWQsIC4uLmFyZ3MpKS5maWx0ZXIoKG9yZ1VuaXQpID0+IGlkcy5oYXMob3JnVW5pdC5pZCkpO1xuICB9XG5cbiAgYXN5bmMgcmVuYW1lT3JnVW5pdChvcmdVbml0SWQ6IHN0cmluZywgbmFtZTogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8T3JnVW5pdD4ge1xuICAgIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgdGhpcy5nZXRCeUlkKG9yZ1VuaXRJZCwgLi4uYXJncyk7XG4gICAgcmV0dXJuIHRoaXMudXBkYXRlT25lKFxuICAgICAgb3JnVW5pdElkLFxuICAgICAgeyBuYW1lLCBwYXRoOiB0aGlzLm9yZ1VuaXRQYXRoKGV4aXN0aW5nLnBhdGguaW5jbHVkZXMoXCIvXCIpID8gZXhpc3RpbmcucGF0aC5yZXBsYWNlKC9cXC9bXi9dKyQvLCBcIlwiKSA6IHVuZGVmaW5lZCwgbmFtZSkgfSxcbiAgICAgIC4uLmFyZ3NcbiAgICApO1xuICB9XG5cbiAgQHRyYW5zYWN0aW9uYWwoKVxuICBhc3luYyBtb3ZlT3JnVW5pdChcbiAgICB0ZW5hbnRJZDogc3RyaW5nLFxuICAgIG9yZ1VuaXRJZDogc3RyaW5nLFxuICAgIG5ld1BhcmVudE9yZ1VuaXRJZDogc3RyaW5nLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8T3JnVW5pdD4ge1xuICAgIGNvbnN0IG5ld1BhcmVudCA9IGF3YWl0IHRoaXMuZ2V0QnlJZChuZXdQYXJlbnRPcmdVbml0SWQsIC4uLmFyZ3MpO1xuICAgIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgdGhpcy5nZXRCeUlkKG9yZ1VuaXRJZCwgLi4uYXJncyk7XG4gICAgY29uc3QgdXBkYXRlZCA9IGF3YWl0IHRoaXMudXBkYXRlT25lKFxuICAgICAgb3JnVW5pdElkLFxuICAgICAge1xuICAgICAgICBwYXJlbnQ6IG5ld1BhcmVudC5pZCxcbiAgICAgICAgcGF0aDogdGhpcy5vcmdVbml0UGF0aChuZXdQYXJlbnQucGF0aCwgZXhpc3RpbmcubmFtZSksXG4gICAgICB9LFxuICAgICAgLi4uYXJnc1xuICAgICk7XG4gICAgYXdhaXQgdGhpcy5yZWJ1aWxkVGVuYW50Q2xvc3VyZSh0ZW5hbnRJZCwgLi4uYXJncyk7XG4gICAgcmV0dXJuIHVwZGF0ZWQ7XG4gIH1cblxuICBAdHJhbnNhY3Rpb25hbCgpXG4gIGFzeW5jIHJlYnVpbGRUZW5hbnRDbG9zdXJlKHRlbmFudElkOiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgY2xvc3VyZVNlcnZpY2UgPSBuZXcgT3JnVW5pdENsb3N1cmVTZXJ2aWNlKCk7XG4gICAgY29uc3QgZXhpc3RpbmdMaW5rcyA9IGF3YWl0IGNsb3N1cmVTZXJ2aWNlLmxpc3RBbGwoLi4uYXJncyk7XG4gICAgYXdhaXQgZGVsZXRlUm93c0J5SWQoXG4gICAgICBjbG9zdXJlU2VydmljZSxcbiAgICAgIGV4aXN0aW5nTGlua3MuZmlsdGVyKChyb3cpID0+IHNhbWVUZW5hbnQocm93LnRlbmFudCwgdGVuYW50SWQpKSxcbiAgICAgIC4uLmFyZ3NcbiAgICApO1xuXG4gICAgY29uc3Qgb3JnVW5pdHMgPSAoYXdhaXQgdGhpcy5saXN0VGVuYW50T3JnVW5pdHModGVuYW50SWQsIC4uLmFyZ3MpKS5zb3J0KChsZWZ0LCByaWdodCkgPT4ge1xuICAgICAgY29uc3QgbGVmdERlcHRoID0gbGVmdC5wYXRoLnNwbGl0KFwiL1wiKS5maWx0ZXIoQm9vbGVhbikubGVuZ3RoO1xuICAgICAgY29uc3QgcmlnaHREZXB0aCA9IHJpZ2h0LnBhdGguc3BsaXQoXCIvXCIpLmZpbHRlcihCb29sZWFuKS5sZW5ndGg7XG4gICAgICByZXR1cm4gbGVmdERlcHRoIC0gcmlnaHREZXB0aDtcbiAgICB9KTtcblxuICAgIGZvciAoY29uc3Qgb3JnVW5pdCBvZiBvcmdVbml0cykge1xuICAgICAgYXdhaXQgY2xvc3VyZVNlcnZpY2UuY3JlYXRlU2VsZkxpbmsodGVuYW50SWQsIG9yZ1VuaXQuaWQsIC4uLmFyZ3MpO1xuICAgICAgaWYgKG9yZ1VuaXQucGFyZW50KSB7XG4gICAgICAgIGF3YWl0IGNsb3N1cmVTZXJ2aWNlLmluc2VydEFuY2VzdG9yTGlua3NGb3JOZXdDaGlsZChcbiAgICAgICAgICB0ZW5hbnRJZCxcbiAgICAgICAgICByZWxhdGlvbklkKG9yZ1VuaXQucGFyZW50KSxcbiAgICAgICAgICBvcmdVbml0LmlkLFxuICAgICAgICAgIC4uLmFyZ3NcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBAdHJhbnNhY3Rpb25hbCgpXG4gIGFzeW5jIGRlbGV0ZU9yZ1VuaXRUcmVlKHRlbmFudElkOiBzdHJpbmcsIG9yZ1VuaXRJZDogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGNsb3N1cmVTZXJ2aWNlID0gbmV3IE9yZ1VuaXRDbG9zdXJlU2VydmljZSgpO1xuICAgIGNvbnN0IGRlc2NlbmRhbnRzID0gYXdhaXQgdGhpcy5saXN0RGVzY2VuZGFudE9yZ1VuaXRzKHRlbmFudElkLCBvcmdVbml0SWQsIHRydWUsIC4uLmFyZ3MpO1xuICAgIGNvbnN0IGRlc2NlbmRhbnRJZHMgPSBuZXcgU2V0KGRlc2NlbmRhbnRzLm1hcCgob3JnVW5pdCkgPT4gb3JnVW5pdC5pZCkpO1xuICAgIGNvbnN0IG9yZ1VuaXRzID0gKGF3YWl0IHRoaXMubGlzdFRlbmFudE9yZ1VuaXRzKHRlbmFudElkLCAuLi5hcmdzKSkuZmlsdGVyKChvcmdVbml0KSA9PlxuICAgICAgZGVzY2VuZGFudElkcy5oYXMob3JnVW5pdC5pZClcbiAgICApO1xuICAgIGF3YWl0IGRlbGV0ZVJvd3NCeUlkKHRoaXMsIG9yZ1VuaXRzLCAuLi5hcmdzKTtcbiAgICBhd2FpdCBjbG9zdXJlU2VydmljZS5kZWxldGVMaW5rc0ZvclN1YnRyZWUodGVuYW50SWQsIG9yZ1VuaXRJZCwgLi4uYXJncyk7XG4gIH1cbn1cbiIsImltcG9ydCB7IEJhc2VNb2RlbFNlcnZpY2UgfSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCB7IENyZWF0ZVVzZXJJbnB1dCB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgVXNlciB9IGZyb20gXCIuLi9tb2RlbHMvdXNlci5tb2RlbFwiO1xuXG5leHBvcnQgY2xhc3MgVXNlclNlcnZpY2UgZXh0ZW5kcyBCYXNlTW9kZWxTZXJ2aWNlPFVzZXI+IHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoVXNlcik7XG4gIH1cblxuICBhc3luYyBjcmVhdGVVc2VyKGlucHV0OiBDcmVhdGVVc2VySW5wdXQsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxVc2VyPiB7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlKFxuICAgICAge1xuICAgICAgICBlbWFpbDogaW5wdXQuZW1haWwsXG4gICAgICAgIHBob25lOiBpbnB1dC5waG9uZSxcbiAgICAgICAgZGlzcGxheU5hbWU6IGlucHV0LmRpc3BsYXlOYW1lLFxuICAgICAgfSxcbiAgICAgIC4uLmFyZ3NcbiAgICApO1xuICB9XG5cbiAgYXN5bmMgZ2V0QnlFbWFpbChlbWFpbDogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8VXNlcj4ge1xuICAgIHJldHVybiAoYXdhaXQgdGhpcy5saXN0QWxsKC4uLmFyZ3MpKS5maW5kKCh1c2VyKSA9PiB1c2VyLmVtYWlsID09PSBlbWFpbCkgYXMgVXNlcjtcbiAgfVxuXG4gIGFzeW5jIHVwZGF0ZURpc3BsYXlOYW1lKHVzZXJJZDogc3RyaW5nLCBkaXNwbGF5TmFtZTogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8VXNlcj4ge1xuICAgIHJldHVybiB0aGlzLnVwZGF0ZU9uZSh1c2VySWQsIHsgZGlzcGxheU5hbWUgfSwgLi4uYXJncyk7XG4gIH1cblxuICBhc3luYyB1cGRhdGVFbWFpbCh1c2VySWQ6IHN0cmluZywgZW1haWw6IHN0cmluZyB8IHVuZGVmaW5lZCwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPFVzZXI+IHtcbiAgICByZXR1cm4gdGhpcy51cGRhdGVPbmUodXNlcklkLCB7IGVtYWlsIH0sIC4uLmFyZ3MpO1xuICB9XG5cbiAgYXN5bmMgdXBkYXRlUGhvbmUodXNlcklkOiBzdHJpbmcsIHBob25lOiBzdHJpbmcgfCB1bmRlZmluZWQsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxVc2VyPiB7XG4gICAgcmV0dXJuIHRoaXMudXBkYXRlT25lKHVzZXJJZCwgeyBwaG9uZSB9LCAuLi5hcmdzKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgQmFzZU1vZGVsU2VydmljZSwgc2FtZVRlbmFudCB9IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHsgUHJpbmNpcGFsS2luZCB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgUHJpbmNpcGFsIH0gZnJvbSBcIi4uL21vZGVscy9wcmluY2lwYWwubW9kZWxcIjtcblxuZXhwb3J0IGNsYXNzIFByaW5jaXBhbFNlcnZpY2UgZXh0ZW5kcyBCYXNlTW9kZWxTZXJ2aWNlPFByaW5jaXBhbD4ge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcihQcmluY2lwYWwpO1xuICB9XG5cbiAgYXN5bmMgY3JlYXRlUHJpbmNpcGFsKFxuICAgIHRlbmFudElkOiBzdHJpbmcsXG4gICAga2luZDogUHJpbmNpcGFsS2luZCxcbiAgICBzdWJqZWN0SWQ6IHN0cmluZyxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPFByaW5jaXBhbD4ge1xuICAgIHJldHVybiB0aGlzLmNyZWF0ZShcbiAgICAgIHtcbiAgICAgICAgdGVuYW50OiB0ZW5hbnRJZCxcbiAgICAgICAga2luZCxcbiAgICAgICAgc3ViamVjdElkLFxuICAgICAgfSxcbiAgICAgIC4uLmFyZ3NcbiAgICApO1xuICB9XG5cbiAgYXN5bmMgZ2V0Rm9yU3ViamVjdChcbiAgICB0ZW5hbnRJZDogc3RyaW5nLFxuICAgIGtpbmQ6IFByaW5jaXBhbEtpbmQsXG4gICAgc3ViamVjdElkOiBzdHJpbmcsXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxQcmluY2lwYWwgfCB1bmRlZmluZWQ+IHtcbiAgICByZXR1cm4gKGF3YWl0IHRoaXMubGlzdEFsbCguLi5hcmdzKSkuZmluZChcbiAgICAgIChwcmluY2lwYWwpID0+XG4gICAgICAgIHNhbWVUZW5hbnQocHJpbmNpcGFsLnRlbmFudCwgdGVuYW50SWQpICYmXG4gICAgICAgIHByaW5jaXBhbC5raW5kID09PSBraW5kICYmXG4gICAgICAgIHByaW5jaXBhbC5zdWJqZWN0SWQgPT09IHN1YmplY3RJZFxuICAgICk7XG4gIH1cblxuICBhc3luYyBnZXRPckNyZWF0ZUZvclN1YmplY3QoXG4gICAgdGVuYW50SWQ6IHN0cmluZyxcbiAgICBraW5kOiBQcmluY2lwYWxLaW5kLFxuICAgIHN1YmplY3RJZDogc3RyaW5nLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8UHJpbmNpcGFsPiB7XG4gICAgcmV0dXJuIChhd2FpdCB0aGlzLmdldEZvclN1YmplY3QodGVuYW50SWQsIGtpbmQsIHN1YmplY3RJZCwgLi4uYXJncykpID8/IChhd2FpdCB0aGlzLmNyZWF0ZVByaW5jaXBhbCh0ZW5hbnRJZCwga2luZCwgc3ViamVjdElkLCAuLi5hcmdzKSk7XG4gIH1cblxuICBhc3luYyBnZXRVc2VyUHJpbmNpcGFsKHRlbmFudElkOiBzdHJpbmcsIHVzZXJJZDogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8UHJpbmNpcGFsPiB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0T3JDcmVhdGVGb3JTdWJqZWN0KHRlbmFudElkLCBQcmluY2lwYWxLaW5kLlVzZXIsIHVzZXJJZCwgLi4uYXJncyk7XG4gIH1cblxuICBhc3luYyBnZXRHcm91cFByaW5jaXBhbCh0ZW5hbnRJZDogc3RyaW5nLCBncm91cElkOiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxQcmluY2lwYWw+IHtcbiAgICByZXR1cm4gdGhpcy5nZXRPckNyZWF0ZUZvclN1YmplY3QodGVuYW50SWQsIFByaW5jaXBhbEtpbmQuR3JvdXAsIGdyb3VwSWQsIC4uLmFyZ3MpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBCYXNlTW9kZWxTZXJ2aWNlLCByZWxhdGlvbk1hdGNoLCBzYW1lVGVuYW50IH0gZnJvbSBcIi4uL3V0aWxzXCI7XG5pbXBvcnQgeyBNZW1iZXJzaGlwU3RhdHVzIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBUZW5hbnRNZW1iZXJzaGlwIH0gZnJvbSBcIi4uL21vZGVscy90ZW5hbnQtbWVtYmVyc2hpcC5tb2RlbFwiO1xuXG5leHBvcnQgY2xhc3MgVGVuYW50TWVtYmVyc2hpcFNlcnZpY2UgZXh0ZW5kcyBCYXNlTW9kZWxTZXJ2aWNlPFRlbmFudE1lbWJlcnNoaXA+IHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoVGVuYW50TWVtYmVyc2hpcCk7XG4gIH1cblxuICBhc3luYyBhZGRVc2VyVG9UZW5hbnQoXG4gICAgdGVuYW50SWQ6IHN0cmluZyxcbiAgICB1c2VySWQ6IHN0cmluZyxcbiAgICBzdGF0dXM6IE1lbWJlcnNoaXBTdGF0dXMgPSBNZW1iZXJzaGlwU3RhdHVzLkFjdGl2ZSxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPFRlbmFudE1lbWJlcnNoaXA+IHtcbiAgICByZXR1cm4gdGhpcy5jcmVhdGUoXG4gICAgICB7XG4gICAgICAgIHRlbmFudDogdGVuYW50SWQsXG4gICAgICAgIHVzZXI6IHVzZXJJZCxcbiAgICAgICAgc3RhdHVzLFxuICAgICAgfSxcbiAgICAgIC4uLmFyZ3NcbiAgICApO1xuICB9XG5cbiAgYXN5bmMgc2V0U3RhdHVzKG1lbWJlcnNoaXBJZDogc3RyaW5nLCBzdGF0dXM6IE1lbWJlcnNoaXBTdGF0dXMsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxUZW5hbnRNZW1iZXJzaGlwPiB7XG4gICAgcmV0dXJuIHRoaXMudXBkYXRlT25lKG1lbWJlcnNoaXBJZCwgeyBzdGF0dXMgfSwgLi4uYXJncyk7XG4gIH1cblxuICBhc3luYyBsaXN0VXNlclRlbmFudHModXNlcklkOiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxUZW5hbnRNZW1iZXJzaGlwW10+IHtcbiAgICByZXR1cm4gKGF3YWl0IHRoaXMubGlzdEFsbCguLi5hcmdzKSkuZmlsdGVyKChtZW1iZXJzaGlwKSA9PiByZWxhdGlvbk1hdGNoKG1lbWJlcnNoaXAudXNlciwgdXNlcklkKSk7XG4gIH1cblxuICBhc3luYyBsaXN0VGVuYW50VXNlcnModGVuYW50SWQ6IHN0cmluZywgLi4uYXJnczogYW55W10pOiBQcm9taXNlPFRlbmFudE1lbWJlcnNoaXBbXT4ge1xuICAgIHJldHVybiAoYXdhaXQgdGhpcy5saXN0QWxsKC4uLmFyZ3MpKS5maWx0ZXIoKG1lbWJlcnNoaXApID0+IHNhbWVUZW5hbnQobWVtYmVyc2hpcC50ZW5hbnQsIHRlbmFudElkKSk7XG4gIH1cblxuICBhc3luYyByZW1vdmVVc2VyRnJvbVRlbmFudChtZW1iZXJzaGlwSWQ6IHN0cmluZywgLi4uYXJnczogYW55W10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLmRlbGV0ZUJ5SWQobWVtYmVyc2hpcElkLCAuLi5hcmdzKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgQmFzZU1vZGVsU2VydmljZSwgcmVsYXRpb25NYXRjaCB9IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHsgTWVtYmVyc2hpcFN0YXR1cyB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgT3JnVW5pdE1lbWJlcnNoaXAgfSBmcm9tIFwiLi4vbW9kZWxzL29yZy11bml0LW1lbWJlcnNoaXAubW9kZWxcIjtcblxuZXhwb3J0IGNsYXNzIE9yZ1VuaXRNZW1iZXJzaGlwU2VydmljZSBleHRlbmRzIEJhc2VNb2RlbFNlcnZpY2U8T3JnVW5pdE1lbWJlcnNoaXA+IHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoT3JnVW5pdE1lbWJlcnNoaXApO1xuICB9XG5cbiAgYXN5bmMgYWRkVXNlclRvT3JnVW5pdChcbiAgICB0ZW5hbnRJZDogc3RyaW5nLFxuICAgIG9yZ1VuaXRJZDogc3RyaW5nLFxuICAgIHVzZXJJZDogc3RyaW5nLFxuICAgIHN0YXR1czogTWVtYmVyc2hpcFN0YXR1cyA9IE1lbWJlcnNoaXBTdGF0dXMuQWN0aXZlLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8T3JnVW5pdE1lbWJlcnNoaXA+IHtcbiAgICByZXR1cm4gdGhpcy5jcmVhdGUoXG4gICAgICB7XG4gICAgICAgIHRlbmFudDogdGVuYW50SWQsXG4gICAgICAgIG9yZ1VuaXQ6IG9yZ1VuaXRJZCxcbiAgICAgICAgdXNlcjogdXNlcklkLFxuICAgICAgICBzdGF0dXMsXG4gICAgICB9LFxuICAgICAgLi4uYXJnc1xuICAgICk7XG4gIH1cblxuICBhc3luYyBzZXRTdGF0dXMobWVtYmVyc2hpcElkOiBzdHJpbmcsIHN0YXR1czogTWVtYmVyc2hpcFN0YXR1cywgLi4uYXJnczogYW55W10pOiBQcm9taXNlPE9yZ1VuaXRNZW1iZXJzaGlwPiB7XG4gICAgcmV0dXJuIHRoaXMudXBkYXRlT25lKG1lbWJlcnNoaXBJZCwgeyBzdGF0dXMgfSwgLi4uYXJncyk7XG4gIH1cblxuICBhc3luYyBsaXN0VXNlck9yZ1VuaXRzKHVzZXJJZDogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8T3JnVW5pdE1lbWJlcnNoaXBbXT4ge1xuICAgIHJldHVybiAoYXdhaXQgdGhpcy5saXN0QWxsKC4uLmFyZ3MpKS5maWx0ZXIoKG1lbWJlcnNoaXApID0+IHJlbGF0aW9uTWF0Y2gobWVtYmVyc2hpcC51c2VyLCB1c2VySWQpKTtcbiAgfVxuXG4gIGFzeW5jIGxpc3RPcmdVbml0VXNlcnMob3JnVW5pdElkOiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxPcmdVbml0TWVtYmVyc2hpcFtdPiB7XG4gICAgcmV0dXJuIChhd2FpdCB0aGlzLmxpc3RBbGwoLi4uYXJncykpLmZpbHRlcigobWVtYmVyc2hpcCkgPT4gcmVsYXRpb25NYXRjaChtZW1iZXJzaGlwLm9yZ1VuaXQsIG9yZ1VuaXRJZCkpO1xuICB9XG5cbiAgYXN5bmMgcmVtb3ZlVXNlckZyb21PcmdVbml0KG1lbWJlcnNoaXBJZDogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMuZGVsZXRlQnlJZChtZW1iZXJzaGlwSWQsIC4uLmFyZ3MpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBCYXNlTW9kZWxTZXJ2aWNlLCBzYW1lVGVuYW50IH0gZnJvbSBcIi4uL3V0aWxzXCI7XG5pbXBvcnQgeyBHcm91cCB9IGZyb20gXCIuLi9tb2RlbHMvZ3JvdXAubW9kZWxcIjtcblxuZXhwb3J0IGNsYXNzIEdyb3VwU2VydmljZSBleHRlbmRzIEJhc2VNb2RlbFNlcnZpY2U8R3JvdXA+IHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoR3JvdXApO1xuICB9XG5cbiAgYXN5bmMgY3JlYXRlR3JvdXAoXG4gICAgdGVuYW50SWQ6IHN0cmluZyxcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgb3JnVW5pdElkPzogc3RyaW5nLFxuICAgIG1ldGFkYXRhPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxHcm91cD4ge1xuICAgIHJldHVybiB0aGlzLmNyZWF0ZShcbiAgICAgIHtcbiAgICAgICAgdGVuYW50OiB0ZW5hbnRJZCxcbiAgICAgICAgb3JnVW5pdDogb3JnVW5pdElkLFxuICAgICAgICBuYW1lLFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgIH0sXG4gICAgICAuLi5hcmdzXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIHJlbmFtZUdyb3VwKGdyb3VwSWQ6IHN0cmluZywgbmFtZTogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8R3JvdXA+IHtcbiAgICByZXR1cm4gdGhpcy51cGRhdGVPbmUoZ3JvdXBJZCwgeyBuYW1lIH0sIC4uLmFyZ3MpO1xuICB9XG5cbiAgYXN5bmMgbW92ZUdyb3VwVG9PcmdVbml0KGdyb3VwSWQ6IHN0cmluZywgb3JnVW5pdElkOiBzdHJpbmcgfCB1bmRlZmluZWQsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxHcm91cD4ge1xuICAgIHJldHVybiB0aGlzLnVwZGF0ZU9uZShncm91cElkLCB7IG9yZ1VuaXQ6IG9yZ1VuaXRJZCB9LCAuLi5hcmdzKTtcbiAgfVxuXG4gIGFzeW5jIGxpc3RUZW5hbnRHcm91cHModGVuYW50SWQ6IHN0cmluZywgLi4uYXJnczogYW55W10pOiBQcm9taXNlPEdyb3VwW10+IHtcbiAgICByZXR1cm4gKGF3YWl0IHRoaXMubGlzdEFsbCguLi5hcmdzKSkuZmlsdGVyKChncm91cCkgPT4gc2FtZVRlbmFudChncm91cC50ZW5hbnQsIHRlbmFudElkKSk7XG4gIH1cbn1cbiIsImltcG9ydCB7IEJhc2VNb2RlbFNlcnZpY2UsIHJlbGF0aW9uSWQsIHJlbGF0aW9uTWF0Y2ggfSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCB7IEdyb3VwTWVtYmVyc2hpcCB9IGZyb20gXCIuLi9tb2RlbHMvZ3JvdXAtbWVtYmVyc2hpcC5tb2RlbFwiO1xuaW1wb3J0IHsgUHJpbmNpcGFsU2VydmljZSB9IGZyb20gXCIuL3ByaW5jaXBhbC5zZXJ2aWNlXCI7XG5cbmV4cG9ydCBjbGFzcyBHcm91cE1lbWJlcnNoaXBTZXJ2aWNlIGV4dGVuZHMgQmFzZU1vZGVsU2VydmljZTxHcm91cE1lbWJlcnNoaXA+IHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoR3JvdXBNZW1iZXJzaGlwKTtcbiAgfVxuXG4gIGFzeW5jIGFkZFByaW5jaXBhbFRvR3JvdXAoXG4gICAgdGVuYW50SWQ6IHN0cmluZyxcbiAgICBncm91cElkOiBzdHJpbmcsXG4gICAgcHJpbmNpcGFsSWQ6IHN0cmluZyxcbiAgICBtZXRhZGF0YT86IFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8R3JvdXBNZW1iZXJzaGlwPiB7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlKFxuICAgICAge1xuICAgICAgICB0ZW5hbnQ6IHRlbmFudElkLFxuICAgICAgICBncm91cDogZ3JvdXBJZCxcbiAgICAgICAgcHJpbmNpcGFsOiBwcmluY2lwYWxJZCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICB9LFxuICAgICAgLi4uYXJnc1xuICAgICk7XG4gIH1cblxuICBhc3luYyBsaXN0R3JvdXBNZW1iZXJzKGdyb3VwSWQ6IHN0cmluZywgLi4uYXJnczogYW55W10pOiBQcm9taXNlPEdyb3VwTWVtYmVyc2hpcFtdPiB7XG4gICAgcmV0dXJuIChhd2FpdCB0aGlzLmxpc3RBbGwoLi4uYXJncykpLmZpbHRlcigobWVtYmVyc2hpcCkgPT4gcmVsYXRpb25NYXRjaChtZW1iZXJzaGlwLmdyb3VwLCBncm91cElkKSk7XG4gIH1cblxuICBhc3luYyBsaXN0UHJpbmNpcGFsR3JvdXBzKHByaW5jaXBhbElkOiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxHcm91cE1lbWJlcnNoaXBbXT4ge1xuICAgIHJldHVybiAoYXdhaXQgdGhpcy5saXN0QWxsKC4uLmFyZ3MpKS5maWx0ZXIoKG1lbWJlcnNoaXApID0+IHJlbGF0aW9uTWF0Y2gobWVtYmVyc2hpcC5wcmluY2lwYWwsIHByaW5jaXBhbElkKSk7XG4gIH1cblxuICBhc3luYyByZW1vdmVQcmluY2lwYWxGcm9tR3JvdXAobWVtYmVyc2hpcElkOiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5kZWxldGVCeUlkKG1lbWJlcnNoaXBJZCwgLi4uYXJncyk7XG4gIH1cblxuICBhc3luYyByZXNvbHZlR3JvdXBQcmluY2lwYWxJZHNGb3JQcmluY2lwYWwocHJpbmNpcGFsSWQ6IHN0cmluZywgLi4uYXJnczogYW55W10pOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgY29uc3QgcHJpbmNpcGFsU2VydmljZSA9IG5ldyBQcmluY2lwYWxTZXJ2aWNlKCk7XG4gICAgY29uc3QgbWVtYmVyc2hpcHMgPSBhd2FpdCB0aGlzLmxpc3RQcmluY2lwYWxHcm91cHMocHJpbmNpcGFsSWQsIC4uLmFyZ3MpO1xuICAgIGNvbnN0IHByaW5jaXBhbHMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIG1lbWJlcnNoaXBzLm1hcChhc3luYyAobWVtYmVyc2hpcCkgPT4ge1xuICAgICAgICBjb25zdCB0ZW5hbnRJZCA9IHJlbGF0aW9uSWQobWVtYmVyc2hpcC50ZW5hbnQpO1xuICAgICAgICBjb25zdCBncm91cElkID0gcmVsYXRpb25JZChtZW1iZXJzaGlwLmdyb3VwKTtcbiAgICAgICAgY29uc3QgcHJpbmNpcGFsID0gYXdhaXQgcHJpbmNpcGFsU2VydmljZS5nZXRHcm91cFByaW5jaXBhbCh0ZW5hbnRJZCwgZ3JvdXBJZCwgLi4uYXJncyk7XG4gICAgICAgIHJldHVybiBwcmluY2lwYWwuaWQ7XG4gICAgICB9KVxuICAgICk7XG4gICAgcmV0dXJuIHByaW5jaXBhbHM7XG4gIH1cbn1cbiIsImltcG9ydCB7IEJhc2VNb2RlbFNlcnZpY2UgfSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCB7IFBlcm1pc3Npb25DYXRlZ29yeSwgQ3JlYXRlUGVybWlzc2lvbklucHV0IH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBQZXJtaXNzaW9uIH0gZnJvbSBcIi4uL21vZGVscy9wZXJtaXNzaW9uLm1vZGVsXCI7XG5cbmV4cG9ydCBjbGFzcyBQZXJtaXNzaW9uU2VydmljZSBleHRlbmRzIEJhc2VNb2RlbFNlcnZpY2U8UGVybWlzc2lvbj4ge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcihQZXJtaXNzaW9uKTtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZVBlcm1pc3Npb24oaW5wdXQ6IENyZWF0ZVBlcm1pc3Npb25JbnB1dCwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPFBlcm1pc3Npb24+IHtcbiAgICByZXR1cm4gdGhpcy5jcmVhdGUoXG4gICAgICB7XG4gICAgICAgIGtleTogaW5wdXQua2V5LFxuICAgICAgICBjYXRlZ29yeTogaW5wdXQuY2F0ZWdvcnksXG4gICAgICAgIGRlc2NyaXB0aW9uOiBpbnB1dC5kZXNjcmlwdGlvbixcbiAgICAgIH0sXG4gICAgICAuLi5hcmdzXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIGdldEJ5S2V5KGtleTogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8UGVybWlzc2lvbj4ge1xuICAgIHJldHVybiAoYXdhaXQgdGhpcy5saXN0QWxsKC4uLmFyZ3MpKS5maW5kKChwZXJtaXNzaW9uKSA9PiBwZXJtaXNzaW9uLmtleSA9PT0ga2V5KSBhcyBQZXJtaXNzaW9uO1xuICB9XG5cbiAgYXN5bmMgbGlzdEJ5Q2F0ZWdvcnkoY2F0ZWdvcnk6IFBlcm1pc3Npb25DYXRlZ29yeSwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPFBlcm1pc3Npb25bXT4ge1xuICAgIHJldHVybiAoYXdhaXQgdGhpcy5saXN0QWxsKC4uLmFyZ3MpKS5maWx0ZXIoKHBlcm1pc3Npb24pID0+IHBlcm1pc3Npb24uY2F0ZWdvcnkgPT09IGNhdGVnb3J5KTtcbiAgfVxuXG4gIGFzeW5jIHVwZGF0ZURlc2NyaXB0aW9uKHBlcm1pc3Npb25JZDogc3RyaW5nLCBkZXNjcmlwdGlvbjogc3RyaW5nIHwgdW5kZWZpbmVkLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8UGVybWlzc2lvbj4ge1xuICAgIHJldHVybiB0aGlzLnVwZGF0ZU9uZShwZXJtaXNzaW9uSWQsIHsgZGVzY3JpcHRpb24gfSwgLi4uYXJncyk7XG4gIH1cbn1cbiIsImltcG9ydCB7IEJhc2VNb2RlbFNlcnZpY2UsIHNhbWVUZW5hbnQgfSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCB7IENyZWF0ZVJvbGVJbnB1dCB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgUm9sZSB9IGZyb20gXCIuLi9tb2RlbHMvcm9sZS5tb2RlbFwiO1xuXG5leHBvcnQgY2xhc3MgUm9sZVNlcnZpY2UgZXh0ZW5kcyBCYXNlTW9kZWxTZXJ2aWNlPFJvbGU+IHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoUm9sZSk7XG4gIH1cblxuICBhc3luYyBjcmVhdGVSb2xlKGlucHV0OiBDcmVhdGVSb2xlSW5wdXQsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxSb2xlPiB7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlKFxuICAgICAge1xuICAgICAgICB0ZW5hbnQ6IGlucHV0LnRlbmFudElkLFxuICAgICAgICBrZXk6IGlucHV0LmtleSxcbiAgICAgICAgbmFtZTogaW5wdXQubmFtZSxcbiAgICAgICAgZGVzY3JpcHRpb246IGlucHV0LmRlc2NyaXB0aW9uLFxuICAgICAgICBtZXRhZGF0YTogaW5wdXQubWV0YWRhdGEsXG4gICAgICB9LFxuICAgICAgLi4uYXJnc1xuICAgICk7XG4gIH1cblxuICBhc3luYyBnZXRTeXN0ZW1Sb2xlQnlLZXkoa2V5OiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxSb2xlPiB7XG4gICAgY29uc3Qgcm9sZSA9IChhd2FpdCB0aGlzLmxpc3RBbGwoLi4uYXJncykpLmZpbmQoKGNhbmRpZGF0ZSkgPT4gIWNhbmRpZGF0ZS50ZW5hbnQgJiYgY2FuZGlkYXRlLmtleSA9PT0ga2V5KTtcbiAgICBpZiAoIXJvbGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgUm9sZSBcIiR7a2V5fVwiIG5vdCBmb3VuZGApO1xuICAgIH1cbiAgICByZXR1cm4gcm9sZTtcbiAgfVxuXG4gIGFzeW5jIGdldFRlbmFudFJvbGVCeUtleSh0ZW5hbnRJZDogc3RyaW5nLCBrZXk6IHN0cmluZywgLi4uYXJnczogYW55W10pOiBQcm9taXNlPFJvbGU+IHtcbiAgICBjb25zdCByb2xlID0gKGF3YWl0IHRoaXMubGlzdEFsbCguLi5hcmdzKSkuZmluZChcbiAgICAgIChjYW5kaWRhdGUpID0+IHNhbWVUZW5hbnQoY2FuZGlkYXRlLnRlbmFudCwgdGVuYW50SWQpICYmIGNhbmRpZGF0ZS5rZXkgPT09IGtleVxuICAgICk7XG4gICAgaWYgKCFyb2xlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFJvbGUgXCIke2tleX1cIiBub3QgZm91bmQgZm9yIHRlbmFudCAke3RlbmFudElkfWApO1xuICAgIH1cbiAgICByZXR1cm4gcm9sZTtcbiAgfVxuXG4gIGFzeW5jIHJlbmFtZVJvbGUocm9sZUlkOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgLi4uYXJnczogYW55W10pOiBQcm9taXNlPFJvbGU+IHtcbiAgICByZXR1cm4gdGhpcy51cGRhdGVPbmUocm9sZUlkLCB7IG5hbWUgfSwgLi4uYXJncyk7XG4gIH1cblxuICBhc3luYyB1cGRhdGVSb2xlTWV0YWRhdGEoXG4gICAgcm9sZUlkOiBzdHJpbmcsXG4gICAgbWV0YWRhdGE6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgdW5kZWZpbmVkLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8Um9sZT4ge1xuICAgIHJldHVybiB0aGlzLnVwZGF0ZU9uZShyb2xlSWQsIHsgbWV0YWRhdGEgfSwgLi4uYXJncyk7XG4gIH1cblxuICBhc3luYyBsaXN0VGVuYW50Um9sZXModGVuYW50SWQ6IHN0cmluZywgaW5jbHVkZVN5c3RlbSA9IGZhbHNlLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8Um9sZVtdPiB7XG4gICAgcmV0dXJuIChhd2FpdCB0aGlzLmxpc3RBbGwoLi4uYXJncykpLmZpbHRlcigocm9sZSkgPT5cbiAgICAgIGluY2x1ZGVTeXN0ZW0gPyAhcm9sZS50ZW5hbnQgfHwgc2FtZVRlbmFudChyb2xlLnRlbmFudCwgdGVuYW50SWQpIDogc2FtZVRlbmFudChyb2xlLnRlbmFudCwgdGVuYW50SWQpXG4gICAgKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgQmFzZU1vZGVsU2VydmljZSwgcmVsYXRpb25NYXRjaCB9IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHsgUm9sZVBlcm1pc3Npb24gfSBmcm9tIFwiLi4vbW9kZWxzL3JvbGUtcGVybWlzc2lvbi5tb2RlbFwiO1xuaW1wb3J0IHsgUGVybWlzc2lvblNlcnZpY2UgfSBmcm9tIFwiLi9wZXJtaXNzaW9uLnNlcnZpY2VcIjtcbmltcG9ydCB7IFJvbGVTZXJ2aWNlIH0gZnJvbSBcIi4vcm9sZS5zZXJ2aWNlXCI7XG5cbmFzeW5jIGZ1bmN0aW9uIGRlbGV0ZVJvd3NCeUlkKFxuICBzZXJ2aWNlOiBCYXNlTW9kZWxTZXJ2aWNlPGFueT4sXG4gIHJvd3M6IEFycmF5PHsgaWQ6IHN0cmluZyB9PixcbiAgLi4uYXJnczogYW55W11cbik6IFByb21pc2U8dm9pZD4ge1xuICBmb3IgKGNvbnN0IHJvdyBvZiByb3dzKSB7XG4gICAgYXdhaXQgc2VydmljZS5kZWxldGVCeUlkKHJvdy5pZCwgLi4uYXJncyk7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFJvbGVQZXJtaXNzaW9uU2VydmljZSBleHRlbmRzIEJhc2VNb2RlbFNlcnZpY2U8Um9sZVBlcm1pc3Npb24+IHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoUm9sZVBlcm1pc3Npb24pO1xuICB9XG5cbiAgYXN5bmMgYWRkUGVybWlzc2lvblRvUm9sZShyb2xlSWQ6IHN0cmluZywgcGVybWlzc2lvbklkOiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxSb2xlUGVybWlzc2lvbj4ge1xuICAgIHJldHVybiB0aGlzLmNyZWF0ZShcbiAgICAgIHtcbiAgICAgICAgcm9sZTogcm9sZUlkLFxuICAgICAgICBwZXJtaXNzaW9uOiBwZXJtaXNzaW9uSWQsXG4gICAgICB9LFxuICAgICAgLi4uYXJnc1xuICAgICk7XG4gIH1cblxuICBhc3luYyBhZGRQZXJtaXNzaW9uS2V5VG9Sb2xlKHJvbGVJZDogc3RyaW5nLCBwZXJtaXNzaW9uS2V5OiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxSb2xlUGVybWlzc2lvbj4ge1xuICAgIGNvbnN0IHBlcm1pc3Npb24gPSBhd2FpdCBuZXcgUGVybWlzc2lvblNlcnZpY2UoKS5nZXRCeUtleShwZXJtaXNzaW9uS2V5LCAuLi5hcmdzKTtcbiAgICByZXR1cm4gdGhpcy5hZGRQZXJtaXNzaW9uVG9Sb2xlKHJvbGVJZCwgcGVybWlzc2lvbi5pZCwgLi4uYXJncyk7XG4gIH1cblxuICBhc3luYyByZW1vdmVQZXJtaXNzaW9uRnJvbVJvbGUocm9sZVBlcm1pc3Npb25JZDogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMuZGVsZXRlQnlJZChyb2xlUGVybWlzc2lvbklkLCAuLi5hcmdzKTtcbiAgfVxuXG4gIGFzeW5jIGxpc3RSb2xlUGVybWlzc2lvbnMocm9sZUlkOiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxSb2xlUGVybWlzc2lvbltdPiB7XG4gICAgcmV0dXJuIChhd2FpdCB0aGlzLmxpc3RBbGwoLi4uYXJncykpLmZpbHRlcigocm9sZVBlcm1pc3Npb24pID0+IHJlbGF0aW9uTWF0Y2gocm9sZVBlcm1pc3Npb24ucm9sZSwgcm9sZUlkKSk7XG4gIH1cblxuICBhc3luYyBsaXN0UGVybWlzc2lvblJvbGVzKHBlcm1pc3Npb25JZDogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8Um9sZVBlcm1pc3Npb25bXT4ge1xuICAgIHJldHVybiAoYXdhaXQgdGhpcy5saXN0QWxsKC4uLmFyZ3MpKS5maWx0ZXIoKHJvbGVQZXJtaXNzaW9uKSA9PiByZWxhdGlvbk1hdGNoKHJvbGVQZXJtaXNzaW9uLnBlcm1pc3Npb24sIHBlcm1pc3Npb25JZCkpO1xuICB9XG5cbiAgYXN5bmMgcmVwbGFjZVJvbGVQZXJtaXNzaW9ucyhyb2xlSWQ6IHN0cmluZywgcGVybWlzc2lvbklkczogc3RyaW5nW10sIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxSb2xlUGVybWlzc2lvbltdPiB7XG4gICAgY29uc3QgZXhpc3RpbmcgPSBhd2FpdCB0aGlzLmxpc3RSb2xlUGVybWlzc2lvbnMocm9sZUlkLCAuLi5hcmdzKTtcbiAgICBhd2FpdCBkZWxldGVSb3dzQnlJZCh0aGlzLCBleGlzdGluZywgLi4uYXJncyk7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKHBlcm1pc3Npb25JZHMubWFwKChwZXJtaXNzaW9uSWQpID0+IHRoaXMuYWRkUGVybWlzc2lvblRvUm9sZShyb2xlSWQsIHBlcm1pc3Npb25JZCwgLi4uYXJncykpKTtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZVJvbGVXaXRoUGVybWlzc2lvbnMoXG4gICAgaW5wdXQ6IGltcG9ydChcIi4uL3R5cGVzXCIpLkNyZWF0ZVJvbGVJbnB1dCxcbiAgICBwZXJtaXNzaW9uS2V5czogc3RyaW5nW10sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxpbXBvcnQoXCIuLi9tb2RlbHMvcm9sZS5tb2RlbFwiKS5Sb2xlPiB7XG4gICAgY29uc3Qgcm9sZSA9IGF3YWl0IG5ldyBSb2xlU2VydmljZSgpLmNyZWF0ZVJvbGUoaW5wdXQsIC4uLmFyZ3MpO1xuICAgIGZvciAoY29uc3QgcGVybWlzc2lvbktleSBvZiBwZXJtaXNzaW9uS2V5cykge1xuICAgICAgYXdhaXQgdGhpcy5hZGRQZXJtaXNzaW9uS2V5VG9Sb2xlKHJvbGUuaWQsIHBlcm1pc3Npb25LZXksIC4uLmFyZ3MpO1xuICAgIH1cbiAgICByZXR1cm4gcm9sZTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgQmFzZU1vZGVsU2VydmljZSwgcmVsYXRpb25NYXRjaCwgc2FtZVRlbmFudCB9IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHsgQXNzaWduUm9sZUlucHV0IH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBSb2xlQXNzaWdubWVudCB9IGZyb20gXCIuLi9tb2RlbHMvcm9sZS1hc3NpZ25tZW50Lm1vZGVsXCI7XG5cbmV4cG9ydCBjbGFzcyBSb2xlQXNzaWdubWVudFNlcnZpY2UgZXh0ZW5kcyBCYXNlTW9kZWxTZXJ2aWNlPFJvbGVBc3NpZ25tZW50PiB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKFJvbGVBc3NpZ25tZW50KTtcbiAgfVxuXG4gIGFzeW5jIGFzc2lnblJvbGUoXG4gICAgaW5wdXQ6IEFzc2lnblJvbGVJbnB1dCxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPFJvbGVBc3NpZ25tZW50PiB7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlKFxuICAgICAge1xuICAgICAgICB0ZW5hbnQ6IGlucHV0LnRlbmFudElkLFxuICAgICAgICBwcmluY2lwYWw6IGlucHV0LnByaW5jaXBhbElkLFxuICAgICAgICByb2xlOiBpbnB1dC5yb2xlSWQsXG4gICAgICAgIHNjb3BlS2luZDogaW5wdXQuc2NvcGVLaW5kLFxuICAgICAgICBzY29wZUlkOiBpbnB1dC5zY29wZUlkLFxuICAgICAgICBpbmhlcml0RG93bjogaW5wdXQuaW5oZXJpdERvd24gPz8gZmFsc2UsXG4gICAgICAgIHN0YXJ0c0F0OiBpbnB1dC5zdGFydHNBdCxcbiAgICAgICAgZXhwaXJlc0F0OiBpbnB1dC5leHBpcmVzQXQsXG4gICAgICAgIGNvbmRpdGlvbnM6IGlucHV0LmNvbmRpdGlvbnMsXG4gICAgICB9LFxuICAgICAgLi4uYXJnc1xuICAgICk7XG4gIH1cblxuICBhc3luYyByZXZva2VBc3NpZ25tZW50KGFzc2lnbm1lbnRJZDogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMuZGVsZXRlQnlJZChhc3NpZ25tZW50SWQsIC4uLmFyZ3MpO1xuICB9XG5cbiAgYXN5bmMgbGlzdFByaW5jaXBhbEFzc2lnbm1lbnRzKFxuICAgIHRlbmFudElkOiBzdHJpbmcsXG4gICAgcHJpbmNpcGFsSWQ6IHN0cmluZyxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPFJvbGVBc3NpZ25tZW50W10+IHtcbiAgICByZXR1cm4gKGF3YWl0IHRoaXMubGlzdEFsbCguLi5hcmdzKSkuZmlsdGVyKFxuICAgICAgKGFzc2lnbm1lbnQpID0+XG4gICAgICAgIHNhbWVUZW5hbnQoYXNzaWdubWVudC50ZW5hbnQsIHRlbmFudElkKSAmJlxuICAgICAgICByZWxhdGlvbk1hdGNoKGFzc2lnbm1lbnQucHJpbmNpcGFsLCBwcmluY2lwYWxJZClcbiAgICApO1xuICB9XG5cbiAgYXN5bmMgbGlzdFJvbGVBc3NpZ25tZW50cyhcbiAgICByb2xlSWQ6IHN0cmluZyxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPFJvbGVBc3NpZ25tZW50W10+IHtcbiAgICByZXR1cm4gKGF3YWl0IHRoaXMubGlzdEFsbCguLi5hcmdzKSkuZmlsdGVyKChhc3NpZ25tZW50KSA9PlxuICAgICAgcmVsYXRpb25NYXRjaChhc3NpZ25tZW50LnJvbGUsIHJvbGVJZClcbiAgICApO1xuICB9XG5cbiAgYXN5bmMgbGlzdFRlbmFudEFzc2lnbm1lbnRzKFxuICAgIHRlbmFudElkOiBzdHJpbmcsXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxSb2xlQXNzaWdubWVudFtdPiB7XG4gICAgcmV0dXJuIChhd2FpdCB0aGlzLmxpc3RBbGwoLi4uYXJncykpLmZpbHRlcigoYXNzaWdubWVudCkgPT5cbiAgICAgIHNhbWVUZW5hbnQoYXNzaWdubWVudC50ZW5hbnQsIHRlbmFudElkKVxuICAgICk7XG4gIH1cblxuICBhc3luYyB1cGRhdGVBc3NpZ25tZW50V2luZG93KFxuICAgIGFzc2lnbm1lbnRJZDogc3RyaW5nLFxuICAgIHN0YXJ0c0F0OiBEYXRlIHwgdW5kZWZpbmVkLFxuICAgIGV4cGlyZXNBdDogRGF0ZSB8IHVuZGVmaW5lZCxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPFJvbGVBc3NpZ25tZW50PiB7XG4gICAgcmV0dXJuIHRoaXMudXBkYXRlT25lKGFzc2lnbm1lbnRJZCwgeyBzdGFydHNBdCwgZXhwaXJlc0F0IH0sIC4uLmFyZ3MpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBCYXNlTW9kZWxTZXJ2aWNlLCByZWxhdGlvbklkLCByZWxhdGlvbk1hdGNoLCBzYW1lVGVuYW50LCB0cmFuc2FjdGlvbmFsIH0gZnJvbSBcIi4uL3V0aWxzXCI7XG5pbXBvcnQgeyBFZmZlY3RpdmVQZXJtaXNzaW9uU25hcHNob3QsIFNjb3BlS2luZCB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgRWZmZWN0aXZlUGVybWlzc2lvbiB9IGZyb20gXCIuLi9tb2RlbHMvZWZmZWN0aXZlLXBlcm1pc3Npb24ubW9kZWxcIjtcbmltcG9ydCB7IFJvbGVBc3NpZ25tZW50U2VydmljZSB9IGZyb20gXCIuL3JvbGUtYXNzaWdubWVudC5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBSb2xlUGVybWlzc2lvblNlcnZpY2UgfSBmcm9tIFwiLi9yb2xlLXBlcm1pc3Npb24uc2VydmljZVwiO1xuaW1wb3J0IHsgUGVybWlzc2lvblNlcnZpY2UgfSBmcm9tIFwiLi9wZXJtaXNzaW9uLnNlcnZpY2VcIjtcbmltcG9ydCB7IEdyb3VwTWVtYmVyc2hpcFNlcnZpY2UgfSBmcm9tIFwiLi9ncm91cC1tZW1iZXJzaGlwLnNlcnZpY2VcIjtcbmltcG9ydCB7IFByaW5jaXBhbFNlcnZpY2UgfSBmcm9tIFwiLi9wcmluY2lwYWwuc2VydmljZVwiO1xuaW1wb3J0IHsgT3JnVW5pdENsb3N1cmVTZXJ2aWNlIH0gZnJvbSBcIi4vb3JnLXVuaXQtY2xvc3VyZS5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBJbmhlcml0YW5jZUJsb2NrU2VydmljZSB9IGZyb20gXCIuL2luaGVyaXRhbmNlLWJsb2NrLnNlcnZpY2VcIjtcblxuZXhwb3J0IGNsYXNzIEVmZmVjdGl2ZVBlcm1pc3Npb25TZXJ2aWNlIGV4dGVuZHMgQmFzZU1vZGVsU2VydmljZTxFZmZlY3RpdmVQZXJtaXNzaW9uPiB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKEVmZmVjdGl2ZVBlcm1pc3Npb24pO1xuICB9XG5cbiAgYXN5bmMgbGlzdEZvclByaW5jaXBhbCh0ZW5hbnRJZDogc3RyaW5nLCBwcmluY2lwYWxJZDogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8RWZmZWN0aXZlUGVybWlzc2lvbltdPiB7XG4gICAgcmV0dXJuIChhd2FpdCB0aGlzLmxpc3RBbGwoLi4uYXJncykpLmZpbHRlcihcbiAgICAgIChwZXJtaXNzaW9uKSA9PiBzYW1lVGVuYW50KHBlcm1pc3Npb24udGVuYW50LCB0ZW5hbnRJZCkgJiYgcmVsYXRpb25NYXRjaChwZXJtaXNzaW9uLnByaW5jaXBhbCwgcHJpbmNpcGFsSWQpXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIGxpc3RGb3JTY29wZShcbiAgICB0ZW5hbnRJZDogc3RyaW5nLFxuICAgIHNjb3BlS2luZDogU2NvcGVLaW5kLFxuICAgIHNjb3BlSWQ6IHN0cmluZyxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPEVmZmVjdGl2ZVBlcm1pc3Npb25bXT4ge1xuICAgIHJldHVybiAoYXdhaXQgdGhpcy5saXN0QWxsKC4uLmFyZ3MpKS5maWx0ZXIoXG4gICAgICAocGVybWlzc2lvbikgPT4gc2FtZVRlbmFudChwZXJtaXNzaW9uLnRlbmFudCwgdGVuYW50SWQpICYmIHBlcm1pc3Npb24uc2NvcGVLaW5kID09PSBzY29wZUtpbmQgJiYgcGVybWlzc2lvbi5zY29wZUlkID09PSBzY29wZUlkXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIGhhc1Blcm1pc3Npb24oXG4gICAgdGVuYW50SWQ6IHN0cmluZyxcbiAgICBwcmluY2lwYWxJZDogc3RyaW5nLFxuICAgIHBlcm1pc3Npb25LZXk6IHN0cmluZyxcbiAgICBzY29wZUtpbmQ6IFNjb3BlS2luZCxcbiAgICBzY29wZUlkOiBzdHJpbmcsXG4gICAgYXQ/OiBEYXRlLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIHJldHVybiAoYXdhaXQgdGhpcy5saXN0Rm9yUHJpbmNpcGFsKHRlbmFudElkLCBwcmluY2lwYWxJZCwgLi4uYXJncykpLnNvbWUoXG4gICAgICAocGVybWlzc2lvbikgPT5cbiAgICAgICAgcGVybWlzc2lvbi5wZXJtaXNzaW9uS2V5ID09PSBwZXJtaXNzaW9uS2V5ICYmXG4gICAgICAgIHBlcm1pc3Npb24uc2NvcGVLaW5kID09PSBzY29wZUtpbmQgJiZcbiAgICAgICAgcGVybWlzc2lvbi5zY29wZUlkID09PSBzY29wZUlkICYmXG4gICAgICAgICghcGVybWlzc2lvbi5zdGFydHNBdCB8fCAhYXQgfHwgcGVybWlzc2lvbi5zdGFydHNBdCA8PSBhdCkgJiZcbiAgICAgICAgKCFwZXJtaXNzaW9uLmV4cGlyZXNBdCB8fCAhYXQgfHwgcGVybWlzc2lvbi5leHBpcmVzQXQgPj0gYXQpXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIGRlbGV0ZUZvclByaW5jaXBhbCh0ZW5hbnRJZDogc3RyaW5nLCBwcmluY2lwYWxJZDogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGZvciAoY29uc3Qgcm93IG9mIGF3YWl0IHRoaXMubGlzdEZvclByaW5jaXBhbCh0ZW5hbnRJZCwgcHJpbmNpcGFsSWQsIC4uLmFyZ3MpKSB7XG4gICAgICBhd2FpdCB0aGlzLmRlbGV0ZUJ5SWQocm93LmlkLCAuLi5hcmdzKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBkZWxldGVGb3JUZW5hbnQodGVuYW50SWQ6IHN0cmluZywgLi4uYXJnczogYW55W10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBmb3IgKGNvbnN0IHJvdyBvZiAoYXdhaXQgdGhpcy5saXN0QWxsKC4uLmFyZ3MpKS5maWx0ZXIoKHBlcm1pc3Npb24pID0+IHNhbWVUZW5hbnQocGVybWlzc2lvbi50ZW5hbnQsIHRlbmFudElkKSkpIHtcbiAgICAgIGF3YWl0IHRoaXMuZGVsZXRlQnlJZChyb3cuaWQsIC4uLmFyZ3MpO1xuICAgIH1cbiAgfVxuXG4gIEB0cmFuc2FjdGlvbmFsKClcbiAgYXN5bmMgcmVidWlsZEZvclByaW5jaXBhbCh0ZW5hbnRJZDogc3RyaW5nLCBwcmluY2lwYWxJZDogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8RWZmZWN0aXZlUGVybWlzc2lvbltdPiB7XG4gICAgYXdhaXQgdGhpcy5kZWxldGVGb3JQcmluY2lwYWwodGVuYW50SWQsIHByaW5jaXBhbElkLCAuLi5hcmdzKTtcblxuICAgIGNvbnN0IHJvbGVBc3NpZ25tZW50U2VydmljZSA9IG5ldyBSb2xlQXNzaWdubWVudFNlcnZpY2UoKTtcbiAgICBjb25zdCByb2xlUGVybWlzc2lvblNlcnZpY2UgPSBuZXcgUm9sZVBlcm1pc3Npb25TZXJ2aWNlKCk7XG4gICAgY29uc3QgcGVybWlzc2lvblNlcnZpY2UgPSBuZXcgUGVybWlzc2lvblNlcnZpY2UoKTtcbiAgICBjb25zdCBncm91cE1lbWJlcnNoaXBTZXJ2aWNlID0gbmV3IEdyb3VwTWVtYmVyc2hpcFNlcnZpY2UoKTtcbiAgICBjb25zdCBwcmluY2lwYWxTZXJ2aWNlID0gbmV3IFByaW5jaXBhbFNlcnZpY2UoKTtcbiAgICBjb25zdCBvcmdVbml0Q2xvc3VyZVNlcnZpY2UgPSBuZXcgT3JnVW5pdENsb3N1cmVTZXJ2aWNlKCk7XG4gICAgY29uc3QgaW5oZXJpdGFuY2VCbG9ja1NlcnZpY2UgPSBuZXcgSW5oZXJpdGFuY2VCbG9ja1NlcnZpY2UoKTtcblxuICAgIGNvbnN0IG1hdGVyaWFsaXplZDogRWZmZWN0aXZlUGVybWlzc2lvblNuYXBzaG90W10gPSBbXTtcbiAgICBjb25zdCBzb3VyY2VBc3NpZ25tZW50cyA9IGF3YWl0IHJvbGVBc3NpZ25tZW50U2VydmljZS5saXN0UHJpbmNpcGFsQXNzaWdubWVudHModGVuYW50SWQsIHByaW5jaXBhbElkLCAuLi5hcmdzKTtcbiAgICBjb25zdCBncm91cE1lbWJlcnNoaXBzID0gYXdhaXQgZ3JvdXBNZW1iZXJzaGlwU2VydmljZS5saXN0UHJpbmNpcGFsR3JvdXBzKHByaW5jaXBhbElkLCAuLi5hcmdzKTtcbiAgICBjb25zdCBncm91cEFzc2lnbm1lbnRzID0gKFxuICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgIGdyb3VwTWVtYmVyc2hpcHMubWFwKGFzeW5jIChtZW1iZXJzaGlwKSA9PiB7XG4gICAgICAgICAgY29uc3QgZ3JvdXBQcmluY2lwYWwgPSBhd2FpdCBwcmluY2lwYWxTZXJ2aWNlLmdldEdyb3VwUHJpbmNpcGFsKHJlbGF0aW9uSWQobWVtYmVyc2hpcC50ZW5hbnQpLCByZWxhdGlvbklkKG1lbWJlcnNoaXAuZ3JvdXApLCAuLi5hcmdzKTtcbiAgICAgICAgICByZXR1cm4gcm9sZUFzc2lnbm1lbnRTZXJ2aWNlLmxpc3RQcmluY2lwYWxBc3NpZ25tZW50cyh0ZW5hbnRJZCwgZ3JvdXBQcmluY2lwYWwuaWQsIC4uLmFyZ3MpO1xuICAgICAgICB9KVxuICAgICAgKVxuICAgICkuZmxhdCgpO1xuXG4gICAgY29uc3QgYXNzaWdubWVudHMgPSBbLi4uc291cmNlQXNzaWdubWVudHMsIC4uLmdyb3VwQXNzaWdubWVudHNdO1xuICAgIGZvciAoY29uc3QgYXNzaWdubWVudCBvZiBhc3NpZ25tZW50cykge1xuICAgICAgY29uc3Qgcm9sZVBlcm1pc3Npb25zID0gYXdhaXQgcm9sZVBlcm1pc3Npb25TZXJ2aWNlLmxpc3RSb2xlUGVybWlzc2lvbnMocmVsYXRpb25JZChhc3NpZ25tZW50LnJvbGUpLCAuLi5hcmdzKTtcbiAgICAgIGNvbnN0IHBlcm1pc3Npb25zID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgIHJvbGVQZXJtaXNzaW9ucy5tYXAoYXN5bmMgKHJvbGVQZXJtaXNzaW9uKSA9PlxuICAgICAgICAgIHBlcm1pc3Npb25TZXJ2aWNlLmZpbmRPbmVCeShcImlkXCIsIHJlbGF0aW9uSWQocm9sZVBlcm1pc3Npb24ucGVybWlzc2lvbikgYXMgbmV2ZXIsIC4uLmFyZ3MpXG4gICAgICAgIClcbiAgICAgICk7XG4gICAgICBmb3IgKGNvbnN0IHBlcm1pc3Npb24gb2YgcGVybWlzc2lvbnMpIHtcbiAgICAgICAgaWYgKCFwZXJtaXNzaW9uKSBjb250aW51ZTtcbiAgICAgICAgY29uc3Qgc2NvcGVLaW5kID0gYXNzaWdubWVudC5zY29wZUtpbmQ7XG4gICAgICAgIGNvbnN0IHNjb3BlSWQgPSBhc3NpZ25tZW50LnNjb3BlSWQ7XG4gICAgICAgIGNvbnN0IHNjb3BlczogQXJyYXk8eyBzY29wZUtpbmQ6IFNjb3BlS2luZDsgc2NvcGVJZDogc3RyaW5nIH0+ID0gW107XG4gICAgICAgIGlmIChzY29wZUtpbmQgPT09IFNjb3BlS2luZC5UZW5hbnQpIHtcbiAgICAgICAgICBzY29wZXMucHVzaCh7IHNjb3BlS2luZCwgc2NvcGVJZDogdGVuYW50SWQgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoc2NvcGVLaW5kID09PSBTY29wZUtpbmQuUmVzb3VyY2UpIHtcbiAgICAgICAgICBzY29wZXMucHVzaCh7IHNjb3BlS2luZCwgc2NvcGVJZCB9KTtcbiAgICAgICAgfSBlbHNlIGlmIChzY29wZUtpbmQgPT09IFNjb3BlS2luZC5PcmdVbml0ICYmICFhc3NpZ25tZW50LmluaGVyaXREb3duKSB7XG4gICAgICAgICAgc2NvcGVzLnB1c2goeyBzY29wZUtpbmQsIHNjb3BlSWQgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoc2NvcGVLaW5kID09PSBTY29wZUtpbmQuT3JnVW5pdCAmJiBhc3NpZ25tZW50LmluaGVyaXREb3duKSB7XG4gICAgICAgICAgY29uc3QgZGVzY2VuZGFudHMgPSBhd2FpdCBvcmdVbml0Q2xvc3VyZVNlcnZpY2UubGlzdERlc2NlbmRhbnRzKHRlbmFudElkLCBzY29wZUlkLCAuLi5hcmdzKTtcbiAgICAgICAgICBzY29wZXMucHVzaCguLi5kZXNjZW5kYW50cy5tYXAoKHJvdykgPT4gKHsgc2NvcGVLaW5kLCBzY29wZUlkOiByZWxhdGlvbklkKHJvdy5kZXNjZW5kYW50KSB9KSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChjb25zdCBzY29wZWQgb2Ygc2NvcGVzKSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgc2NvcGVLaW5kID09PSBTY29wZUtpbmQuT3JnVW5pdCAmJlxuICAgICAgICAgICAgYXNzaWdubWVudC5pbmhlcml0RG93biAmJlxuICAgICAgICAgICAgc2NvcGVkLnNjb3BlSWQgIT09IHNjb3BlSWQgJiZcbiAgICAgICAgICAgIChhd2FpdCBpbmhlcml0YW5jZUJsb2NrU2VydmljZS5jYXRlZ29yeUJsb2NrZWRGb3JBbmNlc3RvcihcbiAgICAgICAgICAgICAgdGVuYW50SWQsXG4gICAgICAgICAgICAgIHNjb3BlZC5zY29wZUlkLFxuICAgICAgICAgICAgICBzY29wZUlkLFxuICAgICAgICAgICAgICBwZXJtaXNzaW9uLmNhdGVnb3J5LFxuICAgICAgICAgICAgICAuLi5hcmdzXG4gICAgICAgICAgICApKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIG1hdGVyaWFsaXplZC5wdXNoKHtcbiAgICAgICAgICAgIGlkOiBcIlwiLFxuICAgICAgICAgICAgdGVuYW50SWQsXG4gICAgICAgICAgICBwcmluY2lwYWxJZCxcbiAgICAgICAgICAgIHBlcm1pc3Npb25LZXk6IHBlcm1pc3Npb24ua2V5LFxuICAgICAgICAgICAgc2NvcGVLaW5kOiBzY29wZWQuc2NvcGVLaW5kLFxuICAgICAgICAgICAgc2NvcGVJZDogc2NvcGVkLnNjb3BlSWQsXG4gICAgICAgICAgICBzb3VyY2VLaW5kOiBcInJvbGVfYXNzaWdubWVudFwiLFxuICAgICAgICAgICAgc291cmNlSWQ6IGFzc2lnbm1lbnQuaWQsXG4gICAgICAgICAgICBzdGFydHNBdDogYXNzaWdubWVudC5zdGFydHNBdCxcbiAgICAgICAgICAgIGV4cGlyZXNBdDogYXNzaWdubWVudC5leHBpcmVzQXQsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBjcmVhdGVkID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBtYXRlcmlhbGl6ZWQubWFwKChwZXJtaXNzaW9uKSA9PlxuICAgICAgICB0aGlzLmNyZWF0ZShcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0ZW5hbnQ6IHBlcm1pc3Npb24udGVuYW50SWQsXG4gICAgICAgICAgICBwcmluY2lwYWw6IHBlcm1pc3Npb24ucHJpbmNpcGFsSWQsXG4gICAgICAgICAgICBwZXJtaXNzaW9uS2V5OiBwZXJtaXNzaW9uLnBlcm1pc3Npb25LZXksXG4gICAgICAgICAgICBzY29wZUtpbmQ6IHBlcm1pc3Npb24uc2NvcGVLaW5kLFxuICAgICAgICAgICAgc2NvcGVJZDogcGVybWlzc2lvbi5zY29wZUlkLFxuICAgICAgICAgICAgc291cmNlS2luZDogcGVybWlzc2lvbi5zb3VyY2VLaW5kLFxuICAgICAgICAgICAgc291cmNlSWQ6IHBlcm1pc3Npb24uc291cmNlSWQsXG4gICAgICAgICAgICBzdGFydHNBdDogcGVybWlzc2lvbi5zdGFydHNBdCxcbiAgICAgICAgICAgIGV4cGlyZXNBdDogcGVybWlzc2lvbi5leHBpcmVzQXQsXG4gICAgICAgICAgfSxcbiAgICAgICAgICAuLi5hcmdzXG4gICAgICAgIClcbiAgICAgIClcbiAgICApO1xuICAgIHJldHVybiBjcmVhdGVkO1xuICB9XG5cbiAgQHRyYW5zYWN0aW9uYWwoKVxuICBhc3luYyByZWJ1aWxkRm9yVGVuYW50KHRlbmFudElkOiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcHJpbmNpcGFscyA9IChhd2FpdCBuZXcgUHJpbmNpcGFsU2VydmljZSgpLmxpc3RBbGwoLi4uYXJncykpLmZpbHRlcigocHJpbmNpcGFsKSA9PiBzYW1lVGVuYW50KHByaW5jaXBhbC50ZW5hbnQsIHRlbmFudElkKSk7XG4gICAgZm9yIChjb25zdCBwcmluY2lwYWwgb2YgcHJpbmNpcGFscykge1xuICAgICAgYXdhaXQgdGhpcy5yZWJ1aWxkRm9yUHJpbmNpcGFsKHRlbmFudElkLCBwcmluY2lwYWwuaWQsIC4uLmFyZ3MpO1xuICAgIH1cbiAgfVxufVxuIiwiaW1wb3J0IHsgQmFzZU1vZGVsU2VydmljZSwgcmVsYXRpb25NYXRjaCwgc2FtZVRlbmFudCB9IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHsgUmVnaXN0ZXJSZXNvdXJjZUlucHV0LCBSZXNvdXJjZVZpc2liaWxpdHkgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IFByb3RlY3RlZFJlc291cmNlIH0gZnJvbSBcIi4uL21vZGVscy9wcm90ZWN0ZWQtcmVzb3VyY2UubW9kZWxcIjtcblxuZXhwb3J0IGNsYXNzIFByb3RlY3RlZFJlc291cmNlU2VydmljZSBleHRlbmRzIEJhc2VNb2RlbFNlcnZpY2U8UHJvdGVjdGVkUmVzb3VyY2U+IHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoUHJvdGVjdGVkUmVzb3VyY2UpO1xuICB9XG5cbiAgYXN5bmMgcmVnaXN0ZXJSZXNvdXJjZShpbnB1dDogUmVnaXN0ZXJSZXNvdXJjZUlucHV0LCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8UHJvdGVjdGVkUmVzb3VyY2U+IHtcbiAgICByZXR1cm4gdGhpcy5jcmVhdGUoXG4gICAgICB7XG4gICAgICAgIHRlbmFudDogaW5wdXQudGVuYW50SWQsXG4gICAgICAgIG9yZ1VuaXQ6IGlucHV0Lm9yZ1VuaXRJZCxcbiAgICAgICAgcmVzb3VyY2VUeXBlOiBpbnB1dC5yZXNvdXJjZVR5cGUsXG4gICAgICAgIHJlc291cmNlSWQ6IGlucHV0LnJlc291cmNlSWQsXG4gICAgICAgIHZpc2liaWxpdHk6IGlucHV0LnZpc2liaWxpdHksXG4gICAgICAgIG93bmVyOiBpbnB1dC5vd25lclByaW5jaXBhbElkLFxuICAgICAgICBzZW5zaXRpdml0eTogaW5wdXQuc2Vuc2l0aXZpdHksXG4gICAgICAgIG1ldGFkYXRhOiBpbnB1dC5tZXRhZGF0YSxcbiAgICAgIH0sXG4gICAgICAuLi5hcmdzXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIGdldEJ5RG9tYWluUmVzb3VyY2UodGVuYW50SWQ6IHN0cmluZywgcmVzb3VyY2VUeXBlOiBzdHJpbmcsIHJlc291cmNlSWQ6IHN0cmluZywgLi4uYXJnczogYW55W10pOiBQcm9taXNlPFByb3RlY3RlZFJlc291cmNlIHwgdW5kZWZpbmVkPiB7XG4gICAgcmV0dXJuIChhd2FpdCB0aGlzLmxpc3RBbGwoLi4uYXJncykpLmZpbmQoXG4gICAgICAocmVzb3VyY2UpID0+IHNhbWVUZW5hbnQocmVzb3VyY2UudGVuYW50LCB0ZW5hbnRJZCkgJiYgcmVzb3VyY2UucmVzb3VyY2VUeXBlID09PSByZXNvdXJjZVR5cGUgJiYgcmVzb3VyY2UucmVzb3VyY2VJZCA9PT0gcmVzb3VyY2VJZFxuICAgICk7XG4gIH1cblxuICBhc3luYyBtb3ZlUmVzb3VyY2VUb09yZ1VuaXQocHJvdGVjdGVkUmVzb3VyY2VJZDogc3RyaW5nLCBvcmdVbml0SWQ6IHN0cmluZywgLi4uYXJnczogYW55W10pOiBQcm9taXNlPFByb3RlY3RlZFJlc291cmNlPiB7XG4gICAgcmV0dXJuIHRoaXMudXBkYXRlT25lKHByb3RlY3RlZFJlc291cmNlSWQsIHsgb3JnVW5pdDogb3JnVW5pdElkIH0sIC4uLmFyZ3MpO1xuICB9XG5cbiAgYXN5bmMgc2V0VmlzaWJpbGl0eShwcm90ZWN0ZWRSZXNvdXJjZUlkOiBzdHJpbmcsIHZpc2liaWxpdHk6IFJlc291cmNlVmlzaWJpbGl0eSwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPFByb3RlY3RlZFJlc291cmNlPiB7XG4gICAgcmV0dXJuIHRoaXMudXBkYXRlT25lKHByb3RlY3RlZFJlc291cmNlSWQsIHsgdmlzaWJpbGl0eSB9LCAuLi5hcmdzKTtcbiAgfVxuXG4gIGFzeW5jIHRyYW5zZmVyT3duZXJzaGlwKHByb3RlY3RlZFJlc291cmNlSWQ6IHN0cmluZywgb3duZXJQcmluY2lwYWxJZDogc3RyaW5nIHwgdW5kZWZpbmVkLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8UHJvdGVjdGVkUmVzb3VyY2U+IHtcbiAgICByZXR1cm4gdGhpcy51cGRhdGVPbmUocHJvdGVjdGVkUmVzb3VyY2VJZCwgeyBvd25lcjogb3duZXJQcmluY2lwYWxJZCB9LCAuLi5hcmdzKTtcbiAgfVxuXG4gIGFzeW5jIGxpc3RPcmdVbml0UmVzb3VyY2VzKG9yZ1VuaXRJZDogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8UHJvdGVjdGVkUmVzb3VyY2VbXT4ge1xuICAgIHJldHVybiAoYXdhaXQgdGhpcy5saXN0QWxsKC4uLmFyZ3MpKS5maWx0ZXIoKHJlc291cmNlKSA9PiByZWxhdGlvbk1hdGNoKHJlc291cmNlLm9yZ1VuaXQsIG9yZ1VuaXRJZCkpO1xuICB9XG5cbiAgYXN5bmMgbGlzdFRlbmFudFJlc291cmNlcyh0ZW5hbnRJZDogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8UHJvdGVjdGVkUmVzb3VyY2VbXT4ge1xuICAgIHJldHVybiAoYXdhaXQgdGhpcy5saXN0QWxsKC4uLmFyZ3MpKS5maWx0ZXIoKHJlc291cmNlKSA9PiBzYW1lVGVuYW50KHJlc291cmNlLnRlbmFudCwgdGVuYW50SWQpKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgQmFzZU1vZGVsU2VydmljZSwgcmVsYXRpb25NYXRjaCwgc2FtZVRlbmFudCB9IGZyb20gXCIuLi91dGlsc1wiO1xuaW1wb3J0IHsgR3JhbnRSZXNvdXJjZUlucHV0IH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBSZXNvdXJjZUdyYW50IH0gZnJvbSBcIi4uL21vZGVscy9yZXNvdXJjZS1ncmFudC5tb2RlbFwiO1xuXG5leHBvcnQgY2xhc3MgUmVzb3VyY2VHcmFudFNlcnZpY2UgZXh0ZW5kcyBCYXNlTW9kZWxTZXJ2aWNlPFJlc291cmNlR3JhbnQ+IHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoUmVzb3VyY2VHcmFudCk7XG4gIH1cblxuICBhc3luYyBncmFudFJlc291cmNlKGlucHV0OiBHcmFudFJlc291cmNlSW5wdXQsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxSZXNvdXJjZUdyYW50PiB7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlKFxuICAgICAge1xuICAgICAgICB0ZW5hbnQ6IGlucHV0LnRlbmFudElkLFxuICAgICAgICByZXNvdXJjZTogaW5wdXQucmVzb3VyY2VJZCxcbiAgICAgICAgcHJpbmNpcGFsOiBpbnB1dC5wcmluY2lwYWxJZCxcbiAgICAgICAgcGVybWlzc2lvbktleTogaW5wdXQucGVybWlzc2lvbktleSxcbiAgICAgICAgc3RhcnRzQXQ6IGlucHV0LnN0YXJ0c0F0LFxuICAgICAgICBleHBpcmVzQXQ6IGlucHV0LmV4cGlyZXNBdCxcbiAgICAgICAgY29uZGl0aW9uczogaW5wdXQuY29uZGl0aW9ucyxcbiAgICAgICAgY3JlYXRlZEJ5OiBpbnB1dC5jcmVhdGVkQnlQcmluY2lwYWxJZCxcbiAgICAgIH0sXG4gICAgICAuLi5hcmdzXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIHJldm9rZUdyYW50KGdyYW50SWQ6IHN0cmluZywgLi4uYXJnczogYW55W10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLmRlbGV0ZUJ5SWQoZ3JhbnRJZCwgLi4uYXJncyk7XG4gIH1cblxuICBhc3luYyBsaXN0UmVzb3VyY2VHcmFudHMocHJvdGVjdGVkUmVzb3VyY2VJZDogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8UmVzb3VyY2VHcmFudFtdPiB7XG4gICAgcmV0dXJuIChhd2FpdCB0aGlzLmxpc3RBbGwoLi4uYXJncykpLmZpbHRlcigoZ3JhbnQpID0+IHJlbGF0aW9uTWF0Y2goZ3JhbnQucmVzb3VyY2UsIHByb3RlY3RlZFJlc291cmNlSWQpKTtcbiAgfVxuXG4gIGFzeW5jIGxpc3RQcmluY2lwYWxHcmFudHModGVuYW50SWQ6IHN0cmluZywgcHJpbmNpcGFsSWQ6IHN0cmluZywgLi4uYXJnczogYW55W10pOiBQcm9taXNlPFJlc291cmNlR3JhbnRbXT4ge1xuICAgIHJldHVybiAoYXdhaXQgdGhpcy5saXN0QWxsKC4uLmFyZ3MpKS5maWx0ZXIoXG4gICAgICAoZ3JhbnQpID0+IHNhbWVUZW5hbnQoZ3JhbnQudGVuYW50LCB0ZW5hbnRJZCkgJiYgcmVsYXRpb25NYXRjaChncmFudC5wcmluY2lwYWwsIHByaW5jaXBhbElkKVxuICAgICk7XG4gIH1cblxuICBhc3luYyBoYXNHcmFudChcbiAgICB0ZW5hbnRJZDogc3RyaW5nLFxuICAgIHByaW5jaXBhbElkOiBzdHJpbmcsXG4gICAgcHJvdGVjdGVkUmVzb3VyY2VJZDogc3RyaW5nLFxuICAgIHBlcm1pc3Npb25LZXk6IHN0cmluZyxcbiAgICBhdD86IERhdGUsXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIChhd2FpdCB0aGlzLmxpc3RQcmluY2lwYWxHcmFudHModGVuYW50SWQsIHByaW5jaXBhbElkLCAuLi5hcmdzKSkuc29tZShcbiAgICAgIChncmFudCkgPT5cbiAgICAgICAgcmVsYXRpb25NYXRjaChncmFudC5yZXNvdXJjZSwgcHJvdGVjdGVkUmVzb3VyY2VJZCkgJiZcbiAgICAgICAgZ3JhbnQucGVybWlzc2lvbktleSA9PT0gcGVybWlzc2lvbktleSAmJlxuICAgICAgICAoIWdyYW50LnN0YXJ0c0F0IHx8ICFhdCB8fCBncmFudC5zdGFydHNBdCA8PSBhdCkgJiZcbiAgICAgICAgKCFncmFudC5leHBpcmVzQXQgfHwgIWF0IHx8IGdyYW50LmV4cGlyZXNBdCA+PSBhdClcbiAgICApO1xuICB9XG5cbiAgYXN5bmMgZGVsZXRlQWxsRm9yUmVzb3VyY2UocHJvdGVjdGVkUmVzb3VyY2VJZDogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGZvciAoY29uc3Qgcm93IG9mIGF3YWl0IHRoaXMubGlzdFJlc291cmNlR3JhbnRzKHByb3RlY3RlZFJlc291cmNlSWQsIC4uLmFyZ3MpKSB7XG4gICAgICBhd2FpdCB0aGlzLmRlbGV0ZUJ5SWQocm93LmlkLCAuLi5hcmdzKTtcbiAgICB9XG4gIH1cbn1cbiIsImltcG9ydCB7IFByb3RlY3RlZFJlc291cmNlU2VydmljZSB9IGZyb20gXCIuL3Byb3RlY3RlZC1yZXNvdXJjZS5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBSZXNvdXJjZUdyYW50U2VydmljZSB9IGZyb20gXCIuL3Jlc291cmNlLWdyYW50LnNlcnZpY2VcIjtcbmltcG9ydCB7IHJlbGF0aW9uSWQgfSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCB7IFJlc291cmNlVmlzaWJpbGl0eSB9IGZyb20gXCIuLi90eXBlc1wiO1xuXG5leHBvcnQgY2xhc3MgUmVzb3VyY2VMaWZlY3ljbGVTZXJ2aWNlIHtcbiAgYXN5bmMgdW5yZWdpc3RlclJlc291cmNlKHByb3RlY3RlZFJlc291cmNlSWQ6IHN0cmluZywgLi4uYXJnczogYW55W10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCBuZXcgUmVzb3VyY2VHcmFudFNlcnZpY2UoKS5kZWxldGVBbGxGb3JSZXNvdXJjZShwcm90ZWN0ZWRSZXNvdXJjZUlkLCAuLi5hcmdzKTtcbiAgICBhd2FpdCBuZXcgUHJvdGVjdGVkUmVzb3VyY2VTZXJ2aWNlKCkuZGVsZXRlQnlJZChwcm90ZWN0ZWRSZXNvdXJjZUlkLCAuLi5hcmdzKTtcbiAgfVxuXG4gIGFzeW5jIHJlc29sdmVSZXNvdXJjZVNjb3BlKFxuICAgIHByb3RlY3RlZFJlc291cmNlSWQ6IHN0cmluZyxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPHtcbiAgICB0ZW5hbnRJZDogc3RyaW5nO1xuICAgIG9yZ1VuaXRJZDogc3RyaW5nO1xuICAgIHZpc2liaWxpdHk6IFJlc291cmNlVmlzaWJpbGl0eTtcbiAgICBvd25lclByaW5jaXBhbElkPzogc3RyaW5nO1xuICB9PiB7XG4gICAgY29uc3QgcmVzb3VyY2UgPSBhd2FpdCBuZXcgUHJvdGVjdGVkUmVzb3VyY2VTZXJ2aWNlKCkuZ2V0QnlJZChwcm90ZWN0ZWRSZXNvdXJjZUlkLCAuLi5hcmdzKTtcbiAgICByZXR1cm4ge1xuICAgICAgdGVuYW50SWQ6IHJlbGF0aW9uSWQocmVzb3VyY2UudGVuYW50KSxcbiAgICAgIG9yZ1VuaXRJZDogcmVsYXRpb25JZChyZXNvdXJjZS5vcmdVbml0KSxcbiAgICAgIHZpc2liaWxpdHk6IHJlc291cmNlLnZpc2liaWxpdHksXG4gICAgICBvd25lclByaW5jaXBhbElkOiByZXNvdXJjZS5vd25lciA/IHJlbGF0aW9uSWQocmVzb3VyY2Uub3duZXIpIDogdW5kZWZpbmVkLFxuICAgIH07XG4gIH1cbn1cbiIsImltcG9ydCB7IEJhc2VNb2RlbFNlcnZpY2UsIHJlbGF0aW9uSWQgfSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCB7IENyZWF0ZVN0b3JhZ2VCaW5kaW5nSW5wdXQsIFN0b3JhZ2VCaW5kaW5nS2luZCwgU3RvcmFnZUtpbmQgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IFN0b3JhZ2VCaW5kaW5nIH0gZnJvbSBcIi4uL21vZGVscy9zdG9yYWdlLWJpbmRpbmcubW9kZWxcIjtcblxuZXhwb3J0IGNsYXNzIFN0b3JhZ2VCaW5kaW5nU2VydmljZSBleHRlbmRzIEJhc2VNb2RlbFNlcnZpY2U8U3RvcmFnZUJpbmRpbmc+IHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoU3RvcmFnZUJpbmRpbmcpO1xuICB9XG5cbiAgYXN5bmMgY3JlYXRlQmluZGluZyhpbnB1dDogQ3JlYXRlU3RvcmFnZUJpbmRpbmdJbnB1dCwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPFN0b3JhZ2VCaW5kaW5nPiB7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlKFxuICAgICAge1xuICAgICAgICB0ZW5hbnQ6IGlucHV0LnRlbmFudElkLFxuICAgICAgICBzdG9yYWdlS2luZDogaW5wdXQuc3RvcmFnZUtpbmQsXG4gICAgICAgIGJpbmRpbmdLaW5kOiBpbnB1dC5iaW5kaW5nS2luZCxcbiAgICAgICAgYmluZGluZ0tleTogaW5wdXQuYmluZGluZ0tleSxcbiAgICAgICAgcmVnaW9uOiBpbnB1dC5yZWdpb24sXG4gICAgICAgIGNvbmZpZzogaW5wdXQuY29uZmlnLFxuICAgICAgfSxcbiAgICAgIC4uLmFyZ3NcbiAgICApO1xuICB9XG5cbiAgYXN5bmMgbGlzdFRlbmFudEJpbmRpbmdzKHRlbmFudElkOiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxTdG9yYWdlQmluZGluZ1tdPiB7XG4gICAgcmV0dXJuIChhd2FpdCB0aGlzLmxpc3RBbGwoLi4uYXJncykpLmZpbHRlcigoYmluZGluZykgPT4gcmVsYXRpb25JZChiaW5kaW5nLnRlbmFudCkgPT09IHRlbmFudElkKTtcbiAgfVxuXG4gIGFzeW5jIGdldEJpbmRpbmcodGVuYW50SWQ6IHN0cmluZywgc3RvcmFnZUtpbmQ6IFN0b3JhZ2VLaW5kLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8U3RvcmFnZUJpbmRpbmcgfCB1bmRlZmluZWQ+IHtcbiAgICByZXR1cm4gKGF3YWl0IHRoaXMubGlzdFRlbmFudEJpbmRpbmdzKHRlbmFudElkLCAuLi5hcmdzKSkuZmluZCgoYmluZGluZykgPT4gYmluZGluZy5zdG9yYWdlS2luZCA9PT0gc3RvcmFnZUtpbmQpO1xuICB9XG5cbiAgYXN5bmMgc2V0QmluZGluZ0NvbmZpZyhcbiAgICBiaW5kaW5nSWQ6IHN0cmluZyxcbiAgICBjb25maWc6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgdW5kZWZpbmVkLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8U3RvcmFnZUJpbmRpbmc+IHtcbiAgICByZXR1cm4gdGhpcy51cGRhdGVPbmUoYmluZGluZ0lkLCB7IGNvbmZpZyB9LCAuLi5hcmdzKTtcbiAgfVxuXG4gIGFzeW5jIHByb21vdGVUb0RlZGljYXRlZChcbiAgICBiaW5kaW5nSWQ6IHN0cmluZyxcbiAgICBiaW5kaW5nS2V5OiBzdHJpbmcsXG4gICAgcmVnaW9uOiBzdHJpbmcsXG4gICAgY29uZmlnPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxTdG9yYWdlQmluZGluZz4ge1xuICAgIHJldHVybiB0aGlzLnVwZGF0ZU9uZShiaW5kaW5nSWQsIHsgYmluZGluZ0tpbmQ6IFN0b3JhZ2VCaW5kaW5nS2luZC5EZWRpY2F0ZWQsIGJpbmRpbmdLZXksIHJlZ2lvbiwgY29uZmlnIH0sIC4uLmFyZ3MpO1xuICB9XG5cbiAgYXN5bmMgc2V0U2hhcmVkKFxuICAgIGJpbmRpbmdJZDogc3RyaW5nLFxuICAgIGJpbmRpbmdLZXk6IHN0cmluZyxcbiAgICByZWdpb246IHN0cmluZyxcbiAgICBjb25maWc/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPFN0b3JhZ2VCaW5kaW5nPiB7XG4gICAgcmV0dXJuIHRoaXMudXBkYXRlT25lKGJpbmRpbmdJZCwgeyBiaW5kaW5nS2luZDogU3RvcmFnZUJpbmRpbmdLaW5kLlNoYXJlZCwgYmluZGluZ0tleSwgcmVnaW9uLCBjb25maWcgfSwgLi4uYXJncyk7XG4gIH1cbn1cbiIsImltcG9ydCB7IHRyYW5zYWN0aW9uYWwgfSBmcm9tIFwiLi4vdXRpbHNcIjtcbmltcG9ydCB0eXBlIHsgQm9vdHN0cmFwT3JnVW5pdCwgQm9vdHN0cmFwVGVtcGxhdGUgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IE1lbWJlcnNoaXBTdGF0dXMsIFNjb3BlS2luZCB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgVGVuYW50U2VydmljZSB9IGZyb20gXCIuL3RlbmFudC5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBUZW5hbnRQcm9maWxlU2VydmljZSB9IGZyb20gXCIuL3RlbmFudC1wcm9maWxlLnNlcnZpY2VcIjtcbmltcG9ydCB7IE9yZ1VuaXRTZXJ2aWNlIH0gZnJvbSBcIi4vb3JnLXVuaXQuc2VydmljZVwiO1xuaW1wb3J0IHsgT3JnVW5pdFByb2ZpbGVTZXJ2aWNlIH0gZnJvbSBcIi4vb3JnLXVuaXQtcHJvZmlsZS5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBVc2VyU2VydmljZSB9IGZyb20gXCIuL3VzZXIuc2VydmljZVwiO1xuaW1wb3J0IHsgVGVuYW50TWVtYmVyc2hpcFNlcnZpY2UgfSBmcm9tIFwiLi90ZW5hbnQtbWVtYmVyc2hpcC5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBQcmluY2lwYWxTZXJ2aWNlIH0gZnJvbSBcIi4vcHJpbmNpcGFsLnNlcnZpY2VcIjtcbmltcG9ydCB7IFBlcm1pc3Npb25TZXJ2aWNlIH0gZnJvbSBcIi4vcGVybWlzc2lvbi5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBSb2xlU2VydmljZSB9IGZyb20gXCIuL3JvbGUuc2VydmljZVwiO1xuaW1wb3J0IHsgUm9sZVBlcm1pc3Npb25TZXJ2aWNlIH0gZnJvbSBcIi4vcm9sZS1wZXJtaXNzaW9uLnNlcnZpY2VcIjtcbmltcG9ydCB7IFJvbGVBc3NpZ25tZW50U2VydmljZSB9IGZyb20gXCIuL3JvbGUtYXNzaWdubWVudC5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBFZmZlY3RpdmVQZXJtaXNzaW9uU2VydmljZSB9IGZyb20gXCIuL2VmZmVjdGl2ZS1wZXJtaXNzaW9uLnNlcnZpY2VcIjtcblxuZXhwb3J0IGNsYXNzIEJvb3RzdHJhcFNlcnZpY2Uge1xuICBwcml2YXRlIHRlbmFudFNlcnZpY2UgPSBuZXcgVGVuYW50U2VydmljZSgpO1xuICBwcml2YXRlIHRlbmFudFByb2ZpbGVTZXJ2aWNlID0gbmV3IFRlbmFudFByb2ZpbGVTZXJ2aWNlKCk7XG4gIHByaXZhdGUgb3JnVW5pdFNlcnZpY2UgPSBuZXcgT3JnVW5pdFNlcnZpY2UoKTtcbiAgcHJpdmF0ZSBvcmdVbml0UHJvZmlsZVNlcnZpY2UgPSBuZXcgT3JnVW5pdFByb2ZpbGVTZXJ2aWNlKCk7XG4gIHByaXZhdGUgdXNlclNlcnZpY2UgPSBuZXcgVXNlclNlcnZpY2UoKTtcbiAgcHJpdmF0ZSBtZW1iZXJzaGlwU2VydmljZSA9IG5ldyBUZW5hbnRNZW1iZXJzaGlwU2VydmljZSgpO1xuICBwcml2YXRlIHByaW5jaXBhbFNlcnZpY2UgPSBuZXcgUHJpbmNpcGFsU2VydmljZSgpO1xuICBwcml2YXRlIHBlcm1pc3Npb25TZXJ2aWNlID0gbmV3IFBlcm1pc3Npb25TZXJ2aWNlKCk7XG4gIHByaXZhdGUgcm9sZVNlcnZpY2UgPSBuZXcgUm9sZVNlcnZpY2UoKTtcbiAgcHJpdmF0ZSByb2xlUGVybWlzc2lvblNlcnZpY2UgPSBuZXcgUm9sZVBlcm1pc3Npb25TZXJ2aWNlKCk7XG4gIHByaXZhdGUgcm9sZUFzc2lnbm1lbnRTZXJ2aWNlID0gbmV3IFJvbGVBc3NpZ25tZW50U2VydmljZSgpO1xuICBwcml2YXRlIGVmZmVjdGl2ZVBlcm1pc3Npb25TZXJ2aWNlID0gbmV3IEVmZmVjdGl2ZVBlcm1pc3Npb25TZXJ2aWNlKCk7XG5cbiAgQHRyYW5zYWN0aW9uYWwoKVxuICBhc3luYyBib290c3RyYXBUZW5hbnRGcm9tVGVtcGxhdGUoXG4gICAgdGVtcGxhdGU6IEJvb3RzdHJhcFRlbXBsYXRlLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8e1xuICAgIHRlbmFudElkOiBzdHJpbmc7XG4gICAgcm9vdE9yZ1VuaXRJZDogc3RyaW5nO1xuICAgIG93bmVyVXNlcklkOiBzdHJpbmc7XG4gICAgb3duZXJQcmluY2lwYWxJZDogc3RyaW5nO1xuICB9PiB7XG4gICAgY29uc3QgdGVuYW50ID0gYXdhaXQgdGhpcy50ZW5hbnRTZXJ2aWNlLmNyZWF0ZVRlbmFudChcbiAgICAgIHRlbXBsYXRlLnRlbmFudCxcbiAgICAgIC4uLmFyZ3NcbiAgICApO1xuICAgIGlmICh0ZW1wbGF0ZS50ZW5hbnQucHJvZmlsZUtleSkge1xuICAgICAgYXdhaXQgdGhpcy50ZW5hbnRQcm9maWxlU2VydmljZS5jcmVhdGVQcm9maWxlKFxuICAgICAgICB0ZW5hbnQuaWQsXG4gICAgICAgIHRlbXBsYXRlLnRlbmFudC5wcm9maWxlS2V5LFxuICAgICAgICB0ZW1wbGF0ZS50ZW5hbnQucHJvZmlsZU1ldGFkYXRhLFxuICAgICAgICAuLi5hcmdzXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IGNyZWF0ZU9yZ1RyZWUgPSBhc3luYyAoXG4gICAgICBwYXJlbnRJZDogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICAgICAgb3JnVW5pdDogQm9vdHN0cmFwT3JnVW5pdFxuICAgICkgPT4ge1xuICAgICAgY29uc3QgY3JlYXRlZCA9XG4gICAgICAgIHBhcmVudElkID09PSB1bmRlZmluZWRcbiAgICAgICAgICA/IGF3YWl0IHRoaXMub3JnVW5pdFNlcnZpY2UuY3JlYXRlUm9vdChcbiAgICAgICAgICAgICAgdGVuYW50LmlkLFxuICAgICAgICAgICAgICBvcmdVbml0Lm5hbWUsXG4gICAgICAgICAgICAgIG9yZ1VuaXQubWV0YWRhdGEsXG4gICAgICAgICAgICAgIG9yZ1VuaXQucHJvZmlsZUtleSxcbiAgICAgICAgICAgICAgb3JnVW5pdC5tZXRhZGF0YSxcbiAgICAgICAgICAgICAgLi4uYXJnc1xuICAgICAgICAgICAgKVxuICAgICAgICAgIDogYXdhaXQgdGhpcy5vcmdVbml0U2VydmljZS5jcmVhdGVDaGlsZChcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHRlbmFudElkOiB0ZW5hbnQuaWQsXG4gICAgICAgICAgICAgICAgcGFyZW50T3JnVW5pdElkOiBwYXJlbnRJZCxcbiAgICAgICAgICAgICAgICBuYW1lOiBvcmdVbml0Lm5hbWUsXG4gICAgICAgICAgICAgICAgbWV0YWRhdGE6IG9yZ1VuaXQubWV0YWRhdGEsXG4gICAgICAgICAgICAgICAgcHJvZmlsZUtleTogb3JnVW5pdC5wcm9maWxlS2V5LFxuICAgICAgICAgICAgICAgIHByb2ZpbGVNZXRhZGF0YTogb3JnVW5pdC5tZXRhZGF0YSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgLi4uYXJnc1xuICAgICAgICAgICAgKTtcbiAgICAgIGZvciAoY29uc3QgY2hpbGQgb2Ygb3JnVW5pdC5jaGlsZHJlbiA/PyBbXSkge1xuICAgICAgICBhd2FpdCBjcmVhdGVPcmdUcmVlKGNyZWF0ZWQuaWQsIGNoaWxkKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjcmVhdGVkO1xuICAgIH07XG5cbiAgICBjb25zdCByb290T3JnVW5pdCA9IGF3YWl0IGNyZWF0ZU9yZ1RyZWUodW5kZWZpbmVkLCB0ZW1wbGF0ZS5yb290T3JnVW5pdCk7XG4gICAgY29uc3Qgb3duZXIgPSBhd2FpdCB0aGlzLnVzZXJTZXJ2aWNlLmNyZWF0ZVVzZXIoXG4gICAgICB0ZW1wbGF0ZS5vd25lclVzZXIsXG4gICAgICAuLi5hcmdzXG4gICAgKTtcbiAgICBhd2FpdCB0aGlzLm1lbWJlcnNoaXBTZXJ2aWNlLmFkZFVzZXJUb1RlbmFudChcbiAgICAgIHRlbmFudC5pZCxcbiAgICAgIG93bmVyLmlkLFxuICAgICAgTWVtYmVyc2hpcFN0YXR1cy5BY3RpdmUsXG4gICAgICAuLi5hcmdzXG4gICAgKTtcbiAgICBjb25zdCBvd25lclByaW5jaXBhbCA9IGF3YWl0IHRoaXMucHJpbmNpcGFsU2VydmljZS5nZXRVc2VyUHJpbmNpcGFsKFxuICAgICAgdGVuYW50LmlkLFxuICAgICAgb3duZXIuaWQsXG4gICAgICAuLi5hcmdzXG4gICAgKTtcblxuICAgIGZvciAoY29uc3QgcGVybWlzc2lvbiBvZiB0ZW1wbGF0ZS5wZXJtaXNzaW9ucykge1xuICAgICAgYXdhaXQgdGhpcy5wZXJtaXNzaW9uU2VydmljZS5jcmVhdGVQZXJtaXNzaW9uKHBlcm1pc3Npb24sIC4uLmFyZ3MpO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IHJvbGUgb2YgdGVtcGxhdGUucm9sZXMpIHtcbiAgICAgIGNvbnN0IGNyZWF0ZWRSb2xlID0gYXdhaXQgdGhpcy5yb2xlU2VydmljZS5jcmVhdGVSb2xlKFxuICAgICAgICB7XG4gICAgICAgICAgdGVuYW50SWQ6IHRlbmFudC5pZCxcbiAgICAgICAgICBrZXk6IHJvbGUua2V5LFxuICAgICAgICAgIG5hbWU6IHJvbGUubmFtZSxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogcm9sZS5kZXNjcmlwdGlvbixcbiAgICAgICAgfSxcbiAgICAgICAgLi4uYXJnc1xuICAgICAgKTtcbiAgICAgIGZvciAoY29uc3QgcGVybWlzc2lvbktleSBvZiByb2xlLnBlcm1pc3Npb25LZXlzKSB7XG4gICAgICAgIGF3YWl0IHRoaXMucm9sZVBlcm1pc3Npb25TZXJ2aWNlLmFkZFBlcm1pc3Npb25LZXlUb1JvbGUoXG4gICAgICAgICAgY3JlYXRlZFJvbGUuaWQsXG4gICAgICAgICAgcGVybWlzc2lvbktleSxcbiAgICAgICAgICAuLi5hcmdzXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgb3duZXJSb2xlID0gYXdhaXQgdGhpcy5yb2xlU2VydmljZS5nZXRUZW5hbnRSb2xlQnlLZXkoXG4gICAgICB0ZW5hbnQuaWQsXG4gICAgICB0ZW1wbGF0ZS5vd25lclJvbGVLZXksXG4gICAgICAuLi5hcmdzXG4gICAgKTtcbiAgICBhd2FpdCB0aGlzLnJvbGVBc3NpZ25tZW50U2VydmljZS5hc3NpZ25Sb2xlKFxuICAgICAge1xuICAgICAgICB0ZW5hbnRJZDogdGVuYW50LmlkLFxuICAgICAgICBwcmluY2lwYWxJZDogb3duZXJQcmluY2lwYWwuaWQsXG4gICAgICAgIHJvbGVJZDogb3duZXJSb2xlLmlkLFxuICAgICAgICBzY29wZUtpbmQ6IFNjb3BlS2luZC5PcmdVbml0LFxuICAgICAgICBzY29wZUlkOiByb290T3JnVW5pdC5pZCxcbiAgICAgICAgaW5oZXJpdERvd246IHRydWUsXG4gICAgICB9LFxuICAgICAgLi4uYXJnc1xuICAgICk7XG4gICAgYXdhaXQgdGhpcy5lZmZlY3RpdmVQZXJtaXNzaW9uU2VydmljZS5yZWJ1aWxkRm9yUHJpbmNpcGFsKFxuICAgICAgdGVuYW50LmlkLFxuICAgICAgb3duZXJQcmluY2lwYWwuaWQsXG4gICAgICAuLi5hcmdzXG4gICAgKTtcblxuICAgIHJldHVybiB7XG4gICAgICB0ZW5hbnRJZDogdGVuYW50LmlkLFxuICAgICAgcm9vdE9yZ1VuaXRJZDogcm9vdE9yZ1VuaXQuaWQsXG4gICAgICBvd25lclVzZXJJZDogb3duZXIuaWQsXG4gICAgICBvd25lclByaW5jaXBhbElkOiBvd25lclByaW5jaXBhbC5pZCxcbiAgICB9O1xuICB9XG59XG4iLCJpbXBvcnQgeyB0cmFuc2FjdGlvbmFsIH0gZnJvbSBcIi4uL3V0aWxzXCI7XG5pbXBvcnQgeyBNZW1iZXJzaGlwU3RhdHVzLCBTY29wZUtpbmQgfSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IFRlbmFudE1lbWJlcnNoaXBTZXJ2aWNlIH0gZnJvbSBcIi4vdGVuYW50LW1lbWJlcnNoaXAuc2VydmljZVwiO1xuaW1wb3J0IHsgT3JnVW5pdE1lbWJlcnNoaXBTZXJ2aWNlIH0gZnJvbSBcIi4vb3JnLXVuaXQtbWVtYmVyc2hpcC5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBQcmluY2lwYWxTZXJ2aWNlIH0gZnJvbSBcIi4vcHJpbmNpcGFsLnNlcnZpY2VcIjtcbmltcG9ydCB7IFJvbGVTZXJ2aWNlIH0gZnJvbSBcIi4vcm9sZS5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBSb2xlQXNzaWdubWVudFNlcnZpY2UgfSBmcm9tIFwiLi9yb2xlLWFzc2lnbm1lbnQuc2VydmljZVwiO1xuaW1wb3J0IHsgRWZmZWN0aXZlUGVybWlzc2lvblNlcnZpY2UgfSBmcm9tIFwiLi9lZmZlY3RpdmUtcGVybWlzc2lvbi5zZXJ2aWNlXCI7XG5cbmV4cG9ydCBjbGFzcyBTeXN0ZW1NYW5hZ2VtZW50U2VydmljZSB7XG4gIHByaXZhdGUgbWVtYmVyc2hpcFNlcnZpY2UgPSBuZXcgVGVuYW50TWVtYmVyc2hpcFNlcnZpY2UoKTtcbiAgcHJpdmF0ZSBvcmdNZW1iZXJzaGlwU2VydmljZSA9IG5ldyBPcmdVbml0TWVtYmVyc2hpcFNlcnZpY2UoKTtcbiAgcHJpdmF0ZSBwcmluY2lwYWxTZXJ2aWNlID0gbmV3IFByaW5jaXBhbFNlcnZpY2UoKTtcbiAgcHJpdmF0ZSByb2xlU2VydmljZSA9IG5ldyBSb2xlU2VydmljZSgpO1xuICBwcml2YXRlIHJvbGVBc3NpZ25tZW50U2VydmljZSA9IG5ldyBSb2xlQXNzaWdubWVudFNlcnZpY2UoKTtcbiAgcHJpdmF0ZSBlZmZlY3RpdmVQZXJtaXNzaW9uU2VydmljZSA9IG5ldyBFZmZlY3RpdmVQZXJtaXNzaW9uU2VydmljZSgpO1xuXG4gIEB0cmFuc2FjdGlvbmFsKClcbiAgYXN5bmMgb25ib2FyZFVzZXJUb1RlbmFudEFuZE9yZ1VuaXQoXG4gICAgdGVuYW50SWQ6IHN0cmluZyxcbiAgICB1c2VySWQ6IHN0cmluZyxcbiAgICBvcmdVbml0SWQ6IHN0cmluZyxcbiAgICByb2xlS2V5OiBzdHJpbmcsXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTx7IHByaW5jaXBhbElkOiBzdHJpbmcgfT4ge1xuICAgIGF3YWl0IHRoaXMubWVtYmVyc2hpcFNlcnZpY2UuYWRkVXNlclRvVGVuYW50KHRlbmFudElkLCB1c2VySWQsIE1lbWJlcnNoaXBTdGF0dXMuQWN0aXZlLCAuLi5hcmdzKTtcbiAgICBhd2FpdCB0aGlzLm9yZ01lbWJlcnNoaXBTZXJ2aWNlLmFkZFVzZXJUb09yZ1VuaXQodGVuYW50SWQsIG9yZ1VuaXRJZCwgdXNlcklkLCBNZW1iZXJzaGlwU3RhdHVzLkFjdGl2ZSwgLi4uYXJncyk7XG4gICAgY29uc3QgcHJpbmNpcGFsID0gYXdhaXQgdGhpcy5wcmluY2lwYWxTZXJ2aWNlLmdldFVzZXJQcmluY2lwYWwodGVuYW50SWQsIHVzZXJJZCwgLi4uYXJncyk7XG4gICAgY29uc3Qgcm9sZSA9IGF3YWl0IHRoaXMucm9sZVNlcnZpY2UuZ2V0VGVuYW50Um9sZUJ5S2V5KHRlbmFudElkLCByb2xlS2V5LCAuLi5hcmdzKTtcbiAgICBhd2FpdCB0aGlzLnJvbGVBc3NpZ25tZW50U2VydmljZS5hc3NpZ25Sb2xlKFxuICAgICAge1xuICAgICAgICB0ZW5hbnRJZCxcbiAgICAgICAgcHJpbmNpcGFsSWQ6IHByaW5jaXBhbC5pZCxcbiAgICAgICAgcm9sZUlkOiByb2xlLmlkLFxuICAgICAgICBzY29wZUtpbmQ6IFNjb3BlS2luZC5PcmdVbml0LFxuICAgICAgICBzY29wZUlkOiBvcmdVbml0SWQsXG4gICAgICAgIGluaGVyaXREb3duOiB0cnVlLFxuICAgICAgfSxcbiAgICAgIC4uLmFyZ3NcbiAgICApO1xuICAgIGF3YWl0IHRoaXMuZWZmZWN0aXZlUGVybWlzc2lvblNlcnZpY2UucmVidWlsZEZvclByaW5jaXBhbCh0ZW5hbnRJZCwgcHJpbmNpcGFsLmlkLCAuLi5hcmdzKTtcbiAgICByZXR1cm4geyBwcmluY2lwYWxJZDogcHJpbmNpcGFsLmlkIH07XG4gIH1cblxuICBAdHJhbnNhY3Rpb25hbCgpXG4gIGFzeW5jIGNoYW5nZVVzZXJPcmdSb2xlKFxuICAgIHRlbmFudElkOiBzdHJpbmcsXG4gICAgcHJpbmNpcGFsSWQ6IHN0cmluZyxcbiAgICBvcmdVbml0SWQ6IHN0cmluZyxcbiAgICByb2xlS2V5OiBzdHJpbmcsXG4gICAgaW5oZXJpdERvd246IGJvb2xlYW4sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3Qgcm9sZSA9IGF3YWl0IHRoaXMucm9sZVNlcnZpY2UuZ2V0VGVuYW50Um9sZUJ5S2V5KHRlbmFudElkLCByb2xlS2V5LCAuLi5hcmdzKTtcbiAgICBjb25zdCBjdXJyZW50QXNzaWdubWVudHMgPSBhd2FpdCB0aGlzLnJvbGVBc3NpZ25tZW50U2VydmljZS5saXN0UHJpbmNpcGFsQXNzaWdubWVudHModGVuYW50SWQsIHByaW5jaXBhbElkLCAuLi5hcmdzKTtcbiAgICBmb3IgKGNvbnN0IGFzc2lnbm1lbnQgb2YgY3VycmVudEFzc2lnbm1lbnRzLmZpbHRlcigocm93KSA9PiByb3cuc2NvcGVLaW5kID09PSBTY29wZUtpbmQuT3JnVW5pdCAmJiByb3cuc2NvcGVJZCA9PT0gb3JnVW5pdElkKSkge1xuICAgICAgYXdhaXQgdGhpcy5yb2xlQXNzaWdubWVudFNlcnZpY2UucmV2b2tlQXNzaWdubWVudChhc3NpZ25tZW50LmlkLCAuLi5hcmdzKTtcbiAgICB9XG4gICAgYXdhaXQgdGhpcy5yb2xlQXNzaWdubWVudFNlcnZpY2UuYXNzaWduUm9sZShcbiAgICAgIHtcbiAgICAgICAgdGVuYW50SWQsXG4gICAgICAgIHByaW5jaXBhbElkLFxuICAgICAgICByb2xlSWQ6IHJvbGUuaWQsXG4gICAgICAgIHNjb3BlS2luZDogU2NvcGVLaW5kLk9yZ1VuaXQsXG4gICAgICAgIHNjb3BlSWQ6IG9yZ1VuaXRJZCxcbiAgICAgICAgaW5oZXJpdERvd24sXG4gICAgICB9LFxuICAgICAgLi4uYXJnc1xuICAgICk7XG4gICAgYXdhaXQgdGhpcy5lZmZlY3RpdmVQZXJtaXNzaW9uU2VydmljZS5yZWJ1aWxkRm9yUHJpbmNpcGFsKHRlbmFudElkLCBwcmluY2lwYWxJZCwgLi4uYXJncyk7XG4gIH1cblxuICBAdHJhbnNhY3Rpb25hbCgpXG4gIGFzeW5jIHN1c3BlbmRVc2VySW5UZW5hbnQodGVuYW50TWVtYmVyc2hpcElkOiBzdHJpbmcsIHRlbmFudElkOiBzdHJpbmcsIHByaW5jaXBhbElkOiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5tZW1iZXJzaGlwU2VydmljZS5zZXRTdGF0dXModGVuYW50TWVtYmVyc2hpcElkLCBNZW1iZXJzaGlwU3RhdHVzLlN1c3BlbmRlZCwgLi4uYXJncyk7XG4gICAgYXdhaXQgdGhpcy5lZmZlY3RpdmVQZXJtaXNzaW9uU2VydmljZS5kZWxldGVGb3JQcmluY2lwYWwodGVuYW50SWQsIHByaW5jaXBhbElkLCAuLi5hcmdzKTtcbiAgfVxuXG4gIEB0cmFuc2FjdGlvbmFsKClcbiAgYXN5bmMgcmVhY3RpdmF0ZVVzZXJJblRlbmFudCh0ZW5hbnRNZW1iZXJzaGlwSWQ6IHN0cmluZywgdGVuYW50SWQ6IHN0cmluZywgcHJpbmNpcGFsSWQ6IHN0cmluZywgLi4uYXJnczogYW55W10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLm1lbWJlcnNoaXBTZXJ2aWNlLnNldFN0YXR1cyh0ZW5hbnRNZW1iZXJzaGlwSWQsIE1lbWJlcnNoaXBTdGF0dXMuQWN0aXZlLCAuLi5hcmdzKTtcbiAgICBhd2FpdCB0aGlzLmVmZmVjdGl2ZVBlcm1pc3Npb25TZXJ2aWNlLnJlYnVpbGRGb3JQcmluY2lwYWwodGVuYW50SWQsIHByaW5jaXBhbElkLCAuLi5hcmdzKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgQXV0aG9yaXphdGlvbkVycm9yIH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQge1xuICBBdXRoekRhdGFTb3VyY2VzLFxuICBDYW5BY2Nlc3NJbnB1dCxcbiAgUmVzb3VyY2VWaXNpYmlsaXR5LFxuICBTY29wZUtpbmQsXG59IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHtcbiAgYXNBcnJheSxcbiAgYnVpbGRBY2Nlc3NDb250ZXh0LFxuICBidWlsZEFyYW5nb0NvbnRleHQsXG4gIGJ1aWxkUWRyYW50RmlsdGVyLFxuICBpc1RpbWVWYWxpZCxcbn0gZnJvbSBcIi4uL3V0aWxzXCI7XG5cbmZ1bmN0aW9uIHNjb3BlS2V5KHNjb3BlS2luZDogU2NvcGVLaW5kLCBzY29wZUlkOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYCR7c2NvcGVLaW5kfToke3Njb3BlSWR9YDtcbn1cblxuZXhwb3J0IGNsYXNzIEF1dGh6U2VydmljZSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgZGF0YVNvdXJjZXM6IEF1dGh6RGF0YVNvdXJjZXM7XG5cbiAgY29uc3RydWN0b3IoZGF0YVNvdXJjZXM6IEF1dGh6RGF0YVNvdXJjZXMgPSB7fSkge1xuICAgIHRoaXMuZGF0YVNvdXJjZXMgPSBkYXRhU291cmNlcztcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgYXN5bmMgY2FuQWNjZXNzKGlucHV0OiBDYW5BY2Nlc3NJbnB1dCwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBhdCA9IGlucHV0LmF0ID8/IG5ldyBEYXRlKCk7XG5cbiAgICBpZiAoaW5wdXQuc2NvcGVLaW5kICYmIGlucHV0LnNjb3BlSWQpIHtcbiAgICAgIGNvbnN0IHBlcm1pc3Npb25zID1cbiAgICAgICAgYXdhaXQgdGhpcy5kYXRhU291cmNlcy5saXN0RWZmZWN0aXZlUGVybWlzc2lvbnNGb3JTY29wZT8uKFxuICAgICAgICAgIGlucHV0LnRlbmFudElkLFxuICAgICAgICAgIGlucHV0LnNjb3BlS2luZCxcbiAgICAgICAgICBpbnB1dC5zY29wZUlkXG4gICAgICAgICk7XG4gICAgICByZXR1cm4gYXNBcnJheShwZXJtaXNzaW9ucykuc29tZShcbiAgICAgICAgKHBlcm1pc3Npb24pID0+XG4gICAgICAgICAgcGVybWlzc2lvbi5wZXJtaXNzaW9uS2V5ID09PSBpbnB1dC5wZXJtaXNzaW9uS2V5ICYmXG4gICAgICAgICAgaXNUaW1lVmFsaWQoYXQsIHBlcm1pc3Npb24uc3RhcnRzQXQsIHBlcm1pc3Npb24uZXhwaXJlc0F0KVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoIWlucHV0LnJlc291cmNlUHJvdGVjdGVkSWQpIHJldHVybiBmYWxzZTtcblxuICAgIGNvbnN0IHJlc291cmNlID0gYXdhaXQgdGhpcy5kYXRhU291cmNlcy5sb2FkUmVzb3VyY2U/LihcbiAgICAgIGlucHV0LnRlbmFudElkLFxuICAgICAgaW5wdXQucmVzb3VyY2VQcm90ZWN0ZWRJZFxuICAgICk7XG4gICAgaWYgKCFyZXNvdXJjZSkgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChyZXNvdXJjZS50ZW5hbnRJZCAhPT0gaW5wdXQudGVuYW50SWQpIHJldHVybiBmYWxzZTtcblxuICAgIGlmIChyZXNvdXJjZS5vd25lclByaW5jaXBhbElkID09PSBpbnB1dC5wcmluY2lwYWxJZCkgcmV0dXJuIHRydWU7XG5cbiAgICBjb25zdCBncmFudHMgPSBhc0FycmF5KFxuICAgICAgYXdhaXQgdGhpcy5kYXRhU291cmNlcy5saXN0UmVzb3VyY2VHcmFudHM/LihcbiAgICAgICAgaW5wdXQudGVuYW50SWQsXG4gICAgICAgIGlucHV0LnJlc291cmNlUHJvdGVjdGVkSWRcbiAgICAgIClcbiAgICApLmZpbHRlcihcbiAgICAgIChncmFudCkgPT5cbiAgICAgICAgZ3JhbnQucHJpbmNpcGFsSWQgPT09IGlucHV0LnByaW5jaXBhbElkICYmXG4gICAgICAgIGdyYW50LnBlcm1pc3Npb25LZXkgPT09IGlucHV0LnBlcm1pc3Npb25LZXkgJiZcbiAgICAgICAgaXNUaW1lVmFsaWQoYXQsIGdyYW50LnN0YXJ0c0F0LCBncmFudC5leHBpcmVzQXQpXG4gICAgKTtcbiAgICBpZiAoZ3JhbnRzLmxlbmd0aCA+IDApIHJldHVybiB0cnVlO1xuXG4gICAgY29uc3QgdmlzaWJpbGl0eSA9IHJlc291cmNlLnZpc2liaWxpdHk7XG4gICAgaWYgKFxuICAgICAgdmlzaWJpbGl0eSA9PT0gUmVzb3VyY2VWaXNpYmlsaXR5LlByaXZhdGUgfHxcbiAgICAgIHZpc2liaWxpdHkgPT09IFJlc291cmNlVmlzaWJpbGl0eS5SZXNvdXJjZUFjbFxuICAgICkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIHZpc2liaWxpdHkgPT09IFJlc291cmNlVmlzaWJpbGl0eS5PcmdVbml0IHx8XG4gICAgICB2aXNpYmlsaXR5ID09PSBSZXNvdXJjZVZpc2liaWxpdHkuT3JnU3VidHJlZVxuICAgICkge1xuICAgICAgY29uc3QgZWZmZWN0aXZlUGVybWlzc2lvbnMgPSBhc0FycmF5KFxuICAgICAgICBhd2FpdCB0aGlzLmRhdGFTb3VyY2VzLmxpc3RFZmZlY3RpdmVQZXJtaXNzaW9uc0ZvclNjb3BlPy4oXG4gICAgICAgICAgaW5wdXQudGVuYW50SWQsXG4gICAgICAgICAgU2NvcGVLaW5kLk9yZ1VuaXQsXG4gICAgICAgICAgcmVzb3VyY2Uub3JnVW5pdElkXG4gICAgICAgIClcbiAgICAgICk7XG4gICAgICByZXR1cm4gZWZmZWN0aXZlUGVybWlzc2lvbnMuc29tZShcbiAgICAgICAgKHBlcm1pc3Npb24pID0+XG4gICAgICAgICAgcGVybWlzc2lvbi5wZXJtaXNzaW9uS2V5ID09PSBpbnB1dC5wZXJtaXNzaW9uS2V5ICYmXG4gICAgICAgICAgaXNUaW1lVmFsaWQoYXQsIHBlcm1pc3Npb24uc3RhcnRzQXQsIHBlcm1pc3Npb24uZXhwaXJlc0F0KVxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAodmlzaWJpbGl0eSA9PT0gUmVzb3VyY2VWaXNpYmlsaXR5LlRlbmFudCkge1xuICAgICAgY29uc3QgZWZmZWN0aXZlUGVybWlzc2lvbnMgPSBhc0FycmF5KFxuICAgICAgICBhd2FpdCB0aGlzLmRhdGFTb3VyY2VzLmxpc3RFZmZlY3RpdmVQZXJtaXNzaW9uc0ZvclNjb3BlPy4oXG4gICAgICAgICAgaW5wdXQudGVuYW50SWQsXG4gICAgICAgICAgU2NvcGVLaW5kLlRlbmFudCxcbiAgICAgICAgICBpbnB1dC50ZW5hbnRJZFxuICAgICAgICApXG4gICAgICApO1xuICAgICAgcmV0dXJuIGVmZmVjdGl2ZVBlcm1pc3Npb25zLnNvbWUoXG4gICAgICAgIChwZXJtaXNzaW9uKSA9PlxuICAgICAgICAgIHBlcm1pc3Npb24ucGVybWlzc2lvbktleSA9PT0gaW5wdXQucGVybWlzc2lvbktleSAmJlxuICAgICAgICAgIGlzVGltZVZhbGlkKGF0LCBwZXJtaXNzaW9uLnN0YXJ0c0F0LCBwZXJtaXNzaW9uLmV4cGlyZXNBdClcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgYXN5bmMgcmVxdWlyZUFjY2VzcyhpbnB1dDogQ2FuQWNjZXNzSW5wdXQsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCEoYXdhaXQgdGhpcy5jYW5BY2Nlc3MoaW5wdXQsIC4uLmFyZ3MpKSkge1xuICAgICAgdGhyb3cgbmV3IEF1dGhvcml6YXRpb25FcnJvcihcbiAgICAgICAgYEFjY2VzcyBkZW5pZWQgZm9yICR7aW5wdXQucGVybWlzc2lvbktleX0gb24gJHtpbnB1dC5yZXNvdXJjZVByb3RlY3RlZElkID8/IHNjb3BlS2V5KGlucHV0LnNjb3BlS2luZCA/PyBTY29wZUtpbmQuUmVzb3VyY2UsIGlucHV0LnNjb3BlSWQgPz8gXCJcIil9YFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBidWlsZEFjY2Vzc0NvbnRleHQoXG4gICAgdGVuYW50SWQ6IHN0cmluZyxcbiAgICBwcmluY2lwYWxJZDogc3RyaW5nLFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPGltcG9ydChcIi4uL3R5cGVzXCIpLkFjY2Vzc0NvbnRleHQ+IHtcbiAgICBjb25zdCBwZXJtaXNzaW9ucyA9IGFzQXJyYXkoXG4gICAgICBhd2FpdCB0aGlzLmRhdGFTb3VyY2VzLmxpc3RFZmZlY3RpdmVQZXJtaXNzaW9ucz8uKHRlbmFudElkLCBwcmluY2lwYWxJZClcbiAgICApO1xuICAgIGNvbnN0IGdyYW50cyA9IGFzQXJyYXkoXG4gICAgICBhd2FpdCB0aGlzLmRhdGFTb3VyY2VzLmxpc3RQcmluY2lwYWxHcmFudHM/Lih0ZW5hbnRJZCwgcHJpbmNpcGFsSWQpXG4gICAgKTtcbiAgICByZXR1cm4gYnVpbGRBY2Nlc3NDb250ZXh0KHtcbiAgICAgIHRlbmFudElkLFxuICAgICAgcHJpbmNpcGFsSWQsXG4gICAgICBwZXJtaXNzaW9ucyxcbiAgICAgIGdyYW50cyxcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGJ1aWxkQXJhbmdvQ29udGV4dChcbiAgICB0ZW5hbnRJZDogc3RyaW5nLFxuICAgIHByaW5jaXBhbElkOiBzdHJpbmcsXG4gICAgcGVybWlzc2lvbktleTogc3RyaW5nLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICkge1xuICAgIGNvbnN0IGFjY2VzcyA9IGF3YWl0IHRoaXMuYnVpbGRBY2Nlc3NDb250ZXh0KFxuICAgICAgdGVuYW50SWQsXG4gICAgICBwcmluY2lwYWxJZCxcbiAgICAgIC4uLmFyZ3NcbiAgICApO1xuICAgIGNvbnN0IGFsbG93ZWRPcmdVbml0SWRzID1cbiAgICAgIGFjY2Vzcy5hbGxvd2VkT3JnVW5pdElkc0J5UGVybWlzc2lvbltwZXJtaXNzaW9uS2V5XSA/PyBbXTtcbiAgICBjb25zdCBhbGxvd2VkUmVzb3VyY2VJZHMgPSBhY2Nlc3MucmVzb3VyY2VHcmFudHNcbiAgICAgIC5maWx0ZXIoKGdyYW50KSA9PiBncmFudC5wZXJtaXNzaW9uS2V5ID09PSBwZXJtaXNzaW9uS2V5KVxuICAgICAgLm1hcCgoZ3JhbnQpID0+IGdyYW50LnJlc291cmNlSWQpO1xuICAgIHJldHVybiBidWlsZEFyYW5nb0NvbnRleHQoe1xuICAgICAgdGVuYW50SWQsXG4gICAgICBwcmluY2lwYWxJZCxcbiAgICAgIHBlcm1pc3Npb25LZXksXG4gICAgICBhbGxvd2VkT3JnVW5pdElkcyxcbiAgICAgIGFsbG93ZWRSZXNvdXJjZUlkcyxcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGJ1aWxkUWRyYW50RmlsdGVyKFxuICAgIHRlbmFudElkOiBzdHJpbmcsXG4gICAgcHJpbmNpcGFsSWQ6IHN0cmluZyxcbiAgICBwZXJtaXNzaW9uS2V5OiBzdHJpbmcsXG4gICAgLi4uYXJnczogYW55W11cbiAgKSB7XG4gICAgY29uc3QgYWNjZXNzID0gYXdhaXQgdGhpcy5idWlsZEFjY2Vzc0NvbnRleHQoXG4gICAgICB0ZW5hbnRJZCxcbiAgICAgIHByaW5jaXBhbElkLFxuICAgICAgLi4uYXJnc1xuICAgICk7XG4gICAgY29uc3QgYWxsb3dlZE9yZ1VuaXRJZHMgPVxuICAgICAgYWNjZXNzLmFsbG93ZWRPcmdVbml0SWRzQnlQZXJtaXNzaW9uW3Blcm1pc3Npb25LZXldID8/IFtdO1xuICAgIGNvbnN0IGFsbG93ZWRSZXNvdXJjZUlkcyA9IGFjY2Vzcy5yZXNvdXJjZUdyYW50c1xuICAgICAgLmZpbHRlcigoZ3JhbnQpID0+IGdyYW50LnBlcm1pc3Npb25LZXkgPT09IHBlcm1pc3Npb25LZXkpXG4gICAgICAubWFwKChncmFudCkgPT4gZ3JhbnQucmVzb3VyY2VJZCk7XG4gICAgcmV0dXJuIGJ1aWxkUWRyYW50RmlsdGVyKHtcbiAgICAgIHRlbmFudElkLFxuICAgICAgcHJpbmNpcGFsSWQsXG4gICAgICBwZXJtaXNzaW9uS2V5LFxuICAgICAgYWxsb3dlZE9yZ1VuaXRJZHMsXG4gICAgICBhbGxvd2VkUmVzb3VyY2VJZHMsXG4gICAgfSk7XG4gIH1cbn1cbiIsIi8qKlxuICogQG1vZHVsZSBpbnRlZ3JhdGlvbnNcbiAqIEBzdW1tYXJ5IFBhY2thZ2UgZW50cnkgcG9pbnQgZm9yIHNoYXJlZCBpbnRlZ3JhdGlvbiBoZWxwZXJzLlxuICogQGRlc2NyaXB0aW9uIEV4cG9zZXMgdGhlIHBhY2thZ2UgdXRpbGl0aWVzIGFuZCBidWlsZC10aW1lIHZlcnNpb24gbWV0YWRhdGEgZm9yIGBAZGVjYWYtdHMvaW50ZWdyYXRpb25zYC5cbiAqL1xuZXhwb3J0ICogZnJvbSBcIi4vdXRpbHNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL25hbWVzcGFjZXNcIjtcblxuZXhwb3J0IGNvbnN0IFZFUlNJT046IHN0cmluZyA9IFwiIyNWRVJTSU9OIyNcIjtcblxuZXhwb3J0IGNvbnN0IENPTU1JVCA9IFwiIyNDT01NSVQjI1wiO1xuXG5leHBvcnQgY29uc3QgRlVMTF9WRVJTSU9OID0gXCIjI0ZVTExfVkVSU0lPTiMjXCI7XG5cbmV4cG9ydCBjb25zdCBQQUNLQUdFX05BTUU6IHN0cmluZyA9IFwiIyNQQUNLQUdFIyNcIjtcbiJdLCJuYW1lcyI6WyJhc3luYyIsImV4ZWNXaXRoTG9nZ2luZyIsImNvbW1hbmQiLCJvcHRpb25zIiwibG9nIiwibGV2ZWwiLCJMb2dMZXZlbCIsImluZm8iLCJkZWJ1ZyIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwiY2hpbGQiLCJleGVjIiwic3Rkb3V0Iiwic3RkZXJyIiwib24iLCJkYXRhIiwicHVzaCIsInRyaW0iLCJjb2RlIiwic2lsbHkiLCJqb2luIiwiY3JpdGljYWwiLCJJbnRlcm5hbEVycm9yIiwiZXJyIiwiSXNvbGF0aW9uVGllciIsIk1lbWJlcnNoaXBTdGF0dXMiLCJQcmluY2lwYWxLaW5kIiwiU2NvcGVLaW5kIiwiUGVybWlzc2lvbkNhdGVnb3J5IiwiUmVzb3VyY2VWaXNpYmlsaXR5IiwiU3RvcmFnZUtpbmQiLCJTdG9yYWdlQmluZGluZ0tpbmQiLCJJc29sYXRpb25UaWVyT3B0aW9ucyIsIk9iamVjdCIsInZhbHVlcyIsIk1lbWJlcnNoaXBTdGF0dXNPcHRpb25zIiwiUHJpbmNpcGFsS2luZE9wdGlvbnMiLCJTY29wZUtpbmRPcHRpb25zIiwiUGVybWlzc2lvbkNhdGVnb3J5T3B0aW9ucyIsIlJlc291cmNlVmlzaWJpbGl0eU9wdGlvbnMiLCJTdG9yYWdlS2luZE9wdGlvbnMiLCJTdG9yYWdlQmluZGluZ0tpbmRPcHRpb25zIiwiUkVMX1JFU1RSSUNUIiwidXBkYXRlIiwiQ2FzY2FkZSIsIk5PTkUiLCJkZWxldGUiLCJudWxsYWJsZSIsIlJFTF9OVUxMSUZZIiwiUkVMX0NBU0NBREVfREVQRU5ERU5UIiwiQ0FTQ0FERSIsIlJFTF9DQVNDQURFX0lOU0VSVF9VUERBVEUiLCJidWlsZEFyYW5nb0NvbnRleHQiLCJ0ZW5hbnRJZCIsInByaW5jaXBhbElkIiwicGVybWlzc2lvbktleSIsImFsbG93ZWRPcmdVbml0SWRzIiwiYWxsb3dlZFJlc291cmNlSWRzIiwiYnVpbGRRZHJhbnRGaWx0ZXIiLCJtdXN0Iiwia2V5IiwibWF0Y2giLCJ2YWx1ZSIsInNob3VsZCIsImFueSIsInNjb3BlS2V5Iiwic2NvcGVLaW5kIiwic2NvcGVJZCIsIm5vd0lzbyIsIkRhdGUiLCJhc0FycmF5Iiwic2FtZVRlbmFudCIsInJvd1RlbmFudCIsInJlbGF0aW9uSWQiLCJyZWxhdGlvbk1hdGNoIiwidGFyZ2V0IiwibG93ZXJTbHVnIiwidG9Mb3dlckNhc2UiLCJyZXBsYWNlIiwiaXNUaW1lVmFsaWQiLCJhdCIsInN0YXJ0c0F0IiwiZXhwaXJlc0F0IiwiaW5zdGFudCIsImJ1aWxkQWNjZXNzQ29udGV4dCIsInBlcm1pc3Npb25zQnlTY29wZSIsImFsbG93ZWRPcmdVbml0SWRzQnlQZXJtaXNzaW9uIiwicGVybWlzc2lvbiIsInBlcm1pc3Npb25zIiwiT3JnVW5pdCIsInJlc291cmNlR3JhbnRzIiwiZ3JhbnRzIiwibWFwIiwiZ3JhbnQiLCJyZXNvdXJjZUlkIiwiQmFzZU1vZGVsU2VydmljZSIsIk1vZGVsU2VydmljZSIsImNvbnN0cnVjdG9yIiwiY2xhenoiLCJzdXBlciIsIm5ld01vZGVsIiwiYXNzaWduIiwiY3JlYXRlIiwiYXJncyIsInRoaXMiLCJyZXBvIiwiY3JlYXRlT25lIiwiZ2V0QnlJZCIsImlkIiwicmVhZCIsInVwZGF0ZU9uZSIsInBhdGNoIiwiZXhpc3RpbmciLCJkZWxldGVCeUlkIiwiZmluZE9uZUJ5IiwiZmluZE1hbnlCeSIsInNlbGVjdCIsIndoZXJlIiwiZXhlY3V0ZSIsImxpc3RBbGwiLCJjcnlwdG8iLCJyYW5kb21VVUlEIiwiQXV0aG9yaXphdGlvbk1vZGVsIiwiTW9kZWwiLCJUZW5hbnRNZW1iZXJzaGlwIiwiX19kZWNvcmF0ZSIsInBrIiwidHlwZSIsIlN0cmluZyIsInV1aWQiLCJwcm90b3R5cGUiLCJtYW55VG9PbmUiLCJUZW5hbnQiLCJ1bmRlZmluZWQiLCJyZXF1aXJlZCIsIlVzZXIiLCJ0eXBlT2YiLCJvcHRpb24iLCJjb2x1bW4iLCJjcmVhdGVkQXQiLCJ1cGRhdGVkQXQiLCJ0YWJsZSIsIm1vZGVsIiwidW5pcXVlIiwib25lVG9NYW55IiwiT3JnVW5pdE1lbWJlcnNoaXAiLCJPcmdVbml0Q2xvc3VyZSIsIk51bWJlciIsIlBlcm1pc3Npb24iLCJSb2xlUGVybWlzc2lvbiIsIlJvbGUiLCJSb2xlQXNzaWdubWVudCIsIlByaW5jaXBhbCIsIkJvb2xlYW4iLCJSZXNvdXJjZUdyYW50IiwiUHJvdGVjdGVkUmVzb3VyY2UiLCJJbmhlcml0YW5jZUJsb2NrIiwiU3RvcmFnZUJpbmRpbmciLCJUZW5hbnRQcm9maWxlIiwiT3JnVW5pdFByb2ZpbGUiLCJHcm91cE1lbWJlcnNoaXAiLCJHcm91cCIsIkVmZmVjdGl2ZVBlcm1pc3Npb24iLCJUZW5hbnRQcm9maWxlU2VydmljZSIsImNyZWF0ZVByb2ZpbGUiLCJwcm9maWxlS2V5IiwibWV0YWRhdGEiLCJ0ZW5hbnQiLCJsaXN0Rm9yVGVuYW50IiwiZmlsdGVyIiwicHJvZmlsZSIsImRlbGV0ZUZvclRlbmFudCIsInJvdyIsIk9yZ1VuaXRQcm9maWxlU2VydmljZSIsIm9yZ1VuaXRJZCIsIm9yZ1VuaXQiLCJsaXN0Rm9yT3JnVW5pdCIsIk9yZ1VuaXRDbG9zdXJlU2VydmljZSIsImxpc3RBbmNlc3RvcnMiLCJkZXNjZW5kYW50Iiwic29ydCIsImxlZnQiLCJyaWdodCIsImRlcHRoIiwibGlzdERlc2NlbmRhbnRzIiwiYW5jZXN0b3IiLCJpc0FuY2VzdG9yT2YiLCJhbmNlc3Rvck9yZ1VuaXRJZCIsImRlc2NlbmRhbnRPcmdVbml0SWQiLCJzb21lIiwiY3JlYXRlU2VsZkxpbmsiLCJpbnNlcnRBbmNlc3RvckxpbmtzRm9yTmV3Q2hpbGQiLCJwYXJlbnRPcmdVbml0SWQiLCJjaGlsZE9yZ1VuaXRJZCIsImFuY2VzdG9yTGlua3MiLCJsaW5rIiwiZGVsZXRlTGlua3NGb3JTdWJ0cmVlIiwic3VidHJlZSIsImRlc2NlbmRhbnRJZHMiLCJTZXQiLCJhbmNlc3RvcklkcyIsInJvd3MiLCJoYXMiLCJJbmhlcml0YW5jZUJsb2NrU2VydmljZSIsImJsb2NrQ2F0ZWdvcnkiLCJwZXJtaXNzaW9uQ2F0ZWdvcnkiLCJibG9ja2VkRnJvbUFuY2VzdG9ySWQiLCJyZWFzb24iLCJibG9ja2VkRnJvbUFuY2VzdG9yIiwidW5ibG9ja0NhdGVnb3J5IiwiYmxvY2tJZCIsImJsb2NrIiwiY2F0ZWdvcnlCbG9ja2VkRm9yQW5jZXN0b3IiLCJjYXRlZ29yeSIsIlRlbmFudFNlcnZpY2UiLCJjcmVhdGVUZW5hbnQiLCJpbnB1dCIsInNsdWciLCJuYW1lIiwiaXNvbGF0aW9uVGllciIsIlBvb2xlZCIsImdldEJ5U2x1ZyIsInJlbmFtZVRlbmFudCIsImNoYW5nZVNsdWciLCJzZXRJc29sYXRpb25UaWVyIiwiZGVsZXRlVGVuYW50Q29udHJvbGxlZCIsImRlbGV0ZVJvd3NCeUlkIiwic2VydmljZSIsIk9yZ1VuaXRTZXJ2aWNlIiwib3JnVW5pdFBhdGgiLCJwYXJlbnRQYXRoIiwic2VnbWVudCIsImNyZWF0ZVByb2ZpbGVJZk5lZWRlZCIsInByb2ZpbGVNZXRhZGF0YSIsImNyZWF0ZVJvb3QiLCJwYXRoIiwiY3JlYXRlQ2hpbGQiLCJwYXJlbnQiLCJjbG9zdXJlU2VydmljZSIsImxpc3RDaGlsZHJlbiIsImxpc3RUZW5hbnRPcmdVbml0cyIsImxpc3REZXNjZW5kYW50T3JnVW5pdHMiLCJpbmNsdWRlU2VsZiIsImRlc2NlbmRhbnRzIiwiaWRzIiwiYWRkIiwibGlzdEFuY2VzdG9yT3JnVW5pdHMiLCJhbmNlc3RvcnMiLCJyZW5hbWVPcmdVbml0IiwiaW5jbHVkZXMiLCJtb3ZlT3JnVW5pdCIsIm5ld1BhcmVudE9yZ1VuaXRJZCIsIm5ld1BhcmVudCIsInVwZGF0ZWQiLCJyZWJ1aWxkVGVuYW50Q2xvc3VyZSIsImV4aXN0aW5nTGlua3MiLCJvcmdVbml0cyIsImxlZnREZXB0aCIsInNwbGl0IiwibGVuZ3RoIiwicmlnaHREZXB0aCIsImRlbGV0ZU9yZ1VuaXRUcmVlIiwidHJhbnNhY3Rpb25hbCIsIlVzZXJTZXJ2aWNlIiwiY3JlYXRlVXNlciIsImVtYWlsIiwicGhvbmUiLCJkaXNwbGF5TmFtZSIsImdldEJ5RW1haWwiLCJmaW5kIiwidXNlciIsInVwZGF0ZURpc3BsYXlOYW1lIiwidXNlcklkIiwidXBkYXRlRW1haWwiLCJ1cGRhdGVQaG9uZSIsIlByaW5jaXBhbFNlcnZpY2UiLCJjcmVhdGVQcmluY2lwYWwiLCJraW5kIiwic3ViamVjdElkIiwiZ2V0Rm9yU3ViamVjdCIsInByaW5jaXBhbCIsImdldE9yQ3JlYXRlRm9yU3ViamVjdCIsImdldFVzZXJQcmluY2lwYWwiLCJnZXRHcm91cFByaW5jaXBhbCIsImdyb3VwSWQiLCJUZW5hbnRNZW1iZXJzaGlwU2VydmljZSIsImFkZFVzZXJUb1RlbmFudCIsInN0YXR1cyIsIkFjdGl2ZSIsInNldFN0YXR1cyIsIm1lbWJlcnNoaXBJZCIsImxpc3RVc2VyVGVuYW50cyIsIm1lbWJlcnNoaXAiLCJsaXN0VGVuYW50VXNlcnMiLCJyZW1vdmVVc2VyRnJvbVRlbmFudCIsIk9yZ1VuaXRNZW1iZXJzaGlwU2VydmljZSIsImFkZFVzZXJUb09yZ1VuaXQiLCJsaXN0VXNlck9yZ1VuaXRzIiwibGlzdE9yZ1VuaXRVc2VycyIsInJlbW92ZVVzZXJGcm9tT3JnVW5pdCIsIkdyb3VwU2VydmljZSIsImNyZWF0ZUdyb3VwIiwicmVuYW1lR3JvdXAiLCJtb3ZlR3JvdXBUb09yZ1VuaXQiLCJsaXN0VGVuYW50R3JvdXBzIiwiZ3JvdXAiLCJHcm91cE1lbWJlcnNoaXBTZXJ2aWNlIiwiYWRkUHJpbmNpcGFsVG9Hcm91cCIsImxpc3RHcm91cE1lbWJlcnMiLCJsaXN0UHJpbmNpcGFsR3JvdXBzIiwicmVtb3ZlUHJpbmNpcGFsRnJvbUdyb3VwIiwicmVzb2x2ZUdyb3VwUHJpbmNpcGFsSWRzRm9yUHJpbmNpcGFsIiwicHJpbmNpcGFsU2VydmljZSIsIm1lbWJlcnNoaXBzIiwicHJpbmNpcGFscyIsImFsbCIsIlBlcm1pc3Npb25TZXJ2aWNlIiwiY3JlYXRlUGVybWlzc2lvbiIsImRlc2NyaXB0aW9uIiwiZ2V0QnlLZXkiLCJsaXN0QnlDYXRlZ29yeSIsInVwZGF0ZURlc2NyaXB0aW9uIiwicGVybWlzc2lvbklkIiwiUm9sZVNlcnZpY2UiLCJjcmVhdGVSb2xlIiwiZ2V0U3lzdGVtUm9sZUJ5S2V5Iiwicm9sZSIsImNhbmRpZGF0ZSIsIkVycm9yIiwiZ2V0VGVuYW50Um9sZUJ5S2V5IiwicmVuYW1lUm9sZSIsInJvbGVJZCIsInVwZGF0ZVJvbGVNZXRhZGF0YSIsImxpc3RUZW5hbnRSb2xlcyIsImluY2x1ZGVTeXN0ZW0iLCJSb2xlUGVybWlzc2lvblNlcnZpY2UiLCJhZGRQZXJtaXNzaW9uVG9Sb2xlIiwiYWRkUGVybWlzc2lvbktleVRvUm9sZSIsInJlbW92ZVBlcm1pc3Npb25Gcm9tUm9sZSIsInJvbGVQZXJtaXNzaW9uSWQiLCJsaXN0Um9sZVBlcm1pc3Npb25zIiwicm9sZVBlcm1pc3Npb24iLCJsaXN0UGVybWlzc2lvblJvbGVzIiwicmVwbGFjZVJvbGVQZXJtaXNzaW9ucyIsInBlcm1pc3Npb25JZHMiLCJjcmVhdGVSb2xlV2l0aFBlcm1pc3Npb25zIiwicGVybWlzc2lvbktleXMiLCJSb2xlQXNzaWdubWVudFNlcnZpY2UiLCJhc3NpZ25Sb2xlIiwiaW5oZXJpdERvd24iLCJjb25kaXRpb25zIiwicmV2b2tlQXNzaWdubWVudCIsImFzc2lnbm1lbnRJZCIsImxpc3RQcmluY2lwYWxBc3NpZ25tZW50cyIsImFzc2lnbm1lbnQiLCJsaXN0Um9sZUFzc2lnbm1lbnRzIiwibGlzdFRlbmFudEFzc2lnbm1lbnRzIiwidXBkYXRlQXNzaWdubWVudFdpbmRvdyIsIkVmZmVjdGl2ZVBlcm1pc3Npb25TZXJ2aWNlIiwibGlzdEZvclByaW5jaXBhbCIsImxpc3RGb3JTY29wZSIsImhhc1Blcm1pc3Npb24iLCJkZWxldGVGb3JQcmluY2lwYWwiLCJyZWJ1aWxkRm9yUHJpbmNpcGFsIiwicm9sZUFzc2lnbm1lbnRTZXJ2aWNlIiwicm9sZVBlcm1pc3Npb25TZXJ2aWNlIiwicGVybWlzc2lvblNlcnZpY2UiLCJncm91cE1lbWJlcnNoaXBTZXJ2aWNlIiwib3JnVW5pdENsb3N1cmVTZXJ2aWNlIiwiaW5oZXJpdGFuY2VCbG9ja1NlcnZpY2UiLCJtYXRlcmlhbGl6ZWQiLCJzb3VyY2VBc3NpZ25tZW50cyIsImdyb3VwTWVtYmVyc2hpcHMiLCJncm91cEFzc2lnbm1lbnRzIiwiZ3JvdXBQcmluY2lwYWwiLCJmbGF0IiwiYXNzaWdubWVudHMiLCJyb2xlUGVybWlzc2lvbnMiLCJzY29wZXMiLCJSZXNvdXJjZSIsInNjb3BlZCIsInNvdXJjZUtpbmQiLCJzb3VyY2VJZCIsImNyZWF0ZWQiLCJyZWJ1aWxkRm9yVGVuYW50IiwiUHJvdGVjdGVkUmVzb3VyY2VTZXJ2aWNlIiwicmVnaXN0ZXJSZXNvdXJjZSIsInJlc291cmNlVHlwZSIsInZpc2liaWxpdHkiLCJvd25lciIsIm93bmVyUHJpbmNpcGFsSWQiLCJzZW5zaXRpdml0eSIsImdldEJ5RG9tYWluUmVzb3VyY2UiLCJyZXNvdXJjZSIsIm1vdmVSZXNvdXJjZVRvT3JnVW5pdCIsInByb3RlY3RlZFJlc291cmNlSWQiLCJzZXRWaXNpYmlsaXR5IiwidHJhbnNmZXJPd25lcnNoaXAiLCJsaXN0T3JnVW5pdFJlc291cmNlcyIsImxpc3RUZW5hbnRSZXNvdXJjZXMiLCJSZXNvdXJjZUdyYW50U2VydmljZSIsImdyYW50UmVzb3VyY2UiLCJjcmVhdGVkQnkiLCJjcmVhdGVkQnlQcmluY2lwYWxJZCIsInJldm9rZUdyYW50IiwiZ3JhbnRJZCIsImxpc3RSZXNvdXJjZUdyYW50cyIsImxpc3RQcmluY2lwYWxHcmFudHMiLCJoYXNHcmFudCIsImRlbGV0ZUFsbEZvclJlc291cmNlIiwiUmVzb3VyY2VMaWZlY3ljbGVTZXJ2aWNlIiwidW5yZWdpc3RlclJlc291cmNlIiwicmVzb2x2ZVJlc291cmNlU2NvcGUiLCJTdG9yYWdlQmluZGluZ1NlcnZpY2UiLCJjcmVhdGVCaW5kaW5nIiwic3RvcmFnZUtpbmQiLCJiaW5kaW5nS2luZCIsImJpbmRpbmdLZXkiLCJyZWdpb24iLCJjb25maWciLCJsaXN0VGVuYW50QmluZGluZ3MiLCJiaW5kaW5nIiwiZ2V0QmluZGluZyIsInNldEJpbmRpbmdDb25maWciLCJiaW5kaW5nSWQiLCJwcm9tb3RlVG9EZWRpY2F0ZWQiLCJEZWRpY2F0ZWQiLCJzZXRTaGFyZWQiLCJTaGFyZWQiLCJCb290c3RyYXBTZXJ2aWNlIiwidGVuYW50U2VydmljZSIsInRlbmFudFByb2ZpbGVTZXJ2aWNlIiwib3JnVW5pdFNlcnZpY2UiLCJvcmdVbml0UHJvZmlsZVNlcnZpY2UiLCJ1c2VyU2VydmljZSIsIm1lbWJlcnNoaXBTZXJ2aWNlIiwicm9sZVNlcnZpY2UiLCJlZmZlY3RpdmVQZXJtaXNzaW9uU2VydmljZSIsImJvb3RzdHJhcFRlbmFudEZyb21UZW1wbGF0ZSIsInRlbXBsYXRlIiwiY3JlYXRlT3JnVHJlZSIsInBhcmVudElkIiwiY2hpbGRyZW4iLCJyb290T3JnVW5pdCIsIm93bmVyVXNlciIsIm93bmVyUHJpbmNpcGFsIiwicm9sZXMiLCJjcmVhdGVkUm9sZSIsIm93bmVyUm9sZSIsIm93bmVyUm9sZUtleSIsInJvb3RPcmdVbml0SWQiLCJvd25lclVzZXJJZCIsIlN5c3RlbU1hbmFnZW1lbnRTZXJ2aWNlIiwib3JnTWVtYmVyc2hpcFNlcnZpY2UiLCJvbmJvYXJkVXNlclRvVGVuYW50QW5kT3JnVW5pdCIsInJvbGVLZXkiLCJjaGFuZ2VVc2VyT3JnUm9sZSIsImN1cnJlbnRBc3NpZ25tZW50cyIsInN1c3BlbmRVc2VySW5UZW5hbnQiLCJ0ZW5hbnRNZW1iZXJzaGlwSWQiLCJTdXNwZW5kZWQiLCJyZWFjdGl2YXRlVXNlckluVGVuYW50IiwiQXV0aHpTZXJ2aWNlIiwiZGF0YVNvdXJjZXMiLCJjYW5BY2Nlc3MiLCJsaXN0RWZmZWN0aXZlUGVybWlzc2lvbnNGb3JTY29wZSIsInJlc291cmNlUHJvdGVjdGVkSWQiLCJsb2FkUmVzb3VyY2UiLCJQcml2YXRlIiwiUmVzb3VyY2VBY2wiLCJPcmdTdWJ0cmVlIiwiZWZmZWN0aXZlUGVybWlzc2lvbnMiLCJyZXF1aXJlQWNjZXNzIiwiQXV0aG9yaXphdGlvbkVycm9yIiwibGlzdEVmZmVjdGl2ZVBlcm1pc3Npb25zIiwiYWNjZXNzIiwiVkVSU0lPTiIsIkNPTU1JVCIsIkZVTExfVkVSU0lPTiIsIlBBQ0tBR0VfTkFNRSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7QUFTT0EsZUFBZUMsZ0JBQ3BCQyxTQUNBQyxTQUNBQyxLQUNBQyxRQUFrQkMsU0FBU0M7SUFFM0JILElBQUlJLE1BQU0sY0FBY047SUFFeEIsT0FBTyxJQUFJTyxRQUFRLENBQUNDLFNBQVNDO1FBQzNCLE1BQU1DLFFBQVFDLEtBQUtYLFNBQVNDO1FBRTVCLE1BQU1XLFNBQW1CO1FBQ3pCLE1BQU1DLFNBQW1CO1FBRXpCSCxNQUFNRSxRQUFRRSxHQUFHLFFBQVNDO1lBQ3hCSCxPQUFPSSxLQUFLRDtZQUNaYixJQUFJQyxPQUFPWSxLQUFLRTs7UUFHbEJQLE1BQU1HLFFBQVFDLEdBQUcsUUFBU0M7WUFDeEJGLE9BQU9HLEtBQUtEO1lBQ1piLElBQUlJLE1BQU1TLEtBQUtFOztRQUdqQlAsTUFBTUksR0FBRyxTQUFVSTtZQUNqQixJQUFJQSxTQUFTLEdBQUc7Z0JBQ2RoQixJQUFJaUIsTUFBTTtnQkFDVlgsUUFBUTtvQkFBRUksUUFBUUEsT0FBT1EsS0FBSztvQkFBT1AsUUFBUUEsT0FBT08sS0FBSzs7QUFDM0QsbUJBQU87Z0JBQ0xsQixJQUFJbUIsU0FDRiw0QkFBNEJILFdBQVdMLE9BQU9PLEtBQUs7Z0JBRXJEWCxPQUNFLElBQUlhLGNBQ0YsNEJBQTRCSixTQUFTTCxPQUFPTyxLQUFL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
|